@deeksha2309/sunbird-collection-editor 8.0.7 → 8.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/deeksha2309-sunbird-collection-editor.d.ts.map +1 -0
- package/esm2022/deeksha2309-sunbird-collection-editor.mjs +5 -0
- package/esm2022/lib/collection-editor-library.module.mjs +30 -6
- package/esm2022/lib/components/answer/answer.component.mjs +6 -3
- package/esm2022/lib/components/app-loader/app-loader.component.mjs +30 -0
- package/esm2022/lib/components/asset-browser/asset-browser.component.mjs +30 -12
- package/esm2022/lib/components/assign-page-number/assign-page-number.component.mjs +1 -1
- package/esm2022/lib/components/bulk-upload/bulk-upload.component.mjs +447 -0
- package/esm2022/lib/components/ckeditor-tool/ckeditor-tool.component.mjs +30 -12
- package/esm2022/lib/components/collection-icon/collection-icon.component.mjs +3 -3
- package/esm2022/lib/components/csv-upload/csv-upload.component.mjs +2 -2
- package/esm2022/lib/components/editor/editor.component.mjs +143 -64
- package/esm2022/lib/components/fancy-tree/fancy-tree.component.mjs +91 -9
- package/esm2022/lib/components/header/header.component.mjs +27 -9
- package/esm2022/lib/components/library/library.component.mjs +4 -4
- package/esm2022/lib/components/library-list/library-list.component.mjs +4 -4
- package/esm2022/lib/components/library-player/library-player.component.mjs +4 -4
- package/esm2022/lib/components/meta-form/meta-form.component.mjs +10 -18
- package/esm2022/lib/components/options/options.component.mjs +40 -27
- package/esm2022/lib/components/progress-status/progress-status.component.mjs +1 -1
- package/esm2022/lib/components/publish-checklist/publish-checklist.component.mjs +6 -3
- package/esm2022/lib/components/question/question.component.mjs +185 -77
- package/esm2022/lib/components/question-option-sub-menu/question-option-sub-menu.component.mjs +36 -0
- package/esm2022/lib/components/quml-player/quml-player.component.mjs +2 -2
- package/esm2022/lib/components/qumlplayer-page/qumlplayer-page.component.mjs +3 -3
- package/esm2022/lib/components/relational-metadata/relational-metadata.component.mjs +80 -0
- package/esm2022/lib/components/resource-reorder/resource-reorder.component.mjs +3 -3
- package/esm2022/lib/components/slider/slider.component.mjs +46 -0
- package/esm2022/lib/components/template/template.component.mjs +3 -3
- package/esm2022/lib/components/translations/translations.component.mjs +132 -0
- package/esm2022/lib/directives/date-format/date-format.pipe.mjs +34 -0
- package/esm2022/lib/interfaces/CreationContext.mjs +2 -0
- package/esm2022/lib/interfaces/editor.mjs +1 -1
- package/esm2022/lib/interfaces/loader.mjs +2 -0
- package/esm2022/lib/pipes/interpolate.pipe.mjs +17 -0
- package/esm2022/lib/pipes/sanitize-html.pipe.mjs +6 -8
- package/esm2022/lib/services/bulk-job/bulk-job.service.mjs +67 -0
- package/esm2022/lib/services/config/category.config.json +1 -0
- package/esm2022/lib/services/config/editor.config.json +29 -2
- package/esm2022/lib/services/config/label.config.json +16 -3
- package/esm2022/lib/services/config/player.config.json +3 -0
- package/esm2022/lib/services/config/url.config.json +17 -1
- package/esm2022/lib/services/editor/editor.service.mjs +64 -26
- package/esm2022/lib/services/question/question.service.mjs +27 -35
- package/esm2022/lib/services/tree/tree.service.mjs +20 -5
- package/fesm2022/{project-sunbird-sunbird-collection-editor.mjs → deeksha2309-sunbird-collection-editor.mjs} +1779 -483
- package/fesm2022/deeksha2309-sunbird-collection-editor.mjs.map +1 -0
- package/index.d.ts +2 -2
- package/lib/collection-editor-library.module.d.ts +51 -43
- package/lib/collection-editor-library.module.d.ts.map +1 -1
- package/lib/components/answer/answer.component.d.ts +2 -1
- package/lib/components/answer/answer.component.d.ts.map +1 -1
- package/lib/components/app-loader/app-loader.component.d.ts +18 -0
- package/lib/components/app-loader/app-loader.component.d.ts.map +1 -0
- package/lib/components/asset-browser/asset-browser.component.d.ts.map +1 -1
- package/lib/components/bulk-upload/bulk-upload.component.d.ts +71 -0
- package/lib/components/bulk-upload/bulk-upload.component.d.ts.map +1 -0
- package/lib/components/ckeditor-tool/ckeditor-tool.component.d.ts +1 -1
- package/lib/components/ckeditor-tool/ckeditor-tool.component.d.ts.map +1 -1
- package/lib/components/editor/editor.component.d.ts +11 -7
- package/lib/components/editor/editor.component.d.ts.map +1 -1
- package/lib/components/fancy-tree/fancy-tree.component.d.ts +11 -3
- package/lib/components/fancy-tree/fancy-tree.component.d.ts.map +1 -1
- package/lib/components/header/header.component.d.ts +6 -2
- package/lib/components/header/header.component.d.ts.map +1 -1
- package/lib/components/library/library.component.d.ts +1 -1
- package/lib/components/library/library.component.d.ts.map +1 -1
- package/lib/components/meta-form/meta-form.component.d.ts +3 -4
- package/lib/components/meta-form/meta-form.component.d.ts.map +1 -1
- package/lib/components/options/options.component.d.ts +15 -7
- package/lib/components/options/options.component.d.ts.map +1 -1
- package/lib/components/publish-checklist/publish-checklist.component.d.ts +2 -1
- package/lib/components/publish-checklist/publish-checklist.component.d.ts.map +1 -1
- package/lib/components/question/question.component.d.ts +21 -28
- package/lib/components/question/question.component.d.ts.map +1 -1
- package/lib/components/question-option-sub-menu/question-option-sub-menu.component.d.ts +27 -0
- package/lib/components/question-option-sub-menu/question-option-sub-menu.component.d.ts.map +1 -0
- package/lib/components/relational-metadata/relational-metadata.component.d.ts +25 -0
- package/lib/components/relational-metadata/relational-metadata.component.d.ts.map +1 -0
- package/lib/components/slider/slider.component.d.ts +25 -0
- package/lib/components/slider/slider.component.d.ts.map +1 -0
- package/lib/components/translations/translations.component.d.ts +70 -0
- package/lib/components/translations/translations.component.d.ts.map +1 -0
- package/lib/directives/date-format/date-format.pipe.d.ts +20 -0
- package/lib/directives/date-format/date-format.pipe.d.ts.map +1 -0
- package/lib/interfaces/CreationContext.d.ts +11 -0
- package/lib/interfaces/CreationContext.d.ts.map +1 -0
- package/lib/interfaces/editor.d.ts +10 -5
- package/lib/interfaces/editor.d.ts.map +1 -1
- package/lib/interfaces/loader.d.ts +11 -0
- package/lib/interfaces/loader.d.ts.map +1 -0
- package/lib/pipes/interpolate.pipe.d.ts +8 -0
- package/lib/pipes/interpolate.pipe.d.ts.map +1 -0
- package/lib/pipes/sanitize-html.pipe.d.ts +4 -4
- package/lib/pipes/sanitize-html.pipe.d.ts.map +1 -1
- package/lib/services/bulk-job/bulk-job.service.d.ts +17 -0
- package/lib/services/bulk-job/bulk-job.service.d.ts.map +1 -0
- package/lib/services/editor/editor.service.d.ts +7 -4
- package/lib/services/editor/editor.service.d.ts.map +1 -1
- package/lib/services/question/question.service.d.ts +2 -2
- package/lib/services/question/question.service.d.ts.map +1 -1
- package/lib/services/tree/tree.service.d.ts +3 -1
- package/lib/services/tree/tree.service.d.ts.map +1 -1
- package/package.json +5 -5
- package/esm2022/project-sunbird-sunbird-collection-editor.mjs +0 -5
- package/fesm2022/project-sunbird-sunbird-collection-editor.mjs.map +0 -1
- package/project-sunbird-sunbird-collection-editor.d.ts.map +0 -1
|
@@ -0,0 +1,447 @@
|
|
|
1
|
+
import { Component, ViewChild, Output, EventEmitter } from '@angular/core';
|
|
2
|
+
import { FineUploader } from 'fine-uploader';
|
|
3
|
+
import * as _ from 'lodash-es';
|
|
4
|
+
import { throwError } from 'rxjs';
|
|
5
|
+
import { catchError, map, mergeMap } from 'rxjs/operators';
|
|
6
|
+
import * as i0 from "@angular/core";
|
|
7
|
+
import * as i1 from "../../services/toaster/toaster.service";
|
|
8
|
+
import * as i2 from "../../services/editor/editor.service";
|
|
9
|
+
import * as i3 from "../../services/config/config.service";
|
|
10
|
+
import * as i4 from "../../services/bulk-job/bulk-job.service";
|
|
11
|
+
import * as i5 from "../../services/tree/tree.service";
|
|
12
|
+
import * as i6 from "../../services/telemetry/telemetry.service";
|
|
13
|
+
import * as i7 from "@angular/common";
|
|
14
|
+
import * as i8 from "@project-sunbird/ng2-semantic-ui";
|
|
15
|
+
import * as i9 from "../../directives/telemetry-interact/telemetry-interact.directive";
|
|
16
|
+
import * as i10 from "../../directives/date-format/date-format.pipe";
|
|
17
|
+
export class BulkUploadComponent {
|
|
18
|
+
constructor(toasterService, editorService, configService, bulkJobService, treeService, telemetryService) {
|
|
19
|
+
this.toasterService = toasterService;
|
|
20
|
+
this.editorService = editorService;
|
|
21
|
+
this.configService = configService;
|
|
22
|
+
this.bulkJobService = bulkJobService;
|
|
23
|
+
this.treeService = treeService;
|
|
24
|
+
this.telemetryService = telemetryService;
|
|
25
|
+
this.bulkUploadEmitter = new EventEmitter();
|
|
26
|
+
this.process = {
|
|
27
|
+
process_id: '',
|
|
28
|
+
status: '',
|
|
29
|
+
type: 'bulk_upload',
|
|
30
|
+
overall_stats: {
|
|
31
|
+
total: 0,
|
|
32
|
+
upload_failed: 0,
|
|
33
|
+
upload_pending: 0,
|
|
34
|
+
upload_success: 0
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
this.oldProcessStatus = '';
|
|
38
|
+
this.stageStatus = '';
|
|
39
|
+
this.contents = [];
|
|
40
|
+
this.completionPercentage = 0;
|
|
41
|
+
this.showBulkUploadModal = false;
|
|
42
|
+
this.bulkUploadState = 0;
|
|
43
|
+
this.loading = false;
|
|
44
|
+
this.assetConfig = {
|
|
45
|
+
csv: {
|
|
46
|
+
accepted: 'csv',
|
|
47
|
+
size: 50
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
this.bulkUploadErrorMsgs = [];
|
|
51
|
+
this.bulkUploadValidationError = '';
|
|
52
|
+
this.sampleMetadataCsvUrl = '';
|
|
53
|
+
}
|
|
54
|
+
ngOnInit() {
|
|
55
|
+
this.collectionId = _.get(this.editorService.editorConfig, 'context.identifier');
|
|
56
|
+
// tslint:disable-next-line:max-line-length
|
|
57
|
+
this.sampleMetadataCsvUrl = _.get(this.editorService, 'editorConfig.config.publicStorageAccount') + _.get(this.configService.urlConFig, 'URLS.BULKJOB.SAMPLE_QUESTION_FILE');
|
|
58
|
+
this.checkBulkUploadStatus();
|
|
59
|
+
this.stageStatus = this.getContentStatus();
|
|
60
|
+
}
|
|
61
|
+
calculateCompletionPercentage() {
|
|
62
|
+
this.completionPercentage = 0;
|
|
63
|
+
console.log('process.overall_stats', this.process.overall_stats);
|
|
64
|
+
const { total, upload_pending } = this.process.overall_stats;
|
|
65
|
+
// tslint:disable-next-line:radix
|
|
66
|
+
this.completionPercentage = parseInt(_.toNumber(100 - ((upload_pending / total) * 100)));
|
|
67
|
+
console.log('completionPercentage', this.completionPercentage);
|
|
68
|
+
}
|
|
69
|
+
checkBulkUploadStatus() {
|
|
70
|
+
const reqData = {
|
|
71
|
+
filters: {
|
|
72
|
+
program_id: _.get(this.editorService.editorConfig, 'context.programId', ''),
|
|
73
|
+
collection_id: this.collectionId,
|
|
74
|
+
type: 'bulk_upload',
|
|
75
|
+
createdby: _.get(this.editorService.editorConfig, 'context.user.id')
|
|
76
|
+
},
|
|
77
|
+
limit: 1
|
|
78
|
+
};
|
|
79
|
+
this.bulkJobService.getBulkOperationStatus(reqData)
|
|
80
|
+
.subscribe((statusResponse) => {
|
|
81
|
+
const count = _.get(statusResponse, 'result.count', 0);
|
|
82
|
+
if (!count) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
this.process = _.first(_.get(statusResponse, 'result.process', []));
|
|
86
|
+
this.oldProcessStatus = this.process.status;
|
|
87
|
+
this.searchContentWithProcessId();
|
|
88
|
+
this.bulkUploadState = 5;
|
|
89
|
+
}, (error) => {
|
|
90
|
+
console.log(error);
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
searchContentWithProcessId() {
|
|
94
|
+
this.bulkJobService.searchContentWithProcessId(this.process.process_id).subscribe((searchResponse) => {
|
|
95
|
+
this.process.overall_stats.upload_failed = 0;
|
|
96
|
+
this.process.overall_stats.upload_success = 0;
|
|
97
|
+
this.process.overall_stats.upload_pending = 0;
|
|
98
|
+
if (_.get(searchResponse, 'result.count', 0) > 0) {
|
|
99
|
+
this.contents = _.compact(_.get(searchResponse.result, 'Question'));
|
|
100
|
+
let status = this.stageStatus;
|
|
101
|
+
if (status === 'draft') {
|
|
102
|
+
status = 'Draft';
|
|
103
|
+
}
|
|
104
|
+
_.each(this.contents, (content) => {
|
|
105
|
+
if (content.status === 'Retired') {
|
|
106
|
+
this.process.overall_stats.upload_failed++;
|
|
107
|
+
}
|
|
108
|
+
else if (content.status === status) {
|
|
109
|
+
this.process.overall_stats.upload_success++;
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
this.process.overall_stats.upload_pending++;
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
this.process.overall_stats.upload_pending = this.process.overall_stats.total -
|
|
116
|
+
(this.process.overall_stats.upload_success + this.process.overall_stats.upload_failed);
|
|
117
|
+
if (this.process.overall_stats.upload_pending === 0) {
|
|
118
|
+
this.process.status = 'completed';
|
|
119
|
+
}
|
|
120
|
+
this.editorService.fetchCollectionHierarchy(this.collectionId).subscribe((response) => {
|
|
121
|
+
this.storedCollectionData = response.result.questionSet;
|
|
122
|
+
this.calculateCompletionPercentage();
|
|
123
|
+
if (this.oldProcessStatus !== this.process.status) {
|
|
124
|
+
this.updateJob();
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
if (this.process.status === 'completed') {
|
|
128
|
+
this.editorService.nextBulkUploadStatus('completed');
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
this.editorService.nextBulkUploadStatus('processing');
|
|
132
|
+
}
|
|
133
|
+
this.bulkUploadEmitter.emit({ status: true, type: 'updateHierarchy' });
|
|
134
|
+
}
|
|
135
|
+
}, (error) => {
|
|
136
|
+
console.log(error);
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
downloadReport() {
|
|
140
|
+
const headers = ['Name of the Question', 'Level 1 Question Set Section', 'Keywords', 'Audience',
|
|
141
|
+
'Author', 'Copyright', 'License', 'Attributions', 'Identifier of the question '];
|
|
142
|
+
try {
|
|
143
|
+
headers.push('Status');
|
|
144
|
+
headers.push('Reason for failure');
|
|
145
|
+
const tableData = _.map(this.contents, (content, i) => {
|
|
146
|
+
const result = {};
|
|
147
|
+
result.name = _.get(content, 'name', '');
|
|
148
|
+
result.level1 = '';
|
|
149
|
+
result.keywords = _.join(_.get(content, 'keywords', []), ', ');
|
|
150
|
+
result.audience = _.join(_.get(content, 'audience', []), ', ');
|
|
151
|
+
result.creator = _.get(content, 'author', '');
|
|
152
|
+
result.copyright = _.get(content, 'copyright', '');
|
|
153
|
+
result.license = _.get(content, 'license', '');
|
|
154
|
+
result.attributions = _.join(_.get(content, 'attributions', []), ', ');
|
|
155
|
+
result.identifier = _.get(content, 'identifier', '');
|
|
156
|
+
const selctedUnitParents = this.getParents(this.storedCollectionData.children, content.identifier);
|
|
157
|
+
if (selctedUnitParents.found && !_.isEmpty(selctedUnitParents.parents)) {
|
|
158
|
+
result.level1 = selctedUnitParents.parents;
|
|
159
|
+
}
|
|
160
|
+
let status = _.get(content, 'status', '');
|
|
161
|
+
if ((this.stageStatus === 'draft' && status === 'Draft')) {
|
|
162
|
+
status = 'Success';
|
|
163
|
+
}
|
|
164
|
+
else if (status === 'Retired') {
|
|
165
|
+
status = 'Failure';
|
|
166
|
+
}
|
|
167
|
+
result.status = status;
|
|
168
|
+
result.failedReason = _.get(content, 'questionUploadStatus', '');
|
|
169
|
+
return result;
|
|
170
|
+
});
|
|
171
|
+
const csvDownloadConfig = {
|
|
172
|
+
filename: `Bulk Upload ${this.questionSetMetadata.name.trim()}`,
|
|
173
|
+
tableData,
|
|
174
|
+
headers,
|
|
175
|
+
showTitle: false
|
|
176
|
+
};
|
|
177
|
+
this.editorService.generateCSV(csvDownloadConfig);
|
|
178
|
+
}
|
|
179
|
+
catch (err) {
|
|
180
|
+
console.log(err);
|
|
181
|
+
this.toasterService.error(_.get(this.configService.labelConfig, 'messages.error.001'));
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
updateJob() {
|
|
185
|
+
const reqData = {
|
|
186
|
+
process_id: this.process.process_id,
|
|
187
|
+
overall_stats: this.process.overall_stats,
|
|
188
|
+
status: this.process.status,
|
|
189
|
+
updatedby: _.get(this.editorService.editorConfig, 'context.user.id')
|
|
190
|
+
};
|
|
191
|
+
this.bulkJobService.updateBulkJob(reqData)
|
|
192
|
+
.subscribe((updateResponse) => {
|
|
193
|
+
if (this.process.status === 'completed') {
|
|
194
|
+
this.bulkUploadState = 6;
|
|
195
|
+
}
|
|
196
|
+
else if (this.process.status === 'processing') {
|
|
197
|
+
this.bulkUploadState = 5;
|
|
198
|
+
}
|
|
199
|
+
this.oldProcessStatus = this.process.status;
|
|
200
|
+
}, (error) => {
|
|
201
|
+
console.log(error);
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
initiateDocumentUploadModal() {
|
|
205
|
+
this.loading = false;
|
|
206
|
+
this.bulkUploadValidationError = '';
|
|
207
|
+
this.bulkUploadErrorMsgs = [];
|
|
208
|
+
return setTimeout(() => {
|
|
209
|
+
this.initiateUploadModal();
|
|
210
|
+
}, 0);
|
|
211
|
+
}
|
|
212
|
+
initiateUploadModal() {
|
|
213
|
+
this.uploader = new FineUploader({
|
|
214
|
+
element: document.getElementById('upload-document-div'),
|
|
215
|
+
template: 'qq-template-validation',
|
|
216
|
+
multiple: false,
|
|
217
|
+
autoUpload: false,
|
|
218
|
+
request: {
|
|
219
|
+
endpoint: '/assets/uploads'
|
|
220
|
+
},
|
|
221
|
+
validation: {
|
|
222
|
+
allowedExtensions: [this.assetConfig.csv.accepted],
|
|
223
|
+
acceptFiles: ['text/csv'],
|
|
224
|
+
itemLimit: 1,
|
|
225
|
+
sizeLimit: _.toNumber(this.assetConfig.csv.size) * 1024 * 1024 // Convert into MB
|
|
226
|
+
},
|
|
227
|
+
messages: {
|
|
228
|
+
sizeError: `{file} is too large, maximum file size is ${this.assetConfig.csv.size} MB.`,
|
|
229
|
+
typeError: `Invalid content type (supported type: ${this.assetConfig.csv.accepted})`
|
|
230
|
+
},
|
|
231
|
+
callbacks: {
|
|
232
|
+
onStatusChange: () => { },
|
|
233
|
+
onSubmit: () => {
|
|
234
|
+
this.uploadContent();
|
|
235
|
+
},
|
|
236
|
+
onError: () => {
|
|
237
|
+
this.uploader.reset();
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
this.fineUploaderUI.nativeElement.remove();
|
|
242
|
+
}
|
|
243
|
+
uploadContent() {
|
|
244
|
+
const file = this.uploader.getFile(0);
|
|
245
|
+
const filename = this.uploader.getName(0);
|
|
246
|
+
if (file == null) {
|
|
247
|
+
this.toasterService.error('File is required to upload');
|
|
248
|
+
this.uploader.reset();
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
this.bulkUploadState = 3;
|
|
252
|
+
this.startBulkUpload(file, filename);
|
|
253
|
+
}
|
|
254
|
+
startBulkUpload(file, filename) {
|
|
255
|
+
this.generatePreSignedUrl(filename).pipe(map(response => {
|
|
256
|
+
return _.get(response.result, 'pre_signed_url');
|
|
257
|
+
}), mergeMap(signedURL => {
|
|
258
|
+
return this.uploadToBlob(signedURL, file);
|
|
259
|
+
}), mergeMap(signedURL => this.createImportRequest(signedURL).pipe(map(importResponse => {
|
|
260
|
+
this.process.process_id = _.get(importResponse, 'result.processId');
|
|
261
|
+
return _.get(importResponse, 'result.count');
|
|
262
|
+
}))), mergeMap(totalQuestion => this.createJobRequest(totalQuestion))).subscribe((jobResponse) => {
|
|
263
|
+
this.process = _.get(jobResponse, 'result');
|
|
264
|
+
this.oldProcessStatus = this.process.status;
|
|
265
|
+
this.calculateCompletionPercentage();
|
|
266
|
+
this.editorService.nextBulkUploadStatus('processing');
|
|
267
|
+
this.bulkUploadEmitter.emit({ status: true, type: 'updateHierarchy' });
|
|
268
|
+
console.log('response ::', jobResponse);
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
generatePreSignedUrl(filename) {
|
|
272
|
+
const request = {
|
|
273
|
+
content: {
|
|
274
|
+
fileName: filename
|
|
275
|
+
}
|
|
276
|
+
};
|
|
277
|
+
return this.editorService.generatePreSignedUrl(request, this.collectionId, 'hierarchy').pipe(catchError(err => {
|
|
278
|
+
const errInfo = { errorMsg: _.get(this.configService.labelConfig, 'messages.error.035') };
|
|
279
|
+
this.uploader.reset();
|
|
280
|
+
this.updateBulkUploadState('decrement');
|
|
281
|
+
return throwError(this.editorService.apiErrorHandling(err, errInfo));
|
|
282
|
+
}));
|
|
283
|
+
}
|
|
284
|
+
uploadToBlob(signedURL, file) {
|
|
285
|
+
const csp = _.get(this.editorService.editorConfig, 'context.cloudStorage.provider', 'azure');
|
|
286
|
+
const uploaderLib = new SunbirdFileUploadLib.FileUploader();
|
|
287
|
+
return uploaderLib.upload({ url: signedURL, file, csp })
|
|
288
|
+
.on("error", (error) => {
|
|
289
|
+
const errInfo = { errorMsg: _.get(this.configService.labelConfig, 'messages.error.036') };
|
|
290
|
+
this.uploader.reset();
|
|
291
|
+
this.updateBulkUploadState('decrement');
|
|
292
|
+
return throwError(this.editorService.apiErrorHandling(error, errInfo));
|
|
293
|
+
}).on("completed", (completed) => {
|
|
294
|
+
return signedURL.split('?')[0];
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
createImportRequest(fileUrl) {
|
|
298
|
+
let reqBody = {
|
|
299
|
+
fileUrl,
|
|
300
|
+
questionType: 'MCQ',
|
|
301
|
+
createdBy: _.get(this.editorService.editorConfig, 'context.user.id'),
|
|
302
|
+
author: _.get(this.editorService.editorConfig, 'context.user.fullName', ''),
|
|
303
|
+
status: 'Draft',
|
|
304
|
+
questionSetId: this.collectionId
|
|
305
|
+
};
|
|
306
|
+
const headers = { 'X-Channel-ID': _.get(this.editorService.editorConfig, 'context.channel') };
|
|
307
|
+
const derivedProperties = ['additionalCategories', 'board', 'medium', 'gradeLevel', 'subject', 'audience',
|
|
308
|
+
'license', 'framework', 'topic'];
|
|
309
|
+
reqBody = _.merge({}, reqBody, _.pick(this.questionSetMetadata, derivedProperties));
|
|
310
|
+
return this.bulkJobService.createBulkImport(reqBody, headers).pipe(catchError(err => {
|
|
311
|
+
const errInfo = { errorMsg: _.get(this.configService.labelConfig, 'messages.error.001') };
|
|
312
|
+
this.uploader.reset();
|
|
313
|
+
if (_.get(err, 'error.result.messages')) {
|
|
314
|
+
this.bulkUploadState = 4;
|
|
315
|
+
this.bulkUploadErrorMsgs = _.get(err, 'error.result.messages');
|
|
316
|
+
return throwError({});
|
|
317
|
+
}
|
|
318
|
+
else {
|
|
319
|
+
this.updateBulkUploadState('decrement');
|
|
320
|
+
return throwError(this.editorService.apiErrorHandling(err, errInfo));
|
|
321
|
+
}
|
|
322
|
+
}));
|
|
323
|
+
}
|
|
324
|
+
get questionSetMetadata() {
|
|
325
|
+
const rootNode = this.treeService.getFirstChild();
|
|
326
|
+
return _.get(rootNode, 'data.metadata');
|
|
327
|
+
}
|
|
328
|
+
viewDetails($event) {
|
|
329
|
+
$event.preventDefault();
|
|
330
|
+
this.showBulkUploadModal = true;
|
|
331
|
+
if (this.process.status === 'processing') {
|
|
332
|
+
this.bulkUploadState = 5;
|
|
333
|
+
this.checkBulkUploadStatus();
|
|
334
|
+
}
|
|
335
|
+
else {
|
|
336
|
+
this.bulkUploadState = 6;
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
getContentStatus() {
|
|
340
|
+
return 'draft';
|
|
341
|
+
}
|
|
342
|
+
createJobRequest(rowsCount) {
|
|
343
|
+
this.bulkUploadState = 5;
|
|
344
|
+
const orgId = _.get(this.editorService.editorConfig, 'context.contributionOrgId');
|
|
345
|
+
const createdby = _.get(this.editorService.editorConfig, 'context.user.id');
|
|
346
|
+
const programId = _.get(this.editorService.editorConfig, 'context.programId', '');
|
|
347
|
+
const collectionId = this.collectionId;
|
|
348
|
+
this.process.overall_stats = {
|
|
349
|
+
total: rowsCount,
|
|
350
|
+
upload_pending: rowsCount,
|
|
351
|
+
upload_failed: 0,
|
|
352
|
+
upload_success: 0
|
|
353
|
+
};
|
|
354
|
+
this.process.data = {
|
|
355
|
+
program_id: programId,
|
|
356
|
+
collection_id: collectionId
|
|
357
|
+
};
|
|
358
|
+
this.process.createdon = new Date();
|
|
359
|
+
this.process.createdby = createdby;
|
|
360
|
+
this.process.program_id = programId;
|
|
361
|
+
this.process.collection_id = collectionId;
|
|
362
|
+
this.process.status = 'processing';
|
|
363
|
+
if (orgId) {
|
|
364
|
+
this.process.data.org_id = orgId;
|
|
365
|
+
this.process.org_id = orgId;
|
|
366
|
+
}
|
|
367
|
+
const request = { ...this.process };
|
|
368
|
+
return this.bulkJobService.createBulkJob(request);
|
|
369
|
+
}
|
|
370
|
+
async openBulkUploadModal() {
|
|
371
|
+
this.bulkUploadState = 0;
|
|
372
|
+
this.showBulkUploadModal = true;
|
|
373
|
+
this.updateBulkUploadState('increment');
|
|
374
|
+
}
|
|
375
|
+
closeBulkUploadModal() {
|
|
376
|
+
this.showBulkUploadModal = false;
|
|
377
|
+
this.bulkUploadState = 0;
|
|
378
|
+
if (this.uploader) {
|
|
379
|
+
this.uploader.reset();
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
updateBulkUploadState(action) {
|
|
383
|
+
if (this.bulkUploadState === 6 && action === 'increment') {
|
|
384
|
+
return this.closeBulkUploadModal();
|
|
385
|
+
}
|
|
386
|
+
if (this.bulkUploadState === 4 && action === 'decrement') {
|
|
387
|
+
this.bulkUploadState = 3;
|
|
388
|
+
}
|
|
389
|
+
this.bulkUploadState += (action === 'increment') ? 1 : -1;
|
|
390
|
+
if (this.bulkUploadState === 2) {
|
|
391
|
+
this.initiateDocumentUploadModal();
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
getParentsHelper(tree, id, parents = '') {
|
|
395
|
+
const self = this;
|
|
396
|
+
if (tree.identifier === id) {
|
|
397
|
+
return {
|
|
398
|
+
found: true,
|
|
399
|
+
parents
|
|
400
|
+
};
|
|
401
|
+
}
|
|
402
|
+
let result = {
|
|
403
|
+
found: false,
|
|
404
|
+
};
|
|
405
|
+
if (tree.children) {
|
|
406
|
+
_.forEach(tree.children, (subtree, key) => {
|
|
407
|
+
let maybeParents = parents;
|
|
408
|
+
if (tree.identifier !== undefined) {
|
|
409
|
+
maybeParents = tree.name;
|
|
410
|
+
}
|
|
411
|
+
const maybeResult = self.getParentsHelper(subtree, id, maybeParents);
|
|
412
|
+
if (maybeResult.found) {
|
|
413
|
+
result = maybeResult;
|
|
414
|
+
return false;
|
|
415
|
+
}
|
|
416
|
+
});
|
|
417
|
+
}
|
|
418
|
+
return result;
|
|
419
|
+
}
|
|
420
|
+
getParents(data, id) {
|
|
421
|
+
const tree = {
|
|
422
|
+
children: data
|
|
423
|
+
};
|
|
424
|
+
return this.getParentsHelper(tree, id);
|
|
425
|
+
}
|
|
426
|
+
downloadSampleCSVFile() {
|
|
427
|
+
const downloadConfig = {
|
|
428
|
+
blobUrl: this.sampleMetadataCsvUrl,
|
|
429
|
+
successMessage: false,
|
|
430
|
+
fileType: 'csv',
|
|
431
|
+
fileName: this.collectionId
|
|
432
|
+
};
|
|
433
|
+
window.open(downloadConfig.blobUrl, '_blank');
|
|
434
|
+
}
|
|
435
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: BulkUploadComponent, deps: [{ token: i1.ToasterService }, { token: i2.EditorService }, { token: i3.ConfigService }, { token: i4.BulkJobService }, { token: i5.TreeService }, { token: i6.EditorTelemetryService }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
436
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: BulkUploadComponent, selector: "lib-bulk-upload", outputs: { bulkUploadEmitter: "bulkUploadEmitter" }, viewQueries: [{ propertyName: "fineUploaderUI", first: true, predicate: ["fineUploaderUI"], descendants: true }], ngImport: i0, template: "<div class=\"d-flex\">\n <button type=\"button\" class=\"sb-btn sb-btn-normal sb-btn-primary text-inherit mt-2\" suiPopup\n popupText=\"Bulk upload multiple question at one time using a CSV file\" (click)=\"openBulkUploadModal()\"\n *ngIf=\"['completed', ''].includes(process?.status)\"\n libTelemetryInteract\n [telemetryInteractEdata]=\"telemetryService.getTelemetryInteractEdata('bulk_upload_question','click','launch',\n telemetryService.telemetryPageId, {key: 'identifier', value: collectionId})\">{{configService.labelConfig?.lbl?.bulkUploadQuestion}}</button>\n <div class=\"divider mx-10\" *ngIf=\"process?.status === 'completed'\"></div>\n <div class=\"d-flex flex-dc fs-0-785\">\n <div class=\"sb-color-gray-400\" *ngIf=\"process?.status === 'completed'\">{{configService.labelConfig?.lbl?.lastUploaded}} : {{ process?.updatedon | dateFormat: 'D MMMM YYYY' }}</div>\n <div *ngIf=\"process?.status === 'processing'\" class=\"relative\">\n <span class=\"sb-loader sb-success-loader\"></span>\n <span class=\"sb-color-warning fs-1\" suiPopup\n popupText=\"Bulk upload of question is in progress, once finished you can initiate another batch\">{{configService.labelConfig?.lbl?.bulkInProgress}}</span>\n </div>\n <a href=\"#\" class=\"text-decor-none\" *ngIf=\"['completed', 'processing'].includes(process?.status)\" (click)=\"viewDetails($event)\"\n libTelemetryInteract\n [telemetryInteractEdata]=\"telemetryService.getTelemetryInteractEdata('view_details','click','launch',\n telemetryService.telemetryPageId, {key: 'identifier', value: collectionId})\">{{configService.labelConfig?.lbl?.viewDetails}}</a>\n </div>\n</div>\n\n\n<sui-modal *ngIf=\"showBulkUploadModal\" [mustScroll]=\"true\" [isClosable]=\"true\" [transitionDuration]=\"0\"\n [size]=\"'normal'\" class=\"sb-modal overflow-modal sb-bk-upload\" appBodyScroll (dismissed)=\"closeBulkUploadModal()\" #modal>\n <div class=\"sb-modal-header\">\n {{configService.labelConfig?.lbl?.bulkUploadQuestion}}\n </div>\n <div class=\"sb-modal-content\">\n <div class=\"d-flex p-30 sb-bg-color-primary-0\">\n <div class=\"p-10 sb-bulk-upload\">\n <img src=\"../../assets/images/bulkuploadfile.png\" alt=\"\" *ngIf=\"bulkUploadState !== 5\">\n <div class=\"text-right my--20\">\n <i class=\"fa fa-download sb-circle-download-icon\" *ngIf=\"bulkUploadState === 1\" aria-hidden=\"true\"></i>\n <i class=\"fa fa-check sb-circle-download-icon\" *ngIf=\"bulkUploadState === 6\" aria-hidden=\"true\"></i>\n </div>\n\n <div class=\"progress-circle progress-circle--xxl mr-8 mt-20\" [attr.data-percentage]=\"completionPercentage\" *ngIf=\"bulkUploadState === 5\">\n <svg class=\"progress-circle__svg\" viewport=\"0 0 2000 2000\">\n <circle class=\"progress-circle__stroke\" r=\"50%\" cx=\"50%\" cy=\"50%\"></circle>\n <circle class=\"progress-circle__stroke\" r=\"50%\" cx=\"50%\" cy=\"50%\"></circle>\n <text x=\"40%\" y=\"50%\" font-size=\"1.5em\">{{completionPercentage}}%</text>\n </svg>\n </div>\n </div>\n\n <div class=\"pl-20 pt-20 d-block\" *ngIf=\"bulkUploadState === 1\">\n <h6 class=\"sb-color-gray-400\">{{configService.labelConfig?.lbl?.downloadSampleMetadataCsvFileAndCreate}}</h6>\n <div class=\"sb-color-gray-200 pt-20 fs-0-92\">{{configService.labelConfig?.lbl?.makeSureYourFile}} : </div>\n <ul class=\"ui ordered list sb-dock-ordered-list mt-15\">\n <li class=\"item\">{{configService.labelConfig?.lbl?.allColumnsAreAvailableShownFormat}}</li>\n <li class=\"item\">{{configService.labelConfig?.lbl?.hasAllMandatoryColumnsFilledAsMarkedInFormat}}</li>\n <li class=\"item\">{{configService.labelConfig?.lbl?.hasNoDuplicateUrlsFilepathColumn}}</li>\n </ul>\n <button (click)=\"downloadSampleCSVFile()\"\n class=\"sb-btn sb-btn-normal sb-btn-success my-20 text-decor-none\"\n libTelemetryInteract\n [telemetryInteractEdata]=\"telemetryService.getTelemetryInteractEdata('download_sample_metadata_csv','click','launch',\n telemetryService.telemetryPageId, {key: 'dialog_id', value: 'bulk_upload_question'})\"><i\n class=\"fa fa-download pr-10\" aria-hidden=\"true\"></i>{{configService.labelConfig?.lbl?.downloadSampleMetadataCsv}}</button>\n </div>\n\n <div class=\"content p-10 d-block w-70 flex-as-center text-center\" *ngIf=\"bulkUploadState === 2\">\n <div type=\"text/template\" id=\"qq-template-validation\" #fineUploaderUI>\n <div class=\"qq-uploader-selector qq-uploader custom-qq-uploader\">\n <div class=\"qq-upload-drop-area-selector qq-upload-drop-area\" qq-hide-dropzone>\n <span class=\"qq-upload-drop-area-text-selector\"></span>\n </div>\n <span class=\"qq-drop-processing-selector qq-drop-processing\">\n <span>{{configService.labelConfig?.lbl?.processingDroppedFiles}}</span>\n <span class=\"qq-drop-processing-spinner-selector qq-drop-processing-spinner\"></span>\n </span>\n <ul class=\"qq-upload-list-selector qq-upload-list custom-qq-upload-list\" aria-live=\"polite\"\n aria-relevant=\"additions removals\">\n <li>\n <div class=\"qq-progress-bar-container-selector\">\n <div role=\"progressbar\" aria-valuenow=\"0\" aria-valuemin=\"0\" aria-valuemax=\"100\"\n class=\"qq-progress-bar-selector qq-progress-bar\"></div>\n </div>\n <span class=\"qq-upload-spinner-selector qq-upload-spinner\"></span>\n <img class=\"qq-thumbnail-selector\" qq-max-size=\"100\" alt=\"\" qq-server-scale>\n <span class=\"qq-upload-file-selector qq-upload-file custom-qq-upload-file\"></span>\n <span class=\"qq-upload-size-selector qq-upload-size\"></span>\n <button type=\"button\"\n class=\"qq-btn qq-upload-retry-selector qq-upload-retry\">{{configService.labelConfig?.lbl?.retry}}</button>\n <button type=\"button\"\n class=\"qq-btn qq-upload-delete-selector qq-upload-delete\">{{configService.labelConfig?.lbl?.retry}}</button>\n <span role=\"status\" class=\"qq-upload-status-text-selector qq-upload-status-text\"></span>\n </li>\n </ul>\n <div id=\"qq-upload-actions\" class=\"upload-file-description d-flex flex-ai-center flex-dc\">\n <h5 class=\"mb-8 sb-color-gray-400\">\n {{configService.labelConfig?.lbl?.dragAndDrop}} <br />\n {{configService.labelConfig?.lbl?.or}}\n </h5>\n <div class=\"qq-upload-button-selector qq-upload-button sb-btn sb-btn-normal sb-btn-success my-20\">\n <div>{{configService.labelConfig?.lbl?.selectFile}}</div>\n </div>\n <p class=\"mt-8 sb-color-gray-200 fs-0-785\">{{configService.labelConfig?.lbl?.uploadCSVXlEntries}}</p>\n </div>\n <dialog class=\"qq-confirm-dialog-selector\">\n <div class=\"qq-dialog-message-selector\"></div>\n <div class=\"qq-dialog-buttons\">\n <button type=\"button\" class=\"qq-cancel-button-selector\">{{configService.labelConfig?.lbl?.no}}</button>\n <button type=\"button\" class=\"qq-ok-button-selector\">{{configService.labelConfig?.lbl?.yes}}</button>\n </div>\n </dialog>\n <dialog class=\"qq-prompt-dialog-selector\">\n <div class=\"qq-dialog-message-selector\"></div>\n <input type=\"text\">\n <div class=\"qq-dialog-buttons\">\n <button type=\"button\"\n class=\"qq-cancel-button-selector\">{{configService.labelConfig?.lbl?.cancel}}</button>\n <button type=\"button\" class=\"qq-ok-button-selector\">{{configService.labelConfig?.lbl?.ok}}</button>\n </div>\n </dialog>\n </div>\n </div>\n <div *ngIf=\"!loading\">\n <div id=\"upload-document-div\" class=\"upload-file-section\"></div>\n </div>\n <div *ngIf='loading' class=\"uploading-files\">\n <div class='d-flex flex-dc flex-jc-center flex-ai-center icon'>\n <img src=\"../../assets/images/Spin.gif\" class='process-icon' alt=\"\">\n </div>\n </div>\n </div>\n\n <div class=\"p-30 w-70 flex-as-center text-center\" *ngIf=\"bulkUploadState === 3\">\n <div>\n <div class=\"relative sb-loader-with-lbl\">\n <span class=\"sb-loader sb-success-loader relative\"></span>\n <span class=\"pl-10 ml-10\">\n <h6 class=\"sb-color-gray-400 pl-10 ml-10\">{{configService.labelConfig?.lbl?.validatingCSVFile}}</h6>\n </span>\n </div>\n </div>\n </div>\n\n <div class=\"pt-20 pl-20\" *ngIf=\"bulkUploadState === 4\">\n <h6 class=\"sb-color-gray-400 pl-5\">\n <i\n class=\"fa fa-exclamation-triangle pr-5 sb-color-error\" aria-hidden=\"true\"></i>{{configService.labelConfig?.lbl?.metadataFileValidationFailed}}\n </h6>\n <div class=\"sb-color-gray-200 pt-20 fs-0-92 ml-20 sb-line-height-1.2\">{{configService.labelConfig?.lbl?.metadataFollowingError}}</div>\n <ul class=\"sb-list-circle mt-15\" *ngIf=\"bulkUploadErrorMsgs.length > 0\">\n <li class=\"item\" *ngFor=\"let msg of bulkUploadErrorMsgs\">{{msg}}</li>\n </ul>\n\n </div>\n\n <div class=\"p-20\" *ngIf=\"bulkUploadState === 5\">\n <div>{{configService.labelConfig?.lbl?.uploadingYourContentFromCSV}}</div>\n <div class=\"mt-20\">\n <div class=\"ui list fs-0-785\">\n <div class=\"item sb-color-error\">{{configService.labelConfig?.lbl?.uploadFail}} : {{ process?.overall_stats?.upload_failed }}</div>\n <div class=\"item sb-color-success\">{{configService.labelConfig?.lbl?.uploadSuccessful}} : {{ process?.overall_stats?.upload_success}}</div>\n <div class=\"item sb-color-warning\">{{configService.labelConfig?.lbl?.uploadRemaining}} : {{ process?.overall_stats?.upload_pending }}</div>\n </div>\n </div>\n </div>\n\n <div class=\"p-30 pt-10\" *ngIf=\"bulkUploadState === 6\">\n <h6 class=\"\">{{configService.labelConfig?.lbl?.bulkUploadComplete}}</h6>\n <div class=\"mt-15\">\n <div class=\"ui list fs-0-785\">\n <div class=\"item sb-color-error\">{{configService.labelConfig?.lbl?.uploadFail}} : {{ process?.overall_stats?.upload_failed }}</div>\n <div class=\"item sb-color-primary\">{{configService.labelConfig?.lbl?.contentUploaded}} : {{ process?.overall_stats?.total }}</div>\n <div class=\"item sb-color-success\">{{configService.labelConfig?.lbl?.uploadSuccessful}} : {{ process?.overall_stats?.upload_success }}</div>\n </div>\n </div>\n <button type=\"button\" class=\"sb-btn sb-btn-normal sb-btn-success my-10\" (click)=\"downloadReport()\"\n libTelemetryInteract\n [telemetryInteractEdata]=\"telemetryService.getTelemetryInteractEdata('download_report','click','launch',\n telemetryService.telemetryPageId, {key: 'dialog_id', value: 'bulk_upload_question'})\">\n <i class=\"fa fa-download pr-10\" aria-hidden=\"true\"></i>{{configService.labelConfig?.lbl?.downloadReport}}\n </button>\n </div>\n </div>\n </div>\n <div class=\"sb-modal-actions\">\n <button type=\"button\" class=\"sb-btn sb-btn-normal sb-btn-primary\" (click)=\"updateBulkUploadState('increment')\"\n *ngIf=\"bulkUploadState === 1\"\n libTelemetryInteract\n [telemetryInteractEdata]=\"telemetryService.getTelemetryInteractEdata('next','click','launch',\n telemetryService.telemetryPageId, {key: 'dialog_id', value: 'bulk_upload_question'})\">{{configService.labelConfig?.lbl?.next}}</button>\n <button type=\"button\" class=\"sb-btn sb-btn-normal sb-btn-outline-primary\"\n (click)=\"updateBulkUploadState('decrement')\"\n *ngIf=\"![1,5,6].includes(bulkUploadState)\"\n libTelemetryInteract\n [telemetryInteractEdata]=\"telemetryService.getTelemetryInteractEdata('back','click','launch',\n telemetryService.telemetryPageId, {key: 'dialog_id', value: 'bulk_upload_question'})\"\n >{{configService.labelConfig?.lbl?.back}}</button>\n <button type=\"button\" class=\"sb-btn sb-btn-normal\"\n [ngClass]=\"{'sb-btn-outline-primary': bulkUploadState === 5, 'sb-btn-primary': bulkUploadState === 6}\"\n (click)=\"closeBulkUploadModal()\"\n *ngIf=\"[5,6].includes(bulkUploadState)\"\n libTelemetryInteract\n [telemetryInteractEdata]=\"telemetryService.getTelemetryInteractEdata('close','click','launch',\n telemetryService.telemetryPageId, {key: 'dialog_id', value: 'bulk_upload_question'})\">{{configService.labelConfig?.lbl?.close}}</button>\n <div class=\"d-flex flex-jc-space-between w-100\" *ngIf=\"bulkUploadState === 5\">\n <div class=\"sb-color-gray-200 fxsmall line-height-1-3 w-100\">\n {{configService.labelConfig?.lbl?.bulkUploadNoticeLine1}}\n <strong>'{{configService.labelConfig?.lbl?.close}}'</strong>\n {{configService.labelConfig?.lbl?.bulkUploadNoticeLine2}}<br />\n {{configService.labelConfig?.lbl?.bulkUploadNoticeLine3}}\n </div>\n </div>\n </div>\n</sui-modal>", styles: [".qq-uploader.qq-uploader-selector.custom-qq-uploader{background:inherit;border-color:none;max-height:inherit;min-height:inherit;overflow-y:inherit;width:inherit;height:240px;display:flex;justify-content:center;align-items:center}.sb-bk-upload h6{line-height:22px}@media screen and (min-width: 768px){.sb-bk-upload .my--20{margin:-1.25rem 0!important}}.sb-bk-upload .sb-circle-download-icon{background:var(--secondary-100);display:inline-block;width:1.8rem;height:1.8rem;line-height:1.8rem;color:var(--white);border-radius:100%;text-align:center;font-size:.8rem}.sb-loader-with-lbl .sb-loader{position:relative!important}\n"], dependencies: [{ kind: "directive", type: i7.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i7.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i8.SuiDropdownMenuItem, selector: ".item" }, { kind: "component", type: i8.SuiModal, selector: "sui-modal", inputs: ["isClosable", "closeResult", "size", "isCentered", "isFullScreen", "isBasic", "mustScroll", "isInverted", "transition", "transitionDuration"], outputs: ["approved", "denied", "dismissed"] }, { kind: "directive", type: i8.SuiPopupDirective, selector: "[suiPopup]", inputs: ["popupHeader", "popupText", "popupInverted", "popupBasic", "popupInline", "popupFlowing", "popupTransition", "popupTransitionDuration", "popupPlacement", "popupWidth", "popupSize", "popupDelay", "popupTrigger", "popupTemplate", "popupTemplateContext", "popupConfig"], exportAs: ["suiPopup"] }, { kind: "directive", type: i9.TelemetryInteractDirective, selector: "[libTelemetryInteract]", inputs: ["telemetryInteractEdata"] }, { kind: "pipe", type: i10.DateFormatPipe, name: "dateFormat" }] }); }
|
|
437
|
+
}
|
|
438
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: BulkUploadComponent, decorators: [{
|
|
439
|
+
type: Component,
|
|
440
|
+
args: [{ selector: 'lib-bulk-upload', template: "<div class=\"d-flex\">\n <button type=\"button\" class=\"sb-btn sb-btn-normal sb-btn-primary text-inherit mt-2\" suiPopup\n popupText=\"Bulk upload multiple question at one time using a CSV file\" (click)=\"openBulkUploadModal()\"\n *ngIf=\"['completed', ''].includes(process?.status)\"\n libTelemetryInteract\n [telemetryInteractEdata]=\"telemetryService.getTelemetryInteractEdata('bulk_upload_question','click','launch',\n telemetryService.telemetryPageId, {key: 'identifier', value: collectionId})\">{{configService.labelConfig?.lbl?.bulkUploadQuestion}}</button>\n <div class=\"divider mx-10\" *ngIf=\"process?.status === 'completed'\"></div>\n <div class=\"d-flex flex-dc fs-0-785\">\n <div class=\"sb-color-gray-400\" *ngIf=\"process?.status === 'completed'\">{{configService.labelConfig?.lbl?.lastUploaded}} : {{ process?.updatedon | dateFormat: 'D MMMM YYYY' }}</div>\n <div *ngIf=\"process?.status === 'processing'\" class=\"relative\">\n <span class=\"sb-loader sb-success-loader\"></span>\n <span class=\"sb-color-warning fs-1\" suiPopup\n popupText=\"Bulk upload of question is in progress, once finished you can initiate another batch\">{{configService.labelConfig?.lbl?.bulkInProgress}}</span>\n </div>\n <a href=\"#\" class=\"text-decor-none\" *ngIf=\"['completed', 'processing'].includes(process?.status)\" (click)=\"viewDetails($event)\"\n libTelemetryInteract\n [telemetryInteractEdata]=\"telemetryService.getTelemetryInteractEdata('view_details','click','launch',\n telemetryService.telemetryPageId, {key: 'identifier', value: collectionId})\">{{configService.labelConfig?.lbl?.viewDetails}}</a>\n </div>\n</div>\n\n\n<sui-modal *ngIf=\"showBulkUploadModal\" [mustScroll]=\"true\" [isClosable]=\"true\" [transitionDuration]=\"0\"\n [size]=\"'normal'\" class=\"sb-modal overflow-modal sb-bk-upload\" appBodyScroll (dismissed)=\"closeBulkUploadModal()\" #modal>\n <div class=\"sb-modal-header\">\n {{configService.labelConfig?.lbl?.bulkUploadQuestion}}\n </div>\n <div class=\"sb-modal-content\">\n <div class=\"d-flex p-30 sb-bg-color-primary-0\">\n <div class=\"p-10 sb-bulk-upload\">\n <img src=\"../../assets/images/bulkuploadfile.png\" alt=\"\" *ngIf=\"bulkUploadState !== 5\">\n <div class=\"text-right my--20\">\n <i class=\"fa fa-download sb-circle-download-icon\" *ngIf=\"bulkUploadState === 1\" aria-hidden=\"true\"></i>\n <i class=\"fa fa-check sb-circle-download-icon\" *ngIf=\"bulkUploadState === 6\" aria-hidden=\"true\"></i>\n </div>\n\n <div class=\"progress-circle progress-circle--xxl mr-8 mt-20\" [attr.data-percentage]=\"completionPercentage\" *ngIf=\"bulkUploadState === 5\">\n <svg class=\"progress-circle__svg\" viewport=\"0 0 2000 2000\">\n <circle class=\"progress-circle__stroke\" r=\"50%\" cx=\"50%\" cy=\"50%\"></circle>\n <circle class=\"progress-circle__stroke\" r=\"50%\" cx=\"50%\" cy=\"50%\"></circle>\n <text x=\"40%\" y=\"50%\" font-size=\"1.5em\">{{completionPercentage}}%</text>\n </svg>\n </div>\n </div>\n\n <div class=\"pl-20 pt-20 d-block\" *ngIf=\"bulkUploadState === 1\">\n <h6 class=\"sb-color-gray-400\">{{configService.labelConfig?.lbl?.downloadSampleMetadataCsvFileAndCreate}}</h6>\n <div class=\"sb-color-gray-200 pt-20 fs-0-92\">{{configService.labelConfig?.lbl?.makeSureYourFile}} : </div>\n <ul class=\"ui ordered list sb-dock-ordered-list mt-15\">\n <li class=\"item\">{{configService.labelConfig?.lbl?.allColumnsAreAvailableShownFormat}}</li>\n <li class=\"item\">{{configService.labelConfig?.lbl?.hasAllMandatoryColumnsFilledAsMarkedInFormat}}</li>\n <li class=\"item\">{{configService.labelConfig?.lbl?.hasNoDuplicateUrlsFilepathColumn}}</li>\n </ul>\n <button (click)=\"downloadSampleCSVFile()\"\n class=\"sb-btn sb-btn-normal sb-btn-success my-20 text-decor-none\"\n libTelemetryInteract\n [telemetryInteractEdata]=\"telemetryService.getTelemetryInteractEdata('download_sample_metadata_csv','click','launch',\n telemetryService.telemetryPageId, {key: 'dialog_id', value: 'bulk_upload_question'})\"><i\n class=\"fa fa-download pr-10\" aria-hidden=\"true\"></i>{{configService.labelConfig?.lbl?.downloadSampleMetadataCsv}}</button>\n </div>\n\n <div class=\"content p-10 d-block w-70 flex-as-center text-center\" *ngIf=\"bulkUploadState === 2\">\n <div type=\"text/template\" id=\"qq-template-validation\" #fineUploaderUI>\n <div class=\"qq-uploader-selector qq-uploader custom-qq-uploader\">\n <div class=\"qq-upload-drop-area-selector qq-upload-drop-area\" qq-hide-dropzone>\n <span class=\"qq-upload-drop-area-text-selector\"></span>\n </div>\n <span class=\"qq-drop-processing-selector qq-drop-processing\">\n <span>{{configService.labelConfig?.lbl?.processingDroppedFiles}}</span>\n <span class=\"qq-drop-processing-spinner-selector qq-drop-processing-spinner\"></span>\n </span>\n <ul class=\"qq-upload-list-selector qq-upload-list custom-qq-upload-list\" aria-live=\"polite\"\n aria-relevant=\"additions removals\">\n <li>\n <div class=\"qq-progress-bar-container-selector\">\n <div role=\"progressbar\" aria-valuenow=\"0\" aria-valuemin=\"0\" aria-valuemax=\"100\"\n class=\"qq-progress-bar-selector qq-progress-bar\"></div>\n </div>\n <span class=\"qq-upload-spinner-selector qq-upload-spinner\"></span>\n <img class=\"qq-thumbnail-selector\" qq-max-size=\"100\" alt=\"\" qq-server-scale>\n <span class=\"qq-upload-file-selector qq-upload-file custom-qq-upload-file\"></span>\n <span class=\"qq-upload-size-selector qq-upload-size\"></span>\n <button type=\"button\"\n class=\"qq-btn qq-upload-retry-selector qq-upload-retry\">{{configService.labelConfig?.lbl?.retry}}</button>\n <button type=\"button\"\n class=\"qq-btn qq-upload-delete-selector qq-upload-delete\">{{configService.labelConfig?.lbl?.retry}}</button>\n <span role=\"status\" class=\"qq-upload-status-text-selector qq-upload-status-text\"></span>\n </li>\n </ul>\n <div id=\"qq-upload-actions\" class=\"upload-file-description d-flex flex-ai-center flex-dc\">\n <h5 class=\"mb-8 sb-color-gray-400\">\n {{configService.labelConfig?.lbl?.dragAndDrop}} <br />\n {{configService.labelConfig?.lbl?.or}}\n </h5>\n <div class=\"qq-upload-button-selector qq-upload-button sb-btn sb-btn-normal sb-btn-success my-20\">\n <div>{{configService.labelConfig?.lbl?.selectFile}}</div>\n </div>\n <p class=\"mt-8 sb-color-gray-200 fs-0-785\">{{configService.labelConfig?.lbl?.uploadCSVXlEntries}}</p>\n </div>\n <dialog class=\"qq-confirm-dialog-selector\">\n <div class=\"qq-dialog-message-selector\"></div>\n <div class=\"qq-dialog-buttons\">\n <button type=\"button\" class=\"qq-cancel-button-selector\">{{configService.labelConfig?.lbl?.no}}</button>\n <button type=\"button\" class=\"qq-ok-button-selector\">{{configService.labelConfig?.lbl?.yes}}</button>\n </div>\n </dialog>\n <dialog class=\"qq-prompt-dialog-selector\">\n <div class=\"qq-dialog-message-selector\"></div>\n <input type=\"text\">\n <div class=\"qq-dialog-buttons\">\n <button type=\"button\"\n class=\"qq-cancel-button-selector\">{{configService.labelConfig?.lbl?.cancel}}</button>\n <button type=\"button\" class=\"qq-ok-button-selector\">{{configService.labelConfig?.lbl?.ok}}</button>\n </div>\n </dialog>\n </div>\n </div>\n <div *ngIf=\"!loading\">\n <div id=\"upload-document-div\" class=\"upload-file-section\"></div>\n </div>\n <div *ngIf='loading' class=\"uploading-files\">\n <div class='d-flex flex-dc flex-jc-center flex-ai-center icon'>\n <img src=\"../../assets/images/Spin.gif\" class='process-icon' alt=\"\">\n </div>\n </div>\n </div>\n\n <div class=\"p-30 w-70 flex-as-center text-center\" *ngIf=\"bulkUploadState === 3\">\n <div>\n <div class=\"relative sb-loader-with-lbl\">\n <span class=\"sb-loader sb-success-loader relative\"></span>\n <span class=\"pl-10 ml-10\">\n <h6 class=\"sb-color-gray-400 pl-10 ml-10\">{{configService.labelConfig?.lbl?.validatingCSVFile}}</h6>\n </span>\n </div>\n </div>\n </div>\n\n <div class=\"pt-20 pl-20\" *ngIf=\"bulkUploadState === 4\">\n <h6 class=\"sb-color-gray-400 pl-5\">\n <i\n class=\"fa fa-exclamation-triangle pr-5 sb-color-error\" aria-hidden=\"true\"></i>{{configService.labelConfig?.lbl?.metadataFileValidationFailed}}\n </h6>\n <div class=\"sb-color-gray-200 pt-20 fs-0-92 ml-20 sb-line-height-1.2\">{{configService.labelConfig?.lbl?.metadataFollowingError}}</div>\n <ul class=\"sb-list-circle mt-15\" *ngIf=\"bulkUploadErrorMsgs.length > 0\">\n <li class=\"item\" *ngFor=\"let msg of bulkUploadErrorMsgs\">{{msg}}</li>\n </ul>\n\n </div>\n\n <div class=\"p-20\" *ngIf=\"bulkUploadState === 5\">\n <div>{{configService.labelConfig?.lbl?.uploadingYourContentFromCSV}}</div>\n <div class=\"mt-20\">\n <div class=\"ui list fs-0-785\">\n <div class=\"item sb-color-error\">{{configService.labelConfig?.lbl?.uploadFail}} : {{ process?.overall_stats?.upload_failed }}</div>\n <div class=\"item sb-color-success\">{{configService.labelConfig?.lbl?.uploadSuccessful}} : {{ process?.overall_stats?.upload_success}}</div>\n <div class=\"item sb-color-warning\">{{configService.labelConfig?.lbl?.uploadRemaining}} : {{ process?.overall_stats?.upload_pending }}</div>\n </div>\n </div>\n </div>\n\n <div class=\"p-30 pt-10\" *ngIf=\"bulkUploadState === 6\">\n <h6 class=\"\">{{configService.labelConfig?.lbl?.bulkUploadComplete}}</h6>\n <div class=\"mt-15\">\n <div class=\"ui list fs-0-785\">\n <div class=\"item sb-color-error\">{{configService.labelConfig?.lbl?.uploadFail}} : {{ process?.overall_stats?.upload_failed }}</div>\n <div class=\"item sb-color-primary\">{{configService.labelConfig?.lbl?.contentUploaded}} : {{ process?.overall_stats?.total }}</div>\n <div class=\"item sb-color-success\">{{configService.labelConfig?.lbl?.uploadSuccessful}} : {{ process?.overall_stats?.upload_success }}</div>\n </div>\n </div>\n <button type=\"button\" class=\"sb-btn sb-btn-normal sb-btn-success my-10\" (click)=\"downloadReport()\"\n libTelemetryInteract\n [telemetryInteractEdata]=\"telemetryService.getTelemetryInteractEdata('download_report','click','launch',\n telemetryService.telemetryPageId, {key: 'dialog_id', value: 'bulk_upload_question'})\">\n <i class=\"fa fa-download pr-10\" aria-hidden=\"true\"></i>{{configService.labelConfig?.lbl?.downloadReport}}\n </button>\n </div>\n </div>\n </div>\n <div class=\"sb-modal-actions\">\n <button type=\"button\" class=\"sb-btn sb-btn-normal sb-btn-primary\" (click)=\"updateBulkUploadState('increment')\"\n *ngIf=\"bulkUploadState === 1\"\n libTelemetryInteract\n [telemetryInteractEdata]=\"telemetryService.getTelemetryInteractEdata('next','click','launch',\n telemetryService.telemetryPageId, {key: 'dialog_id', value: 'bulk_upload_question'})\">{{configService.labelConfig?.lbl?.next}}</button>\n <button type=\"button\" class=\"sb-btn sb-btn-normal sb-btn-outline-primary\"\n (click)=\"updateBulkUploadState('decrement')\"\n *ngIf=\"![1,5,6].includes(bulkUploadState)\"\n libTelemetryInteract\n [telemetryInteractEdata]=\"telemetryService.getTelemetryInteractEdata('back','click','launch',\n telemetryService.telemetryPageId, {key: 'dialog_id', value: 'bulk_upload_question'})\"\n >{{configService.labelConfig?.lbl?.back}}</button>\n <button type=\"button\" class=\"sb-btn sb-btn-normal\"\n [ngClass]=\"{'sb-btn-outline-primary': bulkUploadState === 5, 'sb-btn-primary': bulkUploadState === 6}\"\n (click)=\"closeBulkUploadModal()\"\n *ngIf=\"[5,6].includes(bulkUploadState)\"\n libTelemetryInteract\n [telemetryInteractEdata]=\"telemetryService.getTelemetryInteractEdata('close','click','launch',\n telemetryService.telemetryPageId, {key: 'dialog_id', value: 'bulk_upload_question'})\">{{configService.labelConfig?.lbl?.close}}</button>\n <div class=\"d-flex flex-jc-space-between w-100\" *ngIf=\"bulkUploadState === 5\">\n <div class=\"sb-color-gray-200 fxsmall line-height-1-3 w-100\">\n {{configService.labelConfig?.lbl?.bulkUploadNoticeLine1}}\n <strong>'{{configService.labelConfig?.lbl?.close}}'</strong>\n {{configService.labelConfig?.lbl?.bulkUploadNoticeLine2}}<br />\n {{configService.labelConfig?.lbl?.bulkUploadNoticeLine3}}\n </div>\n </div>\n </div>\n</sui-modal>", styles: [".qq-uploader.qq-uploader-selector.custom-qq-uploader{background:inherit;border-color:none;max-height:inherit;min-height:inherit;overflow-y:inherit;width:inherit;height:240px;display:flex;justify-content:center;align-items:center}.sb-bk-upload h6{line-height:22px}@media screen and (min-width: 768px){.sb-bk-upload .my--20{margin:-1.25rem 0!important}}.sb-bk-upload .sb-circle-download-icon{background:var(--secondary-100);display:inline-block;width:1.8rem;height:1.8rem;line-height:1.8rem;color:var(--white);border-radius:100%;text-align:center;font-size:.8rem}.sb-loader-with-lbl .sb-loader{position:relative!important}\n"] }]
|
|
441
|
+
}], ctorParameters: function () { return [{ type: i1.ToasterService }, { type: i2.EditorService }, { type: i3.ConfigService }, { type: i4.BulkJobService }, { type: i5.TreeService }, { type: i6.EditorTelemetryService }]; }, propDecorators: { fineUploaderUI: [{
|
|
442
|
+
type: ViewChild,
|
|
443
|
+
args: ['fineUploaderUI']
|
|
444
|
+
}], bulkUploadEmitter: [{
|
|
445
|
+
type: Output
|
|
446
|
+
}] } });
|
|
447
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVsay11cGxvYWQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvY29sbGVjdGlvbi1lZGl0b3ItbGlicmFyeS9zcmMvbGliL2NvbXBvbmVudHMvYnVsay11cGxvYWQvYnVsay11cGxvYWQuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvY29sbGVjdGlvbi1lZGl0b3ItbGlicmFyeS9zcmMvbGliL2NvbXBvbmVudHMvYnVsay11cGxvYWQvYnVsay11cGxvYWQuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBVSxTQUFTLEVBQWMsTUFBTSxFQUFFLFlBQVksRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMvRixPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzdDLE9BQU8sS0FBSyxDQUFDLE1BQU0sV0FBVyxDQUFDO0FBQy9CLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDbEMsT0FBTyxFQUFFLFVBQVUsRUFBRSxHQUFHLEVBQUUsUUFBUSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7Ozs7Ozs7Ozs7OztBQWMzRCxNQUFNLE9BQU8sbUJBQW1CO0lBa0M5QixZQUNVLGNBQThCLEVBQVUsYUFBNEIsRUFBUyxhQUE0QixFQUN6RyxjQUE4QixFQUFVLFdBQXdCLEVBQVMsZ0JBQXdDO1FBRGpILG1CQUFjLEdBQWQsY0FBYyxDQUFnQjtRQUFVLGtCQUFhLEdBQWIsYUFBYSxDQUFlO1FBQVMsa0JBQWEsR0FBYixhQUFhLENBQWU7UUFDekcsbUJBQWMsR0FBZCxjQUFjLENBQWdCO1FBQVUsZ0JBQVcsR0FBWCxXQUFXLENBQWE7UUFBUyxxQkFBZ0IsR0FBaEIsZ0JBQWdCLENBQXdCO1FBakNqSCxzQkFBaUIsR0FBRyxJQUFJLFlBQVksRUFBTyxDQUFDO1FBRS9DLFlBQU8sR0FB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LEVBQUUsSUFBSSxDQUFDLFlBQVk7U0FDNUIsQ0FBQztRQUNGLE1BQU0sQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLE9BQU8sRUFBRSxRQUFRLENBQUMsQ0FBQztJQUNoRCxDQUFDOytHQS9iVSxtQkFBbUI7bUdBQW5CLG1CQUFtQiw4TkNsQmhDLDYxYUFpTlk7OzRGRC9MQyxtQkFBbUI7a0JBTC9CLFNBQVM7K0JBQ0UsaUJBQWlCO3lQQU1FLGNBQWM7c0JBQTFDLFNBQVM7dUJBQUMsZ0JBQWdCO2dCQUNqQixpQkFBaUI7c0JBQTFCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIE9uSW5pdCwgVmlld0NoaWxkLCBFbGVtZW50UmVmLCBPdXRwdXQsIEV2ZW50RW1pdHRlciB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRmluZVVwbG9hZGVyIH0gZnJvbSAnZmluZS11cGxvYWRlcic7XG5pbXBvcnQgKiBhcyBfIGZyb20gJ2xvZGFzaC1lcyc7XG5pbXBvcnQgeyB0aHJvd0Vycm9yIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBjYXRjaEVycm9yLCBtYXAsIG1lcmdlTWFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVG9hc3RlclNlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy90b2FzdGVyL3RvYXN0ZXIuc2VydmljZSc7XG5pbXBvcnQgeyBFZGl0b3JTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvZWRpdG9yL2VkaXRvci5zZXJ2aWNlJztcbmltcG9ydCB7IENvbmZpZ1NlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9jb25maWcvY29uZmlnLnNlcnZpY2UnO1xuaW1wb3J0IHsgQnVsa0pvYlNlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9idWxrLWpvYi9idWxrLWpvYi5zZXJ2aWNlJztcbmltcG9ydCB7IFRyZWVTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvdHJlZS90cmVlLnNlcnZpY2UnO1xuaW1wb3J0IHsgRWRpdG9yVGVsZW1ldHJ5U2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL3RlbGVtZXRyeS90ZWxlbWV0cnkuc2VydmljZSc7XG5kZWNsYXJlIGNvbnN0IFN1bmJpcmRGaWxlVXBsb2FkTGliOiBhbnk7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2xpYi1idWxrLXVwbG9hZCcsXG4gIHRlbXBsYXRlVXJsOiAnLi9idWxrLXVwbG9hZC5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL2J1bGstdXBsb2FkLmNvbXBvbmVudC5zY3NzJ11cbn0pXG5leHBvcnQgY2xhc3MgQnVsa1VwbG9hZENvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG4gIHB1YmxpYyBjb2xsZWN0aW9uSWQ6IHN0cmluZztcbiAgQFZpZXdDaGlsZCgnZmluZVVwbG9hZGVyVUknKSBmaW5lVXBsb2FkZXJVSTogRWxlbWVudFJlZjtcbiAgQE91dHB1dCgpIGJ1bGtVcGxvYWRFbWl0dGVyID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG4gIHB1YmxpYyBzdG9yZWRDb2xsZWN0aW9uRGF0YTtcbiAgcHVibGljIHByb2Nlc3M6IGFueSA9IHtcbiAgICBwcm9jZXNzX2lkOiAnJyxcbiAgICBzdGF0dXM6ICcnLFxuICAgIHR5cGU6ICdidWxrX3VwbG9hZCcsXG4gICAgb3ZlcmFsbF9zdGF0czoge1xuICAgICAgdG90YWw6IDAsXG4gICAgICB1cGxvYWRfZmFpbGVkOiAwLFxuICAgICAgdXBsb2FkX3BlbmRpbmc6IDAsXG4gICAgICB1cGxvYWRfc3VjY2VzczogMFxuICAgIH1cbiAgfTtcbiAgcHVibGljIG9sZFByb2Nlc3NTdGF0dXMgPSAnJztcbiAgcHVibGljIHN0YWdlU3RhdHVzID0gJyc7XG4gIHB1YmxpYyBjb250ZW50czogQXJyYXk8YW55PiA9IFtdO1xuICBwdWJsaWMgY29tcGxldGlvblBlcmNlbnRhZ2UgPSAwO1xuICBwdWJsaWMgc2hvd0J1bGtVcGxvYWRNb2RhbCA9IGZhbHNlO1xuICBwdWJsaWMgYnVsa1VwbG9hZFN0YXRlID0gMDtcbiAgcHVibGljIGxvYWRpbmcgPSBmYWxzZTtcbiAgcHVibGljIHRlbGVtZXRyeVBhZ2VJZDogc3RyaW5nO1xuICBwdWJsaWMgYXNzZXRDb25maWc6IGFueSA9IHtcbiAgICBjc3Y6IHtcbiAgICAgIGFjY2VwdGVkOiAnY3N2JyxcbiAgICAgIHNpemU6IDUwXG4gICAgfVxuICB9O1xuICB1cGxvYWRlcjtcbiAgcHVibGljIGJ1bGtVcGxvYWRFcnJvck1zZ3MgPSBbXTtcbiAgcHVibGljIGJ1bGtVcGxvYWRWYWxpZGF0aW9uRXJyb3IgPSAnJztcbiAgcHVibGljIHNhbXBsZU1ldGFkYXRhQ3N2VXJsID0gJyc7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgdG9hc3RlclNlcnZpY2U6IFRvYXN0ZXJTZXJ2aWNlLCBwcml2YXRlIGVkaXRvclNlcnZpY2U6IEVkaXRvclNlcnZpY2UsIHB1YmxpYyBjb25maWdTZXJ2aWNlOiBDb25maWdTZXJ2aWNlLFxuICAgIHByaXZhdGUgYnVsa0pvYlNlcnZpY2U6IEJ1bGtKb2JTZXJ2aWNlLCBwcml2YXRlIHRyZWVTZXJ2aWNlOiBUcmVlU2VydmljZSwgcHVibGljIHRlbGVtZXRyeVNlcnZpY2U6IEVkaXRvclRlbGVtZXRyeVNlcnZpY2UpIHsgfVxuXG4gICBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLmNvbGxlY3Rpb25JZCA9IF8uZ2V0KHRoaXMuZWRpdG9yU2VydmljZS5lZGl0b3JDb25maWcsICdjb250ZXh0LmlkZW50aWZpZXInKTtcbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bWF4LWxpbmUtbGVuZ3RoXG4gICAgdGhpcy5zYW1wbGVNZXRhZGF0YUNzdlVybCA9IF8uZ2V0KHRoaXMuZWRpdG9yU2VydmljZSwgJ2VkaXRvckNvbmZpZy5jb25maWcucHVibGljU3RvcmFnZUFjY291bnQnKSArIF8uZ2V0KHRoaXMuY29uZmlnU2VydmljZS51cmxDb25GaWcsICdVUkxTLkJVTEtKT0IuU0FNUExFX1FVRVNUSU9OX0ZJTEUnKTtcbiAgICB0aGlzLmNoZWNrQnVsa1VwbG9hZFN0YXR1cygpO1xuICAgIHRoaXMuc3RhZ2VTdGF0dXMgPSB0aGlzLmdldENvbnRlbnRTdGF0dXMoKTtcbiAgfVxuXG4gIGNhbGN1bGF0ZUNvbXBsZXRpb25QZXJjZW50YWdlKCkge1xuICAgIHRoaXMuY29tcGxldGlvblBlcmNlbnRhZ2UgPSAwO1xuICAgIGNvbnNvbGUubG9nKCdwcm9jZXNzLm92ZXJhbGxfc3RhdHMnLCB0aGlzLnByb2Nlc3Mub3ZlcmFsbF9zdGF0cyk7XG4gICAgY29uc3QgeyB0b3RhbCwgdXBsb2FkX3BlbmRpbmcgfSA9IHRoaXMucHJvY2Vzcy5vdmVyYWxsX3N0YXRzO1xuXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOnJhZGl4XG4gICAgdGhpcy5jb21wbGV0aW9uUGVyY2VudGFnZSA9IHBhcnNlSW50KF8udG9OdW1iZXIoMTAwIC0gKCh1cGxvYWRfcGVuZGluZyAvIHRvdGFsKSAqIDEwMCkpKTtcbiAgICBjb25zb2xlLmxvZygnY29tcGxldGlvblBlcmNlbnRhZ2UnLCAgdGhpcy5jb21wbGV0aW9uUGVyY2VudGFnZSk7XG4gIH1cblxuICBjaGVja0J1bGtVcGxvYWRTdGF0dXMoKSB7XG4gICAgY29uc3QgcmVxRGF0YSA9IHtcbiAgICAgIGZpbHRlcnM6IHtcbiAgICAgICAgcHJvZ3JhbV9pZDogXy5nZXQodGhpcy5lZGl0b3JTZXJ2aWNlLmVkaXRvckNvbmZpZywgJ2NvbnRleHQucHJvZ3JhbUlkJywgJycpLFxuICAgICAgICBjb2xsZWN0aW9uX2lkOiB0aGlzLmNvbGxlY3Rpb25JZCxcbiAgICAgICAgdHlwZTogJ2J1bGtfdXBsb2FkJyxcbiAgICAgICAgY3JlYXRlZGJ5OiBfLmdldCh0aGlzLmVkaXRvclNlcnZpY2UuZWRpdG9yQ29uZmlnLCAnY29udGV4dC51c2VyLmlkJylcbiAgICAgIH0sXG4gICAgICBsaW1pdDogMVxuICAgIH07XG4gICAgdGhpcy5idWxrSm9iU2VydmljZS5nZXRCdWxrT3BlcmF0aW9uU3RhdHVzKHJlcURhdGEpXG4gICAgICAuc3Vic2NyaWJlKChzdGF0dXNSZXNwb25zZSkgPT4ge1xuICAgICAgICBjb25zdCBjb3VudCA9IF8uZ2V0KHN0YXR1c1Jlc3BvbnNlLCAncmVzdWx0LmNvdW50JywgMCk7XG4gICAgICAgIGlmICghY291bnQpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnByb2Nlc3MgPSBfLmZpcnN0KF8uZ2V0KHN0YXR1c1Jlc3BvbnNlLCAncmVzdWx0LnByb2Nlc3MnLCBbXSkpO1xuICAgICAgICB0aGlzLm9sZFByb2Nlc3NTdGF0dXMgPSB0aGlzLnByb2Nlc3Muc3RhdHVzO1xuICAgICAgICB0aGlzLnNlYXJjaENvbnRlbnRXaXRoUHJvY2Vzc0lkKCk7XG4gICAgICAgIHRoaXMuYnVsa1VwbG9hZFN0YXRlID0gNTtcbiAgICAgIH0sIChlcnJvcikgPT4ge1xuICAgICAgICBjb25zb2xlLmxvZyhlcnJvcik7XG4gICAgICB9KTtcbiAgfVxuXG4gIHNlYXJjaENvbnRlbnRXaXRoUHJvY2Vzc0lkKCkge1xuICAgIHRoaXMuYnVsa0pvYlNlcnZpY2Uuc2VhcmNoQ29udGVudFdpdGhQcm9jZXNzSWQodGhpcy5wcm9jZXNzLnByb2Nlc3NfaWQpLnN1YnNjcmliZSgoc2VhcmNoUmVzcG9uc2UpID0+IHtcbiAgICAgIHRoaXMucHJvY2Vzcy5vdmVyYWxsX3N0YXRzLnVwbG9hZF9mYWlsZWQgPSAwO1xuICAgICAgdGhpcy5wcm9jZXNzLm92ZXJhbGxfc3RhdHMudXBsb2FkX3N1Y2Nlc3MgPSAwO1xuICAgICAgdGhpcy5wcm9jZXNzLm92ZXJhbGxfc3RhdHMudXBsb2FkX3BlbmRpbmcgPSAwO1xuXG4gICAgICBpZiAoXy5nZXQoc2VhcmNoUmVzcG9uc2UsICdyZXN1bHQuY291bnQnLCAwKSA+IDApIHtcbiAgICAgICAgdGhpcy5jb250ZW50cyA9IF8uY29tcGFjdChfLmdldChzZWFyY2hSZXNwb25zZS5yZXN1bHQsICdRdWVzdGlvbicpKTtcbiAgICAgICAgbGV0IHN0YXR1cyA9IHRoaXMuc3RhZ2VTdGF0dXM7XG4gICAgICAgIGlmIChzdGF0dXMgPT09ICdkcmFmdCcpIHtcbiAgICAgICAgICBzdGF0dXMgPSAnRHJhZnQnO1xuICAgICAgICB9XG4gICAgICAgIF8uZWFjaCh0aGlzLmNvbnRlbnRzLCAoY29udGVudCkgPT4ge1xuICAgICAgICAgIGlmIChjb250ZW50LnN0YXR1cyA9PT0gJ1JldGlyZWQnKSB7XG4gICAgICAgICAgICB0aGlzLnByb2Nlc3Mub3ZlcmFsbF9zdGF0cy51cGxvYWRfZmFpbGVkKys7XG4gICAgICAgICAgfSBlbHNlIGlmIChjb250ZW50LnN0YXR1cyA9PT0gc3RhdHVzKSB7XG4gICAgICAgICAgICB0aGlzLnByb2Nlc3Mub3ZlcmFsbF9zdGF0cy51cGxvYWRfc3VjY2VzcysrO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnByb2Nlc3Mub3ZlcmFsbF9zdGF0cy51cGxvYWRfcGVuZGluZysrO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5wcm9jZXNzLm92ZXJhbGxfc3RhdHMudXBsb2FkX3BlbmRpbmcgPSB0aGlzLnByb2Nlc3Mub3ZlcmFsbF9zdGF0cy50b3RhbCAtXG4gICAgICAgICh0aGlzLnByb2Nlc3Mub3ZlcmFsbF9zdGF0cy51cGxvYWRfc3VjY2VzcyArIHRoaXMucHJvY2Vzcy5vdmVyYWxsX3N0YXRzLnVwbG9hZF9mYWlsZWQpO1xuXG4gICAgICAgIGlmICh0aGlzLnByb2Nlc3Mub3ZlcmFsbF9zdGF0cy51cGxvYWRfcGVuZGluZyA9PT0gMCkge1xuICAgICAgICAgIHRoaXMucHJvY2Vzcy5zdGF0dXMgPSAnY29tcGxldGVkJztcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmVkaXRvclNlcnZpY2UuZmV0Y2hDb2xsZWN0aW9uSGllcmFyY2h5KHRoaXMuY29sbGVjdGlvbklkKS5zdWJzY3JpYmUoKHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgdGhpcy5zdG9yZWRDb2xsZWN0aW9uRGF0YSA9IHJlc3BvbnNlLnJlc3VsdC5xdWVzdGlvblNldDtcbiAgICAgICAgICB0aGlzLmNhbGN1bGF0ZUNvbXBsZXRpb25QZXJjZW50YWdlKCk7XG4gICAgICAgICAgaWYgKHRoaXMub2xkUHJvY2Vzc1N0YXR1cyAhPT0gdGhpcy5wcm9jZXNzLnN0YXR1cykge1xuICAgICAgICAgICAgdGhpcy51cGRhdGVKb2IoKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgfSk7XG4gICAgICAgIGlmICh0aGlzLnByb2Nlc3Muc3RhdHVzID09PSAnY29tcGxldGVkJykge1xuICAgICAgICAgIHRoaXMuZWRpdG9yU2VydmljZS5uZXh0QnVsa1VwbG9hZFN0YXR1cygnY29tcGxldGVkJyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuZWRpdG9yU2VydmljZS5uZXh0QnVsa1VwbG9hZFN0YXR1cygncHJvY2Vzc2luZycpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuYnVsa1VwbG9hZEVtaXR0ZXIuZW1pdCh7IHN0YXR1czogdHJ1ZSwgdHlwZTogJ3VwZGF0ZUhpZXJhcmNoeScgfSk7XG4gICAgICB9XG4gICAgfSwgKGVycm9yKSA9PiB7XG4gICAgICBjb25zb2xlLmxvZyhlcnJvcik7XG4gICAgfSk7XG4gIH1cblxuICBkb3dubG9hZFJlcG9ydCgpIHtcbiAgICBjb25zdCBoZWFkZXJzID0gWydOYW1lIG9mIHRoZSBRdWVzdGlvbicsICdMZXZlbCAxIFF1ZXN0aW9uIFNldCBTZWN0aW9uJywgJ0tleXdvcmRzJywgJ0F1ZGllbmNlJyxcbiAgICAnQXV0aG9yJywgJ0NvcHlyaWdodCcsICdMaWNlbnNlJywgJ0F0dHJpYnV0aW9ucycsICdJZGVudGlmaWVyIG9mIHRoZSBxdWVzdGlvbiAnXTtcbiAgICB0cnkge1xuICAgICAgaGVhZGVycy5wdXNoKCdTdGF0dXMnKTtcbiAgICAgIGhlYWRlcnMucHVzaCgnUmVhc29uIGZvciBmYWlsdXJlJyk7XG5cbiAgICAgIGNvbnN0IHRhYmxlRGF0YSA9IF8ubWFwKHRoaXMuY29udGVudHMsIChjb250ZW50LCBpKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlc3VsdDogYW55ID0ge307XG4gICAgICAgIHJlc3VsdC5uYW1lID0gXy5nZXQoY29udGVudCwgJ25hbWUnLCAnJyk7XG4gICAgICAgIHJlc3VsdC5sZXZlbDEgPSAnJztcbiAgICAgICAgcmVzdWx0LmtleXdvcmRzID0gXy5qb2luKF8uZ2V0KGNvbnRlbnQsICdrZXl3b3JkcycsIFtdKSwgJywgJyk7XG4gICAgICAgIHJlc3VsdC5hdWRpZW5jZSA9IF8uam9pbihfLmdldChjb250ZW50LCAnYXVkaWVuY2UnLCBbXSksICcsICcpO1xuICAgICAgICByZXN1bHQuY3JlYXRvciA9IF8uZ2V0KGNvbnRlbnQsICdhdXRob3InLCAnJyk7XG4gICAgICAgIHJlc3VsdC5jb3B5cmlnaHQgPSBfLmdldChjb250ZW50LCAnY29weXJpZ2h0JywgJycpO1xuICAgICAgICByZXN1bHQubGljZW5zZSA9IF8uZ2V0KGNvbnRlbnQsICdsaWNlbnNlJywgJycpO1xuICAgICAgICByZXN1bHQuYXR0cmlidXRpb25zID0gXy5qb2luKF8uZ2V0KGNvbnRlbnQsICdhdHRyaWJ1dGlvbnMnLCBbXSksICcsICcpO1xuICAgICAgICByZXN1bHQuaWRlbnRpZmllciA9IF8uZ2V0KGNvbnRlbnQsICdpZGVudGlmaWVyJywgJycpO1xuICAgICAgICBjb25zdCBzZWxjdGVkVW5pdFBhcmVudHM6IGFueSA9IHRoaXMuZ2V0UGFyZW50cyh0aGlzLnN0b3JlZENvbGxlY3Rpb25EYXRhLmNoaWxkcmVuLCBjb250ZW50LmlkZW50aWZpZXIpO1xuICAgICAgICBpZiAoc2VsY3RlZFVuaXRQYXJlbnRzLmZvdW5kICYmICFfLmlzRW1wdHkoc2VsY3RlZFVuaXRQYXJlbnRzLnBhcmVudHMpKSB7XG4gICAgICAgICAgcmVzdWx0LmxldmVsMSA9IHNlbGN0ZWRVbml0UGFyZW50cy5wYXJlbnRzO1xuICAgICAgICB9XG5cbiAgICAgICAgbGV0IHN0YXR1cyA9IF8uZ2V0KGNvbnRlbnQsICdzdGF0dXMnLCAnJyk7XG4gICAgICAgIGlmICgodGhpcy5zdGFnZVN0YXR1cyA9PT0gJ2RyYWZ0JyAmJiBzdGF0dXMgPT09ICdEcmFmdCcpKSB7XG4gICAgICAgICAgc3RhdHVzID0gJ1N1Y2Nlc3MnO1xuICAgICAgICB9IGVsc2UgaWYgKHN0YXR1cyA9PT0gJ1JldGlyZWQnKSB7XG4gICAgICAgICAgc3RhdHVzID0gJ0ZhaWx1cmUnO1xuICAgICAgICB9XG5cbiAgICAgICAgcmVzdWx0LnN0YXR1cyA9IHN0YXR1cztcbiAgICAgICAgcmVzdWx0LmZhaWxlZFJlYXNvbiA9IF8uZ2V0KGNvbnRlbnQsICdxdWVzdGlvblVwbG9hZFN0YXR1cycsICcnKTtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBjc3ZEb3dubG9hZENvbmZpZyA9IHtcbiAgICAgICAgZmlsZW5hbWU6IGBCdWxrIFVwbG9hZCAke3RoaXMucXVlc3Rpb25TZXRNZXRhZGF0YS5uYW1lLnRyaW0oKX1gLFxuICAgICAgICB0YWJsZURhdGEsXG4gICAgICAgIGhlYWRlcnMsXG4gICAgICAgIHNob3dUaXRsZTogZmFsc2VcbiAgICAgIH07XG4gICAgICB0aGlzLmVkaXRvclNlcnZpY2UuZ2VuZXJhdGVDU1YoY3N2RG93bmxvYWRDb25maWcpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgY29uc29sZS5sb2coZXJyKTtcbiAgICAgIHRoaXMudG9hc3RlclNlcnZpY2UuZXJyb3IoXy5nZXQodGhpcy5jb25maWdTZXJ2aWNlLmxhYmVsQ29uZmlnLCAnbWVzc2FnZXMuZXJyb3IuMDAxJykpO1xuICAgIH1cbiAgfVxuXG4gIHVwZGF0ZUpvYigpIHtcbiAgICBjb25zdCByZXFEYXRhID0ge1xuICAgICAgcHJvY2Vzc19pZDogdGhpcy5wcm9jZXNzLnByb2Nlc3NfaWQsXG4gICAgICBvdmVyYWxsX3N0YXRzOiB0aGlzLnByb2Nlc3Mub3ZlcmFsbF9zdGF0cyxcbiAgICAgIHN0YXR1czogdGhpcy5wcm9jZXNzLnN0YXR1cyxcbiAgICAgIHVwZGF0ZWRieTogXy5nZXQodGhpcy5lZGl0b3JTZXJ2aWNlLmVkaXRvckNvbmZpZywgJ2NvbnRleHQudXNlci5pZCcpXG4gICAgfTtcbiAgICB0aGlzLmJ1bGtKb2JTZXJ2aWNlLnVwZGF0ZUJ1bGtKb2IocmVxRGF0YSlcbiAgICAgIC5zdWJzY3JpYmUoKHVwZGF0ZVJlc3BvbnNlKSA9PiB7XG4gICAgICAgIGlmICh0aGlzLnByb2Nlc3Muc3RhdHVzID09PSAnY29tcGxldGVkJykge1xuICAgICAgICAgIHRoaXMuYnVsa1VwbG9hZFN0YXRlID0gNjtcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLnByb2Nlc3Muc3RhdHVzID09PSAncHJvY2Vzc2luZycpIHtcbiAgICAgICAgICB0aGlzLmJ1bGtVcGxvYWRTdGF0ZSA9IDU7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5vbGRQcm9jZXNzU3RhdHVzID0gdGhpcy5wcm9jZXNzLnN0YXR1cztcbiAgICAgIH0sIChlcnJvcikgPT4ge1xuICAgICAgICBjb25zb2xlLmxvZyhlcnJvcik7XG4gICAgICB9KTtcbiAgfVxuXG4gIGluaXRpYXRlRG9jdW1lbnRVcGxvYWRNb2RhbCgpIHtcbiAgICB0aGlzLmxvYWRpbmcgPSBmYWxzZTtcbiAgICB0aGlzLmJ1bGtVcGxvYWRWYWxpZGF0aW9uRXJyb3IgPSAnJztcbiAgICB0aGlzLmJ1bGtVcGxvYWRFcnJvck1zZ3MgPSBbXTtcbiAgICByZXR1cm4gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLmluaXRpYXRlVXBsb2FkTW9kYWwoKTtcbiAgICB9LCAwKTtcbiAgfVxuXG4gIGluaXRpYXRlVXBsb2FkTW9kYWwoKSB7XG4gICAgdGhpcy51cGxvYWRlciA9IG5ldyBGaW5lVXBsb2FkZXIoe1xuICAgICAgZWxlbWVudDogZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3VwbG9hZC1kb2N1bWVudC1kaXYnKSxcbiAgICAgIHRlbXBsYXRlOiAncXEtdGVtcGxhdGUtdmFsaWRhdGlvbicsXG4gICAgICBtdWx0aXBsZTogZmFsc2UsXG4gICAgICBhdXRvVXBsb2FkOiBmYWxzZSxcbiAgICAgIHJlcXVlc3Q6IHtcbiAgICAgICAgZW5kcG9pbnQ6ICcvYXNzZXRzL3VwbG9hZHMnXG4gICAgICB9LFxuICAgICAgdmFsaWRhdGlvbjoge1xuICAgICAgICBhbGxvd2VkRXh0ZW5zaW9uczogW3RoaXMuYXNzZXRDb25maWcuY3N2LmFjY2VwdGVkXSxcbiAgICAgICAgYWNjZXB0RmlsZXM6IFsndGV4dC9jc3YnXSxcbiAgICAgICAgaXRlbUxpbWl0OiAxLFxuICAgICAgICBzaXplTGltaXQ6IF8udG9OdW1iZXIodGhpcy5hc3NldENvbmZpZy5jc3Yuc2l6ZSkgKiAxMDI0ICogMTAyNCAgLy8gQ29udmVydCBpbnRvIE1CXG4gICAgICB9LFxuICAgICAgbWVzc2FnZXM6IHtcbiAgICAgICAgc2l6ZUVycm9yOiBge2ZpbGV9IGlzIHRvbyBsYXJnZSwgbWF4aW11bSBmaWxlIHNpemUgaXMgJHt0aGlzLmFzc2V0Q29uZmlnLmNzdi5zaXplfSBNQi5gLFxuICAgICAgICB0eXBlRXJyb3I6IGBJbnZhbGlkIGNvbnRlbnQgdHlwZSAoc3VwcG9ydGVkIHR5cGU6ICR7dGhpcy5hc3NldENvbmZpZy5jc3YuYWNjZXB0ZWR9KWBcbiAgICAgIH0sXG4gICAgICBjYWxsYmFja3M6IHtcbiAgICAgICAgb25TdGF0dXNDaGFuZ2U6ICgpID0+IHsgfSxcbiAgICAgICAgb25TdWJtaXQ6ICgpID0+IHtcbiAgICAgICAgICB0aGlzLnVwbG9hZENvbnRlbnQoKTtcbiAgICAgICAgfSxcbiAgICAgICAgb25FcnJvcjogKCkgPT4ge1xuICAgICAgICAgIHRoaXMudXBsb2FkZXIucmVzZXQoKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pO1xuICAgIHRoaXMuZmluZVVwbG9hZGVyVUkubmF0aXZlRWxlbWVudC5yZW1vdmUoKTtcbiAgfVxuXG4gIHVwbG9hZENvbnRlbnQoKSB7XG4gICAgY29uc3QgZmlsZSA9IHRoaXMudXBsb2FkZXIuZ2V0RmlsZSgwKTtcbiAgICBjb25zdCBmaWxlbmFtZSA9IHRoaXMudXBsb2FkZXIuZ2V0TmFtZSgwKTtcbiAgICBpZiAoZmlsZSA9PSBudWxsKSB7XG4gICAgICB0aGlzLnRvYXN0ZXJTZXJ2aWNlLmVycm9yKCdGaWxlIGlzIHJlcXVpcmVkIHRvIHVwbG9hZCcpO1xuICAgICAgdGhpcy51cGxvYWRlci5yZXNldCgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmJ1bGtVcGxvYWRTdGF0ZSA9IDM7XG4gICAgdGhpcy5zdGFydEJ1bGtVcGxvYWQoZmlsZSwgZmlsZW5hbWUpO1xuICB9XG5cbiAgc3RhcnRCdWxrVXBsb2FkKGZpbGUsIGZpbGVuYW1lKSB7XG4gICAgdGhpcy5nZW5lcmF0ZVByZVNpZ25lZFVybChmaWxlbmFtZSkucGlwZShcbiAgICAgIG1hcChyZXNwb25zZSA9PiB7XG4gICAgICAgIHJldHVybiBfLmdldChyZXNwb25zZS5yZXN1bHQsICdwcmVfc2lnbmVkX3VybCcpO1xuICAgIH0pLCBtZXJnZU1hcChzaWduZWRVUkwgPT4gIHtcbiAgICAgIHJldHVybiB0aGlzLnVwbG9hZFRvQmxvYihzaWduZWRVUkwsIGZpbGUpO1xuICAgIH0pLCBtZXJnZU1hcChzaWduZWRVUkwgPT4gdGhpcy5jcmVhdGVJbXBvcnRSZXF1ZXN0KHNpZ25lZFVSTCkucGlwZShcbiAgICAgIG1hcChpbXBvcnRSZXNwb25zZSA9PiB7XG4gICAgICAgIHRoaXMucHJvY2Vzcy5wcm9jZXNzX2lkID0gXy5nZXQoaW1wb3J0UmVzcG9uc2UsICdyZXN1bHQucHJvY2Vzc0lkJyk7XG4gICAgICAgIHJldHVybiBfLmdldChpbXBvcnRSZXNwb25zZSwgJ3Jlc3VsdC5jb3VudCcpO1xuICAgIH0pKSksIG1lcmdlTWFwKHRvdGFsUXVlc3Rpb24gPT4gdGhpcy5jcmVhdGVKb2JSZXF1ZXN0KHRvdGFsUXVlc3Rpb24pXG4gICAgKSkuc3Vic2NyaWJlKChqb2JSZXNwb25zZSkgPT4ge1xuICAgICAgICB0aGlzLnByb2Nlc3MgPSBfLmdldChqb2JSZXNwb25zZSwgJ3Jlc3VsdCcpO1xuICAgICAgICB0aGlzLm9sZFByb2Nlc3NTdGF0dXMgPSB0aGlzLnByb2Nlc3Muc3RhdHVzO1xuICAgICAgICB0aGlzLmNhbGN1bGF0ZUNvbXBsZXRpb25QZXJjZW50YWdlKCk7XG4gICAgICAgIHRoaXMuZWRpdG9yU2VydmljZS5uZXh0QnVsa1VwbG9hZFN0YXR1cygncHJvY2Vzc2luZycpO1xuICAgICAgICB0aGlzLmJ1bGtVcGxvYWRFbWl0dGVyLmVtaXQoeyBzdGF0dXM6IHRydWUsIHR5cGU6ICd1cGRhdGVIaWVyYXJjaHknIH0pO1xuICAgICAgICBjb25zb2xlLmxvZygncmVzcG9uc2UgOjonLCBqb2JSZXNwb25zZSk7XG4gICAgfSk7XG4gIH1cblxuICBnZW5lcmF0ZVByZVNpZ25lZFVybChmaWxlbmFtZSkge1xuICAgIGNvbnN0IHJlcXVlc3QgPSB7XG4gICAgICBjb250ZW50OiB7XG4gICAgICAgIGZpbGVOYW1lOiBmaWxlbmFtZVxuICAgICAgfVxuICAgIH07XG4gICAgcmV0dXJuIHRoaXMuZWRpdG9yU2VydmljZS5nZW5lcmF0ZVByZVNpZ25lZFVybChyZXF1ZXN0LCB0aGlzLmNvbGxlY3Rpb25JZCwgJ2hpZXJhcmNoeScpLnBpcGUoY2F0Y2hFcnJvcihlcnIgPT4ge1xuICAgICAgY29uc3QgZXJySW5mbyA9IHsgZXJyb3JNc2c6IF8uZ2V0KHRoaXMuY29uZmlnU2VydmljZS5sYWJlbENvbmZpZywgJ21lc3NhZ2VzLmVycm9yLjAzNScpIH07XG4gICAgICB0aGlzLnVwbG9hZGVyLnJlc2V0KCk7XG4gICAgICB0aGlzLnVwZGF0ZUJ1bGtVcGxvYWRTdGF0ZSgnZGVjcmVtZW50Jyk7XG4gICAgICByZXR1cm4gdGhyb3dFcnJvcih0aGlzLmVkaXRvclNlcnZpY2UuYXBpRXJyb3JIYW5kbGluZyhlcnIsIGVyckluZm8pKTtcbiAgICB9KSk7XG4gIH1cblxuICB1cGxvYWRUb0Jsb2Ioc2lnbmVkVVJMLCBmaWxlKSB7XG4gICAgY29uc3QgY3NwID0gXy5nZXQodGhpcy5lZGl0b3JTZXJ2aWNlLmVkaXRvckNvbmZpZywgJ2NvbnRleHQuY2xvdWRTdG9yYWdlLnByb3ZpZGVyJywgJ2F6dXJlJyk7XG4gICAgY29uc3QgdXBsb2FkZXJMaWIgPSBuZXcgU3VuYmlyZEZpbGVVcGxvYWRMaWIuRmlsZVVwbG9hZGVyKCk7XG4gICAgcmV0dXJuIHVwbG9hZGVyTGliLnVwbG9hZCh7IHVybDogc2lnbmVkVVJMLCBmaWxlLCBjc3AgfSlcbiAgICAub24oXCJlcnJvclwiLCAoZXJyb3IpID0+IHtcbiAgICAgIGNvbnN0IGVyckluZm8gPSB7IGVycm9yTXNnOiBfLmdldCh0aGlzLmNvbmZpZ1NlcnZpY2UubGFiZWxDb25maWcsICdtZXNzYWdlcy5lcnJvci4wMzYnKX07XG4gICAgICB0aGlzLnVwbG9hZGVyLnJlc2V0KCk7XG4gICAgICB0aGlzLnVwZGF0ZUJ1bGtVcGxvYWRTdGF0ZSgnZGVjcmVtZW50Jyk7XG4gICAgICByZXR1cm4gdGhyb3dFcnJvcih0aGlzLmVkaXRvclNlcnZpY2UuYXBpRXJyb3JIYW5kbGluZyhlcnJvciwgZXJySW5mbykpO1xuICAgIH0pLm9uKFwiY29tcGxldGVkXCIsIChjb21wbGV0ZWQpID0+IHtcbiAgICAgIHJldHVybiAgc2lnbmVkVVJMLnNwbGl0KCc/JylbMF1cbiAgICB9KVxuICB9XG5cbiAgY3JlYXRlSW1wb3J0UmVxdWVzdChmaWxlVXJsKSB7XG4gICAgbGV0IHJlcUJvZHkgPSB7XG4gICAgICBmaWxlVXJsLFxuICAgICAgcXVlc3Rpb25UeXBlOiAnTUNRJyxcbiAgICAgIGNyZWF0ZWRCeTogXy5nZXQodGhpcy5lZGl0b3JTZXJ2aWNlLmVkaXRvckNvbmZpZywgJ2NvbnRleHQudXNlci5pZCcpLFxuICAgICAgYXV0aG9yOiBfLmdldCh0aGlzLmVkaXRvclNlcnZpY2UuZWRpdG9yQ29uZmlnLCAnY29udGV4dC51c2VyLmZ1bGxOYW1lJywgJycpLFxuICAgICAgc3RhdHVzOiAnRHJhZnQnLFxuICAgICAgcXVlc3Rpb25TZXRJZDogdGhpcy5jb2xsZWN0aW9uSWRcbiAgICB9O1xuICAgIGNvbnN0IGhlYWRlcnMgPSB7ICdYLUNoYW5uZWwtSUQnOiBfLmdldCh0aGlzLmVkaXRvclNlcnZpY2UuZWRpdG9yQ29uZmlnLCAnY29udGV4dC5jaGFubmVsJykgfTtcbiAgICBjb25zdCBkZXJpdmVkUHJvcGVydGllcyA9IFsnYWRkaXRpb25hbENhdGVnb3JpZXMnLCAnYm9hcmQnLCAnbWVkaXVtJywgJ2dyYWRlTGV2ZWwnLCAnc3ViamVjdCcsICdhdWRpZW5jZScsXG4gICAgJ2xpY2Vuc2UnLCAnZnJhbWV3b3JrJywgJ3RvcGljJ107XG4gICAgcmVxQm9keSA9IF8ubWVyZ2Uoe30sIHJlcUJvZHksIF8ucGljayh0aGlzLnF1ZXN0aW9uU2V0TWV0YWRhdGEsIGRlcml2ZWRQcm9wZXJ0aWVzKSk7XG4gICAgcmV0dXJuIHRoaXMuYnVsa0pvYlNlcnZpY2UuY3JlYXRlQnVsa0ltcG9ydChyZXFCb2R5LCBoZWFkZXJzKS5waXBlKGNhdGNoRXJyb3IoZXJyID0+IHtcbiAgICAgIGNvbnN0IGVyckluZm8gPSB7IGVycm9yTXNnOiBfLmdldCh0aGlzLmNvbmZpZ1NlcnZpY2UubGFiZWxDb25maWcsICdtZXNzYWdlcy5lcnJvci4wMDEnKX07XG4gICAgICB0aGlzLnVwbG9hZGVyLnJlc2V0KCk7XG4gICAgICBpZiAoXy5nZXQoZXJyLCAnZXJyb3IucmVzdWx0Lm1lc3NhZ2VzJykpIHtcbiAgICAgICAgdGhpcy5idWxrVXBsb2FkU3RhdGUgPSA0O1xuICAgICAgICB0aGlzLmJ1bGtVcGxvYWRFcnJvck1zZ3MgID0gXy5nZXQoZXJyLCAnZXJyb3IucmVzdWx0Lm1lc3NhZ2VzJyk7XG4gICAgICAgIHJldHVybiB0aHJvd0Vycm9yKHt9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMudXBkYXRlQnVsa1VwbG9hZFN0YXRlKCdkZWNyZW1lbnQnKTtcbiAgICAgICAgcmV0dXJuIHRocm93RXJyb3IodGhpcy5lZGl0b3JTZXJ2aWNlLmFwaUVycm9ySGFuZGxpbmcoZXJyLCBlcnJJbmZvKSk7XG4gICAgICB9XG4gICAgfSkpO1xuICB9XG5cbiAgZ2V0IHF1ZXN0aW9uU2V0TWV0YWRhdGEoKSB7XG4gICAgY29uc3Qgcm9vdE5vZGUgPSB0aGlzLnRyZWVTZXJ2aWNlLmdldEZpcnN0Q2hpbGQoKTtcbiAgICByZXR1cm4gXy5nZXQocm9vdE5vZGUsICdkYXRhLm1ldGFkYXRhJyk7XG4gIH1cblxuICB2aWV3RGV0YWlscygkZXZlbnQpIHtcbiAgICAkZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB0aGlzLnNob3dCdWxrVXBsb2FkTW9kYWwgPSB0cnVlO1xuICAgIGlmICh0aGlzLnByb2Nlc3Muc3RhdHVzID09PSAncHJvY2Vzc2luZycpIHtcbiAgICAgIHRoaXMuYnVsa1VwbG9hZFN0YXRlID0gNTtcbiAgICAgIHRoaXMuY2hlY2tCdWxrVXBsb2FkU3RhdHVzKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuYnVsa1VwbG9hZFN0YXRlID0gNjtcbiAgICB9XG4gIH1cblxuICAgZ2V0Q29udGVudFN0YXR1cygpIHtcbiAgICAgcmV0dXJuICdkcmFmdCc7XG4gIH1cblxuICBjcmVhdGVKb2JSZXF1ZXN0KHJvd3NDb3VudCkge1xuICAgIHRoaXMuYnVsa1VwbG9hZFN0YXRlID0gNTtcbiAgICBjb25zdCBvcmdJZCA9ICBfLmdldCh0aGlzLmVkaXRvclNlcnZpY2UuZWRpdG9yQ29uZmlnLCAnY29udGV4dC5jb250cmlidXRpb25PcmdJZCcpO1xuICAgIGNvbnN0IGNyZWF0ZWRieSA9IF8uZ2V0KHRoaXMuZWRpdG9yU2VydmljZS5lZGl0b3JDb25maWcsICdjb250ZXh0LnVzZXIuaWQnKTtcbiAgICBjb25zdCBwcm9ncmFtSWQgPSBfLmdldCh0aGlzLmVkaXRvclNlcnZpY2UuZWRpdG9yQ29uZmlnLCAnY29udGV4dC5wcm9ncmFtSWQnLCAnJyk7XG4gICAgY29uc3QgY29sbGVjdGlvbklkID0gdGhpcy5jb2xsZWN0aW9uSWQ7XG5cbiAgICB0aGlzLnByb2Nlc3Mub3ZlcmFsbF9zdGF0cyA9IHtcbiAgICAgIHRvdGFsOiByb3dzQ291bnQsXG4gICAgICB1cGxvYWRfcGVuZGluZzogcm93c0NvdW50LFxuICAgICAgdXBsb2FkX2ZhaWxlZDogMCxcbiAgICAgIHVwbG9hZF9zdWNjZXNzOiAwXG4gICAgfTtcbiAgICB0aGlzLnByb2Nlc3MuZGF0YSA9IHtcbiAgICAgIHByb2dyYW1faWQ6IHByb2dyYW1JZCxcbiAgICAgIGNvbGxlY3Rpb25faWQ6IGNvbGxlY3Rpb25JZFxuICAgIH07XG4gICAgdGhpcy5wcm9jZXNzLmNyZWF0ZWRvbiA9IG5ldyBEYXRlKCk7XG4gICAgdGhpcy5wcm9jZXNzLmNyZWF0ZWRieSA9IGNyZWF0ZWRieTtcbiAgICB0aGlzLnByb2Nlc3MucHJvZ3JhbV9pZCA9IHByb2dyYW1JZDtcbiAgICB0aGlzLnByb2Nlc3MuY29sbGVjdGlvbl9pZCA9IGNvbGxlY3Rpb25JZDtcbiAgICB0aGlzLnByb2Nlc3Muc3RhdHVzID0gJ3Byb2Nlc3NpbmcnO1xuXG4gICAgaWYgKG9yZ0lkKSB7XG4gICAgICB0aGlzLnByb2Nlc3MuZGF0YS5vcmdfaWQgPSBvcmdJZDtcbiAgICAgIHRoaXMucHJvY2Vzcy5vcmdfaWQgPSBvcmdJZDtcbiAgICB9XG4gICAgY29uc3QgcmVxdWVzdCA9IHsgLi4udGhpcy5wcm9jZXNzIH07XG4gICAgcmV0dXJuIHRoaXMuYnVsa0pvYlNlcnZpY2UuY3JlYXRlQnVsa0pvYihyZXF1ZXN0KTtcbiAgfVxuXG4gIGFzeW5jIG9wZW5CdWxrVXBsb2FkTW9kYWwoKSB7XG4gICAgdGhpcy5idWxrVXBsb2FkU3RhdGUgPSAwO1xuICAgIHRoaXMuc2hvd0J1bGtVcGxvYWRNb2RhbCA9IHRydWU7XG4gICAgdGhpcy51cGRhdGVCdWxrVXBsb2FkU3RhdGUoJ2luY3JlbWVudCcpO1xuICB9XG5cbiAgY2xvc2VCdWxrVXBsb2FkTW9kYWwoKSB7XG4gICAgdGhpcy5zaG93QnVsa1VwbG9hZE1vZGFsID0gZmFsc2U7XG4gICAgdGhpcy5idWxrVXBsb2FkU3RhdGUgPSAwO1xuICAgIGlmICh0aGlzLnVwbG9hZGVyKSB7XG4gICAgICB0aGlzLnVwbG9hZGVyLnJlc2V0KCk7XG4gICAgfVxuICB9XG5cbiAgdXBkYXRlQnVsa1VwbG9hZFN0YXRlKGFjdGlvbikge1xuICAgIGlmICh0aGlzLmJ1bGtVcGxvYWRTdGF0ZSA9PT0gNiAmJiBhY3Rpb24gPT09ICdpbmNyZW1lbnQnKSB7XG4gICAgICByZXR1cm4gdGhpcy5jbG9zZUJ1bGtVcGxvYWRNb2RhbCgpO1xuICAgIH1cbiAgICBpZiAodGhpcy5idWxrVXBsb2FkU3RhdGUgPT09IDQgJiYgYWN0aW9uID09PSAnZGVjcmVtZW50Jykge1xuICAgICAgdGhpcy5idWxrVXBsb2FkU3RhdGUgPSAzO1xuICAgIH1cbiAgICB0aGlzLmJ1bGtVcGxvYWRTdGF0ZSArPSAoYWN0aW9uID09PSAnaW5jcmVtZW50JykgPyAxIDogLTE7XG4gICAgaWYgKHRoaXMuYnVsa1VwbG9hZFN0YXRlID09PSAyKSB7XG4gICAgICB0aGlzLmluaXRpYXRlRG9jdW1lbnRVcGxvYWRNb2RhbCgpO1xuICAgIH1cbiAgfVxuXG4gIGdldFBhcmVudHNIZWxwZXIodHJlZTogYW55LCBpZDogc3RyaW5nLCBwYXJlbnRzOiBzdHJpbmcgPSAnJykge1xuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuICAgIGlmICh0cmVlLmlkZW50aWZpZXIgPT09IGlkKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBmb3VuZDogdHJ1ZSxcbiAgICAgICAgcGFyZW50c1xuICAgICAgfTtcbiAgICB9XG4gICAgbGV0IHJlc3VsdCA9IHtcbiAgICAgIGZvdW5kOiBmYWxzZSxcbiAgICB9O1xuICAgIGlmICh0cmVlLmNoaWxkcmVuKSB7XG4gICAgICBfLmZvckVhY2godHJlZS5jaGlsZHJlbiwgKHN1YnRyZWUsIGtleSkgPT4ge1xuICAgICAgICBsZXQgbWF5YmVQYXJlbnRzID0gcGFyZW50cztcbiAgICAgICAgaWYgKHRyZWUuaWRlbnRpZmllciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgbWF5YmVQYXJlbnRzID0gdHJlZS5uYW1lO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG1heWJlUmVzdWx0OiBhbnkgPSBzZWxmLmdldFBhcmVudHNIZWxwZXIoc3VidHJlZSwgaWQsIG1heWJlUGFyZW50cyk7XG4gICAgICAgIGlmIChtYXliZVJlc3VsdC5mb3VuZCkge1xuICAgICAgICAgIHJlc3VsdCA9IG1heWJlUmVzdWx0O1xuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBnZXRQYXJlbnRzKGRhdGE6IEFycmF5PGFueT4sIGlkOiBzdHJpbmcpIHtcbiAgICBjb25zdCB0cmVlID0ge1xuICAgICAgY2hpbGRyZW46IGRhdGFcbiAgICB9O1xuICAgIHJldHVybiB0aGlzLmdldFBhcmVudHNIZWxwZXIodHJlZSwgaWQpO1xuICB9XG5cbiAgZG93bmxvYWRTYW1wbGVDU1ZGaWxlKCkge1xuICAgIGNvbnN0IGRvd25sb2FkQ29uZmlnID0ge1xuICAgICAgYmxvYlVybDogdGhpcy5zYW1wbGVNZXRhZGF0YUNzdlVybCxcbiAgICAgIHN1Y2Nlc3NNZXNzYWdlOiBmYWxzZSxcbiAgICAgIGZpbGVUeXBlOiAnY3N2JyxcbiAgICAgIGZpbGVOYW1lOiB0aGlzLmNvbGxlY3Rpb25JZFxuICAgIH07XG4gICAgd2luZG93Lm9wZW4oZG93bmxvYWRDb25maWcuYmxvYlVybCwgJ19ibGFuaycpO1xuICB9XG59XG4iLCI8ZGl2IGNsYXNzPVwiZC1mbGV4XCI+XG4gIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwic2ItYnRuIHNiLWJ0bi1ub3JtYWwgc2ItYnRuLXByaW1hcnkgdGV4dC1pbmhlcml0IG10LTJcIiBzdWlQb3B1cFxuICAgIHBvcHVwVGV4dD1cIkJ1bGsgdXBsb2FkIG11bHRpcGxlIHF1ZXN0aW9uIGF0IG9uZSB0aW1lIHVzaW5nIGEgQ1NWIGZpbGVcIiAoY2xpY2spPVwib3BlbkJ1bGtVcGxvYWRNb2RhbCgpXCJcbiAgICAqbmdJZj1cIlsnY29tcGxldGVkJywgJyddLmluY2x1ZGVzKHByb2Nlc3M/LnN0YXR1cylcIlxuICAgIGxpYlRlbGVtZXRyeUludGVyYWN0XG4gICAgW3RlbGVtZXRyeUludGVyYWN0RWRhdGFdPVwidGVsZW1ldHJ5U2VydmljZS5nZXRUZWxlbWV0cnlJbnRlcmFjdEVkYXRhKCdidWxrX3VwbG9hZF9xdWVzdGlvbicsJ2NsaWNrJywnbGF1bmNoJyxcbiAgICB0ZWxlbWV0cnlTZXJ2aWNlLnRlbGVtZXRyeVBhZ2VJZCwge2tleTogJ2lkZW50aWZpZXInLCB2YWx1ZTogY29sbGVjdGlvbklkfSlcIj57e2NvbmZpZ1NlcnZpY2UubGFiZWxDb25maWc/LmxibD8uYnVsa1VwbG9hZFF1ZXN0aW9ufX08L2J1dHRvbj5cbiAgPGRpdiBjbGFzcz1cImRpdmlkZXIgbXgtMTBcIiAqbmdJZj1cInByb2Nlc3M/LnN0YXR1cyA9PT0gJ2NvbXBsZXRlZCdcIj48L2Rpdj5cbiAgPGRpdiBjbGFzcz1cImQtZmxleCBmbGV4LWRjIGZzLTAtNzg1XCI+XG4gICAgPGRpdiBjbGFzcz1cInNiLWNvbG9yLWdyYXktNDAwXCIgKm5nSWY9XCJwcm9jZXNzPy5zdGF0dXMgPT09ICdjb21wbGV0ZWQnXCI+e3tjb25maWdTZXJ2aWNlLmxhYmVsQ29uZmlnPy5sYmw/Lmxhc3RVcGxvYWRlZH19IDoge3sgcHJvY2Vzcz8udXBkYXRlZG9uIHwgZGF0ZUZvcm1hdDogJ0QgTU1NTSBZWVlZJyB9fTwvZGl2PlxuICAgIDxkaXYgKm5nSWY9XCJwcm9jZXNzPy5zdGF0dXMgPT09ICdwcm9jZXNzaW5nJ1wiIGNsYXNzPVwicmVsYXRpdmVcIj5cbiAgICAgIDxzcGFuIGNsYXNzPVwic2ItbG9hZGVyIHNiLXN1Y2Nlc3MtbG9hZGVyXCI+PC9zcGFuPlxuICAgICAgPHNwYW4gY2xhc3M9XCJzYi1jb2xvci13YXJuaW5nIGZzLTFcIiBzdWlQb3B1cFxuICAgICAgICBwb3B1cFRleHQ9XCJCdWxrIHVwbG9hZCBvZiBxdWVzdGlvbiBpcyBpbiBwcm9ncmVzcywgb25jZSBmaW5pc2hlZCB5b3UgY2FuIGluaXRpYXRlIGFub3RoZXIgYmF0Y2hcIj57e2NvbmZpZ1NlcnZpY2UubGFiZWxDb25maWc/LmxibD8uYnVsa0luUHJvZ3Jlc3N9fTwvc3Bhbj5cbiAgICA8L2Rpdj5cbiAgICA8YSBocmVmPVwiI1wiIGNsYXNzPVwidGV4dC1kZWNvci1ub25lXCIgKm5nSWY9XCJbJ2NvbXBsZXRlZCcsICdwcm9jZXNzaW5nJ10uaW5jbHVkZXMocHJvY2Vzcz8uc3RhdHVzKVwiIChjbGljayk9XCJ2aWV3RGV0YWlscygkZXZlbnQpXCJcbiAgICBsaWJUZWxlbWV0cnlJbnRlcmFjdFxuICAgIFt0ZWxlbWV0cnlJbnRlcmFjdEVkYXRhXT1cInRlbGVtZXRyeVNlcnZpY2UuZ2V0VGVsZW1ldHJ5SW50ZXJhY3RFZGF0YSgndmlld19kZXRhaWxzJywnY2xpY2snLCdsYXVuY2gnLFxuICAgIHRlbGVtZXRyeVNlcnZpY2UudGVsZW1ldHJ5UGFnZUlkLCB7a2V5OiAnaWRlbnRpZmllcicsIHZhbHVlOiBjb2xsZWN0aW9uSWR9KVwiPnt7Y29uZmlnU2VydmljZS5sYWJlbENvbmZpZz8ubGJsPy52aWV3RGV0YWlsc319PC9hPlxuICA8L2Rpdj5cbjwvZGl2PlxuXG5cbjxzdWktbW9kYWwgKm5nSWY9XCJzaG93QnVsa1VwbG9hZE1vZGFsXCIgW211c3RTY3JvbGxdPVwidHJ1ZVwiIFtpc0Nsb3NhYmxlXT1cInRydWVcIiBbdHJhbnNpdGlvbkR1cmF0aW9uXT1cIjBcIlxuICBbc2l6ZV09XCInbm9ybWFsJ1wiIGNsYXNzPVwic2ItbW9kYWwgb3ZlcmZsb3ctbW9kYWwgc2ItYmstdXBsb2FkXCIgYXBwQm9keVNjcm9sbCAoZGlzbWlzc2VkKT1cImNsb3NlQnVsa1VwbG9hZE1vZGFsKClcIiAjbW9kYWw+XG4gIDxkaXYgY2xhc3M9XCJzYi1tb2RhbC1oZWFkZXJcIj5cbiAgICB7e2NvbmZpZ1NlcnZpY2UubGFiZWxDb25maWc/LmxibD8uYnVsa1VwbG9hZFF1ZXN0aW9ufX1cbiAgPC9kaXY+XG4gIDxkaXYgY2xhc3M9XCJzYi1tb2RhbC1jb250ZW50XCI+XG4gICAgPGRpdiBjbGFzcz1cImQtZmxleCBwLTMwIHNiLWJnLWNvbG9yLXByaW1hcnktMFwiPlxuICAgICAgPGRpdiBjbGFzcz1cInAtMTAgc2ItYnVsay11cGxvYWRcIj5cbiAgICAgICAgPGltZyBzcmM9XCIuLi8uLi9hc3NldHMvaW1hZ2VzL2J1bGt1cGxvYWRmaWxlLnBuZ1wiIGFsdD1cIlwiICpuZ0lmPVwiYnVsa1VwbG9hZFN0YXRlICE9PSA1XCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LXJpZ2h0IG15LS0yMFwiPlxuICAgICAgICAgIDxpIGNsYXNzPVwiZmEgZmEtZG93bmxvYWQgc2ItY2lyY2xlLWRvd25sb2FkLWljb25cIiAqbmdJZj1cImJ1bGtVcGxvYWRTdGF0ZSA9PT0gMVwiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPjwvaT5cbiAgICAgICAgICA8aSBjbGFzcz1cImZhIGZhLWNoZWNrIHNiLWNpcmNsZS1kb3dubG9hZC1pY29uXCIgKm5nSWY9XCJidWxrVXBsb2FkU3RhdGUgPT09IDZcIiBhcmlhLWhpZGRlbj1cInRydWVcIj48L2k+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDxkaXYgY2xhc3M9XCJwcm9ncmVzcy1jaXJjbGUgcHJvZ3Jlc3MtY2lyY2xlLS14eGwgbXItOCBtdC0yMFwiIFthdHRyLmRhdGEtcGVyY2VudGFnZV09XCJjb21wbGV0aW9uUGVyY2VudGFnZVwiICpuZ0lmPVwiYnVsa1VwbG9hZFN0YXRlID09PSA1XCI+XG4gICAgICAgICAgPHN2ZyBjbGFzcz1cInByb2dyZXNzLWNpcmNsZV9fc3ZnXCIgdmlld3BvcnQ9XCIwIDAgMjAwMCAyMDAwXCI+XG4gICAgICAgICAgICA8Y2lyY2xlIGNsYXNzPVwicHJvZ3Jlc3MtY2lyY2xlX19zdHJva2VcIiByPVwiNTAlXCIgY3g9XCI1MCVcIiBjeT1cIjUwJVwiPjwvY2lyY2xlPlxuICAgICAgICAgICAgPGNpcmNsZSBjbGFzcz1cInByb2dyZXNzLWNpcmNsZV9fc3Ryb2tlXCIgcj1cIjUwJVwiIGN4PVwiNTAlXCIgY3k9XCI1MCVcIj48L2NpcmNsZT5cbiAgICAgICAgICAgIDx0ZXh0IHg9XCI0MCVcIiB5PVwiNTAlXCIgZm9udC1zaXplPVwiMS41ZW1cIj57e2NvbXBsZXRpb25QZXJjZW50YWdlfX0lPC90ZXh0PlxuICAgICAgICAgIDwvc3ZnPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8ZGl2IGNsYXNzPVwicGwtMjAgcHQtMjAgZC1ibG9ja1wiICpuZ0lmPVwiYnVsa1VwbG9hZFN0YXRlID09PSAxXCI+XG4gICAgICAgIDxoNiBjbGFzcz1cInNiLWNvbG9yLWdyYXktNDAwXCI+e3tjb25maWdTZXJ2aWNlLmxhYmVsQ29uZmlnPy5sYmw/LmRvd25sb2FkU2FtcGxlTWV0YWRhdGFDc3ZGaWxlQW5kQ3JlYXRlfX08L2g2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwic2ItY29sb3ItZ3JheS0yMDAgcHQtMjAgZnMtMC05MlwiPnt7Y29uZmlnU2VydmljZS5sYWJlbENvbmZpZz8ubGJsPy5tYWtlU3VyZVlvdXJGaWxlfX0gOiA8L2Rpdj5cbiAgICAgICAgPHVsIGNsYXNzPVwidWkgb3JkZXJlZCBsaXN0IHNiLWRvY2stb3JkZXJlZC1saXN0IG10LTE1XCI+XG4gICAgICAgICAgPGxpIGNsYXNzPVwiaXRlbVwiPnt7Y29uZmlnU2VydmljZS5sYWJlbENvbmZpZz8ubGJsPy5hbGxDb2x1bW5zQXJlQXZhaWxhYmxlU2hvd25Gb3JtYXR9fTwvbGk+XG4gICAgICAgICAgPGxpIGNsYXNzPVwiaXRlbVwiPnt7Y29uZmlnU2VydmljZS5sYWJlbENvbmZpZz8ubGJsPy5oYXNBbGxNYW5kYXRvcnlDb2x1bW5zRmlsbGVkQXNNYXJrZWRJbkZvcm1hdH19PC9saT5cbiAgICAgICAgICA8bGkgY2xhc3M9XCJpdGVtXCI+e3tjb25maWdTZXJ2aWNlLmxhYmVsQ29uZmlnPy5sYmw/Lmhhc05vRHVwbGljYXRlVXJsc0ZpbGVwYXRoQ29sdW1ufX08L2xpPlxuICAgICAgICA8L3VsPlxuICAgICAgICA8YnV0dG9uIChjbGljayk9XCJkb3dubG9hZFNhbXBsZUNTVkZpbGUoKVwiXG4gICAgICAgICAgY2xhc3M9XCJzYi1idG4gc2ItYnRuLW5vcm1hbCBzYi1idG4tc3VjY2VzcyBteS0yMCB0ZXh0LWRlY29yLW5vbmVcIlxuICAgICAgICAgIGxpYlRlbGVtZXRyeUludGVyYWN0XG4gICAgICAgICAgICBbdGVsZW1ldHJ5SW50ZXJhY3RFZGF0YV09XCJ0ZWxlbWV0cnlTZXJ2aWNlLmdldFRlbGVtZXRyeUludGVyYWN0RWRhdGEoJ2Rvd25sb2FkX3NhbXBsZV9tZXRhZGF0YV9jc3YnLCdjbGljaycsJ2xhdW5jaCcsXG4gICAgICAgICAgICB0ZWxlbWV0cnlTZXJ2aWNlLnRlbGVtZXRyeVBhZ2VJZCwge2tleTogJ2RpYWxvZ19pZCcsIHZhbHVlOiAnYnVsa191cGxvYWRfcXVlc3Rpb24nfSlcIj48aVxuICAgICAgICAgICAgY2xhc3M9XCJmYSBmYS1kb3dubG9hZCBwci0xMFwiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPjwvaT57e2NvbmZpZ1NlcnZpY2UubGFiZWxDb25maWc/LmxibD8uZG93bmxvYWRTYW1wbGVNZXRhZGF0YUNzdn19PC9idXR0b24+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPGRpdiBjbGFzcz1cImNvbnRlbnQgcC0xMCBkLWJsb2NrIHctNzAgZmxleC1hcy1jZW50ZXIgdGV4dC1jZW50ZXJcIiAqbmdJZj1cImJ1bGtVcGxvYWRTdGF0ZSA9PT0gMlwiPlxuICAgICAgICA8ZGl2IHR5cGU9XCJ0ZXh0L3RlbXBsYXRlXCIgaWQ9XCJxcS10ZW1wbGF0ZS12YWxpZGF0aW9uXCIgI2ZpbmVVcGxvYWRlclVJPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJxcS11cGxvYWRlci1zZWxlY3RvciBxcS11cGxvYWRlciBjdXN0b20tcXEtdXBsb2FkZXJcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJxcS11cGxvYWQtZHJvcC1hcmVhLXNlbGVjdG9yIHFxLXVwbG9hZC1kcm9wLWFyZWFcIiBxcS1oaWRlLWRyb3B6b25lPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInFxLXVwbG9hZC1kcm9wLWFyZWEtdGV4dC1zZWxlY3RvclwiPjwvc3Bhbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJxcS1kcm9wLXByb2Nlc3Npbmctc2VsZWN0b3IgcXEtZHJvcC1wcm9jZXNzaW5nXCI+XG4gICAgICAgICAgICAgIDxzcGFuPnt7Y29uZmlnU2VydmljZS5sYWJlbENvbmZpZz8ubGJsPy5wcm9jZXNzaW5nRHJvcHBlZEZpbGVzfX08L3NwYW4+XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicXEtZHJvcC1wcm9jZXNzaW5nLXNwaW5uZXItc2VsZWN0b3IgcXEtZHJvcC1wcm9jZXNzaW5nLXNwaW5uZXJcIj48L3NwYW4+XG4gICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICA8dWwgY2xhc3M9XCJxcS11cGxvYWQtbGlzdC1zZWxlY3RvciBxcS11cGxvYWQtbGlzdCBjdXN0b20tcXEtdXBsb2FkLWxpc3RcIiBhcmlhLWxpdmU9XCJwb2xpdGVcIlxuICAgICAgICAgICAgICBhcmlhLXJlbGV2YW50PVwiYWRkaXRpb25zIHJlbW92YWxzXCI+XG4gICAgICAgICAgICAgIDxsaT5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicXEtcHJvZ3Jlc3MtYmFyLWNvbnRhaW5lci1zZWxlY3RvclwiPlxuICAgICAgICAgICAgICAgICAgPGRpdiByb2xlPVwicHJvZ3Jlc3NiYXJcIiBhcmlhLXZhbHVlbm93PVwiMFwiIGFyaWEtdmFsdWVtaW49XCIwXCIgYXJpYS12YWx1ZW1heD1cIjEwMFwiXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzPVwicXEtcHJvZ3Jlc3MtYmFyLXNlbGVjdG9yIHFxLXByb2dyZXNzLWJhclwiPjwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicXEtdXBsb2FkLXNwaW5uZXItc2VsZWN0b3IgcXEtdXBsb2FkLXNwaW5uZXJcIj48L3NwYW4+XG4gICAgICAgICAgICAgICAgPGltZyBjbGFzcz1cInFxLXRodW1ibmFpbC1zZWxlY3RvclwiIHFxLW1heC1zaXplPVwiMTAwXCIgYWx0PVwiXCIgcXEtc2VydmVyLXNjYWxlPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicXEtdXBsb2FkLWZpbGUtc2VsZWN0b3IgcXEtdXBsb2FkLWZpbGUgY3VzdG9tLXFxLXVwbG9hZC1maWxlXCI+PC9zcGFuPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicXEtdXBsb2FkLXNpemUtc2VsZWN0b3IgcXEtdXBsb2FkLXNpemVcIj48L3NwYW4+XG4gICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgIGNsYXNzPVwicXEtYnRuIHFxLXVwbG9hZC1yZXRyeS1zZWxlY3RvciBxcS11cGxvYWQtcmV0cnlcIj57e2NvbmZpZ1NlcnZpY2UubGFiZWxDb25maWc/LmxibD8ucmV0cnl9fTwvYnV0dG9uPlxuICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgICAgICBjbGFzcz1cInFxLWJ0biBxcS11cGxvYWQtZGVsZXRlLXNlbGVjdG9yIHFxLXVwbG9hZC1kZWxldGVcIj57e2NvbmZpZ1NlcnZpY2UubGFiZWxDb25maWc/LmxibD8ucmV0cnl9fTwvYnV0dG9uPlxuICAgICAgICAgICAgICAgIDxzcGFuIHJvbGU9XCJzdGF0dXNcIiBjbGFzcz1cInFxLXVwbG9hZC1zdGF0dXMtdGV4dC1zZWxlY3RvciBxcS11cGxvYWQtc3RhdHVzLXRleHRcIj48L3NwYW4+XG4gICAgICAgICAgICAgIDwvbGk+XG4gICAgICAgICAgICA8L3VsPlxuICAgICAgICAgICAgPGRpdiBpZD1cInFxLXVwbG9hZC1hY3Rpb25zXCIgY2xhc3M9XCJ1cGxvYWQtZmlsZS1kZXNjcmlwdGlvbiBkLWZsZXggZmxleC1haS1jZW50ZXIgZmxleC1kY1wiPlxuICAgICAgICAgICAgICA8aDUgY2xhc3M9XCJtYi04IHNiLWNvbG9yLWdyYXktNDAwXCI+XG4gICAgICAgICAgICAgICAge3tjb25maWdTZXJ2aWNlLmxhYmVsQ29uZmlnPy5sYmw/LmRyYWdBbmREcm9wfX0gPGJyIC8+XG4gICAgICAgICAgICAgICAge3tjb25maWdTZXJ2aWNlLmxhYmVsQ29uZmlnPy5sYmw/Lm9yfX1cbiAgICAgICAgICAgICAgPC9oNT5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInFxLXVwbG9hZC1idXR0b24tc2VsZWN0b3IgcXEtdXBsb2FkLWJ1dHRvbiBzYi1idG4gc2ItYnRuLW5vcm1hbCBzYi1idG4tc3VjY2VzcyBteS0yMFwiPlxuICAgICAgICAgICAgICAgIDxkaXY+e3tjb25maWdTZXJ2aWNlLmxhYmVsQ29uZmlnPy5sYmw/LnNlbGVjdEZpbGV9fTwvZGl2PlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPHAgY2xhc3M9XCJtdC04IHNiLWNvbG9yLWdyYXktMjAwIGZzLTAtNzg1XCI+e3tjb25maWdTZXJ2aWNlLmxhYmVsQ29uZmlnPy5sYmw/LnVwbG9hZENTVlhsRW50cmllc319PC9wPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGlhbG9nIGNsYXNzPVwicXEtY29uZmlybS1kaWFsb2ctc2VsZWN0b3JcIj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInFxLWRpYWxvZy1tZXNzYWdlLXNlbGVjdG9yXCI+PC9kaXY+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJxcS1kaWFsb2ctYnV0dG9uc1wiPlxuICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwicXEtY2FuY2VsLWJ1dHRvbi1zZWxlY3RvclwiPnt7Y29uZmlnU2VydmljZS5sYWJlbENvbmZpZz8ubGJsPy5ub319PC9idXR0b24+XG4gICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJxcS1vay1idXR0b24tc2VsZWN0b3JcIj57e2NvbmZpZ1NlcnZpY2UubGFiZWxDb25maWc/LmxibD8ueWVzfX08L2J1dHRvbj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2RpYWxvZz5cbiAgICAgICAgICAgIDxkaWFsb2cgY2xhc3M9XCJxcS1wcm9tcHQtZGlhbG9nLXNlbGVjdG9yXCI+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJxcS1kaWFsb2ctbWVzc2FnZS1zZWxlY3RvclwiPjwvZGl2PlxuICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInFxLWRpYWxvZy1idXR0b25zXCI+XG4gICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgIGNsYXNzPVwicXEtY2FuY2VsLWJ1dHRvbi1zZWxlY3RvclwiPnt7Y29uZmlnU2VydmljZS5sYWJlbENvbmZpZz8ubGJsPy5jYW5jZWx9fTwvYnV0dG9uPlxuICAgICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwicXEtb2stYnV0dG9uLXNlbGVjdG9yXCI+e3tjb25maWdTZXJ2aWNlLmxhYmVsQ29uZmlnPy5sYmw/Lm9rfX08L2J1dHRvbj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2RpYWxvZz5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgKm5nSWY9XCIhbG9hZGluZ1wiPlxuICAgICAgICAgIDxkaXYgaWQ9XCJ1cGxvYWQtZG9jdW1lbnQtZGl2XCIgY2xhc3M9XCJ1cGxvYWQtZmlsZS1zZWN0aW9uXCI+PC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2ICpuZ0lmPSdsb2FkaW5nJyBjbGFzcz1cInVwbG9hZGluZy1maWxlc1wiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9J2QtZmxleCBmbGV4LWRjIGZsZXgtamMtY2VudGVyIGZsZXgtYWktY2VudGVyIGljb24nPlxuICAgICAgICAgICAgPGltZyBzcmM9XCIuLi8uLi9hc3NldHMvaW1hZ2VzL1NwaW4uZ2lmXCIgY2xhc3M9J3Byb2Nlc3MtaWNvbicgYWx0PVwiXCI+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDxkaXYgY2xhc3M9XCJwLTMwIHctNzAgZmxleC1hcy1jZW50ZXIgdGV4dC1jZW50ZXJcIiAqbmdJZj1cImJ1bGtVcGxvYWRTdGF0ZSA9PT0gM1wiPlxuICAgICAgICA8ZGl2PlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJyZWxhdGl2ZSBzYi1sb2FkZXItd2l0aC1sYmxcIj5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic2ItbG9hZGVyIHNiLXN1Y2Nlc3MtbG9hZGVyIHJlbGF0aXZlXCI+PC9zcGFuPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJwbC0xMCBtbC0xMFwiPlxuICAgICAgICAgICAgICA8aDYgY2xhc3M9XCJzYi1jb2xvci1ncmF5LTQwMCBwbC0xMCBtbC0xMFwiPnt7Y29uZmlnU2VydmljZS5sYWJlbENvbmZpZz8ubGJsPy52YWxpZGF0aW5nQ1NWRmlsZX19PC9oNj5cbiAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPGRpdiBjbGFzcz1cInB0LTIwIHBsLTIwXCIgKm5nSWY9XCJidWxrVXBsb2FkU3RhdGUgPT09IDRcIj5cbiAgICAgICAgPGg2IGNsYXNzPVwic2ItY29sb3ItZ3JheS00MDAgcGwtNVwiPlxuICAgICAgICAgIDxpXG4gICAgICAgICAgICBjbGFzcz1cImZhIGZhLWV4Y2xhbWF0aW9uLXRyaWFuZ2xlIHByLTUgc2ItY29sb3ItZXJyb3JcIiBhcmlhLWhpZGRlbj1cInRydWVcIj48L2k+e3tjb25maWdTZXJ2aWNlLmxhYmVsQ29uZmlnPy5sYmw/Lm1ldGFkYXRhRmlsZVZhbGlkYXRpb25GYWlsZWR9fVxuICAgICAgICA8L2g2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwic2ItY29sb3ItZ3JheS0yMDAgcHQtMjAgZnMtMC05MiBtbC0yMCBzYi1saW5lLWhlaWdodC0xLjJcIj57e2NvbmZpZ1NlcnZpY2UubGFiZWxDb25maWc/LmxibD8ubWV0YWRhdGFGb2xsb3dpbmdFcnJvcn19PC9kaXY+XG4gICAgICAgIDx1bCBjbGFzcz1cInNiLWxpc3QtY2lyY2xlIG10LTE1XCIgKm5nSWY9XCJidWxrVXBsb2FkRXJyb3JNc2dzLmxlbmd0aCA+IDBcIj5cbiAgICAgICAgICA8bGkgY2xhc3M9XCJpdGVtXCIgKm5nRm9yPVwibGV0IG1zZyBvZiBidWxrVXBsb2FkRXJyb3JNc2dzXCI+e3ttc2d9fTwvbGk+XG4gICAgICAgIDwvdWw+XG5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8ZGl2IGNsYXNzPVwicC0yMFwiICpuZ0lmPVwiYnVsa1VwbG9hZFN0YXRlID09PSA1XCI+XG4gICAgICAgIDxkaXY+e3tjb25maWdTZXJ2aWNlLmxhYmVsQ29uZmlnPy5sYmw/LnVwbG9hZGluZ1lvdXJDb250ZW50RnJvbUNTVn19PC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJtdC0yMFwiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJ1aSBsaXN0IGZzLTAtNzg1XCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaXRlbSBzYi1jb2xvci1lcnJvclwiPnt7Y29uZmlnU2VydmljZS5sYWJlbENvbmZpZz8ubGJsPy51cGxvYWRGYWlsfX0gOiB7eyBwcm9jZXNzPy5vdmVyYWxsX3N0YXRzPy51cGxvYWRfZmFpbGVkIH19PC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaXRlbSBzYi1jb2xvci1zdWNjZXNzXCI+e3tjb25maWdTZXJ2aWNlLmxhYmVsQ29uZmlnPy5sYmw/LnVwbG9hZFN1Y2Nlc3NmdWx9fSA6IHt7IHByb2Nlc3M/Lm92ZXJhbGxfc3RhdHM/LnVwbG9hZF9zdWNjZXNzfX08L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpdGVtIHNiLWNvbG9yLXdhcm5pbmdcIj57e2NvbmZpZ1NlcnZpY2UubGFiZWxDb25maWc/LmxibD8udXBsb2FkUmVtYWluaW5nfX0gOiB7eyBwcm9jZXNzPy5vdmVyYWxsX3N0YXRzPy51cGxvYWRfcGVuZGluZyB9fTwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8ZGl2IGNsYXNzPVwicC0zMCBwdC0xMFwiICpuZ0lmPVwiYnVsa1VwbG9hZFN0YXRlID09PSA2XCI+XG4gICAgICAgIDxoNiBjbGFzcz1cIlwiPnt7Y29uZmlnU2VydmljZS5sYWJlbENvbmZpZz8ubGJsPy5idWxrVXBsb2FkQ29tcGxldGV9fTwvaDY+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJtdC0xNVwiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJ1aSBsaXN0IGZzLTAtNzg1XCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaXRlbSBzYi1jb2xvci1lcnJvclwiPnt7Y29uZmlnU2VydmljZS5sYWJlbENvbmZpZz8ubGJsPy51cGxvYWRGYWlsfX0gOiB7eyBwcm9jZXNzPy5vdmVyYWxsX3N0YXRzPy51cGxvYWRfZmFpbGVkIH19PC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiaXRlbSBzYi1jb2xvci1wcmltYXJ5XCI+e3tjb25maWdTZXJ2aWNlLmxhYmVsQ29uZmlnPy5sYmw/LmNvbnRlbnRVcGxvYWRlZH19IDoge3sgcHJvY2Vzcz8ub3ZlcmFsbF9zdGF0cz8udG90YWwgfX08L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJpdGVtIHNiLWNvbG9yLXN1Y2Nlc3NcIj57e2NvbmZpZ1NlcnZpY2UubGFiZWxDb25maWc/LmxibD8udXBsb2FkU3VjY2Vzc2Z1bH19IDoge3sgcHJvY2Vzcz8ub3ZlcmFsbF9zdGF0cz8udXBsb2FkX3N1Y2Nlc3MgfX08L2Rpdj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwic2ItYnRuIHNiLWJ0bi1ub3JtYWwgc2ItYnRuLXN1Y2Nlc3MgbXktMTBcIiAoY2xpY2spPVwiZG93bmxvYWRSZXBvcnQoKVwiXG4gICAgICAgIGxpYlRlbGVtZXRyeUludGVyYWN0XG4gICAgICAgICAgICBbdGVsZW1ldHJ5SW50ZXJhY3RFZGF0YV09XCJ0ZWxlbWV0cnlTZXJ2aWNlLmdldFRlbGVtZXRyeUludGVyYWN0RWRhdGEoJ2Rvd25sb2FkX3JlcG9ydCcsJ2NsaWNrJywnbGF1bmNoJyxcbiAgICAgICAgICAgIHRlbGVtZXRyeVNlcnZpY2UudGVsZW1ldHJ5UGFnZUlkLCB7a2V5OiAnZGlhbG9nX2lkJywgdmFsdWU6ICdidWxrX3VwbG9hZF9xdWVzdGlvbid9KVwiPlxuICAgICAgICAgIDxpIGNsYXNzPVwiZmEgZmEtZG93bmxvYWQgcHItMTBcIiBhcmlhLWhpZGRlbj1cInRydWVcIj48L2k+e3tjb25maWdTZXJ2aWNlLmxhYmVsQ29uZmlnPy5sYmw/LmRvd25sb2FkUmVwb3J0fX1cbiAgICAgICAgPC9idXR0b24+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG4gIDxkaXYgY2xhc3M9XCJzYi1tb2RhbC1hY3Rpb25zXCI+XG4gICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJzYi1idG4gc2ItYnRuLW5vcm1hbCBzYi1idG4tcHJpbWFyeVwiIChjbGljayk9XCJ1cGRhdGVCdWxrVXBsb2FkU3RhdGUoJ2luY3JlbWVudCcpXCJcbiAgICAgICpuZ0lmPVwiYnVsa1VwbG9hZFN0YXRlID09PSAxXCJcbiAgICAgIGxpYlRlbGVtZXRyeUludGVyYWN0XG4gICAgICAgICAgICBbdGVsZW1ldHJ5SW50ZXJhY3RFZGF0YV09XCJ0ZWxlbWV0cnlTZXJ2aWNlLmdldFRlbGVtZXRyeUludGVyYWN0RWRhdGEoJ25leHQnLCdjbGljaycsJ2xhdW5jaCcsXG4gICAgICAgICAgICB0ZWxlbWV0cnlTZXJ2aWNlLnRlbGVtZXRyeVBhZ2VJZCwge2tleTogJ2RpYWxvZ19pZCcsIHZhbHVlOiAnYnVsa191cGxvYWRfcXVlc3Rpb24nfSlcIj57e2NvbmZpZ1NlcnZpY2UubGFiZWxDb25maWc/LmxibD8ubmV4dH19PC9idXR0b24+XG4gICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJzYi1idG4gc2ItYnRuLW5vcm1hbCBzYi1idG4tb3V0bGluZS1wcmltYXJ5XCJcbiAgICAgIChjbGljayk9XCJ1cGRhdGVCdWxrVXBsb2FkU3RhdGUoJ2RlY3JlbWVudCcpXCJcbiAgICAgICpuZ0lmPVwiIVsxLDUsNl0uaW5jbHVkZXMoYnVsa1VwbG9hZFN0YXRlKVwiXG4gICAgICBsaWJUZWxlbWV0cnlJbnRlcmFjdFxuICAgICAgICAgICAgW3RlbGVtZXRyeUludGVyYWN0RWRhdGFdPVwidGVsZW1ldHJ5U2VydmljZS5nZXRUZWxlbWV0cnlJbnRlcmFjdEVkYXRhKCdiYWNrJywnY2xpY2snLCdsYXVuY2gnLFxuICAgICAgICAgICAgdGVsZW1ldHJ5U2VydmljZS50ZWxlbWV0cnlQYWdlSWQsIHtrZXk6ICdkaWFsb2dfaWQnLCB2YWx1ZTogJ2J1bGtfdXBsb2FkX3F1ZXN0aW9uJ30pXCJcbiAgICAgID57e2NvbmZpZ1NlcnZpY2UubGFiZWxDb25maWc/LmxibD8uYmFja319PC9idXR0b24+XG4gICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJzYi1idG4gc2ItYnRuLW5vcm1hbFwiXG4gICAgICBbbmdDbGFzc109XCJ7J3NiLWJ0bi1vdXRsaW5lLXByaW1hcnknOiBidWxrVXBsb2FkU3RhdGUgPT09IDUsICdzYi1idG4tcHJpbWFyeSc6IGJ1bGtVcGxvYWRTdGF0ZSA9PT0gNn1cIlxuICAgICAgKGNsaWNrKT1cImNsb3NlQnVsa1VwbG9hZE1vZGFsKClcIlxuICAgICAgKm5nSWY9XCJbNSw2XS5pbmNsdWRlcyhidWxrVXBsb2FkU3RhdGUpXCJcbiAgICAgIGxpYlRlbGVtZXRyeUludGVyYWN0XG4gICAgICAgICAgICBbdGVsZW1ldHJ5SW50ZXJhY3RFZGF0YV09XCJ0ZWxlbWV0cnlTZXJ2aWNlLmdldFRlbGVtZXRyeUludGVyYWN0RWRhdGEoJ2Nsb3NlJywnY2xpY2snLCdsYXVuY2gnLFxuICAgICAgICAgICAgdGVsZW1ldHJ5U2VydmljZS50ZWxlbWV0cnlQYWdlSWQsIHtrZXk6ICdkaWFsb2dfaWQnLCB2YWx1ZTogJ2J1bGtfdXBsb2FkX3F1ZXN0aW9uJ30pXCI+e3tjb25maWdTZXJ2aWNlLmxhYmVsQ29uZmlnPy5sYmw/LmNsb3NlfX08L2J1dHRvbj5cbiAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGZsZXgtamMtc3BhY2UtYmV0d2VlbiB3LTEwMFwiICpuZ0lmPVwiYnVsa1VwbG9hZFN0YXRlID09PSA1XCI+XG4gICAgICA8ZGl2IGNsYXNzPVwic2ItY29sb3ItZ3JheS0yMDAgZnhzbWFsbCBsaW5lLWhlaWdodC0xLTMgdy0xMDBcIj5cbiAgICAgICAge3tjb25maWdTZXJ2aWNlLmxhYmVsQ29uZmlnPy5sYmw/LmJ1bGtVcGxvYWROb3RpY2VMaW5lMX19XG4gICAgICAgIDxzdHJvbmc+J3t7Y29uZmlnU2VydmljZS5sYWJlbENvbmZpZz8ubGJsPy5jbG9zZX19Jzwvc3Ryb25nPlxuICAgICAgICB7e2NvbmZpZ1NlcnZpY2UubGFiZWxDb25maWc/LmxibD8uYnVsa1VwbG9hZE5vdGljZUxpbmUyfX08YnIgLz5cbiAgICAgICAge3tjb25maWdTZXJ2aWNlLmxhYmVsQ29uZmlnPy5sYmw/LmJ1bGtVcGxvYWROb3RpY2VMaW5lM319XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L3N1aS1tb2RhbD4iXX0=
|