stream-chat-angular 5.0.0-v5.2 → 5.0.0-v5.4

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 (183) hide show
  1. package/assets/version.d.ts +1 -1
  2. package/esm2020/assets/version.mjs +2 -2
  3. package/esm2020/lib/attachment-list/attachment-list.component.mjs +11 -13
  4. package/esm2020/lib/attachment-preview-list/attachment-preview-list.component.mjs +9 -12
  5. package/esm2020/lib/message/message.component.mjs +18 -22
  6. package/esm2020/lib/message-actions-box/message-actions-box.component.mjs +3 -10
  7. package/esm2020/lib/message-input/autocomplete-textarea/autocomplete-textarea.component.mjs +5 -8
  8. package/esm2020/lib/message-input/message-input.component.mjs +13 -15
  9. package/esm2020/lib/message-input/textarea/textarea.component.mjs +3 -5
  10. package/esm2020/lib/message-reactions/message-reactions.component.mjs +9 -14
  11. package/esm2020/lib/notification-list/notification-list.component.mjs +3 -4
  12. package/esm2020/lib/theme.service.mjs +1 -101
  13. package/esm2020/lib/types.mjs +1 -1
  14. package/fesm2015/stream-chat-angular.mjs +60 -182
  15. package/fesm2015/stream-chat-angular.mjs.map +1 -1
  16. package/fesm2020/stream-chat-angular.mjs +60 -183
  17. package/fesm2020/stream-chat-angular.mjs.map +1 -1
  18. package/lib/attachment-list/attachment-list.component.d.ts +1 -3
  19. package/lib/attachment-preview-list/attachment-preview-list.component.d.ts +1 -3
  20. package/lib/channel.service.d.ts +4 -0
  21. package/lib/message/message.component.d.ts +2 -5
  22. package/lib/message-actions-box/message-actions-box.component.d.ts +1 -6
  23. package/lib/message-input/autocomplete-textarea/autocomplete-textarea.component.d.ts +0 -1
  24. package/lib/message-input/message-input.component.d.ts +3 -3
  25. package/lib/message-reactions/message-reactions.component.d.ts +1 -3
  26. package/lib/notification-list/notification-list.component.d.ts +0 -1
  27. package/lib/theme.service.d.ts +0 -42
  28. package/lib/types.d.ts +0 -1
  29. package/package.json +2 -2
  30. package/src/assets/styles/css/index.css +3 -1
  31. package/src/assets/styles/{v2/css → css}/index.layout.css +2 -2
  32. package/src/assets/styles/{v2/scss → scss}/AttachmentList/AttachmentList-layout.scss +1 -1
  33. package/src/assets/styles/{v2/scss → scss}/Message/Message-layout.scss +2 -2
  34. package/src/assets/styles/scss/_base.scss +7 -198
  35. package/src/assets/styles/scss/index.scss +35 -48
  36. package/src/assets/version.ts +1 -1
  37. package/src/assets/EmojiOneColor.woff2 +0 -0
  38. package/src/assets/NotoColorEmoji-flags.woff2 +0 -0
  39. package/src/assets/Poweredby_100px-White_VertText.png +0 -0
  40. package/src/assets/str-chat__alert.svg +0 -1
  41. package/src/assets/str-chat__file-file.svg +0 -20
  42. package/src/assets/str-chat__icon-chevron-down.svg +0 -1
  43. package/src/assets/str-chat__icon-search.svg +0 -1
  44. package/src/assets/str-chat__icon-send.svg +0 -1
  45. package/src/assets/str-chat__icon-sprite.png +0 -0
  46. package/src/assets/str-chat__icon-sprite@1x.png +0 -0
  47. package/src/assets/str-chat__icon-sprite@2x.png +0 -0
  48. package/src/assets/str-chat__icon-sprite@3x.png +0 -0
  49. package/src/assets/str-chat__loading-indicator.svg +0 -23
  50. package/src/assets/str-chat__reaction-list-sprite@1x.png +0 -0
  51. package/src/assets/str-chat__reaction-list-sprite@2x.png +0 -0
  52. package/src/assets/str-chat__reaction-list-sprite@3x.png +0 -0
  53. package/src/assets/str-chat__reactions-sprite@1x.png +0 -0
  54. package/src/assets/str-chat__reactions-sprite@2x.png +0 -0
  55. package/src/assets/str-chat__reactions-sprite@3x.png +0 -0
  56. package/src/assets/styles/assets/EmojiOneColor.woff2 +0 -0
  57. package/src/assets/styles/assets/NotoColorEmoji-flags.woff2 +0 -0
  58. package/src/assets/styles/assets/Poweredby_100px-White_VertText.png +0 -0
  59. package/src/assets/styles/assets/str-chat__reaction-list-sprite@1x.png +0 -0
  60. package/src/assets/styles/assets/str-chat__reaction-list-sprite@2x.png +0 -0
  61. package/src/assets/styles/assets/str-chat__reaction-list-sprite@3x.png +0 -0
  62. package/src/assets/styles/scss/ActionsBox.scss +0 -56
  63. package/src/assets/styles/scss/Attachment.scss +0 -329
  64. package/src/assets/styles/scss/AttachmentActions.scss +0 -44
  65. package/src/assets/styles/scss/Audio.scss +0 -113
  66. package/src/assets/styles/scss/Avatar.scss +0 -79
  67. package/src/assets/styles/scss/Card.scss +0 -125
  68. package/src/assets/styles/scss/ChannelHeader.scss +0 -284
  69. package/src/assets/styles/scss/ChannelList.scss +0 -141
  70. package/src/assets/styles/scss/ChannelListMessenger.scss +0 -9
  71. package/src/assets/styles/scss/ChannelPreview.scss +0 -133
  72. package/src/assets/styles/scss/ChannelSearch.scss +0 -124
  73. package/src/assets/styles/scss/ChatDown.scss +0 -15
  74. package/src/assets/styles/scss/DateSeparator.scss +0 -51
  75. package/src/assets/styles/scss/EditMessageForm.scss +0 -112
  76. package/src/assets/styles/scss/EventComponent.scss +0 -48
  77. package/src/assets/styles/scss/Gallery.scss +0 -121
  78. package/src/assets/styles/scss/ImageCarousel.scss +0 -45
  79. package/src/assets/styles/scss/InfiniteScrollPaginator.scss +0 -6
  80. package/src/assets/styles/scss/LoadMoreButton.scss +0 -44
  81. package/src/assets/styles/scss/LoadingChannels.scss +0 -70
  82. package/src/assets/styles/scss/LoadingIndicator.scss +0 -38
  83. package/src/assets/styles/scss/Message.scss +0 -1283
  84. package/src/assets/styles/scss/MessageActions.scss +0 -137
  85. package/src/assets/styles/scss/MessageCommerce.scss +0 -608
  86. package/src/assets/styles/scss/MessageInput.scss +0 -398
  87. package/src/assets/styles/scss/MessageInputFlat.scss +0 -323
  88. package/src/assets/styles/scss/MessageList.scss +0 -244
  89. package/src/assets/styles/scss/MessageLivestream.scss +0 -338
  90. package/src/assets/styles/scss/MessageNotification.scss +0 -43
  91. package/src/assets/styles/scss/MessageRepliesCountButton.scss +0 -33
  92. package/src/assets/styles/scss/MessageTeam.scss +0 -644
  93. package/src/assets/styles/scss/Modal.scss +0 -78
  94. package/src/assets/styles/scss/ReactionList.scss +0 -197
  95. package/src/assets/styles/scss/ReactionSelector.scss +0 -218
  96. package/src/assets/styles/scss/SendButton.scss +0 -20
  97. package/src/assets/styles/scss/SimpleReactionsList.scss +0 -76
  98. package/src/assets/styles/scss/SmallMessageInput.scss +0 -171
  99. package/src/assets/styles/scss/Thread.scss +0 -381
  100. package/src/assets/styles/scss/Tooltip.scss +0 -41
  101. package/src/assets/styles/scss/TypingIndicator.scss +0 -80
  102. package/src/assets/styles/scss/VirtualMessage.scss +0 -288
  103. package/src/assets/styles/scss/_variables.scss +0 -161
  104. package/src/assets/styles/v2/css/index.css +0 -3
  105. package/src/assets/styles/v2/scss/_base.scss +0 -28
  106. package/src/assets/styles/v2/scss/index.scss +0 -37
  107. package/src/assets/styles/vendor/emoji-mart.scss +0 -514
  108. package/src/assets/styles/vendor/mml-react.scss +0 -2246
  109. package/src/assets/styles/vendor/react-file-utils.scss +0 -441
  110. package/src/assets/styles/vendor/react-image-gallery.scss +0 -237
  111. /package/src/assets/styles/{v2/css → css}/emoji-mart.css +0 -0
  112. /package/src/assets/styles/{v2/css → css}/emoji-replacement.css +0 -0
  113. /package/src/assets/styles/{v2/scss → scss}/AttachmentList/AttachmentList-theme.scss +0 -0
  114. /package/src/assets/styles/{v2/scss → scss}/AttachmentPreviewList/AttachmentPreviewList-layout.scss +0 -0
  115. /package/src/assets/styles/{v2/scss → scss}/AttachmentPreviewList/AttachmentPreviewList-theme.scss +0 -0
  116. /package/src/assets/styles/{v2/scss → scss}/Autocomplete/Autocomplete-layout.scss +0 -0
  117. /package/src/assets/styles/{v2/scss → scss}/Autocomplete/Autocomplete-theme.scss +0 -0
  118. /package/src/assets/styles/{v2/scss → scss}/Avatar/Avatar-layout.scss +0 -0
  119. /package/src/assets/styles/{v2/scss → scss}/Avatar/Avatar-theme.scss +0 -0
  120. /package/src/assets/styles/{v2/scss → scss}/BaseImage/BaseImage-layout.scss +0 -0
  121. /package/src/assets/styles/{v2/scss → scss}/BaseImage/BaseImage-theme.scss +0 -0
  122. /package/src/assets/styles/{v2/scss → scss}/BaseImage/index.scss +0 -0
  123. /package/src/assets/styles/{v2/scss → scss}/Channel/Channel-layout.scss +0 -0
  124. /package/src/assets/styles/{v2/scss → scss}/Channel/Channel-theme.scss +0 -0
  125. /package/src/assets/styles/{v2/scss → scss}/ChannelHeader/ChannelHeader-layout.scss +0 -0
  126. /package/src/assets/styles/{v2/scss → scss}/ChannelHeader/ChannelHeader-theme.scss +0 -0
  127. /package/src/assets/styles/{v2/scss → scss}/ChannelList/ChannelList-layout.scss +0 -0
  128. /package/src/assets/styles/{v2/scss → scss}/ChannelList/ChannelList-theme.scss +0 -0
  129. /package/src/assets/styles/{v2/scss → scss}/ChannelPreview/ChannelPreview-layout.scss +0 -0
  130. /package/src/assets/styles/{v2/scss → scss}/ChannelPreview/ChannelPreview-theme.scss +0 -0
  131. /package/src/assets/styles/{v2/scss → scss}/ChannelSearch/ChannelSearch-layout.scss +0 -0
  132. /package/src/assets/styles/{v2/scss → scss}/ChannelSearch/ChannelSearch-theme.scss +0 -0
  133. /package/src/assets/styles/{v2/scss → scss}/EditMessageForm/EditMessageForm-layout.scss +0 -0
  134. /package/src/assets/styles/{v2/scss → scss}/EditMessageForm/EditMessageForm-theme.scss +0 -0
  135. /package/src/assets/styles/{v2/scss → scss}/ImageCarousel/ImageCarousel-layout.scss +0 -0
  136. /package/src/assets/styles/{v2/scss → scss}/ImageCarousel/ImageCarousel-theme.scss +0 -0
  137. /package/src/assets/styles/{v2/scss → scss}/LinkPreview/LinkPreview-layout.scss +0 -0
  138. /package/src/assets/styles/{v2/scss → scss}/LinkPreview/LinkPreview-theme.scss +0 -0
  139. /package/src/assets/styles/{v2/scss → scss}/LinkPreview/index.scss +0 -0
  140. /package/src/assets/styles/{v2/scss → scss}/LoadingIndicator/LoadingIndicator-layout.scss +0 -0
  141. /package/src/assets/styles/{v2/scss → scss}/LoadingIndicator/LoadingIndicator-theme.scss +0 -0
  142. /package/src/assets/styles/{v2/scss → scss}/Message/Message-theme.scss +0 -0
  143. /package/src/assets/styles/{v2/scss → scss}/MessageActionsBox/MessageActionsBox-layout.scss +0 -0
  144. /package/src/assets/styles/{v2/scss → scss}/MessageActionsBox/MessageActionsBox-theme.scss +0 -0
  145. /package/src/assets/styles/{v2/scss → scss}/MessageBouncePrompt/MessageBouncePrompt-layout.scss +0 -0
  146. /package/src/assets/styles/{v2/scss → scss}/MessageBouncePrompt/MessageBouncePrompt-theme.scss +0 -0
  147. /package/src/assets/styles/{v2/scss → scss}/MessageInput/MessageInput-layout.scss +0 -0
  148. /package/src/assets/styles/{v2/scss → scss}/MessageInput/MessageInput-theme.scss +0 -0
  149. /package/src/assets/styles/{v2/scss → scss}/MessageList/MessageList-layout.scss +0 -0
  150. /package/src/assets/styles/{v2/scss → scss}/MessageList/MessageList-theme.scss +0 -0
  151. /package/src/assets/styles/{v2/scss → scss}/MessageList/VirtualizedMessageList-layout.scss +0 -0
  152. /package/src/assets/styles/{v2/scss → scss}/MessageList/VirtualizedMessageList-theme.scss +0 -0
  153. /package/src/assets/styles/{v2/scss → scss}/MessageReactions/MessageReactions-layout.scss +0 -0
  154. /package/src/assets/styles/{v2/scss → scss}/MessageReactions/MessageReactions-theme.scss +0 -0
  155. /package/src/assets/styles/{v2/scss → scss}/MessageReactions/MessageReactionsSelector-layout.scss +0 -0
  156. /package/src/assets/styles/{v2/scss → scss}/MessageReactions/MessageReactionsSelector-theme.scss +0 -0
  157. /package/src/assets/styles/{v2/scss → scss}/Modal/Modal-layout.scss +0 -0
  158. /package/src/assets/styles/{v2/scss → scss}/Modal/Modal-theme.scss +0 -0
  159. /package/src/assets/styles/{v2/scss → scss}/Notification/MessageNotification-layout.scss +0 -0
  160. /package/src/assets/styles/{v2/scss → scss}/Notification/MessageNotification-theme.scss +0 -0
  161. /package/src/assets/styles/{v2/scss → scss}/Notification/Notification-layout.scss +0 -0
  162. /package/src/assets/styles/{v2/scss → scss}/Notification/Notification-theme.scss +0 -0
  163. /package/src/assets/styles/{v2/scss → scss}/Notification/NotificationList-layout.scss +0 -0
  164. /package/src/assets/styles/{v2/scss → scss}/Notification/NotificationList-theme.scss +0 -0
  165. /package/src/assets/styles/{v2/scss → scss}/Thread/Thread-layout.scss +0 -0
  166. /package/src/assets/styles/{v2/scss → scss}/Thread/Thread-theme.scss +0 -0
  167. /package/src/assets/styles/{v2/scss → scss}/Tooltip/Tooltip-layout.scss +0 -0
  168. /package/src/assets/styles/{v2/scss → scss}/Tooltip/Tooltip-theme.scss +0 -0
  169. /package/src/assets/styles/{v2/scss → scss}/TypingIndicator/TypingIndicator-layout.scss +0 -0
  170. /package/src/assets/styles/{v2/scss → scss}/TypingIndicator/TypingIndicator-theme.scss +0 -0
  171. /package/src/assets/styles/{v2/scss → scss}/_emoji-replacement.scss +0 -0
  172. /package/src/assets/styles/{v2/scss → scss}/_global-layout-variables.scss +0 -0
  173. /package/src/assets/styles/{v2/scss → scss}/_global-theme-variables.scss +0 -0
  174. /package/src/assets/styles/{v2/scss → scss}/_icons.scss +0 -0
  175. /package/src/assets/styles/{v2/scss → scss}/_palette-variables.scss +0 -0
  176. /package/src/assets/styles/{v2/scss → scss}/_utils.scss +0 -0
  177. /package/src/assets/styles/{v2/scss → scss}/common/CTAButton/CTAButton-layout.scss +0 -0
  178. /package/src/assets/styles/{v2/scss → scss}/common/CTAButton/CTAButton-theme.scss +0 -0
  179. /package/src/assets/styles/{v2/scss → scss}/common/CircleFAButton/CircleFAButton-layout.scss +0 -0
  180. /package/src/assets/styles/{v2/scss → scss}/common/CircleFAButton/CircleFAButton-theme.scss +0 -0
  181. /package/src/assets/styles/{v2/scss → scss}/index.layout.scss +0 -0
  182. /package/src/assets/styles/{v2/scss → scss}/vendor/emoji-mart.scss +0 -0
  183. /package/src/assets/styles/{v2/scss → scss}/vendor/react-image-gallery.scss +0 -0
@@ -1 +1 @@
1
- export declare const version = "5.0.0-v5.2";
1
+ export declare const version = "5.0.0-v5.4";
@@ -1,2 +1,2 @@
1
- export const version = '5.0.0-v5.2';
2
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVyc2lvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL3N0cmVhbS1jaGF0LWFuZ3VsYXIvc3JjL2Fzc2V0cy92ZXJzaW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE1BQU0sQ0FBQyxNQUFNLE9BQU8sR0FBRyxZQUFZLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgY29uc3QgdmVyc2lvbiA9ICc1LjAuMC12NS4yJztcbiJdfQ==
1
+ export const version = '5.0.0-v5.4';
2
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmVyc2lvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL3N0cmVhbS1jaGF0LWFuZ3VsYXIvc3JjL2Fzc2V0cy92ZXJzaW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE1BQU0sQ0FBQyxNQUFNLE9BQU8sR0FBRyxZQUFZLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgY29uc3QgdmVyc2lvbiA9ICc1LjAuMC12NS40JztcbiJdfQ==
@@ -5,17 +5,16 @@ import * as i0 from "@angular/core";
5
5
  import * as i1 from "../custom-templates.service";
6
6
  import * as i2 from "../channel.service";
7
7
  import * as i3 from "../attachment-configuration.service";
8
- import * as i4 from "../theme.service";
9
- import * as i5 from "@angular/common";
10
- import * as i6 from "../modal/modal.component";
11
- import * as i7 from "../icon-placeholder/icon-placeholder.component";
12
- import * as i8 from "../voice-recording/voice-recording.component";
13
- import * as i9 from "@ngx-translate/core";
8
+ import * as i4 from "@angular/common";
9
+ import * as i5 from "../modal/modal.component";
10
+ import * as i6 from "../icon-placeholder/icon-placeholder.component";
11
+ import * as i7 from "../voice-recording/voice-recording.component";
12
+ import * as i8 from "@ngx-translate/core";
14
13
  /**
15
14
  * The `AttachmentList` component displays the attachments of a message
16
15
  */
