@ks89/angular-modal-gallery 10.0.1 → 11.0.0-rc.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 (123) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/CONTRIBUTING.md +3 -3
  3. package/LICENSE +1 -1
  4. package/README.md +11 -14
  5. package/esm2022/lib/components/accessible.component.mjs +131 -0
  6. package/esm2022/lib/components/carousel/carousel-previews/carousel-previews.component.mjs +457 -0
  7. package/esm2022/lib/components/carousel/carousel.component.mjs +739 -0
  8. package/{esm2020 → esm2022}/lib/components/components.mjs +2 -2
  9. package/esm2022/lib/components/current-image/current-image.component.mjs +608 -0
  10. package/esm2022/lib/components/current-image/loading-spinner/loading-spinner.component.mjs +81 -0
  11. package/esm2022/lib/components/dots/dots.component.mjs +125 -0
  12. package/{esm2020 → esm2022}/lib/components/modal-gallery/modal-gallery-ref.mjs +2 -2
  13. package/esm2022/lib/components/modal-gallery/modal-gallery.component.mjs +500 -0
  14. package/esm2022/lib/components/modal-gallery/modal-gallery.service.mjs +188 -0
  15. package/{esm2020 → esm2022}/lib/components/modal-gallery/modal-gallery.tokens.mjs +2 -2
  16. package/esm2022/lib/components/plain-gallery/plain-gallery.component.mjs +250 -0
  17. package/esm2022/lib/components/previews/previews.component.mjs +264 -0
  18. package/esm2022/lib/components/upper-buttons/upper-buttons.component.mjs +244 -0
  19. package/esm2022/lib/directives/a-tag-bg-image.directive.mjs +79 -0
  20. package/esm2022/lib/directives/click-outside.directive.mjs +92 -0
  21. package/esm2022/lib/directives/description.directive.mjs +99 -0
  22. package/esm2022/lib/directives/direction.directive.mjs +74 -0
  23. package/esm2022/lib/directives/directives.mjs +51 -0
  24. package/esm2022/lib/directives/fallback-image.directive.mjs +60 -0
  25. package/esm2022/lib/directives/keyboard-navigation.directive.mjs +59 -0
  26. package/esm2022/lib/directives/margin.directive.mjs +85 -0
  27. package/esm2022/lib/directives/max-size.directive.mjs +76 -0
  28. package/esm2022/lib/directives/size.directive.mjs +77 -0
  29. package/esm2022/lib/directives/swipe.directive.mjs +115 -0
  30. package/esm2022/lib/directives/wrap.directive.mjs +75 -0
  31. package/esm2022/lib/modal-gallery.module.mjs +69 -0
  32. package/{esm2020 → esm2022}/lib/model/accessibility.interface.mjs +2 -2
  33. package/{esm2020 → esm2022}/lib/model/action.enum.mjs +2 -2
  34. package/{esm2020 → esm2022}/lib/model/buttons-config.interface.mjs +2 -2
  35. package/{esm2020 → esm2022}/lib/model/carousel-config.interface.mjs +2 -2
  36. package/{esm2020 → esm2022}/lib/model/carousel-image-config.interface.mjs +2 -2
  37. package/{esm2020 → esm2022}/lib/model/carousel-preview-config.interface.mjs +2 -2
  38. package/{esm2020 → esm2022}/lib/model/current-image-config.interface.mjs +2 -2
  39. package/{esm2020 → esm2022}/lib/model/description.interface.mjs +2 -2
  40. package/{esm2020 → esm2022}/lib/model/dots-config.interface.mjs +2 -2
  41. package/{esm2020 → esm2022}/lib/model/image-internal.class.mjs +2 -2
  42. package/{esm2020 → esm2022}/lib/model/image.class.mjs +2 -2
  43. package/{esm2020 → esm2022}/lib/model/keyboard-config.interface.mjs +2 -2
  44. package/{esm2020 → esm2022}/lib/model/keyboard.enum.mjs +2 -2
  45. package/{esm2020 → esm2022}/lib/model/lib-config.interface.mjs +2 -2
  46. package/{esm2020 → esm2022}/lib/model/loading-config.interface.mjs +2 -2
  47. package/{esm2020 → esm2022}/lib/model/max-size.interface.mjs +2 -2
  48. package/{esm2020 → esm2022}/lib/model/modal-gallery-config.interface.mjs +2 -2
  49. package/{esm2020 → esm2022}/lib/model/plain-gallery-config.interface.mjs +2 -2
  50. package/{esm2020 → esm2022}/lib/model/play-config.interface.mjs +2 -2
  51. package/{esm2020 → esm2022}/lib/model/preview-config.interface.mjs +2 -2
  52. package/{esm2020 → esm2022}/lib/model/size.interface.mjs +2 -2
  53. package/{esm2020 → esm2022}/lib/model/slide-config.interface.mjs +2 -2
  54. package/esm2022/lib/services/config.service.mjs +389 -0
  55. package/esm2022/lib/services/id-validator.service.mjs +72 -0
  56. package/{esm2020 → esm2022}/lib/utils/image.util.mjs +4 -4
  57. package/{esm2020 → esm2022}/lib/utils/user-input.util.mjs +2 -2
  58. package/{esm2020 → esm2022}/public-api.mjs +2 -2
  59. package/{fesm2020 → fesm2022}/ks89-angular-modal-gallery.mjs +382 -471
  60. package/fesm2022/ks89-angular-modal-gallery.mjs.map +1 -0
  61. package/lib/components/carousel/carousel-previews/carousel-previews.component.d.ts +4 -4
  62. package/lib/components/carousel/carousel.component.d.ts +5 -8
  63. package/lib/components/current-image/current-image.component.d.ts +6 -10
  64. package/lib/components/current-image/loading-spinner/loading-spinner.component.d.ts +3 -3
  65. package/lib/components/dots/dots.component.d.ts +5 -5
  66. package/lib/components/modal-gallery/modal-gallery.component.d.ts +11 -17
  67. package/lib/components/plain-gallery/plain-gallery.component.d.ts +3 -3
  68. package/lib/components/previews/previews.component.d.ts +6 -6
  69. package/lib/components/upper-buttons/upper-buttons.component.d.ts +4 -4
  70. package/lib/directives/a-tag-bg-image.directive.d.ts +3 -3
  71. package/lib/directives/click-outside.directive.d.ts +2 -2
  72. package/lib/directives/description.directive.d.ts +3 -3
  73. package/lib/directives/direction.directive.d.ts +3 -3
  74. package/lib/directives/directives.d.ts +2 -1
  75. package/lib/directives/fallback-image.directive.d.ts +1 -1
  76. package/lib/directives/keyboard-navigation.directive.d.ts +1 -1
  77. package/lib/directives/margin.directive.d.ts +3 -3
  78. package/lib/directives/max-size.directive.d.ts +3 -3
  79. package/lib/directives/size.directive.d.ts +1 -1
  80. package/lib/directives/swipe.directive.d.ts +33 -0
  81. package/lib/directives/wrap.directive.d.ts +3 -3
  82. package/lib/modal-gallery.module.d.ts +4 -10
  83. package/lib/model/keyboard.enum.d.ts +1 -1
  84. package/lib/model/lib-config.interface.d.ts +2 -6
  85. package/lib/services/config.service.d.ts +0 -2
  86. package/lib/utils/image.util.d.ts +2 -2
  87. package/package.json +10 -18
  88. package/esm2020/lib/components/accessible.component.mjs +0 -130
  89. package/esm2020/lib/components/carousel/carousel-previews/carousel-previews.component.mjs +0 -462
  90. package/esm2020/lib/components/carousel/carousel.component.mjs +0 -747
  91. package/esm2020/lib/components/current-image/current-image.component.mjs +0 -616
  92. package/esm2020/lib/components/current-image/loading-spinner/loading-spinner.component.mjs +0 -80
  93. package/esm2020/lib/components/dots/dots.component.mjs +0 -127
  94. package/esm2020/lib/components/modal-gallery/modal-gallery.component.mjs +0 -524
  95. package/esm2020/lib/components/modal-gallery/modal-gallery.service.mjs +0 -187
  96. package/esm2020/lib/components/plain-gallery/plain-gallery.component.mjs +0 -249
  97. package/esm2020/lib/components/previews/previews.component.mjs +0 -272
  98. package/esm2020/lib/components/upper-buttons/upper-buttons.component.mjs +0 -249
  99. package/esm2020/lib/directives/a-tag-bg-image.directive.mjs +0 -78
  100. package/esm2020/lib/directives/click-outside.directive.mjs +0 -91
  101. package/esm2020/lib/directives/description.directive.mjs +0 -98
  102. package/esm2020/lib/directives/direction.directive.mjs +0 -73
  103. package/esm2020/lib/directives/directives.mjs +0 -49
  104. package/esm2020/lib/directives/fallback-image.directive.mjs +0 -59
  105. package/esm2020/lib/directives/keyboard-navigation.directive.mjs +0 -58
  106. package/esm2020/lib/directives/margin.directive.mjs +0 -84
  107. package/esm2020/lib/directives/max-size.directive.mjs +0 -75
  108. package/esm2020/lib/directives/size.directive.mjs +0 -76
  109. package/esm2020/lib/directives/wrap.directive.mjs +0 -74
  110. package/esm2020/lib/modal-gallery.module.mjs +0 -94
  111. package/esm2020/lib/model/keyboard-service-config.interface.mjs +0 -25
  112. package/esm2020/lib/services/config.service.mjs +0 -396
  113. package/esm2020/lib/services/id-validator.service.mjs +0 -71
  114. package/esm2020/lib/services/keyboard.service.mjs +0 -111
  115. package/fesm2015/ks89-angular-modal-gallery.mjs +0 -5728
  116. package/fesm2015/ks89-angular-modal-gallery.mjs.map +0 -1
  117. package/fesm2020/ks89-angular-modal-gallery.mjs.map +0 -1
  118. package/lib/model/keyboard-service-config.interface.d.ts +0 -8
  119. package/lib/services/keyboard.service.d.ts +0 -26
  120. /package/{esm2020 → esm2022}/ks89-angular-modal-gallery.mjs +0 -0
  121. /package/{esm2020 → esm2022}/lib/components/accessibility-default.mjs +0 -0
  122. /package/{esm2020 → esm2022}/lib/components/upper-buttons/upper-buttons-default.mjs +0 -0
  123. /package/{esm2020 → esm2022}/lib/model/interaction-event.interface.mjs +0 -0
