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