17
16
  export class AttachmentListComponent {
18
- constructor(customTemplatesService, channelService, attachmentConfigurationService, themeService) {
17
+ constructor(customTemplatesService, channelService, attachmentConfigurationService) {
19
18
  this.customTemplatesService = customTemplatesService;
20
19
  this.channelService = channelService;
21
20
  this.attachmentConfigurationService = attachmentConfigurationService;
@@ -32,7 +31,6 @@ export class AttachmentListComponent {
32
31
  this.imagesToView = [];
33
32
  this.imagesToViewCurrentIndex = 0;
34
33
  this.attachmentConfigurations = new Map();
35
- this.themeVersion = themeService.themeVersion;
36
34
  }
37
35
  ngOnChanges(changes) {
38
36
  if (changes.attachments) {
@@ -183,12 +181,12 @@ export class AttachmentListComponent {
183
181
  this.imagesToView = [];
184
182
  }
185
183
  }
186
- AttachmentListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: AttachmentListComponent, deps: [{ token: i1.CustomTemplatesService }, { token: i2.ChannelService }, { token: i3.AttachmentConfigurationService }, { token: i4.ThemeService }], target: i0.ɵɵFactoryTarget.Component });
187
- AttachmentListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: AttachmentListComponent, selector: "stream-attachment-list", inputs: { messageId: "messageId", parentMessageId: "parentMessageId", attachments: "attachments" }, outputs: { imageModalStateChange: "imageModalStateChange" }, host: { properties: { "class": "this.class" } }, viewQueries: [{ propertyName: "modalContent", first: true, predicate: ["modalContent"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<div *ngIf=\"orderedAttachments.length > 0\" class=\"str-chat__attachment-list\">\n <ng-container\n *ngFor=\"let attachment of orderedAttachments; trackBy: trackByUrl\"\n >\n <div\n data-testclass=\"attachment-container\"\n class=\"str-chat__message-attachment str-chat__message-attachment--{{\n attachment.type\n }} str-chat__message-attachment-dynamic-size\"\n [class.str-chat__message-attachment--card]=\"isCard(attachment)\"\n [class.str-chat-angular__message-attachment-file-single]=\"\n isFile(attachment)\n \"\n [class.str-chat__message-attachment--voice-recording]=\"\n isVoiceMessage(attachment)\n \"\n [class.str-chat__message-attachment-with-actions]=\"\n attachment.actions && attachment.actions.length > 0\n \"\n [class.str-chat__message-attachment--svg-image]=\"isSvg(attachment)\"\n >\n <ng-container *ngIf=\"isImage(attachment)\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.imageAttachmentTemplate$ | async) ||\n defaultImage;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultImage let-attachmentContext=\"attachment\">\n <img\n #imgElement\n class=\"str-chat__message-attachment--img\"\n data-testclass=\"image\"\n [src]=\"\n getImageAttachmentConfiguration(\n attachmentContext,\n 'single',\n imgElement\n ).url\n \"\n [alt]=\"attachmentContext?.fallback\"\n [ngStyle]=\"{\n height: getImageAttachmentConfiguration(\n attachmentContext,\n 'single',\n imgElement\n ).height,\n width: getImageAttachmentConfiguration(\n attachmentContext,\n 'single',\n imgElement\n ).width,\n '--original-height': getImageAttachmentConfiguration(\n attachmentContext,\n 'single',\n imgElement\n ).originalHeight,\n '--original-width': getImageAttachmentConfiguration(\n attachmentContext,\n 'single',\n imgElement\n ).originalWidth\n }\"\n (click)=\"openImageModal([attachmentContext])\"\n (keyup.enter)=\"openImageModal([attachmentContext])\"\n />\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"isGallery(attachment)\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.galleryAttachmentTemplate$ | async) ||\n defaultGallery;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultGallery let-attachmentContext=\"attachment\">\n <div\n class=\"str-chat__gallery\"\n data-testid=\"image-gallery\"\n [class.str-chat__gallery--square]=\"\n (attachmentContext?.images)!.length > 3\n \"\n [class.str-chat__gallery-two-rows]=\"\n (attachmentContext?.images)!.length > 2\n \"\n >\n <ng-container\n *ngFor=\"\n let galleryImage of attachmentContext.images;\n let index = index;\n let isLast = last;\n trackBy: trackByImageUrl\n \"\n >\n <button\n *ngIf=\"index < 3 || (index === 3 && isLast)\"\n class=\"str-chat__gallery-image\"\n data-testclass=\"gallery-image\"\n [class.str-chat__message-attachment--svg-image]=\"\n isSvg(galleryImage)\n \"\n (click)=\"openImageModal(attachmentContext.images!, index)\"\n (keyup.enter)=\"openImageModal(attachmentContext.images!, index)\"\n >\n <img\n #imgElement\n fetchpriority=\"low\"\n loading=\"lazy\"\n [src]=\"\n getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n imgElement\n ).url\n \"\n [alt]=\"galleryImage.fallback\"\n [style.--original-height]=\"\n getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n imgElement\n ).originalHeight\n \"\n [style.--original-width]=\"\n getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n imgElement\n ).originalWidth\n \"\n [ngStyle]=\"{\n height: getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n imgElement\n ).height,\n width: getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n imgElement\n ).width\n }\"\n />\n </button>\n <button\n *ngIf=\"index === 3 && !isLast\"\n #element\n class=\"str-chat__gallery-placeholder\"\n data-testclass=\"gallery-image\"\n data-testid=\"more-image-button\"\n [class.str-chat__message-attachment--svg-image]=\"\n isSvg(galleryImage)\n \"\n [ngStyle]=\"{\n 'background-image':\n 'url(' +\n getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n element\n ).url +\n ')',\n height: getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n element\n ).height,\n width: getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n element\n ).width,\n '--original-height': getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n element\n ).originalHeight,\n '--original-width': getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n element\n ).originalWidth\n }\"\n (click)=\"openImageModal(attachmentContext.images!, index)\"\n (keyup.enter)=\"openImageModal(attachmentContext.images!, index)\"\n >\n <p\n [innerHTML]=\"\n 'streamChat.{{ imageCount }} more'\n | translate\n : { imageCount: attachmentContext!.images!.length - 4 }\n \"\n ></p>\n </button>\n </ng-container>\n </div>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"isVideo(attachment)\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.videoAttachmentTemplate$ | async) ||\n defaultVideo;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultVideo let-attachmentContext=\"attachment\">\n <div\n class=\"str-chat__player-wrapper\"\n data-testclass=\"video-attachment-parent\"\n [style.--original-height]=\"\n getVideoAttachmentConfiguration(attachmentContext, videoElement)\n .originalHeight\n \"\n [style.--original-width]=\"\n getVideoAttachmentConfiguration(attachmentContext, videoElement)\n .originalWidth\n \"\n [ngStyle]=\"{\n height: getVideoAttachmentConfiguration(\n attachmentContext,\n videoElement\n ).height,\n width: getVideoAttachmentConfiguration(\n attachmentContext,\n videoElement\n ).width\n }\"\n >\n <video\n #videoElement\n class=\"str-chat__video-angular\"\n controls\n data-testclass=\"video-attachment\"\n [src]=\"\n getVideoAttachmentConfiguration(attachmentContext, videoElement)\n .url\n \"\n [poster]=\"\n getVideoAttachmentConfiguration(attachmentContext, videoElement)\n .thumbUrl\n \"\n ></video>\n </div>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"isFile(attachment)\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.fileAttachmentTemplate$ | async) ||\n defaultFile;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultFile let-attachmentContext=\"attachment\">\n <div\n class=\"\n str-chat__message-attachment-file--item\n str-chat-angular__message-attachment-file-single\n \"\n >\n <stream-icon-placeholder\n *ngIf=\"themeVersion === '1'\"\n icon=\"file\"\n [size]=\"30\"\n ></stream-icon-placeholder>\n <stream-icon-placeholder\n *ngIf=\"themeVersion === '2'\"\n icon=\"unspecified-filetype\"\n [size]=\"30\"\n ></stream-icon-placeholder>\n <div class=\"str-chat__message-attachment-file--item-text\">\n <a\n class=\"str-chat__message-attachment-file--item-first-row\"\n data-testclass=\"file-link\"\n target=\"_blank\"\n href=\"{{ attachmentContext.asset_url }}\"\n >\n <div\n data-testclass=\"file-title\"\n class=\"str-chat__message-attachment-file--item-name\"\n >\n {{ attachmentContext.title }}\n </div>\n <stream-icon-placeholder\n class=\"str-chat__message-attachment-download-icon\"\n icon=\"download\"\n ></stream-icon-placeholder>\n </a>\n <span\n *ngIf=\"hasFileSize(attachmentContext)\"\n class=\"str-chat__message-attachment-file--item-size\"\n data-testclass=\"size\"\n >{{ getFileSize(attachmentContext) }}</span\n >\n </div>\n </div>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"isVoiceMessage(attachment)\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.voiceRecordingAttachmentTemplate$\n | async) || defaultRecording;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultRecording>\n <stream-voice-recording\n data-testclass=\"voice-recording\"\n [attachment]=\"attachment\"\n ></stream-voice-recording>\n </ng-template>\n </ng-container>\n <ng-container\n *ngIf=\"\n isCard(attachment) &&\n getCardAttachmentConfiguration(attachment) as attachmentConfiguration\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.cardAttachmentTemplate$ | async) ||\n defaultCard;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultCard let-attachmentContext=\"attachment\">\n <div\n class=\"str-chat__message-attachment-card str-chat__message-attachment-card--{{\n attachmentContext.type\n }}\"\n >\n <div\n *ngIf=\"attachmentConfiguration.url\"\n class=\"str-chat__message-attachment-card--header\"\n >\n <img\n fetchpriority=\"low\"\n loading=\"lazy\"\n data-testclass=\"card-img\"\n alt=\"{{ attachmentConfiguration.url }}\"\n src=\"{{ attachmentConfiguration.url }}\"\n [ngStyle]=\"{\n height: attachmentConfiguration.height,\n width: attachmentConfiguration.width\n }\"\n />\n </div>\n <div class=\"str-chat__message-attachment-card--content\">\n <div class=\"str-chat__message-attachment-card--flex\">\n <div\n *ngIf=\"attachmentContext.title\"\n data-testclass=\"card-title\"\n class=\"str-chat__message-attachment-card--title\"\n >\n {{ attachmentContext.title }}\n </div>\n <div\n *ngIf=\"attachmentContext.text\"\n class=\"str-chat__message-attachment-card--text\"\n data-testclass=\"card-text\"\n >\n {{ attachmentContext.text }}\n </div>\n <a\n *ngIf=\"\n attachmentContext.title_link ||\n attachmentContext.og_scrape_url\n \"\n class=\"str-chat__message-attachment-card--url\"\n data-testclass=\"url-link\"\n noopener\n noreferrer\n target=\"_blank\"\n href=\"{{\n attachmentContext.title_link ||\n attachmentContext.og_scrape_url\n }}\"\n >\n {{\n trimUrl(\n attachmentContext.title_link ||\n attachmentContext.og_scrape_url\n )\n }}\n </a>\n </div>\n </div>\n </div>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"attachment.actions && attachment.actions.length > 0\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.attachmentActionsTemplate$ | async) ||\n defaultActions;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultActions let-attachmentContext=\"attachment\">\n <div class=\"str-chat__message-attachment-actions\">\n <div class=\"str-chat__message-attachment-actions-form\">\n <button\n *ngFor=\"\n let action of attachmentContext.actions;\n trackBy: trackByActionValue\n \"\n data-testclass=\"attachment-action\"\n class=\"str-chat__message-attachment-actions-button str-chat__message-attachment-actions-button--{{\n action.style\n }}\"\n (click)=\"sendAction(action)\"\n (keyup.enter)=\"sendAction(action)\"\n >\n {{ action.text }}\n </button>\n </div>\n </div>\n </ng-template>\n </ng-container>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"imagesToView && imagesToView.length > 0\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.modalTemplate$ | async) || defaultModal;\n context: getModalContext()\n \"\n ></ng-container>\n </ng-container>\n</div>\n\n<ng-template\n #defaultModal\n let-isOpen=\"isOpen\"\n let-isOpenChangeHandler=\"isOpenChangeHandler\"\n let-content=\"content\"\n>\n <stream-modal\n class=\"stream-chat-angular__image-modal-host\"\n [isOpen]=\"isOpen\"\n [content]=\"content\"\n (isOpenChange)=\"isOpenChangeHandler($event)\"\n >\n </stream-modal>\n</ng-template>\n\n<ng-template #modalContent>\n <div class=\"stream-chat-angular__image-modal str-chat__image-carousel\">\n <img\n #imgElement\n class=\"\n stream-chat-angular__image-modal-image\n str-chat__image-carousel-image\n \"\n data-testid=\"modal-image\"\n [src]=\"\n getCarouselImageAttachmentConfiguration(\n imagesToView[imagesToViewCurrentIndex],\n imgElement\n ).url\n \"\n [style.--original-height]=\"\n getCarouselImageAttachmentConfiguration(\n imagesToView[imagesToViewCurrentIndex],\n imgElement\n ).originalHeight\n \"\n [style.--original-width]=\"\n getCarouselImageAttachmentConfiguration(\n imagesToView[imagesToViewCurrentIndex],\n imgElement\n ).originalWidth\n \"\n [alt]=\"imagesToView[imagesToViewCurrentIndex].fallback\"\n [ngStyle]=\"{\n width: getCarouselImageAttachmentConfiguration(\n imagesToView[imagesToViewCurrentIndex],\n imgElement\n ).width,\n height: getCarouselImageAttachmentConfiguration(\n imagesToView[imagesToViewCurrentIndex],\n imgElement\n ).height\n }\"\n />\n <div>\n <button\n class=\"\n stream-chat-angular__image-modal-stepper\n str-chat__image-carousel-stepper str-chat__image-carousel-stepper-prev\n \"\n data-testid=\"image-modal-prev\"\n type=\"button\"\n [ngStyle]=\"{\n visibility: isImageModalPrevButtonVisible ? 'visible' : 'hidden'\n }\"\n (click)=\"stepImages(-1)\"\n (keyup.enter)=\"stepImages(-1)\"\n >\n <stream-icon-placeholder icon=\"arrow-left\"></stream-icon-placeholder>\n </button>\n <button\n class=\"\n stream-chat-angular__image-modal-stepper\n str-chat__image-carousel-stepper str-chat__image-carousel-stepper-next\n \"\n type=\"button\"\n data-testid=\"image-modal-next\"\n [ngStyle]=\"{\n visibility: isImageModalNextButtonVisible ? 'visible' : 'hidden'\n }\"\n (click)=\"stepImages(1)\"\n (keyup.enter)=\"stepImages(1)\"\n >\n <stream-icon-placeholder icon=\"arrow-right\"></stream-icon-placeholder>\n </button>\n </div>\n </div>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i5.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i6.ModalComponent, selector: "stream-modal", inputs: ["isOpen", "content"], outputs: ["isOpenChange"] }, { kind: "component", type: i7.IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: ["icon", "size"] }, { kind: "component", type: i8.VoiceRecordingComponent, selector: "stream-voice-recording", inputs: ["attachment"] }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }, { kind: "pipe", type: i9.TranslatePipe, name: "translate" }] });
184
+ AttachmentListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: AttachmentListComponent, deps: [{ token: i1.CustomTemplatesService }, { token: i2.ChannelService }, { token: i3.AttachmentConfigurationService }], target: i0.ɵɵFactoryTarget.Component });
185
+ AttachmentListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: AttachmentListComponent, selector: "stream-attachment-list", inputs: { messageId: "messageId", parentMessageId: "parentMessageId", attachments: "attachments" }, outputs: { imageModalStateChange: "imageModalStateChange" }, host: { properties: { "class": "this.class" } }, viewQueries: [{ propertyName: "modalContent", first: true, predicate: ["modalContent"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<div *ngIf=\"orderedAttachments.length > 0\" class=\"str-chat__attachment-list\">\n <ng-container\n *ngFor=\"let attachment of orderedAttachments; trackBy: trackByUrl\"\n >\n <div\n data-testclass=\"attachment-container\"\n class=\"str-chat__message-attachment str-chat__message-attachment--{{\n attachment.type\n }} str-chat__message-attachment-dynamic-size\"\n [class.str-chat__message-attachment--card]=\"isCard(attachment)\"\n [class.str-chat-angular__message-attachment-file-single]=\"\n isFile(attachment)\n \"\n [class.str-chat__message-attachment--voice-recording]=\"\n isVoiceMessage(attachment)\n \"\n [class.str-chat__message-attachment-with-actions]=\"\n attachment.actions && attachment.actions.length > 0\n \"\n [class.str-chat__message-attachment--svg-image]=\"isSvg(attachment)\"\n >\n <ng-container *ngIf=\"isImage(attachment)\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.imageAttachmentTemplate$ | async) ||\n defaultImage;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultImage let-attachmentContext=\"attachment\">\n <img\n #imgElement\n class=\"str-chat__message-attachment--img\"\n data-testclass=\"image\"\n [src]=\"\n getImageAttachmentConfiguration(\n attachmentContext,\n 'single',\n imgElement\n ).url\n \"\n [alt]=\"attachmentContext?.fallback\"\n [ngStyle]=\"{\n height: getImageAttachmentConfiguration(\n attachmentContext,\n 'single',\n imgElement\n ).height,\n width: getImageAttachmentConfiguration(\n attachmentContext,\n 'single',\n imgElement\n ).width,\n '--original-height': getImageAttachmentConfiguration(\n attachmentContext,\n 'single',\n imgElement\n ).originalHeight,\n '--original-width': getImageAttachmentConfiguration(\n attachmentContext,\n 'single',\n imgElement\n ).originalWidth\n }\"\n (click)=\"openImageModal([attachmentContext])\"\n (keyup.enter)=\"openImageModal([attachmentContext])\"\n />\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"isGallery(attachment)\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.galleryAttachmentTemplate$ | async) ||\n defaultGallery;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultGallery let-attachmentContext=\"attachment\">\n <div\n class=\"str-chat__gallery\"\n data-testid=\"image-gallery\"\n [class.str-chat__gallery--square]=\"\n (attachmentContext?.images)!.length > 3\n \"\n [class.str-chat__gallery-two-rows]=\"\n (attachmentContext?.images)!.length > 2\n \"\n >\n <ng-container\n *ngFor=\"\n let galleryImage of attachmentContext.images;\n let index = index;\n let isLast = last;\n trackBy: trackByImageUrl\n \"\n >\n <button\n *ngIf=\"index < 3 || (index === 3 && isLast)\"\n class=\"str-chat__gallery-image\"\n data-testclass=\"gallery-image\"\n [class.str-chat__message-attachment--svg-image]=\"\n isSvg(galleryImage)\n \"\n (click)=\"openImageModal(attachmentContext.images!, index)\"\n (keyup.enter)=\"openImageModal(attachmentContext.images!, index)\"\n >\n <img\n #imgElement\n fetchpriority=\"low\"\n loading=\"lazy\"\n [src]=\"\n getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n imgElement\n ).url\n \"\n [alt]=\"galleryImage.fallback\"\n [style.--original-height]=\"\n getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n imgElement\n ).originalHeight\n \"\n [style.--original-width]=\"\n getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n imgElement\n ).originalWidth\n \"\n [ngStyle]=\"{\n height: getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n imgElement\n ).height,\n width: getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n imgElement\n ).width\n }\"\n />\n </button>\n <button\n *ngIf=\"index === 3 && !isLast\"\n #element\n class=\"str-chat__gallery-placeholder\"\n data-testclass=\"gallery-image\"\n data-testid=\"more-image-button\"\n [class.str-chat__message-attachment--svg-image]=\"\n isSvg(galleryImage)\n \"\n [ngStyle]=\"{\n 'background-image':\n 'url(' +\n getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n element\n ).url +\n ')',\n height: getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n element\n ).height,\n width: getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n element\n ).width,\n '--original-height': getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n element\n ).originalHeight,\n '--original-width': getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n element\n ).originalWidth\n }\"\n (click)=\"openImageModal(attachmentContext.images!, index)\"\n (keyup.enter)=\"openImageModal(attachmentContext.images!, index)\"\n >\n <p\n [innerHTML]=\"\n 'streamChat.{{ imageCount }} more'\n | translate\n : { imageCount: attachmentContext!.images!.length - 4 }\n \"\n ></p>\n </button>\n </ng-container>\n </div>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"isVideo(attachment)\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.videoAttachmentTemplate$ | async) ||\n defaultVideo;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultVideo let-attachmentContext=\"attachment\">\n <div\n class=\"str-chat__player-wrapper\"\n data-testclass=\"video-attachment-parent\"\n [style.--original-height]=\"\n getVideoAttachmentConfiguration(attachmentContext, videoElement)\n .originalHeight\n \"\n [style.--original-width]=\"\n getVideoAttachmentConfiguration(attachmentContext, videoElement)\n .originalWidth\n \"\n [ngStyle]=\"{\n height: getVideoAttachmentConfiguration(\n attachmentContext,\n videoElement\n ).height,\n width: getVideoAttachmentConfiguration(\n attachmentContext,\n videoElement\n ).width\n }\"\n >\n <video\n #videoElement\n class=\"str-chat__video-angular\"\n controls\n data-testclass=\"video-attachment\"\n [src]=\"\n getVideoAttachmentConfiguration(attachmentContext, videoElement)\n .url\n \"\n [poster]=\"\n getVideoAttachmentConfiguration(attachmentContext, videoElement)\n .thumbUrl\n \"\n ></video>\n </div>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"isFile(attachment)\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.fileAttachmentTemplate$ | async) ||\n defaultFile;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultFile let-attachmentContext=\"attachment\">\n <div\n class=\"\n str-chat__message-attachment-file--item\n str-chat-angular__message-attachment-file-single\n \"\n >\n <stream-icon-placeholder\n icon=\"unspecified-filetype\"\n [size]=\"30\"\n ></stream-icon-placeholder>\n <div class=\"str-chat__message-attachment-file--item-text\">\n <a\n class=\"str-chat__message-attachment-file--item-first-row\"\n data-testclass=\"file-link\"\n target=\"_blank\"\n href=\"{{ attachmentContext.asset_url }}\"\n >\n <div\n data-testclass=\"file-title\"\n class=\"str-chat__message-attachment-file--item-name\"\n >\n {{ attachmentContext.title }}\n </div>\n <stream-icon-placeholder\n class=\"str-chat__message-attachment-download-icon\"\n icon=\"download\"\n ></stream-icon-placeholder>\n </a>\n <span\n *ngIf=\"hasFileSize(attachmentContext)\"\n class=\"str-chat__message-attachment-file--item-size\"\n data-testclass=\"size\"\n >{{ getFileSize(attachmentContext) }}</span\n >\n </div>\n </div>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"isVoiceMessage(attachment)\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.voiceRecordingAttachmentTemplate$\n | async) || defaultRecording;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultRecording>\n <stream-voice-recording\n data-testclass=\"voice-recording\"\n [attachment]=\"attachment\"\n ></stream-voice-recording>\n </ng-template>\n </ng-container>\n <ng-container\n *ngIf=\"\n isCard(attachment) &&\n getCardAttachmentConfiguration(attachment) as attachmentConfiguration\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.cardAttachmentTemplate$ | async) ||\n defaultCard;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultCard let-attachmentContext=\"attachment\">\n <div\n class=\"str-chat__message-attachment-card str-chat__message-attachment-card--{{\n attachmentContext.type\n }}\"\n >\n <div\n *ngIf=\"attachmentConfiguration.url\"\n class=\"str-chat__message-attachment-card--header\"\n >\n <img\n fetchpriority=\"low\"\n loading=\"lazy\"\n data-testclass=\"card-img\"\n alt=\"{{ attachmentConfiguration.url }}\"\n src=\"{{ attachmentConfiguration.url }}\"\n [ngStyle]=\"{\n height: attachmentConfiguration.height,\n width: attachmentConfiguration.width\n }\"\n />\n </div>\n <div class=\"str-chat__message-attachment-card--content\">\n <div class=\"str-chat__message-attachment-card--flex\">\n <div\n *ngIf=\"attachmentContext.title\"\n data-testclass=\"card-title\"\n class=\"str-chat__message-attachment-card--title\"\n >\n {{ attachmentContext.title }}\n </div>\n <div\n *ngIf=\"attachmentContext.text\"\n class=\"str-chat__message-attachment-card--text\"\n data-testclass=\"card-text\"\n >\n {{ attachmentContext.text }}\n </div>\n <a\n *ngIf=\"\n attachmentContext.title_link ||\n attachmentContext.og_scrape_url\n \"\n class=\"str-chat__message-attachment-card--url\"\n data-testclass=\"url-link\"\n noopener\n noreferrer\n target=\"_blank\"\n href=\"{{\n attachmentContext.title_link ||\n attachmentContext.og_scrape_url\n }}\"\n >\n {{\n trimUrl(\n attachmentContext.title_link ||\n attachmentContext.og_scrape_url\n )\n }}\n </a>\n </div>\n </div>\n </div>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"attachment.actions && attachment.actions.length > 0\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.attachmentActionsTemplate$ | async) ||\n defaultActions;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultActions let-attachmentContext=\"attachment\">\n <div class=\"str-chat__message-attachment-actions\">\n <div class=\"str-chat__message-attachment-actions-form\">\n <button\n *ngFor=\"\n let action of attachmentContext.actions;\n trackBy: trackByActionValue\n \"\n data-testclass=\"attachment-action\"\n class=\"str-chat__message-attachment-actions-button str-chat__message-attachment-actions-button--{{\n action.style\n }}\"\n (click)=\"sendAction(action)\"\n (keyup.enter)=\"sendAction(action)\"\n >\n {{ action.text }}\n </button>\n </div>\n </div>\n </ng-template>\n </ng-container>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"imagesToView && imagesToView.length > 0\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.modalTemplate$ | async) || defaultModal;\n context: getModalContext()\n \"\n ></ng-container>\n </ng-container>\n</div>\n\n<ng-template\n #defaultModal\n let-isOpen=\"isOpen\"\n let-isOpenChangeHandler=\"isOpenChangeHandler\"\n let-content=\"content\"\n>\n <stream-modal\n class=\"stream-chat-angular__image-modal-host\"\n [isOpen]=\"isOpen\"\n [content]=\"content\"\n (isOpenChange)=\"isOpenChangeHandler($event)\"\n >\n </stream-modal>\n</ng-template>\n\n<ng-template #modalContent>\n <div class=\"stream-chat-angular__image-modal str-chat__image-carousel\">\n <img\n #imgElement\n class=\"\n stream-chat-angular__image-modal-image\n str-chat__image-carousel-image\n \"\n data-testid=\"modal-image\"\n [src]=\"\n getCarouselImageAttachmentConfiguration(\n imagesToView[imagesToViewCurrentIndex],\n imgElement\n ).url\n \"\n [style.--original-height]=\"\n getCarouselImageAttachmentConfiguration(\n imagesToView[imagesToViewCurrentIndex],\n imgElement\n ).originalHeight\n \"\n [style.--original-width]=\"\n getCarouselImageAttachmentConfiguration(\n imagesToView[imagesToViewCurrentIndex],\n imgElement\n ).originalWidth\n \"\n [alt]=\"imagesToView[imagesToViewCurrentIndex].fallback\"\n [ngStyle]=\"{\n width: getCarouselImageAttachmentConfiguration(\n imagesToView[imagesToViewCurrentIndex],\n imgElement\n ).width,\n height: getCarouselImageAttachmentConfiguration(\n imagesToView[imagesToViewCurrentIndex],\n imgElement\n ).height\n }\"\n />\n <div>\n <button\n class=\"\n stream-chat-angular__image-modal-stepper\n str-chat__image-carousel-stepper str-chat__image-carousel-stepper-prev\n \"\n data-testid=\"image-modal-prev\"\n type=\"button\"\n [ngStyle]=\"{\n visibility: isImageModalPrevButtonVisible ? 'visible' : 'hidden'\n }\"\n (click)=\"stepImages(-1)\"\n (keyup.enter)=\"stepImages(-1)\"\n >\n <stream-icon-placeholder icon=\"arrow-left\"></stream-icon-placeholder>\n </button>\n <button\n class=\"\n stream-chat-angular__image-modal-stepper\n str-chat__image-carousel-stepper str-chat__image-carousel-stepper-next\n \"\n type=\"button\"\n data-testid=\"image-modal-next\"\n [ngStyle]=\"{\n visibility: isImageModalNextButtonVisible ? 'visible' : 'hidden'\n }\"\n (click)=\"stepImages(1)\"\n (keyup.enter)=\"stepImages(1)\"\n >\n <stream-icon-placeholder icon=\"arrow-right\"></stream-icon-placeholder>\n </button>\n </div>\n </div>\n</ng-template>\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: i4.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i4.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "component", type: i5.ModalComponent, selector: "stream-modal", inputs: ["isOpen", "content"], outputs: ["isOpenChange"] }, { kind: "component", type: i6.IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: ["icon", "size"] }, { kind: "component", type: i7.VoiceRecordingComponent, selector: "stream-voice-recording", inputs: ["attachment"] }, { kind: "pipe", type: i4.AsyncPipe, name: "async" }, { kind: "pipe", type: i8.TranslatePipe, name: "translate" }] });
188
186
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: AttachmentListComponent, decorators: [{
189
187
  type: Component,
190
- args: [{ selector: 'stream-attachment-list', template: "<div *ngIf=\"orderedAttachments.length > 0\" class=\"str-chat__attachment-list\">\n <ng-container\n *ngFor=\"let attachment of orderedAttachments; trackBy: trackByUrl\"\n >\n <div\n data-testclass=\"attachment-container\"\n class=\"str-chat__message-attachment str-chat__message-attachment--{{\n attachment.type\n }} str-chat__message-attachment-dynamic-size\"\n [class.str-chat__message-attachment--card]=\"isCard(attachment)\"\n [class.str-chat-angular__message-attachment-file-single]=\"\n isFile(attachment)\n \"\n [class.str-chat__message-attachment--voice-recording]=\"\n isVoiceMessage(attachment)\n \"\n [class.str-chat__message-attachment-with-actions]=\"\n attachment.actions && attachment.actions.length > 0\n \"\n [class.str-chat__message-attachment--svg-image]=\"isSvg(attachment)\"\n >\n <ng-container *ngIf=\"isImage(attachment)\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.imageAttachmentTemplate$ | async) ||\n defaultImage;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultImage let-attachmentContext=\"attachment\">\n <img\n #imgElement\n class=\"str-chat__message-attachment--img\"\n data-testclass=\"image\"\n [src]=\"\n getImageAttachmentConfiguration(\n attachmentContext,\n 'single',\n imgElement\n ).url\n \"\n [alt]=\"attachmentContext?.fallback\"\n [ngStyle]=\"{\n height: getImageAttachmentConfiguration(\n attachmentContext,\n 'single',\n imgElement\n ).height,\n width: getImageAttachmentConfiguration(\n attachmentContext,\n 'single',\n imgElement\n ).width,\n '--original-height': getImageAttachmentConfiguration(\n attachmentContext,\n 'single',\n imgElement\n ).originalHeight,\n '--original-width': getImageAttachmentConfiguration(\n attachmentContext,\n 'single',\n imgElement\n ).originalWidth\n }\"\n (click)=\"openImageModal([attachmentContext])\"\n (keyup.enter)=\"openImageModal([attachmentContext])\"\n />\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"isGallery(attachment)\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.galleryAttachmentTemplate$ | async) ||\n defaultGallery;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultGallery let-attachmentContext=\"attachment\">\n <div\n class=\"str-chat__gallery\"\n data-testid=\"image-gallery\"\n [class.str-chat__gallery--square]=\"\n (attachmentContext?.images)!.length > 3\n \"\n [class.str-chat__gallery-two-rows]=\"\n (attachmentContext?.images)!.length > 2\n \"\n >\n <ng-container\n *ngFor=\"\n let galleryImage of attachmentContext.images;\n let index = index;\n let isLast = last;\n trackBy: trackByImageUrl\n \"\n >\n <button\n *ngIf=\"index < 3 || (index === 3 && isLast)\"\n class=\"str-chat__gallery-image\"\n data-testclass=\"gallery-image\"\n [class.str-chat__message-attachment--svg-image]=\"\n isSvg(galleryImage)\n \"\n (click)=\"openImageModal(attachmentContext.images!, index)\"\n (keyup.enter)=\"openImageModal(attachmentContext.images!, index)\"\n >\n <img\n #imgElement\n fetchpriority=\"low\"\n loading=\"lazy\"\n [src]=\"\n getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n imgElement\n ).url\n \"\n [alt]=\"galleryImage.fallback\"\n [style.--original-height]=\"\n getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n imgElement\n ).originalHeight\n \"\n [style.--original-width]=\"\n getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n imgElement\n ).originalWidth\n \"\n [ngStyle]=\"{\n height: getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n imgElement\n ).height,\n width: getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n imgElement\n ).width\n }\"\n />\n </button>\n <button\n *ngIf=\"index === 3 && !isLast\"\n #element\n class=\"str-chat__gallery-placeholder\"\n data-testclass=\"gallery-image\"\n data-testid=\"more-image-button\"\n [class.str-chat__message-attachment--svg-image]=\"\n isSvg(galleryImage)\n \"\n [ngStyle]=\"{\n 'background-image':\n 'url(' +\n getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n element\n ).url +\n ')',\n height: getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n element\n ).height,\n width: getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n element\n ).width,\n '--original-height': getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n element\n ).originalHeight,\n '--original-width': getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n element\n ).originalWidth\n }\"\n (click)=\"openImageModal(attachmentContext.images!, index)\"\n (keyup.enter)=\"openImageModal(attachmentContext.images!, index)\"\n >\n <p\n [innerHTML]=\"\n 'streamChat.{{ imageCount }} more'\n | translate\n : { imageCount: attachmentContext!.images!.length - 4 }\n \"\n ></p>\n </button>\n </ng-container>\n </div>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"isVideo(attachment)\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.videoAttachmentTemplate$ | async) ||\n defaultVideo;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultVideo let-attachmentContext=\"attachment\">\n <div\n class=\"str-chat__player-wrapper\"\n data-testclass=\"video-attachment-parent\"\n [style.--original-height]=\"\n getVideoAttachmentConfiguration(attachmentContext, videoElement)\n .originalHeight\n \"\n [style.--original-width]=\"\n getVideoAttachmentConfiguration(attachmentContext, videoElement)\n .originalWidth\n \"\n [ngStyle]=\"{\n height: getVideoAttachmentConfiguration(\n attachmentContext,\n videoElement\n ).height,\n width: getVideoAttachmentConfiguration(\n attachmentContext,\n videoElement\n ).width\n }\"\n >\n <video\n #videoElement\n class=\"str-chat__video-angular\"\n controls\n data-testclass=\"video-attachment\"\n [src]=\"\n getVideoAttachmentConfiguration(attachmentContext, videoElement)\n .url\n \"\n [poster]=\"\n getVideoAttachmentConfiguration(attachmentContext, videoElement)\n .thumbUrl\n \"\n ></video>\n </div>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"isFile(attachment)\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.fileAttachmentTemplate$ | async) ||\n defaultFile;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultFile let-attachmentContext=\"attachment\">\n <div\n class=\"\n str-chat__message-attachment-file--item\n str-chat-angular__message-attachment-file-single\n \"\n >\n <stream-icon-placeholder\n *ngIf=\"themeVersion === '1'\"\n icon=\"file\"\n [size]=\"30\"\n ></stream-icon-placeholder>\n <stream-icon-placeholder\n *ngIf=\"themeVersion === '2'\"\n icon=\"unspecified-filetype\"\n [size]=\"30\"\n ></stream-icon-placeholder>\n <div class=\"str-chat__message-attachment-file--item-text\">\n <a\n class=\"str-chat__message-attachment-file--item-first-row\"\n data-testclass=\"file-link\"\n target=\"_blank\"\n href=\"{{ attachmentContext.asset_url }}\"\n >\n <div\n data-testclass=\"file-title\"\n class=\"str-chat__message-attachment-file--item-name\"\n >\n {{ attachmentContext.title }}\n </div>\n <stream-icon-placeholder\n class=\"str-chat__message-attachment-download-icon\"\n icon=\"download\"\n ></stream-icon-placeholder>\n </a>\n <span\n *ngIf=\"hasFileSize(attachmentContext)\"\n class=\"str-chat__message-attachment-file--item-size\"\n data-testclass=\"size\"\n >{{ getFileSize(attachmentContext) }}</span\n >\n </div>\n </div>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"isVoiceMessage(attachment)\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.voiceRecordingAttachmentTemplate$\n | async) || defaultRecording;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultRecording>\n <stream-voice-recording\n data-testclass=\"voice-recording\"\n [attachment]=\"attachment\"\n ></stream-voice-recording>\n </ng-template>\n </ng-container>\n <ng-container\n *ngIf=\"\n isCard(attachment) &&\n getCardAttachmentConfiguration(attachment) as attachmentConfiguration\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.cardAttachmentTemplate$ | async) ||\n defaultCard;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultCard let-attachmentContext=\"attachment\">\n <div\n class=\"str-chat__message-attachment-card str-chat__message-attachment-card--{{\n attachmentContext.type\n }}\"\n >\n <div\n *ngIf=\"attachmentConfiguration.url\"\n class=\"str-chat__message-attachment-card--header\"\n >\n <img\n fetchpriority=\"low\"\n loading=\"lazy\"\n data-testclass=\"card-img\"\n alt=\"{{ attachmentConfiguration.url }}\"\n src=\"{{ attachmentConfiguration.url }}\"\n [ngStyle]=\"{\n height: attachmentConfiguration.height,\n width: attachmentConfiguration.width\n }\"\n />\n </div>\n <div class=\"str-chat__message-attachment-card--content\">\n <div class=\"str-chat__message-attachment-card--flex\">\n <div\n *ngIf=\"attachmentContext.title\"\n data-testclass=\"card-title\"\n class=\"str-chat__message-attachment-card--title\"\n >\n {{ attachmentContext.title }}\n </div>\n <div\n *ngIf=\"attachmentContext.text\"\n class=\"str-chat__message-attachment-card--text\"\n data-testclass=\"card-text\"\n >\n {{ attachmentContext.text }}\n </div>\n <a\n *ngIf=\"\n attachmentContext.title_link ||\n attachmentContext.og_scrape_url\n \"\n class=\"str-chat__message-attachment-card--url\"\n data-testclass=\"url-link\"\n noopener\n noreferrer\n target=\"_blank\"\n href=\"{{\n attachmentContext.title_link ||\n attachmentContext.og_scrape_url\n }}\"\n >\n {{\n trimUrl(\n attachmentContext.title_link ||\n attachmentContext.og_scrape_url\n )\n }}\n </a>\n </div>\n </div>\n </div>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"attachment.actions && attachment.actions.length > 0\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.attachmentActionsTemplate$ | async) ||\n defaultActions;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultActions let-attachmentContext=\"attachment\">\n <div class=\"str-chat__message-attachment-actions\">\n <div class=\"str-chat__message-attachment-actions-form\">\n <button\n *ngFor=\"\n let action of attachmentContext.actions;\n trackBy: trackByActionValue\n \"\n data-testclass=\"attachment-action\"\n class=\"str-chat__message-attachment-actions-button str-chat__message-attachment-actions-button--{{\n action.style\n }}\"\n (click)=\"sendAction(action)\"\n (keyup.enter)=\"sendAction(action)\"\n >\n {{ action.text }}\n </button>\n </div>\n </div>\n </ng-template>\n </ng-container>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"imagesToView && imagesToView.length > 0\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.modalTemplate$ | async) || defaultModal;\n context: getModalContext()\n \"\n ></ng-container>\n </ng-container>\n</div>\n\n<ng-template\n #defaultModal\n let-isOpen=\"isOpen\"\n let-isOpenChangeHandler=\"isOpenChangeHandler\"\n let-content=\"content\"\n>\n <stream-modal\n class=\"stream-chat-angular__image-modal-host\"\n [isOpen]=\"isOpen\"\n [content]=\"content\"\n (isOpenChange)=\"isOpenChangeHandler($event)\"\n >\n </stream-modal>\n</ng-template>\n\n<ng-template #modalContent>\n <div class=\"stream-chat-angular__image-modal str-chat__image-carousel\">\n <img\n #imgElement\n class=\"\n stream-chat-angular__image-modal-image\n str-chat__image-carousel-image\n \"\n data-testid=\"modal-image\"\n [src]=\"\n getCarouselImageAttachmentConfiguration(\n imagesToView[imagesToViewCurrentIndex],\n imgElement\n ).url\n \"\n [style.--original-height]=\"\n getCarouselImageAttachmentConfiguration(\n imagesToView[imagesToViewCurrentIndex],\n imgElement\n ).originalHeight\n \"\n [style.--original-width]=\"\n getCarouselImageAttachmentConfiguration(\n imagesToView[imagesToViewCurrentIndex],\n imgElement\n ).originalWidth\n \"\n [alt]=\"imagesToView[imagesToViewCurrentIndex].fallback\"\n [ngStyle]=\"{\n width: getCarouselImageAttachmentConfiguration(\n imagesToView[imagesToViewCurrentIndex],\n imgElement\n ).width,\n height: getCarouselImageAttachmentConfiguration(\n imagesToView[imagesToViewCurrentIndex],\n imgElement\n ).height\n }\"\n />\n <div>\n <button\n class=\"\n stream-chat-angular__image-modal-stepper\n str-chat__image-carousel-stepper str-chat__image-carousel-stepper-prev\n \"\n data-testid=\"image-modal-prev\"\n type=\"button\"\n [ngStyle]=\"{\n visibility: isImageModalPrevButtonVisible ? 'visible' : 'hidden'\n }\"\n (click)=\"stepImages(-1)\"\n (keyup.enter)=\"stepImages(-1)\"\n >\n <stream-icon-placeholder icon=\"arrow-left\"></stream-icon-placeholder>\n </button>\n <button\n class=\"\n stream-chat-angular__image-modal-stepper\n str-chat__image-carousel-stepper str-chat__image-carousel-stepper-next\n \"\n type=\"button\"\n data-testid=\"image-modal-next\"\n [ngStyle]=\"{\n visibility: isImageModalNextButtonVisible ? 'visible' : 'hidden'\n }\"\n (click)=\"stepImages(1)\"\n (keyup.enter)=\"stepImages(1)\"\n >\n <stream-icon-placeholder icon=\"arrow-right\"></stream-icon-placeholder>\n </button>\n </div>\n </div>\n</ng-template>\n" }]
191
- }], ctorParameters: function () { return [{ type: i1.CustomTemplatesService }, { type: i2.ChannelService }, { type: i3.AttachmentConfigurationService }, { type: i4.ThemeService }]; }, propDecorators: { messageId: [{
188
+ args: [{ selector: 'stream-attachment-list', template: "<div *ngIf=\"orderedAttachments.length > 0\" class=\"str-chat__attachment-list\">\n <ng-container\n *ngFor=\"let attachment of orderedAttachments; trackBy: trackByUrl\"\n >\n <div\n data-testclass=\"attachment-container\"\n class=\"str-chat__message-attachment str-chat__message-attachment--{{\n attachment.type\n }} str-chat__message-attachment-dynamic-size\"\n [class.str-chat__message-attachment--card]=\"isCard(attachment)\"\n [class.str-chat-angular__message-attachment-file-single]=\"\n isFile(attachment)\n \"\n [class.str-chat__message-attachment--voice-recording]=\"\n isVoiceMessage(attachment)\n \"\n [class.str-chat__message-attachment-with-actions]=\"\n attachment.actions && attachment.actions.length > 0\n \"\n [class.str-chat__message-attachment--svg-image]=\"isSvg(attachment)\"\n >\n <ng-container *ngIf=\"isImage(attachment)\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.imageAttachmentTemplate$ | async) ||\n defaultImage;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultImage let-attachmentContext=\"attachment\">\n <img\n #imgElement\n class=\"str-chat__message-attachment--img\"\n data-testclass=\"image\"\n [src]=\"\n getImageAttachmentConfiguration(\n attachmentContext,\n 'single',\n imgElement\n ).url\n \"\n [alt]=\"attachmentContext?.fallback\"\n [ngStyle]=\"{\n height: getImageAttachmentConfiguration(\n attachmentContext,\n 'single',\n imgElement\n ).height,\n width: getImageAttachmentConfiguration(\n attachmentContext,\n 'single',\n imgElement\n ).width,\n '--original-height': getImageAttachmentConfiguration(\n attachmentContext,\n 'single',\n imgElement\n ).originalHeight,\n '--original-width': getImageAttachmentConfiguration(\n attachmentContext,\n 'single',\n imgElement\n ).originalWidth\n }\"\n (click)=\"openImageModal([attachmentContext])\"\n (keyup.enter)=\"openImageModal([attachmentContext])\"\n />\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"isGallery(attachment)\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.galleryAttachmentTemplate$ | async) ||\n defaultGallery;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultGallery let-attachmentContext=\"attachment\">\n <div\n class=\"str-chat__gallery\"\n data-testid=\"image-gallery\"\n [class.str-chat__gallery--square]=\"\n (attachmentContext?.images)!.length > 3\n \"\n [class.str-chat__gallery-two-rows]=\"\n (attachmentContext?.images)!.length > 2\n \"\n >\n <ng-container\n *ngFor=\"\n let galleryImage of attachmentContext.images;\n let index = index;\n let isLast = last;\n trackBy: trackByImageUrl\n \"\n >\n <button\n *ngIf=\"index < 3 || (index === 3 && isLast)\"\n class=\"str-chat__gallery-image\"\n data-testclass=\"gallery-image\"\n [class.str-chat__message-attachment--svg-image]=\"\n isSvg(galleryImage)\n \"\n (click)=\"openImageModal(attachmentContext.images!, index)\"\n (keyup.enter)=\"openImageModal(attachmentContext.images!, index)\"\n >\n <img\n #imgElement\n fetchpriority=\"low\"\n loading=\"lazy\"\n [src]=\"\n getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n imgElement\n ).url\n \"\n [alt]=\"galleryImage.fallback\"\n [style.--original-height]=\"\n getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n imgElement\n ).originalHeight\n \"\n [style.--original-width]=\"\n getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n imgElement\n ).originalWidth\n \"\n [ngStyle]=\"{\n height: getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n imgElement\n ).height,\n width: getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n imgElement\n ).width\n }\"\n />\n </button>\n <button\n *ngIf=\"index === 3 && !isLast\"\n #element\n class=\"str-chat__gallery-placeholder\"\n data-testclass=\"gallery-image\"\n data-testid=\"more-image-button\"\n [class.str-chat__message-attachment--svg-image]=\"\n isSvg(galleryImage)\n \"\n [ngStyle]=\"{\n 'background-image':\n 'url(' +\n getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n element\n ).url +\n ')',\n height: getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n element\n ).height,\n width: getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n element\n ).width,\n '--original-height': getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n element\n ).originalHeight,\n '--original-width': getImageAttachmentConfiguration(\n galleryImage,\n 'gallery',\n element\n ).originalWidth\n }\"\n (click)=\"openImageModal(attachmentContext.images!, index)\"\n (keyup.enter)=\"openImageModal(attachmentContext.images!, index)\"\n >\n <p\n [innerHTML]=\"\n 'streamChat.{{ imageCount }} more'\n | translate\n : { imageCount: attachmentContext!.images!.length - 4 }\n \"\n ></p>\n </button>\n </ng-container>\n </div>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"isVideo(attachment)\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.videoAttachmentTemplate$ | async) ||\n defaultVideo;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultVideo let-attachmentContext=\"attachment\">\n <div\n class=\"str-chat__player-wrapper\"\n data-testclass=\"video-attachment-parent\"\n [style.--original-height]=\"\n getVideoAttachmentConfiguration(attachmentContext, videoElement)\n .originalHeight\n \"\n [style.--original-width]=\"\n getVideoAttachmentConfiguration(attachmentContext, videoElement)\n .originalWidth\n \"\n [ngStyle]=\"{\n height: getVideoAttachmentConfiguration(\n attachmentContext,\n videoElement\n ).height,\n width: getVideoAttachmentConfiguration(\n attachmentContext,\n videoElement\n ).width\n }\"\n >\n <video\n #videoElement\n class=\"str-chat__video-angular\"\n controls\n data-testclass=\"video-attachment\"\n [src]=\"\n getVideoAttachmentConfiguration(attachmentContext, videoElement)\n .url\n \"\n [poster]=\"\n getVideoAttachmentConfiguration(attachmentContext, videoElement)\n .thumbUrl\n \"\n ></video>\n </div>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"isFile(attachment)\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.fileAttachmentTemplate$ | async) ||\n defaultFile;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultFile let-attachmentContext=\"attachment\">\n <div\n class=\"\n str-chat__message-attachment-file--item\n str-chat-angular__message-attachment-file-single\n \"\n >\n <stream-icon-placeholder\n icon=\"unspecified-filetype\"\n [size]=\"30\"\n ></stream-icon-placeholder>\n <div class=\"str-chat__message-attachment-file--item-text\">\n <a\n class=\"str-chat__message-attachment-file--item-first-row\"\n data-testclass=\"file-link\"\n target=\"_blank\"\n href=\"{{ attachmentContext.asset_url }}\"\n >\n <div\n data-testclass=\"file-title\"\n class=\"str-chat__message-attachment-file--item-name\"\n >\n {{ attachmentContext.title }}\n </div>\n <stream-icon-placeholder\n class=\"str-chat__message-attachment-download-icon\"\n icon=\"download\"\n ></stream-icon-placeholder>\n </a>\n <span\n *ngIf=\"hasFileSize(attachmentContext)\"\n class=\"str-chat__message-attachment-file--item-size\"\n data-testclass=\"size\"\n >{{ getFileSize(attachmentContext) }}</span\n >\n </div>\n </div>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"isVoiceMessage(attachment)\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.voiceRecordingAttachmentTemplate$\n | async) || defaultRecording;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultRecording>\n <stream-voice-recording\n data-testclass=\"voice-recording\"\n [attachment]=\"attachment\"\n ></stream-voice-recording>\n </ng-template>\n </ng-container>\n <ng-container\n *ngIf=\"\n isCard(attachment) &&\n getCardAttachmentConfiguration(attachment) as attachmentConfiguration\n \"\n >\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.cardAttachmentTemplate$ | async) ||\n defaultCard;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultCard let-attachmentContext=\"attachment\">\n <div\n class=\"str-chat__message-attachment-card str-chat__message-attachment-card--{{\n attachmentContext.type\n }}\"\n >\n <div\n *ngIf=\"attachmentConfiguration.url\"\n class=\"str-chat__message-attachment-card--header\"\n >\n <img\n fetchpriority=\"low\"\n loading=\"lazy\"\n data-testclass=\"card-img\"\n alt=\"{{ attachmentConfiguration.url }}\"\n src=\"{{ attachmentConfiguration.url }}\"\n [ngStyle]=\"{\n height: attachmentConfiguration.height,\n width: attachmentConfiguration.width\n }\"\n />\n </div>\n <div class=\"str-chat__message-attachment-card--content\">\n <div class=\"str-chat__message-attachment-card--flex\">\n <div\n *ngIf=\"attachmentContext.title\"\n data-testclass=\"card-title\"\n class=\"str-chat__message-attachment-card--title\"\n >\n {{ attachmentContext.title }}\n </div>\n <div\n *ngIf=\"attachmentContext.text\"\n class=\"str-chat__message-attachment-card--text\"\n data-testclass=\"card-text\"\n >\n {{ attachmentContext.text }}\n </div>\n <a\n *ngIf=\"\n attachmentContext.title_link ||\n attachmentContext.og_scrape_url\n \"\n class=\"str-chat__message-attachment-card--url\"\n data-testclass=\"url-link\"\n noopener\n noreferrer\n target=\"_blank\"\n href=\"{{\n attachmentContext.title_link ||\n attachmentContext.og_scrape_url\n }}\"\n >\n {{\n trimUrl(\n attachmentContext.title_link ||\n attachmentContext.og_scrape_url\n )\n }}\n </a>\n </div>\n </div>\n </div>\n </ng-template>\n </ng-container>\n <ng-container *ngIf=\"attachment.actions && attachment.actions.length > 0\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.attachmentActionsTemplate$ | async) ||\n defaultActions;\n context: getAttachmentContext(attachment)\n \"\n ></ng-container>\n <ng-template #defaultActions let-attachmentContext=\"attachment\">\n <div class=\"str-chat__message-attachment-actions\">\n <div class=\"str-chat__message-attachment-actions-form\">\n <button\n *ngFor=\"\n let action of attachmentContext.actions;\n trackBy: trackByActionValue\n \"\n data-testclass=\"attachment-action\"\n class=\"str-chat__message-attachment-actions-button str-chat__message-attachment-actions-button--{{\n action.style\n }}\"\n (click)=\"sendAction(action)\"\n (keyup.enter)=\"sendAction(action)\"\n >\n {{ action.text }}\n </button>\n </div>\n </div>\n </ng-template>\n </ng-container>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"imagesToView && imagesToView.length > 0\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.modalTemplate$ | async) || defaultModal;\n context: getModalContext()\n \"\n ></ng-container>\n </ng-container>\n</div>\n\n<ng-template\n #defaultModal\n let-isOpen=\"isOpen\"\n let-isOpenChangeHandler=\"isOpenChangeHandler\"\n let-content=\"content\"\n>\n <stream-modal\n class=\"stream-chat-angular__image-modal-host\"\n [isOpen]=\"isOpen\"\n [content]=\"content\"\n (isOpenChange)=\"isOpenChangeHandler($event)\"\n >\n </stream-modal>\n</ng-template>\n\n<ng-template #modalContent>\n <div class=\"stream-chat-angular__image-modal str-chat__image-carousel\">\n <img\n #imgElement\n class=\"\n stream-chat-angular__image-modal-image\n str-chat__image-carousel-image\n \"\n data-testid=\"modal-image\"\n [src]=\"\n getCarouselImageAttachmentConfiguration(\n imagesToView[imagesToViewCurrentIndex],\n imgElement\n ).url\n \"\n [style.--original-height]=\"\n getCarouselImageAttachmentConfiguration(\n imagesToView[imagesToViewCurrentIndex],\n imgElement\n ).originalHeight\n \"\n [style.--original-width]=\"\n getCarouselImageAttachmentConfiguration(\n imagesToView[imagesToViewCurrentIndex],\n imgElement\n ).originalWidth\n \"\n [alt]=\"imagesToView[imagesToViewCurrentIndex].fallback\"\n [ngStyle]=\"{\n width: getCarouselImageAttachmentConfiguration(\n imagesToView[imagesToViewCurrentIndex],\n imgElement\n ).width,\n height: getCarouselImageAttachmentConfiguration(\n imagesToView[imagesToViewCurrentIndex],\n imgElement\n ).height\n }\"\n />\n <div>\n <button\n class=\"\n stream-chat-angular__image-modal-stepper\n str-chat__image-carousel-stepper str-chat__image-carousel-stepper-prev\n \"\n data-testid=\"image-modal-prev\"\n type=\"button\"\n [ngStyle]=\"{\n visibility: isImageModalPrevButtonVisible ? 'visible' : 'hidden'\n }\"\n (click)=\"stepImages(-1)\"\n (keyup.enter)=\"stepImages(-1)\"\n >\n <stream-icon-placeholder icon=\"arrow-left\"></stream-icon-placeholder>\n </button>\n <button\n class=\"\n stream-chat-angular__image-modal-stepper\n str-chat__image-carousel-stepper str-chat__image-carousel-stepper-next\n \"\n type=\"button\"\n data-testid=\"image-modal-next\"\n [ngStyle]=\"{\n visibility: isImageModalNextButtonVisible ? 'visible' : 'hidden'\n }\"\n (click)=\"stepImages(1)\"\n (keyup.enter)=\"stepImages(1)\"\n >\n <stream-icon-placeholder icon=\"arrow-right\"></stream-icon-placeholder>\n </button>\n </div>\n </div>\n</ng-template>\n" }]
189
+ }], ctorParameters: function () { return [{ type: i1.CustomTemplatesService }, { type: i2.ChannelService }, { type: i3.AttachmentConfigurationService }]; }, propDecorators: { messageId: [{
192
190
  type: Input
193
191
  }], parentMessageId: [{
194
192
  type: Input
@@ -202,4 +200,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImpor
202
200
  type: ViewChild,
203
201
  args: ['modalContent', { static: true }]
204
202
  }] } });
