techlify-inventory-common 18.23.1 → 18.23.2

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.
@@ -149,11 +149,11 @@ export class StockIssuancesListComponent extends TechlifyListingControllerInterf
149
149
  }
150
150
  }
151
151
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: StockIssuancesListComponent, deps: [{ token: i1.FormBuilder }, { token: i2.RequestHelperService }, { token: i3.StockIssuanceService }, { token: i4.ActivatedRoute }, { token: i2.TechlifyFeatureService }], target: i0.ɵɵFactoryTarget.Component });
152
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: StockIssuancesListComponent, selector: "app-stock-issuances-list", inputs: { product: "product", issuableType: "issuableType", issuableId: "issuableId", label: "label", showActions: "showActions", showFilters: "showFilters" }, outputs: { listUpdated: "listUpdated" }, usesInheritance: true, ngImport: i0, template: "<mat-card *ngIf=\"!product\" class=\"mb-2\">\n <mat-card-content class=\"d-flex justify-content-between align-items-center gap-3\">\n <div class=\"d-flex justify-content-start align-items-center gap-2\">\n <h3 class=\"mb-0\">{{ label }}</h3>\n\n <app-stock-issue-form-button icon=\"add\" [issuableType]=\"issuableType\" [issuableId]=\"issuableId\"\n (saved)=\"reload()\"></app-stock-issue-form-button>\n\n <span *ngIf=\"showActions\" matTooltip=\"Import\" routerLink=\"import\"\n class=\"cursor-pointer material-symbols-outlined\">\n file_upload\n </span>\n\n <app-column-selector *ngIf=\"showActions\" mode=\"icon\" class=\"mt-2 d-print-none\" [columnConfigs]=\"columnConfig\"\n [(selectedColumns)]=\"selectedColumns\"></app-column-selector>\n </div>\n\n <form [formGroup]=\"filterForm\" *ngIf=\"showFilters\">\n <mat-form-field>\n <mat-label>Search</mat-label>\n <input matInput placeholder=\"Search products\" formControlName=\"search\" />\n </mat-form-field>\n\n <app-timeline-filter appearance=\"fill\" labelText=\"Date\" formControlName=\"duration\"\n (selectionChange)=\"onDurationChange($event)\" [showClearButton]=\"true\" [dateFrom]=\"filterForm.value?.date_from\"\n [dateTo]=\"filterForm.value?.date_to\"></app-timeline-filter>\n\n <mat-form-field>\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>\n <mat-label>Measure</mat-label>\n <app-searchable-selector apiUrl=\"api/product-measures\" formControlName=\"measure_ids\" [multiple]=\"true\">\n </app-searchable-selector>\n </mat-form-field>\n\n <mat-form-field>\n <mat-label>Location</mat-label>\n <app-searchable-selector apiUrl=\"api/inventory-locations\" formControlName=\"location_ids\" [multiple]=\"true\">\n </app-searchable-selector>\n </mat-form-field>\n </form>\n </mat-card-content>\n</mat-card>\n\n<mat-card>\n <mat-card-content *ngIf=\"product\" class=\"mb-0\">\n <div class=\"d-flex justify-content-start align-items-center gap-2 mb-2\">\n <span class=\"material-symbols-outlined\"> ungroup </span>\n <h3 class=\"mb-0\">Stock Issues</h3>\n\n <app-stock-issue-form-button class=\"mt-2\" [product]=\"product\" icon=\"add\"\n (saved)=\"reload(); listUpdated.emit()\"></app-stock-issue-form-button>\n </div>\n </mat-card-content>\n <mat-card-content class=\"p-0\">\n <table mat-table [dataSource]=\"models\" class=\"w-100\" aria-describedby=\"Stock Issuances\" infiniteScroll\n [infiniteScrollDistance]=\"2\" [infiniteScrollThrottle]=\"50\" (scrolled)=\"onScroll()\" matSort\n (matSortChange)=\"onSortChange($event)\">\n <!-- # Column -->\n <ng-container matColumnDef=\"no\">\n <th mat-header-cell *matHeaderCellDef>#</th>\n <td mat-cell *matCellDef=\"let element; let i = index\">{{ i + 1 }}</td>\n </ng-container>\n\n <!-- Product Column -->\n <ng-container matColumnDef=\"product\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Product</th>\n <td mat-cell *matCellDef=\"let element\">\n <div class=\"d-flex flex-column gap-1\">\n <a class=\"text-decoration-none text-dark\"\n [routerLink]=\"['/inventory/products', element?.stock_issue_products[0]?.product.id, 'view']\">\n {{ element?.stock_issue_products[0]?.product.name }}\n </a>\n <app-product-category-badges\n [product]=\"element?.stock_issue_products[0]?.product\"></app-product-category-badges>\n </div>\n </td>\n </ng-container>\n\n <!-- SKU Column -->\n <ng-container matColumnDef=\"sku\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>SKU</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.stock_issue_products[0]?.product.sku }}</td>\n </ng-container>\n\n <!-- Date Column -->\n <ng-container matColumnDef=\"date\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Date</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.date | date }}</td>\n </ng-container>\n\n <!-- Location Column -->\n <ng-container matColumnDef=\"location\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Location</th>\n <td mat-cell *matCellDef=\"let element\">\n <a class=\"text-decoration-none text-dark\"\n [routerLink]=\"['/inventory/locations', element?.stock_issue_products[0]?.location_id, 'view']\">\n {{ element?.stock_issue_products[0]?.location?.title }}\n </a>\n </td>\n </ng-container>\n\n <!-- Related Column -->\n <ng-container matColumnDef=\"related\">\n <th mat-header-cell *matHeaderCellDef>Related</th>\n <td mat-cell *matCellDef=\"let element\">\n <a class=\"text-dark\" *ngIf=\"element?.issuable\" [routerLink]=\"['/maintenances', element?.issuable_id, 'view']\">\n Maintenance for {{ element?.issuable?.fixed_asset?.name }}\n </a>\n </td>\n </ng-container>\n\n <!-- Quantity Column -->\n <ng-container matColumnDef=\"quantity\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Quantity</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.stock_issue_products[0]?.quantity }} {{\n element?.stock_issue_products[0]?.product.measure?.title }}</td>\n </ng-container>\n\n <!-- Batch Column -->\n <ng-container matColumnDef=\"batch\">\n <th mat-header-cell *matHeaderCellDef>Batch</th>\n <td mat-cell *matCellDef=\"let element\">\n <p class=\"mb-0\" *ngIf=\"element?.stock_issue_products[0]?.batch?.batch_number\">{{ element?.stock_issue_products[0]?.batch?.batch_number }}</p>\n <small class=\"text-secondary\" *ngIf=\"element?.stock_issue_products[0]?.batch?.expires_on\">\n Expires {{ element?.stock_issue_products[0]?.batch?.expires_on | date }}\n </small>\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"measure\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Measure</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.stock_issue_products[0]?.product.measure?.title }}</td>\n </ng-container>\n\n <!-- Purchase Price Column -->\n <ng-container matColumnDef=\"purchase_price\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Purchase Price</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element?.purchase_price | currency }}\n </td>\n </ng-container>\n\n <!-- Total Value Column -->\n <ng-container matColumnDef=\"amount\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Total Value</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element?.amount | currency }}\n </td>\n </ng-container>\n\n <!-- Particulars Column -->\n <ng-container matColumnDef=\"particulars\">\n <th mat-header-cell *matHeaderCellDef>Particulars</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.stock_issue_products[0]?.particulars }}</td>\n </ng-container>\n\n <!-- Supplier Column -->\n <ng-container matColumnDef=\"supplier\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Supplier</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element?.supplier?.company_name }}\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-1\">{{ element?.creator?.name }}</p>\n <small class=\"text-secondary\">{{ element?.created_at | date }}</small>\n </td>\n </ng-container>\n\n <!-- Actions Column -->\n <ng-container matColumnDef=\"actions\">\n <th mat-header-cell *matHeaderCellDef>Actions</th>\n <td mat-cell *matCellDef=\"let element\">\n <div *ngIf=\"!element.stock_transfer\" class=\"d-flex gap-1\">\n <app-stock-issue-form-button [stockIssue]=\"element\"\n (saved)=\"reload(); listUpdated.emit()\"></app-stock-issue-form-button>\n <app-stock-issuance-delete-button [stockIssuance]=\"element\"\n (deleted)=\"reload(); listUpdated.emit()\"></app-stock-issuance-delete-button>\n </div>\n\n <span *ngIf=\"element.stock_transfer\" class=\"badge rounded-pill text-bg-secondary\">Stock Transfer</span>\n </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns\"></tr>\n </table>\n\n <mat-progress-bar *ngIf=\"isWorking\" mode=\"indeterminate\"></mat-progress-bar>\n </mat-card-content>\n</mat-card>", styles: [""], dependencies: [{ kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i7.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: i8.MatSort, selector: "[matSort]", inputs: ["matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear", "matSortDisabled"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i8.MatSortHeader, selector: "[mat-sort-header]", inputs: ["mat-sort-header", "arrowPosition", "start", "disabled", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "component", type: i9.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i9.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i9.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i9.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i9.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i9.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i9.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i9.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i9.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i9.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "component", type: i10.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i10.MatCardContent, selector: "mat-card-content" }, { kind: "directive", type: i11.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: i12.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "component", type: i13.StockIssueFormButtonComponent, selector: "app-stock-issue-form-button", inputs: ["product", "stockIssueProduct", "stockIssue", "icon", "issuableType", "issuableId"], outputs: ["saved"] }, { kind: "directive", type: i14.InfiniteScrollDirective, selector: "[infiniteScroll], [infinite-scroll], [data-infinite-scroll]", inputs: ["infiniteScrollDistance", "infiniteScrollUpDistance", "infiniteScrollThrottle", "infiniteScrollDisabled", "infiniteScrollContainer", "scrollWindow", "immediateCheck", "horizontal", "alwaysCallback", "fromRoot"], outputs: ["scrolled", "scrolledUp"] }, { kind: "component", type: i15.StockIssuanceDeleteButtonComponent, selector: "app-stock-issuance-delete-button", inputs: ["stockIssuance"], outputs: ["deleted"] }, { kind: "directive", type: i4.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: i2.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", "required", "disabled", "value"], outputs: ["selectedValueChange", "selectionChange", "itemsChange"] }, { kind: "component", type: i2.TimelineFilterComponent, selector: "app-timeline-filter", inputs: ["defaultValue", "required", "disabled", "value", "timelines", "dateFrom", "dateTo", "appearance", "showClearButton", "form", "labelText"], outputs: ["selectionChange"] }, { 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: i16.ProductCategoryBadgesComponent, selector: "app-product-category-badges", inputs: ["product"] }, { kind: "component", type: i2.ColumnSelectorComponent, selector: "app-column-selector", inputs: ["label", "mode", "columnConfigs", "selectedColumns"], outputs: ["selectedColumnsChange", "displayedColumnsChange"] }, { kind: "pipe", type: i5.CurrencyPipe, name: "currency" }, { kind: "pipe", type: i5.DatePipe, name: "date" }], preserveWhitespaces: true });
152
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: StockIssuancesListComponent, selector: "app-stock-issuances-list", inputs: { product: "product", issuableType: "issuableType", issuableId: "issuableId", label: "label", showActions: "showActions", showFilters: "showFilters" }, outputs: { listUpdated: "listUpdated" }, usesInheritance: true, ngImport: i0, template: "<mat-card *ngIf=\"!product\" class=\"mb-2\">\n <mat-card-content class=\"d-flex justify-content-between align-items-center gap-3\">\n <div class=\"d-flex justify-content-start align-items-center gap-2\">\n <h3 class=\"mb-0\">{{ label }}</h3>\n\n <app-stock-issue-form-button icon=\"add\" [issuableType]=\"issuableType\" [issuableId]=\"issuableId\"\n (saved)=\"reload()\"></app-stock-issue-form-button>\n\n <span *ngIf=\"showActions\" matTooltip=\"Import\" routerLink=\"import\"\n class=\"cursor-pointer material-symbols-outlined\">\n file_upload\n </span>\n\n <app-column-selector *ngIf=\"showActions\" mode=\"icon\" class=\"mt-2 d-print-none\" [columnConfigs]=\"columnConfig\"\n [(selectedColumns)]=\"selectedColumns\"></app-column-selector>\n </div>\n\n <form [formGroup]=\"filterForm\" *ngIf=\"showFilters\">\n <mat-form-field>\n <mat-label>Search</mat-label>\n <input matInput placeholder=\"Search products\" formControlName=\"search\" />\n </mat-form-field>\n\n <app-timeline-filter appearance=\"fill\" labelText=\"Date\" formControlName=\"duration\"\n (selectionChange)=\"onDurationChange($event)\" [showClearButton]=\"true\" [dateFrom]=\"filterForm.value?.date_from\"\n [dateTo]=\"filterForm.value?.date_to\"></app-timeline-filter>\n\n <mat-form-field>\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>\n <mat-label>Measure</mat-label>\n <app-searchable-selector apiUrl=\"api/product-measures\" formControlName=\"measure_ids\" [multiple]=\"true\">\n </app-searchable-selector>\n </mat-form-field>\n\n <mat-form-field>\n <mat-label>Location</mat-label>\n <app-searchable-selector apiUrl=\"api/inventory-locations\" formControlName=\"location_ids\" [multiple]=\"true\">\n </app-searchable-selector>\n </mat-form-field>\n </form>\n </mat-card-content>\n</mat-card>\n\n<mat-card>\n <mat-card-content *ngIf=\"product\" class=\"mb-0\">\n <div class=\"d-flex justify-content-start align-items-center gap-2 mb-2\">\n <span class=\"material-symbols-outlined\"> ungroup </span>\n <h3 class=\"mb-0\">Stock Issues</h3>\n\n <app-stock-issue-form-button class=\"mt-2\" [product]=\"product\" icon=\"add\"\n (saved)=\"reload(); listUpdated.emit()\"></app-stock-issue-form-button>\n </div>\n </mat-card-content>\n <mat-card-content class=\"p-0\">\n <table mat-table [dataSource]=\"models\" class=\"w-100\" aria-describedby=\"Stock Issuances\" infiniteScroll\n [infiniteScrollDistance]=\"2\" [infiniteScrollThrottle]=\"50\" (scrolled)=\"onScroll()\" matSort\n (matSortChange)=\"onSortChange($event)\">\n <!-- # Column -->\n <ng-container matColumnDef=\"no\">\n <th mat-header-cell *matHeaderCellDef>#</th>\n <td mat-cell *matCellDef=\"let element; let i = index\">{{ i + 1 }}</td>\n </ng-container>\n\n <!-- Product Column -->\n <ng-container matColumnDef=\"product\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Product</th>\n <td mat-cell *matCellDef=\"let element\">\n <div class=\"d-flex flex-column gap-1\">\n <a class=\"text-decoration-none text-dark\"\n [routerLink]=\"['/inventory/products', element?.stock_issue_products[0]?.product?.id, 'view']\">\n {{ element?.stock_issue_products[0]?.product.name }}\n </a>\n <app-product-category-badges\n [product]=\"element?.stock_issue_products[0]?.product\"></app-product-category-badges>\n </div>\n </td>\n </ng-container>\n\n <!-- SKU Column -->\n <ng-container matColumnDef=\"sku\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>SKU</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.stock_issue_products[0]?.product.sku }}</td>\n </ng-container>\n\n <!-- Date Column -->\n <ng-container matColumnDef=\"date\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Date</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.date | date }}</td>\n </ng-container>\n\n <!-- Location Column -->\n <ng-container matColumnDef=\"location\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Location</th>\n <td mat-cell *matCellDef=\"let element\">\n <a class=\"text-decoration-none text-dark\"\n [routerLink]=\"['/inventory/locations', element?.stock_issue_products[0]?.location_id, 'view']\">\n {{ element?.stock_issue_products[0]?.location?.title }}\n </a>\n </td>\n </ng-container>\n\n <!-- Related Column -->\n <ng-container matColumnDef=\"related\">\n <th mat-header-cell *matHeaderCellDef>Related</th>\n <td mat-cell *matCellDef=\"let element\">\n <a class=\"text-dark\" *ngIf=\"element?.issuable\" [routerLink]=\"['/maintenances', element?.issuable_id, 'view']\">\n Maintenance for {{ element?.issuable?.fixed_asset?.name }}\n </a>\n </td>\n </ng-container>\n\n <!-- Quantity Column -->\n <ng-container matColumnDef=\"quantity\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Quantity</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.stock_issue_products[0]?.quantity }} {{\n element?.stock_issue_products[0]?.product.measure?.title }}</td>\n </ng-container>\n\n <!-- Batch Column -->\n <ng-container matColumnDef=\"batch\">\n <th mat-header-cell *matHeaderCellDef>Batch</th>\n <td mat-cell *matCellDef=\"let element\">\n <p class=\"mb-0\" *ngIf=\"element?.stock_issue_products[0]?.batch?.batch_number\">{{ element?.stock_issue_products[0]?.batch?.batch_number }}</p>\n <small class=\"text-secondary\" *ngIf=\"element?.stock_issue_products[0]?.batch?.expires_on\">\n Expires {{ element?.stock_issue_products[0]?.batch?.expires_on | date }}\n </small>\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"measure\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Measure</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.stock_issue_products[0]?.product.measure?.title }}</td>\n </ng-container>\n\n <!-- Purchase Price Column -->\n <ng-container matColumnDef=\"purchase_price\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Purchase Price</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element?.purchase_price | currency }}\n </td>\n </ng-container>\n\n <!-- Total Value Column -->\n <ng-container matColumnDef=\"amount\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Total Value</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element?.amount | currency }}\n </td>\n </ng-container>\n\n <!-- Particulars Column -->\n <ng-container matColumnDef=\"particulars\">\n <th mat-header-cell *matHeaderCellDef>Particulars</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.stock_issue_products[0]?.particulars }}</td>\n </ng-container>\n\n <!-- Supplier Column -->\n <ng-container matColumnDef=\"supplier\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Supplier</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element?.supplier?.company_name }}\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-1\">{{ element?.creator?.name }}</p>\n <small class=\"text-secondary\">{{ element?.created_at | date }}</small>\n </td>\n </ng-container>\n\n <!-- Actions Column -->\n <ng-container matColumnDef=\"actions\">\n <th mat-header-cell *matHeaderCellDef>Actions</th>\n <td mat-cell *matCellDef=\"let element\">\n <div *ngIf=\"!element.stock_transfer\" class=\"d-flex gap-1\">\n <app-stock-issue-form-button [stockIssue]=\"element\"\n (saved)=\"reload(); listUpdated.emit()\"></app-stock-issue-form-button>\n <app-stock-issuance-delete-button [stockIssuance]=\"element\"\n (deleted)=\"reload(); listUpdated.emit()\"></app-stock-issuance-delete-button>\n </div>\n\n <span *ngIf=\"element.stock_transfer\" class=\"badge rounded-pill text-bg-secondary\">Stock Transfer</span>\n </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns\"></tr>\n </table>\n\n <mat-progress-bar *ngIf=\"isWorking\" mode=\"indeterminate\"></mat-progress-bar>\n </mat-card-content>\n</mat-card>", styles: [""], dependencies: [{ kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i6.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i6.MatLabel, selector: "mat-label" }, { kind: "directive", type: i7.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: i8.MatSort, selector: "[matSort]", inputs: ["matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear", "matSortDisabled"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i8.MatSortHeader, selector: "[mat-sort-header]", inputs: ["mat-sort-header", "arrowPosition", "start", "disabled", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "component", type: i9.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i9.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i9.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i9.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i9.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i9.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i9.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i9.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i9.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i9.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "component", type: i10.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i10.MatCardContent, selector: "mat-card-content" }, { kind: "directive", type: i11.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: i12.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "component", type: i13.StockIssueFormButtonComponent, selector: "app-stock-issue-form-button", inputs: ["product", "stockIssueProduct", "stockIssue", "icon", "issuableType", "issuableId"], outputs: ["saved"] }, { kind: "directive", type: i14.InfiniteScrollDirective, selector: "[infiniteScroll], [infinite-scroll], [data-infinite-scroll]", inputs: ["infiniteScrollDistance", "infiniteScrollUpDistance", "infiniteScrollThrottle", "infiniteScrollDisabled", "infiniteScrollContainer", "scrollWindow", "immediateCheck", "horizontal", "alwaysCallback", "fromRoot"], outputs: ["scrolled", "scrolledUp"] }, { kind: "component", type: i15.StockIssuanceDeleteButtonComponent, selector: "app-stock-issuance-delete-button", inputs: ["stockIssuance"], outputs: ["deleted"] }, { kind: "directive", type: i4.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: i2.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", "required", "disabled", "value"], outputs: ["selectedValueChange", "selectionChange", "itemsChange"] }, { kind: "component", type: i2.TimelineFilterComponent, selector: "app-timeline-filter", inputs: ["defaultValue", "required", "disabled", "value", "timelines", "dateFrom", "dateTo", "appearance", "showClearButton", "form", "labelText"], outputs: ["selectionChange"] }, { 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: i16.ProductCategoryBadgesComponent, selector: "app-product-category-badges", inputs: ["product"] }, { kind: "component", type: i2.ColumnSelectorComponent, selector: "app-column-selector", inputs: ["label", "mode", "columnConfigs", "selectedColumns"], outputs: ["selectedColumnsChange", "displayedColumnsChange"] }, { kind: "pipe", type: i5.CurrencyPipe, name: "currency" }, { kind: "pipe", type: i5.DatePipe, name: "date" }], preserveWhitespaces: true });
153
153
  }
154
154
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: StockIssuancesListComponent, decorators: [{
155
155
  type: Component,
156
- args: [{ selector: 'app-stock-issuances-list', template: "<mat-card *ngIf=\"!product\" class=\"mb-2\">\n <mat-card-content class=\"d-flex justify-content-between align-items-center gap-3\">\n <div class=\"d-flex justify-content-start align-items-center gap-2\">\n <h3 class=\"mb-0\">{{ label }}</h3>\n\n <app-stock-issue-form-button icon=\"add\" [issuableType]=\"issuableType\" [issuableId]=\"issuableId\"\n (saved)=\"reload()\"></app-stock-issue-form-button>\n\n <span *ngIf=\"showActions\" matTooltip=\"Import\" routerLink=\"import\"\n class=\"cursor-pointer material-symbols-outlined\">\n file_upload\n </span>\n\n <app-column-selector *ngIf=\"showActions\" mode=\"icon\" class=\"mt-2 d-print-none\" [columnConfigs]=\"columnConfig\"\n [(selectedColumns)]=\"selectedColumns\"></app-column-selector>\n </div>\n\n <form [formGroup]=\"filterForm\" *ngIf=\"showFilters\">\n <mat-form-field>\n <mat-label>Search</mat-label>\n <input matInput placeholder=\"Search products\" formControlName=\"search\" />\n </mat-form-field>\n\n <app-timeline-filter appearance=\"fill\" labelText=\"Date\" formControlName=\"duration\"\n (selectionChange)=\"onDurationChange($event)\" [showClearButton]=\"true\" [dateFrom]=\"filterForm.value?.date_from\"\n [dateTo]=\"filterForm.value?.date_to\"></app-timeline-filter>\n\n <mat-form-field>\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>\n <mat-label>Measure</mat-label>\n <app-searchable-selector apiUrl=\"api/product-measures\" formControlName=\"measure_ids\" [multiple]=\"true\">\n </app-searchable-selector>\n </mat-form-field>\n\n <mat-form-field>\n <mat-label>Location</mat-label>\n <app-searchable-selector apiUrl=\"api/inventory-locations\" formControlName=\"location_ids\" [multiple]=\"true\">\n </app-searchable-selector>\n </mat-form-field>\n </form>\n </mat-card-content>\n</mat-card>\n\n<mat-card>\n <mat-card-content *ngIf=\"product\" class=\"mb-0\">\n <div class=\"d-flex justify-content-start align-items-center gap-2 mb-2\">\n <span class=\"material-symbols-outlined\"> ungroup </span>\n <h3 class=\"mb-0\">Stock Issues</h3>\n\n <app-stock-issue-form-button class=\"mt-2\" [product]=\"product\" icon=\"add\"\n (saved)=\"reload(); listUpdated.emit()\"></app-stock-issue-form-button>\n </div>\n </mat-card-content>\n <mat-card-content class=\"p-0\">\n <table mat-table [dataSource]=\"models\" class=\"w-100\" aria-describedby=\"Stock Issuances\" infiniteScroll\n [infiniteScrollDistance]=\"2\" [infiniteScrollThrottle]=\"50\" (scrolled)=\"onScroll()\" matSort\n (matSortChange)=\"onSortChange($event)\">\n <!-- # Column -->\n <ng-container matColumnDef=\"no\">\n <th mat-header-cell *matHeaderCellDef>#</th>\n <td mat-cell *matCellDef=\"let element; let i = index\">{{ i + 1 }}</td>\n </ng-container>\n\n <!-- Product Column -->\n <ng-container matColumnDef=\"product\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Product</th>\n <td mat-cell *matCellDef=\"let element\">\n <div class=\"d-flex flex-column gap-1\">\n <a class=\"text-decoration-none text-dark\"\n [routerLink]=\"['/inventory/products', element?.stock_issue_products[0]?.product.id, 'view']\">\n {{ element?.stock_issue_products[0]?.product.name }}\n </a>\n <app-product-category-badges\n [product]=\"element?.stock_issue_products[0]?.product\"></app-product-category-badges>\n </div>\n </td>\n </ng-container>\n\n <!-- SKU Column -->\n <ng-container matColumnDef=\"sku\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>SKU</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.stock_issue_products[0]?.product.sku }}</td>\n </ng-container>\n\n <!-- Date Column -->\n <ng-container matColumnDef=\"date\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Date</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.date | date }}</td>\n </ng-container>\n\n <!-- Location Column -->\n <ng-container matColumnDef=\"location\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Location</th>\n <td mat-cell *matCellDef=\"let element\">\n <a class=\"text-decoration-none text-dark\"\n [routerLink]=\"['/inventory/locations', element?.stock_issue_products[0]?.location_id, 'view']\">\n {{ element?.stock_issue_products[0]?.location?.title }}\n </a>\n </td>\n </ng-container>\n\n <!-- Related Column -->\n <ng-container matColumnDef=\"related\">\n <th mat-header-cell *matHeaderCellDef>Related</th>\n <td mat-cell *matCellDef=\"let element\">\n <a class=\"text-dark\" *ngIf=\"element?.issuable\" [routerLink]=\"['/maintenances', element?.issuable_id, 'view']\">\n Maintenance for {{ element?.issuable?.fixed_asset?.name }}\n </a>\n </td>\n </ng-container>\n\n <!-- Quantity Column -->\n <ng-container matColumnDef=\"quantity\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Quantity</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.stock_issue_products[0]?.quantity }} {{\n element?.stock_issue_products[0]?.product.measure?.title }}</td>\n </ng-container>\n\n <!-- Batch Column -->\n <ng-container matColumnDef=\"batch\">\n <th mat-header-cell *matHeaderCellDef>Batch</th>\n <td mat-cell *matCellDef=\"let element\">\n <p class=\"mb-0\" *ngIf=\"element?.stock_issue_products[0]?.batch?.batch_number\">{{ element?.stock_issue_products[0]?.batch?.batch_number }}</p>\n <small class=\"text-secondary\" *ngIf=\"element?.stock_issue_products[0]?.batch?.expires_on\">\n Expires {{ element?.stock_issue_products[0]?.batch?.expires_on | date }}\n </small>\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"measure\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Measure</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.stock_issue_products[0]?.product.measure?.title }}</td>\n </ng-container>\n\n <!-- Purchase Price Column -->\n <ng-container matColumnDef=\"purchase_price\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Purchase Price</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element?.purchase_price | currency }}\n </td>\n </ng-container>\n\n <!-- Total Value Column -->\n <ng-container matColumnDef=\"amount\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Total Value</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element?.amount | currency }}\n </td>\n </ng-container>\n\n <!-- Particulars Column -->\n <ng-container matColumnDef=\"particulars\">\n <th mat-header-cell *matHeaderCellDef>Particulars</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.stock_issue_products[0]?.particulars }}</td>\n </ng-container>\n\n <!-- Supplier Column -->\n <ng-container matColumnDef=\"supplier\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Supplier</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element?.supplier?.company_name }}\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-1\">{{ element?.creator?.name }}</p>\n <small class=\"text-secondary\">{{ element?.created_at | date }}</small>\n </td>\n </ng-container>\n\n <!-- Actions Column -->\n <ng-container matColumnDef=\"actions\">\n <th mat-header-cell *matHeaderCellDef>Actions</th>\n <td mat-cell *matCellDef=\"let element\">\n <div *ngIf=\"!element.stock_transfer\" class=\"d-flex gap-1\">\n <app-stock-issue-form-button [stockIssue]=\"element\"\n (saved)=\"reload(); listUpdated.emit()\"></app-stock-issue-form-button>\n <app-stock-issuance-delete-button [stockIssuance]=\"element\"\n (deleted)=\"reload(); listUpdated.emit()\"></app-stock-issuance-delete-button>\n </div>\n\n <span *ngIf=\"element.stock_transfer\" class=\"badge rounded-pill text-bg-secondary\">Stock Transfer</span>\n </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns\"></tr>\n </table>\n\n <mat-progress-bar *ngIf=\"isWorking\" mode=\"indeterminate\"></mat-progress-bar>\n </mat-card-content>\n</mat-card>" }]
156
+ args: [{ selector: 'app-stock-issuances-list', template: "<mat-card *ngIf=\"!product\" class=\"mb-2\">\n <mat-card-content class=\"d-flex justify-content-between align-items-center gap-3\">\n <div class=\"d-flex justify-content-start align-items-center gap-2\">\n <h3 class=\"mb-0\">{{ label }}</h3>\n\n <app-stock-issue-form-button icon=\"add\" [issuableType]=\"issuableType\" [issuableId]=\"issuableId\"\n (saved)=\"reload()\"></app-stock-issue-form-button>\n\n <span *ngIf=\"showActions\" matTooltip=\"Import\" routerLink=\"import\"\n class=\"cursor-pointer material-symbols-outlined\">\n file_upload\n </span>\n\n <app-column-selector *ngIf=\"showActions\" mode=\"icon\" class=\"mt-2 d-print-none\" [columnConfigs]=\"columnConfig\"\n [(selectedColumns)]=\"selectedColumns\"></app-column-selector>\n </div>\n\n <form [formGroup]=\"filterForm\" *ngIf=\"showFilters\">\n <mat-form-field>\n <mat-label>Search</mat-label>\n <input matInput placeholder=\"Search products\" formControlName=\"search\" />\n </mat-form-field>\n\n <app-timeline-filter appearance=\"fill\" labelText=\"Date\" formControlName=\"duration\"\n (selectionChange)=\"onDurationChange($event)\" [showClearButton]=\"true\" [dateFrom]=\"filterForm.value?.date_from\"\n [dateTo]=\"filterForm.value?.date_to\"></app-timeline-filter>\n\n <mat-form-field>\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>\n <mat-label>Measure</mat-label>\n <app-searchable-selector apiUrl=\"api/product-measures\" formControlName=\"measure_ids\" [multiple]=\"true\">\n </app-searchable-selector>\n </mat-form-field>\n\n <mat-form-field>\n <mat-label>Location</mat-label>\n <app-searchable-selector apiUrl=\"api/inventory-locations\" formControlName=\"location_ids\" [multiple]=\"true\">\n </app-searchable-selector>\n </mat-form-field>\n </form>\n </mat-card-content>\n</mat-card>\n\n<mat-card>\n <mat-card-content *ngIf=\"product\" class=\"mb-0\">\n <div class=\"d-flex justify-content-start align-items-center gap-2 mb-2\">\n <span class=\"material-symbols-outlined\"> ungroup </span>\n <h3 class=\"mb-0\">Stock Issues</h3>\n\n <app-stock-issue-form-button class=\"mt-2\" [product]=\"product\" icon=\"add\"\n (saved)=\"reload(); listUpdated.emit()\"></app-stock-issue-form-button>\n </div>\n </mat-card-content>\n <mat-card-content class=\"p-0\">\n <table mat-table [dataSource]=\"models\" class=\"w-100\" aria-describedby=\"Stock Issuances\" infiniteScroll\n [infiniteScrollDistance]=\"2\" [infiniteScrollThrottle]=\"50\" (scrolled)=\"onScroll()\" matSort\n (matSortChange)=\"onSortChange($event)\">\n <!-- # Column -->\n <ng-container matColumnDef=\"no\">\n <th mat-header-cell *matHeaderCellDef>#</th>\n <td mat-cell *matCellDef=\"let element; let i = index\">{{ i + 1 }}</td>\n </ng-container>\n\n <!-- Product Column -->\n <ng-container matColumnDef=\"product\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Product</th>\n <td mat-cell *matCellDef=\"let element\">\n <div class=\"d-flex flex-column gap-1\">\n <a class=\"text-decoration-none text-dark\"\n [routerLink]=\"['/inventory/products', element?.stock_issue_products[0]?.product?.id, 'view']\">\n {{ element?.stock_issue_products[0]?.product.name }}\n </a>\n <app-product-category-badges\n [product]=\"element?.stock_issue_products[0]?.product\"></app-product-category-badges>\n </div>\n </td>\n </ng-container>\n\n <!-- SKU Column -->\n <ng-container matColumnDef=\"sku\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>SKU</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.stock_issue_products[0]?.product.sku }}</td>\n </ng-container>\n\n <!-- Date Column -->\n <ng-container matColumnDef=\"date\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Date</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.date | date }}</td>\n </ng-container>\n\n <!-- Location Column -->\n <ng-container matColumnDef=\"location\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Location</th>\n <td mat-cell *matCellDef=\"let element\">\n <a class=\"text-decoration-none text-dark\"\n [routerLink]=\"['/inventory/locations', element?.stock_issue_products[0]?.location_id, 'view']\">\n {{ element?.stock_issue_products[0]?.location?.title }}\n </a>\n </td>\n </ng-container>\n\n <!-- Related Column -->\n <ng-container matColumnDef=\"related\">\n <th mat-header-cell *matHeaderCellDef>Related</th>\n <td mat-cell *matCellDef=\"let element\">\n <a class=\"text-dark\" *ngIf=\"element?.issuable\" [routerLink]=\"['/maintenances', element?.issuable_id, 'view']\">\n Maintenance for {{ element?.issuable?.fixed_asset?.name }}\n </a>\n </td>\n </ng-container>\n\n <!-- Quantity Column -->\n <ng-container matColumnDef=\"quantity\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Quantity</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.stock_issue_products[0]?.quantity }} {{\n element?.stock_issue_products[0]?.product.measure?.title }}</td>\n </ng-container>\n\n <!-- Batch Column -->\n <ng-container matColumnDef=\"batch\">\n <th mat-header-cell *matHeaderCellDef>Batch</th>\n <td mat-cell *matCellDef=\"let element\">\n <p class=\"mb-0\" *ngIf=\"element?.stock_issue_products[0]?.batch?.batch_number\">{{ element?.stock_issue_products[0]?.batch?.batch_number }}</p>\n <small class=\"text-secondary\" *ngIf=\"element?.stock_issue_products[0]?.batch?.expires_on\">\n Expires {{ element?.stock_issue_products[0]?.batch?.expires_on | date }}\n </small>\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"measure\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Measure</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.stock_issue_products[0]?.product.measure?.title }}</td>\n </ng-container>\n\n <!-- Purchase Price Column -->\n <ng-container matColumnDef=\"purchase_price\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Purchase Price</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element?.purchase_price | currency }}\n </td>\n </ng-container>\n\n <!-- Total Value Column -->\n <ng-container matColumnDef=\"amount\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Total Value</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element?.amount | currency }}\n </td>\n </ng-container>\n\n <!-- Particulars Column -->\n <ng-container matColumnDef=\"particulars\">\n <th mat-header-cell *matHeaderCellDef>Particulars</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.stock_issue_products[0]?.particulars }}</td>\n </ng-container>\n\n <!-- Supplier Column -->\n <ng-container matColumnDef=\"supplier\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Supplier</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element?.supplier?.company_name }}\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-1\">{{ element?.creator?.name }}</p>\n <small class=\"text-secondary\">{{ element?.created_at | date }}</small>\n </td>\n </ng-container>\n\n <!-- Actions Column -->\n <ng-container matColumnDef=\"actions\">\n <th mat-header-cell *matHeaderCellDef>Actions</th>\n <td mat-cell *matCellDef=\"let element\">\n <div *ngIf=\"!element.stock_transfer\" class=\"d-flex gap-1\">\n <app-stock-issue-form-button [stockIssue]=\"element\"\n (saved)=\"reload(); listUpdated.emit()\"></app-stock-issue-form-button>\n <app-stock-issuance-delete-button [stockIssuance]=\"element\"\n (deleted)=\"reload(); listUpdated.emit()\"></app-stock-issuance-delete-button>\n </div>\n\n <span *ngIf=\"element.stock_transfer\" class=\"badge rounded-pill text-bg-secondary\">Stock Transfer</span>\n </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns\"></tr>\n </table>\n\n <mat-progress-bar *ngIf=\"isWorking\" mode=\"indeterminate\"></mat-progress-bar>\n </mat-card-content>\n</mat-card>" }]
157
157
  }], ctorParameters: () => [{ type: i1.FormBuilder }, { type: i2.RequestHelperService }, { type: i3.StockIssuanceService }, { type: i4.ActivatedRoute }, { type: i2.TechlifyFeatureService }], propDecorators: { product: [{
158
158
  type: Input
159
159
  }], issuableType: [{
@@ -169,4 +169,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImpo
169
169
  }], listUpdated: [{
170
170
  type: Output
171
171
  }] } });
