@cartanova/qgrid-cli 2.4.8 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ko.md +18 -11
- package/README.md +18 -11
- package/bundle/.env +0 -0
- package/bundle/dist/_virtual/{_@oxc-project_runtime@0.122.0/helpers → _@oxc-project_runtime@0.140.0/helpers/esm}/decorate.js +2 -2
- package/bundle/dist/_virtual/{_@oxc-project_runtime@0.122.0/helpers → _@oxc-project_runtime@0.140.0/helpers/esm}/decorateMetadata.js +2 -2
- package/bundle/dist/_virtual/_rolldown/runtime.js +2 -3
- package/bundle/dist/application/monit/log-buffer.js +3 -2
- package/bundle/dist/application/monit/monit.frame.js +5 -6
- package/bundle/dist/application/monit/monit.types.js +1 -2
- package/bundle/dist/application/qgrid/conv-routing.js +1 -2
- package/bundle/dist/application/qgrid/oauth.js +1 -2
- package/bundle/dist/application/qgrid/qgrid-image-generation.js +1 -2
- package/bundle/dist/application/qgrid/qgrid-response-format.js +1 -2
- package/bundle/dist/application/qgrid/qgrid-run-lifecycle.js +76 -47
- package/bundle/dist/application/qgrid/qgrid.dispatcher.js +1 -2
- package/bundle/dist/application/qgrid/qgrid.frame.js +73 -97
- package/bundle/dist/application/qgrid/qgrid.types.js +11 -10
- package/bundle/dist/application/qgrid/token-subscriber.js +3 -2
- package/bundle/dist/application/qgrid/token-trigger-setup.js +1 -2
- package/bundle/dist/application/qgrid/tool-emulation.js +1 -2
- package/bundle/dist/application/queries.generated.js +1 -2
- package/bundle/dist/application/request-log/request-log.model.js +116 -47
- package/bundle/dist/application/request-log/request-log.types.js +1 -2
- package/bundle/dist/application/request-log-step/request-log-step.model.js +3 -4
- package/bundle/dist/application/request-log-step/request-log-step.types.js +1 -2
- package/bundle/dist/application/sonamu.generated.js +14 -15
- package/bundle/dist/application/sonamu.generated.sso.js +1 -2
- package/bundle/dist/application/token/token.model.js +3 -4
- package/bundle/dist/application/token/token.types.js +1 -2
- package/bundle/dist/codex-protocol/AbsolutePathBuf.js +0 -1
- package/bundle/dist/codex-protocol/AgentPath.js +0 -1
- package/bundle/dist/codex-protocol/ApplyPatchApprovalParams.js +0 -1
- package/bundle/dist/codex-protocol/ApplyPatchApprovalResponse.js +0 -1
- package/bundle/dist/codex-protocol/AuthMode.js +0 -1
- package/bundle/dist/codex-protocol/ClientInfo.js +0 -1
- package/bundle/dist/codex-protocol/ClientNotification.js +0 -1
- package/bundle/dist/codex-protocol/ClientRequest.js +0 -1
- package/bundle/dist/codex-protocol/CollaborationMode.js +0 -1
- package/bundle/dist/codex-protocol/ContentItem.js +0 -1
- package/bundle/dist/codex-protocol/ConversationGitInfo.js +0 -1
- package/bundle/dist/codex-protocol/ConversationSummary.js +0 -1
- package/bundle/dist/codex-protocol/ExecCommandApprovalParams.js +0 -1
- package/bundle/dist/codex-protocol/ExecCommandApprovalResponse.js +0 -1
- package/bundle/dist/codex-protocol/ExecPolicyAmendment.js +0 -1
- package/bundle/dist/codex-protocol/FileChange.js +0 -1
- package/bundle/dist/codex-protocol/ForcedLoginMethod.js +0 -1
- package/bundle/dist/codex-protocol/FunctionCallOutputBody.js +0 -1
- package/bundle/dist/codex-protocol/FunctionCallOutputContentItem.js +0 -1
- package/bundle/dist/codex-protocol/FuzzyFileSearchMatchType.js +0 -1
- package/bundle/dist/codex-protocol/FuzzyFileSearchParams.js +0 -1
- package/bundle/dist/codex-protocol/FuzzyFileSearchResponse.js +0 -1
- package/bundle/dist/codex-protocol/FuzzyFileSearchResult.js +0 -1
- package/bundle/dist/codex-protocol/FuzzyFileSearchSessionCompletedNotification.js +0 -1
- package/bundle/dist/codex-protocol/FuzzyFileSearchSessionUpdatedNotification.js +0 -1
- package/bundle/dist/codex-protocol/GetAuthStatusParams.js +0 -1
- package/bundle/dist/codex-protocol/GetAuthStatusResponse.js +0 -1
- package/bundle/dist/codex-protocol/GetConversationSummaryParams.js +0 -1
- package/bundle/dist/codex-protocol/GetConversationSummaryResponse.js +0 -1
- package/bundle/dist/codex-protocol/GitDiffToRemoteParams.js +0 -1
- package/bundle/dist/codex-protocol/GitDiffToRemoteResponse.js +0 -1
- package/bundle/dist/codex-protocol/GitSha.js +0 -1
- package/bundle/dist/codex-protocol/ImageDetail.js +0 -1
- package/bundle/dist/codex-protocol/InitializeCapabilities.js +0 -1
- package/bundle/dist/codex-protocol/InitializeParams.js +0 -1
- package/bundle/dist/codex-protocol/InitializeResponse.js +0 -1
- package/bundle/dist/codex-protocol/InputModality.js +0 -1
- package/bundle/dist/codex-protocol/InternalSessionSource.js +0 -1
- package/bundle/dist/codex-protocol/LocalShellAction.js +0 -1
- package/bundle/dist/codex-protocol/LocalShellExecAction.js +0 -1
- package/bundle/dist/codex-protocol/LocalShellStatus.js +0 -1
- package/bundle/dist/codex-protocol/MessagePhase.js +0 -1
- package/bundle/dist/codex-protocol/ModeKind.js +0 -1
- package/bundle/dist/codex-protocol/NetworkPolicyAmendment.js +0 -1
- package/bundle/dist/codex-protocol/NetworkPolicyRuleAction.js +0 -1
- package/bundle/dist/codex-protocol/ParsedCommand.js +0 -1
- package/bundle/dist/codex-protocol/Personality.js +0 -1
- package/bundle/dist/codex-protocol/PlanType.js +0 -1
- package/bundle/dist/codex-protocol/RealtimeConversationVersion.js +0 -1
- package/bundle/dist/codex-protocol/RealtimeOutputModality.js +0 -1
- package/bundle/dist/codex-protocol/RealtimeVoice.js +0 -1
- package/bundle/dist/codex-protocol/RealtimeVoicesList.js +0 -1
- package/bundle/dist/codex-protocol/ReasoningEffort.js +0 -1
- package/bundle/dist/codex-protocol/ReasoningItemContent.js +0 -1
- package/bundle/dist/codex-protocol/ReasoningItemReasoningSummary.js +0 -1
- package/bundle/dist/codex-protocol/ReasoningSummary.js +0 -1
- package/bundle/dist/codex-protocol/RequestId.js +0 -1
- package/bundle/dist/codex-protocol/Resource.js +0 -1
- package/bundle/dist/codex-protocol/ResourceContent.js +0 -1
- package/bundle/dist/codex-protocol/ResourceTemplate.js +0 -1
- package/bundle/dist/codex-protocol/ResponseItem.js +0 -1
- package/bundle/dist/codex-protocol/ReviewDecision.js +0 -1
- package/bundle/dist/codex-protocol/ServerNotification.js +0 -1
- package/bundle/dist/codex-protocol/ServerRequest.js +0 -1
- package/bundle/dist/codex-protocol/SessionSource.js +0 -1
- package/bundle/dist/codex-protocol/Settings.js +0 -1
- package/bundle/dist/codex-protocol/SubAgentSource.js +0 -1
- package/bundle/dist/codex-protocol/ThreadId.js +0 -1
- package/bundle/dist/codex-protocol/ThreadMemoryMode.js +0 -1
- package/bundle/dist/codex-protocol/Tool.js +0 -1
- package/bundle/dist/codex-protocol/Verbosity.js +0 -1
- package/bundle/dist/codex-protocol/WebSearchAction.js +0 -1
- package/bundle/dist/codex-protocol/WebSearchContextSize.js +0 -1
- package/bundle/dist/codex-protocol/WebSearchLocation.js +0 -1
- package/bundle/dist/codex-protocol/WebSearchMode.js +0 -1
- package/bundle/dist/codex-protocol/WebSearchToolConfig.js +0 -1
- package/bundle/dist/codex-protocol/index.js +0 -1
- package/bundle/dist/codex-protocol/serde_json/JsonValue.js +0 -1
- package/bundle/dist/codex-protocol/v2/Account.js +0 -1
- package/bundle/dist/codex-protocol/v2/AccountLoginCompletedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/AccountRateLimitsUpdatedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/AccountUpdatedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ActivePermissionProfile.js +0 -1
- package/bundle/dist/codex-protocol/v2/ActivePermissionProfileModification.js +0 -1
- package/bundle/dist/codex-protocol/v2/AddCreditsNudgeCreditType.js +0 -1
- package/bundle/dist/codex-protocol/v2/AddCreditsNudgeEmailStatus.js +0 -1
- package/bundle/dist/codex-protocol/v2/AdditionalFileSystemPermissions.js +0 -1
- package/bundle/dist/codex-protocol/v2/AdditionalNetworkPermissions.js +0 -1
- package/bundle/dist/codex-protocol/v2/AdditionalPermissionProfile.js +0 -1
- package/bundle/dist/codex-protocol/v2/AgentMessageDeltaNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/AnalyticsConfig.js +0 -1
- package/bundle/dist/codex-protocol/v2/AppBranding.js +0 -1
- package/bundle/dist/codex-protocol/v2/AppInfo.js +0 -1
- package/bundle/dist/codex-protocol/v2/AppListUpdatedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/AppMetadata.js +0 -1
- package/bundle/dist/codex-protocol/v2/AppReview.js +0 -1
- package/bundle/dist/codex-protocol/v2/AppScreenshot.js +0 -1
- package/bundle/dist/codex-protocol/v2/AppSummary.js +0 -1
- package/bundle/dist/codex-protocol/v2/AppToolApproval.js +0 -1
- package/bundle/dist/codex-protocol/v2/AppToolsConfig.js +0 -1
- package/bundle/dist/codex-protocol/v2/ApprovalsReviewer.js +0 -1
- package/bundle/dist/codex-protocol/v2/AppsConfig.js +0 -1
- package/bundle/dist/codex-protocol/v2/AppsDefaultConfig.js +0 -1
- package/bundle/dist/codex-protocol/v2/AppsListParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/AppsListResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/AskForApproval.js +0 -1
- package/bundle/dist/codex-protocol/v2/AutoReviewDecisionSource.js +0 -1
- package/bundle/dist/codex-protocol/v2/ByteRange.js +0 -1
- package/bundle/dist/codex-protocol/v2/CancelLoginAccountParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/CancelLoginAccountResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/CancelLoginAccountStatus.js +0 -1
- package/bundle/dist/codex-protocol/v2/ChatgptAuthTokensRefreshParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ChatgptAuthTokensRefreshReason.js +0 -1
- package/bundle/dist/codex-protocol/v2/ChatgptAuthTokensRefreshResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/CodexErrorInfo.js +0 -1
- package/bundle/dist/codex-protocol/v2/CollabAgentState.js +0 -1
- package/bundle/dist/codex-protocol/v2/CollabAgentStatus.js +0 -1
- package/bundle/dist/codex-protocol/v2/CollabAgentTool.js +0 -1
- package/bundle/dist/codex-protocol/v2/CollabAgentToolCallStatus.js +0 -1
- package/bundle/dist/codex-protocol/v2/CollaborationModeMask.js +0 -1
- package/bundle/dist/codex-protocol/v2/CommandAction.js +0 -1
- package/bundle/dist/codex-protocol/v2/CommandExecOutputDeltaNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/CommandExecOutputStream.js +0 -1
- package/bundle/dist/codex-protocol/v2/CommandExecParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/CommandExecResizeParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/CommandExecResizeResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/CommandExecResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/CommandExecTerminalSize.js +0 -1
- package/bundle/dist/codex-protocol/v2/CommandExecTerminateParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/CommandExecTerminateResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/CommandExecWriteParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/CommandExecWriteResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/CommandExecutionApprovalDecision.js +0 -1
- package/bundle/dist/codex-protocol/v2/CommandExecutionOutputDeltaNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/CommandExecutionRequestApprovalParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/CommandExecutionRequestApprovalResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/CommandExecutionSource.js +0 -1
- package/bundle/dist/codex-protocol/v2/CommandExecutionStatus.js +0 -1
- package/bundle/dist/codex-protocol/v2/CommandMigration.js +0 -1
- package/bundle/dist/codex-protocol/v2/Config.js +0 -1
- package/bundle/dist/codex-protocol/v2/ConfigBatchWriteParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ConfigEdit.js +0 -1
- package/bundle/dist/codex-protocol/v2/ConfigLayer.js +0 -1
- package/bundle/dist/codex-protocol/v2/ConfigLayerMetadata.js +0 -1
- package/bundle/dist/codex-protocol/v2/ConfigLayerSource.js +0 -1
- package/bundle/dist/codex-protocol/v2/ConfigReadParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ConfigReadResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ConfigRequirements.js +0 -1
- package/bundle/dist/codex-protocol/v2/ConfigRequirementsReadResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ConfigValueWriteParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ConfigWarningNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ConfigWriteResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ConfiguredHookHandler.js +0 -1
- package/bundle/dist/codex-protocol/v2/ConfiguredHookMatcherGroup.js +0 -1
- package/bundle/dist/codex-protocol/v2/ContextCompactedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/CreditsSnapshot.js +0 -1
- package/bundle/dist/codex-protocol/v2/DeprecationNoticeNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/DynamicToolCallOutputContentItem.js +0 -1
- package/bundle/dist/codex-protocol/v2/DynamicToolCallParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/DynamicToolCallResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/DynamicToolCallStatus.js +0 -1
- package/bundle/dist/codex-protocol/v2/DynamicToolSpec.js +0 -1
- package/bundle/dist/codex-protocol/v2/ErrorNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ExecPolicyAmendment.js +0 -1
- package/bundle/dist/codex-protocol/v2/ExperimentalFeature.js +0 -1
- package/bundle/dist/codex-protocol/v2/ExperimentalFeatureEnablementSetParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ExperimentalFeatureEnablementSetResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ExperimentalFeatureListParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ExperimentalFeatureListResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ExperimentalFeatureStage.js +0 -1
- package/bundle/dist/codex-protocol/v2/ExternalAgentConfigDetectParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ExternalAgentConfigDetectResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ExternalAgentConfigImportCompletedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ExternalAgentConfigImportParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ExternalAgentConfigImportResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ExternalAgentConfigMigrationItem.js +0 -1
- package/bundle/dist/codex-protocol/v2/ExternalAgentConfigMigrationItemType.js +0 -1
- package/bundle/dist/codex-protocol/v2/FeedbackUploadParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/FeedbackUploadResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/FileChangeApprovalDecision.js +0 -1
- package/bundle/dist/codex-protocol/v2/FileChangeOutputDeltaNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/FileChangePatchUpdatedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/FileChangeRequestApprovalParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/FileChangeRequestApprovalResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/FileSystemAccessMode.js +0 -1
- package/bundle/dist/codex-protocol/v2/FileSystemPath.js +0 -1
- package/bundle/dist/codex-protocol/v2/FileSystemSandboxEntry.js +0 -1
- package/bundle/dist/codex-protocol/v2/FileSystemSpecialPath.js +0 -1
- package/bundle/dist/codex-protocol/v2/FileUpdateChange.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsChangedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsCopyParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsCopyResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsCreateDirectoryParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsCreateDirectoryResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsGetMetadataParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsGetMetadataResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsReadDirectoryEntry.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsReadDirectoryParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsReadDirectoryResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsReadFileParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsReadFileResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsRemoveParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsRemoveResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsUnwatchParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsUnwatchResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsWatchParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsWatchResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsWriteFileParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/FsWriteFileResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/GetAccountParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/GetAccountRateLimitsResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/GetAccountResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/GitInfo.js +0 -1
- package/bundle/dist/codex-protocol/v2/GrantedPermissionProfile.js +0 -1
- package/bundle/dist/codex-protocol/v2/GuardianApprovalReview.js +0 -1
- package/bundle/dist/codex-protocol/v2/GuardianApprovalReviewAction.js +0 -1
- package/bundle/dist/codex-protocol/v2/GuardianApprovalReviewStatus.js +0 -1
- package/bundle/dist/codex-protocol/v2/GuardianCommandSource.js +0 -1
- package/bundle/dist/codex-protocol/v2/GuardianRiskLevel.js +0 -1
- package/bundle/dist/codex-protocol/v2/GuardianUserAuthorization.js +0 -1
- package/bundle/dist/codex-protocol/v2/GuardianWarningNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/HookCompletedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/HookErrorInfo.js +0 -1
- package/bundle/dist/codex-protocol/v2/HookEventName.js +0 -1
- package/bundle/dist/codex-protocol/v2/HookExecutionMode.js +0 -1
- package/bundle/dist/codex-protocol/v2/HookHandlerType.js +0 -1
- package/bundle/dist/codex-protocol/v2/HookMetadata.js +0 -1
- package/bundle/dist/codex-protocol/v2/HookMigration.js +0 -1
- package/bundle/dist/codex-protocol/v2/HookOutputEntry.js +0 -1
- package/bundle/dist/codex-protocol/v2/HookOutputEntryKind.js +0 -1
- package/bundle/dist/codex-protocol/v2/HookPromptFragment.js +0 -1
- package/bundle/dist/codex-protocol/v2/HookRunStatus.js +0 -1
- package/bundle/dist/codex-protocol/v2/HookRunSummary.js +0 -1
- package/bundle/dist/codex-protocol/v2/HookScope.js +0 -1
- package/bundle/dist/codex-protocol/v2/HookSource.js +0 -1
- package/bundle/dist/codex-protocol/v2/HookStartedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/HookTrustStatus.js +0 -1
- package/bundle/dist/codex-protocol/v2/HooksListEntry.js +0 -1
- package/bundle/dist/codex-protocol/v2/HooksListParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/HooksListResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ItemCompletedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ItemGuardianApprovalReviewCompletedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ItemGuardianApprovalReviewStartedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ItemStartedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ListMcpServerStatusParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ListMcpServerStatusResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/LoginAccountParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/LoginAccountResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/LogoutAccountResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ManagedHooksRequirements.js +0 -1
- package/bundle/dist/codex-protocol/v2/MarketplaceAddParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/MarketplaceAddResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/MarketplaceInterface.js +0 -1
- package/bundle/dist/codex-protocol/v2/MarketplaceLoadErrorInfo.js +0 -1
- package/bundle/dist/codex-protocol/v2/MarketplaceRemoveParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/MarketplaceRemoveResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/MarketplaceUpgradeErrorInfo.js +0 -1
- package/bundle/dist/codex-protocol/v2/MarketplaceUpgradeParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/MarketplaceUpgradeResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpAuthStatus.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationArrayType.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationBooleanSchema.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationBooleanType.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationConstOption.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationEnumSchema.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationLegacyTitledEnumSchema.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationMultiSelectEnumSchema.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationNumberSchema.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationNumberType.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationObjectType.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationPrimitiveSchema.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationSchema.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationSingleSelectEnumSchema.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationStringFormat.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationStringSchema.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationStringType.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationTitledEnumItems.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationTitledMultiSelectEnumSchema.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationTitledSingleSelectEnumSchema.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationUntitledEnumItems.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationUntitledMultiSelectEnumSchema.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpElicitationUntitledSingleSelectEnumSchema.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpResourceReadParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpResourceReadResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpServerElicitationAction.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpServerElicitationRequestParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpServerElicitationRequestResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpServerMigration.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpServerOauthLoginCompletedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpServerOauthLoginParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpServerOauthLoginResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpServerRefreshResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpServerStartupState.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpServerStatus.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpServerStatusDetail.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpServerStatusUpdatedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpServerToolCallParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpServerToolCallResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpToolCallError.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpToolCallProgressNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpToolCallResult.js +0 -1
- package/bundle/dist/codex-protocol/v2/McpToolCallStatus.js +0 -1
- package/bundle/dist/codex-protocol/v2/MemoryCitation.js +0 -1
- package/bundle/dist/codex-protocol/v2/MemoryCitationEntry.js +0 -1
- package/bundle/dist/codex-protocol/v2/MergeStrategy.js +0 -1
- package/bundle/dist/codex-protocol/v2/MigrationDetails.js +0 -1
- package/bundle/dist/codex-protocol/v2/Model.js +0 -1
- package/bundle/dist/codex-protocol/v2/ModelAvailabilityNux.js +0 -1
- package/bundle/dist/codex-protocol/v2/ModelListParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ModelListResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ModelProviderCapabilitiesReadParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ModelProviderCapabilitiesReadResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ModelRerouteReason.js +0 -1
- package/bundle/dist/codex-protocol/v2/ModelReroutedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ModelServiceTier.js +0 -1
- package/bundle/dist/codex-protocol/v2/ModelUpgradeInfo.js +0 -1
- package/bundle/dist/codex-protocol/v2/ModelVerification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ModelVerificationNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/NetworkAccess.js +0 -1
- package/bundle/dist/codex-protocol/v2/NetworkApprovalContext.js +0 -1
- package/bundle/dist/codex-protocol/v2/NetworkApprovalProtocol.js +0 -1
- package/bundle/dist/codex-protocol/v2/NetworkDomainPermission.js +0 -1
- package/bundle/dist/codex-protocol/v2/NetworkPolicyAmendment.js +0 -1
- package/bundle/dist/codex-protocol/v2/NetworkPolicyRuleAction.js +0 -1
- package/bundle/dist/codex-protocol/v2/NetworkRequirements.js +0 -1
- package/bundle/dist/codex-protocol/v2/NetworkUnixSocketPermission.js +0 -1
- package/bundle/dist/codex-protocol/v2/NonSteerableTurnKind.js +0 -1
- package/bundle/dist/codex-protocol/v2/OverriddenMetadata.js +0 -1
- package/bundle/dist/codex-protocol/v2/PatchApplyStatus.js +0 -1
- package/bundle/dist/codex-protocol/v2/PatchChangeKind.js +0 -1
- package/bundle/dist/codex-protocol/v2/PermissionGrantScope.js +0 -1
- package/bundle/dist/codex-protocol/v2/PermissionProfile.js +0 -1
- package/bundle/dist/codex-protocol/v2/PermissionProfileFileSystemPermissions.js +0 -1
- package/bundle/dist/codex-protocol/v2/PermissionProfileModificationParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/PermissionProfileNetworkPermissions.js +0 -1
- package/bundle/dist/codex-protocol/v2/PermissionProfileSelectionParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/PermissionsRequestApprovalParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/PermissionsRequestApprovalResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/PlanDeltaNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginAuthPolicy.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginAvailability.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginDetail.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginHookSummary.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginInstallParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginInstallPolicy.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginInstallResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginInterface.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginListMarketplaceKind.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginListParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginListResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginMarketplaceEntry.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginReadParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginReadResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginShareContext.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginShareDeleteParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginShareDeleteResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginShareDiscoverability.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginShareListItem.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginShareListParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginShareListResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginSharePrincipal.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginSharePrincipalType.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginShareSaveParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginShareSaveResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginShareTarget.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginShareUpdateDiscoverability.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginShareUpdateTargetsParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginShareUpdateTargetsResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginSkillReadParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginSkillReadResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginSource.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginSummary.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginUninstallParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginUninstallResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/PluginsMigration.js +0 -1
- package/bundle/dist/codex-protocol/v2/ProcessExitedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ProcessOutputDeltaNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ProcessOutputStream.js +0 -1
- package/bundle/dist/codex-protocol/v2/ProcessTerminalSize.js +0 -1
- package/bundle/dist/codex-protocol/v2/ProfileV2.js +0 -1
- package/bundle/dist/codex-protocol/v2/RateLimitReachedType.js +0 -1
- package/bundle/dist/codex-protocol/v2/RateLimitSnapshot.js +0 -1
- package/bundle/dist/codex-protocol/v2/RateLimitWindow.js +0 -1
- package/bundle/dist/codex-protocol/v2/RawResponseItemCompletedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ReasoningEffortOption.js +0 -1
- package/bundle/dist/codex-protocol/v2/ReasoningSummaryPartAddedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ReasoningSummaryTextDeltaNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ReasoningTextDeltaNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/RemoteControlConnectionStatus.js +0 -1
- package/bundle/dist/codex-protocol/v2/RemoteControlStatusChangedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/RequestPermissionProfile.js +0 -1
- package/bundle/dist/codex-protocol/v2/ResidencyRequirement.js +0 -1
- package/bundle/dist/codex-protocol/v2/ReviewDelivery.js +0 -1
- package/bundle/dist/codex-protocol/v2/ReviewStartParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ReviewStartResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ReviewTarget.js +0 -1
- package/bundle/dist/codex-protocol/v2/SandboxMode.js +0 -1
- package/bundle/dist/codex-protocol/v2/SandboxPolicy.js +0 -1
- package/bundle/dist/codex-protocol/v2/SandboxWorkspaceWrite.js +0 -1
- package/bundle/dist/codex-protocol/v2/SendAddCreditsNudgeEmailParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/SendAddCreditsNudgeEmailResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ServerRequestResolvedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/SessionMigration.js +0 -1
- package/bundle/dist/codex-protocol/v2/SessionSource.js +0 -1
- package/bundle/dist/codex-protocol/v2/SkillDependencies.js +0 -1
- package/bundle/dist/codex-protocol/v2/SkillErrorInfo.js +0 -1
- package/bundle/dist/codex-protocol/v2/SkillInterface.js +0 -1
- package/bundle/dist/codex-protocol/v2/SkillMetadata.js +0 -1
- package/bundle/dist/codex-protocol/v2/SkillScope.js +0 -1
- package/bundle/dist/codex-protocol/v2/SkillSummary.js +0 -1
- package/bundle/dist/codex-protocol/v2/SkillToolDependency.js +0 -1
- package/bundle/dist/codex-protocol/v2/SkillsChangedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/SkillsConfigWriteParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/SkillsConfigWriteResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/SkillsListEntry.js +0 -1
- package/bundle/dist/codex-protocol/v2/SkillsListParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/SkillsListResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/SortDirection.js +0 -1
- package/bundle/dist/codex-protocol/v2/SubagentMigration.js +0 -1
- package/bundle/dist/codex-protocol/v2/TerminalInteractionNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/TextElement.js +0 -1
- package/bundle/dist/codex-protocol/v2/TextPosition.js +0 -1
- package/bundle/dist/codex-protocol/v2/TextRange.js +0 -1
- package/bundle/dist/codex-protocol/v2/Thread.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadActiveFlag.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadApproveGuardianDeniedActionParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadApproveGuardianDeniedActionResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadArchiveParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadArchiveResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadArchivedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadClosedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadCompactStartParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadCompactStartResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadForkParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadForkResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadGoal.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadGoalClearedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadGoalStatus.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadGoalUpdatedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadInjectItemsParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadInjectItemsResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadItem.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadListParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadListResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadLoadedListParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadLoadedListResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadMetadataGitInfoUpdateParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadMetadataUpdateParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadMetadataUpdateResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadNameUpdatedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadReadParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadReadResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadRealtimeAudioChunk.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadRealtimeClosedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadRealtimeErrorNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadRealtimeItemAddedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadRealtimeOutputAudioDeltaNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadRealtimeSdpNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadRealtimeStartTransport.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadRealtimeStartedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadRealtimeTranscriptDeltaNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadRealtimeTranscriptDoneNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadResumeParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadResumeResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadRollbackParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadRollbackResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadSetNameParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadSetNameResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadShellCommandParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadShellCommandResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadSortKey.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadSource.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadSourceKind.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadStartParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadStartResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadStartSource.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadStartedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadStatus.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadStatusChangedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadTokenUsage.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadTokenUsageUpdatedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadUnarchiveParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadUnarchiveResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadUnarchivedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadUnsubscribeParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadUnsubscribeResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ThreadUnsubscribeStatus.js +0 -1
- package/bundle/dist/codex-protocol/v2/TokenUsageBreakdown.js +0 -1
- package/bundle/dist/codex-protocol/v2/ToolRequestUserInputAnswer.js +0 -1
- package/bundle/dist/codex-protocol/v2/ToolRequestUserInputOption.js +0 -1
- package/bundle/dist/codex-protocol/v2/ToolRequestUserInputParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/ToolRequestUserInputQuestion.js +0 -1
- package/bundle/dist/codex-protocol/v2/ToolRequestUserInputResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/ToolsV2.js +0 -1
- package/bundle/dist/codex-protocol/v2/Turn.js +0 -1
- package/bundle/dist/codex-protocol/v2/TurnCompletedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/TurnDiffUpdatedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/TurnEnvironmentParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/TurnError.js +0 -1
- package/bundle/dist/codex-protocol/v2/TurnInterruptParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/TurnInterruptResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/TurnItemsView.js +0 -1
- package/bundle/dist/codex-protocol/v2/TurnPlanStep.js +0 -1
- package/bundle/dist/codex-protocol/v2/TurnPlanStepStatus.js +0 -1
- package/bundle/dist/codex-protocol/v2/TurnPlanUpdatedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/TurnStartParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/TurnStartResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/TurnStartedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/TurnStatus.js +0 -1
- package/bundle/dist/codex-protocol/v2/TurnSteerParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/TurnSteerResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/UserInput.js +0 -1
- package/bundle/dist/codex-protocol/v2/WarningNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/WebSearchAction.js +0 -1
- package/bundle/dist/codex-protocol/v2/WindowsSandboxReadiness.js +0 -1
- package/bundle/dist/codex-protocol/v2/WindowsSandboxReadinessResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/WindowsSandboxSetupCompletedNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/WindowsSandboxSetupMode.js +0 -1
- package/bundle/dist/codex-protocol/v2/WindowsSandboxSetupStartParams.js +0 -1
- package/bundle/dist/codex-protocol/v2/WindowsSandboxSetupStartResponse.js +0 -1
- package/bundle/dist/codex-protocol/v2/WindowsWorldWritableWarningNotification.js +0 -1
- package/bundle/dist/codex-protocol/v2/WriteStatus.js +0 -1
- package/bundle/dist/i18n/en.js +1 -2
- package/bundle/dist/i18n/ko.js +1 -2
- package/bundle/dist/i18n/sd.generated.js +54 -21
- package/bundle/dist/index.js +1 -2
- package/bundle/dist/migrations/20260410171405_create__request_logs.js +1 -2
- package/bundle/dist/migrations/20260410171406_create__tokens.js +1 -2
- package/bundle/dist/migrations/20260411120624_alter_tokens_alter2.js +1 -2
- package/bundle/dist/migrations/20260415113716_alter_tokens_add_ord.js +1 -2
- package/bundle/dist/migrations/20260415134649_alter_request_logs_alter1.js +1 -2
- package/bundle/dist/migrations/20260421223627_alter_request_logs_add1_alter1.js +1 -2
- package/bundle/dist/migrations/20260423180818_alter_request_logs_add1_alter1.js +1 -2
- package/bundle/dist/migrations/20260423182017_alter_request_logs_add2_drop1_alter1.js +1 -2
- package/bundle/dist/migrations/20260423183613_alter_request_logs_add1_alter1.js +1 -2
- package/bundle/dist/migrations/20260518145411_alter_tokens_add2_drop4_alter1.js +1 -2
- package/bundle/dist/migrations/20260520112853_alter_request_logs_add3_alter1.js +1 -2
- package/bundle/dist/migrations/20260520124755_alter_request_logs_drop1_alter1.js +1 -2
- package/bundle/dist/migrations/20260520130420_create__request_log_steps.js +1 -2
- package/bundle/dist/migrations/20260520134908_alter_request_logs_add2_alter8.js +1 -2
- package/bundle/dist/migrations/20260520134909_alter_request_log_steps_add1_alter3.js +1 -2
- package/bundle/dist/migrations/20260520141449_alter_request_logs_add1_alter1.js +1 -2
- package/bundle/dist/migrations/20260521134025_alter_request_log_steps_alter1.js +1 -2
- package/bundle/dist/migrations/20260521134026_alter_request_log_steps_foreigns.js +1 -2
- package/bundle/dist/migrations/20260522181721_alter_request_log_steps_add2_alter1.js +1 -2
- package/bundle/dist/migrations/20260630223950_alter_tokens_add1_alter1.js +1 -2
- package/bundle/dist/migrations/20260701105327_alter_request_logs_add1_alter1.js +1 -2
- package/bundle/dist/migrations/20260701105328_alter_request_log_steps_add1_alter1.js +1 -2
- package/bundle/dist/migrations/20260705140614_alter_request_logs_add1_alter1.js +1 -2
- package/bundle/dist/migrations/20260706120000_alter_request_logs_add_image_cost.js +1 -2
- package/bundle/dist/migrations/20260710090000_alter_tokens_add_weight.js +1 -2
- package/bundle/dist/migrations/20260718180824_alter_request_logs_add5_alter1.js +1 -2
- package/bundle/dist/migrations/20260718180825_alter_request_log_steps_add7_alter1.js +1 -2
- package/bundle/dist/migrations/20260722174410_alter_request_logs_alter3.js +17 -0
- package/bundle/dist/migrations/20260722174411_alter_request_log_steps_alter3.js +17 -0
- package/bundle/dist/node_modules/.pnpm/@jridgewell_sourcemap-codec@1.5.5/node_modules/@jridgewell/sourcemap-codec/dist/sourcemap-codec.js +255 -4
- package/bundle/dist/node_modules/.pnpm/@vitest_expect@4.1.10/node_modules/@vitest/expect/dist/index.js +1507 -0
- package/bundle/dist/node_modules/.pnpm/@vitest_pretty-format@4.1.10/node_modules/@vitest/pretty-format/dist/index.js +887 -0
- package/bundle/dist/node_modules/.pnpm/@vitest_runner@4.1.10/node_modules/@vitest/runner/dist/chunk-artifact.js +2756 -0
- package/bundle/dist/node_modules/.pnpm/@vitest_runner@4.1.10/node_modules/@vitest/runner/dist/index.js +8 -0
- package/bundle/dist/node_modules/.pnpm/@vitest_runner@4.1.10/node_modules/@vitest/runner/dist/utils.js +8 -0
- package/bundle/dist/node_modules/.pnpm/@vitest_snapshot@4.1.10/node_modules/@vitest/snapshot/dist/index.js +922 -0
- package/bundle/dist/node_modules/.pnpm/@vitest_spy@4.1.10/node_modules/@vitest/spy/dist/index.js +386 -0
- package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/chunk-pathe.M-eThtNZ.js +121 -0
- package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/constants.js +51 -0
- package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/diff.js +1317 -0
- package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/display.js +561 -0
- package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/error.js +40 -0
- package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/helpers.js +272 -0
- package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/offset.js +27 -0
- package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/serialize.js +77 -0
- package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/source-map.js +381 -0
- package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/timers.js +51 -0
- package/bundle/dist/node_modules/.pnpm/chai@6.2.2/node_modules/chai/index.js +103 -3
- package/bundle/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/branding.js +1 -1
- package/bundle/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/index.js +1 -1
- package/bundle/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/messages.js +1 -1
- package/bundle/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/overloads.js +1 -1
- package/bundle/dist/node_modules/.pnpm/expect-type@1.3.0/node_modules/expect-type/dist/utils.js +1 -1
- package/bundle/dist/node_modules/.pnpm/magic-string@0.30.21/node_modules/magic-string/dist/magic-string.es.js +2 -3
- package/bundle/dist/node_modules/.pnpm/pathe@2.0.3/node_modules/pathe/dist/index.js +4 -4
- package/bundle/dist/node_modules/.pnpm/pathe@2.0.3/node_modules/pathe/dist/shared/pathe.M-eThtNZ.js +2 -2
- package/bundle/dist/node_modules/.pnpm/tinybench@2.9.0/node_modules/tinybench/dist/index.js +18 -7
- package/bundle/dist/node_modules/.pnpm/tinyrainbow@3.1.0/node_modules/tinyrainbow/dist/index.js +18 -3
- package/bundle/dist/node_modules/.pnpm/vite@8.0.3_@emnapi_core@1.11.2_@emnapi_runtime@1.11.2_@types_node@25.0.7_esbuild@0.27.4_2519c2e8d8013fcbc7b443879bc9da6d/node_modules/vite/dist/node/module-runner.js +1265 -0
- package/bundle/dist/node_modules/.pnpm/{vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_msw@2.13.3_@types_node@25.0.7__ba64bc4dd2e2bdde58df187864f65496 → vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_ms_f9cfcfeddd63e656d4010c98521af26c}/node_modules/vitest/dist/chunks/_commonjsHelpers.D26ty3Ew.js +6 -3
- package/bundle/dist/node_modules/.pnpm/{vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_msw@2.13.3_@types_node@25.0.7__ba64bc4dd2e2bdde58df187864f65496 → vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_ms_f9cfcfeddd63e656d4010c98521af26c}/node_modules/vitest/dist/chunks/benchmark.CX_oY03V.js +8 -8
- package/bundle/dist/node_modules/.pnpm/{vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_msw@2.13.3_@types_node@25.0.7__ba64bc4dd2e2bdde58df187864f65496 → vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_ms_f9cfcfeddd63e656d4010c98521af26c}/node_modules/vitest/dist/chunks/evaluatedModules.Dg1zASAC.js +5 -5
- package/bundle/dist/node_modules/.pnpm/{vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_msw@2.13.3_@types_node@25.0.7__ba64bc4dd2e2bdde58df187864f65496 → vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_ms_f9cfcfeddd63e656d4010c98521af26c}/node_modules/vitest/dist/chunks/index.Chj8NDwU.js +3 -3
- package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_ms_f9cfcfeddd63e656d4010c98521af26c/node_modules/vitest/dist/chunks/index.DdgEv5B1.js +46 -0
- package/bundle/dist/node_modules/.pnpm/{vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_msw@2.13.3_@types_node@25.0.7__ba64bc4dd2e2bdde58df187864f65496 → vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_ms_f9cfcfeddd63e656d4010c98521af26c}/node_modules/vitest/dist/chunks/rpc.MzXet3jl.js +66 -6
- package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_ms_f9cfcfeddd63e656d4010c98521af26c/node_modules/vitest/dist/chunks/test.DNmyFkvJ.js +3044 -0
- package/bundle/dist/node_modules/.pnpm/{vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_msw@2.13.3_@types_node@25.0.7__ba64bc4dd2e2bdde58df187864f65496 → vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_ms_f9cfcfeddd63e656d4010c98521af26c}/node_modules/vitest/dist/chunks/utils.BX5Fg8C4.js +19 -4
- package/bundle/dist/node_modules/.pnpm/vitest@4.1.10_@opentelemetry_api@1.9.0_@types_node@25.0.7_@vitest_coverage-v8@4.1.10_ms_f9cfcfeddd63e656d4010c98521af26c/node_modules/vitest/dist/index.js +28 -0
- package/bundle/dist/server-bootstrap.js +1 -2
- package/bundle/dist/sonamu.config.js +11 -27
- package/bundle/dist/startup-migrations.js +1 -2
- package/bundle/dist/testing/fixture.js +1 -2
- package/bundle/dist/testing/global.js +6 -7
- package/bundle/dist/testing/setup-mocks.js +3 -4
- package/bundle/dist/testing/test-database-name.js +5 -8
- package/bundle/dist/utils/providers/anthropic/anthropic-constants.js +8 -8
- package/bundle/dist/utils/providers/anthropic/anthropic-dispatcher.js +1 -2
- package/bundle/dist/utils/providers/anthropic/anthropic-quota.js +1 -2
- package/bundle/dist/utils/providers/anthropic/claude-session.js +5 -7
- package/bundle/dist/utils/providers/anthropic/stream-json-adapter.js +1 -2
- package/bundle/dist/utils/providers/common/credentials.js +1 -2
- package/bundle/dist/utils/providers/common/model-cost.js +3 -3
- package/bundle/dist/utils/providers/common/provider-dispatcher.js +0 -1
- package/bundle/dist/utils/providers/common/smooth-weighted-round-robin.js +1 -2
- package/bundle/dist/utils/providers/common/strictifier.js +2 -2
- package/bundle/dist/utils/providers/common/token-picker.js +1 -2
- package/bundle/dist/utils/providers/common/ttft.js +1 -2
- package/bundle/dist/utils/providers/openai/codex-rpc.js +4 -2
- package/bundle/dist/utils/providers/openai/codex-worker.js +2 -2
- package/bundle/dist/utils/providers/openai/openai-constants.js +1 -2
- package/bundle/dist/utils/providers/openai/openai-dispatcher.js +103 -40
- package/bundle/dist/utils/providers/openai/openai-quota.js +1 -2
- package/bundle/dist/utils/providers/openai/openai-refresh.js +1 -2
- package/bundle/dist/utils/subset-loaders.js +1 -2
- package/bundle/src/application/monit/monit.frame.test.ts +2 -2
- package/bundle/src/application/monit/monit.frame.ts +2 -2
- package/bundle/src/application/qgrid/qgrid-run-lifecycle.test.ts +242 -8
- package/bundle/src/application/qgrid/qgrid-run-lifecycle.ts +97 -57
- package/bundle/src/application/qgrid/qgrid.frame.test.ts +400 -96
- package/bundle/src/application/qgrid/qgrid.frame.ts +85 -123
- package/bundle/src/application/qgrid/qgrid.types.ts +35 -27
- package/bundle/src/application/request-log/request-log.entity.json +2 -2
- package/bundle/src/application/request-log/request-log.model.test.ts +325 -21
- package/bundle/src/application/request-log/request-log.model.ts +233 -125
- package/bundle/src/application/request-log-step/request-log-step.entity.json +2 -2
- package/bundle/src/application/sonamu.generated.http +2 -2
- package/bundle/src/application/sonamu.generated.ts +13 -13
- package/bundle/src/i18n/sd.generated.ts +83 -14
- package/bundle/src/migrations/20260722174410_alter_request_logs_alter3.ts +19 -0
- package/bundle/src/migrations/20260722174411_alter_request_log_steps_alter3.ts +19 -0
- package/bundle/src/sonamu.config.ts +5 -23
- package/bundle/src/testing/global.ts +5 -5
- package/bundle/src/testing/test-database-name.test.ts +5 -5
- package/bundle/src/testing/test-database-name.ts +9 -8
- package/bundle/src/utils/providers/anthropic/anthropic-constants.test.ts +10 -6
- package/bundle/src/utils/providers/anthropic/anthropic-constants.ts +9 -5
- package/bundle/src/utils/providers/anthropic/claude-session.test.ts +18 -3
- package/bundle/src/utils/providers/anthropic/claude-session.ts +4 -4
- package/bundle/src/utils/providers/common/model-cost.test.ts +1 -0
- package/bundle/src/utils/providers/common/model-cost.ts +1 -0
- package/bundle/src/utils/providers/openai/openai-dispatcher.test.ts +440 -0
- package/bundle/src/utils/providers/openai/openai-dispatcher.ts +143 -45
- package/bundle/web-dist/client/assets/{index-CmuPjbCl.js → index-B8Qj0LZK.js} +3 -3
- package/bundle/web-dist/client/assets/logs-C7R8Hvyy.js +1 -0
- package/bundle/web-dist/client/assets/{monit-B5Edhvy-.js → monit-Cj2KSodR.js} +1 -1
- package/bundle/web-dist/client/assets/{routes-UPWScORY.js → routes-DI1rjqGY.js} +1 -1
- package/bundle/web-dist/client/assets/{sd.generated-DYuKzBY6.js → sd.generated-DbBC73_z.js} +1 -1
- package/bundle/web-dist/client/assets/{services.generated-D_SkWOo-.js → services.generated-BWyAypSh.js} +1 -1
- package/bundle/web-dist/client/assets/{show-pRp-eZIK.js → show-B9hDSX9F.js} +2 -2
- package/bundle/web-dist/client/assets/{tokens-DJlttxCM.js → tokens-xUexYz3u.js} +1 -1
- package/bundle/web-dist/client/assets/{use-update-token-mutation-CpFGLWUl.js → use-update-token-mutation-DeDBiZiM.js} +1 -1
- package/bundle/web-dist/client/index.html +2 -2
- package/bundle/web-dist/server/assets/{lazyRouteComponent-Cu6IkL8A.js → lazyRouteComponent-BCJr868T.js} +1 -1
- package/bundle/web-dist/server/assets/{logs-Dx2knN2T.js → logs-33YNafdW.js} +32 -11
- package/bundle/web-dist/server/assets/{monit-DU6PLatf.js → monit--9mVsjNU.js} +2 -2
- package/bundle/web-dist/server/assets/{routes-CTco1oJZ.js → routes-BK3Xh1UB.js} +3 -3
- package/bundle/web-dist/server/assets/{sd.generated-qzuRe35X.js → sd.generated-C3gcvRcU.js} +1 -0
- package/bundle/web-dist/server/assets/{services.generated-C8q1M41a.js → services.generated-B2_Auwvk.js} +1 -1
- package/bundle/web-dist/server/assets/{show-B3q8_GDh.js → show-Dxxxe608.js} +15 -9
- package/bundle/web-dist/server/assets/{tokens-Bvjn15h9.js → tokens-BWPVvdfi.js} +3 -3
- package/bundle/web-dist/server/assets/{use-update-token-mutation-BlZo6swF.js → use-update-token-mutation-CNBgTysy.js} +1 -1
- package/bundle/web-dist/server/entry-server.generated.js +23 -23
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +18 -12
- package/package.json +6 -6
- package/skills/qgrid/SKILL.md +4 -0
- package/skills/qgrid/references/ai-sdk-provider-contract.md +28 -2
- package/skills/qgrid/references/anthropic-claude-code-runtime.md +5 -4
- package/skills/qgrid/references/cli-env-and-server-boot.md +20 -8
- package/skills/qgrid/references/decision-rationale.md +4 -0
- package/skills/qgrid/references/docs-workflow.md +10 -0
- package/skills/qgrid/references/openai-codex-runtime.md +11 -3
- package/skills/qgrid/references/provider-runtime-differences.md +3 -3
- package/skills/qgrid/references/request-log-run-lifecycle.md +46 -28
- package/skills/qgrid/references/sonamu-api-web-flow.md +4 -0
- package/skills/qgrid/references/token-auth-quota-lifecycle.md +6 -0
- package/skills/qgrid/references/tool-calling-and-multiturn.md +8 -7
- package/skills/qgrid/references/verification-and-debugging.md +1 -1
- package/bundle/dist/node_modules/.pnpm/@vitest_expect@4.1.2/node_modules/@vitest/expect/dist/index.js +0 -1484
- package/bundle/dist/node_modules/.pnpm/@vitest_pretty-format@4.1.2/node_modules/@vitest/pretty-format/dist/index.js +0 -887
- package/bundle/dist/node_modules/.pnpm/@vitest_runner@4.1.2/node_modules/@vitest/runner/dist/chunk-artifact.js +0 -2746
- package/bundle/dist/node_modules/.pnpm/@vitest_runner@4.1.2/node_modules/@vitest/runner/dist/index.js +0 -8
- package/bundle/dist/node_modules/.pnpm/@vitest_runner@4.1.2/node_modules/@vitest/runner/dist/utils.js +0 -8
- package/bundle/dist/node_modules/.pnpm/@vitest_snapshot@4.1.2/node_modules/@vitest/snapshot/dist/index.js +0 -662
- package/bundle/dist/node_modules/.pnpm/@vitest_spy@4.1.2/node_modules/@vitest/spy/dist/index.js +0 -386
- package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/chunk-pathe.M-eThtNZ.js +0 -82
- package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/constants.js +0 -48
- package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/diff.js +0 -1307
- package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/display.js +0 -558
- package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/error.js +0 -33
- package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/helpers.js +0 -226
- package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/offset.js +0 -27
- package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/serialize.js +0 -77
- package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/source-map.js +0 -374
- package/bundle/dist/node_modules/.pnpm/@vitest_utils@4.1.2/node_modules/@vitest/utils/dist/timers.js +0 -37
- package/bundle/dist/node_modules/.pnpm/vite@8.0.3_@emnapi_core@1.9.2_@emnapi_runtime@1.9.2_@types_node@25.0.7_esbuild@0.27.4_jiti@2.6.1_sass@1.98.0_tsx@4.21.0/node_modules/vite/dist/node/module-runner.js +0 -426
- package/bundle/dist/node_modules/.pnpm/vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_msw@2.13.3_@types_node@25.0.7__ba64bc4dd2e2bdde58df187864f65496/node_modules/vitest/dist/chunks/index.DOa3dzoN.js +0 -16
- package/bundle/dist/node_modules/.pnpm/vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_msw@2.13.3_@types_node@25.0.7__ba64bc4dd2e2bdde58df187864f65496/node_modules/vitest/dist/chunks/test.p_J6dB8a.js +0 -2910
- package/bundle/dist/node_modules/.pnpm/vitest@4.1.2_@opentelemetry_api@1.9.0_@types_node@25.0.7_msw@2.13.3_@types_node@25.0.7__ba64bc4dd2e2bdde58df187864f65496/node_modules/vitest/dist/index.js +0 -28
- package/bundle/web-dist/client/assets/logs-cXOsDli3.js +0 -1
|
@@ -0,0 +1,3044 @@
|
|
|
1
|
+
import { assertTypes, createDefer, createSimpleStackTrace } from "../../../../../@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/helpers.js";
|
|
2
|
+
import { processError } from "../../../../../@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/error.js";
|
|
3
|
+
import { delay, getSafeTimers } from "../../../../../@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/timers.js";
|
|
4
|
+
import { parseSingleStack } from "../../../../../@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/source-map.js";
|
|
5
|
+
import { n as normalize } from "../../../../../pathe@2.0.3/node_modules/pathe/dist/shared/pathe.M-eThtNZ.js";
|
|
6
|
+
import "../../../../../pathe@2.0.3/node_modules/pathe/dist/index.js";
|
|
7
|
+
import { G as getNames, J as getTestName, K as getTests, Q as matchesTags, g as createTaskCollector, i as getCurrentSuite, j as getCurrentTest, k as getFn, l as getHooks, w as updateTask, y as createChainable } from "../../../../../@vitest_runner@4.1.10/node_modules/@vitest/runner/dist/chunk-artifact.js";
|
|
8
|
+
import "../../../../../@vitest_runner@4.1.10/node_modules/@vitest/runner/dist/index.js";
|
|
9
|
+
import "../../../../../@vitest_runner@4.1.10/node_modules/@vitest/runner/dist/utils.js";
|
|
10
|
+
import { g as getWorkerState, i as isChildProcess, r as resetModules, w as waitForImportsToResolve } from "./utils.BX5Fg8C4.js";
|
|
11
|
+
import { a as getBenchOptions, g as getBenchFn } from "./benchmark.CX_oY03V.js";
|
|
12
|
+
import { clearAllMocks, fn, isMockFunction, resetAllMocks, restoreAllMocks, spyOn } from "../../../../../@vitest_spy@4.1.10/node_modules/@vitest/spy/dist/index.js";
|
|
13
|
+
import { Assertion, assert as assert$1, expect, should as should$1, use, util as utils_exports } from "../../../../../chai@6.2.2/node_modules/chai/index.js";
|
|
14
|
+
import { ASYMMETRIC_MATCHERS_OBJECT, ChaiStyleAssertions, GLOBAL_EXPECT, JestAsymmetricMatchers, JestChaiExpect, JestExtend, addCustomEqualityTesters, createAssertionMessage, customMatchers, equals, getState, iterableEquality, recordAsyncExpect, setState, subsetEquality, wrapAssertion } from "../../../../../@vitest_expect@4.1.10/node_modules/@vitest/expect/dist/index.js";
|
|
15
|
+
import "../../../../../@vitest_utils@4.1.10/node_modules/@vitest/utils/dist/offset.js";
|
|
16
|
+
import { c as commonjsGlobal } from "./_commonjsHelpers.D26ty3Ew.js";
|
|
17
|
+
import { R as RealDate, b as resetDate, m as mockDate, r as rpc } from "./rpc.MzXet3jl.js";
|
|
18
|
+
import { SnapshotClient, addSerializer, stripSnapshotIndentation } from "../../../../../@vitest_snapshot@4.1.10/node_modules/@vitest/snapshot/dist/index.js";
|
|
19
|
+
//#region ../../node_modules/.pnpm/vitest@4.1.10_@opentelemetry+api@1.9.0_@types+node@25.0.7_@vitest+coverage-v8@4.1.10_ms_f9cfcfeddd63e656d4010c98521af26c/node_modules/vitest/dist/chunks/test.DNmyFkvJ.js
|
|
20
|
+
var fakeTimersSrc = {};
|
|
21
|
+
var global;
|
|
22
|
+
var hasRequiredGlobal;
|
|
23
|
+
function requireGlobal() {
|
|
24
|
+
if (hasRequiredGlobal) return global;
|
|
25
|
+
hasRequiredGlobal = 1;
|
|
26
|
+
/**
|
|
27
|
+
* A reference to the global object
|
|
28
|
+
* @type {object} globalObject
|
|
29
|
+
*/
|
|
30
|
+
var globalObject;
|
|
31
|
+
/* istanbul ignore else */
|
|
32
|
+
if (typeof commonjsGlobal !== "undefined") globalObject = commonjsGlobal;
|
|
33
|
+
else if (typeof window !== "undefined") globalObject = window;
|
|
34
|
+
else globalObject = self;
|
|
35
|
+
global = globalObject;
|
|
36
|
+
return global;
|
|
37
|
+
}
|
|
38
|
+
var throwsOnProto_1;
|
|
39
|
+
var hasRequiredThrowsOnProto;
|
|
40
|
+
function requireThrowsOnProto() {
|
|
41
|
+
if (hasRequiredThrowsOnProto) return throwsOnProto_1;
|
|
42
|
+
hasRequiredThrowsOnProto = 1;
|
|
43
|
+
/**
|
|
44
|
+
* Is true when the environment causes an error to be thrown for accessing the
|
|
45
|
+
* __proto__ property.
|
|
46
|
+
* This is necessary in order to support `node --disable-proto=throw`.
|
|
47
|
+
*
|
|
48
|
+
* See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto
|
|
49
|
+
* @type {boolean}
|
|
50
|
+
*/
|
|
51
|
+
let throwsOnProto;
|
|
52
|
+
try {
|
|
53
|
+
({}).__proto__;
|
|
54
|
+
throwsOnProto = false;
|
|
55
|
+
} catch (_) {
|
|
56
|
+
/* istanbul ignore next */
|
|
57
|
+
throwsOnProto = true;
|
|
58
|
+
}
|
|
59
|
+
throwsOnProto_1 = throwsOnProto;
|
|
60
|
+
return throwsOnProto_1;
|
|
61
|
+
}
|
|
62
|
+
var copyPrototypeMethods;
|
|
63
|
+
var hasRequiredCopyPrototypeMethods;
|
|
64
|
+
function requireCopyPrototypeMethods() {
|
|
65
|
+
if (hasRequiredCopyPrototypeMethods) return copyPrototypeMethods;
|
|
66
|
+
hasRequiredCopyPrototypeMethods = 1;
|
|
67
|
+
var call = Function.call;
|
|
68
|
+
var throwsOnProto = requireThrowsOnProto();
|
|
69
|
+
var disallowedProperties = [
|
|
70
|
+
"size",
|
|
71
|
+
"caller",
|
|
72
|
+
"callee",
|
|
73
|
+
"arguments"
|
|
74
|
+
];
|
|
75
|
+
/* istanbul ignore next */
|
|
76
|
+
if (throwsOnProto) disallowedProperties.push("__proto__");
|
|
77
|
+
copyPrototypeMethods = function copyPrototypeMethods(prototype) {
|
|
78
|
+
return Object.getOwnPropertyNames(prototype).reduce(function(result, name) {
|
|
79
|
+
if (disallowedProperties.includes(name)) return result;
|
|
80
|
+
if (typeof prototype[name] !== "function") return result;
|
|
81
|
+
result[name] = call.bind(prototype[name]);
|
|
82
|
+
return result;
|
|
83
|
+
}, Object.create(null));
|
|
84
|
+
};
|
|
85
|
+
return copyPrototypeMethods;
|
|
86
|
+
}
|
|
87
|
+
var array;
|
|
88
|
+
var hasRequiredArray;
|
|
89
|
+
function requireArray() {
|
|
90
|
+
if (hasRequiredArray) return array;
|
|
91
|
+
hasRequiredArray = 1;
|
|
92
|
+
array = requireCopyPrototypeMethods()(Array.prototype);
|
|
93
|
+
return array;
|
|
94
|
+
}
|
|
95
|
+
var calledInOrder_1;
|
|
96
|
+
var hasRequiredCalledInOrder;
|
|
97
|
+
function requireCalledInOrder() {
|
|
98
|
+
if (hasRequiredCalledInOrder) return calledInOrder_1;
|
|
99
|
+
hasRequiredCalledInOrder = 1;
|
|
100
|
+
var every = requireArray().every;
|
|
101
|
+
/**
|
|
102
|
+
* @private
|
|
103
|
+
*/
|
|
104
|
+
function hasCallsLeft(callMap, spy) {
|
|
105
|
+
if (callMap[spy.id] === void 0) callMap[spy.id] = 0;
|
|
106
|
+
return callMap[spy.id] < spy.callCount;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* @private
|
|
110
|
+
*/
|
|
111
|
+
function checkAdjacentCalls(callMap, spy, index, spies) {
|
|
112
|
+
var calledBeforeNext = true;
|
|
113
|
+
if (index !== spies.length - 1) calledBeforeNext = spy.calledBefore(spies[index + 1]);
|
|
114
|
+
if (hasCallsLeft(callMap, spy) && calledBeforeNext) {
|
|
115
|
+
callMap[spy.id] += 1;
|
|
116
|
+
return true;
|
|
117
|
+
}
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* A Sinon proxy object (fake, spy, stub)
|
|
122
|
+
* @typedef {object} SinonProxy
|
|
123
|
+
* @property {Function} calledBefore - A method that determines if this proxy was called before another one
|
|
124
|
+
* @property {string} id - Some id
|
|
125
|
+
* @property {number} callCount - Number of times this proxy has been called
|
|
126
|
+
*/
|
|
127
|
+
/**
|
|
128
|
+
* Returns true when the spies have been called in the order they were supplied in
|
|
129
|
+
* @param {SinonProxy[] | SinonProxy} spies An array of proxies, or several proxies as arguments
|
|
130
|
+
* @returns {boolean} true when spies are called in order, false otherwise
|
|
131
|
+
*/
|
|
132
|
+
function calledInOrder(spies) {
|
|
133
|
+
return every(arguments.length > 1 ? arguments : spies, checkAdjacentCalls.bind(null, {}));
|
|
134
|
+
}
|
|
135
|
+
calledInOrder_1 = calledInOrder;
|
|
136
|
+
return calledInOrder_1;
|
|
137
|
+
}
|
|
138
|
+
var className_1;
|
|
139
|
+
var hasRequiredClassName;
|
|
140
|
+
function requireClassName() {
|
|
141
|
+
if (hasRequiredClassName) return className_1;
|
|
142
|
+
hasRequiredClassName = 1;
|
|
143
|
+
/**
|
|
144
|
+
* Returns a display name for a value from a constructor
|
|
145
|
+
* @param {object} value A value to examine
|
|
146
|
+
* @returns {(string|null)} A string or null
|
|
147
|
+
*/
|
|
148
|
+
function className(value) {
|
|
149
|
+
return value.constructor && value.constructor.name || null;
|
|
150
|
+
}
|
|
151
|
+
className_1 = className;
|
|
152
|
+
return className_1;
|
|
153
|
+
}
|
|
154
|
+
var deprecated = {};
|
|
155
|
+
var hasRequiredDeprecated;
|
|
156
|
+
function requireDeprecated() {
|
|
157
|
+
if (hasRequiredDeprecated) return deprecated;
|
|
158
|
+
hasRequiredDeprecated = 1;
|
|
159
|
+
(function(exports$1) {
|
|
160
|
+
/**
|
|
161
|
+
* Returns a function that will invoke the supplied function and print a
|
|
162
|
+
* deprecation warning to the console each time it is called.
|
|
163
|
+
* @param {Function} func
|
|
164
|
+
* @param {string} msg
|
|
165
|
+
* @returns {Function}
|
|
166
|
+
*/
|
|
167
|
+
exports$1.wrap = function(func, msg) {
|
|
168
|
+
var wrapped = function() {
|
|
169
|
+
exports$1.printWarning(msg);
|
|
170
|
+
return func.apply(this, arguments);
|
|
171
|
+
};
|
|
172
|
+
if (func.prototype) wrapped.prototype = func.prototype;
|
|
173
|
+
return wrapped;
|
|
174
|
+
};
|
|
175
|
+
/**
|
|
176
|
+
* Returns a string which can be supplied to `wrap()` to notify the user that a
|
|
177
|
+
* particular part of the sinon API has been deprecated.
|
|
178
|
+
* @param {string} packageName
|
|
179
|
+
* @param {string} funcName
|
|
180
|
+
* @returns {string}
|
|
181
|
+
*/
|
|
182
|
+
exports$1.defaultMsg = function(packageName, funcName) {
|
|
183
|
+
return `${packageName}.${funcName} is deprecated and will be removed from the public API in a future version of ${packageName}.`;
|
|
184
|
+
};
|
|
185
|
+
/**
|
|
186
|
+
* Prints a warning on the console, when it exists
|
|
187
|
+
* @param {string} msg
|
|
188
|
+
* @returns {undefined}
|
|
189
|
+
*/
|
|
190
|
+
exports$1.printWarning = function(msg) {
|
|
191
|
+
/* istanbul ignore next */
|
|
192
|
+
if (typeof process === "object" && process.emitWarning) process.emitWarning(msg);
|
|
193
|
+
else if (console.info) console.info(msg);
|
|
194
|
+
else console.log(msg);
|
|
195
|
+
};
|
|
196
|
+
})(deprecated);
|
|
197
|
+
return deprecated;
|
|
198
|
+
}
|
|
199
|
+
var every;
|
|
200
|
+
var hasRequiredEvery;
|
|
201
|
+
function requireEvery() {
|
|
202
|
+
if (hasRequiredEvery) return every;
|
|
203
|
+
hasRequiredEvery = 1;
|
|
204
|
+
/**
|
|
205
|
+
* Returns true when fn returns true for all members of obj.
|
|
206
|
+
* This is an every implementation that works for all iterables
|
|
207
|
+
* @param {object} obj
|
|
208
|
+
* @param {Function} fn
|
|
209
|
+
* @returns {boolean}
|
|
210
|
+
*/
|
|
211
|
+
every = function every(obj, fn) {
|
|
212
|
+
var pass = true;
|
|
213
|
+
try {
|
|
214
|
+
obj.forEach(function() {
|
|
215
|
+
if (!fn.apply(this, arguments)) throw new Error();
|
|
216
|
+
});
|
|
217
|
+
} catch (e) {
|
|
218
|
+
pass = false;
|
|
219
|
+
}
|
|
220
|
+
return pass;
|
|
221
|
+
};
|
|
222
|
+
return every;
|
|
223
|
+
}
|
|
224
|
+
var functionName;
|
|
225
|
+
var hasRequiredFunctionName;
|
|
226
|
+
function requireFunctionName() {
|
|
227
|
+
if (hasRequiredFunctionName) return functionName;
|
|
228
|
+
hasRequiredFunctionName = 1;
|
|
229
|
+
/**
|
|
230
|
+
* Returns a display name for a function
|
|
231
|
+
* @param {Function} func
|
|
232
|
+
* @returns {string}
|
|
233
|
+
*/
|
|
234
|
+
functionName = function functionName(func) {
|
|
235
|
+
if (!func) return "";
|
|
236
|
+
try {
|
|
237
|
+
return func.displayName || func.name || (String(func).match(/function ([^\s(]+)/) || [])[1];
|
|
238
|
+
} catch (e) {
|
|
239
|
+
return "";
|
|
240
|
+
}
|
|
241
|
+
};
|
|
242
|
+
return functionName;
|
|
243
|
+
}
|
|
244
|
+
var orderByFirstCall_1;
|
|
245
|
+
var hasRequiredOrderByFirstCall;
|
|
246
|
+
function requireOrderByFirstCall() {
|
|
247
|
+
if (hasRequiredOrderByFirstCall) return orderByFirstCall_1;
|
|
248
|
+
hasRequiredOrderByFirstCall = 1;
|
|
249
|
+
var sort = requireArray().sort;
|
|
250
|
+
var slice = requireArray().slice;
|
|
251
|
+
/**
|
|
252
|
+
* @private
|
|
253
|
+
*/
|
|
254
|
+
function comparator(a, b) {
|
|
255
|
+
var aCall = a.getCall(0);
|
|
256
|
+
var bCall = b.getCall(0);
|
|
257
|
+
return (aCall && aCall.callId || -1) < (bCall && bCall.callId || -1) ? -1 : 1;
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* A Sinon proxy object (fake, spy, stub)
|
|
261
|
+
* @typedef {object} SinonProxy
|
|
262
|
+
* @property {Function} getCall - A method that can return the first call
|
|
263
|
+
*/
|
|
264
|
+
/**
|
|
265
|
+
* Sorts an array of SinonProxy instances (fake, spy, stub) by their first call
|
|
266
|
+
* @param {SinonProxy[] | SinonProxy} spies
|
|
267
|
+
* @returns {SinonProxy[]}
|
|
268
|
+
*/
|
|
269
|
+
function orderByFirstCall(spies) {
|
|
270
|
+
return sort(slice(spies), comparator);
|
|
271
|
+
}
|
|
272
|
+
orderByFirstCall_1 = orderByFirstCall;
|
|
273
|
+
return orderByFirstCall_1;
|
|
274
|
+
}
|
|
275
|
+
var _function;
|
|
276
|
+
var hasRequired_function;
|
|
277
|
+
function require_function() {
|
|
278
|
+
if (hasRequired_function) return _function;
|
|
279
|
+
hasRequired_function = 1;
|
|
280
|
+
_function = requireCopyPrototypeMethods()(Function.prototype);
|
|
281
|
+
return _function;
|
|
282
|
+
}
|
|
283
|
+
var map;
|
|
284
|
+
var hasRequiredMap;
|
|
285
|
+
function requireMap() {
|
|
286
|
+
if (hasRequiredMap) return map;
|
|
287
|
+
hasRequiredMap = 1;
|
|
288
|
+
map = requireCopyPrototypeMethods()(Map.prototype);
|
|
289
|
+
return map;
|
|
290
|
+
}
|
|
291
|
+
var object;
|
|
292
|
+
var hasRequiredObject;
|
|
293
|
+
function requireObject() {
|
|
294
|
+
if (hasRequiredObject) return object;
|
|
295
|
+
hasRequiredObject = 1;
|
|
296
|
+
object = requireCopyPrototypeMethods()(Object.prototype);
|
|
297
|
+
return object;
|
|
298
|
+
}
|
|
299
|
+
var set;
|
|
300
|
+
var hasRequiredSet;
|
|
301
|
+
function requireSet() {
|
|
302
|
+
if (hasRequiredSet) return set;
|
|
303
|
+
hasRequiredSet = 1;
|
|
304
|
+
set = requireCopyPrototypeMethods()(Set.prototype);
|
|
305
|
+
return set;
|
|
306
|
+
}
|
|
307
|
+
var string;
|
|
308
|
+
var hasRequiredString;
|
|
309
|
+
function requireString() {
|
|
310
|
+
if (hasRequiredString) return string;
|
|
311
|
+
hasRequiredString = 1;
|
|
312
|
+
string = requireCopyPrototypeMethods()(String.prototype);
|
|
313
|
+
return string;
|
|
314
|
+
}
|
|
315
|
+
var prototypes;
|
|
316
|
+
var hasRequiredPrototypes;
|
|
317
|
+
function requirePrototypes() {
|
|
318
|
+
if (hasRequiredPrototypes) return prototypes;
|
|
319
|
+
hasRequiredPrototypes = 1;
|
|
320
|
+
prototypes = {
|
|
321
|
+
array: requireArray(),
|
|
322
|
+
function: require_function(),
|
|
323
|
+
map: requireMap(),
|
|
324
|
+
object: requireObject(),
|
|
325
|
+
set: requireSet(),
|
|
326
|
+
string: requireString()
|
|
327
|
+
};
|
|
328
|
+
return prototypes;
|
|
329
|
+
}
|
|
330
|
+
var typeDetect$1 = { exports: {} };
|
|
331
|
+
var typeDetect = typeDetect$1.exports;
|
|
332
|
+
var hasRequiredTypeDetect;
|
|
333
|
+
function requireTypeDetect() {
|
|
334
|
+
if (hasRequiredTypeDetect) return typeDetect$1.exports;
|
|
335
|
+
hasRequiredTypeDetect = 1;
|
|
336
|
+
(function(module, exports$1) {
|
|
337
|
+
(function(global, factory) {
|
|
338
|
+
module.exports = factory();
|
|
339
|
+
})(typeDetect, (function() {
|
|
340
|
+
var promiseExists = typeof Promise === "function";
|
|
341
|
+
var globalObject = typeof self === "object" ? self : commonjsGlobal;
|
|
342
|
+
var symbolExists = typeof Symbol !== "undefined";
|
|
343
|
+
var mapExists = typeof Map !== "undefined";
|
|
344
|
+
var setExists = typeof Set !== "undefined";
|
|
345
|
+
var weakMapExists = typeof WeakMap !== "undefined";
|
|
346
|
+
var weakSetExists = typeof WeakSet !== "undefined";
|
|
347
|
+
var dataViewExists = typeof DataView !== "undefined";
|
|
348
|
+
var symbolIteratorExists = symbolExists && typeof Symbol.iterator !== "undefined";
|
|
349
|
+
var symbolToStringTagExists = symbolExists && typeof Symbol.toStringTag !== "undefined";
|
|
350
|
+
var setEntriesExists = setExists && typeof Set.prototype.entries === "function";
|
|
351
|
+
var mapEntriesExists = mapExists && typeof Map.prototype.entries === "function";
|
|
352
|
+
var setIteratorPrototype = setEntriesExists && Object.getPrototypeOf((/* @__PURE__ */ new Set()).entries());
|
|
353
|
+
var mapIteratorPrototype = mapEntriesExists && Object.getPrototypeOf((/* @__PURE__ */ new Map()).entries());
|
|
354
|
+
var arrayIteratorExists = symbolIteratorExists && typeof Array.prototype[Symbol.iterator] === "function";
|
|
355
|
+
var arrayIteratorPrototype = arrayIteratorExists && Object.getPrototypeOf([][Symbol.iterator]());
|
|
356
|
+
var stringIteratorExists = symbolIteratorExists && typeof String.prototype[Symbol.iterator] === "function";
|
|
357
|
+
var stringIteratorPrototype = stringIteratorExists && Object.getPrototypeOf(""[Symbol.iterator]());
|
|
358
|
+
var toStringLeftSliceLength = 8;
|
|
359
|
+
var toStringRightSliceLength = -1;
|
|
360
|
+
/**
|
|
361
|
+
* ### typeOf (obj)
|
|
362
|
+
*
|
|
363
|
+
* Uses `Object.prototype.toString` to determine the type of an object,
|
|
364
|
+
* normalising behaviour across engine versions & well optimised.
|
|
365
|
+
*
|
|
366
|
+
* @param {Mixed} object
|
|
367
|
+
* @return {String} object type
|
|
368
|
+
* @api public
|
|
369
|
+
*/
|
|
370
|
+
function typeDetect(obj) {
|
|
371
|
+
var typeofObj = typeof obj;
|
|
372
|
+
if (typeofObj !== "object") return typeofObj;
|
|
373
|
+
if (obj === null) return "null";
|
|
374
|
+
if (obj === globalObject) return "global";
|
|
375
|
+
if (Array.isArray(obj) && (symbolToStringTagExists === false || !(Symbol.toStringTag in obj))) return "Array";
|
|
376
|
+
if (typeof window === "object" && window !== null) {
|
|
377
|
+
if (typeof window.location === "object" && obj === window.location) return "Location";
|
|
378
|
+
if (typeof window.document === "object" && obj === window.document) return "Document";
|
|
379
|
+
if (typeof window.navigator === "object") {
|
|
380
|
+
if (typeof window.navigator.mimeTypes === "object" && obj === window.navigator.mimeTypes) return "MimeTypeArray";
|
|
381
|
+
if (typeof window.navigator.plugins === "object" && obj === window.navigator.plugins) return "PluginArray";
|
|
382
|
+
}
|
|
383
|
+
if ((typeof window.HTMLElement === "function" || typeof window.HTMLElement === "object") && obj instanceof window.HTMLElement) {
|
|
384
|
+
if (obj.tagName === "BLOCKQUOTE") return "HTMLQuoteElement";
|
|
385
|
+
if (obj.tagName === "TD") return "HTMLTableDataCellElement";
|
|
386
|
+
if (obj.tagName === "TH") return "HTMLTableHeaderCellElement";
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
var stringTag = symbolToStringTagExists && obj[Symbol.toStringTag];
|
|
390
|
+
if (typeof stringTag === "string") return stringTag;
|
|
391
|
+
var objPrototype = Object.getPrototypeOf(obj);
|
|
392
|
+
if (objPrototype === RegExp.prototype) return "RegExp";
|
|
393
|
+
if (objPrototype === Date.prototype) return "Date";
|
|
394
|
+
if (promiseExists && objPrototype === Promise.prototype) return "Promise";
|
|
395
|
+
if (setExists && objPrototype === Set.prototype) return "Set";
|
|
396
|
+
if (mapExists && objPrototype === Map.prototype) return "Map";
|
|
397
|
+
if (weakSetExists && objPrototype === WeakSet.prototype) return "WeakSet";
|
|
398
|
+
if (weakMapExists && objPrototype === WeakMap.prototype) return "WeakMap";
|
|
399
|
+
if (dataViewExists && objPrototype === DataView.prototype) return "DataView";
|
|
400
|
+
if (mapExists && objPrototype === mapIteratorPrototype) return "Map Iterator";
|
|
401
|
+
if (setExists && objPrototype === setIteratorPrototype) return "Set Iterator";
|
|
402
|
+
if (arrayIteratorExists && objPrototype === arrayIteratorPrototype) return "Array Iterator";
|
|
403
|
+
if (stringIteratorExists && objPrototype === stringIteratorPrototype) return "String Iterator";
|
|
404
|
+
if (objPrototype === null) return "Object";
|
|
405
|
+
return Object.prototype.toString.call(obj).slice(toStringLeftSliceLength, toStringRightSliceLength);
|
|
406
|
+
}
|
|
407
|
+
return typeDetect;
|
|
408
|
+
}));
|
|
409
|
+
})(typeDetect$1);
|
|
410
|
+
return typeDetect$1.exports;
|
|
411
|
+
}
|
|
412
|
+
var typeOf;
|
|
413
|
+
var hasRequiredTypeOf;
|
|
414
|
+
function requireTypeOf() {
|
|
415
|
+
if (hasRequiredTypeOf) return typeOf;
|
|
416
|
+
hasRequiredTypeOf = 1;
|
|
417
|
+
var type = requireTypeDetect();
|
|
418
|
+
/**
|
|
419
|
+
* Returns the lower-case result of running type from type-detect on the value
|
|
420
|
+
* @param {*} value
|
|
421
|
+
* @returns {string}
|
|
422
|
+
*/
|
|
423
|
+
typeOf = function typeOf(value) {
|
|
424
|
+
return type(value).toLowerCase();
|
|
425
|
+
};
|
|
426
|
+
return typeOf;
|
|
427
|
+
}
|
|
428
|
+
var valueToString_1;
|
|
429
|
+
var hasRequiredValueToString;
|
|
430
|
+
function requireValueToString() {
|
|
431
|
+
if (hasRequiredValueToString) return valueToString_1;
|
|
432
|
+
hasRequiredValueToString = 1;
|
|
433
|
+
/**
|
|
434
|
+
* Returns a string representation of the value
|
|
435
|
+
* @param {*} value
|
|
436
|
+
* @returns {string}
|
|
437
|
+
*/
|
|
438
|
+
function valueToString(value) {
|
|
439
|
+
if (value && value.toString) return value.toString();
|
|
440
|
+
return String(value);
|
|
441
|
+
}
|
|
442
|
+
valueToString_1 = valueToString;
|
|
443
|
+
return valueToString_1;
|
|
444
|
+
}
|
|
445
|
+
var lib;
|
|
446
|
+
var hasRequiredLib;
|
|
447
|
+
function requireLib() {
|
|
448
|
+
if (hasRequiredLib) return lib;
|
|
449
|
+
hasRequiredLib = 1;
|
|
450
|
+
lib = {
|
|
451
|
+
global: requireGlobal(),
|
|
452
|
+
calledInOrder: requireCalledInOrder(),
|
|
453
|
+
className: requireClassName(),
|
|
454
|
+
deprecated: requireDeprecated(),
|
|
455
|
+
every: requireEvery(),
|
|
456
|
+
functionName: requireFunctionName(),
|
|
457
|
+
orderByFirstCall: requireOrderByFirstCall(),
|
|
458
|
+
prototypes: requirePrototypes(),
|
|
459
|
+
typeOf: requireTypeOf(),
|
|
460
|
+
valueToString: requireValueToString()
|
|
461
|
+
};
|
|
462
|
+
return lib;
|
|
463
|
+
}
|
|
464
|
+
var hasRequiredFakeTimersSrc;
|
|
465
|
+
function requireFakeTimersSrc() {
|
|
466
|
+
if (hasRequiredFakeTimersSrc) return fakeTimersSrc;
|
|
467
|
+
hasRequiredFakeTimersSrc = 1;
|
|
468
|
+
const globalObject = requireLib().global;
|
|
469
|
+
let timersModule, timersPromisesModule;
|
|
470
|
+
if (typeof __vitest_required__ !== "undefined") {
|
|
471
|
+
try {
|
|
472
|
+
timersModule = __vitest_required__.timers;
|
|
473
|
+
} catch (e) {}
|
|
474
|
+
try {
|
|
475
|
+
timersPromisesModule = __vitest_required__.timersPromises;
|
|
476
|
+
} catch (e) {}
|
|
477
|
+
}
|
|
478
|
+
/**
|
|
479
|
+
* @typedef {"nextAsync" | "manual" | "interval"} TickMode
|
|
480
|
+
*/
|
|
481
|
+
/**
|
|
482
|
+
* @typedef {object} NextAsyncTickMode
|
|
483
|
+
* @property {"nextAsync"} mode
|
|
484
|
+
*/
|
|
485
|
+
/**
|
|
486
|
+
* @typedef {object} ManualTickMode
|
|
487
|
+
* @property {"manual"} mode
|
|
488
|
+
*/
|
|
489
|
+
/**
|
|
490
|
+
* @typedef {object} IntervalTickMode
|
|
491
|
+
* @property {"interval"} mode
|
|
492
|
+
* @property {number} [delta]
|
|
493
|
+
*/
|
|
494
|
+
/**
|
|
495
|
+
* @typedef {IntervalTickMode | NextAsyncTickMode | ManualTickMode} TimerTickMode
|
|
496
|
+
*/
|
|
497
|
+
/**
|
|
498
|
+
* @typedef {object} IdleDeadline
|
|
499
|
+
* @property {boolean} didTimeout - whether or not the callback was called before reaching the optional timeout
|
|
500
|
+
* @property {function():number} timeRemaining - a floating-point value providing an estimate of the number of milliseconds remaining in the current idle period
|
|
501
|
+
*/
|
|
502
|
+
/**
|
|
503
|
+
* Queues a function to be called during a browser's idle periods
|
|
504
|
+
* @callback RequestIdleCallback
|
|
505
|
+
* @param {function(IdleDeadline)} callback
|
|
506
|
+
* @param {{timeout: number}} options - an options object
|
|
507
|
+
* @returns {number} the id
|
|
508
|
+
*/
|
|
509
|
+
/**
|
|
510
|
+
* @callback NextTick
|
|
511
|
+
* @param {VoidVarArgsFunc} callback - the callback to run
|
|
512
|
+
* @param {...*} args - optional arguments to call the callback with
|
|
513
|
+
* @returns {void}
|
|
514
|
+
*/
|
|
515
|
+
/**
|
|
516
|
+
* @callback SetImmediate
|
|
517
|
+
* @param {VoidVarArgsFunc} callback - the callback to run
|
|
518
|
+
* @param {...*} args - optional arguments to call the callback with
|
|
519
|
+
* @returns {NodeImmediate}
|
|
520
|
+
*/
|
|
521
|
+
/**
|
|
522
|
+
* @callback VoidVarArgsFunc
|
|
523
|
+
* @param {...*} callback - the callback to run
|
|
524
|
+
* @returns {void}
|
|
525
|
+
*/
|
|
526
|
+
/**
|
|
527
|
+
* @typedef RequestAnimationFrame
|
|
528
|
+
* @property {function(number):void} requestAnimationFrame
|
|
529
|
+
* @returns {number} - the id
|
|
530
|
+
*/
|
|
531
|
+
/**
|
|
532
|
+
* @typedef Performance
|
|
533
|
+
* @property {function(): number} now
|
|
534
|
+
*/
|
|
535
|
+
/**
|
|
536
|
+
* @typedef {object} Clock
|
|
537
|
+
* @property {number} now - the current time
|
|
538
|
+
* @property {Date} Date - the Date constructor
|
|
539
|
+
* @property {number} loopLimit - the maximum number of timers before assuming an infinite loop
|
|
540
|
+
* @property {RequestIdleCallback} requestIdleCallback
|
|
541
|
+
* @property {function(number):void} cancelIdleCallback
|
|
542
|
+
* @property {setTimeout} setTimeout
|
|
543
|
+
* @property {clearTimeout} clearTimeout
|
|
544
|
+
* @property {NextTick} nextTick
|
|
545
|
+
* @property {queueMicrotask} queueMicrotask
|
|
546
|
+
* @property {setInterval} setInterval
|
|
547
|
+
* @property {clearInterval} clearInterval
|
|
548
|
+
* @property {SetImmediate} setImmediate
|
|
549
|
+
* @property {function(NodeImmediate):void} clearImmediate
|
|
550
|
+
* @property {function():number} countTimers
|
|
551
|
+
* @property {RequestAnimationFrame} requestAnimationFrame
|
|
552
|
+
* @property {function(number):void} cancelAnimationFrame
|
|
553
|
+
* @property {function():void} runMicrotasks
|
|
554
|
+
* @property {function(string | number): number} tick
|
|
555
|
+
* @property {function(string | number): Promise<number>} tickAsync
|
|
556
|
+
* @property {function(): number} next
|
|
557
|
+
* @property {function(): Promise<number>} nextAsync
|
|
558
|
+
* @property {function(): number} runAll
|
|
559
|
+
* @property {function(): number} runToFrame
|
|
560
|
+
* @property {function(): Promise<number>} runAllAsync
|
|
561
|
+
* @property {function(): number} runToLast
|
|
562
|
+
* @property {function(): Promise<number>} runToLastAsync
|
|
563
|
+
* @property {function(): void} reset
|
|
564
|
+
* @property {function(number | Date): void} setSystemTime
|
|
565
|
+
* @property {function(number): void} jump
|
|
566
|
+
* @property {Performance} performance
|
|
567
|
+
* @property {function(number[]): number[]} hrtime - process.hrtime (legacy)
|
|
568
|
+
* @property {function(): void} uninstall Uninstall the clock.
|
|
569
|
+
* @property {Function[]} methods - the methods that are faked
|
|
570
|
+
* @property {boolean} [shouldClearNativeTimers] inherited from config
|
|
571
|
+
* @property {{methodName:string, original:any}[] | undefined} timersModuleMethods
|
|
572
|
+
* @property {{methodName:string, original:any}[] | undefined} timersPromisesModuleMethods
|
|
573
|
+
* @property {Map<function(): void, AbortSignal>} abortListenerMap
|
|
574
|
+
* @property {function(TimerTickMode): void} setTickMode
|
|
575
|
+
*/
|
|
576
|
+
/**
|
|
577
|
+
* Configuration object for the `install` method.
|
|
578
|
+
* @typedef {object} Config
|
|
579
|
+
* @property {number|Date} [now] a number (in milliseconds) or a Date object (default epoch)
|
|
580
|
+
* @property {string[]} [toFake] names of the methods that should be faked.
|
|
581
|
+
* @property {number} [loopLimit] the maximum number of timers that will be run when calling runAll()
|
|
582
|
+
* @property {boolean} [shouldAdvanceTime] tells FakeTimers to increment mocked time automatically (default false)
|
|
583
|
+
* @property {number} [advanceTimeDelta] increment mocked time every <<advanceTimeDelta>> ms (default: 20ms)
|
|
584
|
+
* @property {boolean} [shouldClearNativeTimers] forwards clear timer calls to native functions if they are not fakes (default: false)
|
|
585
|
+
* @property {boolean} [ignoreMissingTimers] default is false, meaning asking to fake timers that are not present will throw an error
|
|
586
|
+
*/
|
|
587
|
+
/**
|
|
588
|
+
* The internal structure to describe a scheduled fake timer
|
|
589
|
+
* @typedef {object} Timer
|
|
590
|
+
* @property {Function} func
|
|
591
|
+
* @property {*[]} args
|
|
592
|
+
* @property {number} delay
|
|
593
|
+
* @property {number} callAt
|
|
594
|
+
* @property {number} createdAt
|
|
595
|
+
* @property {boolean} immediate
|
|
596
|
+
* @property {number} id
|
|
597
|
+
* @property {Error} [error]
|
|
598
|
+
*/
|
|
599
|
+
/**
|
|
600
|
+
* A Node timer
|
|
601
|
+
* @typedef {object} NodeImmediate
|
|
602
|
+
* @property {function(): boolean} hasRef
|
|
603
|
+
* @property {function(): NodeImmediate} ref
|
|
604
|
+
* @property {function(): NodeImmediate} unref
|
|
605
|
+
*/
|
|
606
|
+
/**
|
|
607
|
+
* Mocks available features in the specified global namespace.
|
|
608
|
+
* @param {*} _global Namespace to mock (e.g. `window`)
|
|
609
|
+
* @returns {FakeTimers}
|
|
610
|
+
*/
|
|
611
|
+
function withGlobal(_global) {
|
|
612
|
+
const maxTimeout = Math.pow(2, 31) - 1;
|
|
613
|
+
const idCounterStart = 0xe8d4a51000;
|
|
614
|
+
const NOOP = function() {};
|
|
615
|
+
const NOOP_ARRAY = function() {
|
|
616
|
+
return [];
|
|
617
|
+
};
|
|
618
|
+
const isPresent = {};
|
|
619
|
+
let timeoutResult, addTimerReturnsObject = false;
|
|
620
|
+
if (_global.setTimeout) {
|
|
621
|
+
isPresent.setTimeout = true;
|
|
622
|
+
timeoutResult = _global.setTimeout(NOOP, 0);
|
|
623
|
+
addTimerReturnsObject = typeof timeoutResult === "object";
|
|
624
|
+
}
|
|
625
|
+
isPresent.clearTimeout = Boolean(_global.clearTimeout);
|
|
626
|
+
isPresent.setInterval = Boolean(_global.setInterval);
|
|
627
|
+
isPresent.clearInterval = Boolean(_global.clearInterval);
|
|
628
|
+
isPresent.hrtime = _global.process && typeof _global.process.hrtime === "function";
|
|
629
|
+
isPresent.hrtimeBigint = isPresent.hrtime && typeof _global.process.hrtime.bigint === "function";
|
|
630
|
+
isPresent.nextTick = _global.process && typeof _global.process.nextTick === "function";
|
|
631
|
+
const utilPromisify = _global.process && _global.__vitest_required__ && _global.__vitest_required__.util.promisify;
|
|
632
|
+
isPresent.performance = _global.performance && typeof _global.performance.now === "function";
|
|
633
|
+
const hasPerformancePrototype = _global.Performance && (typeof _global.Performance).match(/^(function|object)$/);
|
|
634
|
+
const hasPerformanceConstructorPrototype = _global.performance && _global.performance.constructor && _global.performance.constructor.prototype;
|
|
635
|
+
isPresent.queueMicrotask = _global.hasOwnProperty("queueMicrotask");
|
|
636
|
+
isPresent.requestAnimationFrame = _global.requestAnimationFrame && typeof _global.requestAnimationFrame === "function";
|
|
637
|
+
isPresent.cancelAnimationFrame = _global.cancelAnimationFrame && typeof _global.cancelAnimationFrame === "function";
|
|
638
|
+
isPresent.requestIdleCallback = _global.requestIdleCallback && typeof _global.requestIdleCallback === "function";
|
|
639
|
+
isPresent.cancelIdleCallbackPresent = _global.cancelIdleCallback && typeof _global.cancelIdleCallback === "function";
|
|
640
|
+
isPresent.setImmediate = _global.setImmediate && typeof _global.setImmediate === "function";
|
|
641
|
+
isPresent.clearImmediate = _global.clearImmediate && typeof _global.clearImmediate === "function";
|
|
642
|
+
isPresent.Intl = _global.Intl && typeof _global.Intl === "object";
|
|
643
|
+
if (_global.clearTimeout) _global.clearTimeout(timeoutResult);
|
|
644
|
+
const NativeDate = _global.Date;
|
|
645
|
+
const NativeIntl = isPresent.Intl ? Object.defineProperties(Object.create(null), Object.getOwnPropertyDescriptors(_global.Intl)) : void 0;
|
|
646
|
+
let uniqueTimerId = idCounterStart;
|
|
647
|
+
if (NativeDate === void 0) throw new Error("The global scope doesn't have a `Date` object (see https://github.com/sinonjs/sinon/issues/1852#issuecomment-419622780)");
|
|
648
|
+
isPresent.Date = true;
|
|
649
|
+
/**
|
|
650
|
+
* The PerformanceEntry object encapsulates a single performance metric
|
|
651
|
+
* that is part of the browser's performance timeline.
|
|
652
|
+
*
|
|
653
|
+
* This is an object returned by the `mark` and `measure` methods on the Performance prototype
|
|
654
|
+
*/
|
|
655
|
+
class FakePerformanceEntry {
|
|
656
|
+
constructor(name, entryType, startTime, duration) {
|
|
657
|
+
this.name = name;
|
|
658
|
+
this.entryType = entryType;
|
|
659
|
+
this.startTime = startTime;
|
|
660
|
+
this.duration = duration;
|
|
661
|
+
}
|
|
662
|
+
toJSON() {
|
|
663
|
+
return JSON.stringify({ ...this });
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
/**
|
|
667
|
+
* @param {number} num
|
|
668
|
+
* @returns {boolean}
|
|
669
|
+
*/
|
|
670
|
+
function isNumberFinite(num) {
|
|
671
|
+
if (Number.isFinite) return Number.isFinite(num);
|
|
672
|
+
return isFinite(num);
|
|
673
|
+
}
|
|
674
|
+
let isNearInfiniteLimit = false;
|
|
675
|
+
/**
|
|
676
|
+
* @param {Clock} clock
|
|
677
|
+
* @param {number} i
|
|
678
|
+
*/
|
|
679
|
+
function checkIsNearInfiniteLimit(clock, i) {
|
|
680
|
+
if (clock.loopLimit && i === clock.loopLimit - 1) isNearInfiniteLimit = true;
|
|
681
|
+
}
|
|
682
|
+
/**
|
|
683
|
+
*
|
|
684
|
+
*/
|
|
685
|
+
function resetIsNearInfiniteLimit() {
|
|
686
|
+
isNearInfiniteLimit = false;
|
|
687
|
+
}
|
|
688
|
+
/**
|
|
689
|
+
* Parse strings like "01:10:00" (meaning 1 hour, 10 minutes, 0 seconds) into
|
|
690
|
+
* number of milliseconds. This is used to support human-readable strings passed
|
|
691
|
+
* to clock.tick()
|
|
692
|
+
* @param {string} str
|
|
693
|
+
* @returns {number}
|
|
694
|
+
*/
|
|
695
|
+
function parseTime(str) {
|
|
696
|
+
if (!str) return 0;
|
|
697
|
+
const strings = str.split(":");
|
|
698
|
+
const l = strings.length;
|
|
699
|
+
let i = l;
|
|
700
|
+
let ms = 0;
|
|
701
|
+
let parsed;
|
|
702
|
+
if (l > 3 || !/^(\d\d:){0,2}\d\d?$/.test(str)) throw new Error("tick only understands numbers, 'm:s' and 'h:m:s'. Each part must be two digits");
|
|
703
|
+
while (i--) {
|
|
704
|
+
parsed = parseInt(strings[i], 10);
|
|
705
|
+
if (parsed >= 60) throw new Error(`Invalid time ${str}`);
|
|
706
|
+
ms += parsed * Math.pow(60, l - i - 1);
|
|
707
|
+
}
|
|
708
|
+
return ms * 1e3;
|
|
709
|
+
}
|
|
710
|
+
/**
|
|
711
|
+
* Get the decimal part of the millisecond value as nanoseconds
|
|
712
|
+
* @param {number} msFloat the number of milliseconds
|
|
713
|
+
* @returns {number} an integer number of nanoseconds in the range [0,1e6)
|
|
714
|
+
*
|
|
715
|
+
* Example: nanoRemainer(123.456789) -> 456789
|
|
716
|
+
*/
|
|
717
|
+
function nanoRemainder(msFloat) {
|
|
718
|
+
const modulo = 1e6;
|
|
719
|
+
const remainder = msFloat * 1e6 % modulo;
|
|
720
|
+
const positiveRemainder = remainder < 0 ? remainder + modulo : remainder;
|
|
721
|
+
return Math.floor(positiveRemainder);
|
|
722
|
+
}
|
|
723
|
+
/**
|
|
724
|
+
* Used to grok the `now` parameter to createClock.
|
|
725
|
+
* @param {Date|number} epoch the system time
|
|
726
|
+
* @returns {number}
|
|
727
|
+
*/
|
|
728
|
+
function getEpoch(epoch) {
|
|
729
|
+
if (!epoch) return 0;
|
|
730
|
+
if (typeof epoch.getTime === "function") return epoch.getTime();
|
|
731
|
+
if (typeof epoch === "number") return epoch;
|
|
732
|
+
throw new TypeError("now should be milliseconds since UNIX epoch");
|
|
733
|
+
}
|
|
734
|
+
/**
|
|
735
|
+
* @param {number} from
|
|
736
|
+
* @param {number} to
|
|
737
|
+
* @param {Timer} timer
|
|
738
|
+
* @returns {boolean}
|
|
739
|
+
*/
|
|
740
|
+
function inRange(from, to, timer) {
|
|
741
|
+
return timer && timer.callAt >= from && timer.callAt <= to;
|
|
742
|
+
}
|
|
743
|
+
/**
|
|
744
|
+
* @param {Clock} clock
|
|
745
|
+
* @param {Timer} job
|
|
746
|
+
*/
|
|
747
|
+
function getInfiniteLoopError(clock, job) {
|
|
748
|
+
const infiniteLoopError = /* @__PURE__ */ new Error(`Aborting after running ${clock.loopLimit} timers, assuming an infinite loop!`);
|
|
749
|
+
if (!job.error) return infiniteLoopError;
|
|
750
|
+
const computedTargetPattern = /target\.*[<|(|[].*?[>|\]|)]\s*/;
|
|
751
|
+
let clockMethodPattern = new RegExp(String(Object.keys(clock).join("|")));
|
|
752
|
+
if (addTimerReturnsObject) clockMethodPattern = new RegExp(`\\s+at (Object\\.)?(?:${Object.keys(clock).join("|")})\\s+`);
|
|
753
|
+
let matchedLineIndex = -1;
|
|
754
|
+
job.error.stack.split("\n").some(function(line, i) {
|
|
755
|
+
/* istanbul ignore if */
|
|
756
|
+
if (line.match(computedTargetPattern)) {
|
|
757
|
+
matchedLineIndex = i;
|
|
758
|
+
return true;
|
|
759
|
+
}
|
|
760
|
+
if (line.match(clockMethodPattern)) {
|
|
761
|
+
matchedLineIndex = i;
|
|
762
|
+
return false;
|
|
763
|
+
}
|
|
764
|
+
return matchedLineIndex >= 0;
|
|
765
|
+
});
|
|
766
|
+
const stack = `${infiniteLoopError}\n${job.type || "Microtask"} - ${job.func.name || "anonymous"}\n${job.error.stack.split("\n").slice(matchedLineIndex + 1).join("\n")}`;
|
|
767
|
+
try {
|
|
768
|
+
Object.defineProperty(infiniteLoopError, "stack", { value: stack });
|
|
769
|
+
} catch (e) {}
|
|
770
|
+
return infiniteLoopError;
|
|
771
|
+
}
|
|
772
|
+
function createDate() {
|
|
773
|
+
class ClockDate extends NativeDate {
|
|
774
|
+
/**
|
|
775
|
+
* @param {number} year
|
|
776
|
+
* @param {number} month
|
|
777
|
+
* @param {number} date
|
|
778
|
+
* @param {number} hour
|
|
779
|
+
* @param {number} minute
|
|
780
|
+
* @param {number} second
|
|
781
|
+
* @param {number} ms
|
|
782
|
+
* @returns void
|
|
783
|
+
*/
|
|
784
|
+
constructor(year, month, date, hour, minute, second, ms) {
|
|
785
|
+
if (arguments.length === 0) super(ClockDate.clock.now);
|
|
786
|
+
else super(...arguments);
|
|
787
|
+
Object.defineProperty(this, "constructor", {
|
|
788
|
+
value: NativeDate,
|
|
789
|
+
enumerable: false
|
|
790
|
+
});
|
|
791
|
+
}
|
|
792
|
+
static [Symbol.hasInstance](instance) {
|
|
793
|
+
return instance instanceof NativeDate;
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
ClockDate.isFake = true;
|
|
797
|
+
if (NativeDate.now) ClockDate.now = function now() {
|
|
798
|
+
return ClockDate.clock.now;
|
|
799
|
+
};
|
|
800
|
+
if (NativeDate.toSource) ClockDate.toSource = function toSource() {
|
|
801
|
+
return NativeDate.toSource();
|
|
802
|
+
};
|
|
803
|
+
ClockDate.toString = function toString() {
|
|
804
|
+
return NativeDate.toString();
|
|
805
|
+
};
|
|
806
|
+
return new Proxy(ClockDate, { apply() {
|
|
807
|
+
if (this instanceof ClockDate) throw new TypeError("A Proxy should only capture `new` calls with the `construct` handler. This is not supposed to be possible, so check the logic.");
|
|
808
|
+
return new NativeDate(ClockDate.clock.now).toString();
|
|
809
|
+
} });
|
|
810
|
+
}
|
|
811
|
+
/**
|
|
812
|
+
* Mirror Intl by default on our fake implementation
|
|
813
|
+
*
|
|
814
|
+
* Most of the properties are the original native ones,
|
|
815
|
+
* but we need to take control of those that have a
|
|
816
|
+
* dependency on the current clock.
|
|
817
|
+
* @returns {object} the partly fake Intl implementation
|
|
818
|
+
*/
|
|
819
|
+
function createIntl() {
|
|
820
|
+
const ClockIntl = {};
|
|
821
|
+
Object.getOwnPropertyNames(NativeIntl).forEach((property) => ClockIntl[property] = NativeIntl[property]);
|
|
822
|
+
ClockIntl.DateTimeFormat = function(...args) {
|
|
823
|
+
const realFormatter = new NativeIntl.DateTimeFormat(...args);
|
|
824
|
+
const formatter = {};
|
|
825
|
+
[
|
|
826
|
+
"formatRange",
|
|
827
|
+
"formatRangeToParts",
|
|
828
|
+
"resolvedOptions"
|
|
829
|
+
].forEach((method) => {
|
|
830
|
+
formatter[method] = realFormatter[method].bind(realFormatter);
|
|
831
|
+
});
|
|
832
|
+
["format", "formatToParts"].forEach((method) => {
|
|
833
|
+
formatter[method] = function(date) {
|
|
834
|
+
return realFormatter[method](date || ClockIntl.clock.now);
|
|
835
|
+
};
|
|
836
|
+
});
|
|
837
|
+
return formatter;
|
|
838
|
+
};
|
|
839
|
+
ClockIntl.DateTimeFormat.prototype = Object.create(NativeIntl.DateTimeFormat.prototype);
|
|
840
|
+
ClockIntl.DateTimeFormat.supportedLocalesOf = NativeIntl.DateTimeFormat.supportedLocalesOf;
|
|
841
|
+
return ClockIntl;
|
|
842
|
+
}
|
|
843
|
+
function enqueueJob(clock, job) {
|
|
844
|
+
if (!clock.jobs) clock.jobs = [];
|
|
845
|
+
clock.jobs.push(job);
|
|
846
|
+
}
|
|
847
|
+
function runJobs(clock) {
|
|
848
|
+
if (!clock.jobs) return;
|
|
849
|
+
for (let i = 0; i < clock.jobs.length; i++) {
|
|
850
|
+
const job = clock.jobs[i];
|
|
851
|
+
job.func.apply(null, job.args);
|
|
852
|
+
checkIsNearInfiniteLimit(clock, i);
|
|
853
|
+
if (clock.loopLimit && i > clock.loopLimit) throw getInfiniteLoopError(clock, job);
|
|
854
|
+
}
|
|
855
|
+
resetIsNearInfiniteLimit();
|
|
856
|
+
clock.jobs = [];
|
|
857
|
+
}
|
|
858
|
+
/**
|
|
859
|
+
* @param {Clock} clock
|
|
860
|
+
* @param {Timer} timer
|
|
861
|
+
* @returns {number} id of the created timer
|
|
862
|
+
*/
|
|
863
|
+
function addTimer(clock, timer) {
|
|
864
|
+
if (timer.func === void 0) throw new Error("Callback must be provided to timer calls");
|
|
865
|
+
if (addTimerReturnsObject) {
|
|
866
|
+
if (typeof timer.func !== "function") throw new TypeError(`[ERR_INVALID_CALLBACK]: Callback must be a function. Received ${timer.func} of type ${typeof timer.func}`);
|
|
867
|
+
}
|
|
868
|
+
if (isNearInfiniteLimit) timer.error = /* @__PURE__ */ new Error();
|
|
869
|
+
timer.type = timer.immediate ? "Immediate" : "Timeout";
|
|
870
|
+
if (timer.hasOwnProperty("delay")) {
|
|
871
|
+
if (typeof timer.delay !== "number") timer.delay = parseInt(timer.delay, 10);
|
|
872
|
+
if (!isNumberFinite(timer.delay)) timer.delay = 0;
|
|
873
|
+
timer.delay = timer.delay > maxTimeout ? 1 : timer.delay;
|
|
874
|
+
timer.delay = Math.max(0, timer.delay);
|
|
875
|
+
}
|
|
876
|
+
if (timer.hasOwnProperty("interval")) {
|
|
877
|
+
timer.type = "Interval";
|
|
878
|
+
timer.interval = timer.interval > maxTimeout ? 1 : timer.interval;
|
|
879
|
+
}
|
|
880
|
+
if (timer.hasOwnProperty("animation")) {
|
|
881
|
+
timer.type = "AnimationFrame";
|
|
882
|
+
timer.animation = true;
|
|
883
|
+
}
|
|
884
|
+
if (timer.hasOwnProperty("idleCallback")) {
|
|
885
|
+
timer.type = "IdleCallback";
|
|
886
|
+
timer.idleCallback = true;
|
|
887
|
+
}
|
|
888
|
+
if (!clock.timers) clock.timers = {};
|
|
889
|
+
timer.id = uniqueTimerId++;
|
|
890
|
+
timer.createdAt = clock.now;
|
|
891
|
+
timer.callAt = clock.now + (parseInt(timer.delay) || (clock.duringTick ? 1 : 0));
|
|
892
|
+
clock.timers[timer.id] = timer;
|
|
893
|
+
if (addTimerReturnsObject) {
|
|
894
|
+
const res = {
|
|
895
|
+
refed: true,
|
|
896
|
+
ref: function() {
|
|
897
|
+
this.refed = true;
|
|
898
|
+
return res;
|
|
899
|
+
},
|
|
900
|
+
unref: function() {
|
|
901
|
+
this.refed = false;
|
|
902
|
+
return res;
|
|
903
|
+
},
|
|
904
|
+
hasRef: function() {
|
|
905
|
+
return this.refed;
|
|
906
|
+
},
|
|
907
|
+
refresh: function() {
|
|
908
|
+
timer.callAt = clock.now + (parseInt(timer.delay) || (clock.duringTick ? 1 : 0));
|
|
909
|
+
clock.timers[timer.id] = timer;
|
|
910
|
+
return res;
|
|
911
|
+
},
|
|
912
|
+
[Symbol.toPrimitive]: function() {
|
|
913
|
+
return timer.id;
|
|
914
|
+
}
|
|
915
|
+
};
|
|
916
|
+
return res;
|
|
917
|
+
}
|
|
918
|
+
return timer.id;
|
|
919
|
+
}
|
|
920
|
+
/**
|
|
921
|
+
* Timer comparitor
|
|
922
|
+
* @param {Timer} a
|
|
923
|
+
* @param {Timer} b
|
|
924
|
+
* @returns {number}
|
|
925
|
+
*/
|
|
926
|
+
function compareTimers(a, b) {
|
|
927
|
+
if (a.callAt < b.callAt) return -1;
|
|
928
|
+
if (a.callAt > b.callAt) return 1;
|
|
929
|
+
if (a.immediate && !b.immediate) return -1;
|
|
930
|
+
if (!a.immediate && b.immediate) return 1;
|
|
931
|
+
if (a.createdAt < b.createdAt) return -1;
|
|
932
|
+
if (a.createdAt > b.createdAt) return 1;
|
|
933
|
+
if (a.id < b.id) return -1;
|
|
934
|
+
if (a.id > b.id) return 1;
|
|
935
|
+
}
|
|
936
|
+
/**
|
|
937
|
+
* @param {Clock} clock
|
|
938
|
+
* @param {number} from
|
|
939
|
+
* @param {number} to
|
|
940
|
+
* @returns {Timer}
|
|
941
|
+
*/
|
|
942
|
+
function firstTimerInRange(clock, from, to) {
|
|
943
|
+
const timers = clock.timers;
|
|
944
|
+
let timer = null;
|
|
945
|
+
let id, isInRange;
|
|
946
|
+
for (id in timers) if (timers.hasOwnProperty(id)) {
|
|
947
|
+
isInRange = inRange(from, to, timers[id]);
|
|
948
|
+
if (isInRange && (!timer || compareTimers(timer, timers[id]) === 1)) timer = timers[id];
|
|
949
|
+
}
|
|
950
|
+
return timer;
|
|
951
|
+
}
|
|
952
|
+
/**
|
|
953
|
+
* @param {Clock} clock
|
|
954
|
+
* @returns {Timer}
|
|
955
|
+
*/
|
|
956
|
+
function firstTimer(clock) {
|
|
957
|
+
const timers = clock.timers;
|
|
958
|
+
let timer = null;
|
|
959
|
+
let id;
|
|
960
|
+
for (id in timers) if (timers.hasOwnProperty(id)) {
|
|
961
|
+
if (!timer || compareTimers(timer, timers[id]) === 1) timer = timers[id];
|
|
962
|
+
}
|
|
963
|
+
return timer;
|
|
964
|
+
}
|
|
965
|
+
/**
|
|
966
|
+
* @param {Clock} clock
|
|
967
|
+
* @returns {Timer}
|
|
968
|
+
*/
|
|
969
|
+
function lastTimer(clock) {
|
|
970
|
+
const timers = clock.timers;
|
|
971
|
+
let timer = null;
|
|
972
|
+
let id;
|
|
973
|
+
for (id in timers) if (timers.hasOwnProperty(id)) {
|
|
974
|
+
if (!timer || compareTimers(timer, timers[id]) === -1) timer = timers[id];
|
|
975
|
+
}
|
|
976
|
+
return timer;
|
|
977
|
+
}
|
|
978
|
+
/**
|
|
979
|
+
* @param {Clock} clock
|
|
980
|
+
* @param {Timer} timer
|
|
981
|
+
*/
|
|
982
|
+
function callTimer(clock, timer) {
|
|
983
|
+
if (typeof timer.interval === "number") clock.timers[timer.id].callAt += timer.interval;
|
|
984
|
+
else delete clock.timers[timer.id];
|
|
985
|
+
if (typeof timer.func === "function") timer.func.apply(null, timer.args);
|
|
986
|
+
else {
|
|
987
|
+
const eval2 = eval;
|
|
988
|
+
(function() {
|
|
989
|
+
eval2(timer.func);
|
|
990
|
+
})();
|
|
991
|
+
}
|
|
992
|
+
}
|
|
993
|
+
/**
|
|
994
|
+
* Gets clear handler name for a given timer type
|
|
995
|
+
* @param {string} ttype
|
|
996
|
+
*/
|
|
997
|
+
function getClearHandler(ttype) {
|
|
998
|
+
if (ttype === "IdleCallback" || ttype === "AnimationFrame") return `cancel${ttype}`;
|
|
999
|
+
return `clear${ttype}`;
|
|
1000
|
+
}
|
|
1001
|
+
/**
|
|
1002
|
+
* Gets schedule handler name for a given timer type
|
|
1003
|
+
* @param {string} ttype
|
|
1004
|
+
*/
|
|
1005
|
+
function getScheduleHandler(ttype) {
|
|
1006
|
+
if (ttype === "IdleCallback" || ttype === "AnimationFrame") return `request${ttype}`;
|
|
1007
|
+
return `set${ttype}`;
|
|
1008
|
+
}
|
|
1009
|
+
/**
|
|
1010
|
+
* Creates an anonymous function to warn only once
|
|
1011
|
+
*/
|
|
1012
|
+
function createWarnOnce() {
|
|
1013
|
+
let calls = 0;
|
|
1014
|
+
return function(msg) {
|
|
1015
|
+
!calls++ && console.warn(msg);
|
|
1016
|
+
};
|
|
1017
|
+
}
|
|
1018
|
+
const warnOnce = createWarnOnce();
|
|
1019
|
+
/**
|
|
1020
|
+
* @param {Clock} clock
|
|
1021
|
+
* @param {number} timerId
|
|
1022
|
+
* @param {string} ttype
|
|
1023
|
+
*/
|
|
1024
|
+
function clearTimer(clock, timerId, ttype) {
|
|
1025
|
+
if (!timerId) return;
|
|
1026
|
+
if (!clock.timers) clock.timers = {};
|
|
1027
|
+
const id = Number(timerId);
|
|
1028
|
+
if (Number.isNaN(id) || id < idCounterStart) {
|
|
1029
|
+
const handlerName = getClearHandler(ttype);
|
|
1030
|
+
if (clock.shouldClearNativeTimers === true) {
|
|
1031
|
+
const nativeHandler = clock[`_${handlerName}`];
|
|
1032
|
+
return typeof nativeHandler === "function" ? nativeHandler(timerId) : void 0;
|
|
1033
|
+
}
|
|
1034
|
+
warnOnce(`FakeTimers: ${handlerName} was invoked to clear a native timer instead of one created by this library.
|
|
1035
|
+
To automatically clean-up native timers, use \`shouldClearNativeTimers\`.`);
|
|
1036
|
+
}
|
|
1037
|
+
if (clock.timers.hasOwnProperty(id)) {
|
|
1038
|
+
const timer = clock.timers[id];
|
|
1039
|
+
if (timer.type === ttype || timer.type === "Timeout" && ttype === "Interval" || timer.type === "Interval" && ttype === "Timeout") delete clock.timers[id];
|
|
1040
|
+
else {
|
|
1041
|
+
const clear = getClearHandler(ttype);
|
|
1042
|
+
const schedule = getScheduleHandler(timer.type);
|
|
1043
|
+
throw new Error(`Cannot clear timer: timer created with ${schedule}() but cleared with ${clear}()`);
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
1046
|
+
}
|
|
1047
|
+
/**
|
|
1048
|
+
* @param {Clock} clock
|
|
1049
|
+
* @returns {Timer[]}
|
|
1050
|
+
*/
|
|
1051
|
+
function uninstall(clock) {
|
|
1052
|
+
let method, i, l;
|
|
1053
|
+
const installedHrTime = "_hrtime";
|
|
1054
|
+
const installedNextTick = "_nextTick";
|
|
1055
|
+
for (i = 0, l = clock.methods.length; i < l; i++) {
|
|
1056
|
+
method = clock.methods[i];
|
|
1057
|
+
if (method === "hrtime" && _global.process) _global.process.hrtime = clock[installedHrTime];
|
|
1058
|
+
else if (method === "nextTick" && _global.process) _global.process.nextTick = clock[installedNextTick];
|
|
1059
|
+
else if (method === "performance") {
|
|
1060
|
+
const originalPerfDescriptor = Object.getOwnPropertyDescriptor(clock, `_${method}`);
|
|
1061
|
+
if (originalPerfDescriptor && originalPerfDescriptor.get && !originalPerfDescriptor.set) Object.defineProperty(_global, method, originalPerfDescriptor);
|
|
1062
|
+
else if (originalPerfDescriptor.configurable) _global[method] = clock[`_${method}`];
|
|
1063
|
+
} else if (_global[method] && _global[method].hadOwnProperty) _global[method] = clock[`_${method}`];
|
|
1064
|
+
else try {
|
|
1065
|
+
delete _global[method];
|
|
1066
|
+
} catch (ignore) {}
|
|
1067
|
+
if (clock.timersModuleMethods !== void 0) for (let j = 0; j < clock.timersModuleMethods.length; j++) {
|
|
1068
|
+
const entry = clock.timersModuleMethods[j];
|
|
1069
|
+
timersModule[entry.methodName] = entry.original;
|
|
1070
|
+
}
|
|
1071
|
+
if (clock.timersPromisesModuleMethods !== void 0) for (let j = 0; j < clock.timersPromisesModuleMethods.length; j++) {
|
|
1072
|
+
const entry = clock.timersPromisesModuleMethods[j];
|
|
1073
|
+
timersPromisesModule[entry.methodName] = entry.original;
|
|
1074
|
+
}
|
|
1075
|
+
}
|
|
1076
|
+
clock.setTickMode("manual");
|
|
1077
|
+
clock.methods = [];
|
|
1078
|
+
for (const [listener, signal] of clock.abortListenerMap.entries()) {
|
|
1079
|
+
signal.removeEventListener("abort", listener);
|
|
1080
|
+
clock.abortListenerMap.delete(listener);
|
|
1081
|
+
}
|
|
1082
|
+
if (!clock.timers) return [];
|
|
1083
|
+
return Object.keys(clock.timers).map(function mapper(key) {
|
|
1084
|
+
return clock.timers[key];
|
|
1085
|
+
});
|
|
1086
|
+
}
|
|
1087
|
+
/**
|
|
1088
|
+
* @param {object} target the target containing the method to replace
|
|
1089
|
+
* @param {string} method the keyname of the method on the target
|
|
1090
|
+
* @param {Clock} clock
|
|
1091
|
+
*/
|
|
1092
|
+
function hijackMethod(target, method, clock) {
|
|
1093
|
+
clock[method].hadOwnProperty = Object.prototype.hasOwnProperty.call(target, method);
|
|
1094
|
+
clock[`_${method}`] = target[method];
|
|
1095
|
+
if (method === "Date") target[method] = clock[method];
|
|
1096
|
+
else if (method === "Intl") target[method] = clock[method];
|
|
1097
|
+
else if (method === "performance") {
|
|
1098
|
+
const originalPerfDescriptor = Object.getOwnPropertyDescriptor(target, method);
|
|
1099
|
+
if (originalPerfDescriptor && originalPerfDescriptor.get && !originalPerfDescriptor.set) {
|
|
1100
|
+
Object.defineProperty(clock, `_${method}`, originalPerfDescriptor);
|
|
1101
|
+
const perfDescriptor = Object.getOwnPropertyDescriptor(clock, method);
|
|
1102
|
+
Object.defineProperty(target, method, perfDescriptor);
|
|
1103
|
+
} else target[method] = clock[method];
|
|
1104
|
+
} else {
|
|
1105
|
+
target[method] = function() {
|
|
1106
|
+
return clock[method].apply(clock, arguments);
|
|
1107
|
+
};
|
|
1108
|
+
Object.defineProperties(target[method], Object.getOwnPropertyDescriptors(clock[method]));
|
|
1109
|
+
}
|
|
1110
|
+
target[method].clock = clock;
|
|
1111
|
+
}
|
|
1112
|
+
/**
|
|
1113
|
+
* @param {Clock} clock
|
|
1114
|
+
* @param {number} advanceTimeDelta
|
|
1115
|
+
*/
|
|
1116
|
+
function doIntervalTick(clock, advanceTimeDelta) {
|
|
1117
|
+
clock.tick(advanceTimeDelta);
|
|
1118
|
+
}
|
|
1119
|
+
/**
|
|
1120
|
+
* @typedef {object} Timers
|
|
1121
|
+
* @property {setTimeout} setTimeout
|
|
1122
|
+
* @property {clearTimeout} clearTimeout
|
|
1123
|
+
* @property {setInterval} setInterval
|
|
1124
|
+
* @property {clearInterval} clearInterval
|
|
1125
|
+
* @property {Date} Date
|
|
1126
|
+
* @property {Intl} Intl
|
|
1127
|
+
* @property {SetImmediate=} setImmediate
|
|
1128
|
+
* @property {function(NodeImmediate): void=} clearImmediate
|
|
1129
|
+
* @property {function(number[]):number[]=} hrtime
|
|
1130
|
+
* @property {NextTick=} nextTick
|
|
1131
|
+
* @property {Performance=} performance
|
|
1132
|
+
* @property {RequestAnimationFrame=} requestAnimationFrame
|
|
1133
|
+
* @property {boolean=} queueMicrotask
|
|
1134
|
+
* @property {function(number): void=} cancelAnimationFrame
|
|
1135
|
+
* @property {RequestIdleCallback=} requestIdleCallback
|
|
1136
|
+
* @property {function(number): void=} cancelIdleCallback
|
|
1137
|
+
*/
|
|
1138
|
+
/** @type {Timers} */
|
|
1139
|
+
const timers = {
|
|
1140
|
+
setTimeout: _global.setTimeout,
|
|
1141
|
+
clearTimeout: _global.clearTimeout,
|
|
1142
|
+
setInterval: _global.setInterval,
|
|
1143
|
+
clearInterval: _global.clearInterval,
|
|
1144
|
+
Date: _global.Date
|
|
1145
|
+
};
|
|
1146
|
+
if (isPresent.setImmediate) timers.setImmediate = _global.setImmediate;
|
|
1147
|
+
if (isPresent.clearImmediate) timers.clearImmediate = _global.clearImmediate;
|
|
1148
|
+
if (isPresent.hrtime) timers.hrtime = _global.process.hrtime;
|
|
1149
|
+
if (isPresent.nextTick) timers.nextTick = _global.process.nextTick;
|
|
1150
|
+
if (isPresent.performance) timers.performance = _global.performance;
|
|
1151
|
+
if (isPresent.requestAnimationFrame) timers.requestAnimationFrame = _global.requestAnimationFrame;
|
|
1152
|
+
if (isPresent.queueMicrotask) timers.queueMicrotask = _global.queueMicrotask;
|
|
1153
|
+
if (isPresent.cancelAnimationFrame) timers.cancelAnimationFrame = _global.cancelAnimationFrame;
|
|
1154
|
+
if (isPresent.requestIdleCallback) timers.requestIdleCallback = _global.requestIdleCallback;
|
|
1155
|
+
if (isPresent.cancelIdleCallback) timers.cancelIdleCallback = _global.cancelIdleCallback;
|
|
1156
|
+
if (isPresent.Intl) timers.Intl = NativeIntl;
|
|
1157
|
+
const originalSetTimeout = _global.setImmediate || _global.setTimeout;
|
|
1158
|
+
const originalClearInterval = _global.clearInterval;
|
|
1159
|
+
const originalSetInterval = _global.setInterval;
|
|
1160
|
+
/**
|
|
1161
|
+
* @param {Date|number} [start] the system time - non-integer values are floored
|
|
1162
|
+
* @param {number} [loopLimit] maximum number of timers that will be run when calling runAll()
|
|
1163
|
+
* @returns {Clock}
|
|
1164
|
+
*/
|
|
1165
|
+
function createClock(start, loopLimit) {
|
|
1166
|
+
start = Math.floor(getEpoch(start));
|
|
1167
|
+
loopLimit = loopLimit || 1e3;
|
|
1168
|
+
let nanos = 0;
|
|
1169
|
+
const adjustedSystemTime = [0, 0];
|
|
1170
|
+
const clock = {
|
|
1171
|
+
now: start,
|
|
1172
|
+
Date: createDate(),
|
|
1173
|
+
loopLimit,
|
|
1174
|
+
tickMode: {
|
|
1175
|
+
mode: "manual",
|
|
1176
|
+
counter: 0,
|
|
1177
|
+
delta: void 0
|
|
1178
|
+
}
|
|
1179
|
+
};
|
|
1180
|
+
clock.Date.clock = clock;
|
|
1181
|
+
function getTimeToNextFrame() {
|
|
1182
|
+
return 16 - (clock.now - start) % 16;
|
|
1183
|
+
}
|
|
1184
|
+
function hrtime(prev) {
|
|
1185
|
+
const millisSinceStart = clock.now - adjustedSystemTime[0] - start;
|
|
1186
|
+
const secsSinceStart = Math.floor(millisSinceStart / 1e3);
|
|
1187
|
+
const remainderInNanos = (millisSinceStart - secsSinceStart * 1e3) * 1e6 + nanos - adjustedSystemTime[1];
|
|
1188
|
+
if (Array.isArray(prev)) {
|
|
1189
|
+
if (prev[1] > 1e9) throw new TypeError("Number of nanoseconds can't exceed a billion");
|
|
1190
|
+
const oldSecs = prev[0];
|
|
1191
|
+
let nanoDiff = remainderInNanos - prev[1];
|
|
1192
|
+
let secDiff = secsSinceStart - oldSecs;
|
|
1193
|
+
if (nanoDiff < 0) {
|
|
1194
|
+
nanoDiff += 1e9;
|
|
1195
|
+
secDiff -= 1;
|
|
1196
|
+
}
|
|
1197
|
+
return [secDiff, nanoDiff];
|
|
1198
|
+
}
|
|
1199
|
+
return [secsSinceStart, remainderInNanos];
|
|
1200
|
+
}
|
|
1201
|
+
/**
|
|
1202
|
+
* A high resolution timestamp in milliseconds.
|
|
1203
|
+
* @typedef {number} DOMHighResTimeStamp
|
|
1204
|
+
*/
|
|
1205
|
+
/**
|
|
1206
|
+
* performance.now()
|
|
1207
|
+
* @returns {DOMHighResTimeStamp}
|
|
1208
|
+
*/
|
|
1209
|
+
function fakePerformanceNow() {
|
|
1210
|
+
const hrt = hrtime();
|
|
1211
|
+
return hrt[0] * 1e3 + hrt[1] / 1e6;
|
|
1212
|
+
}
|
|
1213
|
+
if (isPresent.hrtimeBigint) hrtime.bigint = function() {
|
|
1214
|
+
const parts = hrtime();
|
|
1215
|
+
return BigInt(parts[0]) * BigInt(1e9) + BigInt(parts[1]);
|
|
1216
|
+
};
|
|
1217
|
+
if (isPresent.Intl) {
|
|
1218
|
+
clock.Intl = createIntl();
|
|
1219
|
+
clock.Intl.clock = clock;
|
|
1220
|
+
}
|
|
1221
|
+
/**
|
|
1222
|
+
* @param {TimerTickMode} tickModeConfig - The new configuration for how the clock should tick.
|
|
1223
|
+
*/
|
|
1224
|
+
clock.setTickMode = function(tickModeConfig) {
|
|
1225
|
+
const { mode: newMode, delta: newDelta } = tickModeConfig;
|
|
1226
|
+
const { mode: oldMode, delta: oldDelta } = clock.tickMode;
|
|
1227
|
+
if (newMode === oldMode && newDelta === oldDelta) return;
|
|
1228
|
+
if (oldMode === "interval") originalClearInterval(clock.attachedInterval);
|
|
1229
|
+
clock.tickMode = {
|
|
1230
|
+
counter: clock.tickMode.counter + 1,
|
|
1231
|
+
mode: newMode,
|
|
1232
|
+
delta: newDelta
|
|
1233
|
+
};
|
|
1234
|
+
if (newMode === "nextAsync") advanceUntilModeChanges();
|
|
1235
|
+
else if (newMode === "interval") createIntervalTick(clock, newDelta || 20);
|
|
1236
|
+
};
|
|
1237
|
+
async function advanceUntilModeChanges() {
|
|
1238
|
+
async function newMacrotask() {
|
|
1239
|
+
const channel = new MessageChannel();
|
|
1240
|
+
await new Promise((resolve) => {
|
|
1241
|
+
channel.port1.onmessage = () => {
|
|
1242
|
+
resolve();
|
|
1243
|
+
channel.port1.close();
|
|
1244
|
+
};
|
|
1245
|
+
channel.port2.postMessage(void 0);
|
|
1246
|
+
});
|
|
1247
|
+
channel.port1.close();
|
|
1248
|
+
channel.port2.close();
|
|
1249
|
+
await new Promise((resolve) => {
|
|
1250
|
+
originalSetTimeout(resolve);
|
|
1251
|
+
});
|
|
1252
|
+
}
|
|
1253
|
+
const { counter } = clock.tickMode;
|
|
1254
|
+
while (clock.tickMode.counter === counter) {
|
|
1255
|
+
await newMacrotask();
|
|
1256
|
+
if (clock.tickMode.counter !== counter) return;
|
|
1257
|
+
clock.next();
|
|
1258
|
+
}
|
|
1259
|
+
}
|
|
1260
|
+
function pauseAutoTickUntilFinished(promise) {
|
|
1261
|
+
if (clock.tickMode.mode !== "nextAsync") return promise;
|
|
1262
|
+
clock.setTickMode({ mode: "manual" });
|
|
1263
|
+
return promise.finally(() => {
|
|
1264
|
+
clock.setTickMode({ mode: "nextAsync" });
|
|
1265
|
+
});
|
|
1266
|
+
}
|
|
1267
|
+
clock.requestIdleCallback = function requestIdleCallback(func, timeout) {
|
|
1268
|
+
let timeToNextIdlePeriod = 0;
|
|
1269
|
+
if (clock.countTimers() > 0) timeToNextIdlePeriod = 50;
|
|
1270
|
+
const result = addTimer(clock, {
|
|
1271
|
+
func,
|
|
1272
|
+
args: Array.prototype.slice.call(arguments, 2),
|
|
1273
|
+
delay: typeof timeout === "undefined" ? timeToNextIdlePeriod : Math.min(timeout, timeToNextIdlePeriod),
|
|
1274
|
+
idleCallback: true
|
|
1275
|
+
});
|
|
1276
|
+
return Number(result);
|
|
1277
|
+
};
|
|
1278
|
+
clock.cancelIdleCallback = function cancelIdleCallback(timerId) {
|
|
1279
|
+
return clearTimer(clock, timerId, "IdleCallback");
|
|
1280
|
+
};
|
|
1281
|
+
clock.setTimeout = function setTimeout(func, timeout) {
|
|
1282
|
+
return addTimer(clock, {
|
|
1283
|
+
func,
|
|
1284
|
+
args: Array.prototype.slice.call(arguments, 2),
|
|
1285
|
+
delay: timeout
|
|
1286
|
+
});
|
|
1287
|
+
};
|
|
1288
|
+
if (typeof _global.Promise !== "undefined" && utilPromisify) clock.setTimeout[utilPromisify.custom] = function promisifiedSetTimeout(timeout, arg) {
|
|
1289
|
+
return new _global.Promise(function setTimeoutExecutor(resolve) {
|
|
1290
|
+
addTimer(clock, {
|
|
1291
|
+
func: resolve,
|
|
1292
|
+
args: [arg],
|
|
1293
|
+
delay: timeout
|
|
1294
|
+
});
|
|
1295
|
+
});
|
|
1296
|
+
};
|
|
1297
|
+
clock.clearTimeout = function clearTimeout(timerId) {
|
|
1298
|
+
return clearTimer(clock, timerId, "Timeout");
|
|
1299
|
+
};
|
|
1300
|
+
clock.nextTick = function nextTick(func) {
|
|
1301
|
+
return enqueueJob(clock, {
|
|
1302
|
+
func,
|
|
1303
|
+
args: Array.prototype.slice.call(arguments, 1),
|
|
1304
|
+
error: isNearInfiniteLimit ? /* @__PURE__ */ new Error() : null
|
|
1305
|
+
});
|
|
1306
|
+
};
|
|
1307
|
+
clock.queueMicrotask = function queueMicrotask(func) {
|
|
1308
|
+
return clock.nextTick(func);
|
|
1309
|
+
};
|
|
1310
|
+
clock.setInterval = function setInterval(func, timeout) {
|
|
1311
|
+
timeout = parseInt(timeout, 10);
|
|
1312
|
+
return addTimer(clock, {
|
|
1313
|
+
func,
|
|
1314
|
+
args: Array.prototype.slice.call(arguments, 2),
|
|
1315
|
+
delay: timeout,
|
|
1316
|
+
interval: timeout
|
|
1317
|
+
});
|
|
1318
|
+
};
|
|
1319
|
+
clock.clearInterval = function clearInterval(timerId) {
|
|
1320
|
+
return clearTimer(clock, timerId, "Interval");
|
|
1321
|
+
};
|
|
1322
|
+
if (isPresent.setImmediate) {
|
|
1323
|
+
clock.setImmediate = function setImmediate(func) {
|
|
1324
|
+
return addTimer(clock, {
|
|
1325
|
+
func,
|
|
1326
|
+
args: Array.prototype.slice.call(arguments, 1),
|
|
1327
|
+
immediate: true
|
|
1328
|
+
});
|
|
1329
|
+
};
|
|
1330
|
+
if (typeof _global.Promise !== "undefined" && utilPromisify) clock.setImmediate[utilPromisify.custom] = function promisifiedSetImmediate(arg) {
|
|
1331
|
+
return new _global.Promise(function setImmediateExecutor(resolve) {
|
|
1332
|
+
addTimer(clock, {
|
|
1333
|
+
func: resolve,
|
|
1334
|
+
args: [arg],
|
|
1335
|
+
immediate: true
|
|
1336
|
+
});
|
|
1337
|
+
});
|
|
1338
|
+
};
|
|
1339
|
+
clock.clearImmediate = function clearImmediate(timerId) {
|
|
1340
|
+
return clearTimer(clock, timerId, "Immediate");
|
|
1341
|
+
};
|
|
1342
|
+
}
|
|
1343
|
+
clock.countTimers = function countTimers() {
|
|
1344
|
+
return Object.keys(clock.timers || {}).length + (clock.jobs || []).length;
|
|
1345
|
+
};
|
|
1346
|
+
clock.requestAnimationFrame = function requestAnimationFrame(func) {
|
|
1347
|
+
const result = addTimer(clock, {
|
|
1348
|
+
func,
|
|
1349
|
+
delay: getTimeToNextFrame(),
|
|
1350
|
+
get args() {
|
|
1351
|
+
return [fakePerformanceNow()];
|
|
1352
|
+
},
|
|
1353
|
+
animation: true
|
|
1354
|
+
});
|
|
1355
|
+
return Number(result);
|
|
1356
|
+
};
|
|
1357
|
+
clock.cancelAnimationFrame = function cancelAnimationFrame(timerId) {
|
|
1358
|
+
return clearTimer(clock, timerId, "AnimationFrame");
|
|
1359
|
+
};
|
|
1360
|
+
clock.runMicrotasks = function runMicrotasks() {
|
|
1361
|
+
runJobs(clock);
|
|
1362
|
+
};
|
|
1363
|
+
/**
|
|
1364
|
+
* @param {number|string} tickValue milliseconds or a string parseable by parseTime
|
|
1365
|
+
* @param {boolean} isAsync
|
|
1366
|
+
* @param {Function} resolve
|
|
1367
|
+
* @param {Function} reject
|
|
1368
|
+
* @returns {number|undefined} will return the new `now` value or nothing for async
|
|
1369
|
+
*/
|
|
1370
|
+
function doTick(tickValue, isAsync, resolve, reject) {
|
|
1371
|
+
const msFloat = typeof tickValue === "number" ? tickValue : parseTime(tickValue);
|
|
1372
|
+
const ms = Math.floor(msFloat);
|
|
1373
|
+
const remainder = nanoRemainder(msFloat);
|
|
1374
|
+
let nanosTotal = nanos + remainder;
|
|
1375
|
+
let tickTo = clock.now + ms;
|
|
1376
|
+
if (msFloat < 0) throw new TypeError("Negative ticks are not supported");
|
|
1377
|
+
if (nanosTotal >= 1e6) {
|
|
1378
|
+
tickTo += 1;
|
|
1379
|
+
nanosTotal -= 1e6;
|
|
1380
|
+
}
|
|
1381
|
+
nanos = nanosTotal;
|
|
1382
|
+
let tickFrom = clock.now;
|
|
1383
|
+
let previous = clock.now;
|
|
1384
|
+
let timer, firstException, oldNow, nextPromiseTick, compensationCheck, postTimerCall;
|
|
1385
|
+
clock.duringTick = true;
|
|
1386
|
+
oldNow = clock.now;
|
|
1387
|
+
runJobs(clock);
|
|
1388
|
+
if (oldNow !== clock.now) {
|
|
1389
|
+
tickFrom += clock.now - oldNow;
|
|
1390
|
+
tickTo += clock.now - oldNow;
|
|
1391
|
+
}
|
|
1392
|
+
function doTickInner() {
|
|
1393
|
+
timer = firstTimerInRange(clock, tickFrom, tickTo);
|
|
1394
|
+
while (timer && tickFrom <= tickTo) {
|
|
1395
|
+
if (clock.timers[timer.id]) {
|
|
1396
|
+
tickFrom = timer.callAt;
|
|
1397
|
+
clock.now = timer.callAt;
|
|
1398
|
+
oldNow = clock.now;
|
|
1399
|
+
try {
|
|
1400
|
+
runJobs(clock);
|
|
1401
|
+
callTimer(clock, timer);
|
|
1402
|
+
} catch (e) {
|
|
1403
|
+
firstException = firstException || e;
|
|
1404
|
+
}
|
|
1405
|
+
if (isAsync) {
|
|
1406
|
+
originalSetTimeout(nextPromiseTick);
|
|
1407
|
+
return;
|
|
1408
|
+
}
|
|
1409
|
+
compensationCheck();
|
|
1410
|
+
}
|
|
1411
|
+
postTimerCall();
|
|
1412
|
+
}
|
|
1413
|
+
oldNow = clock.now;
|
|
1414
|
+
runJobs(clock);
|
|
1415
|
+
if (oldNow !== clock.now) {
|
|
1416
|
+
tickFrom += clock.now - oldNow;
|
|
1417
|
+
tickTo += clock.now - oldNow;
|
|
1418
|
+
}
|
|
1419
|
+
clock.duringTick = false;
|
|
1420
|
+
timer = firstTimerInRange(clock, tickFrom, tickTo);
|
|
1421
|
+
if (timer) try {
|
|
1422
|
+
clock.tick(tickTo - clock.now);
|
|
1423
|
+
} catch (e) {
|
|
1424
|
+
firstException = firstException || e;
|
|
1425
|
+
}
|
|
1426
|
+
else {
|
|
1427
|
+
clock.now = tickTo;
|
|
1428
|
+
nanos = nanosTotal;
|
|
1429
|
+
}
|
|
1430
|
+
if (firstException) throw firstException;
|
|
1431
|
+
if (isAsync) resolve(clock.now);
|
|
1432
|
+
else return clock.now;
|
|
1433
|
+
}
|
|
1434
|
+
nextPromiseTick = isAsync && function() {
|
|
1435
|
+
try {
|
|
1436
|
+
compensationCheck();
|
|
1437
|
+
postTimerCall();
|
|
1438
|
+
doTickInner();
|
|
1439
|
+
} catch (e) {
|
|
1440
|
+
reject(e);
|
|
1441
|
+
}
|
|
1442
|
+
};
|
|
1443
|
+
compensationCheck = function() {
|
|
1444
|
+
if (oldNow !== clock.now) {
|
|
1445
|
+
tickFrom += clock.now - oldNow;
|
|
1446
|
+
tickTo += clock.now - oldNow;
|
|
1447
|
+
previous += clock.now - oldNow;
|
|
1448
|
+
}
|
|
1449
|
+
};
|
|
1450
|
+
postTimerCall = function() {
|
|
1451
|
+
timer = firstTimerInRange(clock, previous, tickTo);
|
|
1452
|
+
previous = tickFrom;
|
|
1453
|
+
};
|
|
1454
|
+
return doTickInner();
|
|
1455
|
+
}
|
|
1456
|
+
/**
|
|
1457
|
+
* @param {string|number} tickValue number of milliseconds or a human-readable value like "01:11:15"
|
|
1458
|
+
* @returns {number} will return the new `now` value
|
|
1459
|
+
*/
|
|
1460
|
+
clock.tick = function tick(tickValue) {
|
|
1461
|
+
return doTick(tickValue, false);
|
|
1462
|
+
};
|
|
1463
|
+
if (typeof _global.Promise !== "undefined")
|
|
1464
|
+
/**
|
|
1465
|
+
* @param {string|number} tickValue number of milliseconds or a human-readable value like "01:11:15"
|
|
1466
|
+
* @returns {Promise}
|
|
1467
|
+
*/
|
|
1468
|
+
clock.tickAsync = function tickAsync(tickValue) {
|
|
1469
|
+
return pauseAutoTickUntilFinished(new _global.Promise(function(resolve, reject) {
|
|
1470
|
+
originalSetTimeout(function() {
|
|
1471
|
+
try {
|
|
1472
|
+
doTick(tickValue, true, resolve, reject);
|
|
1473
|
+
} catch (e) {
|
|
1474
|
+
reject(e);
|
|
1475
|
+
}
|
|
1476
|
+
});
|
|
1477
|
+
}));
|
|
1478
|
+
};
|
|
1479
|
+
clock.next = function next() {
|
|
1480
|
+
runJobs(clock);
|
|
1481
|
+
const timer = firstTimer(clock);
|
|
1482
|
+
if (!timer) return clock.now;
|
|
1483
|
+
clock.duringTick = true;
|
|
1484
|
+
try {
|
|
1485
|
+
clock.now = timer.callAt;
|
|
1486
|
+
callTimer(clock, timer);
|
|
1487
|
+
runJobs(clock);
|
|
1488
|
+
return clock.now;
|
|
1489
|
+
} finally {
|
|
1490
|
+
clock.duringTick = false;
|
|
1491
|
+
}
|
|
1492
|
+
};
|
|
1493
|
+
if (typeof _global.Promise !== "undefined") clock.nextAsync = function nextAsync() {
|
|
1494
|
+
return pauseAutoTickUntilFinished(new _global.Promise(function(resolve, reject) {
|
|
1495
|
+
originalSetTimeout(function() {
|
|
1496
|
+
try {
|
|
1497
|
+
const timer = firstTimer(clock);
|
|
1498
|
+
if (!timer) {
|
|
1499
|
+
resolve(clock.now);
|
|
1500
|
+
return;
|
|
1501
|
+
}
|
|
1502
|
+
let err;
|
|
1503
|
+
clock.duringTick = true;
|
|
1504
|
+
clock.now = timer.callAt;
|
|
1505
|
+
try {
|
|
1506
|
+
callTimer(clock, timer);
|
|
1507
|
+
} catch (e) {
|
|
1508
|
+
err = e;
|
|
1509
|
+
}
|
|
1510
|
+
clock.duringTick = false;
|
|
1511
|
+
originalSetTimeout(function() {
|
|
1512
|
+
if (err) reject(err);
|
|
1513
|
+
else resolve(clock.now);
|
|
1514
|
+
});
|
|
1515
|
+
} catch (e) {
|
|
1516
|
+
reject(e);
|
|
1517
|
+
}
|
|
1518
|
+
});
|
|
1519
|
+
}));
|
|
1520
|
+
};
|
|
1521
|
+
clock.runAll = function runAll() {
|
|
1522
|
+
let numTimers, i;
|
|
1523
|
+
runJobs(clock);
|
|
1524
|
+
for (i = 0; i < clock.loopLimit; i++) {
|
|
1525
|
+
if (!clock.timers) {
|
|
1526
|
+
resetIsNearInfiniteLimit();
|
|
1527
|
+
return clock.now;
|
|
1528
|
+
}
|
|
1529
|
+
numTimers = Object.keys(clock.timers).length;
|
|
1530
|
+
if (numTimers === 0) {
|
|
1531
|
+
resetIsNearInfiniteLimit();
|
|
1532
|
+
return clock.now;
|
|
1533
|
+
}
|
|
1534
|
+
clock.next();
|
|
1535
|
+
checkIsNearInfiniteLimit(clock, i);
|
|
1536
|
+
}
|
|
1537
|
+
const excessJob = firstTimer(clock);
|
|
1538
|
+
throw getInfiniteLoopError(clock, excessJob);
|
|
1539
|
+
};
|
|
1540
|
+
clock.runToFrame = function runToFrame() {
|
|
1541
|
+
return clock.tick(getTimeToNextFrame());
|
|
1542
|
+
};
|
|
1543
|
+
if (typeof _global.Promise !== "undefined") clock.runAllAsync = function runAllAsync() {
|
|
1544
|
+
return pauseAutoTickUntilFinished(new _global.Promise(function(resolve, reject) {
|
|
1545
|
+
let i = 0;
|
|
1546
|
+
/**
|
|
1547
|
+
*
|
|
1548
|
+
*/
|
|
1549
|
+
function doRun() {
|
|
1550
|
+
originalSetTimeout(function() {
|
|
1551
|
+
try {
|
|
1552
|
+
runJobs(clock);
|
|
1553
|
+
let numTimers;
|
|
1554
|
+
if (i < clock.loopLimit) {
|
|
1555
|
+
if (!clock.timers) {
|
|
1556
|
+
resetIsNearInfiniteLimit();
|
|
1557
|
+
resolve(clock.now);
|
|
1558
|
+
return;
|
|
1559
|
+
}
|
|
1560
|
+
numTimers = Object.keys(clock.timers).length;
|
|
1561
|
+
if (numTimers === 0) {
|
|
1562
|
+
resetIsNearInfiniteLimit();
|
|
1563
|
+
resolve(clock.now);
|
|
1564
|
+
return;
|
|
1565
|
+
}
|
|
1566
|
+
clock.next();
|
|
1567
|
+
i++;
|
|
1568
|
+
doRun();
|
|
1569
|
+
checkIsNearInfiniteLimit(clock, i);
|
|
1570
|
+
return;
|
|
1571
|
+
}
|
|
1572
|
+
const excessJob = firstTimer(clock);
|
|
1573
|
+
reject(getInfiniteLoopError(clock, excessJob));
|
|
1574
|
+
} catch (e) {
|
|
1575
|
+
reject(e);
|
|
1576
|
+
}
|
|
1577
|
+
});
|
|
1578
|
+
}
|
|
1579
|
+
doRun();
|
|
1580
|
+
}));
|
|
1581
|
+
};
|
|
1582
|
+
clock.runToLast = function runToLast() {
|
|
1583
|
+
const timer = lastTimer(clock);
|
|
1584
|
+
if (!timer) {
|
|
1585
|
+
runJobs(clock);
|
|
1586
|
+
return clock.now;
|
|
1587
|
+
}
|
|
1588
|
+
return clock.tick(timer.callAt - clock.now);
|
|
1589
|
+
};
|
|
1590
|
+
if (typeof _global.Promise !== "undefined") clock.runToLastAsync = function runToLastAsync() {
|
|
1591
|
+
return pauseAutoTickUntilFinished(new _global.Promise(function(resolve, reject) {
|
|
1592
|
+
originalSetTimeout(function() {
|
|
1593
|
+
try {
|
|
1594
|
+
const timer = lastTimer(clock);
|
|
1595
|
+
if (!timer) {
|
|
1596
|
+
runJobs(clock);
|
|
1597
|
+
resolve(clock.now);
|
|
1598
|
+
}
|
|
1599
|
+
resolve(clock.tickAsync(timer.callAt - clock.now));
|
|
1600
|
+
} catch (e) {
|
|
1601
|
+
reject(e);
|
|
1602
|
+
}
|
|
1603
|
+
});
|
|
1604
|
+
}));
|
|
1605
|
+
};
|
|
1606
|
+
clock.reset = function reset() {
|
|
1607
|
+
nanos = 0;
|
|
1608
|
+
clock.timers = {};
|
|
1609
|
+
clock.jobs = [];
|
|
1610
|
+
clock.now = start;
|
|
1611
|
+
};
|
|
1612
|
+
clock.setSystemTime = function setSystemTime(systemTime) {
|
|
1613
|
+
const newNow = getEpoch(systemTime);
|
|
1614
|
+
const difference = newNow - clock.now;
|
|
1615
|
+
let id, timer;
|
|
1616
|
+
adjustedSystemTime[0] = adjustedSystemTime[0] + difference;
|
|
1617
|
+
adjustedSystemTime[1] = adjustedSystemTime[1] + nanos;
|
|
1618
|
+
clock.now = newNow;
|
|
1619
|
+
nanos = 0;
|
|
1620
|
+
for (id in clock.timers) if (clock.timers.hasOwnProperty(id)) {
|
|
1621
|
+
timer = clock.timers[id];
|
|
1622
|
+
timer.createdAt += difference;
|
|
1623
|
+
timer.callAt += difference;
|
|
1624
|
+
}
|
|
1625
|
+
};
|
|
1626
|
+
/**
|
|
1627
|
+
* @param {string|number} tickValue number of milliseconds or a human-readable value like "01:11:15"
|
|
1628
|
+
* @returns {number} will return the new `now` value
|
|
1629
|
+
*/
|
|
1630
|
+
clock.jump = function jump(tickValue) {
|
|
1631
|
+
const msFloat = typeof tickValue === "number" ? tickValue : parseTime(tickValue);
|
|
1632
|
+
const ms = Math.floor(msFloat);
|
|
1633
|
+
for (const timer of Object.values(clock.timers)) if (clock.now + ms > timer.callAt) timer.callAt = clock.now + ms;
|
|
1634
|
+
clock.tick(ms);
|
|
1635
|
+
};
|
|
1636
|
+
if (isPresent.performance) {
|
|
1637
|
+
clock.performance = Object.create(null);
|
|
1638
|
+
clock.performance.now = fakePerformanceNow;
|
|
1639
|
+
}
|
|
1640
|
+
if (isPresent.hrtime) clock.hrtime = hrtime;
|
|
1641
|
+
return clock;
|
|
1642
|
+
}
|
|
1643
|
+
function createIntervalTick(clock, delta) {
|
|
1644
|
+
const intervalTick = doIntervalTick.bind(null, clock, delta);
|
|
1645
|
+
clock.attachedInterval = originalSetInterval(intervalTick, delta);
|
|
1646
|
+
}
|
|
1647
|
+
/**
|
|
1648
|
+
* @param {Config=} [config] Optional config
|
|
1649
|
+
* @returns {Clock}
|
|
1650
|
+
*/
|
|
1651
|
+
function install(config) {
|
|
1652
|
+
if (arguments.length > 1 || config instanceof Date || Array.isArray(config) || typeof config === "number") throw new TypeError(`FakeTimers.install called with ${String(config)} install requires an object parameter`);
|
|
1653
|
+
if (_global.Date.isFake === true) throw new TypeError("Can't install fake timers twice on the same global object.");
|
|
1654
|
+
config = typeof config !== "undefined" ? config : {};
|
|
1655
|
+
config.shouldAdvanceTime = config.shouldAdvanceTime || false;
|
|
1656
|
+
config.advanceTimeDelta = config.advanceTimeDelta || 20;
|
|
1657
|
+
config.shouldClearNativeTimers = config.shouldClearNativeTimers || false;
|
|
1658
|
+
if (config.target) throw new TypeError("config.target is no longer supported. Use `withGlobal(target)` instead.");
|
|
1659
|
+
/**
|
|
1660
|
+
* @param {string} timer/object the name of the thing that is not present
|
|
1661
|
+
* @param timer
|
|
1662
|
+
*/
|
|
1663
|
+
function handleMissingTimer(timer) {
|
|
1664
|
+
if (config.ignoreMissingTimers) return;
|
|
1665
|
+
throw new ReferenceError(`non-existent timers and/or objects cannot be faked: '${timer}'`);
|
|
1666
|
+
}
|
|
1667
|
+
let i, l;
|
|
1668
|
+
const clock = createClock(config.now, config.loopLimit);
|
|
1669
|
+
clock.shouldClearNativeTimers = config.shouldClearNativeTimers;
|
|
1670
|
+
clock.uninstall = function() {
|
|
1671
|
+
return uninstall(clock);
|
|
1672
|
+
};
|
|
1673
|
+
clock.abortListenerMap = /* @__PURE__ */ new Map();
|
|
1674
|
+
clock.methods = config.toFake || [];
|
|
1675
|
+
if (clock.methods.length === 0) clock.methods = Object.keys(timers);
|
|
1676
|
+
if (config.shouldAdvanceTime === true) clock.setTickMode({
|
|
1677
|
+
mode: "interval",
|
|
1678
|
+
delta: config.advanceTimeDelta
|
|
1679
|
+
});
|
|
1680
|
+
if (clock.methods.includes("performance")) {
|
|
1681
|
+
const proto = (() => {
|
|
1682
|
+
if (hasPerformanceConstructorPrototype) return _global.performance.constructor.prototype;
|
|
1683
|
+
if (hasPerformancePrototype) return _global.Performance.prototype;
|
|
1684
|
+
})();
|
|
1685
|
+
if (proto) {
|
|
1686
|
+
Object.getOwnPropertyNames(proto).forEach(function(name) {
|
|
1687
|
+
if (name !== "now") clock.performance[name] = name.indexOf("getEntries") === 0 ? NOOP_ARRAY : NOOP;
|
|
1688
|
+
});
|
|
1689
|
+
clock.performance.mark = (name) => new FakePerformanceEntry(name, "mark", 0, 0);
|
|
1690
|
+
clock.performance.measure = (name) => new FakePerformanceEntry(name, "measure", 0, 100);
|
|
1691
|
+
clock.performance.timeOrigin = getEpoch(config.now);
|
|
1692
|
+
} else if ((config.toFake || []).includes("performance")) return handleMissingTimer("performance");
|
|
1693
|
+
}
|
|
1694
|
+
if (_global === globalObject && timersModule) clock.timersModuleMethods = [];
|
|
1695
|
+
if (_global === globalObject && timersPromisesModule) clock.timersPromisesModuleMethods = [];
|
|
1696
|
+
for (i = 0, l = clock.methods.length; i < l; i++) {
|
|
1697
|
+
const nameOfMethodToReplace = clock.methods[i];
|
|
1698
|
+
if (!isPresent[nameOfMethodToReplace]) {
|
|
1699
|
+
handleMissingTimer(nameOfMethodToReplace);
|
|
1700
|
+
continue;
|
|
1701
|
+
}
|
|
1702
|
+
if (nameOfMethodToReplace === "hrtime") {
|
|
1703
|
+
if (_global.process && typeof _global.process.hrtime === "function") hijackMethod(_global.process, nameOfMethodToReplace, clock);
|
|
1704
|
+
} else if (nameOfMethodToReplace === "nextTick") {
|
|
1705
|
+
if (_global.process && typeof _global.process.nextTick === "function") hijackMethod(_global.process, nameOfMethodToReplace, clock);
|
|
1706
|
+
} else hijackMethod(_global, nameOfMethodToReplace, clock);
|
|
1707
|
+
if (clock.timersModuleMethods !== void 0 && timersModule[nameOfMethodToReplace]) {
|
|
1708
|
+
const original = timersModule[nameOfMethodToReplace];
|
|
1709
|
+
clock.timersModuleMethods.push({
|
|
1710
|
+
methodName: nameOfMethodToReplace,
|
|
1711
|
+
original
|
|
1712
|
+
});
|
|
1713
|
+
timersModule[nameOfMethodToReplace] = _global[nameOfMethodToReplace];
|
|
1714
|
+
}
|
|
1715
|
+
if (clock.timersPromisesModuleMethods !== void 0) {
|
|
1716
|
+
if (nameOfMethodToReplace === "setTimeout") {
|
|
1717
|
+
clock.timersPromisesModuleMethods.push({
|
|
1718
|
+
methodName: "setTimeout",
|
|
1719
|
+
original: timersPromisesModule.setTimeout
|
|
1720
|
+
});
|
|
1721
|
+
timersPromisesModule.setTimeout = (delay, value, options = {}) => new Promise((resolve, reject) => {
|
|
1722
|
+
const abort = () => {
|
|
1723
|
+
options.signal.removeEventListener("abort", abort);
|
|
1724
|
+
clock.abortListenerMap.delete(abort);
|
|
1725
|
+
clock.clearTimeout(handle);
|
|
1726
|
+
reject(options.signal.reason);
|
|
1727
|
+
};
|
|
1728
|
+
const handle = clock.setTimeout(() => {
|
|
1729
|
+
if (options.signal) {
|
|
1730
|
+
options.signal.removeEventListener("abort", abort);
|
|
1731
|
+
clock.abortListenerMap.delete(abort);
|
|
1732
|
+
}
|
|
1733
|
+
resolve(value);
|
|
1734
|
+
}, delay);
|
|
1735
|
+
if (options.signal) if (options.signal.aborted) abort();
|
|
1736
|
+
else {
|
|
1737
|
+
options.signal.addEventListener("abort", abort);
|
|
1738
|
+
clock.abortListenerMap.set(abort, options.signal);
|
|
1739
|
+
}
|
|
1740
|
+
});
|
|
1741
|
+
} else if (nameOfMethodToReplace === "setImmediate") {
|
|
1742
|
+
clock.timersPromisesModuleMethods.push({
|
|
1743
|
+
methodName: "setImmediate",
|
|
1744
|
+
original: timersPromisesModule.setImmediate
|
|
1745
|
+
});
|
|
1746
|
+
timersPromisesModule.setImmediate = (value, options = {}) => new Promise((resolve, reject) => {
|
|
1747
|
+
const abort = () => {
|
|
1748
|
+
options.signal.removeEventListener("abort", abort);
|
|
1749
|
+
clock.abortListenerMap.delete(abort);
|
|
1750
|
+
clock.clearImmediate(handle);
|
|
1751
|
+
reject(options.signal.reason);
|
|
1752
|
+
};
|
|
1753
|
+
const handle = clock.setImmediate(() => {
|
|
1754
|
+
if (options.signal) {
|
|
1755
|
+
options.signal.removeEventListener("abort", abort);
|
|
1756
|
+
clock.abortListenerMap.delete(abort);
|
|
1757
|
+
}
|
|
1758
|
+
resolve(value);
|
|
1759
|
+
});
|
|
1760
|
+
if (options.signal) if (options.signal.aborted) abort();
|
|
1761
|
+
else {
|
|
1762
|
+
options.signal.addEventListener("abort", abort);
|
|
1763
|
+
clock.abortListenerMap.set(abort, options.signal);
|
|
1764
|
+
}
|
|
1765
|
+
});
|
|
1766
|
+
} else if (nameOfMethodToReplace === "setInterval") {
|
|
1767
|
+
clock.timersPromisesModuleMethods.push({
|
|
1768
|
+
methodName: "setInterval",
|
|
1769
|
+
original: timersPromisesModule.setInterval
|
|
1770
|
+
});
|
|
1771
|
+
timersPromisesModule.setInterval = (delay, value, options = {}) => ({ [Symbol.asyncIterator]: () => {
|
|
1772
|
+
const createResolvable = () => {
|
|
1773
|
+
let resolve, reject;
|
|
1774
|
+
const promise = new Promise((res, rej) => {
|
|
1775
|
+
resolve = res;
|
|
1776
|
+
reject = rej;
|
|
1777
|
+
});
|
|
1778
|
+
promise.resolve = resolve;
|
|
1779
|
+
promise.reject = reject;
|
|
1780
|
+
return promise;
|
|
1781
|
+
};
|
|
1782
|
+
let done = false;
|
|
1783
|
+
let hasThrown = false;
|
|
1784
|
+
let returnCall;
|
|
1785
|
+
let nextAvailable = 0;
|
|
1786
|
+
const nextQueue = [];
|
|
1787
|
+
const handle = clock.setInterval(() => {
|
|
1788
|
+
if (nextQueue.length > 0) nextQueue.shift().resolve();
|
|
1789
|
+
else nextAvailable++;
|
|
1790
|
+
}, delay);
|
|
1791
|
+
const abort = () => {
|
|
1792
|
+
options.signal.removeEventListener("abort", abort);
|
|
1793
|
+
clock.abortListenerMap.delete(abort);
|
|
1794
|
+
clock.clearInterval(handle);
|
|
1795
|
+
done = true;
|
|
1796
|
+
for (const resolvable of nextQueue) resolvable.resolve();
|
|
1797
|
+
};
|
|
1798
|
+
if (options.signal) if (options.signal.aborted) done = true;
|
|
1799
|
+
else {
|
|
1800
|
+
options.signal.addEventListener("abort", abort);
|
|
1801
|
+
clock.abortListenerMap.set(abort, options.signal);
|
|
1802
|
+
}
|
|
1803
|
+
return {
|
|
1804
|
+
next: async () => {
|
|
1805
|
+
if (options.signal?.aborted && !hasThrown) {
|
|
1806
|
+
hasThrown = true;
|
|
1807
|
+
throw options.signal.reason;
|
|
1808
|
+
}
|
|
1809
|
+
if (done) return {
|
|
1810
|
+
done: true,
|
|
1811
|
+
value: void 0
|
|
1812
|
+
};
|
|
1813
|
+
if (nextAvailable > 0) {
|
|
1814
|
+
nextAvailable--;
|
|
1815
|
+
return {
|
|
1816
|
+
done: false,
|
|
1817
|
+
value
|
|
1818
|
+
};
|
|
1819
|
+
}
|
|
1820
|
+
const resolvable = createResolvable();
|
|
1821
|
+
nextQueue.push(resolvable);
|
|
1822
|
+
await resolvable;
|
|
1823
|
+
if (returnCall && nextQueue.length === 0) returnCall.resolve();
|
|
1824
|
+
if (options.signal?.aborted && !hasThrown) {
|
|
1825
|
+
hasThrown = true;
|
|
1826
|
+
throw options.signal.reason;
|
|
1827
|
+
}
|
|
1828
|
+
if (done) return {
|
|
1829
|
+
done: true,
|
|
1830
|
+
value: void 0
|
|
1831
|
+
};
|
|
1832
|
+
return {
|
|
1833
|
+
done: false,
|
|
1834
|
+
value
|
|
1835
|
+
};
|
|
1836
|
+
},
|
|
1837
|
+
return: async () => {
|
|
1838
|
+
if (done) return {
|
|
1839
|
+
done: true,
|
|
1840
|
+
value: void 0
|
|
1841
|
+
};
|
|
1842
|
+
if (nextQueue.length > 0) {
|
|
1843
|
+
returnCall = createResolvable();
|
|
1844
|
+
await returnCall;
|
|
1845
|
+
}
|
|
1846
|
+
clock.clearInterval(handle);
|
|
1847
|
+
done = true;
|
|
1848
|
+
if (options.signal) {
|
|
1849
|
+
options.signal.removeEventListener("abort", abort);
|
|
1850
|
+
clock.abortListenerMap.delete(abort);
|
|
1851
|
+
}
|
|
1852
|
+
return {
|
|
1853
|
+
done: true,
|
|
1854
|
+
value: void 0
|
|
1855
|
+
};
|
|
1856
|
+
}
|
|
1857
|
+
};
|
|
1858
|
+
} });
|
|
1859
|
+
}
|
|
1860
|
+
}
|
|
1861
|
+
}
|
|
1862
|
+
return clock;
|
|
1863
|
+
}
|
|
1864
|
+
return {
|
|
1865
|
+
timers,
|
|
1866
|
+
createClock,
|
|
1867
|
+
install,
|
|
1868
|
+
withGlobal
|
|
1869
|
+
};
|
|
1870
|
+
}
|
|
1871
|
+
/**
|
|
1872
|
+
* @typedef {object} FakeTimers
|
|
1873
|
+
* @property {Timers} timers
|
|
1874
|
+
* @property {createClock} createClock
|
|
1875
|
+
* @property {Function} install
|
|
1876
|
+
* @property {withGlobal} withGlobal
|
|
1877
|
+
*/
|
|
1878
|
+
/** @type {FakeTimers} */
|
|
1879
|
+
const defaultImplementation = withGlobal(globalObject);
|
|
1880
|
+
fakeTimersSrc.timers = defaultImplementation.timers;
|
|
1881
|
+
fakeTimersSrc.createClock = defaultImplementation.createClock;
|
|
1882
|
+
fakeTimersSrc.install = defaultImplementation.install;
|
|
1883
|
+
fakeTimersSrc.withGlobal = withGlobal;
|
|
1884
|
+
return fakeTimersSrc;
|
|
1885
|
+
}
|
|
1886
|
+
var fakeTimersSrcExports = requireFakeTimersSrc();
|
|
1887
|
+
var FakeTimers = class {
|
|
1888
|
+
_global;
|
|
1889
|
+
_clock;
|
|
1890
|
+
_fakingTime;
|
|
1891
|
+
_fakingDate;
|
|
1892
|
+
_fakeTimers;
|
|
1893
|
+
_userConfig;
|
|
1894
|
+
_now = RealDate.now;
|
|
1895
|
+
constructor({ global, config }) {
|
|
1896
|
+
this._userConfig = config;
|
|
1897
|
+
this._fakingDate = null;
|
|
1898
|
+
this._fakingTime = false;
|
|
1899
|
+
this._fakeTimers = fakeTimersSrcExports.withGlobal(global);
|
|
1900
|
+
this._global = global;
|
|
1901
|
+
}
|
|
1902
|
+
clearAllTimers() {
|
|
1903
|
+
if (this._fakingTime) this._clock.reset();
|
|
1904
|
+
}
|
|
1905
|
+
dispose() {
|
|
1906
|
+
this.useRealTimers();
|
|
1907
|
+
}
|
|
1908
|
+
runAllTimers() {
|
|
1909
|
+
if (this._checkFakeTimers()) this._clock.runAll();
|
|
1910
|
+
}
|
|
1911
|
+
async runAllTimersAsync() {
|
|
1912
|
+
if (this._checkFakeTimers()) await this._clock.runAllAsync();
|
|
1913
|
+
}
|
|
1914
|
+
runOnlyPendingTimers() {
|
|
1915
|
+
if (this._checkFakeTimers()) this._clock.runToLast();
|
|
1916
|
+
}
|
|
1917
|
+
async runOnlyPendingTimersAsync() {
|
|
1918
|
+
if (this._checkFakeTimers()) await this._clock.runToLastAsync();
|
|
1919
|
+
}
|
|
1920
|
+
advanceTimersToNextTimer(steps = 1) {
|
|
1921
|
+
if (this._checkFakeTimers()) for (let i = steps; i > 0; i--) {
|
|
1922
|
+
this._clock.next();
|
|
1923
|
+
this._clock.tick(0);
|
|
1924
|
+
if (this._clock.countTimers() === 0) break;
|
|
1925
|
+
}
|
|
1926
|
+
}
|
|
1927
|
+
async advanceTimersToNextTimerAsync(steps = 1) {
|
|
1928
|
+
if (this._checkFakeTimers()) for (let i = steps; i > 0; i--) {
|
|
1929
|
+
await this._clock.nextAsync();
|
|
1930
|
+
this._clock.tick(0);
|
|
1931
|
+
if (this._clock.countTimers() === 0) break;
|
|
1932
|
+
}
|
|
1933
|
+
}
|
|
1934
|
+
advanceTimersByTime(msToRun) {
|
|
1935
|
+
if (this._checkFakeTimers()) this._clock.tick(msToRun);
|
|
1936
|
+
}
|
|
1937
|
+
async advanceTimersByTimeAsync(msToRun) {
|
|
1938
|
+
if (this._checkFakeTimers()) await this._clock.tickAsync(msToRun);
|
|
1939
|
+
}
|
|
1940
|
+
advanceTimersToNextFrame() {
|
|
1941
|
+
if (this._checkFakeTimers()) this._clock.runToFrame();
|
|
1942
|
+
}
|
|
1943
|
+
runAllTicks() {
|
|
1944
|
+
if (this._checkFakeTimers()) this._clock.runMicrotasks();
|
|
1945
|
+
}
|
|
1946
|
+
useRealTimers() {
|
|
1947
|
+
if (this._fakingDate) {
|
|
1948
|
+
resetDate();
|
|
1949
|
+
this._fakingDate = null;
|
|
1950
|
+
}
|
|
1951
|
+
if (this._fakingTime) {
|
|
1952
|
+
this._clock.uninstall();
|
|
1953
|
+
this._fakingTime = false;
|
|
1954
|
+
}
|
|
1955
|
+
}
|
|
1956
|
+
useFakeTimers() {
|
|
1957
|
+
const fakeDate = this._fakingDate || Date.now();
|
|
1958
|
+
if (this._fakingDate) {
|
|
1959
|
+
resetDate();
|
|
1960
|
+
this._fakingDate = null;
|
|
1961
|
+
}
|
|
1962
|
+
if (this._fakingTime) this._clock.uninstall();
|
|
1963
|
+
const toFake = Object.keys(this._fakeTimers.timers).filter((timer) => timer !== "nextTick" && timer !== "queueMicrotask");
|
|
1964
|
+
if (this._userConfig?.toFake?.includes("nextTick") && isChildProcess()) throw new Error("process.nextTick cannot be mocked inside child_process");
|
|
1965
|
+
this._clock = this._fakeTimers.install({
|
|
1966
|
+
now: fakeDate,
|
|
1967
|
+
...this._userConfig,
|
|
1968
|
+
toFake: this._userConfig?.toFake || toFake,
|
|
1969
|
+
ignoreMissingTimers: true
|
|
1970
|
+
});
|
|
1971
|
+
this._fakingTime = true;
|
|
1972
|
+
}
|
|
1973
|
+
reset() {
|
|
1974
|
+
if (this._checkFakeTimers()) {
|
|
1975
|
+
const { now } = this._clock;
|
|
1976
|
+
this._clock.reset();
|
|
1977
|
+
this._clock.setSystemTime(now);
|
|
1978
|
+
}
|
|
1979
|
+
}
|
|
1980
|
+
setSystemTime(now) {
|
|
1981
|
+
const date = typeof now === "undefined" || now instanceof Date ? now : new Date(now);
|
|
1982
|
+
if (this._fakingTime) this._clock.setSystemTime(date);
|
|
1983
|
+
else {
|
|
1984
|
+
this._fakingDate = date ?? new Date(this.getRealSystemTime());
|
|
1985
|
+
mockDate(this._fakingDate);
|
|
1986
|
+
}
|
|
1987
|
+
}
|
|
1988
|
+
getMockedSystemTime() {
|
|
1989
|
+
return this._fakingTime ? new Date(this._clock.now) : this._fakingDate;
|
|
1990
|
+
}
|
|
1991
|
+
getRealSystemTime() {
|
|
1992
|
+
return this._now();
|
|
1993
|
+
}
|
|
1994
|
+
getTimerCount() {
|
|
1995
|
+
if (this._checkFakeTimers()) return this._clock.countTimers();
|
|
1996
|
+
return 0;
|
|
1997
|
+
}
|
|
1998
|
+
setTimerTickMode(mode, interval) {
|
|
1999
|
+
if (this._checkFakeTimers()) if (mode === "manual") this._clock.setTickMode({ mode: "manual" });
|
|
2000
|
+
else if (mode === "nextTimerAsync") this._clock.setTickMode({ mode: "nextAsync" });
|
|
2001
|
+
else if (mode === "interval") this._clock.setTickMode({
|
|
2002
|
+
mode: "interval",
|
|
2003
|
+
delta: interval
|
|
2004
|
+
});
|
|
2005
|
+
else throw new Error(`Invalid tick mode: ${mode}`);
|
|
2006
|
+
}
|
|
2007
|
+
configure(config) {
|
|
2008
|
+
this._userConfig = config;
|
|
2009
|
+
}
|
|
2010
|
+
isFakeTimers() {
|
|
2011
|
+
return this._fakingTime;
|
|
2012
|
+
}
|
|
2013
|
+
_checkFakeTimers() {
|
|
2014
|
+
if (!this._fakingTime) throw new Error("A function to advance timers was called but the timers APIs are not mocked. Call `vi.useFakeTimers()` in the test file first.");
|
|
2015
|
+
return this._fakingTime;
|
|
2016
|
+
}
|
|
2017
|
+
};
|
|
2018
|
+
function copyStackTrace$1(target, source) {
|
|
2019
|
+
if (source.stack !== void 0) target.stack = source.stack.replace(source.message, target.message);
|
|
2020
|
+
return target;
|
|
2021
|
+
}
|
|
2022
|
+
function waitFor(callback, options = {}) {
|
|
2023
|
+
const { setTimeout, setInterval, clearTimeout, clearInterval } = getSafeTimers();
|
|
2024
|
+
const { interval = 50, timeout = 1e3 } = typeof options === "number" ? { timeout: options } : options;
|
|
2025
|
+
const STACK_TRACE_ERROR = /* @__PURE__ */ new Error("STACK_TRACE_ERROR");
|
|
2026
|
+
return new Promise((resolve, reject) => {
|
|
2027
|
+
let lastError;
|
|
2028
|
+
let promiseStatus = "idle";
|
|
2029
|
+
let timeoutId;
|
|
2030
|
+
let intervalId;
|
|
2031
|
+
const onResolve = (result) => {
|
|
2032
|
+
if (timeoutId) clearTimeout(timeoutId);
|
|
2033
|
+
if (intervalId) clearInterval(intervalId);
|
|
2034
|
+
resolve(result);
|
|
2035
|
+
};
|
|
2036
|
+
const handleTimeout = () => {
|
|
2037
|
+
if (intervalId) clearInterval(intervalId);
|
|
2038
|
+
let error = lastError;
|
|
2039
|
+
if (!error) error = copyStackTrace$1(/* @__PURE__ */ new Error("Timed out in waitFor!"), STACK_TRACE_ERROR);
|
|
2040
|
+
reject(error);
|
|
2041
|
+
};
|
|
2042
|
+
const checkCallback = () => {
|
|
2043
|
+
if (vi.isFakeTimers()) vi.advanceTimersByTime(interval);
|
|
2044
|
+
if (promiseStatus === "pending") return;
|
|
2045
|
+
try {
|
|
2046
|
+
const result = callback();
|
|
2047
|
+
if (result !== null && typeof result === "object" && typeof result.then === "function") {
|
|
2048
|
+
const thenable = result;
|
|
2049
|
+
promiseStatus = "pending";
|
|
2050
|
+
thenable.then((resolvedValue) => {
|
|
2051
|
+
promiseStatus = "resolved";
|
|
2052
|
+
onResolve(resolvedValue);
|
|
2053
|
+
}, (rejectedValue) => {
|
|
2054
|
+
promiseStatus = "rejected";
|
|
2055
|
+
lastError = rejectedValue;
|
|
2056
|
+
});
|
|
2057
|
+
} else {
|
|
2058
|
+
onResolve(result);
|
|
2059
|
+
return true;
|
|
2060
|
+
}
|
|
2061
|
+
} catch (error) {
|
|
2062
|
+
lastError = error;
|
|
2063
|
+
}
|
|
2064
|
+
};
|
|
2065
|
+
if (checkCallback() === true) return;
|
|
2066
|
+
timeoutId = setTimeout(handleTimeout, timeout);
|
|
2067
|
+
intervalId = setInterval(checkCallback, interval);
|
|
2068
|
+
});
|
|
2069
|
+
}
|
|
2070
|
+
function waitUntil(callback, options = {}) {
|
|
2071
|
+
const { setTimeout, setInterval, clearTimeout, clearInterval } = getSafeTimers();
|
|
2072
|
+
const { interval = 50, timeout = 1e3 } = typeof options === "number" ? { timeout: options } : options;
|
|
2073
|
+
const STACK_TRACE_ERROR = /* @__PURE__ */ new Error("STACK_TRACE_ERROR");
|
|
2074
|
+
return new Promise((resolve, reject) => {
|
|
2075
|
+
let promiseStatus = "idle";
|
|
2076
|
+
let timeoutId;
|
|
2077
|
+
let intervalId;
|
|
2078
|
+
const onReject = (error) => {
|
|
2079
|
+
if (intervalId) clearInterval(intervalId);
|
|
2080
|
+
if (!error) error = copyStackTrace$1(/* @__PURE__ */ new Error("Timed out in waitUntil!"), STACK_TRACE_ERROR);
|
|
2081
|
+
reject(error);
|
|
2082
|
+
};
|
|
2083
|
+
const onResolve = (result) => {
|
|
2084
|
+
if (!result) return;
|
|
2085
|
+
if (timeoutId) clearTimeout(timeoutId);
|
|
2086
|
+
if (intervalId) clearInterval(intervalId);
|
|
2087
|
+
resolve(result);
|
|
2088
|
+
return true;
|
|
2089
|
+
};
|
|
2090
|
+
const checkCallback = () => {
|
|
2091
|
+
if (vi.isFakeTimers()) vi.advanceTimersByTime(interval);
|
|
2092
|
+
if (promiseStatus === "pending") return;
|
|
2093
|
+
try {
|
|
2094
|
+
const result = callback();
|
|
2095
|
+
if (result !== null && typeof result === "object" && typeof result.then === "function") {
|
|
2096
|
+
const thenable = result;
|
|
2097
|
+
promiseStatus = "pending";
|
|
2098
|
+
thenable.then((resolvedValue) => {
|
|
2099
|
+
promiseStatus = "resolved";
|
|
2100
|
+
onResolve(resolvedValue);
|
|
2101
|
+
}, (rejectedValue) => {
|
|
2102
|
+
promiseStatus = "rejected";
|
|
2103
|
+
onReject(rejectedValue);
|
|
2104
|
+
});
|
|
2105
|
+
} else return onResolve(result);
|
|
2106
|
+
} catch (error) {
|
|
2107
|
+
onReject(error);
|
|
2108
|
+
}
|
|
2109
|
+
};
|
|
2110
|
+
if (checkCallback() === true) return;
|
|
2111
|
+
timeoutId = setTimeout(onReject, timeout);
|
|
2112
|
+
intervalId = setInterval(checkCallback, interval);
|
|
2113
|
+
});
|
|
2114
|
+
}
|
|
2115
|
+
function createVitest() {
|
|
2116
|
+
let _config = null;
|
|
2117
|
+
const state = () => getWorkerState();
|
|
2118
|
+
let _timers;
|
|
2119
|
+
const timers = () => _timers ||= new FakeTimers({
|
|
2120
|
+
global: globalThis,
|
|
2121
|
+
config: state().config.fakeTimers
|
|
2122
|
+
});
|
|
2123
|
+
const _stubsGlobal = /* @__PURE__ */ new Map();
|
|
2124
|
+
const _stubsEnv = /* @__PURE__ */ new Map();
|
|
2125
|
+
const _envBooleans = [
|
|
2126
|
+
"PROD",
|
|
2127
|
+
"DEV",
|
|
2128
|
+
"SSR"
|
|
2129
|
+
];
|
|
2130
|
+
const utils = {
|
|
2131
|
+
useFakeTimers(config) {
|
|
2132
|
+
if (isChildProcess()) {
|
|
2133
|
+
if (config?.toFake?.includes("nextTick") || state().config?.fakeTimers?.toFake?.includes("nextTick")) throw new Error("vi.useFakeTimers({ toFake: [\"nextTick\"] }) is not supported in node:child_process. Use --pool=threads if mocking nextTick is required.");
|
|
2134
|
+
}
|
|
2135
|
+
if (config) timers().configure({
|
|
2136
|
+
...state().config.fakeTimers,
|
|
2137
|
+
...config
|
|
2138
|
+
});
|
|
2139
|
+
else timers().configure(state().config.fakeTimers);
|
|
2140
|
+
timers().useFakeTimers();
|
|
2141
|
+
return utils;
|
|
2142
|
+
},
|
|
2143
|
+
isFakeTimers() {
|
|
2144
|
+
return timers().isFakeTimers();
|
|
2145
|
+
},
|
|
2146
|
+
useRealTimers() {
|
|
2147
|
+
timers().useRealTimers();
|
|
2148
|
+
return utils;
|
|
2149
|
+
},
|
|
2150
|
+
runOnlyPendingTimers() {
|
|
2151
|
+
timers().runOnlyPendingTimers();
|
|
2152
|
+
return utils;
|
|
2153
|
+
},
|
|
2154
|
+
async runOnlyPendingTimersAsync() {
|
|
2155
|
+
await timers().runOnlyPendingTimersAsync();
|
|
2156
|
+
return utils;
|
|
2157
|
+
},
|
|
2158
|
+
runAllTimers() {
|
|
2159
|
+
timers().runAllTimers();
|
|
2160
|
+
return utils;
|
|
2161
|
+
},
|
|
2162
|
+
async runAllTimersAsync() {
|
|
2163
|
+
await timers().runAllTimersAsync();
|
|
2164
|
+
return utils;
|
|
2165
|
+
},
|
|
2166
|
+
runAllTicks() {
|
|
2167
|
+
timers().runAllTicks();
|
|
2168
|
+
return utils;
|
|
2169
|
+
},
|
|
2170
|
+
advanceTimersByTime(ms) {
|
|
2171
|
+
timers().advanceTimersByTime(ms);
|
|
2172
|
+
return utils;
|
|
2173
|
+
},
|
|
2174
|
+
async advanceTimersByTimeAsync(ms) {
|
|
2175
|
+
await timers().advanceTimersByTimeAsync(ms);
|
|
2176
|
+
return utils;
|
|
2177
|
+
},
|
|
2178
|
+
advanceTimersToNextTimer() {
|
|
2179
|
+
timers().advanceTimersToNextTimer();
|
|
2180
|
+
return utils;
|
|
2181
|
+
},
|
|
2182
|
+
async advanceTimersToNextTimerAsync() {
|
|
2183
|
+
await timers().advanceTimersToNextTimerAsync();
|
|
2184
|
+
return utils;
|
|
2185
|
+
},
|
|
2186
|
+
advanceTimersToNextFrame() {
|
|
2187
|
+
timers().advanceTimersToNextFrame();
|
|
2188
|
+
return utils;
|
|
2189
|
+
},
|
|
2190
|
+
getTimerCount() {
|
|
2191
|
+
return timers().getTimerCount();
|
|
2192
|
+
},
|
|
2193
|
+
setSystemTime(time) {
|
|
2194
|
+
timers().setSystemTime(time);
|
|
2195
|
+
return utils;
|
|
2196
|
+
},
|
|
2197
|
+
getMockedSystemTime() {
|
|
2198
|
+
return timers().getMockedSystemTime();
|
|
2199
|
+
},
|
|
2200
|
+
getRealSystemTime() {
|
|
2201
|
+
return timers().getRealSystemTime();
|
|
2202
|
+
},
|
|
2203
|
+
clearAllTimers() {
|
|
2204
|
+
timers().clearAllTimers();
|
|
2205
|
+
return utils;
|
|
2206
|
+
},
|
|
2207
|
+
setTimerTickMode(mode, interval) {
|
|
2208
|
+
timers().setTimerTickMode(mode, interval);
|
|
2209
|
+
return utils;
|
|
2210
|
+
},
|
|
2211
|
+
spyOn,
|
|
2212
|
+
fn,
|
|
2213
|
+
waitFor,
|
|
2214
|
+
waitUntil,
|
|
2215
|
+
defineHelper: (fn) => {
|
|
2216
|
+
return function __VITEST_HELPER__(...args) {
|
|
2217
|
+
const result = fn.apply(this, args);
|
|
2218
|
+
if (result && typeof result === "object" && typeof result.then === "function") return (async function __VITEST_HELPER__() {
|
|
2219
|
+
return await result;
|
|
2220
|
+
})();
|
|
2221
|
+
return result;
|
|
2222
|
+
};
|
|
2223
|
+
},
|
|
2224
|
+
hoisted(factory) {
|
|
2225
|
+
assertTypes(factory, "\"vi.hoisted\" factory", ["function"]);
|
|
2226
|
+
return factory();
|
|
2227
|
+
},
|
|
2228
|
+
mock(path, factory) {
|
|
2229
|
+
if (typeof path !== "string") throw new TypeError(`vi.mock() expects a string path, but received a ${typeof path}`);
|
|
2230
|
+
const importer = getImporter("mock");
|
|
2231
|
+
_mocker().queueMock(path, importer, typeof factory === "function" ? () => factory(() => _mocker().importActual(path, importer, _mocker().getMockContext().callstack)) : factory);
|
|
2232
|
+
},
|
|
2233
|
+
unmock(path) {
|
|
2234
|
+
if (typeof path !== "string") throw new TypeError(`vi.unmock() expects a string path, but received a ${typeof path}`);
|
|
2235
|
+
_mocker().queueUnmock(path, getImporter("unmock"));
|
|
2236
|
+
},
|
|
2237
|
+
doMock(path, factory) {
|
|
2238
|
+
if (typeof path !== "string") throw new TypeError(`vi.doMock() expects a string path, but received a ${typeof path}`);
|
|
2239
|
+
const importer = getImporter("doMock");
|
|
2240
|
+
_mocker().queueMock(path, importer, typeof factory === "function" ? () => factory(() => _mocker().importActual(path, importer, _mocker().getMockContext().callstack)) : factory);
|
|
2241
|
+
const rv = {};
|
|
2242
|
+
if (Symbol.dispose) rv[Symbol.dispose] = () => {
|
|
2243
|
+
_mocker().queueUnmock(path, importer);
|
|
2244
|
+
};
|
|
2245
|
+
return rv;
|
|
2246
|
+
},
|
|
2247
|
+
doUnmock(path) {
|
|
2248
|
+
if (typeof path !== "string") throw new TypeError(`vi.doUnmock() expects a string path, but received a ${typeof path}`);
|
|
2249
|
+
const importer = getImporter("doUnmock");
|
|
2250
|
+
_mocker().queueUnmock(path, importer);
|
|
2251
|
+
},
|
|
2252
|
+
async importActual(path) {
|
|
2253
|
+
const importer = getImporter("importActual");
|
|
2254
|
+
return _mocker().importActual(path, importer, _mocker().getMockContext().callstack);
|
|
2255
|
+
},
|
|
2256
|
+
async importMock(path) {
|
|
2257
|
+
const importer = getImporter("importMock");
|
|
2258
|
+
return _mocker().importMock(path, importer);
|
|
2259
|
+
},
|
|
2260
|
+
mockObject(value, options) {
|
|
2261
|
+
return _mocker().mockObject({ value }, void 0, options?.spy ? "autospy" : "automock").value;
|
|
2262
|
+
},
|
|
2263
|
+
mocked(item, _options = {}) {
|
|
2264
|
+
return item;
|
|
2265
|
+
},
|
|
2266
|
+
isMockFunction(fn) {
|
|
2267
|
+
return isMockFunction(fn);
|
|
2268
|
+
},
|
|
2269
|
+
clearAllMocks() {
|
|
2270
|
+
clearAllMocks();
|
|
2271
|
+
return utils;
|
|
2272
|
+
},
|
|
2273
|
+
resetAllMocks() {
|
|
2274
|
+
resetAllMocks();
|
|
2275
|
+
return utils;
|
|
2276
|
+
},
|
|
2277
|
+
restoreAllMocks() {
|
|
2278
|
+
restoreAllMocks();
|
|
2279
|
+
return utils;
|
|
2280
|
+
},
|
|
2281
|
+
stubGlobal(name, value) {
|
|
2282
|
+
if (!_stubsGlobal.has(name)) _stubsGlobal.set(name, Object.getOwnPropertyDescriptor(globalThis, name));
|
|
2283
|
+
Object.defineProperty(globalThis, name, {
|
|
2284
|
+
value,
|
|
2285
|
+
writable: true,
|
|
2286
|
+
configurable: true,
|
|
2287
|
+
enumerable: true
|
|
2288
|
+
});
|
|
2289
|
+
return utils;
|
|
2290
|
+
},
|
|
2291
|
+
stubEnv(name, value) {
|
|
2292
|
+
const env = state().metaEnv;
|
|
2293
|
+
if (!_stubsEnv.has(name)) _stubsEnv.set(name, env[name]);
|
|
2294
|
+
if (_envBooleans.includes(name)) env[name] = value ? "1" : "";
|
|
2295
|
+
else if (value === void 0) delete env[name];
|
|
2296
|
+
else env[name] = String(value);
|
|
2297
|
+
return utils;
|
|
2298
|
+
},
|
|
2299
|
+
unstubAllGlobals() {
|
|
2300
|
+
_stubsGlobal.forEach((original, name) => {
|
|
2301
|
+
if (!original) Reflect.deleteProperty(globalThis, name);
|
|
2302
|
+
else Object.defineProperty(globalThis, name, original);
|
|
2303
|
+
});
|
|
2304
|
+
_stubsGlobal.clear();
|
|
2305
|
+
return utils;
|
|
2306
|
+
},
|
|
2307
|
+
unstubAllEnvs() {
|
|
2308
|
+
const env = state().metaEnv;
|
|
2309
|
+
_stubsEnv.forEach((original, name) => {
|
|
2310
|
+
if (original === void 0) delete env[name];
|
|
2311
|
+
else env[name] = original;
|
|
2312
|
+
});
|
|
2313
|
+
_stubsEnv.clear();
|
|
2314
|
+
return utils;
|
|
2315
|
+
},
|
|
2316
|
+
resetModules() {
|
|
2317
|
+
resetModules(state().evaluatedModules);
|
|
2318
|
+
return utils;
|
|
2319
|
+
},
|
|
2320
|
+
async dynamicImportSettled() {
|
|
2321
|
+
return waitForImportsToResolve();
|
|
2322
|
+
},
|
|
2323
|
+
setConfig(config) {
|
|
2324
|
+
if (!_config) _config = { ...state().config };
|
|
2325
|
+
Object.assign(state().config, config);
|
|
2326
|
+
},
|
|
2327
|
+
resetConfig() {
|
|
2328
|
+
if (_config) Object.assign(state().config, _config);
|
|
2329
|
+
}
|
|
2330
|
+
};
|
|
2331
|
+
return utils;
|
|
2332
|
+
}
|
|
2333
|
+
const vitest = createVitest();
|
|
2334
|
+
const vi = vitest;
|
|
2335
|
+
function _mocker() {
|
|
2336
|
+
return typeof __vitest_mocker__ !== "undefined" ? __vitest_mocker__ : new Proxy({}, { get(_, name) {
|
|
2337
|
+
throw new Error(`Vitest mocker was not initialized in this environment. vi.${String(name)}() is forbidden.`);
|
|
2338
|
+
} });
|
|
2339
|
+
}
|
|
2340
|
+
function getImporter(name) {
|
|
2341
|
+
const stackArray = createSimpleStackTrace({ stackTraceLimit: 5 }).split("\n");
|
|
2342
|
+
return parseSingleStack(stackArray[stackArray.findLastIndex((stack) => {
|
|
2343
|
+
return stack.includes(` at Object.${name}`) || stack.includes(`${name}@`) || stack.includes(` at ${name} (`);
|
|
2344
|
+
}) + 1])?.file || "";
|
|
2345
|
+
}
|
|
2346
|
+
const unsupported = [
|
|
2347
|
+
"matchSnapshot",
|
|
2348
|
+
"toMatchSnapshot",
|
|
2349
|
+
"toMatchInlineSnapshot",
|
|
2350
|
+
"toThrowErrorMatchingSnapshot",
|
|
2351
|
+
"toThrowErrorMatchingInlineSnapshot",
|
|
2352
|
+
"throws",
|
|
2353
|
+
"Throw",
|
|
2354
|
+
"throw",
|
|
2355
|
+
"toThrow",
|
|
2356
|
+
"toThrowError"
|
|
2357
|
+
];
|
|
2358
|
+
/**
|
|
2359
|
+
* Attaches a `cause` property to the error if missing, copies the stack trace from the source, and throws.
|
|
2360
|
+
*
|
|
2361
|
+
* @param error - The error to throw
|
|
2362
|
+
* @param source - Error to copy the stack trace from
|
|
2363
|
+
*
|
|
2364
|
+
* @throws Always throws the provided error with an amended stack trace
|
|
2365
|
+
*/
|
|
2366
|
+
function throwWithCause(error, source) {
|
|
2367
|
+
if (error.cause == null) error.cause = /* @__PURE__ */ new Error("Matcher did not succeed in time.");
|
|
2368
|
+
throw copyStackTrace(error, source);
|
|
2369
|
+
}
|
|
2370
|
+
function createExpectPoll(expect) {
|
|
2371
|
+
return function poll(fn, options = {}) {
|
|
2372
|
+
const defaults = getWorkerState().config.expect?.poll ?? {};
|
|
2373
|
+
const { interval = defaults.interval ?? 50, timeout = defaults.timeout ?? 1e3, message } = options;
|
|
2374
|
+
const assertion = expect(null, message).withContext({ poll: true });
|
|
2375
|
+
fn = fn.bind(assertion);
|
|
2376
|
+
utils_exports.flag(assertion, "_poll.fn", fn);
|
|
2377
|
+
utils_exports.flag(assertion, "_poll.timeout", timeout);
|
|
2378
|
+
utils_exports.flag(assertion, "_poll.interval", interval);
|
|
2379
|
+
const test = utils_exports.flag(assertion, "vitest-test");
|
|
2380
|
+
if (!test) throw new Error("expect.poll() must be called inside a test");
|
|
2381
|
+
const proxy = new Proxy(assertion, { get(target, key, receiver) {
|
|
2382
|
+
const assertionFunction = Reflect.get(target, key, receiver);
|
|
2383
|
+
if (typeof assertionFunction !== "function") return assertionFunction instanceof Assertion ? proxy : assertionFunction;
|
|
2384
|
+
if (key === "assert") return assertionFunction;
|
|
2385
|
+
if (typeof key === "string" && unsupported.includes(key)) throw new SyntaxError(`expect.poll() is not supported in combination with .${key}(). Use vi.waitFor() if your assertion condition is unstable.`);
|
|
2386
|
+
return function __VITEST_POLL_CHAIN__(...args) {
|
|
2387
|
+
const STACK_TRACE_ERROR = /* @__PURE__ */ new Error("STACK_TRACE_ERROR");
|
|
2388
|
+
const promise = async () => {
|
|
2389
|
+
utils_exports.flag(assertion, "_name", key);
|
|
2390
|
+
utils_exports.flag(assertion, "error", STACK_TRACE_ERROR);
|
|
2391
|
+
const onSettled = utils_exports.flag(assertion, "_poll.onSettled");
|
|
2392
|
+
if (Object.getOwnPropertyDescriptor(assertionFunction, "__vitest_poll_takeover__")?.value) try {
|
|
2393
|
+
const output = await assertionFunction.call(assertion, ...args);
|
|
2394
|
+
await onSettled?.({
|
|
2395
|
+
assertion,
|
|
2396
|
+
status: "pass"
|
|
2397
|
+
});
|
|
2398
|
+
return output;
|
|
2399
|
+
} catch (err) {
|
|
2400
|
+
await onSettled?.({
|
|
2401
|
+
assertion,
|
|
2402
|
+
status: "fail"
|
|
2403
|
+
});
|
|
2404
|
+
throwWithCause(err, STACK_TRACE_ERROR);
|
|
2405
|
+
}
|
|
2406
|
+
const { setTimeout, clearTimeout } = getSafeTimers();
|
|
2407
|
+
let executionPhase = "fn";
|
|
2408
|
+
let hasTimedOut = false;
|
|
2409
|
+
const timerId = setTimeout(() => {
|
|
2410
|
+
hasTimedOut = true;
|
|
2411
|
+
}, timeout);
|
|
2412
|
+
try {
|
|
2413
|
+
while (true) {
|
|
2414
|
+
const isLastAttempt = hasTimedOut;
|
|
2415
|
+
if (isLastAttempt) utils_exports.flag(assertion, "_isLastPollAttempt", true);
|
|
2416
|
+
try {
|
|
2417
|
+
executionPhase = "fn";
|
|
2418
|
+
const obj = await fn();
|
|
2419
|
+
utils_exports.flag(assertion, "object", obj);
|
|
2420
|
+
executionPhase = "assertion";
|
|
2421
|
+
const output = await assertionFunction.call(assertion, ...args);
|
|
2422
|
+
await onSettled?.({
|
|
2423
|
+
assertion,
|
|
2424
|
+
status: "pass"
|
|
2425
|
+
});
|
|
2426
|
+
return output;
|
|
2427
|
+
} catch (err) {
|
|
2428
|
+
if (isLastAttempt || executionPhase === "assertion" && utils_exports.flag(assertion, "_poll.assert_once")) {
|
|
2429
|
+
await onSettled?.({
|
|
2430
|
+
assertion,
|
|
2431
|
+
status: "fail"
|
|
2432
|
+
});
|
|
2433
|
+
throwWithCause(err, STACK_TRACE_ERROR);
|
|
2434
|
+
}
|
|
2435
|
+
await delay(interval, setTimeout);
|
|
2436
|
+
if (vi.isFakeTimers()) vi.advanceTimersByTime(interval);
|
|
2437
|
+
}
|
|
2438
|
+
}
|
|
2439
|
+
} finally {
|
|
2440
|
+
clearTimeout(timerId);
|
|
2441
|
+
}
|
|
2442
|
+
};
|
|
2443
|
+
let awaited = false;
|
|
2444
|
+
test.onFinished ??= [];
|
|
2445
|
+
test.onFinished.push(() => {
|
|
2446
|
+
if (!awaited) {
|
|
2447
|
+
const negated = utils_exports.flag(assertion, "negate") ? "not." : "";
|
|
2448
|
+
const assertionString = `expect.${utils_exports.flag(assertion, "_poll.element") ? "element(locator)" : "poll(assertion)"}.${negated}${String(key)}()`;
|
|
2449
|
+
throw copyStackTrace(/* @__PURE__ */ new Error(`${assertionString} was not awaited. This assertion is asynchronous and must be awaited; otherwise, it is not executed to avoid unhandled rejections:\n\nawait ${assertionString}\n`), STACK_TRACE_ERROR);
|
|
2450
|
+
}
|
|
2451
|
+
});
|
|
2452
|
+
let resultPromise;
|
|
2453
|
+
return {
|
|
2454
|
+
then(onFulfilled, onRejected) {
|
|
2455
|
+
awaited = true;
|
|
2456
|
+
return (resultPromise ||= promise()).then(onFulfilled, onRejected);
|
|
2457
|
+
},
|
|
2458
|
+
catch(onRejected) {
|
|
2459
|
+
awaited = true;
|
|
2460
|
+
return (resultPromise ||= promise()).catch(onRejected);
|
|
2461
|
+
},
|
|
2462
|
+
finally(onFinally) {
|
|
2463
|
+
awaited = true;
|
|
2464
|
+
return (resultPromise ||= promise()).finally(onFinally);
|
|
2465
|
+
},
|
|
2466
|
+
[Symbol.toStringTag]: "Promise"
|
|
2467
|
+
};
|
|
2468
|
+
};
|
|
2469
|
+
} });
|
|
2470
|
+
return proxy;
|
|
2471
|
+
};
|
|
2472
|
+
}
|
|
2473
|
+
function copyStackTrace(target, source) {
|
|
2474
|
+
if (source.stack !== void 0) target.stack = source.stack.replace(source.message, target.message);
|
|
2475
|
+
return target;
|
|
2476
|
+
}
|
|
2477
|
+
let _client;
|
|
2478
|
+
function getSnapshotClient() {
|
|
2479
|
+
if (!_client) _client = new SnapshotClient({ isEqual: (received, expected) => {
|
|
2480
|
+
return equals(received, expected, [iterableEquality, subsetEquality]);
|
|
2481
|
+
} });
|
|
2482
|
+
return _client;
|
|
2483
|
+
}
|
|
2484
|
+
function getError(expected, promise) {
|
|
2485
|
+
if (typeof expected !== "function") {
|
|
2486
|
+
if (!promise) throw new Error(`expected must be a function, received ${typeof expected}`);
|
|
2487
|
+
return expected;
|
|
2488
|
+
}
|
|
2489
|
+
try {
|
|
2490
|
+
expected();
|
|
2491
|
+
} catch (e) {
|
|
2492
|
+
return e;
|
|
2493
|
+
}
|
|
2494
|
+
throw new Error("snapshot function didn't throw");
|
|
2495
|
+
}
|
|
2496
|
+
function getTestNames(test) {
|
|
2497
|
+
return {
|
|
2498
|
+
filepath: test.file.filepath,
|
|
2499
|
+
name: getNames(test).slice(1).join(" > "),
|
|
2500
|
+
testId: test.id
|
|
2501
|
+
};
|
|
2502
|
+
}
|
|
2503
|
+
function getAssertionName(assertion) {
|
|
2504
|
+
const name = utils_exports.flag(assertion, "_name");
|
|
2505
|
+
if (!name) throw new Error("Assertion name is not set. This is a bug in Vitest. Please, open a new issue with reproduction.");
|
|
2506
|
+
return name;
|
|
2507
|
+
}
|
|
2508
|
+
function getTest(obj) {
|
|
2509
|
+
const test = utils_exports.flag(obj, "vitest-test");
|
|
2510
|
+
if (!test) throw new Error(`'${getAssertionName(obj)}' cannot be used without test context`);
|
|
2511
|
+
return test;
|
|
2512
|
+
}
|
|
2513
|
+
function validateAssertion(assertion) {
|
|
2514
|
+
if (utils_exports.flag(assertion, "negate")) throw new Error(`${getAssertionName(assertion)} cannot be used with "not"`);
|
|
2515
|
+
}
|
|
2516
|
+
const SnapshotPlugin = (chai, utils) => {
|
|
2517
|
+
for (const key of ["matchSnapshot", "toMatchSnapshot"]) utils.addMethod(chai.Assertion.prototype, key, wrapAssertion(utils, key, function(propertiesOrHint, hint) {
|
|
2518
|
+
return assertMatchResult(toMatchSnapshotImpl({
|
|
2519
|
+
assertion: this,
|
|
2520
|
+
received: utils.flag(this, "object"),
|
|
2521
|
+
...normalizeArguments(propertiesOrHint, hint)
|
|
2522
|
+
}), chai.util.flag(this, "message"));
|
|
2523
|
+
}));
|
|
2524
|
+
utils.addMethod(chai.Assertion.prototype, "toMatchFileSnapshot", function(filepath, hint) {
|
|
2525
|
+
utils.flag(this, "_name", "toMatchFileSnapshot");
|
|
2526
|
+
validateAssertion(this);
|
|
2527
|
+
const assertPromise = toMatchFileSnapshotImpl({
|
|
2528
|
+
assertion: this,
|
|
2529
|
+
received: utils.flag(this, "object"),
|
|
2530
|
+
filepath,
|
|
2531
|
+
hint
|
|
2532
|
+
}).then((result) => assertMatchResult(result, chai.util.flag(this, "message")));
|
|
2533
|
+
return recordAsyncExpect(getTest(this), assertPromise, createAssertionMessage(utils, this, true), /* @__PURE__ */ new Error("resolves"), utils.flag(this, "soft"));
|
|
2534
|
+
});
|
|
2535
|
+
utils.addMethod(chai.Assertion.prototype, "toMatchInlineSnapshot", wrapAssertion(utils, "toMatchInlineSnapshot", function __INLINE_SNAPSHOT_OFFSET_3__(propertiesOrInlineSnapshot, inlineSnapshotOrHint, hint) {
|
|
2536
|
+
return assertMatchResult(toMatchSnapshotImpl({
|
|
2537
|
+
assertion: this,
|
|
2538
|
+
received: utils.flag(this, "object"),
|
|
2539
|
+
isInline: true,
|
|
2540
|
+
...normalizeInlineArguments(propertiesOrInlineSnapshot, inlineSnapshotOrHint, hint)
|
|
2541
|
+
}), chai.util.flag(this, "message"));
|
|
2542
|
+
}));
|
|
2543
|
+
utils.addMethod(chai.Assertion.prototype, "toThrowErrorMatchingSnapshot", wrapAssertion(utils, "toThrowErrorMatchingSnapshot", function(propertiesOrHint, hint) {
|
|
2544
|
+
validateAssertion(this);
|
|
2545
|
+
const received = utils.flag(this, "object");
|
|
2546
|
+
const promise = utils.flag(this, "promise");
|
|
2547
|
+
return assertMatchResult(toMatchSnapshotImpl({
|
|
2548
|
+
assertion: this,
|
|
2549
|
+
received: getError(received, promise),
|
|
2550
|
+
...normalizeArguments(propertiesOrHint, hint)
|
|
2551
|
+
}), chai.util.flag(this, "message"));
|
|
2552
|
+
}));
|
|
2553
|
+
utils.addMethod(chai.Assertion.prototype, "toThrowErrorMatchingInlineSnapshot", wrapAssertion(utils, "toThrowErrorMatchingInlineSnapshot", function __INLINE_SNAPSHOT_OFFSET_3__(inlineSnapshotOrHint, hint) {
|
|
2554
|
+
validateAssertion(this);
|
|
2555
|
+
const received = utils.flag(this, "object");
|
|
2556
|
+
const promise = utils.flag(this, "promise");
|
|
2557
|
+
return assertMatchResult(toMatchSnapshotImpl({
|
|
2558
|
+
assertion: this,
|
|
2559
|
+
received: getError(received, promise),
|
|
2560
|
+
isInline: true,
|
|
2561
|
+
...normalizeInlineArguments(void 0, inlineSnapshotOrHint, hint)
|
|
2562
|
+
}), chai.util.flag(this, "message"));
|
|
2563
|
+
}));
|
|
2564
|
+
utils.addMethod(chai.expect, "addSnapshotSerializer", addSerializer);
|
|
2565
|
+
};
|
|
2566
|
+
function toMatchDomainSnapshotImpl(opts) {
|
|
2567
|
+
const { assertion } = opts;
|
|
2568
|
+
validateAssertion(assertion);
|
|
2569
|
+
const assertionName = getAssertionName(assertion);
|
|
2570
|
+
const test = getTest(assertion);
|
|
2571
|
+
let { inlineSnapshot } = opts;
|
|
2572
|
+
if (inlineSnapshot) inlineSnapshot = stripSnapshotIndentation(inlineSnapshot);
|
|
2573
|
+
const pollFn = utils_exports.flag(assertion, "_poll.fn");
|
|
2574
|
+
if (pollFn) return getSnapshotClient().pollMatchDomain({
|
|
2575
|
+
poll: pollFn,
|
|
2576
|
+
adapter: opts.adapter,
|
|
2577
|
+
message: opts.hint,
|
|
2578
|
+
isInline: opts.isInline,
|
|
2579
|
+
errorMessage: utils_exports.flag(assertion, "message"),
|
|
2580
|
+
timeout: utils_exports.flag(assertion, "_poll.timeout"),
|
|
2581
|
+
interval: utils_exports.flag(assertion, "_poll.interval"),
|
|
2582
|
+
assertionName,
|
|
2583
|
+
inlineSnapshot,
|
|
2584
|
+
error: utils_exports.flag(assertion, "error"),
|
|
2585
|
+
...getTestNames(test)
|
|
2586
|
+
});
|
|
2587
|
+
return getSnapshotClient().matchDomain({
|
|
2588
|
+
received: opts.received,
|
|
2589
|
+
adapter: opts.adapter,
|
|
2590
|
+
message: opts.hint,
|
|
2591
|
+
isInline: opts.isInline,
|
|
2592
|
+
errorMessage: utils_exports.flag(assertion, "message"),
|
|
2593
|
+
assertionName,
|
|
2594
|
+
inlineSnapshot,
|
|
2595
|
+
error: utils_exports.flag(assertion, "error"),
|
|
2596
|
+
...getTestNames(test)
|
|
2597
|
+
});
|
|
2598
|
+
}
|
|
2599
|
+
function normalizeArguments(propertiesOrHint, hint) {
|
|
2600
|
+
if (typeof propertiesOrHint === "string") return { hint: propertiesOrHint };
|
|
2601
|
+
return {
|
|
2602
|
+
properties: propertiesOrHint,
|
|
2603
|
+
hint
|
|
2604
|
+
};
|
|
2605
|
+
}
|
|
2606
|
+
function normalizeInlineArguments(propertiesOrInlineSnapshot, inlineSnapshotOrHint, hint) {
|
|
2607
|
+
let inlineSnapshot;
|
|
2608
|
+
if (typeof propertiesOrInlineSnapshot === "string") {
|
|
2609
|
+
inlineSnapshot = stripSnapshotIndentation(propertiesOrInlineSnapshot);
|
|
2610
|
+
return {
|
|
2611
|
+
inlineSnapshot,
|
|
2612
|
+
hint: inlineSnapshotOrHint
|
|
2613
|
+
};
|
|
2614
|
+
}
|
|
2615
|
+
if (inlineSnapshotOrHint) inlineSnapshot = stripSnapshotIndentation(inlineSnapshotOrHint);
|
|
2616
|
+
return {
|
|
2617
|
+
properties: propertiesOrInlineSnapshot,
|
|
2618
|
+
inlineSnapshot,
|
|
2619
|
+
hint
|
|
2620
|
+
};
|
|
2621
|
+
}
|
|
2622
|
+
function toMatchSnapshotImpl(options) {
|
|
2623
|
+
const { assertion } = options;
|
|
2624
|
+
validateAssertion(assertion);
|
|
2625
|
+
const assertionName = getAssertionName(assertion);
|
|
2626
|
+
const test = getTest(assertion);
|
|
2627
|
+
return getSnapshotClient().match({
|
|
2628
|
+
received: options.received,
|
|
2629
|
+
properties: options.properties,
|
|
2630
|
+
message: options.hint,
|
|
2631
|
+
isInline: options.isInline,
|
|
2632
|
+
inlineSnapshot: options.inlineSnapshot,
|
|
2633
|
+
assertionName,
|
|
2634
|
+
error: utils_exports.flag(assertion, "error"),
|
|
2635
|
+
...getTestNames(test)
|
|
2636
|
+
});
|
|
2637
|
+
}
|
|
2638
|
+
async function toMatchFileSnapshotImpl(options) {
|
|
2639
|
+
const { assertion } = options;
|
|
2640
|
+
validateAssertion(assertion);
|
|
2641
|
+
const testNames = getTestNames(getTest(assertion));
|
|
2642
|
+
const snapshotState = getSnapshotClient().getSnapshotState(testNames.filepath);
|
|
2643
|
+
const rawSnapshotFile = await snapshotState.environment.resolveRawPath(testNames.filepath, options.filepath);
|
|
2644
|
+
const rawSnapshotContent = await snapshotState.environment.readSnapshotFile(rawSnapshotFile);
|
|
2645
|
+
return getSnapshotClient().match({
|
|
2646
|
+
received: options.received,
|
|
2647
|
+
message: options.hint,
|
|
2648
|
+
rawSnapshot: {
|
|
2649
|
+
file: rawSnapshotFile,
|
|
2650
|
+
content: rawSnapshotContent ?? void 0
|
|
2651
|
+
},
|
|
2652
|
+
...testNames
|
|
2653
|
+
});
|
|
2654
|
+
}
|
|
2655
|
+
function assertMatchResult(result, customMessage) {
|
|
2656
|
+
if (!result.pass) {
|
|
2657
|
+
const errorMessage = (customMessage ? `${customMessage}: ` : "") + result.message();
|
|
2658
|
+
throw Object.assign(new Error(errorMessage), {
|
|
2659
|
+
actual: result.actual,
|
|
2660
|
+
expected: result.expected,
|
|
2661
|
+
diffOptions: { expand: getWorkerState().config.snapshotOptions.expand }
|
|
2662
|
+
});
|
|
2663
|
+
}
|
|
2664
|
+
}
|
|
2665
|
+
/**
|
|
2666
|
+
* Composable snapshot matcher helpers for building custom snapshot matchers
|
|
2667
|
+
* with `expect.extend`.
|
|
2668
|
+
*
|
|
2669
|
+
* @experimental
|
|
2670
|
+
* @see https://vitest.dev/guide/snapshot.html#custom-snapshot-matchers
|
|
2671
|
+
*/
|
|
2672
|
+
const Snapshots = {
|
|
2673
|
+
toMatchSnapshot(received, propertiesOrHint, hint) {
|
|
2674
|
+
return toMatchSnapshotImpl({
|
|
2675
|
+
assertion: this.assertion,
|
|
2676
|
+
received,
|
|
2677
|
+
...normalizeArguments(propertiesOrHint, hint)
|
|
2678
|
+
});
|
|
2679
|
+
},
|
|
2680
|
+
toMatchInlineSnapshot(received, propertiesOrInlineSnapshot, inlineSnapshotOrHint, hint) {
|
|
2681
|
+
return toMatchSnapshotImpl({
|
|
2682
|
+
assertion: this.assertion,
|
|
2683
|
+
received,
|
|
2684
|
+
isInline: true,
|
|
2685
|
+
...normalizeInlineArguments(propertiesOrInlineSnapshot, inlineSnapshotOrHint, hint)
|
|
2686
|
+
});
|
|
2687
|
+
},
|
|
2688
|
+
toMatchFileSnapshot(received, filepath, hint) {
|
|
2689
|
+
return toMatchFileSnapshotImpl({
|
|
2690
|
+
assertion: this.assertion,
|
|
2691
|
+
received,
|
|
2692
|
+
filepath,
|
|
2693
|
+
hint
|
|
2694
|
+
});
|
|
2695
|
+
},
|
|
2696
|
+
toMatchDomainSnapshot(domain, received) {
|
|
2697
|
+
return toMatchDomainSnapshotImpl({
|
|
2698
|
+
assertion: this.assertion,
|
|
2699
|
+
adapter: domain,
|
|
2700
|
+
received
|
|
2701
|
+
});
|
|
2702
|
+
},
|
|
2703
|
+
toMatchDomainInlineSnapshot(domain, received, inlineSnapshot) {
|
|
2704
|
+
return toMatchDomainSnapshotImpl({
|
|
2705
|
+
assertion: this.assertion,
|
|
2706
|
+
adapter: domain,
|
|
2707
|
+
received,
|
|
2708
|
+
isInline: true,
|
|
2709
|
+
inlineSnapshot
|
|
2710
|
+
});
|
|
2711
|
+
}
|
|
2712
|
+
};
|
|
2713
|
+
use(JestExtend);
|
|
2714
|
+
use(JestChaiExpect);
|
|
2715
|
+
use(ChaiStyleAssertions);
|
|
2716
|
+
use(SnapshotPlugin);
|
|
2717
|
+
use(JestAsymmetricMatchers);
|
|
2718
|
+
function createExpect(test) {
|
|
2719
|
+
const expect$1 = ((value, message) => {
|
|
2720
|
+
const { assertionCalls } = getState(expect$1);
|
|
2721
|
+
setState({ assertionCalls: assertionCalls + 1 }, expect$1);
|
|
2722
|
+
const assert = expect(value, message);
|
|
2723
|
+
const _test = test || getCurrentTest();
|
|
2724
|
+
if (_test) return assert.withTest(_test);
|
|
2725
|
+
else return assert;
|
|
2726
|
+
});
|
|
2727
|
+
Object.assign(expect$1, expect);
|
|
2728
|
+
Object.assign(expect$1, globalThis[ASYMMETRIC_MATCHERS_OBJECT]);
|
|
2729
|
+
expect$1.getState = () => getState(expect$1);
|
|
2730
|
+
expect$1.setState = (state) => setState(state, expect$1);
|
|
2731
|
+
const globalState = getState(globalThis[GLOBAL_EXPECT]) || {};
|
|
2732
|
+
setState({
|
|
2733
|
+
...globalState,
|
|
2734
|
+
assertionCalls: 0,
|
|
2735
|
+
isExpectingAssertions: false,
|
|
2736
|
+
isExpectingAssertionsError: null,
|
|
2737
|
+
expectedAssertionsNumber: null,
|
|
2738
|
+
expectedAssertionsNumberErrorGen: null,
|
|
2739
|
+
get testPath() {
|
|
2740
|
+
return getWorkerState().filepath;
|
|
2741
|
+
},
|
|
2742
|
+
currentTestName: test ? test.fullTestName ?? "" : globalState.currentTestName
|
|
2743
|
+
}, expect$1);
|
|
2744
|
+
expect$1.assert = assert$1;
|
|
2745
|
+
expect$1.extend = (matchers) => expect.extend(expect$1, matchers);
|
|
2746
|
+
expect$1.addEqualityTesters = (customTesters) => addCustomEqualityTesters(customTesters);
|
|
2747
|
+
expect$1.soft = (...args) => {
|
|
2748
|
+
return expect$1(...args).withContext({ soft: true });
|
|
2749
|
+
};
|
|
2750
|
+
expect$1.poll = createExpectPoll(expect$1);
|
|
2751
|
+
expect$1.unreachable = (message) => {
|
|
2752
|
+
assert$1.fail(`expected${message ? ` "${message}" ` : " "}not to be reached`);
|
|
2753
|
+
};
|
|
2754
|
+
function assertions(expected) {
|
|
2755
|
+
const errorGen = () => /* @__PURE__ */ new Error(`expected number of assertions to be ${expected}, but got ${expect$1.getState().assertionCalls}`);
|
|
2756
|
+
if (Error.captureStackTrace) Error.captureStackTrace(errorGen(), assertions);
|
|
2757
|
+
expect$1.setState({
|
|
2758
|
+
expectedAssertionsNumber: expected,
|
|
2759
|
+
expectedAssertionsNumberErrorGen: errorGen
|
|
2760
|
+
});
|
|
2761
|
+
}
|
|
2762
|
+
function hasAssertions() {
|
|
2763
|
+
const error = /* @__PURE__ */ new Error("expected any number of assertion, but got none");
|
|
2764
|
+
if (Error.captureStackTrace) Error.captureStackTrace(error, hasAssertions);
|
|
2765
|
+
expect$1.setState({
|
|
2766
|
+
isExpectingAssertions: true,
|
|
2767
|
+
isExpectingAssertionsError: error
|
|
2768
|
+
});
|
|
2769
|
+
}
|
|
2770
|
+
utils_exports.addMethod(expect$1, "assertions", assertions);
|
|
2771
|
+
utils_exports.addMethod(expect$1, "hasAssertions", hasAssertions);
|
|
2772
|
+
expect$1.extend(customMatchers);
|
|
2773
|
+
return expect$1;
|
|
2774
|
+
}
|
|
2775
|
+
const globalExpect = createExpect();
|
|
2776
|
+
Object.defineProperty(globalThis, GLOBAL_EXPECT, {
|
|
2777
|
+
value: globalExpect,
|
|
2778
|
+
writable: true,
|
|
2779
|
+
configurable: true
|
|
2780
|
+
});
|
|
2781
|
+
const assert = assert$1;
|
|
2782
|
+
const should = should$1;
|
|
2783
|
+
/**
|
|
2784
|
+
* Gives access to injected context provided from the main thread.
|
|
2785
|
+
* This usually returns a value provided by `globalSetup` or an external library.
|
|
2786
|
+
*/
|
|
2787
|
+
function inject(key) {
|
|
2788
|
+
return getWorkerState().providedContext[key];
|
|
2789
|
+
}
|
|
2790
|
+
function createBenchmarkResult(name) {
|
|
2791
|
+
return {
|
|
2792
|
+
name,
|
|
2793
|
+
rank: 0,
|
|
2794
|
+
rme: 0,
|
|
2795
|
+
samples: []
|
|
2796
|
+
};
|
|
2797
|
+
}
|
|
2798
|
+
const benchmarkTasks = /* @__PURE__ */ new WeakMap();
|
|
2799
|
+
async function runBenchmarkSuite(suite, runner) {
|
|
2800
|
+
const { Task, Bench } = await runner.importTinybench();
|
|
2801
|
+
const start = performance.now();
|
|
2802
|
+
const benchmarkGroup = [];
|
|
2803
|
+
const benchmarkSuiteGroup = [];
|
|
2804
|
+
for (const task of suite.tasks) {
|
|
2805
|
+
if (task.mode !== "run" && task.mode !== "queued") continue;
|
|
2806
|
+
if (task.meta?.benchmark) benchmarkGroup.push(task);
|
|
2807
|
+
else if (task.type === "suite") benchmarkSuiteGroup.push(task);
|
|
2808
|
+
}
|
|
2809
|
+
for (const subSuite of benchmarkSuiteGroup) await runBenchmarkSuite(subSuite, runner);
|
|
2810
|
+
if (benchmarkGroup.length) {
|
|
2811
|
+
const defer = createDefer();
|
|
2812
|
+
suite.result = {
|
|
2813
|
+
state: "run",
|
|
2814
|
+
startTime: start,
|
|
2815
|
+
benchmark: createBenchmarkResult(suite.name)
|
|
2816
|
+
};
|
|
2817
|
+
updateTask$1("suite-prepare", suite);
|
|
2818
|
+
const addBenchTaskListener = (task, benchmark) => {
|
|
2819
|
+
task.addEventListener("complete", (e) => {
|
|
2820
|
+
const taskRes = e.task.result;
|
|
2821
|
+
const result = benchmark.result.benchmark;
|
|
2822
|
+
benchmark.result.state = "pass";
|
|
2823
|
+
Object.assign(result, taskRes);
|
|
2824
|
+
const samples = result.samples;
|
|
2825
|
+
result.sampleCount = samples.length;
|
|
2826
|
+
result.median = samples.length % 2 ? samples[Math.floor(samples.length / 2)] : (samples[samples.length / 2] + samples[samples.length / 2 - 1]) / 2;
|
|
2827
|
+
if (!runner.config.benchmark?.includeSamples) result.samples.length = 0;
|
|
2828
|
+
updateTask$1("test-finished", benchmark);
|
|
2829
|
+
}, { once: true });
|
|
2830
|
+
task.addEventListener("error", (e) => {
|
|
2831
|
+
const task = e.task;
|
|
2832
|
+
defer.reject(benchmark ? task.result.error : e);
|
|
2833
|
+
}, { once: true });
|
|
2834
|
+
};
|
|
2835
|
+
benchmarkGroup.forEach((benchmark) => {
|
|
2836
|
+
const benchmarkInstance = new Bench(getBenchOptions(benchmark));
|
|
2837
|
+
const benchmarkFn = getBenchFn(benchmark);
|
|
2838
|
+
benchmark.result = {
|
|
2839
|
+
state: "run",
|
|
2840
|
+
startTime: start,
|
|
2841
|
+
benchmark: createBenchmarkResult(benchmark.name)
|
|
2842
|
+
};
|
|
2843
|
+
const task = new Task(benchmarkInstance, benchmark.name, benchmarkFn);
|
|
2844
|
+
benchmarkTasks.set(benchmark, task);
|
|
2845
|
+
addBenchTaskListener(task, benchmark);
|
|
2846
|
+
});
|
|
2847
|
+
const { setTimeout } = getSafeTimers();
|
|
2848
|
+
const tasks = [];
|
|
2849
|
+
for (const benchmark of benchmarkGroup) {
|
|
2850
|
+
const task = benchmarkTasks.get(benchmark);
|
|
2851
|
+
updateTask$1("test-prepare", benchmark);
|
|
2852
|
+
await task.warmup();
|
|
2853
|
+
tasks.push([await new Promise((resolve) => setTimeout(async () => {
|
|
2854
|
+
resolve(await task.run());
|
|
2855
|
+
})), benchmark]);
|
|
2856
|
+
}
|
|
2857
|
+
suite.result.duration = performance.now() - start;
|
|
2858
|
+
suite.result.state = "pass";
|
|
2859
|
+
updateTask$1("suite-finished", suite);
|
|
2860
|
+
defer.resolve(null);
|
|
2861
|
+
await defer;
|
|
2862
|
+
}
|
|
2863
|
+
function updateTask$1(event, task) {
|
|
2864
|
+
updateTask(event, task, runner);
|
|
2865
|
+
}
|
|
2866
|
+
}
|
|
2867
|
+
var NodeBenchmarkRunner = class {
|
|
2868
|
+
moduleRunner;
|
|
2869
|
+
constructor(config) {
|
|
2870
|
+
this.config = config;
|
|
2871
|
+
}
|
|
2872
|
+
async importTinybench() {
|
|
2873
|
+
return await import("../../../../../tinybench@2.9.0/node_modules/tinybench/dist/index.js");
|
|
2874
|
+
}
|
|
2875
|
+
importFile(filepath, source) {
|
|
2876
|
+
if (source === "setup") {
|
|
2877
|
+
const moduleNode = getWorkerState().evaluatedModules.getModuleById(filepath);
|
|
2878
|
+
if (moduleNode) getWorkerState().evaluatedModules.invalidateModule(moduleNode);
|
|
2879
|
+
}
|
|
2880
|
+
return this.moduleRunner.import(filepath);
|
|
2881
|
+
}
|
|
2882
|
+
async runSuite(suite) {
|
|
2883
|
+
await runBenchmarkSuite(suite, this);
|
|
2884
|
+
}
|
|
2885
|
+
async runTask() {
|
|
2886
|
+
throw new Error("`test()` and `it()` is only available in test mode.");
|
|
2887
|
+
}
|
|
2888
|
+
};
|
|
2889
|
+
var TestRunner = class {
|
|
2890
|
+
snapshotClient = getSnapshotClient();
|
|
2891
|
+
workerState = getWorkerState();
|
|
2892
|
+
moduleRunner;
|
|
2893
|
+
cancelRun = false;
|
|
2894
|
+
assertionsErrors = /* @__PURE__ */ new WeakMap();
|
|
2895
|
+
pool = this.workerState.ctx.pool;
|
|
2896
|
+
_otel;
|
|
2897
|
+
viteEnvironment;
|
|
2898
|
+
viteModuleRunner;
|
|
2899
|
+
constructor(config) {
|
|
2900
|
+
this.config = config;
|
|
2901
|
+
const environment = this.workerState.environment;
|
|
2902
|
+
this.viteEnvironment = environment.viteEnvironment || environment.name;
|
|
2903
|
+
this.viteModuleRunner = config.experimental.viteModuleRunner;
|
|
2904
|
+
}
|
|
2905
|
+
importFile(filepath, source) {
|
|
2906
|
+
if (source === "setup") {
|
|
2907
|
+
const moduleNode = this.workerState.evaluatedModules.getModuleById(filepath);
|
|
2908
|
+
if (moduleNode) this.workerState.evaluatedModules.invalidateModule(moduleNode);
|
|
2909
|
+
}
|
|
2910
|
+
return this._otel.$(`vitest.module.import_${source === "setup" ? "setup" : "spec"}`, { attributes: { "code.file.path": filepath } }, () => {
|
|
2911
|
+
if (!this.viteModuleRunner) filepath = `${filepath}?vitest=${Date.now()}`;
|
|
2912
|
+
return this.moduleRunner.import(filepath);
|
|
2913
|
+
});
|
|
2914
|
+
}
|
|
2915
|
+
onCollectStart(file) {
|
|
2916
|
+
this.workerState.current = file;
|
|
2917
|
+
}
|
|
2918
|
+
onCleanupWorkerContext(listener) {
|
|
2919
|
+
this.workerState.onCleanup(listener);
|
|
2920
|
+
}
|
|
2921
|
+
onAfterRunFiles() {
|
|
2922
|
+
this.snapshotClient.clear();
|
|
2923
|
+
this.workerState.current = void 0;
|
|
2924
|
+
}
|
|
2925
|
+
async onAfterRunSuite(suite) {
|
|
2926
|
+
if (this.config.logHeapUsage && typeof process !== "undefined") suite.result.heap = process.memoryUsage().heapUsed;
|
|
2927
|
+
if (suite.mode !== "skip" && "filepath" in suite) {
|
|
2928
|
+
for (const test of getTests(suite)) if (test.mode === "skip") {
|
|
2929
|
+
const name = getNames(test).slice(1).join(" > ");
|
|
2930
|
+
this.snapshotClient.skipTest(suite.file.filepath, name);
|
|
2931
|
+
}
|
|
2932
|
+
const result = await this.snapshotClient.finish(suite.file.filepath);
|
|
2933
|
+
if (this.workerState.config.snapshotOptions.updateSnapshot === "none" && result.unchecked) {
|
|
2934
|
+
let message = `Obsolete snapshots found when no snapshot update is expected.\n`;
|
|
2935
|
+
for (const key of result.uncheckedKeys) message += `· ${key}\n`;
|
|
2936
|
+
suite.result.errors ??= [];
|
|
2937
|
+
suite.result.errors.push(processError(new Error(message)));
|
|
2938
|
+
suite.result.state = "fail";
|
|
2939
|
+
}
|
|
2940
|
+
await rpc().snapshotSaved(result);
|
|
2941
|
+
}
|
|
2942
|
+
this.workerState.current = suite.suite || suite.file;
|
|
2943
|
+
}
|
|
2944
|
+
onAfterRunTask(test) {
|
|
2945
|
+
if (this.config.logHeapUsage && typeof process !== "undefined") test.result.heap = process.memoryUsage().heapUsed;
|
|
2946
|
+
this.workerState.current = test.suite || test.file;
|
|
2947
|
+
}
|
|
2948
|
+
cancel(_reason) {
|
|
2949
|
+
this.cancelRun = true;
|
|
2950
|
+
}
|
|
2951
|
+
injectValue(key) {
|
|
2952
|
+
return inject(key);
|
|
2953
|
+
}
|
|
2954
|
+
async onBeforeRunTask(test) {
|
|
2955
|
+
if (this.cancelRun) test.mode = "skip";
|
|
2956
|
+
if (test.mode !== "run" && test.mode !== "queued") return;
|
|
2957
|
+
this.workerState.current = test;
|
|
2958
|
+
}
|
|
2959
|
+
async onBeforeRunSuite(suite) {
|
|
2960
|
+
if (this.cancelRun) suite.mode = "skip";
|
|
2961
|
+
if (suite.mode !== "skip" && "filepath" in suite) await this.snapshotClient.setup(suite.file.filepath, this.workerState.config.snapshotOptions);
|
|
2962
|
+
this.workerState.current = suite;
|
|
2963
|
+
}
|
|
2964
|
+
onBeforeTryTask(test) {
|
|
2965
|
+
clearModuleMocks(this.config);
|
|
2966
|
+
this.snapshotClient.clearTest(test.file.filepath, test.id);
|
|
2967
|
+
setState({
|
|
2968
|
+
assertionCalls: 0,
|
|
2969
|
+
isExpectingAssertions: false,
|
|
2970
|
+
isExpectingAssertionsError: null,
|
|
2971
|
+
expectedAssertionsNumber: null,
|
|
2972
|
+
expectedAssertionsNumberErrorGen: null,
|
|
2973
|
+
currentTestName: getTestName(test),
|
|
2974
|
+
snapshotState: this.snapshotClient.getSnapshotState(test.file.filepath)
|
|
2975
|
+
}, globalThis[GLOBAL_EXPECT]);
|
|
2976
|
+
}
|
|
2977
|
+
onAfterTryTask(test) {
|
|
2978
|
+
const { assertionCalls, expectedAssertionsNumber, expectedAssertionsNumberErrorGen, isExpectingAssertions, isExpectingAssertionsError } = test.context._local ? test.context.expect.getState() : getState(globalThis[GLOBAL_EXPECT]);
|
|
2979
|
+
if (expectedAssertionsNumber !== null && assertionCalls !== expectedAssertionsNumber) throw expectedAssertionsNumberErrorGen();
|
|
2980
|
+
if (isExpectingAssertions === true && assertionCalls === 0) throw isExpectingAssertionsError;
|
|
2981
|
+
if (this.config.expect.requireAssertions && assertionCalls === 0) throw this.assertionsErrors.get(test);
|
|
2982
|
+
}
|
|
2983
|
+
extendTaskContext(context) {
|
|
2984
|
+
if (this.config.expect.requireAssertions) this.assertionsErrors.set(context.task, /* @__PURE__ */ new Error("expected any number of assertion, but got none"));
|
|
2985
|
+
let _expect;
|
|
2986
|
+
Object.defineProperty(context, "expect", { get() {
|
|
2987
|
+
if (!_expect) _expect = createExpect(context.task);
|
|
2988
|
+
return _expect;
|
|
2989
|
+
} });
|
|
2990
|
+
Object.defineProperty(context, "_local", { get() {
|
|
2991
|
+
return _expect != null;
|
|
2992
|
+
} });
|
|
2993
|
+
return context;
|
|
2994
|
+
}
|
|
2995
|
+
getImportDurations() {
|
|
2996
|
+
const { limit } = this.config.experimental.importDurations;
|
|
2997
|
+
if (limit === 0) return {};
|
|
2998
|
+
const sortedEntries = [...this.workerState.moduleExecutionInfo?.entries() || []].sort(([, a], [, b]) => b.duration - a.duration).slice(0, limit);
|
|
2999
|
+
const importDurations = {};
|
|
3000
|
+
for (const [filepath, { duration, selfTime, external, importer }] of sortedEntries) importDurations[normalize(filepath)] = {
|
|
3001
|
+
selfTime,
|
|
3002
|
+
totalTime: duration,
|
|
3003
|
+
external,
|
|
3004
|
+
importer
|
|
3005
|
+
};
|
|
3006
|
+
return importDurations;
|
|
3007
|
+
}
|
|
3008
|
+
trace = (name, attributes, cb) => {
|
|
3009
|
+
const options = typeof attributes === "object" ? { attributes } : {};
|
|
3010
|
+
return this._otel.$(`vitest.test.runner.${name}`, options, cb || attributes);
|
|
3011
|
+
};
|
|
3012
|
+
__setTraces(traces) {
|
|
3013
|
+
this._otel = traces;
|
|
3014
|
+
}
|
|
3015
|
+
static createTaskCollector = createTaskCollector;
|
|
3016
|
+
static getCurrentSuite = getCurrentSuite;
|
|
3017
|
+
static getCurrentTest = getCurrentTest;
|
|
3018
|
+
static createChainable = createChainable;
|
|
3019
|
+
static getSuiteHooks = getHooks;
|
|
3020
|
+
static getTestFn = getFn;
|
|
3021
|
+
static setSuiteHooks = getHooks;
|
|
3022
|
+
static setTestFn = getFn;
|
|
3023
|
+
static matchesTags = matchesTags;
|
|
3024
|
+
/**
|
|
3025
|
+
* @deprecated
|
|
3026
|
+
*/
|
|
3027
|
+
static getBenchFn = getBenchFn;
|
|
3028
|
+
/**
|
|
3029
|
+
* @deprecated
|
|
3030
|
+
*/
|
|
3031
|
+
static getBenchOptions = getBenchOptions;
|
|
3032
|
+
};
|
|
3033
|
+
function clearModuleMocks(config) {
|
|
3034
|
+
const { clearMocks, mockReset, restoreMocks, unstubEnvs, unstubGlobals } = config;
|
|
3035
|
+
if (restoreMocks) vi.restoreAllMocks();
|
|
3036
|
+
if (mockReset) vi.resetAllMocks();
|
|
3037
|
+
if (clearMocks) vi.clearAllMocks();
|
|
3038
|
+
if (unstubEnvs) vi.unstubAllEnvs();
|
|
3039
|
+
if (unstubGlobals) vi.unstubAllGlobals();
|
|
3040
|
+
}
|
|
3041
|
+
//#endregion
|
|
3042
|
+
export { NodeBenchmarkRunner as N, Snapshots as S, TestRunner as T, assert as a, vitest as b, createExpect as c, globalExpect as g, inject as i, should as s, vi as v };
|
|
3043
|
+
|
|
3044
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC5ETm15Rmt2Si5qcyIsIm5hbWVzIjpbImNoYWkuQXNzZXJ0aW9uIiwiY2hhaS51c2UiLCJleHBlY3QiLCJjaGFpLmV4cGVjdCIsImNoYWkuYXNzZXJ0IiwiY2hhaS5zaG91bGQiXSwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9ub2RlX21vZHVsZXMvLnBucG0vdml0ZXN0QDQuMS4xMF9Ab3BlbnRlbGVtZXRyeSthcGlAMS45LjBfQHR5cGVzK25vZGVAMjUuMC43X0B2aXRlc3QrY292ZXJhZ2UtdjhANC4xLjEwX21zX2Y5Y2ZjZmVkZGQ2M2U2NTZkNDAxMGM5ODUyMWFmMjZjL25vZGVfbW9kdWxlcy92aXRlc3QvZGlzdC9jaHVua3MvdGVzdC5ETm15Rmt2Si5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBnZXRDdXJyZW50VGVzdCwgdXBkYXRlVGFzaywgY3JlYXRlVGFza0NvbGxlY3RvciwgZ2V0Q3VycmVudFN1aXRlLCBnZXRIb29rcywgZ2V0Rm4gfSBmcm9tICdAdml0ZXN0L3J1bm5lcic7XG5pbXBvcnQgeyBhc3NlcnRUeXBlcywgY3JlYXRlU2ltcGxlU3RhY2tUcmFjZSwgY3JlYXRlRGVmZXIgfSBmcm9tICdAdml0ZXN0L3V0aWxzL2hlbHBlcnMnO1xuaW1wb3J0IHsgZ2V0U2FmZVRpbWVycywgZGVsYXkgfSBmcm9tICdAdml0ZXN0L3V0aWxzL3RpbWVycyc7XG5pbXBvcnQgeyBhIGFzIGdldEJlbmNoT3B0aW9ucywgZyBhcyBnZXRCZW5jaEZuIH0gZnJvbSAnLi9iZW5jaG1hcmsuQ1hfb1kwM1YuanMnO1xuaW1wb3J0IHsgaSBhcyBpc0NoaWxkUHJvY2VzcywgdyBhcyB3YWl0Rm9ySW1wb3J0c1RvUmVzb2x2ZSwgciBhcyByZXNldE1vZHVsZXMsIGcgYXMgZ2V0V29ya2VyU3RhdGUgfSBmcm9tICcuL3V0aWxzLkJYNUZnOEM0LmpzJztcbmltcG9ydCB7IGNoYWksIHdyYXBBc3NlcnRpb24sIHJlY29yZEFzeW5jRXhwZWN0LCBjcmVhdGVBc3NlcnRpb25NZXNzYWdlLCBlcXVhbHMsIGl0ZXJhYmxlRXF1YWxpdHksIHN1YnNldEVxdWFsaXR5LCBKZXN0RXh0ZW5kLCBKZXN0Q2hhaUV4cGVjdCwgQ2hhaVN0eWxlQXNzZXJ0aW9ucywgSmVzdEFzeW1tZXRyaWNNYXRjaGVycywgR0xPQkFMX0VYUEVDVCwgQVNZTU1FVFJJQ19NQVRDSEVSU19PQkpFQ1QsIGdldFN0YXRlLCBzZXRTdGF0ZSwgYWRkQ3VzdG9tRXF1YWxpdHlUZXN0ZXJzLCBjdXN0b21NYXRjaGVycyB9IGZyb20gJ0B2aXRlc3QvZXhwZWN0JztcbmltcG9ydCB7IGdldE5hbWVzLCBnZXRUZXN0cywgZ2V0VGVzdE5hbWUsIGNyZWF0ZUNoYWluYWJsZSwgbWF0Y2hlc1RhZ3MgfSBmcm9tICdAdml0ZXN0L3J1bm5lci91dGlscyc7XG5pbXBvcnQgeyBwcm9jZXNzRXJyb3IgfSBmcm9tICdAdml0ZXN0L3V0aWxzL2Vycm9yJztcbmltcG9ydCB7IG5vcm1hbGl6ZSB9IGZyb20gJ3BhdGhlJztcbmltcG9ydCB7IGZuLCBzcHlPbiwgcmVzdG9yZUFsbE1vY2tzLCByZXNldEFsbE1vY2tzLCBjbGVhckFsbE1vY2tzLCBpc01vY2tGdW5jdGlvbiB9IGZyb20gJ0B2aXRlc3Qvc3B5JztcbmltcG9ydCAnQHZpdGVzdC91dGlscy9vZmZzZXQnO1xuaW1wb3J0IHsgcGFyc2VTaW5nbGVTdGFjayB9IGZyb20gJ0B2aXRlc3QvdXRpbHMvc291cmNlLW1hcCc7XG5pbXBvcnQgeyBjIGFzIGNvbW1vbmpzR2xvYmFsIH0gZnJvbSAnLi9fY29tbW9uanNIZWxwZXJzLkQyNnR5M0V3LmpzJztcbmltcG9ydCB7IFIgYXMgUmVhbERhdGUsIGIgYXMgcmVzZXREYXRlLCBtIGFzIG1vY2tEYXRlLCByIGFzIHJwYyB9IGZyb20gJy4vcnBjLk16WGV0M2psLmpzJztcbmltcG9ydCB7IGFkZFNlcmlhbGl6ZXIsIHN0cmlwU25hcHNob3RJbmRlbnRhdGlvbiwgU25hcHNob3RDbGllbnQgfSBmcm9tICdAdml0ZXN0L3NuYXBzaG90JztcblxudmFyIGZha2VUaW1lcnNTcmMgPSB7fTtcblxudmFyIGdsb2JhbDtcbnZhciBoYXNSZXF1aXJlZEdsb2JhbDtcblxuZnVuY3Rpb24gcmVxdWlyZUdsb2JhbCAoKSB7XG5cdGlmIChoYXNSZXF1aXJlZEdsb2JhbCkgcmV0dXJuIGdsb2JhbDtcblx0aGFzUmVxdWlyZWRHbG9iYWwgPSAxO1xuXG5cdC8qKlxuXHQgKiBBIHJlZmVyZW5jZSB0byB0aGUgZ2xvYmFsIG9iamVjdFxuXHQgKiBAdHlwZSB7b2JqZWN0fSBnbG9iYWxPYmplY3Rcblx0ICovXG5cdHZhciBnbG9iYWxPYmplY3Q7XG5cblx0LyogaXN0YW5idWwgaWdub3JlIGVsc2UgKi9cblx0aWYgKHR5cGVvZiBjb21tb25qc0dsb2JhbCAhPT0gXCJ1bmRlZmluZWRcIikge1xuXHQgICAgLy8gTm9kZVxuXHQgICAgZ2xvYmFsT2JqZWN0ID0gY29tbW9uanNHbG9iYWw7XG5cdH0gZWxzZSBpZiAodHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIikge1xuXHQgICAgLy8gQnJvd3NlclxuXHQgICAgZ2xvYmFsT2JqZWN0ID0gd2luZG93O1xuXHR9IGVsc2Uge1xuXHQgICAgLy8gV2ViV29ya2VyXG5cdCAgICBnbG9iYWxPYmplY3QgPSBzZWxmO1xuXHR9XG5cblx0Z2xvYmFsID0gZ2xvYmFsT2JqZWN0O1xuXHRyZXR1cm4gZ2xvYmFsO1xufVxuXG52YXIgdGhyb3dzT25Qcm90b18xO1xudmFyIGhhc1JlcXVpcmVkVGhyb3dzT25Qcm90bztcblxuZnVuY3Rpb24gcmVxdWlyZVRocm93c09uUHJvdG8gKCkge1xuXHRpZiAoaGFzUmVxdWlyZWRUaHJvd3NPblByb3RvKSByZXR1cm4gdGhyb3dzT25Qcm90b18xO1xuXHRoYXNSZXF1aXJlZFRocm93c09uUHJvdG8gPSAxO1xuXG5cdC8qKlxuXHQgKiBJcyB0cnVlIHdoZW4gdGhlIGVudmlyb25tZW50IGNhdXNlcyBhbiBlcnJvciB0byBiZSB0aHJvd24gZm9yIGFjY2Vzc2luZyB0aGVcblx0ICogX19wcm90b19fIHByb3BlcnR5LlxuXHQgKiBUaGlzIGlzIG5lY2Vzc2FyeSBpbiBvcmRlciB0byBzdXBwb3J0IGBub2RlIC0tZGlzYWJsZS1wcm90bz10aHJvd2AuXG5cdCAqXG5cdCAqIFNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9PYmplY3QvcHJvdG9cblx0ICogQHR5cGUge2Jvb2xlYW59XG5cdCAqL1xuXHRsZXQgdGhyb3dzT25Qcm90bztcblx0dHJ5IHtcblx0ICAgIGNvbnN0IG9iamVjdCA9IHt9O1xuXHQgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXByb3RvLCBuby11bnVzZWQtZXhwcmVzc2lvbnNcblx0ICAgIG9iamVjdC5fX3Byb3RvX187XG5cdCAgICB0aHJvd3NPblByb3RvID0gZmFsc2U7XG5cdH0gY2F0Y2ggKF8pIHtcblx0ICAgIC8vIFRoaXMgYnJhbmNoIGlzIGNvdmVyZWQgd2hlbiB0ZXN0cyBhcmUgcnVuIHdpdGggYC0tZGlzYWJsZS1wcm90bz10aHJvd2AsXG5cdCAgICAvLyBob3dldmVyIHdlIGNhbiB0ZXN0IGJvdGggYnJhbmNoZXMgYXQgdGhlIHNhbWUgdGltZSwgc28gdGhpcyBpcyBpZ25vcmVkXG5cdCAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuXHQgICAgdGhyb3dzT25Qcm90byA9IHRydWU7XG5cdH1cblxuXHR0aHJvd3NPblByb3RvXzEgPSB0aHJvd3NPblByb3RvO1xuXHRyZXR1cm4gdGhyb3dzT25Qcm90b18xO1xufVxuXG52YXIgY29weVByb3RvdHlwZU1ldGhvZHM7XG52YXIgaGFzUmVxdWlyZWRDb3B5UHJvdG90eXBlTWV0aG9kcztcblxuZnVuY3Rpb24gcmVxdWlyZUNvcHlQcm90b3R5cGVNZXRob2RzICgpIHtcblx0aWYgKGhhc1JlcXVpcmVkQ29weVByb3RvdHlwZU1ldGhvZHMpIHJldHVybiBjb3B5UHJvdG90eXBlTWV0aG9kcztcblx0aGFzUmVxdWlyZWRDb3B5UHJvdG90eXBlTWV0aG9kcyA9IDE7XG5cblx0dmFyIGNhbGwgPSBGdW5jdGlvbi5jYWxsO1xuXHR2YXIgdGhyb3dzT25Qcm90byA9IHJlcXVpcmVUaHJvd3NPblByb3RvKCk7XG5cblx0dmFyIGRpc2FsbG93ZWRQcm9wZXJ0aWVzID0gW1xuXHQgICAgLy8gaWdub3JlIHNpemUgYmVjYXVzZSBpdCB0aHJvd3MgZnJvbSBNYXBcblx0ICAgIFwic2l6ZVwiLFxuXHQgICAgXCJjYWxsZXJcIixcblx0ICAgIFwiY2FsbGVlXCIsXG5cdCAgICBcImFyZ3VtZW50c1wiLFxuXHRdO1xuXG5cdC8vIFRoaXMgYnJhbmNoIGlzIGNvdmVyZWQgd2hlbiB0ZXN0cyBhcmUgcnVuIHdpdGggYC0tZGlzYWJsZS1wcm90bz10aHJvd2AsXG5cdC8vIGhvd2V2ZXIgd2UgY2FuIHRlc3QgYm90aCBicmFuY2hlcyBhdCB0aGUgc2FtZSB0aW1lLCBzbyB0aGlzIGlzIGlnbm9yZWRcblx0LyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cblx0aWYgKHRocm93c09uUHJvdG8pIHtcblx0ICAgIGRpc2FsbG93ZWRQcm9wZXJ0aWVzLnB1c2goXCJfX3Byb3RvX19cIik7XG5cdH1cblxuXHRjb3B5UHJvdG90eXBlTWV0aG9kcyA9IGZ1bmN0aW9uIGNvcHlQcm90b3R5cGVNZXRob2RzKHByb3RvdHlwZSkge1xuXHQgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEBzaW5vbmpzL25vLXByb3RvdHlwZS1tZXRob2RzL25vLXByb3RvdHlwZS1tZXRob2RzXG5cdCAgICByZXR1cm4gT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMocHJvdG90eXBlKS5yZWR1Y2UoZnVuY3Rpb24gKFxuXHQgICAgICAgIHJlc3VsdCxcblx0ICAgICAgICBuYW1lXG5cdCAgICApIHtcblx0ICAgICAgICBpZiAoZGlzYWxsb3dlZFByb3BlcnRpZXMuaW5jbHVkZXMobmFtZSkpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcblx0ICAgICAgICB9XG5cblx0ICAgICAgICBpZiAodHlwZW9mIHByb3RvdHlwZVtuYW1lXSAhPT0gXCJmdW5jdGlvblwiKSB7XG5cdCAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgcmVzdWx0W25hbWVdID0gY2FsbC5iaW5kKHByb3RvdHlwZVtuYW1lXSk7XG5cblx0ICAgICAgICByZXR1cm4gcmVzdWx0O1xuXHQgICAgfSxcblx0ICAgIE9iamVjdC5jcmVhdGUobnVsbCkpO1xuXHR9O1xuXHRyZXR1cm4gY29weVByb3RvdHlwZU1ldGhvZHM7XG59XG5cbnZhciBhcnJheTtcbnZhciBoYXNSZXF1aXJlZEFycmF5O1xuXG5mdW5jdGlvbiByZXF1aXJlQXJyYXkgKCkge1xuXHRpZiAoaGFzUmVxdWlyZWRBcnJheSkgcmV0dXJuIGFycmF5O1xuXHRoYXNSZXF1aXJlZEFycmF5ID0gMTtcblxuXHR2YXIgY29weVByb3RvdHlwZSA9IHJlcXVpcmVDb3B5UHJvdG90eXBlTWV0aG9kcygpO1xuXG5cdGFycmF5ID0gY29weVByb3RvdHlwZShBcnJheS5wcm90b3R5cGUpO1xuXHRyZXR1cm4gYXJyYXk7XG59XG5cbnZhciBjYWxsZWRJbk9yZGVyXzE7XG52YXIgaGFzUmVxdWlyZWRDYWxsZWRJbk9yZGVyO1xuXG5mdW5jdGlvbiByZXF1aXJlQ2FsbGVkSW5PcmRlciAoKSB7XG5cdGlmIChoYXNSZXF1aXJlZENhbGxlZEluT3JkZXIpIHJldHVybiBjYWxsZWRJbk9yZGVyXzE7XG5cdGhhc1JlcXVpcmVkQ2FsbGVkSW5PcmRlciA9IDE7XG5cblx0dmFyIGV2ZXJ5ID0gcmVxdWlyZUFycmF5KCkuZXZlcnk7XG5cblx0LyoqXG5cdCAqIEBwcml2YXRlXG5cdCAqL1xuXHRmdW5jdGlvbiBoYXNDYWxsc0xlZnQoY2FsbE1hcCwgc3B5KSB7XG5cdCAgICBpZiAoY2FsbE1hcFtzcHkuaWRdID09PSB1bmRlZmluZWQpIHtcblx0ICAgICAgICBjYWxsTWFwW3NweS5pZF0gPSAwO1xuXHQgICAgfVxuXG5cdCAgICByZXR1cm4gY2FsbE1hcFtzcHkuaWRdIDwgc3B5LmNhbGxDb3VudDtcblx0fVxuXG5cdC8qKlxuXHQgKiBAcHJpdmF0ZVxuXHQgKi9cblx0ZnVuY3Rpb24gY2hlY2tBZGphY2VudENhbGxzKGNhbGxNYXAsIHNweSwgaW5kZXgsIHNwaWVzKSB7XG5cdCAgICB2YXIgY2FsbGVkQmVmb3JlTmV4dCA9IHRydWU7XG5cblx0ICAgIGlmIChpbmRleCAhPT0gc3BpZXMubGVuZ3RoIC0gMSkge1xuXHQgICAgICAgIGNhbGxlZEJlZm9yZU5leHQgPSBzcHkuY2FsbGVkQmVmb3JlKHNwaWVzW2luZGV4ICsgMV0pO1xuXHQgICAgfVxuXG5cdCAgICBpZiAoaGFzQ2FsbHNMZWZ0KGNhbGxNYXAsIHNweSkgJiYgY2FsbGVkQmVmb3JlTmV4dCkge1xuXHQgICAgICAgIGNhbGxNYXBbc3B5LmlkXSArPSAxO1xuXHQgICAgICAgIHJldHVybiB0cnVlO1xuXHQgICAgfVxuXG5cdCAgICByZXR1cm4gZmFsc2U7XG5cdH1cblxuXHQvKipcblx0ICogQSBTaW5vbiBwcm94eSBvYmplY3QgKGZha2UsIHNweSwgc3R1Yilcblx0ICogQHR5cGVkZWYge29iamVjdH0gU2lub25Qcm94eVxuXHQgKiBAcHJvcGVydHkge0Z1bmN0aW9ufSBjYWxsZWRCZWZvcmUgLSBBIG1ldGhvZCB0aGF0IGRldGVybWluZXMgaWYgdGhpcyBwcm94eSB3YXMgY2FsbGVkIGJlZm9yZSBhbm90aGVyIG9uZVxuXHQgKiBAcHJvcGVydHkge3N0cmluZ30gaWQgLSBTb21lIGlkXG5cdCAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBjYWxsQ291bnQgLSBOdW1iZXIgb2YgdGltZXMgdGhpcyBwcm94eSBoYXMgYmVlbiBjYWxsZWRcblx0ICovXG5cblx0LyoqXG5cdCAqIFJldHVybnMgdHJ1ZSB3aGVuIHRoZSBzcGllcyBoYXZlIGJlZW4gY2FsbGVkIGluIHRoZSBvcmRlciB0aGV5IHdlcmUgc3VwcGxpZWQgaW5cblx0ICogQHBhcmFtICB7U2lub25Qcm94eVtdIHwgU2lub25Qcm94eX0gc3BpZXMgQW4gYXJyYXkgb2YgcHJveGllcywgb3Igc2V2ZXJhbCBwcm94aWVzIGFzIGFyZ3VtZW50c1xuXHQgKiBAcmV0dXJucyB7Ym9vbGVhbn0gdHJ1ZSB3aGVuIHNwaWVzIGFyZSBjYWxsZWQgaW4gb3JkZXIsIGZhbHNlIG90aGVyd2lzZVxuXHQgKi9cblx0ZnVuY3Rpb24gY2FsbGVkSW5PcmRlcihzcGllcykge1xuXHQgICAgdmFyIGNhbGxNYXAgPSB7fTtcblx0ICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bmRlcnNjb3JlLWRhbmdsZVxuXHQgICAgdmFyIF9zcGllcyA9IGFyZ3VtZW50cy5sZW5ndGggPiAxID8gYXJndW1lbnRzIDogc3BpZXM7XG5cblx0ICAgIHJldHVybiBldmVyeShfc3BpZXMsIGNoZWNrQWRqYWNlbnRDYWxscy5iaW5kKG51bGwsIGNhbGxNYXApKTtcblx0fVxuXG5cdGNhbGxlZEluT3JkZXJfMSA9IGNhbGxlZEluT3JkZXI7XG5cdHJldHVybiBjYWxsZWRJbk9yZGVyXzE7XG59XG5cbnZhciBjbGFzc05hbWVfMTtcbnZhciBoYXNSZXF1aXJlZENsYXNzTmFtZTtcblxuZnVuY3Rpb24gcmVxdWlyZUNsYXNzTmFtZSAoKSB7XG5cdGlmIChoYXNSZXF1aXJlZENsYXNzTmFtZSkgcmV0dXJuIGNsYXNzTmFtZV8xO1xuXHRoYXNSZXF1aXJlZENsYXNzTmFtZSA9IDE7XG5cblx0LyoqXG5cdCAqIFJldHVybnMgYSBkaXNwbGF5IG5hbWUgZm9yIGEgdmFsdWUgZnJvbSBhIGNvbnN0cnVjdG9yXG5cdCAqIEBwYXJhbSAge29iamVjdH0gdmFsdWUgQSB2YWx1ZSB0byBleGFtaW5lXG5cdCAqIEByZXR1cm5zIHsoc3RyaW5nfG51bGwpfSBBIHN0cmluZyBvciBudWxsXG5cdCAqL1xuXHRmdW5jdGlvbiBjbGFzc05hbWUodmFsdWUpIHtcblx0ICAgIGNvbnN0IG5hbWUgPSB2YWx1ZS5jb25zdHJ1Y3RvciAmJiB2YWx1ZS5jb25zdHJ1Y3Rvci5uYW1lO1xuXHQgICAgcmV0dXJuIG5hbWUgfHwgbnVsbDtcblx0fVxuXG5cdGNsYXNzTmFtZV8xID0gY2xhc3NOYW1lO1xuXHRyZXR1cm4gY2xhc3NOYW1lXzE7XG59XG5cbnZhciBkZXByZWNhdGVkID0ge307XG5cbi8qIGVzbGludC1kaXNhYmxlIG5vLWNvbnNvbGUgKi9cblxudmFyIGhhc1JlcXVpcmVkRGVwcmVjYXRlZDtcblxuZnVuY3Rpb24gcmVxdWlyZURlcHJlY2F0ZWQgKCkge1xuXHRpZiAoaGFzUmVxdWlyZWREZXByZWNhdGVkKSByZXR1cm4gZGVwcmVjYXRlZDtcblx0aGFzUmVxdWlyZWREZXByZWNhdGVkID0gMTtcblx0KGZ1bmN0aW9uIChleHBvcnRzJDEpIHtcblxuXHRcdC8qKlxuXHRcdCAqIFJldHVybnMgYSBmdW5jdGlvbiB0aGF0IHdpbGwgaW52b2tlIHRoZSBzdXBwbGllZCBmdW5jdGlvbiBhbmQgcHJpbnQgYVxuXHRcdCAqIGRlcHJlY2F0aW9uIHdhcm5pbmcgdG8gdGhlIGNvbnNvbGUgZWFjaCB0aW1lIGl0IGlzIGNhbGxlZC5cblx0XHQgKiBAcGFyYW0gIHtGdW5jdGlvbn0gZnVuY1xuXHRcdCAqIEBwYXJhbSAge3N0cmluZ30gbXNnXG5cdFx0ICogQHJldHVybnMge0Z1bmN0aW9ufVxuXHRcdCAqL1xuXHRcdGV4cG9ydHMkMS53cmFwID0gZnVuY3Rpb24gKGZ1bmMsIG1zZykge1xuXHRcdCAgICB2YXIgd3JhcHBlZCA9IGZ1bmN0aW9uICgpIHtcblx0XHQgICAgICAgIGV4cG9ydHMkMS5wcmludFdhcm5pbmcobXNnKTtcblx0XHQgICAgICAgIHJldHVybiBmdW5jLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG5cdFx0ICAgIH07XG5cdFx0ICAgIGlmIChmdW5jLnByb3RvdHlwZSkge1xuXHRcdCAgICAgICAgd3JhcHBlZC5wcm90b3R5cGUgPSBmdW5jLnByb3RvdHlwZTtcblx0XHQgICAgfVxuXHRcdCAgICByZXR1cm4gd3JhcHBlZDtcblx0XHR9O1xuXG5cdFx0LyoqXG5cdFx0ICogUmV0dXJucyBhIHN0cmluZyB3aGljaCBjYW4gYmUgc3VwcGxpZWQgdG8gYHdyYXAoKWAgdG8gbm90aWZ5IHRoZSB1c2VyIHRoYXQgYVxuXHRcdCAqIHBhcnRpY3VsYXIgcGFydCBvZiB0aGUgc2lub24gQVBJIGhhcyBiZWVuIGRlcHJlY2F0ZWQuXG5cdFx0ICogQHBhcmFtICB7c3RyaW5nfSBwYWNrYWdlTmFtZVxuXHRcdCAqIEBwYXJhbSAge3N0cmluZ30gZnVuY05hbWVcblx0XHQgKiBAcmV0dXJucyB7c3RyaW5nfVxuXHRcdCAqL1xuXHRcdGV4cG9ydHMkMS5kZWZhdWx0TXNnID0gZnVuY3Rpb24gKHBhY2thZ2VOYW1lLCBmdW5jTmFtZSkge1xuXHRcdCAgICByZXR1cm4gYCR7cGFja2FnZU5hbWV9LiR7ZnVuY05hbWV9IGlzIGRlcHJlY2F0ZWQgYW5kIHdpbGwgYmUgcmVtb3ZlZCBmcm9tIHRoZSBwdWJsaWMgQVBJIGluIGEgZnV0dXJlIHZlcnNpb24gb2YgJHtwYWNrYWdlTmFtZX0uYDtcblx0XHR9O1xuXG5cdFx0LyoqXG5cdFx0ICogUHJpbnRzIGEgd2FybmluZyBvbiB0aGUgY29uc29sZSwgd2hlbiBpdCBleGlzdHNcblx0XHQgKiBAcGFyYW0gIHtzdHJpbmd9IG1zZ1xuXHRcdCAqIEByZXR1cm5zIHt1bmRlZmluZWR9XG5cdFx0ICovXG5cdFx0ZXhwb3J0cyQxLnByaW50V2FybmluZyA9IGZ1bmN0aW9uIChtc2cpIHtcblx0XHQgICAgLyogaXN0YW5idWwgaWdub3JlIG5leHQgKi9cblx0XHQgICAgaWYgKHR5cGVvZiBwcm9jZXNzID09PSBcIm9iamVjdFwiICYmIHByb2Nlc3MuZW1pdFdhcm5pbmcpIHtcblx0XHQgICAgICAgIC8vIEVtaXQgV2FybmluZ3MgaW4gTm9kZVxuXHRcdCAgICAgICAgcHJvY2Vzcy5lbWl0V2FybmluZyhtc2cpO1xuXHRcdCAgICB9IGVsc2UgaWYgKGNvbnNvbGUuaW5mbykge1xuXHRcdCAgICAgICAgY29uc29sZS5pbmZvKG1zZyk7XG5cdFx0ICAgIH0gZWxzZSB7XG5cdFx0ICAgICAgICBjb25zb2xlLmxvZyhtc2cpO1xuXHRcdCAgICB9XG5cdFx0fTsgXG5cdH0gKGRlcHJlY2F0ZWQpKTtcblx0cmV0dXJuIGRlcHJlY2F0ZWQ7XG59XG5cbnZhciBldmVyeTtcbnZhciBoYXNSZXF1aXJlZEV2ZXJ5O1xuXG5mdW5jdGlvbiByZXF1aXJlRXZlcnkgKCkge1xuXHRpZiAoaGFzUmVxdWlyZWRFdmVyeSkgcmV0dXJuIGV2ZXJ5O1xuXHRoYXNSZXF1aXJlZEV2ZXJ5ID0gMTtcblxuXHQvKipcblx0ICogUmV0dXJucyB0cnVlIHdoZW4gZm4gcmV0dXJucyB0cnVlIGZvciBhbGwgbWVtYmVycyBvZiBvYmouXG5cdCAqIFRoaXMgaXMgYW4gZXZlcnkgaW1wbGVtZW50YXRpb24gdGhhdCB3b3JrcyBmb3IgYWxsIGl0ZXJhYmxlc1xuXHQgKiBAcGFyYW0gIHtvYmplY3R9ICAgb2JqXG5cdCAqIEBwYXJhbSAge0Z1bmN0aW9ufSBmblxuXHQgKiBAcmV0dXJucyB7Ym9vbGVhbn1cblx0ICovXG5cdGV2ZXJ5ID0gZnVuY3Rpb24gZXZlcnkob2JqLCBmbikge1xuXHQgICAgdmFyIHBhc3MgPSB0cnVlO1xuXG5cdCAgICB0cnkge1xuXHQgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAc2lub25qcy9uby1wcm90b3R5cGUtbWV0aG9kcy9uby1wcm90b3R5cGUtbWV0aG9kc1xuXHQgICAgICAgIG9iai5mb3JFYWNoKGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgaWYgKCFmbi5hcHBseSh0aGlzLCBhcmd1bWVudHMpKSB7XG5cdCAgICAgICAgICAgICAgICAvLyBUaHJvd2luZyBhbiBlcnJvciBpcyB0aGUgb25seSB3YXkgdG8gYnJlYWsgYGZvckVhY2hgXG5cdCAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH0pO1xuXHQgICAgfSBjYXRjaCAoZSkge1xuXHQgICAgICAgIHBhc3MgPSBmYWxzZTtcblx0ICAgIH1cblxuXHQgICAgcmV0dXJuIHBhc3M7XG5cdH07XG5cdHJldHVybiBldmVyeTtcbn1cblxudmFyIGZ1bmN0aW9uTmFtZTtcbnZhciBoYXNSZXF1aXJlZEZ1bmN0aW9uTmFtZTtcblxuZnVuY3Rpb24gcmVxdWlyZUZ1bmN0aW9uTmFtZSAoKSB7XG5cdGlmIChoYXNSZXF1aXJlZEZ1bmN0aW9uTmFtZSkgcmV0dXJuIGZ1bmN0aW9uTmFtZTtcblx0aGFzUmVxdWlyZWRGdW5jdGlvbk5hbWUgPSAxO1xuXG5cdC8qKlxuXHQgKiBSZXR1cm5zIGEgZGlzcGxheSBuYW1lIGZvciBhIGZ1bmN0aW9uXG5cdCAqIEBwYXJhbSAge0Z1bmN0aW9ufSBmdW5jXG5cdCAqIEByZXR1cm5zIHtzdHJpbmd9XG5cdCAqL1xuXHRmdW5jdGlvbk5hbWUgPSBmdW5jdGlvbiBmdW5jdGlvbk5hbWUoZnVuYykge1xuXHQgICAgaWYgKCFmdW5jKSB7XG5cdCAgICAgICAgcmV0dXJuIFwiXCI7XG5cdCAgICB9XG5cblx0ICAgIHRyeSB7XG5cdCAgICAgICAgcmV0dXJuIChcblx0ICAgICAgICAgICAgZnVuYy5kaXNwbGF5TmFtZSB8fFxuXHQgICAgICAgICAgICBmdW5jLm5hbWUgfHxcblx0ICAgICAgICAgICAgLy8gVXNlIGZ1bmN0aW9uIGRlY29tcG9zaXRpb24gYXMgYSBsYXN0IHJlc29ydCB0byBnZXQgZnVuY3Rpb25cblx0ICAgICAgICAgICAgLy8gbmFtZS4gRG9lcyBub3QgcmVseSBvbiBmdW5jdGlvbiBkZWNvbXBvc2l0aW9uIHRvIHdvcmsgLSBpZiBpdFxuXHQgICAgICAgICAgICAvLyBkb2Vzbid0IGRlYnVnZ2luZyB3aWxsIGJlIHNsaWdodGx5IGxlc3MgaW5mb3JtYXRpdmVcblx0ICAgICAgICAgICAgLy8gKGkuZS4gdG9TdHJpbmcgd2lsbCBzYXkgJ3NweScgcmF0aGVyIHRoYW4gJ215RnVuYycpLlxuXHQgICAgICAgICAgICAoU3RyaW5nKGZ1bmMpLm1hdGNoKC9mdW5jdGlvbiAoW15cXHMoXSspLykgfHwgW10pWzFdXG5cdCAgICAgICAgKTtcblx0ICAgIH0gY2F0Y2ggKGUpIHtcblx0ICAgICAgICAvLyBTdHJpbmdpZnkgbWF5IGZhaWwgYW5kIHdlIG1pZ2h0IGdldCBhbiBleGNlcHRpb24sIGFzIGEgbGFzdC1sYXN0XG5cdCAgICAgICAgLy8gcmVzb3J0IGZhbGwgYmFjayB0byBlbXB0eSBzdHJpbmcuXG5cdCAgICAgICAgcmV0dXJuIFwiXCI7XG5cdCAgICB9XG5cdH07XG5cdHJldHVybiBmdW5jdGlvbk5hbWU7XG59XG5cbnZhciBvcmRlckJ5Rmlyc3RDYWxsXzE7XG52YXIgaGFzUmVxdWlyZWRPcmRlckJ5Rmlyc3RDYWxsO1xuXG5mdW5jdGlvbiByZXF1aXJlT3JkZXJCeUZpcnN0Q2FsbCAoKSB7XG5cdGlmIChoYXNSZXF1aXJlZE9yZGVyQnlGaXJzdENhbGwpIHJldHVybiBvcmRlckJ5Rmlyc3RDYWxsXzE7XG5cdGhhc1JlcXVpcmVkT3JkZXJCeUZpcnN0Q2FsbCA9IDE7XG5cblx0dmFyIHNvcnQgPSByZXF1aXJlQXJyYXkoKS5zb3J0O1xuXHR2YXIgc2xpY2UgPSByZXF1aXJlQXJyYXkoKS5zbGljZTtcblxuXHQvKipcblx0ICogQHByaXZhdGVcblx0ICovXG5cdGZ1bmN0aW9uIGNvbXBhcmF0b3IoYSwgYikge1xuXHQgICAgLy8gdXVpZCwgd29uJ3QgZXZlciBiZSBlcXVhbFxuXHQgICAgdmFyIGFDYWxsID0gYS5nZXRDYWxsKDApO1xuXHQgICAgdmFyIGJDYWxsID0gYi5nZXRDYWxsKDApO1xuXHQgICAgdmFyIGFJZCA9IChhQ2FsbCAmJiBhQ2FsbC5jYWxsSWQpIHx8IC0xO1xuXHQgICAgdmFyIGJJZCA9IChiQ2FsbCAmJiBiQ2FsbC5jYWxsSWQpIHx8IC0xO1xuXG5cdCAgICByZXR1cm4gYUlkIDwgYklkID8gLTEgOiAxO1xuXHR9XG5cblx0LyoqXG5cdCAqIEEgU2lub24gcHJveHkgb2JqZWN0IChmYWtlLCBzcHksIHN0dWIpXG5cdCAqIEB0eXBlZGVmIHtvYmplY3R9IFNpbm9uUHJveHlcblx0ICogQHByb3BlcnR5IHtGdW5jdGlvbn0gZ2V0Q2FsbCAtIEEgbWV0aG9kIHRoYXQgY2FuIHJldHVybiB0aGUgZmlyc3QgY2FsbFxuXHQgKi9cblxuXHQvKipcblx0ICogU29ydHMgYW4gYXJyYXkgb2YgU2lub25Qcm94eSBpbnN0YW5jZXMgKGZha2UsIHNweSwgc3R1YikgYnkgdGhlaXIgZmlyc3QgY2FsbFxuXHQgKiBAcGFyYW0gIHtTaW5vblByb3h5W10gfCBTaW5vblByb3h5fSBzcGllc1xuXHQgKiBAcmV0dXJucyB7U2lub25Qcm94eVtdfVxuXHQgKi9cblx0ZnVuY3Rpb24gb3JkZXJCeUZpcnN0Q2FsbChzcGllcykge1xuXHQgICAgcmV0dXJuIHNvcnQoc2xpY2Uoc3BpZXMpLCBjb21wYXJhdG9yKTtcblx0fVxuXG5cdG9yZGVyQnlGaXJzdENhbGxfMSA9IG9yZGVyQnlGaXJzdENhbGw7XG5cdHJldHVybiBvcmRlckJ5Rmlyc3RDYWxsXzE7XG59XG5cbnZhciBfZnVuY3Rpb247XG52YXIgaGFzUmVxdWlyZWRfZnVuY3Rpb247XG5cbmZ1bmN0aW9uIHJlcXVpcmVfZnVuY3Rpb24gKCkge1xuXHRpZiAoaGFzUmVxdWlyZWRfZnVuY3Rpb24pIHJldHVybiBfZnVuY3Rpb247XG5cdGhhc1JlcXVpcmVkX2Z1bmN0aW9uID0gMTtcblxuXHR2YXIgY29weVByb3RvdHlwZSA9IHJlcXVpcmVDb3B5UHJvdG90eXBlTWV0aG9kcygpO1xuXG5cdF9mdW5jdGlvbiA9IGNvcHlQcm90b3R5cGUoRnVuY3Rpb24ucHJvdG90eXBlKTtcblx0cmV0dXJuIF9mdW5jdGlvbjtcbn1cblxudmFyIG1hcDtcbnZhciBoYXNSZXF1aXJlZE1hcDtcblxuZnVuY3Rpb24gcmVxdWlyZU1hcCAoKSB7XG5cdGlmIChoYXNSZXF1aXJlZE1hcCkgcmV0dXJuIG1hcDtcblx0aGFzUmVxdWlyZWRNYXAgPSAxO1xuXG5cdHZhciBjb3B5UHJvdG90eXBlID0gcmVxdWlyZUNvcHlQcm90b3R5cGVNZXRob2RzKCk7XG5cblx0bWFwID0gY29weVByb3RvdHlwZShNYXAucHJvdG90eXBlKTtcblx0cmV0dXJuIG1hcDtcbn1cblxudmFyIG9iamVjdDtcbnZhciBoYXNSZXF1aXJlZE9iamVjdDtcblxuZnVuY3Rpb24gcmVxdWlyZU9iamVjdCAoKSB7XG5cdGlmIChoYXNSZXF1aXJlZE9iamVjdCkgcmV0dXJuIG9iamVjdDtcblx0aGFzUmVxdWlyZWRPYmplY3QgPSAxO1xuXG5cdHZhciBjb3B5UHJvdG90eXBlID0gcmVxdWlyZUNvcHlQcm90b3R5cGVNZXRob2RzKCk7XG5cblx0b2JqZWN0ID0gY29weVByb3RvdHlwZShPYmplY3QucHJvdG90eXBlKTtcblx0cmV0dXJuIG9iamVjdDtcbn1cblxudmFyIHNldDtcbnZhciBoYXNSZXF1aXJlZFNldDtcblxuZnVuY3Rpb24gcmVxdWlyZVNldCAoKSB7XG5cdGlmIChoYXNSZXF1aXJlZFNldCkgcmV0dXJuIHNldDtcblx0aGFzUmVxdWlyZWRTZXQgPSAxO1xuXG5cdHZhciBjb3B5UHJvdG90eXBlID0gcmVxdWlyZUNvcHlQcm90b3R5cGVNZXRob2RzKCk7XG5cblx0c2V0ID0gY29weVByb3RvdHlwZShTZXQucHJvdG90eXBlKTtcblx0cmV0dXJuIHNldDtcbn1cblxudmFyIHN0cmluZztcbnZhciBoYXNSZXF1aXJlZFN0cmluZztcblxuZnVuY3Rpb24gcmVxdWlyZVN0cmluZyAoKSB7XG5cdGlmIChoYXNSZXF1aXJlZFN0cmluZykgcmV0dXJuIHN0cmluZztcblx0aGFzUmVxdWlyZWRTdHJpbmcgPSAxO1xuXG5cdHZhciBjb3B5UHJvdG90eXBlID0gcmVxdWlyZUNvcHlQcm90b3R5cGVNZXRob2RzKCk7XG5cblx0c3RyaW5nID0gY29weVByb3RvdHlwZShTdHJpbmcucHJvdG90eXBlKTtcblx0cmV0dXJuIHN0cmluZztcbn1cblxudmFyIHByb3RvdHlwZXM7XG52YXIgaGFzUmVxdWlyZWRQcm90b3R5cGVzO1xuXG5mdW5jdGlvbiByZXF1aXJlUHJvdG90eXBlcyAoKSB7XG5cdGlmIChoYXNSZXF1aXJlZFByb3RvdHlwZXMpIHJldHVybiBwcm90b3R5cGVzO1xuXHRoYXNSZXF1aXJlZFByb3RvdHlwZXMgPSAxO1xuXG5cdHByb3RvdHlwZXMgPSB7XG5cdCAgICBhcnJheTogcmVxdWlyZUFycmF5KCksXG5cdCAgICBmdW5jdGlvbjogcmVxdWlyZV9mdW5jdGlvbigpLFxuXHQgICAgbWFwOiByZXF1aXJlTWFwKCksXG5cdCAgICBvYmplY3Q6IHJlcXVpcmVPYmplY3QoKSxcblx0ICAgIHNldDogcmVxdWlyZVNldCgpLFxuXHQgICAgc3RyaW5nOiByZXF1aXJlU3RyaW5nKCksXG5cdH07XG5cdHJldHVybiBwcm90b3R5cGVzO1xufVxuXG52YXIgdHlwZURldGVjdCQxID0ge2V4cG9ydHM6IHt9fTtcblxudmFyIHR5cGVEZXRlY3QgPSB0eXBlRGV0ZWN0JDEuZXhwb3J0cztcblxudmFyIGhhc1JlcXVpcmVkVHlwZURldGVjdDtcblxuZnVuY3Rpb24gcmVxdWlyZVR5cGVEZXRlY3QgKCkge1xuXHRpZiAoaGFzUmVxdWlyZWRUeXBlRGV0ZWN0KSByZXR1cm4gdHlwZURldGVjdCQxLmV4cG9ydHM7XG5cdGhhc1JlcXVpcmVkVHlwZURldGVjdCA9IDE7XG5cdChmdW5jdGlvbiAobW9kdWxlLCBleHBvcnRzJDEpIHtcblx0XHQoZnVuY3Rpb24gKGdsb2JhbCwgZmFjdG9yeSkge1xuXHRcdFx0bW9kdWxlLmV4cG9ydHMgPSBmYWN0b3J5KCkgO1xuXHRcdH0odHlwZURldGVjdCwgKGZ1bmN0aW9uICgpIHtcblx0XHQvKiAhXG5cdFx0ICogdHlwZS1kZXRlY3Rcblx0XHQgKiBDb3B5cmlnaHQoYykgMjAxMyBqYWtlIGx1ZXIgPGpha2VAYWxvZ2ljYWxwYXJhZG94LmNvbT5cblx0XHQgKiBNSVQgTGljZW5zZWRcblx0XHQgKi9cblx0XHR2YXIgcHJvbWlzZUV4aXN0cyA9IHR5cGVvZiBQcm9taXNlID09PSAnZnVuY3Rpb24nO1xuXG5cdFx0LyogZXNsaW50LWRpc2FibGUgbm8tdW5kZWYgKi9cblx0XHR2YXIgZ2xvYmFsT2JqZWN0ID0gdHlwZW9mIHNlbGYgPT09ICdvYmplY3QnID8gc2VsZiA6IGNvbW1vbmpzR2xvYmFsOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIGlkLWJsYWNrbGlzdFxuXG5cdFx0dmFyIHN5bWJvbEV4aXN0cyA9IHR5cGVvZiBTeW1ib2wgIT09ICd1bmRlZmluZWQnO1xuXHRcdHZhciBtYXBFeGlzdHMgPSB0eXBlb2YgTWFwICE9PSAndW5kZWZpbmVkJztcblx0XHR2YXIgc2V0RXhpc3RzID0gdHlwZW9mIFNldCAhPT0gJ3VuZGVmaW5lZCc7XG5cdFx0dmFyIHdlYWtNYXBFeGlzdHMgPSB0eXBlb2YgV2Vha01hcCAhPT0gJ3VuZGVmaW5lZCc7XG5cdFx0dmFyIHdlYWtTZXRFeGlzdHMgPSB0eXBlb2YgV2Vha1NldCAhPT0gJ3VuZGVmaW5lZCc7XG5cdFx0dmFyIGRhdGFWaWV3RXhpc3RzID0gdHlwZW9mIERhdGFWaWV3ICE9PSAndW5kZWZpbmVkJztcblx0XHR2YXIgc3ltYm9sSXRlcmF0b3JFeGlzdHMgPSBzeW1ib2xFeGlzdHMgJiYgdHlwZW9mIFN5bWJvbC5pdGVyYXRvciAhPT0gJ3VuZGVmaW5lZCc7XG5cdFx0dmFyIHN5bWJvbFRvU3RyaW5nVGFnRXhpc3RzID0gc3ltYm9sRXhpc3RzICYmIHR5cGVvZiBTeW1ib2wudG9TdHJpbmdUYWcgIT09ICd1bmRlZmluZWQnO1xuXHRcdHZhciBzZXRFbnRyaWVzRXhpc3RzID0gc2V0RXhpc3RzICYmIHR5cGVvZiBTZXQucHJvdG90eXBlLmVudHJpZXMgPT09ICdmdW5jdGlvbic7XG5cdFx0dmFyIG1hcEVudHJpZXNFeGlzdHMgPSBtYXBFeGlzdHMgJiYgdHlwZW9mIE1hcC5wcm90b3R5cGUuZW50cmllcyA9PT0gJ2Z1bmN0aW9uJztcblx0XHR2YXIgc2V0SXRlcmF0b3JQcm90b3R5cGUgPSBzZXRFbnRyaWVzRXhpc3RzICYmIE9iamVjdC5nZXRQcm90b3R5cGVPZihuZXcgU2V0KCkuZW50cmllcygpKTtcblx0XHR2YXIgbWFwSXRlcmF0b3JQcm90b3R5cGUgPSBtYXBFbnRyaWVzRXhpc3RzICYmIE9iamVjdC5nZXRQcm90b3R5cGVPZihuZXcgTWFwKCkuZW50cmllcygpKTtcblx0XHR2YXIgYXJyYXlJdGVyYXRvckV4aXN0cyA9IHN5bWJvbEl0ZXJhdG9yRXhpc3RzICYmIHR5cGVvZiBBcnJheS5wcm90b3R5cGVbU3ltYm9sLml0ZXJhdG9yXSA9PT0gJ2Z1bmN0aW9uJztcblx0XHR2YXIgYXJyYXlJdGVyYXRvclByb3RvdHlwZSA9IGFycmF5SXRlcmF0b3JFeGlzdHMgJiYgT2JqZWN0LmdldFByb3RvdHlwZU9mKFtdW1N5bWJvbC5pdGVyYXRvcl0oKSk7XG5cdFx0dmFyIHN0cmluZ0l0ZXJhdG9yRXhpc3RzID0gc3ltYm9sSXRlcmF0b3JFeGlzdHMgJiYgdHlwZW9mIFN0cmluZy5wcm90b3R5cGVbU3ltYm9sLml0ZXJhdG9yXSA9PT0gJ2Z1bmN0aW9uJztcblx0XHR2YXIgc3RyaW5nSXRlcmF0b3JQcm90b3R5cGUgPSBzdHJpbmdJdGVyYXRvckV4aXN0cyAmJiBPYmplY3QuZ2V0UHJvdG90eXBlT2YoJydbU3ltYm9sLml0ZXJhdG9yXSgpKTtcblx0XHR2YXIgdG9TdHJpbmdMZWZ0U2xpY2VMZW5ndGggPSA4O1xuXHRcdHZhciB0b1N0cmluZ1JpZ2h0U2xpY2VMZW5ndGggPSAtMTtcblx0XHQvKipcblx0XHQgKiAjIyMgdHlwZU9mIChvYmopXG5cdFx0ICpcblx0XHQgKiBVc2VzIGBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nYCB0byBkZXRlcm1pbmUgdGhlIHR5cGUgb2YgYW4gb2JqZWN0LFxuXHRcdCAqIG5vcm1hbGlzaW5nIGJlaGF2aW91ciBhY3Jvc3MgZW5naW5lIHZlcnNpb25zICYgd2VsbCBvcHRpbWlzZWQuXG5cdFx0ICpcblx0XHQgKiBAcGFyYW0ge01peGVkfSBvYmplY3Rcblx0XHQgKiBAcmV0dXJuIHtTdHJpbmd9IG9iamVjdCB0eXBlXG5cdFx0ICogQGFwaSBwdWJsaWNcblx0XHQgKi9cblx0XHRmdW5jdGlvbiB0eXBlRGV0ZWN0KG9iaikge1xuXHRcdCAgLyogISBTcGVlZCBvcHRpbWlzYXRpb25cblx0XHQgICAqIFByZTpcblx0XHQgICAqICAgc3RyaW5nIGxpdGVyYWwgICAgIHggMywwMzksMDM1IG9wcy9zZWMgwrExLjYyJSAoNzggcnVucyBzYW1wbGVkKVxuXHRcdCAgICogICBib29sZWFuIGxpdGVyYWwgICAgeCAxLDQyNCwxMzggb3BzL3NlYyDCsTQuNTQlICg3NSBydW5zIHNhbXBsZWQpXG5cdFx0ICAgKiAgIG51bWJlciBsaXRlcmFsICAgICB4IDEsNjUzLDE1MyBvcHMvc2VjIMKxMS45MSUgKDgyIHJ1bnMgc2FtcGxlZClcblx0XHQgICAqICAgdW5kZWZpbmVkICAgICAgICAgIHggOSw5NzgsNjYwIG9wcy9zZWMgwrExLjkyJSAoNzUgcnVucyBzYW1wbGVkKVxuXHRcdCAgICogICBmdW5jdGlvbiAgICAgICAgICAgeCAyLDU1Niw3Njkgb3BzL3NlYyDCsTEuNzMlICg3NyBydW5zIHNhbXBsZWQpXG5cdFx0ICAgKiBQb3N0OlxuXHRcdCAgICogICBzdHJpbmcgbGl0ZXJhbCAgICAgeCAzOCw1NjQsNzk2IG9wcy9zZWMgwrExLjE1JSAoNzkgcnVucyBzYW1wbGVkKVxuXHRcdCAgICogICBib29sZWFuIGxpdGVyYWwgICAgeCAzMSwxNDgsOTQwIG9wcy9zZWMgwrExLjEwJSAoNzkgcnVucyBzYW1wbGVkKVxuXHRcdCAgICogICBudW1iZXIgbGl0ZXJhbCAgICAgeCAzMiw2NzksMzMwIG9wcy9zZWMgwrExLjkwJSAoNzggcnVucyBzYW1wbGVkKVxuXHRcdCAgICogICB1bmRlZmluZWQgICAgICAgICAgeCAzMiwzNjMsMzY4IG9wcy9zZWMgwrExLjA3JSAoODIgcnVucyBzYW1wbGVkKVxuXHRcdCAgICogICBmdW5jdGlvbiAgICAgICAgICAgeCAzMSwyOTYsODcwIG9wcy9zZWMgwrEwLjk2JSAoODMgcnVucyBzYW1wbGVkKVxuXHRcdCAgICovXG5cdFx0ICB2YXIgdHlwZW9mT2JqID0gdHlwZW9mIG9iajtcblx0XHQgIGlmICh0eXBlb2ZPYmogIT09ICdvYmplY3QnKSB7XG5cdFx0ICAgIHJldHVybiB0eXBlb2ZPYmo7XG5cdFx0ICB9XG5cblx0XHQgIC8qICEgU3BlZWQgb3B0aW1pc2F0aW9uXG5cdFx0ICAgKiBQcmU6XG5cdFx0ICAgKiAgIG51bGwgICAgICAgICAgICAgICB4IDI4LDY0NSw3NjUgb3BzL3NlYyDCsTEuMTclICg4MiBydW5zIHNhbXBsZWQpXG5cdFx0ICAgKiBQb3N0OlxuXHRcdCAgICogICBudWxsICAgICAgICAgICAgICAgeCAzNiw0MjgsOTYyIG9wcy9zZWMgwrExLjM3JSAoODQgcnVucyBzYW1wbGVkKVxuXHRcdCAgICovXG5cdFx0ICBpZiAob2JqID09PSBudWxsKSB7XG5cdFx0ICAgIHJldHVybiAnbnVsbCc7XG5cdFx0ICB9XG5cblx0XHQgIC8qICEgU3BlYyBDb25mb3JtYW5jZVxuXHRcdCAgICogVGVzdDogYE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh3aW5kb3cpYGBcblx0XHQgICAqICAtIE5vZGUgPT09IFwiW29iamVjdCBnbG9iYWxdXCJcblx0XHQgICAqICAtIENocm9tZSA9PT0gXCJbb2JqZWN0IGdsb2JhbF1cIlxuXHRcdCAgICogIC0gRmlyZWZveCA9PT0gXCJbb2JqZWN0IFdpbmRvd11cIlxuXHRcdCAgICogIC0gUGhhbnRvbUpTID09PSBcIltvYmplY3QgV2luZG93XVwiXG5cdFx0ICAgKiAgLSBTYWZhcmkgPT09IFwiW29iamVjdCBXaW5kb3ddXCJcblx0XHQgICAqICAtIElFIDExID09PSBcIltvYmplY3QgV2luZG93XVwiXG5cdFx0ICAgKiAgLSBJRSBFZGdlID09PSBcIltvYmplY3QgV2luZG93XVwiXG5cdFx0ICAgKiBUZXN0OiBgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHRoaXMpYGBcblx0XHQgICAqICAtIENocm9tZSBXb3JrZXIgPT09IFwiW29iamVjdCBnbG9iYWxdXCJcblx0XHQgICAqICAtIEZpcmVmb3ggV29ya2VyID09PSBcIltvYmplY3QgRGVkaWNhdGVkV29ya2VyR2xvYmFsU2NvcGVdXCJcblx0XHQgICAqICAtIFNhZmFyaSBXb3JrZXIgPT09IFwiW29iamVjdCBEZWRpY2F0ZWRXb3JrZXJHbG9iYWxTY29wZV1cIlxuXHRcdCAgICogIC0gSUUgMTEgV29ya2VyID09PSBcIltvYmplY3QgV29ya2VyR2xvYmFsU2NvcGVdXCJcblx0XHQgICAqICAtIElFIEVkZ2UgV29ya2VyID09PSBcIltvYmplY3QgV29ya2VyR2xvYmFsU2NvcGVdXCJcblx0XHQgICAqL1xuXHRcdCAgaWYgKG9iaiA9PT0gZ2xvYmFsT2JqZWN0KSB7XG5cdFx0ICAgIHJldHVybiAnZ2xvYmFsJztcblx0XHQgIH1cblxuXHRcdCAgLyogISBTcGVlZCBvcHRpbWlzYXRpb25cblx0XHQgICAqIFByZTpcblx0XHQgICAqICAgYXJyYXkgbGl0ZXJhbCAgICAgIHggMiw4ODgsMzUyIG9wcy9zZWMgwrEwLjY3JSAoODIgcnVucyBzYW1wbGVkKVxuXHRcdCAgICogUG9zdDpcblx0XHQgICAqICAgYXJyYXkgbGl0ZXJhbCAgICAgIHggMjIsNDc5LDY1MCBvcHMvc2VjIMKxMC45NiUgKDgxIHJ1bnMgc2FtcGxlZClcblx0XHQgICAqL1xuXHRcdCAgaWYgKFxuXHRcdCAgICBBcnJheS5pc0FycmF5KG9iaikgJiZcblx0XHQgICAgKHN5bWJvbFRvU3RyaW5nVGFnRXhpc3RzID09PSBmYWxzZSB8fCAhKFN5bWJvbC50b1N0cmluZ1RhZyBpbiBvYmopKVxuXHRcdCAgKSB7XG5cdFx0ICAgIHJldHVybiAnQXJyYXknO1xuXHRcdCAgfVxuXG5cdFx0ICAvLyBOb3QgY2FjaGluZyBleGlzdGVuY2Ugb2YgYHdpbmRvd2AgYW5kIHJlbGF0ZWQgcHJvcGVydGllcyBkdWUgdG8gcG90ZW50aWFsXG5cdFx0ICAvLyBmb3IgYHdpbmRvd2AgdG8gYmUgdW5zZXQgYmVmb3JlIHRlc3RzIGluIHF1YXNpLWJyb3dzZXIgZW52aXJvbm1lbnRzLlxuXHRcdCAgaWYgKHR5cGVvZiB3aW5kb3cgPT09ICdvYmplY3QnICYmIHdpbmRvdyAhPT0gbnVsbCkge1xuXHRcdCAgICAvKiAhIFNwZWMgQ29uZm9ybWFuY2Vcblx0XHQgICAgICogKGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvbXVsdGlwYWdlL2Jyb3dzZXJzLmh0bWwjbG9jYXRpb24pXG5cdFx0ICAgICAqIFdoYXRXRyBIVE1MJDcuNy4zIC0gVGhlIGBMb2NhdGlvbmAgaW50ZXJmYWNlXG5cdFx0ICAgICAqIFRlc3Q6IGBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwod2luZG93LmxvY2F0aW9uKWBgXG5cdFx0ICAgICAqICAtIElFIDw9MTEgPT09IFwiW29iamVjdCBPYmplY3RdXCJcblx0XHQgICAgICogIC0gSUUgRWRnZSA8PTEzID09PSBcIltvYmplY3QgT2JqZWN0XVwiXG5cdFx0ICAgICAqL1xuXHRcdCAgICBpZiAodHlwZW9mIHdpbmRvdy5sb2NhdGlvbiA9PT0gJ29iamVjdCcgJiYgb2JqID09PSB3aW5kb3cubG9jYXRpb24pIHtcblx0XHQgICAgICByZXR1cm4gJ0xvY2F0aW9uJztcblx0XHQgICAgfVxuXG5cdFx0ICAgIC8qICEgU3BlYyBDb25mb3JtYW5jZVxuXHRcdCAgICAgKiAoaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy8jZG9jdW1lbnQpXG5cdFx0ICAgICAqIFdoYXRXRyBIVE1MJDMuMS4xIC0gVGhlIGBEb2N1bWVudGAgb2JqZWN0XG5cdFx0ICAgICAqIE5vdGU6IE1vc3QgYnJvd3NlcnMgY3VycmVudGx5IGFkaGVyIHRvIHRoZSBXM0MgRE9NIExldmVsIDIgc3BlY1xuXHRcdCAgICAgKiAgICAgICAoaHR0cHM6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUhUTUwvaHRtbC5odG1sI0lELTI2ODA5MjY4KVxuXHRcdCAgICAgKiAgICAgICB3aGljaCBzdWdnZXN0cyB0aGF0IGJyb3dzZXJzIHNob3VsZCB1c2UgSFRNTFRhYmxlQ2VsbEVsZW1lbnQgZm9yXG5cdFx0ICAgICAqICAgICAgIGJvdGggVEQgYW5kIFRIIGVsZW1lbnRzLiBXaGF0V0cgc2VwYXJhdGVzIHRoZXNlLlxuXHRcdCAgICAgKiAgICAgICBXaGF0V0cgSFRNTCBzdGF0ZXM6XG5cdFx0ICAgICAqICAgICAgICAgPiBGb3IgaGlzdG9yaWNhbCByZWFzb25zLCBXaW5kb3cgb2JqZWN0cyBtdXN0IGFsc28gaGF2ZSBhXG5cdFx0ICAgICAqICAgICAgICAgPiB3cml0YWJsZSwgY29uZmlndXJhYmxlLCBub24tZW51bWVyYWJsZSBwcm9wZXJ0eSBuYW1lZFxuXHRcdCAgICAgKiAgICAgICAgID4gSFRNTERvY3VtZW50IHdob3NlIHZhbHVlIGlzIHRoZSBEb2N1bWVudCBpbnRlcmZhY2Ugb2JqZWN0LlxuXHRcdCAgICAgKiBUZXN0OiBgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGRvY3VtZW50KWBgXG5cdFx0ICAgICAqICAtIENocm9tZSA9PT0gXCJbb2JqZWN0IEhUTUxEb2N1bWVudF1cIlxuXHRcdCAgICAgKiAgLSBGaXJlZm94ID09PSBcIltvYmplY3QgSFRNTERvY3VtZW50XVwiXG5cdFx0ICAgICAqICAtIFNhZmFyaSA9PT0gXCJbb2JqZWN0IEhUTUxEb2N1bWVudF1cIlxuXHRcdCAgICAgKiAgLSBJRSA8PTEwID09PSBcIltvYmplY3QgRG9jdW1lbnRdXCJcblx0XHQgICAgICogIC0gSUUgMTEgPT09IFwiW29iamVjdCBIVE1MRG9jdW1lbnRdXCJcblx0XHQgICAgICogIC0gSUUgRWRnZSA8PTEzID09PSBcIltvYmplY3QgSFRNTERvY3VtZW50XVwiXG5cdFx0ICAgICAqL1xuXHRcdCAgICBpZiAodHlwZW9mIHdpbmRvdy5kb2N1bWVudCA9PT0gJ29iamVjdCcgJiYgb2JqID09PSB3aW5kb3cuZG9jdW1lbnQpIHtcblx0XHQgICAgICByZXR1cm4gJ0RvY3VtZW50Jztcblx0XHQgICAgfVxuXG5cdFx0ICAgIGlmICh0eXBlb2Ygd2luZG93Lm5hdmlnYXRvciA9PT0gJ29iamVjdCcpIHtcblx0XHQgICAgICAvKiAhIFNwZWMgQ29uZm9ybWFuY2Vcblx0XHQgICAgICAgKiAoaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2Uvd2ViYXBwYXBpcy5odG1sI21pbWV0eXBlYXJyYXkpXG5cdFx0ICAgICAgICogV2hhdFdHIEhUTUwkOC42LjEuNSAtIFBsdWdpbnMgLSBJbnRlcmZhY2UgTWltZVR5cGVBcnJheVxuXHRcdCAgICAgICAqIFRlc3Q6IGBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobmF2aWdhdG9yLm1pbWVUeXBlcylgYFxuXHRcdCAgICAgICAqICAtIElFIDw9MTAgPT09IFwiW29iamVjdCBNU01pbWVUeXBlc0NvbGxlY3Rpb25dXCJcblx0XHQgICAgICAgKi9cblx0XHQgICAgICBpZiAodHlwZW9mIHdpbmRvdy5uYXZpZ2F0b3IubWltZVR5cGVzID09PSAnb2JqZWN0JyAmJlxuXHRcdCAgICAgICAgICBvYmogPT09IHdpbmRvdy5uYXZpZ2F0b3IubWltZVR5cGVzKSB7XG5cdFx0ICAgICAgICByZXR1cm4gJ01pbWVUeXBlQXJyYXknO1xuXHRcdCAgICAgIH1cblxuXHRcdCAgICAgIC8qICEgU3BlYyBDb25mb3JtYW5jZVxuXHRcdCAgICAgICAqIChodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS93ZWJhcHBhcGlzLmh0bWwjcGx1Z2luYXJyYXkpXG5cdFx0ICAgICAgICogV2hhdFdHIEhUTUwkOC42LjEuNSAtIFBsdWdpbnMgLSBJbnRlcmZhY2UgUGx1Z2luQXJyYXlcblx0XHQgICAgICAgKiBUZXN0OiBgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG5hdmlnYXRvci5wbHVnaW5zKWBgXG5cdFx0ICAgICAgICogIC0gSUUgPD0xMCA9PT0gXCJbb2JqZWN0IE1TUGx1Z2luc0NvbGxlY3Rpb25dXCJcblx0XHQgICAgICAgKi9cblx0XHQgICAgICBpZiAodHlwZW9mIHdpbmRvdy5uYXZpZ2F0b3IucGx1Z2lucyA9PT0gJ29iamVjdCcgJiZcblx0XHQgICAgICAgICAgb2JqID09PSB3aW5kb3cubmF2aWdhdG9yLnBsdWdpbnMpIHtcblx0XHQgICAgICAgIHJldHVybiAnUGx1Z2luQXJyYXknO1xuXHRcdCAgICAgIH1cblx0XHQgICAgfVxuXG5cdFx0ICAgIGlmICgodHlwZW9mIHdpbmRvdy5IVE1MRWxlbWVudCA9PT0gJ2Z1bmN0aW9uJyB8fFxuXHRcdCAgICAgICAgdHlwZW9mIHdpbmRvdy5IVE1MRWxlbWVudCA9PT0gJ29iamVjdCcpICYmXG5cdFx0ICAgICAgICBvYmogaW5zdGFuY2VvZiB3aW5kb3cuSFRNTEVsZW1lbnQpIHtcblx0XHQgICAgICAvKiAhIFNwZWMgQ29uZm9ybWFuY2Vcblx0XHQgICAgICAqIChodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS93ZWJhcHBhcGlzLmh0bWwjcGx1Z2luYXJyYXkpXG5cdFx0ICAgICAgKiBXaGF0V0cgSFRNTCQ0LjQuNCAtIFRoZSBgYmxvY2txdW90ZWAgZWxlbWVudCAtIEludGVyZmFjZSBgSFRNTFF1b3RlRWxlbWVudGBcblx0XHQgICAgICAqIFRlc3Q6IGBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYmxvY2txdW90ZScpKWBgXG5cdFx0ICAgICAgKiAgLSBJRSA8PTEwID09PSBcIltvYmplY3QgSFRNTEJsb2NrRWxlbWVudF1cIlxuXHRcdCAgICAgICovXG5cdFx0ICAgICAgaWYgKG9iai50YWdOYW1lID09PSAnQkxPQ0tRVU9URScpIHtcblx0XHQgICAgICAgIHJldHVybiAnSFRNTFF1b3RlRWxlbWVudCc7XG5cdFx0ICAgICAgfVxuXG5cdFx0ICAgICAgLyogISBTcGVjIENvbmZvcm1hbmNlXG5cdFx0ICAgICAgICogKGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvI2h0bWx0YWJsZWRhdGFjZWxsZWxlbWVudClcblx0XHQgICAgICAgKiBXaGF0V0cgSFRNTCQ0LjkuOSAtIFRoZSBgdGRgIGVsZW1lbnQgLSBJbnRlcmZhY2UgYEhUTUxUYWJsZURhdGFDZWxsRWxlbWVudGBcblx0XHQgICAgICAgKiBOb3RlOiBNb3N0IGJyb3dzZXJzIGN1cnJlbnRseSBhZGhlciB0byB0aGUgVzNDIERPTSBMZXZlbCAyIHNwZWNcblx0XHQgICAgICAgKiAgICAgICAoaHR0cHM6Ly93d3cudzMub3JnL1RSL0RPTS1MZXZlbC0yLUhUTUwvaHRtbC5odG1sI0lELTgyOTE1MDc1KVxuXHRcdCAgICAgICAqICAgICAgIHdoaWNoIHN1Z2dlc3RzIHRoYXQgYnJvd3NlcnMgc2hvdWxkIHVzZSBIVE1MVGFibGVDZWxsRWxlbWVudCBmb3Jcblx0XHQgICAgICAgKiAgICAgICBib3RoIFREIGFuZCBUSCBlbGVtZW50cy4gV2hhdFdHIHNlcGFyYXRlcyB0aGVzZS5cblx0XHQgICAgICAgKiBUZXN0OiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgndGQnKSlcblx0XHQgICAgICAgKiAgLSBDaHJvbWUgPT09IFwiW29iamVjdCBIVE1MVGFibGVDZWxsRWxlbWVudF1cIlxuXHRcdCAgICAgICAqICAtIEZpcmVmb3ggPT09IFwiW29iamVjdCBIVE1MVGFibGVDZWxsRWxlbWVudF1cIlxuXHRcdCAgICAgICAqICAtIFNhZmFyaSA9PT0gXCJbb2JqZWN0IEhUTUxUYWJsZUNlbGxFbGVtZW50XVwiXG5cdFx0ICAgICAgICovXG5cdFx0ICAgICAgaWYgKG9iai50YWdOYW1lID09PSAnVEQnKSB7XG5cdFx0ICAgICAgICByZXR1cm4gJ0hUTUxUYWJsZURhdGFDZWxsRWxlbWVudCc7XG5cdFx0ICAgICAgfVxuXG5cdFx0ICAgICAgLyogISBTcGVjIENvbmZvcm1hbmNlXG5cdFx0ICAgICAgICogKGh0dHBzOi8vaHRtbC5zcGVjLndoYXR3Zy5vcmcvI2h0bWx0YWJsZWhlYWRlcmNlbGxlbGVtZW50KVxuXHRcdCAgICAgICAqIFdoYXRXRyBIVE1MJDQuOS45IC0gVGhlIGB0ZGAgZWxlbWVudCAtIEludGVyZmFjZSBgSFRNTFRhYmxlSGVhZGVyQ2VsbEVsZW1lbnRgXG5cdFx0ICAgICAgICogTm90ZTogTW9zdCBicm93c2VycyBjdXJyZW50bHkgYWRoZXIgdG8gdGhlIFczQyBET00gTGV2ZWwgMiBzcGVjXG5cdFx0ICAgICAgICogICAgICAgKGh0dHBzOi8vd3d3LnczLm9yZy9UUi9ET00tTGV2ZWwtMi1IVE1ML2h0bWwuaHRtbCNJRC04MjkxNTA3NSlcblx0XHQgICAgICAgKiAgICAgICB3aGljaCBzdWdnZXN0cyB0aGF0IGJyb3dzZXJzIHNob3VsZCB1c2UgSFRNTFRhYmxlQ2VsbEVsZW1lbnQgZm9yXG5cdFx0ICAgICAgICogICAgICAgYm90aCBURCBhbmQgVEggZWxlbWVudHMuIFdoYXRXRyBzZXBhcmF0ZXMgdGhlc2UuXG5cdFx0ICAgICAgICogVGVzdDogT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3RoJykpXG5cdFx0ICAgICAgICogIC0gQ2hyb21lID09PSBcIltvYmplY3QgSFRNTFRhYmxlQ2VsbEVsZW1lbnRdXCJcblx0XHQgICAgICAgKiAgLSBGaXJlZm94ID09PSBcIltvYmplY3QgSFRNTFRhYmxlQ2VsbEVsZW1lbnRdXCJcblx0XHQgICAgICAgKiAgLSBTYWZhcmkgPT09IFwiW29iamVjdCBIVE1MVGFibGVDZWxsRWxlbWVudF1cIlxuXHRcdCAgICAgICAqL1xuXHRcdCAgICAgIGlmIChvYmoudGFnTmFtZSA9PT0gJ1RIJykge1xuXHRcdCAgICAgICAgcmV0dXJuICdIVE1MVGFibGVIZWFkZXJDZWxsRWxlbWVudCc7XG5cdFx0ICAgICAgfVxuXHRcdCAgICB9XG5cdFx0ICB9XG5cblx0XHQgIC8qICEgU3BlZWQgb3B0aW1pc2F0aW9uXG5cdFx0ICAqIFByZTpcblx0XHQgICogICBGbG9hdDY0QXJyYXkgICAgICAgeCA2MjUsNjQ0IG9wcy9zZWMgwrExLjU4JSAoODAgcnVucyBzYW1wbGVkKVxuXHRcdCAgKiAgIEZsb2F0MzJBcnJheSAgICAgICB4IDEsMjc5LDg1MiBvcHMvc2VjIMKxMi45MSUgKDc3IHJ1bnMgc2FtcGxlZClcblx0XHQgICogICBVaW50MzJBcnJheSAgICAgICAgeCAxLDE3OCwxODUgb3BzL3NlYyDCsTEuOTUlICg4MyBydW5zIHNhbXBsZWQpXG5cdFx0ICAqICAgVWludDE2QXJyYXkgICAgICAgIHggMSwwMDgsMzgwIG9wcy9zZWMgwrEyLjI1JSAoODAgcnVucyBzYW1wbGVkKVxuXHRcdCAgKiAgIFVpbnQ4QXJyYXkgICAgICAgICB4IDEsMTI4LDA0MCBvcHMvc2VjIMKxMi4xMSUgKDgxIHJ1bnMgc2FtcGxlZClcblx0XHQgICogICBJbnQzMkFycmF5ICAgICAgICAgeCAxLDE3MCwxMTkgb3BzL3NlYyDCsTIuODglICg4MCBydW5zIHNhbXBsZWQpXG5cdFx0ICAqICAgSW50MTZBcnJheSAgICAgICAgIHggMSwxNzYsMzQ4IG9wcy9zZWMgwrE1Ljc5JSAoODYgcnVucyBzYW1wbGVkKVxuXHRcdCAgKiAgIEludDhBcnJheSAgICAgICAgICB4IDEsMDU4LDcwNyBvcHMvc2VjIMKxNC45NCUgKDc3IHJ1bnMgc2FtcGxlZClcblx0XHQgICogICBVaW50OENsYW1wZWRBcnJheSAgeCAxLDExMCw2MzMgb3BzL3NlYyDCsTQuMjAlICg4MCBydW5zIHNhbXBsZWQpXG5cdFx0ICAqIFBvc3Q6XG5cdFx0ICAqICAgRmxvYXQ2NEFycmF5ICAgICAgIHggNywxMDUsNjcxIG9wcy9zZWMgwrExMy40NyUgKDY0IHJ1bnMgc2FtcGxlZClcblx0XHQgICogICBGbG9hdDMyQXJyYXkgICAgICAgeCA1LDg4Nyw5MTIgb3BzL3NlYyDCsTEuNDYlICg4MiBydW5zIHNhbXBsZWQpXG5cdFx0ICAqICAgVWludDMyQXJyYXkgICAgICAgIHggNiw0OTEsNjYxIG9wcy9zZWMgwrExLjc2JSAoNzkgcnVucyBzYW1wbGVkKVxuXHRcdCAgKiAgIFVpbnQxNkFycmF5ICAgICAgICB4IDYsNTU5LDc5NSBvcHMvc2VjIMKxMS42NyUgKDgyIHJ1bnMgc2FtcGxlZClcblx0XHQgICogICBVaW50OEFycmF5ICAgICAgICAgeCA2LDQ2Myw5NjYgb3BzL3NlYyDCsTEuNDMlICg4NSBydW5zIHNhbXBsZWQpXG5cdFx0ICAqICAgSW50MzJBcnJheSAgICAgICAgIHggNSw2NDEsODQxIG9wcy9zZWMgwrEzLjQ5JSAoODEgcnVucyBzYW1wbGVkKVxuXHRcdCAgKiAgIEludDE2QXJyYXkgICAgICAgICB4IDYsNTgzLDUxMSBvcHMvc2VjIMKxMS45OCUgKDgwIHJ1bnMgc2FtcGxlZClcblx0XHQgICogICBJbnQ4QXJyYXkgICAgICAgICAgeCA2LDYwNiwwNzggb3BzL3NlYyDCsTEuNzQlICg4MSBydW5zIHNhbXBsZWQpXG5cdFx0ICAqICAgVWludDhDbGFtcGVkQXJyYXkgIHggNiw2MDIsMjI0IG9wcy9zZWMgwrExLjc3JSAoODMgcnVucyBzYW1wbGVkKVxuXHRcdCAgKi9cblx0XHQgIHZhciBzdHJpbmdUYWcgPSAoc3ltYm9sVG9TdHJpbmdUYWdFeGlzdHMgJiYgb2JqW1N5bWJvbC50b1N0cmluZ1RhZ10pO1xuXHRcdCAgaWYgKHR5cGVvZiBzdHJpbmdUYWcgPT09ICdzdHJpbmcnKSB7XG5cdFx0ICAgIHJldHVybiBzdHJpbmdUYWc7XG5cdFx0ICB9XG5cblx0XHQgIHZhciBvYmpQcm90b3R5cGUgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2Yob2JqKTtcblx0XHQgIC8qICEgU3BlZWQgb3B0aW1pc2F0aW9uXG5cdFx0ICAqIFByZTpcblx0XHQgICogICByZWdleCBsaXRlcmFsICAgICAgeCAxLDc3MiwzODUgb3BzL3NlYyDCsTEuODUlICg3NyBydW5zIHNhbXBsZWQpXG5cdFx0ICAqICAgcmVnZXggY29uc3RydWN0b3IgIHggMiwxNDMsNjM0IG9wcy9zZWMgwrEyLjQ2JSAoNzggcnVucyBzYW1wbGVkKVxuXHRcdCAgKiBQb3N0OlxuXHRcdCAgKiAgIHJlZ2V4IGxpdGVyYWwgICAgICB4IDMsOTI4LDAwOSBvcHMvc2VjIMKxMC42NSUgKDc4IHJ1bnMgc2FtcGxlZClcblx0XHQgICogICByZWdleCBjb25zdHJ1Y3RvciAgeCAzLDkzMSwxMDggb3BzL3NlYyDCsTAuNTglICg4NCBydW5zIHNhbXBsZWQpXG5cdFx0ICAqL1xuXHRcdCAgaWYgKG9ialByb3RvdHlwZSA9PT0gUmVnRXhwLnByb3RvdHlwZSkge1xuXHRcdCAgICByZXR1cm4gJ1JlZ0V4cCc7XG5cdFx0ICB9XG5cblx0XHQgIC8qICEgU3BlZWQgb3B0aW1pc2F0aW9uXG5cdFx0ICAqIFByZTpcblx0XHQgICogICBkYXRlICAgICAgICAgICAgICAgeCAyLDEzMCwwNzQgb3BzL3NlYyDCsTQuNDIlICg2OCBydW5zIHNhbXBsZWQpXG5cdFx0ICAqIFBvc3Q6XG5cdFx0ICAqICAgZGF0ZSAgICAgICAgICAgICAgIHggMyw5NTMsNzc5IG9wcy9zZWMgwrExLjM1JSAoNzcgcnVucyBzYW1wbGVkKVxuXHRcdCAgKi9cblx0XHQgIGlmIChvYmpQcm90b3R5cGUgPT09IERhdGUucHJvdG90eXBlKSB7XG5cdFx0ICAgIHJldHVybiAnRGF0ZSc7XG5cdFx0ICB9XG5cblx0XHQgIC8qICEgU3BlYyBDb25mb3JtYW5jZVxuXHRcdCAgICogKGh0dHA6Ly93d3cuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvaW5kZXguaHRtbCNzZWMtcHJvbWlzZS5wcm90b3R5cGUtQEB0b3N0cmluZ3RhZylcblx0XHQgICAqIEVTNiQyNS40LjUuNCAtIFByb21pc2UucHJvdG90eXBlW0BAdG9TdHJpbmdUYWddIHNob3VsZCBiZSBcIlByb21pc2VcIjpcblx0XHQgICAqIFRlc3Q6IGBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoUHJvbWlzZS5yZXNvbHZlKCkpYGBcblx0XHQgICAqICAtIENocm9tZSA8PTQ3ID09PSBcIltvYmplY3QgT2JqZWN0XVwiXG5cdFx0ICAgKiAgLSBFZGdlIDw9MjAgPT09IFwiW29iamVjdCBPYmplY3RdXCJcblx0XHQgICAqICAtIEZpcmVmb3ggMjktTGF0ZXN0ID09PSBcIltvYmplY3QgUHJvbWlzZV1cIlxuXHRcdCAgICogIC0gU2FmYXJpIDcuMS1MYXRlc3QgPT09IFwiW29iamVjdCBQcm9taXNlXVwiXG5cdFx0ICAgKi9cblx0XHQgIGlmIChwcm9taXNlRXhpc3RzICYmIG9ialByb3RvdHlwZSA9PT0gUHJvbWlzZS5wcm90b3R5cGUpIHtcblx0XHQgICAgcmV0dXJuICdQcm9taXNlJztcblx0XHQgIH1cblxuXHRcdCAgLyogISBTcGVlZCBvcHRpbWlzYXRpb25cblx0XHQgICogUHJlOlxuXHRcdCAgKiAgIHNldCAgICAgICAgICAgICAgICB4IDIsMjIyLDE4NiBvcHMvc2VjIMKxMS4zMSUgKDgyIHJ1bnMgc2FtcGxlZClcblx0XHQgICogUG9zdDpcblx0XHQgICogICBzZXQgICAgICAgICAgICAgICAgeCA0LDU0NSw4Nzkgb3BzL3NlYyDCsTEuMTMlICg4MyBydW5zIHNhbXBsZWQpXG5cdFx0ICAqL1xuXHRcdCAgaWYgKHNldEV4aXN0cyAmJiBvYmpQcm90b3R5cGUgPT09IFNldC5wcm90b3R5cGUpIHtcblx0XHQgICAgcmV0dXJuICdTZXQnO1xuXHRcdCAgfVxuXG5cdFx0ICAvKiAhIFNwZWVkIG9wdGltaXNhdGlvblxuXHRcdCAgKiBQcmU6XG5cdFx0ICAqICAgbWFwICAgICAgICAgICAgICAgIHggMiwzOTYsODQyIG9wcy9zZWMgwrExLjU5JSAoODEgcnVucyBzYW1wbGVkKVxuXHRcdCAgKiBQb3N0OlxuXHRcdCAgKiAgIG1hcCAgICAgICAgICAgICAgICB4IDQsMTgzLDk0NSBvcHMvc2VjIMKxNi41OSUgKDgyIHJ1bnMgc2FtcGxlZClcblx0XHQgICovXG5cdFx0ICBpZiAobWFwRXhpc3RzICYmIG9ialByb3RvdHlwZSA9PT0gTWFwLnByb3RvdHlwZSkge1xuXHRcdCAgICByZXR1cm4gJ01hcCc7XG5cdFx0ICB9XG5cblx0XHQgIC8qICEgU3BlZWQgb3B0aW1pc2F0aW9uXG5cdFx0ICAqIFByZTpcblx0XHQgICogICB3ZWFrc2V0ICAgICAgICAgICAgeCAxLDMyMywyMjAgb3BzL3NlYyDCsTIuMTclICg3NiBydW5zIHNhbXBsZWQpXG5cdFx0ICAqIFBvc3Q6XG5cdFx0ICAqICAgd2Vha3NldCAgICAgICAgICAgIHggNCwyMzcsNTEwIG9wcy9zZWMgwrEyLjAxJSAoNzcgcnVucyBzYW1wbGVkKVxuXHRcdCAgKi9cblx0XHQgIGlmICh3ZWFrU2V0RXhpc3RzICYmIG9ialByb3RvdHlwZSA9PT0gV2Vha1NldC5wcm90b3R5cGUpIHtcblx0XHQgICAgcmV0dXJuICdXZWFrU2V0Jztcblx0XHQgIH1cblxuXHRcdCAgLyogISBTcGVlZCBvcHRpbWlzYXRpb25cblx0XHQgICogUHJlOlxuXHRcdCAgKiAgIHdlYWttYXAgICAgICAgICAgICB4IDEsNTAwLDI2MCBvcHMvc2VjIMKxMi4wMiUgKDc4IHJ1bnMgc2FtcGxlZClcblx0XHQgICogUG9zdDpcblx0XHQgICogICB3ZWFrbWFwICAgICAgICAgICAgeCAzLDg4MSwzODQgb3BzL3NlYyDCsTEuNDUlICg4MiBydW5zIHNhbXBsZWQpXG5cdFx0ICAqL1xuXHRcdCAgaWYgKHdlYWtNYXBFeGlzdHMgJiYgb2JqUHJvdG90eXBlID09PSBXZWFrTWFwLnByb3RvdHlwZSkge1xuXHRcdCAgICByZXR1cm4gJ1dlYWtNYXAnO1xuXHRcdCAgfVxuXG5cdFx0ICAvKiAhIFNwZWMgQ29uZm9ybWFuY2Vcblx0XHQgICAqIChodHRwOi8vd3d3LmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wL2luZGV4Lmh0bWwjc2VjLWRhdGF2aWV3LnByb3RvdHlwZS1AQHRvc3RyaW5ndGFnKVxuXHRcdCAgICogRVM2JDI0LjIuNC4yMSAtIERhdGFWaWV3LnByb3RvdHlwZVtAQHRvU3RyaW5nVGFnXSBzaG91bGQgYmUgXCJEYXRhVmlld1wiOlxuXHRcdCAgICogVGVzdDogYE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChuZXcgRGF0YVZpZXcobmV3IEFycmF5QnVmZmVyKDEpKSlgYFxuXHRcdCAgICogIC0gRWRnZSA8PTEzID09PSBcIltvYmplY3QgT2JqZWN0XVwiXG5cdFx0ICAgKi9cblx0XHQgIGlmIChkYXRhVmlld0V4aXN0cyAmJiBvYmpQcm90b3R5cGUgPT09IERhdGFWaWV3LnByb3RvdHlwZSkge1xuXHRcdCAgICByZXR1cm4gJ0RhdGFWaWV3Jztcblx0XHQgIH1cblxuXHRcdCAgLyogISBTcGVjIENvbmZvcm1hbmNlXG5cdFx0ICAgKiAoaHR0cDovL3d3dy5lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC9pbmRleC5odG1sI3NlYy0lbWFwaXRlcmF0b3Jwcm90b3R5cGUlLUBAdG9zdHJpbmd0YWcpXG5cdFx0ICAgKiBFUzYkMjMuMS41LjIuMiAtICVNYXBJdGVyYXRvclByb3RvdHlwZSVbQEB0b1N0cmluZ1RhZ10gc2hvdWxkIGJlIFwiTWFwIEl0ZXJhdG9yXCI6XG5cdFx0ICAgKiBUZXN0OiBgT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKG5ldyBNYXAoKS5lbnRyaWVzKCkpYGBcblx0XHQgICAqICAtIEVkZ2UgPD0xMyA9PT0gXCJbb2JqZWN0IE9iamVjdF1cIlxuXHRcdCAgICovXG5cdFx0ICBpZiAobWFwRXhpc3RzICYmIG9ialByb3RvdHlwZSA9PT0gbWFwSXRlcmF0b3JQcm90b3R5cGUpIHtcblx0XHQgICAgcmV0dXJuICdNYXAgSXRlcmF0b3InO1xuXHRcdCAgfVxuXG5cdFx0ICAvKiAhIFNwZWMgQ29uZm9ybWFuY2Vcblx0XHQgICAqIChodHRwOi8vd3d3LmVjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wL2luZGV4Lmh0bWwjc2VjLSVzZXRpdGVyYXRvcnByb3RvdHlwZSUtQEB0b3N0cmluZ3RhZylcblx0XHQgICAqIEVTNiQyMy4yLjUuMi4yIC0gJVNldEl0ZXJhdG9yUHJvdG90eXBlJVtAQHRvU3RyaW5nVGFnXSBzaG91bGQgYmUgXCJTZXQgSXRlcmF0b3JcIjpcblx0XHQgICAqIFRlc3Q6IGBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobmV3IFNldCgpLmVudHJpZXMoKSlgYFxuXHRcdCAgICogIC0gRWRnZSA8PTEzID09PSBcIltvYmplY3QgT2JqZWN0XVwiXG5cdFx0ICAgKi9cblx0XHQgIGlmIChzZXRFeGlzdHMgJiYgb2JqUHJvdG90eXBlID09PSBzZXRJdGVyYXRvclByb3RvdHlwZSkge1xuXHRcdCAgICByZXR1cm4gJ1NldCBJdGVyYXRvcic7XG5cdFx0ICB9XG5cblx0XHQgIC8qICEgU3BlYyBDb25mb3JtYW5jZVxuXHRcdCAgICogKGh0dHA6Ly93d3cuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvaW5kZXguaHRtbCNzZWMtJWFycmF5aXRlcmF0b3Jwcm90b3R5cGUlLUBAdG9zdHJpbmd0YWcpXG5cdFx0ICAgKiBFUzYkMjIuMS41LjIuMiAtICVBcnJheUl0ZXJhdG9yUHJvdG90eXBlJVtAQHRvU3RyaW5nVGFnXSBzaG91bGQgYmUgXCJBcnJheSBJdGVyYXRvclwiOlxuXHRcdCAgICogVGVzdDogYE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChbXVtTeW1ib2wuaXRlcmF0b3JdKCkpYGBcblx0XHQgICAqICAtIEVkZ2UgPD0xMyA9PT0gXCJbb2JqZWN0IE9iamVjdF1cIlxuXHRcdCAgICovXG5cdFx0ICBpZiAoYXJyYXlJdGVyYXRvckV4aXN0cyAmJiBvYmpQcm90b3R5cGUgPT09IGFycmF5SXRlcmF0b3JQcm90b3R5cGUpIHtcblx0XHQgICAgcmV0dXJuICdBcnJheSBJdGVyYXRvcic7XG5cdFx0ICB9XG5cblx0XHQgIC8qICEgU3BlYyBDb25mb3JtYW5jZVxuXHRcdCAgICogKGh0dHA6Ly93d3cuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvaW5kZXguaHRtbCNzZWMtJXN0cmluZ2l0ZXJhdG9ycHJvdG90eXBlJS1AQHRvc3RyaW5ndGFnKVxuXHRcdCAgICogRVM2JDIxLjEuNS4yLjIgLSAlU3RyaW5nSXRlcmF0b3JQcm90b3R5cGUlW0BAdG9TdHJpbmdUYWddIHNob3VsZCBiZSBcIlN0cmluZyBJdGVyYXRvclwiOlxuXHRcdCAgICogVGVzdDogYE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCgnJ1tTeW1ib2wuaXRlcmF0b3JdKCkpYGBcblx0XHQgICAqICAtIEVkZ2UgPD0xMyA9PT0gXCJbb2JqZWN0IE9iamVjdF1cIlxuXHRcdCAgICovXG5cdFx0ICBpZiAoc3RyaW5nSXRlcmF0b3JFeGlzdHMgJiYgb2JqUHJvdG90eXBlID09PSBzdHJpbmdJdGVyYXRvclByb3RvdHlwZSkge1xuXHRcdCAgICByZXR1cm4gJ1N0cmluZyBJdGVyYXRvcic7XG5cdFx0ICB9XG5cblx0XHQgIC8qICEgU3BlZWQgb3B0aW1pc2F0aW9uXG5cdFx0ICAqIFByZTpcblx0XHQgICogICBvYmplY3QgZnJvbSBudWxsICAgeCAyLDQyNCwzMjAgb3BzL3NlYyDCsTEuNjclICg3NiBydW5zIHNhbXBsZWQpXG5cdFx0ICAqIFBvc3Q6XG5cdFx0ICAqICAgb2JqZWN0IGZyb20gbnVsbCAgIHggNSw4MzgsMDAwIG9wcy9zZWMgwrEwLjk5JSAoODQgcnVucyBzYW1wbGVkKVxuXHRcdCAgKi9cblx0XHQgIGlmIChvYmpQcm90b3R5cGUgPT09IG51bGwpIHtcblx0XHQgICAgcmV0dXJuICdPYmplY3QnO1xuXHRcdCAgfVxuXG5cdFx0ICByZXR1cm4gT2JqZWN0XG5cdFx0ICAgIC5wcm90b3R5cGVcblx0XHQgICAgLnRvU3RyaW5nXG5cdFx0ICAgIC5jYWxsKG9iailcblx0XHQgICAgLnNsaWNlKHRvU3RyaW5nTGVmdFNsaWNlTGVuZ3RoLCB0b1N0cmluZ1JpZ2h0U2xpY2VMZW5ndGgpO1xuXHRcdH1cblxuXHRcdHJldHVybiB0eXBlRGV0ZWN0O1xuXG5cdFx0fSkpKTsgXG5cdH0gKHR5cGVEZXRlY3QkMSkpO1xuXHRyZXR1cm4gdHlwZURldGVjdCQxLmV4cG9ydHM7XG59XG5cbnZhciB0eXBlT2Y7XG52YXIgaGFzUmVxdWlyZWRUeXBlT2Y7XG5cbmZ1bmN0aW9uIHJlcXVpcmVUeXBlT2YgKCkge1xuXHRpZiAoaGFzUmVxdWlyZWRUeXBlT2YpIHJldHVybiB0eXBlT2Y7XG5cdGhhc1JlcXVpcmVkVHlwZU9mID0gMTtcblxuXHR2YXIgdHlwZSA9IHJlcXVpcmVUeXBlRGV0ZWN0KCk7XG5cblx0LyoqXG5cdCAqIFJldHVybnMgdGhlIGxvd2VyLWNhc2UgcmVzdWx0IG9mIHJ1bm5pbmcgdHlwZSBmcm9tIHR5cGUtZGV0ZWN0IG9uIHRoZSB2YWx1ZVxuXHQgKiBAcGFyYW0gIHsqfSB2YWx1ZVxuXHQgKiBAcmV0dXJucyB7c3RyaW5nfVxuXHQgKi9cblx0dHlwZU9mID0gZnVuY3Rpb24gdHlwZU9mKHZhbHVlKSB7XG5cdCAgICByZXR1cm4gdHlwZSh2YWx1ZSkudG9Mb3dlckNhc2UoKTtcblx0fTtcblx0cmV0dXJuIHR5cGVPZjtcbn1cblxudmFyIHZhbHVlVG9TdHJpbmdfMTtcbnZhciBoYXNSZXF1aXJlZFZhbHVlVG9TdHJpbmc7XG5cbmZ1bmN0aW9uIHJlcXVpcmVWYWx1ZVRvU3RyaW5nICgpIHtcblx0aWYgKGhhc1JlcXVpcmVkVmFsdWVUb1N0cmluZykgcmV0dXJuIHZhbHVlVG9TdHJpbmdfMTtcblx0aGFzUmVxdWlyZWRWYWx1ZVRvU3RyaW5nID0gMTtcblxuXHQvKipcblx0ICogUmV0dXJucyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgdmFsdWVcblx0ICogQHBhcmFtICB7Kn0gdmFsdWVcblx0ICogQHJldHVybnMge3N0cmluZ31cblx0ICovXG5cdGZ1bmN0aW9uIHZhbHVlVG9TdHJpbmcodmFsdWUpIHtcblx0ICAgIGlmICh2YWx1ZSAmJiB2YWx1ZS50b1N0cmluZykge1xuXHQgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAc2lub25qcy9uby1wcm90b3R5cGUtbWV0aG9kcy9uby1wcm90b3R5cGUtbWV0aG9kc1xuXHQgICAgICAgIHJldHVybiB2YWx1ZS50b1N0cmluZygpO1xuXHQgICAgfVxuXHQgICAgcmV0dXJuIFN0cmluZyh2YWx1ZSk7XG5cdH1cblxuXHR2YWx1ZVRvU3RyaW5nXzEgPSB2YWx1ZVRvU3RyaW5nO1xuXHRyZXR1cm4gdmFsdWVUb1N0cmluZ18xO1xufVxuXG52YXIgbGliO1xudmFyIGhhc1JlcXVpcmVkTGliO1xuXG5mdW5jdGlvbiByZXF1aXJlTGliICgpIHtcblx0aWYgKGhhc1JlcXVpcmVkTGliKSByZXR1cm4gbGliO1xuXHRoYXNSZXF1aXJlZExpYiA9IDE7XG5cblx0bGliID0ge1xuXHQgICAgZ2xvYmFsOiByZXF1aXJlR2xvYmFsKCksXG5cdCAgICBjYWxsZWRJbk9yZGVyOiByZXF1aXJlQ2FsbGVkSW5PcmRlcigpLFxuXHQgICAgY2xhc3NOYW1lOiByZXF1aXJlQ2xhc3NOYW1lKCksXG5cdCAgICBkZXByZWNhdGVkOiByZXF1aXJlRGVwcmVjYXRlZCgpLFxuXHQgICAgZXZlcnk6IHJlcXVpcmVFdmVyeSgpLFxuXHQgICAgZnVuY3Rpb25OYW1lOiByZXF1aXJlRnVuY3Rpb25OYW1lKCksXG5cdCAgICBvcmRlckJ5Rmlyc3RDYWxsOiByZXF1aXJlT3JkZXJCeUZpcnN0Q2FsbCgpLFxuXHQgICAgcHJvdG90eXBlczogcmVxdWlyZVByb3RvdHlwZXMoKSxcblx0ICAgIHR5cGVPZjogcmVxdWlyZVR5cGVPZigpLFxuXHQgICAgdmFsdWVUb1N0cmluZzogcmVxdWlyZVZhbHVlVG9TdHJpbmcoKSxcblx0fTtcblx0cmV0dXJuIGxpYjtcbn1cblxudmFyIGhhc1JlcXVpcmVkRmFrZVRpbWVyc1NyYztcblxuZnVuY3Rpb24gcmVxdWlyZUZha2VUaW1lcnNTcmMgKCkge1xuXHRpZiAoaGFzUmVxdWlyZWRGYWtlVGltZXJzU3JjKSByZXR1cm4gZmFrZVRpbWVyc1NyYztcblx0aGFzUmVxdWlyZWRGYWtlVGltZXJzU3JjID0gMTtcblxuXHRjb25zdCBnbG9iYWxPYmplY3QgPSByZXF1aXJlTGliKCkuZ2xvYmFsO1xuXHRsZXQgdGltZXJzTW9kdWxlLCB0aW1lcnNQcm9taXNlc01vZHVsZTtcblx0aWYgKHR5cGVvZiBfX3ZpdGVzdF9yZXF1aXJlZF9fICE9PSAndW5kZWZpbmVkJykge1xuXHQgICAgdHJ5IHtcblx0ICAgICAgICB0aW1lcnNNb2R1bGUgPSBfX3ZpdGVzdF9yZXF1aXJlZF9fLnRpbWVycztcblx0ICAgIH0gY2F0Y2ggKGUpIHtcblx0ICAgICAgICAvLyBpZ25vcmVkXG5cdCAgICB9XG5cdCAgICB0cnkge1xuXHQgICAgICAgIHRpbWVyc1Byb21pc2VzTW9kdWxlID0gX192aXRlc3RfcmVxdWlyZWRfXy50aW1lcnNQcm9taXNlcztcblx0ICAgIH0gY2F0Y2ggKGUpIHtcblx0ICAgICAgICAvLyBpZ25vcmVkXG5cdCAgICB9XG5cdH1cblxuXHQvKipcblx0ICogQHR5cGVkZWYge1wibmV4dEFzeW5jXCIgfCBcIm1hbnVhbFwiIHwgXCJpbnRlcnZhbFwifSBUaWNrTW9kZVxuXHQgKi9cblxuXHQvKipcblx0ICogQHR5cGVkZWYge29iamVjdH0gTmV4dEFzeW5jVGlja01vZGVcblx0ICogQHByb3BlcnR5IHtcIm5leHRBc3luY1wifSBtb2RlXG5cdCAqL1xuXG5cdC8qKlxuXHQgKiBAdHlwZWRlZiB7b2JqZWN0fSBNYW51YWxUaWNrTW9kZVxuXHQgKiBAcHJvcGVydHkge1wibWFudWFsXCJ9IG1vZGVcblx0ICovXG5cblx0LyoqXG5cdCAqIEB0eXBlZGVmIHtvYmplY3R9IEludGVydmFsVGlja01vZGVcblx0ICogQHByb3BlcnR5IHtcImludGVydmFsXCJ9IG1vZGVcblx0ICogQHByb3BlcnR5IHtudW1iZXJ9IFtkZWx0YV1cblx0ICovXG5cblx0LyoqXG5cdCAqIEB0eXBlZGVmIHtJbnRlcnZhbFRpY2tNb2RlIHwgTmV4dEFzeW5jVGlja01vZGUgfCBNYW51YWxUaWNrTW9kZX0gVGltZXJUaWNrTW9kZVxuXHQgKi9cblxuXHQvKipcblx0ICogQHR5cGVkZWYge29iamVjdH0gSWRsZURlYWRsaW5lXG5cdCAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gZGlkVGltZW91dCAtIHdoZXRoZXIgb3Igbm90IHRoZSBjYWxsYmFjayB3YXMgY2FsbGVkIGJlZm9yZSByZWFjaGluZyB0aGUgb3B0aW9uYWwgdGltZW91dFxuXHQgKiBAcHJvcGVydHkge2Z1bmN0aW9uKCk6bnVtYmVyfSB0aW1lUmVtYWluaW5nIC0gYSBmbG9hdGluZy1wb2ludCB2YWx1ZSBwcm92aWRpbmcgYW4gZXN0aW1hdGUgb2YgdGhlIG51bWJlciBvZiBtaWxsaXNlY29uZHMgcmVtYWluaW5nIGluIHRoZSBjdXJyZW50IGlkbGUgcGVyaW9kXG5cdCAqL1xuXG5cdC8qKlxuXHQgKiBRdWV1ZXMgYSBmdW5jdGlvbiB0byBiZSBjYWxsZWQgZHVyaW5nIGEgYnJvd3NlcidzIGlkbGUgcGVyaW9kc1xuXHQgKiBAY2FsbGJhY2sgUmVxdWVzdElkbGVDYWxsYmFja1xuXHQgKiBAcGFyYW0ge2Z1bmN0aW9uKElkbGVEZWFkbGluZSl9IGNhbGxiYWNrXG5cdCAqIEBwYXJhbSB7e3RpbWVvdXQ6IG51bWJlcn19IG9wdGlvbnMgLSBhbiBvcHRpb25zIG9iamVjdFxuXHQgKiBAcmV0dXJucyB7bnVtYmVyfSB0aGUgaWRcblx0ICovXG5cblx0LyoqXG5cdCAqIEBjYWxsYmFjayBOZXh0VGlja1xuXHQgKiBAcGFyYW0ge1ZvaWRWYXJBcmdzRnVuY30gY2FsbGJhY2sgLSB0aGUgY2FsbGJhY2sgdG8gcnVuXG5cdCAqIEBwYXJhbSB7Li4uKn0gYXJncyAtIG9wdGlvbmFsIGFyZ3VtZW50cyB0byBjYWxsIHRoZSBjYWxsYmFjayB3aXRoXG5cdCAqIEByZXR1cm5zIHt2b2lkfVxuXHQgKi9cblxuXHQvKipcblx0ICogQGNhbGxiYWNrIFNldEltbWVkaWF0ZVxuXHQgKiBAcGFyYW0ge1ZvaWRWYXJBcmdzRnVuY30gY2FsbGJhY2sgLSB0aGUgY2FsbGJhY2sgdG8gcnVuXG5cdCAqIEBwYXJhbSB7Li4uKn0gYXJncyAtIG9wdGlvbmFsIGFyZ3VtZW50cyB0byBjYWxsIHRoZSBjYWxsYmFjayB3aXRoXG5cdCAqIEByZXR1cm5zIHtOb2RlSW1tZWRpYXRlfVxuXHQgKi9cblxuXHQvKipcblx0ICogQGNhbGxiYWNrIFZvaWRWYXJBcmdzRnVuY1xuXHQgKiBAcGFyYW0gey4uLip9IGNhbGxiYWNrIC0gdGhlIGNhbGxiYWNrIHRvIHJ1blxuXHQgKiBAcmV0dXJucyB7dm9pZH1cblx0ICovXG5cblx0LyoqXG5cdCAqIEB0eXBlZGVmIFJlcXVlc3RBbmltYXRpb25GcmFtZVxuXHQgKiBAcHJvcGVydHkge2Z1bmN0aW9uKG51bWJlcik6dm9pZH0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lXG5cdCAqIEByZXR1cm5zIHtudW1iZXJ9IC0gdGhlIGlkXG5cdCAqL1xuXG5cdC8qKlxuXHQgKiBAdHlwZWRlZiBQZXJmb3JtYW5jZVxuXHQgKiBAcHJvcGVydHkge2Z1bmN0aW9uKCk6IG51bWJlcn0gbm93XG5cdCAqL1xuXG5cdC8qIGVzbGludC1kaXNhYmxlIGpzZG9jL3JlcXVpcmUtcHJvcGVydHktZGVzY3JpcHRpb24gKi9cblx0LyoqXG5cdCAqIEB0eXBlZGVmIHtvYmplY3R9IENsb2NrXG5cdCAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBub3cgLSB0aGUgY3VycmVudCB0aW1lXG5cdCAqIEBwcm9wZXJ0eSB7RGF0ZX0gRGF0ZSAtIHRoZSBEYXRlIGNvbnN0cnVjdG9yXG5cdCAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBsb29wTGltaXQgLSB0aGUgbWF4aW11bSBudW1iZXIgb2YgdGltZXJzIGJlZm9yZSBhc3N1bWluZyBhbiBpbmZpbml0ZSBsb29wXG5cdCAqIEBwcm9wZXJ0eSB7UmVxdWVzdElkbGVDYWxsYmFja30gcmVxdWVzdElkbGVDYWxsYmFja1xuXHQgKiBAcHJvcGVydHkge2Z1bmN0aW9uKG51bWJlcik6dm9pZH0gY2FuY2VsSWRsZUNhbGxiYWNrXG5cdCAqIEBwcm9wZXJ0eSB7c2V0VGltZW91dH0gc2V0VGltZW91dFxuXHQgKiBAcHJvcGVydHkge2NsZWFyVGltZW91dH0gY2xlYXJUaW1lb3V0XG5cdCAqIEBwcm9wZXJ0eSB7TmV4dFRpY2t9IG5leHRUaWNrXG5cdCAqIEBwcm9wZXJ0eSB7cXVldWVNaWNyb3Rhc2t9IHF1ZXVlTWljcm90YXNrXG5cdCAqIEBwcm9wZXJ0eSB7c2V0SW50ZXJ2YWx9IHNldEludGVydmFsXG5cdCAqIEBwcm9wZXJ0eSB7Y2xlYXJJbnRlcnZhbH0gY2xlYXJJbnRlcnZhbFxuXHQgKiBAcHJvcGVydHkge1NldEltbWVkaWF0ZX0gc2V0SW1tZWRpYXRlXG5cdCAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb24oTm9kZUltbWVkaWF0ZSk6dm9pZH0gY2xlYXJJbW1lZGlhdGVcblx0ICogQHByb3BlcnR5IHtmdW5jdGlvbigpOm51bWJlcn0gY291bnRUaW1lcnNcblx0ICogQHByb3BlcnR5IHtSZXF1ZXN0QW5pbWF0aW9uRnJhbWV9IHJlcXVlc3RBbmltYXRpb25GcmFtZVxuXHQgKiBAcHJvcGVydHkge2Z1bmN0aW9uKG51bWJlcik6dm9pZH0gY2FuY2VsQW5pbWF0aW9uRnJhbWVcblx0ICogQHByb3BlcnR5IHtmdW5jdGlvbigpOnZvaWR9IHJ1bk1pY3JvdGFza3Ncblx0ICogQHByb3BlcnR5IHtmdW5jdGlvbihzdHJpbmcgfCBudW1iZXIpOiBudW1iZXJ9IHRpY2tcblx0ICogQHByb3BlcnR5IHtmdW5jdGlvbihzdHJpbmcgfCBudW1iZXIpOiBQcm9taXNlPG51bWJlcj59IHRpY2tBc3luY1xuXHQgKiBAcHJvcGVydHkge2Z1bmN0aW9uKCk6IG51bWJlcn0gbmV4dFxuXHQgKiBAcHJvcGVydHkge2Z1bmN0aW9uKCk6IFByb21pc2U8bnVtYmVyPn0gbmV4dEFzeW5jXG5cdCAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb24oKTogbnVtYmVyfSBydW5BbGxcblx0ICogQHByb3BlcnR5IHtmdW5jdGlvbigpOiBudW1iZXJ9IHJ1blRvRnJhbWVcblx0ICogQHByb3BlcnR5IHtmdW5jdGlvbigpOiBQcm9taXNlPG51bWJlcj59IHJ1bkFsbEFzeW5jXG5cdCAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb24oKTogbnVtYmVyfSBydW5Ub0xhc3Rcblx0ICogQHByb3BlcnR5IHtmdW5jdGlvbigpOiBQcm9taXNlPG51bWJlcj59IHJ1blRvTGFzdEFzeW5jXG5cdCAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb24oKTogdm9pZH0gcmVzZXRcblx0ICogQHByb3BlcnR5IHtmdW5jdGlvbihudW1iZXIgfCBEYXRlKTogdm9pZH0gc2V0U3lzdGVtVGltZVxuXHQgKiBAcHJvcGVydHkge2Z1bmN0aW9uKG51bWJlcik6IHZvaWR9IGp1bXBcblx0ICogQHByb3BlcnR5IHtQZXJmb3JtYW5jZX0gcGVyZm9ybWFuY2Vcblx0ICogQHByb3BlcnR5IHtmdW5jdGlvbihudW1iZXJbXSk6IG51bWJlcltdfSBocnRpbWUgLSBwcm9jZXNzLmhydGltZSAobGVnYWN5KVxuXHQgKiBAcHJvcGVydHkge2Z1bmN0aW9uKCk6IHZvaWR9IHVuaW5zdGFsbCBVbmluc3RhbGwgdGhlIGNsb2NrLlxuXHQgKiBAcHJvcGVydHkge0Z1bmN0aW9uW119IG1ldGhvZHMgLSB0aGUgbWV0aG9kcyB0aGF0IGFyZSBmYWtlZFxuXHQgKiBAcHJvcGVydHkge2Jvb2xlYW59IFtzaG91bGRDbGVhck5hdGl2ZVRpbWVyc10gaW5oZXJpdGVkIGZyb20gY29uZmlnXG5cdCAqIEBwcm9wZXJ0eSB7e21ldGhvZE5hbWU6c3RyaW5nLCBvcmlnaW5hbDphbnl9W10gfCB1bmRlZmluZWR9IHRpbWVyc01vZHVsZU1ldGhvZHNcblx0ICogQHByb3BlcnR5IHt7bWV0aG9kTmFtZTpzdHJpbmcsIG9yaWdpbmFsOmFueX1bXSB8IHVuZGVmaW5lZH0gdGltZXJzUHJvbWlzZXNNb2R1bGVNZXRob2RzXG5cdCAqIEBwcm9wZXJ0eSB7TWFwPGZ1bmN0aW9uKCk6IHZvaWQsIEFib3J0U2lnbmFsPn0gYWJvcnRMaXN0ZW5lck1hcFxuXHQgKiBAcHJvcGVydHkge2Z1bmN0aW9uKFRpbWVyVGlja01vZGUpOiB2b2lkfSBzZXRUaWNrTW9kZVxuXHQgKi9cblx0LyogZXNsaW50LWVuYWJsZSBqc2RvYy9yZXF1aXJlLXByb3BlcnR5LWRlc2NyaXB0aW9uICovXG5cblx0LyoqXG5cdCAqIENvbmZpZ3VyYXRpb24gb2JqZWN0IGZvciB0aGUgYGluc3RhbGxgIG1ldGhvZC5cblx0ICogQHR5cGVkZWYge29iamVjdH0gQ29uZmlnXG5cdCAqIEBwcm9wZXJ0eSB7bnVtYmVyfERhdGV9IFtub3ddIGEgbnVtYmVyIChpbiBtaWxsaXNlY29uZHMpIG9yIGEgRGF0ZSBvYmplY3QgKGRlZmF1bHQgZXBvY2gpXG5cdCAqIEBwcm9wZXJ0eSB7c3RyaW5nW119IFt0b0Zha2VdIG5hbWVzIG9mIHRoZSBtZXRob2RzIHRoYXQgc2hvdWxkIGJlIGZha2VkLlxuXHQgKiBAcHJvcGVydHkge251bWJlcn0gW2xvb3BMaW1pdF0gdGhlIG1heGltdW0gbnVtYmVyIG9mIHRpbWVycyB0aGF0IHdpbGwgYmUgcnVuIHdoZW4gY2FsbGluZyBydW5BbGwoKVxuXHQgKiBAcHJvcGVydHkge2Jvb2xlYW59IFtzaG91bGRBZHZhbmNlVGltZV0gdGVsbHMgRmFrZVRpbWVycyB0byBpbmNyZW1lbnQgbW9ja2VkIHRpbWUgYXV0b21hdGljYWxseSAoZGVmYXVsdCBmYWxzZSlcblx0ICogQHByb3BlcnR5IHtudW1iZXJ9IFthZHZhbmNlVGltZURlbHRhXSBpbmNyZW1lbnQgbW9ja2VkIHRpbWUgZXZlcnkgPDxhZHZhbmNlVGltZURlbHRhPj4gbXMgKGRlZmF1bHQ6IDIwbXMpXG5cdCAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW3Nob3VsZENsZWFyTmF0aXZlVGltZXJzXSBmb3J3YXJkcyBjbGVhciB0aW1lciBjYWxscyB0byBuYXRpdmUgZnVuY3Rpb25zIGlmIHRoZXkgYXJlIG5vdCBmYWtlcyAoZGVmYXVsdDogZmFsc2UpXG5cdCAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gW2lnbm9yZU1pc3NpbmdUaW1lcnNdIGRlZmF1bHQgaXMgZmFsc2UsIG1lYW5pbmcgYXNraW5nIHRvIGZha2UgdGltZXJzIHRoYXQgYXJlIG5vdCBwcmVzZW50IHdpbGwgdGhyb3cgYW4gZXJyb3Jcblx0ICovXG5cblx0LyogZXNsaW50LWRpc2FibGUganNkb2MvcmVxdWlyZS1wcm9wZXJ0eS1kZXNjcmlwdGlvbiAqL1xuXHQvKipcblx0ICogVGhlIGludGVybmFsIHN0cnVjdHVyZSB0byBkZXNjcmliZSBhIHNjaGVkdWxlZCBmYWtlIHRpbWVyXG5cdCAqIEB0eXBlZGVmIHtvYmplY3R9IFRpbWVyXG5cdCAqIEBwcm9wZXJ0eSB7RnVuY3Rpb259IGZ1bmNcblx0ICogQHByb3BlcnR5IHsqW119IGFyZ3Ncblx0ICogQHByb3BlcnR5IHtudW1iZXJ9IGRlbGF5XG5cdCAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBjYWxsQXRcblx0ICogQHByb3BlcnR5IHtudW1iZXJ9IGNyZWF0ZWRBdFxuXHQgKiBAcHJvcGVydHkge2Jvb2xlYW59IGltbWVkaWF0ZVxuXHQgKiBAcHJvcGVydHkge251bWJlcn0gaWRcblx0ICogQHByb3BlcnR5IHtFcnJvcn0gW2Vycm9yXVxuXHQgKi9cblxuXHQvKipcblx0ICogQSBOb2RlIHRpbWVyXG5cdCAqIEB0eXBlZGVmIHtvYmplY3R9IE5vZGVJbW1lZGlhdGVcblx0ICogQHByb3BlcnR5IHtmdW5jdGlvbigpOiBib29sZWFufSBoYXNSZWZcblx0ICogQHByb3BlcnR5IHtmdW5jdGlvbigpOiBOb2RlSW1tZWRpYXRlfSByZWZcblx0ICogQHByb3BlcnR5IHtmdW5jdGlvbigpOiBOb2RlSW1tZWRpYXRlfSB1bnJlZlxuXHQgKi9cblx0LyogZXNsaW50LWVuYWJsZSBqc2RvYy9yZXF1aXJlLXByb3BlcnR5LWRlc2NyaXB0aW9uICovXG5cblx0LyogZXNsaW50LWRpc2FibGUgY29tcGxleGl0eSAqL1xuXG5cdC8qKlxuXHQgKiBNb2NrcyBhdmFpbGFibGUgZmVhdHVyZXMgaW4gdGhlIHNwZWNpZmllZCBnbG9iYWwgbmFtZXNwYWNlLlxuXHQgKiBAcGFyYW0geyp9IF9nbG9iYWwgTmFtZXNwYWNlIHRvIG1vY2sgKGUuZy4gYHdpbmRvd2ApXG5cdCAqIEByZXR1cm5zIHtGYWtlVGltZXJzfVxuXHQgKi9cblx0ZnVuY3Rpb24gd2l0aEdsb2JhbChfZ2xvYmFsKSB7XG5cdCAgICBjb25zdCBtYXhUaW1lb3V0ID0gTWF0aC5wb3coMiwgMzEpIC0gMTsgLy9zZWUgaHR0cHM6Ly9oZXljYW0uZ2l0aHViLmlvL3dlYmlkbC8jYWJzdHJhY3Qtb3BkZWYtY29udmVydHRvaW50XG5cdCAgICBjb25zdCBpZENvdW50ZXJTdGFydCA9IDFlMTI7IC8vIGFyYml0cmFyaWx5IGxhcmdlIG51bWJlciB0byBhdm9pZCBjb2xsaXNpb25zIHdpdGggbmF0aXZlIHRpbWVyIElEc1xuXHQgICAgY29uc3QgTk9PUCA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuXHQgICAgfTtcblx0ICAgIGNvbnN0IE5PT1BfQVJSQVkgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgcmV0dXJuIFtdO1xuXHQgICAgfTtcblx0ICAgIGNvbnN0IGlzUHJlc2VudCA9IHt9O1xuXHQgICAgbGV0IHRpbWVvdXRSZXN1bHQsXG5cdCAgICAgICAgYWRkVGltZXJSZXR1cm5zT2JqZWN0ID0gZmFsc2U7XG5cblx0ICAgIGlmIChfZ2xvYmFsLnNldFRpbWVvdXQpIHtcblx0ICAgICAgICBpc1ByZXNlbnQuc2V0VGltZW91dCA9IHRydWU7XG5cdCAgICAgICAgdGltZW91dFJlc3VsdCA9IF9nbG9iYWwuc2V0VGltZW91dChOT09QLCAwKTtcblx0ICAgICAgICBhZGRUaW1lclJldHVybnNPYmplY3QgPSB0eXBlb2YgdGltZW91dFJlc3VsdCA9PT0gXCJvYmplY3RcIjtcblx0ICAgIH1cblx0ICAgIGlzUHJlc2VudC5jbGVhclRpbWVvdXQgPSBCb29sZWFuKF9nbG9iYWwuY2xlYXJUaW1lb3V0KTtcblx0ICAgIGlzUHJlc2VudC5zZXRJbnRlcnZhbCA9IEJvb2xlYW4oX2dsb2JhbC5zZXRJbnRlcnZhbCk7XG5cdCAgICBpc1ByZXNlbnQuY2xlYXJJbnRlcnZhbCA9IEJvb2xlYW4oX2dsb2JhbC5jbGVhckludGVydmFsKTtcblx0ICAgIGlzUHJlc2VudC5ocnRpbWUgPVxuXHQgICAgICAgIF9nbG9iYWwucHJvY2VzcyAmJiB0eXBlb2YgX2dsb2JhbC5wcm9jZXNzLmhydGltZSA9PT0gXCJmdW5jdGlvblwiO1xuXHQgICAgaXNQcmVzZW50LmhydGltZUJpZ2ludCA9XG5cdCAgICAgICAgaXNQcmVzZW50LmhydGltZSAmJiB0eXBlb2YgX2dsb2JhbC5wcm9jZXNzLmhydGltZS5iaWdpbnQgPT09IFwiZnVuY3Rpb25cIjtcblx0ICAgIGlzUHJlc2VudC5uZXh0VGljayA9XG5cdCAgICAgICAgX2dsb2JhbC5wcm9jZXNzICYmIHR5cGVvZiBfZ2xvYmFsLnByb2Nlc3MubmV4dFRpY2sgPT09IFwiZnVuY3Rpb25cIjtcblx0ICAgIGNvbnN0IHV0aWxQcm9taXNpZnkgPSBfZ2xvYmFsLnByb2Nlc3MgJiYgX2dsb2JhbC5fX3ZpdGVzdF9yZXF1aXJlZF9fICYmIF9nbG9iYWwuX192aXRlc3RfcmVxdWlyZWRfXy51dGlsLnByb21pc2lmeTtcblx0ICAgIGlzUHJlc2VudC5wZXJmb3JtYW5jZSA9XG5cdCAgICAgICAgX2dsb2JhbC5wZXJmb3JtYW5jZSAmJiB0eXBlb2YgX2dsb2JhbC5wZXJmb3JtYW5jZS5ub3cgPT09IFwiZnVuY3Rpb25cIjtcblx0ICAgIGNvbnN0IGhhc1BlcmZvcm1hbmNlUHJvdG90eXBlID1cblx0ICAgICAgICBfZ2xvYmFsLlBlcmZvcm1hbmNlICYmXG5cdCAgICAgICAgKHR5cGVvZiBfZ2xvYmFsLlBlcmZvcm1hbmNlKS5tYXRjaCgvXihmdW5jdGlvbnxvYmplY3QpJC8pO1xuXHQgICAgY29uc3QgaGFzUGVyZm9ybWFuY2VDb25zdHJ1Y3RvclByb3RvdHlwZSA9XG5cdCAgICAgICAgX2dsb2JhbC5wZXJmb3JtYW5jZSAmJlxuXHQgICAgICAgIF9nbG9iYWwucGVyZm9ybWFuY2UuY29uc3RydWN0b3IgJiZcblx0ICAgICAgICBfZ2xvYmFsLnBlcmZvcm1hbmNlLmNvbnN0cnVjdG9yLnByb3RvdHlwZTtcblx0ICAgIGlzUHJlc2VudC5xdWV1ZU1pY3JvdGFzayA9IF9nbG9iYWwuaGFzT3duUHJvcGVydHkoXCJxdWV1ZU1pY3JvdGFza1wiKTtcblx0ICAgIGlzUHJlc2VudC5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUgPVxuXHQgICAgICAgIF9nbG9iYWwucmVxdWVzdEFuaW1hdGlvbkZyYW1lICYmXG5cdCAgICAgICAgdHlwZW9mIF9nbG9iYWwucmVxdWVzdEFuaW1hdGlvbkZyYW1lID09PSBcImZ1bmN0aW9uXCI7XG5cdCAgICBpc1ByZXNlbnQuY2FuY2VsQW5pbWF0aW9uRnJhbWUgPVxuXHQgICAgICAgIF9nbG9iYWwuY2FuY2VsQW5pbWF0aW9uRnJhbWUgJiZcblx0ICAgICAgICB0eXBlb2YgX2dsb2JhbC5jYW5jZWxBbmltYXRpb25GcmFtZSA9PT0gXCJmdW5jdGlvblwiO1xuXHQgICAgaXNQcmVzZW50LnJlcXVlc3RJZGxlQ2FsbGJhY2sgPVxuXHQgICAgICAgIF9nbG9iYWwucmVxdWVzdElkbGVDYWxsYmFjayAmJlxuXHQgICAgICAgIHR5cGVvZiBfZ2xvYmFsLnJlcXVlc3RJZGxlQ2FsbGJhY2sgPT09IFwiZnVuY3Rpb25cIjtcblx0ICAgIGlzUHJlc2VudC5jYW5jZWxJZGxlQ2FsbGJhY2tQcmVzZW50ID1cblx0ICAgICAgICBfZ2xvYmFsLmNhbmNlbElkbGVDYWxsYmFjayAmJlxuXHQgICAgICAgIHR5cGVvZiBfZ2xvYmFsLmNhbmNlbElkbGVDYWxsYmFjayA9PT0gXCJmdW5jdGlvblwiO1xuXHQgICAgaXNQcmVzZW50LnNldEltbWVkaWF0ZSA9XG5cdCAgICAgICAgX2dsb2JhbC5zZXRJbW1lZGlhdGUgJiYgdHlwZW9mIF9nbG9iYWwuc2V0SW1tZWRpYXRlID09PSBcImZ1bmN0aW9uXCI7XG5cdCAgICBpc1ByZXNlbnQuY2xlYXJJbW1lZGlhdGUgPVxuXHQgICAgICAgIF9nbG9iYWwuY2xlYXJJbW1lZGlhdGUgJiYgdHlwZW9mIF9nbG9iYWwuY2xlYXJJbW1lZGlhdGUgPT09IFwiZnVuY3Rpb25cIjtcblx0ICAgIGlzUHJlc2VudC5JbnRsID0gX2dsb2JhbC5JbnRsICYmIHR5cGVvZiBfZ2xvYmFsLkludGwgPT09IFwib2JqZWN0XCI7XG5cblx0ICAgIGlmIChfZ2xvYmFsLmNsZWFyVGltZW91dCkge1xuXHQgICAgICAgIF9nbG9iYWwuY2xlYXJUaW1lb3V0KHRpbWVvdXRSZXN1bHQpO1xuXHQgICAgfVxuXG5cdCAgICBjb25zdCBOYXRpdmVEYXRlID0gX2dsb2JhbC5EYXRlO1xuXHQgICAgY29uc3QgTmF0aXZlSW50bCA9IGlzUHJlc2VudC5JbnRsXG5cdCAgICAgICAgPyBPYmplY3QuZGVmaW5lUHJvcGVydGllcyhcblx0ICAgICAgICAgICAgICBPYmplY3QuY3JlYXRlKG51bGwpLFxuXHQgICAgICAgICAgICAgIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3JzKF9nbG9iYWwuSW50bCksXG5cdCAgICAgICAgICApXG5cdCAgICAgICAgOiB1bmRlZmluZWQ7XG5cdCAgICBsZXQgdW5pcXVlVGltZXJJZCA9IGlkQ291bnRlclN0YXJ0O1xuXG5cdCAgICBpZiAoTmF0aXZlRGF0ZSA9PT0gdW5kZWZpbmVkKSB7XG5cdCAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuXHQgICAgICAgICAgICBcIlRoZSBnbG9iYWwgc2NvcGUgZG9lc24ndCBoYXZlIGEgYERhdGVgIG9iamVjdFwiICtcblx0ICAgICAgICAgICAgICAgIFwiIChzZWUgaHR0cHM6Ly9naXRodWIuY29tL3Npbm9uanMvc2lub24vaXNzdWVzLzE4NTIjaXNzdWVjb21tZW50LTQxOTYyMjc4MClcIixcblx0ICAgICAgICApO1xuXHQgICAgfVxuXHQgICAgaXNQcmVzZW50LkRhdGUgPSB0cnVlO1xuXG5cdCAgICAvKipcblx0ICAgICAqIFRoZSBQZXJmb3JtYW5jZUVudHJ5IG9iamVjdCBlbmNhcHN1bGF0ZXMgYSBzaW5nbGUgcGVyZm9ybWFuY2UgbWV0cmljXG5cdCAgICAgKiB0aGF0IGlzIHBhcnQgb2YgdGhlIGJyb3dzZXIncyBwZXJmb3JtYW5jZSB0aW1lbGluZS5cblx0ICAgICAqXG5cdCAgICAgKiBUaGlzIGlzIGFuIG9iamVjdCByZXR1cm5lZCBieSB0aGUgYG1hcmtgIGFuZCBgbWVhc3VyZWAgbWV0aG9kcyBvbiB0aGUgUGVyZm9ybWFuY2UgcHJvdG90eXBlXG5cdCAgICAgKi9cblx0ICAgIGNsYXNzIEZha2VQZXJmb3JtYW5jZUVudHJ5IHtcblx0ICAgICAgICBjb25zdHJ1Y3RvcihuYW1lLCBlbnRyeVR5cGUsIHN0YXJ0VGltZSwgZHVyYXRpb24pIHtcblx0ICAgICAgICAgICAgdGhpcy5uYW1lID0gbmFtZTtcblx0ICAgICAgICAgICAgdGhpcy5lbnRyeVR5cGUgPSBlbnRyeVR5cGU7XG5cdCAgICAgICAgICAgIHRoaXMuc3RhcnRUaW1lID0gc3RhcnRUaW1lO1xuXHQgICAgICAgICAgICB0aGlzLmR1cmF0aW9uID0gZHVyYXRpb247XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgdG9KU09OKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoeyAuLi50aGlzIH0pO1xuXHQgICAgICAgIH1cblx0ICAgIH1cblxuXHQgICAgLyoqXG5cdCAgICAgKiBAcGFyYW0ge251bWJlcn0gbnVtXG5cdCAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cblx0ICAgICAqL1xuXHQgICAgZnVuY3Rpb24gaXNOdW1iZXJGaW5pdGUobnVtKSB7XG5cdCAgICAgICAgaWYgKE51bWJlci5pc0Zpbml0ZSkge1xuXHQgICAgICAgICAgICByZXR1cm4gTnVtYmVyLmlzRmluaXRlKG51bSk7XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgcmV0dXJuIGlzRmluaXRlKG51bSk7XG5cdCAgICB9XG5cblx0ICAgIGxldCBpc05lYXJJbmZpbml0ZUxpbWl0ID0gZmFsc2U7XG5cblx0ICAgIC8qKlxuXHQgICAgICogQHBhcmFtIHtDbG9ja30gY2xvY2tcblx0ICAgICAqIEBwYXJhbSB7bnVtYmVyfSBpXG5cdCAgICAgKi9cblx0ICAgIGZ1bmN0aW9uIGNoZWNrSXNOZWFySW5maW5pdGVMaW1pdChjbG9jaywgaSkge1xuXHQgICAgICAgIGlmIChjbG9jay5sb29wTGltaXQgJiYgaSA9PT0gY2xvY2subG9vcExpbWl0IC0gMSkge1xuXHQgICAgICAgICAgICBpc05lYXJJbmZpbml0ZUxpbWl0ID0gdHJ1ZTtcblx0ICAgICAgICB9XG5cdCAgICB9XG5cblx0ICAgIC8qKlxuXHQgICAgICpcblx0ICAgICAqL1xuXHQgICAgZnVuY3Rpb24gcmVzZXRJc05lYXJJbmZpbml0ZUxpbWl0KCkge1xuXHQgICAgICAgIGlzTmVhckluZmluaXRlTGltaXQgPSBmYWxzZTtcblx0ICAgIH1cblxuXHQgICAgLyoqXG5cdCAgICAgKiBQYXJzZSBzdHJpbmdzIGxpa2UgXCIwMToxMDowMFwiIChtZWFuaW5nIDEgaG91ciwgMTAgbWludXRlcywgMCBzZWNvbmRzKSBpbnRvXG5cdCAgICAgKiBudW1iZXIgb2YgbWlsbGlzZWNvbmRzLiBUaGlzIGlzIHVzZWQgdG8gc3VwcG9ydCBodW1hbi1yZWFkYWJsZSBzdHJpbmdzIHBhc3NlZFxuXHQgICAgICogdG8gY2xvY2sudGljaygpXG5cdCAgICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyXG5cdCAgICAgKiBAcmV0dXJucyB7bnVtYmVyfVxuXHQgICAgICovXG5cdCAgICBmdW5jdGlvbiBwYXJzZVRpbWUoc3RyKSB7XG5cdCAgICAgICAgaWYgKCFzdHIpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIDA7XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgY29uc3Qgc3RyaW5ncyA9IHN0ci5zcGxpdChcIjpcIik7XG5cdCAgICAgICAgY29uc3QgbCA9IHN0cmluZ3MubGVuZ3RoO1xuXHQgICAgICAgIGxldCBpID0gbDtcblx0ICAgICAgICBsZXQgbXMgPSAwO1xuXHQgICAgICAgIGxldCBwYXJzZWQ7XG5cblx0ICAgICAgICBpZiAobCA+IDMgfHwgIS9eKFxcZFxcZDopezAsMn1cXGRcXGQ/JC8udGVzdChzdHIpKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcblx0ICAgICAgICAgICAgICAgIFwidGljayBvbmx5IHVuZGVyc3RhbmRzIG51bWJlcnMsICdtOnMnIGFuZCAnaDptOnMnLiBFYWNoIHBhcnQgbXVzdCBiZSB0d28gZGlnaXRzXCIsXG5cdCAgICAgICAgICAgICk7XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgd2hpbGUgKGktLSkge1xuXHQgICAgICAgICAgICBwYXJzZWQgPSBwYXJzZUludChzdHJpbmdzW2ldLCAxMCk7XG5cblx0ICAgICAgICAgICAgaWYgKHBhcnNlZCA+PSA2MCkge1xuXHQgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIHRpbWUgJHtzdHJ9YCk7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICBtcyArPSBwYXJzZWQgKiBNYXRoLnBvdyg2MCwgbCAtIGkgLSAxKTtcblx0ICAgICAgICB9XG5cblx0ICAgICAgICByZXR1cm4gbXMgKiAxMDAwO1xuXHQgICAgfVxuXG5cdCAgICAvKipcblx0ICAgICAqIEdldCB0aGUgZGVjaW1hbCBwYXJ0IG9mIHRoZSBtaWxsaXNlY29uZCB2YWx1ZSBhcyBuYW5vc2Vjb25kc1xuXHQgICAgICogQHBhcmFtIHtudW1iZXJ9IG1zRmxvYXQgdGhlIG51bWJlciBvZiBtaWxsaXNlY29uZHNcblx0ICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IGFuIGludGVnZXIgbnVtYmVyIG9mIG5hbm9zZWNvbmRzIGluIHRoZSByYW5nZSBbMCwxZTYpXG5cdCAgICAgKlxuXHQgICAgICogRXhhbXBsZTogbmFub1JlbWFpbmVyKDEyMy40NTY3ODkpIC0+IDQ1Njc4OVxuXHQgICAgICovXG5cdCAgICBmdW5jdGlvbiBuYW5vUmVtYWluZGVyKG1zRmxvYXQpIHtcblx0ICAgICAgICBjb25zdCBtb2R1bG8gPSAxZTY7XG5cdCAgICAgICAgY29uc3QgcmVtYWluZGVyID0gKG1zRmxvYXQgKiAxZTYpICUgbW9kdWxvO1xuXHQgICAgICAgIGNvbnN0IHBvc2l0aXZlUmVtYWluZGVyID1cblx0ICAgICAgICAgICAgcmVtYWluZGVyIDwgMCA/IHJlbWFpbmRlciArIG1vZHVsbyA6IHJlbWFpbmRlcjtcblxuXHQgICAgICAgIHJldHVybiBNYXRoLmZsb29yKHBvc2l0aXZlUmVtYWluZGVyKTtcblx0ICAgIH1cblxuXHQgICAgLyoqXG5cdCAgICAgKiBVc2VkIHRvIGdyb2sgdGhlIGBub3dgIHBhcmFtZXRlciB0byBjcmVhdGVDbG9jay5cblx0ICAgICAqIEBwYXJhbSB7RGF0ZXxudW1iZXJ9IGVwb2NoIHRoZSBzeXN0ZW0gdGltZVxuXHQgICAgICogQHJldHVybnMge251bWJlcn1cblx0ICAgICAqL1xuXHQgICAgZnVuY3Rpb24gZ2V0RXBvY2goZXBvY2gpIHtcblx0ICAgICAgICBpZiAoIWVwb2NoKSB7XG5cdCAgICAgICAgICAgIHJldHVybiAwO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBpZiAodHlwZW9mIGVwb2NoLmdldFRpbWUgPT09IFwiZnVuY3Rpb25cIikge1xuXHQgICAgICAgICAgICByZXR1cm4gZXBvY2guZ2V0VGltZSgpO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBpZiAodHlwZW9mIGVwb2NoID09PSBcIm51bWJlclwiKSB7XG5cdCAgICAgICAgICAgIHJldHVybiBlcG9jaDtcblx0ICAgICAgICB9XG5cdCAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIm5vdyBzaG91bGQgYmUgbWlsbGlzZWNvbmRzIHNpbmNlIFVOSVggZXBvY2hcIik7XG5cdCAgICB9XG5cblx0ICAgIC8qKlxuXHQgICAgICogQHBhcmFtIHtudW1iZXJ9IGZyb21cblx0ICAgICAqIEBwYXJhbSB7bnVtYmVyfSB0b1xuXHQgICAgICogQHBhcmFtIHtUaW1lcn0gdGltZXJcblx0ICAgICAqIEByZXR1cm5zIHtib29sZWFufVxuXHQgICAgICovXG5cdCAgICBmdW5jdGlvbiBpblJhbmdlKGZyb20sIHRvLCB0aW1lcikge1xuXHQgICAgICAgIHJldHVybiB0aW1lciAmJiB0aW1lci5jYWxsQXQgPj0gZnJvbSAmJiB0aW1lci5jYWxsQXQgPD0gdG87XG5cdCAgICB9XG5cblx0ICAgIC8qKlxuXHQgICAgICogQHBhcmFtIHtDbG9ja30gY2xvY2tcblx0ICAgICAqIEBwYXJhbSB7VGltZXJ9IGpvYlxuXHQgICAgICovXG5cdCAgICBmdW5jdGlvbiBnZXRJbmZpbml0ZUxvb3BFcnJvcihjbG9jaywgam9iKSB7XG5cdCAgICAgICAgY29uc3QgaW5maW5pdGVMb29wRXJyb3IgPSBuZXcgRXJyb3IoXG5cdCAgICAgICAgICAgIGBBYm9ydGluZyBhZnRlciBydW5uaW5nICR7Y2xvY2subG9vcExpbWl0fSB0aW1lcnMsIGFzc3VtaW5nIGFuIGluZmluaXRlIGxvb3AhYCxcblx0ICAgICAgICApO1xuXG5cdCAgICAgICAgaWYgKCFqb2IuZXJyb3IpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIGluZmluaXRlTG9vcEVycm9yO1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIC8vIHBhdHRlcm4gbmV2ZXIgbWF0Y2hlZCBpbiBOb2RlXG5cdCAgICAgICAgY29uc3QgY29tcHV0ZWRUYXJnZXRQYXR0ZXJuID0gL3RhcmdldFxcLipbPHwofFtdLio/Wz58XFxdfCldXFxzKi87XG5cdCAgICAgICAgbGV0IGNsb2NrTWV0aG9kUGF0dGVybiA9IG5ldyBSZWdFeHAoXG5cdCAgICAgICAgICAgIFN0cmluZyhPYmplY3Qua2V5cyhjbG9jaykuam9pbihcInxcIikpLFxuXHQgICAgICAgICk7XG5cblx0ICAgICAgICBpZiAoYWRkVGltZXJSZXR1cm5zT2JqZWN0KSB7XG5cdCAgICAgICAgICAgIC8vIG5vZGUuanMgZW52aXJvbm1lbnRcblx0ICAgICAgICAgICAgY2xvY2tNZXRob2RQYXR0ZXJuID0gbmV3IFJlZ0V4cChcblx0ICAgICAgICAgICAgICAgIGBcXFxccythdCAoT2JqZWN0XFxcXC4pPyg/OiR7T2JqZWN0LmtleXMoY2xvY2spLmpvaW4oXCJ8XCIpfSlcXFxccytgLFxuXHQgICAgICAgICAgICApO1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIGxldCBtYXRjaGVkTGluZUluZGV4ID0gLTE7XG5cdCAgICAgICAgam9iLmVycm9yLnN0YWNrLnNwbGl0KFwiXFxuXCIpLnNvbWUoZnVuY3Rpb24gKGxpbmUsIGkpIHtcblx0ICAgICAgICAgICAgLy8gSWYgd2UndmUgbWF0Y2hlZCBhIGNvbXB1dGVkIHRhcmdldCBsaW5lIChlLmcuIHNldFRpbWVvdXQpIHRoZW4gd2Vcblx0ICAgICAgICAgICAgLy8gZG9uJ3QgbmVlZCB0byBsb29rIGFueSBmdXJ0aGVyLiBSZXR1cm4gdHJ1ZSB0byBzdG9wIGl0ZXJhdGluZy5cblx0ICAgICAgICAgICAgY29uc3QgbWF0Y2hlZENvbXB1dGVkVGFyZ2V0ID0gbGluZS5tYXRjaChjb21wdXRlZFRhcmdldFBhdHRlcm4pO1xuXHQgICAgICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cblx0ICAgICAgICAgICAgaWYgKG1hdGNoZWRDb21wdXRlZFRhcmdldCkge1xuXHQgICAgICAgICAgICAgICAgbWF0Y2hlZExpbmVJbmRleCA9IGk7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIC8vIElmIHdlJ3ZlIG1hdGNoZWQgYSBjbG9jayBtZXRob2QgbGluZSwgdGhlbiB0aGVyZSBtYXkgc3RpbGwgYmVcblx0ICAgICAgICAgICAgLy8gb3RoZXJzIGZ1cnRoZXIgZG93biB0aGUgdHJhY2UuIFJldHVybiBmYWxzZSB0byBrZWVwIGl0ZXJhdGluZy5cblx0ICAgICAgICAgICAgY29uc3QgbWF0Y2hlZENsb2NrTWV0aG9kID0gbGluZS5tYXRjaChjbG9ja01ldGhvZFBhdHRlcm4pO1xuXHQgICAgICAgICAgICBpZiAobWF0Y2hlZENsb2NrTWV0aG9kKSB7XG5cdCAgICAgICAgICAgICAgICBtYXRjaGVkTGluZUluZGV4ID0gaTtcblx0ICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIC8vIElmIHdlIGhhdmVuJ3QgbWF0Y2hlZCBhbnl0aGluZyBvbiB0aGlzIGxpbmUsIGJ1dCB3ZSBtYXRjaGVkXG5cdCAgICAgICAgICAgIC8vIHByZXZpb3VzbHkgYW5kIHNldCB0aGUgbWF0Y2hlZCBsaW5lIGluZGV4LCB0aGVuIHdlIGNhbiBzdG9wLlxuXHQgICAgICAgICAgICAvLyBJZiB3ZSBoYXZlbid0IG1hdGNoZWQgcHJldmlvdXNseSwgdGhlbiB3ZSBzaG91bGQga2VlcCBpdGVyYXRpbmcuXG5cdCAgICAgICAgICAgIHJldHVybiBtYXRjaGVkTGluZUluZGV4ID49IDA7XG5cdCAgICAgICAgfSk7XG5cblx0ICAgICAgICBjb25zdCBzdGFjayA9IGAke2luZmluaXRlTG9vcEVycm9yfVxcbiR7am9iLnR5cGUgfHwgXCJNaWNyb3Rhc2tcIn0gLSAke1xuXHQgICAgICAgICAgICBqb2IuZnVuYy5uYW1lIHx8IFwiYW5vbnltb3VzXCJcblx0ICAgICAgICB9XFxuJHtqb2IuZXJyb3Iuc3RhY2tcblx0ICAgICAgICAgICAgLnNwbGl0KFwiXFxuXCIpXG5cdCAgICAgICAgICAgIC5zbGljZShtYXRjaGVkTGluZUluZGV4ICsgMSlcblx0ICAgICAgICAgICAgLmpvaW4oXCJcXG5cIil9YDtcblxuXHQgICAgICAgIHRyeSB7XG5cdCAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShpbmZpbml0ZUxvb3BFcnJvciwgXCJzdGFja1wiLCB7XG5cdCAgICAgICAgICAgICAgICB2YWx1ZTogc3RhY2ssXG5cdCAgICAgICAgICAgIH0pO1xuXHQgICAgICAgIH0gY2F0Y2ggKGUpIHtcblx0ICAgICAgICAgICAgLy8gbm9vcFxuXHQgICAgICAgIH1cblxuXHQgICAgICAgIHJldHVybiBpbmZpbml0ZUxvb3BFcnJvcjtcblx0ICAgIH1cblxuXHQgICAgLy9lc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUganNkb2MvcmVxdWlyZS1qc2RvY1xuXHQgICAgZnVuY3Rpb24gY3JlYXRlRGF0ZSgpIHtcblx0ICAgICAgICBjbGFzcyBDbG9ja0RhdGUgZXh0ZW5kcyBOYXRpdmVEYXRlIHtcblx0ICAgICAgICAgICAgLyoqXG5cdCAgICAgICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfSB5ZWFyXG5cdCAgICAgICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfSBtb250aFxuXHQgICAgICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gZGF0ZVxuXHQgICAgICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gaG91clxuXHQgICAgICAgICAgICAgKiBAcGFyYW0ge251bWJlcn0gbWludXRlXG5cdCAgICAgICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfSBzZWNvbmRcblx0ICAgICAgICAgICAgICogQHBhcmFtIHtudW1iZXJ9IG1zXG5cdCAgICAgICAgICAgICAqIEByZXR1cm5zIHZvaWRcblx0ICAgICAgICAgICAgICovXG5cdCAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bnVzZWQtdmFyc1xuXHQgICAgICAgICAgICBjb25zdHJ1Y3Rvcih5ZWFyLCBtb250aCwgZGF0ZSwgaG91ciwgbWludXRlLCBzZWNvbmQsIG1zKSB7XG5cdCAgICAgICAgICAgICAgICAvLyBEZWZlbnNpdmUgYW5kIHZlcmJvc2UgdG8gYXZvaWQgcG90ZW50aWFsIGhhcm0gaW4gcGFzc2luZ1xuXHQgICAgICAgICAgICAgICAgLy8gZXhwbGljaXQgdW5kZWZpbmVkIHdoZW4gdXNlciBkb2VzIG5vdCBwYXNzIGFyZ3VtZW50XG5cdCAgICAgICAgICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkge1xuXHQgICAgICAgICAgICAgICAgICAgIHN1cGVyKENsb2NrRGF0ZS5jbG9jay5ub3cpO1xuXHQgICAgICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgICAgICBzdXBlciguLi5hcmd1bWVudHMpO1xuXHQgICAgICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgICAgICAvLyBlbnN1cmVzIGlkZW50aXR5IGNoZWNrcyB1c2luZyB0aGUgY29uc3RydWN0b3IgcHJvcCBzdGlsbCB3b3Jrc1xuXHQgICAgICAgICAgICAgICAgLy8gdGhpcyBzaG91bGQgaGF2ZSBubyBvdGhlciBmdW5jdGlvbmFsIGVmZmVjdFxuXHQgICAgICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsIFwiY29uc3RydWN0b3JcIiwge1xuXHQgICAgICAgICAgICAgICAgICAgIHZhbHVlOiBOYXRpdmVEYXRlLFxuXHQgICAgICAgICAgICAgICAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuXHQgICAgICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICBzdGF0aWMgW1N5bWJvbC5oYXNJbnN0YW5jZV0oaW5zdGFuY2UpIHtcblx0ICAgICAgICAgICAgICAgIHJldHVybiBpbnN0YW5jZSBpbnN0YW5jZW9mIE5hdGl2ZURhdGU7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cblx0ICAgICAgICBDbG9ja0RhdGUuaXNGYWtlID0gdHJ1ZTtcblxuXHQgICAgICAgIGlmIChOYXRpdmVEYXRlLm5vdykge1xuXHQgICAgICAgICAgICBDbG9ja0RhdGUubm93ID0gZnVuY3Rpb24gbm93KCkge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIENsb2NrRGF0ZS5jbG9jay5ub3c7XG5cdCAgICAgICAgICAgIH07XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgaWYgKE5hdGl2ZURhdGUudG9Tb3VyY2UpIHtcblx0ICAgICAgICAgICAgQ2xvY2tEYXRlLnRvU291cmNlID0gZnVuY3Rpb24gdG9Tb3VyY2UoKSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gTmF0aXZlRGF0ZS50b1NvdXJjZSgpO1xuXHQgICAgICAgICAgICB9O1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIENsb2NrRGF0ZS50b1N0cmluZyA9IGZ1bmN0aW9uIHRvU3RyaW5nKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gTmF0aXZlRGF0ZS50b1N0cmluZygpO1xuXHQgICAgICAgIH07XG5cblx0ICAgICAgICAvLyBub2luc3BlY3Rpb24gVW5uZWNlc3NhcnlMb2NhbFZhcmlhYmxlSlNcblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBBIG5vcm1hbCBDbGFzcyBjb25zdHJ1Y3RvciBjYW5ub3QgYmUgY2FsbGVkIHdpdGhvdXQgYG5ld2AsIGJ1dCBEYXRlIGNhbiwgc28gd2UgbmVlZFxuXHQgICAgICAgICAqIHRvIHdyYXAgaXQgaW4gYSBQcm94eSBpbiBvcmRlciB0byBlbnN1cmUgdGhpcyBmdW5jdGlvbmFsaXR5IG9mIERhdGUgaXMga2VwdCBpbnRhY3Rcblx0ICAgICAgICAgKiBAdHlwZSB7Q2xvY2tEYXRlfVxuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGNvbnN0IENsb2NrRGF0ZVByb3h5ID0gbmV3IFByb3h5KENsb2NrRGF0ZSwge1xuXHQgICAgICAgICAgICAvLyBoYW5kbGVyIGZvciBbW0NhbGxdXSBpbnZvY2F0aW9ucyAoaS5lLiBub3QgdXNpbmcgYG5ld2ApXG5cdCAgICAgICAgICAgIGFwcGx5KCkge1xuXHQgICAgICAgICAgICAgICAgLy8gdGhlIERhdGUgY29uc3RydWN0b3IgY2FsbGVkIGFzIGEgZnVuY3Rpb24sIHJlZiBFY21hLTI2MiBFZGl0aW9uIDUuMSwgc2VjdGlvbiAxNS45LjIuXG5cdCAgICAgICAgICAgICAgICAvLyBUaGlzIHJlbWFpbnMgc28gaW4gdGhlIDEwdGggZWRpdGlvbiBvZiAyMDE5IGFzIHdlbGwuXG5cdCAgICAgICAgICAgICAgICBpZiAodGhpcyBpbnN0YW5jZW9mIENsb2NrRGF0ZSkge1xuXHQgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG5cdCAgICAgICAgICAgICAgICAgICAgICAgIFwiQSBQcm94eSBzaG91bGQgb25seSBjYXB0dXJlIGBuZXdgIGNhbGxzIHdpdGggdGhlIGBjb25zdHJ1Y3RgIGhhbmRsZXIuIFRoaXMgaXMgbm90IHN1cHBvc2VkIHRvIGJlIHBvc3NpYmxlLCBzbyBjaGVjayB0aGUgbG9naWMuXCIsXG5cdCAgICAgICAgICAgICAgICAgICAgKTtcblx0ICAgICAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBOYXRpdmVEYXRlKENsb2NrRGF0ZS5jbG9jay5ub3cpLnRvU3RyaW5nKCk7XG5cdCAgICAgICAgICAgIH0sXG5cdCAgICAgICAgfSk7XG5cblx0ICAgICAgICByZXR1cm4gQ2xvY2tEYXRlUHJveHk7XG5cdCAgICB9XG5cblx0ICAgIC8qKlxuXHQgICAgICogTWlycm9yIEludGwgYnkgZGVmYXVsdCBvbiBvdXIgZmFrZSBpbXBsZW1lbnRhdGlvblxuXHQgICAgICpcblx0ICAgICAqIE1vc3Qgb2YgdGhlIHByb3BlcnRpZXMgYXJlIHRoZSBvcmlnaW5hbCBuYXRpdmUgb25lcyxcblx0ICAgICAqIGJ1dCB3ZSBuZWVkIHRvIHRha2UgY29udHJvbCBvZiB0aG9zZSB0aGF0IGhhdmUgYVxuXHQgICAgICogZGVwZW5kZW5jeSBvbiB0aGUgY3VycmVudCBjbG9jay5cblx0ICAgICAqIEByZXR1cm5zIHtvYmplY3R9IHRoZSBwYXJ0bHkgZmFrZSBJbnRsIGltcGxlbWVudGF0aW9uXG5cdCAgICAgKi9cblx0ICAgIGZ1bmN0aW9uIGNyZWF0ZUludGwoKSB7XG5cdCAgICAgICAgY29uc3QgQ2xvY2tJbnRsID0ge307XG5cdCAgICAgICAgLypcblx0ICAgICAgICAgKiBBbGwgcHJvcGVydGllcyBvZiBJbnRsIGFyZSBub24tZW51bWVyYWJsZSwgc28gd2UgbmVlZFxuXHQgICAgICAgICAqIHRvIGRvIGEgYml0IG9mIHdvcmsgdG8gZ2V0IHRoZW0gb3V0LlxuXHQgICAgICAgICAqL1xuXHQgICAgICAgIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKE5hdGl2ZUludGwpLmZvckVhY2goXG5cdCAgICAgICAgICAgIChwcm9wZXJ0eSkgPT4gKENsb2NrSW50bFtwcm9wZXJ0eV0gPSBOYXRpdmVJbnRsW3Byb3BlcnR5XSksXG5cdCAgICAgICAgKTtcblxuXHQgICAgICAgIENsb2NrSW50bC5EYXRlVGltZUZvcm1hdCA9IGZ1bmN0aW9uICguLi5hcmdzKSB7XG5cdCAgICAgICAgICAgIGNvbnN0IHJlYWxGb3JtYXR0ZXIgPSBuZXcgTmF0aXZlSW50bC5EYXRlVGltZUZvcm1hdCguLi5hcmdzKTtcblx0ICAgICAgICAgICAgY29uc3QgZm9ybWF0dGVyID0ge307XG5cblx0ICAgICAgICAgICAgW1wiZm9ybWF0UmFuZ2VcIiwgXCJmb3JtYXRSYW5nZVRvUGFydHNcIiwgXCJyZXNvbHZlZE9wdGlvbnNcIl0uZm9yRWFjaChcblx0ICAgICAgICAgICAgICAgIChtZXRob2QpID0+IHtcblx0ICAgICAgICAgICAgICAgICAgICBmb3JtYXR0ZXJbbWV0aG9kXSA9XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIHJlYWxGb3JtYXR0ZXJbbWV0aG9kXS5iaW5kKHJlYWxGb3JtYXR0ZXIpO1xuXHQgICAgICAgICAgICAgICAgfSxcblx0ICAgICAgICAgICAgKTtcblxuXHQgICAgICAgICAgICBbXCJmb3JtYXRcIiwgXCJmb3JtYXRUb1BhcnRzXCJdLmZvckVhY2goKG1ldGhvZCkgPT4ge1xuXHQgICAgICAgICAgICAgICAgZm9ybWF0dGVyW21ldGhvZF0gPSBmdW5jdGlvbiAoZGF0ZSkge1xuXHQgICAgICAgICAgICAgICAgICAgIHJldHVybiByZWFsRm9ybWF0dGVyW21ldGhvZF0oZGF0ZSB8fCBDbG9ja0ludGwuY2xvY2subm93KTtcblx0ICAgICAgICAgICAgICAgIH07XG5cdCAgICAgICAgICAgIH0pO1xuXG5cdCAgICAgICAgICAgIHJldHVybiBmb3JtYXR0ZXI7XG5cdCAgICAgICAgfTtcblxuXHQgICAgICAgIENsb2NrSW50bC5EYXRlVGltZUZvcm1hdC5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKFxuXHQgICAgICAgICAgICBOYXRpdmVJbnRsLkRhdGVUaW1lRm9ybWF0LnByb3RvdHlwZSxcblx0ICAgICAgICApO1xuXG5cdCAgICAgICAgQ2xvY2tJbnRsLkRhdGVUaW1lRm9ybWF0LnN1cHBvcnRlZExvY2FsZXNPZiA9XG5cdCAgICAgICAgICAgIE5hdGl2ZUludGwuRGF0ZVRpbWVGb3JtYXQuc3VwcG9ydGVkTG9jYWxlc09mO1xuXG5cdCAgICAgICAgcmV0dXJuIENsb2NrSW50bDtcblx0ICAgIH1cblxuXHQgICAgLy9lc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUganNkb2MvcmVxdWlyZS1qc2RvY1xuXHQgICAgZnVuY3Rpb24gZW5xdWV1ZUpvYihjbG9jaywgam9iKSB7XG5cdCAgICAgICAgLy8gZW5xdWV1ZXMgYSBtaWNyb3RpY2stZGVmZXJyZWQgdGFzayAtIGVjbWEyNjIvI3NlYy1lbnF1ZXVlam9iXG5cdCAgICAgICAgaWYgKCFjbG9jay5qb2JzKSB7XG5cdCAgICAgICAgICAgIGNsb2NrLmpvYnMgPSBbXTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgY2xvY2suam9icy5wdXNoKGpvYik7XG5cdCAgICB9XG5cblx0ICAgIC8vZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGpzZG9jL3JlcXVpcmUtanNkb2Ncblx0ICAgIGZ1bmN0aW9uIHJ1bkpvYnMoY2xvY2spIHtcblx0ICAgICAgICAvLyBydW5zIGFsbCBtaWNyb3RpY2stZGVmZXJyZWQgdGFza3MgLSBlY21hMjYyLyNzZWMtcnVuam9ic1xuXHQgICAgICAgIGlmICghY2xvY2suam9icykge1xuXHQgICAgICAgICAgICByZXR1cm47XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgY2xvY2suam9icy5sZW5ndGg7IGkrKykge1xuXHQgICAgICAgICAgICBjb25zdCBqb2IgPSBjbG9jay5qb2JzW2ldO1xuXHQgICAgICAgICAgICBqb2IuZnVuYy5hcHBseShudWxsLCBqb2IuYXJncyk7XG5cblx0ICAgICAgICAgICAgY2hlY2tJc05lYXJJbmZpbml0ZUxpbWl0KGNsb2NrLCBpKTtcblx0ICAgICAgICAgICAgaWYgKGNsb2NrLmxvb3BMaW1pdCAmJiBpID4gY2xvY2subG9vcExpbWl0KSB7XG5cdCAgICAgICAgICAgICAgICB0aHJvdyBnZXRJbmZpbml0ZUxvb3BFcnJvcihjbG9jaywgam9iKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblx0ICAgICAgICByZXNldElzTmVhckluZmluaXRlTGltaXQoKTtcblx0ICAgICAgICBjbG9jay5qb2JzID0gW107XG5cdCAgICB9XG5cblx0ICAgIC8qKlxuXHQgICAgICogQHBhcmFtIHtDbG9ja30gY2xvY2tcblx0ICAgICAqIEBwYXJhbSB7VGltZXJ9IHRpbWVyXG5cdCAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBpZCBvZiB0aGUgY3JlYXRlZCB0aW1lclxuXHQgICAgICovXG5cdCAgICBmdW5jdGlvbiBhZGRUaW1lcihjbG9jaywgdGltZXIpIHtcblx0ICAgICAgICBpZiAodGltZXIuZnVuYyA9PT0gdW5kZWZpbmVkKSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIkNhbGxiYWNrIG11c3QgYmUgcHJvdmlkZWQgdG8gdGltZXIgY2FsbHNcIik7XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgaWYgKGFkZFRpbWVyUmV0dXJuc09iamVjdCkge1xuXHQgICAgICAgICAgICAvLyBOb2RlLmpzIGVudmlyb25tZW50XG5cdCAgICAgICAgICAgIGlmICh0eXBlb2YgdGltZXIuZnVuYyAhPT0gXCJmdW5jdGlvblwiKSB7XG5cdCAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuXHQgICAgICAgICAgICAgICAgICAgIGBbRVJSX0lOVkFMSURfQ0FMTEJBQ0tdOiBDYWxsYmFjayBtdXN0IGJlIGEgZnVuY3Rpb24uIFJlY2VpdmVkICR7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIHRpbWVyLmZ1bmNcblx0ICAgICAgICAgICAgICAgICAgICB9IG9mIHR5cGUgJHt0eXBlb2YgdGltZXIuZnVuY31gLFxuXHQgICAgICAgICAgICAgICAgKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblxuXHQgICAgICAgIGlmIChpc05lYXJJbmZpbml0ZUxpbWl0KSB7XG5cdCAgICAgICAgICAgIHRpbWVyLmVycm9yID0gbmV3IEVycm9yKCk7XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgdGltZXIudHlwZSA9IHRpbWVyLmltbWVkaWF0ZSA/IFwiSW1tZWRpYXRlXCIgOiBcIlRpbWVvdXRcIjtcblxuXHQgICAgICAgIGlmICh0aW1lci5oYXNPd25Qcm9wZXJ0eShcImRlbGF5XCIpKSB7XG5cdCAgICAgICAgICAgIGlmICh0eXBlb2YgdGltZXIuZGVsYXkgIT09IFwibnVtYmVyXCIpIHtcblx0ICAgICAgICAgICAgICAgIHRpbWVyLmRlbGF5ID0gcGFyc2VJbnQodGltZXIuZGVsYXksIDEwKTtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIGlmICghaXNOdW1iZXJGaW5pdGUodGltZXIuZGVsYXkpKSB7XG5cdCAgICAgICAgICAgICAgICB0aW1lci5kZWxheSA9IDA7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgdGltZXIuZGVsYXkgPSB0aW1lci5kZWxheSA+IG1heFRpbWVvdXQgPyAxIDogdGltZXIuZGVsYXk7XG5cdCAgICAgICAgICAgIHRpbWVyLmRlbGF5ID0gTWF0aC5tYXgoMCwgdGltZXIuZGVsYXkpO1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIGlmICh0aW1lci5oYXNPd25Qcm9wZXJ0eShcImludGVydmFsXCIpKSB7XG5cdCAgICAgICAgICAgIHRpbWVyLnR5cGUgPSBcIkludGVydmFsXCI7XG5cdCAgICAgICAgICAgIHRpbWVyLmludGVydmFsID0gdGltZXIuaW50ZXJ2YWwgPiBtYXhUaW1lb3V0ID8gMSA6IHRpbWVyLmludGVydmFsO1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIGlmICh0aW1lci5oYXNPd25Qcm9wZXJ0eShcImFuaW1hdGlvblwiKSkge1xuXHQgICAgICAgICAgICB0aW1lci50eXBlID0gXCJBbmltYXRpb25GcmFtZVwiO1xuXHQgICAgICAgICAgICB0aW1lci5hbmltYXRpb24gPSB0cnVlO1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIGlmICh0aW1lci5oYXNPd25Qcm9wZXJ0eShcImlkbGVDYWxsYmFja1wiKSkge1xuXHQgICAgICAgICAgICB0aW1lci50eXBlID0gXCJJZGxlQ2FsbGJhY2tcIjtcblx0ICAgICAgICAgICAgdGltZXIuaWRsZUNhbGxiYWNrID0gdHJ1ZTtcblx0ICAgICAgICB9XG5cblx0ICAgICAgICBpZiAoIWNsb2NrLnRpbWVycykge1xuXHQgICAgICAgICAgICBjbG9jay50aW1lcnMgPSB7fTtcblx0ICAgICAgICB9XG5cblx0ICAgICAgICB0aW1lci5pZCA9IHVuaXF1ZVRpbWVySWQrKztcblx0ICAgICAgICB0aW1lci5jcmVhdGVkQXQgPSBjbG9jay5ub3c7XG5cdCAgICAgICAgdGltZXIuY2FsbEF0ID1cblx0ICAgICAgICAgICAgY2xvY2subm93ICsgKHBhcnNlSW50KHRpbWVyLmRlbGF5KSB8fCAoY2xvY2suZHVyaW5nVGljayA/IDEgOiAwKSk7XG5cblx0ICAgICAgICBjbG9jay50aW1lcnNbdGltZXIuaWRdID0gdGltZXI7XG5cblx0ICAgICAgICBpZiAoYWRkVGltZXJSZXR1cm5zT2JqZWN0KSB7XG5cdCAgICAgICAgICAgIGNvbnN0IHJlcyA9IHtcblx0ICAgICAgICAgICAgICAgIHJlZmVkOiB0cnVlLFxuXHQgICAgICAgICAgICAgICAgcmVmOiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdGhpcy5yZWZlZCA9IHRydWU7XG5cdCAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlcztcblx0ICAgICAgICAgICAgICAgIH0sXG5cdCAgICAgICAgICAgICAgICB1bnJlZjogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICAgICAgICAgIHRoaXMucmVmZWQgPSBmYWxzZTtcblx0ICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzO1xuXHQgICAgICAgICAgICAgICAgfSxcblx0ICAgICAgICAgICAgICAgIGhhc1JlZjogZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnJlZmVkO1xuXHQgICAgICAgICAgICAgICAgfSxcblx0ICAgICAgICAgICAgICAgIHJlZnJlc2g6IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgICAgICAgICB0aW1lci5jYWxsQXQgPVxuXHQgICAgICAgICAgICAgICAgICAgICAgICBjbG9jay5ub3cgK1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAocGFyc2VJbnQodGltZXIuZGVsYXkpIHx8IChjbG9jay5kdXJpbmdUaWNrID8gMSA6IDApKTtcblxuXHQgICAgICAgICAgICAgICAgICAgIC8vIGl0IF9taWdodF8gaGF2ZSBiZWVuIHJlbW92ZWQsIGJ1dCBpZiBub3QgdGhlIGFzc2lnbm1lbnQgaXMgcGVyZmVjdGx5IGZpbmVcblx0ICAgICAgICAgICAgICAgICAgICBjbG9jay50aW1lcnNbdGltZXIuaWRdID0gdGltZXI7XG5cblx0ICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzO1xuXHQgICAgICAgICAgICAgICAgfSxcblx0ICAgICAgICAgICAgICAgIFtTeW1ib2wudG9QcmltaXRpdmVdOiBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRpbWVyLmlkO1xuXHQgICAgICAgICAgICAgICAgfSxcblx0ICAgICAgICAgICAgfTtcblx0ICAgICAgICAgICAgcmV0dXJuIHJlcztcblx0ICAgICAgICB9XG5cblx0ICAgICAgICByZXR1cm4gdGltZXIuaWQ7XG5cdCAgICB9XG5cblx0ICAgIC8qIGVzbGludCBjb25zaXN0ZW50LXJldHVybjogXCJvZmZcIiAqL1xuXHQgICAgLyoqXG5cdCAgICAgKiBUaW1lciBjb21wYXJpdG9yXG5cdCAgICAgKiBAcGFyYW0ge1RpbWVyfSBhXG5cdCAgICAgKiBAcGFyYW0ge1RpbWVyfSBiXG5cdCAgICAgKiBAcmV0dXJucyB7bnVtYmVyfVxuXHQgICAgICovXG5cdCAgICBmdW5jdGlvbiBjb21wYXJlVGltZXJzKGEsIGIpIHtcblx0ICAgICAgICAvLyBTb3J0IGZpcnN0IGJ5IGFic29sdXRlIHRpbWluZ1xuXHQgICAgICAgIGlmIChhLmNhbGxBdCA8IGIuY2FsbEF0KSB7XG5cdCAgICAgICAgICAgIHJldHVybiAtMTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgaWYgKGEuY2FsbEF0ID4gYi5jYWxsQXQpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIDE7XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgLy8gU29ydCBuZXh0IGJ5IGltbWVkaWF0ZSwgaW1tZWRpYXRlIHRpbWVycyB0YWtlIHByZWNlZGVuY2Vcblx0ICAgICAgICBpZiAoYS5pbW1lZGlhdGUgJiYgIWIuaW1tZWRpYXRlKSB7XG5cdCAgICAgICAgICAgIHJldHVybiAtMTtcblx0ICAgICAgICB9XG5cdCAgICAgICAgaWYgKCFhLmltbWVkaWF0ZSAmJiBiLmltbWVkaWF0ZSkge1xuXHQgICAgICAgICAgICByZXR1cm4gMTtcblx0ICAgICAgICB9XG5cblx0ICAgICAgICAvLyBTb3J0IG5leHQgYnkgY3JlYXRpb24gdGltZSwgZWFybGllci1jcmVhdGVkIHRpbWVycyB0YWtlIHByZWNlZGVuY2Vcblx0ICAgICAgICBpZiAoYS5jcmVhdGVkQXQgPCBiLmNyZWF0ZWRBdCkge1xuXHQgICAgICAgICAgICByZXR1cm4gLTE7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGlmIChhLmNyZWF0ZWRBdCA+IGIuY3JlYXRlZEF0KSB7XG5cdCAgICAgICAgICAgIHJldHVybiAxO1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIC8vIFNvcnQgbmV4dCBieSBpZCwgbG93ZXItaWQgdGltZXJzIHRha2UgcHJlY2VkZW5jZVxuXHQgICAgICAgIGlmIChhLmlkIDwgYi5pZCkge1xuXHQgICAgICAgICAgICByZXR1cm4gLTE7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIGlmIChhLmlkID4gYi5pZCkge1xuXHQgICAgICAgICAgICByZXR1cm4gMTtcblx0ICAgICAgICB9XG5cblx0ICAgICAgICAvLyBBcyB0aW1lciBpZHMgYXJlIHVuaXF1ZSwgbm8gZmFsbGJhY2sgYDBgIGlzIG5lY2Vzc2FyeVxuXHQgICAgfVxuXG5cdCAgICAvKipcblx0ICAgICAqIEBwYXJhbSB7Q2xvY2t9IGNsb2NrXG5cdCAgICAgKiBAcGFyYW0ge251bWJlcn0gZnJvbVxuXHQgICAgICogQHBhcmFtIHtudW1iZXJ9IHRvXG5cdCAgICAgKiBAcmV0dXJucyB7VGltZXJ9XG5cdCAgICAgKi9cblx0ICAgIGZ1bmN0aW9uIGZpcnN0VGltZXJJblJhbmdlKGNsb2NrLCBmcm9tLCB0bykge1xuXHQgICAgICAgIGNvbnN0IHRpbWVycyA9IGNsb2NrLnRpbWVycztcblx0ICAgICAgICBsZXQgdGltZXIgPSBudWxsO1xuXHQgICAgICAgIGxldCBpZCwgaXNJblJhbmdlO1xuXG5cdCAgICAgICAgZm9yIChpZCBpbiB0aW1lcnMpIHtcblx0ICAgICAgICAgICAgaWYgKHRpbWVycy5oYXNPd25Qcm9wZXJ0eShpZCkpIHtcblx0ICAgICAgICAgICAgICAgIGlzSW5SYW5nZSA9IGluUmFuZ2UoZnJvbSwgdG8sIHRpbWVyc1tpZF0pO1xuXG5cdCAgICAgICAgICAgICAgICBpZiAoXG5cdCAgICAgICAgICAgICAgICAgICAgaXNJblJhbmdlICYmXG5cdCAgICAgICAgICAgICAgICAgICAgKCF0aW1lciB8fCBjb21wYXJlVGltZXJzKHRpbWVyLCB0aW1lcnNbaWRdKSA9PT0gMSlcblx0ICAgICAgICAgICAgICAgICkge1xuXHQgICAgICAgICAgICAgICAgICAgIHRpbWVyID0gdGltZXJzW2lkXTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblxuXHQgICAgICAgIHJldHVybiB0aW1lcjtcblx0ICAgIH1cblxuXHQgICAgLyoqXG5cdCAgICAgKiBAcGFyYW0ge0Nsb2NrfSBjbG9ja1xuXHQgICAgICogQHJldHVybnMge1RpbWVyfVxuXHQgICAgICovXG5cdCAgICBmdW5jdGlvbiBmaXJzdFRpbWVyKGNsb2NrKSB7XG5cdCAgICAgICAgY29uc3QgdGltZXJzID0gY2xvY2sudGltZXJzO1xuXHQgICAgICAgIGxldCB0aW1lciA9IG51bGw7XG5cdCAgICAgICAgbGV0IGlkO1xuXG5cdCAgICAgICAgZm9yIChpZCBpbiB0aW1lcnMpIHtcblx0ICAgICAgICAgICAgaWYgKHRpbWVycy5oYXNPd25Qcm9wZXJ0eShpZCkpIHtcblx0ICAgICAgICAgICAgICAgIGlmICghdGltZXIgfHwgY29tcGFyZVRpbWVycyh0aW1lciwgdGltZXJzW2lkXSkgPT09IDEpIHtcblx0ICAgICAgICAgICAgICAgICAgICB0aW1lciA9IHRpbWVyc1tpZF07XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cblx0ICAgICAgICByZXR1cm4gdGltZXI7XG5cdCAgICB9XG5cblx0ICAgIC8qKlxuXHQgICAgICogQHBhcmFtIHtDbG9ja30gY2xvY2tcblx0ICAgICAqIEByZXR1cm5zIHtUaW1lcn1cblx0ICAgICAqL1xuXHQgICAgZnVuY3Rpb24gbGFzdFRpbWVyKGNsb2NrKSB7XG5cdCAgICAgICAgY29uc3QgdGltZXJzID0gY2xvY2sudGltZXJzO1xuXHQgICAgICAgIGxldCB0aW1lciA9IG51bGw7XG5cdCAgICAgICAgbGV0IGlkO1xuXG5cdCAgICAgICAgZm9yIChpZCBpbiB0aW1lcnMpIHtcblx0ICAgICAgICAgICAgaWYgKHRpbWVycy5oYXNPd25Qcm9wZXJ0eShpZCkpIHtcblx0ICAgICAgICAgICAgICAgIGlmICghdGltZXIgfHwgY29tcGFyZVRpbWVycyh0aW1lciwgdGltZXJzW2lkXSkgPT09IC0xKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdGltZXIgPSB0aW1lcnNbaWRdO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgcmV0dXJuIHRpbWVyO1xuXHQgICAgfVxuXG5cdCAgICAvKipcblx0ICAgICAqIEBwYXJhbSB7Q2xvY2t9IGNsb2NrXG5cdCAgICAgKiBAcGFyYW0ge1RpbWVyfSB0aW1lclxuXHQgICAgICovXG5cdCAgICBmdW5jdGlvbiBjYWxsVGltZXIoY2xvY2ssIHRpbWVyKSB7XG5cdCAgICAgICAgaWYgKHR5cGVvZiB0aW1lci5pbnRlcnZhbCA9PT0gXCJudW1iZXJcIikge1xuXHQgICAgICAgICAgICBjbG9jay50aW1lcnNbdGltZXIuaWRdLmNhbGxBdCArPSB0aW1lci5pbnRlcnZhbDtcblx0ICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICBkZWxldGUgY2xvY2sudGltZXJzW3RpbWVyLmlkXTtcblx0ICAgICAgICB9XG5cblx0ICAgICAgICBpZiAodHlwZW9mIHRpbWVyLmZ1bmMgPT09IFwiZnVuY3Rpb25cIikge1xuXHQgICAgICAgICAgICB0aW1lci5mdW5jLmFwcGx5KG51bGwsIHRpbWVyLmFyZ3MpO1xuXHQgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgIC8qIGVzbGludCBuby1ldmFsOiBcIm9mZlwiICovXG5cdCAgICAgICAgICAgIGNvbnN0IGV2YWwyID0gZXZhbDtcblx0ICAgICAgICAgICAgKGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgICAgIGV2YWwyKHRpbWVyLmZ1bmMpO1xuXHQgICAgICAgICAgICB9KSgpO1xuXHQgICAgICAgIH1cblx0ICAgIH1cblxuXHQgICAgLyoqXG5cdCAgICAgKiBHZXRzIGNsZWFyIGhhbmRsZXIgbmFtZSBmb3IgYSBnaXZlbiB0aW1lciB0eXBlXG5cdCAgICAgKiBAcGFyYW0ge3N0cmluZ30gdHR5cGVcblx0ICAgICAqL1xuXHQgICAgZnVuY3Rpb24gZ2V0Q2xlYXJIYW5kbGVyKHR0eXBlKSB7XG5cdCAgICAgICAgaWYgKHR0eXBlID09PSBcIklkbGVDYWxsYmFja1wiIHx8IHR0eXBlID09PSBcIkFuaW1hdGlvbkZyYW1lXCIpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIGBjYW5jZWwke3R0eXBlfWA7XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiBgY2xlYXIke3R0eXBlfWA7XG5cdCAgICB9XG5cblx0ICAgIC8qKlxuXHQgICAgICogR2V0cyBzY2hlZHVsZSBoYW5kbGVyIG5hbWUgZm9yIGEgZ2l2ZW4gdGltZXIgdHlwZVxuXHQgICAgICogQHBhcmFtIHtzdHJpbmd9IHR0eXBlXG5cdCAgICAgKi9cblx0ICAgIGZ1bmN0aW9uIGdldFNjaGVkdWxlSGFuZGxlcih0dHlwZSkge1xuXHQgICAgICAgIGlmICh0dHlwZSA9PT0gXCJJZGxlQ2FsbGJhY2tcIiB8fCB0dHlwZSA9PT0gXCJBbmltYXRpb25GcmFtZVwiKSB7XG5cdCAgICAgICAgICAgIHJldHVybiBgcmVxdWVzdCR7dHR5cGV9YDtcblx0ICAgICAgICB9XG5cdCAgICAgICAgcmV0dXJuIGBzZXQke3R0eXBlfWA7XG5cdCAgICB9XG5cblx0ICAgIC8qKlxuXHQgICAgICogQ3JlYXRlcyBhbiBhbm9ueW1vdXMgZnVuY3Rpb24gdG8gd2FybiBvbmx5IG9uY2Vcblx0ICAgICAqL1xuXHQgICAgZnVuY3Rpb24gY3JlYXRlV2Fybk9uY2UoKSB7XG5cdCAgICAgICAgbGV0IGNhbGxzID0gMDtcblx0ICAgICAgICByZXR1cm4gZnVuY3Rpb24gKG1zZykge1xuXHQgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmVcblx0ICAgICAgICAgICAgIWNhbGxzKysgJiYgY29uc29sZS53YXJuKG1zZyk7XG5cdCAgICAgICAgfTtcblx0ICAgIH1cblx0ICAgIGNvbnN0IHdhcm5PbmNlID0gY3JlYXRlV2Fybk9uY2UoKTtcblxuXHQgICAgLyoqXG5cdCAgICAgKiBAcGFyYW0ge0Nsb2NrfSBjbG9ja1xuXHQgICAgICogQHBhcmFtIHtudW1iZXJ9IHRpbWVySWRcblx0ICAgICAqIEBwYXJhbSB7c3RyaW5nfSB0dHlwZVxuXHQgICAgICovXG5cdCAgICBmdW5jdGlvbiBjbGVhclRpbWVyKGNsb2NrLCB0aW1lcklkLCB0dHlwZSkge1xuXHQgICAgICAgIGlmICghdGltZXJJZCkge1xuXHQgICAgICAgICAgICAvLyBudWxsIGFwcGVhcnMgdG8gYmUgYWxsb3dlZCBpbiBtb3N0IGJyb3dzZXJzLCBhbmQgYXBwZWFycyB0byBiZVxuXHQgICAgICAgICAgICAvLyByZWxpZWQgdXBvbiBieSBzb21lIGxpYnJhcmllcywgbGlrZSBCb290c3RyYXAgY2Fyb3VzZWxcblx0ICAgICAgICAgICAgcmV0dXJuO1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIGlmICghY2xvY2sudGltZXJzKSB7XG5cdCAgICAgICAgICAgIGNsb2NrLnRpbWVycyA9IHt9O1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIC8vIGluIE5vZGUsIHRoZSBJRCBpcyBzdG9yZWQgYXMgdGhlIHByaW1pdGl2ZSB2YWx1ZSBmb3IgYFRpbWVvdXRgIG9iamVjdHNcblx0ICAgICAgICAvLyBmb3IgYEltbWVkaWF0ZWAgb2JqZWN0cywgbm8gSUQgZXhpc3RzLCBzbyBpdCBnZXRzIGNvZXJjZWQgdG8gTmFOXG5cdCAgICAgICAgY29uc3QgaWQgPSBOdW1iZXIodGltZXJJZCk7XG5cblx0ICAgICAgICBpZiAoTnVtYmVyLmlzTmFOKGlkKSB8fCBpZCA8IGlkQ291bnRlclN0YXJ0KSB7XG5cdCAgICAgICAgICAgIGNvbnN0IGhhbmRsZXJOYW1lID0gZ2V0Q2xlYXJIYW5kbGVyKHR0eXBlKTtcblxuXHQgICAgICAgICAgICBpZiAoY2xvY2suc2hvdWxkQ2xlYXJOYXRpdmVUaW1lcnMgPT09IHRydWUpIHtcblx0ICAgICAgICAgICAgICAgIGNvbnN0IG5hdGl2ZUhhbmRsZXIgPSBjbG9ja1tgXyR7aGFuZGxlck5hbWV9YF07XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gdHlwZW9mIG5hdGl2ZUhhbmRsZXIgPT09IFwiZnVuY3Rpb25cIlxuXHQgICAgICAgICAgICAgICAgICAgID8gbmF0aXZlSGFuZGxlcih0aW1lcklkKVxuXHQgICAgICAgICAgICAgICAgICAgIDogdW5kZWZpbmVkO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIHdhcm5PbmNlKFxuXHQgICAgICAgICAgICAgICAgYEZha2VUaW1lcnM6ICR7aGFuZGxlck5hbWV9IHdhcyBpbnZva2VkIHRvIGNsZWFyIGEgbmF0aXZlIHRpbWVyIGluc3RlYWQgb2Ygb25lIGNyZWF0ZWQgYnkgdGhpcyBsaWJyYXJ5LmAgK1xuXHQgICAgICAgICAgICAgICAgICAgIFwiXFxuVG8gYXV0b21hdGljYWxseSBjbGVhbi11cCBuYXRpdmUgdGltZXJzLCB1c2UgYHNob3VsZENsZWFyTmF0aXZlVGltZXJzYC5cIixcblx0ICAgICAgICAgICAgKTtcblx0ICAgICAgICB9XG5cblx0ICAgICAgICBpZiAoY2xvY2sudGltZXJzLmhhc093blByb3BlcnR5KGlkKSkge1xuXHQgICAgICAgICAgICAvLyBjaGVjayB0aGF0IHRoZSBJRCBtYXRjaGVzIGEgdGltZXIgb2YgdGhlIGNvcnJlY3QgdHlwZVxuXHQgICAgICAgICAgICBjb25zdCB0aW1lciA9IGNsb2NrLnRpbWVyc1tpZF07XG5cdCAgICAgICAgICAgIGlmIChcblx0ICAgICAgICAgICAgICAgIHRpbWVyLnR5cGUgPT09IHR0eXBlIHx8XG5cdCAgICAgICAgICAgICAgICAodGltZXIudHlwZSA9PT0gXCJUaW1lb3V0XCIgJiYgdHR5cGUgPT09IFwiSW50ZXJ2YWxcIikgfHxcblx0ICAgICAgICAgICAgICAgICh0aW1lci50eXBlID09PSBcIkludGVydmFsXCIgJiYgdHR5cGUgPT09IFwiVGltZW91dFwiKVxuXHQgICAgICAgICAgICApIHtcblx0ICAgICAgICAgICAgICAgIGRlbGV0ZSBjbG9jay50aW1lcnNbaWRdO1xuXHQgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgY29uc3QgY2xlYXIgPSBnZXRDbGVhckhhbmRsZXIodHR5cGUpO1xuXHQgICAgICAgICAgICAgICAgY29uc3Qgc2NoZWR1bGUgPSBnZXRTY2hlZHVsZUhhbmRsZXIodGltZXIudHlwZSk7XG5cdCAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG5cdCAgICAgICAgICAgICAgICAgICAgYENhbm5vdCBjbGVhciB0aW1lcjogdGltZXIgY3JlYXRlZCB3aXRoICR7c2NoZWR1bGV9KCkgYnV0IGNsZWFyZWQgd2l0aCAke2NsZWFyfSgpYCxcblx0ICAgICAgICAgICAgICAgICk7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICB9XG5cblx0ICAgIC8qKlxuXHQgICAgICogQHBhcmFtIHtDbG9ja30gY2xvY2tcblx0ICAgICAqIEByZXR1cm5zIHtUaW1lcltdfVxuXHQgICAgICovXG5cdCAgICBmdW5jdGlvbiB1bmluc3RhbGwoY2xvY2spIHtcblx0ICAgICAgICBsZXQgbWV0aG9kLCBpLCBsO1xuXHQgICAgICAgIGNvbnN0IGluc3RhbGxlZEhyVGltZSA9IFwiX2hydGltZVwiO1xuXHQgICAgICAgIGNvbnN0IGluc3RhbGxlZE5leHRUaWNrID0gXCJfbmV4dFRpY2tcIjtcblxuXHQgICAgICAgIGZvciAoaSA9IDAsIGwgPSBjbG9jay5tZXRob2RzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuXHQgICAgICAgICAgICBtZXRob2QgPSBjbG9jay5tZXRob2RzW2ldO1xuXHQgICAgICAgICAgICBpZiAobWV0aG9kID09PSBcImhydGltZVwiICYmIF9nbG9iYWwucHJvY2Vzcykge1xuXHQgICAgICAgICAgICAgICAgX2dsb2JhbC5wcm9jZXNzLmhydGltZSA9IGNsb2NrW2luc3RhbGxlZEhyVGltZV07XG5cdCAgICAgICAgICAgIH0gZWxzZSBpZiAobWV0aG9kID09PSBcIm5leHRUaWNrXCIgJiYgX2dsb2JhbC5wcm9jZXNzKSB7XG5cdCAgICAgICAgICAgICAgICBfZ2xvYmFsLnByb2Nlc3MubmV4dFRpY2sgPSBjbG9ja1tpbnN0YWxsZWROZXh0VGlja107XG5cdCAgICAgICAgICAgIH0gZWxzZSBpZiAobWV0aG9kID09PSBcInBlcmZvcm1hbmNlXCIpIHtcblx0ICAgICAgICAgICAgICAgIGNvbnN0IG9yaWdpbmFsUGVyZkRlc2NyaXB0b3IgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKFxuXHQgICAgICAgICAgICAgICAgICAgIGNsb2NrLFxuXHQgICAgICAgICAgICAgICAgICAgIGBfJHttZXRob2R9YCxcblx0ICAgICAgICAgICAgICAgICk7XG5cdCAgICAgICAgICAgICAgICBpZiAoXG5cdCAgICAgICAgICAgICAgICAgICAgb3JpZ2luYWxQZXJmRGVzY3JpcHRvciAmJlxuXHQgICAgICAgICAgICAgICAgICAgIG9yaWdpbmFsUGVyZkRlc2NyaXB0b3IuZ2V0ICYmXG5cdCAgICAgICAgICAgICAgICAgICAgIW9yaWdpbmFsUGVyZkRlc2NyaXB0b3Iuc2V0XG5cdCAgICAgICAgICAgICAgICApIHtcblx0ICAgICAgICAgICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoXG5cdCAgICAgICAgICAgICAgICAgICAgICAgIF9nbG9iYWwsXG5cdCAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZCxcblx0ICAgICAgICAgICAgICAgICAgICAgICAgb3JpZ2luYWxQZXJmRGVzY3JpcHRvcixcblx0ICAgICAgICAgICAgICAgICAgICApO1xuXHQgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChvcmlnaW5hbFBlcmZEZXNjcmlwdG9yLmNvbmZpZ3VyYWJsZSkge1xuXHQgICAgICAgICAgICAgICAgICAgIF9nbG9iYWxbbWV0aG9kXSA9IGNsb2NrW2BfJHttZXRob2R9YF07XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICBpZiAoX2dsb2JhbFttZXRob2RdICYmIF9nbG9iYWxbbWV0aG9kXS5oYWRPd25Qcm9wZXJ0eSkge1xuXHQgICAgICAgICAgICAgICAgICAgIF9nbG9iYWxbbWV0aG9kXSA9IGNsb2NrW2BfJHttZXRob2R9YF07XG5cdCAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgICAgIHRyeSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIGRlbGV0ZSBfZ2xvYmFsW21ldGhvZF07XG5cdCAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoaWdub3JlKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIC8qIGVzbGludCBuby1lbXB0eTogXCJvZmZcIiAqL1xuXHQgICAgICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICBpZiAoY2xvY2sudGltZXJzTW9kdWxlTWV0aG9kcyAhPT0gdW5kZWZpbmVkKSB7XG5cdCAgICAgICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGNsb2NrLnRpbWVyc01vZHVsZU1ldGhvZHMubGVuZ3RoOyBqKyspIHtcblx0ICAgICAgICAgICAgICAgICAgICBjb25zdCBlbnRyeSA9IGNsb2NrLnRpbWVyc01vZHVsZU1ldGhvZHNbal07XG5cdCAgICAgICAgICAgICAgICAgICAgdGltZXJzTW9kdWxlW2VudHJ5Lm1ldGhvZE5hbWVdID0gZW50cnkub3JpZ2luYWw7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgaWYgKGNsb2NrLnRpbWVyc1Byb21pc2VzTW9kdWxlTWV0aG9kcyAhPT0gdW5kZWZpbmVkKSB7XG5cdCAgICAgICAgICAgICAgICBmb3IgKFxuXHQgICAgICAgICAgICAgICAgICAgIGxldCBqID0gMDtcblx0ICAgICAgICAgICAgICAgICAgICBqIDwgY2xvY2sudGltZXJzUHJvbWlzZXNNb2R1bGVNZXRob2RzLmxlbmd0aDtcblx0ICAgICAgICAgICAgICAgICAgICBqKytcblx0ICAgICAgICAgICAgICAgICkge1xuXHQgICAgICAgICAgICAgICAgICAgIGNvbnN0IGVudHJ5ID0gY2xvY2sudGltZXJzUHJvbWlzZXNNb2R1bGVNZXRob2RzW2pdO1xuXHQgICAgICAgICAgICAgICAgICAgIHRpbWVyc1Byb21pc2VzTW9kdWxlW2VudHJ5Lm1ldGhvZE5hbWVdID0gZW50cnkub3JpZ2luYWw7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cblx0ICAgICAgICBjbG9jay5zZXRUaWNrTW9kZShcIm1hbnVhbFwiKTtcblxuXHQgICAgICAgIC8vIFByZXZlbnQgbXVsdGlwbGUgZXhlY3V0aW9ucyB3aGljaCB3aWxsIGNvbXBsZXRlbHkgcmVtb3ZlIHRoZXNlIHByb3BzXG5cdCAgICAgICAgY2xvY2subWV0aG9kcyA9IFtdO1xuXG5cdCAgICAgICAgZm9yIChjb25zdCBbbGlzdGVuZXIsIHNpZ25hbF0gb2YgY2xvY2suYWJvcnRMaXN0ZW5lck1hcC5lbnRyaWVzKCkpIHtcblx0ICAgICAgICAgICAgc2lnbmFsLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJhYm9ydFwiLCBsaXN0ZW5lcik7XG5cdCAgICAgICAgICAgIGNsb2NrLmFib3J0TGlzdGVuZXJNYXAuZGVsZXRlKGxpc3RlbmVyKTtcblx0ICAgICAgICB9XG5cblx0ICAgICAgICAvLyByZXR1cm4gcGVuZGluZyB0aW1lcnMsIHRvIGVuYWJsZSBjaGVja2luZyB3aGF0IHRpbWVycyByZW1haW5lZCBvbiB1bmluc3RhbGxcblx0ICAgICAgICBpZiAoIWNsb2NrLnRpbWVycykge1xuXHQgICAgICAgICAgICByZXR1cm4gW107XG5cdCAgICAgICAgfVxuXHQgICAgICAgIHJldHVybiBPYmplY3Qua2V5cyhjbG9jay50aW1lcnMpLm1hcChmdW5jdGlvbiBtYXBwZXIoa2V5KSB7XG5cdCAgICAgICAgICAgIHJldHVybiBjbG9jay50aW1lcnNba2V5XTtcblx0ICAgICAgICB9KTtcblx0ICAgIH1cblxuXHQgICAgLyoqXG5cdCAgICAgKiBAcGFyYW0ge29iamVjdH0gdGFyZ2V0IHRoZSB0YXJnZXQgY29udGFpbmluZyB0aGUgbWV0aG9kIHRvIHJlcGxhY2Vcblx0ICAgICAqIEBwYXJhbSB7c3RyaW5nfSBtZXRob2QgdGhlIGtleW5hbWUgb2YgdGhlIG1ldGhvZCBvbiB0aGUgdGFyZ2V0XG5cdCAgICAgKiBAcGFyYW0ge0Nsb2NrfSBjbG9ja1xuXHQgICAgICovXG5cdCAgICBmdW5jdGlvbiBoaWphY2tNZXRob2QodGFyZ2V0LCBtZXRob2QsIGNsb2NrKSB7XG5cdCAgICAgICAgY2xvY2tbbWV0aG9kXS5oYWRPd25Qcm9wZXJ0eSA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChcblx0ICAgICAgICAgICAgdGFyZ2V0LFxuXHQgICAgICAgICAgICBtZXRob2QsXG5cdCAgICAgICAgKTtcblx0ICAgICAgICBjbG9ja1tgXyR7bWV0aG9kfWBdID0gdGFyZ2V0W21ldGhvZF07XG5cblx0ICAgICAgICBpZiAobWV0aG9kID09PSBcIkRhdGVcIikge1xuXHQgICAgICAgICAgICB0YXJnZXRbbWV0aG9kXSA9IGNsb2NrW21ldGhvZF07XG5cdCAgICAgICAgfSBlbHNlIGlmIChtZXRob2QgPT09IFwiSW50bFwiKSB7XG5cdCAgICAgICAgICAgIHRhcmdldFttZXRob2RdID0gY2xvY2tbbWV0aG9kXTtcblx0ICAgICAgICB9IGVsc2UgaWYgKG1ldGhvZCA9PT0gXCJwZXJmb3JtYW5jZVwiKSB7XG5cdCAgICAgICAgICAgIGNvbnN0IG9yaWdpbmFsUGVyZkRlc2NyaXB0b3IgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKFxuXHQgICAgICAgICAgICAgICAgdGFyZ2V0LFxuXHQgICAgICAgICAgICAgICAgbWV0aG9kLFxuXHQgICAgICAgICAgICApO1xuXHQgICAgICAgICAgICAvLyBKU0RPTSBoYXMgYSByZWFkIG9ubHkgcGVyZm9ybWFuY2UgZmllbGQgc28gd2UgaGF2ZSB0byBzYXZlL2NvcHkgaXQgZGlmZmVyZW50bHlcblx0ICAgICAgICAgICAgaWYgKFxuXHQgICAgICAgICAgICAgICAgb3JpZ2luYWxQZXJmRGVzY3JpcHRvciAmJlxuXHQgICAgICAgICAgICAgICAgb3JpZ2luYWxQZXJmRGVzY3JpcHRvci5nZXQgJiZcblx0ICAgICAgICAgICAgICAgICFvcmlnaW5hbFBlcmZEZXNjcmlwdG9yLnNldFxuXHQgICAgICAgICAgICApIHtcblx0ICAgICAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShcblx0ICAgICAgICAgICAgICAgICAgICBjbG9jayxcblx0ICAgICAgICAgICAgICAgICAgICBgXyR7bWV0aG9kfWAsXG5cdCAgICAgICAgICAgICAgICAgICAgb3JpZ2luYWxQZXJmRGVzY3JpcHRvcixcblx0ICAgICAgICAgICAgICAgICk7XG5cblx0ICAgICAgICAgICAgICAgIGNvbnN0IHBlcmZEZXNjcmlwdG9yID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihcblx0ICAgICAgICAgICAgICAgICAgICBjbG9jayxcblx0ICAgICAgICAgICAgICAgICAgICBtZXRob2QsXG5cdCAgICAgICAgICAgICAgICApO1xuXHQgICAgICAgICAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHRhcmdldCwgbWV0aG9kLCBwZXJmRGVzY3JpcHRvcik7XG5cdCAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICB0YXJnZXRbbWV0aG9kXSA9IGNsb2NrW21ldGhvZF07XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICB0YXJnZXRbbWV0aG9kXSA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgICAgIHJldHVybiBjbG9ja1ttZXRob2RdLmFwcGx5KGNsb2NrLCBhcmd1bWVudHMpO1xuXHQgICAgICAgICAgICB9O1xuXG5cdCAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0aWVzKFxuXHQgICAgICAgICAgICAgICAgdGFyZ2V0W21ldGhvZF0sXG5cdCAgICAgICAgICAgICAgICBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9ycyhjbG9ja1ttZXRob2RdKSxcblx0ICAgICAgICAgICAgKTtcblx0ICAgICAgICB9XG5cblx0ICAgICAgICB0YXJnZXRbbWV0aG9kXS5jbG9jayA9IGNsb2NrO1xuXHQgICAgfVxuXG5cdCAgICAvKipcblx0ICAgICAqIEBwYXJhbSB7Q2xvY2t9IGNsb2NrXG5cdCAgICAgKiBAcGFyYW0ge251bWJlcn0gYWR2YW5jZVRpbWVEZWx0YVxuXHQgICAgICovXG5cdCAgICBmdW5jdGlvbiBkb0ludGVydmFsVGljayhjbG9jaywgYWR2YW5jZVRpbWVEZWx0YSkge1xuXHQgICAgICAgIGNsb2NrLnRpY2soYWR2YW5jZVRpbWVEZWx0YSk7XG5cdCAgICB9XG5cblx0ICAgIC8qKlxuXHQgICAgICogQHR5cGVkZWYge29iamVjdH0gVGltZXJzXG5cdCAgICAgKiBAcHJvcGVydHkge3NldFRpbWVvdXR9IHNldFRpbWVvdXRcblx0ICAgICAqIEBwcm9wZXJ0eSB7Y2xlYXJUaW1lb3V0fSBjbGVhclRpbWVvdXRcblx0ICAgICAqIEBwcm9wZXJ0eSB7c2V0SW50ZXJ2YWx9IHNldEludGVydmFsXG5cdCAgICAgKiBAcHJvcGVydHkge2NsZWFySW50ZXJ2YWx9IGNsZWFySW50ZXJ2YWxcblx0ICAgICAqIEBwcm9wZXJ0eSB7RGF0ZX0gRGF0ZVxuXHQgICAgICogQHByb3BlcnR5IHtJbnRsfSBJbnRsXG5cdCAgICAgKiBAcHJvcGVydHkge1NldEltbWVkaWF0ZT19IHNldEltbWVkaWF0ZVxuXHQgICAgICogQHByb3BlcnR5IHtmdW5jdGlvbihOb2RlSW1tZWRpYXRlKTogdm9pZD19IGNsZWFySW1tZWRpYXRlXG5cdCAgICAgKiBAcHJvcGVydHkge2Z1bmN0aW9uKG51bWJlcltdKTpudW1iZXJbXT19IGhydGltZVxuXHQgICAgICogQHByb3BlcnR5IHtOZXh0VGljaz19IG5leHRUaWNrXG5cdCAgICAgKiBAcHJvcGVydHkge1BlcmZvcm1hbmNlPX0gcGVyZm9ybWFuY2Vcblx0ICAgICAqIEBwcm9wZXJ0eSB7UmVxdWVzdEFuaW1hdGlvbkZyYW1lPX0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lXG5cdCAgICAgKiBAcHJvcGVydHkge2Jvb2xlYW49fSBxdWV1ZU1pY3JvdGFza1xuXHQgICAgICogQHByb3BlcnR5IHtmdW5jdGlvbihudW1iZXIpOiB2b2lkPX0gY2FuY2VsQW5pbWF0aW9uRnJhbWVcblx0ICAgICAqIEBwcm9wZXJ0eSB7UmVxdWVzdElkbGVDYWxsYmFjaz19IHJlcXVlc3RJZGxlQ2FsbGJhY2tcblx0ICAgICAqIEBwcm9wZXJ0eSB7ZnVuY3Rpb24obnVtYmVyKTogdm9pZD19IGNhbmNlbElkbGVDYWxsYmFja1xuXHQgICAgICovXG5cblx0ICAgIC8qKiBAdHlwZSB7VGltZXJzfSAqL1xuXHQgICAgY29uc3QgdGltZXJzID0ge1xuXHQgICAgICAgIHNldFRpbWVvdXQ6IF9nbG9iYWwuc2V0VGltZW91dCxcblx0ICAgICAgICBjbGVhclRpbWVvdXQ6IF9nbG9iYWwuY2xlYXJUaW1lb3V0LFxuXHQgICAgICAgIHNldEludGVydmFsOiBfZ2xvYmFsLnNldEludGVydmFsLFxuXHQgICAgICAgIGNsZWFySW50ZXJ2YWw6IF9nbG9iYWwuY2xlYXJJbnRlcnZhbCxcblx0ICAgICAgICBEYXRlOiBfZ2xvYmFsLkRhdGUsXG5cdCAgICB9O1xuXG5cdCAgICBpZiAoaXNQcmVzZW50LnNldEltbWVkaWF0ZSkge1xuXHQgICAgICAgIHRpbWVycy5zZXRJbW1lZGlhdGUgPSBfZ2xvYmFsLnNldEltbWVkaWF0ZTtcblx0ICAgIH1cblxuXHQgICAgaWYgKGlzUHJlc2VudC5jbGVhckltbWVkaWF0ZSkge1xuXHQgICAgICAgIHRpbWVycy5jbGVhckltbWVkaWF0ZSA9IF9nbG9iYWwuY2xlYXJJbW1lZGlhdGU7XG5cdCAgICB9XG5cblx0ICAgIGlmIChpc1ByZXNlbnQuaHJ0aW1lKSB7XG5cdCAgICAgICAgdGltZXJzLmhydGltZSA9IF9nbG9iYWwucHJvY2Vzcy5ocnRpbWU7XG5cdCAgICB9XG5cblx0ICAgIGlmIChpc1ByZXNlbnQubmV4dFRpY2spIHtcblx0ICAgICAgICB0aW1lcnMubmV4dFRpY2sgPSBfZ2xvYmFsLnByb2Nlc3MubmV4dFRpY2s7XG5cdCAgICB9XG5cblx0ICAgIGlmIChpc1ByZXNlbnQucGVyZm9ybWFuY2UpIHtcblx0ICAgICAgICB0aW1lcnMucGVyZm9ybWFuY2UgPSBfZ2xvYmFsLnBlcmZvcm1hbmNlO1xuXHQgICAgfVxuXG5cdCAgICBpZiAoaXNQcmVzZW50LnJlcXVlc3RBbmltYXRpb25GcmFtZSkge1xuXHQgICAgICAgIHRpbWVycy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUgPSBfZ2xvYmFsLnJlcXVlc3RBbmltYXRpb25GcmFtZTtcblx0ICAgIH1cblxuXHQgICAgaWYgKGlzUHJlc2VudC5xdWV1ZU1pY3JvdGFzaykge1xuXHQgICAgICAgIHRpbWVycy5xdWV1ZU1pY3JvdGFzayA9IF9nbG9iYWwucXVldWVNaWNyb3Rhc2s7XG5cdCAgICB9XG5cblx0ICAgIGlmIChpc1ByZXNlbnQuY2FuY2VsQW5pbWF0aW9uRnJhbWUpIHtcblx0ICAgICAgICB0aW1lcnMuY2FuY2VsQW5pbWF0aW9uRnJhbWUgPSBfZ2xvYmFsLmNhbmNlbEFuaW1hdGlvbkZyYW1lO1xuXHQgICAgfVxuXG5cdCAgICBpZiAoaXNQcmVzZW50LnJlcXVlc3RJZGxlQ2FsbGJhY2spIHtcblx0ICAgICAgICB0aW1lcnMucmVxdWVzdElkbGVDYWxsYmFjayA9IF9nbG9iYWwucmVxdWVzdElkbGVDYWxsYmFjaztcblx0ICAgIH1cblxuXHQgICAgaWYgKGlzUHJlc2VudC5jYW5jZWxJZGxlQ2FsbGJhY2spIHtcblx0ICAgICAgICB0aW1lcnMuY2FuY2VsSWRsZUNhbGxiYWNrID0gX2dsb2JhbC5jYW5jZWxJZGxlQ2FsbGJhY2s7XG5cdCAgICB9XG5cblx0ICAgIGlmIChpc1ByZXNlbnQuSW50bCkge1xuXHQgICAgICAgIHRpbWVycy5JbnRsID0gTmF0aXZlSW50bDtcblx0ICAgIH1cblxuXHQgICAgY29uc3Qgb3JpZ2luYWxTZXRUaW1lb3V0ID0gX2dsb2JhbC5zZXRJbW1lZGlhdGUgfHwgX2dsb2JhbC5zZXRUaW1lb3V0O1xuXHQgICAgY29uc3Qgb3JpZ2luYWxDbGVhckludGVydmFsID0gX2dsb2JhbC5jbGVhckludGVydmFsO1xuXHQgICAgY29uc3Qgb3JpZ2luYWxTZXRJbnRlcnZhbCA9IF9nbG9iYWwuc2V0SW50ZXJ2YWw7XG5cblx0ICAgIC8qKlxuXHQgICAgICogQHBhcmFtIHtEYXRlfG51bWJlcn0gW3N0YXJ0XSB0aGUgc3lzdGVtIHRpbWUgLSBub24taW50ZWdlciB2YWx1ZXMgYXJlIGZsb29yZWRcblx0ICAgICAqIEBwYXJhbSB7bnVtYmVyfSBbbG9vcExpbWl0XSBtYXhpbXVtIG51bWJlciBvZiB0aW1lcnMgdGhhdCB3aWxsIGJlIHJ1biB3aGVuIGNhbGxpbmcgcnVuQWxsKClcblx0ICAgICAqIEByZXR1cm5zIHtDbG9ja31cblx0ICAgICAqL1xuXHQgICAgZnVuY3Rpb24gY3JlYXRlQ2xvY2soc3RhcnQsIGxvb3BMaW1pdCkge1xuXHQgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1wYXJhbS1yZWFzc2lnblxuXHQgICAgICAgIHN0YXJ0ID0gTWF0aC5mbG9vcihnZXRFcG9jaChzdGFydCkpO1xuXHQgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1wYXJhbS1yZWFzc2lnblxuXHQgICAgICAgIGxvb3BMaW1pdCA9IGxvb3BMaW1pdCB8fCAxMDAwO1xuXHQgICAgICAgIGxldCBuYW5vcyA9IDA7XG5cdCAgICAgICAgY29uc3QgYWRqdXN0ZWRTeXN0ZW1UaW1lID0gWzAsIDBdOyAvLyBbbWlsbGlzLCBuYW5vcmVtYWluZGVyXVxuXG5cdCAgICAgICAgY29uc3QgY2xvY2sgPSB7XG5cdCAgICAgICAgICAgIG5vdzogc3RhcnQsXG5cdCAgICAgICAgICAgIERhdGU6IGNyZWF0ZURhdGUoKSxcblx0ICAgICAgICAgICAgbG9vcExpbWl0OiBsb29wTGltaXQsXG5cdCAgICAgICAgICAgIHRpY2tNb2RlOiB7IG1vZGU6IFwibWFudWFsXCIsIGNvdW50ZXI6IDAsIGRlbHRhOiB1bmRlZmluZWQgfSxcblx0ICAgICAgICB9O1xuXG5cdCAgICAgICAgY2xvY2suRGF0ZS5jbG9jayA9IGNsb2NrO1xuXG5cdCAgICAgICAgLy9lc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUganNkb2MvcmVxdWlyZS1qc2RvY1xuXHQgICAgICAgIGZ1bmN0aW9uIGdldFRpbWVUb05leHRGcmFtZSgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIDE2IC0gKChjbG9jay5ub3cgLSBzdGFydCkgJSAxNik7XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgLy9lc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUganNkb2MvcmVxdWlyZS1qc2RvY1xuXHQgICAgICAgIGZ1bmN0aW9uIGhydGltZShwcmV2KSB7XG5cdCAgICAgICAgICAgIGNvbnN0IG1pbGxpc1NpbmNlU3RhcnQgPSBjbG9jay5ub3cgLSBhZGp1c3RlZFN5c3RlbVRpbWVbMF0gLSBzdGFydDtcblx0ICAgICAgICAgICAgY29uc3Qgc2Vjc1NpbmNlU3RhcnQgPSBNYXRoLmZsb29yKG1pbGxpc1NpbmNlU3RhcnQgLyAxMDAwKTtcblx0ICAgICAgICAgICAgY29uc3QgcmVtYWluZGVySW5OYW5vcyA9XG5cdCAgICAgICAgICAgICAgICAobWlsbGlzU2luY2VTdGFydCAtIHNlY3NTaW5jZVN0YXJ0ICogMWUzKSAqIDFlNiArXG5cdCAgICAgICAgICAgICAgICBuYW5vcyAtXG5cdCAgICAgICAgICAgICAgICBhZGp1c3RlZFN5c3RlbVRpbWVbMV07XG5cblx0ICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkocHJldikpIHtcblx0ICAgICAgICAgICAgICAgIGlmIChwcmV2WzFdID4gMWU5KSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcblx0ICAgICAgICAgICAgICAgICAgICAgICAgXCJOdW1iZXIgb2YgbmFub3NlY29uZHMgY2FuJ3QgZXhjZWVkIGEgYmlsbGlvblwiLFxuXHQgICAgICAgICAgICAgICAgICAgICk7XG5cdCAgICAgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgICAgIGNvbnN0IG9sZFNlY3MgPSBwcmV2WzBdO1xuXHQgICAgICAgICAgICAgICAgbGV0IG5hbm9EaWZmID0gcmVtYWluZGVySW5OYW5vcyAtIHByZXZbMV07XG5cdCAgICAgICAgICAgICAgICBsZXQgc2VjRGlmZiA9IHNlY3NTaW5jZVN0YXJ0IC0gb2xkU2VjcztcblxuXHQgICAgICAgICAgICAgICAgaWYgKG5hbm9EaWZmIDwgMCkge1xuXHQgICAgICAgICAgICAgICAgICAgIG5hbm9EaWZmICs9IDFlOTtcblx0ICAgICAgICAgICAgICAgICAgICBzZWNEaWZmIC09IDE7XG5cdCAgICAgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgICAgIHJldHVybiBbc2VjRGlmZiwgbmFub0RpZmZdO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIHJldHVybiBbc2Vjc1NpbmNlU3RhcnQsIHJlbWFpbmRlckluTmFub3NdO1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIEEgaGlnaCByZXNvbHV0aW9uIHRpbWVzdGFtcCBpbiBtaWxsaXNlY29uZHMuXG5cdCAgICAgICAgICogQHR5cGVkZWYge251bWJlcn0gRE9NSGlnaFJlc1RpbWVTdGFtcFxuXHQgICAgICAgICAqL1xuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogcGVyZm9ybWFuY2Uubm93KClcblx0ICAgICAgICAgKiBAcmV0dXJucyB7RE9NSGlnaFJlc1RpbWVTdGFtcH1cblx0ICAgICAgICAgKi9cblx0ICAgICAgICBmdW5jdGlvbiBmYWtlUGVyZm9ybWFuY2VOb3coKSB7XG5cdCAgICAgICAgICAgIGNvbnN0IGhydCA9IGhydGltZSgpO1xuXHQgICAgICAgICAgICBjb25zdCBtaWxsaXMgPSBocnRbMF0gKiAxMDAwICsgaHJ0WzFdIC8gMWU2O1xuXHQgICAgICAgICAgICByZXR1cm4gbWlsbGlzO1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIGlmIChpc1ByZXNlbnQuaHJ0aW1lQmlnaW50KSB7XG5cdCAgICAgICAgICAgIGhydGltZS5iaWdpbnQgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgICAgICBjb25zdCBwYXJ0cyA9IGhydGltZSgpO1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIEJpZ0ludChwYXJ0c1swXSkgKiBCaWdJbnQoMWU5KSArIEJpZ0ludChwYXJ0c1sxXSk7IC8vIGVzbGludC1kaXNhYmxlLWxpbmVcblx0ICAgICAgICAgICAgfTtcblx0ICAgICAgICB9XG5cblx0ICAgICAgICBpZiAoaXNQcmVzZW50LkludGwpIHtcblx0ICAgICAgICAgICAgY2xvY2suSW50bCA9IGNyZWF0ZUludGwoKTtcblx0ICAgICAgICAgICAgY2xvY2suSW50bC5jbG9jayA9IGNsb2NrO1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIEBwYXJhbSB7VGltZXJUaWNrTW9kZX0gdGlja01vZGVDb25maWcgLSBUaGUgbmV3IGNvbmZpZ3VyYXRpb24gZm9yIGhvdyB0aGUgY2xvY2sgc2hvdWxkIHRpY2suXG5cdCAgICAgICAgICovXG5cdCAgICAgICAgY2xvY2suc2V0VGlja01vZGUgPSBmdW5jdGlvbiAodGlja01vZGVDb25maWcpIHtcblx0ICAgICAgICAgICAgY29uc3QgeyBtb2RlOiBuZXdNb2RlLCBkZWx0YTogbmV3RGVsdGEgfSA9IHRpY2tNb2RlQ29uZmlnO1xuXHQgICAgICAgICAgICBjb25zdCB7IG1vZGU6IG9sZE1vZGUsIGRlbHRhOiBvbGREZWx0YSB9ID0gY2xvY2sudGlja01vZGU7XG5cdCAgICAgICAgICAgIGlmIChuZXdNb2RlID09PSBvbGRNb2RlICYmIG5ld0RlbHRhID09PSBvbGREZWx0YSkge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuO1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgaWYgKG9sZE1vZGUgPT09IFwiaW50ZXJ2YWxcIikge1xuXHQgICAgICAgICAgICAgICAgb3JpZ2luYWxDbGVhckludGVydmFsKGNsb2NrLmF0dGFjaGVkSW50ZXJ2YWwpO1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgY2xvY2sudGlja01vZGUgPSB7XG5cdCAgICAgICAgICAgICAgICBjb3VudGVyOiBjbG9jay50aWNrTW9kZS5jb3VudGVyICsgMSxcblx0ICAgICAgICAgICAgICAgIG1vZGU6IG5ld01vZGUsXG5cdCAgICAgICAgICAgICAgICBkZWx0YTogbmV3RGVsdGEsXG5cdCAgICAgICAgICAgIH07XG5cblx0ICAgICAgICAgICAgaWYgKG5ld01vZGUgPT09IFwibmV4dEFzeW5jXCIpIHtcblx0ICAgICAgICAgICAgICAgIGFkdmFuY2VVbnRpbE1vZGVDaGFuZ2VzKCk7XG5cdCAgICAgICAgICAgIH0gZWxzZSBpZiAobmV3TW9kZSA9PT0gXCJpbnRlcnZhbFwiKSB7XG5cdCAgICAgICAgICAgICAgICBjcmVhdGVJbnRlcnZhbFRpY2soY2xvY2ssIG5ld0RlbHRhIHx8IDIwKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH07XG5cblx0ICAgICAgICBhc3luYyBmdW5jdGlvbiBhZHZhbmNlVW50aWxNb2RlQ2hhbmdlcygpIHtcblx0ICAgICAgICAgICAgYXN5bmMgZnVuY3Rpb24gbmV3TWFjcm90YXNrKCkge1xuXHQgICAgICAgICAgICAgICAgLy8gTWVzc2FnZUNoYW5uZWwgZW5zdXJlcyB0aGF0IHNldFRpbWVvdXQgaXMgbm90IHRocm90dGxlZCB0byA0bXMuXG5cdCAgICAgICAgICAgICAgICAvLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvc2V0VGltZW91dCNyZWFzb25zX2Zvcl9kZWxheXNfbG9uZ2VyX3RoYW5fc3BlY2lmaWVkXG5cdCAgICAgICAgICAgICAgICAvLyBodHRwczovL3N0YWNrYmxpdHouY29tL2VkaXQvc3RhY2tibGl0ei1zdGFydGVycy1xdGxwY2Ncblx0ICAgICAgICAgICAgICAgIGNvbnN0IGNoYW5uZWwgPSBuZXcgTWVzc2FnZUNoYW5uZWwoKTtcblx0ICAgICAgICAgICAgICAgIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG5cdCAgICAgICAgICAgICAgICAgICAgY2hhbm5lbC5wb3J0MS5vbm1lc3NhZ2UgPSAoKSA9PiB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgY2hhbm5lbC5wb3J0MS5jbG9zZSgpO1xuXHQgICAgICAgICAgICAgICAgICAgIH07XG5cdCAgICAgICAgICAgICAgICAgICAgY2hhbm5lbC5wb3J0Mi5wb3N0TWVzc2FnZSh1bmRlZmluZWQpO1xuXHQgICAgICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgICAgICAgICBjaGFubmVsLnBvcnQxLmNsb3NlKCk7XG5cdCAgICAgICAgICAgICAgICBjaGFubmVsLnBvcnQyLmNsb3NlKCk7XG5cdCAgICAgICAgICAgICAgICAvLyBzZXRUaW1lb3V0IGVuc3VyZXMgbWljcm90YXNrIHF1ZXVlIGlzIGVtcHRpZWRcblx0ICAgICAgICAgICAgICAgIGF3YWl0IG5ldyBQcm9taXNlKChyZXNvbHZlKSA9PiB7XG5cdCAgICAgICAgICAgICAgICAgICAgb3JpZ2luYWxTZXRUaW1lb3V0KHJlc29sdmUpO1xuXHQgICAgICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICBjb25zdCB7IGNvdW50ZXIgfSA9IGNsb2NrLnRpY2tNb2RlO1xuXHQgICAgICAgICAgICB3aGlsZSAoY2xvY2sudGlja01vZGUuY291bnRlciA9PT0gY291bnRlcikge1xuXHQgICAgICAgICAgICAgICAgYXdhaXQgbmV3TWFjcm90YXNrKCk7XG5cdCAgICAgICAgICAgICAgICBpZiAoY2xvY2sudGlja01vZGUuY291bnRlciAhPT0gY291bnRlcikge1xuXHQgICAgICAgICAgICAgICAgICAgIHJldHVybjtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIGNsb2NrLm5leHQoKTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblxuXHQgICAgICAgIGZ1bmN0aW9uIHBhdXNlQXV0b1RpY2tVbnRpbEZpbmlzaGVkKHByb21pc2UpIHtcblx0ICAgICAgICAgICAgaWYgKGNsb2NrLnRpY2tNb2RlLm1vZGUgIT09IFwibmV4dEFzeW5jXCIpIHtcblx0ICAgICAgICAgICAgICAgIHJldHVybiBwcm9taXNlO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGNsb2NrLnNldFRpY2tNb2RlKHsgbW9kZTogXCJtYW51YWxcIiB9KTtcblx0ICAgICAgICAgICAgcmV0dXJuIHByb21pc2UuZmluYWxseSgoKSA9PiB7XG5cdCAgICAgICAgICAgICAgICBjbG9jay5zZXRUaWNrTW9kZSh7IG1vZGU6IFwibmV4dEFzeW5jXCIgfSk7XG5cdCAgICAgICAgICAgIH0pO1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIGNsb2NrLnJlcXVlc3RJZGxlQ2FsbGJhY2sgPSBmdW5jdGlvbiByZXF1ZXN0SWRsZUNhbGxiYWNrKFxuXHQgICAgICAgICAgICBmdW5jLFxuXHQgICAgICAgICAgICB0aW1lb3V0LFxuXHQgICAgICAgICkge1xuXHQgICAgICAgICAgICBsZXQgdGltZVRvTmV4dElkbGVQZXJpb2QgPSAwO1xuXG5cdCAgICAgICAgICAgIGlmIChjbG9jay5jb3VudFRpbWVycygpID4gMCkge1xuXHQgICAgICAgICAgICAgICAgdGltZVRvTmV4dElkbGVQZXJpb2QgPSA1MDsgLy8gY29uc3QgZm9yIG5vd1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYWRkVGltZXIoY2xvY2ssIHtcblx0ICAgICAgICAgICAgICAgIGZ1bmM6IGZ1bmMsXG5cdCAgICAgICAgICAgICAgICBhcmdzOiBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDIpLFxuXHQgICAgICAgICAgICAgICAgZGVsYXk6XG5cdCAgICAgICAgICAgICAgICAgICAgdHlwZW9mIHRpbWVvdXQgPT09IFwidW5kZWZpbmVkXCJcblx0ICAgICAgICAgICAgICAgICAgICAgICAgPyB0aW1lVG9OZXh0SWRsZVBlcmlvZFxuXHQgICAgICAgICAgICAgICAgICAgICAgICA6IE1hdGgubWluKHRpbWVvdXQsIHRpbWVUb05leHRJZGxlUGVyaW9kKSxcblx0ICAgICAgICAgICAgICAgIGlkbGVDYWxsYmFjazogdHJ1ZSxcblx0ICAgICAgICAgICAgfSk7XG5cblx0ICAgICAgICAgICAgcmV0dXJuIE51bWJlcihyZXN1bHQpO1xuXHQgICAgICAgIH07XG5cblx0ICAgICAgICBjbG9jay5jYW5jZWxJZGxlQ2FsbGJhY2sgPSBmdW5jdGlvbiBjYW5jZWxJZGxlQ2FsbGJhY2sodGltZXJJZCkge1xuXHQgICAgICAgICAgICByZXR1cm4gY2xlYXJUaW1lcihjbG9jaywgdGltZXJJZCwgXCJJZGxlQ2FsbGJhY2tcIik7XG5cdCAgICAgICAgfTtcblxuXHQgICAgICAgIGNsb2NrLnNldFRpbWVvdXQgPSBmdW5jdGlvbiBzZXRUaW1lb3V0KGZ1bmMsIHRpbWVvdXQpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIGFkZFRpbWVyKGNsb2NrLCB7XG5cdCAgICAgICAgICAgICAgICBmdW5jOiBmdW5jLFxuXHQgICAgICAgICAgICAgICAgYXJnczogQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAyKSxcblx0ICAgICAgICAgICAgICAgIGRlbGF5OiB0aW1lb3V0LFxuXHQgICAgICAgICAgICB9KTtcblx0ICAgICAgICB9O1xuXHQgICAgICAgIGlmICh0eXBlb2YgX2dsb2JhbC5Qcm9taXNlICE9PSBcInVuZGVmaW5lZFwiICYmIHV0aWxQcm9taXNpZnkpIHtcblx0ICAgICAgICAgICAgY2xvY2suc2V0VGltZW91dFt1dGlsUHJvbWlzaWZ5LmN1c3RvbV0gPVxuXHQgICAgICAgICAgICAgICAgZnVuY3Rpb24gcHJvbWlzaWZpZWRTZXRUaW1lb3V0KHRpbWVvdXQsIGFyZykge1xuXHQgICAgICAgICAgICAgICAgICAgIHJldHVybiBuZXcgX2dsb2JhbC5Qcm9taXNlKGZ1bmN0aW9uIHNldFRpbWVvdXRFeGVjdXRvcihcblx0ICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSxcblx0ICAgICAgICAgICAgICAgICAgICApIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgYWRkVGltZXIoY2xvY2ssIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmM6IHJlc29sdmUsXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmdzOiBbYXJnXSxcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGF5OiB0aW1lb3V0LFxuXHQgICAgICAgICAgICAgICAgICAgICAgICB9KTtcblx0ICAgICAgICAgICAgICAgICAgICB9KTtcblx0ICAgICAgICAgICAgICAgIH07XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgY2xvY2suY2xlYXJUaW1lb3V0ID0gZnVuY3Rpb24gY2xlYXJUaW1lb3V0KHRpbWVySWQpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIGNsZWFyVGltZXIoY2xvY2ssIHRpbWVySWQsIFwiVGltZW91dFwiKTtcblx0ICAgICAgICB9O1xuXG5cdCAgICAgICAgY2xvY2submV4dFRpY2sgPSBmdW5jdGlvbiBuZXh0VGljayhmdW5jKSB7XG5cdCAgICAgICAgICAgIHJldHVybiBlbnF1ZXVlSm9iKGNsb2NrLCB7XG5cdCAgICAgICAgICAgICAgICBmdW5jOiBmdW5jLFxuXHQgICAgICAgICAgICAgICAgYXJnczogQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKSxcblx0ICAgICAgICAgICAgICAgIGVycm9yOiBpc05lYXJJbmZpbml0ZUxpbWl0ID8gbmV3IEVycm9yKCkgOiBudWxsLFxuXHQgICAgICAgICAgICB9KTtcblx0ICAgICAgICB9O1xuXG5cdCAgICAgICAgY2xvY2sucXVldWVNaWNyb3Rhc2sgPSBmdW5jdGlvbiBxdWV1ZU1pY3JvdGFzayhmdW5jKSB7XG5cdCAgICAgICAgICAgIHJldHVybiBjbG9jay5uZXh0VGljayhmdW5jKTsgLy8gZXhwbGljaXRseSBkcm9wIGFkZGl0aW9uYWwgYXJndW1lbnRzXG5cdCAgICAgICAgfTtcblxuXHQgICAgICAgIGNsb2NrLnNldEludGVydmFsID0gZnVuY3Rpb24gc2V0SW50ZXJ2YWwoZnVuYywgdGltZW91dCkge1xuXHQgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcGFyYW0tcmVhc3NpZ25cblx0ICAgICAgICAgICAgdGltZW91dCA9IHBhcnNlSW50KHRpbWVvdXQsIDEwKTtcblx0ICAgICAgICAgICAgcmV0dXJuIGFkZFRpbWVyKGNsb2NrLCB7XG5cdCAgICAgICAgICAgICAgICBmdW5jOiBmdW5jLFxuXHQgICAgICAgICAgICAgICAgYXJnczogQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAyKSxcblx0ICAgICAgICAgICAgICAgIGRlbGF5OiB0aW1lb3V0LFxuXHQgICAgICAgICAgICAgICAgaW50ZXJ2YWw6IHRpbWVvdXQsXG5cdCAgICAgICAgICAgIH0pO1xuXHQgICAgICAgIH07XG5cblx0ICAgICAgICBjbG9jay5jbGVhckludGVydmFsID0gZnVuY3Rpb24gY2xlYXJJbnRlcnZhbCh0aW1lcklkKSB7XG5cdCAgICAgICAgICAgIHJldHVybiBjbGVhclRpbWVyKGNsb2NrLCB0aW1lcklkLCBcIkludGVydmFsXCIpO1xuXHQgICAgICAgIH07XG5cblx0ICAgICAgICBpZiAoaXNQcmVzZW50LnNldEltbWVkaWF0ZSkge1xuXHQgICAgICAgICAgICBjbG9jay5zZXRJbW1lZGlhdGUgPSBmdW5jdGlvbiBzZXRJbW1lZGlhdGUoZnVuYykge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIGFkZFRpbWVyKGNsb2NrLCB7XG5cdCAgICAgICAgICAgICAgICAgICAgZnVuYzogZnVuYyxcblx0ICAgICAgICAgICAgICAgICAgICBhcmdzOiBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpLFxuXHQgICAgICAgICAgICAgICAgICAgIGltbWVkaWF0ZTogdHJ1ZSxcblx0ICAgICAgICAgICAgICAgIH0pO1xuXHQgICAgICAgICAgICB9O1xuXG5cdCAgICAgICAgICAgIGlmICh0eXBlb2YgX2dsb2JhbC5Qcm9taXNlICE9PSBcInVuZGVmaW5lZFwiICYmIHV0aWxQcm9taXNpZnkpIHtcblx0ICAgICAgICAgICAgICAgIGNsb2NrLnNldEltbWVkaWF0ZVt1dGlsUHJvbWlzaWZ5LmN1c3RvbV0gPVxuXHQgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHByb21pc2lmaWVkU2V0SW1tZWRpYXRlKGFyZykge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IF9nbG9iYWwuUHJvbWlzZShcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIHNldEltbWVkaWF0ZUV4ZWN1dG9yKHJlc29sdmUpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZGRUaW1lcihjbG9jaywge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jOiByZXNvbHZlLFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmdzOiBbYXJnXSxcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW1tZWRpYXRlOiB0cnVlLFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcblx0ICAgICAgICAgICAgICAgICAgICAgICAgKTtcblx0ICAgICAgICAgICAgICAgICAgICB9O1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgY2xvY2suY2xlYXJJbW1lZGlhdGUgPSBmdW5jdGlvbiBjbGVhckltbWVkaWF0ZSh0aW1lcklkKSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gY2xlYXJUaW1lcihjbG9jaywgdGltZXJJZCwgXCJJbW1lZGlhdGVcIik7XG5cdCAgICAgICAgICAgIH07XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgY2xvY2suY291bnRUaW1lcnMgPSBmdW5jdGlvbiBjb3VudFRpbWVycygpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIChcblx0ICAgICAgICAgICAgICAgIE9iamVjdC5rZXlzKGNsb2NrLnRpbWVycyB8fCB7fSkubGVuZ3RoICtcblx0ICAgICAgICAgICAgICAgIChjbG9jay5qb2JzIHx8IFtdKS5sZW5ndGhcblx0ICAgICAgICAgICAgKTtcblx0ICAgICAgICB9O1xuXG5cdCAgICAgICAgY2xvY2sucmVxdWVzdEFuaW1hdGlvbkZyYW1lID0gZnVuY3Rpb24gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKGZ1bmMpIHtcblx0ICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gYWRkVGltZXIoY2xvY2ssIHtcblx0ICAgICAgICAgICAgICAgIGZ1bmM6IGZ1bmMsXG5cdCAgICAgICAgICAgICAgICBkZWxheTogZ2V0VGltZVRvTmV4dEZyYW1lKCksXG5cdCAgICAgICAgICAgICAgICBnZXQgYXJncygpIHtcblx0ICAgICAgICAgICAgICAgICAgICByZXR1cm4gW2Zha2VQZXJmb3JtYW5jZU5vdygpXTtcblx0ICAgICAgICAgICAgICAgIH0sXG5cdCAgICAgICAgICAgICAgICBhbmltYXRpb246IHRydWUsXG5cdCAgICAgICAgICAgIH0pO1xuXG5cdCAgICAgICAgICAgIHJldHVybiBOdW1iZXIocmVzdWx0KTtcblx0ICAgICAgICB9O1xuXG5cdCAgICAgICAgY2xvY2suY2FuY2VsQW5pbWF0aW9uRnJhbWUgPSBmdW5jdGlvbiBjYW5jZWxBbmltYXRpb25GcmFtZSh0aW1lcklkKSB7XG5cdCAgICAgICAgICAgIHJldHVybiBjbGVhclRpbWVyKGNsb2NrLCB0aW1lcklkLCBcIkFuaW1hdGlvbkZyYW1lXCIpO1xuXHQgICAgICAgIH07XG5cblx0ICAgICAgICBjbG9jay5ydW5NaWNyb3Rhc2tzID0gZnVuY3Rpb24gcnVuTWljcm90YXNrcygpIHtcblx0ICAgICAgICAgICAgcnVuSm9icyhjbG9jayk7XG5cdCAgICAgICAgfTtcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIEBwYXJhbSB7bnVtYmVyfHN0cmluZ30gdGlja1ZhbHVlIG1pbGxpc2Vjb25kcyBvciBhIHN0cmluZyBwYXJzZWFibGUgYnkgcGFyc2VUaW1lXG5cdCAgICAgICAgICogQHBhcmFtIHtib29sZWFufSBpc0FzeW5jXG5cdCAgICAgICAgICogQHBhcmFtIHtGdW5jdGlvbn0gcmVzb2x2ZVxuXHQgICAgICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHJlamVjdFxuXHQgICAgICAgICAqIEByZXR1cm5zIHtudW1iZXJ8dW5kZWZpbmVkfSB3aWxsIHJldHVybiB0aGUgbmV3IGBub3dgIHZhbHVlIG9yIG5vdGhpbmcgZm9yIGFzeW5jXG5cdCAgICAgICAgICovXG5cdCAgICAgICAgZnVuY3Rpb24gZG9UaWNrKHRpY2tWYWx1ZSwgaXNBc3luYywgcmVzb2x2ZSwgcmVqZWN0KSB7XG5cdCAgICAgICAgICAgIGNvbnN0IG1zRmxvYXQgPVxuXHQgICAgICAgICAgICAgICAgdHlwZW9mIHRpY2tWYWx1ZSA9PT0gXCJudW1iZXJcIlxuXHQgICAgICAgICAgICAgICAgICAgID8gdGlja1ZhbHVlXG5cdCAgICAgICAgICAgICAgICAgICAgOiBwYXJzZVRpbWUodGlja1ZhbHVlKTtcblx0ICAgICAgICAgICAgY29uc3QgbXMgPSBNYXRoLmZsb29yKG1zRmxvYXQpO1xuXHQgICAgICAgICAgICBjb25zdCByZW1haW5kZXIgPSBuYW5vUmVtYWluZGVyKG1zRmxvYXQpO1xuXHQgICAgICAgICAgICBsZXQgbmFub3NUb3RhbCA9IG5hbm9zICsgcmVtYWluZGVyO1xuXHQgICAgICAgICAgICBsZXQgdGlja1RvID0gY2xvY2subm93ICsgbXM7XG5cblx0ICAgICAgICAgICAgaWYgKG1zRmxvYXQgPCAwKSB7XG5cdCAgICAgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiTmVnYXRpdmUgdGlja3MgYXJlIG5vdCBzdXBwb3J0ZWRcIik7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAvLyBhZGp1c3QgZm9yIHBvc2l0aXZlIG92ZXJmbG93XG5cdCAgICAgICAgICAgIGlmIChuYW5vc1RvdGFsID49IDFlNikge1xuXHQgICAgICAgICAgICAgICAgdGlja1RvICs9IDE7XG5cdCAgICAgICAgICAgICAgICBuYW5vc1RvdGFsIC09IDFlNjtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIG5hbm9zID0gbmFub3NUb3RhbDtcblx0ICAgICAgICAgICAgbGV0IHRpY2tGcm9tID0gY2xvY2subm93O1xuXHQgICAgICAgICAgICBsZXQgcHJldmlvdXMgPSBjbG9jay5ub3c7XG5cdCAgICAgICAgICAgIC8vIEVTTGludCBmYWlscyB0byBkZXRlY3QgdGhpcyBjb3JyZWN0bHlcblx0ICAgICAgICAgICAgLyogZXNsaW50LWRpc2FibGUgcHJlZmVyLWNvbnN0ICovXG5cdCAgICAgICAgICAgIGxldCB0aW1lcixcblx0ICAgICAgICAgICAgICAgIGZpcnN0RXhjZXB0aW9uLFxuXHQgICAgICAgICAgICAgICAgb2xkTm93LFxuXHQgICAgICAgICAgICAgICAgbmV4dFByb21pc2VUaWNrLFxuXHQgICAgICAgICAgICAgICAgY29tcGVuc2F0aW9uQ2hlY2ssXG5cdCAgICAgICAgICAgICAgICBwb3N0VGltZXJDYWxsO1xuXHQgICAgICAgICAgICAvKiBlc2xpbnQtZW5hYmxlIHByZWZlci1jb25zdCAqL1xuXG5cdCAgICAgICAgICAgIGNsb2NrLmR1cmluZ1RpY2sgPSB0cnVlO1xuXG5cdCAgICAgICAgICAgIC8vIHBlcmZvcm0gbWljcm90YXNrc1xuXHQgICAgICAgICAgICBvbGROb3cgPSBjbG9jay5ub3c7XG5cdCAgICAgICAgICAgIHJ1bkpvYnMoY2xvY2spO1xuXHQgICAgICAgICAgICBpZiAob2xkTm93ICE9PSBjbG9jay5ub3cpIHtcblx0ICAgICAgICAgICAgICAgIC8vIGNvbXBlbnNhdGUgZm9yIGFueSBzZXRTeXN0ZW1UaW1lKCkgY2FsbCBkdXJpbmcgbWljcm90YXNrIGNhbGxiYWNrXG5cdCAgICAgICAgICAgICAgICB0aWNrRnJvbSArPSBjbG9jay5ub3cgLSBvbGROb3c7XG5cdCAgICAgICAgICAgICAgICB0aWNrVG8gKz0gY2xvY2subm93IC0gb2xkTm93O1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgLy9lc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUganNkb2MvcmVxdWlyZS1qc2RvY1xuXHQgICAgICAgICAgICBmdW5jdGlvbiBkb1RpY2tJbm5lcigpIHtcblx0ICAgICAgICAgICAgICAgIC8vIHBlcmZvcm0gZWFjaCB0aW1lciBpbiB0aGUgcmVxdWVzdGVkIHJhbmdlXG5cdCAgICAgICAgICAgICAgICB0aW1lciA9IGZpcnN0VGltZXJJblJhbmdlKGNsb2NrLCB0aWNrRnJvbSwgdGlja1RvKTtcblx0ICAgICAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bm1vZGlmaWVkLWxvb3AtY29uZGl0aW9uXG5cdCAgICAgICAgICAgICAgICB3aGlsZSAodGltZXIgJiYgdGlja0Zyb20gPD0gdGlja1RvKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgaWYgKGNsb2NrLnRpbWVyc1t0aW1lci5pZF0pIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgdGlja0Zyb20gPSB0aW1lci5jYWxsQXQ7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIGNsb2NrLm5vdyA9IHRpbWVyLmNhbGxBdDtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgb2xkTm93ID0gY2xvY2subm93O1xuXHQgICAgICAgICAgICAgICAgICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgcnVuSm9icyhjbG9jayk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsVGltZXIoY2xvY2ssIHRpbWVyKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlyc3RFeGNlcHRpb24gPSBmaXJzdEV4Y2VwdGlvbiB8fCBlO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzQXN5bmMpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZpbmlzaCB1cCBhZnRlciBuYXRpdmUgc2V0SW1tZWRpYXRlIGNhbGxiYWNrIHRvIGFsbG93XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBhbGwgbmF0aXZlIGVzNiBwcm9taXNlcyB0byBwcm9jZXNzIHRoZWlyIGNhbGxiYWNrcyBhZnRlclxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZWFjaCB0aW1lciBmaXJlcy5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yaWdpbmFsU2V0VGltZW91dChuZXh0UHJvbWlzZVRpY2spO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgY29tcGVuc2F0aW9uQ2hlY2soKTtcblx0ICAgICAgICAgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgICAgICAgICBwb3N0VGltZXJDYWxsKCk7XG5cdCAgICAgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgICAgIC8vIHBlcmZvcm0gcHJvY2Vzcy5uZXh0VGljaygpcyBhZ2FpblxuXHQgICAgICAgICAgICAgICAgb2xkTm93ID0gY2xvY2subm93O1xuXHQgICAgICAgICAgICAgICAgcnVuSm9icyhjbG9jayk7XG5cdCAgICAgICAgICAgICAgICBpZiAob2xkTm93ICE9PSBjbG9jay5ub3cpIHtcblx0ICAgICAgICAgICAgICAgICAgICAvLyBjb21wZW5zYXRlIGZvciBhbnkgc2V0U3lzdGVtVGltZSgpIGNhbGwgZHVyaW5nIHByb2Nlc3MubmV4dFRpY2soKSBjYWxsYmFja1xuXHQgICAgICAgICAgICAgICAgICAgIHRpY2tGcm9tICs9IGNsb2NrLm5vdyAtIG9sZE5vdztcblx0ICAgICAgICAgICAgICAgICAgICB0aWNrVG8gKz0gY2xvY2subm93IC0gb2xkTm93O1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgY2xvY2suZHVyaW5nVGljayA9IGZhbHNlO1xuXG5cdCAgICAgICAgICAgICAgICAvLyBjb3JuZXIgY2FzZTogZHVyaW5nIHJ1bkpvYnMgbmV3IHRpbWVycyB3ZXJlIHNjaGVkdWxlZCB3aGljaCBjb3VsZCBiZSBpbiB0aGUgcmFuZ2UgW2Nsb2NrLm5vdywgdGlja1RvXVxuXHQgICAgICAgICAgICAgICAgdGltZXIgPSBmaXJzdFRpbWVySW5SYW5nZShjbG9jaywgdGlja0Zyb20sIHRpY2tUbyk7XG5cdCAgICAgICAgICAgICAgICBpZiAodGltZXIpIHtcblx0ICAgICAgICAgICAgICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICBjbG9jay50aWNrKHRpY2tUbyAtIGNsb2NrLm5vdyk7IC8vIGRvIGl0IGFsbCBhZ2FpbiAtIGZvciB0aGUgcmVtYWluZGVyIG9mIHRoZSByZXF1ZXN0ZWQgcmFuZ2Vcblx0ICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIGZpcnN0RXhjZXB0aW9uID0gZmlyc3RFeGNlcHRpb24gfHwgZTtcblx0ICAgICAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgICAgIC8vIG5vIHRpbWVycyByZW1haW5pbmcgaW4gdGhlIHJlcXVlc3RlZCByYW5nZTogbW92ZSB0aGUgY2xvY2sgYWxsIHRoZSB3YXkgdG8gdGhlIGVuZFxuXHQgICAgICAgICAgICAgICAgICAgIGNsb2NrLm5vdyA9IHRpY2tUbztcblxuXHQgICAgICAgICAgICAgICAgICAgIC8vIHVwZGF0ZSBuYW5vc1xuXHQgICAgICAgICAgICAgICAgICAgIG5hbm9zID0gbmFub3NUb3RhbDtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIGlmIChmaXJzdEV4Y2VwdGlvbikge1xuXHQgICAgICAgICAgICAgICAgICAgIHRocm93IGZpcnN0RXhjZXB0aW9uO1xuXHQgICAgICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgICAgICBpZiAoaXNBc3luYykge1xuXHQgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoY2xvY2subm93KTtcblx0ICAgICAgICAgICAgICAgIH0gZWxzZSB7XG5cdCAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGNsb2NrLm5vdztcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIG5leHRQcm9taXNlVGljayA9XG5cdCAgICAgICAgICAgICAgICBpc0FzeW5jICYmXG5cdCAgICAgICAgICAgICAgICBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgY29tcGVuc2F0aW9uQ2hlY2soKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgcG9zdFRpbWVyQ2FsbCgpO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICBkb1RpY2tJbm5lcigpO1xuXHQgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGUpO1xuXHQgICAgICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIH07XG5cblx0ICAgICAgICAgICAgY29tcGVuc2F0aW9uQ2hlY2sgPSBmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgICAgICAvLyBjb21wZW5zYXRlIGZvciBhbnkgc2V0U3lzdGVtVGltZSgpIGNhbGwgZHVyaW5nIHRpbWVyIGNhbGxiYWNrXG5cdCAgICAgICAgICAgICAgICBpZiAob2xkTm93ICE9PSBjbG9jay5ub3cpIHtcblx0ICAgICAgICAgICAgICAgICAgICB0aWNrRnJvbSArPSBjbG9jay5ub3cgLSBvbGROb3c7XG5cdCAgICAgICAgICAgICAgICAgICAgdGlja1RvICs9IGNsb2NrLm5vdyAtIG9sZE5vdztcblx0ICAgICAgICAgICAgICAgICAgICBwcmV2aW91cyArPSBjbG9jay5ub3cgLSBvbGROb3c7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH07XG5cblx0ICAgICAgICAgICAgcG9zdFRpbWVyQ2FsbCA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgICAgIHRpbWVyID0gZmlyc3RUaW1lckluUmFuZ2UoY2xvY2ssIHByZXZpb3VzLCB0aWNrVG8pO1xuXHQgICAgICAgICAgICAgICAgcHJldmlvdXMgPSB0aWNrRnJvbTtcblx0ICAgICAgICAgICAgfTtcblxuXHQgICAgICAgICAgICByZXR1cm4gZG9UaWNrSW5uZXIoKTtcblx0ICAgICAgICB9XG5cblx0ICAgICAgICAvKipcblx0ICAgICAgICAgKiBAcGFyYW0ge3N0cmluZ3xudW1iZXJ9IHRpY2tWYWx1ZSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIG9yIGEgaHVtYW4tcmVhZGFibGUgdmFsdWUgbGlrZSBcIjAxOjExOjE1XCJcblx0ICAgICAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSB3aWxsIHJldHVybiB0aGUgbmV3IGBub3dgIHZhbHVlXG5cdCAgICAgICAgICovXG5cdCAgICAgICAgY2xvY2sudGljayA9IGZ1bmN0aW9uIHRpY2sodGlja1ZhbHVlKSB7XG5cdCAgICAgICAgICAgIHJldHVybiBkb1RpY2sodGlja1ZhbHVlLCBmYWxzZSk7XG5cdCAgICAgICAgfTtcblxuXHQgICAgICAgIGlmICh0eXBlb2YgX2dsb2JhbC5Qcm9taXNlICE9PSBcInVuZGVmaW5lZFwiKSB7XG5cdCAgICAgICAgICAgIC8qKlxuXHQgICAgICAgICAgICAgKiBAcGFyYW0ge3N0cmluZ3xudW1iZXJ9IHRpY2tWYWx1ZSBudW1iZXIgb2YgbWlsbGlzZWNvbmRzIG9yIGEgaHVtYW4tcmVhZGFibGUgdmFsdWUgbGlrZSBcIjAxOjExOjE1XCJcblx0ICAgICAgICAgICAgICogQHJldHVybnMge1Byb21pc2V9XG5cdCAgICAgICAgICAgICAqL1xuXHQgICAgICAgICAgICBjbG9jay50aWNrQXN5bmMgPSBmdW5jdGlvbiB0aWNrQXN5bmModGlja1ZhbHVlKSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gcGF1c2VBdXRvVGlja1VudGlsRmluaXNoZWQoXG5cdCAgICAgICAgICAgICAgICAgICAgbmV3IF9nbG9iYWwuUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIG9yaWdpbmFsU2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvVGljayh0aWNrVmFsdWUsIHRydWUsIHJlc29sdmUsIHJlamVjdCk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGUpO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgICAgICAgICB9KTtcblx0ICAgICAgICAgICAgICAgICAgICB9KSxcblx0ICAgICAgICAgICAgICAgICk7XG5cdCAgICAgICAgICAgIH07XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgY2xvY2submV4dCA9IGZ1bmN0aW9uIG5leHQoKSB7XG5cdCAgICAgICAgICAgIHJ1bkpvYnMoY2xvY2spO1xuXHQgICAgICAgICAgICBjb25zdCB0aW1lciA9IGZpcnN0VGltZXIoY2xvY2spO1xuXHQgICAgICAgICAgICBpZiAoIXRpbWVyKSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gY2xvY2subm93O1xuXHQgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgY2xvY2suZHVyaW5nVGljayA9IHRydWU7XG5cdCAgICAgICAgICAgIHRyeSB7XG5cdCAgICAgICAgICAgICAgICBjbG9jay5ub3cgPSB0aW1lci5jYWxsQXQ7XG5cdCAgICAgICAgICAgICAgICBjYWxsVGltZXIoY2xvY2ssIHRpbWVyKTtcblx0ICAgICAgICAgICAgICAgIHJ1bkpvYnMoY2xvY2spO1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIGNsb2NrLm5vdztcblx0ICAgICAgICAgICAgfSBmaW5hbGx5IHtcblx0ICAgICAgICAgICAgICAgIGNsb2NrLmR1cmluZ1RpY2sgPSBmYWxzZTtcblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH07XG5cblx0ICAgICAgICBpZiAodHlwZW9mIF9nbG9iYWwuUHJvbWlzZSAhPT0gXCJ1bmRlZmluZWRcIikge1xuXHQgICAgICAgICAgICBjbG9jay5uZXh0QXN5bmMgPSBmdW5jdGlvbiBuZXh0QXN5bmMoKSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gcGF1c2VBdXRvVGlja1VudGlsRmluaXNoZWQoXG5cdCAgICAgICAgICAgICAgICAgICAgbmV3IF9nbG9iYWwuUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIG9yaWdpbmFsU2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHRpbWVyID0gZmlyc3RUaW1lcihjbG9jayk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF0aW1lcikge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKGNsb2NrLm5vdyk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgZXJyO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsb2NrLmR1cmluZ1RpY2sgPSB0cnVlO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsb2NrLm5vdyA9IHRpbWVyLmNhbGxBdDtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cnkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsVGltZXIoY2xvY2ssIHRpbWVyKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVyciA9IGU7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsb2NrLmR1cmluZ1RpY2sgPSBmYWxzZTtcblxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yaWdpbmFsU2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnIpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChlcnIpO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShjbG9jay5ub3cpO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGUpO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgICAgICAgICB9KTtcblx0ICAgICAgICAgICAgICAgICAgICB9KSxcblx0ICAgICAgICAgICAgICAgICk7XG5cdCAgICAgICAgICAgIH07XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgY2xvY2sucnVuQWxsID0gZnVuY3Rpb24gcnVuQWxsKCkge1xuXHQgICAgICAgICAgICBsZXQgbnVtVGltZXJzLCBpO1xuXHQgICAgICAgICAgICBydW5Kb2JzKGNsb2NrKTtcblx0ICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGNsb2NrLmxvb3BMaW1pdDsgaSsrKSB7XG5cdCAgICAgICAgICAgICAgICBpZiAoIWNsb2NrLnRpbWVycykge1xuXHQgICAgICAgICAgICAgICAgICAgIHJlc2V0SXNOZWFySW5maW5pdGVMaW1pdCgpO1xuXHQgICAgICAgICAgICAgICAgICAgIHJldHVybiBjbG9jay5ub3c7XG5cdCAgICAgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgICAgIG51bVRpbWVycyA9IE9iamVjdC5rZXlzKGNsb2NrLnRpbWVycykubGVuZ3RoO1xuXHQgICAgICAgICAgICAgICAgaWYgKG51bVRpbWVycyA9PT0gMCkge1xuXHQgICAgICAgICAgICAgICAgICAgIHJlc2V0SXNOZWFySW5maW5pdGVMaW1pdCgpO1xuXHQgICAgICAgICAgICAgICAgICAgIHJldHVybiBjbG9jay5ub3c7XG5cdCAgICAgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgICAgIGNsb2NrLm5leHQoKTtcblx0ICAgICAgICAgICAgICAgIGNoZWNrSXNOZWFySW5maW5pdGVMaW1pdChjbG9jaywgaSk7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICBjb25zdCBleGNlc3NKb2IgPSBmaXJzdFRpbWVyKGNsb2NrKTtcblx0ICAgICAgICAgICAgdGhyb3cgZ2V0SW5maW5pdGVMb29wRXJyb3IoY2xvY2ssIGV4Y2Vzc0pvYik7XG5cdCAgICAgICAgfTtcblxuXHQgICAgICAgIGNsb2NrLnJ1blRvRnJhbWUgPSBmdW5jdGlvbiBydW5Ub0ZyYW1lKCkge1xuXHQgICAgICAgICAgICByZXR1cm4gY2xvY2sudGljayhnZXRUaW1lVG9OZXh0RnJhbWUoKSk7XG5cdCAgICAgICAgfTtcblxuXHQgICAgICAgIGlmICh0eXBlb2YgX2dsb2JhbC5Qcm9taXNlICE9PSBcInVuZGVmaW5lZFwiKSB7XG5cdCAgICAgICAgICAgIGNsb2NrLnJ1bkFsbEFzeW5jID0gZnVuY3Rpb24gcnVuQWxsQXN5bmMoKSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gcGF1c2VBdXRvVGlja1VudGlsRmluaXNoZWQoXG5cdCAgICAgICAgICAgICAgICAgICAgbmV3IF9nbG9iYWwuUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSwgcmVqZWN0KSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIGxldCBpID0gMDtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgLyoqXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAqXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAqL1xuXHQgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBkb1J1bigpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yaWdpbmFsU2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcnVuSm9icyhjbG9jayk7XG5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IG51bVRpbWVycztcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGkgPCBjbG9jay5sb29wTGltaXQpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghY2xvY2sudGltZXJzKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzZXRJc05lYXJJbmZpbml0ZUxpbWl0KCk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShjbG9jay5ub3cpO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVtVGltZXJzID0gT2JqZWN0LmtleXMoXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xvY2sudGltZXJzLFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKS5sZW5ndGg7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobnVtVGltZXJzID09PSAwKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzZXRJc05lYXJJbmZpbml0ZUxpbWl0KCk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShjbG9jay5ub3cpO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xvY2submV4dCgpO1xuXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpKys7XG5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvUnVuKCk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGVja0lzTmVhckluZmluaXRlTGltaXQoY2xvY2ssIGkpO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZXhjZXNzSm9iID0gZmlyc3RUaW1lcihjbG9jayk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldEluZmluaXRlTG9vcEVycm9yKGNsb2NrLCBleGNlc3NKb2IpLFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGUpO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIGRvUnVuKCk7XG5cdCAgICAgICAgICAgICAgICAgICAgfSksXG5cdCAgICAgICAgICAgICAgICApO1xuXHQgICAgICAgICAgICB9O1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIGNsb2NrLnJ1blRvTGFzdCA9IGZ1bmN0aW9uIHJ1blRvTGFzdCgpIHtcblx0ICAgICAgICAgICAgY29uc3QgdGltZXIgPSBsYXN0VGltZXIoY2xvY2spO1xuXHQgICAgICAgICAgICBpZiAoIXRpbWVyKSB7XG5cdCAgICAgICAgICAgICAgICBydW5Kb2JzKGNsb2NrKTtcblx0ICAgICAgICAgICAgICAgIHJldHVybiBjbG9jay5ub3c7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICByZXR1cm4gY2xvY2sudGljayh0aW1lci5jYWxsQXQgLSBjbG9jay5ub3cpO1xuXHQgICAgICAgIH07XG5cblx0ICAgICAgICBpZiAodHlwZW9mIF9nbG9iYWwuUHJvbWlzZSAhPT0gXCJ1bmRlZmluZWRcIikge1xuXHQgICAgICAgICAgICBjbG9jay5ydW5Ub0xhc3RBc3luYyA9IGZ1bmN0aW9uIHJ1blRvTGFzdEFzeW5jKCkge1xuXHQgICAgICAgICAgICAgICAgcmV0dXJuIHBhdXNlQXV0b1RpY2tVbnRpbEZpbmlzaGVkKFxuXHQgICAgICAgICAgICAgICAgICAgIG5ldyBfZ2xvYmFsLlByb21pc2UoZnVuY3Rpb24gKHJlc29sdmUsIHJlamVjdCkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICBvcmlnaW5hbFNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB0aW1lciA9IGxhc3RUaW1lcihjbG9jayk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF0aW1lcikge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBydW5Kb2JzKGNsb2NrKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShjbG9jay5ub3cpO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc29sdmUoXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsb2NrLnRpY2tBc3luYyh0aW1lci5jYWxsQXQgLSBjbG9jay5ub3cpLFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KGUpO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgICAgICAgICB9KTtcblx0ICAgICAgICAgICAgICAgICAgICB9KSxcblx0ICAgICAgICAgICAgICAgICk7XG5cdCAgICAgICAgICAgIH07XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgY2xvY2sucmVzZXQgPSBmdW5jdGlvbiByZXNldCgpIHtcblx0ICAgICAgICAgICAgbmFub3MgPSAwO1xuXHQgICAgICAgICAgICBjbG9jay50aW1lcnMgPSB7fTtcblx0ICAgICAgICAgICAgY2xvY2suam9icyA9IFtdO1xuXHQgICAgICAgICAgICBjbG9jay5ub3cgPSBzdGFydDtcblx0ICAgICAgICB9O1xuXG5cdCAgICAgICAgY2xvY2suc2V0U3lzdGVtVGltZSA9IGZ1bmN0aW9uIHNldFN5c3RlbVRpbWUoc3lzdGVtVGltZSkge1xuXHQgICAgICAgICAgICAvLyBkZXRlcm1pbmUgdGltZSBkaWZmZXJlbmNlXG5cdCAgICAgICAgICAgIGNvbnN0IG5ld05vdyA9IGdldEVwb2NoKHN5c3RlbVRpbWUpO1xuXHQgICAgICAgICAgICBjb25zdCBkaWZmZXJlbmNlID0gbmV3Tm93IC0gY2xvY2subm93O1xuXHQgICAgICAgICAgICBsZXQgaWQsIHRpbWVyO1xuXG5cdCAgICAgICAgICAgIGFkanVzdGVkU3lzdGVtVGltZVswXSA9IGFkanVzdGVkU3lzdGVtVGltZVswXSArIGRpZmZlcmVuY2U7XG5cdCAgICAgICAgICAgIGFkanVzdGVkU3lzdGVtVGltZVsxXSA9IGFkanVzdGVkU3lzdGVtVGltZVsxXSArIG5hbm9zO1xuXHQgICAgICAgICAgICAvLyB1cGRhdGUgJ3N5c3RlbSBjbG9jaydcblx0ICAgICAgICAgICAgY2xvY2subm93ID0gbmV3Tm93O1xuXHQgICAgICAgICAgICBuYW5vcyA9IDA7XG5cblx0ICAgICAgICAgICAgLy8gdXBkYXRlIHRpbWVycyBhbmQgaW50ZXJ2YWxzIHRvIGtlZXAgdGhlbSBzdGFibGVcblx0ICAgICAgICAgICAgZm9yIChpZCBpbiBjbG9jay50aW1lcnMpIHtcblx0ICAgICAgICAgICAgICAgIGlmIChjbG9jay50aW1lcnMuaGFzT3duUHJvcGVydHkoaWQpKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgdGltZXIgPSBjbG9jay50aW1lcnNbaWRdO1xuXHQgICAgICAgICAgICAgICAgICAgIHRpbWVyLmNyZWF0ZWRBdCArPSBkaWZmZXJlbmNlO1xuXHQgICAgICAgICAgICAgICAgICAgIHRpbWVyLmNhbGxBdCArPSBkaWZmZXJlbmNlO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgfTtcblxuXHQgICAgICAgIC8qKlxuXHQgICAgICAgICAqIEBwYXJhbSB7c3RyaW5nfG51bWJlcn0gdGlja1ZhbHVlIG51bWJlciBvZiBtaWxsaXNlY29uZHMgb3IgYSBodW1hbi1yZWFkYWJsZSB2YWx1ZSBsaWtlIFwiMDE6MTE6MTVcIlxuXHQgICAgICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IHdpbGwgcmV0dXJuIHRoZSBuZXcgYG5vd2AgdmFsdWVcblx0ICAgICAgICAgKi9cblx0ICAgICAgICBjbG9jay5qdW1wID0gZnVuY3Rpb24ganVtcCh0aWNrVmFsdWUpIHtcblx0ICAgICAgICAgICAgY29uc3QgbXNGbG9hdCA9XG5cdCAgICAgICAgICAgICAgICB0eXBlb2YgdGlja1ZhbHVlID09PSBcIm51bWJlclwiXG5cdCAgICAgICAgICAgICAgICAgICAgPyB0aWNrVmFsdWVcblx0ICAgICAgICAgICAgICAgICAgICA6IHBhcnNlVGltZSh0aWNrVmFsdWUpO1xuXHQgICAgICAgICAgICBjb25zdCBtcyA9IE1hdGguZmxvb3IobXNGbG9hdCk7XG5cblx0ICAgICAgICAgICAgZm9yIChjb25zdCB0aW1lciBvZiBPYmplY3QudmFsdWVzKGNsb2NrLnRpbWVycykpIHtcblx0ICAgICAgICAgICAgICAgIGlmIChjbG9jay5ub3cgKyBtcyA+IHRpbWVyLmNhbGxBdCkge1xuXHQgICAgICAgICAgICAgICAgICAgIHRpbWVyLmNhbGxBdCA9IGNsb2NrLm5vdyArIG1zO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGNsb2NrLnRpY2sobXMpO1xuXHQgICAgICAgIH07XG5cblx0ICAgICAgICBpZiAoaXNQcmVzZW50LnBlcmZvcm1hbmNlKSB7XG5cdCAgICAgICAgICAgIGNsb2NrLnBlcmZvcm1hbmNlID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcblx0ICAgICAgICAgICAgY2xvY2sucGVyZm9ybWFuY2Uubm93ID0gZmFrZVBlcmZvcm1hbmNlTm93O1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIGlmIChpc1ByZXNlbnQuaHJ0aW1lKSB7XG5cdCAgICAgICAgICAgIGNsb2NrLmhydGltZSA9IGhydGltZTtcblx0ICAgICAgICB9XG5cblx0ICAgICAgICByZXR1cm4gY2xvY2s7XG5cdCAgICB9XG5cblx0ICAgIGZ1bmN0aW9uIGNyZWF0ZUludGVydmFsVGljayhjbG9jaywgZGVsdGEpIHtcblx0ICAgICAgICBjb25zdCBpbnRlcnZhbFRpY2sgPSBkb0ludGVydmFsVGljay5iaW5kKG51bGwsIGNsb2NrLCBkZWx0YSk7XG5cdCAgICAgICAgY29uc3QgaW50ZXJ2YWxJZCA9IG9yaWdpbmFsU2V0SW50ZXJ2YWwoaW50ZXJ2YWxUaWNrLCBkZWx0YSk7XG5cdCAgICAgICAgY2xvY2suYXR0YWNoZWRJbnRlcnZhbCA9IGludGVydmFsSWQ7XG5cdCAgICB9XG5cblx0ICAgIC8qIGVzbGludC1kaXNhYmxlIGNvbXBsZXhpdHkgKi9cblxuXHQgICAgLyoqXG5cdCAgICAgKiBAcGFyYW0ge0NvbmZpZz19IFtjb25maWddIE9wdGlvbmFsIGNvbmZpZ1xuXHQgICAgICogQHJldHVybnMge0Nsb2NrfVxuXHQgICAgICovXG5cdCAgICBmdW5jdGlvbiBpbnN0YWxsKGNvbmZpZykge1xuXHQgICAgICAgIGlmIChcblx0ICAgICAgICAgICAgYXJndW1lbnRzLmxlbmd0aCA+IDEgfHxcblx0ICAgICAgICAgICAgY29uZmlnIGluc3RhbmNlb2YgRGF0ZSB8fFxuXHQgICAgICAgICAgICBBcnJheS5pc0FycmF5KGNvbmZpZykgfHxcblx0ICAgICAgICAgICAgdHlwZW9mIGNvbmZpZyA9PT0gXCJudW1iZXJcIlxuXHQgICAgICAgICkge1xuXHQgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuXHQgICAgICAgICAgICAgICAgYEZha2VUaW1lcnMuaW5zdGFsbCBjYWxsZWQgd2l0aCAke1N0cmluZyhcblx0ICAgICAgICAgICAgICAgICAgICBjb25maWcsXG5cdCAgICAgICAgICAgICAgICApfSBpbnN0YWxsIHJlcXVpcmVzIGFuIG9iamVjdCBwYXJhbWV0ZXJgLFxuXHQgICAgICAgICAgICApO1xuXHQgICAgICAgIH1cblxuXHQgICAgICAgIGlmIChfZ2xvYmFsLkRhdGUuaXNGYWtlID09PSB0cnVlKSB7XG5cdCAgICAgICAgICAgIC8vIFRpbWVycyBhcmUgYWxyZWFkeSBmYWtlZDsgdGhpcyBpcyBhIHByb2JsZW0uXG5cdCAgICAgICAgICAgIC8vIE1ha2UgdGhlIHVzZXIgcmVzZXQgdGltZXJzIGJlZm9yZSBjb250aW51aW5nLlxuXHQgICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxuXHQgICAgICAgICAgICAgICAgXCJDYW4ndCBpbnN0YWxsIGZha2UgdGltZXJzIHR3aWNlIG9uIHRoZSBzYW1lIGdsb2JhbCBvYmplY3QuXCIsXG5cdCAgICAgICAgICAgICk7XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXBhcmFtLXJlYXNzaWduXG5cdCAgICAgICAgY29uZmlnID0gdHlwZW9mIGNvbmZpZyAhPT0gXCJ1bmRlZmluZWRcIiA/IGNvbmZpZyA6IHt9O1xuXHQgICAgICAgIGNvbmZpZy5zaG91bGRBZHZhbmNlVGltZSA9IGNvbmZpZy5zaG91bGRBZHZhbmNlVGltZSB8fCBmYWxzZTtcblx0ICAgICAgICBjb25maWcuYWR2YW5jZVRpbWVEZWx0YSA9IGNvbmZpZy5hZHZhbmNlVGltZURlbHRhIHx8IDIwO1xuXHQgICAgICAgIGNvbmZpZy5zaG91bGRDbGVhck5hdGl2ZVRpbWVycyA9XG5cdCAgICAgICAgICAgIGNvbmZpZy5zaG91bGRDbGVhck5hdGl2ZVRpbWVycyB8fCBmYWxzZTtcblxuXHQgICAgICAgIGlmIChjb25maWcudGFyZ2V0KSB7XG5cdCAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoXG5cdCAgICAgICAgICAgICAgICBcImNvbmZpZy50YXJnZXQgaXMgbm8gbG9uZ2VyIHN1cHBvcnRlZC4gVXNlIGB3aXRoR2xvYmFsKHRhcmdldClgIGluc3RlYWQuXCIsXG5cdCAgICAgICAgICAgICk7XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgLyoqXG5cdCAgICAgICAgICogQHBhcmFtIHtzdHJpbmd9IHRpbWVyL29iamVjdCB0aGUgbmFtZSBvZiB0aGUgdGhpbmcgdGhhdCBpcyBub3QgcHJlc2VudFxuXHQgICAgICAgICAqIEBwYXJhbSB0aW1lclxuXHQgICAgICAgICAqL1xuXHQgICAgICAgIGZ1bmN0aW9uIGhhbmRsZU1pc3NpbmdUaW1lcih0aW1lcikge1xuXHQgICAgICAgICAgICBpZiAoY29uZmlnLmlnbm9yZU1pc3NpbmdUaW1lcnMpIHtcblx0ICAgICAgICAgICAgICAgIHJldHVybjtcblx0ICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgIHRocm93IG5ldyBSZWZlcmVuY2VFcnJvcihcblx0ICAgICAgICAgICAgICAgIGBub24tZXhpc3RlbnQgdGltZXJzIGFuZC9vciBvYmplY3RzIGNhbm5vdCBiZSBmYWtlZDogJyR7dGltZXJ9J2AsXG5cdCAgICAgICAgICAgICk7XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgbGV0IGksIGw7XG5cdCAgICAgICAgY29uc3QgY2xvY2sgPSBjcmVhdGVDbG9jayhjb25maWcubm93LCBjb25maWcubG9vcExpbWl0KTtcblx0ICAgICAgICBjbG9jay5zaG91bGRDbGVhck5hdGl2ZVRpbWVycyA9IGNvbmZpZy5zaG91bGRDbGVhck5hdGl2ZVRpbWVycztcblxuXHQgICAgICAgIGNsb2NrLnVuaW5zdGFsbCA9IGZ1bmN0aW9uICgpIHtcblx0ICAgICAgICAgICAgcmV0dXJuIHVuaW5zdGFsbChjbG9jayk7XG5cdCAgICAgICAgfTtcblxuXHQgICAgICAgIGNsb2NrLmFib3J0TGlzdGVuZXJNYXAgPSBuZXcgTWFwKCk7XG5cblx0ICAgICAgICBjbG9jay5tZXRob2RzID0gY29uZmlnLnRvRmFrZSB8fCBbXTtcblxuXHQgICAgICAgIGlmIChjbG9jay5tZXRob2RzLmxlbmd0aCA9PT0gMCkge1xuXHQgICAgICAgICAgICBjbG9jay5tZXRob2RzID0gT2JqZWN0LmtleXModGltZXJzKTtcblx0ICAgICAgICB9XG5cblx0ICAgICAgICBpZiAoY29uZmlnLnNob3VsZEFkdmFuY2VUaW1lID09PSB0cnVlKSB7XG5cdCAgICAgICAgICAgIGNsb2NrLnNldFRpY2tNb2RlKHtcblx0ICAgICAgICAgICAgICAgIG1vZGU6IFwiaW50ZXJ2YWxcIixcblx0ICAgICAgICAgICAgICAgIGRlbHRhOiBjb25maWcuYWR2YW5jZVRpbWVEZWx0YSxcblx0ICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgfVxuXG5cdCAgICAgICAgaWYgKGNsb2NrLm1ldGhvZHMuaW5jbHVkZXMoXCJwZXJmb3JtYW5jZVwiKSkge1xuXHQgICAgICAgICAgICBjb25zdCBwcm90byA9ICgoKSA9PiB7XG5cdCAgICAgICAgICAgICAgICBpZiAoaGFzUGVyZm9ybWFuY2VDb25zdHJ1Y3RvclByb3RvdHlwZSkge1xuXHQgICAgICAgICAgICAgICAgICAgIHJldHVybiBfZ2xvYmFsLnBlcmZvcm1hbmNlLmNvbnN0cnVjdG9yLnByb3RvdHlwZTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgICAgIGlmIChoYXNQZXJmb3JtYW5jZVByb3RvdHlwZSkge1xuXHQgICAgICAgICAgICAgICAgICAgIHJldHVybiBfZ2xvYmFsLlBlcmZvcm1hbmNlLnByb3RvdHlwZTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfSkoKTtcblx0ICAgICAgICAgICAgaWYgKHByb3RvKSB7XG5cdCAgICAgICAgICAgICAgICBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhwcm90bykuZm9yRWFjaChmdW5jdGlvbiAobmFtZSkge1xuXHQgICAgICAgICAgICAgICAgICAgIGlmIChuYW1lICE9PSBcIm5vd1wiKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIGNsb2NrLnBlcmZvcm1hbmNlW25hbWVdID1cblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWUuaW5kZXhPZihcImdldEVudHJpZXNcIikgPT09IDBcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IE5PT1BfQVJSQVlcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IE5PT1A7XG5cdCAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgICAgICAgICAvLyBlbnN1cmUgYG1hcmtgIHJldHVybnMgYSB2YWx1ZSB0aGF0IGlzIHZhbGlkXG5cdCAgICAgICAgICAgICAgICBjbG9jay5wZXJmb3JtYW5jZS5tYXJrID0gKG5hbWUpID0+XG5cdCAgICAgICAgICAgICAgICAgICAgbmV3IEZha2VQZXJmb3JtYW5jZUVudHJ5KG5hbWUsIFwibWFya1wiLCAwLCAwKTtcblx0ICAgICAgICAgICAgICAgIGNsb2NrLnBlcmZvcm1hbmNlLm1lYXN1cmUgPSAobmFtZSkgPT5cblx0ICAgICAgICAgICAgICAgICAgICBuZXcgRmFrZVBlcmZvcm1hbmNlRW50cnkobmFtZSwgXCJtZWFzdXJlXCIsIDAsIDEwMCk7XG5cdCAgICAgICAgICAgICAgICAvLyBgdGltZU9yaWdpbmAgc2hvdWxkIHJldHVybiB0aGUgdGltZSBvZiB3aGVuIHRoZSBXaW5kb3cgc2Vzc2lvbiBzdGFydGVkXG5cdCAgICAgICAgICAgICAgICAvLyAob3IgdGhlIFdvcmtlciB3YXMgaW5zdGFsbGVkKVxuXHQgICAgICAgICAgICAgICAgY2xvY2sucGVyZm9ybWFuY2UudGltZU9yaWdpbiA9IGdldEVwb2NoKGNvbmZpZy5ub3cpO1xuXHQgICAgICAgICAgICB9IGVsc2UgaWYgKChjb25maWcudG9GYWtlIHx8IFtdKS5pbmNsdWRlcyhcInBlcmZvcm1hbmNlXCIpKSB7XG5cdCAgICAgICAgICAgICAgICByZXR1cm4gaGFuZGxlTWlzc2luZ1RpbWVyKFwicGVyZm9ybWFuY2VcIik7XG5cdCAgICAgICAgICAgIH1cblx0ICAgICAgICB9XG5cdCAgICAgICAgaWYgKF9nbG9iYWwgPT09IGdsb2JhbE9iamVjdCAmJiB0aW1lcnNNb2R1bGUpIHtcblx0ICAgICAgICAgICAgY2xvY2sudGltZXJzTW9kdWxlTWV0aG9kcyA9IFtdO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBpZiAoX2dsb2JhbCA9PT0gZ2xvYmFsT2JqZWN0ICYmIHRpbWVyc1Byb21pc2VzTW9kdWxlKSB7XG5cdCAgICAgICAgICAgIGNsb2NrLnRpbWVyc1Byb21pc2VzTW9kdWxlTWV0aG9kcyA9IFtdO1xuXHQgICAgICAgIH1cblx0ICAgICAgICBmb3IgKGkgPSAwLCBsID0gY2xvY2subWV0aG9kcy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcblx0ICAgICAgICAgICAgY29uc3QgbmFtZU9mTWV0aG9kVG9SZXBsYWNlID0gY2xvY2subWV0aG9kc1tpXTtcblxuXHQgICAgICAgICAgICBpZiAoIWlzUHJlc2VudFtuYW1lT2ZNZXRob2RUb1JlcGxhY2VdKSB7XG5cdCAgICAgICAgICAgICAgICBoYW5kbGVNaXNzaW5nVGltZXIobmFtZU9mTWV0aG9kVG9SZXBsYWNlKTtcblx0ICAgICAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZVxuXHQgICAgICAgICAgICAgICAgY29udGludWU7XG5cdCAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICBpZiAobmFtZU9mTWV0aG9kVG9SZXBsYWNlID09PSBcImhydGltZVwiKSB7XG5cdCAgICAgICAgICAgICAgICBpZiAoXG5cdCAgICAgICAgICAgICAgICAgICAgX2dsb2JhbC5wcm9jZXNzICYmXG5cdCAgICAgICAgICAgICAgICAgICAgdHlwZW9mIF9nbG9iYWwucHJvY2Vzcy5ocnRpbWUgPT09IFwiZnVuY3Rpb25cIlxuXHQgICAgICAgICAgICAgICAgKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgaGlqYWNrTWV0aG9kKF9nbG9iYWwucHJvY2VzcywgbmFtZU9mTWV0aG9kVG9SZXBsYWNlLCBjbG9jayk7XG5cdCAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIH0gZWxzZSBpZiAobmFtZU9mTWV0aG9kVG9SZXBsYWNlID09PSBcIm5leHRUaWNrXCIpIHtcblx0ICAgICAgICAgICAgICAgIGlmIChcblx0ICAgICAgICAgICAgICAgICAgICBfZ2xvYmFsLnByb2Nlc3MgJiZcblx0ICAgICAgICAgICAgICAgICAgICB0eXBlb2YgX2dsb2JhbC5wcm9jZXNzLm5leHRUaWNrID09PSBcImZ1bmN0aW9uXCJcblx0ICAgICAgICAgICAgICAgICkge1xuXHQgICAgICAgICAgICAgICAgICAgIGhpamFja01ldGhvZChfZ2xvYmFsLnByb2Nlc3MsIG5hbWVPZk1ldGhvZFRvUmVwbGFjZSwgY2xvY2spO1xuXHQgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgaGlqYWNrTWV0aG9kKF9nbG9iYWwsIG5hbWVPZk1ldGhvZFRvUmVwbGFjZSwgY2xvY2spO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGlmIChcblx0ICAgICAgICAgICAgICAgIGNsb2NrLnRpbWVyc01vZHVsZU1ldGhvZHMgIT09IHVuZGVmaW5lZCAmJlxuXHQgICAgICAgICAgICAgICAgdGltZXJzTW9kdWxlW25hbWVPZk1ldGhvZFRvUmVwbGFjZV1cblx0ICAgICAgICAgICAgKSB7XG5cdCAgICAgICAgICAgICAgICBjb25zdCBvcmlnaW5hbCA9IHRpbWVyc01vZHVsZVtuYW1lT2ZNZXRob2RUb1JlcGxhY2VdO1xuXHQgICAgICAgICAgICAgICAgY2xvY2sudGltZXJzTW9kdWxlTWV0aG9kcy5wdXNoKHtcblx0ICAgICAgICAgICAgICAgICAgICBtZXRob2ROYW1lOiBuYW1lT2ZNZXRob2RUb1JlcGxhY2UsXG5cdCAgICAgICAgICAgICAgICAgICAgb3JpZ2luYWw6IG9yaWdpbmFsLFxuXHQgICAgICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgICAgICAgICB0aW1lcnNNb2R1bGVbbmFtZU9mTWV0aG9kVG9SZXBsYWNlXSA9XG5cdCAgICAgICAgICAgICAgICAgICAgX2dsb2JhbFtuYW1lT2ZNZXRob2RUb1JlcGxhY2VdO1xuXHQgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgIGlmIChjbG9jay50aW1lcnNQcm9taXNlc01vZHVsZU1ldGhvZHMgIT09IHVuZGVmaW5lZCkge1xuXHQgICAgICAgICAgICAgICAgaWYgKG5hbWVPZk1ldGhvZFRvUmVwbGFjZSA9PT0gXCJzZXRUaW1lb3V0XCIpIHtcblx0ICAgICAgICAgICAgICAgICAgICBjbG9jay50aW1lcnNQcm9taXNlc01vZHVsZU1ldGhvZHMucHVzaCh7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZE5hbWU6IFwic2V0VGltZW91dFwiLFxuXHQgICAgICAgICAgICAgICAgICAgICAgICBvcmlnaW5hbDogdGltZXJzUHJvbWlzZXNNb2R1bGUuc2V0VGltZW91dCxcblx0ICAgICAgICAgICAgICAgICAgICB9KTtcblxuXHQgICAgICAgICAgICAgICAgICAgIHRpbWVyc1Byb21pc2VzTW9kdWxlLnNldFRpbWVvdXQgPSAoXG5cdCAgICAgICAgICAgICAgICAgICAgICAgIGRlbGF5LFxuXHQgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSxcblx0ICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucyA9IHt9LFxuXHQgICAgICAgICAgICAgICAgICAgICkgPT5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgYWJvcnQgPSAoKSA9PiB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5zaWduYWwucmVtb3ZlRXZlbnRMaXN0ZW5lcihcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJhYm9ydFwiLFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhYm9ydCxcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsb2NrLmFib3J0TGlzdGVuZXJNYXAuZGVsZXRlKGFib3J0KTtcblxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoaXMgaXMgc2FmZSwgdGhlcmUgaXMgbm8gY29kZSBwYXRoIHRoYXQgbGVhZHMgdG8gdGhpcyBmdW5jdGlvblxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGJlaW5nIGludm9rZWQgYmVmb3JlIGhhbmRsZSBoYXMgYmVlbiBhc3NpZ25lZC5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdXNlLWJlZm9yZS1kZWZpbmVcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbG9jay5jbGVhclRpbWVvdXQoaGFuZGxlKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3Qob3B0aW9ucy5zaWduYWwucmVhc29uKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGhhbmRsZSA9IGNsb2NrLnNldFRpbWVvdXQoKCkgPT4ge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvcHRpb25zLnNpZ25hbCkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zLnNpZ25hbC5yZW1vdmVFdmVudExpc3RlbmVyKFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJhYm9ydFwiLFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWJvcnQsXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsb2NrLmFib3J0TGlzdGVuZXJNYXAuZGVsZXRlKGFib3J0KTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHZhbHVlKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sIGRlbGF5KTtcblxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuc2lnbmFsKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuc2lnbmFsLmFib3J0ZWQpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWJvcnQoKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zLnNpZ25hbC5hZGRFdmVudExpc3RlbmVyKFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJhYm9ydFwiLFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWJvcnQsXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsb2NrLmFib3J0TGlzdGVuZXJNYXAuc2V0KFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWJvcnQsXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zLnNpZ25hbCxcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuXHQgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChuYW1lT2ZNZXRob2RUb1JlcGxhY2UgPT09IFwic2V0SW1tZWRpYXRlXCIpIHtcblx0ICAgICAgICAgICAgICAgICAgICBjbG9jay50aW1lcnNQcm9taXNlc01vZHVsZU1ldGhvZHMucHVzaCh7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIG1ldGhvZE5hbWU6IFwic2V0SW1tZWRpYXRlXCIsXG5cdCAgICAgICAgICAgICAgICAgICAgICAgIG9yaWdpbmFsOiB0aW1lcnNQcm9taXNlc01vZHVsZS5zZXRJbW1lZGlhdGUsXG5cdCAgICAgICAgICAgICAgICAgICAgfSk7XG5cblx0ICAgICAgICAgICAgICAgICAgICB0aW1lcnNQcm9taXNlc01vZHVsZS5zZXRJbW1lZGlhdGUgPSAodmFsdWUsIG9wdGlvbnMgPSB7fSkgPT5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgYWJvcnQgPSAoKSA9PiB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5zaWduYWwucmVtb3ZlRXZlbnRMaXN0ZW5lcihcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJhYm9ydFwiLFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhYm9ydCxcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsb2NrLmFib3J0TGlzdGVuZXJNYXAuZGVsZXRlKGFib3J0KTtcblxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoaXMgaXMgc2FmZSwgdGhlcmUgaXMgbm8gY29kZSBwYXRoIHRoYXQgbGVhZHMgdG8gdGhpcyBmdW5jdGlvblxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGJlaW5nIGludm9rZWQgYmVmb3JlIGhhbmRsZSBoYXMgYmVlbiBhc3NpZ25lZC5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tdXNlLWJlZm9yZS1kZWZpbmVcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbG9jay5jbGVhckltbWVkaWF0ZShoYW5kbGUpO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlamVjdChvcHRpb25zLnNpZ25hbC5yZWFzb24pO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcblxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaGFuZGxlID0gY2xvY2suc2V0SW1tZWRpYXRlKCgpID0+IHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAob3B0aW9ucy5zaWduYWwpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5zaWduYWwucmVtb3ZlRXZlbnRMaXN0ZW5lcihcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiYWJvcnRcIixcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFib3J0LFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbG9jay5hYm9ydExpc3RlbmVyTWFwLmRlbGV0ZShhYm9ydCk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSh2YWx1ZSk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcblxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuc2lnbmFsKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuc2lnbmFsLmFib3J0ZWQpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWJvcnQoKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zLnNpZ25hbC5hZGRFdmVudExpc3RlbmVyKFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJhYm9ydFwiLFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWJvcnQsXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsb2NrLmFib3J0TGlzdGVuZXJNYXAuc2V0KFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWJvcnQsXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zLnNpZ25hbCxcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cdCAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuXHQgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChuYW1lT2ZNZXRob2RUb1JlcGxhY2UgPT09IFwic2V0SW50ZXJ2YWxcIikge1xuXHQgICAgICAgICAgICAgICAgICAgIGNsb2NrLnRpbWVyc1Byb21pc2VzTW9kdWxlTWV0aG9kcy5wdXNoKHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgbWV0aG9kTmFtZTogXCJzZXRJbnRlcnZhbFwiLFxuXHQgICAgICAgICAgICAgICAgICAgICAgICBvcmlnaW5hbDogdGltZXJzUHJvbWlzZXNNb2R1bGUuc2V0SW50ZXJ2YWwsXG5cdCAgICAgICAgICAgICAgICAgICAgfSk7XG5cblx0ICAgICAgICAgICAgICAgICAgICB0aW1lcnNQcm9taXNlc01vZHVsZS5zZXRJbnRlcnZhbCA9IChcblx0ICAgICAgICAgICAgICAgICAgICAgICAgZGVsYXksXG5cdCAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlLFxuXHQgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zID0ge30sXG5cdCAgICAgICAgICAgICAgICAgICAgKSA9PiAoe1xuXHQgICAgICAgICAgICAgICAgICAgICAgICBbU3ltYm9sLmFzeW5jSXRlcmF0b3JdOiAoKSA9PiB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjcmVhdGVSZXNvbHZhYmxlID0gKCkgPT4ge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCByZXNvbHZlLCByZWplY3Q7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcHJvbWlzZSA9IG5ldyBQcm9taXNlKChyZXMsIHJlaikgPT4ge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlID0gcmVzO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWplY3QgPSByZWo7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvbWlzZS5yZXNvbHZlID0gcmVzb2x2ZTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9taXNlLnJlamVjdCA9IHJlamVjdDtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcHJvbWlzZTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIH07XG5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBkb25lID0gZmFsc2U7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgaGFzVGhyb3duID0gZmFsc2U7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgcmV0dXJuQ2FsbDtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBuZXh0QXZhaWxhYmxlID0gMDtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5leHRRdWV1ZSA9IFtdO1xuXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBoYW5kbGUgPSBjbG9jay5zZXRJbnRlcnZhbCgoKSA9PiB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5leHRRdWV1ZS5sZW5ndGggPiAwKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5leHRRdWV1ZS5zaGlmdCgpLnJlc29sdmUoKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXh0QXZhaWxhYmxlKys7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSwgZGVsYXkpO1xuXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBhYm9ydCA9ICgpID0+IHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcHRpb25zLnNpZ25hbC5yZW1vdmVFdmVudExpc3RlbmVyKFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcImFib3J0XCIsXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFib3J0LFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xvY2suYWJvcnRMaXN0ZW5lck1hcC5kZWxldGUoYWJvcnQpO1xuXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xvY2suY2xlYXJJbnRlcnZhbChoYW5kbGUpO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgcmVzb2x2YWJsZSBvZiBuZXh0UXVldWUpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x2YWJsZS5yZXNvbHZlKCk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcblxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuc2lnbmFsKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuc2lnbmFsLmFib3J0ZWQpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9uZSA9IHRydWU7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5zaWduYWwuYWRkRXZlbnRMaXN0ZW5lcihcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiYWJvcnRcIixcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFib3J0LFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbG9jay5hYm9ydExpc3RlbmVyTWFwLnNldChcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFib3J0LFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5zaWduYWwsXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4ge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5leHQ6IGFzeW5jICgpID0+IHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuc2lnbmFsPy5hYm9ydGVkICYmICFoYXNUaHJvd24pIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhc1Rocm93biA9IHRydWU7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBvcHRpb25zLnNpZ25hbC5yZWFzb247XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZG9uZSkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHsgZG9uZTogdHJ1ZSwgdmFsdWU6IHVuZGVmaW5lZCB9O1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG5leHRBdmFpbGFibGUgPiAwKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXh0QXZhaWxhYmxlLS07XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4geyBkb25lOiBmYWxzZSwgdmFsdWU6IHZhbHVlIH07XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCByZXNvbHZhYmxlID0gY3JlYXRlUmVzb2x2YWJsZSgpO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXh0UXVldWUucHVzaChyZXNvbHZhYmxlKTtcblxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCByZXNvbHZhYmxlO1xuXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXR1cm5DYWxsICYmIG5leHRRdWV1ZS5sZW5ndGggPT09IDApIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybkNhbGwucmVzb2x2ZSgpO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG9wdGlvbnMuc2lnbmFsPy5hYm9ydGVkICYmICFoYXNUaHJvd24pIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhhc1Rocm93biA9IHRydWU7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBvcHRpb25zLnNpZ25hbC5yZWFzb247XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZG9uZSkge1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHsgZG9uZTogdHJ1ZSwgdmFsdWU6IHVuZGVmaW5lZCB9O1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHsgZG9uZTogZmFsc2UsIHZhbHVlOiB2YWx1ZSB9O1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOiBhc3luYyAoKSA9PiB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChkb25lKSB7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4geyBkb25lOiB0cnVlLCB2YWx1ZTogdW5kZWZpbmVkIH07XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobmV4dFF1ZXVlLmxlbmd0aCA+IDApIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybkNhbGwgPSBjcmVhdGVSZXNvbHZhYmxlKCk7XG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCByZXR1cm5DYWxsO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xvY2suY2xlYXJJbnRlcnZhbChoYW5kbGUpO1xuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTtcblxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAob3B0aW9ucy5zaWduYWwpIHtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMuc2lnbmFsLnJlbW92ZUV2ZW50TGlzdGVuZXIoXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJhYm9ydFwiLFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFib3J0LFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsb2NrLmFib3J0TGlzdGVuZXJNYXAuZGVsZXRlKGFib3J0KTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG5cdCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB7IGRvbmU6IHRydWUsIHZhbHVlOiB1bmRlZmluZWQgfTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuXHQgICAgICAgICAgICAgICAgICAgICAgICAgICAgfTtcblx0ICAgICAgICAgICAgICAgICAgICAgICAgfSxcblx0ICAgICAgICAgICAgICAgICAgICB9KTtcblx0ICAgICAgICAgICAgICAgIH1cblx0ICAgICAgICAgICAgfVxuXHQgICAgICAgIH1cblxuXHQgICAgICAgIHJldHVybiBjbG9jaztcblx0ICAgIH1cblxuXHQgICAgLyogZXNsaW50LWVuYWJsZSBjb21wbGV4aXR5ICovXG5cblx0ICAgIHJldHVybiB7XG5cdCAgICAgICAgdGltZXJzOiB0aW1lcnMsXG5cdCAgICAgICAgY3JlYXRlQ2xvY2s6IGNyZWF0ZUNsb2NrLFxuXHQgICAgICAgIGluc3RhbGw6IGluc3RhbGwsXG5cdCAgICAgICAgd2l0aEdsb2JhbDogd2l0aEdsb2JhbCxcblx0ICAgIH07XG5cdH1cblxuXHQvKipcblx0ICogQHR5cGVkZWYge29iamVjdH0gRmFrZVRpbWVyc1xuXHQgKiBAcHJvcGVydHkge1RpbWVyc30gdGltZXJzXG5cdCAqIEBwcm9wZXJ0eSB7Y3JlYXRlQ2xvY2t9IGNyZWF0ZUNsb2NrXG5cdCAqIEBwcm9wZXJ0eSB7RnVuY3Rpb259IGluc3RhbGxcblx0ICogQHByb3BlcnR5IHt3aXRoR2xvYmFsfSB3aXRoR2xvYmFsXG5cdCAqL1xuXG5cdC8qIGVzbGludC1lbmFibGUgY29tcGxleGl0eSAqL1xuXG5cdC8qKiBAdHlwZSB7RmFrZVRpbWVyc30gKi9cblx0Y29uc3QgZGVmYXVsdEltcGxlbWVudGF0aW9uID0gd2l0aEdsb2JhbChnbG9iYWxPYmplY3QpO1xuXG5cdGZha2VUaW1lcnNTcmMudGltZXJzID0gZGVmYXVsdEltcGxlbWVudGF0aW9uLnRpbWVycztcblx0ZmFrZVRpbWVyc1NyYy5jcmVhdGVDbG9jayA9IGRlZmF1bHRJbXBsZW1lbnRhdGlvbi5jcmVhdGVDbG9jaztcblx0ZmFrZVRpbWVyc1NyYy5pbnN0YWxsID0gZGVmYXVsdEltcGxlbWVudGF0aW9uLmluc3RhbGw7XG5cdGZha2VUaW1lcnNTcmMud2l0aEdsb2JhbCA9IHdpdGhHbG9iYWw7XG5cdHJldHVybiBmYWtlVGltZXJzU3JjO1xufVxuXG52YXIgZmFrZVRpbWVyc1NyY0V4cG9ydHMgPSByZXF1aXJlRmFrZVRpbWVyc1NyYygpO1xuXG5jbGFzcyBGYWtlVGltZXJzIHtcblx0X2dsb2JhbDtcblx0X2Nsb2NrO1xuXHQvLyB8IF9mYWtpbmdUaW1lIHwgX2Zha2luZ0RhdGUgfFxuXHQvLyArLS0tLS0tLS0tLS0tLSstLS0tLS0tLS0tLS0tK1xuXHQvLyB8IGZhbHNlICAgICAgIHwgZmFsc3kgICAgICAgfCBpbml0aWFsXG5cdC8vIHwgZmFsc2UgICAgICAgfCB0cnV0aHkgICAgICB8IHZpLnNldFN5c3RlbVRpbWUgY2FsbGVkIGZpcnN0IChmb3IgbW9ja2luZyBvbmx5IERhdGUgd2l0aG91dCBmYWtlIHRpbWVycylcblx0Ly8gfCB0cnVlICAgICAgICB8IGZhbHN5ICAgICAgIHwgdmkudXNlRmFrZVRpbWVycyBjYWxsZWQgZmlyc3Rcblx0Ly8gfCB0cnVlICAgICAgICB8IHRydXRoeSAgICAgIHwgdW5yZWFjaGFibGVcblx0X2Zha2luZ1RpbWU7XG5cdF9mYWtpbmdEYXRlO1xuXHRfZmFrZVRpbWVycztcblx0X3VzZXJDb25maWc7XG5cdF9ub3cgPSBSZWFsRGF0ZS5ub3c7XG5cdGNvbnN0cnVjdG9yKHsgZ2xvYmFsLCBjb25maWcgfSkge1xuXHRcdHRoaXMuX3VzZXJDb25maWcgPSBjb25maWc7XG5cdFx0dGhpcy5fZmFraW5nRGF0ZSA9IG51bGw7XG5cdFx0dGhpcy5fZmFraW5nVGltZSA9IGZhbHNlO1xuXHRcdHRoaXMuX2Zha2VUaW1lcnMgPSBmYWtlVGltZXJzU3JjRXhwb3J0cy53aXRoR2xvYmFsKGdsb2JhbCk7XG5cdFx0dGhpcy5fZ2xvYmFsID0gZ2xvYmFsO1xuXHR9XG5cdGNsZWFyQWxsVGltZXJzKCkge1xuXHRcdGlmICh0aGlzLl9mYWtpbmdUaW1lKSB0aGlzLl9jbG9jay5yZXNldCgpO1xuXHR9XG5cdGRpc3Bvc2UoKSB7XG5cdFx0dGhpcy51c2VSZWFsVGltZXJzKCk7XG5cdH1cblx0cnVuQWxsVGltZXJzKCkge1xuXHRcdGlmICh0aGlzLl9jaGVja0Zha2VUaW1lcnMoKSkgdGhpcy5fY2xvY2sucnVuQWxsKCk7XG5cdH1cblx0YXN5bmMgcnVuQWxsVGltZXJzQXN5bmMoKSB7XG5cdFx0aWYgKHRoaXMuX2NoZWNrRmFrZVRpbWVycygpKSBhd2FpdCB0aGlzLl9jbG9jay5ydW5BbGxBc3luYygpO1xuXHR9XG5cdHJ1bk9ubHlQZW5kaW5nVGltZXJzKCkge1xuXHRcdGlmICh0aGlzLl9jaGVja0Zha2VUaW1lcnMoKSkgdGhpcy5fY2xvY2sucnVuVG9MYXN0KCk7XG5cdH1cblx0YXN5bmMgcnVuT25seVBlbmRpbmdUaW1lcnNBc3luYygpIHtcblx0XHRpZiAodGhpcy5fY2hlY2tGYWtlVGltZXJzKCkpIGF3YWl0IHRoaXMuX2Nsb2NrLnJ1blRvTGFzdEFzeW5jKCk7XG5cdH1cblx0YWR2YW5jZVRpbWVyc1RvTmV4dFRpbWVyKHN0ZXBzID0gMSkge1xuXHRcdGlmICh0aGlzLl9jaGVja0Zha2VUaW1lcnMoKSkgZm9yIChsZXQgaSA9IHN0ZXBzOyBpID4gMDsgaS0tKSB7XG5cdFx0XHR0aGlzLl9jbG9jay5uZXh0KCk7XG5cdFx0XHQvLyBGaXJlIGFsbCB0aW1lcnMgYXQgdGhpcyBwb2ludDogaHR0cHM6Ly9naXRodWIuY29tL3Npbm9uanMvZmFrZS10aW1lcnMvaXNzdWVzLzI1MFxuXHRcdFx0dGhpcy5fY2xvY2sudGljaygwKTtcblx0XHRcdGlmICh0aGlzLl9jbG9jay5jb3VudFRpbWVycygpID09PSAwKSBicmVhaztcblx0XHR9XG5cdH1cblx0YXN5bmMgYWR2YW5jZVRpbWVyc1RvTmV4dFRpbWVyQXN5bmMoc3RlcHMgPSAxKSB7XG5cdFx0aWYgKHRoaXMuX2NoZWNrRmFrZVRpbWVycygpKSBmb3IgKGxldCBpID0gc3RlcHM7IGkgPiAwOyBpLS0pIHtcblx0XHRcdGF3YWl0IHRoaXMuX2Nsb2NrLm5leHRBc3luYygpO1xuXHRcdFx0Ly8gRmlyZSBhbGwgdGltZXJzIGF0IHRoaXMgcG9pbnQ6IGh0dHBzOi8vZ2l0aHViLmNvbS9zaW5vbmpzL2Zha2UtdGltZXJzL2lzc3Vlcy8yNTBcblx0XHRcdHRoaXMuX2Nsb2NrLnRpY2soMCk7XG5cdFx0XHRpZiAodGhpcy5fY2xvY2suY291bnRUaW1lcnMoKSA9PT0gMCkgYnJlYWs7XG5cdFx0fVxuXHR9XG5cdGFkdmFuY2VUaW1lcnNCeVRpbWUobXNUb1J1bikge1xuXHRcdGlmICh0aGlzLl9jaGVja0Zha2VUaW1lcnMoKSkgdGhpcy5fY2xvY2sudGljayhtc1RvUnVuKTtcblx0fVxuXHRhc3luYyBhZHZhbmNlVGltZXJzQnlUaW1lQXN5bmMobXNUb1J1bikge1xuXHRcdGlmICh0aGlzLl9jaGVja0Zha2VUaW1lcnMoKSkgYXdhaXQgdGhpcy5fY2xvY2sudGlja0FzeW5jKG1zVG9SdW4pO1xuXHR9XG5cdGFkdmFuY2VUaW1lcnNUb05leHRGcmFtZSgpIHtcblx0XHRpZiAodGhpcy5fY2hlY2tGYWtlVGltZXJzKCkpIHRoaXMuX2Nsb2NrLnJ1blRvRnJhbWUoKTtcblx0fVxuXHRydW5BbGxUaWNrcygpIHtcblx0XHRpZiAodGhpcy5fY2hlY2tGYWtlVGltZXJzKCkpIHRoaXMuX2Nsb2NrLnJ1bk1pY3JvdGFza3MoKTtcblx0fVxuXHR1c2VSZWFsVGltZXJzKCkge1xuXHRcdGlmICh0aGlzLl9mYWtpbmdEYXRlKSB7XG5cdFx0XHRyZXNldERhdGUoKTtcblx0XHRcdHRoaXMuX2Zha2luZ0RhdGUgPSBudWxsO1xuXHRcdH1cblx0XHRpZiAodGhpcy5fZmFraW5nVGltZSkge1xuXHRcdFx0dGhpcy5fY2xvY2sudW5pbnN0YWxsKCk7XG5cdFx0XHR0aGlzLl9mYWtpbmdUaW1lID0gZmFsc2U7XG5cdFx0fVxuXHR9XG5cdHVzZUZha2VUaW1lcnMoKSB7XG5cdFx0Y29uc3QgZmFrZURhdGUgPSB0aGlzLl9mYWtpbmdEYXRlIHx8IERhdGUubm93KCk7XG5cdFx0aWYgKHRoaXMuX2Zha2luZ0RhdGUpIHtcblx0XHRcdHJlc2V0RGF0ZSgpO1xuXHRcdFx0dGhpcy5fZmFraW5nRGF0ZSA9IG51bGw7XG5cdFx0fVxuXHRcdGlmICh0aGlzLl9mYWtpbmdUaW1lKSB0aGlzLl9jbG9jay51bmluc3RhbGwoKTtcblx0XHRjb25zdCB0b0Zha2UgPSBPYmplY3Qua2V5cyh0aGlzLl9mYWtlVGltZXJzLnRpbWVycykuZmlsdGVyKCh0aW1lcikgPT4gdGltZXIgIT09IFwibmV4dFRpY2tcIiAmJiB0aW1lciAhPT0gXCJxdWV1ZU1pY3JvdGFza1wiKTtcblx0XHRpZiAodGhpcy5fdXNlckNvbmZpZz8udG9GYWtlPy5pbmNsdWRlcyhcIm5leHRUaWNrXCIpICYmIGlzQ2hpbGRQcm9jZXNzKCkpIHRocm93IG5ldyBFcnJvcihcInByb2Nlc3MubmV4dFRpY2sgY2Fubm90IGJlIG1vY2tlZCBpbnNpZGUgY2hpbGRfcHJvY2Vzc1wiKTtcblx0XHR0aGlzLl9jbG9jayA9IHRoaXMuX2Zha2VUaW1lcnMuaW5zdGFsbCh7XG5cdFx0XHRub3c6IGZha2VEYXRlLFxuXHRcdFx0Li4udGhpcy5fdXNlckNvbmZpZyxcblx0XHRcdHRvRmFrZTogdGhpcy5fdXNlckNvbmZpZz8udG9GYWtlIHx8IHRvRmFrZSxcblx0XHRcdGlnbm9yZU1pc3NpbmdUaW1lcnM6IHRydWVcblx0XHR9KTtcblx0XHR0aGlzLl9mYWtpbmdUaW1lID0gdHJ1ZTtcblx0fVxuXHRyZXNldCgpIHtcblx0XHRpZiAodGhpcy5fY2hlY2tGYWtlVGltZXJzKCkpIHtcblx0XHRcdGNvbnN0IHsgbm93IH0gPSB0aGlzLl9jbG9jaztcblx0XHRcdHRoaXMuX2Nsb2NrLnJlc2V0KCk7XG5cdFx0XHR0aGlzLl9jbG9jay5zZXRTeXN0ZW1UaW1lKG5vdyk7XG5cdFx0fVxuXHR9XG5cdHNldFN5c3RlbVRpbWUobm93KSB7XG5cdFx0Y29uc3QgZGF0ZSA9IHR5cGVvZiBub3cgPT09IFwidW5kZWZpbmVkXCIgfHwgbm93IGluc3RhbmNlb2YgRGF0ZSA/IG5vdyA6IG5ldyBEYXRlKG5vdyk7XG5cdFx0aWYgKHRoaXMuX2Zha2luZ1RpbWUpIHRoaXMuX2Nsb2NrLnNldFN5c3RlbVRpbWUoZGF0ZSk7XG5cdFx0ZWxzZSB7XG5cdFx0XHR0aGlzLl9mYWtpbmdEYXRlID0gZGF0ZSA/PyBuZXcgRGF0ZSh0aGlzLmdldFJlYWxTeXN0ZW1UaW1lKCkpO1xuXHRcdFx0bW9ja0RhdGUodGhpcy5fZmFraW5nRGF0ZSk7XG5cdFx0fVxuXHR9XG5cdGdldE1vY2tlZFN5c3RlbVRpbWUoKSB7XG5cdFx0cmV0dXJuIHRoaXMuX2Zha2luZ1RpbWUgPyBuZXcgRGF0ZSh0aGlzLl9jbG9jay5ub3cpIDogdGhpcy5fZmFraW5nRGF0ZTtcblx0fVxuXHRnZXRSZWFsU3lzdGVtVGltZSgpIHtcblx0XHRyZXR1cm4gdGhpcy5fbm93KCk7XG5cdH1cblx0Z2V0VGltZXJDb3VudCgpIHtcblx0XHRpZiAodGhpcy5fY2hlY2tGYWtlVGltZXJzKCkpIHJldHVybiB0aGlzLl9jbG9jay5jb3VudFRpbWVycygpO1xuXHRcdHJldHVybiAwO1xuXHR9XG5cdHNldFRpbWVyVGlja01vZGUobW9kZSwgaW50ZXJ2YWwpIHtcblx0XHRpZiAodGhpcy5fY2hlY2tGYWtlVGltZXJzKCkpIGlmIChtb2RlID09PSBcIm1hbnVhbFwiKSB0aGlzLl9jbG9jay5zZXRUaWNrTW9kZSh7IG1vZGU6IFwibWFudWFsXCIgfSk7XG5cdFx0ZWxzZSBpZiAobW9kZSA9PT0gXCJuZXh0VGltZXJBc3luY1wiKSB0aGlzLl9jbG9jay5zZXRUaWNrTW9kZSh7IG1vZGU6IFwibmV4dEFzeW5jXCIgfSk7XG5cdFx0ZWxzZSBpZiAobW9kZSA9PT0gXCJpbnRlcnZhbFwiKSB0aGlzLl9jbG9jay5zZXRUaWNrTW9kZSh7XG5cdFx0XHRtb2RlOiBcImludGVydmFsXCIsXG5cdFx0XHRkZWx0YTogaW50ZXJ2YWxcblx0XHR9KTtcblx0XHRlbHNlIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCB0aWNrIG1vZGU6ICR7bW9kZX1gKTtcblx0fVxuXHRjb25maWd1cmUoY29uZmlnKSB7XG5cdFx0dGhpcy5fdXNlckNvbmZpZyA9IGNvbmZpZztcblx0fVxuXHRpc0Zha2VUaW1lcnMoKSB7XG5cdFx0cmV0dXJuIHRoaXMuX2Zha2luZ1RpbWU7XG5cdH1cblx0X2NoZWNrRmFrZVRpbWVycygpIHtcblx0XHRpZiAoIXRoaXMuX2Zha2luZ1RpbWUpIHRocm93IG5ldyBFcnJvcihcIkEgZnVuY3Rpb24gdG8gYWR2YW5jZSB0aW1lcnMgd2FzIGNhbGxlZCBidXQgdGhlIHRpbWVycyBBUElzIGFyZSBub3QgbW9ja2VkLiBDYWxsIGB2aS51c2VGYWtlVGltZXJzKClgIGluIHRoZSB0ZXN0IGZpbGUgZmlyc3QuXCIpO1xuXHRcdHJldHVybiB0aGlzLl9mYWtpbmdUaW1lO1xuXHR9XG59XG5cbmZ1bmN0aW9uIGNvcHlTdGFja1RyYWNlJDEodGFyZ2V0LCBzb3VyY2UpIHtcblx0aWYgKHNvdXJjZS5zdGFjayAhPT0gdm9pZCAwKSB0YXJnZXQuc3RhY2sgPSBzb3VyY2Uuc3RhY2sucmVwbGFjZShzb3VyY2UubWVzc2FnZSwgdGFyZ2V0Lm1lc3NhZ2UpO1xuXHRyZXR1cm4gdGFyZ2V0O1xufVxuZnVuY3Rpb24gd2FpdEZvcihjYWxsYmFjaywgb3B0aW9ucyA9IHt9KSB7XG5cdGNvbnN0IHsgc2V0VGltZW91dCwgc2V0SW50ZXJ2YWwsIGNsZWFyVGltZW91dCwgY2xlYXJJbnRlcnZhbCB9ID0gZ2V0U2FmZVRpbWVycygpO1xuXHRjb25zdCB7IGludGVydmFsID0gNTAsIHRpbWVvdXQgPSAxZTMgfSA9IHR5cGVvZiBvcHRpb25zID09PSBcIm51bWJlclwiID8geyB0aW1lb3V0OiBvcHRpb25zIH0gOiBvcHRpb25zO1xuXHRjb25zdCBTVEFDS19UUkFDRV9FUlJPUiA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgRXJyb3IoXCJTVEFDS19UUkFDRV9FUlJPUlwiKTtcblx0cmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcblx0XHRsZXQgbGFzdEVycm9yO1xuXHRcdGxldCBwcm9taXNlU3RhdHVzID0gXCJpZGxlXCI7XG5cdFx0bGV0IHRpbWVvdXRJZDtcblx0XHRsZXQgaW50ZXJ2YWxJZDtcblx0XHRjb25zdCBvblJlc29sdmUgPSAocmVzdWx0KSA9PiB7XG5cdFx0XHRpZiAodGltZW91dElkKSBjbGVhclRpbWVvdXQodGltZW91dElkKTtcblx0XHRcdGlmIChpbnRlcnZhbElkKSBjbGVhckludGVydmFsKGludGVydmFsSWQpO1xuXHRcdFx0cmVzb2x2ZShyZXN1bHQpO1xuXHRcdH07XG5cdFx0Y29uc3QgaGFuZGxlVGltZW91dCA9ICgpID0+IHtcblx0XHRcdGlmIChpbnRlcnZhbElkKSBjbGVhckludGVydmFsKGludGVydmFsSWQpO1xuXHRcdFx0bGV0IGVycm9yID0gbGFzdEVycm9yO1xuXHRcdFx0aWYgKCFlcnJvcikgZXJyb3IgPSBjb3B5U3RhY2tUcmFjZSQxKC8qIEBfX1BVUkVfXyAqLyBuZXcgRXJyb3IoXCJUaW1lZCBvdXQgaW4gd2FpdEZvciFcIiksIFNUQUNLX1RSQUNFX0VSUk9SKTtcblx0XHRcdHJlamVjdChlcnJvcik7XG5cdFx0fTtcblx0XHRjb25zdCBjaGVja0NhbGxiYWNrID0gKCkgPT4ge1xuXHRcdFx0aWYgKHZpLmlzRmFrZVRpbWVycygpKSB2aS5hZHZhbmNlVGltZXJzQnlUaW1lKGludGVydmFsKTtcblx0XHRcdGlmIChwcm9taXNlU3RhdHVzID09PSBcInBlbmRpbmdcIikgcmV0dXJuO1xuXHRcdFx0dHJ5IHtcblx0XHRcdFx0Y29uc3QgcmVzdWx0ID0gY2FsbGJhY2soKTtcblx0XHRcdFx0aWYgKHJlc3VsdCAhPT0gbnVsbCAmJiB0eXBlb2YgcmVzdWx0ID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiByZXN1bHQudGhlbiA9PT0gXCJmdW5jdGlvblwiKSB7XG5cdFx0XHRcdFx0Y29uc3QgdGhlbmFibGUgPSByZXN1bHQ7XG5cdFx0XHRcdFx0cHJvbWlzZVN0YXR1cyA9IFwicGVuZGluZ1wiO1xuXHRcdFx0XHRcdHRoZW5hYmxlLnRoZW4oKHJlc29sdmVkVmFsdWUpID0+IHtcblx0XHRcdFx0XHRcdHByb21pc2VTdGF0dXMgPSBcInJlc29sdmVkXCI7XG5cdFx0XHRcdFx0XHRvblJlc29sdmUocmVzb2x2ZWRWYWx1ZSk7XG5cdFx0XHRcdFx0fSwgKHJlamVjdGVkVmFsdWUpID0+IHtcblx0XHRcdFx0XHRcdHByb21pc2VTdGF0dXMgPSBcInJlamVjdGVkXCI7XG5cdFx0XHRcdFx0XHRsYXN0RXJyb3IgPSByZWplY3RlZFZhbHVlO1xuXHRcdFx0XHRcdH0pO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdG9uUmVzb2x2ZShyZXN1bHQpO1xuXHRcdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGNhdGNoIChlcnJvcikge1xuXHRcdFx0XHRsYXN0RXJyb3IgPSBlcnJvcjtcblx0XHRcdH1cblx0XHR9O1xuXHRcdGlmIChjaGVja0NhbGxiYWNrKCkgPT09IHRydWUpIHJldHVybjtcblx0XHR0aW1lb3V0SWQgPSBzZXRUaW1lb3V0KGhhbmRsZVRpbWVvdXQsIHRpbWVvdXQpO1xuXHRcdGludGVydmFsSWQgPSBzZXRJbnRlcnZhbChjaGVja0NhbGxiYWNrLCBpbnRlcnZhbCk7XG5cdH0pO1xufVxuZnVuY3Rpb24gd2FpdFVudGlsKGNhbGxiYWNrLCBvcHRpb25zID0ge30pIHtcblx0Y29uc3QgeyBzZXRUaW1lb3V0LCBzZXRJbnRlcnZhbCwgY2xlYXJUaW1lb3V0LCBjbGVhckludGVydmFsIH0gPSBnZXRTYWZlVGltZXJzKCk7XG5cdGNvbnN0IHsgaW50ZXJ2YWwgPSA1MCwgdGltZW91dCA9IDFlMyB9ID0gdHlwZW9mIG9wdGlvbnMgPT09IFwibnVtYmVyXCIgPyB7IHRpbWVvdXQ6IG9wdGlvbnMgfSA6IG9wdGlvbnM7XG5cdGNvbnN0IFNUQUNLX1RSQUNFX0VSUk9SID0gLyogQF9fUFVSRV9fICovIG5ldyBFcnJvcihcIlNUQUNLX1RSQUNFX0VSUk9SXCIpO1xuXHRyZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXHRcdGxldCBwcm9taXNlU3RhdHVzID0gXCJpZGxlXCI7XG5cdFx0bGV0IHRpbWVvdXRJZDtcblx0XHRsZXQgaW50ZXJ2YWxJZDtcblx0XHRjb25zdCBvblJlamVjdCA9IChlcnJvcikgPT4ge1xuXHRcdFx0aWYgKGludGVydmFsSWQpIGNsZWFySW50ZXJ2YWwoaW50ZXJ2YWxJZCk7XG5cdFx0XHRpZiAoIWVycm9yKSBlcnJvciA9IGNvcHlTdGFja1RyYWNlJDEoLyogQF9fUFVSRV9fICovIG5ldyBFcnJvcihcIlRpbWVkIG91dCBpbiB3YWl0VW50aWwhXCIpLCBTVEFDS19UUkFDRV9FUlJPUik7XG5cdFx0XHRyZWplY3QoZXJyb3IpO1xuXHRcdH07XG5cdFx0Y29uc3Qgb25SZXNvbHZlID0gKHJlc3VsdCkgPT4ge1xuXHRcdFx0aWYgKCFyZXN1bHQpIHJldHVybjtcblx0XHRcdGlmICh0aW1lb3V0SWQpIGNsZWFyVGltZW91dCh0aW1lb3V0SWQpO1xuXHRcdFx0aWYgKGludGVydmFsSWQpIGNsZWFySW50ZXJ2YWwoaW50ZXJ2YWxJZCk7XG5cdFx0XHRyZXNvbHZlKHJlc3VsdCk7XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHR9O1xuXHRcdGNvbnN0IGNoZWNrQ2FsbGJhY2sgPSAoKSA9PiB7XG5cdFx0XHRpZiAodmkuaXNGYWtlVGltZXJzKCkpIHZpLmFkdmFuY2VUaW1lcnNCeVRpbWUoaW50ZXJ2YWwpO1xuXHRcdFx0aWYgKHByb21pc2VTdGF0dXMgPT09IFwicGVuZGluZ1wiKSByZXR1cm47XG5cdFx0XHR0cnkge1xuXHRcdFx0XHRjb25zdCByZXN1bHQgPSBjYWxsYmFjaygpO1xuXHRcdFx0XHRpZiAocmVzdWx0ICE9PSBudWxsICYmIHR5cGVvZiByZXN1bHQgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIHJlc3VsdC50aGVuID09PSBcImZ1bmN0aW9uXCIpIHtcblx0XHRcdFx0XHRjb25zdCB0aGVuYWJsZSA9IHJlc3VsdDtcblx0XHRcdFx0XHRwcm9taXNlU3RhdHVzID0gXCJwZW5kaW5nXCI7XG5cdFx0XHRcdFx0dGhlbmFibGUudGhlbigocmVzb2x2ZWRWYWx1ZSkgPT4ge1xuXHRcdFx0XHRcdFx0cHJvbWlzZVN0YXR1cyA9IFwicmVzb2x2ZWRcIjtcblx0XHRcdFx0XHRcdG9uUmVzb2x2ZShyZXNvbHZlZFZhbHVlKTtcblx0XHRcdFx0XHR9LCAocmVqZWN0ZWRWYWx1ZSkgPT4ge1xuXHRcdFx0XHRcdFx0cHJvbWlzZVN0YXR1cyA9IFwicmVqZWN0ZWRcIjtcblx0XHRcdFx0XHRcdG9uUmVqZWN0KHJlamVjdGVkVmFsdWUpO1xuXHRcdFx0XHRcdH0pO1xuXHRcdFx0XHR9IGVsc2UgcmV0dXJuIG9uUmVzb2x2ZShyZXN1bHQpO1xuXHRcdFx0fSBjYXRjaCAoZXJyb3IpIHtcblx0XHRcdFx0b25SZWplY3QoZXJyb3IpO1xuXHRcdFx0fVxuXHRcdH07XG5cdFx0aWYgKGNoZWNrQ2FsbGJhY2soKSA9PT0gdHJ1ZSkgcmV0dXJuO1xuXHRcdHRpbWVvdXRJZCA9IHNldFRpbWVvdXQob25SZWplY3QsIHRpbWVvdXQpO1xuXHRcdGludGVydmFsSWQgPSBzZXRJbnRlcnZhbChjaGVja0NhbGxiYWNrLCBpbnRlcnZhbCk7XG5cdH0pO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVWaXRlc3QoKSB7XG5cdGxldCBfY29uZmlnID0gbnVsbDtcblx0Y29uc3Qgc3RhdGUgPSAoKSA9PiBnZXRXb3JrZXJTdGF0ZSgpO1xuXHRsZXQgX3RpbWVycztcblx0Y29uc3QgdGltZXJzID0gKCkgPT4gX3RpbWVycyB8fD0gbmV3IEZha2VUaW1lcnMoe1xuXHRcdGdsb2JhbDogZ2xvYmFsVGhpcyxcblx0XHRjb25maWc6IHN0YXRlKCkuY29uZmlnLmZha2VUaW1lcnNcblx0fSk7XG5cdGNvbnN0IF9zdHVic0dsb2JhbCA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCk7XG5cdGNvbnN0IF9zdHVic0VudiA9IC8qIEBfX1BVUkVfXyAqLyBuZXcgTWFwKCk7XG5cdGNvbnN0IF9lbnZCb29sZWFucyA9IFtcblx0XHRcIlBST0RcIixcblx0XHRcIkRFVlwiLFxuXHRcdFwiU1NSXCJcblx0XTtcblx0Y29uc3QgdXRpbHMgPSB7XG5cdFx0dXNlRmFrZVRpbWVycyhjb25maWcpIHtcblx0XHRcdGlmIChpc0NoaWxkUHJvY2VzcygpKSB7XG5cdFx0XHRcdGlmIChjb25maWc/LnRvRmFrZT8uaW5jbHVkZXMoXCJuZXh0VGlja1wiKSB8fCBzdGF0ZSgpLmNvbmZpZz8uZmFrZVRpbWVycz8udG9GYWtlPy5pbmNsdWRlcyhcIm5leHRUaWNrXCIpKSB0aHJvdyBuZXcgRXJyb3IoXCJ2aS51c2VGYWtlVGltZXJzKHsgdG9GYWtlOiBbXFxcIm5leHRUaWNrXFxcIl0gfSkgaXMgbm90IHN1cHBvcnRlZCBpbiBub2RlOmNoaWxkX3Byb2Nlc3MuIFVzZSAtLXBvb2w9dGhyZWFkcyBpZiBtb2NraW5nIG5leHRUaWNrIGlzIHJlcXVpcmVkLlwiKTtcblx0XHRcdH1cblx0XHRcdGlmIChjb25maWcpIHRpbWVycygpLmNvbmZpZ3VyZSh7XG5cdFx0XHRcdC4uLnN0YXRlKCkuY29uZmlnLmZha2VUaW1lcnMsXG5cdFx0XHRcdC4uLmNvbmZpZ1xuXHRcdFx0fSk7XG5cdFx0XHRlbHNlIHRpbWVycygpLmNvbmZpZ3VyZShzdGF0ZSgpLmNvbmZpZy5mYWtlVGltZXJzKTtcblx0XHRcdHRpbWVycygpLnVzZUZha2VUaW1lcnMoKTtcblx0XHRcdHJldHVybiB1dGlscztcblx0XHR9LFxuXHRcdGlzRmFrZVRpbWVycygpIHtcblx0XHRcdHJldHVybiB0aW1lcnMoKS5pc0Zha2VUaW1lcnMoKTtcblx0XHR9LFxuXHRcdHVzZVJlYWxUaW1lcnMoKSB7XG5cdFx0XHR0aW1lcnMoKS51c2VSZWFsVGltZXJzKCk7XG5cdFx0XHRyZXR1cm4gdXRpbHM7XG5cdFx0fSxcblx0XHRydW5Pbmx5UGVuZGluZ1RpbWVycygpIHtcblx0XHRcdHRpbWVycygpLnJ1bk9ubHlQZW5kaW5nVGltZXJzKCk7XG5cdFx0XHRyZXR1cm4gdXRpbHM7XG5cdFx0fSxcblx0XHRhc3luYyBydW5Pbmx5UGVuZGluZ1RpbWVyc0FzeW5jKCkge1xuXHRcdFx0YXdhaXQgdGltZXJzKCkucnVuT25seVBlbmRpbmdUaW1lcnNBc3luYygpO1xuXHRcdFx0cmV0dXJuIHV0aWxzO1xuXHRcdH0sXG5cdFx0cnVuQWxsVGltZXJzKCkge1xuXHRcdFx0dGltZXJzKCkucnVuQWxsVGltZXJzKCk7XG5cdFx0XHRyZXR1cm4gdXRpbHM7XG5cdFx0fSxcblx0XHRhc3luYyBydW5BbGxUaW1lcnNBc3luYygpIHtcblx0XHRcdGF3YWl0IHRpbWVycygpLnJ1bkFsbFRpbWVyc0FzeW5jKCk7XG5cdFx0XHRyZXR1cm4gdXRpbHM7XG5cdFx0fSxcblx0XHRydW5BbGxUaWNrcygpIHtcblx0XHRcdHRpbWVycygpLnJ1bkFsbFRpY2tzKCk7XG5cdFx0XHRyZXR1cm4gdXRpbHM7XG5cdFx0fSxcblx0XHRhZHZhbmNlVGltZXJzQnlUaW1lKG1zKSB7XG5cdFx0XHR0aW1lcnMoKS5hZHZhbmNlVGltZXJzQnlUaW1lKG1zKTtcblx0XHRcdHJldHVybiB1dGlscztcblx0XHR9LFxuXHRcdGFzeW5jIGFkdmFuY2VUaW1lcnNCeVRpbWVBc3luYyhtcykge1xuXHRcdFx0YXdhaXQgdGltZXJzKCkuYWR2YW5jZVRpbWVyc0J5VGltZUFzeW5jKG1zKTtcblx0XHRcdHJldHVybiB1dGlscztcblx0XHR9LFxuXHRcdGFkdmFuY2VUaW1lcnNUb05leHRUaW1lcigpIHtcblx0XHRcdHRpbWVycygpLmFkdmFuY2VUaW1lcnNUb05leHRUaW1lcigpO1xuXHRcdFx0cmV0dXJuIHV0aWxzO1xuXHRcdH0sXG5cdFx0YXN5bmMgYWR2YW5jZVRpbWVyc1RvTmV4dFRpbWVyQXN5bmMoKSB7XG5cdFx0XHRhd2FpdCB0aW1lcnMoKS5hZHZhbmNlVGltZXJzVG9OZXh0VGltZXJBc3luYygpO1xuXHRcdFx0cmV0dXJuIHV0aWxzO1xuXHRcdH0sXG5cdFx0YWR2YW5jZVRpbWVyc1RvTmV4dEZyYW1lKCkge1xuXHRcdFx0dGltZXJzKCkuYWR2YW5jZVRpbWVyc1RvTmV4dEZyYW1lKCk7XG5cdFx0XHRyZXR1cm4gdXRpbHM7XG5cdFx0fSxcblx0XHRnZXRUaW1lckNvdW50KCkge1xuXHRcdFx0cmV0dXJuIHRpbWVycygpLmdldFRpbWVyQ291bnQoKTtcblx0XHR9LFxuXHRcdHNldFN5c3RlbVRpbWUodGltZSkge1xuXHRcdFx0dGltZXJzKCkuc2V0U3lzdGVtVGltZSh0aW1lKTtcblx0XHRcdHJldHVybiB1dGlscztcblx0XHR9LFxuXHRcdGdldE1vY2tlZFN5c3RlbVRpbWUoKSB7XG5cdFx0XHRyZXR1cm4gdGltZXJzKCkuZ2V0TW9ja2VkU3lzdGVtVGltZSgpO1xuXHRcdH0sXG5cdFx0Z2V0UmVhbFN5c3RlbVRpbWUoKSB7XG5cdFx0XHRyZXR1cm4gdGltZXJzKCkuZ2V0UmVhbFN5c3RlbVRpbWUoKTtcblx0XHR9LFxuXHRcdGNsZWFyQWxsVGltZXJzKCkge1xuXHRcdFx0dGltZXJzKCkuY2xlYXJBbGxUaW1lcnMoKTtcblx0XHRcdHJldHVybiB1dGlscztcblx0XHR9LFxuXHRcdHNldFRpbWVyVGlja01vZGUobW9kZSwgaW50ZXJ2YWwpIHtcblx0XHRcdHRpbWVycygpLnNldFRpbWVyVGlja01vZGUobW9kZSwgaW50ZXJ2YWwpO1xuXHRcdFx0cmV0dXJuIHV0aWxzO1xuXHRcdH0sXG5cdFx0c3B5T24sXG5cdFx0Zm4sXG5cdFx0d2FpdEZvcixcblx0XHR3YWl0VW50aWwsXG5cdFx0ZGVmaW5lSGVscGVyOiAoZm4pID0+IHtcblx0XHRcdHJldHVybiBmdW5jdGlvbiBfX1ZJVEVTVF9IRUxQRVJfXyguLi5hcmdzKSB7XG5cdFx0XHRcdGNvbnN0IHJlc3VsdCA9IGZuLmFwcGx5KHRoaXMsIGFyZ3MpO1xuXHRcdFx0XHRpZiAocmVzdWx0ICYmIHR5cGVvZiByZXN1bHQgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIHJlc3VsdC50aGVuID09PSBcImZ1bmN0aW9uXCIpIHJldHVybiAoYXN5bmMgZnVuY3Rpb24gX19WSVRFU1RfSEVMUEVSX18oKSB7XG5cdFx0XHRcdFx0cmV0dXJuIGF3YWl0IHJlc3VsdDtcblx0XHRcdFx0fSkoKTtcblx0XHRcdFx0cmV0dXJuIHJlc3VsdDtcblx0XHRcdH07XG5cdFx0fSxcblx0XHRob2lzdGVkKGZhY3RvcnkpIHtcblx0XHRcdGFzc2VydFR5cGVzKGZhY3RvcnksIFwiXFxcInZpLmhvaXN0ZWRcXFwiIGZhY3RvcnlcIiwgW1wiZnVuY3Rpb25cIl0pO1xuXHRcdFx0cmV0dXJuIGZhY3RvcnkoKTtcblx0XHR9LFxuXHRcdG1vY2socGF0aCwgZmFjdG9yeSkge1xuXHRcdFx0aWYgKHR5cGVvZiBwYXRoICE9PSBcInN0cmluZ1wiKSB0aHJvdyBuZXcgVHlwZUVycm9yKGB2aS5tb2NrKCkgZXhwZWN0cyBhIHN0cmluZyBwYXRoLCBidXQgcmVjZWl2ZWQgYSAke3R5cGVvZiBwYXRofWApO1xuXHRcdFx0Y29uc3QgaW1wb3J0ZXIgPSBnZXRJbXBvcnRlcihcIm1vY2tcIik7XG5cdFx0XHRfbW9ja2VyKCkucXVldWVNb2NrKHBhdGgsIGltcG9ydGVyLCB0eXBlb2YgZmFjdG9yeSA9PT0gXCJmdW5jdGlvblwiID8gKCkgPT4gZmFjdG9yeSgoKSA9PiBfbW9ja2VyKCkuaW1wb3J0QWN0dWFsKHBhdGgsIGltcG9ydGVyLCBfbW9ja2VyKCkuZ2V0TW9ja0NvbnRleHQoKS5jYWxsc3RhY2spKSA6IGZhY3RvcnkpO1xuXHRcdH0sXG5cdFx0dW5tb2NrKHBhdGgpIHtcblx0XHRcdGlmICh0eXBlb2YgcGF0aCAhPT0gXCJzdHJpbmdcIikgdGhyb3cgbmV3IFR5cGVFcnJvcihgdmkudW5tb2NrKCkgZXhwZWN0cyBhIHN0cmluZyBwYXRoLCBidXQgcmVjZWl2ZWQgYSAke3R5cGVvZiBwYXRofWApO1xuXHRcdFx0X21vY2tlcigpLnF1ZXVlVW5tb2NrKHBhdGgsIGdldEltcG9ydGVyKFwidW5tb2NrXCIpKTtcblx0XHR9LFxuXHRcdGRvTW9jayhwYXRoLCBmYWN0b3J5KSB7XG5cdFx0XHRpZiAodHlwZW9mIHBhdGggIT09IFwic3RyaW5nXCIpIHRocm93IG5ldyBUeXBlRXJyb3IoYHZpLmRvTW9jaygpIGV4cGVjdHMgYSBzdHJpbmcgcGF0aCwgYnV0IHJlY2VpdmVkIGEgJHt0eXBlb2YgcGF0aH1gKTtcblx0XHRcdGNvbnN0IGltcG9ydGVyID0gZ2V0SW1wb3J0ZXIoXCJkb01vY2tcIik7XG5cdFx0XHRfbW9ja2VyKCkucXVldWVNb2NrKHBhdGgsIGltcG9ydGVyLCB0eXBlb2YgZmFjdG9yeSA9PT0gXCJmdW5jdGlvblwiID8gKCkgPT4gZmFjdG9yeSgoKSA9PiBfbW9ja2VyKCkuaW1wb3J0QWN0dWFsKHBhdGgsIGltcG9ydGVyLCBfbW9ja2VyKCkuZ2V0TW9ja0NvbnRleHQoKS5jYWxsc3RhY2spKSA6IGZhY3RvcnkpO1xuXHRcdFx0Y29uc3QgcnYgPSB7fTtcblx0XHRcdGlmIChTeW1ib2wuZGlzcG9zZSkgcnZbU3ltYm9sLmRpc3Bvc2VdID0gKCkgPT4ge1xuXHRcdFx0XHRfbW9ja2VyKCkucXVldWVVbm1vY2socGF0aCwgaW1wb3J0ZXIpO1xuXHRcdFx0fTtcblx0XHRcdHJldHVybiBydjtcblx0XHR9LFxuXHRcdGRvVW5tb2NrKHBhdGgpIHtcblx0XHRcdGlmICh0eXBlb2YgcGF0aCAhPT0gXCJzdHJpbmdcIikgdGhyb3cgbmV3IFR5cGVFcnJvcihgdmkuZG9Vbm1vY2soKSBleHBlY3RzIGEgc3RyaW5nIHBhdGgsIGJ1dCByZWNlaXZlZCBhICR7dHlwZW9mIHBhdGh9YCk7XG5cdFx0XHRjb25zdCBpbXBvcnRlciA9IGdldEltcG9ydGVyKFwiZG9Vbm1vY2tcIik7XG5cdFx0XHRfbW9ja2VyKCkucXVldWVVbm1vY2socGF0aCwgaW1wb3J0ZXIpO1xuXHRcdH0sXG5cdFx0YXN5bmMgaW1wb3J0QWN0dWFsKHBhdGgpIHtcblx0XHRcdGNvbnN0IGltcG9ydGVyID0gZ2V0SW1wb3J0ZXIoXCJpbXBvcnRBY3R1YWxcIik7XG5cdFx0XHRyZXR1cm4gX21vY2tlcigpLmltcG9ydEFjdHVhbChwYXRoLCBpbXBvcnRlciwgX21vY2tlcigpLmdldE1vY2tDb250ZXh0KCkuY2FsbHN0YWNrKTtcblx0XHR9LFxuXHRcdGFzeW5jIGltcG9ydE1vY2socGF0aCkge1xuXHRcdFx0Y29uc3QgaW1wb3J0ZXIgPSBnZXRJbXBvcnRlcihcImltcG9ydE1vY2tcIik7XG5cdFx0XHRyZXR1cm4gX21vY2tlcigpLmltcG9ydE1vY2socGF0aCwgaW1wb3J0ZXIpO1xuXHRcdH0sXG5cdFx0bW9ja09iamVjdCh2YWx1ZSwgb3B0aW9ucykge1xuXHRcdFx0cmV0dXJuIF9tb2NrZXIoKS5tb2NrT2JqZWN0KHsgdmFsdWUgfSwgdm9pZCAwLCBvcHRpb25zPy5zcHkgPyBcImF1dG9zcHlcIiA6IFwiYXV0b21vY2tcIikudmFsdWU7XG5cdFx0fSxcblx0XHRtb2NrZWQoaXRlbSwgX29wdGlvbnMgPSB7fSkge1xuXHRcdFx0cmV0dXJuIGl0ZW07XG5cdFx0fSxcblx0XHRpc01vY2tGdW5jdGlvbihmbikge1xuXHRcdFx0cmV0dXJuIGlzTW9ja0Z1bmN0aW9uKGZuKTtcblx0XHR9LFxuXHRcdGNsZWFyQWxsTW9ja3MoKSB7XG5cdFx0XHRjbGVhckFsbE1vY2tzKCk7XG5cdFx0XHRyZXR1cm4gdXRpbHM7XG5cdFx0fSxcblx0XHRyZXNldEFsbE1vY2tzKCkge1xuXHRcdFx0cmVzZXRBbGxNb2NrcygpO1xuXHRcdFx0cmV0dXJuIHV0aWxzO1xuXHRcdH0sXG5cdFx0cmVzdG9yZUFsbE1vY2tzKCkge1xuXHRcdFx0cmVzdG9yZUFsbE1vY2tzKCk7XG5cdFx0XHRyZXR1cm4gdXRpbHM7XG5cdFx0fSxcblx0XHRzdHViR2xvYmFsKG5hbWUsIHZhbHVlKSB7XG5cdFx0XHRpZiAoIV9zdHVic0dsb2JhbC5oYXMobmFtZSkpIF9zdHVic0dsb2JhbC5zZXQobmFtZSwgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihnbG9iYWxUaGlzLCBuYW1lKSk7XG5cdFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoZ2xvYmFsVGhpcywgbmFtZSwge1xuXHRcdFx0XHR2YWx1ZSxcblx0XHRcdFx0d3JpdGFibGU6IHRydWUsXG5cdFx0XHRcdGNvbmZpZ3VyYWJsZTogdHJ1ZSxcblx0XHRcdFx0ZW51bWVyYWJsZTogdHJ1ZVxuXHRcdFx0fSk7XG5cdFx0XHRyZXR1cm4gdXRpbHM7XG5cdFx0fSxcblx0XHRzdHViRW52KG5hbWUsIHZhbHVlKSB7XG5cdFx0XHRjb25zdCBlbnYgPSBzdGF0ZSgpLm1ldGFFbnY7XG5cdFx0XHRpZiAoIV9zdHVic0Vudi5oYXMobmFtZSkpIF9zdHVic0Vudi5zZXQobmFtZSwgZW52W25hbWVdKTtcblx0XHRcdGlmIChfZW52Qm9vbGVhbnMuaW5jbHVkZXMobmFtZSkpIGVudltuYW1lXSA9IHZhbHVlID8gXCIxXCIgOiBcIlwiO1xuXHRcdFx0ZWxzZSBpZiAodmFsdWUgPT09IHZvaWQgMCkgZGVsZXRlIGVudltuYW1lXTtcblx0XHRcdGVsc2UgZW52W25hbWVdID0gU3RyaW5nKHZhbHVlKTtcblx0XHRcdHJldHVybiB1dGlscztcblx0XHR9LFxuXHRcdHVuc3R1YkFsbEdsb2JhbHMoKSB7XG5cdFx0XHRfc3R1YnNHbG9iYWwuZm9yRWFjaCgob3JpZ2luYWwsIG5hbWUpID0+IHtcblx0XHRcdFx0aWYgKCFvcmlnaW5hbCkgUmVmbGVjdC5kZWxldGVQcm9wZXJ0eShnbG9iYWxUaGlzLCBuYW1lKTtcblx0XHRcdFx0ZWxzZSBPYmplY3QuZGVmaW5lUHJvcGVydHkoZ2xvYmFsVGhpcywgbmFtZSwgb3JpZ2luYWwpO1xuXHRcdFx0fSk7XG5cdFx0XHRfc3R1YnNHbG9iYWwuY2xlYXIoKTtcblx0XHRcdHJldHVybiB1dGlscztcblx0XHR9LFxuXHRcdHVuc3R1YkFsbEVudnMoKSB7XG5cdFx0XHRjb25zdCBlbnYgPSBzdGF0ZSgpLm1ldGFFbnY7XG5cdFx0XHRfc3R1YnNFbnYuZm9yRWFjaCgob3JpZ2luYWwsIG5hbWUpID0+IHtcblx0XHRcdFx0aWYgKG9yaWdpbmFsID09PSB2b2lkIDApIGRlbGV0ZSBlbnZbbmFtZV07XG5cdFx0XHRcdGVsc2UgZW52W25hbWVdID0gb3JpZ2luYWw7XG5cdFx0XHR9KTtcblx0XHRcdF9zdHVic0Vudi5jbGVhcigpO1xuXHRcdFx0cmV0dXJuIHV0aWxzO1xuXHRcdH0sXG5cdFx0cmVzZXRNb2R1bGVzKCkge1xuXHRcdFx0cmVzZXRNb2R1bGVzKHN0YXRlKCkuZXZhbHVhdGVkTW9kdWxlcyk7XG5cdFx0XHRyZXR1cm4gdXRpbHM7XG5cdFx0fSxcblx0XHRhc3luYyBkeW5hbWljSW1wb3J0U2V0dGxlZCgpIHtcblx0XHRcdHJldHVybiB3YWl0Rm9ySW1wb3J0c1RvUmVzb2x2ZSgpO1xuXHRcdH0sXG5cdFx0c2V0Q29uZmlnKGNvbmZpZykge1xuXHRcdFx0aWYgKCFfY29uZmlnKSBfY29uZmlnID0geyAuLi5zdGF0ZSgpLmNvbmZpZyB9O1xuXHRcdFx0T2JqZWN0LmFzc2lnbihzdGF0ZSgpLmNvbmZpZywgY29uZmlnKTtcblx0XHR9LFxuXHRcdHJlc2V0Q29uZmlnKCkge1xuXHRcdFx0aWYgKF9jb25maWcpIE9iamVjdC5hc3NpZ24oc3RhdGUoKS5jb25maWcsIF9jb25maWcpO1xuXHRcdH1cblx0fTtcblx0cmV0dXJuIHV0aWxzO1xufVxuY29uc3Qgdml0ZXN0ID0gY3JlYXRlVml0ZXN0KCk7XG5jb25zdCB2aSA9IHZpdGVzdDtcbmZ1bmN0aW9uIF9tb2NrZXIoKSB7XG5cdC8vIEB0cy1leHBlY3QtZXJyb3IgaW5qZWN0ZWQgYnkgdml0ZS1uaWRlXG5cdHJldHVybiB0eXBlb2YgX192aXRlc3RfbW9ja2VyX18gIT09IFwidW5kZWZpbmVkXCIgPyBfX3ZpdGVzdF9tb2NrZXJfXyA6IG5ldyBQcm94eSh7fSwgeyBnZXQoXywgbmFtZSkge1xuXHRcdHRocm93IG5ldyBFcnJvcihgVml0ZXN0IG1vY2tlciB3YXMgbm90IGluaXRpYWxpemVkIGluIHRoaXMgZW52aXJvbm1lbnQuIHZpLiR7U3RyaW5nKG5hbWUpfSgpIGlzIGZvcmJpZGRlbi5gKTtcblx0fSB9KTtcbn1cbmZ1bmN0aW9uIGdldEltcG9ydGVyKG5hbWUpIHtcblx0Y29uc3Qgc3RhY2tBcnJheSA9IGNyZWF0ZVNpbXBsZVN0YWNrVHJhY2UoeyBzdGFja1RyYWNlTGltaXQ6IDUgfSkuc3BsaXQoXCJcXG5cIik7XG5cdHJldHVybiBwYXJzZVNpbmdsZVN0YWNrKHN0YWNrQXJyYXlbc3RhY2tBcnJheS5maW5kTGFzdEluZGV4KChzdGFjaykgPT4ge1xuXHRcdHJldHVybiBzdGFjay5pbmNsdWRlcyhgIGF0IE9iamVjdC4ke25hbWV9YCkgfHwgc3RhY2suaW5jbHVkZXMoYCR7bmFtZX1AYCkgfHwgc3RhY2suaW5jbHVkZXMoYCBhdCAke25hbWV9IChgKTtcblx0fSkgKyAxXSk/LmZpbGUgfHwgXCJcIjtcbn1cblxuLy8gdGhlc2UgbWF0Y2hlcnMgYXJlIG5vdCBzdXBwb3J0ZWQgYmVjYXVzZSB0aGV5IGRvbid0IG1ha2Ugc2Vuc2Ugd2l0aCBwb2xsXG5jb25zdCB1bnN1cHBvcnRlZCA9IFtcblx0XCJtYXRjaFNuYXBzaG90XCIsXG5cdFwidG9NYXRjaFNuYXBzaG90XCIsXG5cdFwidG9NYXRjaElubGluZVNuYXBzaG90XCIsXG5cdFwidG9UaHJvd0Vycm9yTWF0Y2hpbmdTbmFwc2hvdFwiLFxuXHRcInRvVGhyb3dFcnJvck1hdGNoaW5nSW5saW5lU25hcHNob3RcIixcblx0XCJ0aHJvd3NcIixcblx0XCJUaHJvd1wiLFxuXHRcInRocm93XCIsXG5cdFwidG9UaHJvd1wiLFxuXHRcInRvVGhyb3dFcnJvclwiXG5dO1xuLyoqXG4qIEF0dGFjaGVzIGEgYGNhdXNlYCBwcm9wZXJ0eSB0byB0aGUgZXJyb3IgaWYgbWlzc2luZywgY29waWVzIHRoZSBzdGFjayB0cmFjZSBmcm9tIHRoZSBzb3VyY2UsIGFuZCB0aHJvd3MuXG4qXG4qIEBwYXJhbSBlcnJvciAtIFRoZSBlcnJvciB0byB0aHJvd1xuKiBAcGFyYW0gc291cmNlIC0gRXJyb3IgdG8gY29weSB0aGUgc3RhY2sgdHJhY2UgZnJvbVxuKlxuKiBAdGhyb3dzIEFsd2F5cyB0aHJvd3MgdGhlIHByb3ZpZGVkIGVycm9yIHdpdGggYW4gYW1lbmRlZCBzdGFjayB0cmFjZVxuKi9cbmZ1bmN0aW9uIHRocm93V2l0aENhdXNlKGVycm9yLCBzb3VyY2UpIHtcblx0aWYgKGVycm9yLmNhdXNlID09IG51bGwpIGVycm9yLmNhdXNlID0gLyogQF9fUFVSRV9fICovIG5ldyBFcnJvcihcIk1hdGNoZXIgZGlkIG5vdCBzdWNjZWVkIGluIHRpbWUuXCIpO1xuXHR0aHJvdyBjb3B5U3RhY2tUcmFjZShlcnJvciwgc291cmNlKTtcbn1cbmZ1bmN0aW9uIGNyZWF0ZUV4cGVjdFBvbGwoZXhwZWN0KSB7XG5cdHJldHVybiBmdW5jdGlvbiBwb2xsKGZuLCBvcHRpb25zID0ge30pIHtcblx0XHRjb25zdCBkZWZhdWx0cyA9IGdldFdvcmtlclN0YXRlKCkuY29uZmlnLmV4cGVjdD8ucG9sbCA/PyB7fTtcblx0XHRjb25zdCB7IGludGVydmFsID0gZGVmYXVsdHMuaW50ZXJ2YWwgPz8gNTAsIHRpbWVvdXQgPSBkZWZhdWx0cy50aW1lb3V0ID8/IDFlMywgbWVzc2FnZSB9ID0gb3B0aW9ucztcblx0XHQvLyBAdHMtZXhwZWN0LWVycm9yIHByaXZhdGUgcG9sbCBhY2Nlc3Ncblx0XHRjb25zdCBhc3NlcnRpb24gPSBleHBlY3QobnVsbCwgbWVzc2FnZSkud2l0aENvbnRleHQoeyBwb2xsOiB0cnVlIH0pO1xuXHRcdGZuID0gZm4uYmluZChhc3NlcnRpb24pO1xuXHRcdC8vIGluamVjdGVkIHNvIHRoYXQgZG9tYWluIHNuYXBzaG90IGNhbiB0YWtlIG92ZXIgcG9sbCBpbXBsZW1lbnRhdGlvbi5cblx0XHRjaGFpLnV0aWwuZmxhZyhhc3NlcnRpb24sIFwiX3BvbGwuZm5cIiwgZm4pO1xuXHRcdGNoYWkudXRpbC5mbGFnKGFzc2VydGlvbiwgXCJfcG9sbC50aW1lb3V0XCIsIHRpbWVvdXQpO1xuXHRcdGNoYWkudXRpbC5mbGFnKGFzc2VydGlvbiwgXCJfcG9sbC5pbnRlcnZhbFwiLCBpbnRlcnZhbCk7XG5cdFx0Y29uc3QgdGVzdCA9IGNoYWkudXRpbC5mbGFnKGFzc2VydGlvbiwgXCJ2aXRlc3QtdGVzdFwiKTtcblx0XHRpZiAoIXRlc3QpIHRocm93IG5ldyBFcnJvcihcImV4cGVjdC5wb2xsKCkgbXVzdCBiZSBjYWxsZWQgaW5zaWRlIGEgdGVzdFwiKTtcblx0XHRjb25zdCBwcm94eSA9IG5ldyBQcm94eShhc3NlcnRpb24sIHsgZ2V0KHRhcmdldCwga2V5LCByZWNlaXZlcikge1xuXHRcdFx0Y29uc3QgYXNzZXJ0aW9uRnVuY3Rpb24gPSBSZWZsZWN0LmdldCh0YXJnZXQsIGtleSwgcmVjZWl2ZXIpO1xuXHRcdFx0aWYgKHR5cGVvZiBhc3NlcnRpb25GdW5jdGlvbiAhPT0gXCJmdW5jdGlvblwiKSByZXR1cm4gYXNzZXJ0aW9uRnVuY3Rpb24gaW5zdGFuY2VvZiBjaGFpLkFzc2VydGlvbiA/IHByb3h5IDogYXNzZXJ0aW9uRnVuY3Rpb247XG5cdFx0XHRpZiAoa2V5ID09PSBcImFzc2VydFwiKSByZXR1cm4gYXNzZXJ0aW9uRnVuY3Rpb247XG5cdFx0XHRpZiAodHlwZW9mIGtleSA9PT0gXCJzdHJpbmdcIiAmJiB1bnN1cHBvcnRlZC5pbmNsdWRlcyhrZXkpKSB0aHJvdyBuZXcgU3ludGF4RXJyb3IoYGV4cGVjdC5wb2xsKCkgaXMgbm90IHN1cHBvcnRlZCBpbiBjb21iaW5hdGlvbiB3aXRoIC4ke2tleX0oKS4gVXNlIHZpLndhaXRGb3IoKSBpZiB5b3VyIGFzc2VydGlvbiBjb25kaXRpb24gaXMgdW5zdGFibGUuYCk7XG5cdFx0XHQvLyBDb3JlIHBvbGwgc3RhY2stdHJhY2UgdHJpY2s6XG5cdFx0XHQvLyAgIDEuIGNhcHR1cmUgU1RBQ0tfVFJBQ0VfRVJST1IgaGVyZSBiZWZvcmUgZW50ZXJpbmcgdGhlIGFzeW5jIHBvbGwgbG9vcFxuXHRcdFx0Ly8gICAyLiB3aGVuIHRoZSBtYXRjaGVyIGV2ZW50dWFsbHkgZmFpbHMsIHJldGhyb3cgdmlhIHRocm93V2l0aENhdXNlKClcblx0XHRcdC8vICAgICAgc28gdGhlIGZpbmFsIGVycm9yIGtlZXBzIHRoaXMgZWFybGllciBzdGFja1xuXHRcdFx0Ly9cblx0XHRcdC8vIEZvciBleGFtcGxlLCB3aGVuIHVzZXIgd3JpdGVzOlxuXHRcdFx0Ly8gICAgYXdhaXQgZXhwZWN0LnBvbGwoLi4uKS50b0JlU29tZXRoaW5nKClcblx0XHRcdC8vIFNUQUNLX1RSQUNFX0VSUk9SLnN0YWNrIHdvdWxkIGxvb2sgbGlrZVxuXHRcdFx0Ly8gICBhdCAuLi4obW9yZSBpbnRlcm5hbCBzdGFja3MpLi4uXG5cdFx0XHQvLyAgIGF0IF9fVklURVNUX1BPTExfQ0hBSU5fXyAuLi4vcGFja2FnZXMvdml0ZXN0L2Rpc3QvLi4uXG5cdFx0XHQvLyAgIGF0IC4uLi9teS1maWxlLnRlc3QudHM6MTI6MyAgICh0aGlzIHBvaW50cyB0byBgdG9CZVNvbWV0aGluZygpYCBjYWxsc2l0ZSBpbiB1c2VyIHRlc3QgZmlsZSlcblx0XHRcdC8vIFZpdGVzdCBsYXRlciBmaWx0ZXJzIG91dCBpbnRlcm5hbCBzdGFja3MgZnJvbSBgdml0ZXN0L2Rpc3RgLCBzbyB0aGUgcmVwb3J0ZWQgZXJyb3JzIGNvcnJlY3RseVxuXHRcdFx0Ly8gcG9pbnRzIHRvIHRoZSB1c2VyIGNhbGxzaXRlIGZvciBwb2xsIGFzc2VydGlvbiBlcnJvcnMuXG5cdFx0XHQvL1xuXHRcdFx0Ly8gSW5saW5lIHNuYXBzaG90cyBwaWdneWJhY2sgb24gdGhlIHNhbWUgaWRlYS4gV2UgcGFzc1xuXHRcdFx0Ly8gU1RBQ0tfVFJBQ0VfRVJST1IgdGhyb3VnaCBgY2hhaS51dGlsLmZsYWcoYXNzZXJ0aW9uLCAnZXJyb3InLCAuLi4pYC5cblx0XHRcdC8vIElubGluZSBzbmFwc2hvdCBhc3NlcnRpb24gYWNjZXNzIHRoZSBzYW1lIGVycm9yIHN0YWNrIGZvclxuXHRcdFx0Ly8gZXh0cmFjdGluZyBpbmxpbmUgc25hcHNob3QgbG9jYXRpb24gdG8gdmFsaWRhdGUgYW5kIHVwZGF0ZSBuZXcgc25hcHNob3RzLlxuXHRcdFx0cmV0dXJuIGZ1bmN0aW9uIF9fVklURVNUX1BPTExfQ0hBSU5fXyguLi5hcmdzKSB7XG5cdFx0XHRcdGNvbnN0IFNUQUNLX1RSQUNFX0VSUk9SID0gLyogQF9fUFVSRV9fICovIG5ldyBFcnJvcihcIlNUQUNLX1RSQUNFX0VSUk9SXCIpO1xuXHRcdFx0XHRjb25zdCBwcm9taXNlID0gYXN5bmMgKCkgPT4ge1xuXHRcdFx0XHRcdGNoYWkudXRpbC5mbGFnKGFzc2VydGlvbiwgXCJfbmFtZVwiLCBrZXkpO1xuXHRcdFx0XHRcdGNoYWkudXRpbC5mbGFnKGFzc2VydGlvbiwgXCJlcnJvclwiLCBTVEFDS19UUkFDRV9FUlJPUik7XG5cdFx0XHRcdFx0Y29uc3Qgb25TZXR0bGVkID0gY2hhaS51dGlsLmZsYWcoYXNzZXJ0aW9uLCBcIl9wb2xsLm9uU2V0dGxlZFwiKTtcblx0XHRcdFx0XHRpZiAoT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihhc3NlcnRpb25GdW5jdGlvbiwgXCJfX3ZpdGVzdF9wb2xsX3Rha2VvdmVyX19cIik/LnZhbHVlKSB0cnkge1xuXHRcdFx0XHRcdFx0Y29uc3Qgb3V0cHV0ID0gYXdhaXQgYXNzZXJ0aW9uRnVuY3Rpb24uY2FsbChhc3NlcnRpb24sIC4uLmFyZ3MpO1xuXHRcdFx0XHRcdFx0YXdhaXQgb25TZXR0bGVkPy4oe1xuXHRcdFx0XHRcdFx0XHRhc3NlcnRpb24sXG5cdFx0XHRcdFx0XHRcdHN0YXR1czogXCJwYXNzXCJcblx0XHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdFx0cmV0dXJuIG91dHB1dDtcblx0XHRcdFx0XHR9IGNhdGNoIChlcnIpIHtcblx0XHRcdFx0XHRcdGF3YWl0IG9uU2V0dGxlZD8uKHtcblx0XHRcdFx0XHRcdFx0YXNzZXJ0aW9uLFxuXHRcdFx0XHRcdFx0XHRzdGF0dXM6IFwiZmFpbFwiXG5cdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHRcdHRocm93V2l0aENhdXNlKGVyciwgU1RBQ0tfVFJBQ0VfRVJST1IpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRjb25zdCB7IHNldFRpbWVvdXQsIGNsZWFyVGltZW91dCB9ID0gZ2V0U2FmZVRpbWVycygpO1xuXHRcdFx0XHRcdGxldCBleGVjdXRpb25QaGFzZSA9IFwiZm5cIjtcblx0XHRcdFx0XHRsZXQgaGFzVGltZWRPdXQgPSBmYWxzZTtcblx0XHRcdFx0XHRjb25zdCB0aW1lcklkID0gc2V0VGltZW91dCgoKSA9PiB7XG5cdFx0XHRcdFx0XHRoYXNUaW1lZE91dCA9IHRydWU7XG5cdFx0XHRcdFx0fSwgdGltZW91dCk7XG5cdFx0XHRcdFx0dHJ5IHtcblx0XHRcdFx0XHRcdHdoaWxlICh0cnVlKSB7XG5cdFx0XHRcdFx0XHRcdGNvbnN0IGlzTGFzdEF0dGVtcHQgPSBoYXNUaW1lZE91dDtcblx0XHRcdFx0XHRcdFx0aWYgKGlzTGFzdEF0dGVtcHQpIGNoYWkudXRpbC5mbGFnKGFzc2VydGlvbiwgXCJfaXNMYXN0UG9sbEF0dGVtcHRcIiwgdHJ1ZSk7XG5cdFx0XHRcdFx0XHRcdHRyeSB7XG5cdFx0XHRcdFx0XHRcdFx0ZXhlY3V0aW9uUGhhc2UgPSBcImZuXCI7XG5cdFx0XHRcdFx0XHRcdFx0Y29uc3Qgb2JqID0gYXdhaXQgZm4oKTtcblx0XHRcdFx0XHRcdFx0XHRjaGFpLnV0aWwuZmxhZyhhc3NlcnRpb24sIFwib2JqZWN0XCIsIG9iaik7XG5cdFx0XHRcdFx0XHRcdFx0ZXhlY3V0aW9uUGhhc2UgPSBcImFzc2VydGlvblwiO1xuXHRcdFx0XHRcdFx0XHRcdGNvbnN0IG91dHB1dCA9IGF3YWl0IGFzc2VydGlvbkZ1bmN0aW9uLmNhbGwoYXNzZXJ0aW9uLCAuLi5hcmdzKTtcblx0XHRcdFx0XHRcdFx0XHRhd2FpdCBvblNldHRsZWQ/Lih7XG5cdFx0XHRcdFx0XHRcdFx0XHRhc3NlcnRpb24sXG5cdFx0XHRcdFx0XHRcdFx0XHRzdGF0dXM6IFwicGFzc1wiXG5cdFx0XHRcdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0XHRcdFx0cmV0dXJuIG91dHB1dDtcblx0XHRcdFx0XHRcdFx0fSBjYXRjaCAoZXJyKSB7XG5cdFx0XHRcdFx0XHRcdFx0aWYgKGlzTGFzdEF0dGVtcHQgfHwgZXhlY3V0aW9uUGhhc2UgPT09IFwiYXNzZXJ0aW9uXCIgJiYgY2hhaS51dGlsLmZsYWcoYXNzZXJ0aW9uLCBcIl9wb2xsLmFzc2VydF9vbmNlXCIpKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRhd2FpdCBvblNldHRsZWQ/Lih7XG5cdFx0XHRcdFx0XHRcdFx0XHRcdGFzc2VydGlvbixcblx0XHRcdFx0XHRcdFx0XHRcdFx0c3RhdHVzOiBcImZhaWxcIlxuXHRcdFx0XHRcdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0XHRcdFx0XHR0aHJvd1dpdGhDYXVzZShlcnIsIFNUQUNLX1RSQUNFX0VSUk9SKTtcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0YXdhaXQgZGVsYXkoaW50ZXJ2YWwsIHNldFRpbWVvdXQpO1xuXHRcdFx0XHRcdFx0XHRcdGlmICh2aS5pc0Zha2VUaW1lcnMoKSkgdmkuYWR2YW5jZVRpbWVyc0J5VGltZShpbnRlcnZhbCk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9IGZpbmFsbHkge1xuXHRcdFx0XHRcdFx0Y2xlYXJUaW1lb3V0KHRpbWVySWQpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fTtcblx0XHRcdFx0bGV0IGF3YWl0ZWQgPSBmYWxzZTtcblx0XHRcdFx0dGVzdC5vbkZpbmlzaGVkID8/PSBbXTtcblx0XHRcdFx0dGVzdC5vbkZpbmlzaGVkLnB1c2goKCkgPT4ge1xuXHRcdFx0XHRcdGlmICghYXdhaXRlZCkge1xuXHRcdFx0XHRcdFx0Y29uc3QgbmVnYXRlZCA9IGNoYWkudXRpbC5mbGFnKGFzc2VydGlvbiwgXCJuZWdhdGVcIikgPyBcIm5vdC5cIiA6IFwiXCI7XG5cdFx0XHRcdFx0XHRjb25zdCBhc3NlcnRpb25TdHJpbmcgPSBgZXhwZWN0LiR7Y2hhaS51dGlsLmZsYWcoYXNzZXJ0aW9uLCBcIl9wb2xsLmVsZW1lbnRcIikgPyBcImVsZW1lbnQobG9jYXRvcilcIiA6IFwicG9sbChhc3NlcnRpb24pXCJ9LiR7bmVnYXRlZH0ke1N0cmluZyhrZXkpfSgpYDtcblx0XHRcdFx0XHRcdHRocm93IGNvcHlTdGFja1RyYWNlKC8qIEBfX1BVUkVfXyAqLyBuZXcgRXJyb3IoYCR7YXNzZXJ0aW9uU3RyaW5nfSB3YXMgbm90IGF3YWl0ZWQuIFRoaXMgYXNzZXJ0aW9uIGlzIGFzeW5jaHJvbm91cyBhbmQgbXVzdCBiZSBhd2FpdGVkOyBvdGhlcndpc2UsIGl0IGlzIG5vdCBleGVjdXRlZCB0byBhdm9pZCB1bmhhbmRsZWQgcmVqZWN0aW9uczpcXG5cXG5hd2FpdCAke2Fzc2VydGlvblN0cmluZ31cXG5gKSwgU1RBQ0tfVFJBQ0VfRVJST1IpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSk7XG5cdFx0XHRcdGxldCByZXN1bHRQcm9taXNlO1xuXHRcdFx0XHQvLyBvbmx5IC50aGVuIGlzIGVub3VnaCB0byBjaGVjayBhd2FpdGVkLCBidXQgd2UgdHlwZSB0aGlzIGFzIGBQcm9taXNlPHZvaWQ+YCBpbiBnbG9iYWwgdHlwZXNcblx0XHRcdFx0Ly8gc28gbGV0J3MgZm9sbG93IGl0XG5cdFx0XHRcdHJldHVybiB7XG5cdFx0XHRcdFx0dGhlbihvbkZ1bGZpbGxlZCwgb25SZWplY3RlZCkge1xuXHRcdFx0XHRcdFx0YXdhaXRlZCA9IHRydWU7XG5cdFx0XHRcdFx0XHRyZXR1cm4gKHJlc3VsdFByb21pc2UgfHw9IHByb21pc2UoKSkudGhlbihvbkZ1bGZpbGxlZCwgb25SZWplY3RlZCk7XG5cdFx0XHRcdFx0fSxcblx0XHRcdFx0XHRjYXRjaChvblJlamVjdGVkKSB7XG5cdFx0XHRcdFx0XHRhd2FpdGVkID0gdHJ1ZTtcblx0XHRcdFx0XHRcdHJldHVybiAocmVzdWx0UHJvbWlzZSB8fD0gcHJvbWlzZSgpKS5jYXRjaChvblJlamVjdGVkKTtcblx0XHRcdFx0XHR9LFxuXHRcdFx0XHRcdGZpbmFsbHkob25GaW5hbGx5KSB7XG5cdFx0XHRcdFx0XHRhd2FpdGVkID0gdHJ1ZTtcblx0XHRcdFx0XHRcdHJldHVybiAocmVzdWx0UHJvbWlzZSB8fD0gcHJvbWlzZSgpKS5maW5hbGx5KG9uRmluYWxseSk7XG5cdFx0XHRcdFx0fSxcblx0XHRcdFx0XHRbU3ltYm9sLnRvU3RyaW5nVGFnXTogXCJQcm9taXNlXCJcblx0XHRcdFx0fTtcblx0XHRcdH07XG5cdFx0fSB9KTtcblx0XHRyZXR1cm4gcHJveHk7XG5cdH07XG59XG5mdW5jdGlvbiBjb3B5U3RhY2tUcmFjZSh0YXJnZXQsIHNvdXJjZSkge1xuXHRpZiAoc291cmNlLnN0YWNrICE9PSB2b2lkIDApIHRhcmdldC5zdGFjayA9IHNvdXJjZS5zdGFjay5yZXBsYWNlKHNvdXJjZS5tZXNzYWdlLCB0YXJnZXQubWVzc2FnZSk7XG5cdHJldHVybiB0YXJnZXQ7XG59XG5cbmxldCBfY2xpZW50O1xuZnVuY3Rpb24gZ2V0U25hcHNob3RDbGllbnQoKSB7XG5cdGlmICghX2NsaWVudCkgX2NsaWVudCA9IG5ldyBTbmFwc2hvdENsaWVudCh7IGlzRXF1YWw6IChyZWNlaXZlZCwgZXhwZWN0ZWQpID0+IHtcblx0XHRyZXR1cm4gZXF1YWxzKHJlY2VpdmVkLCBleHBlY3RlZCwgW2l0ZXJhYmxlRXF1YWxpdHksIHN1YnNldEVxdWFsaXR5XSk7XG5cdH0gfSk7XG5cdHJldHVybiBfY2xpZW50O1xufVxuZnVuY3Rpb24gZ2V0RXJyb3IoZXhwZWN0ZWQsIHByb21pc2UpIHtcblx0aWYgKHR5cGVvZiBleHBlY3RlZCAhPT0gXCJmdW5jdGlvblwiKSB7XG5cdFx0aWYgKCFwcm9taXNlKSB0aHJvdyBuZXcgRXJyb3IoYGV4cGVjdGVkIG11c3QgYmUgYSBmdW5jdGlvbiwgcmVjZWl2ZWQgJHt0eXBlb2YgZXhwZWN0ZWR9YCk7XG5cdFx0Ly8gd2hlbiBcInByb21pc2VkXCIsIGl0IHJlY2VpdmVzIHRocm93biBlcnJvclxuXHRcdHJldHVybiBleHBlY3RlZDtcblx0fVxuXHR0cnkge1xuXHRcdGV4cGVjdGVkKCk7XG5cdH0gY2F0Y2ggKGUpIHtcblx0XHRyZXR1cm4gZTtcblx0fVxuXHR0aHJvdyBuZXcgRXJyb3IoXCJzbmFwc2hvdCBmdW5jdGlvbiBkaWRuJ3QgdGhyb3dcIik7XG59XG5mdW5jdGlvbiBnZXRUZXN0TmFtZXModGVzdCkge1xuXHRyZXR1cm4ge1xuXHRcdGZpbGVwYXRoOiB0ZXN0LmZpbGUuZmlsZXBhdGgsXG5cdFx0bmFtZTogZ2V0TmFtZXModGVzdCkuc2xpY2UoMSkuam9pbihcIiA+IFwiKSxcblx0XHR0ZXN0SWQ6IHRlc3QuaWRcblx0fTtcbn1cbmZ1bmN0aW9uIGdldEFzc2VydGlvbk5hbWUoYXNzZXJ0aW9uKSB7XG5cdGNvbnN0IG5hbWUgPSBjaGFpLnV0aWwuZmxhZyhhc3NlcnRpb24sIFwiX25hbWVcIik7XG5cdGlmICghbmFtZSkgdGhyb3cgbmV3IEVycm9yKFwiQXNzZXJ0aW9uIG5hbWUgaXMgbm90IHNldC4gVGhpcyBpcyBhIGJ1ZyBpbiBWaXRlc3QuIFBsZWFzZSwgb3BlbiBhIG5ldyBpc3N1ZSB3aXRoIHJlcHJvZHVjdGlvbi5cIik7XG5cdHJldHVybiBuYW1lO1xufVxuZnVuY3Rpb24gZ2V0VGVzdChvYmopIHtcblx0Y29uc3QgdGVzdCA9IGNoYWkudXRpbC5mbGFnKG9iaiwgXCJ2aXRlc3QtdGVzdFwiKTtcblx0aWYgKCF0ZXN0KSB0aHJvdyBuZXcgRXJyb3IoYCcke2dldEFzc2VydGlvbk5hbWUob2JqKX0nIGNhbm5vdCBiZSB1c2VkIHdpdGhvdXQgdGVzdCBjb250ZXh0YCk7XG5cdHJldHVybiB0ZXN0O1xufVxuZnVuY3Rpb24gdmFsaWRhdGVBc3NlcnRpb24oYXNzZXJ0aW9uKSB7XG5cdGlmIChjaGFpLnV0aWwuZmxhZyhhc3NlcnRpb24sIFwibmVnYXRlXCIpKSB0aHJvdyBuZXcgRXJyb3IoYCR7Z2V0QXNzZXJ0aW9uTmFtZShhc3NlcnRpb24pfSBjYW5ub3QgYmUgdXNlZCB3aXRoIFwibm90XCJgKTtcbn1cbmNvbnN0IFNuYXBzaG90UGx1Z2luID0gKGNoYWksIHV0aWxzKSA9PiB7XG5cdGZvciAoY29uc3Qga2V5IG9mIFtcIm1hdGNoU25hcHNob3RcIiwgXCJ0b01hdGNoU25hcHNob3RcIl0pIHV0aWxzLmFkZE1ldGhvZChjaGFpLkFzc2VydGlvbi5wcm90b3R5cGUsIGtleSwgd3JhcEFzc2VydGlvbih1dGlscywga2V5LCBmdW5jdGlvbihwcm9wZXJ0aWVzT3JIaW50LCBoaW50KSB7XG5cdFx0cmV0dXJuIGFzc2VydE1hdGNoUmVzdWx0KHRvTWF0Y2hTbmFwc2hvdEltcGwoe1xuXHRcdFx0YXNzZXJ0aW9uOiB0aGlzLFxuXHRcdFx0cmVjZWl2ZWQ6IHV0aWxzLmZsYWcodGhpcywgXCJvYmplY3RcIiksXG5cdFx0XHQuLi5ub3JtYWxpemVBcmd1bWVudHMocHJvcGVydGllc09ySGludCwgaGludClcblx0XHR9KSwgY2hhaS51dGlsLmZsYWcodGhpcywgXCJtZXNzYWdlXCIpKTtcblx0fSkpO1xuXHR1dGlscy5hZGRNZXRob2QoY2hhaS5Bc3NlcnRpb24ucHJvdG90eXBlLCBcInRvTWF0Y2hGaWxlU25hcHNob3RcIiwgZnVuY3Rpb24oZmlsZXBhdGgsIGhpbnQpIHtcblx0XHQvLyBzZXQgbmFtZSBtYW51YWxseSBzaW5jZSBpdCdzIG5vdCB3cmFwcGVkIGJ5IHdyYXBBc3NlcnRpb25cblx0XHR1dGlscy5mbGFnKHRoaXMsIFwiX25hbWVcIiwgXCJ0b01hdGNoRmlsZVNuYXBzaG90XCIpO1xuXHRcdC8vIHZhbGlkYXRlIGVhcmx5IHN5bmNocm9ub3VzbHkganVzdCBub3QgdG8gYnJlYWsgc29tZSBleGlzdGluZyB0ZXN0c1xuXHRcdHZhbGlkYXRlQXNzZXJ0aW9uKHRoaXMpO1xuXHRcdGNvbnN0IGFzc2VydFByb21pc2UgPSB0b01hdGNoRmlsZVNuYXBzaG90SW1wbCh7XG5cdFx0XHRhc3NlcnRpb246IHRoaXMsXG5cdFx0XHRyZWNlaXZlZDogdXRpbHMuZmxhZyh0aGlzLCBcIm9iamVjdFwiKSxcblx0XHRcdGZpbGVwYXRoLFxuXHRcdFx0aGludFxuXHRcdH0pLnRoZW4oKHJlc3VsdCkgPT4gYXNzZXJ0TWF0Y2hSZXN1bHQocmVzdWx0LCBjaGFpLnV0aWwuZmxhZyh0aGlzLCBcIm1lc3NhZ2VcIikpKTtcblx0XHRyZXR1cm4gcmVjb3JkQXN5bmNFeHBlY3QoZ2V0VGVzdCh0aGlzKSwgYXNzZXJ0UHJvbWlzZSwgY3JlYXRlQXNzZXJ0aW9uTWVzc2FnZSh1dGlscywgdGhpcywgdHJ1ZSksIC8qIEBfX1BVUkVfXyAqLyBuZXcgRXJyb3IoXCJyZXNvbHZlc1wiKSwgdXRpbHMuZmxhZyh0aGlzLCBcInNvZnRcIikpO1xuXHR9KTtcblx0dXRpbHMuYWRkTWV0aG9kKGNoYWkuQXNzZXJ0aW9uLnByb3RvdHlwZSwgXCJ0b01hdGNoSW5saW5lU25hcHNob3RcIiwgd3JhcEFzc2VydGlvbih1dGlscywgXCJ0b01hdGNoSW5saW5lU25hcHNob3RcIiwgZnVuY3Rpb24gX19JTkxJTkVfU05BUFNIT1RfT0ZGU0VUXzNfXyhwcm9wZXJ0aWVzT3JJbmxpbmVTbmFwc2hvdCwgaW5saW5lU25hcHNob3RPckhpbnQsIGhpbnQpIHtcblx0XHRyZXR1cm4gYXNzZXJ0TWF0Y2hSZXN1bHQodG9NYXRjaFNuYXBzaG90SW1wbCh7XG5cdFx0XHRhc3NlcnRpb246IHRoaXMsXG5cdFx0XHRyZWNlaXZlZDogdXRpbHMuZmxhZyh0aGlzLCBcIm9iamVjdFwiKSxcblx0XHRcdGlzSW5saW5lOiB0cnVlLFxuXHRcdFx0Li4ubm9ybWFsaXplSW5saW5lQXJndW1lbnRzKHByb3BlcnRpZXNPcklubGluZVNuYXBzaG90LCBpbmxpbmVTbmFwc2hvdE9ySGludCwgaGludClcblx0XHR9KSwgY2hhaS51dGlsLmZsYWcodGhpcywgXCJtZXNzYWdlXCIpKTtcblx0fSkpO1xuXHR1dGlscy5hZGRNZXRob2QoY2hhaS5Bc3NlcnRpb24ucHJvdG90eXBlLCBcInRvVGhyb3dFcnJvck1hdGNoaW5nU25hcHNob3RcIiwgd3JhcEFzc2VydGlvbih1dGlscywgXCJ0b1Rocm93RXJyb3JNYXRjaGluZ1NuYXBzaG90XCIsIGZ1bmN0aW9uKHByb3BlcnRpZXNPckhpbnQsIGhpbnQpIHtcblx0XHR2YWxpZGF0ZUFzc2VydGlvbih0aGlzKTtcblx0XHRjb25zdCByZWNlaXZlZCA9IHV0aWxzLmZsYWcodGhpcywgXCJvYmplY3RcIik7XG5cdFx0Y29uc3QgcHJvbWlzZSA9IHV0aWxzLmZsYWcodGhpcywgXCJwcm9taXNlXCIpO1xuXHRcdHJldHVybiBhc3NlcnRNYXRjaFJlc3VsdCh0b01hdGNoU25hcHNob3RJbXBsKHtcblx0XHRcdGFzc2VydGlvbjogdGhpcyxcblx0XHRcdHJlY2VpdmVkOiBnZXRFcnJvcihyZWNlaXZlZCwgcHJvbWlzZSksXG5cdFx0XHQuLi5ub3JtYWxpemVBcmd1bWVudHMocHJvcGVydGllc09ySGludCwgaGludClcblx0XHR9KSwgY2hhaS51dGlsLmZsYWcodGhpcywgXCJtZXNzYWdlXCIpKTtcblx0fSkpO1xuXHR1dGlscy5hZGRNZXRob2QoY2hhaS5Bc3NlcnRpb24ucHJvdG90eXBlLCBcInRvVGhyb3dFcnJvck1hdGNoaW5nSW5saW5lU25hcHNob3RcIiwgd3JhcEFzc2VydGlvbih1dGlscywgXCJ0b1Rocm93RXJyb3JNYXRjaGluZ0lubGluZVNuYXBzaG90XCIsIGZ1bmN0aW9uIF9fSU5MSU5FX1NOQVBTSE9UX09GRlNFVF8zX18oaW5saW5lU25hcHNob3RPckhpbnQsIGhpbnQpIHtcblx0XHR2YWxpZGF0ZUFzc2VydGlvbih0aGlzKTtcblx0XHRjb25zdCByZWNlaXZlZCA9IHV0aWxzLmZsYWcodGhpcywgXCJvYmplY3RcIik7XG5cdFx0Y29uc3QgcHJvbWlzZSA9IHV0aWxzLmZsYWcodGhpcywgXCJwcm9taXNlXCIpO1xuXHRcdHJldHVybiBhc3NlcnRNYXRjaFJlc3VsdCh0b01hdGNoU25hcHNob3RJbXBsKHtcblx0XHRcdGFzc2VydGlvbjogdGhpcyxcblx0XHRcdHJlY2VpdmVkOiBnZXRFcnJvcihyZWNlaXZlZCwgcHJvbWlzZSksXG5cdFx0XHRpc0lubGluZTogdHJ1ZSxcblx0XHRcdC4uLm5vcm1hbGl6ZUlubGluZUFyZ3VtZW50cyh2b2lkIDAsIGlubGluZVNuYXBzaG90T3JIaW50LCBoaW50KVxuXHRcdH0pLCBjaGFpLnV0aWwuZmxhZyh0aGlzLCBcIm1lc3NhZ2VcIikpO1xuXHR9KSk7XG5cdHV0aWxzLmFkZE1ldGhvZChjaGFpLmV4cGVjdCwgXCJhZGRTbmFwc2hvdFNlcmlhbGl6ZXJcIiwgYWRkU2VyaWFsaXplcik7XG59O1xuZnVuY3Rpb24gdG9NYXRjaERvbWFpblNuYXBzaG90SW1wbChvcHRzKSB7XG5cdGNvbnN0IHsgYXNzZXJ0aW9uIH0gPSBvcHRzO1xuXHR2YWxpZGF0ZUFzc2VydGlvbihhc3NlcnRpb24pO1xuXHRjb25zdCBhc3NlcnRpb25OYW1lID0gZ2V0QXNzZXJ0aW9uTmFtZShhc3NlcnRpb24pO1xuXHRjb25zdCB0ZXN0ID0gZ2V0VGVzdChhc3NlcnRpb24pO1xuXHRsZXQgeyBpbmxpbmVTbmFwc2hvdCB9ID0gb3B0cztcblx0aWYgKGlubGluZVNuYXBzaG90KSBpbmxpbmVTbmFwc2hvdCA9IHN0cmlwU25hcHNob3RJbmRlbnRhdGlvbihpbmxpbmVTbmFwc2hvdCk7XG5cdGNvbnN0IHBvbGxGbiA9IGNoYWkudXRpbC5mbGFnKGFzc2VydGlvbiwgXCJfcG9sbC5mblwiKTtcblx0aWYgKHBvbGxGbikgcmV0dXJuIGdldFNuYXBzaG90Q2xpZW50KCkucG9sbE1hdGNoRG9tYWluKHtcblx0XHRwb2xsOiBwb2xsRm4sXG5cdFx0YWRhcHRlcjogb3B0cy5hZGFwdGVyLFxuXHRcdG1lc3NhZ2U6IG9wdHMuaGludCxcblx0XHRpc0lubGluZTogb3B0cy5pc0lubGluZSxcblx0XHRlcnJvck1lc3NhZ2U6IGNoYWkudXRpbC5mbGFnKGFzc2VydGlvbiwgXCJtZXNzYWdlXCIpLFxuXHRcdHRpbWVvdXQ6IGNoYWkudXRpbC5mbGFnKGFzc2VydGlvbiwgXCJfcG9sbC50aW1lb3V0XCIpLFxuXHRcdGludGVydmFsOiBjaGFpLnV0aWwuZmxhZyhhc3NlcnRpb24sIFwiX3BvbGwuaW50ZXJ2YWxcIiksXG5cdFx0YXNzZXJ0aW9uTmFtZSxcblx0XHRpbmxpbmVTbmFwc2hvdCxcblx0XHRlcnJvcjogY2hhaS51dGlsLmZsYWcoYXNzZXJ0aW9uLCBcImVycm9yXCIpLFxuXHRcdC4uLmdldFRlc3ROYW1lcyh0ZXN0KVxuXHR9KTtcblx0cmV0dXJuIGdldFNuYXBzaG90Q2xpZW50KCkubWF0Y2hEb21haW4oe1xuXHRcdHJlY2VpdmVkOiBvcHRzLnJlY2VpdmVkLFxuXHRcdGFkYXB0ZXI6IG9wdHMuYWRhcHRlcixcblx0XHRtZXNzYWdlOiBvcHRzLmhpbnQsXG5cdFx0aXNJbmxpbmU6IG9wdHMuaXNJbmxpbmUsXG5cdFx0ZXJyb3JNZXNzYWdlOiBjaGFpLnV0aWwuZmxhZyhhc3NlcnRpb24sIFwibWVzc2FnZVwiKSxcblx0XHRhc3NlcnRpb25OYW1lLFxuXHRcdGlubGluZVNuYXBzaG90LFxuXHRcdGVycm9yOiBjaGFpLnV0aWwuZmxhZyhhc3NlcnRpb24sIFwiZXJyb3JcIiksXG5cdFx0Li4uZ2V0VGVzdE5hbWVzKHRlc3QpXG5cdH0pO1xufVxuLy8gdG9NYXRjaFNuYXBzaG90KHByb3BlcnRpZXNPckhpbnQ/LCBoaW50PylcbmZ1bmN0aW9uIG5vcm1hbGl6ZUFyZ3VtZW50cyhwcm9wZXJ0aWVzT3JIaW50LCBoaW50KSB7XG5cdGlmICh0eXBlb2YgcHJvcGVydGllc09ySGludCA9PT0gXCJzdHJpbmdcIikgcmV0dXJuIHsgaGludDogcHJvcGVydGllc09ySGludCB9O1xuXHRyZXR1cm4ge1xuXHRcdHByb3BlcnRpZXM6IHByb3BlcnRpZXNPckhpbnQsXG5cdFx0aGludFxuXHR9O1xufVxuLy8gdG9NYXRjaElubGluZVNuYXBzaG90KHByb3BlcnRpZXNPcklubGluZVNuYXBzaG90PywgaW5saW5lU25hcHNob3RPckhpbnQ/LCBoaW50PylcbmZ1bmN0aW9uIG5vcm1hbGl6ZUlubGluZUFyZ3VtZW50cyhwcm9wZXJ0aWVzT3JJbmxpbmVTbmFwc2hvdCwgaW5saW5lU25hcHNob3RPckhpbnQsIGhpbnQpIHtcblx0bGV0IGlubGluZVNuYXBzaG90O1xuXHRpZiAodHlwZW9mIHByb3BlcnRpZXNPcklubGluZVNuYXBzaG90ID09PSBcInN0cmluZ1wiKSB7XG5cdFx0aW5saW5lU25hcHNob3QgPSBzdHJpcFNuYXBzaG90SW5kZW50YXRpb24ocHJvcGVydGllc09ySW5saW5lU25hcHNob3QpO1xuXHRcdHJldHVybiB7XG5cdFx0XHRpbmxpbmVTbmFwc2hvdCxcblx0XHRcdGhpbnQ6IGlubGluZVNuYXBzaG90T3JIaW50XG5cdFx0fTtcblx0fVxuXHRpZiAoaW5saW5lU25hcHNob3RPckhpbnQpIGlubGluZVNuYXBzaG90ID0gc3RyaXBTbmFwc2hvdEluZGVudGF0aW9uKGlubGluZVNuYXBzaG90T3JIaW50KTtcblx0cmV0dXJuIHtcblx0XHRwcm9wZXJ0aWVzOiBwcm9wZXJ0aWVzT3JJbmxpbmVTbmFwc2hvdCxcblx0XHRpbmxpbmVTbmFwc2hvdCxcblx0XHRoaW50XG5cdH07XG59XG5mdW5jdGlvbiB0b01hdGNoU25hcHNob3RJbXBsKG9wdGlvbnMpIHtcblx0Y29uc3QgeyBhc3NlcnRpb24gfSA9IG9wdGlvbnM7XG5cdHZhbGlkYXRlQXNzZXJ0aW9uKGFzc2VydGlvbik7XG5cdGNvbnN0IGFzc2VydGlvbk5hbWUgPSBnZXRBc3NlcnRpb25OYW1lKGFzc2VydGlvbik7XG5cdGNvbnN0IHRlc3QgPSBnZXRUZXN0KGFzc2VydGlvbik7XG5cdHJldHVybiBnZXRTbmFwc2hvdENsaWVudCgpLm1hdGNoKHtcblx0XHRyZWNlaXZlZDogb3B0aW9ucy5yZWNlaXZlZCxcblx0XHRwcm9wZXJ0aWVzOiBvcHRpb25zLnByb3BlcnRpZXMsXG5cdFx0bWVzc2FnZTogb3B0aW9ucy5oaW50LFxuXHRcdGlzSW5saW5lOiBvcHRpb25zLmlzSW5saW5lLFxuXHRcdGlubGluZVNuYXBzaG90OiBvcHRpb25zLmlubGluZVNuYXBzaG90LFxuXHRcdGFzc2VydGlvbk5hbWUsXG5cdFx0ZXJyb3I6IGNoYWkudXRpbC5mbGFnKGFzc2VydGlvbiwgXCJlcnJvclwiKSxcblx0XHQuLi5nZXRUZXN0TmFtZXModGVzdClcblx0fSk7XG59XG5hc3luYyBmdW5jdGlvbiB0b01hdGNoRmlsZVNuYXBzaG90SW1wbChvcHRpb25zKSB7XG5cdGNvbnN0IHsgYXNzZXJ0aW9uIH0gPSBvcHRpb25zO1xuXHR2YWxpZGF0ZUFzc2VydGlvbihhc3NlcnRpb24pO1xuXHRjb25zdCB0ZXN0TmFtZXMgPSBnZXRUZXN0TmFtZXMoZ2V0VGVzdChhc3NlcnRpb24pKTtcblx0Y29uc3Qgc25hcHNob3RTdGF0ZSA9IGdldFNuYXBzaG90Q2xpZW50KCkuZ2V0U25hcHNob3RTdGF0ZSh0ZXN0TmFtZXMuZmlsZXBhdGgpO1xuXHRjb25zdCByYXdTbmFwc2hvdEZpbGUgPSBhd2FpdCBzbmFwc2hvdFN0YXRlLmVudmlyb25tZW50LnJlc29sdmVSYXdQYXRoKHRlc3ROYW1lcy5maWxlcGF0aCwgb3B0aW9ucy5maWxlcGF0aCk7XG5cdGNvbnN0IHJhd1NuYXBzaG90Q29udGVudCA9IGF3YWl0IHNuYXBzaG90U3RhdGUuZW52aXJvbm1lbnQucmVhZFNuYXBzaG90RmlsZShyYXdTbmFwc2hvdEZpbGUpO1xuXHRyZXR1cm4gZ2V0U25hcHNob3RDbGllbnQoKS5tYXRjaCh7XG5cdFx0cmVjZWl2ZWQ6IG9wdGlvbnMucmVjZWl2ZWQsXG5cdFx0bWVzc2FnZTogb3B0aW9ucy5oaW50LFxuXHRcdHJhd1NuYXBzaG90OiB7XG5cdFx0XHRmaWxlOiByYXdTbmFwc2hvdEZpbGUsXG5cdFx0XHRjb250ZW50OiByYXdTbmFwc2hvdENvbnRlbnQgPz8gdm9pZCAwXG5cdFx0fSxcblx0XHQuLi50ZXN0TmFtZXNcblx0fSk7XG59XG5mdW5jdGlvbiBhc3NlcnRNYXRjaFJlc3VsdChyZXN1bHQsIGN1c3RvbU1lc3NhZ2UpIHtcblx0aWYgKCFyZXN1bHQucGFzcykge1xuXHRcdGNvbnN0IGVycm9yTWVzc2FnZSA9IChjdXN0b21NZXNzYWdlID8gYCR7Y3VzdG9tTWVzc2FnZX06IGAgOiBcIlwiKSArIHJlc3VsdC5tZXNzYWdlKCk7XG5cdFx0dGhyb3cgT2JqZWN0LmFzc2lnbihuZXcgRXJyb3IoZXJyb3JNZXNzYWdlKSwge1xuXHRcdFx0YWN0dWFsOiByZXN1bHQuYWN0dWFsLFxuXHRcdFx0ZXhwZWN0ZWQ6IHJlc3VsdC5leHBlY3RlZCxcblx0XHRcdGRpZmZPcHRpb25zOiB7IGV4cGFuZDogZ2V0V29ya2VyU3RhdGUoKS5jb25maWcuc25hcHNob3RPcHRpb25zLmV4cGFuZCB9XG5cdFx0fSk7XG5cdH1cbn1cbi8qKlxuKiBDb21wb3NhYmxlIHNuYXBzaG90IG1hdGNoZXIgaGVscGVycyBmb3IgYnVpbGRpbmcgY3VzdG9tIHNuYXBzaG90IG1hdGNoZXJzXG4qIHdpdGggYGV4cGVjdC5leHRlbmRgLlxuKlxuKiBAZXhwZXJpbWVudGFsXG4qIEBzZWUgaHR0cHM6Ly92aXRlc3QuZGV2L2d1aWRlL3NuYXBzaG90Lmh0bWwjY3VzdG9tLXNuYXBzaG90LW1hdGNoZXJzXG4qL1xuY29uc3QgU25hcHNob3RzID0ge1xuXHR0b01hdGNoU25hcHNob3QocmVjZWl2ZWQsIHByb3BlcnRpZXNPckhpbnQsIGhpbnQpIHtcblx0XHRyZXR1cm4gdG9NYXRjaFNuYXBzaG90SW1wbCh7XG5cdFx0XHRhc3NlcnRpb246IHRoaXMuYXNzZXJ0aW9uLFxuXHRcdFx0cmVjZWl2ZWQsXG5cdFx0XHQuLi5ub3JtYWxpemVBcmd1bWVudHMocHJvcGVydGllc09ySGludCwgaGludClcblx0XHR9KTtcblx0fSxcblx0dG9NYXRjaElubGluZVNuYXBzaG90KHJlY2VpdmVkLCBwcm9wZXJ0aWVzT3JJbmxpbmVTbmFwc2hvdCwgaW5saW5lU25hcHNob3RPckhpbnQsIGhpbnQpIHtcblx0XHRyZXR1cm4gdG9NYXRjaFNuYXBzaG90SW1wbCh7XG5cdFx0XHRhc3NlcnRpb246IHRoaXMuYXNzZXJ0aW9uLFxuXHRcdFx0cmVjZWl2ZWQsXG5cdFx0XHRpc0lubGluZTogdHJ1ZSxcblx0XHRcdC4uLm5vcm1hbGl6ZUlubGluZUFyZ3VtZW50cyhwcm9wZXJ0aWVzT3JJbmxpbmVTbmFwc2hvdCwgaW5saW5lU25hcHNob3RPckhpbnQsIGhpbnQpXG5cdFx0fSk7XG5cdH0sXG5cdHRvTWF0Y2hGaWxlU25hcHNob3QocmVjZWl2ZWQsIGZpbGVwYXRoLCBoaW50KSB7XG5cdFx0cmV0dXJuIHRvTWF0Y2hGaWxlU25hcHNob3RJbXBsKHtcblx0XHRcdGFzc2VydGlvbjogdGhpcy5hc3NlcnRpb24sXG5cdFx0XHRyZWNlaXZlZCxcblx0XHRcdGZpbGVwYXRoLFxuXHRcdFx0aGludFxuXHRcdH0pO1xuXHR9LFxuXHR0b01hdGNoRG9tYWluU25hcHNob3QoZG9tYWluLCByZWNlaXZlZCkge1xuXHRcdHJldHVybiB0b01hdGNoRG9tYWluU25hcHNob3RJbXBsKHtcblx0XHRcdGFzc2VydGlvbjogdGhpcy5hc3NlcnRpb24sXG5cdFx0XHRhZGFwdGVyOiBkb21haW4sXG5cdFx0XHRyZWNlaXZlZFxuXHRcdH0pO1xuXHR9LFxuXHR0b01hdGNoRG9tYWluSW5saW5lU25hcHNob3QoZG9tYWluLCByZWNlaXZlZCwgaW5saW5lU25hcHNob3QpIHtcblx0XHRyZXR1cm4gdG9NYXRjaERvbWFpblNuYXBzaG90SW1wbCh7XG5cdFx0XHRhc3NlcnRpb246IHRoaXMuYXNzZXJ0aW9uLFxuXHRcdFx0YWRhcHRlcjogZG9tYWluLFxuXHRcdFx0cmVjZWl2ZWQsXG5cdFx0XHRpc0lubGluZTogdHJ1ZSxcblx0XHRcdGlubGluZVNuYXBzaG90XG5cdFx0fSk7XG5cdH1cbn07XG5cbmNoYWkudXNlKEplc3RFeHRlbmQpO1xuY2hhaS51c2UoSmVzdENoYWlFeHBlY3QpO1xuY2hhaS51c2UoQ2hhaVN0eWxlQXNzZXJ0aW9ucyk7XG5jaGFpLnVzZShTbmFwc2hvdFBsdWdpbik7XG5jaGFpLnVzZShKZXN0QXN5bW1ldHJpY01hdGNoZXJzKTtcblxuZnVuY3Rpb24gY3JlYXRlRXhwZWN0KHRlc3QpIHtcblx0Y29uc3QgZXhwZWN0ID0gKCh2YWx1ZSwgbWVzc2FnZSkgPT4ge1xuXHRcdGNvbnN0IHsgYXNzZXJ0aW9uQ2FsbHMgfSA9IGdldFN0YXRlKGV4cGVjdCk7XG5cdFx0c2V0U3RhdGUoeyBhc3NlcnRpb25DYWxsczogYXNzZXJ0aW9uQ2FsbHMgKyAxIH0sIGV4cGVjdCk7XG5cdFx0Y29uc3QgYXNzZXJ0ID0gY2hhaS5leHBlY3QodmFsdWUsIG1lc3NhZ2UpO1xuXHRcdGNvbnN0IF90ZXN0ID0gdGVzdCB8fCBnZXRDdXJyZW50VGVzdCgpO1xuXHRcdGlmIChfdGVzdClcbiAvLyBAdHMtZXhwZWN0LWVycm9yIGludGVybmFsXG5cdFx0cmV0dXJuIGFzc2VydC53aXRoVGVzdChfdGVzdCk7XG5cdFx0ZWxzZSByZXR1cm4gYXNzZXJ0O1xuXHR9KTtcblx0T2JqZWN0LmFzc2lnbihleHBlY3QsIGNoYWkuZXhwZWN0KTtcblx0T2JqZWN0LmFzc2lnbihleHBlY3QsIGdsb2JhbFRoaXNbQVNZTU1FVFJJQ19NQVRDSEVSU19PQkpFQ1RdKTtcblx0ZXhwZWN0LmdldFN0YXRlID0gKCkgPT4gZ2V0U3RhdGUoZXhwZWN0KTtcblx0ZXhwZWN0LnNldFN0YXRlID0gKHN0YXRlKSA9PiBzZXRTdGF0ZShzdGF0ZSwgZXhwZWN0KTtcblx0Ly8gQHRzLWV4cGVjdC1lcnJvciBnbG9iYWwgaXMgbm90IHR5cGVkXG5cdGNvbnN0IGdsb2JhbFN0YXRlID0gZ2V0U3RhdGUoZ2xvYmFsVGhpc1tHTE9CQUxfRVhQRUNUXSkgfHwge307XG5cdHNldFN0YXRlKHtcblx0XHQuLi5nbG9iYWxTdGF0ZSxcblx0XHRhc3NlcnRpb25DYWxsczogMCxcblx0XHRpc0V4cGVjdGluZ0Fzc2VydGlvbnM6IGZhbHNlLFxuXHRcdGlzRXhwZWN0aW5nQXNzZXJ0aW9uc0Vycm9yOiBudWxsLFxuXHRcdGV4cGVjdGVkQXNzZXJ0aW9uc051bWJlcjogbnVsbCxcblx0XHRleHBlY3RlZEFzc2VydGlvbnNOdW1iZXJFcnJvckdlbjogbnVsbCxcblx0XHRnZXQgdGVzdFBhdGgoKSB7XG5cdFx0XHRyZXR1cm4gZ2V0V29ya2VyU3RhdGUoKS5maWxlcGF0aDtcblx0XHR9LFxuXHRcdGN1cnJlbnRUZXN0TmFtZTogdGVzdCA/IHRlc3QuZnVsbFRlc3ROYW1lID8/IFwiXCIgOiBnbG9iYWxTdGF0ZS5jdXJyZW50VGVzdE5hbWVcblx0fSwgZXhwZWN0KTtcblx0ZXhwZWN0LmFzc2VydCA9IGNoYWkuYXNzZXJ0O1xuXHQvLyBAdHMtZXhwZWN0LWVycm9yIHVudHlwZWRcblx0ZXhwZWN0LmV4dGVuZCA9IChtYXRjaGVycykgPT4gY2hhaS5leHBlY3QuZXh0ZW5kKGV4cGVjdCwgbWF0Y2hlcnMpO1xuXHRleHBlY3QuYWRkRXF1YWxpdHlUZXN0ZXJzID0gKGN1c3RvbVRlc3RlcnMpID0+IGFkZEN1c3RvbUVxdWFsaXR5VGVzdGVycyhjdXN0b21UZXN0ZXJzKTtcblx0ZXhwZWN0LnNvZnQgPSAoLi4uYXJncykgPT4ge1xuXHRcdC8vIEB0cy1leHBlY3QtZXJyb3IgcHJpdmF0ZSBzb2Z0IGFjY2Vzc1xuXHRcdHJldHVybiBleHBlY3QoLi4uYXJncykud2l0aENvbnRleHQoeyBzb2Z0OiB0cnVlIH0pO1xuXHR9O1xuXHRleHBlY3QucG9sbCA9IGNyZWF0ZUV4cGVjdFBvbGwoZXhwZWN0KTtcblx0ZXhwZWN0LnVucmVhY2hhYmxlID0gKG1lc3NhZ2UpID0+IHtcblx0XHRjaGFpLmFzc2VydC5mYWlsKGBleHBlY3RlZCR7bWVzc2FnZSA/IGAgXCIke21lc3NhZ2V9XCIgYCA6IFwiIFwifW5vdCB0byBiZSByZWFjaGVkYCk7XG5cdH07XG5cdGZ1bmN0aW9uIGFzc2VydGlvbnMoZXhwZWN0ZWQpIHtcblx0XHRjb25zdCBlcnJvckdlbiA9ICgpID0+IC8qIEBfX1BVUkVfXyAqLyBuZXcgRXJyb3IoYGV4cGVjdGVkIG51bWJlciBvZiBhc3NlcnRpb25zIHRvIGJlICR7ZXhwZWN0ZWR9LCBidXQgZ290ICR7ZXhwZWN0LmdldFN0YXRlKCkuYXNzZXJ0aW9uQ2FsbHN9YCk7XG5cdFx0aWYgKEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKSBFcnJvci5jYXB0dXJlU3RhY2tUcmFjZShlcnJvckdlbigpLCBhc3NlcnRpb25zKTtcblx0XHRleHBlY3Quc2V0U3RhdGUoe1xuXHRcdFx0ZXhwZWN0ZWRBc3NlcnRpb25zTnVtYmVyOiBleHBlY3RlZCxcblx0XHRcdGV4cGVjdGVkQXNzZXJ0aW9uc051bWJlckVycm9yR2VuOiBlcnJvckdlblxuXHRcdH0pO1xuXHR9XG5cdGZ1bmN0aW9uIGhhc0Fzc2VydGlvbnMoKSB7XG5cdFx0Y29uc3QgZXJyb3IgPSAvKiBAX19QVVJFX18gKi8gbmV3IEVycm9yKFwiZXhwZWN0ZWQgYW55IG51bWJlciBvZiBhc3NlcnRpb24sIGJ1dCBnb3Qgbm9uZVwiKTtcblx0XHRpZiAoRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UpIEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKGVycm9yLCBoYXNBc3NlcnRpb25zKTtcblx0XHRleHBlY3Quc2V0U3RhdGUoe1xuXHRcdFx0aXNFeHBlY3RpbmdBc3NlcnRpb25zOiB0cnVlLFxuXHRcdFx0aXNFeHBlY3RpbmdBc3NlcnRpb25zRXJyb3I6IGVycm9yXG5cdFx0fSk7XG5cdH1cblx0Y2hhaS51dGlsLmFkZE1ldGhvZChleHBlY3QsIFwiYXNzZXJ0aW9uc1wiLCBhc3NlcnRpb25zKTtcblx0Y2hhaS51dGlsLmFkZE1ldGhvZChleHBlY3QsIFwiaGFzQXNzZXJ0aW9uc1wiLCBoYXNBc3NlcnRpb25zKTtcblx0ZXhwZWN0LmV4dGVuZChjdXN0b21NYXRjaGVycyk7XG5cdHJldHVybiBleHBlY3Q7XG59XG5jb25zdCBnbG9iYWxFeHBlY3QgPSBjcmVhdGVFeHBlY3QoKTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShnbG9iYWxUaGlzLCBHTE9CQUxfRVhQRUNULCB7XG5cdHZhbHVlOiBnbG9iYWxFeHBlY3QsXG5cdHdyaXRhYmxlOiB0cnVlLFxuXHRjb25maWd1cmFibGU6IHRydWVcbn0pO1xuY29uc3QgYXNzZXJ0ID0gY2hhaS5hc3NlcnQ7XG5jb25zdCBzaG91bGQgPSBjaGFpLnNob3VsZDtcblxuLyoqXG4qIEdpdmVzIGFjY2VzcyB0byBpbmplY3RlZCBjb250ZXh0IHByb3ZpZGVkIGZyb20gdGhlIG1haW4gdGhyZWFkLlxuKiBUaGlzIHVzdWFsbHkgcmV0dXJucyBhIHZhbHVlIHByb3ZpZGVkIGJ5IGBnbG9iYWxTZXR1cGAgb3IgYW4gZXh0ZXJuYWwgbGlicmFyeS5cbiovXG5mdW5jdGlvbiBpbmplY3Qoa2V5KSB7XG5cdHJldHVybiBnZXRXb3JrZXJTdGF0ZSgpLnByb3ZpZGVkQ29udGV4dFtrZXldO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVCZW5jaG1hcmtSZXN1bHQobmFtZSkge1xuXHRyZXR1cm4ge1xuXHRcdG5hbWUsXG5cdFx0cmFuazogMCxcblx0XHRybWU6IDAsXG5cdFx0c2FtcGxlczogW11cblx0fTtcbn1cbmNvbnN0IGJlbmNobWFya1Rhc2tzID0gLyogQF9fUFVSRV9fICovIG5ldyBXZWFrTWFwKCk7XG5hc3luYyBmdW5jdGlvbiBydW5CZW5jaG1hcmtTdWl0ZShzdWl0ZSwgcnVubmVyKSB7XG5cdGNvbnN0IHsgVGFzaywgQmVuY2ggfSA9IGF3YWl0IHJ1bm5lci5pbXBvcnRUaW55YmVuY2goKTtcblx0Y29uc3Qgc3RhcnQgPSBwZXJmb3JtYW5jZS5ub3coKTtcblx0Y29uc3QgYmVuY2htYXJrR3JvdXAgPSBbXTtcblx0Y29uc3QgYmVuY2htYXJrU3VpdGVHcm91cCA9IFtdO1xuXHRmb3IgKGNvbnN0IHRhc2sgb2Ygc3VpdGUudGFza3MpIHtcblx0XHRpZiAodGFzay5tb2RlICE9PSBcInJ1blwiICYmIHRhc2subW9kZSAhPT0gXCJxdWV1ZWRcIikgY29udGludWU7XG5cdFx0aWYgKHRhc2subWV0YT8uYmVuY2htYXJrKSBiZW5jaG1hcmtHcm91cC5wdXNoKHRhc2spO1xuXHRcdGVsc2UgaWYgKHRhc2sudHlwZSA9PT0gXCJzdWl0ZVwiKSBiZW5jaG1hcmtTdWl0ZUdyb3VwLnB1c2godGFzayk7XG5cdH1cblx0Ly8gcnVuIHN1YiBzdWl0ZXMgc2VxdWVudGlhbGx5XG5cdGZvciAoY29uc3Qgc3ViU3VpdGUgb2YgYmVuY2htYXJrU3VpdGVHcm91cCkgYXdhaXQgcnVuQmVuY2htYXJrU3VpdGUoc3ViU3VpdGUsIHJ1bm5lcik7XG5cdGlmIChiZW5jaG1hcmtHcm91cC5sZW5ndGgpIHtcblx0XHRjb25zdCBkZWZlciA9IGNyZWF0ZURlZmVyKCk7XG5cdFx0c3VpdGUucmVzdWx0ID0ge1xuXHRcdFx0c3RhdGU6IFwicnVuXCIsXG5cdFx0XHRzdGFydFRpbWU6IHN0YXJ0LFxuXHRcdFx0YmVuY2htYXJrOiBjcmVhdGVCZW5jaG1hcmtSZXN1bHQoc3VpdGUubmFtZSlcblx0XHR9O1xuXHRcdHVwZGF0ZVRhc2skMShcInN1aXRlLXByZXBhcmVcIiwgc3VpdGUpO1xuXHRcdGNvbnN0IGFkZEJlbmNoVGFza0xpc3RlbmVyID0gKHRhc2ssIGJlbmNobWFyaykgPT4ge1xuXHRcdFx0dGFzay5hZGRFdmVudExpc3RlbmVyKFwiY29tcGxldGVcIiwgKGUpID0+IHtcblx0XHRcdFx0Y29uc3QgdGFza1JlcyA9IGUudGFzay5yZXN1bHQ7XG5cdFx0XHRcdGNvbnN0IHJlc3VsdCA9IGJlbmNobWFyay5yZXN1bHQuYmVuY2htYXJrO1xuXHRcdFx0XHRiZW5jaG1hcmsucmVzdWx0LnN0YXRlID0gXCJwYXNzXCI7XG5cdFx0XHRcdE9iamVjdC5hc3NpZ24ocmVzdWx0LCB0YXNrUmVzKTtcblx0XHRcdFx0Ly8gY29tcHV0ZSBleHRyYSBzdGF0cyBhbmQgZnJlZSByYXcgc2FtcGxlcyBhcyBlYXJseSBhcyBwb3NzaWJsZVxuXHRcdFx0XHRjb25zdCBzYW1wbGVzID0gcmVzdWx0LnNhbXBsZXM7XG5cdFx0XHRcdHJlc3VsdC5zYW1wbGVDb3VudCA9IHNhbXBsZXMubGVuZ3RoO1xuXHRcdFx0XHRyZXN1bHQubWVkaWFuID0gc2FtcGxlcy5sZW5ndGggJSAyID8gc2FtcGxlc1tNYXRoLmZsb29yKHNhbXBsZXMubGVuZ3RoIC8gMildIDogKHNhbXBsZXNbc2FtcGxlcy5sZW5ndGggLyAyXSArIHNhbXBsZXNbc2FtcGxlcy5sZW5ndGggLyAyIC0gMV0pIC8gMjtcblx0XHRcdFx0aWYgKCFydW5uZXIuY29uZmlnLmJlbmNobWFyaz8uaW5jbHVkZVNhbXBsZXMpIHJlc3VsdC5zYW1wbGVzLmxlbmd0aCA9IDA7XG5cdFx0XHRcdHVwZGF0ZVRhc2skMShcInRlc3QtZmluaXNoZWRcIiwgYmVuY2htYXJrKTtcblx0XHRcdH0sIHsgb25jZTogdHJ1ZSB9KTtcblx0XHRcdHRhc2suYWRkRXZlbnRMaXN0ZW5lcihcImVycm9yXCIsIChlKSA9PiB7XG5cdFx0XHRcdGNvbnN0IHRhc2sgPSBlLnRhc2s7XG5cdFx0XHRcdGRlZmVyLnJlamVjdChiZW5jaG1hcmsgPyB0YXNrLnJlc3VsdC5lcnJvciA6IGUpO1xuXHRcdFx0fSwgeyBvbmNlOiB0cnVlIH0pO1xuXHRcdH07XG5cdFx0YmVuY2htYXJrR3JvdXAuZm9yRWFjaCgoYmVuY2htYXJrKSA9PiB7XG5cdFx0XHRjb25zdCBiZW5jaG1hcmtJbnN0YW5jZSA9IG5ldyBCZW5jaChnZXRCZW5jaE9wdGlvbnMoYmVuY2htYXJrKSk7XG5cdFx0XHRjb25zdCBiZW5jaG1hcmtGbiA9IGdldEJlbmNoRm4oYmVuY2htYXJrKTtcblx0XHRcdGJlbmNobWFyay5yZXN1bHQgPSB7XG5cdFx0XHRcdHN0YXRlOiBcInJ1blwiLFxuXHRcdFx0XHRzdGFydFRpbWU6IHN0YXJ0LFxuXHRcdFx0XHRiZW5jaG1hcms6IGNyZWF0ZUJlbmNobWFya1Jlc3VsdChiZW5jaG1hcmsubmFtZSlcblx0XHRcdH07XG5cdFx0XHRjb25zdCB0YXNrID0gbmV3IFRhc2soYmVuY2htYXJrSW5zdGFuY2UsIGJlbmNobWFyay5uYW1lLCBiZW5jaG1hcmtGbik7XG5cdFx0XHRiZW5jaG1hcmtUYXNrcy5zZXQoYmVuY2htYXJrLCB0YXNrKTtcblx0XHRcdGFkZEJlbmNoVGFza0xpc3RlbmVyKHRhc2ssIGJlbmNobWFyayk7XG5cdFx0fSk7XG5cdFx0Y29uc3QgeyBzZXRUaW1lb3V0IH0gPSBnZXRTYWZlVGltZXJzKCk7XG5cdFx0Y29uc3QgdGFza3MgPSBbXTtcblx0XHRmb3IgKGNvbnN0IGJlbmNobWFyayBvZiBiZW5jaG1hcmtHcm91cCkge1xuXHRcdFx0Y29uc3QgdGFzayA9IGJlbmNobWFya1Rhc2tzLmdldChiZW5jaG1hcmspO1xuXHRcdFx0dXBkYXRlVGFzayQxKFwidGVzdC1wcmVwYXJlXCIsIGJlbmNobWFyayk7XG5cdFx0XHRhd2FpdCB0YXNrLndhcm11cCgpO1xuXHRcdFx0dGFza3MucHVzaChbYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHNldFRpbWVvdXQoYXN5bmMgKCkgPT4ge1xuXHRcdFx0XHRyZXNvbHZlKGF3YWl0IHRhc2sucnVuKCkpO1xuXHRcdFx0fSkpLCBiZW5jaG1hcmtdKTtcblx0XHR9XG5cdFx0c3VpdGUucmVzdWx0LmR1cmF0aW9uID0gcGVyZm9ybWFuY2Uubm93KCkgLSBzdGFydDtcblx0XHRzdWl0ZS5yZXN1bHQuc3RhdGUgPSBcInBhc3NcIjtcblx0XHR1cGRhdGVUYXNrJDEoXCJzdWl0ZS1maW5pc2hlZFwiLCBzdWl0ZSk7XG5cdFx0ZGVmZXIucmVzb2x2ZShudWxsKTtcblx0XHRhd2FpdCBkZWZlcjtcblx0fVxuXHRmdW5jdGlvbiB1cGRhdGVUYXNrJDEoZXZlbnQsIHRhc2spIHtcblx0XHR1cGRhdGVUYXNrKGV2ZW50LCB0YXNrLCBydW5uZXIpO1xuXHR9XG59XG5jbGFzcyBOb2RlQmVuY2htYXJrUnVubmVyIHtcblx0bW9kdWxlUnVubmVyO1xuXHRjb25zdHJ1Y3Rvcihjb25maWcpIHtcblx0XHR0aGlzLmNvbmZpZyA9IGNvbmZpZztcblx0fVxuXHRhc3luYyBpbXBvcnRUaW55YmVuY2goKSB7XG5cdFx0cmV0dXJuIGF3YWl0IGltcG9ydCgndGlueWJlbmNoJyk7XG5cdH1cblx0aW1wb3J0RmlsZShmaWxlcGF0aCwgc291cmNlKSB7XG5cdFx0aWYgKHNvdXJjZSA9PT0gXCJzZXR1cFwiKSB7XG5cdFx0XHRjb25zdCBtb2R1bGVOb2RlID0gZ2V0V29ya2VyU3RhdGUoKS5ldmFsdWF0ZWRNb2R1bGVzLmdldE1vZHVsZUJ5SWQoZmlsZXBhdGgpO1xuXHRcdFx0aWYgKG1vZHVsZU5vZGUpIGdldFdvcmtlclN0YXRlKCkuZXZhbHVhdGVkTW9kdWxlcy5pbnZhbGlkYXRlTW9kdWxlKG1vZHVsZU5vZGUpO1xuXHRcdH1cblx0XHRyZXR1cm4gdGhpcy5tb2R1bGVSdW5uZXIuaW1wb3J0KGZpbGVwYXRoKTtcblx0fVxuXHRhc3luYyBydW5TdWl0ZShzdWl0ZSkge1xuXHRcdGF3YWl0IHJ1bkJlbmNobWFya1N1aXRlKHN1aXRlLCB0aGlzKTtcblx0fVxuXHRhc3luYyBydW5UYXNrKCkge1xuXHRcdHRocm93IG5ldyBFcnJvcihcImB0ZXN0KClgIGFuZCBgaXQoKWAgaXMgb25seSBhdmFpbGFibGUgaW4gdGVzdCBtb2RlLlwiKTtcblx0fVxufVxuXG5jbGFzcyBUZXN0UnVubmVyIHtcblx0c25hcHNob3RDbGllbnQgPSBnZXRTbmFwc2hvdENsaWVudCgpO1xuXHR3b3JrZXJTdGF0ZSA9IGdldFdvcmtlclN0YXRlKCk7XG5cdG1vZHVsZVJ1bm5lcjtcblx0Y2FuY2VsUnVuID0gZmFsc2U7XG5cdGFzc2VydGlvbnNFcnJvcnMgPSAvKiBAX19QVVJFX18gKi8gbmV3IFdlYWtNYXAoKTtcblx0cG9vbCA9IHRoaXMud29ya2VyU3RhdGUuY3R4LnBvb2w7XG5cdF9vdGVsO1xuXHR2aXRlRW52aXJvbm1lbnQ7XG5cdHZpdGVNb2R1bGVSdW5uZXI7XG5cdGNvbnN0cnVjdG9yKGNvbmZpZykge1xuXHRcdHRoaXMuY29uZmlnID0gY29uZmlnO1xuXHRcdGNvbnN0IGVudmlyb25tZW50ID0gdGhpcy53b3JrZXJTdGF0ZS5lbnZpcm9ubWVudDtcblx0XHR0aGlzLnZpdGVFbnZpcm9ubWVudCA9IGVudmlyb25tZW50LnZpdGVFbnZpcm9ubWVudCB8fCBlbnZpcm9ubWVudC5uYW1lO1xuXHRcdHRoaXMudml0ZU1vZHVsZVJ1bm5lciA9IGNvbmZpZy5leHBlcmltZW50YWwudml0ZU1vZHVsZVJ1bm5lcjtcblx0fVxuXHRpbXBvcnRGaWxlKGZpbGVwYXRoLCBzb3VyY2UpIHtcblx0XHRpZiAoc291cmNlID09PSBcInNldHVwXCIpIHtcblx0XHRcdGNvbnN0IG1vZHVsZU5vZGUgPSB0aGlzLndvcmtlclN0YXRlLmV2YWx1YXRlZE1vZHVsZXMuZ2V0TW9kdWxlQnlJZChmaWxlcGF0aCk7XG5cdFx0XHRpZiAobW9kdWxlTm9kZSkgdGhpcy53b3JrZXJTdGF0ZS5ldmFsdWF0ZWRNb2R1bGVzLmludmFsaWRhdGVNb2R1bGUobW9kdWxlTm9kZSk7XG5cdFx0fVxuXHRcdHJldHVybiB0aGlzLl9vdGVsLiQoYHZpdGVzdC5tb2R1bGUuaW1wb3J0XyR7c291cmNlID09PSBcInNldHVwXCIgPyBcInNldHVwXCIgOiBcInNwZWNcIn1gLCB7IGF0dHJpYnV0ZXM6IHsgXCJjb2RlLmZpbGUucGF0aFwiOiBmaWxlcGF0aCB9IH0sICgpID0+IHtcblx0XHRcdGlmICghdGhpcy52aXRlTW9kdWxlUnVubmVyKSBmaWxlcGF0aCA9IGAke2ZpbGVwYXRofT92aXRlc3Q9JHtEYXRlLm5vdygpfWA7XG5cdFx0XHRyZXR1cm4gdGhpcy5tb2R1bGVSdW5uZXIuaW1wb3J0KGZpbGVwYXRoKTtcblx0XHR9KTtcblx0fVxuXHRvbkNvbGxlY3RTdGFydChmaWxlKSB7XG5cdFx0dGhpcy53b3JrZXJTdGF0ZS5jdXJyZW50ID0gZmlsZTtcblx0fVxuXHRvbkNsZWFudXBXb3JrZXJDb250ZXh0KGxpc3RlbmVyKSB7XG5cdFx0dGhpcy53b3JrZXJTdGF0ZS5vbkNsZWFudXAobGlzdGVuZXIpO1xuXHR9XG5cdG9uQWZ0ZXJSdW5GaWxlcygpIHtcblx0XHR0aGlzLnNuYXBzaG90Q2xpZW50LmNsZWFyKCk7XG5cdFx0dGhpcy53b3JrZXJTdGF0ZS5jdXJyZW50ID0gdm9pZCAwO1xuXHR9XG5cdGFzeW5jIG9uQWZ0ZXJSdW5TdWl0ZShzdWl0ZSkge1xuXHRcdGlmICh0aGlzLmNvbmZpZy5sb2dIZWFwVXNhZ2UgJiYgdHlwZW9mIHByb2Nlc3MgIT09IFwidW5kZWZpbmVkXCIpIHN1aXRlLnJlc3VsdC5oZWFwID0gcHJvY2Vzcy5tZW1vcnlVc2FnZSgpLmhlYXBVc2VkO1xuXHRcdGlmIChzdWl0ZS5tb2RlICE9PSBcInNraXBcIiAmJiBcImZpbGVwYXRoXCIgaW4gc3VpdGUpIHtcblx0XHRcdC8vIG1hcmsgc25hcHNob3RzIGluIHNraXBwZWQgdGVzdHMgYXMgbm90IG9ic29sZXRlXG5cdFx0XHRmb3IgKGNvbnN0IHRlc3Qgb2YgZ2V0VGVzdHMoc3VpdGUpKSBpZiAodGVzdC5tb2RlID09PSBcInNraXBcIikge1xuXHRcdFx0XHRjb25zdCBuYW1lID0gZ2V0TmFtZXModGVzdCkuc2xpY2UoMSkuam9pbihcIiA+IFwiKTtcblx0XHRcdFx0dGhpcy5zbmFwc2hvdENsaWVudC5za2lwVGVzdChzdWl0ZS5maWxlLmZpbGVwYXRoLCBuYW1lKTtcblx0XHRcdH1cblx0XHRcdGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMuc25hcHNob3RDbGllbnQuZmluaXNoKHN1aXRlLmZpbGUuZmlsZXBhdGgpO1xuXHRcdFx0aWYgKHRoaXMud29ya2VyU3RhdGUuY29uZmlnLnNuYXBzaG90T3B0aW9ucy51cGRhdGVTbmFwc2hvdCA9PT0gXCJub25lXCIgJiYgcmVzdWx0LnVuY2hlY2tlZCkge1xuXHRcdFx0XHRsZXQgbWVzc2FnZSA9IGBPYnNvbGV0ZSBzbmFwc2hvdHMgZm91bmQgd2hlbiBubyBzbmFwc2hvdCB1cGRhdGUgaXMgZXhwZWN0ZWQuXFxuYDtcblx0XHRcdFx0Zm9yIChjb25zdCBrZXkgb2YgcmVzdWx0LnVuY2hlY2tlZEtleXMpIG1lc3NhZ2UgKz0gYMK3ICR7a2V5fVxcbmA7XG5cdFx0XHRcdHN1aXRlLnJlc3VsdC5lcnJvcnMgPz89IFtdO1xuXHRcdFx0XHRzdWl0ZS5yZXN1bHQuZXJyb3JzLnB1c2gocHJvY2Vzc0Vycm9yKG5ldyBFcnJvcihtZXNzYWdlKSkpO1xuXHRcdFx0XHRzdWl0ZS5yZXN1bHQuc3RhdGUgPSBcImZhaWxcIjtcblx0XHRcdH1cblx0XHRcdGF3YWl0IHJwYygpLnNuYXBzaG90U2F2ZWQocmVzdWx0KTtcblx0XHR9XG5cdFx0dGhpcy53b3JrZXJTdGF0ZS5jdXJyZW50ID0gc3VpdGUuc3VpdGUgfHwgc3VpdGUuZmlsZTtcblx0fVxuXHRvbkFmdGVyUnVuVGFzayh0ZXN0KSB7XG5cdFx0aWYgKHRoaXMuY29uZmlnLmxvZ0hlYXBVc2FnZSAmJiB0eXBlb2YgcHJvY2VzcyAhPT0gXCJ1bmRlZmluZWRcIikgdGVzdC5yZXN1bHQuaGVhcCA9IHByb2Nlc3MubWVtb3J5VXNhZ2UoKS5oZWFwVXNlZDtcblx0XHR0aGlzLndvcmtlclN0YXRlLmN1cnJlbnQgPSB0ZXN0LnN1aXRlIHx8IHRlc3QuZmlsZTtcblx0fVxuXHRjYW5jZWwoX3JlYXNvbikge1xuXHRcdHRoaXMuY2FuY2VsUnVuID0gdHJ1ZTtcblx0fVxuXHRpbmplY3RWYWx1ZShrZXkpIHtcblx0XHQvLyBpbmplY3QgaGFzIGEgdmVyeSBsaW1pdGluZyB0eXBlIGNvbnRyb2xsZWQgYnkgUHJvdmlkZWRDb250ZXh0XG5cdFx0Ly8gc29tZSB0ZXN0cyBvdmVycmlkZSBpdCB3aGljaCBjYXVzZXMgdGhlIGJ1aWxkIHRvIGZhaWxcblx0XHRyZXR1cm4gaW5qZWN0KGtleSk7XG5cdH1cblx0YXN5bmMgb25CZWZvcmVSdW5UYXNrKHRlc3QpIHtcblx0XHRpZiAodGhpcy5jYW5jZWxSdW4pIHRlc3QubW9kZSA9IFwic2tpcFwiO1xuXHRcdGlmICh0ZXN0Lm1vZGUgIT09IFwicnVuXCIgJiYgdGVzdC5tb2RlICE9PSBcInF1ZXVlZFwiKSByZXR1cm47XG5cdFx0dGhpcy53b3JrZXJTdGF0ZS5jdXJyZW50ID0gdGVzdDtcblx0fVxuXHRhc3luYyBvbkJlZm9yZVJ1blN1aXRlKHN1aXRlKSB7XG5cdFx0aWYgKHRoaXMuY2FuY2VsUnVuKSBzdWl0ZS5tb2RlID0gXCJza2lwXCI7XG5cdFx0Ly8gaW5pdGlhbGl6ZSBzbmFwc2hvdCBzdGF0ZSBiZWZvcmUgcnVubmluZyBmaWxlIHN1aXRlXG5cdFx0aWYgKHN1aXRlLm1vZGUgIT09IFwic2tpcFwiICYmIFwiZmlsZXBhdGhcIiBpbiBzdWl0ZSkgYXdhaXQgdGhpcy5zbmFwc2hvdENsaWVudC5zZXR1cChzdWl0ZS5maWxlLmZpbGVwYXRoLCB0aGlzLndvcmtlclN0YXRlLmNvbmZpZy5zbmFwc2hvdE9wdGlvbnMpO1xuXHRcdHRoaXMud29ya2VyU3RhdGUuY3VycmVudCA9IHN1aXRlO1xuXHR9XG5cdG9uQmVmb3JlVHJ5VGFzayh0ZXN0KSB7XG5cdFx0Y2xlYXJNb2R1bGVNb2Nrcyh0aGlzLmNvbmZpZyk7XG5cdFx0dGhpcy5zbmFwc2hvdENsaWVudC5jbGVhclRlc3QodGVzdC5maWxlLmZpbGVwYXRoLCB0ZXN0LmlkKTtcblx0XHRzZXRTdGF0ZSh7XG5cdFx0XHRhc3NlcnRpb25DYWxsczogMCxcblx0XHRcdGlzRXhwZWN0aW5nQXNzZXJ0aW9uczogZmFsc2UsXG5cdFx0XHRpc0V4cGVjdGluZ0Fzc2VydGlvbnNFcnJvcjogbnVsbCxcblx0XHRcdGV4cGVjdGVkQXNzZXJ0aW9uc051bWJlcjogbnVsbCxcblx0XHRcdGV4cGVjdGVkQXNzZXJ0aW9uc051bWJlckVycm9yR2VuOiBudWxsLFxuXHRcdFx0Y3VycmVudFRlc3ROYW1lOiBnZXRUZXN0TmFtZSh0ZXN0KSxcblx0XHRcdHNuYXBzaG90U3RhdGU6IHRoaXMuc25hcHNob3RDbGllbnQuZ2V0U25hcHNob3RTdGF0ZSh0ZXN0LmZpbGUuZmlsZXBhdGgpXG5cdFx0fSwgZ2xvYmFsVGhpc1tHTE9CQUxfRVhQRUNUXSk7XG5cdH1cblx0b25BZnRlclRyeVRhc2sodGVzdCkge1xuXHRcdGNvbnN0IHsgYXNzZXJ0aW9uQ2FsbHMsIGV4cGVjdGVkQXNzZXJ0aW9uc051bWJlciwgZXhwZWN0ZWRBc3NlcnRpb25zTnVtYmVyRXJyb3JHZW4sIGlzRXhwZWN0aW5nQXNzZXJ0aW9ucywgaXNFeHBlY3RpbmdBc3NlcnRpb25zRXJyb3IgfSA9IHRlc3QuY29udGV4dC5fbG9jYWwgPyB0ZXN0LmNvbnRleHQuZXhwZWN0LmdldFN0YXRlKCkgOiBnZXRTdGF0ZShnbG9iYWxUaGlzW0dMT0JBTF9FWFBFQ1RdKTtcblx0XHRpZiAoZXhwZWN0ZWRBc3NlcnRpb25zTnVtYmVyICE9PSBudWxsICYmIGFzc2VydGlvbkNhbGxzICE9PSBleHBlY3RlZEFzc2VydGlvbnNOdW1iZXIpIHRocm93IGV4cGVjdGVkQXNzZXJ0aW9uc051bWJlckVycm9yR2VuKCk7XG5cdFx0aWYgKGlzRXhwZWN0aW5nQXNzZXJ0aW9ucyA9PT0gdHJ1ZSAmJiBhc3NlcnRpb25DYWxscyA9PT0gMCkgdGhyb3cgaXNFeHBlY3RpbmdBc3NlcnRpb25zRXJyb3I7XG5cdFx0aWYgKHRoaXMuY29uZmlnLmV4cGVjdC5yZXF1aXJlQXNzZXJ0aW9ucyAmJiBhc3NlcnRpb25DYWxscyA9PT0gMCkgdGhyb3cgdGhpcy5hc3NlcnRpb25zRXJyb3JzLmdldCh0ZXN0KTtcblx0fVxuXHRleHRlbmRUYXNrQ29udGV4dChjb250ZXh0KSB7XG5cdFx0Ly8gY3JlYXRlIGVycm9yIGR1cmluZyB0aGUgdGVzdCBpbml0aWFsaXphdGlvbiBzbyB3ZSBoYXZlIGEgbmljZSBzdGFjayB0cmFjZVxuXHRcdGlmICh0aGlzLmNvbmZpZy5leHBlY3QucmVxdWlyZUFzc2VydGlvbnMpIHRoaXMuYXNzZXJ0aW9uc0Vycm9ycy5zZXQoY29udGV4dC50YXNrLCAvKiBAX19QVVJFX18gKi8gbmV3IEVycm9yKFwiZXhwZWN0ZWQgYW55IG51bWJlciBvZiBhc3NlcnRpb24sIGJ1dCBnb3Qgbm9uZVwiKSk7XG5cdFx0bGV0IF9leHBlY3Q7XG5cdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGNvbnRleHQsIFwiZXhwZWN0XCIsIHsgZ2V0KCkge1xuXHRcdFx0aWYgKCFfZXhwZWN0KSBfZXhwZWN0ID0gY3JlYXRlRXhwZWN0KGNvbnRleHQudGFzayk7XG5cdFx0XHRyZXR1cm4gX2V4cGVjdDtcblx0XHR9IH0pO1xuXHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShjb250ZXh0LCBcIl9sb2NhbFwiLCB7IGdldCgpIHtcblx0XHRcdHJldHVybiBfZXhwZWN0ICE9IG51bGw7XG5cdFx0fSB9KTtcblx0XHRyZXR1cm4gY29udGV4dDtcblx0fVxuXHRnZXRJbXBvcnREdXJhdGlvbnMoKSB7XG5cdFx0Y29uc3QgeyBsaW1pdCB9ID0gdGhpcy5jb25maWcuZXhwZXJpbWVudGFsLmltcG9ydER1cmF0aW9ucztcblx0XHQvLyBza2lwIHNvcnRpbmcgaWYgbGltaXQgaXMgMFxuXHRcdGlmIChsaW1pdCA9PT0gMCkgcmV0dXJuIHt9O1xuXHRcdC8vIFNvcnQgYnkgZHVyYXRpb24gZGVzY2VuZGluZyBhbmQga2VlcCB0b3AgZW50cmllc1xuXHRcdGNvbnN0IHNvcnRlZEVudHJpZXMgPSBbLi4udGhpcy53b3JrZXJTdGF0ZS5tb2R1bGVFeGVjdXRpb25JbmZvPy5lbnRyaWVzKCkgfHwgW11dLnNvcnQoKFssIGFdLCBbLCBiXSkgPT4gYi5kdXJhdGlvbiAtIGEuZHVyYXRpb24pLnNsaWNlKDAsIGxpbWl0KTtcblx0XHRjb25zdCBpbXBvcnREdXJhdGlvbnMgPSB7fTtcblx0XHRmb3IgKGNvbnN0IFtmaWxlcGF0aCwgeyBkdXJhdGlvbiwgc2VsZlRpbWUsIGV4dGVybmFsLCBpbXBvcnRlciB9XSBvZiBzb3J0ZWRFbnRyaWVzKSBpbXBvcnREdXJhdGlvbnNbbm9ybWFsaXplKGZpbGVwYXRoKV0gPSB7XG5cdFx0XHRzZWxmVGltZSxcblx0XHRcdHRvdGFsVGltZTogZHVyYXRpb24sXG5cdFx0XHRleHRlcm5hbCxcblx0XHRcdGltcG9ydGVyXG5cdFx0fTtcblx0XHRyZXR1cm4gaW1wb3J0RHVyYXRpb25zO1xuXHR9XG5cdHRyYWNlID0gKG5hbWUsIGF0dHJpYnV0ZXMsIGNiKSA9PiB7XG5cdFx0Y29uc3Qgb3B0aW9ucyA9IHR5cGVvZiBhdHRyaWJ1dGVzID09PSBcIm9iamVjdFwiID8geyBhdHRyaWJ1dGVzIH0gOiB7fTtcblx0XHRyZXR1cm4gdGhpcy5fb3RlbC4kKGB2aXRlc3QudGVzdC5ydW5uZXIuJHtuYW1lfWAsIG9wdGlvbnMsIGNiIHx8IGF0dHJpYnV0ZXMpO1xuXHR9O1xuXHRfX3NldFRyYWNlcyh0cmFjZXMpIHtcblx0XHR0aGlzLl9vdGVsID0gdHJhY2VzO1xuXHR9XG5cdHN0YXRpYyBjcmVhdGVUYXNrQ29sbGVjdG9yID0gY3JlYXRlVGFza0NvbGxlY3Rvcjtcblx0c3RhdGljIGdldEN1cnJlbnRTdWl0ZSA9IGdldEN1cnJlbnRTdWl0ZTtcblx0c3RhdGljIGdldEN1cnJlbnRUZXN0ID0gZ2V0Q3VycmVudFRlc3Q7XG5cdHN0YXRpYyBjcmVhdGVDaGFpbmFibGUgPSBjcmVhdGVDaGFpbmFibGU7XG5cdHN0YXRpYyBnZXRTdWl0ZUhvb2tzID0gZ2V0SG9va3M7XG5cdHN0YXRpYyBnZXRUZXN0Rm4gPSBnZXRGbjtcblx0c3RhdGljIHNldFN1aXRlSG9va3MgPSBnZXRIb29rcztcblx0c3RhdGljIHNldFRlc3RGbiA9IGdldEZuO1xuXHRzdGF0aWMgbWF0Y2hlc1RhZ3MgPSBtYXRjaGVzVGFncztcblx0LyoqXG5cdCogQGRlcHJlY2F0ZWRcblx0Ki9cblx0c3RhdGljIGdldEJlbmNoRm4gPSBnZXRCZW5jaEZuO1xuXHQvKipcblx0KiBAZGVwcmVjYXRlZFxuXHQqL1xuXHRzdGF0aWMgZ2V0QmVuY2hPcHRpb25zID0gZ2V0QmVuY2hPcHRpb25zO1xufVxuZnVuY3Rpb24gY2xlYXJNb2R1bGVNb2Nrcyhjb25maWcpIHtcblx0Y29uc3QgeyBjbGVhck1vY2tzLCBtb2NrUmVzZXQsIHJlc3RvcmVNb2NrcywgdW5zdHViRW52cywgdW5zdHViR2xvYmFscyB9ID0gY29uZmlnO1xuXHRpZiAocmVzdG9yZU1vY2tzKSB2aS5yZXN0b3JlQWxsTW9ja3MoKTtcblx0aWYgKG1vY2tSZXNldCkgdmkucmVzZXRBbGxNb2NrcygpO1xuXHRpZiAoY2xlYXJNb2NrcykgdmkuY2xlYXJBbGxNb2NrcygpO1xuXHRpZiAodW5zdHViRW52cykgdmkudW5zdHViQWxsRW52cygpO1xuXHRpZiAodW5zdHViR2xvYmFscykgdmkudW5zdHViQWxsR2xvYmFscygpO1xufVxuXG5leHBvcnQgeyBOb2RlQmVuY2htYXJrUnVubmVyIGFzIE4sIFNuYXBzaG90cyBhcyBTLCBUZXN0UnVubmVyIGFzIFQsIGFzc2VydCBhcyBhLCB2aXRlc3QgYXMgYiwgY3JlYXRlRXhwZWN0IGFzIGMsIGdsb2JhbEV4cGVjdCBhcyBnLCBpbmplY3QgYXMgaSwgc2hvdWxkIGFzIHMsIHZpIGFzIHYgfTtcbiJdLCJ4X2dvb2dsZV9pZ25vcmVMaXN0IjpbMF0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBZ0JBLElBQUksZ0JBQWdCLENBQUM7QUFFckIsSUFBSTtBQUNKLElBQUk7QUFFSixTQUFTLGdCQUFpQjtDQUN6QixJQUFJLG1CQUFtQixPQUFPO0NBQzlCLG9CQUFvQjs7Ozs7Q0FNcEIsSUFBSTs7Q0FHSixJQUFJLE9BQU8sbUJBQW1CLGFBRTFCLGVBQWU7TUFDWixJQUFJLE9BQU8sV0FBVyxhQUV6QixlQUFlO01BR2YsZUFBZTtDQUduQixTQUFTO0NBQ1QsT0FBTztBQUNSO0FBRUEsSUFBSTtBQUNKLElBQUk7QUFFSixTQUFTLHVCQUF3QjtDQUNoQyxJQUFJLDBCQUEwQixPQUFPO0NBQ3JDLDJC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
|