205
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXR0YWNobWVudC1saXN0LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3N0cmVhbS1jaGF0LWFuZ3VsYXIvc3JjL2xpYi9hdHRhY2htZW50LWxpc3QvYXR0YWNobWVudC1saXN0LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3N0cmVhbS1jaGF0LWFuZ3VsYXIvc3JjL2xpYi9hdHRhY2htZW50LWxpc3QvYXR0YWNobWVudC1saXN0LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxTQUFTLEVBQ1QsWUFBWSxFQUNaLFdBQVcsRUFDWCxLQUFLLEVBRUwsTUFBTSxFQUdOLFNBQVMsR0FDVixNQUFNLGVBQWUsQ0FBQztBQVV2QixPQUFPLFdBQVcsTUFBTSxjQUFjLENBQUM7QUFDdkMsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7Ozs7Ozs7Ozs7O0FBTTNEOztHQUVHO0FBTUgsTUFBTSxPQUFPLHVCQUF1QjtJQWlDbEMsWUFDa0Isc0JBQThDLEVBQ3RELGNBQThCLEVBQzlCLDhCQUE4RCxFQUN0RSxZQUEwQjtRQUhWLDJCQUFzQixHQUF0QixzQkFBc0IsQ0FBd0I7UUFDdEQsbUJBQWMsR0FBZCxjQUFjLENBQWdCO1FBQzlCLG1DQUE4QixHQUE5Qiw4QkFBOEIsQ0FBZ0M7UUEzQnhFOztXQUVHO1FBQ00sZ0JBQVcsR0FBNEMsRUFBRSxDQUFDO1FBQ25FOztXQUVHO1FBQ2dCLDBCQUFxQixHQUFHLElBQUksWUFBWSxFQUV4RCxDQUFDO1FBQ1csVUFBSyxHQUFHLHdDQUF3QyxDQUFDO1FBQ2hFLHVCQUFrQixHQUE0QyxFQUFFLENBQUM7UUFDakUsaUJBQVksR0FBNEMsRUFBRSxDQUFDO1FBQzNELDZCQUF3QixHQUFHLENBQUMsQ0FBQztRQUlyQiw2QkFBd0IsR0FLNUIsSUFBSSxHQUFHLEVBQUUsQ0FBQztRQVFaLElBQUksQ0FBQyxZQUFZLEdBQUcsWUFBWSxDQUFDLFlBQVksQ0FBQztJQUNoRCxDQUFDO0lBQ0QsV0FBVyxDQUFDLE9BQXNCO1FBQ2hDLElBQUksT0FBTyxDQUFDLFdBQVcsRUFBRTtZQUN2QixNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDckQsTUFBTSxlQUFlLEdBQUcsTUFBTSxDQUFDLE1BQU0sSUFBSSxDQUFDLENBQUM7WUFDM0MsSUFBSSxDQUFDLGtCQUFrQixHQUFHO2dCQUN4QixHQUFHLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUM7Z0JBQzFELEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ2xELEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ3pELEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7YUFDbEQsQ0FBQztZQUNGLElBQUksQ0FBQyx3QkFBd0IsR0FBRyxJQUFJLEdBQUcsRUFBRSxDQUFDO1lBQzFDLGtFQUFrRTtZQUNsRSxnREFBZ0Q7WUFDaEQsSUFBSSxJQUFJLENBQUMsa0JBQWtCLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtnQkFDeEMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FDMUIsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUNsRCxDQUFDO2FBQ0g7U0FDRjtJQUNILENBQUM7SUFFRCxVQUFVLENBQUMsQ0FBUyxFQUFFLFVBQXNCO1FBQzFDLE9BQU8sQ0FDTCxVQUFVLENBQUMsU0FBUztZQUNwQixVQUFVLENBQUMsT0FBTztZQUNsQixVQUFVLENBQUMsU0FBUztZQUNwQixVQUFVLENBQUMsU0FBUyxDQUNyQixDQUFDO0lBQ0osQ0FBQztJQUVELE9BQU8sQ0FBQyxVQUFzQjtRQUM1QixPQUFPLGlCQUFpQixDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ3ZDLENBQUM7SUFFRCxLQUFLLENBQUMsVUFBc0I7UUFDMUIsTUFBTSxRQUFRLEdBQUcsVUFBVSxDQUFDLFFBQVEsSUFBSSxFQUFFLENBQUM7UUFDM0MsT0FBTyxDQUFDLENBQUMsUUFBUSxDQUFDLFdBQVcsRUFBRSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUNuRCxDQUFDO0lBRUQsTUFBTSxDQUFDLFVBQXNCO1FBQzNCLE9BQU8sVUFBVSxDQUFDLElBQUksS0FBSyxNQUFNLENBQUM7SUFDcEMsQ0FBQztJQUVELFNBQVMsQ0FBQyxVQUFzQjtRQUM5QixPQUFPLFVBQVUsQ0FBQyxJQUFJLEtBQUssU0FBUyxDQUFDO0lBQ3ZDLENBQUM7SUFFRCxPQUFPLENBQUMsVUFBc0I7UUFDNUIsT0FBTyxDQUNMLFVBQVUsQ0FBQyxJQUFJLEtBQUssT0FBTztZQUMzQixVQUFVLENBQUMsU0FBUztZQUNwQixDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMsb0ZBQW9GO1NBQy9HLENBQUM7SUFDSixDQUFDO0lBRUQsTUFBTSxDQUFDLFVBQXNCO1FBQzNCLE9BQU8sQ0FDTCxDQUFDLFVBQVUsQ0FBQyxJQUFJO1lBQ2hCLENBQUMsVUFBVSxDQUFDLElBQUksS0FBSyxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQzFELFVBQVUsQ0FBQyxJQUFJLEtBQUssT0FBTyxDQUM1QixDQUFDO0lBQ0osQ0FBQztJQUVELGNBQWMsQ0FBQyxVQUFzQjtRQUNuQyxPQUFPLFVBQVUsQ0FBQyxJQUFJLEtBQUssZ0JBQWdCLENBQUM7SUFDOUMsQ0FBQztJQUVELFdBQVcsQ0FBQyxVQUFpRDtRQUMzRCxPQUFPLENBQ0wsVUFBVSxDQUFDLFNBQVMsSUFBSSxNQUFNLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FDdEUsQ0FBQztJQUNKLENBQUM7SUFFRCxXQUFXLENBQUMsVUFBaUQ7UUFDM0QsT0FBTyxXQUFXLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxTQUFVLENBQUMsQ0FBQyxDQUFDO0lBQ3BELENBQUM7SUFFRCxlQUFlO1FBQ2IsT0FBTztZQUNMLE1BQU0sRUFBRSxJQUFJLENBQUMsWUFBWSxJQUFJLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxHQUFHLENBQUM7WUFDekQsbUJBQW1CLEVBQUUsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztZQUN6RSxPQUFPLEVBQUUsSUFBSSxDQUFDLFlBQVk7U0FDM0IsQ0FBQztJQUNKLENBQUM7SUFFRCxPQUFPLENBQUMsR0FBbUI7UUFDekIsSUFBSSxHQUFHLEtBQUssU0FBUyxJQUFJLEdBQUcsS0FBSyxJQUFJLEVBQUU7WUFDckMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxHQUFHLEdBQUc7aUJBQ3JCLE9BQU8sQ0FBQyw4QkFBOEIsRUFBRSxFQUFFLENBQUM7aUJBQzNDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUVkLE9BQU8sVUFBVSxDQUFDO1NBQ25CO1FBQ0QsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsVUFBVSxDQUFDLE1BQWM7UUFDdkIsS0FBSyxJQUFJLENBQUMsY0FBYyxDQUFDLFVBQVUsQ0FDakMsSUFBSSxDQUFDLFNBQVUsRUFDZjtZQUNFLENBQUMsTUFBTSxDQUFDLElBQUssQ0FBQyxFQUFFLE1BQU0sQ0FBQyxLQUFNO1NBQzlCLEVBQ0QsSUFBSSxDQUFDLGVBQWUsQ0FDckIsQ0FBQztJQUNKLENBQUM7SUFFRCxrQkFBa0IsQ0FBQyxDQUFTLEVBQUUsSUFBWTtRQUN4QyxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUM7SUFDcEIsQ0FBQztJQUVELGNBQWMsQ0FBQyxXQUF5QixFQUFFLGFBQWEsR0FBRyxDQUFDO1FBQ3pELElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDMUMsSUFBSSxDQUFDLFlBQVksR0FBRyxXQUFXLENBQUM7UUFDaEMsSUFBSSxDQUFDLHdCQUF3QixHQUFHLGFBQWEsQ0FBQztJQUNoRCxDQUFDO0lBRUQsVUFBVSxDQUFDLEdBQVc7UUFDcEIsSUFBSSxDQUFDLHdCQUF3QixJQUFJLEdBQUcsR0FBRyxDQUFDLENBQUM7SUFDM0MsQ0FBQztJQUVELGVBQWUsQ0FBQyxDQUFTLEVBQUUsSUFBZ0I7UUFDekMsT0FBTyxJQUFJLENBQUMsU0FBUyxJQUFJLElBQUksQ0FBQyxPQUFPLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQztJQUMxRCxDQUFDO0lBRUQsb0JBQW9CLENBQ2xCLFVBQWlEO1FBRWpELE9BQU8sRUFBRSxVQUFVLEVBQUUsQ0FBQztJQUN4QixDQUFDO0lBRUQsK0JBQStCLENBQzdCLFVBQXNCLEVBQ3RCLElBQTBCLEVBQzFCLE9BQW9CO1FBRXBCLE1BQU0scUJBQXFCLEdBQUcsSUFBSSxDQUFDLHdCQUF3QixDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUM1RSxJQUFJLHFCQUFxQixFQUFFO1lBQ3pCLE9BQU8scUJBQXFELENBQUM7U0FDOUQ7UUFDRCxNQUFNLGFBQWEsR0FDakIsSUFBSSxDQUFDLDhCQUE4QixDQUFDLCtCQUErQixDQUNqRSxVQUFVLEVBQ1YsSUFBSSxFQUNKLE9BQU8sQ0FDUixDQUFDO1FBQ0osSUFBSSxDQUFDLHdCQUF3QixDQUFDLEdBQUcsQ0FBQyxVQUFVLEVBQUUsYUFBYSxDQUFDLENBQUM7UUFDN0QsT0FBTyxhQUFhLENBQUM7SUFDdkIsQ0FBQztJQUVELHVDQUF1QyxDQUNyQyxVQUFzQixFQUN0QixPQUFvQjtRQUVwQixPQUFPLElBQUksQ0FBQyw4QkFBOEIsQ0FBQywrQkFBK0IsQ0FDeEUsVUFBVSxFQUNWLFVBQVUsRUFDVixPQUFPLENBQ1IsQ0FBQztJQUNKLENBQUM7SUFFRCwrQkFBK0IsQ0FDN0IsVUFBc0IsRUFDdEIsT0FBb0I7UUFFcEIsTUFBTSxxQkFBcUIsR0FBRyxJQUFJLENBQUMsd0JBQXdCLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQzVFLElBQUkscUJBQXFCLEVBQUU7WUFDekIsT0FBTyxxQkFBcUQsQ0FBQztTQUM5RDtRQUNELE1BQU0sYUFBYSxHQUNqQixJQUFJLENBQUMsOEJBQThCLENBQUMsK0JBQStCLENBQ2pFLFVBQVUsRUFDVixPQUFPLENBQ1IsQ0FBQztRQUNKLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxHQUFHLENBQUMsVUFBVSxFQUFFLGFBQWEsQ0FBQyxDQUFDO1FBQzdELE9BQU8sYUFBYSxDQUFDO0lBQ3ZCLENBQUM7SUFFRCw4QkFBOEIsQ0FBQyxVQUFzQjtRQUNuRCxNQUFNLHFCQUFxQixHQUFHLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDNUUsSUFBSSxxQkFBcUIsRUFBRTtZQUN6QixPQUFPLHFCQUFxQixDQUFDO1NBQzlCO1FBQ0QsSUFBSSxVQUFVLENBQUMsSUFBSSxLQUFLLE9BQU8sRUFBRTtZQUMvQixPQUFPLElBQUksQ0FBQyw4QkFBOEIsQ0FBQywrQkFBK0IsQ0FDeEUsVUFBVSxDQUNYLENBQUM7U0FDSDthQUFNO1lBQ0wsTUFBTSxhQUFhLEdBQ2pCLElBQUksQ0FBQyw4QkFBOEIsQ0FBQyxzQ0FBc0MsQ0FDeEUsVUFBVSxDQUNYLENBQUM7WUFDSixJQUFJLENBQUMsd0JBQXdCLENBQUMsR0FBRyxDQUFDLFVBQVUsRUFBRSxhQUFhLENBQUMsQ0FBQztZQUM3RCxPQUFPLGFBQWEsQ0FBQztTQUN0QjtJQUNILENBQUM7SUFFRCxJQUFJLDZCQUE2QjtRQUMvQixPQUFPLElBQUksQ0FBQyx3QkFBd0IsS0FBSyxDQUFDLENBQUM7SUFDN0MsQ0FBQztJQUVELElBQUksNkJBQTZCO1FBQy9CLE9BQU8sSUFBSSxDQUFDLHdCQUF3QixLQUFLLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztJQUN4RSxDQUFDO0lBRU8sYUFBYSxDQUFDLE1BQW9CO1FBQ3hDLE9BQU87WUFDTDtnQkFDRSxJQUFJLEVBQUUsU0FBUztnQkFDZixNQUFNO2FBQ1A7U0FDRixDQUFDO0lBQ0osQ0FBQztJQUVPLGVBQWU7UUFDckIsSUFBSSxDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUMxQyxJQUFJLENBQUMsWUFBWSxHQUFHLEVBQUUsQ0FBQztJQUN6QixDQUFDOztvSEFqUVUsdUJBQXVCO3dHQUF2Qix1QkFBdUIsaWFDbkNwQywydmxCQTRnQkE7MkZEemVhLHVCQUF1QjtrQkFMbkMsU0FBUzsrQkFDRSx3QkFBd0I7a05BUXpCLFNBQVM7c0JBQWpCLEtBQUs7Z0JBSUcsZUFBZTtzQkFBdkIsS0FBSztnQkFJRyxXQUFXO3NCQUFuQixLQUFLO2dCQUlhLHFCQUFxQjtzQkFBdkMsTUFBTTtnQkFHUSxLQUFLO3NCQUFuQixXQUFXO2dCQU1KLFlBQVk7c0JBRG5CLFNBQVM7dUJBQUMsY0FBYyxFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENvbXBvbmVudCxcbiAgRXZlbnRFbWl0dGVyLFxuICBIb3N0QmluZGluZyxcbiAgSW5wdXQsXG4gIE9uQ2hhbmdlcyxcbiAgT3V0cHV0LFxuICBTaW1wbGVDaGFuZ2VzLFxuICBUZW1wbGF0ZVJlZixcbiAgVmlld0NoaWxkLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEFjdGlvbiwgQXR0YWNobWVudCB9IGZyb20gJ3N0cmVhbS1jaGF0JztcbmltcG9ydCB7XG4gIE1vZGFsQ29udGV4dCxcbiAgRGVmYXVsdFN0cmVhbUNoYXRHZW5lcmljcyxcbiAgQXR0YWNobWVudENvbmZpZ3JhdGlvbixcbiAgVmlkZW9BdHRhY2htZW50Q29uZmlndXJhdGlvbixcbiAgSW1hZ2VBdHRhY2htZW50Q29uZmlndXJhdGlvbixcbiAgQXR0YWNobWVudENvbnRleHQsXG59IGZyb20gJy4uL3R5cGVzJztcbmltcG9ydCBwcmV0dHlieXRlcyBmcm9tICdwcmV0dHktYnl0ZXMnO1xuaW1wb3J0IHsgaXNJbWFnZUF0dGFjaG1lbnQgfSBmcm9tICcuLi9pcy1pbWFnZS1hdHRhY2htZW50JztcbmltcG9ydCB7IENoYW5uZWxTZXJ2aWNlIH0gZnJvbSAnLi4vY2hhbm5lbC5zZXJ2aWNlJztcbmltcG9ydCB7IEN1c3RvbVRlbXBsYXRlc1NlcnZpY2UgfSBmcm9tICcuLi9jdXN0b20tdGVtcGxhdGVzLnNlcnZpY2UnO1xuaW1wb3J0IHsgQXR0YWNobWVudENvbmZpZ3VyYXRpb25TZXJ2aWNlIH0gZnJvbSAnLi4vYXR0YWNobWVudC1jb25maWd1cmF0aW9uLnNlcnZpY2UnO1xuaW1wb3J0IHsgVGhlbWVTZXJ2aWNlIH0gZnJvbSAnLi4vdGhlbWUuc2VydmljZSc7XG5cbi8qKlxuICogVGhlIGBBdHRhY2htZW50TGlzdGAgY29tcG9uZW50IGRpc3BsYXlzIHRoZSBhdHRhY2htZW50cyBvZiBhIG1lc3NhZ2VcbiAqL1xuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnc3RyZWFtLWF0dGFjaG1lbnQtbGlzdCcsXG4gIHRlbXBsYXRlVXJsOiAnLi9hdHRhY2htZW50LWxpc3QuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZXM6IFtdLFxufSlcbmV4cG9ydCBjbGFzcyBBdHRhY2htZW50TGlzdENvbXBvbmVudCBpbXBsZW1lbnRzIE9uQ2hhbmdlcyB7XG4gIC8qKlxuICAgKiBUaGUgaWQgb2YgdGhlIG1lc3NhZ2UgdGhlIGF0dGFjaG1lbnRzIGJlbG9uZyB0b1xuICAgKi9cbiAgQElucHV0KCkgbWVzc2FnZUlkOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gIC8qKlxuICAgKiBUaGUgcGFyZW50IGlkIG9mIHRoZSBtZXNzYWdlIHRoZSBhdHRhY2htZW50cyBiZWxvbmcgdG9cbiAgICovXG4gIEBJbnB1dCgpIHBhcmVudE1lc3NhZ2VJZDogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAvKipcbiAgICogVGhlIGF0dGFjaG1lbnRzIHRvIGRpc3BsYXlcbiAgICovXG4gIEBJbnB1dCgpIGF0dGFjaG1lbnRzOiBBdHRhY2htZW50PERlZmF1bHRTdHJlYW1DaGF0R2VuZXJpY3M+W10gPSBbXTtcbiAgLyoqXG4gICAqIEVtaXRzIHRoZSBzdGF0ZSBvZiB0aGUgaW1hZ2UgY2Fyb3VzZWwgd2luZG93XG4gICAqL1xuICBAT3V0cHV0KCkgcmVhZG9ubHkgaW1hZ2VNb2RhbFN0YXRlQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxcbiAgICAnb3BlbmVkJyB8ICdjbG9zZWQnXG4gID4oKTtcbiAgQEhvc3RCaW5kaW5nKCkgY2xhc3MgPSAnc3RyLWNoYXRfX2F0dGFjaG1lbnQtbGlzdC1hbmd1bGFyLWhvc3QnO1xuICBvcmRlcmVkQXR0YWNobWVudHM6IEF0dGFjaG1lbnQ8RGVmYXVsdFN0cmVhbUNoYXRHZW5lcmljcz5bXSA9IFtdO1xuICBpbWFnZXNUb1ZpZXc6IEF0dGFjaG1lbnQ8RGVmYXVsdFN0cmVhbUNoYXRHZW5lcmljcz5bXSA9IFtdO1xuICBpbWFnZXNUb1ZpZXdDdXJyZW50SW5kZXggPSAwO1xuICB0aGVtZVZlcnNpb246ICcxJyB8ICcyJztcbiAgQFZpZXdDaGlsZCgnbW9kYWxDb250ZW50JywgeyBzdGF0aWM6IHRydWUgfSlcbiAgcHJpdmF0ZSBtb2RhbENvbnRlbnQhOiBUZW1wbGF0ZVJlZjx2b2lkPjtcbiAgcHJpdmF0ZSBhdHRhY2htZW50Q29uZmlndXJhdGlvbnM6IE1hcDxcbiAgICBBdHRhY2htZW50LFxuICAgIHwgQXR0YWNobWVudENvbmZpZ3JhdGlvblxuICAgIHwgVmlkZW9BdHRhY2htZW50Q29uZmlndXJhdGlvblxuICAgIHwgSW1hZ2VBdHRhY2htZW50Q29uZmlndXJhdGlvblxuICA+ID0gbmV3IE1hcCgpO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHB1YmxpYyByZWFkb25seSBjdXN0b21UZW1wbGF0ZXNTZXJ2aWNlOiBDdXN0b21UZW1wbGF0ZXNTZXJ2aWNlLFxuICAgIHByaXZhdGUgY2hhbm5lbFNlcnZpY2U6IENoYW5uZWxTZXJ2aWNlLFxuICAgIHByaXZhdGUgYXR0YWNobWVudENvbmZpZ3VyYXRpb25TZXJ2aWNlOiBBdHRhY2htZW50Q29uZmlndXJhdGlvblNlcnZpY2UsXG4gICAgdGhlbWVTZXJ2aWNlOiBUaGVtZVNlcnZpY2VcbiAgKSB7XG4gICAgdGhpcy50aGVtZVZlcnNpb24gPSB0aGVtZVNlcnZpY2UudGhlbWVWZXJzaW9uO1xuICB9XG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICBpZiAoY2hhbmdlcy5hdHRhY2htZW50cykge1xuICAgICAgY29uc3QgaW1hZ2VzID0gdGhpcy5hdHRhY2htZW50cy5maWx0ZXIodGhpcy5pc0ltYWdlKTtcbiAgICAgIGNvbnN0IGNvbnRhaW5zR2FsbGVyeSA9IGltYWdlcy5sZW5ndGggPj0gMjtcbiAgICAgIHRoaXMub3JkZXJlZEF0dGFjaG1lbnRzID0gW1xuICAgICAgICAuLi4oY29udGFpbnNHYWxsZXJ5ID8gdGhpcy5jcmVhdGVHYWxsZXJ5KGltYWdlcykgOiBpbWFnZXMpLFxuICAgICAgICAuLi50aGlzLmF0dGFjaG1lbnRzLmZpbHRlcigoYSkgPT4gdGhpcy5pc1ZpZGVvKGEpKSxcbiAgICAgICAgLi4udGhpcy5hdHRhY2htZW50cy5maWx0ZXIoKGEpID0+IHRoaXMuaXNWb2ljZU1lc3NhZ2UoYSkpLFxuICAgICAgICAuLi50aGlzLmF0dGFjaG1lbnRzLmZpbHRlcigoYSkgPT4gdGhpcy5pc0ZpbGUoYSkpLFxuICAgICAgXTtcbiAgICAgIHRoaXMuYXR0YWNobWVudENvbmZpZ3VyYXRpb25zID0gbmV3IE1hcCgpO1xuICAgICAgLy8gRGlzcGxheSBsaW5rIGF0dGFjaG1lbnRzIG9ubHkgaWYgdGhlcmUgYXJlIG5vIG90aGVyIGF0dGFjaG1lbnRzXG4gICAgICAvLyBHaXBoeS1zIGFsd2F5cyBzZW50IHdpdGhvdXQgb3RoZXIgYXR0YWNobWVudHNcbiAgICAgIGlmICh0aGlzLm9yZGVyZWRBdHRhY2htZW50cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgdGhpcy5vcmRlcmVkQXR0YWNobWVudHMucHVzaChcbiAgICAgICAgICAuLi50aGlzLmF0dGFjaG1lbnRzLmZpbHRlcigoYSkgPT4gdGhpcy5pc0NhcmQoYSkpXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgdHJhY2tCeVVybChfOiBudW1iZXIsIGF0dGFjaG1lbnQ6IEF0dGFjaG1lbnQpIHtcbiAgICByZXR1cm4gKFxuICAgICAgYXR0YWNobWVudC5pbWFnZV91cmwgfHxcbiAgICAgIGF0dGFjaG1lbnQuaW1nX3VybCB8fFxuICAgICAgYXR0YWNobWVudC5hc3NldF91cmwgfHxcbiAgICAgIGF0dGFjaG1lbnQudGh1bWJfdXJsXG4gICAgKTtcbiAgfVxuXG4gIGlzSW1hZ2UoYXR0YWNobWVudDogQXR0YWNobWVudCkge1xuICAgIHJldHVybiBpc0ltYWdlQXR0YWNobWVudChhdHRhY2htZW50KTtcbiAgfVxuXG4gIGlzU3ZnKGF0dGFjaG1lbnQ6IEF0dGFjaG1lbnQpIHtcbiAgICBjb25zdCBmaWxlbmFtZSA9IGF0dGFjaG1lbnQuZmFsbGJhY2sgfHwgJyc7XG4gICAgcmV0dXJuICEhZmlsZW5hbWUudG9Mb3dlckNhc2UoKS5lbmRzV2l0aCgnLnN2ZycpO1xuICB9XG5cbiAgaXNGaWxlKGF0dGFjaG1lbnQ6IEF0dGFjaG1lbnQpIHtcbiAgICByZXR1cm4gYXR0YWNobWVudC50eXBlID09PSAnZmlsZSc7XG4gIH1cblxuICBpc0dhbGxlcnkoYXR0YWNobWVudDogQXR0YWNobWVudCkge1xuICAgIHJldHVybiBhdHRhY2htZW50LnR5cGUgPT09ICdnYWxsZXJ5JztcbiAgfVxuXG4gIGlzVmlkZW8oYXR0YWNobWVudDogQXR0YWNobWVudCkge1xuICAgIHJldHVybiAoXG4gICAgICBhdHRhY2htZW50LnR5cGUgPT09ICd2aWRlbycgJiZcbiAgICAgIGF0dGFjaG1lbnQuYXNzZXRfdXJsICYmXG4gICAgICAhYXR0YWNobWVudC5vZ19zY3JhcGVfdXJsIC8vIGxpbmtzIGZyb20gdmlkZW8gc2hhcmUgc2VydmljZXMgKHN1Y2ggYXMgWW91VHViZSBvciBGYWNlYm9vaykgYXJlIGNhbid0IGJlIHBsYXllZFxuICAgICk7XG4gIH1cblxuICBpc0NhcmQoYXR0YWNobWVudDogQXR0YWNobWVudCkge1xuICAgIHJldHVybiAoXG4gICAgICAhYXR0YWNobWVudC50eXBlIHx8XG4gICAgICAoYXR0YWNobWVudC50eXBlID09PSAnaW1hZ2UnICYmICF0aGlzLmlzSW1hZ2UoYXR0YWNobWVudCkpIHx8XG4gICAgICBhdHRhY2htZW50LnR5cGUgPT09ICdnaXBoeSdcbiAgICApO1xuICB9XG5cbiAgaXNWb2ljZU1lc3NhZ2UoYXR0YWNobWVudDogQXR0YWNobWVudCkge1xuICAgIHJldHVybiBhdHRhY2htZW50LnR5cGUgPT09ICd2b2ljZVJlY29yZGluZyc7XG4gIH1cblxuICBoYXNGaWxlU2l6ZShhdHRhY2htZW50OiBBdHRhY2htZW50PERlZmF1bHRTdHJlYW1DaGF0R2VuZXJpY3M+KSB7XG4gICAgcmV0dXJuIChcbiAgICAgIGF0dGFjaG1lbnQuZmlsZV9zaXplICYmIE51bWJlci5pc0Zpbml0ZShOdW1iZXIoYXR0YWNobWVudC5maWxlX3NpemUpKVxuICAgICk7XG4gIH1cblxuICBnZXRGaWxlU2l6ZShhdHRhY2htZW50OiBBdHRhY2htZW50PERlZmF1bHRTdHJlYW1DaGF0R2VuZXJpY3M+KSB7XG4gICAgcmV0dXJuIHByZXR0eWJ5dGVzKE51bWJlcihhdHRhY2htZW50LmZpbGVfc2l6ZSEpKTtcbiAgfVxuXG4gIGdldE1vZGFsQ29udGV4dCgpOiBNb2RhbENvbnRleHQge1xuICAgIHJldHVybiB7XG4gICAgICBpc09wZW46IHRoaXMuaW1hZ2VzVG9WaWV3ICYmIHRoaXMuaW1hZ2VzVG9WaWV3Lmxlbmd0aCA+IDAsXG4gICAgICBpc09wZW5DaGFuZ2VIYW5kbGVyOiAoaXNPcGVuKSA9PiAoaXNPcGVuID8gbnVsbCA6IHRoaXMuY2xvc2VJbWFnZU1vZGFsKCkpLFxuICAgICAgY29udGVudDogdGhpcy5tb2RhbENvbnRlbnQsXG4gICAgfTtcbiAgfVxuXG4gIHRyaW1VcmwodXJsPzogc3RyaW5nIHwgbnVsbCkge1xuICAgIGlmICh1cmwgIT09IHVuZGVmaW5lZCAmJiB1cmwgIT09IG51bGwpIHtcbiAgICAgIGNvbnN0IFt0cmltbWVkVXJsXSA9IHVybFxuICAgICAgICAucmVwbGFjZSgvXig/Omh0dHBzPzpcXC9cXC8pPyg/Ond3d1xcLik/L2ksICcnKVxuICAgICAgICAuc3BsaXQoJy8nKTtcblxuICAgICAgcmV0dXJuIHRyaW1tZWRVcmw7XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgc2VuZEFjdGlvbihhY3Rpb246IEFjdGlvbikge1xuICAgIHZvaWQgdGhpcy5jaGFubmVsU2VydmljZS5zZW5kQWN0aW9uKFxuICAgICAgdGhpcy5tZXNzYWdlSWQhLFxuICAgICAge1xuICAgICAgICBbYWN0aW9uLm5hbWUhXTogYWN0aW9uLnZhbHVlISxcbiAgICAgIH0sXG4gICAgICB0aGlzLnBhcmVudE1lc3NhZ2VJZFxuICAgICk7XG4gIH1cblxuICB0cmFja0J5QWN0aW9uVmFsdWUoXzogbnVtYmVyLCBpdGVtOiBBY3Rpb24pIHtcbiAgICByZXR1cm4gaXRlbS52YWx1ZTtcbiAgfVxuXG4gIG9wZW5JbWFnZU1vZGFsKGF0dGFjaG1lbnRzOiBBdHRhY2htZW50W10sIHNlbGVjdGVkSW5kZXggPSAwKSB7XG4gICAgdGhpcy5pbWFnZU1vZGFsU3RhdGVDaGFuZ2UubmV4dCgnb3BlbmVkJyk7XG4gICAgdGhpcy5pbWFnZXNUb1ZpZXcgPSBhdHRhY2htZW50cztcbiAgICB0aGlzLmltYWdlc1RvVmlld0N1cnJlbnRJbmRleCA9IHNlbGVjdGVkSW5kZXg7XG4gIH1cblxuICBzdGVwSW1hZ2VzKGRpcjogLTEgfCAxKSB7XG4gICAgdGhpcy5pbWFnZXNUb1ZpZXdDdXJyZW50SW5kZXggKz0gZGlyICogMTtcbiAgfVxuXG4gIHRyYWNrQnlJbWFnZVVybChfOiBudW1iZXIsIGl0ZW06IEF0dGFjaG1lbnQpIHtcbiAgICByZXR1cm4gaXRlbS5pbWFnZV91cmwgfHwgaXRlbS5pbWdfdXJsIHx8IGl0ZW0udGh1bWJfdXJsO1xuICB9XG5cbiAgZ2V0QXR0YWNobWVudENvbnRleHQoXG4gICAgYXR0YWNobWVudDogQXR0YWNobWVudDxEZWZhdWx0U3RyZWFtQ2hhdEdlbmVyaWNzPlxuICApOiBBdHRhY2htZW50Q29udGV4dCB7XG4gICAgcmV0dXJuIHsgYXR0YWNobWVudCB9O1xuICB9XG5cbiAgZ2V0SW1hZ2VBdHRhY2htZW50Q29uZmlndXJhdGlvbihcbiAgICBhdHRhY2htZW50OiBBdHRhY2htZW50LFxuICAgIHR5cGU6ICdnYWxsZXJ5JyB8ICdzaW5nbGUnLFxuICAgIGVsZW1lbnQ6IEhUTUxFbGVtZW50XG4gICk6IEltYWdlQXR0YWNobWVudENvbmZpZ3VyYXRpb24ge1xuICAgIGNvbnN0IGV4aXN0aW5nQ29uZmlndXJhdGlvbiA9IHRoaXMuYXR0YWNobWVudENvbmZpZ3VyYXRpb25zLmdldChhdHRhY2htZW50KTtcbiAgICBpZiAoZXhpc3RpbmdDb25maWd1cmF0aW9uKSB7XG4gICAgICByZXR1cm4gZXhpc3RpbmdDb25maWd1cmF0aW9uIGFzIEltYWdlQXR0YWNobWVudENvbmZpZ3VyYXRpb247XG4gICAgfVxuICAgIGNvbnN0IGNvbmZpZ3VyYXRpb24gPVxuICAgICAgdGhpcy5hdHRhY2htZW50Q29uZmlndXJhdGlvblNlcnZpY2UuZ2V0SW1hZ2VBdHRhY2htZW50Q29uZmlndXJhdGlvbihcbiAgICAgICAgYXR0YWNobWVudCxcbiAgICAgICAgdHlwZSxcbiAgICAgICAgZWxlbWVudFxuICAgICAgKTtcbiAgICB0aGlzLmF0dGFjaG1lbnRDb25maWd1cmF0aW9ucy5zZXQoYXR0YWNobWVudCwgY29uZmlndXJhdGlvbik7XG4gICAgcmV0dXJuIGNvbmZpZ3VyYXRpb247XG4gIH1cblxuICBnZXRDYXJvdXNlbEltYWdlQXR0YWNobWVudENvbmZpZ3VyYXRpb24oXG4gICAgYXR0YWNobWVudDogQXR0YWNobWVudCxcbiAgICBlbGVtZW50OiBIVE1MRWxlbWVudFxuICApIHtcbiAgICByZXR1cm4gdGhpcy5hdHRhY2htZW50Q29uZmlndXJhdGlvblNlcnZpY2UuZ2V0SW1hZ2VBdHRhY2htZW50Q29uZmlndXJhdGlvbihcbiAgICAgIGF0dGFjaG1lbnQsXG4gICAgICAnY2Fyb3VzZWwnLFxuICAgICAgZWxlbWVudFxuICAgICk7XG4gIH1cblxuICBnZXRWaWRlb0F0dGFjaG1lbnRDb25maWd1cmF0aW9uKFxuICAgIGF0dGFjaG1lbnQ6IEF0dGFjaG1lbnQsXG4gICAgZWxlbWVudDogSFRNTEVsZW1lbnRcbiAgKTogVmlkZW9BdHRhY2htZW50Q29uZmlndXJhdGlvbiB7XG4gICAgY29uc3QgZXhpc3RpbmdDb25maWd1cmF0aW9uID0gdGhpcy5hdHRhY2htZW50Q29uZmlndXJhdGlvbnMuZ2V0KGF0dGFjaG1lbnQpO1xuICAgIGlmIChleGlzdGluZ0NvbmZpZ3VyYXRpb24pIHtcbiAgICAgIHJldHVybiBleGlzdGluZ0NvbmZpZ3VyYXRpb24gYXMgVmlkZW9BdHRhY2htZW50Q29uZmlndXJhdGlvbjtcbiAgICB9XG4gICAgY29uc3QgY29uZmlndXJhdGlvbiA9XG4gICAgICB0aGlzLmF0dGFjaG1lbnRDb25maWd1cmF0aW9uU2VydmljZS5nZXRWaWRlb0F0dGFjaG1lbnRDb25maWd1cmF0aW9uKFxuICAgICAgICBhdHRhY2htZW50LFxuICAgICAgICBlbGVtZW50XG4gICAgICApO1xuICAgIHRoaXMuYXR0YWNobWVudENvbmZpZ3VyYXRpb25zLnNldChhdHRhY2htZW50LCBjb25maWd1cmF0aW9uKTtcbiAgICByZXR1cm4gY29uZmlndXJhdGlvbjtcbiAgfVxuXG4gIGdldENhcmRBdHRhY2htZW50Q29uZmlndXJhdGlvbihhdHRhY2htZW50OiBBdHRhY2htZW50KSB7XG4gICAgY29uc3QgZXhpc3RpbmdDb25maWd1cmF0aW9uID0gdGhpcy5hdHRhY2htZW50Q29uZmlndXJhdGlvbnMuZ2V0KGF0dGFjaG1lbnQpO1xuICAgIGlmIChleGlzdGluZ0NvbmZpZ3VyYXRpb24pIHtcbiAgICAgIHJldHVybiBleGlzdGluZ0NvbmZpZ3VyYXRpb247XG4gICAgfVxuICAgIGlmIChhdHRhY2htZW50LnR5cGUgPT09ICdnaXBoeScpIHtcbiAgICAgIHJldHVybiB0aGlzLmF0dGFjaG1lbnRDb25maWd1cmF0aW9uU2VydmljZS5nZXRHaXBoeUF0dGFjaG1lbnRDb25maWd1cmF0aW9uKFxuICAgICAgICBhdHRhY2htZW50XG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBjb25maWd1cmF0aW9uID1cbiAgICAgICAgdGhpcy5hdHRhY2htZW50Q29uZmlndXJhdGlvblNlcnZpY2UuZ2V0U2NyYXBlZEltYWdlQXR0YWNobWVudENvbmZpZ3VyYXRpb24oXG4gICAgICAgICAgYXR0YWNobWVudFxuICAgICAgICApO1xuICAgICAgdGhpcy5hdHRhY2htZW50Q29uZmlndXJhdGlvbnMuc2V0KGF0dGFjaG1lbnQsIGNvbmZpZ3VyYXRpb24pO1xuICAgICAgcmV0dXJuIGNvbmZpZ3VyYXRpb247XG4gICAgfVxuICB9XG5cbiAgZ2V0IGlzSW1hZ2VNb2RhbFByZXZCdXR0b25WaXNpYmxlKCkge1xuICAgIHJldHVybiB0aGlzLmltYWdlc1RvVmlld0N1cnJlbnRJbmRleCAhPT0gMDtcbiAgfVxuXG4gIGdldCBpc0ltYWdlTW9kYWxOZXh0QnV0dG9uVmlzaWJsZSgpIHtcbiAgICByZXR1cm4gdGhpcy5pbWFnZXNUb1ZpZXdDdXJyZW50SW5kZXggIT09IHRoaXMuaW1hZ2VzVG9WaWV3Lmxlbmd0aCAtIDE7XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZUdhbGxlcnkoaW1hZ2VzOiBBdHRhY2htZW50W10pIHtcbiAgICByZXR1cm4gW1xuICAgICAge1xuICAgICAgICB0eXBlOiAnZ2FsbGVyeScsXG4gICAgICAgIGltYWdlcyxcbiAgICAgIH0sXG4gICAgXTtcbiAgfVxuXG4gIHByaXZhdGUgY2xvc2VJbWFnZU1vZGFsKCkge1xuICAgIHRoaXMuaW1hZ2VNb2RhbFN0YXRlQ2hhbmdlLm5leHQoJ2Nsb3NlZCcpO1xuICAgIHRoaXMuaW1hZ2VzVG9WaWV3ID0gW107XG4gIH1cbn1cbiIsIjxkaXYgKm5nSWY9XCJvcmRlcmVkQXR0YWNobWVudHMubGVuZ3RoID4gMFwiIGNsYXNzPVwic3RyLWNoYXRfX2F0dGFjaG1lbnQtbGlzdFwiPlxuICA8bmctY29udGFpbmVyXG4gICAgKm5nRm9yPVwibGV0IGF0dGFjaG1lbnQgb2Ygb3JkZXJlZEF0dGFjaG1lbnRzOyB0cmFja0J5OiB0cmFja0J5VXJsXCJcbiAgPlxuICAgIDxkaXZcbiAgICAgIGRhdGEtdGVzdGNsYXNzPVwiYXR0YWNobWVudC1jb250YWluZXJcIlxuICAgICAgY2xhc3M9XCJzdHItY2hhdF9fbWVzc2FnZS1hdHRhY2htZW50IHN0ci1jaGF0X19tZXNzYWdlLWF0dGFjaG1lbnQtLXt7XG4gICAgICAgIGF0dGFjaG1lbnQudHlwZVxuICAgICAgfX0gc3RyLWNoYXRfX21lc3NhZ2UtYXR0YWNobWVudC1keW5hbWljLXNpemVcIlxuICAgICAgW2NsYXNzLnN0ci1jaGF0X19tZXNzYWdlLWF0dGFjaG1lbnQtLWNhcmRdPVwiaXNDYXJkKGF0dGFjaG1lbnQpXCJcbiAgICAgIFtjbGFzcy5zdHItY2hhdC1hbmd1bGFyX19tZXNzYWdlLWF0dGFjaG1lbnQtZmlsZS1zaW5nbGVdPVwiXG4gICAgICAgIGlzRmlsZShhdHRhY2htZW50KVxuICAgICAgXCJcbiAgICAgIFtjbGFzcy5zdHItY2hhdF9fbWVzc2FnZS1hdHRhY2htZW50LS12b2ljZS1yZWNvcmRpbmddPVwiXG4gICAgICAgIGlzVm9pY2VNZXNzYWdlKGF0dGFjaG1lbnQpXG4gICAgICBcIlxuICAgICAgW2NsYXNzLnN0ci1jaGF0X19tZXNzYWdlLWF0dGFjaG1lbnQtd2l0aC1hY3Rpb25zXT1cIlxuICAgICAgICBhdHRhY2htZW50LmFjdGlvbnMgJiYgYXR0YWNobWVudC5hY3Rpb25zLmxlbmd0aCA+IDBcbiAgICAgIFwiXG4gICAgICBbY2xhc3Muc3RyLWNoYXRfX21lc3NhZ2UtYXR0YWNobWVudC0tc3ZnLWltYWdlXT1cImlzU3ZnKGF0dGFjaG1lbnQpXCJcbiAgICA+XG4gICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXNJbWFnZShhdHRhY2htZW50KVwiPlxuICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgKm5nVGVtcGxhdGVPdXRsZXQ9XCJcbiAgICAgICAgICAgIChjdXN0b21UZW1wbGF0ZXNTZXJ2aWNlLmltYWdlQXR0YWNobWVudFRlbXBsYXRlJCB8IGFzeW5jKSB8fFxuICAgICAgICAgICAgICBkZWZhdWx0SW1hZ2U7XG4gICAgICAgICAgICBjb250ZXh0OiBnZXRBdHRhY2htZW50Q29udGV4dChhdHRhY2htZW50KVxuICAgICAgICAgIFwiXG4gICAgICAgID48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPG5nLXRlbXBsYXRlICNkZWZhdWx0SW1hZ2UgbGV0LWF0dGFjaG1lbnRDb250ZXh0PVwiYXR0YWNobWVudFwiPlxuICAgICAgICAgIDxpbWdcbiAgICAgICAgICAgICNpbWdFbGVtZW50XG4gICAgICAgICAgICBjbGFzcz1cInN0ci1jaGF0X19tZXNzYWdlLWF0dGFjaG1lbnQtLWltZ1wiXG4gICAgICAgICAgICBkYXRhLXRlc3RjbGFzcz1cImltYWdlXCJcbiAgICAgICAgICAgIFtzcmNdPVwiXG4gICAgICAgICAgICAgIGdldEltYWdlQXR0YWNobWVudENvbmZpZ3VyYXRpb24oXG4gICAgICAgICAgICAgICAgYXR0YWNobWVudENvbnRleHQsXG4gICAgICAgICAgICAgICAgJ3NpbmdsZScsXG4gICAgICAgICAgICAgICAgaW1nRWxlbWVudFxuICAgICAgICAgICAgICApLnVybFxuICAgICAgICAgICAgXCJcbiAgICAgICAgICAgIFthbHRdPVwiYXR0YWNobWVudENvbnRleHQ/LmZhbGxiYWNrXCJcbiAgICAgICAgICAgIFtuZ1N0eWxlXT1cIntcbiAgICAgICAgICAgICAgaGVpZ2h0OiBnZXRJbWFnZUF0dGFjaG1lbnRDb25maWd1cmF0aW9uKFxuICAgICAgICAgICAgICAgIGF0dGFjaG1lbnRDb250ZXh0LFxuICAgICAgICAgICAgICAgICdzaW5nbGUnLFxuICAgICAgICAgICAgICAgIGltZ0VsZW1lbnRcbiAgICAgICAgICAgICAgKS5oZWlnaHQsXG4gICAgICAgICAgICAgIHdpZHRoOiBnZXRJbWFnZUF0dGFjaG1lbnRDb25maWd1cmF0aW9uKFxuICAgICAgICAgICAgICAgIGF0dGFjaG1lbnRDb250ZXh0LFxuICAgICAgICAgICAgICAgICdzaW5nbGUnLFxuICAgICAgICAgICAgICAgIGltZ0VsZW1lbnRcbiAgICAgICAgICAgICAgKS53aWR0aCxcbiAgICAgICAgICAgICAgJy0tb3JpZ2luYWwtaGVpZ2h0JzogZ2V0SW1hZ2VBdHRhY2htZW50Q29uZmlndXJhdGlvbihcbiAgICAgICAgICAgICAgICBhdHRhY2htZW50Q29udGV4dCxcbiAgICAgICAgICAgICAgICAnc2luZ2xlJyxcbiAgICAgICAgICAgICAgICBpbWdFbGVtZW50XG4gICAgICAgICAgICAgICkub3JpZ2luYWxIZWlnaHQsXG4gICAgICAgICAgICAgICctLW9yaWdpbmFsLXdpZHRoJzogZ2V0SW1hZ2VBdHRhY2htZW50Q29uZmlndXJhdGlvbihcbiAgICAgICAgICAgICAgICBhdHRhY2htZW50Q29udGV4dCxcbiAgICAgICAgICAgICAgICAnc2luZ2xlJyxcbiAgICAgICAgICAgICAgICBpbWdFbGVtZW50XG4gICAgICAgICAgICAgICkub3JpZ2luYWxXaWR0aFxuICAgICAgICAgICAgfVwiXG4gICAgICAgICAgICAoY2xpY2spPVwib3BlbkltYWdlTW9kYWwoW2F0dGFjaG1lbnRDb250ZXh0XSlcIlxuICAgICAgICAgICAgKGtleXVwLmVudGVyKT1cIm9wZW5JbWFnZU1vZGFsKFthdHRhY2htZW50Q29udGV4dF0pXCJcbiAgICAgICAgICAvPlxuICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXNHYWxsZXJ5KGF0dGFjaG1lbnQpXCI+XG4gICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAqbmdUZW1wbGF0ZU91dGxldD1cIlxuICAgICAgICAgICAgKGN1c3RvbVRlbXBsYXRlc1NlcnZpY2UuZ2FsbGVyeUF0dGFjaG1lbnRUZW1wbGF0ZSQgfCBhc3luYykgfHxcbiAgICAgICAgICAgICAgZGVmYXVsdEdhbGxlcnk7XG4gICAgICAgICAgICBjb250ZXh0OiBnZXRBdHRhY2htZW50Q29udGV4dChhdHRhY2htZW50KVxuICAgICAgICAgIFwiXG4gICAgICAgID48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPG5nLXRlbXBsYXRlICNkZWZhdWx0R2FsbGVyeSBsZXQtYXR0YWNobWVudENvbnRleHQ9XCJhdHRhY2htZW50XCI+XG4gICAgICAgICAgPGRpdlxuICAgICAgICAgICAgY2xhc3M9XCJzdHItY2hhdF9fZ2FsbGVyeVwiXG4gICAgICAgICAgICBkYXRhLXRlc3RpZD1cImltYWdlLWdhbGxlcnlcIlxuICAgICAgICAgICAgW2NsYXNzLnN0ci1jaGF0X19nYWxsZXJ5LS1zcXVhcmVdPVwiXG4gICAgICAgICAgICAgIChhdHRhY2htZW50Q29udGV4dD8uaW1hZ2VzKSEubGVuZ3RoID4gM1xuICAgICAgICAgICAgXCJcbiAgICAgICAgICAgIFtjbGFzcy5zdHItY2hhdF9fZ2FsbGVyeS10d28tcm93c109XCJcbiAgICAgICAgICAgICAgKGF0dGFjaG1lbnRDb250ZXh0Py5pbWFnZXMpIS5sZW5ndGggPiAyXG4gICAgICAgICAgICBcIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAgICAgKm5nRm9yPVwiXG4gICAgICAgICAgICAgICAgbGV0IGdhbGxlcnlJbWFnZSBvZiBhdHRhY2htZW50Q29udGV4dC5pbWFnZXM7XG4gICAgICAgICAgICAgICAgbGV0IGluZGV4ID0gaW5kZXg7XG4gICAgICAgICAgICAgICAgbGV0IGlzTGFzdCA9IGxhc3Q7XG4gICAgICAgICAgICAgICAgdHJhY2tCeTogdHJhY2tCeUltYWdlVXJsXG4gICAgICAgICAgICAgIFwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICAqbmdJZj1cImluZGV4IDwgMyB8fCAoaW5kZXggPT09IDMgJiYgaXNMYXN0KVwiXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJzdHItY2hhdF9fZ2FsbGVyeS1pbWFnZVwiXG4gICAgICAgICAgICAgICAgZGF0YS10ZXN0Y2xhc3M9XCJnYWxsZXJ5LWltYWdlXCJcbiAgICAgICAgICAgICAgICBbY2xhc3Muc3RyLWNoYXRfX21lc3NhZ2UtYXR0YWNobWVudC0tc3ZnLWltYWdlXT1cIlxuICAgICAgICAgICAgICAgICAgaXNTdmcoZ2FsbGVyeUltYWdlKVxuICAgICAgICAgICAgICAgIFwiXG4gICAgICAgICAgICAgICAgKGNsaWNrKT1cIm9wZW5JbWFnZU1vZGFsKGF0dGFjaG1lbnRDb250ZXh0LmltYWdlcyEsIGluZGV4KVwiXG4gICAgICAgICAgICAgICAgKGtleXVwLmVudGVyKT1cIm9wZW5JbWFnZU1vZGFsKGF0dGFjaG1lbnRDb250ZXh0LmltYWdlcyEsIGluZGV4KVwiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICA8aW1nXG4gICAgICAgICAgICAgICAgICAjaW1nRWxlbWVudFxuICAgICAgICAgICAgICAgICAgZmV0Y2hwcmlvcml0eT1cImxvd1wiXG4gICAgICAgICAgICAgICAgICBsb2FkaW5nPVwibGF6eVwiXG4gICAgICAgICAgICAgICAgICBbc3JjXT1cIlxuICAgICAgICAgICAgICAgICAgICBnZXRJbWFnZUF0dGFjaG1lbnRDb25maWd1cmF0aW9uKFxuICAgICAgICAgICAgICAgICAgICAgIGdhbGxlcnlJbWFnZSxcbiAgICAgICAgICAgICAgICAgICAgICAnZ2FsbGVyeScsXG4gICAgICAgICAgICAgICAgICAgICAgaW1nRWxlbWVudFxuICAgICAgICAgICAgICAgICAgICApLnVybFxuICAgICAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgICAgIFthbHRdPVwiZ2FsbGVyeUltYWdlLmZhbGxiYWNrXCJcbiAgICAgICAgICAgICAgICAgIFtzdHlsZS4tLW9yaWdpbmFsLWhlaWdodF09XCJcbiAgICAgICAgICAgICAgICAgICAgZ2V0SW1hZ2VBdHRhY2htZW50Q29uZmlndXJhdGlvbihcbiAgICAgICAgICAgICAgICAgICAgICBnYWxsZXJ5SW1hZ2UsXG4gICAgICAgICAgICAgICAgICAgICAgJ2dhbGxlcnknLFxuICAgICAgICAgICAgICAgICAgICAgIGltZ0VsZW1lbnRcbiAgICAgICAgICAgICAgICAgICAgKS5vcmlnaW5hbEhlaWdodFxuICAgICAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgICAgIFtzdHlsZS4tLW9yaWdpbmFsLXdpZHRoXT1cIlxuICAgICAgICAgICAgICAgICAgICBnZXRJbWFnZUF0dGFjaG1lbnRDb25maWd1cmF0aW9uKFxuICAgICAgICAgICAgICAgICAgICAgIGdhbGxlcnlJbWFnZSxcbiAgICAgICAgICAgICAgICAgICAgICAnZ2FsbGVyeScsXG4gICAgICAgICAgICAgICAgICAgICAgaW1nRWxlbWVudFxuICAgICAgICAgICAgICAgICAgICApLm9yaWdpbmFsV2lkdGhcbiAgICAgICAgICAgICAgICAgIFwiXG4gICAgICAgICAgICAgICAgICBbbmdTdHlsZV09XCJ7XG4gICAgICAgICAgICAgICAgICAgIGhlaWdodDogZ2V0SW1hZ2VBdHRhY2htZW50Q29uZmlndXJhdGlvbihcbiAgICAgICAgICAgICAgICAgICAgICBnYWxsZXJ5SW1hZ2UsXG4gICAgICAgICAgICAgICAgICAgICAgJ2dhbGxlcnknLFxuICAgICAgICAgICAgICAgICAgICAgIGltZ0VsZW1lbnRcbiAgICAgICAgICAgICAgICAgICAgKS5oZWlnaHQsXG4gICAgICAgICAgICAgICAgICAgIHdpZHRoOiBnZXRJbWFnZUF0dGFjaG1lbnRDb25maWd1cmF0aW9uKFxuICAgICAgICAgICAgICAgICAgICAgIGdhbGxlcnlJbWFnZSxcbiAgICAgICAgICAgICAgICAgICAgICAnZ2FsbGVyeScsXG4gICAgICAgICAgICAgICAgICAgICAgaW1nRWxlbWVudFxuICAgICAgICAgICAgICAgICAgICApLndpZHRoXG4gICAgICAgICAgICAgICAgICB9XCJcbiAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgICpuZ0lmPVwiaW5kZXggPT09IDMgJiYgIWlzTGFzdFwiXG4gICAgICAgICAgICAgICAgI2VsZW1lbnRcbiAgICAgICAgICAgICAgICBjbGFzcz1cInN0ci1jaGF0X19nYWxsZXJ5LXBsYWNlaG9sZGVyXCJcbiAgICAgICAgICAgICAgICBkYXRhLXRlc3RjbGFzcz1cImdhbGxlcnktaW1hZ2VcIlxuICAgICAgICAgICAgICAgIGRhdGEtdGVzdGlkPVwibW9yZS1pbWFnZS1idXR0b25cIlxuICAgICAgICAgICAgICAgIFtjbGFzcy5zdHItY2hhdF9fbWVzc2FnZS1hdHRhY2htZW50LS1zdmctaW1hZ2VdPVwiXG4gICAgICAgICAgICAgICAgICBpc1N2ZyhnYWxsZXJ5SW1hZ2UpXG4gICAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgICBbbmdTdHlsZV09XCJ7XG4gICAgICAgICAgICAgICAgICAnYmFja2dyb3VuZC1pbWFnZSc6XG4gICAgICAgICAgICAgICAgICAgICd1cmwoJyArXG4gICAgICAgICAgICAgICAgICAgIGdldEltYWdlQXR0YWNobWVudENvbmZpZ3VyYXRpb24oXG4gICAgICAgICAgICAgICAgICAgICAgZ2FsbGVyeUltYWdlLFxuICAgICAgICAgICAgICAgICAgICAgICdnYWxsZXJ5JyxcbiAgICAgICAgICAgICAgICAgICAgICBlbGVtZW50XG4gICAgICAgICAgICAgICAgICAgICkudXJsICtcbiAgICAgICAgICAgICAgICAgICAgJyknLFxuICAgICAgICAgICAgICAgICAgaGVpZ2h0OiBnZXRJbWFnZUF0dGFjaG1lbnRDb25maWd1cmF0aW9uKFxuICAgICAgICAgICAgICAgICAgICBnYWxsZXJ5SW1hZ2UsXG4gICAgICAgICAgICAgICAgICAgICdnYWxsZXJ5JyxcbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudFxuICAgICAgICAgICAgICAgICAgKS5oZWlnaHQsXG4gICAgICAgICAgICAgICAgICB3aWR0aDogZ2V0SW1hZ2VBdHRhY2htZW50Q29uZmlndXJhdGlvbihcbiAgICAgICAgICAgICAgICAgICAgZ2FsbGVyeUltYWdlLFxuICAgICAgICAgICAgICAgICAgICAnZ2FsbGVyeScsXG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnRcbiAgICAgICAgICAgICAgICAgICkud2lkdGgsXG4gICAgICAgICAgICAgICAgICAnLS1vcmlnaW5hbC1oZWlnaHQnOiBnZXRJbWFnZUF0dGFjaG1lbnRDb25maWd1cmF0aW9uKFxuICAgICAgICAgICAgICAgICAgICBnYWxsZXJ5SW1hZ2UsXG4gICAgICAgICAgICAgICAgICAgICdnYWxsZXJ5JyxcbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudFxuICAgICAgICAgICAgICAgICAgKS5vcmlnaW5hbEhlaWdodCxcbiAgICAgICAgICAgICAgICAgICctLW9yaWdpbmFsLXdpZHRoJzogZ2V0SW1hZ2VBdHRhY2htZW50Q29uZmlndXJhdGlvbihcbiAgICAgICAgICAgICAgICAgICAgZ2FsbGVyeUltYWdlLFxuICAgICAgICAgICAgICAgICAgICAnZ2FsbGVyeScsXG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnRcbiAgICAgICAgICAgICAgICAgICkub3JpZ2luYWxXaWR0aFxuICAgICAgICAgICAgICAgIH1cIlxuICAgICAgICAgICAgICAgIChjbGljayk9XCJvcGVuSW1hZ2VNb2RhbChhdHRhY2htZW50Q29udGV4dC5pbWFnZXMhLCBpbmRleClcIlxuICAgICAgICAgICAgICAgIChrZXl1cC5lbnRlcik9XCJvcGVuSW1hZ2VNb2RhbChhdHRhY2htZW50Q29udGV4dC5pbWFnZXMhLCBpbmRleClcIlxuICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgPHBcbiAgICAgICAgICAgICAgICAgIFtpbm5lckhUTUxdPVwiXG4gICAgICAgICAgICAgICAgICAgICdzdHJlYW1DaGF0Lnt7IGltYWdlQ291bnQgfX0gbW9yZSdcbiAgICAgICAgICAgICAgICAgICAgICB8IHRyYW5zbGF0ZVxuICAgICAgICAgICAgICAgICAgICAgICAgOiB7IGltYWdlQ291bnQ6IGF0dGFjaG1lbnRDb250ZXh0IS5pbWFnZXMhLmxlbmd0aCAtIDQgfVxuICAgICAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgICA+PC9wPlxuICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXNWaWRlbyhhdHRhY2htZW50KVwiPlxuICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgKm5nVGVtcGxhdGVPdXRsZXQ9XCJcbiAgICAgICAgICAgIChjdXN0b21UZW1wbGF0ZXNTZXJ2aWNlLnZpZGVvQXR0YWNobWVudFRlbXBsYXRlJCB8IGFzeW5jKSB8fFxuICAgICAgICAgICAgICBkZWZhdWx0VmlkZW87XG4gICAgICAgICAgICBjb250ZXh0OiBnZXRBdHRhY2htZW50Q29udGV4dChhdHRhY2htZW50KVxuICAgICAgICAgIFwiXG4gICAgICAgID48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPG5nLXRlbXBsYXRlICNkZWZhdWx0VmlkZW8gbGV0LWF0dGFjaG1lbnRDb250ZXh0PVwiYXR0YWNobWVudFwiPlxuICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgIGNsYXNzPVwic3RyLWNoYXRfX3BsYXllci13cmFwcGVyXCJcbiAgICAgICAgICAgIGRhdGEtdGVzdGNsYXNzPVwidmlkZW8tYXR0YWNobWVudC1wYXJlbnRcIlxuICAgICAgICAgICAgW3N0eWxlLi0tb3JpZ2luYWwtaGVpZ2h0XT1cIlxuICAgICAgICAgICAgICBnZXRWaWRlb0F0dGFjaG1lbnRDb25maWd1cmF0aW9uKGF0dGFjaG1lbnRDb250ZXh0LCB2aWRlb0VsZW1lbnQpXG4gICAgICAgICAgICAgICAgLm9yaWdpbmFsSGVpZ2h0XG4gICAgICAgICAgICBcIlxuICAgICAgICAgICAgW3N0eWxlLi0tb3JpZ2luYWwtd2lkdGhdPVwiXG4gICAgICAgICAgICAgIGdldFZpZGVvQXR0YWNobWVudENvbmZpZ3VyYXRpb24oYXR0YWNobWVudENvbnRleHQsIHZpZGVvRWxlbWVudClcbiAgICAgICAgICAgICAgICAub3JpZ2luYWxXaWR0aFxuICAgICAgICAgICAgXCJcbiAgICAgICAgICAgIFtuZ1N0eWxlXT1cIntcbiAgICAgICAgICAgICAgaGVpZ2h0OiBnZXRWaWRlb0F0dGFjaG1lbnRDb25maWd1cmF0aW9uKFxuICAgICAgICAgICAgICAgIGF0dGFjaG1lbnRDb250ZXh0LFxuICAgICAgICAgICAgICAgIHZpZGVvRWxlbWVudFxuICAgICAgICAgICAgICApLmhlaWdodCxcbiAgICAgICAgICAgICAgd2lkdGg6IGdldFZpZGVvQXR0YWNobWVudENvbmZpZ3VyYXRpb24oXG4gICAgICAgICAgICAgICAgYXR0YWNobWVudENvbnRleHQsXG4gICAgICAgICAgICAgICAgdmlkZW9FbGVtZW50XG4gICAgICAgICAgICAgICkud2lkdGhcbiAgICAgICAgICAgIH1cIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIDx2aWRlb1xuICAgICAgICAgICAgICAjdmlkZW9FbGVtZW50XG4gICAgICAgICAgICAgIGNsYXNzPVwic3RyLWNoYXRfX3ZpZGVvLWFuZ3VsYXJcIlxuICAgICAgICAgICAgICBjb250cm9sc1xuICAgICAgICAgICAgICBkYXRhLXRlc3RjbGFzcz1cInZpZGVvLWF0dGFjaG1lbnRcIlxuICAgICAgICAgICAgICBbc3JjXT1cIlxuICAgICAgICAgICAgICAgIGdldFZpZGVvQXR0YWNobWVudENvbmZpZ3VyYXRpb24oYXR0YWNobWVudENvbnRleHQsIHZpZGVvRWxlbWVudClcbiAgICAgICAgICAgICAgICAgIC51cmxcbiAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgW3Bvc3Rlcl09XCJcbiAgICAgICAgICAgICAgICBnZXRWaWRlb0F0dGFjaG1lbnRDb25maWd1cmF0aW9uKGF0dGFjaG1lbnRDb250ZXh0LCB2aWRlb0VsZW1lbnQpXG4gICAgICAgICAgICAgICAgICAudGh1bWJVcmxcbiAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgID48L3ZpZGVvPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXNGaWxlKGF0dGFjaG1lbnQpXCI+XG4gICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAqbmdUZW1wbGF0ZU91dGxldD1cIlxuICAgICAgICAgICAgKGN1c3RvbVRlbXBsYXRlc1NlcnZpY2UuZmlsZUF0dGFjaG1lbnRUZW1wbGF0ZSQgfCBhc3luYykgfHxcbiAgICAgICAgICAgICAgZGVmYXVsdEZpbGU7XG4gICAgICAgICAgICBjb250ZXh0OiBnZXRBdHRhY2htZW50Q29udGV4dChhdHRhY2htZW50KVxuICAgICAgICAgIFwiXG4gICAgICAgID48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPG5nLXRlbXBsYXRlICNkZWZhdWx0RmlsZSBsZXQtYXR0YWNobWVudENvbnRleHQ9XCJhdHRhY2htZW50XCI+XG4gICAgICAgICAgPGRpdlxuICAgICAgICAgICAgY2xhc3M9XCJcbiAgICAgICAgICAgICAgc3RyLWNoYXRfX21lc3NhZ2UtYXR0YWNobWVudC1maWxlLS1pdGVtXG4gICAgICAgICAgICAgIHN0ci1jaGF0LWFuZ3VsYXJfX21lc3NhZ2UtYXR0YWNobWVudC1maWxlLXNpbmdsZVxuICAgICAgICAgICAgXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICA8c3RyZWFtLWljb24tcGxhY2Vob2xkZXJcbiAgICAgICAgICAgICAgKm5nSWY9XCJ0aGVtZVZlcnNpb24gPT09ICcxJ1wiXG4gICAgICAgICAgICAgIGljb249XCJmaWxlXCJcbiAgICAgICAgICAgICAgW3NpemVdPVwiMzBcIlxuICAgICAgICAgICAgPjwvc3RyZWFtLWljb24tcGxhY2Vob2xkZXI+XG4gICAgICAgICAgICA8c3RyZWFtLWljb24tcGxhY2Vob2xkZXJcbiAgICAgICAgICAgICAgKm5nSWY9XCJ0aGVtZVZlcnNpb24gPT09ICcyJ1wiXG4gICAgICAgICAgICAgIGljb249XCJ1bnNwZWNpZmllZC1maWxldHlwZVwiXG4gICAgICAgICAgICAgIFtzaXplXT1cIjMwXCJcbiAgICAgICAgICAgID48L3N0cmVhbS1pY29uLXBsYWNlaG9sZGVyPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN0ci1jaGF0X19tZXNzYWdlLWF0dGFjaG1lbnQtZmlsZS0taXRlbS10ZXh0XCI+XG4gICAgICAgICAgICAgIDxhXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJzdHItY2hhdF9fbWVzc2FnZS1hdHRhY2htZW50LWZpbGUtLWl0ZW0tZmlyc3Qtcm93XCJcbiAgICAgICAgICAgICAgICBkYXRhLXRlc3RjbGFzcz1cImZpbGUtbGlua1wiXG4gICAgICAgICAgICAgICAgdGFyZ2V0PVwiX2JsYW5rXCJcbiAgICAgICAgICAgICAgICBocmVmPVwie3sgYXR0YWNobWVudENvbnRleHQuYXNzZXRfdXJsIH19XCJcbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICAgIGRhdGEtdGVzdGNsYXNzPVwiZmlsZS10aXRsZVwiXG4gICAgICAgICAgICAgICAgICBjbGFzcz1cInN0ci1jaGF0X19tZXNzYWdlLWF0dGFjaG1lbnQtZmlsZS0taXRlbS1uYW1lXCJcbiAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICB7eyBhdHRhY2htZW50Q29udGV4dC50aXRsZSB9fVxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxzdHJlYW0taWNvbi1wbGFjZWhvbGRlclxuICAgICAgICAgICAgICAgICAgY2xhc3M9XCJzdHItY2hhdF9fbWVzc2FnZS1hdHRhY2htZW50LWRvd25sb2FkLWljb25cIlxuICAgICAgICAgICAgICAgICAgaWNvbj1cImRvd25sb2FkXCJcbiAgICAgICAgICAgICAgICA+PC9zdHJlYW0taWNvbi1wbGFjZWhvbGRlcj5cbiAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgICA8c3BhblxuICAgICAgICAgICAgICAgICpuZ0lmPVwiaGFzRmlsZVNpemUoYXR0YWNobWVudENvbnRleHQpXCJcbiAgICAgICAgICAgICAgICBjbGFzcz1cInN0ci1jaGF0X19tZXNzYWdlLWF0dGFjaG1lbnQtZmlsZS0taXRlbS1zaXplXCJcbiAgICAgICAgICAgICAgICBkYXRhLXRlc3RjbGFzcz1cInNpemVcIlxuICAgICAgICAgICAgICAgID57eyBnZXRGaWxlU2l6ZShhdHRhY2htZW50Q29udGV4dCkgfX08L3NwYW5cbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpc1ZvaWNlTWVzc2FnZShhdHRhY2htZW50KVwiPlxuICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgKm5nVGVtcGxhdGVPdXRsZXQ9XCJcbiAgICAgICAgICAgIChjdXN0b21UZW1wbGF0ZXNTZXJ2aWNlLnZvaWNlUmVjb3JkaW5nQXR0YWNobWVudFRlbXBsYXRlJFxuICAgICAgICAgICAgICB8IGFzeW5jKSB8fCBkZWZhdWx0UmVjb3JkaW5nO1xuICAgICAgICAgICAgY29udGV4dDogZ2V0QXR0YWNobWVudENvbnRleHQoYXR0YWNobWVudClcbiAgICAgICAgICBcIlxuICAgICAgICA+PC9uZy1jb250YWluZXI+XG4gICAgICAgIDxuZy10ZW1wbGF0ZSAjZGVmYXVsdFJlY29yZGluZz5cbiAgICAgICAgICA8c3RyZWFtLXZvaWNlLXJlY29yZGluZ1xuICAgICAgICAgICAgZGF0YS10ZXN0Y2xhc3M9XCJ2b2ljZS1yZWNvcmRpbmdcIlxuICAgICAgICAgICAgW2F0dGFjaG1lbnRdPVwiYXR0YWNobWVudFwiXG4gICAgICAgICAgPjwvc3RyZWFtLXZvaWNlLXJlY29yZGluZz5cbiAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAqbmdJZj1cIlxuICAgICAgICAgIGlzQ2FyZChhdHRhY2htZW50KSAmJlxuICAgICAgICAgIGdldENhcmRBdHRhY2htZW50Q29uZmlndXJhdGlvbihhdHRhY2htZW50KSBhcyBhdHRhY2htZW50Q29uZmlndXJhdGlvblxuICAgICAgICBcIlxuICAgICAgPlxuICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgKm5nVGVtcGxhdGVPdXRsZXQ9XCJcbiAgICAgICAgICAgIChjdXN0b21UZW1wbGF0ZXNTZXJ2aWNlLmNhcmRBdHRhY2htZW50VGVtcGxhdGUkIHwgYXN5bmMpIHx8XG4gICAgICAgICAgICAgIGRlZmF1bHRDYXJkO1xuICAgICAgICAgICAgY29udGV4dDogZ2V0QXR0YWNobWVudENvbnRleHQoYXR0YWNobWVudClcbiAgICAgICAgICBcIlxuICAgICAgICA+PC9uZy1jb250YWluZXI+XG4gICAgICAgIDxuZy10ZW1wbGF0ZSAjZGVmYXVsdENhcmQgbGV0LWF0dGFjaG1lbnRDb250ZXh0PVwiYXR0YWNobWVudFwiPlxuICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgIGNsYXNzPVwic3RyLWNoYXRfX21lc3NhZ2UtYXR0YWNobWVudC1jYXJkIHN0ci1jaGF0X19tZXNzYWdlLWF0dGFjaG1lbnQtY2FyZC0te3tcbiAgICAgICAgICAgICAgYXR0YWNobWVudENvbnRleHQudHlwZVxuICAgICAgICAgICAgfX1cIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgKm5nSWY9XCJhdHRhY2htZW50Q29uZmlndXJhdGlvbi51cmxcIlxuICAgICAgICAgICAgICBjbGFzcz1cInN0ci1jaGF0X19tZXNzYWdlLWF0dGFjaG1lbnQtY2FyZC0taGVhZGVyXCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgPGltZ1xuICAgICAgICAgICAgICAgIGZldGNocHJpb3JpdHk9XCJsb3dcIlxuICAgICAgICAgICAgICAgIGxvYWRpbmc9XCJsYXp5XCJcbiAgICAgICAgICAgICAgICBkYXRhLXRlc3RjbGFzcz1cImNhcmQtaW1nXCJcbiAgICAgICAgICAgICAgICBhbHQ9XCJ7eyBhdHRhY2htZW50Q29uZmlndXJhdGlvbi51cmwgfX1cIlxuICAgICAgICAgICAgICAgIHNyYz1cInt7IGF0dGFjaG1lbnRDb25maWd1cmF0aW9uLnVybCB9fVwiXG4gICAgICAgICAgICAgICAgW25nU3R5bGVdPVwie1xuICAgICAgICAgICAgICAgICAgaGVpZ2h0OiBhdHRhY2htZW50Q29uZmlndXJhdGlvbi5oZWlnaHQsXG4gICAgICAgICAgICAgICAgICB3aWR0aDogYXR0YWNobWVudENvbmZpZ3VyYXRpb24ud2lkdGhcbiAgICAgICAgICAgICAgICB9XCJcbiAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN0ci1jaGF0X19tZXNzYWdlLWF0dGFjaG1lbnQtY2FyZC0tY29udGVudFwiPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3RyLWNoYXRfX21lc3NhZ2UtYXR0YWNobWVudC1jYXJkLS1mbGV4XCI+XG4gICAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgICAgKm5nSWY9XCJhdHRhY2htZW50Q29udGV4dC50aXRsZVwiXG4gICAgICAgICAgICAgICAgICBkYXRhLXRlc3RjbGFzcz1cImNhcmQtdGl0bGVcIlxuICAgICAgICAgICAgICAgICAgY2xhc3M9XCJzdHItY2hhdF9fbWVzc2FnZS1hdHRhY2htZW50LWNhcmQtLXRpdGxlXCJcbiAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICB7eyBhdHRhY2htZW50Q29udGV4dC50aXRsZSB9fVxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICAgICpuZ0lmPVwiYXR0YWNobWVudENvbnRleHQudGV4dFwiXG4gICAgICAgICAgICAgICAgICBjbGFzcz1cInN0ci1jaGF0X19tZXNzYWdlLWF0dGFjaG1lbnQtY2FyZC0tdGV4dFwiXG4gICAgICAgICAgICAgICAgICBkYXRhLXRlc3RjbGFzcz1cImNhcmQtdGV4dFwiXG4gICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAge3sgYXR0YWNobWVudENvbnRleHQudGV4dCB9fVxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxhXG4gICAgICAgICAgICAgICAgICAqbmdJZj1cIlxuICAgICAgICAgICAgICAgICAgICBhdHRhY2htZW50Q29udGV4dC50aXRsZV9saW5rIHx8XG4gICAgICAgICAgICAgICAgICAgIGF0dGFjaG1lbnRDb250ZXh0Lm9nX3NjcmFwZV91cmxcbiAgICAgICAgICAgICAgICAgIFwiXG4gICAgICAgICAgICAgICAgICBjbGFzcz1cInN0ci1jaGF0X19tZXNzYWdlLWF0dGFjaG1lbnQtY2FyZC0tdXJsXCJcbiAgICAgICAgICAgICAgICAgIGRhdGEtdGVzdGNsYXNzPVwidXJsLWxpbmtcIlxuICAgICAgICAgICAgICAgICAgbm9vcGVuZXJcbiAgICAgICAgICAgICAgICAgIG5vcmVmZXJyZXJcbiAgICAgICAgICAgICAgICAgIHRhcmdldD1cIl9ibGFua1wiXG4gICAgICAgICAgICAgICAgICBocmVmPVwie3tcbiAgICAgICAgICAgICAgICAgICAgYXR0YWNobWVudENvbnRleHQudGl0bGVfbGluayB8fFxuICAgICAgICAgICAgICAgICAgICAgIGF0dGFjaG1lbnRDb250ZXh0Lm9nX3NjcmFwZV91cmxcbiAgICAgICAgICAgICAgICAgIH19XCJcbiAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICB7e1xuICAgICAgICAgICAgICAgICAgICB0cmltVXJsKFxuICAgICAgICAgICAgICAgICAgICAgIGF0dGFjaG1lbnRDb250ZXh0LnRpdGxlX2xpbmsgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgIGF0dGFjaG1lbnRDb250ZXh0Lm9nX3NjcmFwZV91cmxcbiAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgfX1cbiAgICAgICAgICAgICAgICA8L2E+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJhdHRhY2htZW50LmFjdGlvbnMgJiYgYXR0YWNobWVudC5hY3Rpb25zLmxlbmd0aCA+IDBcIj5cbiAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICpuZ1RlbXBsYXRlT3V0bGV0PVwiXG4gICAgICAgICAgICAoY3VzdG9tVGVtcGxhdGVzU2VydmljZS5hdHRhY2htZW50QWN0aW9uc1RlbXBsYXRlJCB8IGFzeW5jKSB8fFxuICAgICAgICAgICAgICBkZWZhdWx0QWN0aW9ucztcbiAgICAgICAgICAgIGNvbnRleHQ6IGdldEF0dGFjaG1lbnRDb250ZXh0KGF0dGFjaG1lbnQpXG4gICAgICAgICAgXCJcbiAgICAgICAgPjwvbmctY29udGFpbmVyPlxuICAgICAgICA8bmctdGVtcGxhdGUgI2RlZmF1bHRBY3Rpb25zIGxldC1hdHRhY2htZW50Q29udGV4dD1cImF0dGFjaG1lbnRcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwic3RyLWNoYXRfX21lc3NhZ2UtYXR0YWNobWVudC1hY3Rpb25zXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3RyLWNoYXRfX21lc3NhZ2UtYXR0YWNobWVudC1hY3Rpb25zLWZvcm1cIj5cbiAgICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgICpuZ0Zvcj1cIlxuICAgICAgICAgICAgICAgICAgbGV0IGFjdGlvbiBvZiBhdHRhY2htZW50Q29udGV4dC5hY3Rpb25zO1xuICAgICAgICAgICAgICAgICAgdHJhY2tCeTogdHJhY2tCeUFjdGlvblZhbHVlXG4gICAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgICBkYXRhLXRlc3RjbGFzcz1cImF0dGFjaG1lbnQtYWN0aW9uXCJcbiAgICAgICAgICAgICAgICBjbGFzcz1cInN0ci1jaGF0X19tZXNzYWdlLWF0dGFjaG1lbnQtYWN0aW9ucy1idXR0b24gc3RyLWNoYXRfX21lc3NhZ2UtYXR0YWNobWVudC1hY3Rpb25zLWJ1dHRvbi0te3tcbiAgICAgICAgICAgICAgICAgIGFjdGlvbi5zdHlsZVxuICAgICAgICAgICAgICAgIH19XCJcbiAgICAgICAgICAgICAgICAoY2xpY2spPVwic2VuZEFjdGlvbihhY3Rpb24pXCJcbiAgICAgICAgICAgICAgICAoa2V5dXAuZW50ZXIpPVwic2VuZEFjdGlvbihhY3Rpb24pXCJcbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIHt7IGFjdGlvbi50ZXh0IH19XG4gICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICA8L2Rpdj5cbiAgPC9uZy1jb250YWluZXI+XG5cbiAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImltYWdlc1RvVmlldyAmJiBpbWFnZXNUb1ZpZXcubGVuZ3RoID4gMFwiPlxuICAgIDxuZy1jb250YWluZXJcbiAgICAgICpuZ1RlbXBsYXRlT3V0bGV0PVwiXG4gICAgICAgIChjdXN0b21UZW1wbGF0ZXNTZXJ2aWNlLm1vZGFsVGVtcGxhdGUkIHwgYXN5bmMpIHx8IGRlZmF1bHRNb2RhbDtcbiAgICAgICAgY29udGV4dDogZ2V0TW9kYWxDb250ZXh0KClcbiAgICAgIFwiXG4gICAgPjwvbmctY29udGFpbmVyPlxuICA8L25nLWNvbnRhaW5lcj5cbjwvZGl2PlxuXG48bmctdGVtcGxhdGVcbiAgI2RlZmF1bHRNb2RhbFxuICBsZXQtaXNPcGVuPVwiaXNPcGVuXCJcbiAgbGV0LWlzT3BlbkNoYW5nZUhhbmRsZXI9XCJpc09wZW5DaGFuZ2VIYW5kbGVyXCJcbiAgbGV0LWNvbnRlbnQ9XCJjb250ZW50XCJcbj5cbiAgPHN0cmVhbS1tb2RhbFxuICAgIGNsYXNzPVwic3RyZWFtLWNoYXQtYW5ndWxhcl9faW1hZ2UtbW9kYWwtaG9zdFwiXG4gICAgW2lzT3Blbl09XCJpc09wZW5cIlxuICAgIFtjb250ZW50XT1cImNvbnRlbnRcIlxuICAgIChpc09wZW5DaGFuZ2UpPVwiaXNPcGVuQ2hhbmdlSGFuZGxlcigkZXZlbnQpXCJcbiAgPlxuICA8L3N0cmVhbS1tb2RhbD5cbjwvbmctdGVtcGxhdGU+XG5cbjxuZy10ZW1wbGF0ZSAjbW9kYWxDb250ZW50PlxuICA8ZGl2IGNsYXNzPVwic3RyZWFtLWNoYXQtYW5ndWxhcl9faW1hZ2UtbW9kYWwgc3RyLWNoYXRfX2ltYWdlLWNhcm91c2VsXCI+XG4gICAgPGltZ1xuICAgICAgI2ltZ0VsZW1lbnRcbiAgICAgIGNsYXNzPVwiXG4gICAgICAgIHN0cmVhbS1jaGF0LWFuZ3VsYXJfX2ltYWdlLW1vZGFsLWltYWdlXG4gICAgICAgIHN0ci1jaGF0X19pbWFnZS1jYXJvdXNlbC1pbWFnZVxuICAgICAgXCJcbiAgICAgIGRhdGEtdGVzdGlkPVwibW9kYWwtaW1hZ2VcIlxuICAgICAgW3NyY109XCJcbiAgICAgICAgZ2V0Q2Fyb3VzZWxJbWFnZUF0dGFjaG1lbnRDb25maWd1cmF0aW9uKFxuICAgICAgICAgIGltYWdlc1RvVmlld1tpbWFnZXNUb1ZpZXdDdXJyZW50SW5kZXhdLFxuICAgICAgICAgIGltZ0VsZW1lbnRcbiAgICAgICAgKS51cmxcbiAgICAgIFwiXG4gICAgICBbc3R5bGUuLS1vcmlnaW5hbC1oZWlnaHRdPVwiXG4gICAgICAgIGdldENhcm91c2VsSW1hZ2VBdHRhY2htZW50Q29uZmlndXJhdGlvbihcbiAgICAgICAgICBpbWFnZXNUb1ZpZXdbaW1hZ2VzVG9WaWV3Q3VycmVudEluZGV4XSxcbiAgICAgICAgICBpbWdFbGVtZW50XG4gICAgICAgICkub3JpZ2luYWxIZWlnaHRcbiAgICAgIFwiXG4gICAgICBbc3R5bGUuLS1vcmlnaW5hbC13aWR0aF09XCJcbiAgICAgICAgZ2V0Q2Fyb3VzZWxJbWFnZUF0dGFjaG1lbnRDb25maWd1cmF0aW9uKFxuICAgICAgICAgIGltYWdlc1RvVmlld1tpbWFnZXNUb1ZpZXdDdXJyZW50SW5kZXhdLFxuICAgICAgICAgIGltZ0VsZW1lbnRcbiAgICAgICAgKS5vcmlnaW5hbFdpZHRoXG4gICAgICBcIlxuICAgICAgW2FsdF09XCJpbWFnZXNUb1ZpZXdbaW1hZ2VzVG9WaWV3Q3VycmVudEluZGV4XS5mYWxsYmFja1wiXG4gICAgICBbbmdTdHlsZV09XCJ7XG4gICAgICAgIHdpZHRoOiBnZXRDYXJvdXNlbEltYWdlQXR0YWNobWVudENvbmZpZ3VyYXRpb24oXG4gICAgICAgICAgaW1hZ2VzVG9WaWV3W2ltYWdlc1RvVmlld0N1cnJlbnRJbmRleF0sXG4gICAgICAgICAgaW1nRWxlbWVudFxuICAgICAgICApLndpZHRoLFxuICAgICAgICBoZWlnaHQ6IGdldENhcm91c2VsSW1hZ2VBdHRhY2htZW50Q29uZmlndXJhdGlvbihcbiAgICAgICAgICBpbWFnZXNUb1ZpZXdbaW1hZ2VzVG9WaWV3Q3VycmVudEluZGV4XSxcbiAgICAgICAgICBpbWdFbGVtZW50XG4gICAgICAgICkuaGVpZ2h0XG4gICAgICB9XCJcbiAgICAvPlxuICAgIDxkaXY+XG4gICAgICA8YnV0dG9uXG4gICAgICAgIGNsYXNzPVwiXG4gICAgICAgICAgc3RyZWFtLWNoYXQtYW5ndWxhcl9faW1hZ2UtbW9kYWwtc3RlcHBlclxuICAgICAgICAgIHN0ci1jaGF0X19pbWFnZS1jYXJvdXNlbC1zdGVwcGVyIHN0ci1jaGF0X19pbWFnZS1jYXJvdXNlbC1zdGVwcGVyLXByZXZcbiAgICAgICAgXCJcbiAgICAgICAgZGF0YS10ZXN0aWQ9XCJpbWFnZS1tb2RhbC1wcmV2XCJcbiAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgIFtuZ1N0eWxlXT1cIntcbiAgICAgICAgICB2aXNpYmlsaXR5OiBpc0ltYWdlTW9kYWxQcmV2QnV0dG9uVmlzaWJsZSA/ICd2aXNpYmxlJyA6ICdoaWRkZW4nXG4gICAgICAgIH1cIlxuICAgICAgICAoY2xpY2spPVwic3RlcEltYWdlcygtMSlcIlxuICAgICAgICAoa2V5dXAuZW50ZXIpPVwic3RlcEltYWdlcygtMSlcIlxuICAgICAgPlxuICAgICAgICA8c3RyZWFtLWljb24tcGxhY2Vob2xkZXIgaWNvbj1cImFycm93LWxlZnRcIj48L3N0cmVhbS1pY29uLXBsYWNlaG9sZGVyPlxuICAgICAgPC9idXR0b24+XG4gICAgICA8YnV0dG9uXG4gICAgICAgIGNsYXNzPVwiXG4gICAgICAgICAgc3RyZWFtLWNoYXQtYW5ndWxhcl9faW1hZ2UtbW9kYWwtc3RlcHBlclxuICAgICAgICAgIHN0ci1jaGF0X19pbWFnZS1jYXJvdXNlbC1zdGVwcGVyIHN0ci1jaGF0X19pbWFnZS1jYXJvdXNlbC1zdGVwcGVyLW5leHRcbiAgICAgICAgXCJcbiAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgIGRhdGEtdGVzdGlkPVwiaW1hZ2UtbW9kYWwtbmV4dFwiXG4gICAgICAgIFtuZ1N0eWxlXT1cIntcbiAgICAgICAgICB2aXNpYmlsaXR5OiBpc0ltYWdlTW9kYWxOZXh0QnV0dG9uVmlzaWJsZSA/ICd2aXNpYmxlJyA6ICdoaWRkZW4nXG4gICAgICAgIH1cIlxuICAgICAgICAoY2xpY2spPVwic3RlcEltYWdlcygxKVwiXG4gICAgICAgIChrZXl1cC5lbnRlcik9XCJzdGVwSW1hZ2VzKDEpXCJcbiAgICAgID5cbiAgICAgICAgPHN0cmVhbS1pY29uLXBsYWNlaG9sZGVyIGljb249XCJhcnJvdy1yaWdodFwiPjwvc3RyZWFtLWljb24tcGxhY2Vob2xkZXI+XG4gICAgICA8L2J1dHRvbj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L25nLXRlbXBsYXRlPlxuIl19
203
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXR0YWNobWVudC1saXN0LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3N0cmVhbS1jaGF0LWFuZ3VsYXIvc3JjL2xpYi9hdHRhY2htZW50LWxpc3QvYXR0YWNobWVudC1saXN0LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3N0cmVhbS1jaGF0LWFuZ3VsYXIvc3JjL2xpYi9hdHRhY2htZW50LWxpc3QvYXR0YWNobWVudC1saXN0LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxTQUFTLEVBQ1QsWUFBWSxFQUNaLFdBQVcsRUFDWCxLQUFLLEVBRUwsTUFBTSxFQUdOLFNBQVMsR0FDVixNQUFNLGVBQWUsQ0FBQztBQVV2QixPQUFPLFdBQVcsTUFBTSxjQUFjLENBQUM7QUFDdkMsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7Ozs7Ozs7Ozs7QUFLM0Q7O0dBRUc7QUFNSCxNQUFNLE9BQU8sdUJBQXVCO0lBZ0NsQyxZQUNrQixzQkFBOEMsRUFDdEQsY0FBOEIsRUFDOUIsOEJBQThEO1FBRnRELDJCQUFzQixHQUF0QixzQkFBc0IsQ0FBd0I7UUFDdEQsbUJBQWMsR0FBZCxjQUFjLENBQWdCO1FBQzlCLG1DQUE4QixHQUE5Qiw4QkFBOEIsQ0FBZ0M7UUExQnhFOztXQUVHO1FBQ00sZ0JBQVcsR0FBNEMsRUFBRSxDQUFDO1FBQ25FOztXQUVHO1FBQ2dCLDBCQUFxQixHQUFHLElBQUksWUFBWSxFQUV4RCxDQUFDO1FBQ1csVUFBSyxHQUFHLHdDQUF3QyxDQUFDO1FBQ2hFLHVCQUFrQixHQUE0QyxFQUFFLENBQUM7UUFDakUsaUJBQVksR0FBNEMsRUFBRSxDQUFDO1FBQzNELDZCQUF3QixHQUFHLENBQUMsQ0FBQztRQUdyQiw2QkFBd0IsR0FLNUIsSUFBSSxHQUFHLEVBQUUsQ0FBQztJQU1YLENBQUM7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LE9BQU8sSUFBSSxDQUFDLHdCQUF3QixLQUFLLENBQUMsQ0FBQztJQUM3QyxDQUFDO0lBRUQsSUFBSSw2QkFBNkI7UUFDL0IsT0FBTyxJQUFJLENBQUMsd0JBQXdCLEtBQUssSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO0lBQ3hFLENBQUM7SUFFTyxhQUFhLENBQUMsTUFBb0I7UUFDeEMsT0FBTztZQUNMO2dCQUNFLElBQUksRUFBRSxTQUFTO2dCQUNmLE1BQU07YUFDUDtTQUNGLENBQUM7SUFDSixDQUFDO0lBRU8sZUFBZTtRQUNyQixJQUFJLENBQUMscUJBQXFCLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQzFDLElBQUksQ0FBQyxZQUFZLEdBQUcsRUFBRSxDQUFDO0lBQ3pCLENBQUM7O29IQTlQVSx1QkFBdUI7d0dBQXZCLHVCQUF1QixpYUNsQ3BDLHNobEJBc2dCQTsyRkRwZWEsdUJBQXVCO2tCQUxuQyxTQUFTOytCQUNFLHdCQUF3Qjt1TEFRekIsU0FBUztzQkFBakIsS0FBSztnQkFJRyxlQUFlO3NCQUF2QixLQUFLO2dCQUlHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBSWEscUJBQXFCO3NCQUF2QyxNQUFNO2dCQUdRLEtBQUs7c0JBQW5CLFdBQVc7Z0JBS0osWUFBWTtzQkFEbkIsU0FBUzt1QkFBQyxjQUFjLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ29tcG9uZW50LFxuICBFdmVudEVtaXR0ZXIsXG4gIEhvc3RCaW5kaW5nLFxuICBJbnB1dCxcbiAgT25DaGFuZ2VzLFxuICBPdXRwdXQsXG4gIFNpbXBsZUNoYW5nZXMsXG4gIFRlbXBsYXRlUmVmLFxuICBWaWV3Q2hpbGQsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQWN0aW9uLCBBdHRhY2htZW50IH0gZnJvbSAnc3RyZWFtLWNoYXQnO1xuaW1wb3J0IHtcbiAgTW9kYWxDb250ZXh0LFxuICBEZWZhdWx0U3RyZWFtQ2hhdEdlbmVyaWNzLFxuICBBdHRhY2htZW50Q29uZmlncmF0aW9uLFxuICBWaWRlb0F0dGFjaG1lbnRDb25maWd1cmF0aW9uLFxuICBJbWFnZUF0dGFjaG1lbnRDb25maWd1cmF0aW9uLFxuICBBdHRhY2htZW50Q29udGV4dCxcbn0gZnJvbSAnLi4vdHlwZXMnO1xuaW1wb3J0IHByZXR0eWJ5dGVzIGZyb20gJ3ByZXR0eS1ieXRlcyc7XG5pbXBvcnQgeyBpc0ltYWdlQXR0YWNobWVudCB9IGZyb20gJy4uL2lzLWltYWdlLWF0dGFjaG1lbnQnO1xuaW1wb3J0IHsgQ2hhbm5lbFNlcnZpY2UgfSBmcm9tICcuLi9jaGFubmVsLnNlcnZpY2UnO1xuaW1wb3J0IHsgQ3VzdG9tVGVtcGxhdGVzU2VydmljZSB9IGZyb20gJy4uL2N1c3RvbS10ZW1wbGF0ZXMuc2VydmljZSc7XG5pbXBvcnQgeyBBdHRhY2htZW50Q29uZmlndXJhdGlvblNlcnZpY2UgfSBmcm9tICcuLi9hdHRhY2htZW50LWNvbmZpZ3VyYXRpb24uc2VydmljZSc7XG5cbi8qKlxuICogVGhlIGBBdHRhY2htZW50TGlzdGAgY29tcG9uZW50IGRpc3BsYXlzIHRoZSBhdHRhY2htZW50cyBvZiBhIG1lc3NhZ2VcbiAqL1xuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnc3RyZWFtLWF0dGFjaG1lbnQtbGlzdCcsXG4gIHRlbXBsYXRlVXJsOiAnLi9hdHRhY2htZW50LWxpc3QuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZXM6IFtdLFxufSlcbmV4cG9ydCBjbGFzcyBBdHRhY2htZW50TGlzdENvbXBvbmVudCBpbXBsZW1lbnRzIE9uQ2hhbmdlcyB7XG4gIC8qKlxuICAgKiBUaGUgaWQgb2YgdGhlIG1lc3NhZ2UgdGhlIGF0dGFjaG1lbnRzIGJlbG9uZyB0b1xuICAgKi9cbiAgQElucHV0KCkgbWVzc2FnZUlkOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gIC8qKlxuICAgKiBUaGUgcGFyZW50IGlkIG9mIHRoZSBtZXNzYWdlIHRoZSBhdHRhY2htZW50cyBiZWxvbmcgdG9cbiAgICovXG4gIEBJbnB1dCgpIHBhcmVudE1lc3NhZ2VJZDogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAvKipcbiAgICogVGhlIGF0dGFjaG1lbnRzIHRvIGRpc3BsYXlcbiAgICovXG4gIEBJbnB1dCgpIGF0dGFjaG1lbnRzOiBBdHRhY2htZW50PERlZmF1bHRTdHJlYW1DaGF0R2VuZXJpY3M+W10gPSBbXTtcbiAgLyoqXG4gICAqIEVtaXRzIHRoZSBzdGF0ZSBvZiB0aGUgaW1hZ2UgY2Fyb3VzZWwgd2luZG93XG4gICAqL1xuICBAT3V0cHV0KCkgcmVhZG9ubHkgaW1hZ2VNb2RhbFN0YXRlQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxcbiAgICAnb3BlbmVkJyB8ICdjbG9zZWQnXG4gID4oKTtcbiAgQEhvc3RCaW5kaW5nKCkgY2xhc3MgPSAnc3RyLWNoYXRfX2F0dGFjaG1lbnQtbGlzdC1hbmd1bGFyLWhvc3QnO1xuICBvcmRlcmVkQXR0YWNobWVudHM6IEF0dGFjaG1lbnQ8RGVmYXVsdFN0cmVhbUNoYXRHZW5lcmljcz5bXSA9IFtdO1xuICBpbWFnZXNUb1ZpZXc6IEF0dGFjaG1lbnQ8RGVmYXVsdFN0cmVhbUNoYXRHZW5lcmljcz5bXSA9IFtdO1xuICBpbWFnZXNUb1ZpZXdDdXJyZW50SW5kZXggPSAwO1xuICBAVmlld0NoaWxkKCdtb2RhbENvbnRlbnQnLCB7IHN0YXRpYzogdHJ1ZSB9KVxuICBwcml2YXRlIG1vZGFsQ29udGVudCE6IFRlbXBsYXRlUmVmPHZvaWQ+O1xuICBwcml2YXRlIGF0dGFjaG1lbnRDb25maWd1cmF0aW9uczogTWFwPFxuICAgIEF0dGFjaG1lbnQsXG4gICAgfCBBdHRhY2htZW50Q29uZmlncmF0aW9uXG4gICAgfCBWaWRlb0F0dGFjaG1lbnRDb25maWd1cmF0aW9uXG4gICAgfCBJbWFnZUF0dGFjaG1lbnRDb25maWd1cmF0aW9uXG4gID4gPSBuZXcgTWFwKCk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIHJlYWRvbmx5IGN1c3RvbVRlbXBsYXRlc1NlcnZpY2U6IEN1c3RvbVRlbXBsYXRlc1NlcnZpY2UsXG4gICAgcHJpdmF0ZSBjaGFubmVsU2VydmljZTogQ2hhbm5lbFNlcnZpY2UsXG4gICAgcHJpdmF0ZSBhdHRhY2htZW50Q29uZmlndXJhdGlvblNlcnZpY2U6IEF0dGFjaG1lbnRDb25maWd1cmF0aW9uU2VydmljZVxuICApIHt9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIGlmIChjaGFuZ2VzLmF0dGFjaG1lbnRzKSB7XG4gICAgICBjb25zdCBpbWFnZXMgPSB0aGlzLmF0dGFjaG1lbnRzLmZpbHRlcih0aGlzLmlzSW1hZ2UpO1xuICAgICAgY29uc3QgY29udGFpbnNHYWxsZXJ5ID0gaW1hZ2VzLmxlbmd0aCA+PSAyO1xuICAgICAgdGhpcy5vcmRlcmVkQXR0YWNobWVudHMgPSBbXG4gICAgICAgIC4uLihjb250YWluc0dhbGxlcnkgPyB0aGlzLmNyZWF0ZUdhbGxlcnkoaW1hZ2VzKSA6IGltYWdlcyksXG4gICAgICAgIC4uLnRoaXMuYXR0YWNobWVudHMuZmlsdGVyKChhKSA9PiB0aGlzLmlzVmlkZW8oYSkpLFxuICAgICAgICAuLi50aGlzLmF0dGFjaG1lbnRzLmZpbHRlcigoYSkgPT4gdGhpcy5pc1ZvaWNlTWVzc2FnZShhKSksXG4gICAgICAgIC4uLnRoaXMuYXR0YWNobWVudHMuZmlsdGVyKChhKSA9PiB0aGlzLmlzRmlsZShhKSksXG4gICAgICBdO1xuICAgICAgdGhpcy5hdHRhY2htZW50Q29uZmlndXJhdGlvbnMgPSBuZXcgTWFwKCk7XG4gICAgICAvLyBEaXNwbGF5IGxpbmsgYXR0YWNobWVudHMgb25seSBpZiB0aGVyZSBhcmUgbm8gb3RoZXIgYXR0YWNobWVudHNcbiAgICAgIC8vIEdpcGh5LXMgYWx3YXlzIHNlbnQgd2l0aG91dCBvdGhlciBhdHRhY2htZW50c1xuICAgICAgaWYgKHRoaXMub3JkZXJlZEF0dGFjaG1lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB0aGlzLm9yZGVyZWRBdHRhY2htZW50cy5wdXNoKFxuICAgICAgICAgIC4uLnRoaXMuYXR0YWNobWVudHMuZmlsdGVyKChhKSA9PiB0aGlzLmlzQ2FyZChhKSlcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICB0cmFja0J5VXJsKF86IG51bWJlciwgYXR0YWNobWVudDogQXR0YWNobWVudCkge1xuICAgIHJldHVybiAoXG4gICAgICBhdHRhY2htZW50LmltYWdlX3VybCB8fFxuICAgICAgYXR0YWNobWVudC5pbWdfdXJsIHx8XG4gICAgICBhdHRhY2htZW50LmFzc2V0X3VybCB8fFxuICAgICAgYXR0YWNobWVudC50aHVtYl91cmxcbiAgICApO1xuICB9XG5cbiAgaXNJbWFnZShhdHRhY2htZW50OiBBdHRhY2htZW50KSB7XG4gICAgcmV0dXJuIGlzSW1hZ2VBdHRhY2htZW50KGF0dGFjaG1lbnQpO1xuICB9XG5cbiAgaXNTdmcoYXR0YWNobWVudDogQXR0YWNobWVudCkge1xuICAgIGNvbnN0IGZpbGVuYW1lID0gYXR0YWNobWVudC5mYWxsYmFjayB8fCAnJztcbiAgICByZXR1cm4gISFmaWxlbmFtZS50b0xvd2VyQ2FzZSgpLmVuZHNXaXRoKCcuc3ZnJyk7XG4gIH1cblxuICBpc0ZpbGUoYXR0YWNobWVudDogQXR0YWNobWVudCkge1xuICAgIHJldHVybiBhdHRhY2htZW50LnR5cGUgPT09ICdmaWxlJztcbiAgfVxuXG4gIGlzR2FsbGVyeShhdHRhY2htZW50OiBBdHRhY2htZW50KSB7XG4gICAgcmV0dXJuIGF0dGFjaG1lbnQudHlwZSA9PT0gJ2dhbGxlcnknO1xuICB9XG5cbiAgaXNWaWRlbyhhdHRhY2htZW50OiBBdHRhY2htZW50KSB7XG4gICAgcmV0dXJuIChcbiAgICAgIGF0dGFjaG1lbnQudHlwZSA9PT0gJ3ZpZGVvJyAmJlxuICAgICAgYXR0YWNobWVudC5hc3NldF91cmwgJiZcbiAgICAgICFhdHRhY2htZW50Lm9nX3NjcmFwZV91cmwgLy8gbGlua3MgZnJvbSB2aWRlbyBzaGFyZSBzZXJ2aWNlcyAoc3VjaCBhcyBZb3VUdWJlIG9yIEZhY2Vib29rKSBhcmUgY2FuJ3QgYmUgcGxheWVkXG4gICAgKTtcbiAgfVxuXG4gIGlzQ2FyZChhdHRhY2htZW50OiBBdHRhY2htZW50KSB7XG4gICAgcmV0dXJuIChcbiAgICAgICFhdHRhY2htZW50LnR5cGUgfHxcbiAgICAgIChhdHRhY2htZW50LnR5cGUgPT09ICdpbWFnZScgJiYgIXRoaXMuaXNJbWFnZShhdHRhY2htZW50KSkgfHxcbiAgICAgIGF0dGFjaG1lbnQudHlwZSA9PT0gJ2dpcGh5J1xuICAgICk7XG4gIH1cblxuICBpc1ZvaWNlTWVzc2FnZShhdHRhY2htZW50OiBBdHRhY2htZW50KSB7XG4gICAgcmV0dXJuIGF0dGFjaG1lbnQudHlwZSA9PT0gJ3ZvaWNlUmVjb3JkaW5nJztcbiAgfVxuXG4gIGhhc0ZpbGVTaXplKGF0dGFjaG1lbnQ6IEF0dGFjaG1lbnQ8RGVmYXVsdFN0cmVhbUNoYXRHZW5lcmljcz4pIHtcbiAgICByZXR1cm4gKFxuICAgICAgYXR0YWNobWVudC5maWxlX3NpemUgJiYgTnVtYmVyLmlzRmluaXRlKE51bWJlcihhdHRhY2htZW50LmZpbGVfc2l6ZSkpXG4gICAgKTtcbiAgfVxuXG4gIGdldEZpbGVTaXplKGF0dGFjaG1lbnQ6IEF0dGFjaG1lbnQ8RGVmYXVsdFN0cmVhbUNoYXRHZW5lcmljcz4pIHtcbiAgICByZXR1cm4gcHJldHR5Ynl0ZXMoTnVtYmVyKGF0dGFjaG1lbnQuZmlsZV9zaXplISkpO1xuICB9XG5cbiAgZ2V0TW9kYWxDb250ZXh0KCk6IE1vZGFsQ29udGV4dCB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGlzT3BlbjogdGhpcy5pbWFnZXNUb1ZpZXcgJiYgdGhpcy5pbWFnZXNUb1ZpZXcubGVuZ3RoID4gMCxcbiAgICAgIGlzT3BlbkNoYW5nZUhhbmRsZXI6IChpc09wZW4pID0+IChpc09wZW4gPyBudWxsIDogdGhpcy5jbG9zZUltYWdlTW9kYWwoKSksXG4gICAgICBjb250ZW50OiB0aGlzLm1vZGFsQ29udGVudCxcbiAgICB9O1xuICB9XG5cbiAgdHJpbVVybCh1cmw/OiBzdHJpbmcgfCBudWxsKSB7XG4gICAgaWYgKHVybCAhPT0gdW5kZWZpbmVkICYmIHVybCAhPT0gbnVsbCkge1xuICAgICAgY29uc3QgW3RyaW1tZWRVcmxdID0gdXJsXG4gICAgICAgIC5yZXBsYWNlKC9eKD86aHR0cHM/OlxcL1xcLyk/KD86d3d3XFwuKT8vaSwgJycpXG4gICAgICAgIC5zcGxpdCgnLycpO1xuXG4gICAgICByZXR1cm4gdHJpbW1lZFVybDtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBzZW5kQWN0aW9uKGFjdGlvbjogQWN0aW9uKSB7XG4gICAgdm9pZCB0aGlzLmNoYW5uZWxTZXJ2aWNlLnNlbmRBY3Rpb24oXG4gICAgICB0aGlzLm1lc3NhZ2VJZCEsXG4gICAgICB7XG4gICAgICAgIFthY3Rpb24ubmFtZSFdOiBhY3Rpb24udmFsdWUhLFxuICAgICAgfSxcbiAgICAgIHRoaXMucGFyZW50TWVzc2FnZUlkXG4gICAgKTtcbiAgfVxuXG4gIHRyYWNrQnlBY3Rpb25WYWx1ZShfOiBudW1iZXIsIGl0ZW06IEFjdGlvbikge1xuICAgIHJldHVybiBpdGVtLnZhbHVlO1xuICB9XG5cbiAgb3BlbkltYWdlTW9kYWwoYXR0YWNobWVudHM6IEF0dGFjaG1lbnRbXSwgc2VsZWN0ZWRJbmRleCA9IDApIHtcbiAgICB0aGlzLmltYWdlTW9kYWxTdGF0ZUNoYW5nZS5uZXh0KCdvcGVuZWQnKTtcbiAgICB0aGlzLmltYWdlc1RvVmlldyA9IGF0dGFjaG1lbnRzO1xuICAgIHRoaXMuaW1hZ2VzVG9WaWV3Q3VycmVudEluZGV4ID0gc2VsZWN0ZWRJbmRleDtcbiAgfVxuXG4gIHN0ZXBJbWFnZXMoZGlyOiAtMSB8IDEpIHtcbiAgICB0aGlzLmltYWdlc1RvVmlld0N1cnJlbnRJbmRleCArPSBkaXIgKiAxO1xuICB9XG5cbiAgdHJhY2tCeUltYWdlVXJsKF86IG51bWJlciwgaXRlbTogQXR0YWNobWVudCkge1xuICAgIHJldHVybiBpdGVtLmltYWdlX3VybCB8fCBpdGVtLmltZ191cmwgfHwgaXRlbS50aHVtYl91cmw7XG4gIH1cblxuICBnZXRBdHRhY2htZW50Q29udGV4dChcbiAgICBhdHRhY2htZW50OiBBdHRhY2htZW50PERlZmF1bHRTdHJlYW1DaGF0R2VuZXJpY3M+XG4gICk6IEF0dGFjaG1lbnRDb250ZXh0IHtcbiAgICByZXR1cm4geyBhdHRhY2htZW50IH07XG4gIH1cblxuICBnZXRJbWFnZUF0dGFjaG1lbnRDb25maWd1cmF0aW9uKFxuICAgIGF0dGFjaG1lbnQ6IEF0dGFjaG1lbnQsXG4gICAgdHlwZTogJ2dhbGxlcnknIHwgJ3NpbmdsZScsXG4gICAgZWxlbWVudDogSFRNTEVsZW1lbnRcbiAgKTogSW1hZ2VBdHRhY2htZW50Q29uZmlndXJhdGlvbiB7XG4gICAgY29uc3QgZXhpc3RpbmdDb25maWd1cmF0aW9uID0gdGhpcy5hdHRhY2htZW50Q29uZmlndXJhdGlvbnMuZ2V0KGF0dGFjaG1lbnQpO1xuICAgIGlmIChleGlzdGluZ0NvbmZpZ3VyYXRpb24pIHtcbiAgICAgIHJldHVybiBleGlzdGluZ0NvbmZpZ3VyYXRpb24gYXMgSW1hZ2VBdHRhY2htZW50Q29uZmlndXJhdGlvbjtcbiAgICB9XG4gICAgY29uc3QgY29uZmlndXJhdGlvbiA9XG4gICAgICB0aGlzLmF0dGFjaG1lbnRDb25maWd1cmF0aW9uU2VydmljZS5nZXRJbWFnZUF0dGFjaG1lbnRDb25maWd1cmF0aW9uKFxuICAgICAgICBhdHRhY2htZW50LFxuICAgICAgICB0eXBlLFxuICAgICAgICBlbGVtZW50XG4gICAgICApO1xuICAgIHRoaXMuYXR0YWNobWVudENvbmZpZ3VyYXRpb25zLnNldChhdHRhY2htZW50LCBjb25maWd1cmF0aW9uKTtcbiAgICByZXR1cm4gY29uZmlndXJhdGlvbjtcbiAgfVxuXG4gIGdldENhcm91c2VsSW1hZ2VBdHRhY2htZW50Q29uZmlndXJhdGlvbihcbiAgICBhdHRhY2htZW50OiBBdHRhY2htZW50LFxuICAgIGVsZW1lbnQ6IEhUTUxFbGVtZW50XG4gICkge1xuICAgIHJldHVybiB0aGlzLmF0dGFjaG1lbnRDb25maWd1cmF0aW9uU2VydmljZS5nZXRJbWFnZUF0dGFjaG1lbnRDb25maWd1cmF0aW9uKFxuICAgICAgYXR0YWNobWVudCxcbiAgICAgICdjYXJvdXNlbCcsXG4gICAgICBlbGVtZW50XG4gICAgKTtcbiAgfVxuXG4gIGdldFZpZGVvQXR0YWNobWVudENvbmZpZ3VyYXRpb24oXG4gICAgYXR0YWNobWVudDogQXR0YWNobWVudCxcbiAgICBlbGVtZW50OiBIVE1MRWxlbWVudFxuICApOiBWaWRlb0F0dGFjaG1lbnRDb25maWd1cmF0aW9uIHtcbiAgICBjb25zdCBleGlzdGluZ0NvbmZpZ3VyYXRpb24gPSB0aGlzLmF0dGFjaG1lbnRDb25maWd1cmF0aW9ucy5nZXQoYXR0YWNobWVudCk7XG4gICAgaWYgKGV4aXN0aW5nQ29uZmlndXJhdGlvbikge1xuICAgICAgcmV0dXJuIGV4aXN0aW5nQ29uZmlndXJhdGlvbiBhcyBWaWRlb0F0dGFjaG1lbnRDb25maWd1cmF0aW9uO1xuICAgIH1cbiAgICBjb25zdCBjb25maWd1cmF0aW9uID1cbiAgICAgIHRoaXMuYXR0YWNobWVudENvbmZpZ3VyYXRpb25TZXJ2aWNlLmdldFZpZGVvQXR0YWNobWVudENvbmZpZ3VyYXRpb24oXG4gICAgICAgIGF0dGFjaG1lbnQsXG4gICAgICAgIGVsZW1lbnRcbiAgICAgICk7XG4gICAgdGhpcy5hdHRhY2htZW50Q29uZmlndXJhdGlvbnMuc2V0KGF0dGFjaG1lbnQsIGNvbmZpZ3VyYXRpb24pO1xuICAgIHJldHVybiBjb25maWd1cmF0aW9uO1xuICB9XG5cbiAgZ2V0Q2FyZEF0dGFjaG1lbnRDb25maWd1cmF0aW9uKGF0dGFjaG1lbnQ6IEF0dGFjaG1lbnQpIHtcbiAgICBjb25zdCBleGlzdGluZ0NvbmZpZ3VyYXRpb24gPSB0aGlzLmF0dGFjaG1lbnRDb25maWd1cmF0aW9ucy5nZXQoYXR0YWNobWVudCk7XG4gICAgaWYgKGV4aXN0aW5nQ29uZmlndXJhdGlvbikge1xuICAgICAgcmV0dXJuIGV4aXN0aW5nQ29uZmlndXJhdGlvbjtcbiAgICB9XG4gICAgaWYgKGF0dGFjaG1lbnQudHlwZSA9PT0gJ2dpcGh5Jykge1xuICAgICAgcmV0dXJuIHRoaXMuYXR0YWNobWVudENvbmZpZ3VyYXRpb25TZXJ2aWNlLmdldEdpcGh5QXR0YWNobWVudENvbmZpZ3VyYXRpb24oXG4gICAgICAgIGF0dGFjaG1lbnRcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGNvbmZpZ3VyYXRpb24gPVxuICAgICAgICB0aGlzLmF0dGFjaG1lbnRDb25maWd1cmF0aW9uU2VydmljZS5nZXRTY3JhcGVkSW1hZ2VBdHRhY2htZW50Q29uZmlndXJhdGlvbihcbiAgICAgICAgICBhdHRhY2htZW50XG4gICAgICAgICk7XG4gICAgICB0aGlzLmF0dGFjaG1lbnRDb25maWd1cmF0aW9ucy5zZXQoYXR0YWNobWVudCwgY29uZmlndXJhdGlvbik7XG4gICAgICByZXR1cm4gY29uZmlndXJhdGlvbjtcbiAgICB9XG4gIH1cblxuICBnZXQgaXNJbWFnZU1vZGFsUHJldkJ1dHRvblZpc2libGUoKSB7XG4gICAgcmV0dXJuIHRoaXMuaW1hZ2VzVG9WaWV3Q3VycmVudEluZGV4ICE9PSAwO1xuICB9XG5cbiAgZ2V0IGlzSW1hZ2VNb2RhbE5leHRCdXR0b25WaXNpYmxlKCkge1xuICAgIHJldHVybiB0aGlzLmltYWdlc1RvVmlld0N1cnJlbnRJbmRleCAhPT0gdGhpcy5pbWFnZXNUb1ZpZXcubGVuZ3RoIC0gMTtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlR2FsbGVyeShpbWFnZXM6IEF0dGFjaG1lbnRbXSkge1xuICAgIHJldHVybiBbXG4gICAgICB7XG4gICAgICAgIHR5cGU6ICdnYWxsZXJ5JyxcbiAgICAgICAgaW1hZ2VzLFxuICAgICAgfSxcbiAgICBdO1xuICB9XG5cbiAgcHJpdmF0ZSBjbG9zZUltYWdlTW9kYWwoKSB7XG4gICAgdGhpcy5pbWFnZU1vZGFsU3RhdGVDaGFuZ2UubmV4dCgnY2xvc2VkJyk7XG4gICAgdGhpcy5pbWFnZXNUb1ZpZXcgPSBbXTtcbiAgfVxufVxuIiwiPGRpdiAqbmdJZj1cIm9yZGVyZWRBdHRhY2htZW50cy5sZW5ndGggPiAwXCIgY2xhc3M9XCJzdHItY2hhdF9fYXR0YWNobWVudC1saXN0XCI+XG4gIDxuZy1jb250YWluZXJcbiAgICAqbmdGb3I9XCJsZXQgYXR0YWNobWVudCBvZiBvcmRlcmVkQXR0YWNobWVudHM7IHRyYWNrQnk6IHRyYWNrQnlVcmxcIlxuICA+XG4gICAgPGRpdlxuICAgICAgZGF0YS10ZXN0Y2xhc3M9XCJhdHRhY2htZW50LWNvbnRhaW5lclwiXG4gICAgICBjbGFzcz1cInN0ci1jaGF0X19tZXNzYWdlLWF0dGFjaG1lbnQgc3RyLWNoYXRfX21lc3NhZ2UtYXR0YWNobWVudC0te3tcbiAgICAgICAgYXR0YWNobWVudC50eXBlXG4gICAgICB9fSBzdHItY2hhdF9fbWVzc2FnZS1hdHRhY2htZW50LWR5bmFtaWMtc2l6ZVwiXG4gICAgICBbY2xhc3Muc3RyLWNoYXRfX21lc3NhZ2UtYXR0YWNobWVudC0tY2FyZF09XCJpc0NhcmQoYXR0YWNobWVudClcIlxuICAgICAgW2NsYXNzLnN0ci1jaGF0LWFuZ3VsYXJfX21lc3NhZ2UtYXR0YWNobWVudC1maWxlLXNpbmdsZV09XCJcbiAgICAgICAgaXNGaWxlKGF0dGFjaG1lbnQpXG4gICAgICBcIlxuICAgICAgW2NsYXNzLnN0ci1jaGF0X19tZXNzYWdlLWF0dGFjaG1lbnQtLXZvaWNlLXJlY29yZGluZ109XCJcbiAgICAgICAgaXNWb2ljZU1lc3NhZ2UoYXR0YWNobWVudClcbiAgICAgIFwiXG4gICAgICBbY2xhc3Muc3RyLWNoYXRfX21lc3NhZ2UtYXR0YWNobWVudC13aXRoLWFjdGlvbnNdPVwiXG4gICAgICAgIGF0dGFjaG1lbnQuYWN0aW9ucyAmJiBhdHRhY2htZW50LmFjdGlvbnMubGVuZ3RoID4gMFxuICAgICAgXCJcbiAgICAgIFtjbGFzcy5zdHItY2hhdF9fbWVzc2FnZS1hdHRhY2htZW50LS1zdmctaW1hZ2VdPVwiaXNTdmcoYXR0YWNobWVudClcIlxuICAgID5cbiAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpc0ltYWdlKGF0dGFjaG1lbnQpXCI+XG4gICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAqbmdUZW1wbGF0ZU91dGxldD1cIlxuICAgICAgICAgICAgKGN1c3RvbVRlbXBsYXRlc1NlcnZpY2UuaW1hZ2VBdHRhY2htZW50VGVtcGxhdGUkIHwgYXN5bmMpIHx8XG4gICAgICAgICAgICAgIGRlZmF1bHRJbWFnZTtcbiAgICAgICAgICAgIGNvbnRleHQ6IGdldEF0dGFjaG1lbnRDb250ZXh0KGF0dGFjaG1lbnQpXG4gICAgICAgICAgXCJcbiAgICAgICAgPjwvbmctY29udGFpbmVyPlxuICAgICAgICA8bmctdGVtcGxhdGUgI2RlZmF1bHRJbWFnZSBsZXQtYXR0YWNobWVudENvbnRleHQ9XCJhdHRhY2htZW50XCI+XG4gICAgICAgICAgPGltZ1xuICAgICAgICAgICAgI2ltZ0VsZW1lbnRcbiAgICAgICAgICAgIGNsYXNzPVwic3RyLWNoYXRfX21lc3NhZ2UtYXR0YWNobWVudC0taW1nXCJcbiAgICAgICAgICAgIGRhdGEtdGVzdGNsYXNzPVwiaW1hZ2VcIlxuICAgICAgICAgICAgW3NyY109XCJcbiAgICAgICAgICAgICAgZ2V0SW1hZ2VBdHRhY2htZW50Q29uZmlndXJhdGlvbihcbiAgICAgICAgICAgICAgICBhdHRhY2htZW50Q29udGV4dCxcbiAgICAgICAgICAgICAgICAnc2luZ2xlJyxcbiAgICAgICAgICAgICAgICBpbWdFbGVtZW50XG4gICAgICAgICAgICAgICkudXJsXG4gICAgICAgICAgICBcIlxuICAgICAgICAgICAgW2FsdF09XCJhdHRhY2htZW50Q29udGV4dD8uZmFsbGJhY2tcIlxuICAgICAgICAgICAgW25nU3R5bGVdPVwie1xuICAgICAgICAgICAgICBoZWlnaHQ6IGdldEltYWdlQXR0YWNobWVudENvbmZpZ3VyYXRpb24oXG4gICAgICAgICAgICAgICAgYXR0YWNobWVudENvbnRleHQsXG4gICAgICAgICAgICAgICAgJ3NpbmdsZScsXG4gICAgICAgICAgICAgICAgaW1nRWxlbWVudFxuICAgICAgICAgICAgICApLmhlaWdodCxcbiAgICAgICAgICAgICAgd2lkdGg6IGdldEltYWdlQXR0YWNobWVudENvbmZpZ3VyYXRpb24oXG4gICAgICAgICAgICAgICAgYXR0YWNobWVudENvbnRleHQsXG4gICAgICAgICAgICAgICAgJ3NpbmdsZScsXG4gICAgICAgICAgICAgICAgaW1nRWxlbWVudFxuICAgICAgICAgICAgICApLndpZHRoLFxuICAgICAgICAgICAgICAnLS1vcmlnaW5hbC1oZWlnaHQnOiBnZXRJbWFnZUF0dGFjaG1lbnRDb25maWd1cmF0aW9uKFxuICAgICAgICAgICAgICAgIGF0dGFjaG1lbnRDb250ZXh0LFxuICAgICAgICAgICAgICAgICdzaW5nbGUnLFxuICAgICAgICAgICAgICAgIGltZ0VsZW1lbnRcbiAgICAgICAgICAgICAgKS5vcmlnaW5hbEhlaWdodCxcbiAgICAgICAgICAgICAgJy0tb3JpZ2luYWwtd2lkdGgnOiBnZXRJbWFnZUF0dGFjaG1lbnRDb25maWd1cmF0aW9uKFxuICAgICAgICAgICAgICAgIGF0dGFjaG1lbnRDb250ZXh0LFxuICAgICAgICAgICAgICAgICdzaW5nbGUnLFxuICAgICAgICAgICAgICAgIGltZ0VsZW1lbnRcbiAgICAgICAgICAgICAgKS5vcmlnaW5hbFdpZHRoXG4gICAgICAgICAgICB9XCJcbiAgICAgICAgICAgIChjbGljayk9XCJvcGVuSW1hZ2VNb2RhbChbYXR0YWNobWVudENvbnRleHRdKVwiXG4gICAgICAgICAgICAoa2V5dXAuZW50ZXIpPVwib3BlbkltYWdlTW9kYWwoW2F0dGFjaG1lbnRDb250ZXh0XSlcIlxuICAgICAgICAgIC8+XG4gICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpc0dhbGxlcnkoYXR0YWNobWVudClcIj5cbiAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICpuZ1RlbXBsYXRlT3V0bGV0PVwiXG4gICAgICAgICAgICAoY3VzdG9tVGVtcGxhdGVzU2VydmljZS5nYWxsZXJ5QXR0YWNobWVudFRlbXBsYXRlJCB8IGFzeW5jKSB8fFxuICAgICAgICAgICAgICBkZWZhdWx0R2FsbGVyeTtcbiAgICAgICAgICAgIGNvbnRleHQ6IGdldEF0dGFjaG1lbnRDb250ZXh0KGF0dGFjaG1lbnQpXG4gICAgICAgICAgXCJcbiAgICAgICAgPjwvbmctY29udGFpbmVyPlxuICAgICAgICA8bmctdGVtcGxhdGUgI2RlZmF1bHRHYWxsZXJ5IGxldC1hdHRhY2htZW50Q29udGV4dD1cImF0dGFjaG1lbnRcIj5cbiAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICBjbGFzcz1cInN0ci1jaGF0X19nYWxsZXJ5XCJcbiAgICAgICAgICAgIGRhdGEtdGVzdGlkPVwiaW1hZ2UtZ2FsbGVyeVwiXG4gICAgICAgICAgICBbY2xhc3Muc3RyLWNoYXRfX2dhbGxlcnktLXNxdWFyZV09XCJcbiAgICAgICAgICAgICAgKGF0dGFjaG1lbnRDb250ZXh0Py5pbWFnZXMpIS5sZW5ndGggPiAzXG4gICAgICAgICAgICBcIlxuICAgICAgICAgICAgW2NsYXNzLnN0ci1jaGF0X19nYWxsZXJ5LXR3by1yb3dzXT1cIlxuICAgICAgICAgICAgICAoYXR0YWNobWVudENvbnRleHQ/LmltYWdlcykhLmxlbmd0aCA+IDJcbiAgICAgICAgICAgIFwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICAgICAqbmdGb3I9XCJcbiAgICAgICAgICAgICAgICBsZXQgZ2FsbGVyeUltYWdlIG9mIGF0dGFjaG1lbnRDb250ZXh0LmltYWdlcztcbiAgICAgICAgICAgICAgICBsZXQgaW5kZXggPSBpbmRleDtcbiAgICAgICAgICAgICAgICBsZXQgaXNMYXN0ID0gbGFzdDtcbiAgICAgICAgICAgICAgICB0cmFja0J5OiB0cmFja0J5SW1hZ2VVcmxcbiAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgICpuZ0lmPVwiaW5kZXggPCAzIHx8IChpbmRleCA9PT0gMyAmJiBpc0xhc3QpXCJcbiAgICAgICAgICAgICAgICBjbGFzcz1cInN0ci1jaGF0X19nYWxsZXJ5LWltYWdlXCJcbiAgICAgICAgICAgICAgICBkYXRhLXRlc3RjbGFzcz1cImdhbGxlcnktaW1hZ2VcIlxuICAgICAgICAgICAgICAgIFtjbGFzcy5zdHItY2hhdF9fbWVzc2FnZS1hdHRhY2htZW50LS1zdmctaW1hZ2VdPVwiXG4gICAgICAgICAgICAgICAgICBpc1N2ZyhnYWxsZXJ5SW1hZ2UpXG4gICAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgICAoY2xpY2spPVwib3BlbkltYWdlTW9kYWwoYXR0YWNobWVudENvbnRleHQuaW1hZ2VzISwgaW5kZXgpXCJcbiAgICAgICAgICAgICAgICAoa2V5dXAuZW50ZXIpPVwib3BlbkltYWdlTW9kYWwoYXR0YWNobWVudENvbnRleHQuaW1hZ2VzISwgaW5kZXgpXCJcbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIDxpbWdcbiAgICAgICAgICAgICAgICAgICNpbWdFbGVtZW50XG4gICAgICAgICAgICAgICAgICBmZXRjaHByaW9yaXR5PVwibG93XCJcbiAgICAgICAgICAgICAgICAgIGxvYWRpbmc9XCJsYXp5XCJcbiAgICAgICAgICAgICAgICAgIFtzcmNdPVwiXG4gICAgICAgICAgICAgICAgICAgIGdldEltYWdlQXR0YWNobWVudENvbmZpZ3VyYXRpb24oXG4gICAgICAgICAgICAgICAgICAgICAgZ2FsbGVyeUltYWdlLFxuICAgICAgICAgICAgICAgICAgICAgICdnYWxsZXJ5JyxcbiAgICAgICAgICAgICAgICAgICAgICBpbWdFbGVtZW50XG4gICAgICAgICAgICAgICAgICAgICkudXJsXG4gICAgICAgICAgICAgICAgICBcIlxuICAgICAgICAgICAgICAgICAgW2FsdF09XCJnYWxsZXJ5SW1hZ2UuZmFsbGJhY2tcIlxuICAgICAgICAgICAgICAgICAgW3N0eWxlLi0tb3JpZ2luYWwtaGVpZ2h0XT1cIlxuICAgICAgICAgICAgICAgICAgICBnZXRJbWFnZUF0dGFjaG1lbnRDb25maWd1cmF0aW9uKFxuICAgICAgICAgICAgICAgICAgICAgIGdhbGxlcnlJbWFnZSxcbiAgICAgICAgICAgICAgICAgICAgICAnZ2FsbGVyeScsXG4gICAgICAgICAgICAgICAgICAgICAgaW1nRWxlbWVudFxuICAgICAgICAgICAgICAgICAgICApLm9yaWdpbmFsSGVpZ2h0XG4gICAgICAgICAgICAgICAgICBcIlxuICAgICAgICAgICAgICAgICAgW3N0eWxlLi0tb3JpZ2luYWwtd2lkdGhdPVwiXG4gICAgICAgICAgICAgICAgICAgIGdldEltYWdlQXR0YWNobWVudENvbmZpZ3VyYXRpb24oXG4gICAgICAgICAgICAgICAgICAgICAgZ2FsbGVyeUltYWdlLFxuICAgICAgICAgICAgICAgICAgICAgICdnYWxsZXJ5JyxcbiAgICAgICAgICAgICAgICAgICAgICBpbWdFbGVtZW50XG4gICAgICAgICAgICAgICAgICAgICkub3JpZ2luYWxXaWR0aFxuICAgICAgICAgICAgICAgICAgXCJcbiAgICAgICAgICAgICAgICAgIFtuZ1N0eWxlXT1cIntcbiAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiBnZXRJbWFnZUF0dGFjaG1lbnRDb25maWd1cmF0aW9uKFxuICAgICAgICAgICAgICAgICAgICAgIGdhbGxlcnlJbWFnZSxcbiAgICAgICAgICAgICAgICAgICAgICAnZ2FsbGVyeScsXG4gICAgICAgICAgICAgICAgICAgICAgaW1nRWxlbWVudFxuICAgICAgICAgICAgICAgICAgICApLmhlaWdodCxcbiAgICAgICAgICAgICAgICAgICAgd2lkdGg6IGdldEltYWdlQXR0YWNobWVudENvbmZpZ3VyYXRpb24oXG4gICAgICAgICAgICAgICAgICAgICAgZ2FsbGVyeUltYWdlLFxuICAgICAgICAgICAgICAgICAgICAgICdnYWxsZXJ5JyxcbiAgICAgICAgICAgICAgICAgICAgICBpbWdFbGVtZW50XG4gICAgICAgICAgICAgICAgICAgICkud2lkdGhcbiAgICAgICAgICAgICAgICAgIH1cIlxuICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgKm5nSWY9XCJpbmRleCA9PT0gMyAmJiAhaXNMYXN0XCJcbiAgICAgICAgICAgICAgICAjZWxlbWVudFxuICAgICAgICAgICAgICAgIGNsYXNzPVwic3RyLWNoYXRfX2dhbGxlcnktcGxhY2Vob2xkZXJcIlxuICAgICAgICAgICAgICAgIGRhdGEtdGVzdGNsYXNzPVwiZ2FsbGVyeS1pbWFnZVwiXG4gICAgICAgICAgICAgICAgZGF0YS10ZXN0aWQ9XCJtb3JlLWltYWdlLWJ1dHRvblwiXG4gICAgICAgICAgICAgICAgW2NsYXNzLnN0ci1jaGF0X19tZXNzYWdlLWF0dGFjaG1lbnQtLXN2Zy1pbWFnZV09XCJcbiAgICAgICAgICAgICAgICAgIGlzU3ZnKGdhbGxlcnlJbWFnZSlcbiAgICAgICAgICAgICAgICBcIlxuICAgICAgICAgICAgICAgIFtuZ1N0eWxlXT1cIntcbiAgICAgICAgICAgICAgICAgICdiYWNrZ3JvdW5kLWltYWdlJzpcbiAgICAgICAgICAgICAgICAgICAgJ3VybCgnICtcbiAgICAgICAgICAgICAgICAgICAgZ2V0SW1hZ2VBdHRhY2htZW50Q29uZmlndXJhdGlvbihcbiAgICAgICAgICAgICAgICAgICAgICBnYWxsZXJ5SW1hZ2UsXG4gICAgICAgICAgICAgICAgICAgICAgJ2dhbGxlcnknLFxuICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnRcbiAgICAgICAgICAgICAgICAgICAgKS51cmwgK1xuICAgICAgICAgICAgICAgICAgICAnKScsXG4gICAgICAgICAgICAgICAgICBoZWlnaHQ6IGdldEltYWdlQXR0YWNobWVudENvbmZpZ3VyYXRpb24oXG4gICAgICAgICAgICAgICAgICAgIGdhbGxlcnlJbWFnZSxcbiAgICAgICAgICAgICAgICAgICAgJ2dhbGxlcnknLFxuICAgICAgICAgICAgICAgICAgICBlbGVtZW50XG4gICAgICAgICAgICAgICAgICApLmhlaWdodCxcbiAgICAgICAgICAgICAgICAgIHdpZHRoOiBnZXRJbWFnZUF0dGFjaG1lbnRDb25maWd1cmF0aW9uKFxuICAgICAgICAgICAgICAgICAgICBnYWxsZXJ5SW1hZ2UsXG4gICAgICAgICAgICAgICAgICAgICdnYWxsZXJ5JyxcbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudFxuICAgICAgICAgICAgICAgICAgKS53aWR0aCxcbiAgICAgICAgICAgICAgICAgICctLW9yaWdpbmFsLWhlaWdodCc6IGdldEltYWdlQXR0YWNobWVudENvbmZpZ3VyYXRpb24oXG4gICAgICAgICAgICAgICAgICAgIGdhbGxlcnlJbWFnZSxcbiAgICAgICAgICAgICAgICAgICAgJ2dhbGxlcnknLFxuICAgICAgICAgICAgICAgICAgICBlbGVtZW50XG4gICAgICAgICAgICAgICAgICApLm9yaWdpbmFsSGVpZ2h0LFxuICAgICAgICAgICAgICAgICAgJy0tb3JpZ2luYWwtd2lkdGgnOiBnZXRJbWFnZUF0dGFjaG1lbnRDb25maWd1cmF0aW9uKFxuICAgICAgICAgICAgICAgICAgICBnYWxsZXJ5SW1hZ2UsXG4gICAgICAgICAgICAgICAgICAgICdnYWxsZXJ5JyxcbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudFxuICAgICAgICAgICAgICAgICAgKS5vcmlnaW5hbFdpZHRoXG4gICAgICAgICAgICAgICAgfVwiXG4gICAgICAgICAgICAgICAgKGNsaWNrKT1cIm9wZW5JbWFnZU1vZGFsKGF0dGFjaG1lbnRDb250ZXh0LmltYWdlcyEsIGluZGV4KVwiXG4gICAgICAgICAgICAgICAgKGtleXVwLmVudGVyKT1cIm9wZW5JbWFnZU1vZGFsKGF0dGFjaG1lbnRDb250ZXh0LmltYWdlcyEsIGluZGV4KVwiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICA8cFxuICAgICAgICAgICAgICAgICAgW2lubmVySFRNTF09XCJcbiAgICAgICAgICAgICAgICAgICAgJ3N0cmVhbUNoYXQue3sgaW1hZ2VDb3VudCB9fSBtb3JlJ1xuICAgICAgICAgICAgICAgICAgICAgIHwgdHJhbnNsYXRlXG4gICAgICAgICAgICAgICAgICAgICAgICA6IHsgaW1hZ2VDb3VudDogYXR0YWNobWVudENvbnRleHQhLmltYWdlcyEubGVuZ3RoIC0gNCB9XG4gICAgICAgICAgICAgICAgICBcIlxuICAgICAgICAgICAgICAgID48L3A+XG4gICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpc1ZpZGVvKGF0dGFjaG1lbnQpXCI+XG4gICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAqbmdUZW1wbGF0ZU91dGxldD1cIlxuICAgICAgICAgICAgKGN1c3RvbVRlbXBsYXRlc1NlcnZpY2UudmlkZW9BdHRhY2htZW50VGVtcGxhdGUkIHwgYXN5bmMpIHx8XG4gICAgICAgICAgICAgIGRlZmF1bHRWaWRlbztcbiAgICAgICAgICAgIGNvbnRleHQ6IGdldEF0dGFjaG1lbnRDb250ZXh0KGF0dGFjaG1lbnQpXG4gICAgICAgICAgXCJcbiAgICAgICAgPjwvbmctY29udGFpbmVyPlxuICAgICAgICA8bmctdGVtcGxhdGUgI2RlZmF1bHRWaWRlbyBsZXQtYXR0YWNobWVudENvbnRleHQ9XCJhdHRhY2htZW50XCI+XG4gICAgICAgICAgPGRpdlxuICAgICAgICAgICAgY2xhc3M9XCJzdHItY2hhdF9fcGxheWVyLXdyYXBwZXJcIlxuICAgICAgICAgICAgZGF0YS10ZXN0Y2xhc3M9XCJ2aWRlby1hdHRhY2htZW50LXBhcmVudFwiXG4gICAgICAgICAgICBbc3R5bGUuLS1vcmlnaW5hbC1oZWlnaHRdPVwiXG4gICAgICAgICAgICAgIGdldFZpZGVvQXR0YWNobWVudENvbmZpZ3VyYXRpb24oYXR0YWNobWVudENvbnRleHQsIHZpZGVvRWxlbWVudClcbiAgICAgICAgICAgICAgICAub3JpZ2luYWxIZWlnaHRcbiAgICAgICAgICAgIFwiXG4gICAgICAgICAgICBbc3R5bGUuLS1vcmlnaW5hbC13aWR0aF09XCJcbiAgICAgICAgICAgICAgZ2V0VmlkZW9BdHRhY2htZW50Q29uZmlndXJhdGlvbihhdHRhY2htZW50Q29udGV4dCwgdmlkZW9FbGVtZW50KVxuICAgICAgICAgICAgICAgIC5vcmlnaW5hbFdpZHRoXG4gICAgICAgICAgICBcIlxuICAgICAgICAgICAgW25nU3R5bGVdPVwie1xuICAgICAgICAgICAgICBoZWlnaHQ6IGdldFZpZGVvQXR0YWNobWVudENvbmZpZ3VyYXRpb24oXG4gICAgICAgICAgICAgICAgYXR0YWNobWVudENvbnRleHQsXG4gICAgICAgICAgICAgICAgdmlkZW9FbGVtZW50XG4gICAgICAgICAgICAgICkuaGVpZ2h0LFxuICAgICAgICAgICAgICB3aWR0aDogZ2V0VmlkZW9BdHRhY2htZW50Q29uZmlndXJhdGlvbihcbiAgICAgICAgICAgICAgICBhdHRhY2htZW50Q29udGV4dCxcbiAgICAgICAgICAgICAgICB2aWRlb0VsZW1lbnRcbiAgICAgICAgICAgICAgKS53aWR0aFxuICAgICAgICAgICAgfVwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPHZpZGVvXG4gICAgICAgICAgICAgICN2aWRlb0VsZW1lbnRcbiAgICAgICAgICAgICAgY2xhc3M9XCJzdHItY2hhdF9fdmlkZW8tYW5ndWxhclwiXG4gICAgICAgICAgICAgIGNvbnRyb2xzXG4gICAgICAgICAgICAgIGRhdGEtdGVzdGNsYXNzPVwidmlkZW8tYXR0YWNobWVudFwiXG4gICAgICAgICAgICAgIFtzcmNdPVwiXG4gICAgICAgICAgICAgICAgZ2V0VmlkZW9BdHRhY2htZW50Q29uZmlndXJhdGlvbihhdHRhY2htZW50Q29udGV4dCwgdmlkZW9FbGVtZW50KVxuICAgICAgICAgICAgICAgICAgLnVybFxuICAgICAgICAgICAgICBcIlxuICAgICAgICAgICAgICBbcG9zdGVyXT1cIlxuICAgICAgICAgICAgICAgIGdldFZpZGVvQXR0YWNobWVudENvbmZpZ3VyYXRpb24oYXR0YWNobWVudENvbnRleHQsIHZpZGVvRWxlbWVudClcbiAgICAgICAgICAgICAgICAgIC50aHVtYlVybFxuICAgICAgICAgICAgICBcIlxuICAgICAgICAgICAgPjwvdmlkZW8+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpc0ZpbGUoYXR0YWNobWVudClcIj5cbiAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICpuZ1RlbXBsYXRlT3V0bGV0PVwiXG4gICAgICAgICAgICAoY3VzdG9tVGVtcGxhdGVzU2VydmljZS5maWxlQXR0YWNobWVudFRlbXBsYXRlJCB8IGFzeW5jKSB8fFxuICAgICAgICAgICAgICBkZWZhdWx0RmlsZTtcbiAgICAgICAgICAgIGNvbnRleHQ6IGdldEF0dGFjaG1lbnRDb250ZXh0KGF0dGFjaG1lbnQpXG4gICAgICAgICAgXCJcbiAgICAgICAgPjwvbmctY29udGFpbmVyPlxuICAgICAgICA8bmctdGVtcGxhdGUgI2RlZmF1bHRGaWxlIGxldC1hdHRhY2htZW50Q29udGV4dD1cImF0dGFjaG1lbnRcIj5cbiAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICBjbGFzcz1cIlxuICAgICAgICAgICAgICBzdHItY2hhdF9fbWVzc2FnZS1hdHRhY2htZW50LWZpbGUtLWl0ZW1cbiAgICAgICAgICAgICAgc3RyLWNoYXQtYW5ndWxhcl9fbWVzc2FnZS1hdHRhY2htZW50LWZpbGUtc2luZ2xlXG4gICAgICAgICAgICBcIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIDxzdHJlYW0taWNvbi1wbGFjZWhvbGRlclxuICAgICAgICAgICAgICBpY29uPVwidW5zcGVjaWZpZWQtZmlsZXR5cGVcIlxuICAgICAgICAgICAgICBbc2l6ZV09XCIzMFwiXG4gICAgICAgICAgICA+PC9zdHJlYW0taWNvbi1wbGFjZWhvbGRlcj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdHItY2hhdF9fbWVzc2FnZS1hdHRhY2htZW50LWZpbGUtLWl0ZW0tdGV4dFwiPlxuICAgICAgICAgICAgICA8YVxuICAgICAgICAgICAgICAgIGNsYXNzPVwic3RyLWNoYXRfX21lc3NhZ2UtYXR0YWNobWVudC1maWxlLS1pdGVtLWZpcnN0LXJvd1wiXG4gICAgICAgICAgICAgICAgZGF0YS10ZXN0Y2xhc3M9XCJmaWxlLWxpbmtcIlxuICAgICAgICAgICAgICAgIHRhcmdldD1cIl9ibGFua1wiXG4gICAgICAgICAgICAgICAgaHJlZj1cInt7IGF0dGFjaG1lbnRDb250ZXh0LmFzc2V0X3VybCB9fVwiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICAgICBkYXRhLXRlc3RjbGFzcz1cImZpbGUtdGl0bGVcIlxuICAgICAgICAgICAgICAgICAgY2xhc3M9XCJzdHItY2hhdF9fbWVzc2FnZS1hdHRhY2htZW50LWZpbGUtLWl0ZW0tbmFtZVwiXG4gICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAge3sgYXR0YWNobWVudENvbnRleHQudGl0bGUgfX1cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8c3RyZWFtLWljb24tcGxhY2Vob2xkZXJcbiAgICAgICAgICAgICAgICAgIGNsYXNzPVwic3RyLWNoYXRfX21lc3NhZ2UtYXR0YWNobWVudC1kb3dubG9hZC1pY29uXCJcbiAgICAgICAgICAgICAgICAgIGljb249XCJkb3dubG9hZFwiXG4gICAgICAgICAgICAgICAgPjwvc3RyZWFtLWljb24tcGxhY2Vob2xkZXI+XG4gICAgICAgICAgICAgIDwvYT5cbiAgICAgICAgICAgICAgPHNwYW5cbiAgICAgICAgICAgICAgICAqbmdJZj1cImhhc0ZpbGVTaXplKGF0dGFjaG1lbnRDb250ZXh0KVwiXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJzdHItY2hhdF9fbWVzc2FnZS1hdHRhY2htZW50LWZpbGUtLWl0ZW0tc2l6ZVwiXG4gICAgICAgICAgICAgICAgZGF0YS10ZXN0Y2xhc3M9XCJzaXplXCJcbiAgICAgICAgICAgICAgICA+e3sgZ2V0RmlsZVNpemUoYXR0YWNobWVudENvbnRleHQpIH19PC9zcGFuXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXNWb2ljZU1lc3NhZ2UoYXR0YWNobWVudClcIj5cbiAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICpuZ1RlbXBsYXRlT3V0bGV0PVwiXG4gICAgICAgICAgICAoY3VzdG9tVGVtcGxhdGVzU2VydmljZS52b2ljZVJlY29yZGluZ0F0dGFjaG1lbnRUZW1wbGF0ZSRcbiAgICAgICAgICAgICAgfCBhc3luYykgfHwgZGVmYXVsdFJlY29yZGluZztcbiAgICAgICAgICAgIGNvbnRleHQ6IGdldEF0dGFjaG1lbnRDb250ZXh0KGF0dGFjaG1lbnQpXG4gICAgICAgICAgXCJcbiAgICAgICAgPjwvbmctY29udGFpbmVyPlxuICAgICAgICA8bmctdGVtcGxhdGUgI2RlZmF1bHRSZWNvcmRpbmc+XG4gICAgICAgICAgPHN0cmVhbS12b2ljZS1yZWNvcmRpbmdcbiAgICAgICAgICAgIGRhdGEtdGVzdGNsYXNzPVwidm9pY2UtcmVjb3JkaW5nXCJcbiAgICAgICAgICAgIFthdHRhY2htZW50XT1cImF0dGFjaG1lbnRcIlxuICAgICAgICAgID48L3N0cmVhbS12b2ljZS1yZWNvcmRpbmc+XG4gICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgKm5nSWY9XCJcbiAgICAgICAgICBpc0NhcmQoYXR0YWNobWVudCkgJiZcbiAgICAgICAgICBnZXRDYXJkQXR0YWNobWVudENvbmZpZ3VyYXRpb24oYXR0YWNobWVudCkgYXMgYXR0YWNobWVudENvbmZpZ3VyYXRpb25cbiAgICAgICAgXCJcbiAgICAgID5cbiAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICpuZ1RlbXBsYXRlT3V0bGV0PVwiXG4gICAgICAgICAgICAoY3VzdG9tVGVtcGxhdGVzU2VydmljZS5jYXJkQXR0YWNobWVudFRlbXBsYXRlJCB8IGFzeW5jKSB8fFxuICAgICAgICAgICAgICBkZWZhdWx0Q2FyZDtcbiAgICAgICAgICAgIGNvbnRleHQ6IGdldEF0dGFjaG1lbnRDb250ZXh0KGF0dGFjaG1lbnQpXG4gICAgICAgICAgXCJcbiAgICAgICAgPjwvbmctY29udGFpbmVyPlxuICAgICAgICA8bmctdGVtcGxhdGUgI2RlZmF1bHRDYXJkIGxldC1hdHRhY2htZW50Q29udGV4dD1cImF0dGFjaG1lbnRcIj5cbiAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICBjbGFzcz1cInN0ci1jaGF0X19tZXNzYWdlLWF0dGFjaG1lbnQtY2FyZCBzdHItY2hhdF9fbWVzc2FnZS1hdHRhY2htZW50LWNhcmQtLXt7XG4gICAgICAgICAgICAgIGF0dGFjaG1lbnRDb250ZXh0LnR5cGVcbiAgICAgICAgICAgIH19XCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICpuZ0lmPVwiYXR0YWNobWVudENvbmZpZ3VyYXRpb24udXJsXCJcbiAgICAgICAgICAgICAgY2xhc3M9XCJzdHItY2hhdF9fbWVzc2FnZS1hdHRhY2htZW50LWNhcmQtLWhlYWRlclwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIDxpbWdcbiAgICAgICAgICAgICAgICBmZXRjaHByaW9yaXR5PVwibG93XCJcbiAgICAgICAgICAgICAgICBsb2FkaW5nPVwibGF6eVwiXG4gICAgICAgICAgICAgICAgZGF0YS10ZXN0Y2xhc3M9XCJjYXJkLWltZ1wiXG4gICAgICAgICAgICAgICAgYWx0PVwie3sgYXR0YWNobWVudENvbmZpZ3VyYXRpb24udXJsIH19XCJcbiAgICAgICAgICAgICAgICBzcmM9XCJ7eyBhdHRhY2htZW50Q29uZmlndXJhdGlvbi51cmwgfX1cIlxuICAgICAgICAgICAgICAgIFtuZ1N0eWxlXT1cIntcbiAgICAgICAgICAgICAgICAgIGhlaWdodDogYXR0YWNobWVudENvbmZpZ3VyYXRpb24uaGVpZ2h0LFxuICAgICAgICAgICAgICAgICAgd2lkdGg6IGF0dGFjaG1lbnRDb25maWd1cmF0aW9uLndpZHRoXG4gICAgICAgICAgICAgICAgfVwiXG4gICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdHItY2hhdF9fbWVzc2FnZS1hdHRhY2htZW50LWNhcmQtLWNvbnRlbnRcIj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN0ci1jaGF0X19tZXNzYWdlLWF0dGFjaG1lbnQtY2FyZC0tZmxleFwiPlxuICAgICAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICAgICpuZ0lmPVwiYXR0YWNobWVudENvbnRleHQudGl0bGVcIlxuICAgICAgICAgICAgICAgICAgZGF0YS10ZXN0Y2xhc3M9XCJjYXJkLXRpdGxlXCJcbiAgICAgICAgICAgICAgICAgIGNsYXNzPVwic3RyLWNoYXRfX21lc3NhZ2UtYXR0YWNobWVudC1jYXJkLS10aXRsZVwiXG4gICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAge3sgYXR0YWNobWVudENvbnRleHQudGl0bGUgfX1cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICAgICAqbmdJZj1cImF0dGFjaG1lbnRDb250ZXh0LnRleHRcIlxuICAgICAgICAgICAgICAgICAgY2xhc3M9XCJzdHItY2hhdF9fbWVzc2FnZS1hdHRhY2htZW50LWNhcmQtLXRleHRcIlxuICAgICAgICAgICAgICAgICAgZGF0YS10ZXN0Y2xhc3M9XCJjYXJkLXRleHRcIlxuICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgIHt7IGF0dGFjaG1lbnRDb250ZXh0LnRleHQgfX1cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8YVxuICAgICAgICAgICAgICAgICAgKm5nSWY9XCJcbiAgICAgICAgICAgICAgICAgICAgYXR0YWNobWVudENvbnRleHQudGl0bGVfbGluayB8fFxuICAgICAgICAgICAgICAgICAgICBhdHRhY2htZW50Q29udGV4dC5vZ19zY3JhcGVfdXJsXG4gICAgICAgICAgICAgICAgICBcIlxuICAgICAgICAgICAgICAgICAgY2xhc3M9XCJzdHItY2hhdF9fbWVzc2FnZS1hdHRhY2htZW50LWNhcmQtLXVybFwiXG4gICAgICAgICAgICAgICAgICBkYXRhLXRlc3RjbGFzcz1cInVybC1saW5rXCJcbiAgICAgICAgICAgICAgICAgIG5vb3BlbmVyXG4gICAgICAgICAgICAgICAgICBub3JlZmVycmVyXG4gICAgICAgICAgICAgICAgICB0YXJnZXQ9XCJfYmxhbmtcIlxuICAgICAgICAgICAgICAgICAgaHJlZj1cInt7XG4gICAgICAgICAgICAgICAgICAgIGF0dGFjaG1lbnRDb250ZXh0LnRpdGxlX2xpbmsgfHxcbiAgICAgICAgICAgICAgICAgICAgICBhdHRhY2htZW50Q29udGV4dC5vZ19zY3JhcGVfdXJsXG4gICAgICAgICAgICAgICAgICB9fVwiXG4gICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAge3tcbiAgICAgICAgICAgICAgICAgICAgdHJpbVVybChcbiAgICAgICAgICAgICAgICAgICAgICBhdHRhY2htZW50Q29udGV4dC50aXRsZV9saW5rIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICBhdHRhY2htZW50Q29udGV4dC5vZ19zY3JhcGVfdXJsXG4gICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgIH19XG4gICAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiYXR0YWNobWVudC5hY3Rpb25zICYmIGF0dGFjaG1lbnQuYWN0aW9ucy5sZW5ndGggPiAwXCI+XG4gICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAqbmdUZW1wbGF0ZU91dGxldD1cIlxuICAgICAgICAgICAgKGN1c3RvbVRlbXBsYXRlc1NlcnZpY2UuYXR0YWNobWVudEFjdGlvbnNUZW1wbGF0ZSQgfCBhc3luYykgfHxcbiAgICAgICAgICAgICAgZGVmYXVsdEFjdGlvbnM7XG4gICAgICAgICAgICBjb250ZXh0OiBnZXRBdHRhY2htZW50Q29udGV4dChhdHRhY2htZW50KVxuICAgICAgICAgIFwiXG4gICAgICAgID48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPG5nLXRlbXBsYXRlICNkZWZhdWx0QWN0aW9ucyBsZXQtYXR0YWNobWVudENvbnRleHQ9XCJhdHRhY2htZW50XCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInN0ci1jaGF0X19tZXNzYWdlLWF0dGFjaG1lbnQtYWN0aW9uc1wiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN0ci1jaGF0X19tZXNzYWdlLWF0dGFjaG1lbnQtYWN0aW9ucy1mb3JtXCI+XG4gICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICAqbmdGb3I9XCJcbiAgICAgICAgICAgICAgICAgIGxldCBhY3Rpb24gb2YgYXR0YWNobWVudENvbnRleHQuYWN0aW9ucztcbiAgICAgICAgICAgICAgICAgIHRyYWNrQnk6IHRyYWNrQnlBY3Rpb25WYWx1ZVxuICAgICAgICAgICAgICAgIFwiXG4gICAgICAgICAgICAgICAgZGF0YS10ZXN0Y2xhc3M9XCJhdHRhY2htZW50LWFjdGlvblwiXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJzdHItY2hhdF9fbWVzc2FnZS1hdHRhY2htZW50LWFjdGlvbnMtYnV0dG9uIHN0ci1jaGF0X19tZXNzYWdlLWF0dGFjaG1lbnQtYWN0aW9ucy1idXR0b24tLXt7XG4gICAgICAgICAgICAgICAgICBhY3Rpb24uc3R5bGVcbiAgICAgICAgICAgICAgICB9fVwiXG4gICAgICAgICAgICAgICAgKGNsaWNrKT1cInNlbmRBY3Rpb24oYWN0aW9uKVwiXG4gICAgICAgICAgICAgICAgKGtleXVwLmVudGVyKT1cInNlbmRBY3Rpb24oYWN0aW9uKVwiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICB7eyBhY3Rpb24udGV4dCB9fVxuICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgPC9kaXY+XG4gIDwvbmctY29udGFpbmVyPlxuXG4gIDxuZy1jb250YWluZXIgKm5nSWY9XCJpbWFnZXNUb1ZpZXcgJiYgaW1hZ2VzVG9WaWV3Lmxlbmd0aCA+IDBcIj5cbiAgICA8bmctY29udGFpbmVyXG4gICAgICAqbmdUZW1wbGF0ZU91dGxldD1cIlxuICAgICAgICAoY3VzdG9tVGVtcGxhdGVzU2VydmljZS5tb2RhbFRlbXBsYXRlJCB8IGFzeW5jKSB8fCBkZWZhdWx0TW9kYWw7XG4gICAgICAgIGNvbnRleHQ6IGdldE1vZGFsQ29udGV4dCgpXG4gICAgICBcIlxuICAgID48L25nLWNvbnRhaW5lcj5cbiAgPC9uZy1jb250YWluZXI+XG48L2Rpdj5cblxuPG5nLXRlbXBsYXRlXG4gICNkZWZhdWx0TW9kYWxcbiAgbGV0LWlzT3Blbj1cImlzT3BlblwiXG4gIGxldC1pc09wZW5DaGFuZ2VIYW5kbGVyPVwiaXNPcGVuQ2hhbmdlSGFuZGxlclwiXG4gIGxldC1jb250ZW50PVwiY29udGVudFwiXG4+XG4gIDxzdHJlYW0tbW9kYWxcbiAgICBjbGFzcz1cInN0cmVhbS1jaGF0LWFuZ3VsYXJfX2ltYWdlLW1vZGFsLWhvc3RcIlxuICAgIFtpc09wZW5dPVwiaXNPcGVuXCJcbiAgICBbY29udGVudF09XCJjb250ZW50XCJcbiAgICAoaXNPcGVuQ2hhbmdlKT1cImlzT3BlbkNoYW5nZUhhbmRsZXIoJGV2ZW50KVwiXG4gID5cbiAgPC9zdHJlYW0tbW9kYWw+XG48L25nLXRlbXBsYXRlPlxuXG48bmctdGVtcGxhdGUgI21vZGFsQ29udGVudD5cbiAgPGRpdiBjbGFzcz1cInN0cmVhbS1jaGF0LWFuZ3VsYXJfX2ltYWdlLW1vZGFsIHN0ci1jaGF0X19pbWFnZS1jYXJvdXNlbFwiPlxuICAgIDxpbWdcbiAgICAgICNpbWdFbGVtZW50XG4gICAgICBjbGFzcz1cIlxuICAgICAgICBzdHJlYW0tY2hhdC1hbmd1bGFyX19pbWFnZS1tb2RhbC1pbWFnZVxuICAgICAgICBzdHItY2hhdF9faW1hZ2UtY2Fyb3VzZWwtaW1hZ2VcbiAgICAgIFwiXG4gICAgICBkYXRhLXRlc3RpZD1cIm1vZGFsLWltYWdlXCJcbiAgICAgIFtzcmNdPVwiXG4gICAgICAgIGdldENhcm91c2VsSW1hZ2VBdHRhY2htZW50Q29uZmlndXJhdGlvbihcbiAgICAgICAgICBpbWFnZXNUb1ZpZXdbaW1hZ2VzVG9WaWV3Q3VycmVudEluZGV4XSxcbiAgICAgICAgICBpbWdFbGVtZW50XG4gICAgICAgICkudXJsXG4gICAgICBcIlxuICAgICAgW3N0eWxlLi0tb3JpZ2luYWwtaGVpZ2h0XT1cIlxuICAgICAgICBnZXRDYXJvdXNlbEltYWdlQXR0YWNobWVudENvbmZpZ3VyYXRpb24oXG4gICAgICAgICAgaW1hZ2VzVG9WaWV3W2ltYWdlc1RvVmlld0N1cnJlbnRJbmRleF0sXG4gICAgICAgICAgaW1nRWxlbWVudFxuICAgICAgICApLm9yaWdpbmFsSGVpZ2h0XG4gICAgICBcIlxuICAgICAgW3N0eWxlLi0tb3JpZ2luYWwtd2lkdGhdPVwiXG4gICAgICAgIGdldENhcm91c2VsSW1hZ2VBdHRhY2htZW50Q29uZmlndXJhdGlvbihcbiAgICAgICAgICBpbWFnZXNUb1ZpZXdbaW1hZ2VzVG9WaWV3Q3VycmVudEluZGV4XSxcbiAgICAgICAgICBpbWdFbGVtZW50XG4gICAgICAgICkub3JpZ2luYWxXaWR0aFxuICAgICAgXCJcbiAgICAgIFthbHRdPVwiaW1hZ2VzVG9WaWV3W2ltYWdlc1RvVmlld0N1cnJlbnRJbmRleF0uZmFsbGJhY2tcIlxuICAgICAgW25nU3R5bGVdPVwie1xuICAgICAgICB3aWR0aDogZ2V0Q2Fyb3VzZWxJbWFnZUF0dGFjaG1lbnRDb25maWd1cmF0aW9uKFxuICAgICAgICAgIGltYWdlc1RvVmlld1tpbWFnZXNUb1ZpZXdDdXJyZW50SW5kZXhdLFxuICAgICAgICAgIGltZ0VsZW1lbnRcbiAgICAgICAgKS53aWR0aCxcbiAgICAgICAgaGVpZ2h0OiBnZXRDYXJvdXNlbEltYWdlQXR0YWNobWVudENvbmZpZ3VyYXRpb24oXG4gICAgICAgICAgaW1hZ2VzVG9WaWV3W2ltYWdlc1RvVmlld0N1cnJlbnRJbmRleF0sXG4gICAgICAgICAgaW1nRWxlbWVudFxuICAgICAgICApLmhlaWdodFxuICAgICAgfVwiXG4gICAgLz5cbiAgICA8ZGl2PlxuICAgICAgPGJ1dHRvblxuICAgICAgICBjbGFzcz1cIlxuICAgICAgICAgIHN0cmVhbS1jaGF0LWFuZ3VsYXJfX2ltYWdlLW1vZGFsLXN0ZXBwZXJcbiAgICAgICAgICBzdHItY2hhdF9faW1hZ2UtY2Fyb3VzZWwtc3RlcHBlciBzdHItY2hhdF9faW1hZ2UtY2Fyb3VzZWwtc3RlcHBlci1wcmV2XG4gICAgICAgIFwiXG4gICAgICAgIGRhdGEtdGVzdGlkPVwiaW1hZ2UtbW9kYWwtcHJldlwiXG4gICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICBbbmdTdHlsZV09XCJ7XG4gICAgICAgICAgdmlzaWJpbGl0eTogaXNJbWFnZU1vZGFsUHJldkJ1dHRvblZpc2libGUgPyAndmlzaWJsZScgOiAnaGlkZGVuJ1xuICAgICAgICB9XCJcbiAgICAgICAgKGNsaWNrKT1cInN0ZXBJbWFnZXMoLTEpXCJcbiAgICAgICAgKGtleXVwLmVudGVyKT1cInN0ZXBJbWFnZXMoLTEpXCJcbiAgICAgID5cbiAgICAgICAgPHN0cmVhbS1pY29uLXBsYWNlaG9sZGVyIGljb249XCJhcnJvdy1sZWZ0XCI+PC9zdHJlYW0taWNvbi1wbGFjZWhvbGRlcj5cbiAgICAgIDwvYnV0dG9uPlxuICAgICAgPGJ1dHRvblxuICAgICAgICBjbGFzcz1cIlxuICAgICAgICAgIHN0cmVhbS1jaGF0LWFuZ3VsYXJfX2ltYWdlLW1vZGFsLXN0ZXBwZXJcbiAgICAgICAgICBzdHItY2hhdF9faW1hZ2UtY2Fyb3VzZWwtc3RlcHBlciBzdHItY2hhdF9faW1hZ2UtY2Fyb3VzZWwtc3RlcHBlci1uZXh0XG4gICAgICAgIFwiXG4gICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICBkYXRhLXRlc3RpZD1cImltYWdlLW1vZGFsLW5leHRcIlxuICAgICAgICBbbmdTdHlsZV09XCJ7XG4gICAgICAgICAgdmlzaWJpbGl0eTogaXNJbWFnZU1vZGFsTmV4dEJ1dHRvblZpc2libGUgPyAndmlzaWJsZScgOiAnaGlkZGVuJ1xuICAgICAgICB9XCJcbiAgICAgICAgKGNsaWNrKT1cInN0ZXBJbWFnZXMoMSlcIlxuICAgICAgICAoa2V5dXAuZW50ZXIpPVwic3RlcEltYWdlcygxKVwiXG4gICAgICA+XG4gICAgICAgIDxzdHJlYW0taWNvbi1wbGFjZWhvbGRlciBpY29uPVwiYXJyb3ctcmlnaHRcIj48L3N0cmVhbS1pY29uLXBsYWNlaG9sZGVyPlxuICAgICAgPC9idXR0b24+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuPC9uZy10ZW1wbGF0ZT5cbiJdfQ==