@@ -0,0 +1,457 @@
1
+ /*
2
+ The MIT License (MIT)
3
+
4
+ Copyright (C) 2017-2021 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
+ 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: "16.0.0", 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: "16.0.0", 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 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:black;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
+ export { CarouselPreviewsComponent };
439
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.0", ngImport: i0, type: CarouselPreviewsComponent, decorators: [{
440
+ type: Component,
441
+ 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 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:black;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"] }]
442
+ }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i1.BreakpointObserver }, { type: i2.DomSanitizer }, { type: i3.ConfigService }]; }, propDecorators: { hostMaxWidth: [{
443
+ type: HostBinding,
444
+ args: ['style.max-width']
445
+ }], ariaLabel: [{
446
+ type: HostBinding,
447
+ args: ['attr.aria-label']
448
+ }], id: [{
449
+ type: Input
450
+ }], currentImage: [{
451
+ type: Input
452
+ }], images: [{
453
+ type: Input
454
+ }], clickPreview: [{
455
+ type: Output
456
+ }] } });
457
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2Fyb3VzZWwtcHJldmlld3MuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMva3M4OS9hbmd1bGFyLW1vZGFsLWdhbGxlcnkvc3JjL2xpYi9jb21wb25lbnRzL2Nhcm91c2VsL2Nhcm91c2VsLXByZXZpZXdzL2Nhcm91c2VsLXByZXZpZXdzLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2tzODkvYW5ndWxhci1tb2RhbC1nYWxsZXJ5L3NyYy9saWIvY29tcG9uZW50cy9jYXJvdXNlbC9jYXJvdXNlbC1wcmV2aWV3cy9jYXJvdXNlbC1wcmV2aWV3cy5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBc0JHO0FBRUgsT0FBTyxFQUNMLHVCQUF1QixFQUV2QixTQUFTLEVBQ1QsWUFBWSxFQUNaLFdBQVcsRUFDWCxLQUFLLEVBSUwsTUFBTSxFQUdQLE1BQU0sZUFBZSxDQUFDO0FBRXZCLE9BQU8sRUFBc0IsV0FBVyxFQUFtQixNQUFNLHFCQUFxQixDQUFDO0FBSXZGLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBUWpFLE9BQU8sRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDNUQsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQ3JELE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQzs7Ozs7Ozs7QUFJcEQ7O0dBRUc7QUFDSCxNQUFNLGtCQUFrQixHQUFHLE9BQU8sQ0FBQztBQUVuQzs7R0FFRztBQUNILE1BTWEseUJBQTBCLFNBQVEsbUJBQW1CO0lBbUZoRSxZQUNVLEdBQXNCLEVBQ3RCLGtCQUFzQztJQUM5QywrR0FBK0c7SUFDdkcsU0FBdUIsRUFDdkIsYUFBNEI7UUFFcEMsS0FBSyxF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LENBQUMsS0FBSyxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDNUcsQ0FBQztJQUVEOzs7O09BSUc7SUFDSyxnQkFBZ0IsQ0FBQyxhQUFxQjtRQUM1QyxPQUFPLFFBQVEsQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxhQUFhLENBQUM7SUFDcEUsQ0FBQzs4R0E5Y1UseUJBQXlCO2tHQUF6Qix5QkFBeUIsZ1VDdkV0Qyx1eEVBd0NBOztTRCtCYSx5QkFBeUI7MkZBQXpCLHlCQUF5QjtrQkFOckMsU0FBUzsrQkFDRSxzQkFBc0IsbUJBR2YsdUJBQXVCLENBQUMsTUFBTTtnTUFPL0MsWUFBWTtzQkFEWCxXQUFXO3VCQUFDLGlCQUFpQjtnQkFPOUIsU0FBUztzQkFEUixXQUFXO3VCQUFDLGlCQUFpQjtnQkFPOUIsRUFBRTtzQkFERCxLQUFLO2dCQU1OLFlBQVk7c0JBRFgsS0FBSztnQkFPTixNQUFNO3NCQURMLEtBQUs7Z0JBT04sWUFBWTtzQkFEWCxNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiBUaGUgTUlUIExpY2Vuc2UgKE1JVClcblxuIENvcHlyaWdodCAoQykgMjAxNy0yMDIxIFN0ZWZhbm8gQ2FwcGEgKEtzODkpXG5cbiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5XG4gb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbFxuIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHNcbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsXG4gY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzXG4gZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcblxuIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkIGluIGFsbFxuIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG5cbiBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4gSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksXG4gRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTiBJTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxuIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVJcbiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLFxuIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFXG4gU09GVFdBUkUuXG4gKi9cblxuaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBDb21wb25lbnQsXG4gIEV2ZW50RW1pdHRlcixcbiAgSG9zdEJpbmRpbmcsXG4gIElucHV0LFxuICBPbkNoYW5nZXMsXG4gIE9uRGVzdHJveSxcbiAgT25Jbml0LFxuICBPdXRwdXQsXG4gIFNpbXBsZUNoYW5nZSxcbiAgU2ltcGxlQ2hhbmdlc1xufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IERvbVNhbml0aXplciwgU2FmZVJlc291cmNlVXJsLCBTYWZlU3R5bGUgfSBmcm9tICdAYW5ndWxhci9wbGF0Zm9ybS1icm93c2VyJztcbmltcG9ydCB7IEJyZWFrcG9pbnRPYnNlcnZlciwgQnJlYWtwb2ludHMsIEJyZWFrcG9pbnRTdGF0ZSB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9sYXlvdXQnO1xuXG5pbXBvcnQgeyBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcblxuaW1wb3J0IHsgQWNjZXNzaWJsZUNvbXBvbmVudCB9IGZyb20gJy4uLy4uL2FjY2Vzc2libGUuY29tcG9uZW50JztcblxuaW1wb3J0IHsgQWNjZXNzaWJpbGl0eUNvbmZpZyB9IGZyb20gJy4uLy4uLy4uL21vZGVsL2FjY2Vzc2liaWxpdHkuaW50ZXJmYWNlJztcbmltcG9ydCB7IEltYWdlLCBJbWFnZUV2ZW50IH0gZnJvbSAnLi4vLi4vLi4vbW9kZWwvaW1hZ2UuY2xhc3MnO1xuaW1wb3J0IHsgSW50ZXJuYWxMaWJJbWFnZSB9IGZyb20gJy4uLy4uLy4uL21vZGVsL2ltYWdlLWludGVybmFsLmNsYXNzJztcbmltcG9ydCB7IENhcm91c2VsUHJldmlld0NvbmZpZyB9IGZyb20gJy4uLy4uLy4uL21vZGVsL2Nhcm91c2VsLXByZXZpZXctY29uZmlnLmludGVyZmFjZSc7XG5pbXBvcnQgeyBDYXJvdXNlbENvbmZpZyB9IGZyb20gJy4uLy4uLy4uL21vZGVsL2Nhcm91c2VsLWNvbmZpZy5pbnRlcmZhY2UnO1xuXG5pbXBvcnQgeyBORVhULCBQUkVWIH0gZnJvbSAnLi4vLi4vLi4vdXRpbHMvdXNlci1pbnB1dC51dGlsJztcbmltcG9ydCB7IGdldEluZGV4IH0gZnJvbSAnLi4vLi4vLi4vdXRpbHMvaW1hZ2UudXRpbCc7XG5pbXBvcnQgeyBBY3Rpb24gfSBmcm9tICcuLi8uLi8uLi9tb2RlbC9hY3Rpb24uZW51bSc7XG5pbXBvcnQgeyBDb25maWdTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vLi4vc2VydmljZXMvY29uZmlnLnNlcnZpY2UnO1xuaW1wb3J0IHsgTGliQ29uZmlnIH0gZnJvbSAnLi4vLi4vLi4vbW9kZWwvbGliLWNvbmZpZy5pbnRlcmZhY2UnO1xuXG4vKipcbiAqIERlZmF1bHQgbWF4IGhlaWdodCBvZiBwcmV2aWV3cy5cbiAqL1xuY29uc3QgREVGQVVMVF9NQVhfSEVJR0hUID0gJzIwMHB4JztcblxuLyoqXG4gKiBDb21wb25lbnQgd2l0aCBpbWFnZSBwcmV2aWV3cyBmb3IgY2Fyb3VzZWxcbiAqL1xuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAna3MtY2Fyb3VzZWwtcHJldmlld3MnLFxuICBzdHlsZVVybHM6IFsnY2Fyb3VzZWwtcHJldmlld3Muc2NzcycsICcuLi8uLi9wcmV2aWV3cy1hcnJvd3Muc2NzcyddLFxuICB0ZW1wbGF0ZVVybDogJ2Nhcm91c2VsLXByZXZpZXdzLmh0bWwnLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaFxufSlcbmV4cG9ydCBjbGFzcyBDYXJvdXNlbFByZXZpZXdzQ29tcG9uZW50IGV4dGVuZHMgQWNjZXNzaWJsZUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25DaGFuZ2VzLCBPbkRlc3Ryb3kge1xuICAvKipcbiAgICogVmFyaWFibGUgdG8gY2hhbmdlIHRoZSBtYXgtd2lkdGggb2YgdGhlIGhvc3QgY29tcG9uZW50XG4gICAqL1xuICBASG9zdEJpbmRpbmcoJ3N0eWxlLm1heC13aWR0aCcpXG4gIGhvc3RNYXhXaWR0aCA9ICcxMDAlJztcblxuICAvKipcbiAgICogVmFyaWFibGUgdG8gc2V0IGFyaWEtbGFiZWwgb2YgdGhlIGhvc3QgY29tcG9uZW50XG4gICAqL1xuICBASG9zdEJpbmRpbmcoJ2F0dHIuYXJpYS1sYWJlbCcpXG4gIGFyaWFMYWJlbCA9IGBDYXJvdXNlbCBwcmV2aWV3c2A7XG5cbiAgLyoqXG4gICAqIFRPRE8gd3JpdGUgZG9jXG4gICAqL1xuICBASW5wdXQoKVxuICBpZCE6IG51bWJlcjtcbiAgLyoqXG4gICAqIE9iamVjdCBvZiB0eXBlIGBJbnRlcm5hbExpYkltYWdlYCB0aGF0IHJlcHJlc2VudCB0aGUgdmlzaWJsZSBpbWFnZS5cbiAgICovXG4gIEBJbnB1dCgpXG4gIGN1cnJlbnRJbWFnZSE6IEludGVybmFsTGliSW1hZ2U7XG4gIC8qKlxuICAgKiBBcnJheSBvZiBgSW50ZXJuYWxMaWJJbWFnZWAgdGhhdCByZXByZXNlbnQgdGhlIG1vZGVsIG9mIHRoaXMgbGlicmFyeSB3aXRoIGFsbCBpbWFnZXMsXG4gICAqIHRodW1icyBhbmQgc28gb24uXG4gICAqL1xuICBASW5wdXQoKVxuICBpbWFnZXMhOiBJbnRlcm5hbExpYkltYWdlW107XG5cbiAgLyoqXG4gICAqIE91dHB1dCB0byBlbWl0IHRoZSBjbGlja2VkIHByZXZpZXcuIFRoZSBwYXlsb2FkIGNvbnRhaW5zIHRoZSBgSW50ZXJuYWxMaWJJbWFnZWAgYXNzb2NpYXRlZCB0byB0aGUgY2xpY2tlZCBwcmV2aWV3LlxuICAgKi9cbiAgQE91dHB1dCgpXG4gIGNsaWNrUHJldmlldzogRXZlbnRFbWl0dGVyPEltYWdlRXZlbnQ+ID0gbmV3IEV2ZW50RW1pdHRlcjxJbWFnZUV2ZW50PigpO1xuXG4gIC8qKlxuICAgKiBPYmplY3Qgb2YgdHlwZSBgQ2Fyb3VzZWxDb25maWdgIHRvIGluaXQgQ2Fyb3VzZWxDb21wb25lbnQncyBmZWF0dXJlcy5cbiAgICogRm9yIGluc3RhbmNlLCBpdCBjb250YWlucyBwYXJhbWV0ZXJzIHRvIGNoYW5nZSB0aGUgc3R5bGUsIGhvdyBpdCBuYXZpZ2F0ZXMgYW5kIHNvIG9uLlxuICAgKi9cbiAgY2Fyb3VzZWxDb25maWc6IENhcm91c2VsQ29uZmlnIHwgdW5kZWZpbmVkO1xuICAvKipcbiAgICogT2JqZWN0IG9mIHR5cGUgYENhcm91c2VsUHJldmlld0NvbmZpZ2AgdG8gaW5pdCBQcmV2aWV3c0NvbXBvbmVudCdzIGZlYXR1cmVzLlxuICAgKiBGb3IgaW5zdGFuY2UsIGl0IGNvbnRhaW5zIGEgcGFyYW0gdG8gc2hvdy9oaWRlIHRoaXMgY29tcG9uZW50LCBzaXplcy5cbiAgICovXG4gIHByZXZpZXdDb25maWc6IENhcm91c2VsUHJldmlld0NvbmZpZyB8IHVuZGVmaW5lZDtcbiAgLyoqXG4gICAqIE9iamVjdCBvZiB0eXBlIGBBY2Nlc3NpYmlsaXR5Q29uZmlnYCB0byBpbml0IGN1c3RvbSBhY2Nlc3NpYmlsaXR5IGZlYXR1cmVzLlxuICAgKiBGb3IgaW5zdGFuY2UsIGl0IGNvbnRhaW5zIHRpdGxlcywgYWx0IHRleHRzLCBhcmlhLWxhYmVscyBhbmQgc28gb24uXG4gICAqL1xuICBhY2Nlc3NpYmlsaXR5Q29uZmlnOiBBY2Nlc3NpYmlsaXR5Q29uZmlnIHwgdW5kZWZpbmVkO1xuICAvKipcbiAgICogRW51bSBvZiB0eXBlIGBBY3Rpb25gIHRoYXQgcmVwcmVzZW50cyBhIG1vdXNlIGNsaWNrIG9uIGEgYnV0dG9uLlxuICAgKiBEZWNsYXJlZCBoZXJlIHRvIGJlIHVzZWQgaW5zaWRlIHRoZSB0ZW1wbGF0ZS5cbiAgICovXG4gIGNsaWNrQWN0aW9uOiBBY3Rpb24gPSBBY3Rpb24uQ0xJQ0s7XG4gIC8qKlxuICAgKiBFbnVtIG9mIHR5cGUgYEFjdGlvbmAgdGhhdCByZXByZXNlbnRzIGEga2V5Ym9hcmQgYWN0aW9uLlxuICAgKiBEZWNsYXJlZCBoZXJlIHRvIGJlIHVzZWQgaW5zaWRlIHRoZSB0ZW1wbGF0ZS5cbiAgICovXG4gIGtleWJvYXJkQWN0aW9uOiBBY3Rpb24gPSBBY3Rpb24uS0VZQk9BUkQ7XG4gIC8qKlxuICAgKiBBcnJheSBvZiBgSW50ZXJuYWxMaWJJbWFnZWAgZXhwb3NlZCB0byB0aGUgdGVtcGxhdGUuIFRoaXMgZmllbGQgaXMgaW5pdGlhbGl6ZWRcbiAgICogYXBwbHlpbmcgdHJhbnNmb3JtYXRpb25zLCBkZWZhdWx0IHZhbHVlcyBhbmQgc28gb24gdG8gdGhlIGlucHV0IG9mIHRoZSBzYW1lIHR5cGUuXG4gICAqL1xuICBwcmV2aWV3czogSW50ZXJuYWxMaWJJbWFnZVtdID0gW107XG4gIC8qKlxuICAgKiBWYXJpYWJsZSB3aXRoIHRoZSBwcmV2aWV3J3MgbWF4SGVpZ2h0XG4gICAqL1xuICBwcmV2aWV3TWF4SGVpZ2h0OiBzdHJpbmcgPSBERUZBVUxUX01BWF9IRUlHSFQ7XG4gIC8qKlxuICAgKiBTdGFydCBpbmRleCAoaW5jbHVzaXZlKSBvZiB0aGUgaW5wdXQgaW1hZ2VzIHVzZWQgdG8gZGlzcGxheSBwcmV2aWV3cy5cbiAgICovXG4gIC8vIEB0cy1pZ25vcmVcbiAgc3RhcnQ6IG51bWJlcjtcbiAgLyoqXG4gICAqIEVuZCBpbmRleCAobm9uIGluY2x1c2l2ZSkgb2YgdGhlIGlucHV0IGltYWdlcyB1c2VkIHRvIGRpc3BsYXkgcHJldmlld3MuXG4gICAqL1xuICAvLyBAdHMtaWdub3JlXG4gIGVuZDogbnVtYmVyO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgYnJlYWtwb2ludFN1YnNjcmlwdGlvbjogU3Vic2NyaXB0aW9uO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVmOiBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICBwcml2YXRlIGJyZWFrcG9pbnRPYnNlcnZlcjogQnJlYWtwb2ludE9ic2VydmVyLFxuICAgIC8vIHNhbml0aXplciBpcyB1c2VkIG9ubHkgdG8gc2FuaXRpemUgc3R5bGUgYmVmb3JlIGFkZCBpdCB0byBiYWNrZ3JvdW5kIHByb3BlcnR5IHdoZW4gbGVnYWN5SUUxMU1vZGUgaXMgZW5hYmxlZFxuICAgIHByaXZhdGUgc2FuaXRpemVyOiBEb21TYW5pdGl6ZXIsXG4gICAgcHJpdmF0ZSBjb25maWdTZXJ2aWNlOiBDb25maWdTZXJ2aWNlXG4gICkge1xuICAgIHN1cGVyKCk7XG5cbiAgICAvLyBsaXN0ZW4gZm9yIHdpZHRoIGNoYW5nZXMgYW5kIHVwZGF0ZSBwcmV2aWV3IGhlaWdodHMgYWNjb3JkaW5nbHlcbiAgICB0aGlzLmJyZWFrcG9pbnRTdWJzY3JpcHRpb24gPSBicmVha3BvaW50T2JzZXJ2ZXJcbiAgICAgIC5vYnNlcnZlKFtCcmVha3BvaW50cy5YU21hbGwsIEJyZWFrcG9pbnRzLlNtYWxsLCBCcmVha3BvaW50cy5NZWRpdW0sIEJyZWFrcG9pbnRzLkxhcmdlLCBCcmVha3BvaW50cy5YTGFyZ2VdKVxuICAgICAgLnN1YnNjcmliZSgocmVzdWx0OiBCcmVha3BvaW50U3RhdGUpID0+IHtcbiAgICAgICAgaWYgKCF0aGlzLnByZXZpZXdDb25maWcgfHwgIXRoaXMucHJldmlld0NvbmZpZy5icmVha3BvaW50cykge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmVzdWx0LmJyZWFrcG9pbnRzW0JyZWFrcG9pbnRzLlhTbWFsbF0pIHtcbiAgICAgICAgICB0aGlzLnVwZGF0ZUhlaWdodCh0aGlzLnByZXZpZXdDb25maWcuYnJlYWtwb2ludHMueFNtYWxsKTtcbiAgICAgICAgfSBlbHNlIGlmIChyZXN1bHQuYnJlYWtwb2ludHNbQnJlYWtwb2ludHMuU21hbGxdKSB7XG4gICAgICAgICAgdGhpcy51cGRhdGVIZWlnaHQodGhpcy5wcmV2aWV3Q29uZmlnLmJyZWFrcG9pbnRzLnNtYWxsKTtcbiAgICAgICAgfSBlbHNlIGlmIChyZXN1bHQuYnJlYWtwb2ludHNbQnJlYWtwb2ludHMuTWVkaXVtXSkge1xuICAgICAgICAgIHRoaXMudXBkYXRlSGVpZ2h0KHRoaXMucHJldmlld0NvbmZpZy5icmVha3BvaW50cy5tZWRpdW0pO1xuICAgICAgICB9IGVsc2UgaWYgKHJlc3VsdC5icmVha3BvaW50c1tCcmVha3BvaW50cy5MYXJnZV0pIHtcbiAgICAgICAgICB0aGlzLnVwZGF0ZUhlaWdodCh0aGlzLnByZXZpZXdDb25maWcuYnJlYWtwb2ludHMubGFyZ2UpO1xuICAgICAgICB9IGVsc2UgaWYgKHJlc3VsdC5icmVha3BvaW50c1tCcmVha3BvaW50cy5YTGFyZ2VdKSB7XG4gICAgICAgICAgdGhpcy51cGRhdGVIZWlnaHQodGhpcy5wcmV2aWV3Q29uZmlnLmJyZWFrcG9pbnRzLnhMYXJnZSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIE1ldGhvZCB0byB1cGRhdGUgdGhlIGhlaWdodCBvZiBwcmV2aWV3cywgcGFzc2luZyB0aGUgZGVzaXJlZCBoZWlnaHQgYXMgaW5wdXQuXG4gICAqIEBwYXJhbSBjb25maWdCcmVha3BvaW50SGVpZ2h0IGlzIGEgbnVtYmVyIHRoYXQgcmVwcmVzZW50IHRoZSBkZXNpcmVkIGhlaWdodCB0byBzZXQuXG4gICAqL1xuICBwcml2YXRlIHVwZGF0ZUhlaWdodChjb25maWdCcmVha3BvaW50SGVpZ2h0OiBudW1iZXIpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5wcmV2aWV3Q29uZmlnICYmIHRoaXMucHJldmlld0NvbmZpZy5tYXhIZWlnaHQpIHtcbiAgICAgIGNvbnN0IGhlaWdodE51bTogbnVtYmVyID0gK3RoaXMucHJldmlld0NvbmZpZy5tYXhIZWlnaHQucmVwbGFjZSgnL3B4L2cnLCAnJykucmVwbGFjZSgnLyUvZycsICcnKTtcbiAgICAgIHRoaXMucHJldmlld01heEhlaWdodCA9IE1hdGgubWluKGNvbmZpZ0JyZWFrcG9pbnRIZWlnaHQsIGhlaWdodE51bSkgKyAncHgnO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBoZWlnaHROdW06IG51bWJlciA9ICtERUZBVUxUX01BWF9IRUlHSFQucmVwbGFjZSgnL3B4L2cnLCAnJykucmVwbGFjZSgnLyUvZycsICcnKTtcbiAgICAgIHRoaXMucHJldmlld01heEhlaWdodCA9IE1hdGgubWluKGNvbmZpZ0JyZWFrcG9pbnRIZWlnaHQsIGhlaWdodE51bSkgKyAncHgnO1xuICAgIH1cbiAgICB0aGlzLnJlZi5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNZXRob2QgwrRuZ09uSW5pdMK0IHRvIGJ1aWxkIGBjb25maWdQcmV2aWV3YCBhcHBseWluZyBhIGRlZmF1bHQgdmFsdWUgYW5kIGFsc28gdG9cbiAgICogaW5pdCB0aGUgYHByZXZpZXdzYCBhcnJheS5cbiAgICogVGhpcyBpcyBhbiBhbmd1bGFyIGxpZmVjeWNsZSBob29rLCBzbyBpdHMgY2FsbGVkIGF1dG9tYXRpY2FsbHkgYnkgQW5ndWxhciBpdHNlbGYuXG4gICAqIEluIHBhcnRpY3VsYXIsIGl0J3MgY2FsbGVkIG9ubHkgb25lIHRpbWUhISFcbiAgICovXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIGNvbnN0IGxpYkNvbmZpZzogTGliQ29uZmlnIHwgdW5kZWZpbmVkID0gdGhpcy5jb25maWdTZXJ2aWNlLmdldENvbmZpZyh0aGlzLmlkKTtcbiAgICBpZiAoIWxpYkNvbmZpZykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnRlcm5hbCBsaWJyYXJ5IGVycm9yIC0gbGliQ29uZmlnIG11c3QgYmUgZGVmaW5lZCcpO1xuICAgIH1cbiAgICB0aGlzLmNhcm91c2VsQ29uZmlnID0gbGliQ29uZmlnLmNhcm91c2VsQ29uZmlnO1xuICAgIHRoaXMucHJldmlld0NvbmZpZyA9IGxpYkNvbmZpZy5jYXJvdXNlbFByZXZpZXdzQ29uZmlnO1xuICAgIHRoaXMuYWNjZXNzaWJpbGl0eUNvbmZpZyA9IGxpYkNvbmZpZy5hY2Nlc3NpYmlsaXR5Q29uZmlnO1xuXG4gICAgaWYgKCF0aGlzLnByZXZpZXdDb25maWcgfHwgIXRoaXMucHJldmlld0NvbmZpZy5tYXhIZWlnaHQgfHwgIXRoaXMucHJldmlld0NvbmZpZy5icmVha3BvaW50cykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnRlcm5hbCBsaWJyYXJ5IGVycm9yIC0gcHJldmlld0NvbmZpZyBtdXN0IGJlIGRlZmluZWQnKTtcbiAgICB9XG4gICAgLy8gY2hhbmdlIHRoZSBtYXgtd2lkdGggb2YgdGhpcyBjb21wb25lbnQgaWYgdGhlcmUgaXMgYSBzcGVjaWZpZWQgd2lkdGggIT09IDEwMCUgaW4gY2Fyb3VzZWxDb25maWdcbiAgICBpZiAodGhpcy5jYXJvdXNlbENvbmZpZyAmJiB0aGlzLmNhcm91c2VsQ29uZmlnLm1heFdpZHRoICE9PSAnMTAwJScpIHtcbiAgICAgIHRoaXMuaG9zdE1heFdpZHRoID0gdGhpcy5jYXJvdXNlbENvbmZpZy5tYXhXaWR0aDtcbiAgICB9XG5cbiAgICB0aGlzLnByZXZpZXdNYXhIZWlnaHQgPSB0aGlzLnByZXZpZXdDb25maWcubWF4SGVpZ2h0O1xuICAgIC8vIGluaXQgcHJldmlld3MgYmFzZWQgb24gY3VycmVudEltYWdlIGFuZCB0aGUgZnVsbCBhcnJheSBvZiBpbWFnZXNcbiAgICB0aGlzLmluaXRQcmV2aWV3cyh0aGlzLmN1cnJlbnRJbWFnZSwgdGhpcy5pbWFnZXMpO1xuXG4gICAgLy8gYXBwbHkgY3VzdG9tIGhlaWdodCBiYXNlZCBvbiByZXNwb25zaXZlIGJyZWFrcG9pbnRzXG4gICAgLy8gVGhpcyBpcyByZXF1aXJlZCwgYmVjYXVzZSB0aGUgYnJlYWtwb2ludFN1YnNjcmlwdGlvbiBpcyBub3QgdHJpZ2dlcmVkIGF0IGNyZWF0aW9uLFxuICAgIC8vIGJ1dCBvbmx5IHdoZW4gdGhlIHdpZHRoIGNoYW5nZXNcbiAgICBjb25zdCBpc1hzbWFsbFNjcmVlbiA9IHRoaXMuYnJlYWtwb2ludE9ic2VydmVyLmlzTWF0Y2hlZChCcmVha3BvaW50cy5YU21hbGwpO1xuICAgIGNvbnN0IGlzU21hbGxTY3JlZW4gPSB0aGlzLmJyZWFrcG9pbnRPYnNlcnZlci5pc01hdGNoZWQoQnJlYWtwb2ludHMuU21hbGwpO1xuICAgIGNvbnN0IGlzTWVkaXVtU2NyZWVuID0gdGhpcy5icmVha3BvaW50T2JzZXJ2ZXIuaXNNYXRjaGVkKEJyZWFrcG9pbnRzLk1lZGl1bSk7XG4gICAgY29uc3QgaXNMYXJnZVNjcmVlbiA9IHRoaXMuYnJlYWtwb2ludE9ic2VydmVyLmlzTWF0Y2hlZChCcmVha3BvaW50cy5MYXJnZSk7XG4gICAgY29uc3QgaXN4TGFyZ2VTY3JlZW4gPSB0aGlzLmJyZWFrcG9pbnRPYnNlcnZlci5pc01hdGNoZWQoQnJlYWtwb2ludHMuWExhcmdlKTtcbiAgICBpZiAoaXNYc21hbGxTY3JlZW4pIHtcbiAgICAgIHRoaXMudXBkYXRlSGVpZ2h0KHRoaXMucHJldmlld0NvbmZpZy5icmVha3BvaW50cy54U21hbGwpO1xuICAgIH0gZWxzZSBpZiAoaXNTbWFsbFNjcmVlbikge1xuICAgICAgdGhpcy51cGRhdGVIZWlnaHQodGhpcy5wcmV2aWV3Q29uZmlnLmJyZWFrcG9pbnRzLnNtYWxsKTtcbiAgICB9IGVsc2UgaWYgKGlzTWVkaXVtU2NyZWVuKSB7XG4gICAgICB0aGlzLnVwZGF0ZUhlaWdodCh0aGlzLnByZXZpZXdDb25maWcuYnJlYWtwb2ludHMubWVkaXVtKTtcbiAgICB9IGVsc2UgaWYgKGlzTGFyZ2VTY3JlZW4pIHtcbiAgICAgIHRoaXMudXBkYXRlSGVpZ2h0KHRoaXMucHJldmlld0NvbmZpZy5icmVha3BvaW50cy5sYXJnZSk7XG4gICAgfSBlbHNlIGlmIChpc3hMYXJnZVNjcmVlbikge1xuICAgICAgdGhpcy51cGRhdGVIZWlnaHQodGhpcy5wcmV2aWV3Q29uZmlnLmJyZWFrcG9pbnRzLnhMYXJnZSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIE1ldGhvZCB0byBjaGVjayBpZiBhbiBpbWFnZSBpcyBhY3RpdmUgKGkuZS4gYSBwcmV2aWV3IGltYWdlKS5cbiAgICogQHBhcmFtIEludGVybmFsTGliSW1hZ2UgcHJldmlldyBpcyBhbiBpbWFnZSB0byBjaGVjayBpZiBpdCdzIGFjdGl2ZSBvciBub3RcbiAgICogQHJldHVybnMgYm9vbGVhbiB0cnVlIGlmIGlzIGFjdGl2ZSwgZmFsc2Ugb3RoZXJ3aXNlXG4gICAqL1xuICBpc0FjdGl2ZShwcmV2aWV3OiBJbnRlcm5hbExpYkltYWdlKTogYm9vbGVhbiB7XG4gICAgaWYgKCFwcmV2aWV3IHx8ICF0aGlzLmN1cnJlbnRJbWFnZSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gcHJldmlldy5pZCA9PT0gdGhpcy5jdXJyZW50SW1hZ2UuaWQ7XG4gIH1cblxuICAvKipcbiAgICogTWV0aG9kIMK0bmdPbkNoYW5nZXPCtCB0byB1cGRhdGUgYHByZXZpZXdzYCBhcnJheS5cbiAgICogQWxzbywgYm90aCBgc3RhcnRgIGFuZCBgZW5kYCBsb2NhbCB2YXJpYWJsZXMgd2lsbCBiZSB1cGRhdGVkIGFjY29yZGluZ2x5LlxuICAgKiBUaGlzIGlzIGFuIGFuZ3VsYXIgbGlmZWN5Y2xlIGhvb2ssIHNvIGl0cyBjYWxsZWQgYXV0b21hdGljYWxseSBieSBBbmd1bGFyIGl0c2VsZi5cbiAgICogSW4gcGFydGljdWxhciwgaXQncyBjYWxsZWQgd2hlbiBhbnkgZGF0YS1ib3VuZCBwcm9wZXJ0eSBvZiBhIGRpcmVjdGl2ZSBjaGFuZ2VzISEhXG4gICAqL1xuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XG4gICAgY29uc3Qgc2ltcGxlQ2hhbmdlOiBTaW1wbGVDaGFuZ2UgPSBjaGFuZ2VzLmN1cnJlbnRJbWFnZTtcbiAgICBpZiAoIXNpbXBsZUNoYW5nZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHByZXY6IEludGVybmFsTGliSW1hZ2UgPSBzaW1wbGVDaGFuZ2UucHJldmlvdXNWYWx1ZTtcbiAgICBjb25zdCBjdXJyZW50OiBJbnRlcm5hbExpYkltYWdlID0gc2ltcGxlQ2hhbmdlLmN1cnJlbnRWYWx1ZTtcblxuICAgIGlmIChjdXJyZW50ICYmIGNoYW5nZXMuaW1hZ2VzICYmIGNoYW5nZXMuaW1hZ2VzLnByZXZpb3VzVmFsdWUgJiYgY2hhbmdlcy5pbWFnZXMuY3VycmVudFZhbHVlKSB7XG4gICAgICAvLyBJJ20gaW4gdGhpcyBpZiBzdGF0ZW1lbnQsIGlmIGlucHV0IGltYWdlcyBhcmUgY2hhbmdlZCAoZm9yIGluc3RhbmNlLCBiZWNhdXNlIEkgcmVtb3ZlZCBvbmUgb2YgdGhlbSB3aXRoIHRoZSAnZGVsZXRlIGJ1dHRvbicsXG4gICAgICAvLyBvciBiZWNhdXNlIHVzZXJzIGNoYW5nZWQgdGhlIGltYWdlcyBhcnJheSB3aGlsZSBtb2RhbCBnYWxsZXJ5IGlzIHN0aWxsIG9wZW4pLlxuICAgICAgLy8gSW4gdGhpcyBjYXNlLCBJIGhhdmUgdG8gcmUtaW5pdCBwcmV2aWV3cywgYmVjYXVzZSB0aGUgaW5wdXQgYXJyYXkgb2YgaW1hZ2VzIGlzIGNoYW5nZWQuXG4gICAgICB0aGlzLmluaXRQcmV2aWV3cyhjdXJyZW50LCBjaGFuZ2VzLmltYWdlcy5jdXJyZW50VmFsdWUpO1xuICAgIH1cblxuICAgIGlmIChwcmV2ICYmIGN1cnJlbnQgJiYgcHJldi5pZCAhPT0gY3VycmVudC5pZCkge1xuICAgICAgLy8gdG8gbWFuYWdlIGluZmluaXRlIHNsaWRpbmcgSSBoYXZlIHRvIHJlc2V0IGJvdGggYHN0YXJ0YCBhbmQgYGVuZGAgYXQgdGhlIGJlZ2lubmluZ1xuICAgICAgLy8gdG8gc2hvdyBhZ2FpbiBwcmV2aWV3cyBmcm9tIHRoZSBmaXJzdCBpbWFnZS5cbiAgICAgIC8vIFRoaXMgaGFwcGVucyB3aGVuIHlvdSBuYXZpZ2F0ZSBvdmVyIHRoZSBsYXN0IGltYWdlIHRvIHJldHVybiB0byB0aGUgZmlyc3Qgb25lXG4gICAgICBsZXQgcHJldkluZGV4OiBudW1iZXI7XG4gICAgICBsZXQgY3VycmVudEluZGV4OiBudW1iZXI7XG4gICAgICB0cnkge1xuICAgICAgICBwcmV2SW5kZXggPSBnZXRJbmRleChwcmV2LCB0aGlzLmltYWdlcyk7XG4gICAgICAgIGN1cnJlbnRJbmRleCA9IGdldEluZGV4KGN1cnJlbnQsIHRoaXMuaW1hZ2VzKTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBjb25zb2xlLmVycm9yKCdDYW5ub3QgZ2V0IHByZXZpb3VzIGFuZCBjdXJyZW50IGltYWdlIGluZGV4ZXMgaW4gcHJldmlld3MnKTtcbiAgICAgICAgdGhyb3cgZXJyO1xuICAgICAgfVxuXG4gICAgICAvLyBhcHBseSBhIGZvcm11bGEgdG8gZ2V0IGEgdmFsdWVzIHRvIGJlIHVzZWQgdG8gZGVjaWRlIGlmIGdvIG5leHQsIHJldHVybiBiYWNrIG9yIHN0YXkgd2l0aG91dCBkb2luZyBhbnl0aGluZ1xuICAgICAgY29uc3QgY2FsYyA9IE1hdGguZmxvb3IoKHRoaXMuZW5kIC0gdGhpcy5zdGFydCkgLyAyKSArIHRoaXMuc3RhcnQ7XG5cbiAgICAgIGlmIChwcmV2SW5kZXggPT09IHRoaXMuaW1hZ2VzLmxlbmd0aCAtIDEgJiYgY3VycmVudEluZGV4ID09PSAwKSB7XG4gICAgICAgIC8vIGZpcnN0IGltYWdlXG4gICAgICAgIHRoaXMuc2V0QmVnaW5uaW5nSW5kZXhlc1ByZXZpZXdzKCk7XG4gICAgICAgIHRoaXMucHJldmlld3MgPSB0aGlzLmltYWdlcy5maWx0ZXIoKGltZzogSW50ZXJuYWxMaWJJbWFnZSwgaTogbnVtYmVyKSA9PiBpID49IHRoaXMuc3RhcnQgJiYgaSA8IHRoaXMuZW5kKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgLy8gdGhlIHNhbWUgZm9yIHRoZSBvcHBvc2l0ZSBjYXNlLCB3aGVuIHlvdSBuYXZpZ2F0ZSBiYWNrIGZyb20gdGhlIGZpc3QgaW1hZ2UgdG8gZ28gdG8gdGhlIGxhc3Qgb25lLlxuICAgICAgaWYgKHByZXZJbmRleCA9PT0gMCAmJiBjdXJyZW50SW5kZXggPT09IHRoaXMuaW1hZ2VzLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgLy8gbGFzdCBpbWFnZVxuICAgICAgICB0aGlzLnNldEVuZEluZGV4ZXNQcmV2aWV3cygpO1xuICAgICAgICB0aGlzLnByZXZpZXdzID0gdGhpcy5pbWFnZXMuZmlsdGVyKChpbWc6IEludGVybmFsTGliSW1hZ2UsIGk6IG51bWJlcikgPT4gaSA+PSB0aGlzLnN0YXJ0ICYmIGkgPCB0aGlzLmVuZCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMucHJldmlld0NvbmZpZyAmJiAodGhpcy5wcmV2aWV3Q29uZmlnLm51bWJlciBhcyBudW1iZXIpICUgMiA9PT0gMCkge1xuICAgICAgICBpZiAoY2FsYyA+IGN1cnJlbnRJbmRleCkge1xuICAgICAgICAgIHRoaXMucHJldmlvdXMoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLm5leHQoKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKGNhbGMgPiBjdXJyZW50SW5kZXgpIHtcbiAgICAgICAgICB0aGlzLnByZXZpb3VzKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNhbGMgPCBjdXJyZW50SW5kZXgpIHtcbiAgICAgICAgICB0aGlzLm5leHQoKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBNZXRob2QgY2FsbGVkIGJ5IGV2ZW50cyBmcm9tIGJvdGgga2V5Ym9hcmQgYW5kIG1vdXNlIG9uIGEgcHJldmlldy5cbiAgICogVGhpcyB3aWxsIHRyaWdnZXIgdGhlIGBjbGlja3ByZXZpZXdgIG91dHB1dCB3aXRoIHRoZSBpbnB1dCBwcmV2aWV3IGFzIGl0cyBwYXlsb2FkLlxuICAgKiBAcGFyYW0gSW50ZXJuYWxMaWJJbWFnZSBwcmV2aWV3IHRoYXQgdHJpZ2dlcmVkIHRoaXMgbWV0aG9kXG4gICAqIEBwYXJhbSBLZXlib2FyZEV2ZW50IHwgTW91c2VFdmVudCBldmVudCBwYXlsb2FkXG4gICAqIEBwYXJhbSBBY3Rpb24gdGhhdCB0cmlnZ2VyZWQgdGhpcyBldmVudCAoQWN0aW9uLk5PUk1BTCBieSBkZWZhdWx0KVxuICAgKi9cbiAgb25JbWFnZUV2ZW50KHByZXZpZXc6IEludGVybmFsTGliSW1hZ2UsIGV2ZW50OiBLZXlib2FyZEV2ZW50IHwgTW91c2VFdmVudCwgYWN0aW9uOiBBY3Rpb24gPSBBY3Rpb24uTk9STUFMKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLnByZXZpZXdDb25maWcgfHwgIXRoaXMucHJldmlld0NvbmZpZy5jbGlja2FibGUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgY2xpY2tlZEltYWdlSW5kZXg6IG51bWJlciA9IHRoaXMuaW1hZ2VzLmluZGV4T2YocHJldmlldyk7XG4gICAgY29uc3QgcmVzdWx0OiBudW1iZXIgPSBzdXBlci5oYW5kbGVJbWFnZUV2ZW50KGV2ZW50KTtcbiAgICBpZiAocmVzdWx0ID09PSBORVhUKSB7XG4gICAgICB0aGlzLmNsaWNrUHJldmlldy5lbWl0KHsgYWN0aW9uLCByZXN1bHQ6IGNsaWNrZWRJbWFnZUluZGV4IH0gYXMgSW1hZ2VFdmVudCk7XG4gICAgfSBlbHNlIGlmIChyZXN1bHQgPT09IFBSRVYpIHtcbiAgICAgIHRoaXMuY2xpY2tQcmV2aWV3LmVtaXQoeyBhY3Rpb24sIHJlc3VsdDogY2xpY2tlZEltYWdlSW5kZXggfSBhcyBJbWFnZUV2ZW50KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogTWV0aG9kIGNhbGxlZCBieSBldmVudHMgZnJvbSBib3RoIGtleWJvYXJkIGFuZCBtb3VzZSBvbiBhIG5hdmlnYXRpb24gYXJyb3cuXG4gICAqIEBwYXJhbSBzdHJpbmcgZGlyZWN0aW9uIG9mIHRoZSBuYXZpZ2F0aW9uIHRoYXQgY2FuIGJlIGVpdGhlciAnbmV4dCcgb3IgJ3ByZXYnXG4gICAqIEBwYXJhbSBLZXlib2FyZEV2ZW50IHwgTW91c2VFdmVudCBldmVudCBwYXlsb2FkXG4gICAqL1xuICBvbk5hdmlnYXRpb25FdmVudChkaXJlY3Rpb246IHN0cmluZywgZXZlbnQ6IEtleWJvYXJkRXZlbnQgfCBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgY29uc3QgcmVzdWx0OiBudW1iZXIgPSBzdXBlci5oYW5kbGVOYXZpZ2F0aW9uRXZlbnQoZGlyZWN0aW9uLCBldmVudCk7XG4gICAgaWYgKHJlc3VsdCA9PT0gTkVYVCkge1xuICAgICAgdGhpcy5uZXh0KCk7XG4gICAgfSBlbHNlIGlmIChyZXN1bHQgPT09IFBSRVYpIHtcbiAgICAgIHRoaXMucHJldmlvdXMoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogTWV0aG9kIHRvIGdldCBhcmlhLWxhYmVsIHRleHQgZm9yIGEgcHJldmlldyBpbWFnZS5cbiAgICogQHBhcmFtIEltYWdlIGlzIHRoZSBwcmV2aWV3XG4gICAqL1xuICBnZXRBcmlhTGFiZWwocHJldmlldzogSW1hZ2UpOiBzdHJpbmcge1xuICAgIGlmICghcHJldmlldy5wbGFpbikge1xuICAgICAgcmV0dXJuIHByZXZpZXcubW9kYWwuYXJpYUxhYmVsIHx8ICcnO1xuICAgIH1cbiAgICByZXR1cm4gcHJldmlldy5wbGFpbi5hcmlhTGFiZWwgfHwgcHJldmlldy5tb2RhbC5hcmlhTGFiZWwgfHwgJyc7XG4gIH1cblxuICAvKipcbiAgICogTWV0aG9kIHRvIGdldCB0aXRsZSB0ZXh0IGZvciBhIHByZXZpZXcgaW1hZ2UuXG4gICAqIEBwYXJhbSBJbWFnZSBpcyB0aGUgcHJldmlld1xuICAgKi9cbiAgZ2V0VGl0bGUocHJldmlldzogSW1hZ2UpOiBzdHJpbmcge1xuICAgIGlmICghcHJldmlldy5wbGFpbikge1xuICAgICAgcmV0dXJuIHByZXZpZXcubW9kYWwudGl0bGUgfHwgJyc7XG4gICAgfVxuICAgIHJldHVybiBwcmV2aWV3LnBsYWluLnRpdGxlIHx8IHByZXZpZXcubW9kYWwudGl0bGUgfHwgJyc7XG4gIH1cblxuICAvKipcbiAgICogTWV0aG9kIHRvIGdldCBhbHQgdGV4dCBmb3IgYSBwcmV2aWV3IGltYWdlLlxuICAgKiBAcGFyYW0gSW1hZ2UgaXMgdGhlIHByZXZpZXdcbiAgICovXG4gIGdldEFsdChwcmV2aWV3OiBJbWFnZSk6IHN0cmluZyB7XG4gICAgaWYgKCFwcmV2aWV3LnBsYWluKSB7XG4gICAgICByZXR1cm4gcHJldmlldy5tb2RhbC5hbHQgfHwgJyc7XG4gICAgfVxuICAgIHJldHVybiBwcmV2aWV3LnBsYWluLmFsdCB8fCBwcmV2aWV3Lm1vZGFsLmFsdCB8fCAnJztcbiAgfVxuXG4gIC8qKlxuICAgKiBNZXRob2QgdXNlZCBpbiB0aGUgdGVtcGxhdGUgdG8gdHJhY2sgaWRzIGluIG5nRm9yLlxuICAgKiBAcGFyYW0gbnVtYmVyIGluZGV4IG9mIHRoZSBhcnJheVxuICAgKiBAcGFyYW0gSW1hZ2UgaXRlbSBvZiB0aGUgYXJyYXlcbiAgICogQHJldHVybnMgbnVtYmVyIHRoZSBpZCBvZiB0aGUgaXRlbVxuICAgKi9cbiAgdHJhY2tCeUlkKGluZGV4OiBudW1iZXIsIGl0ZW06IEltYWdlKTogbnVtYmVyIHtcbiAgICByZXR1cm4gaXRlbS5pZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBNZXRob2QgdXNlZCBpbiB0ZW1wbGF0ZSB0byBzYW5pdGl6ZSBhbiB1cmwgd2hlbiB5b3UgbmVlZCBsZWdhY3lJRTExTW9kZS5cbiAgICogSW4gdGhpcyB3YXkgeW91IGNhbiBzZXQgYW4gdXJsIGFzIGJhY2tncm91bmQgb2YgYSBkaXYuXG4gICAqIEBwYXJhbSB1bnNhZmVTdHlsZSBpcyBhIHN0cmluZyBvciBhIFNhZmVSZXNvdXJjZVVybCB0aGF0IHJlcHJlc2VudHMgdGhlIHVybCB0byBzYW5pdGl6ZS5cbiAgICogQHBhcmFtIHVuc2FmZVN0eWxlRmFsbGJhY2sgaXMgYSBzdHJpbmcgb3IgYSBTYWZlUmVzb3VyY2VVcmwgdGhhdCByZXByZXNlbnRzIHRoZSBmYWxsYmFjayB1cmwgdG8gc2FuaXRpemUuXG4gICAqIEByZXR1cm5zIGEgU2FmZVN0eWxlIG9iamVjdCB0aGF0IGNhbiBiZSB1c2VkIGluIHRlbXBsYXRlIHdpdGhvdXQgcHJvYmxlbXMuXG4gICAqL1xuICBzYW5pdGl6ZVVybEJnU3R5bGUodW5zYWZlU3R5bGU6IHN0cmluZyB8IFNhZmVSZXNvdXJjZVVybCwgdW5zYWZlU3R5bGVGYWxsYmFjazogc3RyaW5nIHwgU2FmZVJlc291cmNlVXJsKTogU2FmZVN0eWxlIHtcbiAgICAvLyBNZXRob2QgdXNlZCBvbmx5IHRvIHNhbml0aXplIGJhY2tncm91bmQtaW1hZ2Ugc3R5bGUgYmVmb3JlIGFkZCBpdCB0byBiYWNrZ3JvdW5kIHByb3BlcnR5IHdoZW4gbGVnYWN5SUUxMU1vZGUgaXMgZW5hYmxlZFxuICAgIGxldCBiZzogc3RyaW5nID0gJ3VybCgnICsgdW5zYWZlU3R5bGUgKyAnKSc7XG4gICAgaWYgKCEhdW5zYWZlU3R5bGVGYWxsYmFjaykge1xuICAgICAgLy8gaWYgYSBmYWxsYmFjayBpbWFnZSBpcyBkZWZpbmVkLCBhcHBlbmQgaXQuIEluIHRoaXMgd2F5LCBpdCB3aWxsIGJlIHVzZWQgYnkgdGhlIGJyb3dzZXIgYXMgZmFsbGJhY2suXG4gICAgICBiZyArPSAnLCAnICsgJ3VybCgnICsgdW5zYWZlU3R5bGVGYWxsYmFjayArICcpJztcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuc2FuaXRpemVyLmJ5cGFzc1NlY3VyaXR5VHJ1c3RTdHlsZShiZyk7XG4gIH1cblxuICAvKipcbiAgICogTWV0aG9kIHRvIGNsZWFudXAgcmVzb3VyY2VzLiBJbiBmYWN0LCBpdCBjbGVhbnMgYnJlYWtwb2ludFN1YnNjcmlwdGlvbi5cbiAgICogVGhpcyBpcyBhbiBhbmd1bGFyIGxpZmVjeWNsZSBob29rIHRoYXQgaXMgY2FsbGVkIHdoZW4gdGhpcyBjb21wb25lbnQgaXMgZGVzdHJveWVkLlxuICAgKi9cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuYnJlYWtwb2ludFN1YnNjcmlwdGlvbikge1xuICAgICAgdGhpcy5icmVha3BvaW50U3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFByaXZhdGUgbWV0aG9kIHRvIGluaXQgcHJldmlld3MgYmFzZWQgb24gdGhlIGN1cnJlbnRJbWFnZSBhbmQgdGhlIGZ1bGwgYXJyYXkgb2YgaW1hZ2VzLlxuICAgKiBUaGUgY3VycmVudCBpbWFnZSBpbiBtYW5kYXRvcnkgdG8gc2hvdyBhbHdheXMgdGhlIGN1cnJlbnQgcHJldmlldyAoYXMgaGlnaGxpZ2h0ZWQpLlxuICAgKiBAcGFyYW0gSW50ZXJuYWxMaWJJbWFnZSBjdXJyZW50SW1hZ2UgdG8gZGVjaWRlIGhvdyB0byBzaG93IHByZXZpZXdzLCBiZWNhdXNlIEkgYWx3YXlzIHdhbnQgdG8gc2VlIHRoZSBjdXJyZW50IGltYWdlIGFzIGhpZ2hsaWdodGVkXG4gICAqIEBwYXJhbSBJbnRlcm5hbExpYkltYWdlW10gaW1hZ2VzIGlzIHRoZSBhcnJheSBvZiBhbGwgaW1hZ2VzLlxuICAgKi9cbiAgcHJpdmF0ZSBpbml0UHJldmlld3MoY3VycmVudEltYWdlOiBJbnRlcm5hbExpYkltYWdlLCBpbWFnZXM6IEludGVybmFsTGliSW1hZ2VbXSk6IHZvaWQge1xuICAgIGxldCBpbmRleDogbnVtYmVyO1xuICAgIHRyeSB7XG4gICAgICBpbmRleCA9IGdldEluZGV4KGN1cnJlbnRJbWFnZSwgaW1hZ2VzKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHRocm93IGVycjtcbiAgICB9XG4gICAgc3dpdGNoIChpbmRleCkge1xuICAgICAgY2FzZSAwOlxuICAgICAgICAvLyBmaXJzdCBpbWFnZVxuICAgICAgICB0aGlzLnNldEJlZ2lubmluZ0luZGV4ZXNQcmV2aWV3cygpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgaW1hZ2VzLmxlbmd0aCAtIDE6XG4gICAgICAgIC8vIGxhc3QgaW1hZ2VcbiAgICAgICAgdGhpcy5zZXRFbmRJbmRleGVzUHJldmlld3MoKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICAvLyBkZWZhdWx0OlxuICAgICAgLy8gICAvLyBvdGhlciBpbWFnZXNcbiAgICAgIC8vICAgLy8gVE9ETyB1bnVzZWQgYmVjYXVzZSBpdCBzdGFydHMgYWx3YXlzIGF0IGltYWdlIDBcbiAgICAgIC8vICAgdGhpcy5zZXRJbmRleGVzUHJldmlld3MoKTtcbiAgICAgIC8vICAgYnJlYWs7XG4gICAgfVxuICAgIHRoaXMucHJldmlld3MgPSBpbWFnZXMuZmlsdGVyKChpbWc6IEludGVybmFsTGliSW1hZ2UsIGk6IG51bWJlcikgPT4gaSA+PSB0aGlzLnN0YXJ0ICYmIGkgPCB0aGlzLmVuZCk7XG4gIH1cblxuICAvKipcbiAgICogUHJpdmF0ZSBtZXRob2QgdG8gaW5pdCBib3RoIGBzdGFydGAgYW5kIGBlbmRgIHRvIHRoZSBiZWdpbm5pbmcuXG4gICAqL1xuICBwcml2YXRlIHNldEJlZ2lubmluZ0luZGV4ZXNQcmV2aWV3cygpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMucHJldmlld0NvbmZpZyB8fCB0aGlzLnByZXZpZXdDb25maWcubnVtYmVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW50ZXJuYWwgbGlicmFyeSBlcnJvciAtIHByZXZpZXdDb25maWcgYW5kIG51bWJlciBtdXN0IGJlIGRlZmluZWQnKTtcbiAgICB9XG5cbiAgICB0aGlzLnN0YXJ0ID0gMDtcbiAgICB0aGlzLmVuZCA9IE1hdGgubWluKHRoaXMucHJldmlld0NvbmZpZy5udW1iZXIgYXMgbnVtYmVyLCB0aGlzLmltYWdlcy5sZW5ndGgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFByaXZhdGUgbWV0aG9kIHRvIGluaXQgYm90aCBgc3RhcnRgIGFuZCBgZW5kYCB0byB0aGUgZW5kLlxuICAgKi9cbiAgcHJpdmF0ZSBzZXRFbmRJbmRleGVzUHJldmlld3MoKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLnByZXZpZXdDb25maWcgfHwgdGhpcy5wcmV2aWV3Q29uZmlnLm51bWJlciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludGVybmFsIGxpYnJhcnkgZXJyb3IgLSBwcmV2aWV3Q29uZmlnIGFuZCBudW1iZXIgbXVzdCBiZSBkZWZpbmVkJyk7XG4gICAgfVxuXG4gICAgdGhpcy5zdGFydCA9IHRoaXMuaW1hZ2VzLmxlbmd0aCAtIDEgLSAoKHRoaXMucHJldmlld0NvbmZpZy5udW1iZXIgYXMgbnVtYmVyKSAtIDEpO1xuICAgIHRoaXMuZW5kID0gdGhpcy5pbWFnZXMubGVuZ3RoO1xuICB9XG5cbiAgLyoqXG4gICAqIFByaXZhdGUgbWV0aG9kIHRvIHVwZGF0ZSB0aGUgdmlzaWJsZSBwcmV2aWV3cyBuYXZpZ2F0aW5nIHRvIHRoZSByaWdodCAobmV4dCkuXG4gICAqL1xuICBwcml2YXRlIG5leHQoKTogdm9pZCB7XG4gICAgLy8gY2hlY2sgaWYgbmV4dEltYWdlIHNob3VsZCBiZSBibG9ja2VkXG4gICAgaWYgKHRoaXMuaXNQcmV2ZW50U2xpZGluZyh0aGlzLmltYWdlcy5sZW5ndGggLSAxKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmVuZCA9PT0gdGhpcy5pbWFnZXMubGVuZ3RoKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5zdGFydCsrO1xuICAgIHRoaXMuZW5kID0gTWF0aC5taW4odGhpcy5lbmQgKyAxLCB0aGlzLmltYWdlcy5sZW5ndGgpO1xuXG4gICAgdGhpcy5wcmV2aWV3cyA9IHRoaXMuaW1hZ2VzLmZpbHRlcigoaW1nOiBJbnRlcm5hbExpYkltYWdlLCBpOiBudW1iZXIpID0+IGkgPj0gdGhpcy5zdGFydCAmJiBpIDwgdGhpcy5lbmQpO1xuICB9XG5cbiAgLyoqXG4gICAqIFByaXZhdGUgbWV0aG9kIHRvIHVwZGF0ZSB0aGUgdmlzaWJsZSBwcmV2aWV3cyBuYXZpZ2F0aW5nIHRvIHRoZSBsZWZ0IChwcmV2aW91cykuXG4gICAqL1xuICBwcml2YXRlIHByZXZpb3VzKCk6IHZvaWQge1xuICAgIC8vIGNoZWNrIGlmIHByZXZJbWFnZSBzaG91bGQgYmUgYmxvY2tlZFxuICAgIGlmICh0aGlzLmlzUHJldmVudFNsaWRpbmcoMCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5zdGFydCA9PT0gMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuc3RhcnQgPSBNYXRoLm1heCh0aGlzLnN0YXJ0IC0gMSwgMCk7XG4gICAgdGhpcy5lbmQgPSBNYXRoLm1pbih0aGlzLmVuZCAtIDEsIHRoaXMuaW1hZ2VzLmxlbmd0aCk7XG5cbiAgICB0aGlzLnByZXZpZXdzID0gdGhpcy5pbWFnZXMuZmlsdGVyKChpbWc6IEludGVybmFsTGliSW1hZ2UsIGk6IG51bWJlcikgPT4gaSA+PSB0aGlzLnN0YXJ0ICYmIGkgPCB0aGlzLmVuZCk7XG4gIH1cblxuICAvKipcbiAgICogUHJpdmF0ZSBtZXRob2QgdG8gYmxvY2svcGVybWl0IHNsaWRpbmcgYmV0d2VlbiBwcmV2aWV3cy5cbiAgICogQHBhcmFtIG51bWJlciBib3VuZGFyeUluZGV4IGlzIHRoZSBmaXJzdCBvciB0aGUgbGFzdCBpbmRleCBvZiBgaW1hZ2VzYCBpbnB1dCBhcnJheVxuICAgKiBAcmV0dXJucyBib29sZWFuIGlmIHRydWUgYmxvY2sgc2xpZGluZywgb3RoZXJ3aXNlIG5vdFxuICAgKi9cbiAgcHJpdmF0ZSBpc1ByZXZlbnRTbGlkaW5nKGJvdW5kYXJ5SW5kZXg6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgIHJldHVybiBnZXRJbmRleCh0aGlzLmN1cnJlbnRJbWFnZSwgdGhpcy5pbWFnZXMpID09PSBib3VuZGFyeUluZGV4O1xuICB9XG59XG4iLCI8bmF2ICpuZ0lmPVwicHJldmlld0NvbmZpZz8udmlzaWJsZVwiXG4gICAgIGNsYXNzPVwicHJldmlld3MtY29udGFpbmVyXCJcbiAgICAgW2F0dHIuYXJpYS1sYWJlbF09XCJhY2Nlc3NpYmlsaXR5Q29uZmlnPy5jYXJvdXNlbFByZXZpZXdzQ29udGFpbmVyQXJpYUxhYmVsXCJcbiAgICAgW3RpdGxlXT1cImFjY2Vzc2liaWxpdHlDb25maWc/LmNhcm91c2VsUHJldmlld3NDb250YWluZXJUaXRsZVwiPlxuXG4gIDxhIGNsYXNzPVwibmF2LWxlZnRcIlxuICAgICBbYXR0ci5hcmlhLWxhYmVsXT1cImFjY2Vzc2liaWxpdHlDb25maWc/LmNhcm91c2VsUHJldmlld1Njcm9sbFByZXZBcmlhTGFiZWxcIlxuICAgICBbdGFiSW5kZXhdPVwicHJldmlld0NvbmZpZz8uYXJyb3dzICYmIHN0YXJ0ID4gMCA/IDAgOiAtMVwiIHJvbGU9XCJidXR0b25cIlxuICAgICAoY2xpY2spPVwib25OYXZpZ2F0aW9uRXZlbnQoJ2xlZnQnLCAkZXZlbnQpXCIgKGtleXVwKT1cIm9uTmF2aWdhdGlvbkV2ZW50KCdsZWZ0JywgJGV2ZW50KVwiPlxuICAgIDxkaXYgY2xhc3M9XCJpbnNpZGUge3twcmV2aWV3Q29uZmlnPy5hcnJvd3MgJiYgc3RhcnQgPiAwID8gJ2xlZnQtYXJyb3ctcHJldmlldy1pbWFnZScgOiAnZW1wdHktYXJyb3ctcHJldmlldy1pbWFnZSd9fVwiXG4gICAgICAgICBhcmlhLWhpZGRlbj1cInRydWVcIlxuICAgICAgICAgW3RpdGxlXT1cImFjY2Vzc2liaWxpdHlDb25maWc/LmNhcm91c2VsUHJldmlld1Njcm9sbFByZXZUaXRsZVwiPjwvZGl2PlxuICA8L2E+XG5cbiAgPGRpdiBjbGFzcz1cInByZXZpZXctaW5uZXItY29udGFpbmVyXCI+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgcHJldmlldyBvZiBwcmV2aWV3czsgdHJhY2tCeTogdHJhY2tCeUlkOyBsZXQgaW5kZXggPSBpbmRleFwiPlxuICAgICAgPGltZyAqbmdJZj1cInByZXZpZXc/Lm1vZGFsPy5pbWdcIlxuICAgICAgICAgICBjbGFzcz1cImluc2lkZSBwcmV2aWV3LWltYWdle3tpc0FjdGl2ZShwcmV2aWV3KSA/ICcgYWN0aXZlJyA6ICcnfX17eyFwcmV2aWV3Q29uZmlnPy5jbGlja2FibGUgPyAnIHVuY2xpY2thYmxlJyA6ICcnfX1cIlxuICAgICAgICAgICBbc3JjXT1cInByZXZpZXcucGxhaW4/LmltZyA/IHByZXZpZXcucGxhaW4/LmltZyA6IHByZXZpZXcubW9kYWwuaW1nXCJcbiAgICAgICAgICAga3NGYWxsYmFja0ltYWdlIFtmYWxsYmFja0ltZ109XCJwcmV2aWV3LnBsYWluPy5mYWxsYmFja0ltZyA/IHByZXZpZXcucGxhaW4/LmZhbGxiYWNrSW1nIDogcHJldmlldy5tb2RhbC5mYWxsYmFja0ltZ1wiXG4gICAgICAgICAgIGtzU2l6ZSBbc2l6ZUNvbmZpZ109XCJ7d2lkdGg6IHByZXZpZXdDb25maWc/LndpZHRoISxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhlaWdodDogcHJldmlld01heEhlaWdodH1cIlxuICAgICAgICAgICBbYXR0ci5hcmlhLWxhYmVsXT1cImdldEFyaWFMYWJlbChwcmV2aWV3KVwiXG4gICAgICAgICAgIFt0aXRsZV09XCJnZXRUaXRsZShwcmV2aWV3KVwiXG4gICAgICAgICAgIGFsdD1cInt7Z2V0QWx0KHByZXZpZXcpfX1cIlxuICAgICAgICAgICBbdGFiSW5kZXhdPVwiMFwiIHJvbGU9XCJpbWdcIlxuICAgICAgICAgICAoY2xpY2spPVwib25JbWFnZUV2ZW50KHByZXZpZXcsICRldmVudCwgY2xpY2tBY3Rpb24pXCIgKGtleXVwKT1cIm9uSW1hZ2VFdmVudChwcmV2aWV3LCAkZXZlbnQsIGtleWJvYXJkQWN0aW9uKVwiLz5cbiAgICA8L25nLWNvbnRhaW5lcj5cbiAgPC9kaXY+XG5cbiAgPGEgY2xhc3M9XCJuYXYtcmlnaHRcIlxuICAgICBbYXR0ci5hcmlhLWxhYmVsXT1cImFjY2Vzc2liaWxpdHlDb25maWc/LmNhcm91c2VsUHJldmlld1Njcm9sbE5leHRBcmlhTGFiZWxcIlxuICAgICBbdGFiSW5kZXhdPVwicHJldmlld0NvbmZpZz8uYXJyb3dzICYmIGVuZCA8IGltYWdlcy5sZW5ndGggPyAwIDogLTFcIiByb2xlPVwiYnV0dG9uXCJcbiAgICAgKGNsaWNrKT1cIm9uTmF2aWdhdGlvbkV2ZW50KCdyaWdodCcsICRldmVudClcIiAoa2V5dXApPVwib25OYXZpZ2F0aW9uRXZlbnQoJ3JpZ2h0JywgJGV2ZW50KVwiPlxuICAgIDxkaXYgY2xhc3M9XCJpbnNpZGUge3twcmV2aWV3Q29uZmlnPy5hcnJvd3MgJiYgZW5kIDwgaW1hZ2VzLmxlbmd0aCA/ICdyaWdodC1hcnJvdy1wcmV2aWV3LWltYWdlJyA6ICdlbXB0eS1hcnJvdy1wcmV2aWV3LWltYWdlJ319XCJcbiAgICAgICAgIGFyaWEtaGlkZGVuPVwidHJ1ZVwiXG4gICAgICAgICBbdGl0bGVdPVwiYWNjZXNzaWJpbGl0eUNvbmZpZz8uY2Fyb3VzZWxQcmV2aWV3U2Nyb2xsTmV4dFRpdGxlXCI+PC9kaXY+XG4gIDwvYT5cblxuPC9uYXY+XG4iXX0=