ngx-scandoc 18.0.3 → 19.0.1
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/fesm2022/ngx-scandoc.mjs +128 -127
- package/fesm2022/ngx-scandoc.mjs.map +1 -1
- package/package.json +9 -11
- package/esm2022/core/app.worker.mjs +0 -236
- package/esm2022/core/components/base.component.mjs +0 -15
- package/esm2022/core/components/camera-switch/camera-switch.component.mjs +0 -25
- package/esm2022/core/components/components.module.mjs +0 -69
- package/esm2022/core/components/manual-scan/manual-scan.component.mjs +0 -290
- package/esm2022/core/components/scan/scan.component.mjs +0 -732
- package/esm2022/core/components/scan-results/scan-results.component.mjs +0 -65
- package/esm2022/core/components/webcam/domain/webcam-image.mjs +0 -58
- package/esm2022/core/components/webcam/domain/webcam-init-error.mjs +0 -3
- package/esm2022/core/components/webcam/domain/webcam-mirror-properties.mjs +0 -3
- package/esm2022/core/components/webcam/util/webcam.util.mjs +0 -50
- package/esm2022/core/components/webcam/webcam/webcam.component.mjs +0 -543
- package/esm2022/core/components/webcam/webcam.module.mjs +0 -29
- package/esm2022/core/helpers/object-utils.mjs +0 -100
- package/esm2022/core/interfaces/config.mjs +0 -2
- package/esm2022/core/interfaces/guest.data.mjs +0 -2
- package/esm2022/core/pipes/pipes.module.mjs +0 -19
- package/esm2022/core/pipes/safeResourceUrl.pipe.mjs +0 -20
- package/esm2022/core/shared/material.module.mjs +0 -162
- package/esm2022/core/tokens/config.tokens.mjs +0 -4
- package/esm2022/dialogs/components/blank/blank.component.mjs +0 -46
- package/esm2022/dialogs/components/confirm/confirm.component.mjs +0 -51
- package/esm2022/dialogs/components/loading/loading.component.mjs +0 -12
- package/esm2022/dialogs/components/prompt-manual/prompt-manual.component.mjs +0 -30
- package/esm2022/dialogs/components/scan-profile/scan-profile.component.mjs +0 -79
- package/esm2022/dialogs/components/scan-selfie/scan-selfie.component.mjs +0 -95
- package/esm2022/dialogs/components/turn-document/turn-document.component.mjs +0 -31
- package/esm2022/dialogs/dialogs.core.provider.mjs +0 -120
- package/esm2022/dialogs/dialogs.module.mjs +0 -102
- package/esm2022/forms/form.module.mjs +0 -87
- package/esm2022/forms/types/avatar.type.mjs +0 -58
- package/esm2022/forms/types/profile.image.type.mjs +0 -64
- package/esm2022/forms/types/title.type.mjs +0 -32
- package/esm2022/lib/ngx-scandoc.module.mjs +0 -44
- package/esm2022/ngx-scandoc.mjs +0 -5
- package/esm2022/providers/auth.provider.mjs +0 -113
- package/esm2022/providers/camera.provider.mjs +0 -87
- package/esm2022/providers/interceptor.provider.mjs +0 -77
- package/esm2022/providers/layout.provider.mjs +0 -30
- package/esm2022/providers/scan.form.mjs +0 -347
- package/esm2022/providers/scan.provider.mjs +0 -756
- package/esm2022/providers/translate-loader.provider.mjs +0 -126
- package/esm2022/providers/translation.provider.mjs +0 -133
- package/esm2022/providers/webrtc.provider.mjs +0 -58
- package/esm2022/public-api.mjs +0 -33
|
@@ -1,543 +0,0 @@
|
|
|
1
|
-
import { ChangeDetectionStrategy, Component, EventEmitter, HostListener, Input, Output, ViewChild, } from '@angular/core';
|
|
2
|
-
import { WebcamImage } from '../domain/webcam-image';
|
|
3
|
-
import { from } from 'rxjs';
|
|
4
|
-
import { BaseComponent } from '../../base.component';
|
|
5
|
-
import * as i0 from "@angular/core";
|
|
6
|
-
import * as i1 from "@angular/cdk/layout";
|
|
7
|
-
import * as i2 from "@angular/cdk/platform";
|
|
8
|
-
import * as i3 from "../../../../providers/camera.provider";
|
|
9
|
-
import * as i4 from "@angular/common";
|
|
10
|
-
export class WebcamComponent extends BaseComponent {
|
|
11
|
-
onResize() {
|
|
12
|
-
this.cameraProvider.rectPosition.t = 0;
|
|
13
|
-
// this.videoReady.next(false);
|
|
14
|
-
if (this.resizeTimeout) {
|
|
15
|
-
clearTimeout(this.resizeTimeout);
|
|
16
|
-
}
|
|
17
|
-
this.resizeTimeout = setTimeout(() => {
|
|
18
|
-
this.drawRectangle();
|
|
19
|
-
}, 1000);
|
|
20
|
-
}
|
|
21
|
-
constructor(breakpointObserver, platform, cd, zone, cameraProvider) {
|
|
22
|
-
super();
|
|
23
|
-
this.breakpointObserver = breakpointObserver;
|
|
24
|
-
this.platform = platform;
|
|
25
|
-
this.cd = cd;
|
|
26
|
-
this.zone = zone;
|
|
27
|
-
this.cameraProvider = cameraProvider;
|
|
28
|
-
this.canvasSize = { width: 0, height: 0 };
|
|
29
|
-
this.showVideo = false;
|
|
30
|
-
this.setupAttempt = 0;
|
|
31
|
-
this.canvasData = {
|
|
32
|
-
ctx: null,
|
|
33
|
-
ctxO: null,
|
|
34
|
-
};
|
|
35
|
-
this.chunks = [];
|
|
36
|
-
this.cameraSwitched = new EventEmitter();
|
|
37
|
-
this.videoReady = new EventEmitter();
|
|
38
|
-
this.imageCapture = new EventEmitter();
|
|
39
|
-
this.initError = new EventEmitter();
|
|
40
|
-
}
|
|
41
|
-
ngAfterViewInit() {
|
|
42
|
-
console.warn('[video] start');
|
|
43
|
-
// initial load
|
|
44
|
-
this.__subs(this.cameraProvider.getDevices()).subscribe((resp) => {
|
|
45
|
-
this.init();
|
|
46
|
-
});
|
|
47
|
-
if (this.refresh) {
|
|
48
|
-
this.__subs(this.refresh).subscribe(() => {
|
|
49
|
-
if (this.resizeTimeout) {
|
|
50
|
-
clearTimeout(this.resizeTimeout);
|
|
51
|
-
}
|
|
52
|
-
this.resizeTimeout = setTimeout(() => {
|
|
53
|
-
this.drawRectangle();
|
|
54
|
-
}, 50);
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
// camera switch
|
|
58
|
-
this.__subs(this.cameraProvider.webcamObservable).subscribe((device) => {
|
|
59
|
-
const videoTrackConstraints = this.setConstraints();
|
|
60
|
-
this.stopAllTracks();
|
|
61
|
-
this.showVideo = false;
|
|
62
|
-
this.cd.detectChanges();
|
|
63
|
-
videoTrackConstraints.deviceId = device;
|
|
64
|
-
this.setup(videoTrackConstraints);
|
|
65
|
-
});
|
|
66
|
-
this.__subs(this.trigger).subscribe((time) => this.takeSnapshot(time));
|
|
67
|
-
}
|
|
68
|
-
get video() {
|
|
69
|
-
return this.videoRef.nativeElement;
|
|
70
|
-
}
|
|
71
|
-
get isMobile() {
|
|
72
|
-
return this.platform.ANDROID || this.platform.IOS;
|
|
73
|
-
}
|
|
74
|
-
setConstraints() {
|
|
75
|
-
const out = {};
|
|
76
|
-
console.warn('MOBILE', this.isMobile);
|
|
77
|
-
switch (this.type) {
|
|
78
|
-
default:
|
|
79
|
-
if (this.isMobile) {
|
|
80
|
-
out.video = { height: { ideal: 1600 }, width: { ideal: 1600 } };
|
|
81
|
-
out.video.facingMode = 'environment';
|
|
82
|
-
}
|
|
83
|
-
else {
|
|
84
|
-
out.video = {
|
|
85
|
-
width: {
|
|
86
|
-
min: 1280,
|
|
87
|
-
ideal: 1920,
|
|
88
|
-
max: 2900,
|
|
89
|
-
},
|
|
90
|
-
height: {
|
|
91
|
-
min: 720,
|
|
92
|
-
ideal: 1080,
|
|
93
|
-
max: 2900,
|
|
94
|
-
},
|
|
95
|
-
};
|
|
96
|
-
}
|
|
97
|
-
break;
|
|
98
|
-
case 'selfie':
|
|
99
|
-
if (this.isMobile) {
|
|
100
|
-
out.video = { height: { ideal: 1600 }, width: { ideal: 1600 } };
|
|
101
|
-
out.video.facingMode = 'user';
|
|
102
|
-
}
|
|
103
|
-
else {
|
|
104
|
-
out.video = {
|
|
105
|
-
frameRate: { min: 10 },
|
|
106
|
-
height: { ideal: 1080 },
|
|
107
|
-
width: { ideal: 1920 },
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
break;
|
|
111
|
-
}
|
|
112
|
-
return out.video;
|
|
113
|
-
}
|
|
114
|
-
get activeTrackSettings() {
|
|
115
|
-
return this.mediaStream.getVideoTracks()[0].getSettings();
|
|
116
|
-
}
|
|
117
|
-
get activeTrackCapabilities() {
|
|
118
|
-
try {
|
|
119
|
-
return this.mediaStream.getVideoTracks()[0].getCapabilities();
|
|
120
|
-
}
|
|
121
|
-
catch (e) {
|
|
122
|
-
return {};
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
init() {
|
|
126
|
-
this.__subs(this.cameraProvider.getDevices()).subscribe((resp) => {
|
|
127
|
-
console.warn('DEVICES', resp);
|
|
128
|
-
const videoTrackConstraints = this.setConstraints();
|
|
129
|
-
this.setupAttempt = 0;
|
|
130
|
-
this.setup(videoTrackConstraints);
|
|
131
|
-
});
|
|
132
|
-
}
|
|
133
|
-
setDeviceId(stream) {
|
|
134
|
-
this.mediaStream = stream;
|
|
135
|
-
this.cameraProvider.deviceId = this.activeTrackSettings.deviceId;
|
|
136
|
-
this.startVideo();
|
|
137
|
-
}
|
|
138
|
-
setup(videoTrackConstraints) {
|
|
139
|
-
console.warn('videoTrackConstraints', videoTrackConstraints);
|
|
140
|
-
console.time('device');
|
|
141
|
-
this.__subs(from(navigator.mediaDevices.getUserMedia({
|
|
142
|
-
video: videoTrackConstraints,
|
|
143
|
-
}))).subscribe((stream) => {
|
|
144
|
-
console.timeEnd('device');
|
|
145
|
-
stream.getTracks().forEach((t) => {
|
|
146
|
-
//console.warn(t.getConstraints());
|
|
147
|
-
if (!this.isMobile) {
|
|
148
|
-
try {
|
|
149
|
-
if (!t.getCapabilities) {
|
|
150
|
-
this.setDeviceId(stream);
|
|
151
|
-
return;
|
|
152
|
-
}
|
|
153
|
-
const settings = t.getSettings();
|
|
154
|
-
const cap = t.getCapabilities();
|
|
155
|
-
const con = t.getConstraints();
|
|
156
|
-
console.warn(cap, con);
|
|
157
|
-
console.warn(settings);
|
|
158
|
-
const max = cap.width?.max;
|
|
159
|
-
const min = cap.width?.min;
|
|
160
|
-
const currentWidth = settings.width;
|
|
161
|
-
const currentHeight = settings.height;
|
|
162
|
-
const conWidth = con.width;
|
|
163
|
-
const conHeight = con.width;
|
|
164
|
-
console.warn('CAPS', min, max, 'CURENT', currentWidth, currentHeight);
|
|
165
|
-
if (max &&
|
|
166
|
-
currentWidth &&
|
|
167
|
-
max > currentWidth &&
|
|
168
|
-
conWidth != max) {
|
|
169
|
-
console.log('[SET NEW RESOLUTION]');
|
|
170
|
-
this.setupAttempt++;
|
|
171
|
-
if (this.setupAttempt < 4) {
|
|
172
|
-
this.setup(videoTrackConstraints);
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
else {
|
|
176
|
-
this.setDeviceId(stream);
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
catch (error) {
|
|
180
|
-
console.warn(error);
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
else {
|
|
184
|
-
console.warn('MOBILE VIDEO START');
|
|
185
|
-
this.setDeviceId(stream);
|
|
186
|
-
}
|
|
187
|
-
});
|
|
188
|
-
}, (er) => {
|
|
189
|
-
this.setupAttempt++;
|
|
190
|
-
console.warn('ERROR', er);
|
|
191
|
-
if (this.setupAttempt < 4) {
|
|
192
|
-
if (er instanceof OverconstrainedError) {
|
|
193
|
-
if (!this.isMobile) {
|
|
194
|
-
this.setup(videoTrackConstraints);
|
|
195
|
-
}
|
|
196
|
-
// this.setup({
|
|
197
|
-
// height: 720,
|
|
198
|
-
// width: 1280,
|
|
199
|
-
// });
|
|
200
|
-
//}
|
|
201
|
-
}
|
|
202
|
-
else {
|
|
203
|
-
this.setup(videoTrackConstraints);
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
});
|
|
207
|
-
}
|
|
208
|
-
startVideo() {
|
|
209
|
-
console.log('START VIDEO');
|
|
210
|
-
this.video.srcObject = this.mediaStream;
|
|
211
|
-
this.video.onloadedmetadata = (data) => {
|
|
212
|
-
console.log(data);
|
|
213
|
-
this.video.play();
|
|
214
|
-
this.showVideo = true;
|
|
215
|
-
this.cd.detectChanges();
|
|
216
|
-
console.log('VIDEO PLAY');
|
|
217
|
-
};
|
|
218
|
-
this.video.onplay = () => {
|
|
219
|
-
this.videoReady.next(true);
|
|
220
|
-
console.log(this.video.videoWidth, this.video.videoHeight);
|
|
221
|
-
this.drawRectangle();
|
|
222
|
-
};
|
|
223
|
-
}
|
|
224
|
-
setCanvas() {
|
|
225
|
-
let _canvas = document.createElement('canvas'); //this.canvasSnapshot.nativeElement;
|
|
226
|
-
const { videoWidth, videoHeight } = this.video;
|
|
227
|
-
const aspect = videoWidth / videoHeight;
|
|
228
|
-
const canvasSmalSize = 384;
|
|
229
|
-
const smallSize = {
|
|
230
|
-
w: 0,
|
|
231
|
-
h: 0,
|
|
232
|
-
};
|
|
233
|
-
if (videoWidth >= videoHeight) {
|
|
234
|
-
smallSize.w = canvasSmalSize;
|
|
235
|
-
smallSize.h = canvasSmalSize / aspect;
|
|
236
|
-
}
|
|
237
|
-
else {
|
|
238
|
-
smallSize.h = canvasSmalSize;
|
|
239
|
-
smallSize.h = canvasSmalSize * aspect;
|
|
240
|
-
}
|
|
241
|
-
//console.log('SZ', smallSize);
|
|
242
|
-
_canvas.width = videoWidth;
|
|
243
|
-
_canvas.height = videoHeight;
|
|
244
|
-
const ctx = _canvas.getContext('2d', {
|
|
245
|
-
// alpha: false,
|
|
246
|
-
// powerPreference: 'high-performance',
|
|
247
|
-
// antialias: false,
|
|
248
|
-
// depth: false,
|
|
249
|
-
// desynchronized: true,
|
|
250
|
-
// willReadFrequently: true,
|
|
251
|
-
});
|
|
252
|
-
const canvas = document.createElement('canvas'); // needs an initial size
|
|
253
|
-
canvas.height = smallSize.h;
|
|
254
|
-
canvas.width = smallSize.w;
|
|
255
|
-
const ctxO = canvas.getContext('2d', {
|
|
256
|
-
// alpha: false,
|
|
257
|
-
// powerPreference: 'high-performance',
|
|
258
|
-
// antialias: false,
|
|
259
|
-
// depth: false,
|
|
260
|
-
// desynchronized: true,
|
|
261
|
-
// willReadFrequently: true,
|
|
262
|
-
});
|
|
263
|
-
this.canvasData.ctx = ctx;
|
|
264
|
-
this.canvasData.ctxO = ctxO;
|
|
265
|
-
this.canvasData.canvas = canvas;
|
|
266
|
-
this.canvasData._canvas = _canvas;
|
|
267
|
-
this.canvasData.size = smallSize;
|
|
268
|
-
// const stream = this.video.captureStream(5);
|
|
269
|
-
// const mediaRecorder = new MediaRecorder(stream);
|
|
270
|
-
// mediaRecorder.start();
|
|
271
|
-
// mediaRecorder.ondataavailable = (e:any) => {
|
|
272
|
-
// console.log(e)
|
|
273
|
-
// this.chunks.push(e.data);
|
|
274
|
-
// var url = window.URL.createObjectURL(e.data);
|
|
275
|
-
// var anchor = document.createElement('a');
|
|
276
|
-
// anchor.download = 'myfile.webm';
|
|
277
|
-
// anchor.href = url;
|
|
278
|
-
// anchor.click();
|
|
279
|
-
// };
|
|
280
|
-
}
|
|
281
|
-
takeSelfie() {
|
|
282
|
-
const mimeType = 'image/jpeg';
|
|
283
|
-
const { videoWidth, offsetWidth, videoHeight } = this.video;
|
|
284
|
-
let _canvas = document.createElement('canvas'); //this.canvasSnapshot.nativeElement;
|
|
285
|
-
const { w, h } = this.cameraProvider.rectPosition;
|
|
286
|
-
const aspect = videoWidth / offsetWidth;
|
|
287
|
-
// console.log(videoWidth, offsetWidth, l, t, w, h);
|
|
288
|
-
_canvas.width = w * aspect;
|
|
289
|
-
_canvas.height = h * aspect;
|
|
290
|
-
const dx = videoWidth - w * aspect;
|
|
291
|
-
const dy = videoHeight - h * aspect;
|
|
292
|
-
const x = dx / 2;
|
|
293
|
-
const y = dy / 2;
|
|
294
|
-
const ctx = _canvas.getContext('2d', {
|
|
295
|
-
alpha: false,
|
|
296
|
-
powerPreference: 'high-performance',
|
|
297
|
-
antialias: false,
|
|
298
|
-
depth: false,
|
|
299
|
-
desynchronized: true,
|
|
300
|
-
});
|
|
301
|
-
if (ctx) {
|
|
302
|
-
ctx.drawImage(this.video, x, y, w * aspect, h * aspect, 0, 0, w * aspect, h * aspect);
|
|
303
|
-
const imgAsUrl = _canvas.toDataURL(mimeType, 1);
|
|
304
|
-
this.imageCapture.emit(new WebcamImage(imgAsUrl, mimeType, new ImageData(1, 1), null));
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
humanFileSize(bytes, si = false, dp = 1) {
|
|
308
|
-
const thresh = si ? 1000 : 1024;
|
|
309
|
-
if (Math.abs(bytes) < thresh) {
|
|
310
|
-
return bytes + ' B';
|
|
311
|
-
}
|
|
312
|
-
const units = si
|
|
313
|
-
? ['kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
|
|
314
|
-
: ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'];
|
|
315
|
-
let u = -1;
|
|
316
|
-
const r = 10 ** dp;
|
|
317
|
-
do {
|
|
318
|
-
bytes /= thresh;
|
|
319
|
-
++u;
|
|
320
|
-
} while (Math.round(Math.abs(bytes) * r) / r >= thresh &&
|
|
321
|
-
u < units.length - 1);
|
|
322
|
-
return bytes.toFixed(dp) + ' ' + units[u];
|
|
323
|
-
}
|
|
324
|
-
takeSnapshot(time) {
|
|
325
|
-
if (this.type !== 'document') {
|
|
326
|
-
this.takeSelfie();
|
|
327
|
-
return;
|
|
328
|
-
}
|
|
329
|
-
// console.warn('SNAP', time);
|
|
330
|
-
if (!this.showVideo) {
|
|
331
|
-
return;
|
|
332
|
-
}
|
|
333
|
-
this.zone.runOutsideAngular(() => {
|
|
334
|
-
const canvasSmalSize = 384;
|
|
335
|
-
const mimeType = 'image/jpeg';
|
|
336
|
-
// let _canvas: HTMLCanvasElement = document.createElement('canvas'); //this.canvasSnapshot.nativeElement;
|
|
337
|
-
const { videoWidth, videoHeight } = this.video;
|
|
338
|
-
// _canvas.width = videoWidth;
|
|
339
|
-
// _canvas.height = videoHeight;
|
|
340
|
-
// console.log(videoWidth, videoHeight);
|
|
341
|
-
// const ctx: any = _canvas.getContext('2d', {
|
|
342
|
-
// alpha: false,
|
|
343
|
-
// powerPreference: 'high-performance',
|
|
344
|
-
// antialias: false,
|
|
345
|
-
// depth: false,
|
|
346
|
-
// desynchronized: true,
|
|
347
|
-
// });
|
|
348
|
-
// const canvas = document.createElement('canvas'); // needs an initial size
|
|
349
|
-
// canvas.height = canvasSmalSize;
|
|
350
|
-
// canvas.width = canvasSmalSize;
|
|
351
|
-
// const ctxO: any = canvas.getContext('2d', {
|
|
352
|
-
// alpha: false,
|
|
353
|
-
// powerPreference: 'high-performance',
|
|
354
|
-
// antialias: false,
|
|
355
|
-
// depth: false,
|
|
356
|
-
// desynchronized: true,
|
|
357
|
-
// });
|
|
358
|
-
const { ctx, ctxO, canvas, _canvas, size } = this.canvasData;
|
|
359
|
-
if (ctx && ctxO) {
|
|
360
|
-
ctx.imageSmoothingEnabled = false;
|
|
361
|
-
const drawStart = Date.now();
|
|
362
|
-
ctx.clearRect(0, 0, videoWidth, videoHeight);
|
|
363
|
-
ctxO.clearRect(0, 0, size.w, size.h);
|
|
364
|
-
ctx.drawImage(this.video, 0, 0);
|
|
365
|
-
//console.time('drawVideo');
|
|
366
|
-
ctxO.drawImage(_canvas, 0, 0, size.w, size.h);
|
|
367
|
-
//console.timeEnd('drawVideo');
|
|
368
|
-
//console.time('DRAW');
|
|
369
|
-
// const imData: any = ctx.getImageData(0, 0, videoWidth, videoHeight);
|
|
370
|
-
console.log(canvas.width, _canvas.width);
|
|
371
|
-
//console.timeEnd('DRAW');
|
|
372
|
-
//console.time('CTX');
|
|
373
|
-
const resize = canvas.toDataURL('image/jpeg');
|
|
374
|
-
const canvasData = _canvas.toDataURL(mimeType, 1);
|
|
375
|
-
console.log(this.humanFileSize(canvasData.length));
|
|
376
|
-
console.log(this.humanFileSize(resize.length));
|
|
377
|
-
console.log(new Date().toISOString());
|
|
378
|
-
//console.timeEnd('CTX');
|
|
379
|
-
const currentTime = new Date().getTime();
|
|
380
|
-
const diff = currentTime - time;
|
|
381
|
-
// total time for pack one image
|
|
382
|
-
const drawTime = Date.now() - drawStart;
|
|
383
|
-
//console.warn('DRAW TIME', drawTime);
|
|
384
|
-
const delayMax = drawTime < 60 ? 100 : 200;
|
|
385
|
-
const delay = diff > delayMax ? 0 : delayMax - diff;
|
|
386
|
-
const timeout = setTimeout(() => {
|
|
387
|
-
this.imageCapture.emit(new WebcamImage(canvasData, mimeType, '', resize));
|
|
388
|
-
clearTimeout(timeout);
|
|
389
|
-
}, delay);
|
|
390
|
-
}
|
|
391
|
-
});
|
|
392
|
-
}
|
|
393
|
-
test() {
|
|
394
|
-
this.drawRectangle();
|
|
395
|
-
}
|
|
396
|
-
stopAllTracks() {
|
|
397
|
-
this.showVideo = false;
|
|
398
|
-
if (this.mediaStream && this.mediaStream.getTracks) {
|
|
399
|
-
// getTracks() returns all media tracks (video+audio)
|
|
400
|
-
this.mediaStream.getTracks().forEach((track) => {
|
|
401
|
-
// console.log(track);
|
|
402
|
-
track.enabled = false;
|
|
403
|
-
this.cd.detectChanges();
|
|
404
|
-
track.stop();
|
|
405
|
-
this.video.srcObject.removeTrack(track);
|
|
406
|
-
this.mediaStream.removeTrack(track);
|
|
407
|
-
this.cd.detectChanges();
|
|
408
|
-
});
|
|
409
|
-
this.video.srcObject = null;
|
|
410
|
-
// this.video.src = null;
|
|
411
|
-
this.video.load();
|
|
412
|
-
}
|
|
413
|
-
// this.__subs(this.stopVideoTracks()).subscribe()
|
|
414
|
-
}
|
|
415
|
-
drawRectangle() {
|
|
416
|
-
console.warn('RECT');
|
|
417
|
-
this.zone.run(() => {
|
|
418
|
-
const _canvas = this.canvas.nativeElement;
|
|
419
|
-
let padding = 10;
|
|
420
|
-
if (!this.isMobile && _canvas.width !== _canvas.height) {
|
|
421
|
-
padding = 40;
|
|
422
|
-
}
|
|
423
|
-
const ctx = _canvas.getContext('2d');
|
|
424
|
-
ctx.clearRect(0, 0, _canvas.width, _canvas.height);
|
|
425
|
-
const { width, height } = _canvas;
|
|
426
|
-
console.log('CANVAS', width, height);
|
|
427
|
-
let { videoWidth, videoHeight } = this.video;
|
|
428
|
-
// video will be scaled to max canvas height
|
|
429
|
-
const aspect = videoWidth / videoHeight;
|
|
430
|
-
// if (videoHeight < height) {
|
|
431
|
-
// videoHeight = height;
|
|
432
|
-
// videoWidth = height*aspect;
|
|
433
|
-
// }
|
|
434
|
-
console.log('VIDEO', videoWidth, videoHeight);
|
|
435
|
-
const docSize = this.type === 'selfie' ? 1 : 86 / 55;
|
|
436
|
-
let _height;
|
|
437
|
-
let _width;
|
|
438
|
-
if (videoWidth >= videoHeight) {
|
|
439
|
-
_width = width;
|
|
440
|
-
_height = _width / aspect;
|
|
441
|
-
if (_height > height) {
|
|
442
|
-
_height = height;
|
|
443
|
-
_width = aspect * _height;
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
else {
|
|
447
|
-
_height = height;
|
|
448
|
-
_width = aspect * _height;
|
|
449
|
-
if (_width > width) {
|
|
450
|
-
_width = width;
|
|
451
|
-
_height = _width / aspect;
|
|
452
|
-
}
|
|
453
|
-
}
|
|
454
|
-
console.log('CALC', _width, _height);
|
|
455
|
-
let w, h;
|
|
456
|
-
if (_width <= _height) {
|
|
457
|
-
w = _width - 2 * padding;
|
|
458
|
-
h = w / docSize;
|
|
459
|
-
}
|
|
460
|
-
else {
|
|
461
|
-
h = _height - 2 * padding;
|
|
462
|
-
w = docSize * h;
|
|
463
|
-
}
|
|
464
|
-
if (w > _width) {
|
|
465
|
-
w = _width - 2 * padding;
|
|
466
|
-
h = w / docSize;
|
|
467
|
-
}
|
|
468
|
-
h = Math.floor(h);
|
|
469
|
-
w = Math.floor(w);
|
|
470
|
-
console.log(w, h);
|
|
471
|
-
const left = Math.floor((width - w) / 2);
|
|
472
|
-
const top = Math.floor((height - h) / 2);
|
|
473
|
-
ctx.strokeStyle = 'white';
|
|
474
|
-
// ctx.strokeRect(left, top, _width, _height);
|
|
475
|
-
ctx.fillStyle = 'rgba(255, 255, 255, 0.2)';
|
|
476
|
-
// ctx.shadowColor = 'white';
|
|
477
|
-
ctx.shadowBlur = 15;
|
|
478
|
-
ctx.beginPath();
|
|
479
|
-
// Draw using 5px for border radius on all sides
|
|
480
|
-
// stroke it but no fill
|
|
481
|
-
const radius = this.isMobile ? 10 : 30;
|
|
482
|
-
ctx.roundRect(left, top, w, h, radius);
|
|
483
|
-
ctx.stroke();
|
|
484
|
-
ctx.fill();
|
|
485
|
-
console.warn('CAN', left, top, w, h, radius, ctx);
|
|
486
|
-
this.cameraProvider.rectPosition = {
|
|
487
|
-
l: left,
|
|
488
|
-
t: top,
|
|
489
|
-
w,
|
|
490
|
-
h,
|
|
491
|
-
_w: _width,
|
|
492
|
-
_h: _height,
|
|
493
|
-
};
|
|
494
|
-
this.setCanvas();
|
|
495
|
-
// ctx.stroke();
|
|
496
|
-
});
|
|
497
|
-
}
|
|
498
|
-
ngOnDestroy() {
|
|
499
|
-
this.video.pause();
|
|
500
|
-
// this.video.getTracks().forEach((track: any) => {
|
|
501
|
-
// track.stop();
|
|
502
|
-
// this.video.srcObject.removeTrack(track);
|
|
503
|
-
// });
|
|
504
|
-
this.stopAllTracks();
|
|
505
|
-
if (this.triggerSubscription) {
|
|
506
|
-
this.triggerSubscription.unsubscribe();
|
|
507
|
-
}
|
|
508
|
-
this.__destroy();
|
|
509
|
-
console.warn('[VIDEO] destroyed');
|
|
510
|
-
}
|
|
511
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: WebcamComponent, deps: [{ token: i1.BreakpointObserver }, { token: i2.Platform }, { token: i0.ChangeDetectorRef }, { token: i0.NgZone }, { token: i3.NgxScandocCameraProvider }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
512
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: WebcamComponent, selector: "ngx-scandoc-webcam", inputs: { imageHandler: "imageHandler", type: "type", trigger: "trigger", refresh: "refresh" }, outputs: { cameraSwitched: "cameraSwitched", videoReady: "videoReady", imageCapture: "imageCapture", initError: "initError" }, host: { listeners: { "window:resize": "onResize($event)" } }, viewQueries: [{ propertyName: "canvas", first: true, predicate: ["canvas"], descendants: true, static: true }, { propertyName: "videoRef", first: true, predicate: ["video"], descendants: true, static: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"webcam-wrapper\">\n <video #video autoplay muted style=\"display: block\" playsinline></video>\n\n <div class=\"rectangle\">\n <canvas\n #canvas\n [ngStyle]=\"{ visibility: showVideo ? 'visible' : 'hidden' }\"\n [width]=\"video.offsetWidth\"\n [height]=\"video.offsetHeight\"\n ></canvas>\n </div>\n\n\n</div>\n", styles: [":host{display:flex;flex-direction:row;flex:1;transform:transale3d(0,0,0);background-color:#000;overflow:hidden}.webcam-wrapper{display:flex;overflow:hidden;flex-direction:row;flex:1;position:relative}.webcam-wrapper video{overflow:hidden;flex:1;object-fit:contain}.webcam-wrapper canvas{transform:translateZ(0);display:block;position:absolute;z-index:20;left:0;top:0}.webcam-wrapper .rectangle{position:absolute;left:0;top:0;display:flex;flex-direction:row;align-items:center;justify-content:center;width:100%;height:100%}\n"], dependencies: [{ kind: "directive", type: i4.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
513
|
-
}
|
|
514
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: WebcamComponent, decorators: [{
|
|
515
|
-
type: Component,
|
|
516
|
-
args: [{ selector: 'ngx-scandoc-webcam', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"webcam-wrapper\">\n <video #video autoplay muted style=\"display: block\" playsinline></video>\n\n <div class=\"rectangle\">\n <canvas\n #canvas\n [ngStyle]=\"{ visibility: showVideo ? 'visible' : 'hidden' }\"\n [width]=\"video.offsetWidth\"\n [height]=\"video.offsetHeight\"\n ></canvas>\n </div>\n\n\n</div>\n", styles: [":host{display:flex;flex-direction:row;flex:1;transform:transale3d(0,0,0);background-color:#000;overflow:hidden}.webcam-wrapper{display:flex;overflow:hidden;flex-direction:row;flex:1;position:relative}.webcam-wrapper video{overflow:hidden;flex:1;object-fit:contain}.webcam-wrapper canvas{transform:translateZ(0);display:block;position:absolute;z-index:20;left:0;top:0}.webcam-wrapper .rectangle{position:absolute;left:0;top:0;display:flex;flex-direction:row;align-items:center;justify-content:center;width:100%;height:100%}\n"] }]
|
|
517
|
-
}], ctorParameters: () => [{ type: i1.BreakpointObserver }, { type: i2.Platform }, { type: i0.ChangeDetectorRef }, { type: i0.NgZone }, { type: i3.NgxScandocCameraProvider }], propDecorators: { imageHandler: [{
|
|
518
|
-
type: Input
|
|
519
|
-
}], type: [{
|
|
520
|
-
type: Input
|
|
521
|
-
}], trigger: [{
|
|
522
|
-
type: Input
|
|
523
|
-
}], refresh: [{
|
|
524
|
-
type: Input
|
|
525
|
-
}], onResize: [{
|
|
526
|
-
type: HostListener,
|
|
527
|
-
args: ['window:resize', ['$event']]
|
|
528
|
-
}], canvas: [{
|
|
529
|
-
type: ViewChild,
|
|
530
|
-
args: ['canvas', { static: true }]
|
|
531
|
-
}], videoRef: [{
|
|
532
|
-
type: ViewChild,
|
|
533
|
-
args: ['video', { static: true }]
|
|
534
|
-
}], cameraSwitched: [{
|
|
535
|
-
type: Output
|
|
536
|
-
}], videoReady: [{
|
|
537
|
-
type: Output
|
|
538
|
-
}], imageCapture: [{
|
|
539
|
-
type: Output
|
|
540
|
-
}], initError: [{
|
|
541
|
-
type: Output
|
|
542
|
-
}] } });
|
|
543
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2ViY2FtLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1zY2FuZG9jL3NyYy9jb3JlL2NvbXBvbmVudHMvd2ViY2FtL3dlYmNhbS93ZWJjYW0uY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LXNjYW5kb2Mvc3JjL2NvcmUvY29tcG9uZW50cy93ZWJjYW0vd2ViY2FtL3dlYmNhbS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBRUwsdUJBQXVCLEVBRXZCLFNBQVMsRUFDVCxZQUFZLEVBQ1osWUFBWSxFQUNaLEtBQUssRUFHTCxNQUFNLEVBQ04sU0FBUyxHQUNWLE1BQU0sZUFBZSxDQUFDO0FBRXZCLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNyRCxPQUFPLEVBQUUsSUFBSSxFQUF5QyxNQUFNLE1BQU0sQ0FBQztBQVluRSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7Ozs7OztBQVVyRCxNQUFNLE9BQU8sZUFDWCxTQUFRLGFBQWE7SUFnQ3JCLFFBQVE7UUFDTixJQUFJLENBQUMsY0FBYyxDQUFDLFlBQVksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3ZDLCtCQUErQjtRQUMvQixJQUFJLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUN2QixZQUFZLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQ25DLENBQUM7UUFDRCxJQUFJLENBQUMsYUFBYSxHQUFHLFVBQVUsQ0FBQyxHQUFHLEVBQUU7WUFDbkMsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQ3ZCLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUNYLENBQUM7SUFnQkQsWUFDUyxrQkFBc0MsRUFDdEMsUUFBa0IsRUFDakIsRUFBcUIsRUFDckIsSUFBWSxFQUVa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O3VCQUFDLGVBQWUsRUFBRSxDQUFDLFFBQVEsQ0FBQztnQkFhTSxNQUFNO3NCQUFwRCxTQUFTO3VCQUFDLFFBQVEsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7Z0JBRVMsUUFBUTtzQkFBckQsU0FBUzt1QkFBQyxPQUFPLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFO2dCQUVuQixjQUFjO3NCQUE5QixNQUFNO2dCQUVVLFVBQVU7c0JBQTFCLE1BQU07Z0JBRVUsWUFBWTtzQkFBNUIsTUFBTTtnQkFHVSxTQUFTO3NCQUF6QixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQWZ0ZXJWaWV3SW5pdCxcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBDb21wb25lbnQsXG4gIEV2ZW50RW1pdHRlcixcbiAgSG9zdExpc3RlbmVyLFxuICBJbnB1dCxcbiAgTmdab25lLFxuICBPbkRlc3Ryb3ksXG4gIE91dHB1dCxcbiAgVmlld0NoaWxkLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFdlYmNhbUluaXRFcnJvciB9IGZyb20gJy4uL2RvbWFpbi93ZWJjYW0taW5pdC1lcnJvcic7XG5pbXBvcnQgeyBXZWJjYW1JbWFnZSB9IGZyb20gJy4uL2RvbWFpbi93ZWJjYW0taW1hZ2UnO1xuaW1wb3J0IHsgZnJvbSwgT2JzZXJ2YWJsZSwgb2YsIFN1YmplY3QsIFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgV2ViY2FtVXRpbCB9IGZyb20gJy4uL3V0aWwvd2ViY2FtLnV0aWwnO1xuaW1wb3J0IHsgV2ViY2FtTWlycm9yUHJvcGVydGllcyB9IGZyb20gJy4uL2RvbWFpbi93ZWJjYW0tbWlycm9yLXByb3BlcnRpZXMnO1xuaW1wb3J0IHtcbiAgQnJlYWtwb2ludE9ic2VydmVyLFxuICBCcmVha3BvaW50cyxcbiAgQnJlYWtwb2ludFN0YXRlLFxufSBmcm9tICdAYW5ndWxhci9jZGsvbGF5b3V0JztcbmltcG9ydCB7IFBsYXRmb3JtIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL3BsYXRmb3JtJztcbmltcG9ydCB7IG1hcCwgc3dpdGNoTWFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgd29ya2VydGV4dCB9IGZyb20gJy4uLy4uLy4uL2FwcC53b3JrZXInO1xuaW1wb3J0IHsgTmd4U2NhbmRvY0NhbWVyYVByb3ZpZGVyIH0gZnJvbSAnLi4vLi4vLi4vLi4vcHJvdmlkZXJzL2NhbWVyYS5wcm92aWRlcic7XG5pbXBvcnQgeyBCYXNlQ29tcG9uZW50IH0gZnJvbSAnLi4vLi4vYmFzZS5jb21wb25lbnQnO1xuXG5kZWNsYXJlIHZhciBNZWRpYVN0cmVhbVRyYWNrUHJvY2Vzc29yOiBhbnk7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ25neC1zY2FuZG9jLXdlYmNhbScsXG4gIHRlbXBsYXRlVXJsOiAnLi93ZWJjYW0uY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi93ZWJjYW0uY29tcG9uZW50LnNjc3MnXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG59KVxuZXhwb3J0IGNsYXNzIFdlYmNhbUNvbXBvbmVudFxuICBleHRlbmRzIEJhc2VDb21wb25lbnRcbiAgaW1wbGVtZW50cyBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3lcbntcbiAgcHJpdmF0ZSB0cmlnZ2VyU3Vic2NyaXB0aW9uPzogU3Vic2NyaXB0aW9uO1xuICBjYW52YXNTaXplOiBhbnkgPSB7IHdpZHRoOiAwLCBoZWlnaHQ6IDAgfTtcbiAgc2hvd1ZpZGVvID0gZmFsc2U7XG4gIHNldHVwQXR0ZW1wdCA9IDA7XG4gIGNhbnZhc0RhdGE6IGFueSA9IHtcbiAgICBjdHg6IG51bGwsXG4gICAgY3R4TzogbnVsbCxcbiAgfTtcblxuICBtZWRpYVN0cmVhbSE6IE1lZGlhU3RyZWFtO1xuICBASW5wdXQoKSBpbWFnZUhhbmRsZXIhOiBTdWJqZWN0PGFueT47XG5cbiAgQElucHV0KCkgcHVibGljIHR5cGU/OiAnZG9jdW1lbnQnIHwgJ3NlbGZpZScgfCAnbWFudWFsJztcblxuICBASW5wdXQoKSB0cmlnZ2VyITogT2JzZXJ2YWJsZTxudW1iZXI+O1xuXG4gIEBJbnB1dCgpIHJlZnJlc2ghOiBTdWJqZWN0PGJvb2xlYW4+O1xuICAvLyBwdWJsaWMgc2V0IHRyaWdnZXIodHJpZ2dlcjogT2JzZXJ2YWJsZTxudW1iZXI+KSB7XG4gIC8vICAgaWYgKHRoaXMudHJpZ2dlclN1YnNjcmlwdGlvbikge1xuICAvLyAgICAgdGhpcy50cmlnZ2VyU3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XG4gIC8vICAgfVxuXG4gIC8vICAgLy8gU3Vic2NyaWJlIHRvIGV2ZW50cyBmcm9tIHRoaXMgT2JzZXJ2YWJsZSB0byB0YWtlIHNuYXBzaG90c1xuICAvLyAgIHRoaXMudHJpZ2dlclN1YnNjcmlwdGlvbiA9IHRyaWdnZXIuc3Vic2NyaWJlKCh0aW1lKSA9PiB7XG4gIC8vICAgICB0aGlzLnRha2VTbmFwc2hvdCh0aW1lKTtcbiAgLy8gICB9KTtcbiAgLy8gfVxuICByZXNpemVUaW1lb3V0OiBhbnk7XG4gIEBIb3N0TGlzdGVuZXIoJ3dpbmRvdzpyZXNpemUnLCBbJyRldmVudCddKVxuICBvblJlc2l6ZSgpIHtcbiAgICB0aGlzLmNhbWVyYVByb3ZpZGVyLnJlY3RQb3NpdGlvbi50ID0gMDtcbiAgICAvLyB0aGlzLnZpZGVvUmVhZHkubmV4dChmYWxzZSk7XG4gICAgaWYgKHRoaXMucmVzaXplVGltZW91dCkge1xuICAgICAgY2xlYXJUaW1lb3V0KHRoaXMucmVzaXplVGltZW91dCk7XG4gICAgfVxuICAgIHRoaXMucmVzaXplVGltZW91dCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy5kcmF3UmVjdGFuZ2xlKCk7XG4gICAgfSwgMTAwMCk7XG4gIH1cblxuICBwcml2YXRlIGNodW5rczogYW55ID0gW107XG4gIEBWaWV3Q2hpbGQoJ2NhbnZhcycsIHsgc3RhdGljOiB0cnVlIH0pIHByaXZhdGUgY2FudmFzOiBhbnk7XG5cbiAgQFZpZXdDaGlsZCgndmlkZW8nLCB7IHN0YXRpYzogdHJ1ZSB9KSBwcml2YXRlIHZpZGVvUmVmOiBhbnk7XG5cbiAgQE91dHB1dCgpIHB1YmxpYyBjYW1lcmFTd2l0Y2hlZDogRXZlbnRFbWl0dGVyPHN0cmluZz4gPVxuICAgIG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xuICBAT3V0cHV0KCkgcHVibGljIHZpZGVvUmVhZHk6IEV2ZW50RW1pdHRlcjxib29sZWFuPiA9XG4gICAgbmV3IEV2ZW50RW1pdHRlcjxib29sZWFuPigpO1xuICBAT3V0cHV0KCkgcHVibGljIGltYWdlQ2FwdHVyZTogRXZlbnRFbWl0dGVyPFdlYmNhbUltYWdlPiA9XG4gICAgbmV3IEV2ZW50RW1pdHRlcjxXZWJjYW1JbWFnZT4oKTtcblxuICBAT3V0cHV0KCkgcHVibGljIGluaXRFcnJvcjogRXZlbnRFbWl0dGVyPFdlYmNhbUluaXRFcnJvcj4gPVxuICAgIG5ldyBFdmVudEVtaXR0ZXI8V2ViY2FtSW5pdEVycm9yPigpO1xuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgYnJlYWtwb2ludE9ic2VydmVyOiBCcmVha3BvaW50T2JzZXJ2ZXIsXG4gICAgcHVibGljIHBsYXRmb3JtOiBQbGF0Zm9ybSxcbiAgICBwcml2YXRlIGNkOiBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICBwcml2YXRlIHpvbmU6IE5nWm9uZSxcblxuICAgIHByaXZhdGUgY2FtZXJhUHJvdmlkZXI6IE5neFNjYW5kb2NDYW1lcmFQcm92aWRlclxuICApIHtcbiAgICBzdXBlcigpO1xuICB9XG4gIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcbiAgICBjb25zb2xlLndhcm4oJ1t2aWRlb10gc3RhcnQnKTtcbiAgICAvLyBpbml0aWFsIGxvYWRcbiAgICB0aGlzLl9fc3Vicyh0aGlzLmNhbWVyYVByb3ZpZGVyLmdldERldmljZXMoKSkuc3Vic2NyaWJlKChyZXNwKSA9PiB7XG4gICAgICB0aGlzLmluaXQoKTtcbiAgICB9KTtcbiAgICBpZih0aGlzLnJlZnJlc2gpe1xuICAgICAgdGhpcy5fX3N1YnModGhpcy5yZWZyZXNoKS5zdWJzY3JpYmUoKCk9PntcbiAgICAgICAgIGlmICh0aGlzLnJlc2l6ZVRpbWVvdXQpIHtcbiAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMucmVzaXplVGltZW91dCk7XG4gICAgICAgICB9XG4gICAgICAgICB0aGlzLnJlc2l6ZVRpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgdGhpcy5kcmF3UmVjdGFuZ2xlKCk7XG4gICAgICAgICB9LCA1MCk7XG4gICAgICB9KVxuICAgIH1cblxuICAgIC8vIGNhbWVyYSBzd2l0Y2hcbiAgICB0aGlzLl9fc3Vicyh0aGlzLmNhbWVyYVByb3ZpZGVyLndlYmNhbU9ic2VydmFibGUpLnN1YnNjcmliZSgoZGV2aWNlKSA9PiB7XG4gICAgICBjb25zdCB2aWRlb1RyYWNrQ29uc3RyYWludHM6IGFueSA9IHRoaXMuc2V0Q29uc3RyYWludHMoKTtcbiAgICAgIHRoaXMuc3RvcEFsbFRyYWNrcygpO1xuICAgICAgdGhpcy5zaG93VmlkZW8gPSBmYWxzZTtcbiAgICAgIHRoaXMuY2QuZGV0ZWN0Q2hhbmdlcygpO1xuICAgICAgdmlkZW9UcmFja0NvbnN0cmFpbnRzLmRldmljZUlkID0gZGV2aWNlO1xuICAgICAgdGhpcy5zZXR1cCh2aWRlb1RyYWNrQ29uc3RyYWludHMpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5fX3N1YnModGhpcy50cmlnZ2VyKS5zdWJzY3JpYmUoKHRpbWUpID0+IHRoaXMudGFrZVNuYXBzaG90KHRpbWUpKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgdmlkZW8oKSB7XG4gICAgcmV0dXJuIHRoaXMudmlkZW9SZWYubmF0aXZlRWxlbWVudDtcbiAgfVxuICBnZXQgaXNNb2JpbGUoKSB7XG4gICAgcmV0dXJuIHRoaXMucGxhdGZvcm0uQU5EUk9JRCB8fCB0aGlzLnBsYXRmb3JtLklPUztcbiAgfVxuICBwcml2YXRlIHNldENvbnN0cmFpbnRzKCkge1xuICAgIGNvbnN0IG91dDogTWVkaWFTdHJlYW1Db25zdHJhaW50cyA9IHt9O1xuICAgIGNvbnNvbGUud2FybignTU9CSUxFJywgdGhpcy5pc01vYmlsZSk7XG4gICAgc3dpdGNoICh0aGlzLnR5cGUpIHtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGlmICh0aGlzLmlzTW9iaWxlKSB7XG4gICAgICAgICAgb3V0LnZpZGVvID0geyBoZWlnaHQ6IHsgaWRlYWw6IDE2MDAgfSwgd2lkdGg6IHsgaWRlYWw6IDE2MDAgfSB9O1xuICAgICAgICAgIG91dC52aWRlby5mYWNpbmdNb2RlID0gJ2Vudmlyb25tZW50JztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBvdXQudmlkZW8gPSB7XG4gICAgICAgICAgICB3aWR0aDoge1xuICAgICAgICAgICAgICBtaW46IDEyODAsXG4gICAgICAgICAgICAgIGlkZWFsOiAxOTIwLFxuICAgICAgICAgICAgICBtYXg6IDI5MDAsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgaGVpZ2h0OiB7XG4gICAgICAgICAgICAgIG1pbjogNzIwLFxuICAgICAgICAgICAgICBpZGVhbDogMTA4MCxcbiAgICAgICAgICAgICAgbWF4OiAyOTAwLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ3NlbGZpZSc6XG4gICAgICAgIGlmICh0aGlzLmlzTW9iaWxlKSB7XG4gICAgICAgICAgb3V0LnZpZGVvID0geyBoZWlnaHQ6IHsgaWRlYWw6IDE2MDAgfSwgd2lkdGg6IHsgaWRlYWw6IDE2MDAgfSB9O1xuICAgICAgICAgIG91dC52aWRlby5mYWNpbmdNb2RlID0gJ3VzZXInO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG91dC52aWRlbyA9IHtcbiAgICAgICAgICAgIGZyYW1lUmF0ZTogeyBtaW46IDEwIH0sXG4gICAgICAgICAgICBoZWlnaHQ6IHsgaWRlYWw6IDEwODAgfSxcbiAgICAgICAgICAgIHdpZHRoOiB7IGlkZWFsOiAxOTIwIH0sXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIGJyZWFrO1xuICAgIH1cblxuICAgIHJldHVybiBvdXQudmlkZW87XG4gIH1cblxuICBwcml2YXRlIGdldCBhY3RpdmVUcmFja1NldHRpbmdzKCkge1xuICAgIHJldHVybiB0aGlzLm1lZGlhU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF0uZ2V0U2V0dGluZ3MoKTtcbiAgfVxuICBwcml2YXRlIGdldCBhY3RpdmVUcmFja0NhcGFiaWxpdGllcygpIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIHRoaXMubWVkaWFTdHJlYW0uZ2V0VmlkZW9UcmFja3MoKVswXS5nZXRDYXBhYmlsaXRpZXMoKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZXR1cm4ge307XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBpbml0KCkge1xuICAgIHRoaXMuX19zdWJzKHRoaXMuY2FtZXJhUHJvdmlkZXIuZ2V0RGV2aWNlcygpKS5zdWJzY3JpYmUoKHJlc3ApID0+IHtcbiAgICAgIGNvbnNvbGUud2FybignREVWSUNFUycsIHJlc3ApO1xuICAgICAgY29uc3QgdmlkZW9UcmFja0NvbnN0cmFpbnRzID0gdGhpcy5zZXRDb25zdHJhaW50cygpO1xuICAgICAgdGhpcy5zZXR1cEF0dGVtcHQgPSAwO1xuICAgICAgdGhpcy5zZXR1cCh2aWRlb1RyYWNrQ29uc3RyYWludHMpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBzZXREZXZpY2VJZChzdHJlYW06IE1lZGlhU3RyZWFtKSB7XG4gICAgdGhpcy5tZWRpYVN0cmVhbSA9IHN0cmVhbTtcbiAgICB0aGlzLmNhbWVyYVByb3ZpZGVyLmRldmljZUlkID0gdGhpcy5hY3RpdmVUcmFja1NldHRpbmdzLmRldmljZUlkO1xuICAgIHRoaXMuc3RhcnRWaWRlbygpO1xuICB9XG4gIHByaXZhdGUgc2V0dXAodmlkZW9UcmFja0NvbnN0cmFpbnRzOiBhbnkpIHtcbiAgICBjb25zb2xlLndhcm4oJ3ZpZGVvVHJhY2tDb25zdHJhaW50cycsIHZpZGVvVHJhY2tDb25zdHJhaW50cyk7XG4gICAgY29uc29sZS50aW1lKCdkZXZpY2UnKTtcbiAgICB0aGlzLl9fc3VicyhcbiAgICAgIGZyb20oXG4gICAgICAgIG5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhKDxNZWRpYVN0cmVhbUNvbnN0cmFpbnRzPntcbiAgICAgICAgICB2aWRlbzogdmlkZW9UcmFja0NvbnN0cmFpbnRzLFxuICAgICAgICB9KVxuICAgICAgKVxuICAgICkuc3Vic2NyaWJlKFxuICAgICAgKHN0cmVhbTogTWVkaWFTdHJlYW0pID0+IHtcbiAgICAgICAgY29uc29sZS50aW1lRW5kKCdkZXZpY2UnKTtcbiAgICAgICAgc3RyZWFtLmdldFRyYWNrcygpLmZvckVhY2goKHQpID0+IHtcbiAgICAgICAgICAvL2NvbnNvbGUud2Fybih0LmdldENvbnN0cmFpbnRzKCkpO1xuXG4gICAgICAgICAgaWYgKCF0aGlzLmlzTW9iaWxlKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBpZiAoIXQuZ2V0Q2FwYWJpbGl0aWVzKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXREZXZpY2VJZChzdHJlYW0pO1xuXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGNvbnN0IHNldHRpbmdzID0gdC5nZXRTZXR0aW5ncygpO1xuICAgICAgICAgICAgICBjb25zdCBjYXAgPSB0LmdldENhcGFiaWxpdGllcygpO1xuICAgICAgICAgICAgICBjb25zdCBjb24gPSB0LmdldENvbnN0cmFpbnRzKCk7XG5cbiAgICAgICAgICAgICAgY29uc29sZS53YXJuKGNhcCwgY29uKTtcbiAgICAgICAgICAgICAgY29uc29sZS53YXJuKHNldHRpbmdzKTtcbiAgICAgICAgICAgICAgY29uc3QgbWF4ID0gY2FwLndpZHRoPy5tYXg7XG4gICAgICAgICAgICAgIGNvbnN0IG1pbiA9IGNhcC53aWR0aD8ubWluO1xuICAgICAgICAgICAgICBjb25zdCBjdXJyZW50V2lkdGggPSBzZXR0aW5ncy53aWR0aDtcbiAgICAgICAgICAgICAgY29uc3QgY3VycmVudEhlaWdodCA9IHNldHRpbmdzLmhlaWdodDtcblxuICAgICAgICAgICAgICBjb25zdCBjb25XaWR0aCA9IGNvbi53aWR0aDtcbiAgICAgICAgICAgICAgY29uc3QgY29uSGVpZ2h0ID0gY29uLndpZHRoO1xuICAgICAgICAgICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICAgICAgICAgJ0NBUFMnLFxuICAgICAgICAgICAgICAgIG1pbixcbiAgICAgICAgICAgICAgICBtYXgsXG4gICAgICAgICAgICAgICAgJ0NVUkVOVCcsXG4gICAgICAgICAgICAgICAgY3VycmVudFdpZHRoLFxuICAgICAgICAgICAgICAgIGN1cnJlbnRIZWlnaHRcbiAgICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgbWF4ICYmXG4gICAgICAgICAgICAgICAgY3VycmVudFdpZHRoICYmXG4gICAgICAgICAgICAgICAgbWF4ID4gY3VycmVudFdpZHRoICYmXG4gICAgICAgICAgICAgICAgY29uV2lkdGggIT0gbWF4XG4gICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKCdbU0VUIE5FVyBSRVNPTFVUSU9OXScpO1xuICAgICAgICAgICAgICAgIHRoaXMuc2V0dXBBdHRlbXB0Kys7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuc2V0dXBBdHRlbXB0IDwgNCkge1xuICAgICAgICAgICAgICAgICAgdGhpcy5zZXR1cCh2aWRlb1RyYWNrQ29uc3RyYWludHMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNldERldmljZUlkKHN0cmVhbSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgIGNvbnNvbGUud2FybihlcnJvcik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybignTU9CSUxFIFZJREVPIFNUQVJUJyk7XG4gICAgICAgICAgICB0aGlzLnNldERldmljZUlkKHN0cmVhbSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgIH0sXG4gICAgICAoZXIpID0+IHtcbiAgICAgICAgdGhpcy5zZXR1cEF0dGVtcHQrKztcbiAgICAgICAgY29uc29sZS53YXJuKCdFUlJPUicsIGVyKTtcblxuICAgICAgICBpZiAodGhpcy5zZXR1cEF0dGVtcHQgPCA0KSB7XG4gICAgICAgICAgaWYgKGVyIGluc3RhbmNlb2YgT3ZlcmNvbnN0cmFpbmVkRXJyb3IpIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5pc01vYmlsZSkge1xuICAgICAgICAgICAgICB0aGlzLnNldHVwKHZpZGVvVHJhY2tDb25zdHJhaW50cyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyB0aGlzLnNldHVwKHtcbiAgICAgICAgICAgIC8vICAgaGVpZ2h0OiA3MjAsXG4gICAgICAgICAgICAvLyAgIHdpZHRoOiAxMjgwLFxuICAgICAgICAgICAgLy8gfSk7XG4gICAgICAgICAgICAvL31cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zZXR1cCh2aWRlb1RyYWNrQ29uc3RyYWludHMpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIHN0YXJ0VmlkZW8oKSB7XG4gICAgY29uc29sZS5sb2coJ1NUQVJUIFZJREVPJyk7XG4gICAgdGhpcy52aWRlby5zcmNPYmplY3QgPSB0aGlzLm1lZGlhU3RyZWFtO1xuXG4gICAgdGhpcy52aWRlby5vbmxvYWRlZG1ldGFkYXRhID0gKGRhdGE6IGFueSkgPT4ge1xuICAgICAgY29uc29sZS5sb2coZGF0YSk7XG4gICAgICB0aGlzLnZpZGVvLnBsYXkoKTtcbiAgICAgIHRoaXMuc2hvd1ZpZGVvID0gdHJ1ZTtcbiAgICAgIHRoaXMuY2QuZGV0ZWN0Q2hhbmdlcygpO1xuICAgICAgY29uc29sZS5sb2coJ1ZJREVPIFBMQVknKTtcbiAgICB9O1xuICAgIHRoaXMudmlkZW8ub25wbGF5ID0gKCkgPT4ge1xuICAgICAgdGhpcy52aWRlb1JlYWR5Lm5leHQodHJ1ZSk7XG4gICAgICBjb25zb2xlLmxvZyh0aGlzLnZpZGVvLnZpZGVvV2lkdGgsIHRoaXMudmlkZW8udmlkZW9IZWlnaHQpO1xuICAgICAgdGhpcy5kcmF3UmVjdGFuZ2xlKCk7XG4gICAgfTtcbiAgfVxuICBzZXRDYW52YXMoKSB7XG4gICAgbGV0IF9jYW52YXM6IEhUTUxDYW52YXNFbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJyk7IC8vdGhpcy5jYW52YXNTbmFwc2hvdC5uYXRpdmVFbGVtZW50O1xuXG4gICAgY29uc3QgeyB2aWRlb1dpZHRoLCB2aWRlb0hlaWdodCB9ID0gdGhpcy52aWRlbztcblxuICAgIGNvbnN0IGFzcGVjdCA9IHZpZGVvV2lkdGggLyB2aWRlb0hlaWdodDtcblxuICAgIGNvbnN0IGNhbnZhc1NtYWxTaXplID0gMzg0O1xuICAgIGNvbnN0IHNtYWxsU2l6ZSA9IHtcbiAgICAgIHc6IDAsXG4gICAgICBoOiAwLFxuICAgIH07XG5cbiAgICBpZiAodmlkZW9XaWR0aCA+PSB2aWRlb0hlaWdodCkge1xuICAgICAgc21hbGxTaXplLncgPSBjYW52YXNTbWFsU2l6ZTtcbiAgICAgIHNtYWxsU2l6ZS5oID0gY2FudmFzU21hbFNpemUgLyBhc3BlY3Q7XG4gICAgfSBlbHNlIHtcbiAgICAgIHNtYWxsU2l6ZS5oID0gY2FudmFzU21hbFNpemU7XG4gICAgICBzbWFsbFNpemUuaCA9IGNhbnZhc1NtYWxTaXplICogYXNwZWN0O1xuICAgIH1cblxuICAgIC8vY29uc29sZS5sb2coJ1NaJywgc21hbGxTaXplKTtcblxuICAgIF9jYW52YXMud2lkdGggPSB2aWRlb1dpZHRoO1xuICAgIF9jYW52YXMuaGVpZ2h0ID0gdmlkZW9IZWlnaHQ7XG4gICAgY29uc3QgY3R4OiBhbnkgPSBfY2FudmFzLmdldENvbnRleHQoJzJkJywge1xuICAgICAgLy8gYWxwaGE6IGZhbHNlLFxuICAgICAgLy8gcG93ZXJQcmVmZXJlbmNlOiAnaGlnaC1wZXJmb3JtYW5jZScsXG4gICAgICAvLyBhbnRpYWxpYXM6IGZhbHNlLFxuICAgICAgLy8gZGVwdGg6IGZhbHNlLFxuICAgICAgLy8gZGVzeW5jaHJvbml6ZWQ6IHRydWUsXG4gICAgICAvLyB3aWxsUmVhZEZyZXF1ZW50bHk6IHRydWUsXG4gICAgfSk7XG5cbiAgICBjb25zdCBjYW52YXMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKTsgLy8gbmVlZHMgYW4gaW5pdGlhbCBzaXplXG4gICAgY2FudmFzLmhlaWdodCA9IHNtYWxsU2l6ZS5oO1xuICAgIGNhbnZhcy53aWR0aCA9IHNtYWxsU2l6ZS53O1xuXG4gICAgY29uc3QgY3R4TzogYW55ID0gY2FudmFzLmdldENvbnRleHQoJzJkJywge1xuICAgICAgLy8gYWxwaGE6IGZhbHNlLFxuICAgICAgLy8gcG93ZXJQcmVmZXJlbmNlOiAnaGlnaC1wZXJmb3JtYW5jZScsXG4gICAgICAvLyBhbnRpYWxpYXM6IGZhbHNlLFxuICAgICAgLy8gZGVwdGg6IGZhbHNlLFxuICAgICAgLy8gZGVzeW5jaHJvbml6ZWQ6IHRydWUsXG4gICAgICAvLyB3aWxsUmVhZEZyZXF1ZW50bHk6IHRydWUsXG4gICAgfSk7XG5cbiAgICB0aGlzLmNhbnZhc0RhdGEuY3R4ID0gY3R4O1xuICAgIHRoaXMuY2FudmFzRGF0YS5jdHhPID0gY3R4TztcbiAgICB0aGlzLmNhbnZhc0RhdGEuY2FudmFzID0gY2FudmFzO1xuICAgIHRoaXMuY2FudmFzRGF0YS5fY2FudmFzID0gX2NhbnZhcztcbiAgICB0aGlzLmNhbnZhc0RhdGEuc2l6ZSA9IHNtYWxsU2l6ZTtcblxuICAgIC8vIGNvbnN0IHN0cmVhbSA9IHRoaXMudmlkZW8uY2FwdHVyZVN0cmVhbSg1KTtcblxuICAgIC8vIGNvbnN0IG1lZGlhUmVjb3JkZXIgPSBuZXcgTWVkaWFSZWNvcmRlcihzdHJlYW0pO1xuXG4gICAgLy8gbWVkaWFSZWNvcmRlci5zdGFydCgpO1xuXG4gICAgLy8gbWVkaWFSZWNvcmRlci5vbmRhdGFhdmFpbGFibGUgPSAoZTphbnkpID0+IHtcbiAgICAvLyAgIGNvbnNvbGUubG9nKGUpXG4gICAgLy8gICB0aGlzLmNodW5rcy5wdXNoKGUuZGF0YSk7XG5cbiAgICAvLyAgIHZhciB1cmwgPSB3aW5kb3cuVVJMLmNyZWF0ZU9iamVjdFVSTChlLmRhdGEpO1xuICAgIC8vICAgdmFyIGFuY2hvciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2EnKTtcbiAgICAvLyAgIGFuY2hvci5kb3dubG9hZCA9ICdteWZpbGUud2VibSc7XG4gICAgLy8gICBhbmNob3IuaHJlZiA9IHVybDtcbiAgICAvLyAgIGFuY2hvci5jbGljaygpO1xuICAgIC8vIH07XG4gIH1cblxuICBwcml2YXRlIHRha2VTZWxmaWUoKSB7XG4gICAgY29uc3QgbWltZVR5cGU6IHN0cmluZyA9ICdpbWFnZS9qcGVnJztcbiAgICBjb25zdCB7IHZpZGVvV2lkdGgsIG9mZnNldFdpZHRoLCB2aWRlb0hlaWdodCB9ID0gdGhpcy52aWRlbztcblxuICAgIGxldCBfY2FudmFzOiBIVE1MQ2FudmFzRWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpOyAvL3RoaXMuY2FudmFzU25hcHNob3QubmF0aXZlRWxlbWVudDtcblxuICAgIGNvbnN0IHsgdywgaCB9ID0gdGhpcy5jYW1lcmFQcm92aWRlci5yZWN0UG9zaXRpb247XG5cbiAgICBjb25zdCBhc3BlY3QgPSB2aWRlb1dpZHRoIC8gb2Zmc2V0V2lkdGg7XG5cbiAgICAvLyBjb25zb2xlLmxvZyh2aWRlb1dpZHRoLCBvZmZzZXRXaWR0aCwgbCwgdCwgdywgaCk7XG5cbiAgICBfY2FudmFzLndpZHRoID0gdyAqIGFzcGVjdDtcbiAgICBfY2FudmFzLmhlaWdodCA9IGggKiBhc3BlY3Q7XG5cbiAgICBjb25zdCBkeCA9IHZpZGVvV2lkdGggLSB3ICogYXNwZWN0O1xuICAgIGNvbnN0IGR5ID0gdmlkZW9IZWlnaHQgLSBoICogYXNwZWN0O1xuICAgIGNvbnN0IHggPSBkeCAvIDI7XG4gICAgY29uc3QgeSA9IGR5IC8gMjtcblxuICAgIGNvbnN0IGN0eDogYW55ID0gX2NhbnZhcy5nZXRDb250ZXh0KCcyZCcsIHtcbiAgICAgIGFscGhhOiBmYWxzZSxcbiAgICAgIHBvd2VyUHJlZmVyZW5jZTogJ2hpZ2gtcGVyZm9ybWFuY2UnLFxuICAgICAgYW50aWFsaWFzOiBmYWxzZSxcbiAgICAgIGRlcHRoOiBmYWxzZSxcbiAgICAgIGRlc3luY2hyb25pemVkOiB0cnVlLFxuICAgIH0pO1xuXG4gICAgaWYgKGN0eCkge1xuICAgICAgY3R4LmRyYXdJbWFnZShcbiAgICAgICAgdGhpcy52aWRlbyxcbiAgICAgICAgeCxcbiAgICAgICAgeSxcbiAgICAgICAgdyAqIGFzcGVjdCxcbiAgICAgICAgaCAqIGFzcGVjdCxcbiAgICAgICAgMCxcbiAgICAgICAgMCxcbiAgICAgICAgdyAqIGFzcGVjdCxcbiAgICAgICAgaCAqIGFzcGVjdFxuICAgICAgKTtcblxuICAgICAgY29uc3QgaW1nQXNVcmw6IGFueSA9IF9jYW52YXMudG9EYXRhVVJMKG1pbWVUeXBlLCAxKTtcblxuICAgICAgdGhpcy5pbWFnZUNhcHR1cmUuZW1pdChcbiAgICAgICAgbmV3IFdlYmNhbUltYWdlKGltZ0FzVXJsLCBtaW1lVHlwZSwgbmV3IEltYWdlRGF0YSgxLCAxKSwgbnVsbClcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgaHVtYW5GaWxlU2l6ZShieXRlczogbnVtYmVyLCBzaSA9IGZhbHNlLCBkcCA9IDEpIHtcbiAgICBjb25zdCB0aHJlc2ggPSBzaSA/IDEwMDAgOiAxMDI0O1xuXG4gICAgaWYgKE1hdGguYWJzKGJ5dGVzKSA8IHRocmVzaCkge1xuICAgICAgcmV0dXJuIGJ5dGVzICsgJyBCJztcbiAgICB9XG5cbiAgICBjb25zdCB1bml0cyA9IHNpXG4gICAgICA/IFsna0InLCAnTUInLCAnR0InLCAnVEInLCAnUEInLCAnRUInLCAnWkInLCAnWUInXVxuICAgICAgOiBbJ0tpQicsICdNaUInLCAnR2lCJywgJ1RpQicsICdQaUInLCAnRWlCJywgJ1ppQicsICdZaUInXTtcbiAgICBsZXQgdSA9IC0xO1xuICAgIGNvbnN0IHIgPSAxMCAqKiBkcDtcblxuICAgIGRvIHtcbiAgICAgIGJ5dGVzIC89IHRocmVzaDtcbiAgICAgICsrdTtcbiAgICB9IHdoaWxlIChcbiAgICAgIE1hdGgucm91bmQoTWF0aC5hYnMoYnl0ZXMpICogcikgLyByID49IHRocmVzaCAmJlxuICAgICAgdSA8IHVuaXRzLmxlbmd0aCAtIDFcbiAgICApO1xuXG4gICAgcmV0dXJuIGJ5dGVzLnRvRml4ZWQoZHApICsgJyAnICsgdW5pdHNbdV07XG4gIH1cblxuICB0YWtlU25hcHNob3QodGltZTogbnVtYmVyKSB7XG4gICAgaWYgKHRoaXMudHlwZSAhPT0gJ2RvY3VtZW50Jykge1xuICAgICAgdGhpcy50YWtlU2VsZmllKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vIGNvbnNvbGUud2FybignU05BUCcsIHRpbWUpO1xuICAgIGlmICghdGhpcy5zaG93VmlkZW8pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy56b25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgIGNvbnN0IGNhbnZhc1NtYWxTaXplID0gMzg0O1xuXG4gICAgICBjb25zdCBtaW1lVHlwZTogc3RyaW5nID0gJ2ltYWdlL2pwZWcnO1xuXG4gICAgICAvLyBsZXQgX2NhbnZhczogSFRNTENhbnZhc0VsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKTsgLy90aGlzLmNhbnZhc1NuYXBzaG90Lm5hdGl2ZUVsZW1lbnQ7XG5cbiAgICAgIGNvbnN0IHsgdmlkZW9XaWR0aCwgdmlkZW9IZWlnaHQgfSA9IHRoaXMudmlkZW87XG5cbiAgICAgIC8vIF9jYW52YXMud2lkdGggPSB2aWRlb1dpZHRoO1xuICAgICAgLy8gX2NhbnZhcy5oZWlnaHQgPSB2aWRlb0hlaWdodDtcbiAgICAgIC8vIGNvbnNvbGUubG9nKHZpZGVvV2lkdGgsIHZpZGVvSGVpZ2h0KTtcblxuICAgICAgLy8gY29uc3QgY3R4OiBhbnkgPSBfY2FudmFzLmdldENvbnRleHQoJzJkJywge1xuICAgICAgLy8gICBhbHBoYTogZmFsc2UsXG4gICAgICAvLyAgIHBvd2VyUHJlZmVyZW5jZTogJ2hpZ2gtcGVyZm9ybWFuY2UnLFxuICAgICAgLy8gICBhbnRpYWxpYXM6IGZhbHNlLFxuICAgICAgLy8gICBkZXB0aDogZmFsc2UsXG4gICAgICAvLyAgIGRlc3luY2hyb25pemVkOiB0cnVlLFxuICAgICAgLy8gfSk7XG5cbiAgICAgIC8vIGNvbnN0IGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpOyAvLyBuZWVkcyBhbiBpbml0aWFsIHNpemVcbiAgICAgIC8vIGNhbnZhcy5oZWlnaHQgPSBjYW52YXNTbWFsU2l6ZTtcbiAgICAgIC8vIGNhbnZhcy53aWR0aCA9IGNhbnZhc1NtYWxTaXplO1xuXG4gICAgICAvLyBjb25zdCBjdHhPOiBhbnkgPSBjYW52YXMuZ2V0Q29udGV4dCgnMmQnLCB7XG4gICAgICAvLyAgIGFscGhhOiBmYWxzZSxcbiAgICAgIC8vICAgcG93ZXJQcmVmZXJlbmNlOiAnaGlnaC1wZXJmb3JtYW5jZScsXG4gICAgICAvLyAgIGFudGlhbGlhczogZmFsc2UsXG4gICAgICAvLyAgIGRlcHRoOiBmYWxzZSxcbiAgICAgIC8vICAgZGVzeW5jaHJvbml6ZWQ6IHRydWUsXG4gICAgICAvLyB9KTtcblxuICAgICAgY29uc3QgeyBjdHgsIGN0eE8sIGNhbnZhcywgX2NhbnZhcywgc2l6ZSB9ID0gdGhpcy5jYW52YXNEYXRhO1xuXG4gICAgICBpZiAoY3R4ICYmIGN0eE8pIHtcbiAgICAgICAgY3R4LmltYWdlU21vb3RoaW5nRW5hYmxlZCA9IGZhbHNlO1xuICAgICAgICBjb25zdCBkcmF3U3RhcnQgPSBEYXRlLm5vdygpO1xuICAgICAgICBjdHguY2xlYXJSZWN0KDAsIDAsIHZpZGVvV2lkdGgsIHZpZGVvSGVpZ2h0KTtcbiAgICAgICAgY3R4Ty5jbGVhclJlY3QoMCwgMCwgc2l6ZS53LCBzaXplLmgpO1xuXG4gICAgICAgIGN0eC5kcmF3SW1hZ2UodGhpcy52aWRlbywgMCwgMCk7XG4gICAgICAgIC8vY29uc29sZS50aW1lKCdkcmF3VmlkZW8nKTtcbiAgICAgICAgY3R4Ty5kcmF3SW1hZ2UoX2NhbnZhcywgMCwgMCwgc2l6ZS53LCBzaXplLmgpO1xuICAgICAgICAvL2NvbnNvbGUudGltZUVuZCgnZHJhd1ZpZGVvJyk7XG4gICAgICAgIC8vY29uc29sZS50aW1lKCdEUkFXJyk7XG5cbiAgICAgICAgLy8gIGNvbnN0IGltRGF0YTogYW55ID0gY3R4LmdldEltYWdlRGF0YSgwLCAwLCB2aWRlb1dpZHRoLCB2aWRlb0hlaWdodCk7XG5cbiAgICAgICAgY29uc29sZS5sb2coY2FudmFzLndpZHRoLCBfY2FudmFzLndpZHRoKTtcbiAgICAgICAgLy9jb25zb2xlLnRpbWVFbmQoJ0RSQVcnKTtcblxuICAgICAgICAvL2NvbnNvbGUudGltZSgnQ1RYJyk7XG5cbiAgICAgICAgY29uc3QgcmVzaXplID0gY2FudmFzLnRvRGF0YVVSTCgnaW1hZ2UvanBlZycpO1xuXG4gICAgICAgIGNvbnN0IGNhbnZhc0RhdGEgPSBfY2FudmFzLnRvRGF0YVVSTChtaW1lVHlwZSwgMSk7XG5cbiAgICAgICAgY29uc29sZS5sb2codGhpcy5odW1hbkZpbGVTaXplKGNhbnZhc0RhdGEubGVuZ3RoKSk7XG4gICAgICAgIGNvbnNvbGUubG9nKHRoaXMuaHVtYW5GaWxlU2l6ZShyZXNpemUubGVuZ3RoKSk7XG4gICAgICAgIGNvbnNvbGUubG9nKG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKSk7XG4gICAgICAgIC8vY29uc29sZS50aW1lRW5kKCdDVFgnKTtcbiAgICAgICAgY29uc3QgY3VycmVudFRpbWUgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbiAgICAgICAgY29uc3QgZGlmZiA9IGN1cnJlbnRUaW1lIC0gdGltZTtcblxuICAgICAgICAvLyB0b3RhbCB0aW1lIGZvciBwYWNrIG9uZSBpbWFnZVxuICAgICAgICBjb25zdCBkcmF3VGltZSA9IERhdGUubm93KCkgLSBkcmF3U3RhcnQ7XG5cbiAgICAgICAgLy9jb25zb2xlLndhcm4oJ0RSQVcgVElNRScsIGRyYXdUaW1lKTtcbiAgICAgICAgY29uc3QgZGVsYXlNYXggPSBkcmF3VGltZSA8IDYwID8gMTAwIDogMjAwO1xuXG4gICAgICAgIGNvbnN0IGRlbGF5ID0gZGlmZiA+IGRlbGF5TWF4ID8gMCA6IGRlbGF5TWF4IC0gZGlmZjtcblxuICAgICAgICBjb25zdCB0aW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgdGhpcy5pbWFnZUNhcHR1cmUuZW1pdChcbiAgICAgICAgICAgIG5ldyBXZWJjYW1JbWFnZShjYW52YXNEYXRhLCBtaW1lVHlwZSwgJycsIHJlc2l6ZSlcbiAgICAgICAgICApO1xuICAgICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcbiAgICAgICAgfSwgZGVsYXkpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG50ZXN0KCl7XG4gIHRoaXMuZHJhd1JlY3RhbmdsZSgpXG59XG4gIHByaXZhdGUgc3RvcEFsbFRyYWNrcygpIHtcbiAgICB0aGlzLnNob3dWaWRlbyA9IGZhbHNlO1xuICAgIGlmICh0aGlzLm1lZGlhU3RyZWFtICYmIHRoaXMubWVkaWFTdHJlYW0uZ2V0VHJhY2tzKSB7XG4gICAgICAvLyBnZXRUcmFja3MoKSByZXR1cm5zIGFsbCBtZWRpYSB0cmFja3MgKHZpZGVvK2F1ZGlvKVxuXG4gICAgICB0aGlzLm1lZGlhU3RyZWFtLmdldFRyYWNrcygpLmZvckVhY2goKHRyYWNrOiBNZWRpYVN0cmVhbVRyYWNrKSA9PiB7XG4gICAgICAgIC8vICBjb25zb2xlLmxvZyh0cmFjayk7XG4gICAgICAgIHRyYWNrLmVuYWJsZWQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5jZC5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICAgIHRyYWNrLnN0b3AoKTtcblxuICAgICAgICB0aGlzLnZpZGVvLnNyY09iamVjdC5yZW1vdmVUcmFjayh0cmFjayk7XG4gICAgICAgIHRoaXMubWVkaWFTdHJlYW0ucmVtb3ZlVHJhY2sodHJhY2spO1xuXG4gICAgICAgIHRoaXMuY2QuZGV0ZWN0Q2hhbmdlcygpO1xuICAgICAgfSk7XG4gICAgICB0aGlzLnZpZGVvLnNyY09iamVjdCA9IG51bGw7XG4gICAgICAvLyB0aGlzLnZpZGVvLnNyYyA9IG51bGw7XG5cbiAgICAgIHRoaXMudmlkZW8ubG9hZCgpO1xuICAgIH1cbiAgICAvLyB0aGlzLl9fc3Vicyh0aGlzLnN0b3BWaWRlb1RyYWNrcygpKS5zdWJzY3JpYmUoKVxuICB9XG5cbiAgcHJpdmF0ZSBkcmF3UmVjdGFuZ2xlKCkge1xuICAgIGNvbnNvbGUud2FybignUkVDVCcpXG4gICAgdGhpcy56b25lLnJ1bigoKSA9PiB7XG4gICAgICBjb25zdCBfY2FudmFzID0gdGhpcy5jYW52YXMubmF0aXZlRWxlbWVudDtcbiAgICAgIGxldCBwYWRkaW5nID0gMTA7XG4gICAgICBpZiAoIXRoaXMuaXNNb2JpbGUgJiYgX2NhbnZhcy53aWR0aCAhPT0gX2NhbnZhcy5oZWlnaHQpIHtcbiAgICAgICAgcGFkZGluZyA9IDQwO1xuICAgICAgfVxuICAgICAgY29uc3QgY3R4ID0gX2NhbnZhcy5nZXRDb250ZXh0KCcyZCcpO1xuXG4gICAgICBjdHguY2xlYXJSZWN0KDAsIDAsIF9jYW52YXMud2lkdGgsIF9jYW52YXMuaGVpZ2h0KTtcblxuICAgICAgY29uc3QgeyB3aWR0aCwgaGVpZ2h0IH0gPSBfY2FudmFzO1xuXG4gICAgICBjb25zb2xlLmxvZygnQ0FOVkFTJywgd2lkdGgsIGhlaWdodCk7XG5cbiAgICAgIGxldCB7IHZpZGVvV2lkdGgsIHZpZGVvSGVpZ2h0IH0gPSB0aGlzLnZpZGVvO1xuXG4gICAgICAvLyB2aWRlbyB3aWxsIGJlIHNjYWxlZCB0byBtYXggY2FudmFzIGhlaWdodFxuICAgICAgY29uc3QgYXNwZWN0ID0gdmlkZW9XaWR0aCAvIHZpZGVvSGVpZ2h0O1xuXG4gICAgICAvLyBpZiAodmlkZW9IZWlnaHQgPCBoZWlnaHQpIHtcbiAgICAgIC8vICAgdmlkZW9IZWlnaHQgPSBoZWlnaHQ7XG4gICAgICAvLyAgIHZpZGVvV2lkdGggPSBoZWlnaHQqYXNwZWN0O1xuICAgICAgLy8gfVxuXG4gICAgICBjb25zb2xlLmxvZygnVklERU8nLCB2aWRlb1dpZHRoLCB2aWRlb0hlaWdodCk7XG5cbiAgICAgIGNvbnN0IGRvY1NpemUgPSB0aGlzLnR5cGUgPT09ICdzZWxmaWUnID8gMSA6IDg2IC8gNTU7XG5cbiAgICAgIGxldCBfaGVpZ2h0O1xuICAgICAgbGV0IF93aWR0aDtcblxuICAgICAgaWYgKHZpZGVvV2lkdGggPj0gdmlkZW9IZWlnaHQpIHtcbiAgICAgICAgX3dpZHRoID0gd2lkdGg7XG5cbiAgICAgICAgX2hlaWdodCA9IF93aWR0aCAvIGFzcGVjdDtcblxuICAgICAgICBpZiAoX2hlaWdodCA+IGhlaWdodCkge1xuICAgICAgICAgIF9oZWlnaHQgPSBoZWlnaHQ7XG4gICAgICAgICAgX3dpZHRoID0gYXNwZWN0ICogX2hlaWdodDtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgX2hlaWdodCA9IGhlaWdodDtcbiAgICAgICAgX3dpZHRoID0gYXNwZWN0ICogX2hlaWdodDtcbiAgICAgICAgaWYgKF93aWR0aCA+IHdpZHRoKSB7XG4gICAgICAgICAgX3dpZHRoID0gd2lkdGg7XG4gICAgICAgICAgX2hlaWdodCA9IF93aWR0aCAvIGFzcGVjdDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjb25zb2xlLmxvZygnQ0FMQycsIF93aWR0aCwgX2hlaWdodCk7XG4gICAgICBsZXQgdywgaDtcblxuICAgICAgaWYgKF93aWR0aCA8PSBfaGVpZ2h0KSB7XG4gICAgICAgIHcgPSBfd2lkdGggLSAyICogcGFkZGluZztcbiAgICAgICAgaCA9IHcgLyBkb2NTaXplO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaCA9IF9oZWlnaHQgLSAyICogcGFkZGluZztcbiAgICAgICAgdyA9IGRvY1NpemUgKiBoO1xuICAgICAgfVxuICAgICAgaWYgKHcgPiBfd2lkdGgpIHtcbiAgICAgICAgdyA9IF93aWR0aCAtIDIgKiBwYWRkaW5nO1xuICAgICAgICBoID0gdyAvIGRvY1NpemU7XG4gICAgICB9XG5cbiAgICAgIGggPSBNYXRoLmZsb29yKGgpO1xuICAgICAgdyA9IE1hdGguZmxvb3Iodyk7XG4gICAgICBjb25zb2xlLmxvZyh3LCBoKTtcblxuICAgICAgY29uc3QgbGVmdCA9IE1hdGguZmxvb3IoKHdpZHRoIC0gdykgLyAyKTtcbiAgICAgIGNvbnN0IHRvcCA9IE1hdGguZmxvb3IoKGhlaWdodCAtIGgpIC8gMik7XG5cbiAgICAgIGN0eC5zdHJva2VTdHlsZSA9ICd3aGl0ZSc7XG5cbiAgICAgIC8vIGN0eC5zdHJva2VSZWN0KGxlZnQsIHRvcCwgX3dpZHRoLCBfaGVpZ2h0KTtcbiAgICAgIGN0eC5maWxsU3R5bGUgPSAncmdiYSgyNTUsIDI1NSwgMjU1LCAwLjIpJztcbiAgICAgIC8vIGN0eC5zaGFkb3dDb2xvciA9ICd3aGl0ZSc7XG4gICAgICBjdHguc2hhZG93Qmx1ciA9IDE1O1xuICAgICAgY3R4LmJlZ2luUGF0aCgpO1xuXG4gICAgICAvLyBEcmF3IHVzaW5nIDVweCBmb3IgYm9yZGVyIHJhZGl1cyBvbiBhbGwgc2lkZXNcbiAgICAgIC8vIHN0cm9rZSBpdCBidXQgbm8gZmlsbFxuICAgICAgY29uc3QgcmFkaXVzID0gdGhpcy5pc01vYmlsZSA/IDEwIDogMzA7XG5cbiAgICAgIGN0eC5yb3VuZFJlY3QobGVmdCwgdG9wLCB3LCBoLCByYWRpdXMpO1xuICAgICAgY3R4LnN0cm9rZSgpO1xuICAgICAgY3R4LmZpbGwoKTtcbiAgICAgIGNvbnNvbGUud2FybignQ0FOJyxsZWZ0LCB0b3AsIHcsIGgsIHJhZGl1cyxjdHgpO1xuXG4gICAgICB0aGlzLmNhbWVyYVByb3ZpZGVyLnJlY3RQb3NpdGlvbiA9IHtcbiAgICAgICAgbDogbGVmdCxcbiAgICAgICAgdDogdG9wLFxuICAgICAgICB3LFxuICAgICAgICBoLFxuICAgICAgICBfdzogX3dpZHRoLFxuICAgICAgICBfaDogX2hlaWdodCxcbiAgICAgIH07XG5cbiAgICAgIHRoaXMuc2V0Q2FudmFzKCk7XG4gICAgICAvLyBjdHguc3Ryb2tlKCk7XG4gICAgfSk7XG4gIH1cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy52aWRlby5wYXVzZSgpO1xuXG4gICAgLy8gdGhpcy52aWRlby5nZXRUcmFja3MoKS5mb3JFYWNoKCh0cmFjazogYW55KSA9PiB7XG4gICAgLy8gICB0cmFjay5zdG9wKCk7XG4gICAgLy8gICB0aGlzLnZpZGVvLnNyY09iamVjdC5yZW1vdmVUcmFjayh0cmFjayk7XG4gICAgLy8gfSk7XG5cbiAgICB0aGlzLnN0b3BBbGxUcmFja3MoKTtcblxuICAgIGlmICh0aGlzLnRyaWdnZXJTdWJzY3JpcHRpb24pIHtcbiAgICAgIHRoaXMudHJpZ2dlclN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICAgIH1cbiAgICB0aGlzLl9fZGVzdHJveSgpO1xuXG4gICAgY29uc29sZS53YXJuKCdbVklERU9dIGRlc3Ryb3llZCcpO1xuICB9XG59XG4iLCI8ZGl2IGNsYXNzPVwid2ViY2FtLXdyYXBwZXJcIj5cbiAgPHZpZGVvICN2aWRlbyBhdXRvcGxheSBtdXRlZCBzdHlsZT1cImRpc3BsYXk6IGJsb2NrXCIgcGxheXNpbmxpbmU+PC92aWRlbz5cblxuICA8ZGl2IGNsYXNzPVwicmVjdGFuZ2xlXCI+XG4gICAgPGNhbnZhc1xuICAgICAgI2NhbnZhc1xuICAgICAgW25nU3R5bGVdPVwieyB2aXNpYmlsaXR5OiBzaG93VmlkZW8gPyAndmlzaWJsZScgOiAnaGlkZGVuJyB9XCJcbiAgICAgIFt3aWR0aF09XCJ2aWRlby5vZmZzZXRXaWR0aFwiXG4gICAgICBbaGVpZ2h0XT1cInZpZGVvLm9mZnNldEhlaWdodFwiXG4gICAgPjwvY2FudmFzPlxuICA8L2Rpdj5cblxuXG48L2Rpdj5cbiJdfQ==
|