@magic-xpa/engine 4.800.0 → 4.801.0-dev000.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 (379) hide show
  1. package/esm2020/index.mjs +190 -0
  2. package/{esm2015/magic-xpa-engine.js → esm2020/magic-xpa-engine.mjs} +0 -0
  3. package/esm2020/src/AccessHelper.mjs +3 -0
  4. package/esm2020/src/ClientManager.mjs +403 -0
  5. package/esm2020/src/CommandsProcessorBase.mjs +58 -0
  6. package/esm2020/src/CommandsProcessorManager.mjs +26 -0
  7. package/esm2020/src/CommandsTable.mjs +163 -0
  8. package/{esm2015/src/ConstInterface.js → esm2020/src/ConstInterface.mjs} +0 -0
  9. package/{esm2015/src/CurrentClientVersion.js → esm2020/src/CurrentClientVersion.mjs} +2 -2
  10. package/{esm2015/src/FlowMonitorInterface.js → esm2020/src/FlowMonitorInterface.mjs} +0 -0
  11. package/esm2020/src/GUIManager.mjs +63 -0
  12. package/{esm2015/src/GlobalCommandsManager.js → esm2020/src/GlobalCommandsManager.mjs} +0 -0
  13. package/esm2020/src/GuiEventsProcessor.mjs +171 -0
  14. package/{esm2015/src/ICommandsTable.js → esm2020/src/ICommandsTable.mjs} +1 -0
  15. package/{esm2015/src/ServerConfig.js → esm2020/src/ServerConfig.mjs} +0 -0
  16. package/{esm2015/src/bridge/IGuiEvent.js → esm2020/src/bridge/IGuiEvent.mjs} +0 -0
  17. package/esm2020/src/bridge/MagicBridge.mjs +41 -0
  18. package/{esm2015/src/commands/ClientOriginatedCommandTaskTag.js → esm2020/src/commands/ClientOriginatedCommandTaskTag.mjs} +0 -0
  19. package/{esm2015/src/commands/ClientToServer/AddUserLocateDataViewCommand.js → esm2020/src/commands/ClientToServer/AddUserLocateDataViewCommand.mjs} +0 -0
  20. package/{esm2015/src/commands/ClientToServer/AddUserRangeDataviewCommand.js → esm2020/src/commands/ClientToServer/AddUserRangeDataviewCommand.mjs} +0 -0
  21. package/{esm2015/src/commands/ClientToServer/AddUserSortDataViewCommand.js → esm2020/src/commands/ClientToServer/AddUserSortDataViewCommand.mjs} +0 -0
  22. package/esm2020/src/commands/ClientToServer/BrowserEscEventCommand.mjs +23 -0
  23. package/esm2020/src/commands/ClientToServer/ClientOriginatedCommand.mjs +15 -0
  24. package/esm2020/src/commands/ClientToServer/ClientOriginatedCommandSerializer.mjs +60 -0
  25. package/esm2020/src/commands/ClientToServer/ColumnSortEventCommand.mjs +26 -0
  26. package/esm2020/src/commands/ClientToServer/CommandFactory.mjs +278 -0
  27. package/{esm2015/src/commands/ClientToServer/CommandSerializationHelper.js → esm2020/src/commands/ClientToServer/CommandSerializationHelper.mjs} +0 -0
  28. package/esm2020/src/commands/ClientToServer/ComputeEventCommand.mjs +23 -0
  29. package/esm2020/src/commands/ClientToServer/ContextTerminationEventCommand.mjs +21 -0
  30. package/esm2020/src/commands/ClientToServer/ContextTimeoutResetCommand.mjs +20 -0
  31. package/{esm2015/src/commands/ClientToServer/ControlItemsRefreshCommand.js → esm2020/src/commands/ClientToServer/ControlItemsRefreshCommand.mjs} +0 -0
  32. package/{esm2015/src/commands/ClientToServer/DataViewOutputCommand.js → esm2020/src/commands/ClientToServer/DataViewOutputCommand.mjs} +0 -0
  33. package/{esm2015/src/commands/ClientToServer/DataviewCommand.js → esm2020/src/commands/ClientToServer/DataviewCommand.mjs} +2 -2
  34. package/esm2020/src/commands/ClientToServer/EvaluateCommand.mjs +36 -0
  35. package/esm2020/src/commands/ClientToServer/EventCommand.mjs +40 -0
  36. package/esm2020/src/commands/ClientToServer/ExecOperCommand.mjs +67 -0
  37. package/esm2020/src/commands/ClientToServer/FetchDataControlValuesEventCommand.mjs +22 -0
  38. package/{esm2015/src/commands/ClientToServer/GlobalParamsQueryCommand.js → esm2020/src/commands/ClientToServer/GlobalParamsQueryCommand.mjs} +0 -0
  39. package/{esm2015/src/commands/ClientToServer/ICommandTaskTag.js → esm2020/src/commands/ClientToServer/ICommandTaskTag.mjs} +1 -0
  40. package/esm2020/src/commands/ClientToServer/IndexChangeEventCommand.mjs +21 -0
  41. package/esm2020/src/commands/ClientToServer/IniputForceWriteCommand.mjs +23 -0
  42. package/esm2020/src/commands/ClientToServer/NonReversibleExitEventCommand.mjs +23 -0
  43. package/esm2020/src/commands/ClientToServer/QueryCommand.mjs +21 -0
  44. package/esm2020/src/commands/ClientToServer/RecomputeCommand.mjs +27 -0
  45. package/esm2020/src/commands/ClientToServer/RefreshEventCommand.mjs +27 -0
  46. package/esm2020/src/commands/ClientToServer/RefreshScreenEventCommand.mjs +24 -0
  47. package/esm2020/src/commands/ClientToServer/RollbackEventCommand.mjs +39 -0
  48. package/{esm2015/src/commands/ClientToServer/SelectProgramCommand.js → esm2020/src/commands/ClientToServer/SelectProgramCommand.mjs} +0 -0
  49. package/{esm2015/src/commands/ClientToServer/SetTransactionStateDataviewCommand.js → esm2020/src/commands/ClientToServer/SetTransactionStateDataviewCommand.mjs} +0 -0
  50. package/esm2020/src/commands/ClientToServer/SubformOpenEventCommand.mjs +21 -0
  51. package/esm2020/src/commands/ClientToServer/SubformRefreshEventCommand.mjs +24 -0
  52. package/esm2020/src/commands/ClientToServer/TransactionCommand.mjs +28 -0
  53. package/{esm2015/src/commands/ClientToServer/UnloadCommand.js → esm2020/src/commands/ClientToServer/UnloadCommand.mjs} +0 -0
  54. package/esm2020/src/commands/ClientToServer/WriteMessageToServerLogCommand.mjs +18 -0
  55. package/esm2020/src/commands/DataViewCommandBase.mjs +10 -0
  56. package/{esm2015/src/commands/IClientCommand.js → esm2020/src/commands/IClientCommand.mjs} +1 -0
  57. package/esm2020/src/commands/IClientTargetedCommand.mjs +9 -0
  58. package/{esm2015/src/commands/IClientToServerCommandInfo.js → esm2020/src/commands/IClientToServerCommandInfo.mjs} +1 -0
  59. package/esm2020/src/commands/ServerToClient/AbortCommand.mjs +65 -0
  60. package/esm2020/src/commands/ServerToClient/AddLocateCommand.mjs +22 -0
  61. package/esm2020/src/commands/ServerToClient/AddRangeCommand.mjs +62 -0
  62. package/esm2020/src/commands/ServerToClient/AddSortCommand.mjs +33 -0
  63. package/{esm2015/src/commands/ServerToClient/ClientRefreshCommand.js → esm2020/src/commands/ServerToClient/ClientRefreshCommand.mjs} +14 -17
  64. package/esm2020/src/commands/ServerToClient/ClientTargetedCommandBase.mjs +27 -0
  65. package/esm2020/src/commands/ServerToClient/EnhancedVerifyCommand.mjs +45 -0
  66. package/esm2020/src/commands/ServerToClient/OpenURLCommand.mjs +222 -0
  67. package/esm2020/src/commands/ServerToClient/ResetLocateCommand.mjs +15 -0
  68. package/esm2020/src/commands/ServerToClient/ResetRangeCommand.mjs +15 -0
  69. package/esm2020/src/commands/ServerToClient/ResetSortCommand.mjs +15 -0
  70. package/esm2020/src/commands/ServerToClient/ResultCommand.mjs +37 -0
  71. package/esm2020/src/commands/ServerToClient/VerifyCommand.mjs +85 -0
  72. package/{esm2015/src/commands/ServerToClient/XMLBasedCommandBuilder.js → esm2020/src/commands/ServerToClient/XMLBasedCommandBuilder.mjs} +0 -0
  73. package/{esm2015/src/communications/IConnectionStateManager.js → esm2020/src/communications/IConnectionStateManager.mjs} +1 -0
  74. package/esm2020/src/communications/InteractiveCommunicationsFailureHandler.mjs +17 -0
  75. package/{esm2015/src/data/DataSourceIdKey.js → esm2020/src/data/DataSourceIdKey.mjs} +0 -0
  76. package/esm2020/src/data/DataView.mjs +1634 -0
  77. package/{esm2015/src/data/DataViewBase.js → esm2020/src/data/DataViewBase.mjs} +0 -0
  78. package/esm2020/src/data/DataviewManager.mjs +28 -0
  79. package/esm2020/src/data/DataviewManagerBase.mjs +15 -0
  80. package/{esm2015/src/data/DvCache.js → esm2020/src/data/DvCache.mjs} +0 -0
  81. package/esm2020/src/data/Field.mjs +645 -0
  82. package/esm2020/src/data/FieldBase.mjs +18 -0
  83. package/{esm2015/src/data/FieldsTable.js → esm2020/src/data/FieldsTable.mjs} +0 -0
  84. package/{esm2015/src/data/IRecordsTable.js → esm2020/src/data/IRecordsTable.mjs} +1 -0
  85. package/{esm2015/src/data/Key.js → esm2020/src/data/Key.mjs} +0 -0
  86. package/esm2020/src/data/Record.mjs +846 -0
  87. package/{esm2015/src/data/RecordOutOfDataViewException.js → esm2020/src/data/RecordOutOfDataViewException.mjs} +0 -0
  88. package/esm2020/src/data/RecordsTable.mjs +267 -0
  89. package/esm2020/src/data/TaskTransactionManager.mjs +103 -0
  90. package/esm2020/src/data/XMLBasedDcValuesBuilder.mjs +74 -0
  91. package/{esm2015/src/enums.js → esm2020/src/enums.mjs} +0 -0
  92. package/esm2020/src/env/EnvVariablesTable.mjs +340 -0
  93. package/esm2020/src/env/Environment.mjs +554 -0
  94. package/{esm2015/src/env/ILanguageData.js → esm2020/src/env/ILanguageData.mjs} +1 -0
  95. package/esm2020/src/env/LanguageData.mjs +222 -0
  96. package/esm2020/src/env/MirrorString.mjs +66 -0
  97. package/{esm2015/src/event/ActionManager.js → esm2020/src/event/ActionManager.mjs} +0 -0
  98. package/esm2020/src/event/Event.mjs +1436 -0
  99. package/esm2020/src/event/EventHandler.mjs +773 -0
  100. package/esm2020/src/event/EventHandlerPosition.mjs +201 -0
  101. package/esm2020/src/event/EventsManager.mjs +2983 -0
  102. package/esm2020/src/event/IEventsManager.mjs +7 -0
  103. package/esm2020/src/event/RunTimeEvent.mjs +406 -0
  104. package/{esm2015/src/event/RunTimeEventBase.js → esm2020/src/event/RunTimeEventBase.mjs} +0 -0
  105. package/{esm2015/src/event/UserEventsTable.js → esm2020/src/event/UserEventsTable.mjs} +0 -0
  106. package/{esm2015/src/exp/ExpTable.js → esm2020/src/exp/ExpTable.mjs} +0 -0
  107. package/esm2020/src/exp/Expression.mjs +200 -0
  108. package/{esm2015/src/exp/ExpressionDict.js → esm2020/src/exp/ExpressionDict.mjs} +0 -0
  109. package/esm2020/src/exp/ExpressionEvaluator.mjs +4373 -0
  110. package/esm2020/src/exp/ExpressionLocalJpn.mjs +314 -0
  111. package/esm2020/src/exp/GlobalParamsTable.mjs +85 -0
  112. package/esm2020/src/exp/YesNoExp.mjs +41 -0
  113. package/{esm2015/src/gui/CreatedFormVector.js → esm2020/src/gui/CreatedFormVector.mjs} +0 -0
  114. package/esm2020/src/gui/FormsTable.mjs +66 -0
  115. package/esm2020/src/gui/MgControl.mjs +357 -0
  116. package/esm2020/src/gui/MgForm.mjs +1195 -0
  117. package/esm2020/src/http/HttpManager.mjs +97 -0
  118. package/esm2020/src/http/client/HttpClientAsync.mjs +67 -0
  119. package/esm2020/src/http/client/HttpClientBase.mjs +148 -0
  120. package/{esm2015/src/http/client/HttpClientEvents.js → esm2020/src/http/client/HttpClientEvents.mjs} +0 -0
  121. package/esm2020/src/http/client/HttpClientSync.mjs +42 -0
  122. package/{esm2015/src/http/client/HttpUtility.js → esm2020/src/http/client/HttpUtility.mjs} +0 -0
  123. package/{esm2015/src/http/client/ICommunicationsFailureHandler.js → esm2020/src/http/client/ICommunicationsFailureHandler.mjs} +1 -0
  124. package/esm2020/src/remote/AddUserLocateRemoteDataViewCommand.mjs +18 -0
  125. package/esm2020/src/remote/AddUserRangeRemoteDataViewCommand.mjs +18 -0
  126. package/esm2020/src/remote/AddUserSortRemoteDataViewCommand.mjs +18 -0
  127. package/esm2020/src/remote/RemoteCommandsProcessor.mjs +872 -0
  128. package/esm2020/src/remote/RemoteControlItemsRefreshCommand.mjs +25 -0
  129. package/esm2020/src/remote/RemoteDataViewCommandBase.mjs +24 -0
  130. package/{esm2015/src/remote/RemoteDataViewCommandFactory.js → esm2020/src/remote/RemoteDataViewCommandFactory.mjs} +0 -0
  131. package/esm2020/src/remote/RemoteDataViewCommandUpdateNonModifiable.mjs +16 -0
  132. package/esm2020/src/remote/RemoteDataviewManager.mjs +17 -0
  133. package/esm2020/src/remote/RemoteInitDataViewCommand.mjs +11 -0
  134. package/esm2020/src/remote/ResetUserLocateRemoteDataviewCommand.mjs +17 -0
  135. package/esm2020/src/remote/ResetUserRangeRemoteDataviewCommand.mjs +13 -0
  136. package/esm2020/src/remote/ResetUserSortRemoteDataviewCommand.mjs +16 -0
  137. package/esm2020/src/remote/ServerError.mjs +44 -0
  138. package/{esm2015/src/remote/SetTransactionStateRemoteDataViewCommand.js → esm2020/src/remote/SetTransactionStateRemoteDataViewCommand.mjs} +8 -11
  139. package/esm2020/src/rt/Argument.mjs +274 -0
  140. package/esm2020/src/rt/ArgumentsList.mjs +103 -0
  141. package/esm2020/src/rt/Boundary.mjs +158 -0
  142. package/{esm2015/src/rt/CompMainPrgTable.js → esm2020/src/rt/CompMainPrgTable.mjs} +0 -0
  143. package/esm2020/src/rt/DataviewHeaderBase.mjs +96 -0
  144. package/esm2020/src/rt/DataviewHeaderFactory.mjs +7 -0
  145. package/{esm2015/src/rt/DataviewHeaders.js → esm2020/src/rt/DataviewHeaders.mjs} +0 -0
  146. package/esm2020/src/rt/DataviewHeadersSaxHandler.mjs +39 -0
  147. package/{esm2015/src/rt/ExecutionStack.js → esm2020/src/rt/ExecutionStack.mjs} +0 -0
  148. package/{esm2015/src/rt/ExecutionStackEntry.js → esm2020/src/rt/ExecutionStackEntry.mjs} +0 -0
  149. package/{esm2015/src/rt/HandlersTable.js → esm2020/src/rt/HandlersTable.mjs} +0 -0
  150. package/{esm2015/src/rt/IDataSourceViewDefinition.js → esm2020/src/rt/IDataSourceViewDefinition.mjs} +1 -0
  151. package/{esm2015/src/rt/IDataviewHeader.js → esm2020/src/rt/IDataviewHeader.mjs} +1 -0
  152. package/{esm2015/src/rt/IResultValue.js → esm2020/src/rt/IResultValue.mjs} +1 -0
  153. package/{esm2015/src/rt/LastFocusedManager.js → esm2020/src/rt/LastFocusedManager.mjs} +0 -0
  154. package/esm2020/src/rt/Operation.mjs +745 -0
  155. package/{esm2015/src/rt/OperationTable.js → esm2020/src/rt/OperationTable.mjs} +0 -0
  156. package/esm2020/src/rt/Recompute.mjs +355 -0
  157. package/{esm2015/src/rt/RecomputeTable.js → esm2020/src/rt/RecomputeTable.mjs} +0 -0
  158. package/esm2020/src/rt/RemoteDataviewHeader.mjs +105 -0
  159. package/{esm2015/src/rt/ResultValue.js → esm2020/src/rt/ResultValue.mjs} +0 -0
  160. package/esm2020/src/rt/TableCache.mjs +177 -0
  161. package/esm2020/src/rt/TableCacheManager.mjs +67 -0
  162. package/esm2020/src/rt/Transaction.mjs +54 -0
  163. package/{esm2015/src/security/UserDetails.js → esm2020/src/security/UserDetails.mjs} +0 -0
  164. package/{esm2015/src/tasks/IMGDataCollection.js → esm2020/src/tasks/IMGDataCollection.mjs} +1 -0
  165. package/esm2020/src/tasks/MGData.mjs +552 -0
  166. package/esm2020/src/tasks/MGDataCollection.mjs +259 -0
  167. package/{esm2015/src/tasks/MenusDeserializer.js → esm2020/src/tasks/MenusDeserializer.mjs} +0 -0
  168. package/{esm2015/src/tasks/RCTimer.js → esm2020/src/tasks/RCTimer.mjs} +0 -0
  169. package/esm2020/src/tasks/RemoteTaskService.mjs +45 -0
  170. package/esm2020/src/tasks/Task.mjs +2501 -0
  171. package/{esm2015/src/tasks/TaskBase.js → esm2020/src/tasks/TaskBase.mjs} +22 -1
  172. package/esm2020/src/tasks/TaskServiceBase.mjs +25 -0
  173. package/esm2020/src/tasks/TasksTable.mjs +80 -0
  174. package/{esm2015/src/tasks/sort/Sort.js → esm2020/src/tasks/sort/Sort.mjs} +0 -0
  175. package/esm2020/src/tasks/sort/SortCollection.mjs +72 -0
  176. package/{esm2015/src/util/ConstUtils.js → esm2020/src/util/ConstUtils.mjs} +0 -0
  177. package/{esm2015/src/util/FlowMonitorQueue.js → esm2020/src/util/FlowMonitorQueue.mjs} +15 -18
  178. package/{esm2015/src/util/HeapSort.js → esm2020/src/util/HeapSort.mjs} +0 -0
  179. package/{esm2015/src/util/IMirrorXML.js → esm2020/src/util/IMirrorXML.mjs} +2 -1
  180. package/{esm2015/src/util/IServerConfig.js → esm2020/src/util/IServerConfig.mjs} +1 -0
  181. package/{esm2015/src/util/MgBlockingQueue.js → esm2020/src/util/MgBlockingQueue.mjs} +1 -0
  182. package/esm2020/src/util/MgPriorityBlockingQueue.mjs +76 -0
  183. package/{esm2015/src/util/MgPriorityQueue.js → esm2020/src/util/MgPriorityQueue.mjs} +0 -0
  184. package/esm2020/src/util/ParamParseResult.mjs +8 -0
  185. package/esm2020/src/util/PrmMap.mjs +151 -0
  186. package/esm2020/src/util/Process.mjs +7 -0
  187. package/esm2020/src/util/ReturnResult.mjs +46 -0
  188. package/{esm2015/src/util/ReturnResultBase.js → esm2020/src/util/ReturnResultBase.mjs} +0 -0
  189. package/{esm2015/src/util/Scrambler.js → esm2020/src/util/Scrambler.mjs} +0 -0
  190. package/{esm2015/src/util/UniqueIDUtils.js → esm2020/src/util/UniqueIDUtils.mjs} +0 -0
  191. package/{esm2015/src/util/cookie.service.js → esm2020/src/util/cookie.service.mjs} +0 -0
  192. package/fesm2015/{magic-xpa-engine.js → magic-xpa-engine.mjs} +267 -254
  193. package/fesm2015/magic-xpa-engine.mjs.map +1 -0
  194. package/fesm2020/magic-xpa-engine.mjs +30705 -0
  195. package/fesm2020/magic-xpa-engine.mjs.map +1 -0
  196. package/index.d.ts +2 -0
  197. package/package.json +27 -13
  198. package/src/AccessHelper.d.ts +1 -1
  199. package/src/CommandsProcessorBase.d.ts +3 -3
  200. package/src/GuiEventsProcessor.d.ts +1 -1
  201. package/src/commands/ClientToServer/BrowserEscEventCommand.d.ts +1 -2
  202. package/src/commands/ClientToServer/ClientOriginatedCommand.d.ts +1 -2
  203. package/src/commands/ClientToServer/ColumnSortEventCommand.d.ts +1 -2
  204. package/src/commands/ClientToServer/ComputeEventCommand.d.ts +1 -2
  205. package/src/commands/ClientToServer/ContextTerminationEventCommand.d.ts +1 -2
  206. package/src/commands/ClientToServer/ContextTimeoutResetCommand.d.ts +1 -2
  207. package/src/commands/ClientToServer/DataviewCommand.d.ts +1 -2
  208. package/src/commands/ClientToServer/EvaluateCommand.d.ts +1 -2
  209. package/src/commands/ClientToServer/EventCommand.d.ts +1 -2
  210. package/src/commands/ClientToServer/ExecOperCommand.d.ts +1 -2
  211. package/src/commands/ClientToServer/FetchDataControlValuesEventCommand.d.ts +1 -2
  212. package/src/commands/ClientToServer/IndexChangeEventCommand.d.ts +1 -2
  213. package/src/commands/ClientToServer/IniputForceWriteCommand.d.ts +1 -2
  214. package/src/commands/ClientToServer/NonReversibleExitEventCommand.d.ts +1 -2
  215. package/src/commands/ClientToServer/QueryCommand.d.ts +1 -2
  216. package/src/commands/ClientToServer/RecomputeCommand.d.ts +1 -2
  217. package/src/commands/ClientToServer/RefreshEventCommand.d.ts +1 -2
  218. package/src/commands/ClientToServer/RefreshScreenEventCommand.d.ts +1 -2
  219. package/src/commands/ClientToServer/RollbackEventCommand.d.ts +1 -2
  220. package/src/commands/ClientToServer/SubformOpenEventCommand.d.ts +1 -2
  221. package/src/commands/ClientToServer/SubformRefreshEventCommand.d.ts +1 -2
  222. package/src/commands/ClientToServer/TransactionCommand.d.ts +1 -2
  223. package/src/commands/ClientToServer/WriteMessageToServerLogCommand.d.ts +1 -2
  224. package/src/commands/DataViewCommandBase.d.ts +2 -2
  225. package/src/commands/IClientTargetedCommand.d.ts +1 -1
  226. package/src/commands/ServerToClient/ClientTargetedCommandBase.d.ts +1 -1
  227. package/src/data/FieldBase.d.ts +3 -3
  228. package/src/data/Record.d.ts +2 -9
  229. package/src/data/RecordsTable.d.ts +1 -2
  230. package/src/data/XMLBasedDcValuesBuilder.d.ts +1 -1
  231. package/src/env/EnvVariablesTable.d.ts +2 -15
  232. package/src/env/Environment.d.ts +0 -3
  233. package/src/env/MirrorString.d.ts +15 -0
  234. package/src/event/Event.d.ts +0 -3
  235. package/src/event/EventsManager.d.ts +7 -8
  236. package/src/event/IEventsManager.d.ts +5 -6
  237. package/src/exp/ExpressionEvaluator.d.ts +2 -2
  238. package/src/exp/ExpressionLocalJpn.d.ts +2 -2
  239. package/src/exp/GlobalParamsTable.d.ts +2 -1
  240. package/src/gui/MgControl.d.ts +0 -2
  241. package/src/gui/MgForm.d.ts +4 -4
  242. package/src/http/client/HttpClientAsync.d.ts +2 -2
  243. package/src/http/client/HttpClientBase.d.ts +3 -3
  244. package/src/http/client/HttpClientSync.d.ts +2 -2
  245. package/src/remote/RemoteCommandsProcessor.d.ts +1 -1
  246. package/src/rt/DataviewHeaderBase.d.ts +2 -2
  247. package/src/rt/DataviewHeaderFactory.d.ts +1 -1
  248. package/src/rt/Operation.d.ts +3 -1
  249. package/src/rt/RemoteDataviewHeader.d.ts +1 -2
  250. package/src/rt/Transaction.d.ts +1 -1
  251. package/src/tasks/RemoteTaskService.d.ts +2 -3
  252. package/src/tasks/Task.d.ts +1 -1
  253. package/src/tasks/TaskBase.d.ts +7 -7
  254. package/src/tasks/TaskServiceBase.d.ts +2 -4
  255. package/src/tasks/sort/SortCollection.d.ts +2 -3
  256. package/src/util/FlowMonitorQueue.d.ts +1 -1
  257. package/src/util/IMirrorXML.d.ts +1 -1
  258. package/src/util/ParamParseResult.d.ts +6 -0
  259. package/src/util/PrmMap.d.ts +0 -6
  260. package/src/util/Process.d.ts +1 -1
  261. package/bundles/magic-xpa-engine.umd.js +0 -38066
  262. package/bundles/magic-xpa-engine.umd.js.map +0 -1
  263. package/bundles/magic-xpa-engine.umd.min.js +0 -16
  264. package/bundles/magic-xpa-engine.umd.min.js.map +0 -1
  265. package/esm2015/index.js +0 -188
  266. package/esm2015/src/AccessHelper.js +0 -3
  267. package/esm2015/src/ClientManager.js +0 -412
  268. package/esm2015/src/CommandsProcessorBase.js +0 -54
  269. package/esm2015/src/CommandsProcessorManager.js +0 -31
  270. package/esm2015/src/CommandsTable.js +0 -166
  271. package/esm2015/src/GUIManager.js +0 -72
  272. package/esm2015/src/GuiEventsProcessor.js +0 -171
  273. package/esm2015/src/bridge/MagicBridge.js +0 -44
  274. package/esm2015/src/commands/ClientToServer/BrowserEscEventCommand.js +0 -24
  275. package/esm2015/src/commands/ClientToServer/ClientOriginatedCommand.js +0 -15
  276. package/esm2015/src/commands/ClientToServer/ClientOriginatedCommandSerializer.js +0 -60
  277. package/esm2015/src/commands/ClientToServer/ColumnSortEventCommand.js +0 -26
  278. package/esm2015/src/commands/ClientToServer/CommandFactory.js +0 -283
  279. package/esm2015/src/commands/ClientToServer/ComputeEventCommand.js +0 -23
  280. package/esm2015/src/commands/ClientToServer/ContextTerminationEventCommand.js +0 -21
  281. package/esm2015/src/commands/ClientToServer/ContextTimeoutResetCommand.js +0 -20
  282. package/esm2015/src/commands/ClientToServer/EvaluateCommand.js +0 -36
  283. package/esm2015/src/commands/ClientToServer/EventCommand.js +0 -40
  284. package/esm2015/src/commands/ClientToServer/ExecOperCommand.js +0 -67
  285. package/esm2015/src/commands/ClientToServer/FetchDataControlValuesEventCommand.js +0 -22
  286. package/esm2015/src/commands/ClientToServer/IndexChangeEventCommand.js +0 -21
  287. package/esm2015/src/commands/ClientToServer/IniputForceWriteCommand.js +0 -23
  288. package/esm2015/src/commands/ClientToServer/NonReversibleExitEventCommand.js +0 -23
  289. package/esm2015/src/commands/ClientToServer/QueryCommand.js +0 -21
  290. package/esm2015/src/commands/ClientToServer/RecomputeCommand.js +0 -27
  291. package/esm2015/src/commands/ClientToServer/RefreshEventCommand.js +0 -27
  292. package/esm2015/src/commands/ClientToServer/RefreshScreenEventCommand.js +0 -24
  293. package/esm2015/src/commands/ClientToServer/RollbackEventCommand.js +0 -39
  294. package/esm2015/src/commands/ClientToServer/SubformOpenEventCommand.js +0 -21
  295. package/esm2015/src/commands/ClientToServer/SubformRefreshEventCommand.js +0 -24
  296. package/esm2015/src/commands/ClientToServer/TransactionCommand.js +0 -28
  297. package/esm2015/src/commands/ClientToServer/WriteMessageToServerLogCommand.js +0 -18
  298. package/esm2015/src/commands/DataViewCommandBase.js +0 -6
  299. package/esm2015/src/commands/IClientTargetedCommand.js +0 -6
  300. package/esm2015/src/commands/ServerToClient/AbortCommand.js +0 -68
  301. package/esm2015/src/commands/ServerToClient/AddLocateCommand.js +0 -25
  302. package/esm2015/src/commands/ServerToClient/AddRangeCommand.js +0 -65
  303. package/esm2015/src/commands/ServerToClient/AddSortCommand.js +0 -36
  304. package/esm2015/src/commands/ServerToClient/ClientTargetedCommandBase.js +0 -24
  305. package/esm2015/src/commands/ServerToClient/EnhancedVerifyCommand.js +0 -48
  306. package/esm2015/src/commands/ServerToClient/OpenURLCommand.js +0 -225
  307. package/esm2015/src/commands/ServerToClient/ResetLocateCommand.js +0 -18
  308. package/esm2015/src/commands/ServerToClient/ResetRangeCommand.js +0 -18
  309. package/esm2015/src/commands/ServerToClient/ResetSortCommand.js +0 -18
  310. package/esm2015/src/commands/ServerToClient/ResultCommand.js +0 -40
  311. package/esm2015/src/commands/ServerToClient/VerifyCommand.js +0 -88
  312. package/esm2015/src/communications/InteractiveCommunicationsFailureHandler.js +0 -20
  313. package/esm2015/src/data/DataView.js +0 -1693
  314. package/esm2015/src/data/DataviewManager.js +0 -31
  315. package/esm2015/src/data/DataviewManagerBase.js +0 -18
  316. package/esm2015/src/data/Field.js +0 -672
  317. package/esm2015/src/data/FieldBase.js +0 -9
  318. package/esm2015/src/data/Record.js +0 -914
  319. package/esm2015/src/data/RecordsTable.js +0 -267
  320. package/esm2015/src/data/TaskTransactionManager.js +0 -110
  321. package/esm2015/src/data/XMLBasedDcValuesBuilder.js +0 -74
  322. package/esm2015/src/env/EnvVariablesTable.js +0 -408
  323. package/esm2015/src/env/Environment.js +0 -563
  324. package/esm2015/src/env/LanguageData.js +0 -230
  325. package/esm2015/src/event/Event.js +0 -1449
  326. package/esm2015/src/event/EventHandler.js +0 -787
  327. package/esm2015/src/event/EventHandlerPosition.js +0 -201
  328. package/esm2015/src/event/EventsManager.js +0 -3107
  329. package/esm2015/src/event/IEventsManager.js +0 -7
  330. package/esm2015/src/event/RunTimeEvent.js +0 -406
  331. package/esm2015/src/exp/Expression.js +0 -209
  332. package/esm2015/src/exp/ExpressionEvaluator.js +0 -4441
  333. package/esm2015/src/exp/ExpressionLocalJpn.js +0 -314
  334. package/esm2015/src/exp/GlobalParamsTable.js +0 -84
  335. package/esm2015/src/exp/YesNoExp.js +0 -44
  336. package/esm2015/src/gui/FormsTable.js +0 -73
  337. package/esm2015/src/gui/MgControl.js +0 -438
  338. package/esm2015/src/gui/MgForm.js +0 -1292
  339. package/esm2015/src/http/HttpManager.js +0 -100
  340. package/esm2015/src/http/client/HttpClientAsync.js +0 -72
  341. package/esm2015/src/http/client/HttpClientBase.js +0 -148
  342. package/esm2015/src/http/client/HttpClientSync.js +0 -47
  343. package/esm2015/src/remote/AddUserLocateRemoteDataViewCommand.js +0 -21
  344. package/esm2015/src/remote/AddUserRangeRemoteDataViewCommand.js +0 -21
  345. package/esm2015/src/remote/AddUserSortRemoteDataViewCommand.js +0 -21
  346. package/esm2015/src/remote/RemoteCommandsProcessor.js +0 -903
  347. package/esm2015/src/remote/RemoteControlItemsRefreshCommand.js +0 -28
  348. package/esm2015/src/remote/RemoteDataViewCommandBase.js +0 -27
  349. package/esm2015/src/remote/RemoteDataViewCommandUpdateNonModifiable.js +0 -19
  350. package/esm2015/src/remote/RemoteDataviewManager.js +0 -23
  351. package/esm2015/src/remote/RemoteInitDataViewCommand.js +0 -14
  352. package/esm2015/src/remote/ResetUserLocateRemoteDataviewCommand.js +0 -20
  353. package/esm2015/src/remote/ResetUserRangeRemoteDataviewCommand.js +0 -16
  354. package/esm2015/src/remote/ResetUserSortRemoteDataviewCommand.js +0 -19
  355. package/esm2015/src/remote/ServerError.js +0 -45
  356. package/esm2015/src/rt/Argument.js +0 -281
  357. package/esm2015/src/rt/ArgumentsList.js +0 -108
  358. package/esm2015/src/rt/Boundary.js +0 -161
  359. package/esm2015/src/rt/DataviewHeaderBase.js +0 -96
  360. package/esm2015/src/rt/DataviewHeaderFactory.js +0 -7
  361. package/esm2015/src/rt/DataviewHeadersSaxHandler.js +0 -40
  362. package/esm2015/src/rt/Operation.js +0 -769
  363. package/esm2015/src/rt/Recompute.js +0 -372
  364. package/esm2015/src/rt/RemoteDataviewHeader.js +0 -114
  365. package/esm2015/src/rt/TableCache.js +0 -182
  366. package/esm2015/src/rt/TableCacheManager.js +0 -70
  367. package/esm2015/src/rt/Transaction.js +0 -54
  368. package/esm2015/src/tasks/MGData.js +0 -561
  369. package/esm2015/src/tasks/MGDataCollection.js +0 -270
  370. package/esm2015/src/tasks/RemoteTaskService.js +0 -45
  371. package/esm2015/src/tasks/Task.js +0 -2593
  372. package/esm2015/src/tasks/TaskServiceBase.js +0 -30
  373. package/esm2015/src/tasks/TasksTable.js +0 -87
  374. package/esm2015/src/tasks/sort/SortCollection.js +0 -72
  375. package/esm2015/src/util/MgPriorityBlockingQueue.js +0 -79
  376. package/esm2015/src/util/PrmMap.js +0 -157
  377. package/esm2015/src/util/Process.js +0 -7
  378. package/esm2015/src/util/ReturnResult.js +0 -46
  379. package/fesm2015/magic-xpa-engine.js.map +0 -1
