ngx-scandoc 15.2.2 → 16.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/core/components/scan/scan.component.d.ts +3 -1
- package/core/components/scan-results/scan-results.component.d.ts +1 -1
- package/core/components/webcam/webcam/webcam.component.d.ts +1 -1
- package/core/interfaces/config.d.ts +1 -0
- package/dialogs/components/scan-profile/scan-profile.component.d.ts +1 -1
- package/{esm2020 → esm2022}/core/components/camera-switch/camera-switch.component.mjs +4 -4
- package/{esm2020 → esm2022}/core/components/components.module.mjs +21 -21
- package/{esm2020 → esm2022}/core/components/manual-scan/manual-scan.component.mjs +4 -4
- package/esm2022/core/components/scan/scan.component.mjs +714 -0
- package/{esm2020 → esm2022}/core/components/scan-results/scan-results.component.mjs +4 -4
- package/{esm2020 → esm2022}/core/components/webcam/webcam/webcam.component.mjs +4 -4
- package/{esm2020 → esm2022}/core/components/webcam/webcam.module.mjs +5 -5
- package/{esm2020 → esm2022}/core/interfaces/config.mjs +1 -1
- package/{esm2020 → esm2022}/core/pipes/pipes.module.mjs +5 -5
- package/{esm2020 → esm2022}/core/pipes/safeResourceUrl.pipe.mjs +4 -4
- package/{esm2020 → esm2022}/core/shared/material.module.mjs +85 -85
- package/{esm2020 → esm2022}/dialogs/components/blank/blank.component.mjs +4 -4
- package/{esm2020 → esm2022}/dialogs/components/confirm/confirm.component.mjs +4 -4
- package/{esm2020 → esm2022}/dialogs/components/loading/loading.component.mjs +4 -4
- package/{esm2020 → esm2022}/dialogs/components/prompt-manual/prompt-manual.component.mjs +4 -4
- package/{esm2020 → esm2022}/dialogs/components/scan-profile/scan-profile.component.mjs +4 -4
- package/{esm2020 → esm2022}/dialogs/components/scan-selfie/scan-selfie.component.mjs +4 -4
- package/{esm2020 → esm2022}/dialogs/components/turn-document/turn-document.component.mjs +4 -4
- package/{esm2020 → esm2022}/dialogs/dialogs.core.provider.mjs +4 -4
- package/{esm2020 → esm2022}/dialogs/dialogs.module.mjs +35 -35
- package/esm2022/forms/form.module.mjs +87 -0
- package/{esm2020 → esm2022}/forms/types/avatar.type.mjs +6 -6
- package/{esm2020 → esm2022}/forms/types/profile.image.type.mjs +6 -6
- package/{esm2020 → esm2022}/forms/types/title.type.mjs +6 -6
- package/{esm2020 → esm2022}/lib/ngx-scandoc.module.mjs +5 -5
- package/{esm2020 → esm2022}/providers/auth.provider.mjs +4 -4
- package/{esm2020 → esm2022}/providers/camera.provider.mjs +4 -4
- package/{esm2020 → esm2022}/providers/interceptor.provider.mjs +4 -4
- package/{esm2020 → esm2022}/providers/layout.provider.mjs +4 -4
- package/{esm2020 → esm2022}/providers/scan.form.mjs +4 -4
- package/esm2022/providers/scan.provider.mjs +766 -0
- package/{esm2020 → esm2022}/providers/translate-loader.provider.mjs +4 -4
- package/{esm2020 → esm2022}/providers/translation.provider.mjs +4 -4
- package/{esm2020 → esm2022}/providers/webrtc.provider.mjs +4 -4
- package/{fesm2020 → fesm2022}/ngx-scandoc.mjs +322 -321
- package/fesm2022/ngx-scandoc.mjs.map +1 -0
- package/package.json +13 -19
- package/providers/scan.provider.d.ts +8 -1
- package/src/assets/i18n/de.json +3 -1
- package/src/assets/i18n/en.json +3 -2
- package/src/assets/i18n/hr.json +3 -1
- package/src/assets/i18n/it.json +3 -1
- package/esm2020/core/components/scan/scan.component.mjs +0 -723
- package/esm2020/forms/form.module.mjs +0 -87
- package/esm2020/providers/scan.provider.mjs +0 -756
- package/fesm2015/ngx-scandoc.mjs +0 -4476
- package/fesm2015/ngx-scandoc.mjs.map +0 -1
- package/fesm2020/ngx-scandoc.mjs.map +0 -1
- /package/{esm2020 → esm2022}/core/app.worker.mjs +0 -0
- /package/{esm2020 → esm2022}/core/components/base.component.mjs +0 -0
- /package/{esm2020 → esm2022}/core/components/webcam/domain/webcam-image.mjs +0 -0
- /package/{esm2020 → esm2022}/core/components/webcam/domain/webcam-init-error.mjs +0 -0
- /package/{esm2020 → esm2022}/core/components/webcam/domain/webcam-mirror-properties.mjs +0 -0
- /package/{esm2020 → esm2022}/core/components/webcam/util/webcam.util.mjs +0 -0
- /package/{esm2020 → esm2022}/core/helpers/object-utils.mjs +0 -0
- /package/{esm2020 → esm2022}/core/interfaces/guest.data.mjs +0 -0
- /package/{esm2020 → esm2022}/core/tokens/config.tokens.mjs +0 -0
- /package/{esm2020 → esm2022}/ngx-scandoc.mjs +0 -0
- /package/{esm2020 → esm2022}/public-api.mjs +0 -0
|
@@ -0,0 +1,714 @@
|
|
|
1
|
+
import { Component, EventEmitter, Output, HostListener, ChangeDetectionStrategy, Input, HostBinding, } from '@angular/core';
|
|
2
|
+
import { Subject } from 'rxjs';
|
|
3
|
+
import { FormGroup } from '@angular/forms';
|
|
4
|
+
import { catchError } from 'rxjs/operators';
|
|
5
|
+
import { ScanProvider } from '../../../providers/scan.provider';
|
|
6
|
+
import { BaseComponent } from '../base.component';
|
|
7
|
+
import * as i0 from "@angular/core";
|
|
8
|
+
import * as i1 from "../../../providers/camera.provider";
|
|
9
|
+
import * as i2 from "../../../providers/layout.provider";
|
|
10
|
+
import * as i3 from "@angular/cdk/platform";
|
|
11
|
+
import * as i4 from "ngx-device-detector";
|
|
12
|
+
import * as i5 from "../../../providers/auth.provider";
|
|
13
|
+
import * as i6 from "@angular/common";
|
|
14
|
+
import * as i7 from "../webcam/webcam/webcam.component";
|
|
15
|
+
import * as i8 from "@angular/material/icon";
|
|
16
|
+
import * as i9 from "@angular/material/button";
|
|
17
|
+
import * as i10 from "@angular/material/progress-bar";
|
|
18
|
+
import * as i11 from "../scan-results/scan-results.component";
|
|
19
|
+
import * as i12 from "../manual-scan/manual-scan.component";
|
|
20
|
+
import * as i13 from "@ngx-translate/core";
|
|
21
|
+
export class ScanComponent extends BaseComponent {
|
|
22
|
+
get class() {
|
|
23
|
+
return this.isMobile;
|
|
24
|
+
}
|
|
25
|
+
onResize() {
|
|
26
|
+
if (this.result) {
|
|
27
|
+
this.cd.detectChanges();
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
constructor(cd, zone, cameraProvider, injector, layoutProvider, platform, deviceService, auth // private api: ServerProvider
|
|
31
|
+
) {
|
|
32
|
+
super();
|
|
33
|
+
this.cd = cd;
|
|
34
|
+
this.zone = zone;
|
|
35
|
+
this.cameraProvider = cameraProvider;
|
|
36
|
+
this.injector = injector;
|
|
37
|
+
this.layoutProvider = layoutProvider;
|
|
38
|
+
this.platform = platform;
|
|
39
|
+
this.deviceService = deviceService;
|
|
40
|
+
this.auth = auth;
|
|
41
|
+
this.scanBlastData = [
|
|
42
|
+
{
|
|
43
|
+
title: 'pms.dialogs.components.scanProfile.front',
|
|
44
|
+
description: 'pms.dialogs.components.scanProfile.frontDescription',
|
|
45
|
+
side: 'FRONT',
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
title: 'pms.dialogs.components.scanProfile.back',
|
|
49
|
+
description: 'pms.dialogs.components.scanProfile.backDescription',
|
|
50
|
+
disabled: true,
|
|
51
|
+
side: 'BACK',
|
|
52
|
+
},
|
|
53
|
+
];
|
|
54
|
+
this.type = 'desktop';
|
|
55
|
+
this.actions = new EventEmitter();
|
|
56
|
+
this.scanResults = new Subject();
|
|
57
|
+
this.scanSecondSide = false;
|
|
58
|
+
this.startTime = 0;
|
|
59
|
+
this.scanInProgress = false;
|
|
60
|
+
// webcam snapshot trigger
|
|
61
|
+
this.documentTypeSelected = false;
|
|
62
|
+
this.preview = null;
|
|
63
|
+
this.errorCode = '1000';
|
|
64
|
+
this.displayInfo = 'scandoc.info.position';
|
|
65
|
+
this.verificationErrorSent = false;
|
|
66
|
+
this.error = false;
|
|
67
|
+
this.cameraReady = false;
|
|
68
|
+
this.scaning = false;
|
|
69
|
+
this.promptManual = false;
|
|
70
|
+
this.imageHandler = new Subject();
|
|
71
|
+
this.manualDataSet = false;
|
|
72
|
+
this.logData = {
|
|
73
|
+
AcceptTermsAndConditions: true,
|
|
74
|
+
Request: null,
|
|
75
|
+
Response: null,
|
|
76
|
+
ExpectedOutput: null,
|
|
77
|
+
};
|
|
78
|
+
this.blurValues = [];
|
|
79
|
+
this.scanDatas = [];
|
|
80
|
+
this.idScan = null;
|
|
81
|
+
this.validation = false;
|
|
82
|
+
this.scannedImages = [];
|
|
83
|
+
this.scanDelay = 0;
|
|
84
|
+
this.trigger = new Subject();
|
|
85
|
+
// switch to next / previous / specific webcam; true/false: forward/backwards, string: deviceId
|
|
86
|
+
this.nextWebcam = new Subject();
|
|
87
|
+
this.imageVerified = false;
|
|
88
|
+
this.form = new FormGroup({});
|
|
89
|
+
this.manual = false;
|
|
90
|
+
this.isMobile = this.platform.IOS || this.platform.ANDROID;
|
|
91
|
+
this.showDialog = false;
|
|
92
|
+
this.scanImageTimestamps = {
|
|
93
|
+
time: 0,
|
|
94
|
+
load: 0,
|
|
95
|
+
};
|
|
96
|
+
this.numberOfValidations = 0;
|
|
97
|
+
this.validationDebug = [];
|
|
98
|
+
this.scanProvider = this.injector.get(ScanProvider);
|
|
99
|
+
if (!this.scanProvider.config.development) {
|
|
100
|
+
// console = {
|
|
101
|
+
// log: (...args: any) => {},
|
|
102
|
+
// time: (...args: any) => {},
|
|
103
|
+
// timeEnd: (...args: any) => {},
|
|
104
|
+
// warn: (...args: any) => {},
|
|
105
|
+
// error: (...args: any) => {},
|
|
106
|
+
// };
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
resetLogData() {
|
|
110
|
+
this.logData = {
|
|
111
|
+
Request: null,
|
|
112
|
+
Response: null,
|
|
113
|
+
ExpectedOutput: null,
|
|
114
|
+
AcceptTermsAndConditions: true,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
init() {
|
|
118
|
+
this.auth.accesToken.subscribe();
|
|
119
|
+
this.resetLogData();
|
|
120
|
+
// this.result=true;
|
|
121
|
+
// this.result ={};
|
|
122
|
+
console.log('INIT SCAN');
|
|
123
|
+
}
|
|
124
|
+
continue() {
|
|
125
|
+
this.documentTypeSelected = false;
|
|
126
|
+
setTimeout(() => {
|
|
127
|
+
this.selectedSide.image = this.webcamImage;
|
|
128
|
+
if (this.selectedSide.side === 'FRONT') {
|
|
129
|
+
this.scanBlastData[1].disabled = false;
|
|
130
|
+
}
|
|
131
|
+
this.cd.detectChanges();
|
|
132
|
+
}, 200);
|
|
133
|
+
}
|
|
134
|
+
scan() {
|
|
135
|
+
this.trigger.next(new Date().getTime());
|
|
136
|
+
}
|
|
137
|
+
handleImage(webcamImage) {
|
|
138
|
+
if (this.startTime === 0) {
|
|
139
|
+
this.startTime = Date.now();
|
|
140
|
+
}
|
|
141
|
+
// console.log('[received webcam image]', webcamImage);
|
|
142
|
+
this.zone.runOutsideAngular(() => {
|
|
143
|
+
const time = new Date().getTime();
|
|
144
|
+
if (this.scanImageTimestamps.load > 0) {
|
|
145
|
+
const { load } = this.scanImageTimestamps;
|
|
146
|
+
const diff = time - load;
|
|
147
|
+
// console.log('time:', diff);
|
|
148
|
+
this.scanDelay = diff;
|
|
149
|
+
}
|
|
150
|
+
this.scanImageTimestamps.load = time;
|
|
151
|
+
if (webcamImage.imageAsDataUrl) {
|
|
152
|
+
this.scannedImages.push(webcamImage);
|
|
153
|
+
}
|
|
154
|
+
this.cd.detectChanges();
|
|
155
|
+
if (this.scannedImages.length > 0 && !this.validation) {
|
|
156
|
+
// if (this.scanProvider.config.development) {
|
|
157
|
+
// this.scannedImages.forEach((img) => {
|
|
158
|
+
// const consoleBackground =
|
|
159
|
+
// "font-size:100px;background-image: url('" +
|
|
160
|
+
// img.imageResized +
|
|
161
|
+
// "');background-size: contain; background-repeat: no-repeat;";
|
|
162
|
+
// console.log('%c ', consoleBackground);
|
|
163
|
+
// });
|
|
164
|
+
// }
|
|
165
|
+
// this.frontImage = webcamImage.imageResized;
|
|
166
|
+
// console.timeEnd('scan');
|
|
167
|
+
// console.time('scan');
|
|
168
|
+
// get last 10
|
|
169
|
+
// console.log('CAPTURED:', this.scannedImages.length);
|
|
170
|
+
const images = this.scannedImages.slice(-5);
|
|
171
|
+
// set images to 0
|
|
172
|
+
this.scannedImages = [];
|
|
173
|
+
const imagesArray = images.map((m) => m.imageResized.split(',')[1]);
|
|
174
|
+
this.validation = true;
|
|
175
|
+
// console.log('BURST');
|
|
176
|
+
this.handleBurstData(imagesArray, images);
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
if (this.cameraReady) {
|
|
180
|
+
this.scan();
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
handleBurstData(imagesArray, images, type = 'plain') {
|
|
186
|
+
this.__subs(this.scanProvider.burst(imagesArray, this.blurValues)).subscribe((resp) => {
|
|
187
|
+
this.displayInfo = 'scandoc.info.c' + resp.InfoCode;
|
|
188
|
+
// console.timeEnd('validationPOST');
|
|
189
|
+
// console.log('AnalysisTime', resp.AnalysisTime);
|
|
190
|
+
const { DocType, Series, Side, InfoCode, TransactionID } = resp;
|
|
191
|
+
this.handleLongValidationError(TransactionID, images[0].imageAsDataUrl.split(',')[1]);
|
|
192
|
+
// if (InfoCode === '1006' && this.idScan) {
|
|
193
|
+
// this.handleLongVaylidationError(image);
|
|
194
|
+
// }
|
|
195
|
+
// console.warn(resp.Validated, this.numberOfValidations);
|
|
196
|
+
if (resp.DetectedBlurValue) {
|
|
197
|
+
this.blurValues.push(resp.DetectedBlurValue);
|
|
198
|
+
}
|
|
199
|
+
else {
|
|
200
|
+
this.blurValues = [];
|
|
201
|
+
}
|
|
202
|
+
console.log();
|
|
203
|
+
if (resp.Validated) {
|
|
204
|
+
this.numberOfValidations++;
|
|
205
|
+
this.validationDebug.push(resp);
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
this.numberOfValidations = 0;
|
|
209
|
+
this.validationDebug = [];
|
|
210
|
+
}
|
|
211
|
+
if (resp.Validated) {
|
|
212
|
+
this.displayInfo = '';
|
|
213
|
+
// console.log('[SCANNED INDEX]', resp.Index);
|
|
214
|
+
const selectedImage = images[resp.Index];
|
|
215
|
+
// this.preview = this.webcamImage.imageAsDataUrl;
|
|
216
|
+
this.cd.detectChanges();
|
|
217
|
+
let image = selectedImage;
|
|
218
|
+
console.warn(type);
|
|
219
|
+
if (type == 'worker') {
|
|
220
|
+
//const dataUrl = this.handleBitmapImage(selectedImage.bitmap);
|
|
221
|
+
image = selectedImage.imageAsDataUrl;
|
|
222
|
+
}
|
|
223
|
+
if (InfoCode === '1007') {
|
|
224
|
+
// For ID ask for other side
|
|
225
|
+
if (Side === 'FRONT') {
|
|
226
|
+
this.scanBlastData[0].image = image;
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
this.scanBlastData[1].image = image;
|
|
230
|
+
}
|
|
231
|
+
if (this.scanBlastData[0].image && this.scanBlastData[1].image) {
|
|
232
|
+
// console.warn('UPLOAD');
|
|
233
|
+
if (type == 'worker') {
|
|
234
|
+
this.imageHandler.next({ type: 'stop' });
|
|
235
|
+
}
|
|
236
|
+
//console.warn('DEBUG', Side, this.validationDebug);
|
|
237
|
+
this.scanBlastFinish();
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
this.blurValues = [];
|
|
241
|
+
this.numberOfValidations = 0;
|
|
242
|
+
// console.warn('DEBUG',Side,this.validationDebug)
|
|
243
|
+
this.validationDebug = [];
|
|
244
|
+
const num = Side === 'FRONT' ? 1 : 0;
|
|
245
|
+
this.scanSecondSide = true;
|
|
246
|
+
this.singleScan(this.scanBlastData[num]);
|
|
247
|
+
this.idScan = this.scanBlastData[num].side;
|
|
248
|
+
if (!this.showDialog) {
|
|
249
|
+
this.showDialog = true;
|
|
250
|
+
this.cd.detectChanges();
|
|
251
|
+
}
|
|
252
|
+
// reset manual scan popup interval
|
|
253
|
+
this.verificationErrorSent = false;
|
|
254
|
+
this.startTime = Date.now();
|
|
255
|
+
this.displayInfo = 'scandoc.info.turn';
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
259
|
+
// console.warn('DEBUG', Side, this.validationDebug);
|
|
260
|
+
this.scanBlastData[0].image = image;
|
|
261
|
+
// console.warn('UPLOAD');
|
|
262
|
+
if (type == 'worker') {
|
|
263
|
+
this.imageHandler.next({ type: 'stop' });
|
|
264
|
+
}
|
|
265
|
+
this.scanBlastFinish();
|
|
266
|
+
}
|
|
267
|
+
this.scannedImages = [];
|
|
268
|
+
// this.scanBlastData[0].image = selectedImage;
|
|
269
|
+
//this.scanBlastFinish();
|
|
270
|
+
}
|
|
271
|
+
else {
|
|
272
|
+
this.validation = false;
|
|
273
|
+
this.scan();
|
|
274
|
+
}
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
closeDialog() {
|
|
278
|
+
this.showDialog = false;
|
|
279
|
+
this.validation = false;
|
|
280
|
+
this.scan();
|
|
281
|
+
}
|
|
282
|
+
handleInitError(error) {
|
|
283
|
+
console.log(error);
|
|
284
|
+
}
|
|
285
|
+
get scanBlastCanUpload() {
|
|
286
|
+
return this.scanBlastData[0].image ? true : false;
|
|
287
|
+
}
|
|
288
|
+
manualMode(type = 'plain') {
|
|
289
|
+
this.manual = true;
|
|
290
|
+
this.promptManual = false;
|
|
291
|
+
this.scanInProgress = false;
|
|
292
|
+
this.cameraProvider.$showSwitch.next(false);
|
|
293
|
+
this.cd.detectChanges();
|
|
294
|
+
}
|
|
295
|
+
handleExtractionError(data) {
|
|
296
|
+
this.logData.ExpectedOutput = {};
|
|
297
|
+
// if (this.logData.ExpectedOutput?._avatar) {
|
|
298
|
+
// delete this.logData.ExpectedOutput._avatar;
|
|
299
|
+
// }
|
|
300
|
+
// this.scanProvider.sendLog(this.logData).subscribe();
|
|
301
|
+
// console.log('LOG DATA', this.logData);
|
|
302
|
+
// this.__subs(this.scanProvider.sendLog(this.logData)).subscribe();
|
|
303
|
+
}
|
|
304
|
+
sendErrorLog(TransactionID, image) {
|
|
305
|
+
const { browser, os, device } = this.deviceService;
|
|
306
|
+
const FrontImage = this.scanBlastData[0]?.image ? this.getImgBase64(0) : null;
|
|
307
|
+
const out = {
|
|
308
|
+
OS: os,
|
|
309
|
+
Device: device,
|
|
310
|
+
Browser: browser,
|
|
311
|
+
TransactionID,
|
|
312
|
+
AcceptTermsAndConditions: true,
|
|
313
|
+
FrontImage: FrontImage || image,
|
|
314
|
+
BackImage: FrontImage ? image : '',
|
|
315
|
+
};
|
|
316
|
+
console.log(out);
|
|
317
|
+
this.__subs(this.scanProvider.sendErrorLog(out)).subscribe();
|
|
318
|
+
}
|
|
319
|
+
handleLongValidationError(TransactionID, image) {
|
|
320
|
+
// save current image after 10sec
|
|
321
|
+
let MANUAL_INTERVAL = this.scanProvider.config.manualScanDelay;
|
|
322
|
+
const diff = (Date.now() - this.startTime) / 1000;
|
|
323
|
+
const showDialog = diff > MANUAL_INTERVAL;
|
|
324
|
+
if (showDialog && !this.verificationErrorSent) {
|
|
325
|
+
this.verificationErrorSent = true;
|
|
326
|
+
console.warn('[HANDLE ERROR]');
|
|
327
|
+
this.zone.run(() => {
|
|
328
|
+
// if (!this.scanSecondSide) {
|
|
329
|
+
if (this.scanProvider.config.manualModeEnabled) {
|
|
330
|
+
this.promptManual = true;
|
|
331
|
+
}
|
|
332
|
+
if (this.scanProvider.config.errorLogging) {
|
|
333
|
+
this.sendErrorLog(TransactionID, image);
|
|
334
|
+
}
|
|
335
|
+
// }
|
|
336
|
+
this.startTime = Date.now();
|
|
337
|
+
});
|
|
338
|
+
// this.verificationErrorSent = true;
|
|
339
|
+
// const dataUrl = this.handleBitmapImage(img.bitmap);
|
|
340
|
+
// console.warn('SENT');
|
|
341
|
+
// // this.displayInfo = 'Cant detect document!';
|
|
342
|
+
// this.logData.Request = this.__subs(
|
|
343
|
+
// this.scanProvider.sendLog({
|
|
344
|
+
// AcceptTermsAndConditions: true,
|
|
345
|
+
// ExpectedOutput: {},
|
|
346
|
+
// Request: {
|
|
347
|
+
// verification: dataUrl.split(',')[1],
|
|
348
|
+
// },
|
|
349
|
+
// Response: {
|
|
350
|
+
// TransactionID: uuidv4(),
|
|
351
|
+
// },
|
|
352
|
+
// })
|
|
353
|
+
// ).subscribe();
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
ngAfterViewInit() {
|
|
357
|
+
// this.result = true;
|
|
358
|
+
this.cameraProvider.$showSwitch.next(true);
|
|
359
|
+
this.cd.detectChanges();
|
|
360
|
+
// this.scanResults.next({ type: 'model', data: {} });
|
|
361
|
+
this.__subs(this.cameraProvider.webcamObservable).subscribe((resp) => {
|
|
362
|
+
this.cameraReady = false;
|
|
363
|
+
this.scanInProgress = false;
|
|
364
|
+
this.scannedImages = [];
|
|
365
|
+
});
|
|
366
|
+
this.__subs(this.cameraProvider.selfie$).subscribe((resp) => {
|
|
367
|
+
this.selfie();
|
|
368
|
+
});
|
|
369
|
+
this.autoScan();
|
|
370
|
+
this.__subs(this.layoutProvider.breakpoint$).subscribe((v) => {
|
|
371
|
+
this.isMobile = !v.matches || this.platform.IOS || this.platform.ANDROID;
|
|
372
|
+
console.log('MNOBILE', this.isMobile);
|
|
373
|
+
});
|
|
374
|
+
}
|
|
375
|
+
handleBitmapImage(bitmap) {
|
|
376
|
+
const { width, height } = bitmap;
|
|
377
|
+
const offscreenSmall = document.createElement('canvas');
|
|
378
|
+
offscreenSmall.width = width;
|
|
379
|
+
offscreenSmall.height = height;
|
|
380
|
+
const ctx = offscreenSmall.getContext('bitmaprenderer');
|
|
381
|
+
if (ctx) {
|
|
382
|
+
ctx.imageSmoothingEnabled = false;
|
|
383
|
+
ctx.transferFromImageBitmap(bitmap);
|
|
384
|
+
bitmap.close();
|
|
385
|
+
const data = ctx.canvas.toDataURL('image/jpeg');
|
|
386
|
+
return data;
|
|
387
|
+
}
|
|
388
|
+
return null;
|
|
389
|
+
}
|
|
390
|
+
autoScan() {
|
|
391
|
+
const side = this.scanBlastData[0];
|
|
392
|
+
this.idScan = null;
|
|
393
|
+
this.singleScan(side);
|
|
394
|
+
}
|
|
395
|
+
singleScan(side) {
|
|
396
|
+
this.scanType = side.side;
|
|
397
|
+
this.preview = null;
|
|
398
|
+
this.selectedSide = side;
|
|
399
|
+
this.selectedSide.image = null;
|
|
400
|
+
this.documentTypeSelected = true;
|
|
401
|
+
this.scanBlastData[1].disabled = false;
|
|
402
|
+
this.cd.detectChanges();
|
|
403
|
+
}
|
|
404
|
+
manualScanData(data) {
|
|
405
|
+
console.log(data);
|
|
406
|
+
this.scanBlastData = data;
|
|
407
|
+
this.manual = false;
|
|
408
|
+
this.manualDataSet = true;
|
|
409
|
+
this.scanBlastFinish();
|
|
410
|
+
}
|
|
411
|
+
getImgBase64(num) {
|
|
412
|
+
console.log('GET 64');
|
|
413
|
+
// if (this.manualDataSet) {
|
|
414
|
+
return this.scanBlastData[num].image._imageAsDataUrl.split(',')[1];
|
|
415
|
+
// }
|
|
416
|
+
// return this.scanBlastData[num].image.dataUrl.split(',')[1];
|
|
417
|
+
}
|
|
418
|
+
scanBlastFinish() {
|
|
419
|
+
const { browser, os, device } = this.deviceService;
|
|
420
|
+
this.zone.run(() => {
|
|
421
|
+
this.cameraProvider.$showSwitch.next(false);
|
|
422
|
+
});
|
|
423
|
+
console.time('upload');
|
|
424
|
+
if (this.type === 'mobile') {
|
|
425
|
+
this.actions.emit({ data: this.scanBlastData });
|
|
426
|
+
this.retake();
|
|
427
|
+
return;
|
|
428
|
+
}
|
|
429
|
+
this.idScan = null;
|
|
430
|
+
// const loading = this.dialogs.loading();
|
|
431
|
+
this.scaning = true;
|
|
432
|
+
this.cd.detectChanges();
|
|
433
|
+
console.time('payload');
|
|
434
|
+
const payload = {
|
|
435
|
+
AcceptTermsAndConditions: true,
|
|
436
|
+
DataFields: {
|
|
437
|
+
DeviceInfo: {
|
|
438
|
+
OS: os,
|
|
439
|
+
Device: device,
|
|
440
|
+
Browser: browser,
|
|
441
|
+
},
|
|
442
|
+
FrontImageType: 'base64',
|
|
443
|
+
FrontImageCropped: false,
|
|
444
|
+
BackImageType: 'base64',
|
|
445
|
+
BackImageCropped: false,
|
|
446
|
+
FrontImage: this.getImgBase64(0),
|
|
447
|
+
BackImage: this.scanBlastData[1].image ? this.getImgBase64(1) : null,
|
|
448
|
+
},
|
|
449
|
+
Settings: {
|
|
450
|
+
ShouldValidate: true,
|
|
451
|
+
ShouldReturnDocumentImage: true,
|
|
452
|
+
ShouldReturnFaceIfDetected: true,
|
|
453
|
+
SkipImageSizeCheck: true,
|
|
454
|
+
CanStoreImages: this.scanProvider.canStoreImages,
|
|
455
|
+
},
|
|
456
|
+
// CallBackUrl: 'http://demo:5000/report/extracted/',
|
|
457
|
+
};
|
|
458
|
+
this.frontImage = 'data:image/jpeg;base64,' + payload.DataFields.FrontImage;
|
|
459
|
+
this.backImage = 'data:image/jpeg;base64,' + payload.DataFields.BackImage;
|
|
460
|
+
if (!this.scanBlastData[1].image) {
|
|
461
|
+
payload.Settings.IgnoreBackImage = true;
|
|
462
|
+
}
|
|
463
|
+
this.logData.Request = JSON.parse(JSON.stringify(payload));
|
|
464
|
+
console.timeEnd('payload');
|
|
465
|
+
this.__subs(this.scanProvider.blastPost(payload).pipe(catchError((e) => {
|
|
466
|
+
if (this.manualDataSet) {
|
|
467
|
+
// console.warn('MANUAL DATA SET',e);
|
|
468
|
+
this.logData.Response = JSON.parse(JSON.stringify(e.error));
|
|
469
|
+
this.handleExtractionError({});
|
|
470
|
+
}
|
|
471
|
+
this.zone.run(() => {
|
|
472
|
+
this.error = true;
|
|
473
|
+
this.preview = true;
|
|
474
|
+
this.cd.detectChanges();
|
|
475
|
+
});
|
|
476
|
+
// console.log('EEE', e);
|
|
477
|
+
return e;
|
|
478
|
+
}))).subscribe((data) => {
|
|
479
|
+
//console.log(data);
|
|
480
|
+
const results = data.Data;
|
|
481
|
+
console.timeEnd('upload');
|
|
482
|
+
console.time('parse');
|
|
483
|
+
// data.InfoCode = '1001';
|
|
484
|
+
console.time('p');
|
|
485
|
+
this.logData.Response = JSON.parse(JSON.stringify(data));
|
|
486
|
+
console.timeEnd('p');
|
|
487
|
+
//loading.close();
|
|
488
|
+
this.documentTypeSelected = true;
|
|
489
|
+
this.scaning = false;
|
|
490
|
+
if (data.InfoCode === '1001') {
|
|
491
|
+
this.error = true;
|
|
492
|
+
console.log('[ERROR] 1001');
|
|
493
|
+
this.errorCode = '1001';
|
|
494
|
+
// this.scanSide = 0;
|
|
495
|
+
this.preview = true;
|
|
496
|
+
this.cd.detectChanges();
|
|
497
|
+
return;
|
|
498
|
+
}
|
|
499
|
+
if (data.InfoCode === '1002') {
|
|
500
|
+
this.error = true;
|
|
501
|
+
console.log('[ERROR] 1002');
|
|
502
|
+
this.errorCode = '1002';
|
|
503
|
+
// this.scanSide = 0;
|
|
504
|
+
this.preview = true;
|
|
505
|
+
this.cd.detectChanges();
|
|
506
|
+
return;
|
|
507
|
+
}
|
|
508
|
+
if (results && data.Metadata.length > 0 && data.InfoCode === '1000') {
|
|
509
|
+
// console.log('Extraction time', data.AnalysisTime);
|
|
510
|
+
// this.zone.run(() => {
|
|
511
|
+
// console.time('parseblast');
|
|
512
|
+
const result = this.scanProvider.parseBlast(results);
|
|
513
|
+
// console.timeEnd('parseblast');
|
|
514
|
+
// console.log('RES', this.result);
|
|
515
|
+
// this.cd.detectChanges();
|
|
516
|
+
const model = result.model;
|
|
517
|
+
if (data.ImageData?.FaceImage) {
|
|
518
|
+
model._avatar =
|
|
519
|
+
'data:image/jpeg;base64,' + data.ImageData?.FaceImage;
|
|
520
|
+
}
|
|
521
|
+
if (data.ImageData?.Documents) {
|
|
522
|
+
const { Documents } = data.ImageData;
|
|
523
|
+
model.images = Documents.map((image, i) => {
|
|
524
|
+
return { data: 'data:image/jpeg;base64,' + Documents[i] };
|
|
525
|
+
});
|
|
526
|
+
}
|
|
527
|
+
this.model = model;
|
|
528
|
+
// console.log('MODEL', this.model);
|
|
529
|
+
this.actions.emit({
|
|
530
|
+
type: 'scanFinish',
|
|
531
|
+
data: {
|
|
532
|
+
model: this.model,
|
|
533
|
+
images: this.images,
|
|
534
|
+
results,
|
|
535
|
+
},
|
|
536
|
+
});
|
|
537
|
+
if (!this.scanProvider.config.hideResults) {
|
|
538
|
+
this.zone.run(() => {
|
|
539
|
+
this.result = true;
|
|
540
|
+
// console.time('ff');
|
|
541
|
+
this.cd.detectChanges();
|
|
542
|
+
this.scanResults.next({ type: 'model', data: model });
|
|
543
|
+
// this.cd.detectChanges();
|
|
544
|
+
// });
|
|
545
|
+
// console.timeEnd('ff');
|
|
546
|
+
});
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
else {
|
|
550
|
+
console.log('ERROR');
|
|
551
|
+
if (this.manualDataSet) {
|
|
552
|
+
this.handleExtractionError(data);
|
|
553
|
+
}
|
|
554
|
+
// this.scanSide = 0;
|
|
555
|
+
this.zone.run(() => {
|
|
556
|
+
this.error = true;
|
|
557
|
+
this.preview = true;
|
|
558
|
+
this.cd.detectChanges();
|
|
559
|
+
});
|
|
560
|
+
// this.documentTypeSelected = false;
|
|
561
|
+
// this.retry();
|
|
562
|
+
}
|
|
563
|
+
// this.cd.detectChanges();
|
|
564
|
+
console.timeEnd('parse');
|
|
565
|
+
}, (err) => {
|
|
566
|
+
// loading.close();
|
|
567
|
+
// this.scanSide = 0;
|
|
568
|
+
this.error = true;
|
|
569
|
+
this.preview = true;
|
|
570
|
+
this.documentTypeSelected = true;
|
|
571
|
+
this.scaning = false;
|
|
572
|
+
});
|
|
573
|
+
}
|
|
574
|
+
retry() {
|
|
575
|
+
this.preview = false;
|
|
576
|
+
this.validation = false;
|
|
577
|
+
this.errorCode = '1000';
|
|
578
|
+
this.result = false;
|
|
579
|
+
this.idScan = null;
|
|
580
|
+
this.cameraProvider.$showSwitch.next(true);
|
|
581
|
+
if (this.error) {
|
|
582
|
+
this.documentTypeSelected = false;
|
|
583
|
+
this.scanBlastData.forEach((element) => {
|
|
584
|
+
element.image = null;
|
|
585
|
+
});
|
|
586
|
+
}
|
|
587
|
+
this.error = false;
|
|
588
|
+
this.startTime = Date.now();
|
|
589
|
+
this.autoScan();
|
|
590
|
+
this.scan();
|
|
591
|
+
this.cd.detectChanges();
|
|
592
|
+
}
|
|
593
|
+
retake() {
|
|
594
|
+
this.validation = false;
|
|
595
|
+
this.preview = false;
|
|
596
|
+
this.error = false;
|
|
597
|
+
this.result = false;
|
|
598
|
+
this.scanSide = 0;
|
|
599
|
+
this.cameraProvider.$showSwitch.next(true);
|
|
600
|
+
this.imageVerified = false;
|
|
601
|
+
this.scanDatas = [];
|
|
602
|
+
this.scaning = false;
|
|
603
|
+
this.images = [];
|
|
604
|
+
this.scanInProgress = false;
|
|
605
|
+
this.startTime = Date.now();
|
|
606
|
+
this.idScan = null;
|
|
607
|
+
this.documentTypeSelected = false;
|
|
608
|
+
this.scanBlastData.forEach((m) => {
|
|
609
|
+
m.image = null;
|
|
610
|
+
});
|
|
611
|
+
this.scanSecondSide = false;
|
|
612
|
+
this.autoScan();
|
|
613
|
+
this.cd.detectChanges();
|
|
614
|
+
}
|
|
615
|
+
use() {
|
|
616
|
+
// save images??
|
|
617
|
+
// if (this.scanProvider.config.sendLog) {
|
|
618
|
+
// this.logData.ExpectedOutput = JSON.parse(JSON.stringify(this.model));
|
|
619
|
+
// if (this.logData.ExpectedOutput?._avatar) {
|
|
620
|
+
// delete this.logData.ExpectedOutput._avatar;
|
|
621
|
+
// }
|
|
622
|
+
// // this.__subs(this.scanProvider.sendLog(this.logData)).subscribe();
|
|
623
|
+
// console.log(this.logData);
|
|
624
|
+
// }
|
|
625
|
+
this.actions.emit({
|
|
626
|
+
type: 'scanDataClose',
|
|
627
|
+
data: {
|
|
628
|
+
model: this.model,
|
|
629
|
+
images: this.images,
|
|
630
|
+
},
|
|
631
|
+
});
|
|
632
|
+
}
|
|
633
|
+
selfie() {
|
|
634
|
+
const avatar = this.model?._avatar;
|
|
635
|
+
this.dialogs
|
|
636
|
+
.scanSelfie({ avatar })
|
|
637
|
+
.afterClosed()
|
|
638
|
+
.subscribe((resp) => {
|
|
639
|
+
if (resp) {
|
|
640
|
+
console.log(resp);
|
|
641
|
+
if (this.scanProvider.enableVerification) {
|
|
642
|
+
this.imageVerified = true;
|
|
643
|
+
}
|
|
644
|
+
this.scanResults.next({
|
|
645
|
+
type: 'avatar',
|
|
646
|
+
data: resp.imageAsDataUrl,
|
|
647
|
+
});
|
|
648
|
+
// this.model._avatar = resp.imageAsDataUrl;
|
|
649
|
+
this.cd.detectChanges();
|
|
650
|
+
}
|
|
651
|
+
});
|
|
652
|
+
}
|
|
653
|
+
cameraOff(ev) {
|
|
654
|
+
this.cameraReady = false;
|
|
655
|
+
this.cd.detectChanges();
|
|
656
|
+
}
|
|
657
|
+
videoReady(event) {
|
|
658
|
+
console.log('READY', event);
|
|
659
|
+
this.cameraReady = event;
|
|
660
|
+
if (this.cameraReady && !this.scanInProgress && !this.manual) {
|
|
661
|
+
this.scanInProgress = true;
|
|
662
|
+
setTimeout(() => {
|
|
663
|
+
this.scan();
|
|
664
|
+
}, 20);
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
manualSet(key) {
|
|
668
|
+
if (key) {
|
|
669
|
+
if (this.scanProvider.config.showManualMode) {
|
|
670
|
+
this.manualMode();
|
|
671
|
+
}
|
|
672
|
+
else {
|
|
673
|
+
this.actions.emit({
|
|
674
|
+
type: 'manualMode',
|
|
675
|
+
data: {},
|
|
676
|
+
});
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
else {
|
|
680
|
+
this.promptManual = false;
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
ngOnDestroy() {
|
|
684
|
+
if (this.scanTimeout) {
|
|
685
|
+
clearTimeout(this.scanTimeout);
|
|
686
|
+
}
|
|
687
|
+
if (this.imageHandlerSubscription) {
|
|
688
|
+
this.imageHandlerSubscription.unsubscribe();
|
|
689
|
+
}
|
|
690
|
+
console.log('DESTROXY');
|
|
691
|
+
this.__destroy();
|
|
692
|
+
}
|
|
693
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ScanComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.NgZone }, { token: i1.NgxScandocCameraProvider }, { token: i0.Injector }, { token: i2.LayoutProvider }, { token: i3.Platform }, { token: i4.DeviceDetectorService }, { token: i5.NgxScandocAuthProvider }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
694
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: ScanComponent, selector: "ngx-scan", inputs: { type: "type", dialogs: "dialogs", showDialog: "showDialog" }, outputs: { actions: "actions" }, host: { listeners: { "window:resize": "onResize($event)" }, properties: { "class.mobile": "this.class" } }, usesInheritance: true, ngImport: i0, template: "<ng-container\n *ngIf=\"cameraProvider.rectPosition.t > 0 && displayInfo && !result && !manual\"\n>\n <div class=\"hint\" [ngStyle]=\"{ top: cameraProvider.hintPosition + 'px' }\">\n <span class=\"text\">\n {{ displayInfo | translate }}\n </span>\n </div>\n</ng-container>\n\n<ng-container *ngIf=\"showDialog\">\n <div class=\"pageTurn\">\n <div class=\"content\">\n <div class=\"inner\">\n <mat-icon>360</mat-icon>\n <div class=\"text\">\n <ng-container *ngIf=\"idScan === 'BACK'\">\n {{ \"scandoc.turnAndCapture.back\" | translate }}\n </ng-container>\n <ng-container *ngIf=\"idScan === 'FRONT'\">\n {{ \"scandoc.turnAndCapture.front\" | translate }}\n </ng-container>\n </div>\n </div>\n <footer>\n <button (click)=\"closeDialog()\" mat-raised-button>Ok</button>\n </footer>\n </div>\n </div>\n</ng-container>\n\n<ng-container *ngIf=\"promptManual\">\n <div class=\"manualMode\">\n <div class=\"content\">\n <div class=\"inner\">\n <mat-icon>screenshot</mat-icon>\n <div class=\"text\">\n {{ \"scandoc.manual\" | translate }}\n </div>\n </div>\n <footer>\n <button\n style=\"margin-right: 8px\"\n (click)=\"manualSet(true)\"\n mat-raised-button\n >\n {{ \"scandoc.yes\" | translate }}\n </button>\n <button\n style=\"margin-left: 8px\"\n (click)=\"manualSet(false)\"\n mat-raised-button\n >\n {{ \"scandoc.no\" | translate }}\n </button>\n </footer>\n </div>\n </div>\n</ng-container>\n<ng-container *ngIf=\"result\">\n <section>\n <ngx-scan-results\n (action)=\"selfie()\"\n [form]=\"form\"\n [data]=\"scanResults\"\n ></ngx-scan-results>\n\n <footer>\n <div class=\"actions\">\n <button class=\"mr-4\" mat-raised-button (click)=\"retake()\">\n {{ \"scandoc.reTake\" | translate }}\n </button>\n <button\n [disabled]=\"error || form.invalid\"\n class=\"ml-4\"\n mat-raised-button\n (click)=\"use()\"\n >\n {{ \"scandoc.useData\" | translate }}\n </button>\n </div>\n </footer>\n </section>\n</ng-container>\n\n<ng-container *ngIf=\"manual\">\n <section>\n <ngx-manual-scan (action)=\"manualScanData($event)\"></ngx-manual-scan>\n </section>\n</ng-container>\n<ng-container *ngIf=\"!result && documentTypeSelected && !manual\">\n <section>\n <div #wraper class=\"wraper\">\n <div class=\"loading\" *ngIf=\"(!cameraReady && !preview) || scaning\">\n <mat-progress-bar mode=\"indeterminate\"></mat-progress-bar>\n </div>\n\n <ng-container *ngIf=\"!error\">\n <ngx-scandoc-webcam\n *ngIf=\"!preview && !scaning\"\n class=\"main\"\n #webcam\n type=\"document\"\n [trigger]=\"trigger\"\n [imageHandler]=\"imageHandler\"\n (imageCapture)=\"handleImage($event)\"\n (initError)=\"handleInitError($event)\"\n (destroyed)=\"cameraOff($event)\"\n (videoReady)=\"videoReady($event)\"\n >\n </ngx-scandoc-webcam>\n </ng-container>\n <div\n class=\"previewData\"\n *ngIf=\"preview\"\n style=\"\n z-index: 20;\n display: flex;\n position: absolute;\n width: 100%;\n height: 100%;\n \"\n >\n <div class=\"p-16 error\" *ngIf=\"error\">\n <div>\n <div class=\"title\">\n <mat-icon>error_outline</mat-icon\n ><span class=\"ml-8\">{{\n \"scandoc.unableToDetectId\" | translate\n }}</span>\n </div>\n\n <ng-container *ngIf=\"errorCode === '1001'\">\n <div>\n {{ \"scandoc.extraction.c1001\" | translate }}\n </div>\n </ng-container>\n <ng-container *ngIf=\"errorCode === '1002'\">\n <div>\n {{ \"scandoc.extraction.c1002\" | translate }}\n </div>\n </ng-container>\n\n <ul *ngIf=\"errorCode === '1000'\">\n <li>\n {{ \"scandoc.placeIdCloseToDevice\" | translate }}\n </li>\n <li>\n {{ \"scandoc.ensureSufficientLight\" | translate }}\n </li>\n <li>\n {{ \"scandoc.holdDocumentSteady\" | translate }}\n </li>\n <li>\n {{ \"scandoc.makeSureAllEdgesOfTheIdAreVisible\" | translate }}\n </li>\n <li>\n {{\n \"scandoc.makeSureThereAreNoGlareAndShadowsOnTheId\" | translate\n }}\n </li>\n </ul>\n </div>\n </div>\n\n <div class=\"scanPreview\" *ngIf=\"!error && !scaning\">\n <!-- <div class=\"py-16\" style=\"font-size: 16px\">\n {{\n \"scandoc.ensureAllTextsAreVisible\"\n | translate\n }}\n </div> -->\n <div\n class=\"image\"\n [style.background-image]=\"'url(' + preview + ')'\"\n ></div>\n </div>\n </div>\n </div>\n\n <footer *ngIf=\"preview\">\n <!-- <div class=\"displayInfo\" *ngIf=\"!preview && cameraReady\">\n <ng-container *ngIf=\"displayInfo\">\n {{ displayInfo | translate }}\n </ng-container>\n </div> -->\n <!-- <div style=\"height: 26px\">\n <div\n style=\"text-align: center; font-size: 18px\"\n *ngIf=\"idScan && !preview && cameraReady\"\n >\n <ng-container *ngIf=\"idScan === 'BACK'\">\n Turn document and:\n {{ \"scandoc.captureBack\" | translate }}\n </ng-container>\n <ng-container *ngIf=\"idScan === 'FRONT'\">\n Turn document and:\n {{ \"scandoc.captureFront\" | translate }}\n </ng-container>\n </div>\n </div> -->\n\n <div class=\"actions\" *ngIf=\"preview\">\n <button class=\"mr-4\" mat-raised-button (click)=\"retry()\">\n {{ \"scandoc.retry\" | translate }}\n </button>\n\n <button\n [disabled]=\"error\"\n class=\"ml-4\"\n mat-raised-button\n (click)=\"continue()\"\n >\n {{ \"scandoc.continueWithSelectedImage\" | translate }}\n </button>\n </div>\n </footer>\n </section>\n</ng-container>\n", styles: [":host{display:flex;flex-direction:column!important;flex:1;background-color:#f5f5f5;overflow:hidden;position:relative}:host.mobile .hint{font-size:13px}section{flex:1;display:flex;flex-direction:column;position:relative;overflow:hidden}.wraper{position:relative;overflow:hidden;display:flex;flex-direction:column;flex:1}.wraper .loading{position:absolute;inset:0;z-index:20;background-color:#f5f5f5}.documentTurnOver{position:absolute;width:100%;height:100%;top:0;left:0;display:flex;flex-direction:column;align-items:center;justify-content:center}.documentTurnOver mat-icon{width:200px;color:#fff;height:200px;font-size:100px}.displayInfo{text-align:center;flex:1;width:100%;background-color:#000;height:50px;display:flex;flex-direction:row;align-items:center;justify-content:center;color:#fff;z-index:200}.displayInfo.mobile{font-size:12px}.preview{width:100%;border-radius:1%}footer button{box-shadow:none!important;height:45px;min-height:45px;text-transform:uppercase}footer .actions{display:flex;flex-direction:row;align-items:center;padding:8px}footer .actions button{flex:1}.error{display:flex;align-items:center;justify-content:center;flex:1}.error .title{font-size:20px;margin-bottom:8px}.error .title mat-icon{margin-right:8px}.error ul{font-size:18px;list-style-type:none}mat-card{box-shadow:none!important}.mr-4{margin-right:4px}.ml-4{margin-left:4px}.p-16{padding:16px}.p-8{padding:8px}.py-16{padding:16px 0}.w-100-p{width:100%}.scanPreview{padding:16px}.scanPreview .image{background-position:center;background-repeat:no-repeat;background-size:contain}.empty{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center}.manualMode{position:absolute;width:100%;height:100%;z-index:200;top:0;left:0;display:flex;flex-direction:column;align-items:center;justify-content:center}.manualMode .content{margin-top:20px;background-color:#fff;border-radius:6px;max-width:300px;width:100%;display:flex;flex-direction:column;padding:30px 20px 0}.manualMode .inner{display:flex;flex-direction:column;align-items:center;justify-content:center;font-size:14px}.manualMode .inner mat-icon{width:60px;height:60px;font-size:60px}.manualMode .inner .text{margin:20px 0}.manualMode footer{display:flex;flex-direction:row;align-items:center;justify-content:center;padding-bottom:20px}.manualMode footer button{min-width:140px;box-shadow:none;border:1px solid #ccc}.pageTurn{position:absolute;width:100%;height:100%;z-index:200;top:0;left:0;display:flex;flex-direction:column;align-items:center;justify-content:center}.pageTurn .content{background-color:#fff;border-radius:6px;max-width:300px;width:100%;display:flex;flex-direction:column;padding:30px 20px 0}.pageTurn .inner{display:flex;flex-direction:column;align-items:center;justify-content:center}.pageTurn .inner mat-icon{width:60px;height:60px;font-size:60px}.pageTurn .inner .text{margin:20px 0;font-size:14px}.pageTurn footer{display:flex;flex-direction:row;align-items:center;justify-content:center;padding-bottom:20px}.pageTurn footer button{min-width:200px;box-shadow:none;border:1px solid #ccc}.hint{position:absolute;z-index:5;font-size:18px;line-height:18px;display:flex;flex-direction:row;align-items:center;justify-content:center;width:100%}.hint .text{border-radius:3px;padding:4px 8px;background-color:#000;color:#fff;text-align:center;display:inline;-webkit-box-decoration-break:clone;box-decoration-break:clone}\n"], dependencies: [{ kind: "directive", type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i6.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i7.WebcamComponent, selector: "ngx-scandoc-webcam", inputs: ["imageHandler", "type", "trigger"], outputs: ["cameraSwitched", "videoReady", "imageCapture", "initError"] }, { kind: "component", type: i8.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i9.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i10.MatProgressBar, selector: "mat-progress-bar", inputs: ["color", "value", "bufferValue", "mode"], outputs: ["animationEnd"], exportAs: ["matProgressBar"] }, { kind: "component", type: i11.ScanResultsComponent, selector: "ngx-scan-results", inputs: ["data", "images", "form"], outputs: ["action"] }, { kind: "component", type: i12.ManualScanComponent, selector: "ngx-manual-scan", outputs: ["action"] }, { kind: "pipe", type: i13.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
695
|
+
}
|
|
696
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: ScanComponent, decorators: [{
|
|
697
|
+
type: Component,
|
|
698
|
+
args: [{ selector: 'ngx-scan', changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container\n *ngIf=\"cameraProvider.rectPosition.t > 0 && displayInfo && !result && !manual\"\n>\n <div class=\"hint\" [ngStyle]=\"{ top: cameraProvider.hintPosition + 'px' }\">\n <span class=\"text\">\n {{ displayInfo | translate }}\n </span>\n </div>\n</ng-container>\n\n<ng-container *ngIf=\"showDialog\">\n <div class=\"pageTurn\">\n <div class=\"content\">\n <div class=\"inner\">\n <mat-icon>360</mat-icon>\n <div class=\"text\">\n <ng-container *ngIf=\"idScan === 'BACK'\">\n {{ \"scandoc.turnAndCapture.back\" | translate }}\n </ng-container>\n <ng-container *ngIf=\"idScan === 'FRONT'\">\n {{ \"scandoc.turnAndCapture.front\" | translate }}\n </ng-container>\n </div>\n </div>\n <footer>\n <button (click)=\"closeDialog()\" mat-raised-button>Ok</button>\n </footer>\n </div>\n </div>\n</ng-container>\n\n<ng-container *ngIf=\"promptManual\">\n <div class=\"manualMode\">\n <div class=\"content\">\n <div class=\"inner\">\n <mat-icon>screenshot</mat-icon>\n <div class=\"text\">\n {{ \"scandoc.manual\" | translate }}\n </div>\n </div>\n <footer>\n <button\n style=\"margin-right: 8px\"\n (click)=\"manualSet(true)\"\n mat-raised-button\n >\n {{ \"scandoc.yes\" | translate }}\n </button>\n <button\n style=\"margin-left: 8px\"\n (click)=\"manualSet(false)\"\n mat-raised-button\n >\n {{ \"scandoc.no\" | translate }}\n </button>\n </footer>\n </div>\n </div>\n</ng-container>\n<ng-container *ngIf=\"result\">\n <section>\n <ngx-scan-results\n (action)=\"selfie()\"\n [form]=\"form\"\n [data]=\"scanResults\"\n ></ngx-scan-results>\n\n <footer>\n <div class=\"actions\">\n <button class=\"mr-4\" mat-raised-button (click)=\"retake()\">\n {{ \"scandoc.reTake\" | translate }}\n </button>\n <button\n [disabled]=\"error || form.invalid\"\n class=\"ml-4\"\n mat-raised-button\n (click)=\"use()\"\n >\n {{ \"scandoc.useData\" | translate }}\n </button>\n </div>\n </footer>\n </section>\n</ng-container>\n\n<ng-container *ngIf=\"manual\">\n <section>\n <ngx-manual-scan (action)=\"manualScanData($event)\"></ngx-manual-scan>\n </section>\n</ng-container>\n<ng-container *ngIf=\"!result && documentTypeSelected && !manual\">\n <section>\n <div #wraper class=\"wraper\">\n <div class=\"loading\" *ngIf=\"(!cameraReady && !preview) || scaning\">\n <mat-progress-bar mode=\"indeterminate\"></mat-progress-bar>\n </div>\n\n <ng-container *ngIf=\"!error\">\n <ngx-scandoc-webcam\n *ngIf=\"!preview && !scaning\"\n class=\"main\"\n #webcam\n type=\"document\"\n [trigger]=\"trigger\"\n [imageHandler]=\"imageHandler\"\n (imageCapture)=\"handleImage($event)\"\n (initError)=\"handleInitError($event)\"\n (destroyed)=\"cameraOff($event)\"\n (videoReady)=\"videoReady($event)\"\n >\n </ngx-scandoc-webcam>\n </ng-container>\n <div\n class=\"previewData\"\n *ngIf=\"preview\"\n style=\"\n z-index: 20;\n display: flex;\n position: absolute;\n width: 100%;\n height: 100%;\n \"\n >\n <div class=\"p-16 error\" *ngIf=\"error\">\n <div>\n <div class=\"title\">\n <mat-icon>error_outline</mat-icon\n ><span class=\"ml-8\">{{\n \"scandoc.unableToDetectId\" | translate\n }}</span>\n </div>\n\n <ng-container *ngIf=\"errorCode === '1001'\">\n <div>\n {{ \"scandoc.extraction.c1001\" | translate }}\n </div>\n </ng-container>\n <ng-container *ngIf=\"errorCode === '1002'\">\n <div>\n {{ \"scandoc.extraction.c1002\" | translate }}\n </div>\n </ng-container>\n\n <ul *ngIf=\"errorCode === '1000'\">\n <li>\n {{ \"scandoc.placeIdCloseToDevice\" | translate }}\n </li>\n <li>\n {{ \"scandoc.ensureSufficientLight\" | translate }}\n </li>\n <li>\n {{ \"scandoc.holdDocumentSteady\" | translate }}\n </li>\n <li>\n {{ \"scandoc.makeSureAllEdgesOfTheIdAreVisible\" | translate }}\n </li>\n <li>\n {{\n \"scandoc.makeSureThereAreNoGlareAndShadowsOnTheId\" | translate\n }}\n </li>\n </ul>\n </div>\n </div>\n\n <div class=\"scanPreview\" *ngIf=\"!error && !scaning\">\n <!-- <div class=\"py-16\" style=\"font-size: 16px\">\n {{\n \"scandoc.ensureAllTextsAreVisible\"\n | translate\n }}\n </div> -->\n <div\n class=\"image\"\n [style.background-image]=\"'url(' + preview + ')'\"\n ></div>\n </div>\n </div>\n </div>\n\n <footer *ngIf=\"preview\">\n <!-- <div class=\"displayInfo\" *ngIf=\"!preview && cameraReady\">\n <ng-container *ngIf=\"displayInfo\">\n {{ displayInfo | translate }}\n </ng-container>\n </div> -->\n <!-- <div style=\"height: 26px\">\n <div\n style=\"text-align: center; font-size: 18px\"\n *ngIf=\"idScan && !preview && cameraReady\"\n >\n <ng-container *ngIf=\"idScan === 'BACK'\">\n Turn document and:\n {{ \"scandoc.captureBack\" | translate }}\n </ng-container>\n <ng-container *ngIf=\"idScan === 'FRONT'\">\n Turn document and:\n {{ \"scandoc.captureFront\" | translate }}\n </ng-container>\n </div>\n </div> -->\n\n <div class=\"actions\" *ngIf=\"preview\">\n <button class=\"mr-4\" mat-raised-button (click)=\"retry()\">\n {{ \"scandoc.retry\" | translate }}\n </button>\n\n <button\n [disabled]=\"error\"\n class=\"ml-4\"\n mat-raised-button\n (click)=\"continue()\"\n >\n {{ \"scandoc.continueWithSelectedImage\" | translate }}\n </button>\n </div>\n </footer>\n </section>\n</ng-container>\n", styles: [":host{display:flex;flex-direction:column!important;flex:1;background-color:#f5f5f5;overflow:hidden;position:relative}:host.mobile .hint{font-size:13px}section{flex:1;display:flex;flex-direction:column;position:relative;overflow:hidden}.wraper{position:relative;overflow:hidden;display:flex;flex-direction:column;flex:1}.wraper .loading{position:absolute;inset:0;z-index:20;background-color:#f5f5f5}.documentTurnOver{position:absolute;width:100%;height:100%;top:0;left:0;display:flex;flex-direction:column;align-items:center;justify-content:center}.documentTurnOver mat-icon{width:200px;color:#fff;height:200px;font-size:100px}.displayInfo{text-align:center;flex:1;width:100%;background-color:#000;height:50px;display:flex;flex-direction:row;align-items:center;justify-content:center;color:#fff;z-index:200}.displayInfo.mobile{font-size:12px}.preview{width:100%;border-radius:1%}footer button{box-shadow:none!important;height:45px;min-height:45px;text-transform:uppercase}footer .actions{display:flex;flex-direction:row;align-items:center;padding:8px}footer .actions button{flex:1}.error{display:flex;align-items:center;justify-content:center;flex:1}.error .title{font-size:20px;margin-bottom:8px}.error .title mat-icon{margin-right:8px}.error ul{font-size:18px;list-style-type:none}mat-card{box-shadow:none!important}.mr-4{margin-right:4px}.ml-4{margin-left:4px}.p-16{padding:16px}.p-8{padding:8px}.py-16{padding:16px 0}.w-100-p{width:100%}.scanPreview{padding:16px}.scanPreview .image{background-position:center;background-repeat:no-repeat;background-size:contain}.empty{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center}.manualMode{position:absolute;width:100%;height:100%;z-index:200;top:0;left:0;display:flex;flex-direction:column;align-items:center;justify-content:center}.manualMode .content{margin-top:20px;background-color:#fff;border-radius:6px;max-width:300px;width:100%;display:flex;flex-direction:column;padding:30px 20px 0}.manualMode .inner{display:flex;flex-direction:column;align-items:center;justify-content:center;font-size:14px}.manualMode .inner mat-icon{width:60px;height:60px;font-size:60px}.manualMode .inner .text{margin:20px 0}.manualMode footer{display:flex;flex-direction:row;align-items:center;justify-content:center;padding-bottom:20px}.manualMode footer button{min-width:140px;box-shadow:none;border:1px solid #ccc}.pageTurn{position:absolute;width:100%;height:100%;z-index:200;top:0;left:0;display:flex;flex-direction:column;align-items:center;justify-content:center}.pageTurn .content{background-color:#fff;border-radius:6px;max-width:300px;width:100%;display:flex;flex-direction:column;padding:30px 20px 0}.pageTurn .inner{display:flex;flex-direction:column;align-items:center;justify-content:center}.pageTurn .inner mat-icon{width:60px;height:60px;font-size:60px}.pageTurn .inner .text{margin:20px 0;font-size:14px}.pageTurn footer{display:flex;flex-direction:row;align-items:center;justify-content:center;padding-bottom:20px}.pageTurn footer button{min-width:200px;box-shadow:none;border:1px solid #ccc}.hint{position:absolute;z-index:5;font-size:18px;line-height:18px;display:flex;flex-direction:row;align-items:center;justify-content:center;width:100%}.hint .text{border-radius:3px;padding:4px 8px;background-color:#000;color:#fff;text-align:center;display:inline;-webkit-box-decoration-break:clone;box-decoration-break:clone}\n"] }]
|
|
699
|
+
}], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i0.NgZone }, { type: i1.NgxScandocCameraProvider }, { type: i0.Injector }, { type: i2.LayoutProvider }, { type: i3.Platform }, { type: i4.DeviceDetectorService }, { type: i5.NgxScandocAuthProvider }]; }, propDecorators: { type: [{
|
|
700
|
+
type: Input
|
|
701
|
+
}], dialogs: [{
|
|
702
|
+
type: Input
|
|
703
|
+
}], actions: [{
|
|
704
|
+
type: Output
|
|
705
|
+
}], showDialog: [{
|
|
706
|
+
type: Input
|
|
707
|
+
}], class: [{
|
|
708
|
+
type: HostBinding,
|
|
709
|
+
args: ['class.mobile']
|
|
710
|
+
}], onResize: [{
|
|
711
|
+
type: HostListener,
|
|
712
|
+
args: ['window:resize', ['$event']]
|
|
713
|
+
}] } });
|
|
714
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2Nhbi5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtc2NhbmRvYy9zcmMvY29yZS9jb21wb25lbnRzL3NjYW4vc2Nhbi5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtc2NhbmRvYy9zcmMvY29yZS9jb21wb25lbnRzL3NjYW4vc2Nhbi5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUVULFlBQVksRUFDWixNQUFNLEVBQ04sWUFBWSxFQUlaLHVCQUF1QixFQUN2QixLQUFLLEVBSUwsV0FBVyxHQUdaLE1BQU0sZUFBZSxDQUFDO0FBRXZCLE9BQU8sRUFBRSxPQUFPLEVBQWdELE1BQU0sTUFBTSxDQUFDO0FBRzdFLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUUzQyxPQUFPLEVBQXlCLFVBQVUsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBR25FLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQU1oRSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7Ozs7Ozs7Ozs7Ozs7OztBQTJCbEQsTUFBTSxPQUFPLGFBQ1gsU0FBUSxhQUFhO0lBcUZyQixJQUFpQyxLQUFLO1FBQ3BDLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQztJQUN2QixDQUFDO0lBR0QsUUFBUTtRQUNOLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRTtZQUNmLElBQUksQ0FBQyxFQUFFLENBQUMsYUFBYSxFQUFFLENBQUM7U0FDekI7SUFDSCxDQUFDO0lBSUQsWUFDUyxFQUFxQixFQUNwQixJQUFZLEVBQ2IsY0FBd0MsRUFDdkMsUUFBa0IsRUFDbEIsY0FBOEIsRUFDOUIsUUFBa0IsRUFDbEIsYUFBb0MsRUFDcEMsSUFBNEIsQ0FBQyw4QkFBOEI7O1FBRW5FLEtB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IEV2ZW50RW1pdHRlcixcbiAgT3V0cHV0LFxuICBIb3N0TGlzdGVuZXIsXG4gIEVsZW1lbnRSZWYsXG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBBZnRlclZpZXdJbml0LFxuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgSW5wdXQsXG4gIE9uRGVzdHJveSxcbiAgTmdab25lLFxuICBJbmplY3RvcixcbiAgSG9zdEJpbmRpbmcsXG4gIFZpZXdSZWYsXG4gIFZpZXdDb250YWluZXJSZWYsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgTWF0RGlhbG9nUmVmIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvZGlhbG9nJztcbmltcG9ydCB7IFN1YmplY3QsIE9ic2VydmFibGUsIG9mLCBmb3JrSm9pbiwgZnJvbSwgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyB2NCBhcyB1dWlkdjQgfSBmcm9tICd1dWlkJztcblxuaW1wb3J0IHsgRm9ybUdyb3VwIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuXG5pbXBvcnQgeyBzd2l0Y2hNYXAsIG1hcCwgZGVsYXksIGNhdGNoRXJyb3IgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7IFRyYW5zbGF0ZVNlcnZpY2UgfSBmcm9tICdAbmd4LXRyYW5zbGF0ZS9jb3JlJztcbmltcG9ydCB7IFNjYW5Qcm92aWRlciB9IGZyb20gJy4uLy4uLy4uL3Byb3ZpZGVycy9zY2FuLnByb3ZpZGVyJztcbmltcG9ydCB7IFdlYmNhbUltYWdlIH0gZnJvbSAnLi4vLi4vLi4vY29yZS9jb21wb25lbnRzL3dlYmNhbS9kb21haW4vd2ViY2FtLWltYWdlJztcbmltcG9ydCB7IFdlYmNhbUluaXRFcnJvciB9IGZyb20gJy4uLy4uLy4uL2NvcmUvY29tcG9uZW50cy93ZWJjYW0vZG9tYWluL3dlYmNhbS1pbml0LWVycm9yJztcbmltcG9ydCB7IE5neFNjYW5kb2NBdXRoUHJvdmlkZXIgfSBmcm9tICcuLi8uLi8uLi9wcm92aWRlcnMvYXV0aC5wcm92aWRlcic7XG5pbXBvcnQgeyBOZ3hTY2FuZG9jQ2FtZXJhUHJvdmlkZXIgfSBmcm9tICcuLi8uLi8uLi9wcm92aWRlcnMvY2FtZXJhLnByb3ZpZGVyJztcbmltcG9ydCB7IExheW91dFByb3ZpZGVyIH0gZnJvbSAnLi4vLi4vLi4vcHJvdmlkZXJzL2xheW91dC5wcm92aWRlcic7XG5pbXBvcnQgeyBCYXNlQ29tcG9uZW50IH0gZnJvbSAnLi4vYmFzZS5jb21wb25lbnQnO1xuaW1wb3J0IHsgUGxhdGZvcm0gfSBmcm9tICdAYW5ndWxhci9jZGsvcGxhdGZvcm0nO1xuXG5pbXBvcnQgeyBEZXZpY2VEZXRlY3RvclNlcnZpY2UgfSBmcm9tICduZ3gtZGV2aWNlLWRldGVjdG9yJztcblxuZXhwb3J0IGludGVyZmFjZSBJV2luZG93IGV4dGVuZHMgV2luZG93IHtcbiAgVGV4dERldGVjdG9yOiBhbnk7XG59XG5cbmludGVyZmFjZSBUcm91Ymxlc2hvb3Rpbmcge1xuICBSZXF1ZXN0OiBhbnk7XG4gIFJlc3BvbnNlOiBhbnk7XG4gIEV4cGVjdGVkT3V0cHV0OiBhbnk7XG4gIEFjY2VwdFRlcm1zQW5kQ29uZGl0aW9uczogYm9vbGVhbjtcbn1cblxuaW50ZXJmYWNlIFRpbWVzdGFtcHMge1xuICB0aW1lOiBudW1iZXI7XG4gIGxvYWQ6IG51bWJlcjtcbn1cblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbmd4LXNjYW4nLFxuICB0ZW1wbGF0ZVVybDogJy4vc2Nhbi5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL3NjYW4uY29tcG9uZW50LnNjc3MnXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG59KVxuZXhwb3J0IGNsYXNzIFNjYW5Db21wb25lbnRcbiAgZXh0ZW5kcyBCYXNlQ29tcG9uZW50XG4gIGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCwgT25EZXN0cm95XG57XG4gIHNjYW5CbGFzdERhdGE6IGFueSA9IFtcbiAgICB7XG4gICAgICB0aXRsZTogJ3Btcy5kaWFsb2dzLmNvbXBvbmVudHMuc2NhblByb2ZpbGUuZnJvbnQnLFxuICAgICAgZGVzY3JpcHRpb246ICdwbXMuZGlhbG9ncy5jb21wb25lbnRzLnNjYW5Qcm9maWxlLmZyb250RGVzY3JpcHRpb24nLFxuICAgICAgc2lkZTogJ0ZST05UJyxcbiAgICB9LFxuICAgIHtcbiAgICAgIHRpdGxlOiAncG1zLmRpYWxvZ3MuY29tcG9uZW50cy5zY2FuUHJvZmlsZS5iYWNrJyxcbiAgICAgIGRlc2NyaXB0aW9uOiAncG1zLmRpYWxvZ3MuY29tcG9uZW50cy5zY2FuUHJvZmlsZS5iYWNrRGVzY3JpcHRpb24nLFxuICAgICAgZGlzYWJsZWQ6IHRydWUsXG4gICAgICBzaWRlOiAnQkFDSycsXG4gICAgfSxcbiAgXTtcbiAgQElucHV0KCkgdHlwZSA9ICdkZXNrdG9wJztcbiAgQElucHV0KCkgZGlhbG9nczogYW55O1xuICBAT3V0cHV0KCkgYWN0aW9ucyA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcblxuICBwdWJsaWMgZGV2aWNlSWQ/OiBzdHJpbmc7XG5cbiAgc2NhblJlc3VsdHMgPSBuZXcgU3ViamVjdCgpO1xuICBzY2FuU2Vjb25kU2lkZSA9IGZhbHNlO1xuICBzdGFydFRpbWU6IG51bWJlciA9IDA7XG5cbiAgc2NhbkluUHJvZ3Jlc3MgPSBmYWxzZTtcblxuICAvLyB3ZWJjYW0gc25hcHNob3QgdHJpZ2dlclxuICBkb2N1bWVudFR5cGVTZWxlY3RlZCA9IGZhbHNlO1xuICBpbWFnZUhhbmRsZXJTdWJzY3JpcHRpb24hOiBTdWJzY3JpcHRpb247XG4gIHNlbGVjdGVkU2lkZTogYW55O1xuICBpbWFnZXM6IGFueTtcbiAgc2NhblRpbWVvdXQ6IGFueTtcbiAgcHJldmlldzogYW55ID0gbnVsbDtcbiAgc2NhblR5cGU6IGFueTtcblxuICBlcnJvckNvZGUgPSAnMTAwMCc7XG4gIGRpc3BsYXlJbmZvOiBhbnkgPSAnc2NhbmRvYy5pbmZvLnBvc2l0aW9uJztcblxuICB2ZXJpZmljYXRpb25FcnJvclNlbnQgPSBmYWxzZTtcbiAgZXJyb3IgPSBmYWxzZTtcbiAgY2FtZXJhUmVhZHkgPSBmYWxzZTtcbiAgcmVzdWx0OiBhbnk7XG4gIHNjYW5pbmcgPSBmYWxzZTtcblxuICBwcm9tcHRNYW51YWwgPSBmYWxzZTtcblxuICBmcm9udEltYWdlOiBhbnk7XG4gIGJhY2tJbWFnZTogYW55O1xuXG4gIGltYWdlSGFuZGxlciA9IG5ldyBTdWJqZWN0KCk7XG4gIG1hbnVhbERhdGFTZXQgPSBmYWxzZTtcbiAgbG9nRGF0YTogVHJvdWJsZXNob290aW5nID0ge1xuICAgIEFjY2VwdFRlcm1zQW5kQ29uZGl0aW9uczogdHJ1ZSxcbiAgICBSZXF1ZXN0OiBudWxsLFxuICAgIFJlc3BvbnNlOiBudWxsLFxuICAgIEV4cGVjdGVkT3V0cHV0OiBudWxsLFxuICB9O1xuICBibHVyVmFsdWVzOiBhbnkgPSBbXTtcbiAgc2NhbkRhdGFzOiBhbnkgPSBbXTtcbiAgc2NhblNpZGU6IGFueTtcbiAgaWRTY2FuOiBhbnkgPSBudWxsO1xuICB3ZWJjYW1JbWFnZT86IFdlYmNhbUltYWdlO1xuICBtb2RlbDogYW55O1xuICB2YWxpZGF0aW9uID0gZmFsc2U7XG4gIHNjYW5uZWRJbWFnZXM6IGFueVtdID0gW107XG4gIHNjYW5EZWxheTogYW55ID0gMDtcbiAgcHVibGljIHRyaWdnZXI6IFN1YmplY3Q8bnVtYmVyPiA9IG5ldyBTdWJqZWN0PG51bWJlcj4oKTtcbiAgLy8gc3dpdGNoIHRvIG5leHQgLyBwcmV2aW91cyAvIHNwZWNpZmljIHdlYmNhbTsgdHJ1ZS9mYWxzZTogZm9yd2FyZC9iYWNrd2FyZHMsIHN0cmluZzogZGV2aWNlSWRcbiAgcHVibGljIG5leHRXZWJjYW06IFN1YmplY3Q8Ym9vbGVhbiB8IHN0cmluZz4gPSBuZXcgU3ViamVjdDxcbiAgICBib29sZWFuIHwgc3RyaW5nXG4gID4oKTtcbiAgaW1hZ2VWZXJpZmllZCA9IGZhbHNlO1xuICBmb3JtID0gbmV3IEZvcm1Hcm91cCh7fSk7XG4gIG1hbnVhbCA9IGZhbHNlO1xuICBpc01vYmlsZSA9IHRoaXMucGxhdGZvcm0uSU9TIHx8IHRoaXMucGxhdGZvcm0uQU5EUk9JRDtcbiAgQElucHV0KCkgc2hvd0RpYWxvZyA9IGZhbHNlO1xuICBzY2FuSW1hZ2VUaW1lc3RhbXBzOiBUaW1lc3RhbXBzID0ge1xuICAgIHRpbWU6IDAsXG4gICAgbG9hZDogMCxcbiAgfTtcbiAgbnVtYmVyT2ZWYWxpZGF0aW9ucyA9IDA7XG4gIHZhbGlkYXRpb25EZWJ1ZzogYW55ID0gW107XG5cbiAgQEhvc3RCaW5kaW5nKCdjbGFzcy5tb2JpbGUnKSBnZXQgY2xhc3MoKSB7XG4gICAgcmV0dXJuIHRoaXMuaXNNb2JpbGU7XG4gIH1cblxuICBASG9zdExpc3RlbmVyKCd3aW5kb3c6cmVzaXplJywgWyckZXZlbnQnXSlcbiAgb25SZXNpemUoKSB7XG4gICAgaWYgKHRoaXMucmVzdWx0KSB7XG4gICAgICB0aGlzLmNkLmRldGVjdENoYW5nZXMoKTtcbiAgICB9XG4gIH1cblxuICBzY2FuUHJvdmlkZXIhOiBTY2FuUHJvdmlkZXI7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIGNkOiBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICBwcml2YXRlIHpvbmU6IE5nWm9uZSxcbiAgICBwdWJsaWMgY2FtZXJhUHJvdmlkZXI6IE5neFNjYW5kb2NDYW1lcmFQcm92aWRlcixcbiAgICBwcml2YXRlIGluamVjdG9yOiBJbmplY3RvcixcbiAgICBwcml2YXRlIGxheW91dFByb3ZpZGVyOiBMYXlvdXRQcm92aWRlcixcbiAgICBwcml2YXRlIHBsYXRmb3JtOiBQbGF0Zm9ybSxcbiAgICBwcml2YXRlIGRldmljZVNlcnZpY2U6IERldmljZURldGVjdG9yU2VydmljZSxcbiAgICBwcml2YXRlIGF1dGg6IE5neFNjYW5kb2NBdXRoUHJvdmlkZXIgLy8gcHJpdmF0ZSBhcGk6IFNlcnZlclByb3ZpZGVyXG4gICkge1xuICAgIHN1cGVyKCk7XG4gICAgdGhpcy5zY2FuUHJvdmlkZXIgPSB0aGlzLmluamVjdG9yLmdldChTY2FuUHJvdmlkZXIpO1xuXG4gICAgaWYgKCF0aGlzLnNjYW5Qcm92aWRlci5jb25maWcuZGV2ZWxvcG1lbnQpIHtcbiAgICAgIC8vIGNvbnNvbGUgPSB7XG4gICAgICAvLyAgIGxvZzogKC4uLmFyZ3M6IGFueSkgPT4ge30sXG4gICAgICAvLyAgIHRpbWU6ICguLi5hcmdzOiBhbnkpID0+IHt9LFxuICAgICAgLy8gICB0aW1lRW5kOiAoLi4uYXJnczogYW55KSA9PiB7fSxcbiAgICAgIC8vICAgd2FybjogKC4uLmFyZ3M6IGFueSkgPT4ge30sXG4gICAgICAvLyAgIGVycm9yOiAoLi4uYXJnczogYW55KSA9PiB7fSxcbiAgICAgIC8vIH07XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSByZXNldExvZ0RhdGEoKSB7XG4gICAgdGhpcy5sb2dEYXRhID0ge1xuICAgICAgUmVxdWVzdDogbnVsbCxcbiAgICAgIFJlc3BvbnNlOiBudWxsLFxuICAgICAgRXhwZWN0ZWRPdXRwdXQ6IG51bGwsXG4gICAgICBBY2NlcHRUZXJtc0FuZENvbmRpdGlvbnM6IHRydWUsXG4gICAgfTtcbiAgfVxuXG4gIGluaXQoKSB7XG4gICAgdGhpcy5hdXRoLmFjY2VzVG9rZW4uc3Vic2NyaWJlKCk7XG4gICAgdGhpcy5yZXNldExvZ0RhdGEoKTtcbiAgICAvLyB0aGlzLnJlc3VsdD10cnVlO1xuICAgIC8vIHRoaXMucmVzdWx0ID17fTtcblxuICAgIGNvbnNvbGUubG9nKCdJTklUIFNDQU4nKTtcbiAgfVxuXG4gIGNvbnRpbnVlKCkge1xuICAgIHRoaXMuZG9jdW1lbnRUeXBlU2VsZWN0ZWQgPSBmYWxzZTtcblxuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy5zZWxlY3RlZFNpZGUuaW1hZ2UgPSB0aGlzLndlYmNhbUltYWdlO1xuICAgICAgaWYgKHRoaXMuc2VsZWN0ZWRTaWRlLnNpZGUgPT09ICdGUk9OVCcpIHtcbiAgICAgICAgdGhpcy5zY2FuQmxhc3REYXRhWzFdLmRpc2FibGVkID0gZmFsc2U7XG4gICAgICB9XG4gICAgICB0aGlzLmNkLmRldGVjdENoYW5nZXMoKTtcbiAgICB9LCAyMDApO1xuICB9XG5cbiAgc2NhbigpIHtcbiAgICB0aGlzLnRyaWdnZXIubmV4dChuZXcgRGF0ZSgpLmdldFRpbWUoKSk7XG4gIH1cblxuICBwdWJsaWMgaGFuZGxlSW1hZ2Uod2ViY2FtSW1hZ2U6IFdlYmNhbUltYWdlKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuc3RhcnRUaW1lID09PSAwKSB7XG4gICAgICB0aGlzLnN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgfVxuICAgIC8vIGNvbnNvbGUubG9nKCdbcmVjZWl2ZWQgd2ViY2FtIGltYWdlXScsIHdlYmNhbUltYWdlKTtcbiAgICB0aGlzLnpvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgY29uc3QgdGltZSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuXG4gICAgICBpZiAodGhpcy5zY2FuSW1hZ2VUaW1lc3RhbXBzLmxvYWQgPiAwKSB7XG4gICAgICAgIGNvbnN0IHsgbG9hZCB9ID0gdGhpcy5zY2FuSW1hZ2VUaW1lc3RhbXBzO1xuICAgICAgICBjb25zdCBkaWZmID0gdGltZSAtIGxvYWQ7XG4gICAgICAgIC8vICAgY29uc29sZS5sb2coJ3RpbWU6JywgZGlmZik7XG4gICAgICAgIHRoaXMuc2NhbkRlbGF5ID0gZGlmZjtcbiAgICAgIH1cblxuICAgICAgdGhpcy5zY2FuSW1hZ2VUaW1lc3RhbXBzLmxvYWQgPSB0aW1lO1xuXG4gICAgICBpZiAod2ViY2FtSW1hZ2UuaW1hZ2VBc0RhdGFVcmwpIHtcbiAgICAgICAgdGhpcy5zY2FubmVkSW1hZ2VzLnB1c2god2ViY2FtSW1hZ2UpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLmNkLmRldGVjdENoYW5nZXMoKTtcbiAgICAgIGlmICh0aGlzLnNjYW5uZWRJbWFnZXMubGVuZ3RoID4gMCAmJiAhdGhpcy52YWxpZGF0aW9uKSB7XG4gICAgICAgIC8vIGlmICh0aGlzLnNjYW5Qcm92aWRlci5jb25maWcuZGV2ZWxvcG1lbnQpIHtcbiAgICAgICAgLy8gICB0aGlzLnNjYW5uZWRJbWFnZXMuZm9yRWFjaCgoaW1nKSA9PiB7XG4gICAgICAgIC8vICAgICBjb25zdCBjb25zb2xlQmFja2dyb3VuZCA9XG4gICAgICAgIC8vICAgICAgIFwiZm9udC1zaXplOjEwMHB4O2JhY2tncm91bmQtaW1hZ2U6IHVybCgnXCIgK1xuICAgICAgICAvLyAgICAgICBpbWcuaW1hZ2VSZXNpemVkICtcbiAgICAgICAgLy8gICAgICAgXCInKTtiYWNrZ3JvdW5kLXNpemU6IGNvbnRhaW47IGJhY2tncm91bmQtcmVwZWF0OiBuby1yZXBlYXQ7XCI7XG4gICAgICAgIC8vICAgICBjb25zb2xlLmxvZygnJWMgICAgJywgY29uc29sZUJhY2tncm91bmQpO1xuICAgICAgICAvLyAgIH0pO1xuICAgICAgICAvLyB9XG4gICAgICAgIC8vICAgdGhpcy5mcm9udEltYWdlID0gd2ViY2FtSW1hZ2UuaW1hZ2VSZXNpemVkO1xuXG4gICAgICAgIC8vIGNvbnNvbGUudGltZUVuZCgnc2NhbicpO1xuICAgICAgICAvLyBjb25zb2xlLnRpbWUoJ3NjYW4nKTtcbiAgICAgICAgLy8gZ2V0IGxhc3QgMTBcbiAgICAgICAgLy8gY29uc29sZS5sb2coJ0NBUFRVUkVEOicsIHRoaXMuc2Nhbm5lZEltYWdlcy5sZW5ndGgpO1xuICAgICAgICBjb25zdCBpbWFnZXMgPSB0aGlzLnNjYW5uZWRJbWFnZXMuc2xpY2UoLTUpO1xuICAgICAgICAvLyBzZXQgaW1hZ2VzIHRvIDBcbiAgICAgICAgdGhpcy5zY2FubmVkSW1hZ2VzID0gW107XG4gICAgICAgIGNvbnN0IGltYWdlc0FycmF5ID0gaW1hZ2VzLm1hcCgobSkgPT4gbS5pbWFnZVJlc2l6ZWQuc3BsaXQoJywnKVsxXSk7XG4gICAgICAgIHRoaXMudmFsaWRhdGlvbiA9IHRydWU7XG4gICAgICAgIC8vIGNvbnNvbGUubG9nKCdCVVJTVCcpO1xuICAgICAgICB0aGlzLmhhbmRsZUJ1cnN0RGF0YShpbWFnZXNBcnJheSwgaW1hZ2VzKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICh0aGlzLmNhbWVyYVJlYWR5KSB7XG4gICAgICAgICAgdGhpcy5zY2FuKCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgaGFuZGxlQnVyc3REYXRhKFxuICAgIGltYWdlc0FycmF5OiBhbnksXG4gICAgaW1hZ2VzOiBhbnksXG4gICAgdHlwZTogJ3dvcmtlcicgfCAncGxhaW4nID0gJ3BsYWluJ1xuICApIHtcbiAgICB0aGlzLl9fc3VicyhcbiAgICAgIHRoaXMuc2NhblByb3ZpZGVyLmJ1cnN0KGltYWdlc0FycmF5LCB0aGlzLmJsdXJWYWx1ZXMpXG4gICAgKS5zdWJzY3JpYmUoKHJlc3A6IGFueSkgPT4ge1xuICAgICAgdGhpcy5kaXNwbGF5SW5mbyA9ICdzY2FuZG9jLmluZm8uYycgKyByZXNwLkluZm9Db2RlO1xuICAgICAgLy8gY29uc29sZS50aW1lRW5kKCd2YWxpZGF0aW9uUE9TVCcpO1xuICAgICAgLy8gY29uc29sZS5sb2coJ0FuYWx5c2lzVGltZScsIHJlc3AuQW5hbHlzaXNUaW1lKTtcbiAgICAgIGNvbnN0IHsgRG9jVHlwZSwgU2VyaWVzLCBTaWRlLCBJbmZvQ29kZSwgVHJhbnNhY3Rpb25JRCB9ID0gcmVzcDtcblxuICAgICAgdGhpcy5oYW5kbGVMb25nVmFsaWRhdGlvbkVycm9yKFRyYW5zYWN0aW9uSUQsIGltYWdlc1swXS5pbWFnZUFzRGF0YVVybC5zcGxpdCgnLCcpWzFdKTtcbiAgICAgIC8vIGlmIChJbmZvQ29kZSA9PT0gJzEwMDYnICYmIHRoaXMuaWRTY2FuKSB7XG4gICAgICAvLyAgIHRoaXMuaGFuZGxlTG9uZ1ZheWxpZGF0aW9uRXJyb3IoaW1hZ2UpO1xuICAgICAgLy8gfVxuICAgICAgLy8gIGNvbnNvbGUud2FybihyZXNwLlZhbGlkYXRlZCwgdGhpcy5udW1iZXJPZlZhbGlkYXRpb25zKTtcbiAgICAgIGlmIChyZXNwLkRldGVjdGVkQmx1clZhbHVlKSB7XG4gICAgICAgIHRoaXMuYmx1clZhbHVlcy5wdXNoKHJlc3AuRGV0ZWN0ZWRCbHVyVmFsdWUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5ibHVyVmFsdWVzID0gW107XG4gICAgICB9XG5cbiAgICAgIGNvbnNvbGUubG9nKCk7XG4gICAgICBpZiAocmVzcC5WYWxpZGF0ZWQpIHtcbiAgICAgICAgdGhpcy5udW1iZXJPZlZhbGlkYXRpb25zKys7XG4gICAgICAgIHRoaXMudmFsaWRhdGlvbkRlYnVnLnB1c2gocmVzcCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLm51bWJlck9mVmFsaWRhdGlvbnMgPSAwO1xuICAgICAgICB0aGlzLnZhbGlkYXRpb25EZWJ1ZyA9IFtdO1xuICAgICAgfVxuICAgICAgaWYgKHJlc3AuVmFsaWRhdGVkKSB7XG4gICAgICAgIHRoaXMuZGlzcGxheUluZm8gPSAnJztcbiAgICAgICAgLy8gY29uc29sZS5sb2coJ1tTQ0FOTkVEIElOREVYXScsIHJlc3AuSW5kZXgpO1xuICAgICAgICBjb25zdCBzZWxlY3RlZEltYWdlID0gaW1hZ2VzW3Jlc3AuSW5kZXhdO1xuXG4gICAgICAgIC8vIHRoaXMucHJldmlldyA9IHRoaXMud2ViY2FtSW1hZ2UuaW1hZ2VBc0RhdGFVcmw7XG4gICAgICAgIHRoaXMuY2QuZGV0ZWN0Q2hhbmdlcygpO1xuXG4gICAgICAgIGxldCBpbWFnZSA9IHNlbGVjdGVkSW1hZ2U7XG4gICAgICAgIGNvbnNvbGUud2Fybih0eXBlKTtcbiAgICAgICAgaWYgKHR5cGUgPT0gJ3dvcmtlcicpIHtcbiAgICAgICAgICAvL2NvbnN0IGRhdGFVcmwgPSB0aGlzLmhhbmRsZUJpdG1hcEltYWdlKHNlbGVjdGVkSW1hZ2UuYml0bWFwKTtcbiAgICAgICAgICBpbWFnZSA9IHNlbGVjdGVkSW1hZ2UuaW1hZ2VBc0RhdGFVcmw7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoSW5mb0NvZGUgPT09ICcxMDA3Jykge1xuICAgICAgICAgIC8vIEZvciBJRCBhc2sgZm9yIG90aGVyIHNpZGVcbiAgICAgICAgICBpZiAoU2lkZSA9PT0gJ0ZST05UJykge1xuICAgICAgICAgICAgdGhpcy5zY2FuQmxhc3REYXRhWzBdLmltYWdlID0gaW1hZ2U7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuc2NhbkJsYXN0RGF0YVsxXS5pbWFnZSA9IGltYWdlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmICh0aGlzLnNjYW5CbGFzdERhdGFbMF0uaW1hZ2UgJiYgdGhpcy5zY2FuQmxhc3REYXRhWzFdLmltYWdlKSB7XG4gICAgICAgICAgICAvLyAgIGNvbnNvbGUud2FybignVVBMT0FEJyk7XG4gICAgICAgICAgICBpZiAodHlwZSA9PSAnd29ya2VyJykge1xuICAgICAgICAgICAgICB0aGlzLmltYWdlSGFuZGxlci5uZXh0KHsgdHlwZTogJ3N0b3AnIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy9jb25zb2xlLndhcm4oJ0RFQlVHJywgU2lkZSwgdGhpcy52YWxpZGF0aW9uRGVidWcpO1xuICAgICAgICAgICAgdGhpcy5zY2FuQmxhc3RGaW5pc2goKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5ibHVyVmFsdWVzID0gW107XG4gICAgICAgICAgICB0aGlzLm51bWJlck9mVmFsaWRhdGlvbnMgPSAwO1xuICAgICAgICAgICAgLy8gY29uc29sZS53YXJuKCdERUJVRycsU2lkZSx0aGlzLnZhbGlkYXRpb25EZWJ1ZylcbiAgICAgICAgICAgIHRoaXMudmFsaWRhdGlvbkRlYnVnID0gW107XG4gICAgICAgICAgICBjb25zdCBudW0gPSBTaWRlID09PSAnRlJPTlQnID8gMSA6IDA7XG4gICAgICAgICAgICB0aGlzLnNjYW5TZWNvbmRTaWRlID0gdHJ1ZTtcblxuICAgICAgICAgICAgdGhpcy5zaW5nbGVTY2FuKHRoaXMuc2NhbkJsYXN0RGF0YVtudW1dKTtcblxuICAgICAgICAgICAgdGhpcy5pZFNjYW4gPSB0aGlzLnNjYW5CbGFzdERhdGFbbnVtXS5zaWRlO1xuXG4gICAgICAgICAgICBpZiAoIXRoaXMuc2hvd0RpYWxvZykge1xuICAgICAgICAgICAgICB0aGlzLnNob3dEaWFsb2cgPSB0cnVlO1xuICAgICAgICAgICAgICB0aGlzLmNkLmRldGVjdENoYW5nZXMoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIHJlc2V0IG1hbnVhbCBzY2FuIHBvcHVwIGludGVydmFsXG4gICAgICAgICAgICB0aGlzLnZlcmlmaWNhdGlvbkVycm9yU2VudCA9IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5zdGFydFRpbWUgPSBEYXRlLm5vdygpO1xuXG4gICAgICAgICAgICB0aGlzLmRpc3BsYXlJbmZvID0gJ3NjYW5kb2MuaW5mby50dXJuJztcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gY29uc29sZS53YXJuKCdERUJVRycsIFNpZGUsIHRoaXMudmFsaWRhdGlvbkRlYnVnKTtcbiAgICAgICAgICB0aGlzLnNjYW5CbGFzdERhdGFbMF0uaW1hZ2UgPSBpbWFnZTtcbiAgICAgICAgICAvLyBjb25zb2xlLndhcm4oJ1VQTE9BRCcpO1xuICAgICAgICAgIGlmICh0eXBlID09ICd3b3JrZXInKSB7XG4gICAgICAgICAgICB0aGlzLmltYWdlSGFuZGxlci5uZXh0KHsgdHlwZTogJ3N0b3AnIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzLnNjYW5CbGFzdEZpbmlzaCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5zY2FubmVkSW1hZ2VzID0gW107XG5cbiAgICAgICAgLy8gdGhpcy5zY2FuQmxhc3REYXRhWzBdLmltYWdlID0gc2VsZWN0ZWRJbWFnZTtcblxuICAgICAgICAvL3RoaXMuc2NhbkJsYXN0RmluaXNoKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnZhbGlkYXRpb24gPSBmYWxzZTtcbiAgICAgICAgdGhpcy5zY2FuKCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBjbG9zZURpYWxvZygpIHtcbiAgICB0aGlzLnNob3dEaWFsb2cgPSBmYWxzZTtcbiAgICB0aGlzLnZhbGlkYXRpb24gPSBmYWxzZTtcblxuICAgIHRoaXMuc2NhbigpO1xuICB9XG5cbiAgcHVibGljIGhhbmRsZUluaXRFcnJvcihlcnJvcjogV2ViY2FtSW5pdEVycm9yKTogdm9pZCB7XG4gICAgY29uc29sZS5sb2coZXJyb3IpO1xuICB9XG5cbiAgZ2V0IHNjYW5CbGFzdENhblVwbG9hZCgpIHtcbiAgICByZXR1cm4gdGhpcy5zY2FuQmxhc3REYXRhWzBdLmltYWdlID8gdHJ1ZSA6IGZhbHNlO1xuICB9XG5cbiAgcHJpdmF0ZSBtYW51YWxNb2RlKHR5cGU6ICd3b3JrZXInIHwgJ3BsYWluJyA9ICdwbGFpbicpIHtcbiAgICB0aGlzLm1hbnVhbCA9IHRydWU7XG4gICAgdGhpcy5wcm9tcHRNYW51YWwgPSBmYWxzZTtcbiAgICB0aGlzLnNjYW5JblByb2dyZXNzID0gZmFsc2U7XG4gICAgdGhpcy5jYW1lcmFQcm92aWRlci4kc2hvd1N3aXRjaC5uZXh0KGZhbHNlKTtcblxuICAgIHRoaXMuY2QuZGV0ZWN0Q2hhbmdlcygpO1xuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVFeHRyYWN0aW9uRXJyb3IoZGF0YTogYW55KSB7XG4gICAgdGhpcy5sb2dEYXRhLkV4cGVjdGVkT3V0cHV0ID0ge307XG4gICAgLy8gaWYgKHRoaXMubG9nRGF0YS5FeHBlY3RlZE91dHB1dD8uX2F2YXRhcikge1xuICAgIC8vICAgZGVsZXRlIHRoaXMubG9nRGF0YS5FeHBlY3RlZE91dHB1dC5fYXZhdGFyO1xuICAgIC8vIH1cbiAgICAvLyB0aGlzLnNjYW5Qcm92aWRlci5zZW5kTG9nKHRoaXMubG9nRGF0YSkuc3Vic2NyaWJlKCk7XG5cbiAgICAvLyBjb25zb2xlLmxvZygnTE9HIERBVEEnLCB0aGlzLmxvZ0RhdGEpO1xuICAvLyAgdGhpcy5fX3N1YnModGhpcy5zY2FuUHJvdmlkZXIuc2VuZExvZyh0aGlzLmxvZ0RhdGEpKS5zdWJzY3JpYmUoKTtcbiAgfVxuXG4gIHByaXZhdGUgc2VuZEVycm9yTG9nKFRyYW5zYWN0aW9uSUQ6IHN0cmluZywgaW1hZ2U6IHN0cmluZykge1xuXG5cbiAgICBjb25zdCB7IGJyb3dzZXIsIG9zLCBkZXZpY2UgfSA9IHRoaXMuZGV2aWNlU2VydmljZTtcblxuICAgIGNvbnN0IEZyb250SW1hZ2UgPSB0aGlzLnNjYW5CbGFzdERhdGFbMF0/LmltYWdlID8gdGhpcy5nZXRJbWdCYXNlNjQoMCkgOiBudWxsO1xuXG4gICAgY29uc3Qgb3V0ID0ge1xuICAgICAgT1M6IG9zLFxuICAgICAgRGV2aWNlOiBkZXZpY2UsXG4gICAgICBCcm93c2VyOiBicm93c2VyLFxuICAgICAgVHJhbnNhY3Rpb25JRCxcbiAgICAgIEFjY2VwdFRlcm1zQW5kQ29uZGl0aW9uczogdHJ1ZSxcbiAgICAgIEZyb250SW1hZ2U6IEZyb250SW1hZ2UgfHwgaW1hZ2UsXG4gICAgICBCYWNrSW1hZ2U6IEZyb250SW1hZ2UgPyBpbWFnZSA6ICcnLFxuICAgIH07XG4gICAgY29uc29sZS5sb2cob3V0KTtcbiAgICB0aGlzLl9fc3VicyhcbiAgICAgIHRoaXMuc2NhblByb3ZpZGVyLnNlbmRFcnJvckxvZyhvdXQpKS5zdWJzY3JpYmUoKVxuICB9XG4gIHByaXZhdGUgaGFuZGxlTG9uZ1ZhbGlkYXRpb25FcnJvcihUcmFuc2FjdGlvbklEOiBzdHJpbmcsIGltYWdlOiBzdHJpbmcpIHtcbiAgICAvLyBzYXZlIGN1cnJlbnQgaW1hZ2UgYWZ0ZXIgMTBzZWNcbiAgICBsZXQgTUFOVUFMX0lOVEVSVkFMID0gdGhpcy5zY2FuUHJvdmlkZXIuY29uZmlnLm1hbnVhbFNjYW5EZWxheTtcbiAgICBjb25zdCBkaWZmID0gKERhdGUubm93KCkgLSB0aGlzLnN0YXJ0VGltZSkgLyAxMDAwO1xuXG4gICAgY29uc3Qgc2hvd0RpYWxvZyA9IGRpZmYgPiBNQU5VQUxfSU5URVJWQUw7XG5cbiAgICBpZiAoc2hvd0RpYWxvZyAmJiAhdGhpcy52ZXJpZmljYXRpb25FcnJvclNlbnQpIHtcbiAgICAgIHRoaXMudmVyaWZpY2F0aW9uRXJyb3JTZW50ID0gdHJ1ZTtcbiAgICAgIGNvbnNvbGUud2FybignW0hBTkRMRSBFUlJPUl0nKTtcblxuICAgICAgdGhpcy56b25lLnJ1bigoKSA9PiB7XG4gICAgICAgIC8vIGlmICghdGhpcy5zY2FuU2Vjb25kU2lkZSkge1xuICAgICAgICBpZiAodGhpcy5zY2FuUHJvdmlkZXIuY29uZmlnLm1hbnVhbE1vZGVFbmFibGVkKSB7XG4gICAgICAgICAgdGhpcy5wcm9tcHRNYW51YWwgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLnNjYW5Qcm92aWRlci5jb25maWcuZXJyb3JMb2dnaW5nKSB7XG4gICAgICAgICAgdGhpcy5zZW5kRXJyb3JMb2coVHJhbnNhY3Rpb25JRCwgaW1hZ2UpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gfVxuICAgICAgICB0aGlzLnN0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgICB9KTtcbiAgICAgIC8vIHRoaXMudmVyaWZpY2F0aW9uRXJyb3JTZW50ID0gdHJ1ZTtcbiAgICAgIC8vIGNvbnN0IGRhdGFVcmwgPSB0aGlzLmhhbmRsZUJpdG1hcEltYWdlKGltZy5iaXRtYXApO1xuXG4gICAgICAvLyBjb25zb2xlLndhcm4oJ1NFTlQnKTtcbiAgICAgIC8vIC8vICB0aGlzLmRpc3BsYXlJbmZvID0gJ0NhbnQgZGV0ZWN0IGRvY3VtZW50ISc7XG4gICAgICAvLyB0aGlzLmxvZ0RhdGEuUmVxdWVzdCA9IHRoaXMuX19zdWJzKFxuICAgICAgLy8gICB0aGlzLnNjYW5Qcm92aWRlci5zZW5kTG9nKHtcbiAgICAgIC8vICAgICBBY2NlcHRUZXJtc0FuZENvbmRpdGlvbnM6IHRydWUsXG4gICAgICAvLyAgICAgRXhwZWN0ZWRPdXRwdXQ6IHt9LFxuICAgICAgLy8gICAgIFJlcXVlc3Q6IHtcbiAgICAgIC8vICAgICAgIHZlcmlmaWNhdGlvbjogZGF0YVVybC5zcGxpdCgnLCcpWzFdLFxuICAgICAgLy8gICAgIH0sXG4gICAgICAvLyAgICAgUmVzcG9uc2U6IHtcbiAgICAgIC8vICAgICAgIFRyYW5zYWN0aW9uSUQ6IHV1aWR2NCgpLFxuICAgICAgLy8gICAgIH0sXG4gICAgICAvLyAgIH0pXG4gICAgICAvLyApLnN1YnNjcmliZSgpO1xuICAgIH1cbiAgfVxuICBuZ0FmdGVyVmlld0luaXQoKSB7XG4gICAgLy8gIHRoaXMucmVzdWx0ID0gdHJ1ZTtcblxuICAgIHRoaXMuY2FtZXJhUHJvdmlkZXIuJHNob3dTd2l0Y2gubmV4dCh0cnVlKTtcbiAgICB0aGlzLmNkLmRldGVjdENoYW5nZXMoKTtcblxuICAgIC8vIHRoaXMuc2NhblJlc3VsdHMubmV4dCh7IHR5cGU6ICdtb2RlbCcsIGRhdGE6IHt9IH0pO1xuXG4gICAgdGhpcy5fX3N1YnModGhpcy5jYW1lcmFQcm92aWRlci53ZWJjYW1PYnNlcnZhYmxlKS5zdWJzY3JpYmUoKHJlc3ApID0+IHtcbiAgICAgIHRoaXMuY2FtZXJhUmVhZHkgPSBmYWxzZTtcbiAgICAgIHRoaXMuc2NhbkluUHJvZ3Jlc3MgPSBmYWxzZTtcbiAgICAgIHRoaXMuc2Nhbm5lZEltYWdlcyA9IFtdO1xuICAgIH0pO1xuICAgIHRoaXMuX19zdWJzKHRoaXMuY2FtZXJhUHJvdmlkZXIuc2VsZmllJCkuc3Vic2NyaWJlKChyZXNwKSA9PiB7XG4gICAgICB0aGlzLnNlbGZpZSgpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5hdXRvU2NhbigpO1xuXG4gICAgdGhpcy5fX3N1YnModGhpcy5sYXlvdXRQcm92aWRlci5icmVha3BvaW50JCkuc3Vic2NyaWJlKCh2OiBhbnkpID0+IHtcbiAgICAgIHRoaXMuaXNNb2JpbGUgPSAhdi5tYXRjaGVzIHx8IHRoaXMucGxhdGZvcm0uSU9TIHx8IHRoaXMucGxhdGZvcm0uQU5EUk9JRDtcbiAgICAgIGNvbnNvbGUubG9nKCdNTk9CSUxFJywgdGhpcy5pc01vYmlsZSk7XG4gICAgfSk7XG4gIH1cblxuICBoYW5kbGVCaXRtYXBJbWFnZShiaXRtYXA6IGFueSkge1xuICAgIGNvbnN0IHsgd2lkdGgsIGhlaWdodCB9ID0gYml0bWFwO1xuXG4gICAgY29uc3Qgb2Zmc2NyZWVuU21hbGwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKTtcbiAgICBvZmZzY3JlZW5TbWFsbC53aWR0aCA9IHdpZHRoO1xuICAgIG9mZnNjcmVlblNtYWxsLmhlaWdodCA9IGhlaWdodDtcbiAgICBjb25zdCBjdHg6IGFueSA9IG9mZnNjcmVlblNtYWxsLmdldENvbnRleHQoJ2JpdG1hcHJlbmRlcmVyJyk7XG5cbiAgICBpZiAoY3R4KSB7XG4gICAgICBjdHguaW1hZ2VTbW9vdGhpbmdFbmFibGVkID0gZmFsc2U7XG4gICAgICBjdHgudHJhbnNmZXJGcm9tSW1hZ2VCaXRtYXAoYml0bWFwKTtcbiAgICAgIGJpdG1hcC5jbG9zZSgpO1xuICAgICAgY29uc3QgZGF0YSA9IGN0eC5jYW52YXMudG9EYXRhVVJMKCdpbWFnZS9qcGVnJyk7XG4gICAgICByZXR1cm4gZGF0YTtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBhdXRvU2NhbigpIHtcbiAgICBjb25zdCBzaWRlID0gdGhpcy5zY2FuQmxhc3REYXRhWzBdO1xuICAgIHRoaXMuaWRTY2FuID0gbnVsbDtcbiAgICB0aGlzLnNpbmdsZVNjYW4oc2lkZSk7XG4gIH1cblxuICBzaW5nbGVTY2FuKHNpZGU6IGFueSkge1xuICAgIHRoaXMuc2NhblR5cGUgPSBzaWRlLnNpZGU7XG4gICAgdGhpcy5wcmV2aWV3ID0gbnVsbDtcbiAgICB0aGlzLnNlbGVjdGVkU2lkZSA9IHNpZGU7XG5cbiAgICB0aGlzLnNlbGVjdGVkU2lkZS5pbWFnZSA9IG51bGw7XG4gICAgdGhpcy5kb2N1bWVudFR5cGVTZWxlY3RlZCA9IHRydWU7XG4gICAgdGhpcy5zY2FuQmxhc3REYXRhWzFdLmRpc2FibGVkID0gZmFsc2U7XG4gICAgdGhpcy5jZC5kZXRlY3RDaGFuZ2VzKCk7XG4gIH1cblxuICBtYW51YWxTY2FuRGF0YShkYXRhOiBhbnkpIHtcbiAgICBjb25zb2xlLmxvZyhkYXRhKTtcbiAgICB0aGlzLnNjYW5CbGFzdERhdGEgPSBkYXRhO1xuICAgIHRoaXMubWFudWFsID0gZmFsc2U7XG4gICAgdGhpcy5tYW51YWxEYXRhU2V0ID0gdHJ1ZTtcbiAgICB0aGlzLnNjYW5CbGFzdEZpbmlzaCgpO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRJbWdCYXNlNjQobnVtOiBhbnkpIHtcbiAgICBjb25zb2xlLmxvZygnR0VUIDY0Jyk7XG5cbiAgICAvLyBpZiAodGhpcy5tYW51YWxEYXRhU2V0KSB7XG4gICAgcmV0dXJuIHRoaXMuc2NhbkJsYXN0RGF0YVtudW1dLmltYWdlLl9pbWFnZUFzRGF0YVVybC5zcGxpdCgnLCcpWzFdO1xuICAgIC8vIH1cbiAgICAvLyByZXR1cm4gdGhpcy5zY2FuQmxhc3REYXRhW251bV0uaW1hZ2UuZGF0YVVybC5zcGxpdCgnLCcpWzFdO1xuICB9XG4gIHNjYW5CbGFzdEZpbmlzaCgpIHtcbiAgICBjb25zdCB7IGJyb3dzZXIsIG9zLCBkZXZpY2UgfSA9IHRoaXMuZGV2aWNlU2VydmljZTtcblxuICAgIHRoaXMuem9uZS5ydW4oKCkgPT4ge1xuICAgICAgdGhpcy5jYW1lcmFQcm92aWRlci4kc2hvd1N3aXRjaC5uZXh0KGZhbHNlKTtcbiAgICB9KTtcbiAgICBjb25zb2xlLnRpbWUoJ3VwbG9hZCcpO1xuICAgIGlmICh0aGlzLnR5cGUgPT09ICdtb2JpbGUnKSB7XG4gICAgICB0aGlzLmFjdGlvbnMuZW1pdCh7IGRhdGE6IHRoaXMuc2NhbkJsYXN0RGF0YSB9KTtcbiAgICAgIHRoaXMucmV0YWtlKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuaWRTY2FuID0gbnVsbDtcbiAgICAvLyBjb25zdCBsb2FkaW5nID0gdGhpcy5kaWFsb2dzLmxvYWRpbmcoKTtcbiAgICB0aGlzLnNjYW5pbmcgPSB0cnVlO1xuICAgIHRoaXMuY2QuZGV0ZWN0Q2hhbmdlcygpO1xuICAgIGNvbnNvbGUudGltZSgncGF5bG9hZCcpO1xuICAgIGNvbnN0IHBheWxvYWQ6IGFueSA9IHtcbiAgICAgIEFjY2VwdFRlcm1zQW5kQ29uZGl0aW9uczogdHJ1ZSxcbiAgICAgIERhdGFGaWVsZHM6IHtcbiAgICAgICAgRGV2aWNlSW5mbzoge1xuICAgICAgICAgIE9TOiBvcyxcbiAgICAgICAgICBEZXZpY2U6IGRldmljZSxcbiAgICAgICAgICBCcm93c2VyOiBicm93c2VyLFxuICAgICAgICB9LFxuICAgICAgICBGcm9udEltYWdlVHlwZTogJ2Jhc2U2NCcsXG4gICAgICAgIEZyb250SW1hZ2VDcm9wcGVkOiBmYWxzZSxcbiAgICAgICAgQmFja0ltYWdlVHlwZTogJ2Jhc2U2NCcsXG4gICAgICAgIEJhY2tJbWFnZUNyb3BwZWQ6IGZhbHNlLFxuICAgICAgICBGcm9udEltYWdlOiB0aGlzLmdldEltZ0Jhc2U2NCgwKSxcbiAgICAgICAgQmFja0ltYWdlOiB0aGlzLnNjYW5CbGFzdERhdGFbMV0uaW1hZ2UgPyB0aGlzLmdldEltZ0Jhc2U2NCgxKSA6IG51bGwsXG4gICAgICB9LFxuICAgICAgU2V0dGluZ3M6IHtcbiAgICAgICAgU2hvdWxkVmFsaWRhdGU6IHRydWUsXG4gICAgICAgIFNob3VsZFJldHVybkRvY3VtZW50SW1hZ2U6IHRydWUsXG4gICAgICAgIFNob3VsZFJldHVybkZhY2VJZkRldGVjdGVkOiB0cnVlLFxuICAgICAgICBTa2lwSW1hZ2VTaXplQ2hlY2s6IHRydWUsXG4gICAgICAgIENhblN0b3JlSW1hZ2VzOiB0aGlzLnNjYW5Qcm92aWRlci5jYW5TdG9yZUltYWdlcyxcbiAgICAgIH0sXG4gICAgICAvLyBDYWxsQmFja1VybDogJ2h0dHA6Ly9kZW1vOjUwMDAvcmVwb3J0L2V4dHJhY3RlZC8nLFxuICAgIH07XG4gICAgdGhpcy5mcm9udEltYWdlID0gJ2RhdGE6aW1hZ2UvanBlZztiYXNlNjQsJyArIHBheWxvYWQuRGF0YUZpZWxkcy5Gcm9udEltYWdlO1xuICAgIHRoaXMuYmFja0ltYWdlID0gJ2RhdGE6aW1hZ2UvanBlZztiYXNlNjQsJyArIHBheWxvYWQuRGF0YUZpZWxkcy5CYWNrSW1hZ2U7XG4gICAgaWYgKCF0aGlzLnNjYW5CbGFzdERhdGFbMV0uaW1hZ2UpIHtcbiAgICAgIHBheWxvYWQuU2V0dGluZ3MuSWdub3JlQmFja0ltYWdlID0gdHJ1ZTtcbiAgICB9XG4gICAgdGhpcy5sb2dEYXRhLlJlcXVlc3QgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHBheWxvYWQpKTtcblxuICAgIGNvbnNvbGUudGltZUVuZCgncGF5bG9hZCcpO1xuICAgIHRoaXMuX19zdWJzKFxuICAgICAgdGhpcy5zY2FuUHJvdmlkZXIuYmxhc3RQb3N0KHBheWxvYWQpLnBpcGUoXG4gICAgICAgIGNhdGNoRXJyb3IoKGU6IGFueSkgPT4ge1xuICAgICAgICAgIGlmICh0aGlzLm1hbnVhbERhdGFTZXQpIHtcbiAgICAgICAgICAgIC8vIGNvbnNvbGUud2FybignTUFOVUFMIERBVEEgU0VUJyxlKTtcbiAgICAgICAgICAgIHRoaXMubG9nRGF0YS5SZXNwb25zZSA9IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkoZS5lcnJvcikpO1xuXG4gICAgICAgICAgICB0aGlzLmhhbmRsZUV4dHJhY3Rpb25FcnJvcih7fSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdGhpcy56b25lLnJ1bigoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmVycm9yID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMucHJldmlldyA9IHRydWU7XG4gICAgICAgICAgICB0aGlzLmNkLmRldGVjdENoYW5nZXMoKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgICAvLyBjb25zb2xlLmxvZygnRUVFJywgZSk7XG4gICAgICAgICAgcmV0dXJuIGU7XG4gICAgICAgIH0pXG4gICAgICApXG4gICAgKS5zdWJzY3JpYmUoXG4gICAgICAoZGF0YTogYW55KSA9PiB7XG4gICAgICAgIC8vY29uc29sZS5sb2coZGF0YSk7XG4gICAgICAgIGNvbnN0IHJlc3VsdHMgPSBkYXRhLkRhdGE7XG4gICAgICAgIGNvbnNvbGUudGltZUVuZCgndXBsb2FkJyk7XG4gICAgICAgIGNvbnNvbGUudGltZSgncGFyc2UnKTtcbiAgICAgICAgLy8gZGF0YS5JbmZvQ29kZSA9ICcxMDAxJztcbiAgICAgICAgY29uc29sZS50aW1lKCdwJyk7XG4gICAgICAgIHRoaXMubG9nRGF0YS5SZXNwb25zZSA9IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkoZGF0YSkpO1xuICAgICAgICBjb25zb2xlLnRpbWVFbmQoJ3AnKTtcbiAgICAgICAgLy9sb2FkaW5nLmNsb3NlKCk7XG4gICAgICAgIHRoaXMuZG9jdW1lbnRUeXBlU2VsZWN0ZWQgPSB0cnVlO1xuICAgICAgICB0aGlzLnNjYW5pbmcgPSBmYWxzZTtcblxuICAgICAgICBpZiAoZGF0YS5JbmZvQ29kZSA9PT0gJzEwMDEnKSB7XG4gICAgICAgICAgdGhpcy5lcnJvciA9IHRydWU7XG4gICAgICAgICAgY29uc29sZS5sb2coJ1tFUlJPUl0gMTAwMScpO1xuICAgICAgICAgIHRoaXMuZXJyb3JDb2RlID0gJzEwMDEnO1xuICAgICAgICAgIC8vIHRoaXMuc2NhblNpZGUgPSAwO1xuXG4gICAgICAgICAgdGhpcy5wcmV2aWV3ID0gdHJ1ZTtcbiAgICAgICAgICB0aGlzLmNkLmRldGVjdENoYW5nZXMoKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGRhdGEuSW5mb0NvZGUgPT09ICcxMDAyJykge1xuICAgICAgICAgIHRoaXMuZXJyb3IgPSB0cnVlO1xuICAgICAgICAgIGNvbnNvbGUubG9nKCdbRVJST1JdIDEwMDInKTtcbiAgICAgICAgICB0aGlzLmVycm9yQ29kZSA9ICcxMDAyJztcbiAgICAgICAgICAvLyB0aGlzLnNjYW5TaWRlID0gMDtcblxuICAgICAgICAgIHRoaXMucHJldmlldyA9IHRydWU7XG4gICAgICAgICAgdGhpcy5jZC5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChyZXN1bHRzICYmIGRhdGEuTWV0YWRhdGEubGVuZ3RoID4gMCAmJiBkYXRhLkluZm9Db2RlID09PSAnMTAwMCcpIHtcbiAgICAgICAgICAvLyBjb25zb2xlLmxvZygnRXh0cmFjdGlvbiB0aW1lJywgZGF0YS5BbmFseXNpc1RpbWUpO1xuXG4gICAgICAgICAgLy8gIHRoaXMuem9uZS5ydW4oKCkgPT4ge1xuXG4gICAgICAgICAgLy8gY29uc29sZS50aW1lKCdwYXJzZWJsYXN0Jyk7XG4gICAgICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5zY2FuUHJvdmlkZXIucGFyc2VCbGFzdChyZXN1bHRzKTtcbiAgICAgICAgICAvLyBjb25zb2xlLnRpbWVFbmQoJ3BhcnNlYmxhc3QnKTtcbiAgICAgICAgICAvLyBjb25zb2xlLmxvZygnUkVTJywgdGhpcy5yZXN1bHQpO1xuICAgICAgICAgIC8vIHRoaXMuY2QuZGV0ZWN0Q2hhbmdlcygpO1xuXG4gICAgICAgICAgY29uc3QgbW9kZWwgPSByZXN1bHQubW9kZWw7XG5cbiAgICAgICAgICBpZiAoZGF0YS5JbWFnZURhdGE/LkZhY2VJbWFnZSkge1xuICAgICAgICAgICAgbW9kZWwuX2F2YXRhciA9XG4gICAgICAgICAgICAgICdkYXRhOmltYWdlL2pwZWc7YmFzZTY0LCcgKyBkYXRhLkltYWdlRGF0YT8uRmFjZUltYWdlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmIChkYXRhLkltYWdlRGF0YT8uRG9jdW1lbnRzKSB7XG4gICAgICAgICAgICBjb25zdCB7IERvY3VtZW50cyB9ID0gZGF0YS5JbWFnZURhdGE7XG4gICAgICAgICAgICBtb2RlbC5pbWFnZXMgPSBEb2N1bWVudHMubWFwKChpbWFnZTogYW55LCBpOiBudW1iZXIpID0+IHtcbiAgICAgICAgICAgICAgcmV0dXJuIHsgZGF0YTogJ2RhdGE6aW1hZ2UvanBlZztiYXNlNjQsJyArIERvY3VtZW50c1tpXSB9O1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMubW9kZWwgPSBtb2RlbDtcbiAgICAgICAgICAvLyBjb25zb2xlLmxvZygnTU9ERUwnLCB0aGlzLm1vZGVsKTtcbiAgICAgICAgICB0aGlzLmFjdGlvbnMuZW1pdCh7XG4gICAgICAgICAgICB0eXBlOiAnc2NhbkZpbmlzaCcsXG4gICAgICAgICAgICBkYXRhOiB7XG4gICAgICAgICAgICAgIG1vZGVsOiB0aGlzLm1vZGVsLFxuICAgICAgICAgICAgICBpbWFnZXM6IHRoaXMuaW1hZ2VzLFxuICAgICAgICAgICAgICByZXN1bHRzLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIGlmICghdGhpcy5zY2FuUHJvdmlkZXIuY29uZmlnLmhpZGVSZXN1bHRzKSB7XG4gICAgICAgICAgICB0aGlzLnpvbmUucnVuKCgpID0+IHtcbiAgICAgICAgICAgICAgdGhpcy5yZXN1bHQgPSB0cnVlO1xuICAgICAgICAgICAgICAvLyBjb25zb2xlLnRpbWUoJ2ZmJyk7XG4gICAgICAgICAgICAgIHRoaXMuY2QuZGV0ZWN0Q2hhbmdlcygpO1xuXG4gICAgICAgICAgICAgIHRoaXMuc2NhblJlc3VsdHMubmV4dCh7IHR5cGU6ICdtb2RlbCcsIGRhdGE6IG1vZGVsIH0pO1xuICAgICAgICAgICAgICAvLyB0aGlzLmNkLmRldGVjdENoYW5nZXMoKTtcbiAgICAgICAgICAgICAgLy8gIH0pO1xuICAgICAgICAgICAgICAvLyBjb25zb2xlLnRpbWVFbmQoJ2ZmJyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc29sZS5sb2coJ0VSUk9SJyk7XG4gICAgICAgICAgaWYgKHRoaXMubWFudWFsRGF0YVNldCkge1xuICAgICAgICAgICAgdGhpcy5oYW5kbGVFeHRyYWN0aW9uRXJyb3IoZGF0YSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIHRoaXMuc2NhblNpZGUgPSAwO1xuICAgICAgICAgIHRoaXMuem9uZS5ydW4oKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5lcnJvciA9IHRydWU7XG4gICAgICAgICAgICB0aGlzLnByZXZpZXcgPSB0cnVlO1xuICAgICAgICAgICAgdGhpcy5jZC5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgLy8gdGhpcy5kb2N1bWVudFR5cGVTZWxlY3RlZCA9IGZhbHNlO1xuXG4gICAgICAgICAgLy8gdGhpcy5yZXRyeSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gdGhpcy5jZC5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICAgIGNvbnNvbGUudGltZUVuZCgncGFyc2UnKTtcbiAgICAgIH0sXG4gICAgICAoZXJyKSA9PiB7XG4gICAgICAgIC8vIGxvYWRpbmcuY2xvc2UoKTtcbiAgICAgICAgLy8gdGhpcy5zY2FuU2lkZSA9IDA7XG4gICAgICAgIHRoaXMuZXJyb3IgPSB0cnVlO1xuICAgICAgICB0aGlzLnByZXZpZXcgPSB0cnVlO1xuICAgICAgICB0aGlzLmRvY3VtZW50VHlwZVNlbGVjdGVkID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5zY2FuaW5nID0gZmFsc2U7XG4gICAgICB9XG4gICAgKTtcbiAgfVxuXG4gIHJldHJ5KCkge1xuICAgIHRoaXMucHJldmlldyA9IGZhbHNlO1xuICAgIHRoaXMudmFsaWRhdGlvbiA9IGZhbHNlO1xuICAgIHRoaXMuZXJyb3JDb2RlID0gJzEwMDAnO1xuICAgIHRoaXMucmVzdWx0ID0gZmFsc2U7XG4gICAgdGhpcy5pZFNjYW4gPSBudWxsO1xuICAgIHRoaXMuY2FtZXJhUHJvdmlkZXIuJHNob3dTd2l0Y2gubmV4dCh0cnVlKTtcbiAgICBpZiAodGhpcy5lcnJvcikge1xuICAgICAgdGhpcy5kb2N1bWVudFR5cGVTZWxlY3RlZCA9IGZhbHNlO1xuICAgICAgdGhpcy5zY2FuQmxhc3REYXRhLmZvckVhY2goKGVsZW1lbnQ6IGFueSkgPT4ge1xuICAgICAgICBlbGVtZW50LmltYWdlID0gbnVsbDtcbiAgICAgIH0pO1xuICAgIH1cbiAgICB0aGlzLmVycm9yID0gZmFsc2U7XG4gICAgdGhpcy5zdGFydFRpbWUgPSBEYXRlLm5vdygpO1xuICAgIHRoaXMuYXV0b1NjYW4oKTtcbiAgICB0aGlzLnNjYW4oKTtcbiAgICB0aGlzLmNkLmRldGVjdENoYW5nZXMoKTtcbiAgfVxuXG4gIHB1YmxpYyByZXRha2UoKSB7XG4gICAgdGhpcy52YWxpZGF0aW9uID0gZmFsc2U7XG4gICAgdGhpcy5wcmV2aWV3ID0gZmFsc2U7XG4gICAgdGhpcy5lcnJvciA9IGZhbHNlO1xuICAgIHRoaXMucmVzdWx0ID0gZmFsc2U7XG4gICAgdGhpcy5zY2FuU2lkZSA9IDA7XG4gICAgdGhpcy5jYW1lcmFQcm92aWRlci4kc2hvd1N3aXRjaC5uZXh0KHRydWUpO1xuICAgIHRoaXMuaW1hZ2VWZXJpZmllZCA9IGZhbHNlO1xuICAgIHRoaXMuc2NhbkRhdGFzID0gW107XG4gICAgdGhpcy5zY2FuaW5nID0gZmFsc2U7XG4gICAgdGhpcy5pbWFnZXMgPSBbXTtcbiAgICB0aGlzLnNjYW5JblByb2dyZXNzID0gZmFsc2U7XG4gICAgdGhpcy5zdGFydFRpbWUgPSBEYXRlLm5vdygpO1xuICAgIHRoaXMuaWRTY2FuID0gbnVsbDtcbiAgICB0aGlzLmRvY3VtZW50VHlwZVNlbGVjdGVkID0gZmFsc2U7XG4gICAgdGhpcy5zY2FuQmxhc3REYXRhLmZvckVhY2goKG06IGFueSkgPT4ge1xuICAgICAgbS5pbWFnZSA9IG51bGw7XG4gICAgfSk7XG5cbiAgICB0aGlzLnNjYW5TZWNvbmRTaWRlID0gZmFsc2U7XG5cbiAgICB0aGlzLmF1dG9TY2FuKCk7XG5cbiAgICB0aGlzLmNkLmRldGVjdENoYW5nZXMoKTtcbiAgfVxuXG4gIHVzZSgpIHtcbiAgICAvLyBzYXZlIGltYWdlcz8/XG5cbiAgICAvLyBpZiAodGhpcy5zY2FuUHJvdmlkZXIuY29uZmlnLnNlbmRMb2cpIHtcbiAgICAvLyAgIHRoaXMubG9nRGF0YS5FeHBlY3RlZE91dHB1dCA9IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkodGhpcy5tb2RlbCkpO1xuICAgIC8vICAgaWYgKHRoaXMubG9nRGF0YS5FeHBlY3RlZE91dHB1dD8uX2F2YXRhcikge1xuICAgIC8vICAgICBkZWxldGUgdGhpcy5sb2dEYXRhLkV4cGVjdGVkT3V0cHV0Ll9hdmF0YXI7XG4gICAgLy8gICB9XG4gICAgLy8gIC8vIHRoaXMuX19zdWJzKHRoaXMuc2NhblByb3ZpZGVyLnNlbmRMb2codGhpcy5sb2dEYXRhKSkuc3Vic2NyaWJlKCk7XG4gICAgLy8gICBjb25zb2xlLmxvZyh0aGlzLmxvZ0RhdGEpO1xuICAgIC8vIH1cblxuICAgIHRoaXMuYWN0aW9ucy5lbWl0KHtcbiAgICAgIHR5cGU6ICdzY2FuRGF0YUNsb3NlJyxcbiAgICAgIGRhdGE6IHtcbiAgICAgICAgbW9kZWw6IHRoaXMubW9kZWwsXG4gICAgICAgIGltYWdlczogdGhpcy5pbWFnZXMsXG4gICAgICB9LFxuICAgIH0pO1xuICB9XG4gIHNlbGZpZSgpIHtcbiAgICBjb25zdCBhdmF0YXIgPSB0aGlzLm1vZGVsPy5fYXZhdGFyO1xuICAgIHRoaXMuZGlhbG9nc1xuICAgICAgLnNjYW5TZWxmaWUoeyBhdmF0YXIgfSlcbiAgICAgIC5hZnRlckNsb3NlZCgpXG4gICAgICAuc3Vic2NyaWJlKChyZXNwOiBhbnkpID0+IHtcbiAgICAgICAgaWYgKHJlc3ApIHtcbiAgICAgICAgICBjb25zb2xlLmxvZyhyZXNwKTtcbiAgICAgICAgICBpZiAodGhpcy5zY2FuUHJvdmlkZXIuZW5hYmxlVmVyaWZpY2F0aW9uKSB7XG4gICAgICAgICAgICB0aGlzLmltYWdlVmVyaWZpZWQgPSB0cnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzLnNjYW5SZXN1bHRzLm5leHQoe1xuICAgICAgICAgICAgdHlwZTogJ2F2YXRhcicsXG4gICAgICAgICAgICBkYXRhOiByZXNwLmltYWdlQXNEYXRhVXJsLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIC8vIHRoaXMubW9kZWwuX2F2YXRhciA9IHJlc3AuaW1hZ2VBc0RhdGFVcmw7XG4gICAgICAgICAgdGhpcy5jZC5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICB9XG5cbiAgY2FtZXJhT2ZmKGV2OiBhbnkpIHtcbiAgICB0aGlzLmNhbWVyYVJlYWR5ID0gZmFsc2U7XG4gICAgdGhpcy5jZC5kZXRlY3RDaGFuZ2VzKCk7XG4gIH1cblxuICB2aWRlb1JlYWR5KGV2ZW50OiBib29sZWFuKSB7XG4gICAgY29uc29sZS5sb2coJ1JFQURZJywgZXZlbnQpO1xuICAgIHRoaXMuY2FtZXJhUmVhZHkgPSBldmVudDtcbiAgICBpZiAodGhpcy5jYW1lcmFSZWFkeSAmJiAhdGhpcy5zY2FuSW5Qcm9ncmVzcyAmJiAhdGhpcy5tYW51YWwpIHtcbiAgICAgIHRoaXMuc2NhbkluUHJvZ3Jlc3MgPSB0cnVlO1xuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIHRoaXMuc2NhbigpO1xuICAgICAgfSwgMjApO1xuICAgIH1cbiAgfVxuXG4gIG1hbnVhbFNldChrZXk6IGJvb2xlYW4pIHtcbiAgICBpZiAoa2V5KSB7XG4gICAgICBpZiAodGhpcy5zY2FuUHJvdmlkZXIuY29uZmlnLnNob3dNYW51YWxNb2RlKSB7XG4gICAgICAgIHRoaXMubWFudWFsTW9kZSgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5hY3Rpb25zLmVtaXQoe1xuICAgICAgICAgIHR5cGU6ICdtYW51YWxNb2RlJyxcbiAgICAgICAgICBkYXRhOiB7fSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucHJvbXB0TWFudWFsID0gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuc2NhblRpbWVvdXQpIHtcbiAgICAgIGNsZWFyVGltZW91dCh0aGlzLnNjYW5UaW1lb3V0KTtcbiAgICB9XG4gICAgaWYgKHRoaXMuaW1hZ2VIYW5kbGVyU3Vic2NyaXB0aW9uKSB7XG4gICAgICB0aGlzLmltYWdlSGFuZGxlclN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICAgIH1cblxuICAgIGNvbnNvbGUubG9nKCdERVNUUk9YWScpO1xuXG4gICAgdGhpcy5fX2Rlc3Ryb3koKTtcbiAgfVxufVxuIiwiPG5nLWNvbnRhaW5lclxuICAqbmdJZj1cImNhbWVyYVByb3ZpZGVyLnJlY3RQb3NpdGlvbi50ID4gMCAmJiBkaXNwbGF5SW5mbyAmJiAhcmVzdWx0ICYmICFtYW51YWxcIlxuPlxuICA8ZGl2IGNsYXNzPVwiaGludFwiIFtuZ1N0eWxlXT1cInsgdG9wOiBjYW1lcmFQcm92aWRlci5oaW50UG9zaXRpb24gKyAncHgnIH1cIj5cbiAgICA8c3BhbiBjbGFzcz1cInRleHRcIj5cbiAgICAgIHt7IGRpc3BsYXlJbmZvIHwgdHJhbnNsYXRlIH19XG4gICAgPC9zcGFuPlxuICA8L2Rpdj5cbjwvbmctY29udGFpbmVyPlxuXG48bmctY29udGFpbmVyICpuZ0lmPVwic2hvd0RpYWxvZ1wiPlxuICA8ZGl2IGNsYXNzPVwicGFnZVR1cm5cIj5cbiAgICA8ZGl2IGNsYXNzPVwiY29udGVudFwiPlxuICAgICAgPGRpdiBjbGFzcz1cImlubmVyXCI+XG4gICAgICAgIDxtYXQtaWNvbj4zNjA8L21hdC1pY29uPlxuICAgICAgICA8ZGl2IGNsYXNzPVwidGV4dFwiPlxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpZFNjYW4gPT09ICdCQUNLJ1wiPlxuICAgICAgICAgICAge3sgXCJzY2FuZG9jLnR1cm5BbmRDYXB0dXJlLmJhY2tcIiB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpZFNjYW4gPT09ICdGUk9OVCdcIj5cbiAgICAgICAgICAgIHt7IFwic2NhbmRvYy50dXJuQW5kQ2FwdHVyZS5mcm9udFwiIHwgdHJhbnNsYXRlIH19XG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgICA8Zm9vdGVyPlxuICAgICAgICA8YnV0dG9uIChjbGljayk9XCJjbG9zZURpYWxvZygpXCIgbWF0LXJhaXNlZC1idXR0b24+T2s8L2J1dHRvbj5cbiAgICAgIDwvZm9vdGVyPlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbjwvbmctY29udGFpbmVyPlxuXG48bmctY29udGFpbmVyICpuZ0lmPVwicHJvbXB0TWFudWFsXCI+XG4gIDxkaXYgY2xhc3M9XCJtYW51YWxNb2RlXCI+XG4gICAgPGRpdiBjbGFzcz1cImNvbnRlbnRcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJpbm5lclwiPlxuICAgICAgICA8bWF0LWljb24+c2NyZWVuc2hvdDwvbWF0LWljb24+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0XCI+XG4gICAgICAgICAge3sgXCJzY2FuZG9jLm1hbnVhbFwiIHwgdHJhbnNsYXRlIH19XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgICA8Zm9vdGVyPlxuICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgc3R5bGU9XCJtYXJnaW4tcmlnaHQ6IDhweFwiXG4gICAgICAgICAgKGNsaWNrKT1cIm1hbnVhbFNldCh0cnVlKVwiXG4gICAgICAgICAgbWF0LXJhaXNlZC1idXR0b25cbiAgICAgICAgPlxuICAgICAgICAgIHt7IFwic2NhbmRvYy55ZXNcIiB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPGJ1dHRvblxuICAgICAgICAgIHN0eWxlPVwibWFyZ2luLWxlZnQ6IDhweFwiXG4gICAgICAgICAgKGNsaWNrKT1cIm1hbnVhbFNldChmYWxzZSlcIlxuICAgICAgICAgIG1hdC1yYWlzZWQtYnV0dG9uXG4gICAgICAgID5cbiAgICAgICAgICB7eyBcInNjYW5kb2Mubm9cIiB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgIDwvZm9vdGVyPlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbjwvbmctY29udGFpbmVyPlxuPG5nLWNvbnRhaW5lciAqbmdJZj1cInJlc3VsdFwiPlxuICA8c2VjdGlvbj5cbiAgICA8bmd4LXNjYW4tcmVzdWx0c1xuICAgICAgKGFjdGlvbik9XCJzZWxmaWUoKVwiXG4gICAgICBbZm9ybV09XCJmb3JtXCJcbiAgICAgIFtkYXRhXT1cInNjYW5SZXN1bHRzXCJcbiAgICA+PC9uZ3gtc2Nhbi1yZXN1bHRzPlxuXG4gICAgPGZvb3Rlcj5cbiAgICAgIDxkaXYgY2xhc3M9XCJhY3Rpb25zXCI+XG4gICAgICAgIDxidXR0b24gY2xhc3M9XCJtci00XCIgbWF0LXJhaXNlZC1idXR0b24gKGNsaWNrKT1cInJldGFrZSgpXCI+XG4gICAgICAgICAge3sgXCJzY2FuZG9jLnJlVGFrZVwiIHwgdHJhbnNsYXRlIH19XG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgW2Rpc2FibGVkXT1cImVycm9yIHx8IGZvcm0uaW52YWxpZFwiXG4gICAgICAgICAgY2xhc3M9XCJtbC00XCJcbiAgICAgICAgICBtYXQtcmFpc2VkLWJ1dHRvblxuICAgICAgICAgIChjbGljayk9XCJ1c2UoKVwiXG4gICAgICAgID5cbiAgICAgICAgICB7eyBcInNjYW5kb2MudXNlRGF0YVwiIHwgdHJhbnNsYXRlIH19XG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG4gICAgPC9mb290ZXI+XG4gIDwvc2VjdGlvbj5cbjwvbmctY29udGFpbmVyPlxuXG48bmctY29udGFpbmVyICpuZ0lmPVwibWFudWFsXCI+XG4gIDxzZWN0aW9uPlxuICAgIDxuZ3gtbWFudWFsLXNjYW4gKGFjdGlvbik9XCJtYW51YWxTY2FuRGF0YSgkZXZlbnQpXCI+PC9uZ3gtbWFudWFsLXNjYW4+XG4gIDwvc2VjdGlvbj5cbjwvbmctY29udGFpbmVyPlxuPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFyZXN1bHQgJiYgZG9jdW1lbnRUeXBlU2VsZWN0ZWQgJiYgIW1hbnVhbFwiPlxuICA8c2VjdGlvbj5cbiAgICA8ZGl2ICN3cmFwZXIgY2xhc3M9XCJ3cmFwZXJcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJsb2FkaW5nXCIgKm5nSWY9XCIoIWNhbWVyYVJlYWR5ICYmICFwcmV2aWV3KSB8fCBzY2FuaW5nXCI+XG4gICAgICAgIDxtYXQtcHJvZ3Jlc3MtYmFyIG1vZGU9XCJpbmRldGVybWluYXRlXCI+PC9tYXQtcHJvZ3Jlc3MtYmFyPlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhZXJyb3JcIj5cbiAgICAgICAgPG5neC1zY2FuZG9jLXdlYmNhbVxuICAgICAgICAgICpuZ0lmPVwiIXByZXZpZXcgJiYgIXNjYW5pbmdcIlxuICAgICAgICAgIGNsYXNzPVwibWFpblwiXG4gICAgICAgICAgI3dlYmNhbVxuICAgICAgICAgIHR5cGU9XCJkb2N1bWVudFwiXG4gICAgICAgICAgW3RyaWdnZXJdPVwidHJpZ2dlclwiXG4gICAgICAgICAgW2ltYWdlSGFuZGxlcl09XCJpbWFnZUhhbmRsZXJcIlxuICAgICAgICAgIChpbWFnZUNhcHR1cmUpPVwiaGFuZGxlSW1hZ2UoJGV2ZW50KVwiXG4gICAgICAgICAgKGluaXRFcnJvcik9XCJoYW5kbGVJbml0RXJyb3IoJGV2ZW50KVwiXG4gICAgICAgICAgKGRlc3Ryb3llZCk9XCJjYW1lcmFPZmYoJGV2ZW50KVwiXG4gICAgICAgICAgKHZpZGVvUmVhZHkpPVwidmlkZW9SZWFkeSgkZXZlbnQpXCJcbiAgICAgICAgPlxuICAgICAgICA8L25neC1zY2FuZG9jLXdlYmNhbT5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgPGRpdlxuICAgICAgICBjbGFzcz1cInByZXZpZXdEYXRhXCJcbiAgICAgICAgKm5nSWY9XCJwcmV2aWV3XCJcbiAgICAgICAgc3R5bGU9XCJcbiAgICAgICAgICB6LWluZGV4OiAyMDtcbiAgICAgICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICAgICAgICB3aWR0aDogMTAwJTtcbiAgICAgICAgICBoZWlnaHQ6IDEwMCU7XG4gICAgICAgIFwiXG4gICAgICA+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJwLTE2IGVycm9yXCIgKm5nSWY9XCJlcnJvclwiPlxuICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGl0bGVcIj5cbiAgICAgICAgICAgICAgPG1hdC1pY29uPmVycm9yX291dGxpbmU8L21hdC1pY29uXG4gICAgICAgICAgICAgID48c3BhbiBjbGFzcz1cIm1sLThcIj57e1xuICAgICAgICAgICAgICAgIFwic2NhbmRvYy51bmFibGVUb0RldGVjdElkXCIgfCB0cmFuc2xhdGVcbiAgICAgICAgICAgICAgfX08L3NwYW4+XG4gICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImVycm9yQ29kZSA9PT0gJzEwMDEnXCI+XG4gICAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgICAge3sgXCJzY2FuZG9jLmV4dHJhY3Rpb24uYzEwMDFcIiB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImVycm9yQ29kZSA9PT0gJzEwMDInXCI+XG4gICAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgICAge3sgXCJzY2FuZG9jLmV4dHJhY3Rpb24uYzEwMDJcIiB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgICAgICA8dWwgKm5nSWY9XCJlcnJvckNvZGUgPT09ICcxMDAwJ1wiPlxuICAgICAgICAgICAgICA8bGk+XG4gICAgICAgICAgICAgICAge3sgXCJzY2FuZG9jLnBsYWNlSWRDbG9zZVRvRGV2aWNlXCIgfCB0cmFuc2xhdGUgfX1cbiAgICAgICAgICAgICAgPC9saT5cbiAgICAgICAgICAgICAgPGxpPlxuICAgICAgICAgICAgICAgIHt7IFwic2NhbmRvYy5lbnN1cmVTdWZmaWNpZW50TGlnaHRcIiB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICAgICAgICA8L2xpPlxuICAgICAgICAgICAgICA8bGk+XG4gICAgICAgICAgICAgICAge3sgXCJzY2FuZG9jLmhvbGREb2N1bWVudFN0ZWFkeVwiIHwgdHJhbnNsYXRlIH19XG4gICAgICAgICAgICAgIDwvbGk+XG4gICAgICAgICAgICAgIDxsaT5cbiAgICAgICAgICAgICAgICB7eyBcInNjYW5kb2MubWFrZVN1cmVBbGxFZGdlc09mVGhlSWRBcmVWaXNpYmxlXCIgfCB0cmFuc2xhdGUgfX1cbiAgICAgICAgICAgICAgPC9saT5cbiAgICAgICAgICAgICAgPGxpPlxuICAgICAgICAgICAgICAgIHt7XG4gICAgICAgICAgICAgICAgICBcInNjYW5kb2MubWFrZVN1cmVUaGVyZUFyZU5vR2xhcmVBbmRTaGFkb3dzT25UaGVJZFwiIHwgdHJhbnNsYXRlXG4gICAgICAgICAgICAgICAgfX1cbiAgICAgICAgICAgICAgPC9saT5cbiAgICAgICAgICAgIDwvdWw+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDxkaXYgY2xhc3M9XCJzY2FuUHJldmlld1wiICpuZ0lmPVwiIWVycm9yICYmICFzY2FuaW5nXCI+XG4gICAgICAgICAgPCEtLSA8ZGl2IGNsYXNzPVwicHktMTZcIiBzdHlsZT1cImZvbnQtc2l6ZTogMTZweFwiPlxuICAgICAgICAgIHt7XG4gICAgICAgICAgICBcInNjYW5kb2MuZW5zdXJlQWxsVGV4dHNBcmVWaXNpYmxlXCJcbiAgICAgICAgICAgICAgfCB0cmFuc2xhdGVcbiAgICAgICAgICB9fVxuICAgICAgICA8L2Rpdj4gLS0+XG4gICAgICAgICAgPGRpdlxuICAgICAgICAgICAgY2xhc3M9XCJpbWFnZVwiXG4gICAgICAgICAgICBbc3R5bGUuYmFja2dyb3VuZC1pbWFnZV09XCIndXJsKCcgKyBwcmV2aWV3ICsgJyknXCJcbiAgICAgICAgICA+PC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG5cbiAgICA8Zm9vdGVyICpuZ0lmPVwicHJldmlld1wiPlxuICAgICAgPCEtLSA8ZGl2IGNsYXNzPVwiZGlzcGxheUluZm9cIiAqbmdJZj1cIiFwcmV2aWV3ICYmIGNhbWVyYVJlYWR5XCI+XG4gICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZGlzcGxheUluZm9cIj5cbiAgICAgICAge3sgZGlzcGxheUluZm8gfCB0cmFuc2xhdGUgfX1cbiAgICAgIDwvbmctY29udGFpbmVyPlxuICAgIDwvZGl2PiAtLT5cbiAgICAgIDwhLS0gPGRpdiBzdHlsZT1cImhlaWdodDogMjZweFwiPlxuICAgICAgPGRpdlxuICAgICAgICBzdHlsZT1cInRleHQtYWxpZ246IGNlbnRlcjsgZm9udC1zaXplOiAxOHB4XCJcbiAgICAgICAgKm5nSWY9XCJpZFNjYW4gJiYgIXByZXZpZXcgJiYgY2FtZXJhUmVhZHlcIlxuICAgICAgPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaWRTY2FuID09PSAnQkFDSydcIj5cbiAgICAgICAgICBUdXJuIGRvY3VtZW50IGFuZDpcbiAgICAgICAgICB7eyBcInNjYW5kb2MuY2FwdHVyZUJhY2tcIiB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImlkU2NhbiA9PT0gJ0ZST05UJ1wiPlxuICAgICAgICAgIFR1cm4gZG9jdW1lbnQgYW5kOlxuICAgICAgICAgIHt7IFwic2NhbmRvYy5jYXB0dXJlRnJvbnRcIiB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PiAtLT5cblxuICAgICAgPGRpdiBjbGFzcz1cImFjdGlvbnNcIiAqbmdJZj1cInByZXZpZXdcIj5cbiAgICAgICAgPGJ1dHRvbiBjbGFzcz1cIm1yLTRcIiBtYXQtcmFpc2VkLWJ1dHRvbiAoY2xpY2spPVwicmV0cnkoKVwiPlxuICAgICAgICAgIHt7IFwic2NhbmRvYy5yZXRyeVwiIHwgdHJhbnNsYXRlIH19XG4gICAgICAgIDwvYnV0dG9uPlxuXG4gICAgICAgIDxidXR0b25cbiAgICAgICAgICBbZGlzYWJsZWRdPVwiZXJyb3JcIlxuICAgICAgICAgIGNsYXNzPVwibWwtNFwiXG4gICAgICAgICAgbWF0LXJhaXNlZC1idXR0b25cbiAgICAgICAgICAoY2xpY2spPVwiY29udGludWUoKVwiXG4gICAgICAgID5cbiAgICAgICAgICB7eyBcInNjYW5kb2MuY29udGludWVXaXRoU2VsZWN0ZWRJbWFnZVwiIHwgdHJhbnNsYXRlIH19XG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG4gICAgPC9mb290ZXI+XG4gIDwvc2VjdGlvbj5cbjwvbmctY29udGFpbmVyPlxuIl19
|