@ks89/angular-modal-gallery 12.0.0 → 13.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/CONTRIBUTING.md +8 -11
  2. package/README.md +7 -5
  3. package/fesm2022/ks89-angular-modal-gallery.mjs +112 -100
  4. package/fesm2022/ks89-angular-modal-gallery.mjs.map +1 -1
  5. package/package.json +6 -8
  6. package/public-api.d.ts +23 -18
  7. package/esm2022/ks89-angular-modal-gallery.mjs +0 -5
  8. package/esm2022/lib/components/accessibility-default.mjs +0 -41
  9. package/esm2022/lib/components/accessible.component.mjs +0 -130
  10. package/esm2022/lib/components/carousel/carousel-previews/carousel-previews.component.mjs +0 -456
  11. package/esm2022/lib/components/carousel/carousel.component.mjs +0 -738
  12. package/esm2022/lib/components/components.mjs +0 -50
  13. package/esm2022/lib/components/current-image/current-image.component.mjs +0 -607
  14. package/esm2022/lib/components/current-image/loading-spinner/loading-spinner.component.mjs +0 -80
  15. package/esm2022/lib/components/dots/dots.component.mjs +0 -124
  16. package/esm2022/lib/components/modal-gallery/attach-to-overlay.service.mjs +0 -42
  17. package/esm2022/lib/components/modal-gallery/modal-gallery-ref.mjs +0 -103
  18. package/esm2022/lib/components/modal-gallery/modal-gallery.component.mjs +0 -499
  19. package/esm2022/lib/components/modal-gallery/modal-gallery.service.mjs +0 -168
  20. package/esm2022/lib/components/modal-gallery/modal-gallery.tokens.mjs +0 -26
  21. package/esm2022/lib/components/plain-gallery/plain-gallery.component.mjs +0 -249
  22. package/esm2022/lib/components/previews/previews.component.mjs +0 -263
  23. package/esm2022/lib/components/upper-buttons/upper-buttons-default.mjs +0 -76
  24. package/esm2022/lib/components/upper-buttons/upper-buttons.component.mjs +0 -243
  25. package/esm2022/lib/directives/a-tag-bg-image.directive.mjs +0 -78
  26. package/esm2022/lib/directives/click-outside.directive.mjs +0 -91
  27. package/esm2022/lib/directives/description.directive.mjs +0 -98
  28. package/esm2022/lib/directives/direction.directive.mjs +0 -73
  29. package/esm2022/lib/directives/directives.mjs +0 -51
  30. package/esm2022/lib/directives/fallback-image.directive.mjs +0 -59
  31. package/esm2022/lib/directives/keyboard-navigation.directive.mjs +0 -64
  32. package/esm2022/lib/directives/margin.directive.mjs +0 -84
  33. package/esm2022/lib/directives/max-size.directive.mjs +0 -75
  34. package/esm2022/lib/directives/size.directive.mjs +0 -76
  35. package/esm2022/lib/directives/swipe.directive.mjs +0 -116
  36. package/esm2022/lib/directives/wrap.directive.mjs +0 -74
  37. package/esm2022/lib/modal-gallery.module.mjs +0 -88
  38. package/esm2022/lib/model/accessibility.interface.mjs +0 -25
  39. package/esm2022/lib/model/action.enum.mjs +0 -36
  40. package/esm2022/lib/model/buttons-config.interface.mjs +0 -62
  41. package/esm2022/lib/model/carousel-config.interface.mjs +0 -25
  42. package/esm2022/lib/model/carousel-image-config.interface.mjs +0 -25
  43. package/esm2022/lib/model/carousel-preview-config.interface.mjs +0 -25
  44. package/esm2022/lib/model/current-image-config.interface.mjs +0 -25
  45. package/esm2022/lib/model/description.interface.mjs +0 -33
  46. package/esm2022/lib/model/dots-config.interface.mjs +0 -25
  47. package/esm2022/lib/model/image-internal.class.mjs +0 -35
  48. package/esm2022/lib/model/image.class.mjs +0 -56
  49. package/esm2022/lib/model/interaction-event.interface.mjs +0 -2
  50. package/esm2022/lib/model/keyboard-config.interface.mjs +0 -25
  51. package/esm2022/lib/model/keyboard.enum.mjs +0 -35
  52. package/esm2022/lib/model/lib-config.interface.mjs +0 -25
  53. package/esm2022/lib/model/loading-config.interface.mjs +0 -37
  54. package/esm2022/lib/model/max-size.interface.mjs +0 -25
  55. package/esm2022/lib/model/modal-gallery-config.interface.mjs +0 -25
  56. package/esm2022/lib/model/plain-gallery-config.interface.mjs +0 -55
  57. package/esm2022/lib/model/play-config.interface.mjs +0 -25
  58. package/esm2022/lib/model/preview-config.interface.mjs +0 -25
  59. package/esm2022/lib/model/size.interface.mjs +0 -25
  60. package/esm2022/lib/model/slide-config.interface.mjs +0 -25
  61. package/esm2022/lib/services/config.service.mjs +0 -388
  62. package/esm2022/lib/services/id-validator.service.mjs +0 -71
  63. package/esm2022/lib/utils/image.util.mjs +0 -48
  64. package/esm2022/lib/utils/user-input.util.mjs +0 -104
  65. package/esm2022/public-api.mjs +0 -42