172
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RvY2staXNzdWFuY2VzLWxpc3QuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvaW52ZW50b3J5LWNvbW1vbi9zcmMvbGliL2ludmVudG9yeS1jb21tb24vc3RvY2staXNzdWFuY2VzL3N0b2NrLWlzc3VhbmNlcy1saXN0L3N0b2NrLWlzc3VhbmNlcy1saXN0LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2ludmVudG9yeS1jb21tb24vc3JjL2xpYi9pbnZlbnRvcnktY29tbW9uL3N0b2NrLWlzc3VhbmNlcy9zdG9jay1pc3N1YW5jZXMtbGlzdC9zdG9jay1pc3N1YW5jZXMtbGlzdC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQVUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQy9FLE9BQU8sRUFFTCxrQ0FBa0MsRUFDbkMsTUFBTSxtQkFBbUIsQ0FBQztBQUUzQixPQUFPLEVBQUUsWUFBWSxFQUFFLG9CQUFvQixFQUFFLE1BQU0sTUFBTSxDQUFDO0FBSTFELE9BQU8sTUFBTSxNQUFNLFFBQVEsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBTzVCLE1BQU0sT0FBTywyQkFBNEIsU0FBUSxrQ0FBa0M7SUF5QnZFO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUE1QkQsT0FBTyxDQUFNO0lBQ2IsWUFBWSxDQUFVO0lBQ3RCLFVBQVUsQ0FBVTtJQUNwQixLQUFLLEdBQUcsY0FBYyxDQUFDO0lBQ3ZCLFdBQVcsR0FBWSxJQUFJLENBQUM7SUFDNUIsV0FBVyxHQUFZLElBQUksQ0FBQztJQUMzQixXQUFXLEdBQXNCLElBQUksWUFBWSxFQUFPLENBQUM7SUFFbkUsc0JBQXNCLEdBQWE7UUFDakMsSUFBSSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsTUFBTSxF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Q0FBQyxDQUFDLENBQUMsRUFBRTtZQUNsRSxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFO1NBQzdELEVBQ0QsRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLENBQ3JCLENBQUM7SUFDSixDQUFDO0lBRU8sWUFBWTtRQUNsQixJQUFJLGNBQWMsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLGVBQWUsQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO1FBQ2xGLDBDQUEwQztRQUMxQyxJQUFJLGNBQWMsRUFBRSxDQUFDO1lBQ25CLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDakUsSUFBSSxRQUFRLElBQUksQ0FBQyxFQUFFLENBQUM7Z0JBQ2xCLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxNQUFNLENBQUMsUUFBUSxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUM7WUFDL0QsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO3dHQS9JVSwyQkFBMkI7NEZBQTNCLDJCQUEyQixnU0NqQnhDLGk4UkF1TVc7OzRGRHRMRSwyQkFBMkI7a0JBTHZDLFNBQVM7K0JBQ0UsMEJBQTBCO3dOQUszQixPQUFPO3NCQUFmLEtBQUs7Z0JBQ0csWUFBWTtzQkFBcEIsS0FBSztnQkFDRyxVQUFVO3NCQUFsQixLQUFLO2dCQUNHLEtBQUs7c0JBQWIsS0FBSztnQkFDRyxXQUFXO3NCQUFuQixLQUFLO2dCQUNHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBQ0ksV0FBVztzQkFBcEIsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgRXZlbnRFbWl0dGVyLCBJbnB1dCwgT25Jbml0LCBPdXRwdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7XG4gIENvbHVtbkNvbmZpZywgUmVxdWVzdEhlbHBlclNlcnZpY2UsIFRlY2hsaWZ5RmVhdHVyZVNlcnZpY2UsXG4gIFRlY2hsaWZ5TGlzdGluZ0NvbnRyb2xsZXJJbnRlcmZhY2UsIFRpbWVsaW5lVmFsdWVcbn0gZnJvbSAnbmd4LXRlY2hsaWZ5LWNvcmUnO1xuaW1wb3J0IHsgRm9ybUJ1aWxkZXIsIEZvcm1Hcm91cCB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IGRlYm91bmNlVGltZSwgZGlzdGluY3RVbnRpbENoYW5nZWQgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IFNvcnQgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9zb3J0JztcbmltcG9ydCB7IFN0b2NrSXNzdWFuY2VTZXJ2aWNlIH0gZnJvbSAnLi4vc3RvY2staXNzdWFuY2Uuc2VydmljZSc7XG5pbXBvcnQgeyBBY3RpdmF0ZWRSb3V0ZSB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgbW9tZW50IGZyb20gJ21vbWVudCc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2FwcC1zdG9jay1pc3N1YW5jZXMtbGlzdCcsXG4gIHRlbXBsYXRlVXJsOiAnLi9zdG9jay1pc3N1YW5jZXMtbGlzdC5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL3N0b2NrLWlzc3VhbmNlcy1saXN0LmNvbXBvbmVudC5zY3NzJ10sXG59KVxuZXhwb3J0IGNsYXNzIFN0b2NrSXNzdWFuY2VzTGlzdENvbXBvbmVudCBleHRlbmRzIFRlY2hsaWZ5TGlzdGluZ0NvbnRyb2xsZXJJbnRlcmZhY2UgaW1wbGVtZW50cyBPbkluaXQge1xuICBASW5wdXQoKSBwcm9kdWN0OiBhbnk7XG4gIEBJbnB1dCgpIGlzc3VhYmxlVHlwZSE6IHN0cmluZztcbiAgQElucHV0KCkgaXNzdWFibGVJZCE6IG51bWJlcjtcbiAgQElucHV0KCkgbGFiZWwgPSAnU3RvY2sgSXNzdWVzJztcbiAgQElucHV0KCkgc2hvd0FjdGlvbnM6IGJvb2xlYW4gPSB0cnVlO1xuICBASW5wdXQoKSBzaG93RmlsdGVyczogYm9vbGVhbiA9IHRydWU7XG4gIEBPdXRwdXQoKSBsaXN0VXBkYXRlZDogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcblxuICBkZWZhdWx0U2VsZWN0ZWRDb2x1bW5zOiBzdHJpbmdbXSA9IFtcbiAgICAnbm8nLCAncHJvZHVjdCcsICdza3UnLCAnZGF0ZScsICdxdWFudGl0eScsICdtZWFzdXJlJywgJ2xvY2F0aW9uJywgJ3JlbGF0ZWQnLCAncGFydGljdWxhcnMnLFxuICBdO1xuXG4gIGNvbHVtbkNvbmZpZzogQ29sdW1uQ29uZmlnW10gPSBbXG4gICAgeyBsYWJlbDogJ0NyZWF0b3InLCBkZWY6ICdjcmVhdG9yJywgaXNTZWxlY3RlZDogZmFsc2UsIGlzRWRpdGFibGU6IHRydWUgfSxcbiAgXTtcblxuICBzZWxlY3RlZENvbHVtbnM6IENvbHVtbkNvbmZpZ1tdID0gdGhpcy5jb2x1bW5Db25maWcuZmlsdGVyKGNvbCA9PiBjb2wuaXNTZWxlY3RlZCk7XG5cbiAgZ2V0IGRpc3BsYXllZENvbHVtbnMoKTogc3RyaW5nW10ge1xuICAgIGNvbnN0IHNlbGVjdGVkQ29sdW1uczogc3RyaW5nW10gPSB0aGlzLnNlbGVjdGVkQ29sdW1ucy5tYXAoY29sID0+IGNvbC5kZWYpO1xuICAgIHJldHVybiB0aGlzLmRlZmF1bHRTZWxlY3RlZENvbHVtbnMuY29uY2F0KC4uLnNlbGVjdGVkQ29sdW1ucywgJ2FjdGlvbnMnKTtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgZm9ybUJ1aWxkZXI6IEZvcm1CdWlsZGVyLFxuICAgIHByaXZhdGUgcmVxdWVzdEhlbHBlclNlcnZpY2U6IFJlcXVlc3RIZWxwZXJTZXJ2aWNlLFxuICAgIHByaXZhdGUgc3RvY2tJc3N1YW5jZVNlcnZpY2U6IFN0b2NrSXNzdWFuY2VTZXJ2aWNlLFxuICAgIHByaXZhdGUgYWN0aXZhdGVkUm91dGU6IEFjdGl2YXRlZFJvdXRlLFxuICAgIHByaXZhdGUgZmVhdHVyZVNlcnZpY2U6IFRlY2hsaWZ5RmVhdHVyZVNlcnZpY2VcbiAgKSB7XG4gICAgc3VwZXIoKTtcbiAgICB0aGlzLmxhc3RQYWdlID0gMDtcbiAgICB0aGlzLmZpbHRlckZvcm0gPSB0aGlzLmZvcm1CdWlsZGVyLmdyb3VwKHtcbiAgICAgIGNhdGVnb3J5X2lkczogWycnXSxcbiAgICAgIGRhdGVfZnJvbTogWycnXSxcbiAgICAgIGRhdGVfdG86IFsnJ10sXG4gICAgICBkdXJhdGlvbjogWycnXSxcbiAgICAgIGltcG9ydF9pZDogWycnXSxcbiAgICAgIGxvY2F0aW9uX2lkczogWycnXSxcbiAgICAgIG1lYXN1cmVfaWRzOiBbJyddLFxuICAgICAgcHJvZHVjdF9pZHM6IFsnJ10sXG4gICAgICBzZWFyY2g6IFsnJ10sXG4gICAgICBzb3J0X2J5OiBbJ2RhdGV8ZGVzYyddLFxuICAgIH0pO1xuICB9XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5sb2FkRmVhdHVyZXMoKTtcbiAgICBpZiAodGhpcy5wcm9kdWN0KSB7XG4gICAgICB0aGlzLmZpbHRlckZvcm0uZ2V0KCdwcm9kdWN0X2lkcycpPy5zZXRWYWx1ZSh0aGlzLnByb2R1Y3Q/LmlkKTtcbiAgICAgIHRoaXMuZGVmYXVsdFNlbGVjdGVkQ29sdW1ucyA9IHRoaXMuZGVmYXVsdFNlbGVjdGVkQ29sdW1ucy5maWx0ZXIoYyA9PiBjICE9PSAncHJvZHVjdCcgJiYgYyAhPT0gJ3NrdScpO1xuICAgIH1cblxuICAgIHRoaXMudXBkYXRlRm9ybVdpdGhRdWVyeVBhcmFtcygpO1xuICAgIHRoaXMuc3Vic2NyaWJlVG9Gb3JtQ2hhbmdlcygpO1xuICAgIHRoaXMuc3Vic2NyaWJlVG9Sb3V0ZUNoYW5nZXMoKTtcbiAgfVxuXG4gIGxvYWREYXRhKCk6IHZvaWQge1xuICAgIGNvbnN0IHBhcmFtczogYW55ID0ge1xuICAgICAgcGFnZTogdGhpcy5wYWdlLFxuICAgICAgcGVyUGFnZTogdGhpcy5wZXJQYWdlLFxuICAgICAgd2l0aDogYGNyZWF0b3IsaXNzdWFibGUuZml4ZWRBc3NldCxzdG9ja0lzc3VlUHJvZHVjdHMucHJvZHVjdCxzdG9ja0lzc3VlUHJvZHVjdHMubG9jYXRpb24sc3RvY2tJc3N1ZVByb2R1Y3RzLnByb2R1Y3QuY2F0ZWdvcmllcyxzdG9ja1RyYW5zZmVyLHN0b2NrSXNzdWVQcm9kdWN0cy5iYXRjaGAsXG4gICAgICAuLi50aGlzLnJlcXVlc3RIZWxwZXJTZXJ2aWNlLmNvbnZlcnRUb0Zvcm1EYXRhKHRoaXMuZmlsdGVyRm9ybS52YWx1ZSksXG4gICAgfTtcbiAgICBpZiAodGhpcy5pc3N1YWJsZUlkICYmIHRoaXMuaXNzdWFibGVUeXBlKSB7XG4gICAgICBwYXJhbXMuaXNzdWFibGVfaWRzID0gdGhpcy5pc3N1YWJsZUlkO1xuICAgICAgcGFyYW1zLmlzc3VhYmxlX3R5cGVzID0gdGhpcy5pc3N1YWJsZVR5cGU7XG4gICAgfVxuICAgIHRoaXMuaXNXb3JraW5nID0gdHJ1ZTtcbiAgICB0aGlzLnN0b2NrSXNzdWFuY2VTZXJ2aWNlLmluZGV4KHBhcmFtcykuc3Vic2NyaWJlKHtcbiAgICAgIG5leHQ6IChyZXNwb25zZTogYW55KSA9PiB7XG4gICAgICAgIHRoaXMubW9kZWxzID0gdGhpcy5tb2RlbHMuY29uY2F0KHJlc3BvbnNlPy5kYXRhKTtcbiAgICAgICAgdGhpcy5sYXN0UGFnZSA9IHJlc3BvbnNlPy5sYXN0X3BhZ2U7XG4gICAgICAgIHRoaXMuaXNXb3JraW5nID0gZmFsc2U7XG4gICAgICB9LFxuICAgICAgZXJyb3I6ICgpID0+IHtcbiAgICAgICAgdGhpcy5pc1dvcmtpbmcgPSBmYWxzZTtcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICBvblNvcnRDaGFuZ2Uoc29ydDogU29ydCkge1xuICAgIGxldCB7IGFjdGl2ZSwgZGlyZWN0aW9uIH0gPSBzb3J0O1xuICAgIGlmICghYWN0aXZlKSB7XG4gICAgICBhY3RpdmUgPSAnZGF0ZSc7XG4gICAgfVxuICAgIGlmICghZGlyZWN0aW9uKSB7XG4gICAgICBkaXJlY3Rpb24gPSAnZGVzYyc7XG4gICAgICBhY3RpdmUgPSAnZGF0ZSc7XG4gICAgfVxuICAgIHRoaXMuZmlsdGVyRm9ybS5nZXQoJ3NvcnRfYnknKS5zZXRWYWx1ZShhY3RpdmUgKyAnfCcgKyBkaXJlY3Rpb24pO1xuICB9XG5cbiAgcHJpdmF0ZSB1cGRhdGVGb3JtV2l0aFF1ZXJ5UGFyYW1zKCk6IHZvaWQge1xuICAgIHRoaXMucmVxdWVzdEhlbHBlclNlcnZpY2UudXBkYXRlRm9ybVdpdGhRdWVyeVBhcmFtcyh0aGlzLmZpbHRlckZvcm0sIHtcbiAgICAgIHByb2R1Y3RfaWRzOiB7IG11bHRpcGxlOiB0cnVlIH0sXG4gICAgICBtZWFzdXJlX2lkczogeyBtdWx0aXBsZTogdHJ1ZSB9LFxuICAgICAgY2F0ZWdvcnlfaWRzOiB7IG11bHRpcGxlOiB0cnVlIH0sXG4gICAgICBzdXBwbGllcl9pZHM6IHsgbXVsdGlwbGU6IHRydWUgfSxcbiAgICAgIGxvY2F0aW9uX2lkczogeyBtdWx0aXBsZTogdHJ1ZSB9LFxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBzdWJzY3JpYmVUb0Zvcm1DaGFuZ2VzKCk6IHZvaWQge1xuICAgICh0aGlzLmZpbHRlckZvcm0gYXMgRm9ybUdyb3VwKS52YWx1ZUNoYW5nZXMucGlwZShkZWJvdW5jZVRpbWUoODAwKSkuc3Vic2NyaWJlKHtcbiAgICAgIG5leHQ6ICgpID0+IHtcbiAgICAgICAgdGhpcy5yZXF1ZXN0SGVscGVyU2VydmljZS51cGRhdGVRdWVyeVBhcmFtcyhcbiAgICAgICAgICB0aGlzLnJlcXVlc3RIZWxwZXJTZXJ2aWNlLmNvbnZlcnRUb0Zvcm1EYXRhKHRoaXMuZmlsdGVyRm9ybS52YWx1ZSlcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgc3Vic2NyaWJlVG9Sb3V0ZUNoYW5nZXMoKTogdm9pZCB7XG4gICAgdGhpcy5hY3RpdmF0ZWRSb3V0ZS5xdWVyeVBhcmFtc1xuICAgICAgLnBpcGUoZGVib3VuY2VUaW1lKDUwMCksIGRpc3RpbmN0VW50aWxDaGFuZ2VkKCkpXG4gICAgICAuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgdGhpcy5yZWxvYWQoKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgb25EdXJhdGlvbkNoYW5nZSh0aW1lbGluZVZhbHVlOiBUaW1lbGluZVZhbHVlKSB7XG4gICAgbGV0IHsgZGF0ZV90bywgZGF0ZV9mcm9tIH0gPSB0aW1lbGluZVZhbHVlO1xuICAgIHRoaXMuZmlsdGVyRm9ybS5wYXRjaFZhbHVlKFxuICAgICAge1xuICAgICAgICBkYXRlX2Zyb206IGRhdGVfZnJvbSA/IG1vbWVudChkYXRlX2Zyb20pLmZvcm1hdChcIllZWVktTU0tRERcIikgOiBcIlwiLFxuICAgICAgICBkYXRlX3RvOiBkYXRlX3RvID8gbW9tZW50KGRhdGVfdG8pLmZvcm1hdChcIllZWVktTU0tRERcIikgOiBcIlwiLFxuICAgICAgfSxcbiAgICAgIHsgZW1pdEV2ZW50OiBmYWxzZSB9XG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgbG9hZEZlYXR1cmVzKCkge1xuICAgIGxldCBpc0JhdGNoRW5hYmxlZCA9IHRoaXMuZmVhdHVyZVNlcnZpY2UuaXNGZWF0dXJlRXhpc3RzKCdwcm9kdWN0LWJhdGNoLW51bWJlcnMnKTtcbiAgICAvLyBub3cgdXBkYXRlIGRpc3BsYXllZENvbHVtbnMgYWNjb3JkaW5nbHlcbiAgICBpZiAoaXNCYXRjaEVuYWJsZWQpIHtcbiAgICAgIGNvbnN0IHF0eUluZGV4ID0gdGhpcy5kZWZhdWx0U2VsZWN0ZWRDb2x1bW5zLmluZGV4T2YoJ3F1YW50aXR5Jyk7XG4gICAgICBpZiAocXR5SW5kZXggPj0gMCkge1xuICAgICAgICB0aGlzLmRlZmF1bHRTZWxlY3RlZENvbHVtbnMuc3BsaWNlKHF0eUluZGV4ICsgMSwgMCwgJ2JhdGNoJyk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG4iLCI8bWF0LWNhcmQgKm5nSWY9XCIhcHJvZHVjdFwiIGNsYXNzPVwibWItMlwiPlxuICA8bWF0LWNhcmQtY29udGVudCBjbGFzcz1cImQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtYmV0d2VlbiBhbGlnbi1pdGVtcy1jZW50ZXIgZ2FwLTNcIj5cbiAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGp1c3RpZnktY29udGVudC1zdGFydCBhbGlnbi1pdGVtcy1jZW50ZXIgZ2FwLTJcIj5cbiAgICAgIDxoMyBjbGFzcz1cIm1iLTBcIj57eyBsYWJlbCB9fTwvaDM+XG5cbiAgICAgIDxhcHAtc3RvY2staXNzdWUtZm9ybS1idXR0b24gaWNvbj1cImFkZFwiIFtpc3N1YWJsZVR5cGVdPVwiaXNzdWFibGVUeXBlXCIgW2lzc3VhYmxlSWRdPVwiaXNzdWFibGVJZFwiXG4gICAgICAgIChzYXZlZCk9XCJyZWxvYWQoKVwiPjwvYXBwLXN0b2NrLWlzc3VlLWZvcm0tYnV0dG9uPlxuXG4gICAgICA8c3BhbiAqbmdJZj1cInNob3dBY3Rpb25zXCIgbWF0VG9vbHRpcD1cIkltcG9ydFwiIHJvdXRlckxpbms9XCJpbXBvcnRcIlxuICAgICAgICBjbGFzcz1cImN1cnNvci1wb2ludGVyIG1hdGVyaWFsLXN5bWJvbHMtb3V0bGluZWRcIj5cbiAgICAgICAgZmlsZV91cGxvYWRcbiAgICAgIDwvc3Bhbj5cblxuICAgICAgPGFwcC1jb2x1bW4tc2VsZWN0b3IgKm5nSWY9XCJzaG93QWN0aW9uc1wiIG1vZGU9XCJpY29uXCIgY2xhc3M9XCJtdC0yIGQtcHJpbnQtbm9uZVwiIFtjb2x1bW5Db25maWdzXT1cImNvbHVtbkNvbmZpZ1wiXG4gICAgICAgIFsoc2VsZWN0ZWRDb2x1bW5zKV09XCJzZWxlY3RlZENvbHVtbnNcIj48L2FwcC1jb2x1bW4tc2VsZWN0b3I+XG4gICAgPC9kaXY+XG5cbiAgICA8Zm9ybSBbZm9ybUdyb3VwXT1cImZpbHRlckZvcm1cIiAqbmdJZj1cInNob3dGaWx0ZXJzXCI+XG4gICAgICA8bWF0LWZvcm0tZmllbGQ+XG4gICAgICAgIDxtYXQtbGFiZWw+U2VhcmNoPC9tYXQtbGFiZWw+XG4gICAgICAgIDxpbnB1dCBtYXRJbnB1dCBwbGFjZWhvbGRlcj1cIlNlYXJjaCBwcm9kdWN0c1wiIGZvcm1Db250cm9sTmFtZT1cInNlYXJjaFwiIC8+XG4gICAgICA8L21hdC1mb3JtLWZpZWxkPlxuXG4gICAgICA8YXBwLXRpbWVsaW5lLWZpbHRlciBhcHBlYXJhbmNlPVwiZmlsbFwiIGxhYmVsVGV4dD1cIkRhdGVcIiBmb3JtQ29udHJvbE5hbWU9XCJkdXJhdGlvblwiXG4gICAgICAgIChzZWxlY3Rpb25DaGFuZ2UpPVwib25EdXJhdGlvbkNoYW5nZSgkZXZlbnQpXCIgW3Nob3dDbGVhckJ1dHRvbl09XCJ0cnVlXCIgW2RhdGVGcm9tXT1cImZpbHRlckZvcm0udmFsdWU/LmRhdGVfZnJvbVwiXG4gICAgICAgIFtkYXRlVG9dPVwiZmlsdGVyRm9ybS52YWx1ZT8uZGF0ZV90b1wiPjwvYXBwLXRpbWVsaW5lLWZpbHRlcj5cblxuICAgICAgPG1hdC1mb3JtLWZpZWxkPlxuICAgICAgICA8bWF0LWxhYmVsPkNhdGVnb3J5PC9tYXQtbGFiZWw+XG4gICAgICAgIDxhcHAtc2VhcmNoYWJsZS1zZWxlY3RvciBhcGlVcmw9XCJhcGkvcHJvZHVjdC1jYXRlZ29yaWVzXCIgZm9ybUNvbnRyb2xOYW1lPVwiY2F0ZWdvcnlfaWRzXCIgW211bHRpcGxlXT1cInRydWVcIj5cbiAgICAgICAgPC9hcHAtc2VhcmNoYWJsZS1zZWxlY3Rvcj5cbiAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG5cbiAgICAgIDxtYXQtZm9ybS1maWVsZD5cbiAgICAgICAgPG1hdC1sYWJlbD5NZWFzdXJlPC9tYXQtbGFiZWw+XG4gICAgICAgIDxhcHAtc2VhcmNoYWJsZS1zZWxlY3RvciBhcGlVcmw9XCJhcGkvcHJvZHVjdC1tZWFzdXJlc1wiIGZvcm1Db250cm9sTmFtZT1cIm1lYXN1cmVfaWRzXCIgW211bHRpcGxlXT1cInRydWVcIj5cbiAgICAgICAgPC9hcHAtc2VhcmNoYWJsZS1zZWxlY3Rvcj5cbiAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG5cbiAgICAgIDxtYXQtZm9ybS1maWVsZD5cbiAgICAgICAgPG1hdC1sYWJlbD5Mb2NhdGlvbjwvbWF0LWxhYmVsPlxuICAgICAgICA8YXBwLXNlYXJjaGFibGUtc2VsZWN0b3IgYXBpVXJsPVwiYXBpL2ludmVudG9yeS1sb2NhdGlvbnNcIiBmb3JtQ29udHJvbE5hbWU9XCJsb2NhdGlvbl9pZHNcIiBbbXVsdGlwbGVdPVwidHJ1ZVwiPlxuICAgICAgICA8L2FwcC1zZWFyY2hhYmxlLXNlbGVjdG9yPlxuICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICA8L2Zvcm0+XG4gIDwvbWF0LWNhcmQtY29udGVudD5cbjwvbWF0LWNhcmQ+XG5cbjxtYXQtY2FyZD5cbiAgPG1hdC1jYXJkLWNvbnRlbnQgKm5nSWY9XCJwcm9kdWN0XCIgY2xhc3M9XCJtYi0wXCI+XG4gICAgPGRpdiBjbGFzcz1cImQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtc3RhcnQgYWxpZ24taXRlbXMtY2VudGVyIGdhcC0yIG1iLTJcIj5cbiAgICAgIDxzcGFuIGNsYXNzPVwibWF0ZXJpYWwtc3ltYm9scy1vdXRsaW5lZFwiPiB1bmdyb3VwIDwvc3Bhbj5cbiAgICAgIDxoMyBjbGFzcz1cIm1iLTBcIj5TdG9jayBJc3N1ZXM8L2gzPlxuXG4gICAgICA8YXBwLXN0b2NrLWlzc3VlLWZvcm0tYnV0dG9uIGNsYXNzPVwibXQtMlwiIFtwcm9kdWN0XT1cInByb2R1Y3RcIiBpY29uPVwiYWRkXCJcbiAgICAgICAgKHNhdmVkKT1cInJlbG9hZCgpOyBsaXN0VXBkYXRlZC5lbWl0KClcIj48L2FwcC1zdG9jay1pc3N1ZS1mb3JtLWJ1dHRvbj5cbiAgICA8L2Rpdj5cbiAgPC9tYXQtY2FyZC1jb250ZW50PlxuICA8bWF0LWNhcmQtY29udGVudCBjbGFzcz1cInAtMFwiPlxuICAgIDx0YWJsZSBtYXQtdGFibGUgW2RhdGFTb3VyY2VdPVwibW9kZWxzXCIgY2xhc3M9XCJ3LTEwMFwiIGFyaWEtZGVzY3JpYmVkYnk9XCJTdG9jayBJc3N1YW5jZXNcIiBpbmZpbml0ZVNjcm9sbFxuICAgICAgW2luZmluaXRlU2Nyb2xsRGlzdGFuY2VdPVwiMlwiIFtpbmZpbml0ZVNjcm9sbFRocm90dGxlXT1cIjUwXCIgKHNjcm9sbGVkKT1cIm9uU2Nyb2xsKClcIiBtYXRTb3J0XG4gICAgICAobWF0U29ydENoYW5nZSk9XCJvblNvcnRDaGFuZ2UoJGV2ZW50KVwiPlxuICAgICAgPCEtLSAjIENvbHVtbiAtLT5cbiAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwibm9cIj5cbiAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZj4jPC90aD5cbiAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IGVsZW1lbnQ7IGxldCBpID0gaW5kZXhcIj57eyBpICsgMSB9fTwvdGQ+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgPCEtLSBQcm9kdWN0IENvbHVtbiAtLT5cbiAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwicHJvZHVjdFwiPlxuICAgICAgICA8dGggbWF0LWhlYWRlci1jZWxsICptYXRIZWFkZXJDZWxsRGVmIG1hdC1zb3J0LWhlYWRlcj5Qcm9kdWN0PC90aD5cbiAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IGVsZW1lbnRcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGZsZXgtY29sdW1uIGdhcC0xXCI+XG4gICAgICAgICAgICA8YSBjbGFzcz1cInRleHQtZGVjb3JhdGlvbi1ub25lIHRleHQtZGFya1wiXG4gICAgICAgICAgICAgIFtyb3V0ZXJMaW5rXT1cIlsnL2ludmVudG9yeS9wcm9kdWN0cycsIGVsZW1lbnQ/LnN0b2NrX2lzc3VlX3Byb2R1Y3RzWzBdPy5wcm9kdWN0LmlkLCAndmlldyddXCI+XG4gICAgICAgICAgICAgIHt7IGVsZW1lbnQ/LnN0b2NrX2lzc3VlX3Byb2R1Y3RzWzBdPy5wcm9kdWN0Lm5hbWUgfX1cbiAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgIDxhcHAtcHJvZHVjdC1jYXRlZ29yeS1iYWRnZXNcbiAgICAgICAgICAgICAgW3Byb2R1Y3RdPVwiZWxlbWVudD8uc3RvY2tfaXNzdWVfcHJvZHVjdHNbMF0/LnByb2R1Y3RcIj48L2FwcC1wcm9kdWN0LWNhdGVnb3J5LWJhZGdlcz5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC90ZD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8IS0tIFNLVSBDb2x1bW4gLS0+XG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cInNrdVwiPlxuICAgICAgICA8dGggbWF0LWhlYWRlci1jZWxsICptYXRIZWFkZXJDZWxsRGVmIG1hdC1zb3J0LWhlYWRlcj5TS1U8L3RoPlxuICAgICAgICA8dGQgbWF0LWNlbGwgKm1hdENlbGxEZWY9XCJsZXQgZWxlbWVudFwiPnt7IGVsZW1lbnQ/LnN0b2NrX2lzc3VlX3Byb2R1Y3RzWzBdPy5wcm9kdWN0LnNrdSB9fTwvdGQ+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgPCEtLSBEYXRlIENvbHVtbiAtLT5cbiAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwiZGF0ZVwiPlxuICAgICAgICA8dGggbWF0LWhlYWRlci1jZWxsICptYXRIZWFkZXJDZWxsRGVmIG1hdC1zb3J0LWhlYWRlcj5EYXRlPC90aD5cbiAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IGVsZW1lbnRcIj57eyBlbGVtZW50Py5kYXRlIHwgZGF0ZSB9fTwvdGQ+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgPCEtLSBMb2NhdGlvbiBDb2x1bW4gLS0+XG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cImxvY2F0aW9uXCI+XG4gICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgKm1hdEhlYWRlckNlbGxEZWYgbWF0LXNvcnQtaGVhZGVyPkxvY2F0aW9uPC90aD5cbiAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IGVsZW1lbnRcIj5cbiAgICAgICAgICA8YSBjbGFzcz1cInRleHQtZGVjb3JhdGlvbi1ub25lIHRleHQtZGFya1wiXG4gICAgICAgICAgICBbcm91dGVyTGlua109XCJbJy9pbnZlbnRvcnkvbG9jYXRpb25zJywgZWxlbWVudD8uc3RvY2tfaXNzdWVfcHJvZHVjdHNbMF0/LmxvY2F0aW9uX2lkLCAndmlldyddXCI+XG4gICAgICAgICAgICB7eyBlbGVtZW50Py5zdG9ja19pc3N1ZV9wcm9kdWN0c1swXT8ubG9jYXRpb24/LnRpdGxlIH19XG4gICAgICAgICAgPC9hPlxuICAgICAgICA8L3RkPlxuICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDwhLS0gUmVsYXRlZCBDb2x1bW4gLS0+XG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cInJlbGF0ZWRcIj5cbiAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZj5SZWxhdGVkPC90aD5cbiAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IGVsZW1lbnRcIj5cbiAgICAgICAgICA8YSBjbGFzcz1cInRleHQtZGFya1wiICpuZ0lmPVwiZWxlbWVudD8uaXNzdWFibGVcIiBbcm91dGVyTGlua109XCJbJy9tYWludGVuYW5jZXMnLCBlbGVtZW50Py5pc3N1YWJsZV9pZCwgJ3ZpZXcnXVwiPlxuICAgICAgICAgICAgTWFpbnRlbmFuY2UgZm9yIHt7IGVsZW1lbnQ/Lmlzc3VhYmxlPy5maXhlZF9hc3NldD8ubmFtZSB9fVxuICAgICAgICAgIDwvYT5cbiAgICAgICAgPC90ZD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8IS0tIFF1YW50aXR5IENvbHVtbiAtLT5cbiAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwicXVhbnRpdHlcIj5cbiAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZiBtYXQtc29ydC1oZWFkZXI+UXVhbnRpdHk8L3RoPlxuICAgICAgICA8dGQgbWF0LWNlbGwgKm1hdENlbGxEZWY9XCJsZXQgZWxlbWVudFwiPnt7IGVsZW1lbnQ/LnN0b2NrX2lzc3VlX3Byb2R1Y3RzWzBdPy5xdWFudGl0eSB9fSB7e1xuICAgICAgICAgIGVsZW1lbnQ/LnN0b2NrX2lzc3VlX3Byb2R1Y3RzWzBdPy5wcm9kdWN0Lm1lYXN1cmU/LnRpdGxlIH19PC90ZD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8IS0tIEJhdGNoIENvbHVtbiAtLT5cbiAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwiYmF0Y2hcIj5cbiAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZj5CYXRjaDwvdGg+XG4gICAgICAgIDx0ZCBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCBlbGVtZW50XCI+XG4gICAgICAgICAgPHAgY2xhc3M9XCJtYi0wXCIgKm5nSWY9XCJlbGVtZW50Py5zdG9ja19pc3N1ZV9wcm9kdWN0c1swXT8uYmF0Y2g/LmJhdGNoX251bWJlclwiPnt7IGVsZW1lbnQ/LnN0b2NrX2lzc3VlX3Byb2R1Y3RzWzBdPy5iYXRjaD8uYmF0Y2hfbnVtYmVyIH19PC9wPlxuICAgICAgICAgIDxzbWFsbCBjbGFzcz1cInRleHQtc2Vjb25kYXJ5XCIgKm5nSWY9XCJlbGVtZW50Py5zdG9ja19pc3N1ZV9wcm9kdWN0c1swXT8uYmF0Y2g/LmV4cGlyZXNfb25cIj5cbiAgICAgICAgICAgIEV4cGlyZXMge3sgZWxlbWVudD8uc3RvY2tfaXNzdWVfcHJvZHVjdHNbMF0/LmJhdGNoPy5leHBpcmVzX29uIHwgZGF0ZSB9fVxuICAgICAgICAgIDwvc21hbGw+XG4gICAgICAgIDwvdGQ+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJtZWFzdXJlXCI+XG4gICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgKm1hdEhlYWRlckNlbGxEZWYgbWF0LXNvcnQtaGVhZGVyPk1lYXN1cmU8L3RoPlxuICAgICAgICA8dGQgbWF0LWNlbGwgKm1hdENlbGxEZWY9XCJsZXQgZWxlbWVudFwiPnt7IGVsZW1lbnQ/LnN0b2NrX2lzc3VlX3Byb2R1Y3RzWzBdPy5wcm9kdWN0Lm1lYXN1cmU/LnRpdGxlIH19PC90ZD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8IS0tIFB1cmNoYXNlIFByaWNlIENvbHVtbiAtLT5cbiAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwicHVyY2hhc2VfcHJpY2VcIj5cbiAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZiBtYXQtc29ydC1oZWFkZXI+UHVyY2hhc2UgUHJpY2U8L3RoPlxuICAgICAgICA8dGQgbWF0LWNlbGwgKm1hdENlbGxEZWY9XCJsZXQgZWxlbWVudFwiPlxuICAgICAgICAgIHt7IGVsZW1lbnQ/LnB1cmNoYXNlX3ByaWNlIHwgY3VycmVuY3kgfX1cbiAgICAgICAgPC90ZD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8IS0tIFRvdGFsIFZhbHVlIENvbHVtbiAtLT5cbiAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwiYW1vdW50XCI+XG4gICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgKm1hdEhlYWRlckNlbGxEZWYgbWF0LXNvcnQtaGVhZGVyPlRvdGFsIFZhbHVlPC90aD5cbiAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IGVsZW1lbnRcIj5cbiAgICAgICAgICB7eyBlbGVtZW50Py5hbW91bnQgfCBjdXJyZW5jeSB9fVxuICAgICAgICA8L3RkPlxuICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDwhLS0gUGFydGljdWxhcnMgQ29sdW1uIC0tPlxuICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJwYXJ0aWN1bGFyc1wiPlxuICAgICAgICA8dGggbWF0LWhlYWRlci1jZWxsICptYXRIZWFkZXJDZWxsRGVmPlBhcnRpY3VsYXJzPC90aD5cbiAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IGVsZW1lbnRcIj57eyBlbGVtZW50Py5zdG9ja19pc3N1ZV9wcm9kdWN0c1swXT8ucGFydGljdWxhcnMgfX08L3RkPlxuICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDwhLS0gU3VwcGxpZXIgQ29sdW1uIC0tPlxuICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJzdXBwbGllclwiPlxuICAgICAgICA8dGggbWF0LWhlYWRlci1jZWxsICptYXRIZWFkZXJDZWxsRGVmIG1hdC1zb3J0LWhlYWRlcj5TdXBwbGllcjwvdGg+XG4gICAgICAgIDx0ZCBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCBlbGVtZW50XCI+XG4gICAgICAgICAge3sgZWxlbWVudD8uc3VwcGxpZXI/LmNvbXBhbnlfbmFtZSB9fVxuICAgICAgICA8L3RkPlxuICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDwhLS0gQ3JlYXRvciBDb2x1bW4gLS0+XG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cImNyZWF0b3JcIj5cbiAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZj5DcmVhdG9yPC90aD5cbiAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IGVsZW1lbnRcIj5cbiAgICAgICAgICA8cCBjbGFzcz1cIm1iLTFcIj57eyBlbGVtZW50Py5jcmVhdG9yPy5uYW1lIH19PC9wPlxuICAgICAgICAgIDxzbWFsbCBjbGFzcz1cInRleHQtc2Vjb25kYXJ5XCI+e3sgZWxlbWVudD8uY3JlYXRlZF9hdCB8IGRhdGUgfX08L3NtYWxsPlxuICAgICAgICA8L3RkPlxuICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDwhLS0gQWN0aW9ucyBDb2x1bW4gLS0+XG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cImFjdGlvbnNcIj5cbiAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZj5BY3Rpb25zPC90aD5cbiAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IGVsZW1lbnRcIj5cbiAgICAgICAgICA8ZGl2ICpuZ0lmPVwiIWVsZW1lbnQuc3RvY2tfdHJhbnNmZXJcIiBjbGFzcz1cImQtZmxleCBnYXAtMVwiPlxuICAgICAgICAgICAgPGFwcC1zdG9jay1pc3N1ZS1mb3JtLWJ1dHRvbiBbc3RvY2tJc3N1ZV09XCJlbGVtZW50XCJcbiAgICAgICAgICAgICAgKHNhdmVkKT1cInJlbG9hZCgpOyBsaXN0VXBkYXRlZC5lbWl0KClcIj48L2FwcC1zdG9jay1pc3N1ZS1mb3JtLWJ1dHRvbj5cbiAgICAgICAgICAgIDxhcHAtc3RvY2staXNzdWFuY2UtZGVsZXRlLWJ1dHRvbiBbc3RvY2tJc3N1YW5jZV09XCJlbGVtZW50XCJcbiAgICAgICAgICAgICAgKGRlbGV0ZWQpPVwicmVsb2FkKCk7IGxpc3RVcGRhdGVkLmVtaXQoKVwiPjwvYXBwLXN0b2NrLWlzc3VhbmNlLWRlbGV0ZS1idXR0b24+XG4gICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICA8c3BhbiAqbmdJZj1cImVsZW1lbnQuc3RvY2tfdHJhbnNmZXJcIiBjbGFzcz1cImJhZGdlIHJvdW5kZWQtcGlsbCB0ZXh0LWJnLXNlY29uZGFyeVwiPlN0b2NrIFRyYW5zZmVyPC9zcGFuPlxuICAgICAgICA8L3RkPlxuICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDx0ciBtYXQtaGVhZGVyLXJvdyAqbWF0SGVhZGVyUm93RGVmPVwiZGlzcGxheWVkQ29sdW1uc1wiPjwvdHI+XG4gICAgICA8dHIgbWF0LXJvdyAqbWF0Um93RGVmPVwibGV0IHJvdzsgY29sdW1uczogZGlzcGxheWVkQ29sdW1uc1wiPjwvdHI+XG4gICAgPC90YWJsZT5cblxuICAgIDxtYXQtcHJvZ3Jlc3MtYmFyICpuZ0lmPVwiaXNXb3JraW5nXCIgbW9kZT1cImluZGV0ZXJtaW5hdGVcIj48L21hdC1wcm9ncmVzcy1iYXI+XG4gIDwvbWF0LWNhcmQtY29udGVudD5cbjwvbWF0LWNhcmQ+Il19
172
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RvY2staXNzdWFuY2VzLWxpc3QuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvaW52ZW50b3J5LWNvbW1vbi9zcmMvbGliL2ludmVudG9yeS1jb21tb24vc3RvY2staXNzdWFuY2VzL3N0b2NrLWlzc3VhbmNlcy1saXN0L3N0b2NrLWlzc3VhbmNlcy1saXN0LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2ludmVudG9yeS1jb21tb24vc3JjL2xpYi9pbnZlbnRvcnktY29tbW9uL3N0b2NrLWlzc3VhbmNlcy9zdG9jay1pc3N1YW5jZXMtbGlzdC9zdG9jay1pc3N1YW5jZXMtbGlzdC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQVUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQy9FLE9BQU8sRUFFTCxrQ0FBa0MsRUFDbkMsTUFBTSxtQkFBbUIsQ0FBQztBQUUzQixPQUFPLEVBQUUsWUFBWSxFQUFFLG9CQUFvQixFQUFFLE1BQU0sTUFBTSxDQUFDO0FBSTFELE9BQU8sTUFBTSxNQUFNLFFBQVEsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBTzVCLE1BQU0sT0FBTywyQkFBNEIsU0FBUSxrQ0FBa0M7SUF5QnZFO0lBQ0E7SUFDQTtJQUNBO0lBQ0E7SUE1QkQsT0FBTyxDQUFNO0lBQ2IsWUFBWSxDQUFVO0lBQ3RCLFVBQVUsQ0FBVTtJQUNwQixLQUFLLEdBQUcsY0FBYyxDQUFDO0lBQ3ZCLFdBQVcsR0FBWSxJQUFJLENBQUM7SUFDNUIsV0FBVyxHQUFZLElBQUksQ0FBQztJQUMzQixXQUFXLEdBQXNCLElBQUksWUFBWSxFQUFPLENBQUM7SUFFbkUsc0JBQXNCLEdBQWE7UUFDakMsSUFBSSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsTUFBTSxF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Q0FBQyxDQUFDLENBQUMsRUFBRTtZQUNsRSxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFO1NBQzdELEVBQ0QsRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLENBQ3JCLENBQUM7SUFDSixDQUFDO0lBRU8sWUFBWTtRQUNsQixJQUFJLGNBQWMsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLGVBQWUsQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO1FBQ2xGLDBDQUEwQztRQUMxQyxJQUFJLGNBQWMsRUFBRSxDQUFDO1lBQ25CLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDakUsSUFBSSxRQUFRLElBQUksQ0FBQyxFQUFFLENBQUM7Z0JBQ2xCLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxNQUFNLENBQUMsUUFBUSxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUM7WUFDL0QsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO3dHQS9JVSwyQkFBMkI7NEZBQTNCLDJCQUEyQixnU0NqQnhDLGs4UkF1TVc7OzRGRHRMRSwyQkFBMkI7a0JBTHZDLFNBQVM7K0JBQ0UsMEJBQTBCO3dOQUszQixPQUFPO3NCQUFmLEtBQUs7Z0JBQ0csWUFBWTtzQkFBcEIsS0FBSztnQkFDRyxVQUFVO3NCQUFsQixLQUFLO2dCQUNHLEtBQUs7c0JBQWIsS0FBSztnQkFDRyxXQUFXO3NCQUFuQixLQUFLO2dCQUNHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBQ0ksV0FBVztzQkFBcEIsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgRXZlbnRFbWl0dGVyLCBJbnB1dCwgT25Jbml0LCBPdXRwdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7XG4gIENvbHVtbkNvbmZpZywgUmVxdWVzdEhlbHBlclNlcnZpY2UsIFRlY2hsaWZ5RmVhdHVyZVNlcnZpY2UsXG4gIFRlY2hsaWZ5TGlzdGluZ0NvbnRyb2xsZXJJbnRlcmZhY2UsIFRpbWVsaW5lVmFsdWVcbn0gZnJvbSAnbmd4LXRlY2hsaWZ5LWNvcmUnO1xuaW1wb3J0IHsgRm9ybUJ1aWxkZXIsIEZvcm1Hcm91cCB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IGRlYm91bmNlVGltZSwgZGlzdGluY3RVbnRpbENoYW5nZWQgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IFNvcnQgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9zb3J0JztcbmltcG9ydCB7IFN0b2NrSXNzdWFuY2VTZXJ2aWNlIH0gZnJvbSAnLi4vc3RvY2staXNzdWFuY2Uuc2VydmljZSc7XG5pbXBvcnQgeyBBY3RpdmF0ZWRSb3V0ZSB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgbW9tZW50IGZyb20gJ21vbWVudCc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2FwcC1zdG9jay1pc3N1YW5jZXMtbGlzdCcsXG4gIHRlbXBsYXRlVXJsOiAnLi9zdG9jay1pc3N1YW5jZXMtbGlzdC5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL3N0b2NrLWlzc3VhbmNlcy1saXN0LmNvbXBvbmVudC5zY3NzJ10sXG59KVxuZXhwb3J0IGNsYXNzIFN0b2NrSXNzdWFuY2VzTGlzdENvbXBvbmVudCBleHRlbmRzIFRlY2hsaWZ5TGlzdGluZ0NvbnRyb2xsZXJJbnRlcmZhY2UgaW1wbGVtZW50cyBPbkluaXQge1xuICBASW5wdXQoKSBwcm9kdWN0OiBhbnk7XG4gIEBJbnB1dCgpIGlzc3VhYmxlVHlwZSE6IHN0cmluZztcbiAgQElucHV0KCkgaXNzdWFibGVJZCE6IG51bWJlcjtcbiAgQElucHV0KCkgbGFiZWwgPSAnU3RvY2sgSXNzdWVzJztcbiAgQElucHV0KCkgc2hvd0FjdGlvbnM6IGJvb2xlYW4gPSB0cnVlO1xuICBASW5wdXQoKSBzaG93RmlsdGVyczogYm9vbGVhbiA9IHRydWU7XG4gIEBPdXRwdXQoKSBsaXN0VXBkYXRlZDogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcblxuICBkZWZhdWx0U2VsZWN0ZWRDb2x1bW5zOiBzdHJpbmdbXSA9IFtcbiAgICAnbm8nLCAncHJvZHVjdCcsICdza3UnLCAnZGF0ZScsICdxdWFudGl0eScsICdtZWFzdXJlJywgJ2xvY2F0aW9uJywgJ3JlbGF0ZWQnLCAncGFydGljdWxhcnMnLFxuICBdO1xuXG4gIGNvbHVtbkNvbmZpZzogQ29sdW1uQ29uZmlnW10gPSBbXG4gICAgeyBsYWJlbDogJ0NyZWF0b3InLCBkZWY6ICdjcmVhdG9yJywgaXNTZWxlY3RlZDogZmFsc2UsIGlzRWRpdGFibGU6IHRydWUgfSxcbiAgXTtcblxuICBzZWxlY3RlZENvbHVtbnM6IENvbHVtbkNvbmZpZ1tdID0gdGhpcy5jb2x1bW5Db25maWcuZmlsdGVyKGNvbCA9PiBjb2wuaXNTZWxlY3RlZCk7XG5cbiAgZ2V0IGRpc3BsYXllZENvbHVtbnMoKTogc3RyaW5nW10ge1xuICAgIGNvbnN0IHNlbGVjdGVkQ29sdW1uczogc3RyaW5nW10gPSB0aGlzLnNlbGVjdGVkQ29sdW1ucy5tYXAoY29sID0+IGNvbC5kZWYpO1xuICAgIHJldHVybiB0aGlzLmRlZmF1bHRTZWxlY3RlZENvbHVtbnMuY29uY2F0KC4uLnNlbGVjdGVkQ29sdW1ucywgJ2FjdGlvbnMnKTtcbiAgfVxuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgZm9ybUJ1aWxkZXI6IEZvcm1CdWlsZGVyLFxuICAgIHByaXZhdGUgcmVxdWVzdEhlbHBlclNlcnZpY2U6IFJlcXVlc3RIZWxwZXJTZXJ2aWNlLFxuICAgIHByaXZhdGUgc3RvY2tJc3N1YW5jZVNlcnZpY2U6IFN0b2NrSXNzdWFuY2VTZXJ2aWNlLFxuICAgIHByaXZhdGUgYWN0aXZhdGVkUm91dGU6IEFjdGl2YXRlZFJvdXRlLFxuICAgIHByaXZhdGUgZmVhdHVyZVNlcnZpY2U6IFRlY2hsaWZ5RmVhdHVyZVNlcnZpY2VcbiAgKSB7XG4gICAgc3VwZXIoKTtcbiAgICB0aGlzLmxhc3RQYWdlID0gMDtcbiAgICB0aGlzLmZpbHRlckZvcm0gPSB0aGlzLmZvcm1CdWlsZGVyLmdyb3VwKHtcbiAgICAgIGNhdGVnb3J5X2lkczogWycnXSxcbiAgICAgIGRhdGVfZnJvbTogWycnXSxcbiAgICAgIGRhdGVfdG86IFsnJ10sXG4gICAgICBkdXJhdGlvbjogWycnXSxcbiAgICAgIGltcG9ydF9pZDogWycnXSxcbiAgICAgIGxvY2F0aW9uX2lkczogWycnXSxcbiAgICAgIG1lYXN1cmVfaWRzOiBbJyddLFxuICAgICAgcHJvZHVjdF9pZHM6IFsnJ10sXG4gICAgICBzZWFyY2g6IFsnJ10sXG4gICAgICBzb3J0X2J5OiBbJ2RhdGV8ZGVzYyddLFxuICAgIH0pO1xuICB9XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5sb2FkRmVhdHVyZXMoKTtcbiAgICBpZiAodGhpcy5wcm9kdWN0KSB7XG4gICAgICB0aGlzLmZpbHRlckZvcm0uZ2V0KCdwcm9kdWN0X2lkcycpPy5zZXRWYWx1ZSh0aGlzLnByb2R1Y3Q/LmlkKTtcbiAgICAgIHRoaXMuZGVmYXVsdFNlbGVjdGVkQ29sdW1ucyA9IHRoaXMuZGVmYXVsdFNlbGVjdGVkQ29sdW1ucy5maWx0ZXIoYyA9PiBjICE9PSAncHJvZHVjdCcgJiYgYyAhPT0gJ3NrdScpO1xuICAgIH1cblxuICAgIHRoaXMudXBkYXRlRm9ybVdpdGhRdWVyeVBhcmFtcygpO1xuICAgIHRoaXMuc3Vic2NyaWJlVG9Gb3JtQ2hhbmdlcygpO1xuICAgIHRoaXMuc3Vic2NyaWJlVG9Sb3V0ZUNoYW5nZXMoKTtcbiAgfVxuXG4gIGxvYWREYXRhKCk6IHZvaWQge1xuICAgIGNvbnN0IHBhcmFtczogYW55ID0ge1xuICAgICAgcGFnZTogdGhpcy5wYWdlLFxuICAgICAgcGVyUGFnZTogdGhpcy5wZXJQYWdlLFxuICAgICAgd2l0aDogYGNyZWF0b3IsaXNzdWFibGUuZml4ZWRBc3NldCxzdG9ja0lzc3VlUHJvZHVjdHMucHJvZHVjdCxzdG9ja0lzc3VlUHJvZHVjdHMubG9jYXRpb24sc3RvY2tJc3N1ZVByb2R1Y3RzLnByb2R1Y3QuY2F0ZWdvcmllcyxzdG9ja1RyYW5zZmVyLHN0b2NrSXNzdWVQcm9kdWN0cy5iYXRjaGAsXG4gICAgICAuLi50aGlzLnJlcXVlc3RIZWxwZXJTZXJ2aWNlLmNvbnZlcnRUb0Zvcm1EYXRhKHRoaXMuZmlsdGVyRm9ybS52YWx1ZSksXG4gICAgfTtcbiAgICBpZiAodGhpcy5pc3N1YWJsZUlkICYmIHRoaXMuaXNzdWFibGVUeXBlKSB7XG4gICAgICBwYXJhbXMuaXNzdWFibGVfaWRzID0gdGhpcy5pc3N1YWJsZUlkO1xuICAgICAgcGFyYW1zLmlzc3VhYmxlX3R5cGVzID0gdGhpcy5pc3N1YWJsZVR5cGU7XG4gICAgfVxuICAgIHRoaXMuaXNXb3JraW5nID0gdHJ1ZTtcbiAgICB0aGlzLnN0b2NrSXNzdWFuY2VTZXJ2aWNlLmluZGV4KHBhcmFtcykuc3Vic2NyaWJlKHtcbiAgICAgIG5leHQ6IChyZXNwb25zZTogYW55KSA9PiB7XG4gICAgICAgIHRoaXMubW9kZWxzID0gdGhpcy5tb2RlbHMuY29uY2F0KHJlc3BvbnNlPy5kYXRhKTtcbiAgICAgICAgdGhpcy5sYXN0UGFnZSA9IHJlc3BvbnNlPy5sYXN0X3BhZ2U7XG4gICAgICAgIHRoaXMuaXNXb3JraW5nID0gZmFsc2U7XG4gICAgICB9LFxuICAgICAgZXJyb3I6ICgpID0+IHtcbiAgICAgICAgdGhpcy5pc1dvcmtpbmcgPSBmYWxzZTtcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICBvblNvcnRDaGFuZ2Uoc29ydDogU29ydCkge1xuICAgIGxldCB7IGFjdGl2ZSwgZGlyZWN0aW9uIH0gPSBzb3J0O1xuICAgIGlmICghYWN0aXZlKSB7XG4gICAgICBhY3RpdmUgPSAnZGF0ZSc7XG4gICAgfVxuICAgIGlmICghZGlyZWN0aW9uKSB7XG4gICAgICBkaXJlY3Rpb24gPSAnZGVzYyc7XG4gICAgICBhY3RpdmUgPSAnZGF0ZSc7XG4gICAgfVxuICAgIHRoaXMuZmlsdGVyRm9ybS5nZXQoJ3NvcnRfYnknKS5zZXRWYWx1ZShhY3RpdmUgKyAnfCcgKyBkaXJlY3Rpb24pO1xuICB9XG5cbiAgcHJpdmF0ZSB1cGRhdGVGb3JtV2l0aFF1ZXJ5UGFyYW1zKCk6IHZvaWQge1xuICAgIHRoaXMucmVxdWVzdEhlbHBlclNlcnZpY2UudXBkYXRlRm9ybVdpdGhRdWVyeVBhcmFtcyh0aGlzLmZpbHRlckZvcm0sIHtcbiAgICAgIHByb2R1Y3RfaWRzOiB7IG11bHRpcGxlOiB0cnVlIH0sXG4gICAgICBtZWFzdXJlX2lkczogeyBtdWx0aXBsZTogdHJ1ZSB9LFxuICAgICAgY2F0ZWdvcnlfaWRzOiB7IG11bHRpcGxlOiB0cnVlIH0sXG4gICAgICBzdXBwbGllcl9pZHM6IHsgbXVsdGlwbGU6IHRydWUgfSxcbiAgICAgIGxvY2F0aW9uX2lkczogeyBtdWx0aXBsZTogdHJ1ZSB9LFxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBzdWJzY3JpYmVUb0Zvcm1DaGFuZ2VzKCk6IHZvaWQge1xuICAgICh0aGlzLmZpbHRlckZvcm0gYXMgRm9ybUdyb3VwKS52YWx1ZUNoYW5nZXMucGlwZShkZWJvdW5jZVRpbWUoODAwKSkuc3Vic2NyaWJlKHtcbiAgICAgIG5leHQ6ICgpID0+IHtcbiAgICAgICAgdGhpcy5yZXF1ZXN0SGVscGVyU2VydmljZS51cGRhdGVRdWVyeVBhcmFtcyhcbiAgICAgICAgICB0aGlzLnJlcXVlc3RIZWxwZXJTZXJ2aWNlLmNvbnZlcnRUb0Zvcm1EYXRhKHRoaXMuZmlsdGVyRm9ybS52YWx1ZSlcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgc3Vic2NyaWJlVG9Sb3V0ZUNoYW5nZXMoKTogdm9pZCB7XG4gICAgdGhpcy5hY3RpdmF0ZWRSb3V0ZS5xdWVyeVBhcmFtc1xuICAgICAgLnBpcGUoZGVib3VuY2VUaW1lKDUwMCksIGRpc3RpbmN0VW50aWxDaGFuZ2VkKCkpXG4gICAgICAuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgdGhpcy5yZWxvYWQoKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgb25EdXJhdGlvbkNoYW5nZSh0aW1lbGluZVZhbHVlOiBUaW1lbGluZVZhbHVlKSB7XG4gICAgbGV0IHsgZGF0ZV90bywgZGF0ZV9mcm9tIH0gPSB0aW1lbGluZVZhbHVlO1xuICAgIHRoaXMuZmlsdGVyRm9ybS5wYXRjaFZhbHVlKFxuICAgICAge1xuICAgICAgICBkYXRlX2Zyb206IGRhdGVfZnJvbSA/IG1vbWVudChkYXRlX2Zyb20pLmZvcm1hdChcIllZWVktTU0tRERcIikgOiBcIlwiLFxuICAgICAgICBkYXRlX3RvOiBkYXRlX3RvID8gbW9tZW50KGRhdGVfdG8pLmZvcm1hdChcIllZWVktTU0tRERcIikgOiBcIlwiLFxuICAgICAgfSxcbiAgICAgIHsgZW1pdEV2ZW50OiBmYWxzZSB9XG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgbG9hZEZlYXR1cmVzKCkge1xuICAgIGxldCBpc0JhdGNoRW5hYmxlZCA9IHRoaXMuZmVhdHVyZVNlcnZpY2UuaXNGZWF0dXJlRXhpc3RzKCdwcm9kdWN0LWJhdGNoLW51bWJlcnMnKTtcbiAgICAvLyBub3cgdXBkYXRlIGRpc3BsYXllZENvbHVtbnMgYWNjb3JkaW5nbHlcbiAgICBpZiAoaXNCYXRjaEVuYWJsZWQpIHtcbiAgICAgIGNvbnN0IHF0eUluZGV4ID0gdGhpcy5kZWZhdWx0U2VsZWN0ZWRDb2x1bW5zLmluZGV4T2YoJ3F1YW50aXR5Jyk7XG4gICAgICBpZiAocXR5SW5kZXggPj0gMCkge1xuICAgICAgICB0aGlzLmRlZmF1bHRTZWxlY3RlZENvbHVtbnMuc3BsaWNlKHF0eUluZGV4ICsgMSwgMCwgJ2JhdGNoJyk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG4iLCI8bWF0LWNhcmQgKm5nSWY9XCIhcHJvZHVjdFwiIGNsYXNzPVwibWItMlwiPlxuICA8bWF0LWNhcmQtY29udGVudCBjbGFzcz1cImQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtYmV0d2VlbiBhbGlnbi1pdGVtcy1jZW50ZXIgZ2FwLTNcIj5cbiAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGp1c3RpZnktY29udGVudC1zdGFydCBhbGlnbi1pdGVtcy1jZW50ZXIgZ2FwLTJcIj5cbiAgICAgIDxoMyBjbGFzcz1cIm1iLTBcIj57eyBsYWJlbCB9fTwvaDM+XG5cbiAgICAgIDxhcHAtc3RvY2staXNzdWUtZm9ybS1idXR0b24gaWNvbj1cImFkZFwiIFtpc3N1YWJsZVR5cGVdPVwiaXNzdWFibGVUeXBlXCIgW2lzc3VhYmxlSWRdPVwiaXNzdWFibGVJZFwiXG4gICAgICAgIChzYXZlZCk9XCJyZWxvYWQoKVwiPjwvYXBwLXN0b2NrLWlzc3VlLWZvcm0tYnV0dG9uPlxuXG4gICAgICA8c3BhbiAqbmdJZj1cInNob3dBY3Rpb25zXCIgbWF0VG9vbHRpcD1cIkltcG9ydFwiIHJvdXRlckxpbms9XCJpbXBvcnRcIlxuICAgICAgICBjbGFzcz1cImN1cnNvci1wb2ludGVyIG1hdGVyaWFsLXN5bWJvbHMtb3V0bGluZWRcIj5cbiAgICAgICAgZmlsZV91cGxvYWRcbiAgICAgIDwvc3Bhbj5cblxuICAgICAgPGFwcC1jb2x1bW4tc2VsZWN0b3IgKm5nSWY9XCJzaG93QWN0aW9uc1wiIG1vZGU9XCJpY29uXCIgY2xhc3M9XCJtdC0yIGQtcHJpbnQtbm9uZVwiIFtjb2x1bW5Db25maWdzXT1cImNvbHVtbkNvbmZpZ1wiXG4gICAgICAgIFsoc2VsZWN0ZWRDb2x1bW5zKV09XCJzZWxlY3RlZENvbHVtbnNcIj48L2FwcC1jb2x1bW4tc2VsZWN0b3I+XG4gICAgPC9kaXY+XG5cbiAgICA8Zm9ybSBbZm9ybUdyb3VwXT1cImZpbHRlckZvcm1cIiAqbmdJZj1cInNob3dGaWx0ZXJzXCI+XG4gICAgICA8bWF0LWZvcm0tZmllbGQ+XG4gICAgICAgIDxtYXQtbGFiZWw+U2VhcmNoPC9tYXQtbGFiZWw+XG4gICAgICAgIDxpbnB1dCBtYXRJbnB1dCBwbGFjZWhvbGRlcj1cIlNlYXJjaCBwcm9kdWN0c1wiIGZvcm1Db250cm9sTmFtZT1cInNlYXJjaFwiIC8+XG4gICAgICA8L21hdC1mb3JtLWZpZWxkPlxuXG4gICAgICA8YXBwLXRpbWVsaW5lLWZpbHRlciBhcHBlYXJhbmNlPVwiZmlsbFwiIGxhYmVsVGV4dD1cIkRhdGVcIiBmb3JtQ29udHJvbE5hbWU9XCJkdXJhdGlvblwiXG4gICAgICAgIChzZWxlY3Rpb25DaGFuZ2UpPVwib25EdXJhdGlvbkNoYW5nZSgkZXZlbnQpXCIgW3Nob3dDbGVhckJ1dHRvbl09XCJ0cnVlXCIgW2RhdGVGcm9tXT1cImZpbHRlckZvcm0udmFsdWU/LmRhdGVfZnJvbVwiXG4gICAgICAgIFtkYXRlVG9dPVwiZmlsdGVyRm9ybS52YWx1ZT8uZGF0ZV90b1wiPjwvYXBwLXRpbWVsaW5lLWZpbHRlcj5cblxuICAgICAgPG1hdC1mb3JtLWZpZWxkPlxuICAgICAgICA8bWF0LWxhYmVsPkNhdGVnb3J5PC9tYXQtbGFiZWw+XG4gICAgICAgIDxhcHAtc2VhcmNoYWJsZS1zZWxlY3RvciBhcGlVcmw9XCJhcGkvcHJvZHVjdC1jYXRlZ29yaWVzXCIgZm9ybUNvbnRyb2xOYW1lPVwiY2F0ZWdvcnlfaWRzXCIgW211bHRpcGxlXT1cInRydWVcIj5cbiAgICAgICAgPC9hcHAtc2VhcmNoYWJsZS1zZWxlY3Rvcj5cbiAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG5cbiAgICAgIDxtYXQtZm9ybS1maWVsZD5cbiAgICAgICAgPG1hdC1sYWJlbD5NZWFzdXJlPC9tYXQtbGFiZWw+XG4gICAgICAgIDxhcHAtc2VhcmNoYWJsZS1zZWxlY3RvciBhcGlVcmw9XCJhcGkvcHJvZHVjdC1tZWFzdXJlc1wiIGZvcm1Db250cm9sTmFtZT1cIm1lYXN1cmVfaWRzXCIgW211bHRpcGxlXT1cInRydWVcIj5cbiAgICAgICAgPC9hcHAtc2VhcmNoYWJsZS1zZWxlY3Rvcj5cbiAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG5cbiAgICAgIDxtYXQtZm9ybS1maWVsZD5cbiAgICAgICAgPG1hdC1sYWJlbD5Mb2NhdGlvbjwvbWF0LWxhYmVsPlxuICAgICAgICA8YXBwLXNlYXJjaGFibGUtc2VsZWN0b3IgYXBpVXJsPVwiYXBpL2ludmVudG9yeS1sb2NhdGlvbnNcIiBmb3JtQ29udHJvbE5hbWU9XCJsb2NhdGlvbl9pZHNcIiBbbXVsdGlwbGVdPVwidHJ1ZVwiPlxuICAgICAgICA8L2FwcC1zZWFyY2hhYmxlLXNlbGVjdG9yPlxuICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICA8L2Zvcm0+XG4gIDwvbWF0LWNhcmQtY29udGVudD5cbjwvbWF0LWNhcmQ+XG5cbjxtYXQtY2FyZD5cbiAgPG1hdC1jYXJkLWNvbnRlbnQgKm5nSWY9XCJwcm9kdWN0XCIgY2xhc3M9XCJtYi0wXCI+XG4gICAgPGRpdiBjbGFzcz1cImQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtc3RhcnQgYWxpZ24taXRlbXMtY2VudGVyIGdhcC0yIG1iLTJcIj5cbiAgICAgIDxzcGFuIGNsYXNzPVwibWF0ZXJpYWwtc3ltYm9scy1vdXRsaW5lZFwiPiB1bmdyb3VwIDwvc3Bhbj5cbiAgICAgIDxoMyBjbGFzcz1cIm1iLTBcIj5TdG9jayBJc3N1ZXM8L2gzPlxuXG4gICAgICA8YXBwLXN0b2NrLWlzc3VlLWZvcm0tYnV0dG9uIGNsYXNzPVwibXQtMlwiIFtwcm9kdWN0XT1cInByb2R1Y3RcIiBpY29uPVwiYWRkXCJcbiAgICAgICAgKHNhdmVkKT1cInJlbG9hZCgpOyBsaXN0VXBkYXRlZC5lbWl0KClcIj48L2FwcC1zdG9jay1pc3N1ZS1mb3JtLWJ1dHRvbj5cbiAgICA8L2Rpdj5cbiAgPC9tYXQtY2FyZC1jb250ZW50PlxuICA8bWF0LWNhcmQtY29udGVudCBjbGFzcz1cInAtMFwiPlxuICAgIDx0YWJsZSBtYXQtdGFibGUgW2RhdGFTb3VyY2VdPVwibW9kZWxzXCIgY2xhc3M9XCJ3LTEwMFwiIGFyaWEtZGVzY3JpYmVkYnk9XCJTdG9jayBJc3N1YW5jZXNcIiBpbmZpbml0ZVNjcm9sbFxuICAgICAgW2luZmluaXRlU2Nyb2xsRGlzdGFuY2VdPVwiMlwiIFtpbmZpbml0ZVNjcm9sbFRocm90dGxlXT1cIjUwXCIgKHNjcm9sbGVkKT1cIm9uU2Nyb2xsKClcIiBtYXRTb3J0XG4gICAgICAobWF0U29ydENoYW5nZSk9XCJvblNvcnRDaGFuZ2UoJGV2ZW50KVwiPlxuICAgICAgPCEtLSAjIENvbHVtbiAtLT5cbiAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwibm9cIj5cbiAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZj4jPC90aD5cbiAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IGVsZW1lbnQ7IGxldCBpID0gaW5kZXhcIj57eyBpICsgMSB9fTwvdGQ+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgPCEtLSBQcm9kdWN0IENvbHVtbiAtLT5cbiAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwicHJvZHVjdFwiPlxuICAgICAgICA8dGggbWF0LWhlYWRlci1jZWxsICptYXRIZWFkZXJDZWxsRGVmIG1hdC1zb3J0LWhlYWRlcj5Qcm9kdWN0PC90aD5cbiAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IGVsZW1lbnRcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGZsZXgtY29sdW1uIGdhcC0xXCI+XG4gICAgICAgICAgICA8YSBjbGFzcz1cInRleHQtZGVjb3JhdGlvbi1ub25lIHRleHQtZGFya1wiXG4gICAgICAgICAgICAgIFtyb3V0ZXJMaW5rXT1cIlsnL2ludmVudG9yeS9wcm9kdWN0cycsIGVsZW1lbnQ/LnN0b2NrX2lzc3VlX3Byb2R1Y3RzWzBdPy5wcm9kdWN0Py5pZCwgJ3ZpZXcnXVwiPlxuICAgICAgICAgICAgICB7eyBlbGVtZW50Py5zdG9ja19pc3N1ZV9wcm9kdWN0c1swXT8ucHJvZHVjdC5uYW1lIH19XG4gICAgICAgICAgICA8L2E+XG4gICAgICAgICAgICA8YXBwLXByb2R1Y3QtY2F0ZWdvcnktYmFkZ2VzXG4gICAgICAgICAgICAgIFtwcm9kdWN0XT1cImVsZW1lbnQ/LnN0b2NrX2lzc3VlX3Byb2R1Y3RzWzBdPy5wcm9kdWN0XCI+PC9hcHAtcHJvZHVjdC1jYXRlZ29yeS1iYWRnZXM+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvdGQ+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgPCEtLSBTS1UgQ29sdW1uIC0tPlxuICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJza3VcIj5cbiAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZiBtYXQtc29ydC1oZWFkZXI+U0tVPC90aD5cbiAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IGVsZW1lbnRcIj57eyBlbGVtZW50Py5zdG9ja19pc3N1ZV9wcm9kdWN0c1swXT8ucHJvZHVjdC5za3UgfX08L3RkPlxuICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDwhLS0gRGF0ZSBDb2x1bW4gLS0+XG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cImRhdGVcIj5cbiAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZiBtYXQtc29ydC1oZWFkZXI+RGF0ZTwvdGg+XG4gICAgICAgIDx0ZCBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCBlbGVtZW50XCI+e3sgZWxlbWVudD8uZGF0ZSB8IGRhdGUgfX08L3RkPlxuICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDwhLS0gTG9jYXRpb24gQ29sdW1uIC0tPlxuICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJsb2NhdGlvblwiPlxuICAgICAgICA8dGggbWF0LWhlYWRlci1jZWxsICptYXRIZWFkZXJDZWxsRGVmIG1hdC1zb3J0LWhlYWRlcj5Mb2NhdGlvbjwvdGg+XG4gICAgICAgIDx0ZCBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCBlbGVtZW50XCI+XG4gICAgICAgICAgPGEgY2xhc3M9XCJ0ZXh0LWRlY29yYXRpb24tbm9uZSB0ZXh0LWRhcmtcIlxuICAgICAgICAgICAgW3JvdXRlckxpbmtdPVwiWycvaW52ZW50b3J5L2xvY2F0aW9ucycsIGVsZW1lbnQ/LnN0b2NrX2lzc3VlX3Byb2R1Y3RzWzBdPy5sb2NhdGlvbl9pZCwgJ3ZpZXcnXVwiPlxuICAgICAgICAgICAge3sgZWxlbWVudD8uc3RvY2tfaXNzdWVfcHJvZHVjdHNbMF0/LmxvY2F0aW9uPy50aXRsZSB9fVxuICAgICAgICAgIDwvYT5cbiAgICAgICAgPC90ZD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8IS0tIFJlbGF0ZWQgQ29sdW1uIC0tPlxuICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJyZWxhdGVkXCI+XG4gICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgKm1hdEhlYWRlckNlbGxEZWY+UmVsYXRlZDwvdGg+XG4gICAgICAgIDx0ZCBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCBlbGVtZW50XCI+XG4gICAgICAgICAgPGEgY2xhc3M9XCJ0ZXh0LWRhcmtcIiAqbmdJZj1cImVsZW1lbnQ/Lmlzc3VhYmxlXCIgW3JvdXRlckxpbmtdPVwiWycvbWFpbnRlbmFuY2VzJywgZWxlbWVudD8uaXNzdWFibGVfaWQsICd2aWV3J11cIj5cbiAgICAgICAgICAgIE1haW50ZW5hbmNlIGZvciB7eyBlbGVtZW50Py5pc3N1YWJsZT8uZml4ZWRfYXNzZXQ/Lm5hbWUgfX1cbiAgICAgICAgICA8L2E+XG4gICAgICAgIDwvdGQ+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgPCEtLSBRdWFudGl0eSBDb2x1bW4gLS0+XG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cInF1YW50aXR5XCI+XG4gICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgKm1hdEhlYWRlckNlbGxEZWYgbWF0LXNvcnQtaGVhZGVyPlF1YW50aXR5PC90aD5cbiAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IGVsZW1lbnRcIj57eyBlbGVtZW50Py5zdG9ja19pc3N1ZV9wcm9kdWN0c1swXT8ucXVhbnRpdHkgfX0ge3tcbiAgICAgICAgICBlbGVtZW50Py5zdG9ja19pc3N1ZV9wcm9kdWN0c1swXT8ucHJvZHVjdC5tZWFzdXJlPy50aXRsZSB9fTwvdGQ+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgPCEtLSBCYXRjaCBDb2x1bW4gLS0+XG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cImJhdGNoXCI+XG4gICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgKm1hdEhlYWRlckNlbGxEZWY+QmF0Y2g8L3RoPlxuICAgICAgICA8dGQgbWF0LWNlbGwgKm1hdENlbGxEZWY9XCJsZXQgZWxlbWVudFwiPlxuICAgICAgICAgIDxwIGNsYXNzPVwibWItMFwiICpuZ0lmPVwiZWxlbWVudD8uc3RvY2tfaXNzdWVfcHJvZHVjdHNbMF0/LmJhdGNoPy5iYXRjaF9udW1iZXJcIj57eyBlbGVtZW50Py5zdG9ja19pc3N1ZV9wcm9kdWN0c1swXT8uYmF0Y2g/LmJhdGNoX251bWJlciB9fTwvcD5cbiAgICAgICAgICA8c21hbGwgY2xhc3M9XCJ0ZXh0LXNlY29uZGFyeVwiICpuZ0lmPVwiZWxlbWVudD8uc3RvY2tfaXNzdWVfcHJvZHVjdHNbMF0/LmJhdGNoPy5leHBpcmVzX29uXCI+XG4gICAgICAgICAgICBFeHBpcmVzIHt7IGVsZW1lbnQ/LnN0b2NrX2lzc3VlX3Byb2R1Y3RzWzBdPy5iYXRjaD8uZXhwaXJlc19vbiB8IGRhdGUgfX1cbiAgICAgICAgICA8L3NtYWxsPlxuICAgICAgICA8L3RkPlxuICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwibWVhc3VyZVwiPlxuICAgICAgICA8dGggbWF0LWhlYWRlci1jZWxsICptYXRIZWFkZXJDZWxsRGVmIG1hdC1zb3J0LWhlYWRlcj5NZWFzdXJlPC90aD5cbiAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IGVsZW1lbnRcIj57eyBlbGVtZW50Py5zdG9ja19pc3N1ZV9wcm9kdWN0c1swXT8ucHJvZHVjdC5tZWFzdXJlPy50aXRsZSB9fTwvdGQ+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgPCEtLSBQdXJjaGFzZSBQcmljZSBDb2x1bW4gLS0+XG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cInB1cmNoYXNlX3ByaWNlXCI+XG4gICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgKm1hdEhlYWRlckNlbGxEZWYgbWF0LXNvcnQtaGVhZGVyPlB1cmNoYXNlIFByaWNlPC90aD5cbiAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IGVsZW1lbnRcIj5cbiAgICAgICAgICB7eyBlbGVtZW50Py5wdXJjaGFzZV9wcmljZSB8IGN1cnJlbmN5IH19XG4gICAgICAgIDwvdGQ+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgPCEtLSBUb3RhbCBWYWx1ZSBDb2x1bW4gLS0+XG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cImFtb3VudFwiPlxuICAgICAgICA8dGggbWF0LWhlYWRlci1jZWxsICptYXRIZWFkZXJDZWxsRGVmIG1hdC1zb3J0LWhlYWRlcj5Ub3RhbCBWYWx1ZTwvdGg+XG4gICAgICAgIDx0ZCBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCBlbGVtZW50XCI+XG4gICAgICAgICAge3sgZWxlbWVudD8uYW1vdW50IHwgY3VycmVuY3kgfX1cbiAgICAgICAgPC90ZD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8IS0tIFBhcnRpY3VsYXJzIENvbHVtbiAtLT5cbiAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwicGFydGljdWxhcnNcIj5cbiAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZj5QYXJ0aWN1bGFyczwvdGg+XG4gICAgICAgIDx0ZCBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCBlbGVtZW50XCI+e3sgZWxlbWVudD8uc3RvY2tfaXNzdWVfcHJvZHVjdHNbMF0/LnBhcnRpY3VsYXJzIH19PC90ZD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8IS0tIFN1cHBsaWVyIENvbHVtbiAtLT5cbiAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwic3VwcGxpZXJcIj5cbiAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZiBtYXQtc29ydC1oZWFkZXI+U3VwcGxpZXI8L3RoPlxuICAgICAgICA8dGQgbWF0LWNlbGwgKm1hdENlbGxEZWY9XCJsZXQgZWxlbWVudFwiPlxuICAgICAgICAgIHt7IGVsZW1lbnQ/LnN1cHBsaWVyPy5jb21wYW55X25hbWUgfX1cbiAgICAgICAgPC90ZD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8IS0tIENyZWF0b3IgQ29sdW1uIC0tPlxuICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJjcmVhdG9yXCI+XG4gICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgKm1hdEhlYWRlckNlbGxEZWY+Q3JlYXRvcjwvdGg+XG4gICAgICAgIDx0ZCBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCBlbGVtZW50XCI+XG4gICAgICAgICAgPHAgY2xhc3M9XCJtYi0xXCI+e3sgZWxlbWVudD8uY3JlYXRvcj8ubmFtZSB9fTwvcD5cbiAgICAgICAgICA8c21hbGwgY2xhc3M9XCJ0ZXh0LXNlY29uZGFyeVwiPnt7IGVsZW1lbnQ/LmNyZWF0ZWRfYXQgfCBkYXRlIH19PC9zbWFsbD5cbiAgICAgICAgPC90ZD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8IS0tIEFjdGlvbnMgQ29sdW1uIC0tPlxuICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJhY3Rpb25zXCI+XG4gICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgKm1hdEhlYWRlckNlbGxEZWY+QWN0aW9uczwvdGg+XG4gICAgICAgIDx0ZCBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCBlbGVtZW50XCI+XG4gICAgICAgICAgPGRpdiAqbmdJZj1cIiFlbGVtZW50LnN0b2NrX3RyYW5zZmVyXCIgY2xhc3M9XCJkLWZsZXggZ2FwLTFcIj5cbiAgICAgICAgICAgIDxhcHAtc3RvY2staXNzdWUtZm9ybS1idXR0b24gW3N0b2NrSXNzdWVdPVwiZWxlbWVudFwiXG4gICAgICAgICAgICAgIChzYXZlZCk9XCJyZWxvYWQoKTsgbGlzdFVwZGF0ZWQuZW1pdCgpXCI+PC9hcHAtc3RvY2staXNzdWUtZm9ybS1idXR0b24+XG4gICAgICAgICAgICA8YXBwLXN0b2NrLWlzc3VhbmNlLWRlbGV0ZS1idXR0b24gW3N0b2NrSXNzdWFuY2VdPVwiZWxlbWVudFwiXG4gICAgICAgICAgICAgIChkZWxldGVkKT1cInJlbG9hZCgpOyBsaXN0VXBkYXRlZC5lbWl0KClcIj48L2FwcC1zdG9jay1pc3N1YW5jZS1kZWxldGUtYnV0dG9uPlxuICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgPHNwYW4gKm5nSWY9XCJlbGVtZW50LnN0b2NrX3RyYW5zZmVyXCIgY2xhc3M9XCJiYWRnZSByb3VuZGVkLXBpbGwgdGV4dC1iZy1zZWNvbmRhcnlcIj5TdG9jayBUcmFuc2Zlcjwvc3Bhbj5cbiAgICAgICAgPC90ZD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8dHIgbWF0LWhlYWRlci1yb3cgKm1hdEhlYWRlclJvd0RlZj1cImRpc3BsYXllZENvbHVtbnNcIj48L3RyPlxuICAgICAgPHRyIG1hdC1yb3cgKm1hdFJvd0RlZj1cImxldCByb3c7IGNvbHVtbnM6IGRpc3BsYXllZENvbHVtbnNcIj48L3RyPlxuICAgIDwvdGFibGU+XG5cbiAgICA8bWF0LXByb2dyZXNzLWJhciAqbmdJZj1cImlzV29ya2luZ1wiIG1vZGU9XCJpbmRldGVybWluYXRlXCI+PC9tYXQtcHJvZ3Jlc3MtYmFyPlxuICA8L21hdC1jYXJkLWNvbnRlbnQ+XG48L21hdC1jYXJkPiJdfQ==
@@ -2121,11 +2121,11 @@ class StockIssuancesListComponent extends TechlifyListingControllerInterface {
2121
2121
  }
