ngx-techlify-checksheet 18.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/README.md +24 -0
  2. package/esm2022/lib/@shared/file-upload-button/file-upload-button.component.mjs +50 -0
  3. package/esm2022/lib/@shared/index.mjs +2 -0
  4. package/esm2022/lib/@shared/material.module.mjs +171 -0
  5. package/esm2022/lib/@shared/shared.module.mjs +54 -0
  6. package/esm2022/lib/checksheet/checksheet-form/checksheet-form.component.mjs +161 -0
  7. package/esm2022/lib/checksheet/checksheet-form-button/checksheet-form-button.component.mjs +58 -0
  8. package/esm2022/lib/checksheet/checksheet-format-list/checksheet-format-list.component.mjs +123 -0
  9. package/esm2022/lib/checksheet/checksheet-format-question.service.mjs +18 -0
  10. package/esm2022/lib/checksheet/checksheet-format.service.mjs +24 -0
  11. package/esm2022/lib/checksheet/checksheet-list/checksheet-list.component.mjs +138 -0
  12. package/esm2022/lib/checksheet/checksheet-node-view/checksheet-node-view.component.mjs +59 -0
  13. package/esm2022/lib/checksheet/checksheet-question/checksheet-question.component.mjs +174 -0
  14. package/esm2022/lib/checksheet/checksheet-question-form/checksheet-question-form.component.mjs +148 -0
  15. package/esm2022/lib/checksheet/checksheet-question-list/checksheet-question-list.component.mjs +161 -0
  16. package/esm2022/lib/checksheet/checksheet-report/checksheet-report.component.mjs +242 -0
  17. package/esm2022/lib/checksheet/checksheet-review-button/checksheet-review-button.component.mjs +68 -0
  18. package/esm2022/lib/checksheet/checksheet-routing.module.mjs +44 -0
  19. package/esm2022/lib/checksheet/checksheet-submission-answer.service.mjs +18 -0
  20. package/esm2022/lib/checksheet/checksheet-submission-delete-button/checksheet-submission-delete-button.component.mjs +52 -0
  21. package/esm2022/lib/checksheet/checksheet-submission-file/checksheet-submission-file-delete-button/checksheet-submission-file-delete-button.component.mjs +55 -0
  22. package/esm2022/lib/checksheet/checksheet-submission-file/checksheet-submission-files/checksheet-submission-files.component.mjs +67 -0
  23. package/esm2022/lib/checksheet/checksheet-submission-file-upload/checksheet-submisison-file-upload.component.mjs +46 -0
  24. package/esm2022/lib/checksheet/checksheet-submission-file.service.mjs +18 -0
  25. package/esm2022/lib/checksheet/checksheet-submission-form/checksheet-submission-form.component.mjs +131 -0
  26. package/esm2022/lib/checksheet/checksheet-submission-form-button/checksheet-submission-form-button.component.mjs +58 -0
  27. package/esm2022/lib/checksheet/checksheet-submission-list/checksheet-submission-list.component.mjs +107 -0
  28. package/esm2022/lib/checksheet/checksheet-submission-review-button/checksheet-submission-review-button.component.mjs +68 -0
  29. package/esm2022/lib/checksheet/checksheet-submission-view/checksheet-submission-view.component.mjs +142 -0
  30. package/esm2022/lib/checksheet/checksheet-submission.service.mjs +36 -0
  31. package/esm2022/lib/checksheet/checksheet-submittable.type.mjs +2 -0
  32. package/esm2022/lib/checksheet/checksheet-view/checksheet-view.component.mjs +140 -0
  33. package/esm2022/lib/checksheet/checksheet.module.mjs +131 -0
  34. package/esm2022/lib/checksheet/checksheet.service.mjs +44 -0
  35. package/esm2022/lib/checksheet/mechanical-issue-form/mechanical-issue-form.component.mjs +73 -0
  36. package/esm2022/ngx-techlify-checksheet.mjs +5 -0
  37. package/esm2022/public-api.mjs +9 -0
  38. package/fesm2022/ngx-techlify-checksheet.mjs +2550 -0
  39. package/fesm2022/ngx-techlify-checksheet.mjs.map +1 -0
  40. package/index.d.ts +5 -0
  41. package/lib/@shared/file-upload-button/file-upload-button.component.d.ts +20 -0
  42. package/lib/@shared/index.d.ts +1 -0
  43. package/lib/@shared/material.module.d.ts +40 -0
  44. package/lib/@shared/shared.module.d.ts +14 -0
  45. package/lib/checksheet/checksheet-form/checksheet-form.component.d.ts +45 -0
  46. package/lib/checksheet/checksheet-form-button/checksheet-form-button.component.d.ts +29 -0
  47. package/lib/checksheet/checksheet-format-list/checksheet-format-list.component.d.ts +19 -0
  48. package/lib/checksheet/checksheet-format-question.service.d.ts +7 -0
  49. package/lib/checksheet/checksheet-format.service.d.ts +10 -0
  50. package/lib/checksheet/checksheet-list/checksheet-list.component.d.ts +31 -0
  51. package/lib/checksheet/checksheet-node-view/checksheet-node-view.component.d.ts +25 -0
  52. package/lib/checksheet/checksheet-question/checksheet-question.component.d.ts +34 -0
  53. package/lib/checksheet/checksheet-question-form/checksheet-question-form.component.d.ts +38 -0
  54. package/lib/checksheet/checksheet-question-list/checksheet-question-list.component.d.ts +26 -0
  55. package/lib/checksheet/checksheet-report/checksheet-report.component.d.ts +47 -0
  56. package/lib/checksheet/checksheet-review-button/checksheet-review-button.component.d.ts +32 -0
  57. package/lib/checksheet/checksheet-routing.module.d.ts +7 -0
  58. package/lib/checksheet/checksheet-submission-answer.service.d.ts +7 -0
  59. package/lib/checksheet/checksheet-submission-delete-button/checksheet-submission-delete-button.component.d.ts +24 -0
  60. package/lib/checksheet/checksheet-submission-file/checksheet-submission-file-delete-button/checksheet-submission-file-delete-button.component.d.ts +24 -0
  61. package/lib/checksheet/checksheet-submission-file/checksheet-submission-files/checksheet-submission-files.component.d.ts +17 -0
  62. package/lib/checksheet/checksheet-submission-file-upload/checksheet-submisison-file-upload.component.d.ts +13 -0
  63. package/lib/checksheet/checksheet-submission-file.service.d.ts +7 -0
  64. package/lib/checksheet/checksheet-submission-form/checksheet-submission-form.component.d.ts +27 -0
  65. package/lib/checksheet/checksheet-submission-form-button/checksheet-submission-form-button.component.d.ts +29 -0
  66. package/lib/checksheet/checksheet-submission-list/checksheet-submission-list.component.d.ts +24 -0
  67. package/lib/checksheet/checksheet-submission-review-button/checksheet-submission-review-button.component.d.ts +32 -0
  68. package/lib/checksheet/checksheet-submission-view/checksheet-submission-view.component.d.ts +37 -0
  69. package/lib/checksheet/checksheet-submission.service.d.ts +22 -0
  70. package/lib/checksheet/checksheet-submittable.type.d.ts +1 -0
  71. package/lib/checksheet/checksheet-view/checksheet-view.component.d.ts +37 -0
  72. package/lib/checksheet/checksheet.module.d.ts +34 -0
  73. package/lib/checksheet/checksheet.service.d.ts +25 -0
  74. package/lib/checksheet/mechanical-issue-form/mechanical-issue-form.component.d.ts +21 -0
  75. package/package.json +45 -0
  76. package/public-api.d.ts +5 -0