@@ -1,456 +0,0 @@
1
- /*
2
- The MIT License (MIT)
3
-
4
- Copyright (c) 2017-2024 Stefano Cappa (Ks89)
5
-
6
- Permission is hereby granted, free of charge, to any person obtaining a copy
7
- of this software and associated documentation files (the "Software"), to deal
8
- in the Software without restriction, including without limitation the rights
9
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
- copies of the Software, and to permit persons to whom the Software is
11
- furnished to do so, subject to the following conditions:
12
-
13
- The above copyright notice and this permission notice shall be included in all
14
- copies or substantial portions of the Software.
15
-
16
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
- FITNESS FOR A PARTICULAR PURPOSE AND NON INFRINGEMENT. IN NO EVENT SHALL THE
19
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
- SOFTWARE.
23
- */
24
- import { ChangeDetectionStrategy, Component, EventEmitter, HostBinding, Input, Output } from '@angular/core';
25
- import { Breakpoints } from '@angular/cdk/layout';
26
- import { AccessibleComponent } from '../../accessible.component';
27
- import { NEXT, PREV } from '../../../utils/user-input.util';
28
- import { getIndex } from '../../../utils/image.util';
29
- import { Action } from '../../../model/action.enum';
30
- import * as i0 from "@angular/core";
31
- import * as i1 from "@angular/cdk/layout";
32
- import * as i2 from "@angular/platform-browser";
33
- import * as i3 from "../../../services/config.service";
34
- import * as i4 from "@angular/common";
35
- import * as i5 from "../../../directives/size.directive";
36
- import * as i6 from "../../../directives/fallback-image.directive";
37
- /**
38
- * Default max height of previews.
39
- */
40
- const DEFAULT_MAX_HEIGHT = '200px';
41
- /**
42
- * Component with image previews for carousel
43
- */
44
- export class CarouselPreviewsComponent extends AccessibleComponent {
45
- constructor(ref, breakpointObserver,
46
- // sanitizer is used only to sanitize style before add it to background property when legacyIE11Mode is enabled
47
- sanitizer, configService) {
48
- super();
49
- this.ref = ref;
50
- this.breakpointObserver = breakpointObserver;
51
- this.sanitizer = sanitizer;
52
- this.configService = configService;
53
- /**
54
- * Variable to change the max-width of the host component
55
- */
56
- this.hostMaxWidth = '100%';
57
- /**
58
- * Variable to set aria-label of the host component
59
- */
60
- this.ariaLabel = `Carousel previews`;
61
- /**
62
- * Output to emit the clicked preview. The payload contains the `InternalLibImage` associated to the clicked preview.
63
- */
64
- this.clickPreview = new EventEmitter();
65
- /**
66
- * Enum of type `Action` that represents a mouse click on a button.
67
- * Declared here to be used inside the template.
68
- */
69
- this.clickAction = Action.CLICK;
70
- /**
71
- * Enum of type `Action` that represents a keyboard action.
72
- * Declared here to be used inside the template.
73
- */
74
- this.keyboardAction = Action.KEYBOARD;
75
- /**
76
- * Array of `InternalLibImage` exposed to the template. This field is initialized
77
- * applying transformations, default values and so on to the input of the same type.
78
- */
79
- this.previews = [];
80
- /**
81
- * Variable with the preview's maxHeight
82
- */
83
- this.previewMaxHeight = DEFAULT_MAX_HEIGHT;
84
- // listen for width changes and update preview heights accordingly
85
- this.breakpointSubscription = breakpointObserver
86
- .observe([Breakpoints.XSmall, Breakpoints.Small, Breakpoints.Medium, Breakpoints.Large, Breakpoints.XLarge])
87
- .subscribe((result) => {
88
- if (!this.previewConfig || !this.previewConfig.breakpoints) {
89
- return;
90
- }
91
- if (result.breakpoints[Breakpoints.XSmall]) {
92
- this.updateHeight(this.previewConfig.breakpoints.xSmall);
93
- }
94
- else if (result.breakpoints[Breakpoints.Small]) {
95
- this.updateHeight(this.previewConfig.breakpoints.small);
96
- }
97
- else if (result.breakpoints[Breakpoints.Medium]) {
98
- this.updateHeight(this.previewConfig.breakpoints.medium);
99
- }
100
- else if (result.breakpoints[Breakpoints.Large]) {
101
- this.updateHeight(this.previewConfig.breakpoints.large);
102
- }
103
- else if (result.breakpoints[Breakpoints.XLarge]) {
104
- this.updateHeight(this.previewConfig.breakpoints.xLarge);
105
- }
106
- });
107
- }
108
- /**
109
- * Method to update the height of previews, passing the desired height as input.
110
- * @param configBreakpointHeight is a number that represent the desired height to set.
111
- */
112
- updateHeight(configBreakpointHeight) {
113
- if (this.previewConfig && this.previewConfig.maxHeight) {
114
- const heightNum = +this.previewConfig.maxHeight.replace('/px/g', '').replace('/%/g', '');
115
- this.previewMaxHeight = Math.min(configBreakpointHeight, heightNum) + 'px';
116
- }
117
- else {
118
- const heightNum = +DEFAULT_MAX_HEIGHT.replace('/px/g', '').replace('/%/g', '');
119
- this.previewMaxHeight = Math.min(configBreakpointHeight, heightNum) + 'px';
120
- }
121
- this.ref.markForCheck();
122
- }
123
- /**
124
- * Method ´ngOnInit´ to build `configPreview` applying a default value and also to
125
- * init the `previews` array.
126
- * This is an angular lifecycle hook, so its called automatically by Angular itself.
127
- * In particular, it's called only one time!!!
128
- */
129
- ngOnInit() {
130
- const libConfig = this.configService.getConfig(this.id);
131
- if (!libConfig) {
132
- throw new Error('Internal library error - libConfig must be defined');
133
- }
134
- this.carouselConfig = libConfig.carouselConfig;
135
- this.previewConfig = libConfig.carouselPreviewsConfig;
136
- this.accessibilityConfig = libConfig.accessibilityConfig;
137
- if (!this.previewConfig || !this.previewConfig.maxHeight || !this.previewConfig.breakpoints) {
138
- throw new Error('Internal library error - previewConfig must be defined');
139
- }
140
- // change the max-width of this component if there is a specified width !== 100% in carouselConfig
141
- if (this.carouselConfig && this.carouselConfig.maxWidth !== '100%') {
142
- this.hostMaxWidth = this.carouselConfig.maxWidth;
143
- }
144
- this.previewMaxHeight = this.previewConfig.maxHeight;
145
- // init previews based on currentImage and the full array of images
146
- this.initPreviews(this.currentImage, this.images);
147
- // apply custom height based on responsive breakpoints
148
- // This is required, because the breakpointSubscription is not triggered at creation,
149
- // but only when the width changes
150
- const isXsmallScreen = this.breakpointObserver.isMatched(Breakpoints.XSmall);
151
- const isSmallScreen = this.breakpointObserver.isMatched(Breakpoints.Small);
152
- const isMediumScreen = this.breakpointObserver.isMatched(Breakpoints.Medium);
153
- const isLargeScreen = this.breakpointObserver.isMatched(Breakpoints.Large);
154
- const isxLargeScreen = this.breakpointObserver.isMatched(Breakpoints.XLarge);
155
- if (isXsmallScreen) {
156
- this.updateHeight(this.previewConfig.breakpoints.xSmall);
157
- }
158
- else if (isSmallScreen) {
159
- this.updateHeight(this.previewConfig.breakpoints.small);
160
- }
161
- else if (isMediumScreen) {
162
- this.updateHeight(this.previewConfig.breakpoints.medium);
163
- }
164
- else if (isLargeScreen) {
165
- this.updateHeight(this.previewConfig.breakpoints.large);
166
- }
167
- else if (isxLargeScreen) {
168
- this.updateHeight(this.previewConfig.breakpoints.xLarge);
169
- }
170
- }
171
- /**
172
- * Method to check if an image is active (i.e. a preview image).
173
- * @param InternalLibImage preview is an image to check if it's active or not
174
- * @returns boolean true if is active, false otherwise
175
- */
176
- isActive(preview) {
177
- if (!preview || !this.currentImage) {
178
- return false;
179
- }
180
- return preview.id === this.currentImage.id;
181
- }
182
- /**
183
- * Method ´ngOnChanges´ to update `previews` array.
184
- * Also, both `start` and `end` local variables will be updated accordingly.
185
- * This is an angular lifecycle hook, so its called automatically by Angular itself.
186
- * In particular, it's called when any data-bound property of a directive changes!!!
187
- */
188
- ngOnChanges(changes) {
189
- const simpleChange = changes.currentImage;
190
- if (!simpleChange) {
191
- return;
192
- }
193
- const prev = simpleChange.previousValue;
194
- const current = simpleChange.currentValue;
195
- if (current && changes.images && changes.images.previousValue && changes.images.currentValue) {
196
- // I'm in this if statement, if input images are changed (for instance, because I removed one of them with the 'delete button',
197
- // or because users changed the images array while modal gallery is still open).
198
- // In this case, I have to re-init previews, because the input array of images is changed.
199
- this.initPreviews(current, changes.images.currentValue);
200
- }
201
- if (prev && current && prev.id !== current.id) {
202
- // to manage infinite sliding I have to reset both `start` and `end` at the beginning
203
- // to show again previews from the first image.
204
- // This happens when you navigate over the last image to return to the first one
205
- let prevIndex;
206
- let currentIndex;
207
- try {
208
- prevIndex = getIndex(prev, this.images);
209
- currentIndex = getIndex(current, this.images);
210
- }
211
- catch (err) {
212
- console.error('Cannot get previous and current image indexes in previews');
213
- throw err;
214
- }
215
- // apply a formula to get a values to be used to decide if go next, return back or stay without doing anything
216
- const calc = Math.floor((this.end - this.start) / 2) + this.start;
217
- if (prevIndex === this.images.length - 1 && currentIndex === 0) {
218
- // first image
219
- this.setBeginningIndexesPreviews();
220
- this.previews = this.images.filter((img, i) => i >= this.start && i < this.end);
221
- return;
222
- }
223
- // the same for the opposite case, when you navigate back from the fist image to go to the last one.
224
- if (prevIndex === 0 && currentIndex === this.images.length - 1) {
225
- // last image
226
- this.setEndIndexesPreviews();
227
- this.previews = this.images.filter((img, i) => i >= this.start && i < this.end);
228
- return;
229
- }
230
- if (this.previewConfig && this.previewConfig.number % 2 === 0) {
231
- if (calc > currentIndex) {
232
- this.previous();
233
- }
234
- else {
235
- this.next();
236
- }
237
- }
238
- else {
239
- if (calc > currentIndex) {
240
- this.previous();
241
- }
242
- if (calc < currentIndex) {
243
- this.next();
244
- }
245
- }
246
- }
247
- }
248
- /**
249
- * Method called by events from both keyboard and mouse on a preview.
250
- * This will trigger the `clickpreview` output with the input preview as its payload.
251
- * @param InternalLibImage preview that triggered this method
252
- * @param KeyboardEvent | MouseEvent event payload
253
- * @param Action that triggered this event (Action.NORMAL by default)
254
- */
255
- onImageEvent(preview, event, action = Action.NORMAL) {
256
- if (!this.previewConfig || !this.previewConfig.clickable) {
257
- return;
258
- }
259
- const clickedImageIndex = this.images.indexOf(preview);
260
- const result = super.handleImageEvent(event);
261
- if (result === NEXT) {
262
- this.clickPreview.emit({ action, result: clickedImageIndex });
263
- }
264
- else if (result === PREV) {
265
- this.clickPreview.emit({ action, result: clickedImageIndex });
266
- }
267
- }
268
- /**
269
- * Method called by events from both keyboard and mouse on a navigation arrow.
270
- * @param string direction of the navigation that can be either 'next' or 'prev'
271
- * @param KeyboardEvent | MouseEvent event payload
272
- */
273
- onNavigationEvent(direction, event) {
274
- const result = super.handleNavigationEvent(direction, event);
275
- if (result === NEXT) {
276
- this.next();
277
- }
278
- else if (result === PREV) {
279
- this.previous();
280
- }
281
- }
282
- /**
283
- * Method to get aria-label text for a preview image.
284
- * @param Image is the preview
285
- */
286
- getAriaLabel(preview) {
287
- if (!preview.plain) {
288
- return preview.modal.ariaLabel || '';
289
- }
290
- return preview.plain.ariaLabel || preview.modal.ariaLabel || '';
291
- }
292
- /**
293
- * Method to get title text for a preview image.
294
- * @param Image is the preview
295
- */
296
- getTitle(preview) {
297
- if (!preview.plain) {
298
- return preview.modal.title || '';
299
- }
300
- return preview.plain.title || preview.modal.title || '';
301
- }
302
- /**
303
- * Method to get alt text for a preview image.
304
- * @param Image is the preview
305
- */
306
- getAlt(preview) {
307
- if (!preview.plain) {
308
- return preview.modal.alt || '';
309
- }
310
- return preview.plain.alt || preview.modal.alt || '';
311
- }
312
- /**
313
- * Method used in the template to track ids in ngFor.
314
- * @param number index of the array
315
- * @param Image item of the array
316
- * @returns number the id of the item
317
- */
318
- trackById(index, item) {
319
- return item.id;
320
- }
321
- /**
322
- * Method used in template to sanitize an url when you need legacyIE11Mode.
323
- * In this way you can set an url as background of a div.
324
- * @param unsafeStyle is a string or a SafeResourceUrl that represents the url to sanitize.
325
- * @param unsafeStyleFallback is a string or a SafeResourceUrl that represents the fallback url to sanitize.
326
- * @returns a SafeStyle object that can be used in template without problems.
327
- */
328
- sanitizeUrlBgStyle(unsafeStyle, unsafeStyleFallback) {
329
- // Method used only to sanitize background-image style before add it to background property when legacyIE11Mode is enabled
330
- let bg = 'url(' + unsafeStyle + ')';
331
- if (!!unsafeStyleFallback) {
332
- // if a fallback image is defined, append it. In this way, it will be used by the browser as fallback.
333
- bg += ', ' + 'url(' + unsafeStyleFallback + ')';
334
- }
335
- return this.sanitizer.bypassSecurityTrustStyle(bg);
336
- }
337
- /**
338
- * Method to cleanup resources. In fact, it cleans breakpointSubscription.
339
- * This is an angular lifecycle hook that is called when this component is destroyed.
340
- */
341
- ngOnDestroy() {
342
- if (this.breakpointSubscription) {
343
- this.breakpointSubscription.unsubscribe();
344
- }
345
- }
346
- /**
347
- * Private method to init previews based on the currentImage and the full array of images.
348
- * The current image in mandatory to show always the current preview (as highlighted).
349
- * @param InternalLibImage currentImage to decide how to show previews, because I always want to see the current image as highlighted
350
- * @param InternalLibImage[] images is the array of all images.
351
- */
352
- initPreviews(currentImage, images) {
353
- let index;
354
- try {
355
- index = getIndex(currentImage, images);
356
- }
357
- catch (err) {
358
- throw err;
359
- }
360
- switch (index) {
361
- case 0:
362
- // first image
363
- this.setBeginningIndexesPreviews();
364
- break;
365
- case images.length - 1:
366
- // last image
367
- this.setEndIndexesPreviews();
368
- break;
369
- // default:
370
- // // other images
371
- // // TODO unused because it starts always at image 0
372
- // this.setIndexesPreviews();
373
- // break;
374
- }
375
- this.previews = images.filter((img, i) => i >= this.start && i < this.end);
376
- }
377
- /**
378
- * Private method to init both `start` and `end` to the beginning.
379
- */
380
- setBeginningIndexesPreviews() {
381
- if (!this.previewConfig || this.previewConfig.number === undefined) {
382
- throw new Error('Internal library error - previewConfig and number must be defined');
383
- }
384
- this.start = 0;
385
- this.end = Math.min(this.previewConfig.number, this.images.length);
386
- }
387
- /**
388
- * Private method to init both `start` and `end` to the end.
389
- */
390
- setEndIndexesPreviews() {
391
- if (!this.previewConfig || this.previewConfig.number === undefined) {
392
- throw new Error('Internal library error - previewConfig and number must be defined');
393
- }
394
- this.start = this.images.length - 1 - (this.previewConfig.number - 1);
395
- this.end = this.images.length;
396
- }
397
- /**
398
- * Private method to update the visible previews navigating to the right (next).
399
- */
400
- next() {
401
- // check if nextImage should be blocked
402
- if (this.isPreventSliding(this.images.length - 1)) {
403
- return;
404
- }
405
- if (this.end === this.images.length) {
406
- return;
407
- }
408
- this.start++;
409
- this.end = Math.min(this.end + 1, this.images.length);
410
- this.previews = this.images.filter((img, i) => i >= this.start && i < this.end);
411
- }
412
- /**
413
- * Private method to update the visible previews navigating to the left (previous).
414
- */
415
- previous() {
416
- // check if prevImage should be blocked
417
- if (this.isPreventSliding(0)) {
418
- return;
419
- }
420
- if (this.start === 0) {
421
- return;
422
- }
423
- this.start = Math.max(this.start - 1, 0);
424
- this.end = Math.min(this.end - 1, this.images.length);
425
- this.previews = this.images.filter((img, i) => i >= this.start && i < this.end);
426
- }
427
- /**
428
- * Private method to block/permit sliding between previews.
429
- * @param number boundaryIndex is the first or the last index of `images` input array
430
- * @returns boolean if true block sliding, otherwise not
431
- */
432
- isPreventSliding(boundaryIndex) {
433
- return getIndex(this.currentImage, this.images) === boundaryIndex;
434
- }
435
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: CarouselPreviewsComponent, deps: [{ token: i0.ChangeDetectorRef }, { token: i1.BreakpointObserver }, { token: i2.DomSanitizer }, { token: i3.ConfigService }], target: i0.ɵɵFactoryTarget.Component }); }
436
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.0.1", type: CarouselPreviewsComponent, selector: "ks-carousel-previews", inputs: { id: "id", currentImage: "currentImage", images: "images" }, outputs: { clickPreview: "clickPreview" }, host: { properties: { "style.max-width": "this.hostMaxWidth", "attr.aria-label": "this.ariaLabel" } }, usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<nav *ngIf=\"previewConfig?.visible\"\n class=\"previews-container\"\n [attr.aria-label]=\"accessibilityConfig?.carouselPreviewsContainerAriaLabel\"\n [title]=\"accessibilityConfig?.carouselPreviewsContainerTitle\">\n\n <a class=\"nav-left\"\n [attr.aria-label]=\"accessibilityConfig?.carouselPreviewScrollPrevAriaLabel\"\n [tabIndex]=\"previewConfig?.arrows && start > 0 ? 0 : -1\" role=\"button\"\n (click)=\"onNavigationEvent('left', $event)\" (keyup)=\"onNavigationEvent('left', $event)\">\n <div class=\"inside {{previewConfig?.arrows && start > 0 ? 'left-arrow-preview-image' : 'empty-arrow-preview-image'}}\"\n aria-hidden=\"true\"\n [title]=\"accessibilityConfig?.carouselPreviewScrollPrevTitle\"></div>\n </a>\n\n <div class=\"preview-inner-container\">\n <ng-container *ngFor=\"let preview of previews; trackBy: trackById; let index = index\">\n <img *ngIf=\"preview?.modal?.img\"\n [loading]=\"preview.loading\"\n [attr.fetchpriority]=\"preview.fetchpriority\"\n class=\"inside preview-image{{isActive(preview) ? ' active' : ''}}{{!previewConfig?.clickable ? ' unclickable' : ''}}\"\n [src]=\"preview.plain?.img ? preview.plain?.img : preview.modal.img\"\n ksFallbackImage [fallbackImg]=\"preview.plain?.fallbackImg ? preview.plain?.fallbackImg : preview.modal.fallbackImg\"\n ksSize [sizeConfig]=\"{width: previewConfig?.width!,\n height: previewMaxHeight}\"\n [attr.aria-label]=\"getAriaLabel(preview)\"\n [title]=\"getTitle(preview)\"\n alt=\"{{getAlt(preview)}}\"\n [tabIndex]=\"0\" role=\"img\"\n (click)=\"onImageEvent(preview, $event, clickAction)\" (keyup)=\"onImageEvent(preview, $event, keyboardAction)\"/>\n </ng-container>\n </div>\n\n <a class=\"nav-right\"\n [attr.aria-label]=\"accessibilityConfig?.carouselPreviewScrollNextAriaLabel\"\n [tabIndex]=\"previewConfig?.arrows && end < images.length ? 0 : -1\" role=\"button\"\n (click)=\"onNavigationEvent('right', $event)\" (keyup)=\"onNavigationEvent('right', $event)\">\n <div class=\"inside {{previewConfig?.arrows && end < images.length ? 'right-arrow-preview-image' : 'empty-arrow-preview-image'}}\"\n aria-hidden=\"true\"\n [title]=\"accessibilityConfig?.carouselPreviewScrollNextTitle\"></div>\n </a>\n\n</nav>\n", styles: [":host{position:relative;margin-top:3px;margin-bottom:3px;width:100%}.previews-container{align-items:center;animation:fadein-semi-visible08 .8s;display:flex;flex-direction:row;justify-content:center;margin-bottom:0}.previews-container>.preview-inner-container{display:flex;flex-direction:row;justify-content:center;align-items:center;flex-wrap:nowrap;width:100%}.previews-container>.preview-inner-container>.preview-image{cursor:pointer;object-fit:cover}.previews-container>.preview-inner-container>.preview-image.unclickable{cursor:not-allowed}.previews-container .nav,.previews-container>.nav-right,.previews-container>.nav-left{position:absolute;top:calc(50% - 7px);color:#919191;z-index:1000;cursor:pointer;transition:all .5s}.previews-container .nav:hover,.previews-container>.nav-right:hover,.previews-container>.nav-left:hover{transform:scale(1.1)}.previews-container>.nav-left{margin-right:10px;left:10px}.previews-container>.nav-left>.left-arrow-preview-image{opacity:1}.previews-container>.nav-right{margin-left:10px;right:10px}.previews-container>.nav-right>.right-arrow-preview-image{opacity:1}\n", ".arrow-preview-image,.right-arrow-preview-image,.left-arrow-preview-image,.empty-arrow-preview-image{width:15px;height:15px;opacity:.5}.empty-arrow-preview-image{background:#000;opacity:0}.left-arrow-preview-image{background-image:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgdmlld0JveD0iMCAwIDQ3Ny4xNzUgNDc3LjE3NSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgNDc3LjE3NSA0NzcuMTc1OyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSIgd2lkdGg9IjUxMnB4IiBoZWlnaHQ9IjUxMnB4Ij48Zz48cGF0aCBkPSJNMTQ1LjE4OCwyMzguNTc1bDIxNS41LTIxNS41YzUuMy01LjMsNS4zLTEzLjgsMC0xOS4xcy0xMy44LTUuMy0xOS4xLDBsLTIyNS4xLDIyNS4xYy01LjMsNS4zLTUuMywxMy44LDAsMTkuMWwyMjUuMSwyMjUgICBjMi42LDIuNiw2LjEsNCw5LjUsNHM2LjktMS4zLDkuNS00YzUuMy01LjMsNS4zLTEzLjgsMC0xOS4xTDE0NS4xODgsMjM4LjU3NXoiIGZpbGw9IiNGRkZGRkYiLz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PC9zdmc+);background-size:15px;transition:all .5s}.left-arrow-preview-image:hover{transform:scale(1.2)}.right-arrow-preview-image{background-image:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgdmlld0JveD0iMCAwIDQ3Ny4xNzUgNDc3LjE3NSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgNDc3LjE3NSA0NzcuMTc1OyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSIgd2lkdGg9IjUxMnB4IiBoZWlnaHQ9IjUxMnB4Ij48Zz48cGF0aCBkPSJNMzYwLjczMSwyMjkuMDc1bC0yMjUuMS0yMjUuMWMtNS4zLTUuMy0xMy44LTUuMy0xOS4xLDBzLTUuMywxMy44LDAsMTkuMWwyMTUuNSwyMTUuNWwtMjE1LjUsMjE1LjUgICBjLTUuMyw1LjMtNS4zLDEzLjgsMCwxOS4xYzIuNiwyLjYsNi4xLDQsOS41LDRjMy40LDAsNi45LTEuMyw5LjUtNGwyMjUuMS0yMjUuMUMzNjUuOTMxLDI0Mi44NzUsMzY1LjkzMSwyMzQuMjc1LDM2MC43MzEsMjI5LjA3NXogICAiIGZpbGw9IiNGRkZGRkYiLz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PC9zdmc+);background-size:15px;transition:all .5s}.right-arrow-preview-image:hover{transform:scale(1.2)}\n"], dependencies: [{ kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.SizeDirective, selector: "[ksSize]", inputs: ["sizeConfig"] }, { kind: "directive", type: i6.FallbackImageDirective, selector: "[ksFallbackImage]", inputs: ["fallbackImg"], outputs: ["fallbackApplied"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
437
- }
438
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.1", ngImport: i0, type: CarouselPreviewsComponent, decorators: [{
439
- type: Component,
440
- args: [{ selector: 'ks-carousel-previews', changeDetection: ChangeDetectionStrategy.OnPush, template: "<nav *ngIf=\"previewConfig?.visible\"\n class=\"previews-container\"\n [attr.aria-label]=\"accessibilityConfig?.carouselPreviewsContainerAriaLabel\"\n [title]=\"accessibilityConfig?.carouselPreviewsContainerTitle\">\n\n <a class=\"nav-left\"\n [attr.aria-label]=\"accessibilityConfig?.carouselPreviewScrollPrevAriaLabel\"\n [tabIndex]=\"previewConfig?.arrows && start > 0 ? 0 : -1\" role=\"button\"\n (click)=\"onNavigationEvent('left', $event)\" (keyup)=\"onNavigationEvent('left', $event)\">\n <div class=\"inside {{previewConfig?.arrows && start > 0 ? 'left-arrow-preview-image' : 'empty-arrow-preview-image'}}\"\n aria-hidden=\"true\"\n [title]=\"accessibilityConfig?.carouselPreviewScrollPrevTitle\"></div>\n </a>\n\n <div class=\"preview-inner-container\">\n <ng-container *ngFor=\"let preview of previews; trackBy: trackById; let index = index\">\n <img *ngIf=\"preview?.modal?.img\"\n [loading]=\"preview.loading\"\n [attr.fetchpriority]=\"preview.fetchpriority\"\n class=\"inside preview-image{{isActive(preview) ? ' active' : ''}}{{!previewConfig?.clickable ? ' unclickable' : ''}}\"\n [src]=\"preview.plain?.img ? preview.plain?.img : preview.modal.img\"\n ksFallbackImage [fallbackImg]=\"preview.plain?.fallbackImg ? preview.plain?.fallbackImg : preview.modal.fallbackImg\"\n ksSize [sizeConfig]=\"{width: previewConfig?.width!,\n height: previewMaxHeight}\"\n [attr.aria-label]=\"getAriaLabel(preview)\"\n [title]=\"getTitle(preview)\"\n alt=\"{{getAlt(preview)}}\"\n [tabIndex]=\"0\" role=\"img\"\n (click)=\"onImageEvent(preview, $event, clickAction)\" (keyup)=\"onImageEvent(preview, $event, keyboardAction)\"/>\n </ng-container>\n </div>\n\n <a class=\"nav-right\"\n [attr.aria-label]=\"accessibilityConfig?.carouselPreviewScrollNextAriaLabel\"\n [tabIndex]=\"previewConfig?.arrows && end < images.length ? 0 : -1\" role=\"button\"\n (click)=\"onNavigationEvent('right', $event)\" (keyup)=\"onNavigationEvent('right', $event)\">\n <div class=\"inside {{previewConfig?.arrows && end < images.length ? 'right-arrow-preview-image' : 'empty-arrow-preview-image'}}\"\n aria-hidden=\"true\"\n [title]=\"accessibilityConfig?.carouselPreviewScrollNextTitle\"></div>\n </a>\n\n</nav>\n", styles: [":host{position:relative;margin-top:3px;margin-bottom:3px;width:100%}.previews-container{align-items:center;animation:fadein-semi-visible08 .8s;display:flex;flex-direction:row;justify-content:center;margin-bottom:0}.previews-container>.preview-inner-container{display:flex;flex-direction:row;justify-content:center;align-items:center;flex-wrap:nowrap;width:100%}.previews-container>.preview-inner-container>.preview-image{cursor:pointer;object-fit:cover}.previews-container>.preview-inner-container>.preview-image.unclickable{cursor:not-allowed}.previews-container .nav,.previews-container>.nav-right,.previews-container>.nav-left{position:absolute;top:calc(50% - 7px);color:#919191;z-index:1000;cursor:pointer;transition:all .5s}.previews-container .nav:hover,.previews-container>.nav-right:hover,.previews-container>.nav-left:hover{transform:scale(1.1)}.previews-container>.nav-left{margin-right:10px;left:10px}.previews-container>.nav-left>.left-arrow-preview-image{opacity:1}.previews-container>.nav-right{margin-left:10px;right:10px}.previews-container>.nav-right>.right-arrow-preview-image{opacity:1}\n", ".arrow-preview-image,.right-arrow-preview-image,.left-arrow-preview-image,.empty-arrow-preview-image{width:15px;height:15px;opacity:.5}.empty-arrow-preview-image{background:#000;opacity:0}.left-arrow-preview-image{background-image:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgdmlld0JveD0iMCAwIDQ3Ny4xNzUgNDc3LjE3NSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgNDc3LjE3NSA0NzcuMTc1OyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSIgd2lkdGg9IjUxMnB4IiBoZWlnaHQ9IjUxMnB4Ij48Zz48cGF0aCBkPSJNMTQ1LjE4OCwyMzguNTc1bDIxNS41LTIxNS41YzUuMy01LjMsNS4zLTEzLjgsMC0xOS4xcy0xMy44LTUuMy0xOS4xLDBsLTIyNS4xLDIyNS4xYy01LjMsNS4zLTUuMywxMy44LDAsMTkuMWwyMjUuMSwyMjUgICBjMi42LDIuNiw2LjEsNCw5LjUsNHM2LjktMS4zLDkuNS00YzUuMy01LjMsNS4zLTEzLjgsMC0xOS4xTDE0NS4xODgsMjM4LjU3NXoiIGZpbGw9IiNGRkZGRkYiLz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PC9zdmc+);background-size:15px;transition:all .5s}.left-arrow-preview-image:hover{transform:scale(1.2)}.right-arrow-preview-image{background-image:url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgdmlld0JveD0iMCAwIDQ3Ny4xNzUgNDc3LjE3NSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgNDc3LjE3NSA0NzcuMTc1OyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSIgd2lkdGg9IjUxMnB4IiBoZWlnaHQ9IjUxMnB4Ij48Zz48cGF0aCBkPSJNMzYwLjczMSwyMjkuMDc1bC0yMjUuMS0yMjUuMWMtNS4zLTUuMy0xMy44LTUuMy0xOS4xLDBzLTUuMywxMy44LDAsMTkuMWwyMTUuNSwyMTUuNWwtMjE1LjUsMjE1LjUgICBjLTUuMyw1LjMtNS4zLDEzLjgsMCwxOS4xYzIuNiwyLjYsNi4xLDQsOS41LDRjMy40LDAsNi45LTEuMyw5LjUtNGwyMjUuMS0yMjUuMUMzNjUuOTMxLDI0Mi44NzUsMzY1LjkzMSwyMzQuMjc1LDM2MC43MzEsMjI5LjA3NXogICAiIGZpbGw9IiNGRkZGRkYiLz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PC9zdmc+);background-size:15px;transition:all .5s}.right-arrow-preview-image:hover{transform:scale(1.2)}\n"] }]
441
- }], ctorParameters: () => [{ type: i0.ChangeDetectorRef }, { type: i1.BreakpointObserver }, { type: i2.DomSanitizer }, { type: i3.ConfigService }], propDecorators: { hostMaxWidth: [{
442
- type: HostBinding,
443
- args: ['style.max-width']
444
- }], ariaLabel: [{
445
- type: HostBinding,
446
- args: ['attr.aria-label']
447
- }], id: [{
448
- type: Input
449
- }], currentImage: [{
450
- type: Input
451
- }], images: [{
452
- type: Input
453
- }], clickPreview: [{
454
- type: Output
455
- }] } });
456
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2Fyb3VzZWwtcHJldmlld3MuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMva3M4OS9hbmd1bGFyLW1vZGFsLWdhbGxlcnkvc3JjL2xpYi9jb21wb25lbnRzL2Nhcm91c2VsL2Nhcm91c2VsLXByZXZpZXdzL2Nhcm91c2VsLXByZXZpZXdzLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2tzODkvYW5ndWxhci1tb2RhbC1nYWxsZXJ5L3NyYy9saWIvY29tcG9uZW50cy9jYXJvdXNlbC9jYXJvdXNlbC1wcmV2aWV3cy9jYXJvdXNlbC1wcmV2aWV3cy5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBc0JHO0FBRUgsT0FBTyxFQUNMLHVCQUF1QixFQUV2QixTQUFTLEVBQ1QsWUFBWSxFQUNaLFdBQVcsRUFDWCxLQUFLLEVBSUwsTUFBTSxFQUdQLE1BQU0sZUFBZSxDQUFDO0FBRXZCLE9BQU8sRUFBc0IsV0FBVyxFQUFtQixNQUFNLHFCQUFxQixDQUFDO0FBSXZGLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBUWpFLE9BQU8sRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDNUQsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQ3JELE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQzs7Ozs7Ozs7QUFJcEQ7O0dBRUc7QUFDSCxNQUFNLGtCQUFrQixHQUFHLE9BQU8sQ0FBQztBQUVuQzs7R0FFRztBQU9ILE1BQU0sT0FBTyx5QkFBMEIsU0FBUSxtQkFBbUI7SUFtRmhFLFlBQ1UsR0FBc0IsRUFDdEIsa0JBQXNDO0lBQzlDLCtHQUErRztJQUN2RyxTQUF1QixFQUN2QixhQUE0QjtRQUVwQyxL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QUFLO2dCQU9OLE1BQU07c0JBREwsS0FBSztnQkFPTixZQUFZO3NCQURYLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuIFRoZSBNSVQgTGljZW5zZSAoTUlUKVxuXG4gQ29weXJpZ2h0IChjKSAyMDE3LTIwMjQgU3RlZmFubyBDYXBwYSAoS3M4OSlcblxuIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHlcbiBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZSBcIlNvZnR3YXJlXCIpLCB0byBkZWFsXG4gaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0c1xuIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGxcbiBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbiBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuXG4gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW4gYWxsXG4gY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cblxuIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1JcbiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OIElORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFXG4gQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxuIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sXG4gT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEVcbiBTT0ZUV0FSRS5cbiAqL1xuXG5pbXBvcnQge1xuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIENvbXBvbmVudCxcbiAgRXZlbnRFbWl0dGVyLFxuICBIb3N0QmluZGluZyxcbiAgSW5wdXQsXG4gIE9uQ2hhbmdlcyxcbiAgT25EZXN0cm95LFxuICBPbkluaXQsXG4gIE91dHB1dCxcbiAgU2ltcGxlQ2hhbmdlLFxuICBTaW1wbGVDaGFuZ2VzXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRG9tU2FuaXRpemVyLCBTYWZlUmVzb3VyY2VVcmwsIFNhZmVTdHlsZSB9IGZyb20gJ0Bhbmd1bGFyL3BsYXRmb3JtLWJyb3dzZXInO1xuaW1wb3J0IHsgQnJlYWtwb2ludE9ic2VydmVyLCBCcmVha3BvaW50cywgQnJlYWtwb2ludFN0YXRlIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL2xheW91dCc7XG5cbmltcG9ydCB7IFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQgeyBBY2Nlc3NpYmxlQ29tcG9uZW50IH0gZnJvbSAnLi4vLi4vYWNjZXNzaWJsZS5jb21wb25lbnQnO1xuXG5pbXBvcnQgeyBBY2Nlc3NpYmlsaXR5Q29uZmlnIH0gZnJvbSAnLi4vLi4vLi4vbW9kZWwvYWNjZXNzaWJpbGl0eS5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgSW1hZ2UsIEltYWdlRXZlbnQgfSBmcm9tICcuLi8uLi8uLi9tb2RlbC9pbWFnZS5jbGFzcyc7XG5pbXBvcnQgeyBJbnRlcm5hbExpYkltYWdlIH0gZnJvbSAnLi4vLi4vLi4vbW9kZWwvaW1hZ2UtaW50ZXJuYWwuY2xhc3MnO1xuaW1wb3J0IHsgQ2Fyb3VzZWxQcmV2aWV3Q29uZmlnIH0gZnJvbSAnLi4vLi4vLi4vbW9kZWwvY2Fyb3VzZWwtcHJldmlldy1jb25maWcuaW50ZXJmYWNlJztcbmltcG9ydCB7IENhcm91c2VsQ29uZmlnIH0gZnJvbSAnLi4vLi4vLi4vbW9kZWwvY2Fyb3VzZWwtY29uZmlnLmludGVyZmFjZSc7XG5cbmltcG9ydCB7IE5FWFQsIFBSRVYgfSBmcm9tICcuLi8uLi8uLi91dGlscy91c2VyLWlucHV0LnV0aWwnO1xuaW1wb3J0IHsgZ2V0SW5kZXggfSBmcm9tICcuLi8uLi8uLi91dGlscy9pbWFnZS51dGlsJztcbmltcG9ydCB7IEFjdGlvbiB9IGZyb20gJy4uLy4uLy4uL21vZGVsL2FjdGlvbi5lbnVtJztcbmltcG9ydCB7IENvbmZpZ1NlcnZpY2UgfSBmcm9tICcuLi8uLi8uLi9zZXJ2aWNlcy9jb25maWcuc2VydmljZSc7XG5pbXBvcnQgeyBMaWJDb25maWcgfSBmcm9tICcuLi8uLi8uLi9tb2RlbC9saWItY29uZmlnLmludGVyZmFjZSc7XG5cbi8qKlxuICogRGVmYXVsdCBtYXggaGVpZ2h0IG9mIHByZXZpZXdzLlxuICovXG5jb25zdCBERUZBVUxUX01BWF9IRUlHSFQgPSAnMjAwcHgnO1xuXG4vKipcbiAqIENvbXBvbmVudCB3aXRoIGltYWdlIHByZXZpZXdzIGZvciBjYXJvdXNlbFxuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdrcy1jYXJvdXNlbC1wcmV2aWV3cycsXG4gIHN0eWxlVXJsczogWydjYXJvdXNlbC1wcmV2aWV3cy5zY3NzJywgJy4uLy4uL3ByZXZpZXdzLWFycm93cy5zY3NzJ10sXG4gIHRlbXBsYXRlVXJsOiAnY2Fyb3VzZWwtcHJldmlld3MuaHRtbCcsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoXG59KVxuZXhwb3J0IGNsYXNzIENhcm91c2VsUHJldmlld3NDb21wb25lbnQgZXh0ZW5kcyBBY2Nlc3NpYmxlQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkNoYW5nZXMsIE9uRGVzdHJveSB7XG4gIC8qKlxuICAgKiBWYXJpYWJsZSB0byBjaGFuZ2UgdGhlIG1heC13aWR0aCBvZiB0aGUgaG9zdCBjb21wb25lbnRcbiAgICovXG4gIEBIb3N0QmluZGluZygnc3R5bGUubWF4LXdpZHRoJylcbiAgaG9zdE1heFdpZHRoID0gJzEwMCUnO1xuXG4gIC8qKlxuICAgKiBWYXJpYWJsZSB0byBzZXQgYXJpYS1sYWJlbCBvZiB0aGUgaG9zdCBjb21wb25lbnRcbiAgICovXG4gIEBIb3N0QmluZGluZygnYXR0ci5hcmlhLWxhYmVsJylcbiAgYXJpYUxhYmVsID0gYENhcm91c2VsIHByZXZpZXdzYDtcblxuICAvKipcbiAgICogVE9ETyB3cml0ZSBkb2NcbiAgICovXG4gIEBJbnB1dCgpXG4gIGlkITogbnVtYmVyO1xuICAvKipcbiAgICogT2JqZWN0IG9mIHR5cGUgYEludGVybmFsTGliSW1hZ2VgIHRoYXQgcmVwcmVzZW50IHRoZSB2aXNpYmxlIGltYWdlLlxuICAgKi9cbiAgQElucHV0KClcbiAgY3VycmVudEltYWdlITogSW50ZXJuYWxMaWJJbWFnZTtcbiAgLyoqXG4gICAqIEFycmF5IG9mIGBJbnRlcm5hbExpYkltYWdlYCB0aGF0IHJlcHJlc2VudCB0aGUgbW9kZWwgb2YgdGhpcyBsaWJyYXJ5IHdpdGggYWxsIGltYWdlcyxcbiAgICogdGh1bWJzIGFuZCBzbyBvbi5cbiAgICovXG4gIEBJbnB1dCgpXG4gIGltYWdlcyE6IEludGVybmFsTGliSW1hZ2VbXTtcblxuICAvKipcbiAgICogT3V0cHV0IHRvIGVtaXQgdGhlIGNsaWNrZWQgcHJldmlldy4gVGhlIHBheWxvYWQgY29udGFpbnMgdGhlIGBJbnRlcm5hbExpYkltYWdlYCBhc3NvY2lhdGVkIHRvIHRoZSBjbGlja2VkIHByZXZpZXcuXG4gICAqL1xuICBAT3V0cHV0KClcbiAgY2xpY2tQcmV2aWV3OiBFdmVudEVtaXR0ZXI8SW1hZ2VFdmVudD4gPSBuZXcgRXZlbnRFbWl0dGVyPEltYWdlRXZlbnQ+KCk7XG5cbiAgLyoqXG4gICAqIE9iamVjdCBvZiB0eXBlIGBDYXJvdXNlbENvbmZpZ2AgdG8gaW5pdCBDYXJvdXNlbENvbXBvbmVudCdzIGZlYXR1cmVzLlxuICAgKiBGb3IgaW5zdGFuY2UsIGl0IGNvbnRhaW5zIHBhcmFtZXRlcnMgdG8gY2hhbmdlIHRoZSBzdHlsZSwgaG93IGl0IG5hdmlnYXRlcyBhbmQgc28gb24uXG4gICAqL1xuICBjYXJvdXNlbENvbmZpZzogQ2Fyb3VzZWxDb25maWcgfCB1bmRlZmluZWQ7XG4gIC8qKlxuICAgKiBPYmplY3Qgb2YgdHlwZSBgQ2Fyb3VzZWxQcmV2aWV3Q29uZmlnYCB0byBpbml0IFByZXZpZXdzQ29tcG9uZW50J3MgZmVhdHVyZXMuXG4gICAqIEZvciBpbnN0YW5jZSwgaXQgY29udGFpbnMgYSBwYXJhbSB0byBzaG93L2hpZGUgdGhpcyBjb21wb25lbnQsIHNpemVzLlxuICAgKi9cbiAgcHJldmlld0NvbmZpZzogQ2Fyb3VzZWxQcmV2aWV3Q29uZmlnIHwgdW5kZWZpbmVkO1xuICAvKipcbiAgICogT2JqZWN0IG9mIHR5cGUgYEFjY2Vzc2liaWxpdHlDb25maWdgIHRvIGluaXQgY3VzdG9tIGFjY2Vzc2liaWxpdHkgZmVhdHVyZXMuXG4gICAqIEZvciBpbnN0YW5jZSwgaXQgY29udGFpbnMgdGl0bGVzLCBhbHQgdGV4dHMsIGFyaWEtbGFiZWxzIGFuZCBzbyBvbi5cbiAgICovXG4gIGFjY2Vzc2liaWxpdHlDb25maWc6IEFjY2Vzc2liaWxpdHlDb25maWcgfCB1bmRlZmluZWQ7XG4gIC8qKlxuICAgKiBFbnVtIG9mIHR5cGUgYEFjdGlvbmAgdGhhdCByZXByZXNlbnRzIGEgbW91c2UgY2xpY2sgb24gYSBidXR0b24uXG4gICAqIERlY2xhcmVkIGhlcmUgdG8gYmUgdXNlZCBpbnNpZGUgdGhlIHRlbXBsYXRlLlxuICAgKi9cbiAgY2xpY2tBY3Rpb246IEFjdGlvbiA9IEFjdGlvbi5DTElDSztcbiAgLyoqXG4gICAqIEVudW0gb2YgdHlwZSBgQWN0aW9uYCB0aGF0IHJlcHJlc2VudHMgYSBrZXlib2FyZCBhY3Rpb24uXG4gICAqIERlY2xhcmVkIGhlcmUgdG8gYmUgdXNlZCBpbnNpZGUgdGhlIHRlbXBsYXRlLlxuICAgKi9cbiAga2V5Ym9hcmRBY3Rpb246IEFjdGlvbiA9IEFjdGlvbi5LRVlCT0FSRDtcbiAgLyoqXG4gICAqIEFycmF5IG9mIGBJbnRlcm5hbExpYkltYWdlYCBleHBvc2VkIHRvIHRoZSB0ZW1wbGF0ZS4gVGhpcyBmaWVsZCBpcyBpbml0aWFsaXplZFxuICAgKiBhcHBseWluZyB0cmFuc2Zvcm1hdGlvbnMsIGRlZmF1bHQgdmFsdWVzIGFuZCBzbyBvbiB0byB0aGUgaW5wdXQgb2YgdGhlIHNhbWUgdHlwZS5cbiAgICovXG4gIHByZXZpZXdzOiBJbnRlcm5hbExpYkltYWdlW10gPSBbXTtcbiAgLyoqXG4gICAqIFZhcmlhYmxlIHdpdGggdGhlIHByZXZpZXcncyBtYXhIZWlnaHRcbiAgICovXG4gIHByZXZpZXdNYXhIZWlnaHQ6IHN0cmluZyA9IERFRkFVTFRfTUFYX0hFSUdIVDtcbiAgLyoqXG4gICAqIFN0YXJ0IGluZGV4IChpbmNsdXNpdmUpIG9mIHRoZSBpbnB1dCBpbWFnZXMgdXNlZCB0byBkaXNwbGF5IHByZXZpZXdzLlxuICAgKi9cbiAgLy8gQHRzLWlnbm9yZVxuICBzdGFydDogbnVtYmVyO1xuICAvKipcbiAgICogRW5kIGluZGV4IChub24gaW5jbHVzaXZlKSBvZiB0aGUgaW5wdXQgaW1hZ2VzIHVzZWQgdG8gZGlzcGxheSBwcmV2aWV3cy5cbiAgICovXG4gIC8vIEB0cy1pZ25vcmVcbiAgZW5kOiBudW1iZXI7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBicmVha3BvaW50U3Vic2NyaXB0aW9uOiBTdWJzY3JpcHRpb247XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWY6IENoYW5nZURldGVjdG9yUmVmLFxuICAgIHByaXZhdGUgYnJlYWtwb2ludE9ic2VydmVyOiBCcmVha3BvaW50T2JzZXJ2ZXIsXG4gICAgLy8gc2FuaXRpemVyIGlzIHVzZWQgb25seSB0byBzYW5pdGl6ZSBzdHlsZSBiZWZvcmUgYWRkIGl0IHRvIGJhY2tncm91bmQgcHJvcGVydHkgd2hlbiBsZWdhY3lJRTExTW9kZSBpcyBlbmFibGVkXG4gICAgcHJpdmF0ZSBzYW5pdGl6ZXI6IERvbVNhbml0aXplcixcbiAgICBwcml2YXRlIGNvbmZpZ1NlcnZpY2U6IENvbmZpZ1NlcnZpY2VcbiAgKSB7XG4gICAgc3VwZXIoKTtcblxuICAgIC8vIGxpc3RlbiBmb3Igd2lkdGggY2hhbmdlcyBhbmQgdXBkYXRlIHByZXZpZXcgaGVpZ2h0cyBhY2NvcmRpbmdseVxuICAgIHRoaXMuYnJlYWtwb2ludFN1YnNjcmlwdGlvbiA9IGJyZWFrcG9pbnRPYnNlcnZlclxuICAgICAgLm9ic2VydmUoW0JyZWFrcG9pbnRzLlhTbWFsbCwgQnJlYWtwb2ludHMuU21hbGwsIEJyZWFrcG9pbnRzLk1lZGl1bSwgQnJlYWtwb2ludHMuTGFyZ2UsIEJyZWFrcG9pbnRzLlhMYXJnZV0pXG4gICAgICAuc3Vic2NyaWJlKChyZXN1bHQ6IEJyZWFrcG9pbnRTdGF0ZSkgPT4ge1xuICAgICAgICBpZiAoIXRoaXMucHJldmlld0NvbmZpZyB8fCAhdGhpcy5wcmV2aWV3Q29uZmlnLmJyZWFrcG9pbnRzKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChyZXN1bHQuYnJlYWtwb2ludHNbQnJlYWtwb2ludHMuWFNtYWxsXSkge1xuICAgICAgICAgIHRoaXMudXBkYXRlSGVpZ2h0KHRoaXMucHJldmlld0NvbmZpZy5icmVha3BvaW50cy54U21hbGwpO1xuICAgICAgICB9IGVsc2UgaWYgKHJlc3VsdC5icmVha3BvaW50c1tCcmVha3BvaW50cy5TbWFsbF0pIHtcbiAgICAgICAgICB0aGlzLnVwZGF0ZUhlaWdodCh0aGlzLnByZXZpZXdDb25maWcuYnJlYWtwb2ludHMuc21hbGwpO1xuICAgICAgICB9IGVsc2UgaWYgKHJlc3VsdC5icmVha3BvaW50c1tCcmVha3BvaW50cy5NZWRpdW1dKSB7XG4gICAgICAgICAgdGhpcy51cGRhdGVIZWlnaHQodGhpcy5wcmV2aWV3Q29uZmlnLmJyZWFrcG9pbnRzLm1lZGl1bSk7XG4gICAgICAgIH0gZWxzZSBpZiAocmVzdWx0LmJyZWFrcG9pbnRzW0JyZWFrcG9pbnRzLkxhcmdlXSkge1xuICAgICAgICAgIHRoaXMudXBkYXRlSGVpZ2h0KHRoaXMucHJldmlld0NvbmZpZy5icmVha3BvaW50cy5sYXJnZSk7XG4gICAgICAgIH0gZWxzZSBpZiAocmVzdWx0LmJyZWFrcG9pbnRzW0JyZWFrcG9pbnRzLlhMYXJnZV0pIHtcbiAgICAgICAgICB0aGlzLnVwZGF0ZUhlaWdodCh0aGlzLnByZXZpZXdDb25maWcuYnJlYWtwb2ludHMueExhcmdlKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogTWV0aG9kIHRvIHVwZGF0ZSB0aGUgaGVpZ2h0IG9mIHByZXZpZXdzLCBwYXNzaW5nIHRoZSBkZXNpcmVkIGhlaWdodCBhcyBpbnB1dC5cbiAgICogQHBhcmFtIGNvbmZpZ0JyZWFrcG9pbnRIZWlnaHQgaXMgYSBudW1iZXIgdGhhdCByZXByZXNlbnQgdGhlIGRlc2lyZWQgaGVpZ2h0IHRvIHNldC5cbiAgICovXG4gIHByaXZhdGUgdXBkYXRlSGVpZ2h0KGNvbmZpZ0JyZWFrcG9pbnRIZWlnaHQ6IG51bWJlcik6IHZvaWQge1xuICAgIGlmICh0aGlzLnByZXZpZXdDb25maWcgJiYgdGhpcy5wcmV2aWV3Q29uZmlnLm1heEhlaWdodCkge1xuICAgICAgY29uc3QgaGVpZ2h0TnVtOiBudW1iZXIgPSArdGhpcy5wcmV2aWV3Q29uZmlnLm1heEhlaWdodC5yZXBsYWNlKCcvcHgvZycsICcnKS5yZXBsYWNlKCcvJS9nJywgJycpO1xuICAgICAgdGhpcy5wcmV2aWV3TWF4SGVpZ2h0ID0gTWF0aC5taW4oY29uZmlnQnJlYWtwb2ludEhlaWdodCwgaGVpZ2h0TnVtKSArICdweCc7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGhlaWdodE51bTogbnVtYmVyID0gK0RFRkFVTFRfTUFYX0hFSUdIVC5yZXBsYWNlKCcvcHgvZycsICcnKS5yZXBsYWNlKCcvJS9nJywgJycpO1xuICAgICAgdGhpcy5wcmV2aWV3TWF4SGVpZ2h0ID0gTWF0aC5taW4oY29uZmlnQnJlYWtwb2ludEhlaWdodCwgaGVpZ2h0TnVtKSArICdweCc7XG4gICAgfVxuICAgIHRoaXMucmVmLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgLyoqXG4gICAqIE1ldGhvZCDCtG5nT25Jbml0wrQgdG8gYnVpbGQgYGNvbmZpZ1ByZXZpZXdgIGFwcGx5aW5nIGEgZGVmYXVsdCB2YWx1ZSBhbmQgYWxzbyB0b1xuICAgKiBpbml0IHRoZSBgcHJldmlld3NgIGFycmF5LlxuICAgKiBUaGlzIGlzIGFuIGFuZ3VsYXIgbGlmZWN5Y2xlIGhvb2ssIHNvIGl0cyBjYWxsZWQgYXV0b21hdGljYWxseSBieSBBbmd1bGFyIGl0c2VsZi5cbiAgICogSW4gcGFydGljdWxhciwgaXQncyBjYWxsZWQgb25seSBvbmUgdGltZSEhIVxuICAgKi9cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgY29uc3QgbGliQ29uZmlnOiBMaWJDb25maWcgfCB1bmRlZmluZWQgPSB0aGlzLmNvbmZpZ1NlcnZpY2UuZ2V0Q29uZmlnKHRoaXMuaWQpO1xuICAgIGlmICghbGliQ29uZmlnKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludGVybmFsIGxpYnJhcnkgZXJyb3IgLSBsaWJDb25maWcgbXVzdCBiZSBkZWZpbmVkJyk7XG4gICAgfVxuICAgIHRoaXMuY2Fyb3VzZWxDb25maWcgPSBsaWJDb25maWcuY2Fyb3VzZWxDb25maWc7XG4gICAgdGhpcy5wcmV2aWV3Q29uZmlnID0gbGliQ29uZmlnLmNhcm91c2VsUHJldmlld3NDb25maWc7XG4gICAgdGhpcy5hY2Nlc3NpYmlsaXR5Q29uZmlnID0gbGliQ29uZmlnLmFjY2Vzc2liaWxpdHlDb25maWc7XG5cbiAgICBpZiAoIXRoaXMucHJldmlld0NvbmZpZyB8fCAhdGhpcy5wcmV2aWV3Q29uZmlnLm1heEhlaWdodCB8fCAhdGhpcy5wcmV2aWV3Q29uZmlnLmJyZWFrcG9pbnRzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludGVybmFsIGxpYnJhcnkgZXJyb3IgLSBwcmV2aWV3Q29uZmlnIG11c3QgYmUgZGVmaW5lZCcpO1xuICAgIH1cbiAgICAvLyBjaGFuZ2UgdGhlIG1heC13aWR0aCBvZiB0aGlzIGNvbXBvbmVudCBpZiB0aGVyZSBpcyBhIHNwZWNpZmllZCB3aWR0aCAhPT0gMTAwJSBpbiBjYXJvdXNlbENvbmZpZ1xuICAgIGlmICh0aGlzLmNhcm91c2VsQ29uZmlnICYmIHRoaXMuY2Fyb3VzZWxDb25maWcubWF4V2lkdGggIT09ICcxMDAlJykge1xuICAgICAgdGhpcy5ob3N0TWF4V2lkdGggPSB0aGlzLmNhcm91c2VsQ29uZmlnLm1heFdpZHRoO1xuICAgIH1cblxuICAgIHRoaXMucHJldmlld01heEhlaWdodCA9IHRoaXMucHJldmlld0NvbmZpZy5tYXhIZWlnaHQ7XG4gICAgLy8gaW5pdCBwcmV2aWV3cyBiYXNlZCBvbiBjdXJyZW50SW1hZ2UgYW5kIHRoZSBmdWxsIGFycmF5IG9mIGltYWdlc1xuICAgIHRoaXMuaW5pdFByZXZpZXdzKHRoaXMuY3VycmVudEltYWdlLCB0aGlzLmltYWdlcyk7XG5cbiAgICAvLyBhcHBseSBjdXN0b20gaGVpZ2h0IGJhc2VkIG9uIHJlc3BvbnNpdmUgYnJlYWtwb2ludHNcbiAgICAvLyBUaGlzIGlzIHJlcXVpcmVkLCBiZWNhdXNlIHRoZSBicmVha3BvaW50U3Vic2NyaXB0aW9uIGlzIG5vdCB0cmlnZ2VyZWQgYXQgY3JlYXRpb24sXG4gICAgLy8gYnV0IG9ubHkgd2hlbiB0aGUgd2lkdGggY2hhbmdlc1xuICAgIGNvbnN0IGlzWHNtYWxsU2NyZWVuID0gdGhpcy5icmVha3BvaW50T2JzZXJ2ZXIuaXNNYXRjaGVkKEJyZWFrcG9pbnRzLlhTbWFsbCk7XG4gICAgY29uc3QgaXNTbWFsbFNjcmVlbiA9IHRoaXMuYnJlYWtwb2ludE9ic2VydmVyLmlzTWF0Y2hlZChCcmVha3BvaW50cy5TbWFsbCk7XG4gICAgY29uc3QgaXNNZWRpdW1TY3JlZW4gPSB0aGlzLmJyZWFrcG9pbnRPYnNlcnZlci5pc01hdGNoZWQoQnJlYWtwb2ludHMuTWVkaXVtKTtcbiAgICBjb25zdCBpc0xhcmdlU2NyZWVuID0gdGhpcy5icmVha3BvaW50T2JzZXJ2ZXIuaXNNYXRjaGVkKEJyZWFrcG9pbnRzLkxhcmdlKTtcbiAgICBjb25zdCBpc3hMYXJnZVNjcmVlbiA9IHRoaXMuYnJlYWtwb2ludE9ic2VydmVyLmlzTWF0Y2hlZChCcmVha3BvaW50cy5YTGFyZ2UpO1xuICAgIGlmIChpc1hzbWFsbFNjcmVlbikge1xuICAgICAgdGhpcy51cGRhdGVIZWlnaHQodGhpcy5wcmV2aWV3Q29uZmlnLmJyZWFrcG9pbnRzLnhTbWFsbCk7XG4gICAgfSBlbHNlIGlmIChpc1NtYWxsU2NyZWVuKSB7XG4gICAgICB0aGlzLnVwZGF0ZUhlaWdodCh0aGlzLnByZXZpZXdDb25maWcuYnJlYWtwb2ludHMuc21hbGwpO1xuICAgIH0gZWxzZSBpZiAoaXNNZWRpdW1TY3JlZW4pIHtcbiAgICAgIHRoaXMudXBkYXRlSGVpZ2h0KHRoaXMucHJldmlld0NvbmZpZy5icmVha3BvaW50cy5tZWRpdW0pO1xuICAgIH0gZWxzZSBpZiAoaXNMYXJnZVNjcmVlbikge1xuICAgICAgdGhpcy51cGRhdGVIZWlnaHQodGhpcy5wcmV2aWV3Q29uZmlnLmJyZWFrcG9pbnRzLmxhcmdlKTtcbiAgICB9IGVsc2UgaWYgKGlzeExhcmdlU2NyZWVuKSB7XG4gICAgICB0aGlzLnVwZGF0ZUhlaWdodCh0aGlzLnByZXZpZXdDb25maWcuYnJlYWtwb2ludHMueExhcmdlKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogTWV0aG9kIHRvIGNoZWNrIGlmIGFuIGltYWdlIGlzIGFjdGl2ZSAoaS5lLiBhIHByZXZpZXcgaW1hZ2UpLlxuICAgKiBAcGFyYW0gSW50ZXJuYWxMaWJJbWFnZSBwcmV2aWV3IGlzIGFuIGltYWdlIHRvIGNoZWNrIGlmIGl0J3MgYWN0aXZlIG9yIG5vdFxuICAgKiBAcmV0dXJucyBib29sZWFuIHRydWUgaWYgaXMgYWN0aXZlLCBmYWxzZSBvdGhlcndpc2VcbiAgICovXG4gIGlzQWN0aXZlKHByZXZpZXc6IEludGVybmFsTGliSW1hZ2UpOiBib29sZWFuIHtcbiAgICBpZiAoIXByZXZpZXcgfHwgIXRoaXMuY3VycmVudEltYWdlKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiBwcmV2aWV3LmlkID09PSB0aGlzLmN1cnJlbnRJbWFnZS5pZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBNZXRob2QgwrRuZ09uQ2hhbmdlc8K0IHRvIHVwZGF0ZSBgcHJldmlld3NgIGFycmF5LlxuICAgKiBBbHNvLCBib3RoIGBzdGFydGAgYW5kIGBlbmRgIGxvY2FsIHZhcmlhYmxlcyB3aWxsIGJlIHVwZGF0ZWQgYWNjb3JkaW5nbHkuXG4gICAqIFRoaXMgaXMgYW4gYW5ndWxhciBsaWZlY3ljbGUgaG9vaywgc28gaXRzIGNhbGxlZCBhdXRvbWF0aWNhbGx5IGJ5IEFuZ3VsYXIgaXRzZWxmLlxuICAgKiBJbiBwYXJ0aWN1bGFyLCBpdCdzIGNhbGxlZCB3aGVuIGFueSBkYXRhLWJvdW5kIHByb3BlcnR5IG9mIGEgZGlyZWN0aXZlIGNoYW5nZXMhISFcbiAgICovXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICBjb25zdCBzaW1wbGVDaGFuZ2U6IFNpbXBsZUNoYW5nZSA9IGNoYW5nZXMuY3VycmVudEltYWdlO1xuICAgIGlmICghc2ltcGxlQ2hhbmdlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgcHJldjogSW50ZXJuYWxMaWJJbWFnZSA9IHNpbXBsZUNoYW5nZS5wcmV2aW91c1ZhbHVlO1xuICAgIGNvbnN0IGN1cnJlbnQ6IEludGVybmFsTGliSW1hZ2UgPSBzaW1wbGVDaGFuZ2UuY3VycmVudFZhbHVlO1xuXG4gICAgaWYgKGN1cnJlbnQgJiYgY2hhbmdlcy5pbWFnZXMgJiYgY2hhbmdlcy5pbWFnZXMucHJldmlvdXNWYWx1ZSAmJiBjaGFuZ2VzLmltYWdlcy5jdXJyZW50VmFsdWUpIHtcbiAgICAgIC8vIEknbSBpbiB0aGlzIGlmIHN0YXRlbWVudCwgaWYgaW5wdXQgaW1hZ2VzIGFyZSBjaGFuZ2VkIChmb3IgaW5zdGFuY2UsIGJlY2F1c2UgSSByZW1vdmVkIG9uZSBvZiB0aGVtIHdpdGggdGhlICdkZWxldGUgYnV0dG9uJyxcbiAgICAgIC8vIG9yIGJlY2F1c2UgdXNlcnMgY2hhbmdlZCB0aGUgaW1hZ2VzIGFycmF5IHdoaWxlIG1vZGFsIGdhbGxlcnkgaXMgc3RpbGwgb3BlbikuXG4gICAgICAvLyBJbiB0aGlzIGNhc2UsIEkgaGF2ZSB0byByZS1pbml0IHByZXZpZXdzLCBiZWNhdXNlIHRoZSBpbnB1dCBhcnJheSBvZiBpbWFnZXMgaXMgY2hhbmdlZC5cbiAgICAgIHRoaXMuaW5pdFByZXZpZXdzKGN1cnJlbnQsIGNoYW5nZXMuaW1hZ2VzLmN1cnJlbnRWYWx1ZSk7XG4gICAgfVxuXG4gICAgaWYgKHByZXYgJiYgY3VycmVudCAmJiBwcmV2LmlkICE9PSBjdXJyZW50LmlkKSB7XG4gICAgICAvLyB0byBtYW5hZ2UgaW5maW5pdGUgc2xpZGluZyBJIGhhdmUgdG8gcmVzZXQgYm90aCBgc3RhcnRgIGFuZCBgZW5kYCBhdCB0aGUgYmVnaW5uaW5nXG4gICAgICAvLyB0byBzaG93IGFnYWluIHByZXZpZXdzIGZyb20gdGhlIGZpcnN0IGltYWdlLlxuICAgICAgLy8gVGhpcyBoYXBwZW5zIHdoZW4geW91IG5hdmlnYXRlIG92ZXIgdGhlIGxhc3QgaW1hZ2UgdG8gcmV0dXJuIHRvIHRoZSBmaXJzdCBvbmVcbiAgICAgIGxldCBwcmV2SW5kZXg6IG51bWJlcjtcbiAgICAgIGxldCBjdXJyZW50SW5kZXg6IG51bWJlcjtcbiAgICAgIHRyeSB7XG4gICAgICAgIHByZXZJbmRleCA9IGdldEluZGV4KHByZXYsIHRoaXMuaW1hZ2VzKTtcbiAgICAgICAgY3VycmVudEluZGV4ID0gZ2V0SW5kZXgoY3VycmVudCwgdGhpcy5pbWFnZXMpO1xuICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Nhbm5vdCBnZXQgcHJldmlvdXMgYW5kIGN1cnJlbnQgaW1hZ2UgaW5kZXhlcyBpbiBwcmV2aWV3cycpO1xuICAgICAgICB0aHJvdyBlcnI7XG4gICAgICB9XG5cbiAgICAgIC8vIGFwcGx5IGEgZm9ybXVsYSB0byBnZXQgYSB2YWx1ZXMgdG8gYmUgdXNlZCB0byBkZWNpZGUgaWYgZ28gbmV4dCwgcmV0dXJuIGJhY2sgb3Igc3RheSB3aXRob3V0IGRvaW5nIGFueXRoaW5nXG4gICAgICBjb25zdCBjYWxjID0gTWF0aC5mbG9vcigodGhpcy5lbmQgLSB0aGlzLnN0YXJ0KSAvIDIpICsgdGhpcy5zdGFydDtcblxuICAgICAgaWYgKHByZXZJbmRleCA9PT0gdGhpcy5pbWFnZXMubGVuZ3RoIC0gMSAmJiBjdXJyZW50SW5kZXggPT09IDApIHtcbiAgICAgICAgLy8gZmlyc3QgaW1hZ2VcbiAgICAgICAgdGhpcy5zZXRCZWdpbm5pbmdJbmRleGVzUHJldmlld3MoKTtcbiAgICAgICAgdGhpcy5wcmV2aWV3cyA9IHRoaXMuaW1hZ2VzLmZpbHRlcigoaW1nOiBJbnRlcm5hbExpYkltYWdlLCBpOiBudW1iZXIpID0+IGkgPj0gdGhpcy5zdGFydCAmJiBpIDwgdGhpcy5lbmQpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICAvLyB0aGUgc2FtZSBmb3IgdGhlIG9wcG9zaXRlIGNhc2UsIHdoZW4geW91IG5hdmlnYXRlIGJhY2sgZnJvbSB0aGUgZmlzdCBpbWFnZSB0byBnbyB0byB0aGUgbGFzdCBvbmUuXG4gICAgICBpZiAocHJldkluZGV4ID09PSAwICYmIGN1cnJlbnRJbmRleCA9PT0gdGhpcy5pbWFnZXMubGVuZ3RoIC0gMSkge1xuICAgICAgICAvLyBsYXN0IGltYWdlXG4gICAgICAgIHRoaXMuc2V0RW5kSW5kZXhlc1ByZXZpZXdzKCk7XG4gICAgICAgIHRoaXMucHJldmlld3MgPSB0aGlzLmltYWdlcy5maWx0ZXIoKGltZzogSW50ZXJuYWxMaWJJbWFnZSwgaTogbnVtYmVyKSA9PiBpID49IHRoaXMuc3RhcnQgJiYgaSA8IHRoaXMuZW5kKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5wcmV2aWV3Q29uZmlnICYmICh0aGlzLnByZXZpZXdDb25maWcubnVtYmVyIGFzIG51bWJlcikgJSAyID09PSAwKSB7XG4gICAgICAgIGlmIChjYWxjID4gY3VycmVudEluZGV4KSB7XG4gICAgICAgICAgdGhpcy5wcmV2aW91cygpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMubmV4dCgpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoY2FsYyA+IGN1cnJlbnRJbmRleCkge1xuICAgICAgICAgIHRoaXMucHJldmlvdXMoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoY2FsYyA8IGN1cnJlbnRJbmRleCkge1xuICAgICAgICAgIHRoaXMubmV4dCgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIE1ldGhvZCBjYWxsZWQgYnkgZXZlbnRzIGZyb20gYm90aCBrZXlib2FyZCBhbmQgbW91c2Ugb24gYSBwcmV2aWV3LlxuICAgKiBUaGlzIHdpbGwgdHJpZ2dlciB0aGUgYGNsaWNrcHJldmlld2Agb3V0cHV0IHdpdGggdGhlIGlucHV0IHByZXZpZXcgYXMgaXRzIHBheWxvYWQuXG4gICAqIEBwYXJhbSBJbnRlcm5hbExpYkltYWdlIHByZXZpZXcgdGhhdCB0cmlnZ2VyZWQgdGhpcyBtZXRob2RcbiAgICogQHBhcmFtIEtleWJvYXJkRXZlbnQgfCBNb3VzZUV2ZW50IGV2ZW50IHBheWxvYWRcbiAgICogQHBhcmFtIEFjdGlvbiB0aGF0IHRyaWdnZXJlZCB0aGlzIGV2ZW50IChBY3Rpb24uTk9STUFMIGJ5IGRlZmF1bHQpXG4gICAqL1xuICBvbkltYWdlRXZlbnQocHJldmlldzogSW50ZXJuYWxMaWJJbWFnZSwgZXZlbnQ6IEtleWJvYXJkRXZlbnQgfCBNb3VzZUV2ZW50LCBhY3Rpb246IEFjdGlvbiA9IEFjdGlvbi5OT1JNQUwpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMucHJldmlld0NvbmZpZyB8fCAhdGhpcy5wcmV2aWV3Q29uZmlnLmNsaWNrYWJsZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBjbGlja2VkSW1hZ2VJbmRleDogbnVtYmVyID0gdGhpcy5pbWFnZXMuaW5kZXhPZihwcmV2aWV3KTtcbiAgICBjb25zdCByZXN1bHQ6IG51bWJlciA9IHN1cGVyLmhhbmRsZUltYWdlRXZlbnQoZXZlbnQpO1xuICAgIGlmIChyZXN1bHQgPT09IE5FWFQpIHtcbiAgICAgIHRoaXMuY2xpY2tQcmV2aWV3LmVtaXQoeyBhY3Rpb24sIHJlc3VsdDogY2xpY2tlZEltYWdlSW5kZXggfSBhcyBJbWFnZUV2ZW50KTtcbiAgICB9IGVsc2UgaWYgKHJlc3VsdCA9PT0gUFJFVikge1xuICAgICAgdGhpcy5jbGlja1ByZXZpZXcuZW1pdCh7IGFjdGlvbiwgcmVzdWx0OiBjbGlja2VkSW1hZ2VJbmRleCB9IGFzIEltYWdlRXZlbnQpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBNZXRob2QgY2FsbGVkIGJ5IGV2ZW50cyBmcm9tIGJvdGgga2V5Ym9hcmQgYW5kIG1vdXNlIG9uIGEgbmF2aWdhdGlvbiBhcnJvdy5cbiAgICogQHBhcmFtIHN0cmluZyBkaXJlY3Rpb24gb2YgdGhlIG5hdmlnYXRpb24gdGhhdCBjYW4gYmUgZWl0aGVyICduZXh0JyBvciAncHJldidcbiAgICogQHBhcmFtIEtleWJvYXJkRXZlbnQgfCBNb3VzZUV2ZW50IGV2ZW50IHBheWxvYWRcbiAgICovXG4gIG9uTmF2aWdhdGlvbkV2ZW50KGRpcmVjdGlvbjogc3RyaW5nLCBldmVudDogS2V5Ym9hcmRFdmVudCB8IE1vdXNlRXZlbnQpOiB2b2lkIHtcbiAgICBjb25zdCByZXN1bHQ6IG51bWJlciA9IHN1cGVyLmhhbmRsZU5hdmlnYXRpb25FdmVudChkaXJlY3Rpb24sIGV2ZW50KTtcbiAgICBpZiAocmVzdWx0ID09PSBORVhUKSB7XG4gICAgICB0aGlzLm5leHQoKTtcbiAgICB9IGVsc2UgaWYgKHJlc3VsdCA9PT0gUFJFVikge1xuICAgICAgdGhpcy5wcmV2aW91cygpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBNZXRob2QgdG8gZ2V0IGFyaWEtbGFiZWwgdGV4dCBmb3IgYSBwcmV2aWV3IGltYWdlLlxuICAgKiBAcGFyYW0gSW1hZ2UgaXMgdGhlIHByZXZpZXdcbiAgICovXG4gIGdldEFyaWFMYWJlbChwcmV2aWV3OiBJbWFnZSk6IHN0cmluZyB7XG4gICAgaWYgKCFwcmV2aWV3LnBsYWluKSB7XG4gICAgICByZXR1cm4gcHJldmlldy5tb2RhbC5hcmlhTGFiZWwgfHwgJyc7XG4gICAgfVxuICAgIHJldHVybiBwcmV2aWV3LnBsYWluLmFyaWFMYWJlbCB8fCBwcmV2aWV3Lm1vZGFsLmFyaWFMYWJlbCB8fCAnJztcbiAgfVxuXG4gIC8qKlxuICAgKiBNZXRob2QgdG8gZ2V0IHRpdGxlIHRleHQgZm9yIGEgcHJldmlldyBpbWFnZS5cbiAgICogQHBhcmFtIEltYWdlIGlzIHRoZSBwcmV2aWV3XG4gICAqL1xuICBnZXRUaXRsZShwcmV2aWV3OiBJbWFnZSk6IHN0cmluZyB7XG4gICAgaWYgKCFwcmV2aWV3LnBsYWluKSB7XG4gICAgICByZXR1cm4gcHJldmlldy5tb2RhbC50aXRsZSB8fCAnJztcbiAgICB9XG4gICAgcmV0dXJuIHByZXZpZXcucGxhaW4udGl0bGUgfHwgcHJldmlldy5tb2RhbC50aXRsZSB8fCAnJztcbiAgfVxuXG4gIC8qKlxuICAgKiBNZXRob2QgdG8gZ2V0IGFsdCB0ZXh0IGZvciBhIHByZXZpZXcgaW1hZ2UuXG4gICAqIEBwYXJhbSBJbWFnZSBpcyB0aGUgcHJldmlld1xuICAgKi9cbiAgZ2V0QWx0KHByZXZpZXc6IEltYWdlKTogc3RyaW5nIHtcbiAgICBpZiAoIXByZXZpZXcucGxhaW4pIHtcbiAgICAgIHJldHVybiBwcmV2aWV3Lm1vZGFsLmFsdCB8fCAnJztcbiAgICB9XG4gICAgcmV0dXJuIHByZXZpZXcucGxhaW4uYWx0IHx8IHByZXZpZXcubW9kYWwuYWx0IHx8ICcnO1xuICB9XG5cbiAgLyoqXG4gICAqIE1ldGhvZCB1c2VkIGluIHRoZSB0ZW1wbGF0ZSB0byB0cmFjayBpZHMgaW4gbmdGb3IuXG4gICAqIEBwYXJhbSBudW1iZXIgaW5kZXggb2YgdGhlIGFycmF5XG4gICAqIEBwYXJhbSBJbWFnZSBpdGVtIG9mIHRoZSBhcnJheVxuICAgKiBAcmV0dXJucyBudW1iZXIgdGhlIGlkIG9mIHRoZSBpdGVtXG4gICAqL1xuICB0cmFja0J5SWQoaW5kZXg6IG51bWJlciwgaXRlbTogSW1hZ2UpOiBudW1iZXIge1xuICAgIHJldHVybiBpdGVtLmlkO1xuICB9XG5cbiAgLyoqXG4gICAqIE1ldGhvZCB1c2VkIGluIHRlbXBsYXRlIHRvIHNhbml0aXplIGFuIHVybCB3aGVuIHlvdSBuZWVkIGxlZ2FjeUlFMTFNb2RlLlxuICAgKiBJbiB0aGlzIHdheSB5b3UgY2FuIHNldCBhbiB1cmwgYXMgYmFja2dyb3VuZCBvZiBhIGRpdi5cbiAgICogQHBhcmFtIHVuc2FmZVN0eWxlIGlzIGEgc3RyaW5nIG9yIGEgU2FmZVJlc291cmNlVXJsIHRoYXQgcmVwcmVzZW50cyB0aGUgdXJsIHRvIHNhbml0aXplLlxuICAgKiBAcGFyYW0gdW5zYWZlU3R5bGVGYWxsYmFjayBpcyBhIHN0cmluZyBvciBhIFNhZmVSZXNvdXJjZVVybCB0aGF0IHJlcHJlc2VudHMgdGhlIGZhbGxiYWNrIHVybCB0byBzYW5pdGl6ZS5cbiAgICogQHJldHVybnMgYSBTYWZlU3R5bGUgb2JqZWN0IHRoYXQgY2FuIGJlIHVzZWQgaW4gdGVtcGxhdGUgd2l0aG91dCBwcm9ibGVtcy5cbiAgICovXG4gIHNhbml0aXplVXJsQmdTdHlsZSh1bnNhZmVTdHlsZTogc3RyaW5nIHwgU2FmZVJlc291cmNlVXJsLCB1bnNhZmVTdHlsZUZhbGxiYWNrOiBzdHJpbmcgfCBTYWZlUmVzb3VyY2VVcmwpOiBTYWZlU3R5bGUge1xuICAgIC8vIE1ldGhvZCB1c2VkIG9ubHkgdG8gc2FuaXRpemUgYmFja2dyb3VuZC1pbWFnZSBzdHlsZSBiZWZvcmUgYWRkIGl0IHRvIGJhY2tncm91bmQgcHJvcGVydHkgd2hlbiBsZWdhY3lJRTExTW9kZSBpcyBlbmFibGVkXG4gICAgbGV0IGJnOiBzdHJpbmcgPSAndXJsKCcgKyB1bnNhZmVTdHlsZSArICcpJztcbiAgICBpZiAoISF1bnNhZmVTdHlsZUZhbGxiYWNrKSB7XG4gICAgICAvLyBpZiBhIGZhbGxiYWNrIGltYWdlIGlzIGRlZmluZWQsIGFwcGVuZCBpdC4gSW4gdGhpcyB3YXksIGl0IHdpbGwgYmUgdXNlZCBieSB0aGUgYnJvd3NlciBhcyBmYWxsYmFjay5cbiAgICAgIGJnICs9ICcsICcgKyAndXJsKCcgKyB1bnNhZmVTdHlsZUZhbGxiYWNrICsgJyknO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5zYW5pdGl6ZXIuYnlwYXNzU2VjdXJpdHlUcnVzdFN0eWxlKGJnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNZXRob2QgdG8gY2xlYW51cCByZXNvdXJjZXMuIEluIGZhY3QsIGl0IGNsZWFucyBicmVha3BvaW50U3Vic2NyaXB0aW9uLlxuICAgKiBUaGlzIGlzIGFuIGFuZ3VsYXIgbGlmZWN5Y2xlIGhvb2sgdGhhdCBpcyBjYWxsZWQgd2hlbiB0aGlzIGNvbXBvbmVudCBpcyBkZXN0cm95ZWQuXG4gICAqL1xuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5icmVha3BvaW50U3Vic2NyaXB0aW9uKSB7XG4gICAgICB0aGlzLmJyZWFrcG9pbnRTdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUHJpdmF0ZSBtZXRob2QgdG8gaW5pdCBwcmV2aWV3cyBiYXNlZCBvbiB0aGUgY3VycmVudEltYWdlIGFuZCB0aGUgZnVsbCBhcnJheSBvZiBpbWFnZXMuXG4gICAqIFRoZSBjdXJyZW50IGltYWdlIGluIG1hbmRhdG9yeSB0byBzaG93IGFsd2F5cyB0aGUgY3VycmVudCBwcmV2aWV3IChhcyBoaWdobGlnaHRlZCkuXG4gICAqIEBwYXJhbSBJbnRlcm5hbExpYkltYWdlIGN1cnJlbnRJbWFnZSB0byBkZWNpZGUgaG93IHRvIHNob3cgcHJldmlld3MsIGJlY2F1c2UgSSBhbHdheXMgd2FudCB0byBzZWUgdGhlIGN1cnJlbnQgaW1hZ2UgYXMgaGlnaGxpZ2h0ZWRcbiAgICogQHBhcmFtIEludGVybmFsTGliSW1hZ2VbXSBpbWFnZXMgaXMgdGhlIGFycmF5IG9mIGFsbCBpbWFnZXMuXG4gICAqL1xuICBwcml2YXRlIGluaXRQcmV2aWV3cyhjdXJyZW50SW1hZ2U6IEludGVybmFsTGliSW1hZ2UsIGltYWdlczogSW50ZXJuYWxMaWJJbWFnZVtdKTogdm9pZCB7XG4gICAgbGV0IGluZGV4OiBudW1iZXI7XG4gICAgdHJ5IHtcbiAgICAgIGluZGV4ID0gZ2V0SW5kZXgoY3VycmVudEltYWdlLCBpbWFnZXMpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgdGhyb3cgZXJyO1xuICAgIH1cbiAgICBzd2l0Y2ggKGluZGV4KSB7XG4gICAgICBjYXNlIDA6XG4gICAgICAgIC8vIGZpcnN0IGltYWdlXG4gICAgICAgIHRoaXMuc2V0QmVnaW5uaW5nSW5kZXhlc1ByZXZpZXdzKCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBpbWFnZXMubGVuZ3RoIC0gMTpcbiAgICAgICAgLy8gbGFzdCBpbWFnZVxuICAgICAgICB0aGlzLnNldEVuZEluZGV4ZXNQcmV2aWV3cygpO1xuICAgICAgICBicmVhaztcbiAgICAgIC8vIGRlZmF1bHQ6XG4gICAgICAvLyAgIC8vIG90aGVyIGltYWdlc1xuICAgICAgLy8gICAvLyBUT0RPIHVudXNlZCBiZWNhdXNlIGl0IHN0YXJ0cyBhbHdheXMgYXQgaW1hZ2UgMFxuICAgICAgLy8gICB0aGlzLnNldEluZGV4ZXNQcmV2aWV3cygpO1xuICAgICAgLy8gICBicmVhaztcbiAgICB9XG4gICAgdGhpcy5wcmV2aWV3cyA9IGltYWdlcy5maWx0ZXIoKGltZzogSW50ZXJuYWxMaWJJbWFnZSwgaTogbnVtYmVyKSA9PiBpID49IHRoaXMuc3RhcnQgJiYgaSA8IHRoaXMuZW5kKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQcml2YXRlIG1ldGhvZCB0byBpbml0IGJvdGggYHN0YXJ0YCBhbmQgYGVuZGAgdG8gdGhlIGJlZ2lubmluZy5cbiAgICovXG4gIHByaXZhdGUgc2V0QmVnaW5uaW5nSW5kZXhlc1ByZXZpZXdzKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5wcmV2aWV3Q29uZmlnIHx8IHRoaXMucHJldmlld0NvbmZpZy5udW1iZXIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnRlcm5hbCBsaWJyYXJ5IGVycm9yIC0gcHJldmlld0NvbmZpZyBhbmQgbnVtYmVyIG11c3QgYmUgZGVmaW5lZCcpO1xuICAgIH1cblxuICAgIHRoaXMuc3RhcnQgPSAwO1xuICAgIHRoaXMuZW5kID0gTWF0aC5taW4odGhpcy5wcmV2aWV3Q29uZmlnLm51bWJlciBhcyBudW1iZXIsIHRoaXMuaW1hZ2VzLmxlbmd0aCk7XG4gIH1cblxuICAvKipcbiAgICogUHJpdmF0ZSBtZXRob2QgdG8gaW5pdCBib3RoIGBzdGFydGAgYW5kIGBlbmRgIHRvIHRoZSBlbmQuXG4gICAqL1xuICBwcml2YXRlIHNldEVuZEluZGV4ZXNQcmV2aWV3cygpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMucHJldmlld0NvbmZpZyB8fCB0aGlzLnByZXZpZXdDb25maWcubnVtYmVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW50ZXJuYWwgbGlicmFyeSBlcnJvciAtIHByZXZpZXdDb25maWcgYW5kIG51bWJlciBtdXN0IGJlIGRlZmluZWQnKTtcbiAgICB9XG5cbiAgICB0aGlzLnN0YXJ0ID0gdGhpcy5pbWFnZXMubGVuZ3RoIC0gMSAtICgodGhpcy5wcmV2aWV3Q29uZmlnLm51bWJlciBhcyBudW1iZXIpIC0gMSk7XG4gICAgdGhpcy5lbmQgPSB0aGlzLmltYWdlcy5sZW5ndGg7XG4gIH1cblxuICAvKipcbiAgICogUHJpdmF0ZSBtZXRob2QgdG8gdXBkYXRlIHRoZSB2aXNpYmxlIHByZXZpZXdzIG5hdmlnYXRpbmcgdG8gdGhlIHJpZ2h0IChuZXh0KS5cbiAgICovXG4gIHByaXZhdGUgbmV4dCgpOiB2b2lkIHtcbiAgICAvLyBjaGVjayBpZiBuZXh0SW1hZ2Ugc2hvdWxkIGJlIGJsb2NrZWRcbiAgICBpZiAodGhpcy5pc1ByZXZlbnRTbGlkaW5nKHRoaXMuaW1hZ2VzLmxlbmd0aCAtIDEpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuZW5kID09PSB0aGlzLmltYWdlcy5sZW5ndGgpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLnN0YXJ0Kys7XG4gICAgdGhpcy5lbmQgPSBNYXRoLm1pbih0aGlzLmVuZCArIDEsIHRoaXMuaW1hZ2VzLmxlbmd0aCk7XG5cbiAgICB0aGlzLnByZXZpZXdzID0gdGhpcy5pbWFnZXMuZmlsdGVyKChpbWc6IEludGVybmFsTGliSW1hZ2UsIGk6IG51bWJlcikgPT4gaSA+PSB0aGlzLnN0YXJ0ICYmIGkgPCB0aGlzLmVuZCk7XG4gIH1cblxuICAvKipcbiAgICogUHJpdmF0ZSBtZXRob2QgdG8gdXBkYXRlIHRoZSB2aXNpYmxlIHByZXZpZXdzIG5hdmlnYXRpbmcgdG8gdGhlIGxlZnQgKHByZXZpb3VzKS5cbiAgICovXG4gIHByaXZhdGUgcHJldmlvdXMoKTogdm9pZCB7XG4gICAgLy8gY2hlY2sgaWYgcHJldkltYWdlIHNob3VsZCBiZSBibG9ja2VkXG4gICAgaWYgKHRoaXMuaXNQcmV2ZW50U2xpZGluZygwKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnN0YXJ0ID09PSAwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5zdGFydCA9IE1hdGgubWF4KHRoaXMuc3RhcnQgLSAxLCAwKTtcbiAgICB0aGlzLmVuZCA9IE1hdGgubWluKHRoaXMuZW5kIC0gMSwgdGhpcy5pbWFnZXMubGVuZ3RoKTtcblxuICAgIHRoaXMucHJldmlld3MgPSB0aGlzLmltYWdlcy5maWx0ZXIoKGltZzogSW50ZXJuYWxMaWJJbWFnZSwgaTogbnVtYmVyKSA9PiBpID49IHRoaXMuc3RhcnQgJiYgaSA8IHRoaXMuZW5kKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQcml2YXRlIG1ldGhvZCB0byBibG9jay9wZXJtaXQgc2xpZGluZyBiZXR3ZWVuIHByZXZpZXdzLlxuICAgKiBAcGFyYW0gbnVtYmVyIGJvdW5kYXJ5SW5kZXggaXMgdGhlIGZpcnN0IG9yIHRoZSBsYXN0IGluZGV4IG9mIGBpbWFnZXNgIGlucHV0IGFycmF5XG4gICAqIEByZXR1cm5zIGJvb2xlYW4gaWYgdHJ1ZSBibG9jayBzbGlkaW5nLCBvdGhlcndpc2Ugbm90XG4gICAqL1xuICBwcml2YXRlIGlzUHJldmVudFNsaWRpbmcoYm91bmRhcnlJbmRleDogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGdldEluZGV4KHRoaXMuY3VycmVudEltYWdlLCB0aGlzLmltYWdlcykgPT09IGJvdW5kYXJ5SW5kZXg7XG4gIH1cbn1cbiIsIjxuYXYgKm5nSWY9XCJwcmV2aWV3Q29uZmlnPy52aXNpYmxlXCJcbiAgICAgY2xhc3M9XCJwcmV2aWV3cy1jb250YWluZXJcIlxuICAgICBbYXR0ci5hcmlhLWxhYmVsXT1cImFjY2Vzc2liaWxpdHlDb25maWc/LmNhcm91c2VsUHJldmlld3NDb250YWluZXJBcmlhTGFiZWxcIlxuICAgICBbdGl0bGVdPVwiYWNjZXNzaWJpbGl0eUNvbmZpZz8uY2Fyb3VzZWxQcmV2aWV3c0NvbnRhaW5lclRpdGxlXCI+XG5cbiAgPGEgY2xhc3M9XCJuYXYtbGVmdFwiXG4gICAgIFthdHRyLmFyaWEtbGFiZWxdPVwiYWNjZXNzaWJpbGl0eUNvbmZpZz8uY2Fyb3VzZWxQcmV2aWV3U2Nyb2xsUHJldkFyaWFMYWJlbFwiXG4gICAgIFt0YWJJbmRleF09XCJwcmV2aWV3Q29uZmlnPy5hcnJvd3MgJiYgc3RhcnQgPiAwID8gMCA6IC0xXCIgcm9sZT1cImJ1dHRvblwiXG4gICAgIChjbGljayk9XCJvbk5hdmlnYXRpb25FdmVudCgnbGVmdCcsICRldmVudClcIiAoa2V5dXApPVwib25OYXZpZ2F0aW9uRXZlbnQoJ2xlZnQnLCAkZXZlbnQpXCI+XG4gICAgPGRpdiBjbGFzcz1cImluc2lkZSB7e3ByZXZpZXdDb25maWc/LmFycm93cyAmJiBzdGFydCA+IDAgPyAnbGVmdC1hcnJvdy1wcmV2aWV3LWltYWdlJyA6ICdlbXB0eS1hcnJvdy1wcmV2aWV3LWltYWdlJ319XCJcbiAgICAgICAgIGFyaWEtaGlkZGVuPVwidHJ1ZVwiXG4gICAgICAgICBbdGl0bGVdPVwiYWNjZXNzaWJpbGl0eUNvbmZpZz8uY2Fyb3VzZWxQcmV2aWV3U2Nyb2xsUHJldlRpdGxlXCI+PC9kaXY+XG4gIDwvYT5cblxuICA8ZGl2IGNsYXNzPVwicHJldmlldy1pbm5lci1jb250YWluZXJcIj5cbiAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBwcmV2aWV3IG9mIHByZXZpZXdzOyB0cmFja0J5OiB0cmFja0J5SWQ7IGxldCBpbmRleCA9IGluZGV4XCI+XG4gICAgICA8aW1nICpuZ0lmPVwicHJldmlldz8ubW9kYWw/LmltZ1wiXG4gICAgICAgICAgIFtsb2FkaW5nXT1cInByZXZpZXcubG9hZGluZ1wiXG4gICAgICAgICAgIFthdHRyLmZldGNocHJpb3JpdHldPVwicHJldmlldy5mZXRjaHByaW9yaXR5XCJcbiAgICAgICAgICAgY2xhc3M9XCJpbnNpZGUgcHJldmlldy1pbWFnZXt7aXNBY3RpdmUocHJldmlldykgPyAnIGFjdGl2ZScgOiAnJ319e3shcHJldmlld0NvbmZpZz8uY2xpY2thYmxlID8gJyB1bmNsaWNrYWJsZScgOiAnJ319XCJcbiAgICAgICAgICAgW3NyY109XCJwcmV2aWV3LnBsYWluPy5pbWcgPyBwcmV2aWV3LnBsYWluPy5pbWcgOiBwcmV2aWV3Lm1vZGFsLmltZ1wiXG4gICAgICAgICAgIGtzRmFsbGJhY2tJbWFnZSBbZmFsbGJhY2tJbWddPVwicHJldmlldy5wbGFpbj8uZmFsbGJhY2tJbWcgPyBwcmV2aWV3LnBsYWluPy5mYWxsYmFja0ltZyA6IHByZXZpZXcubW9kYWwuZmFsbGJhY2tJbWdcIlxuICAgICAgICAgICBrc1NpemUgW3NpemVDb25maWddPVwie3dpZHRoOiBwcmV2aWV3Q29uZmlnPy53aWR0aCEsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IHByZXZpZXdNYXhIZWlnaHR9XCJcbiAgICAgICAgICAgW2F0dHIuYXJpYS1sYWJlbF09XCJnZXRBcmlhTGFiZWwocHJldmlldylcIlxuICAgICAgICAgICBbdGl0bGVdPVwiZ2V0VGl0bGUocHJldmlldylcIlxuICAgICAgICAgICBhbHQ9XCJ7e2dldEFsdChwcmV2aWV3KX19XCJcbiAgICAgICAgICAgW3RhYkluZGV4XT1cIjBcIiByb2xlPVwiaW1nXCJcbiAgICAgICAgICAgKGNsaWNrKT1cIm9uSW1hZ2VFdmVudChwcmV2aWV3LCAkZXZlbnQsIGNsaWNrQWN0aW9uKVwiIChrZXl1cCk9XCJvbkltYWdlRXZlbnQocHJldmlldywgJGV2ZW50LCBrZXlib2FyZEFjdGlvbilcIi8+XG4gICAgPC9uZy1jb250YWluZXI+XG4gIDwvZGl2PlxuXG4gIDxhIGNsYXNzPVwibmF2LXJpZ2h0XCJcbiAgICAgW2F0dHIuYXJpYS1sYWJlbF09XCJhY2Nlc3NpYmlsaXR5Q29uZmlnPy5jYXJvdXNlbFByZXZpZXdTY3JvbGxOZXh0QXJpYUxhYmVsXCJcbiAgICAgW3RhYkluZGV4XT1cInByZXZpZXdDb25maWc/LmFycm93cyAmJiBlbmQgPCBpbWFnZXMubGVuZ3RoID8gMCA6IC0xXCIgcm9sZT1cImJ1dHRvblwiXG4gICAgIChjbGljayk9XCJvbk5hdmlnYXRpb25FdmVudCgncmlnaHQnLCAkZXZlbnQpXCIgKGtleXVwKT1cIm9uTmF2aWdhdGlvbkV2ZW50KCdyaWdodCcsICRldmVudClcIj5cbiAgICA8ZGl2IGNsYXNzPVwiaW5zaWRlIHt7cHJldmlld0NvbmZpZz8uYXJyb3dzICYmIGVuZCA8IGltYWdlcy5sZW5ndGggPyAncmlnaHQtYXJyb3ctcHJldmlldy1pbWFnZScgOiAnZW1wdHktYXJyb3ctcHJldmlldy1pbWFnZSd9fVwiXG4gICAgICAgICBhcmlhLWhpZGRlbj1cInRydWVcIlxuICAgICAgICAgW3RpdGxlXT1cImFjY2Vzc2liaWxpdHlDb25maWc/LmNhcm91c2VsUHJldmlld1Njcm9sbE5leHRUaXRsZVwiPjwvZGl2PlxuICA8L2E+XG5cbjwvbmF2PlxuIl19