mediasfu-angular 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (471) hide show
  1. package/README.md +2068 -0
  2. package/dist/README.md +2068 -0
  3. package/dist/esm2022/lib/@types/types.mjs +2 -0
  4. package/dist/esm2022/lib/components/background-components/background-modal/background-modal.component.mjs +763 -0
  5. package/dist/esm2022/lib/components/breakout-components/breakout-rooms-modal.component.mjs +316 -0
  6. package/dist/esm2022/lib/components/breakout-components/edit-room-modal/edit-room-modal.component.mjs +95 -0
  7. package/dist/esm2022/lib/components/breakout-components/room-list/room-list.component.mjs +40 -0
  8. package/dist/esm2022/lib/components/co-host-components/co-host-modal/co-host-modal.component.mjs +246 -0
  9. package/dist/esm2022/lib/components/display-components/alert-component/alert.component.component.mjs +73 -0
  10. package/dist/esm2022/lib/components/display-components/audio-card/audio-card.component.mjs +297 -0
  11. package/dist/esm2022/lib/components/display-components/audio-grid/audio-grid.component.mjs +60 -0
  12. package/dist/esm2022/lib/components/display-components/card-video-display/card-video-display.component.mjs +94 -0
  13. package/dist/esm2022/lib/components/display-components/control-buttons-alt-component/control-buttons-alt-component.component.mjs +100 -0
  14. package/dist/esm2022/lib/components/display-components/control-buttons-component/control-buttons-component.component.mjs +231 -0
  15. package/dist/esm2022/lib/components/display-components/control-buttons-component-touch/control-buttons-component-touch.component.mjs +298 -0
  16. package/dist/esm2022/lib/components/display-components/control-widgets/menu-participants-widget.component.mjs +61 -0
  17. package/dist/esm2022/lib/components/display-components/control-widgets/menu-record-widget.component.mjs +43 -0
  18. package/dist/esm2022/lib/components/display-components/control-widgets/menu-widget.component.mjs +114 -0
  19. package/dist/esm2022/lib/components/display-components/control-widgets/message-widget.component.mjs +114 -0
  20. package/dist/esm2022/lib/components/display-components/control-widgets/record-timer-widget.component.mjs +36 -0
  21. package/dist/esm2022/lib/components/display-components/control-widgets/screenshare-widget.component.mjs +74 -0
  22. package/dist/esm2022/lib/components/display-components/flexible-grid/flexible-grid.component.mjs +142 -0
  23. package/dist/esm2022/lib/components/display-components/flexible-video/flexible-video.component.mjs +265 -0
  24. package/dist/esm2022/lib/components/display-components/loading-modal/loading-modal.component.mjs +100 -0
  25. package/dist/esm2022/lib/components/display-components/main-aspect-component/main-aspect-component.component.mjs +132 -0
  26. package/dist/esm2022/lib/components/display-components/main-container-component/main-container-component.component.mjs +119 -0
  27. package/dist/esm2022/lib/components/display-components/main-grid-component/main-grid-component.component.mjs +106 -0
  28. package/dist/esm2022/lib/components/display-components/main-screen-component/main-screen-component.component.mjs +180 -0
  29. package/dist/esm2022/lib/components/display-components/meeting-progress-timer/meeting-progress-timer.component.mjs +120 -0
  30. package/dist/esm2022/lib/components/display-components/mini-audio/mini-audio.component.mjs +326 -0
  31. package/dist/esm2022/lib/components/display-components/mini-card/mini-card.component.mjs +165 -0
  32. package/dist/esm2022/lib/components/display-components/mini-card-audio/mini-card-audio.component.mjs +230 -0
  33. package/dist/esm2022/lib/components/display-components/other-grid-component/other-grid-component.component.mjs +111 -0
  34. package/dist/esm2022/lib/components/display-components/pagination/pagination.component.mjs +328 -0
  35. package/dist/esm2022/lib/components/display-components/sub-aspect-component/sub-aspect-component.component.mjs +118 -0
  36. package/dist/esm2022/lib/components/display-components/video-card/video-card.component.mjs +330 -0
  37. package/dist/esm2022/lib/components/display-settings-components/display-settings-modal.component.mjs +95 -0
  38. package/dist/esm2022/lib/components/event-settings-components/event-settings-modal/event-settings-modal.component.mjs +190 -0
  39. package/dist/esm2022/lib/components/exit-components/confirm-exit-modal/confirm-exit-modal.component.mjs +119 -0
  40. package/dist/esm2022/lib/components/media-settings-components/media-settings-modal/media-settings-modal.component.mjs +209 -0
  41. package/dist/esm2022/lib/components/mediasfu-components/mediasfu-broadcast.component.mjs +4187 -0
  42. package/dist/esm2022/lib/components/mediasfu-components/mediasfu-chat.component.mjs +3703 -0
  43. package/dist/esm2022/lib/components/mediasfu-components/mediasfu-conference.component.mjs +5022 -0
  44. package/dist/esm2022/lib/components/mediasfu-components/mediasfu-generic.component.mjs +5331 -0
  45. package/dist/esm2022/lib/components/mediasfu-components/mediasfu-webinar.component.mjs +5021 -0
  46. package/dist/esm2022/lib/components/menu-components/custom-buttons/custom-buttons.component.mjs +85 -0
  47. package/dist/esm2022/lib/components/menu-components/meeting-id-component/meeting-id-component.component.mjs +22 -0
  48. package/dist/esm2022/lib/components/menu-components/meeting-passcode-component/meeting-passcode-component.component.mjs +22 -0
  49. package/dist/esm2022/lib/components/menu-components/menu-modal/menu-modal.component.mjs +132 -0
  50. package/dist/esm2022/lib/components/menu-components/share-buttons-component/share-buttons-component.component.mjs +104 -0
  51. package/dist/esm2022/lib/components/message-components/message-panel/message-panel.component.mjs +204 -0
  52. package/dist/esm2022/lib/components/message-components/messages-modal/messages-modal.component.mjs +243 -0
  53. package/dist/esm2022/lib/components/misc-components/confirm-here-modal/confirm-here-modal.component.mjs +147 -0
  54. package/dist/esm2022/lib/components/misc-components/pre-join-page/pre-join-page.component.mjs +335 -0
  55. package/dist/esm2022/lib/components/misc-components/share-event-modal/share-event-modal.component.mjs +113 -0
  56. package/dist/esm2022/lib/components/misc-components/welcome-page/welcome-page.component.mjs +226 -0
  57. package/dist/esm2022/lib/components/participants-components/participant-list/participant-list.component.mjs +63 -0
  58. package/dist/esm2022/lib/components/participants-components/participant-list-item/participant-list-item.component.mjs +120 -0
  59. package/dist/esm2022/lib/components/participants-components/participant-list-others/participant-list-others.component.mjs +23 -0
  60. package/dist/esm2022/lib/components/participants-components/participant-list-others-item/participant-list-others-item.component.mjs +43 -0
  61. package/dist/esm2022/lib/components/participants-components/participants-modal/participants-modal.component.mjs +100 -0
  62. package/dist/esm2022/lib/components/polls-components/poll-modal/poll-modal.component.mjs +174 -0
  63. package/dist/esm2022/lib/components/recording-components/advanced-panel-component/advanced-panel-components.component.mjs +77 -0
  64. package/dist/esm2022/lib/components/recording-components/recording-modal/recording-modal.component.mjs +121 -0
  65. package/dist/esm2022/lib/components/recording-components/standard-panel-component/standard-panel-component.component.mjs +85 -0
  66. package/dist/esm2022/lib/components/requests-components/render-request-component/render-request-component.component.mjs +59 -0
  67. package/dist/esm2022/lib/components/requests-components/requests-modal/requests-modal.component.mjs +130 -0
  68. package/dist/esm2022/lib/components/screenboard-components/screenboard/screenboard.component.mjs +617 -0
  69. package/dist/esm2022/lib/components/screenboard-components/screenboard-modal/screenboard-modal.component.mjs +380 -0
  70. package/dist/esm2022/lib/components/waiting-components/waiting-room-modal.component.mjs +142 -0
  71. package/dist/esm2022/lib/components/whiteboard-components/configure-whiteboard-modal/configure-whiteboard-modal.component.mjs +265 -0
  72. package/dist/esm2022/lib/components/whiteboard-components/whiteboard/whiteboard.component.mjs +1784 -0
  73. package/dist/esm2022/lib/consumers/add-videos-grid.service.mjs +296 -0
  74. package/dist/esm2022/lib/consumers/auto-adjust.service.mjs +83 -0
  75. package/dist/esm2022/lib/consumers/calculate-rows-and-columns.service.mjs +42 -0
  76. package/dist/esm2022/lib/consumers/change-vids.service.mjs +486 -0
  77. package/dist/esm2022/lib/consumers/check-grid.service.mjs +79 -0
  78. package/dist/esm2022/lib/consumers/check-permission.service.mjs +80 -0
  79. package/dist/esm2022/lib/consumers/check-screen-share.service.mjs +71 -0
  80. package/dist/esm2022/lib/consumers/close-and-resize.service.mjs +229 -0
  81. package/dist/esm2022/lib/consumers/compare-active-names.service.mjs +75 -0
  82. package/dist/esm2022/lib/consumers/compare-screen-states.service.mjs +63 -0
  83. package/dist/esm2022/lib/consumers/connect-ips.service.mjs +112 -0
  84. package/dist/esm2022/lib/consumers/connect-recv-transport.service.mjs +113 -0
  85. package/dist/esm2022/lib/consumers/connect-send-transport-audio.service.mjs +46 -0
  86. package/dist/esm2022/lib/consumers/connect-send-transport-screen.service.mjs +62 -0
  87. package/dist/esm2022/lib/consumers/connect-send-transport-video.service.mjs +55 -0
  88. package/dist/esm2022/lib/consumers/connect-send-transport.service.mjs +86 -0
  89. package/dist/esm2022/lib/consumers/consumer-resume.service.mjs +332 -0
  90. package/dist/esm2022/lib/consumers/control-media.service.mjs +68 -0
  91. package/dist/esm2022/lib/consumers/create-send-transport.service.mjs +126 -0
  92. package/dist/esm2022/lib/consumers/disconnect-send-transport-audio.service.mjs +58 -0
  93. package/dist/esm2022/lib/consumers/disconnect-send-transport-screen.service.mjs +45 -0
  94. package/dist/esm2022/lib/consumers/disconnect-send-transport-video.service.mjs +56 -0
  95. package/dist/esm2022/lib/consumers/disp-streams.service.mjs +421 -0
  96. package/dist/esm2022/lib/consumers/generate-page-content.service.mjs +59 -0
  97. package/dist/esm2022/lib/consumers/get-estimate.service.mjs +70 -0
  98. package/dist/esm2022/lib/consumers/get-piped-producers-alt.service.mjs +49 -0
  99. package/dist/esm2022/lib/consumers/get-producers-piped.service.mjs +46 -0
  100. package/dist/esm2022/lib/consumers/get-videos.service.mjs +58 -0
  101. package/dist/esm2022/lib/consumers/mix-streams.service.mjs +73 -0
  102. package/dist/esm2022/lib/consumers/on-screen-changes.service.mjs +63 -0
  103. package/dist/esm2022/lib/consumers/prepopulate-user-media.service.mjs +442 -0
  104. package/dist/esm2022/lib/consumers/process-consumer-transports-audio.service.mjs +72 -0
  105. package/dist/esm2022/lib/consumers/process-consumer-transports.service.mjs +91 -0
  106. package/dist/esm2022/lib/consumers/re-port.service.mjs +66 -0
  107. package/dist/esm2022/lib/consumers/re-update-inter.service.mjs +157 -0
  108. package/dist/esm2022/lib/consumers/readjust.service.mjs +123 -0
  109. package/dist/esm2022/lib/consumers/receive-all-piped-transports.service.mjs +56 -0
  110. package/dist/esm2022/lib/consumers/receive-room-messages.service.mjs +42 -0
  111. package/dist/esm2022/lib/consumers/reorder-streams.service.mjs +181 -0
  112. package/dist/esm2022/lib/consumers/request-screen-share.service.mjs +67 -0
  113. package/dist/esm2022/lib/consumers/resume-pause-audio-streams.service.mjs +99 -0
  114. package/dist/esm2022/lib/consumers/resume-pause-streams.service.mjs +70 -0
  115. package/dist/esm2022/lib/consumers/resume-send-transport-audio.service.mjs +55 -0
  116. package/dist/esm2022/lib/consumers/signal-new-consumer-transport.service.mjs +136 -0
  117. package/dist/esm2022/lib/consumers/socket-receive-methods/join-consume-room.service.mjs +63 -0
  118. package/dist/esm2022/lib/consumers/socket-receive-methods/new-pipe-producer.service.mjs +61 -0
  119. package/dist/esm2022/lib/consumers/socket-receive-methods/producer-closed.service.mjs +51 -0
  120. package/dist/esm2022/lib/consumers/start-share-screen.service.mjs +80 -0
  121. package/dist/esm2022/lib/consumers/stop-share-screen.service.mjs +120 -0
  122. package/dist/esm2022/lib/consumers/stream-success-audio-switch.service.mjs +132 -0
  123. package/dist/esm2022/lib/consumers/stream-success-audio.service.mjs +149 -0
  124. package/dist/esm2022/lib/consumers/stream-success-screen.service.mjs +143 -0
  125. package/dist/esm2022/lib/consumers/stream-success-video.service.mjs +202 -0
  126. package/dist/esm2022/lib/consumers/switch-user-audio.service.mjs +87 -0
  127. package/dist/esm2022/lib/consumers/switch-user-video-alt.service.mjs +228 -0
  128. package/dist/esm2022/lib/consumers/switch-user-video.service.mjs +125 -0
  129. package/dist/esm2022/lib/consumers/trigger.service.mjs +172 -0
  130. package/dist/esm2022/lib/consumers/update-mini-cards-grid.service.mjs +81 -0
  131. package/dist/esm2022/lib/consumers/update-participant-audio-decibels.service.mjs +39 -0
  132. package/dist/esm2022/lib/methods/background-methods/launch-background.service.mjs +23 -0
  133. package/dist/esm2022/lib/methods/breakout-room-methods/breakout-room-updated.service.mjs +112 -0
  134. package/dist/esm2022/lib/methods/breakout-room-methods/launch-breakout-rooms.service.mjs +22 -0
  135. package/dist/esm2022/lib/methods/co-host-methods/launch-co-host.service.mjs +22 -0
  136. package/dist/esm2022/lib/methods/co-host-methods/modify-co-host-settings.service.mjs +60 -0
  137. package/dist/esm2022/lib/methods/display-settings-methods/launch-display-settings.service.mjs +24 -0
  138. package/dist/esm2022/lib/methods/display-settings-methods/modify-display-settings.service.mjs +119 -0
  139. package/dist/esm2022/lib/methods/exit-methods/confirm-exit.service.mjs +28 -0
  140. package/dist/esm2022/lib/methods/exit-methods/launch-confirm-exit.service.mjs +22 -0
  141. package/dist/esm2022/lib/methods/media-settings-methods/launch-media-settings.service.mjs +50 -0
  142. package/dist/esm2022/lib/methods/menu-methods/launch-menu-modal.service.mjs +22 -0
  143. package/dist/esm2022/lib/methods/message-methods/launch-messages.service.mjs +23 -0
  144. package/dist/esm2022/lib/methods/message-methods/send-message.service.mjs +94 -0
  145. package/dist/esm2022/lib/methods/participants-methods/launch-participants.service.mjs +23 -0
  146. package/dist/esm2022/lib/methods/participants-methods/message-participants.service.mjs +52 -0
  147. package/dist/esm2022/lib/methods/participants-methods/mute-participants.service.mjs +57 -0
  148. package/dist/esm2022/lib/methods/participants-methods/remove-participants.service.mjs +62 -0
  149. package/dist/esm2022/lib/methods/polls-methods/handle-create-poll.service.mjs +37 -0
  150. package/dist/esm2022/lib/methods/polls-methods/handle-end-poll.service.mjs +40 -0
  151. package/dist/esm2022/lib/methods/polls-methods/handle-vote-poll.service.mjs +49 -0
  152. package/dist/esm2022/lib/methods/polls-methods/launch-poll.service.mjs +23 -0
  153. package/dist/esm2022/lib/methods/polls-methods/poll-updated.service.mjs +64 -0
  154. package/dist/esm2022/lib/methods/recording-methods/check-pause-state.service.mjs +45 -0
  155. package/dist/esm2022/lib/methods/recording-methods/check-resume-state.service.mjs +34 -0
  156. package/dist/esm2022/lib/methods/recording-methods/confirm-recording.service.mjs +215 -0
  157. package/dist/esm2022/lib/methods/recording-methods/launch-recording.service.mjs +82 -0
  158. package/dist/esm2022/lib/methods/recording-methods/record-pause-timer.service.mjs +40 -0
  159. package/dist/esm2022/lib/methods/recording-methods/record-resume-timer.service.mjs +86 -0
  160. package/dist/esm2022/lib/methods/recording-methods/record-start-timer.service.mjs +89 -0
  161. package/dist/esm2022/lib/methods/recording-methods/record-update-timer.service.mjs +48 -0
  162. package/dist/esm2022/lib/methods/recording-methods/start-recording.service.mjs +147 -0
  163. package/dist/esm2022/lib/methods/recording-methods/stop-recording.service.mjs +74 -0
  164. package/dist/esm2022/lib/methods/recording-methods/update-recording.service.mjs +224 -0
  165. package/dist/esm2022/lib/methods/requests-methods/launch-requests.service.mjs +26 -0
  166. package/dist/esm2022/lib/methods/requests-methods/respond-to-requests.service.mjs +45 -0
  167. package/dist/esm2022/lib/methods/settings-methods/launch-settings.service.mjs +26 -0
  168. package/dist/esm2022/lib/methods/settings-methods/modify-settings.service.mjs +67 -0
  169. package/dist/esm2022/lib/methods/stream-methods/click-audio.service.mjs +178 -0
  170. package/dist/esm2022/lib/methods/stream-methods/click-chat.service.mjs +44 -0
  171. package/dist/esm2022/lib/methods/stream-methods/click-screen-share.service.mjs +110 -0
  172. package/dist/esm2022/lib/methods/stream-methods/click-video.service.mjs +183 -0
  173. package/dist/esm2022/lib/methods/stream-methods/switch-audio.service.mjs +33 -0
  174. package/dist/esm2022/lib/methods/stream-methods/switch-video-alt.service.mjs +66 -0
  175. package/dist/esm2022/lib/methods/stream-methods/switch-video.service.mjs +76 -0
  176. package/dist/esm2022/lib/methods/utils/format-number.service.mjs +45 -0
  177. package/dist/esm2022/lib/methods/utils/generate-random-messages.service.mjs +87 -0
  178. package/dist/esm2022/lib/methods/utils/generate-random-participants.service.mjs +99 -0
  179. package/dist/esm2022/lib/methods/utils/generate-random-polls.service.mjs +52 -0
  180. package/dist/esm2022/lib/methods/utils/generate-random-request-list.service.mjs +54 -0
  181. package/dist/esm2022/lib/methods/utils/generate-random-waiting-room-list.service.mjs +38 -0
  182. package/dist/esm2022/lib/methods/utils/get-modal-position.util.mjs +22 -0
  183. package/dist/esm2022/lib/methods/utils/get-overlay-position.util.mjs +21 -0
  184. package/dist/esm2022/lib/methods/utils/initial-values.util.mjs +369 -0
  185. package/dist/esm2022/lib/methods/utils/meeting-timer/start-meeting-progress-timer.service.mjs +59 -0
  186. package/dist/esm2022/lib/methods/utils/mini-audio-player/mini-audio-player.component.mjs +260 -0
  187. package/dist/esm2022/lib/methods/utils/producer/a-params.service.mjs +21 -0
  188. package/dist/esm2022/lib/methods/utils/producer/h-params.service.mjs +37 -0
  189. package/dist/esm2022/lib/methods/utils/producer/screen-params.service.mjs +24 -0
  190. package/dist/esm2022/lib/methods/utils/producer/v-params.service.mjs +37 -0
  191. package/dist/esm2022/lib/methods/utils/producer/video-capture-constraints.service.mjs +38 -0
  192. package/dist/esm2022/lib/methods/utils/sleep.util.mjs +11 -0
  193. package/dist/esm2022/lib/methods/utils/sound-player.service.mjs +42 -0
  194. package/dist/esm2022/lib/methods/utils/validate-alphanumeric.service.mjs +33 -0
  195. package/dist/esm2022/lib/methods/waiting-methods/launch-waiting.service.mjs +23 -0
  196. package/dist/esm2022/lib/methods/waiting-methods/respond-to-waiting.service.mjs +40 -0
  197. package/dist/esm2022/lib/methods/whiteboard-methods/capture-canvas-stream.service.mjs +69 -0
  198. package/dist/esm2022/lib/methods/whiteboard-methods/launch-configure-whiteboard.service.mjs +24 -0
  199. package/dist/esm2022/lib/producer-client/producer-client-emits/create-device-client.service.mjs +51 -0
  200. package/dist/esm2022/lib/producer-client/producer-client-emits/join-room-client.service.mjs +65 -0
  201. package/dist/esm2022/lib/producer-client/producer-client-emits/update-room-parameters-client.service.mjs +232 -0
  202. package/dist/esm2022/lib/producers/producer-emits/join-con-room.service.mjs +114 -0
  203. package/dist/esm2022/lib/producers/producer-emits/join-room.service.mjs +114 -0
  204. package/dist/esm2022/lib/producers/socket-receive-methods/all-members-rest.service.mjs +155 -0
  205. package/dist/esm2022/lib/producers/socket-receive-methods/all-members.service.mjs +147 -0
  206. package/dist/esm2022/lib/producers/socket-receive-methods/all-waiting-room-members.service.mjs +30 -0
  207. package/dist/esm2022/lib/producers/socket-receive-methods/ban-participant.service.mjs +40 -0
  208. package/dist/esm2022/lib/producers/socket-receive-methods/control-media-host.service.mjs +146 -0
  209. package/dist/esm2022/lib/producers/socket-receive-methods/disconnect-user-self.service.mjs +26 -0
  210. package/dist/esm2022/lib/producers/socket-receive-methods/disconnect.service.mjs +38 -0
  211. package/dist/esm2022/lib/producers/socket-receive-methods/get-domains.service.mjs +63 -0
  212. package/dist/esm2022/lib/producers/socket-receive-methods/host-request-response.service.mjs +167 -0
  213. package/dist/esm2022/lib/producers/socket-receive-methods/meeting-ended.service.mjs +44 -0
  214. package/dist/esm2022/lib/producers/socket-receive-methods/meeting-still-there.service.mjs +24 -0
  215. package/dist/esm2022/lib/producers/socket-receive-methods/meeting-time-remaining.service.mjs +36 -0
  216. package/dist/esm2022/lib/producers/socket-receive-methods/participant-requested.service.mjs +32 -0
  217. package/dist/esm2022/lib/producers/socket-receive-methods/person-joined.service.mjs +29 -0
  218. package/dist/esm2022/lib/producers/socket-receive-methods/producer-media-closed.service.mjs +68 -0
  219. package/dist/esm2022/lib/producers/socket-receive-methods/producer-media-paused.service.mjs +90 -0
  220. package/dist/esm2022/lib/producers/socket-receive-methods/producer-media-resumed.service.mjs +54 -0
  221. package/dist/esm2022/lib/producers/socket-receive-methods/re-initiate-recording.service.mjs +38 -0
  222. package/dist/esm2022/lib/producers/socket-receive-methods/receive-message.service.mjs +96 -0
  223. package/dist/esm2022/lib/producers/socket-receive-methods/recording-notice.service.mjs +195 -0
  224. package/dist/esm2022/lib/producers/socket-receive-methods/room-record-params.service.mjs +59 -0
  225. package/dist/esm2022/lib/producers/socket-receive-methods/screen-producer-id.service.mjs +45 -0
  226. package/dist/esm2022/lib/producers/socket-receive-methods/start-records.service.mjs +35 -0
  227. package/dist/esm2022/lib/producers/socket-receive-methods/stopped-recording.service.mjs +37 -0
  228. package/dist/esm2022/lib/producers/socket-receive-methods/time-left-recording.service.mjs +36 -0
  229. package/dist/esm2022/lib/producers/socket-receive-methods/update-consuming-domains.service.mjs +63 -0
  230. package/dist/esm2022/lib/producers/socket-receive-methods/update-media-settings.service.mjs +36 -0
  231. package/dist/esm2022/lib/producers/socket-receive-methods/updated-co-host.service.mjs +56 -0
  232. package/dist/esm2022/lib/producers/socket-receive-methods/user-waiting.service.mjs +78 -0
  233. package/dist/esm2022/lib/sockets/socket-manager.service.mjs +73 -0
  234. package/dist/esm2022/mediasfu-angular.mjs +5 -0
  235. package/dist/esm2022/public-api.mjs +187 -0
  236. package/dist/fesm2022/mediasfu-angular.mjs +47885 -0
  237. package/dist/fesm2022/mediasfu-angular.mjs.map +1 -0
  238. package/dist/index.d.ts +5 -0
  239. package/dist/lib/@types/types.d.ts +634 -0
  240. package/dist/lib/components/background-components/background-modal/background-modal.component.d.ts +146 -0
  241. package/dist/lib/components/breakout-components/breakout-rooms-modal.component.d.ts +112 -0
  242. package/dist/lib/components/breakout-components/edit-room-modal/edit-room-modal.component.d.ts +54 -0
  243. package/dist/lib/components/breakout-components/room-list/room-list.component.d.ts +20 -0
  244. package/dist/lib/components/co-host-components/co-host-modal/co-host-modal.component.d.ts +86 -0
  245. package/dist/lib/components/display-components/alert-component/alert.component.component.d.ts +50 -0
  246. package/dist/lib/components/display-components/audio-card/audio-card.component.d.ts +84 -0
  247. package/dist/lib/components/display-components/audio-grid/audio-grid.component.d.ts +23 -0
  248. package/dist/lib/components/display-components/card-video-display/card-video-display.component.d.ts +37 -0
  249. package/dist/lib/components/display-components/control-buttons-alt-component/control-buttons-alt-component.component.d.ts +88 -0
  250. package/dist/lib/components/display-components/control-buttons-component/control-buttons-component.component.d.ts +52 -0
  251. package/dist/lib/components/display-components/control-buttons-component-touch/control-buttons-component-touch.component.d.ts +100 -0
  252. package/dist/lib/components/display-components/control-widgets/menu-participants-widget.component.d.ts +10 -0
  253. package/dist/lib/components/display-components/control-widgets/menu-record-widget.component.d.ts +18 -0
  254. package/dist/lib/components/display-components/control-widgets/menu-widget.component.d.ts +11 -0
  255. package/dist/lib/components/display-components/control-widgets/message-widget.component.d.ts +11 -0
  256. package/dist/lib/components/display-components/control-widgets/record-timer-widget.component.d.ts +7 -0
  257. package/dist/lib/components/display-components/control-widgets/screenshare-widget.component.d.ts +12 -0
  258. package/dist/lib/components/display-components/flexible-grid/flexible-grid.component.d.ts +70 -0
  259. package/dist/lib/components/display-components/flexible-video/flexible-video.component.d.ts +97 -0
  260. package/dist/lib/components/display-components/loading-modal/loading-modal.component.d.ts +70 -0
  261. package/dist/lib/components/display-components/main-aspect-component/main-aspect-component.component.d.ts +72 -0
  262. package/dist/lib/components/display-components/main-container-component/main-container-component.component.d.ts +63 -0
  263. package/dist/lib/components/display-components/main-grid-component/main-grid-component.component.d.ts +67 -0
  264. package/dist/lib/components/display-components/main-screen-component/main-screen-component.component.d.ts +82 -0
  265. package/dist/lib/components/display-components/meeting-progress-timer/meeting-progress-timer.component.d.ts +82 -0
  266. package/dist/lib/components/display-components/mini-audio/mini-audio.component.d.ts +128 -0
  267. package/dist/lib/components/display-components/mini-card/mini-card.component.d.ts +1085 -0
  268. package/dist/lib/components/display-components/mini-card-audio/mini-card-audio.component.d.ts +95 -0
  269. package/dist/lib/components/display-components/other-grid-component/other-grid-component.component.d.ts +45 -0
  270. package/dist/lib/components/display-components/pagination/pagination.component.d.ts +112 -0
  271. package/dist/lib/components/display-components/sub-aspect-component/sub-aspect-component.component.d.ts +61 -0
  272. package/dist/lib/components/display-components/video-card/video-card.component.d.ts +89 -0
  273. package/dist/lib/components/display-settings-components/display-settings-modal.component.d.ts +65 -0
  274. package/dist/lib/components/event-settings-components/event-settings-modal/event-settings-modal.component.d.ts +124 -0
  275. package/dist/lib/components/exit-components/confirm-exit-modal/confirm-exit-modal.component.d.ts +71 -0
  276. package/dist/lib/components/media-settings-components/media-settings-modal/media-settings-modal.component.d.ts +123 -0
  277. package/dist/lib/components/mediasfu-components/mediasfu-broadcast.component.d.ts +5264 -0
  278. package/dist/lib/components/mediasfu-components/mediasfu-chat.component.d.ts +5194 -0
  279. package/dist/lib/components/mediasfu-components/mediasfu-conference.component.d.ts +6825 -0
  280. package/dist/lib/components/mediasfu-components/mediasfu-generic.component.d.ts +6851 -0
  281. package/dist/lib/components/mediasfu-components/mediasfu-webinar.component.d.ts +6825 -0
  282. package/dist/lib/components/menu-components/custom-buttons/custom-buttons.component.d.ts +83 -0
  283. package/dist/lib/components/menu-components/meeting-id-component/meeting-id-component.component.d.ts +18 -0
  284. package/dist/lib/components/menu-components/meeting-passcode-component/meeting-passcode-component.component.d.ts +18 -0
  285. package/dist/lib/components/menu-components/menu-modal/menu-modal.component.d.ts +91 -0
  286. package/dist/lib/components/menu-components/share-buttons-component/share-buttons-component.component.d.ts +46 -0
  287. package/dist/lib/components/message-components/message-panel/message-panel.component.d.ts +112 -0
  288. package/dist/lib/components/message-components/messages-modal/messages-modal.component.d.ts +124 -0
  289. package/dist/lib/components/misc-components/confirm-here-modal/confirm-here-modal.component.d.ts +92 -0
  290. package/dist/lib/components/misc-components/pre-join-page/pre-join-page.component.d.ts +159 -0
  291. package/dist/lib/components/misc-components/share-event-modal/share-event-modal.component.d.ts +77 -0
  292. package/dist/lib/components/misc-components/welcome-page/welcome-page.component.d.ts +47 -0
  293. package/dist/lib/components/participants-components/participant-list/participant-list.component.d.ts +41 -0
  294. package/dist/lib/components/participants-components/participant-list-item/participant-list-item.component.d.ts +53 -0
  295. package/dist/lib/components/participants-components/participant-list-others/participant-list-others.component.d.ts +15 -0
  296. package/dist/lib/components/participants-components/participant-list-others-item/participant-list-others-item.component.d.ts +17 -0
  297. package/dist/lib/components/participants-components/participants-modal/participants-modal.component.d.ts +70 -0
  298. package/dist/lib/components/polls-components/poll-modal/poll-modal.component.d.ts +76 -0
  299. package/dist/lib/components/recording-components/advanced-panel-component/advanced-panel-components.component.d.ts +48 -0
  300. package/dist/lib/components/recording-components/recording-modal/recording-modal.component.d.ts +117 -0
  301. package/dist/lib/components/recording-components/standard-panel-component/standard-panel-component.component.d.ts +58 -0
  302. package/dist/lib/components/requests-components/render-request-component/render-request-component.component.d.ts +34 -0
  303. package/dist/lib/components/requests-components/requests-modal/requests-modal.component.d.ts +94 -0
  304. package/dist/lib/components/screenboard-components/screenboard/screenboard.component.d.ts +210 -0
  305. package/dist/lib/components/screenboard-components/screenboard-modal/screenboard-modal.component.d.ts +103 -0
  306. package/dist/lib/components/waiting-components/waiting-room-modal.component.d.ts +85 -0
  307. package/dist/lib/components/whiteboard-components/configure-whiteboard-modal/configure-whiteboard-modal.component.d.ts +103 -0
  308. package/dist/lib/components/whiteboard-components/whiteboard/whiteboard.component.d.ts +414 -0
  309. package/dist/lib/consumers/add-videos-grid.service.d.ts +35 -0
  310. package/dist/lib/consumers/auto-adjust.service.d.ts +25 -0
  311. package/dist/lib/consumers/calculate-rows-and-columns.service.d.ts +17 -0
  312. package/dist/lib/consumers/change-vids.service.d.ts +137 -0
  313. package/dist/lib/consumers/check-grid.service.d.ts +30 -0
  314. package/dist/lib/consumers/check-permission.service.d.ts +26 -0
  315. package/dist/lib/consumers/check-screen-share.service.d.ts +41 -0
  316. package/dist/lib/consumers/close-and-resize.service.d.ts +107 -0
  317. package/dist/lib/consumers/compare-active-names.service.d.ts +37 -0
  318. package/dist/lib/consumers/compare-screen-states.service.d.ts +40 -0
  319. package/dist/lib/consumers/connect-ips.service.d.ts +59 -0
  320. package/dist/lib/consumers/connect-recv-transport.service.d.ts +58 -0
  321. package/dist/lib/consumers/connect-send-transport-audio.service.d.ts +33 -0
  322. package/dist/lib/consumers/connect-send-transport-screen.service.d.ts +42 -0
  323. package/dist/lib/consumers/connect-send-transport-video.service.d.ts +41 -0
  324. package/dist/lib/consumers/connect-send-transport.service.d.ts +49 -0
  325. package/dist/lib/consumers/consumer-resume.service.d.ts +85 -0
  326. package/dist/lib/consumers/control-media.service.d.ts +40 -0
  327. package/dist/lib/consumers/create-send-transport.service.d.ts +46 -0
  328. package/dist/lib/consumers/disconnect-send-transport-audio.service.d.ts +49 -0
  329. package/dist/lib/consumers/disconnect-send-transport-screen.service.d.ts +36 -0
  330. package/dist/lib/consumers/disconnect-send-transport-video.service.d.ts +43 -0
  331. package/dist/lib/consumers/disp-streams.service.d.ts +92 -0
  332. package/dist/lib/consumers/generate-page-content.service.d.ts +41 -0
  333. package/dist/lib/consumers/get-estimate.service.d.ts +46 -0
  334. package/dist/lib/consumers/get-piped-producers-alt.service.d.ts +33 -0
  335. package/dist/lib/consumers/get-producers-piped.service.d.ts +33 -0
  336. package/dist/lib/consumers/get-videos.service.d.ts +28 -0
  337. package/dist/lib/consumers/mix-streams.service.d.ts +32 -0
  338. package/dist/lib/consumers/on-screen-changes.service.d.ts +44 -0
  339. package/dist/lib/consumers/prepopulate-user-media.service.d.ts +107 -0
  340. package/dist/lib/consumers/process-consumer-transports-audio.service.d.ts +30 -0
  341. package/dist/lib/consumers/process-consumer-transports.service.d.ts +42 -0
  342. package/dist/lib/consumers/re-port.service.d.ts +55 -0
  343. package/dist/lib/consumers/re-update-inter.service.d.ts +83 -0
  344. package/dist/lib/consumers/readjust.service.d.ts +48 -0
  345. package/dist/lib/consumers/receive-all-piped-transports.service.d.ts +33 -0
  346. package/dist/lib/consumers/receive-room-messages.service.d.ts +22 -0
  347. package/dist/lib/consumers/reorder-streams.service.d.ts +72 -0
  348. package/dist/lib/consumers/request-screen-share.service.d.ts +38 -0
  349. package/dist/lib/consumers/resume-pause-audio-streams.service.d.ts +41 -0
  350. package/dist/lib/consumers/resume-pause-streams.service.d.ts +36 -0
  351. package/dist/lib/consumers/resume-send-transport-audio.service.d.ts +43 -0
  352. package/dist/lib/consumers/signal-new-consumer-transport.service.d.ts +63 -0
  353. package/dist/lib/consumers/socket-receive-methods/join-consume-room.service.d.ts +43 -0
  354. package/dist/lib/consumers/socket-receive-methods/new-pipe-producer.service.d.ts +46 -0
  355. package/dist/lib/consumers/socket-receive-methods/producer-closed.service.d.ts +27 -0
  356. package/dist/lib/consumers/start-share-screen.service.d.ts +38 -0
  357. package/dist/lib/consumers/stop-share-screen.service.d.ts +86 -0
  358. package/dist/lib/consumers/stream-success-audio-switch.service.d.ts +90 -0
  359. package/dist/lib/consumers/stream-success-audio.service.d.ts +100 -0
  360. package/dist/lib/consumers/stream-success-screen.service.d.ts +78 -0
  361. package/dist/lib/consumers/stream-success-video.service.d.ts +76 -0
  362. package/dist/lib/consumers/switch-user-audio.service.d.ts +41 -0
  363. package/dist/lib/consumers/switch-user-video-alt.service.d.ts +43 -0
  364. package/dist/lib/consumers/switch-user-video.service.d.ts +61 -0
  365. package/dist/lib/consumers/trigger.service.d.ts +72 -0
  366. package/dist/lib/consumers/update-mini-cards-grid.service.d.ts +54 -0
  367. package/dist/lib/consumers/update-participant-audio-decibels.service.d.ts +25 -0
  368. package/dist/lib/methods/background-methods/launch-background.service.d.ts +18 -0
  369. package/dist/lib/methods/breakout-room-methods/breakout-room-updated.service.d.ts +63 -0
  370. package/dist/lib/methods/breakout-room-methods/launch-breakout-rooms.service.d.ts +17 -0
  371. package/dist/lib/methods/co-host-methods/launch-co-host.service.d.ts +17 -0
  372. package/dist/lib/methods/co-host-methods/modify-co-host-settings.service.d.ts +42 -0
  373. package/dist/lib/methods/display-settings-methods/launch-display-settings.service.d.ts +17 -0
  374. package/dist/lib/methods/display-settings-methods/modify-display-settings.service.d.ts +74 -0
  375. package/dist/lib/methods/exit-methods/confirm-exit.service.d.ts +24 -0
  376. package/dist/lib/methods/exit-methods/launch-confirm-exit.service.d.ts +17 -0
  377. package/dist/lib/methods/media-settings-methods/launch-media-settings.service.d.ts +27 -0
  378. package/dist/lib/methods/menu-methods/launch-menu-modal.service.d.ts +17 -0
  379. package/dist/lib/methods/message-methods/launch-messages.service.d.ts +18 -0
  380. package/dist/lib/methods/message-methods/send-message.service.d.ts +48 -0
  381. package/dist/lib/methods/participants-methods/launch-participants.service.d.ts +18 -0
  382. package/dist/lib/methods/participants-methods/message-participants.service.d.ts +34 -0
  383. package/dist/lib/methods/participants-methods/mute-participants.service.d.ts +36 -0
  384. package/dist/lib/methods/participants-methods/remove-participants.service.d.ts +38 -0
  385. package/dist/lib/methods/polls-methods/handle-create-poll.service.d.ts +24 -0
  386. package/dist/lib/methods/polls-methods/handle-end-poll.service.d.ts +27 -0
  387. package/dist/lib/methods/polls-methods/handle-vote-poll.service.d.ts +33 -0
  388. package/dist/lib/methods/polls-methods/launch-poll.service.d.ts +18 -0
  389. package/dist/lib/methods/polls-methods/poll-updated.service.d.ts +34 -0
  390. package/dist/lib/methods/recording-methods/check-pause-state.service.d.ts +26 -0
  391. package/dist/lib/methods/recording-methods/check-resume-state.service.d.ts +23 -0
  392. package/dist/lib/methods/recording-methods/confirm-recording.service.d.ts +78 -0
  393. package/dist/lib/methods/recording-methods/launch-recording.service.d.ts +42 -0
  394. package/dist/lib/methods/recording-methods/record-pause-timer.service.d.ts +25 -0
  395. package/dist/lib/methods/recording-methods/record-resume-timer.service.d.ts +47 -0
  396. package/dist/lib/methods/recording-methods/record-start-timer.service.d.ts +58 -0
  397. package/dist/lib/methods/recording-methods/record-update-timer.service.d.ts +29 -0
  398. package/dist/lib/methods/recording-methods/start-recording.service.d.ts +83 -0
  399. package/dist/lib/methods/recording-methods/stop-recording.service.d.ts +37 -0
  400. package/dist/lib/methods/recording-methods/update-recording.service.d.ts +88 -0
  401. package/dist/lib/methods/requests-methods/launch-requests.service.d.ts +19 -0
  402. package/dist/lib/methods/requests-methods/respond-to-requests.service.d.ts +30 -0
  403. package/dist/lib/methods/settings-methods/launch-settings.service.d.ts +19 -0
  404. package/dist/lib/methods/settings-methods/modify-settings.service.d.ts +44 -0
  405. package/dist/lib/methods/stream-methods/click-audio.service.d.ts +73 -0
  406. package/dist/lib/methods/stream-methods/click-chat.service.d.ts +27 -0
  407. package/dist/lib/methods/stream-methods/click-screen-share.service.d.ts +44 -0
  408. package/dist/lib/methods/stream-methods/click-video.service.d.ts +58 -0
  409. package/dist/lib/methods/stream-methods/switch-audio.service.d.ts +28 -0
  410. package/dist/lib/methods/stream-methods/switch-video-alt.service.d.ts +29 -0
  411. package/dist/lib/methods/stream-methods/switch-video.service.d.ts +35 -0
  412. package/dist/lib/methods/utils/format-number.service.d.ts +24 -0
  413. package/dist/lib/methods/utils/generate-random-messages.service.d.ts +26 -0
  414. package/dist/lib/methods/utils/generate-random-participants.service.d.ts +24 -0
  415. package/dist/lib/methods/utils/generate-random-polls.service.d.ts +18 -0
  416. package/dist/lib/methods/utils/generate-random-request-list.service.d.ts +24 -0
  417. package/dist/lib/methods/utils/generate-random-waiting-room-list.service.d.ts +19 -0
  418. package/dist/lib/methods/utils/get-modal-position.util.d.ts +15 -0
  419. package/dist/lib/methods/utils/get-overlay-position.util.d.ts +12 -0
  420. package/dist/lib/methods/utils/initial-values.util.d.ts +343 -0
  421. package/dist/lib/methods/utils/meeting-timer/start-meeting-progress-timer.service.d.ts +31 -0
  422. package/dist/lib/methods/utils/mini-audio-player/mini-audio-player.component.d.ts +46 -0
  423. package/dist/lib/methods/utils/producer/a-params.service.d.ts +11 -0
  424. package/dist/lib/methods/utils/producer/h-params.service.d.ts +11 -0
  425. package/dist/lib/methods/utils/producer/screen-params.service.d.ts +11 -0
  426. package/dist/lib/methods/utils/producer/v-params.service.d.ts +11 -0
  427. package/dist/lib/methods/utils/producer/video-capture-constraints.service.d.ts +131 -0
  428. package/dist/lib/methods/utils/sleep.util.d.ts +12 -0
  429. package/dist/lib/methods/utils/sound-player.service.d.ts +13 -0
  430. package/dist/lib/methods/utils/validate-alphanumeric.service.d.ts +17 -0
  431. package/dist/lib/methods/waiting-methods/launch-waiting.service.d.ts +17 -0
  432. package/dist/lib/methods/waiting-methods/respond-to-waiting.service.d.ts +31 -0
  433. package/dist/lib/methods/whiteboard-methods/capture-canvas-stream.service.d.ts +33 -0
  434. package/dist/lib/methods/whiteboard-methods/launch-configure-whiteboard.service.d.ts +17 -0
  435. package/dist/lib/producer-client/producer-client-emits/create-device-client.service.d.ts +20 -0
  436. package/dist/lib/producer-client/producer-client-emits/join-room-client.service.d.ts +36 -0
  437. package/dist/lib/producer-client/producer-client-emits/update-room-parameters-client.service.d.ts +104 -0
  438. package/dist/lib/producers/producer-emits/join-con-room.service.d.ts +44 -0
  439. package/dist/lib/producers/producer-emits/join-room.service.d.ts +34 -0
  440. package/dist/lib/producers/socket-receive-methods/all-members-rest.service.d.ts +75 -0
  441. package/dist/lib/producers/socket-receive-methods/all-members.service.d.ts +72 -0
  442. package/dist/lib/producers/socket-receive-methods/all-waiting-room-members.service.d.ts +22 -0
  443. package/dist/lib/producers/socket-receive-methods/ban-participant.service.d.ts +35 -0
  444. package/dist/lib/producers/socket-receive-methods/control-media-host.service.d.ts +60 -0
  445. package/dist/lib/producers/socket-receive-methods/disconnect-user-self.service.d.ts +22 -0
  446. package/dist/lib/producers/socket-receive-methods/disconnect.service.d.ts +23 -0
  447. package/dist/lib/producers/socket-receive-methods/get-domains.service.d.ts +48 -0
  448. package/dist/lib/producers/socket-receive-methods/host-request-response.service.d.ts +81 -0
  449. package/dist/lib/producers/socket-receive-methods/meeting-ended.service.d.ts +26 -0
  450. package/dist/lib/producers/socket-receive-methods/meeting-still-there.service.d.ts +17 -0
  451. package/dist/lib/producers/socket-receive-methods/meeting-time-remaining.service.d.ts +22 -0
  452. package/dist/lib/producers/socket-receive-methods/participant-requested.service.d.ts +26 -0
  453. package/dist/lib/producers/socket-receive-methods/person-joined.service.d.ts +20 -0
  454. package/dist/lib/producers/socket-receive-methods/producer-media-closed.service.d.ts +47 -0
  455. package/dist/lib/producers/socket-receive-methods/producer-media-paused.service.d.ts +51 -0
  456. package/dist/lib/producers/socket-receive-methods/producer-media-resumed.service.d.ts +44 -0
  457. package/dist/lib/producers/socket-receive-methods/re-initiate-recording.service.d.ts +25 -0
  458. package/dist/lib/producers/socket-receive-methods/receive-message.service.d.ts +37 -0
  459. package/dist/lib/producers/socket-receive-methods/recording-notice.service.d.ts +120 -0
  460. package/dist/lib/producers/socket-receive-methods/room-record-params.service.d.ts +75 -0
  461. package/dist/lib/producers/socket-receive-methods/screen-producer-id.service.d.ts +32 -0
  462. package/dist/lib/producers/socket-receive-methods/start-records.service.d.ts +23 -0
  463. package/dist/lib/producers/socket-receive-methods/stopped-recording.service.d.ts +22 -0
  464. package/dist/lib/producers/socket-receive-methods/time-left-recording.service.d.ts +21 -0
  465. package/dist/lib/producers/socket-receive-methods/update-consuming-domains.service.d.ts +44 -0
  466. package/dist/lib/producers/socket-receive-methods/update-media-settings.service.d.ts +27 -0
  467. package/dist/lib/producers/socket-receive-methods/updated-co-host.service.d.ts +37 -0
  468. package/dist/lib/producers/socket-receive-methods/user-waiting.service.d.ts +68 -0
  469. package/dist/lib/sockets/socket-manager.service.d.ts +26 -0
  470. package/dist/public-api.d.ts +177 -0
  471. package/package.json +89 -0
