ngx-image-cropper 4.0.1 → 6.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.
Files changed (89) hide show
  1. package/README.md +1 -0
  2. package/esm2020/lib/component/image-cropper.component.mjs +540 -0
  3. package/esm2020/lib/image-cropper.module.mjs +26 -0
  4. package/esm2020/lib/interfaces/cropper-options.interface.mjs +2 -0
  5. package/esm2020/lib/interfaces/cropper-position.interface.mjs +2 -0
  6. package/esm2020/lib/interfaces/cropper.settings.mjs +50 -0
  7. package/esm2020/lib/interfaces/dimensions.interface.mjs +2 -0
  8. package/esm2020/lib/interfaces/exif-transform.interface.mjs +2 -0
  9. package/esm2020/lib/interfaces/image-cropped-event.interface.mjs +2 -0
  10. package/esm2020/lib/interfaces/image-transform.interface.mjs +2 -0
  11. package/esm2020/lib/interfaces/index.mjs +2 -0
  12. package/esm2020/lib/interfaces/loaded-image.interface.mjs +2 -0
  13. package/esm2020/lib/interfaces/move-start.interface.mjs +7 -0
  14. package/esm2020/lib/services/crop.service.mjs +117 -0
  15. package/esm2020/lib/services/cropper-position.service.mjs +201 -0
  16. package/esm2020/lib/services/load-image.service.mjs +168 -0
  17. package/esm2020/lib/utils/blob.utils.mjs +12 -0
  18. package/esm2020/lib/utils/exif.utils.mjs +89 -0
  19. package/esm2020/lib/utils/hammer.utils.mjs +2 -0
  20. package/esm2020/lib/utils/keyboard.utils.mjs +40 -0
  21. package/esm2020/lib/utils/resize.utils.mjs +75 -0
  22. package/esm2020/ngx-image-cropper.mjs +5 -0
  23. package/esm2020/public-api.mjs +6 -0
  24. package/fesm2015/{ngx-image-cropper.js → ngx-image-cropper.mjs} +544 -1324
  25. package/fesm2015/ngx-image-cropper.mjs.map +1 -0
  26. package/fesm2020/ngx-image-cropper.mjs +1315 -0
  27. package/fesm2020/ngx-image-cropper.mjs.map +1 -0
  28. package/lib/component/image-cropper.component.d.ts +15 -12
  29. package/lib/image-cropper.module.d.ts +6 -0
  30. package/lib/interfaces/cropper.settings.d.ts +1 -1
  31. package/lib/interfaces/index.d.ts +1 -0
  32. package/lib/services/crop.service.d.ts +4 -1
  33. package/lib/services/cropper-position.service.d.ts +3 -0
  34. package/lib/services/load-image.service.d.ts +3 -0
  35. package/lib/utils/hammer.utils.d.ts +1 -1
  36. package/ngx-image-cropper.d.ts +1 -3
  37. package/package.json +24 -15
  38. package/bundles/ngx-image-cropper.umd.js +0 -2617
  39. package/bundles/ngx-image-cropper.umd.js.map +0 -1
  40. package/bundles/ngx-image-cropper.umd.min.js +0 -16
  41. package/bundles/ngx-image-cropper.umd.min.js.map +0 -1
  42. package/esm2015/lib/component/image-cropper.component.js +0 -825
  43. package/esm2015/lib/image-cropper.module.js +0 -24
  44. package/esm2015/lib/interfaces/cropper-options.interface.js +0 -56
  45. package/esm2015/lib/interfaces/cropper-position.interface.js +0 -20
  46. package/esm2015/lib/interfaces/cropper.settings.js +0 -140
  47. package/esm2015/lib/interfaces/dimensions.interface.js +0 -16
  48. package/esm2015/lib/interfaces/exif-transform.interface.js +0 -16
  49. package/esm2015/lib/interfaces/image-cropped-event.interface.js +0 -24
  50. package/esm2015/lib/interfaces/image-transform.interface.js +0 -20
  51. package/esm2015/lib/interfaces/index.js +0 -6
  52. package/esm2015/lib/interfaces/loaded-image.interface.js +0 -18
  53. package/esm2015/lib/interfaces/move-start.interface.js +0 -37
  54. package/esm2015/lib/services/crop.service.js +0 -176
  55. package/esm2015/lib/services/cropper-position.service.js +0 -257
  56. package/esm2015/lib/services/load-image.service.js +0 -304
  57. package/esm2015/lib/utils/blob.utils.js +0 -26
  58. package/esm2015/lib/utils/exif.utils.js +0 -128
  59. package/esm2015/lib/utils/hammer.utils.js +0 -29
  60. package/esm2015/lib/utils/keyboard.utils.js +0 -58
  61. package/esm2015/lib/utils/resize.utils.js +0 -116
  62. package/esm2015/ngx-image-cropper.js +0 -13
  63. package/esm2015/public-api.js +0 -11
  64. package/esm5/lib/component/image-cropper.component.js +0 -978
  65. package/esm5/lib/image-cropper.module.js +0 -28
  66. package/esm5/lib/interfaces/cropper-options.interface.js +0 -56
  67. package/esm5/lib/interfaces/cropper-position.interface.js +0 -20
  68. package/esm5/lib/interfaces/cropper.settings.js +0 -156
  69. package/esm5/lib/interfaces/dimensions.interface.js +0 -16
  70. package/esm5/lib/interfaces/exif-transform.interface.js +0 -16
  71. package/esm5/lib/interfaces/image-cropped-event.interface.js +0 -24
  72. package/esm5/lib/interfaces/image-transform.interface.js +0 -20
  73. package/esm5/lib/interfaces/index.js +0 -6
  74. package/esm5/lib/interfaces/loaded-image.interface.js +0 -18
  75. package/esm5/lib/interfaces/move-start.interface.js +0 -37
  76. package/esm5/lib/services/crop.service.js +0 -214
  77. package/esm5/lib/services/cropper-position.service.js +0 -296
  78. package/esm5/lib/services/load-image.service.js +0 -366
  79. package/esm5/lib/utils/blob.utils.js +0 -26
  80. package/esm5/lib/utils/exif.utils.js +0 -128
  81. package/esm5/lib/utils/hammer.utils.js +0 -29
  82. package/esm5/lib/utils/keyboard.utils.js +0 -58
  83. package/esm5/lib/utils/resize.utils.js +0 -116
  84. package/esm5/ngx-image-cropper.js +0 -13
  85. package/esm5/public-api.js +0 -11
  86. package/fesm2015/ngx-image-cropper.js.map +0 -1
  87. package/fesm5/ngx-image-cropper.js +0 -2399
  88. package/fesm5/ngx-image-cropper.js.map +0 -1
  89. package/ngx-image-cropper.metadata.json +0 -1