2122
2122
  }
2123
2123
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: StockIssuancesListComponent, deps: [{ token: i2$1.FormBuilder }, { token: i1.RequestHelperService }, { token: StockIssuanceService }, { token: i4$1.ActivatedRoute }, { token: i1.TechlifyFeatureService }], target: i0.ɵɵFactoryTarget.Component });
2124
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: StockIssuancesListComponent, selector: "app-stock-issuances-list", inputs: { product: "product", issuableType: "issuableType", issuableId: "issuableId", label: "label", showActions: "showActions", showFilters: "showFilters" }, outputs: { listUpdated: "listUpdated" }, usesInheritance: true, ngImport: i0, template: "<mat-card *ngIf=\"!product\" class=\"mb-2\">\n <mat-card-content class=\"d-flex justify-content-between align-items-center gap-3\">\n <div class=\"d-flex justify-content-start align-items-center gap-2\">\n <h3 class=\"mb-0\">{{ label }}</h3>\n\n <app-stock-issue-form-button icon=\"add\" [issuableType]=\"issuableType\" [issuableId]=\"issuableId\"\n (saved)=\"reload()\"></app-stock-issue-form-button>\n\n <span *ngIf=\"showActions\" matTooltip=\"Import\" routerLink=\"import\"\n class=\"cursor-pointer material-symbols-outlined\">\n file_upload\n </span>\n\n <app-column-selector *ngIf=\"showActions\" mode=\"icon\" class=\"mt-2 d-print-none\" [columnConfigs]=\"columnConfig\"\n [(selectedColumns)]=\"selectedColumns\"></app-column-selector>\n </div>\n\n <form [formGroup]=\"filterForm\" *ngIf=\"showFilters\">\n <mat-form-field>\n <mat-label>Search</mat-label>\n <input matInput placeholder=\"Search products\" formControlName=\"search\" />\n </mat-form-field>\n\n <app-timeline-filter appearance=\"fill\" labelText=\"Date\" formControlName=\"duration\"\n (selectionChange)=\"onDurationChange($event)\" [showClearButton]=\"true\" [dateFrom]=\"filterForm.value?.date_from\"\n [dateTo]=\"filterForm.value?.date_to\"></app-timeline-filter>\n\n <mat-form-field>\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>\n <mat-label>Measure</mat-label>\n <app-searchable-selector apiUrl=\"api/product-measures\" formControlName=\"measure_ids\" [multiple]=\"true\">\n </app-searchable-selector>\n </mat-form-field>\n\n <mat-form-field>\n <mat-label>Location</mat-label>\n <app-searchable-selector apiUrl=\"api/inventory-locations\" formControlName=\"location_ids\" [multiple]=\"true\">\n </app-searchable-selector>\n </mat-form-field>\n </form>\n </mat-card-content>\n</mat-card>\n\n<mat-card>\n <mat-card-content *ngIf=\"product\" class=\"mb-0\">\n <div class=\"d-flex justify-content-start align-items-center gap-2 mb-2\">\n <span class=\"material-symbols-outlined\"> ungroup </span>\n <h3 class=\"mb-0\">Stock Issues</h3>\n\n <app-stock-issue-form-button class=\"mt-2\" [product]=\"product\" icon=\"add\"\n (saved)=\"reload(); listUpdated.emit()\"></app-stock-issue-form-button>\n </div>\n </mat-card-content>\n <mat-card-content class=\"p-0\">\n <table mat-table [dataSource]=\"models\" class=\"w-100\" aria-describedby=\"Stock Issuances\" infiniteScroll\n [infiniteScrollDistance]=\"2\" [infiniteScrollThrottle]=\"50\" (scrolled)=\"onScroll()\" matSort\n (matSortChange)=\"onSortChange($event)\">\n <!-- # Column -->\n <ng-container matColumnDef=\"no\">\n <th mat-header-cell *matHeaderCellDef>#</th>\n <td mat-cell *matCellDef=\"let element; let i = index\">{{ i + 1 }}</td>\n </ng-container>\n\n <!-- Product Column -->\n <ng-container matColumnDef=\"product\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Product</th>\n <td mat-cell *matCellDef=\"let element\">\n <div class=\"d-flex flex-column gap-1\">\n <a class=\"text-decoration-none text-dark\"\n [routerLink]=\"['/inventory/products', element?.stock_issue_products[0]?.product.id, 'view']\">\n {{ element?.stock_issue_products[0]?.product.name }}\n </a>\n <app-product-category-badges\n [product]=\"element?.stock_issue_products[0]?.product\"></app-product-category-badges>\n </div>\n </td>\n </ng-container>\n\n <!-- SKU Column -->\n <ng-container matColumnDef=\"sku\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>SKU</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.stock_issue_products[0]?.product.sku }}</td>\n </ng-container>\n\n <!-- Date Column -->\n <ng-container matColumnDef=\"date\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Date</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.date | date }}</td>\n </ng-container>\n\n <!-- Location Column -->\n <ng-container matColumnDef=\"location\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Location</th>\n <td mat-cell *matCellDef=\"let element\">\n <a class=\"text-decoration-none text-dark\"\n [routerLink]=\"['/inventory/locations', element?.stock_issue_products[0]?.location_id, 'view']\">\n {{ element?.stock_issue_products[0]?.location?.title }}\n </a>\n </td>\n </ng-container>\n\n <!-- Related Column -->\n <ng-container matColumnDef=\"related\">\n <th mat-header-cell *matHeaderCellDef>Related</th>\n <td mat-cell *matCellDef=\"let element\">\n <a class=\"text-dark\" *ngIf=\"element?.issuable\" [routerLink]=\"['/maintenances', element?.issuable_id, 'view']\">\n Maintenance for {{ element?.issuable?.fixed_asset?.name }}\n </a>\n </td>\n </ng-container>\n\n <!-- Quantity Column -->\n <ng-container matColumnDef=\"quantity\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Quantity</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.stock_issue_products[0]?.quantity }} {{\n element?.stock_issue_products[0]?.product.measure?.title }}</td>\n </ng-container>\n\n <!-- Batch Column -->\n <ng-container matColumnDef=\"batch\">\n <th mat-header-cell *matHeaderCellDef>Batch</th>\n <td mat-cell *matCellDef=\"let element\">\n <p class=\"mb-0\" *ngIf=\"element?.stock_issue_products[0]?.batch?.batch_number\">{{ element?.stock_issue_products[0]?.batch?.batch_number }}</p>\n <small class=\"text-secondary\" *ngIf=\"element?.stock_issue_products[0]?.batch?.expires_on\">\n Expires {{ element?.stock_issue_products[0]?.batch?.expires_on | date }}\n </small>\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"measure\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Measure</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.stock_issue_products[0]?.product.measure?.title }}</td>\n </ng-container>\n\n <!-- Purchase Price Column -->\n <ng-container matColumnDef=\"purchase_price\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Purchase Price</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element?.purchase_price | currency }}\n </td>\n </ng-container>\n\n <!-- Total Value Column -->\n <ng-container matColumnDef=\"amount\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Total Value</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element?.amount | currency }}\n </td>\n </ng-container>\n\n <!-- Particulars Column -->\n <ng-container matColumnDef=\"particulars\">\n <th mat-header-cell *matHeaderCellDef>Particulars</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.stock_issue_products[0]?.particulars }}</td>\n </ng-container>\n\n <!-- Supplier Column -->\n <ng-container matColumnDef=\"supplier\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Supplier</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element?.supplier?.company_name }}\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-1\">{{ element?.creator?.name }}</p>\n <small class=\"text-secondary\">{{ element?.created_at | date }}</small>\n </td>\n </ng-container>\n\n <!-- Actions Column -->\n <ng-container matColumnDef=\"actions\">\n <th mat-header-cell *matHeaderCellDef>Actions</th>\n <td mat-cell *matCellDef=\"let element\">\n <div *ngIf=\"!element.stock_transfer\" class=\"d-flex gap-1\">\n <app-stock-issue-form-button [stockIssue]=\"element\"\n (saved)=\"reload(); listUpdated.emit()\"></app-stock-issue-form-button>\n <app-stock-issuance-delete-button [stockIssuance]=\"element\"\n (deleted)=\"reload(); listUpdated.emit()\"></app-stock-issuance-delete-button>\n </div>\n\n <span *ngIf=\"element.stock_transfer\" class=\"badge rounded-pill text-bg-secondary\">Stock Transfer</span>\n </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns\"></tr>\n </table>\n\n <mat-progress-bar *ngIf=\"isWorking\" mode=\"indeterminate\"></mat-progress-bar>\n </mat-card-content>\n</mat-card>", styles: [""], dependencies: [{ kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i8.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i8.MatLabel, selector: "mat-label" }, { kind: "directive", type: i9.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: i13.MatSort, selector: "[matSort]", inputs: ["matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear", "matSortDisabled"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i13.MatSortHeader, selector: "[mat-sort-header]", inputs: ["mat-sort-header", "arrowPosition", "start", "disabled", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "component", type: i15.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i15.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i15.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i15.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i15.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i15.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i15.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i15.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i15.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i15.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "component", type: i4.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i4.MatCardContent, selector: "mat-card-content" }, { kind: "directive", type: i2$2.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: i5$1.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "component", type: StockIssueFormButtonComponent, selector: "app-stock-issue-form-button", inputs: ["product", "stockIssueProduct", "stockIssue", "icon", "issuableType", "issuableId"], outputs: ["saved"] }, { kind: "directive", type: i11.InfiniteScrollDirective, selector: "[infiniteScroll], [infinite-scroll], [data-infinite-scroll]", inputs: ["infiniteScrollDistance", "infiniteScrollUpDistance", "infiniteScrollThrottle", "infiniteScrollDisabled", "infiniteScrollContainer", "scrollWindow", "immediateCheck", "horizontal", "alwaysCallback", "fromRoot"], outputs: ["scrolled", "scrolledUp"] }, { kind: "component", type: StockIssuanceDeleteButtonComponent, selector: "app-stock-issuance-delete-button", inputs: ["stockIssuance"], outputs: ["deleted"] }, { kind: "directive", type: i4$1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: i1.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", "required", "disabled", "value"], outputs: ["selectedValueChange", "selectionChange", "itemsChange"] }, { kind: "component", type: i1.TimelineFilterComponent, selector: "app-timeline-filter", inputs: ["defaultValue", "required", "disabled", "value", "timelines", "dateFrom", "dateTo", "appearance", "showClearButton", "form", "labelText"], outputs: ["selectionChange"] }, { kind: "directive", type: i2$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: ProductCategoryBadgesComponent, selector: "app-product-category-badges", inputs: ["product"] }, { kind: "component", type: i1.ColumnSelectorComponent, selector: "app-column-selector", inputs: ["label", "mode", "columnConfigs", "selectedColumns"], outputs: ["selectedColumnsChange", "displayedColumnsChange"] }, { kind: "pipe", type: i5.CurrencyPipe, name: "currency" }, { kind: "pipe", type: i5.DatePipe, name: "date" }], preserveWhitespaces: true });
2124
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: StockIssuancesListComponent, selector: "app-stock-issuances-list", inputs: { product: "product", issuableType: "issuableType", issuableId: "issuableId", label: "label", showActions: "showActions", showFilters: "showFilters" }, outputs: { listUpdated: "listUpdated" }, usesInheritance: true, ngImport: i0, template: "<mat-card *ngIf=\"!product\" class=\"mb-2\">\n <mat-card-content class=\"d-flex justify-content-between align-items-center gap-3\">\n <div class=\"d-flex justify-content-start align-items-center gap-2\">\n <h3 class=\"mb-0\">{{ label }}</h3>\n\n <app-stock-issue-form-button icon=\"add\" [issuableType]=\"issuableType\" [issuableId]=\"issuableId\"\n (saved)=\"reload()\"></app-stock-issue-form-button>\n\n <span *ngIf=\"showActions\" matTooltip=\"Import\" routerLink=\"import\"\n class=\"cursor-pointer material-symbols-outlined\">\n file_upload\n </span>\n\n <app-column-selector *ngIf=\"showActions\" mode=\"icon\" class=\"mt-2 d-print-none\" [columnConfigs]=\"columnConfig\"\n [(selectedColumns)]=\"selectedColumns\"></app-column-selector>\n </div>\n\n <form [formGroup]=\"filterForm\" *ngIf=\"showFilters\">\n <mat-form-field>\n <mat-label>Search</mat-label>\n <input matInput placeholder=\"Search products\" formControlName=\"search\" />\n </mat-form-field>\n\n <app-timeline-filter appearance=\"fill\" labelText=\"Date\" formControlName=\"duration\"\n (selectionChange)=\"onDurationChange($event)\" [showClearButton]=\"true\" [dateFrom]=\"filterForm.value?.date_from\"\n [dateTo]=\"filterForm.value?.date_to\"></app-timeline-filter>\n\n <mat-form-field>\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>\n <mat-label>Measure</mat-label>\n <app-searchable-selector apiUrl=\"api/product-measures\" formControlName=\"measure_ids\" [multiple]=\"true\">\n </app-searchable-selector>\n </mat-form-field>\n\n <mat-form-field>\n <mat-label>Location</mat-label>\n <app-searchable-selector apiUrl=\"api/inventory-locations\" formControlName=\"location_ids\" [multiple]=\"true\">\n </app-searchable-selector>\n </mat-form-field>\n </form>\n </mat-card-content>\n</mat-card>\n\n<mat-card>\n <mat-card-content *ngIf=\"product\" class=\"mb-0\">\n <div class=\"d-flex justify-content-start align-items-center gap-2 mb-2\">\n <span class=\"material-symbols-outlined\"> ungroup </span>\n <h3 class=\"mb-0\">Stock Issues</h3>\n\n <app-stock-issue-form-button class=\"mt-2\" [product]=\"product\" icon=\"add\"\n (saved)=\"reload(); listUpdated.emit()\"></app-stock-issue-form-button>\n </div>\n </mat-card-content>\n <mat-card-content class=\"p-0\">\n <table mat-table [dataSource]=\"models\" class=\"w-100\" aria-describedby=\"Stock Issuances\" infiniteScroll\n [infiniteScrollDistance]=\"2\" [infiniteScrollThrottle]=\"50\" (scrolled)=\"onScroll()\" matSort\n (matSortChange)=\"onSortChange($event)\">\n <!-- # Column -->\n <ng-container matColumnDef=\"no\">\n <th mat-header-cell *matHeaderCellDef>#</th>\n <td mat-cell *matCellDef=\"let element; let i = index\">{{ i + 1 }}</td>\n </ng-container>\n\n <!-- Product Column -->\n <ng-container matColumnDef=\"product\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Product</th>\n <td mat-cell *matCellDef=\"let element\">\n <div class=\"d-flex flex-column gap-1\">\n <a class=\"text-decoration-none text-dark\"\n [routerLink]=\"['/inventory/products', element?.stock_issue_products[0]?.product?.id, 'view']\">\n {{ element?.stock_issue_products[0]?.product.name }}\n </a>\n <app-product-category-badges\n [product]=\"element?.stock_issue_products[0]?.product\"></app-product-category-badges>\n </div>\n </td>\n </ng-container>\n\n <!-- SKU Column -->\n <ng-container matColumnDef=\"sku\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>SKU</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.stock_issue_products[0]?.product.sku }}</td>\n </ng-container>\n\n <!-- Date Column -->\n <ng-container matColumnDef=\"date\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Date</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.date | date }}</td>\n </ng-container>\n\n <!-- Location Column -->\n <ng-container matColumnDef=\"location\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Location</th>\n <td mat-cell *matCellDef=\"let element\">\n <a class=\"text-decoration-none text-dark\"\n [routerLink]=\"['/inventory/locations', element?.stock_issue_products[0]?.location_id, 'view']\">\n {{ element?.stock_issue_products[0]?.location?.title }}\n </a>\n </td>\n </ng-container>\n\n <!-- Related Column -->\n <ng-container matColumnDef=\"related\">\n <th mat-header-cell *matHeaderCellDef>Related</th>\n <td mat-cell *matCellDef=\"let element\">\n <a class=\"text-dark\" *ngIf=\"element?.issuable\" [routerLink]=\"['/maintenances', element?.issuable_id, 'view']\">\n Maintenance for {{ element?.issuable?.fixed_asset?.name }}\n </a>\n </td>\n </ng-container>\n\n <!-- Quantity Column -->\n <ng-container matColumnDef=\"quantity\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Quantity</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.stock_issue_products[0]?.quantity }} {{\n element?.stock_issue_products[0]?.product.measure?.title }}</td>\n </ng-container>\n\n <!-- Batch Column -->\n <ng-container matColumnDef=\"batch\">\n <th mat-header-cell *matHeaderCellDef>Batch</th>\n <td mat-cell *matCellDef=\"let element\">\n <p class=\"mb-0\" *ngIf=\"element?.stock_issue_products[0]?.batch?.batch_number\">{{ element?.stock_issue_products[0]?.batch?.batch_number }}</p>\n <small class=\"text-secondary\" *ngIf=\"element?.stock_issue_products[0]?.batch?.expires_on\">\n Expires {{ element?.stock_issue_products[0]?.batch?.expires_on | date }}\n </small>\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"measure\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Measure</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.stock_issue_products[0]?.product.measure?.title }}</td>\n </ng-container>\n\n <!-- Purchase Price Column -->\n <ng-container matColumnDef=\"purchase_price\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Purchase Price</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element?.purchase_price | currency }}\n </td>\n </ng-container>\n\n <!-- Total Value Column -->\n <ng-container matColumnDef=\"amount\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Total Value</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element?.amount | currency }}\n </td>\n </ng-container>\n\n <!-- Particulars Column -->\n <ng-container matColumnDef=\"particulars\">\n <th mat-header-cell *matHeaderCellDef>Particulars</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.stock_issue_products[0]?.particulars }}</td>\n </ng-container>\n\n <!-- Supplier Column -->\n <ng-container matColumnDef=\"supplier\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Supplier</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element?.supplier?.company_name }}\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-1\">{{ element?.creator?.name }}</p>\n <small class=\"text-secondary\">{{ element?.created_at | date }}</small>\n </td>\n </ng-container>\n\n <!-- Actions Column -->\n <ng-container matColumnDef=\"actions\">\n <th mat-header-cell *matHeaderCellDef>Actions</th>\n <td mat-cell *matCellDef=\"let element\">\n <div *ngIf=\"!element.stock_transfer\" class=\"d-flex gap-1\">\n <app-stock-issue-form-button [stockIssue]=\"element\"\n (saved)=\"reload(); listUpdated.emit()\"></app-stock-issue-form-button>\n <app-stock-issuance-delete-button [stockIssuance]=\"element\"\n (deleted)=\"reload(); listUpdated.emit()\"></app-stock-issuance-delete-button>\n </div>\n\n <span *ngIf=\"element.stock_transfer\" class=\"badge rounded-pill text-bg-secondary\">Stock Transfer</span>\n </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns\"></tr>\n </table>\n\n <mat-progress-bar *ngIf=\"isWorking\" mode=\"indeterminate\"></mat-progress-bar>\n </mat-card-content>\n</mat-card>", styles: [""], dependencies: [{ kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i8.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i8.MatLabel, selector: "mat-label" }, { kind: "directive", type: i9.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: i13.MatSort, selector: "[matSort]", inputs: ["matSortActive", "matSortStart", "matSortDirection", "matSortDisableClear", "matSortDisabled"], outputs: ["matSortChange"], exportAs: ["matSort"] }, { kind: "component", type: i13.MatSortHeader, selector: "[mat-sort-header]", inputs: ["mat-sort-header", "arrowPosition", "start", "disabled", "sortActionDescription", "disableClear"], exportAs: ["matSortHeader"] }, { kind: "component", type: i15.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i15.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i15.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i15.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i15.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i15.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i15.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i15.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i15.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i15.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "component", type: i4.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "directive", type: i4.MatCardContent, selector: "mat-card-content" }, { kind: "directive", type: i2$2.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: i5$1.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "component", type: StockIssueFormButtonComponent, selector: "app-stock-issue-form-button", inputs: ["product", "stockIssueProduct", "stockIssue", "icon", "issuableType", "issuableId"], outputs: ["saved"] }, { kind: "directive", type: i11.InfiniteScrollDirective, selector: "[infiniteScroll], [infinite-scroll], [data-infinite-scroll]", inputs: ["infiniteScrollDistance", "infiniteScrollUpDistance", "infiniteScrollThrottle", "infiniteScrollDisabled", "infiniteScrollContainer", "scrollWindow", "immediateCheck", "horizontal", "alwaysCallback", "fromRoot"], outputs: ["scrolled", "scrolledUp"] }, { kind: "component", type: StockIssuanceDeleteButtonComponent, selector: "app-stock-issuance-delete-button", inputs: ["stockIssuance"], outputs: ["deleted"] }, { kind: "directive", type: i4$1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: i1.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", "required", "disabled", "value"], outputs: ["selectedValueChange", "selectionChange", "itemsChange"] }, { kind: "component", type: i1.TimelineFilterComponent, selector: "app-timeline-filter", inputs: ["defaultValue", "required", "disabled", "value", "timelines", "dateFrom", "dateTo", "appearance", "showClearButton", "form", "labelText"], outputs: ["selectionChange"] }, { kind: "directive", type: i2$1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2$1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2$1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2$1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2$1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: ProductCategoryBadgesComponent, selector: "app-product-category-badges", inputs: ["product"] }, { kind: "component", type: i1.ColumnSelectorComponent, selector: "app-column-selector", inputs: ["label", "mode", "columnConfigs", "selectedColumns"], outputs: ["selectedColumnsChange", "displayedColumnsChange"] }, { kind: "pipe", type: i5.CurrencyPipe, name: "currency" }, { kind: "pipe", type: i5.DatePipe, name: "date" }], preserveWhitespaces: true });
2125
2125
  }
2126
2126
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: StockIssuancesListComponent, decorators: [{
2127
2127
  type: Component,
2128
- args: [{ selector: 'app-stock-issuances-list', template: "<mat-card *ngIf=\"!product\" class=\"mb-2\">\n <mat-card-content class=\"d-flex justify-content-between align-items-center gap-3\">\n <div class=\"d-flex justify-content-start align-items-center gap-2\">\n <h3 class=\"mb-0\">{{ label }}</h3>\n\n <app-stock-issue-form-button icon=\"add\" [issuableType]=\"issuableType\" [issuableId]=\"issuableId\"\n (saved)=\"reload()\"></app-stock-issue-form-button>\n\n <span *ngIf=\"showActions\" matTooltip=\"Import\" routerLink=\"import\"\n class=\"cursor-pointer material-symbols-outlined\">\n file_upload\n </span>\n\n <app-column-selector *ngIf=\"showActions\" mode=\"icon\" class=\"mt-2 d-print-none\" [columnConfigs]=\"columnConfig\"\n [(selectedColumns)]=\"selectedColumns\"></app-column-selector>\n </div>\n\n <form [formGroup]=\"filterForm\" *ngIf=\"showFilters\">\n <mat-form-field>\n <mat-label>Search</mat-label>\n <input matInput placeholder=\"Search products\" formControlName=\"search\" />\n </mat-form-field>\n\n <app-timeline-filter appearance=\"fill\" labelText=\"Date\" formControlName=\"duration\"\n (selectionChange)=\"onDurationChange($event)\" [showClearButton]=\"true\" [dateFrom]=\"filterForm.value?.date_from\"\n [dateTo]=\"filterForm.value?.date_to\"></app-timeline-filter>\n\n <mat-form-field>\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>\n <mat-label>Measure</mat-label>\n <app-searchable-selector apiUrl=\"api/product-measures\" formControlName=\"measure_ids\" [multiple]=\"true\">\n </app-searchable-selector>\n </mat-form-field>\n\n <mat-form-field>\n <mat-label>Location</mat-label>\n <app-searchable-selector apiUrl=\"api/inventory-locations\" formControlName=\"location_ids\" [multiple]=\"true\">\n </app-searchable-selector>\n </mat-form-field>\n </form>\n </mat-card-content>\n</mat-card>\n\n<mat-card>\n <mat-card-content *ngIf=\"product\" class=\"mb-0\">\n <div class=\"d-flex justify-content-start align-items-center gap-2 mb-2\">\n <span class=\"material-symbols-outlined\"> ungroup </span>\n <h3 class=\"mb-0\">Stock Issues</h3>\n\n <app-stock-issue-form-button class=\"mt-2\" [product]=\"product\" icon=\"add\"\n (saved)=\"reload(); listUpdated.emit()\"></app-stock-issue-form-button>\n </div>\n </mat-card-content>\n <mat-card-content class=\"p-0\">\n <table mat-table [dataSource]=\"models\" class=\"w-100\" aria-describedby=\"Stock Issuances\" infiniteScroll\n [infiniteScrollDistance]=\"2\" [infiniteScrollThrottle]=\"50\" (scrolled)=\"onScroll()\" matSort\n (matSortChange)=\"onSortChange($event)\">\n <!-- # Column -->\n <ng-container matColumnDef=\"no\">\n <th mat-header-cell *matHeaderCellDef>#</th>\n <td mat-cell *matCellDef=\"let element; let i = index\">{{ i + 1 }}</td>\n </ng-container>\n\n <!-- Product Column -->\n <ng-container matColumnDef=\"product\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Product</th>\n <td mat-cell *matCellDef=\"let element\">\n <div class=\"d-flex flex-column gap-1\">\n <a class=\"text-decoration-none text-dark\"\n [routerLink]=\"['/inventory/products', element?.stock_issue_products[0]?.product.id, 'view']\">\n {{ element?.stock_issue_products[0]?.product.name }}\n </a>\n <app-product-category-badges\n [product]=\"element?.stock_issue_products[0]?.product\"></app-product-category-badges>\n </div>\n </td>\n </ng-container>\n\n <!-- SKU Column -->\n <ng-container matColumnDef=\"sku\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>SKU</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.stock_issue_products[0]?.product.sku }}</td>\n </ng-container>\n\n <!-- Date Column -->\n <ng-container matColumnDef=\"date\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Date</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.date | date }}</td>\n </ng-container>\n\n <!-- Location Column -->\n <ng-container matColumnDef=\"location\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Location</th>\n <td mat-cell *matCellDef=\"let element\">\n <a class=\"text-decoration-none text-dark\"\n [routerLink]=\"['/inventory/locations', element?.stock_issue_products[0]?.location_id, 'view']\">\n {{ element?.stock_issue_products[0]?.location?.title }}\n </a>\n </td>\n </ng-container>\n\n <!-- Related Column -->\n <ng-container matColumnDef=\"related\">\n <th mat-header-cell *matHeaderCellDef>Related</th>\n <td mat-cell *matCellDef=\"let element\">\n <a class=\"text-dark\" *ngIf=\"element?.issuable\" [routerLink]=\"['/maintenances', element?.issuable_id, 'view']\">\n Maintenance for {{ element?.issuable?.fixed_asset?.name }}\n </a>\n </td>\n </ng-container>\n\n <!-- Quantity Column -->\n <ng-container matColumnDef=\"quantity\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Quantity</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.stock_issue_products[0]?.quantity }} {{\n element?.stock_issue_products[0]?.product.measure?.title }}</td>\n </ng-container>\n\n <!-- Batch Column -->\n <ng-container matColumnDef=\"batch\">\n <th mat-header-cell *matHeaderCellDef>Batch</th>\n <td mat-cell *matCellDef=\"let element\">\n <p class=\"mb-0\" *ngIf=\"element?.stock_issue_products[0]?.batch?.batch_number\">{{ element?.stock_issue_products[0]?.batch?.batch_number }}</p>\n <small class=\"text-secondary\" *ngIf=\"element?.stock_issue_products[0]?.batch?.expires_on\">\n Expires {{ element?.stock_issue_products[0]?.batch?.expires_on | date }}\n </small>\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"measure\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Measure</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.stock_issue_products[0]?.product.measure?.title }}</td>\n </ng-container>\n\n <!-- Purchase Price Column -->\n <ng-container matColumnDef=\"purchase_price\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Purchase Price</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element?.purchase_price | currency }}\n </td>\n </ng-container>\n\n <!-- Total Value Column -->\n <ng-container matColumnDef=\"amount\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Total Value</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element?.amount | currency }}\n </td>\n </ng-container>\n\n <!-- Particulars Column -->\n <ng-container matColumnDef=\"particulars\">\n <th mat-header-cell *matHeaderCellDef>Particulars</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.stock_issue_products[0]?.particulars }}</td>\n </ng-container>\n\n <!-- Supplier Column -->\n <ng-container matColumnDef=\"supplier\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Supplier</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element?.supplier?.company_name }}\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-1\">{{ element?.creator?.name }}</p>\n <small class=\"text-secondary\">{{ element?.created_at | date }}</small>\n </td>\n </ng-container>\n\n <!-- Actions Column -->\n <ng-container matColumnDef=\"actions\">\n <th mat-header-cell *matHeaderCellDef>Actions</th>\n <td mat-cell *matCellDef=\"let element\">\n <div *ngIf=\"!element.stock_transfer\" class=\"d-flex gap-1\">\n <app-stock-issue-form-button [stockIssue]=\"element\"\n (saved)=\"reload(); listUpdated.emit()\"></app-stock-issue-form-button>\n <app-stock-issuance-delete-button [stockIssuance]=\"element\"\n (deleted)=\"reload(); listUpdated.emit()\"></app-stock-issuance-delete-button>\n </div>\n\n <span *ngIf=\"element.stock_transfer\" class=\"badge rounded-pill text-bg-secondary\">Stock Transfer</span>\n </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns\"></tr>\n </table>\n\n <mat-progress-bar *ngIf=\"isWorking\" mode=\"indeterminate\"></mat-progress-bar>\n </mat-card-content>\n</mat-card>" }]
2128
+ args: [{ selector: 'app-stock-issuances-list', template: "<mat-card *ngIf=\"!product\" class=\"mb-2\">\n <mat-card-content class=\"d-flex justify-content-between align-items-center gap-3\">\n <div class=\"d-flex justify-content-start align-items-center gap-2\">\n <h3 class=\"mb-0\">{{ label }}</h3>\n\n <app-stock-issue-form-button icon=\"add\" [issuableType]=\"issuableType\" [issuableId]=\"issuableId\"\n (saved)=\"reload()\"></app-stock-issue-form-button>\n\n <span *ngIf=\"showActions\" matTooltip=\"Import\" routerLink=\"import\"\n class=\"cursor-pointer material-symbols-outlined\">\n file_upload\n </span>\n\n <app-column-selector *ngIf=\"showActions\" mode=\"icon\" class=\"mt-2 d-print-none\" [columnConfigs]=\"columnConfig\"\n [(selectedColumns)]=\"selectedColumns\"></app-column-selector>\n </div>\n\n <form [formGroup]=\"filterForm\" *ngIf=\"showFilters\">\n <mat-form-field>\n <mat-label>Search</mat-label>\n <input matInput placeholder=\"Search products\" formControlName=\"search\" />\n </mat-form-field>\n\n <app-timeline-filter appearance=\"fill\" labelText=\"Date\" formControlName=\"duration\"\n (selectionChange)=\"onDurationChange($event)\" [showClearButton]=\"true\" [dateFrom]=\"filterForm.value?.date_from\"\n [dateTo]=\"filterForm.value?.date_to\"></app-timeline-filter>\n\n <mat-form-field>\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>\n <mat-label>Measure</mat-label>\n <app-searchable-selector apiUrl=\"api/product-measures\" formControlName=\"measure_ids\" [multiple]=\"true\">\n </app-searchable-selector>\n </mat-form-field>\n\n <mat-form-field>\n <mat-label>Location</mat-label>\n <app-searchable-selector apiUrl=\"api/inventory-locations\" formControlName=\"location_ids\" [multiple]=\"true\">\n </app-searchable-selector>\n </mat-form-field>\n </form>\n </mat-card-content>\n</mat-card>\n\n<mat-card>\n <mat-card-content *ngIf=\"product\" class=\"mb-0\">\n <div class=\"d-flex justify-content-start align-items-center gap-2 mb-2\">\n <span class=\"material-symbols-outlined\"> ungroup </span>\n <h3 class=\"mb-0\">Stock Issues</h3>\n\n <app-stock-issue-form-button class=\"mt-2\" [product]=\"product\" icon=\"add\"\n (saved)=\"reload(); listUpdated.emit()\"></app-stock-issue-form-button>\n </div>\n </mat-card-content>\n <mat-card-content class=\"p-0\">\n <table mat-table [dataSource]=\"models\" class=\"w-100\" aria-describedby=\"Stock Issuances\" infiniteScroll\n [infiniteScrollDistance]=\"2\" [infiniteScrollThrottle]=\"50\" (scrolled)=\"onScroll()\" matSort\n (matSortChange)=\"onSortChange($event)\">\n <!-- # Column -->\n <ng-container matColumnDef=\"no\">\n <th mat-header-cell *matHeaderCellDef>#</th>\n <td mat-cell *matCellDef=\"let element; let i = index\">{{ i + 1 }}</td>\n </ng-container>\n\n <!-- Product Column -->\n <ng-container matColumnDef=\"product\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Product</th>\n <td mat-cell *matCellDef=\"let element\">\n <div class=\"d-flex flex-column gap-1\">\n <a class=\"text-decoration-none text-dark\"\n [routerLink]=\"['/inventory/products', element?.stock_issue_products[0]?.product?.id, 'view']\">\n {{ element?.stock_issue_products[0]?.product.name }}\n </a>\n <app-product-category-badges\n [product]=\"element?.stock_issue_products[0]?.product\"></app-product-category-badges>\n </div>\n </td>\n </ng-container>\n\n <!-- SKU Column -->\n <ng-container matColumnDef=\"sku\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>SKU</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.stock_issue_products[0]?.product.sku }}</td>\n </ng-container>\n\n <!-- Date Column -->\n <ng-container matColumnDef=\"date\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Date</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.date | date }}</td>\n </ng-container>\n\n <!-- Location Column -->\n <ng-container matColumnDef=\"location\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Location</th>\n <td mat-cell *matCellDef=\"let element\">\n <a class=\"text-decoration-none text-dark\"\n [routerLink]=\"['/inventory/locations', element?.stock_issue_products[0]?.location_id, 'view']\">\n {{ element?.stock_issue_products[0]?.location?.title }}\n </a>\n </td>\n </ng-container>\n\n <!-- Related Column -->\n <ng-container matColumnDef=\"related\">\n <th mat-header-cell *matHeaderCellDef>Related</th>\n <td mat-cell *matCellDef=\"let element\">\n <a class=\"text-dark\" *ngIf=\"element?.issuable\" [routerLink]=\"['/maintenances', element?.issuable_id, 'view']\">\n Maintenance for {{ element?.issuable?.fixed_asset?.name }}\n </a>\n </td>\n </ng-container>\n\n <!-- Quantity Column -->\n <ng-container matColumnDef=\"quantity\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Quantity</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.stock_issue_products[0]?.quantity }} {{\n element?.stock_issue_products[0]?.product.measure?.title }}</td>\n </ng-container>\n\n <!-- Batch Column -->\n <ng-container matColumnDef=\"batch\">\n <th mat-header-cell *matHeaderCellDef>Batch</th>\n <td mat-cell *matCellDef=\"let element\">\n <p class=\"mb-0\" *ngIf=\"element?.stock_issue_products[0]?.batch?.batch_number\">{{ element?.stock_issue_products[0]?.batch?.batch_number }}</p>\n <small class=\"text-secondary\" *ngIf=\"element?.stock_issue_products[0]?.batch?.expires_on\">\n Expires {{ element?.stock_issue_products[0]?.batch?.expires_on | date }}\n </small>\n </td>\n </ng-container>\n\n <ng-container matColumnDef=\"measure\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Measure</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.stock_issue_products[0]?.product.measure?.title }}</td>\n </ng-container>\n\n <!-- Purchase Price Column -->\n <ng-container matColumnDef=\"purchase_price\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Purchase Price</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element?.purchase_price | currency }}\n </td>\n </ng-container>\n\n <!-- Total Value Column -->\n <ng-container matColumnDef=\"amount\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Total Value</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element?.amount | currency }}\n </td>\n </ng-container>\n\n <!-- Particulars Column -->\n <ng-container matColumnDef=\"particulars\">\n <th mat-header-cell *matHeaderCellDef>Particulars</th>\n <td mat-cell *matCellDef=\"let element\">{{ element?.stock_issue_products[0]?.particulars }}</td>\n </ng-container>\n\n <!-- Supplier Column -->\n <ng-container matColumnDef=\"supplier\">\n <th mat-header-cell *matHeaderCellDef mat-sort-header>Supplier</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element?.supplier?.company_name }}\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-1\">{{ element?.creator?.name }}</p>\n <small class=\"text-secondary\">{{ element?.created_at | date }}</small>\n </td>\n </ng-container>\n\n <!-- Actions Column -->\n <ng-container matColumnDef=\"actions\">\n <th mat-header-cell *matHeaderCellDef>Actions</th>\n <td mat-cell *matCellDef=\"let element\">\n <div *ngIf=\"!element.stock_transfer\" class=\"d-flex gap-1\">\n <app-stock-issue-form-button [stockIssue]=\"element\"\n (saved)=\"reload(); listUpdated.emit()\"></app-stock-issue-form-button>\n <app-stock-issuance-delete-button [stockIssuance]=\"element\"\n (deleted)=\"reload(); listUpdated.emit()\"></app-stock-issuance-delete-button>\n </div>\n\n <span *ngIf=\"element.stock_transfer\" class=\"badge rounded-pill text-bg-secondary\">Stock Transfer</span>\n </td>\n </ng-container>\n\n <tr mat-header-row *matHeaderRowDef=\"displayedColumns\"></tr>\n <tr mat-row *matRowDef=\"let row; columns: displayedColumns\"></tr>\n </table>\n\n <mat-progress-bar *ngIf=\"isWorking\" mode=\"indeterminate\"></mat-progress-bar>\n </mat-card-content>\n</mat-card>" }]
2129
2129
  }], ctorParameters: () => [{ type: i2$1.FormBuilder }, { type: i1.RequestHelperService }, { type: StockIssuanceService }, { type: i4$1.ActivatedRoute }, { type: i1.TechlifyFeatureService }], propDecorators: { product: [{
2130
2130
  type: Input
2131
2131
  }], issuableType: [{