@@ -0,0 +1,763 @@
1
+ /* eslint-disable @typescript-eslint/no-non-null-assertion */
2
+ import { Component, Input, ViewChild, } from '@angular/core';
3
+ import { CommonModule } from '@angular/common';
4
+ import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
5
+ import { faTimes } from '@fortawesome/free-solid-svg-icons';
6
+ import { SelfieSegmentation } from '@mediapipe/selfie_segmentation';
7
+ import * as i0 from "@angular/core";
8
+ import * as i1 from "@angular/common";
9
+ import * as i2 from "@fortawesome/angular-fontawesome";
10
+ export class BackgroundModal {
11
+ isVisible = false;
12
+ parameters = {};
13
+ position = 'topLeft';
14
+ backgroundColor = '#f5f5f5';
15
+ onClose = () => {
16
+ console.log('onClose');
17
+ };
18
+ defaultImagesContainerRef;
19
+ uploadImageInputRef;
20
+ backgroundCanvasRef;
21
+ videoPreviewRef;
22
+ captureVideoRef;
23
+ loadingOverlayRef;
24
+ applyBackgroundButtonRef;
25
+ saveBackgroundButtonRef;
26
+ faTimes = faTimes;
27
+ customImage = '';
28
+ selectedImage = '';
29
+ segmentVideo = null;
30
+ selfieSegmentation = null;
31
+ pauseSegmentation = false;
32
+ processedStream = null;
33
+ keepBackground = false;
34
+ backgroundHasChanged = false;
35
+ virtualStream = null;
36
+ mainCanvas;
37
+ prevKeepBackground = false;
38
+ appliedBackground = false;
39
+ videoAlreadyOn = false;
40
+ audioOnlyRoom = false;
41
+ islevel = '0';
42
+ recordStarted = false;
43
+ recordResumed = false;
44
+ recordPaused = false;
45
+ recordStopped = false;
46
+ recordingMediaOptions = '';
47
+ vidCons = {};
48
+ frameRate = 5;
49
+ targetResolution = '1280x720';
50
+ videoParams = {};
51
+ autoClickBackground = false;
52
+ localStreamVideo = null;
53
+ clonedStream = null;
54
+ clonedTrack = null;
55
+ updateCustomImage;
56
+ updateSelectedImage;
57
+ updateSegmentVideo;
58
+ updateSelfieSegmentation;
59
+ updatePauseSegmentation;
60
+ updateProcessedStream;
61
+ updateKeepBackground;
62
+ updateBackgroundHasChanged;
63
+ updateVirtualStream;
64
+ updateMainCanvas;
65
+ updatePrevKeepBackground;
66
+ updateAppliedBackground;
67
+ updateVideoParams;
68
+ updateAutoClickBackground;
69
+ // Media functions
70
+ createSendTransport;
71
+ connectSendTransportVideo;
72
+ disconnectSendTransportVideo;
73
+ onScreenChanges;
74
+ sleep;
75
+ ngOnInit() {
76
+ // Initialize local properties from the parameters
77
+ if (this.parameters) {
78
+ try {
79
+ this.updateVariables();
80
+ }
81
+ catch {
82
+ /* handle error */
83
+ }
84
+ }
85
+ }
86
+ ngOnChanges(changes) {
87
+ if (changes['isVisible']) {
88
+ this.onVisibilityChange();
89
+ }
90
+ if (changes['autoClickBackground']) {
91
+ console.log('Auto click background changed:', this.autoClickBackground, changes['autoClickBackground']);
92
+ }
93
+ }
94
+ updateVariables() {
95
+ this.customImage = this.parameters.customImage || '';
96
+ this.selectedImage = this.parameters.selectedImage || '';
97
+ this.segmentVideo = this.parameters.segmentVideo || null;
98
+ this.selfieSegmentation = this.parameters.selfieSegmentation || null;
99
+ this.pauseSegmentation = this.parameters.pauseSegmentation || false;
100
+ this.processedStream = this.parameters.processedStream || null;
101
+ this.keepBackground = this.parameters.keepBackground || false;
102
+ this.backgroundHasChanged = this.parameters.backgroundHasChanged || false;
103
+ this.virtualStream = this.parameters.virtualStream || null;
104
+ this.mainCanvas = this.parameters.mainCanvas || this.backgroundCanvasRef?.nativeElement || null;
105
+ this.prevKeepBackground = this.parameters.prevKeepBackground || false;
106
+ this.appliedBackground = this.parameters.appliedBackground || false;
107
+ this.videoAlreadyOn = this.parameters.videoAlreadyOn || false;
108
+ this.audioOnlyRoom = this.parameters.audioOnlyRoom || false;
109
+ this.islevel = this.parameters.islevel || '0';
110
+ this.recordStarted = this.parameters.recordStarted || false;
111
+ this.recordResumed = this.parameters.recordResumed || false;
112
+ this.recordPaused = this.parameters.recordPaused || false;
113
+ this.recordStopped = this.parameters.recordStopped || false;
114
+ this.recordingMediaOptions = this.parameters.recordingMediaOptions || '';
115
+ this.vidCons = this.parameters.vidCons || {};
116
+ this.frameRate = this.parameters.frameRate || 5;
117
+ this.videoParams = this.parameters.videoParams || null;
118
+ this.autoClickBackground = this.parameters.autoClickBackground || false;
119
+ this.localStreamVideo = this.parameters.localStreamVideo || null;
120
+ // Assign method references
121
+ this.updateCustomImage = this.parameters.updateCustomImage;
122
+ this.updateSelectedImage = this.parameters.updateSelectedImage;
123
+ this.updateSegmentVideo = this.parameters.updateSegmentVideo;
124
+ this.updateSelfieSegmentation = this.parameters.updateSelfieSegmentation;
125
+ this.updatePauseSegmentation = this.parameters.updatePauseSegmentation;
126
+ this.updateProcessedStream = this.parameters.updateProcessedStream;
127
+ this.updateKeepBackground = this.parameters.updateKeepBackground;
128
+ this.updateBackgroundHasChanged = this.parameters.updateBackgroundHasChanged;
129
+ this.updateVirtualStream = this.parameters.updateVirtualStream;
130
+ this.updateMainCanvas = this.parameters.updateMainCanvas;
131
+ this.updatePrevKeepBackground = this.parameters.updatePrevKeepBackground;
132
+ this.updateAppliedBackground = this.parameters.updateAppliedBackground;
133
+ this.updateVideoParams = this.parameters.updateVideoParams;
134
+ this.updateAutoClickBackground = this.parameters.updateAutoClickBackground;
135
+ this.createSendTransport = this.parameters.createSendTransport;
136
+ this.connectSendTransportVideo = this.parameters.connectSendTransportVideo;
137
+ this.disconnectSendTransportVideo = this.parameters.disconnectSendTransportVideo;
138
+ this.onScreenChanges = this.parameters.onScreenChanges;
139
+ this.sleep = this.parameters.sleep;
140
+ }
141
+ onVisibilityChange = async () => {
142
+ if (this.parameters) {
143
+ this.parameters = this.parameters.getUpdatedAllParams();
144
+ this.updateVariables();
145
+ }
146
+ if (this.isVisible) {
147
+ if (!this.selfieSegmentation) {
148
+ await this.preloadModel().catch(() => console.log('Error preloading model:'));
149
+ }
150
+ this.renderDefaultImages();
151
+ if (this.selectedImage) {
152
+ await this.loadImageToCanvas(this.selectedImage, this.selectedImage);
153
+ }
154
+ else {
155
+ this.clearCanvas();
156
+ this.backgroundCanvasRef.nativeElement.classList.remove('d-none');
157
+ }
158
+ this.saveBackgroundButtonRef.nativeElement.classList.add('d-none');
159
+ this.saveBackgroundButtonRef.nativeElement.disabled = true;
160
+ this.applyBackgroundButtonRef.nativeElement.classList.remove('d-none');
161
+ this.applyBackgroundButtonRef.nativeElement.disabled = false;
162
+ if (this.processedStream &&
163
+ this.prevKeepBackground == this.keepBackground &&
164
+ this.keepBackground &&
165
+ this.appliedBackground) {
166
+ this.applyBackgroundButtonRef.nativeElement.innerText = 'Apply Background';
167
+ }
168
+ else {
169
+ this.applyBackgroundButtonRef.nativeElement.innerText = 'Preview Background';
170
+ }
171
+ if (this.autoClickBackground) {
172
+ await this.applyBackground();
173
+ await this.saveBackground();
174
+ this.autoClickBackground = false;
175
+ this.updateAutoClickBackground(this.autoClickBackground);
176
+ }
177
+ }
178
+ else {
179
+ try {
180
+ // If no background is applied or the applied background should not be kept
181
+ if (!this.appliedBackground ||
182
+ (this.appliedBackground && !this.keepBackground) ||
183
+ (this.appliedBackground && !this.videoAlreadyOn)) {
184
+ const refVideo = this.captureVideoRef.nativeElement;
185
+ this.pauseSegmentation = true;
186
+ this.updatePauseSegmentation(this.pauseSegmentation);
187
+ if (!this.videoAlreadyOn) {
188
+ // Stop video tracks and clear the video element's srcObject
189
+ if (refVideo && refVideo.srcObject) {
190
+ refVideo.srcObject.getTracks().forEach((track) => track.stop());
191
+ refVideo.srcObject = null;
192
+ }
193
+ // Stop segmentVideo tracks
194
+ if (this.segmentVideo) {
195
+ this.segmentVideo.getTracks().forEach((track) => track.stop());
196
+ this.segmentVideo = null;
197
+ this.updateSegmentVideo(this.segmentVideo);
198
+ }
199
+ // Stop virtualStream tracks
200
+ if (this.virtualStream) {
201
+ this.virtualStream.getTracks().forEach((track) => track.stop());
202
+ this.virtualStream = null;
203
+ this.updateVirtualStream(this.virtualStream);
204
+ }
205
+ }
206
+ }
207
+ // Hide the video preview and show the canvas
208
+ this.videoPreviewRef.nativeElement.classList.add('d-none');
209
+ this.backgroundCanvasRef.nativeElement.classList.remove('d-none');
210
+ }
211
+ catch {
212
+ /* handle error */
213
+ }
214
+ }
215
+ };
216
+ async preloadModel() {
217
+ this.selfieSegmentation = new SelfieSegmentation({
218
+ locateFile: (file) => `https://cdn.jsdelivr.net/npm/@mediapipe/selfie_segmentation/${file}`,
219
+ });
220
+ this.selfieSegmentation.setOptions({
221
+ modelSelection: 1,
222
+ selfieMode: false,
223
+ });
224
+ await this.selfieSegmentation.initialize();
225
+ this.updateSelfieSegmentation(this.selfieSegmentation);
226
+ }
227
+ renderDefaultImages() {
228
+ const defaultImages = ['wall', 'wall2', 'shelf', 'clock', 'desert', 'flower'];
229
+ const defaultImagesContainer = this.defaultImagesContainerRef.nativeElement;
230
+ defaultImagesContainer.innerHTML = '';
231
+ defaultImages.forEach((baseName) => {
232
+ const thumb = `https://mediasfu.com/images/backgrounds/${baseName}_thumbnail.jpg`;
233
+ const small = `https://mediasfu.com/images/backgrounds/${baseName}_small.jpg`;
234
+ const large = `https://mediasfu.com/images/backgrounds/${baseName}_large.jpg`;
235
+ const full = `https://mediasfu.com/images/backgrounds/${baseName}.jpg`;
236
+ const img = document.createElement('img');
237
+ img.src = thumb;
238
+ img.classList.add('img-thumbnail', 'm-1');
239
+ img.style.width = '80px';
240
+ img.style.cursor = 'pointer';
241
+ img.addEventListener('click', async () => {
242
+ if (this.targetResolution == 'fhd' || this.targetResolution == 'qhd') {
243
+ await this.loadImageToCanvas(small, large);
244
+ }
245
+ else {
246
+ await this.loadImageToCanvas(small, full);
247
+ }
248
+ });
249
+ defaultImagesContainer.appendChild(img);
250
+ });
251
+ const noBackgroundImg = document.createElement('div');
252
+ noBackgroundImg.classList.add('img-thumbnail', 'm-1', 'd-flex', 'align-items-center', 'justify-content-center');
253
+ noBackgroundImg.style.width = '76px';
254
+ noBackgroundImg.style.minHeight = '60px';
255
+ noBackgroundImg.style.cursor = 'pointer';
256
+ noBackgroundImg.style.backgroundColor = '#f8f9fa';
257
+ noBackgroundImg.style.border = '1px solid #dee2e6';
258
+ noBackgroundImg.style.position = 'relative';
259
+ noBackgroundImg.innerHTML =
260
+ '<span style="position:absolute; top:50%; left:50%; transform:translate(-50%, -50%); color:#000;">None</span>';
261
+ noBackgroundImg.addEventListener('click', async () => {
262
+ this.selectedImage = '';
263
+ this.updateSelectedImage(this.selectedImage);
264
+ this.updateCustomImage('');
265
+ this.showLoading();
266
+ this.videoPreviewRef.nativeElement.classList.add('d-none');
267
+ this.backgroundCanvasRef.nativeElement.classList.remove('d-none');
268
+ this.clearCanvas();
269
+ this.hideLoading();
270
+ });
271
+ defaultImagesContainer.appendChild(noBackgroundImg);
272
+ if (this.customImage) {
273
+ const img = document.createElement('img');
274
+ img.src = this.customImage;
275
+ img.classList.add('img-thumbnail', 'm-1');
276
+ img.style.width = '80px';
277
+ img.style.cursor = 'pointer';
278
+ img.addEventListener('click', async () => {
279
+ await this.loadImageToCanvas(this.customImage, this.customImage);
280
+ });
281
+ defaultImagesContainer.appendChild(img);
282
+ }
283
+ }
284
+ async handleImageUpload(event) {
285
+ let minWidth = 1280;
286
+ let minHeight = 1280;
287
+ let maxWidth = 2560;
288
+ let maxHeight = 2560;
289
+ if (this.targetResolution == 'fhd') {
290
+ minWidth = 1920;
291
+ minHeight = 1920;
292
+ }
293
+ else if (this.targetResolution == 'qhd') {
294
+ minWidth = 2560;
295
+ minHeight = 2560;
296
+ } // For other resolutions, stick to the default 1280x1280
297
+ const input = event.target;
298
+ if (input.files && input.files.length > 0) {
299
+ const file = input.files[0];
300
+ const img = new Image();
301
+ img.crossOrigin = 'anonymous';
302
+ img.onload = async () => {
303
+ if (img.width < minWidth ||
304
+ img.height < minHeight ||
305
+ img.width > maxWidth ||
306
+ img.height > maxHeight) {
307
+ this.customImage = img.src;
308
+ this.updateCustomImage(this.customImage);
309
+ await this.loadImageToCanvas(img.src, img.src);
310
+ }
311
+ };
312
+ const reader = new FileReader();
313
+ reader.onload = (e) => {
314
+ if (e.target) {
315
+ img.src = e.target.result;
316
+ }
317
+ };
318
+ reader.readAsDataURL(file);
319
+ }
320
+ }
321
+ clearCanvas() {
322
+ const ctx = this.backgroundCanvasRef.nativeElement.getContext('2d');
323
+ ctx.clearRect(0, 0, this.backgroundCanvasRef.nativeElement.width, this.backgroundCanvasRef.nativeElement.height);
324
+ ctx.font = '30px Arial';
325
+ ctx.fillStyle = '#000';
326
+ ctx.textAlign = 'center';
327
+ ctx.textBaseline = 'middle';
328
+ ctx.fillText('No Background', this.backgroundCanvasRef.nativeElement.width / 2, this.backgroundCanvasRef.nativeElement.height / 2);
329
+ this.applyBackgroundButtonRef.nativeElement.classList.remove('d-none');
330
+ this.applyBackgroundButtonRef.nativeElement.disabled = false;
331
+ if (this.processedStream &&
332
+ this.prevKeepBackground == this.keepBackground &&
333
+ this.keepBackground &&
334
+ this.appliedBackground) {
335
+ this.applyBackgroundButtonRef.nativeElement.innerText = 'Apply Background';
336
+ }
337
+ else {
338
+ this.applyBackgroundButtonRef.nativeElement.innerText = 'Preview Background';
339
+ }
340
+ }
341
+ async loadImageToCanvas(src, fullSrc) {
342
+ this.showLoading();
343
+ await this.backgroundCanvasRef.nativeElement.classList.remove('d-none');
344
+ await this.videoPreviewRef.nativeElement.classList.add('d-none');
345
+ const img = new Image();
346
+ img.crossOrigin = 'anonymous';
347
+ img.onload = async () => {
348
+ const ctx = await this.backgroundCanvasRef.nativeElement.getContext('2d');
349
+ this.backgroundCanvasRef.nativeElement.width = img.width;
350
+ this.backgroundCanvasRef.nativeElement.height = img.height;
351
+ await ctx.drawImage(img, 0, 0);
352
+ this.removeBackground(img);
353
+ this.hideLoading();
354
+ };
355
+ img.src = src;
356
+ this.selectedImage = fullSrc;
357
+ this.updateSelectedImage(this.selectedImage);
358
+ this.saveBackgroundButtonRef.nativeElement.classList.add('d-none');
359
+ this.saveBackgroundButtonRef.nativeElement.disabled = true;
360
+ this.applyBackgroundButtonRef.nativeElement.classList.remove('d-none');
361
+ this.applyBackgroundButtonRef.nativeElement.disabled = false;
362
+ if (this.processedStream &&
363
+ this.prevKeepBackground == this.keepBackground &&
364
+ this.keepBackground &&
365
+ this.appliedBackground) {
366
+ this.applyBackgroundButtonRef.nativeElement.innerText = 'Apply Background';
367
+ }
368
+ else {
369
+ this.applyBackgroundButtonRef.nativeElement.innerText = 'Preview Background';
370
+ }
371
+ }
372
+ removeBackground(img) {
373
+ const ctx = this.backgroundCanvasRef.nativeElement.getContext('2d');
374
+ ctx.clearRect(0, 0, this.backgroundCanvasRef.nativeElement.width, this.backgroundCanvasRef.nativeElement.height);
375
+ ctx.drawImage(img, 0, 0);
376
+ }
377
+ async applyBackground() {
378
+ try {
379
+ if (this.audioOnlyRoom) {
380
+ this.parameters.showAlert?.({
381
+ message: 'You cannot use a background in an audio only event.',
382
+ type: 'danger',
383
+ });
384
+ return;
385
+ }
386
+ this.showLoading();
387
+ this.videoPreviewRef.nativeElement.classList.remove('d-none');
388
+ this.backgroundCanvasRef.nativeElement.classList.add('d-none');
389
+ const doSegmentation = this.selectedImage ? true : false;
390
+ this.pauseSegmentation = false;
391
+ this.updatePauseSegmentation(this.pauseSegmentation);
392
+ await this.selfieSegmentationPreview(doSegmentation);
393
+ this.hideLoading();
394
+ this.applyBackgroundButtonRef.nativeElement.classList.add('d-none');
395
+ this.applyBackgroundButtonRef.nativeElement.disabled = true;
396
+ if (this.processedStream &&
397
+ this.prevKeepBackground == this.keepBackground &&
398
+ this.keepBackground &&
399
+ this.appliedBackground) {
400
+ this.saveBackgroundButtonRef.nativeElement.classList.add('d-none');
401
+ this.saveBackgroundButtonRef.nativeElement.disabled = true;
402
+ }
403
+ else {
404
+ this.saveBackgroundButtonRef.nativeElement.classList.remove('d-none');
405
+ this.saveBackgroundButtonRef.nativeElement.disabled = false;
406
+ }
407
+ }
408
+ catch (error) {
409
+ console.log(error);
410
+ }
411
+ }
412
+ async selfieSegmentationPreview(doSegmentation) {
413
+ const refVideo = this.captureVideoRef.nativeElement;
414
+ const previewVideo = this.videoPreviewRef.nativeElement;
415
+ const virtualImage = new Image();
416
+ virtualImage.crossOrigin = 'anonymous';
417
+ virtualImage.src = this.selectedImage;
418
+ if (!this.mainCanvas) {
419
+ this.mainCanvas = await this.backgroundCanvasRef.nativeElement;
420
+ }
421
+ let mediaCanvas = this.mainCanvas;
422
+ mediaCanvas.width = refVideo.videoWidth;
423
+ mediaCanvas.height = refVideo.videoHeight;
424
+ let ctx = mediaCanvas.getContext('2d');
425
+ this.backgroundHasChanged = true;
426
+ this.updateBackgroundHasChanged(this.backgroundHasChanged);
427
+ this.prevKeepBackground = this.keepBackground;
428
+ this.updatePrevKeepBackground(this.keepBackground);
429
+ if (!doSegmentation) {
430
+ const tracks = this.processedStream?.getVideoTracks();
431
+ if (tracks) {
432
+ tracks.forEach((track) => track.stop());
433
+ }
434
+ this.processedStream = null;
435
+ this.keepBackground = false;
436
+ this.updateProcessedStream(null);
437
+ this.updateKeepBackground(false);
438
+ previewVideo.classList.remove('d-none');
439
+ }
440
+ const segmentImage = async (videoElement) => {
441
+ const processFrame = () => {
442
+ if (!this.selfieSegmentation ||
443
+ this.pauseSegmentation ||
444
+ !videoElement ||
445
+ videoElement.videoWidth == 0 ||
446
+ videoElement.videoHeight == 0) {
447
+ return;
448
+ }
449
+ this.selfieSegmentation.send({ image: videoElement });
450
+ requestAnimationFrame(processFrame);
451
+ };
452
+ videoElement.onloadeddata = () => {
453
+ processFrame();
454
+ };
455
+ setTimeout(async () => {
456
+ console.log('Capturing stream:', this.frameRate || 5);
457
+ this.processedStream = mediaCanvas.captureStream(this.frameRate || 5);
458
+ this.updateProcessedStream(this.processedStream);
459
+ previewVideo.srcObject = this.processedStream;
460
+ previewVideo.classList.remove('d-none');
461
+ this.keepBackground = true;
462
+ this.updateKeepBackground(this.keepBackground);
463
+ if (previewVideo.paused) {
464
+ try {
465
+ // play the video
466
+ previewVideo.play().then(() => {
467
+ /* handle success */
468
+ });
469
+ }
470
+ catch {
471
+ /* handle error */
472
+ }
473
+ }
474
+ }, 100);
475
+ };
476
+ if (this.videoAlreadyOn) {
477
+ if (this.clonedTrack &&
478
+ this.clonedTrack.readyState == 'live' &&
479
+ this.localStreamVideo?.getVideoTracks()[0].label == this.clonedTrack.label) {
480
+ // Use existing clonedTrack
481
+ }
482
+ else {
483
+ const localTracks = this.localStreamVideo?.getVideoTracks()[0];
484
+ this.clonedTrack = localTracks.clone();
485
+ this.clonedStream = new MediaStream([this.clonedTrack]);
486
+ this.segmentVideo = this.clonedStream;
487
+ }
488
+ this.updateSegmentVideo(this.segmentVideo);
489
+ refVideo.srcObject = this.segmentVideo;
490
+ if (refVideo.paused) {
491
+ refVideo.play();
492
+ }
493
+ refVideo.width = this.segmentVideo.getVideoTracks()[0].getSettings().width;
494
+ refVideo.height = this.segmentVideo.getVideoTracks()[0].getSettings().height;
495
+ mediaCanvas.width = refVideo.width;
496
+ mediaCanvas.height = refVideo.height;
497
+ ctx = mediaCanvas.getContext('2d');
498
+ try {
499
+ doSegmentation
500
+ ? await segmentImage(refVideo)
501
+ : (previewVideo.srcObject = this.clonedStream
502
+ ? this.clonedStream
503
+ : this.localStreamVideo);
504
+ }
505
+ catch (error) {
506
+ console.log('Error segmenting image:', error);
507
+ }
508
+ }
509
+ else {
510
+ if (this.segmentVideo && this.segmentVideo.getVideoTracks()[0].readyState == 'live') {
511
+ // Use existing segmentVideo
512
+ }
513
+ else {
514
+ try {
515
+ const stream = await navigator.mediaDevices.getUserMedia({
516
+ video: { ...this.vidCons, frameRate: { ideal: this.frameRate || 5 } },
517
+ audio: false,
518
+ });
519
+ this.segmentVideo = stream;
520
+ this.updateSegmentVideo(this.segmentVideo);
521
+ refVideo.srcObject = this.segmentVideo;
522
+ if (refVideo.paused) {
523
+ refVideo.play();
524
+ }
525
+ }
526
+ catch (error) {
527
+ console.log('Error getting user media:', error);
528
+ }
529
+ refVideo.width = this.segmentVideo.getVideoTracks()[0].getSettings().width;
530
+ refVideo.height = this.segmentVideo.getVideoTracks()[0].getSettings().height;
531
+ mediaCanvas.width = refVideo.width;
532
+ mediaCanvas.height = refVideo.height;
533
+ ctx = mediaCanvas.getContext('2d');
534
+ }
535
+ try {
536
+ doSegmentation
537
+ ? await segmentImage(refVideo)
538
+ : (previewVideo.srcObject = refVideo.srcObject);
539
+ }
540
+ catch (error) {
541
+ console.log(error);
542
+ }
543
+ }
544
+ let repeatPattern = 'no-repeat';
545
+ try {
546
+ if (virtualImage.width < mediaCanvas.width || virtualImage.height < mediaCanvas.height) {
547
+ repeatPattern = 'repeat';
548
+ }
549
+ }
550
+ catch {
551
+ /* handle error */
552
+ }
553
+ const onResults = (results) => {
554
+ try {
555
+ if (!this.pauseSegmentation &&
556
+ mediaCanvas &&
557
+ mediaCanvas.width > 0 &&
558
+ mediaCanvas.height > 0 &&
559
+ virtualImage.width > 0 &&
560
+ virtualImage.height > 0) {
561
+ ctx.clearRect(0, 0, mediaCanvas.width, mediaCanvas.height);
562
+ ctx.drawImage(results.segmentationMask, 0, 0, mediaCanvas.width, mediaCanvas.height);
563
+ ctx.globalCompositeOperation = 'source-out';
564
+ const pat = ctx.createPattern(virtualImage, repeatPattern);
565
+ ctx.fillStyle = pat;
566
+ ctx.fillRect(0, 0, mediaCanvas.width, mediaCanvas.height);
567
+ ctx.globalCompositeOperation = 'destination-atop';
568
+ ctx.drawImage(results.image, 0, 0, mediaCanvas.width, mediaCanvas.height);
569
+ }
570
+ }
571
+ catch (error) {
572
+ console.log('Error processing results:', error);
573
+ }
574
+ };
575
+ if (!this.selfieSegmentation) {
576
+ await this.preloadModel().catch(() => console.log('Error preloading model:'));
577
+ }
578
+ try {
579
+ this.selfieSegmentation.onResults(onResults);
580
+ }
581
+ catch (error) {
582
+ console.log(error);
583
+ }
584
+ }
585
+ saveBackground = async () => {
586
+ if (this.audioOnlyRoom) {
587
+ this.parameters.showAlert?.({
588
+ message: 'You cannot use a background in an audio-only event.',
589
+ type: 'danger',
590
+ });
591
+ return;
592
+ }
593
+ if (this.backgroundHasChanged) {
594
+ if (this.videoAlreadyOn) {
595
+ if (this.islevel == '2' && (this.recordStarted || this.recordResumed)) {
596
+ if (!(this.recordPaused || this.recordStopped)) {
597
+ if (this.recordingMediaOptions == 'video') {
598
+ this.parameters.showAlert?.({
599
+ message: 'Please pause the recording before changing the background.',
600
+ type: 'danger',
601
+ });
602
+ return;
603
+ }
604
+ }
605
+ }
606
+ if (this.keepBackground && this.selectedImage && this.processedStream) {
607
+ this.virtualStream = this.processedStream;
608
+ this.updateVirtualStream(this.virtualStream);
609
+ this.videoParams = { track: this.virtualStream.getVideoTracks()[0] };
610
+ this.updateVideoParams(this.videoParams);
611
+ }
612
+ else {
613
+ if (this.localStreamVideo?.getVideoTracks()[0].readyState == 'live') {
614
+ this.videoParams = { track: this.localStreamVideo.getVideoTracks()[0] };
615
+ this.updateVideoParams(this.videoParams);
616
+ }
617
+ else {
618
+ try {
619
+ if (this.localStreamVideo?.getVideoTracks()[0].readyState !== 'live') {
620
+ this.localStreamVideo?.removeTrack(this.localStreamVideo.getVideoTracks()[0]);
621
+ this.localStreamVideo?.addTrack(this.segmentVideo.getVideoTracks()[0].clone());
622
+ }
623
+ }
624
+ catch (error) {
625
+ console.log('Error handling local stream video:', error);
626
+ }
627
+ this.videoParams = { track: this.segmentVideo.getVideoTracks()[0] };
628
+ this.updateVideoParams(this.videoParams);
629
+ }
630
+ }
631
+ if (this.keepBackground) {
632
+ this.appliedBackground = true;
633
+ this.updateAppliedBackground(this.appliedBackground);
634
+ }
635
+ else {
636
+ this.appliedBackground = false;
637
+ this.updateAppliedBackground(this.appliedBackground);
638
+ }
639
+ if (!this.parameters.transportCreated) {
640
+ await this.createSendTransport({
641
+ option: 'video',
642
+ parameters: { ...this.parameters, videoParams: this.videoParams },
643
+ });
644
+ }
645
+ else {
646
+ try {
647
+ if (this.parameters.videoProducer?.id &&
648
+ this.parameters.videoProducer.track?.id !== this.videoParams?.track?.id) {
649
+ await this.disconnectSendTransportVideo({ parameters: this.parameters });
650
+ await this.sleep({ ms: 500 });
651
+ }
652
+ await this.connectSendTransportVideo({
653
+ videoParams: this.videoParams,
654
+ parameters: this.parameters,
655
+ });
656
+ }
657
+ catch (error) {
658
+ console.log(error);
659
+ }
660
+ }
661
+ await this.onScreenChanges({ changed: true, parameters: this.parameters });
662
+ }
663
+ }
664
+ if (this.keepBackground) {
665
+ this.appliedBackground = true;
666
+ this.updateAppliedBackground(this.appliedBackground);
667
+ }
668
+ else {
669
+ this.appliedBackground = false;
670
+ this.updateAppliedBackground(this.appliedBackground);
671
+ }
672
+ this.saveBackgroundButtonRef.nativeElement.classList.add('d-none');
673
+ this.saveBackgroundButtonRef.nativeElement.disabled = true;
674
+ };
675
+ handleModalClose = () => {
676
+ try {
677
+ // If no background is applied or the applied background should not be kept
678
+ if (!this.appliedBackground ||
679
+ (this.appliedBackground && !this.keepBackground) ||
680
+ (this.appliedBackground && !this.videoAlreadyOn)) {
681
+ console.log('No background applied or applied background should not be kept');
682
+ const refVideo = this.captureVideoRef.nativeElement;
683
+ this.pauseSegmentation = true;
684
+ this.updatePauseSegmentation(this.pauseSegmentation);
685
+ if (!this.videoAlreadyOn) {
686
+ // Stop video tracks and clear the video element's srcObject
687
+ if (refVideo && refVideo.srcObject) {
688
+ refVideo.srcObject.getTracks().forEach((track) => track.stop());
689
+ refVideo.srcObject = null;
690
+ }
691
+ // Stop segmentVideo tracks
692
+ if (this.segmentVideo) {
693
+ this.segmentVideo.getTracks().forEach((track) => track.stop());
694
+ this.segmentVideo = null;
695
+ this.updateSegmentVideo(this.segmentVideo);
696
+ }
697
+ // Stop virtualStream tracks
698
+ if (this.virtualStream) {
699
+ this.virtualStream.getTracks().forEach((track) => track.stop());
700
+ this.virtualStream = null;
701
+ this.updateVirtualStream(this.virtualStream);
702
+ }
703
+ }
704
+ }
705
+ // Hide the video preview and show the canvas
706
+ this.videoPreviewRef.nativeElement.classList.add('d-none');
707
+ this.backgroundCanvasRef.nativeElement.classList.remove('d-none');
708
+ // Hide the modal
709
+ // this.isVisible = false;
710
+ this.onClose();
711
+ }
712
+ catch (error) {
713
+ console.log('Error during modal close:', error);
714
+ }
715
+ };
716
+ showLoading() {
717
+ this.loadingOverlayRef.nativeElement.classList.remove('d-none');
718
+ }
719
+ hideLoading() {
720
+ this.loadingOverlayRef.nativeElement.classList.add('d-none');
721
+ }
722
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: BackgroundModal, deps: [], target: i0.ɵɵFactoryTarget.Component });
723
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.8", type: BackgroundModal, isStandalone: true, selector: "app-background-modal", inputs: { isVisible: "isVisible", parameters: "parameters", position: "position", backgroundColor: "backgroundColor", onClose: "onClose" }, viewQueries: [{ propertyName: "defaultImagesContainerRef", first: true, predicate: ["defaultImagesContainer"], descendants: true }, { propertyName: "uploadImageInputRef", first: true, predicate: ["uploadImageInput"], descendants: true }, { propertyName: "backgroundCanvasRef", first: true, predicate: ["backgroundCanvas"], descendants: true }, { propertyName: "videoPreviewRef", first: true, predicate: ["videoPreview"], descendants: true }, { propertyName: "captureVideoRef", first: true, predicate: ["captureVideo"], descendants: true }, { propertyName: "loadingOverlayRef", first: true, predicate: ["loadingOverlay"], descendants: true }, { propertyName: "applyBackgroundButtonRef", first: true, predicate: ["applyBackgroundButton"], descendants: true }, { propertyName: "saveBackgroundButtonRef", first: true, predicate: ["saveBackgroundButton"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div [ngStyle]=\"{ position: 'fixed', top: 0, left: 0, width: '100%', height: '100%', backgroundColor: 'rgba(0, 0, 0, 0.5)', display: isVisible ? 'block' : 'none', zIndex: 999 }\">\r\n <div [ngStyle]=\"{ position: 'fixed', backgroundColor: backgroundColor, borderRadius: '10px', padding: '10px', width: '80%', maxWidth: '500px', maxHeight: '75%', overflowY: 'auto', overflowX: 'hidden', top: position.includes('top') ? '10px' : 'auto', bottom: position.includes('bottom') ? '10px' : 'auto', left: position.includes('Left') ? '10px' : 'auto', right: position.includes('Right') ? '10px' : 'auto' }\">\r\n <div style=\"display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px;\">\r\n <h2 style=\"font-size: x-large; font-weight: bold; color: black;\">Background Settings</h2>\r\n <button (click)=\"onClose()\" style=\"border: none; background: none; cursor: pointer;\">\r\n <fa-icon [icon]=\"faTimes\" size=\"xl\" style=\"font-size: 20px; color: black;\"></fa-icon>\r\n </button>\r\n </div>\r\n <hr style=\"height: 1px; background-color: black; margin-top: 5px; margin-bottom: 5px;\" />\r\n <div style=\"max-width: 95%; overflow-x: auto;\">\r\n <div id=\"defaultImages\" #defaultImagesContainer></div>\r\n <div class=\"form-group\" style=\"max-width: 70%; overflow-x: auto;\">\r\n <label for=\"uploadImage\">Upload Custom Image</label>\r\n <input type=\"file\" class=\"form-control\" id=\"uploadImage\" #uploadImageInput (change)=\"handleImageUpload($event)\" />\r\n </div>\r\n <canvas id=\"mainCanvas\" #mainCanvas class=\"d-none\"></canvas>\r\n <canvas id=\"backgroundCanvas\" #backgroundCanvas class=\"d-none\" style=\"width: 100%; max-width: 400px; height: auto; background-color: transparent; border: 1px solid black;\"></canvas>\r\n <video id=\"captureVideo\" #captureVideo class=\"d-none\" muted autoplay playsinline></video>\r\n <video id=\"previewVideo\" #videoPreview class=\"d-none\" muted autoplay playsinline style=\"width: 100%; max-width: 400px; height: auto; background-color: transparent; border: 1px solid black;\"></video>\r\n <div id=\"loadingOverlay\" #loadingOverlay class=\"d-none\" [ngStyle]=\"{ position: 'absolute', top: 0, left: 0, width: '100%', height: '100%', backgroundColor: 'rgba(0, 0, 0, 0.5)', display: 'flex', 'justify-content': 'center', 'align-items': 'center', zIndex: 1000 }\">\r\n <div [ngStyle]=\"{ width: '50px', height: '50px', border: '5px solid rgba(255, 255, 255, 0.3)', borderRadius: '50%', borderTop: '5px solid white', animation: 'spin 1s linear infinite' }\"></div>\r\n </div>\r\n <br />\r\n <button id=\"applyBackgroundButton\" #applyBackgroundButton class=\"btn btn-primary\" (click)=\"applyBackground()\">Preview Background</button>\r\n <button id=\"saveBackgroundButton\" #saveBackgroundButton class=\"btn btn-success d-none\" (click)=\"saveBackground()\">Save Background</button>\r\n </div>\r\n </div>\r\n </div>\r\n", styles: ["@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FontAwesomeModule }, { kind: "component", type: i2.FaIconComponent, selector: "fa-icon", inputs: ["icon", "title", "animation", "mask", "flip", "size", "pull", "border", "inverse", "symbol", "rotate", "fixedWidth", "transform", "a11yRole"] }] });
724
+ }
725
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.8", ngImport: i0, type: BackgroundModal, decorators: [{
726
+ type: Component,
727
+ args: [{ selector: 'app-background-modal', standalone: true, imports: [CommonModule, FontAwesomeModule], template: "<div [ngStyle]=\"{ position: 'fixed', top: 0, left: 0, width: '100%', height: '100%', backgroundColor: 'rgba(0, 0, 0, 0.5)', display: isVisible ? 'block' : 'none', zIndex: 999 }\">\r\n <div [ngStyle]=\"{ position: 'fixed', backgroundColor: backgroundColor, borderRadius: '10px', padding: '10px', width: '80%', maxWidth: '500px', maxHeight: '75%', overflowY: 'auto', overflowX: 'hidden', top: position.includes('top') ? '10px' : 'auto', bottom: position.includes('bottom') ? '10px' : 'auto', left: position.includes('Left') ? '10px' : 'auto', right: position.includes('Right') ? '10px' : 'auto' }\">\r\n <div style=\"display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px;\">\r\n <h2 style=\"font-size: x-large; font-weight: bold; color: black;\">Background Settings</h2>\r\n <button (click)=\"onClose()\" style=\"border: none; background: none; cursor: pointer;\">\r\n <fa-icon [icon]=\"faTimes\" size=\"xl\" style=\"font-size: 20px; color: black;\"></fa-icon>\r\n </button>\r\n </div>\r\n <hr style=\"height: 1px; background-color: black; margin-top: 5px; margin-bottom: 5px;\" />\r\n <div style=\"max-width: 95%; overflow-x: auto;\">\r\n <div id=\"defaultImages\" #defaultImagesContainer></div>\r\n <div class=\"form-group\" style=\"max-width: 70%; overflow-x: auto;\">\r\n <label for=\"uploadImage\">Upload Custom Image</label>\r\n <input type=\"file\" class=\"form-control\" id=\"uploadImage\" #uploadImageInput (change)=\"handleImageUpload($event)\" />\r\n </div>\r\n <canvas id=\"mainCanvas\" #mainCanvas class=\"d-none\"></canvas>\r\n <canvas id=\"backgroundCanvas\" #backgroundCanvas class=\"d-none\" style=\"width: 100%; max-width: 400px; height: auto; background-color: transparent; border: 1px solid black;\"></canvas>\r\n <video id=\"captureVideo\" #captureVideo class=\"d-none\" muted autoplay playsinline></video>\r\n <video id=\"previewVideo\" #videoPreview class=\"d-none\" muted autoplay playsinline style=\"width: 100%; max-width: 400px; height: auto; background-color: transparent; border: 1px solid black;\"></video>\r\n <div id=\"loadingOverlay\" #loadingOverlay class=\"d-none\" [ngStyle]=\"{ position: 'absolute', top: 0, left: 0, width: '100%', height: '100%', backgroundColor: 'rgba(0, 0, 0, 0.5)', display: 'flex', 'justify-content': 'center', 'align-items': 'center', zIndex: 1000 }\">\r\n <div [ngStyle]=\"{ width: '50px', height: '50px', border: '5px solid rgba(255, 255, 255, 0.3)', borderRadius: '50%', borderTop: '5px solid white', animation: 'spin 1s linear infinite' }\"></div>\r\n </div>\r\n <br />\r\n <button id=\"applyBackgroundButton\" #applyBackgroundButton class=\"btn btn-primary\" (click)=\"applyBackground()\">Preview Background</button>\r\n <button id=\"saveBackgroundButton\" #saveBackgroundButton class=\"btn btn-success d-none\" (click)=\"saveBackground()\">Save Background</button>\r\n </div>\r\n </div>\r\n </div>\r\n", styles: ["@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}\n"] }]
728
+ }], propDecorators: { isVisible: [{
729
+ type: Input
730
+ }], parameters: [{
731
+ type: Input
732
+ }], position: [{
733
+ type: Input
734
+ }], backgroundColor: [{
735
+ type: Input
736
+ }], onClose: [{
737
+ type: Input
738
+ }], defaultImagesContainerRef: [{
739
+ type: ViewChild,
740
+ args: ['defaultImagesContainer']
741
+ }], uploadImageInputRef: [{
742
+ type: ViewChild,
743
+ args: ['uploadImageInput']
744
+ }], backgroundCanvasRef: [{
745
+ type: ViewChild,
746
+ args: ['backgroundCanvas']
747
+ }], videoPreviewRef: [{
748
+ type: ViewChild,
749
+ args: ['videoPreview']
750
+ }], captureVideoRef: [{
751
+ type: ViewChild,
752
+ args: ['captureVideo']
753
+ }], loadingOverlayRef: [{
754
+ type: ViewChild,
755
+ args: ['loadingOverlay']
756
+ }], applyBackgroundButtonRef: [{
757
+ type: ViewChild,
758
+ args: ['applyBackgroundButton']
759
+ }], saveBackgroundButtonRef: [{
760
+ type: ViewChild,
761
+ args: ['saveBackgroundButton']
762
+ }] } });
763
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFja2dyb3VuZC1tb2RhbC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9tZWRpYXNmdS1hbmd1bGFyL3NyYy9saWIvY29tcG9uZW50cy9iYWNrZ3JvdW5kLWNvbXBvbmVudHMvYmFja2dyb3VuZC1tb2RhbC9iYWNrZ3JvdW5kLW1vZGFsLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL21lZGlhc2Z1LWFuZ3VsYXIvc3JjL2xpYi9jb21wb25lbnRzL2JhY2tncm91bmQtY29tcG9uZW50cy9iYWNrZ3JvdW5kLW1vZGFsL2JhY2tncm91bmQtbW9kYWwuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsNkRBQTZEO0FBQzdELE9BQU8sRUFDTCxTQUFTLEVBQ1QsS0FBSyxFQUdMLFNBQVMsR0FHVixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDckUsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLG1DQUFtQyxDQUFDO0FBQzVELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLGdDQUFnQyxDQUFDOzs7O0FBOEZwRSxNQUFNLE9BQU8sZUFBZTtJQUNqQixTQUFTLEdBQUcsS0FBSyxDQUFDO0lBQ2xCLFVBQVUsR0FBOEIsRUFBK0IsQ0FBQztJQUN4RSxRQUFRLEdBQUcsU0FBUyxDQUFDO0lBQ3JCLGVBQWUsR0FBRyxTQUFTLENBQUM7SUFDNUIsT0FBTyxHQUFlLEdBQUcsRUFBRTtRQUNsQyxPQUFPLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ3pCLENBQUMsQ0FBQztJQUVtQyx5QkFBeUIsQ0FBYztJQUM3QyxtQkFBbUIsQ0FBYztJQUNqQyxtQkFBbUIsQ0FBYztJQUNyQyxlQUFlLENBQWM7SUFDN0IsZUFBZSxDQUFjO0lBQzNCLGlCQUFpQixDQUFjO0lBQ3hCLHdCQUF3QixDQUFjO0lBQ3ZDLHVCQUF1QixDQUFjO0lBRXhFLE9BQU8sR0FBRyxPQUFPLENBQUM7SUFFbEIsV0FBVyxHQUFHLEVBQUUsQ0FBQztJQUNqQixhQUFhLEdBQUcsRUFBRSxDQUFDO0lBQ25CLFlBQVksR0FBdUIsSUFBSSxDQUFDO0lBQ3hDLGtCQUFrQixHQUE4QixJQUFJLENBQUM7SUFDckQsaUJBQWlCLEdBQUcsS0FBSyxDQUFDO0lBQzFCLGVBQWUsR0FBdUIsSUFBSSxDQUFDO0lBQzNDLGNBQWMsR0FBRyxLQUFLLENBQUM7SUFDdkIsb0JBQW9CLEdBQUcsS0FBSyxDQUFDO0lBQzdCLGFBQWEsR0FBdUIsSUFBSSxDQUFDO0lBQ3pDLFVBQVUsQ0FBcUI7SUFDL0Isa0JBQWtCLEdBQUcsS0FBSyxDQUFDO0lBQzNCLGlCQUFpQixHQUFHLEtBQUssQ0FBQztJQUMxQixjQUFjLEdBQUcsS0FBSyxDQUFDO0lBQ3ZCLGFBQWEsR0FBRyxLQUFLLENBQUM7SUFDdEIsT0FBTyxHQUFHLEdBQUcsQ0FBQztJQUNkLGFBQWEsR0FBRyxLQUFLLENBQUM7SUFDdEIsYUFBYSxHQUFHLEtBQUssQ0FBQztJQUN0QixZQUFZLEdBQUcsS0FBSyxDQUFDO0lBQ3JCLGFBQWEsR0FBRyxLQUFLLENBQUM7SUFDdEIscUJBQXFCLEdBQUcsRUFBRSxDQUFDO0lBQzNCLE9BQU8sR0FBUSxFQUFFLENBQUM7SUFDbEIsU0FBUyxHQUFHLENBQUMsQ0FBQztJQUNkLGdCQUFnQixHQUFHLFVBQVUsQ0FBQztJQUM5QixXQUFXLEdBQW9CLEVBQUUsQ0FBQztJQUNsQyxtQkFBbUIsR0FBRyxLQUFLLENBQUM7SUFDNUIsZ0JBQWdCLEdBQXVCLElBQUksQ0FBQztJQUU1QyxZQUFZLEdBQXVCLElBQUksQ0FBQztJQUN4QyxXQUFXLEdBQTRCLElBQUksQ0FBQztJQUU1QyxpQkFBaUIsQ0FBMkI7SUFDNUMsbUJBQW1CLENBQTJCO0lBQzlDLGtCQUFrQixDQUF1QztJQUN6RCx3QkFBd0IsQ0FBOEM7SUFDdEUsdUJBQXVCLENBQTRCO0lBQ25ELHFCQUFxQixDQUF1QztJQUM1RCxvQkFBb0IsQ0FBNEI7SUFDaEQsMEJBQTBCLENBQTRCO0lBQ3RELG1CQUFtQixDQUF1QztJQUMxRCxnQkFBZ0IsQ0FBc0M7SUFDdEQsd0JBQXdCLENBQTRCO0lBQ3BELHVCQUF1QixDQUE0QjtJQUNuRCxpQkFBaUIsQ0FBb0M7SUFDckQseUJBQXlCLENBQTRCO0lBRXJELGtCQUFrQjtJQUNsQixtQkFBbUIsQ0FBMkI7SUFDOUMseUJBQXlCLENBQWlDO0lBQzFELDRCQUE0QixDQUFvQztJQUNoRSxlQUFlLENBQXVCO0lBQ3RDLEtBQUssQ0FBYTtJQUVsQixRQUFRO1FBQ04sa0RBQWtEO1FBQ2xELElBQUksSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQ3BCLElBQUksQ0FBQztnQkFDSCxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7WUFDekIsQ0FBQztZQUFDLE1BQU0sQ0FBQztnQkFDUCxrQkFBa0I7WUFDcEIsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBRUQsV0FBVyxDQUFDLE9BQXNCO1FBQ2hDLElBQUksT0FBTyxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUM7WUFDekIsSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUM7UUFDNUIsQ0FBQztRQUVELElBQUksT0FBTyxDQUFDLHFCQUFxQixDQUFDLEVBQUUsQ0FBQztZQUNuQyxPQUFPLENBQUMsR0FBRyxDQUNULGdDQUFnQyxFQUNoQyxJQUFJLENBQUMsbUJBQW1CLEVBQ3hCLE9BQU8sQ0FBQyxxQkFBcUIsQ0FBQyxDQUMvQixDQUFDO1FBQ0osQ0FBQztJQUNILENBQUM7SUFFRCxlQUFlO1FBQ2IsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLFdBQVcsSUFBSSxFQUFFLENBQUM7UUFDckQsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLGFBQWEsSUFBSSxFQUFFLENBQUM7UUFDekQsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLFlBQVksSUFBSSxJQUFJLENBQUM7UUFDekQsSUFBSSxDQUFDLGtCQUFrQixHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsa0JBQWtCLElBQUksSUFBSSxDQUFDO1FBQ3JFLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLGlCQUFpQixJQUFJLEtBQUssQ0FBQztRQUNwRSxJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsZUFBZSxJQUFJLElBQUksQ0FBQztRQUMvRCxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsY0FBYyxJQUFJLEtBQUssQ0FBQztRQUM5RCxJQUFJLENBQUMsb0JBQW9CLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxvQkFBb0IsSUFBSSxLQUFLLENBQUM7UUFDMUUsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLGFBQWEsSUFBSSxJQUFJLENBQUM7UUFDM0QsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLFVBQVUsSUFBSSxJQUFJLENBQUMsbUJBQW1CLEVBQUUsYUFBYSxJQUFJLElBQUksQ0FBQztRQUNoRyxJQUFJLENBQUMsa0JBQWtCLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxrQkFBa0IsSUFBSSxLQUFLLENBQUM7UUFDdEUsSUFBSSxDQUFDLGlCQUFpQixHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsaUJBQWlCLElBQUksS0FBSyxDQUFDO1FBQ3BFLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxjQUFjLElBQUksS0FBSyxDQUFDO1FBQzlELElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLElBQUksS0FBSyxDQUFDO1FBQzVELElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxPQUFPLElBQUksR0FBRyxDQUFDO1FBQzlDLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLElBQUksS0FBSyxDQUFDO1FBQzVELElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLElBQUksS0FBSyxDQUFDO1FBQzVELElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxZQUFZLElBQUksS0FBSyxDQUFDO1FBQzFELElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLElBQUksS0FBSyxDQUFDO1FBQzVELElBQUksQ0FBQyxxQkFBcUIsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLHFCQUFxQixJQUFJLEVBQUUsQ0FBQztRQUN6RSxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsT0FBTyxJQUFJLEVBQUUsQ0FBQztRQUM3QyxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsU0FBUyxJQUFJLENBQUMsQ0FBQztRQUNoRCxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsV0FBVyxJQUFJLElBQUksQ0FBQztRQUN2RCxJQUFJLENBQUMsbUJBQW1CLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxtQkFBbUIsSUFBSSxLQUFLLENBQUM7UUFDeEUsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsZ0JBQWdCLElBQUksSUFBSSxDQUFDO1FBRWpFLDJCQUEyQjtRQUMzQixJQUFJLENBQUMsaUJBQWlCLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxpQkFBaUIsQ0FBQztRQUMzRCxJQUFJLENBQUMsbUJBQW1CLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxtQkFBbUIsQ0FBQztRQUMvRCxJQUFJLENBQUMsa0JBQWtCLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxrQkFBa0IsQ0FBQztRQUM3RCxJQUFJLENBQUMsd0JBQXdCLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyx3QkFBd0IsQ0FBQztRQUN6RSxJQUFJLENBQUMsdUJBQXVCLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyx1QkFBdUIsQ0FBQztRQUN2RSxJQUFJLENBQUMscUJBQXFCLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxxQkFBcUIsQ0FBQztRQUNuRSxJQUFJLENBQUMsb0JBQW9CLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxvQkFBb0IsQ0FBQztRQUNqRSxJQUFJLENBQUMsMEJBQTBCLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQywwQkFBMEIsQ0FBQztRQUM3RSxJQUFJLENBQUMsbUJBQW1CLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxtQkFBbUIsQ0FBQztRQUMvRCxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxnQkFBZ0IsQ0FBQztRQUN6RCxJQUFJLENBQUMsd0JBQXdCLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyx3QkFBd0IsQ0FBQztRQUN6RSxJQUFJLENBQUMsdUJBQXVCLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyx1QkFBdUIsQ0FBQztRQUN2RSxJQUFJLENBQUMsaUJBQWlCLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxpQkFBaUIsQ0FBQztRQUMzRCxJQUFJLENBQUMseUJBQXlCLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyx5QkFBeUIsQ0FBQztRQUUzRSxJQUFJLENBQUMsbUJBQW1CLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxtQkFBbUIsQ0FBQztRQUMvRCxJQUFJLENBQUMseUJBQXlCLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyx5QkFBeUIsQ0FBQztRQUMzRSxJQUFJLENBQUMsNEJBQTRCLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyw0QkFBNEIsQ0FBQztRQUNqRixJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsZUFBZSxDQUFDO1FBQ3ZELElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUM7SUFDckMsQ0FBQztJQUVELGtCQUFrQixHQUFHLEtBQUssSUFBSSxFQUFFO1FBQzlCLElBQUksSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQ3BCLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1lBQ3hELElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUN6QixDQUFDO1FBRUQsSUFBSSxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDbkIsSUFBSSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO2dCQUM3QixNQUFNLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDLENBQUM7WUFDaEYsQ0FBQztZQUNELElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1lBRTNCLElBQUksSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO2dCQUN2QixNQUFNLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQztZQUN2RSxDQUFDO2lCQUFNLENBQUM7Z0JBQ04sSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO2dCQUNuQixJQUFJLENBQUMsbUJBQW1CLENBQUMsYUFBYSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDcEUsQ0FBQztZQUVELElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxhQUFhLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUNuRSxJQUFJLENBQUMsdUJBQXVCLENBQUMsYUFBYSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUM7WUFDM0QsSUFBSSxDQUFDLHdCQUF3QixDQUFDLGFBQWEsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ3ZFLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxhQUFhLENBQUMsUUFBUSxHQUFHLEtBQUssQ0FBQztZQUU3RCxJQUNFLElBQUksQ0FBQyxlQUFlO2dCQUNwQixJQUFJLENBQUMsa0JBQWtCLElBQUksSUFBSSxDQUFDLGNBQWM7Z0JBQzlDLElBQUksQ0FBQyxjQUFjO2dCQUNuQixJQUFJLENBQUMsaUJBQWlCLEVBQ3RCLENBQUM7Z0JBQ0QsSUFBSSxDQUFDLHdCQUF3QixDQUFDLGFBQWEsQ0FBQyxTQUFTLEdBQUcsa0JBQWtCLENBQUM7WUFDN0UsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxhQUFhLENBQUMsU0FBUyxHQUFHLG9CQUFvQixDQUFDO1lBQy9FLENBQUM7WUFFRCxJQUFJLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO2dCQUM3QixNQUFNLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztnQkFDN0IsTUFBTSxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7Z0JBQzVCLElBQUksQ0FBQyxtQkFBbUIsR0FBRyxLQUFLLENBQUM7Z0JBQ2pDLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxJQUFJLENBQUMsbUJBQW1CLENBQUMsQ0FBQztZQUMzRCxDQUFDO1FBQ0gsQ0FBQzthQUFNLENBQUM7WUFDTixJQUFJLENBQUM7Z0JBQ0gsMkVBQTJFO2dCQUMzRSxJQUNFLENBQUMsSUFBSSxDQUFDLGlCQUFpQjtvQkFDdkIsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLElBQUksQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDO29CQUNoRCxDQUFDLElBQUksQ0FBQyxpQkFBaUIsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsRUFDaEQsQ0FBQztvQkFDRCxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLGFBQWEsQ0FBQztvQkFDcEQsSUFBSSxDQUFDLGlCQUFpQixHQUFHLElBQUksQ0FBQztvQkFDOUIsSUFBSSxDQUFDLHVCQUF1QixDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO29CQUVyRCxJQUFJLENBQUMsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO3dCQUN6Qiw0REFBNEQ7d0JBQzVELElBQUksUUFBUSxJQUFJLFFBQVEsQ0FBQyxTQUFTLEVBQUUsQ0FBQzs0QkFDbkMsUUFBUSxDQUFDLFNBQVMsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxLQUFVLEVBQUUsRUFBRSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDOzRCQUNyRSxRQUFRLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQzt3QkFDNUIsQ0FBQzt3QkFFRCwyQkFBMkI7d0JBQzNCLElBQUksSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDOzRCQUN0QixJQUFJLENBQUMsWUFBWSxDQUFDLFNBQVMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEtBQVUsRUFBRSxFQUFFLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7NEJBQ3BFLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDOzRCQUN6QixJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO3dCQUM3QyxDQUFDO3dCQUVELDRCQUE0Qjt3QkFDNUIsSUFBSSxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7NEJBQ3ZCLElBQUksQ0FBQyxhQUFhLENBQUMsU0FBUyxFQUFFLENBQUMsT0FBTyxDQUFDLENBQUMsS0FBVSxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQzs0QkFDckUsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUM7NEJBQzFCLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7d0JBQy9DLENBQUM7b0JBQ0gsQ0FBQztnQkFDSCxDQUFDO2dCQUVELDZDQUE2QztnQkFDN0MsSUFBSSxDQUFDLGVBQWUsQ0FBQyxhQUFhLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQztnQkFDM0QsSUFBSSxDQUFDLG1CQUFtQixDQUFDLGFBQWEsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ3BFLENBQUM7WUFBQyxNQUFNLENBQUM7Z0JBQ1Asa0JBQWtCO1lBQ3BCLENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQyxDQUFDO0lBRUYsS0FBSyxDQUFDLFlBQVk7UUFDaEIsSUFBSSxDQUFDLGtCQUFrQixHQUFHLElBQUksa0JBQWtCLENBQUM7WUFDL0MsVUFBVSxFQUFFLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQywrREFBK0QsSUFBSSxFQUFFO1NBQzVGLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxVQUFVLENBQUM7WUFDakMsY0FBYyxFQUFFLENBQUM7WUFDakIsVUFBVSxFQUFFLEtBQUs7U0FDbEIsQ0FBQyxDQUFDO1FBQ0gsTUFBTSxJQUFJLENBQUMsa0JBQWtCLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDM0MsSUFBSSxDQUFDLHdCQUF3QixDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO0lBQ3pELENBQUM7SUFFRCxtQkFBbUI7UUFDakIsTUFBTSxhQUFhLEdBQUcsQ0FBQyxNQUFNLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsUUFBUSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQzlFLE1BQU0sc0JBQXNCLEdBQUcsSUFBSSxDQUFDLHlCQUF5QixDQUFDLGFBQWEsQ0FBQztRQUM1RSxzQkFBc0IsQ0FBQyxTQUFTLEdBQUcsRUFBRSxDQUFDO1FBRXRDLGFBQWEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxRQUFRLEVBQUUsRUFBRTtZQUNqQyxNQUFNLEtBQUssR0FBRywyQ0FBMkMsUUFBUSxnQkFBZ0IsQ0FBQztZQUNsRixNQUFNLEtBQUssR0FBRywyQ0FBMkMsUUFBUSxZQUFZLENBQUM7WUFDOUUsTUFBTSxLQUFLLEdBQUcsMkNBQTJDLFFBQVEsWUFBWSxDQUFDO1lBQzlFLE1BQU0sSUFBSSxHQUFHLDJDQUEyQyxRQUFRLE1BQU0sQ0FBQztZQUN2RSxNQUFNLEdBQUcsR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQzFDLEdBQUcsQ0FBQyxHQUFHLEdBQUcsS0FBSyxDQUFDO1lBQ2hCLEdBQUcsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLGVBQWUsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUMxQyxHQUFHLENBQUMsS0FBSyxDQUFDLEtBQUssR0FBRyxNQUFNLENBQUM7WUFDekIsR0FBRyxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsU0FBUyxDQUFDO1lBQzdCLEdBQUcsQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLEVBQUUsS0FBSyxJQUFJLEVBQUU7Z0JBQ3ZDLElBQUksSUFBSSxDQUFDLGdCQUFnQixJQUFJLEtBQUssSUFBSSxJQUFJLENBQUMsZ0JBQWdCLElBQUksS0FBSyxFQUFFLENBQUM7b0JBQ3JFLE1BQU0sSUFBSSxDQUFDLGlCQUFpQixDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztnQkFDN0MsQ0FBQztxQkFBTSxDQUFDO29CQUNOLE1BQU0sSUFBSSxDQUFDLGlCQUFpQixDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsQ0FBQztnQkFDNUMsQ0FBQztZQUNILENBQUMsQ0FBQyxDQUFDO1lBQ0gsc0JBQXNCLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQzFDLENBQUMsQ0FBQyxDQUFDO1FBRUgsTUFBTSxlQUFlLEdBQUcsUUFBUSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUN0RCxlQUFlLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FDM0IsZUFBZSxFQUNmLEtBQUssRUFDTCxRQUFRLEVBQ1Isb0JBQW9CLEVBQ3BCLHdCQUF3QixDQUN6QixDQUFDO1FBQ0YsZUFBZSxDQUFDLEtBQUssQ0FBQyxLQUFLLEdBQUcsTUFBTSxDQUFDO1FBQ3JDLGVBQWUsQ0FBQyxLQUFLLENBQUMsU0FBUyxHQUFHLE1BQU0sQ0FBQztRQUN6QyxlQUFlLENBQUMsS0FBSyxDQUFDLE1BQU0sR0FBRyxTQUFTLENBQUM7UUFDekMsZUFBZSxDQUFDLEtBQUssQ0FBQyxlQUFlLEdBQUcsU0FBUyxDQUFDO1FBQ2xELGVBQWUsQ0FBQyxLQUFLLENBQUMsTUFBTSxHQUFHLG1CQUFtQixDQUFDO1FBQ25ELGVBQWUsQ0FBQyxLQUFLLENBQUMsUUFBUSxHQUFHLFVBQVUsQ0FBQztRQUM1QyxlQUFlLENBQUMsU0FBUztZQUN2Qiw4R0FBOEcsQ0FBQztRQUNqSCxlQUFlLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxFQUFFLEtBQUssSUFBSSxFQUFFO1lBQ25ELElBQUksQ0FBQyxhQUFhLEdBQUcsRUFBRSxDQUFDO1lBQ3hCLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7WUFDN0MsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQzNCLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUNuQixJQUFJLENBQUMsZUFBZSxDQUFDLGFBQWEsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQzNELElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxhQUFhLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUNsRSxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDbkIsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ3JCLENBQUMsQ0FBQyxDQUFDO1FBQ0gsc0JBQXNCLENBQUMsV0FBVyxDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBRXBELElBQUksSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQ3JCLE1BQU0sR0FBRyxHQUFHLFFBQVEsQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDMUMsR0FBRyxDQUFDLEdBQUcsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDO1lBQzNCLEdBQUcsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLGVBQWUsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUMxQyxHQUFHLENBQUMsS0FBSyxDQUFDLEtBQUssR0FBRyxNQUFNLENBQUM7WUFDekIsR0FBRyxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsU0FBUyxDQUFDO1lBQzdCLEdBQUcsQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLEVBQUUsS0FBSyxJQUFJLEVBQUU7Z0JBQ3ZDLE1BQU0sSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBQ25FLENBQUMsQ0FBQyxDQUFDO1lBQ0gsc0JBQXNCLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQzFDLENBQUM7SUFDSCxDQUFDO0lBRUQsS0FBSyxDQUFDLGlCQUFpQixDQUFDLEtBQVk7UUFDbEMsSUFBSSxRQUFRLEdBQUcsSUFBSSxDQUFDO1FBQ3BCLElBQUksU0FBUyxHQUFHLElBQUksQ0FBQztRQUNyQixJQUFJLFFBQVEsR0FBRyxJQUFJLENBQUM7UUFDcEIsSUFBSSxTQUFTLEdBQUcsSUFBSSxDQUFDO1FBRXJCLElBQUksSUFBSSxDQUFDLGdCQUFnQixJQUFJLEtBQUssRUFBRSxDQUFDO1lBQ25DLFFBQVEsR0FBRyxJQUFJLENBQUM7WUFDaEIsU0FBUyxHQUFHLElBQUksQ0FBQztRQUNuQixDQUFDO2FBQU0sSUFBSSxJQUFJLENBQUMsZ0JBQWdCLElBQUksS0FBSyxFQUFFLENBQUM7WUFDMUMsUUFBUSxHQUFHLElBQUksQ0FBQztZQUNoQixTQUFTLEdBQUcsSUFBSSxDQUFDO1FBQ25CLENBQUMsQ0FBQyx3REFBd0Q7UUFFMUQsTUFBTSxLQUFLLEdBQUcsS0FBSyxDQUFDLE1BQTBCLENBQUM7UUFDL0MsSUFBSSxLQUFLLENBQUMsS0FBSyxJQUFJLEtBQUssQ0FBQyxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQzFDLE1BQU0sSUFBSSxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDNUIsTUFBTSxHQUFHLEdBQUcsSUFBSSxLQUFLLEVBQUUsQ0FBQztZQUN4QixHQUFHLENBQUMsV0FBVyxHQUFHLFdBQVcsQ0FBQztZQUM5QixHQUFHLENBQUMsTUFBTSxHQUFHLEtBQUssSUFBSSxFQUFFO2dCQUN0QixJQUNFLEdBQUcsQ0FBQyxLQUFLLEdBQUcsUUFBUTtvQkFDcEIsR0FBRyxDQUFDLE1BQU0sR0FBRyxTQUFTO29CQUN0QixHQUFHLENBQUMsS0FBSyxHQUFHLFFBQVE7b0JBQ3BCLEdBQUcsQ0FBQyxNQUFNLEdBQUcsU0FBUyxFQUN0QixDQUFDO29CQUNELElBQUksQ0FBQyxXQUFXLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQztvQkFDM0IsSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztvQkFDekMsTUFBTSxJQUFJLENBQUMsaUJBQWlCLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQ2pELENBQUM7WUFDSCxDQUFDLENBQUM7WUFDRixNQUFNLE1BQU0sR0FBRyxJQUFJLFVBQVUsRUFBRSxDQUFDO1lBQ2hDLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUE0QixFQUFFLEVBQUU7Z0JBQy9DLElBQUksQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDO29CQUNiLEdBQUcsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxNQUFnQixDQUFDO2dCQUN0QyxDQUFDO1lBQ0gsQ0FBQyxDQUFDO1lBQ0YsTUFBTSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUM3QixDQUFDO0lBQ0gsQ0FBQztJQUVELFdBQVc7UUFDVCxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsbUJBQW1CLENBQUMsYUFBYSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNwRSxHQUFHLENBQUMsU0FBUyxDQUNYLENBQUMsRUFDRCxDQUFDLEVBQ0QsSUFBSSxDQUFDLG1CQUFtQixDQUFDLGFBQWEsQ0FBQyxLQUFLLEVBQzVDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUM5QyxDQUFDO1FBQ0YsR0FBRyxDQUFDLElBQUksR0FBRyxZQUFZLENBQUM7UUFDeEIsR0FBRyxDQUFDLFNBQVMsR0FBRyxNQUFNLENBQUM7UUFDdkIsR0FBRyxDQUFDLFNBQVMsR0FBRyxRQUFRLENBQUM7UUFDekIsR0FBRyxDQUFDLFlBQVksR0FBRyxRQUFRLENBQUM7UUFDNUIsR0FBRyxDQUFDLFFBQVEsQ0FDVixlQUFlLEVBQ2YsSUFBSSxDQUFDLG1CQUFtQixDQUFDLGFBQWEsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxFQUNoRCxJQUFJLENBQUMsbUJBQW1CLENBQUMsYUFBYSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQ2xELENBQUM7UUFFRixJQUFJLENBQUMsd0JBQXdCLENBQUMsYUFBYSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDdkUsSUFBSSxDQUFDLHdCQUF3QixDQUFDLGFBQWEsQ0FBQyxRQUFRLEdBQUcsS0FBSyxDQUFDO1FBRTdELElBQ0UsSUFBSSxDQUFDLGVBQWU7WUFDcEIsSUFBSSxDQUFDLGtCQUFrQixJQUFJLElBQUksQ0FBQyxjQUFjO1lBQzlDLElBQUksQ0FBQyxjQUFjO1lBQ25CLElBQUksQ0FBQyxpQkFBaUIsRUFDdEIsQ0FBQztZQUNELElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxhQUFhLENBQUMsU0FBUyxHQUFHLGtCQUFrQixDQUFDO1FBQzdFLENBQUM7YUFBTSxDQUFDO1lBQ04sSUFBSSxDQUFDLHdCQUF3QixDQUFDLGFBQWEsQ0FBQyxTQUFTLEdBQUcsb0JBQW9CLENBQUM7UUFDL0UsQ0FBQztJQUNILENBQUM7SUFFRCxLQUFLLENBQUMsaUJBQWlCLENBQUMsR0FBVyxFQUFFLE9BQWU7UUFDbEQsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ25CLE1BQU0sSUFBSSxDQUFDLG1CQUFtQixDQUFDLGFBQWEsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ3hFLE1BQU0sSUFBSSxDQUFDLGVBQWUsQ0FBQyxhQUFhLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUVqRSxNQUFNLEdBQUcsR0FBRyxJQUFJLEtBQUssRUFBRSxDQUFDO1FBQ3hCLEdBQUcsQ0FBQyxXQUFXLEdBQUcsV0FBVyxDQUFDO1FBQzlCLEdBQUcsQ0FBQyxNQUFNLEdBQUcsS0FBSyxJQUFJLEVBQUU7WUFDdEIsTUFBTSxHQUFHLEdBQUcsTUFBTSxJQUFJLENBQUMsbUJBQW1CLENBQUMsYUFBYSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUMxRSxJQUFJLENBQUMsbUJBQW1CLENBQUMsYUFBYSxDQUFDLEtBQUssR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDO1lBQ3pELElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxhQUFhLENBQUMsTUFBTSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUM7WUFDM0QsTUFBTSxHQUFHLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDL0IsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQzNCLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUNyQixDQUFDLENBQUM7UUFDRixHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQztRQUNkLElBQUksQ0FBQyxhQUFhLEdBQUcsT0FBTyxDQUFDO1FBQzdCLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7UUFFN0MsSUFBSSxDQUFDLHVCQUF1QixDQUFDLGFBQWEsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ25FLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxhQUFhLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQztRQUMzRCxJQUFJLENBQUMsd0JBQXdCLENBQUMsYUFBYSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDdkUsSUFBSSxDQUFDLHdCQUF3QixDQUFDLGFBQWEsQ0FBQyxRQUFRLEdBQUcsS0FBSyxDQUFDO1FBRTdELElBQ0UsSUFBSSxDQUFDLGVBQWU7WUFDcEIsSUFBSSxDQUFDLGtCQUFrQixJQUFJLElBQUksQ0FBQyxjQUFjO1lBQzlDLElBQUksQ0FBQyxjQUFjO1lBQ25CLElBQUksQ0FBQyxpQkFBaUIsRUFDdEIsQ0FBQztZQUNELElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxhQUFhLENBQUMsU0FBUyxHQUFHLGtCQUFrQixDQUFDO1FBQzdFLENBQUM7YUFBTSxDQUFDO1lBQ04sSUFBSSxDQUFDLHdCQUF3QixDQUFDLGFBQWEsQ0FBQyxTQUFTLEdBQUcsb0JBQW9CLENBQUM7UUFDL0UsQ0FBQztJQUNILENBQUM7SUFFRCxnQkFBZ0IsQ0FBQyxHQUFxQjtRQUNwQyxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsbUJBQW1CLENBQUMsYUFBYSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNwRSxHQUFHLENBQUMsU0FBUyxDQUNYLENBQUMsRUFDRCxDQUFDLEVBQ0QsSUFBSSxDQUFDLG1CQUFtQixDQUFDLGFBQWEsQ0FBQyxLQUFLLEVBQzVDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUM5QyxDQUFDO1FBQ0YsR0FBRyxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQzNCLENBQUM7SUFFRCxLQUFLLENBQUMsZUFBZTtRQUNuQixJQUFJLENBQUM7WUFDSCxJQUFJLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztnQkFDdkIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxTQUFTLEVBQUUsQ0FBQztvQkFDMUIsT0FBTyxFQUFFLHFEQUFxRDtvQkFDOUQsSUFBSSxFQUFFLFFBQVE7aUJBQ2YsQ0FBQyxDQUFDO2dCQUNILE9BQU87WUFDVCxDQUFDO1lBRUQsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBRW5CLElBQUksQ0FBQyxlQUFlLENBQUMsYUFBYSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDOUQsSUFBSSxDQUFDLG1CQUFtQixDQUFDLGFBQWEsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBRS9ELE1BQU0sY0FBYyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDO1lBQ3pELElBQUksQ0FBQyxpQkFBaUIsR0FBRyxLQUFLLENBQUM7WUFDL0IsSUFBSSxDQUFDLHVCQUF1QixDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1lBQ3JELE1BQU0sSUFBSSxDQUFDLHlCQUF5QixDQUFDLGNBQWMsQ0FBQyxDQUFDO1lBRXJELElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUVuQixJQUFJLENBQUMsd0JBQXdCLENBQUMsYUFBYSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDcEUsSUFBSSxDQUFDLHdCQUF3QixDQUFDLGFBQWEsQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDO1lBRTVELElBQ0UsSUFBSSxDQUFDLGVBQWU7Z0JBQ3BCLElBQUksQ0FBQyxrQkFBa0IsSUFBSSxJQUFJLENBQUMsY0FBYztnQkFDOUMsSUFBSSxDQUFDLGNBQWM7Z0JBQ25CLElBQUksQ0FBQyxpQkFBaUIsRUFDdEIsQ0FBQztnQkFDRCxJQUFJLENBQUMsdUJBQXVCLENBQUMsYUFBYSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBQ25FLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxhQUFhLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQztZQUM3RCxDQUFDO2lCQUFNLENBQUM7Z0JBQ04sSUFBSSxDQUFDLHVCQUF1QixDQUFDLGFBQWEsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUN0RSxJQUFJLENBQUMsdUJBQXVCLENBQUMsYUFBYSxDQUFDLFFBQVEsR0FBRyxLQUFLLENBQUM7WUFDOUQsQ0FBQztRQUNILENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsT0FBTyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNyQixDQUFDO0lBQ0gsQ0FBQztJQUVELEtBQUssQ0FBQyx5QkFBeUIsQ0FBQyxjQUF1QjtRQUNyRCxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLGFBQWEsQ0FBQztRQUNwRCxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLGFBQWEsQ0FBQztRQUN4RCxNQUFNLFlBQVksR0FBRyxJQUFJLEtBQUssRUFBRSxDQUFDO1FBQ2pDLFlBQVksQ0FBQyxXQUFXLEdBQUcsV0FBVyxDQUFDO1FBQ3ZDLFlBQVksQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQztRQUV0QyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQ3JCLElBQUksQ0FBQyxVQUFVLEdBQUcsTUFBTSxJQUFJLENBQUMsbUJBQW1CLENBQUMsYUFBYSxDQUFDO1FBQ2pFLENBQUM7UUFFRCxJQUFJLFdBQVcsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDO1FBQ2xDLFdBQVcsQ0FBQyxLQUFLLEdBQUcsUUFBUSxDQUFDLFVBQVUsQ0FBQztRQUN4QyxXQUFXLENBQUMsTUFBTSxHQUFHLFFBQVEsQ0FBQyxXQUFXLENBQUM7UUFDMUMsSUFBSSxHQUFHLEdBQUcsV0FBVyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUV2QyxJQUFJLENBQUMsb0JBQW9CLEdBQUcsSUFBSSxDQUFDO1FBQ2pDLElBQUksQ0FBQywwQkFBMEIsQ0FBQyxJQUFJLENBQUMsb0JBQW9CLENBQUMsQ0FBQztRQUMzRCxJQUFJLENBQUMsa0JBQWtCLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQztRQUM5QyxJQUFJLENBQUMsd0JBQXdCLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBRW5ELElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUNwQixNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsZUFBZSxFQUFFLGNBQWMsRUFBRSxDQUFDO1lBQ3RELElBQUksTUFBTSxFQUFFLENBQUM7Z0JBQ1gsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEtBQXVCLEVBQUUsRUFBRSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO1lBQzVELENBQUM7WUFDRCxJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksQ0FBQztZQUM1QixJQUFJLENBQUMsY0FBYyxHQUFHLEtBQUssQ0FBQztZQUM1QixJQUFJLENBQUMscUJBQXFCLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDakMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ2pDLFlBQVksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQzFDLENBQUM7UUFFRCxNQUFNLFlBQVksR0FBRyxLQUFLLEVBQUUsWUFBOEIsRUFBRSxFQUFFO1lBQzVELE1BQU0sWUFBWSxHQUFHLEdBQUcsRUFBRTtnQkFDeEIsSUFDRSxDQUFDLElBQUksQ0FBQyxrQkFBa0I7b0JBQ3hCLElBQUksQ0FBQyxpQkFBaUI7b0JBQ3RCLENBQUMsWUFBWTtvQkFDYixZQUFZLENBQUMsVUFBVSxJQUFJLENBQUM7b0JBQzVCLFlBQVksQ0FBQyxXQUFXLElBQUksQ0FBQyxFQUM3QixDQUFDO29CQUNELE9BQU87Z0JBQ1QsQ0FBQztnQkFDRCxJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxFQUFFLFlBQVksRUFBRSxDQUFDLENBQUM7Z0JBQ3RELHFCQUFxQixDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQ3RDLENBQUMsQ0FBQztZQUVGLFlBQVksQ0FBQyxZQUFZLEdBQUcsR0FBRyxFQUFFO2dCQUMvQixZQUFZLEVBQUUsQ0FBQztZQUNqQixDQUFDLENBQUM7WUFFRixVQUFVLENBQUMsS0FBSyxJQUFJLEVBQUU7Z0JBQ3BCLE9BQU8sQ0FBQyxHQUFHLENBQUMsbUJBQW1CLEVBQUUsSUFBSSxDQUFDLFNBQVMsSUFBSSxDQUFDLENBQUMsQ0FBQztnQkFDdEQsSUFBSSxDQUFDLGVBQWUsR0FBRyxXQUFXLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxTQUFTLElBQUksQ0FBQyxDQUFDLENBQUM7Z0JBQ3RFLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUM7Z0JBQ2pELFlBQVksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQztnQkFDOUMsWUFBWSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBQ3hDLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDO2dCQUMzQixJQUFJLENBQUMsb0JBQW9CLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDO2dCQUUvQyxJQUFJLFlBQVksQ0FBQyxNQUFNLEVBQUUsQ0FBQztvQkFDeEIsSUFBSSxDQUFDO3dCQUNILGlCQUFpQjt3QkFDakIsWUFBWSxDQUFDLElBQUksRUFBRSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUU7NEJBQzVCLG9CQUFvQjt3QkFDdEIsQ0FBQyxDQUFDLENBQUM7b0JBQ0wsQ0FBQztvQkFBQyxNQUFNLENBQUM7d0JBQ1Asa0JBQWtCO29CQUNwQixDQUFDO2dCQUNILENBQUM7WUFDSCxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFDVixDQUFDLENBQUM7UUFFRixJQUFJLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUN4QixJQUNFLElBQUksQ0FBQyxXQUFXO2dCQUNoQixJQUFJLENBQUMsV0FBVyxDQUFDLFVBQVUsSUFBSSxNQUFNO2dCQUNyQyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsY0FBYyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJLElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxFQUMxRSxDQUFDO2dCQUNELDJCQUEyQjtZQUM3QixDQUFDO2lCQUFNLENBQUM7Z0JBQ04sTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixFQUFFLGNBQWMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUMvRCxJQUFJLENBQUMsV0FBVyxHQUFHLFdBQVksQ0FBQyxLQUFLLEVBQUUsQ0FBQztnQkFDeEMsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLFdBQVcsQ0FBQyxDQUFDLElBQUksQ0FBQyxXQUFZLENBQUMsQ0FBQyxDQUFDO2dCQUN6RCxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUM7WUFDeEMsQ0FBQztZQUNELElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7WUFDM0MsUUFBUSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDO1lBQ3ZDLElBQUksUUFBUSxDQUFDLE1BQU0sRUFBRSxDQUFDO2dCQUNwQixRQUFRLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDbEIsQ0FBQztZQUVELFFBQVEsQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLFlBQWEsQ0FBQyxjQUFjLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxLQUFNLENBQUM7WUFDN0UsUUFBUSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsWUFBYSxDQUFDLGNBQWMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFDLE1BQU8sQ0FBQztZQUMvRSxXQUFXLENBQUMsS0FBSyxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUM7WUFDbkMsV0FBVyxDQUFDLE1BQU0sR0FBRyxRQUFRLENBQUMsTUFBTSxDQUFDO1lBQ3JDLEdBQUcsR0FBRyxXQUFXLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBRW5DLElBQUksQ0FBQztnQkFDSCxjQUFjO29CQUNaLENBQUMsQ0FBQyxNQUFNLFlBQVksQ0FBQyxRQUFRLENBQUM7b0JBQzlCLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDLFlBQVk7d0JBQ3pDLENBQUMsQ0FBQyxJQUFJLENBQUMsWUFBWTt3QkFDbkIsQ0FBQyxDQUFDLElBQUksQ0FBQyxnQkFBaUIsQ0FBQyxDQUFDO1lBQ2xDLENBQUM7WUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO2dCQUNmLE9BQU8sQ0FBQyxHQUFHLENBQUMseUJBQXlCLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDaEQsQ0FBQztRQUNILENBQUM7YUFBTSxDQUFDO1lBQ04sSUFBSSxJQUFJLENBQUMsWUFBWSxJQUFJLElBQUksQ0FBQyxZQUFZLENBQUMsY0FBYyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxJQUFJLE1BQU0sRUFBRSxDQUFDO2dCQUNwRiw0QkFBNEI7WUFDOUIsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLElBQUksQ0FBQztvQkFDSCxNQUFNLE1BQU0sR0FBRyxNQUFNLFNBQVMsQ0FBQyxZQUFZLENBQUMsWUFBWSxDQUFDO3dCQUN2RCxLQUFLLEVBQUUsRUFBRSxHQUFHLElBQUksQ0FBQyxPQUFPLEVBQUUsU0FBUyxFQUFFLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxTQUFTLElBQUksQ0FBQyxFQUFFLEVBQUU7d0JBQ3JFLEtBQUssRUFBRSxLQUFLO3FCQUNiLENBQUMsQ0FBQztvQkFDSCxJQUFJLENBQUMsWUFBWSxHQUFHLE1BQU0sQ0FBQztvQkFDM0IsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztvQkFDM0MsUUFBUSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDO29CQUN2QyxJQUFJLFFBQVEsQ0FBQyxNQUFNLEVBQUUsQ0FBQzt3QkFDcEIsUUFBUSxDQUFDLElBQUksRUFBRSxDQUFDO29CQUNsQixDQUFDO2dCQUNILENBQUM7Z0JBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztvQkFDZixPQUFPLENBQUMsR0FBRyxDQUFDLDJCQUEyQixFQUFFLEtBQUssQ0FBQyxDQUFDO2dCQUNsRCxDQUFDO2dCQUVELFFBQVEsQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLFlBQWEsQ0FBQyxjQUFjLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxLQUFNLENBQUM7Z0JBQzdFLFFBQVEsQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLFlBQWEsQ0FBQyxjQUFjLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxNQUFPLENBQUM7Z0JBQy9FLFdBQVcsQ0FBQyxLQUFLLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQztnQkFDbkMsV0FBVyxDQUFDLE1BQU0sR0FBRyxRQUFRLENBQUMsTUFBTSxDQUFDO2dCQUNyQyxHQUFHLEdBQUcsV0FBVyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNyQyxDQUFDO1lBRUQsSUFBSSxDQUFDO2dCQUNILGNBQWM7b0JBQ1osQ0FBQyxDQUFDLE1BQU0sWUFBWSxDQUFDLFFBQVEsQ0FBQztvQkFDOUIsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLFNBQVMsR0FBRyxRQUFRLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDcEQsQ0FBQztZQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7Z0JBQ2YsT0FBTyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUNyQixDQUFDO1FBQ0gsQ0FBQztRQUVELElBQUksYUFBYSxHQUFHLFdBQVcsQ0FBQztRQUNoQyxJQUFJLENBQUM7WUFDSCxJQUFJLFlBQVksQ0FBQyxLQUFLLEdBQUcsV0FBVyxDQUFDLEtBQUssSUFBSSxZQUFZLENBQUMsTUFBTSxHQUFHLFdBQVcsQ0FBQyxNQUFNLEVBQUUsQ0FBQztnQkFDdkYsYUFBYSxHQUFHLFFBQVEsQ0FBQztZQUMzQixDQUFDO1FBQ0gsQ0FBQztRQUFDLE1BQU0sQ0FBQztZQUNQLGtCQUFrQjtRQUNwQixDQUFDO1FBRUQsTUFBTSxTQUFTLEdBQUcsQ0FBQyxPQUFZLEVBQUUsRUFBRTtZQUNqQyxJQUFJLENBQUM7Z0JBQ0gsSUFDRSxDQUFDLElBQUksQ0FBQyxpQkFBaUI7b0JBQ3ZCLFdBQVc7b0JBQ1gsV0FBVyxDQUFDLEtBQUssR0FBRyxDQUFDO29CQUNyQixXQUFXLENBQUMsTUFBTSxHQUFHLENBQUM7b0JBQ3RCLFlBQVksQ0FBQyxLQUFLLEdBQUcsQ0FBQztvQkFDdEIsWUFBWSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQ3ZCLENBQUM7b0JBQ0QsR0FBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLFdBQVcsQ0FBQyxLQUFLLEVBQUUsV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDO29CQUM1RCxHQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLFdBQVcsQ0FBQyxLQUFLLEVBQUUsV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDO29CQUV0RixHQUFJLENBQUMsd0JBQXdCLEdBQUcsWUFBWSxDQUFDO29CQUM3QyxNQUFNLEdBQUcsR0FBRyxHQUFJLENBQUMsYUFBYSxDQUFDLFlBQVksRUFBRSxhQUFhLENBQUMsQ0FBQztvQkFDNUQsR0FBSSxDQUFDLFNBQVMsR0FBRyxHQUFJLENBQUM7b0JBQ3RCLEdBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxXQUFXLENBQUMsS0FBSyxFQUFFLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQztvQkFFM0QsR0FBSSxDQUFDLHdCQUF3QixHQUFHLGtCQUFrQixDQUFDO29CQUNuRCxHQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxXQUFXLENBQUMsS0FBSyxFQUFFLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQztnQkFDN0UsQ0FBQztZQUNILENBQUM7WUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO2dCQUNmLE9BQU8sQ0FBQyxHQUFHLENBQUMsMkJBQTJCLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDbEQsQ0FBQztRQUNILENBQUMsQ0FBQztRQUVGLElBQUksQ0FBQyxJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztZQUM3QixNQUFNLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDLENBQUM7UUFDaEYsQ0FBQztRQUVELElBQUksQ0FBQztZQUNILElBQUksQ0FBQyxrQkFBbUIsQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDaEQsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixPQUFPLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3JCLENBQUM7SUFDSCxDQUFDO0lBRUQsY0FBYyxHQUFHLEtBQUssSUFBSSxFQUFFO1FBQzFCLElBQUksSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQ3ZCLElBQUksQ0FBQyxVQUFVLENBQUMsU0FBUyxFQUFFLENBQUM7Z0JBQzFCLE9BQU8sRUFBRSxxREFBcUQ7Z0JBQzlELElBQUksRUFBRSxRQUFRO2FBQ2YsQ0FBQyxDQUFDO1lBQ0gsT0FBTztRQUNULENBQUM7UUFFRCxJQUFJLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxDQUFDO1lBQzlCLElBQUksSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO2dCQUN4QixJQUFJLElBQUksQ0FBQyxPQUFPLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsSUFBSSxJQUFJLENBQUMsYUFBYSxDQUFDLEVBQUUsQ0FBQztvQkFDdEUsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLFlBQVksSUFBSSxJQUFJLENBQUMsYUFBYSxDQUFDLEVBQUUsQ0FBQzt3QkFDL0MsSUFBSSxJQUFJLENBQUMscUJBQXFCLElBQUksT0FBTyxFQUFFLENBQUM7NEJBQzFDLElBQUksQ0FBQyxVQUFVLENBQUMsU0FBUyxFQUFFLENBQUM7Z0NBQzFCLE9BQU8sRUFBRSw0REFBNEQ7Z0NBQ3JFLElBQUksRUFBRSxRQUFROzZCQUNmLENBQUMsQ0FBQzs0QkFDSCxPQUFPO3dCQUNULENBQUM7b0JBQ0gsQ0FBQztnQkFDSCxDQUFDO2dCQUVELElBQUksSUFBSSxDQUFDLGNBQWMsSUFBSSxJQUFJLENBQUMsYUFBYSxJQUFJLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztvQkFDdEUsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDO29CQUMxQyxJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO29CQUM3QyxJQUFJLENBQUMsV0FBVyxHQUFHLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxhQUFhLENBQUMsY0FBYyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztvQkFDckUsSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztnQkFDM0MsQ0FBQztxQkFBTSxDQUFDO29CQUNOLElBQUksSUFBSSxDQUFDLGdCQUFnQixFQUFFLGNBQWMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsSUFBSSxNQUFNLEVBQUUsQ0FBQzt3QkFDcEUsSUFBSSxDQUFDLFdBQVcsR0FBRyxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsY0FBYyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQzt3QkFDeEUsSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztvQkFDM0MsQ0FBQzt5QkFBTSxDQUFDO3dCQUNOLElBQUksQ0FBQzs0QkFDSCxJQUFJLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxjQUFjLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLEtBQUssTUFBTSxFQUFFLENBQUM7Z0NBQ3JFLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxXQUFXLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLGNBQWMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0NBQzlFLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxRQUFRLENBQUMsSUFBSSxDQUFDLFlBQWEsQ0FBQyxjQUFjLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDOzRCQUNsRixDQUFDO3dCQUNILENBQUM7d0JBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQzs0QkFDZixPQUFPLENBQUMsR0FBRyxDQUFDLG9DQUFvQyxFQUFFLEtBQUssQ0FBQyxDQUFDO3dCQUMzRCxDQUFDO3dCQUVELElBQUksQ0FBQyxXQUFXLEdBQUcsRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLFlBQWEsQ0FBQyxjQUFjLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO3dCQUNyRSxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO29CQUMzQyxDQUFDO2dCQUNILENBQUM7Z0JBRUQsSUFBSSxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7b0JBQ3hCLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLENBQUM7b0JBQzlCLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsQ0FBQztnQkFDdkQsQ0FBQztxQkFBTSxDQUFDO29CQUNOLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxLQUFLLENBQUM7b0JBQy9CLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsQ0FBQztnQkFDdkQsQ0FBQztnQkFFRCxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO29CQUN0QyxNQUFNLElBQUksQ0FBQyxtQkFBbUIsQ0FBQzt3QkFDN0IsTUFBTSxFQUFFLE9BQU87d0JBQ2YsVUFBVSxFQUFFLEVBQUUsR0FBRyxJQUFJLENBQUMsVUFBVSxFQUFFLFdBQVcsRUFBRSxJQUFJLENBQUMsV0FBVyxFQUFFO3FCQUNsRSxDQUFDLENBQUM7Z0JBQ0wsQ0FBQztxQkFBTSxDQUFDO29CQUNOLElBQUksQ0FBQzt3QkFDSCxJQUNFLElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxFQUFFLEVBQUU7NEJBQ2pDLElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLEtBQUssRUFBRSxFQUFFLEtBQUssSUFBSSxDQUFDLFdBQVcsRUFBRSxLQUFLLEVBQUUsRUFBRSxFQUN2RSxDQUFDOzRCQUNELE1BQU0sSUFBSSxDQUFDLDRCQUE0QixDQUFDLEVBQUUsVUFBVSxFQUFFLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQUFDOzRCQUN6RSxNQUFNLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQzt3QkFDaEMsQ0FBQzt3QkFDRCxNQUFNLElBQUksQ0FBQyx5QkFBeUIsQ0FBQzs0QkFDbkMsV0FBVyxFQUFFLElBQUksQ0FBQyxXQUFXOzRCQUM3QixVQUFVLEVBQUUsSUFBSSxDQUFDLFVBQVU7eUJBQzVCLENBQUMsQ0FBQztvQkFDTCxDQUFDO29CQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7d0JBQ2YsT0FBTyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztvQkFDckIsQ0FBQztnQkFDSCxDQUFDO2dCQUNELE1BQU0sSUFBSSxDQUFDLGVBQWUsQ0FBQyxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQUFDO1lBQzdFLENBQUM7UUFDSCxDQUFDO1FBRUQsSUFBSSxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7WUFDeEIsSUFBSSxDQUFDLGlCQUFpQixHQUFHLElBQUksQ0FBQztZQUM5QixJQUFJLENBQUMsdUJBQXVCLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUM7UUFDdkQsQ0FBQzthQUFNLENBQUM7WUFDTixJQUFJLENBQUMsaUJBQWlCLEdBQUcsS0FBSyxDQUFDO1lBQy9CLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsQ0FBQztRQUN2RCxDQUFDO1FBRUQsSUFBSSxDQUFDLHVCQUF1QixDQUFDLGFBQWEsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ25FLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxhQUFhLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQztJQUM3RCxDQUFDLENBQUM7SUFFRixnQkFBZ0IsR0FBRyxHQUFHLEVBQUU7UUFDdEIsSUFBSSxDQUFDO1lBQ0gsMkVBQTJFO1lBQzNFLElBQ0UsQ0FBQyxJQUFJLENBQUMsaUJBQWlCO2dCQUN2QixDQUFDLElBQUksQ0FBQyxpQkFBaUIsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUM7Z0JBQ2hELENBQUMsSUFBSSxDQUFDLGlCQUFpQixJQUFJLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxFQUNoRCxDQUFDO2dCQUNELE9BQU8sQ0FBQyxHQUFHLENBQUMsZ0VBQWdFLENBQUMsQ0FBQztnQkFDOUUsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxhQUFhLENBQUM7Z0JBQ3BELElBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLENBQUM7Z0JBQzlCLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsQ0FBQztnQkFFckQsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztvQkFDekIsNERBQTREO29CQUM1RCxJQUFJLFFBQVEsSUFBSSxRQUFRLENBQUMsU0FBUyxFQUFFLENBQUM7d0JBQ25DLFFBQVEsQ0FBQyxTQUFTLENBQUMsU0FBUyxFQUFFLENBQUMsT0FBTyxDQUFDLENBQUMsS0FBVSxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQzt3QkFDckUsUUFBUSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUM7b0JBQzVCLENBQUM7b0JBRUQsMkJBQTJCO29CQUMzQixJQUFJLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQzt3QkFDdEIsSUFBSSxDQUFDLFlBQVksQ0FBQyxTQUFTLEVBQUUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxLQUFVLEVBQUUsRUFBRSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO3dCQUNwRSxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQzt3QkFDekIsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztvQkFDN0MsQ0FBQztvQkFFRCw0QkFBNEI7b0JBQzVCLElBQUksSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO3dCQUN2QixJQUFJLENBQUMsYUFBYSxDQUFDLFNBQVMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEtBQVUsRUFBRSxFQUFFLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7d0JBQ3JFLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDO3dCQUMxQixJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO29CQUMvQyxDQUFDO2dCQUNILENBQUM7WUFDSCxDQUFDO1lBRUQsNkNBQTZDO1lBQzdDLElBQUksQ0FBQyxlQUFlLENBQUMsYUFBYSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDM0QsSUFBSSxDQUFDLG1CQUFtQixDQUFDLGFBQWEsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBRWxFLGlCQUFpQjtZQUNqQiwwQkFBMEI7WUFDMUIsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ2pCLENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsT0FBTyxDQUFDLEdBQUcsQ0FBQywyQkFBMkIsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUNsRCxDQUFDO0lBQ0gsQ0FBQyxDQUFDO0lBRUYsV0FBVztRQUNULElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxhQUFhLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUNsRSxDQUFDO0lBRUQsV0FBVztRQUNULElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxhQUFhLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUMvRCxDQUFDO3VHQXp5QlUsZUFBZTsyRkFBZixlQUFlLDBsQ0MzRzVCLG1nR0E0QkEsK0hEMkVZLFlBQVksbUhBQUUsaUJBQWlCOzsyRkFJOUIsZUFBZTtrQkFQM0IsU0FBUzsrQkFDRSxzQkFBc0IsY0FDcEIsSUFBSSxXQUNQLENBQUMsWUFBWSxFQUFFLGlCQUFpQixDQUFDOzhCQUtqQyxTQUFTO3NCQUFqQixLQUFLO2dCQUNHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSztnQkFDRyxlQUFlO3NCQUF2QixLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSztnQkFJK0IseUJBQXlCO3NCQUE3RCxTQUFTO3VCQUFDLHdCQUF3QjtnQkFDSixtQkFBbUI7c0JBQWpELFNBQVM7dUJBQUMsa0JBQWtCO2dCQUNFLG1CQUFtQjtzQkFBakQsU0FBUzt1QkFBQyxrQkFBa0I7Z0JBQ0YsZUFBZTtzQkFBekMsU0FBUzt1QkFBQyxjQUFjO2dCQUNFLGVBQWU7c0JBQXpDLFNBQVM7dUJBQUMsY0FBYztnQkFDSSxpQkFBaUI7c0JBQTdDLFNBQVM7dUJBQUMsZ0JBQWdCO2dCQUNTLHdCQUF3QjtzQkFBM0QsU0FBUzt1QkFBQyx1QkFBdUI7Z0JBQ0MsdUJBQXVCO3NCQUF6RCxTQUFTO3VCQUFDLHNCQUFzQiIsInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby1ub24tbnVsbC1hc3NlcnRpb24gKi9cbmltcG9ydCB7XG4gIENvbXBvbmVudCxcbiAgSW5wdXQsXG4gIE9uQ2hhbmdlcyxcbiAgU2ltcGxlQ2hhbmdlcyxcbiAgVmlld0NoaWxkLFxuICBFbGVtZW50UmVmLFxuICBPbkluaXQsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IEZvbnRBd2Vzb21lTW9kdWxlIH0gZnJvbSAnQGZvcnRhd2Vzb21lL2FuZ3VsYXItZm9udGF3ZXNvbWUnO1xuaW1wb3J0IHsgZmFUaW1lcyB9IGZyb20gJ0Bmb3J0YXdlc29tZS9mcmVlLXNvbGlkLXN2Zy1pY29ucyc7XG5pbXBvcnQgeyBTZWxmaWVTZWdtZW50YXRpb24gfSBmcm9tICdAbWVkaWFwaXBlL3NlbGZpZV9zZWdtZW50YXRpb24nO1xuaW1wb3J0IHtcbiAgQ29ubmVjdFNlbmRUcmFuc3BvcnRWaWRlb1BhcmFtZXRlcnMsXG4gIENvbm5lY3RTZW5kVHJhbnNwb3J0VmlkZW9UeXBlLFxuICBDcmVhdGVTZW5kVHJhbnNwb3J0UGFyYW1ldGVycyxcbiAgQ3JlYXRlU2VuZFRyYW5zcG9ydFR5cGUsXG4gIERpc2Nvbm5lY3RTZW5kVHJhbnNwb3J0VmlkZW9QYXJhbWV0ZXJzLFxuICBEaXNjb25uZWN0U2VuZFRyYW5zcG9ydFZpZGVvVHlwZSxcbiAgT25TY3JlZW5DaGFuZ2VzUGFyYW1ldGVycyxcbiAgT25TY3JlZW5DaGFuZ2VzVHlwZSxcbiAgU2hvd0FsZXJ0LFxuICBTbGVlcFR5cGUsXG4gIFZpZENvbnMsXG59IGZyb20gJy4uLy4uLy4uL0B0eXBlcy90eXBlcyc7XG5pbXBvcnQgeyBQcm9kdWNlciwgUHJvZHVjZXJPcHRpb25zIH0gZnJvbSAnbWVkaWFzb3VwLWNsaWVudC9saWIvdHlwZXMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIEJhY2tncm91bmRNb2RhbFBhcmFtZXRlcnNcbiAgZXh0ZW5kcyBDcmVhdGVTZW5kVHJhbnNwb3J0UGFyYW1ldGVycyxcbiAgICBDb25uZWN0U2VuZFRyYW5zcG9ydFZpZGVvUGFyYW1ldGVycyxcbiAgICBEaXNjb25uZWN0U2VuZFRyYW5zcG9ydFZpZGVvUGFyYW1ldGVycyxcbiAgICBPblNjcmVlbkNoYW5nZXNQYXJhbWV0ZXJzIHtcbiAgY3VzdG9tSW1hZ2U6IHN0cmluZztcbiAgc2VsZWN0ZWRJbWFnZTogc3RyaW5nO1xuICBzZWdtZW50VmlkZW86IE1lZGlhU3RyZWFtIHwgbnVsbDtcbiAgc2VsZmllU2VnbWVudGF0aW9uOiBTZWxmaWVTZWdtZW50YXRpb24gfCBudWxsO1xuICBwYXVzZVNlZ21lbnRhdGlvbjogYm9vbGVhbjtcbiAgcHJvY2Vzc2VkU3RyZWFtOiBNZWRpYVN0cmVhbSB8IG51bGw7XG4gIGtlZXBCYWNrZ3JvdW5kOiBib29sZWFuO1xuICBiYWNrZ3JvdW5kSGFzQ2hhbmdlZDogYm9vbGVhbjtcbiAgdmlydHVhbFN0cmVhbTogTWVkaWFTdHJlYW0gfCBudWxsO1xuICBtYWluQ2FudmFzOiBIVE1MQ2FudmFzRWxlbWVudCB8IG51bGw7XG4gIHByZXZLZWVwQmFja2dyb3VuZDogYm9vbGVhbjtcbiAgYXBwbGllZEJhY2tncm91bmQ6IGJvb2xlYW47XG4gIHZpZGVvQWxyZWFkeU9uOiBib29sZWFuO1xuICBhdWRpb09ubHlSb29tOiBib29sZWFuO1xuICBpc2xldmVsOiBzdHJpbmc7XG4gIHJlY29yZFN0YXJ0ZWQ6IGJvb2xlYW47XG4gIHJlY29yZFJlc3VtZWQ6IGJvb2xlYW47XG4gIHJlY29yZFBhdXNlZDogYm9vbGVhbjtcbiAgcmVjb3JkU3RvcHBlZDogYm9vbGVhbjtcbiAgcmVjb3JkaW5nTWVkaWFPcHRpb25zOiBzdHJpbmc7XG4gIHNob3dBbGVydD86IFNob3dBbGVydDtcbiAgbG9jYWxTdHJlYW1WaWRlbzogTWVkaWFTdHJlYW0gfCBudWxsO1xuICB2aWRDb25zOiBWaWRDb25zO1xuICBmcmFtZVJhdGU6IG51bWJlcjtcbiAgdGFyZ2V0UmVzb2x1dGlvbjogc3RyaW5nO1xuICB1cGRhdGVDdXN0b21JbWFnZTogKGltYWdlOiBzdHJpbmcpID0+IHZvaWQ7XG4gIHVwZGF0ZVNlbGVjdGVkSW1hZ2U6IChpbWFnZTogc3RyaW5nKSA9PiB2b2lkO1xuICB1cGRhdGVTZWdtZW50VmlkZW86IChzdHJlYW06IE1lZGlhU3RyZWFtIHwgbnVsbCkgPT4gdm9pZDtcbiAgdXBkYXRlU2VsZmllU2VnbWVudGF0aW9uOiAoc2VnbWVudGF0aW9uOiBTZWxmaWVTZWdtZW50YXRpb24gfCBudWxsKSA9PiB2b2lkO1xuICB1cGRhdGVQYXVzZVNlZ21lbnRhdGlvbjogKHBhdXNlOiBib29sZWFuKSA9PiB2b2lkO1xuICB1cGRhdGVQcm9jZXNzZWRTdHJlYW06IChzdHJlYW06IE1lZGlhU3RyZWFtIHwgbnVsbCkgPT4gdm9pZDtcbiAgdXBkYXRlS2VlcEJhY2tncm91bmQ6IChrZWVwOiBib29sZWFuKSA9PiB2b2lkO1xuICB1cGRhdGVCYWNrZ3JvdW5kSGFzQ2hhbmdlZDogKGNoYW5nZWQ6IGJvb2xlYW4pID0+IHZvaWQ7XG4gIHVwZGF0ZVZpcnR1YWxTdHJlYW06IChzdHJlYW06IE1lZGlhU3RyZWFtIHwgbnVsbCkgPT4gdm9pZDtcbiAgdXBkYXRlUHJldktlZXBCYWNrZ3JvdW5kOiAocHJldjogYm9vbGVhbikgPT4gdm9pZDtcbiAgdXBkYXRlQXBwbGllZEJhY2tncm91bmQ6IChhcHBsaWVkOiBib29sZWFuKSA9PiB2b2lkO1xuICB2aWRlb1Byb2R1Y2VyOiBQcm9kdWNlciB8IG51bGw7XG4gIHRyYW5zcG9ydENyZWF0ZWQ6IGJvb2xlYW47XG4gIHZpZGVvUGFyYW1zOiBQcm9kdWNlck9wdGlvbnM7XG4gIHVwZGF0ZVZpZGVvUGFyYW1zOiAocGFyYW1zOiBQcm9kdWNlck9wdGlvbnMpID0+IHZvaWQ7XG4gIGF1dG9DbGlja0JhY2tncm91bmQ6IGJvb2xlYW47XG4gIHVwZGF0ZUF1dG9DbGlja0JhY2tncm91bmQ6IChhdXRvQ2xpY2s6IGJvb2xlYW4pID0+IHZvaWQ7XG4gIHVwZGF0ZU1haW5DYW52YXM6IChjYW52YXM6IEhUTUxDYW52YXNFbGVtZW50KSA9PiB2b2lkO1xuXG4gIC8vIG1lZGlhc2Z1IGZ1bmN0aW9uc1xuICBjcmVhdGVTZW5kVHJhbnNwb3J0OiBDcmVhdGVTZW5kVHJhbnNwb3J0VHlwZTtcbiAgY29ubmVjdFNlbmRUcmFuc3BvcnRWaWRlbzogQ29ubmVjdFNlbmRUcmFuc3BvcnRWaWRlb1R5cGU7XG4gIGRpc2Nvbm5lY3RTZW5kVHJhbnNwb3J0VmlkZW86IERpc2Nvbm5lY3RTZW5kVHJhbnNwb3J0VmlkZW9UeXBlO1xuICBvblNjcmVlbkNoYW5nZXM6IE9uU2NyZWVuQ2hhbmdlc1R5cGU7XG4gIHNsZWVwOiBTbGVlcFR5cGU7XG5cbiAgZ2V0VXBkYXRlZEFsbFBhcmFtczogKCkgPT4gQmFja2dyb3VuZE1vZGFsUGFyYW1ldGVycztcbiAgW2tleTogc3RyaW5nXTogYW55O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEJhY2tncm91bmRNb2RhbE9wdGlvbnMge1xuICBpc1Zpc2libGU6IGJvb2xlYW47XG4gIHBhcmFtZXRlcnM6IEJhY2tncm91bmRNb2RhbFBhcmFtZXRlcnM7XG4gIHBvc2l0aW9uOiBzdHJpbmc7XG4gIGJhY2tncm91bmRDb2xvcjogc3RyaW5nO1xuICBvbkNsb3NlOiAoKSA9PiB2b2lkO1xufVxuXG4vLyBleHBvcnQgdGhlIHR5cGUgZGVmaW5pdGlvbiBmb3IgdGhlIGNvbXBvbmVudFxuZXhwb3J0IHR5cGUgQmFja2dyb3VuZE1vZGFsVHlwZSA9IChvcHRpb25zOiBCYWNrZ3JvdW5kTW9kYWxPcHRpb25zKSA9PiBIVE1MRWxlbWVudDtcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnYXBwLWJhY2tncm91bmQtbW9kYWwnLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlLCBGb250QXdlc29tZU1vZHVsZV0sXG4gIHRlbXBsYXRlVXJsOiAnLi9iYWNrZ3JvdW5kLW1vZGFsLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vYmFja2dyb3VuZC1tb2RhbC5jb21wb25lbnQuY3NzJ10sXG59KVxuZXhwb3J0IGNsYXNzIEJhY2tncm91bmRNb2RhbCBpbXBsZW1lbnRzIE9uQ2hhbmdlcywgT25Jbml0IHtcbiAgQElucHV0KCkgaXNWaXNpYmxlID0gZmFsc2U7XG4gIEBJbnB1dCgpIHBhcmFtZXRlcnM6IEJhY2tncm91bmRNb2RhbFBhcmFtZXRlcnMgPSB7fSBhcyBCYWNrZ3JvdW5kTW9kYWxQYXJhbWV0ZXJzO1xuICBASW5wdXQoKSBwb3NpdGlvbiA9ICd0b3BMZWZ0JztcbiAgQElucHV0KCkgYmFja2dyb3VuZENvbG9yID0gJyNmNWY1ZjUnO1xuICBASW5wdXQoKSBvbkNsb3NlOiAoKSA9PiB2b2lkID0gKCkgPT4ge1xuICAgIGNvbnNvbGUubG9nKCdvbkNsb3NlJyk7XG4gIH07XG5cbiAgQFZpZXdDaGlsZCgnZGVmYXVsdEltYWdlc0NvbnRhaW5lcicpIGRlZmF1bHRJbWFnZXNDb250YWluZXJSZWYhOiBFbGVtZW50UmVmO1xuICBAVmlld0NoaWxkKCd1cGxvYWRJbWFnZUlucHV0JykgdXBsb2FkSW1hZ2VJbnB1dFJlZiE6IEVsZW1lbnRSZWY7XG4gIEBWaWV3Q2hpbGQoJ2JhY2tncm91bmRDYW52YXMnKSBiYWNrZ3JvdW5kQ2FudmFzUmVmITogRWxlbWVudFJlZjtcbiAgQFZpZXdDaGlsZCgndmlkZW9QcmV2aWV3JykgdmlkZW9QcmV2aWV3UmVmITogRWxlbWVudFJlZjtcbiAgQFZpZXdDaGlsZCgnY2FwdHVyZVZpZGVvJykgY2FwdHVyZVZpZGVvUmVmITogRWxlbWVudFJlZjtcbiAgQFZpZXdDaGlsZCgnbG9hZGluZ092ZXJsYXknKSBsb2FkaW5nT3ZlcmxheVJlZiE6IEVsZW1lbnRSZWY7XG4gIEBWaWV3Q2hpbGQoJ2FwcGx5QmFja2dyb3VuZEJ1dHRvbicpIGFwcGx5QmFja2dyb3VuZEJ1dHRvblJlZiE6IEVsZW1lbnRSZWY7XG4gIEBWaWV3Q2hpbGQoJ3NhdmVCYWNrZ3JvdW5kQnV0dG9uJykgc2F2ZUJhY2tncm91bmRCdXR0b25SZWYhOiBFbGVtZW50UmVmO1xuXG4gIGZhVGltZXMgPSBmYVRpbWVzO1xuXG4gIGN1c3RvbUltYWdlID0gJyc7XG4gIHNlbGVjdGVkSW1hZ2UgPSAnJztcbiAgc2VnbWVudFZpZGVvOiBNZWRpYVN0cmVhbSB8IG51bGwgPSBudWxsO1xuICBzZWxmaWVTZWdtZW50YXRpb246IFNlbGZpZVNlZ21lbnRhdGlvbiB8IG51bGwgPSBudWxsO1xuICBwYXVzZVNlZ21lbnRhdGlvbiA9IGZhbHNlO1xuICBwcm9jZXNzZWRTdHJlYW06IE1lZGlhU3RyZWFtIHwgbnVsbCA9IG51bGw7XG4gIGtlZXBCYWNrZ3JvdW5kID0gZmFsc2U7XG4gIGJhY2tncm91bmRIYXNDaGFuZ2VkID0gZmFsc2U7XG4gIHZpcnR1YWxTdHJlYW06IE1lZGlhU3RyZWFtIHwgbnVsbCA9IG51bGw7XG4gIG1haW5DYW52YXMhOiBIVE1MQ2FudmFzRWxlbWVudDtcbiAgcHJldktlZXBCYWNrZ3JvdW5kID0gZmFsc2U7XG4gIGFwcGxpZWRCYWNrZ3JvdW5kID0gZmFsc2U7XG4gIHZpZGVvQWxyZWFkeU9uID0gZmFsc2U7XG4gIGF1ZGlvT25seVJvb20gPSBmYWxzZTtcbiAgaXNsZXZlbCA9ICcwJztcbiAgcmVjb3JkU3RhcnRlZCA9IGZhbHNlO1xuICByZWNvcmRSZXN1bWVkID0gZmFsc2U7XG4gIHJlY29yZFBhdXNlZCA9IGZhbHNlO1xuICByZWNvcmRTdG9wcGVkID0gZmFsc2U7XG4gIHJlY29yZGluZ01lZGlhT3B0aW9ucyA9ICcnO1xuICB2aWRDb25zOiBhbnkgPSB7fTtcbiAgZnJhbWVSYXRlID0gNTtcbiAgdGFyZ2V0UmVzb2x1dGlvbiA9ICcxMjgweDcyMCc7XG4gIHZpZGVvUGFyYW1zOiBQcm9kdWNlck9wdGlvbnMgPSB7fTtcbiAgYXV0b0NsaWNrQmFja2dyb3VuZCA9IGZhbHNlO1xuICBsb2NhbFN0cmVhbVZpZGVvOiBNZWRpYVN0cmVhbSB8IG51bGwgPSBudWxsO1xuXG4gIGNsb25lZFN0cmVhbTogTWVkaWFTdHJlYW0gfCBudWxsID0gbnVsbDtcbiAgY2xvbmVkVHJhY2s6IE1lZGlhU3RyZWFtVHJhY2sgfCBudWxsID0gbnVsbDtcblxuICB1cGRhdGVDdXN0b21JbWFnZSE6ICh2YWx1ZTogc3RyaW5nKSA9PiB2b2lkO1xuICB1cGRhdGVTZWxlY3RlZEltYWdlITogKHZhbHVlOiBzdHJpbmcpID0+IHZvaWQ7XG4gIHVwZGF0ZVNlZ21lbnRWaWRlbyE6ICh2YWx1ZTogTWVkaWFTdHJlYW0gfCBudWxsKSA9PiB2b2lkO1xuICB1cGRhdGVTZWxmaWVTZWdtZW50YXRpb24hOiAodmFsdWU6IFNlbGZpZVNlZ21lbnRhdGlvbiB8IG51bGwpID0+IHZvaWQ7XG4gIHVwZGF0ZVBhdXNlU2VnbWVudGF0aW9uITogKHZhbHVlOiBib29sZWFuKSA9PiB2b2lkO1xuICB1cGRhdGVQcm9jZXNzZWRTdHJlYW0hOiAodmFsdWU6IE1lZGlhU3RyZWFtIHwgbnVsbCkgPT4gdm9pZDtcbiAgdXBkYXRlS2VlcEJhY2tncm91bmQhOiAodmFsdWU6IGJvb2xlYW4pID0+IHZvaWQ7XG4gIHVwZGF0ZUJhY2tncm91bmRIYXNDaGFuZ2VkITogKHZhbHVlOiBib29sZWFuKSA9PiB2b2lkO1xuICB1cGRhdGVWaXJ0dWFsU3RyZWFtITogKHZhbHVlOiBNZWRpYVN0cmVhbSB8IG51bGwpID0+IHZvaWQ7XG4gIHVwZGF0ZU1haW5DYW52YXMhOiAodmFsdWU6IEhUTUxDYW52YXNFbGVtZW50KSA9PiB2b2lkO1xuICB1cGRhdGVQcmV2S2VlcEJhY2tncm91bmQhOiAodmFsdWU6IGJvb2xlYW4pID0+IHZvaWQ7XG4gIHVwZGF0ZUFwcGxpZWRCYWNrZ3JvdW5kITogKHZhbHVlOiBib29sZWFuKSA9PiB2b2lkO1xuICB1cGRhdGVWaWRlb1BhcmFtcyE6ICh2YWx1ZTogUHJvZHVjZXJPcHRpb25zKSA9PiB2b2lkO1xuICB1cGRhdGVBdXRvQ2xpY2tCYWNrZ3JvdW5kITogKHZhbHVlOiBib29sZWFuKSA9PiB2b2lkO1xuXG4gIC8vIE1lZGlhIGZ1bmN0aW9uc1xuICBjcmVhdGVTZW5kVHJhbnNwb3J0ITogQ3JlYXRlU2VuZFRyYW5zcG9ydFR5cGU7XG4gIGNvbm5lY3RTZW5kVHJhbnNwb3J0VmlkZW8hOiBDb25uZWN0U2VuZFRyYW5zcG9ydFZpZGVvVHlwZTtcbiAgZGlzY29ubmVjdFNlbmRUcmFuc3BvcnRWaWRlbyE6IERpc2Nvbm5lY3RTZW5kVHJhbnNwb3J0VmlkZW9UeXBlO1xuICBvblNjcmVlbkNoYW5nZXMhOiBPblNjcmVlbkNoYW5nZXNUeXBlO1xuICBzbGVlcCE6IFNsZWVwVHlwZTtcblxuICBuZ09uSW5pdCgpIHtcbiAgICAvLyBJbml0aWFsaXplIGxvY2FsIHByb3BlcnRpZXMgZnJvbSB0aGUgcGFyYW1ldGVyc1xuICAgIGlmICh0aGlzLnBhcmFtZXRlcnMpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHRoaXMudXBkYXRlVmFyaWFibGVzKCk7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgLyogaGFuZGxlIGVycm9yICovXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcykge1xuICAgIGlmIChjaGFuZ2VzWydpc1Zpc2libGUnXSkge1xuICAgICAgdGhpcy5vblZpc2liaWxpdHlDaGFuZ2UoKTtcbiAgICB9XG5cbiAgICBpZiAoY2hhbmdlc1snYXV0b0NsaWNrQmFja2dyb3VuZCddKSB7XG4gICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgJ0F1dG8gY2xpY2sgYmFja2dyb3VuZCBjaGFuZ2VkOicsXG4gICAgICAgIHRoaXMuYXV0b0NsaWNrQmFja2dyb3VuZCxcbiAgICAgICAgY2hhbmdlc1snYXV0b0NsaWNrQmFja2dyb3VuZCddLFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICB1cGRhdGVWYXJpYWJsZXMoKSB7XG4gICAgdGhpcy5jdXN0b21JbWFnZSA9IHRoaXMucGFyYW1ldGVycy5jdXN0b21JbWFnZSB8fCAnJztcbiAgICB0aGlzLnNlbGVjdGVkSW1hZ2UgPSB0aGlzLnBhcmFtZXRlcnMuc2VsZWN0ZWRJbWFnZSB8fCAnJztcbiAgICB0aGlzLnNlZ21lbnRWaWRlbyA9IHRoaXMucGFyYW1ldGVycy5zZWdtZW50VmlkZW8gfHwgbnVsbDtcbiAgICB0aGlzLnNlbGZpZVNlZ21lbnRhdGlvbiA9IHRoaXMucGFyYW1ldGVycy5zZWxmaWVTZWdtZW50YXRpb24gfHwgbnVsbDtcbiAgICB0aGlzLnBhdXNlU2VnbWVudGF0aW9uID0gdGhpcy5wYXJhbWV0ZXJzLnBhdXNlU2VnbWVudGF0aW9uIHx8IGZhbHNlO1xuICAgIHRoaXMucHJvY2Vzc2VkU3RyZWFtID0gdGhpcy5wYXJhbWV0ZXJzLnByb2Nlc3NlZFN0cmVhbSB8fCBudWxsO1xuICAgIHRoaXMua2VlcEJhY2tncm91bmQgPSB0aGlzLnBhcmFtZXRlcnMua2VlcEJhY2tncm91bmQgfHwgZmFsc2U7XG4gICAgdGhpcy5iYWNrZ3JvdW5kSGFzQ2hhbmdlZCA9IHRoaXMucGFyYW1ldGVycy5iYWNrZ3JvdW5kSGFzQ2hhbmdlZCB8fCBmYWxzZTtcbiAgICB0aGlzLnZpcnR1YWxTdHJlYW0gPSB0aGlzLnBhcmFtZXRlcnMudmlydHVhbFN0cmVhbSB8fCBudWxsO1xuICAgIHRoaXMubWFpbkNhbnZhcyA9IHRoaXMucGFyYW1ldGVycy5tYWluQ2FudmFzIHx8IHRoaXMuYmFja2dyb3VuZENhbnZhc1JlZj8ubmF0aXZlRWxlbWVudCB8fCBudWxsO1xuICAgIHRoaXMucHJldktlZXBCYWNrZ3JvdW5kID0gdGhpcy5wYXJhbWV0ZXJzLnByZXZLZWVwQmFja2dyb3VuZCB8fCBmYWxzZTtcbiAgICB0aGlzLmFwcGxpZWRCYWNrZ3JvdW5kID0gdGhpcy5wYXJhbWV0ZXJzLmFwcGxpZWRCYWNrZ3JvdW5kIHx8IGZhbHNlO1xuICAgIHRoaXMudmlkZW9BbHJlYWR5T24gPSB0aGlzLnBhcmFtZXRlcnMudmlkZW9BbHJlYWR5T24gfHwgZmFsc2U7XG4gICAgdGhpcy5hdWRpb09ubHlSb29tID0gdGhpcy5wYXJhbWV0ZXJzLmF1ZGlvT25seVJvb20gfHwgZmFsc2U7XG4gICAgdGhpcy5pc2xldmVsID0gdGhpcy5wYXJhbWV0ZXJzLmlzbGV2ZWwgfHwgJzAnO1xuICAgIHRoaXMucmVjb3JkU3RhcnRlZCA9IHRoaXMucGFyYW1ldGVycy5yZWNvcmRTdGFydGVkIHx8IGZhbHNlO1xuICAgIHRoaXMucmVjb3JkUmVzdW1lZCA9IHRoaXMucGFyYW1ldGVycy5yZWNvcmRSZXN1bWVkIHx8IGZhbHNlO1xuICAgIHRoaXMucmVjb3JkUGF1c2VkID0gdGhpcy5wYXJhbWV0ZXJzLnJlY29yZFBhdXNlZCB8fCBmYWxzZTtcbiAgICB0aGlzLnJlY29yZFN0b3BwZWQgPSB0aGlzLnBhcmFtZXRlcnMucmVjb3JkU3RvcHBlZCB8fCBmYWxzZTtcbiAgICB0aGlzLnJlY29yZGluZ01lZGlhT3B0aW9ucyA9IHRoaXMucGFyYW1ldGVycy5yZWNvcmRpbmdNZWRpYU9wdGlvbnMgfHwgJyc7XG4gICAgdGhpcy52aWRDb25zID0gdGhpcy5wYXJhbWV0ZXJzLnZpZENvbnMgfHwge307XG4gICAgdGhpcy5mcmFtZVJhdGUgPSB0aGlzLnBhcmFtZXRlcnMuZnJhbWVSYXRlIHx8IDU7XG4gICAgdGhpcy52aWRlb1BhcmFtcyA9IHRoaXMucGFyYW1ldGVycy52aWRlb1BhcmFtcyB8fCBudWxsO1xuICAgIHRoaXMuYXV0b0NsaWNrQmFja2dyb3VuZCA9IHRoaXMucGFyYW1ldGVycy5hdXRvQ2xpY2tCYWNrZ3JvdW5kIHx8IGZhbHNlO1xuICAgIHRoaXMubG9jYWxTdHJlYW1WaWRlbyA9IHRoaXMucGFyYW1ldGVycy5sb2NhbFN0cmVhbVZpZGVvIHx8IG51bGw7XG5cbiAgICAvLyBBc3NpZ24gbWV0aG9kIHJlZmVyZW5jZXNcbiAgICB0aGlzLnVwZGF0ZUN1c3RvbUltYWdlID0gdGhpcy5wYXJhbWV0ZXJzLnVwZGF0ZUN1c3RvbUltYWdlO1xuICAgIHRoaXMudXBkYXRlU2VsZWN0ZWRJbWFnZSA9IHRoaXMucGFyYW1ldGVycy51cGRhdGVTZWxlY3RlZEltYWdlO1xuICAgIHRoaXMudXBkYXRlU2VnbWVudFZpZGVvID0gdGhpcy5wYXJhbWV0ZXJzLnVwZGF0ZVNlZ21lbnRWaWRlbztcbiAgICB0aGlzLnVwZGF0ZVNlbGZpZVNlZ21lbnRhdGlvbiA9IHRoaXMucGFyYW1ldGVycy51cGRhdGVTZWxmaWVTZWdtZW50YXRpb247XG4gICAgdGhpcy51cGRhdGVQYXVzZVNlZ21lbnRhdGlvbiA9IHRoaXMucGFyYW1ldGVycy51cGRhdGVQYXVzZVNlZ21lbnRhdGlvbjtcbiAgICB0aGlzLnVwZGF0ZVByb2Nlc3NlZFN0cmVhbSA9IHRoaXMucGFyYW1ldGVycy51cGRhdGVQcm9jZXNzZWRTdHJlYW07XG4gICAgdGhpcy51cGRhdGVLZWVwQmFja2dyb3VuZCA9IHRoaXMucGFyYW1ldGVycy51cGRhdGVLZWVwQmFja2dyb3VuZDtcbiAgICB0aGlzLnVwZGF0ZUJhY2tncm91bmRIYXNDaGFuZ2VkID0gdGhpcy5wYXJhbWV0ZXJzLnVwZGF0ZUJhY2tncm91bmRIYXNDaGFuZ2VkO1xuICAgIHRoaXMudXBkYXRlVmlydHVhbFN0cmVhbSA9IHRoaXMucGFyYW1ldGVycy51cGRhdGVWaXJ0dWFsU3RyZWFtO1xuICAgIHRoaXMudXBkYXRlTWFpbkNhbnZhcyA9IHRoaXMucGFyYW1ldGVycy51cGRhdGVNYWluQ2FudmFzO1xuICAgIHRoaXMudXBkYXRlUHJldktlZXBCYWNrZ3JvdW5kID0gdGhpcy5wYXJhbWV0ZXJzLnVwZGF0ZVByZXZLZWVwQmFja2dyb3VuZDtcbiAgICB0aGlzLnVwZGF0ZUFwcGxpZWRCYWNrZ3JvdW5kID0gdGhpcy5wYXJhbWV0ZXJzLnVwZGF0ZUFwcGxpZWRCYWNrZ3JvdW5kO1xuICAgIHRoaXMudXBkYXRlVmlkZW9QYXJhbXMgPSB0aGlzLnBhcmFtZXRlcnMudXBkYXRlVmlkZW9QYXJhbXM7XG4gICAgdGhpcy51cGRhdGVBdXRvQ2xpY2tCYWNrZ3JvdW5kID0gdGhpcy5wYXJhbWV0ZXJzLnVwZGF0ZUF1dG9DbGlja0JhY2tncm91bmQ7XG5cbiAgICB0aGlzLmNyZWF0ZVNlbmRUcmFuc3BvcnQgPSB0aGlzLnBhcmFtZXRlcnMuY3JlYXRlU2VuZFRyYW5zcG9ydDtcbiAgICB0aGlzLmNvbm5lY3RTZW5kVHJhbnNwb3J0VmlkZW8gPSB0aGlzLnBhcmFtZXRlcnMuY29ubmVjdFNlbmRUcmFuc3BvcnRWaWRlbztcbiAgICB0aGlzLmRpc2Nvbm5lY3RTZW5kVHJhbnNwb3J0VmlkZW8gPSB0aGlzLnBhcmFtZXRlcnMuZGlzY29ubmVjdFNlbmRUcmFuc3BvcnRWaWRlbztcbiAgICB0aGlzLm9uU2NyZWVuQ2hhbmdlcyA9IHRoaXMucGFyYW1ldGVycy5vblNjcmVlbkNoYW5nZXM7XG4gICAgdGhpcy5zbGVlcCA9IHRoaXMucGFyYW1ldGVycy5zbGVlcDtcbiAgfVxuXG4gIG9uVmlzaWJpbGl0eUNoYW5nZSA9IGFzeW5jICgpID0+IHtcbiAgICBpZiAodGhpcy5wYXJhbWV0ZXJzKSB7XG4gICAgICB0aGlzLnBhcmFtZXRlcnMgPSB0aGlzLnBhcmFtZXRlcnMuZ2V0VXBkYXRlZEFsbFBhcmFtcygpO1xuICAgICAgdGhpcy51cGRhdGVWYXJpYWJsZXMoKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5pc1Zpc2libGUpIHtcbiAgICAgIGlmICghdGhpcy5zZWxmaWVTZWdtZW50YXRpb24pIHtcbiAgICAgICAgYXdhaXQgdGhpcy5wcmVsb2FkTW9kZWwoKS5jYXRjaCgoKSA9PiBjb25zb2xlLmxvZygnRXJyb3IgcHJlbG9hZGluZyBtb2RlbDonKSk7XG4gICAgICB9XG4gICAgICB0aGlzLnJlbmRlckRlZmF1bHRJbWFnZXMoKTtcblxuICAgICAgaWYgKHRoaXMuc2VsZWN0ZWRJbWFnZSkge1xuICAgICAgICBhd2FpdCB0aGlzLmxvYWRJbWFnZVRvQ2FudmFzKHRoaXMuc2VsZWN0ZWRJbWFnZSwgdGhpcy5zZWxlY3RlZEltYWdlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuY2xlYXJDYW52YXMoKTtcbiAgICAgICAgdGhpcy5iYWNrZ3JvdW5kQ2FudmFzUmVmLm5hdGl2ZUVsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZSgnZC1ub25lJyk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuc2F2ZUJhY2tncm91bmRCdXR0b25SZWYubmF0aXZlRWxlbWVudC5jbGFzc0xpc3QuYWRkKCdkLW5vbmUnKTtcbiAgICAgIHRoaXMuc2F2ZUJhY2tncm91bmRCdXR0b25SZWYubmF0aXZlRWxlbWVudC5kaXNhYmxlZCA9IHRydWU7XG4gICAgICB0aGlzLmFwcGx5QmFja2dyb3VuZEJ1dHRvblJlZi5uYXRpdmVFbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoJ2Qtbm9uZScpO1xuICAgICAgdGhpcy5hcHBseUJhY2tncm91bmRCdXR0b25SZWYubmF0aXZlRWxlbWVudC5kaXNhYmxlZCA9IGZhbHNlO1xuXG4gICAgICBpZiAoXG4gICAgICAgIHRoaXMucHJvY2Vzc2VkU3RyZWFtICYmXG4gICAgICAgIHRoaXMucHJldktlZXBCYWNrZ3JvdW5kID09IHRoaXMua2VlcEJhY2tncm91bmQgJiZcbiAgICAgICAgdGhpcy5rZWVwQmFja2dyb3VuZCAmJlxuICAgICAgICB0aGlzLmFwcGxpZWRCYWNrZ3JvdW5kXG4gICAgICApIHtcbiAgICAgICAgdGhpcy5hcHBseUJhY2tncm91bmRCdXR0b25SZWYubmF0aXZlRWxlbWVudC5pbm5lclRleHQgPSAnQXBwbHkgQmFja2dyb3VuZCc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmFwcGx5QmFja2dyb3VuZEJ1dHRvblJlZi5uYXRpdmVFbGVtZW50LmlubmVyVGV4dCA9ICdQcmV2aWV3IEJhY2tncm91bmQnO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5hdXRvQ2xpY2tCYWNrZ3JvdW5kKSB7XG4gICAgICAgIGF3YWl0IHRoaXMuYXBwbHlCYWNrZ3JvdW5kKCk7XG4gICAgICAgIGF3YWl0IHRoaXMuc2F2ZUJhY2tncm91bmQoKTtcbiAgICAgICAgdGhpcy5hdXRvQ2xpY2tCYWNrZ3JvdW5kID0gZmFsc2U7XG4gICAgICAgIHRoaXMudXBkYXRlQXV0b0NsaWNrQmFja2dyb3VuZCh0aGlzLmF1dG9DbGlja0JhY2tncm91bmQpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0cnkge1xuICAgICAgICAvLyBJZiBubyBiYWNrZ3JvdW5kIGlzIGFwcGxpZWQgb3IgdGhlIGFwcGxpZWQgYmFja2dyb3VuZCBzaG91bGQgbm90IGJlIGtlcHRcbiAgICAgICAgaWYgKFxuICAgICAgICAgICF0aGlzLmFwcGxpZWRCYWNrZ3JvdW5kIHx8XG4gICAgICAgICAgKHRoaXMuYXBwbGllZEJhY2tncm91bmQgJiYgIXRoaXMua2VlcEJhY2tncm91bmQpIHx8XG4gICAgICAgICAgKHRoaXMuYXBwbGllZEJhY2tncm91bmQgJiYgIXRoaXMudmlkZW9BbHJlYWR5T24pXG4gICAgICAgICkge1xuICAgICAgICAgIGNvbnN0IHJlZlZpZGVvID0gdGhpcy5jYXB0dXJlVmlkZW9SZWYubmF0aXZlRWxlbWVudDtcbiAgICAgICAgICB0aGlzLnBhdXNlU2VnbWVudGF0aW9uID0gdHJ1ZTtcbiAgICAgICAgICB0aGlzLnVwZGF0ZVBhdXNlU2VnbWVudGF0aW9uKHRoaXMucGF1c2VTZWdtZW50YXRpb24pO1xuXG4gICAgICAgICAgaWYgKCF0aGlzLnZpZGVvQWxyZWFkeU9uKSB7XG4gICAgICAgICAgICAvLyBTdG9wIHZpZGVvIHRyYWNrcyBhbmQgY2xlYXIgdGhlIHZpZGVvIGVsZW1lbnQncyBzcmNPYmplY3RcbiAgICAgICAgICAgIGlmIChyZWZWaWRlbyAmJiByZWZWaWRlby5zcmNPYmplY3QpIHtcbiAgICAgICAgICAgICAgcmVmVmlkZW8uc3JjT2JqZWN0LmdldFRyYWNrcygpLmZvckVhY2goKHRyYWNrOiBhbnkpID0+IHRyYWNrLnN0b3AoKSk7XG4gICAgICAgICAgICAgIHJlZlZpZGVvLnNyY09iamVjdCA9IG51bGw7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFN0b3Agc2VnbWVudFZpZGVvIHRyYWNrc1xuICAgICAgICAgICAgaWYgKHRoaXMuc2VnbWVudFZpZGVvKSB7XG4gICAgICAgICAgICAgIHRoaXMuc2VnbWVudFZpZGVvLmdldFRyYWNrcygpLmZvckVhY2goKHRyYWNrOiBhbnkpID0+IHRyYWNrLnN0b3AoKSk7XG4gICAgICAgICAgICAgIHRoaXMuc2VnbWVudFZpZGVvID0gbnVsbDtcbiAgICAgICAgICAgICAgdGhpcy51cGRhdGVTZWdtZW50VmlkZW8odGhpcy5zZWdtZW50VmlkZW8pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBTdG9wIHZpcnR1YWxTdHJlYW0gdHJhY2tzXG4gICAgICAgICAgICBpZiAodGhpcy52aXJ0dWFsU3RyZWFtKSB7XG4gICAgICAgICAgICAgIHRoaXMudmlydHVhbFN0cmVhbS5nZXRUcmFja3MoKS5mb3JFYWNoKCh0cmFjazogYW55KSA9PiB0cmFjay5zdG9wKCkpO1xuICAgICAgICAgICAgICB0aGlzLnZpcnR1YWxTdHJlYW0gPSBudWxsO1xuICAgICAgICAgICAgICB0aGlzLnVwZGF0ZVZpcnR1YWxTdHJlYW0odGhpcy52aXJ0dWFsU3RyZWFtKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBIaWRlIHRoZSB2aWRlbyBwcmV2aWV3IGFuZCBzaG93IHRoZSBjYW52YXNcbiAgICAgICAgdGhpcy52aWRlb1ByZXZpZXdSZWYubmF0aXZlRWxlbWVudC5jbGFzc0xpc3QuYWRkKCdkLW5vbmUnKTtcbiAgICAgICAgdGhpcy5iYWNrZ3JvdW5kQ2FudmFzUmVmLm5hdGl2ZUVsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZSgnZC1ub25lJyk7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgLyogaGFuZGxlIGVycm9yICovXG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIGFzeW5jIHByZWxvYWRNb2RlbCgpIHtcbiAgICB0aGlzLnNlbGZpZVNlZ21lbnRhdGlvbiA9IG5ldyBTZWxmaWVTZWdtZW50YXRpb24oe1xuICAgICAgbG9jYXRlRmlsZTogKGZpbGUpID0+IGBodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL0BtZWRpYXBpcGUvc2VsZmllX3NlZ21lbnRhdGlvbi8ke2ZpbGV9YCxcbiAgICB9KTtcbiAgICB0aGlzLnNlbGZpZVNlZ21lbnRhdGlvbi5zZXRPcHRpb25zKHtcbiAgICAgIG1vZGVsU2VsZWN0aW9uOiAxLFxuICAgICAgc2VsZmllTW9kZTogZmFsc2UsXG4gICAgfSk7XG4gICAgYXdhaXQgdGhpcy5zZWxmaWVTZWdtZW50YXRpb24uaW5pdGlhbGl6ZSgpO1xuICAgIHRoaXMudXBkYXRlU2VsZmllU2VnbWVudGF0aW9uKHRoaXMuc2VsZmllU2VnbWVudGF0aW9uKTtcbiAgfVxuXG4gIHJlbmRlckRlZmF1bHRJbWFnZXMoKSB7XG4gICAgY29uc3QgZGVmYXVsdEltYWdlcyA9IFsnd2FsbCcsICd3YWxsMicsICdzaGVsZicsICdjbG9jaycsICdkZXNlcnQnLCAnZmxvd2VyJ107XG4gICAgY29uc3QgZGVmYXVsdEltYWdlc0NvbnRhaW5lciA9IHRoaXMuZGVmYXVsdEltYWdlc0NvbnRhaW5lclJlZi5uYXRpdmVFbGVtZW50O1xuICAgIGRlZmF1bHRJbWFnZXNDb250YWluZXIuaW5uZXJIVE1MID0gJyc7XG5cbiAgICBkZWZhdWx0SW1hZ2VzLmZvckVhY2goKGJhc2VOYW1lKSA9PiB7XG4gICAgICBjb25zdCB0aHVtYiA9IGBodHRwczovL21lZGlhc2Z1LmNvbS9pbWFnZXMvYmFja2dyb3VuZHMvJHtiYXNlTmFtZX1fdGh1bWJuYWlsLmpwZ2A7XG4gICAgICBjb25zdCBzbWFsbCA9IGBodHRwczovL21lZGlhc2Z1LmNvbS9pbWFnZXMvYmFja2dyb3VuZHMvJHtiYXNlTmFtZX1fc21hbGwuanBnYDtcbiAgICAgIGNvbnN0IGxhcmdlID0gYGh0dHBzOi8vbWVkaWFzZnUuY29tL2ltYWdlcy9iYWNrZ3JvdW5kcy8ke2Jhc2VOYW1lfV9sYXJnZS5qcGdgO1xuICAgICAgY29uc3QgZnVsbCA9IGBodHRwczovL21lZGlhc2Z1LmNvbS9pbWFnZXMvYmFja2dyb3VuZHMvJHtiYXNlTmFtZX0uanBnYDtcbiAgICAgIGNvbnN0IGltZyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2ltZycpO1xuICAgICAgaW1nLnNyYyA9IHRodW1iO1xuICAgICAgaW1nLmNsYXNzTGlzdC5hZGQoJ2ltZy10aHVtYm5haWwnLCAnbS0xJyk7XG4gICAgICBpbWcuc3R5bGUud2lkdGggPSAnODBweCc7XG4gICAgICBpbWcuc3R5bGUuY3Vyc29yID0gJ3BvaW50ZXInO1xuICAgICAgaW1nLmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgYXN5bmMgKCkgPT4ge1xuICAgICAgICBpZiAodGhpcy50YXJnZXRSZXNvbHV0aW9uID09ICdmaGQnIHx8IHRoaXMudGFyZ2V0UmVzb2x1dGlvbiA9PSAncWhkJykge1xuICAgICAgICAgIGF3YWl0IHRoaXMubG9hZEltYWdlVG9DYW52YXMoc21hbGwsIGxhcmdlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBhd2FpdCB0aGlzLmxvYWRJbWFnZVRvQ2FudmFzKHNtYWxsLCBmdWxsKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBkZWZhdWx0SW1hZ2VzQ29udGFpbmVyLmFwcGVuZENoaWxkKGltZyk7XG4gICAgfSk7XG5cbiAgICBjb25zdCBub0JhY2tncm91bmRJbWcgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICBub0JhY2tncm91bmRJbWcuY2xhc3NMaXN0LmFkZChcbiAgICAgICdpbWctdGh1bWJuYWlsJyxcbiAgICAgICdtLTEnLFxuICAgICAgJ2QtZmxleCcsXG4gICAgICAnYWxpZ24taXRlbXMtY2VudGVyJyxcbiAgICAgICdqdXN0aWZ5LWNvbnRlbnQtY2VudGVyJyxcbiAgICApO1xuICAgIG5vQmFja2dyb3VuZEltZy5zdHlsZS53aWR0aCA9ICc3NnB4JztcbiAgICBub0JhY2tncm91bmRJbWcuc3R5bGUubWluSGVpZ2h0ID0gJzYwcHgnO1xuICAgIG5vQmFja2dyb3VuZEltZy5zdHlsZS5jdXJzb3IgPSAncG9pbnRlcic7XG4gICAgbm9CYWNrZ3JvdW5kSW1nLnN0eWxlLmJhY2tncm91bmRDb2xvciA9ICcjZjhmOWZhJztcbiAgICBub0JhY2tncm91bmRJbWcuc3R5bGUuYm9yZGVyID0gJzFweCBzb2xpZCAjZGVlMmU2JztcbiAgICBub0JhY2tncm91bmRJbWcuc3R5bGUucG9zaXRpb24gPSAncmVsYXRpdmUnO1xuICAgIG5vQmFja2dyb3VuZEltZy5pbm5lckhUTUwgPVxuICAgICAgJzxzcGFuIHN0eWxlPVwicG9zaXRpb246YWJzb2x1dGU7IHRvcDo1MCU7IGxlZnQ6NTAlOyB0cmFuc2Zvcm06dHJhbnNsYXRlKC01MCUsIC01MCUpOyBjb2xvcjojMDAwO1wiPk5vbmU8L3NwYW4+JztcbiAgICBub0JhY2tncm91bmRJbWcuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBhc3luYyAoKSA9PiB7XG4gICAgICB0aGlzLnNlbGVjdGVkSW1hZ2UgPSAnJztcbiAgICAgIHRoaXMudXBkYXRlU2VsZWN0ZWRJbWFnZSh0aGlzLnNlbGVjdGVkSW1hZ2UpO1xuICAgICAgdGhpcy51cGRhdGVDdXN0b21JbWFnZSgnJyk7XG4gICAgICB0aGlzLnNob3dMb2FkaW5nKCk7XG4gICAgICB0aGlzLnZpZGVvUHJldmlld1JlZi5uYXRpdmVFbGVtZW50LmNsYXNzTGlzdC5hZGQoJ2Qtbm9uZScpO1xuICAgICAgdGhpcy5iYWNrZ3JvdW5kQ2FudmFzUmVmLm5hdGl2ZUVsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZSgnZC1ub25lJyk7XG4gICAgICB0aGlzLmNsZWFyQ2FudmFzKCk7XG4gICAgICB0aGlzLmhpZGVMb2FkaW5nKCk7XG4gICAgfSk7XG4gICAgZGVmYXVsdEltYWdlc0NvbnRhaW5lci5hcHBlbmRDaGlsZChub0JhY2tncm91bmRJbWcpO1xuXG4gICAgaWYgKHRoaXMuY3VzdG9tSW1hZ2UpIHtcbiAgICAgIGNvbnN0IGltZyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2ltZycpO1xuICAgICAgaW1nLnNyYyA9IHRoaXMuY3VzdG9tSW1hZ2U7XG4gICAgICBpbWcuY2xhc3NMaXN0LmFkZCgnaW1nLXRodW1ibmFpbCcsICdtLTEnKTtcbiAgICAgIGltZy5zdHlsZS53aWR0aCA9ICc4MHB4JztcbiAgICAgIGltZy5zdHlsZS5jdXJzb3IgPSAncG9pbnRlcic7XG4gICAgICBpbWcuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGF3YWl0IHRoaXMubG9hZEltYWdlVG9DYW52YXModGhpcy5jdXN0b21JbWFnZSwgdGhpcy5jdXN0b21JbWFnZSk7XG4gICAgICB9KTtcbiAgICAgIGRlZmF1bHRJbWFnZXNDb250YWluZXIuYXBwZW5kQ2hpbGQoaW1nKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBoYW5kbGVJbWFnZVVwbG9hZChldmVudDogRXZlbnQpIHtcbiAgICBsZXQgbWluV2lkdGggPSAxMjgwO1xuICAgIGxldCBtaW5IZWlnaHQgPSAxMjgwO1xuICAgIGxldCBtYXhXaWR0aCA9IDI1NjA7XG4gICAgbGV0IG1heEhlaWdodCA9IDI1NjA7XG5cbiAgICBpZiAodGhpcy50YXJnZXRSZXNvbHV0aW9uID09ICdmaGQnKSB7XG4gICAgICBtaW5XaWR0aCA9IDE5MjA7XG4gICAgICBtaW5IZWlnaHQgPSAxOTIwO1xuICAgIH0gZWxzZSBpZiAodGhpcy50YXJnZXRSZXNvbHV0aW9uID09ICdxaGQnKSB7XG4gICAgICBtaW5XaWR0aCA9IDI1NjA7XG4gICAgICBtaW5IZWlnaHQgPSAyNTYwO1xuICAgIH0gLy8gRm9yIG90aGVyIHJlc29sdXRpb25zLCBzdGljayB0byB0aGUgZGVmYXVsdCAxMjgweDEyODBcblxuICAgIGNvbnN0IGlucHV0ID0gZXZlbnQudGFyZ2V0IGFzIEhUTUxJbnB1dEVsZW1lbnQ7XG4gICAgaWYgKGlucHV0LmZpbGVzICYmIGlucHV0LmZpbGVzLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IGZpbGUgPSBpbnB1dC5maWxlc1swXTtcbiAgICAgIGNvbnN0IGltZyA9IG5ldyBJbWFnZSgpO1xuICAgICAgaW1nLmNyb3NzT3JpZ2luID0gJ2Fub255bW91cyc7XG4gICAgICBpbWcub25sb2FkID0gYXN5bmMgKCkgPT4ge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgaW1nLndpZHRoIDwgbWluV2lkdGggfHxcbiAgICAgICAgICBpbWcuaGVpZ2h0IDwgbWluSGVpZ2h0IHx8XG4gICAgICAgICAgaW1nLndpZHRoID4gbWF4V2lkdGggfHxcbiAgICAgICAgICBpbWcuaGVpZ2h0ID4gbWF4SGVpZ2h0XG4gICAgICAgICkge1xuICAgICAgICAgIHRoaXMuY3VzdG9tSW1hZ2UgPSBpbWcuc3JjO1xuICAgICAgICAgIHRoaXMudXBkYXRlQ3VzdG9tSW1hZ2UodGhpcy5jdXN0b21JbWFnZSk7XG4gICAgICAgICAgYXdhaXQgdGhpcy5sb2FkSW1hZ2VUb0NhbnZhcyhpbWcuc3JjLCBpbWcuc3JjKTtcbiAgICAgICAgfVxuICAgICAgfTtcbiAgICAgIGNvbnN0IHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7XG4gICAgICByZWFkZXIub25sb2FkID0gKGU6IFByb2dyZXNzRXZlbnQ8RmlsZVJlYWRlcj4pID0+IHtcbiAgICAgICAgaWYgKGUudGFyZ2V0KSB7XG4gICAgICAgICAgaW1nLnNyYyA9IGUudGFyZ2V0LnJlc3VsdCBhcyBzdHJpbmc7XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgICByZWFkZXIucmVhZEFzRGF0YVVSTChmaWxlKTtcbiAgICB9XG4gIH1cblxuICBjbGVhckNhbnZhcygpIHtcbiAgICBjb25zdCBjdHggPSB0aGlzLmJhY2tncm91bmRDYW52YXNSZWYubmF0aXZlRWxlbWVudC5nZXRDb250ZXh0KCcyZCcpO1xuICAgIGN0eC5jbGVhclJlY3QoXG4gICAgICAwLFxuICAgICAgMCxcbiAgICAgIHRoaXMuYmFja2dyb3VuZENhbnZhc1JlZi5uYXRpdmVFbGVtZW50LndpZHRoLFxuICAgICAgdGhpcy5iYWNrZ3JvdW5kQ2FudmFzUmVmLm5hdGl2ZUVsZW1lbnQuaGVpZ2h0LFxuICAgICk7XG4gICAgY3R4LmZvbnQgPSAnMzBweCBBcmlhbCc7XG4gICAgY3R4LmZpbGxTdHlsZSA9ICcjMDAwJztcbiAgICBjdHgudGV4dEFsaWduID0gJ2NlbnRlcic7XG4gICAgY3R4LnRleHRCYXNlbGluZSA9ICdtaWRkbGUnO1xuICAgIGN0eC5maWxsVGV4dChcbiAgICAgICdObyBCYWNrZ3JvdW5kJyxcbiAgICAgIHRoaXMuYmFja2dyb3VuZENhbnZhc1JlZi5uYXRpdmVFbGVtZW50LndpZHRoIC8gMixcbiAgICAgIHRoaXMuYmFja2dyb3VuZENhbnZhc1JlZi5uYXRpdmVFbGVtZW50LmhlaWdodCAvIDIsXG4gICAgKTtcblxuICAgIHRoaXMuYXBwbHlCYWNrZ3JvdW5kQnV0dG9uUmVmLm5hdGl2ZUVsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZSgnZC1ub25lJyk7XG4gICAgdGhpcy5hcHBseUJhY2tncm91bmRCdXR0b25SZWYubmF0aXZlRWxlbWVudC5kaXNhYmxlZCA9IGZhbHNlO1xuXG4gICAgaWYgKFxuICAgICAgdGhpcy5wcm9jZXNzZWRTdHJlYW0gJiZcbiAgICAgIHRoaXMucHJldktlZXBCYWNrZ3JvdW5kID09IHRoaXMua2VlcEJhY2tncm91bmQgJiZcbiAgICAgIHRoaXMua2VlcEJhY2tncm91bmQgJiZcbiAgICAgIHRoaXMuYXBwbGllZEJhY2tncm91bmRcbiAgICApIHtcbiAgICAgIHRoaXMuYXBwbHlCYWNrZ3JvdW5kQnV0dG9uUmVmLm5hdGl2ZUVsZW1lbnQuaW5uZXJUZXh0ID0gJ0FwcGx5IEJhY2tncm91bmQnO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmFwcGx5QmFja2dyb3VuZEJ1dHRvblJlZi5uYXRpdmVFbGVtZW50LmlubmVyVGV4dCA9ICdQcmV2aWV3IEJhY2tncm91bmQnO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGxvYWRJbWFnZVRvQ2FudmFzKHNyYzogc3RyaW5nLCBmdWxsU3JjOiBzdHJpbmcpIHtcbiAgICB0aGlzLnNob3dMb2FkaW5nKCk7XG4gICAgYXdhaXQgdGhpcy5iYWNrZ3JvdW5kQ2FudmFzUmVmLm5hdGl2ZUVsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZSgnZC1ub25lJyk7XG4gICAgYXdhaXQgdGhpcy52aWRlb1ByZXZpZXdSZWYubmF0aXZlRWxlbWVudC5jbGFzc0xpc3QuYWRkKCdkLW5vbmUnKTtcblxuICAgIGNvbnN0IGltZyA9IG5ldyBJbWFnZSgpO1xuICAgIGltZy5jcm9zc09yaWdpbiA9ICdhbm9ueW1vdXMnO1xuICAgIGltZy5vbmxvYWQgPSBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCBjdHggPSBhd2FpdCB0aGlzLmJhY2tncm91bmRDYW52YXNSZWYubmF0aXZlRWxlbWVudC5nZXRDb250ZXh0KCcyZCcpO1xuICAgICAgdGhpcy5iYWNrZ3JvdW5kQ2FudmFzUmVmLm5hdGl2ZUVsZW1lbnQud2lkdGggPSBpbWcud2lkdGg7XG4gICAgICB0aGlzLmJhY2tncm91bmRDYW52YXNSZWYubmF0aXZlRWxlbWVudC5oZWlnaHQgPSBpbWcuaGVpZ2h0O1xuICAgICAgYXdhaXQgY3R4LmRyYXdJbWFnZShpbWcsIDAsIDApO1xuICAgICAgdGhpcy5yZW1vdmVCYWNrZ3JvdW5kKGltZyk7XG4gICAgICB0aGlzLmhpZGVMb2FkaW5nKCk7XG4gICAgfTtcbiAgICBpbWcuc3JjID0gc3JjO1xuICAgIHRoaXMuc2VsZWN0ZWRJbWFnZSA9IGZ1bGxTcmM7XG4gICAgdGhpcy51cGRhdGVTZWxlY3RlZEltYWdlKHRoaXMuc2VsZWN0ZWRJbWFnZSk7XG5cbiAgICB0aGlzLnNhdmVCYWNrZ3JvdW5kQnV0dG9uUmVmLm5hdGl2ZUVsZW1lbnQuY2xhc3NMaXN0LmFkZCgnZC1ub25lJyk7XG4gICAgdGhpcy5zYXZlQmFja2dyb3VuZEJ1dHRvblJlZi5uYXRpdmVFbGVtZW50LmRpc2FibGVkID0gdHJ1ZTtcbiAgICB0aGlzLmFwcGx5QmFja2dyb3VuZEJ1dHRvblJlZi5uYXRpdmVFbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoJ2Qtbm9uZScpO1xuICAgIHRoaXMuYXBwbHlCYWNrZ3JvdW5kQnV0dG9uUmVmLm5hdGl2ZUVsZW1lbnQuZGlzYWJsZWQgPSBmYWxzZTtcblxuICAgIGlmIChcbiAgICAgIHRoaXMucHJvY2Vzc2VkU3RyZWFtICYmXG4gICAgICB0aGlzLnByZXZLZWVwQmFja2dyb3VuZCA9PSB0aGlzLmtlZXBCYWNrZ3JvdW5kICYmXG4gICAgICB0aGlzLmtlZXBCYWNrZ3JvdW5kICYmXG4gICAgICB0aGlzLmFwcGxpZWRCYWNrZ3JvdW5kXG4gICAgKSB7XG4gICAgICB0aGlzLmFwcGx5QmFja2dyb3VuZEJ1dHRvblJlZi5uYXRpdmVFbGVtZW50LmlubmVyVGV4dCA9ICdBcHBseSBCYWNrZ3JvdW5kJztcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5hcHBseUJhY2tncm91bmRCdXR0b25SZWYubmF0aXZlRWxlbWVudC5pbm5lclRleHQgPSAnUHJldmlldyBCYWNrZ3JvdW5kJztcbiAgICB9XG4gIH1cblxuICByZW1vdmVCYWNrZ3JvdW5kKGltZzogSFRNTEltYWdlRWxlbWVudCkge1xuICAgIGNvbnN0IGN0eCA9IHRoaXMuYmFja2dyb3VuZENhbnZhc1JlZi5uYXRpdmVFbGVtZW50LmdldENvbnRleHQoJzJkJyk7XG4gICAgY3R4LmNsZWFyUmVjdChcbiAgICAgIDAsXG4gICAgICAwLFxuICAgICAgdGhpcy5iYWNrZ3JvdW5kQ2FudmFzUmVmLm5hdGl2ZUVsZW1lbnQud2lkdGgsXG4gICAgICB0aGlzLmJhY2tncm91bmRDYW52YXNSZWYubmF0aXZlRWxlbWVudC5oZWlnaHQsXG4gICAgKTtcbiAgICBjdHguZHJhd0ltYWdlKGltZywgMCwgMCk7XG4gIH1cblxuICBhc3luYyBhcHBseUJhY2tncm91bmQoKSB7XG4gICAgdHJ5IHtcbiAgICAgIGlmICh0aGlzLmF1ZGlvT25seVJvb20pIHtcbiAgICAgICAgdGhpcy5wYXJhbWV0ZXJzLnNob3dBbGVydD8uKHtcbiAgICAgICAgICBtZXNzYWdlOiAnWW91IGNhbm5vdCB1c2UgYSBiYWNrZ3JvdW5kIGluIGFuIGF1ZGlvIG9ubHkgZXZlbnQuJyxcbiAgICAgICAgICB0eXBlOiAnZGFuZ2VyJyxcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdGhpcy5zaG93TG9hZGluZygpO1xuXG4gICAgICB0aGlzLnZpZGVvUHJldmlld1JlZi5uYXRpdmVFbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoJ2Qtbm9uZScpO1xuICAgICAgdGhpcy5iYWNrZ3JvdW5kQ2FudmFzUmVmLm5hdGl2ZUVsZW1lbnQuY2xhc3NMaXN0LmFkZCgnZC1ub25lJyk7XG5cbiAgICAgIGNvbnN0IGRvU2VnbWVudGF0aW9uID0gdGhpcy5zZWxlY3RlZEltYWdlID8gdHJ1ZSA6IGZhbHNlO1xuICAgICAgdGhpcy5wYXVzZVNlZ21lbnRhdGlvbiA9IGZhbHNlO1xuICAgICAgdGhpcy51cGRhdGVQYXVzZVNlZ21lbnRhdGlvbih0aGlzLnBhdXNlU2VnbWVudGF0aW9uKTtcbiAgICAgIGF3YWl0IHRoaXMuc2VsZmllU2VnbWVudGF0aW9uUHJldmlldyhkb1NlZ21lbnRhdGlvbik7XG5cbiAgICAgIHRoaXMuaGlkZUxvYWRpbmcoKTtcblxuICAgICAgdGhpcy5hcHBseUJhY2tncm91bmRCdXR0b25SZWYubmF0aXZlRWxlbWVudC5jbGFzc0xpc3QuYWRkKCdkLW5vbmUnKTtcbiAgICAgIHRoaXMuYXBwbHlCYWNrZ3JvdW5kQnV0dG9uUmVmLm5hdGl2ZUVsZW1lbnQuZGlzYWJsZWQgPSB0cnVlO1xuXG4gICAgICBpZiAoXG4gICAgICAgIHRoaXMucHJvY2Vzc2VkU3RyZWFtICYmXG4gICAgICAgIHRoaXMucHJldktlZXBCYWNrZ3JvdW5kID09IHRoaXMua2VlcEJhY2tncm91bmQgJiZcbiAgICAgICAgdGhpcy5rZWVwQmFja2dyb3VuZCAmJlxuICAgICAgICB0aGlzLmFwcGxpZWRCYWNrZ3JvdW5kXG4gICAgICApIHtcbiAgICAgICAgdGhpcy5zYXZlQmFja2dyb3VuZEJ1dHRvblJlZi5uYXRpdmVFbGVtZW50LmNsYXNzTGlzdC5hZGQoJ2Qtbm9uZScpO1xuICAgICAgICB0aGlzLnNhdmVCYWNrZ3JvdW5kQnV0dG9uUmVmLm5hdGl2ZUVsZW1lbnQuZGlzYWJsZWQgPSB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5zYXZlQmFja2dyb3VuZEJ1dHRvblJlZi5uYXRpdmVFbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoJ2Qtbm9uZScpO1xuICAgICAgICB0aGlzLnNhdmVCYWNrZ3JvdW5kQnV0dG9uUmVmLm5hdGl2ZUVsZW1lbnQuZGlzYWJsZWQgPSBmYWxzZTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc29sZS5sb2coZXJyb3IpO1xuICAgIH1cbiAgfVxuXG4gIGFzeW5jIHNlbGZpZVNlZ21lbnRhdGlvblByZXZpZXcoZG9TZWdtZW50YXRpb246IGJvb2xlYW4pIHtcbiAgICBjb25zdCByZWZWaWRlbyA9IHRoaXMuY2FwdHVyZVZpZGVvUmVmLm5hdGl2ZUVsZW1lbnQ7XG4gICAgY29uc3QgcHJldmlld1ZpZGVvID0gdGhpcy52aWRlb1ByZXZpZXdSZWYubmF0aXZlRWxlbWVudDtcbiAgICBjb25zdCB2aXJ0dWFsSW1hZ2UgPSBuZXcgSW1hZ2UoKTtcbiAgICB2aXJ0dWFsSW1hZ2UuY3Jvc3NPcmlnaW4gPSAnYW5vbnltb3VzJztcbiAgICB2aXJ0dWFsSW1hZ2Uuc3JjID0gdGhpcy5zZWxlY3RlZEltYWdlO1xuXG4gICAgaWYgKCF0aGlzLm1haW5DYW52YXMpIHtcbiAgICAgIHRoaXMubWFpbkNhbnZhcyA9IGF3YWl0IHRoaXMuYmFja2dyb3VuZENhbnZhc1JlZi5uYXRpdmVFbGVtZW50O1xuICAgIH1cblxuICAgIGxldCBtZWRpYUNhbnZhcyA9IHRoaXMubWFpbkNhbnZhcztcbiAgICBtZWRpYUNhbnZhcy53aWR0aCA9IHJlZlZpZGVvLnZpZGVvV2lkdGg7XG4gICAgbWVkaWFDYW52YXMuaGVpZ2h0ID0gcmVmVmlkZW8udmlkZW9IZWlnaHQ7XG4gICAgbGV0IGN0eCA9IG1lZGlhQ2FudmFzLmdldENvbnRleHQoJzJkJyk7XG5cbiAgICB0aGlzLmJhY2tncm91bmRIYXNDaGFuZ2VkID0gdHJ1ZTtcbiAgICB0aGlzLnVwZGF0ZUJhY2tncm91bmRIYXNDaGFuZ2VkKHRoaXMuYmFja2dyb3VuZEhhc0NoYW5nZWQpO1xuICAgIHRoaXMucHJldktlZXBCYWNrZ3JvdW5kID0gdGhpcy5rZWVwQmFja2dyb3VuZDtcbiAgICB0aGlzLnVwZGF0ZVByZXZLZWVwQmFja2dyb3VuZCh0aGlzLmtlZXBCYWNrZ3JvdW5kKTtcblxuICAgIGlmICghZG9TZWdtZW50YXRpb24pIHtcbiAgICAgIGNvbnN0IHRyYWNrcyA9IHRoaXMucHJvY2Vzc2VkU3RyZWFtPy5nZXRWaWRlb1RyYWNrcygpO1xuICAgICAgaWYgKHRyYWNrcykge1xuICAgICAgICB0cmFja3MuZm9yRWFjaCgodHJhY2s6IE1lZGlhU3RyZWFtVHJhY2spID0+IHRyYWNrLnN0b3AoKSk7XG4gICAgICB9XG4gICAgICB0aGlzLnByb2Nlc3NlZFN0cmVhbSA9IG51bGw7XG4gICAgICB0aGlzLmtlZXBCYWNrZ3JvdW5kID0gZmFsc2U7XG4gICAgICB0aGlzLnVwZGF0ZVByb2Nlc3NlZFN0cmVhbShudWxsKTtcbiAgICAgIHRoaXMudXBkYXRlS2VlcEJhY2tncm91bmQoZmFsc2UpO1xuICAgICAgcHJldmlld1ZpZGVvLmNsYXNzTGlzdC5yZW1vdmUoJ2Qtbm9uZScpO1xuICAgIH1cblxuICAgIGNvbnN0IHNlZ21lbnRJbWFnZSA9IGFzeW5jICh2aWRlb0VsZW1lbnQ6IEhUTUxWaWRlb0VsZW1lbnQpID0+IHtcbiAgICAgIGNvbnN0IHByb2Nlc3NGcmFtZSA9ICgpID0+IHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgICF0aGlzLnNlbGZpZVNlZ21lbnRhdGlvbiB8fFxuICAgICAgICAgIHRoaXMucGF1c2VTZWdtZW50YXRpb24gfHxcbiAgICAgICAgICAhdmlkZW9FbGVtZW50IHx8XG4gICAgICAgICAgdmlkZW9FbGVtZW50LnZpZGVvV2lkdGggPT0gMCB8fFxuICAgICAgICAgIHZpZGVvRWxlbWVudC52aWRlb0hlaWdodCA9PSAwXG4gICAgICAgICkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNlbGZpZVNlZ21lbnRhdGlvbi5zZW5kKHsgaW1hZ2U6IHZpZGVvRWxlbWVudCB9KTtcbiAgICAgICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKHByb2Nlc3NGcmFtZSk7XG4gICAgICB9O1xuXG4gICAgICB2aWRlb0VsZW1lbnQub25sb2FkZWRkYXRhID0gKCkgPT4ge1xuICAgICAgICBwcm9jZXNzRnJhbWUoKTtcbiAgICAgIH07XG5cbiAgICAgIHNldFRpbWVvdXQoYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zb2xlLmxvZygnQ2FwdHVyaW5nIHN0cmVhbTonLCB0aGlzLmZyYW1lUmF0ZSB8fCA1KTtcbiAgICAgICAgdGhpcy5wcm9jZXNzZWRTdHJlYW0gPSBtZWRpYUNhbnZhcy5jYXB0dXJlU3RyZWFtKHRoaXMuZnJhbWVSYXRlIHx8IDUpO1xuICAgICAgICB0aGlzLnVwZGF0ZVByb2Nlc3NlZFN0cmVhbSh0aGlzLnByb2Nlc3NlZFN0cmVhbSk7XG4gICAgICAgIHByZXZpZXdWaWRlby5zcmNPYmplY3QgPSB0aGlzLnByb2Nlc3NlZFN0cmVhbTtcbiAgICAgICAgcHJldmlld1ZpZGVvLmNsYXNzTGlzdC5yZW1vdmUoJ2Qtbm9uZScpO1xuICAgICAgICB0aGlzLmtlZXBCYWNrZ3JvdW5kID0gdHJ1ZTtcbiAgICAgICAgdGhpcy51cGRhdGVLZWVwQmFja2dyb3VuZCh0aGlzLmtlZXBCYWNrZ3JvdW5kKTtcblxuICAgICAgICBpZiAocHJldmlld1ZpZGVvLnBhdXNlZCkge1xuICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBwbGF5IHRoZSB2aWRlb1xuICAgICAgICAgICAgcHJldmlld1ZpZGVvLnBsYXkoKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgLyogaGFuZGxlIHN1Y2Nlc3MgKi9cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0gY2F0Y2gge1xuICAgICAgICAgICAgLyogaGFuZGxlIGVycm9yICovXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9LCAxMDApO1xuICAgIH07XG5cbiAgICBpZiAodGhpcy52aWRlb0FscmVhZHlPbikge1xuICAgICAgaWYgKFxuICAgICAgICB0aGlzLmNsb25lZFRyYWNrICYmXG4gICAgICAgIHRoaXMuY2xvbmVkVHJhY2sucmVhZHlTdGF0ZSA9PSAnbGl2ZScgJiZcbiAgICAgICAgdGhpcy5sb2NhbFN0cmVhbVZpZGVvPy5nZXRWaWRlb1RyYWNrcygpWzBdLmxhYmVsID09IHRoaXMuY2xvbmVkVHJhY2subGFiZWxcbiAgICAgICkge1xuICAgICAgICAvLyBVc2UgZXhpc3RpbmcgY2xvbmVkVHJhY2tcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IGxvY2FsVHJhY2tzID0gdGhpcy5sb2NhbFN0cmVhbVZpZGVvPy5nZXRWaWRlb1RyYWNrcygpWzBdO1xuICAgICAgICB0aGlzLmNsb25lZFRyYWNrID0gbG9jYWxUcmFja3MhLmNsb25lKCk7XG4gICAgICAgIHRoaXMuY2xvbmVkU3RyZWFtID0gbmV3IE1lZGlhU3RyZWFtKFt0aGlzLmNsb25lZFRyYWNrIV0pO1xuICAgICAgICB0aGlzLnNlZ21lbnRWaWRlbyA9IHRoaXMuY2xvbmVkU3RyZWFtO1xuICAgICAgfVxuICAgICAgdGhpcy51cGRhdGVTZWdtZW50VmlkZW8odGhpcy5zZWdtZW50VmlkZW8pO1xuICAgICAgcmVmVmlkZW8uc3JjT2JqZWN0ID0gdGhpcy5zZWdtZW50VmlkZW87XG4gICAgICBpZiAocmVmVmlkZW8ucGF1c2VkKSB7XG4gICAgICAgIHJlZlZpZGVvLnBsYXkoKTtcbiAgICAgIH1cblxuICAgICAgcmVmVmlkZW8ud2lkdGggPSB0aGlzLnNlZ21lbnRWaWRlbyEuZ2V0VmlkZW9UcmFja3MoKVswXS5nZXRTZXR0aW5ncygpLndpZHRoITtcbiAgICAgIHJlZlZpZGVvLmhlaWdodCA9IHRoaXMuc2VnbWVudFZpZGVvIS5nZXRWaWRlb1RyYWNrcygpWzBdLmdldFNldHRpbmdzKCkuaGVpZ2h0ITtcbiAgICAgIG1lZGlhQ2FudmFzLndpZHRoID0gcmVmVmlkZW8ud2lkdGg7XG4gICAgICBtZWRpYUNhbnZhcy5oZWlnaHQgPSByZWZWaWRlby5oZWlnaHQ7XG4gICAgICBjdHggPSBtZWRpYUNhbnZhcy5nZXRDb250ZXh0KCcyZCcpO1xuXG4gICAgICB0cnkge1xuICAgICAgICBkb1NlZ21lbnRhdGlvblxuICAgICAgICAgID8gYXdhaXQgc2VnbWVudEltYWdlKHJlZlZpZGVvKVxuICAgICAgICAgIDogKHByZXZpZXdWaWRlby5zcmNPYmplY3QgPSB0aGlzLmNsb25lZFN0cmVhbVxuICAgICAgICAgICAgICA/IHRoaXMuY2xvbmVkU3RyZWFtXG4gICAgICAgICAgICAgIDogdGhpcy5sb2NhbFN0cmVhbVZpZGVvISk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBjb25zb2xlLmxvZygnRXJyb3Igc2VnbWVudGluZyBpbWFnZTonLCBlcnJvcik7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh0aGlzLnNlZ21lbnRWaWRlbyAmJiB0aGlzLnNlZ21lbnRWaWRlby5nZXRWaWRlb1RyYWNrcygpWzBdLnJlYWR5U3RhdGUgPT0gJ2xpdmUnKSB7XG4gICAgICAgIC8vIFVzZSBleGlzdGluZyBzZWdtZW50VmlkZW9cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3Qgc3RyZWFtID0gYXdhaXQgbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5nZXRVc2VyTWVkaWEoe1xuICAgICAgICAgICAgdmlkZW86IHsgLi4udGhpcy52aWRDb25zLCBmcmFtZVJhdGU6IHsgaWRlYWw6IHRoaXMuZnJhbWVSYXRlIHx8IDUgfSB9LFxuICAgICAgICAgICAgYXVkaW86IGZhbHNlLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHRoaXMuc2VnbWVudFZpZGVvID0gc3RyZWFtO1xuICAgICAgICAgIHRoaXMudXBkYXRlU2VnbWVudFZpZGVvKHRoaXMuc2VnbWVudFZpZGVvKTtcbiAgICAgICAgICByZWZWaWRlby5zcmNPYmplY3QgPSB0aGlzLnNlZ21lbnRWaWRlbztcbiAgICAgICAgICBpZiAocmVmVmlkZW8ucGF1c2VkKSB7XG4gICAgICAgICAgICByZWZWaWRlby5wbGF5KCk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIGNvbnNvbGUubG9nKCdFcnJvciBnZXR0aW5nIHVzZXIgbWVkaWE6JywgZXJyb3IpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmVmVmlkZW8ud2lkdGggPSB0aGlzLnNlZ21lbnRWaWRlbyEuZ2V0VmlkZW9UcmFja3MoKVswXS5nZXRTZXR0aW5ncygpLndpZHRoITtcbiAgICAgICAgcmVmVmlkZW8uaGVpZ2h0ID0gdGhpcy5zZWdtZW50VmlkZW8hLmdldFZpZGVvVHJhY2tzKClbMF0uZ2V0U2V0dGluZ3MoKS5oZWlnaHQhO1xuICAgICAgICBtZWRpYUNhbnZhcy53aWR0aCA9IHJlZlZpZGVvLndpZHRoO1xuICAgICAgICBtZWRpYUNhbnZhcy5oZWlnaHQgPSByZWZWaWRlby5oZWlnaHQ7XG4gICAgICAgIGN0eCA9IG1lZGlhQ2FudmFzLmdldENvbnRleHQoJzJkJyk7XG4gICAgICB9XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIGRvU2VnbWVudGF0aW9uXG4gICAgICAgICAgPyBhd2FpdCBzZWdtZW50SW1hZ2UocmVmVmlkZW8pXG4gICAgICAgICAgOiAocHJldmlld1ZpZGVvLnNyY09iamVjdCA9IHJlZlZpZGVvLnNyY09iamVjdCk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBjb25zb2xlLmxvZyhlcnJvcik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgbGV0IHJlcGVhdFBhdHRlcm4gPSAnbm8tcmVwZWF0JztcbiAgICB0cnkge1xuICAgICAgaWYgKHZpcnR1YWxJbWFnZS53aWR0aCA8IG1lZGlhQ2FudmFzLndpZHRoIHx8IHZpcnR1YWxJbWFnZS5oZWlnaHQgPCBtZWRpYUNhbnZhcy5oZWlnaHQpIHtcbiAgICAgICAgcmVwZWF0UGF0dGVybiA9ICdyZXBlYXQnO1xuICAgICAgfVxuICAgIH0gY2F0Y2gge1xuICAgICAgLyogaGFuZGxlIGVycm9yICovXG4gICAgfVxuXG4gICAgY29uc3Qgb25SZXN1bHRzID0gKHJlc3VsdHM6IGFueSkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgICF0aGlzLnBhdXNlU2VnbWVudGF0aW9uICYmXG4gICAgICAgICAgbWVkaWFDYW52YXMgJiZcbiAgICAgICAgICBtZWRpYUNhbnZhcy53aWR0aCA+IDAgJiZcbiAgICAgICAgICBtZWRpYUNhbnZhcy5oZWlnaHQgPiAwICYmXG4gICAgICAgICAgdmlydHVhbEltYWdlLndpZHRoID4gMCAmJlxuICAgICAgICAgIHZpcnR1YWxJbWFnZS5oZWlnaHQgPiAwXG4gICAgICAgICkge1xuICAgICAgICAgIGN0eCEuY2xlYXJSZWN0KDAsIDAsIG1lZGlhQ2FudmFzLndpZHRoLCBtZWRpYUNhbnZhcy5oZWlnaHQpO1xuICAgICAgICAgIGN0eCEuZHJhd0ltYWdlKHJlc3VsdHMuc2VnbWVudGF0aW9uTWFzaywgMCwgMCwgbWVkaWFDYW52YXMud2lkdGgsIG1lZGlhQ2FudmFzLmhlaWdodCk7XG5cbiAgICAgICAgICBjdHghLmdsb2JhbENvbXBvc2l0ZU9wZXJhdGlvbiA9ICdzb3VyY2Utb3V0JztcbiAgICAgICAgICBjb25zdCBwYXQgPSBjdHghLmNyZWF0ZVBhdHRlcm4odmlydHVhbEltYWdlLCByZXBlYXRQYXR0ZXJuKTtcbiAgICAgICAgICBjdHghLmZpbGxTdHlsZSA9IHBhdCE7XG4gICAgICAgICAgY3R4IS5maWxsUmVjdCgwLCAwLCBtZWRpYUNhbnZhcy53aWR0aCwgbWVkaWFDYW52YXMuaGVpZ2h0KTtcblxuICAgICAgICAgIGN0eCEuZ2xvYmFsQ29tcG9zaXRlT3BlcmF0aW9uID0gJ2Rlc3RpbmF0aW9uLWF0b3AnO1xuICAgICAgICAgIGN0eCEuZHJhd0ltYWdlKHJlc3VsdHMuaW1hZ2UsIDAsIDAsIG1lZGlhQ2FudmFzLndpZHRoLCBtZWRpYUNhbnZhcy5oZWlnaHQpO1xuICAgICAgICB9XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBjb25zb2xlLmxvZygnRXJyb3IgcHJvY2Vzc2luZyByZXN1bHRzOicsIGVycm9yKTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgaWYgKCF0aGlzLnNlbGZpZVNlZ21lbnRhdGlvbikge1xuICAgICAgYXdhaXQgdGhpcy5wcmVsb2FkTW9kZWwoKS5jYXRjaCgoKSA9PiBjb25zb2xlLmxvZygnRXJyb3IgcHJlbG9hZGluZyBtb2RlbDonKSk7XG4gICAgfVxuXG4gICAgdHJ5IHtcbiAgICAgIHRoaXMuc2VsZmllU2VnbWVudGF0aW9uIS5vblJlc3VsdHMob25SZXN1bHRzKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc29sZS5sb2coZXJyb3IpO1xuICAgIH1cbiAgfVxuXG4gIHNhdmVCYWNrZ3JvdW5kID0gYXN5bmMgKCkgPT4ge1xuICAgIGlmICh0aGlzLmF1ZGlvT25seVJvb20pIHtcbiAgICAgIHRoaXMucGFyYW1ldGVycy5zaG93QWxlcnQ/Lih7XG4gICAgICAgIG1lc3NhZ2U6ICdZb3UgY2Fubm90IHVzZSBhIGJhY2tncm91bmQgaW4gYW4gYXVkaW8tb25seSBldmVudC4nLFxuICAgICAgICB0eXBlOiAnZGFuZ2VyJyxcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmJhY2tncm91bmRIYXNDaGFuZ2VkKSB7XG4gICAgICBpZiAodGhpcy52aWRlb0FscmVhZHlPbikge1xuICAgICAgICBpZiAodGhpcy5pc2xldmVsID09ICcyJyAmJiAodGhpcy5yZWNvcmRTdGFydGVkIHx8IHRoaXMucmVjb3JkUmVzdW1lZCkpIHtcbiAgICAgICAgICBpZiAoISh0aGlzLnJlY29yZFBhdXNlZCB8fCB0aGlzLnJlY29yZFN0b3BwZWQpKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5yZWNvcmRpbmdNZWRpYU9wdGlvbnMgPT0gJ3ZpZGVvJykge1xuICAgICAgICAgICAgICB0aGlzLnBhcmFtZXRlcnMuc2hvd0FsZXJ0Py4oe1xuICAgICAgICAgICAgICAgIG1lc3NhZ2U6ICdQbGVhc2UgcGF1c2UgdGhlIHJlY29yZGluZyBiZWZvcmUgY2hhbmdpbmcgdGhlIGJhY2tncm91bmQuJyxcbiAgICAgICAgICAgICAgICB0eXBlOiAnZGFuZ2VyJyxcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5rZWVwQmFja2dyb3VuZCAmJiB0aGlzLnNlbGVjdGVkSW1hZ2UgJiYgdGhpcy5wcm9jZXNzZWRTdHJlYW0pIHtcbiAgICAgICAgICB0aGlzLnZpcnR1YWxTdHJlYW0gPSB0aGlzLnByb2Nlc3NlZFN0cmVhbTtcbiAgICAgICAgICB0aGlzLnVwZGF0ZVZpcnR1YWxTdHJlYW0odGhpcy52aXJ0dWFsU3RyZWFtKTtcbiAgICAgICAgICB0aGlzLnZpZGVvUGFyYW1zID0geyB0cmFjazogdGhpcy52aXJ0dWFsU3RyZWFtLmdldFZpZGVvVHJhY2tzKClbMF0gfTtcbiAgICAgICAgICB0aGlzLnVwZGF0ZVZpZGVvUGFyYW1zKHRoaXMudmlkZW9QYXJhbXMpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmICh0aGlzLmxvY2FsU3RyZWFtVmlkZW8/LmdldFZpZGVvVHJhY2tzKClbMF0ucmVhZHlTdGF0ZSA9PSAnbGl2ZScpIHtcbiAgICAgICAgICAgIHRoaXMudmlkZW9QYXJhbXMgPSB7IHRyYWNrOiB0aGlzLmxvY2FsU3RyZWFtVmlkZW8uZ2V0VmlkZW9UcmFja3MoKVswXSB9O1xuICAgICAgICAgICAgdGhpcy51cGRhdGVWaWRlb1BhcmFtcyh0aGlzLnZpZGVvUGFyYW1zKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgaWYgKHRoaXMubG9jYWxTdHJlYW1WaWRlbz8uZ2V0VmlkZW9UcmFja3MoKVswXS5yZWFkeVN0YXRlICE9PSAnbGl2ZScpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmxvY2FsU3RyZWFtVmlkZW8/LnJlbW92ZVRyYWNrKHRoaXMubG9jYWxTdHJlYW1WaWRlby5nZXRWaWRlb1RyYWNrcygpWzBdKTtcbiAgICAgICAgICAgICAgICB0aGlzLmxvY2FsU3RyZWFtVmlkZW8/LmFkZFRyYWNrKHRoaXMuc2VnbWVudFZpZGVvIS5nZXRWaWRlb1RyYWNrcygpWzBdLmNsb25lKCkpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICBjb25zb2xlLmxvZygnRXJyb3IgaGFuZGxpbmcgbG9jYWwgc3RyZWFtIHZpZGVvOicsIGVycm9yKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy52aWRlb1BhcmFtcyA9IHsgdHJhY2s6IHRoaXMuc2VnbWVudFZpZGVvIS5nZXRWaWRlb1RyYWNrcygpWzBdIH07XG4gICAgICAgICAgICB0aGlzLnVwZGF0ZVZpZGVvUGFyYW1zKHRoaXMudmlkZW9QYXJhbXMpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmtlZXBCYWNrZ3JvdW5kKSB7XG4gICAgICAgICAgdGhpcy5hcHBsaWVkQmFja2dyb3VuZCA9IHRydWU7XG4gICAgICAgICAgdGhpcy51cGRhdGVBcHBsaWVkQmFja2dyb3VuZCh0aGlzLmFwcGxpZWRCYWNrZ3JvdW5kKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLmFwcGxpZWRCYWNrZ3JvdW5kID0gZmFsc2U7XG4gICAgICAgICAgdGhpcy51cGRhdGVBcHBsaWVkQmFja2dyb3VuZCh0aGlzLmFwcGxpZWRCYWNrZ3JvdW5kKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghdGhpcy5wYXJhbWV0ZXJzLnRyYW5zcG9ydENyZWF0ZWQpIHtcbiAgICAgICAgICBhd2FpdCB0aGlzLmNyZWF0ZVNlbmRUcmFuc3BvcnQoe1xuICAgICAgICAgICAgb3B0aW9uOiAndmlkZW8nLFxuICAgICAgICAgICAgcGFyYW1ldGVyczogeyAuLi50aGlzLnBhcmFtZXRlcnMsIHZpZGVvUGFyYW1zOiB0aGlzLnZpZGVvUGFyYW1zIH0sXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgdGhpcy5wYXJhbWV0ZXJzLnZpZGVvUHJvZHVjZXI/LmlkICYmXG4gICAgICAgICAgICAgIHRoaXMucGFyYW1ldGVycy52aWRlb1Byb2R1Y2VyLnRyYWNrPy5pZCAhPT0gdGhpcy52aWRlb1BhcmFtcz8udHJhY2s/LmlkXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgYXdhaXQgdGhpcy5kaXNjb25uZWN0U2VuZFRyYW5zcG9ydFZpZGVvKHsgcGFyYW1ldGVyczogdGhpcy5wYXJhbWV0ZXJzIH0pO1xuICAgICAgICAgICAgICBhd2FpdCB0aGlzLnNsZWVwKHsgbXM6IDUwMCB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGF3YWl0IHRoaXMuY29ubmVjdFNlbmRUcmFuc3BvcnRWaWRlbyh7XG4gICAgICAgICAgICAgIHZpZGVvUGFyYW1zOiB0aGlzLnZpZGVvUGFyYW1zLFxuICAgICAgICAgICAgICBwYXJhbWV0ZXJzOiB0aGlzLnBhcmFtZXRlcnMsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgY29uc29sZS5sb2coZXJyb3IpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBhd2FpdCB0aGlzLm9uU2NyZWVuQ2hhbmdlcyh7IGNoYW5nZWQ6IHRydWUsIHBhcmFtZXRlcnM6IHRoaXMucGFyYW1ldGVycyB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodGhpcy5rZWVwQmFja2dyb3VuZCkge1xuICAgICAgdGhpcy5hcHBsaWVkQmFja2dyb3VuZCA9IHRydWU7XG4gICAgICB0aGlzLnVwZGF0ZUFwcGxpZWRCYWNrZ3JvdW5kKHRoaXMuYXBwbGllZEJhY2tncm91bmQpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmFwcGxpZWRCYWNrZ3JvdW5kID0gZmFsc2U7XG4gICAgICB0aGlzLnVwZGF0ZUFwcGxpZWRCYWNrZ3JvdW5kKHRoaXMuYXBwbGllZEJhY2tncm91bmQpO1xuICAgIH1cblxuICAgIHRoaXMuc2F2ZUJhY2tncm91bmRCdXR0b25SZWYubmF0aXZlRWxlbWVudC5jbGFzc0xpc3QuYWRkKCdkLW5vbmUnKTtcbiAgICB0aGlzLnNhdmVCYWNrZ3JvdW5kQnV0dG9uUmVmLm5hdGl2ZUVsZW1lbnQuZGlzYWJsZWQgPSB0cnVlO1xuICB9O1xuXG4gIGhhbmRsZU1vZGFsQ2xvc2UgPSAoKSA9PiB7XG4gICAgdHJ5IHtcbiAgICAgIC8vIElmIG5vIGJhY2tncm91bmQgaXMgYXBwbGllZCBvciB0aGUgYXBwbGllZCBiYWNrZ3JvdW5kIHNob3VsZCBub3QgYmUga2VwdFxuICAgICAgaWYgKFxuICAgICAgICAhdGhpcy5hcHBsaWVkQmFja2dyb3VuZCB8fFxuICAgICAgICAodGhpcy5hcHBsaWVkQmFja2dyb3VuZCAmJiAhdGhpcy5rZWVwQmFja2dyb3VuZCkgfHxcbiAgICAgICAgKHRoaXMuYXBwbGllZEJhY2tncm91bmQgJiYgIXRoaXMudmlkZW9BbHJlYWR5T24pXG4gICAgICApIHtcbiAgICAgICAgY29uc29sZS5sb2coJ05vIGJhY2tncm91bmQgYXBwbGllZCBvciBhcHBsaWVkIGJhY2tncm91bmQgc2hvdWxkIG5vdCBiZSBrZXB0Jyk7XG4gICAgICAgIGNvbnN0IHJlZlZpZGVvID0gdGhpcy5jYXB0dXJlVmlkZW9SZWYubmF0aXZlRWxlbWVudDtcbiAgICAgICAgdGhpcy5wYXVzZVNlZ21lbnRhdGlvbiA9IHRydWU7XG4gICAgICAgIHRoaXMudXBkYXRlUGF1c2VTZWdtZW50YXRpb24odGhpcy5wYXVzZVNlZ21lbnRhdGlvbik7XG5cbiAgICAgICAgaWYgKCF0aGlzLnZpZGVvQWxyZWFkeU9uKSB7XG4gICAgICAgICAgLy8gU3RvcCB2aWRlbyB0cmFja3MgYW5kIGNsZWFyIHRoZSB2aWRlbyBlbGVtZW50J3Mgc3JjT2JqZWN0XG4gICAgICAgICAgaWYgKHJlZlZpZGVvICYmIHJlZlZpZGVvLnNyY09iamVjdCkge1xuICAgICAgICAgICAgcmVmVmlkZW8uc3JjT2JqZWN0LmdldFRyYWNrcygpLmZvckVhY2goKHRyYWNrOiBhbnkpID0+IHRyYWNrLnN0b3AoKSk7XG4gICAgICAgICAgICByZWZWaWRlby5zcmNPYmplY3QgPSBudWxsO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIFN0b3Agc2VnbWVudFZpZGVvIHRyYWNrc1xuICAgICAgICAgIGlmICh0aGlzLnNlZ21lbnRWaWRlbykge1xuICAgICAgICAgICAgdGhpcy5zZWdtZW50VmlkZW8uZ2V0VHJhY2tzKCkuZm9yRWFjaCgodHJhY2s6IGFueSkgPT4gdHJhY2suc3RvcCgpKTtcbiAgICAgICAgICAgIHRoaXMuc2VnbWVudFZpZGVvID0gbnVsbDtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlU2VnbWVudFZpZGVvKHRoaXMuc2VnbWVudFZpZGVvKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBTdG9wIHZpcnR1YWxTdHJlYW0gdHJhY2tzXG4gICAgICAgICAgaWYgKHRoaXMudmlydHVhbFN0cmVhbSkge1xuICAgICAgICAgICAgdGhpcy52aXJ0dWFsU3RyZWFtLmdldFRyYWNrcygpLmZvckVhY2goKHRyYWNrOiBhbnkpID0+IHRyYWNrLnN0b3AoKSk7XG4gICAgICAgICAgICB0aGlzLnZpcnR1YWxTdHJlYW0gPSBudWxsO1xuICAgICAgICAgICAgdGhpcy51cGRhdGVWaXJ0dWFsU3RyZWFtKHRoaXMudmlydHVhbFN0cmVhbSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIEhpZGUgdGhlIHZpZGVvIHByZXZpZXcgYW5kIHNob3cgdGhlIGNhbnZhc1xuICAgICAgdGhpcy52aWRlb1ByZXZpZXdSZWYubmF0aXZlRWxlbWVudC5jbGFzc0xpc3QuYWRkKCdkLW5vbmUnKTtcbiAgICAgIHRoaXMuYmFja2dyb3VuZENhbnZhc1JlZi5uYXRpdmVFbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoJ2Qtbm9uZScpO1xuXG4gICAgICAvLyBIaWRlIHRoZSBtb2RhbFxuICAgICAgLy8gdGhpcy5pc1Zpc2libGUgPSBmYWxzZTtcbiAgICAgIHRoaXMub25DbG9zZSgpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zb2xlLmxvZygnRXJyb3IgZHVyaW5nIG1vZGFsIGNsb3NlOicsIGVycm9yKTtcbiAgICB9XG4gIH07XG5cbiAgc2hvd0xvYWRpbmcoKSB7XG4gICAgdGhpcy5sb2FkaW5nT3ZlcmxheVJlZi5uYXRpdmVFbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoJ2Qtbm9uZScpO1xuICB9XG5cbiAgaGlkZUxvYWRpbmcoKSB7XG4gICAgdGhpcy5sb2FkaW5nT3ZlcmxheVJlZi5uYXRpdmVFbGVtZW50LmNsYXNzTGlzdC5hZGQoJ2Qtbm9uZScpO1xuICB9XG59XG4iLCI8ZGl2IFtuZ1N0eWxlXT1cInsgcG9zaXRpb246ICdmaXhlZCcsIHRvcDogMCwgbGVmdDogMCwgd2lkdGg6ICcxMDAlJywgaGVpZ2h0OiAnMTAwJScsIGJhY2tncm91bmRDb2xvcjogJ3JnYmEoMCwgMCwgMCwgMC41KScsIGRpc3BsYXk6IGlzVmlzaWJsZSA/ICdibG9jaycgOiAnbm9uZScsIHpJbmRleDogOTk5IH1cIj5cclxuICAgIDxkaXYgW25nU3R5bGVdPVwieyBwb3NpdGlvbjogJ2ZpeGVkJywgYmFja2dyb3VuZENvbG9yOiBiYWNrZ3JvdW5kQ29sb3IsIGJvcmRlclJhZGl1czogJzEwcHgnLCBwYWRkaW5nOiAnMTBweCcsIHdpZHRoOiAnODAlJywgbWF4V2lkdGg6ICc1MDBweCcsIG1heEhlaWdodDogJzc1JScsIG92ZXJmbG93WTogJ2F1dG8nLCBvdmVyZmxvd1g6ICdoaWRkZW4nLCB0b3A6IHBvc2l0aW9uLmluY2x1ZGVzKCd0b3AnKSA/ICcxMHB4JyA6ICdhdXRvJywgYm90dG9tOiBwb3NpdGlvbi5pbmNsdWRlcygnYm90dG9tJykgPyAnMTBweCcgOiAnYXV0bycsIGxlZnQ6IHBvc2l0aW9uLmluY2x1ZGVzKCdMZWZ0JykgPyAnMTBweCcgOiAnYXV0bycsIHJpZ2h0OiBwb3NpdGlvbi5pbmNsdWRlcygnUmlnaHQnKSA/ICcxMHB4JyA6ICdhdXRvJyB9XCI+XHJcbiAgICAgIDxkaXYgc3R5bGU9XCJkaXNwbGF5OiBmbGV4OyBqdXN0aWZ5LWNvbnRlbnQ6IHNwYWNlLWJldHdlZW47IGFsaWduLWl0ZW1zOiBjZW50ZXI7IG1hcmdpbi1ib3R0b206IDE1cHg7XCI+XHJcbiAgICAgICAgPGgyIHN0eWxlPVwiZm9udC1zaXplOiB4LWxhcmdlOyBmb250LXdlaWdodDogYm9sZDsgY29sb3I6IGJsYWNrO1wiPkJhY2tncm91bmQgU2V0dGluZ3M8L2gyPlxyXG4gICAgICAgIDxidXR0b24gKGNsaWNrKT1cIm9uQ2xvc2UoKVwiIHN0eWxlPVwiYm9yZGVyOiBub25lOyBiYWNrZ3JvdW5kOiBub25lOyBjdXJzb3I6IHBvaW50ZXI7XCI+XHJcbiAgICAgICAgICA8ZmEtaWNvbiBbaWNvbl09XCJmYVRpbWVzXCIgc2l6ZT1cInhsXCIgc3R5bGU9XCJmb250LXNpemU6IDIwcHg7IGNvbG9yOiBibGFjaztcIj48L2ZhLWljb24+XHJcbiAgICAgICAgPC9idXR0b24+XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgICA8aHIgc3R5bGU9XCJoZWlnaHQ6IDFweDsgYmFja2dyb3VuZC1jb2xvcjogYmxhY2s7IG1hcmdpbi10b3A6IDVweDsgbWFyZ2luLWJvdHRvbTogNXB4O1wiIC8+XHJcbiAgICAgIDxkaXYgc3R5bGU9XCJtYXgtd2lkdGg6IDk1JTsgb3ZlcmZsb3cteDogYXV0bztcIj5cclxuICAgICAgICA8ZGl2IGlkPVwiZGVmYXVsdEltYWdlc1wiICNkZWZhdWx0SW1hZ2VzQ29udGFpbmVyPjwvZGl2PlxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwXCIgc3R5bGU9XCJtYXgtd2lkdGg6IDcwJTsgb3ZlcmZsb3cteDogYXV0bztcIj5cclxuICAgICAgICAgIDxsYWJlbCBmb3I9XCJ1cGxvYWRJbWFnZVwiPlVwbG9hZCBDdXN0b20gSW1hZ2U8L2xhYmVsPlxyXG4gICAgICAgICAgPGlucHV0IHR5cGU9XCJmaWxlXCIgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIiBpZD1cInVwbG9hZEltYWdlXCIgI3VwbG9hZEltYWdlSW5wdXQgKGNoYW5nZSk9XCJoYW5kbGVJbWFnZVVwbG9hZCgkZXZlbnQpXCIgLz5cclxuICAgICAgICA8L2Rpdj5cclxuICAgICAgICA8Y2FudmFzIGlkPVwibWFpbkNhbnZhc1wiICNtYWluQ2FudmFzIGNsYXNzPVwiZC1ub25lXCI+PC9jYW52YXM+XHJcbiAgICAgICAgPGNhbnZhcyBpZD1cImJhY2tncm91bmRDYW52YXNcIiAjYmFja2dyb3VuZENhbnZhcyBjbGFzcz1cImQtbm9uZVwiIHN0eWxlPVwid2lkdGg6IDEwMCU7IG1heC13aWR0aDogNDAwcHg7IGhlaWdodDogYXV0bzsgYmFja2dyb3VuZC1jb2xvcjogdHJhbnNwYXJlbnQ7IGJvcmRlcjogMXB4IHNvbGlkIGJsYWNrO1wiPjwvY2FudmFzPlxyXG4gICAgICAgIDx2aWRlbyBpZD1cImNhcHR1cmVWaWRlb1wiICNjYXB0dXJlVmlkZW8gY2xhc3M9XCJkLW5vbmVcIiBtdXRlZCBhdXRvcGxheSBwbGF5c2lubGluZT48L3ZpZGVvPlxyXG4gICAgICAgIDx2aWRlbyBpZD1cInByZXZpZXdWaWRlb1wiICN2aWRlb1ByZXZpZXcgY2xhc3M9XCJkLW5vbmVcIiBtdXRlZCBhdXRvcGxheSBwbGF5c2lubGluZSBzdHlsZT1cIndpZHRoOiAxMDAlOyBtYXgtd2lkdGg6IDQwMHB4OyBoZWlnaHQ6IGF1dG87IGJhY2tncm91bmQtY29sb3I6IHRyYW5zcGFyZW50OyBib3JkZXI6IDFweCBzb2xpZCBibGFjaztcIj48L3ZpZGVvPlxyXG4gICAgICAgIDxkaXYgaWQ9XCJsb2FkaW5nT3ZlcmxheVwiICNsb2FkaW5nT3ZlcmxheSBjbGFzcz1cImQtbm9uZVwiIFtuZ1N0eWxlXT1cInsgcG9zaXRpb246ICdhYnNvbHV0ZScsIHRvcDogMCwgbGVmdDogMCwgd2lkdGg6ICcxMDAlJywgaGVpZ2h0OiAnMTAwJScsIGJhY2tncm91bmRDb2xvcjogJ3JnYmEoMCwgMCwgMCwgMC41KScsIGRpc3BsYXk6ICdmbGV4JywgJ2p1c3RpZnktY29udGVudCc6ICdjZW50ZXInLCAnYWxpZ24taXRlbXMnOiAnY2VudGVyJywgekluZGV4OiAxMDAwIH1cIj5cclxuICAgICAgICAgIDxkaXYgW25nU3R5bGVdPVwieyB3aWR0aDogJzUwcHgnLCBoZWlnaHQ6ICc1MHB4JywgYm9yZGVyOiAnNXB4IHNvbGlkIHJnYmEoMjU1LCAyNTUsIDI1NSwgMC4zKScsIGJvcmRlclJhZGl1czogJzUwJScsIGJvcmRlclRvcDogJzVweCBzb2xpZCB3aGl0ZScsIGFuaW1hdGlvbjogJ3NwaW4gMXMgbGluZWFyIGluZmluaXRlJyB9XCI+PC9kaXY+XHJcbiAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgPGJyIC8+XHJcbiAgICAgICAgPGJ1dHRvbiBpZD1cImFwcGx5QmFja2dyb3VuZEJ1dHRvblwiICNhcHBseUJhY2tncm91bmRCdXR0b24gY2xhc3M9XCJidG4gYnRuLXByaW1hcnlcIiAoY2xpY2spPVwiYXBwbHlCYWNrZ3JvdW5kKClcIj5QcmV2aWV3IEJhY2tncm91bmQ8L2J1dHRvbj5cclxuICAgICAgICA8YnV0dG9uIGlkPVwic2F2ZUJhY2tncm91bmRCdXR0b25cIiAjc2F2ZUJhY2tncm91bmRCdXR0b24gY2xhc3M9XCJidG4gYnRuLXN1Y2Nlc3MgZC1ub25lXCIgKGNsaWNrKT1cInNhdmVCYWNrZ3JvdW5kKClcIj5TYXZlIEJhY2tncm91bmQ8L2J1dHRvbj5cclxuICAgICAgPC9kaXY+XHJcbiAgICA8L2Rpdj5cclxuICA8L2Rpdj5cclxuIl19