@@ -0,0 +1,161 @@
1
+ import { Component, EventEmitter, Input, Output } from '@angular/core';
2
+ import { ActionPopupComponent } from 'ngx-techlify-core';
3
+ import { ChecksheetQuestionFormComponent } from '../checksheet-question-form/checksheet-question-form.component';
4
+ import * as i0 from "@angular/core";
5
+ import * as i1 from "ngx-spinner";
6
+ import * as i2 from "ngx-techlify-core";
7
+ import * as i3 from "@angular/material/dialog";
8
+ import * as i4 from "@angular/common";
9
+ import * as i5 from "@angular/flex-layout/flex";
10
+ import * as i6 from "@angular/material/button";
11
+ import * as i7 from "@angular/material/card";
12
+ import * as i8 from "@angular/material/icon";
13
+ import * as i9 from "ngx-infinite-scroll";
14
+ import * as i10 from "../checksheet-question/checksheet-question.component";
15
+ export class ChecksheetQuestionListComponent {
16
+ spinnerService;
17
+ alertService;
18
+ dialog;
19
+ dataManager;
20
+ checksheet = {};
21
+ checksheetChange = new EventEmitter();
22
+ submission;
23
+ disableInput;
24
+ questions = [];
25
+ constructor(spinnerService, alertService, dialog, dataManager) {
26
+ this.spinnerService = spinnerService;
27
+ this.alertService = alertService;
28
+ this.dialog = dialog;
29
+ this.dataManager = dataManager;
30
+ }
31
+ ngOnInit() {
32
+ this.questions = this.checksheet?.questions || [];
33
+ }
34
+ onScroll() { }
35
+ editQuestion(question, index) {
36
+ const dialogRef = this.dialog.open(ChecksheetQuestionFormComponent, {
37
+ width: '800px',
38
+ data: {
39
+ update: true,
40
+ question: question
41
+ },
42
+ autoFocus: false
43
+ });
44
+ dialogRef.afterClosed().subscribe((result) => {
45
+ if (result) {
46
+ question = result;
47
+ this.questions[index] = question;
48
+ }
49
+ });
50
+ }
51
+ addQuestion() {
52
+ const dialogRef = this.dialog.open(ChecksheetQuestionFormComponent, {
53
+ width: '800px',
54
+ data: {
55
+ question: {
56
+ format_id: this.checksheet.id
57
+ }
58
+ },
59
+ autoFocus: false
60
+ });
61
+ dialogRef.afterClosed().subscribe((result) => {
62
+ if (result) {
63
+ this.questions.push(result);
64
+ }
65
+ });
66
+ }
67
+ async moveQuestionUp(index) {
68
+ if (index < this.questions.length) {
69
+ this.spinnerService.show();
70
+ try {
71
+ if (index <= 0) {
72
+ return;
73
+ }
74
+ const q1 = this.questions[index];
75
+ const q2 = this.questions[index - 1];
76
+ await this.dataManager.PUT(`api/checksheet-format-questions/${q1.id}`, {
77
+ ...q1,
78
+ rank: index - 1
79
+ });
80
+ await this.dataManager.PUT(`api/checksheet-format-questions/${q2.id}`, {
81
+ ...q2,
82
+ rank: index
83
+ });
84
+ this.questions[index] = q2;
85
+ this.questions[index - 1] = q1;
86
+ }
87
+ catch (error) {
88
+ this.alertService.addAlert('Unable to move question, try later', 'warn');
89
+ }
90
+ finally {
91
+ this.spinnerService.hide();
92
+ }
93
+ }
94
+ }
95
+ async moveQuestionDown(index) {
96
+ if (index < this.questions.length) {
97
+ this.spinnerService.show();
98
+ try {
99
+ const q1 = this.questions[index];
100
+ const q2 = this.questions[index + 1];
101
+ await this.dataManager.PUT(`api/checksheet-format-questions/${q1.id}`, {
102
+ ...q1,
103
+ rank: index + 1
104
+ });
105
+ await this.dataManager.PUT(`api/checksheet-format-questions/${q2.id}`, {
106
+ ...q2,
107
+ rank: index
108
+ });
109
+ this.questions[index] = q2;
110
+ this.questions[index + 1] = q1;
111
+ }
112
+ catch (error) {
113
+ this.alertService.addAlert('Unable to move question, try later', 'warn');
114
+ }
115
+ finally {
116
+ this.spinnerService.hide();
117
+ }
118
+ }
119
+ }
120
+ deleteQuestion(question) {
121
+ const dialogRef = this.dialog.open(ActionPopupComponent, {
122
+ width: '400px',
123
+ data: {
124
+ title: 'Delete Question',
125
+ message: `Are you sure to delete the question?`
126
+ },
127
+ autoFocus: false
128
+ });
129
+ dialogRef.afterClosed().subscribe(async (result) => {
130
+ if (result) {
131
+ //Action confirmed
132
+ try {
133
+ this.spinnerService.show();
134
+ await this.dataManager.DELETE(`api/checksheet-format-questions/${question.id}`);
135
+ this.questions = this.questions.filter((x) => x.id !== question.id);
136
+ }
137
+ catch (error) {
138
+ this.alertService.addAlert('Unable to delete question, try later', 'warn');
139
+ }
140
+ finally {
141
+ this.spinnerService.hide();
142
+ }
143
+ }
144
+ });
145
+ }
146
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ChecksheetQuestionListComponent, deps: [{ token: i1.NgxSpinnerService }, { token: i2.AlertService }, { token: i3.MatDialog }, { token: i2.DataManager }], target: i0.ɵɵFactoryTarget.Component });
147
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: ChecksheetQuestionListComponent, selector: "app-checksheet-question-list", inputs: { checksheet: "checksheet", submission: "submission", disableInput: "disableInput" }, outputs: { checksheetChange: "checksheetChange" }, ngImport: i0, template: "<ng-container *ngIf=\"checksheet?.id\">\n <button\n *ngIf=\"!disableInput\"\n type=\"button\"\n mat-raised-button\n color=\"primary\"\n (click)=\"addQuestion()\"\n class=\"mb-2\"\n >\n Add Question\n </button>\n\n <div\n class=\"d-flex flex-column gap-3 mat-typography scroll-container\"\n infiniteScroll\n [infiniteScrollDistance]=\"1\"\n [infiniteScrollThrottle]=\"50\"\n (scrolled)=\"onScroll()\"\n [scrollWindow]=\"false\"\n >\n <mat-card\n class=\"d-flex flex-column gap-3\"\n *ngFor=\"let question of questions; let i = index\"\n >\n <div\n class=\"d-flex flex-row gap-3 justify-content-end\"\n *ngIf=\"!disableInput\"\n >\n <mat-icon class=\"cursor-pointer\" (click)=\"deleteQuestion(question)\">\n delete\n </mat-icon>\n <mat-icon class=\"cursor-pointer\" (click)=\"editQuestion(question, i)\">\n edit\n </mat-icon>\n <mat-icon\n class=\"cursor-pointer\"\n *ngIf=\"i > 0\"\n (click)=\"moveQuestionUp(i)\"\n >\n arrow_upward\n </mat-icon>\n <mat-icon\n class=\"cursor-pointer\"\n *ngIf=\"i < questions.length - 1\"\n (click)=\"moveQuestionDown(i)\"\n >\n arrow_downward\n </mat-icon>\n </div>\n\n <div>\n <app-checksheet-question\n [questionInfo]=\"question\"\n [index]=\"i\"\n ></app-checksheet-question>\n </div>\n </mat-card>\n </div>\n</ng-container>\n\n<ng-container *ngIf=\"submission?.id\">\n <div fxLayout=\"column\" fxLayoutGap=\"1rem\" class=\"mat-typography\">\n <mat-card\n fxLayout=\"column\"\n fxLayoutGap=\"0.5rem\"\n class=\"w-100\"\n *ngFor=\"let question of submission.format.questions; let i = index\"\n >\n <app-checksheet-question\n [questionInfo]=\"question\"\n [index]=\"i\"\n [submissionView]=\"true\"\n [submissionId]=\"submission.id\"\n [disableInput]=\"disableInput\"\n >\n </app-checksheet-question>\n </mat-card>\n </div>\n</ng-container>\n", styles: [""], dependencies: [{ kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.DefaultLayoutDirective, selector: " [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]", inputs: ["fxLayout", "fxLayout.xs", "fxLayout.sm", "fxLayout.md", "fxLayout.lg", "fxLayout.xl", "fxLayout.lt-sm", "fxLayout.lt-md", "fxLayout.lt-lg", "fxLayout.lt-xl", "fxLayout.gt-xs", "fxLayout.gt-sm", "fxLayout.gt-md", "fxLayout.gt-lg"] }, { kind: "directive", type: i5.DefaultLayoutGapDirective, selector: " [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]", inputs: ["fxLayoutGap", "fxLayoutGap.xs", "fxLayoutGap.sm", "fxLayoutGap.md", "fxLayoutGap.lg", "fxLayoutGap.xl", "fxLayoutGap.lt-sm", "fxLayoutGap.lt-md", "fxLayoutGap.lt-lg", "fxLayoutGap.lt-xl", "fxLayoutGap.gt-xs", "fxLayoutGap.gt-sm", "fxLayoutGap.gt-md", "fxLayoutGap.gt-lg"] }, { kind: "component", type: i6.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i7.MatCard, selector: "mat-card", inputs: ["appearance"], exportAs: ["matCard"] }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i9.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: i10.ChecksheetQuestionComponent, selector: "app-checksheet-question", inputs: ["questionInfo", "index", "submissionView", "submissionId", "disableInput", "isWorking"], outputs: ["isWorkingChange"] }] });
148
+ }
149
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ChecksheetQuestionListComponent, decorators: [{
150
+ type: Component,
151
+ args: [{ selector: 'app-checksheet-question-list', template: "<ng-container *ngIf=\"checksheet?.id\">\n <button\n *ngIf=\"!disableInput\"\n type=\"button\"\n mat-raised-button\n color=\"primary\"\n (click)=\"addQuestion()\"\n class=\"mb-2\"\n >\n Add Question\n </button>\n\n <div\n class=\"d-flex flex-column gap-3 mat-typography scroll-container\"\n infiniteScroll\n [infiniteScrollDistance]=\"1\"\n [infiniteScrollThrottle]=\"50\"\n (scrolled)=\"onScroll()\"\n [scrollWindow]=\"false\"\n >\n <mat-card\n class=\"d-flex flex-column gap-3\"\n *ngFor=\"let question of questions; let i = index\"\n >\n <div\n class=\"d-flex flex-row gap-3 justify-content-end\"\n *ngIf=\"!disableInput\"\n >\n <mat-icon class=\"cursor-pointer\" (click)=\"deleteQuestion(question)\">\n delete\n </mat-icon>\n <mat-icon class=\"cursor-pointer\" (click)=\"editQuestion(question, i)\">\n edit\n </mat-icon>\n <mat-icon\n class=\"cursor-pointer\"\n *ngIf=\"i > 0\"\n (click)=\"moveQuestionUp(i)\"\n >\n arrow_upward\n </mat-icon>\n <mat-icon\n class=\"cursor-pointer\"\n *ngIf=\"i < questions.length - 1\"\n (click)=\"moveQuestionDown(i)\"\n >\n arrow_downward\n </mat-icon>\n </div>\n\n <div>\n <app-checksheet-question\n [questionInfo]=\"question\"\n [index]=\"i\"\n ></app-checksheet-question>\n </div>\n </mat-card>\n </div>\n</ng-container>\n\n<ng-container *ngIf=\"submission?.id\">\n <div fxLayout=\"column\" fxLayoutGap=\"1rem\" class=\"mat-typography\">\n <mat-card\n fxLayout=\"column\"\n fxLayoutGap=\"0.5rem\"\n class=\"w-100\"\n *ngFor=\"let question of submission.format.questions; let i = index\"\n >\n <app-checksheet-question\n [questionInfo]=\"question\"\n [index]=\"i\"\n [submissionView]=\"true\"\n [submissionId]=\"submission.id\"\n [disableInput]=\"disableInput\"\n >\n </app-checksheet-question>\n </mat-card>\n </div>\n</ng-container>\n" }]
152
+ }], ctorParameters: () => [{ type: i1.NgxSpinnerService }, { type: i2.AlertService }, { type: i3.MatDialog }, { type: i2.DataManager }], propDecorators: { checksheet: [{
153
+ type: Input
154
+ }], checksheetChange: [{
155
+ type: Output
156
+ }], submission: [{
157
+ type: Input
158
+ }], disableInput: [{
159
+ type: Input
160
+ }] } });
161
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hlY2tzaGVldC1xdWVzdGlvbi1saXN0LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25neC10ZWNobGlmeS1jaGVja3NoZWV0L3NyYy9saWIvY2hlY2tzaGVldC9jaGVja3NoZWV0LXF1ZXN0aW9uLWxpc3QvY2hlY2tzaGVldC1xdWVzdGlvbi1saXN0LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25neC10ZWNobGlmeS1jaGVja3NoZWV0L3NyYy9saWIvY2hlY2tzaGVldC9jaGVja3NoZWV0LXF1ZXN0aW9uLWxpc3QvY2hlY2tzaGVldC1xdWVzdGlvbi1saXN0LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBVSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFHL0UsT0FBTyxFQUVMLG9CQUFvQixFQUdyQixNQUFNLG1CQUFtQixDQUFDO0FBQzNCLE9BQU8sRUFBRSwrQkFBK0IsRUFBRSxNQUFNLGdFQUFnRSxDQUFDOzs7Ozs7Ozs7Ozs7QUFPakgsTUFBTSxPQUFPLCtCQUErQjtJQVNoQztJQUNBO0lBQ0E7SUFDQTtJQVhELFVBQVUsR0FBUSxFQUFFLENBQUM7SUFDcEIsZ0JBQWdCLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQztJQUV2QyxVQUFVLENBQU87SUFDakIsWUFBWSxDQUFXO0lBQ2hDLFNBQVMsR0FBVSxFQUFFLENBQUM7SUFFdEIsWUFDVSxjQUFpQyxFQUNqQyxZQUEwQixFQUMxQixNQUFpQixFQUNqQixXQUF3QjtRQUh4QixtQkFBYyxHQUFkLGNBQWMsQ0FBbUI7UUFDakMsaUJBQVksR0FBWixZQUFZLENBQWM7UUFDMUIsV0FBTSxHQUFOLE1BQU0sQ0FBVztRQUNqQixnQkFBVyxHQUFYLFdBQVcsQ0FBYTtJQUMvQixDQUFDO0lBRUosUUFB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QUNHLFlBQVk7c0JBQXBCLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIEV2ZW50RW1pdHRlciwgSW5wdXQsIE9uSW5pdCwgT3V0cHV0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBNYXREaWFsb2cgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9kaWFsb2cnO1xuaW1wb3J0IHsgTmd4U3Bpbm5lclNlcnZpY2UgfSBmcm9tICduZ3gtc3Bpbm5lcic7XG5pbXBvcnQge1xuICBBY3Rpb25Qb3B1cCxcbiAgQWN0aW9uUG9wdXBDb21wb25lbnQsXG4gIEFsZXJ0U2VydmljZSxcbiAgRGF0YU1hbmFnZXJcbn0gZnJvbSAnbmd4LXRlY2hsaWZ5LWNvcmUnO1xuaW1wb3J0IHsgQ2hlY2tzaGVldFF1ZXN0aW9uRm9ybUNvbXBvbmVudCB9IGZyb20gJy4uL2NoZWNrc2hlZXQtcXVlc3Rpb24tZm9ybS9jaGVja3NoZWV0LXF1ZXN0aW9uLWZvcm0uY29tcG9uZW50JztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnYXBwLWNoZWNrc2hlZXQtcXVlc3Rpb24tbGlzdCcsXG4gIHRlbXBsYXRlVXJsOiAnLi9jaGVja3NoZWV0LXF1ZXN0aW9uLWxpc3QuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9jaGVja3NoZWV0LXF1ZXN0aW9uLWxpc3QuY29tcG9uZW50LnNjc3MnXVxufSlcbmV4cG9ydCBjbGFzcyBDaGVja3NoZWV0UXVlc3Rpb25MaXN0Q29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcbiAgQElucHV0KCkgY2hlY2tzaGVldDogYW55ID0ge307XG4gIEBPdXRwdXQoKSBjaGVja3NoZWV0Q2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gIEBJbnB1dCgpIHN1Ym1pc3Npb24hOiBhbnk7XG4gIEBJbnB1dCgpIGRpc2FibGVJbnB1dCE6IGJvb2xlYW47XG4gIHF1ZXN0aW9uczogYW55W10gPSBbXTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHNwaW5uZXJTZXJ2aWNlOiBOZ3hTcGlubmVyU2VydmljZSxcbiAgICBwcml2YXRlIGFsZXJ0U2VydmljZTogQWxlcnRTZXJ2aWNlLFxuICAgIHByaXZhdGUgZGlhbG9nOiBNYXREaWFsb2csXG4gICAgcHJpdmF0ZSBkYXRhTWFuYWdlcjogRGF0YU1hbmFnZXJcbiAgKSB7fVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMucXVlc3Rpb25zID0gdGhpcy5jaGVja3NoZWV0Py5xdWVzdGlvbnMgfHwgW107XG4gIH1cblxuICBvblNjcm9sbCgpIHt9XG5cbiAgZWRpdFF1ZXN0aW9uKHF1ZXN0aW9uOiBhbnksIGluZGV4OiBhbnkpIHtcbiAgICBjb25zdCBkaWFsb2dSZWYgPSB0aGlzLmRpYWxvZy5vcGVuKENoZWNrc2hlZXRRdWVzdGlvbkZvcm1Db21wb25lbnQsIHtcbiAgICAgIHdpZHRoOiAnODAwcHgnLFxuICAgICAgZGF0YToge1xuICAgICAgICB1cGRhdGU6IHRydWUsXG4gICAgICAgIHF1ZXN0aW9uOiBxdWVzdGlvblxuICAgICAgfSxcbiAgICAgIGF1dG9Gb2N1czogZmFsc2VcbiAgICB9KTtcblxuICAgIGRpYWxvZ1JlZi5hZnRlckNsb3NlZCgpLnN1YnNjcmliZSgocmVzdWx0KSA9PiB7XG4gICAgICBpZiAocmVzdWx0KSB7XG4gICAgICAgIHF1ZXN0aW9uID0gcmVzdWx0O1xuICAgICAgICB0aGlzLnF1ZXN0aW9uc1tpbmRleF0gPSBxdWVzdGlvbjtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGFkZFF1ZXN0aW9uKCkge1xuICAgIGNvbnN0IGRpYWxvZ1JlZiA9IHRoaXMuZGlhbG9nLm9wZW4oQ2hlY2tzaGVldFF1ZXN0aW9uRm9ybUNvbXBvbmVudCwge1xuICAgICAgd2lkdGg6ICc4MDBweCcsXG4gICAgICBkYXRhOiB7XG4gICAgICAgIHF1ZXN0aW9uOiB7XG4gICAgICAgICAgZm9ybWF0X2lkOiB0aGlzLmNoZWNrc2hlZXQuaWRcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIGF1dG9Gb2N1czogZmFsc2VcbiAgICB9KTtcblxuICAgIGRpYWxvZ1JlZi5hZnRlckNsb3NlZCgpLnN1YnNjcmliZSgocmVzdWx0KSA9PiB7XG4gICAgICBpZiAocmVzdWx0KSB7XG4gICAgICAgIHRoaXMucXVlc3Rpb25zLnB1c2gocmVzdWx0KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIG1vdmVRdWVzdGlvblVwKGluZGV4OiBhbnkpIHtcbiAgICBpZiAoaW5kZXggPCB0aGlzLnF1ZXN0aW9ucy5sZW5ndGgpIHtcbiAgICAgIHRoaXMuc3Bpbm5lclNlcnZpY2Uuc2hvdygpO1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKGluZGV4IDw9IDApIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcTEgPSB0aGlzLnF1ZXN0aW9uc1tpbmRleF07XG4gICAgICAgIGNvbnN0IHEyID0gdGhpcy5xdWVzdGlvbnNbaW5kZXggLSAxXTtcbiAgICAgICAgYXdhaXQgdGhpcy5kYXRhTWFuYWdlci5QVVQoYGFwaS9jaGVja3NoZWV0LWZvcm1hdC1xdWVzdGlvbnMvJHtxMS5pZH1gLCB7XG4gICAgICAgICAgLi4ucTEsXG4gICAgICAgICAgcmFuazogaW5kZXggLSAxXG4gICAgICAgIH0pO1xuICAgICAgICBhd2FpdCB0aGlzLmRhdGFNYW5hZ2VyLlBVVChgYXBpL2NoZWNrc2hlZXQtZm9ybWF0LXF1ZXN0aW9ucy8ke3EyLmlkfWAsIHtcbiAgICAgICAgICAuLi5xMixcbiAgICAgICAgICByYW5rOiBpbmRleFxuICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLnF1ZXN0aW9uc1tpbmRleF0gPSBxMjtcbiAgICAgICAgdGhpcy5xdWVzdGlvbnNbaW5kZXggLSAxXSA9IHExO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgdGhpcy5hbGVydFNlcnZpY2UuYWRkQWxlcnQoXG4gICAgICAgICAgJ1VuYWJsZSB0byBtb3ZlIHF1ZXN0aW9uLCB0cnkgbGF0ZXInLFxuICAgICAgICAgICd3YXJuJ1xuICAgICAgICApO1xuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgdGhpcy5zcGlubmVyU2VydmljZS5oaWRlKCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgYXN5bmMgbW92ZVF1ZXN0aW9uRG93bihpbmRleDogYW55KSB7XG4gICAgaWYgKGluZGV4IDwgdGhpcy5xdWVzdGlvbnMubGVuZ3RoKSB7XG4gICAgICB0aGlzLnNwaW5uZXJTZXJ2aWNlLnNob3coKTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHExID0gdGhpcy5xdWVzdGlvbnNbaW5kZXhdO1xuICAgICAgICBjb25zdCBxMiA9IHRoaXMucXVlc3Rpb25zW2luZGV4ICsgMV07XG4gICAgICAgIGF3YWl0IHRoaXMuZGF0YU1hbmFnZXIuUFVUKGBhcGkvY2hlY2tzaGVldC1mb3JtYXQtcXVlc3Rpb25zLyR7cTEuaWR9YCwge1xuICAgICAgICAgIC4uLnExLFxuICAgICAgICAgIHJhbms6IGluZGV4ICsgMVxuICAgICAgICB9KTtcbiAgICAgICAgYXdhaXQgdGhpcy5kYXRhTWFuYWdlci5QVVQoYGFwaS9jaGVja3NoZWV0LWZvcm1hdC1xdWVzdGlvbnMvJHtxMi5pZH1gLCB7XG4gICAgICAgICAgLi4ucTIsXG4gICAgICAgICAgcmFuazogaW5kZXhcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5xdWVzdGlvbnNbaW5kZXhdID0gcTI7XG4gICAgICAgIHRoaXMucXVlc3Rpb25zW2luZGV4ICsgMV0gPSBxMTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIHRoaXMuYWxlcnRTZXJ2aWNlLmFkZEFsZXJ0KFxuICAgICAgICAgICdVbmFibGUgdG8gbW92ZSBxdWVzdGlvbiwgdHJ5IGxhdGVyJyxcbiAgICAgICAgICAnd2FybidcbiAgICAgICAgKTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIHRoaXMuc3Bpbm5lclNlcnZpY2UuaGlkZSgpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGRlbGV0ZVF1ZXN0aW9uKHF1ZXN0aW9uOiBhbnkpIHtcbiAgICBjb25zdCBkaWFsb2dSZWYgPSB0aGlzLmRpYWxvZy5vcGVuKEFjdGlvblBvcHVwQ29tcG9uZW50LCB7XG4gICAgICB3aWR0aDogJzQwMHB4JyxcbiAgICAgIGRhdGE6IDxBY3Rpb25Qb3B1cD57XG4gICAgICAgIHRpdGxlOiAnRGVsZXRlIFF1ZXN0aW9uJyxcbiAgICAgICAgbWVzc2FnZTogYEFyZSB5b3Ugc3VyZSB0byBkZWxldGUgdGhlIHF1ZXN0aW9uP2BcbiAgICAgIH0sXG4gICAgICBhdXRvRm9jdXM6IGZhbHNlXG4gICAgfSk7XG5cbiAgICBkaWFsb2dSZWYuYWZ0ZXJDbG9zZWQoKS5zdWJzY3JpYmUoYXN5bmMgKHJlc3VsdCkgPT4ge1xuICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICAvL0FjdGlvbiBjb25maXJtZWRcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICB0aGlzLnNwaW5uZXJTZXJ2aWNlLnNob3coKTtcbiAgICAgICAgICBhd2FpdCB0aGlzLmRhdGFNYW5hZ2VyLkRFTEVURShcbiAgICAgICAgICAgIGBhcGkvY2hlY2tzaGVldC1mb3JtYXQtcXVlc3Rpb25zLyR7cXVlc3Rpb24uaWR9YFxuICAgICAgICAgICk7XG4gICAgICAgICAgdGhpcy5xdWVzdGlvbnMgPSB0aGlzLnF1ZXN0aW9ucy5maWx0ZXIoXG4gICAgICAgICAgICAoeDogYW55KSA9PiB4LmlkICE9PSBxdWVzdGlvbi5pZFxuICAgICAgICAgICk7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgdGhpcy5hbGVydFNlcnZpY2UuYWRkQWxlcnQoXG4gICAgICAgICAgICAnVW5hYmxlIHRvIGRlbGV0ZSBxdWVzdGlvbiwgdHJ5IGxhdGVyJyxcbiAgICAgICAgICAgICd3YXJuJ1xuICAgICAgICAgICk7XG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgdGhpcy5zcGlubmVyU2VydmljZS5oaWRlKCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgfVxufVxuIiwiPG5nLWNvbnRhaW5lciAqbmdJZj1cImNoZWNrc2hlZXQ/LmlkXCI+XG4gIDxidXR0b25cbiAgICAqbmdJZj1cIiFkaXNhYmxlSW5wdXRcIlxuICAgIHR5cGU9XCJidXR0b25cIlxuICAgIG1hdC1yYWlzZWQtYnV0dG9uXG4gICAgY29sb3I9XCJwcmltYXJ5XCJcbiAgICAoY2xpY2spPVwiYWRkUXVlc3Rpb24oKVwiXG4gICAgY2xhc3M9XCJtYi0yXCJcbiAgPlxuICAgIEFkZCBRdWVzdGlvblxuICA8L2J1dHRvbj5cblxuICA8ZGl2XG4gICAgY2xhc3M9XCJkLWZsZXggZmxleC1jb2x1bW4gZ2FwLTMgbWF0LXR5cG9ncmFwaHkgc2Nyb2xsLWNvbnRhaW5lclwiXG4gICAgaW5maW5pdGVTY3JvbGxcbiAgICBbaW5maW5pdGVTY3JvbGxEaXN0YW5jZV09XCIxXCJcbiAgICBbaW5maW5pdGVTY3JvbGxUaHJvdHRsZV09XCI1MFwiXG4gICAgKHNjcm9sbGVkKT1cIm9uU2Nyb2xsKClcIlxuICAgIFtzY3JvbGxXaW5kb3ddPVwiZmFsc2VcIlxuICA+XG4gICAgPG1hdC1jYXJkXG4gICAgICBjbGFzcz1cImQtZmxleCBmbGV4LWNvbHVtbiBnYXAtM1wiXG4gICAgICAqbmdGb3I9XCJsZXQgcXVlc3Rpb24gb2YgcXVlc3Rpb25zOyBsZXQgaSA9IGluZGV4XCJcbiAgICA+XG4gICAgICA8ZGl2XG4gICAgICAgIGNsYXNzPVwiZC1mbGV4IGZsZXgtcm93IGdhcC0zIGp1c3RpZnktY29udGVudC1lbmRcIlxuICAgICAgICAqbmdJZj1cIiFkaXNhYmxlSW5wdXRcIlxuICAgICAgPlxuICAgICAgICA8bWF0LWljb24gY2xhc3M9XCJjdXJzb3ItcG9pbnRlclwiIChjbGljayk9XCJkZWxldGVRdWVzdGlvbihxdWVzdGlvbilcIj5cbiAgICAgICAgICBkZWxldGVcbiAgICAgICAgPC9tYXQtaWNvbj5cbiAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwiY3Vyc29yLXBvaW50ZXJcIiAoY2xpY2spPVwiZWRpdFF1ZXN0aW9uKHF1ZXN0aW9uLCBpKVwiPlxuICAgICAgICAgIGVkaXRcbiAgICAgICAgPC9tYXQtaWNvbj5cbiAgICAgICAgPG1hdC1pY29uXG4gICAgICAgICAgY2xhc3M9XCJjdXJzb3ItcG9pbnRlclwiXG4gICAgICAgICAgKm5nSWY9XCJpID4gMFwiXG4gICAgICAgICAgKGNsaWNrKT1cIm1vdmVRdWVzdGlvblVwKGkpXCJcbiAgICAgICAgPlxuICAgICAgICAgIGFycm93X3Vwd2FyZFxuICAgICAgICA8L21hdC1pY29uPlxuICAgICAgICA8bWF0LWljb25cbiAgICAgICAgICBjbGFzcz1cImN1cnNvci1wb2ludGVyXCJcbiAgICAgICAgICAqbmdJZj1cImkgPCBxdWVzdGlvbnMubGVuZ3RoIC0gMVwiXG4gICAgICAgICAgKGNsaWNrKT1cIm1vdmVRdWVzdGlvbkRvd24oaSlcIlxuICAgICAgICA+XG4gICAgICAgICAgYXJyb3dfZG93bndhcmRcbiAgICAgICAgPC9tYXQtaWNvbj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8ZGl2PlxuICAgICAgICA8YXBwLWNoZWNrc2hlZXQtcXVlc3Rpb25cbiAgICAgICAgICBbcXVlc3Rpb25JbmZvXT1cInF1ZXN0aW9uXCJcbiAgICAgICAgICBbaW5kZXhdPVwiaVwiXG4gICAgICAgID48L2FwcC1jaGVja3NoZWV0LXF1ZXN0aW9uPlxuICAgICAgPC9kaXY+XG4gICAgPC9tYXQtY2FyZD5cbiAgPC9kaXY+XG48L25nLWNvbnRhaW5lcj5cblxuPG5nLWNvbnRhaW5lciAqbmdJZj1cInN1Ym1pc3Npb24/LmlkXCI+XG4gIDxkaXYgZnhMYXlvdXQ9XCJjb2x1bW5cIiBmeExheW91dEdhcD1cIjFyZW1cIiBjbGFzcz1cIm1hdC10eXBvZ3JhcGh5XCI+XG4gICAgPG1hdC1jYXJkXG4gICAgICBmeExheW91dD1cImNvbHVtblwiXG4gICAgICBmeExheW91dEdhcD1cIjAuNXJlbVwiXG4gICAgICBjbGFzcz1cInctMTAwXCJcbiAgICAgICpuZ0Zvcj1cImxldCBxdWVzdGlvbiBvZiBzdWJtaXNzaW9uLmZvcm1hdC5xdWVzdGlvbnM7IGxldCBpID0gaW5kZXhcIlxuICAgID5cbiAgICAgIDxhcHAtY2hlY2tzaGVldC1xdWVzdGlvblxuICAgICAgICBbcXVlc3Rpb25JbmZvXT1cInF1ZXN0aW9uXCJcbiAgICAgICAgW2luZGV4XT1cImlcIlxuICAgICAgICBbc3VibWlzc2lvblZpZXddPVwidHJ1ZVwiXG4gICAgICAgIFtzdWJtaXNzaW9uSWRdPVwic3VibWlzc2lvbi5pZFwiXG4gICAgICAgIFtkaXNhYmxlSW5wdXRdPVwiZGlzYWJsZUlucHV0XCJcbiAgICAgID5cbiAgICAgIDwvYXBwLWNoZWNrc2hlZXQtcXVlc3Rpb24+XG4gICAgPC9tYXQtY2FyZD5cbiAgPC9kaXY+XG48L25nLWNvbnRhaW5lcj5cbiJdfQ==
@@ -0,0 +1,242 @@
1
+ import { __decorate } from "tslib";
2
+ import { Component, Input } from '@angular/core';
3
+ import { Validators } from '@angular/forms';
4
+ import { DateValidator } from 'ngx-techlify-core';
5
+ import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
6
+ import { ActionPopupComponent } from 'ngx-techlify-core';
7
+ import { debounceTime } from 'rxjs/operators';
8
+ import { ChecksheetSubmissionFormComponent } from '../checksheet-submission-form/checksheet-submission-form.component';
9
+ import * as i0 from "@angular/core";
10
+ import * as i1 from "ngx-spinner";
11
+ import * as i2 from "ngx-techlify-core";
12
+ import * as i3 from "@angular/router";
13
+ import * as i4 from "@angular/material/dialog";
14
+ import * as i5 from "@angular/forms";
15
+ import * as i6 from "@angular/common";
16
+ import * as i7 from "@angular/flex-layout/flex";
17
+ import * as i8 from "@angular/material/button";
18
+ import * as i9 from "@angular/material/datepicker";
19
+ import * as i10 from "@angular/material/form-field";
20
+ import * as i11 from "@angular/material/icon";
21
+ import * as i12 from "@angular/material/input";
22
+ import * as i13 from "@angular/material/table";
23
+ import * as i14 from "ngx-infinite-scroll";
24
+ const errorMessages = {
25
+ date_from: {
26
+ required: 'Start date is required',
27
+ invalidDate: 'Invalid date'
28
+ },
29
+ date_to: {
30
+ required: 'End date is required',
31
+ invalidDate: 'Invalid date'
32
+ }
33
+ };
34
+ let ChecksheetReportComponent = class ChecksheetReportComponent {
35
+ spinnerService;
36
+ alertService;
37
+ router;
38
+ dataManager;
39
+ currentUserService;
40
+ dialog;
41
+ formValidator;
42
+ fb;
43
+ datePipe;
44
+ checksheetSubmissionList = [];
45
+ pageEvent = { page: 1, perPage: 25, lastPage: 1 };
46
+ filters;
47
+ vehicle;
48
+ displayedColumns = [
49
+ 'index',
50
+ 'date',
51
+ 'vehicle',
52
+ 'created_at',
53
+ 'reviewer.name',
54
+ 'mechanical_issues',
55
+ 'notes'
56
+ ];
57
+ filterFormGroup;
58
+ constructor(spinnerService, alertService, router, dataManager, currentUserService, dialog, formValidator, fb, datePipe) {
59
+ this.spinnerService = spinnerService;
60
+ this.alertService = alertService;
61
+ this.router = router;
62
+ this.dataManager = dataManager;
63
+ this.currentUserService = currentUserService;
64
+ this.dialog = dialog;
65
+ this.formValidator = formValidator;
66
+ this.fb = fb;
67
+ this.datePipe = datePipe;
68
+ this.filters = {};
69
+ this.filters.sort_by = 'created_at|DESC';
70
+ this.createForm();
71
+ }
72
+ get excelData() {
73
+ if (this.checksheetSubmissionList.length <= 0) {
74
+ return [];
75
+ }
76
+ return this.checksheetSubmissionList.map((item) => {
77
+ return {
78
+ Date: item?.date ? new Date(item?.date).toDateString() : '',
79
+ Vehicle: item?.vehicle?.title_field,
80
+ Driver: item?.creator?.name,
81
+ 'Time Submitted': item?.created_at
82
+ ? this.datePipe.transform(new Date(item?.created_at), 'yyyy-MM-dd HH:mm')
83
+ : '',
84
+ 'Verified By ': item?.reviewer?.name,
85
+ 'Mechanical Issues': (item?.mechanical_issues || []).reduce((a, v) => `${a}${v?.details_without_html}, `, ''),
86
+ Notes: item?.comments
87
+ };
88
+ });
89
+ }
90
+ ngOnInit() {
91
+ this.filterFormGroup.valueChanges
92
+ .pipe(debounceTime(500), untilDestroyed(this))
93
+ .subscribe((x) => {
94
+ let model = this.filterFormGroup.value;
95
+ model.date_from = model.date_from
96
+ ? this.datePipe.transform(model.date_from, 'yyyy-MM-dd')
97
+ : '';
98
+ model.date_to = model.date_to
99
+ ? this.datePipe.transform(model.date_to, 'yyyy-MM-dd')
100
+ : '';
101
+ this.filters = { ...this.filters, ...model };
102
+ this.reload();
103
+ });
104
+ this.fetchChecksheetSubmissionsDetails();
105
+ }
106
+ createForm() {
107
+ this.filterFormGroup = this.fb.group({
108
+ date_from: ['', Validators.compose([DateValidator()])],
109
+ date_to: ['', Validators.compose([DateValidator()])],
110
+ status_id: [''],
111
+ model_id: [''],
112
+ creator_id: [''],
113
+ reviewer_id: [''],
114
+ checksheet_format_id: [''],
115
+ driver_assigned_customer_id: [''],
116
+ vehicle_assigned_customer_id: ['']
117
+ });
118
+ }
119
+ get currentUserId() {
120
+ return this.currentUserService.getUser().id;
121
+ }
122
+ createChecksheetSubmission() {
123
+ const dialogRef = this.dialog.open(ChecksheetSubmissionFormComponent, {
124
+ width: '400px',
125
+ data: {
126
+ submission: {},
127
+ vehicle: this.vehicle
128
+ },
129
+ autoFocus: false
130
+ });
131
+ dialogRef.afterClosed().subscribe((result) => {
132
+ if (result) {
133
+ //Action confirmed
134
+ this.editChecksheetSubmission(result);
135
+ }
136
+ });
137
+ }
138
+ deactivateChecksheetSubmission(checksheetSubmission) {
139
+ const dialogRef = this.dialog.open(ActionPopupComponent, {
140
+ width: '400px',
141
+ data: {
142
+ title: 'Deactivate Submissions',
143
+ message: `Are you sure to proceed deactivate?`
144
+ },
145
+ autoFocus: false
146
+ });
147
+ dialogRef.afterClosed().subscribe(async (result) => {
148
+ if (result) {
149
+ //Action confirmed
150
+ try {
151
+ this.spinnerService.show();
152
+ await this.dataManager.DELETE(`api/checksheets/${checksheetSubmission.id}`);
153
+ this.checksheetSubmissionList = this.checksheetSubmissionList.filter((x) => x.id !== checksheetSubmission.id);
154
+ }
155
+ catch (error) {
156
+ this.alertService.addAlert('Unable to deactivate Checksheet, try later', 'warn');
157
+ }
158
+ finally {
159
+ this.spinnerService.hide();
160
+ }
161
+ }
162
+ });
163
+ }
164
+ editChecksheetSubmission(checksheetSubmission) {
165
+ this.router.navigate([
166
+ 'vehicles/checksheets/checksheets/view',
167
+ checksheetSubmission.id
168
+ ], { queryParams: { is_vehicle_view: true } });
169
+ }
170
+ viewChecksheetSubmission(checksheetSubmission) {
171
+ this.router.navigate([
172
+ 'vehicles/checksheets/checksheets-view',
173
+ checksheetSubmission.id
174
+ ]);
175
+ }
176
+ reviewChecksheetSubmission(checksheetSubmission) {
177
+ this.router.navigate([
178
+ 'vehicles/checksheets/checksheets/review',
179
+ checksheetSubmission.id
180
+ ]);
181
+ }
182
+ onScroll() {
183
+ if (this.pageEvent.page < this.pageEvent.lastPage) {
184
+ this.pageEvent.page += 1;
185
+ }
186
+ this.fetchChecksheetSubmissionsDetails();
187
+ }
188
+ async fetchChecksheetSubmissionsDetails() {
189
+ this.spinnerService.show();
190
+ if (this.vehicle) {
191
+ this.filters.model_id = this.vehicle.id;
192
+ }
193
+ try {
194
+ const result = await this.dataManager.GET(`api/checksheets`, {
195
+ ...this.pageEvent,
196
+ ...this.filters
197
+ });
198
+ this.checksheetSubmissionList = this.checksheetSubmissionList.concat(result.data);
199
+ this.pageEvent.page = result.current_page;
200
+ this.pageEvent.lastPage = result.last_page;
201
+ }
202
+ catch (error) {
203
+ this.alertService.addAlert('Unable to get Checksheets, try later', 'warn');
204
+ }
205
+ finally {
206
+ this.spinnerService.hide();
207
+ }
208
+ }
209
+ reload() {
210
+ this.pageEvent = { page: 1, perPage: 25, lastPage: 1 };
211
+ this.checksheetSubmissionList = [];
212
+ this.fetchChecksheetSubmissionsDetails();
213
+ }
214
+ getFieldValue(field) {
215
+ return this.filterFormGroup.get(field)?.value;
216
+ }
217
+ resetFieldValue(field, event) {
218
+ event.stopPropagation();
219
+ this.filterFormGroup.get(field)?.setValue('');
220
+ }
221
+ /** Method to evaluate form fields*/
222
+ isFieldValid(field) {
223
+ return this.formValidator.isFieldValid(field, this.filterFormGroup, true);
224
+ }
225
+ /** Method to find error in form fields*/
226
+ getErrorMessage(field) {
227
+ return this.formValidator.getErrorMessage(field, this.filterFormGroup, errorMessages);
228
+ }
229
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ChecksheetReportComponent, deps: [{ token: i1.NgxSpinnerService }, { token: i2.AlertService }, { token: i3.Router }, { token: i2.DataManager }, { token: i2.CurrentUserService }, { token: i4.MatDialog }, { token: i2.FormValidatorService }, { token: i5.UntypedFormBuilder }, { token: i6.DatePipe }], target: i0.ɵɵFactoryTarget.Component });
230
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: ChecksheetReportComponent, selector: "app-checksheet-report", inputs: { vehicle: "vehicle" }, ngImport: i0, template: "<div\n fxLayout=\"column\"\n fxLayoutAlign=\"start\"\n fxLayoutGap=\"1.5rem\"\n class=\"mat-typography m-4\"\n>\n <div fxLayout fxLayoutAlign=\"center center\">\n <h3 class=\"m-0 font-weight-bold mr-3\">\n Checksheet Report\n\n <app-export-excel-button\n class=\"ml-2\"\n elementId=\"pdfable-section\"\n name=\"checksheet-report-download\"\n [data]=\"excelData\"\n >\n </app-export-excel-button>\n </h3>\n </div>\n\n <form\n fxLayout=\"row wrap d-print-none\"\n fxLayoutGap=\"1rem\"\n [formGroup]=\"filterFormGroup\"\n >\n <mat-form-field>\n <input\n matInput\n [matDatepicker]=\"picker\"\n placeholder=\"Start Date (MM/DD/YYYY)\"\n formControlName=\"date_from\"\n autocomplete=\"off\"\n />\n <mat-datepicker-toggle matSuffix [for]=\"picker\"></mat-datepicker-toggle>\n <mat-datepicker #picker></mat-datepicker>\n <mat-error *ngIf=\"isFieldValid('date_from')\"\n >{{ getErrorMessage('date_from') }}\n </mat-error>\n <button\n mat-button\n *ngIf=\"getFieldValue('date_from')\"\n matSuffix\n mat-icon-button\n (click)=\"resetFieldValue('date_from', $event)\"\n >\n <mat-icon>close</mat-icon>\n </button>\n </mat-form-field>\n\n <mat-form-field>\n <input\n matInput\n [matDatepicker]=\"p2\"\n placeholder=\"End Date (MM/DD/YYYY)\"\n formControlName=\"date_to\"\n autocomplete=\"off\"\n />\n <mat-datepicker-toggle matSuffix [for]=\"p2\"></mat-datepicker-toggle>\n <mat-datepicker #p2></mat-datepicker>\n <mat-error *ngIf=\"isFieldValid('date_to')\"\n >{{ getErrorMessage('date_to') }}\n </mat-error>\n <button\n mat-button\n *ngIf=\"getFieldValue('date_to')\"\n matSuffix\n mat-icon-button\n (click)=\"resetFieldValue('date_to', $event)\"\n >\n <mat-icon>close</mat-icon>\n </button>\n </mat-form-field>\n\n <mat-form-field>\n <mat-label>Status</mat-label>\n <app-searchable-selector\n formControlName=\"status_id\"\n apiUrl=\"api/checksheet-submission-statuses\"\n [enableSearch]=\"false\"\n >\n </app-searchable-selector>\n <mat-icon\n matSuffix\n *ngIf=\"getFieldValue('status_id')\"\n (click)=\"resetFieldValue('status_id', $event)\"\n >\n close</mat-icon\n >\n </mat-form-field>\n\n <mat-form-field *ngIf=\"!vehicle\">\n <mat-label>Vehicle</mat-label>\n <app-searchable-selector\n formControlName=\"model_id\"\n apiUrl=\"api/vehicles\"\n [enableSearch]=\"true\"\n titleField=\"title_field\"\n [sort]=\"false\"\n >\n </app-searchable-selector>\n <mat-icon\n matSuffix\n *ngIf=\"getFieldValue('model_id')\"\n (click)=\"resetFieldValue('model_id', $event)\"\n >\n close</mat-icon\n >\n </mat-form-field>\n\n <mat-form-field>\n <mat-label>Creator</mat-label>\n <app-searchable-selector\n formControlName=\"creator_id\"\n apiUrl=\"api/users\"\n [enableSearch]=\"true\"\n titleField=\"name\"\n >\n </app-searchable-selector>\n <mat-icon\n matSuffix\n *ngIf=\"getFieldValue('creator_id')\"\n (click)=\"resetFieldValue('creator_id', $event)\"\n >\n close</mat-icon\n >\n </mat-form-field>\n\n <mat-form-field>\n <mat-label>Reviewer</mat-label>\n <app-searchable-selector\n formControlName=\"reviewer_id\"\n apiUrl=\"api/users\"\n [enableSearch]=\"true\"\n titleField=\"name\"\n >\n </app-searchable-selector>\n <mat-icon\n matSuffix\n *ngIf=\"getFieldValue('reviewer_id')\"\n (click)=\"resetFieldValue('reviewer_id', $event)\"\n >\n close</mat-icon\n >\n </mat-form-field>\n\n <mat-form-field>\n <mat-label>Checksheet Format</mat-label>\n <app-searchable-selector\n formControlName=\"checksheet_format_id\"\n apiUrl=\"api/checksheet-formats?is_published=true\"\n [enableSearch]=\"true\"\n >\n </app-searchable-selector>\n <mat-icon\n matSuffix\n *ngIf=\"getFieldValue('checksheet_format_id')\"\n (click)=\"resetFieldValue('checksheet_format_id', $event)\"\n >\n close</mat-icon\n >\n </mat-form-field>\n\n <mat-form-field>\n <mat-label>Vehicle Assigned Customer</mat-label>\n <app-searchable-selector\n formControlName=\"vehicle_assigned_customer_id\"\n apiUrl=\"api/customers\"\n [enableSearch]=\"true\"\n titleField=\"name\"\n >\n </app-searchable-selector>\n <mat-icon\n matSuffix\n *ngIf=\"getFieldValue('vehicle_assigned_customer_id')\"\n (click)=\"resetFieldValue('vehicle_assigned_customer_id', $event)\"\n >\n close</mat-icon\n >\n </mat-form-field>\n\n <!-- <mat-form-field>\n <mat-label>Driver Assigned Customer</mat-label>\n <app-searchable-selector formControlName=\"driver_assigned_customer_id\" apiUrl=\"api/customers\"\n [enableSearch]=\"true\" titleField=\"name\">\n </app-searchable-selector>\n <mat-icon matSuffix *ngIf=\"getFieldValue('driver_assigned_customer_id')\"\n (click)=\"resetFieldValue('driver_assigned_customer_id', $event)\">\n close</mat-icon>\n </mat-form-field> -->\n </form>\n\n <div\n id=\"pdfable-section\"\n class=\"scroll-container\"\n infiniteScroll\n [infiniteScrollDistance]=\"2\"\n [infiniteScrollThrottle]=\"50\"\n (scrolled)=\"onScroll()\"\n [scrollWindow]=\"false\"\n >\n <table\n mat-table\n [dataSource]=\"checksheetSubmissionList\"\n class=\"w-100\"\n multiTemplateDataRows\n >\n <!-- Index Column -->\n <ng-container matColumnDef=\"index\">\n <th mat-header-cell *matHeaderCellDef>#</th>\n <td mat-cell *matCellDef=\"let element; let i = dataIndex\">\n {{ i + 1 }}\n </td>\n </ng-container>\n\n <!-- Date Column -->\n <ng-container matColumnDef=\"date\">\n <th mat-header-cell *matHeaderCellDef>Date</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element.date | date : 'mediumDate' }}\n </td>\n </ng-container>\n\n <!-- Vehicle Column -->\n <ng-container matColumnDef=\"vehicle\">\n <th mat-header-cell *matHeaderCellDef>Vehicle</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element.vehicle?.title_field }}\n </td>\n </ng-container>\n\n <!-- Category Column -->\n <ng-container matColumnDef=\"created_at\">\n <th mat-header-cell *matHeaderCellDef>Submitted On</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element.created_at | date : 'mediumDate' }}\n {{ element.created_at | date : 'shortTime' }} <br />\n <small>by {{ element.creator?.name }}</small>\n </td>\n </ng-container>\n\n <!-- Category Column -->\n <ng-container matColumnDef=\"reviewer.name\">\n <th mat-header-cell *matHeaderCellDef>Verified By</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element.reviewer?.name }} <br />\n <small *ngIf=\"element.reviewed_at\">\n on {{ element.reviewed_at | date : 'mediumDate' }}\n {{ element.reviewed_at | date : 'shortTime' }}\n </small>\n </td>\n </ng-container>\n\n <!-- Category Column -->\n <ng-container matColumnDef=\"mechanical_issues\">\n <th mat-header-cell *matHeaderCellDef>Mechanical Issues</th>\n <td mat-cell *matCellDef=\"let element\" class=\"w-50\">\n <ul>\n <li\n *ngFor=\"let issue of element?.mechanical_issues\"\n [innerHTML]=\"issue.details_without_html\"\n ></li>\n </ul>\n </td>\n </ng-container>\n\n <!-- Category Column -->\n <ng-container matColumnDef=\"notes\">\n <th mat-header-cell *matHeaderCellDef>Notes</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element.comments }}\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 </div>\n</div>\n", styles: [""], dependencies: [{ kind: "directive", type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i7.DefaultLayoutDirective, selector: " [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]", inputs: ["fxLayout", "fxLayout.xs", "fxLayout.sm", "fxLayout.md", "fxLayout.lg", "fxLayout.xl", "fxLayout.lt-sm", "fxLayout.lt-md", "fxLayout.lt-lg", "fxLayout.lt-xl", "fxLayout.gt-xs", "fxLayout.gt-sm", "fxLayout.gt-md", "fxLayout.gt-lg"] }, { kind: "directive", type: i7.DefaultLayoutGapDirective, selector: " [fxLayoutGap], [fxLayoutGap.xs], [fxLayoutGap.sm], [fxLayoutGap.md], [fxLayoutGap.lg], [fxLayoutGap.xl], [fxLayoutGap.lt-sm], [fxLayoutGap.lt-md], [fxLayoutGap.lt-lg], [fxLayoutGap.lt-xl], [fxLayoutGap.gt-xs], [fxLayoutGap.gt-sm], [fxLayoutGap.gt-md], [fxLayoutGap.gt-lg]", inputs: ["fxLayoutGap", "fxLayoutGap.xs", "fxLayoutGap.sm", "fxLayoutGap.md", "fxLayoutGap.lg", "fxLayoutGap.xl", "fxLayoutGap.lt-sm", "fxLayoutGap.lt-md", "fxLayoutGap.lt-lg", "fxLayoutGap.lt-xl", "fxLayoutGap.gt-xs", "fxLayoutGap.gt-sm", "fxLayoutGap.gt-md", "fxLayoutGap.gt-lg"] }, { kind: "directive", type: i7.DefaultLayoutAlignDirective, selector: " [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]", inputs: ["fxLayoutAlign", "fxLayoutAlign.xs", "fxLayoutAlign.sm", "fxLayoutAlign.md", "fxLayoutAlign.lg", "fxLayoutAlign.xl", "fxLayoutAlign.lt-sm", "fxLayoutAlign.lt-md", "fxLayoutAlign.lt-lg", "fxLayoutAlign.lt-xl", "fxLayoutAlign.gt-xs", "fxLayoutAlign.gt-sm", "fxLayoutAlign.gt-md", "fxLayoutAlign.gt-lg"] }, { kind: "component", type: i8.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i8.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i9.MatDatepicker, selector: "mat-datepicker", exportAs: ["matDatepicker"] }, { kind: "directive", type: i9.MatDatepickerInput, selector: "input[matDatepicker]", inputs: ["matDatepicker", "min", "max", "matDatepickerFilter"], exportAs: ["matDatepickerInput"] }, { kind: "component", type: i9.MatDatepickerToggle, selector: "mat-datepicker-toggle", inputs: ["for", "tabIndex", "aria-label", "disabled", "disableRipple"], exportAs: ["matDatepickerToggle"] }, { kind: "component", type: i10.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i10.MatLabel, selector: "mat-label" }, { kind: "directive", type: i10.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i10.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: i11.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i12.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: "component", type: i13.MatTable, selector: "mat-table, table[mat-table]", exportAs: ["matTable"] }, { kind: "directive", type: i13.MatHeaderCellDef, selector: "[matHeaderCellDef]" }, { kind: "directive", type: i13.MatHeaderRowDef, selector: "[matHeaderRowDef]", inputs: ["matHeaderRowDef", "matHeaderRowDefSticky"] }, { kind: "directive", type: i13.MatColumnDef, selector: "[matColumnDef]", inputs: ["matColumnDef"] }, { kind: "directive", type: i13.MatCellDef, selector: "[matCellDef]" }, { kind: "directive", type: i13.MatRowDef, selector: "[matRowDef]", inputs: ["matRowDefColumns", "matRowDefWhen"] }, { kind: "directive", type: i13.MatHeaderCell, selector: "mat-header-cell, th[mat-header-cell]" }, { kind: "directive", type: i13.MatCell, selector: "mat-cell, td[mat-cell]" }, { kind: "component", type: i13.MatHeaderRow, selector: "mat-header-row, tr[mat-header-row]", exportAs: ["matHeaderRow"] }, { kind: "component", type: i13.MatRow, selector: "mat-row, tr[mat-row]", exportAs: ["matRow"] }, { kind: "directive", type: i5.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i5.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: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i5.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i5.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { 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: 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.ExportExcelButtonComponent, selector: "app-export-excel-button", inputs: ["name", "data"] }, { kind: "pipe", type: i6.DatePipe, name: "date" }] });
231
+ };
232
+ ChecksheetReportComponent = __decorate([
233
+ UntilDestroy()
234
+ ], ChecksheetReportComponent);
235
+ export { ChecksheetReportComponent };
236
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ChecksheetReportComponent, decorators: [{
237
+ type: Component,
238
+ args: [{ selector: 'app-checksheet-report', template: "<div\n fxLayout=\"column\"\n fxLayoutAlign=\"start\"\n fxLayoutGap=\"1.5rem\"\n class=\"mat-typography m-4\"\n>\n <div fxLayout fxLayoutAlign=\"center center\">\n <h3 class=\"m-0 font-weight-bold mr-3\">\n Checksheet Report\n\n <app-export-excel-button\n class=\"ml-2\"\n elementId=\"pdfable-section\"\n name=\"checksheet-report-download\"\n [data]=\"excelData\"\n >\n </app-export-excel-button>\n </h3>\n </div>\n\n <form\n fxLayout=\"row wrap d-print-none\"\n fxLayoutGap=\"1rem\"\n [formGroup]=\"filterFormGroup\"\n >\n <mat-form-field>\n <input\n matInput\n [matDatepicker]=\"picker\"\n placeholder=\"Start Date (MM/DD/YYYY)\"\n formControlName=\"date_from\"\n autocomplete=\"off\"\n />\n <mat-datepicker-toggle matSuffix [for]=\"picker\"></mat-datepicker-toggle>\n <mat-datepicker #picker></mat-datepicker>\n <mat-error *ngIf=\"isFieldValid('date_from')\"\n >{{ getErrorMessage('date_from') }}\n </mat-error>\n <button\n mat-button\n *ngIf=\"getFieldValue('date_from')\"\n matSuffix\n mat-icon-button\n (click)=\"resetFieldValue('date_from', $event)\"\n >\n <mat-icon>close</mat-icon>\n </button>\n </mat-form-field>\n\n <mat-form-field>\n <input\n matInput\n [matDatepicker]=\"p2\"\n placeholder=\"End Date (MM/DD/YYYY)\"\n formControlName=\"date_to\"\n autocomplete=\"off\"\n />\n <mat-datepicker-toggle matSuffix [for]=\"p2\"></mat-datepicker-toggle>\n <mat-datepicker #p2></mat-datepicker>\n <mat-error *ngIf=\"isFieldValid('date_to')\"\n >{{ getErrorMessage('date_to') }}\n </mat-error>\n <button\n mat-button\n *ngIf=\"getFieldValue('date_to')\"\n matSuffix\n mat-icon-button\n (click)=\"resetFieldValue('date_to', $event)\"\n >\n <mat-icon>close</mat-icon>\n </button>\n </mat-form-field>\n\n <mat-form-field>\n <mat-label>Status</mat-label>\n <app-searchable-selector\n formControlName=\"status_id\"\n apiUrl=\"api/checksheet-submission-statuses\"\n [enableSearch]=\"false\"\n >\n </app-searchable-selector>\n <mat-icon\n matSuffix\n *ngIf=\"getFieldValue('status_id')\"\n (click)=\"resetFieldValue('status_id', $event)\"\n >\n close</mat-icon\n >\n </mat-form-field>\n\n <mat-form-field *ngIf=\"!vehicle\">\n <mat-label>Vehicle</mat-label>\n <app-searchable-selector\n formControlName=\"model_id\"\n apiUrl=\"api/vehicles\"\n [enableSearch]=\"true\"\n titleField=\"title_field\"\n [sort]=\"false\"\n >\n </app-searchable-selector>\n <mat-icon\n matSuffix\n *ngIf=\"getFieldValue('model_id')\"\n (click)=\"resetFieldValue('model_id', $event)\"\n >\n close</mat-icon\n >\n </mat-form-field>\n\n <mat-form-field>\n <mat-label>Creator</mat-label>\n <app-searchable-selector\n formControlName=\"creator_id\"\n apiUrl=\"api/users\"\n [enableSearch]=\"true\"\n titleField=\"name\"\n >\n </app-searchable-selector>\n <mat-icon\n matSuffix\n *ngIf=\"getFieldValue('creator_id')\"\n (click)=\"resetFieldValue('creator_id', $event)\"\n >\n close</mat-icon\n >\n </mat-form-field>\n\n <mat-form-field>\n <mat-label>Reviewer</mat-label>\n <app-searchable-selector\n formControlName=\"reviewer_id\"\n apiUrl=\"api/users\"\n [enableSearch]=\"true\"\n titleField=\"name\"\n >\n </app-searchable-selector>\n <mat-icon\n matSuffix\n *ngIf=\"getFieldValue('reviewer_id')\"\n (click)=\"resetFieldValue('reviewer_id', $event)\"\n >\n close</mat-icon\n >\n </mat-form-field>\n\n <mat-form-field>\n <mat-label>Checksheet Format</mat-label>\n <app-searchable-selector\n formControlName=\"checksheet_format_id\"\n apiUrl=\"api/checksheet-formats?is_published=true\"\n [enableSearch]=\"true\"\n >\n </app-searchable-selector>\n <mat-icon\n matSuffix\n *ngIf=\"getFieldValue('checksheet_format_id')\"\n (click)=\"resetFieldValue('checksheet_format_id', $event)\"\n >\n close</mat-icon\n >\n </mat-form-field>\n\n <mat-form-field>\n <mat-label>Vehicle Assigned Customer</mat-label>\n <app-searchable-selector\n formControlName=\"vehicle_assigned_customer_id\"\n apiUrl=\"api/customers\"\n [enableSearch]=\"true\"\n titleField=\"name\"\n >\n </app-searchable-selector>\n <mat-icon\n matSuffix\n *ngIf=\"getFieldValue('vehicle_assigned_customer_id')\"\n (click)=\"resetFieldValue('vehicle_assigned_customer_id', $event)\"\n >\n close</mat-icon\n >\n </mat-form-field>\n\n <!-- <mat-form-field>\n <mat-label>Driver Assigned Customer</mat-label>\n <app-searchable-selector formControlName=\"driver_assigned_customer_id\" apiUrl=\"api/customers\"\n [enableSearch]=\"true\" titleField=\"name\">\n </app-searchable-selector>\n <mat-icon matSuffix *ngIf=\"getFieldValue('driver_assigned_customer_id')\"\n (click)=\"resetFieldValue('driver_assigned_customer_id', $event)\">\n close</mat-icon>\n </mat-form-field> -->\n </form>\n\n <div\n id=\"pdfable-section\"\n class=\"scroll-container\"\n infiniteScroll\n [infiniteScrollDistance]=\"2\"\n [infiniteScrollThrottle]=\"50\"\n (scrolled)=\"onScroll()\"\n [scrollWindow]=\"false\"\n >\n <table\n mat-table\n [dataSource]=\"checksheetSubmissionList\"\n class=\"w-100\"\n multiTemplateDataRows\n >\n <!-- Index Column -->\n <ng-container matColumnDef=\"index\">\n <th mat-header-cell *matHeaderCellDef>#</th>\n <td mat-cell *matCellDef=\"let element; let i = dataIndex\">\n {{ i + 1 }}\n </td>\n </ng-container>\n\n <!-- Date Column -->\n <ng-container matColumnDef=\"date\">\n <th mat-header-cell *matHeaderCellDef>Date</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element.date | date : 'mediumDate' }}\n </td>\n </ng-container>\n\n <!-- Vehicle Column -->\n <ng-container matColumnDef=\"vehicle\">\n <th mat-header-cell *matHeaderCellDef>Vehicle</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element.vehicle?.title_field }}\n </td>\n </ng-container>\n\n <!-- Category Column -->\n <ng-container matColumnDef=\"created_at\">\n <th mat-header-cell *matHeaderCellDef>Submitted On</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element.created_at | date : 'mediumDate' }}\n {{ element.created_at | date : 'shortTime' }} <br />\n <small>by {{ element.creator?.name }}</small>\n </td>\n </ng-container>\n\n <!-- Category Column -->\n <ng-container matColumnDef=\"reviewer.name\">\n <th mat-header-cell *matHeaderCellDef>Verified By</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element.reviewer?.name }} <br />\n <small *ngIf=\"element.reviewed_at\">\n on {{ element.reviewed_at | date : 'mediumDate' }}\n {{ element.reviewed_at | date : 'shortTime' }}\n </small>\n </td>\n </ng-container>\n\n <!-- Category Column -->\n <ng-container matColumnDef=\"mechanical_issues\">\n <th mat-header-cell *matHeaderCellDef>Mechanical Issues</th>\n <td mat-cell *matCellDef=\"let element\" class=\"w-50\">\n <ul>\n <li\n *ngFor=\"let issue of element?.mechanical_issues\"\n [innerHTML]=\"issue.details_without_html\"\n ></li>\n </ul>\n </td>\n </ng-container>\n\n <!-- Category Column -->\n <ng-container matColumnDef=\"notes\">\n <th mat-header-cell *matHeaderCellDef>Notes</th>\n <td mat-cell *matCellDef=\"let element\">\n {{ element.comments }}\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 </div>\n</div>\n" }]
239
+ }], ctorParameters: () => [{ type: i1.NgxSpinnerService }, { type: i2.AlertService }, { type: i3.Router }, { type: i2.DataManager }, { type: i2.CurrentUserService }, { type: i4.MatDialog }, { type: i2.FormValidatorService }, { type: i5.UntypedFormBuilder }, { type: i6.DatePipe }], propDecorators: { vehicle: [{
240
+ type: Input
241
+ }] } });
242
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hlY2tzaGVldC1yZXBvcnQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LXRlY2hsaWZ5LWNoZWNrc2hlZXQvc3JjL2xpYi9jaGVja3NoZWV0L2NoZWNrc2hlZXQtcmVwb3J0L2NoZWNrc2hlZXQtcmVwb3J0LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25neC10ZWNobGlmeS1jaGVja3NoZWV0L3NyYy9saWIvY2hlY2tzaGVldC9jaGVja3NoZWV0LXJlcG9ydC9jaGVja3NoZWV0LXJlcG9ydC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQ0EsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQVUsTUFBTSxlQUFlLENBQUM7QUFDekQsT0FBTyxFQUdMLFVBQVUsRUFDWCxNQUFNLGdCQUFnQixDQUFDO0FBR3hCLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUNsRCxPQUFPLEVBQUUsWUFBWSxFQUFFLGNBQWMsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBRXJFLE9BQU8sRUFFTCxvQkFBb0IsRUFJckIsTUFBTSxtQkFBbUIsQ0FBQztBQUUzQixPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDOUMsT0FBTyxFQUFFLGlDQUFpQyxFQUFFLE1BQU0sb0VBQW9FLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7QUFFdkgsTUFBTSxhQUFhLEdBQVE7SUFDekIsU0FBUyxFQUFFO1FBQ1QsUUFBUSxFQUFFLHdCQUF3QjtRQUNsQyxXQUFXLEVBQUUsY0FBYztLQUM1QjtJQUNELE9BQU8sRUFBRTtRQUNQLFFBQVEsRUFBRSxzQkFBc0I7UUFDaEMsV0FBVyxFQUFFLGNBQWM7S0FDNUI7Q0FDRixDQUFDO0FBT0ssSUFBTSx5QkFBeUIsR0FBL0IsTUFBTSx5QkFBeUI7SUFtQjFCO0lBQ0E7SUFDQTtJ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QUM7UUFDdkQsSUFBSSxDQUFDLHdCQUF3QixHQUFHLEVBQUUsQ0FBQztRQUNuQyxJQUFJLENBQUMsaUNBQWlDLEVBQUUsQ0FBQztJQUMzQyxDQUFDO0lBRUQsYUFBYSxDQUFDLEtBQWE7UUFDekIsT0FBTyxJQUFJLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRSxLQUFLLENBQUM7SUFDaEQsQ0FBQztJQUVELGVBQWUsQ0FBQyxLQUFhLEVBQUUsS0FBVTtRQUN2QyxLQUFLLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDeEIsSUFBSSxDQUFDLGVBQWUsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLEVBQUUsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQ2hELENBQUM7SUFFRCxvQ0FBb0M7SUFDcEMsWUFBWSxDQUFDLEtBQWE7UUFDeEIsT0FBTyxJQUFJLENBQUMsYUFBYSxDQUFDLFlBQVksQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLGVBQWUsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUM1RSxDQUFDO0lBQ0QseUNBQXlDO0lBQ3pDLGVBQWUsQ0FBQyxLQUFhO1FBQzNCLE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQyxlQUFlLENBQ3ZDLEtBQUssRUFDTCxJQUFJLENBQUMsZUFBZSxFQUNwQixhQUFhLENBQ2QsQ0FBQztJQUNKLENBQUM7d0dBek9VLHlCQUF5Qjs0RkFBekIseUJBQXlCLDZGQ3ZDdEMsODRRQXNSQTs7QUQvT2EseUJBQXlCO0lBTnJDLFlBQVksRUFBRTtHQU1GLHlCQUF5QixDQTBPckM7OzRGQTFPWSx5QkFBeUI7a0JBTHJDLFNBQVM7K0JBQ0UsdUJBQXVCO29UQVF4QixPQUFPO3NCQUFmLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBEYXRlUGlwZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBDb21wb25lbnQsIElucHV0LCBPbkluaXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7XG4gIFVudHlwZWRGb3JtQnVpbGRlcixcbiAgVW50eXBlZEZvcm1Hcm91cCxcbiAgVmFsaWRhdG9yc1xufSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBNYXREaWFsb2cgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9kaWFsb2cnO1xuaW1wb3J0IHsgUm91dGVyIH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcbmltcG9ydCB7IERhdGVWYWxpZGF0b3IgfSBmcm9tICduZ3gtdGVjaGxpZnktY29yZSc7XG5pbXBvcnQgeyBVbnRpbERlc3Ryb3ksIHVudGlsRGVzdHJveWVkIH0gZnJvbSAnQG5nbmVhdC91bnRpbC1kZXN0cm95JztcbmltcG9ydCB7IE5neFNwaW5uZXJTZXJ2aWNlIH0gZnJvbSAnbmd4LXNwaW5uZXInO1xuaW1wb3J0IHtcbiAgQWN0aW9uUG9wdXAsXG4gIEFjdGlvblBvcHVwQ29tcG9uZW50LFxuICBBbGVydFNlcnZpY2UsXG4gIERhdGFNYW5hZ2VyLFxuICBGb3JtVmFsaWRhdG9yU2VydmljZVxufSBmcm9tICduZ3gtdGVjaGxpZnktY29yZSc7XG5pbXBvcnQgeyBDdXJyZW50VXNlclNlcnZpY2UgfSBmcm9tICduZ3gtdGVjaGxpZnktY29yZSc7XG5pbXBvcnQgeyBkZWJvdW5jZVRpbWUgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBDaGVja3NoZWV0U3VibWlzc2lvbkZvcm1Db21wb25lbnQgfSBmcm9tICcuLi9jaGVja3NoZWV0LXN1Ym1pc3Npb24tZm9ybS9jaGVja3NoZWV0LXN1Ym1pc3Npb24tZm9ybS5jb21wb25lbnQnO1xuXG5jb25zdCBlcnJvck1lc3NhZ2VzOiBhbnkgPSB7XG4gIGRhdGVfZnJvbToge1xuICAgIHJlcXVpcmVkOiAnU3RhcnQgZGF0ZSBpcyByZXF1aXJlZCcsXG4gICAgaW52YWxpZERhdGU6ICdJbnZhbGlkIGRhdGUnXG4gIH0sXG4gIGRhdGVfdG86IHtcbiAgICByZXF1aXJlZDogJ0VuZCBkYXRlIGlzIHJlcXVpcmVkJyxcbiAgICBpbnZhbGlkRGF0ZTogJ0ludmFsaWQgZGF0ZSdcbiAgfVxufTtcbkBVbnRpbERlc3Ryb3koKVxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnYXBwLWNoZWNrc2hlZXQtcmVwb3J0JyxcbiAgdGVtcGxhdGVVcmw6ICcuL2NoZWNrc2hlZXQtcmVwb3J0LmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vY2hlY2tzaGVldC1yZXBvcnQuY29tcG9uZW50LnNjc3MnXVxufSlcbmV4cG9ydCBjbGFzcyBDaGVja3NoZWV0UmVwb3J0Q29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcbiAgY2hlY2tzaGVldFN1Ym1pc3Npb25MaXN0OiBhbnlbXSA9IFtdO1xuICBwYWdlRXZlbnQ6IGFueSA9IHsgcGFnZTogMSwgcGVyUGFnZTogMjUsIGxhc3RQYWdlOiAxIH07XG4gIGZpbHRlcnM6IGFueTtcbiAgQElucHV0KCkgdmVoaWNsZTogYW55O1xuXG4gIGRpc3BsYXllZENvbHVtbnM6IGFueVtdID0gW1xuICAgICdpbmRleCcsXG4gICAgJ2RhdGUnLFxuICAgICd2ZWhpY2xlJyxcbiAgICAnY3JlYXRlZF9hdCcsXG4gICAgJ3Jldmlld2VyLm5hbWUnLFxuICAgICdtZWNoYW5pY2FsX2lzc3VlcycsXG4gICAgJ25vdGVzJ1xuICBdO1xuXG4gIGZpbHRlckZvcm1Hcm91cCE6IFVudHlwZWRGb3JtR3JvdXA7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBzcGlubmVyU2VydmljZTogTmd4U3Bpbm5lclNlcnZpY2UsXG4gICAgcHJpdmF0ZSBhbGVydFNlcnZpY2U6IEFsZXJ0U2VydmljZSxcbiAgICBwcml2YXRlIHJvdXRlcjogUm91dGVyLFxuICAgIHByaXZhdGUgZGF0YU1hbmFnZXI6IERhdGFNYW5hZ2VyLFxuICAgIHByaXZhdGUgY3VycmVudFVzZXJTZXJ2aWNlOiBDdXJyZW50VXNlclNlcnZpY2UsXG4gICAgcHJpdmF0ZSBkaWFsb2c6IE1hdERpYWxvZyxcbiAgICBwcml2YXRlIGZvcm1WYWxpZGF0b3I6IEZvcm1WYWxpZGF0b3JTZXJ2aWNlLFxuICAgIHByaXZhdGUgZmI6IFVudHlwZWRGb3JtQnVpbGRlcixcbiAgICBwcml2YXRlIGRhdGVQaXBlOiBEYXRlUGlwZVxuICApIHtcbiAgICB0aGlzLmZpbHRlcnMgPSB7fTtcbiAgICB0aGlzLmZpbHRlcnMuc29ydF9ieSA9ICdjcmVhdGVkX2F0fERFU0MnO1xuICAgIHRoaXMuY3JlYXRlRm9ybSgpO1xuICB9XG5cbiAgZ2V0IGV4Y2VsRGF0YSgpOiBhbnlbXSB7XG4gICAgaWYgKHRoaXMuY2hlY2tzaGVldFN1Ym1pc3Npb25MaXN0Lmxlbmd0aCA8PSAwKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuY2hlY2tzaGVldFN1Ym1pc3Npb25MaXN0Lm1hcCgoaXRlbSkgPT4ge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgRGF0ZTogaXRlbT8uZGF0ZSA/IG5ldyBEYXRlKGl0ZW0/LmRhdGUpLnRvRGF0ZVN0cmluZygpIDogJycsXG4gICAgICAgIFZlaGljbGU6IGl0ZW0/LnZlaGljbGU/LnRpdGxlX2ZpZWxkLFxuICAgICAgICBEcml2ZXI6IGl0ZW0/LmNyZWF0b3I/Lm5hbWUsXG4gICAgICAgICdUaW1lIFN1Ym1pdHRlZCc6IGl0ZW0/LmNyZWF0ZWRfYXRcbiAgICAgICAgICA/IHRoaXMuZGF0ZVBpcGUudHJhbnNmb3JtKFxuICAgICAgICAgICAgICBuZXcgRGF0ZShpdGVtPy5jcmVhdGVkX2F0KSxcbiAgICAgICAgICAgICAgJ3l5eXktTU0tZGQgSEg6bW0nXG4gICAgICAgICAgICApXG4gICAgICAgICAgOiAnJyxcbiAgICAgICAgJ1ZlcmlmaWVkIEJ5ICc6IGl0ZW0/LnJldmlld2VyPy5uYW1lLFxuICAgICAgICAnTWVjaGFuaWNhbCBJc3N1ZXMnOiAoKGl0ZW0/Lm1lY2hhbmljYWxfaXNzdWVzIHx8IFtdKSBhcyBbXSkucmVkdWNlKFxuICAgICAgICAgIChhOiBhbnksIHY6IGFueSkgPT4gYCR7YX0ke3Y/LmRldGFpbHNfd2l0aG91dF9odG1sfSwgYCxcbiAgICAgICAgICAnJ1xuICAgICAgICApLFxuICAgICAgICBOb3RlczogaXRlbT8uY29tbWVudHNcbiAgICAgIH07XG4gICAgfSk7XG4gIH1cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLmZpbHRlckZvcm1Hcm91cC52YWx1ZUNoYW5nZXNcbiAgICAgIC5waXBlKGRlYm91bmNlVGltZSg1MDApLCB1bnRpbERlc3Ryb3llZCh0aGlzKSlcbiAgICAgIC5zdWJzY3JpYmUoKHgpID0+IHtcbiAgICAgICAgbGV0IG1vZGVsID0gdGhpcy5maWx0ZXJGb3JtR3JvdXAudmFsdWU7XG4gICAgICAgIG1vZGVsLmRhdGVfZnJvbSA9IG1vZGVsLmRhdGVfZnJvbVxuICAgICAgICAgID8gdGhpcy5kYXRlUGlwZS50cmFuc2Zvcm0obW9kZWwuZGF0ZV9mcm9tLCAneXl5eS1NTS1kZCcpXG4gICAgICAgICAgOiAnJztcbiAgICAgICAgbW9kZWwuZGF0ZV90byA9IG1vZGVsLmRhdGVfdG9cbiAgICAgICAgICA/IHRoaXMuZGF0ZVBpcGUudHJhbnNmb3JtKG1vZGVsLmRhdGVfdG8sICd5eXl5LU1NLWRkJylcbiAgICAgICAgICA6ICcnO1xuICAgICAgICB0aGlzLmZpbHRlcnMgPSB7IC4uLnRoaXMuZmlsdGVycywgLi4ubW9kZWwgfTtcbiAgICAgICAgdGhpcy5yZWxvYWQoKTtcbiAgICAgIH0pO1xuICAgIHRoaXMuZmV0Y2hDaGVja3NoZWV0U3VibWlzc2lvbnNEZXRhaWxzKCk7XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZUZvcm0oKSB7XG4gICAgdGhpcy5maWx0ZXJGb3JtR3JvdXAgPSB0aGlzLmZiLmdyb3VwKHtcbiAgICAgIGRhdGVfZnJvbTogWycnLCBWYWxpZGF0b3JzLmNvbXBvc2UoW0RhdGVWYWxpZGF0b3IoKV0pXSxcbiAgICAgIGRhdGVfdG86IFsnJywgVmFsaWRhdG9ycy5jb21wb3NlKFtEYXRlVmFsaWRhdG9yKCldKV0sXG4gICAgICBzdGF0dXNfaWQ6IFsnJ10sXG4gICAgICBtb2RlbF9pZDogWycnXSxcbiAgICAgIGNyZWF0b3JfaWQ6IFsnJ10sXG4gICAgICByZXZpZXdlcl9pZDogWycnXSxcbiAgICAgIGNoZWNrc2hlZXRfZm9ybWF0X2lkOiBbJyddLFxuICAgICAgZHJpdmVyX2Fzc2lnbmVkX2N1c3RvbWVyX2lkOiBbJyddLFxuICAgICAgdmVoaWNsZV9hc3NpZ25lZF9jdXN0b21lcl9pZDogWycnXVxuICAgIH0pO1xuICB9XG5cbiAgZ2V0IGN1cnJlbnRVc2VySWQoKSB7XG4gICAgcmV0dXJuIHRoaXMuY3VycmVudFVzZXJTZXJ2aWNlLmdldFVzZXIoKS5pZDtcbiAgfVxuXG4gIGNyZWF0ZUNoZWNrc2hlZXRTdWJtaXNzaW9uKCkge1xuICAgIGNvbnN0IGRpYWxvZ1JlZiA9IHRoaXMuZGlhbG9nLm9wZW4oXG4gICAgICBDaGVja3NoZWV0U3VibWlzc2lvbkZvcm1Db21wb25lbnQsXG4gICAgICB7XG4gICAgICAgIHdpZHRoOiAnNDAwcHgnLFxuICAgICAgICBkYXRhOiB7XG4gICAgICAgICAgc3VibWlzc2lvbjoge30sXG4gICAgICAgICAgdmVoaWNsZTogdGhpcy52ZWhpY2xlXG4gICAgICAgIH0sXG4gICAgICAgIGF1dG9Gb2N1czogZmFsc2VcbiAgICAgIH1cbiAgICApO1xuXG4gICAgZGlhbG9nUmVmLmFmdGVyQ2xvc2VkKCkuc3Vic2NyaWJlKChyZXN1bHQpID0+IHtcbiAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgLy9BY3Rpb24gY29uZmlybWVkXG4gICAgICAgIHRoaXMuZWRpdENoZWNrc2hlZXRTdWJtaXNzaW9uKHJlc3VsdCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBkZWFjdGl2YXRlQ2hlY2tzaGVldFN1Ym1pc3Npb24oY2hlY2tzaGVldFN1Ym1pc3Npb246IGFueSkge1xuICAgIGNvbnN0IGRpYWxvZ1JlZiA9IHRoaXMuZGlhbG9nLm9wZW4oQWN0aW9uUG9wdXBDb21wb25lbnQsIHtcbiAgICAgIHdpZHRoOiAnNDAwcHgnLFxuICAgICAgZGF0YTogPEFjdGlvblBvcHVwPntcbiAgICAgICAgdGl0bGU6ICdEZWFjdGl2YXRlIFN1Ym1pc3Npb25zJyxcbiAgICAgICAgbWVzc2FnZTogYEFyZSB5b3Ugc3VyZSB0byBwcm9jZWVkIGRlYWN0aXZhdGU/YFxuICAgICAgfSxcbiAgICAgIGF1dG9Gb2N1czogZmFsc2VcbiAgICB9KTtcblxuICAgIGRpYWxvZ1JlZi5hZnRlckNsb3NlZCgpLnN1YnNjcmliZShhc3luYyAocmVzdWx0KSA9PiB7XG4gICAgICBpZiAocmVzdWx0KSB7XG4gICAgICAgIC8vQWN0aW9uIGNvbmZpcm1lZFxuICAgICAgICB0cnkge1xuICAgICAgICAgIHRoaXMuc3Bpbm5lclNlcnZpY2Uuc2hvdygpO1xuICAgICAgICAgIGF3YWl0IHRoaXMuZGF0YU1hbmFnZXIuREVMRVRFKFxuICAgICAgICAgICAgYGFwaS9jaGVja3NoZWV0cy8ke2NoZWNrc2hlZXRTdWJtaXNzaW9uLmlkfWBcbiAgICAgICAgICApO1xuXG4gICAgICAgICAgdGhpcy5jaGVja3NoZWV0U3VibWlzc2lvbkxpc3QgPSB0aGlzLmNoZWNrc2hlZXRTdWJtaXNzaW9uTGlzdC5maWx0ZXIoXG4gICAgICAgICAgICAoeCkgPT4geC5pZCAhPT0gY2hlY2tzaGVldFN1Ym1pc3Npb24uaWRcbiAgICAgICAgICApO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIHRoaXMuYWxlcnRTZXJ2aWNlLmFkZEFsZXJ0KFxuICAgICAgICAgICAgJ1VuYWJsZSB0byBkZWFjdGl2YXRlIENoZWNrc2hlZXQsIHRyeSBsYXRlcicsXG4gICAgICAgICAgICAnd2FybidcbiAgICAgICAgICApO1xuICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgIHRoaXMuc3Bpbm5lclNlcnZpY2UuaGlkZSgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBlZGl0Q2hlY2tzaGVldFN1Ym1pc3Npb24oY2hlY2tzaGVldFN1Ym1pc3Npb246IGFueSkge1xuICAgIHRoaXMucm91dGVyLm5hdmlnYXRlKFxuICAgICAgW1xuICAgICAgICAndmVoaWNsZXMvY2hlY2tzaGVldHMvY2hlY2tzaGVldHMvdmlldycsXG4gICAgICAgIGNoZWNrc2hlZXRTdWJtaXNzaW9uLmlkXG4gICAgICBdLFxuICAgICAgeyBxdWVyeVBhcmFtczogeyBpc192ZWhpY2xlX3ZpZXc6IHRydWUgfSB9XG4gICAgKTtcbiAgfVxuXG4gIHZpZXdDaGVja3NoZWV0U3VibWlzc2lvbihjaGVja3NoZWV0U3VibWlzc2lvbjogYW55KSB7XG4gICAgdGhpcy5yb3V0ZXIubmF2aWdhdGUoW1xuICAgICAgJ3ZlaGljbGVzL2NoZWNrc2hlZXRzL2NoZWNrc2hlZXRzLXZpZXcnLFxuICAgICAgY2hlY2tzaGVldFN1Ym1pc3Npb24uaWRcbiAgICBdKTtcbiAgfVxuXG4gIHJldmlld0NoZWNrc2hlZXRTdWJtaXNzaW9uKGNoZWNrc2hlZXRTdWJtaXNzaW9uOiBhbnkpIHtcbiAgICB0aGlzLnJvdXRlci5uYXZpZ2F0ZShbXG4gICAgICAndmVoaWNsZXMvY2hlY2tzaGVldHMvY2hlY2tzaGVldHMvcmV2aWV3JyxcbiAgICAgIGNoZWNrc2hlZXRTdWJtaXNzaW9uLmlkXG4gICAgXSk7XG4gIH1cblxuICBvblNjcm9sbCgpIHtcbiAgICBpZiAodGhpcy5wYWdlRXZlbnQucGFnZSA8IHRoaXMucGFnZUV2ZW50Lmxhc3RQYWdlKSB7XG4gICAgICB0aGlzLnBhZ2VFdmVudC5wYWdlICs9IDE7XG4gICAgfVxuICAgIHRoaXMuZmV0Y2hDaGVja3NoZWV0U3VibWlzc2lvbnNEZXRhaWxzKCk7XG4gIH1cblxuICBhc3luYyBmZXRjaENoZWNrc2hlZXRTdWJtaXNzaW9uc0RldGFpbHMoKSB7XG4gICAgdGhpcy5zcGlubmVyU2VydmljZS5zaG93KCk7XG4gICAgaWYgKHRoaXMudmVoaWNsZSkge1xuICAgICAgdGhpcy5maWx0ZXJzLm1vZGVsX2lkID0gdGhpcy52ZWhpY2xlLmlkO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCB0aGlzLmRhdGFNYW5hZ2VyLkdFVChgYXBpL2NoZWNrc2hlZXRzYCwge1xuICAgICAgICAuLi50aGlzLnBhZ2VFdmVudCxcbiAgICAgICAgLi4udGhpcy5maWx0ZXJzXG4gICAgICB9KTtcbiAgICAgIHRoaXMuY2hlY2tzaGVldFN1Ym1pc3Npb25MaXN0ID0gdGhpcy5jaGVja3NoZWV0U3VibWlzc2lvbkxpc3QuY29uY2F0KFxuICAgICAgICByZXN1bHQuZGF0YVxuICAgICAgKTtcbiAgICAgIHRoaXMucGFnZUV2ZW50LnBhZ2UgPSByZXN1bHQuY3VycmVudF9wYWdlO1xuICAgICAgdGhpcy5wYWdlRXZlbnQubGFzdFBhZ2UgPSByZXN1bHQubGFzdF9wYWdlO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICB0aGlzLmFsZXJ0U2VydmljZS5hZGRBbGVydChcbiAgICAgICAgJ1VuYWJsZSB0byBnZXQgQ2hlY2tzaGVldHMsIHRyeSBsYXRlcicsXG4gICAgICAgICd3YXJuJ1xuICAgICAgKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgdGhpcy5zcGlubmVyU2VydmljZS5oaWRlKCk7XG4gICAgfVxuICB9XG5cbiAgcmVsb2FkKCkge1xuICAgIHRoaXMucGFnZUV2ZW50ID0geyBwYWdlOiAxLCBwZXJQYWdlOiAyNSwgbGFzdFBhZ2U6IDEgfTtcbiAgICB0aGlzLmNoZWNrc2hlZXRTdWJtaXNzaW9uTGlzdCA9IFtdO1xuICAgIHRoaXMuZmV0Y2hDaGVja3NoZWV0U3VibWlzc2lvbnNEZXRhaWxzKCk7XG4gIH1cblxuICBnZXRGaWVsZFZhbHVlKGZpZWxkOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5maWx0ZXJGb3JtR3JvdXAuZ2V0KGZpZWxkKT8udmFsdWU7XG4gIH1cblxuICByZXNldEZpZWxkVmFsdWUoZmllbGQ6IHN0cmluZywgZXZlbnQ6IGFueSkge1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIHRoaXMuZmlsdGVyRm9ybUdyb3VwLmdldChmaWVsZCk/LnNldFZhbHVlKCcnKTtcbiAgfVxuXG4gIC8qKiBNZXRob2QgdG8gZXZhbHVhdGUgZm9ybSBmaWVsZHMqL1xuICBpc0ZpZWxkVmFsaWQoZmllbGQ6IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmZvcm1WYWxpZGF0b3IuaXNGaWVsZFZhbGlkKGZpZWxkLCB0aGlzLmZpbHRlckZvcm1Hcm91cCwgdHJ1ZSk7XG4gIH1cbiAgLyoqIE1ldGhvZCB0byBmaW5kIGVycm9yIGluIGZvcm0gZmllbGRzKi9cbiAgZ2V0RXJyb3JNZXNzYWdlKGZpZWxkOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5mb3JtVmFsaWRhdG9yLmdldEVycm9yTWVzc2FnZShcbiAgICAgIGZpZWxkLFxuICAgICAgdGhpcy5maWx0ZXJGb3JtR3JvdXAsXG4gICAgICBlcnJvck1lc3NhZ2VzXG4gICAgKTtcbiAgfVxufVxuIiwiPGRpdlxuICBmeExheW91dD1cImNvbHVtblwiXG4gIGZ4TGF5b3V0QWxpZ249XCJzdGFydFwiXG4gIGZ4TGF5b3V0R2FwPVwiMS41cmVtXCJcbiAgY2xhc3M9XCJtYXQtdHlwb2dyYXBoeSBtLTRcIlxuPlxuICA8ZGl2IGZ4TGF5b3V0IGZ4TGF5b3V0QWxpZ249XCJjZW50ZXIgY2VudGVyXCI+XG4gICAgPGgzIGNsYXNzPVwibS0wIGZvbnQtd2VpZ2h0LWJvbGQgbXItM1wiPlxuICAgICAgQ2hlY2tzaGVldCBSZXBvcnRcblxuICAgICAgPGFwcC1leHBvcnQtZXhjZWwtYnV0dG9uXG4gICAgICAgIGNsYXNzPVwibWwtMlwiXG4gICAgICAgIGVsZW1lbnRJZD1cInBkZmFibGUtc2VjdGlvblwiXG4gICAgICAgIG5hbWU9XCJjaGVja3NoZWV0LXJlcG9ydC1kb3dubG9hZFwiXG4gICAgICAgIFtkYXRhXT1cImV4Y2VsRGF0YVwiXG4gICAgICA+XG4gICAgICA8L2FwcC1leHBvcnQtZXhjZWwtYnV0dG9uPlxuICAgIDwvaDM+XG4gIDwvZGl2PlxuXG4gIDxmb3JtXG4gICAgZnhMYXlvdXQ9XCJyb3cgd3JhcCBkLXByaW50LW5vbmVcIlxuICAgIGZ4TGF5b3V0R2FwPVwiMXJlbVwiXG4gICAgW2Zvcm1Hcm91cF09XCJmaWx0ZXJGb3JtR3JvdXBcIlxuICA+XG4gICAgPG1hdC1mb3JtLWZpZWxkPlxuICAgICAgPGlucHV0XG4gICAgICAgIG1hdElucHV0XG4gICAgICAgIFttYXREYXRlcGlja2VyXT1cInBpY2tlclwiXG4gICAgICAgIHBsYWNlaG9sZGVyPVwiU3RhcnQgRGF0ZSAoTU0vREQvWVlZWSlcIlxuICAgICAgICBmb3JtQ29udHJvbE5hbWU9XCJkYXRlX2Zyb21cIlxuICAgICAgICBhdXRvY29tcGxldGU9XCJvZmZcIlxuICAgICAgLz5cbiAgICAgIDxtYXQtZGF0ZXBpY2tlci10b2dnbGUgbWF0U3VmZml4IFtmb3JdPVwicGlja2VyXCI+PC9tYXQtZGF0ZXBpY2tlci10b2dnbGU+XG4gICAgICA8bWF0LWRhdGVwaWNrZXIgI3BpY2tlcj48L21hdC1kYXRlcGlja2VyPlxuICAgICAgPG1hdC1lcnJvciAqbmdJZj1cImlzRmllbGRWYWxpZCgnZGF0ZV9mcm9tJylcIlxuICAgICAgICA+e3sgZ2V0RXJyb3JNZXNzYWdlKCdkYXRlX2Zyb20nKSB9fVxuICAgICAgPC9tYXQtZXJyb3I+XG4gICAgICA8YnV0dG9uXG4gICAgICAgIG1hdC1idXR0b25cbiAgICAgICAgKm5nSWY9XCJnZXRGaWVsZFZhbHVlKCdkYXRlX2Zyb20nKVwiXG4gICAgICAgIG1hdFN1ZmZpeFxuICAgICAgICBtYXQtaWNvbi1idXR0b25cbiAgICAgICAgKGNsaWNrKT1cInJlc2V0RmllbGRWYWx1ZSgnZGF0ZV9mcm9tJywgJGV2ZW50KVwiXG4gICAgICA+XG4gICAgICAgIDxtYXQtaWNvbj5jbG9zZTwvbWF0LWljb24+XG4gICAgICA8L2J1dHRvbj5cbiAgICA8L21hdC1mb3JtLWZpZWxkPlxuXG4gICAgPG1hdC1mb3JtLWZpZWxkPlxuICAgICAgPGlucHV0XG4gICAgICAgIG1hdElucHV0XG4gICAgICAgIFttYXREYXRlcGlja2VyXT1cInAyXCJcbiAgICAgICAgcGxhY2Vob2xkZXI9XCJFbmQgRGF0ZSAoTU0vREQvWVlZWSlcIlxuICAgICAgICBmb3JtQ29udHJvbE5hbWU9XCJkYXRlX3RvXCJcbiAgICAgICAgYXV0b2NvbXBsZXRlPVwib2ZmXCJcbiAgICAgIC8+XG4gICAgICA8bWF0LWRhdGVwaWNrZXItdG9nZ2xlIG1hdFN1ZmZpeCBbZm9yXT1cInAyXCI+PC9tYXQtZGF0ZXBpY2tlci10b2dnbGU+XG4gICAgICA8bWF0LWRhdGVwaWNrZXIgI3AyPjwvbWF0LWRhdGVwaWNrZXI+XG4gICAgICA8bWF0LWVycm9yICpuZ0lmPVwiaXNGaWVsZFZhbGlkKCdkYXRlX3RvJylcIlxuICAgICAgICA+e3sgZ2V0RXJyb3JNZXNzYWdlKCdkYXRlX3RvJykgfX1cbiAgICAgIDwvbWF0LWVycm9yPlxuICAgICAgPGJ1dHRvblxuICAgICAgICBtYXQtYnV0dG9uXG4gICAgICAgICpuZ0lmPVwiZ2V0RmllbGRWYWx1ZSgnZGF0ZV90bycpXCJcbiAgICAgICAgbWF0U3VmZml4XG4gICAgICAgIG1hdC1pY29uLWJ1dHRvblxuICAgICAgICAoY2xpY2spPVwicmVzZXRGaWVsZFZhbHVlKCdkYXRlX3RvJywgJGV2ZW50KVwiXG4gICAgICA+XG4gICAgICAgIDxtYXQtaWNvbj5jbG9zZTwvbWF0LWljb24+XG4gICAgICA8L2J1dHRvbj5cbiAgICA8L21hdC1mb3JtLWZpZWxkPlxuXG4gICAgPG1hdC1mb3JtLWZpZWxkPlxuICAgICAgPG1hdC1sYWJlbD5TdGF0dXM8L21hdC1sYWJlbD5cbiAgICAgIDxhcHAtc2VhcmNoYWJsZS1zZWxlY3RvclxuICAgICAgICBmb3JtQ29udHJvbE5hbWU9XCJzdGF0dXNfaWRcIlxuICAgICAgICBhcGlVcmw9XCJhcGkvY2hlY2tzaGVldC1zdWJtaXNzaW9uLXN0YXR1c2VzXCJcbiAgICAgICAgW2VuYWJsZVNlYXJjaF09XCJmYWxzZVwiXG4gICAgICA+XG4gICAgICA8L2FwcC1zZWFyY2hhYmxlLXNlbGVjdG9yPlxuICAgICAgPG1hdC1pY29uXG4gICAgICAgIG1hdFN1ZmZpeFxuICAgICAgICAqbmdJZj1cImdldEZpZWxkVmFsdWUoJ3N0YXR1c19pZCcpXCJcbiAgICAgICAgKGNsaWNrKT1cInJlc2V0RmllbGRWYWx1ZSgnc3RhdHVzX2lkJywgJGV2ZW50KVwiXG4gICAgICA+XG4gICAgICAgIGNsb3NlPC9tYXQtaWNvblxuICAgICAgPlxuICAgIDwvbWF0LWZvcm0tZmllbGQ+XG5cbiAgICA8bWF0LWZvcm0tZmllbGQgKm5nSWY9XCIhdmVoaWNsZVwiPlxuICAgICAgPG1hdC1sYWJlbD5WZWhpY2xlPC9tYXQtbGFiZWw+XG4gICAgICA8YXBwLXNlYXJjaGFibGUtc2VsZWN0b3JcbiAgICAgICAgZm9ybUNvbnRyb2xOYW1lPVwibW9kZWxfaWRcIlxuICAgICAgICBhcGlVcmw9XCJhcGkvdmVoaWNsZXNcIlxuICAgICAgICBbZW5hYmxlU2VhcmNoXT1cInRydWVcIlxuICAgICAgICB0aXRsZUZpZWxkPVwidGl0bGVfZmllbGRcIlxuICAgICAgICBbc29ydF09XCJmYWxzZVwiXG4gICAgICA+XG4gICAgICA8L2FwcC1zZWFyY2hhYmxlLXNlbGVjdG9yPlxuICAgICAgPG1hdC1pY29uXG4gICAgICAgIG1hdFN1ZmZpeFxuICAgICAgICAqbmdJZj1cImdldEZpZWxkVmFsdWUoJ21vZGVsX2lkJylcIlxuICAgICAgICAoY2xpY2spPVwicmVzZXRGaWVsZFZhbHVlKCdtb2RlbF9pZCcsICRldmVudClcIlxuICAgICAgPlxuICAgICAgICBjbG9zZTwvbWF0LWljb25cbiAgICAgID5cbiAgICA8L21hdC1mb3JtLWZpZWxkPlxuXG4gICAgPG1hdC1mb3JtLWZpZWxkPlxuICAgICAgPG1hdC1sYWJlbD5DcmVhdG9yPC9tYXQtbGFiZWw+XG4gICAgICA8YXBwLXNlYXJjaGFibGUtc2VsZWN0b3JcbiAgICAgICAgZm9ybUNvbnRyb2xOYW1lPVwiY3JlYXRvcl9pZFwiXG4gICAgICAgIGFwaVVybD1cImFwaS91c2Vyc1wiXG4gICAgICAgIFtlbmFibGVTZWFyY2hdPVwidHJ1ZVwiXG4gICAgICAgIHRpdGxlRmllbGQ9XCJuYW1lXCJcbiAgICAgID5cbiAgICAgIDwvYXBwLXNlYXJjaGFibGUtc2VsZWN0b3I+XG4gICAgICA8bWF0LWljb25cbiAgICAgICAgbWF0U3VmZml4XG4gICAgICAgICpuZ0lmPVwiZ2V0RmllbGRWYWx1ZSgnY3JlYXRvcl9pZCcpXCJcbiAgICAgICAgKGNsaWNrKT1cInJlc2V0RmllbGRWYWx1ZSgnY3JlYXRvcl9pZCcsICRldmVudClcIlxuICAgICAgPlxuICAgICAgICBjbG9zZTwvbWF0LWljb25cbiAgICAgID5cbiAgICA8L21hdC1mb3JtLWZpZWxkPlxuXG4gICAgPG1hdC1mb3JtLWZpZWxkPlxuICAgICAgPG1hdC1sYWJlbD5SZXZpZXdlcjwvbWF0LWxhYmVsPlxuICAgICAgPGFwcC1zZWFyY2hhYmxlLXNlbGVjdG9yXG4gICAgICAgIGZvcm1Db250cm9sTmFtZT1cInJldmlld2VyX2lkXCJcbiAgICAgICAgYXBpVXJsPVwiYXBpL3VzZXJzXCJcbiAgICAgICAgW2VuYWJsZVNlYXJjaF09XCJ0cnVlXCJcbiAgICAgICAgdGl0bGVGaWVsZD1cIm5hbWVcIlxuICAgICAgPlxuICAgICAgPC9hcHAtc2VhcmNoYWJsZS1zZWxlY3Rvcj5cbiAgICAgIDxtYXQtaWNvblxuICAgICAgICBtYXRTdWZmaXhcbiAgICAgICAgKm5nSWY9XCJnZXRGaWVsZFZhbHVlKCdyZXZpZXdlcl9pZCcpXCJcbiAgICAgICAgKGNsaWNrKT1cInJlc2V0RmllbGRWYWx1ZSgncmV2aWV3ZXJfaWQnLCAkZXZlbnQpXCJcbiAgICAgID5cbiAgICAgICAgY2xvc2U8L21hdC1pY29uXG4gICAgICA+XG4gICAgPC9tYXQtZm9ybS1maWVsZD5cblxuICAgIDxtYXQtZm9ybS1maWVsZD5cbiAgICAgIDxtYXQtbGFiZWw+Q2hlY2tzaGVldCBGb3JtYXQ8L21hdC1sYWJlbD5cbiAgICAgIDxhcHAtc2VhcmNoYWJsZS1zZWxlY3RvclxuICAgICAgICBmb3JtQ29udHJvbE5hbWU9XCJjaGVja3NoZWV0X2Zvcm1hdF9pZFwiXG4gICAgICAgIGFwaVVybD1cImFwaS9jaGVja3NoZWV0LWZvcm1hdHM/aXNfcHVibGlzaGVkPXRydWVcIlxuICAgICAgICBbZW5hYmxlU2VhcmNoXT1cInRydWVcIlxuICAgICAgPlxuICAgICAgPC9hcHAtc2VhcmNoYWJsZS1zZWxlY3Rvcj5cbiAgICAgIDxtYXQtaWNvblxuICAgICAgICBtYXRTdWZmaXhcbiAgICAgICAgKm5nSWY9XCJnZXRGaWVsZFZhbHVlKCdjaGVja3NoZWV0X2Zvcm1hdF9pZCcpXCJcbiAgICAgICAgKGNsaWNrKT1cInJlc2V0RmllbGRWYWx1ZSgnY2hlY2tzaGVldF9mb3JtYXRfaWQnLCAkZXZlbnQpXCJcbiAgICAgID5cbiAgICAgICAgY2xvc2U8L21hdC1pY29uXG4gICAgICA+XG4gICAgPC9tYXQtZm9ybS1maWVsZD5cblxuICAgIDxtYXQtZm9ybS1maWVsZD5cbiAgICAgIDxtYXQtbGFiZWw+VmVoaWNsZSBBc3NpZ25lZCBDdXN0b21lcjwvbWF0LWxhYmVsPlxuICAgICAgPGFwcC1zZWFyY2hhYmxlLXNlbGVjdG9yXG4gICAgICAgIGZvcm1Db250cm9sTmFtZT1cInZlaGljbGVfYXNzaWduZWRfY3VzdG9tZXJfaWRcIlxuICAgICAgICBhcGlVcmw9XCJhcGkvY3VzdG9tZXJzXCJcbiAgICAgICAgW2VuYWJsZVNlYXJjaF09XCJ0cnVlXCJcbiAgICAgICAgdGl0bGVGaWVsZD1cIm5hbWVcIlxuICAgICAgPlxuICAgICAgPC9hcHAtc2VhcmNoYWJsZS1zZWxlY3Rvcj5cbiAgICAgIDxtYXQtaWNvblxuICAgICAgICBtYXRTdWZmaXhcbiAgICAgICAgKm5nSWY9XCJnZXRGaWVsZFZhbHVlKCd2ZWhpY2xlX2Fzc2lnbmVkX2N1c3RvbWVyX2lkJylcIlxuICAgICAgICAoY2xpY2spPVwicmVzZXRGaWVsZFZhbHVlKCd2ZWhpY2xlX2Fzc2lnbmVkX2N1c3RvbWVyX2lkJywgJGV2ZW50KVwiXG4gICAgICA+XG4gICAgICAgIGNsb3NlPC9tYXQtaWNvblxuICAgICAgPlxuICAgIDwvbWF0LWZvcm0tZmllbGQ+XG5cbiAgICA8IS0tIDxtYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgIDxtYXQtbGFiZWw+RHJpdmVyIEFzc2lnbmVkIEN1c3RvbWVyPC9tYXQtbGFiZWw+XG4gICAgICAgICAgICA8YXBwLXNlYXJjaGFibGUtc2VsZWN0b3IgZm9ybUNvbnRyb2xOYW1lPVwiZHJpdmVyX2Fzc2lnbmVkX2N1c3RvbWVyX2lkXCIgYXBpVXJsPVwiYXBpL2N1c3RvbWVyc1wiXG4gICAgICAgICAgICAgICAgW2VuYWJsZVNlYXJjaF09XCJ0cnVlXCIgdGl0bGVGaWVsZD1cIm5hbWVcIj5cbiAgICAgICAgICAgIDwvYXBwLXNlYXJjaGFibGUtc2VsZWN0b3I+XG4gICAgICAgICAgICA8bWF0LWljb24gbWF0U3VmZml4ICpuZ0lmPVwiZ2V0RmllbGRWYWx1ZSgnZHJpdmVyX2Fzc2lnbmVkX2N1c3RvbWVyX2lkJylcIlxuICAgICAgICAgICAgICAgIChjbGljayk9XCJyZXNldEZpZWxkVmFsdWUoJ2RyaXZlcl9hc3NpZ25lZF9jdXN0b21lcl9pZCcsICRldmVudClcIj5cbiAgICAgICAgICAgICAgICBjbG9zZTwvbWF0LWljb24+XG4gICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+IC0tPlxuICA8L2Zvcm0+XG5cbiAgPGRpdlxuICAgIGlkPVwicGRmYWJsZS1zZWN0aW9uXCJcbiAgICBjbGFzcz1cInNjcm9sbC1jb250YWluZXJcIlxuICAgIGluZmluaXRlU2Nyb2xsXG4gICAgW2luZmluaXRlU2Nyb2xsRGlzdGFuY2VdPVwiMlwiXG4gICAgW2luZmluaXRlU2Nyb2xsVGhyb3R0bGVdPVwiNTBcIlxuICAgIChzY3JvbGxlZCk9XCJvblNjcm9sbCgpXCJcbiAgICBbc2Nyb2xsV2luZG93XT1cImZhbHNlXCJcbiAgPlxuICAgIDx0YWJsZVxuICAgICAgbWF0LXRhYmxlXG4gICAgICBbZGF0YVNvdXJjZV09XCJjaGVja3NoZWV0U3VibWlzc2lvbkxpc3RcIlxuICAgICAgY2xhc3M9XCJ3LTEwMFwiXG4gICAgICBtdWx0aVRlbXBsYXRlRGF0YVJvd3NcbiAgICA+XG4gICAgICA8IS0tIEluZGV4IENvbHVtbiAtLT5cbiAgICAgIDxuZy1jb250YWluZXIgbWF0Q29sdW1uRGVmPVwiaW5kZXhcIj5cbiAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZj4jPC90aD5cbiAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IGVsZW1lbnQ7IGxldCBpID0gZGF0YUluZGV4XCI+XG4gICAgICAgICAge3sgaSArIDEgfX1cbiAgICAgICAgPC90ZD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8IS0tIERhdGUgQ29sdW1uIC0tPlxuICAgICAgPG5nLWNvbnRhaW5lciBtYXRDb2x1bW5EZWY9XCJkYXRlXCI+XG4gICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgKm1hdEhlYWRlckNlbGxEZWY+RGF0ZTwvdGg+XG4gICAgICAgIDx0ZCBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCBlbGVtZW50XCI+XG4gICAgICAgICAge3sgZWxlbWVudC5kYXRlIHwgZGF0ZSA6ICdtZWRpdW1EYXRlJyB9fVxuICAgICAgICA8L3RkPlxuICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgIDwhLS0gVmVoaWNsZSBDb2x1bW4gLS0+XG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cInZlaGljbGVcIj5cbiAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZj5WZWhpY2xlPC90aD5cbiAgICAgICAgPHRkIG1hdC1jZWxsICptYXRDZWxsRGVmPVwibGV0IGVsZW1lbnRcIj5cbiAgICAgICAgICB7eyBlbGVtZW50LnZlaGljbGU/LnRpdGxlX2ZpZWxkIH19XG4gICAgICAgIDwvdGQ+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgPCEtLSBDYXRlZ29yeSBDb2x1bW4gLS0+XG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cImNyZWF0ZWRfYXRcIj5cbiAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZj5TdWJtaXR0ZWQgT248L3RoPlxuICAgICAgICA8dGQgbWF0LWNlbGwgKm1hdENlbGxEZWY9XCJsZXQgZWxlbWVudFwiPlxuICAgICAgICAgIHt7IGVsZW1lbnQuY3JlYXRlZF9hdCB8IGRhdGUgOiAnbWVkaXVtRGF0ZScgfX1cbiAgICAgICAgICB7eyBlbGVtZW50LmNyZWF0ZWRfYXQgfCBkYXRlIDogJ3Nob3J0VGltZScgfX0gPGJyIC8+XG4gICAgICAgICAgPHNtYWxsPmJ5IHt7IGVsZW1lbnQuY3JlYXRvcj8ubmFtZSB9fTwvc21hbGw+XG4gICAgICAgIDwvdGQ+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgPCEtLSBDYXRlZ29yeSBDb2x1bW4gLS0+XG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cInJldmlld2VyLm5hbWVcIj5cbiAgICAgICAgPHRoIG1hdC1oZWFkZXItY2VsbCAqbWF0SGVhZGVyQ2VsbERlZj5WZXJpZmllZCBCeTwvdGg+XG4gICAgICAgIDx0ZCBtYXQtY2VsbCAqbWF0Q2VsbERlZj1cImxldCBlbGVtZW50XCI+XG4gICAgICAgICAge3sgZWxlbWVudC5yZXZpZXdlcj8ubmFtZSB9fSA8YnIgLz5cbiAgICAgICAgICA8c21hbGwgKm5nSWY9XCJlbGVtZW50LnJldmlld2VkX2F0XCI+XG4gICAgICAgICAgICBvbiB7eyBlbGVtZW50LnJldmlld2VkX2F0IHwgZGF0ZSA6ICdtZWRpdW1EYXRlJyB9fVxuICAgICAgICAgICAge3sgZWxlbWVudC5yZXZpZXdlZF9hdCB8IGRhdGUgOiAnc2hvcnRUaW1lJyB9fVxuICAgICAgICAgIDwvc21hbGw+XG4gICAgICAgIDwvdGQ+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgPCEtLSBDYXRlZ29yeSBDb2x1bW4gLS0+XG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cIm1lY2hhbmljYWxfaXNzdWVzXCI+XG4gICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgKm1hdEhlYWRlckNlbGxEZWY+TWVjaGFuaWNhbCBJc3N1ZXM8L3RoPlxuICAgICAgICA8dGQgbWF0LWNlbGwgKm1hdENlbGxEZWY9XCJsZXQgZWxlbWVudFwiIGNsYXNzPVwidy01MFwiPlxuICAgICAgICAgIDx1bD5cbiAgICAgICAgICAgIDxsaVxuICAgICAgICAgICAgICAqbmdGb3I9XCJsZXQgaXNzdWUgb2YgZWxlbWVudD8ubWVjaGFuaWNhbF9pc3N1ZXNcIlxuICAgICAgICAgICAgICBbaW5uZXJIVE1MXT1cImlzc3VlLmRldGFpbHNfd2l0aG91dF9odG1sXCJcbiAgICAgICAgICAgID48L2xpPlxuICAgICAgICAgIDwvdWw+XG4gICAgICAgIDwvdGQ+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgPCEtLSBDYXRlZ29yeSBDb2x1bW4gLS0+XG4gICAgICA8bmctY29udGFpbmVyIG1hdENvbHVtbkRlZj1cIm5vdGVzXCI+XG4gICAgICAgIDx0aCBtYXQtaGVhZGVyLWNlbGwgKm1hdEhlYWRlckNlbGxEZWY+Tm90ZXM8L3RoPlxuICAgICAgICA8dGQgbWF0LWNlbGwgKm1hdENlbGxEZWY9XCJsZXQgZWxlbWVudFwiPlxuICAgICAgICAgIHt7IGVsZW1lbnQuY29tbWVudHMgfX1cbiAgICAgICAgPC90ZD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICA8dHIgbWF0LWhlYWRlci1yb3cgKm1hdEhlYWRlclJvd0RlZj1cImRpc3BsYXllZENvbHVtbnNcIj48L3RyPlxuICAgICAgPHRyIG1hdC1yb3cgKm1hdFJvd0RlZj1cImxldCByb3c7IGNvbHVtbnM6IGRpc3BsYXllZENvbHVtbnNcIj48L3RyPlxuICAgIDwvdGFibGU+XG4gIDwvZGl2PlxuPC9kaXY+XG4iXX0=