@@ -0,0 +1,872 @@
1
+ import { Base64, JSON_Utils, Logger, Logger_LogLevels, Misc, MsgInterface, OSEnvironment, RequestInfo, StrUtil, XMLConstants } from "@magic-xpa/utils";
2
+ import { Debug, Encoding, Exception, List, NString, RefParam, StringBuilder, isNullOrUndefined, isUndefined } from "@magic-xpa/mscorelib";
3
+ import { Commands, RuntimeContextBase, Styles, UsernamePasswordCredentials } from "@magic-xpa/gui";
4
+ import { ExecOperCommand } from '../commands/ClientToServer/ExecOperCommand';
5
+ import { CommandsProcessorBase, CommandsProcessorBase_SendingInstruction, CommandsProcessorBase_SessionStage } from "../CommandsProcessorBase";
6
+ import { HttpManager } from "../http/HttpManager";
7
+ import { ConstInterface } from "../ConstInterface";
8
+ import { Scrambler } from "../util/Scrambler";
9
+ import { ServerError } from "./ServerError";
10
+ import { FlowMonitorQueue } from "../util/FlowMonitorQueue";
11
+ import { OpeningTaskDetails } from "../tasks/TaskBase";
12
+ import { HttpUtility } from "../http/client/HttpUtility";
13
+ import { HttpClientEvents } from "../http/client/HttpClientEvents";
14
+ import { ServerConfig } from "../ServerConfig";
15
+ import { AccessHelper } from "../AccessHelper";
16
+ import { Environment, Event, EventCommand, EventsManager, GUIManager } from "../../";
17
+ import { MGDataCollection } from "../tasks/MGDataCollection";
18
+ import { timer } from "rxjs";
19
+ var RequestStatus;
20
+ (function (RequestStatus) {
21
+ RequestStatus[RequestStatus["Handled"] = 0] = "Handled";
22
+ RequestStatus[RequestStatus["Retry"] = 1] = "Retry";
23
+ RequestStatus[RequestStatus["Abort"] = 2] = "Abort";
24
+ })(RequestStatus || (RequestStatus = {}));
25
+ export class RemoteCommandsProcessor extends CommandsProcessorBase {
26
+ constructor() {
27
+ super();
28
+ this._lastRequestTime = 0;
29
+ this.ServerUrl = null;
30
+ this.DelayCommandExecution = false;
31
+ this._requestInfo = new RequestInfo();
32
+ this.ServerUrl = ServerConfig.Instance.getServerURL();
33
+ HttpManager.GetInstance();
34
+ this.RegisterDelegates();
35
+ }
36
+ static GetInstance() {
37
+ if (RemoteCommandsProcessor._instance === null) {
38
+ RemoteCommandsProcessor._instance = new RemoteCommandsProcessor();
39
+ }
40
+ return RemoteCommandsProcessor._instance;
41
+ }
42
+ CheckAndSetSessionCounter(newSessionCounter) {
43
+ if (newSessionCounter === ConstInterface.SESSION_COUNTER_CLOSE_CTX_INDICATION) {
44
+ Debug.Assert(this.GetSessionCounter() === ConstInterface.SESSION_COUNTER_CLOSE_CTX_INDICATION);
45
+ }
46
+ else {
47
+ Debug.Assert(newSessionCounter === this.GetSessionCounter() + 1);
48
+ this.SetSessionCounter(newSessionCounter);
49
+ Logger.Instance.WriteServerToLog(NString.Format("Session Counter --> {0}", this._sessionCounter));
50
+ }
51
+ }
52
+ ClearSessionCounter() {
53
+ this._sessionCounter = 0;
54
+ Logger.Instance.WriteServerToLog(NString.Format("Session Counter --> {0}", this._sessionCounter));
55
+ }
56
+ SetSessionCounter(newSessionCounter) {
57
+ this._sessionCounter = newSessionCounter;
58
+ }
59
+ get GetLastRequestTime() {
60
+ return this._lastRequestTime;
61
+ }
62
+ async ReStartSession() {
63
+ RemoteCommandsProcessor.IsSessionReInitializing = true;
64
+ await this.StoreSessionReInitializingDataOnLocalStorage();
65
+ let navigateRootRoute = false;
66
+ if (!RuntimeContextBase.Instance.RemovedContextFromServer)
67
+ navigateRootRoute = Environment.Instance.getSpecialRouteToRootProgOnContextRecreation() ? true : false;
68
+ Commands.addRefreshPage(navigateRootRoute, RemoteCommandsProcessor.InitialUrl);
69
+ throw new Exception('');
70
+ }
71
+ async StoreSessionReInitializingDataOnLocalStorage() {
72
+ let mainPrgViewStringForServer = await this.BuildXMLForMainProgramDataView();
73
+ let globalParamsString = AccessHelper.globalParams.mirrorAllToXML();
74
+ let dataStorage = window.localStorage;
75
+ dataStorage.setItem(ConstInterface.IS_SESSION_REINITIALIZING, "true");
76
+ dataStorage.setItem(ConstInterface.MAIN_PROG_VIEW, mainPrgViewStringForServer.toString());
77
+ dataStorage.setItem(ConstInterface.GLOBAL_PARAM_LIST, globalParamsString);
78
+ dataStorage.setItem(ConstInterface.LAST_EXCEPTION, RemoteCommandsProcessor.lastExceptionMessage);
79
+ if (RuntimeContextBase.Instance.RemovedContextFromServer)
80
+ dataStorage.setItem(ConstInterface.CTX_REMOVED_FROM_SRVR, "1");
81
+ EventsManager.Instance.storeLastSavedRouteEventOnLocalStorage();
82
+ }
83
+ RestoreSessionReInitializingDataFromLocalStorage(key) {
84
+ let dataStorage = window.localStorage;
85
+ let val = dataStorage.getItem(key);
86
+ return val;
87
+ }
88
+ async StartSession() {
89
+ let authenticationCancelled = false;
90
+ let handshakeResponse = null;
91
+ let dialog = null;
92
+ try {
93
+ let lastTypedUserId = null;
94
+ let handshakeInitialTokens = new StringBuilder();
95
+ handshakeInitialTokens.Append(ConstInterface.UTF8TRANS +
96
+ ConstInterface.REQ_APP_NAME + "=" +
97
+ HttpUtility.UrlEncode(ServerConfig.Instance.getAppName(), Encoding.UTF8));
98
+ handshakeInitialTokens.Append("&" + ConstInterface.REQ_ARGS + "=" + ConstInterface.REQ_ARG_ALPHA +
99
+ "<Richclient><Requires EncryptionKey=\"False\"/><RIAProtocolVersion=\"" + RemoteCommandsProcessor.WEB_COMMUNICATION_PROTOCOL_VERSION + "\"/></Richclient>");
100
+ Logger.Instance.WriteDevToLog(NString.Format("Handshake request #1 (not scrambled) : {0}", this.ServerUrl + ConstInterface.REQ_ARG_START +
101
+ ConstInterface.RC_INDICATION_INITIAL + handshakeInitialTokens));
102
+ let handshakeInitialUrl = this.ServerUrl + ConstInterface.REQ_ARG_START +
103
+ ConstInterface.RC_INDICATION_INITIAL +
104
+ ConstInterface.RC_TOKEN_DATA +
105
+ HttpUtility.UrlEncode(Scrambler.Scramble(handshakeInitialTokens.ToString()), Encoding.UTF8);
106
+ Logger.Instance.WriteServerMessagesToLog("");
107
+ Logger.Instance.WriteServerMessagesToLog(NString.Format("Handshake request #1: {0}", handshakeInitialUrl));
108
+ let ctxGroup = ServerConfig.Instance.getCtxGroup();
109
+ while (!authenticationCancelled) {
110
+ let requestStatus = new RefParam(RequestStatus.Handled);
111
+ let responseStr = await this.DispatchRequest(handshakeInitialUrl, null, CommandsProcessorBase_SessionStage.HANDSHAKE, requestStatus);
112
+ if (NString.IsNullOrEmpty(responseStr)) {
113
+ throw new ServerError("Client failed to initialize a session." + OSEnvironment.EolSeq +
114
+ "Empty response was received from the web server." + OSEnvironment.EolSeq + OSEnvironment.EolSeq + this.ServerUrl);
115
+ }
116
+ Logger.Instance.WriteServerMessagesToLog(NString.Format("Handshake response #1: {0}", responseStr));
117
+ Logger.Instance.WriteServerMessagesToLog("");
118
+ handshakeResponse = new HandshakeResponse(responseStr);
119
+ RuntimeContextBase.Instance.ContextID = handshakeResponse.ContextId;
120
+ this.SessionId = handshakeResponse.GetSessionId;
121
+ HttpManager.GetInstance().HttpCommunicationTimeoutMS = handshakeResponse.HttpTimeout * 1000;
122
+ if (NString.IsNullOrEmpty(ServerConfig.Instance.getCtxGroup())) {
123
+ ctxGroup = handshakeResponse.ContextId;
124
+ }
125
+ let credentials = null;
126
+ if (ServerConfig.Instance.getSkipAuthenticationDialog()) {
127
+ if (ServerConfig.Instance.getUsername() !== null) {
128
+ credentials = new UsernamePasswordCredentials(ServerConfig.Instance.getUsername(), ServerConfig.Instance.getPassword());
129
+ ServerConfig.Instance.setUsername("");
130
+ ServerConfig.Instance.setPassword("");
131
+ }
132
+ }
133
+ else if (handshakeResponse.InputPassword && handshakeResponse.SystemLogin !== HandshakeResponse.SYSTEM_LOGIN_AD) {
134
+ if (lastTypedUserId !== null) {
135
+ let title = AccessHelper.languageData.getConstMessage(MsgInterface.BRKTAB_STR_ERROR);
136
+ let error = AccessHelper.languageData.getConstMessage(MsgInterface.USRINP_STR_BADPASSW);
137
+ await GUIManager.Instance.MessageBox(title, error, Styles.MSGBOX_ICON_ERROR | Styles.MSGBOX_BUTTON_OK);
138
+ }
139
+ }
140
+ if (authenticationCancelled) {
141
+ this.SetSessionCounter(ConstInterface.SESSION_COUNTER_CLOSE_CTX_INDICATION);
142
+ }
143
+ let handshakeAuthUrl = this.PrepareAuthenticationUrl(handshakeResponse.ContextId, ctxGroup, this.GetSessionCounter());
144
+ try {
145
+ if (credentials !== null) {
146
+ let credentialsStr = credentials.Username + ":";
147
+ if (!NString.IsNullOrEmpty(credentials.Password)) {
148
+ credentialsStr = credentialsStr + credentials.Password + ":";
149
+ }
150
+ credentialsStr += handshakeResponse.ContextId;
151
+ credentialsStr = Scrambler.Scramble(credentialsStr);
152
+ credentialsStr = Base64.encode(credentialsStr, true, Encoding.UTF8);
153
+ handshakeAuthUrl += ("&USERNAME=" + HttpUtility.UrlEncode(credentialsStr, Encoding.UTF8));
154
+ Logger.Instance.WriteServerMessagesToLog(NString.Format("Handshake request #2: {0}", handshakeAuthUrl));
155
+ let statusRequest = new RefParam(RequestStatus.Handled);
156
+ responseStr = await this.DispatchRequest(handshakeAuthUrl, null, CommandsProcessorBase_SessionStage.HANDSHAKE, statusRequest);
157
+ if (responseStr.indexOf(handshakeResponse.ContextId) === -1) {
158
+ throw new ServerError(AccessHelper.languageData.getConstMessage(MsgInterface.USRINP_STR_BADPASSW));
159
+ }
160
+ ServerConfig.Instance.setUsername(credentials.Username);
161
+ ServerConfig.Instance.setPassword(credentials.Password);
162
+ }
163
+ else {
164
+ let requestStatus = new RefParam(RequestStatus.Handled);
165
+ Logger.Instance.WriteServerMessagesToLog(NString.Format("Handshake request #2: {0}", handshakeAuthUrl));
166
+ responseStr = await this.DispatchRequest(handshakeAuthUrl, null, CommandsProcessorBase_SessionStage.HANDSHAKE, requestStatus);
167
+ }
168
+ Logger.Instance.WriteServerMessagesToLog(NString.Format("Handshake response #2: {0}", responseStr));
169
+ Logger.Instance.WriteServerMessagesToLog("");
170
+ break;
171
+ }
172
+ catch (ex) {
173
+ if (ex instanceof ServerError) {
174
+ let serverError = ex;
175
+ if (ServerConfig.Instance.getSkipAuthenticationDialog()) {
176
+ switch (serverError.GetCode()) {
177
+ case ServerError.ERR_ACCESS_DENIED:
178
+ case ServerError.ERR_AUTHENTICATION:
179
+ ServerConfig.Instance.setSkipAuthenticationDialog(false);
180
+ throw serverError;
181
+ }
182
+ }
183
+ if (!handshakeResponse.InputPassword)
184
+ throw serverError;
185
+ if (serverError.GetCode() !== ServerError.ERR_AUTHENTICATION &&
186
+ (!authenticationCancelled || serverError.GetCode() !== ServerError.INF_NO_RESULT)) {
187
+ throw serverError;
188
+ }
189
+ }
190
+ else
191
+ throw ex;
192
+ }
193
+ }
194
+ ServerConfig.Instance.setSkipAuthenticationDialog(true);
195
+ ServerConfig.Instance.setCtxGroup(ctxGroup);
196
+ if (dialog !== null)
197
+ dialog.closeDialog();
198
+ RemoteCommandsProcessor.ShouldScrambleAndUnscrambleMessages = handshakeResponse.ScrambleMessages;
199
+ if (Logger.Instance.LogLevel !== Logger_LogLevels.Basic) {
200
+ let maxInternalLogLevel = handshakeResponse.MaxInternalLogLevel;
201
+ if (maxInternalLogLevel !== null) {
202
+ let maxLogLevel = this.parseLogLevel(maxInternalLogLevel);
203
+ if (maxLogLevel < Logger.Instance.LogLevel) {
204
+ ServerConfig.Instance.setInternalLogLevel(maxInternalLogLevel);
205
+ Logger.Instance.WriteToLog(NString.Format("Internal log level was restricted to '{0}' by the Magic xpa server.", maxInternalLogLevel), false);
206
+ Logger.Instance.LogLevel = maxLogLevel;
207
+ }
208
+ }
209
+ }
210
+ if (!authenticationCancelled) {
211
+ await this.ExecuteInitialRequest();
212
+ }
213
+ }
214
+ catch (ex) {
215
+ if (ex instanceof ServerError)
216
+ throw ex;
217
+ if (isNullOrUndefined(ex.InnerException))
218
+ throw new ServerError(ex.message, new Exception(ex));
219
+ else
220
+ throw new ServerError(ex.message, ex.InnerException);
221
+ }
222
+ return !authenticationCancelled;
223
+ }
224
+ PrepareAuthenticationUrl(contextId, ctxGroup, sessionCount) {
225
+ let handshakeAuthUrl = this.ServerUrl + ConstInterface.REQ_ARG_START +
226
+ ConstInterface.RC_INDICATION + ConstInterface.UTF8TRANS +
227
+ ConstInterface.RC_TOKEN_CTX_ID + contextId;
228
+ if (!isNullOrUndefined(this.SessionId))
229
+ handshakeAuthUrl += (ConstInterface.REQ_ARG_SEPARATOR + ConstInterface.RC_TOKEN_SESSION_ID + this.SessionId);
230
+ handshakeAuthUrl += (ConstInterface.REQ_ARG_SEPARATOR +
231
+ ConstInterface.RC_TOKEN_SESSION_COUNT + sessionCount +
232
+ ConstInterface.REQ_ARG_SEPARATOR +
233
+ ConstInterface.RC_TOKEN_CTX_GROUP + ctxGroup +
234
+ ConstInterface.REQ_ARG_SEPARATOR +
235
+ ConstInterface.RC_AUTHENTICATION_REQUEST);
236
+ return handshakeAuthUrl;
237
+ }
238
+ async ExecuteInitialRequest() {
239
+ await this.Execute_1(CommandsProcessorBase_SendingInstruction.TASKS_AND_COMMANDS, CommandsProcessorBase_SessionStage.INITIAL, null);
240
+ }
241
+ GetTaskTree(task) {
242
+ let taskTree = new List();
243
+ while (!isNullOrUndefined(task)) {
244
+ taskTree.push(task.getTaskInfo());
245
+ task = task.getParent();
246
+ }
247
+ return taskTree;
248
+ }
249
+ async UpdateRequestInfo() {
250
+ let currMGData = AccessHelper.mgDataTable.getCurrMGData();
251
+ let eventsManager = AccessHelper.eventsManager;
252
+ let operExecution = false;
253
+ let cmdsToServer = currMGData.CmdsToServer;
254
+ for (let i = 0; i < cmdsToServer.getSize(); i++) {
255
+ if (cmdsToServer.getCmd(i) instanceof ExecOperCommand) {
256
+ let operCmd = currMGData.CmdsToServer.getCmd(i);
257
+ this._requestInfo.serverCallAt = operCmd.getCommandInfo();
258
+ this._requestInfo.runtimeTaskTree = this.GetTaskTree(operCmd.getTask());
259
+ operExecution = true;
260
+ break;
261
+ }
262
+ }
263
+ this._requestInfo.extraInfo.contextID = RuntimeContextBase.Instance.ContextID;
264
+ this._requestInfo.extraInfo.sessionCounter = this.GetSessionCounter();
265
+ if (!operExecution) {
266
+ if (eventsManager.getLastRtEvent() != null && eventsManager.getLastRtEvent().InternalEvent != 0) {
267
+ let rtEvt = eventsManager.getLastRtEvent();
268
+ this._requestInfo.runtimeTaskTree = this.GetTaskTree(rtEvt.getTask());
269
+ let eventDescription = rtEvt.isNewInternalEvent()
270
+ ? NString.TrimEnd(rtEvt.getNewInternalEventDescription())
271
+ : Event.getInternalEvtDescription(rtEvt.InternalEvent);
272
+ let cmd = cmdsToServer.getCmd(cmdsToServer.getSize() - 1);
273
+ if (cmd) {
274
+ let commandInfo = NString.IsNullOrEmpty(cmd.getCommandInfo())
275
+ ? NString.Empty
276
+ : cmd.getCommandInfo();
277
+ if (cmd instanceof EventCommand && rtEvt.InternalEvent == cmd.MagicEvent)
278
+ eventDescription = NString.Empty;
279
+ this._requestInfo.serverCallAt = 'Event ' + commandInfo +
280
+ (!NString.IsNullOrEmpty(eventDescription)
281
+ ? NString.Format(' while executing [{0}]', eventDescription)
282
+ : NString.Empty);
283
+ }
284
+ }
285
+ }
286
+ }
287
+ async BuildXMLForMainProgramDataView() {
288
+ let message = new StringBuilder();
289
+ let firstMgData = MGDataCollection.Instance.getMGData(0);
290
+ let mainPrg = firstMgData.getMainProg(0);
291
+ while (mainPrg != null) {
292
+ await mainPrg.buildXML(message);
293
+ mainPrg = firstMgData.getNextMainProg(mainPrg.getCtlIdx());
294
+ }
295
+ if (RemoteCommandsProcessor.ShouldScrambleAndUnscrambleMessages) {
296
+ let scrambledChanges = Scrambler.Scramble(message.ToString());
297
+ message = new StringBuilder(scrambledChanges);
298
+ }
299
+ message.Insert(0, XMLConstants.MG_TAG_OPEN);
300
+ message.Append(XMLConstants.MG_TAG_XML_END_TAGGED);
301
+ return message.ToString();
302
+ }
303
+ async Execute_1(sendingInstruction, sessionStage, res) {
304
+ let reqBuf;
305
+ let isInitialCall = sessionStage === CommandsProcessorBase_SessionStage.INITIAL;
306
+ let globalParamsString = null;
307
+ if (this.DelayCommandExecution)
308
+ return;
309
+ if (Logger.Instance.LogLevel == Logger_LogLevels.RequestInfo && !isInitialCall)
310
+ await this.UpdateRequestInfo();
311
+ if (isInitialCall) {
312
+ let val = this.RestoreSessionReInitializingDataFromLocalStorage(ConstInterface.IS_SESSION_REINITIALIZING);
313
+ if (val === 'true') {
314
+ RemoteCommandsProcessor.IsSessionReInitializing = (val === "true") ? true : false;
315
+ RemoteCommandsProcessor.lastExceptionMessage = this.RestoreSessionReInitializingDataFromLocalStorage(ConstInterface.LAST_EXCEPTION);
316
+ let ctxRemoved = this.RestoreSessionReInitializingDataFromLocalStorage(ConstInterface.CTX_REMOVED_FROM_SRVR);
317
+ if (ctxRemoved !== '1') {
318
+ Logger.Instance.WriteErrorToLog(RemoteCommandsProcessor.lastExceptionMessage);
319
+ Logger.Instance.WriteToLog("Session is reinitializing...", true);
320
+ }
321
+ }
322
+ }
323
+ if (sendingInstruction === CommandsProcessorBase_SendingInstruction.NO_TASKS_OR_COMMANDS)
324
+ reqBuf = null;
325
+ else {
326
+ reqBuf = await this.PrepareRequest(sendingInstruction === CommandsProcessorBase_SendingInstruction.TASKS_AND_COMMANDS);
327
+ if (RemoteCommandsProcessor.IsSessionReInitializing || !isInitialCall) {
328
+ let changes = new StringBuilder();
329
+ let buffer = new StringBuilder();
330
+ if (!RemoteCommandsProcessor.IsSessionReInitializing)
331
+ buffer.Append(reqBuf);
332
+ if (RemoteCommandsProcessor.IsSessionReInitializing)
333
+ globalParamsString = this.RestoreSessionReInitializingDataFromLocalStorage(ConstInterface.GLOBAL_PARAM_LIST);
334
+ else
335
+ globalParamsString = AccessHelper.globalParams.mirrorToXML();
336
+ changes.Append(globalParamsString);
337
+ changes.Append(AccessHelper.envParamsTable.mirrorToXML());
338
+ if (changes.Length > 0) {
339
+ changes.Insert(0, "<" + ConstInterface.MG_TAG_ENV_CHANGES + ">");
340
+ changes.Append("</" + ConstInterface.MG_TAG_ENV_CHANGES + ">");
341
+ if (RemoteCommandsProcessor.ShouldScrambleAndUnscrambleMessages) {
342
+ let scrambledChanges = Scrambler.Scramble(changes.ToString());
343
+ changes = new StringBuilder(scrambledChanges);
344
+ }
345
+ changes.Insert(0, XMLConstants.MG_TAG_OPEN);
346
+ changes.Append(XMLConstants.MG_TAG_XML_END_TAGGED);
347
+ buffer.Append(changes.ToString());
348
+ }
349
+ reqBuf = buffer.ToString();
350
+ }
351
+ }
352
+ let requestStatus = new RefParam(RequestStatus.Handled);
353
+ let respBuf = null;
354
+ if (RemoteCommandsProcessor.IsSessionReInitializing) {
355
+ reqBuf = reqBuf + this.RestoreSessionReInitializingDataFromLocalStorage(ConstInterface.MAIN_PROG_VIEW);
356
+ }
357
+ if (RuntimeContextBase.Instance.RemovedContextFromServer)
358
+ requestStatus.value = RequestStatus.Retry;
359
+ else {
360
+ if (RuntimeContextBase.Instance.RemovingContextFromServer)
361
+ RuntimeContextBase.Instance.RemovedContextFromServer = true;
362
+ respBuf = await this.DispatchRequest(this.ServerUrl, reqBuf, sessionStage, requestStatus);
363
+ }
364
+ if (requestStatus.value == RequestStatus.Retry) {
365
+ await this.ReStartSession();
366
+ }
367
+ if (respBuf == null)
368
+ return;
369
+ if (isInitialCall) {
370
+ RemoteCommandsProcessor.InitialUrl = window.location.href;
371
+ if (RemoteCommandsProcessor.IsSessionReInitializing) {
372
+ let dataStorage = window.localStorage;
373
+ dataStorage.removeItem(ConstInterface.IS_SESSION_REINITIALIZING);
374
+ dataStorage.removeItem(ConstInterface.MAIN_PROG_VIEW);
375
+ dataStorage.removeItem(ConstInterface.GLOBAL_PARAM_LIST);
376
+ dataStorage.removeItem(ConstInterface.LAST_EXCEPTION);
377
+ }
378
+ }
379
+ FlowMonitorQueue.Instance.enable(false);
380
+ await this.ProcessResponse(respBuf, AccessHelper.mgDataTable.currMgdID, null, res);
381
+ if (RemoteCommandsProcessor.IsSessionReInitializing) {
382
+ AccessHelper.globalParams.RestoreGlobalParams(globalParamsString);
383
+ let dataStorage = window.localStorage;
384
+ let ctxRemoved = dataStorage.getItem(ConstInterface.CTX_REMOVED_FROM_SRVR);
385
+ if (ctxRemoved === "1") {
386
+ EventsManager.Instance.restoreLastSavedRouteEventFromLocalStorage();
387
+ dataStorage.removeItem(ConstInterface.CTX_REMOVED_FROM_SRVR);
388
+ dataStorage.removeItem(ConstInterface.LAST_ROUTE_EVENT);
389
+ dataStorage.removeItem(ConstInterface.LAST_ROUTE_EVENT_SRC_TSK);
390
+ dataStorage.removeItem(ConstInterface.LAST_ROUTE_EVENT_ARG_LIST);
391
+ }
392
+ RemoteCommandsProcessor.IsSessionReInitializing = false;
393
+ }
394
+ if (sendingInstruction === CommandsProcessorBase_SendingInstruction.TASKS_AND_COMMANDS) {
395
+ AccessHelper.mgDataTable.startTasksIteration();
396
+ let task;
397
+ while ((task = AccessHelper.mgDataTable.getNextTask()) !== null) {
398
+ let dataViewWasRetrieved = task.DataViewWasRetrieved;
399
+ if (dataViewWasRetrieved) {
400
+ await task.RefreshDisplay();
401
+ }
402
+ }
403
+ }
404
+ if (isInitialCall)
405
+ ServerConfig.Instance.setGlobalParams(null);
406
+ }
407
+ async DispatchRequest(url, reqBuf, sessionStage, requestStatus) {
408
+ let response = null;
409
+ let encodedBody = null;
410
+ requestStatus.value = RequestStatus.Handled;
411
+ if (url === null) {
412
+ Logger.Instance.WriteExceptionToLogWithMsg("in sendMsgToSrvr() unknown server");
413
+ return response;
414
+ }
415
+ if (sessionStage !== CommandsProcessorBase_SessionStage.HANDSHAKE) {
416
+ let urlSuffix = this.BuildUrlSuffix(reqBuf !== null, sessionStage === CommandsProcessorBase_SessionStage.INITIAL);
417
+ let reqBufEncoded = HttpUtility.UrlEncode(reqBuf, Encoding.UTF8);
418
+ encodedBody = urlSuffix + reqBufEncoded;
419
+ }
420
+ try {
421
+ if (Logger.Instance.ShouldLogExtendedServerRelatedMessages())
422
+ Logger.Instance.WriteServerMessagesToLog(NString.Format("MESSAGE TO SERVER:\n URL: {0}\n BODY: {1}", url, encodedBody));
423
+ response = await this.ExecuteRequest(url, encodedBody);
424
+ if (!response.toUpperCase().startsWith("<HTML")) {
425
+ let startIdx = response.indexOf("<xml id=\"MGDATA\">");
426
+ if (startIdx > 0)
427
+ response = response.substr(startIdx);
428
+ }
429
+ Logger.Instance.WriteServerMessagesToLog("MESSAGE FROM SERVER: " + response);
430
+ if (sessionStage === CommandsProcessorBase_SessionStage.HANDSHAKE ||
431
+ (response.length > 0 &&
432
+ RemoteCommandsProcessor.ShouldScrambleAndUnscrambleMessages && response !== "<xml id=\"MGDATA\">\n</xml>")) {
433
+ if (sessionStage === CommandsProcessorBase_SessionStage.HANDSHAKE) {
434
+ Debug.Assert(response.length > 0 && response[0] !== '<');
435
+ }
436
+ response = CommandsProcessorBase.UnScramble(response);
437
+ }
438
+ Logger.Instance.WriteDevToLog("MESSAGE FROM SERVER: (size = " + response.length + ")" + OSEnvironment.EolSeq + response);
439
+ this._lastRequestTime = Misc.getSystemMilliseconds();
440
+ }
441
+ catch (ex) {
442
+ if (ex instanceof ServerError) {
443
+ requestStatus.value = RequestStatus.Abort;
444
+ if (sessionStage == CommandsProcessorBase_SessionStage.NORMAL) {
445
+ if (ex.GetCode() == ServerError.ERR_CTX_NOT_FOUND || ex.GetCode() == ServerError.ERR_THREAD_ABORTED) {
446
+ if (RuntimeContextBase.Instance.RemovedContextFromServer) {
447
+ requestStatus.value = RequestStatus.Retry;
448
+ }
449
+ else {
450
+ switch (Environment.Instance.getWebClientReinitSession()) {
451
+ case 'Y':
452
+ requestStatus.value = RequestStatus.Retry;
453
+ break;
454
+ case 'A':
455
+ let retval = await GUIManager.Instance.MessageBox("Error", "Unknown error occurred at server-side." +
456
+ " Would you like to reinitialize the session?", Styles.MSGBOX_BUTTON_YES_NO);
457
+ requestStatus.value = (retval == Styles.MSGBOX_RESULT_YES) ? RequestStatus.Retry : RequestStatus.Abort;
458
+ break;
459
+ case 'N':
460
+ default:
461
+ requestStatus.value = RequestStatus.Abort;
462
+ break;
463
+ }
464
+ }
465
+ if (requestStatus.value == RequestStatus.Abort) {
466
+ Environment.Instance.setWebClientReinitSession('N');
467
+ throw ex;
468
+ }
469
+ else {
470
+ let errForConsole = StrUtil.getConsoleErorString(ex.GetMessage());
471
+ RemoteCommandsProcessor.lastExceptionMessage = "Exception Occured at server side : " + ex.GetCode().toString() + " : " + errForConsole;
472
+ console.log(RemoteCommandsProcessor.lastExceptionMessage);
473
+ }
474
+ return null;
475
+ }
476
+ }
477
+ }
478
+ window.localStorage.clear();
479
+ throw ex;
480
+ }
481
+ return response;
482
+ }
483
+ HandleErrorResponse(response) {
484
+ try {
485
+ Logger.Instance.WriteServerMessagesToLog("MESSAGE FROM SERVER: " + response);
486
+ response = CommandsProcessorBase.UnScramble(response);
487
+ Logger.Instance.WriteServerMessagesToLog("MESSAGE FROM SERVER: " + StrUtil.getConsoleErorString(response));
488
+ }
489
+ catch (ex) {
490
+ }
491
+ if (response.startsWith("<xmlerr")) {
492
+ let errorMessageXml = new ErrorMessageXml(response, this._lastRequestTime, AccessHelper.environment.getContextInactivityTimeout());
493
+ throw new ServerError(errorMessageXml.GetMessage(), errorMessageXml.GetCode());
494
+ }
495
+ else if (response.toUpperCase().startsWith("<HTML")) {
496
+ throw new ServerError(response);
497
+ }
498
+ }
499
+ async ExecuteRequest(url, encodedBody) {
500
+ return await this.GetContent(url, false, encodedBody);
501
+ }
502
+ async GetContent(requestedURL, useCache, requestContent) {
503
+ if (isUndefined(requestContent))
504
+ requestContent = null;
505
+ let responseStr;
506
+ try {
507
+ if (requestedURL.startsWith("/"))
508
+ requestedURL = ServerConfig.Instance.getProtocol() + "://" + ServerConfig.Instance.getServer() + requestedURL;
509
+ var spinnerTimer = timer(50, 50);
510
+ var spinnerTimerSubscription = spinnerTimer.subscribe(() => {
511
+ AccessHelper.eventsManager.CheckAndShowSpinner(true);
512
+ });
513
+ let isError = new RefParam(false);
514
+ RemoteCommandsProcessor.requestNumber++;
515
+ responseStr = await HttpManager.GetInstance().GetContent(requestedURL, requestContent, useCache, isError);
516
+ RemoteCommandsProcessor.totalResponseDataLength += RemoteCommandsProcessor.totalResponseDataLength + (!isNullOrUndefined(responseStr) ? responseStr.length : 0);
517
+ spinnerTimerSubscription.unsubscribe();
518
+ spinnerTimerSubscription = null;
519
+ if (isError.value) {
520
+ this.HandleErrorResponse(responseStr);
521
+ }
522
+ }
523
+ catch (ex) {
524
+ if (!(ex instanceof ServerError) || Logger.Instance.LogLevel !== Logger_LogLevels.Basic) {
525
+ Logger.Instance.WriteExceptionToLog(ex, NString.Format("requested URL = \"{0}\"", requestedURL));
526
+ }
527
+ if (!(ex instanceof ServerError)) {
528
+ ex = new ServerError(ex.Message, ex.InnerException ? ex.InnerException : ex);
529
+ }
530
+ throw ex;
531
+ }
532
+ finally {
533
+ if (spinnerTimerSubscription != null)
534
+ spinnerTimerSubscription.unsubscribe();
535
+ }
536
+ return responseStr;
537
+ }
538
+ ClientActivated() {
539
+ }
540
+ BuildUrlSuffix(hasContent, isInitialCall) {
541
+ let prefix = ConstInterface.RC_INDICATION + ConstInterface.RC_TOKEN_CTX_ID + RuntimeContextBase.Instance.ContextID;
542
+ if (!isNullOrUndefined(this.SessionId))
543
+ prefix += (ConstInterface.REQ_ARG_SEPARATOR + ConstInterface.RC_TOKEN_SESSION_ID + this.SessionId);
544
+ if (isInitialCall) {
545
+ if (RemoteCommandsProcessor.IsSessionReInitializing)
546
+ prefix += (ConstInterface.REQ_ARG_SEPARATOR + ConstInterface.WEBCLIENT_REINITIALIZE_REQUEST);
547
+ let globalParams = ServerConfig.Instance.getGlobalParams();
548
+ if (globalParams !== null) {
549
+ globalParams = NString.Replace(globalParams, "+", "%2B");
550
+ prefix += ("&" + ConstInterface.MG_TAG_GLOBALPARAMS + "=" + globalParams);
551
+ }
552
+ }
553
+ if (hasContent) {
554
+ prefix += ("&" + ConstInterface.RC_TOKEN_SESSION_COUNT + this.GetSessionCounter() +
555
+ ConstInterface.REQ_ARG_SEPARATOR + ConstInterface.RC_TOKEN_DATA);
556
+ }
557
+ return prefix;
558
+ }
559
+ async SendMonitorOnly() {
560
+ let flowMonitor = FlowMonitorQueue.Instance;
561
+ if (AccessHelper.mgDataTable == null || AccessHelper.mgDataTable.getMGData(0) == null || AccessHelper.mgDataTable.getMGData(0).IsAborting)
562
+ return;
563
+ if (!flowMonitor.isEmpty()) {
564
+ let buffer = this.BuildMonitorMessage();
565
+ let shouldAccumulateClientLog = false;
566
+ if (shouldAccumulateClientLog) {
567
+ }
568
+ else {
569
+ try {
570
+ let requestStatus = new RefParam(RequestStatus.Handled);
571
+ await this.DispatchRequest(this.ServerUrl, buffer.ToString(), CommandsProcessorBase_SessionStage.NORMAL, requestStatus);
572
+ }
573
+ catch (err) {
574
+ }
575
+ }
576
+ }
577
+ }
578
+ BuildMonitorMessage() {
579
+ let buffer = new StringBuilder(1000);
580
+ let flowMonitor = FlowMonitorQueue.Instance;
581
+ if (!RemoteCommandsProcessor.ShouldScrambleAndUnscrambleMessages) {
582
+ buffer.Append(XMLConstants.MG_TAG_OPEN);
583
+ flowMonitor.buildXML(buffer);
584
+ }
585
+ else {
586
+ flowMonitor.buildXML(buffer);
587
+ let scrambledOut = Scrambler.Scramble(buffer.ToString());
588
+ buffer = new StringBuilder(1000);
589
+ buffer.Append(XMLConstants.MG_TAG_OPEN + scrambledOut);
590
+ }
591
+ buffer.Append("</" + XMLConstants.MG_TAG_XML + XMLConstants.TAG_CLOSE);
592
+ return buffer;
593
+ }
594
+ RegisterDelegates() {
595
+ HttpClientEvents.GetSessionCounter_Event = this.GetSessionCounter.bind(this);
596
+ HttpClientEvents.CheckAndSetSessionCounter_Event = this.CheckAndSetSessionCounter.bind(this);
597
+ HttpClientEvents.ComputeAndLogRequestInfo_Event = this.ComputeAndLogRequestInfo.bind(this);
598
+ AccessHelper.eventsManager.SpinnerStopped.subscribe(clientBusyTime => this.ClientActivated());
599
+ }
600
+ ComputeAndLogRequestInfo(contentLength, roundTrip, isLoggingResponse) {
601
+ if (!isNullOrUndefined(this._requestInfo.serverCallAt)) {
602
+ this._requestInfo.extraInfo.contentLength = contentLength;
603
+ this._requestInfo.extraInfo.timeStamp = new Date().toString();
604
+ let extraMessageStr = isLoggingResponse ? 'Response ⤵' : 'Request ⤵';
605
+ if (isLoggingResponse) {
606
+ this._requestInfo.roundtripTime = roundTrip;
607
+ RemoteCommandsProcessor.totalTimeForHTTPRequests += roundTrip;
608
+ }
609
+ else
610
+ RemoteCommandsProcessor.totalRequestDataLength += contentLength;
611
+ Logger.Instance.WriteRequestInfoToLog(this._requestInfo, extraMessageStr);
612
+ if (isLoggingResponse)
613
+ this._requestInfo.clear();
614
+ }
615
+ }
616
+ static set ShouldScrambleAndUnscrambleMessages(value) {
617
+ RemoteCommandsProcessor._shouldScrambleAndUnscrambleMessages = value;
618
+ Logger.Instance.WriteServerMessagesToLog(NString.Format("ShouldScrambleAndUnscrambleMessages.Set: {0}", this._shouldScrambleAndUnscrambleMessages));
619
+ }
620
+ static get ShouldScrambleAndUnscrambleMessages() {
621
+ Logger.Instance.WriteServerMessagesToLog(NString.Format("ShouldScrambleAndUnscrambleMessages.Get: {0}", this._shouldScrambleAndUnscrambleMessages));
622
+ return RemoteCommandsProcessor._shouldScrambleAndUnscrambleMessages;
623
+ }
624
+ parseLogLevel(strLogLevel) {
625
+ let logLevel = Logger_LogLevels.None;
626
+ if (!NString.IsNullOrEmpty(strLogLevel)) {
627
+ if (strLogLevel.toUpperCase().startsWith("SERVER"))
628
+ logLevel = strLogLevel.endsWith("#") ? Logger_LogLevels.ServerMessages : Logger_LogLevels.Server;
629
+ else if (strLogLevel.toUpperCase().startsWith("S") || strLogLevel.toUpperCase().startsWith("Q"))
630
+ logLevel = Logger_LogLevels.Support;
631
+ else if (strLogLevel.toUpperCase().startsWith("G"))
632
+ logLevel = Logger_LogLevels.Gui;
633
+ else if (strLogLevel.toUpperCase().startsWith("D"))
634
+ logLevel = Logger_LogLevels.Development;
635
+ else if (strLogLevel.toUpperCase().startsWith("B"))
636
+ logLevel = Logger_LogLevels.Basic;
637
+ else if (strLogLevel.toUpperCase().startsWith("R"))
638
+ logLevel = Logger_LogLevels.RequestInfo;
639
+ }
640
+ return logLevel;
641
+ }
642
+ async PrepareRequest(serializeTasks) {
643
+ let xmlBuf = new StringBuilder();
644
+ xmlBuf.Append(XMLConstants.MG_TAG_OPEN);
645
+ if (AccessHelper.mgDataTable.getCurrMGData() !== null) {
646
+ let xmlUnscrambled = new StringBuilder();
647
+ await AccessHelper.mgDataTable.buildXML(xmlUnscrambled, serializeTasks);
648
+ if (RemoteCommandsProcessor.ShouldScrambleAndUnscrambleMessages)
649
+ xmlBuf.Append(Scrambler.Scramble(xmlUnscrambled.ToString()));
650
+ else
651
+ xmlBuf.Append(xmlUnscrambled.ToString());
652
+ }
653
+ xmlBuf.Append("</" + XMLConstants.MG_TAG_XML + XMLConstants.TAG_CLOSE);
654
+ return xmlBuf.ToString();
655
+ }
656
+ async ProcessResponse(response, currMgdID, openingTaskDetails, res) {
657
+ Logger.Instance.WriteDevToLog("<-- ProcessResponse started -->");
658
+ if (openingTaskDetails === null)
659
+ openingTaskDetails = new OpeningTaskDetails();
660
+ let systemMilliseconds = Misc.getSystemMilliseconds();
661
+ if (response === null || response.trim().length === 0)
662
+ return;
663
+ AccessHelper.mgDataTable.currMgdID = currMgdID;
664
+ RuntimeContextBase.Instance.Parser.push();
665
+ RuntimeContextBase.Instance.Parser.setXMLdata(response);
666
+ RuntimeContextBase.Instance.Parser.setCurrIndex(0);
667
+ let currMGData = AccessHelper.mgDataTable.getCurrMGData();
668
+ await currMGData.fillData(openingTaskDetails, RuntimeContextBase.Instance.Parser);
669
+ RuntimeContextBase.Instance.Parser.setXMLdata(null);
670
+ RuntimeContextBase.Instance.Parser.pop();
671
+ Logger.Instance.WriteDevToLog("<-- ProcessResponse finished --> (" + (Misc.getSystemMilliseconds() - systemMilliseconds) + ")");
672
+ await currMGData.CmdsToClient.Execute(res);
673
+ await this.ProcessRecovery();
674
+ }
675
+ async ProcessRecovery() {
676
+ AccessHelper.eventsManager.pushNewExecStacks();
677
+ await AccessHelper.mgDataTable.processRecovery();
678
+ AccessHelper.eventsManager.popNewExecStacks();
679
+ }
680
+ }
681
+ RemoteCommandsProcessor.RC_NO_CONTEXT_ID = '-1';
682
+ RemoteCommandsProcessor._instance = null;
683
+ RemoteCommandsProcessor.IsSessionReInitializing = false;
684
+ RemoteCommandsProcessor.lastExceptionMessage = null;
685
+ RemoteCommandsProcessor.InitialUrl = null;
686
+ RemoteCommandsProcessor.requestNumber = 0;
687
+ RemoteCommandsProcessor.totalTimeForHTTPRequests = 0;
688
+ RemoteCommandsProcessor.totalRequestDataLength = 0;
689
+ RemoteCommandsProcessor.totalResponseDataLength = 0;
690
+ RemoteCommandsProcessor.WEB_COMMUNICATION_PROTOCOL_VERSION = "14002";
691
+ RemoteCommandsProcessor._shouldScrambleAndUnscrambleMessages = false;
692
+ class HandshakeResponse {
693
+ constructor(responseXML) {
694
+ this._scrambleMessages = true;
695
+ this._contextId = null;
696
+ this._privateSessionId = null;
697
+ this._inputPassword = false;
698
+ this._httpTimeout = 0;
699
+ this._systemLogin = null;
700
+ this._maxInternalLogLevel = null;
701
+ try {
702
+ JSON_Utils.JSONFromXML(responseXML, this.FillFromJSON.bind(this));
703
+ }
704
+ catch (ex) {
705
+ Logger.Instance.WriteExceptionToLog(ex, responseXML);
706
+ }
707
+ }
708
+ get ScrambleMessages() {
709
+ return this._scrambleMessages;
710
+ }
711
+ get ContextId() {
712
+ return this._contextId;
713
+ }
714
+ get GetSessionId() {
715
+ return this._privateSessionId;
716
+ }
717
+ get InputPassword() {
718
+ return this._inputPassword;
719
+ }
720
+ get HttpTimeout() {
721
+ return this._httpTimeout;
722
+ }
723
+ get SystemLogin() {
724
+ return this._systemLogin;
725
+ }
726
+ get MaxInternalLogLevel() {
727
+ return this._maxInternalLogLevel;
728
+ }
729
+ FillFromJSON(error, result) {
730
+ if (error != null) {
731
+ throw error;
732
+ }
733
+ let response = result['Richclientresponse'];
734
+ for (let elementName in response) {
735
+ if (response.hasOwnProperty(elementName)) {
736
+ switch (elementName) {
737
+ case "ContextID":
738
+ this._contextId = response[elementName][0];
739
+ break;
740
+ case "SessionID":
741
+ this._privateSessionId = response[elementName][0];
742
+ break;
743
+ case "Environment":
744
+ let envAttributes = response["Environment"][0]['$'];
745
+ if (!isNullOrUndefined(envAttributes["ScrambleMessages"])) {
746
+ Debug.Assert(envAttributes["ScrambleMessages"] === "N");
747
+ this._scrambleMessages = false;
748
+ }
749
+ if (!isNullOrUndefined(envAttributes["MaxInternalLogLevel"]))
750
+ this._maxInternalLogLevel = envAttributes["MaxInternalLogLevel"];
751
+ if (!isNullOrUndefined(envAttributes["InputPassword"]) && envAttributes["InputPassword"].toLocaleLowerCase() === "y")
752
+ this._inputPassword = true;
753
+ if (!isNullOrUndefined(envAttributes["SystemLogin"]))
754
+ this._systemLogin = envAttributes["SystemLogin"];
755
+ if (!isNullOrUndefined(envAttributes[ConstInterface.MG_TAG_HTTP_COMMUNICATION_TIMEOUT]))
756
+ this._httpTimeout = +envAttributes[ConstInterface.MG_TAG_HTTP_COMMUNICATION_TIMEOUT];
757
+ if (!isNullOrUndefined(envAttributes["ForwardSlash"]))
758
+ AccessHelper.environment.ForwardSlashUsage = envAttributes["ForwardSlash"];
759
+ break;
760
+ }
761
+ }
762
+ }
763
+ }
764
+ }
765
+ HandshakeResponse.SYSTEM_LOGIN_AD = 'D';
766
+ class ErrorMessageXml {
767
+ constructor(xmlContent, lastRequestTime, contextInactivityTimeout) {
768
+ this._lastRequestTime = 0;
769
+ this._errorMessage = null;
770
+ this._errorCode = 0;
771
+ this._middlewareAddress = null;
772
+ this._parsingFailed = false;
773
+ this._lastRequestTime = lastRequestTime;
774
+ this.contextInactivityTimeout = contextInactivityTimeout;
775
+ try {
776
+ JSON_Utils.JSONFromXML(xmlContent, this.FillFromJSON.bind(this));
777
+ }
778
+ catch (ex) {
779
+ Logger.Instance.WriteExceptionToLog(ex);
780
+ Misc.WriteStackTrace(ex);
781
+ this._parsingFailed = true;
782
+ }
783
+ }
784
+ FillFromJSON(error, result) {
785
+ if (error != null) {
786
+ throw error;
787
+ }
788
+ let xmlerr = result['xmlerr'];
789
+ for (let elementName in xmlerr) {
790
+ if (xmlerr.hasOwnProperty(elementName)) {
791
+ switch (elementName) {
792
+ case "errmsg":
793
+ this._errorMessage = xmlerr[elementName][0];
794
+ break;
795
+ case "errcode":
796
+ this._errorCode = +(xmlerr[elementName]);
797
+ break;
798
+ case "server":
799
+ this._middlewareAddress = xmlerr[elementName][0];
800
+ break;
801
+ case "appname":
802
+ case "prgname":
803
+ case "arguments":
804
+ case "username":
805
+ case "xmlerr":
806
+ break;
807
+ default:
808
+ Logger.Instance.WriteExceptionToLogWithMsg(NString.Format("Unknown element: '{0}'", elementName));
809
+ break;
810
+ }
811
+ }
812
+ }
813
+ }
814
+ GetCode() {
815
+ return this._errorCode;
816
+ }
817
+ GetMessage() {
818
+ let sb = new StringBuilder();
819
+ if (this._parsingFailed) {
820
+ sb.Append(AccessHelper.languageData.getConstMessage(MsgInterface.RC_STR_F7_UNEXPECTED_ERR));
821
+ }
822
+ else {
823
+ switch (this._errorCode) {
824
+ case ServerError.ERR_CTX_NOT_FOUND:
825
+ if (this.InactivityTimeoutExpired())
826
+ sb.Append(NString.Format("{0} ({1} {2})", AccessHelper.languageData.getConstMessage(MsgInterface.STR_ERR_SESSION_CLOSED_INACTIVITY), Math.floor(this.contextInactivityTimeout / 600), AccessHelper.languageData.getConstMessage(MsgInterface.STR_MINUTES)));
827
+ else
828
+ sb.Append(NString.Format("{0} ({1}).", AccessHelper.languageData.getConstMessage(MsgInterface.STR_ERR_SESSION_CLOSED), this._errorCode));
829
+ break;
830
+ case ServerError.ERR_WEBCLIENT_PROGRAM_RELOADED:
831
+ sb.Append(AccessHelper.languageData.getConstMessage(MsgInterface.STR_ERR_WEBCLIENT_PROGRAM_RELOADED));
832
+ break;
833
+ case ServerError.ERR_EXECUTED_PROGRAM_CHANGED:
834
+ sb.Append(AccessHelper.languageData.getConstMessage(MsgInterface.STR_ERR_EXECUTED_PROGRAM_CHANGED));
835
+ break;
836
+ case ServerError.ERR_AUTHENTICATION:
837
+ sb.Append(AccessHelper.languageData.getConstMessage(MsgInterface.USRINP_STR_BADPASSW));
838
+ break;
839
+ case ServerError.ERR_ACCESS_DENIED:
840
+ sb.Append(AccessHelper.languageData.getConstMessage(MsgInterface.STR_ERR_AUTHORIZATION_FAILURE));
841
+ break;
842
+ default:
843
+ sb.Append(this._errorMessage);
844
+ break;
845
+ }
846
+ sb.Append(OSEnvironment.EolSeq + OSEnvironment.EolSeq);
847
+ if (!ServerConfig.Instance.ShouldDisplayGenericError()) {
848
+ sb.Append(AccessHelper.languageData.getConstMessage(MsgInterface.BROWSER_OPT_INFO_SERVER_STR) + ": ");
849
+ sb.Append(ServerConfig.Instance.getServer());
850
+ if (!NString.IsNullOrEmpty(this._middlewareAddress)) {
851
+ sb.Append(" --> ");
852
+ sb.Append(this._middlewareAddress);
853
+ }
854
+ sb.Append(OSEnvironment.EolSeq);
855
+ }
856
+ sb.Append(AccessHelper.languageData.getConstMessage(MsgInterface.TASKRULE_STR_APPLICATION) + ": \"");
857
+ sb.Append(ServerConfig.Instance.getAppName());
858
+ sb.Append("\" (\"");
859
+ sb.Append("\")");
860
+ }
861
+ return sb.ToString();
862
+ }
863
+ InactivityTimeoutExpired() {
864
+ let expired = false;
865
+ if (this.contextInactivityTimeout > 0) {
866
+ let currTimeMilli = Misc.getSystemMilliseconds();
867
+ expired = ((currTimeMilli - this._lastRequestTime) > (this.contextInactivityTimeout * 100));
868
+ }
869
+ return expired;
870
+ }
871
+ }
872
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUmVtb3RlQ29tbWFuZHNQcm9jZXNzb3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9lbmdpbmUvc3JjL3JlbW90ZS9SZW1vdGVDb21tYW5kc1Byb2Nlc3Nvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsTUFBTSxFQUNOLFVBQVUsRUFDVixNQUFNLEVBQ04sZ0JBQWdCLEVBQ2hCLElBQUksRUFDSixZQUFZLEVBQ1osYUFBYSxFQUNiLFdBQVcsRUFDWCxPQUFPLEVBQ1AsWUFBWSxFQUNiLE1BQU0sa0JBQWtCLENBQUM7QUFDMUIsT0FBTyxFQUFDLEtBQUssRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsUUFBUSxFQUFFLGFBQWEsRUFBRSxpQkFBaUIsRUFBRSxXQUFXLEVBQUMsTUFBTSxzQkFBc0IsQ0FBQztBQUN4SSxPQUFPLEVBRUwsUUFBUSxFQUNSLGtCQUFrQixFQUNsQixNQUFNLEVBQ04sMkJBQTJCLEVBQzVCLE1BQU0sZ0JBQWdCLENBQUM7QUFDeEIsT0FBTyxFQUFDLGVBQWUsRUFBQyxNQUFNLDRDQUE0QyxDQUFDO0FBRTNFLE9BQU8sRUFDTCxxQkFBcUIsRUFDckIsd0NBQXdDLEVBQ3hDLGtDQUFrQyxFQUNuQyxNQUFNLDBCQUEwQixDQUFDO0FBQ2xDLE9BQU8sRUFBQyxXQUFXLEVBQUMsTUFBTSxxQkFBcUIsQ0FBQztBQUNoRCxPQUFPLEVBQUMsY0FBYyxFQUFDLE1BQU0sbUJBQW1CLENBQUM7QUFDakQsT0FBTyxFQUFDLFNBQVMsRUFBQyxNQUFNLG1CQUFtQixDQUFDO0FBQzVDLE9BQU8sRUFBQyxXQUFXLEVBQUMsTUFBTSxlQUFlLENBQUM7QUFFMUMsT0FBTyxFQUFDLGdCQUFnQixFQUFDLE1BQU0sMEJBQTBCLENBQUM7QUFDMUQsT0FBTyxFQUFDLGtCQUFrQixFQUFXLE1BQU0sbUJBQW1CLENBQUM7QUFDL0QsT0FBTyxF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QUM7WUFDcEIsRUFBRSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztTQUNsQjtRQUVELE9BQU8sRUFBRSxDQUFDLFFBQVEsRUFBRSxDQUFDO0lBQ3ZCLENBQUM7SUFFTyx3QkFBd0I7UUFDOUIsSUFBSSxPQUFPLEdBQVksS0FBSyxDQUFDO1FBQzdCLElBQUksSUFBSSxDQUFDLHdCQUF3QixHQUFHLENBQUMsRUFBRTtZQUNyQyxJQUFJLGFBQWEsR0FBVyxJQUFJLENBQUMscUJBQXFCLEVBQUUsQ0FBQztZQUN6RCxPQUFPLEdBQUcsQ0FBQyxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyx3QkFBd0IsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDO1NBQzdGO1FBQ0QsT0FBTyxPQUFPLENBQUM7SUFDakIsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcclxuICBCYXNlNjQsXHJcbiAgSlNPTl9VdGlscyxcclxuICBMb2dnZXIsXHJcbiAgTG9nZ2VyX0xvZ0xldmVscyxcclxuICBNaXNjLFxyXG4gIE1zZ0ludGVyZmFjZSxcclxuICBPU0Vudmlyb25tZW50LFxyXG4gIFJlcXVlc3RJbmZvLFxyXG4gIFN0clV0aWwsXHJcbiAgWE1MQ29uc3RhbnRzXHJcbn0gZnJvbSBcIkBtYWdpYy14cGEvdXRpbHNcIjtcclxuaW1wb3J0IHtEZWJ1ZywgRW5jb2RpbmcsIEV4Y2VwdGlvbiwgTGlzdCwgTlN0cmluZywgUmVmUGFyYW0sIFN0cmluZ0J1aWxkZXIsIGlzTnVsbE9yVW5kZWZpbmVkLCBpc1VuZGVmaW5lZH0gZnJvbSBcIkBtYWdpYy14cGEvbXNjb3JlbGliXCI7XHJcbmltcG9ydCB7XHJcbiAgQXV0aGVudGljYXRpb25EaWFsb2dIYW5kbGVyLFxyXG4gIENvbW1hbmRzLFxyXG4gIFJ1bnRpbWVDb250ZXh0QmFzZSxcclxuICBTdHlsZXMsXHJcbiAgVXNlcm5hbWVQYXNzd29yZENyZWRlbnRpYWxzXHJcbn0gZnJvbSBcIkBtYWdpYy14cGEvZ3VpXCI7XHJcbmltcG9ydCB7RXhlY09wZXJDb21tYW5kfSBmcm9tICcuLi9jb21tYW5kcy9DbGllbnRUb1NlcnZlci9FeGVjT3BlckNvbW1hbmQnO1xyXG5pbXBvcnQge1Rhc2t9IGZyb20gJy4uL3Rhc2tzL1Rhc2snXHJcbmltcG9ydCB7XHJcbiAgQ29tbWFuZHNQcm9jZXNzb3JCYXNlLFxyXG4gIENvbW1hbmRzUHJvY2Vzc29yQmFzZV9TZW5kaW5nSW5zdHJ1Y3Rpb24sXHJcbiAgQ29tbWFuZHNQcm9jZXNzb3JCYXNlX1Nlc3Npb25TdGFnZVxyXG59IGZyb20gXCIuLi9Db21tYW5kc1Byb2Nlc3NvckJhc2VcIjtcclxuaW1wb3J0IHtIdHRwTWFuYWdlcn0gZnJvbSBcIi4uL2h0dHAvSHR0cE1hbmFnZXJcIjtcclxuaW1wb3J0IHtDb25zdEludGVyZmFjZX0gZnJvbSBcIi4uL0NvbnN0SW50ZXJmYWNlXCI7XHJcbmltcG9ydCB7U2NyYW1ibGVyfSBmcm9tIFwiLi4vdXRpbC9TY3JhbWJsZXJcIjtcclxuaW1wb3J0IHtTZXJ2ZXJFcnJvcn0gZnJvbSBcIi4vU2VydmVyRXJyb3JcIjtcclxuaW1wb3J0IHtJUmVzdWx0VmFsdWV9IGZyb20gXCIuLi9ydC9JUmVzdWx0VmFsdWVcIjtcclxuaW1wb3J0IHtGbG93TW9uaXRvclF1ZXVlfSBmcm9tIFwiLi4vdXRpbC9GbG93TW9uaXRvclF1ZXVlXCI7XHJcbmltcG9ydCB7T3BlbmluZ1Rhc2tEZXRhaWxzLCBUYXNrQmFzZX0gZnJvbSBcIi4uL3Rhc2tzL1Rhc2tCYXNlXCI7XHJcbmltcG9ydCB7SHR0cFV0aWxpdHl9IGZyb20gXCIuLi9odHRwL2NsaWVudC9IdHRwVXRpbGl0eVwiO1xyXG5pbXBvcnQge0h0dHBDbGllbnRFdmVudHN9IGZyb20gXCIuLi9odHRwL2NsaWVudC9IdHRwQ2xpZW50RXZlbnRzXCI7XHJcbmltcG9ydCB7U2VydmVyQ29uZmlnfSBmcm9tIFwiLi4vU2VydmVyQ29uZmlnXCI7XHJcbmltcG9ydCB7TUdEYXRhfSBmcm9tIFwiLi4vdGFza3MvTUdEYXRhXCI7XHJcbmltcG9ydCB7Q29tbWFuZHNUYWJsZX0gZnJvbSBcIi4uL0NvbW1hbmRzVGFibGVcIjtcclxuaW1wb3J0IHtBY2Nlc3NIZWxwZXJ9IGZyb20gXCIuLi9BY2Nlc3NIZWxwZXJcIjtcclxuaW1wb3J0IHtFbnZpcm9ubWVudCwgRXZlbnQsIEV2ZW50Q29tbWFuZCwgRXZlbnRzTWFuYWdlciwgR1VJTWFuYWdlciwgSUNsaWVudENvbW1hbmQsIFJ1blRpbWVFdmVudH0gZnJvbSBcIi4uLy4uL1wiO1xyXG5pbXBvcnQge0lDbGllbnRUb1NlcnZlckNvbW1hbmRJbmZvfSBmcm9tIFwiLi4vY29tbWFuZHMvSUNsaWVudFRvU2VydmVyQ29tbWFuZEluZm9cIjtcclxuaW1wb3J0IHtNR0RhdGFDb2xsZWN0aW9ufSBmcm9tIFwiLi4vdGFza3MvTUdEYXRhQ29sbGVjdGlvblwiO1xyXG5pbXBvcnQge1N1YnNjcmlwdGlvbiwgdGltZXJ9IGZyb20gXCJyeGpzXCI7XHJcblxyXG4vLy8gPHN1bW1hcnk+IFJlcHJlc2VudHMgdGhlIHN0YXR1cyBvZiBhIHJlcXVlc3QgPC9zdW1tYXJ5PlxyXG5lbnVtICBSZXF1ZXN0U3RhdHVzXHJcbntcclxuICBIYW5kbGVkLCAvL3RoZSByZXF1ZXN0IHdhcyBzdWNjZXNzZnVsbHkgaGFuZGxlZC5cclxuICBSZXRyeSwgICAvL3RoZSByZXF1ZXN0IHNob3VsZCBiZSByZS1zZW50LlxyXG4gIEFib3J0ICAgLy90aGUgcmVxdWVzdCBjb3VsZCBub3QgYmUgaGFuZGxlZCBhbmQgc2hvdWxkIGJlIGFib3J0ZWQuXHJcbn1cclxuXHJcbi8vIEBkeW5hbWljXHJcbmV4cG9ydCBjbGFzcyBSZW1vdGVDb21tYW5kc1Byb2Nlc3NvciBleHRlbmRzIENvbW1hbmRzUHJvY2Vzc29yQmFzZSB7XHJcbiAgc3RhdGljIHJlYWRvbmx5IFJDX05PX0NPTlRFWFRfSUQ6IHN0cmluZyA9ICctMSc7XHJcbiAgcHJpdmF0ZSBzdGF0aWMgX2luc3RhbmNlOiBSZW1vdGVDb21tYW5kc1Byb2Nlc3NvciA9IG51bGw7XHJcbiAgcHVibGljIHN0YXRpYyBJc1Nlc3Npb25SZUluaXRpYWxpemluZyA9IGZhbHNlO1xyXG4gIHByaXZhdGUgc3RhdGljIGxhc3RFeGNlcHRpb25NZXNzYWdlID0gbnVsbDtcclxuICBwcml2YXRlIHN0YXRpYyBJbml0aWFsVXJsOiBzdHJpbmcgPSBudWxsO1xyXG5cclxuICAvLyBUT0RPIC0gbW92ZSBpdCB0byBjbGFzc1xyXG4gIHByaXZhdGUgc3RhdGljIHJlcXVlc3ROdW1iZXIgPSAwO1xyXG4gIHByaXZhdGUgc3RhdGljIHRvdGFsVGltZUZvckhUVFBSZXF1ZXN0cyA9IDA7XHJcbiAgcHJpdmF0ZSBzdGF0aWMgdG90YWxSZXF1ZXN0RGF0YUxlbmd0aCA9IDA7XHJcbiAgcHJpdmF0ZSBzdGF0aWMgdG90YWxSZXNwb25zZURhdGFMZW5ndGggPSAwO1xyXG5cclxuICAvLyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxyXG4gIC8vICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXHJcbiAgLy8gKioqKioqKiogV2hlbiBjaGFuZ2luZyBXRUJfQ09NTVVOSUNBVElPTl9QUk9UT0NPTF9WRVJTSU9OLCBwbGVhc2UgY2hhbmdlIG9uIG1vYmlsZSBwbGF0Zm9ybXMgYXMgd2VsbDpcclxuICAvLyAqKioqKioqKiBXMTBNOiBSZW1vdGVDb21tYW5kc1Byb2Nlc3Nvci5jc1xyXG4gIHByaXZhdGUgc3RhdGljIHJlYWRvbmx5IFdFQl9DT01NVU5JQ0FUSU9OX1BST1RPQ09MX1ZFUlNJT046IHN0cmluZyA9IFwiMTQwMDJcIjtcclxuICAvLyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxyXG4gIC8vICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXHJcblxyXG4gIC8vIFRPRE86IENoZWNrIGlmIHdlIG5lZWQgX2xvZ0FjY3VtdWxhdG9yLlxyXG4gIC8vIHByaXZhdGUgX2xvZ0FjY3VtdWxhdG9yOiBDbGllbnRMb2dBY2N1bXVsYXRvciA9IG51bGw7XHJcblxyXG4gIHByaXZhdGUgX2xhc3RSZXF1ZXN0VGltZTogbnVtYmVyID0gMDsgLy8gdGhlIHRpbWUgb2YgdGhlIGxhc3QgcmVxdWVzdCB0byB0aGUgc2VydmVyXHJcblxyXG4gIFNlcnZlclVybDogc3RyaW5nID0gbnVsbDtcclxuICBwcml2YXRlIHN0YXRpYyBfc2hvdWxkU2NyYW1ibGVBbmRVbnNjcmFtYmxlTWVzc2FnZXM6IGJvb2xlYW4gPSBmYWxzZTsgLy8gc3RhdGljIGJlY2F1c2UgaXQgaXMgaW5pdGlhbGl6ZWQgYmVmb3JlIHRoZSBleGVjdXRpb24gcHJvcHMgYXJlIGF2YWlsYWJsZVxyXG5cclxuICBwdWJsaWMgU2Vzc2lvbklkOiBzdHJpbmc7XHJcblxyXG4gIHB1YmxpYyBEZWxheUNvbW1hbmRFeGVjdXRpb246IGJvb2xlYW4gPSBmYWxzZTtcclxuICBwcml2YXRlIF9yZXF1ZXN0SW5mbyA9IG5ldyBSZXF1ZXN0SW5mbygpO1xyXG5cclxuICBzdGF0aWMgR2V0SW5zdGFuY2UoKTogUmVtb3RlQ29tbWFuZHNQcm9jZXNzb3Ige1xyXG4gICAgaWYgKFJlbW90ZUNvbW1hbmRzUHJvY2Vzc29yLl9pbnN0YW5jZSA9PT0gbnVsbCkge1xyXG4gICAgICBSZW1vdGVDb21tYW5kc1Byb2Nlc3Nvci5faW5zdGFuY2UgPSBuZXcgUmVtb3RlQ29tbWFuZHNQcm9jZXNzb3IoKTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gUmVtb3RlQ29tbWFuZHNQcm9jZXNzb3IuX2luc3RhbmNlO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBjb25zdHJ1Y3RvcigpIHtcclxuICAgIHN1cGVyKCk7XHJcbiAgICB0aGlzLlNlcnZlclVybCA9IFNlcnZlckNvbmZpZy5JbnN0YW5jZS5nZXRTZXJ2ZXJVUkwoKTtcclxuXHJcbiAgICBIdHRwTWFuYWdlci5HZXRJbnN0YW5jZSgpO1xyXG5cclxuICAgIHRoaXMuUmVnaXN0ZXJEZWxlZ2F0ZXMoKTtcclxuICB9XHJcblxyXG4gIC8vLyA8c3VtbWFyeT5cclxuICAvLy8gQ2hlY2tzIHRoYXQgc2Vzc2lvbiBjb3VudGVyIGlzIGNvbnNlY3V0aXZlIGR1cmluZyB0aGUgc2Vzc2lvbiBhbmQgc2V0cyBuZXcgdmFsdWUuXHJcbiAgLy8vIFRoZSBvbmx5IGV4Y2VwdGlvbiBpcyBpbiBjYXNlIHRoZSBjbGllbnQgc2VudCB0byB0aGUgc2VydmVyIENvbnN0SW50ZXJmYWNlLlNFU1NJT05fQ09VTlRFUl9DTE9TRV9DVFhfSU5ESUNBVElPTixcclxuICAvLy8gICAgdGhlIHNlcnZlciBpcyBleHBlY3RlZCB0byByZXR1cm4gQ29uc3RJbnRlcmZhY2UuU0VTU0lPTl9DT1VOVEVSX0NMT1NFX0NUWF9JTkRJQ0FUSU9OIGluIHJlc3BvbnNlIChSZXF1ZXN0c1NlcnZlckJhc2U6OlByb2Nlc3NSZXF1ZXN0KSwgdG8gYWNrbm93bGVkZ2UgdGhlIHJlcXVlc3QgdG8gY2xvc2UgdGhlIGNvbnRleHQuXHJcbiAgLy8vIDwvc3VtbWFyeT5cclxuICAvLy8gPHBhcmFtIG5hbWU9XCJuZXdTZXNzaW9uQ291bnRlclwiPiEhLjwvcGFyYW0+XHJcbiAgQ2hlY2tBbmRTZXRTZXNzaW9uQ291bnRlcihuZXdTZXNzaW9uQ291bnRlcjogbnVtYmVyKTogdm9pZCB7XHJcbiAgICBpZiAobmV3U2Vzc2lvbkNvdW50ZXIgPT09IENvbnN0SW50ZXJmYWNlLlNFU1NJT05fQ09VTlRFUl9DTE9TRV9DVFhfSU5ESUNBVElPTikge1xyXG4gICAgICBEZWJ1Zy5Bc3NlcnQodGhpcy5HZXRTZXNzaW9uQ291bnRlcigpID09PSBDb25zdEludGVyZmFjZS5TRVNTSU9OX0NPVU5URVJfQ0xPU0VfQ1RYX0lORElDQVRJT04pO1xyXG4gICAgfVxyXG4gICAgZWxzZSB7XHJcbiAgICAgIERlYnVnLkFzc2VydChuZXdTZXNzaW9uQ291bnRlciA9PT0gdGhpcy5HZXRTZXNzaW9uQ291bnRlcigpICsgMSk7XHJcbiAgICAgIHRoaXMuU2V0U2Vzc2lvbkNvdW50ZXIobmV3U2Vzc2lvbkNvdW50ZXIpO1xyXG4gICAgICBMb2dnZXIuSW5zdGFuY2UuV3JpdGVTZXJ2ZXJUb0xvZyhOU3RyaW5nLkZvcm1hdChcIlNlc3Npb24gQ291bnRlciAtLT4gezB9XCIsIHRoaXMuX3Nlc3Npb25Db3VudGVyKSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvLy8gPHN1bW1hcnk+XHJcbiAgLy8vIFplcm8gc2Vzc2lvbiBjb3VudGVyIHdoZW4gcmVpbml0aWFsaXppbmcgc2VydmVyIGNvbW11bmljYXRpb24gZGV0YWlsc1xyXG4gIC8vLyA8L3N1bW1hcnk+XHJcbiAgLy8vIDxyZXR1cm5zPjwvcmV0dXJucz5cclxuICBDbGVhclNlc3Npb25Db3VudGVyKCk6IHZvaWRcclxuICB7XHJcbiAgICB0aGlzLl9zZXNzaW9uQ291bnRlciA9IDA7XHJcbiAgICBMb2dnZXIuSW5zdGFuY2UuV3JpdGVTZXJ2ZXJUb0xvZyhOU3RyaW5nLkZvcm1hdChcIlNlc3Npb24gQ291bnRlciAtLT4gezB9XCIsIHRoaXMuX3Nlc3Npb25Db3VudGVyKSk7XHJcbiAgfVxyXG5cclxuICAvLy8gPHN1bW1hcnk+XHJcbiAgLy8vIDwvc3VtbWFyeT5cclxuICAvLy8gPHBhcmFtIG5hbWU9XCJuZXdTZXNzaW9uQ291bnRlclwiPjwvcGFyYW0+XHJcbiAgcHJpdmF0ZSBTZXRTZXNzaW9uQ291bnRlcihuZXdTZXNzaW9uQ291bnRlcjogbnVtYmVyKTogdm9pZCB7XHJcbiAgICB0aGlzLl9zZXNzaW9uQ291bnRlciA9IG5ld1Nlc3Npb25Db3VudGVyO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGdldCBHZXRMYXN0UmVxdWVzdFRpbWUoKSB7XHJcbiAgICAgIHJldHVybiB0aGlzLl9sYXN0UmVxdWVzdFRpbWU7XHJcbiAgfVxyXG5cclxuICAvLy8gPHN1bW1hcnk+XHJcbiAgLy8vIFJlU3RhcnRTZXNzaW9uXHJcbiAgLy8vIDwvc3VtbWFyeT5cclxuICBhc3luYyBSZVN0YXJ0U2Vzc2lvbiggKTogUHJvbWlzZTx2b2lkPiB7XHJcblxyXG4gICAgUmVtb3RlQ29tbWFuZHNQcm9jZXNzb3IuSXNTZXNzaW9uUmVJbml0aWFsaXppbmcgPSB0cnVlO1xyXG5cclxuICAgIGF3YWl0IHRoaXMuU3RvcmVTZXNzaW9uUmVJbml0aWFsaXppbmdEYXRhT25Mb2NhbFN0b3JhZ2UoKTtcclxuICAgIGxldCBuYXZpZ2F0ZVJvb3RSb3V0ZSA9IGZhbHNlO1xyXG4gICAgaWYgKCFSdW50aW1lQ29udGV4dEJhc2UuSW5zdGFuY2UuUmVtb3ZlZENvbnRleHRGcm9tU2VydmVyKVxyXG4gICAgICBuYXZpZ2F0ZVJvb3RSb3V0ZSA9IEVudmlyb25tZW50Lkluc3RhbmNlLmdldFNwZWNpYWxSb3V0ZVRvUm9vdFByb2dPbkNvbnRleHRSZWNyZWF0aW9uKCkgPyB0cnVlIDogZmFsc2U7XHJcbiAgICBDb21tYW5kcy5hZGRSZWZyZXNoUGFnZShuYXZpZ2F0ZVJvb3RSb3V0ZSwgUmVtb3RlQ29tbWFuZHNQcm9jZXNzb3IuSW5pdGlhbFVybCk7XHJcbiAgICAvL3N0b3AgdGhlIGV4ZWN1dGlvbiBieSB0aHJvd2luZyBleGNlcHRpb24uXHJcbiAgICB0aHJvdyBuZXcgRXhjZXB0aW9uKCcnKTtcclxuXHJcbiAgfVxyXG5cclxuICAvLy8gPHN1bW1hcnk+XHJcbiAgLy8vIFN0b3JlU2Vzc2lvblJlSW5pdGlhbGl6aW5nRGF0YU9uTG9jYWxTdG9yYWdlXHJcbiAgLy8vIDwvc3VtbWFyeT5cclxuICBhc3luYyBTdG9yZVNlc3Npb25SZUluaXRpYWxpemluZ0RhdGFPbkxvY2FsU3RvcmFnZSAoKSA6IFByb21pc2U8dm9pZD4ge1xyXG5cclxuICAgIGxldCBtYWluUHJnVmlld1N0cmluZ0ZvclNlcnZlciA9IGF3YWl0IHRoaXMuQnVpbGRYTUxGb3JNYWluUHJvZ3JhbURhdGFWaWV3KCk7XHJcbiAgICBsZXQgZ2xvYmFsUGFyYW1zU3RyaW5nID0gQWNjZXNzSGVscGVyLmdsb2JhbFBhcmFtcy5taXJyb3JBbGxUb1hNTCgpO1xyXG5cclxuICAgIC8vIHN0b3JlIG1haW5QcmdWaWV3U3RyaW5nRm9yU2VydmVyLCBJc1Nlc3Npb25SZUluaXRpYWxpemluZyBhbmQgZ2xvYmFsUGFyYW1zU3RyaW5nIG9uIGxvY2FsXHJcbiAgICAvLyBzdG9yYWdlIGluIG9yZGVyIHRvIHVzZSBpdCBmb3IgbmV4dCBzZXNzaW9uLlxyXG4gICAgbGV0IGRhdGFTdG9yYWdlID0gd2luZG93LmxvY2FsU3RvcmFnZTtcclxuICAgIGRhdGFTdG9yYWdlLnNldEl0ZW0oQ29uc3RJbnRlcmZhY2UuSVNfU0VTU0lPTl9SRUlOSVRJQUxJWklORywgXCJ0cnVlXCIpO1xyXG4gICAgZGF0YVN0b3JhZ2Uuc2V0SXRlbShDb25zdEludGVyZmFjZS5NQUlOX1BST0dfVklFVywgbWFpblByZ1ZpZXdTdHJpbmdGb3JTZXJ2ZXIudG9TdHJpbmcoKSk7XHJcbiAgICBkYXRhU3RvcmFnZS5zZXRJdGVtKENvbnN0SW50ZXJmYWNlLkdMT0JBTF9QQVJBTV9MSVNULCBnbG9iYWxQYXJhbXNTdHJpbmcpO1xyXG4gICAgZGF0YVN0b3JhZ2Uuc2V0SXRlbShDb25zdEludGVyZmFjZS5MQVNUX0VYQ0VQVElPTiwgUmVtb3RlQ29tbWFuZHNQcm9jZXNzb3IubGFzdEV4Y2VwdGlvbk1lc3NhZ2UpO1xyXG4gICAgaWYgKFJ1bnRpbWVDb250ZXh0QmFzZS5JbnN0YW5jZS5SZW1vdmVkQ29udGV4dEZyb21TZXJ2ZXIpXHJcbiAgICAgIGRhdGFTdG9yYWdlLnNldEl0ZW0oQ29uc3RJbnRlcmZhY2UuQ1RYX1JFTU9WRURfRlJPTV9TUlZSLCBcIjFcIik7XHJcblxyXG4gICAgRXZlbnRzTWFuYWdlci5JbnN0YW5jZS5zdG9yZUxhc3RTYXZlZFJvdXRlRXZlbnRPbkxvY2FsU3RvcmFnZSAoKTtcclxuICB9XHJcblxyXG4gIC8vLyA8c3VtbWFyeT5cclxuICAvLy8gUmVzdG9yZVNlc3Npb25SZUluaXRpYWxpemluZ0RhdGFGcm9tTG9jYWxTdG9yYWdlXHJcbiAgLy8vIDwvc3VtbWFyeT5cclxuICBSZXN0b3JlU2Vzc2lvblJlSW5pdGlhbGl6aW5nRGF0YUZyb21Mb2NhbFN0b3JhZ2UgKGtleTogc3RyaW5nICk6c3RyaW5nIHtcclxuXHJcbiAgICBsZXQgZGF0YVN0b3JhZ2UgPSB3aW5kb3cubG9jYWxTdG9yYWdlO1xyXG4gICAgbGV0IHZhbCA9IGRhdGFTdG9yYWdlLmdldEl0ZW0oa2V5KTtcclxuICAgIHJldHVybiB2YWw7XHJcbiAgfVxyXG5cclxuICAgIC8vLyA8c3VtbWFyeT5QcmVwYXJlIGFuZCBleGVjdXRlIHRoZSAxc3QgJiAybmQgaGFuZHNoYWtlIHJlcXVlc3RzOlxyXG4gIC8vLyAxc3QgcmVxdWVzdDogIFVURjhUUkFOUz0uLiZhcHBuYW1lPS4uJnByZ25hbWU9Li4mYXJndW1lbnRzPS1BPFJpY2hjbGllbnQ+PFJlcXVlc3RpbmdWZXJzaW9uRGV0YWlscz1cIi4uXCIvPjwvUmljaGNsaWVudD5cclxuICAvLy8gICAgIHJlc3BvbnNlOiBpbnN0cnVjdGlvbnMgdG8gdGhlIGNsaWVudCAtIHdoZXRoZXIgdG8gZGlzcGxheSBhdXRoZW50aWNhdGlvbiBkaWFsb2csIHRoZSBzZXJ2ZXIncyB2ZXJzaW9uLCBhbmQgbW9yZSAuLlxyXG4gIC8vLyAgICAgICAgICAgICAgIGUuZy4gPFJpY2hjbGllbnRyZXNwb25zZT48Q29udGV4dElEPjEyMDMwODc4OTcyNjM3MTIwMDwvQ29udGV4dElEPjxFbnZpcm9ubWVudCBJbnB1dFBhc3N3b3JkPVwiTlwiIFN5c3RlbUxvZ2luPVwiTlwiIFNjcmFtYmxlTWVzc2FnZXM9XCJOXCIgTWF4SW50ZXJuYWxMb2dMZXZlbD1cIlNlcnZlciNcIiBIdHRwVGltZW91dD1cIjEwXCIgQ2xpZW50TmV0d29ya1JlY292ZXJ5SW50ZXJ2YWw9XCIwXCIgRm9yd2FyZFNsYXNoPVwid2ViXCIvPjwvUmljaGNsaWVudHJlc3BvbnNlPlxyXG4gIC8vLyAybmQgcmVxdWVzdDogYXV0aGVudGljYXRpb24gKG9wdGlvbmFsLCBkZXBlbmRpbmcgb24gdGhlIDFzdCByZXF1ZXN0KS5cclxuICAvLy8gPC9zdW1tYXJ5PlxyXG4gIC8vLyA8cmV0dXJucz50cnVlIG9ubHkgaWYgdGhlIGNsaWVudCBzaG91bGQgY29udGludWUgdG8gc3RhcnQgdGhlIGFjdHVhbCBwcm9ncmFtIChpLmUuIGFmdGVyIGhhbmRzaGFrZSkuPC9yZXR1cm5zPlxyXG4gIGFzeW5jIFN0YXJ0U2Vzc2lvbigpOiBQcm9taXNlPGJvb2xlYW4+IHtcclxuICAgIGxldCBhdXRoZW50aWNhdGlvbkNhbmNlbGxlZDogYm9vbGVhbiA9IGZhbHNlO1xyXG4gICAgbGV0IGhhbmRzaGFrZVJlc3BvbnNlOiBIYW5kc2hha2VSZXNwb25zZSA9IG51bGw7XHJcbiAgICBsZXQgZGlhbG9nOiBBdXRoZW50aWNhdGlvbkRpYWxvZ0hhbmRsZXIgPSBudWxsO1xyXG5cclxuICAgIHRyeSB7XHJcbiAgICAgIGxldCBsYXN0VHlwZWRVc2VySWQ6IHN0cmluZyA9IG51bGw7XHJcblxyXG4gICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbiAgICAgIC8vIDFzdCBoYW5kc2hha2UgcmVxdWVzdDogcHJlcGFyZSAxc3QgaGFuZHNoYWtlIHJlcXVlc3QgYW5kIHNjcmFtYmxlIGl0XHJcbiAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuICAgICAgbGV0IGhhbmRzaGFrZUluaXRpYWxUb2tlbnM6IFN0cmluZ0J1aWxkZXIgPSBuZXcgU3RyaW5nQnVpbGRlcigpO1xyXG4gICAgICBoYW5kc2hha2VJbml0aWFsVG9rZW5zLkFwcGVuZChDb25zdEludGVyZmFjZS5VVEY4VFJBTlMgK1xyXG4gICAgICAgIENvbnN0SW50ZXJmYWNlLlJFUV9BUFBfTkFNRSArIFwiPVwiICtcclxuICAgICAgICBIdHRwVXRpbGl0eS5VcmxFbmNvZGUoU2VydmVyQ29uZmlnLkluc3RhbmNlLmdldEFwcE5hbWUoKSwgRW5jb2RpbmcuVVRGOCkpO1xyXG5cclxuICAgICAgaGFuZHNoYWtlSW5pdGlhbFRva2Vucy5BcHBlbmQoXCImXCIgKyBDb25zdEludGVyZmFjZS5SRVFfQVJHUyArIFwiPVwiICsgQ29uc3RJbnRlcmZhY2UuUkVRX0FSR19BTFBIQSArXHJcbiAgICAgIFwiPFJpY2hjbGllbnQ+PFJlcXVpcmVzIEVuY3J5cHRpb25LZXk9XFxcIkZhbHNlXFxcIi8+PFJJQVByb3RvY29sVmVyc2lvbj1cXFwiXCIgKyBSZW1vdGVDb21tYW5kc1Byb2Nlc3Nvci5XRUJfQ09NTVVOSUNBVElPTl9QUk9UT0NPTF9WRVJTSU9OICsgXCJcXFwiLz48L1JpY2hjbGllbnQ+XCIpO1xyXG5cclxuICAgICAgTG9nZ2VyLkluc3RhbmNlLldyaXRlRGV2VG9Mb2coTlN0cmluZy5Gb3JtYXQoXCJIYW5kc2hha2UgcmVxdWVzdCAjMSAobm90IHNjcmFtYmxlZCkgOiB7MH1cIixcclxuICAgICAgICB0aGlzLlNlcnZlclVybCArIENvbnN0SW50ZXJmYWNlLlJFUV9BUkdfU1RBUlQgK1xyXG4gICAgICAgIENvbnN0SW50ZXJmYWNlLlJDX0lORElDQVRJT05fSU5JVElBTCArIGhhbmRzaGFrZUluaXRpYWxUb2tlbnMpKTtcclxuXHJcbiAgICAgIGxldCBoYW5kc2hha2VJbml0aWFsVXJsOiBzdHJpbmcgPSB0aGlzLlNlcnZlclVybCArIENvbnN0SW50ZXJmYWNlLlJFUV9BUkdfU1RBUlQgK1xyXG4gICAgICAgIENvbnN0SW50ZXJmYWNlLlJDX0lORElDQVRJT05fSU5JVElBTCArXHJcbiAgICAgICAgQ29uc3RJbnRlcmZhY2UuUkNfVE9LRU5fREFUQSArXHJcbiAgICAgICAgSHR0cFV0aWxpdHkuVXJsRW5jb2RlKFNjcmFtYmxlci5TY3JhbWJsZShoYW5kc2hha2VJbml0aWFsVG9rZW5zLlRvU3RyaW5nKCkpLCBFbmNvZGluZy5VVEY4KTtcclxuXHJcbiAgICAgIExvZ2dlci5JbnN0YW5jZS5Xcml0ZVNlcnZlck1lc3NhZ2VzVG9Mb2coXCJcIik7XHJcbiAgICAgIExvZ2dlci5JbnN0YW5jZS5Xcml0ZVNlcnZlck1lc3NhZ2VzVG9Mb2coTlN0cmluZy5Gb3JtYXQoXCJIYW5kc2hha2UgcmVxdWVzdCAjMTogezB9XCIsIGhhbmRzaGFrZUluaXRpYWxVcmwpKTtcclxuXHJcbiAgICAgIC8vIEluaXRpYWxpemUgdGVtcCBjdHhHcm91cCB3aXRoIEN0eEdyb3VwIGZyb20gZXhlY3V0aW9uLnByb3BlcnRpZXNcclxuICAgICAgbGV0IGN0eEdyb3VwOiBzdHJpbmcgPSBTZXJ2ZXJDb25maWcuSW5zdGFuY2UuZ2V0Q3R4R3JvdXAoKTtcclxuXHJcbiAgICAgIHdoaWxlICghYXV0aGVudGljYXRpb25DYW5jZWxsZWQpIHtcclxuICAgICAgICBsZXQgcmVxdWVzdFN0YXR1czogUmVmUGFyYW08UmVxdWVzdFN0YXR1cz4gPSBuZXcgUmVmUGFyYW0oUmVxdWVzdFN0YXR1cy5IYW5kbGVkKTtcclxuICAgICAgICAvLyBleGVjdXRlIHRoZSAxc3QgcmVxdWVzdFxyXG4gICAgICAgIGxldCByZXNwb25zZVN0cjogc3RyaW5nID0gYXdhaXQgdGhpcy5EaXNwYXRjaFJlcXVlc3QoaGFuZHNoYWtlSW5pdGlhbFVybCwgbnVsbCwgQ29tbWFuZHNQcm9jZXNzb3JCYXNlX1Nlc3Npb25TdGFnZS5IQU5EU0hBS0UsIHJlcXVlc3RTdGF0dXMpO1xyXG5cclxuICAgICAgICAvLyBwcm9jZXNzIHRoZSAxc3QgcmVzcG9uc2UgLSBjaGVjayBpZiB0aGUgcmVzcG9uc2UgaXMgZXJyb3IsIHVuc2NyYW1ibGUgYW5kIHBhcnNlIGl0XHJcbiAgICAgICAgaWYgKE5TdHJpbmcuSXNOdWxsT3JFbXB0eShyZXNwb25zZVN0cikpIHtcclxuICAgICAgICAgIHRocm93IG5ldyBTZXJ2ZXJFcnJvcihcIkNsaWVudCBmYWlsZWQgdG8gaW5pdGlhbGl6ZSBhIHNlc3Npb24uXCIgKyBPU0Vudmlyb25tZW50LkVvbFNlcSArXHJcbiAgICAgICAgICAgIFwiRW1wdHkgcmVzcG9uc2Ugd2FzIHJlY2VpdmVkIGZyb20gdGhlIHdlYiBzZXJ2ZXIuXCIgKyBPU0Vudmlyb25tZW50LkVvbFNlcSArIE9TRW52aXJvbm1lbnQuRW9sU2VxICsgdGhpcy5TZXJ2ZXJVcmwpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgTG9nZ2VyLkluc3RhbmNlLldyaXRlU2VydmVyTWVzc2FnZXNUb0xvZyhOU3RyaW5nLkZvcm1hdChcIkhhbmRzaGFrZSByZXNwb25zZSAjMTogezB9XCIsIHJlc3BvbnNlU3RyKSk7XHJcbiAgICAgICAgTG9nZ2VyLkluc3RhbmNlLldyaXRlU2VydmVyTWVzc2FnZXNUb0xvZyhcIlwiKTtcclxuXHJcbiAgICAgICAgaGFuZHNoYWtlUmVzcG9uc2UgPSBuZXcgSGFuZHNoYWtlUmVzcG9uc2UocmVzcG9uc2VTdHIpO1xyXG5cclxuICAgICAgICBSdW50aW1lQ29udGV4dEJhc2UuSW5zdGFuY2UuQ29udGV4dElEID0gaGFuZHNoYWtlUmVzcG9uc2UuQ29udGV4dElkO1xyXG5cclxuICAgICAgICAvLyBzYXZlIHNlc3Npb24gaWQgb24gY2xpZW50IHdoaWNoIGlzIHJlY2VpdmVkIGluIDFzdCByZXNwb25zZS5cclxuICAgICAgICB0aGlzLlNlc3Npb25JZCA9IGhhbmRzaGFrZVJlc3BvbnNlLkdldFNlc3Npb25JZDtcclxuXHJcbiAgICAgICAgSHR0cE1hbmFnZXIuR2V0SW5zdGFuY2UoKS5IdHRwQ29tbXVuaWNhdGlvblRpbWVvdXRNUyA9IGhhbmRzaGFrZVJlc3BvbnNlLkh0dHBUaW1lb3V0ICogMTAwMDtcclxuXHJcbiAgICAgICAgLy8gRHVyaW5nIGF1dGhlbnRpY2F0aW9uLCBpZiBhdXRoZW50aWNhdGlvbiBmYWlsZWQgdGhlbiBzZXJ2ZXIgdW5sb2FkcyBjdHggYW5kIGNyZWF0ZXMgbmV3IGN0eCBmb3IgbmV4dCBhdXRoZW50aWNhdGlvbiByZXF1ZXN0LlxyXG4gICAgICAgIC8vIFNvIGV2ZXJ5IHRpbWUgYWZ0ZXIgYXV0aGVudGljYXRpb24gZmFpbHMgd2UgcmVjZWl2ZSBuZXcgY3R4aWQgZm9yIG5leHQgYXV0aGVudGljYXRpb24gcmVxdWVzdC5cclxuICAgICAgICAvLyBIZW5jZSB0YWtlIGN0eGdyb3VwIGluIGxvY2FsIHZhcmlhYmxlIGFuZCB1cGRhdGUgQ2xpZW50TWFuYWdlciBvbmx5IGFmdGVyIGF1dGhlbnRpY2F0aW9uIGlzIGRvbmUuXHJcbiAgICAgICAgaWYgKE5TdHJpbmcuSXNOdWxsT3JFbXB0eShTZXJ2ZXJDb25maWcuSW5zdGFuY2UuZ2V0Q3R4R3JvdXAoKSkpIHtcclxuICAgICAgICAgIGN0eEdyb3VwID0gaGFuZHNoYWtlUmVzcG9uc2UuQ29udGV4dElkO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuICAgICAgICAvLyAybmQgaGFuZHNoYWtlIHJlcXVlc3RcclxuICAgICAgICAvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4gICAgICAgIGxldCBjcmVkZW50aWFsczogVXNlcm5hbWVQYXNzd29yZENyZWRlbnRpYWxzID0gbnVsbDtcclxuICAgICAgICBpZiAoU2VydmVyQ29uZmlnLkluc3RhbmNlLmdldFNraXBBdXRoZW50aWNhdGlvbkRpYWxvZygpKSB7XHJcbiAgICAgICAgICAvLyBza2lwIGF1dGhlbnRpY2F0aW9uICh0byB0aGUgcnVudGltZS1lbmdpbmUpIGRpYWxvZ1xyXG4gICAgICAgICAgaWYgKFNlcnZlckNvbmZpZy5JbnN0YW5jZS5nZXRVc2VybmFtZSgpICE9PSBudWxsKSB7XHJcbiAgICAgICAgICAgIC8vIHVzZXIgdGhlIHVzZXJJZCAmIHBhc3N3b3JkIHRoYXQgd2VyZSBwYXNzZWQsIGFuZCByZXNldCB0aGVtICh0aGV5J2xsIGJlIHNldCBiZWxvdywgaWYgYXV0aGVudGljYXRlZCBieSB0aGUgcnVudGltZS1lbmdpbmUpXHJcbiAgICAgICAgICAgIGNyZWRlbnRpYWxzID0gbmV3IFVzZXJuYW1lUGFzc3dvcmRDcmVkZW50aWFscyhTZXJ2ZXJDb25maWcuSW5zdGFuY2UuZ2V0VXNlcm5hbWUoKSwgU2VydmVyQ29uZmlnLkluc3RhbmNlLmdldFBhc3N3b3JkKCkpO1xyXG4gICAgICAgICAgICBTZXJ2ZXJDb25maWcuSW5zdGFuY2Uuc2V0VXNlcm5hbWUoXCJcIik7XHJcbiAgICAgICAgICAgIFNlcnZlckNvbmZpZy5JbnN0YW5jZS5zZXRQYXNzd29yZChcIlwiKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAoaGFuZHNoYWtlUmVzcG9uc2UuSW5wdXRQYXNzd29yZCAmJiBoYW5kc2hha2VSZXNwb25zZS5TeXN0ZW1Mb2dpbiAhPT0gSGFuZHNoYWtlUmVzcG9uc2UuU1lTVEVNX0xPR0lOX0FEKSB7XHJcbiAgICAgICAgICAvLyBhdXRoZW50aWNhdGlvbiAodG8gdGhlIHJ1bnRpbWUtZW5naW5lKSBkaWFsb2dcclxuICAgICAgICAgIGlmIChsYXN0VHlwZWRVc2VySWQgIT09IG51bGwpIHtcclxuICAgICAgICAgICAgbGV0IHRpdGxlOiBzdHJpbmcgPSBBY2Nlc3NIZWxwZXIubGFuZ3VhZ2VEYXRhLmdldENvbnN0TWVzc2FnZShNc2dJbnRlcmZhY2UuQlJLVEFCX1NUUl9FUlJPUik7XHJcbiAgICAgICAgICAgIGxldCBlcnJvcjogc3RyaW5nID0gQWNjZXNzSGVscGVyLmxhbmd1YWdlRGF0YS5nZXRDb25zdE1lc3NhZ2UoTXNnSW50ZXJmYWNlLlVTUklOUF9TVFJfQkFEUEFTU1cpO1xyXG4gICAgICAgICAgICBhd2FpdCBHVUlNYW5hZ2VyLkluc3RhbmNlLk1lc3NhZ2VCb3godGl0bGUsIGVycm9yLCBTdHlsZXMuTVNHQk9YX0lDT05fRVJST1IgfCBTdHlsZXMuTVNHQk9YX0JVVFRPTl9PSyk7XHJcbiAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgLy8gVE9ETzogaW1wbGVtZW50IGF1dGhlbnRpY2F0aW9uIGRpYWxvZ1xyXG4gICAgICAgICAgLy8gbGV0IHVzZXJJZDogc3RyaW5nID0gbGFzdFR5cGVkVXNlcklkO1xyXG4gICAgICAgICAgLy9cclxuICAgICAgICAgIC8vIGlmIChkaWFsb2cgPT09IG51bGwpIHtcclxuICAgICAgICAgIC8vICAgZGlhbG9nID0gbmV3IEF1dGhlbnRpY2F0aW9uRGlhbG9nSGFuZGxlcih1c2VySWQsIEdldExvZ29uRGlhbG9nRXhlY1Byb3BzKCkpO1xyXG4gICAgICAgICAgLy8gfVxyXG4gICAgICAgICAgLy8gZGlhbG9nLm9wZW5EaWFsb2coKTtcclxuXHJcbiAgICAgICAgICAvLyBjcmVkZW50aWFscyA9IGRpYWxvZy5nZXRDcmVkZW50aWFscygpO1xyXG4gICAgICAgICAgLy8gaWYgKGNyZWRlbnRpYWxzICE9PSBudWxsKVxyXG4gICAgICAgICAgLy8gICBsYXN0VHlwZWRVc2VySWQgPSBjcmVkZW50aWFscy5Vc2VybmFtZTtcclxuICAgICAgICAgIC8vIGVsc2VcclxuICAgICAgICAgIC8vICAgYXV0aGVudGljYXRpb25DYW5jZWxsZWQgPSB0cnVlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gQ29uc3RJbnRlcmZhY2UuU0VTU0lPTl9DT1VOVEVSX0NMT1NFX0NUWF9JTkRJQ0FUSU9OIGluc3RydWN0cyB0aGUgc2VydmVyIHRvIGNsb3NlIHRoZSBjb250ZXh0LlxyXG4gICAgICAgIC8vIChub3RlOiB1bmxvYWRpbmcgYSBjb250ZXh0IHBvc3QgaGFuZHNoYWtlIHNob3VsZCBiZSBkb25lIHVzaW5nIENvbW1hbmQuY3JlYXRlVW5sb2FkQ29tbWFuZCkuXHJcbiAgICAgICAgaWYgKGF1dGhlbnRpY2F0aW9uQ2FuY2VsbGVkKSB7XHJcbiAgICAgICAgICB0aGlzLlNldFNlc3Npb25Db3VudGVyKENvbnN0SW50ZXJmYWNlLlNFU1NJT05fQ09VTlRFUl9DTE9TRV9DVFhfSU5ESUNBVElPTik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBsZXQgaGFuZHNoYWtlQXV0aFVybDogc3RyaW5nID0gdGhpcy5QcmVwYXJlQXV0aGVudGljYXRpb25VcmwoaGFuZHNoYWtlUmVzcG9uc2UuQ29udGV4dElkLCBjdHhHcm91cCwgdGhpcy5HZXRTZXNzaW9uQ291bnRlcigpKTtcclxuXHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgIGlmIChjcmVkZW50aWFscyAhPT0gbnVsbCkge1xyXG4gICAgICAgICAgICBsZXQgY3JlZGVudGlhbHNTdHI6IHN0cmluZyA9IGNyZWRlbnRpYWxzLlVzZXJuYW1lICsgXCI6XCI7XHJcbiAgICAgICAgICAgIGlmICghTlN0cmluZy5Jc051bGxPckVtcHR5KGNyZWRlbnRpYWxzLlBhc3N3b3JkKSkge1xyXG4gICAgICAgICAgICAgIGNyZWRlbnRpYWxzU3RyID0gY3JlZGVudGlhbHNTdHIgKyBjcmVkZW50aWFscy5QYXNzd29yZCArIFwiOlwiO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNyZWRlbnRpYWxzU3RyICs9IGhhbmRzaGFrZVJlc3BvbnNlLkNvbnRleHRJZDtcclxuICAgICAgICAgICAgY3JlZGVudGlhbHNTdHIgPSBTY3JhbWJsZXIuU2NyYW1ibGUoY3JlZGVudGlhbHNTdHIpO1xyXG4gICAgICAgICAgICBjcmVkZW50aWFsc1N0ciA9IEJhc2U2NC5lbmNvZGUoY3JlZGVudGlhbHNTdHIsIHRydWUsIEVuY29kaW5nLlVURjgpO1xyXG4gICAgICAgICAgICBoYW5kc2hha2VBdXRoVXJsICs9IChcIiZVU0VSTkFNRT1cIiArIEh0dHBVdGlsaXR5LlVybEVuY29kZShjcmVkZW50aWFsc1N0ciwgRW5jb2RpbmcuVVRGOCkpO1xyXG5cclxuICAgICAgICAgICAgLy8gc2VuZCAybmQgaGFuZHNoYWtlIHJlcXVlc3QgLSB3aXRoIGF1dGhlbnRpY2F0aW9uXHJcbiAgICAgICAgICAgIExvZ2dlci5JbnN0YW5jZS5Xcml0ZVNlcnZlck1lc3NhZ2VzVG9Mb2coTlN0cmluZy5Gb3JtYXQoXCJIYW5kc2hha2UgcmVxdWVzdCAjMjogezB9XCIsIGhhbmRzaGFrZUF1dGhVcmwpKTtcclxuICAgICAgICAgICAgbGV0IHN0YXR1c1JlcXVlc3Q6IFJlZlBhcmFtPFJlcXVlc3RTdGF0dXM+ID0gbmV3IFJlZlBhcmFtKFJlcXVlc3RTdGF0dXMuSGFuZGxlZCk7XHJcbiAgICAgICAgICAgIHJlc3BvbnNlU3RyID0gYXdhaXQgdGhpcy5EaXNwYXRjaFJlcXVlc3QoaGFuZHNoYWtlQXV0aFVybCwgbnVsbCwgQ29tbWFuZHNQcm9jZXNzb3JCYXNlX1Nlc3Npb25TdGFnZS5IQU5EU0hBS0UsIHN0YXR1c1JlcXVlc3QpO1xyXG5cclxuICAgICAgICAgICAgLy8gdmVyaWZ5IHRoYXQgdGhlIHJlc3BvbnNlIHdhc24ndCByZXBsYXllZFxyXG4gICAgICAgICAgICBpZiAocmVzcG9uc2VTdHIuaW5kZXhPZihoYW5kc2hha2VSZXNwb25zZS5Db250ZXh0SWQpID09PSAtMSkge1xyXG4gICAgICAgICAgICAgIHRocm93IG5ldyBTZXJ2ZXJFcnJvcihBY2Nlc3NIZWxwZXIubGFuZ3VhZ2VEYXRhLmdldENvbnN0TWVzc2FnZShNc2dJbnRlcmZhY2UuVVNSSU5QX1NUUl9CQURQQVNTVykpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBTZXJ2ZXJDb25maWcuSW5zdGFuY2Uuc2V0VXNlcm5hbWUoY3JlZGVudGlhbHMuVXNlcm5hbWUpO1xyXG4gICAgICAgICAgICBTZXJ2ZXJDb25maWcuSW5zdGFuY2Uuc2V0UGFzc3dvcmQoY3JlZGVudGlhbHMuUGFzc3dvcmQpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIGxldCByZXF1ZXN0U3RhdHVzOiBSZWZQYXJhbTxSZXF1ZXN0U3RhdHVzPiA9IG5ldyBSZWZQYXJhbShSZXF1ZXN0U3RhdHVzLkhhbmRsZWQpO1xyXG4gICAgICAgICAgICAvLyBzZW5kIDJuZCBoYW5kc2hha2UgcmVxdWVzdCAtIHdpdGhvdXQgYXV0aGVudGljYXRpb25cclxuICAgICAgICAgICAgTG9nZ2VyLkluc3RhbmNlLldyaXRlU2VydmVyTWVzc2FnZXNUb0xvZyhOU3RyaW5nLkZvcm1hdChcIkhhbmRzaGFrZSByZXF1ZXN0ICMyOiB7MH1cIiwgaGFuZHNoYWtlQXV0aFVybCkpO1xyXG4gICAgICAgICAgICByZXNwb25zZVN0ciA9IGF3YWl0IHRoaXMuRGlzcGF0Y2hSZXF1ZXN0KGhhbmRzaGFrZUF1dGhVcmwsIG51bGwsIENvbW1hbmRzUHJvY2Vzc29yQmFzZV9TZXNzaW9uU3RhZ2UuSEFORFNIQUtFLCByZXF1ZXN0U3RhdHVzKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIExvZ2dlci5JbnN0YW5jZS5Xcml0ZVNlcnZlck1lc3NhZ2VzVG9Mb2coTlN0cmluZy5Gb3JtYXQoXCJIYW5kc2hha2UgcmVzcG9uc2UgIzI6IHswfVwiLCByZXNwb25zZVN0cikpO1xyXG4gICAgICAgICAgTG9nZ2VyLkluc3RhbmNlLldyaXRlU2VydmVyTWVzc2FnZXNUb0xvZyhcIlwiKTtcclxuICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjYXRjaCAoZXgpIHtcclxuICAgICAgICAgIGlmIChleCBpbnN0YW5jZW9mIFNlcnZlckVycm9yKSB7XHJcbiAgICAgICAgICAgIGxldCBzZXJ2ZXJFcnJvcjogU2VydmVyRXJyb3IgPSA8U2VydmVyRXJyb3I+ZXg7XHJcbiAgICAgICAgICAgIGlmIChTZXJ2ZXJDb25maWcuSW5zdGFuY2UuZ2V0U2tpcEF1dGhlbnRpY2F0aW9uRGlhbG9nKCkpIHtcclxuICAgICAgICAgICAgICBzd2l0Y2ggKHNlcnZlckVycm9yLkdldENvZGUoKSlcclxuICAgICAgICAgICAgICB7XHJcbiAgICAgICAgICAgICAgICBjYXNlIFNlcnZlckVycm9yLkVSUl9BQ0NFU1NfREVOSUVEOlxyXG4gICAgICAgICAgICAgICAgLy8gRXh0ZXJuYWwgQXV0aGVudGljYXRvciBhdXRoZW50aWNhdGVkIHRoZSB1c2VyLCBhY2Nlc3MgdG8gdGhlIGFwcGxpY2F0aW9uIHdhc24ndCBhdXRob3JpemVkLlxyXG4gICAgICAgICAgICAgICAgY2FzZSBTZXJ2ZXJFcnJvci5FUlJfQVVUSEVOVElDQVRJT046XHJcbiAgICAgICAgICAgICAgICAgIC8vIEV4dGVybmFsIEF1dGhlbnRpY2F0b3IgYXV0aGVudGljYXRlZCB0aGUgdXNlciBidXQgYXBwbGljYXRpb24gYXV0aGVudGljYXRpb24gZmFpbGVkXHJcbiAgICAgICAgICAgICAgICAgIFNlcnZlckNvbmZpZy5JbnN0YW5jZS5zZXRTa2lwQXV0aGVudGljYXRpb25EaWFsb2coZmFsc2UpO1xyXG4gICAgICAgICAgICAgICAgICB0aHJvdyBzZXJ2ZXJFcnJvcjtcclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIHRoZSBzZXNzaW9uIHdpbGwgbmV2ZXIgcHJvdmlkZSBhIHdheSB0byBjaGFuZ2UgdGhlIGNyZWRlbnRpYWxzLCB0aGVyZWZvcmUgYWJvcnRcclxuICAgICAgICAgICAgaWYgKCFoYW5kc2hha2VSZXNwb25zZS5JbnB1dFBhc3N3b3JkKVxyXG4gICAgICAgICAgICAgIHRocm93IHNlcnZlckVycm9yO1xyXG5cclxuICAgICAgICAgICAgLy8gRXJyb3IuSU5GX05PX1JFU1VMVDpcclxuICAgICAgICAgICAgLy8gICAgaWYgYXV0aGVudGljYXRpb24gZGlhbG9nIHdhcyBjYW5jZWxlZCwgdGhlIHJlcXVlc3Qgd2FzIHNlbnQgb25seSB0byBjbG9zZSB0aGUgY29udGV4dCxcclxuICAgICAgICAgICAgLy8gICAgYW5kIHRoZSBzZXJ2ZXIgaXNuJ3QgZXhwZWN0ZWQgdG8gcmV0dXJuIGEgcmVzcG9uc2VcclxuICAgICAgICAgICAgaWYgKHNlcnZlckVycm9yLkdldENvZGUoKSAhPT0gU2VydmVyRXJyb3IuRVJSX0FVVEhFTlRJQ0FUSU9OICYmXHJcbiAgICAgICAgICAgICAgICAoIWF1dGhlbnRpY2F0aW9uQ2FuY2VsbGVkIHx8IHNlcnZlckVycm9yLkdldENvZGUoKSAhPT0gU2VydmVyRXJyb3IuSU5GX05PX1JFU1VMVCkpIHtcclxuICAgICAgICAgICAgICB0aHJvdyBzZXJ2ZXJFcnJvcjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgZWxzZVxyXG4gICAgICAgICAgICB0aHJvdyBleDtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIHN0b3JlIGFuIGluZGljYXRpb24gdG8gc2tpcCBmdXR1cmUgYXV0aGVudGljYXRpb24gKHNlc3Npb24gcmVzdGFydCwgcGFyYWxsZWwgcHJvZ3JhbSlcclxuICAgICAgU2VydmVyQ29uZmlnLkluc3RhbmNlLnNldFNraXBBdXRoZW50aWNhdGlvbkRpYWxvZyh0cnVlKTtcclxuXHJcbiAgICAgIC8vIHNhdmUgY29udGV4dCBncm91cFxyXG4gICAgICBTZXJ2ZXJDb25maWcuSW5zdGFuY2Uuc2V0Q3R4R3JvdXAoY3R4R3JvdXApO1xyXG5cclxuICAgICAgaWYgKGRpYWxvZyAhPT0gbnVsbClcclxuICAgICAgICBkaWFsb2cuY2xvc2VEaWFsb2coKTtcclxuXHJcbiAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4gICAgICAvLyBzZXQgc2Vzc2lvbiBwcm9wZXJ0aWVzXHJcbiAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4gICAgICBSZW1vdGVDb21tYW5kc1Byb2Nlc3Nvci5TaG91bGRTY3JhbWJsZUFuZFVuc2NyYW1ibGVNZXNzYWdlcyA9IGhhbmRzaGFrZVJlc3BvbnNlLlNjcmFtYmxlTWVzc2FnZXM7XHJcbiAgICAgIGlmIChMb2dnZXIuSW5zdGFuY2UuTG9nTGV2ZWwgIT09IExvZ2dlcl9Mb2dMZXZlbHMuQmFzaWMpIHtcclxuICAgICAgICAvLyBtYXhpbWFsIHZhbHVlIG9mIHRoZSBJbnRlcm5hbExvZ0xldmVsIHRoYXQgY2FuIGJlIHNldCBieSB0aGUgY2xpZW50LlxyXG4gICAgICAgIC8vIGlmIHNldCwgaXQgY29udHJvbHMgdGhlIG1heGltYWwgdmFsdWU7IG90aGVyd2lzZSwgYW55IGxvZyBsZXZlbCBpcyBhbGxvd2VkLlxyXG4gICAgICAgIGxldCBtYXhJbnRlcm5hbExvZ0xldmVsOiBzdHJpbmcgPSBoYW5kc2hha2VSZXNwb25zZS5NYXhJbnRlcm5hbExvZ0xldmVsO1xyXG4gICAgICAgIGlmIChtYXhJbnRlcm5hbExvZ0xldmVsICE9PSBudWxsKSB7XHJcbiAgICAgICAgICBsZXQgbWF4TG9nTGV2ZWw6IExvZ2dlcl9Mb2dMZXZlbHMgPSB0aGlzLnBhcnNlTG9nTGV2ZWwobWF4SW50ZXJuYWxMb2dMZXZlbCk7XHJcbiAgICAgICAgICBpZiAobWF4TG9nTGV2ZWwgPCBMb2dnZXIuSW5zdGFuY2UuTG9nTGV2ZWwpIHtcclxuICAgICAgICAgICAgLy8gdGV4dHVhbCB2YWx1ZSAoYXMgbG9hZGVkIGZyb20gdGhlIGV4ZWN1dGlvbiBwcm9wZXJ0aWVzKVxyXG4gICAgICAgICAgICBTZXJ2ZXJDb25maWcuSW5zdGFuY2Uuc2V0SW50ZXJuYWxMb2dMZXZlbChtYXhJbnRlcm5hbExvZ0xldmVsKTtcclxuXHJcbiAgICAgICAgICAgIC8vIHNldCB0aGUgYWN0dWFsIGxvZyBsZXZlbCB0byB0aGUgbGV2ZWwgYWxsb3dlZCBieSB0aGUgc2VydmVyXHJcbiAgICAgICAgICAgIExvZ2dlci5JbnN0YW5jZS5Xcml0ZVRvTG9nKE5TdHJpbmcuRm9ybWF0KFwiSW50ZXJuYWwgbG9nIGxldmVsIHdhcyByZXN0cmljdGVkIHRvICd7MH0nIGJ5IHRoZSBNYWdpYyB4cGEgc2VydmVyLlwiLCBtYXhJbnRlcm5hbExvZ0xldmVsKSwgZmFsc2UpO1xyXG4gICAgICAgICAgICBMb2dnZXIuSW5zdGFuY2UuTG9nTGV2ZWwgPSBtYXhMb2dMZXZlbDtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuICAgICAgLy8gM3JkIHJlcXVlc3Q6IEV4ZWN1dGVzIHRoZSBpbml0aWFsIHByb2dyYW0gaW4gdGhlIHNlcnZlci5cclxuICAgICAgLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG4gICAgICBpZiAoIWF1dGhlbnRpY2F0aW9uQ2FuY2VsbGVkKSB7XHJcbiAgICAgICAgYXdhaXQgdGhpcy5FeGVjdXRlSW5pdGlhbFJlcXVlc3QoKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgY2F0Y2ggKGV4KSB7XHJcbiAgICAgIGlmIChleCBpbnN0YW5jZW9mIFNlcnZlckVycm9yKVxyXG4gICAgICAgIHRocm93IGV4O1xyXG5cclxuICAgICAgaWYgKGlzTnVsbE9yVW5kZWZpbmVkKGV4LklubmVyRXhjZXB0aW9uKSlcclxuICAgICAgICB0aHJvdyAgbmV3IFNlcnZlckVycm9yKGV4Lm1lc3NhZ2UsIG5ldyBFeGNlcHRpb24oZXgpKTtcclxuICAgICAgZWxzZVxyXG4gICAgICAgIHRocm93IG5ldyBTZXJ2ZXJFcnJvcihleC5tZXNzYWdlLCBleC5Jbm5lckV4Y2VwdGlvbik7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuICFhdXRoZW50aWNhdGlvbkNhbmNlbGxlZDtcclxuICB9XHJcblxyXG4gIC8vLyA8c3VtbWFyeT5cclxuICAvLy8gcHJlcGFyZXMgaGFuZHNoYWtlIHJlcXVlc3QgdXJsIGZvciBhdXRoZW50aWNhdGlvblxyXG4gIC8vLyA8L3N1bW1hcnk+XHJcbiAgLy8vIDxwYXJhbSBuYW1lPVwiY29udGV4dElkXCI+PC9wYXJhbT5cclxuICAvLy8gPHBhcmFtIG5hbWU9XCJjdHhHcm91cFwiPjwvcGFyYW0+XHJcbiAgLy8vIDxwYXJhbSBuYW1lPVwic2Vzc2lvbkNvdW50XCI+PC9wYXJhbT5cclxuICAvLy8gPHJldHVybnM+PC9yZXR1cm5zPlxyXG4gIHByaXZhdGUgUHJlcGFyZUF1dGhlbnRpY2F0aW9uVXJsKGNvbnRleHRJZDogc3RyaW5nLCBjdHhHcm91cDogc3RyaW5nLCBzZXNzaW9uQ291bnQ6IG51bWJlcik6IHN0cmluZyB7XHJcbiAgICBsZXQgaGFuZHNoYWtlQXV0aFVybDogc3RyaW5nID0gdGhpcy5TZXJ2ZXJVcmwgKyBDb25zdEludGVyZmFjZS5SRVFfQVJHX1NUQVJUICtcclxuICAgICAgQ29uc3RJbnRlcmZhY2UuUkNfSU5ESUNBVElPTiArIENvbnN0SW50ZXJmYWNlLlVURjhUUkFOUyArXHJcbiAgICAgIENvbnN0SW50ZXJmYWNlLlJDX1RPS0VOX0NUWF9JRCArIGNvbnRleHRJZDtcclxuXHJcbiAgICBpZiAoIWlzTnVsbE9yVW5kZWZpbmVkKHRoaXMuU2Vzc2lvbklkKSlcclxuICAgICAgaGFuZHNoYWtlQXV0aFVybCArPSAoQ29uc3RJbnRlcmZhY2UuUkVRX0FSR19TRVBBUkFUT1IgKyAgQ29uc3RJbnRlcmZhY2UuUkNfVE9LRU5fU0VTU0lPTl9JRCArIHRoaXMuU2Vzc2lvbklkKTtcclxuXHJcbiAgICBoYW5kc2hha2VBdXRoVXJsICs9IChDb25zdEludGVyZmFjZS5SRVFfQVJHX1NFUEFSQVRPUiArXHJcbiAgICAgICAgQ29uc3RJbnRlcmZhY2UuUkNfVE9LRU5fU0VTU0lPTl9DT1VOVCArIHNlc3Npb25Db3VudCArXHJcbiAgICAgICAgQ29uc3RJbnRlcmZhY2UuUkVRX0FSR19TRVBBUkFUT1IgK1xyXG4gICAgICAgIENvbnN0SW50ZXJmYWNlLlJDX1RPS0VOX0NUWF9HUk9VUCArIGN0eEdyb3VwICtcclxuICAgICAgICBDb25zdEludGVyZmFjZS5SRVFfQVJHX1NFUEFSQVRPUiArXHJcbiAgICAgICAgQ29uc3RJbnRlcmZhY2UuUkNfQVVUSEVOVElDQVRJT05fUkVRVUVTVCk7XHJcblxyXG4gICAgcmV0dXJuIGhhbmRzaGFrZUF1dGhVcmw7XHJcbiAgfVxyXG5cclxuICAvLy8gPHN1bW1hcnk+XHJcbiAgLy8vIEV4ZWN1dGVzIHRoZSBpbml0aWFsIHByb2dyYW0gaW4gdGhlIHNlcnZlcjpcclxuICAvLy8gPC9zdW1tYXJ5PlxyXG4gIHByaXZhdGUgYXN5bmMgRXhlY3V0ZUluaXRpYWxSZXF1ZXN0KCk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgLy8gc2VuZCB0aGUgSU5JVElBTCByZXF1ZXN0IHRvIHRoZSBzZXJ2ZXIuXHJcbiAgICBhd2FpdCB0aGlzLkV4ZWN1dGVfMShDb21tYW5kc1Byb2Nlc3NvckJhc2VfU2VuZGluZ0luc3RydWN0aW9uLlRBU0tTX0FORF9DT01NQU5EUywgQ29tbWFuZHNQcm9jZXNzb3JCYXNlX1Nlc3Npb25TdGFnZS5JTklUSUFMLCBudWxsKTtcclxuICB9XHJcblxyXG4gIC8vIHByaXZhdGUgc3RhdGljIEdldExvZ29uRGlhbG9nRXhlY1Byb3BzKCk6IERpY3Rpb25hcnk8c3RyaW5nLCBzdHJpbmc+IHtcclxuICAvLyAgIGxldCBkaWN0aW9uYXJ5OiBEaWN0aW9uYXJ5PHN0cmluZywgc3RyaW5nPiA9IG5ldyBEaWN0aW9uYXJ5PHN0cmluZywgc3RyaW5nPigpO1xyXG4gIC8vICAgbGV0IHZhbHVlOiBzdHJpbmcgPSBDbGllbnRNYW5hZ2VyLkluc3RhbmNlLmdldExvZ29uV2luZG93VGl0bGUoKTtcclxuICAvLyAgIGxldCBmbGFnOiBib29sZWFuID0gTlN0cmluZy5Jc051bGxPckVtcHR5KHZhbHVlKTtcclxuICAvLyAgIGlmIChmbGFnKSB7XHJcbiAgLy8gICAgIHZhbHVlID0gXCJMb2dvbiAtIFwiICsgQ2xpZW50TWFuYWdlci5JbnN0YW5jZS5nZXRBcHBOYW1lKCk7XHJcbiAgLy8gICB9XHJcbiAgLy8gICBkaWN0aW9uYXJ5LkFkZChcIkxvZ29uV2luZG93VGl0bGVcIiwgdmFsdWUpO1xyXG4gIC8vICAgbGV0IHRleHQ6IHN0cmluZyA9IENsaWVudE1hbmFnZXIuSW5zdGFuY2UuZ2V0TG9nb25Hcm91cFRpdGxlKCk7XHJcbiAgLy8gICBsZXQgZmxhZzI6IGJvb2xlYW4gPSAhTlN0cmluZy5Jc051bGxPckVtcHR5KHRleHQpO1xyXG4gIC8vICAgaWYgKGZsYWcyKSB7XHJcbiAgLy8gICAgIHRleHQgPSAoKHRleHQubGVuZ3RoID4gNjIpID8gTlN0cmluZy5TdWJzdHJpbmcodGV4dCwgMCwgNjIpIDogdGV4dCk7XHJcbiAgLy8gICB9XHJcbiAgLy8gICBlbHNlIHtcclxuICAvLyAgICAgdGV4dCA9IFwiTG9nb24gUGFyYW1ldGVyc1wiO1xyXG4gIC8vICAgfVxyXG4gIC8vICAgZGljdGlvbmFyeS5BZGQoXCJMb2dvbkdyb3VwVGl0bGVcIiwgdGV4dCk7XHJcbiAgLy8gICBsZXQgdGV4dDI6IHN0cmluZyA9IENsaWVudE1hbmFnZXIuSW5zdGFuY2UuZ2V0TG9nb25Nc2dDYXB0aW9uKCk7XHJcbiAgLy8gICBsZXQgZmxhZzM6IGJvb2xlYW4gPSAhTlN0cmluZy5Jc051bGxPckVtcHR5KHRleHQyKTtcclxuICAvLyAgIGlmIChmbGFnMykge1xyXG4gIC8vICAgICB0ZXh0MiA9ICgodGV4dDIubGVuZ3RoID4gNTYpID8gTlN0cmluZy5TdWJzdHJpbmcodGV4dDIsIDAsIDU2KSA6IHRleHQyKTtcclxuICAvLyAgICAgZGljdGlvbmFyeS5BZGQoXCJMb2dvbk1lc3NhZ2VDYXB0aW9uXCIsIHRleHQyKTtcclxuICAvLyAgIH1cclxuICAvLyAgIGxldCBsb2dvbldpbmRvd0ljb25VUkw6IFVyaSA9IENsaWVudE1hbmFnZXIuSW5zdGFuY2UuZ2V0TG9nb25XaW5kb3dJY29uVVJMKCk7XHJcbiAgLy8gICBsZXQgZmxhZzQ6IGJvb2xlYW4gPSBVcmkub3BfSW5lcXVhbGl0eShsb2dvbldpbmRvd0ljb25VUkwsIG51bGwpICYmICFOU3RyaW5nLklzTnVsbE9yRW1wdHkobG9nb25XaW5kb3dJY29uVVJMLlRvU3RyaW5nKCkpO1xyXG4gIC8vICAgaWYgKGZsYWc0KSB7XHJcbiAgLy8gICAgIGRpY3Rpb25hcnkuQWRkKFwiTG9nb25XaW5kb3dJY29uVVJMXCIsIGxvZ29uV2luZG93SWNvblVSTC5Ub1N0cmluZygpKTtcclxuICAvLyAgIH1cclxuICAvLyAgIGxldCBsb2dvbldpbmRvd0ltYWdlVVJMOiBVcmkgPSBDbGllbnRNYW5hZ2VyLkluc3RhbmNlLmdldExvZ29uV2luZG93SW1hZ2VVUkwoKTtcclxuICAvLyAgIGxldCBmbGFnNTogYm9vbGVhbiA9IFVyaS5vcF9JbmVxdWFsaXR5KGxvZ29uV2luZG93SW1hZ2VVUkwsIG51bGwpICYmICFOU3RyaW5nLklzTnVsbE9yRW1wdHkobG9nb25XaW5kb3dJbWFnZVVSTC5Ub1N0cmluZygpKTtcclxuICAvLyAgIGlmIChmbGFnNSkge1xyXG4gIC8vICAgICBkaWN0aW9uYXJ5LkFkZChcIkxvZ29uSW1hZ2VVUkxcIiwgbG9nb25XaW5kb3dJbWFnZVVSTC5Ub1N0cmluZygpKTtcclxuICAvLyAgIH1cclxuICAvLyAgIGxldCB0ZXh0Mzogc3RyaW5nID0gQ2xpZW50TWFuYWdlci5JbnN0YW5jZS5nZXRMb2dvblVzZXJJZENhcHRpb24oKTtcclxuICAvLyAgIGxldCBmbGFnNjogYm9vbGVhbiA9ICFOU3RyaW5nLklzTnVsbE9yRW1wdHkodGV4dDMpO1xyXG4gIC8vICAgaWYgKGZsYWc2KSB7XHJcbiAgLy8gICAgIHRleHQzID0gKCh0ZXh0My5sZW5ndGggPiA5KSA/IE5TdHJpbmcuU3Vic3RyaW5nKHRleHQzLCAwLCA5KSA6IHRleHQzKTtcclxuICAvLyAgICAgZGljdGlvbmFyeS5BZGQoXCJMb2dvblVzZXJJRENhcHRpb25cIiwgdGV4dDMpO1xyXG4gIC8vICAgfVxyXG4gIC8vICAgbGV0IHRleHQ0OiBzdHJpbmcgPSBDbGllbnRNYW5hZ2VyLkluc3RhbmNlLmdldExvZ29uUGFzc3dvcmRDYXB0aW9uKCk7XHJcbiAgLy8gICBsZXQgZmxhZzc6IGJvb2xlYW4gPSAhTlN0cmluZy5Jc051bGxPckVtcHR5KHRleHQ0KTtcclxuICAvLyAgIGlmIChmbGFnNykge1xyXG4gIC8vICAgICB0ZXh0NCA9ICgodGV4dDQubGVuZ3RoID4gOSkgPyBOU3RyaW5nLlN1YnN0cmluZyh0ZXh0NCwgMCwgOSkgOiB0ZXh0NCk7XHJcbiAgLy8gICAgIGRpY3Rpb25hcnkuQWRkKFwiTG9nb25QYXNzd29yZENhcHRpb25cIiwgdGV4dDQpO1xyXG4gIC8vICAgfVxyXG4gIC8vICAgbGV0IGxvZ29uT0tDYXB0aW9uOiBzdHJpbmcgPSBDbGllbnRNYW5hZ2VyLkluc3RhbmNlLmdldExvZ29uT0tDYXB0aW9uKCk7XHJcbiAgLy8gICBsZXQgZmxhZzg6IGJvb2xlYW4gPSAhTlN0cmluZy5Jc051bGxPckVtcHR5KGxvZ29uT0tDYXB0aW9uKTtcclxuICAvLyAgIGlmIChmbGFnOCkge1xyXG4gIC8vICAgICBkaWN0aW9uYXJ5LkFkZChcIkxvZ29uT0tDYXB0aW9uXCIsIGxvZ29uT0tDYXB0aW9uKTtcclxuICAvLyAgIH1cclxuICAvLyAgIGxldCBsb2dvbkNhbmNlbENhcHRpb246IHN0cmluZyA9IENsaWVudE1hbmFnZXIuSW5zdGFuY2UuZ2V0TG9nb25DYW5jZWxDYXB0aW9uKCk7XHJcbiAgLy8gICBsZXQgZmxhZzk6IGJvb2xlYW4gPSAhTlN0cmluZy5Jc051bGxPckVtcHR5KGxvZ29uQ2FuY2VsQ2FwdGlvbik7XHJcbiAgLy8gICBpZiAoZmxhZzkpIHtcclxuICAvLyAgICAgZGljdGlvbmFyeS5BZGQoXCJMb2dvbkNhbmNlbENhcHRpb25cIiwgbG9nb25DYW5jZWxDYXB0aW9uKTtcclxuICAvLyAgIH1cclxuICAvLyAgIHJldHVybiBkaWN0aW9uYXJ5O1xyXG4gIC8vIH1cclxuXHJcblxyXG5cclxuICAvLy8gPHN1bW1hcnk+XHJcbiAgLy8vIFJldHVybiB0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHJ1bnRpbWUgdGFzayB0cmVlIHN0cnVjdHVyZSBieSBnb2luZyB1cCBmcm9tIHRoZSBjdXJyZW50IHRhc2tcclxuICAvLy8gPC9zdW1tYXJ5PlxyXG4gIHByaXZhdGUgR2V0VGFza1RyZWUodGFzazogVGFzayk6IExpc3Q8c3RyaW5nPiB7XHJcbiAgICBsZXQgdGFza1RyZWU6IExpc3Q8c3RyaW5nPiA9IG5ldyBMaXN0PHN0cmluZz4oKTtcclxuXHJcbiAgICB3aGlsZSghaXNOdWxsT3JVbmRlZmluZWQodGFzaykpXHJcbiAgICB7XHJcbiAgICAgIHRhc2tUcmVlLnB1c2godGFzay5nZXRUYXNrSW5mbygpKTtcclxuICAgICAgdGFzayA9IDxUYXNrPnRhc2suZ2V0UGFyZW50KCk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHRhc2tUcmVlO1xyXG4gIH1cclxuXHJcbiAgLy8vIDxzdW1tYXJ5PlxyXG4gIC8vLyBVcGRhdGUgdGhlIHJlcXVlc3QgaW5mbyBvYmplY3QgdXNpbmcgaW5mb3JtYXRpb24gb2J0YWluZWQgZnJvbSBjdXJyZW50IG9wZXJhdGlvbiBiZWluZyBleGVjdXRlZC5cclxuICAvLy8gPC9zdW1tYXJ5PlxyXG4gIHByaXZhdGUgYXN5bmMgVXBkYXRlUmVxdWVzdEluZm8oKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICBsZXQgY3Vyck1HRGF0YTogTUdEYXRhID0gQWNjZXNzSGVscGVyLm1nRGF0YVRhYmxlLmdldEN1cnJNR0RhdGEoKTtcclxuICAgIGxldCBldmVudHNNYW5hZ2VyOiBFdmVudHNNYW5hZ2VyID0gPEV2ZW50c01hbmFnZXI+QWNjZXNzSGVscGVyLmV2ZW50c01hbmFnZXI7XHJcbiAgICBsZXQgb3BlckV4ZWN1dGlvbjpib29sZWFuID0gZmFsc2U7XHJcbiAgICBsZXQgY21kc1RvU2VydmVyOiBDb21tYW5kc1RhYmxlID0gPENvbW1hbmRzVGFibGU+Y3Vyck1HRGF0YS5DbWRzVG9TZXJ2ZXI7XHJcblxyXG4gICAgZm9yKGxldCBpPTA7IGk8IGNtZHNUb1NlcnZlci5nZXRTaXplKCk7IGkrKylcclxuICAgIHtcclxuICAgICAgLy8gV2hlbiB0aGUgcmVxdWVzdCBpcyBiZWluZyBzZW50IHRvIHNlcnZlciBkdWUgdG8gYW4gb3BlcmF0aW9uIGV4ZWN1dGlvbiwgZ2V0IHRoZSBpbmZvcm1hdGlvbiBvZiBjdXJyZW50IG9wZXJhdGlvbiBmcm9tIENtZHNUb1NlcnZlclxyXG4gICAgICBpZihjbWRzVG9TZXJ2ZXIuZ2V0Q21kKGkpIGluc3RhbmNlb2YgRXhlY09wZXJDb21tYW5kKSB7XHJcbiAgICAgICAgbGV0IG9wZXJDbWQ6RXhlY09wZXJDb21tYW5kID0gPEV4ZWNPcGVyQ29tbWFuZD4oPENvbW1hbmRzVGFibGU+Y3Vyck1HRGF0YS5DbWRzVG9TZXJ2ZXIpLmdldENtZChpKTtcclxuXHJcbiAgICAgICAgdGhpcy5fcmVxdWVzdEluZm8uc2VydmVyQ2FsbEF0ID0gb3BlckNtZC5nZXRDb21tYW5kSW5mbygpO1xyXG5cclxuICAgICAgICB0aGlzLl9yZXF1ZXN0SW5mby5ydW50aW1lVGFza1RyZWUgPSB0aGlzLkdldFRhc2tUcmVlKG9wZXJDbWQuZ2V0VGFzaygpKTtcclxuICAgICAgICBvcGVyRXhlY3V0aW9uID0gdHJ1ZTtcclxuICAgICAgICBicmVhaztcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuX3JlcXVlc3RJbmZvLmV4dHJhSW5mby5jb250ZXh0SUQgPSBSdW50aW1lQ29udGV4dEJhc2UuSW5zdGFuY2UuQ29udGV4dElEO1xyXG4gICAgdGhpcy5fcmVxdWVzdEluZm8uZXh0cmFJbmZvLnNlc3Npb25Db3VudGVyID0gdGhpcy5HZXRTZXNzaW9uQ291bnRlcigpO1xyXG5cclxuICAgIC8vIExvZyBpbmZvcm1hdGlvbiBhYm91dCBtYWdpYyBpbnRlcm5hbCBldmVudHMgY2F1c2luZyByZXF1ZXN0cyB0byBzZXJ2ZXJcclxuICAgIGlmKCFvcGVyRXhlY3V0aW9uKVxyXG4gICAge1xyXG4gICAgICBpZihldmVudHNNYW5hZ2VyLmdldExhc3RSdEV2ZW50KCkgIT0gbnVsbCAmJiBldmVudHNNYW5hZ2VyLmdldExhc3RSdEV2ZW50KCkuSW50ZXJuYWxFdmVudCAhPSAwKVxyXG4gICAgICB7XHJcbiAgICAgICAgbGV0IHJ0RXZ0OlJ1blRpbWVFdmVudCA9IGV2ZW50c01hbmFnZXIuZ2V0TGFzdFJ0RXZlbnQoKTtcclxuICAgICAgICB0aGlzLl9yZXF1ZXN0SW5mby5ydW50aW1lVGFza1RyZWUgPSB0aGlzLkdldFRhc2tUcmVlKDxUYXNrPnJ0RXZ0LmdldFRhc2soKSk7XHJcblxyXG4gICAgICAgIC8vIHJldHVybiBkZXNjcmlwdGlvbiBhcyBwZXIgbmV3L29sZCBpbnRlcm5hbCBldmVudCBkZXNjXHJcbiAgICAgICAgbGV0IGV2ZW50RGVzY3JpcHRpb246IHN0cmluZyA9ICBydEV2dC5pc05ld0ludGVybmFsRXZlbnQoKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IE5TdHJpbmcuVHJpbUVuZChydEV2dC5nZXROZXdJbnRlcm5hbEV2ZW50RGVzY3JpcHRpb24oKSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBFdmVudC5nZXRJbnRlcm5hbEV2dERlc2NyaXB0aW9uKHJ0RXZ0LkludGVybmFsRXZlbnQpO1xyXG5cclxuXHJcbiAgICAgICAgLy8gZS5nLiBFdmVudCBbPE5leHQgQ2h1bms+XSB3aGlsZSBleGVjdXRpbmcgWzxWaWV3IFJlZnJlc2g+XVxyXG4gICAgICAgIGxldCBjbWQ6IElDbGllbnRDb21tYW5kID0gY21kc1RvU2VydmVyLmdldENtZChjbWRzVG9TZXJ2ZXIuZ2V0U2l6ZSgpIC0gMSk7XHJcbiAgICAgICAgaWYoY21kIGFzIElDbGllbnRUb1NlcnZlckNvbW1hbmRJbmZvKSB7XHJcbiAgICAgICAgICBsZXQgY29tbWFuZEluZm86IHN0cmluZyA9IE5TdHJpbmcuSXNOdWxsT3JFbXB0eSgoPElDbGllbnRUb1NlcnZlckNvbW1hbmRJbmZvPmNtZCkuZ2V0Q29tbWFuZEluZm8oKSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IE5TdHJpbmcuRW1wdHlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6ICg8SUNsaWVudFRvU2VydmVyQ29tbWFuZEluZm8+Y21kKS5nZXRDb21tYW5kSW5mbygpO1xyXG5cclxuICAgICAgICAgIC8vIEluIGNhc2UgdGhlIHJ1bnRpbWUgZXZlbnQgYW5kIEV2ZW50IGNvbW1hbmQgYXJlIHNhbWUsIG5vIG5lZWQgdG8gbG9nIHRoZSBleHRyYSBpbmZvcm1hdGlvblxyXG4gICAgICAgICAgaWYoY21kIGluc3RhbmNlb2YgRXZlbnRDb21tYW5kICYmIHJ0RXZ0LkludGVybmFsRXZlbnQgPT0gKDxFdmVudENvbW1hbmQ+Y21kKS5NYWdpY0V2ZW50KVxyXG4gICAgICAgICAgICBldmVudERlc2NyaXB0aW9uID0gTlN0cmluZy5FbXB0eTtcclxuXHJcbiAgICAgICAgICB0aGlzLl9yZXF1ZXN0SW5mby5zZXJ2ZXJDYWxsQXQgPSAgJ0V2ZW50ICcgKyBjb21tYW5kSW5mbyArXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCFOU3RyaW5nLklzTnVsbE9yRW1wdHkoZXZlbnREZXNjcmlwdGlvbilcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBOU3RyaW5nLkZvcm1hdCgnIHdoaWxlIGV4ZWN1dGluZyBbezB9XScsIGV2ZW50RGVzY3JpcHRpb24pXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogTlN0cmluZy5FbXB0eSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvLy8gPHN1bW1hcnk+XHJcbiAgLy8vIEJ1aWxkIHhtbCBmb3IgbWFpbiBwcm9nIGRhdGF2aWV3LiByZXF1aXJlZCBmb3IgcmUtaW5pdGlhbGl6aW5nIHNlc3Npb24uXHJcbiAgLy8vIDwvc3VtbWFyeT5cclxuICBwcml2YXRlIGFzeW5jIEJ1aWxkWE1MRm9yTWFpblByb2dyYW1EYXRhVmlldygpOiBQcm9taXNlPFN0cmluZz5cclxuICB7XHJcbiAgICBsZXQgbWVzc2FnZTogU3RyaW5nQnVpbGRlciA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7XHJcbiAgICBsZXQgZmlyc3RNZ0RhdGE6IE1HRGF0YSA9IE1HRGF0YUNvbGxlY3Rpb24uSW5zdGFuY2UuZ2V0TUdEYXRhKDApO1xyXG4gICAgbGV0IG1haW5Qcmc6IFRhc2sgPSBmaXJzdE1nRGF0YS5nZXRNYWluUHJvZygwKTtcclxuXHJcbiAgICB3aGlsZSAobWFpblByZyAhPSBudWxsKVxyXG4gICAge1xyXG4gICAgICBhd2FpdCBtYWluUHJnLmJ1aWxkWE1MKG1lc3NhZ2UpO1xyXG4gICAgICBtYWluUHJnID0gZmlyc3RNZ0RhdGEuZ2V0TmV4dE1haW5Qcm9nKG1haW5QcmcuZ2V0Q3RsSWR4KCkpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChSZW1vdGVDb21tYW5kc1Byb2Nlc3Nvci5TaG91bGRTY3JhbWJsZUFuZFVuc2NyYW1ibGVNZXNzYWdlcylcclxuICAgIHtcclxuICAgICAgbGV0IHNjcmFtYmxlZENoYW5nZXM6IHN0cmluZyA9IFNjcmFtYmxlci5TY3JhbWJsZShtZXNzYWdlLlRvU3RyaW5nKCkpO1xyXG4gICAgICBtZXNzYWdlID0gbmV3IFN0cmluZ0J1aWxkZXIoc2NyYW1ibGVkQ2hhbmdlcyk7XHJcbiAgICB9XHJcblxyXG4gICAgbWVzc2FnZS5JbnNlcnQoMCwgWE1MQ29uc3RhbnRzLk1HX1RBR19PUEVOKTtcclxuICAgIG1lc3NhZ2UuQXBwZW5kKFhNTENvbnN0YW50cy5NR19UQUdfWE1MX0VORF9UQUdHRUQpO1xyXG5cclxuICAgIHJldHVybiBtZXNzYWdlLlRvU3RyaW5nKCk7XHJcbiAgfVxyXG5cclxuXHJcbiAgYXN5bmMgRXhlY3V0ZV8xKHNlbmRpbmdJbnN0cnVjdGlvbjogQ29tbWFuZHNQcm9jZXNzb3JCYXNlX1NlbmRpbmdJbnN0cnVjdGlvbiwgc2Vzc2lvblN0YWdlOiBDb21tYW5kc1Byb2Nlc3NvckJhc2VfU2Vzc2lvblN0YWdlLCByZXM6IElSZXN1bHRWYWx1ZSk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgbGV0IHJlcUJ1Zjogc3RyaW5nO1xyXG4gICAgbGV0IGlzSW5pdGlhbENhbGw6IGJvb2xlYW4gPSBzZXNzaW9uU3RhZ2UgPT09IENvbW1hbmRzUHJvY2Vzc29yQmFzZV9TZXNzaW9uU3RhZ2UuSU5JVElBTDtcclxuICAgIGxldCBnbG9iYWxQYXJhbXNTdHJpbmc6IHN0cmluZyA9IG51bGw7XHJcblxyXG4gICAgaWYgKHRoaXMuRGVsYXlDb21tYW5kRXhlY3V0aW9uKVxyXG4gICAgICByZXR1cm47XHJcblxyXG4gICAgaWYoTG9nZ2VyLkluc3RhbmNlLkxvZ0xldmVsID09IExvZ2dlcl9Mb2dMZXZlbHMuUmVxdWVzdEluZm8gJiYgIWlzSW5pdGlhbENhbGwpXHJcbiAgICAgIGF3YWl0IHRoaXMuVXBkYXRlUmVxdWVzdEluZm8oKTtcclxuXHJcbiAgICBpZiAoaXNJbml0aWFsQ2FsbCkge1xyXG4gICAgICBsZXQgdmFsID0gdGhpcy5SZXN0b3JlU2Vzc2lvblJlSW5pdGlhbGl6aW5nRGF0YUZyb21Mb2NhbFN0b3JhZ2UoQ29uc3RJbnRlcmZhY2UuSVNfU0VTU0lPTl9SRUlOSVRJQUxJWklORyk7XHJcbiAgICAgIGlmICh2YWwgPT09ICd0cnVlJykge1xyXG4gICAgICAgIFJlbW90ZUNvbW1hbmRzUHJvY2Vzc29yLklzU2Vzc2lvblJlSW5pdGlhbGl6aW5nID0gKHZhbCA9PT0gXCJ0cnVlXCIpID8gdHJ1ZSA6IGZhbHNlO1xyXG4gICAgICAgIFJlbW90ZUNvbW1hbmRzUHJvY2Vzc29yLmxhc3RFeGNlcHRpb25NZXNzYWdlID0gdGhpcy5SZXN0b3JlU2Vzc2lvblJlSW5pdGlhbGl6aW5nRGF0YUZyb21Mb2NhbFN0b3JhZ2UoQ29uc3RJbnRlcmZhY2UuTEFTVF9FWENFUFRJT04pO1xyXG4gICAgICAgIGxldCBjdHhSZW1vdmVkID0gdGhpcy5SZXN0b3JlU2Vzc2lvblJlSW5pdGlhbGl6aW5nRGF0YUZyb21Mb2NhbFN0b3JhZ2UoQ29uc3RJbnRlcmZhY2UuQ1RYX1JFTU9WRURfRlJPTV9TUlZSKTtcclxuXHJcbiAgICAgICAgaWYgKGN0eFJlbW92ZWQgIT09ICcxJykge1xyXG4gICAgICAgICAgTG9nZ2VyLkluc3RhbmNlLldyaXRlRXJyb3JUb0xvZyhSZW1vdGVDb21tYW5kc1Byb2Nlc3Nvci5sYXN0RXhjZXB0aW9uTWVzc2FnZSk7XHJcbiAgICAgICAgICBMb2dnZXIuSW5zdGFuY2UuV3JpdGVUb0xvZyhcIlNlc3Npb24gaXMgcmVpbml0aWFsaXppbmcuLi5cIiwgdHJ1ZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHNlbmRpbmdJbnN0cnVjdGlvbiA9PT0gQ29tbWFuZHNQcm9jZXNzb3JCYXNlX1NlbmRpbmdJbnN0cnVjdGlvbi5OT19UQVNLU19PUl9DT01NQU5EUylcclxuICAgICAgcmVxQnVmID0gbnVsbDtcclxuICAgIGVsc2Uge1xyXG4gICAgICByZXFCdWYgPSBhd2FpdCB0aGlzLlByZXBhcmVSZXF1ZXN0KHNlbmRpbmdJbnN0cnVjdGlvbiA9PT0gQ29tbWFuZHNQcm9jZXNzb3JCYXNlX1NlbmRpbmdJbnN0cnVjdGlvbi5UQVNLU19BTkRfQ09NTUFORFMpO1xyXG5cclxuICAgICAgaWYgKFJlbW90ZUNvbW1hbmRzUHJvY2Vzc29yLklzU2Vzc2lvblJlSW5pdGlhbGl6aW5nIHx8ICFpc0luaXRpYWxDYWxsKSB7XHJcbiAgICAgICAgbGV0IGNoYW5nZXM6IFN0cmluZ0J1aWxkZXIgPSBuZXcgU3RyaW5nQnVpbGRlcigpO1xyXG4gICAgICAgIGxldCBidWZmZXI6IFN0cmluZ0J1aWxkZXIgPSBuZXcgU3RyaW5nQnVpbGRlcigpO1xyXG4gICAgICAgIGlmICghUmVtb3RlQ29tbWFuZHNQcm9jZXNzb3IuSXNTZXNzaW9uUmVJbml0aWFsaXppbmcpXHJcbiAgICAgICAgICBidWZmZXIuQXBwZW5kKHJlcUJ1Zik7XHJcblxyXG4gICAgICAgIC8vIHNlbmQgYWN0aXZpdHkgbW9uaXRvciBsb2dzIHRvIHRoZSBzZXJ2ZXJcclxuICAgICAgICAvLyBpZiAodGhpcy5fbG9nQWNjdW11bGF0b3IgIT09IG51bGwgJiYgIXRoaXMuX2xvZ0FjY3VtdWxhdG9yLkVtcHR5KCkpXHJcbiAgICAgICAgLy8gICBidWZmZXIuQXBwZW5kKHRoaXMuX2xvZ0FjY3VtdWxhdG9yLlJlYWQoKSk7XHJcblxyXG4gICAgICAgIC8vIHN5bmNocm9uaXplIGNsaWVudC1zaWRlIFNldFBhcmFtcyBhbmQgSU5JUHV0IGRhdGEgdG8gdGhlIHNlcnZlclxyXG4gICAgICAgIGlmIChSZW1vdGVDb21tYW5kc1Byb2Nlc3Nvci5Jc1Nlc3Npb25SZUluaXRpYWxpemluZylcclxuICAgICAgICAgIGdsb2JhbFBhcmFtc1N0cmluZyA9IHRoaXMuUmVzdG9yZVNlc3Npb25SZUluaXRpYWxpemluZ0RhdGFGcm9tTG9jYWxTdG9yYWdlKENvbnN0SW50ZXJmYWNlLkdMT0JBTF9QQVJBTV9MSVNUKTtcclxuICAgICAgICBlbHNlXHJcbiAgICAgICAgICBnbG9iYWxQYXJhbXNTdHJpbmcgPSBBY2Nlc3NIZWxwZXIuZ2xvYmFsUGFyYW1zLm1pcnJvclRvWE1MKCk7XHJcbiAgICAgICAgY2hhbmdlcy5BcHBlbmQoZ2xvYmFsUGFyYW1zU3RyaW5nKTtcclxuICAgICAgICBjaGFuZ2VzLkFwcGVuZChBY2Nlc3NIZWxwZXIuZW52UGFyYW1zVGFibGUubWlycm9yVG9YTUwoKSk7XHJcblxyXG4gICAgICAgIC8vIElmIHRoZXJlIGlzIHN0dWZmIHRvIHN5bmNocm9uaXplLCB3cmFwIGl0LCBzY3JhbWJsZSBpdCBhbmQgYWRkIHRoZSBNR0RBVEEgZmxhZ1xyXG4gICAgICAgIGlmIChjaGFuZ2VzLkxlbmd0aCA+IDApIHtcclxuICAgICAgICAgIGNoYW5nZXMuSW5zZXJ0KDAsIFwiPFwiICsgQ29uc3RJbnRlcmZhY2UuTUdfVEFHX0VOVl9DSEFOR0VTICsgXCI+XCIpO1xyXG4gICAgICAgICAgY2hhbmdlcy5BcHBlbmQoXCI8L1wiICsgQ29uc3RJbnRlcmZhY2UuTUdfVEFHX0VOVl9DSEFOR0VTICsgXCI+XCIpO1xyXG5cclxuICAgICAgICAgIGlmIChSZW1vdGVDb21tYW5kc1Byb2Nlc3Nvci5TaG91bGRTY3JhbWJsZUFuZFVuc2NyYW1ibGVNZXNzYWdlcykge1xyXG4gICAgICAgICAgICBsZXQgc2NyYW1ibGVkQ2hhbmdlczogc3RyaW5nID0gU2NyYW1ibGVyLlNjcmFtYmxlKGNoYW5nZXMuVG9TdHJpbmcoKSk7XHJcbiAgICAgICAgICAgIGNoYW5nZXMgPSBuZXcgU3RyaW5nQnVpbGRlcihzY3JhbWJsZWRDaGFuZ2VzKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIGNoYW5nZXMuSW5zZXJ0KDAsIFhNTENvbnN0YW50cy5NR19UQUdfT1BFTik7XHJcbiAgICAgICAgICBjaGFuZ2VzLkFwcGVuZChYTUxDb25zdGFudHMuTUdfVEFHX1hNTF9FTkRfVEFHR0VEKTtcclxuXHJcbiAgICAgICAgICBidWZmZXIuQXBwZW5kKGNoYW5nZXMuVG9TdHJpbmcoKSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXFCdWYgPSBidWZmZXIuVG9TdHJpbmcoKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGxldCByZXF1ZXN0U3RhdHVzOiBSZWZQYXJhbTxSZXF1ZXN0U3RhdHVzPiA9IG5ldyBSZWZQYXJhbShSZXF1ZXN0U3RhdHVzLkhhbmRsZWQpO1xyXG4gICAgbGV0IHJlc3BCdWY6IHN0cmluZyA9IG51bGw7XHJcblxyXG4gICAgaWYgKFJlbW90ZUNvbW1hbmRzUHJvY2Vzc29yLklzU2Vzc2lvblJlSW5pdGlhbGl6aW5nICkge1xyXG4gICAgICByZXFCdWYgPSAgcmVxQnVmICsgdGhpcy5SZXN0b3JlU2Vzc2lvblJlSW5pdGlhbGl6aW5nRGF0YUZyb21Mb2NhbFN0b3JhZ2UoQ29uc3RJbnRlcmZhY2UuTUFJTl9QUk9HX1ZJRVcpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChSdW50aW1lQ29udGV4dEJhc2UuSW5zdGFuY2UuUmVtb3ZlZENvbnRleHRGcm9tU2VydmVyKVxyXG4gICAgICByZXF1ZXN0U3RhdHVzLnZhbHVlID0gUmVxdWVzdFN0YXR1cy5SZXRyeTsgLy90cnkgdG8gcmUtc3RhcnQgc2Vzc2lvbiBmaXJzdFxyXG4gICAgZWxzZVxyXG4gICAge1xyXG4gICAgICBpZiAoUnVudGltZUNvbnRleHRCYXNlLkluc3RhbmNlLlJlbW92aW5nQ29udGV4dEZyb21TZXJ2ZXIpXHJcbiAgICAgICAgUnVudGltZUNvbnRleHRCYXNlLkluc3RhbmNlLlJlbW92ZWRDb250ZXh0RnJvbVNlcnZlciA9IHRydWU7XHJcblxyXG4gICAgICByZXNwQnVmID0gYXdhaXQgdGhpcy5EaXNwYXRjaFJlcXVlc3QodGhpcy5TZXJ2ZXJVcmwsIHJlcUJ1Ziwgc2Vzc2lvblN0YWdlLCByZXF1ZXN0U3RhdHVzKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAocmVxdWVzdFN0YXR1cy52YWx1ZSA9PSBSZXF1ZXN0U3RhdHVzLlJldHJ5KSB7XHJcbiAgICAgIGF3YWl0IHRoaXMuUmVTdGFydFNlc3Npb24oKTtcclxuICAgIH1cclxuICAgIGlmIChyZXNwQnVmID09IG51bGwpXHJcbiAgICAgIHJldHVybjtcclxuXHJcbiAgICBpZiAoaXNJbml0aWFsQ2FsbClcclxuICAgIHtcclxuICAgICAgUmVtb3RlQ29tbWFuZHNQcm9jZXNzb3IuSW5pdGlhbFVybCA9IHdpbmRvdy5sb2NhdGlvbi5ocmVmO1xyXG4gICAgICBpZiAoUmVtb3RlQ29tbWFuZHNQcm9jZXNzb3IuSXNTZXNzaW9uUmVJbml0aWFsaXppbmcpIHtcclxuICAgICAgICBsZXQgZGF0YVN0b3JhZ2UgPSB3aW5kb3cubG9jYWxTdG9yYWdlO1xyXG4gICAgICAgIGRhdGFTdG9yYWdlLnJlbW92ZUl0ZW0oQ29uc3RJbnRlcmZhY2UuSVNfU0VTU0lPTl9SRUlOSVRJQUxJWklORyk7XHJcbiAgICAgICAgZGF0YVN0b3JhZ2UucmVtb3ZlSXRlbShDb25zdEludGVyZmFjZS5NQUlOX1BST0dfVklFVyk7XHJcbiAgICAgICAgZGF0YVN0b3JhZ2UucmVtb3ZlSXRlbShDb25zdEludGVyZmFjZS5HTE9CQUxfUEFSQU1fTElTVCk7XHJcbiAgICAgICAgZGF0YVN0b3JhZ2UucmVtb3ZlSXRlbShDb25zdEludGVyZmFjZS5MQVNUX0VYQ0VQVElPTik7XHJcblxyXG5cclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIEZsb3dNb25pdG9yUXVldWUuSW5zdGFuY2UuZW5hYmxlKGZhbHNlKTtcclxuICAgIGF3YWl0IHRoaXMuUHJvY2Vzc1Jlc3BvbnNlKHJlc3BCdWYsIEFjY2Vzc0hlbHBlci5tZ0RhdGFUYWJsZS5jdXJyTWdkSUQsIG51bGwsIHJlcyk7XHJcblxyXG4gICAgaWYgKFJlbW90ZUNvbW1hbmRzUHJvY2Vzc29yLklzU2Vzc2lvblJlSW5pdGlhbGl6aW5nKSB7XHJcbiAgICAgIEFjY2Vzc0hlbHBlci5nbG9iYWxQYXJhbXMuUmVzdG9yZUdsb2JhbFBhcmFtcyhnbG9iYWxQYXJhbXNTdHJpbmcpO1xyXG5cclxuICAgICAgbGV0IGRhdGFTdG9yYWdlID0gd2luZG93LmxvY2FsU3RvcmFnZTtcclxuICAgICAgbGV0IGN0eFJlbW92ZWQgPSBkYXRhU3RvcmFnZS5nZXRJdGVtKENvbnN0SW50ZXJmYWNlLkNUWF9SRU1PVkVEX0ZST01fU1JWUik7XHJcblxyXG4gICAgICBpZiAoY3R4UmVtb3ZlZCA9PT0gXCIxXCIpIHtcclxuXHJcbiAgICAgIEV2ZW50c01hbmFnZXIuSW5zdGFuY2UucmVzdG9yZUxhc3RTYXZlZFJvdXRlRXZlbnRGcm9tTG9jYWxTdG9yYWdlKCk7XHJcblxyXG4gICAgICBkYXRhU3RvcmFnZS5yZW1vdmVJdGVtKENvbnN0SW50ZXJmYWNlLkNUWF9SRU1PVkVEX0ZST01fU1JWUik7XHJcbiAgICAgIGRhdGFTdG9yYWdlLnJlbW92ZUl0ZW0oQ29uc3RJbnRlcmZhY2UuTEFTVF9ST1VURV9FVkVOVCk7XHJcbiAgICAgIGRhdGFTdG9yYWdlLnJlbW92ZUl0ZW0oQ29uc3RJbnRlcmZhY2UuTEFTVF9ST1VURV9FVkVOVF9TUkNfVFNLKTtcclxuICAgICAgZGF0YVN0b3JhZ2UucmVtb3ZlSXRlbShDb25zdEludGVyZmFjZS5MQVNUX1JPVVRFX0VWRU5UX0FSR19MSVNUKTtcclxuICAgIH1cclxuXHJcbiAgICAgIFJlbW90ZUNvbW1hbmRzUHJvY2Vzc29yLklzU2Vzc2lvblJlSW5pdGlhbGl6aW5nID0gZmFsc2U7XHJcbiAgICB9XHJcbiAgICAvLyBpZiAoaXNJbml0aWFsQ2FsbCkge1xyXG4gICAgLy8gICAvLyBJZiBpdCB3YXMgaW5pdGlhbCBjYWxsLCB3ZSB3aWxsIHNlbmQgYWxsIHBlbmRpbmcgbG9ncyAoRmFpbGVkIGVhcmxpZXIgZXhlY3V0aW9uIHNjZW5hcmlvKVxyXG4gICAgLy8gICAvLyBUaGV5IHdpbGwgYmUgc2VudCBoZXJlLCBhZnRlciBmaXJzdCByZXF1ZXN0IGlzIHNlcnZlZC5cclxuICAgIC8vICAgaWYgKENsaWVudE1hbmFnZXIuSW5zdGFuY2UuZ2V0TG9nQ2xpZW50U2VxdWVuY2VGb3JBY3Rpdml0eU1vbml0b3IoKSAmJiBDbGllbnRMb2dBY2N1bXVsYXRvci5FeGlzdGluZ0xvZ3NGb3VuZCgpKSB7XHJcbiAgICAvLyAgICAgbGV0IHN1Y2Nlc3M6IGJvb2xlYW4gPSB0aGlzLlNlbmRQZW5kaW5nTG9nc1RvU2VydmVyKCk7XHJcbiAgICAvL1xyXG4gICAgLy8gICAgIC8vIGlmIHdlIGhhdmUgc3VjY2Vzc2Z1bGx5IHNlbnQgdGhlIHBlbmRpbmcgbG9ncyBkZWxldGUgdGhlbVxyXG4gICAgLy8gICAgIGlmIChzdWNjZXNzKSB7XHJcbiAgICAvLyAgICAgICBSZW1vdGVDb21tYW5kc1Byb2Nlc3Nvci5EZWxldGVQZW5kaW5nTG9ncygpO1xyXG4gICAgLy8gICAgIH1cclxuICAgIC8vICAgfVxyXG4gICAgLy8gfVxyXG4gICAgLy8gZWxzZSBpZiAodGhpcy5fbG9nQWNjdW11bGF0b3IgIT09IG51bGwgJiYgIXRoaXMuX2xvZ0FjY3VtdWxhdG9yLkVtcHR5KCkpIHtcclxuICAgIC8vICAgLy8gQWNjdW11bGF0ZWQgbG9ncyB3ZXJlIHNlbnQsIHNvIHJlc2V0IChkZWxldGUpIHRoZW0gbm93XHJcbiAgICAvLyAgIHRoaXMuX2xvZ0FjY3VtdWxhdG9yLlJlc2V0KCk7XHJcbiAgICAvLyB9XHJcblxyXG4gICAgLy8gcmVmcmVzaCB0aGUgZGlzcGxheXNcclxuICAgIGlmIChzZW5kaW5nSW5zdHJ1Y3Rpb24gPT09IENvbW1hbmRzUHJvY2Vzc29yQmFzZV9TZW5kaW5nSW5zdHJ1Y3Rpb24uVEFTS1NfQU5EX0NPTU1BTkRTKSB7XHJcbiAgICAgIEFjY2Vzc0hlbHBlci5tZ0RhdGFUYWJsZS5zdGFydFRhc2tzSXRlcmF0aW9uKCk7XHJcbiAgICAgIGxldCB0YXNrOiBUYXNrQmFzZTtcclxuICAgICAgd2hpbGUgKCh0YXNrID0gPFRhc2tCYXNlPkFjY2Vzc0hlbHBlci5tZ0RhdGFUYWJsZS5nZXROZXh0VGFzaygpKSAhPT0gbnVsbCkge1xyXG4gICAgICAgIGxldCBkYXRhVmlld1dhc1JldHJpZXZlZDogYm9vbGVhbiA9IHRhc2suRGF0YVZpZXdXYXNSZXRyaWV2ZWQ7XHJcbiAgICAgICAgaWYgKGRhdGFWaWV3V2FzUmV0cmlldmVkKSB7XHJcbiAgICAgICAgICBhd2FpdCB0YXNrLlJlZnJlc2hEaXNwbGF5KCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGlzSW5pdGlhbENhbGwpXHJcbiAgICAgIFNlcnZlckNvbmZpZy5JbnN0YW5jZS5zZXRHbG9iYWxQYXJhbXMobnVsbCk7XHJcbiAgfVxyXG5cclxuICAvLy8gPHN1bW1hcnk+c2VuZCAncmVxQnVmJyB0byAndXJsJzsgcmVjZWl2ZSBhIHJlc3BvbnNlLlxyXG4gIC8vLyBGb3IgTm9ybWFsL0luaXRpYWxDYWxsIHJlcXVlc3RzLCB0aGUgdXJsIHBvaW50cyB0byB0aGUgd2ViLXJlcXVlc3Rlci5cclxuICAvLy8gVGhlIG90aGVyIHBhcmFtZXRlcnMgYW5kIGRhdGEgZ29lcyBhcyB0aGUgZW5jb2RlZCBib2R5LlxyXG4gIC8vLyBUaGlzIG1lYW5zIHRoYXQgaXQgaXMgYSBQT1NUIHJlcXVlc3QuXHJcbiAgLy8vIE9uIHRoZSBvdGhlciBoYW5kLCBIYW5kU2hha2UgcmVxdWVzdCBpcyBhIEdFVCByZXF1ZXN0IGFuZCBzbyB0aGUgcGFyYW1ldGVycyBhcmVcclxuICAvLy8gc2VudCBpbiB0aGUgVVJMIGl0c2VsZi4gSW4gdGhpcyBjYXNlLCBlbmNvZGVkQm9keSBoYXMgdG8gYmUgbnVsbC5cclxuICAvLy8gPC9zdW1tYXJ5PlxyXG4gIC8vLyA8cGFyYW0gbmFtZT1cInVybFwiPlVSTCB0byBiZSBhY2Nlc3NlZC48L3BhcmFtPlxyXG4gIC8vLyA8cGFyYW0gbmFtZT1cInJlcUJ1ZlwiPmRhdGEgdG8gYmUgc2VudCB0byB0aGUgdXJsPC9wYXJhbT5cclxuICAvLy8gPHBhcmFtIG5hbWU9XCJzZXNzaW9uU3RhZ2VcIj5IQU5EU0hBS0UgLyBJTklUSUFMIC8gTk9STUFMLjwvcGFyYW0+XHJcbiAgLy8vIDxyZXR1cm5zPnJlc3BvbnNlPC9yZXR1cm5zPlxyXG4gICBwcml2YXRlIGFzeW5jIERpc3BhdGNoUmVxdWVzdCh1cmw6IHN0cmluZywgcmVxQnVmOiBzdHJpbmcsIHNlc3Npb25TdGFnZTogQ29tbWFuZHNQcm9jZXNzb3JCYXNlX1Nlc3Npb25TdGFnZSwgcmVxdWVzdFN0YXR1czogUmVmUGFyYW08UmVxdWVzdFN0YXR1cz4pOiBQcm9taXNlPHN0cmluZz4ge1xyXG4gICAgbGV0IHJlc3BvbnNlOiBzdHJpbmcgPSBudWxsO1xyXG4gICAgbGV0IGVuY29kZWRCb2R5OiBzdHJpbmcgPSBudWxsO1xyXG4gICAgcmVxdWVzdFN0YXR1cy52YWx1ZSA9IFJlcXVlc3RTdGF0dXMuSGFuZGxlZDtcclxuXHJcbiAgICBpZiAodXJsID09PSBudWxsKSB7XHJcbiAgICAgIExvZ2dlci5JbnN0YW5jZS5Xcml0ZUV4Y2VwdGlvblRvTG9nV2l0aE1zZyhcImluIHNlbmRNc2dUb1NydnIoKSB1bmtub3duIHNlcnZlclwiKTtcclxuICAgICAgcmV0dXJuIHJlc3BvbnNlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChzZXNzaW9uU3RhZ2UgIT09IENvbW1hbmRzUHJvY2Vzc29yQmFzZV9TZXNzaW9uU3RhZ2UuSEFORFNIQUtFKSB7XHJcbiAgICAgIGxldCB1cmxTdWZmaXg6IHN0cmluZyA9IHRoaXMuQnVpbGRVcmxTdWZmaXgocmVxQnVmICE9PSBudWxsLCBzZXNzaW9uU3RhZ2UgPT09IENvbW1hbmRzUHJvY2Vzc29yQmFzZV9TZXNzaW9uU3RhZ2UuSU5JVElBTCk7XHJcbiAgICAgIGxldCByZXFCdWZFbmNvZGVkOiBzdHJpbmcgPSBIdHRwVXRpbGl0eS5VcmxFbmNvZGUocmVxQnVmLCBFbmNvZGluZy5VVEY4KTtcclxuICAgICAgZW5jb2RlZEJvZHkgPSB1cmxTdWZmaXggKyByZXFCdWZFbmNvZGVkO1xyXG4gICAgfVxyXG5cclxuXHJcbiAgICAgdHJ5IHtcclxuICAgICAgIGlmIChMb2dnZXIuSW5zdGFuY2UuU2hvdWxkTG9nRXh0ZW5kZWRTZXJ2ZXJSZWxhdGVkTWVzc2FnZXMoKSlcclxuICAgICAgICAgTG9nZ2VyLkluc3RhbmNlLldyaXRlU2VydmVyTWVzc2FnZXNUb0xvZyhOU3RyaW5nLkZvcm1hdChcIk1FU1NBR0UgVE8gU0VSVkVSOlxcbiBVUkw6IHswfVxcbiBCT0RZOiB7MX1cIiwgdXJsLCBlbmNvZGVkQm9keSkpO1xyXG5cclxuICAgICAgIHJlc3BvbnNlID0gYXdhaXQgdGhpcy5FeGVjdXRlUmVxdWVzdCh1cmwsIGVuY29kZWRCb2R5KTtcclxuXHJcbiAgICAgICAvKiByZW1vdmUgdGhlIHVud2FudGVkIGRhdGEgYmVmb3JlIHRoZSBNR0RBVEEgdGFnICovXHJcbiAgICAgICBpZiAoIXJlc3BvbnNlLnRvVXBwZXJDYXNlKCkuc3RhcnRzV2l0aChcIjxIVE1MXCIpKSB7XHJcbiAgICAgICAgIGxldCBzdGFydElkeDogbnVtYmVyID0gcmVzcG9uc2UuaW5kZXhPZihcIjx4bWwgaWQ9XFxcIk1HREFUQVxcXCI+XCIpO1xyXG4gICAgICAgICBpZiAoc3RhcnRJZHggPiAwKVxyXG4gICAgICAgICAgIHJlc3BvbnNlID0gcmVzcG9uc2Uuc3Vic3RyKHN0YXJ0SWR4KTtcclxuICAgICAgIH1cclxuXHJcbiAgICAgICBMb2dnZXIuSW5zdGFuY2UuV3JpdGVTZXJ2ZXJNZXNzYWdlc1RvTG9nKFwiTUVTU0FHRSBGUk9NIFNFUlZFUjogXCIgKyByZXNwb25zZSk7XHJcblxyXG4gICAgICAgLy8gaGFuZHNoYWtlIHJlcXVlc3RzIGFyZSBhbHdheXMgc2NyYW1ibGVkICh0aGUgc2NyYW1ibGluZyBjYW4gYmUgZGlzYWJsZWQgc3RhcnRpbmcgZnJvbSB0aGUgM3JkIHJlcXVlc3QpLlxyXG4gICAgICAgaWYgKHNlc3Npb25TdGFnZSA9PT0gQ29tbWFuZHNQcm9jZXNzb3JCYXNlX1Nlc3Npb25TdGFnZS5IQU5EU0hBS0UgfHxcclxuICAgICAgICAgKHJlc3BvbnNlLmxlbmd0aCA+IDAgJiZcclxuICAgICAgICAgICBSZW1vdGVDb21tYW5kc1Byb2Nlc3Nvci5TaG91bGRTY3JhbWJsZUFuZFVuc2NyYW1ibGVNZXNzYWdlcyAmJiByZXNwb25zZSAhPT0gXCI8eG1sIGlkPVxcXCJNR0RBVEFcXFwiPlxcbjwveG1sPlwiKSkge1xyXG4gICAgICAgICBpZiAoc2Vzc2lvblN0YWdlID09PSBDb21tYW5kc1Byb2Nlc3NvckJhc2VfU2Vzc2lvblN0YWdlLkhBTkRTSEFLRSkge1xyXG4gICAgICAgICAgIC8vIGhhbmRzaGFrZSByZXF1ZXN0cyBhcmUgYWx3YXlzIHNjcmFtYmxlZC5cclxuICAgICAgICAgICBEZWJ1Zy5Bc3NlcnQocmVzcG9uc2UubGVuZ3RoID4gMCAmJiByZXNwb25zZVswXSAhPT0gJzwnKTtcclxuICAgICAgICAgfVxyXG4gICAgICAgICByZXNwb25zZSA9IENvbW1hbmRzUHJvY2Vzc29yQmFzZS5VblNjcmFtYmxlKHJlc3BvbnNlKTtcclxuICAgICAgIH1cclxuXHJcbiAgICAgIExvZ2dlci5JbnN0YW5jZS5Xcml0ZURldlRvTG9nKFwiTUVTU0FHRSBGUk9NIFNFUlZFUjogKHNpemUgPSBcIiArIHJlc3BvbnNlLmxlbmd0aCArIFwiKVwiICsgT1NFbnZpcm9ubWVudC5Fb2xTZXEgKyByZXNwb25zZSk7XHJcblxyXG4gICAgICB0aGlzLl9sYXN0UmVxdWVzdFRpbWUgPSBNaXNjLmdldFN5c3RlbU1pbGxpc2Vjb25kcygpO1xyXG4gICAgIH1cclxuICAgICBjYXRjaCAoZXgpXHJcbiAgICAge1xyXG4gICAgICAgaWYgKGV4IGluc3RhbmNlb2YgU2VydmVyRXJyb3IpIHtcclxuICAgICAgICAgcmVxdWVzdFN0YXR1cy52YWx1ZSA9IFJlcXVlc3RTdGF0dXMuQWJvcnQ7XHJcblxyXG5cclxuICAgICAgICAgaWYgKHNlc3Npb25TdGFnZSA9PSBDb21tYW5kc1Byb2Nlc3NvckJhc2VfU2Vzc2lvblN0YWdlLk5PUk1BTCkge1xyXG4gICAgICAgICAgIC8vIElmIGNvbnRleHQgaXMgbm90IGZvdW5kIGF0IHNlcnZlciBkdWUgdG8gY3Jhc2ggb3IgdGhyZWFkIGlzIGFib3J0ZWQgZHVlIHRvIGNyYXNoLFxyXG4gICAgICAgICAgIC8vIGNoZWNrIFdlYkNsaWVudFJlaW5pdFNlc3Npb24uIGJhc2VkIG9uIHRoZSBmbGFnLCByZS1pbml0aWFsaXppbmcgcmVxdWVzdCBzaG91bGQgYmUgc2VudCB0byBjcmVhdGVcclxuICAgICAgICAgICAvLyBhIG5ldyBjb250ZXh0IGFuZCBpdCBzaG91bGQgYmUgZXhlY3V0ZWQgaW4gdGhpcyBuZXcgY29udGV4dC5cclxuICAgICAgICAgICAvLyBzbywgc2V0IHRoZSBSZXF1ZXN0U3RhdHVzIHRvIFJldHJ5IHNvIHRoYXQgdGhlIGNsaWVudCB3aWxsIHJlc2VuZCByZXF1ZXN0LlxyXG4gICAgICAgICAgIGlmIChleC5HZXRDb2RlKCkgPT0gU2VydmVyRXJyb3IuRVJSX0NUWF9OT1RfRk9VTkQgfHwgZXguR2V0Q29kZSgpID09IFNlcnZlckVycm9yLkVSUl9USFJFQURfQUJPUlRFRCkge1xyXG4gICAgICAgICAgICAgaWYgKFJ1bnRpbWVDb250ZXh0QmFzZS5JbnN0YW5jZS5SZW1vdmVkQ29udGV4dEZyb21TZXJ2ZXIpIHtcclxuICAgICAgICAgICAgICAgcmVxdWVzdFN0YXR1cy52YWx1ZSA9IFJlcXVlc3RTdGF0dXMuUmV0cnk7XHJcbiAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgc3dpdGNoIChFbnZpcm9ubWVudC5JbnN0YW5jZS5nZXRXZWJDbGllbnRSZWluaXRTZXNzaW9uKCkpIHtcclxuICAgICAgICAgICAgICAgICBjYXNlICdZJyA6XHJcbiAgICAgICAgICAgICAgICAgICByZXF1ZXN0U3RhdHVzLnZhbHVlID0gUmVxdWVzdFN0YXR1cy5SZXRyeTtcclxuICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgIGNhc2UgJ0EnOlxyXG4gICAgICAgICAgICAgICAgICAgbGV0IHJldHZhbCA9IGF3YWl0IEdVSU1hbmFnZXIuSW5zdGFuY2UuTWVzc2FnZUJveChcIkVycm9yXCIsIFwiVW5rbm93biBlcnJvciBvY2N1cnJlZCBhdCBzZXJ2ZXItc2lkZS5cIiArXHJcbiAgICAgICAgICAgICAgICAgICAgIFwiIFdvdWxkIHlvdSBsaWtlIHRvIHJlaW5pdGlhbGl6ZSB0aGUgc2Vzc2lvbj9cIiwgU3R5bGVzLk1TR0JPWF9CVVRUT05fWUVTX05PKTtcclxuICAgICAgICAgICAgICAgICAgIHJlcXVlc3RTdGF0dXMudmFsdWUgPSAocmV0dmFsID09IFN0eWxlcy5NU0dCT1hfUkVTVUxUX1lFUykgPyBSZXF1ZXN0U3RhdHVzLlJldHJ5IDogUmVxdWVzdFN0YXR1cy5BYm9ydDtcclxuICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgIGNhc2UgJ04nOlxyXG4gICAgICAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICAgICByZXF1ZXN0U3RhdHVzLnZhbHVlID0gUmVxdWVzdFN0YXR1cy5BYm9ydDtcclxuICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICBpZiAocmVxdWVzdFN0YXR1cy52YWx1ZSA9PSBSZXF1ZXN0U3RhdHVzLkFib3J0KVxyXG4gICAgICAgICAgICAge1xyXG4gICAgICAgICAgICAgICBFbnZpcm9ubWVudC5JbnN0YW5jZS5zZXRXZWJDbGllbnRSZWluaXRTZXNzaW9uKCdOJyk7XHJcbiAgICAgICAgICAgICAgIHRocm93ICBleDtcclxuICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICBsZXQgZXJyRm9yQ29uc29sZSA9IFN0clV0aWwuZ2V0Q29uc29sZUVyb3JTdHJpbmcoZXguR2V0TWVzc2FnZSgpKTtcclxuICAgICAgICAgICAgICAgUmVtb3RlQ29tbWFuZHNQcm9jZXNzb3IubGFzdEV4Y2VwdGlvbk1lc3NhZ2UgPSBcIkV4Y2VwdGlvbiBPY2N1cmVkIGF0IHNlcnZlciBzaWRlIDogXCIgKyBleC5HZXRDb2RlKCkudG9TdHJpbmcoKSArIFwiIDogXCIgKyBlcnJGb3JDb25zb2xlO1xyXG4gICAgICAgICAgICAgICBjb25zb2xlLmxvZyhSZW1vdGVDb21tYW5kc1Byb2Nlc3Nvci5sYXN0RXhjZXB0aW9uTWVzc2FnZSk7XHJcbiAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgICAgICAgICB9XHJcbiAgICAgICAgIH1cclxuICAgICAgIH1cclxuICAgICAgIC8vSWYgYW55IGl0ZW1zIGFyZSBzdG9yZWQgb24gbG9jYWwgc3RvcmFnZSBjbGVhciBpdCBub3cgYXMgc2Vzc2lvbiBjYW5ub3QgY29udGludWVkLlxyXG4gICAgICAgd2luZG93LmxvY2FsU3RvcmFnZS5jbGVhcigpO1xyXG4gICAgICAgdGhyb3cgZXg7XHJcbiAgICAgfVxyXG4gICAgcmV0dXJuIHJlc3BvbnNlO1xyXG4gIH1cclxuXHJcbiAgLy8vIDxzdW1tYXJ5PiBDaGVja3MgdGhlIHJlc3BvbnNlIHN0cmluZywgdGhyb3dzIGFuIGVycm9yIGlmIHRoZSByZXNwb25zZSBzdHJpbmcgY29udGFpbnNcclxuICAvLy8gYW4geG1sL2h0bWwgZXJyb3I8L3N1bW1hcnk+XHJcbiAgLy8vIDxwYXJhbSBuYW1lPVwicmVzcG9uc2VcIj48L3BhcmFtPlxyXG4gIHByaXZhdGUgSGFuZGxlRXJyb3JSZXNwb25zZShyZXNwb25zZTogc3RyaW5nKTogdm9pZCB7XHJcbiAgICB0cnkge1xyXG4gICAgICAvLyBlcnJvciByZXNwb25zZXMgYXJlIGFsd2F5cyBzY3JhbWJsZWQgYnkgdGhlIHdlYiBzZXJ2ZXIuXHJcbiAgICAgIExvZ2dlci5JbnN0YW5jZS5Xcml0ZVNlcnZlck1lc3NhZ2VzVG9Mb2coXCJNRVNTQUdFIEZST00gU0VSVkVSOiBcIiArIHJlc3BvbnNlKTtcclxuICAgICAgcmVzcG9uc2UgPSBDb21tYW5kc1Byb2Nlc3NvckJhc2UuVW5TY3JhbWJsZShyZXNwb25zZSk7XHJcbiAgICAgIExvZ2dlci5JbnN0YW5jZS5Xcml0ZVNlcnZlck1lc3NhZ2VzVG9Mb2coXCJNRVNTQUdFIEZST00gU0VSVkVSOiBcIiArIFN0clV0aWwuZ2V0Q29uc29sZUVyb3JTdHJpbmcocmVzcG9uc2UpKTtcclxuICAgIH1cclxuICAgIGNhdGNoIChleCkge1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChyZXNwb25zZS5zdGFydHNXaXRoKFwiPHhtbGVyclwiKSkge1xyXG4gICAgICAgIGxldCBlcnJvck1lc3NhZ2VYbWw6IEVycm9yTWVzc2FnZVhtbCA9IG5ldyBFcnJvck1lc3NhZ2VYbWwocmVzcG9uc2UsIHRoaXMuX2xhc3RSZXF1ZXN0VGltZSwgQWNjZXNzSGVscGVyLmVudmlyb25tZW50LmdldENvbnRleHRJbmFjdGl2aXR5VGltZW91dCgpKTtcclxuICAgICAgdGhyb3cgbmV3IFNlcnZlckVycm9yKGVycm9yTWVzc2FnZVhtbC5HZXRNZXNzYWdlKCksIGVycm9yTWVzc2FnZVhtbC5HZXRDb2RlKCkpO1xyXG4gICAgfVxyXG4gICAgZWxzZSBpZiAocmVzcG9uc2UudG9VcHBlckNhc2UoKS5zdGFydHNXaXRoKFwiPEhUTUxcIikpIHtcclxuICAgICAgdGhyb3cgbmV3IFNlcnZlckVycm9yKHJlc3BvbnNlKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8vLyA8c3VtbWFyeT5zZW5kICdlbmNvZGVkQm9keScgdG8gJ3VybCcgYW5kIHJlY2VpdmUgYSByZXNwb25zZS5cclxuICAvLy8gPC9zdW1tYXJ5PlxyXG4gIC8vLyA8cGFyYW0gbmFtZT1cInVybFwiPlVSTCB0byBiZSBhY2Nlc3NlZC48L3BhcmFtPlxyXG4gIC8vLyA8cGFyYW0gbmFtZT1cImVuY29kZWRCb2R5XCI+SW4gY2FzZSBvZiBQT1NULCBjb250ZW50IHRvIGJlIHNlbnQgdG8gc2VydmVyLiBGb3Igb3RoZXIgbWV0aG9kcywgbnVsbC48L3BhcmFtPlxyXG4gIC8vLyA8cmV0dXJucz50aGUgcmVzcG9uc2UgZnJvbSB0aGUgc2VydmVyPC9yZXR1cm5zPlxyXG4gcHJpdmF0ZSBhc3luYyBFeGVjdXRlUmVxdWVzdCh1cmw6IHN0cmluZywgZW5jb2RlZEJvZHk6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nPiB7XHJcbiAgICByZXR1cm4gYXdhaXQgdGhpcy5HZXRDb250ZW50KHVybCwgZmFsc2UsIGVuY29kZWRCb2R5KTtcclxuICB9XHJcblxyXG4gIGFzeW5jIEdldENvbnRlbnQocmVxdWVzdGVkVVJMOiBzdHJpbmcsIHVzZUNhY2hlOiBib29sZWFuLCByZXF1ZXN0Q29udGVudD86IHN0cmluZyk6IFByb21pc2U8c3RyaW5nPiB7XHJcbiAgICBpZiAoaXNVbmRlZmluZWQocmVxdWVzdENvbnRlbnQpKVxyXG4gICAgICByZXF1ZXN0Q29udGVudCA9IG51bGw7XHJcblxyXG4gICAgbGV0IHJlc3BvbnNlU3RyOiBzdHJpbmc7XHJcblxyXG4gICAgdHJ5IHtcclxuICAgICAgLy8gaWYgcmVsYXRpdmUsIHByZWZpeCB3aXRoIHRoZSAncHJvdG9jb2w6Ly9zZXJ2ZXIvJyBmcm9tIHdoaWNoIHRoZSByaWNoLWNsaWVudCB3YXMgYWN0aXZhdGVkXHJcbiAgICAgIGlmIChyZXF1ZXN0ZWRVUkwuc3RhcnRzV2l0aChcIi9cIikpXHJcbiAgICAgICAgcmVxdWVzdGVkVVJMID0gU2VydmVyQ29uZmlnLkluc3RhbmNlLmdldFByb3RvY29sKCkgKyBcIjovL1wiICsgU2VydmVyQ29uZmlnLkluc3RhbmNlLmdldFNlcnZlcigpICsgcmVxdWVzdGVkVVJMO1xyXG5cclxuICAgICAgdmFyIHNwaW5uZXJUaW1lciA9IHRpbWVyKDUwLCA1MCk7XHJcbiAgICAgIHZhciBzcGlubmVyVGltZXJTdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbiA9IHNwaW5uZXJUaW1lci5zdWJzY3JpYmUoKCkgPT4ge1xyXG4gICAgICAgIEFjY2Vzc0hlbHBlci5ldmVudHNNYW5hZ2VyLkNoZWNrQW5kU2hvd1NwaW5uZXIodHJ1ZSk7XHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgbGV0IGlzRXJyb3I6IFJlZlBhcmFtPGJvb2xlYW4+ID0gbmV3IFJlZlBhcmFtKGZhbHNlKTtcclxuXHJcbiAgICAgIFJlbW90ZUNvbW1hbmRzUHJvY2Vzc29yLnJlcXVlc3ROdW1iZXIrKzsgLy8gaW5jcmVhc2UgdGhlIG5vIG9mIHJlcXVlc3RzXHJcbiAgICAgIHJlc3BvbnNlU3RyID0gYXdhaXQgSHR0cE1hbmFnZXIuR2V0SW5zdGFuY2UoKS5HZXRDb250ZW50KHJlcXVlc3RlZFVSTCwgcmVxdWVzdENvbnRlbnQsIHVzZUNhY2hlLCBpc0Vycm9yKTtcclxuICAgICAgUmVtb3RlQ29tbWFuZHNQcm9jZXNzb3IudG90YWxSZXNwb25zZURhdGFMZW5ndGggKz0gUmVtb3RlQ29tbWFuZHNQcm9jZXNzb3IudG90YWxSZXNwb25zZURhdGFMZW5ndGggKyAoIWlzTnVsbE9yVW5kZWZpbmVkKHJlc3BvbnNlU3RyKSA/IHJlc3BvbnNlU3RyLmxlbmd0aCA6IDApO1xyXG5cclxuICAgICAgc3Bpbm5lclRpbWVyU3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XHJcbiAgICAgIHNwaW5uZXJUaW1lclN1YnNjcmlwdGlvbiA9IG51bGw7XHJcblxyXG4gICAgICBpZiAoaXNFcnJvci52YWx1ZSkge1xyXG4gICAgICAgIHRoaXMuSGFuZGxlRXJyb3JSZXNwb25zZShyZXNwb25zZVN0cik7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIGNhdGNoIChleCkge1xyXG4gICAgICAvLyBkb24ndCB3cml0ZSBzZXJ2ZXIgZXJyb3IgdG8gbG9nIHdoZW4gdGhlIGxvZyBsZXZlbCBpcyBiYXNpY1xyXG4gICAgICBpZiAoIShleCBpbnN0YW5jZW9mIFNlcnZlckVycm9yKSB8fCBMb2dnZXIuSW5zdGFuY2UuTG9nTGV2ZWwgIT09IExvZ2dlcl9Mb2dMZXZlbHMuQmFzaWMpIHtcclxuICAgICAgICBMb2dnZXIuSW5zdGFuY2UuV3JpdGVFeGNlcHRpb25Ub0xvZyhleCwgTlN0cmluZy5Gb3JtYXQoXCJyZXF1ZXN0ZWQgVVJMID0gXFxcInswfVxcXCJcIiwgcmVxdWVzdGVkVVJMKSk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIHRoZSBleGNlcHRpb24gc2hvdWxkIGJlIHRocm93biBhbmQgdGhlIGNhbGxlcnMgc2hvdWxkIGhhbmRsZSBpdC5cclxuICAgICAgaWYgKCEoZXggaW5zdGFuY2VvZiBTZXJ2ZXJFcnJvcikpIHtcclxuICAgICAgICBleCA9IG5ldyBTZXJ2ZXJFcnJvcihleC5NZXNzYWdlLCBleC5Jbm5lckV4Y2VwdGlvbiA/IGV4LklubmVyRXhjZXB0aW9uIDogZXgpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB0aHJvdyBleDtcclxuICAgIH1cclxuICAgIGZpbmFsbHkge1xyXG4gICAgICBpZiAoc3Bpbm5lclRpbWVyU3Vic2NyaXB0aW9uICE9IG51bGwpXHJcbiAgICAgICAgc3Bpbm5lclRpbWVyU3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHJlc3BvbnNlU3RyO1xyXG4gIH1cclxuXHJcblxyXG4gIENsaWVudEFjdGl2YXRlZCgpIHtcclxuXHJcbiAgICAvLyBsb2cgdGhlIHZhbHVlcyBhcyBjbGllbnQgaXMgYWN0aXZlIGFnYWluXHJcbiAgICAvLyBUT0RPIC0gZm9ybWF0dGluZ1xyXG4gICAgLy8gY29uc29sZS5sb2coJ0xvZ2dpbmcgU3VtbWFyeSAnICsgJ1xcbicgK1xyXG4gICAgLy8gICAnVG90YWwgbnVtYmVyIHJlcXVlc3RzIDogJyArIFJlbW90ZUNvbW1hbmRzUHJvY2Vzc29yLnJlcXVlc3ROdW1iZXIgKyAnXFxuJyArXHJcbiAgICAvLyAgICdUb3RhbCB0aW1lIG5lZWRlZCBmb3IgaHR0cCByZXF1ZXN0cyA6ICcgKyBSZW1vdGVDb21tYW5kc1Byb2Nlc3Nvci50b3RhbFRpbWVGb3JIVFRQUmVxdWVzdHMgKyAnIG1zICcgKyAnXFxuJyArXHJcbiAgICAvLyAgICdUb3RhbCB0aW1lIG5lZWRlZCBmb3IgY2xpZW50IHRvIGdldCBhY3RpdmUgOiAnICsgZXhlY3V0aW9uVGltZSArICcgbXMgJyArICdcXG4nXHJcbiAgICAvLyApO1xyXG4gICAgLy9cclxuICAgIC8vIC8vIFRPRE8gLSBtb3ZlIGl0IHRvIG1ldGhvZFxyXG4gICAgLy8gUmVtb3RlQ29tbWFuZHNQcm9jZXNzb3IucmVxdWVzdE51bWJlciA9IDA7XHJcbiAgICAvLyBSZW1vdGVDb21tYW5kc1Byb2Nlc3Nvci50b3RhbFRpbWVGb3JIVFRQUmVxdWVzdHMgPSAwO1xyXG4gICAgLy8gUmVtb3RlQ29tbWFuZHNQcm9jZXNzb3IudG90YWxSZXF1ZXN0RGF0YUxlbmd0aCA9IDA7XHJcbiAgICAvLyBSZW1vdGVDb21tYW5kc1Byb2Nlc3Nvci50b3RhbFJlc3BvbnNlRGF0YUxlbmd0aCA9IDA7XHJcbiAgfVxyXG5cclxuICAvLy8gPHN1bW1hcnk+IFdoZW4gTG9nQ2xpZW50U2VxdWVuY2VGb3JBY3Rpdml0eU1vbml0b3IgPSBZIHdlIHdpbGwgYmUga2VlcGluZyB0aGUgbG9ncyBpbiBmaWxlIGFuZCBzZW5kIHRoZSBmaWxlIHdpdGggbmV4dFxyXG4gIC8vLyBzZXJ2ZXIgYWNjZXNzLiBJZiBjbGllbnQgaXMgYWJub3JtYWxseSB0ZXJtaW5hdGVkIHRoZW4gdGhlcmUgY2FuIGJlIDEgb3IgbW9yZSBmaWxlcyBjb250YWluaW5nIGxvZ3Mgc2luY2VcclxuICAvLy8gbGFzdCBzZXJ2ZXIgYWNjZXNzLk5vdyB0aGVzZSBsb2dzIHdpbGwgYmUgc2VudCB0byBzZXJ2ZXIsIHdoZW4gbmV4dCB0aW1lIFJDIHByb2dyYW0gaXMgZXhlY3V0ZWQsLjwvc3VtbWFyeT5cclxuICAvLy8gPHJldHVybnM+IElmIHNlbmRpbmcgd2FzIHN1Y2Nlc3NmdWw8L3JldHVybnM+XHJcbiAgLy8gICBUT0RPOiBIYW5kbGUgcGVuZGluZyBsb2dzLlxyXG4gIC8vIHByaXZhdGUgU2VuZFBlbmRpbmdMb2dzVG9TZXJ2ZXIoKTogYm9vbGVhbiB7XHJcbiAgLy8gICBsZXQgc3VjY2VzczogYm9vbGVhbiA9IHRydWU7XHJcbiAgLy9cclxuICAvLyAgIFRoZSBwZW5kaW5nIGxvZ3MgY2Fubm90IGJlIHJlYWQgZnJvbSB0aGUgZmlsZSBzeXN0ZW0gc2luY2UgV2ViQ2xpZW50IGRvZXNuJ3QgaGF2ZSBhY2Nlc3MgdG8gdGhhdC5cclxuICAvLyAgIE1heWJlLCB0aGUgbG9ncyBzaG91bGQgYmUgd3JpdHRlbiBpbnRvIExvY2FsU3RvcmFnZSBhZCByZWFkIGZyb20gdGhlcmUuXHJcbiAgLy9cclxuICAvLyAgIGxldCBzdHJpbmdCdWlsZGVyOiBTdHJpbmdCdWlsZGVyID0gbmV3IFN0cmluZ0J1aWxkZXIoMTAwMCk7XHJcbiAgLy8gICBsZXQgZmxvd01vbml0b3I6IEZsb3dNb25pdG9yUXVldWUgPSBGbG93TW9uaXRvclF1ZXVlLkluc3RhbmNlO1xyXG4gIC8vXHJcbiAgLy8gICAvLyBHZXQgaXRlcmF0b3IgdG8gbmFtZXMgb2YgbG9nIGZpbGVzLlxyXG4gIC8vICAgbGV0IGVudW1lcmF0b3I6IElFbnVtZXJhdG9yPHN0cmluZz4gPSBDbGllbnRMb2dBY2N1bXVsYXRvci5FeGlzdGluZ0xvZ0l0ZXJhdG9yKCk7XHJcbiAgLy9cclxuICAvLyAgIC8vIHdoaWxlIHRoZXJlIGFyZSBtb3JlIGZpbGVzXHJcbiAgLy8gICB3aGlsZSAoZW51bWVyYXRvci5Nb3ZlTmV4dCgpKSB7XHJcbiAgLy8gICAgIC8vIFRha2UgbmV4dCBmaWxlIG5hbWVcclxuICAvLyAgICAgbGV0IGxvZ05hbWU6IHN0cmluZyA9IGVudW1lcmF0b3IuQ3VycmVudDtcclxuICAvLyAgICAgLy8gUHJlcGFyZSB0aGUgaGVhZGVyIGxpbmUgKENsaWVudCBsb2cgZmlsZSA6IDxDb250ZXh0IDogWFhYWFhYPikgYW5kIGFkZCBpdCB0b1xyXG4gIC8vICAgICAvLyBmbG93IG1vbml0b3IgYnVpbGQgbW9uaXRvciBtZXNzYWdlXHJcbiAgLy8gICAgIGxldCBoZWFkZXJMaW5lOiBzdHJpbmcgPSBDbGllbnRMb2dBY2N1bXVsYXRvci5CdWlsZExvZ0hlYWRlckxpbmUobG9nTmFtZSk7XHJcbiAgLy8gICAgIGZsb3dNb25pdG9yLmFkZEZsb3dWZXJpZnlJbmZvKGhlYWRlckxpbmUpO1xyXG4gIC8vICAgICBsZXQgbG9nQ3R4QnVmOiBTdHJpbmdCdWlsZGVyID0gUmVtb3RlQ29tbWFuZHNQcm9jZXNzb3IuQnVpbGRNb25pdG9yTWVzc2FnZSgpO1xyXG4gIC8vXHJcbiAgLy8gICAgIGxldCBmaWxlQ29udGVudHM6IHN0cmluZyA9IEhhbmRsZUZpbGVzLnJlYWRUb1N0cmluZyhsb2dOYW1lKTtcclxuICAvLyAgICAgbG9nQ3R4QnVmLkFwcGVuZChmaWxlQ29udGVudHMpO1xyXG4gIC8vICAgICBzdHJpbmdCdWlsZGVyLkFwcGVuZChsb2dDdHhCdWYuVG9TdHJpbmcoKSk7XHJcbiAgLy8gICB9XHJcbiAgLy9cclxuICAvLyAgIGxldCByZXNwQnVmOiBzdHJpbmcgPSBudWxsO1xyXG4gIC8vXHJcbiAgLy8gICB0cnkge1xyXG4gIC8vICAgICByZXNwQnVmID0gdGhpcy5EaXNwYXRjaFJlcXVlc3QodGhpcy5TZXJ2ZXJVcmwsIHN0cmluZ0J1aWxkZXIuVG9TdHJpbmcoKSwgQ29tbWFuZHNQcm9jZXNzb3JCYXNlX1Nlc3Npb25TdGFnZS5OT1JNQUwpO1xyXG4gIC8vICAgfVxyXG4gIC8vICAgY2F0Y2ggKGV4KSB7XHJcbiAgLy8gICAgIC8vIGRvIG5vdGhpbmcuIGlmIHNlbmRpbmcgbG9nIGZhaWxzLCB0aGVyZSBpcyBubyBoYXJtLlxyXG4gIC8vICAgfVxyXG4gIC8vXHJcbiAgLy8gICBpZiAocmVzcEJ1ZiA9PT0gbnVsbCkge1xyXG4gIC8vICAgICBzdWNjZXNzID0gZmFsc2U7XHJcbiAgLy8gICB9XHJcbiAgLy9cclxuICAvLyAgIHJldHVybiBzdWNjZXNzO1xyXG4gIC8vIH1cclxuXHJcbiAgLy8gVE9ETzogSGFuZGxlIHBlbmRpbmcgbG9ncy5cclxuICAvLyBwcml2YXRlIHN0YXRpYyBEZWxldGVQZW5kaW5nTG9ncygpOiB2b2lkIHtcclxuICAvLyAgIGxldCBlbnVtZXJhdG9yOiBJRW51bWVyYXRvciA9IENsaWVudExvZ0FjY3VtdWxhdG9yLkV4aXN0aW5nTG9nSXRlcmF0b3IoKTtcclxuICAvLyAgIHdoaWxlIChlbnVtZXJhdG9yLk1vdmVOZXh0KCkpIHtcclxuICAvLyAgICAgbGV0IGZpbGVuYW1lOiBzdHJpbmcgPSA8c3RyaW5nPmVudW1lcmF0b3IuQ3VycmVudDtcclxuICAvLyAgICAgSGFuZGxlRmlsZXMuZGVsZXRlRmlsZShmaWxlbmFtZSk7XHJcbiAgLy8gICB9XHJcbiAgLy8gfVxyXG5cclxuICAvLy8gPHN1bW1hcnk+IGdldCB0aGUgc3VmZml4IG9mIHRoZSBVUkwgdG8gYmUgc2VudCB0byB0aGUgc2VydmVyLiBUaGlzIGluY2x1ZGVzIHRoZSBDVFgsIFNFU1NJT04gYW5kIERBVEEgcGFyYW1ldGVycy48L3N1bW1hcnk+XHJcbiAgLy8vIDxwYXJhbSBuYW1lPVwiaGFzQ29udGVudFwiPmlmIHRydWUsIHRoZSBIVFRQIERBVEEgcGFyYW1ldGVyIGNvbnRhaW5zIHNvbWV0aGluZy48L3BhcmFtPlxyXG4gIC8vLyA8cGFyYW0gbmFtZT1cImlzSW5pdGlhbENhbGxcIj5pZiB0cnVlIHRoZW4gdGhlIGdlbmVyYXRlZCBzdWZmaXggaGFzIG5vIHNwZWNpZmljIGNvbnRleHQgZGF0YTwvcGFyYW0+XHJcbiAgLy8vIDxyZXR1cm5zPiB0aGUgVVJMIHN1ZmZpeCAoaS5lLiBcIkNUWD0uLi4mU0VTU0lPTj0uLi4mREFUQT1cIjwvcmV0dXJucz5cclxuICBwcml2YXRlIEJ1aWxkVXJsU3VmZml4KGhhc0NvbnRlbnQ6IGJvb2xlYW4sIGlzSW5pdGlhbENhbGw6IGJvb2xlYW4pOiBzdHJpbmcge1xyXG4gICAgbGV0IHByZWZpeDogc3RyaW5nID0gQ29uc3RJbnRlcmZhY2UuUkNfSU5ESUNBVElPTiArIENvbnN0SW50ZXJmYWNlLlJDX1RPS0VOX0NUWF9JRCArIFJ1bnRpbWVDb250ZXh0QmFzZS5JbnN0YW5jZS5Db250ZXh0SUQ7XHJcblxyXG4gICAgLy8gQXBwZW5kIHNlc3Npb24gaWQgaW4gdXJsIG9ubHkgd2hlbiBpdCBpcyBub3QgbnVsbCBvciBlbXB0eVxyXG4gICAgLy8gTk9URTogc2Vzc2lvbiBpZCB3aWxsIGJlIHNlbmQgYnkgc2VydmVyIG9ubHkgZm9yIEdTIGFzIG1pZGRsZXdhcmVcclxuICAgIC8vICAgICAgIGFuZCB3aGVuIHNlcGVjaWFsIGZsYWcgKFNwZWNpYWxSSUFHZW5lcmF0ZUFuZFZhbGlkYXRlU2Vzc2lvbklEKSBpcyBvblxyXG4gICAgLy8gICAgICAgc28gc2Vzc2lvbiBpZCB3aWxsIGJlIG51bGwgZm9yIGJyb2tlciBtaWRkbGV3YXJlIGFuZCB3aGVuIHNwZWNpYWwgZmxhZyBpcyBPRkYuXHJcbiAgICBpZiAoIWlzTnVsbE9yVW5kZWZpbmVkKHRoaXMuU2Vzc2lvbklkKSlcclxuICAgICAgcHJlZml4ICs9IChDb25zdEludGVyZmFjZS5SRVFfQVJHX1NFUEFSQVRPUiArIENvbnN0SW50ZXJmYWNlLlJDX1RPS0VOX1NFU1NJT05fSUQgKyB0aGlzLlNlc3Npb25JZCk7XHJcblxyXG4gICAgaWYgKGlzSW5pdGlhbENhbGwpIHtcclxuICAgICAgLy8gVE9ETzogSG93IHRvIGdldCBlbnZpcm9ubWVudCB2YXJpYWJsZXM/XHJcbiAgICAgIC8vIGxldCBlbnZWYXJzOiBzdHJpbmcgPSBDbGllbnRNYW5hZ2VyLkluc3RhbmNlLmdldEVudlZhcnMoKTtcclxuICAgICAgLy8gaWYgKCFOU3RyaW5nLklzTnVsbE9yRW1wdHkoZW52VmFycykpIHtcclxuICAgICAgLy8gICAvLyBlbnZpcm9ubWVudCB2YXJpYWJsZXM6IEVOVjEsRU5WMiwuLiAtLT4gJkVOVjE9dmFsMSZFTlYyPXZhbDIuLi5cclxuICAgICAgLy8gICBsZXQgZW52VmFyc1ZlYzogc3RyaW5nW10gPSBlbnZWYXJzLnNwbGl0KFwiLFwiKTtcclxuICAgICAgLy8gICBmb3IgKGxldCBpOiBudW1iZXIgPSAwOyBpIDwgZW52VmFyc1ZlYy5sZW5ndGg7IGkgPSBpICsgMSkge1xyXG4gICAgICAvLyAgICAgcHJlZml4ICs9IChcIiZcIiArIGVudlZhcnNWZWNbaV0gKyBcIj1cIiArIE9TRW52aXJvbm1lbnQuZ2V0KGVudlZhcnNWZWNbaV0pKTtcclxuICAgICAgLy8gICB9XHJcbiAgICAgIC8vIH1cclxuICAgICAgaWYgKFJlbW90ZUNvbW1hbmRzUHJvY2Vzc29yLklzU2Vzc2lvblJlSW5pdGlhbGl6aW5nKVxyXG4gICAgICAgIHByZWZpeCArPSAoQ29uc3RJbnRlcmZhY2UuUkVRX0FSR19TRVBBUkFUT1IgKyBDb25zdEludGVyZmFjZS5XRUJDTElFTlRfUkVJTklUSUFMSVpFX1JFUVVFU1QpO1xyXG5cclxuICAgICAgbGV0IGdsb2JhbFBhcmFtczogc3RyaW5nID0gU2VydmVyQ29uZmlnLkluc3RhbmNlLmdldEdsb2JhbFBhcmFtcygpO1xyXG4gICAgICBpZiAoZ2xvYmFsUGFyYW1zICE9PSBudWxsKSB7XHJcbiAgICAgICAgZ2xvYmFsUGFyYW1zID0gTlN0cmluZy5SZXBsYWNlKGdsb2JhbFBhcmFtcywgXCIrXCIsIFwiJTJCXCIpO1xyXG4gICAgICAgIHByZWZpeCArPSAoXCImXCIgKyBDb25zdEludGVyZmFjZS5NR19UQUdfR0xPQkFMUEFSQU1TICsgXCI9XCIgKyBnbG9iYWxQYXJhbXMpO1xyXG4gICAgICB9XHJcbiAgICB9IC8vIGlzSW5pdGlhbENhbGxcclxuXHJcbiAgICBpZiAoaGFzQ29udGVudCkge1xyXG4gICAgICBwcmVmaXggKz0gKFwiJlwiICsgQ29uc3RJbnRlcmZhY2UuUkNfVE9LRU5fU0VTU0lPTl9DT1VOVCArIHRoaXMuR2V0U2Vzc2lvbkNvdW50ZXIoKSArXHJcbiAgICAgICAgQ29uc3RJbnRlcmZhY2UuUkVRX0FSR19TRVBBUkFUT1IgKyBDb25zdEludGVyZmFjZS5SQ19UT0tFTl9EQVRBKTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gcHJlZml4O1xyXG4gIH1cclxuXHJcbiAgLy8vIDxzdW1tYXJ5PnNlbmQgTW9uaXRvciBtZXNzYWdpbmcgdG8gdGhlIHNlcnZlcjwvc3VtbWFyeT5cclxuICBwdWJsaWMgYXN5bmMgU2VuZE1vbml0b3JPbmx5KCk6IFByb21pc2U8dm9pZD5cclxuICB7XHJcbiAgICBsZXQgZmxvd01vbml0b3I6IEZsb3dNb25pdG9yUXVldWUgPSBGbG93TW9uaXRvclF1ZXVlLkluc3RhbmNlO1xyXG5cclxuICAgIGlmIChBY2Nlc3NIZWxwZXIubWdEYXRhVGFibGUgPT0gbnVsbCB8fCBBY2Nlc3NIZWxwZXIubWdEYXRhVGFibGUuZ2V0TUdEYXRhKDApID09IG51bGwgfHwgQWNjZXNzSGVscGVyLm1nRGF0YVRhYmxlLmdldE1HRGF0YSgwKS5Jc0Fib3J0aW5nKVxyXG4gICAgICByZXR1cm47XHJcblxyXG4gICAgaWYgKCFmbG93TW9uaXRvci5pc0VtcHR5KCkpXHJcbiAgICB7XHJcbiAgICAgIC8vIGJ1aWxkIG91dCBtZXNzYWdlXHJcbiAgICAgIGxldCBidWZmZXI6IFN0cmluZ0J1aWxkZXIgPSB0aGlzLkJ1aWxkTW9uaXRvck1lc3NhZ2UoKTtcclxuXHJcbiAgICAgIC8vIElmIGNsaWVudCBzZXF1ZW5jZSBpcyB0byBiZSBhY2N1bXVsYXRlZCB1bnRpbCBuZXh0IHNlcnZlciBhY2Nlc3MuXHJcbiAgICAgIGxldCBzaG91bGRBY2N1bXVsYXRlQ2xpZW50TG9nOiBib29sZWFuID0gZmFsc2U7XHJcbiAgICAgIC8vIHNob3VsZEFjY3VtdWxhdGVDbGllbnRMb2cgPSBDbGllbnRNYW5hZ2VyLkluc3RhbmNlLmdldExvZ0NsaWVudFNlcXVlbmNlRm9yQWN0aXZpdHlNb25pdG9yKCk7XHJcbiAgICAgIC8vIGlmIChzaG91bGRBY2N1bXVsYXRlQ2xpZW50TG9nKSB7XHJcbiAgICAgIC8vICAgaWYgKHRoaXMuX2xvZ0FjY3VtdWxhdG9yID09IG51bGwpXHJcbiAgICAgIC8vICAgICB0aGlzLl9sb2dBY2N1bXVsYXRvciA9IG5ldyBDbGllbnRMb2dBY2N1bXVsYXRvcihDbGllbnRNYW5hZ2VyUnVudGltZS5JbnN0YW5jZS5SdW50aW1lQ3R4LkNvbnRleHRJRCk7XHJcbiAgICAgIC8vXHJcbiAgICAgIC8vICAgLy8gSWYgd2UncmUgdW5hYmxlIHRvIG9wZW4gdGhlIGZpbGUsIGRlYWN0aXZhdGUgbG9nZ2luZyBhY2N1bXVsYXRpb24sXHJcbiAgICAgIC8vICAgLy8gICAgYW5kIGxldCB0aGUgbWVzc2FnZSBiZSBzZW50IHRvIHRoZSBzZXJ2ZXIgYXMgZG9uZSB3aXRob3V0IGFjY3VtdWxhdGVkIGxvZ2dpbmdcclxuICAgICAgLy8gICBpZiAodGhpcy5fbG9nQWNjdW11bGF0b3IuSXNGYWlsZWQoKSlcclxuICAgICAgLy8gICAgIHNob3VsZEFjY3VtdWxhdGVDbGllbnRMb2cgPSBmYWxzZTtcclxuICAgICAgLy8gfVxyXG5cclxuICAgICAgaWYgKHNob3VsZEFjY3VtdWxhdGVDbGllbnRMb2cpIHtcclxuICAgICAgICAvLyBXcml0ZSBtZXNzYWdlIHRvIGZpbGUuXHJcbiAgICAgICAgLy8gdGhpcy5fbG9nQWNjdW11bGF0b3IuV3JpdGUoYnVmZmVyLlRvU3RyaW5nKCkpO1xyXG4gICAgICB9XHJcbiAgICAgIGVsc2Uge1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICBsZXQgcmVxdWVzdFN0YXR1czogUmVmUGFyYW08UmVxdWVzdFN0YXR1cz4gPSBuZXcgUmVmUGFyYW0oUmVxdWVzdFN0YXR1cy5IYW5kbGVkKTtcclxuICAgICAgICAgIGF3YWl0IHRoaXMuRGlzcGF0Y2hSZXF1ZXN0KHRoaXMuU2VydmVyVXJsLCBidWZmZXIuVG9TdHJpbmcoKSwgQ29tbWFuZHNQcm9jZXNzb3JCYXNlX1Nlc3Npb25TdGFnZS5OT1JNQUwsIHJlcXVlc3RTdGF0dXMpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjYXRjaCAoZXJyKSB7XHJcbiAgICAgICAgICAvLyBkbyBub3RoaW5nLiBpZiBzZW5kaW5nIGxvZyBmYWlscywgdGhlcmUgaXMgbm8gaGFybS5cclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8vLyA8c3VtbWFyeT5idWlsZCBGbG93IE1vbml0b3IgbWVzc2FnZTwvc3VtbWFyeT5cclxuICBwcml2YXRlIEJ1aWxkTW9uaXRvck1lc3NhZ2UoKTogU3RyaW5nQnVpbGRlciB7XHJcbiAgICBsZXQgYnVmZmVyOiBTdHJpbmdCdWlsZGVyID0gbmV3IFN0cmluZ0J1aWxkZXIoMTAwMCk7XHJcbiAgICBsZXQgZmxvd01vbml0b3I6IEZsb3dNb25pdG9yUXVldWUgPSBGbG93TW9uaXRvclF1ZXVlLkluc3RhbmNlO1xyXG5cclxuICAgIGlmICghUmVtb3RlQ29tbWFuZHNQcm9jZXNzb3IuU2hvdWxkU2NyYW1ibGVBbmRVbnNjcmFtYmxlTWVzc2FnZXMpIHtcclxuICAgICAgYnVmZmVyLkFwcGVuZChYTUxDb25zdGFudHMuTUdfVEFHX09QRU4pO1xyXG4gICAgICBmbG93TW9uaXRvci5idWlsZFhNTChidWZmZXIpO1xyXG4gICAgfVxyXG4gICAgZWxzZSB7XHJcbiAgICAgIGZsb3dNb25pdG9yLmJ1aWxkWE1MKGJ1ZmZlcik7XHJcbiAgICAgIGxldCBzY3JhbWJsZWRPdXQ6IHN0cmluZyA9IFNjcmFtYmxlci5TY3JhbWJsZShidWZmZXIuVG9TdHJpbmcoKSk7XHJcbiAgICAgIGJ1ZmZlciA9IG5ldyBTdHJpbmdCdWlsZGVyKDEwMDApO1xyXG4gICAgICBidWZmZXIuQXBwZW5kKFhNTENvbnN0YW50cy5NR19UQUdfT1BFTiArIHNjcmFtYmxlZE91dCk7XHJcbiAgICB9XHJcbiAgICBidWZmZXIuQXBwZW5kKFwiPC9cIiArIFhNTENvbnN0YW50cy5NR19UQUdfWE1MICsgWE1MQ29uc3RhbnRzLlRBR19DTE9TRSk7XHJcblxyXG4gICAgcmV0dXJuIGJ1ZmZlcjtcclxuICB9XHJcblxyXG4gIFJlZ2lzdGVyRGVsZWdhdGVzKCk6IHZvaWQge1xyXG4gICAgSHR0cENsaWVudEV2ZW50cy5HZXRTZXNzaW9uQ291bnRlcl9FdmVudCA9IHRoaXMuR2V0U2Vzc2lvbkNvdW50ZXIuYmluZCh0aGlzKTtcclxuICAgIEh0dHBDbGllbnRFdmVudHMuQ2hlY2tBbmRTZXRTZXNzaW9uQ291bnRlcl9FdmVudCA9IHRoaXMuQ2hlY2tBbmRTZXRTZXNzaW9uQ291bnRlci5iaW5kKHRoaXMpO1xyXG4gICAgSHR0cENsaWVudEV2ZW50cy5Db21wdXRlQW5kTG9nUmVxdWVzdEluZm9fRXZlbnQgPSB0aGlzLkNvbXB1dGVBbmRMb2dSZXF1ZXN0SW5mby5iaW5kKHRoaXMpO1xyXG4gICAgQWNjZXNzSGVscGVyLmV2ZW50c01hbmFnZXIuU3Bpbm5lclN0b3BwZWQuc3Vic2NyaWJlKGNsaWVudEJ1c3lUaW1lID0+IHRoaXMuQ2xpZW50QWN0aXZhdGVkKCkpO1xyXG4gIH1cclxuXHJcbiAgLy8vIDxzdW1tYXJ5PlxyXG4gIC8vLyBMb2cgdGhlIGN1cnJlbnQgcmVxdWVzdCBpbmZvcm1hdGlvbiBpbiBjb25zb2xlXHJcbiAgLy8vIDwvc3VtbWFyeT5cclxuICBDb21wdXRlQW5kTG9nUmVxdWVzdEluZm8oY29udGVudExlbmd0aDogbnVtYmVyLCByb3VuZFRyaXA6IG51bWJlciwgaXNMb2dnaW5nUmVzcG9uc2U6IGJvb2xlYW4pOiB2b2lkIHtcclxuICAgIGlmKCFpc051bGxPclVuZGVmaW5lZCh0aGlzLl9yZXF1ZXN0SW5mby5zZXJ2ZXJDYWxsQXQpKSB7XHJcblxyXG4gICAgICB0aGlzLl9yZXF1ZXN0SW5mby5leHRyYUluZm8uY29udGVudExlbmd0aCA9IGNvbnRlbnRMZW5ndGg7XHJcbiAgICAgIHRoaXMuX3JlcXVlc3RJbmZvLmV4dHJhSW5mby50aW1lU3RhbXAgPSBuZXcgRGF0ZSgpLnRvU3RyaW5nKCk7XHJcbiAgICAgIGxldCBleHRyYU1lc3NhZ2VTdHI6IHN0cmluZyA9IGlzTG9nZ2luZ1Jlc3BvbnNlPyAnUmVzcG9uc2Ug4qS1JyA6ICdSZXF1ZXN0IOKktSc7XHJcblxyXG4gICAgICBpZiAoaXNMb2dnaW5nUmVzcG9uc2UpIHtcclxuICAgICAgICB0aGlzLl9yZXF1ZXN0SW5mby5yb3VuZHRyaXBUaW1lID0gcm91bmRUcmlwO1xyXG4gICAgICAgIFJlbW90ZUNvbW1hbmRzUHJvY2Vzc29yLnRvdGFsVGltZUZvckhUVFBSZXF1ZXN0cyArPSByb3VuZFRyaXA7IC8vIGFkZCB0aGUgcmVxdWVzdCB0aW1lIHRvIHRvdGFsIHRpbWVcclxuICAgICAgfSBlbHNlXHJcbiAgICAgICAgUmVtb3RlQ29tbWFuZHNQcm9jZXNzb3IudG90YWxSZXF1ZXN0RGF0YUxlbmd0aCArPSBjb250ZW50TGVuZ3RoOyAvLyBhZGQgdGhlIHJlcXVlc3QgY29udGVudCB0byB0b3RhbCB0aW1lXHJcblxyXG5cclxuICAgICAgTG9nZ2VyLkluc3RhbmNlLldyaXRlUmVxdWVzdEluZm9Ub0xvZyh0aGlzLl9yZXF1ZXN0SW5mbywgZXh0cmFNZXNzYWdlU3RyKTtcclxuXHJcbiAgICAgIC8vIENsZWFyIHRoZSBjbGllbnQgc2Vzc2lvbiBhZnRlciBsb2dnaW5nIHRoZSByZXNwb25zZVxyXG4gICAgICBpZiAoaXNMb2dnaW5nUmVzcG9uc2UpXHJcbiAgICAgICAgdGhpcy5fcmVxdWVzdEluZm8uY2xlYXIoKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8vLyA8c3VtbWFyeT5cclxuICAvLy8gV2hlbiB0cnVlLCByZXF1ZXN0cyBhcmUgc2NyYW1ibGVkIGFuZCByZXNwb25zZXMgYXJlIHVuc2NyYW1ibGVkLlxyXG4gIC8vLyA8L3N1bW1hcnk+XHJcbiAgc3RhdGljIHNldCBTaG91bGRTY3JhbWJsZUFuZFVuc2NyYW1ibGVNZXNzYWdlcyh2YWx1ZTogYm9vbGVhbikge1xyXG4gICAgUmVtb3RlQ29tbWFuZHNQcm9jZXNzb3IuX3Nob3VsZFNjcmFtYmxlQW5kVW5zY3JhbWJsZU1lc3NhZ2VzID0gdmFsdWU7XHJcbiAgICBMb2dnZXIuSW5zdGFuY2UuV3JpdGVTZXJ2ZXJNZXNzYWdlc1RvTG9nKE5TdHJpbmcuRm9ybWF0KFwiU2hvdWxkU2NyYW1ibGVBbmRVbnNjcmFtYmxlTWVzc2FnZXMuU2V0OiB7MH1cIiwgdGhpcy5fc2hvdWxkU2NyYW1ibGVBbmRVbnNjcmFtYmxlTWVzc2FnZXMpKTtcclxuICB9XHJcbiAgc3RhdGljIGdldCBTaG91bGRTY3JhbWJsZUFuZFVuc2NyYW1ibGVNZXNzYWdlcygpOiBib29sZWFuIHtcclxuICAgIExvZ2dlci5JbnN0YW5jZS5Xcml0ZVNlcnZlck1lc3NhZ2VzVG9Mb2coTlN0cmluZy5Gb3JtYXQoXCJTaG91bGRTY3JhbWJsZUFuZFVuc2NyYW1ibGVNZXNzYWdlcy5HZXQ6IHswfVwiLCB0aGlzLl9zaG91bGRTY3JhbWJsZUFuZFVuc2NyYW1ibGVNZXNzYWdlcykpO1xyXG4gICAgcmV0dXJuIFJlbW90ZUNvbW1hbmRzUHJvY2Vzc29yLl9zaG91bGRTY3JhbWJsZUFuZFVuc2NyYW1ibGVNZXNzYWdlcztcclxuICB9XHJcblxyXG5cclxuICAvLy8gPHN1bW1hcnk+cGFyc2UgdGhlIGxvZyBsZXZlbCBmcm9tIGEgc3RyaW5nIHZhbHVlPC9zdW1tYXJ5PlxyXG4gIC8vLyA8cGFyYW0gbmFtZT1cInN0ckxvZ0xldmVsXCI+c3RyaW5nIHZhbHVlIG9mIHRoZSBsb2cgbGV2ZWw8L3BhcmFtPlxyXG4gIC8vLyA8cmV0dXJucz5sb2cgbGV2ZWw8L3JldHVybnM+XHJcbiAgcGFyc2VMb2dMZXZlbChzdHJMb2dMZXZlbDogc3RyaW5nKTogTG9nZ2VyX0xvZ0xldmVscyB7XHJcbiAgICBsZXQgbG9nTGV2ZWw6IExvZ2dlcl9Mb2dMZXZlbHMgPSBMb2dnZXJfTG9nTGV2ZWxzLk5vbmU7XHJcblxyXG4gICAgaWYgKCFOU3RyaW5nLklzTnVsbE9yRW1wdHkoc3RyTG9nTGV2ZWwpKSB7XHJcbiAgICAgIGlmIChzdHJMb2dMZXZlbC50b1VwcGVyQ2FzZSgpLnN0YXJ0c1dpdGgoIFwiU0VSVkVSXCIpKVxyXG4gICAgICAgIGxvZ0xldmVsID0gc3RyTG9nTGV2ZWwuZW5kc1dpdGgoXCIjXCIpID8gTG9nZ2VyX0xvZ0xldmVscy5TZXJ2ZXJNZXNzYWdlcyA6IExvZ2dlcl9Mb2dMZXZlbHMuU2VydmVyOyAvLyBvbmx5IHJlcXVlc3RzIHRvIHRoZSBzZXJ2ZXJcclxuICAgICAgZWxzZSBpZiAoc3RyTG9nTGV2ZWwudG9VcHBlckNhc2UoKS5zdGFydHNXaXRoKFwiU1wiKSB8fCBzdHJMb2dMZXZlbC50b1VwcGVyQ2FzZSgpLnN0YXJ0c1dpdGgoXCJRXCIpKVxyXG4gICAgICAgIGxvZ0xldmVsID0gTG9nZ2VyX0xvZ0xldmVscy5TdXBwb3J0O1xyXG4gICAgICBlbHNlIGlmIChzdHJMb2dMZXZlbC50b1VwcGVyQ2FzZSgpLnN0YXJ0c1dpdGgoXCJHXCIpKVxyXG4gICAgICAgIGxvZ0xldmVsID0gTG9nZ2VyX0xvZ0xldmVscy5HdWk7XHJcbiAgICAgIGVsc2UgaWYgKHN0ckxvZ0xldmVsLnRvVXBwZXJDYXNlKCkuc3RhcnRzV2l0aChcIkRcIikpXHJcbiAgICAgICAgbG9nTGV2ZWwgPSBMb2dnZXJfTG9nTGV2ZWxzLkRldmVsb3BtZW50O1xyXG4gICAgICBlbHNlIGlmIChzdHJMb2dMZXZlbC50b1VwcGVyQ2FzZSgpLnN0YXJ0c1dpdGgoXCJCXCIpKVxyXG4gICAgICAgIGxvZ0xldmVsID0gTG9nZ2VyX0xvZ0xldmVscy5CYXNpYztcclxuICAgICAgZWxzZSBpZiAoc3RyTG9nTGV2ZWwudG9VcHBlckNhc2UoKS5zdGFydHNXaXRoKFwiUlwiKSlcclxuICAgICAgICBsb2dMZXZlbCA9IExvZ2dlcl9Mb2dMZXZlbHMuUmVxdWVzdEluZm87XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIGxvZ0xldmVsO1xyXG4gIH1cclxuXHJcblxyXG4gIC8vLyA8c3VtbWFyeT4gYnVpbGQgdGhlIFhNTCBzdHJpbmcgb2YgdGhlIGRhdGEgdGhhdCBzaG91bGQgYmUgc2VudCB0byB0aGUgc2VydmVyPC9zdW1tYXJ5PlxyXG4gIC8vLyA8cGFyYW0gbmFtZT1cInNlcmlhbGl6ZVRhc2tzXCI+aWYgdHJ1ZSwgdGFza3MgaW4gdGhlIGN1cnJlbnQgZXhlY3V0aW9uIHdpbGwgYWxzbyBiZSBzZXJpYWxpemVkLjwvcGFyYW0+XHJcbiAgYXN5bmMgUHJlcGFyZVJlcXVlc3Qoc2VyaWFsaXplVGFza3M6IGJvb2xlYW4pOiBQcm9taXNlPHN0cmluZz4ge1xyXG4gICAgbGV0IHhtbEJ1ZjogU3RyaW5nQnVpbGRlciA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7XHJcbiAgICB4bWxCdWYuQXBwZW5kKFhNTENvbnN0YW50cy5NR19UQUdfT1BFTik7XHJcblxyXG4gICAgLy8gdGhlIGNsaWVudCBubyBsb25nZXIgc2VuZHMgKGFuZCBlbXB0aWVzKSB0aGUgZXZlbnQgcXVldWUgdG8gdGhlIHNlcnZlclxyXG4gICAgLy8gc2luY2UgdGhlIHNlcnZlciBoYXMgbm90aGluZyB1c2VmdWwgdG8gZG8gd2l0aCB0aGUgY2xpZW50IHBlbmRpbmcgZXZlbnRzXHJcbiAgICBpZiAoQWNjZXNzSGVscGVyLm1nRGF0YVRhYmxlLmdldEN1cnJNR0RhdGEoKSAhPT0gbnVsbCkge1xyXG4gICAgICBsZXQgeG1sVW5zY3JhbWJsZWQ6IFN0cmluZ0J1aWxkZXIgPSBuZXcgU3RyaW5nQnVpbGRlcigpO1xyXG4gICAgICBhd2FpdCBBY2Nlc3NIZWxwZXIubWdEYXRhVGFibGUuYnVpbGRYTUwoeG1sVW5zY3JhbWJsZWQsIHNlcmlhbGl6ZVRhc2tzKTtcclxuXHJcbiAgICAgIGlmIChSZW1vdGVDb21tYW5kc1Byb2Nlc3Nvci5TaG91bGRTY3JhbWJsZUFuZFVuc2NyYW1ibGVNZXNzYWdlcylcclxuICAgICAgICB4bWxCdWYuQXBwZW5kKFNjcmFtYmxlci5TY3JhbWJsZSh4bWxVbnNjcmFtYmxlZC5Ub1N0cmluZygpKSk7XHJcbiAgICAgIGVsc2VcclxuICAgICAgICB4bWxCdWYuQXBwZW5kKHhtbFVuc2NyYW1ibGVkLlRvU3RyaW5nKCkpO1xyXG4gICAgfVxyXG4gICAgeG1sQnVmLkFwcGVuZChcIjwvXCIgKyBYTUxDb25zdGFudHMuTUdfVEFHX1hNTCArIFhNTENvbnN0YW50cy5UQUdfQ0xPU0UpO1xyXG5cclxuICAgIHJldHVybiB4bWxCdWYuVG9TdHJpbmcoKTtcclxuICB9XHJcblxyXG5cclxuICAvLy8gPHN1bW1hcnk+cGFyc2UgYSByZXNwb25zZSAoZnJvbSB0aGUgU2VydmVyKSBhbmQgZXhlY3V0ZSBjb21tYW5kcyBpZiByZXR1cm5lZCB3aXRoaW4gdGhlIHJlc3BvbnNlLjwvc3VtbWFyeT5cclxuICAvLy8gPHBhcmFtIG5hbWU9XCJyZXNwb25zZVwiPihYTUwgZm9ybWF0dGVkKSByZXNwb25zZS48L3BhcmFtPlxyXG4gIC8vLyA8cGFyYW0gbmFtZT1cImN1cnJNZ2RJRFwiPm51bWJlciBvZiB3aW5kb3cgaW4gZ2xvYmFsIGFycmF5PC9wYXJhbT5cclxuICAvLy8gPHBhcmFtIG5hbWU9XCJvcGVuaW5nVGFza0RldGFpbHNcIj5hZGRpdGlvbmFsIGluZm9ybWF0aW9uIG9mIG9wZW5pbmcgdGFzazwvcGFyYW0+XHJcbiAgLy8vIDxwYXJhbSBuYW1lPVwicmVzXCI+cmVzdWx0IHRvIGJlIHJlYWQgZnJvbSBjb21tYW5kIHJldHVybmVkIHdpdGluIHRoZSByZXNwb25zZS48L3BhcmFtPlxyXG4gIGFzeW5jIFByb2Nlc3NSZXNwb25zZShyZXNwb25zZTogc3RyaW5nLCBjdXJyTWdkSUQ6IG51bWJlciwgb3BlbmluZ1Rhc2tEZXRhaWxzOiBPcGVuaW5nVGFza0RldGFpbHMsIHJlczogSVJlc3VsdFZhbHVlKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICBMb2dnZXIuSW5zdGFuY2UuV3JpdGVEZXZUb0xvZyhcIjwtLSBQcm9jZXNzUmVzcG9uc2Ugc3RhcnRlZCAtLT5cIik7XHJcbiAgICBpZihvcGVuaW5nVGFza0RldGFpbHMgPT09IG51bGwpXHJcbiAgICAgIG9wZW5pbmdUYXNrRGV0YWlscyA9IG5ldyBPcGVuaW5nVGFza0RldGFpbHMoKTtcclxuXHJcbiAgICBsZXQgc3lzdGVtTWlsbGlzZWNvbmRzOiBudW1iZXIgPSBNaXNjLmdldFN5c3RlbU1pbGxpc2Vjb25kcygpO1xyXG4gICAgaWYgKHJlc3BvbnNlID09PSBudWxsIHx8IHJlc3BvbnNlLnRyaW0oKS5sZW5ndGggPT09IDApXHJcbiAgICAgIHJldHVybjtcclxuXHJcbiAgICBBY2Nlc3NIZWxwZXIubWdEYXRhVGFibGUuY3Vyck1nZElEID0gY3Vyck1nZElEO1xyXG5cclxuICAgIFJ1bnRpbWVDb250ZXh0QmFzZS5JbnN0YW5jZS5QYXJzZXIucHVzaCgpOyAvLyBhbGxvdyByZWN1cnNpdmUgcGFyc2luZ1xyXG4gICAgUnVudGltZUNvbnRleHRCYXNlLkluc3RhbmNlLlBhcnNlci5zZXRYTUxkYXRhKHJlc3BvbnNlKTtcclxuICAgIFJ1bnRpbWVDb250ZXh0QmFzZS5JbnN0YW5jZS5QYXJzZXIuc2V0Q3VyckluZGV4KDApO1xyXG5cclxuICAgIGxldCBjdXJyTUdEYXRhOiBNR0RhdGEgPSBBY2Nlc3NIZWxwZXIubWdEYXRhVGFibGUuZ2V0Q3Vyck1HRGF0YSgpO1xyXG4gICAgYXdhaXQgY3Vyck1HRGF0YS5maWxsRGF0YShvcGVuaW5nVGFza0RldGFpbHMsIFJ1bnRpbWVDb250ZXh0QmFzZS5JbnN0YW5jZS5QYXJzZXIpO1xyXG5cclxuICAgIC8vIGZyZWUgbWVtb3J5XHJcbiAgICBSdW50aW1lQ29udGV4dEJhc2UuSW5zdGFuY2UuUGFyc2VyLnNldFhNTGRhdGEobnVsbCk7XHJcbiAgICBSdW50aW1lQ29udGV4dEJhc2UuSW5zdGFuY2UuUGFyc2VyLnBvcCgpO1xyXG5cclxuICAgIExvZ2dlci5JbnN0YW5jZS5Xcml0ZURldlRvTG9nKFwiPC0tIFByb2Nlc3NSZXNwb25zZSBmaW5pc2hlZCAtLT4gKFwiICsgKE1pc2MuZ2V0U3lzdGVtTWlsbGlzZWNvbmRzKCkgLSBzeXN0ZW1NaWxsaXNlY29uZHMpICsgXCIpXCIpO1xyXG4gICAgLy8gZXhlY3V0ZSB0aGUgY29tbWFuZHMgdGhhdCB3ZXJlIHJldHVybmVkIGluIHRoZSByZXNwb25zZVxyXG4gICAgYXdhaXQoPENvbW1hbmRzVGFibGU+Y3Vyck1HRGF0YS5DbWRzVG9DbGllbnQpLkV4ZWN1dGUocmVzKTtcclxuICAgIGF3YWl0IHRoaXMuUHJvY2Vzc1JlY292ZXJ5KCk7XHJcbiAgfVxyXG5cclxuICAvLy8gPHN1bW1hcnk+XHJcbiAgLy8vIHByb2Nlc3NSZWNvdmVyeVxyXG4gIC8vLyA8L3N1bW1hcnk+XHJcbiAgYXN5bmMgUHJvY2Vzc1JlY292ZXJ5KCk6IFByb21pc2U8dm9pZD4ge1xyXG5cclxuICAgIC8vIFFDUiAjNzcxMDEyIC0gcHJvY2VzcyBkYXRhIGVycm9yIHJlY292ZXJ5IG9ubHkgYWZ0ZXIgdGhlIHBhcnNpbmcgcHJvY2VzcyBpcyBvdmVyLlxyXG4gICAgQWNjZXNzSGVscGVyLmV2ZW50c01hbmFnZXIucHVzaE5ld0V4ZWNTdGFja3MoKTtcclxuICAgIGF3YWl0IEFjY2Vzc0hlbHBlci5tZ0RhdGFUYWJsZS5wcm9jZXNzUmVjb3ZlcnkoKTtcclxuICAgIEFjY2Vzc0hlbHBlci5ldmVudHNNYW5hZ2VyLnBvcE5ld0V4ZWNTdGFja3MoKTtcclxuICB9XHJcbn1cclxuXHJcbi8vLyA8c3VtbWFyeT5oZWxwZXIgY2xhc3M6IGRldGFpbHMgZnJvbSB0aGUgcnVudGltZS1lbmdpbmUgLSBlbnZpcm9ubWVudCB2YWx1ZXMuXHJcbi8vLyBIYW5kc2hha2UgcmVzcG9uc2U6IDxSaWNoY2xpZW50cmVzcG9uc2U+IDxDb250ZXh0SUQ+Li4uPC9Db250ZXh0SUQ+IDxFbnZpcm9ubWVudCBJbnB1dFBhc3N3b3JkPVwiWXxOXCJcclxuLy8vIFN5c3RlbUxvZ2luPVwiRnxOfER8TFwiIC8+IDwvUmljaGNsaWVudHJlc3BvbnNlPlxyXG4vLy8gPC9zdW1tYXJ5PlxyXG5jbGFzcyBIYW5kc2hha2VSZXNwb25zZSB7XHJcbiAgc3RhdGljIHJlYWRvbmx5IFNZU1RFTV9MT0dJTl9BRDogc3RyaW5nID0gJ0QnO1xyXG5cclxuICBwcml2YXRlIF9zY3JhbWJsZU1lc3NhZ2VzOiBib29sZWFuID0gdHJ1ZTsgLy8gdHJ1ZSBpZiBtZXNzYWdlcyBzaG91bGQgYmUgc2NyYW1ibGVkL3Vuc2NyYW1ibGVkIGJ5IHRoZSBjbGllbnQgYW5kIHNlcnZlclxyXG4gIGdldCBTY3JhbWJsZU1lc3NhZ2VzKCk6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuIHRoaXMuX3NjcmFtYmxlTWVzc2FnZXM7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIF9jb250ZXh0SWQ6IHN0cmluZyA9IG51bGw7XHJcbiAgZ2V0IENvbnRleHRJZCgpOiBzdHJpbmcge1xyXG4gICAgcmV0dXJuIHRoaXMuX2NvbnRleHRJZDtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgX3ByaXZhdGVTZXNzaW9uSWQ6IHN0cmluZyA9IG51bGw7XHJcbiAgZ2V0IEdldFNlc3Npb25JZCgpOiBzdHJpbmcge1xyXG4gICAgcmV0dXJuIHRoaXMuX3ByaXZhdGVTZXNzaW9uSWQ7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIF9pbnB1dFBhc3N3b3JkOiBib29sZWFuID0gZmFsc2U7XHJcbiAgZ2V0IElucHV0UGFzc3dvcmQoKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gdGhpcy5faW5wdXRQYXNzd29yZDtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgX2h0dHBUaW1lb3V0OiBudW1iZXIgPSAwO1xyXG4gIGdldCBIdHRwVGltZW91dCgpOiBudW1iZXIge1xyXG4gICAgcmV0dXJuIHRoaXMuX2h0dHBUaW1lb3V0O1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfc3lzdGVtTG9naW46IHN0cmluZyA9IG51bGw7XHJcbiAgZ2V0IFN5c3RlbUxvZ2luKCk6IHN0cmluZyB7XHJcbiAgICByZXR1cm4gdGhpcy5fc3lzdGVtTG9naW47XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIF9tYXhJbnRlcm5hbExvZ0xldmVsOiBzdHJpbmcgPSBudWxsO1xyXG4gIGdldCBNYXhJbnRlcm5hbExvZ0xldmVsKCk6IHN0cmluZyB7XHJcbiAgICByZXR1cm4gdGhpcy5fbWF4SW50ZXJuYWxMb2dMZXZlbDtcclxuICB9XHJcblxyXG4gIGNvbnN0cnVjdG9yKHJlc3BvbnNlWE1MOiBzdHJpbmcpIHtcclxuICAgIHRyeSB7XHJcbiAgICAgIEpTT05fVXRpbHMuSlNPTkZyb21YTUwocmVzcG9uc2VYTUwsIHRoaXMuRmlsbEZyb21KU09OLmJpbmQodGhpcykpO1xyXG4gICAgfVxyXG4gICAgY2F0Y2ggKGV4KSB7XHJcbiAgICAgIExvZ2dlci5JbnN0YW5jZS5Xcml0ZUV4Y2VwdGlvblRvTG9nKGV4LCByZXNwb25zZVhNTCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIEZpbGxGcm9tSlNPTiAoZXJyb3IsIHJlc3VsdCk6IHZvaWQge1xyXG5cclxuICAgIC8vIElmIHRoZXJlIHdhcyBhbiBlcnJvciBpbiBwYXJzaW5nIHRoZSBYTUwsXHJcbiAgICBpZiAoZXJyb3IgIT0gbnVsbCkge1xyXG4gICAgICB0aHJvdyBlcnJvcjtcclxuICAgIH1cclxuXHJcbiAgICBsZXQgcmVzcG9uc2UgPSByZXN1bHRbJ1JpY2hjbGllbnRyZXNwb25zZSddO1xyXG5cclxuICAgIGZvciAobGV0IGVsZW1lbnROYW1lIGluIHJlc3BvbnNlKSB7XHJcbiAgICAgIGlmIChyZXNwb25zZS5oYXNPd25Qcm9wZXJ0eShlbGVtZW50TmFtZSkpIHtcclxuXHJcbiAgICAgICAgc3dpdGNoIChlbGVtZW50TmFtZSlcclxuICAgICAgICB7XHJcbiAgICAgICAgICBjYXNlIFwiQ29udGV4dElEXCI6XHJcbiAgICAgICAgICAgIHRoaXMuX2NvbnRleHRJZCA9IHJlc3BvbnNlW2VsZW1lbnROYW1lXVswXTtcclxuICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICBjYXNlIFwiU2Vzc2lvbklEXCI6XHJcbiAgICAgICAgICAgIHRoaXMuX3ByaXZhdGVTZXNzaW9uSWQgPSByZXNwb25zZVtlbGVtZW50TmFtZV1bMF07XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgY2FzZSBcIkVudmlyb25tZW50XCI6XHJcbiAgICAgICAgICAgIGxldCBlbnZBdHRyaWJ1dGVzID0gcmVzcG9uc2VbXCJFbnZpcm9ubWVudFwiXVswXVsnJCddO1xyXG5cclxuICAgICAgICAgICAgaWYgKCFpc051bGxPclVuZGVmaW5lZChlbnZBdHRyaWJ1dGVzW1wiU2NyYW1ibGVNZXNzYWdlc1wiXSkpIHtcclxuICAgICAgICAgICAgICBEZWJ1Zy5Bc3NlcnQoZW52QXR0cmlidXRlc1tcIlNjcmFtYmxlTWVzc2FnZXNcIl0gPT09IFwiTlwiKTtcclxuICAgICAgICAgICAgICB0aGlzLl9zY3JhbWJsZU1lc3NhZ2VzID0gZmFsc2U7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKCFpc051bGxPclVuZGVmaW5lZChlbnZBdHRyaWJ1dGVzW1wiTWF4SW50ZXJuYWxMb2dMZXZlbFwiXSkpXHJcbiAgICAgICAgICAgICAgdGhpcy5fbWF4SW50ZXJuYWxMb2dMZXZlbCA9IGVudkF0dHJpYnV0ZXNbXCJNYXhJbnRlcm5hbExvZ0xldmVsXCJdO1xyXG4gICAgICAgICAgICBpZiAoIWlzTnVsbE9yVW5kZWZpbmVkKGVudkF0dHJpYnV0ZXNbXCJJbnB1dFBhc3N3b3JkXCJdKSAmJiBlbnZBdHRyaWJ1dGVzW1wiSW5wdXRQYXNzd29yZFwiXS50b0xvY2FsZUxvd2VyQ2FzZSgpID09PSBcInlcIilcclxuICAgICAgICAgICAgICB0aGlzLl9pbnB1dFBhc3N3b3JkID0gdHJ1ZTtcclxuICAgICAgICAgICAgaWYgKCFpc051bGxPclVuZGVmaW5lZChlbnZBdHRyaWJ1dGVzW1wiU3lzdGVtTG9naW5cIl0pKVxyXG4gICAgICAgICAgICAgIHRoaXMuX3N5c3RlbUxvZ2luID0gZW52QXR0cmlidXRlc1tcIlN5c3RlbUxvZ2luXCJdO1xyXG4gICAgICAgICAgICBpZiAoIWlzTnVsbE9yVW5kZWZpbmVkKGVudkF0dHJpYnV0ZXNbQ29uc3RJbnRlcmZhY2UuTUdfVEFHX0hUVFBfQ09NTVVOSUNBVElPTl9USU1FT1VUXSkpXHJcbiAgICAgICAgICAgICAgdGhpcy5faHR0cFRpbWVvdXQgPSArZW52QXR0cmlidXRlc1tDb25zdEludGVyZmFjZS5NR19UQUdfSFRUUF9DT01NVU5JQ0FUSU9OX1RJTUVPVVRdO1xyXG4gICAgICAgICAgICBpZiAoIWlzTnVsbE9yVW5kZWZpbmVkKGVudkF0dHJpYnV0ZXNbXCJGb3J3YXJkU2xhc2hcIl0pKVxyXG4gICAgICAgICAgICAgIEFjY2Vzc0hlbHBlci5lbnZpcm9ubWVudC5Gb3J3YXJkU2xhc2hVc2FnZSA9IGVudkF0dHJpYnV0ZXNbXCJGb3J3YXJkU2xhc2hcIl07XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxufVxyXG5cclxuLy8vIDxzdW1tYXJ5PlRoaXMgY2xhc3MgaW1wbGVtZW50cyBNZ1NBWEhhbmRsZXJJbnRlcmZhY2UsIHdoaWNoIG1lYW5zIHRoYXQgaXQgZGVmaW5lcyBhbGwgdGhlIFwiY2FsbGJhY2tcIlxyXG4vLy8gbWV0aG9kcyB0aGF0IHRoZSBTQVggcGFyc2VyIHdpbGwgaW52b2tlIHRvIG5vdGlmeSB0aGUgYXBwbGljYXRpb24uIEluIHRoaXMgZXhhbXBsZSB3ZSBvdmVycmlkZSB0aGVcclxuLy8vIG1ldGhvZHMgdGhhdCB3ZSByZXF1aXJlLjwvc3VtbWFyeT5cclxuY2xhc3MgRXJyb3JNZXNzYWdlWG1sIHtcclxuICBwcml2YXRlIF9sYXN0UmVxdWVzdFRpbWU6IG51bWJlciA9IDA7XHJcbiAgY29udGV4dEluYWN0aXZpdHlUaW1lb3V0OiBudW1iZXI7XHJcblxyXG4gIHByaXZhdGUgX2Vycm9yTWVzc2FnZTogc3RyaW5nID0gbnVsbDtcclxuICBwcml2YXRlIF9lcnJvckNvZGU6IG51bWJlciA9IDA7XHJcbiAgcHJpdmF0ZSBfbWlkZGxld2FyZUFkZHJlc3M6IHN0cmluZyA9IG51bGw7XHJcbiAgcHJpdmF0ZSByZWFkb25seSBfcGFyc2luZ0ZhaWxlZDogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICBjb25zdHJ1Y3Rvcih4bWxDb250ZW50OiBzdHJpbmcsIGxhc3RSZXF1ZXN0VGltZTogbnVtYmVyLCBjb250ZXh0SW5hY3Rpdml0eVRpbWVvdXQ6IG51bWJlcikge1xyXG4gICAgdGhpcy5fbGFzdFJlcXVlc3RUaW1lID0gbGFzdFJlcXVlc3RUaW1lO1xyXG4gICAgdGhpcy5jb250ZXh0SW5hY3Rpdml0eVRpbWVvdXQgPSBjb250ZXh0SW5hY3Rpdml0eVRpbWVvdXQ7XHJcbiAgICB0cnkge1xyXG4gICAgICBKU09OX1V0aWxzLkpTT05Gcm9tWE1MKHhtbENvbnRlbnQsIHRoaXMuRmlsbEZyb21KU09OLmJpbmQodGhpcykpO1xyXG4gICAgfVxyXG4gICAgY2F0Y2ggKGV4KSB7XHJcbiAgICAgIExvZ2dlci5JbnN0YW5jZS5Xcml0ZUV4Y2VwdGlvblRvTG9nKGV4KTtcclxuICAgICAgTWlzYy5Xcml0ZVN0YWNrVHJhY2UoZXgpO1xyXG4gICAgICB0aGlzLl9wYXJzaW5nRmFpbGVkID0gdHJ1ZTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgRmlsbEZyb21KU09OIChlcnJvciwgcmVzdWx0KTogdm9pZCB7XHJcblxyXG4gICAgLy8gSWYgdGhlcmUgd2FzIGFuIGVycm9yIGluIHBhcnNpbmcgdGhlIFhNTCxcclxuICAgIGlmIChlcnJvciAhPSBudWxsKSB7XHJcbiAgICAgIHRocm93IGVycm9yO1xyXG4gICAgfVxyXG5cclxuICAgIGxldCB4bWxlcnIgPSByZXN1bHRbJ3htbGVyciddO1xyXG5cclxuICAgIGZvciAobGV0IGVsZW1lbnROYW1lIGluIHhtbGVycikge1xyXG4gICAgICBpZiAoeG1sZXJyLmhhc093blByb3BlcnR5KGVsZW1lbnROYW1lKSkge1xyXG4gICAgICAgIHN3aXRjaCAoZWxlbWVudE5hbWUpXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgY2FzZSBcImVycm1zZ1wiOlxyXG4gICAgICAgICAgICB0aGlzLl9lcnJvck1lc3NhZ2UgPSB4bWxlcnJbZWxlbWVudE5hbWVdWzBdO1xyXG4gICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgIGNhc2UgXCJlcnJjb2RlXCI6XHJcbiAgICAgICAgICAgIHRoaXMuX2Vycm9yQ29kZSA9ICsoeG1sZXJyW2VsZW1lbnROYW1lXSk7XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgY2FzZSBcInNlcnZlclwiOlxyXG4gICAgICAgICAgICB0aGlzLl9taWRkbGV3YXJlQWRkcmVzcyA9IHhtbGVycltlbGVtZW50TmFtZV1bMF07XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgY2FzZSBcImFwcG5hbWVcIjogLy8gaWdub3JlZCAtIHRoZSBjbGllbnQgbGlzdHMgdGhpcyB2YWx1ZSBmcm9tIHRoZSBleGVjdXRpb24gcHJvcGVydGllc1xyXG4gICAgICAgICAgY2FzZSBcInByZ25hbWVcIjogLy8gaWdub3JlZCAtIHRoZSBjbGllbnQgbGlzdHMgdGhpcyB2YWx1ZSBmcm9tIHRoZSBleGVjdXRpb24gcHJvcGVydGllc1xyXG4gICAgICAgICAgY2FzZSBcImFyZ3VtZW50c1wiOiAvLyBpZ25vcmVkXHJcbiAgICAgICAgICBjYXNlIFwidXNlcm5hbWVcIjogIC8vIGlnbm9yZWRcclxuICAgICAgICAgIGNhc2UgXCJ4bWxlcnJcIjogLy8gZW5kIG9mIHRoZSBlcnJvciBtZXNzYWdlXHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgTG9nZ2VyLkluc3RhbmNlLldyaXRlRXhjZXB0aW9uVG9Mb2dXaXRoTXNnKE5TdHJpbmcuRm9ybWF0KFwiVW5rbm93biBlbGVtZW50OiAnezB9J1wiLCBlbGVtZW50TmFtZSkpO1xyXG4gICAgICAgICAgICBicmVhaztcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIEdldENvZGUoKTogbnVtYmVyIHtcclxuICAgIHJldHVybiB0aGlzLl9lcnJvckNvZGU7XHJcbiAgfVxyXG5cclxuICAvLyBidWlsZCAmIHJldHVybiBhIGZvcm1hdHRlZCBlcnJvciBtZXNzYWdlXHJcbiAgR2V0TWVzc2FnZSgpOiBzdHJpbmcge1xyXG4gICAgbGV0IHNiOiBTdHJpbmdCdWlsZGVyID0gbmV3IFN0cmluZ0J1aWxkZXIoKTtcclxuXHJcbiAgICBpZiAodGhpcy5fcGFyc2luZ0ZhaWxlZCkge1xyXG4gICAgICBzYi5BcHBlbmQoQWNjZXNzSGVscGVyLmxhbmd1YWdlRGF0YS5nZXRDb25zdE1lc3NhZ2UoTXNnSW50ZXJmYWNlLlJDX1NUUl9GN19VTkVYUEVDVEVEX0VSUikpO1xyXG4gICAgfVxyXG4gICAgZWxzZSB7XHJcbiAgICAgIHN3aXRjaCAodGhpcy5fZXJyb3JDb2RlKSB7XHJcbiAgICAgICAgY2FzZSBTZXJ2ZXJFcnJvci5FUlJfQ1RYX05PVF9GT1VORDpcclxuICAgICAgICAgIGlmICh0aGlzLkluYWN0aXZpdHlUaW1lb3V0RXhwaXJlZCgpKVxyXG4gICAgICAgICAgICBzYi5BcHBlbmQoTlN0cmluZy5Gb3JtYXQoXCJ7MH0gKHsxfSB7Mn0pXCIsXHJcbiAgICAgICAgICAgICAgQWNjZXNzSGVscGVyLmxhbmd1YWdlRGF0YS5nZXRDb25zdE1lc3NhZ2UoTXNnSW50ZXJmYWNlLlNUUl9FUlJfU0VTU0lPTl9DTE9TRURfSU5BQ1RJVklUWSksXHJcbiAgICAgICAgICAgICAgTWF0aC5mbG9vcih0aGlzLmNvbnRleHRJbmFjdGl2aXR5VGltZW91dCAvIDYwMCksIC8vIGNvbnZlcnNpb24gZnJvbSAxLzEwIG9mIHNlY29uZHMgdG8gbWludXRlc1xyXG4gICAgICAgICAgICAgIEFjY2Vzc0hlbHBlci5sYW5ndWFnZURhdGEuZ2V0Q29uc3RNZXNzYWdlKE1zZ0ludGVyZmFjZS5TVFJfTUlOVVRFUykpKTtcclxuICAgICAgICAgIGVsc2VcclxuICAgICAgICAgICAgc2IuQXBwZW5kKE5TdHJpbmcuRm9ybWF0KFwiezB9ICh7MX0pLlwiLCBBY2Nlc3NIZWxwZXIubGFuZ3VhZ2VEYXRhLmdldENvbnN0TWVzc2FnZShNc2dJbnRlcmZhY2UuU1RSX0VSUl9TRVNTSU9OX0NMT1NFRCksIHRoaXMuX2Vycm9yQ29kZSkpO1xyXG4gICAgICAgICAgYnJlYWs7XHJcblxyXG4gICAgICAgIGNhc2UgU2VydmVyRXJyb3IuRVJSX1dFQkNMSUVOVF9QUk9HUkFNX1JFTE9BREVEOlxyXG4gICAgICAgICAgc2IuQXBwZW5kKEFjY2Vzc0hlbHBlci5sYW5ndWFnZURhdGEuZ2V0Q29uc3RNZXNzYWdlKE1zZ0ludGVyZmFjZS5TVFJfRVJSX1dFQkNMSUVOVF9QUk9HUkFNX1JFTE9BREVEKSk7XHJcbiAgICAgICAgICBicmVhaztcclxuXHJcbiAgICAgICAgY2FzZSBTZXJ2ZXJFcnJvci5FUlJfRVhFQ1VURURfUFJPR1JBTV9DSEFOR0VEOlxyXG4gICAgICAgICAgc2IuQXBwZW5kKEFjY2Vzc0hlbHBlci5sYW5ndWFnZURhdGEuZ2V0Q29uc3RNZXNzYWdlKE1zZ0ludGVyZmFjZS5TVFJfRVJSX0VYRUNVVEVEX1BST0dSQU1fQ0hBTkdFRCkpO1xyXG4gICAgICAgICAgYnJlYWs7XHJcblxyXG4gICAgICAgIGNhc2UgU2VydmVyRXJyb3IuRVJSX0FVVEhFTlRJQ0FUSU9OOlxyXG4gICAgICAgICAgc2IuQXBwZW5kKEFjY2Vzc0hlbHBlci5sYW5ndWFnZURhdGEuZ2V0Q29uc3RNZXNzYWdlKE1zZ0ludGVyZmFjZS5VU1JJTlBfU1RSX0JBRFBBU1NXKSk7XHJcbiAgICAgICAgICBicmVhaztcclxuXHJcbiAgICAgICAgY2FzZSBTZXJ2ZXJFcnJvci5FUlJfQUNDRVNTX0RFTklFRDpcclxuICAgICAgICAgIHNiLkFwcGVuZChBY2Nlc3NIZWxwZXIubGFuZ3VhZ2VEYXRhLmdldENvbnN0TWVzc2FnZShNc2dJbnRlcmZhY2UuU1RSX0VSUl9BVVRIT1JJWkFUSU9OX0ZBSUxVUkUpKTtcclxuICAgICAgICAgIGJyZWFrO1xyXG5cclxuICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgc2IuQXBwZW5kKHRoaXMuX2Vycm9yTWVzc2FnZSk7XHJcbiAgICAgICAgICBicmVhaztcclxuICAgICAgfVxyXG5cclxuICAgICAgc2IuQXBwZW5kKE9TRW52aXJvbm1lbnQuRW9sU2VxICsgT1NFbnZpcm9ubWVudC5Fb2xTZXEpO1xyXG5cclxuICAgICAgaWYgKCFTZXJ2ZXJDb25maWcuSW5zdGFuY2UuU2hvdWxkRGlzcGxheUdlbmVyaWNFcnJvcigpKSB7XHJcbiAgICAgICAgc2IuQXBwZW5kKEFjY2Vzc0hlbHBlci5sYW5ndWFnZURhdGEuZ2V0Q29uc3RNZXNzYWdlKE1zZ0ludGVyZmFjZS5CUk9XU0VSX09QVF9JTkZPX1NFUlZFUl9TVFIpICsgXCI6ICAgXCIpO1xyXG4gICAgICAgIHNiLkFwcGVuZChTZXJ2ZXJDb25maWcuSW5zdGFuY2UuZ2V0U2VydmVyKCkpO1xyXG4gICAgICAgIGlmICghTlN0cmluZy5Jc051bGxPckVtcHR5KHRoaXMuX21pZGRsZXdhcmVBZGRyZXNzKSkge1xyXG4gICAgICAgICAgc2IuQXBwZW5kKFwiIC0tPiBcIik7XHJcbiAgICAgICAgICBzYi5BcHBlbmQodGhpcy5fbWlkZGxld2FyZUFkZHJlc3MpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBzYi5BcHBlbmQoT1NFbnZpcm9ubWVudC5Fb2xTZXEpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBzYi5BcHBlbmQoQWNjZXNzSGVscGVyLmxhbmd1YWdlRGF0YS5nZXRDb25zdE1lc3NhZ2UoTXNnSW50ZXJmYWNlLlRBU0tSVUxFX1NUUl9BUFBMSUNBVElPTikgKyBcIjogICBcXFwiXCIpO1xyXG4gICAgICBzYi5BcHBlbmQoU2VydmVyQ29uZmlnLkluc3RhbmNlLmdldEFwcE5hbWUoKSk7XHJcbiAgICAgIHNiLkFwcGVuZChcIlxcXCIgKFxcXCJcIik7XHJcbiAgICAgIHNiLkFwcGVuZChcIlxcXCIpXCIpO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBzYi5Ub1N0cmluZygpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBJbmFjdGl2aXR5VGltZW91dEV4cGlyZWQoKTogYm9vbGVhbiB7XHJcbiAgICBsZXQgZXhwaXJlZDogYm9vbGVhbiA9IGZhbHNlO1xyXG4gICAgaWYgKHRoaXMuY29udGV4dEluYWN0aXZpdHlUaW1lb3V0ID4gMCkge1xyXG4gICAgICBsZXQgY3VyclRpbWVNaWxsaTogbnVtYmVyID0gTWlzYy5nZXRTeXN0ZW1NaWxsaXNlY29uZHMoKTtcclxuICAgICAgZXhwaXJlZCA9ICgoY3VyclRpbWVNaWxsaSAtIHRoaXMuX2xhc3RSZXF1ZXN0VGltZSkgPiAodGhpcy5jb250ZXh0SW5hY3Rpdml0eVRpbWVvdXQgKiAxMDApKTtcclxuICAgIH1cclxuICAgIHJldHVybiBleHBpcmVkO1xyXG4gIH1cclxufVxyXG5cclxuLy8gVE9ETzogSW1wbGVtZW50IHRoaXMgY2xhc3NcclxuLy8gY2xhc3MgQ2xpZW50TG9nQWNjdW11bGF0b3Ige1xyXG4vL1xyXG4vLyAgIHByaXZhdGUgc3RhdGljIENMSUVOVF9MT0dfSERSX01TRzogc3RyaW5nID0gXCJDbGllbnQgbG9nIGZpbGVcIjtcclxuLy8gICBwcml2YXRlIHN0YXRpYyBfZXhpc3RpbmdMb2dOYW1lczogTGlzdDxzdHJpbmc+ID0gbmV3IExpc3Q8c3RyaW5nPigpO1xyXG4vLyAgIHByaXZhdGUgX2NsaWVudExvZ09zOiBTdHJlYW1Xcml0ZXIgPSBudWxsO1xyXG4vLyAgIHByaXZhdGUgX2NvbnRleHRJZDogbnVtYmVyID0gMDtcclxuLy8gICBwcml2YXRlIF9mYWlsZWQ6IGJvb2xlYW4gPSBmYWxzZTtcclxuLy8gICBwcml2YXRlIF9maWxlTmFtZTogc3RyaW5nID0gbnVsbDtcclxuLy9cclxuLy8gICBjb25zdHJ1Y3Rvcihjb250ZXh0SUQ6IG51bWJlcikge1xyXG4vLyAgICAgdGhpcy5fY29udGV4dElkID0gY29udGV4dElEO1xyXG4vLyAgICAgdGhpcy5fZmlsZU5hbWUgPSB0aGlzLkJ1aWxkRmlsZU5hbWUoKTtcclxuLy8gICAgIHRoaXMuT3BlbkZvcldyaXRlKCk7XHJcbi8vICAgfVxyXG4vL1xyXG4vLyAgIFdyaXRlKGJ1ZmZlcjogc3RyaW5nKTogdm9pZCB7XHJcbi8vICAgICB0cnkge1xyXG4vLyAgICAgICBsZXQgZmxhZzogYm9vbGVhbiA9ICF0aGlzLl9mYWlsZWQ7XHJcbi8vICAgICAgIGlmICghZmxhZykge1xyXG4vLyAgICAgICAgIHRocm93IG5ldyBJT0V4Y2VwdGlvbihcIkNsaWVudExvZ1NlcXVlbmNlIDogTG9naW5nIGNsaWVudCBzZXF1ZW5jZSBpcyBkZWFjdGl2YXRlZFwiKTtcclxuLy8gICAgICAgfVxyXG4vLyAgICAgICBsZXQgZmxhZzI6IGJvb2xlYW4gPSB0aGlzLk9wZW5Gb3JXcml0ZSgpO1xyXG4vLyAgICAgICBpZiAoZmxhZzIpIHtcclxuLy8gICAgICAgICB0aGlzLl9jbGllbnRMb2dPcy5Xcml0ZShidWZmZXIpO1xyXG4vLyAgICAgICAgIHRoaXMuX2NsaWVudExvZ09zLkNsb3NlKCk7XHJcbi8vICAgICAgICAgdGhpcy5fY2xpZW50TG9nT3MgPSBudWxsO1xyXG4vLyAgICAgICAgIHRoaXMuT3BlbkZvcldyaXRlKCk7XHJcbi8vICAgICAgIH1cclxuLy8gICAgIH1cclxuLy8gICAgIGNhdGNoIChleCkge1xyXG4vLyAgICAgICBpZiAoZXggaW5zdGFuY2VvZiBJT0V4Y2VwdGlvbikge1xyXG4vLyAgICAgICAgIExvZ2dlci5JbnN0YW5jZS5Xcml0ZURldlRvTG9nKGV4Lk1lc3NhZ2UpO1xyXG4vLyAgICAgICAgIE1pc2MuV3JpdGVTdGFja1RyYWNlKGV4LCBOQ29uc29sZS5FcnJvcik7XHJcbi8vICAgICAgIH1cclxuLy8gICAgICAgZWxzZVxyXG4vLyAgICAgICAgIHRocm93IGV4O1xyXG4vLyAgICAgfVxyXG4vLyAgIH1cclxuLy9cclxuLy8gICBSZWFkKCk6IHN0cmluZyB7XHJcbi8vICAgICBsZXQgcmVzdWx0OiBzdHJpbmcgPSBudWxsO1xyXG4vLyAgICAgdHJ5IHtcclxuLy8gICAgICAgbGV0IGZsYWc6IGJvb2xlYW4gPSAhdGhpcy5fZmFpbGVkO1xyXG4vLyAgICAgICBpZiAoIWZsYWcpIHtcclxuLy8gICAgICAgICB0aHJvdyBuZXcgSU9FeGNlcHRpb24oXCJDbGllbnRMb2dTZXF1ZW5jZSA6IExvZ2luZyBjbGllbnQgc2VxdWVuY2UgaXMgZGVhY3RpdmF0ZWRcIik7XHJcbi8vICAgICAgIH1cclxuLy8gICAgICAgdGhpcy5fY2xpZW50TG9nT3MuQ2xvc2UoKTtcclxuLy8gICAgICAgdGhpcy5fY2xpZW50TG9nT3MgPSBudWxsO1xyXG4vLyAgICAgICByZXN1bHQgPSBIYW5kbGVGaWxlcy5yZWFkVG9TdHJpbmcodGhpcy5fZmlsZU5hbWUsIEVuY29kaW5nLkRlZmF1bHQpO1xyXG4vLyAgICAgICB0aGlzLk9wZW5Gb3JXcml0ZSgpO1xyXG4vLyAgICAgfVxyXG4vLyAgICAgY2F0Y2ggKGV4KSB7XHJcbi8vICAgICAgIGlmIChleCBpbnN0YW5jZW9mIElPRXhjZXB0aW9uKSB7XHJcbi8vICAgICAgICAgTG9nZ2VyLkluc3RhbmNlLldyaXRlRGV2VG9Mb2coZXguTWVzc2FnZSk7XHJcbi8vICAgICAgICAgTWlzYy5Xcml0ZVN0YWNrVHJhY2UoZXgsIE5Db25zb2xlLkVycm9yKTtcclxuLy8gICAgICAgfVxyXG4vLyAgICAgICBlbHNlXHJcbi8vICAgICAgICAgdGhyb3cgZXg7XHJcbi8vICAgICB9XHJcbi8vICAgICByZXR1cm4gcmVzdWx0O1xyXG4vLyAgIH1cclxuLy9cclxuLy8gICBSZXNldCgpOiB2b2lkIHtcclxuLy8gICAgIHRyeSB7XHJcbi8vICAgICAgIGxldCBmbGFnOiBib29sZWFuID0gIXRoaXMuX2ZhaWxlZDtcclxuLy8gICAgICAgaWYgKCFmbGFnKSB7XHJcbi8vICAgICAgICAgdGhyb3cgbmV3IElPRXhjZXB0aW9uKFwiQ2xpZW50TG9nU2VxdWVuY2UgOiBMb2dpbmcgY2xpZW50IHNlcXVlbmNlIGlzIGRlYWN0aXZhdGVkXCIpO1xyXG4vLyAgICAgICB9XHJcbi8vICAgICAgIHRoaXMuX2NsaWVudExvZ09zLkNsb3NlKCk7XHJcbi8vICAgICAgIHRoaXMuX2NsaWVudExvZ09zID0gbnVsbDtcclxuLy8gICAgICAgSGFuZGxlRmlsZXMuZGVsZXRlRmlsZSh0aGlzLl9maWxlTmFtZSk7XHJcbi8vICAgICB9XHJcbi8vICAgICBjYXRjaCAoZXgpIHtcclxuLy8gICAgICAgaWYgKGV4IGluc3RhbmNlb2YgSU9FeGNlcHRpb24pIHtcclxuLy8gICAgICAgICBMb2dnZXIuSW5zdGFuY2UuV3JpdGVFeGNlcHRpb25Ub0xvZyhleCk7XHJcbi8vICAgICAgIH1cclxuLy8gICAgICAgZWxzZVxyXG4vLyAgICAgICAgIHRocm93IGV4O1xyXG4vLyAgICAgfVxyXG4vLyAgIH1cclxuLy9cclxuLy8gICBzdGF0aWMgRXhpc3RpbmdMb2dzRm91bmQoKTogYm9vbGVhbiB7XHJcbi8vICAgICBsZXQgcmVzdWx0OiBib29sZWFuID0gZmFsc2U7XHJcbi8vICAgICBDbGllbnRMb2dBY2N1bXVsYXRvci5CdWlsZGV4aXN0aW5nTG9nTGlzdCgpO1xyXG4vLyAgICAgbGV0IGZsYWc6IGJvb2xlYW4gPSBDbGllbnRMb2dBY2N1bXVsYXRvci5fZXhpc3RpbmdMb2dOYW1lcyAhPT0gbnVsbCAmJiBDbGllbnRMb2dBY2N1bXVsYXRvci5fZXhpc3RpbmdMb2dOYW1lcy5Db3VudCA+IDA7XHJcbi8vICAgICBpZiAoZmxhZykge1xyXG4vLyAgICAgICByZXN1bHQgPSB0cnVlO1xyXG4vLyAgICAgfVxyXG4vLyAgICAgcmV0dXJuIHJlc3VsdDtcclxuLy8gICB9XHJcbi8vXHJcbi8vICAgc3RhdGljIEV4aXN0aW5nTG9nSXRlcmF0b3IoKTogSUVudW1lcmF0b3I8c3RyaW5nPiB7XHJcbi8vICAgICByZXR1cm4gQ2xpZW50TG9nQWNjdW11bGF0b3IuX2V4aXN0aW5nTG9nTmFtZXMuR2V0RW51bWVyYXRvcigpO1xyXG4vLyAgIH1cclxuLy9cclxuLy8gICBzdGF0aWMgQnVpbGRMb2dIZWFkZXJMaW5lKGxvZ05hbWU6IHN0cmluZyk6IHN0cmluZyB7XHJcbi8vICAgICBsZXQgc3RyaW5nQnVpbGRlcjogU3RyaW5nQnVpbGRlciA9IG5ldyBTdHJpbmdCdWlsZGVyKFwiQ2xpZW50IGxvZyBmaWxlXCIpO1xyXG4vLyAgICAgbGV0IHN0cjogc3RyaW5nID0gTlN0cmluZy5TdWJzdHJpbmcobG9nTmFtZSwgbG9nTmFtZS5MYXN0SW5kZXhPZihOTnVtYmVyLlRvU3RyaW5nKFBhdGguRGlyZWN0b3J5U2VwYXJhdG9yQ2hhcikgKyBcIkNTXCIpICsgMywgbG9nTmFtZS5MYXN0SW5kZXhPZihcIi5sb2dcIikgLSAobG9nTmFtZS5MYXN0SW5kZXhPZihOTnVtYmVyLlRvU3RyaW5nKFBhdGguRGlyZWN0b3J5U2VwYXJhdG9yQ2hhcikgKyBcIkNTXCIpICsgMykpO1xyXG4vLyAgICAgc3RyaW5nQnVpbGRlci5BcHBlbmQoXCIgKENvbnRleHQgOiBcIik7XHJcbi8vICAgICBzdHJpbmdCdWlsZGVyLkFwcGVuZChzdHIgKyBcIiApIFwiKTtcclxuLy8gICAgIHJldHVybiBzdHJpbmdCdWlsZGVyLlRvU3RyaW5nKCk7XHJcbi8vICAgfVxyXG4vL1xyXG4vLyAgIEVtcHR5KCk6IGJvb2xlYW4ge1xyXG4vLyAgICAgcmV0dXJuIHRoaXMuX2ZhaWxlZCB8fCAhSGFuZGxlRmlsZXMuaXNFeGlzdHModGhpcy5fZmlsZU5hbWUpIHx8IEhhbmRsZUZpbGVzLmdldEZpbGVTaXplKHRoaXMuX2ZpbGVOYW1lKSA9PT0gMDtcclxuLy8gICB9XHJcbi8vXHJcbi8vICAgSXNGYWlsZWQoKTogYm9vbGVhbiB7XHJcbi8vICAgICByZXR1cm4gdGhpcy5fZmFpbGVkO1xyXG4vLyAgIH1cclxuLy9cclxuLy8gICBwcml2YXRlIHN0YXRpYyBCdWlsZGV4aXN0aW5nTG9nTGlzdCgpOiB2b2lkIHtcclxuLy8gICAgIGxldCBmbGFnOiBib29sZWFuID0gQ2xpZW50TG9nQWNjdW11bGF0b3IuX2V4aXN0aW5nTG9nTmFtZXMgIT09IG51bGwgJiYgQ2xpZW50TG9nQWNjdW11bGF0b3IuX2V4aXN0aW5nTG9nTmFtZXMuQ291bnQgPT09IDA7XHJcbi8vICAgICBpZiAoZmxhZykge1xyXG4vLyAgICAgICBsZXQgcGF0aDogc3RyaW5nID0gXCJcIjtcclxuLy8gICAgICAgQ2xpZW50TG9nQWNjdW11bGF0b3IuX2V4aXN0aW5nTG9nTmFtZXMuQWRkUmFuZ2UoTkFycmF5LlRvRW51bWVyYWJsZShEaXJlY3RvcnkuR2V0RmlsZXMocGF0aCwgXCJDUyouTE9HXCIpKSk7XHJcbi8vICAgICB9XHJcbi8vICAgfVxyXG4vL1xyXG4vLyAgIHByaXZhdGUgT3BlbkZvcldyaXRlKCk6IGJvb2xlYW4ge1xyXG4vLyAgICAgbGV0IGZsYWc6IGJvb2xlYW4gPSB0aGlzLl9jbGllbnRMb2dPcyA9PT0gbnVsbDtcclxuLy8gICAgIGlmIChmbGFnKSB7XHJcbi8vICAgICAgIHRyeSB7XHJcbi8vICAgICAgICAgdGhpcy5fY2xpZW50TG9nT3MgPSBuZXcgU3RyZWFtV3JpdGVyKHRoaXMuX2ZpbGVOYW1lLCB0cnVlLCBFbmNvZGluZy5EZWZhdWx0KTtcclxuLy8gICAgICAgICB0aGlzLl9mYWlsZWQgPSBmYWxzZTtcclxuLy8gICAgICAgfVxyXG4vLyAgICAgICBjYXRjaCAoZXgpIHtcclxuLy8gICAgICAgICBpZiAoZXggaW5zdGFuY2VvZiBJT0V4Y2VwdGlvbikge1xyXG4vLyAgICAgICAgICAgTG9nZ2VyLkluc3RhbmNlLldyaXRlRGV2VG9Mb2coXCJDbGllbnRMb2dTZXF1ZW5jZXMgOiBcIiArIGV4Lk1lc3NhZ2UpO1xyXG4vLyAgICAgICAgICAgdGhpcy5fZmFpbGVkID0gdHJ1ZTtcclxuLy8gICAgICAgICAgIHRoaXMuX2NsaWVudExvZ09zID0gbnVsbDtcclxuLy8gICAgICAgICAgIHRoaXMuX2NvbnRleHRJZCA9IC0xO1xyXG4vLyAgICAgICAgICAgdGhpcy5fZmlsZU5hbWUgPSBudWxsO1xyXG4vLyAgICAgICAgIH1cclxuLy8gICAgICAgICBlbHNlXHJcbi8vICAgICAgICAgICB0aHJvdyBleDtcclxuLy8gICAgICAgfVxyXG4vLyAgICAgfVxyXG4vLyAgICAgcmV0dXJuICF0aGlzLl9mYWlsZWQ7XHJcbi8vICAgfVxyXG4vL1xyXG4vLyAgIHByaXZhdGUgQnVpbGRGaWxlTmFtZSgpOiBzdHJpbmcge1xyXG4vLyAgICAgcmV0dXJuIFwiXCI7XHJcbi8vICAgfVxyXG4vLyB9XHJcbiJdfQ==