@@ -1,825 +0,0 @@
1
- /**
2
- * @fileoverview added by tsickle
3
- * Generated from: lib/component/image-cropper.component.ts
4
- * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
5
- */
6
- import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, EventEmitter, HostBinding, HostListener, Input, isDevMode, Output, ViewChild } from '@angular/core';
7
- import { DomSanitizer } from '@angular/platform-browser';
8
- import { MoveTypes } from '../interfaces/move-start.interface';
9
- import { CropService } from '../services/crop.service';
10
- import { CropperSettings } from '../interfaces/cropper.settings';
11
- import { LoadImageService } from '../services/load-image.service';
12
- import { CropperPositionService } from '../services/cropper-position.service';
13
- import { getEventForKey, getInvertedPositionForKey, getPositionForKey } from '../utils/keyboard.utils';
14
- export class ImageCropperComponent {
15
- /**
16
- * @param {?} cropService
17
- * @param {?} cropperPositionService
18
- * @param {?} loadImageService
19
- * @param {?} sanitizer
20
- * @param {?} cd
21
- */
22
- constructor(cropService, cropperPositionService, loadImageService, sanitizer, cd) {
23
- this.cropService = cropService;
24
- this.cropperPositionService = cropperPositionService;
25
- this.loadImageService = loadImageService;
26
- this.sanitizer = sanitizer;
27
- this.cd = cd;
28
- this.Hammer = typeof window !== 'undefined'
29
- ? (/** @type {?} */ (((/** @type {?} */ (window))).Hammer))
30
- : null;
31
- this.settings = new CropperSettings();
32
- this.setImageMaxSizeRetries = 0;
33
- this.marginLeft = '0px';
34
- this.moveTypes = MoveTypes;
35
- this.imageVisible = false;
36
- this.format = this.settings.format;
37
- this.transform = {};
38
- this.maintainAspectRatio = this.settings.maintainAspectRatio;
39
- this.aspectRatio = this.settings.aspectRatio;
40
- this.resizeToWidth = this.settings.resizeToWidth;
41
- this.resizeToHeight = this.settings.resizeToHeight;
42
- this.cropperMinWidth = this.settings.cropperMinWidth;
43
- this.cropperMinHeight = this.settings.cropperMinHeight;
44
- this.cropperMaxHeight = this.settings.cropperMaxHeight;
45
- this.cropperMaxWidth = this.settings.cropperMaxWidth;
46
- this.cropperStaticWidth = this.settings.cropperStaticWidth;
47
- this.cropperStaticHeight = this.settings.cropperStaticHeight;
48
- this.canvasRotation = this.settings.canvasRotation;
49
- this.initialStepSize = this.settings.initialStepSize;
50
- this.roundCropper = this.settings.roundCropper;
51
- this.onlyScaleDown = this.settings.onlyScaleDown;
52
- this.imageQuality = this.settings.imageQuality;
53
- this.autoCrop = this.settings.autoCrop;
54
- this.backgroundColor = this.settings.backgroundColor;
55
- this.containWithinAspectRatio = this.settings.containWithinAspectRatio;
56
- this.hideResizeSquares = this.settings.hideResizeSquares;
57
- this.cropper = {
58
- x1: -100,
59
- y1: -100,
60
- x2: 10000,
61
- y2: 10000
62
- };
63
- this.alignImage = this.settings.alignImage;
64
- this.disabled = false;
65
- this.imageCropped = new EventEmitter();
66
- this.startCropImage = new EventEmitter();
67
- this.imageLoaded = new EventEmitter();
68
- this.cropperReady = new EventEmitter();
69
- this.loadImageFailed = new EventEmitter();
70
- this.reset();
71
- }
72
- /**
73
- * @param {?} changes
74
- * @return {?}
75
- */
76
- ngOnChanges(changes) {
77
- this.onChangesUpdateSettings(changes);
78
- this.onChangesInputImage(changes);
79
- if (this.loadedImage && this.loadedImage.original.image.complete
80
- && (changes.containWithinAspectRatio || changes.canvasRotation)) {
81
- this.loadImageService
82
- .transformLoadedImage(this.loadedImage, this.settings)
83
- .then((/**
84
- * @param {?} res
85
- * @return {?}
86
- */
87
- (res) => this.setLoadedImage(res)))
88
- .catch((/**
89
- * @param {?} err
90
- * @return {?}
91
- */
92
- (err) => this.loadImageError(err)));
93
- }
94
- if (changes.cropper || changes.maintainAspectRatio || changes.aspectRatio) {
95
- this.setMaxSize();
96
- this.setCropperScaledMinSize();
97
- this.setCropperScaledMaxSize();
98
- if (this.maintainAspectRatio && (changes.maintainAspectRatio || changes.aspectRatio)) {
99
- this.resetCropperPosition();
100
- }
101
- else if (changes.cropper) {
102
- this.checkCropperPosition(false);
103
- this.doAutoCrop();
104
- }
105
- this.cd.markForCheck();
106
- }
107
- if (changes.transform) {
108
- this.transform = this.transform || {};
109
- this.setCssTransform();
110
- this.doAutoCrop();
111
- }
112
- }
113
- /**
114
- * @private
115
- * @param {?} changes
116
- * @return {?}
117
- */
118
- onChangesUpdateSettings(changes) {
119
- this.settings.setOptionsFromChanges(changes);
120
- if (this.settings.cropperStaticHeight && this.settings.cropperStaticWidth) {
121
- this.settings.setOptions({
122
- hideResizeSquares: true,
123
- cropperMinWidth: this.settings.cropperStaticWidth,
124
- cropperMinHeight: this.settings.cropperStaticHeight,
125
- cropperMaxHeight: this.settings.cropperStaticHeight,
126
- cropperMaxWidth: this.settings.cropperStaticWidth,
127
- maintainAspectRatio: false
128
- });
129
- }
130
- }
131
- /**
132
- * @private
133
- * @param {?} changes
134
- * @return {?}
135
- */
136
- onChangesInputImage(changes) {
137
- if (changes.imageChangedEvent || changes.imageURL || changes.imageBase64 || changes.imageFile) {
138
- this.reset();
139
- }
140
- if (changes.imageChangedEvent && this.isValidImageChangedEvent()) {
141
- this.loadImageFile(this.imageChangedEvent.target.files[0]);
142
- }
143
- if (changes.imageURL && this.imageURL) {
144
- this.loadImageFromURL(this.imageURL);
145
- }
146
- if (changes.imageBase64 && this.imageBase64) {
147
- this.loadBase64Image(this.imageBase64);
148
- }
149
- if (changes.imageFile && this.imageFile) {
150
- this.loadImageFile(this.imageFile);
151
- }
152
- }
153
- /**
154
- * @private
155
- * @return {?}
156
- */
157
- isValidImageChangedEvent() {
158
- return this.imageChangedEvent
159
- && this.imageChangedEvent.target
160
- && this.imageChangedEvent.target.files
161
- && this.imageChangedEvent.target.files.length > 0;
162
- }
163
- /**
164
- * @private
165
- * @return {?}
166
- */
167
- setCssTransform() {
168
- this.safeTransformStyle = this.sanitizer.bypassSecurityTrustStyle('scaleX(' + (this.transform.scale || 1) * (this.transform.flipH ? -1 : 1) + ')' +
169
- 'scaleY(' + (this.transform.scale || 1) * (this.transform.flipV ? -1 : 1) + ')' +
170
- 'rotate(' + (this.transform.rotate || 0) + 'deg)');
171
- }
172
- /**
173
- * @return {?}
174
- */
175
- ngOnInit() {
176
- this.settings.stepSize = this.initialStepSize;
177
- this.activatePinchGesture();
178
- }
179
- /**
180
- * @private
181
- * @return {?}
182
- */
183
- reset() {
184
- this.imageVisible = false;
185
- this.loadedImage = null;
186
- this.safeImgDataUrl = 'data:image/png;base64,iVBORw0KGg'
187
- + 'oAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQYV2NgAAIAAAU'
188
- + 'AAarVyFEAAAAASUVORK5CYII=';
189
- this.moveStart = {
190
- active: false,
191
- type: null,
192
- position: null,
193
- x1: 0,
194
- y1: 0,
195
- x2: 0,
196
- y2: 0,
197
- clientX: 0,
198
- clientY: 0
199
- };
200
- this.maxSize = {
201
- width: 0,
202
- height: 0
203
- };
204
- this.cropper.x1 = -100;
205
- this.cropper.y1 = -100;
206
- this.cropper.x2 = 10000;
207
- this.cropper.y2 = 10000;
208
- }
209
- /**
210
- * @private
211
- * @param {?} file
212
- * @return {?}
213
- */
214
- loadImageFile(file) {
215
- this.loadImageService
216
- .loadImageFile(file, this.settings)
217
- .then((/**
218
- * @param {?} res
219
- * @return {?}
220
- */
221
- (res) => this.setLoadedImage(res)))
222
- .catch((/**
223
- * @param {?} err
224
- * @return {?}
225
- */
226
- (err) => this.loadImageError(err)));
227
- }
228
- /**
229
- * @private
230
- * @param {?} imageBase64
231
- * @return {?}
232
- */
233
- loadBase64Image(imageBase64) {
234
- this.loadImageService
235
- .loadBase64Image(imageBase64, this.settings)
236
- .then((/**
237
- * @param {?} res
238
- * @return {?}
239
- */
240
- (res) => this.setLoadedImage(res)))
241
- .catch((/**
242
- * @param {?} err
243
- * @return {?}
244
- */
245
- (err) => this.loadImageError(err)));
246
- }
247
- /**
248
- * @private
249
- * @param {?} url
250
- * @return {?}
251
- */
252
- loadImageFromURL(url) {
253
- this.loadImageService
254
- .loadImageFromURL(url, this.settings)
255
- .then((/**
256
- * @param {?} res
257
- * @return {?}
258
- */
259
- (res) => this.setLoadedImage(res)))
260
- .catch((/**
261
- * @param {?} err
262
- * @return {?}
263
- */
264
- (err) => this.loadImageError(err)));
265
- }
266
- /**
267
- * @private
268
- * @param {?} loadedImage
269
- * @return {?}
270
- */
271
- setLoadedImage(loadedImage) {
272
- this.loadedImage = loadedImage;
273
- this.safeImgDataUrl = this.sanitizer.bypassSecurityTrustResourceUrl(loadedImage.transformed.base64);
274
- this.cd.markForCheck();
275
- }
276
- /**
277
- * @private
278
- * @param {?} error
279
- * @return {?}
280
- */
281
- loadImageError(error) {
282
- console.error(error);
283
- this.loadImageFailed.emit();
284
- }
285
- /**
286
- * @return {?}
287
- */
288
- imageLoadedInView() {
289
- if (this.loadedImage != null) {
290
- this.imageLoaded.emit(this.loadedImage);
291
- this.setImageMaxSizeRetries = 0;
292
- setTimeout((/**
293
- * @return {?}
294
- */
295
- () => this.checkImageMaxSizeRecursively()));
296
- }
297
- }
298
- /**
299
- * @private
300
- * @return {?}
301
- */
302
- checkImageMaxSizeRecursively() {
303
- if (this.setImageMaxSizeRetries > 40) {
304
- this.loadImageFailed.emit();
305
- }
306
- else if (this.sourceImageLoaded()) {
307
- this.setMaxSize();
308
- this.setCropperScaledMinSize();
309
- this.setCropperScaledMaxSize();
310
- this.resetCropperPosition();
311
- this.cropperReady.emit(Object.assign({}, this.maxSize));
312
- this.cd.markForCheck();
313
- }
314
- else {
315
- this.setImageMaxSizeRetries++;
316
- setTimeout((/**
317
- * @return {?}
318
- */
319
- () => this.checkImageMaxSizeRecursively()), 50);
320
- }
321
- }
322
- /**
323
- * @private
324
- * @return {?}
325
- */
326
- sourceImageLoaded() {
327
- return this.sourceImage && this.sourceImage.nativeElement && this.sourceImage.nativeElement.offsetWidth > 0;
328
- }
329
- /**
330
- * @return {?}
331
- */
332
- onResize() {
333
- if (!this.loadedImage) {
334
- return;
335
- }
336
- this.resizeCropperPosition();
337
- this.setMaxSize();
338
- this.setCropperScaledMinSize();
339
- this.setCropperScaledMaxSize();
340
- }
341
- /**
342
- * @private
343
- * @return {?}
344
- */
345
- activatePinchGesture() {
346
- if (this.Hammer) {
347
- /** @type {?} */
348
- const hammer = new this.Hammer(this.wrapper.nativeElement);
349
- hammer.get('pinch').set({ enable: true });
350
- hammer.on('pinchmove', this.onPinch.bind(this));
351
- hammer.on('pinchend', this.pinchStop.bind(this));
352
- hammer.on('pinchstart', this.startPinch.bind(this));
353
- }
354
- else if (isDevMode()) {
355
- console.warn('[NgxImageCropper] Could not find HammerJS - Pinch Gesture won\'t work');
356
- }
357
- }
358
- /**
359
- * @private
360
- * @return {?}
361
- */
362
- resizeCropperPosition() {
363
- /** @type {?} */
364
- const sourceImageElement = this.sourceImage.nativeElement;
365
- if (this.maxSize.width !== sourceImageElement.offsetWidth || this.maxSize.height !== sourceImageElement.offsetHeight) {
366
- this.cropper.x1 = this.cropper.x1 * sourceImageElement.offsetWidth / this.maxSize.width;
367
- this.cropper.x2 = this.cropper.x2 * sourceImageElement.offsetWidth / this.maxSize.width;
368
- this.cropper.y1 = this.cropper.y1 * sourceImageElement.offsetHeight / this.maxSize.height;
369
- this.cropper.y2 = this.cropper.y2 * sourceImageElement.offsetHeight / this.maxSize.height;
370
- }
371
- }
372
- /**
373
- * @return {?}
374
- */
375
- resetCropperPosition() {
376
- this.cropperPositionService.resetCropperPosition(this.sourceImage, this.cropper, this.settings);
377
- this.doAutoCrop();
378
- this.imageVisible = true;
379
- }
380
- /**
381
- * @param {?} event
382
- * @return {?}
383
- */
384
- keyboardAccess(event) {
385
- this.changeKeyboardStepSize(event);
386
- this.keyboardMoveCropper(event);
387
- }
388
- /**
389
- * @private
390
- * @param {?} event
391
- * @return {?}
392
- */
393
- changeKeyboardStepSize(event) {
394
- if (event.key >= '1' && event.key <= '9') {
395
- this.settings.stepSize = +event.key;
396
- return;
397
- }
398
- }
399
- /**
400
- * @private
401
- * @param {?} event
402
- * @return {?}
403
- */
404
- keyboardMoveCropper(event) {
405
- /** @type {?} */
406
- const keyboardWhiteList = ['ArrowUp', 'ArrowDown', 'ArrowRight', 'ArrowLeft'];
407
- if (!(keyboardWhiteList.includes(event.key))) {
408
- return;
409
- }
410
- /** @type {?} */
411
- const moveType = event.shiftKey ? MoveTypes.Resize : MoveTypes.Move;
412
- /** @type {?} */
413
- const position = event.altKey ? getInvertedPositionForKey(event.key) : getPositionForKey(event.key);
414
- /** @type {?} */
415
- const moveEvent = getEventForKey(event.key, this.settings.stepSize);
416
- event.preventDefault();
417
- event.stopPropagation();
418
- this.startMove({ clientX: 0, clientY: 0 }, moveType, position);
419
- this.moveImg(moveEvent);
420
- this.moveStop();
421
- }
422
- /**
423
- * @param {?} event
424
- * @param {?} moveType
425
- * @param {?=} position
426
- * @return {?}
427
- */
428
- startMove(event, moveType, position = null) {
429
- if (this.moveStart && this.moveStart.active && this.moveStart.type === MoveTypes.Pinch) {
430
- return;
431
- }
432
- if (event.preventDefault) {
433
- event.preventDefault();
434
- }
435
- this.moveStart = Object.assign({ active: true, type: moveType, position, clientX: this.cropperPositionService.getClientX(event), clientY: this.cropperPositionService.getClientY(event) }, this.cropper);
436
- }
437
- /**
438
- * @param {?} event
439
- * @return {?}
440
- */
441
- startPinch(event) {
442
- if (!this.safeImgDataUrl) {
443
- return;
444
- }
445
- if (event.preventDefault) {
446
- event.preventDefault();
447
- }
448
- this.moveStart = Object.assign({ active: true, type: MoveTypes.Pinch, position: 'center', clientX: this.cropper.x1 + (this.cropper.x2 - this.cropper.x1) / 2, clientY: this.cropper.y1 + (this.cropper.y2 - this.cropper.y1) / 2 }, this.cropper);
449
- }
450
- /**
451
- * @param {?} event
452
- * @return {?}
453
- */
454
- moveImg(event) {
455
- if (this.moveStart.active) {
456
- if (event.stopPropagation) {
457
- event.stopPropagation();
458
- }
459
- if (event.preventDefault) {
460
- event.preventDefault();
461
- }
462
- if (this.moveStart.type === MoveTypes.Move) {
463
- this.cropperPositionService.move(event, this.moveStart, this.cropper);
464
- this.checkCropperPosition(true);
465
- }
466
- else if (this.moveStart.type === MoveTypes.Resize) {
467
- if (!this.cropperStaticWidth && !this.cropperStaticHeight) {
468
- this.cropperPositionService.resize(event, this.moveStart, this.cropper, this.maxSize, this.settings);
469
- }
470
- this.checkCropperPosition(false);
471
- }
472
- this.cd.detectChanges();
473
- }
474
- }
475
- /**
476
- * @param {?} event
477
- * @return {?}
478
- */
479
- onPinch(event) {
480
- if (this.moveStart.active) {
481
- if (event.stopPropagation) {
482
- event.stopPropagation();
483
- }
484
- if (event.preventDefault) {
485
- event.preventDefault();
486
- }
487
- if (this.moveStart.type === MoveTypes.Pinch) {
488
- this.cropperPositionService.resize(event, this.moveStart, this.cropper, this.maxSize, this.settings);
489
- this.checkCropperPosition(false);
490
- }
491
- this.cd.detectChanges();
492
- }
493
- }
494
- /**
495
- * @private
496
- * @return {?}
497
- */
498
- setMaxSize() {
499
- if (this.sourceImage) {
500
- /** @type {?} */
501
- const sourceImageElement = this.sourceImage.nativeElement;
502
- this.maxSize.width = sourceImageElement.offsetWidth;
503
- this.maxSize.height = sourceImageElement.offsetHeight;
504
- this.marginLeft = this.sanitizer.bypassSecurityTrustStyle('calc(50% - ' + this.maxSize.width / 2 + 'px)');
505
- }
506
- }
507
- /**
508
- * @private
509
- * @return {?}
510
- */
511
- setCropperScaledMinSize() {
512
- if (this.loadedImage && this.loadedImage.transformed && this.loadedImage.transformed.image) {
513
- this.setCropperScaledMinWidth();
514
- this.setCropperScaledMinHeight();
515
- }
516
- else {
517
- this.settings.cropperScaledMinWidth = 20;
518
- this.settings.cropperScaledMinHeight = 20;
519
- }
520
- }
521
- /**
522
- * @private
523
- * @return {?}
524
- */
525
- setCropperScaledMinWidth() {
526
- this.settings.cropperScaledMinWidth = this.cropperMinWidth > 0
527
- ? Math.max(20, this.cropperMinWidth / this.loadedImage.transformed.image.width * this.maxSize.width)
528
- : 20;
529
- }
530
- /**
531
- * @private
532
- * @return {?}
533
- */
534
- setCropperScaledMinHeight() {
535
- if (this.maintainAspectRatio) {
536
- this.settings.cropperScaledMinHeight = Math.max(20, this.settings.cropperScaledMinWidth / this.aspectRatio);
537
- }
538
- else if (this.cropperMinHeight > 0) {
539
- this.settings.cropperScaledMinHeight = Math.max(20, this.cropperMinHeight / this.loadedImage.transformed.image.height * this.maxSize.height);
540
- }
541
- else {
542
- this.settings.cropperScaledMinHeight = 20;
543
- }
544
- }
545
- /**
546
- * @private
547
- * @return {?}
548
- */
549
- setCropperScaledMaxSize() {
550
- if (this.loadedImage && this.loadedImage.transformed && this.loadedImage.transformed.image) {
551
- /** @type {?} */
552
- const ratio = this.loadedImage.transformed.size.width / this.maxSize.width;
553
- this.settings.cropperScaledMaxWidth = this.cropperMaxWidth > 20 ? this.cropperMaxWidth / ratio : this.maxSize.width;
554
- this.settings.cropperScaledMaxHeight = this.cropperMaxHeight > 20 ? this.cropperMaxHeight / ratio : this.maxSize.height;
555
- if (this.maintainAspectRatio) {
556
- if (this.settings.cropperScaledMaxWidth > this.settings.cropperScaledMaxHeight * this.aspectRatio) {
557
- this.settings.cropperScaledMaxWidth = this.settings.cropperScaledMaxHeight * this.aspectRatio;
558
- }
559
- else if (this.settings.cropperScaledMaxWidth < this.settings.cropperScaledMaxHeight * this.aspectRatio) {
560
- this.settings.cropperScaledMaxHeight = this.settings.cropperScaledMaxWidth / this.aspectRatio;
561
- }
562
- }
563
- }
564
- else {
565
- this.settings.cropperScaledMaxWidth = this.maxSize.width;
566
- this.settings.cropperScaledMaxHeight = this.maxSize.height;
567
- }
568
- }
569
- /**
570
- * @private
571
- * @param {?=} maintainSize
572
- * @return {?}
573
- */
574
- checkCropperPosition(maintainSize = false) {
575
- if (this.cropper.x1 < 0) {
576
- this.cropper.x2 -= maintainSize ? this.cropper.x1 : 0;
577
- this.cropper.x1 = 0;
578
- }
579
- if (this.cropper.y1 < 0) {
580
- this.cropper.y2 -= maintainSize ? this.cropper.y1 : 0;
581
- this.cropper.y1 = 0;
582
- }
583
- if (this.cropper.x2 > this.maxSize.width) {
584
- this.cropper.x1 -= maintainSize ? (this.cropper.x2 - this.maxSize.width) : 0;
585
- this.cropper.x2 = this.maxSize.width;
586
- }
587
- if (this.cropper.y2 > this.maxSize.height) {
588
- this.cropper.y1 -= maintainSize ? (this.cropper.y2 - this.maxSize.height) : 0;
589
- this.cropper.y2 = this.maxSize.height;
590
- }
591
- }
592
- /**
593
- * @return {?}
594
- */
595
- moveStop() {
596
- if (this.moveStart.active) {
597
- this.moveStart.active = false;
598
- this.doAutoCrop();
599
- }
600
- }
601
- /**
602
- * @return {?}
603
- */
604
- pinchStop() {
605
- if (this.moveStart.active) {
606
- this.moveStart.active = false;
607
- this.doAutoCrop();
608
- }
609
- }
610
- /**
611
- * @private
612
- * @return {?}
613
- */
614
- doAutoCrop() {
615
- if (this.autoCrop) {
616
- this.crop();
617
- }
618
- }
619
- /**
620
- * @return {?}
621
- */
622
- crop() {
623
- if (this.sourceImage && this.sourceImage.nativeElement && this.loadedImage.transformed.image != null) {
624
- this.startCropImage.emit();
625
- /** @type {?} */
626
- const output = this.cropService.crop(this.sourceImage, this.loadedImage, this.cropper, this.settings);
627
- if (output != null) {
628
- this.imageCropped.emit(output);
629
- }
630
- return output;
631
- }
632
- return null;
633
- }
634
- }
635
- ImageCropperComponent.decorators = [
636
- { type: Component, args: [{
637
- selector: 'image-cropper',
638
- template: "<div [style.background]=\"imageVisible && backgroundColor\"\n #wrapper\n>\n <img\n #sourceImage\n class=\"source-image\"\n *ngIf=\"safeImgDataUrl\"\n [src]=\"safeImgDataUrl\"\n [style.visibility]=\"imageVisible ? 'visible' : 'hidden'\"\n [style.transform]=\"safeTransformStyle\"\n (load)=\"imageLoadedInView()\"\n />\n <div\n class=\"overlay\"\n [style.width.px]=\"maxSize.width\"\n [style.height.px]=\"maxSize.height\"\n [style.margin-left]=\"alignImage === 'center' ? marginLeft : null\"\n ></div>\n <div class=\"cropper\"\n *ngIf=\"imageVisible\"\n [class.rounded]=\"roundCropper\"\n [style.top.px]=\"cropper.y1\"\n [style.left.px]=\"cropper.x1\"\n [style.width.px]=\"cropper.x2 - cropper.x1\"\n [style.height.px]=\"cropper.y2 - cropper.y1\"\n [style.margin-left]=\"alignImage === 'center' ? marginLeft : null\"\n [style.visibility]=\"imageVisible ? 'visible' : 'hidden'\"\n (keydown)=\"keyboardAccess($event)\"\n tabindex=\"0\"\n >\n <div\n (mousedown)=\"startMove($event, moveTypes.Move)\"\n (touchstart)=\"startMove($event, moveTypes.Move)\"\n class=\"move\">\n </div>\n <ng-container *ngIf=\"!hideResizeSquares\">\n <span class=\"resize topleft\"\n (mousedown)=\"startMove($event, moveTypes.Resize, 'topleft')\"\n (touchstart)=\"startMove($event, moveTypes.Resize, 'topleft')\">\n <span class=\"square\"></span>\n </span>\n <span class=\"resize top\">\n <span class=\"square\"></span>\n </span>\n <span class=\"resize topright\"\n (mousedown)=\"startMove($event, moveTypes.Resize, 'topright')\"\n (touchstart)=\"startMove($event, moveTypes.Resize, 'topright')\">\n <span class=\"square\"></span>\n </span>\n <span class=\"resize right\">\n <span class=\"square\"></span>\n </span>\n <span class=\"resize bottomright\"\n (mousedown)=\"startMove($event, moveTypes.Resize, 'bottomright')\"\n (touchstart)=\"startMove($event, moveTypes.Resize, 'bottomright')\">\n <span class=\"square\"></span>\n </span>\n <span class=\"resize bottom\">\n <span class=\"square\"></span>\n </span>\n <span class=\"resize bottomleft\"\n (mousedown)=\"startMove($event, moveTypes.Resize, 'bottomleft')\"\n (touchstart)=\"startMove($event, moveTypes.Resize, 'bottomleft')\">\n <span class=\"square\"></span>\n </span>\n <span class=\"resize left\">\n <span class=\"square\"></span>\n </span>\n <span class=\"resize-bar top\"\n (mousedown)=\"startMove($event, moveTypes.Resize, 'top')\"\n (touchstart)=\"startMove($event, moveTypes.Resize, 'top')\">\n </span>\n <span class=\"resize-bar right\"\n (mousedown)=\"startMove($event, moveTypes.Resize, 'right')\"\n (touchstart)=\"startMove($event, moveTypes.Resize, 'right')\">\n </span>\n <span class=\"resize-bar bottom\"\n (mousedown)=\"startMove($event, moveTypes.Resize, 'bottom')\"\n (touchstart)=\"startMove($event, moveTypes.Resize, 'bottom')\">\n </span>\n <span class=\"resize-bar left\"\n (mousedown)=\"startMove($event, moveTypes.Resize, 'left')\"\n (touchstart)=\"startMove($event, moveTypes.Resize, 'left')\">\n </span>\n </ng-container>\n </div>\n</div>\n",
639
- changeDetection: ChangeDetectionStrategy.OnPush,
640
- styles: [":host{display:flex;position:relative;width:100%;max-width:100%;max-height:100%;overflow:hidden;padding:5px;text-align:center}:host>div{width:100%;position:relative}:host>div img.source-image{max-width:100%;max-height:100%;transform-origin:center}:host .overlay{position:absolute;pointer-events:none;touch-action:none;outline:var(--cropper-overlay-color,#fff) solid 100vw;top:0;left:0}:host .cropper{position:absolute;display:flex;color:#53535c;background:0 0;outline:rgba(255,255,255,.3) solid 100vw;outline:var(--cropper-outline-color,rgba(255,255,255,.3)) solid 100vw;touch-action:none}:host .cropper:after{position:absolute;content:\"\";top:0;bottom:0;left:0;right:0;pointer-events:none;border:1px dashed;opacity:.75;color:inherit;z-index:1}:host .cropper .move{width:100%;cursor:move;border:1px solid rgba(255,255,255,.5)}:host .cropper:focus .move{border-color:#1e90ff;border-width:2px}:host .cropper .resize{position:absolute;display:inline-block;line-height:6px;padding:8px;opacity:.85;z-index:1}:host .cropper .resize .square{display:inline-block;background:#53535c;width:6px;height:6px;border:1px solid rgba(255,255,255,.5);box-sizing:content-box}:host .cropper .resize.topleft{top:-12px;left:-12px;cursor:nwse-resize}:host .cropper .resize.top{top:-12px;left:calc(50% - 12px);cursor:ns-resize}:host .cropper .resize.topright{top:-12px;right:-12px;cursor:nesw-resize}:host .cropper .resize.right{top:calc(50% - 12px);right:-12px;cursor:ew-resize}:host .cropper .resize.bottomright{bottom:-12px;right:-12px;cursor:nwse-resize}:host .cropper .resize.bottom{bottom:-12px;left:calc(50% - 12px);cursor:ns-resize}:host .cropper .resize.bottomleft{bottom:-12px;left:-12px;cursor:nesw-resize}:host .cropper .resize.left{top:calc(50% - 12px);left:-12px;cursor:ew-resize}:host .cropper .resize-bar{position:absolute;z-index:1}:host .cropper .resize-bar.top{top:-11px;left:11px;width:calc(100% - 22px);height:22px;cursor:ns-resize}:host .cropper .resize-bar.right{top:11px;right:-11px;height:calc(100% - 22px);width:22px;cursor:ew-resize}:host .cropper .resize-bar.bottom{bottom:-11px;left:11px;width:calc(100% - 22px);height:22px;cursor:ns-resize}:host .cropper .resize-bar.left{top:11px;left:-11px;height:calc(100% - 22px);width:22px;cursor:ew-resize}:host .cropper.rounded{outline-color:transparent}:host .cropper.rounded:after{border-radius:100%;box-shadow:0 0 0 100vw rgba(255,255,255,.3);box-shadow:0 0 0 100vw var(--cropper-outline-color,rgba(255,255,255,.3))}@media (orientation:portrait){:host .cropper{outline-width:100vh}:host .cropper.rounded:after{box-shadow:0 0 0 100vh rgba(255,255,255,.3);box-shadow:0 0 0 100vh var(--cropper-outline-color,rgba(255,255,255,.3))}}:host .cropper.rounded .move{border-radius:100%}:host.disabled .cropper .move,:host.disabled .cropper .resize,:host.disabled .cropper .resize-bar{display:none}"]
641
- }] }
642
- ];
643
- /** @nocollapse */
644
- ImageCropperComponent.ctorParameters = () => [
645
- { type: CropService },
646
- { type: CropperPositionService },
647
- { type: LoadImageService },
648
- { type: DomSanitizer },
649
- { type: ChangeDetectorRef }
650
- ];
651
- ImageCropperComponent.propDecorators = {
652
- wrapper: [{ type: ViewChild, args: ['wrapper', { static: true },] }],
653
- sourceImage: [{ type: ViewChild, args: ['sourceImage', { static: false },] }],
654
- imageChangedEvent: [{ type: Input }],
655
- imageURL: [{ type: Input }],
656
- imageBase64: [{ type: Input }],
657
- imageFile: [{ type: Input }],
658
- format: [{ type: Input }],
659
- transform: [{ type: Input }],
660
- maintainAspectRatio: [{ type: Input }],
661
- aspectRatio: [{ type: Input }],
662
- resizeToWidth: [{ type: Input }],
663
- resizeToHeight: [{ type: Input }],
664
- cropperMinWidth: [{ type: Input }],
665
- cropperMinHeight: [{ type: Input }],
666
- cropperMaxHeight: [{ type: Input }],
667
- cropperMaxWidth: [{ type: Input }],
668
- cropperStaticWidth: [{ type: Input }],
669
- cropperStaticHeight: [{ type: Input }],
670
- canvasRotation: [{ type: Input }],
671
- initialStepSize: [{ type: Input }],
672
- roundCropper: [{ type: Input }],
673
- onlyScaleDown: [{ type: Input }],
674
- imageQuality: [{ type: Input }],
675
- autoCrop: [{ type: Input }],
676
- backgroundColor: [{ type: Input }],
677
- containWithinAspectRatio: [{ type: Input }],
678
- hideResizeSquares: [{ type: Input }],
679
- cropper: [{ type: Input }],
680
- alignImage: [{ type: HostBinding, args: ['style.text-align',] }, { type: Input }],
681
- disabled: [{ type: HostBinding, args: ['class.disabled',] }, { type: Input }],
682
- imageCropped: [{ type: Output }],
683
- startCropImage: [{ type: Output }],
684
- imageLoaded: [{ type: Output }],
685
- cropperReady: [{ type: Output }],
686
- loadImageFailed: [{ type: Output }],
687
- onResize: [{ type: HostListener, args: ['window:resize',] }],
688
- moveImg: [{ type: HostListener, args: ['document:mousemove', ['$event'],] }, { type: HostListener, args: ['document:touchmove', ['$event'],] }],
689
- moveStop: [{ type: HostListener, args: ['document:mouseup',] }, { type: HostListener, args: ['document:touchend',] }]
690
- };
691
- if (false) {
692
- /**
693
- * @type {?}
694
- * @private
695
- */
696
- ImageCropperComponent.prototype.Hammer;
697
- /**
698
- * @type {?}
699
- * @private
700
- */
701
- ImageCropperComponent.prototype.settings;
702
- /**
703
- * @type {?}
704
- * @private
705
- */
706
- ImageCropperComponent.prototype.setImageMaxSizeRetries;
707
- /**
708
- * @type {?}
709
- * @private
710
- */
711
- ImageCropperComponent.prototype.moveStart;
712
- /**
713
- * @type {?}
714
- * @private
715
- */
716
- ImageCropperComponent.prototype.loadedImage;
717
- /** @type {?} */
718
- ImageCropperComponent.prototype.safeImgDataUrl;
719
- /** @type {?} */
720
- ImageCropperComponent.prototype.safeTransformStyle;
721
- /** @type {?} */
722
- ImageCropperComponent.prototype.marginLeft;
723
- /** @type {?} */
724
- ImageCropperComponent.prototype.maxSize;
725
- /** @type {?} */
726
- ImageCropperComponent.prototype.moveTypes;
727
- /** @type {?} */
728
- ImageCropperComponent.prototype.imageVisible;
729
- /** @type {?} */
730
- ImageCropperComponent.prototype.wrapper;
731
- /** @type {?} */
732
- ImageCropperComponent.prototype.sourceImage;
733
- /** @type {?} */
734
- ImageCropperComponent.prototype.imageChangedEvent;
735
- /** @type {?} */
736
- ImageCropperComponent.prototype.imageURL;
737
- /** @type {?} */
738
- ImageCropperComponent.prototype.imageBase64;
739
- /** @type {?} */
740
- ImageCropperComponent.prototype.imageFile;
741
- /** @type {?} */
742
- ImageCropperComponent.prototype.format;
743
- /** @type {?} */
744
- ImageCropperComponent.prototype.transform;
745
- /** @type {?} */
746
- ImageCropperComponent.prototype.maintainAspectRatio;
747
- /** @type {?} */
748
- ImageCropperComponent.prototype.aspectRatio;
749
- /** @type {?} */
750
- ImageCropperComponent.prototype.resizeToWidth;
751
- /** @type {?} */
752
- ImageCropperComponent.prototype.resizeToHeight;
753
- /** @type {?} */
754
- ImageCropperComponent.prototype.cropperMinWidth;
755
- /** @type {?} */
756
- ImageCropperComponent.prototype.cropperMinHeight;
757
- /** @type {?} */
758
- ImageCropperComponent.prototype.cropperMaxHeight;
759
- /** @type {?} */
760
- ImageCropperComponent.prototype.cropperMaxWidth;
761
- /** @type {?} */
762
- ImageCropperComponent.prototype.cropperStaticWidth;
763
- /** @type {?} */
764
- ImageCropperComponent.prototype.cropperStaticHeight;
765
- /** @type {?} */
766
- ImageCropperComponent.prototype.canvasRotation;
767
- /** @type {?} */
768
- ImageCropperComponent.prototype.initialStepSize;
769
- /** @type {?} */
770
- ImageCropperComponent.prototype.roundCropper;
771
- /** @type {?} */
772
- ImageCropperComponent.prototype.onlyScaleDown;
773
- /** @type {?} */
774
- ImageCropperComponent.prototype.imageQuality;
775
- /** @type {?} */
776
- ImageCropperComponent.prototype.autoCrop;
777
- /** @type {?} */
778
- ImageCropperComponent.prototype.backgroundColor;
779
- /** @type {?} */
780
- ImageCropperComponent.prototype.containWithinAspectRatio;
781
- /** @type {?} */
782
- ImageCropperComponent.prototype.hideResizeSquares;
783
- /** @type {?} */
784
- ImageCropperComponent.prototype.cropper;
785
- /** @type {?} */
786
- ImageCropperComponent.prototype.alignImage;
787
- /** @type {?} */
788
- ImageCropperComponent.prototype.disabled;
789
- /** @type {?} */
790
- ImageCropperComponent.prototype.imageCropped;
791
- /** @type {?} */
792
- ImageCropperComponent.prototype.startCropImage;
793
- /** @type {?} */
794
- ImageCropperComponent.prototype.imageLoaded;
795
- /** @type {?} */
796
- ImageCropperComponent.prototype.cropperReady;
797
- /** @type {?} */
798
- ImageCropperComponent.prototype.loadImageFailed;
799
- /**
800
- * @type {?}
801
- * @private
802
- */
803
- ImageCropperComponent.prototype.cropService;
804
- /**
805
- * @type {?}
806
- * @private
807
- */
808
- ImageCropperComponent.prototype.cropperPositionService;
809
- /**
810
- * @type {?}
811
- * @private
812
- */
813
- ImageCropperComponent.prototype.loadImageService;
814
- /**
815
- * @type {?}
816
- * @private
817
- */
818
- ImageCropperComponent.prototype.sanitizer;
819
- /**
820
- * @type {?}
821
- * @private
822
- */
823
- ImageCropperComponent.prototype.cd;
824
- }
825
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW1hZ2UtY3JvcHBlci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9uZ3gtaW1hZ2UtY3JvcHBlci8iLCJzb3VyY2VzIjpbImxpYi9jb21wb25lbnQvaW1hZ2UtY3JvcHBlci5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLGlCQUFpQixFQUNqQixTQUFTLEVBQ1QsVUFBVSxFQUNWLFlBQVksRUFDWixXQUFXLEVBQ1gsWUFBWSxFQUNaLEtBQUssRUFDTCxTQUFTLEVBR1QsTUFBTSxFQUVOLFNBQVMsRUFDVixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsWUFBWSxFQUFzQixNQUFNLDJCQUEyQixDQUFDO0FBRTdFLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQztBQUUvRCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDdkQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQ2pFLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBRWxFLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLHNDQUFzQyxDQUFDO0FBQzlFLE9BQU8sRUFBRSxjQUFjLEVBQUUseUJBQXlCLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQVF2RyxNQUFNLE9BQU8scUJBQXFCOzs7Ozs7OztJQThEaEMsWUFDVSxXQUF3QixFQUN4QixzQkFBOEMsRUFDOUMsZ0JBQWtDLEVBQ2xDLFNBQXVCLEVBQ3ZCLEVBQXFCO1FBSnJCLGdCQUFXLEdBQVgsV0FBVyxDQUFhO1FBQ3hCLDJCQUFzQixHQUF0QixzQkFBc0IsQ0FBd0I7UUFDOUMscUJBQWdCLEdBQWhCLGdCQUFnQixDQUFrQjtRQUNsQyxjQUFTLEdBQVQsU0FBUyxDQUFjO1FBQ3ZCLE9BQUUsR0FBRixFQUFFLENBQW1CO1FBbEV2QixXQUFN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NkNBQStEOztJQUMvRCwrQ0FBb0Q7O0lBQ3BELDRDQUF3RDs7SUFDeEQsNkNBQXdEOztJQUN4RCxnREFBcUQ7Ozs7O0lBR25ELDRDQUFnQzs7Ozs7SUFDaEMsdURBQXNEOzs7OztJQUN0RCxpREFBMEM7Ozs7O0lBQzFDLDBDQUErQjs7Ozs7SUFDL0IsbUNBQTZCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBDb21wb25lbnQsXG4gIEVsZW1lbnRSZWYsXG4gIEV2ZW50RW1pdHRlcixcbiAgSG9zdEJpbmRpbmcsXG4gIEhvc3RMaXN0ZW5lcixcbiAgSW5wdXQsXG4gIGlzRGV2TW9kZSxcbiAgT25DaGFuZ2VzLFxuICBPbkluaXQsXG4gIE91dHB1dCxcbiAgU2ltcGxlQ2hhbmdlcyxcbiAgVmlld0NoaWxkXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRG9tU2FuaXRpemVyLCBTYWZlU3R5bGUsIFNhZmVVcmwgfSBmcm9tICdAYW5ndWxhci9wbGF0Zm9ybS1icm93c2VyJztcbmltcG9ydCB7IENyb3BwZXJQb3NpdGlvbiwgRGltZW5zaW9ucywgSW1hZ2VDcm9wcGVkRXZlbnQsIEltYWdlVHJhbnNmb3JtLCBMb2FkZWRJbWFnZSwgTW92ZVN0YXJ0IH0gZnJvbSAnLi4vaW50ZXJmYWNlcyc7XG5pbXBvcnQgeyBNb3ZlVHlwZXMgfSBmcm9tICcuLi9pbnRlcmZhY2VzL21vdmUtc3RhcnQuaW50ZXJmYWNlJztcbmltcG9ydCB7IEhhbW1lclN0YXRpYyB9IGZyb20gJy4uL3V0aWxzL2hhbW1lci51dGlscyc7XG5pbXBvcnQgeyBDcm9wU2VydmljZSB9IGZyb20gJy4uL3NlcnZpY2VzL2Nyb3Auc2VydmljZSc7XG5pbXBvcnQgeyBDcm9wcGVyU2V0dGluZ3MgfSBmcm9tICcuLi9pbnRlcmZhY2VzL2Nyb3BwZXIuc2V0dGluZ3MnO1xuaW1wb3J0IHsgTG9hZEltYWdlU2VydmljZSB9IGZyb20gJy4uL3NlcnZpY2VzL2xvYWQtaW1hZ2Uuc2VydmljZSc7XG5pbXBvcnQgeyBPdXRwdXRGb3JtYXQgfSBmcm9tICcuLi9pbnRlcmZhY2VzL2Nyb3BwZXItb3B0aW9ucy5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgQ3JvcHBlclBvc2l0aW9uU2VydmljZSB9IGZyb20gJy4uL3NlcnZpY2VzL2Nyb3BwZXItcG9zaXRpb24uc2VydmljZSc7XG5pbXBvcnQgeyBnZXRFdmVudEZvcktleSwgZ2V0SW52ZXJ0ZWRQb3NpdGlvbkZvcktleSwgZ2V0UG9zaXRpb25Gb3JLZXkgfSBmcm9tICcuLi91dGlscy9rZXlib2FyZC51dGlscyc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2ltYWdlLWNyb3BwZXInLFxuICB0ZW1wbGF0ZVVybDogJy4vaW1hZ2UtY3JvcHBlci5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL2ltYWdlLWNyb3BwZXIuY29tcG9uZW50LnNjc3MnXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2hcbn0pXG5leHBvcnQgY2xhc3MgSW1hZ2VDcm9wcGVyQ29tcG9uZW50IGltcGxlbWVudHMgT25DaGFuZ2VzLCBPbkluaXQge1xuICBwcml2YXRlIEhhbW1lcjogSGFtbWVyU3RhdGljID0gdHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCdcbiAgICA/ICh3aW5kb3cgYXMgYW55KS5IYW1tZXIgYXMgSGFtbWVyU3RhdGljXG4gICAgOiBudWxsO1xuICBwcml2YXRlIHNldHRpbmdzID0gbmV3IENyb3BwZXJTZXR0aW5ncygpO1xuICBwcml2YXRlIHNldEltYWdlTWF4U2l6ZVJldHJpZXMgPSAwO1xuICBwcml2YXRlIG1vdmVTdGFydDogTW92ZVN0YXJ0O1xuICBwcml2YXRlIGxvYWRlZEltYWdlOiBMb2FkZWRJbWFnZTtcblxuICBzYWZlSW1nRGF0YVVybDogU2FmZVVybCB8IHN0cmluZztcbiAgc2FmZVRyYW5zZm9ybVN0eWxlOiBTYWZlU3R5bGUgfCBzdHJpbmc7XG4gIG1hcmdpbkxlZnQ6IFNhZmVTdHlsZSB8IHN0cmluZyA9ICcwcHgnO1xuICBtYXhTaXplOiBEaW1lbnNpb25zO1xuICBtb3ZlVHlwZXMgPSBNb3ZlVHlwZXM7XG4gIGltYWdlVmlzaWJsZSA9IGZhbHNlO1xuXG4gIEBWaWV3Q2hpbGQoJ3dyYXBwZXInLCB7c3RhdGljOiB0cnVlfSkgd3JhcHBlcjogRWxlbWVudFJlZjxIVE1MRGl2RWxlbWVudD47XG4gIEBWaWV3Q2hpbGQoJ3NvdXJjZUltYWdlJywge3N0YXRpYzogZmFsc2V9KSBzb3VyY2VJbWFnZTogRWxlbWVudFJlZjxIVE1MRGl2RWxlbWVudD47XG5cbiAgQElucHV0KCkgaW1hZ2VDaGFuZ2VkRXZlbnQ6IGFueTtcbiAgQElucHV0KCkgaW1hZ2VVUkw6IHN0cmluZztcbiAgQElucHV0KCkgaW1hZ2VCYXNlNjQ6IHN0cmluZztcbiAgQElucHV0KCkgaW1hZ2VGaWxlOiBGaWxlO1xuXG4gIEBJbnB1dCgpIGZvcm1hdDogT3V0cHV0Rm9ybWF0ID0gdGhpcy5zZXR0aW5ncy5mb3JtYXQ7XG4gIEBJbnB1dCgpIHRyYW5zZm9ybTogSW1hZ2VUcmFuc2Zvcm0gPSB7fTtcbiAgQElucHV0KCkgbWFpbnRhaW5Bc3BlY3RSYXRpbyA9IHRoaXMuc2V0dGluZ3MubWFpbnRhaW5Bc3BlY3RSYXRpbztcbiAgQElucHV0KCkgYXNwZWN0UmF0aW8gPSB0aGlzLnNldHRpbmdzLmFzcGVjdFJhdGlvO1xuICBASW5wdXQoKSByZXNpemVUb1dpZHRoID0gdGhpcy5zZXR0aW5ncy5yZXNpemVUb1dpZHRoO1xuICBASW5wdXQoKSByZXNpemVUb0hlaWdodCA9IHRoaXMuc2V0dGluZ3MucmVzaXplVG9IZWlnaHQ7XG4gIEBJbnB1dCgpIGNyb3BwZXJNaW5XaWR0aCA9IHRoaXMuc2V0dGluZ3MuY3JvcHBlck1pbldpZHRoO1xuICBASW5wdXQoKSBjcm9wcGVyTWluSGVpZ2h0ID0gdGhpcy5zZXR0aW5ncy5jcm9wcGVyTWluSGVpZ2h0O1xuICBASW5wdXQoKSBjcm9wcGVyTWF4SGVpZ2h0ID0gdGhpcy5zZXR0aW5ncy5jcm9wcGVyTWF4SGVpZ2h0O1xuICBASW5wdXQoKSBjcm9wcGVyTWF4V2lkdGggPSB0aGlzLnNldHRpbmdzLmNyb3BwZXJNYXhXaWR0aDtcbiAgQElucHV0KCkgY3JvcHBlclN0YXRpY1dpZHRoID0gdGhpcy5zZXR0aW5ncy5jcm9wcGVyU3RhdGljV2lkdGg7XG4gIEBJbnB1dCgpIGNyb3BwZXJTdGF0aWNIZWlnaHQgPSB0aGlzLnNldHRpbmdzLmNyb3BwZXJTdGF0aWNIZWlnaHQ7XG4gIEBJbnB1dCgpIGNhbnZhc1JvdGF0aW9uID0gdGhpcy5zZXR0aW5ncy5jYW52YXNSb3RhdGlvbjtcbiAgQElucHV0KCkgaW5pdGlhbFN0ZXBTaXplID0gdGhpcy5zZXR0aW5ncy5pbml0aWFsU3RlcFNpemU7XG4gIEBJbnB1dCgpIHJvdW5kQ3JvcHBlciA9IHRoaXMuc2V0dGluZ3Mucm91bmRDcm9wcGVyO1xuICBASW5wdXQoKSBvbmx5U2NhbGVEb3duID0gdGhpcy5zZXR0aW5ncy5vbmx5U2NhbGVEb3duO1xuICBASW5wdXQoKSBpbWFnZVF1YWxpdHkgPSB0aGlzLnNldHRpbmdzLmltYWdlUXVhbGl0eTtcbiAgQElucHV0KCkgYXV0b0Nyb3AgPSB0aGlzLnNldHRpbmdzLmF1dG9Dcm9wO1xuICBASW5wdXQoKSBiYWNrZ3JvdW5kQ29sb3IgPSB0aGlzLnNldHRpbmdzLmJhY2tncm91bmRDb2xvcjtcbiAgQElucHV0KCkgY29udGFpbldpdGhpbkFzcGVjdFJhdGlvID0gdGhpcy5zZXR0aW5ncy5jb250YWluV2l0aGluQXNwZWN0UmF0aW87XG4gIEBJbnB1dCgpIGhpZGVSZXNpemVTcXVhcmVzID0gdGhpcy5zZXR0aW5ncy5oaWRlUmVzaXplU3F1YXJlcztcbiAgQElucHV0KCkgY3JvcHBlcjogQ3JvcHBlclBvc2l0aW9uID0ge1xuICAgIHgxOiAtMTAwLFxuICAgIHkxOiAtMTAwLFxuICAgIHgyOiAxMDAwMCxcbiAgICB5MjogMTAwMDBcbiAgfTtcbiAgQEhvc3RCaW5kaW5nKCdzdHlsZS50ZXh0LWFsaWduJylcbiAgQElucHV0KCkgYWxpZ25JbWFnZTogJ2xlZnQnIHwgJ2NlbnRlcicgPSB0aGlzLnNldHRpbmdzLmFsaWduSW1hZ2U7XG4gIEBIb3N0QmluZGluZygnY2xhc3MuZGlzYWJsZWQnKVxuICBASW5wdXQoKSBkaXNhYmxlZCA9IGZhbHNlO1xuXG4gIEBPdXRwdXQoKSBpbWFnZUNyb3BwZWQgPSBuZXcgRXZlbnRFbWl0dGVyPEltYWdlQ3JvcHBlZEV2ZW50PigpO1xuICBAT3V0cHV0KCkgc3RhcnRDcm9wSW1hZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG4gIEBPdXRwdXQoKSBpbWFnZUxvYWRlZCA9IG5ldyBFdmVudEVtaXR0ZXI8TG9hZGVkSW1hZ2U+KCk7XG4gIEBPdXRwdXQoKSBjcm9wcGVyUmVhZHkgPSBuZXcgRXZlbnRFbWl0dGVyPERpbWVuc2lvbnM+KCk7XG4gIEBPdXRwdXQoKSBsb2FkSW1hZ2VGYWlsZWQgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBjcm9wU2VydmljZTogQ3JvcFNlcnZpY2UsXG4gICAgcHJpdmF0ZSBjcm9wcGVyUG9zaXRpb25TZXJ2aWNlOiBDcm9wcGVyUG9zaXRpb25TZXJ2aWNlLFxuICAgIHByaXZhdGUgbG9hZEltYWdlU2VydmljZTogTG9hZEltYWdlU2VydmljZSxcbiAgICBwcml2YXRlIHNhbml0aXplcjogRG9tU2FuaXRpemVyLFxuICAgIHByaXZhdGUgY2Q6IENoYW5nZURldGVjdG9yUmVmXG4gICkge1xuICAgIHRoaXMucmVzZXQoKTtcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICB0aGlzLm9uQ2hhbmdlc1VwZGF0ZVNldHRpbmdzKGNoYW5nZXMpO1xuICAgIHRoaXMub25DaGFuZ2VzSW5wdXRJbWFnZShjaGFuZ2VzKTtcblxuICAgIGlmICh0aGlzLmxvYWRlZEltYWdlICYmIHRoaXMubG9hZGVkSW1hZ2Uub3JpZ2luYWwuaW1hZ2UuY29tcGxldGVcbiAgICAgICYmIChjaGFuZ2VzLmNvbnRhaW5XaXRoaW5Bc3BlY3RSYXRpbyB8fCBjaGFuZ2VzLmNhbnZhc1JvdGF0aW9uKSkge1xuICAgICAgdGhpcy5sb2FkSW1hZ2VTZXJ2aWNlXG4gICAgICAgIC50cmFuc2Zvcm1Mb2FkZWRJbWFnZSh0aGlzLmxvYWRlZEltYWdlLCB0aGlzLnNldHRpbmdzKVxuICAgICAgICAudGhlbigocmVzKSA9PiB0aGlzLnNldExvYWRlZEltYWdlKHJlcykpXG4gICAgICAgIC5jYXRjaCgoZXJyKSA9PiB0aGlzLmxvYWRJbWFnZUVycm9yKGVycikpO1xuICAgIH1cbiAgICBpZiAoY2hhbmdlcy5jcm9wcGVyIHx8IGNoYW5nZXMubWFpbnRhaW5Bc3BlY3RSYXRpbyB8fCBjaGFuZ2VzLmFzcGVjdFJhdGlvKSB7XG4gICAgICB0aGlzLnNldE1heFNpemUoKTtcbiAgICAgIHRoaXMuc2V0Q3JvcHBlclNjYWxlZE1pblNpemUoKTtcbiAgICAgIHRoaXMuc2V0Q3JvcHBlclNjYWxlZE1heFNpemUoKTtcbiAgICAgIGlmICh0aGlzLm1haW50YWluQXNwZWN0UmF0aW8gJiYgKGNoYW5nZXMubWFpbnRhaW5Bc3BlY3RSYXRpbyB8fCBjaGFuZ2VzLmFzcGVjdFJhdGlvKSkge1xuICAgICAgICB0aGlzLnJlc2V0Q3JvcHBlclBvc2l0aW9uKCk7XG4gICAgICB9IGVsc2UgaWYgKGNoYW5nZXMuY3JvcHBlcikge1xuICAgICAgICB0aGlzLmNoZWNrQ3JvcHBlclBvc2l0aW9uKGZhbHNlKTtcbiAgICAgICAgdGhpcy5kb0F1dG9Dcm9wKCk7XG4gICAgICB9XG4gICAgICB0aGlzLmNkLm1hcmtGb3JDaGVjaygpO1xuICAgIH1cbiAgICBpZiAoY2hhbmdlcy50cmFuc2Zvcm0pIHtcbiAgICAgIHRoaXMudHJhbnNmb3JtID0gdGhpcy50cmFuc2Zvcm0gfHwge307XG4gICAgICB0aGlzLnNldENzc1RyYW5zZm9ybSgpO1xuICAgICAgdGhpcy5kb0F1dG9Dcm9wKCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBvbkNoYW5nZXNVcGRhdGVTZXR0aW5ncyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKSB7XG4gICAgdGhpcy5zZXR0aW5ncy5zZXRPcHRpb25zRnJvbUNoYW5nZXMoY2hhbmdlcyk7XG5cbiAgICBpZiAodGhpcy5zZXR0aW5ncy5jcm9wcGVyU3RhdGljSGVpZ2h0ICYmIHRoaXMuc2V0dGluZ3MuY3JvcHBlclN0YXRpY1dpZHRoKSB7XG4gICAgICB0aGlzLnNldHRpbmdzLnNldE9wdGlvbnMoe1xuICAgICAgICBoaWRlUmVzaXplU3F1YXJlczogdHJ1ZSxcbiAgICAgICAgY3JvcHBlck1pbldpZHRoOiB0aGlzLnNldHRpbmdzLmNyb3BwZXJTdGF0aWNXaWR0aCxcbiAgICAgICAgY3JvcHBlck1pbkhlaWdodDogdGhpcy5zZXR0aW5ncy5jcm9wcGVyU3RhdGljSGVpZ2h0LFxuICAgICAgICBjcm9wcGVyTWF4SGVpZ2h0OiB0aGlzLnNldHRpbmdzLmNyb3BwZXJTdGF0aWNIZWlnaHQsXG4gICAgICAgIGNyb3BwZXJNYXhXaWR0aDogdGhpcy5zZXR0aW5ncy5jcm9wcGVyU3RhdGljV2lkdGgsXG4gICAgICAgIG1haW50YWluQXNwZWN0UmF0aW86IGZhbHNlXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIG9uQ2hhbmdlc0lucHV0SW1hZ2UoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIGlmIChjaGFuZ2VzLmltYWdlQ2hhbmdlZEV2ZW50IHx8IGNoYW5nZXMuaW1hZ2VVUkwgfHwgY2hhbmdlcy5pbWFnZUJhc2U2NCB8fCBjaGFuZ2VzLmltYWdlRmlsZSkge1xuICAgICAgdGhpcy5yZXNldCgpO1xuICAgIH1cbiAgICBpZiAoY2hhbmdlcy5pbWFnZUNoYW5nZWRFdmVudCAmJiB0aGlzLmlzVmFsaWRJbWFnZUNoYW5nZWRFdmVudCgpKSB7XG4gICAgICB0aGlzLmxvYWRJbWFnZUZpbGUodGhpcy5pbWFnZUNoYW5nZWRFdmVudC50YXJnZXQuZmlsZXNbMF0pO1xuICAgIH1cbiAgICBpZiAoY2hhbmdlcy5pbWFnZVVSTCAmJiB0aGlzLmltYWdlVVJMKSB7XG4gICAgICB0aGlzLmxvYWRJbWFnZUZyb21VUkwodGhpcy5pbWFnZVVSTCk7XG4gICAgfVxuICAgIGlmIChjaGFuZ2VzLmltYWdlQmFzZTY0ICYmIHRoaXMuaW1hZ2VCYXNlNjQpIHtcbiAgICAgIHRoaXMubG9hZEJhc2U2NEltYWdlKHRoaXMuaW1hZ2VCYXNlNjQpO1xuICAgIH1cbiAgICBpZiAoY2hhbmdlcy5pbWFnZUZpbGUgJiYgdGhpcy5pbWFnZUZpbGUpIHtcbiAgICAgIHRoaXMubG9hZEltYWdlRmlsZSh0aGlzLmltYWdlRmlsZSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBpc1ZhbGlkSW1hZ2VDaGFuZ2VkRXZlbnQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuaW1hZ2VDaGFuZ2VkRXZlbnRcbiAgICAgICYmIHRoaXMuaW1hZ2VDaGFuZ2VkRXZlbnQudGFyZ2V0XG4gICAgICAmJiB0aGlzLmltYWdlQ2hhbmdlZEV2ZW50LnRhcmdldC5maWxlc1xuICAgICAgJiYgdGhpcy5pbWFnZUNoYW5nZWRFdmVudC50YXJnZXQuZmlsZXMubGVuZ3RoID4gMDtcbiAgfVxuXG4gIHByaXZhdGUgc2V0Q3NzVHJhbnNmb3JtKCkge1xuICAgIHRoaXMuc2FmZVRyYW5zZm9ybVN0eWxlID0gdGhpcy5zYW5pdGl6ZXIuYnlwYXNzU2VjdXJpdHlUcnVzdFN0eWxlKFxuICAgICAgJ3NjYWxlWCgnICsgKHRoaXMudHJhbnNmb3JtLnNjYWxlIHx8IDEpICogKHRoaXMudHJhbnNmb3JtLmZsaXBIID8gLTEgOiAxKSArICcpJyArXG4gICAgICAnc2NhbGVZKCcgKyAodGhpcy50cmFuc2Zvcm0uc2NhbGUgfHwgMSkgKiAodGhpcy50cmFuc2Zvcm0uZmxpcFYgPyAtMSA6IDEpICsgJyknICtcbiAgICAgICdyb3RhdGUoJyArICh0aGlzLnRyYW5zZm9ybS5yb3RhdGUgfHwgMCkgKyAnZGVnKSdcbiAgICApO1xuICB9XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5zZXR0aW5ncy5zdGVwU2l6ZSA9IHRoaXMuaW5pdGlhbFN0ZXBTaXplO1xuICAgIHRoaXMuYWN0aXZhdGVQaW5jaEdlc3R1cmUoKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVzZXQoKTogdm9pZCB7XG4gICAgdGhpcy5pbWFnZVZpc2libGUgPSBmYWxzZTtcbiAgICB0aGlzLmxvYWRlZEltYWdlID0gbnVsbDtcbiAgICB0aGlzLnNhZmVJbWdEYXRhVXJsID0gJ2RhdGE6aW1hZ2UvcG5nO2Jhc2U2NCxpVkJPUncwS0dnJ1xuICAgICAgKyAnb0FBQUFOU1VoRVVnQUFBQUVBQUFBQkNBWUFBQUFmRmNTSkFBQUFDMGxFUVZRWVYyTmdBQUlBQUFVJ1xuICAgICAgKyAnQUFhclZ5RkVBQUFBQVNVVk9SSzVDWUlJPSc7XG4gICAgdGhpcy5tb3ZlU3RhcnQgPSB7XG4gICAgICBhY3RpdmU6IGZhbHNlLFxuICAgICAgdHlwZTogbnVsbCxcbiAgICAgIHBvc2l0aW9uOiBudWxsLFxuICAgICAgeDE6IDAsXG4gICAgICB5MTogMCxcbiAgICAgIHgyOiAwLFxuICAgICAgeTI6IDAsXG4gICAgICBjbGllbnRYOiAwLFxuICAgICAgY2xpZW50WTogMFxuICAgIH07XG4gICAgdGhpcy5tYXhTaXplID0ge1xuICAgICAgd2lkdGg6IDAsXG4gICAgICBoZWlnaHQ6IDBcbiAgICB9O1xuICAgIHRoaXMuY3JvcHBlci54MSA9IC0xMDA7XG4gICAgdGhpcy5jcm9wcGVyLnkxID0gLTEwMDtcbiAgICB0aGlzLmNyb3BwZXIueDIgPSAxMDAwMDtcbiAgICB0aGlzLmNyb3BwZXIueTIgPSAxMDAwMDtcbiAgfVxuXG4gIHByaXZhdGUgbG9hZEltYWdlRmlsZShmaWxlOiBGaWxlKTogdm9pZCB7XG4gICAgdGhpcy5sb2FkSW1hZ2VTZXJ2aWNlXG4gICAgICAubG9hZEltYWdlRmlsZShmaWxlLCB0aGlzLnNldHRpbmdzKVxuICAgICAgLnRoZW4oKHJlcykgPT4gdGhpcy5zZXRMb2FkZWRJbWFnZShyZXMpKVxuICAgICAgLmNhdGNoKChlcnIpID0+IHRoaXMubG9hZEltYWdlRXJyb3IoZXJyKSk7XG4gIH1cblxuICBwcml2YXRlIGxvYWRCYXNlNjRJbWFnZShpbWFnZUJhc2U2NDogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5sb2FkSW1hZ2VTZXJ2aWNlXG4gICAgICAubG9hZEJhc2U2NEltYWdlKGltYWdlQmFzZTY0LCB0aGlzLnNldHRpbmdzKVxuICAgICAgLnRoZW4oKHJlcykgPT4gdGhpcy5zZXRMb2FkZWRJbWFnZShyZXMpKVxuICAgICAgLmNhdGNoKChlcnIpID0+IHRoaXMubG9hZEltYWdlRXJyb3IoZXJyKSk7XG4gIH1cblxuICBwcml2YXRlIGxvYWRJbWFnZUZyb21VUkwodXJsOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLmxvYWRJbWFnZVNlcnZpY2VcbiAgICAgIC5sb2FkSW1hZ2VGcm9tVVJMKHVybCwgdGhpcy5zZXR0aW5ncylcbiAgICAgIC50aGVuKChyZXMpID0+IHRoaXMuc2V0TG9hZGVkSW1hZ2UocmVzKSlcbiAgICAgIC5jYXRjaCgoZXJyKSA9PiB0aGlzLmxvYWRJbWFnZUVycm9yKGVycikpO1xuICB9XG5cbiAgcHJpdmF0ZSBzZXRMb2FkZWRJbWFnZShsb2FkZWRJbWFnZTogTG9hZGVkSW1hZ2UpOiB2b2lkIHtcbiAgICB0aGlzLmxvYWRlZEltYWdlID0gbG9hZGVkSW1hZ2U7XG4gICAgdGhpcy5zYWZlSW1nRGF0YVVybCA9IHRoaXMuc2FuaXRpemVyLmJ5cGFzc1NlY3VyaXR5VHJ1c3RSZXNvdXJjZVVybChsb2FkZWRJbWFnZS50cmFuc2Zvcm1lZC5iYXNlNjQpO1xuICAgIHRoaXMuY2QubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBwcml2YXRlIGxvYWRJbWFnZUVycm9yKGVycm9yOiBhbnkpOiB2b2lkIHtcbiAgICBjb25zb2xlLmVycm9yKGVycm9yKTtcbiAgICB0aGlzLmxvYWRJbWFnZUZhaWxlZC5lbWl0KCk7XG4gIH1cblxuICBpbWFnZUxvYWRlZEluVmlldygpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5sb2FkZWRJbWFnZSAhPSBudWxsKSB7XG4gICAgICB0aGlzLmltYWdlTG9hZGVkLmVtaXQodGhpcy5sb2FkZWRJbWFnZSk7XG4gICAgICB0aGlzLnNldEltYWdlTWF4U2l6ZVJldHJpZXMgPSAwO1xuICAgICAgc2V0VGltZW91dCgoKSA9PiB0aGlzLmNoZWNrSW1hZ2VNYXhTaXplUmVjdXJzaXZlbHkoKSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBjaGVja0ltYWdlTWF4U2l6ZVJlY3Vyc2l2ZWx5KCk6IHZvaWQge1xuICAgIGlmICh0aGlzLnNldEltYWdlTWF4U2l6ZVJldHJpZXMgPiA0MCkge1xuICAgICAgdGhpcy5sb2FkSW1hZ2VGYWlsZWQuZW1pdCgpO1xuICAgIH0gZWxzZSBpZiAodGhpcy5zb3VyY2VJbWFnZUxvYWRlZCgpKSB7XG4gICAgICB0aGlzLnNldE1heFNpemUoKTtcbiAgICAgIHRoaXMuc2V0Q3JvcHBlclNjYWxlZE1pblNpemUoKTtcbiAgICAgIHRoaXMuc2V0Q3JvcHBlclNjYWxlZE1heFNpemUoKTtcbiAgICAgIHRoaXMucmVzZXRDcm9wcGVyUG9zaXRpb24oKTtcbiAgICAgIHRoaXMuY3JvcHBlclJlYWR5LmVtaXQoey4uLnRoaXMubWF4U2l6ZX0pO1xuICAgICAgdGhpcy5jZC5tYXJrRm9yQ2hlY2soKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zZXRJbWFnZU1heFNpemVSZXRyaWVzKys7XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHRoaXMuY2hlY2tJbWFnZU1heFNpemVSZWN1cnNpdmVseSgpLCA1MCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBzb3VyY2VJbWFnZUxvYWRlZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5zb3VyY2VJbWFnZSAmJiB0aGlzLnNvdXJjZUltYWdlLm5hdGl2ZUVsZW1lbnQgJiYgdGhpcy5zb3VyY2VJbWFnZS5uYXRpdmVFbGVtZW50Lm9mZnNldFdpZHRoID4gMDtcbiAgfVxuXG4gIEBIb3N0TGlzdGVuZXIoJ3dpbmRvdzpyZXNpemUnKVxuICBvblJlc2l6ZSgpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMubG9hZGVkSW1hZ2UpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5yZXNpemVDcm9wcGVyUG9zaXRpb24oKTtcbiAgICB0aGlzLnNldE1heFNpemUoKTtcbiAgICB0aGlzLnNldENyb3BwZXJTY2FsZWRNaW5TaXplKCk7XG4gICAgdGhpcy5zZXRDcm9wcGVyU2NhbGVkTWF4U2l6ZSgpO1xuICB9XG5cbiAgcHJpdmF0ZSBhY3RpdmF0ZVBpbmNoR2VzdHVyZSgpIHtcbiAgICBpZiAodGhpcy5IYW1tZXIpIHtcbiAgICAgIGNvbnN0IGhhbW1lciA9IG5ldyB0aGlzLkhhbW1lcih0aGlzLndyYXBwZXIubmF0aXZlRWxlbWVudCk7XG4gICAgICBoYW1tZXIuZ2V0KCdwaW5jaCcpLnNldCh7ZW5hYmxlOiB0cnVlfSk7XG4gICAgICBoYW1tZXIub24oJ3BpbmNobW92ZScsIHRoaXMub25QaW5jaC5iaW5kKHRoaXMpKTtcbiAgICAgIGhhbW1lci5vbigncGluY2hlbmQnLCB0aGlzLnBpbmNoU3RvcC5iaW5kKHRoaXMpKTtcbiAgICAgIGhhbW1lci5vbigncGluY2hzdGFydCcsIHRoaXMuc3RhcnRQaW5jaC5iaW5kKHRoaXMpKTtcbiAgICB9IGVsc2UgaWYgKGlzRGV2TW9kZSgpKSB7XG4gICAgICBjb25zb2xlLndhcm4oJ1tOZ3hJbWFnZUNyb3BwZXJdIENvdWxkIG5vdCBmaW5kIEhhbW1lckpTIC0gUGluY2ggR2VzdHVyZSB3b25cXCd0IHdvcmsnKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHJlc2l6ZUNyb3BwZXJQb3NpdGlvbigpOiB2b2lkIHtcbiAgICBjb25zdCBzb3VyY2VJbWFnZUVsZW1lbnQgPSB0aGlzLnNvdXJjZUltYWdlLm5hdGl2ZUVsZW1lbnQ7XG4gICAgaWYgKHRoaXMubWF4U2l6ZS53aWR0aCAhPT0gc291cmNlSW1hZ2VFbGVtZW50Lm9mZnNldFdpZHRoIHx8IHRoaXMubWF4U2l6ZS5oZWlnaHQgIT09IHNvdXJjZUltYWdlRWxlbWVudC5vZmZzZXRIZWlnaHQpIHtcbiAgICAgIHRoaXMuY3JvcHBlci54MSA9IHRoaXMuY3JvcHBlci54MSAqIHNvdXJjZUltYWdlRWxlbWVudC5vZmZzZXRXaWR0aCAvIHRoaXMubWF4U2l6ZS53aWR0aDtcbiAgICAgIHRoaXMuY3JvcHBlci54MiA9IHRoaXMuY3JvcHBlci54MiAqIHNvdXJjZUltYWdlRWxlbWVudC5vZmZzZXRXaWR0aCAvIHRoaXMubWF4U2l6ZS53aWR0aDtcbiAgICAgIHRoaXMuY3JvcHBlci55MSA9IHRoaXMuY3JvcHBlci55MSAqIHNvdXJjZUltYWdlRWxlbWVudC5vZmZzZXRIZWlnaHQgLyB0aGlzLm1heFNpemUuaGVpZ2h0O1xuICAgICAgdGhpcy5jcm9wcGVyLnkyID0gdGhpcy5jcm9wcGVyLnkyICogc291cmNlSW1hZ2VFbGVtZW50Lm9mZnNldEhlaWdodCAvIHRoaXMubWF4U2l6ZS5oZWlnaHQ7XG4gICAgfVxuICB9XG5cbiAgcmVzZXRDcm9wcGVyUG9zaXRpb24oKTogdm9pZCB7XG4gICAgdGhpcy5jcm9wcGVyUG9zaXRpb25TZXJ2aWNlLnJlc2V0Q3JvcHBlclBvc2l0aW9uKHRoaXMuc291cmNlSW1hZ2UsIHRoaXMuY3JvcHBlciwgdGhpcy5zZXR0aW5ncyk7XG4gICAgdGhpcy5kb0F1dG9Dcm9wKCk7XG4gICAgdGhpcy5pbWFnZVZpc2libGUgPSB0cnVlO1xuICB9XG5cbiAga2V5Ym9hcmRBY2Nlc3MoZXZlbnQ6IGFueSkge1xuICAgIHRoaXMuY2hhbmdlS2V5Ym9hcmRTdGVwU2l6ZShldmVudCk7XG4gICAgdGhpcy5rZXlib2FyZE1vdmVDcm9wcGVyKGV2ZW50KTtcbiAgfVxuXG4gIHByaXZhdGUgY2hhbmdlS2V5Ym9hcmRTdGVwU2l6ZShldmVudDogYW55KTogdm9pZCB7XG4gICAgaWYgKGV2ZW50LmtleSA+PSAnMScgJiYgZXZlbnQua2V5IDw9ICc5Jykge1xuICAgICAgdGhpcy5zZXR0aW5ncy5zdGVwU2l6ZSA9ICtldmVudC5rZXk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBrZXlib2FyZE1vdmVDcm9wcGVyKGV2ZW50KSB7XG4gICAgY29uc3Qga2V5Ym9hcmRXaGl0ZUxpc3Q6IHN0cmluZ1tdID0gWydBcnJvd1VwJywgJ0Fycm93RG93bicsICdBcnJvd1JpZ2h0JywgJ0Fycm93TGVmdCddO1xuICAgIGlmICghKGtleWJvYXJkV2hpdGVMaXN0LmluY2x1ZGVzKGV2ZW50LmtleSkpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IG1vdmVUeXBlID0gZXZlbnQuc2hpZnRLZXkgPyBNb3ZlVHlwZXMuUmVzaXplIDogTW92ZVR5cGVzLk1vdmU7XG4gICAgY29uc3QgcG9zaXRpb24gPSBldmVudC5hbHRLZXkgPyBnZXRJbnZlcnRlZFBvc2l0aW9uRm9yS2V5KGV2ZW50LmtleSkgOiBnZXRQb3NpdGlvbkZvcktleShldmVudC5rZXkpO1xuICAgIGNvbnN0IG1vdmVFdmVudCA9IGdldEV2ZW50Rm9yS2V5KGV2ZW50LmtleSwgdGhpcy5zZXR0aW5ncy5zdGVwU2l6ZSk7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB0aGlzLnN0YXJ0TW92ZSh7Y2xpZW50WDogMCwgY2xpZW50WTogMH0sIG1vdmVUeXBlLCBwb3NpdGlvbik7XG4gICAgdGhpcy5tb3ZlSW1nKG1vdmVFdmVudCk7XG4gICAgdGhpcy5tb3ZlU3RvcCgpO1xuICB9XG5cbiAgc3RhcnRNb3ZlKGV2ZW50OiBhbnksIG1vdmVUeXBlOiBNb3ZlVHlwZXMsIHBvc2l0aW9uOiBzdHJpbmcgfCBudWxsID0gbnVsbCk6IHZvaWQge1xuICAgIGlmICh0aGlzLm1vdmVTdGFydCAmJiB0aGlzLm1vdmVTdGFydC5hY3RpdmUgJiYgdGhpcy5tb3ZlU3RhcnQudHlwZSA9PT0gTW92ZVR5cGVzLlBpbmNoKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChldmVudC5wcmV2ZW50RGVmYXVsdCkge1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB9XG4gICAgdGhpcy5tb3ZlU3RhcnQgPSB7XG4gICAgICBhY3RpdmU6IHRydWUsXG4gICAgICB0eXBlOiBtb3ZlVHlwZSxcbiAgICAgIHBvc2l0aW9uLFxuICAgICAgY2xpZW50WDogdGhpcy5jcm9wcGVyUG9zaXRpb25TZXJ2aWNlLmdldENsaWVudFgoZXZlbnQpLFxuICAgICAgY2xpZW50WTogdGhpcy5jcm9wcGVyUG9zaXRpb25TZXJ2aWNlLmdldENsaWVudFkoZXZlbnQpLFxuICAgICAgLi4udGhpcy5jcm9wcGVyXG4gICAgfTtcbiAgfVxuXG4gIHN0YXJ0UGluY2goZXZlbnQ6IGFueSkge1xuICAgIGlmICghdGhpcy5zYWZlSW1nRGF0YVVybCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoZXZlbnQucHJldmVudERlZmF1bHQpIHtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuICAgIHRoaXMubW92ZVN0YXJ0ID0ge1xuICAgICAgYWN0aXZlOiB0cnVlLFxuICAgICAgdHlwZTogTW92ZVR5cGVzLlBpbmNoLFxuICAgICAgcG9zaXRpb246ICdjZW50ZXInLFxuICAgICAgY2xpZW50WDogdGhpcy5jcm9wcGVyLngxICsgKHRoaXMuY3JvcHBlci54MiAtIHRoaXMuY3JvcHBlci54MSkgLyAyLFxuICAgICAgY2xpZW50WTogdGhpcy5jcm9wcGVyLnkxICsgKHRoaXMuY3JvcHBlci55MiAtIHRoaXMuY3JvcHBlci55MSkgLyAyLFxuICAgICAgLi4udGhpcy5jcm9wcGVyXG4gICAgfTtcbiAgfVxuXG4gIEBIb3N0TGlzdGVuZXIoJ2RvY3VtZW50Om1vdXNlbW92ZScsIFsnJGV2ZW50J10pXG4gIEBIb3N0TGlzdGVuZXIoJ2RvY3VtZW50OnRvdWNobW92ZScsIFsnJGV2ZW50J10pXG4gIG1vdmVJbWcoZXZlbnQ6IGFueSk6IHZvaWQge1xuICAgIGlmICh0aGlzLm1vdmVTdGFydC5hY3RpdmUpIHtcbiAgICAgIGlmIChldmVudC5zdG9wUHJvcGFnYXRpb24pIHtcbiAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICB9XG4gICAgICBpZiAoZXZlbnQucHJldmVudERlZmF1bHQpIHtcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLm1vdmVTdGFydC50eXBlID09PSBNb3ZlVHlwZXMuTW92ZSkge1xuICAgICAgICB0aGlzLmNyb3BwZXJQb3NpdGlvblNlcnZpY2UubW92ZShldmVudCwgdGhpcy5tb3ZlU3RhcnQsIHRoaXMuY3JvcHBlcik7XG4gICAgICAgIHRoaXMuY2hlY2tDcm9wcGVyUG9zaXRpb24odHJ1ZSk7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMubW92ZVN0YXJ0LnR5cGUgPT09IE1vdmVUeXBlcy5SZXNpemUpIHtcbiAgICAgICAgaWYgKCF0aGlzLmNyb3BwZXJTdGF0aWNXaWR0aCAmJiAhdGhpcy5jcm9wcGVyU3RhdGljSGVpZ2h0KSB7XG4gICAgICAgICAgdGhpcy5jcm9wcGVyUG9zaXRpb25TZXJ2aWNlLnJlc2l6ZShldmVudCwgdGhpcy5tb3ZlU3RhcnQsIHRoaXMuY3JvcHBlciwgdGhpcy5tYXhTaXplLCB0aGlzLnNldHRpbmdzKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmNoZWNrQ3JvcHBlclBvc2l0aW9uKGZhbHNlKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuY2QuZGV0ZWN0Q2hhbmdlcygpO1xuICAgIH1cbiAgfVxuXG4gIG9uUGluY2goZXZlbnQ6IGFueSkge1xuICAgIGlmICh0aGlzLm1vdmVTdGFydC5hY3RpdmUpIHtcbiAgICAgIGlmIChldmVudC5zdG9wUHJvcGFnYXRpb24pIHtcbiAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICB9XG4gICAgICBpZiAoZXZlbnQucHJldmVudERlZmF1bHQpIHtcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLm1vdmVTdGFydC50eXBlID09PSBNb3ZlVHlwZXMuUGluY2gpIHtcbiAgICAgICAgdGhpcy5jcm9wcGVyUG9zaXRpb25TZXJ2aWNlLnJlc2l6ZShldmVudCwgdGhpcy5tb3ZlU3RhcnQsIHRoaXMuY3JvcHBlciwgdGhpcy5tYXhTaXplLCB0aGlzLnNldHRpbmdzKTtcbiAgICAgICAgdGhpcy5jaGVja0Nyb3BwZXJQb3NpdGlvbihmYWxzZSk7XG4gICAgICB9XG4gICAgICB0aGlzLmNkLmRldGVjdENoYW5nZXMoKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHNldE1heFNpemUoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuc291cmNlSW1hZ2UpIHtcbiAgICAgIGNvbnN0IHNvdXJjZUltYWdlRWxlbWVudCA9IHRoaXMuc291cmNlSW1hZ2UubmF0aXZlRWxlbWVudDtcbiAgICAgIHRoaXMubWF4U2l6ZS53aWR0aCA9IHNvdXJjZUltYWdlRWxlbWVudC5vZmZzZXRXaWR0aDtcbiAgICAgIHRoaXMubWF4U2l6ZS5oZWlnaHQgPSBzb3VyY2VJbWFnZUVsZW1lbnQub2Zmc2V0SGVpZ2h0O1xuICAgICAgdGhpcy5tYXJnaW5MZWZ0ID0gdGhpcy5zYW5pdGl6ZXIuYnlwYXNzU2VjdXJpdHlUcnVzdFN0eWxlKCdjYWxjKDUwJSAtICcgKyB0aGlzLm1heFNpemUud2lkdGggLyAyICsgJ3B4KScpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc2V0Q3JvcHBlclNjYWxlZE1pblNpemUoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMubG9hZGVkSW1hZ2UgJiYgdGhpcy5sb2FkZWRJbWFnZS50cmFuc2Zvcm1lZCAmJiB0aGlzLmxvYWRlZEltYWdlLnRyYW5zZm9ybWVkLmltYWdlKSB7XG4gICAgICB0aGlzLnNldENyb3BwZXJTY2FsZWRNaW5XaWR0aCgpO1xuICAgICAgdGhpcy5zZXRDcm9wcGVyU2NhbGVkTWluSGVpZ2h0KCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc2V0dGluZ3MuY3JvcHBlclNjYWxlZE1pbldpZHRoID0gMjA7XG4gICAgICB0aGlzLnNldHRpbmdzLmNyb3BwZXJTY2FsZWRNaW5IZWlnaHQgPSAyMDtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHNldENyb3BwZXJTY2FsZWRNaW5XaWR0aCgpOiB2b2lkIHtcbiAgICB0aGlzLnNldHRpbmdzLmNyb3BwZXJTY2FsZWRNaW5XaWR0aCA9IHRoaXMuY3JvcHBlck1pbldpZHRoID4gMFxuICAgICAgPyBNYXRoLm1heCgyMCwgdGhpcy5jcm9wcGVyTWluV2lkdGggLyB0aGlzLmxvYWRlZEltYWdlLnRyYW5zZm9ybWVkLmltYWdlLndpZHRoICogdGhpcy5tYXhTaXplLndpZHRoKVxuICAgICAgOiAyMDtcbiAgfVxuXG4gIHByaXZhdGUgc2V0Q3JvcHBlclNjYWxlZE1pbkhlaWdodCgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5tYWludGFpbkFzcGVjdFJhdGlvKSB7XG4gICAgICB0aGlzLnNldHRpbmdzLmNyb3BwZXJTY2FsZWRNaW5IZWlnaHQgPSBNYXRoLm1heCgyMCwgdGhpcy5zZXR0aW5ncy5jcm9wcGVyU2NhbGVkTWluV2lkdGggLyB0aGlzLmFzcGVjdFJhdGlvKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuY3JvcHBlck1pbkhlaWdodCA+IDApIHtcbiAgICAgIHRoaXMuc2V0dGluZ3MuY3JvcHBlclNjYWxlZE1pbkhlaWdodCA9IE1hdGgubWF4KFxuICAgICAgICAyMCxcbiAgICAgICAgdGhpcy5jcm9wcGVyTWluSGVpZ2h0IC8gdGhpcy5sb2FkZWRJbWFnZS50cmFuc2Zvcm1lZC5pbWFnZS5oZWlnaHQgKiB0aGlzLm1heFNpemUuaGVpZ2h0XG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnNldHRpbmdzLmNyb3BwZXJTY2FsZWRNaW5IZWlnaHQgPSAyMDtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHNldENyb3BwZXJTY2FsZWRNYXhTaXplKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmxvYWRlZEltYWdlICYmIHRoaXMubG9hZGVkSW1hZ2UudHJhbnNmb3JtZWQgJiYgdGhpcy5sb2FkZWRJbWFnZS50cmFuc2Zvcm1lZC5pbWFnZSkge1xuICAgICAgY29uc3QgcmF0aW8gPSB0aGlzLmxvYWRlZEltYWdlLnRyYW5zZm9ybWVkLnNpemUud2lkdGggLyB0aGlzLm1heFNpemUud2lkdGg7XG4gICAgICB0aGlzLnNldHRpbmdzLmNyb3BwZXJTY2FsZWRNYXhXaWR0aCA9IHRoaXMuY3JvcHBlck1heFdpZHRoID4gMjAgPyB0aGlzLmNyb3BwZXJNYXhXaWR0aCAvIHJhdGlvIDogdGhpcy5tYXhTaXplLndpZHRoO1xuICAgICAgdGhpcy5zZXR0aW5ncy5jcm9wcGVyU2NhbGVkTWF4SGVpZ2h0ID0gdGhpcy5jcm9wcGVyTWF4SGVpZ2h0ID4gMjAgPyB0aGlzLmNyb3BwZXJNYXhIZWlnaHQgLyByYXRpbyA6IHRoaXMubWF4U2l6ZS5oZWlnaHQ7XG4gICAgICBpZiAodGhpcy5tYWludGFpbkFzcGVjdFJhdGlvKSB7XG4gICAgICAgIGlmICh0aGlzLnNldHRpbmdzLmNyb3BwZXJTY2FsZWRNYXhXaWR0aCA+IHRoaXMuc2V0dGluZ3MuY3JvcHBlclNjYWxlZE1heEhlaWdodCAqIHRoaXMuYXNwZWN0UmF0aW8pIHtcbiAgICAgICAgICB0aGlzLnNldHRpbmdzLmNyb3BwZXJTY2FsZWRNYXhXaWR0aCA9IHRoaXMuc2V0dGluZ3MuY3JvcHBlclNjYWxlZE1heEhlaWdodCAqIHRoaXMuYXNwZWN0UmF0aW87XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5zZXR0aW5ncy5jcm9wcGVyU2NhbGVkTWF4V2lkdGggPCB0aGlzLnNldHRpbmdzLmNyb3BwZXJTY2FsZWRNYXhIZWlnaHQgKiB0aGlzLmFzcGVjdFJhdGlvKSB7XG4gICAgICAgICAgdGhpcy5zZXR0aW5ncy5jcm9wcGVyU2NhbGVkTWF4SGVpZ2h0ID0gdGhpcy5zZXR0aW5ncy5jcm9wcGVyU2NhbGVkTWF4V2lkdGggLyB0aGlzLmFzcGVjdFJhdGlvO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc2V0dGluZ3MuY3JvcHBlclNjYWxlZE1heFdpZHRoID0gdGhpcy5tYXhTaXplLndpZHRoO1xuICAgICAgdGhpcy5zZXR0aW5ncy5jcm9wcGVyU2NhbGVkTWF4SGVpZ2h0ID0gdGhpcy5tYXhTaXplLmhlaWdodDtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGNoZWNrQ3JvcHBlclBvc2l0aW9uKG1haW50YWluU2l6ZSA9IGZhbHNlKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuY3JvcHBlci54MSA8IDApIHtcbiAgICAgIHRoaXMuY3JvcHBlci54MiAtPSBtYWludGFpblNpemUgPyB0aGlzLmNyb3BwZXIueDEgOiAwO1xuICAgICAgdGhpcy5jcm9wcGVyLngxID0gMDtcbiAgICB9XG4gICAgaWYgKHRoaXMuY3JvcHBlci55MSA8IDApIHtcbiAgICAgIHRoaXMuY3JvcHBlci55MiAtPSBtYWludGFpblNpemUgPyB0aGlzLmNyb3BwZXIueTEgOiAwO1xuICAgICAgdGhpcy5jcm9wcGVyLnkxID0gMDtcbiAgICB9XG4gICAgaWYgKHRoaXMuY3JvcHBlci54MiA+IHRoaXMubWF4U2l6ZS53aWR0aCkge1xuICAgICAgdGhpcy5jcm9wcGVyLngxIC09IG1haW50YWluU2l6ZSA/ICh0aGlzLmNyb3BwZXIueDIgLSB0aGlzLm1heFNpemUud2lkdGgpIDogMDtcbiAgICAgIHRoaXMuY3JvcHBlci54MiA9IHRoaXMubWF4U2l6ZS53aWR0aDtcbiAgICB9XG4gICAgaWYgKHRoaXMuY3JvcHBlci55MiA+IHRoaXMubWF4U2l6ZS5oZWlnaHQpIHtcbiAgICAgIHRoaXMuY3JvcHBlci55MSAtPSBtYWludGFpblNpemUgPyAodGhpcy5jcm9wcGVyLnkyIC0gdGhpcy5tYXhTaXplLmhlaWdodCkgOiAwO1xuICAgICAgdGhpcy5jcm9wcGVyLnkyID0gdGhpcy5tYXhTaXplLmhlaWdodDtcbiAgICB9XG4gIH1cblxuICBASG9zdExpc3RlbmVyKCdkb2N1bWVudDptb3VzZXVwJylcbiAgQEhvc3RMaXN0ZW5lcignZG9jdW1lbnQ6dG91Y2hlbmQnKVxuICBtb3ZlU3RvcCgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5tb3ZlU3RhcnQuYWN0aXZlKSB7XG4gICAgICB0aGlzLm1vdmVTdGFydC5hY3RpdmUgPSBmYWxzZTtcbiAgICAgIHRoaXMuZG9BdXRvQ3JvcCgpO1xuICAgIH1cbiAgfVxuXG4gIHBpbmNoU3RvcCgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5tb3ZlU3RhcnQuYWN0aXZlKSB7XG4gICAgICB0aGlzLm1vdmVTdGFydC5hY3RpdmUgPSBmYWxzZTtcbiAgICAgIHRoaXMuZG9BdXRvQ3JvcCgpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZG9BdXRvQ3JvcCgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5hdXRvQ3JvcCkge1xuICAgICAgdGhpcy5jcm9wKCk7XG4gICAgfVxuICB9XG5cbiAgY3JvcCgpOiBJbWFnZUNyb3BwZWRFdmVudCB8IG51bGwge1xuICAgIGlmICh0aGlzLnNvdXJjZUltYWdlICYmIHRoaXMuc291cmNlSW1hZ2UubmF0aXZlRWxlbWVudCAmJiB0aGlzLmxvYWRlZEltYWdlLnRyYW5zZm9ybWVkLmltYWdlICE9IG51bGwpIHtcbiAgICAgIHRoaXMuc3RhcnRDcm9wSW1hZ2UuZW1pdCgpO1xuICAgICAgY29uc3Qgb3V0cHV0ID0gdGhpcy5jcm9wU2VydmljZS5jcm9wKHRoaXMuc291cmNlSW1hZ2UsIHRoaXMubG9hZGVkSW1hZ2UsIHRoaXMuY3JvcHBlciwgdGhpcy5zZXR0aW5ncyk7XG4gICAgICBpZiAob3V0cHV0ICE9IG51bGwpIHtcbiAgICAgICAgdGhpcy5pbWFnZUNyb3BwZWQuZW1pdChvdXRwdXQpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG91dHB1dDtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbn1cbiJdfQ==