stream-chat-angular 4.66.2 → 5.0.0-v5.10
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.
- package/assets/version.d.ts +1 -1
- package/{esm2015/assets/version.js → esm2020/assets/version.mjs} +2 -2
- package/esm2020/lib/attachment-configuration.service.mjs +185 -0
- package/esm2020/lib/attachment-list/attachment-list.component.mjs +203 -0
- package/esm2020/lib/attachment-preview-list/attachment-preview-list.component.mjs +42 -0
- package/esm2020/lib/attachment.service.mjs +262 -0
- package/esm2020/lib/avatar/avatar.component.mjs +163 -0
- package/esm2020/lib/avatar-placeholder/avatar-placeholder.component.mjs +74 -0
- package/esm2020/lib/channel/channel.component.mjs +46 -0
- package/esm2020/lib/channel-header/channel-header.component.mjs +72 -0
- package/esm2020/lib/channel-list/channel-list.component.mjs +51 -0
- package/esm2020/lib/channel-preview/channel-preview.component.mjs +155 -0
- package/esm2020/lib/channel.service.mjs +1454 -0
- package/esm2020/lib/chat-client.service.mjs +206 -0
- package/{esm2015/lib/custom-templates.service.js → esm2020/lib/custom-templates.service.mjs} +3 -3
- package/{esm2015/lib/date-parser.service.js → esm2020/lib/date-parser.service.mjs} +3 -3
- package/esm2020/lib/edit-message-form/edit-message-form.component.mjs +83 -0
- package/esm2020/lib/get-channel-display-text.mjs +14 -0
- package/esm2020/lib/get-message-translation.mjs +12 -0
- package/esm2020/lib/icon/icon.component.mjs +21 -0
- package/esm2020/lib/icon-placeholder/icon-placeholder.component.mjs +31 -0
- package/esm2020/lib/loading-indicator/loading-indicator.component.mjs +31 -0
- package/esm2020/lib/loading-indicator-placeholder/loading-indicator-placeholder.component.mjs +38 -0
- package/esm2020/lib/message/message.component.mjs +402 -0
- package/esm2020/lib/message-actions-box/message-actions-box.component.mjs +98 -0
- package/esm2020/lib/message-actions.service.mjs +119 -0
- package/esm2020/lib/message-bounce-prompt/message-bounce-prompt.component.mjs +71 -0
- package/esm2020/lib/message-input/autocomplete-textarea/autocomplete-textarea.component.mjs +259 -0
- package/{esm2015/lib/message-input/emoji-input.service.js → esm2020/lib/message-input/emoji-input.service.mjs} +3 -3
- package/{esm2015/lib/message-input/message-input-config.service.js → esm2020/lib/message-input/message-input-config.service.mjs} +3 -3
- package/esm2020/lib/message-input/message-input.component.mjs +441 -0
- package/{esm2015/lib/message-input/textarea/textarea.component.js → esm2020/lib/message-input/textarea/textarea.component.mjs} +7 -13
- package/esm2020/lib/message-input/textarea.directive.mjs +89 -0
- package/esm2020/lib/message-list/group-styles.mjs +52 -0
- package/esm2020/lib/message-list/message-list.component.mjs +679 -0
- package/esm2020/lib/message-preview.mjs +21 -0
- package/esm2020/lib/message-reactions/message-reactions.component.mjs +247 -0
- package/esm2020/lib/message-reactions.service.mjs +44 -0
- package/{esm2015/lib/message.service.js → esm2020/lib/message.service.mjs} +4 -4
- package/esm2020/lib/modal/modal.component.mjs +69 -0
- package/esm2020/lib/notification/notification.component.mjs +20 -0
- package/esm2020/lib/notification-list/notification-list.component.mjs +36 -0
- package/esm2020/lib/notification.service.mjs +79 -0
- package/esm2020/lib/read-by.mjs +12 -0
- package/{esm2015/lib/stream-autocomplete-textarea.module.js → esm2020/lib/stream-autocomplete-textarea.module.mjs} +6 -6
- package/{esm2015/lib/stream-avatar.module.js → esm2020/lib/stream-avatar.module.mjs} +5 -5
- package/{esm2015/lib/stream-chat.module.js → esm2020/lib/stream-chat.module.mjs} +14 -16
- package/{esm2015/lib/stream-i18n.service.js → esm2020/lib/stream-i18n.service.mjs} +5 -5
- package/{esm2015/lib/stream-textarea.module.js → esm2020/lib/stream-textarea.module.mjs} +6 -6
- package/esm2020/lib/theme.service.mjs +23 -0
- package/esm2020/lib/thread/thread.component.mjs +51 -0
- package/{esm2015/lib/transliteration.service.js → esm2020/lib/transliteration.service.mjs} +3 -3
- package/esm2020/lib/types.mjs +2 -0
- package/esm2020/lib/voice-recording/voice-recording-wavebar/voice-recording-wavebar.component.mjs +183 -0
- package/esm2020/lib/voice-recording/voice-recording.component.mjs +102 -0
- package/esm2020/public-api.mjs +64 -0
- package/fesm2015/{stream-chat-angular.js → stream-chat-angular.mjs} +354 -754
- package/fesm2015/stream-chat-angular.mjs.map +1 -0
- package/fesm2020/stream-chat-angular.mjs +6835 -0
- package/fesm2020/stream-chat-angular.mjs.map +1 -0
- package/lib/attachment-list/attachment-list.component.d.ts +4 -6
- package/lib/attachment-preview-list/attachment-preview-list.component.d.ts +2 -4
- package/lib/attachment.service.d.ts +0 -1
- package/lib/avatar/avatar.component.d.ts +1 -1
- package/lib/avatar-placeholder/avatar-placeholder.component.d.ts +1 -1
- package/lib/channel/channel.component.d.ts +1 -1
- package/lib/channel-header/channel-header.component.d.ts +2 -5
- package/lib/channel-list/channel-list.component.d.ts +4 -9
- package/lib/channel-preview/channel-preview.component.d.ts +1 -1
- package/lib/channel.service.d.ts +7 -14
- package/lib/chat-client.service.d.ts +1 -1
- package/lib/edit-message-form/edit-message-form.component.d.ts +1 -1
- package/lib/get-message-translation.d.ts +1 -1
- package/lib/icon/icon.component.d.ts +1 -1
- package/lib/icon-placeholder/icon-placeholder.component.d.ts +1 -1
- package/lib/loading-indicator/loading-indicator.component.d.ts +1 -1
- package/lib/loading-indicator-placeholder/loading-indicator-placeholder.component.d.ts +1 -1
- package/lib/message/message.component.d.ts +6 -19
- package/lib/message-actions-box/message-actions-box.component.d.ts +4 -32
- package/lib/message-actions.service.d.ts +0 -1
- package/lib/message-bounce-prompt/message-bounce-prompt.component.d.ts +1 -1
- package/lib/message-input/autocomplete-textarea/autocomplete-textarea.component.d.ts +1 -2
- package/lib/message-input/message-input.component.d.ts +3 -5
- package/lib/message-input/textarea/textarea.component.d.ts +1 -1
- package/lib/message-input/textarea.directive.d.ts +1 -1
- package/lib/message-list/group-styles.d.ts +1 -1
- package/lib/message-list/message-list.component.d.ts +4 -12
- package/lib/message-reactions/message-reactions.component.d.ts +2 -7
- package/lib/message.service.d.ts +0 -1
- package/lib/modal/modal.component.d.ts +1 -1
- package/lib/notification/notification.component.d.ts +1 -1
- package/lib/notification-list/notification-list.component.d.ts +2 -3
- package/lib/notification.service.d.ts +2 -5
- package/lib/stream-chat.module.d.ts +3 -3
- package/lib/theme.service.d.ts +1 -44
- package/lib/thread/thread.component.d.ts +1 -1
- package/lib/types.d.ts +16 -33
- package/lib/voice-recording/voice-recording-wavebar/voice-recording-wavebar.component.d.ts +2 -2
- package/lib/voice-recording/voice-recording.component.d.ts +1 -1
- package/package.json +31 -17
- package/public-api.d.ts +0 -2
- package/src/assets/styles/css/index.css +3 -1
- package/src/assets/styles/css/index.layout.css +3 -0
- package/src/assets/styles/{v2/scss → scss}/AttachmentList/AttachmentList-layout.scss +1 -1
- package/src/assets/styles/{v2/scss → scss}/Message/Message-layout.scss +2 -2
- package/src/assets/styles/scss/_base.scss +7 -198
- package/src/assets/styles/scss/index.scss +35 -48
- package/src/assets/version.ts +1 -1
- package/bundles/stream-chat-angular.umd.js +0 -8445
- package/bundles/stream-chat-angular.umd.js.map +0 -1
- package/esm2015/lib/attachment-configuration.service.js +0 -186
- package/esm2015/lib/attachment-list/attachment-list.component.js +0 -209
- package/esm2015/lib/attachment-preview-list/attachment-preview-list.component.js +0 -49
- package/esm2015/lib/attachment.service.js +0 -276
- package/esm2015/lib/avatar/avatar.component.js +0 -172
- package/esm2015/lib/avatar-placeholder/avatar-placeholder.component.js +0 -78
- package/esm2015/lib/channel/channel.component.js +0 -50
- package/esm2015/lib/channel-header/channel-header.component.js +0 -86
- package/esm2015/lib/channel-list/channel-list-toggle.service.js +0 -73
- package/esm2015/lib/channel-list/channel-list.component.js +0 -67
- package/esm2015/lib/channel-preview/channel-preview.component.js +0 -167
- package/esm2015/lib/channel.service.js +0 -1487
- package/esm2015/lib/chat-client.service.js +0 -211
- package/esm2015/lib/edit-message-form/edit-message-form.component.js +0 -87
- package/esm2015/lib/get-channel-display-text.js +0 -15
- package/esm2015/lib/get-message-translation.js +0 -13
- package/esm2015/lib/icon/icon.component.js +0 -25
- package/esm2015/lib/icon-placeholder/icon-placeholder.component.js +0 -35
- package/esm2015/lib/loading-indicator/loading-indicator.component.js +0 -35
- package/esm2015/lib/loading-indicator-placeholder/loading-indicator-placeholder.component.js +0 -42
- package/esm2015/lib/message/message.component.js +0 -436
- package/esm2015/lib/message-actions-box/message-actions-box.component.js +0 -137
- package/esm2015/lib/message-actions.service.js +0 -114
- package/esm2015/lib/message-bounce-prompt/message-bounce-prompt.component.js +0 -80
- package/esm2015/lib/message-input/autocomplete-textarea/autocomplete-textarea.component.js +0 -262
- package/esm2015/lib/message-input/message-input.component.js +0 -455
- package/esm2015/lib/message-input/textarea.directive.js +0 -90
- package/esm2015/lib/message-list/group-styles.js +0 -53
- package/esm2015/lib/message-list/image-load.service.js +0 -24
- package/esm2015/lib/message-list/message-list.component.js +0 -726
- package/esm2015/lib/message-preview.js +0 -7
- package/esm2015/lib/message-reactions/message-reactions.component.js +0 -266
- package/esm2015/lib/message-reactions.service.js +0 -45
- package/esm2015/lib/modal/modal.component.js +0 -74
- package/esm2015/lib/notification/notification.component.js +0 -24
- package/esm2015/lib/notification-list/notification-list.component.js +0 -38
- package/esm2015/lib/notification.service.js +0 -79
- package/esm2015/lib/read-by.js +0 -13
- package/esm2015/lib/theme.service.js +0 -122
- package/esm2015/lib/thread/thread.component.js +0 -55
- package/esm2015/lib/types.js +0 -2
- package/esm2015/lib/voice-recording/voice-recording-wavebar/voice-recording-wavebar.component.js +0 -192
- package/esm2015/lib/voice-recording/voice-recording.component.js +0 -115
- package/esm2015/public-api.js +0 -66
- package/fesm2015/stream-chat-angular.js.map +0 -1
- package/lib/channel-list/channel-list-toggle.service.d.ts +0 -40
- package/lib/message-list/image-load.service.d.ts +0 -15
- package/src/assets/EmojiOneColor.woff2 +0 -0
- package/src/assets/NotoColorEmoji-flags.woff2 +0 -0
- package/src/assets/Poweredby_100px-White_VertText.png +0 -0
- package/src/assets/str-chat__alert.svg +0 -1
- package/src/assets/str-chat__file-file.svg +0 -20
- package/src/assets/str-chat__icon-chevron-down.svg +0 -1
- package/src/assets/str-chat__icon-search.svg +0 -1
- package/src/assets/str-chat__icon-send.svg +0 -1
- package/src/assets/str-chat__icon-sprite.png +0 -0
- package/src/assets/str-chat__icon-sprite@1x.png +0 -0
- package/src/assets/str-chat__icon-sprite@2x.png +0 -0
- package/src/assets/str-chat__icon-sprite@3x.png +0 -0
- package/src/assets/str-chat__loading-indicator.svg +0 -23
- package/src/assets/str-chat__reaction-list-sprite@1x.png +0 -0
- package/src/assets/str-chat__reaction-list-sprite@2x.png +0 -0
- package/src/assets/str-chat__reaction-list-sprite@3x.png +0 -0
- package/src/assets/str-chat__reactions-sprite@1x.png +0 -0
- package/src/assets/str-chat__reactions-sprite@2x.png +0 -0
- package/src/assets/str-chat__reactions-sprite@3x.png +0 -0
- package/src/assets/styles/assets/EmojiOneColor.woff2 +0 -0
- package/src/assets/styles/assets/NotoColorEmoji-flags.woff2 +0 -0
- package/src/assets/styles/assets/Poweredby_100px-White_VertText.png +0 -0
- package/src/assets/styles/assets/str-chat__reaction-list-sprite@1x.png +0 -0
- package/src/assets/styles/assets/str-chat__reaction-list-sprite@2x.png +0 -0
- package/src/assets/styles/assets/str-chat__reaction-list-sprite@3x.png +0 -0
- package/src/assets/styles/scss/ActionsBox.scss +0 -56
- package/src/assets/styles/scss/Attachment.scss +0 -329
- package/src/assets/styles/scss/AttachmentActions.scss +0 -44
- package/src/assets/styles/scss/Audio.scss +0 -113
- package/src/assets/styles/scss/Avatar.scss +0 -79
- package/src/assets/styles/scss/Card.scss +0 -125
- package/src/assets/styles/scss/ChannelHeader.scss +0 -284
- package/src/assets/styles/scss/ChannelList.scss +0 -141
- package/src/assets/styles/scss/ChannelListMessenger.scss +0 -9
- package/src/assets/styles/scss/ChannelPreview.scss +0 -133
- package/src/assets/styles/scss/ChannelSearch.scss +0 -124
- package/src/assets/styles/scss/ChatDown.scss +0 -15
- package/src/assets/styles/scss/DateSeparator.scss +0 -51
- package/src/assets/styles/scss/EditMessageForm.scss +0 -112
- package/src/assets/styles/scss/EventComponent.scss +0 -48
- package/src/assets/styles/scss/Gallery.scss +0 -121
- package/src/assets/styles/scss/ImageCarousel.scss +0 -45
- package/src/assets/styles/scss/InfiniteScrollPaginator.scss +0 -6
- package/src/assets/styles/scss/LoadMoreButton.scss +0 -44
- package/src/assets/styles/scss/LoadingChannels.scss +0 -70
- package/src/assets/styles/scss/LoadingIndicator.scss +0 -38
- package/src/assets/styles/scss/Message.scss +0 -1283
- package/src/assets/styles/scss/MessageActions.scss +0 -137
- package/src/assets/styles/scss/MessageCommerce.scss +0 -608
- package/src/assets/styles/scss/MessageInput.scss +0 -398
- package/src/assets/styles/scss/MessageInputFlat.scss +0 -323
- package/src/assets/styles/scss/MessageList.scss +0 -244
- package/src/assets/styles/scss/MessageLivestream.scss +0 -338
- package/src/assets/styles/scss/MessageNotification.scss +0 -43
- package/src/assets/styles/scss/MessageRepliesCountButton.scss +0 -33
- package/src/assets/styles/scss/MessageTeam.scss +0 -644
- package/src/assets/styles/scss/Modal.scss +0 -78
- package/src/assets/styles/scss/ReactionList.scss +0 -197
- package/src/assets/styles/scss/ReactionSelector.scss +0 -218
- package/src/assets/styles/scss/SendButton.scss +0 -20
- package/src/assets/styles/scss/SimpleReactionsList.scss +0 -76
- package/src/assets/styles/scss/SmallMessageInput.scss +0 -171
- package/src/assets/styles/scss/Thread.scss +0 -381
- package/src/assets/styles/scss/Tooltip.scss +0 -41
- package/src/assets/styles/scss/TypingIndicator.scss +0 -80
- package/src/assets/styles/scss/VirtualMessage.scss +0 -288
- package/src/assets/styles/scss/_variables.scss +0 -161
- package/src/assets/styles/v2/css/index.css +0 -3
- package/src/assets/styles/v2/css/index.layout.css +0 -3
- package/src/assets/styles/v2/scss/_base.scss +0 -28
- package/src/assets/styles/v2/scss/index.scss +0 -37
- package/src/assets/styles/vendor/emoji-mart.scss +0 -514
- package/src/assets/styles/vendor/mml-react.scss +0 -2246
- package/src/assets/styles/vendor/react-file-utils.scss +0 -441
- package/src/assets/styles/vendor/react-image-gallery.scss +0 -237
- /package/{esm2015/assets/i18n/en.js → esm2020/assets/i18n/en.mjs} +0 -0
- /package/{esm2015/lib/injection-tokens.js → esm2020/lib/injection-tokens.mjs} +0 -0
- /package/{esm2015/lib/is-image-attachment.js → esm2020/lib/is-image-attachment.mjs} +0 -0
- /package/{esm2015/lib/is-image-file.js → esm2020/lib/is-image-file.mjs} +0 -0
- /package/{esm2015/lib/is-on-separate-date.js → esm2020/lib/is-on-separate-date.mjs} +0 -0
- /package/{esm2015/lib/list-users.js → esm2020/lib/list-users.mjs} +0 -0
- /package/{esm2015/lib/message-input/textarea.interface.js → esm2020/lib/message-input/textarea.interface.mjs} +0 -0
- /package/{esm2015/lib/parse-date.js → esm2020/lib/parse-date.mjs} +0 -0
- /package/{esm2015/stream-chat-angular.js → esm2020/stream-chat-angular.mjs} +0 -0
- /package/{stream-chat-angular.d.ts → index.d.ts} +0 -0
- /package/src/assets/styles/{v2/css → css}/emoji-mart.css +0 -0
- /package/src/assets/styles/{v2/css → css}/emoji-replacement.css +0 -0
- /package/src/assets/styles/{v2/scss → scss}/AttachmentList/AttachmentList-theme.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/AttachmentPreviewList/AttachmentPreviewList-layout.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/AttachmentPreviewList/AttachmentPreviewList-theme.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/Autocomplete/Autocomplete-layout.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/Autocomplete/Autocomplete-theme.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/Avatar/Avatar-layout.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/Avatar/Avatar-theme.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/BaseImage/BaseImage-layout.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/BaseImage/BaseImage-theme.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/BaseImage/index.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/Channel/Channel-layout.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/Channel/Channel-theme.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/ChannelHeader/ChannelHeader-layout.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/ChannelHeader/ChannelHeader-theme.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/ChannelList/ChannelList-layout.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/ChannelList/ChannelList-theme.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/ChannelPreview/ChannelPreview-layout.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/ChannelPreview/ChannelPreview-theme.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/ChannelSearch/ChannelSearch-layout.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/ChannelSearch/ChannelSearch-theme.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/EditMessageForm/EditMessageForm-layout.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/EditMessageForm/EditMessageForm-theme.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/ImageCarousel/ImageCarousel-layout.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/ImageCarousel/ImageCarousel-theme.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/LinkPreview/LinkPreview-layout.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/LinkPreview/LinkPreview-theme.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/LinkPreview/index.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/LoadingIndicator/LoadingIndicator-layout.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/LoadingIndicator/LoadingIndicator-theme.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/Message/Message-theme.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/MessageActionsBox/MessageActionsBox-layout.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/MessageActionsBox/MessageActionsBox-theme.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/MessageBouncePrompt/MessageBouncePrompt-layout.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/MessageBouncePrompt/MessageBouncePrompt-theme.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/MessageInput/MessageInput-layout.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/MessageInput/MessageInput-theme.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/MessageList/MessageList-layout.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/MessageList/MessageList-theme.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/MessageList/VirtualizedMessageList-layout.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/MessageList/VirtualizedMessageList-theme.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/MessageReactions/MessageReactions-layout.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/MessageReactions/MessageReactions-theme.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/MessageReactions/MessageReactionsSelector-layout.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/MessageReactions/MessageReactionsSelector-theme.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/Modal/Modal-layout.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/Modal/Modal-theme.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/Notification/MessageNotification-layout.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/Notification/MessageNotification-theme.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/Notification/Notification-layout.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/Notification/Notification-theme.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/Notification/NotificationList-layout.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/Notification/NotificationList-theme.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/Thread/Thread-layout.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/Thread/Thread-theme.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/Tooltip/Tooltip-layout.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/Tooltip/Tooltip-theme.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/TypingIndicator/TypingIndicator-layout.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/TypingIndicator/TypingIndicator-theme.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/_emoji-replacement.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/_global-layout-variables.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/_global-theme-variables.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/_icons.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/_palette-variables.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/_utils.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/common/CTAButton/CTAButton-layout.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/common/CTAButton/CTAButton-theme.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/common/CircleFAButton/CircleFAButton-layout.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/common/CircleFAButton/CircleFAButton-theme.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/index.layout.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/vendor/emoji-mart.scss +0 -0
- /package/src/assets/styles/{v2/scss → scss}/vendor/react-image-gallery.scss +0 -0
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
import { Component, Input, ChangeDetectionStrategy, } from '@angular/core';
|
|
2
|
+
import emojiRegex from 'emoji-regex';
|
|
3
|
+
import { listUsers } from '../list-users';
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
import * as i1 from "../chat-client.service";
|
|
6
|
+
import * as i2 from "../channel.service";
|
|
7
|
+
import * as i3 from "../custom-templates.service";
|
|
8
|
+
import * as i4 from "../date-parser.service";
|
|
9
|
+
import * as i5 from "../message.service";
|
|
10
|
+
import * as i6 from "../message-actions.service";
|
|
11
|
+
import * as i7 from "@angular/common";
|
|
12
|
+
import * as i8 from "ngx-float-ui";
|
|
13
|
+
import * as i9 from "../avatar-placeholder/avatar-placeholder.component";
|
|
14
|
+
import * as i10 from "@ngx-translate/core";
|
|
15
|
+
import * as i11 from "../message-actions-box/message-actions-box.component";
|
|
16
|
+
import * as i12 from "../attachment-list/attachment-list.component";
|
|
17
|
+
import * as i13 from "../message-reactions/message-reactions.component";
|
|
18
|
+
import * as i14 from "../icon-placeholder/icon-placeholder.component";
|
|
19
|
+
import * as i15 from "../loading-indicator-placeholder/loading-indicator-placeholder.component";
|
|
20
|
+
/**
|
|
21
|
+
* The `Message` component displays a message with additional information such as sender and date, and enables [interaction with the message (i.e. edit or react)](../concepts/message-interactions.mdx).
|
|
22
|
+
*/
|
|
23
|
+
export class MessageComponent {
|
|
24
|
+
constructor(chatClientService, channelService, customTemplatesService, cdRef, dateParser, messageService, messageActionsService) {
|
|
25
|
+
this.chatClientService = chatClientService;
|
|
26
|
+
this.channelService = channelService;
|
|
27
|
+
this.customTemplatesService = customTemplatesService;
|
|
28
|
+
this.cdRef = cdRef;
|
|
29
|
+
this.dateParser = dateParser;
|
|
30
|
+
this.messageService = messageService;
|
|
31
|
+
this.messageActionsService = messageActionsService;
|
|
32
|
+
/**
|
|
33
|
+
* The list of [channel capabilities](https://getstream.io/chat/docs/javascript/channel_capabilities/?language=javascript) that are enabled for the current user, the list of [supported interactions](../concepts/message-interactions.mdx) can be found in our message interaction guide. Unathorized actions won't be displayed on the UI. The [`MessageList`](./MessageListComponent.mdx) component automatically sets this based on [channel capabilities](https://getstream.io/chat/docs/javascript/channel_capabilities/?language=javascript).
|
|
34
|
+
*/
|
|
35
|
+
this.enabledMessageActions = [];
|
|
36
|
+
/**
|
|
37
|
+
* Determines if the message is being dispalyed in a channel or in a [thread](https://getstream.io/chat/docs/javascript/threads/?language=javascript).
|
|
38
|
+
*/
|
|
39
|
+
this.mode = 'main';
|
|
40
|
+
/**
|
|
41
|
+
* Highlighting is used to add visual emphasize to a message when jumping to the message
|
|
42
|
+
*/
|
|
43
|
+
this.isHighlighted = false;
|
|
44
|
+
this.isActionBoxOpen = false;
|
|
45
|
+
this.isEditedFlagOpened = false;
|
|
46
|
+
this.isReactionSelectorOpen = false;
|
|
47
|
+
this.visibleMessageActionsCount = 0;
|
|
48
|
+
this.messageTextParts = [];
|
|
49
|
+
this.shouldDisplayTranslationNotice = false;
|
|
50
|
+
this.displayedMessageTextContent = 'original';
|
|
51
|
+
this.imageAttachmentModalState = 'closed';
|
|
52
|
+
this.shouldDisplayThreadLink = false;
|
|
53
|
+
this.isSentByCurrentUser = false;
|
|
54
|
+
this.readByText = '';
|
|
55
|
+
this.lastReadUser = undefined;
|
|
56
|
+
this.isOnlyReadByMe = false;
|
|
57
|
+
this.isReadByMultipleUsers = false;
|
|
58
|
+
this.isMessageDeliveredAndRead = false;
|
|
59
|
+
this.parsedDate = '';
|
|
60
|
+
this.pasedEditedDate = '';
|
|
61
|
+
this.areOptionsVisible = false;
|
|
62
|
+
this.hasAttachment = false;
|
|
63
|
+
this.hasReactions = false;
|
|
64
|
+
this.replyCountParam = {
|
|
65
|
+
replyCount: undefined,
|
|
66
|
+
};
|
|
67
|
+
this.canDisplayReadStatus = false;
|
|
68
|
+
this.subscriptions = [];
|
|
69
|
+
this.isViewInited = false;
|
|
70
|
+
this.urlRegexp = /(?:(?:https?|ftp|file):\/\/|www\.|ftp\.)(?:\([-A-Z0-9+&@#/%=~_|$?!:,.]*\)|[-A-Z0-9+&@#/%=~_|$?!:,.])*(?:\([-A-Z0-9+&@#/%=~_|$?!:,.]*\)|[A-Z0-9+&@#/%=~_|$])/gim;
|
|
71
|
+
this.emojiRegexp = new RegExp(emojiRegex(), 'g');
|
|
72
|
+
this.displayAs = this.messageService.displayAs;
|
|
73
|
+
}
|
|
74
|
+
ngOnInit() {
|
|
75
|
+
this.subscriptions.push(this.chatClientService.user$.subscribe((u) => {
|
|
76
|
+
if (u?.id !== this.userId) {
|
|
77
|
+
this.userId = u?.id;
|
|
78
|
+
this.setIsSentByCurrentUser();
|
|
79
|
+
this.setLastReadUser();
|
|
80
|
+
if (this.isViewInited) {
|
|
81
|
+
this.cdRef.detectChanges();
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}));
|
|
85
|
+
this.subscriptions.push(this.messageActionsService.customActions$.subscribe(() => {
|
|
86
|
+
if (this.message) {
|
|
87
|
+
const numberOfEnabledActions = this.messageActionsService.getAuthorizedMessageActionsCount(this.message, this.enabledMessageActions);
|
|
88
|
+
if (numberOfEnabledActions !== this.visibleMessageActionsCount) {
|
|
89
|
+
this.visibleMessageActionsCount = numberOfEnabledActions;
|
|
90
|
+
if (this.isViewInited) {
|
|
91
|
+
this.cdRef.detectChanges();
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}));
|
|
96
|
+
}
|
|
97
|
+
ngOnChanges(changes) {
|
|
98
|
+
if (changes.message) {
|
|
99
|
+
this.shouldDisplayTranslationNotice = false;
|
|
100
|
+
this.displayedMessageTextContent = 'original';
|
|
101
|
+
this.createMessageParts();
|
|
102
|
+
const originalAttachments = this.message?.quoted_message?.attachments;
|
|
103
|
+
this.quotedMessageAttachments =
|
|
104
|
+
originalAttachments && originalAttachments.length
|
|
105
|
+
? [originalAttachments[0]]
|
|
106
|
+
: [];
|
|
107
|
+
this.setIsSentByCurrentUser();
|
|
108
|
+
this.setLastReadUser();
|
|
109
|
+
this.readByText = this.message?.readBy
|
|
110
|
+
? listUsers(this.message.readBy)
|
|
111
|
+
: '';
|
|
112
|
+
this.isOnlyReadByMe = !!(this.message &&
|
|
113
|
+
this.message.readBy &&
|
|
114
|
+
this.message.readBy.length === 0);
|
|
115
|
+
this.isReadByMultipleUsers = !!(this.message &&
|
|
116
|
+
this.message.readBy &&
|
|
117
|
+
this.message.readBy.length > 1);
|
|
118
|
+
this.isMessageDeliveredAndRead = !!(this.message &&
|
|
119
|
+
this.message.readBy &&
|
|
120
|
+
this.message.status === 'received' &&
|
|
121
|
+
this.message.readBy.length > 0);
|
|
122
|
+
this.parsedDate =
|
|
123
|
+
(this.message &&
|
|
124
|
+
this.message.created_at &&
|
|
125
|
+
this.dateParser.parseDateTime(this.message.created_at)) ||
|
|
126
|
+
'';
|
|
127
|
+
this.pasedEditedDate =
|
|
128
|
+
(this.message &&
|
|
129
|
+
this.message.message_text_updated_at &&
|
|
130
|
+
this.dateParser.parseDateTime(new Date(this.message.message_text_updated_at))) ||
|
|
131
|
+
'';
|
|
132
|
+
this.hasAttachment =
|
|
133
|
+
!!this.message?.attachments && !!this.message.attachments.length;
|
|
134
|
+
this.hasReactions =
|
|
135
|
+
!!this.message?.reaction_counts &&
|
|
136
|
+
Object.keys(this.message.reaction_counts).length > 0;
|
|
137
|
+
this.replyCountParam = { replyCount: this.message?.reply_count };
|
|
138
|
+
}
|
|
139
|
+
if (changes.enabledMessageActions) {
|
|
140
|
+
this.canReactToMessage =
|
|
141
|
+
this.enabledMessageActions.indexOf('send-reaction') !== -1;
|
|
142
|
+
this.canReceiveReadEvents =
|
|
143
|
+
this.enabledMessageActions.indexOf('read-events') !== -1;
|
|
144
|
+
this.canDisplayReadStatus =
|
|
145
|
+
this.canReceiveReadEvents !== false &&
|
|
146
|
+
this.enabledMessageActions.indexOf('read-events') !== -1;
|
|
147
|
+
}
|
|
148
|
+
if (changes.message || changes.enabledMessageActions || changes.mode) {
|
|
149
|
+
this.shouldDisplayThreadLink =
|
|
150
|
+
!!this.message?.reply_count && this.mode !== 'thread';
|
|
151
|
+
}
|
|
152
|
+
if (changes.message || changes.mode) {
|
|
153
|
+
this.areOptionsVisible = this.message
|
|
154
|
+
? !(!this.message.type ||
|
|
155
|
+
this.message.type === 'error' ||
|
|
156
|
+
this.message.type === 'system' ||
|
|
157
|
+
this.message.type === 'ephemeral' ||
|
|
158
|
+
this.message.status === 'failed' ||
|
|
159
|
+
this.message.status === 'sending' ||
|
|
160
|
+
(this.mode === 'thread' && !this.message.parent_id))
|
|
161
|
+
: false;
|
|
162
|
+
}
|
|
163
|
+
if (changes.message || changes.enabledMessageActions) {
|
|
164
|
+
if (this.message) {
|
|
165
|
+
this.visibleMessageActionsCount =
|
|
166
|
+
this.messageActionsService.getAuthorizedMessageActionsCount(this.message, this.enabledMessageActions);
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
this.visibleMessageActionsCount = 0;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
ngAfterViewInit() {
|
|
174
|
+
this.isViewInited = true;
|
|
175
|
+
}
|
|
176
|
+
ngOnDestroy() {
|
|
177
|
+
this.subscriptions.forEach((s) => s.unsubscribe());
|
|
178
|
+
}
|
|
179
|
+
messageActionsClicked() {
|
|
180
|
+
if (!this.message) {
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
if (this.messageActionsService.customActionClickHandler) {
|
|
184
|
+
this.messageActionsService.customActionClickHandler({
|
|
185
|
+
message: this.message,
|
|
186
|
+
enabledActions: this.enabledMessageActions,
|
|
187
|
+
customActions: this.messageActionsService.customActions$.getValue(),
|
|
188
|
+
isMine: this.isSentByCurrentUser,
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
else {
|
|
192
|
+
this.isActionBoxOpen = !this.isActionBoxOpen;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
messageActionsBoxClicked(floatingContent) {
|
|
196
|
+
floatingContent.hide();
|
|
197
|
+
}
|
|
198
|
+
getAttachmentListContext() {
|
|
199
|
+
return {
|
|
200
|
+
messageId: this.message?.id || '',
|
|
201
|
+
attachments: this.message?.attachments || [],
|
|
202
|
+
parentMessageId: this.message?.parent_id,
|
|
203
|
+
imageModalStateChangeHandler: (state) => (this.imageAttachmentModalState = state),
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
getMessageContext() {
|
|
207
|
+
return {
|
|
208
|
+
message: this.message,
|
|
209
|
+
enabledMessageActions: this.enabledMessageActions,
|
|
210
|
+
isHighlighted: this.isHighlighted,
|
|
211
|
+
isLastSentMessage: this.isLastSentMessage,
|
|
212
|
+
mode: this.mode,
|
|
213
|
+
customActions: this.messageActionsService.customActions$.getValue(),
|
|
214
|
+
parsedDate: this.parsedDate,
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
getQuotedMessageAttachmentListContext() {
|
|
218
|
+
return {
|
|
219
|
+
messageId: this.message?.quoted_message?.id || '',
|
|
220
|
+
attachments: this.quotedMessageAttachments,
|
|
221
|
+
parentMessageId: this?.message?.quoted_message?.parent_id,
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
getMessageReactionsContext() {
|
|
225
|
+
return {
|
|
226
|
+
messageReactionCounts: this.message?.reaction_counts || {},
|
|
227
|
+
latestReactions: this.message?.latest_reactions || [],
|
|
228
|
+
isSelectorOpen: this.isReactionSelectorOpen,
|
|
229
|
+
isSelectorOpenChangeHandler: (isOpen) => (this.isReactionSelectorOpen = isOpen),
|
|
230
|
+
messageId: this.message?.id,
|
|
231
|
+
ownReactions: this.message?.own_reactions || [],
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
messageClicked() {
|
|
235
|
+
if (this.message?.status === 'failed' &&
|
|
236
|
+
this.message?.errorStatusCode !== 403) {
|
|
237
|
+
this.resendMessage();
|
|
238
|
+
}
|
|
239
|
+
else if (this.message?.type === 'error' &&
|
|
240
|
+
this.message?.moderation_details) {
|
|
241
|
+
this.openMessageBouncePrompt();
|
|
242
|
+
}
|
|
243
|
+
else {
|
|
244
|
+
this.isEditedFlagOpened = !this.isEditedFlagOpened;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
resendMessage() {
|
|
248
|
+
void this.channelService.resendMessage(this.message);
|
|
249
|
+
}
|
|
250
|
+
setAsActiveParentMessage() {
|
|
251
|
+
void this.channelService.setAsActiveParentMessage(this.message);
|
|
252
|
+
}
|
|
253
|
+
getMentionContext(messagePart) {
|
|
254
|
+
return {
|
|
255
|
+
content: messagePart.content,
|
|
256
|
+
user: messagePart.user,
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
getMessageActionsBoxContext() {
|
|
260
|
+
return {
|
|
261
|
+
isMine: this.isSentByCurrentUser,
|
|
262
|
+
enabledActions: this.enabledMessageActions,
|
|
263
|
+
message: this.message,
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
getDeliveredStatusContext() {
|
|
267
|
+
return {
|
|
268
|
+
message: this.message,
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
getSendingStatusContext() {
|
|
272
|
+
return {
|
|
273
|
+
message: this.message,
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
getReadStatusContext() {
|
|
277
|
+
return {
|
|
278
|
+
message: this.message,
|
|
279
|
+
readByText: this.readByText,
|
|
280
|
+
};
|
|
281
|
+
}
|
|
282
|
+
getMessageMetadataContext() {
|
|
283
|
+
return {
|
|
284
|
+
message: this.message,
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
jumpToMessage(messageId, parentMessageId) {
|
|
288
|
+
void this.channelService.jumpToMessage(messageId, parentMessageId);
|
|
289
|
+
}
|
|
290
|
+
displayTranslatedMessage() {
|
|
291
|
+
this.createMessageParts(true);
|
|
292
|
+
}
|
|
293
|
+
displayOriginalMessage() {
|
|
294
|
+
this.createMessageParts(false);
|
|
295
|
+
}
|
|
296
|
+
openMessageBouncePrompt() {
|
|
297
|
+
this.channelService.bouncedMessage$.next(this.message);
|
|
298
|
+
}
|
|
299
|
+
createMessageParts(shouldTranslate = true) {
|
|
300
|
+
this.messageTextParts = undefined;
|
|
301
|
+
this.messageText = undefined;
|
|
302
|
+
let content = this.getMessageContent(shouldTranslate);
|
|
303
|
+
if ((!this.message.mentioned_users ||
|
|
304
|
+
this.message.mentioned_users.length === 0) &&
|
|
305
|
+
!content?.match(this.emojiRegexp) &&
|
|
306
|
+
!content?.match(this.urlRegexp)) {
|
|
307
|
+
this.messageTextParts = undefined;
|
|
308
|
+
this.messageText = content;
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
if (!content) {
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
if (!this.message.mentioned_users ||
|
|
315
|
+
this.message.mentioned_users.length === 0) {
|
|
316
|
+
content = this.fixEmojiDisplay(content);
|
|
317
|
+
content = this.wrapLinksWithAnchorTag(content);
|
|
318
|
+
this.messageTextParts = [{ content, type: 'text' }];
|
|
319
|
+
}
|
|
320
|
+
else {
|
|
321
|
+
this.messageTextParts = [];
|
|
322
|
+
let text = content;
|
|
323
|
+
this.message.mentioned_users.forEach((user) => {
|
|
324
|
+
const mention = `@${user.name || user.id}`;
|
|
325
|
+
const precedingText = text.substring(0, text.indexOf(mention));
|
|
326
|
+
let formattedPrecedingText = this.fixEmojiDisplay(precedingText);
|
|
327
|
+
formattedPrecedingText = this.wrapLinksWithAnchorTag(formattedPrecedingText);
|
|
328
|
+
this.messageTextParts.push({
|
|
329
|
+
content: formattedPrecedingText,
|
|
330
|
+
type: 'text',
|
|
331
|
+
});
|
|
332
|
+
this.messageTextParts.push({
|
|
333
|
+
content: mention,
|
|
334
|
+
type: 'mention',
|
|
335
|
+
user,
|
|
336
|
+
});
|
|
337
|
+
text = text.replace(precedingText + mention, '');
|
|
338
|
+
});
|
|
339
|
+
if (text) {
|
|
340
|
+
text = this.fixEmojiDisplay(text);
|
|
341
|
+
text = this.wrapLinksWithAnchorTag(text);
|
|
342
|
+
this.messageTextParts.push({ content: text, type: 'text' });
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
getMessageContent(shouldTranslate) {
|
|
347
|
+
const originalContent = this.message?.text;
|
|
348
|
+
if (shouldTranslate) {
|
|
349
|
+
const translation = this.message?.translation;
|
|
350
|
+
if (translation) {
|
|
351
|
+
this.shouldDisplayTranslationNotice = true;
|
|
352
|
+
this.displayedMessageTextContent = 'translation';
|
|
353
|
+
}
|
|
354
|
+
return translation || originalContent;
|
|
355
|
+
}
|
|
356
|
+
else {
|
|
357
|
+
this.displayedMessageTextContent = 'original';
|
|
358
|
+
return originalContent;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
fixEmojiDisplay(content) {
|
|
362
|
+
// Wrap emojis in span to display emojis correctly in Chrome https://bugs.chromium.org/p/chromium/issues/detail?id=596223
|
|
363
|
+
// Based on this: https://stackoverflow.com/questions/4565112/javascript-how-to-find-out-if-the-user-browser-is-chrome
|
|
364
|
+
/* eslint-disable @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any */
|
|
365
|
+
const isChrome = !!window.chrome && typeof window.opr === 'undefined';
|
|
366
|
+
/* eslint-enable @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any */
|
|
367
|
+
content = content.replace(this.emojiRegexp, (match) => `<span ${isChrome ? 'class="str-chat__emoji-display-fix"' : ''}>${match}</span>`);
|
|
368
|
+
return content;
|
|
369
|
+
}
|
|
370
|
+
wrapLinksWithAnchorTag(content) {
|
|
371
|
+
if (this.displayAs === 'html') {
|
|
372
|
+
return content;
|
|
373
|
+
}
|
|
374
|
+
content = content.replace(this.urlRegexp, (match) => this.messageService.customLinkRenderer
|
|
375
|
+
? this.messageService.customLinkRenderer(match)
|
|
376
|
+
: `<a href="${match}" target="_blank" rel="nofollow">${match}</a>`);
|
|
377
|
+
return content;
|
|
378
|
+
}
|
|
379
|
+
setIsSentByCurrentUser() {
|
|
380
|
+
this.isSentByCurrentUser = this.message?.user?.id === this.userId;
|
|
381
|
+
}
|
|
382
|
+
setLastReadUser() {
|
|
383
|
+
this.lastReadUser = this.message?.readBy?.filter((u) => u.id !== this.userId)[0];
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
MessageComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: MessageComponent, deps: [{ token: i1.ChatClientService }, { token: i2.ChannelService }, { token: i3.CustomTemplatesService }, { token: i0.ChangeDetectorRef }, { token: i4.DateParserService }, { token: i5.MessageService }, { token: i6.MessageActionsService }], target: i0.ɵɵFactoryTarget.Component });
|
|
387
|
+
MessageComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: MessageComponent, selector: "stream-message", inputs: { message: "message", enabledMessageActions: "enabledMessageActions", isLastSentMessage: "isLastSentMessage", mode: "mode", isHighlighted: "isHighlighted" }, usesOnChanges: true, ngImport: i0, template: "<div\n #container\n data-testid=\"message-container\"\n class=\"str-chat__message-simple str-chat__message str-chat__message--{{\n message?.type\n }} str-chat__message--{{ message?.status }} {{\n message?.text ? 'str-chat__message--has-text' : 'has-no-text'\n }}\"\n [class.str-chat__message--me]=\"isSentByCurrentUser\"\n [class.str-chat__message--other]=\"!isSentByCurrentUser\"\n [class.str-chat__message-simple--me]=\"isSentByCurrentUser\"\n [class.str-chat__message--has-attachment]=\"hasAttachment\"\n [class.str-chat__message--with-reactions]=\"hasReactions\"\n [class.str-chat__message--highlighted]=\"isHighlighted\"\n [class.str-chat__message-with-thread-link]=\"shouldDisplayThreadLink\"\n [class.str-chat__message-send-can-be-retried]=\"\n (message?.status === 'failed' && message?.errorStatusCode !== 403) ||\n (message?.type === 'error' && message?.moderation_details)\n \"\n>\n <ng-container *ngIf=\"!message?.deleted_at; else deletedMessage\">\n <ng-container *ngIf=\"message?.type !== 'system'; else systemMessage\">\n <stream-avatar-placeholder\n data-testid=\"avatar\"\n class=\"str-chat-angular__avatar-host str-chat__message-sender-avatar\"\n type=\"user\"\n location=\"message-sender\"\n [imageUrl]=\"message?.user?.image\"\n [name]=\"message?.user?.name || message?.user?.id\"\n [user]=\"message?.user || undefined\"\n ></stream-avatar-placeholder>\n <div class=\"str-chat__message-inner\">\n <div\n *ngIf=\"areOptionsVisible\"\n class=\"str-chat__message-simple__actions str-chat__message-options\"\n data-testid=\"message-options\"\n [class.str-chat__message-actions-open]=\"isActionBoxOpen\"\n >\n <div\n #messageActionsToggle\n data-testid=\"message-actions-container\"\n class=\"\n str-chat__message-actions-container\n str-chat__message-simple__actions__action\n str-chat__message-simple__actions__action--options\n \"\n [floatUiLoose]=\"floatingContent\"\n looseTrigger=\"click\"\n [hideOnScroll]=\"false\"\n [hideOnClickOutside]=\"true\"\n [hideOnMouseLeave]=\"false\"\n [disableAnimation]=\"true\"\n (onHidden)=\"isActionBoxOpen = false\"\n >\n <float-ui-content #floatingContent>\n <ng-template\n #defaultMessageActionsBox\n let-isMine=\"isMine\"\n let-messageInput=\"message\"\n let-enabledActions=\"enabledActions\"\n >\n <stream-message-actions-box\n [isMine]=\"isMine\"\n [message]=\"messageInput\"\n [enabledActions]=\"enabledActions\"\n (click)=\"messageActionsBoxClicked(floatingContent)\"\n ></stream-message-actions-box>\n </ng-template>\n <ng-container *ngIf=\"isActionBoxOpen\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.messageActionsBoxTemplate$\n | async) || defaultMessageActionsBox;\n context: getMessageActionsBoxContext()\n \"\n >\n </ng-container>\n </ng-container>\n </float-ui-content>\n <div\n *ngIf=\"visibleMessageActionsCount > 0\"\n class=\"str-chat__message-actions-box-button\"\n data-testid=\"action-icon\"\n (click)=\"messageActionsClicked()\"\n (keyup.enter)=\"messageActionsClicked()\"\n >\n <stream-icon-placeholder\n icon=\"action-icon\"\n class=\"str-chat__message-action-icon\"\n ></stream-icon-placeholder>\n </div>\n </div>\n <div\n *ngIf=\"\n enabledMessageActions.indexOf('send-reply') !== -1 &&\n mode === 'main'\n \"\n class=\"\n str-chat__message-simple__actions__action\n str-chat__message-simple__actions__action--thread\n str-chat__message-reply-in-thread-button\n \"\n data-testid=\"reply-in-thread\"\n (click)=\"setAsActiveParentMessage()\"\n (keyup.enter)=\"setAsActiveParentMessage()\"\n >\n <stream-icon-placeholder\n class=\"str-chat__message-action-icon\"\n icon=\"reply-in-thread\"\n ></stream-icon-placeholder>\n </div>\n <div\n *ngIf=\"canReactToMessage\"\n class=\"\n str-chat__message-simple__actions__action\n str-chat__message-simple__actions__action--reactions\n str-chat__message-reactions-button\n \"\n data-testid=\"reaction-icon\"\n (click)=\"isReactionSelectorOpen = !isReactionSelectorOpen\"\n (keyup.enter)=\"isReactionSelectorOpen = !isReactionSelectorOpen\"\n >\n <stream-icon-placeholder\n class=\"str-chat__message-action-icon\"\n icon=\"reaction-icon\"\n ></stream-icon-placeholder>\n </div>\n </div>\n <div class=\"str-chat__message-reactions-host\">\n <ng-template\n #defaultMessageReactions\n let-messageReactionCounts=\"messageReactionCounts\"\n let-latestReactions=\"latestReactions\"\n let-isSelectorOpen=\"isSelectorOpen\"\n let-isSelectorOpenChangeHandler=\"isSelectorOpenChangeHandler\"\n let-messageId=\"messageId\"\n let-ownReactions=\"ownReactions\"\n >\n <stream-message-reactions\n [messageReactionCounts]=\"messageReactionCounts\"\n [latestReactions]=\"latestReactions\"\n [isSelectorOpen]=\"isSelectorOpen\"\n [messageId]=\"messageId\"\n [ownReactions]=\"ownReactions\"\n (isSelectorOpenChange)=\"isSelectorOpenChangeHandler($event)\"\n ></stream-message-reactions>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.messageReactionsTemplate$ | async) ||\n defaultMessageReactions;\n context: getMessageReactionsContext()\n \"\n ></ng-container>\n </div>\n <div\n class=\"str-chat__message-bubble str-chat-angular__message-bubble\"\n [class.str-chat-angular__message-bubble--attachment-modal-open]=\"\n imageAttachmentModalState === 'opened'\n \"\n >\n <ng-container *ngIf=\"hasAttachment && !message?.quoted_message\">\n <ng-container\n *ngTemplateOutlet=\"attachmentsTemplate\"\n ></ng-container>\n </ng-container>\n <div\n *ngIf=\"message?.text || (message?.quoted_message && hasAttachment)\"\n class=\"str-chat__message-text\"\n tabindex=\"0\"\n [class.str-chat__message-text--pointer-cursor]=\"\n (message?.status === 'failed' &&\n message?.errorStatusCode !== 403) ||\n (this.message?.type === 'error' &&\n this.message?.moderation_details) ||\n message?.message_text_updated_at\n \"\n (click)=\"messageClicked()\"\n (keyup.enter)=\"messageClicked()\"\n >\n <div\n data-testid=\"inner-message\"\n class=\"\n str-chat__message-text-inner str-chat__message-simple-text-inner\n \"\n [class.str-chat__message-light-text-inner--has-attachment]=\"\n hasAttachment\n \"\n >\n <ng-container *ngTemplateOutlet=\"quotedMessage\"></ng-container>\n <ng-container *ngIf=\"hasAttachment && message?.quoted_message\">\n <ng-container\n *ngTemplateOutlet=\"attachmentsTemplate\"\n ></ng-container>\n </ng-container>\n <div\n *ngIf=\"message?.type === 'error'\"\n data-testid=\"client-error-message\"\n class=\"\n str-chat__simple-message--error-message\n str-chat__message--error-message\n \"\n >\n <ng-container *ngIf=\"!message?.moderation_details\">{{\n \"streamChat.Error \u00B7 Unsent\" | translate\n }}</ng-container>\n </div>\n <div\n *ngIf=\"message?.status === 'failed'\"\n data-testid=\"error-message\"\n class=\"\n str-chat__simple-message--error-message\n str-chat__message--error-message\n \"\n >\n {{\n (message?.errorStatusCode === 403\n ? \"streamChat.Message Failed \u00B7 Unauthorized\"\n : \"streamChat.Message Failed \u00B7 Click to try again\"\n ) | translate\n }}\n </div>\n <div data-testid=\"text\">\n <p>\n <ng-container *ngIf=\"messageTextParts; else defaultContent\">\n <!-- eslint-disable-next-line @angular-eslint/template/use-track-by-function -->\n <ng-container *ngFor=\"let part of messageTextParts\">\n <span\n *ngIf=\"part.type === 'text'; else mention\"\n [innerHTML]=\"part.content\"\n ></span>\n <ng-template #mention>\n <ng-template #defaultMention let-content=\"content\">\n <span class=\"str-chat__message-mention\">{{\n content\n }}</span>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.mentionTemplate$ | async) ||\n defaultMention;\n context: getMentionContext(part)\n \"\n ></ng-container>\n </ng-template>\n </ng-container>\n </ng-container>\n <ng-template #defaultContent>\n <ng-container *ngIf=\"displayAs === 'text'; else asHTML\">\n {{ messageText || \"\" }}\n </ng-container>\n <ng-template #asHTML\n ><span\n data-testid=\"html-content\"\n [innerHTML]=\"messageText\"\n ></span\n ></ng-template>\n </ng-template>\n </p>\n </div>\n </div>\n </div>\n <stream-icon-placeholder\n class=\"str-chat__message-error-icon\"\n icon=\"error\"\n ></stream-icon-placeholder>\n </div>\n </div>\n <ng-container\n *ngTemplateOutlet=\"replyCountButton; context: { message: message }\"\n ></ng-container>\n\n <ng-container *ngTemplateOutlet=\"messageDateAndSender\"></ng-container>\n </ng-container>\n </ng-container>\n</div>\n\n<ng-template #deletedMessage>\n <div data-testid=\"message-deleted-component\">\n <div class=\"str-chat__message--deleted-inner\" translate>\n streamChat.This message was deleted...\n </div>\n </div>\n</ng-template>\n\n<ng-template #systemMessage>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.systemMessageTemplate$ | async) ||\n defaultSystemMessage;\n context: getMessageContext()\n \"\n ></ng-container>\n <ng-template #defaultSystemMessage let-messageInput=\"message\">\n <div data-testid=\"system-message\" class=\"str-chat__message--system\">\n <div class=\"str-chat__message--system__text\">\n <div class=\"str-chat__message--system__line\"></div>\n <p>{{ messageInput?.text }}</p>\n <div class=\"str-chat__message--system__line\"></div>\n </div>\n <div class=\"str-chat__message--system__date\">\n {{ parsedDate }}\n </div>\n </div>\n </ng-template>\n</ng-template>\n\n<ng-template #quotedMessage>\n <div\n *ngIf=\"message?.quoted_message\"\n class=\"quoted-message str-chat__quoted-message-preview\"\n data-testid=\"quoted-message-container\"\n [class.mine]=\"isSentByCurrentUser\"\n (click)=\"\n jumpToMessage(\n (message?.quoted_message)!.id,\n message?.quoted_message?.parent_id\n )\n \"\n (keyup.enter)=\"\n jumpToMessage(\n (message?.quoted_message)!.id,\n message?.quoted_message?.parent_id\n )\n \"\n >\n <stream-avatar-placeholder\n data-testid=\"qouted-message-avatar\"\n class=\"str-chat-angular__avatar-host str-chat__message-sender-avatar\"\n type=\"user\"\n location=\"quoted-message-sender\"\n [imageUrl]=\"message?.quoted_message?.user?.image\"\n [name]=\"\n message?.quoted_message?.user?.name || message?.quoted_message?.user?.id\n \"\n [size]=\"20\"\n [user]=\"message?.quoted_message?.user || undefined\"\n ></stream-avatar-placeholder>\n <div class=\"quoted-message-inner str-chat__quoted-message-bubble\">\n <ng-container\n *ngIf=\"\n message?.quoted_message?.attachments &&\n message?.quoted_message?.attachments?.length\n \"\n >\n <ng-template\n #defaultAttachments\n let-messageId=\"messageId\"\n let-attachments=\"attachments\"\n let-parentMessageId=\"parentMessageId\"\n let-imageModalStateChangeHandler=\"imageModalStateChangeHandler\"\n >\n <stream-attachment-list\n [messageId]=\"messageId\"\n [attachments]=\"attachments\"\n [parentMessageId]=\"parentMessageId\"\n (imageModalStateChange)=\"imageModalStateChangeHandler($event)\"\n ></stream-attachment-list>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.attachmentListTemplate$ | async) ||\n defaultAttachments;\n context: getQuotedMessageAttachmentListContext()\n \"\n ></ng-container>\n </ng-container>\n <div\n data-testid=\"quoted-message-text\"\n [innerHTML]=\"\n message?.quoted_message?.translation ||\n message?.quoted_message?.html ||\n message?.quoted_message?.text\n \"\n ></div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #messageDateAndSender>\n <ng-container>\n <div\n *ngIf=\"shouldDisplayTranslationNotice\"\n class=\"str-chat__translation-notice\"\n data-testid=\"translation-notice\"\n >\n <button\n *ngIf=\"displayedMessageTextContent === 'translation'\"\n data-testid=\"see-original\"\n translate\n (click)=\"displayOriginalMessage()\"\n (keyup.enter)=\"displayOriginalMessage()\"\n >\n streamChat.See original (automatically translated)\n </button>\n <button\n *ngIf=\"displayedMessageTextContent === 'original'\"\n data-testid=\"see-translation\"\n translate\n (click)=\"displayTranslatedMessage()\"\n (keyup.enter)=\"displayTranslatedMessage()\"\n >\n streamChat.See translation\n </button>\n </div>\n <ng-container\n *ngIf=\"customTemplatesService.customMessageMetadataTemplate$ | async\"\n >\n <div class=\"str-chat__custom-message-metadata\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.customMessageMetadataTemplate$ | async)!;\n context: getMessageMetadataContext()\n \"\n ></ng-container>\n </div>\n </ng-container>\n <div\n class=\"\n str-chat__message-data\n str-chat__message-simple-data\n str-chat__message-metadata\n \"\n >\n <ng-container *ngTemplateOutlet=\"messageStatus\"></ng-container>\n\n <span\n *ngIf=\"!isSentByCurrentUser\"\n data-testid=\"sender\"\n class=\"str-chat__message-simple-name str-chat__message-sender-name\"\n >\n {{ message?.user?.name ? message?.user?.name : message?.user?.id }}\n </span>\n <span\n data-testid=\"date\"\n class=\"str-chat__message-simple-timestamp str-chat__message-simple-time\"\n >\n {{ parsedDate }}\n </span>\n <ng-container *ngIf=\"message?.message_text_updated_at\">\n <span\n data-testid=\"edited-flag\"\n class=\"str-chat__mesage-simple-edited\"\n translate\n >streamChat.Edited</span\n >\n <div\n data-testid=\"edited-timestamp\"\n class=\"str-chat__message-edited-timestamp\"\n [ngClass]=\"{\n 'str-chat__message-edited-timestamp--open': isEditedFlagOpened,\n 'str-chat__message-edited-timestamp--collapsed': !isEditedFlagOpened\n }\"\n >\n <span translate>streamChat.Edited</span>\n <time\n dateTime=\"{{ message?.message_text_updated_at }}\"\n title=\"{{ message?.message_text_updated_at }}\"\n >\n {{ pasedEditedDate }}\n </time>\n </div>\n </ng-container>\n </div>\n </ng-container>\n</ng-template>\n\n<ng-template #messageStatus>\n <ng-container\n *ngIf=\"\n isSentByCurrentUser &&\n ((isLastSentMessage && message?.status === 'received') ||\n message?.status === 'sending')\n \"\n >\n <ng-container *ngIf=\"message?.status === 'sending'; else sentStatus\">\n <ng-container *ngTemplateOutlet=\"sendingStatus\"></ng-container>\n </ng-container>\n <ng-template #sentStatus>\n <ng-container\n *ngIf=\"\n mode === 'main' && isMessageDeliveredAndRead && canDisplayReadStatus;\n else deliveredStatus\n \"\n >\n <ng-container *ngTemplateOutlet=\"readStatus\"></ng-container>\n </ng-container>\n </ng-template>\n <ng-template #deliveredStatus>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.deliveredStatusTemplate$ | async) ||\n defaultDeliveredStatus;\n context: getDeliveredStatusContext()\n \"\n ></ng-container>\n </ng-template>\n <ng-template #defaultDeliveredStatus>\n <span\n *ngIf=\"mode === 'main'\"\n class=\"\n str-chat__message-simple-status\n str-chat__message-simple-status-angular\n str-chat__message-status\n \"\n data-testid=\"delivered-indicator\"\n tabindex=\"0\"\n [floatUiLoose]=\"floatingContent\"\n looseTrigger=\"hover\"\n >\n <float-ui-content #floatingContent>\n <div class=\"str-chat__tooltip str-chat__tooltip-angular\">\n {{ \"streamChat.Delivered\" | translate }}\n </div>\n </float-ui-content>\n <stream-icon-placeholder\n data-testid=\"delivered-icon\"\n icon=\"delivered-icon\"\n ></stream-icon-placeholder>\n </span>\n </ng-template>\n <ng-template #sendingStatus>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.sendingStatusTemplate$ | async) ||\n defaultSendingStatus;\n context: getSendingStatusContext()\n \"\n ></ng-container>\n </ng-template>\n <ng-template #defaultSendingStatus>\n <span\n class=\"\n str-chat__message-simple-status\n str-chat__message-simple-status-angular\n str-chat__message-status\n \"\n data-testid=\"sending-indicator\"\n tabindex=\"0\"\n [floatUiLoose]=\"floatingContent\"\n looseTrigger=\"hover\"\n >\n <float-ui-content #floatingContent>\n <div class=\"str-chat__tooltip str-chat__tooltip-angular\">\n {{ \"streamChat.Sending...\" | translate }}\n </div>\n </float-ui-content>\n <stream-loading-indicator-placeholder\n data-testid=\"loading-indicator\"\n ></stream-loading-indicator-placeholder>\n </span>\n </ng-template>\n <ng-template #readStatus>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.readStatusTemplate$ | async) ||\n defaultReadStatus;\n context: getReadStatusContext()\n \"\n ></ng-container>\n </ng-template>\n <ng-template #defaultReadStatus>\n <span\n class=\"\n str-chat__message-simple-status\n str-chat__message-simple-status-angular\n str-chat__message-status\n \"\n data-testid=\"read-indicator\"\n tabindex=\"0\"\n [floatUiLoose]=\"floatingContent\"\n looseTrigger=\"hover\"\n >\n <float-ui-content #floatingContent>\n <div\n class=\"str-chat__tooltip str-chat__tooltip-angular\"\n data-testid=\"read-by-tooltip\"\n >\n {{ readByText }}\n </div>\n </float-ui-content>\n <stream-icon-placeholder icon=\"read-icon\"></stream-icon-placeholder>\n </span>\n </ng-template>\n </ng-container>\n</ng-template>\n\n<ng-template #replyCountButton>\n <div\n class=\"\n str-chat__message-simple-reply-button\n str-chat__message-replies-count-button-wrapper\n \"\n >\n <button\n *ngIf=\"shouldDisplayThreadLink\"\n class=\"str-chat__message-replies-count-button\"\n data-testid=\"reply-count-button\"\n (click)=\"setAsActiveParentMessage()\"\n >\n {{message?.reply_count === 1 ? ('streamChat.1 reply' | translate) : ('streamChat.{{ replyCount }}\n replies' | translate:replyCountParam)}}\n </button>\n </div>\n</ng-template>\n\n<ng-template #attachmentsTemplate>\n <ng-template\n #defaultAttachments\n let-messageId=\"messageId\"\n let-attachments=\"attachments\"\n let-parentMessageId=\"parentMessageId\"\n let-imageModalStateChangeHandler=\"imageModalStateChangeHandler\"\n >\n <stream-attachment-list\n [messageId]=\"messageId\"\n [attachments]=\"attachments\"\n [parentMessageId]=\"parentMessageId\"\n (imageModalStateChange)=\"imageModalStateChangeHandler($event)\"\n ></stream-attachment-list>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.attachmentListTemplate$ | async) ||\n defaultAttachments;\n context: getAttachmentListContext()\n \"\n ></ng-container>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i7.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i7.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i7.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i8.NgxFloatUiContentComponent, selector: "float-ui-content", exportAs: ["ngxFloatUiContent"] }, { kind: "directive", type: i8.NgxFloatUiLooseDirective, selector: "[floatUiLoose]", inputs: ["floatUiLoose", "loosePlacement", "looseTrigger"], exportAs: ["floatUiLoose"] }, { kind: "component", type: i9.AvatarPlaceholderComponent, selector: "stream-avatar-placeholder", inputs: ["name", "imageUrl", "size", "location", "channel", "user", "type", "initialsType", "showOnlineIndicator"] }, { kind: "directive", type: i10.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { kind: "component", type: i11.MessageActionsBoxComponent, selector: "stream-message-actions-box", inputs: ["isMine", "message", "enabledActions"] }, { kind: "component", type: i12.AttachmentListComponent, selector: "stream-attachment-list", inputs: ["messageId", "parentMessageId", "attachments"], outputs: ["imageModalStateChange"] }, { kind: "component", type: i13.MessageReactionsComponent, selector: "stream-message-reactions", inputs: ["messageId", "messageReactionCounts", "isSelectorOpen", "latestReactions", "ownReactions"], outputs: ["isSelectorOpenChange"] }, { kind: "component", type: i14.IconPlaceholderComponent, selector: "stream-icon-placeholder", inputs: ["icon", "size"] }, { kind: "component", type: i15.LoadingIndicatorPlaceholderComponent, selector: "stream-loading-indicator-placeholder", inputs: ["size", "color"] }, { kind: "pipe", type: i7.AsyncPipe, name: "async" }, { kind: "pipe", type: i10.TranslatePipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
388
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: MessageComponent, decorators: [{
|
|
389
|
+
type: Component,
|
|
390
|
+
args: [{ selector: 'stream-message', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div\n #container\n data-testid=\"message-container\"\n class=\"str-chat__message-simple str-chat__message str-chat__message--{{\n message?.type\n }} str-chat__message--{{ message?.status }} {{\n message?.text ? 'str-chat__message--has-text' : 'has-no-text'\n }}\"\n [class.str-chat__message--me]=\"isSentByCurrentUser\"\n [class.str-chat__message--other]=\"!isSentByCurrentUser\"\n [class.str-chat__message-simple--me]=\"isSentByCurrentUser\"\n [class.str-chat__message--has-attachment]=\"hasAttachment\"\n [class.str-chat__message--with-reactions]=\"hasReactions\"\n [class.str-chat__message--highlighted]=\"isHighlighted\"\n [class.str-chat__message-with-thread-link]=\"shouldDisplayThreadLink\"\n [class.str-chat__message-send-can-be-retried]=\"\n (message?.status === 'failed' && message?.errorStatusCode !== 403) ||\n (message?.type === 'error' && message?.moderation_details)\n \"\n>\n <ng-container *ngIf=\"!message?.deleted_at; else deletedMessage\">\n <ng-container *ngIf=\"message?.type !== 'system'; else systemMessage\">\n <stream-avatar-placeholder\n data-testid=\"avatar\"\n class=\"str-chat-angular__avatar-host str-chat__message-sender-avatar\"\n type=\"user\"\n location=\"message-sender\"\n [imageUrl]=\"message?.user?.image\"\n [name]=\"message?.user?.name || message?.user?.id\"\n [user]=\"message?.user || undefined\"\n ></stream-avatar-placeholder>\n <div class=\"str-chat__message-inner\">\n <div\n *ngIf=\"areOptionsVisible\"\n class=\"str-chat__message-simple__actions str-chat__message-options\"\n data-testid=\"message-options\"\n [class.str-chat__message-actions-open]=\"isActionBoxOpen\"\n >\n <div\n #messageActionsToggle\n data-testid=\"message-actions-container\"\n class=\"\n str-chat__message-actions-container\n str-chat__message-simple__actions__action\n str-chat__message-simple__actions__action--options\n \"\n [floatUiLoose]=\"floatingContent\"\n looseTrigger=\"click\"\n [hideOnScroll]=\"false\"\n [hideOnClickOutside]=\"true\"\n [hideOnMouseLeave]=\"false\"\n [disableAnimation]=\"true\"\n (onHidden)=\"isActionBoxOpen = false\"\n >\n <float-ui-content #floatingContent>\n <ng-template\n #defaultMessageActionsBox\n let-isMine=\"isMine\"\n let-messageInput=\"message\"\n let-enabledActions=\"enabledActions\"\n >\n <stream-message-actions-box\n [isMine]=\"isMine\"\n [message]=\"messageInput\"\n [enabledActions]=\"enabledActions\"\n (click)=\"messageActionsBoxClicked(floatingContent)\"\n ></stream-message-actions-box>\n </ng-template>\n <ng-container *ngIf=\"isActionBoxOpen\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.messageActionsBoxTemplate$\n | async) || defaultMessageActionsBox;\n context: getMessageActionsBoxContext()\n \"\n >\n </ng-container>\n </ng-container>\n </float-ui-content>\n <div\n *ngIf=\"visibleMessageActionsCount > 0\"\n class=\"str-chat__message-actions-box-button\"\n data-testid=\"action-icon\"\n (click)=\"messageActionsClicked()\"\n (keyup.enter)=\"messageActionsClicked()\"\n >\n <stream-icon-placeholder\n icon=\"action-icon\"\n class=\"str-chat__message-action-icon\"\n ></stream-icon-placeholder>\n </div>\n </div>\n <div\n *ngIf=\"\n enabledMessageActions.indexOf('send-reply') !== -1 &&\n mode === 'main'\n \"\n class=\"\n str-chat__message-simple__actions__action\n str-chat__message-simple__actions__action--thread\n str-chat__message-reply-in-thread-button\n \"\n data-testid=\"reply-in-thread\"\n (click)=\"setAsActiveParentMessage()\"\n (keyup.enter)=\"setAsActiveParentMessage()\"\n >\n <stream-icon-placeholder\n class=\"str-chat__message-action-icon\"\n icon=\"reply-in-thread\"\n ></stream-icon-placeholder>\n </div>\n <div\n *ngIf=\"canReactToMessage\"\n class=\"\n str-chat__message-simple__actions__action\n str-chat__message-simple__actions__action--reactions\n str-chat__message-reactions-button\n \"\n data-testid=\"reaction-icon\"\n (click)=\"isReactionSelectorOpen = !isReactionSelectorOpen\"\n (keyup.enter)=\"isReactionSelectorOpen = !isReactionSelectorOpen\"\n >\n <stream-icon-placeholder\n class=\"str-chat__message-action-icon\"\n icon=\"reaction-icon\"\n ></stream-icon-placeholder>\n </div>\n </div>\n <div class=\"str-chat__message-reactions-host\">\n <ng-template\n #defaultMessageReactions\n let-messageReactionCounts=\"messageReactionCounts\"\n let-latestReactions=\"latestReactions\"\n let-isSelectorOpen=\"isSelectorOpen\"\n let-isSelectorOpenChangeHandler=\"isSelectorOpenChangeHandler\"\n let-messageId=\"messageId\"\n let-ownReactions=\"ownReactions\"\n >\n <stream-message-reactions\n [messageReactionCounts]=\"messageReactionCounts\"\n [latestReactions]=\"latestReactions\"\n [isSelectorOpen]=\"isSelectorOpen\"\n [messageId]=\"messageId\"\n [ownReactions]=\"ownReactions\"\n (isSelectorOpenChange)=\"isSelectorOpenChangeHandler($event)\"\n ></stream-message-reactions>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.messageReactionsTemplate$ | async) ||\n defaultMessageReactions;\n context: getMessageReactionsContext()\n \"\n ></ng-container>\n </div>\n <div\n class=\"str-chat__message-bubble str-chat-angular__message-bubble\"\n [class.str-chat-angular__message-bubble--attachment-modal-open]=\"\n imageAttachmentModalState === 'opened'\n \"\n >\n <ng-container *ngIf=\"hasAttachment && !message?.quoted_message\">\n <ng-container\n *ngTemplateOutlet=\"attachmentsTemplate\"\n ></ng-container>\n </ng-container>\n <div\n *ngIf=\"message?.text || (message?.quoted_message && hasAttachment)\"\n class=\"str-chat__message-text\"\n tabindex=\"0\"\n [class.str-chat__message-text--pointer-cursor]=\"\n (message?.status === 'failed' &&\n message?.errorStatusCode !== 403) ||\n (this.message?.type === 'error' &&\n this.message?.moderation_details) ||\n message?.message_text_updated_at\n \"\n (click)=\"messageClicked()\"\n (keyup.enter)=\"messageClicked()\"\n >\n <div\n data-testid=\"inner-message\"\n class=\"\n str-chat__message-text-inner str-chat__message-simple-text-inner\n \"\n [class.str-chat__message-light-text-inner--has-attachment]=\"\n hasAttachment\n \"\n >\n <ng-container *ngTemplateOutlet=\"quotedMessage\"></ng-container>\n <ng-container *ngIf=\"hasAttachment && message?.quoted_message\">\n <ng-container\n *ngTemplateOutlet=\"attachmentsTemplate\"\n ></ng-container>\n </ng-container>\n <div\n *ngIf=\"message?.type === 'error'\"\n data-testid=\"client-error-message\"\n class=\"\n str-chat__simple-message--error-message\n str-chat__message--error-message\n \"\n >\n <ng-container *ngIf=\"!message?.moderation_details\">{{\n \"streamChat.Error \u00B7 Unsent\" | translate\n }}</ng-container>\n </div>\n <div\n *ngIf=\"message?.status === 'failed'\"\n data-testid=\"error-message\"\n class=\"\n str-chat__simple-message--error-message\n str-chat__message--error-message\n \"\n >\n {{\n (message?.errorStatusCode === 403\n ? \"streamChat.Message Failed \u00B7 Unauthorized\"\n : \"streamChat.Message Failed \u00B7 Click to try again\"\n ) | translate\n }}\n </div>\n <div data-testid=\"text\">\n <p>\n <ng-container *ngIf=\"messageTextParts; else defaultContent\">\n <!-- eslint-disable-next-line @angular-eslint/template/use-track-by-function -->\n <ng-container *ngFor=\"let part of messageTextParts\">\n <span\n *ngIf=\"part.type === 'text'; else mention\"\n [innerHTML]=\"part.content\"\n ></span>\n <ng-template #mention>\n <ng-template #defaultMention let-content=\"content\">\n <span class=\"str-chat__message-mention\">{{\n content\n }}</span>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.mentionTemplate$ | async) ||\n defaultMention;\n context: getMentionContext(part)\n \"\n ></ng-container>\n </ng-template>\n </ng-container>\n </ng-container>\n <ng-template #defaultContent>\n <ng-container *ngIf=\"displayAs === 'text'; else asHTML\">\n {{ messageText || \"\" }}\n </ng-container>\n <ng-template #asHTML\n ><span\n data-testid=\"html-content\"\n [innerHTML]=\"messageText\"\n ></span\n ></ng-template>\n </ng-template>\n </p>\n </div>\n </div>\n </div>\n <stream-icon-placeholder\n class=\"str-chat__message-error-icon\"\n icon=\"error\"\n ></stream-icon-placeholder>\n </div>\n </div>\n <ng-container\n *ngTemplateOutlet=\"replyCountButton; context: { message: message }\"\n ></ng-container>\n\n <ng-container *ngTemplateOutlet=\"messageDateAndSender\"></ng-container>\n </ng-container>\n </ng-container>\n</div>\n\n<ng-template #deletedMessage>\n <div data-testid=\"message-deleted-component\">\n <div class=\"str-chat__message--deleted-inner\" translate>\n streamChat.This message was deleted...\n </div>\n </div>\n</ng-template>\n\n<ng-template #systemMessage>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.systemMessageTemplate$ | async) ||\n defaultSystemMessage;\n context: getMessageContext()\n \"\n ></ng-container>\n <ng-template #defaultSystemMessage let-messageInput=\"message\">\n <div data-testid=\"system-message\" class=\"str-chat__message--system\">\n <div class=\"str-chat__message--system__text\">\n <div class=\"str-chat__message--system__line\"></div>\n <p>{{ messageInput?.text }}</p>\n <div class=\"str-chat__message--system__line\"></div>\n </div>\n <div class=\"str-chat__message--system__date\">\n {{ parsedDate }}\n </div>\n </div>\n </ng-template>\n</ng-template>\n\n<ng-template #quotedMessage>\n <div\n *ngIf=\"message?.quoted_message\"\n class=\"quoted-message str-chat__quoted-message-preview\"\n data-testid=\"quoted-message-container\"\n [class.mine]=\"isSentByCurrentUser\"\n (click)=\"\n jumpToMessage(\n (message?.quoted_message)!.id,\n message?.quoted_message?.parent_id\n )\n \"\n (keyup.enter)=\"\n jumpToMessage(\n (message?.quoted_message)!.id,\n message?.quoted_message?.parent_id\n )\n \"\n >\n <stream-avatar-placeholder\n data-testid=\"qouted-message-avatar\"\n class=\"str-chat-angular__avatar-host str-chat__message-sender-avatar\"\n type=\"user\"\n location=\"quoted-message-sender\"\n [imageUrl]=\"message?.quoted_message?.user?.image\"\n [name]=\"\n message?.quoted_message?.user?.name || message?.quoted_message?.user?.id\n \"\n [size]=\"20\"\n [user]=\"message?.quoted_message?.user || undefined\"\n ></stream-avatar-placeholder>\n <div class=\"quoted-message-inner str-chat__quoted-message-bubble\">\n <ng-container\n *ngIf=\"\n message?.quoted_message?.attachments &&\n message?.quoted_message?.attachments?.length\n \"\n >\n <ng-template\n #defaultAttachments\n let-messageId=\"messageId\"\n let-attachments=\"attachments\"\n let-parentMessageId=\"parentMessageId\"\n let-imageModalStateChangeHandler=\"imageModalStateChangeHandler\"\n >\n <stream-attachment-list\n [messageId]=\"messageId\"\n [attachments]=\"attachments\"\n [parentMessageId]=\"parentMessageId\"\n (imageModalStateChange)=\"imageModalStateChangeHandler($event)\"\n ></stream-attachment-list>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.attachmentListTemplate$ | async) ||\n defaultAttachments;\n context: getQuotedMessageAttachmentListContext()\n \"\n ></ng-container>\n </ng-container>\n <div\n data-testid=\"quoted-message-text\"\n [innerHTML]=\"\n message?.quoted_message?.translation ||\n message?.quoted_message?.html ||\n message?.quoted_message?.text\n \"\n ></div>\n </div>\n </div>\n</ng-template>\n\n<ng-template #messageDateAndSender>\n <ng-container>\n <div\n *ngIf=\"shouldDisplayTranslationNotice\"\n class=\"str-chat__translation-notice\"\n data-testid=\"translation-notice\"\n >\n <button\n *ngIf=\"displayedMessageTextContent === 'translation'\"\n data-testid=\"see-original\"\n translate\n (click)=\"displayOriginalMessage()\"\n (keyup.enter)=\"displayOriginalMessage()\"\n >\n streamChat.See original (automatically translated)\n </button>\n <button\n *ngIf=\"displayedMessageTextContent === 'original'\"\n data-testid=\"see-translation\"\n translate\n (click)=\"displayTranslatedMessage()\"\n (keyup.enter)=\"displayTranslatedMessage()\"\n >\n streamChat.See translation\n </button>\n </div>\n <ng-container\n *ngIf=\"customTemplatesService.customMessageMetadataTemplate$ | async\"\n >\n <div class=\"str-chat__custom-message-metadata\">\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.customMessageMetadataTemplate$ | async)!;\n context: getMessageMetadataContext()\n \"\n ></ng-container>\n </div>\n </ng-container>\n <div\n class=\"\n str-chat__message-data\n str-chat__message-simple-data\n str-chat__message-metadata\n \"\n >\n <ng-container *ngTemplateOutlet=\"messageStatus\"></ng-container>\n\n <span\n *ngIf=\"!isSentByCurrentUser\"\n data-testid=\"sender\"\n class=\"str-chat__message-simple-name str-chat__message-sender-name\"\n >\n {{ message?.user?.name ? message?.user?.name : message?.user?.id }}\n </span>\n <span\n data-testid=\"date\"\n class=\"str-chat__message-simple-timestamp str-chat__message-simple-time\"\n >\n {{ parsedDate }}\n </span>\n <ng-container *ngIf=\"message?.message_text_updated_at\">\n <span\n data-testid=\"edited-flag\"\n class=\"str-chat__mesage-simple-edited\"\n translate\n >streamChat.Edited</span\n >\n <div\n data-testid=\"edited-timestamp\"\n class=\"str-chat__message-edited-timestamp\"\n [ngClass]=\"{\n 'str-chat__message-edited-timestamp--open': isEditedFlagOpened,\n 'str-chat__message-edited-timestamp--collapsed': !isEditedFlagOpened\n }\"\n >\n <span translate>streamChat.Edited</span>\n <time\n dateTime=\"{{ message?.message_text_updated_at }}\"\n title=\"{{ message?.message_text_updated_at }}\"\n >\n {{ pasedEditedDate }}\n </time>\n </div>\n </ng-container>\n </div>\n </ng-container>\n</ng-template>\n\n<ng-template #messageStatus>\n <ng-container\n *ngIf=\"\n isSentByCurrentUser &&\n ((isLastSentMessage && message?.status === 'received') ||\n message?.status === 'sending')\n \"\n >\n <ng-container *ngIf=\"message?.status === 'sending'; else sentStatus\">\n <ng-container *ngTemplateOutlet=\"sendingStatus\"></ng-container>\n </ng-container>\n <ng-template #sentStatus>\n <ng-container\n *ngIf=\"\n mode === 'main' && isMessageDeliveredAndRead && canDisplayReadStatus;\n else deliveredStatus\n \"\n >\n <ng-container *ngTemplateOutlet=\"readStatus\"></ng-container>\n </ng-container>\n </ng-template>\n <ng-template #deliveredStatus>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.deliveredStatusTemplate$ | async) ||\n defaultDeliveredStatus;\n context: getDeliveredStatusContext()\n \"\n ></ng-container>\n </ng-template>\n <ng-template #defaultDeliveredStatus>\n <span\n *ngIf=\"mode === 'main'\"\n class=\"\n str-chat__message-simple-status\n str-chat__message-simple-status-angular\n str-chat__message-status\n \"\n data-testid=\"delivered-indicator\"\n tabindex=\"0\"\n [floatUiLoose]=\"floatingContent\"\n looseTrigger=\"hover\"\n >\n <float-ui-content #floatingContent>\n <div class=\"str-chat__tooltip str-chat__tooltip-angular\">\n {{ \"streamChat.Delivered\" | translate }}\n </div>\n </float-ui-content>\n <stream-icon-placeholder\n data-testid=\"delivered-icon\"\n icon=\"delivered-icon\"\n ></stream-icon-placeholder>\n </span>\n </ng-template>\n <ng-template #sendingStatus>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.sendingStatusTemplate$ | async) ||\n defaultSendingStatus;\n context: getSendingStatusContext()\n \"\n ></ng-container>\n </ng-template>\n <ng-template #defaultSendingStatus>\n <span\n class=\"\n str-chat__message-simple-status\n str-chat__message-simple-status-angular\n str-chat__message-status\n \"\n data-testid=\"sending-indicator\"\n tabindex=\"0\"\n [floatUiLoose]=\"floatingContent\"\n looseTrigger=\"hover\"\n >\n <float-ui-content #floatingContent>\n <div class=\"str-chat__tooltip str-chat__tooltip-angular\">\n {{ \"streamChat.Sending...\" | translate }}\n </div>\n </float-ui-content>\n <stream-loading-indicator-placeholder\n data-testid=\"loading-indicator\"\n ></stream-loading-indicator-placeholder>\n </span>\n </ng-template>\n <ng-template #readStatus>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.readStatusTemplate$ | async) ||\n defaultReadStatus;\n context: getReadStatusContext()\n \"\n ></ng-container>\n </ng-template>\n <ng-template #defaultReadStatus>\n <span\n class=\"\n str-chat__message-simple-status\n str-chat__message-simple-status-angular\n str-chat__message-status\n \"\n data-testid=\"read-indicator\"\n tabindex=\"0\"\n [floatUiLoose]=\"floatingContent\"\n looseTrigger=\"hover\"\n >\n <float-ui-content #floatingContent>\n <div\n class=\"str-chat__tooltip str-chat__tooltip-angular\"\n data-testid=\"read-by-tooltip\"\n >\n {{ readByText }}\n </div>\n </float-ui-content>\n <stream-icon-placeholder icon=\"read-icon\"></stream-icon-placeholder>\n </span>\n </ng-template>\n </ng-container>\n</ng-template>\n\n<ng-template #replyCountButton>\n <div\n class=\"\n str-chat__message-simple-reply-button\n str-chat__message-replies-count-button-wrapper\n \"\n >\n <button\n *ngIf=\"shouldDisplayThreadLink\"\n class=\"str-chat__message-replies-count-button\"\n data-testid=\"reply-count-button\"\n (click)=\"setAsActiveParentMessage()\"\n >\n {{message?.reply_count === 1 ? ('streamChat.1 reply' | translate) : ('streamChat.{{ replyCount }}\n replies' | translate:replyCountParam)}}\n </button>\n </div>\n</ng-template>\n\n<ng-template #attachmentsTemplate>\n <ng-template\n #defaultAttachments\n let-messageId=\"messageId\"\n let-attachments=\"attachments\"\n let-parentMessageId=\"parentMessageId\"\n let-imageModalStateChangeHandler=\"imageModalStateChangeHandler\"\n >\n <stream-attachment-list\n [messageId]=\"messageId\"\n [attachments]=\"attachments\"\n [parentMessageId]=\"parentMessageId\"\n (imageModalStateChange)=\"imageModalStateChangeHandler($event)\"\n ></stream-attachment-list>\n </ng-template>\n <ng-container\n *ngTemplateOutlet=\"\n (customTemplatesService.attachmentListTemplate$ | async) ||\n defaultAttachments;\n context: getAttachmentListContext()\n \"\n ></ng-container>\n</ng-template>\n" }]
|
|
391
|
+
}], ctorParameters: function () { return [{ type: i1.ChatClientService }, { type: i2.ChannelService }, { type: i3.CustomTemplatesService }, { type: i0.ChangeDetectorRef }, { type: i4.DateParserService }, { type: i5.MessageService }, { type: i6.MessageActionsService }]; }, propDecorators: { message: [{
|
|
392
|
+
type: Input
|
|
393
|
+
}], enabledMessageActions: [{
|
|
394
|
+
type: Input
|
|
395
|
+
}], isLastSentMessage: [{
|
|
396
|
+
type: Input
|
|
397
|
+
}], mode: [{
|
|
398
|
+
type: Input
|
|
399
|
+
}], isHighlighted: [{
|
|
400
|
+
type: Input
|
|
401
|
+
}] } });
|
|
402
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVzc2FnZS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9zdHJlYW0tY2hhdC1hbmd1bGFyL3NyYy9saWIvbWVzc2FnZS9tZXNzYWdlLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3N0cmVhbS1jaGF0LWFuZ3VsYXIvc3JjL2xpYi9tZXNzYWdlL21lc3NhZ2UuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLFNBQVMsRUFDVCxLQUFLLEVBTUwsdUJBQXVCLEdBRXhCLE1BQU0sZUFBZSxDQUFDO0FBaUJ2QixPQUFPLFVBQVUsTUFBTSxhQUFhLENBQUM7QUFHckMsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGVBQWUsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFZMUM7O0dBRUc7QUFPSCxNQUFNLE9BQU8sZ0JBQWdCO0lBMkQzQixZQUNVLGlCQUFvQyxFQUNwQyxjQUE4QixFQUMvQixzQkFBOEMsRUFDN0MsS0FBd0IsRUFDeEIsVUFBNkIsRUFDN0IsY0FBOEIsRUFDOUIscUJBQTRDO1FBTjVDLHNCQUFpQixHQUFqQixpQkFBaUIsQ0FBbUI7UUFDcEMsbUJBQWMsR0FBZCxjQUFjLENBQWdCO1FBQy9CLDJCQUFzQixHQUF0QixzQkFBc0IsQ0FBd0I7UUFDN0MsVUFBSyxHQUFMLEtBQUssQ0FBbUI7UUFDeEIsZUFBVSxHQUFWLFVBQVUsQ0FBbUI7UUFDN0IsbUJBQWMsR0FBZCxjQUFjLENBQWdCO1FBQzlCLDBCQUFxQixHQUFyQixxQkFBcUIsQ0FBdUI7UUEzRHREOztXQUVHO1FBQ00sMEJBQXFCLEdBQWEsRUFBRSxDQUFDO1FBSzlDOztXQUVHO1FBQ00sU0FBSSxHQUFzQixNQUFNLENBQUM7UUFDMUM7O1dBRUc7UUFDTSxrQkFBYSxHQUFHLEtBQUssQ0FBQztRQUcvQixvQkFBZSxHQUFHLEtBQUssQ0FBQztRQUN4Qix1QkFB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QU0sQ0FDOUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssSUFBSSxDQUFDLE1BQU0sQ0FDNUIsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7OzZHQWpjVSxnQkFBZ0I7aUdBQWhCLGdCQUFnQixpUENuRDdCLDhxdEJBcW5CQTsyRkRsa0JhLGdCQUFnQjtrQkFONUIsU0FBUzsrQkFDRSxnQkFBZ0IsbUJBR1QsdUJBQXVCLENBQUMsTUFBTTsyU0FRdEMsT0FBTztzQkFBZixLQUFLO2dCQUlHLHFCQUFxQjtzQkFBN0IsS0FBSztnQkFJRyxpQkFBaUI7c0JBQXpCLEtBQUs7Z0JBSUcsSUFBSTtzQkFBWixLQUFLO2dCQUlHLGFBQWE7c0JBQXJCLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDb21wb25lbnQsXG4gIElucHV0LFxuICBPbkNoYW5nZXMsXG4gIFNpbXBsZUNoYW5nZXMsXG4gIE9uRGVzdHJveSxcbiAgT25Jbml0LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIEFmdGVyVmlld0luaXQsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQXR0YWNobWVudCwgVXNlclJlc3BvbnNlIH0gZnJvbSAnc3RyZWFtLWNoYXQnO1xuaW1wb3J0IHsgQ2hhbm5lbFNlcnZpY2UgfSBmcm9tICcuLi9jaGFubmVsLnNlcnZpY2UnO1xuaW1wb3J0IHsgQ2hhdENsaWVudFNlcnZpY2UgfSBmcm9tICcuLi9jaGF0LWNsaWVudC5zZXJ2aWNlJztcbmltcG9ydCB7XG4gIEF0dGFjaG1lbnRMaXN0Q29udGV4dCxcbiAgTWVudGlvblRlbXBsYXRlQ29udGV4dCxcbiAgTWVzc2FnZUFjdGlvbnNCb3hDb250ZXh0LFxuICBNZXNzYWdlUmVhY3Rpb25zQ29udGV4dCxcbiAgRGVmYXVsdFN0cmVhbUNoYXRHZW5lcmljcyxcbiAgU3RyZWFtTWVzc2FnZSxcbiAgRGVsaXZlcmVkU3RhdHVzQ29udGV4dCxcbiAgU2VuZGluZ1N0YXR1c0NvbnRleHQsXG4gIFJlYWRTdGF0dXNDb250ZXh0LFxuICBTeXN0ZW1NZXNzYWdlQ29udGV4dCxcbiAgQ3VzdG9tTWV0YWRhdGFDb250ZXh0LFxufSBmcm9tICcuLi90eXBlcyc7XG5pbXBvcnQgZW1vamlSZWdleCBmcm9tICdlbW9qaS1yZWdleCc7XG5pbXBvcnQgeyBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IEN1c3RvbVRlbXBsYXRlc1NlcnZpY2UgfSBmcm9tICcuLi9jdXN0b20tdGVtcGxhdGVzLnNlcnZpY2UnO1xuaW1wb3J0IHsgbGlzdFVzZXJzIH0gZnJvbSAnLi4vbGlzdC11c2Vycyc7XG5pbXBvcnQgeyBEYXRlUGFyc2VyU2VydmljZSB9IGZyb20gJy4uL2RhdGUtcGFyc2VyLnNlcnZpY2UnO1xuaW1wb3J0IHsgTWVzc2FnZVNlcnZpY2UgfSBmcm9tICcuLi9tZXNzYWdlLnNlcnZpY2UnO1xuaW1wb3J0IHsgTWVzc2FnZUFjdGlvbnNTZXJ2aWNlIH0gZnJvbSAnLi4vbWVzc2FnZS1hY3Rpb25zLnNlcnZpY2UnO1xuaW1wb3J0IHsgTmd4RmxvYXRVaUNvbnRlbnRDb21wb25lbnQgfSBmcm9tICduZ3gtZmxvYXQtdWknO1xuXG50eXBlIE1lc3NhZ2VQYXJ0ID0ge1xuICBjb250ZW50OiBzdHJpbmc7XG4gIHR5cGU6ICd0ZXh0JyB8ICdtZW50aW9uJztcbiAgdXNlcj86IFVzZXJSZXNwb25zZTtcbn07XG5cbi8qKlxuICogVGhlIGBNZXNzYWdlYCBjb21wb25lbnQgZGlzcGxheXMgYSBtZXNzYWdlIHdpdGggYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBzdWNoIGFzIHNlbmRlciBhbmQgZGF0ZSwgYW5kIGVuYWJsZXMgW2ludGVyYWN0aW9uIHdpdGggdGhlIG1lc3NhZ2UgKGkuZS4gZWRpdCBvciByZWFjdCldKC4uL2NvbmNlcHRzL21lc3NhZ2UtaW50ZXJhY3Rpb25zLm1keCkuXG4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3N0cmVhbS1tZXNzYWdlJyxcbiAgdGVtcGxhdGVVcmw6ICcuL21lc3NhZ2UuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZXM6IFtdLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbn0pXG5leHBvcnQgY2xhc3MgTWVzc2FnZUNvbXBvbmVudFxuICBpbXBsZW1lbnRzIE9uSW5pdCwgT25DaGFuZ2VzLCBPbkRlc3Ryb3ksIEFmdGVyVmlld0luaXRcbntcbiAgLyoqXG4gICAqIFRoZSBtZXNzYWdlIHRvIGJlIGRpc3BsYXllZFxuICAgKi9cbiAgQElucHV0KCkgbWVzc2FnZTogU3RyZWFtTWVzc2FnZSB8IHVuZGVmaW5lZDtcbiAgLyoqXG4gICAqIFRoZSBsaXN0IG9mIFtjaGFubmVsIGNhcGFiaWxpdGllc10oaHR0cHM6Ly9nZXRzdHJlYW0uaW8vY2hhdC9kb2NzL2phdmFzY3JpcHQvY2hhbm5lbF9jYXBhYmlsaXRpZXMvP2xhbmd1YWdlPWphdmFzY3JpcHQpIHRoYXQgYXJlIGVuYWJsZWQgZm9yIHRoZSBjdXJyZW50IHVzZXIsIHRoZSBsaXN0IG9mIFtzdXBwb3J0ZWQgaW50ZXJhY3Rpb25zXSguLi9jb25jZXB0cy9tZXNzYWdlLWludGVyYWN0aW9ucy5tZHgpIGNhbiBiZSBmb3VuZCBpbiBvdXIgbWVzc2FnZSBpbnRlcmFjdGlvbiBndWlkZS4gVW5hdGhvcml6ZWQgYWN0aW9ucyB3b24ndCBiZSBkaXNwbGF5ZWQgb24gdGhlIFVJLiBUaGUgW2BNZXNzYWdlTGlzdGBdKC4vTWVzc2FnZUxpc3RDb21wb25lbnQubWR4KSBjb21wb25lbnQgYXV0b21hdGljYWxseSBzZXRzIHRoaXMgYmFzZWQgb24gW2NoYW5uZWwgY2FwYWJpbGl0aWVzXShodHRwczovL2dldHN0cmVhbS5pby9jaGF0L2RvY3MvamF2YXNjcmlwdC9jaGFubmVsX2NhcGFiaWxpdGllcy8/bGFuZ3VhZ2U9amF2YXNjcmlwdCkuXG4gICAqL1xuICBASW5wdXQoKSBlbmFibGVkTWVzc2FnZUFjdGlvbnM6IHN0cmluZ1tdID0gW107XG4gIC8qKlxuICAgKiBJZiBgdHJ1ZWAsIHRoZSBtZXNzYWdlIHN0YXR1cyAoc2VuZGluZywgc2VudCwgd2hvIHJlYWQgdGhlIG1lc3NhZ2UpIGlzIGRpc3BsYXllZC5cbiAgICovXG4gIEBJbnB1dCgpIGlzTGFzdFNlbnRNZXNzYWdlOiBib29sZWFuIHwgdW5kZWZpbmVkO1xuICAvKipcbiAgICogRGV0ZXJtaW5lcyBpZiB0aGUgbWVzc2FnZSBpcyBiZWluZyBkaXNwYWx5ZWQgaW4gYSBjaGFubmVsIG9yIGluIGEgW3RocmVhZF0oaHR0cHM6Ly9nZXRzdHJlYW0uaW8vY2hhdC9kb2NzL2phdmFzY3JpcHQvdGhyZWFkcy8/bGFuZ3VhZ2U9amF2YXNjcmlwdCkuXG4gICAqL1xuICBASW5wdXQoKSBtb2RlOiAndGhyZWFkJyB8ICdtYWluJyA9ICdtYWluJztcbiAgLyoqXG4gICAqIEhpZ2hsaWdodGluZyBpcyB1c2VkIHRvIGFkZCB2aXN1YWwgZW1waGFzaXplIHRvIGEgbWVzc2FnZSB3aGVuIGp1bXBpbmcgdG8gdGhlIG1lc3NhZ2VcbiAgICovXG4gIEBJbnB1dCgpIGlzSGlnaGxpZ2h0ZWQgPSBmYWxzZTtcbiAgY2FuUmVjZWl2ZVJlYWRFdmVudHM6IGJvb2xlYW4gfCB1bmRlZmluZWQ7XG4gIGNhblJlYWN0VG9NZXNzYWdlOiBib29sZWFuIHwgdW5kZWZpbmVkO1xuICBpc0FjdGlvbkJveE9wZW4gPSBmYWxzZTtcbiAgaXNFZGl0ZWRGbGFnT3BlbmVkID0gZmFsc2U7XG4gIGlzUmVhY3Rpb25TZWxlY3Rvck9wZW4gPSBmYWxzZTtcbiAgdmlzaWJsZU1lc3NhZ2VBY3Rpb25zQ291bnQgPSAwO1xuICBtZXNzYWdlVGV4dFBhcnRzOiBNZXNzYWdlUGFydFtdIHwgdW5kZWZpbmVkID0gW107XG4gIG1lc3NhZ2VUZXh0Pzogc3RyaW5nO1xuICBzaG91bGREaXNwbGF5VHJhbnNsYXRpb25Ob3RpY2UgPSBmYWxzZTtcbiAgZGlzcGxheWVkTWVzc2FnZVRleHRDb250ZW50OiAnb3JpZ2luYWwnIHwgJ3RyYW5zbGF0aW9uJyA9ICdvcmlnaW5hbCc7XG4gIGltYWdlQXR0YWNobWVudE1vZGFsU3RhdGU6ICdvcGVuZWQnIHwgJ2Nsb3NlZCcgPSAnY2xvc2VkJztcbiAgc2hvdWxkRGlzcGxheVRocmVhZExpbmsgPSBmYWxzZTtcbiAgaXNTZW50QnlDdXJyZW50VXNlciA9IGZhbHNlO1xuICByZWFkQnlUZXh0ID0gJyc7XG4gIGRpc3BsYXlBczogJ3RleHQnIHwgJ2h0bWwnO1xuICBsYXN0UmVhZFVzZXI6IFVzZXJSZXNwb25zZTxEZWZhdWx0U3RyZWFtQ2hhdEdlbmVyaWNzPiB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcbiAgaXNPbmx5UmVhZEJ5TWUgPSBmYWxzZTtcbiAgaXNSZWFkQnlNdWx0aXBsZVVzZXJzID0gZmFsc2U7XG4gIGlzTWVzc2FnZURlbGl2ZXJlZEFuZFJlYWQgPSBmYWxzZTtcbiAgcGFyc2VkRGF0ZSA9ICcnO1xuICBwYXNlZEVkaXRlZERhdGUgPSAnJztcbiAgYXJlT3B0aW9uc1Zpc2libGUgPSBmYWxzZTtcbiAgaGFzQXR0YWNobWVudCA9IGZhbHNlO1xuICBoYXNSZWFjdGlvbnMgPSBmYWxzZTtcbiAgcmVwbHlDb3VudFBhcmFtOiB7IHJlcGx5Q291bnQ6IG51bWJlciB8IHVuZGVmaW5lZCB9ID0ge1xuICAgIHJlcGx5Q291bnQ6IHVuZGVmaW5lZCxcbiAgfTtcbiAgY2FuRGlzcGxheVJlYWRTdGF0dXMgPSBmYWxzZTtcbiAgcHJpdmF0ZSBxdW90ZWRNZXNzYWdlQXR0YWNobWVudHM6IEF0dGFjaG1lbnRbXSB8IHVuZGVmaW5lZDtcbiAgcHJpdmF0ZSBzdWJzY3JpcHRpb25zOiBTdWJzY3JpcHRpb25bXSA9IFtdO1xuICBwcml2YXRlIGlzVmlld0luaXRlZCA9IGZhbHNlO1xuICBwcml2YXRlIHVzZXJJZD86IHN0cmluZztcbiAgcHJpdmF0ZSByZWFkb25seSB1cmxSZWdleHAgPVxuICAgIC8oPzooPzpodHRwcz98ZnRwfGZpbGUpOlxcL1xcL3x3d3dcXC58ZnRwXFwuKSg/OlxcKFstQS1aMC05KyZAIy8lPX5ffCQ/ITosLl0qXFwpfFstQS1aMC05KyZAIy8lPX5ffCQ/ITosLl0pKig/OlxcKFstQS1aMC05KyZAIy8lPX5ffCQ/ITosLl0qXFwpfFtBLVowLTkrJkAjLyU9fl98JF0pL2dpbTtcbiAgcHJpdmF0ZSBlbW9qaVJlZ2V4cCA9IG5ldyBSZWdFeHAoZW1vamlSZWdleCgpLCAnZycpO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgY2hhdENsaWVudFNlcnZpY2U6IENoYXRDbGllbnRTZXJ2aWNlLFxuICAgIHByaXZhdGUgY2hhbm5lbFNlcnZpY2U6IENoYW5uZWxTZXJ2aWNlLFxuICAgIHB1YmxpYyBjdXN0b21UZW1wbGF0ZXNTZXJ2aWNlOiBDdXN0b21UZW1wbGF0ZXNTZXJ2aWNlLFxuICAgIHByaXZhdGUgY2RSZWY6IENoYW5nZURldGVjdG9yUmVmLFxuICAgIHByaXZhdGUgZGF0ZVBhcnNlcjogRGF0ZVBhcnNlclNlcnZpY2UsXG4gICAgcHJpdmF0ZSBtZXNzYWdlU2VydmljZTogTWVzc2FnZVNlcnZpY2UsXG4gICAgcHJpdmF0ZSBtZXNzYWdlQWN0aW9uc1NlcnZpY2U6IE1lc3NhZ2VBY3Rpb25zU2VydmljZVxuICApIHtcbiAgICB0aGlzLmRpc3BsYXlBcyA9IHRoaXMubWVzc2FnZVNlcnZpY2UuZGlzcGxheUFzO1xuICB9XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLnB1c2goXG4gICAgICB0aGlzLmNoYXRDbGllbnRTZXJ2aWNlLnVzZXIkLnN1YnNjcmliZSgodSkgPT4ge1xuICAgICAgICBpZiAodT8uaWQgIT09IHRoaXMudXNlcklkKSB7XG4gICAgICAgICAgdGhpcy51c2VySWQgPSB1Py5pZDtcbiAgICAgICAgICB0aGlzLnNldElzU2VudEJ5Q3VycmVudFVzZXIoKTtcbiAgICAgICAgICB0aGlzLnNldExhc3RSZWFkVXNlcigpO1xuICAgICAgICAgIGlmICh0aGlzLmlzVmlld0luaXRlZCkge1xuICAgICAgICAgICAgdGhpcy5jZFJlZi5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KVxuICAgICk7XG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLnB1c2goXG4gICAgICB0aGlzLm1lc3NhZ2VBY3Rpb25zU2VydmljZS5jdXN0b21BY3Rpb25zJC5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICBpZiAodGhpcy5tZXNzYWdlKSB7XG4gICAgICAgICAgY29uc3QgbnVtYmVyT2ZFbmFibGVkQWN0aW9ucyA9XG4gICAgICAgICAgICB0aGlzLm1lc3NhZ2VBY3Rpb25zU2VydmljZS5nZXRBdXRob3JpemVkTWVzc2FnZUFjdGlvbnNDb3VudChcbiAgICAgICAgICAgICAgdGhpcy5tZXNzYWdlLFxuICAgICAgICAgICAgICB0aGlzLmVuYWJsZWRNZXNzYWdlQWN0aW9uc1xuICAgICAgICAgICAgKTtcbiAgICAgICAgICBpZiAobnVtYmVyT2ZFbmFibGVkQWN0aW9ucyAhPT0gdGhpcy52aXNpYmxlTWVzc2FnZUFjdGlvbnNDb3VudCkge1xuICAgICAgICAgICAgdGhpcy52aXNpYmxlTWVzc2FnZUFjdGlvbnNDb3VudCA9IG51bWJlck9mRW5hYmxlZEFjdGlvbnM7XG4gICAgICAgICAgICBpZiAodGhpcy5pc1ZpZXdJbml0ZWQpIHtcbiAgICAgICAgICAgICAgdGhpcy5jZFJlZi5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KVxuICAgICk7XG4gIH1cblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XG4gICAgaWYgKGNoYW5nZXMubWVzc2FnZSkge1xuICAgICAgdGhpcy5zaG91bGREaXNwbGF5VHJhbnNsYXRpb25Ob3RpY2UgPSBmYWxzZTtcbiAgICAgIHRoaXMuZGlzcGxheWVkTWVzc2FnZVRleHRDb250ZW50ID0gJ29yaWdpbmFsJztcbiAgICAgIHRoaXMuY3JlYXRlTWVzc2FnZVBhcnRzKCk7XG4gICAgICBjb25zdCBvcmlnaW5hbEF0dGFjaG1lbnRzID0gdGhpcy5tZXNzYWdlPy5xdW90ZWRfbWVzc2FnZT8uYXR0YWNobWVudHM7XG4gICAgICB0aGlzLnF1b3RlZE1lc3NhZ2VBdHRhY2htZW50cyA9XG4gICAgICAgIG9yaWdpbmFsQXR0YWNobWVudHMgJiYgb3JpZ2luYWxBdHRhY2htZW50cy5sZW5ndGhcbiAgICAgICAgICA/IFtvcmlnaW5hbEF0dGFjaG1lbnRzWzBdXVxuICAgICAgICAgIDogW107XG4gICAgICB0aGlzLnNldElzU2VudEJ5Q3VycmVudFVzZXIoKTtcbiAgICAgIHRoaXMuc2V0TGFzdFJlYWRVc2VyKCk7XG4gICAgICB0aGlzLnJlYWRCeVRleHQgPSB0aGlzLm1lc3NhZ2U/LnJlYWRCeVxuICAgICAgICA/IGxpc3RVc2Vycyh0aGlzLm1lc3NhZ2UucmVhZEJ5KVxuICAgICAgICA6ICcnO1xuICAgICAgdGhpcy5pc09ubHlSZWFkQnlNZSA9ICEhKFxuICAgICAgICB0aGlzLm1lc3NhZ2UgJiZcbiAgICAgICAgdGhpcy5tZXNzYWdlLnJlYWRCeSAmJlxuICAgICAgICB0aGlzLm1lc3NhZ2UucmVhZEJ5Lmxlbmd0aCA9PT0gMFxuICAgICAgKTtcbiAgICAgIHRoaXMuaXNSZWFkQnlNdWx0aXBsZVVzZXJzID0gISEoXG4gICAgICAgIHRoaXMubWVzc2FnZSAmJlxuICAgICAgICB0aGlzLm1lc3NhZ2UucmVhZEJ5ICYmXG4gICAgICAgIHRoaXMubWVzc2FnZS5yZWFkQnkubGVuZ3RoID4gMVxuICAgICAgKTtcbiAgICAgIHRoaXMuaXNNZXNzYWdlRGVsaXZlcmVkQW5kUmVhZCA9ICEhKFxuICAgICAgICB0aGlzLm1lc3NhZ2UgJiZcbiAgICAgICAgdGhpcy5tZXNzYWdlLnJlYWRCeSAmJlxuICAgICAgICB0aGlzLm1lc3NhZ2Uuc3RhdHVzID09PSAncmVjZWl2ZWQnICYmXG4gICAgICAgIHRoaXMubWVzc2FnZS5yZWFkQnkubGVuZ3RoID4gMFxuICAgICAgKTtcbiAgICAgIHRoaXMucGFyc2VkRGF0ZSA9XG4gICAgICAgICh0aGlzLm1lc3NhZ2UgJiZcbiAgICAgICAgICB0aGlzLm1lc3NhZ2UuY3JlYXRlZF9hdCAmJlxuICAgICAgICAgIHRoaXMuZGF0ZVBhcnNlci5wYXJzZURhdGVUaW1lKHRoaXMubWVzc2FnZS5jcmVhdGVkX2F0KSkgfHxcbiAgICAgICAgJyc7XG4gICAgICB0aGlzLnBhc2VkRWRpdGVkRGF0ZSA9XG4gICAgICAgICh0aGlzLm1lc3NhZ2UgJiZcbiAgICAgICAgICB0aGlzLm1lc3NhZ2UubWVzc2FnZV90ZXh0X3VwZGF0ZWRfYXQgJiZcbiAgICAgICAgICB0aGlzLmRhdGVQYXJzZXIucGFyc2VEYXRlVGltZShcbiAgICAgICAgICAgIG5ldyBEYXRlKHRoaXMubWVzc2FnZS5tZXNzYWdlX3RleHRfdXBkYXRlZF9hdClcbiAgICAgICAgICApKSB8fFxuICAgICAgICAnJztcbiAgICAgIHRoaXMuaGFzQXR0YWNobWVudCA9XG4gICAgICAgICEhdGhpcy5tZXNzYWdlPy5hdHRhY2htZW50cyAmJiAhIXRoaXMubWVzc2FnZS5hdHRhY2htZW50cy5sZW5ndGg7XG4gICAgICB0aGlzLmhhc1JlYWN0aW9ucyA9XG4gICAgICAgICEhdGhpcy5tZXNzYWdlPy5yZWFjdGlvbl9jb3VudHMgJiZcbiAgICAgICAgT2JqZWN0LmtleXModGhpcy5tZXNzYWdlLnJlYWN0aW9uX2NvdW50cykubGVuZ3RoID4gMDtcbiAgICAgIHRoaXMucmVwbHlDb3VudFBhcmFtID0geyByZXBseUNvdW50OiB0aGlzLm1lc3NhZ2U/LnJlcGx5X2NvdW50IH07XG4gICAgfVxuICAgIGlmIChjaGFuZ2VzLmVuYWJsZWRNZXNzYWdlQWN0aW9ucykge1xuICAgICAgdGhpcy5jYW5SZWFjdFRvTWVzc2FnZSA9XG4gICAgICAgIHRoaXMuZW5hYmxlZE1lc3NhZ2VBY3Rpb25zLmluZGV4T2YoJ3NlbmQtcmVhY3Rpb24nKSAhPT0gLTE7XG4gICAgICB0aGlzLmNhblJlY2VpdmVSZWFkRXZlbnRzID1cbiAgICAgICAgdGhpcy5lbmFibGVkTWVzc2FnZUFjdGlvbnMuaW5kZXhPZigncmVhZC1ldmVudHMnKSAhPT0gLTE7XG4gICAgICB0aGlzLmNhbkRpc3BsYXlSZWFkU3RhdHVzID1cbiAgICAgICAgdGhpcy5jYW5SZWNlaXZlUmVhZEV2ZW50cyAhPT0gZmFsc2UgJiZcbiAgICAgICAgdGhpcy5lbmFibGVkTWVzc2FnZUFjdGlvbnMuaW5kZXhPZigncmVhZC1ldmVudHMnKSAhPT0gLTE7XG4gICAgfVxuICAgIGlmIChjaGFuZ2VzLm1lc3NhZ2UgfHwgY2hhbmdlcy5lbmFibGVkTWVzc2FnZUFjdGlvbnMgfHwgY2hhbmdlcy5tb2RlKSB7XG4gICAgICB0aGlzLnNob3VsZERpc3BsYXlUaHJlYWRMaW5rID1cbiAgICAgICAgISF0aGlzLm1lc3NhZ2U/LnJlcGx5X2NvdW50ICYmIHRoaXMubW9kZSAhPT0gJ3RocmVhZCc7XG4gICAgfVxuICAgIGlmIChjaGFuZ2VzLm1lc3NhZ2UgfHwgY2hhbmdlcy5tb2RlKSB7XG4gICAgICB0aGlzLmFyZU9wdGlvbnNWaXNpYmxlID0gdGhpcy5tZXNzYWdlXG4gICAgICAgID8gIShcbiAgICAgICAgICAgICF0aGlzLm1lc3NhZ2UudHlwZSB8fFxuICAgICAgICAgICAgdGhpcy5tZXNzYWdlLnR5cGUgPT09ICdlcnJvcicgfHxcbiAgICAgICAgICAgIHRoaXMubWVzc2FnZS50eXBlID09PSAnc3lzdGVtJyB8fFxuICAgICAgICAgICAgdGhpcy5tZXNzYWdlLnR5cGUgPT09ICdlcGhlbWVyYWwnIHx8XG4gICAgICAgICAgICB0aGlzLm1lc3NhZ2Uuc3RhdHVzID09PSAnZmFpbGVkJyB8fFxuICAgICAgICAgICAgdGhpcy5tZXNzYWdlLnN0YXR1cyA9PT0gJ3NlbmRpbmcnIHx8XG4gICAgICAgICAgICAodGhpcy5tb2RlID09PSAndGhyZWFkJyAmJiAhdGhpcy5tZXNzYWdlLnBhcmVudF9pZClcbiAgICAgICAgICApXG4gICAgICAgIDogZmFsc2U7XG4gICAgfVxuICAgIGlmIChjaGFuZ2VzLm1lc3NhZ2UgfHwgY2hhbmdlcy5lbmFibGVkTWVzc2FnZUFjdGlvbnMpIHtcbiAgICAgIGlmICh0aGlzLm1lc3NhZ2UpIHtcbiAgICAgICAgdGhpcy52aXNpYmxlTWVzc2FnZUFjdGlvbnNDb3VudCA9XG4gICAgICAgICAgdGhpcy5tZXNzYWdlQWN0aW9uc1NlcnZpY2UuZ2V0QXV0aG9yaXplZE1lc3NhZ2VBY3Rpb25zQ291bnQoXG4gICAgICAgICAgICB0aGlzLm1lc3NhZ2UsXG4gICAgICAgICAgICB0aGlzLmVuYWJsZWRNZXNzYWdlQWN0aW9uc1xuICAgICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnZpc2libGVNZXNzYWdlQWN0aW9uc0NvdW50ID0gMDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBuZ0FmdGVyVmlld0luaXQoKTogdm9pZCB7XG4gICAgdGhpcy5pc1ZpZXdJbml0ZWQgPSB0cnVlO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLmZvckVhY2goKHMpID0+IHMudW5zdWJzY3JpYmUoKSk7XG4gIH1cblxuICBtZXNzYWdlQWN0aW9uc0NsaWNrZWQoKSB7XG4gICAgaWYgKCF0aGlzLm1lc3NhZ2UpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHRoaXMubWVzc2FnZUFjdGlvbnNTZXJ2aWNlLmN1c3RvbUFjdGlvbkNsaWNrSGFuZGxlcikge1xuICAgICAgdGhpcy5tZXNzYWdlQWN0aW9uc1NlcnZpY2UuY3VzdG9tQWN0aW9uQ2xpY2tIYW5kbGVyKHtcbiAgICAgICAgbWVzc2FnZTogdGhpcy5tZXNzYWdlLFxuICAgICAgICBlbmFibGVkQWN0aW9uczogdGhpcy5lbmFibGVkTWVzc2FnZUFjdGlvbnMsXG4gICAgICAgIGN1c3RvbUFjdGlvbnM6IHRoaXMubWVzc2FnZUFjdGlvbnNTZXJ2aWNlLmN1c3RvbUFjdGlvbnMkLmdldFZhbHVlKCksXG4gICAgICAgIGlzTWluZTogdGhpcy5pc1NlbnRCeUN1cnJlbnRVc2VyLFxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuaXNBY3Rpb25Cb3hPcGVuID0gIXRoaXMuaXNBY3Rpb25Cb3hPcGVuO1xuICAgIH1cbiAgfVxuXG4gIG1lc3NhZ2VBY3Rpb25zQm94Q2xpY2tlZChmbG9hdGluZ0NvbnRlbnQ6IE5neEZsb2F0VWlDb250ZW50Q29tcG9uZW50KSB7XG4gICAgZmxvYXRpbmdDb250ZW50LmhpZGUoKTtcbiAgfVxuXG4gIGdldEF0dGFjaG1lbnRMaXN0Q29udGV4dCgpOiBBdHRhY2htZW50TGlzdENvbnRleHQge1xuICAgIHJldHVybiB7XG4gICAgICBtZXNzYWdlSWQ6IHRoaXMubWVzc2FnZT8uaWQgfHwgJycsXG4gICAgICBhdHRhY2htZW50czogdGhpcy5tZXNzYWdlPy5hdHRhY2htZW50cyB8fCBbXSxcbiAgICAgIHBhcmVudE1lc3NhZ2VJZDogdGhpcy5tZXNzYWdlPy5wYXJlbnRfaWQsXG4gICAgICBpbWFnZU1vZGFsU3RhdGVDaGFuZ2VIYW5kbGVyOiAoc3RhdGUpID0+XG4gICAgICAgICh0aGlzLmltYWdlQXR0YWNobWVudE1vZGFsU3RhdGUgPSBzdGF0ZSksXG4gICAgfTtcbiAgfVxuXG4gIGdldE1lc3NhZ2VDb250ZXh0KCk6IFN5c3RlbU1lc3NhZ2VDb250ZXh0IHtcbiAgICByZXR1cm4ge1xuICAgICAgbWVzc2FnZTogdGhpcy5tZXNzYWdlLFxuICAgICAgZW5hYmxlZE1lc3NhZ2VBY3Rpb25zOiB0aGlzLmVuYWJsZWRNZXNzYWdlQWN0aW9ucyxcbiAgICAgIGlzSGlnaGxpZ2h0ZWQ6IHRoaXMuaXNIaWdobGlnaHRlZCxcbiAgICAgIGlzTGFzdFNlbnRNZXNzYWdlOiB0aGlzLmlzTGFzdFNlbnRNZXNzYWdlLFxuICAgICAgbW9kZTogdGhpcy5tb2RlLFxuICAgICAgY3VzdG9tQWN0aW9uczogdGhpcy5tZXNzYWdlQWN0aW9uc1NlcnZpY2UuY3VzdG9tQWN0aW9ucyQuZ2V0VmFsdWUoKSxcbiAgICAgIHBhcnNlZERhdGU6IHRoaXMucGFyc2VkRGF0ZSxcbiAgICB9O1xuICB9XG5cbiAgZ2V0UXVvdGVkTWVzc2FnZUF0dGFjaG1lbnRMaXN0Q29udGV4dCgpOiBBdHRhY2htZW50TGlzdENvbnRleHQge1xuICAgIHJldHVybiB7XG4gICAgICBtZXNzYWdlSWQ6IHRoaXMubWVzc2FnZT8ucXVvdGVkX21lc3NhZ2U/LmlkIHx8ICcnLFxuICAgICAgYXR0YWNobWVudHM6IHRoaXMucXVvdGVkTWVzc2FnZUF0dGFjaG1lbnRzISxcbiAgICAgIHBhcmVudE1lc3NhZ2VJZDogdGhpcz8ubWVzc2FnZT8ucXVvdGVkX21lc3NhZ2U/LnBhcmVudF9pZCxcbiAgICB9O1xuICB9XG5cbiAgZ2V0TWVzc2FnZVJlYWN0aW9uc0NvbnRleHQoKTogTWVzc2FnZVJlYWN0aW9uc0NvbnRleHQge1xuICAgIHJldHVybiB7XG4gICAgICBtZXNzYWdlUmVhY3Rpb25Db3VudHM6IHRoaXMubWVzc2FnZT8ucmVhY3Rpb25fY291bnRzIHx8IHt9LFxuICAgICAgbGF0ZXN0UmVhY3Rpb25zOiB0aGlzLm1lc3NhZ2U/LmxhdGVzdF9yZWFjdGlvbnMgfHwgW10sXG4gICAgICBpc1NlbGVjdG9yT3BlbjogdGhpcy5pc1JlYWN0aW9uU2VsZWN0b3JPcGVuLFxuICAgICAgaXNTZWxlY3Rvck9wZW5DaGFuZ2VIYW5kbGVyOiAoaXNPcGVuKSA9PlxuICAgICAgICAodGhpcy5pc1JlYWN0aW9uU2VsZWN0b3JPcGVuID0gaXNPcGVuKSxcbiAgICAgIG1lc3NhZ2VJZDogdGhpcy5tZXNzYWdlPy5pZCxcbiAgICAgIG93blJlYWN0aW9uczogdGhpcy5tZXNzYWdlPy5vd25fcmVhY3Rpb25zIHx8IFtdLFxuICAgIH07XG4gIH1cblxuICBtZXNzYWdlQ2xpY2tlZCgpIHtcbiAgICBpZiAoXG4gICAgICB0aGlzLm1lc3NhZ2U/LnN0YXR1cyA9PT0gJ2ZhaWxlZCcgJiZcbiAgICAgIHRoaXMubWVzc2FnZT8uZXJyb3JTdGF0dXNDb2RlICE9PSA0MDNcbiAgICApIHtcbiAgICAgIHRoaXMucmVzZW5kTWVzc2FnZSgpO1xuICAgIH0gZWxzZSBpZiAoXG4gICAgICB0aGlzLm1lc3NhZ2U/LnR5cGUgPT09ICdlcnJvcicgJiZcbiAgICAgIHRoaXMubWVzc2FnZT8ubW9kZXJhdGlvbl9kZXRhaWxzXG4gICAgKSB7XG4gICAgICB0aGlzLm9wZW5NZXNzYWdlQm91bmNlUHJvbXB0KCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuaXNFZGl0ZWRGbGFnT3BlbmVkID0gIXRoaXMuaXNFZGl0ZWRGbGFnT3BlbmVkO1xuICAgIH1cbiAgfVxuXG4gIHJlc2VuZE1lc3NhZ2UoKSB7XG4gICAgdm9pZCB0aGlzLmNoYW5uZWxTZXJ2aWNlLnJlc2VuZE1lc3NhZ2UodGhpcy5tZXNzYWdlISk7XG4gIH1cblxuICBzZXRBc0FjdGl2ZVBhcmVudE1lc3NhZ2UoKSB7XG4gICAgdm9pZCB0aGlzLmNoYW5uZWxTZXJ2aWNlLnNldEFzQWN0aXZlUGFyZW50TWVzc2FnZSh0aGlzLm1lc3NhZ2UpO1xuICB9XG5cbiAgZ2V0TWVudGlvbkNvbnRleHQobWVzc2FnZVBhcnQ6IE1lc3NhZ2VQYXJ0KTogTWVudGlvblRlbXBsYXRlQ29udGV4dCB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGNvbnRlbnQ6IG1lc3NhZ2VQYXJ0LmNvbnRlbnQsXG4gICAgICB1c2VyOiBtZXNzYWdlUGFydC51c2VyISxcbiAgICB9O1xuICB9XG5cbiAgZ2V0TWVzc2FnZUFjdGlvbnNCb3hDb250ZXh0KCk6IE1lc3NhZ2VBY3Rpb25zQm94Q29udGV4dCB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGlzTWluZTogdGhpcy5pc1NlbnRCeUN1cnJlbnRVc2VyLFxuICAgICAgZW5hYmxlZEFjdGlvbnM6IHRoaXMuZW5hYmxlZE1lc3NhZ2VBY3Rpb25zLFxuICAgICAgbWVzc2FnZTogdGhpcy5tZXNzYWdlLFxuICAgIH07XG4gIH1cblxuICBnZXREZWxpdmVyZWRTdGF0dXNDb250ZXh0KCk6IERlbGl2ZXJlZFN0YXR1c0NvbnRleHQge1xuICAgIHJldHVybiB7XG4gICAgICBtZXNzYWdlOiB0aGlzLm1lc3NhZ2UhLFxuICAgIH07XG4gIH1cblxuICBnZXRTZW5kaW5nU3RhdHVzQ29udGV4dCgpOiBTZW5kaW5nU3RhdHVzQ29udGV4dCB7XG4gICAgcmV0dXJuIHtcbiAgICAgIG1lc3NhZ2U6IHRoaXMubWVzc2FnZSEsXG4gICAgfTtcbiAgfVxuXG4gIGdldFJlYWRTdGF0dXNDb250ZXh0KCk6IFJlYWRTdGF0dXNDb250ZXh0IHtcbiAgICByZXR1cm4ge1xuICAgICAgbWVzc2FnZTogdGhpcy5tZXNzYWdlISxcbiAgICAgIHJlYWRCeVRleHQ6IHRoaXMucmVhZEJ5VGV4dCxcbiAgICB9O1xuICB9XG5cbiAgZ2V0TWVzc2FnZU1ldGFkYXRhQ29udGV4dCgpOiBDdXN0b21NZXRhZGF0YUNvbnRleHQge1xuICAgIHJldHVybiB7XG4gICAgICBtZXNzYWdlOiB0aGlzLm1lc3NhZ2UhLFxuICAgIH07XG4gIH1cblxuICBqdW1wVG9NZXNzYWdlKG1lc3NhZ2VJZDogc3RyaW5nLCBwYXJlbnRNZXNzYWdlSWQ/OiBzdHJpbmcpIHtcbiAgICB2b2lkIHRoaXMuY2hhbm5lbFNlcnZpY2UuanVtcFRvTWVzc2FnZShtZXNzYWdlSWQsIHBhcmVudE1lc3NhZ2VJZCk7XG4gIH1cblxuICBkaXNwbGF5VHJhbnNsYXRlZE1lc3NhZ2UoKSB7XG4gICAgdGhpcy5jcmVhdGVNZXNzYWdlUGFydHModHJ1ZSk7XG4gIH1cblxuICBkaXNwbGF5T3JpZ2luYWxNZXNzYWdlKCkge1xuICAgIHRoaXMuY3JlYXRlTWVzc2FnZVBhcnRzKGZhbHNlKTtcbiAgfVxuXG4gIG9wZW5NZXNzYWdlQm91bmNlUHJvbXB0KCkge1xuICAgIHRoaXMuY2hhbm5lbFNlcnZpY2UuYm91bmNlZE1lc3NhZ2UkLm5leHQodGhpcy5tZXNzYWdlKTtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlTWVzc2FnZVBhcnRzKHNob3VsZFRyYW5zbGF0ZSA9IHRydWUpIHtcbiAgICB0aGlzLm1lc3NhZ2VUZXh0UGFydHMgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5tZXNzYWdlVGV4dCA9IHVuZGVmaW5lZDtcbiAgICBsZXQgY29udGVudCA9IHRoaXMuZ2V0TWVzc2FnZUNvbnRlbnQoc2hvdWxkVHJhbnNsYXRlKTtcbiAgICBpZiAoXG4gICAgICAoIXRoaXMubWVzc2FnZSEubWVudGlvbmVkX3VzZXJzIHx8XG4gICAgICAgIHRoaXMubWVzc2FnZSEubWVudGlvbmVkX3VzZXJzLmxlbmd0aCA9PT0gMCkgJiZcbiAgICAgICFjb250ZW50Py5tYXRjaCh0aGlzLmVtb2ppUmVnZXhwKSAmJlxuICAgICAgIWNvbnRlbnQ/Lm1hdGNoKHRoaXMudXJsUmVnZXhwKVxuICAgICkge1xuICAgICAgdGhpcy5tZXNzYWdlVGV4dFBhcnRzID0gdW5kZWZpbmVkO1xuICAgICAgdGhpcy5tZXNzYWdlVGV4dCA9IGNvbnRlbnQ7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICghY29udGVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoXG4gICAgICAhdGhpcy5tZXNzYWdlIS5tZW50aW9uZWRfdXNlcnMgfHxcbiAgICAgIHRoaXMubWVzc2FnZSEubWVudGlvbmVkX3VzZXJzLmxlbmd0aCA9PT0gMFxuICAgICkge1xuICAgICAgY29udGVudCA9IHRoaXMuZml4RW1vamlEaXNwbGF5KGNvbnRlbnQpO1xuICAgICAgY29udGVudCA9IHRoaXMud3JhcExpbmtzV2l0aEFuY2hvclRhZyhjb250ZW50KTtcbiAgICAgIHRoaXMubWVzc2FnZVRleHRQYXJ0cyA9IFt7IGNvbnRlbnQsIHR5cGU6ICd0ZXh0JyB9XTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5tZXNzYWdlVGV4dFBhcnRzID0gW107XG4gICAgICBsZXQgdGV4dCA9IGNvbnRlbnQ7XG4gICAgICB0aGlzLm1lc3NhZ2UhLm1lbnRpb25lZF91c2Vycy5mb3JFYWNoKCh1c2VyKSA9PiB7XG4gICAgICAgIGNvbnN0IG1lbnRpb24gPSBgQCR7dXNlci5uYW1lIHx8IHVzZXIuaWR9YDtcbiAgICAgICAgY29uc3QgcHJlY2VkaW5nVGV4dCA9IHRleHQuc3Vic3RyaW5nKDAsIHRleHQuaW5kZXhPZihtZW50aW9uKSk7XG4gICAgICAgIGxldCBmb3JtYXR0ZWRQcmVjZWRpbmdUZXh0ID0gdGhpcy5maXhFbW9qaURpc3BsYXkocHJlY2VkaW5nVGV4dCk7XG4gICAgICAgIGZvcm1hdHRlZFByZWNlZGluZ1RleHQgPSB0aGlzLndyYXBMaW5rc1dpdGhBbmNob3JUYWcoXG4gICAgICAgICAgZm9ybWF0dGVkUHJlY2VkaW5nVGV4dFxuICAgICAgICApO1xuICAgICAgICB0aGlzLm1lc3NhZ2VUZXh0UGFydHMhLnB1c2goe1xuICAgICAgICAgIGNvbnRlbnQ6IGZvcm1hdHRlZFByZWNlZGluZ1RleHQsXG4gICAgICAgICAgdHlwZTogJ3RleHQnLFxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5tZXNzYWdlVGV4dFBhcnRzIS5wdXNoKHtcbiAgICAgICAgICBjb250ZW50OiBtZW50aW9uLFxuICAgICAgICAgIHR5cGU6ICdtZW50aW9uJyxcbiAgICAgICAgICB1c2VyLFxuICAgICAgICB9KTtcbiAgICAgICAgdGV4dCA9IHRleHQucmVwbGFjZShwcmVjZWRpbmdUZXh0ICsgbWVudGlvbiwgJycpO1xuICAgICAgfSk7XG4gICAgICBpZiAodGV4dCkge1xuICAgICAgICB0ZXh0ID0gdGhpcy5maXhFbW9qaURpc3BsYXkodGV4dCk7XG4gICAgICAgIHRleHQgPSB0aGlzLndyYXBMaW5rc1dpdGhBbmNob3JUYWcodGV4dCk7XG4gICAgICAgIHRoaXMubWVzc2FnZVRleHRQYXJ0cy5wdXNoKHsgY29udGVudDogdGV4dCwgdHlwZTogJ3RleHQnIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZ2V0TWVzc2FnZUNvbnRlbnQoc2hvdWxkVHJhbnNsYXRlOiBib29sZWFuKSB7XG4gICAgY29uc3Qgb3JpZ2luYWxDb250ZW50ID0gdGhpcy5tZXNzYWdlPy50ZXh0O1xuICAgIGlmIChzaG91bGRUcmFuc2xhdGUpIHtcbiAgICAgIGNvbnN0IHRyYW5zbGF0aW9uID0gdGhpcy5tZXNzYWdlPy50cmFuc2xhdGlvbjtcbiAgICAgIGlmICh0cmFuc2xhdGlvbikge1xuICAgICAgICB0aGlzLnNob3VsZERpc3BsYXlUcmFuc2xhdGlvbk5vdGljZSA9IHRydWU7XG4gICAgICAgIHRoaXMuZGlzcGxheWVkTWVzc2FnZVRleHRDb250ZW50ID0gJ3RyYW5zbGF0aW9uJztcbiAgICAgIH1cbiAgICAgIHJldHVybiB0cmFuc2xhdGlvbiB8fCBvcmlnaW5hbENvbnRlbnQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZGlzcGxheWVkTWVzc2FnZVRleHRDb250ZW50ID0gJ29yaWdpbmFsJztcbiAgICAgIHJldHVybiBvcmlnaW5hbENvbnRlbnQ7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBmaXhFbW9qaURpc3BsYXkoY29udGVudDogc3RyaW5nKSB7XG4gICAgLy8gV3JhcCBlbW9qaXMgaW4gc3BhbiB0byBkaXNwbGF5IGVtb2ppcyBjb3JyZWN0bHkgaW4gQ2hyb21lIGh0dHBzOi8vYnVncy5jaHJvbWl1bS5vcmcvcC9jaHJvbWl1bS9pc3N1ZXMvZGV0YWlsP2lkPTU5NjIyM1xuICAgIC8vIEJhc2VkIG9uIHRoaXM6IGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzQ1NjUxMTIvamF2YXNjcmlwdC1ob3ctdG8tZmluZC1vdXQtaWYtdGhlLXVzZXItYnJvd3Nlci1pcy1jaHJvbWVcbiAgICAvKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW5zYWZlLW1lbWJlci1hY2Nlc3MsIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnkgKi9cbiAgICBjb25zdCBpc0Nocm9tZSA9XG4gICAgICAhISh3aW5kb3cgYXMgYW55KS5jaHJvbWUgJiYgdHlwZW9mICh3aW5kb3cgYXMgYW55KS5vcHIgPT09ICd1bmRlZmluZWQnO1xuICAgIC8qIGVzbGludC1lbmFibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVuc2FmZS1tZW1iZXItYWNjZXNzLCBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55ICovXG4gICAgY29udGVudCA9IGNvbnRlbnQucmVwbGFjZShcbiAgICAgIHRoaXMuZW1vamlSZWdleHAsXG4gICAgICAobWF0Y2gpID0+XG4gICAgICAgIGA8c3BhbiAke1xuICAgICAgICAgIGlzQ2hyb21lID8gJ2NsYXNzPVwic3RyLWNoYXRfX2Vtb2ppLWRpc3BsYXktZml4XCInIDogJydcbiAgICAgICAgfT4ke21hdGNofTwvc3Bhbj5gXG4gICAgKTtcblxuICAgIHJldHVybiBjb250ZW50O1xuICB9XG5cbiAgcHJpdmF0ZSB3cmFwTGlua3NXaXRoQW5jaG9yVGFnKGNvbnRlbnQ6IHN0cmluZykge1xuICAgIGlmICh0aGlzLmRpc3BsYXlBcyA9PT0gJ2h0bWwnKSB7XG4gICAgICByZXR1cm4gY29udGVudDtcbiAgICB9XG4gICAgY29udGVudCA9IGNvbnRlbnQucmVwbGFjZSh0aGlzLnVybFJlZ2V4cCwgKG1hdGNoKSA9PlxuICAgICAgdGhpcy5tZXNzYWdlU2VydmljZS5jdXN0b21MaW5rUmVuZGVyZXJcbiAgICAgICAgPyB0aGlzLm1lc3NhZ2VTZXJ2aWNlLmN1c3RvbUxpbmtSZW5kZXJlcihtYXRjaClcbiAgICAgICAgOiBgPGEgaHJlZj1cIiR7bWF0Y2h9XCIgdGFyZ2V0PVwiX2JsYW5rXCIgcmVsPVwibm9mb2xsb3dcIj4ke21hdGNofTwvYT5gXG4gICAgKTtcblxuICAgIHJldHVybiBjb250ZW50O1xuICB9XG5cbiAgcHJpdmF0ZSBzZXRJc1NlbnRCeUN1cnJlbnRVc2VyKCkge1xuICAgIHRoaXMuaXNTZW50QnlDdXJyZW50VXNlciA9IHRoaXMubWVzc2FnZT8udXNlcj8uaWQgPT09IHRoaXMudXNlcklkO1xuICB9XG5cbiAgcHJpdmF0ZSBzZXRMYXN0UmVhZFVzZXIoKSB7XG4gICAgdGhpcy5sYXN0UmVhZFVzZXIgPSB0aGlzLm1lc3NhZ2U/LnJlYWRCeT8uZmlsdGVyKFxuICAgICAgKHUpID0+IHUuaWQgIT09IHRoaXMudXNlcklkXG4gICAgKVswXTtcbiAgfVxufVxuIiwiPGRpdlxuICAjY29udGFpbmVyXG4gIGRhdGEtdGVzdGlkPVwibWVzc2FnZS1jb250YWluZXJcIlxuICBjbGFzcz1cInN0ci1jaGF0X19tZXNzYWdlLXNpbXBsZSBzdHItY2hhdF9fbWVzc2FnZSBzdHItY2hhdF9fbWVzc2FnZS0te3tcbiAgICBtZXNzYWdlPy50eXBlXG4gIH19IHN0ci1jaGF0X19tZXNzYWdlLS17eyBtZXNzYWdlPy5zdGF0dXMgfX0ge3tcbiAgICBtZXNzYWdlPy50ZXh0ID8gJ3N0ci1jaGF0X19tZXNzYWdlLS1oYXMtdGV4dCcgOiAnaGFzLW5vLXRleHQnXG4gIH19XCJcbiAgW2NsYXNzLnN0ci1jaGF0X19tZXNzYWdlLS1tZV09XCJpc1NlbnRCeUN1cnJlbnRVc2VyXCJcbiAgW2NsYXNzLnN0ci1jaGF0X19tZXNzYWdlLS1vdGhlcl09XCIhaXNTZW50QnlDdXJyZW50VXNlclwiXG4gIFtjbGFzcy5zdHItY2hhdF9fbWVzc2FnZS1zaW1wbGUtLW1lXT1cImlzU2VudEJ5Q3VycmVudFVzZXJcIlxuICBbY2xhc3Muc3RyLWNoYXRfX21lc3NhZ2UtLWhhcy1hdHRhY2htZW50XT1cImhhc0F0dGFjaG1lbnRcIlxuICBbY2xhc3Muc3RyLWNoYXRfX21lc3NhZ2UtLXdpdGgtcmVhY3Rpb25zXT1cImhhc1JlYWN0aW9uc1wiXG4gIFtjbGFzcy5zdHItY2hhdF9fbWVzc2FnZS0taGlnaGxpZ2h0ZWRdPVwiaXNIaWdobGlnaHRlZFwiXG4gIFtjbGFzcy5zdHItY2hhdF9fbWVzc2FnZS13aXRoLXRocmVhZC1saW5rXT1cInNob3VsZERpc3BsYXlUaHJlYWRMaW5rXCJcbiAgW2NsYXNzLnN0ci1jaGF0X19tZXNzYWdlLXNlbmQtY2FuLWJlLXJldHJpZWRdPVwiXG4gICAgKG1lc3NhZ2U/LnN0YXR1cyA9PT0gJ2ZhaWxlZCcgJiYgbWVzc2FnZT8uZXJyb3JTdGF0dXNDb2RlICE9PSA0MDMpIHx8XG4gICAgKG1lc3NhZ2U/LnR5cGUgPT09ICdlcnJvcicgJiYgbWVzc2FnZT8ubW9kZXJhdGlvbl9kZXRhaWxzKVxuICBcIlxuPlxuICA8bmctY29udGFpbmVyICpuZ0lmPVwiIW1lc3NhZ2U/LmRlbGV0ZWRfYXQ7IGVsc2UgZGVsZXRlZE1lc3NhZ2VcIj5cbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwibWVzc2FnZT8udHlwZSAhPT0gJ3N5c3RlbSc7IGVsc2Ugc3lzdGVtTWVzc2FnZVwiPlxuICAgICAgPHN0cmVhbS1hdmF0YXItcGxhY2Vob2xkZXJcbiAgICAgICAgZGF0YS10ZXN0aWQ9XCJhdmF0YXJcIlxuICAgICAgICBjbGFzcz1cInN0ci1jaGF0LWFuZ3VsYXJfX2F2YXRhci1ob3N0IHN0ci1jaGF0X19tZXNzYWdlLXNlbmRlci1hdmF0YXJcIlxuICAgICAgICB0eXBlPVwidXNlclwiXG4gICAgICAgIGxvY2F0aW9uPVwibWVzc2FnZS1zZW5kZXJcIlxuICAgICAgICBbaW1hZ2VVcmxdPVwibWVzc2FnZT8udXNlcj8uaW1hZ2VcIlxuICAgICAgICBbbmFtZV09XCJtZXNzYWdlPy51c2VyPy5uYW1lIHx8IG1lc3NhZ2U/LnVzZXI/LmlkXCJcbiAgICAgICAgW3VzZXJdPVwibWVzc2FnZT8udXNlciB8fCB1bmRlZmluZWRcIlxuICAgICAgPjwvc3RyZWFtLWF2YXRhci1wbGFjZWhvbGRlcj5cbiAgICAgIDxkaXYgY2xhc3M9XCJzdHItY2hhdF9fbWVzc2FnZS1pbm5lclwiPlxuICAgICAgICA8ZGl2XG4gICAgICAgICAgKm5nSWY9XCJhcmVPcHRpb25zVmlzaWJsZVwiXG4gICAgICAgICAgY2xhc3M9XCJzdHItY2hhdF9fbWVzc2FnZS1zaW1wbGVfX2FjdGlvbnMgc3RyLWNoYXRfX21lc3NhZ2Utb3B0aW9uc1wiXG4gICAgICAgICAgZGF0YS10ZXN0aWQ9XCJtZXNzYWdlLW9wdGlvbnNcIlxuICAgICAgICAgIFtjbGFzcy5zdHItY2hhdF9fbWVzc2FnZS1hY3Rpb25zLW9wZW5dPVwiaXNBY3Rpb25Cb3hPcGVuXCJcbiAgICAgICAgPlxuICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICNtZXNzYWdlQWN0aW9uc1RvZ2dsZVxuICAgICAgICAgICAgZGF0YS10ZXN0aWQ9XCJtZXNzYWdlLWFjdGlvbnMtY29udGFpbmVyXCJcbiAgICAgICAgICAgIGNsYXNzPVwiXG4gICAgICAgICAgICAgIHN0ci1jaGF0X19tZXNzYWdlLWFjdGlvbnMtY29udGFpbmVyXG4gICAgICAgICAgICAgIHN0ci1jaGF0X19tZXNzYWdlLXNpbXBsZV9fYWN0aW9uc19fYWN0aW9uXG4gICAgICAgICAgICAgIHN0ci1jaGF0X19tZXNzYWdlLXNpbXBsZV9fYWN0aW9uc19fYWN0aW9uLS1vcHRpb25zXG4gICAgICAgICAgICBcIlxuICAgICAgICAgICAgW2Zsb2F0VWlMb29zZV09XCJmbG9hdGluZ0NvbnRlbnRcIlxuICAgICAgICAgICAgbG9vc2VUcmlnZ2VyPVwiY2xpY2tcIlxuICAgICAgICAgICAgW2hpZGVPblNjcm9sbF09XCJmYWxzZVwiXG4gICAgICAgICAgICBbaGlkZU9uQ2xpY2tPdXRzaWRlXT1cInRydWVcIlxuICAgICAgICAgICAgW2hpZGVPbk1vdXNlTGVhdmVdPVwiZmFsc2VcIlxuICAgICAgICAgICAgW2Rpc2FibGVBbmltYXRpb25dPVwidHJ1ZVwiXG4gICAgICAgICAgICAob25IaWRkZW4pPVwiaXNBY3Rpb25Cb3hPcGVuID0gZmFsc2VcIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIDxmbG9hdC11aS1jb250ZW50ICNmbG9hdGluZ0NvbnRlbnQ+XG4gICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZVxuICAgICAgICAgICAgICAgICNkZWZhdWx0TWVzc2FnZUFjdGlvbnNCb3hcbiAgICAgICAgICAgICAgICBsZXQtaXNNaW5lPVwiaXNNaW5lXCJcbiAgICAgICAgICAgICAgICBsZXQtbWVzc2FnZUlucHV0PVwibWVzc2FnZVwiXG4gICAgICAgICAgICAgICAgbGV0LWVuYWJsZWRBY3Rpb25zPVwiZW5hYmxlZEFjdGlvbnNcIlxuICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgPHN0cmVhbS1tZXNzYWdlLWFjdGlvbnMtYm94XG4gICAgICAgICAgICAgICAgICBbaXNNaW5lXT1cImlzTWluZVwiXG4gICAgICAgICAgICAgICAgICBbbWVzc2FnZV09XCJtZXNzYWdlSW5wdXRcIlxuICAgICAgICAgICAgICAgICAgW2VuYWJsZWRBY3Rpb25zXT1cImVuYWJsZWRBY3Rpb25zXCJcbiAgICAgICAgICAgICAgICAgIChjbGljayk9XCJtZXNzYWdlQWN0aW9uc0JveENsaWNrZWQoZmxvYXRpbmdDb250ZW50KVwiXG4gICAgICAgICAgICAgICAgPjwvc3RyZWFtLW1lc3NhZ2UtYWN0aW9ucy1ib3g+XG4gICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpc0FjdGlvbkJveE9wZW5cIj5cbiAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgICAgICAgICAqbmdUZW1wbGF0ZU91dGxldD1cIlxuICAgICAgICAgICAgICAgICAgICAoY3VzdG9tVGVtcGxhdGVzU2VydmljZS5tZXNzYWdlQWN0aW9uc0JveFRlbXBsYXRlJFxuICAgICAgICAgICAgICAgICAgICAgIHwgYXN5bmMpIHx8IGRlZmF1bHRNZXNzYWdlQWN0aW9uc0JveDtcbiAgICAgICAgICAgICAgICAgICAgY29udGV4dDogZ2V0TWVzc2FnZUFjdGlvbnNCb3hDb250ZXh0KClcbiAgICAgICAgICAgICAgICAgIFwiXG4gICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwvZmxvYXQtdWktY29udGVudD5cbiAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgKm5nSWY9XCJ2aXNpYmxlTWVzc2FnZUFjdGlvbnNDb3VudCA+IDBcIlxuICAgICAgICAgICAgICBjbGFzcz1cInN0ci1jaGF0X19tZXNzYWdlLWFjdGlvbnMtYm94LWJ1dHRvblwiXG4gICAgICAgICAgICAgIGRhdGEtdGVzdGlkPVwiYWN0aW9uLWljb25cIlxuICAgICAgICAgICAgICAoY2xpY2spPVwibWVzc2FnZUFjdGlvbnNDbGlja2VkKClcIlxuICAgICAgICAgICAgICAoa2V5dXAuZW50ZXIpPVwibWVzc2FnZUFjdGlvbnNDbGlja2VkKClcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICA8c3RyZWFtLWljb24tcGxhY2Vob2xkZXJcbiAgICAgICAgICAgICAgICBpY29uPVwiYWN0aW9uLWljb25cIlxuICAgICAgICAgICAgICAgIGNsYXNzPVwic3RyLWNoYXRfX21lc3NhZ2UtYWN0aW9uLWljb25cIlxuICAgICAgICAgICAgICA+PC9zdHJlYW0taWNvbi1wbGFjZWhvbGRlcj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICpuZ0lmPVwiXG4gICAgICAgICAgICAgIGVuYWJsZWRNZXNzYWdlQWN0aW9ucy5pbmRleE9mKCdzZW5kLXJlcGx5JykgIT09IC0xICYmXG4gICAgICAgICAgICAgIG1vZGUgPT09ICdtYWluJ1xuICAgICAgICAgICAgXCJcbiAgICAgICAgICAgIGNsYXNzPVwiXG4gICAgICAgICAgICAgIHN0ci1jaGF0X19tZXNzYWdlLXNpbXBsZV9fYWN0aW9uc19fYWN0aW9uXG4gICAgICAgICAgICAgIHN0ci1jaGF0X19tZXNzYWdlLXNpbXBsZV9fYWN0aW9uc19fYWN0aW9uLS10aHJlYWRcbiAgICAgICAgICAgICAgc3RyLWNoYXRfX21lc3NhZ2UtcmVwbHktaW4tdGhyZWFkLWJ1dHRvblxuICAgICAgICAgICAgXCJcbiAgICAgICAgICAgIGRhdGEtdGVzdGlkPVwicmVwbHktaW4tdGhyZWFkXCJcbiAgICAgICAgICAgIChjbGljayk9XCJzZXRBc0FjdGl2ZVBhcmVudE1lc3NhZ2UoKVwiXG4gICAgICAgICAgICAoa2V5dXAuZW50ZXIpPVwic2V0QXNBY3RpdmVQYXJlbnRNZXNzYWdlKClcIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIDxzdHJlYW0taWNvbi1wbGFjZWhvbGRlclxuICAgICAgICAgICAgICBjbGFzcz1cInN0ci1jaGF0X19tZXNzYWdlLWFjdGlvbi1pY29uXCJcbiAgICAgICAgICAgICAgaWNvbj1cInJlcGx5LWluLXRocmVhZFwiXG4gICAgICAgICAgICA+PC9zdHJlYW0taWNvbi1wbGFjZWhvbGRlcj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAqbmdJZj1cImNhblJlYWN0VG9NZXNzYWdlXCJcbiAgICAgICAgICAgIGNsYXNzPVwiXG4gICAgICAgICAgICAgIHN0ci1jaGF0X19tZXNzYWdlLXNpbXBsZV9fYWN0aW9uc19fYWN0aW9uXG4gICAgICAgICAgICAgIHN0ci1jaGF0X19tZXNzYWdlLXNpbXBsZV9fYWN0aW9uc19fYWN0aW9uLS1yZWFjdGlvbnNcbiAgICAgICAgICAgICAgc3RyLWNoYXRfX21lc3NhZ2UtcmVhY3Rpb25zLWJ1dHRvblxuICAgICAgICAgICAgXCJcbiAgICAgICAgICAgIGRhdGEtdGVzdGlkPVwicmVhY3Rpb24taWNvblwiXG4gICAgICAgICAgICAoY2xpY2spPVwiaXNSZWFjdGlvblNlbGVjdG9yT3BlbiA9ICFpc1JlYWN0aW9uU2VsZWN0b3JPcGVuXCJcbiAgICAgICAgICAgIChrZXl1cC5lbnRlcik9XCJpc1JlYWN0aW9uU2VsZWN0b3JPcGVuID0gIWlzUmVhY3Rpb25TZWxlY3Rvck9wZW5cIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIDxzdHJlYW0taWNvbi1wbGFjZWhvbGRlclxuICAgICAgICAgICAgICBjbGFzcz1cInN0ci1jaGF0X19tZXNzYWdlLWFjdGlvbi1pY29uXCJcbiAgICAgICAgICAgICAgaWNvbj1cInJlYWN0aW9uLWljb25cIlxuICAgICAgICAgICAgPjwvc3RyZWFtLWljb24tcGxhY2Vob2xkZXI+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwic3RyLWNoYXRfX21lc3NhZ2UtcmVhY3Rpb25zLWhvc3RcIj5cbiAgICAgICAgICA8bmctdGVtcGxhdGVcbiAgICAgICAgICAgICNkZWZhdWx0TWVzc2FnZVJlYWN0aW9uc1xuICAgICAgICAgICAgbGV0LW1lc3NhZ2VSZWFjdGlvbkNvdW50cz1cIm1lc3NhZ2VSZWFjdGlvbkNvdW50c1wiXG4gICAgICAgICAgICBsZXQtbGF0ZXN0UmVhY3Rpb25zPVwibGF0ZXN0UmVhY3Rpb25zXCJcbiAgICAgICAgICAgIGxldC1pc1NlbGVjdG9yT3Blbj1cImlzU2VsZWN0b3JPcGVuXCJcbiAgICAgICAgICAgIGxldC1pc1NlbGVjdG9yT3BlbkNoYW5nZUhhbmRsZXI9XCJpc1NlbGVjdG9yT3BlbkNoYW5nZUhhbmRsZXJcIlxuICAgICAgICAgICAgbGV0LW1lc3NhZ2VJZD1cIm1lc3NhZ2VJZFwiXG4gICAgICAgICAgICBsZXQtb3duUmVhY3Rpb25zPVwib3duUmVhY3Rpb25zXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICA8c3RyZWFtLW1lc3NhZ2UtcmVhY3Rpb25zXG4gICAgICAgICAgICAgIFttZXNzYWdlUmVhY3Rpb25Db3VudHNdPVwibWVzc2FnZVJlYWN0aW9uQ291bnRzXCJcbiAgICAgICAgICAgICAgW2xhdGVzdFJlYWN0aW9uc109XCJsYXRlc3RSZWFjdGlvbnNcIlxuICAgICAgICAgICAgICBbaXNTZWxlY3Rvck9wZW5dPVwiaXNTZWxlY3Rvck9wZW5cIlxuICAgICAgICAgICAgICBbbWVzc2FnZUlkXT1cIm1lc3NhZ2VJZFwiXG4gICAgICAgICAgICAgIFtvd25SZWFjdGlvbnNdPVwib3duUmVhY3Rpb25zXCJcbiAgICAgICAgICAgICAgKGlzU2VsZWN0b3JPcGVuQ2hhbmdlKT1cImlzU2VsZWN0b3JPcGVuQ2hhbmdlSGFuZGxlcigkZXZlbnQpXCJcbiAgICAgICAgICAgID48L3N0cmVhbS1tZXNzYWdlLXJlYWN0aW9ucz5cbiAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAgICpuZ1RlbXBsYXRlT3V0bGV0PVwiXG4gICAgICAgICAgICAgIChjdXN0b21UZW1wbGF0ZXNTZXJ2aWNlLm1lc3NhZ2VSZWFjdGlvbnNUZW1wbGF0ZSQgfCBhc3luYykgfHxcbiAgICAgICAgICAgICAgICBkZWZhdWx0TWVzc2FnZVJlYWN0aW9ucztcbiAgICAgICAgICAgICAgY29udGV4dDogZ2V0TWVzc2FnZVJlYWN0aW9uc0NvbnRleHQoKVxuICAgICAgICAgICAgXCJcbiAgICAgICAgICA+PC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8ZGl2XG4gICAgICAgICAgY2xhc3M9XCJzdHItY2hhdF9fbWVzc2FnZS1idWJibGUgc3RyLWNoYXQtYW5ndWxhcl9fbWVzc2FnZS1idWJibGVcIlxuICAgICAgICAgIFtjbGFzcy5zdHItY2hhdC1hbmd1bGFyX19tZXNzYWdlLWJ1YmJsZS0tYXR0YWNobWVudC1tb2RhbC1vcGVuXT1cIlxuICAgICAgICAgICAgaW1hZ2VBdHRhY2htZW50TW9kYWxTdGF0ZSA9PT0gJ29wZW5lZCdcbiAgICAgICAgICBcIlxuICAgICAgICA+XG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImhhc0F0dGFjaG1lbnQgJiYgIW1lc3NhZ2U/LnF1b3RlZF9tZXNzYWdlXCI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgICAgICpuZ1RlbXBsYXRlT3V0bGV0PVwiYXR0YWNobWVudHNUZW1wbGF0ZVwiXG4gICAgICAgICAgICA+PC9uZy1jb250YWluZXI+XG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgPGRpdlxuICAgICAgICAgICAgKm5nSWY9XCJtZXNzYWdlPy50ZXh0IHx8IChtZXNzYWdlPy5xdW90ZWRfbWVzc2FnZSAmJiBoYXNBdHRhY2htZW50KVwiXG4gICAgICAgICAgICBjbGFzcz1cInN0ci1jaGF0X19tZXNzYWdlLXRleHRcIlxuICAgICAgICAgICAgdGFiaW5kZXg9XCIwXCJcbiAgICAgICAgICAgIFtjbGFzcy5zdHItY2hhdF9fbWVzc2FnZS10ZXh0LS1wb2ludGVyLWN1cnNvcl09XCJcbiAgICAgICAgICAgICAgKG1lc3NhZ2U/LnN0YXR1cyA9PT0gJ2ZhaWxlZCcgJiZcbiAgICAgICAgICAgICAgICBtZXNzYWdlPy5lcnJvclN0YXR1c0NvZGUgIT09IDQwMykgfHxcbiAgICAgICAgICAgICAgKHRoaXMubWVzc2FnZT8udHlwZSA9PT0gJ2Vycm9yJyAmJlxuICAgICAgICAgICAgICAgIHRoaXMubWVzc2FnZT8ubW9kZXJhdGlvbl9kZXRhaWxzKSB8fFxuICAgICAgICAgICAgICBtZXNzYWdlPy5tZXNzYWdlX3RleHRfdXBkYXRlZF9hdFxuICAgICAgICAgICAgXCJcbiAgICAgICAgICAgIChjbGljayk9XCJtZXNzYWdlQ2xpY2tlZCgpXCJcbiAgICAgICAgICAgIChrZXl1cC5lbnRlcik9XCJtZXNzYWdlQ2xpY2tlZCgpXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgIGRhdGEtdGVzdGlkPVwiaW5uZXItbWVzc2FnZVwiXG4gICAgICAgICAgICAgIGNsYXNzPVwiXG4gICAgICAgICAgICAgICAgc3RyLWNoYXRfX21lc3NhZ2UtdGV4dC1pbm5lciBzdHItY2hhdF9fbWVzc2FnZS1zaW1wbGUtdGV4dC1pbm5lclxuICAgICAgICAgICAgICBcIlxuICAgICAgICAgICAgICBbY2xhc3Muc3RyLWNoYXRfX21lc3NhZ2UtbGlnaHQtdGV4dC1pbm5lci0taGFzLWF0dGFjaG1lbnRdPVwiXG4gICAgICAgICAgICAgICAgaGFzQXR0YWNobWVudFxuICAgICAgICAgICAgICBcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwicXVvdGVkTWVzc2FnZVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaGFzQXR0YWNobWVudCAmJiBtZXNzYWdlPy5xdW90ZWRfbWVzc2FnZVwiPlxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAgICAgICAgICpuZ1RlbXBsYXRlT3V0bGV0PVwiYXR0YWNobWVudHNUZW1wbGF0ZVwiXG4gICAgICAgICAgICAgICAgPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgICpuZ0lmPVwibWVzc2FnZT8udHlwZSA9PT0gJ2Vycm9yJ1wiXG4gICAgICAgICAgICAgICAgZGF0YS10ZXN0aWQ9XCJjbGllbnQtZXJyb3ItbWVzc2FnZVwiXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJcbiAgICAgICAgICAgICAgICAgIHN0ci1jaGF0X19zaW1wbGUtbWVzc2FnZS0tZXJyb3ItbWVzc2FnZVxuICAgICAgICAgICAgICAgICAgc3RyLWNoYXRfX21lc3NhZ2UtLWVycm9yLW1lc3NhZ2VcbiAgICAgICAgICAgICAgICBcIlxuICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFtZXNzYWdlPy5tb2RlcmF0aW9uX2RldGFpbHNcIj57e1xuICAgICAgICAgICAgICAgICAgXCJzdHJlYW1DaGF0LkVycm9yIMK3IFVuc2VudFwiIHwgdHJhbnNsYXRlXG4gICAgICAgICAgICAgICAgfX08L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICAqbmdJZj1cIm1lc3NhZ2U/LnN0YXR1cyA9PT0gJ2ZhaWxlZCdcIlxuICAgICAgICAgICAgICAgIGRhdGEtdGVzdGlkPVwiZXJyb3ItbWVzc2FnZVwiXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJcbiAgICAgICAgICAgICAgICAgIHN0ci1jaGF0X19zaW1wbGUtbWVzc2FnZS0tZXJyb3ItbWVzc2FnZVxuICAgICAgICAgICAgICAgICAgc3RyLWNoYXRfX21lc3NhZ2UtLWVycm9yLW1lc3NhZ2VcbiAgICAgICAgICAgICAgICBcIlxuICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAge3tcbiAgICAgICAgICAgICAgICAgIChtZXNzYWdlPy5lcnJvclN0YXR1c0NvZGUgPT09IDQwM1xuICAgICAgICAgICAgICAgICAgICA/IFwic3RyZWFtQ2hhdC5NZXNzYWdlIEZhaWxlZCDCtyBVbmF1dGhvcml6ZWRcIlxuICAgICAgICAgICAgICAgICAgICA6IFwic3RyZWFtQ2hhdC5NZXNzYWdlIEZhaWxlZCDCtyBDbGljayB0byB0cnkgYWdhaW5cIlxuICAgICAgICAgICAgICAgICAgKSB8IHRyYW5zbGF0ZVxuICAgICAgICAgICAgICAgIH19XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8ZGl2IGRhdGEtdGVzdGlkPVwidGV4dFwiPlxuICAgICAgICAgICAgICAgIDxwPlxuICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIm1lc3NhZ2VUZXh0UGFydHM7IGVsc2UgZGVmYXVsdENvbnRlbnRcIj5cbiAgICAgICAgICAgICAgICAgICAgPCEtLSBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQGFuZ3VsYXItZXNsaW50L3RlbXBsYXRlL3VzZS10cmFjay1ieS1mdW5jdGlvbiAtLT5cbiAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgcGFydCBvZiBtZXNzYWdlVGV4dFBhcnRzXCI+XG4gICAgICAgICAgICAgICAgICAgICAgPHNwYW5cbiAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwicGFydC50eXBlID09PSAndGV4dCc7IGVsc2UgbWVudGlvblwiXG4gICAgICAgICAgICAgICAgICAgICAgICBbaW5uZXJIVE1MXT1cInBhcnQuY29udGVudFwiXG4gICAgICAgICAgICAgICAgICAgICAgPjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgI21lbnRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgI2RlZmF1bHRNZW50aW9uIGxldC1jb250ZW50PVwiY29udGVudFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInN0ci1jaGF0X19tZXNzYWdlLW1lbnRpb25cIj57e1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRlbnRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdUZW1wbGF0ZU91dGxldD1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjdXN0b21UZW1wbGF0ZXNTZXJ2aWNlLm1lbnRpb25UZW1wbGF0ZSQgfCBhc3luYykgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHRNZW50aW9uO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRleHQ6IGdldE1lbnRpb25Db250ZXh0KHBhcnQpXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFwiXG4gICAgICAgICAgICAgICAgICAgICAgICA+PC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjZGVmYXVsdENvbnRlbnQ+XG4gICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJkaXNwbGF5QXMgPT09ICd0ZXh0JzsgZWxzZSBhc0hUTUxcIj5cbiAgICAgICAgICAgICAgICAgICAgICB7eyBtZXNzYWdlVGV4dCB8fCBcIlwiIH19XG4gICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgI2FzSFRNTFxuICAgICAgICAgICAgICAgICAgICAgID48c3BhblxuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YS10ZXN0aWQ9XCJodG1sLWNvbnRlbnRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2lubmVySFRNTF09XCJtZXNzYWdlVGV4dFwiXG4gICAgICAgICAgICAgICAgICAgICAgPjwvc3BhblxuICAgICAgICAgICAgICAgICAgICA+PC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgPC9wPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDxzdHJlYW0taWNvbi1wbGFjZWhvbGRlclxuICAgICAgICAgICAgY2xhc3M9XCJzdHItY2hhdF9fbWVzc2FnZS1lcnJvci1pY29uXCJcbiAgICAgICAgICAgIGljb249XCJlcnJvclwiXG4gICAgICAgICAgPjwvc3RyZWFtLWljb24tcGxhY2Vob2xkZXI+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICpuZ1RlbXBsYXRlT3V0bGV0PVwicmVwbHlDb3VudEJ1dHRvbjsgY29udGV4dDogeyBtZXNzYWdlOiBtZXNzYWdlIH1cIlxuICAgICAgPjwvbmctY29udGFpbmVyPlxuXG4gICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwibWVzc2FnZURhdGVBbmRTZW5kZXJcIj48L25nLWNvbnRhaW5lcj5cbiAgICA8L25nLWNvbnRhaW5lcj5cbiAgPC9uZy1jb250YWluZXI+XG48L2Rpdj5cblxuPG5nLXRlbXBsYXRlICNkZWxldGVkTWVzc2FnZT5cbiAgPGRpdiBkYXRhLXRlc3RpZD1cIm1lc3NhZ2UtZGVsZXRlZC1jb21wb25lbnRcIj5cbiAgICA8ZGl2IGNsYXNzPVwic3RyLWNoYXRfX21lc3NhZ2UtLWRlbGV0ZWQtaW5uZXJcIiB0cmFuc2xhdGU+XG4gICAgICBzdHJlYW1DaGF0LlRoaXMgbWVzc2FnZSB3YXMgZGVsZXRlZC4uLlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbjwvbmctdGVtcGxhdGU+XG5cbjxuZy10ZW1wbGF0ZSAjc3lzdGVtTWVzc2FnZT5cbiAgPG5nLWNvbnRhaW5lclxuICAgICpuZ1RlbXBsYXRlT3V0bGV0PVwiXG4gICAgICAoY3VzdG9tVGVtcGxhdGVzU2VydmljZS5zeXN0ZW1NZXNzYWdlVGVtcGxhdGUkIHwgYXN5bmMpIHx8XG4gICAgICAgIGRlZmF1bHRTeXN0ZW1NZXNzYWdlO1xuICAgICAgY29udGV4dDogZ2V0TWVzc2FnZUNvbnRleHQoKVxuICAgIFwiXG4gID48L25nLWNvbnRhaW5lcj5cbiAgPG5nLXRlbXBsYXRlICNkZWZhdWx0U3lzdGVtTWVzc2FnZSBsZXQtbWVzc2FnZUlucHV0PVwibWVzc2FnZVwiPlxuICAgIDxkaXYgZGF0YS10ZXN0aWQ9XCJzeXN0ZW0tbWVzc2FnZVwiIGNsYXNzPVwic3RyLWNoYXRfX21lc3NhZ2UtLXN5c3RlbVwiPlxuICAgICAgPGRpdiBjbGFzcz1cInN0ci1jaGF0X19tZXNzYWdlLS1zeXN0ZW1fX3RleHRcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInN0ci1jaGF0X19tZXNzYWdlLS1zeXN0ZW1fX2xpbmVcIj48L2Rpdj5cbiAgICAgICAgPHA+e3sgbWVzc2FnZUlucHV0Py50ZXh0IH19PC9wPlxuICAgICAgICA8ZGl2IGNsYXNzPVwic3RyLWNoYXRfX21lc3NhZ2UtLXN5c3RlbV9fbGluZVwiPjwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwic3RyLWNoYXRfX21lc3NhZ2UtLXN5c3RlbV9fZGF0ZVwiPlxuICAgICAgICB7eyBwYXJzZWREYXRlIH19XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9uZy10ZW1wbGF0ZT5cbjwvbmctdGVtcGxhdGU+XG5cbjxuZy10ZW1wbGF0ZSAjcXVvdGVkTWVzc2FnZT5cbiAgPGRpdlxuICAgICpuZ0lmPVwibWVzc2FnZT8ucXVvdGVkX21lc3NhZ2VcIlxuICAgIGNsYXNzPVwicXVvdGVkLW1lc3NhZ2Ugc3RyLWNoYXRfX3F1b3RlZC1tZXNzYWdlLXByZXZpZXdcIlxuICAgIGRhdGEtdGVzdGlkPVwicXVvdGVkLW1lc3NhZ2UtY29udGFpbmVyXCJcbiAgICBbY2xhc3MubWluZV09XCJpc1NlbnRCeUN1cnJlbnRVc2VyXCJcbiAgICAoY2xpY2spPVwiXG4gICAgICBqdW1wVG9NZXNzYWdlKFxuICAgICAgICAobWVzc2FnZT8ucXVvdGVkX21lc3NhZ2UpIS5pZCxcbiAgICAgICAgbWVzc2FnZT8ucXVvdGVkX21lc3NhZ2U/LnBhcmVudF9pZFxuICAgICAgKVxuICAgIFwiXG4gICAgKGtleXVwLmVudGVyKT1cIlxuICAgICAganVtcFRvTWVzc2FnZShcbiAgICAgICAgKG1lc3NhZ2U/LnF1b3RlZF9tZXNzYWdlKSEuaWQsXG4gICAgICAgIG1lc3NhZ2U/LnF1b3RlZF9tZXNzYWdlPy5wYXJlbnRfaWRcbiAgICAgIClcbiAgICBcIlxuICA+XG4gICAgPHN0cmVhbS1hdmF0YXItcGxhY2Vob2xkZXJcbiAgICAgIGRhdGEtdGVzdGlkPVwicW91dGVkLW1lc3NhZ2UtYXZhdGFyXCJcbiAgICAgIGNsYXNzPVwic3RyLWNoYXQtYW5ndWxhcl9fYXZhdGFyLWhvc3Qgc3RyLWNoYXRfX21lc3NhZ2Utc2VuZGVyLWF2YXRhclwiXG4gICAgICB0eXBlPVwidXNlclwiXG4gICAgICBsb2NhdGlvbj1cInF1b3RlZC1tZXNzYWdlLXNlbmRlclwiXG4gICAgICBbaW1hZ2VVcmxdPVwibWVzc2FnZT8ucXVvdGVkX21lc3NhZ2U/LnVzZXI/LmltYWdlXCJcbiAgICAgIFtuYW1lXT1cIlxuICAgICAgICBtZXNzYWdlPy5xdW90ZWRfbWVzc2FnZT8udXNlcj8ubmFtZSB8fCBtZXNzYWdlPy5xdW90ZWRfbWVzc2FnZT8udXNlcj8uaWRcbiAgICAgIFwiXG4gICAgICBbc2l6ZV09XCIyMFwiXG4gICAgICBbdXNlcl09XCJtZXNzYWdlPy5xdW90ZWRfbWVzc2FnZT8udXNlciB8fCB1bmRlZmluZWRcIlxuICAgID48L3N0cmVhbS1hdmF0YXItcGxhY2Vob2xkZXI+XG4gICAgPGRpdiBjbGFzcz1cInF1b3RlZC1tZXNzYWdlLWlubmVyIHN0ci1jaGF0X19xdW90ZWQtbWVzc2FnZS1idWJibGVcIj5cbiAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgKm5nSWY9XCJcbiAgICAgICAgICBtZXNzYWdlPy5xdW90ZWRfbWVzc2FnZT8uYXR0YWNobWVudHMgJiZcbiAgICAgICAgICBtZXNzYWdlPy5xdW90ZWRfbWVzc2FnZT8uYXR0YWNobWVudHM/Lmxlbmd0aFxuICAgICAgICBcIlxuICAgICAgPlxuICAgICAgICA8bmctdGVtcGxhdGVcbiAgICAgICAgICAjZGVmYXVsdEF0dGFjaG1lbnRzXG4gICAgICAgICAgbGV0LW1lc3NhZ2VJZD1cIm1lc3NhZ2VJZFwiXG4gICAgICAgICAgbGV0LWF0dGFjaG1lbnRzPVwiYXR0YWNobWVudHNcIlxuICAgICAgICAgIGxldC1wYXJlbnRNZXNzYWdlSWQ9XCJwYXJlbnRNZXNzYWdlSWRcIlxuICAgICAgICAgIGxldC1pbWFnZU1vZGFsU3RhdGVDaGFuZ2VIYW5kbGVyPVwiaW1hZ2VNb2RhbFN0YXRlQ2hhbmdlSGFuZGxlclwiXG4gICAgICAgID5cbiAgICAgICAgICA8c3RyZWFtLWF0dGFjaG1lbnQtbGlzdFxuICAgICAgICAgICAgW21lc3NhZ2VJZF09XCJtZXNzYWdlSWRcIlxuICAgICAgICAgICAgW2F0dGFjaG1lbnRzXT1cImF0dGFjaG1lbnRzXCJcbiAgICAgICAgICAgIFtwYXJlbnRNZXNzYWdlSWRdPVwicGFyZW50TWVzc2FnZUlkXCJcbiAgICAgICAgICAgIChpbWFnZU1vZGFsU3RhdGVDaGFuZ2UpPVwiaW1hZ2VNb2RhbFN0YXRlQ2hhbmdlSGFuZGxlcigkZXZlbnQpXCJcbiAgICAgICAgICA+PC9zdHJlYW0tYXR0YWNobWVudC1saXN0PlxuICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgKm5nVGVtcGxhdGVPdXRsZXQ9XCJcbiAgICAgICAgICAgIChjdXN0b21UZW1wbGF0ZXNTZXJ2aWNlLmF0dGFjaG1lbnRMaXN0VGVtcGxhdGUkIHwgYXN5bmMpIHx8XG4gICAgICAgICAgICAgIGRlZmF1bHRBdHRhY2htZW50cztcbiAgICAgICAgICAgIGNvbnRleHQ6IGdldFF1b3RlZE1lc3NhZ2VBdHRhY2htZW50TGlzdENvbnRleHQoKVxuICAgICAgICAgIFwiXG4gICAgICAgID48L25nLWNvbnRhaW5lcj5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgPGRpdlxuICAgICAgICBkYXRhLXRlc3RpZD1cInF1b3RlZC1tZXNzYWdlLXRleHRcIlxuICAgICAgICBbaW5uZXJIVE1MXT1cIlxuICAgICAgICAgIG1lc3NhZ2U/LnF1b3RlZF9tZXNzYWdlPy50cmFuc2xhdGlvbiB8fFxuICAgICAgICAgIG1lc3NhZ2U/LnF1b3RlZF9tZXNzYWdlPy5odG1sIHx8XG4gICAgICAgICAgbWVzc2FnZT8ucXVvdGVkX21lc3NhZ2U/LnRleHRcbiAgICAgICAgXCJcbiAgICAgID48L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L25nLXRlbXBsYXRlPlxuXG48bmctdGVtcGxhdGUgI21lc3NhZ2VEYXRlQW5kU2VuZGVyPlxuICA8bmctY29udGFpbmVyPlxuICAgIDxkaXZcbiAgICAgICpuZ0lmPVwic2hvdWxkRGlzcGxheVRyYW5zbGF0aW9uTm90aWNlXCJcbiAgICAgIGNsYXNzPVwic3RyLWNoYXRfX3RyYW5zbGF0aW9uLW5vdGljZVwiXG4gICAgICBkYXRhLXRlc3RpZD1cInRyYW5zbGF0aW9uLW5vdGljZVwiXG4gICAgPlxuICAgICAgPGJ1dHRvblxuICAgICAgICAqbmdJZj1cImRpc3BsYXllZE1lc3NhZ2VUZXh0Q29udGVudCA9PT0gJ3RyYW5zbGF0aW9uJ1wiXG4gICAgICAgIGRhdGEtdGVzdGlkPVwic2VlLW9yaWdpbmFsXCJcbiAgICAgICAgdHJhbnNsYXRlXG4gICAgICAgIChjbGljayk9XCJkaXNwbGF5T3JpZ2luYWxNZXNzYWdlKClcIlxuICAgICAgICAoa2V5dXAuZW50ZXIpPVwiZGlzcGxheU9yaWdpbmFsTWVzc2FnZSgpXCJcbiAgICAgID5cbiAgICAgICAgc3RyZWFtQ2hhdC5TZWUgb3JpZ2luYWwgKGF1dG9tYXRpY2FsbHkgdHJhbnNsYXRlZClcbiAgICAgIDwvYnV0dG9uPlxuICAgICAgPGJ1dHRvblxuICAgICAgICAqbmdJZj1cImRpc3BsYXllZE1lc3NhZ2VUZXh0Q29udGVudCA9PT0gJ29yaWdpbmFsJ1wiXG4gICAgICAgIGRhdGEtdGVzdGlkPVwic2VlLXRyYW5zbGF0aW9uXCJcbiAgICAgICAgdHJhbnNsYXRlXG4gICAgICAgIChjbGljayk9XCJkaXNwbGF5VHJhbnNsYXRlZE1lc3NhZ2UoKVwiXG4gICAgICAgIChrZXl1cC5lbnRlcik9XCJkaXNwbGF5VHJhbnNsYXRlZE1lc3NhZ2UoKVwiXG4gICAgICA+XG4gICAgICAgIHN0cmVhbUNoYXQuU2VlIHRyYW5zbGF0aW9uXG4gICAgICA8L2J1dHRvbj5cbiAgICA8L2Rpdj5cbiAgICA8bmctY29udGFpbmVyXG4gICAgICAqbmdJZj1cImN1c3RvbVRlbXBsYXRlc1NlcnZpY2UuY3VzdG9tTWVzc2FnZU1ldGFkYXRhVGVtcGxhdGUkIHwgYXN5bmNcIlxuICAgID5cbiAgICAgIDxkaXYgY2xhc3M9XCJzdHItY2hhdF9fY3VzdG9tLW1lc3NhZ2UtbWV0YWRhdGFcIj5cbiAgICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAgICpuZ1RlbXBsYXRlT3V0bGV0PVwiXG4gICAgICAgICAgICAoY3VzdG9tVGVtcGxhdGVzU2VydmljZS5jdXN0b21NZXNzYWdlTWV0YWRhdGFUZW1wbGF0ZSQgfCBhc3luYykhO1xuICAgICAgICAgICAgY29udGV4dDogZ2V0TWVzc2FnZU1ldGFkYXRhQ29udGV4dCgpXG4gICAgICAgICAgXCJcbiAgICAgICAgPjwvbmctY29udGFpbmVyPlxuICAgICAgPC9kaXY+XG4gICAgPC9uZy1jb250YWluZXI+XG4gICAgPGRpdlxuICAgICAgY2xhc3M9XCJcbiAgICAgICAgc3RyLWNoYXRfX21lc3NhZ2UtZGF0YVxuICAgICAgICBzdHItY2hhdF9fbWVzc2FnZS1zaW1wbGUtZGF0YVxuICAgICAgICBzdHItY2hhdF9fbWVzc2FnZS1tZXRhZGF0YVxuICAgICAgXCJcbiAgICA+XG4gICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwibWVzc2FnZVN0YXR1c1wiPjwvbmctY29udGFpbmVyPlxuXG4gICAgICA8c3BhblxuICAgICAgICAqbmdJZj1cIiFpc1NlbnRCeUN1cnJlbnRVc2VyXCJcbiAgICAgICAgZGF0YS10ZXN0aWQ9XCJzZW5kZXJcIlxuICAgICAgICBjbGFzcz1cInN0ci1jaGF0X19tZXNzYWdlLXNpbXBsZS1uYW1lIHN0ci1jaGF0X19tZXNzYWdlLXNlbmRlci1uYW1lXCJcbiAgICAgID5cbiAgICAgICAge3sgbWVzc2FnZT8udXNlcj8ubmFtZSA/IG1lc3NhZ2U/LnVzZXI/Lm5hbWUgOiBtZXNzYWdlPy51c2VyPy5pZCB9fVxuICAgICAgPC9zcGFuPlxuICAgICAgPHNwYW5cbiAgICAgICAgZGF0YS10ZXN0aWQ9XCJkYXRlXCJcbiAgICAgICAgY2xhc3M9XCJzdHItY2hhdF9fbWVzc2FnZS1zaW1wbGUtdGltZXN0YW1wIHN0ci1jaGF0X19tZXNzYWdlLXNpbXBsZS10aW1lXCJcbiAgICAgID5cbiAgICAgICAge3sgcGFyc2VkRGF0ZSB9fVxuICAgICAgPC9zcGFuPlxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIm1lc3NhZ2U/Lm1lc3NhZ2VfdGV4dF91cGRhdGVkX2F0XCI+XG4gICAgICAgIDxzcGFuXG4gICAgICAgICAgZGF0YS10ZXN0aWQ9XCJlZGl0ZWQtZmxhZ1wiXG4gICAgICAgICAgY2xhc3M9XCJzdHItY2hhdF9fbWVzYWdlLXNpbXBsZS1lZGl0ZWRcIlxuICAgICAgICAgIHRyYW5zbGF0ZVxuICAgICAgICAgID5zdHJlYW1DaGF0LkVkaXRlZDwvc3BhblxuICAgICAgICA+XG4gICAgICAgIDxkaXZcbiAgICAgICAgICBkYXRhLXRlc3RpZD1cImVkaXRlZC10aW1lc3RhbXBcIlxuICAgICAgICAgIGNsYXNzPVwic3RyLWNoYXRfX21lc3NhZ2UtZWRpdGVkLXRpbWVzdGFtcFwiXG4gICAgICAgICAgW25nQ2xhc3NdPVwie1xuICAgICAgICAgICAgJ3N0ci1jaGF0X19tZXNzYWdlLWVkaXRlZC10aW1lc3RhbXAtLW9wZW4nOiBpc0VkaXRlZEZsYWdPcGVuZWQsXG4gICAgICAgICAgICAnc3RyLWNoYXRfX21lc3NhZ2UtZWRpdGVkLXRpbWVzdGFtcC0tY29sbGFwc2VkJzogIWlzRWRpdGVkRmxhZ09wZW5lZFxuICAgICAgICAgIH1cIlxuICAgICAgICA+XG4gICAgICAgICAgPHNwYW4gdHJhbnNsYXRlPnN0cmVhbUNoYXQuRWRpdGVkPC9zcGFuPlxuICAgICAgICAgIDx0aW1lXG4gICAgICAgICAgICBkYXRlVGltZT1cInt7IG1lc3NhZ2U/Lm1lc3NhZ2VfdGV4dF91cGRhdGVkX2F0IH19XCJcbiAgICAgICAgICAgIHRpdGxlPVwie3sgbWVzc2FnZT8ubWVzc2FnZV90ZXh0X3VwZGF0ZWRfYXQgfX1cIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIHt7IHBhc2VkRWRpdGVkRGF0ZSB9fVxuICAgICAgICAgIDwvdGltZT5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICA8L2Rpdj5cbiAgPC9uZy1jb250YWluZXI+XG48L25nLXRlbXBsYXRlPlxuXG48bmctdGVtcGxhdGUgI21lc3NhZ2VTdGF0dXM+XG4gIDxuZy1jb250YWluZXJcbiAgICAqbmdJZj1cIlxuICAgICAgaXNTZW50QnlDdXJyZW50VXNlciAmJlxuICAgICAgKChpc0xhc3RTZW50TWVzc2FnZSAmJiBtZXNzYWdlPy5zdGF0dXMgPT09ICdyZWNlaXZlZCcpIHx8XG4gICAgICAgIG1lc3NhZ2U/LnN0YXR1cyA9PT0gJ3NlbmRpbmcnKVxuICAgIFwiXG4gID5cbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwibWVzc2FnZT8uc3RhdHVzID09PSAnc2VuZGluZyc7IGVsc2Ugc2VudFN0YXR1c1wiPlxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cInNlbmRpbmdTdGF0dXNcIj48L25nLWNvbnRhaW5lcj5cbiAgICA8L25nLWNvbnRhaW5lcj5cbiAgICA8bmctdGVtcGxhdGUgI3NlbnRTdGF0dXM+XG4gICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICpuZ0lmPVwiXG4gICAgICAgICAgbW9kZSA9PT0gJ21haW4nICYmIGlzTWVzc2FnZURlbGl2ZXJlZEFuZFJlYWQgJiYgY2FuRGlzcGxheVJlYWRTdGF0dXM7XG4gICAgICAgICAgZWxzZSBkZWxpdmVyZWRTdGF0dXNcbiAgICAgICAgXCJcbiAgICAgID5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cInJlYWRTdGF0dXNcIj48L25nLWNvbnRhaW5lcj5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuICAgIDwvbmctdGVtcGxhdGU+XG4gICAgPG5nLXRlbXBsYXRlICNkZWxpdmVyZWRTdGF0dXM+XG4gICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICpuZ1RlbXBsYXRlT3V0bGV0PVwiXG4gICAgICAgICAgKGN1c3RvbVRlbXBsYXRlc1NlcnZpY2UuZGVsaXZlcmVkU3RhdHVzVGVtcGxhdGUkIHwgYXN5bmMpIHx8XG4gICAgICAgICAgICBkZWZhdWx0RGVsaXZlcmVkU3RhdHVzO1xuICAgICAgICAgIGNvbnRleHQ6IGdldERlbGl2ZXJlZFN0YXR1c0NvbnRleHQoKVxuICAgICAgICBcIlxuICAgICAgPjwvbmctY29udGFpbmVyPlxuICAgIDwvbmctdGVtcGxhdGU+XG4gICAgPG5nLXRlbXBsYXRlICNkZWZhdWx0RGVsaXZlcmVkU3RhdHVzPlxuICAgICAgPHNwYW5cbiAgICAgICAgKm5nSWY9XCJtb2RlID09PSAnbWFpbidcIlxuICAgICAgICBjbGFzcz1cIlxuICAgICAgICAgIHN0ci1jaGF0X19tZXNzYWdlLXNpbXBsZS1zdGF0dXNcbiAgICAgICAgICBzdHItY2hhdF9fbWVzc2FnZS1zaW1wbGUtc3RhdHVzLWFuZ3VsYXJcbiAgICAgICAgICBzdHItY2hhdF9fbWVzc2FnZS1zdGF0dXNcbiAgICAgICAgXCJcbiAgICAgICAgZGF0YS10ZXN0aWQ9XCJkZWxpdmVyZWQtaW5kaWNhdG9yXCJcbiAgICAgICAgdGFiaW5kZXg9XCIwXCJcbiAgICAgICAgW2Zsb2F0VWlMb29zZV09XCJmbG9hdGluZ0NvbnRlbnRcIlxuICAgICAgICBsb29zZVRyaWdnZXI9XCJob3ZlclwiXG4gICAgICA+XG4gICAgICAgIDxmbG9hdC11aS1jb250ZW50ICNmbG9hdGluZ0NvbnRlbnQ+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInN0ci1jaGF0X190b29sdGlwIHN0ci1jaGF0X190b29sdGlwLWFuZ3VsYXJcIj5cbiAgICAgICAgICAgIHt7IFwic3RyZWFtQ2hhdC5EZWxpdmVyZWRcIiB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Zsb2F0LXVpLWNvbnRlbnQ+XG4gICAgICAgIDxzdHJlYW0taWNvbi1wbGFjZWhvbGRlclxuICAgICAgICAgIGRhdGEtdGVzdGlkPVwiZGVsaXZlcmVkLWljb25cIlxuICAgICAgICAgIGljb249XCJkZWxpdmVyZWQtaWNvblwiXG4gICAgICAgID48L3N0cmVhbS1pY29uLXBsYWNlaG9sZGVyPlxuICAgICAgPC9zcGFuPlxuICAgIDwvbmctdGVtcGxhdGU+XG4gICAgPG5nLXRlbXBsYXRlICNzZW5kaW5nU3RhdHVzPlxuICAgICAgPG5nLWNvbnRhaW5lclxuICAgICAgICAqbmdUZW1wbGF0ZU91dGxldD1cIlxuICAgICAgICAgIChjdXN0b21UZW1wbGF0ZXNTZXJ2aWNlLnNlbmRpbmdTdGF0dXNUZW1wbGF0ZSQgfCBhc3luYykgfHxcbiAgICAgICAgICAgIGRlZmF1bHRTZW5kaW5nU3RhdHVzO1xuICAgICAgICAgIGNvbnRleHQ6IGdldFNlbmRpbmdTdGF0dXNDb250ZXh0KClcbiAgICAgICAgXCJcbiAgICAgID48L25nLWNvbnRhaW5lcj5cbiAgICA8L25nLXRlbXBsYXRlPlxuICAgIDxuZy10ZW1wbGF0ZSAjZGVmYXVsdFNlbmRpbmdTdGF0dXM+XG4gICAgICA8c3BhblxuICAgICAgICBjbGFzcz1cIlxuICAgICAgICAgIHN0ci1jaGF0X19tZXNzYWdlLXNpbXBsZS1zdGF0dXNcbiAgICAgICAgICBzdHItY2hhdF9fbWVzc2FnZS1zaW1wbGUtc3RhdHVzLWFuZ3VsYXJcbiAgICAgICAgICBzdHItY2hhdF9fbWVzc2FnZS1zdGF0dXNcbiAgICAgICAgXCJcbiAgICAgICAgZGF0YS10ZXN0aWQ9XCJzZW5kaW5nLWluZGljYXRvclwiXG4gICAgICAgIHRhYmluZGV4PVwiMFwiXG4gICAgICAgIFtmbG9hdFVpTG9vc2VdPVwiZmxvYXRpbmdDb250ZW50XCJcbiAgICAgICAgbG9vc2VUcmlnZ2VyPVwiaG92ZXJcIlxuICAgICAgPlxuICAgICAgICA8ZmxvYXQtdWktY29udGVudCAjZmxvYXRpbmdDb250ZW50PlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdHItY2hhdF9fdG9vbHRpcCBzdHItY2hhdF9fdG9vbHRpcC1hbmd1bGFyXCI+XG4gICAgICAgICAgICB7eyBcInN0cmVhbUNoYXQuU2VuZGluZy4uLlwiIHwgdHJhbnNsYXRlIH19XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZmxvYXQtdWktY29udGVudD5cbiAgICAgICAgPHN0cmVhbS1sb2FkaW5nLWluZGljYXRvci1wbGFjZWhvbGRlclxuICAgICAgICAgIGRhdGEtdGVzdGlkPVwibG9hZGluZy1pbmRpY2F0b3JcIlxuICAgICAgICA+PC9zdHJlYW0tbG9hZGluZy1pbmRpY2F0b3ItcGxhY2Vob2xkZXI+XG4gICAgICA8L3NwYW4+XG4gICAgPC9uZy10ZW1wbGF0ZT5cbiAgICA8bmctdGVtcGxhdGUgI3JlYWRTdGF0dXM+XG4gICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICpuZ1RlbXBsYXRlT3V0bGV0PVwiXG4gICAgICAgICAgKGN1c3RvbVRlbXBsYXRlc1NlcnZpY2UucmVhZFN0YXR1c1RlbXBsYXRlJCB8IGFzeW5jKSB8fFxuICAgICAgICAgICAgZGVmYXVsdFJlYWRTdGF0dXM7XG4gICAgICAgICAgY29udGV4dDogZ2V0UmVhZFN0YXR1c0NvbnRleHQoKVxuICAgICAgICBcIlxuICAgICAgPjwvbmctY29udGFpbmVyPlxuICAgIDwvbmctdGVtcGxhdGU+XG4gICAgPG5nLXRlbXBsYXRlICNkZWZhdWx0UmVhZFN0YXR1cz5cbiAgICAgIDxzcGFuXG4gICAgICAgIGNsYXNzPVwiXG4gICAgICAgICAgc3RyLWNoYXRfX21lc3NhZ2Utc2ltcGxlLXN0YXR1c1xuICAgICAgICAgIHN0ci1jaGF0X19tZXNzYWdlLXNpbXBsZS1zdGF0dXMtYW5ndWxhclxuICAgICAgICAgIHN0ci1jaGF0X19tZXNzYWdlLXN0YXR1c1xuICAgICAgICBcIlxuICAgICAgICBkYXRhLXRlc3RpZD1cInJlYWQtaW5kaWNhdG9yXCJcbiAgICAgICAgdGFiaW5kZXg9XCIwXCJcbiAgICAgICAgW2Zsb2F0VWlMb29zZV09XCJmbG9hdGluZ0NvbnRlbnRcIlxuICAgICAgICBsb29zZVRyaWdnZXI9XCJob3ZlclwiXG4gICAgICA+XG4gICAgICAgIDxmbG9hdC11aS1jb250ZW50ICNmbG9hdGluZ0NvbnRlbnQ+XG4gICAgICAgICAgPGRpdlxuICAgICAgICAgICAgY2xhc3M9XCJzdHItY2hhdF9fdG9vbHRpcCBzdHItY2hhdF9fdG9vbHRpcC1hbmd1bGFyXCJcbiAgICAgICAgICAgIGRhdGEtdGVzdGlkPVwicmVhZC1ieS10b29sdGlwXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICB7eyByZWFkQnlUZXh0IH19XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZmxvYXQtdWktY29udGVudD5cbiAgICAgICAgPHN0cmVhbS1pY29uLXBsYWNlaG9sZGVyIGljb249XCJyZWFkLWljb25cIj48L3N0cmVhbS1pY29uLXBsYWNlaG9sZGVyPlxuICAgICAgPC9zcGFuPlxuICAgIDwvbmctdGVtcGxhdGU+XG4gIDwvbmctY29udGFpbmVyPlxuPC9uZy10ZW1wbGF0ZT5cblxuPG5nLXRlbXBsYXRlICNyZXBseUNvdW50QnV0dG9uPlxuICA8ZGl2XG4gICAgY2xhc3M9XCJcbiAgICAgIHN0ci1jaGF0X19tZXNzYWdlLXNpbXBsZS1yZXBseS1idXR0b25cbiAgICAgIHN0ci1jaGF0X19tZXNzYWdlLXJlcGxpZXMtY291bnQtYnV0dG9uLXdyYXBwZXJcbiAgICBcIlxuICA+XG4gICAgPGJ1dHRvblxuICAgICAgKm5nSWY9XCJzaG91bGREaXNwbGF5VGhyZWFkTGlua1wiXG4gICAgICBjbGFzcz1cInN0ci1jaGF0X19tZXNzYWdlLXJlcGxpZXMtY291bnQtYnV0dG9uXCJcbiAgICAgIGRhdGEtdGVzdGlkPVwicmVwbHktY291bnQtYnV0dG9uXCJcbiAgICAgIChjbGljayk9XCJzZXRBc0FjdGl2ZVBhcmVudE1lc3NhZ2UoKVwiXG4gICAgPlxuICAgICAge3ttZXNzYWdlPy5yZXBseV9jb3VudCA9PT0gMSA/ICgnc3RyZWFtQ2hhdC4xIHJlcGx5JyB8IHRyYW5zbGF0ZSkgOiAoJ3N0cmVhbUNoYXQue3sgcmVwbHlDb3VudCB9fVxuICAgICAgcmVwbGllcycgfCB0cmFuc2xhdGU6cmVwbHlDb3VudFBhcmFtKX19XG4gICAgPC9idXR0b24+XG4gIDwvZGl2PlxuPC9uZy10ZW1wbGF0ZT5cblxuPG5nLXRlbXBsYXRlICNhdHRhY2htZW50c1RlbXBsYXRlPlxuICA8bmctdGVtcGxhdGVcbiAgICAjZGVmYXVsdEF0dGFjaG1lbnRzXG4gICAgbGV0LW1lc3NhZ2VJZD1cIm1lc3NhZ2VJZFwiXG4gICAgbGV0LWF0dGFjaG1lbnRzPVwiYXR0YWNobWVudHNcIlxuICAgIGxldC1wYXJlbnRNZXNzYWdlSWQ9XCJwYXJlbnRNZXNzYWdlSWRcIlxuICAgIGxldC1pbWFnZU1vZGFsU3RhdGVDaGFuZ2VIYW5kbGVyPVwiaW1hZ2VNb2RhbFN0YXRlQ2hhbmdlSGFuZGxlclwiXG4gID5cbiAgICA8c3RyZWFtLWF0dGFjaG1lbnQtbGlzdFxuICAgICAgW21lc3NhZ2VJZF09XCJtZXNzYWdlSWRcIlxuICAgICAgW2F0dGFjaG1lbnRzXT1cImF0dGFjaG1lbnRzXCJcbiAgICAgIFtwYXJlbnRNZXNzYWdlSWRdPVwicGFyZW50TWVzc2FnZUlkXCJcbiAgICAgIChpbWFnZU1vZGFsU3RhdGVDaGFuZ2UpPVwiaW1hZ2VNb2RhbFN0YXRlQ2hhbmdlSGFuZGxlcigkZXZlbnQpXCJcbiAgICA+PC9zdHJlYW0tYXR0YWNobWVudC1saXN0PlxuICA8L25nLXRlbXBsYXRlPlxuICA8bmctY29udGFpbmVyXG4gICAgKm5nVGVtcGxhdGVPdXRsZXQ9XCJcbiAgICAgIChjdXN0b21UZW1wbGF0ZXNTZXJ2aWNlLmF0dGFjaG1lbnRMaXN0VGVtcGxhdGUkIHwgYXN5bmMpIHx8XG4gICAgICAgIGRlZmF1bHRBdHRhY2htZW50cztcbiAgICAgIGNvbnRleHQ6IGdldEF0dGFjaG1lbnRMaXN0Q29udGV4dCgpXG4gICAgXCJcbiAgPjwvbmctY29udGFpbmVyPlxuPC9uZy10ZW1wbGF0ZT5cbiJdfQ==
|