From 116cc8e6bda358956540b59577a195ee85f439ff Mon Sep 17 00:00:00 2001 From: Anandan Date: Fri, 3 Apr 2026 18:48:00 +0530 Subject: [PATCH] Route third-party first-run setup into the provider wizard (#261) The login picker previously sent third-party users to a dead-end info screen that only mentioned env vars. This change reuses the existing provider wizard from the login flow so first-run setup can continue without requiring slash command access first. Constraint: The existing provider setup logic must remain the single source of truth Rejected: Build a separate third-party auth wizard in ConsoleOAuthFlow | would duplicate provider setup behavior and drift over time Confidence: high Scope-risk: moderate Reversibility: clean Directive: Keep third-party onboarding routed through ProviderWizard unless the provider command flow is intentionally redesigned Tested: bun test src/components/ConsoleOAuthFlow.test.tsx src/commands/provider/provider.test.tsx Tested: tsc --noEmit via project diagnostics Not-tested: Live gh-authenticated push and PR creation path Co-authored-by: anandh8x --- src/commands/login/login.tsx | 230 +++++----- src/commands/provider/provider.tsx | 6 +- src/components/ConsoleOAuthFlow.test.tsx | 117 ++++++ src/components/ConsoleOAuthFlow.tsx | 511 ++++++++++------------- 4 files changed, 470 insertions(+), 394 deletions(-) create mode 100644 src/components/ConsoleOAuthFlow.test.tsx diff --git a/src/commands/login/login.tsx b/src/commands/login/login.tsx index 8eeec9e3..4dcaa878 100644 --- a/src/commands/login/login.tsx +++ b/src/commands/login/login.tsx @@ -1,104 +1,132 @@ -import { c as _c } from "react-compiler-runtime"; -import { feature } from 'bun:bundle'; -import * as React from 'react'; -import { resetCostState } from '../../bootstrap/state.js'; -import { clearTrustedDeviceToken, enrollTrustedDevice } from '../../bridge/trustedDevice.js'; -import type { LocalJSXCommandContext } from '../../commands.js'; -import { ConfigurableShortcutHint } from '../../components/ConfigurableShortcutHint.js'; -import { ConsoleOAuthFlow } from '../../components/ConsoleOAuthFlow.js'; -import { Dialog } from '../../components/design-system/Dialog.js'; -import { useMainLoopModel } from '../../hooks/useMainLoopModel.js'; -import { Text } from '../../ink.js'; -import { refreshGrowthBookAfterAuthChange } from '../../services/analytics/growthbook.js'; -import { refreshPolicyLimits } from '../../services/policyLimits/index.js'; -import { refreshRemoteManagedSettings } from '../../services/remoteManagedSettings/index.js'; -import type { LocalJSXCommandOnDone } from '../../types/command.js'; -import { stripSignatureBlocks } from '../../utils/messages.js'; -import { checkAndDisableAutoModeIfNeeded, checkAndDisableBypassPermissionsIfNeeded, resetAutoModeGateCheck, resetBypassPermissionsCheck } from '../../utils/permissions/bypassPermissionsKillswitch.js'; -import { resetUserCache } from '../../utils/user.js'; -export async function call(onDone: LocalJSXCommandOnDone, context: LocalJSXCommandContext): Promise { - return { - context.onChangeAPIKey(); - // Signature-bearing blocks (thinking, connector_text) are bound to the API key — - // strip them so the new key doesn't reject stale signatures. - context.setMessages(stripSignatureBlocks); - if (success) { - // Post-login refresh logic. Keep in sync with onboarding in src/interactiveHelpers.tsx - // Reset cost state when switching accounts - resetCostState(); - // Refresh remotely managed settings after login (non-blocking) - void refreshRemoteManagedSettings(); - // Refresh policy limits after login (non-blocking) - void refreshPolicyLimits(); - // Clear user data cache BEFORE GrowthBook refresh so it picks up fresh credentials - resetUserCache(); - // Refresh GrowthBook after login to get updated feature flags (e.g., for claude.ai MCPs) - refreshGrowthBookAfterAuthChange(); - // Clear any stale trusted device token from a previous account before - // re-enrolling — prevents sending the old token on bridge calls while - // the async enrollTrustedDevice() is in-flight. - clearTrustedDeviceToken(); - // Enroll as a trusted device for Remote Control (10-min fresh-session window) - void enrollTrustedDevice(); - // Reset killswitch gate checks and re-run with new org - resetBypassPermissionsCheck(); - const appState = context.getAppState(); - void checkAndDisableBypassPermissionsIfNeeded(appState.toolPermissionContext, context.setAppState); - if (feature('TRANSCRIPT_CLASSIFIER')) { - resetAutoModeGateCheck(); - void checkAndDisableAutoModeIfNeeded(appState.toolPermissionContext, context.setAppState, appState.fastMode); - } - // Increment authVersion to trigger re-fetching of auth-dependent data in hooks (e.g., MCP servers) - context.setAppState(prev => ({ - ...prev, - authVersion: prev.authVersion + 1 - })); +import { feature } from 'bun:bundle' +import * as React from 'react' + +import { resetCostState } from '../../bootstrap/state.js' +import { + clearTrustedDeviceToken, + enrollTrustedDevice, +} from '../../bridge/trustedDevice.js' +import type { LocalJSXCommandContext } from '../../commands.js' +import { ConfigurableShortcutHint } from '../../components/ConfigurableShortcutHint.js' +import { + ConsoleOAuthFlow, + type ConsoleOAuthFlowResult, +} from '../../components/ConsoleOAuthFlow.js' +import { Dialog } from '../../components/design-system/Dialog.js' +import { useMainLoopModel } from '../../hooks/useMainLoopModel.js' +import { Text } from '../../ink.js' +import { refreshGrowthBookAfterAuthChange } from '../../services/analytics/growthbook.js' +import { refreshPolicyLimits } from '../../services/policyLimits/index.js' +import { refreshRemoteManagedSettings } from '../../services/remoteManagedSettings/index.js' +import type { LocalJSXCommandOnDone } from '../../types/command.js' +import { stripSignatureBlocks } from '../../utils/messages.js' +import { + checkAndDisableAutoModeIfNeeded, + checkAndDisableBypassPermissionsIfNeeded, + resetAutoModeGateCheck, + resetBypassPermissionsCheck, +} from '../../utils/permissions/bypassPermissionsKillswitch.js' +import { resetUserCache } from '../../utils/user.js' + +type LoginCompletion = + | ConsoleOAuthFlowResult + | { + type: 'cancel' } - onDone(success ? 'Login successful' : 'Login interrupted'); - }} />; + +export async function call( + onDone: LocalJSXCommandOnDone, + context: LocalJSXCommandContext, +): Promise { + return ( + { + if (result.type === 'cancel') { + onDone('Login interrupted') + return + } + + if (result.type === 'provider-setup') { + onDone(result.message, { display: 'system' }) + return + } + + context.onChangeAPIKey() + // Signature-bearing blocks (thinking, connector_text) are bound to the + // API key. Strip them so the new key doesn't reject stale signatures. + context.setMessages(stripSignatureBlocks) + + // Post-login refresh logic. Keep in sync with onboarding in + // src/interactiveHelpers.tsx. + resetCostState() + void refreshRemoteManagedSettings() + void refreshPolicyLimits() + resetUserCache() + refreshGrowthBookAfterAuthChange() + + // Clear any stale trusted device token from a previous account before + // re-enrolling to avoid sending the old token while enrollment is + // in flight. + clearTrustedDeviceToken() + void enrollTrustedDevice() + + resetBypassPermissionsCheck() + const appState = context.getAppState() + void checkAndDisableBypassPermissionsIfNeeded( + appState.toolPermissionContext, + context.setAppState, + ) + + if (feature('TRANSCRIPT_CLASSIFIER')) { + resetAutoModeGateCheck() + void checkAndDisableAutoModeIfNeeded( + appState.toolPermissionContext, + context.setAppState, + appState.fastMode, + ) + } + + context.setAppState(prev => ({ + ...prev, + authVersion: prev.authVersion + 1, + })) + + onDone('Login successful') + }} + /> + ) } -export function Login(props) { - const $ = _c(12); - const mainLoopModel = useMainLoopModel(); - let t0; - if ($[0] !== mainLoopModel || $[1] !== props) { - t0 = () => props.onDone(false, mainLoopModel); - $[0] = mainLoopModel; - $[1] = props; - $[2] = t0; - } else { - t0 = $[2]; - } - let t1; - if ($[3] !== mainLoopModel || $[4] !== props) { - t1 = () => props.onDone(true, mainLoopModel); - $[3] = mainLoopModel; - $[4] = props; - $[5] = t1; - } else { - t1 = $[5]; - } - let t2; - if ($[6] !== props.startingMessage || $[7] !== t1) { - t2 = ; - $[6] = props.startingMessage; - $[7] = t1; - $[8] = t2; - } else { - t2 = $[8]; - } - let t3; - if ($[9] !== t0 || $[10] !== t2) { - t3 = {t2}; - $[9] = t0; - $[10] = t2; - $[11] = t3; - } else { - t3 = $[11]; - } - return t3; + +export function Login(props: { + onDone: (result: LoginCompletion, mainLoopModel: string) => void + startingMessage?: string +}): React.ReactNode { + const mainLoopModel = useMainLoopModel() + + return ( + props.onDone({ type: 'cancel' }, mainLoopModel)} + color="permission" + inputGuide={exitState => + exitState.pending ? ( + Press {exitState.keyName} again to exit + ) : ( + + ) + } + > + + props.onDone(result ?? { type: 'cancel' }, mainLoopModel) + } + startingMessage={props.startingMessage} + /> + + ) } -function _temp(exitState) { - return exitState.pending ? Press {exitState.keyName} again to exit : ; -} -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJmZWF0dXJlIiwiUmVhY3QiLCJyZXNldENvc3RTdGF0ZSIsImNsZWFyVHJ1c3RlZERldmljZVRva2VuIiwiZW5yb2xsVHJ1c3RlZERldmljZSIsIkxvY2FsSlNYQ29tbWFuZENvbnRleHQiLCJDb25maWd1cmFibGVTaG9ydGN1dEhpbnQiLCJDb25zb2xlT0F1dGhGbG93IiwiRGlhbG9nIiwidXNlTWFpbkxvb3BNb2RlbCIsIlRleHQiLCJyZWZyZXNoR3Jvd3RoQm9va0FmdGVyQXV0aENoYW5nZSIsInJlZnJlc2hQb2xpY3lMaW1pdHMiLCJyZWZyZXNoUmVtb3RlTWFuYWdlZFNldHRpbmdzIiwiTG9jYWxKU1hDb21tYW5kT25Eb25lIiwic3RyaXBTaWduYXR1cmVCbG9ja3MiLCJjaGVja0FuZERpc2FibGVBdXRvTW9kZUlmTmVlZGVkIiwiY2hlY2tBbmREaXNhYmxlQnlwYXNzUGVybWlzc2lvbnNJZk5lZWRlZCIsInJlc2V0QXV0b01vZGVHYXRlQ2hlY2siLCJyZXNldEJ5cGFzc1Blcm1pc3Npb25zQ2hlY2siLCJyZXNldFVzZXJDYWNoZSIsImNhbGwiLCJvbkRvbmUiLCJjb250ZXh0IiwiUHJvbWlzZSIsIlJlYWN0Tm9kZSIsInN1Y2Nlc3MiLCJvbkNoYW5nZUFQSUtleSIsInNldE1lc3NhZ2VzIiwiYXBwU3RhdGUiLCJnZXRBcHBTdGF0ZSIsInRvb2xQZXJtaXNzaW9uQ29udGV4dCIsInNldEFwcFN0YXRlIiwiZmFzdE1vZGUiLCJwcmV2IiwiYXV0aFZlcnNpb24iLCJMb2dpbiIsInByb3BzIiwiJCIsIl9jIiwibWFpbkxvb3BNb2RlbCIsInQwIiwidDEiLCJ0MiIsInN0YXJ0aW5nTWVzc2FnZSIsInQzIiwiX3RlbXAiLCJleGl0U3RhdGUiLCJwZW5kaW5nIiwia2V5TmFtZSJdLCJzb3VyY2VzIjpbImxvZ2luLnRzeCJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBmZWF0dXJlIH0gZnJvbSAnYnVuOmJ1bmRsZSdcbmltcG9ydCAqIGFzIFJlYWN0IGZyb20gJ3JlYWN0J1xuaW1wb3J0IHsgcmVzZXRDb3N0U3RhdGUgfSBmcm9tICcuLi8uLi9ib290c3RyYXAvc3RhdGUuanMnXG5pbXBvcnQge1xuICBjbGVhclRydXN0ZWREZXZpY2VUb2tlbixcbiAgZW5yb2xsVHJ1c3RlZERldmljZSxcbn0gZnJvbSAnLi4vLi4vYnJpZGdlL3RydXN0ZWREZXZpY2UuanMnXG5pbXBvcnQgdHlwZSB7IExvY2FsSlNYQ29tbWFuZENvbnRleHQgfSBmcm9tICcuLi8uLi9jb21tYW5kcy5qcydcbmltcG9ydCB7IENvbmZpZ3VyYWJsZVNob3J0Y3V0SGludCB9IGZyb20gJy4uLy4uL2NvbXBvbmVudHMvQ29uZmlndXJhYmxlU2hvcnRjdXRIaW50LmpzJ1xuaW1wb3J0IHsgQ29uc29sZU9BdXRoRmxvdyB9IGZyb20gJy4uLy4uL2NvbXBvbmVudHMvQ29uc29sZU9BdXRoRmxvdy5qcydcbmltcG9ydCB7IERpYWxvZyB9IGZyb20gJy4uLy4uL2NvbXBvbmVudHMvZGVzaWduLXN5c3RlbS9EaWFsb2cuanMnXG5pbXBvcnQgeyB1c2VNYWluTG9vcE1vZGVsIH0gZnJvbSAnLi4vLi4vaG9va3MvdXNlTWFpbkxvb3BNb2RlbC5qcydcbmltcG9ydCB7IFRleHQgfSBmcm9tICcuLi8uLi9pbmsuanMnXG5pbXBvcnQgeyByZWZyZXNoR3Jvd3RoQm9va0FmdGVyQXV0aENoYW5nZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL2FuYWx5dGljcy9ncm93dGhib29rLmpzJ1xuaW1wb3J0IHsgcmVmcmVzaFBvbGljeUxpbWl0cyB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL3BvbGljeUxpbWl0cy9pbmRleC5qcydcbmltcG9ydCB7IHJlZnJlc2hSZW1vdGVNYW5hZ2VkU2V0dGluZ3MgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9yZW1vdGVNYW5hZ2VkU2V0dGluZ3MvaW5kZXguanMnXG5pbXBvcnQgdHlwZSB7IExvY2FsSlNYQ29tbWFuZE9uRG9uZSB9IGZyb20gJy4uLy4uL3R5cGVzL2NvbW1hbmQuanMnXG5pbXBvcnQgeyBzdHJpcFNpZ25hdHVyZUJsb2NrcyB9IGZyb20gJy4uLy4uL3V0aWxzL21lc3NhZ2VzLmpzJ1xuaW1wb3J0IHtcbiAgY2hlY2tBbmREaXNhYmxlQXV0b01vZGVJZk5lZWRlZCxcbiAgY2hlY2tBbmREaXNhYmxlQnlwYXNzUGVybWlzc2lvbnNJZk5lZWRlZCxcbiAgcmVzZXRBdXRvTW9kZUdhdGVDaGVjayxcbiAgcmVzZXRCeXBhc3NQZXJtaXNzaW9uc0NoZWNrLFxufSBmcm9tICcuLi8uLi91dGlscy9wZXJtaXNzaW9ucy9ieXBhc3NQZXJtaXNzaW9uc0tpbGxzd2l0Y2guanMnXG5pbXBvcnQgeyByZXNldFVzZXJDYWNoZSB9IGZyb20gJy4uLy4uL3V0aWxzL3VzZXIuanMnXG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjYWxsKFxuICBvbkRvbmU6IExvY2FsSlNYQ29tbWFuZE9uRG9uZSxcbiAgY29udGV4dDogTG9jYWxKU1hDb21tYW5kQ29udGV4dCxcbik6IFByb21pc2U8UmVhY3QuUmVhY3ROb2RlPiB7XG4gIHJldHVybiAoXG4gICAgPExvZ2luXG4gICAgICBvbkRvbmU9e2FzeW5jIHN1Y2Nlc3MgPT4ge1xuICAgICAgICBjb250ZXh0Lm9uQ2hhbmdlQVBJS2V5KClcbiAgICAgICAgLy8gU2lnbmF0dXJlLWJlYXJpbmcgYmxvY2tzICh0aGlua2luZywgY29ubmVjdG9yX3RleHQpIGFyZSBib3VuZCB0byB0aGUgQVBJIGtleSDigJRcbiAgICAgICAgLy8gc3RyaXAgdGhlbSBzbyB0aGUgbmV3IGtleSBkb2Vzbid0IHJlamVjdCBzdGFsZSBzaWduYXR1cmVzLlxuICAgICAgICBjb250ZXh0LnNldE1lc3NhZ2VzKHN0cmlwU2lnbmF0dXJlQmxvY2tzKVxuICAgICAgICBpZiAoc3VjY2Vzcykge1xuICAgICAgICAgIC8vIFBvc3QtbG9naW4gcmVmcmVzaCBsb2dpYy4gS2VlcCBpbiBzeW5jIHdpdGggb25ib2FyZGluZyBpbiBzcmMvaW50ZXJhY3RpdmVIZWxwZXJzLnRzeFxuICAgICAgICAgIC8vIFJlc2V0IGNvc3Qgc3RhdGUgd2hlbiBzd2l0Y2hpbmcgYWNjb3VudHNcbiAgICAgICAgICByZXNldENvc3RTdGF0ZSgpXG4gICAgICAgICAgLy8gUmVmcmVzaCByZW1vdGVseSBtYW5hZ2VkIHNldHRpbmdzIGFmdGVyIGxvZ2luIChub24tYmxvY2tpbmcpXG4gICAgICAgICAgdm9pZCByZWZyZXNoUmVtb3RlTWFuYWdlZFNldHRpbmdzKClcbiAgICAgICAgICAvLyBSZWZyZXNoIHBvbGljeSBsaW1pdHMgYWZ0ZXIgbG9naW4gKG5vbi1ibG9ja2luZylcbiAgICAgICAgICB2b2lkIHJlZnJlc2hQb2xpY3lMaW1pdHMoKVxuICAgICAgICAgIC8vIENsZWFyIHVzZXIgZGF0YSBjYWNoZSBCRUZPUkUgR3Jvd3RoQm9vayByZWZyZXNoIHNvIGl0IHBpY2tzIHVwIGZyZXNoIGNyZWRlbnRpYWxzXG4gICAgICAgICAgcmVzZXRVc2VyQ2FjaGUoKVxuICAgICAgICAgIC8vIFJlZnJlc2ggR3Jvd3RoQm9vayBhZnRlciBsb2dpbiB0byBnZXQgdXBkYXRlZCBmZWF0dXJlIGZsYWdzIChlLmcuLCBmb3IgY2xhdWRlLmFpIE1DUHMpXG4gICAgICAgICAgcmVmcmVzaEdyb3d0aEJvb2tBZnRlckF1dGhDaGFuZ2UoKVxuICAgICAgICAgIC8vIENsZWFyIGFueSBzdGFsZSB0cnVzdGVkIGRldmljZSB0b2tlbiBmcm9tIGEgcHJldmlvdXMgYWNjb3VudCBiZWZvcmVcbiAgICAgICAgICAvLyByZS1lbnJvbGxpbmcg4oCUIHByZXZlbnRzIHNlbmRpbmcgdGhlIG9sZCB0b2tlbiBvbiBicmlkZ2UgY2FsbHMgd2hpbGVcbiAgICAgICAgICAvLyB0aGUgYXN5bmMgZW5yb2xsVHJ1c3RlZERldmljZSgpIGlzIGluLWZsaWdodC5cbiAgICAgICAgICBjbGVhclRydXN0ZWREZXZpY2VUb2tlbigpXG4gICAgICAgICAgLy8gRW5yb2xsIGFzIGEgdHJ1c3RlZCBkZXZpY2UgZm9yIFJlbW90ZSBDb250cm9sICgxMC1taW4gZnJlc2gtc2Vzc2lvbiB3aW5kb3cpXG4gICAgICAgICAgdm9pZCBlbnJvbGxUcnVzdGVkRGV2aWNlKClcbiAgICAgICAgICAvLyBSZXNldCBraWxsc3dpdGNoIGdhdGUgY2hlY2tzIGFuZCByZS1ydW4gd2l0aCBuZXcgb3JnXG4gICAgICAgICAgcmVzZXRCeXBhc3NQZXJtaXNzaW9uc0NoZWNrKClcbiAgICAgICAgICBjb25zdCBhcHBTdGF0ZSA9IGNvbnRleHQuZ2V0QXBwU3RhdGUoKVxuICAgICAgICAgIHZvaWQgY2hlY2tBbmREaXNhYmxlQnlwYXNzUGVybWlzc2lvbnNJZk5lZWRlZChcbiAgICAgICAgICAgIGFwcFN0YXRlLnRvb2xQZXJtaXNzaW9uQ29udGV4dCxcbiAgICAgICAgICAgIGNvbnRleHQuc2V0QXBwU3RhdGUsXG4gICAgICAgICAgKVxuICAgICAgICAgIGlmIChmZWF0dXJlKCdUUkFOU0NSSVBUX0NMQVNTSUZJRVInKSkge1xuICAgICAgICAgICAgcmVzZXRBdXRvTW9kZUdhdGVDaGVjaygpXG4gICAgICAgICAgICB2b2lkIGNoZWNrQW5kRGlzYWJsZUF1dG9Nb2RlSWZOZWVkZWQoXG4gICAgICAgICAgICAgIGFwcFN0YXRlLnRvb2xQZXJtaXNzaW9uQ29udGV4dCxcbiAgICAgICAgICAgICAgY29udGV4dC5zZXRBcHBTdGF0ZSxcbiAgICAgICAgICAgICAgYXBwU3RhdGUuZmFzdE1vZGUsXG4gICAgICAgICAgICApXG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIEluY3JlbWVudCBhdXRoVmVyc2lvbiB0byB0cmlnZ2VyIHJlLWZldGNoaW5nIG9mIGF1dGgtZGVwZW5kZW50IGRhdGEgaW4gaG9va3MgKGUuZy4sIE1DUCBzZXJ2ZXJzKVxuICAgICAgICAgIGNvbnRleHQuc2V0QXBwU3RhdGUocHJldiA9PiAoe1xuICAgICAgICAgICAgLi4ucHJldixcbiAgICAgICAgICAgIGF1dGhWZXJzaW9uOiBwcmV2LmF1dGhWZXJzaW9uICsgMSxcbiAgICAgICAgICB9KSlcbiAgICAgICAgfVxuICAgICAgICBvbkRvbmUoc3VjY2VzcyA/ICdMb2dpbiBzdWNjZXNzZnVsJyA6ICdMb2dpbiBpbnRlcnJ1cHRlZCcpXG4gICAgICB9fVxuICAgIC8+XG4gIClcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIExvZ2luKHByb3BzOiB7XG4gIG9uRG9uZTogKHN1Y2Nlc3M6IGJvb2xlYW4sIG1haW5Mb29wTW9kZWw6IHN0cmluZykgPT4gdm9pZFxuICBzdGFydGluZ01lc3NhZ2U/OiBzdHJpbmdcbn0pOiBSZWFjdC5SZWFjdE5vZGUge1xuICBjb25zdCBtYWluTG9vcE1vZGVsID0gdXNlTWFpbkxvb3BNb2RlbCgpXG5cbiAgcmV0dXJuIChcbiAgICA8RGlhbG9nXG4gICAgICB0aXRsZT1cIkxvZ2luXCJcbiAgICAgIG9uQ2FuY2VsPXsoKSA9PiBwcm9wcy5vbkRvbmUoZmFsc2UsIG1haW5Mb29wTW9kZWwpfVxuICAgICAgY29sb3I9XCJwZXJtaXNzaW9uXCJcbiAgICAgIGlucHV0R3VpZGU9e2V4aXRTdGF0ZSA9PlxuICAgICAgICBleGl0U3RhdGUucGVuZGluZyA/IChcbiAgICAgICAgICA8VGV4dD5QcmVzcyB7ZXhpdFN0YXRlLmtleU5hbWV9IGFnYWluIHRvIGV4aXQ8L1RleHQ+XG4gICAgICAgICkgOiAoXG4gICAgICAgICAgPENvbmZpZ3VyYWJsZVNob3J0Y3V0SGludFxuICAgICAgICAgICAgYWN0aW9uPVwiY29uZmlybTpub1wiXG4gICAgICAgICAgICBjb250ZXh0PVwiQ29uZmlybWF0aW9uXCJcbiAgICAgICAgICAgIGZhbGxiYWNrPVwiRXNjXCJcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uPVwiY2FuY2VsXCJcbiAgICAgICAgICAvPlxuICAgICAgICApXG4gICAgICB9XG4gICAgPlxuICAgICAgPENvbnNvbGVPQXV0aEZsb3dcbiAgICAgICAgb25Eb25lPXsoKSA9PiBwcm9wcy5vbkRvbmUodHJ1ZSwgbWFpbkxvb3BNb2RlbCl9XG4gICAgICAgIHN0YXJ0aW5nTWVzc2FnZT17cHJvcHMu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 \ No newline at end of file diff --git a/src/commands/provider/provider.tsx b/src/commands/provider/provider.tsx index 95109e7d..b43b6c3d 100644 --- a/src/commands/provider/provider.tsx +++ b/src/commands/provider/provider.tsx @@ -903,7 +903,11 @@ function resolveCodexCredentials(processEnv: NodeJS.ProcessEnv): } } -function ProviderWizard({ onDone }: { onDone: LocalJSXCommandOnDone }): React.ReactNode { +export function ProviderWizard({ + onDone, +}: { + onDone: LocalJSXCommandOnDone +}): React.ReactNode { const defaults = getProviderWizardDefaults() const [step, setStep] = React.useState({ name: 'choose' }) diff --git a/src/components/ConsoleOAuthFlow.test.tsx b/src/components/ConsoleOAuthFlow.test.tsx new file mode 100644 index 00000000..dd0b6b75 --- /dev/null +++ b/src/components/ConsoleOAuthFlow.test.tsx @@ -0,0 +1,117 @@ +import { PassThrough } from 'node:stream' + +import { expect, test } from 'bun:test' +import React from 'react' +import stripAnsi from 'strip-ansi' + +import { AppStateProvider } from '../state/AppState.js' +import { createRoot } from '../ink.js' +import { KeybindingSetup } from '../keybindings/KeybindingProviderSetup.js' +import { ConsoleOAuthFlow } from './ConsoleOAuthFlow.js' + +const SYNC_START = '\x1B[?2026h' +const SYNC_END = '\x1B[?2026l' + +function extractLastFrame(output: string): string { + let lastFrame: string | null = null + let cursor = 0 + + while (cursor < output.length) { + const start = output.indexOf(SYNC_START, cursor) + if (start === -1) { + break + } + + const contentStart = start + SYNC_START.length + const end = output.indexOf(SYNC_END, contentStart) + if (end === -1) { + break + } + + const frame = output.slice(contentStart, end) + if (frame.trim().length > 0) { + lastFrame = frame + } + cursor = end + SYNC_END.length + } + + return lastFrame ?? output +} + +function createTestStreams(): { + stdout: PassThrough + stdin: PassThrough & { + isTTY: boolean + setRawMode: (mode: boolean) => void + ref: () => void + unref: () => void + } + getOutput: () => string +} { + let output = '' + const stdout = new PassThrough() + const stdin = new PassThrough() as PassThrough & { + isTTY: boolean + setRawMode: (mode: boolean) => void + ref: () => void + unref: () => void + } + + stdin.isTTY = true + stdin.setRawMode = () => {} + stdin.ref = () => {} + stdin.unref = () => {} + ;(stdout as unknown as { columns: number }).columns = 120 + stdout.on('data', chunk => { + output += chunk.toString() + }) + + return { + stdout, + stdin, + getOutput: () => output, + } +} + +async function renderFrame(node: React.ReactNode): Promise { + const { stdout, stdin, getOutput } = createTestStreams() + const root = await createRoot({ + stdout: stdout as unknown as NodeJS.WriteStream, + stdin: stdin as unknown as NodeJS.ReadStream, + patchConsole: false, + }) + + root.render( + + {node} + , + ) + + await Bun.sleep(50) + root.unmount() + stdin.end() + stdout.end() + await Bun.sleep(25) + + return stripAnsi(extractLastFrame(getOutput())) +} + +test('login picker shows the third-party platform option', async () => { + const output = await renderFrame( {}} />) + + expect(output).toContain('Select login method:') + expect(output).toContain('3rd-party platform') +}) + +test('third-party provider branch opens the provider wizard', async () => { + const output = await renderFrame( + {}} + />, + ) + + expect(output).toContain('Set up a provider profile') + expect(output).toContain('OpenAI-compatible') + expect(output).toContain('Ollama') +}) diff --git a/src/components/ConsoleOAuthFlow.tsx b/src/components/ConsoleOAuthFlow.tsx index c0feb587..54288bc8 100644 --- a/src/components/ConsoleOAuthFlow.tsx +++ b/src/components/ConsoleOAuthFlow.tsx @@ -1,4 +1,3 @@ -import { c as _c } from "react-compiler-runtime"; import React, { useCallback, useEffect, useRef, useState } from 'react'; import { type AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS, logEvent } from 'src/services/analytics/index.js'; import { installOAuthTokens } from '../cli/handlers/auth.js'; @@ -13,22 +12,34 @@ import { OAuthService } from '../services/oauth/index.js'; import { getOauthAccountInfo, validateForceLoginOrg } from '../utils/auth.js'; import { logError } from '../utils/log.js'; import { getSettings_DEPRECATED } from '../utils/settings/settings.js'; +import { ProviderWizard } from '../commands/provider/provider.js'; import { Select } from './CustomSelect/select.js'; import { KeyboardShortcutHint } from './design-system/KeyboardShortcutHint.js'; import { Spinner } from './Spinner.js'; import TextInput from './TextInput.js'; +export type ConsoleOAuthFlowResult = { + type: 'oauth'; +} | { + type: 'provider-setup'; + message: string; +}; type Props = { - onDone(): void; + onDone(result?: ConsoleOAuthFlowResult): void; startingMessage?: string; mode?: 'login' | 'setup-token'; forceLoginMethod?: 'claudeai' | 'console'; + initialStatus?: OAuthStatus; }; type OAuthStatus = { state: 'idle'; } // Initial state, waiting to select login method | { state: 'platform_setup'; -} // Show platform setup info (Bedrock/Vertex/Foundry) +} // Show third-party provider setup flow +| { + state: 'platform_setup_complete'; + message: string; +} | { state: 'ready_to_start'; } // Flow started, waiting for browser to open @@ -55,7 +66,8 @@ export function ConsoleOAuthFlow({ onDone, startingMessage, mode = 'login', - forceLoginMethod: forceLoginMethodProp + forceLoginMethod: forceLoginMethodProp, + initialStatus }: Props): React.ReactNode { const settings = getSettings_DEPRECATED() || {}; const forceLoginMethod = forceLoginMethodProp ?? settings.forceLoginMethod; @@ -63,6 +75,9 @@ export function ConsoleOAuthFlow({ const forcedMethodMessage = forceLoginMethod === 'claudeai' ? 'Login method pre-selected: Subscription Plan (Claude Pro/Max)' : forceLoginMethod === 'console' ? 'Login method pre-selected: API Usage Billing (Anthropic Console)' : null; const terminal = useTerminalNotification(); const [oauthStatus, setOAuthStatus] = useState(() => { + if (initialStatus) { + return initialStatus; + } if (mode === 'setup-token') { return { state: 'ready_to_start' @@ -113,20 +128,26 @@ export function ConsoleOAuthFlow({ logEvent('tengu_oauth_success', { loginWithClaudeAi }); - onDone(); + onDone({ + type: 'oauth' + }); }, { context: 'Confirmation', isActive: oauthStatus.state === 'success' && mode !== 'setup-token' }); - // Handle Enter to continue from platform setup + // Handle Enter to continue after third-party provider setup useKeybinding('confirm:yes', () => { - setOAuthStatus({ - state: 'idle' + if (oauthStatus.state !== 'platform_setup_complete') { + return; + } + onDone({ + type: 'provider-setup', + message: oauthStatus.message }); }, { context: 'Confirmation', - isActive: oauthStatus.state === 'platform_setup' + isActive: oauthStatus.state === 'platform_setup_complete' }); // Handle Enter to retry on error state @@ -344,292 +365,198 @@ type OAuthStatusMessageProps = { setOAuthStatus: (status: OAuthStatus) => void; setLoginWithClaudeAi: (value: boolean) => void; }; -function OAuthStatusMessage(t0) { - const $ = _c(51); - const { - oauthStatus, - mode, - startingMessage, - forcedMethodMessage, - showPastePrompt, - pastedCode, - setPastedCode, - cursorOffset, - setCursorOffset, - textInputColumns, - handleSubmitCode, - setOAuthStatus, - setLoginWithClaudeAi - } = t0; +function OAuthStatusMessage({ + oauthStatus, + mode, + startingMessage, + forcedMethodMessage, + showPastePrompt, + pastedCode, + setPastedCode, + cursorOffset, + setCursorOffset, + textInputColumns, + handleSubmitCode, + setOAuthStatus, + setLoginWithClaudeAi, +}: OAuthStatusMessageProps) { switch (oauthStatus.state) { - case "idle": - { - const t1 = startingMessage ? startingMessage : "Claude Code can be used with your Claude subscription or billed based on API usage through your Console account."; - let t2; - if ($[0] !== t1) { - t2 = {t1}; - $[0] = t1; - $[1] = t2; - } else { - t2 = $[1]; - } - let t3; - if ($[2] === Symbol.for("react.memo_cache_sentinel")) { - t3 = Select login method:; - $[2] = t3; - } else { - t3 = $[2]; - } - let t4; - if ($[3] === Symbol.for("react.memo_cache_sentinel")) { - t4 = { - label: Claude account with subscription ·{" "}Pro, Max, Team, or Enterprise{false && {"\n"}[ANT-ONLY]{" "}Please use this option unless you need to login to a special org for accessing sensitive data (e.g. customer data, HIPI data) with the Console option}{"\n"}, - value: "claudeai" - }; - $[3] = t4; - } else { - t4 = $[3]; - } - let t5; - if ($[4] === Symbol.for("react.memo_cache_sentinel")) { - t5 = { - label: Anthropic Console account ·{" "}API usage billing{"\n"}, - value: "console" - }; - $[4] = t5; - } else { - t5 = $[4]; - } - let t6; - if ($[5] === Symbol.for("react.memo_cache_sentinel")) { - t6 = [t4, t5, { - label: 3rd-party platform ·{" "}OpenAI, Gemini, Bedrock, Ollama, and more{"\n"}, - value: "platform" - }]; - $[5] = t6; - } else { - t6 = $[5]; - } - let t7; - if ($[6] !== setLoginWithClaudeAi || $[7] !== setOAuthStatus) { - t7 = { + if (value === 'platform') { + logEvent('tengu_oauth_platform_selected', {}) + setOAuthStatus({ state: 'platform_setup' }) + return } - } - }} />; - $[6] = setLoginWithClaudeAi; - $[7] = setOAuthStatus; - $[8] = t7; - } else { - t7 = $[8]; - } - let t8; - if ($[9] !== t2 || $[10] !== t7) { - t8 = {t2}{t3}{t7}; - $[9] = t2; - $[10] = t7; - $[11] = t8; - } else { - t8 = $[11]; - } - return t8; - } - case "platform_setup": - { - let t1; - if ($[12] === Symbol.for("react.memo_cache_sentinel")) { - t1 = Using 3rd-party platforms; - $[12] = t1; - } else { - t1 = $[12]; - } - let t2; - let t3; - if ($[13] === Symbol.for("react.memo_cache_sentinel")) { - t2 = OpenClaude supports OpenAI-compatible providers (GPT-4o, DeepSeek, Ollama, Groq), Google Gemini, Amazon Bedrock, Microsoft Foundry, and Vertex AI. Run /provider to save a provider profile, or set the required environment variables manually, then restart OpenClaude.; - t3 = If you are part of an enterprise organization, contact your administrator for setup instructions.; - $[13] = t2; - $[14] = t3; - } else { - t2 = $[13]; - t3 = $[14]; - } - let t4; - if ($[15] === Symbol.for("react.memo_cache_sentinel")) { - t4 = Documentation:; - $[15] = t4; - } else { - t4 = $[15]; - } - let t5; - if ($[16] === Symbol.for("react.memo_cache_sentinel")) { - t5 = · Amazon Bedrock:{" "}https://code.claude.com/docs/en/amazon-bedrock; - $[16] = t5; - } else { - t5 = $[16]; - } - let t6; - if ($[17] === Symbol.for("react.memo_cache_sentinel")) { - t6 = · Microsoft Foundry:{" "}https://code.claude.com/docs/en/microsoft-foundry; - $[17] = t6; - } else { - t6 = $[17]; - } - let t7; - if ($[18] === Symbol.for("react.memo_cache_sentinel")) { - t7 = {t4} - · Guided setup inside OpenClaude:{"\n"}{" "}/provider - · OpenAI / any OpenAI-compatible provider (GPT-4o, DeepSeek, Ollama, Groq):{"\n"}{" "}CLAUDE_CODE_USE_OPENAI=1 OPENAI_API_KEY=sk-... OPENAI_MODEL=gpt-4o - · Google Gemini (free key at https://aistudio.google.com/apikey):{"\n"}{" "}CLAUDE_CODE_USE_GEMINI=1 GEMINI_API_KEY=your-key - {t5}{t6}· Vertex AI:{" "}https://code.claude.com/docs/en/google-vertex-ai; - $[18] = t7; - } else { - t7 = $[18]; - } - let t8; - if ($[19] === Symbol.for("react.memo_cache_sentinel")) { - t8 = {t1}{t2}{t3}{t7}Press Enter to go back to login options.; - $[19] = t8; - } else { - t8 = $[19]; - } - return t8; - } - case "waiting_for_login": - { - let t1; - if ($[20] !== forcedMethodMessage) { - t1 = forcedMethodMessage && {forcedMethodMessage}; - $[20] = forcedMethodMessage; - $[21] = t1; - } else { - t1 = $[21]; - } - let t2; - if ($[22] !== showPastePrompt) { - t2 = !showPastePrompt && Opening browser to sign in…; - $[22] = showPastePrompt; - $[23] = t2; - } else { - t2 = $[23]; - } - let t3; - if ($[24] !== cursorOffset || $[25] !== handleSubmitCode || $[26] !== oauthStatus.url || $[27] !== pastedCode || $[28] !== setCursorOffset || $[29] !== setPastedCode || $[30] !== showPastePrompt || $[31] !== textInputColumns) { - t3 = showPastePrompt && {PASTE_HERE_MSG} handleSubmitCode(value, oauthStatus.url)} cursorOffset={cursorOffset} onChangeCursorOffset={setCursorOffset} columns={textInputColumns} mask="*" />; - $[24] = cursorOffset; - $[25] = handleSubmitCode; - $[26] = oauthStatus.url; - $[27] = pastedCode; - $[28] = setCursorOffset; - $[29] = setPastedCode; - $[30] = showPastePrompt; - $[31] = textInputColumns; - $[32] = t3; - } else { - t3 = $[32]; - } - let t4; - if ($[33] !== t1 || $[34] !== t2 || $[35] !== t3) { - t4 = {t1}{t2}{t3}; - $[33] = t1; - $[34] = t2; - $[35] = t3; - $[36] = t4; - } else { - t4 = $[36]; - } - return t4; - } - case "creating_api_key": - { - let t1; - if ($[37] === Symbol.for("react.memo_cache_sentinel")) { - t1 = Creating API key for Claude Code…; - $[37] = t1; - } else { - t1 = $[37]; - } - return t1; - } - case "about_to_retry": - { - let t1; - if ($[38] === Symbol.for("react.memo_cache_sentinel")) { - t1 = Retrying…; - $[38] = t1; - } else { - t1 = $[38]; - } - return t1; - } - case "success": - { - let t1; - if ($[39] !== mode || $[40] !== oauthStatus.token) { - t1 = mode === "setup-token" && oauthStatus.token ? null : <>{getOauthAccountInfo()?.emailAddress ? Logged in as{" "}{getOauthAccountInfo()?.emailAddress} : null}Login successful. Press Enter to continue…; - $[39] = mode; - $[40] = oauthStatus.token; - $[41] = t1; - } else { - t1 = $[41]; - } - let t2; - if ($[42] !== t1) { - t2 = {t1}; - $[42] = t1; - $[43] = t2; - } else { - t2 = $[43]; - } - return t2; - } - case "error": - { - let t1; - if ($[44] !== oauthStatus.message) { - t1 = OAuth error: {oauthStatus.message}; - $[44] = oauthStatus.message; - $[45] = t1; - } else { - t1 = $[45]; - } - let t2; - if ($[46] !== oauthStatus.toRetry) { - t2 = oauthStatus.toRetry && Press Enter to retry.; - $[46] = oauthStatus.toRetry; - $[47] = t2; - } else { - t2 = $[47]; - } - let t3; - if ($[48] !== t1 || $[49] !== t2) { - t3 = {t1}{t2}; - $[48] = t1; - $[49] = t2; - $[50] = t3; - } else { - t3 = $[50]; - } - return t3; - } + + setOAuthStatus({ state: 'ready_to_start' }) + if (value === 'claudeai') { + logEvent('tengu_oauth_claudeai_selected', {}) + setLoginWithClaudeAi(true) + } else { + logEvent('tengu_oauth_console_selected', {}) + setLoginWithClaudeAi(false) + } + }} + /> + + + ) + } + + case 'platform_setup': + return ( + { + if (!result) { + setOAuthStatus({ state: 'idle' }) + return + } + + setOAuthStatus({ + state: 'platform_setup_complete', + message: result, + }) + }} + /> + ) + + case 'platform_setup_complete': + return ( + + {oauthStatus.message} + + Press Enter to continue. + + + ) + + case 'waiting_for_login': + return ( + + {forcedMethodMessage ? ( + + {forcedMethodMessage} + + ) : null} + {!showPastePrompt ? ( + + + Opening browser to sign in… + + ) : null} + {showPastePrompt ? ( + + {PASTE_HERE_MSG} + handleSubmitCode(value, oauthStatus.url)} + cursorOffset={cursorOffset} + onChangeCursorOffset={setCursorOffset} + columns={textInputColumns} + mask="*" + /> + + ) : null} + + ) + + case 'creating_api_key': + return ( + + + + Creating API key for Claude Code… + + + ) + + case 'about_to_retry': + return ( + + Retrying… + + ) + + case 'success': + return ( + + {mode === 'setup-token' && oauthStatus.token ? null : ( + <> + {getOauthAccountInfo()?.emailAddress ? ( + + Logged in as {getOauthAccountInfo()?.emailAddress} + + ) : null} + + Login successful. Press Enter to continue… + + + )} + + ) + + case 'error': + return ( + + OAuth error: {oauthStatus.message} + {oauthStatus.toRetry ? ( + + + Press Enter to retry. + + + ) : null} + + ) + default: - { - return null; - } + return null } } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJSZWFjdCIsInVzZUNhbGxiYWNrIiwidXNlRWZmZWN0IiwidXNlUmVmIiwidXNlU3RhdGUiLCJBbmFseXRpY3NNZXRhZGF0YV9JX1ZFUklGSUVEX1RISVNfSVNfTk9UX0NPREVfT1JfRklMRVBBVEhTIiwibG9nRXZlbnQiLCJpbnN0YWxsT0F1dGhUb2tlbnMiLCJ1c2VUZXJtaW5hbFNpemUiLCJzZXRDbGlwYm9hcmQiLCJ1c2VUZXJtaW5hbE5vdGlmaWNhdGlvbiIsIkJveCIsIkxpbmsiLCJUZXh0IiwidXNlS2V5YmluZGluZyIsImdldFNTTEVycm9ySGludCIsInNlbmROb3RpZmljYXRpb24iLCJPQXV0aFNlcnZpY2UiLCJnZXRPYXV0aEFjY291bnRJbmZvIiwidmFsaWRhdGVGb3JjZUxvZ2luT3JnIiwibG9nRXJyb3IiLCJnZXRTZXR0aW5nc19ERVBSRUNBVEVEIiwiU2VsZWN0IiwiS2V5Ym9hcmRTaG9ydGN1dEhpbnQiLCJTcGlubmVyIiwiVGV4dElucHV0IiwiUHJvcHMiLCJvbkRvbmUiLCJzdGFydGluZ01lc3NhZ2UiLCJtb2RlIiwiZm9yY2VMb2dpbk1ldGhvZCIsIk9BdXRoU3RhdHVzIiwic3RhdGUiLCJ1cmwiLCJuZXh0U3RhdGUiLCJ0b2tlbiIsIm1lc3NhZ2UiLCJ0b1JldHJ5IiwiUEFTVEVfSEVSRV9NU0ciLCJDb25zb2xlT0F1dGhGbG93IiwiZm9yY2VMb2dpbk1ldGhvZFByb3AiLCJSZWFjdE5vZGUiLCJzZXR0aW5ncyIsIm9yZ1VVSUQiLCJmb3JjZUxvZ2luT3JnVVVJRCIsImZvcmNlZE1ldGhvZE1lc3NhZ2UiLCJ0ZXJtaW5hbCIsIm9hdXRoU3RhdHVzIiwic2V0T0F1dGhTdGF0dXMiLCJwYXN0ZWRDb2RlIiwic2V0UGFzdGVkQ29kZSIsImN1cnNvck9mZnNldCIsInNldEN1cnNvck9mZnNldCIsIm9hdXRoU2VydmljZSIsImxvZ2luV2l0aENsYXVkZUFpIiwic2V0TG9naW5XaXRoQ2xhdWRlQWkiLCJzaG93UGFzdGVQcm9tcHQiLCJzZXRTaG93UGFzdGVQcm9tcHQiLCJ1cmxDb3BpZWQiLCJzZXRVcmxDb3BpZWQiLCJ0ZXh0SW5wdXRDb2x1bW5zIiwiY29sdW1ucyIsImxlbmd0aCIsInRpbWVyIiwic2V0VGltZW91dCIsImNsZWFyVGltZW91dCIsImNvbnRleHQiLCJpc0FjdGl2ZSIsInRoZW4iLCJyYXciLCJwcm9jZXNzIiwic3Rkb3V0Iiwid3JpdGUiLCJoYW5kbGVTdWJtaXRDb2RlIiwidmFsdWUiLCJhdXRob3JpemF0aW9uQ29kZSIsInNwbGl0IiwiaGFuZGxlTWFudWFsQXV0aENvZGVJbnB1dCIsImVyciIsIkVycm9yIiwic3RhcnRPQXV0aCIsInJlc3VsdCIsInN0YXJ0T0F1dGhGbG93IiwiaW5mZXJlbmNlT25seSIsImV4cGlyZXNJbiIsInVuZGVmaW5lZCIsImNhdGNoIiwiaXNUb2tlbkV4Y2hhbmdlRXJyb3IiLCJpbmNsdWRlcyIsInNzbEhpbnQiLCJlcnJvciIsInNzbF9lcnJvciIsImFjY2Vzc1Rva2VuIiwib3JnUmVzdWx0IiwidmFsaWQiLCJub3RpZmljYXRpb25UeXBlIiwiZXJyb3JNZXNzYWdlIiwicGVuZGluZ09BdXRoU3RhcnRSZWYiLCJjdXJyZW50IiwibmV4dFRpY2siLCJQcm9taXNlIiwiTXV0YWJsZVJlZk9iamVjdCIsImNsZWFudXAiLCJPQXV0aFN0YXR1c01lc3NhZ2VQcm9wcyIsIm9mZnNldCIsInN0YXR1cyIsIk9BdXRoU3RhdHVzTWVzc2FnZSIsInQwIiwiJCIsIl9jIiwidDEiLCJ0MiIsInQzIiwiU3ltYm9sIiwiZm9yIiwidDQiLCJsYWJlbCIsInQ1IiwidDYiLCJ0NyIsInZhbHVlXzAiLCJ0OCIsImVtYWlsQWRkcmVzcyJdLCJzb3VyY2VzIjpbIkNvbnNvbGVPQXV0aEZsb3cudHN4Il0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBSZWFjdCwgeyB1c2VDYWxsYmFjaywgdXNlRWZmZWN0LCB1c2VSZWYsIHVzZVN0YXRlIH0gZnJvbSAncmVhY3QnXG5pbXBvcnQge1xuICB0eXBlIEFuYWx5dGljc01ldGFkYXRhX0lfVkVSSUZJRURfVEhJU19JU19OT1RfQ09ERV9PUl9GSUxFUEFUSFMsXG4gIGxvZ0V2ZW50LFxufSBmcm9tICdzcmMvc2VydmljZXMvYW5hbHl0aWNzL2luZGV4LmpzJ1xuaW1wb3J0IHsgaW5zdGFsbE9BdXRoVG9rZW5zIH0gZnJvbSAnLi4vY2xpL2hhbmRsZXJzL2F1dGguanMnXG5pbXBvcnQgeyB1c2VUZXJtaW5hbFNpemUgfSBmcm9tICcuLi9ob29rcy91c2VUZXJtaW5hbFNpemUuanMnXG5pbXBvcnQgeyBzZXRDbGlwYm9hcmQgfSBmcm9tICcuLi9pbmsvdGVybWlvL29zYy5qcydcbmltcG9ydCB7IHVzZVRlcm1pbmFsTm90aWZpY2F0aW9uIH0gZnJvbSAnLi4vaW5rL3VzZVRlcm1pbmFsTm90aWZpY2F0aW9uLmpzJ1xuaW1wb3J0IHsgQm94LCBMaW5rLCBUZXh0IH0gZnJvbSAnLi4vaW5rLmpzJ1xuaW1wb3J0IHsgdXNlS2V5YmluZGluZyB9IGZyb20gJy4uL2tleWJpbmRpbmdzL3VzZUtleWJpbmRpbmcuanMnXG5pbXBvcnQgeyBnZXRTU0xFcnJvckhpbnQgfSBmcm9tICcuLi9zZXJ2aWNlcy9hcGkvZXJyb3JVdGlscy5qcydcbmltcG9ydCB7IHNlbmROb3RpZmljYXRpb24gfSBmcm9tICcuLi9zZXJ2aWNlcy9ub3RpZmllci5qcydcbmltcG9ydCB7IE9BdXRoU2VydmljZSB9IGZyb20gJy4uL3NlcnZpY2VzL29hdXRoL2luZGV4LmpzJ1xuaW1wb3J0IHsgZ2V0T2F1dGhBY2NvdW50SW5mbywgdmFsaWRhdGVGb3JjZUxvZ2luT3JnIH0gZnJvbSAnLi4vdXRpbHMvYXV0aC5qcydcbmltcG9ydCB7IGxvZ0Vycm9yIH0gZnJvbSAnLi4vdXRpbHMvbG9nLmpzJ1xuaW1wb3J0IHsgZ2V0U2V0dGluZ3NfREVQUkVDQVRFRCB9IGZyb20gJy4uL3V0aWxzL3NldHRpbmdzL3NldHRpbmdzLmpzJ1xuaW1wb3J0IHsgU2VsZWN0IH0gZnJvbSAnLi9DdXN0b21TZWxlY3Qvc2VsZWN0LmpzJ1xuaW1wb3J0IHsgS2V5Ym9hcmRTaG9ydGN1dEhpbnQgfSBmcm9tICcuL2Rlc2lnbi1zeXN0ZW0vS2V5Ym9hcmRTaG9ydGN1dEhpbnQuanMnXG5pbXBvcnQgeyBTcGlubmVyIH0gZnJvbSAnLi9TcGlubmVyLmpzJ1xuaW1wb3J0IFRleHRJbnB1dCBmcm9tICcuL1RleHRJbnB1dC5qcydcblxudHlwZSBQcm9wcyA9IHtcbiAgb25Eb25lKCk6IHZvaWRcbiAgc3RhcnRpbmdNZXNzYWdlPzogc3RyaW5nXG4gIG1vZGU/OiAnbG9naW4nIHwgJ3NldHVwLXRva2VuJ1xuICBmb3JjZUxvZ2luTWV0aG9kPzogJ2NsYXVkZWFpJyB8ICdjb25zb2xlJ1xufVxuXG50eXBlIE9BdXRoU3RhdHVzID1cbiAgfCB7IHN0YXRlOiAnaWRsZScgfSAvLyBJbml0aWFsIHN0YXRlLCB3YWl0aW5nIHRvIHNlbGVjdCBsb2dpbiBtZXRob2RcbiAgfCB7IHN0YXRlOiAncGxhdGZvcm1fc2V0dXAnIH0gLy8gU2hvdyBwbGF0Zm9ybSBzZXR1cCBpbmZvIChCZWRyb2NrL1ZlcnRleC9Gb3VuZHJ5KVxuICB8IHsgc3RhdGU6ICdyZWFkeV90b19zdGFydCcgfSAvLyBGbG93IHN0YXJ0ZWQsIHdhaXRpbmcgZm9yIGJyb3dzZXIgdG8gb3BlblxuICB8IHsgc3RhdGU6ICd3YWl0aW5nX2Zvcl9sb2dpbic7IHVybDogc3RyaW5nIH0gLy8gQnJvd3NlciBvcGVuZWQsIHdhaXRpbmcgZm9yIHVzZXIgdG8gbG9naW5cbiAgfCB7IHN0YXRlOiAnY3JlYXRpbmdfYXBpX2tleScgfSAvLyBHb3QgYWNjZXNzIHRva2VuLCBjcmVhdGluZyBBUEkga2V5XG4gIHwgeyBzdGF0ZTogJ2Fib3V0X3RvX3JldHJ5JzsgbmV4dFN0YXRlOiBPQXV0aFN0YXR1cyB9XG4gIHwgeyBzdGF0ZTogJ3N1Y2Nlc3MnOyB0b2tlbj86IHN0cmluZyB9XG4gIHwge1xuICAgICAgc3RhdGU6ICdlcnJvcidcbiAgICAgIG1lc3NhZ2U6IHN0cmluZ1xuICAgICAgdG9SZXRyeT86IE9BdXRoU3RhdHVzXG4gICAgfVxuXG5jb25zdCBQQVNURV9IRVJFX01TRyA9ICdQYXN0ZSBjb2RlIGhlcmUgaWYgcHJvbXB0ZWQgPiAnXG5cbmV4cG9ydCBmdW5jdGlvbiBDb25zb2xlT0F1dGhGbG93KHtcbiAgb25Eb25lLFxuICBzdGFydGluZ01lc3NhZ2UsXG4gIG1vZGUgPSAnbG9naW4nLFxuICBmb3JjZUxvZ2luTWV0aG9kOiBmb3JjZUxvZ2luTWV0aG9kUHJvcCxcbn06IFByb3BzKTogUmVhY3QuUmVhY3ROb2RlIHtcbiAgY29uc3Qgc2V0dGluZ3MgPSBnZXRTZXR0aW5nc19ERVBSRUNBVEVEKCkgfHwge31cbiAgY29uc3QgZm9yY2VMb2dpbk1ldGhvZCA9IGZvcmNlTG9naW5NZXRob2RQcm9wID8/IHNldHRpbmdzLmZvcmNlTG9naW5NZXRob2RcbiAgY29uc3Qgb3JnVVVJRCA9IHNldHRpbmdzLmZvcmNlTG9naW5PcmdVVUlEXG4gIGNvbnN0IGZvcmNlZE1ldGhvZE1lc3NhZ2UgPVxuICAgIGZvcmNlTG9naW5NZXRob2QgPT09ICdjbGF1ZGVhaSdcbiAgICAgID8gJ0xvZ2luIG1ldGhvZCBwcmUtc2VsZWN0ZWQ6IFN1YnNjcmlwdGlvbiBQbGFuIChDbGF1ZGUgUHJvL01heCknXG4gICAgICA6IGZvcmNlTG9naW5NZXRob2QgPT09ICdjb25zb2xlJ1xuICAgICAgICA/ICdMb2dpbiBtZXRob2QgcHJlLXNlbGVjdGVkOiBBUEkgVXNhZ2UgQmlsbGluZyAoQW50aHJvcGljIENvbnNvbGUpJ1xuICAgICAgICA6IG51bGxcblxuICBjb25zdCB0ZXJtaW5hbCA9IHVzZVRlcm1pbmFsTm90aWZpY2F0aW9uKClcblxuICBjb25zdCBbb2F1dGhTdGF0dXMsIHNldE9BdXRoU3RhdHVzXSA9IHVzZVN0YXRlPE9BdXRoU3RhdHVzPigoKSA9PiB7XG4gICAgaWYgKG1vZGUgPT09ICdzZXR1cC10b2tlbicpIHtcbiAgICAgIHJldHVybiB7IHN0YXRlOiAncmVhZHlfdG9fc3RhcnQnIH1cbiAgICB9XG4gICAgaWYgKGZvcmNlTG9naW5NZXRob2QgPT09ICdjbGF1ZGVhaScgfHwgZm9yY2VMb2dpbk1ldGhvZCA9PT0gJ2NvbnNvbGUnKSB7XG4gICAgICByZXR1cm4geyBzdGF0ZTogJ3JlYWR5X3RvX3N0YXJ0JyB9XG4gICAgfVxuICAgIHJldHVybiB7IHN0YXRlOiAnaWRsZScgfVxuICB9KVxuXG4gIGNvbnN0IFtwYXN0ZWRDb2RlLCBzZXRQYXN0ZWRDb2RlXSA9IHVzZVN0YXRlKCcnKVxuICBjb25zdCBbY3Vyc29yT2Zmc2V0LCBzZXRDdXJzb3JPZmZzZXRdID0gdXNlU3RhdGUoMClcbiAgY29uc3QgW29hdXRoU2VydmljZV0gPSB1c2VTdGF0ZSgoKSA9PiBuZXcgT0F1dGhTZXJ2aWNlKCkpXG4gIGNvbnN0IFtsb2dpbldpdGhDbGF1ZGVBaSwgc2V0TG9naW5XaXRoQ2xhdWRlQWldID0gdXNlU3RhdGUoKCkgPT4ge1xuICAgIC8vIFVzZSBDbGF1ZGUgQUkgYXV0aCBmb3Igc2V0dXAtdG9rZW4gbW9kZSB0byBzdXBwb3J0IHVzZXI6aW5mZXJlbmNlIHNjb3BlXG4gICAgcmV0dXJuIG1vZGUgPT09ICdzZXR1cC10b2tlbicgfHwgZm9yY2VMb2dpbk1ldGhvZCA9PT0gJ2NsYXVkZWFpJ1xuICB9KVxuICAvLyBBZnRlciBhIGZldyBzZWNvbmRzIHdlIHN1Z2dlc3QgdGhlIHVzZXIgdG8gY29weS9wYXN0ZSB1cmwgaWYgdGhlXG4gIC8vIGJyb3dzZXIgZGlkIG5vdCBvcGVuIGF1dG9tYXRpY2FsbHkuIEluIHRoaXMgZmxvdyB3ZSBleHBlY3QgdGhlIHVzZXIgdG9cbiAgLy8gY29weSB0aGUgY29kZSBmcm9tIHRoZSBicm93c2VyIGFuZCBwYXN0ZSBpdCBpbiB0aGUgdGVybWluYWxcbiAgY29uc3QgW3Nob3dQYXN0ZVByb21wdCwgc2V0U2hvd1Bhc3RlUHJvbXB0XSA9IHVzZVN0YXRlKGZhbHNlKVxuICBjb25zdCBbdXJsQ29waWVkLCBzZXRVcmxDb3BpZWRdID0gdXNlU3RhdGUoZmFsc2UpXG5cbiAgY29uc3QgdGV4dElucHV0Q29sdW1ucyA9IHVzZVRlcm1pbmFsU2l6ZSgpLmNvbHVtbnMgLSBQQVNURV9IRVJFX01TRy5sZW5ndGggLSAxXG5cbiAgLy8gTG9nIGZvcmNlZCBsb2dpbiBtZXRob2Qgb24gbW91bnRcbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBpZiAoZm9yY2VMb2dpbk1ldGhvZCA9PT0gJ2NsYXVkZWFpJykge1xuICAgICAgbG9nRXZlbnQoJ3Rlbmd1X29hdXRoX2NsYXVkZWFpX2ZvcmNlZCcsIHt9KVxuICAgIH0gZWxzZSBpZiAoZm9yY2VMb2dpbk1ldGhvZCA9PT0gJ2NvbnNvbGUnKSB7XG4gICAgICBsb2dFdmVudCgndGVuZ3Vfb2F1dGhfY29uc29sZV9mb3JjZWQnLCB7fSlcbiAgICB9XG4gIH0sIFtmb3JjZUxvZ2luTWV0aG9kXSlcblxuICAvLyBSZXRyeSBsb2dpY1xuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGlmIChvYXV0aFN0YXR1cy5zdGF0ZSA9PT0gJ2Fib3V0X3RvX3JldHJ5Jykge1xuICAgICAgY29uc3QgdGltZXIgPSBzZXRUaW1lb3V0KHNldE9BdXRoU3RhdHVzLCAxMDAwLCBvYXV0aFN0YXR1cy5uZXh0U3RhdGUpXG4gICAgICByZXR1cm4gKCkgPT4gY2xlYXJUaW1lb3V0KHRpbWVyKVxuICAgIH1cbiAgfSwgW29hdXRoU3RhdHVzXSlcblxuICAvLyBIYW5kbGUgRW50ZXIgdG8gY29udGludWUgb24gc3VjY2VzcyBzdGF0ZVxuICB1c2VLZXliaW5kaW5nKFxuICAgICdjb25maXJtOnllcycsXG4gICAgKCkgPT4ge1xuICAgICAgbG9nRXZlbnQoJ3Rlbmd1X29hdXRoX3N1Y2Nlc3MnLCB7IGxvZ2luV2l0aENsYXVkZUFpIH0pXG4gICAgICBvbkRvbmUoKVxuICAgIH0sXG4gICAge1xuICAgICAgY29udGV4dDogJ0NvbmZpcm1hdGlvbicsXG4gICAgICBpc0FjdGl2ZTogb2F1dGhTdGF0dXMuc3RhdGUgPT09ICdzdWNjZXNzJyAmJiBtb2RlICE9PSAnc2V0dXAtdG9rZW4nLFxuICAgIH0sXG4gIClcblxuICAvLyBIYW5kbGUgRW50ZXIgdG8gY29udGludWUgZnJvbSBwbGF0Zm9ybSBzZXR1cFxuICB1c2VLZXliaW5kaW5nKFxuICAgICdjb25maXJtOnllcycsXG4gICAgKCkgPT4ge1xuICAgICAgc2V0T0F1dGhTdGF0dXMoeyBzdGF0ZTogJ2lkbGUnIH0pXG4gICAgfSxcbiAgICB7XG4gICAgICBjb250ZXh0OiAnQ29uZmlybWF0aW9uJyxcbiAgICAgIGlzQWN0aXZlOiBvYXV0aFN0YXR1cy5zdGF0ZSA9PT0gJ3BsYXRmb3JtX3NldHVwJyxcbiAgICB9LFxuICApXG5cbiAgLy8gSGFuZGxlIEVudGVyIHRvIHJldHJ5IG9uIGVycm9yIHN0YXRlXG4gIHVzZUtleWJpbmRpbmcoXG4gICAgJ2NvbmZpcm06eWVzJyxcbiAgICAoKSA9PiB7XG4gICAgICBpZiAob2F1dGhTdGF0dXMuc3RhdGUgPT09ICdlcnJvcicgJiYgb2F1dGhTdGF0dXMudG9SZXRyeSkge1xuICAgICAgICBzZXRQYXN0ZWRDb2RlKCcnKVxuICAgICAgICBzZXRPQXV0aFN0YXR1cyh7XG4gICAgICAgICAgc3RhdGU6ICdhYm91dF90b19yZXRyeScsXG4gICAgICAgICAgbmV4dFN0YXRlOiBvYXV0aFN0YXR1cy50b1JldHJ5LFxuICAgICAgICB9KVxuICAgICAgfVxuICAgIH0sXG4gICAge1xuICAgICAgY29udGV4dDogJ0NvbmZpcm1hdGlvbicsXG4gICAgICBpc0FjdGl2ZTogb2F1dGhTdGF0dXMuc3RhdGUgPT09ICdlcnJvcicgJiYgISFvYXV0aFN0YXR1cy50b1JldHJ5LFxuICAgIH0sXG4gIClcblxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGlmIChcbiAgICAgIHBhc3RlZENvZGUgPT09ICdjJyAmJlxuICAgICAgb2F1dGhTdGF0dXMuc3RhdGUgPT09ICd3YWl0aW5nX2Zvcl9sb2dpbicgJiZcbiAgICAgIHNob3dQYXN0ZVByb21wdCAmJlxuICAgICAgIXVybENvcGllZFxuICAgICkge1xuICAgICAgdm9pZCBzZXRDbGlwYm9hcmQob2F1dGhTdGF0dXMudXJsKS50aGVuKHJhdyA9PiB7XG4gICAgICAgIGlmIChyYXcpIHByb2Nlc3Muc3Rkb3V0LndyaXRlKHJhdylcbiAgICAgICAgc2V0VXJsQ29waWVkKHRydWUpXG4gICAgICAgIHNldFRpbWVvdXQoc2V0VXJsQ29waWVkLCAyMDAwLCBmYWxzZSlcbiAgICAgIH0pXG4gICAgICBzZXRQYXN0ZWRDb2RlKCcnKVxuICAgIH1cbiAgfSwgW3Bhc3RlZENvZGUsIG9hdXRoU3RhdHVzLCBzaG93UGFzdGVQcm9tcHQsIHVybENvcGllZF0pXG5cbiAgYXN5bmMgZnVuY3Rpb24gaGFuZGxlU3VibWl0Q29kZSh2YWx1ZTogc3RyaW5nLCB1cmw6IHN0cmluZykge1xuICAgIHRyeSB7XG4gICAgICAvLyBFeHBlY3RpbmcgZm9ybWF0IFwiYXV0aG9yaXphdGlvbkNvZGUjc3RhdGVcIiBmcm9tIHRoZSBhdXRob3JpemF0aW9uIGNhbGxiYWNrIFVSTFxuICAgICAgY29uc3QgW2F1dGhvcml6YXRpb25Db2RlLCBzdGF0ZV0gPSB2YWx1ZS5zcGxpdCgnIycpXG5cbiAgICAgIGlmICghYXV0aG9yaXphdGlvbkNvZGUgfHwgIXN0YXRlKSB7XG4gICAgICAgIHNldE9BdXRoU3RhdHVzKHtcbiAgICAgICAgICBzdGF0ZTogJ2Vycm9yJyxcbiAgICAgICAgICBtZXNzYWdlOiAnSW52YWxpZCBjb2RlLiBQbGVhc2UgbWFrZSBzdXJlIHRoZSBmdWxsIGNvZGUgd2FzIGNvcGllZCcsXG4gICAgICAgICAgdG9SZXRyeTogeyBzdGF0ZTogJ3dhaXRpbmdfZm9yX2xvZ2luJywgdXJsIH0sXG4gICAgICAgIH0pXG4gICAgICAgIHJldHVyblxuICAgICAgfVxuXG4gICAgICAvLyBUcmFjayB3aGljaCBwYXRoIHRoZSB1c2VyIGlzIHRha2luZyAobWFudWFsIGNvZGUgZW50cnkpXG4gICAgICBsb2dFdmVudCgndGVuZ3Vfb2F1dGhfbWFudWFsX2VudHJ5Jywge30pXG4gICAgICBvYXV0aFNlcnZpY2UuaGFuZGxlTWFudWFsQXV0aENvZGVJbnB1dCh7XG4gICAgICAgIGF1dGhvcml6YXRpb25Db2RlLFxuICAgICAgICBzdGF0ZSxcbiAgICAgIH0pXG4gICAgfSBjYXRjaCAoZXJyOiB1bmtub3duKSB7XG4gICAgICBsb2dFcnJvcihlcnIpXG4gICAgICBzZXRPQXV0aFN0YXR1cyh7XG4gICAgICAgIHN0YXRlOiAnZXJyb3InLFxuICAgICAgICBtZXNzYWdlOiAoZXJyIGFzIEVycm9yKS5tZXNzYWdlLFxuICAgICAgICB0b1JldHJ5OiB7IHN0YXRlOiAnd2FpdGluZ19mb3JfbG9naW4nLCB1cmwgfSxcbiAgICAgIH0pXG4gICAgfVxuICB9XG5cbiAgY29uc3Qgc3RhcnRPQXV0aCA9IHVzZUNhbGxiYWNrKGFzeW5jICgpID0+IHtcbiAgICB0cnkge1xuICAgICAgbG9nRXZlbnQoJ3Rlbmd1X29hdXRoX2Zsb3dfc3RhcnQnLCB7IGxvZ2luV2l0aENsYXVkZUFpIH0pXG5cbiAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IG9hdXRoU2VydmljZVxuICAgICAgICAuc3RhcnRPQXV0aEZsb3coXG4gICAgICAgICAgYXN5bmMgdXJsID0+IHtcbiAgICAgICAgICAgIHNldE9BdXRoU3RhdHVzKHsgc3RhdGU6ICd3YWl0aW5nX2Zvcl9sb2dpbicsIHVybCB9KVxuICAgICAgICAgICAgc2V0VGltZW91dChzZXRTaG93UGFzdGVQcm9tcHQsIDMwMDAsIHRydWUpXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBsb2dpbldpdGhDbGF1ZGVBaSxcbiAgICAgICAgICAgIGluZmVyZW5jZU9ubHk6IG1vZGUgPT09ICdzZXR1cC10b2tlbicsXG4gICAgICAgICAgICBleHBpcmVzSW46IG1vZGUgPT09ICdzZXR1cC10b2tlbicgPyAzNjUgKiAyNCAqIDYwICogNjAgOiB1bmRlZmluZWQsIC8vIDEgeWVhciBmb3Igc2V0dXAtdG9rZW5cbiAgICAgICAgICAgIG9yZ1VVSUQsXG4gICAgICAgICAgfSxcbiAgICAgICAgKVxuICAgICAgICAuY2F0Y2goZXJyID0+IHtcbiAgICAgICAgICBjb25zdCBpc1Rva2VuRXhjaGFuZ2VFcnJvciA9IGVyci5tZXNzYWdlLmluY2x1ZGVzKFxuICAgICAgICAgICAgJ1Rva2VuIGV4Y2hhbmdlIGZhaWxlZCcsXG4gICAgICAgICAgKVxuICAgICAgICAgIC8vIEVudGVycHJpc2UgVExTIHByb3hpZXMgKFpzY2FsZXIgZXQgYWwuKSBpbnRlcmNlcHQgdGhlIHRva2VuXG4gICAgICAgICAgLy8gZXhjaGFuZ2UgUE9TVCBhbmQgY2F1c2UgY3J5cHRpYyBTU0wgZXJyb3JzLiBTdXJmYWNlIGFuXG4gICAgICAgICAgLy8gYWN0aW9uYWJsZSBoaW50IHNvIHRoZSB1c2VyIGlzbid0IHN0dWNrIGluIGEgbG9naW4gbG9vcC5cbiAgICAgICAgICBjb25zdCBzc2xIaW50ID0gZ2V0U1NMRXJyb3JIaW50KGVycilcbiAgICAgICAgICBzZXRPQXV0aFN0YXR1cyh7XG4gICAgICAgICAgICBzdGF0ZTogJ2Vycm9yJyxcbiAgICAgICAgICAgIG1lc3NhZ2U6XG4gICAgICAgICAgICAgIHNzbEhpbnQgPz9cbiAgICAgICAgICAgICAgKGlzVG9rZW5FeGNoYW5nZUVycm9yXG4gICAgICAgICAgICAgICAgPyAnRmFpbGVkIHRvIGV4Y2hhbmdlIGF1dGhvcml6YXRpb24gY29kZSBmb3IgYWNjZXNzIHRva2VuLiBQbGVhc2UgdHJ5IGFnYWluLidcbiAgICAgICAgICAgICAgICA6IGVyci5tZXNzYWdlKSxcbiAgICAgICAgICAgIHRvUmV0cnk6XG4gICAgICAgICAgICAgIG1vZGUgPT09ICdzZXR1cC10b2tlbidcbiAgICAgICAgICAgICAgICA/IHsgc3RhdGU6ICdyZWFkeV90b19zdGFydCcgfVxuICAgICAgICAgICAgICAgIDogeyBzdGF0ZTogJ2lkbGUnIH0sXG4gICAgICAgICAgfSlcbiAgICAgICAgICBsb2dFdmVudCgndGVuZ3Vfb2F1dGhfdG9rZW5fZXhjaGFuZ2VfZXJyb3InLCB7XG4gICAgICAgICAgICBlcnJvcjogZXJyLm1lc3NhZ2UsXG4gICAgICAgICAgICBzc2xfZXJyb3I6IHNzbEhpbnQgIT09IG51bGwsXG4gICAgICAgICAgfSlcbiAgICAgICAgICB0aHJvdyBlcnJcbiAgICAgICAgfSlcblxuICAgICAgaWYgKG1vZGUgPT09ICdzZXR1cC10b2tlbicpIHtcbiAgICAgICAgLy8gRm9yIHNldHVwLXRva2VuIG1vZGUsIHJldHVybiB0aGUgT0F1dGggYWNjZXNzIHRva2VuIGRpcmVjdGx5IChpdCBjYW4gYmUgdXNlZCBhcyBhbiBBUEkga2V5KVxuICAgICAgICAvLyBEb24ndCBzYXZlIHRvIGtleWNoYWluIC0gdGhlIHRva2VuIGlzIGRpc3BsYXllZCBmb3IgbWFudWFsIHVzZSB3aXRoIENMQVVERV9DT0RFX09BVVRIX1RPS0VOXG4gICAgICAgIHNldE9BdXRoU3RhdHVzKHsgc3RhdGU6ICdzdWNjZXNzJywgdG9rZW46IHJlc3VsdC5hY2Nlc3NUb2tlbiB9KVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYXdhaXQgaW5zdGFsbE9BdXRoVG9rZW5zKHJlc3VsdClcblxuICAgICAgICBjb25zdCBvcmdSZXN1bHQgPSBhd2FpdCB2YWxpZGF0ZUZvcmNlTG9naW5PcmcoKVxuICAgICAgICBpZiAoIW9yZ1Jlc3VsdC52YWxpZCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihvcmdSZXN1bHQubWVzc2FnZSlcbiAgICAgICAgfVxuXG4gICAgICAgIHNldE9BdXRoU3RhdHVzKHsgc3RhdGU6ICdzdWNjZXNzJyB9KVxuICAgICAgICB2b2lkIHNlbmROb3RpZmljYXRpb24oXG4gICAgICAgICAge1xuICAgICAgICAgICAgbWVzc2FnZTogJ0NsYXVkZSBDb2RlIGxvZ2luIHN1Y2Nlc3NmdWwnLFxuICAgICAgICAgICAgbm90aWZpY2F0aW9uVHlwZTogJ2F1dGhfc3VjY2VzcycsXG4gICAgICAgICAgfSxcbiAgICAgICAgICB0ZXJtaW5hbCxcbiAgICAgICAgKVxuICAgICAgfVxuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgY29uc3QgZXJyb3JNZXNzYWdlID0gKGVyciBhcyBFcnJvcikubWVzc2FnZVxuICAgICAgY29uc3Qgc3NsSGludCA9IGdldFNTTEVycm9ySGludChlcnIpXG4gICAgICBzZXRPQXV0aFN0YXR1cyh7XG4gICAgICAgIHN0YXRlOiAnZXJyb3InLFxuICAgICAgICBtZXNzYWdlOiBzc2xIaW50ID8/IGVycm9yTWVzc2FnZSxcbiAgICAgICAgdG9SZXRyeToge1xuICAgICAgICAgIHN0YXRlOiBtb2RlID09PSAnc2V0dXAtdG9rZW4nID8gJ3JlYWR5X3RvX3N0YXJ0JyA6ICdpZGxlJyxcbiAgICAgICAgfSxcbiAgICAgIH0pXG4gICAgICBsb2dFdmVudCgndGVuZ3Vfb2F1dGhfZXJyb3InLCB7XG4gICAgICAgIGVycm9yOlxuICAgICAgICAgIGVycm9yTWVzc2FnZSBhcyBBbmFseXRpY3NNZXRhZGF0YV9JX1ZFUklGSUVEX1RISVNfSVNfTk9UX0NPREVfT1JfRklMRVBBVEhTLFxuICAgICAgICBzc2xfZXJyb3I6IHNzbEhpbnQgIT09IG51bGwsXG4gICAgICB9KVxuICAgIH1cbiAgfSwgW29hdXRoU2VydmljZSwgc2V0U2hvd1Bhc3RlUHJvbXB0LCBsb2dpbldpdGhDbGF1ZGVBaSwgbW9kZSwgb3JnVVVJRF0pXG5cbiAgY29uc3QgcGVuZGluZ09BdXRoU3RhcnRSZWYgPSB1c2VSZWYoZmFsc2UpXG5cbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBpZiAoXG4gICAgICBvYXV0aFN0YXR1cy5zdGF0ZSA9PT0gJ3JlYWR5X3RvX3N0YXJ0JyAmJlxuICAgICAgIXBlbmRpbmdPQXV0aFN0YXJ0UmVmLmN1cnJlbnRcbiAgICApIHtcbiAgICAgIHBlbmRpbmdPQXV0aFN0YXJ0UmVmLmN1cnJlbnQgPSB0cnVlXG4gICAgICBwcm9jZXNzLm5leHRUaWNrKFxuICAgICAgICAoXG4gICAgICAgICAgc3RhcnRPQXV0aDogKCkgPT4gUHJvbWlzZTx2b2lkPixcbiAgICAgICAgICBwZW5kaW5nT0F1dGhTdGFydFJlZjogUmVhY3QuTXV0YWJsZVJlZk9iamVjdDxib29sZWFuPixcbiAgICAgICAgKSA9PiB7XG4gICAgICAgICAgdm9pZCBzdGFydE9BdXRoKClcbiAgICAgICAgICBwZW5kaW5nT0F1dGhTdGFydFJlZi5jdXJyZW50ID0gZmFsc2VcbiAgICAgICAgfSxcbiAgICAgICAgc3RhcnRPQXV0aCxcbiAgICAgICAgcGVuZGluZ09BdXRoU3RhcnRSZWYsXG4gICAgICApXG4gICAgfVxuICB9LCBbb2F1dGhTdGF0dXMuc3RhdGUsIHN0YXJ0T0F1dGhdKVxuXG4gIC8vIEF1dG8tZXhpdCBmb3Igc2V0dXAtdG9rZW4gbW9kZVxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGlmIChtb2RlID09PSAnc2V0dXAtdG9rZW4nICYmIG9hdXRoU3RhdHVzLnN0YXRlID09PSAnc3VjY2VzcycpIHtcbiAgICAgIC8vIERlbGF5IHRvIGVuc3VyZSBzdGF0aWMgY29udGVudCBpcyBmdWxseSByZW5kZXJlZCBiZWZvcmUgZXhpdGluZ1xuICAgICAgY29uc3QgdGltZXIgPSBzZXRUaW1lb3V0KFxuICAgICAgICAobG9naW5XaXRoQ2xhdWRlQWksIG9uRG9uZSkgPT4ge1xuICAgICAgICAgIGxvZ0V2ZW50KCd0ZW5ndV9vYXV0aF9zdWNjZXNzJywgeyBsb2dpbldpdGhDbGF1ZGVBaSB9KVxuICAgICAgICAgIC8vIERvbid0IGNsZWFyIHRlcm1pbmFsIHNvIHRoZSB0b2tlbiByZW1haW5zIHZpc2libGVcbiAgICAgICAgICBvbkRvbmUoKVxuICAgICAgICB9LFxuICAgICAgICA1MDAsXG4gICAgICAgIGxvZ2luV2l0aENsYXVkZUFpLFxuICAgICAgICBvbkRvbmUsXG4gICAgICApXG4gICAgICByZXR1cm4gKCkgPT4gY2xlYXJUaW1lb3V0KHRpbWVyKVxuICAgIH1cbiAgfSwgW21vZGUsIG9hdXRoU3RhdHVzLCBsb2dpbldpdGhDbGF1ZGVBaSwgb25Eb25lXSlcblxuICAvLyBDbGVhbnVwIE9BdXRoIHNlcnZpY2Ugd2hlbiBjb21wb25lbnQgdW5tb3VudHNcbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgb2F1dGhTZXJ2aWNlLmNsZWFudXAoKVxuICAgIH1cbiAgfSwgW29hdXRoU2VydmljZV0pXG5cbiAgcmV0dXJuIChcbiAgICA8Qm94IGZsZXhEaXJlY3Rpb249XCJjb2x1bW5cIiBnYXA9ezF9PlxuICAgICAge29hdXRoU3RhdHVzLnN0YXRlID09PSAnd2FpdGluZ19mb3JfbG9naW4nICYmIHNob3dQYXN0ZVByb21wdCAmJiAoXG4gICAgICAgIDxCb3ggZmxleERpcmVjdGlvbj1cImNvbHVtblwiIGtleT1cInVybFRvQ29weVwiIGdhcD17MX0gcGFkZGluZ0JvdHRvbT17MX0+XG4gICAgICAgICAgPEJveCBwYWRkaW5nWD17MX0+XG4gICAgICAgICAgICA8VGV4dCBkaW1Db2xvcj5cbiAgICAgICAgICAgICAgQnJvd3NlciBkaWRuJmFwb3M7dCBvcGVuPyBVc2UgdGhlIHVybCBiZWxvdyB0byBzaWduIGlueycgJ31cbiAgICAgICAgICAgIDwvVGV4dD5cbiAgICAgICAgICAgIHt1cmxDb3BpZWQgPyAoXG4gICAgICAgICAgICAgIDxUZXh0IGNvbG9yPVwic3VjY2Vzc1wiPihDb3BpZWQhKTwvVGV4dD5cbiAgICAgICAgICAgICkgOiAoXG4gICAgICAgICAgICAgIDxUZXh0IGRpbUNvbG9yPlxuICAgICAgICAgICAgICAgIDxLZXlib2FyZFNob3J0Y3V0SGludCBzaG9ydGN1dD1cImNcIiBhY3Rpb249XCJjb3B5XCIgcGFyZW5zIC8+XG4gICAgICAgICAgICAgIDwvVGV4dD5cbiAgICAgICAgICAgICl9XG4gICAgICAgICAgPC9Cb3g+XG4gICAgICAgICAgPExpbmsgdXJsPXtvYXV0aFN0YXR1cy51cmx9PlxuICAgICAgICAgICAgPFRleHQgZGltQ29sb3I+e29hdXRoU3RhdHVzLnVybH08L1RleHQ+XG4gICAgICAgICAgPC9MaW5rPlxuICAgICAgICA8L0JveD5cbiAgICAgICl9XG4gICAgICB7bW9kZSA9PT0gJ3NldHVwLXRva2VuJyAmJlxuICAgICAgICBvYXV0aFN0YXR1cy5zdGF0ZSA9PT0gJ3N1Y2Nlc3MnICYmXG4gICAgICAgIG9hdXRoU3RhdHVzLnRva2VuICYmIChcbiAgICAgICAgICA8Qm94IGtleT1cInRva2VuT3V0cHV0XCIgZmxleERpcmVjdGlvbj1cImNvbHVtblwiIGdhcD17MX0gcGFkZGluZ1RvcD17MX0+XG4gICAgICAgICAgICA8VGV4dCBjb2xvcj1cInN1Y2Nlc3NcIj5cbiAgICAgICAgICAgICAg4pyTIExvbmctbGl2ZWQgYXV0aGVudGljYXRpb24gdG9rZW4gY3JlYXRlZCBzdWNjZXNzZnVsbHkhXG4gICAgICAgICAgICA8L1RleHQ+XG4gICAgICAgICAgICA8Qm94IGZsZXhEaXJlY3Rpb249XCJjb2x1bW5cIiBnYXA9ezF9PlxuICAgICAgICAgICAgICA8VGV4dD5Zb3VyIE9BdXRoIHRva2VuICh2YWxpZCBmb3IgMSB5ZWFyKTo8L1RleHQ+XG4gICAgICAgICAgICAgIDxUZXh0IGNvbG9yPVwid2FybmluZ1wiPntvYXV0aFN0YXR1cy50b2tlbn08L1RleHQ+XG4gICAgICAgICAgICAgIDxUZXh0IGRpbUNvbG9yPlxuICAgICAgICAgICAgICAgIFN0b3JlIHRoaXMgdG9rZW4gc2VjdXJlbHkuIFlvdSB3b24mYXBvczt0IGJlIGFibGUgdG8gc2VlIGl0XG4gICAgICAgICAgICAgICAgYWdhaW4uXG4gICAgICAgICAgICAgIDwvVGV4dD5cbiAgICAgICAgICAgICAgPFRleHQgZGltQ29sb3I+XG4gICAgICAgICAgICAgICAgVXNlIHRoaXMgdG9rZW4gYnkgc2V0dGluZzogZXhwb3J0XG4gICAgICAgICAgICAgICAgQ0xBVURFX0NPREVfT0FVVEhfVE9LRU49Jmx0O3Rva2VuJmd0O1xuICAgICAgICAgICAgICA8L1RleHQ+XG4gICAgICAgICAgICA8L0JveD5cbiAgICAgICAgICA8L0JveD5cbiAgICAgICAgKX1cbiAgICAgIDxCb3ggcGFkZGluZ0xlZnQ9ezF9IGZsZXhEaXJlY3Rpb249XCJjb2x1bW5cIiBnYXA9ezF9PlxuICAgICAgICA8T0F1dGhTdGF0dXNNZXNzYWdlXG4gICAgICAgICAgb2F1dGhTdGF0dXM9e29hdXRoU3RhdHVzfVxuICAgICAgICAgIG1vZGU9e21vZGV9XG4gICAgICAgICAgc3RhcnRpbmdNZXNzYWdlPXtzdGFydGluZ01lc3NhZ2V9XG4gICAgICAgICAgZm9yY2VkTWV0aG9kTWVzc2FnZT17Zm9yY2VkTWV0aG9kTWVzc2FnZX1cbiAgICAgICAgICBzaG93UGFzdGVQcm9tcHQ9e3Nob3dQYXN0ZVByb21wdH1cbiAgICAgICAgICBwYXN0ZWRDb2RlPXtwYXN0ZWRDb2RlfVxuICAgICAgICAgIHNldFBhc3RlZENvZGU9e3NldFBhc3RlZENvZGV9XG4gICAgICAgICAgY3Vyc29yT2Zmc2V0PXtjdXJzb3JPZmZzZXR9XG4gICAgICAgICAgc2V0Q3Vyc29yT2Zmc2V0PXtzZXRDdXJzb3JPZmZzZXR9XG4gICAgICAgICAgdGV4dElucHV0Q29sdW1ucz17dGV4dElucHV0Q29sdW1uc31cbiAgICAgICAgICBoYW5kbGVTdWJtaXRDb2RlPXtoYW5kbGVTdWJtaXRDb2RlfVxuICAgICAgICAgIHNldE9BdXRoU3RhdHVzPXtzZXRPQXV0aFN0YXR1c31cbiAgICAgICAgICBzZXRMb2dpbldpdGhDbGF1ZGVBaT17c2V0TG9naW5XaXRoQ2xhdWRlQWl9XG4gICAgICAgIC8+XG4gICAgICA8L0JveD5cbiAgICA8L0JveD5cbiAgKVxufVxuXG50eXBlIE9BdXRoU3RhdHVzTWVzc2FnZVByb3BzID0ge1xuICBvYXV0aFN0YXR1czogT0F1dGhTdGF0dXNcbiAgbW9kZTogJ2xvZ2luJyB8ICdzZXR1cC10b2tlbidcbiAgc3RhcnRpbmdNZXNzYWdlOiBzdHJpbmcgfCB1bmRlZmluZWRcbiAgZm9yY2VkTWV0aG9kTWVzc2FnZTogc3RyaW5nIHwgbnVsbFxuICBzaG93UGFzdGVQcm9tcHQ6IGJvb2xlYW5cbiAgcGFzdGVkQ29kZTogc3RyaW5nXG4gIHNldFBhc3RlZENvZGU6ICh2YWx1ZTogc3RyaW5nKSA9PiB2b2lkXG4gIGN1cnNvck9mZnNldDogbnVtYmVyXG4gIHNldEN1cnNvck9mZnNldDogKG9mZnNldDogbnVtYmVyKSA9PiB2b2lkXG4gIHRleHRJbnB1dENvbHVtbnM6IG51bWJlclxuICBoYW5kbGVTdWJtaXRDb2RlOiAodmFsdWU6IHN0cmluZywgdXJsOiBzdHJpbmcpID0+IHZvaWRcbiAgc2V0T0F1dGhTdGF0dXM6IChzdGF0dXM6IE9BdXRoU3RhdHVzKSA9PiB2b2lkXG4gIHNldExvZ2luV2l0aENsYXVkZUFpOiAodmFsdWU6IGJvb2xlYW4pID0+IHZvaWRcbn1cblxuZnVuY3Rpb24gT0F1dGhTdGF0dXNNZXNzYWdlKHtcbiAgb2F1dGhTdGF0dXMsXG4gIG1vZGUsXG4gIHN0YXJ0aW5nTWVzc2FnZSxcbiAgZm9yY2VkTWV0aG9kTWVzc2FnZSxcbiAgc2hvd1Bhc3RlUHJvbXB0LFxuICBwYXN0ZWRDb2RlLFxuICBzZXRQYXN0ZWRDb2RlLFxuICBjdXJzb3JPZmZzZXQsXG4gIHNldEN1cnNvck9mZnNldCxcbiAgdGV4dElucHV0Q29sdW1ucyxcbiAgaGFuZGxlU3VibWl0Q29kZSxcbiAgc2V0T0F1dGhTdGF0dXMsXG4gIHNldExvZ2luV2l0aENsYXVkZUFpLFxufTogT0F1dGhTdGF0dXNNZXNzYWdlUHJvcHMpOiBSZWFjdC5SZWFjdE5vZGUge1xuICBzd2l0Y2ggKG9hdXRoU3RhdHVzLnN0YXRlKSB7XG4gICAgY2FzZSAnaWRsZSc6XG4gICAgICByZXR1cm4gKFxuICAgICAgICA8Qm94IGZsZXhEaXJlY3Rpb249XCJjb2x1bW5cIiBnYXA9ezF9IG1hcmdpblRvcD17MX0+XG4gICAgICAgICAgPFRleHQgYm9sZD5cbiAgICAgICAgICAgIHtzdGFydGluZ01lc3NhZ2VcbiAgICAgICAgICAgICAgPyBzdGFydGluZ01lc3NhZ2VcbiAgICAgICAgICAgICAgOiBgQ2xhdWRlIENvZGUgY2FuIGJlIHVzZWQgd2l0aCB5b3VyIENsYXVkZSBzdWJzY3JpcHRpb24gb3IgYmlsbGVkIGJhc2VkIG9uIEFQSSB1c2FnZSB0aHJvdWdoIHlvdXIgQ29uc29sZSBhY2NvdW50LmB9XG4gICAgICAgICAgPC9UZXh0PlxuXG4gICAgICAgICAgPFRleHQ+U2VsZWN0IGxvZ2luIG1ldGhvZDo8L1RleHQ+XG5cbiAgICAgICAgICA8Qm94PlxuICAgICAgICAgICAgPFNlbGVjdFxuICAgICAgICAgICAgICBvcHRpb25zPXtbXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgbGFiZWw6IChcbiAgICAgICAgICAgICAgICAgICAgPFRleHQ+XG4gICAgICAgICAgICAgICAgICAgICAgQ2xhdWRlIGFjY291bnQgd2l0aCBzdWJzY3JpcHRpb24gwrd7JyAnfVxuICAgICAgICAgICAgICAgICAgICAgIDxUZXh0IGRpbUNvbG9yPlBybywgTWF4LCBUZWFtLCBvciBFbnRlcnByaXNlPC9UZXh0PlxuICAgICAgICAgICAgICAgICAgICAgIHtcImV4dGVybmFsXCIgPT09ICdhbnQnICYmIChcbiAgICAgICAgICAgICAgICAgICAgICAgIDxUZXh0PlxuICAgICAgICAgICAgICAgICAgICAgICAgICB7J1xcbid9XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxUZXh0IGNvbG9yPVwid2FybmluZ1wiPltBTlQtT05MWV08L1RleHQ+eycgJ31cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPFRleHQgZGltQ29sb3I+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgUGxlYXNlIHVzZSB0aGlzIG9wdGlvbiB1bmxlc3MgeW91IG5lZWQgdG8gbG9naW4gdG8gYVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwZWNpYWwgb3JnIGZvciBhY2Nlc3Npbmcgc2Vuc2l0aXZlIGRhdGEgKGUuZy5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXN0b21lciBkYXRhLCBISVBJIGRhdGEpIHdpdGggdGhlIENvbnNvbGUgb3B0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwvVGV4dD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvVGV4dD5cbiAgICAgICAgICAgICAgICAgICAgICApfVxuICAgICAgICAgICAgICAgICAgICAgIHsnXFxuJ31cbiAgICAgICAgICAgICAgICAgICAgPC9UZXh0PlxuICAgICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICAgIHZhbHVlOiAnY2xhdWRlYWknLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgbGFiZWw6IChcbiAgICAgICAgICAgICAgICAgICAgPFRleHQ+XG4gICAgICAgICAgICAgICAgICAgICAgQW50aHJvcGljIENvbnNvbGUgYWNjb3VudCDCt3snICd9XG4gICAgICAgICAgICAgICAgICAgICAgPFRleHQgZGltQ29sb3I+QVBJIHVzYWdlIGJpbGxpbmc8L1RleHQ+XG4gICAgICAgICAgICAgICAgICAgICAgeydcXG4nfVxuICAgICAgICAgICAgICAgICAgICA8L1RleHQ+XG4gICAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgICAgdmFsdWU6ICdjb25zb2xlJyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgIGxhYmVsOiAoXG4gICAgICAgICAgICAgICAgICAgIDxUZXh0PlxuICAgICAgICAgICAgICAgICAgICAgIDNyZC1wYXJ0eSBwbGF0Zm9ybSDCt3snICd9XG4gICAgICAgICAgICAgICAgICAgICAgPFRleHQgZGltQ29sb3I+XG4gICAgICAgICAgICAgICAgICAgICAgICBBbWF6b24gQmVkcm9jaywgTWljcm9zb2Z0IEZvdW5kcnksIG9yIFZlcnRleCBBSVxuICAgICAgICAgICAgICAgICAgICAgIDwvVGV4dD5cbiAgICAgICAgICAgICAgICAgICAgICB7J1xcbid9XG4gICAgICAgICAgICAgICAgICAgIDwvVGV4dD5cbiAgICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgICB2YWx1ZTogJ3BsYXRmb3JtJyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICBdfVxuICAgICAgICAgICAgICBvbkNoYW5nZT17dmFsdWUgPT4ge1xuICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PT0gJ3BsYXRmb3JtJykge1xuICAgICAgICAgICAgICAgICAgbG9nRXZlbnQoJ3Rlbmd1X29hdXRoX3BsYXRmb3JtX3NlbGVjdGVkJywge30pXG4gICAgICAgICAgICAgICAgICBzZXRPQXV0aFN0YXR1cyh7IHN0YXRlOiAncGxhdGZvcm1fc2V0dXAnIH0pXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIHNldE9BdXRoU3RhdHVzKHsgc3RhdGU6ICdyZWFkeV90b19zdGFydCcgfSlcbiAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PT0gJ2NsYXVkZWFpJykge1xuICAgICAgICAgICAgICAgICAgICBsb2dFdmVudCgndGVuZ3Vfb2F1dGhfY2xhdWRlYWlfc2VsZWN0ZWQnLCB7fSlcbiAgICAgICAgICAgICAgICAgICAgc2V0TG9naW5XaXRoQ2xhdWRlQWkodHJ1ZSlcbiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGxvZ0V2ZW50KCd0ZW5ndV9vYXV0aF9jb25zb2xlX3NlbGVjdGVkJywge30pXG4gICAgICAgICAgICAgICAgICAgIHNldExvZ2luV2l0aENsYXVkZUFpKGZhbHNlKVxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfX1cbiAgICAgICAgICAgIC8+XG4gICAgICAgICAgPC9Cb3g+XG4gICAgICAgIDwvQm94PlxuICAgICAgKVxuXG4gICAgY2FzZSAncGxhdGZvcm1fc2V0dXAnOlxuICAgICAgcmV0dXJuIChcbiAgICAgICAgPEJveCBmbGV4RGlyZWN0aW9uPVwiY29sdW1uXCIgZ2FwPXsxfSBtYXJnaW5Ub3A9ezF9PlxuICAgICAgICAgIDxUZXh0IGJvbGQ+VXNpbmcgM3JkLXBhcnR5IHBsYXRmb3JtczwvVGV4dD5cblxuICAgICAgICAgIDxCb3ggZmxleERpcmVjdGlvbj1cImNvbHVtblwiIGdhcD17MX0+XG4gICAgICAgICAgICA8VGV4dD5cbiAgICAgICAgICAgICAgQ2xhdWRlIENvZGUgc3VwcG9ydHMgQW1hem9uIEJlZHJvY2ssIE1pY3Jvc29mdCBGb3VuZHJ5LCBhbmQgVmVydGV4XG4gICAgICAgICAgICAgIEFJLiBTZXQgdGhlIHJlcXVpcmVkIGVudmlyb25tZW50IHZhcmlhYmxlcywgdGhlbiByZXN0YXJ0IENsYXVkZVxuICAgICAgICAgICAgICBDb2RlLlxuICAgICAgICAgICAgPC9UZXh0PlxuXG4gICAgICAgICAgICA8VGV4dD5cbiAgICAgICAgICAgICAgSWYgeW91IGFyZSBwYXJ0IG9mIGFuIGVudGVycHJpc2Ugb3JnYW5pemF0aW9uLCBjb250YWN0IHlvdXJcbiAgICAgICAgICAgICAgYWRtaW5pc3RyYXRvciBmb3Igc2V0dXAgaW5zdHJ1Y3Rpb25zLlxuICAgICAgICAgICAgPC9UZXh0PlxuXG4gICAgICAgICAgICA8Qm94IGZsZXhEaXJlY3Rpb249XCJjb2x1bW5cIiBtYXJnaW5Ub3A9ezF9PlxuICAgICAgICAgICAgICA8VGV4dCBib2xkPkRvY3VtZW50YXRpb246PC9UZXh0PlxuICAgICAgICAgICAgICA8VGV4dD5cbiAgICAgICAgICAgICAgICDCtyBBbWF6b24gQmVkcm9jazp7JyAnfVxuICAgICAgICAgICAgICAgIDxMaW5rIHVybD1cImh0dHBzOi8vY29kZS5jbGF1ZGUuY29tL2RvY3MvZW4vYW1hem9uLWJlZHJvY2tcIj5cbiAgICAgICAgICAgICAgICAgIGh0dHBzOi8vY29kZS5jbGF1ZGUuY29tL2RvY3MvZW4vYW1hem9uLWJlZHJvY2tcbiAgICAgICAgICAgICAgICA8L0xpbms+XG4gICAgICAgICAgICAgIDwvVGV4dD5cbiAgICAgICAgICAgICAgPFRleHQ+XG4gICAgICAgICAgICAgICAgwrcgTWljcm9zb2Z0IEZvdW5kcnk6eycgJ31cbiAgICAgICAgICAgICAgICA8TGluayB1cmw9XCJodHRwczovL2NvZGUuY2xhdWRlLmNvbS9kb2NzL2VuL21pY3Jvc29mdC1mb3VuZHJ5XCI+XG4gICAgICAgICAgICAgICAgICBodHRwczovL2NvZGUuY2xhdWRlLmNvbS9kb2NzL2VuL21pY3Jvc29mdC1mb3VuZHJ5XG4gICAgICAgICAgICAgICAgPC9MaW5rPlxuICAgICAgICAgICAgICA8L1RleHQ+XG4gICAgICAgICAgICAgIDxUZXh0PlxuICAgICAgICAgICAgICAgIMK3IFZlcnRleCBBSTp7JyAnfVxuICAgICAgICAgICAgICAgIDxMaW5rIHVybD1cImh0dHBzOi8vY29kZS5jbGF1ZGUuY29tL2RvY3MvZW4vZ29vZ2xlLXZlcnRleC1haVwiPlxuICAgICAgICAgICAgICAgICAgaHR0cHM6Ly9jb2RlLmNsYXVkZS5jb20vZG9jcy9lbi9nb29nbGUtdmVydGV4LWFpXG4gICAgICAgICAgICAgICAgPC9MaW5rPlxuICAgICAgICAgICAgICA8L1RleHQ+XG4gICAgICAgICAgICA8L0JveD5cblxuICAgICAgICAgICAgPEJveCBtYXJnaW5Ub3A9ezF9PlxuICAgICAgICAgICAgICA8VGV4dCBkaW1Db2xvcj5cbiAgICAgICAgICAgICAgICBQcmVzcyA8VGV4dCBib2xkPkVudGVyPC9UZXh0PiB0byBnbyBiYWNrIHRvIGxvZ2luIG9wdGlvbnMuXG4gICAgICAgICAgICAgIDwvVGV4dD5cbiAgICAgICAgICAgIDwvQm94PlxuICAgICAgICAgIDwvQm94PlxuICAgICAgICA8L0JveD5cbiAgICAgIClcblxuICAgIGNhc2UgJ3dhaXRpbmdfZm9yX2xvZ2luJzpcbiAgICAgIHJldHVybiAoXG4gICAgICAgIDxCb3ggZmxleERpcmVjdGlvbj1cImNvbHVtblwiIGdhcD17MX0+XG4gICAgICAgICAge2ZvcmNlZE1ldGhvZE1lc3NhZ2UgJiYgKFxuICAgICAgICAgICAgPEJveD5cbiAgICAgICAgICAgICAgPFRleHQgZGltQ29sb3I+e2ZvcmNlZE1ldGhvZE1lc3NhZ2V9PC9UZXh0PlxuICAgICAgICAgICAgPC9Cb3g+XG4gICAgICAgICAgKX1cblxuICAgICAgICAgIHshc2hvd1Bhc3RlUHJvbXB0ICYmIChcbiAgICAgICAgICAgIDxCb3g+XG4gICAgICAgICAgICAgIDxTcGlubmVyIC8+XG4gICAgICAgICAgICAgIDxUZXh0Pk9wZW5pbmcgYnJvd3NlciB0byBzaWduIGlu4oCmPC9UZXh0PlxuICAgICAgICAgICAgPC9Cb3g+XG4gICAgICAgICAgKX1cblxuICAgICAgICAgIHtzaG93UGFzdGVQcm9tcHQgJiYgKFxuICAgICAgICAgICAgPEJveD5cbiAgICAgICAgICAgICAgPFRleHQ+e1BBU1RFX0hFUkVfTVNHfTwvVGV4dD5cbiAgICAgICAgICAgICAgPFRleHRJbnB1dFxuICAgICAgICAgICAgICAgIHZhbHVlPXtwYXN0ZWRDb2RlfVxuICAgICAgICAgICAgICAgIG9uQ2hhbmdlPXtzZXRQYXN0ZWRDb2RlfVxuICAgICAgICAgICAgICAgIG9uU3VibWl0PXsodmFsdWU6IHN0cmluZykgPT5cbiAgICAgICAgICAgICAgICAgIGhhbmRsZVN1Ym1pdENvZGUodmFsdWUsIG9hdXRoU3RhdHVzLnVybClcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY3Vyc29yT2Zmc2V0PXtjdXJzb3JPZmZzZXR9XG4gICAgICAgICAgICAgICAgb25DaGFuZ2VDdXJzb3JPZmZzZXQ9e3NldEN1cnNvck9mZnNldH1cbiAgICAgICAgICAgICAgICBjb2x1bW5zPXt0ZXh0SW5wdXRDb2x1bW5zfVxuICAgICAgICAgICAgICAgIG1hc2s9XCIqXCJcbiAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgIDwvQm94PlxuICAgICAgICAgICl9XG4gICAgICAgIDwvQm94PlxuICAgICAgKVxuXG4gICAgY2FzZSAnY3JlYXRpbmdfYXBpX2tleSc6XG4gICAgICByZXR1cm4gKFxuICAgICAgICA8Qm94IGZsZXhEaXJlY3Rpb249XCJjb2x1bW5cIiBnYXA9ezF9PlxuICAgICAgICAgIDxCb3g+XG4gICAgICAgICAgICA8U3Bpbm5lciAvPlxuICAgICAgICAgICAgPFRleHQ+Q3JlYXRpbmcgQVBJIGtleSBmb3IgQ2xhdWRlIENvZGXigKY8L1RleHQ+XG4gICAgICAgICAgPC9Cb3g+XG4gICAgICAgIDwvQm94PlxuICAgICAgKVxuXG4gICAgY2FzZSAnYWJvdXRfdG9fcmV0cnknOlxuICAgICAgcmV0dXJuIChcbiAgICAgICAgPEJveCBmbGV4RGlyZWN0aW9uPVwiY29sdW1uXCIgZ2FwPXsxfT5cbiAgICAgICAgICA8VGV4dCBjb2xvcj1cInBlcm1pc3Npb25cIj5SZXRyeWluZ+KApjwvVGV4dD5cbiAgICAgICAgPC9Cb3g+XG4gICAgICApXG5cbiAgICBjYXNlICdzdWNjZXNzJzpcbiAgICAgIHJldHVybiAoXG4gICAgICAgIDxCb3ggZmxleERpcmVjdGlvbj1cImNvbHVtblwiPlxuICAgICAgICAgIHttb2RlID09PSAnc2V0dXAtdG9rZW4nICYmIG9hdXRoU3RhdHVzLnRva2VuID8gbnVsbCA6IChcbiAgICAgICAgICAgIDw+XG4gICAgICAgICAgICAgIHtnZXRPYXV0aEFjY291bnRJbmZvKCk/LmVtYWlsQWRkcmVzcyA/IChcbiAgICAgICAgICAgICAgICA8VGV4dCBkaW1Db2xvcj5cbiAgICAgICAgICAgICAgICAgIExvZ2dlZCBpbiBhc3snICd9XG4gICAgICAgICAgICAgICAgICA8VGV4dD57Z2V0T2F1dGhBY2NvdW50SW5mbygpPy5lbWFpbEFkZHJlc3N9PC9UZXh0PlxuICAgICAgICAgICAgICAgIDwvVGV4dD5cbiAgICAgICAgICAgICAgKSA6IG51bGx9XG4gICAgICAgICAgICAgIDxUZXh0IGNvbG9yPVwic3VjY2Vzc1wiPlxuICAgICAgICAgICAgICAgIExvZ2luIHN1Y2Nlc3NmdWwuIFByZXNzIDxUZXh0IGJvbGQ+RW50ZXI8L1RleHQ+IHRvIGNvbnRpbnVl4oCmXG4gICAgICAgICAgICAgIDwvVGV4dD5cbiAgICAgICAgICAgIDwvPlxuICAgICAgICAgICl9XG4gICAgICAgIDwvQm94PlxuICAgICAgKVxuXG4gICAgY2FzZSAnZXJyb3InOlxuICAgICAgcmV0dXJuIChcbiAgICAgICAgPEJveCBmbGV4RGlyZWN0aW9uPVwiY29sdW1uXCIgZ2FwPXsxfT5cbiAgICAgICAgICA8VGV4dCBjb2xvcj1cImVycm9yXCI+T0F1dGggZXJyb3I6IHtvYXV0aFN0YXR1cy5tZXNzYWdlfTwvVGV4dD5cblxuICAgICAgICAgIHtvYXV0aFN0YXR1cy50b1JldHJ5ICYmIChcbiAgICAgICAgICAgIDxCb3ggbWFyZ2luVG9wPXsxfT5cbiAgICAgICAgICAgICAgPFRleHQgY29sb3I9XCJwZXJtaXNzaW9uXCI+XG4gICAgICAgICAgICAgICAgUHJlc3MgPFRleHQgYm9sZD5FbnRlcjwvVGV4dD4gdG8gcmV0cnkuXG4gICAgICAgICAgICAgIDwvVGV4dD5cbiAgICAgICAgICAgIDwvQm94PlxuICAgICAgICAgICl9XG4gICAgICAgIDwvQm94PlxuICAgICAgKVxuXG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBudWxsXG4gIH1cbn1cbiJdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU9BLEtBQUssSUFBSUMsV0FBVyxFQUFFQyxTQUFTLEVBQUVDLE1BQU0sRUFBRUMsUUFBUSxRQUFRLE9BQU87QUFDdkUsU0FDRSxLQUFLQywwREFBMEQsRUFDL0RDLFFBQVEsUUFDSCxpQ0FBaUM7QUFDeEMsU0FBU0Msa0JBQWtCLFFBQVEseUJBQXlCO0FBQzVELFNBQVNDLGVBQWUsUUFBUSw2QkFBNkI7QUFDN0QsU0FBU0MsWUFBWSxRQUFRLHNCQUFzQjtBQUNuRCxTQUFTQyx1QkFBdUIsUUFBUSxtQ0FBbUM7QUFDM0UsU0FBU0MsR0FBRyxFQUFFQyxJQUFJLEVBQUVDLElBQUksUUFBUSxXQUFXO0FBQzNDLFNBQVNDLGFBQWEsUUFBUSxpQ0FBaUM7QUFDL0QsU0FBU0MsZUFBZSxRQUFRLCtCQUErQjtBQUMvRCxTQUFTQyxn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