@ks89/angular-modal-gallery 8.0.0-beta.5 → 9.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 (161) hide show
  1. package/CHANGELOG.md +153 -0
  2. package/CONTRIBUTING.md +20 -38
  3. package/LICENSE +1 -1
  4. package/README.md +36 -42
  5. package/esm2020/ks89-angular-modal-gallery.mjs +5 -0
  6. package/esm2020/lib/components/accessibility-default.mjs +41 -0
  7. package/esm2020/lib/components/accessible.component.mjs +130 -0
  8. package/esm2020/lib/components/carousel/carousel-previews/carousel-previews.component.mjs +462 -0
  9. package/esm2020/lib/components/carousel/carousel.component.mjs +747 -0
  10. package/esm2020/lib/components/components.mjs +50 -0
  11. package/esm2020/lib/components/current-image/current-image.component.mjs +616 -0
  12. package/esm2020/lib/components/current-image/loading-spinner/loading-spinner.component.mjs +80 -0
  13. package/esm2020/lib/components/dots/dots.component.mjs +127 -0
  14. package/esm2020/lib/components/modal-gallery/modal-gallery-ref.mjs +103 -0
  15. package/esm2020/lib/components/modal-gallery/modal-gallery.component.mjs +523 -0
  16. package/esm2020/lib/components/modal-gallery/modal-gallery.service.mjs +187 -0
  17. package/esm2020/lib/components/modal-gallery/modal-gallery.tokens.mjs +26 -0
  18. package/esm2020/lib/components/plain-gallery/plain-gallery.component.mjs +249 -0
  19. package/esm2020/lib/components/previews/previews.component.mjs +332 -0
  20. package/esm2020/lib/components/upper-buttons/upper-buttons-default.mjs +76 -0
  21. package/esm2020/lib/components/upper-buttons/upper-buttons.component.mjs +249 -0
  22. package/esm2020/lib/directives/a-tag-bg-image.directive.mjs +78 -0
  23. package/esm2020/lib/directives/click-outside.directive.mjs +91 -0
  24. package/esm2020/lib/directives/description.directive.mjs +98 -0
  25. package/esm2020/lib/directives/direction.directive.mjs +73 -0
  26. package/esm2020/lib/directives/directives.mjs +49 -0
  27. package/esm2020/lib/directives/fallback-image.directive.mjs +59 -0
  28. package/esm2020/lib/directives/keyboard-navigation.directive.mjs +58 -0
  29. package/esm2020/lib/directives/margin.directive.mjs +84 -0
  30. package/esm2020/lib/directives/max-size.directive.mjs +75 -0
  31. package/esm2020/lib/directives/size.directive.mjs +76 -0
  32. package/{esm2015/lib/directives/size.directive.js → esm2020/lib/directives/wrap.directive.mjs} +23 -22
  33. package/esm2020/lib/modal-gallery.module.mjs +94 -0
  34. package/esm2020/lib/model/accessibility.interface.mjs +25 -0
  35. package/esm2020/lib/model/action.enum.mjs +36 -0
  36. package/esm2020/lib/model/buttons-config.interface.mjs +62 -0
  37. package/esm2020/lib/model/carousel-config.interface.mjs +25 -0
  38. package/esm2020/lib/model/carousel-image-config.interface.mjs +25 -0
  39. package/esm2020/lib/model/carousel-preview-config.interface.mjs +25 -0
  40. package/{esm2015/lib/model/keyboard-service-config.interface.js → esm2020/lib/model/current-image-config.interface.mjs} +2 -2
  41. package/esm2020/lib/model/description.interface.mjs +33 -0
  42. package/{esm2015/lib/model/preview-config.interface.js → esm2020/lib/model/dots-config.interface.mjs} +2 -2
  43. package/esm2020/lib/model/image-internal.class.mjs +35 -0
  44. package/esm2020/lib/model/image.class.mjs +54 -0
  45. package/esm2020/lib/model/interaction-event.interface.mjs +2 -0
  46. package/esm2020/lib/model/keyboard-config.interface.mjs +25 -0
  47. package/esm2020/lib/model/keyboard-service-config.interface.mjs +25 -0
  48. package/esm2020/lib/model/keyboard.enum.mjs +35 -0
  49. package/esm2020/lib/model/lib-config.interface.mjs +25 -0
  50. package/esm2020/lib/model/loading-config.interface.mjs +37 -0
  51. package/{esm2015/lib/model/dots-config.interface.js → esm2020/lib/model/max-size.interface.mjs} +2 -2
  52. package/{esm2015/lib/model/carousel-preview-config.interface.js → esm2020/lib/model/modal-gallery-config.interface.mjs} +2 -2
  53. package/esm2020/lib/model/plain-gallery-config.interface.mjs +55 -0
  54. package/{esm2015/lib/model/image-internal.class.js → esm2020/lib/model/play-config.interface.mjs} +3 -13
  55. package/esm2020/lib/model/preview-config.interface.mjs +25 -0
  56. package/esm2020/lib/model/size.interface.mjs +25 -0
  57. package/{esm2015/lib/model/carousel-config.interface.js → esm2020/lib/model/slide-config.interface.mjs} +2 -2
  58. package/esm2020/lib/services/config.service.mjs +396 -0
  59. package/esm2020/lib/services/id-validator.service.mjs +71 -0
  60. package/esm2020/lib/services/keyboard.service.mjs +111 -0
  61. package/esm2020/lib/utils/image.util.mjs +48 -0
  62. package/esm2020/lib/utils/user-input.util.mjs +104 -0
  63. package/esm2020/public-api.mjs +42 -0
  64. package/fesm2015/ks89-angular-modal-gallery.mjs +5782 -0
  65. package/fesm2015/ks89-angular-modal-gallery.mjs.map +1 -0
  66. package/{fesm2015/ks89-angular-modal-gallery.js → fesm2020/ks89-angular-modal-gallery.mjs} +3046 -2947
  67. package/fesm2020/ks89-angular-modal-gallery.mjs.map +1 -0
  68. package/ks89-angular-modal-gallery.d.ts +1 -24
  69. package/lib/components/accessible.component.d.ts +5 -2
  70. package/lib/components/carousel/carousel-previews/carousel-previews.component.d.ts +7 -11
  71. package/lib/components/carousel/carousel.component.d.ts +28 -67
  72. package/lib/components/current-image/current-image.component.d.ts +10 -4
  73. package/lib/components/current-image/loading-spinner/loading-spinner.component.d.ts +3 -0
  74. package/lib/components/dots/dots.component.d.ts +7 -0
  75. package/lib/components/modal-gallery/modal-gallery-ref.d.ts +35 -0
  76. package/lib/components/modal-gallery/modal-gallery.component.d.ts +58 -50
  77. package/lib/components/modal-gallery/modal-gallery.service.d.ts +60 -1
  78. package/lib/components/plain-gallery/plain-gallery.component.d.ts +18 -9
  79. package/lib/components/previews/previews.component.d.ts +9 -0
  80. package/lib/components/upper-buttons/upper-buttons.component.d.ts +8 -1
  81. package/lib/directives/a-tag-bg-image.directive.d.ts +3 -0
  82. package/lib/directives/click-outside.directive.d.ts +3 -0
  83. package/lib/directives/description.directive.d.ts +3 -0
  84. package/lib/directives/direction.directive.d.ts +3 -0
  85. package/lib/directives/fallback-image.directive.d.ts +6 -0
  86. package/lib/directives/keyboard-navigation.directive.d.ts +4 -1
  87. package/lib/directives/margin.directive.d.ts +3 -0
  88. package/lib/directives/max-size.directive.d.ts +3 -0
  89. package/lib/directives/size.directive.d.ts +5 -2
  90. package/lib/directives/wrap.directive.d.ts +4 -1
  91. package/lib/modal-gallery.module.d.ts +28 -0
  92. package/lib/model/carousel-config.interface.d.ts +0 -1
  93. package/lib/model/keyboard-config.interface.d.ts +4 -4
  94. package/lib/model/keyboard.enum.d.ts +11 -8
  95. package/lib/model/lib-config.interface.d.ts +20 -7
  96. package/lib/model/modal-gallery-config.interface.d.ts +2 -2
  97. package/lib/model/plain-gallery-config.interface.d.ts +1 -9
  98. package/lib/services/config.service.d.ts +3 -0
  99. package/lib/services/id-validator.service.d.ts +5 -1
  100. package/lib/services/keyboard.service.d.ts +5 -2
  101. package/lib/utils/user-input.util.d.ts +35 -26
  102. package/package.json +28 -16
  103. package/public-api.d.ts +2 -2
  104. package/bundles/ks89-angular-modal-gallery.umd.js +0 -5906
  105. package/bundles/ks89-angular-modal-gallery.umd.js.map +0 -1
  106. package/bundles/ks89-angular-modal-gallery.umd.min.js +0 -16
  107. package/bundles/ks89-angular-modal-gallery.umd.min.js.map +0 -1
  108. package/esm2015/ks89-angular-modal-gallery.js +0 -29
  109. package/esm2015/lib/components/accessibility-default.js +0 -41
  110. package/esm2015/lib/components/accessible.component.js +0 -127
  111. package/esm2015/lib/components/carousel/carousel-previews/carousel-previews.component.js +0 -466
  112. package/esm2015/lib/components/carousel/carousel.component.js +0 -772
  113. package/esm2015/lib/components/components.js +0 -50
  114. package/esm2015/lib/components/current-image/current-image.component.js +0 -590
  115. package/esm2015/lib/components/current-image/loading-spinner/loading-spinner.component.js +0 -80
  116. package/esm2015/lib/components/dots/dots.component.js +0 -127
  117. package/esm2015/lib/components/modal-gallery/modal-gallery-ref.js +0 -45
  118. package/esm2015/lib/components/modal-gallery/modal-gallery.component.js +0 -534
  119. package/esm2015/lib/components/modal-gallery/modal-gallery.service.js +0 -135
  120. package/esm2015/lib/components/modal-gallery/modal-gallery.tokens.js +0 -3
  121. package/esm2015/lib/components/plain-gallery/plain-gallery.component.js +0 -243
  122. package/esm2015/lib/components/previews/previews.component.js +0 -331
  123. package/esm2015/lib/components/upper-buttons/upper-buttons-default.js +0 -76
  124. package/esm2015/lib/components/upper-buttons/upper-buttons.component.js +0 -256
  125. package/esm2015/lib/directives/a-tag-bg-image.directive.js +0 -78
  126. package/esm2015/lib/directives/click-outside.directive.js +0 -85
  127. package/esm2015/lib/directives/description.directive.js +0 -99
  128. package/esm2015/lib/directives/direction.directive.js +0 -73
  129. package/esm2015/lib/directives/directives.js +0 -49
  130. package/esm2015/lib/directives/fallback-image.directive.js +0 -54
  131. package/esm2015/lib/directives/keyboard-navigation.directive.js +0 -52
  132. package/esm2015/lib/directives/margin.directive.js +0 -82
  133. package/esm2015/lib/directives/max-size.directive.js +0 -76
  134. package/esm2015/lib/directives/wrap.directive.js +0 -74
  135. package/esm2015/lib/modal-gallery.module.js +0 -64
  136. package/esm2015/lib/model/accessibility.interface.js +0 -25
  137. package/esm2015/lib/model/action.enum.js +0 -36
  138. package/esm2015/lib/model/buttons-config.interface.js +0 -66
  139. package/esm2015/lib/model/carousel-image-config.interface.js +0 -25
  140. package/esm2015/lib/model/current-image-config.interface.js +0 -25
  141. package/esm2015/lib/model/description.interface.js +0 -33
  142. package/esm2015/lib/model/image.class.js +0 -54
  143. package/esm2015/lib/model/interaction-event.interface.js +0 -2
  144. package/esm2015/lib/model/keyboard-config.interface.js +0 -25
  145. package/esm2015/lib/model/keyboard.enum.js +0 -35
  146. package/esm2015/lib/model/lib-config.interface.js +0 -25
  147. package/esm2015/lib/model/loading-config.interface.js +0 -37
  148. package/esm2015/lib/model/max-size.interface.js +0 -25
  149. package/esm2015/lib/model/modal-gallery-config.interface.js +0 -25
  150. package/esm2015/lib/model/plain-gallery-config.interface.js +0 -64
  151. package/esm2015/lib/model/play-config.interface.js +0 -25
  152. package/esm2015/lib/model/size.interface.js +0 -25
  153. package/esm2015/lib/model/slide-config.interface.js +0 -25
  154. package/esm2015/lib/services/config.service.js +0 -392
  155. package/esm2015/lib/services/id-validator.service.js +0 -71
  156. package/esm2015/lib/services/keyboard.service.js +0 -108
  157. package/esm2015/lib/utils/image.util.js +0 -48
  158. package/esm2015/lib/utils/user-input.util.js +0 -95
  159. package/esm2015/public-api.js +0 -46
  160. package/fesm2015/ks89-angular-modal-gallery.js.map +0 -1
  161. package/ks89-angular-modal-gallery.metadata.json +0 -1
@@ -1,590 +0,0 @@
1
- /*
2
- The MIT License (MIT)
3
-
4
- Copyright (c) 2017-2020 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, ChangeDetectorRef, Component, EventEmitter, HostListener, Inject, Input, NgZone, Output, PLATFORM_ID } from '@angular/core';
25
- import { isPlatformBrowser } from '@angular/common';
26
- import { Subject, timer } from 'rxjs';
27
- import { filter, map, switchMap, takeUntil } from 'rxjs/operators';
28
- import { AccessibleComponent } from '../accessible.component';
29
- import { Action } from '../../model/action.enum';
30
- import { DescriptionStrategy } from '../../model/description.interface';
31
- import { ImageModalEvent } from '../../model/image.class';
32
- import { Keyboard } from '../../model/keyboard.enum';
33
- import { NEXT, PREV } from '../../utils/user-input.util';
34
- import { getIndex } from '../../utils/image.util';
35
- import { ConfigService } from '../../services/config.service';
36
- /**
37
- * Component with the current image with some additional elements like arrows and side previews.
38
- */
39
- export class CurrentImageComponent extends AccessibleComponent {
40
- // tslint:disable-next-line:no-any
41
- constructor(platformId, ngZone, ref, configService) {
42
- super();
43
- this.platformId = platformId;
44
- this.ngZone = ngZone;
45
- this.ref = ref;
46
- this.configService = configService;
47
- /**
48
- * Output to emit an event when images are loaded. The payload contains an `ImageLoadEvent`.
49
- */
50
- this.loadImage = new EventEmitter();
51
- /**
52
- * Output to emit any changes of the current image. The payload contains an `ImageModalEvent`.
53
- */
54
- this.changeImage = new EventEmitter();
55
- /**
56
- * Output to emit an event when the modal gallery is closed. The payload contains an `ImageModalEvent`.
57
- */
58
- this.closeGallery = new EventEmitter();
59
- /**
60
- * Subject to play modal-gallery.
61
- */
62
- this.start$ = new Subject();
63
- /**
64
- * Subject to stop modal-gallery.
65
- */
66
- this.stop$ = new Subject();
67
- /**
68
- * Enum of type `Action` that represents a normal action.
69
- * Declared here to be used inside the template.
70
- */
71
- this.normalAction = Action.NORMAL;
72
- /**
73
- * Enum of type `Action` that represents a mouse click on a button.
74
- * Declared here to be used inside the template.
75
- */
76
- this.clickAction = Action.CLICK;
77
- /**
78
- * Enum of type `Action` that represents a keyboard action.
79
- * Declared here to be used inside the template.
80
- */
81
- this.keyboardAction = Action.KEYBOARD;
82
- /**
83
- * Boolean that it's true when you are watching the first image (currently visible).
84
- * False by default
85
- */
86
- this.isFirstImage = false;
87
- /**
88
- * Boolean that it's true when you are watching the last image (currently visible).
89
- * False by default
90
- */
91
- this.isLastImage = false;
92
- /**
93
- * Boolean that it's true if an image of the modal gallery is still loading.
94
- * True by default
95
- */
96
- this.loading = true;
97
- /**
98
- * Private object without type to define all swipe actions used by hammerjs.
99
- */
100
- this.SWIPE_ACTION = {
101
- LEFT: 'swipeleft',
102
- RIGHT: 'swiperight',
103
- UP: 'swipeup',
104
- DOWN: 'swipedown'
105
- };
106
- }
107
- /**
108
- * Listener to stop the gallery when the mouse pointer is over the current image.
109
- */
110
- onMouseEnter() {
111
- // if carousel feature is disable, don't do anything in any case
112
- if (!this.slideConfig || !this.slideConfig.playConfig) {
113
- return;
114
- }
115
- if (!this.slideConfig.playConfig.pauseOnHover) {
116
- return;
117
- }
118
- this.stopCarousel();
119
- }
120
- /**
121
- * Listener to play the gallery when the mouse pointer leave the current image.
122
- */
123
- onMouseLeave() {
124
- // if carousel feature is disable, don't do anything in any case
125
- if (!this.slideConfig || !this.slideConfig.playConfig) {
126
- return;
127
- }
128
- if (!this.slideConfig.playConfig.pauseOnHover || !this.slideConfig.playConfig.autoPlay) {
129
- return;
130
- }
131
- this.playCarousel();
132
- }
133
- /**
134
- * Method ´ngOnInit´ to init configuration.
135
- * This is an Angular's lifecycle hook, so its called automatically by Angular itself.
136
- * In particular, it's called only one time!!!
137
- */
138
- ngOnInit() {
139
- const libConfig = this.configService.getConfig(this.id);
140
- if (!libConfig || !libConfig.buttonsConfig) {
141
- throw new Error('Internal library error - libConfig and buttonsConfig must be defined');
142
- }
143
- this.slideConfig = libConfig.slideConfig;
144
- this.accessibilityConfig = libConfig.accessibilityConfig;
145
- this.currentImageConfig = libConfig.currentImageConfig;
146
- this.keyboardConfig = libConfig.keyboardConfig;
147
- }
148
- /**
149
- * Method ´ngOnChanges´ to update `loading` status and emit events.
150
- * If the gallery is open, then it will also manage boundary arrows and sliding.
151
- * This is an Angular's lifecycle hook, so its called automatically by Angular itself.
152
- * In particular, it's called when any data-bound property of a directive changes!!!
153
- */
154
- ngOnChanges(changes) {
155
- const libConfig = this.configService.getConfig(this.id);
156
- if (!libConfig) {
157
- throw new Error('Internal library error - libConfig must be defined');
158
- }
159
- const images = changes.images;
160
- const currentImage = changes.currentImage;
161
- if (currentImage && currentImage.previousValue !== currentImage.currentValue) {
162
- this.updateIndexes();
163
- }
164
- else if (images && images.previousValue !== images.currentValue) {
165
- this.updateIndexes();
166
- }
167
- const slideConfig = changes.slideConfig;
168
- if (slideConfig && slideConfig.previousValue !== slideConfig.currentValue) {
169
- this.slideConfig = libConfig.slideConfig;
170
- }
171
- }
172
- ngAfterContentInit() {
173
- // interval doesn't play well with SSR and protractor,
174
- // so we should run it in the browser and outside Angular
175
- if (isPlatformBrowser(this.platformId)) {
176
- this.ngZone.runOutsideAngular(() => {
177
- this.start$
178
- .pipe(map(() => this.slideConfig && this.slideConfig.playConfig && this.slideConfig.playConfig.autoPlay && this.slideConfig.playConfig.interval),
179
- // tslint:disable-next-line:no-any
180
- filter((interval) => interval > 0), switchMap(interval => timer(interval).pipe(takeUntil(this.stop$))))
181
- .subscribe(() => this.ngZone.run(() => {
182
- if (!this.isLastImage) {
183
- this.nextImage(Action.AUTOPLAY);
184
- }
185
- this.ref.markForCheck();
186
- }));
187
- this.start$.next();
188
- });
189
- }
190
- }
191
- /**
192
- * Method to handle keypress based on the `keyboardConfig` input. It gets the keyCode of
193
- * the key that triggered the keypress event to navigate between images or to close the modal gallery.
194
- * @param number keyCode of the key that triggered the keypress event
195
- */
196
- onKeyPress(keyCode) {
197
- const esc = this.keyboardConfig && this.keyboardConfig.esc ? this.keyboardConfig.esc : Keyboard.ESC;
198
- const right = this.keyboardConfig && this.keyboardConfig.right ? this.keyboardConfig.right : Keyboard.RIGHT_ARROW;
199
- const left = this.keyboardConfig && this.keyboardConfig.left ? this.keyboardConfig.left : Keyboard.LEFT_ARROW;
200
- switch (keyCode) {
201
- case esc:
202
- this.closeGallery.emit(new ImageModalEvent(this.id, Action.KEYBOARD, true));
203
- break;
204
- case right:
205
- this.nextImage(Action.KEYBOARD);
206
- break;
207
- case left:
208
- this.prevImage(Action.KEYBOARD);
209
- break;
210
- }
211
- }
212
- /**
213
- * Method to get the image description based on input params.
214
- * If you provide a full description this will be the visible description, otherwise,
215
- * it will be built using the `Description` object, concatenating its fields.
216
- * @param Image image to get its description. If not provided it will be the current image
217
- * @returns String description of the image (or the current image if not provided)
218
- * @throws an Error if description isn't available
219
- */
220
- getDescriptionToDisplay(image = this.currentImage) {
221
- if (!this.currentImageConfig || !this.currentImageConfig.description) {
222
- throw new Error('Description input must be a valid object implementing the Description interface');
223
- }
224
- const imageWithoutDescription = !image.modal || !image.modal.description || image.modal.description === '';
225
- switch (this.currentImageConfig.description.strategy) {
226
- case DescriptionStrategy.HIDE_IF_EMPTY:
227
- return imageWithoutDescription ? '' : image.modal.description + '';
228
- case DescriptionStrategy.ALWAYS_HIDDEN:
229
- return '';
230
- default:
231
- // ----------- DescriptionStrategy.ALWAYS_VISIBLE -----------------
232
- return this.buildTextDescription(image, imageWithoutDescription);
233
- }
234
- }
235
- /**
236
- * Method to get `alt attribute`.
237
- * `alt` specifies an alternate text for an image, if the image cannot be displayed.
238
- * @param Image image to get its alt description. If not provided it will be the current image
239
- * @returns String alt description of the image (or the current image if not provided)
240
- */
241
- getAltDescriptionByImage(image = this.currentImage) {
242
- if (!image) {
243
- return '';
244
- }
245
- return image.modal && image.modal.description ? image.modal.description : `Image ${getIndex(image, this.images) + 1}`;
246
- }
247
- /**
248
- * Method to get the title attributes based on descriptions.
249
- * This is useful to prevent accessibility issues, because if DescriptionStrategy is ALWAYS_HIDDEN,
250
- * it prevents an empty string as title.
251
- * @param Image image to get its description. If not provided it will be the current image
252
- * @returns String title of the image based on descriptions
253
- * @throws an Error if description isn't available
254
- */
255
- getTitleToDisplay(image = this.currentImage) {
256
- if (!this.currentImageConfig || !this.currentImageConfig.description) {
257
- throw new Error('Description input must be a valid object implementing the Description interface');
258
- }
259
- const imageWithoutDescription = !image.modal || !image.modal.description || image.modal.description === '';
260
- const description = this.buildTextDescription(image, imageWithoutDescription);
261
- return description;
262
- }
263
- /**
264
- * Method to get the left side preview image.
265
- * @returns Image the image to show as size preview on the left
266
- */
267
- getLeftPreviewImage() {
268
- if (!this.slideConfig) {
269
- throw new Error('Internal library error - slideConfig must be defined');
270
- }
271
- const currentIndex = getIndex(this.currentImage, this.images);
272
- if (currentIndex === 0 && this.slideConfig.infinite) {
273
- // the current image is the first one,
274
- // so the previous one is the last image
275
- // because infinite is true
276
- return this.images[this.images.length - 1];
277
- }
278
- this.handleBoundaries(currentIndex);
279
- return this.images[Math.max(currentIndex - 1, 0)];
280
- }
281
- /**
282
- * Method to get the right side preview image.
283
- * @returns Image the image to show as size preview on the right
284
- */
285
- getRightPreviewImage() {
286
- if (!this.slideConfig) {
287
- throw new Error('Internal library error - slideConfig must be defined');
288
- }
289
- const currentIndex = getIndex(this.currentImage, this.images);
290
- if (currentIndex === this.images.length - 1 && this.slideConfig.infinite) {
291
- // the current image is the last one,
292
- // so the next one is the first image
293
- // because infinite is true
294
- return this.images[0];
295
- }
296
- this.handleBoundaries(currentIndex);
297
- return this.images[Math.min(currentIndex + 1, this.images.length - 1)];
298
- }
299
- /**
300
- * Method called by events from both keyboard and mouse on an image.
301
- * This will invoke the nextImage method.
302
- * @param KeyboardEvent | MouseEvent event payload
303
- * @param Action action that triggered the event or `Action.NORMAL` if not provided
304
- */
305
- onImageEvent(event, action = Action.NORMAL) {
306
- if (!this.currentImageConfig) {
307
- throw new Error('Internal library error - currentImageConfig must be defined');
308
- }
309
- // check if triggered by a mouse click
310
- // If yes, It should block navigation when navigateOnClick is false
311
- if (action === Action.CLICK && !this.currentImageConfig.navigateOnClick) {
312
- // a user has requested to block navigation via configCurrentImage.navigateOnClick property
313
- return;
314
- }
315
- const result = super.handleImageEvent(event);
316
- if (result === NEXT) {
317
- this.nextImage(action);
318
- }
319
- }
320
- /**
321
- * Method called by events from both keyboard and mouse on a navigation arrow.
322
- * @param string direction of the navigation that can be either 'next' or 'prev'
323
- * @param KeyboardEvent | MouseEvent event payload
324
- * @param Action action that triggered the event or `Action.NORMAL` if not provided
325
- * @param boolean disable to disable navigation
326
- */
327
- onNavigationEvent(direction, event, action = Action.NORMAL, disable = false) {
328
- if (disable) {
329
- return;
330
- }
331
- const result = super.handleNavigationEvent(direction, event);
332
- if (result === NEXT) {
333
- this.nextImage(action);
334
- }
335
- else if (result === PREV) {
336
- this.prevImage(action);
337
- }
338
- }
339
- /**
340
- * Method to go back to the previous image.
341
- * @param action Enum of type `Action` that represents the source
342
- * action that moved back to the previous image. `Action.NORMAL` by default.
343
- */
344
- prevImage(action = Action.NORMAL) {
345
- // check if prevImage should be blocked
346
- if (this.isPreventSliding(0)) {
347
- return;
348
- }
349
- const prevImage = this.getPrevImage();
350
- this.loading = !prevImage.previouslyLoaded;
351
- this.changeImage.emit(new ImageModalEvent(this.id, action, getIndex(prevImage, this.images)));
352
- this.start$.next();
353
- }
354
- /**
355
- * Method to go back to the previous image.
356
- * @param action Enum of type `Action` that represents the source
357
- * action that moved to the next image. `Action.NORMAL` by default.
358
- */
359
- nextImage(action = Action.NORMAL) {
360
- // check if nextImage should be blocked
361
- if (this.isPreventSliding(this.images.length - 1)) {
362
- return;
363
- }
364
- const nextImage = this.getNextImage();
365
- this.loading = !nextImage.previouslyLoaded;
366
- this.changeImage.emit(new ImageModalEvent(this.id, action, getIndex(nextImage, this.images)));
367
- this.start$.next();
368
- }
369
- /**
370
- * Method to emit an event as loadImage output to say that the requested image if loaded.
371
- * This method is invoked by the javascript's 'load' event on an img tag.
372
- * @param Event event that triggered the load
373
- */
374
- onImageLoad(event) {
375
- const loadImageData = {
376
- status: true,
377
- index: getIndex(this.currentImage, this.images),
378
- id: this.currentImage.id
379
- };
380
- this.loadImage.emit(loadImageData);
381
- this.loading = false;
382
- }
383
- /**
384
- * Method used by Hammerjs to support touch gestures (you can also invert the swipe direction with configCurrentImage.invertSwipe).
385
- * @param action String that represent the direction of the swipe action. 'swiperight' by default.
386
- */
387
- swipe(action = this.SWIPE_ACTION.RIGHT) {
388
- if (!this.currentImageConfig) {
389
- throw new Error('Internal library error - currentImageConfig must be defined');
390
- }
391
- switch (action) {
392
- case this.SWIPE_ACTION.RIGHT:
393
- if (this.currentImageConfig.invertSwipe) {
394
- this.prevImage(Action.SWIPE);
395
- }
396
- else {
397
- this.nextImage(Action.SWIPE);
398
- }
399
- break;
400
- case this.SWIPE_ACTION.LEFT:
401
- if (this.currentImageConfig.invertSwipe) {
402
- this.nextImage(Action.SWIPE);
403
- }
404
- else {
405
- this.prevImage(Action.SWIPE);
406
- }
407
- break;
408
- // case this.SWIPE_ACTION.UP:
409
- // break;
410
- // case this.SWIPE_ACTION.DOWN:
411
- // break;
412
- }
413
- }
414
- /**
415
- * Method used in `modal-gallery.component` to get the index of an image to delete.
416
- * @param Image image to get the index, or the visible image, if not passed
417
- * @returns number the index of the image
418
- */
419
- getIndexToDelete(image = this.currentImage) {
420
- return getIndex(image, this.images);
421
- }
422
- /**
423
- * Method to play modal gallery.
424
- */
425
- playCarousel() {
426
- this.start$.next();
427
- }
428
- /**
429
- * Stops modal gallery from cycling through items.
430
- */
431
- stopCarousel() {
432
- this.stop$.next();
433
- }
434
- /**
435
- * Method to cleanup resources. In fact, this will stop the modal gallery.
436
- * This is an Angular's lifecycle hook that is called when this component is destroyed.
437
- */
438
- ngOnDestroy() {
439
- this.stopCarousel();
440
- }
441
- /**
442
- * Private method to update both `isFirstImage` and `isLastImage` based on
443
- * the index of the current image.
444
- * @param number currentIndex is the index of the current image
445
- */
446
- handleBoundaries(currentIndex) {
447
- if (this.images.length === 1) {
448
- this.isFirstImage = true;
449
- this.isLastImage = true;
450
- return;
451
- }
452
- if (!this.slideConfig || this.slideConfig.infinite === true) {
453
- // infinite sliding enabled
454
- this.isFirstImage = false;
455
- this.isLastImage = false;
456
- }
457
- else {
458
- switch (currentIndex) {
459
- case 0:
460
- // execute this only if infinite sliding is disabled
461
- this.isFirstImage = true;
462
- this.isLastImage = false;
463
- break;
464
- case this.images.length - 1:
465
- // execute this only if infinite sliding is disabled
466
- this.isFirstImage = false;
467
- this.isLastImage = true;
468
- break;
469
- default:
470
- this.isFirstImage = false;
471
- this.isLastImage = false;
472
- break;
473
- }
474
- }
475
- }
476
- /**
477
- * Private method to check if next/prev actions should be blocked.
478
- * It checks if slideConfig.infinite === false and if the image index is equals to the input parameter.
479
- * If yes, it returns true to say that sliding should be blocked, otherwise not.
480
- * @param number boundaryIndex that could be either the beginning index (0) or the last index
481
- * of images (this.images.length - 1).
482
- * @returns boolean true if slideConfig.infinite === false and the current index is
483
- * either the first or the last one.
484
- */
485
- isPreventSliding(boundaryIndex) {
486
- return !!this.slideConfig && this.slideConfig.infinite === false && getIndex(this.currentImage, this.images) === boundaryIndex;
487
- }
488
- /**
489
- * Private method to get the next index.
490
- * This is necessary because at the end, when you call next again, you'll go to the first image.
491
- * That happens because all modal images are shown like in a circle.
492
- */
493
- getNextImage() {
494
- const currentIndex = getIndex(this.currentImage, this.images);
495
- let newIndex = 0;
496
- if (currentIndex >= 0 && currentIndex < this.images.length - 1) {
497
- newIndex = currentIndex + 1;
498
- }
499
- else {
500
- newIndex = 0; // start from the first index
501
- }
502
- return this.images[newIndex];
503
- }
504
- /**
505
- * Private method to get the previous index.
506
- * This is necessary because at index 0, when you call prev again, you'll go to the last image.
507
- * That happens because all modal images are shown like in a circle.
508
- */
509
- getPrevImage() {
510
- const currentIndex = getIndex(this.currentImage, this.images);
511
- let newIndex = 0;
512
- if (currentIndex > 0 && currentIndex <= this.images.length - 1) {
513
- newIndex = currentIndex - 1;
514
- }
515
- else {
516
- newIndex = this.images.length - 1; // start from the last index
517
- }
518
- return this.images[newIndex];
519
- }
520
- /**
521
- * Private method to build a text description.
522
- * This is used also to create titles.
523
- * @param Image image to get its description. If not provided it will be the current image.
524
- * @param boolean imageWithoutDescription is a boolean that it's true if the image hasn't a 'modal' description.
525
- * @returns String description built concatenating image fields with a specific logic.
526
- */
527
- buildTextDescription(image, imageWithoutDescription) {
528
- if (!this.currentImageConfig || !this.currentImageConfig.description) {
529
- throw new Error('Description input must be a valid object implementing the Description interface');
530
- }
531
- // If customFullDescription use it, otherwise proceed to build a description
532
- if (this.currentImageConfig.description.customFullDescription && this.currentImageConfig.description.customFullDescription !== '') {
533
- return this.currentImageConfig.description.customFullDescription;
534
- }
535
- const currentIndex = getIndex(image, this.images);
536
- // If the current image hasn't a description,
537
- // prevent to write the ' - ' (or this.description.beforeTextDescription)
538
- const prevDescription = this.currentImageConfig.description.imageText ? this.currentImageConfig.description.imageText : '';
539
- const midSeparator = this.currentImageConfig.description.numberSeparator ? this.currentImageConfig.description.numberSeparator : '';
540
- const middleDescription = currentIndex + 1 + midSeparator + this.images.length;
541
- if (imageWithoutDescription) {
542
- return prevDescription + middleDescription;
543
- }
544
- const currImgDescription = image.modal && image.modal.description ? image.modal.description : '';
545
- const endDescription = this.currentImageConfig.description.beforeTextDescription + currImgDescription;
546
- return prevDescription + middleDescription + endDescription;
547
- }
548
- /**
549
- * Private method to call handleBoundaries when ngOnChanges is called.
550
- */
551
- updateIndexes() {
552
- let index;
553
- try {
554
- index = getIndex(this.currentImage, this.images);
555
- }
556
- catch (err) {
557
- console.error('Cannot get the current image index in current-image');
558
- throw err;
559
- }
560
- if (this.isOpen) {
561
- this.handleBoundaries(index);
562
- }
563
- }
564
- }
565
- CurrentImageComponent.decorators = [
566
- { type: Component, args: [{
567
- selector: 'ks-current-image',
568
- template: "<main class=\"main-image-container\"\n ksKeyboardNavigation [isOpen]=\"isOpen\" (keyboardNavigation)=\"onKeyPress($event)\"\n [attr.aria-label]=\"accessibilityConfig.mainContainerAriaLabel\"\n [title]=\"accessibilityConfig.mainContainerTitle\">\n\n <div class=\"left-sub-container\">\n <a class=\"nav-left {{isFirstImage ? 'no-pointer' : ''}}\"\n [attr.aria-label]=\"accessibilityConfig.mainPrevImageAriaLabel\"\n [tabIndex]=\"isFirstImage ? -1 : 0\" role=\"button\"\n (click)=\"onNavigationEvent('left', $event)\" (keyup)=\"onNavigationEvent('left', $event)\">\n <div class=\"inside {{isFirstImage ? 'empty-arrow-image' : 'left-arrow-image'}}\"\n aria-hidden=\"true\"\n [title]=\"isFirstImage ? '' : accessibilityConfig.mainPrevImageTitle\"></div>\n </a>\n\n <ng-container *ngIf=\"slideConfig?.sidePreviews?.show\">\n <ng-container *ngIf=\"getLeftPreviewImage() as leftPreview\">\n <img *ngIf=\"!isFirstImage; else firstImage\"\n class=\"inside current-image-previous\"\n [src]=\"leftPreview.plain?.img ? leftPreview.plain.img : leftPreview.modal.img\"\n ksFallbackImage [fallbackImg]=\"leftPreview.plain?.fallbackImg ? leftPreview.plain.fallbackImg : leftPreview.modal.fallbackImg\"\n [hidden]=\"loading\"\n ksSize [sizeConfig]=\"{width: slideConfig.sidePreviews?.size.width, height: slideConfig.sidePreviews?.size.height}\"\n [attr.aria-label]=\"leftPreview.modal.ariaLabel\"\n [title]=\"(leftPreview.modal.title || leftPreview.modal.title === '') ? leftPreview.modal.title : getDescriptionToDisplay(leftPreview)\"\n alt=\"{{leftPreview.modal.alt ? leftPreview.modal.alt : getAltDescriptionByImage(leftPreview)}}\"\n [tabIndex]=\"0\" role=\"img\"\n (click)=\"onNavigationEvent('left', $event, clickAction)\" (keyup)=\"onNavigationEvent('left', $event, keyboardAction)\"/>\n <ng-template #firstImage>\n <div class=\"current-image-previous hidden\"\n ksSize [sizeConfig]=\"{width: slideConfig.sidePreviews?.size.width, height: slideConfig.sidePreviews?.size.height}\"></div>\n </ng-template>\n </ng-container>\n </ng-container>\n </div>\n\n\n <figure id=\"current-figure\" [style.display]=\"loading ? 'none' : ''\">\n <img id=\"current-image\"\n class=\"inside\"\n [ngClass]=\"currentImageConfig.navigateOnClick ? '' : 'unclickable'\"\n [src]=\"currentImage.modal.img\"\n ksFallbackImage [fallbackImg]=\"currentImage.modal.fallbackImg\"\n [attr.aria-label]=\"currentImage.modal.ariaLabel\"\n [title]=\"(currentImage.modal.title || currentImage.modal.title === '') ? currentImage.modal.title : getTitleToDisplay()\"\n alt=\"{{currentImage.modal.alt ? currentImage.modal.alt : getAltDescriptionByImage()}}\"\n [tabIndex]=\"0\" role=\"img\"\n (load)=\"onImageLoad($event)\"\n (click)=\"onImageEvent($event, clickAction)\" (keyup)=\"onImageEvent($event, keyboardAction)\"\n (swipeleft)=\"swipe($event.type)\"\n (swiperight)=\"swipe($event.type)\"/>\n <figcaption *ngIf=\"getDescriptionToDisplay() !== ''\"\n class=\"inside description\"\n ksDescription [description]=\"currentImageConfig?.description\"\n [innerHTML]=\"getDescriptionToDisplay()\">\n </figcaption>\n </figure>\n\n <div class=\"right-sub-container\">\n <ng-container *ngIf=\"slideConfig?.sidePreviews?.show\">\n <ng-container *ngIf=\"getRightPreviewImage() as rightPreview\">\n <img *ngIf=\"!isLastImage; else lastImage\"\n class=\"inside current-image-next\"\n [src]=\"rightPreview.plain?.img ? rightPreview.plain.img : rightPreview.modal.img\"\n ksFallbackImage [fallbackImg]=\"rightPreview.plain?.fallbackImg ? rightPreview.plain.fallbackImg : rightPreview.modal.fallbackImg\"\n [hidden]=\"loading\"\n ksSize [sizeConfig]=\"{width: slideConfig.sidePreviews?.size.width, height: slideConfig.sidePreviews?.size.height}\"\n [attr.aria-label]=\"rightPreview.modal.ariaLabel\"\n [title]=\"(rightPreview.modal.title || rightPreview.modal.title === '') ? rightPreview.modal.title : getDescriptionToDisplay(rightPreview)\"\n alt=\"{{rightPreview.modal.alt ? rightPreview.modal.alt : getAltDescriptionByImage(rightPreview)}}\"\n [tabIndex]=\"0\" role=\"img\"\n (click)=\"onNavigationEvent('right', $event, clickAction)\" (keyup)=\"onNavigationEvent('right', $event, keyboardAction)\"/>\n <ng-template #lastImage>\n <div class=\"current-image-next hidden\"\n ksSize [sizeConfig]=\"{width: slideConfig.sidePreviews?.size.width, height: slideConfig.sidePreviews?.size.height}\">\n </div>\n </ng-template>\n </ng-container>\n </ng-container>\n\n <ng-container *ngIf=\"loading && currentImageConfig?.loadingConfig?.enable\">\n <ks-loading-spinner [loadingConfig]=\"currentImageConfig?.loadingConfig\"\n [accessibilityConfig]=\"accessibilityConfig\"></ks-loading-spinner>\n </ng-container>\n\n <a class=\"nav-right {{isFirstImage ? 'no-pointer' : ''}}\"\n [attr.aria-label]=\"accessibilityConfig.mainNextImageAriaLabel\"\n [tabIndex]=\"isLastImage ? -1 : 0\" role=\"button\"\n (click)=\"onNavigationEvent('right', $event)\" (keyup)=\"onNavigationEvent('right', $event)\">\n <div class=\"inside {{isLastImage ? 'empty-arrow-image' : 'right-arrow-image'}}\"\n aria-hidden=\"true\"\n [title]=\"isLastImage ? '' : accessibilityConfig.mainNextImageTitle\"></div>\n </a>\n </div>\n</main>\n",
569
- changeDetection: ChangeDetectionStrategy.OnPush,
570
- styles: [":host{display:flex;flex-direction:column;justify-content:center}.main-image-container{align-items:center;display:flex;flex-direction:row;justify-content:space-between}.main-image-container .nav,.main-image-container>.left-sub-container>.nav-left,.main-image-container>.right-sub-container>.nav-right{animation:animatezoom 1s;cursor:pointer;transition:all .5s}.main-image-container .nav:hover,.main-image-container>.left-sub-container>.nav-left:hover,.main-image-container>.right-sub-container>.nav-right:hover{transform:scale(1.1)}.main-image-container>.left-sub-container{align-items:center;display:flex;flex-direction:row;justify-content:space-around}.main-image-container>.left-sub-container>.nav-left{margin-left:15px;margin-right:5px}.main-image-container>.left-sub-container>.nav-left.no-pointer{cursor:default!important}.main-image-container>.right-sub-container{align-items:center;display:flex;flex-direction:row;justify-content:space-around}.main-image-container>.right-sub-container>.nav-right{margin-left:5px;margin-right:15px}.main-image-container>.right-sub-container>.nav-right.no-pointer{cursor:default!important}.main-image-container #current-figure{animation:fadein-visible .8s;margin:0;position:relative;text-align:center}.main-image-container #current-figure>#current-image{display:block;height:auto;max-width:100%}.main-image-container #current-figure>#current-image.unclickable{cursor:not-allowed}.main-image-container #current-figure figcaption{bottom:0;left:0;padding:10px;position:absolute;right:0}.main-image-container #current-figure figcaption .description{font-weight:700;text-align:center}#current-image{cursor:pointer;height:auto;max-height:60vh;max-width:80vw}@media screen and (min-width:70vw){#current-image{max-width:70vw}}@keyframes fadein-visible{0%{opacity:0}to{opacity:1}}@keyframes fadein-semi-visible05{0%{opacity:0}to{opacity:.5}}@keyframes fadein-semi-visible08{0%{opacity:0}to{opacity:.8}}@keyframes fadein-semi-visible09{0%{opacity:0}to{opacity:.9}}", ".arrow-image,.empty-arrow-image,.left-arrow-image,.right-arrow-image{background-size:30px;height:30px;width:30px}.empty-arrow-image{background:#000;opacity:0}.left-arrow-image{background-image:url(\"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgdmlld0JveD0iMCAwIDQ3Ny4xNzUgNDc3LjE3NSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgNDc3LjE3NSA0NzcuMTc1OyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSIgd2lkdGg9IjUxMnB4IiBoZWlnaHQ9IjUxMnB4Ij48Zz48cGF0aCBkPSJNMTQ1LjE4OCwyMzguNTc1bDIxNS41LTIxNS41YzUuMy01LjMsNS4zLTEzLjgsMC0xOS4xcy0xMy44LTUuMy0xOS4xLDBsLTIyNS4xLDIyNS4xYy01LjMsNS4zLTUuMywxMy44LDAsMTkuMWwyMjUuMSwyMjUgICBjMi42LDIuNiw2LjEsNCw5LjUsNHM2LjktMS4zLDkuNS00YzUuMy01LjMsNS4zLTEzLjgsMC0xOS4xTDE0NS4xODgsMjM4LjU3NXoiIGZpbGw9IiNGRkZGRkYiLz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PC9zdmc+\");opacity:.8;transition:all .5s}.left-arrow-image:hover{transform:scale(1.2)}.right-arrow-image{background-image:url(\"data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/PjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iQ2FwYV8xIiB4PSIwcHgiIHk9IjBweCIgdmlld0JveD0iMCAwIDQ3Ny4xNzUgNDc3LjE3NSIgc3R5bGU9ImVuYWJsZS1iYWNrZ3JvdW5kOm5ldyAwIDAgNDc3LjE3NSA0NzcuMTc1OyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSIgd2lkdGg9IjUxMnB4IiBoZWlnaHQ9IjUxMnB4Ij48Zz48cGF0aCBkPSJNMzYwLjczMSwyMjkuMDc1bC0yMjUuMS0yMjUuMWMtNS4zLTUuMy0xMy44LTUuMy0xOS4xLDBzLTUuMywxMy44LDAsMTkuMWwyMTUuNSwyMTUuNWwtMjE1LjUsMjE1LjUgICBjLTUuMyw1LjMtNS4zLDEzLjgsMCwxOS4xYzIuNiwyLjYsNi4xLDQsOS41LDRjMy40LDAsNi45LTEuMyw5LjUtNGwyMjUuMS0yMjUuMUMzNjUuOTMxLDI0Mi44NzUsMzY1LjkzMSwyMzQuMjc1LDM2MC43MzEsMjI5LjA3NXogICAiIGZpbGw9IiNGRkZGRkYiLz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PGc+PC9nPjxnPjwvZz48Zz48L2c+PC9zdmc+\");opacity:.8;transition:all .5s}.right-arrow-image:hover{transform:scale(1.2)}", "@media only screen and (max-device-width:1024px),only screen and (max-width:1024px){.current-image-next,.current-image-previous{display:none}}@media only screen and (min-device-width:1025px){.current-image-next,.current-image-preview,.current-image-previous{animation:fadein-semi-visible05 .8s;cursor:pointer;filter:alpha(opacity=50);height:auto;opacity:.5}.current-image-next:hover,.current-image-preview:hover,.current-image-previous:hover{opacity:1;transition:all .5s ease;transition-property:opacity}.current-image-previous{margin-left:10px;margin-right:5px}.current-image-next{margin-left:5px;margin-right:10px}}@keyframes fadein-semi-visible05{0%{opacity:0}to{opacity:.5}}"]
571
- },] }
572
- ];
573
- CurrentImageComponent.ctorParameters = () => [
574
- { type: undefined, decorators: [{ type: Inject, args: [PLATFORM_ID,] }] },
575
- { type: NgZone },
576
- { type: ChangeDetectorRef },
577
- { type: ConfigService }
578
- ];
579
- CurrentImageComponent.propDecorators = {
580
- id: [{ type: Input }],
581
- currentImage: [{ type: Input }],
582
- images: [{ type: Input }],
583
- isOpen: [{ type: Input }],
584
- loadImage: [{ type: Output }],
585
- changeImage: [{ type: Output }],
586
- closeGallery: [{ type: Output }],
587
- onMouseEnter: [{ type: HostListener, args: ['mouseenter',] }],
588
- onMouseLeave: [{ type: HostListener, args: ['mouseleave',] }]
589
- };
590
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3VycmVudC1pbWFnZS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiLi4vLi4vLi4vLi4vcHJvamVjdHMva3M4OS9hbmd1bGFyLW1vZGFsLWdhbGxlcnkvc3JjLyIsInNvdXJjZXMiOlsibGliL2NvbXBvbmVudHMvY3VycmVudC1pbWFnZS9jdXJyZW50LWltYWdlLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXNCRztBQUVILE9BQU8sRUFFTCx1QkFBdUIsRUFDdkIsaUJBQWlCLEVBQ2pCLFNBQVMsRUFDVCxZQUFZLEVBQ1osWUFBWSxFQUNaLE1BQU0sRUFDTixLQUFLLEVBQ0wsTUFBTSxFQUlOLE1BQU0sRUFDTixXQUFXLEVBR1osTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFFcEQsT0FBTyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDdEMsT0FBTyxFQUFFLE1BQU0sRUFBRSxHQUFHLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRW5FLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBRzlELE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNqRCxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQztBQUN4RSxPQUFPLEVBQVMsZUFBZSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFFakUsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBSXJELE9BQU8sRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDekQsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBRWxELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSwrQkFBK0Is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QUFLO3FCQU9MLEtBQUs7d0JBT0wsTUFBTTswQkFLTixNQUFNOzJCQUtOLE1BQU07MkJBK0VOLFlBQVksU0FBQyxZQUFZOzJCQWV6QixZQUFZLFNBQUMsWUFBWSIsInNvdXJjZXNDb250ZW50IjpbIi8qXG4gVGhlIE1JVCBMaWNlbnNlIChNSVQpXG5cbiBDb3B5cmlnaHQgKGMpIDIwMTctMjAyMCBTdGVmYW5vIENhcHBhIChLczg5KVxuXG4gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGEgY29weVxuIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksIHRvIGRlYWxcbiBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzXG4gdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbFxuIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpc1xuIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG5cbiBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpbiBhbGxcbiBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuXG4gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUlxuIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT04gSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEVcbiBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSXG4gTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSxcbiBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRVxuIFNPRlRXQVJFLlxuICovXG5cbmltcG9ydCB7XG4gIEFmdGVyQ29udGVudEluaXQsXG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50LFxuICBFdmVudEVtaXR0ZXIsXG4gIEhvc3RMaXN0ZW5lcixcbiAgSW5qZWN0LFxuICBJbnB1dCxcbiAgTmdab25lLFxuICBPbkNoYW5nZXMsXG4gIE9uRGVzdHJveSxcbiAgT25Jbml0LFxuICBPdXRwdXQsXG4gIFBMQVRGT1JNX0lELFxuICBTaW1wbGVDaGFuZ2UsXG4gIFNpbXBsZUNoYW5nZXNcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBpc1BsYXRmb3JtQnJvd3NlciB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5cbmltcG9ydCB7IFN1YmplY3QsIHRpbWVyIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBmaWx0ZXIsIG1hcCwgc3dpdGNoTWFwLCB0YWtlVW50aWwgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7IEFjY2Vzc2libGVDb21wb25lbnQgfSBmcm9tICcuLi9hY2Nlc3NpYmxlLmNvbXBvbmVudCc7XG5cbmltcG9ydCB7IEFjY2Vzc2liaWxpdHlDb25maWcgfSBmcm9tICcuLi8uLi9tb2RlbC9hY2Nlc3NpYmlsaXR5LmludGVyZmFjZSc7XG5pbXBvcnQgeyBBY3Rpb24gfSBmcm9tICcuLi8uLi9tb2RlbC9hY3Rpb24uZW51bSc7XG5pbXBvcnQgeyBEZXNjcmlwdGlvblN0cmF0ZWd5IH0gZnJvbSAnLi4vLi4vbW9kZWwvZGVzY3JpcHRpb24uaW50ZXJmYWNlJztcbmltcG9ydCB7IEltYWdlLCBJbWFnZU1vZGFsRXZlbnQgfSBmcm9tICcuLi8uLi9tb2RlbC9pbWFnZS5jbGFzcyc7XG5pbXBvcnQgeyBJbnRlcm5hbExpYkltYWdlIH0gZnJvbSAnLi4vLi4vbW9kZWwvaW1hZ2UtaW50ZXJuYWwuY2xhc3MnO1xuaW1wb3J0IHsgS2V5Ym9hcmQgfSBmcm9tICcuLi8uLi9tb2RlbC9rZXlib2FyZC5lbnVtJztcbmltcG9ydCB7IEtleWJvYXJkQ29uZmlnIH0gZnJvbSAnLi4vLi4vbW9kZWwva2V5Ym9hcmQtY29uZmlnLmludGVyZmFjZSc7XG5pbXBvcnQgeyBTbGlkZUNvbmZpZyB9IGZyb20gJy4uLy4uL21vZGVsL3NsaWRlLWNvbmZpZy5pbnRlcmZhY2UnO1xuXG5pbXBvcnQgeyBORVhULCBQUkVWIH0gZnJvbSAnLi4vLi4vdXRpbHMvdXNlci1pbnB1dC51dGlsJztcbmltcG9ydCB7IGdldEluZGV4IH0gZnJvbSAnLi4vLi4vdXRpbHMvaW1hZ2UudXRpbCc7XG5pbXBvcnQgeyBDdXJyZW50SW1hZ2VDb25maWcgfSBmcm9tICcuLi8uLi9tb2RlbC9jdXJyZW50LWltYWdlLWNvbmZpZy5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgQ29uZmlnU2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL2NvbmZpZy5zZXJ2aWNlJztcbmltcG9ydCB7IExpYkNvbmZpZyB9IGZyb20gJy4uLy4uL21vZGVsL2xpYi1jb25maWcuaW50ZXJmYWNlJztcblxuLyoqXG4gKiBJbnRlcmZhY2UgdG8gZGVzY3JpYmUgdGhlIExvYWQgRXZlbnQsIHVzZWQgdG9cbiAqIGVtaXQgYW4gZXZlbnQgd2hlbiB0aGUgaW1hZ2UgaXMgZmluYWxseSBsb2FkZWQgYW5kIHRoZSBzcGlubmVyIGhhcyBnb25lLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEltYWdlTG9hZEV2ZW50IHtcbiAgc3RhdHVzOiBib29sZWFuO1xuICBpbmRleDogbnVtYmVyO1xuICBpZDogbnVtYmVyO1xufVxuXG4vKipcbiAqIENvbXBvbmVudCB3aXRoIHRoZSBjdXJyZW50IGltYWdlIHdpdGggc29tZSBhZGRpdGlvbmFsIGVsZW1lbnRzIGxpa2UgYXJyb3dzIGFuZCBzaWRlIHByZXZpZXdzLlxuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdrcy1jdXJyZW50LWltYWdlJyxcbiAgc3R5bGVVcmxzOiBbJ2N1cnJlbnQtaW1hZ2Uuc2NzcycsICcuLi9pbWFnZS1hcnJvd3Muc2NzcycsICdjdXJyZW50LWltYWdlLXByZXZpZXdzLnNjc3MnXSxcbiAgdGVtcGxhdGVVcmw6ICdjdXJyZW50LWltYWdlLmh0bWwnLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaFxufSlcbmV4cG9ydCBjbGFzcyBDdXJyZW50SW1hZ2VDb21wb25lbnQgZXh0ZW5kcyBBY2Nlc3NpYmxlQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkNoYW5nZXMsIEFmdGVyQ29udGVudEluaXQsIE9uRGVzdHJveSB7XG4gIC8qKlxuICAgKiBVbmlxdWUgaWQgKD49MCkgb2YgdGhlIGN1cnJlbnQgaW5zdGFuY2Ugb2YgdGhpcyBsaWJyYXJ5LiBUaGlzIGlzIHVzZWZ1bCB3aGVuIHlvdSBhcmUgdXNpbmdcbiAgICogdGhlIHNlcnZpY2UgdG8gY2FsbCBtb2RhbCBnYWxsZXJ5IHdpdGhvdXQgb3BlbiBpdCBtYW51YWxseS5cbiAgICovXG4gIEBJbnB1dCgpXG4gIC8vIEB0cy1pZ25vcmVcbiAgaWQ6IG51bWJlcjtcbiAgLyoqXG4gICAqIE9iamVjdCBvZiB0eXBlIGBJbnRlcm5hbExpYkltYWdlYCB0aGF0IHJlcHJlc2VudCB0aGUgdmlzaWJsZSBpbWFnZS5cbiAgICovXG4gIEBJbnB1dCgpXG4gIC8vIEB0cy1pZ25vcmVcbiAgY3VycmVudEltYWdlOiBJbnRlcm5hbExpYkltYWdlO1xuICAvKipcbiAgICogQXJyYXkgb2YgYEludGVybmFsTGliSW1hZ2VgIHRoYXQgcmVwcmVzZW50IHRoZSBtb2RlbCBvZiB0aGlzIGxpYnJhcnkgd2l0aCBhbGwgaW1hZ2VzLFxuICAgKiB0aHVtYnMgYW5kIHNvIG9uLlxuICAgKi9cbiAgQElucHV0KClcbiAgLy8gQHRzLWlnbm9yZVxuICBpbWFnZXM6IEludGVybmFsTGliSW1hZ2VbXTtcbiAgLyoqXG4gICAqIEJvb2xlYW4gdGhhdCBpdCBpcyB0cnVlIGlmIHRoZSBtb2RhbCBnYWxsZXJ5IGlzIHZpc2libGUuXG4gICAqIElmIHllcywgYWxzbyB0aGlzIGNvbXBvbmVudCBzaG91bGQgYmUgdmlzaWJsZS5cbiAgICovXG4gIEBJbnB1dCgpXG4gIC8vIEB0cy1pZ25vcmVcbiAgaXNPcGVuOiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBPdXRwdXQgdG8gZW1pdCBhbiBldmVudCB3aGVuIGltYWdlcyBhcmUgbG9hZGVkLiBUaGUgcGF5bG9hZCBjb250YWlucyBhbiBgSW1hZ2VMb2FkRXZlbnRgLlxuICAgKi9cbiAgQE91dHB1dCgpXG4gIGxvYWRJbWFnZTogRXZlbnRFbWl0dGVyPEltYWdlTG9hZEV2ZW50PiA9IG5ldyBFdmVudEVtaXR0ZXI8SW1hZ2VMb2FkRXZlbnQ+KCk7XG4gIC8qKlxuICAgKiBPdXRwdXQgdG8gZW1pdCBhbnkgY2hhbmdlcyBvZiB0aGUgY3VycmVudCBpbWFnZS4gVGhlIHBheWxvYWQgY29udGFpbnMgYW4gYEltYWdlTW9kYWxFdmVudGAuXG4gICAqL1xuICBAT3V0cHV0KClcbiAgY2hhbmdlSW1hZ2U6IEV2ZW50RW1pdHRlcjxJbWFnZU1vZGFsRXZlbnQ+ID0gbmV3IEV2ZW50RW1pdHRlcjxJbWFnZU1vZGFsRXZlbnQ+KCk7XG4gIC8qKlxuICAgKiBPdXRwdXQgdG8gZW1pdCBhbiBldmVudCB3aGVuIHRoZSBtb2RhbCBnYWxsZXJ5IGlzIGNsb3NlZC4gVGhlIHBheWxvYWQgY29udGFpbnMgYW4gYEltYWdlTW9kYWxFdmVudGAuXG4gICAqL1xuICBAT3V0cHV0KClcbiAgY2xvc2VHYWxsZXJ5OiBFdmVudEVtaXR0ZXI8SW1hZ2VNb2RhbEV2ZW50PiA9IG5ldyBFdmVudEVtaXR0ZXI8SW1hZ2VNb2RhbEV2ZW50PigpO1xuXG4gIC8qKlxuICAgKiBTdWJqZWN0IHRvIHBsYXkgbW9kYWwtZ2FsbGVyeS5cbiAgICovXG4gIHByaXZhdGUgc3RhcnQkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcbiAgLyoqXG4gICAqIFN1YmplY3QgdG8gc3RvcCBtb2RhbC1nYWxsZXJ5LlxuICAgKi9cbiAgcHJpdmF0ZSBzdG9wJCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG5cbiAgLyoqXG4gICAqIEVudW0gb2YgdHlwZSBgQWN0aW9uYCB0aGF0IHJlcHJlc2VudHMgYSBub3JtYWwgYWN0aW9uLlxuICAgKiBEZWNsYXJlZCBoZXJlIHRvIGJlIHVzZWQgaW5zaWRlIHRoZSB0ZW1wbGF0ZS5cbiAgICovXG4gIG5vcm1hbEFjdGlvbjogQWN0aW9uID0gQWN0aW9uLk5PUk1BTDtcbiAgLyoqXG4gICAqIE9iamVjdCBvZiB0eXBlIGBBY2Nlc3NpYmlsaXR5Q29uZmlnYCB0byBpbml0IGN1c3RvbSBhY2Nlc3NpYmlsaXR5IGZlYXR1cmVzLlxuICAgKiBGb3IgaW5zdGFuY2UsIGl0IGNvbnRhaW5zIHRpdGxlcywgYWx0IHRleHRzLCBhcmlhLWxhYmVscyBhbmQgc28gb24uXG4gICAqL1xuICBhY2Nlc3NpYmlsaXR5Q29uZmlnOiBBY2Nlc3NpYmlsaXR5Q29uZmlnIHwgdW5kZWZpbmVkO1xuICAvKipcbiAgICogT2JqZWN0IG9mIHR5cGUgYFNsaWRlQ29uZmlnYCB0byBnZXQgYGluZmluaXRlIHNsaWRpbmdgLlxuICAgKi9cbiAgc2xpZGVDb25maWc6IFNsaWRlQ29uZmlnIHwgdW5kZWZpbmVkO1xuICAvKipcbiAgICogT2JqZWN0IHRvIGNvbmZpZ3VyZSBjdXJyZW50IGltYWdlIGluIG1vZGFsLWdhbGxlcnkuXG4gICAqIEZvciBpbnN0YW5jZSB5b3UgY2FuIGRpc2FibGUgbmF2aWdhdGlvbiBvbiBjbGljayBvbiBjdXJyZW50IGltYWdlIChlbmFibGVkIGJ5IGRlZmF1bHQpLlxuICAgKi9cbiAgY3VycmVudEltYWdlQ29uZmlnOiBDdXJyZW50SW1hZ2VDb25maWcgfCB1bmRlZmluZWQ7XG4gIC8qKlxuICAgKiBPYmplY3Qgb2YgdHlwZSBgS2V5Ym9hcmRDb25maWdgIHRvIGFzc2lnbiBjdXN0b20ga2V5cyB0byBib3RoIEVTQywgUklHSFQgYW5kIExFRlQga2V5Ym9hcmQncyBhY3Rpb25zLlxuICAgKi9cbiAga2V5Ym9hcmRDb25maWc6IEtleWJvYXJkQ29uZmlnIHwgdW5kZWZpbmVkO1xuICAvKipcbiAgICogRW51bSBvZiB0eXBlIGBBY3Rpb25gIHRoYXQgcmVwcmVzZW50cyBhIG1vdXNlIGNsaWNrIG9uIGEgYnV0dG9uLlxuICAgKiBEZWNsYXJlZCBoZXJlIHRvIGJlIHVzZWQgaW5zaWRlIHRoZSB0ZW1wbGF0ZS5cbiAgICovXG4gIGNsaWNrQWN0aW9uOiBBY3Rpb24gPSBBY3Rpb24uQ0xJQ0s7XG4gIC8qKlxuICAgKiBFbnVtIG9mIHR5cGUgYEFjdGlvbmAgdGhhdCByZXByZXNlbnRzIGEga2V5Ym9hcmQgYWN0aW9uLlxuICAgKiBEZWNsYXJlZCBoZXJlIHRvIGJlIHVzZWQgaW5zaWRlIHRoZSB0ZW1wbGF0ZS5cbiAgICovXG4gIGtleWJvYXJkQWN0aW9uOiBBY3Rpb24gPSBBY3Rpb24uS0VZQk9BUkQ7XG4gIC8qKlxuICAgKiBCb29sZWFuIHRoYXQgaXQncyB0cnVlIHdoZW4geW91IGFyZSB3YXRjaGluZyB0aGUgZmlyc3QgaW1hZ2UgKGN1cnJlbnRseSB2aXNpYmxlKS5cbiAgICogRmFsc2UgYnkgZGVmYXVsdFxuICAgKi9cbiAgaXNGaXJzdEltYWdlID0gZmFsc2U7XG4gIC8qKlxuICAgKiBCb29sZWFuIHRoYXQgaXQncyB0cnVlIHdoZW4geW91IGFyZSB3YXRjaGluZyB0aGUgbGFzdCBpbWFnZSAoY3VycmVudGx5IHZpc2libGUpLlxuICAgKiBGYWxzZSBieSBkZWZhdWx0XG4gICAqL1xuICBpc0xhc3RJbWFnZSA9IGZhbHNlO1xuICAvKipcbiAgICogQm9vbGVhbiB0aGF0IGl0J3MgdHJ1ZSBpZiBhbiBpbWFnZSBvZiB0aGUgbW9kYWwgZ2FsbGVyeSBpcyBzdGlsbCBsb2FkaW5nLlxuICAgKiBUcnVlIGJ5IGRlZmF1bHRcbiAgICovXG4gIGxvYWRpbmcgPSB0cnVlO1xuXG4gIC8qKlxuICAgKiBQcml2YXRlIG9iamVjdCB3aXRob3V0IHR5cGUgdG8gZGVmaW5lIGFsbCBzd2lwZSBhY3Rpb25zIHVzZWQgYnkgaGFtbWVyanMuXG4gICAqL1xuICBwcml2YXRlIFNXSVBFX0FDVElPTiA9IHtcbiAgICBMRUZUOiAnc3dpcGVsZWZ0JyxcbiAgICBSSUdIVDogJ3N3aXBlcmlnaHQnLFxuICAgIFVQOiAnc3dpcGV1cCcsXG4gICAgRE9XTjogJ3N3aXBlZG93bidcbiAgfTtcblxuICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bm8tYW55XG4gIGNvbnN0cnVjdG9yKEBJbmplY3QoUExBVEZPUk1fSUQpIHByaXZhdGUgcGxhdGZvcm1JZDogYW55LCBwcml2YXRlIG5nWm9uZTogTmdab25lLCBwcml2YXRlIHJlZjogQ2hhbmdlRGV0ZWN0b3JSZWYsIHByaXZhdGUgY29uZmlnU2VydmljZTogQ29uZmlnU2VydmljZSkge1xuICAgIHN1cGVyKCk7XG4gIH1cblxuICAvKipcbiAgICogTGlzdGVuZXIgdG8gc3RvcCB0aGUgZ2FsbGVyeSB3aGVuIHRoZSBtb3VzZSBwb2ludGVyIGlzIG92ZXIgdGhlIGN1cnJlbnQgaW1hZ2UuXG4gICAqL1xuICBASG9zdExpc3RlbmVyKCdtb3VzZWVudGVyJylcbiAgb25Nb3VzZUVudGVyKCk6IHZvaWQge1xuICAgIC8vIGlmIGNhcm91c2VsIGZlYXR1cmUgaXMgZGlzYWJsZSwgZG9uJ3QgZG8gYW55dGhpbmcgaW4gYW55IGNhc2VcbiAgICBpZiAoIXRoaXMuc2xpZGVDb25maWcgfHwgIXRoaXMuc2xpZGVDb25maWcucGxheUNvbmZpZykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoIXRoaXMuc2xpZGVDb25maWcucGxheUNvbmZpZy5wYXVzZU9uSG92ZXIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5zdG9wQ2Fyb3VzZWwoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMaXN0ZW5lciB0byBwbGF5IHRoZSBnYWxsZXJ5IHdoZW4gdGhlIG1vdXNlIHBvaW50ZXIgbGVhdmUgdGhlIGN1cnJlbnQgaW1hZ2UuXG4gICAqL1xuICBASG9zdExpc3RlbmVyKCdtb3VzZWxlYXZlJylcbiAgb25Nb3VzZUxlYXZlKCk6IHZvaWQge1xuICAgIC8vIGlmIGNhcm91c2VsIGZlYXR1cmUgaXMgZGlzYWJsZSwgZG9uJ3QgZG8gYW55dGhpbmcgaW4gYW55IGNhc2VcbiAgICBpZiAoIXRoaXMuc2xpZGVDb25maWcgfHwgIXRoaXMuc2xpZGVDb25maWcucGxheUNvbmZpZykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoIXRoaXMuc2xpZGVDb25maWcucGxheUNvbmZpZy5wYXVzZU9uSG92ZXIgfHwgIXRoaXMuc2xpZGVDb25maWcucGxheUNvbmZpZy5hdXRvUGxheSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLnBsYXlDYXJvdXNlbCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIE1ldGhvZCDCtG5nT25Jbml0wrQgdG8gaW5pdCBjb25maWd1cmF0aW9uLlxuICAgKiBUaGlzIGlzIGFuIEFuZ3VsYXIncyBsaWZlY3ljbGUgaG9vaywgc28gaXRzIGNhbGxlZCBhdXRvbWF0aWNhbGx5IGJ5IEFuZ3VsYXIgaXRzZWxmLlxuICAgKiBJbiBwYXJ0aWN1bGFyLCBpdCdzIGNhbGxlZCBvbmx5IG9uZSB0aW1lISEhXG4gICAqL1xuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICBjb25zdCBsaWJDb25maWc6IExpYkNvbmZpZyB8IHVuZGVmaW5lZCA9IHRoaXMuY29uZmlnU2VydmljZS5nZXRDb25maWcodGhpcy5pZCk7XG4gICAgaWYgKCFsaWJDb25maWcgfHwgIWxpYkNvbmZpZy5idXR0b25zQ29uZmlnKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludGVybmFsIGxpYnJhcnkgZXJyb3IgLSBsaWJDb25maWcgYW5kIGJ1dHRvbnNDb25maWcgbXVzdCBiZSBkZWZpbmVkJyk7XG4gICAgfVxuICAgIHRoaXMuc2xpZGVDb25maWcgPSBsaWJDb25maWcuc2xpZGVDb25maWc7XG4gICAgdGhpcy5hY2Nlc3NpYmlsaXR5Q29uZmlnID0gbGliQ29uZmlnLmFjY2Vzc2liaWxpdHlDb25maWc7XG4gICAgdGhpcy5jdXJyZW50SW1hZ2VDb25maWcgPSBsaWJDb25maWcuY3VycmVudEltYWdlQ29uZmlnO1xuICAgIHRoaXMua2V5Ym9hcmRDb25maWcgPSBsaWJDb25maWcua2V5Ym9hcmRDb25maWc7XG4gIH1cblxuICAvKipcbiAgICogTWV0aG9kIMK0bmdPbkNoYW5nZXPCtCB0byB1cGRhdGUgYGxvYWRpbmdgIHN0YXR1cyBhbmQgZW1pdCBldmVudHMuXG4gICAqIElmIHRoZSBnYWxsZXJ5IGlzIG9wZW4sIHRoZW4gaXQgd2lsbCBhbHNvIG1hbmFnZSBib3VuZGFyeSBhcnJvd3MgYW5kIHNsaWRpbmcuXG4gICAqIFRoaXMgaXMgYW4gQW5ndWxhcidzIGxpZmVjeWNsZSBob29rLCBzbyBpdHMgY2FsbGVkIGF1dG9tYXRpY2FsbHkgYnkgQW5ndWxhciBpdHNlbGYuXG4gICAqIEluIHBhcnRpY3VsYXIsIGl0J3MgY2FsbGVkIHdoZW4gYW55IGRhdGEtYm91bmQgcHJvcGVydHkgb2YgYSBkaXJlY3RpdmUgY2hhbmdlcyEhIVxuICAgKi9cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIGNvbnN0IGxpYkNvbmZpZzogTGliQ29uZmlnIHwgdW5kZWZpbmVkID0gdGhpcy5jb25maWdTZXJ2aWNlLmdldENvbmZpZyh0aGlzLmlkKTtcbiAgICBpZiAoIWxpYkNvbmZpZykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnRlcm5hbCBsaWJyYXJ5IGVycm9yIC0gbGliQ29uZmlnIG11c3QgYmUgZGVmaW5lZCcpO1xuICAgIH1cbiAgICBjb25zdCBpbWFnZXM6IFNpbXBsZUNoYW5nZSA9IGNoYW5nZXMuaW1hZ2VzO1xuICAgIGNvbnN0IGN1cnJlbnRJbWFnZTogU2ltcGxlQ2hhbmdlID0gY2hhbmdlcy5jdXJyZW50SW1hZ2U7XG5cbiAgICBpZiAoY3VycmVudEltYWdlICYmIGN1cnJlbnRJbWFnZS5wcmV2aW91c1ZhbHVlICE9PSBjdXJyZW50SW1hZ2UuY3VycmVudFZhbHVlKSB7XG4gICAgICB0aGlzLnVwZGF0ZUluZGV4ZXMoKTtcbiAgICB9IGVsc2UgaWYgKGltYWdlcyAmJiBpbWFnZXMucHJldmlvdXNWYWx1ZSAhPT0gaW1hZ2VzLmN1cnJlbnRWYWx1ZSkge1xuICAgICAgdGhpcy51cGRhdGVJbmRleGVzKCk7XG4gICAgfVxuXG4gICAgY29uc3Qgc2xpZGVDb25maWc6IFNpbXBsZUNoYW5nZSA9IGNoYW5nZXMuc2xpZGVDb25maWc7XG4gICAgaWYgKHNsaWRlQ29uZmlnICYmIHNsaWRlQ29uZmlnLnByZXZpb3VzVmFsdWUgIT09IHNsaWRlQ29uZmlnLmN1cnJlbnRWYWx1ZSkge1xuICAgICAgdGhpcy5zbGlkZUNvbmZpZyA9IGxpYkNvbmZpZy5zbGlkZUNvbmZpZztcbiAgICB9XG4gIH1cblxuICBuZ0FmdGVyQ29udGVudEluaXQoKTogdm9pZCB7XG4gICAgLy8gaW50ZXJ2YWwgZG9lc24ndCBwbGF5IHdlbGwgd2l0aCBTU1IgYW5kIHByb3RyYWN0b3IsXG4gICAgLy8gc28gd2Ugc2hvdWxkIHJ1biBpdCBpbiB0aGUgYnJvd3NlciBhbmQgb3V0c2lkZSBBbmd1bGFyXG4gICAgaWYgKGlzUGxhdGZvcm1Ccm93c2VyKHRoaXMucGxhdGZvcm1JZCkpIHtcbiAgICAgIHRoaXMubmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHtcbiAgICAgICAgdGhpcy5zdGFydCRcbiAgICAgICAgICAucGlwZShcbiAgICAgICAgICAgIG1hcCgoKSA9PiB0aGlzLnNsaWRlQ29uZmlnICYmIHRoaXMuc2xpZGVDb25maWcucGxheUNvbmZpZyAmJiB0aGlzLnNsaWRlQ29uZmlnLnBsYXlDb25maWcuYXV0b1BsYXkgJiYgdGhpcy5zbGlkZUNvbmZpZy5wbGF5Q29uZmlnLmludGVydmFsKSxcbiAgICAgICAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1hbnlcbiAgICAgICAgICAgIGZpbHRlcigoaW50ZXJ2YWw6IGFueSkgPT4gaW50ZXJ2YWwgPiAwKSxcbiAgICAgICAgICAgIHN3aXRjaE1hcChpbnRlcnZhbCA9PiB0aW1lcihpbnRlcnZhbCkucGlwZSh0YWtlVW50aWwodGhpcy5zdG9wJCkpKVxuICAgICAgICAgIClcbiAgICAgICAgICAuc3Vic2NyaWJlKCgpID0+XG4gICAgICAgICAgICB0aGlzLm5nWm9uZS5ydW4oKCkgPT4ge1xuICAgICAgICAgICAgICBpZiAoIXRoaXMuaXNMYXN0SW1hZ2UpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm5leHRJbWFnZShBY3Rpb24uQVVUT1BMQVkpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHRoaXMucmVmLm1hcmtGb3JDaGVjaygpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICApO1xuXG4gICAgICAgIHRoaXMuc3RhcnQkLm5leHQoKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBNZXRob2QgdG8gaGFuZGxlIGtleXByZXNzIGJhc2VkIG9uIHRoZSBga2V5Ym9hcmRDb25maWdgIGlucHV0LiBJdCBnZXRzIHRoZSBrZXlDb2RlIG9mXG4gICAqIHRoZSBrZXkgdGhhdCB0cmlnZ2VyZWQgdGhlIGtleXByZXNzIGV2ZW50IHRvIG5hdmlnYXRlIGJldHdlZW4gaW1hZ2VzIG9yIHRvIGNsb3NlIHRoZSBtb2RhbCBnYWxsZXJ5LlxuICAgKiBAcGFyYW0gbnVtYmVyIGtleUNvZGUgb2YgdGhlIGtleSB0aGF0IHRyaWdnZXJlZCB0aGUga2V5cHJlc3MgZXZlbnRcbiAgICovXG4gIG9uS2V5UHJlc3Moa2V5Q29kZTogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgZXNjOiBudW1iZXIgPSB0aGlzLmtleWJvYXJkQ29uZmlnICYmIHRoaXMua2V5Ym9hcmRDb25maWcuZXNjID8gdGhpcy5rZXlib2FyZENvbmZpZy5lc2MgOiBLZXlib2FyZC5FU0M7XG4gICAgY29uc3QgcmlnaHQ6IG51bWJlciA9IHRoaXMua2V5Ym9hcmRDb25maWcgJiYgdGhpcy5rZXlib2FyZENvbmZpZy5yaWdodCA/IHRoaXMua2V5Ym9hcmRDb25maWcucmlnaHQgOiBLZXlib2FyZC5SSUdIVF9BUlJPVztcbiAgICBjb25zdCBsZWZ0OiBudW1iZXIgPSB0aGlzLmtleWJvYXJkQ29uZmlnICYmIHRoaXMua2V5Ym9hcmRDb25maWcubGVmdCA/IHRoaXMua2V5Ym9hcmRDb25maWcubGVmdCA6IEtleWJvYXJkLkxFRlRfQVJST1c7XG5cbiAgICBzd2l0Y2ggKGtleUNvZGUpIHtcbiAgICAgIGNhc2UgZXNjOlxuICAgICAgICB0aGlzLmNsb3NlR2FsbGVyeS5lbWl0KG5ldyBJbWFnZU1vZGFsRXZlbnQodGhpcy5pZCwgQWN0aW9uLktFWUJPQVJELCB0cnVlKSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSByaWdodDpcbiAgICAgICAgdGhpcy5uZXh0SW1hZ2UoQWN0aW9uLktFWUJPQVJEKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIGxlZnQ6XG4gICAgICAgIHRoaXMucHJldkltYWdlKEFjdGlvbi5LRVlCT0FSRCk7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBNZXRob2QgdG8gZ2V0IHRoZSBpbWFnZSBkZXNjcmlwdGlvbiBiYXNlZCBvbiBpbnB1dCBwYXJhbXMuXG4gICAqIElmIHlvdSBwcm92aWRlIGEgZnVsbCBkZXNjcmlwdGlvbiB0aGlzIHdpbGwgYmUgdGhlIHZpc2libGUgZGVzY3JpcHRpb24sIG90aGVyd2lzZSxcbiAgICogaXQgd2lsbCBiZSBidWlsdCB1c2luZyB0aGUgYERlc2NyaXB0aW9uYCBvYmplY3QsIGNvbmNhdGVuYXRpbmcgaXRzIGZpZWxkcy5cbiAgICogQHBhcmFtIEltYWdlIGltYWdlIHRvIGdldCBpdHMgZGVzY3JpcHRpb24uIElmIG5vdCBwcm92aWRlZCBpdCB3aWxsIGJlIHRoZSBjdXJyZW50IGltYWdlXG4gICAqIEByZXR1cm5zIFN0cmluZyBkZXNjcmlwdGlvbiBvZiB0aGUgaW1hZ2UgKG9yIHRoZSBjdXJyZW50IGltYWdlIGlmIG5vdCBwcm92aWRlZClcbiAgICogQHRocm93cyBhbiBFcnJvciBpZiBkZXNjcmlwdGlvbiBpc24ndCBhdmFpbGFibGVcbiAgICovXG4gIGdldERlc2NyaXB0aW9uVG9EaXNwbGF5KGltYWdlOiBJbWFnZSA9IHRoaXMuY3VycmVudEltYWdlKTogc3RyaW5nIHtcbiAgICBpZiAoIXRoaXMuY3VycmVudEltYWdlQ29uZmlnIHx8ICF0aGlzLmN1cnJlbnRJbWFnZUNvbmZpZy5kZXNjcmlwdGlvbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdEZXNjcmlwdGlvbiBpbnB1dCBtdXN0IGJlIGEgdmFsaWQgb2JqZWN0IGltcGxlbWVudGluZyB0aGUgRGVzY3JpcHRpb24gaW50ZXJmYWNlJyk7XG4gICAgfVxuXG4gICAgY29uc3QgaW1hZ2VXaXRob3V0RGVzY3JpcHRpb246IGJvb2xlYW4gPSAhaW1hZ2UubW9kYWwgfHwgIWltYWdlLm1vZGFsLmRlc2NyaXB0aW9uIHx8IGltYWdlLm1vZGFsLmRlc2NyaXB0aW9uID09PSAnJztcblxuICAgIHN3aXRjaCAodGhpcy5jdXJyZW50SW1hZ2VDb25maWcuZGVzY3JpcHRpb24uc3RyYXRlZ3kpIHtcbiAgICAgIGNhc2UgRGVzY3JpcHRpb25TdHJhdGVneS5ISURFX0lGX0VNUFRZOlxuICAgICAgICByZXR1cm4gaW1hZ2VXaXRob3V0RGVzY3JpcHRpb24gPyAnJyA6IGltYWdlLm1vZGFsLmRlc2NyaXB0aW9uICsgJyc7XG4gICAgICBjYXNlIERlc2NyaXB0aW9uU3RyYXRlZ3kuQUxXQVlTX0hJRERFTjpcbiAgICAgICAgcmV0dXJuICcnO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgLy8gLS0tLS0tLS0tLS0gRGVzY3JpcHRpb25TdHJhdGVneS5BTFdBWVNfVklTSUJMRSAtLS0tLS0tLS0tLS0tLS0tLVxuICAgICAgICByZXR1cm4gdGhpcy5idWlsZFRleHREZXNjcmlwdGlvbihpbWFnZSwgaW1hZ2VXaXRob3V0RGVzY3JpcHRpb24pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBNZXRob2QgdG8gZ2V0IGBhbHQgYXR0cmlidXRlYC5cbiAgICogYGFsdGAgc3BlY2lmaWVzIGFuIGFsdGVybmF0ZSB0ZXh0IGZvciBhbiBpbWFnZSwgaWYgdGhlIGltYWdlIGNhbm5vdCBiZSBkaXNwbGF5ZWQuXG4gICAqIEBwYXJhbSBJbWFnZSBpbWFnZSB0byBnZXQgaXRzIGFsdCBkZXNjcmlwdGlvbi4gSWYgbm90IHByb3ZpZGVkIGl0IHdpbGwgYmUgdGhlIGN1cnJlbnQgaW1hZ2VcbiAgICogQHJldHVybnMgU3RyaW5nIGFsdCBkZXNjcmlwdGlvbiBvZiB0aGUgaW1hZ2UgKG9yIHRoZSBjdXJyZW50IGltYWdlIGlmIG5vdCBwcm92aWRlZClcbiAgICovXG4gIGdldEFsdERlc2NyaXB0aW9uQnlJbWFnZShpbWFnZTogSW1hZ2UgPSB0aGlzLmN1cnJlbnRJbWFnZSk6IHN0cmluZyB7XG4gICAgaWYgKCFpbWFnZSkge1xuICAgICAgcmV0dXJuICcnO1xuICAgIH1cbiAgICByZXR1cm4gaW1hZ2UubW9kYWwgJiYgaW1hZ2UubW9kYWwuZGVzY3JpcHRpb24gPyBpbWFnZS5tb2RhbC5kZXNjcmlwdGlvbiA6IGBJbWFnZSAke2dldEluZGV4KGltYWdlLCB0aGlzLmltYWdlcykgKyAxfWA7XG4gIH1cblxuICAvKipcbiAgICogTWV0aG9kIHRvIGdldCB0aGUgdGl0bGUgYXR0cmlidXRlcyBiYXNlZCBvbiBkZXNjcmlwdGlvbnMuXG4gICAqIFRoaXMgaXMgdXNlZnVsIHRvIHByZXZlbnQgYWNjZXNzaWJpbGl0eSBpc3N1ZXMsIGJlY2F1c2UgaWYgRGVzY3JpcHRpb25TdHJhdGVneSBpcyBBTFdBWVNfSElEREVOLFxuICAgKiBpdCBwcmV2ZW50cyBhbiBlbXB0eSBzdHJpbmcgYXMgdGl0bGUuXG4gICAqIEBwYXJhbSBJbWFnZSBpbWFnZSB0byBnZXQgaXRzIGRlc2NyaXB0aW9uLiBJZiBub3QgcHJvdmlkZWQgaXQgd2lsbCBiZSB0aGUgY3VycmVudCBpbWFnZVxuICAgKiBAcmV0dXJucyBTdHJpbmcgdGl0bGUgb2YgdGhlIGltYWdlIGJhc2VkIG9uIGRlc2NyaXB0aW9uc1xuICAgKiBAdGhyb3dzIGFuIEVycm9yIGlmIGRlc2NyaXB0aW9uIGlzbid0IGF2YWlsYWJsZVxuICAgKi9cbiAgZ2V0VGl0bGVUb0Rpc3BsYXkoaW1hZ2U6IEltYWdlID0gdGhpcy5jdXJyZW50SW1hZ2UpOiBzdHJpbmcge1xuICAgIGlmICghdGhpcy5jdXJyZW50SW1hZ2VDb25maWcgfHwgIXRoaXMuY3VycmVudEltYWdlQ29uZmlnLmRlc2NyaXB0aW9uKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Rlc2NyaXB0aW9uIGlucHV0IG11c3QgYmUgYSB2YWxpZCBvYmplY3QgaW1wbGVtZW50aW5nIHRoZSBEZXNjcmlwdGlvbiBpbnRlcmZhY2UnKTtcbiAgICB9XG4gICAgY29uc3QgaW1hZ2VXaXRob3V0RGVzY3JpcHRpb246IGJvb2xlYW4gPSAhaW1hZ2UubW9kYWwgfHwgIWltYWdlLm1vZGFsLmRlc2NyaXB0aW9uIHx8IGltYWdlLm1vZGFsLmRlc2NyaXB0aW9uID09PSAnJztcbiAgICBjb25zdCBkZXNjcmlwdGlvbjogc3RyaW5nID0gdGhpcy5idWlsZFRleHREZXNjcmlwdGlvbihpbWFnZSwgaW1hZ2VXaXRob3V0RGVzY3JpcHRpb24pO1xuICAgIHJldHVybiBkZXNjcmlwdGlvbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBNZXRob2QgdG8gZ2V0IHRoZSBsZWZ0IHNpZGUgcHJldmlldyBpbWFnZS5cbiAgICogQHJldHVybnMgSW1hZ2UgdGhlIGltYWdlIHRvIHNob3cgYXMgc2l6ZSBwcmV2aWV3IG9uIHRoZSBsZWZ0XG4gICAqL1xuICBnZXRMZWZ0UHJldmlld0ltYWdlKCk6IEltYWdlIHtcbiAgICBpZiAoIXRoaXMuc2xpZGVDb25maWcpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW50ZXJuYWwgbGlicmFyeSBlcnJvciAtIHNsaWRlQ29uZmlnIG11c3QgYmUgZGVmaW5lZCcpO1xuICAgIH1cbiAgICBjb25zdCBjdXJyZW50SW5kZXg6IG51bWJlciA9IGdldEluZGV4KHRoaXMuY3VycmVudEltYWdlLCB0aGlzLmltYWdlcyk7XG4gICAgaWYgKGN1cnJlbnRJbmRleCA9PT0gMCAmJiB0aGlzLnNsaWRlQ29uZmlnLmluZmluaXRlKSB7XG4gICAgICAvLyB0aGUgY3VycmVudCBpbWFnZSBpcyB0aGUgZmlyc3Qgb25lLFxuICAgICAgLy8gc28gdGhlIHByZXZpb3VzIG9uZSBpcyB0aGUgbGFzdCBpbWFnZVxuICAgICAgLy8gYmVjYXVzZSBpbmZpbml0ZSBpcyB0cnVlXG4gICAgICByZXR1cm4gdGhpcy5pbWFnZXNbdGhpcy5pbWFnZXMubGVuZ3RoIC0gMV07XG4gICAgfVxuICAgIHRoaXMuaGFuZGxlQm91bmRhcmllcyhjdXJyZW50SW5kZXgpO1xuICAgIHJldHVybiB0aGlzLmltYWdlc1tNYXRoLm1heChjdXJyZW50SW5kZXggLSAxLCAwKV07XG4gIH1cblxuICAvKipcbiAgICogTWV0aG9kIHRvIGdldCB0aGUgcmlnaHQgc2lkZSBwcmV2aWV3IGltYWdlLlxuICAgKiBAcmV0dXJucyBJbWFnZSB0aGUgaW1hZ2UgdG8gc2hvdyBhcyBzaXplIHByZXZpZXcgb24gdGhlIHJpZ2h0XG4gICAqL1xuICBnZXRSaWdodFByZXZpZXdJbWFnZSgpOiBJbWFnZSB7XG4gICAgaWYgKCF0aGlzLnNsaWRlQ29uZmlnKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludGVybmFsIGxpYnJhcnkgZXJyb3IgLSBzbGlkZUNvbmZpZyBtdXN0IGJlIGRlZmluZWQnKTtcbiAgICB9XG4gICAgY29uc3QgY3VycmVudEluZGV4OiBudW1iZXIgPSBnZXRJbmRleCh0aGlzLmN1cnJlbnRJbWFnZSwgdGhpcy5pbWFnZXMpO1xuICAgIGlmIChjdXJyZW50SW5kZXggPT09IHRoaXMuaW1hZ2VzLmxlbmd0aCAtIDEgJiYgdGhpcy5zbGlkZUNvbmZpZy5pbmZpbml0ZSkge1xuICAgICAgLy8gdGhlIGN1cnJlbnQgaW1hZ2UgaXMgdGhlIGxhc3Qgb25lLFxuICAgICAgLy8gc28gdGhlIG5leHQgb25lIGlzIHRoZSBmaXJzdCBpbWFnZVxuICAgICAgLy8gYmVjYXVzZSBpbmZpbml0ZSBpcyB0cnVlXG4gICAgICByZXR1cm4gdGhpcy5pbWFnZXNbMF07XG4gICAgfVxuICAgIHRoaXMuaGFuZGxlQm91bmRhcmllcyhjdXJyZW50SW5kZXgpO1xuICAgIHJldHVybiB0aGlzLmltYWdlc1tNYXRoLm1pbihjdXJyZW50SW5kZXggKyAxLCB0aGlzLmltYWdlcy5sZW5ndGggLSAxKV07XG4gIH1cblxuICAvKipcbiAgICogTWV0aG9kIGNhbGxlZCBieSBldmVudHMgZnJvbSBib3RoIGtleWJvYXJkIGFuZCBtb3VzZSBvbiBhbiBpbWFnZS5cbiAgICogVGhpcyB3aWxsIGludm9rZSB0aGUgbmV4dEltYWdlIG1ldGhvZC5cbiAgICogQHBhcmFtIEtleWJvYXJkRXZlbnQgfCBNb3VzZUV2ZW50IGV2ZW50IHBheWxvYWRcbiAgICogQHBhcmFtIEFjdGlvbiBhY3Rpb24gdGhhdCB0cmlnZ2VyZWQgdGhlIGV2ZW50IG9yIGBBY3Rpb24uTk9STUFMYCBpZiBub3QgcHJvdmlkZWRcbiAgICovXG4gIG9uSW1hZ2VFdmVudChldmVudDogS2V5Ym9hcmRFdmVudCB8IE1vdXNlRXZlbnQsIGFjdGlvbjogQWN0aW9uID0gQWN0aW9uLk5PUk1BTCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5jdXJyZW50SW1hZ2VDb25maWcpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSW50ZXJuYWwgbGlicmFyeSBlcnJvciAtIGN1cnJlbnRJbWFnZUNvbmZpZyBtdXN0IGJlIGRlZmluZWQnKTtcbiAgICB9XG4gICAgLy8gY2hlY2sgaWYgdHJpZ2dlcmVkIGJ5IGEgbW91c2UgY2xpY2tcbiAgICAvLyBJZiB5ZXMsIEl0IHNob3VsZCBibG9jayBuYXZpZ2F0aW9uIHdoZW4gbmF2aWdhdGVPbkNsaWNrIGlzIGZhbHNlXG4gICAgaWYgKGFjdGlvbiA9PT0gQWN0aW9uLkNMSUNLICYmICF0aGlzLmN1cnJlbnRJbWFnZUNvbmZpZy5uYXZpZ2F0ZU9uQ2xpY2spIHtcbiAgICAgIC8vIGEgdXNlciBoYXMgcmVxdWVzdGVkIHRvIGJsb2NrIG5hdmlnYXRpb24gdmlhIGNvbmZpZ0N1cnJlbnRJbWFnZS5uYXZpZ2F0ZU9uQ2xpY2sgcHJvcGVydHlcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCByZXN1bHQ6IG51bWJlciA9IHN1cGVyLmhhbmRsZUltYWdlRXZlbnQoZXZlbnQpO1xuICAgIGlmIChyZXN1bHQgPT09IE5FWFQpIHtcbiAgICAgIHRoaXMubmV4dEltYWdlKGFjdGlvbik7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIE1ldGhvZCBjYWxsZWQgYnkgZXZlbnRzIGZyb20gYm90aCBrZXlib2FyZCBhbmQgbW91c2Ugb24gYSBuYXZpZ2F0aW9uIGFycm93LlxuICAgKiBAcGFyYW0gc3RyaW5nIGRpcmVjdGlvbiBvZiB0aGUgbmF2aWdhdGlvbiB0aGF0IGNhbiBiZSBlaXRoZXIgJ25leHQnIG9yICdwcmV2J1xuICAgKiBAcGFyYW0gS2V5Ym9hcmRFdmVudCB8IE1vdXNlRXZlbnQgZXZlbnQgcGF5bG9hZFxuICAgKiBAcGFyYW0gQWN0aW9uIGFjdGlvbiB0aGF0IHRyaWdnZXJlZCB0aGUgZXZlbnQgb3IgYEFjdGlvbi5OT1JNQUxgIGlmIG5vdCBwcm92aWRlZFxuICAgKiBAcGFyYW0gYm9vbGVhbiBkaXNhYmxlIHRvIGRpc2FibGUgbmF2aWdhdGlvblxuICAgKi9cbiAgb25OYXZpZ2F0aW9uRXZlbnQoZGlyZWN0aW9uOiBzdHJpbmcsIGV2ZW50OiBLZXlib2FyZEV2ZW50IHwgTW91c2VFdmVudCwgYWN0aW9uOiBBY3Rpb24gPSBBY3Rpb24uTk9STUFMLCBkaXNhYmxlOiBib29sZWFuID0gZmFsc2UpOiB2b2lkIHtcbiAgICBpZiAoZGlzYWJsZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCByZXN1bHQ6IG51bWJlciA9IHN1cGVyLmhhbmRsZU5hdmlnYXRpb25FdmVudChkaXJlY3Rpb24sIGV2ZW50KTtcbiAgICBpZiAocmVzdWx0ID09PSBORVhUKSB7XG4gICAgICB0aGlzLm5leHRJbWFnZShhY3Rpb24pO1xuICAgIH0gZWxzZSBpZiAocmVzdWx0ID09PSBQUkVWKSB7XG4gICAgICB0aGlzLnByZXZJbWFnZShhY3Rpb24pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBNZXRob2QgdG8gZ28gYmFjayB0byB0aGUgcHJldmlvdXMgaW1hZ2UuXG4gICAqIEBwYXJhbSBhY3Rpb24gRW51bSBvZiB0eXBlIGBBY3Rpb25gIHRoYXQgcmVwcmVzZW50cyB0aGUgc291cmNlXG4gICAqICBhY3Rpb24gdGhhdCBtb3ZlZCBiYWNrIHRvIHRoZSBwcmV2aW91cyBpbWFnZS4gYEFjdGlvbi5OT1JNQUxgIGJ5IGRlZmF1bHQuXG4gICAqL1xuICBwcmV2SW1hZ2UoYWN0aW9uOiBBY3Rpb24gPSBBY3Rpb24uTk9STUFMKTogdm9pZCB7XG4gICAgLy8gY2hlY2sgaWYgcHJldkltYWdlIHNob3VsZCBiZSBibG9ja2VkXG4gICAgaWYgKHRoaXMuaXNQcmV2ZW50U2xpZGluZygwKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBwcmV2SW1hZ2U6IEludGVybmFsTGliSW1hZ2UgPSB0aGlzLmdldFByZXZJbWFnZSgpO1xuICAgIHRoaXMubG9hZGluZyA9ICFwcmV2SW1hZ2UucHJldmlvdXNseUxvYWRlZDtcbiAgICB0aGlzLmNoYW5nZUltYWdlLmVtaXQobmV3IEltYWdlTW9kYWxFdmVudCh0aGlzLmlkLCBhY3Rpb24sIGdldEluZGV4KHByZXZJbWFnZSwgdGhpcy5pbWFnZXMpKSk7XG5cbiAgICB0aGlzLnN0YXJ0JC5uZXh0KCk7XG4gIH1cblxuICAvKipcbiAgICogTWV0aG9kIHRvIGdvIGJhY2sgdG8gdGhlIHByZXZpb3VzIGltYWdlLlxuICAgKiBAcGFyYW0gYWN0aW9uIEVudW0gb2YgdHlwZSBgQWN0aW9uYCB0aGF0IHJlcHJlc2VudHMgdGhlIHNvdXJjZVxuICAgKiAgYWN0aW9uIHRoYXQgbW92ZWQgdG8gdGhlIG5leHQgaW1hZ2UuIGBBY3Rpb24uTk9STUFMYCBieSBkZWZhdWx0LlxuICAgKi9cbiAgbmV4dEltYWdlKGFjdGlvbjogQWN0aW9uID0gQWN0aW9uLk5PUk1BTCk6IHZvaWQge1xuICAgIC8vIGNoZWNrIGlmIG5leHRJbWFnZSBzaG91bGQgYmUgYmxvY2tlZFxuICAgIGlmICh0aGlzLmlzUHJldmVudFNsaWRpbmcodGhpcy5pbWFnZXMubGVuZ3RoIC0gMSkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgbmV4dEltYWdlOiBJbnRlcm5hbExpYkltYWdlID0gdGhpcy5nZXROZXh0SW1hZ2UoKTtcbiAgICB0aGlzLmxvYWRpbmcgPSAhbmV4dEltYWdlLnByZXZpb3VzbHlMb2FkZWQ7XG4gICAgdGhpcy5jaGFuZ2VJbWFnZS5lbWl0KG5ldyBJbWFnZU1vZGFsRXZlbnQodGhpcy5pZCwgYWN0aW9uLCBnZXRJbmRleChuZXh0SW1hZ2UsIHRoaXMuaW1hZ2VzKSkpO1xuXG4gICAgdGhpcy5zdGFydCQubmV4dCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIE1ldGhvZCB0byBlbWl0IGFuIGV2ZW50IGFzIGxvYWRJbWFnZSBvdXRwdXQgdG8gc2F5IHRoYXQgdGhlIHJlcXVlc3RlZCBpbWFnZSBpZiBsb2FkZWQuXG4gICAqIFRoaXMgbWV0aG9kIGlzIGludm9rZWQgYnkgdGhlIGphdmFzY3JpcHQncyAnbG9hZCcgZXZlbnQgb24gYW4gaW1nIHRhZy5cbiAgICogQHBhcmFtIEV2ZW50IGV2ZW50IHRoYXQgdHJpZ2dlcmVkIHRoZSBsb2FkXG4gICAqL1xuICBvbkltYWdlTG9hZChldmVudDogRXZlbnQpOiB2b2lkIHtcbiAgICBjb25zdCBsb2FkSW1hZ2VEYXRhOiBJbWFnZUxvYWRFdmVudCA9IHtcbiAgICAgIHN0YXR1czogdHJ1ZSxcbiAgICAgIGluZGV4OiBnZXRJbmRleCh0aGlzLmN1cnJlbnRJbWFnZSwgdGhpcy5pbWFnZXMpLFxuICAgICAgaWQ6IHRoaXMuY3VycmVudEltYWdlLmlkXG4gICAgfTtcblxuICAgIHRoaXMubG9hZEltYWdlLmVtaXQobG9hZEltYWdlRGF0YSk7XG5cbiAgICB0aGlzLmxvYWRpbmcgPSBmYWxzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNZXRob2QgdXNlZCBieSBIYW1tZXJqcyB0byBzdXBwb3J0IHRvdWNoIGdlc3R1cmVzICh5b3UgY2FuIGFsc28gaW52ZXJ0IHRoZSBzd2lwZSBkaXJlY3Rpb24gd2l0aCBjb25maWdDdXJyZW50SW1hZ2UuaW52ZXJ0U3dpcGUpLlxuICAgKiBAcGFyYW0gYWN0aW9uIFN0cmluZyB0aGF0IHJlcHJlc2VudCB0aGUgZGlyZWN0aW9uIG9mIHRoZSBzd2lwZSBhY3Rpb24uICdzd2lwZXJpZ2h0JyBieSBkZWZhdWx0LlxuICAgKi9cbiAgc3dpcGUoYWN0aW9uID0gdGhpcy5TV0lQRV9BQ1RJT04uUklHSFQpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuY3VycmVudEltYWdlQ29uZmlnKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludGVybmFsIGxpYnJhcnkgZXJyb3IgLSBjdXJyZW50SW1hZ2VDb25maWcgbXVzdCBiZSBkZWZpbmVkJyk7XG4gICAgfVxuICAgIHN3aXRjaCAoYWN0aW9uKSB7XG4gICAgICBjYXNlIHRoaXMuU1dJUEVfQUNUSU9OLlJJR0hUOlxuICAgICAgICBpZiAodGhpcy5jdXJyZW50SW1hZ2VDb25maWcuaW52ZXJ0U3dpcGUpIHtcbiAgICAgICAgICB0aGlzLnByZXZJbWFnZShBY3Rpb24uU1dJUEUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMubmV4dEltYWdlKEFjdGlvbi5TV0lQRSk7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIHRoaXMuU1dJUEVfQUNUSU9OLkxFRlQ6XG4gICAgICAgIGlmICh0aGlzLmN1cnJlbnRJbWFnZUNvbmZpZy5pbnZlcnRTd2lwZSkge1xuICAgICAgICAgIHRoaXMubmV4dEltYWdlKEFjdGlvbi5TV0lQRSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5wcmV2SW1hZ2UoQWN0aW9uLlNXSVBFKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIC8vIGNhc2UgdGhpcy5TV0lQRV9BQ1RJT04uVVA6XG4gICAgICAvLyAgIGJyZWFrO1xuICAgICAgLy8gY2FzZSB0aGlzLlNXSVBFX0FDVElPTi5ET1dOOlxuICAgICAgLy8gICBicmVhaztcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogTWV0aG9kIHVzZWQgaW4gYG1vZGFsLWdhbGxlcnkuY29tcG9uZW50YCB0byBnZXQgdGhlIGluZGV4IG9mIGFuIGltYWdlIHRvIGRlbGV0ZS5cbiAgICogQHBhcmFtIEltYWdlIGltYWdlIHRvIGdldCB0aGUgaW5kZXgsIG9yIHRoZSB2aXNpYmxlIGltYWdlLCBpZiBub3QgcGFzc2VkXG4gICAqIEByZXR1cm5zIG51bWJlciB0aGUgaW5kZXggb2YgdGhlIGltYWdlXG4gICAqL1xuICBnZXRJbmRleFRvRGVsZXRlKGltYWdlOiBJbWFnZSA9IHRoaXMuY3VycmVudEltYWdlKTogbnVtYmVyIHtcbiAgICByZXR1cm4gZ2V0SW5kZXgoaW1hZ2UsIHRoaXMuaW1hZ2VzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNZXRob2QgdG8gcGxheSBtb2RhbCBnYWxsZXJ5LlxuICAgKi9cbiAgcGxheUNhcm91c2VsKCk6IHZvaWQge1xuICAgIHRoaXMuc3RhcnQkLm5leHQoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdG9wcyBtb2RhbCBnYWxsZXJ5IGZyb20gY3ljbGluZyB0aHJvdWdoIGl0ZW1zLlxuICAgKi9cbiAgc3RvcENhcm91c2VsKCk6IHZvaWQge1xuICAgIHRoaXMuc3RvcCQubmV4dCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIE1ldGhvZCB0byBjbGVhbnVwIHJlc291cmNlcy4gSW4gZmFjdCwgdGhpcyB3aWxsIHN0b3AgdGhlIG1vZGFsIGdhbGxlcnkuXG4gICAqIFRoaXMgaXMgYW4gQW5ndWxhcidzIGxpZmVjeWNsZSBob29rIHRoYXQgaXMgY2FsbGVkIHdoZW4gdGhpcyBjb21wb25lbnQgaXMgZGVzdHJveWVkLlxuICAgKi9cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5zdG9wQ2Fyb3VzZWwoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQcml2YXRlIG1ldGhvZCB0byB1cGRhdGUgYm90aCBgaXNGaXJzdEltYWdlYCBhbmQgYGlzTGFzdEltYWdlYCBiYXNlZCBvblxuICAgKiB0aGUgaW5kZXggb2YgdGhlIGN1cnJlbnQgaW1hZ2UuXG4gICAqIEBwYXJhbSBudW1iZXIgY3VycmVudEluZGV4IGlzIHRoZSBpbmRleCBvZiB0aGUgY3VycmVudCBpbWFnZVxuICAgKi9cbiAgcHJpdmF0ZSBoYW5kbGVCb3VuZGFyaWVzKGN1cnJlbnRJbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuaW1hZ2VzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgdGhpcy5pc0ZpcnN0SW1hZ2UgPSB0cnVlO1xuICAgICAgdGhpcy5pc0xhc3RJbWFnZSA9IHRydWU7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICghdGhpcy5zbGlkZUNvbmZpZyB8fCB0aGlzLnNsaWRlQ29uZmlnLmluZmluaXRlID09PSB0cnVlKSB7XG4gICAgICAvLyBpbmZpbml0ZSBzbGlkaW5nIGVuYWJsZWRcbiAgICAgIHRoaXMuaXNGaXJzdEltYWdlID0gZmFsc2U7XG4gICAgICB0aGlzLmlzTGFzdEltYWdlID0gZmFsc2U7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN3aXRjaCAoY3VycmVudEluZGV4KSB7XG4gICAgICAgIGNhc2UgMDpcbiAgICAgICAgICAvLyBleGVjdXRlIHRoaXMgb25seSBpZiBpbmZpbml0ZSBzbGlkaW5nIGlzIGRpc2FibGVkXG4gICAgICAgICAgdGhpcy5pc0ZpcnN0SW1hZ2UgPSB0cnVlO1xuICAgICAgICAgIHRoaXMuaXNMYXN0SW1hZ2UgPSBmYWxzZTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSB0aGlzLmltYWdlcy5sZW5ndGggLSAxOlxuICAgICAgICAgIC8vIGV4ZWN1dGUgdGhpcyBvbmx5IGlmIGluZmluaXRlIHNsaWRpbmcgaXMgZGlzYWJsZWRcbiAgICAgICAgICB0aGlzLmlzRmlyc3RJbWFnZSA9IGZhbHNlO1xuICAgICAgICAgIHRoaXMuaXNMYXN0SW1hZ2UgPSB0cnVlO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgIHRoaXMuaXNGaXJzdEltYWdlID0gZmFsc2U7XG4gICAgICAgICAgdGhpcy5pc0xhc3RJbWFnZSA9IGZhbHNlO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBQcml2YXRlIG1ldGhvZCB0byBjaGVjayBpZiBuZXh0L3ByZXYgYWN0aW9ucyBzaG91bGQgYmUgYmxvY2tlZC5cbiAgICogSXQgY2hlY2tzIGlmIHNsaWRlQ29uZmlnLmluZmluaXRlID09PSBmYWxzZSBhbmQgaWYgdGhlIGltYWdlIGluZGV4IGlzIGVxdWFscyB0byB0aGUgaW5wdXQgcGFyYW1ldGVyLlxuICAgKiBJZiB5ZXMsIGl0IHJldHVybnMgdHJ1ZSB0byBzYXkgdGhhdCBzbGlkaW5nIHNob3VsZCBiZSBibG9ja2VkLCBvdGhlcndpc2Ugbm90LlxuICAgKiBAcGFyYW0gbnVtYmVyIGJvdW5kYXJ5SW5kZXggdGhhdCBjb3VsZCBiZSBlaXRoZXIgdGhlIGJlZ2lubmluZyBpbmRleCAoMCkgb3IgdGhlIGxhc3QgaW5kZXhcbiAgICogIG9mIGltYWdlcyAodGhpcy5pbWFnZXMubGVuZ3RoIC0gMSkuXG4gICAqIEByZXR1cm5zIGJvb2xlYW4gdHJ1ZSBpZiBzbGlkZUNvbmZpZy5pbmZpbml0ZSA9PT0gZmFsc2UgYW5kIHRoZSBjdXJyZW50IGluZGV4IGlzXG4gICAqICBlaXRoZXIgdGhlIGZpcnN0IG9yIHRoZSBsYXN0IG9uZS5cbiAgICovXG4gIHByaXZhdGUgaXNQcmV2ZW50U2xpZGluZyhib3VuZGFyeUluZGV4OiBudW1iZXIpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISF0aGlzLnNsaWRlQ29uZmlnICYmIHRoaXMuc2xpZGVDb25maWcuaW5maW5pdGUgPT09IGZhbHNlICYmIGdldEluZGV4KHRoaXMuY3VycmVudEltYWdlLCB0aGlzLmltYWdlcykgPT09IGJvdW5kYXJ5SW5kZXg7XG4gIH1cblxuICAvKipcbiAgICogUHJpdmF0ZSBtZXRob2QgdG8gZ2V0IHRoZSBuZXh0IGluZGV4LlxuICAgKiBUaGlzIGlzIG5lY2Vzc2FyeSBiZWNhdXNlIGF0IHRoZSBlbmQsIHdoZW4geW91IGNhbGwgbmV4dCBhZ2FpbiwgeW91J2xsIGdvIHRvIHRoZSBmaXJzdCBpbWFnZS5cbiAgICogVGhhdCBoYXBwZW5zIGJlY2F1c2UgYWxsIG1vZGFsIGltYWdlcyBhcmUgc2hvd24gbGlrZSBpbiBhIGNpcmNsZS5cbiAgICovXG4gIHByaXZhdGUgZ2V0TmV4dEltYWdlKCk6IEludGVybmFsTGliSW1hZ2Uge1xuICAgIGNvbnN0IGN1cnJlbnRJbmRleDogbnVtYmVyID0gZ2V0SW5kZXgodGhpcy5jdXJyZW50SW1hZ2UsIHRoaXMuaW1hZ2VzKTtcbiAgICBsZXQgbmV3SW5kZXggPSAwO1xuICAgIGlmIChjdXJyZW50SW5kZXggPj0gMCAmJiBjdXJyZW50SW5kZXggPCB0aGlzLmltYWdlcy5sZW5ndGggLSAxKSB7XG4gICAgICBuZXdJbmRleCA9IGN1cnJlbnRJbmRleCArIDE7XG4gICAgfSBlbHNlIHtcbiAgICAgIG5ld0luZGV4ID0gMDsgLy8gc3RhcnQgZnJvbSB0aGUgZmlyc3QgaW5kZXhcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuaW1hZ2VzW25ld0luZGV4XTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQcml2YXRlIG1ldGhvZCB0byBnZXQgdGhlIHByZXZpb3VzIGluZGV4LlxuICAgKiBUaGlzIGlzIG5lY2Vzc2FyeSBiZWNhdXNlIGF0IGluZGV4IDAsIHdoZW4geW91IGNhbGwgcHJldiBhZ2FpbiwgeW91J2xsIGdvIHRvIHRoZSBsYXN0IGltYWdlLlxuICAgKiBUaGF0IGhhcHBlbnMgYmVjYXVzZSBhbGwgbW9kYWwgaW1hZ2VzIGFyZSBzaG93biBsaWtlIGluIGEgY2lyY2xlLlxuICAgKi9cbiAgcHJpdmF0ZSBnZXRQcmV2SW1hZ2UoKTogSW50ZXJuYWxMaWJJbWFnZSB7XG4gICAgY29uc3QgY3VycmVudEluZGV4OiBudW1iZXIgPSBnZXRJbmRleCh0aGlzLmN1cnJlbnRJbWFnZSwgdGhpcy5pbWFnZXMpO1xuICAgIGxldCBuZXdJbmRleCA9IDA7XG4gICAgaWYgKGN1cnJlbnRJbmRleCA+IDAgJiYgY3VycmVudEluZGV4IDw9IHRoaXMuaW1hZ2VzLmxlbmd0aCAtIDEpIHtcbiAgICAgIG5ld0luZGV4ID0gY3VycmVudEluZGV4IC0gMTtcbiAgICB9IGVsc2Uge1xuICAgICAgbmV3SW5kZXggPSB0aGlzLmltYWdlcy5sZW5ndGggLSAxOyAvLyBzdGFydCBmcm9tIHRoZSBsYXN0IGluZGV4XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmltYWdlc1tuZXdJbmRleF07XG4gIH1cblxuICAvKipcbiAgICogUHJpdmF0ZSBtZXRob2QgdG8gYnVpbGQgYSB0ZXh0IGRlc2NyaXB0aW9uLlxuICAgKiBUaGlzIGlzIHVzZWQgYWxzbyB0byBjcmVhdGUgdGl0bGVzLlxuICAgKiBAcGFyYW0gSW1hZ2UgaW1hZ2UgdG8gZ2V0IGl0cyBkZXNjcmlwdGlvbi4gSWYgbm90IHByb3ZpZGVkIGl0IHdpbGwgYmUgdGhlIGN1cnJlbnQgaW1hZ2UuXG4gICAqIEBwYXJhbSBib29sZWFuIGltYWdlV2l0aG91dERlc2NyaXB0aW9uIGlzIGEgYm9vbGVhbiB0aGF0IGl0J3MgdHJ1ZSBpZiB0aGUgaW1hZ2UgaGFzbid0IGEgJ21vZGFsJyBkZXNjcmlwdGlvbi5cbiAgICogQHJldHVybnMgU3RyaW5nIGRlc2NyaXB0aW9uIGJ1aWx0IGNvbmNhdGVuYXRpbmcgaW1hZ2UgZmllbGRzIHdpdGggYSBzcGVjaWZpYyBsb2dpYy5cbiAgICovXG4gIHByaXZhdGUgYnVpbGRUZXh0RGVzY3JpcHRpb24oaW1hZ2U6IEltYWdlLCBpbWFnZVdpdGhvdXREZXNjcmlwdGlvbjogYm9vbGVhbik6IHN0cmluZyB7XG4gICAgaWYgKCF0aGlzLmN1cnJlbnRJbWFnZUNvbmZpZyB8fCAhdGhpcy5jdXJyZW50SW1hZ2VDb25maWcuZGVzY3JpcHRpb24pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignRGVzY3JpcHRpb24gaW5wdXQgbXVzdCBiZSBhIHZhbGlkIG9iamVjdCBpbXBsZW1lbnRpbmcgdGhlIERlc2NyaXB0aW9uIGludGVyZmFjZScpO1xuICAgIH1cblxuICAgIC8vIElmIGN1c3RvbUZ1bGxEZXNjcmlwdGlvbiB1c2UgaXQsIG90aGVyd2lzZSBwcm9jZWVkIHRvIGJ1aWxkIGEgZGVzY3JpcHRpb25cbiAgICBpZiAodGhpcy5jdXJyZW50SW1hZ2VDb25maWcuZGVzY3JpcHRpb24uY3VzdG9tRnVsbERlc2NyaXB0aW9uICYmIHRoaXMuY3VycmVudEltYWdlQ29uZmlnLmRlc2NyaXB0aW9uLmN1c3RvbUZ1bGxEZXNjcmlwdGlvbiAhPT0gJycpIHtcbiAgICAgIHJldHVybiB0aGlzLmN1cnJlbnRJbWFnZUNvbmZpZy5kZXNjcmlwdGlvbi5jdXN0b21GdWxsRGVzY3JpcHRpb247XG4gICAgfVxuXG4gICAgY29uc3QgY3VycmVudEluZGV4OiBudW1iZXIgPSBnZXRJbmRleChpbWFnZSwgdGhpcy5pbWFnZXMpO1xuICAgIC8vIElmIHRoZSBjdXJyZW50IGltYWdlIGhhc24ndCBhIGRlc2NyaXB0aW9uLFxuICAgIC8vIHByZXZlbnQgdG8gd3JpdGUgdGhlICcgLSAnIChvciB0aGlzLmRlc2NyaXB0aW9uLmJlZm9yZVRleHREZXNjcmlwdGlvbilcblxuICAgIGNvbnN0IHByZXZEZXNjcmlwdGlvbjogc3RyaW5nID0gdGhpcy5jdXJyZW50SW1hZ2VDb25maWcuZGVzY3JpcHRpb24uaW1hZ2VUZXh0ID8gdGhpcy5jdXJyZW50SW1hZ2VDb25maWcuZGVzY3JpcHRpb24uaW1hZ2VUZXh0IDogJyc7XG4gICAgY29uc3QgbWlkU2VwYXJhdG9yOiBzdHJpbmcgPSB0aGlzLmN1cnJlbnRJbWFnZUNvbmZpZy5kZXNjcmlwdGlvbi5udW1iZXJTZXBhcmF0b3IgPyB0aGlzLmN1cnJlbnRJbWFnZUNvbmZpZy5kZXNjcmlwdGlvbi5udW1iZXJTZXBhcmF0b3IgOiAnJztcbiAgICBjb25zdCBtaWRkbGVEZXNjcmlwdGlvbjogc3RyaW5nID0gY3VycmVudEluZGV4ICsgMSArIG1pZFNlcGFyYXRvciArIHRoaXMuaW1hZ2VzLmxlbmd0aDtcblxuICAgIGlmIChpbWFnZVdpdGhvdXREZXNjcmlwdGlvbikge1xuICAgICAgcmV0dXJuIHByZXZEZXNjcmlwdGlvbiArIG1pZGRsZURlc2NyaXB0aW9uO1xuICAgIH1cblxuICAgIGNvbnN0IGN1cnJJbWdEZXNjcmlwdGlvbjogc3RyaW5nID0gaW1hZ2UubW9kYWwgJiYgaW1hZ2UubW9kYWwuZGVzY3JpcHRpb24gPyBpbWFnZS5tb2RhbC5kZXNjcmlwdGlvbiA6ICcnO1xuICAgIGNvbnN0IGVuZERlc2NyaXB0aW9uOiBzdHJpbmcgPSB0aGlzLmN1cnJlbnRJbWFnZUNvbmZpZy5kZXNjcmlwdGlvbi5iZWZvcmVUZXh0RGVzY3JpcHRpb24gKyBjdXJySW1nRGVzY3JpcHRpb247XG4gICAgcmV0dXJuIHByZXZEZXNjcmlwdGlvbiArIG1pZGRsZURlc2NyaXB0aW9uICsgZW5kRGVzY3JpcHRpb247XG4gIH1cblxuICAvKipcbiAgICogUHJpdmF0ZSBtZXRob2QgdG8gY2FsbCBoYW5kbGVCb3VuZGFyaWVzIHdoZW4gbmdPbkNoYW5nZXMgaXMgY2FsbGVkLlxuICAgKi9cbiAgcHJpdmF0ZSB1cGRhdGVJbmRleGVzKCk6IHZvaWQge1xuICAgIGxldCBpbmRleDogbnVtYmVyO1xuICAgIHRyeSB7XG4gICAgICBpbmRleCA9IGdldEluZGV4KHRoaXMuY3VycmVudEltYWdlLCB0aGlzLmltYWdlcyk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBjb25zb2xlLmVycm9yKCdDYW5ub3QgZ2V0IHRoZSBjdXJyZW50IGltYWdlIGluZGV4IGluIGN1cnJlbnQtaW1hZ2UnKTtcbiAgICAgIHRocm93IGVycjtcbiAgICB9XG4gICAgaWYgKHRoaXMuaXNPcGVuKSB7XG4gICAgICB0aGlzLmhhbmRsZUJvdW5kYXJpZXMoaW5kZXgpO1xuICAgIH1cbiAgfVxufVxuIl19