diff --git a/src/components/StatusLine.tsx b/src/components/StatusLine.tsx index eafb49ad..f2132ae9 100644 --- a/src/components/StatusLine.tsx +++ b/src/components/StatusLine.tsx @@ -16,15 +16,17 @@ import type { Message } from '../types/message.js'; import type { StatusLineCommandInput } from '../types/statusLine.js'; import type { VimMode } from '../types/textInputTypes.js'; import { checkHasTrustDialogAccepted } from '../utils/config.js'; -import { calculateContextPercentages, getContextWindowForModel } from '../utils/context.js'; +import { calculateCurrentContextTokenTotal, getContextWindowForModel } from '../utils/context.js'; +import { calculateContextPercentagesFromTokens, getProviderUsageTrust, hasMediaInput } from '../utils/contextBudget.js'; import { getCwd } from '../utils/cwd.js'; import { logForDebugging } from '../utils/debug.js'; import { isFullscreenEnvEnabled } from '../utils/fullscreen.js'; import { createBaseHookInput, executeStatusLineCommand } from '../utils/hooks.js'; import { getLastAssistantMessage } from '../utils/messages.js'; import { getRuntimeMainLoopModel, type ModelName, renderModelName } from '../utils/model/model.js'; +import { isFirstPartyAnthropicBaseUrl } from '../utils/model/providers.js'; import { getCurrentSessionTitle } from '../utils/sessionStorage.js'; -import { doesMostRecentAssistantMessageExceed200k, getCurrentUsage } from '../utils/tokens.js'; +import { doesMostRecentAssistantMessageExceed200k, getCurrentUsage, tokenCountWithEstimation } from '../utils/tokens.js'; import { getCurrentWorktreeSession } from '../utils/worktree.js'; import { isVimModeEnabled } from './PromptInput/utils.js'; export function statusLineShouldDisplay(settings: ReadonlySettings): boolean { @@ -44,7 +46,14 @@ function buildStatusLineCommandInput(permissionMode: PermissionMode, exceeds200k const outputStyleName = settings?.outputStyle || DEFAULT_OUTPUT_STYLE_NAME; const currentUsage = getCurrentUsage(messages); const contextWindowSize = getContextWindowForModel(runtimeModel, getSdkBetas()); - const contextPercentages = calculateContextPercentages(currentUsage, contextWindowSize); + const estimatedContextTokens = tokenCountWithEstimation(messages); + const contextTokens = calculateCurrentContextTokenTotal(estimatedContextTokens, currentUsage, contextWindowSize, { + usageTrust: getProviderUsageTrust({ + isFirstPartyAnthropic: isFirstPartyAnthropicBaseUrl() + }), + hasMediaInput: hasMediaInput(messages) + }); + const contextPercentages = calculateContextPercentagesFromTokens(contextTokens, contextWindowSize); const sessionId = getSessionId(); const sessionName = getCurrentSessionTitle(sessionId); const rawUtil = getRawUtilization(); @@ -321,4 +330,4 @@ function StatusLineInner({ // own props now only change when lastAssistantMessageId flips — memo keeps it // from being dragged along (previously ~18 no-prop-change renders per session). export const StatusLine = memo(StatusLineInner); -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJmZWF0dXJlIiwiUmVhY3QiLCJtZW1vIiwidXNlQ2FsbGJhY2siLCJ1c2VFZmZlY3QiLCJ1c2VSZWYiLCJsb2dFdmVudCIsInVzZUFwcFN0YXRlIiwidXNlU2V0QXBwU3RhdGUiLCJQZXJtaXNzaW9uTW9kZSIsImdldElzUmVtb3RlTW9kZSIsImdldEthaXJvc0FjdGl2ZSIsImdldE1haW5UaHJlYWRBZ2VudFR5cGUiLCJnZXRPcmlnaW5hbEN3ZCIsImdldFNka0JldGFzIiwiZ2V0U2Vzc2lvbklkIiwiREVGQVVMVF9PVVRQVVRfU1RZTEVfTkFNRSIsInVzZU5vdGlmaWNhdGlvbnMiLCJnZXRUb3RhbEFQSUR1cmF0aW9uIiwiZ2V0VG90YWxDb3N0IiwiZ2V0VG90YWxEdXJhdGlvbiIsImdldFRvdGFsSW5wdXRUb2tlbnMiLCJnZXRUb3RhbExpbmVzQWRkZWQiLCJnZXRUb3RhbExpbmVzUmVtb3ZlZCIsImdldFRvdGFsT3V0cHV0VG9rZW5zIiwidXNlTWFpbkxvb3BNb2RlbCIsIlJlYWRvbmx5U2V0dGluZ3MiLCJ1c2VTZXR0aW5ncyIsIkFuc2kiLCJCb3giLCJUZXh0IiwiZ2V0UmF3VXRpbGl6YXRpb24iLCJNZXNzYWdlIiwiU3RhdHVzTGluZUNvbW1hbmRJbnB1dCIsIlZpbU1vZGUiLCJjaGVja0hhc1RydXN0RGlhbG9nQWNjZXB0ZWQiLCJjYWxjdWxhdGVDb250ZXh0UGVyY2VudGFnZXMiLCJnZXRDb250ZXh0V2luZG93Rm9yTW9kZWwiLCJnZXRDd2QiLCJsb2dGb3JEZWJ1Z2dpbmciLCJpc0Z1bGxzY3JlZW5FbnZFbmFibGVkIiwiY3JlYXRlQmFzZUhvb2tJbnB1dCIsImV4ZWN1dGVTdGF0dXNMaW5lQ29tbWFuZCIsImdldExhc3RBc3Npc3RhbnRNZXNzYWdlIiwiZ2V0UnVudGltZU1haW5Mb29wTW9kZWwiLCJNb2RlbE5hbWUiLCJyZW5kZXJNb2RlbE5hbWUiLCJnZXRDdXJyZW50U2Vzc2lvblRpdGxlIiwiZG9lc01vc3RSZWNlbnRBc3Npc3RhbnRNZXNzYWdlRXhjZWVkMjAwayIsImdldEN1cnJlbnRVc2FnZSIsImdldEN1cnJlbnRXb3JrdHJlZVNlc3Npb24iLCJpc1ZpbU1vZGVFbmFibGVkIiwic3RhdHVzTGluZVNob3VsZERpc3BsYXkiLCJzZXR0aW5ncyIsInN0YXR1c0xpbmUiLCJ1bmRlZmluZWQiLCJidWlsZFN0YXR1c0xpbmVDb21tYW5kSW5wdXQiLCJwZXJtaXNzaW9uTW9kZSIsImV4Y2VlZHMyMDBrVG9rZW5zIiwibWVzc2FnZXMiLCJhZGRlZERpcnMiLCJtYWluTG9vcE1vZGVsIiwidmltTW9kZSIsImFnZW50VHlwZSIsIndvcmt0cmVlU2Vzc2lvbiIsInJ1bnRpbWVNb2RlbCIsIm91dHB1dFN0eWxlTmFtZSIsIm91dHB1dFN0eWxlIiwiY3VycmVudFVzYWdlIiwiY29udGV4dFdpbmRvd1NpemUiLCJjb250ZXh0UGVyY2VudGFnZXMiLCJzZXNzaW9uSWQiLCJzZXNzaW9uTmFtZSIsInJhd1V0aWwiLCJyYXRlTGltaXRzIiwiZml2ZV9ob3VyIiwidXNlZF9wZXJjZW50YWdlIiwidXRpbGl6YXRpb24iLCJyZXNldHNfYXQiLCJzZXZlbl9kYXkiLCJzZXNzaW9uX25hbWUiLCJtb2RlbCIsImlkIiwiZGlzcGxheV9uYW1lIiwid29ya3NwYWNlIiwiY3VycmVudF9kaXIiLCJwcm9qZWN0X2RpciIsImFkZGVkX2RpcnMiLCJ2ZXJzaW9uIiwiTUFDUk8iLCJWRVJTSU9OIiwib3V0cHV0X3N0eWxlIiwibmFtZSIsImNvc3QiLCJ0b3RhbF9jb3N0X3VzZCIsInRvdGFsX2R1cmF0aW9uX21zIiwidG90YWxfYXBpX2R1cmF0aW9uX21zIiwidG90YWxfbGluZXNfYWRkZWQiLCJ0b3RhbF9saW5lc19yZW1vdmVkIiwiY29udGV4dF93aW5kb3ciLCJ0b3RhbF9pbnB1dF90b2tlbnMiLCJ0b3RhbF9vdXRwdXRfdG9rZW5zIiwiY29udGV4dF93aW5kb3dfc2l6ZSIsImN1cnJlbnRfdXNhZ2UiLCJ1c2VkIiwicmVtYWluaW5nX3BlcmNlbnRhZ2UiLCJyZW1haW5pbmciLCJleGNlZWRzXzIwMGtfdG9rZW5zIiwicmF0ZV9saW1pdHMiLCJ2aW0iLCJtb2RlIiwiYWdlbnQiLCJyZW1vdGUiLCJzZXNzaW9uX2lkIiwid29ya3RyZWUiLCJ3b3JrdHJlZU5hbWUiLCJwYXRoIiwid29ya3RyZWVQYXRoIiwiYnJhbmNoIiwid29ya3RyZWVCcmFuY2giLCJvcmlnaW5hbF9jd2QiLCJvcmlnaW5hbEN3ZCIsIm9yaWdpbmFsX2JyYW5jaCIsIm9yaWdpbmFsQnJhbmNoIiwiUHJvcHMiLCJtZXNzYWdlc1JlZiIsIlJlZk9iamVjdCIsImxhc3RBc3Npc3RhbnRNZXNzYWdlSWQiLCJnZXRMYXN0QXNzaXN0YW50TWVzc2FnZUlkIiwidXVpZCIsIlN0YXR1c0xpbmVJbm5lciIsIlJlYWN0Tm9kZSIsImFib3J0Q29udHJvbGxlclJlZiIsIkFib3J0Q29udHJvbGxlciIsInMiLCJ0b29sUGVybWlzc2lvbkNvbnRleHQiLCJhZGRpdGlvbmFsV29ya2luZ0RpcmVjdG9yaWVzIiwic3RhdHVzTGluZVRleHQiLCJzZXRBcHBTdGF0ZSIsImFkZE5vdGlmaWNhdGlvbiIsInNldHRpbmdzUmVmIiwiY3VycmVudCIsInZpbU1vZGVSZWYiLCJwZXJtaXNzaW9uTW9kZVJlZiIsImFkZGVkRGlyc1JlZiIsIm1haW5Mb29wTW9kZWxSZWYiLCJwcmV2aW91c1N0YXRlUmVmIiwibWVzc2FnZUlkIiwiZGVib3VuY2VUaW1lclJlZiIsIlJldHVyblR5cGUiLCJzZXRUaW1lb3V0IiwibG9nTmV4dFJlc3VsdFJlZiIsImRvVXBkYXRlIiwiYWJvcnQiLCJjb250cm9sbGVyIiwibXNncyIsImxvZ1Jlc3VsdCIsImN1cnJlbnRNZXNzYWdlSWQiLCJzdGF0dXNJbnB1dCIsIkFycmF5IiwiZnJvbSIsImtleXMiLCJ0ZXh0Iiwic2lnbmFsIiwiYWJvcnRlZCIsInByZXYiLCJzY2hlZHVsZVVwZGF0ZSIsImNsZWFyVGltZW91dCIsInJlZiIsInN0YXR1c0xpbmVDb21tYW5kIiwiY29tbWFuZCIsImlzRmlyc3RTZXR0aW5nc1JlbmRlciIsImNvbW1hbmRfbGVuZ3RoIiwibGVuZ3RoIiwicGFkZGluZyIsImRpc2FibGVBbGxIb29rcyIsImxldmVsIiwia2V5IiwiY29sb3IiLCJwcmlvcml0eSIsInBhZGRpbmdYIiwiU3RhdHVzTGluZSJdLCJzb3VyY2VzIjpbIlN0YXR1c0xpbmUudHN4Il0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGZlYXR1cmUgfSBmcm9tICdidW46YnVuZGxlJ1xuaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnXG5pbXBvcnQgeyBtZW1vLCB1c2VDYWxsYmFjaywgdXNlRWZmZWN0LCB1c2VSZWYgfSBmcm9tICdyZWFjdCdcbmltcG9ydCB7IGxvZ0V2ZW50IH0gZnJvbSAnc3JjL3NlcnZpY2VzL2FuYWx5dGljcy9pbmRleC5qcydcbmltcG9ydCB7IHVzZUFwcFN0YXRlLCB1c2VTZXRBcHBTdGF0ZSB9IGZyb20gJ3NyYy9zdGF0ZS9BcHBTdGF0ZS5qcydcbmltcG9ydCB0eXBlIHsgUGVybWlzc2lvbk1vZGUgfSBmcm9tICdzcmMvdXRpbHMvcGVybWlzc2lvbnMvUGVybWlzc2lvbk1vZGUuanMnXG5pbXBvcnQge1xuICBnZXRJc1JlbW90ZU1vZGUsXG4gIGdldEthaXJvc0FjdGl2ZSxcbiAgZ2V0TWFpblRocmVhZEFnZW50VHlwZSxcbiAgZ2V0T3JpZ2luYWxDd2QsXG4gIGdldFNka0JldGFzLFxuICBnZXRTZXNzaW9uSWQsXG59IGZyb20gJy4uL2Jvb3RzdHJhcC9zdGF0ZS5qcydcbmltcG9ydCB7IERFRkFVTFRfT1VUUFVUX1NUWUxFX05BTUUgfSBmcm9tICcuLi9jb25zdGFudHMvb3V0cHV0U3R5bGVzLmpzJ1xuaW1wb3J0IHsgdXNlTm90aWZpY2F0aW9ucyB9IGZyb20gJy4uL2NvbnRleHQvbm90aWZpY2F0aW9ucy5qcydcbmltcG9ydCB7XG4gIGdldFRvdGFsQVBJRHVyYXRpb24sXG4gIGdldFRvdGFsQ29zdCxcbiAgZ2V0VG90YWxEdXJhdGlvbixcbiAgZ2V0VG90YWxJbnB1dFRva2VucyxcbiAgZ2V0VG90YWxMaW5lc0FkZGVkLFxuICBnZXRUb3RhbExpbmVzUmVtb3ZlZCxcbiAgZ2V0VG90YWxPdXRwdXRUb2tlbnMsXG59IGZyb20gJy4uL2Nvc3QtdHJhY2tlci5qcydcbmltcG9ydCB7IHVzZU1haW5Mb29wTW9kZWwgfSBmcm9tICcuLi9ob29rcy91c2VNYWluTG9vcE1vZGVsLmpzJ1xuaW1wb3J0IHsgdHlwZSBSZWFkb25seVNldHRpbmdzLCB1c2VTZXR0aW5ncyB9IGZyb20gJy4uL2hvb2tzL3VzZVNldHRpbmdzLmpzJ1xuaW1wb3J0IHsgQW5zaSwgQm94LCBUZXh0IH0gZnJvbSAnLi4vaW5rLmpzJ1xuaW1wb3J0IHsgZ2V0UmF3VXRpbGl6YXRpb24gfSBmcm9tICcuLi9zZXJ2aWNlcy9jbGF1ZGVBaUxpbWl0cy5qcydcbmltcG9ydCB0eXBlIHsgTWVzc2FnZSB9IGZyb20gJy4uL3R5cGVzL21lc3NhZ2UuanMnXG5pbXBvcnQgdHlwZSB7IFN0YXR1c0xpbmVDb21tYW5kSW5wdXQgfSBmcm9tICcuLi90eXBlcy9zdGF0dXNMaW5lLmpzJ1xuaW1wb3J0IHR5cGUgeyBWaW1Nb2RlIH0gZnJvbSAnLi4vdHlwZXMvdGV4dElucHV0VHlwZXMuanMnXG5pbXBvcnQgeyBjaGVja0hhc1RydXN0RGlhbG9nQWNjZXB0ZWQgfSBmcm9tICcuLi91dGlscy9jb25maWcuanMnXG5pbXBvcnQge1xuICBjYWxjdWxhdGVDb250ZXh0UGVyY2VudGFnZXMsXG4gIGdldENvbnRleHRXaW5kb3dGb3JNb2RlbCxcbn0gZnJvbSAnLi4vdXRpbHMvY29udGV4dC5qcydcbmltcG9ydCB7IGdldEN3ZCB9IGZyb20gJy4uL3V0aWxzL2N3ZC5qcydcbmltcG9ydCB7IGxvZ0ZvckRlYnVnZ2luZyB9IGZyb20gJy4uL3V0aWxzL2RlYnVnLmpzJ1xuaW1wb3J0IHsgaXNGdWxsc2NyZWVuRW52RW5hYmxlZCB9IGZyb20gJy4uL3V0aWxzL2Z1bGxzY3JlZW4uanMnXG5pbXBvcnQge1xuICBjcmVhdGVCYXNlSG9va0lucHV0LFxuICBleGVjdXRlU3RhdHVzTGluZUNvbW1hbmQsXG59IGZyb20gJy4uL3V0aWxzL2hvb2tzLmpzJ1xuaW1wb3J0IHsgZ2V0TGFzdEFzc2lzdGFudE1lc3NhZ2UgfSBmcm9tICcuLi91dGlscy9tZXNzYWdlcy5qcydcbmltcG9ydCB7XG4gIGdldFJ1bnRpbWVNYWluTG9vcE1vZGVsLFxuICB0eXBlIE1vZGVsTmFtZSxcbiAgcmVuZGVyTW9kZWxOYW1lLFxufSBmcm9tICcuLi91dGlscy9tb2RlbC9tb2RlbC5qcydcbmltcG9ydCB7IGdldEN1cnJlbnRTZXNzaW9uVGl0bGUgfSBmcm9tICcuLi91dGlscy9zZXNzaW9uU3RvcmFnZS5qcydcbmltcG9ydCB7XG4gIGRvZXNNb3N0UmVjZW50QXNzaXN0YW50TWVzc2FnZUV4Y2VlZDIwMGssXG4gIGdldEN1cnJlbnRVc2FnZSxcbn0gZnJvbSAnLi4vdXRpbHMvdG9rZW5zLmpzJ1xuaW1wb3J0IHsgZ2V0Q3VycmVudFdvcmt0cmVlU2Vzc2lvbiB9IGZyb20gJy4uL3V0aWxzL3dvcmt0cmVlLmpzJ1xuaW1wb3J0IHsgaXNWaW1Nb2RlRW5hYmxlZCB9IGZyb20gJy4vUHJvbXB0SW5wdXQvdXRpbHMuanMnXG5cbmV4cG9ydCBmdW5jdGlvbiBzdGF0dXNMaW5lU2hvdWxkRGlzcGxheShzZXR0aW5nczogUmVhZG9ubHlTZXR0aW5ncyk6IGJvb2xlYW4ge1xuICAvLyBBc3Npc3RhbnQgbW9kZTogc3RhdHVzbGluZSBmaWVsZHMgKG1vZGVsLCBwZXJtaXNzaW9uIG1vZGUsIGN3ZCkgcmVmbGVjdCB0aGVcbiAgLy8gUkVQTC9kYWVtb24gcHJvY2Vzcywgbm90IHdoYXQgdGhlIGFnZW50IGNoaWxkIGlzIGFjdHVhbGx5IHJ1bm5pbmcuIEhpZGUgaXQuXG4gIGlmIChmZWF0dXJlKCdLQUlST1MnKSAmJiBnZXRLYWlyb3NBY3RpdmUoKSkgcmV0dXJuIGZhbHNlXG4gIHJldHVybiBzZXR0aW5ncz8uc3RhdHVzTGluZSAhPT0gdW5kZWZpbmVkXG59XG5cbmZ1bmN0aW9uIGJ1aWxkU3RhdHVzTGluZUNvbW1hbmRJbnB1dChcbiAgcGVybWlzc2lvbk1vZGU6IFBlcm1pc3Npb25Nb2RlLFxuICBleGNlZWRzMjAwa1Rva2VuczogYm9vbGVhbixcbiAgc2V0dGluZ3M6IFJlYWRvbmx5U2V0dGluZ3MsXG4gIG1lc3NhZ2VzOiBNZXNzYWdlW10sXG4gIGFkZGVkRGlyczogc3RyaW5nW10sXG4gIG1haW5Mb29wTW9kZWw6IE1vZGVsTmFtZSxcbiAgdmltTW9kZT86IFZpbU1vZGUsXG4pOiBTdGF0dXNMaW5lQ29tbWFuZElucHV0IHtcbiAgY29uc3QgYWdlbnRUeXBlID0gZ2V0TWFpblRocmVhZEFnZW50VHlwZSgpXG4gIGNvbnN0IHdvcmt0cmVlU2Vzc2lvbiA9IGdldEN1cnJlbnRXb3JrdHJlZVNlc3Npb24oKVxuICBjb25zdCBydW50aW1lTW9kZWwgPSBnZXRSdW50aW1lTWFpbkxvb3BNb2RlbCh7XG4gICAgcGVybWlzc2lvbk1vZGUsXG4gICAgbWFpbkxvb3BNb2RlbCxcbiAgICBleGNlZWRzMjAwa1Rva2VucyxcbiAgfSlcbiAgY29uc3Qgb3V0cHV0U3R5bGVOYW1lID0gc2V0dGluZ3M/Lm91dHB1dFN0eWxlIHx8IERFRkFVTFRfT1VUUFVUX1NUWUxFX05BTUVcblxuICBjb25zdCBjdXJyZW50VXNhZ2UgPSBnZXRDdXJyZW50VXNhZ2UobWVzc2FnZXMpXG4gIGNvbnN0IGNvbnRleHRXaW5kb3dTaXplID0gZ2V0Q29udGV4dFdpbmRvd0Zvck1vZGVsKFxuICAgIHJ1bnRpbWVNb2RlbCxcbiAgICBnZXRTZGtCZXRhcygpLFxuICApXG4gIGNvbnN0IGNvbnRleHRQZXJjZW50YWdlcyA9IGNhbGN1bGF0ZUNvbnRleHRQZXJjZW50YWdlcyhcbiAgICBjdXJyZW50VXNhZ2UsXG4gICAgY29udGV4dFdpbmRvd1NpemUsXG4gIClcblxuICBjb25zdCBzZXNzaW9uSWQgPSBnZXRTZXNzaW9uSWQoKVxuICBjb25zdCBzZXNzaW9uTmFtZSA9IGdldEN1cnJlbnRTZXNzaW9uVGl0bGUoc2Vzc2lvbklkKVxuICBjb25zdCByYXdVdGlsID0gZ2V0UmF3VXRpbGl6YXRpb24oKVxuICBjb25zdCByYXRlTGltaXRzOiBTdGF0dXNMaW5lQ29tbWFuZElucHV0WydyYXRlX2xpbWl0cyddID0ge1xuICAgIC4uLihyYXdVdGlsLmZpdmVfaG91ciAmJiB7XG4gICAgICBmaXZlX2hvdXI6IHtcbiAgICAgICAgdXNlZF9wZXJjZW50YWdlOiByYXdVdGlsLmZpdmVfaG91ci51dGlsaXphdGlvbiAqIDEwMCxcbiAgICAgICAgcmVzZXRzX2F0OiByYXdVdGlsLmZpdmVfaG91ci5yZXNldHNfYXQsXG4gICAgICB9LFxuICAgIH0pLFxuICAgIC4uLihyYXdVdGlsLnNldmVuX2RheSAmJiB7XG4gICAgICBzZXZlbl9kYXk6IHtcbiAgICAgICAgdXNlZF9wZXJjZW50YWdlOiByYXdVdGlsLnNldmVuX2RheS51dGlsaXphdGlvbiAqIDEwMCxcbiAgICAgICAgcmVzZXRzX2F0OiByYXdVdGlsLnNldmVuX2RheS5yZXNldHNfYXQsXG4gICAgICB9LFxuICAgIH0pLFxuICB9XG4gIHJldHVybiB7XG4gICAgLi4uY3JlYXRlQmFzZUhvb2tJbnB1dCgpLFxuICAgIC4uLihzZXNzaW9uTmFtZSAmJiB7IHNlc3Npb25fbmFtZTogc2Vzc2lvbk5hbWUgfSksXG4gICAgbW9kZWw6IHtcbiAgICAgIGlkOiBydW50aW1lTW9kZWwsXG4gICAgICBkaXNwbGF5X25hbWU6IHJlbmRlck1vZGVsTmFtZShydW50aW1lTW9kZWwpLFxuICAgIH0sXG4gICAgd29ya3NwYWNlOiB7XG4gICAgICBjdXJyZW50X2RpcjogZ2V0Q3dkKCksXG4gICAgICBwcm9qZWN0X2RpcjogZ2V0T3JpZ2luYWxDd2QoKSxcbiAgICAgIGFkZGVkX2RpcnM6IGFkZGVkRGlycyxcbiAgICB9LFxuICAgIHZlcnNpb246IE1BQ1JPLlZFUlNJT04sXG4gICAgb3V0cHV0X3N0eWxlOiB7XG4gICAgICBuYW1lOiBvdXRwdXRTdHlsZU5hbWUsXG4gICAgfSxcbiAgICBjb3N0OiB7XG4gICAgICB0b3RhbF9jb3N0X3VzZDogZ2V0VG90YWxDb3N0KCksXG4gICAgICB0b3RhbF9kdXJhdGlvbl9tczogZ2V0VG90YWxEdXJhdGlvbigpLFxuICAgICAgdG90YWxfYXBpX2R1cmF0aW9uX21zOiBnZXRUb3RhbEFQSUR1cmF0aW9uKCksXG4gICAgICB0b3RhbF9saW5lc19hZGRlZDogZ2V0VG90YWxMaW5lc0FkZGVkKCksXG4gICAgICB0b3RhbF9saW5lc19yZW1vdmVkOiBnZXRUb3RhbExpbmVzUmVtb3ZlZCgpLFxuICAgIH0sXG4gICAgY29udGV4dF93aW5kb3c6IHtcbiAgICAgIHRvdGFsX2lucHV0X3Rva2VuczogZ2V0VG90YWxJbnB1dFRva2VucygpLFxuICAgICAgdG90YWxfb3V0cHV0X3Rva2VuczogZ2V0VG90YWxPdXRwdXRUb2tlbnMoKSxcbiAgICAgIGNvbnRleHRfd2luZG93X3NpemU6IGNvbnRleHRXaW5kb3dTaXplLFxuICAgICAgY3VycmVudF91c2FnZTogY3VycmVudFVzYWdlLFxuICAgICAgdXNlZF9wZXJjZW50YWdlOiBjb250ZXh0UGVyY2VudGFnZXMudXNlZCxcbiAgICAgIHJlbWFpbmluZ19wZXJjZW50YWdlOiBjb250ZXh0UGVyY2VudGFnZXMucmVtYWluaW5nLFxuICAgIH0sXG4gICAgZXhjZWVkc18yMDBrX3Rva2VuczogZXhjZWVkczIwMGtUb2tlbnMsXG4gICAgLi4uKChyYXRlTGltaXRzLmZpdmVfaG91ciB8fCByYXRlTGltaXRzLnNldmVuX2RheSkgJiYge1xuICAgICAgcmF0ZV9saW1pdHM6IHJhdGVMaW1pdHMsXG4gICAgfSksXG4gICAgLi4uKGlzVmltTW9kZUVuYWJsZWQoKSAmJiB7XG4gICAgICB2aW06IHtcbiAgICAgICAgbW9kZTogdmltTW9kZSA/PyAnSU5TRVJUJyxcbiAgICAgIH0sXG4gICAgfSksXG4gICAgLi4uKGFnZW50VHlwZSAmJiB7XG4gICAgICBhZ2VudDoge1xuICAgICAgICBuYW1lOiBhZ2VudFR5cGUsXG4gICAgICB9LFxuICAgIH0pLFxuICAgIC4uLihnZXRJc1JlbW90ZU1vZGUoKSAmJiB7XG4gICAgICByZW1vdGU6IHtcbiAgICAgICAgc2Vzc2lvbl9pZDogZ2V0U2Vzc2lvbklkKCksXG4gICAgICB9LFxuICAgIH0pLFxuICAgIC4uLih3b3JrdHJlZVNlc3Npb24gJiYge1xuICAgICAgd29ya3RyZWU6IHtcbiAgICAgICAgbmFtZTogd29ya3RyZWVTZXNzaW9uLndvcmt0cmVlTmFtZSxcbiAgICAgICAgcGF0aDogd29ya3RyZWVTZXNzaW9uLndvcmt0cmVlUGF0aCxcbiAgICAgICAgYnJhbmNoOiB3b3JrdHJlZVNlc3Npb24ud29ya3RyZWVCcmFuY2gsXG4gICAgICAgIG9yaWdpbmFsX2N3ZDogd29ya3RyZWVTZXNzaW9uLm9yaWdpbmFsQ3dkLFxuICAgICAgICBvcmlnaW5hbF9icmFuY2g6IHdvcmt0cmVlU2Vzc2lvbi5vcmlnaW5hbEJyYW5jaCxcbiAgICAgIH0sXG4gICAgfSksXG4gIH1cbn1cblxudHlwZSBQcm9wcyA9IHtcbiAgLy8gbWVzc2FnZXMgc3RheXMgYmVoaW5kIGEgcmVmIChyZWFkIG9ubHkgaW4gdGhlIGRlYm91bmNlZCBjYWxsYmFjayk7XG4gIC8vIGxhc3RBc3Npc3RhbnRNZXNzYWdlSWQgaXMgdGhlIGFjdHVhbCByZS1yZW5kZXIgdHJpZ2dlci5cbiAgbWVzc2FnZXNSZWY6IFJlYWN0LlJlZk9iamVjdDxNZXNzYWdlW10+XG4gIGxhc3RBc3Npc3RhbnRNZXNzYWdlSWQ6IHN0cmluZyB8IG51bGxcbiAgdmltTW9kZT86IFZpbU1vZGVcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldExhc3RBc3Npc3RhbnRNZXNzYWdlSWQobWVzc2FnZXM6IE1lc3NhZ2VbXSk6IHN0cmluZyB8IG51bGwge1xuICByZXR1cm4gZ2V0TGFzdEFzc2lzdGFudE1lc3NhZ2UobWVzc2FnZXMpPy51dWlkID8/IG51bGxcbn1cblxuZnVuY3Rpb24gU3RhdHVzTGluZUlubmVyKHtcbiAgbWVzc2FnZXNSZWYsXG4gIGxhc3RBc3Npc3RhbnRNZXNzYWdlSWQsXG4gIHZpbU1vZGUsXG59OiBQcm9wcyk6IFJlYWN0LlJlYWN0Tm9kZSB7XG4gIGNvbnN0IGFib3J0Q29udHJvbGxlclJlZiA9IHVzZVJlZjxBYm9ydENvbnRyb2xsZXIgfCB1bmRlZmluZWQ+KHVuZGVmaW5lZClcbiAgY29uc3QgcGVybWlzc2lvbk1vZGUgPSB1c2VBcHBTdGF0ZShzID0+IHMudG9vbFBlcm1pc3Npb25Db250ZXh0Lm1vZGUpXG4gIGNvbnN0IGFkZGl0aW9uYWxXb3JraW5nRGlyZWN0b3JpZXMgPSB1c2VBcHBTdGF0ZShcbiAgICBzID0+IHMudG9vbFBlcm1pc3Npb25Db250ZXh0LmFkZGl0aW9uYWxXb3JraW5nRGlyZWN0b3JpZXMsXG4gIClcbiAgY29uc3Qgc3RhdHVzTGluZVRleHQgPSB1c2VBcHBTdGF0ZShzID0+IHMuc3RhdHVzTGluZVRleHQpXG4gIGNvbnN0IHNldEFwcFN0YXRlID0gdXNlU2V0QXBwU3RhdGUoKVxuICBjb25zdCBzZXR0aW5ncyA9IHVzZVNldHRpbmdzKClcbiAgY29uc3QgeyBhZGROb3RpZmljYXRpb24gfSA9IHVzZU5vdGlmaWNhdGlvbnMoKVxuICAvLyBBcHBTdGF0ZS1zb3VyY2VkIG1vZGVsIOKAlCBzYW1lIHNvdXJjZSBhcyBBUEkgcmVxdWVzdHMuIGdldE1haW5Mb29wTW9kZWwoKVxuICAvLyByZS1yZWFkcyBzZXR0aW5ncy5qc29uIG9uIGV2ZXJ5IGNhbGwsIHNvIGFub3RoZXIgc2Vzc2lvbidzIC9tb2RlbCB3cml0ZVxuICAvLyB3b3VsZCBsZWFrIGludG8gdGhpcyBzZXNzaW9uJ3Mgc3RhdHVzbGluZSAoYW50aHJvcGljcy9jbGF1ZGUtY29kZSMzNzU5NikuXG4gIGNvbnN0IG1haW5Mb29wTW9kZWwgPSB1c2VNYWluTG9vcE1vZGVsKClcblxuICAvLyBLZWVwIGxhdGVzdCB2YWx1ZXMgaW4gcmVmcyBmb3Igc3RhYmxlIGNhbGxiYWNrIGFjY2Vzc1xuICBjb25zdCBzZXR0aW5nc1JlZiA9IHVzZVJlZihzZXR0aW5ncylcbiAgc2V0dGluZ3NSZWYuY3VycmVudCA9IHNldHRpbmdzXG4gIGNvbnN0IHZpbU1vZGVSZWYgPSB1c2VSZWYodmltTW9kZSlcbiAgdmltTW9kZVJlZi5jdXJyZW50ID0gdmltTW9kZVxuICBjb25zdCBwZXJtaXNzaW9uTW9kZVJlZiA9IHVzZVJlZihwZXJtaXNzaW9uTW9kZSlcbiAgcGVybWlzc2lvbk1vZGVSZWYuY3VycmVudCA9IHBlcm1pc3Npb25Nb2RlXG4gIGNvbnN0IGFkZGVkRGlyc1JlZiA9IHVzZVJlZihhZGRpdGlvbmFsV29ya2luZ0RpcmVjdG9yaWVzKVxuICBhZGRlZERpcnNSZWYuY3VycmVudCA9IGFkZGl0aW9uYWxXb3JraW5nRGlyZWN0b3JpZXNcbiAgY29uc3QgbWFpbkxvb3BNb2RlbFJlZiA9IHVzZVJlZihtYWluTG9vcE1vZGVsKVxuICBtYWluTG9vcE1vZGVsUmVmLmN1cnJlbnQgPSBtYWluTG9vcE1vZGVsXG5cbiAgLy8gVHJhY2sgcHJldmlvdXMgc3RhdGUgdG8gZGV0ZWN0IGNoYW5nZXMgYW5kIGNhY2hlIGV4cGVuc2l2ZSBjYWxjdWxhdGlvbnNcbiAgY29uc3QgcHJldmlvdXNTdGF0ZVJlZiA9IHVzZVJlZjx7XG4gICAgbWVzc2FnZUlkOiBzdHJpbmcgfCBudWxsXG4gICAgZXhjZWVkczIwMGtUb2tlbnM6IGJvb2xlYW5cbiAgICBwZXJtaXNzaW9uTW9kZTogUGVybWlzc2lvbk1vZGVcbiAgICB2aW1Nb2RlOiBWaW1Nb2RlIHwgdW5kZWZpbmVkXG4gICAgbWFpbkxvb3BNb2RlbDogTW9kZWxOYW1lXG4gIH0+KHtcbiAgICBtZXNzYWdlSWQ6IG51bGwsXG4gICAgZXhjZWVkczIwMGtUb2tlbnM6IGZhbHNlLFxuICAgIHBlcm1pc3Npb25Nb2RlLFxuICAgIHZpbU1vZGUsXG4gICAgbWFpbkxvb3BNb2RlbCxcbiAgfSlcblxuICAvLyBEZWJvdW5jZSB0aW1lciByZWZcbiAgY29uc3QgZGVib3VuY2VUaW1lclJlZiA9IHVzZVJlZjxSZXR1cm5UeXBlPHR5cGVvZiBzZXRUaW1lb3V0PiB8IHVuZGVmaW5lZD4oXG4gICAgdW5kZWZpbmVkLFxuICApXG5cbiAgLy8gVHJ1ZSB3aGVuIHRoZSBuZXh0IGludm9jYXRpb24gc2hvdWxkIGxvZyBpdHMgcmVzdWx0IChmaXJzdCBydW4gb3IgYWZ0ZXIgc2V0dGluZ3MgcmVsb2FkKVxuICBjb25zdCBsb2dOZXh0UmVzdWx0UmVmID0gdXNlUmVmKHRydWUpXG5cbiAgLy8gU3RhYmxlIHVwZGF0ZSBmdW5jdGlvbiDigJQgcmVhZHMgbGF0ZXN0IHZhbHVlcyBmcm9tIHJlZnNcbiAgY29uc3QgZG9VcGRhdGUgPSB1c2VDYWxsYmFjayhhc3luYyAoKSA9PiB7XG4gICAgLy8gQ2FuY2VsIGFueSBpbi1mbGlnaHQgcmVxdWVzdHNcbiAgICBhYm9ydENvbnRyb2xsZXJSZWYuY3VycmVudD8uYWJvcnQoKVxuXG4gICAgY29uc3QgY29udHJvbGxlciA9IG5ldyBBYm9ydENvbnRyb2xsZXIoKVxuICAgIGFib3J0Q29udHJvbGxlclJlZi5jdXJyZW50ID0gY29udHJvbGxlclxuXG4gICAgY29uc3QgbXNncyA9IG1lc3NhZ2VzUmVmLmN1cnJlbnRcblxuICAgIGNvbnN0IGxvZ1Jlc3VsdCA9IGxvZ05leHRSZXN1bHRSZWYuY3VycmVudFxuICAgIGxvZ05leHRSZXN1bHRSZWYuY3VycmVudCA9IGZhbHNlXG5cbiAgICB0cnkge1xuICAgICAgbGV0IGV4Y2VlZHMyMDBrVG9rZW5zID0gcHJldmlvdXNTdGF0ZVJlZi5jdXJyZW50LmV4Y2VlZHMyMDBrVG9rZW5zXG5cbiAgICAgIC8vIE9ubHkgcmVjYWxjdWxhdGUgMjAwayBjaGVjayBpZiBtZXNzYWdlcyBjaGFuZ2VkXG4gICAgICBjb25zdCBjdXJyZW50TWVzc2FnZUlkID0gZ2V0TGFzdEFzc2lzdGFudE1lc3NhZ2VJZChtc2dzKVxuICAgICAgaWYgKGN1cnJlbnRNZXNzYWdlSWQgIT09IHByZXZpb3VzU3RhdGVSZWYuY3VycmVudC5tZXNzYWdlSWQpIHtcbiAgICAgICAgZXhjZWVkczIwMGtUb2tlbnMgPSBkb2VzTW9zdFJlY2VudEFzc2lzdGFudE1lc3NhZ2VFeGNlZWQyMDBrKG1zZ3MpXG4gICAgICAgIHByZXZpb3VzU3RhdGVSZWYuY3VycmVudC5tZXNzYWdlSWQgPSBjdXJyZW50TWVzc2FnZUlkXG4gICAgICAgIHByZXZpb3VzU3RhdGVSZWYuY3VycmVudC5leGNlZWRzMjAwa1Rva2VucyA9IGV4Y2VlZHMyMDBrVG9rZW5zXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHN0YXR1c0lucHV0ID0gYnVpbGRTdGF0dXNMaW5lQ29tbWFuZElucHV0KFxuICAgICAgICBwZXJtaXNzaW9uTW9kZVJlZi5jdXJyZW50LFxuICAgICAgICBleGNlZWRzMjAwa1Rva2VucyxcbiAgICAgICAgc2V0dGluZ3NSZWYuY3VycmVudCxcbiAgICAgICAgbXNncyxcbiAgICAgICAgQXJyYXkuZnJvbShhZGRlZERpcnNSZWYuY3VycmVudC5rZXlzKCkpLFxuICAgICAgICBtYWluTG9vcE1vZGVsUmVmLmN1cnJlbnQsXG4gICAgICAgIHZpbU1vZGVSZWYuY3VycmVudCxcbiAgICAgIClcblxuICAgICAgY29uc3QgdGV4dCA9IGF3YWl0IGV4ZWN1dGVTdGF0dXNMaW5lQ29tbWFuZChcbiAgICAgICAgc3RhdHVzSW5wdXQsXG4gICAgICAgIGNvbnRyb2xsZXIuc2lnbmFsLFxuICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgIGxvZ1Jlc3VsdCxcbiAgICAgIClcbiAgICAgIGlmICghY29udHJvbGxlci5zaWduYWwuYWJvcnRlZCkge1xuICAgICAgICBzZXRBcHBTdGF0ZShwcmV2ID0+IHtcbiAgICAgICAgICBpZiAocHJldi5zdGF0dXNMaW5lVGV4dCA9PT0gdGV4dCkgcmV0dXJuIHByZXZcbiAgICAgICAgICByZXR1cm4geyAuLi5wcmV2LCBzdGF0dXNMaW5lVGV4dDogdGV4dCB9XG4gICAgICAgIH0pXG4gICAgICB9XG4gICAgfSBjYXRjaCB7XG4gICAgICAvLyBTaWxlbnRseSBpZ25vcmUgZXJyb3JzIGluIHN0YXR1cyBsaW5lIHVwZGF0ZXNcbiAgICB9XG4gIH0sIFttZXNzYWdlc1JlZiwgc2V0QXBwU3RhdGVdKVxuXG4gIC8vIFN0YWJsZSBkZWJvdW5jZWQgc2NoZWR1bGUgZnVuY3Rpb24g4oCUIG5vIGRlcHMsIHVzZXMgcmVmc1xuICBjb25zdCBzY2hlZHVsZVVwZGF0ZSA9IHVzZUNhbGxiYWNrKCgpID0+IHtcbiAgICBpZiAoZGVib3VuY2VUaW1lclJlZi5jdXJyZW50ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGNsZWFyVGltZW91dChkZWJvdW5jZVRpbWVyUmVmLmN1cnJlbnQpXG4gICAgfVxuICAgIGRlYm91bmNlVGltZXJSZWYuY3VycmVudCA9IHNldFRpbWVvdXQoXG4gICAgICAocmVmLCBkb1VwZGF0ZSkgPT4ge1xuICAgICAgICByZWYuY3VycmVudCA9IHVuZGVmaW5lZFxuICAgICAgICB2b2lkIGRvVXBkYXRlKClcbiAgICAgIH0sXG4gICAgICAzMDAsXG4gICAgICBkZWJvdW5jZVRpbWVyUmVmLFxuICAgICAgZG9VcGRhdGUsXG4gICAgKVxuICB9LCBbZG9VcGRhdGVdKVxuXG4gIC8vIE9ubHkgdHJpZ2dlciB1cGRhdGUgd2hlbiBhc3Npc3RhbnQgbWVzc2FnZSwgcGVybWlzc2lvbiBtb2RlLCB2aW0gbW9kZSwgb3IgbW9kZWwgYWN0dWFsbHkgY2hhbmdlc1xuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGlmIChcbiAgICAgIGxhc3RBc3Npc3RhbnRNZXNzYWdlSWQgIT09IHByZXZpb3VzU3RhdGVSZWYuY3VycmVudC5tZXNzYWdlSWQgfHxcbiAgICAgIHBlcm1pc3Npb25Nb2RlICE9PSBwcmV2aW91c1N0YXRlUmVmLmN1cnJlbnQucGVybWlzc2lvbk1vZGUgfHxcbiAgICAgIHZpbU1vZGUgIT09IHByZXZpb3VzU3RhdGVSZWYuY3VycmVudC52aW1Nb2RlIHx8XG4gICAgICBtYWluTG9vcE1vZGVsICE9PSBwcmV2aW91c1N0YXRlUmVmLmN1cnJlbnQubWFpbkxvb3BNb2RlbFxuICAgICkge1xuICAgICAgLy8gRG9uJ3QgdXBkYXRlIG1lc3NhZ2VJZCBoZXJlIOKAlCBsZXQgZG9VcGRhdGUgaGFuZGxlIGl0IHNvXG4gICAgICAvLyBleGNlZWRzMjAwa1Rva2VucyBpcyByZWNhbGN1bGF0ZWQgd2l0aCB0aGUgbGF0ZXN0IG1lc3NhZ2VzXG4gICAgICBwcmV2aW91c1N0YXRlUmVmLmN1cnJlbnQucGVybWlzc2lvbk1vZGUgPSBwZXJtaXNzaW9uTW9kZVxuICAgICAgcHJldmlvdXNTdGF0ZVJlZi5jdXJyZW50LnZpbU1vZGUgPSB2aW1Nb2RlXG4gICAgICBwcmV2aW91c1N0YXRlUmVmLmN1cnJlbnQubWFpbkxvb3BNb2RlbCA9IG1haW5Mb29wTW9kZWxcbiAgICAgIHNjaGVkdWxlVXBkYXRlKClcbiAgICB9XG4gIH0sIFtcbiAgICBsYXN0QXNzaXN0YW50TWVzc2FnZUlkLFxuICAgIHBlcm1pc3Npb25Nb2RlLFxuICAgIHZpbU1vZGUsXG4gICAgbWFpbkxvb3BNb2RlbCxcbiAgICBzY2hlZHVsZVVwZGF0ZSxcbiAgXSlcblxuICAvLyBXaGVuIHRoZSBzdGF0dXNMaW5lIGNvbW1hbmQgY2hhbmdlcyAoaG90IHJlbG9hZCksIGxvZyB0aGUgbmV4dCByZXN1bHRcbiAgY29uc3Qgc3RhdHVzTGluZUNvbW1hbmQgPSBzZXR0aW5ncz8uc3RhdHVzTGluZT8uY29tbWFuZFxuICBjb25zdCBpc0ZpcnN0U2V0dGluZ3NSZW5kZXIgPSB1c2VSZWYodHJ1ZSlcbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBpZiAoaXNGaXJzdFNldHRpbmdzUmVuZGVyLmN1cnJlbnQpIHtcbiAgICAgIGlzRmlyc3RTZXR0aW5nc1JlbmRlci5jdXJyZW50ID0gZmFsc2VcbiAgICAgIHJldHVyblxuICAgIH1cbiAgICBsb2dOZXh0UmVzdWx0UmVmLmN1cnJlbnQgPSB0cnVlXG4gICAgdm9pZCBkb1VwZGF0ZSgpXG4gIH0sIFtzdGF0dXNMaW5lQ29tbWFuZCwgZG9VcGRhdGVdKVxuXG4gIC8vIFNlcGFyYXRlIGVmZmVjdCBmb3IgbG9nZ2luZyBvbiBtb3VudFxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGNvbnN0IHN0YXR1c0xpbmUgPSBzZXR0aW5ncz8uc3RhdHVzTGluZVxuICAgIGlmIChzdGF0dXNMaW5lKSB7XG4gICAgICBsb2dFdmVudCgndGVuZ3Vfc3RhdHVzX2xpbmVfbW91bnQnLCB7XG4gICAgICAgIGNvbW1hbmRfbGVuZ3RoOiBzdGF0dXNMaW5lLmNvbW1hbmQubGVuZ3RoLFxuICAgICAgICBwYWRkaW5nOiBzdGF0dXNMaW5lLnBhZGRpbmcsXG4gICAgICB9KVxuICAgICAgLy8gTG9nIGlmIHN0YXR1cyBsaW5lIGlzIGNvbmZpZ3VyZWQgYnV0IGRpc2FibGVkIGJ5IGRpc2FibGVBbGxIb29rc1xuICAgICAgaWYgKHNldHRpbmdzLmRpc2FibGVBbGxIb29rcyA9PT0gdHJ1ZSkge1xuICAgICAgICBsb2dGb3JEZWJ1Z2dpbmcoXG4gICAgICAgICAgJ1N0YXR1cyBsaW5lIGlzIGNvbmZpZ3VyZWQgYnV0IGRpc2FibGVBbGxIb29rcyBpcyB0cnVlJyxcbiAgICAgICAgICB7IGxldmVsOiAnd2FybicgfSxcbiAgICAgICAgKVxuICAgICAgfVxuICAgICAgLy8gZXhlY3V0ZVN0YXR1c0xpbmVDb21tYW5kIChob29rcy50cykgcmV0dXJucyB1bmRlZmluZWQgd2hlbiB0cnVzdCBpc1xuICAgICAgLy8gYmxvY2tlZCDigJQgc3RhdHVzTGluZVRleHQgc3RheXMgdW5kZWZpbmVkIGZvcmV2ZXIsIHVzZXIgc2VlcyBub3RoaW5nLFxuICAgICAgLy8gYW5kIHRlbmd1X3N0YXR1c19saW5lX21vdW50IGFib3ZlIGZpcmVzIGFueXdheSBzbyB0ZWxlbWV0cnkgbG9va3MgZmluZS5cbiAgICAgIGlmICghY2hlY2tIYXNUcnVzdERpYWxvZ0FjY2VwdGVkKCkpIHtcbiAgICAgICAgYWRkTm90aWZpY2F0aW9uKHtcbiAgICAgICAgICBrZXk6ICdzdGF0dXNsaW5lLXRydXN0LWJsb2NrZWQnLFxuICAgICAgICAgIHRleHQ6ICdzdGF0dXNsaW5lIHNraXBwZWQgwrcgcmVzdGFydCB0byBmaXgnLFxuICAgICAgICAgIGNvbG9yOiAnd2FybmluZycsXG4gICAgICAgICAgcHJpb3JpdHk6ICdsb3cnLFxuICAgICAgICB9KVxuICAgICAgICBsb2dGb3JEZWJ1Z2dpbmcoXG4gICAgICAgICAgJ1N0YXR1cyBsaW5lIGNvbW1hbmQgc2tpcHBlZDogd29ya3NwYWNlIHRydXN0IG5vdCBhY2NlcHRlZCcsXG4gICAgICAgICAgeyBsZXZlbDogJ3dhcm4nIH0sXG4gICAgICAgIClcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHJlYWN0LWhvb2tzL2V4aGF1c3RpdmUtZGVwc1xuICAgIC8vIGJpb21lLWlnbm9yZSBsaW50L2NvcnJlY3RuZXNzL3VzZUV4aGF1c3RpdmVEZXBlbmRlbmNpZXM6IGludGVudGlvbmFsXG4gIH0sIFtdKSAvLyBPbmx5IHJ1biBvbmNlIG9uIG1vdW50IC0gc2V0dGluZ3Mgc3RhYmxlIGZvciBpbml0aWFsIGxvZ2dpbmdcblxuICAvLyBJbml0aWFsIHVwZGF0ZSBvbiBtb3VudCArIGNsZWFudXAgb24gdW5tb3VudFxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIHZvaWQgZG9VcGRhdGUoKVxuXG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIGFib3J0Q29udHJvbGxlclJlZi5jdXJyZW50Py5hYm9ydCgpXG4gICAgICBpZiAoZGVib3VuY2VUaW1lclJlZi5jdXJyZW50ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgY2xlYXJUaW1lb3V0KGRlYm91bmNlVGltZXJSZWYuY3VycmVudClcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHJlYWN0LWhvb2tzL2V4aGF1c3RpdmUtZGVwc1xuICAgIC8vIGJpb21lLWlnbm9yZSBsaW50L2NvcnJlY3RuZXNzL3VzZUV4aGF1c3RpdmVEZXBlbmRlbmNpZXM6IGludGVudGlvbmFsXG4gIH0sIFtdKSAvLyBPbmx5IHJ1biBvbmNlIG9uIG1vdW50LCBub3Qgd2hlbiBkb1VwZGF0ZSBjaGFuZ2VzXG5cbiAgLy8gR2V0IHBhZGRpbmcgZnJvbSBzZXR0aW5ncyBvciBkZWZhdWx0IHRvIDBcbiAgY29uc3QgcGFkZGluZ1ggPSBzZXR0aW5ncz8uc3RhdHVzTGluZT8ucGFkZGluZyA/PyAwXG5cbiAgLy8gU3RhdHVzTGluZSBtdXN0IGhhdmUgc3RhYmxlIGhlaWdodCBpbiBmdWxsc2NyZWVuIOKAlCB0aGUgZm9vdGVyIGlzXG4gIC8vIGZsZXhTaHJpbms6MCBzbyBhIDDihpIxIHJvdyBjaGFuZ2Ugd2hlbiB0aGUgY29tbWFuZCBmaW5pc2hlcyBzdGVhbHNcbiAgLy8gYSByb3cgZnJvbSBTY3JvbGxCb3ggYW5kIHNoaWZ0cyBjb250ZW50LiBSZXNlcnZlIHRoZSByb3cgd2hpbGUgbG9hZGluZ1xuICAvLyAoc2FtZSB0cmljayBhcyBQcm9tcHRJbnB1dEZvb3RlckxlZnRTaWRlKS5cbiAgcmV0dXJuIChcbiAgICA8Qm94IHBhZGRpbmdYPXtwYWRkaW5nWH0gZ2FwPXsyfT5cbiAgICAgIHtzdGF0dXNMaW5lVGV4dCA/IChcbiAgICAgICAgPFRleHQgZGltQ29sb3Igd3JhcD1cInRydW5jYXRlXCI+XG4gICAgICAgICAgPEFuc2k+e3N0YXR1c0xpbmVUZXh0fTwvQW5zaT5cbiAgICAgICAgPC9UZXh0PlxuICAgICAgKSA6IGlzRnVsbHNjcmVlbkVudkVuYWJsZWQoKSA/IChcbiAgICAgICAgPFRleHQ+IDwvVGV4dD5cbiAgICAgICkgOiBudWxsfVxuICAgIDwvQm94PlxuICApXG59XG5cbi8vIFBhcmVudCAoUHJvbXB0SW5wdXRGb290ZXIpIHJlLXJlbmRlcnMgb24gZXZlcnkgc2V0TWVzc2FnZXMsIGJ1dCBTdGF0dXNMaW5lJ3Ncbi8vIG93biBwcm9wcyBub3cgb25seSBjaGFuZ2Ugd2hlbiBsYXN0QXNzaXN0YW50TWVzc2FnZUlkIGZsaXBzIOKAlCBtZW1vIGtlZXBzIGl0XG4vLyBmcm9tIGJlaW5nIGRyYWdnZWQgYWxvbmcgKHByZXZpb3VzbHkgfjE4IG5vLXByb3AtY2hhbmdlIHJlbmRlcnMgcGVyIHNlc3Npb24pLlxuZXhwb3J0IGNvbnN0IFN0YXR1c0xpbmUgPSBtZW1vKFN0YXR1c0xpbmVJbm5lcilcbiJdLCJtYXBwaW5ncyI6IkFBQUEsU0FBU0EsT0FBTyxRQUFRLFlBQVk7QUFDcEMsT0FBTyxLQUFLQyxLQUFLLE1BQU0sT0FBTztBQUM5QixTQUFTQyxJQUFJLEVBQUVDLFdBQVcsRUFBRUMsU0FBUyxFQUFFQyxNQUFNLFFBQVEsT0FBTztBQUM1RCxTQUFTQyxRQUFRLFFBQVEsaUNBQWlDO0FBQzFELFNBQVNDLFdBQVcsRUFBRUMsY0FBYyxRQUFRLHVCQUF1QjtBQUNuRSxjQUFjQyxjQUFjLFFBQVEseUNBQXlDO0FBQzdFLFNBQ0VDLGVBQWUsRUFDZkMsZUFBZSxFQUNmQyxzQkFBc0IsRUFDdEJDLGNBQWMsRUFDZEMsV0FBVyxFQUNYQyxZQUFZLFFBQ1AsdUJBQXVCO0FBQzlCLFNBQVNDLHlCQUF5QixRQUFRLDhCQUE4QjtBQUN4RSxTQUFTQyxnQkFBZ0IsUUFBUSw2QkFBNkI7QUFDOUQsU0FDRUMsbUJBQW1CLEVBQ25CQyxZQUFZLEVBQ1pDLGdCQUFnQixFQUNoQkMsbUJBQW1CLEVBQ25CQyxrQkFBa0IsRUFDbEJDLG9CQUFvQixFQUNwQkMsb0JBQW9CLFFBQ2Ysb0JBQW9CO0FBQzNCLFNBQVNDLGdCQUFnQixRQUFRLDhCQUE4QjtBQUMvRCxTQUFTLEtBQUtDLGdCQUFnQixFQUFFQyxXQUFXLFFBQVEseUJBQXlCO0FBQzVFLFNBQVNDLElBQUksRUFBRUMsR0FBRyxFQUFFQyxJQUFJLFFBQVEsV0FBVztBQUMzQyxTQUFTQyxpQkFBaUIsUUFBUSwrQkFBK0I7QUFDakUsY0FBY0MsT0FBTyxRQUFRLHFCQUFxQjtBQUNsRCxjQUFjQyxzQkFBc0IsUUFBUSx3QkFBd0I7QUFDcEUsY0FBY0MsT0FBTyxRQUFRLDRCQUE0QjtBQUN6RCxTQUFTQywyQkFBMkIsUUFBUSxvQkFBb0I7QUFDaEUsU0FDRUMsMkJBQTJCLEVBQzNCQyx3QkFBd0IsUUFDbkIscUJBQXFC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 \ No newline at end of file +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJmZWF0dXJlIiwiUmVhY3QiLCJtZW1vIiwidXNlQ2FsbGJhY2siLCJ1c2VFZmZlY3QiLCJ1c2VSZWYiLCJsb2dFdmVudCIsInVzZUFwcFN0YXRlIiwidXNlU2V0QXBwU3RhdGUiLCJQZXJtaXNzaW9uTW9kZSIsImdldElzUmVtb3RlTW9kZSIsImdldEthaXJvc0FjdGl2ZSIsImdldE1haW5UaHJlYWRBZ2VudFR5cGUiLCJnZXRPcmlnaW5hbEN3ZCIsImdldFNka0JldGFzIiwiZ2V0U2Vzc2lvbklkIiwiREVGQVVMVF9PVVRQVVRfU1RZTEVfTkFNRSIsInVzZU5vdGlmaWNhdGlvbnMiLCJnZXRUb3RhbEFQSUR1cmF0aW9uIiwiZ2V0VG90YWxDb3N0IiwiZ2V0VG90YWxEdXJhdGlvbiIsImdldFRvdGFsSW5wdXRUb2tlbnMiLCJnZXRUb3RhbExpbmVzQWRkZWQiLCJnZXRUb3RhbExpbmVzUmVtb3ZlZCIsImdldFRvdGFsT3V0cHV0VG9rZW5zIiwidXNlTWFpbkxvb3BNb2RlbCIsIlJlYWRvbmx5U2V0dGluZ3MiLCJ1c2VTZXR0aW5ncyIsIkFuc2kiLCJCb3giLCJUZXh0IiwiZ2V0UmF3VXRpbGl6YXRpb24iLCJNZXNzYWdlIiwiU3RhdHVzTGluZUNvbW1hbmRJbnB1dCIsIlZpbU1vZGUiLCJjaGVja0hhc1RydXN0RGlhbG9nQWNjZXB0ZWQiLCJjYWxjdWxhdGVDb250ZXh0UGVyY2VudGFnZXMiLCJnZXRDb250ZXh0V2luZG93Rm9yTW9kZWwiLCJnZXRDd2QiLCJsb2dGb3JEZWJ1Z2dpbmciLCJpc0Z1bGxzY3JlZW5FbnZFbmFibGVkIiwiY3JlYXRlQmFzZUhvb2tJbnB1dCIsImV4ZWN1dGVTdGF0dXNMaW5lQ29tbWFuZCIsImdldExhc3RBc3Npc3RhbnRNZXNzYWdlIiwiZ2V0UnVudGltZU1haW5Mb29wTW9kZWwiLCJNb2RlbE5hbWUiLCJyZW5kZXJNb2RlbE5hbWUiLCJnZXRDdXJyZW50U2Vzc2lvblRpdGxlIiwiZG9lc01vc3RSZWNlbnRBc3Npc3RhbnRNZXNzYWdlRXhjZWVkMjAwayIsImdldEN1cnJlbnRVc2FnZSIsImdldEN1cnJlbnRXb3JrdHJlZVNlc3Npb24iLCJpc1ZpbU1vZGVFbmFibGVkIiwic3RhdHVzTGluZVNob3VsZERpc3BsYXkiLCJzZXR0aW5ncyIsInN0YXR1c0xpbmUiLCJ1bmRlZmluZWQiLCJidWlsZFN0YXR1c0xpbmVDb21tYW5kSW5wdXQiLCJwZXJtaXNzaW9uTW9kZSIsImV4Y2VlZHMyMDBrVG9rZW5zIiwibWVzc2FnZXMiLCJhZGRlZERpcnMiLCJtYWluTG9vcE1vZGVsIiwidmltTW9kZSIsImFnZW50VHlwZSIsIndvcmt0cmVlU2Vzc2lvbiIsInJ1bnRpbWVNb2RlbCIsIm91dHB1dFN0eWxlTmFtZSIsIm91dHB1dFN0eWxlIiwiY3VycmVudFVzYWdlIiwiY29udGV4dFdpbmRvd1NpemUiLCJjb250ZXh0UGVyY2VudGFnZXMiLCJzZXNzaW9uSWQiLCJzZXNzaW9uTmFtZSIsInJhd1V0aWwiLCJyYXRlTGltaXRzIiwiZml2ZV9ob3VyIiwidXNlZF9wZXJjZW50YWdlIiwidXRpbGl6YXRpb24iLCJyZXNldHNfYXQiLCJzZXZlbl9kYXkiLCJzZXNzaW9uX25hbWUiLCJtb2RlbCIsImlkIiwiZGlzcGxheV9uYW1lIiwid29ya3NwYWNlIiwiY3VycmVudF9kaXIiLCJwcm9qZWN0X2RpciIsImFkZGVkX2RpcnMiLCJ2ZXJzaW9uIiwiTUFDUk8iLCJWRVJTSU9OIiwib3V0cHV0X3N0eWxlIiwibmFtZSIsImNvc3QiLCJ0b3RhbF9jb3N0X3VzZCIsInRvdGFsX2R1cmF0aW9uX21zIiwidG90YWxfYXBpX2R1cmF0aW9uX21zIiwidG90YWxfbGluZXNfYWRkZWQiLCJ0b3RhbF9saW5lc19yZW1vdmVkIiwiY29udGV4dF93aW5kb3ciLCJ0b3RhbF9pbnB1dF90b2tlbnMiLCJ0b3RhbF9vdXRwdXRfdG9rZW5zIiwiY29udGV4dF93aW5kb3dfc2l6ZSIsImN1cnJlbnRfdXNhZ2UiLCJ1c2VkIiwicmVtYWluaW5nX3BlcmNlbnRhZ2UiLCJyZW1haW5pbmciLCJleGNlZWRzXzIwMGtfdG9rZW5zIiwicmF0ZV9saW1pdHMiLCJ2aW0iLCJtb2RlIiwiYWdlbnQiLCJyZW1vdGUiLCJzZXNzaW9uX2lkIiwid29ya3RyZWUiLCJ3b3JrdHJlZU5hbWUiLCJwYXRoIiwid29ya3RyZWVQYXRoIiwiYnJhbmNoIiwid29ya3RyZWVCcmFuY2giLCJvcmlnaW5hbF9jd2QiLCJvcmlnaW5hbEN3ZCIsIm9yaWdpbmFsX2JyYW5jaCIsIm9yaWdpbmFsQnJhbmNoIiwiUHJvcHMiLCJtZXNzYWdlc1JlZiIsIlJlZk9iamVjdCIsImxhc3RBc3Npc3RhbnRNZXNzYWdlSWQiLCJnZXRMYXN0QXNzaXN0YW50TWVzc2FnZUlkIiwidXVpZCIsIlN0YXR1c0xpbmVJbm5lciIsIlJlYWN0Tm9kZSIsImFib3J0Q29udHJvbGxlclJlZiIsIkFib3J0Q29udHJvbGxlciIsInMiLCJ0b29sUGVybWlzc2lvbkNvbnRleHQiLCJhZGRpdGlvbmFsV29ya2luZ0RpcmVjdG9yaWVzIiwic3RhdHVzTGluZVRleHQiLCJzZXRBcHBTdGF0ZSIsImFkZE5vdGlmaWNhdGlvbiIsInNldHRpbmdzUmVmIiwiY3VycmVudCIsInZpbU1vZGVSZWYiLCJwZXJtaXNzaW9uTW9kZVJlZiIsImFkZGVkRGlyc1JlZiIsIm1haW5Mb29wTW9kZWxSZWYiLCJwcmV2aW91c1N0YXRlUmVmIiwibWVzc2FnZUlkIiwiZGVib3VuY2VUaW1lclJlZiIsIlJldHVyblR5cGUiLCJzZXRUaW1lb3V0IiwibG9nTmV4dFJlc3VsdFJlZiIsImRvVXBkYXRlIiwiYWJvcnQiLCJjb250cm9sbGVyIiwibXNncyIsImxvZ1Jlc3VsdCIsImN1cnJlbnRNZXNzYWdlSWQiLCJzdGF0dXNJbnB1dCIsIkFycmF5IiwiZnJvbSIsImtleXMiLCJ0ZXh0Iiwic2lnbmFsIiwiYWJvcnRlZCIsInByZXYiLCJzY2hlZHVsZVVwZGF0ZSIsImNsZWFyVGltZW91dCIsInJlZiIsInN0YXR1c0xpbmVDb21tYW5kIiwiY29tbWFuZCIsImlzRmlyc3RTZXR0aW5nc1JlbmRlciIsImNvbW1hbmRfbGVuZ3RoIiwibGVuZ3RoIiwicGFkZGluZyIsImRpc2FibGVBbGxIb29rcyIsImxldmVsIiwia2V5IiwiY29sb3IiLCJwcmlvcml0eSIsInBhZGRpbmdYIiwiU3RhdHVzTGluZSJdLCJzb3VyY2VzIjpbIlN0YXR1c0xpbmUudHN4Il0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGZlYXR1cmUgfSBmcm9tICdidW46YnVuZGxlJ1xuaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnXG5pbXBvcnQgeyBtZW1vLCB1c2VDYWxsYmFjaywgdXNlRWZmZWN0LCB1c2VSZWYgfSBmcm9tICdyZWFjdCdcbmltcG9ydCB7IGxvZ0V2ZW50IH0gZnJvbSAnc3JjL3NlcnZpY2VzL2FuYWx5dGljcy9pbmRleC5qcydcbmltcG9ydCB7IHVzZUFwcFN0YXRlLCB1c2VTZXRBcHBTdGF0ZSB9IGZyb20gJ3NyYy9zdGF0ZS9BcHBTdGF0ZS5qcydcbmltcG9ydCB0eXBlIHsgUGVybWlzc2lvbk1vZGUgfSBmcm9tICdzcmMvdXRpbHMvcGVybWlzc2lvbnMvUGVybWlzc2lvbk1vZGUuanMnXG5pbXBvcnQge1xuICBnZXRJc1JlbW90ZU1vZGUsXG4gIGdldEthaXJvc0FjdGl2ZSxcbiAgZ2V0TWFpblRocmVhZEFnZW50VHlwZSxcbiAgZ2V0T3JpZ2luYWxDd2QsXG4gIGdldFNka0JldGFzLFxuICBnZXRTZXNzaW9uSWQsXG59IGZyb20gJy4uL2Jvb3RzdHJhcC9zdGF0ZS5qcydcbmltcG9ydCB7IERFRkFVTFRfT1VUUFVUX1NUWUxFX05BTUUgfSBmcm9tICcuLi9jb25zdGFudHMvb3V0cHV0U3R5bGVzLmpzJ1xuaW1wb3J0IHsgdXNlTm90aWZpY2F0aW9ucyB9IGZyb20gJy4uL2NvbnRleHQvbm90aWZpY2F0aW9ucy5qcydcbmltcG9ydCB7XG4gIGdldFRvdGFsQVBJRHVyYXRpb24sXG4gIGdldFRvdGFsQ29zdCxcbiAgZ2V0VG90YWxEdXJhdGlvbixcbiAgZ2V0VG90YWxJbnB1dFRva2VucyxcbiAgZ2V0VG90YWxMaW5lc0FkZGVkLFxuICBnZXRUb3RhbExpbmVzUmVtb3ZlZCxcbiAgZ2V0VG90YWxPdXRwdXRUb2tlbnMsXG59IGZyb20gJy4uL2Nvc3QtdHJhY2tlci5qcydcbmltcG9ydCB7IHVzZU1haW5Mb29wTW9kZWwgfSBmcm9tICcuLi9ob29rcy91c2VNYWluTG9vcE1vZGVsLmpzJ1xuaW1wb3J0IHsgdHlwZSBSZWFkb25seVNldHRpbmdzLCB1c2VTZXR0aW5ncyB9IGZyb20gJy4uL2hvb2tzL3VzZVNldHRpbmdzLmpzJ1xuaW1wb3J0IHsgQW5zaSwgQm94LCBUZXh0IH0gZnJvbSAnLi4vaW5rLmpzJ1xuaW1wb3J0IHsgZ2V0UmF3VXRpbGl6YXRpb24gfSBmcm9tICcuLi9zZXJ2aWNlcy9jbGF1ZGVBaUxpbWl0cy5qcydcbmltcG9ydCB0eXBlIHsgTWVzc2FnZSB9IGZyb20gJy4uL3R5cGVzL21lc3NhZ2UuanMnXG5pbXBvcnQgdHlwZSB7IFN0YXR1c0xpbmVDb21tYW5kSW5wdXQgfSBmcm9tICcuLi90eXBlcy9zdGF0dXNMaW5lLmpzJ1xuaW1wb3J0IHR5cGUgeyBWaW1Nb2RlIH0gZnJvbSAnLi4vdHlwZXMvdGV4dElucHV0VHlwZXMuanMnXG5pbXBvcnQgeyBjaGVja0hhc1RydXN0RGlhbG9nQWNjZXB0ZWQgfSBmcm9tICcuLi91dGlscy9jb25maWcuanMnXG5pbXBvcnQge1xuICBjYWxjdWxhdGVDb250ZXh0UGVyY2VudGFnZXMsXG4gIGdldENvbnRleHRXaW5kb3dGb3JNb2RlbCxcbn0gZnJvbSAnLi4vdXRpbHMvY29udGV4dC5qcydcbmltcG9ydCB7IGdldEN3ZCB9IGZyb20gJy4uL3V0aWxzL2N3ZC5qcydcbmltcG9ydCB7IGxvZ0ZvckRlYnVnZ2luZyB9IGZyb20gJy4uL3V0aWxzL2RlYnVnLmpzJ1xuaW1wb3J0IHsgaXNGdWxsc2NyZWVuRW52RW5hYmxlZCB9IGZyb20gJy4uL3V0aWxzL2Z1bGxzY3JlZW4uanMnXG5pbXBvcnQge1xuICBjcmVhdGVCYXNlSG9va0lucHV0LFxuICBleGVjdXRlU3RhdHVzTGluZUNvbW1hbmQsXG59IGZyb20gJy4uL3V0aWxzL2hvb2tzLmpzJ1xuaW1wb3J0IHsgZ2V0TGFzdEFzc2lzdGFudE1lc3NhZ2UgfSBmcm9tICcuLi91dGlscy9tZXNzYWdlcy5qcydcbmltcG9ydCB7XG4gIGdldFJ1bnRpbWVNYWluTG9vcE1vZGVsLFxuICB0eXBlIE1vZGVsTmFtZSxcbiAgcmVuZGVyTW9kZWxOYW1lLFxufSBmcm9tICcuLi91dGlscy9tb2RlbC9tb2RlbC5qcydcbmltcG9ydCB7IGdldEN1cnJlbnRTZXNzaW9uVGl0bGUgfSBmcm9tICcuLi91dGlscy9zZXNzaW9uU3RvcmFnZS5qcydcbmltcG9ydCB7XG4gIGRvZXNNb3N0UmVjZW50QXNzaXN0YW50TWVzc2FnZUV4Y2VlZDIwMGssXG4gIGdldEN1cnJlbnRVc2FnZSxcbn0gZnJvbSAnLi4vdXRpbHMvdG9rZW5zLmpzJ1xuaW1wb3J0IHsgZ2V0Q3VycmVudFdvcmt0cmVlU2Vzc2lvbiB9IGZyb20gJy4uL3V0aWxzL3dvcmt0cmVlLmpzJ1xuaW1wb3J0IHsgaXNWaW1Nb2RlRW5hYmxlZCB9IGZyb20gJy4vUHJvbXB0SW5wdXQvdXRpbHMuanMnXG5cbmV4cG9ydCBmdW5jdGlvbiBzdGF0dXNMaW5lU2hvdWxkRGlzcGxheShzZXR0aW5nczogUmVhZG9ubHlTZXR0aW5ncyk6IGJvb2xlYW4ge1xuICAvLyBBc3Npc3RhbnQgbW9kZTogc3RhdHVzbGluZSBmaWVsZHMgKG1vZGVsLCBwZXJtaXNzaW9uIG1vZGUsIGN3ZCkgcmVmbGVjdCB0aGVcbiAgLy8gUkVQTC9kYWVtb24gcHJvY2Vzcywgbm90IHdoYXQgdGhlIGFnZW50IGNoaWxkIGlzIGFjdHVhbGx5IHJ1bm5pbmcuIEhpZGUgaXQuXG4gIGlmIChmZWF0dXJlKCdLQUlST1MnKSAmJiBnZXRLYWlyb3NBY3RpdmUoKSkgcmV0dXJuIGZhbHNlXG4gIHJldHVybiBzZXR0aW5ncz8uc3RhdHVzTGluZSAhPT0gdW5kZWZpbmVkXG59XG5cbmZ1bmN0aW9uIGJ1aWxkU3RhdHVzTGluZUNvbW1hbmRJbnB1dChcbiAgcGVybWlzc2lvbk1vZGU6IFBlcm1pc3Npb25Nb2RlLFxuICBleGNlZWRzMjAwa1Rva2VuczogYm9vbGVhbixcbiAgc2V0dGluZ3M6IFJlYWRvbmx5U2V0dGluZ3MsXG4gIG1lc3NhZ2VzOiBNZXNzYWdlW10sXG4gIGFkZGVkRGlyczogc3RyaW5nW10sXG4gIG1haW5Mb29wTW9kZWw6IE1vZGVsTmFtZSxcbiAgdmltTW9kZT86IFZpbU1vZGUsXG4pOiBTdGF0dXNMaW5lQ29tbWFuZElucHV0IHtcbiAgY29uc3QgYWdlbnRUeXBlID0gZ2V0TWFpblRocmVhZEFnZW50VHlwZSgpXG4gIGNvbnN0IHdvcmt0cmVlU2Vzc2lvbiA9IGdldEN1cnJlbnRXb3JrdHJlZVNlc3Npb24oKVxuICBjb25zdCBydW50aW1lTW9kZWwgPSBnZXRSdW50aW1lTWFpbkxvb3BNb2RlbCh7XG4gICAgcGVybWlzc2lvbk1vZGUsXG4gICAgbWFpbkxvb3BNb2RlbCxcbiAgICBleGNlZWRzMjAwa1Rva2VucyxcbiAgfSlcbiAgY29uc3Qgb3V0cHV0U3R5bGVOYW1lID0gc2V0dGluZ3M/Lm91dHB1dFN0eWxlIHx8IERFRkFVTFRfT1VUUFVUX1NUWUxFX05BTUVcblxuICBjb25zdCBjdXJyZW50VXNhZ2UgPSBnZXRDdXJyZW50VXNhZ2UobWVzc2FnZXMpXG4gIGNvbnN0IGNvbnRleHRXaW5kb3dTaXplID0gZ2V0Q29udGV4dFdpbmRvd0Zvck1vZGVsKFxuICAgIHJ1bnRpbWVNb2RlbCxcbiAgICBnZXRTZGtCZXRhcygpLFxuICApXG4gIGNvbnN0IGNvbnRleHRQZXJjZW50YWdlcyA9IGNhbGN1bGF0ZUNvbnRleHRQZXJjZW50YWdlcyhcbiAgICBjdXJyZW50VXNhZ2UsXG4gICAgY29udGV4dFdpbmRvd1NpemUsXG4gIClcblxuICBjb25zdCBzZXNzaW9uSWQgPSBnZXRTZXNzaW9uSWQoKVxuICBjb25zdCBzZXNzaW9uTmFtZSA9IGdldEN1cnJlbnRTZXNzaW9uVGl0bGUoc2Vzc2lvbklkKVxuICBjb25zdCByYXdVdGlsID0gZ2V0UmF3VXRpbGl6YXRpb24oKVxuICBjb25zdCByYXRlTGltaXRzOiBTdGF0dXNMaW5lQ29tbWFuZElucHV0WydyYXRlX2xpbWl0cyddID0ge1xuICAgIC4uLihyYXdVdGlsLmZpdmVfaG91ciAmJiB7XG4gICAgICBmaXZlX2hvdXI6IHtcbiAgICAgICAgdXNlZF9wZXJjZW50YWdlOiByYXdVdGlsLmZpdmVfaG91ci51dGlsaXphdGlvbiAqIDEwMCxcbiAgICAgICAgcmVzZXRzX2F0OiByYXdVdGlsLmZpdmVfaG91ci5yZXNldHNfYXQsXG4gICAgICB9LFxuICAgIH0pLFxuICAgIC4uLihyYXdVdGlsLnNldmVuX2RheSAmJiB7XG4gICAgICBzZXZlbl9kYXk6IHtcbiAgICAgICAgdXNlZF9wZXJjZW50YWdlOiByYXdVdGlsLnNldmVuX2RheS51dGlsaXphdGlvbiAqIDEwMCxcbiAgICAgICAgcmVzZXRzX2F0OiByYXdVdGlsLnNldmVuX2RheS5yZXNldHNfYXQsXG4gICAgICB9LFxuICAgIH0pLFxuICB9XG4gIHJldHVybiB7XG4gICAgLi4uY3JlYXRlQmFzZUhvb2tJbnB1dCgpLFxuICAgIC4uLihzZXNzaW9uTmFtZSAmJiB7IHNlc3Npb25fbmFtZTogc2Vzc2lvbk5hbWUgfSksXG4gICAgbW9kZWw6IHtcbiAgICAgIGlkOiBydW50aW1lTW9kZWwsXG4gICAgICBkaXNwbGF5X25hbWU6IHJlbmRlck1vZGVsTmFtZShydW50aW1lTW9kZWwpLFxuICAgIH0sXG4gICAgd29ya3NwYWNlOiB7XG4gICAgICBjdXJyZW50X2RpcjogZ2V0Q3dkKCksXG4gICAgICBwcm9qZWN0X2RpcjogZ2V0T3JpZ2luYWxDd2QoKSxcbiAgICAgIGFkZGVkX2RpcnM6IGFkZGVkRGlycyxcbiAgICB9LFxuICAgIHZlcnNpb246IE1BQ1JPLlZFUlNJT04sXG4gICAgb3V0cHV0X3N0eWxlOiB7XG4gICAgICBuYW1lOiBvdXRwdXRTdHlsZU5hbWUsXG4gICAgfSxcbiAgICBjb3N0OiB7XG4gICAgICB0b3RhbF9jb3N0X3VzZDogZ2V0VG90YWxDb3N0KCksXG4gICAgICB0b3RhbF9kdXJhdGlvbl9tczogZ2V0VG90YWxEdXJhdGlvbigpLFxuICAgICAgdG90YWxfYXBpX2R1cmF0aW9uX21zOiBnZXRUb3RhbEFQSUR1cmF0aW9uKCksXG4gICAgICB0b3RhbF9saW5lc19hZGRlZDogZ2V0VG90YWxMaW5lc0FkZGVkKCksXG4gICAgICB0b3RhbF9saW5lc19yZW1vdmVkOiBnZXRUb3RhbExpbmVzUmVtb3ZlZCgpLFxuICAgIH0sXG4gICAgY29udGV4dF93aW5kb3c6IHtcbiAgICAgIHRvdGFsX2lucHV0X3Rva2VuczogZ2V0VG90YWxJbnB1dFRva2VucygpLFxuICAgICAgdG90YWxfb3V0cHV0X3Rva2VuczogZ2V0VG90YWxPdXRwdXRUb2tlbnMoKSxcbiAgICAgIGNvbnRleHRfd2luZG93X3NpemU6IGNvbnRleHRXaW5kb3dTaXplLFxuICAgICAgY3VycmVudF91c2FnZTogY3VycmVudFVzYWdlLFxuICAgICAgdXNlZF9wZXJjZW50YWdlOiBjb250ZXh0UGVyY2VudGFnZXMudXNlZCxcbiAgICAgIHJlbWFpbmluZ19wZXJjZW50YWdlOiBjb250ZXh0UGVyY2VudGFnZXMucmVtYWluaW5nLFxuICAgIH0sXG4gICAgZXhjZWVkc18yMDBrX3Rva2VuczogZXhjZWVkczIwMGtUb2tlbnMsXG4gICAgLi4uKChyYXRlTGltaXRzLmZpdmVfaG91ciB8fCByYXRlTGltaXRzLnNldmVuX2RheSkgJiYge1xuICAgICAgcmF0ZV9saW1pdHM6IHJhdGVMaW1pdHMsXG4gICAgfSksXG4gICAgLi4uKGlzVmltTW9kZUVuYWJsZWQoKSAmJiB7XG4gICAgICB2aW06IHtcbiAgICAgICAgbW9kZTogdmltTW9kZSA/PyAnSU5TRVJUJyxcbiAgICAgIH0sXG4gICAgfSksXG4gICAgLi4uKGFnZW50VHlwZSAmJiB7XG4gICAgICBhZ2VudDoge1xuICAgICAgICBuYW1lOiBhZ2VudFR5cGUsXG4gICAgICB9LFxuICAgIH0pLFxuICAgIC4uLihnZXRJc1JlbW90ZU1vZGUoKSAmJiB7XG4gICAgICByZW1vdGU6IHtcbiAgICAgICAgc2Vzc2lvbl9pZDogZ2V0U2Vzc2lvbklkKCksXG4gICAgICB9LFxuICAgIH0pLFxuICAgIC4uLih3b3JrdHJlZVNlc3Npb24gJiYge1xuICAgICAgd29ya3RyZWU6IHtcbiAgICAgICAgbmFtZTogd29ya3RyZWVTZXNzaW9uLndvcmt0cmVlTmFtZSxcbiAgICAgICAgcGF0aDogd29ya3RyZWVTZXNzaW9uLndvcmt0cmVlUGF0aCxcbiAgICAgICAgYnJhbmNoOiB3b3JrdHJlZVNlc3Npb24ud29ya3RyZWVCcmFuY2gsXG4gICAgICAgIG9yaWdpbmFsX2N3ZDogd29ya3RyZWVTZXNzaW9uLm9yaWdpbmFsQ3dkLFxuICAgICAgICBvcmlnaW5hbF9icmFuY2g6IHdvcmt0cmVlU2Vzc2lvbi5vcmlnaW5hbEJyYW5jaCxcbiAgICAgIH0sXG4gICAgfSksXG4gIH1cbn1cblxudHlwZSBQcm9wcyA9IHtcbiAgLy8gbWVzc2FnZXMgc3RheXMgYmVoaW5kIGEgcmVmIChyZWFkIG9ubHkgaW4gdGhlIGRlYm91bmNlZCBjYWxsYmFjayk7XG4gIC8vIGxhc3RBc3Npc3RhbnRNZXNzYWdlSWQgaXMgdGhlIGFjdHVhbCByZS1yZW5kZXIgdHJpZ2dlci5cbiAgbWVzc2FnZXNSZWY6IFJlYWN0LlJlZk9iamVjdDxNZXNzYWdlW10+XG4gIGxhc3RBc3Npc3RhbnRNZXNzYWdlSWQ6IHN0cmluZyB8IG51bGxcbiAgdmltTW9kZT86IFZpbU1vZGVcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldExhc3RBc3Npc3RhbnRNZXNzYWdlSWQobWVzc2FnZXM6IE1lc3NhZ2VbXSk6IHN0cmluZyB8IG51bGwge1xuICByZXR1cm4gZ2V0TGFzdEFzc2lzdGFudE1lc3NhZ2UobWVzc2FnZXMpPy51dWlkID8/IG51bGxcbn1cblxuZnVuY3Rpb24gU3RhdHVzTGluZUlubmVyKHtcbiAgbWVzc2FnZXNSZWYsXG4gIGxhc3RBc3Npc3RhbnRNZXNzYWdlSWQsXG4gIHZpbU1vZGUsXG59OiBQcm9wcyk6IFJlYWN0LlJlYWN0Tm9kZSB7XG4gIGNvbnN0IGFib3J0Q29udHJvbGxlclJlZiA9IHVzZVJlZjxBYm9ydENvbnRyb2xsZXIgfCB1bmRlZmluZWQ+KHVuZGVmaW5lZClcbiAgY29uc3QgcGVybWlzc2lvbk1vZGUgPSB1c2VBcHBTdGF0ZShzID0+IHMudG9vbFBlcm1pc3Npb25Db250ZXh0Lm1vZGUpXG4gIGNvbnN0IGFkZGl0aW9uYWxXb3JraW5nRGlyZWN0b3JpZXMgPSB1c2VBcHBTdGF0ZShcbiAgICBzID0+IHMudG9vbFBlcm1pc3Npb25Db250ZXh0LmFkZGl0aW9uYWxXb3JraW5nRGlyZWN0b3JpZXMsXG4gIClcbiAgY29uc3Qgc3RhdHVzTGluZVRleHQgPSB1c2VBcHBTdGF0ZShzID0+IHMuc3RhdHVzTGluZVRleHQpXG4gIGNvbnN0IHNldEFwcFN0YXRlID0gdXNlU2V0QXBwU3RhdGUoKVxuICBjb25zdCBzZXR0aW5ncyA9IHVzZVNldHRpbmdzKClcbiAgY29uc3QgeyBhZGROb3RpZmljYXRpb24gfSA9IHVzZU5vdGlmaWNhdGlvbnMoKVxuICAvLyBBcHBTdGF0ZS1zb3VyY2VkIG1vZGVsIOKAlCBzYW1lIHNvdXJjZSBhcyBBUEkgcmVxdWVzdHMuIGdldE1haW5Mb29wTW9kZWwoKVxuICAvLyByZS1yZWFkcyBzZXR0aW5ncy5qc29uIG9uIGV2ZXJ5IGNhbGwsIHNvIGFub3RoZXIgc2Vzc2lvbidzIC9tb2RlbCB3cml0ZVxuICAvLyB3b3VsZCBsZWFrIGludG8gdGhpcyBzZXNzaW9uJ3Mgc3RhdHVzbGluZSAoYW50aHJvcGljcy9jbGF1ZGUtY29kZSMzNzU5NikuXG4gIGNvbnN0IG1haW5Mb29wTW9kZWwgPSB1c2VNYWluTG9vcE1vZGVsKClcblxuICAvLyBLZWVwIGxhdGVzdCB2YWx1ZXMgaW4gcmVmcyBmb3Igc3RhYmxlIGNhbGxiYWNrIGFjY2Vzc1xuICBjb25zdCBzZXR0aW5nc1JlZiA9IHVzZVJlZihzZXR0aW5ncylcbiAgc2V0dGluZ3NSZWYuY3VycmVudCA9IHNldHRpbmdzXG4gIGNvbnN0IHZpbU1vZGVSZWYgPSB1c2VSZWYodmltTW9kZSlcbiAgdmltTW9kZVJlZi5jdXJyZW50ID0gdmltTW9kZVxuICBjb25zdCBwZXJtaXNzaW9uTW9kZVJlZiA9IHVzZVJlZihwZXJtaXNzaW9uTW9kZSlcbiAgcGVybWlzc2lvbk1vZGVSZWYuY3VycmVudCA9IHBlcm1pc3Npb25Nb2RlXG4gIGNvbnN0IGFkZGVkRGlyc1JlZiA9IHVzZVJlZihhZGRpdGlvbmFsV29ya2luZ0RpcmVjdG9yaWVzKVxuICBhZGRlZERpcnNSZWYuY3VycmVudCA9IGFkZGl0aW9uYWxXb3JraW5nRGlyZWN0b3JpZXNcbiAgY29uc3QgbWFpbkxvb3BNb2RlbFJlZiA9IHVzZVJlZihtYWluTG9vcE1vZGVsKVxuICBtYWluTG9vcE1vZGVsUmVmLmN1cnJlbnQgPSBtYWluTG9vcE1vZGVsXG5cbiAgLy8gVHJhY2sgcHJldmlvdXMgc3RhdGUgdG8gZGV0ZWN0IGNoYW5nZXMgYW5kIGNhY2hlIGV4cGVuc2l2ZSBjYWxjdWxhdGlvbnNcbiAgY29uc3QgcHJldmlvdXNTdGF0ZVJlZiA9IHVzZVJlZjx7XG4gICAgbWVzc2FnZUlkOiBzdHJpbmcgfCBudWxsXG4gICAgZXhjZWVkczIwMGtUb2tlbnM6IGJvb2xlYW5cbiAgICBwZXJtaXNzaW9uTW9kZTogUGVybWlzc2lvbk1vZGVcbiAgICB2aW1Nb2RlOiBWaW1Nb2RlIHwgdW5kZWZpbmVkXG4gICAgbWFpbkxvb3BNb2RlbDogTW9kZWxOYW1lXG4gIH0+KHtcbiAgICBtZXNzYWdlSWQ6IG51bGwsXG4gICAgZXhjZWVkczIwMGtUb2tlbnM6IGZhbHNlLFxuICAgIHBlcm1pc3Npb25Nb2RlLFxuICAgIHZpbU1vZGUsXG4gICAgbWFpbkxvb3BNb2RlbCxcbiAgfSlcblxuICAvLyBEZWJvdW5jZSB0aW1lciByZWZcbiAgY29uc3QgZGVib3VuY2VUaW1lclJlZiA9IHVzZVJlZjxSZXR1cm5UeXBlPHR5cGVvZiBzZXRUaW1lb3V0PiB8IHVuZGVmaW5lZD4oXG4gICAgdW5kZWZpbmVkLFxuICApXG5cbiAgLy8gVHJ1ZSB3aGVuIHRoZSBuZXh0IGludm9jYXRpb24gc2hvdWxkIGxvZyBpdHMgcmVzdWx0IChmaXJzdCBydW4gb3IgYWZ0ZXIgc2V0dGluZ3MgcmVsb2FkKVxuICBjb25zdCBsb2dOZXh0UmVzdWx0UmVmID0gdXNlUmVmKHRydWUpXG5cbiAgLy8gU3RhYmxlIHVwZGF0ZSBmdW5jdGlvbiDigJQgcmVhZHMgbGF0ZXN0IHZhbHVlcyBmcm9tIHJlZnNcbiAgY29uc3QgZG9VcGRhdGUgPSB1c2VDYWxsYmFjayhhc3luYyAoKSA9PiB7XG4gICAgLy8gQ2FuY2VsIGFueSBpbi1mbGlnaHQgcmVxdWVzdHNcbiAgICBhYm9ydENvbnRyb2xsZXJSZWYuY3VycmVudD8uYWJvcnQoKVxuXG4gICAgY29uc3QgY29udHJvbGxlciA9IG5ldyBBYm9ydENvbnRyb2xsZXIoKVxuICAgIGFib3J0Q29udHJvbGxlclJlZi5jdXJyZW50ID0gY29udHJvbGxlclxuXG4gICAgY29uc3QgbXNncyA9IG1lc3NhZ2VzUmVmLmN1cnJlbnRcblxuICAgIGNvbnN0IGxvZ1Jlc3VsdCA9IGxvZ05leHRSZXN1bHRSZWYuY3VycmVudFxuICAgIGxvZ05leHRSZXN1bHRSZWYuY3VycmVudCA9IGZhbHNlXG5cbiAgICB0cnkge1xuICAgICAgbGV0IGV4Y2VlZHMyMDBrVG9rZW5zID0gcHJldmlvdXNTdGF0ZVJlZi5jdXJyZW50LmV4Y2VlZHMyMDBrVG9rZW5zXG5cbiAgICAgIC8vIE9ubHkgcmVjYWxjdWxhdGUgMjAwayBjaGVjayBpZiBtZXNzYWdlcyBjaGFuZ2VkXG4gICAgICBjb25zdCBjdXJyZW50TWVzc2FnZUlkID0gZ2V0TGFzdEFzc2lzdGFudE1lc3NhZ2VJZChtc2dzKVxuICAgICAgaWYgKGN1cnJlbnRNZXNzYWdlSWQgIT09IHByZXZpb3VzU3RhdGVSZWYuY3VycmVudC5tZXNzYWdlSWQpIHtcbiAgICAgICAgZXhjZWVkczIwMGtUb2tlbnMgPSBkb2VzTW9zdFJlY2VudEFzc2lzdGFudE1lc3NhZ2VFeGNlZWQyMDBrKG1zZ3MpXG4gICAgICAgIHByZXZpb3VzU3RhdGVSZWYuY3VycmVudC5tZXNzYWdlSWQgPSBjdXJyZW50TWVzc2FnZUlkXG4gICAgICAgIHByZXZpb3VzU3RhdGVSZWYuY3VycmVudC5leGNlZWRzMjAwa1Rva2VucyA9IGV4Y2VlZHMyMDBrVG9rZW5zXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHN0YXR1c0lucHV0ID0gYnVpbGRTdGF0dXNMaW5lQ29tbWFuZElucHV0KFxuICAgICAgICBwZXJtaXNzaW9uTW9kZVJlZi5jdXJyZW50LFxuICAgICAgICBleGNlZWRzMjAwa1Rva2VucyxcbiAgICAgICAgc2V0dGluZ3NSZWYuY3VycmVudCxcbiAgICAgICAgbXNncyxcbiAgICAgICAgQXJyYXkuZnJvbShhZGRlZERpcnNSZWYuY3VycmVudC5rZXlzKCkpLFxuICAgICAgICBtYWluTG9vcE1vZGVsUmVmLmN1cnJlbnQsXG4gICAgICAgIHZpbU1vZGVSZWYuY3VycmVudCxcbiAgICAgIClcblxuICAgICAgY29uc3QgdGV4dCA9IGF3YWl0IGV4ZWN1dGVTdGF0dXNMaW5lQ29tbWFuZChcbiAgICAgICAgc3RhdHVzSW5wdXQsXG4gICAgICAgIGNvbnRyb2xsZXIuc2lnbmFsLFxuICAgICAgICB1bmRlZmluZWQsXG4gICAgICAgIGxvZ1Jlc3VsdCxcbiAgICAgIClcbiAgICAgIGlmICghY29udHJvbGxlci5zaWduYWwuYWJvcnRlZCkge1xuICAgICAgICBzZXRBcHBTdGF0ZShwcmV2ID0+IHtcbiAgICAgICAgICBpZiAocHJldi5zdGF0dXNMaW5lVGV4dCA9PT0gdGV4dCkgcmV0dXJuIHByZXZcbiAgICAgICAgICByZXR1cm4geyAuLi5wcmV2LCBzdGF0dXNMaW5lVGV4dDogdGV4dCB9XG4gICAgICAgIH0pXG4gICAgICB9XG4gICAgfSBjYXRjaCB7XG4gICAgICAvLyBTaWxlbnRseSBpZ25vcmUgZXJyb3JzIGluIHN0YXR1cyBsaW5lIHVwZGF0ZXNcbiAgICB9XG4gIH0sIFttZXNzYWdlc1JlZiwgc2V0QXBwU3RhdGVdKVxuXG4gIC8vIFN0YWJsZSBkZWJvdW5jZWQgc2NoZWR1bGUgZnVuY3Rpb24g4oCUIG5vIGRlcHMsIHVzZXMgcmVmc1xuICBjb25zdCBzY2hlZHVsZVVwZGF0ZSA9IHVzZUNhbGxiYWNrKCgpID0+IHtcbiAgICBpZiAoZGVib3VuY2VUaW1lclJlZi5jdXJyZW50ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGNsZWFyVGltZW91dChkZWJvdW5jZVRpbWVyUmVmLmN1cnJlbnQpXG4gICAgfVxuICAgIGRlYm91bmNlVGltZXJSZWYuY3VycmVudCA9IHNldFRpbWVvdXQoXG4gICAgICAocmVmLCBkb1VwZGF0ZSkgPT4ge1xuICAgICAgICByZWYuY3VycmVudCA9IHVuZGVmaW5lZFxuICAgICAgICB2b2lkIGRvVXBkYXRlKClcbiAgICAgIH0sXG4gICAgICAzMDAsXG4gICAgICBkZWJvdW5jZVRpbWVyUmVmLFxuICAgICAgZG9VcGRhdGUsXG4gICAgKVxuICB9LCBbZG9VcGRhdGVdKVxuXG4gIC8vIE9ubHkgdHJpZ2dlciB1cGRhdGUgd2hlbiBhc3Npc3RhbnQgbWVzc2FnZSwgcGVybWlzc2lvbiBtb2RlLCB2aW0gbW9kZSwgb3IgbW9kZWwgYWN0dWFsbHkgY2hhbmdlc1xuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGlmIChcbiAgICAgIGxhc3RBc3Npc3RhbnRNZXNzYWdlSWQgIT09IHByZXZpb3VzU3RhdGVSZWYuY3VycmVudC5tZXNzYWdlSWQgfHxcbiAgICAgIHBlcm1pc3Npb25Nb2RlICE9PSBwcmV2aW91c1N0YXRlUmVmLmN1cnJlbnQucGVybWlzc2lvbk1vZGUgfHxcbiAgICAgIHZpbU1vZGUgIT09IHByZXZpb3VzU3RhdGVSZWYuY3VycmVudC52aW1Nb2RlIHx8XG4gICAgICBtYWluTG9vcE1vZGVsICE9PSBwcmV2aW91c1N0YXRlUmVmLmN1cnJlbnQubWFpbkxvb3BNb2RlbFxuICAgICkge1xuICAgICAgLy8gRG9uJ3QgdXBkYXRlIG1lc3NhZ2VJZCBoZXJlIOKAlCBsZXQgZG9VcGRhdGUgaGFuZGxlIGl0IHNvXG4gICAgICAvLyBleGNlZWRzMjAwa1Rva2VucyBpcyByZWNhbGN1bGF0ZWQgd2l0aCB0aGUgbGF0ZXN0IG1lc3NhZ2VzXG4gICAgICBwcmV2aW91c1N0YXRlUmVmLmN1cnJlbnQucGVybWlzc2lvbk1vZGUgPSBwZXJtaXNzaW9uTW9kZVxuICAgICAgcHJldmlvdXNTdGF0ZVJlZi5jdXJyZW50LnZpbU1vZGUgPSB2aW1Nb2RlXG4gICAgICBwcmV2aW91c1N0YXRlUmVmLmN1cnJlbnQubWFpbkxvb3BNb2RlbCA9IG1haW5Mb29wTW9kZWxcbiAgICAgIHNjaGVkdWxlVXBkYXRlKClcbiAgICB9XG4gIH0sIFtcbiAgICBsYXN0QXNzaXN0YW50TWVzc2FnZUlkLFxuICAgIHBlcm1pc3Npb25Nb2RlLFxuICAgIHZpbU1vZGUsXG4gICAgbWFpbkxvb3BNb2RlbCxcbiAgICBzY2hlZHVsZVVwZGF0ZSxcbiAgXSlcblxuICAvLyBXaGVuIHRoZSBzdGF0dXNMaW5lIGNvbW1hbmQgY2hhbmdlcyAoaG90IHJlbG9hZCksIGxvZyB0aGUgbmV4dCByZXN1bHRcbiAgY29uc3Qgc3RhdHVzTGluZUNvbW1hbmQgPSBzZXR0aW5ncz8uc3RhdHVzTGluZT8uY29tbWFuZFxuICBjb25zdCBpc0ZpcnN0U2V0dGluZ3NSZW5kZXIgPSB1c2VSZWYodHJ1ZSlcbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBpZiAoaXNGaXJzdFNldHRpbmdzUmVuZGVyLmN1cnJlbnQpIHtcbiAgICAgIGlzRmlyc3RTZXR0aW5nc1JlbmRlci5jdXJyZW50ID0gZmFsc2VcbiAgICAgIHJldHVyblxuICAgIH1cbiAgICBsb2dOZXh0UmVzdWx0UmVmLmN1cnJlbnQgPSB0cnVlXG4gICAgdm9pZCBkb1VwZGF0ZSgpXG4gIH0sIFtzdGF0dXNMaW5lQ29tbWFuZCwgZG9VcGRhdGVdKVxuXG4gIC8vIFNlcGFyYXRlIGVmZmVjdCBmb3IgbG9nZ2luZyBvbiBtb3VudFxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGNvbnN0IHN0YXR1c0xpbmUgPSBzZXR0aW5ncz8uc3RhdHVzTGluZVxuICAgIGlmIChzdGF0dXNMaW5lKSB7XG4gICAgICBsb2dFdmVudCgndGVuZ3Vfc3RhdHVzX2xpbmVfbW91bnQnLCB7XG4gICAgICAgIGNvbW1hbmRfbGVuZ3RoOiBzdGF0dXNMaW5lLmNvbW1hbmQubGVuZ3RoLFxuICAgICAgICBwYWRkaW5nOiBzdGF0dXNMaW5lLnBhZGRpbmcsXG4gICAgICB9KVxuICAgICAgLy8gTG9nIGlmIHN0YXR1cyBsaW5lIGlzIGNvbmZpZ3VyZWQgYnV0IGRpc2FibGVkIGJ5IGRpc2FibGVBbGxIb29rc1xuICAgICAgaWYgKHNldHRpbmdzLmRpc2FibGVBbGxIb29rcyA9PT0gdHJ1ZSkge1xuICAgICAgICBsb2dGb3JEZWJ1Z2dpbmcoXG4gICAgICAgICAgJ1N0YXR1cyBsaW5lIGlzIGNvbmZpZ3VyZWQgYnV0IGRpc2FibGVBbGxIb29rcyBpcyB0cnVlJyxcbiAgICAgICAgICB7IGxldmVsOiAnd2FybicgfSxcbiAgICAgICAgKVxuICAgICAgfVxuICAgICAgLy8gZXhlY3V0ZVN0YXR1c0xpbmVDb21tYW5kIChob29rcy50cykgcmV0dXJucyB1bmRlZmluZWQgd2hlbiB0cnVzdCBpc1xuICAgICAgLy8gYmxvY2tlZCDigJQgc3RhdHVzTGluZVRleHQgc3RheXMgdW5kZWZpbmVkIGZvcmV2ZXIsIHVzZXIgc2VlcyBub3RoaW5nLFxuICAgICAgLy8gYW5kIHRlbmd1X3N0YXR1c19saW5lX21vdW50IGFib3ZlIGZpcmVzIGFueXdheSBzbyB0ZWxlbWV0cnkgbG9va3MgZmluZS5cbiAgICAgIGlmICghY2hlY2tIYXNUcnVzdERpYWxvZ0FjY2VwdGVkKCkpIHtcbiAgICAgICAgYWRkTm90aWZpY2F0aW9uKHtcbiAgICAgICAgICBrZXk6ICdzdGF0dXNsaW5lLXRydXN0LWJsb2NrZWQnLFxuICAgICAgICAgIHRleHQ6ICdzdGF0dXNsaW5lIHNraXBwZWQgwrcgcmVzdGFydCB0byBmaXgnLFxuICAgICAgICAgIGNvbG9yOiAnd2FybmluZycsXG4gICAgICAgICAgcHJpb3JpdHk6ICdsb3cnLFxuICAgICAgICB9KVxuICAgICAgICBsb2dGb3JEZWJ1Z2dpbmcoXG4gICAgICAgICAgJ1N0YXR1cyBsaW5lIGNvbW1hbmQgc2tpcHBlZDogd29ya3NwYWNlIHRydXN0IG5vdCBhY2NlcHRlZCcsXG4gICAgICAgICAgeyBsZXZlbDogJ3dhcm4nIH0sXG4gICAgICAgIClcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHJlYWN0LWhvb2tzL2V4aGF1c3RpdmUtZGVwc1xuICAgIC8vIGJpb21lLWlnbm9yZSBsaW50L2NvcnJlY3RuZXNzL3VzZUV4aGF1c3RpdmVEZXBlbmRlbmNpZXM6IGludGVudGlvbmFsXG4gIH0sIFtdKSAvLyBPbmx5IHJ1biBvbmNlIG9uIG1vdW50IC0gc2V0dGluZ3Mgc3RhYmxlIGZvciBpbml0aWFsIGxvZ2dpbmdcblxuICAvLyBJbml0aWFsIHVwZGF0ZSBvbiBtb3VudCArIGNsZWFudXAgb24gdW5tb3VudFxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIHZvaWQgZG9VcGRhdGUoKVxuXG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIGFib3J0Q29udHJvbGxlclJlZi5jdXJyZW50Py5hYm9ydCgpXG4gICAgICBpZiAoZGVib3VuY2VUaW1lclJlZi5jdXJyZW50ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgY2xlYXJUaW1lb3V0KGRlYm91bmNlVGltZXJSZWYuY3VycmVudClcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHJlYWN0LWhvb2tzL2V4aGF1c3RpdmUtZGVwc1xuICAgIC8vIGJpb21lLWlnbm9yZSBsaW50L2NvcnJlY3RuZXNzL3VzZUV4aGF1c3RpdmVEZXBlbmRlbmNpZXM6IGludGVudGlvbmFsXG4gIH0sIFtdKSAvLyBPbmx5IHJ1biBvbmNlIG9uIG1vdW50LCBub3Qgd2hlbiBkb1VwZGF0ZSBjaGFuZ2VzXG5cbiAgLy8gR2V0IHBhZGRpbmcgZnJvbSBzZXR0aW5ncyBvciBkZWZhdWx0IHRvIDBcbiAgY29uc3QgcGFkZGluZ1ggPSBzZXR0aW5ncz8uc3RhdHVzTGluZT8ucGFkZGluZyA/PyAwXG5cbiAgLy8gU3RhdHVzTGluZSBtdXN0IGhhdmUgc3RhYmxlIGhlaWdodCBpbiBmdWxsc2NyZWVuIOKAlCB0aGUgZm9vdGVyIGlzXG4gIC8vIGZsZXhTaHJpbms6MCBzbyBhIDDihpIxIHJvdyBjaGFuZ2Ugd2hlbiB0aGUgY29tbWFuZCBmaW5pc2hlcyBzdGVhbHNcbiAgLy8gYSByb3cgZnJvbSBTY3JvbGxCb3ggYW5kIHNoaWZ0cyBjb250ZW50LiBSZXNlcnZlIHRoZSByb3cgd2hpbGUgbG9hZGluZ1xuICAvLyAoc2FtZSB0cmljayBhcyBQcm9tcHRJbnB1dEZvb3RlckxlZnRTaWRlKS5cbiAgcmV0dXJuIChcbiAgICA8Qm94IHBhZGRpbmdYPXtwYWRkaW5nWH0gZ2FwPXsyfT5cbiAgICAgIHtzdGF0dXNMaW5lVGV4dCA/IChcbiAgICAgICAgPFRleHQgZGltQ29sb3Igd3JhcD1cInRydW5jYXRlXCI+XG4gICAgICAgICAgPEFuc2k+e3N0YXR1c0xpbmVUZXh0fTwvQW5zaT5cbiAgICAgICAgPC9UZXh0PlxuICAgICAgKSA6IGlzRnVsbHNjcmVlbkVudkVuYWJsZWQoKSA/IChcbiAgICAgICAgPFRleHQ+IDwvVGV4dD5cbiAgICAgICkgOiBudWxsfVxuICAgIDwvQm94PlxuICApXG59XG5cbi8vIFBhcmVudCAoUHJvbXB0SW5wdXRGb290ZXIpIHJlLXJlbmRlcnMgb24gZXZlcnkgc2V0TWVzc2FnZXMsIGJ1dCBTdGF0dXNMaW5lJ3Ncbi8vIG93biBwcm9wcyBub3cgb25seSBjaGFuZ2Ugd2hlbiBsYXN0QXNzaXN0YW50TWVzc2FnZUlkIGZsaXBzIOKAlCBtZW1vIGtlZXBzIGl0XG4vLyBmcm9tIGJlaW5nIGRyYWdnZWQgYWxvbmcgKHByZXZpb3VzbHkgfjE4IG5vLXByb3AtY2hhbmdlIHJlbmRlcnMgcGVyIHNlc3Npb24pLlxuZXhwb3J0IGNvbnN0IFN0YXR1c0xpbmUgPSBtZW1vKFN0YXR1c0xpbmVJbm5lcilcbiJdLCJtYXBwaW5ncyI6IkFBQUEsU0FBU0EsT0FBTyxRQUFRLFlBQVk7QUFDcEMsT0FBTyxLQUFLQyxLQUFLLE1BQU0sT0FBTztBQUM5QixTQUFTQyxJQUFJLEVBQUVDLFdBQVcsRUFBRUMsU0FBUyxFQUFFQyxNQUFNLFFBQVEsT0FBTztBQUM1RCxTQUFTQyxRQUFRLFFBQVEsaUNBQWlDO0FBQzFELFNBQVNDLFdBQVcsRUFBRUMsY0FBYyxRQUFRLHVCQUF1QjtBQUNuRSxjQUFjQyxjQUFjLFFBQVEseUNBQXlDO0FBQzdFLFNBQ0VDLGVBQWUsRUFDZkMsZUFBZSxFQUNmQyxzQkFBc0IsRUFDdEJDLGNBQWMsRUFDZEMsV0FBVyxFQUNYQyxZQUFZLFFBQ1AsdUJBQXVCO0FBQzlCLFNBQVNDLHlCQUF5QixRQUFRLDhCQUE4QjtBQUN4RSxTQUFTQyxnQkFBZ0IsUUFBUSw2QkFBNkI7QUFDOUQsU0FDRUMsbUJBQW1CLEVBQ25CQyxZQUFZLEVBQ1pDLGdCQUFnQixFQUNoQkMsbUJBQW1CLEVBQ25CQyxrQkFBa0IsRUFDbEJDLG9CQUFvQixFQUNwQkMsb0JBQW9CLFFBQ2Ysb0JBQW9CO0FBQzNCLFNBQVNDLGdCQUFnQixRQUFRLDhCQUE4QjtBQUMvRCxTQUFTLEtBQUtDLGdCQUFnQixFQUFFQyxXQUFXLFFBQVEseUJBQXlCO0FBQzVFLFNBQVNDLElBQUksRUFBRUMsR0FBRyxFQUFFQyxJQUFJLFFBQVEsV0FBVztBQUMzQyxTQUFTQyxpQkFBaUIsUUFBUSwrQkFBK0I7QUFDakUsY0FBY0MsT0FBTyxRQUFRLHFCQUFxQjtBQUNsRCxjQUFjQyxzQkFBc0IsUUFBUSx3QkFBd0I7QUFDcEUsY0FBY0MsT0FBTyxRQUFRLDRCQUE0QjtBQUN6RCxTQUFTQywyQkFBMkIsUUFBUSxvQkFBb0I7QUFDaEUsU0FDRUMsMkJBQTJCLEVBQzNCQyx3QkFBd0IsUUFDbkIscUJBQXFC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 diff --git a/src/components/permissions/ExitPlanModePermissionRequest/ExitPlanModePermissionRequest.tsx b/src/components/permissions/ExitPlanModePermissionRequest/ExitPlanModePermissionRequest.tsx index 8e0ca6c5..e3974b99 100644 --- a/src/components/permissions/ExitPlanModePermissionRequest/ExitPlanModePermissionRequest.tsx +++ b/src/components/permissions/ExitPlanModePermissionRequest/ExitPlanModePermissionRequest.tsx @@ -16,7 +16,8 @@ import { EXIT_PLAN_MODE_V2_TOOL_NAME } from '../../../tools/ExitPlanModeTool/con import type { AllowedPrompt } from '../../../tools/ExitPlanModeTool/ExitPlanModeV2Tool.js'; import { TEAM_CREATE_TOOL_NAME } from '../../../tools/TeamCreateTool/constants.js'; import { isAgentSwarmsEnabled } from '../../../utils/agentSwarmsEnabled.js'; -import { calculateContextPercentages, getContextWindowForModel } from '../../../utils/context.js'; +import { calculateCurrentContextTokenTotal, getContextWindowForModel } from '../../../utils/context.js'; +import { calculateContextPercentagesFromTokens, getProviderUsageTrust, hasMediaInput } from '../../../utils/contextBudget.js'; import { getExternalEditor } from '../../../utils/editor.js'; import { getDisplayPath } from '../../../utils/file.js'; import { toIDEDisplayName } from '../../../utils/ide.js'; @@ -24,6 +25,7 @@ import { logError } from '../../../utils/log.js'; import { enqueuePendingNotification } from '../../../utils/messageQueueManager.js'; import { createUserMessage } from '../../../utils/messages.js'; import { getMainLoopModel, getRuntimeMainLoopModel } from '../../../utils/model/model.js'; +import { isFirstPartyAnthropicBaseUrl } from '../../../utils/model/providers.js'; import { createPromptRuleContent, isClassifierPermissionsEnabled, PROMPT_PREFIX } from '../../../utils/permissions/bashClassifier.js'; import { type PermissionMode, toExternalPermissionMode } from '../../../utils/permissions/PermissionMode.js'; import type { PermissionUpdate } from '../../../utils/permissions/PermissionUpdateSchema.js'; @@ -33,6 +35,7 @@ import { getPlan, getPlanFilePath } from '../../../utils/plans.js'; import { editFileInEditor, editPromptInEditor } from '../../../utils/promptEditor.js'; import { getCurrentSessionTitle, getTranscriptPath, saveAgentName, saveCustomTitle } from '../../../utils/sessionStorage.js'; import { getSettings_DEPRECATED } from '../../../utils/settings/settings.js'; +import { tokenCountWithEstimation } from '../../../utils/tokens.js'; import { type OptionWithDescription, Select } from '../../CustomSelect/index.js'; import { Markdown } from '../../Markdown.js'; import { PermissionDialog } from '../PermissionDialog.js'; @@ -143,6 +146,7 @@ export function ExitPlanModePermissionRequest({ // feature() must sit directly in an if/ternary (bun:bundle DCE constraint). const showUltraplan = feature('ULTRAPLAN') ? !ultraplanSessionUrl && !ultraplanLaunching : false; const usage = toolUseConfirm.assistantMessage.message.usage; + const messages = useAppState(s => s.messages); const { mode, isAutoModeAvailable, @@ -151,11 +155,11 @@ export function ExitPlanModePermissionRequest({ const options = useMemo(() => buildPlanApprovalOptions({ showClearContext, showUltraplan, - usedPercent: showClearContext ? getContextUsedPercent(usage, mode) : null, + usedPercent: showClearContext ? getContextUsedPercent(usage, mode, tokenCountWithEstimation(messages), hasMediaInput(messages)) : null, isAutoModeAvailable, isBypassPermissionsModeAvailable, onFeedbackChange: setPlanFeedback - }), [showClearContext, showUltraplan, usage, mode, isAutoModeAvailable, isBypassPermissionsModeAvailable]); + }), [showClearContext, showUltraplan, usage, mode, messages, isAutoModeAvailable, isBypassPermissionsModeAvailable]); function onImagePaste(base64Image: string, mediaType?: string, filename?: string, dimensions?: ImageDimensions, _sourcePath?: string) { const pasteId = nextPasteIdRef.current++; const newContent: PastedContent = { @@ -746,9 +750,10 @@ export function buildPlanApprovalOptions({ } function getContextUsedPercent(usage: { input_tokens: number; + output_tokens?: number | null; cache_creation_input_tokens?: number | null; cache_read_input_tokens?: number | null; -} | undefined, permissionMode: PermissionMode): number | null { +} | undefined, permissionMode: PermissionMode, estimatedContextTokens: number, containsMediaInput: boolean): number | null { if (!usage) return null; const runtimeModel = getRuntimeMainLoopModel({ permissionMode, @@ -756,13 +761,20 @@ function getContextUsedPercent(usage: { exceeds200kTokens: false }); const contextWindowSize = getContextWindowForModel(runtimeModel, getSdkBetas()); - const { - used - } = calculateContextPercentages({ + const usedTokens = calculateCurrentContextTokenTotal(estimatedContextTokens, { input_tokens: usage.input_tokens, + output_tokens: usage.output_tokens ?? 0, cache_creation_input_tokens: usage.cache_creation_input_tokens ?? 0, cache_read_input_tokens: usage.cache_read_input_tokens ?? 0 - }, contextWindowSize); + }, contextWindowSize, { + usageTrust: getProviderUsageTrust({ + isFirstPartyAnthropic: isFirstPartyAnthropicBaseUrl() + }), + hasMediaInput: containsMediaInput + }); + const { + used + } = calculateContextPercentagesFromTokens(usedTokens, contextWindowSize); return used; } -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJmZWF0dXJlIiwiVVVJRCIsImZpZ3VyZXMiLCJSZWFjdCIsInVzZUNhbGxiYWNrIiwidXNlRWZmZWN0IiwidXNlTGF5b3V0RWZmZWN0IiwidXNlTWVtbyIsInVzZVJlZiIsInVzZVN0YXRlIiwidXNlTm90aWZpY2F0aW9ucyIsIkFuYWx5dGljc01ldGFkYXRhX0lfVkVSSUZJRURfVEhJU19JU19OT1RfQ09ERV9PUl9GSUxFUEFUSFMiLCJsb2dFdmVudCIsInVzZUFwcFN0YXRlIiwidXNlQXBwU3RhdGVTdG9yZSIsInVzZVNldEFwcFN0YXRlIiwiZ2V0U2RrQmV0YXMiLCJnZXRTZXNzaW9uSWQiLCJpc1Nlc3Npb25QZXJzaXN0ZW5jZURpc2FibGVkIiwic2V0SGFzRXhpdGVkUGxhbk1vZGUiLCJzZXROZWVkc0F1dG9Nb2RlRXhpdEF0dGFjaG1lbnQiLCJzZXROZWVkc1BsYW5Nb2RlRXhpdEF0dGFjaG1lbnQiLCJnZW5lcmF0ZVNlc3Npb25OYW1lIiwibGF1bmNoVWx0cmFwbGFuIiwiS2V5Ym9hcmRFdmVudCIsIkJveCIsIlRleHQiLCJBcHBTdGF0ZSIsIkFHRU5UX1RPT0xfTkFNRSIsIkVYSVRfUExBTl9NT0RFX1YyX1RPT0xfTkFNRSIsIkFsbG93ZWRQcm9tcHQiLCJURUFNX0NSRUFURV9UT09MX05BTUUiLCJpc0FnZW50U3dhcm1zRW5hYmxlZCIsImNhbGN1bGF0ZUNvbnRleHRQZXJjZW50YWdlcyIsImdldENvbnRleHRXaW5kb3dGb3JNb2RlbCIsImdldEV4dGVybmFsRWRpdG9yIiwiZ2V0RGlzcGxheVBhdGgiLCJ0b0lERURpc3BsYXlOYW1lIiwibG9nRXJyb3IiLCJlbnF1ZXVlUGVuZGluZ05vdGlmaWNhdGlvbiIsImNyZWF0ZVVzZXJNZXNzYWdlIiwiZ2V0TWFpbkxvb3BNb2RlbCIsImdldFJ1bnRpbWVNYWluTG9vcE1vZGVsIiwiY3JlYXRlUHJvbXB0UnVsZUNvbnRlbnQiLCJpc0NsYXNzaWZpZXJQZXJtaXNzaW9uc0VuYWJsZWQiLCJQUk9NUFRfUFJFRklYIiwiUGVybWlzc2lvbk1vZGUiLCJ0b0V4dGVybmFsUGVybWlzc2lvbk1vZGUiLCJQZXJtaXNzaW9uVXBkYXRlIiwiaXNBdXRvTW9kZUdhdGVFbmFibGVkIiwicmVzdG9yZURhbmdlcm91c1Blcm1pc3Npb25zIiwic3RyaXBEYW5nZXJvdXNQZXJtaXNzaW9uc0ZvckF1dG9Nb2RlIiwiZ2V0UGV3dGVyTGVkZ2VyVmFyaWFudCIsImlzUGxhbk1vZGVJbnRlcnZpZXdQaGFzZUVuYWJsZWQiLCJnZXRQbGFuIiwiZ2V0UGxhbkZpbGVQYXRoIiwiZWRpdEZpbGVJbkVkaXRvciIsImVkaXRQcm9tcHRJbkVkaXRvciIsImdldEN1cnJlbnRTZXNzaW9uVGl0bGUiLCJnZXRUcmFuc2NyaXB0UGF0aCIsInNhdmVBZ2VudE5hbWUiLCJzYXZlQ3VzdG9tVGl0bGUiLCJnZXRTZXR0aW5nc19ERVBSRUNBVEVEIiwiT3B0aW9uV2l0aERlc2NyaXB0aW9uIiwiU2VsZWN0IiwiTWFya2Rvd24iLCJQZXJtaXNzaW9uRGlhbG9nIiwiUGVybWlzc2lvblJlcXVlc3RQcm9wcyIsIlBlcm1pc3Npb25SdWxlRXhwbGFuYXRpb24iLCJhdXRvTW9kZVN0YXRlTW9kdWxlIiwicmVxdWlyZSIsIkJhc2U2NEltYWdlU291cmNlIiwiSW1hZ2VCbG9ja1BhcmFtIiwiUGFzdGVkQ29udGVudCIsIkltYWdlRGltZW5zaW9ucyIsIm1heWJlUmVzaXplQW5kRG93bnNhbXBsZUltYWdlQmxvY2siLCJjYWNoZUltYWdlUGF0aCIsInN0b3JlSW1hZ2UiLCJSZXNwb25zZVZhbHVlIiwiYnVpbGRQZXJtaXNzaW9uVXBkYXRlcyIsIm1vZGUiLCJhbGxvd2VkUHJvbXB0cyIsInVwZGF0ZXMiLCJ0eXBlIiwiZGVzdGluYXRpb24iLCJsZW5ndGgiLCJwdXNoIiwicnVsZXMiLCJtYXAiLCJwIiwidG9vbE5hbWUiLCJ0b29sIiwicnVsZUNvbnRlbnQiLCJwcm9tcHQiLCJiZWhhdmlvciIsImF1dG9OYW1lU2Vzc2lvbkZyb21QbGFuIiwicGxhbiIsInNldEFwcFN0YXRlIiwidXBkYXRlciIsInByZXYiLCJpc0NsZWFyQ29udGV4dCIsImNsZWFudXBQZXJpb2REYXlzIiwiY29udGVudCIsInNsaWNlIiwiQWJvcnRDb250cm9sbGVyIiwic2lnbmFsIiwidGhlbiIsIm5hbWUiLCJzZXNzaW9uSWQiLCJmdWxsUGF0aCIsInN0YW5kYWxvbmVBZ2VudENvbnRleHQiLCJjYXRjaCIsIkV4aXRQbGFuTW9kZVBlcm1pc3Npb25SZXF1ZXN0IiwidG9vbFVzZUNvbmZpcm0iLCJvbkRvbmUiLCJvblJlamVjdCIsIndvcmtlckJhZGdlIiwic2V0U3RpY2t5Rm9vdGVyIiwiUmVhY3ROb2RlIiwidG9vbFBlcm1pc3Npb25Db250ZXh0IiwicyIsInN0b3JlIiwiYWRkTm90aWZpY2F0aW9uIiwicGxhbkZlZWRiYWNrIiwic2V0UGxhbkZlZWRiYWNrIiwicGFzdGVkQ29udGVudHMiLCJzZXRQYXN0ZWRDb250ZW50cyIsIlJlY29yZCIsIm5leHRQYXN0ZUlkUmVmIiwic2hvd0NsZWFyQ29udGV4dCIsInNldHRpbmdzIiwic2hvd0NsZWFyQ29udGV4dE9uUGxhbkFjY2VwdCIsInVsdHJhcGxhblNlc3Npb25VcmwiLCJ1bHRyYXBsYW5MYXVuY2hpbmciLCJzaG93VWx0cmFwbGFuIiwidXNhZ2UiLCJhc3Npc3RhbnRNZXNzYWdlIiwibWVzc2FnZSIsImlzQXV0b01vZGVBdmFpbGFibGUiLCJpc0J5cGFzc1Blcm1pc3Npb25zTW9kZUF2YWlsYWJsZSIsIm9wdGlvbnMiLCJidWlsZFBsYW5BcHByb3ZhbE9wdGlvbnMiLCJ1c2VkUGVyY2VudCIsImdldENvbnRleHRVc2VkUGVyY2VudCIsIm9uRmVlZGJhY2tDaGFuZ2UiLCJvbkltYWdlUGFzdGUiLCJiYXNlNjRJbWFnZSIsIm1lZGlhVHlwZSIsImZpbGVuYW1lIiwiZGltZW5zaW9ucyIsIl9zb3VyY2VQYXRoIiwicGFzdGVJZCIsImN1cnJlbnQiLCJuZXdDb250ZW50IiwiaWQiLCJvblJlbW92ZUltYWdlIiwibmV4dCIsImltYWdlQXR0YWNobWVudHMiLCJPYmplY3QiLCJ2YWx1ZXMiLCJmaWx0ZXIiLCJjIiwiaGFzSW1hZ2VzIiwiaXNWMiIsImlucHV0UGxhbiIsInVuZGVmaW5lZCIsImlucHV0IiwicGxhbkZpbGVQYXRoIiwicmF3UGxhbiIsImlzRW1wdHkiLCJ0cmltIiwicGxhblN0cnVjdHVyZVZhcmlhbnQiLCJjdXJyZW50UGxhbiIsInNldEN1cnJlbnRQbGFuIiwic2hvd1NhdmVNZXNzYWdlIiwic2V0U2hvd1NhdmVNZXNzYWdlIiwicGxhbkVkaXRlZExvY2FsbHkiLCJzZXRQbGFuRWRpdGVkTG9jYWxseSIsInRpbWVyIiwic2V0VGltZW91dCIsImNsZWFyVGltZW91dCIsImhhbmRsZUtleURvd24iLCJlIiwiY3RybCIsImtleSIsInByZXZlbnREZWZhdWx0IiwicmVzdWx0IiwiZXJyb3IiLCJ0ZXh0IiwiY29sb3IiLCJwcmlvcml0eSIsInNoaWZ0IiwiaGFuZGxlUmVzcG9uc2UiLCJ2YWx1ZSIsIlByb21pc2UiLCJ0cmltbWVkRmVlZGJhY2siLCJhY2NlcHRGZWVkYmFjayIsInBsYW5MZW5ndGhDaGFycyIsIm91dGNvbWUiLCJpbnRlcnZpZXdQaGFzZUVuYWJsZWQiLCJibHVyYiIsInNlZWRQbGFuIiwiZ2V0QXBwU3RhdGUiLCJnZXRTdGF0ZSIsInNldFN0YXRlIiwibXNnIiwidXBkYXRlZElucHV0IiwiZ29pbmdUb0F1dG8iLCJhdXRvV2FzVXNlZER1cmluZ1BsYW4iLCJpc0F1dG9Nb2RlQWN0aXZlIiwic2V0QXV0b01vZGVBY3RpdmUiLCJwcmVQbGFuTW9kZSIsImlzUmVzdW1lQXV0b09wdGlvbiIsImlzS2VlcENvbnRleHRPcHRpb24iLCJjbGVhckNvbnRleHQiLCJoYXNGZWVkYmFjayIsInZlcmlmaWNhdGlvbkluc3RydWN0aW9uIiwidHJhbnNjcmlwdFBhdGgiLCJ0cmFuc2NyaXB0SGludCIsInRlYW1IaW50IiwiZmVlZGJhY2tTdWZmaXgiLCJpbml0aWFsTWVzc2FnZSIsInBsYW5Db250ZW50Iiwib25BbGxvdyIsImtlZXBDb250ZXh0TW9kZXMiLCJjb25zdCIsImtlZXBDb250ZXh0TW9kZSIsInN0YW5kYXJkTW9kZXMiLCJzdGFuZGFyZE1vZGUiLCJpbWFnZUJsb2NrcyIsImFsbCIsImltZyIsImJsb2NrIiwic291cmNlIiwibWVkaWFfdHlwZSIsImRhdGEiLCJyZXNpemVkIiwiZWRpdG9yIiwiZWRpdG9yTmFtZSIsImhhbmRsZVJlc3BvbnNlUmVmIiwiaGFuZGxlQ2FuY2VsUmVmIiwidXNlU3RpY2t5Rm9vdGVyIiwidiIsInRpY2siLCJoYW5kbGVFbXB0eVBsYW5SZXNwb25zZSIsImxhYmVsIiwicGVybWlzc2lvblJlc3VsdCIsImkiLCJ1c2VkTGFiZWwiLCJwbGFjZWhvbGRlciIsImRlc2NyaXB0aW9uIiwib25DaGFuZ2UiLCJpbnB1dF90b2tlbnMiLCJjYWNoZV9jcmVhdGlvbl9pbnB1dF90b2tlbnMiLCJjYWNoZV9yZWFkX2lucHV0X3Rva2VucyIsInBlcm1pc3Npb25Nb2RlIiwicnVudGltZU1vZGVsIiwibWFpbkxvb3BNb2RlbCIsImV4Y2VlZHMyMDBrVG9rZW5zIiwiY29udGV4dFdpbmRvd1NpemUiLCJ1c2VkIl0sInNvdXJjZXMiOlsiRXhpdFBsYW5Nb2RlUGVybWlzc2lvblJlcXVlc3QudHN4Il0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGZlYXR1cmUgfSBmcm9tICdidW46YnVuZGxlJ1xuaW1wb3J0IHR5cGUgeyBVVUlEIH0gZnJvbSAnY3J5cHRvJ1xuaW1wb3J0IGZpZ3VyZXMgZnJvbSAnZmlndXJlcydcbmltcG9ydCBSZWFjdCwge1xuICB1c2VDYWxsYmFjayxcbiAgdXNlRWZmZWN0LFxuICB1c2VMYXlvdXRFZmZlY3QsXG4gIHVzZU1lbW8sXG4gIHVzZVJlZixcbiAgdXNlU3RhdGUsXG59IGZyb20gJ3JlYWN0J1xuaW1wb3J0IHsgdXNlTm90aWZpY2F0aW9ucyB9IGZyb20gJ3NyYy9jb250ZXh0L25vdGlmaWNhdGlvbnMuanMnXG5pbXBvcnQge1xuICB0eXBlIEFuYWx5dGljc01ldGFkYXRhX0lfVkVSSUZJRURfVEhJU19JU19OT1RfQ09ERV9PUl9GSUxFUEFUSFMsXG4gIGxvZ0V2ZW50LFxufSBmcm9tICdzcmMvc2VydmljZXMvYW5hbHl0aWNzL2luZGV4LmpzJ1xuaW1wb3J0IHtcbiAgdXNlQXBwU3RhdGUsXG4gIHVzZUFwcFN0YXRlU3RvcmUsXG4gIHVzZVNldEFwcFN0YXRlLFxufSBmcm9tICdzcmMvc3RhdGUvQXBwU3RhdGUuanMnXG5pbXBvcnQge1xuICBnZXRTZGtCZXRhcyxcbiAgZ2V0U2Vzc2lvbklkLFxuICBpc1Nlc3Npb25QZXJzaXN0ZW5jZURpc2FibGVkLFxuICBzZXRIYXNFeGl0ZWRQbGFuTW9kZSxcbiAgc2V0TmVlZHNBdXRvTW9kZUV4aXRBdHRhY2htZW50LFxuICBzZXROZWVkc1BsYW5Nb2RlRXhpdEF0dGFjaG1lbnQsXG59IGZyb20gJy4uLy4uLy4uL2Jvb3RzdHJhcC9zdGF0ZS5qcydcbmltcG9ydCB7IGdlbmVyYXRlU2Vzc2lvbk5hbWUgfSBmcm9tICcuLi8uLi8uLi9jb21tYW5kcy9yZW5hbWUvZ2VuZXJhdGVTZXNzaW9uTmFtZS5qcydcbmltcG9ydCB7IGxhdW5jaFVsdHJhcGxhbiB9IGZyb20gJy4uLy4uLy4uL2NvbW1hbmRzL3VsdHJhcGxhbi5qcydcbmltcG9ydCB0eXBlIHsgS2V5Ym9hcmRFdmVudCB9IGZyb20gJy4uLy4uLy4uL2luay9ldmVudHMva2V5Ym9hcmQtZXZlbnQuanMnXG5pbXBvcnQgeyBCb3gsIFRleHQgfSBmcm9tICcuLi8uLi8uLi9pbmsuanMnXG5pbXBvcnQgdHlwZSB7IEFwcFN0YXRlIH0gZnJvbSAnLi4vLi4vLi4vc3RhdGUvQXBwU3RhdGVTdG9yZS5qcydcbmltcG9ydCB7IEFHRU5UX1RPT0xfTkFNRSB9IGZyb20gJy4uLy4uLy4uL3Rvb2xzL0FnZW50VG9vbC9jb25zdGFudHMuanMnXG5pbXBvcnQgeyBFWElUX1BMQU5fTU9ERV9WMl9UT09MX05BTUUgfSBmcm9tICcuLi8uLi8uLi90b29scy9FeGl0UGxhbk1vZGVUb29sL2NvbnN0YW50cy5qcydcbmltcG9ydCB0eXBlIHsgQWxsb3dlZFByb21wdCB9IGZyb20gJy4uLy4uLy4uL3Rvb2xzL0V4aXRQbGFuTW9kZVRvb2wvRXhpdFBsYW5Nb2RlVjJUb29sLmpzJ1xuaW1wb3J0IHsgVEVBTV9DUkVBVEVfVE9PTF9OQU1FIH0gZnJvbSAnLi4vLi4vLi4vdG9vbHMvVGVhbUNyZWF0ZVRvb2wvY29uc3RhbnRzLmpzJ1xuaW1wb3J0IHsgaXNBZ2VudFN3YXJtc0VuYWJsZWQgfSBmcm9tICcuLi8uLi8uLi91dGlscy9hZ2VudFN3YXJtc0VuYWJsZWQuanMnXG5pbXBvcnQge1xuICBjYWxjdWxhdGVDb250ZXh0UGVyY2VudGFnZXMsXG4gIGdldENvbnRleHRXaW5kb3dGb3JNb2RlbCxcbn0gZnJvbSAnLi4vLi4vLi4vdXRpbHMvY29udGV4dC5qcydcbmltcG9ydCB7IGdldEV4dGVybmFsRWRpdG9yIH0gZnJvbSAnLi4vLi4vLi4vdXRpbHMvZWRpdG9yLmpzJ1xuaW1wb3J0IHsgZ2V0RGlzcGxheVBhdGggfSBmcm9tICcuLi8uLi8uLi91dGlscy9maWxlLmpzJ1xuaW1wb3J0IHsgdG9JREVEaXNwbGF5TmFtZSB9IGZyb20gJy4uLy4uLy4uL3V0aWxzL2lkZS5qcydcbmltcG9ydCB7IGxvZ0Vycm9yIH0gZnJvbSAnLi4vLi4vLi4vdXRpbHMvbG9nLmpzJ1xuaW1wb3J0IHsgZW5xdWV1ZVBlbmRpbmdOb3RpZmljYXRpb24gfSBmcm9tICcuLi8uLi8uLi91dGlscy9tZXNzYWdlUXVldWVNYW5hZ2VyLmpzJ1xuaW1wb3J0IHsgY3JlYXRlVXNlck1lc3NhZ2UgfSBmcm9tICcuLi8uLi8uLi91dGlscy9tZXNzYWdlcy5qcydcbmltcG9ydCB7XG4gIGdldE1haW5Mb29wTW9kZWwsXG4gIGdldFJ1bnRpbWVNYWluTG9vcE1vZGVsLFxufSBmcm9tICcuLi8uLi8uLi91dGlscy9tb2RlbC9tb2RlbC5qcydcbmltcG9ydCB7XG4gIGNyZWF0ZVByb21wdFJ1bGVDb250ZW50LFxuICBpc0NsYXNzaWZpZXJQZXJtaXNzaW9uc0VuYWJsZWQsXG4gIFBST01QVF9QUkVGSVgsXG59IGZyb20gJy4uLy4uLy4uL3V0aWxzL3Blcm1pc3Npb25zL2Jhc2hDbGFzc2lmaWVyLmpzJ1xuaW1wb3J0IHtcbiAgdHlwZSBQZXJtaXNzaW9uTW9kZSxcbiAgdG9FeHRlcm5hbFBlcm1pc3Npb25Nb2RlLFxufSBmcm9tICcuLi8uLi8uLi91dGlscy9wZXJtaXNzaW9ucy9QZXJtaXNzaW9uTW9kZS5qcydcbmltcG9ydCB0eXBlIHsgUGVybWlzc2lvblVwZGF0ZSB9IGZyb20gJy4uLy4uLy4uL3V0aWxzL3Blcm1pc3Npb25zL1Blcm1pc3Npb25VcGRhdGVTY2hlbWEuanMnXG5pbXBvcnQge1xuICBpc0F1dG9Nb2RlR2F0ZUVuYWJsZWQsXG4gIHJlc3RvcmVEYW5nZXJvdXNQZXJtaXNzaW9ucyxcbiAgc3RyaXBEYW5nZXJvdXNQZXJtaXNzaW9uc0ZvckF1dG9Nb2RlLFxufSBmcm9tICcuLi8uLi8uLi91dGlscy9wZXJtaXNzaW9ucy9wZXJtaXNzaW9uU2V0dXAuanMnXG5pbXBvcnQge1xuICBnZXRQZXd0ZXJMZWRnZXJWYXJpYW50LFxuICBpc1BsYW5Nb2RlSW50ZXJ2aWV3UGhhc2VFbmFibGVkLFxufSBmcm9tICcuLi8uLi8uLi91dGlscy9wbGFuTW9kZVYyLmpzJ1xuaW1wb3J0IHsgZ2V0UGxhbiwgZ2V0UGxhbkZpbGVQYXRoIH0gZnJvbSAnLi4vLi4vLi4vdXRpbHMvcGxhbnMuanMnXG5pbXBvcnQge1xuICBlZGl0RmlsZUluRWRpdG9yLFxuICBlZGl0UHJvbXB0SW5FZGl0b3IsXG59IGZyb20gJy4uLy4uLy4uL3V0aWxzL3Byb21wdEVkaXRvci5qcydcbmltcG9ydCB7XG4gIGdldEN1cnJlbnRTZXNzaW9uVGl0bGUsXG4gIGdldFRyYW5zY3JpcHRQYXRoLFxuICBzYXZlQWdlbnROYW1lLFxuICBzYXZlQ3VzdG9tVGl0bGUsXG59IGZyb20gJy4uLy4uLy4uL3V0aWxzL3Nlc3Npb25TdG9yYWdlLmpzJ1xuaW1wb3J0IHsgZ2V0U2V0dGluZ3NfREVQUkVDQVRFRCB9IGZyb20gJy4uLy4uLy4uL3V0aWxzL3NldHRpbmdzL3NldHRpbmdzLmpzJ1xuaW1wb3J0IHsgdHlwZSBPcHRpb25XaXRoRGVzY3JpcHRpb24sIFNlbGVjdCB9IGZyb20gJy4uLy4uL0N1c3RvbVNlbGVjdC9pbmRleC5qcydcbmltcG9ydCB7IE1hcmtkb3duIH0gZnJvbSAnLi4vLi4vTWFya2Rvd24uanMnXG5pbXBvcnQgeyBQZXJtaXNzaW9uRGlhbG9nIH0gZnJvbSAnLi4vUGVybWlzc2lvbkRpYWxvZy5qcydcbmltcG9ydCB0eXBlIHsgUGVybWlzc2lvblJlcXVlc3RQcm9wcyB9IGZyb20gJy4uL1Blcm1pc3Npb25SZXF1ZXN0LmpzJ1xuaW1wb3J0IHsgUGVybWlzc2lvblJ1bGVFeHBsYW5hdGlvbiB9IGZyb20gJy4uL1Blcm1pc3Npb25SdWxlRXhwbGFuYXRpb24uanMnXG5cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby1yZXF1aXJlLWltcG9ydHMgKi9cbmNvbnN0IGF1dG9Nb2RlU3RhdGVNb2R1bGUgPSBmZWF0dXJlKCdUUkFOU0NSSVBUX0NMQVNTSUZJRVInKVxuICA/IChyZXF1aXJlKCcuLi8uLi8uLi91dGlscy9wZXJtaXNzaW9ucy9hdXRvTW9kZVN0YXRlLmpzJykgYXMgdHlwZW9mIGltcG9ydCgnLi4vLi4vLi4vdXRpbHMvcGVybWlzc2lvbnMvYXV0b01vZGVTdGF0ZS5qcycpKVxuICA6IG51bGxcblxuaW1wb3J0IHR5cGUge1xuICBCYXNlNjRJbWFnZVNvdXJjZSxcbiAgSW1hZ2VCbG9ja1BhcmFtLFxufSBmcm9tICdAYW50aHJvcGljLWFpL3Nkay9yZXNvdXJjZXMvbWVzc2FnZXMubWpzJ1xuLyogZXNsaW50LWVuYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tcmVxdWlyZS1pbXBvcnRzICovXG5pbXBvcnQgdHlwZSB7IFBhc3RlZENvbnRlbnQgfSBmcm9tICcuLi8uLi8uLi91dGlscy9jb25maWcuanMnXG5pbXBvcnQgdHlwZSB7IEltYWdlRGltZW5zaW9ucyB9IGZyb20gJy4uLy4uLy4uL3V0aWxzL2ltYWdlUmVzaXplci5qcydcbmltcG9ydCB7IG1heWJlUmVzaXplQW5kRG93bnNhbXBsZUltYWdlQmxvY2sgfSBmcm9tICcuLi8uLi8uLi91dGlscy9pbWFnZVJlc2l6ZXIuanMnXG5pbXBvcnQgeyBjYWNoZUltYWdlUGF0aCwgc3RvcmVJbWFnZSB9IGZyb20gJy4uLy4uLy4uL3V0aWxzL2ltYWdlU3RvcmUuanMnXG5cbnR5cGUgUmVzcG9uc2VWYWx1ZSA9XG4gIHwgJ3llcy1ieXBhc3MtcGVybWlzc2lvbnMnXG4gIHwgJ3llcy1hY2NlcHQtZWRpdHMnXG4gIHwgJ3llcy1hY2NlcHQtZWRpdHMta2VlcC1jb250ZXh0J1xuICB8ICd5ZXMtZGVmYXVsdC1rZWVwLWNvbnRleHQnXG4gIHwgJ3llcy1yZXN1bWUtYXV0by1tb2RlJ1xuICB8ICd5ZXMtYXV0by1jbGVhci1jb250ZXh0J1xuICB8ICd1bHRyYXBsYW4nXG4gIHwgJ25vJ1xuXG4vKipcbiAqIEJ1aWxkIHBlcm1pc3Npb24gdXBkYXRlcyBmb3IgcGxhbiBhcHByb3ZhbCwgaW5jbHVkaW5nIHByb21wdC1iYXNlZCBydWxlcyBpZiBwcm92aWRlZC5cbiAqIFByb21wdC1iYXNlZCBydWxlcyBhcmUgb25seSBhZGRlZCB3aGVuIGNsYXNzaWZpZXIgcGVybWlzc2lvbnMgYXJlIGVuYWJsZWQgKEFudC1vbmx5KS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkUGVybWlzc2lvblVwZGF0ZXMoXG4gIG1vZGU6IFBlcm1pc3Npb25Nb2RlLFxuICBhbGxvd2VkUHJvbXB0cz86IEFsbG93ZWRQcm9tcHRbXSxcbik6IFBlcm1pc3Npb25VcGRhdGVbXSB7XG4gIGNvbnN0IHVwZGF0ZXM6IFBlcm1pc3Npb25VcGRhdGVbXSA9IFtcbiAgICB7XG4gICAgICB0eXBlOiAnc2V0TW9kZScsXG4gICAgICBtb2RlOiB0b0V4dGVybmFsUGVybWlzc2lvbk1vZGUobW9kZSksXG4gICAgICBkZXN0aW5hdGlvbjogJ3Nlc3Npb24nLFxuICAgIH0sXG4gIF1cblxuICAvLyBBZGQgcHJvbXB0LWJhc2VkIHBlcm1pc3Npb24gcnVsZXMgaWYgcHJvdmlkZWQgKEFudC1vbmx5IGZlYXR1cmUpXG4gIGlmIChcbiAgICBpc0NsYXNzaWZpZXJQZXJtaXNzaW9uc0VuYWJsZWQoKSAmJlxuICAgIGFsbG93ZWRQcm9tcHRzICYmXG4gICAgYWxsb3dlZFByb21wdHMubGVuZ3RoID4gMFxuICApIHtcbiAgICB1cGRhdGVzLnB1c2goe1xuICAgICAgdHlwZTogJ2FkZFJ1bGVzJyxcbiAgICAgIHJ1bGVzOiBhbGxvd2VkUHJvbXB0cy5tYXAocCA9PiAoe1xuICAgICAgICB0b29sTmFtZTogcC50b29sLFxuICAgICAgICBydWxlQ29udGVudDogY3JlYXRlUHJvbXB0UnVsZUNvbnRlbnQocC5wcm9tcHQpLFxuICAgICAgfSkpLFxuICAgICAgYmVoYXZpb3I6ICdhbGxvdycsXG4gICAgICBkZXN0aW5hdGlvbjogJ3Nlc3Npb24nLFxuICAgIH0pXG4gIH1cblxuICByZXR1cm4gdXBkYXRlc1xufVxuXG4vKipcbiAqIEF1dG8tbmFtZSB0aGUgc2Vzc2lvbiBmcm9tIHRoZSBwbGFuIGNvbnRlbnQgd2hlbiB0aGUgdXNlciBhY2NlcHRzIGEgcGxhbixcbiAqIGlmIHRoZXkgaGF2ZW4ndCBhbHJlYWR5IG5hbWVkIGl0IHZpYSAvcmVuYW1lIG9yIC0tbmFtZS4gRmlyZS1hbmQtZm9yZ2V0LlxuICogTWlycm9ycyAvcmVuYW1lOiBrZWJhYi1jYXNlIG5hbWUsIHVwZGF0ZXMgdGhlIHByb21wdC1ib3JkZXIgYmFkZ2UuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhdXRvTmFtZVNlc3Npb25Gcm9tUGxhbihcbiAgcGxhbjogc3RyaW5nLFxuICBzZXRBcHBTdGF0ZTogKHVwZGF0ZXI6IChwcmV2OiBBcHBTdGF0ZSkgPT4gQXBwU3RhdGUpID0+IHZvaWQsXG4gIGlzQ2xlYXJDb250ZXh0OiBib29sZWFuLFxuKTogdm9pZCB7XG4gIGlmIChcbiAgICBpc1Nlc3Npb25QZXJzaXN0ZW5jZURpc2FibGVkKCkgfHxcbiAgICBnZXRTZXR0aW5nc19ERVBSRUNBVEVEKCk/LmNsZWFudXBQZXJpb2REYXlzID09PSAwXG4gICkge1xuICAgIHJldHVyblxuICB9XG4gIC8vIE9uIGNsZWFyLWNvbnRleHQsIHRoZSBjdXJyZW50IHNlc3Npb24gaXMgYWJvdXQgdG8gYmUgYWJhbmRvbmVkIOKAlCBpdHNcbiAgLy8gdGl0bGUgKHdoaWNoIG1heSBoYXZlIGJlZW4gc2V0IGJ5IGEgUFJJT1IgYXV0by1uYW1lKSBpcyBpcnJlbGV2YW50LlxuICAvLyBDaGVja2luZyBpdCB3b3VsZCBtYWtlIHRoZSBmZWF0dXJlIHNlbGYtZGVmZWF0aW5nIGFmdGVyIGZpcnN0IHVzZS5cbiAgaWYgKCFpc0NsZWFyQ29udGV4dCAmJiBnZXRDdXJyZW50U2Vzc2lvblRpdGxlKGdldFNlc3Npb25JZCgpKSkgcmV0dXJuXG4gIHZvaWQgZ2VuZXJhdGVTZXNzaW9uTmFtZShcbiAgICAvLyBnZW5lcmF0ZVNlc3Npb25OYW1lIHRhaWwtc2xpY2VzIHRvIHRoZSBsYXN0IDEwMDAgY2hhcnMgKGNvcnJlY3QgZm9yXG4gICAgLy8gY29udmVyc2F0aW9ucywgd2hlcmUgcmVjZW5jeSBtYXR0ZXJzKS4gUGxhbnMgZnJvbnQtbG9hZCB0aGUgZ29hbCBhbmRcbiAgICAvLyBlbmQgd2l0aCB0ZXN0aW5nIHN0ZXBzIOKAlCBoZWFkLXNsaWNlIHNvIEhhaWt1IHNlZXMgdGhlIHN1bW1hcnkuXG4gICAgW2NyZWF0ZVVzZXJNZXNzYWdlKHsgY29udGVudDogcGxhbi5zbGljZSgwLCAxMDAwKSB9KV0sXG4gICAgbmV3IEFib3J0Q29udHJvbGxlcigpLnNpZ25hbCxcbiAgKVxuICAgIC50aGVuKGFzeW5jIG5hbWUgPT4ge1xuICAgICAgLy8gT24gY2xlYXItY29udGV4dCBhY2NlcHRhbmNlLCByZWdlbmVyYXRlU2Vzc2lvbklkKCkgaGFzIHJ1biBieSBub3cg4oCUXG4gICAgICAvLyB0aGlzIGludGVudGlvbmFsbHkgbmFtZXMgdGhlIE5FVyBleGVjdXRpb24gc2Vzc2lvbi4gRG8gbm90IFwiZml4XCIgYnlcbiAgICAgIC8vIGNhcHR1cmluZyBzZXNzaW9uSWQgb25jZTsgdGhhdCB3b3VsZCBuYW1lIHRoZSBhYmFuZG9uZWQgcGxhbm5pbmcgc2Vzc2lvbi5cbiAgICAgIGlmICghbmFtZSB8fCBnZXRDdXJyZW50U2Vzc2lvblRpdGxlKGdldFNlc3Npb25JZCgpKSkgcmV0dXJuXG4gICAgICBjb25zdCBzZXNzaW9uSWQgPSBnZXRTZXNzaW9uSWQoKSBhcyBVVUlEXG4gICAgICBjb25zdCBmdWxsUGF0aCA9IGdldFRyYW5zY3JpcHRQYXRoKClcbiAgICAgIGF3YWl0IHNhdmVDdXN0b21UaXRsZShzZXNzaW9uSWQsIG5hbWUsIGZ1bGxQYXRoLCAnYXV0bycpXG4gICAgICBhd2FpdCBzYXZlQWdlbnROYW1lKHNlc3Npb25JZCwgbmFtZSwgZnVsbFBhdGgsICdhdXRvJylcbiAgICAgIHNldEFwcFN0YXRlKHByZXYgPT4ge1xuICAgICAgICBpZiAocHJldi5zdGFuZGFsb25lQWdlbnRDb250ZXh0Py5uYW1lID09PSBuYW1lKSByZXR1cm4gcHJldlxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIC4uLnByZXYsXG4gICAgICAgICAgc3RhbmRhbG9uZUFnZW50Q29udGV4dDogeyAuLi5wcmV2LnN0YW5kYWxvbmVBZ2VudENvbnRleHQsIG5hbWUgfSxcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICB9KVxuICAgIC5jYXRjaChsb2dFcnJvcilcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIEV4aXRQbGFuTW9kZVBlcm1pc3Npb25SZXF1ZXN0KHtcbiAgdG9vbFVzZUNvbmZpcm0sXG4gIG9uRG9uZSxcbiAgb25SZWplY3QsXG4gIHdvcmtlckJhZGdlLFxuICBzZXRTdGlja3lGb290ZXIsXG59OiBQZXJtaXNzaW9uUmVxdWVzdFByb3BzKTogUmVhY3QuUmVhY3ROb2RlIHtcbiAgY29uc3QgdG9vbFBlcm1pc3Npb25Db250ZXh0ID0gdXNlQXBwU3RhdGUocyA9PiBzLnRvb2xQZXJtaXNzaW9uQ29udGV4dClcbiAgY29uc3Qgc2V0QXBwU3RhdGUgPSB1c2VTZXRBcHBTdGF0ZSgpXG4gIGNvbnN0IHN0b3JlID0gdXNlQXBwU3RhdGVTdG9yZSgpXG4gIGNvbnN0IHsgYWRkTm90aWZpY2F0aW9uIH0gPSB1c2VOb3RpZmljYXRpb25zKClcbiAgLy8gRmVlZGJhY2sgdGV4dCBmcm9tIHRoZSAnTm8nIG9wdGlvbidzIGlucHV0LiBUaHJlYWRlZCB0aHJvdWdoIG9uQWxsb3cgYXNcbiAgLy8gYWNjZXB0RmVlZGJhY2sgd2hlbiB0aGUgdXNlciBhcHByb3ZlcyDigJQgbGV0cyB1c2VycyBhbm5vdGF0ZSB0aGUgcGxhblxuICAvLyAoXCJhbHNvIHVwZGF0ZSB0aGUgUkVBRE1FXCIpIHdpdGhvdXQgYSByZWplY3QrcmUtcGxhbiByb3VuZC10cmlwLlxuICBjb25zdCBbcGxhbkZlZWRiYWNrLCBzZXRQbGFuRmVlZGJhY2tdID0gdXNlU3RhdGUoJycpXG4gIGNvbnN0IFtwYXN0ZWRDb250ZW50cywgc2V0UGFzdGVkQ29udGVudHNdID0gdXNlU3RhdGU8XG4gICAgUmVjb3JkPG51bWJlciwgUGFzdGVkQ29udGVudD5cbiAgPih7fSlcbiAgY29uc3QgbmV4dFBhc3RlSWRSZWYgPSB1c2VSZWYoMClcblxuICBjb25zdCBzaG93Q2xlYXJDb250ZXh0ID1cbiAgICB1c2VBcHBTdGF0ZShzID0+IHMuc2V0dGluZ3Muc2hvd0NsZWFyQ29udGV4dE9uUGxhbkFjY2VwdCkgPz8gZmFsc2VcbiAgY29uc3QgdWx0cmFwbGFuU2Vzc2lvblVybCA9IHVzZUFwcFN0YXRlKHMgPT4gcy51bHRyYXBsYW5TZXNzaW9uVXJsKVxuICBjb25zdCB1bHRyYXBsYW5MYXVuY2hpbmcgPSB1c2VBcHBTdGF0ZShzID0+IHMudWx0cmFwbGFuTGF1bmNoaW5nKVxuICAvLyBIaWRlIHRoZSBVbHRyYXBsYW4gYnV0dG9uIHdoaWxlIGEgc2Vzc2lvbiBpcyBhY3RpdmUgb3IgbGF1bmNoaW5nIOKAlFxuICAvLyBzZWxlY3RpbmcgaXQgd291bGQgZGlzbWlzcyB0aGUgZGlhbG9nIGFuZCByZWplY3QgbG9jYWxseSBiZWZvcmVcbiAgLy8gbGF1bmNoVWx0cmFwbGFuIGNhbiBub3RpY2UgdGhlIHNlc3Npb24gZXhpc3RzIGFuZCByZXR1cm4gXCJhbHJlYWR5IHBvbGxpbmdcIi5cbiAgLy8gZmVhdHVyZSgpIG11c3Qgc2l0IGRpcmVjdGx5IGluIGFuIGlmL3Rlcm5hcnkgKGJ1bjpidW5kbGUgRENFIGNvbnN0cmFpbnQpLlxuICBjb25zdCBzaG93VWx0cmFwbGFuID0gZmVhdHVyZSgnVUxUUkFQTEFOJylcbiAgICA/ICF1bHRyYXBsYW5TZXNzaW9uVXJsICYmICF1bHRyYXBsYW5MYXVuY2hpbmdcbiAgICA6IGZhbHNlXG4gIGNvbnN0IHVzYWdlID0gdG9vbFVzZUNvbmZpcm0uYXNzaXN0YW50TWVzc2FnZS5tZXNzYWdlLnVzYWdlXG4gIGNvbnN0IHsgbW9kZSwgaXNBdXRvTW9kZUF2YWlsYWJsZSwgaXNCeXBhc3NQZXJtaXNzaW9uc01vZGVBdmFpbGFibGUgfSA9XG4gICAgdG9vbFBlcm1pc3Npb25Db250ZXh0XG4gIGNvbnN0IG9wdGlvbnMgPSB1c2VNZW1vKFxuICAgICgpID0+XG4gICAgICBidWlsZFBsYW5BcHByb3ZhbE9wdGlvbnMoe1xuICAgICAgICBzaG93Q2xlYXJDb250ZXh0LFxuICAgICAgICBzaG93VWx0cmFwbGFuLFxuICAgICAgICB1c2VkUGVyY2VudDogc2hvd0NsZWFyQ29udGV4dFxuICAgICAgICAgID8gZ2V0Q29udGV4dFVzZWRQZXJjZW50KHVzYWdlLCBtb2RlKVxuICAgICAgICAgIDogbnVsbCxcbiAgICAgICAgaXNBdXRvTW9kZUF2YWlsYWJsZSxcbiAgICAgICAgaXNCeXBhc3NQZXJtaXNzaW9uc01vZGVBdmFpbGFibGUsXG4gICAgICAgIG9uRmVlZGJhY2tDaGFuZ2U6IHNldFBsYW5GZWVkYmFjayxcbiAgICAgIH0pLFxuICAgIFtcbiAgICAgIHNob3dDbGVhckNvbnRleHQsXG4gICAgICBzaG93VWx0cmFwbGFuLFxuICAgICAgdXNhZ2UsXG4gICAgICBtb2RlLFxuICAgICAgaXNBdXRvTW9kZUF2YWlsYWJsZSxcbiAgICAgIGlzQnlwYXNzUGVybWlzc2lvbnNNb2RlQXZhaWxhYmxlLFxuICAgIF0sXG4gIClcblxuICBmdW5jdGlvbiBvbkltYWdlUGFzdGUoXG4gICAgYmFzZTY0SW1hZ2U6IHN0cmluZyxcbiAgICBtZWRpYVR5cGU/OiBzdHJpbmcsXG4gICAgZmlsZW5hbWU/OiBzdHJpbmcsXG4gICAgZGltZW5zaW9ucz86IEltYWdlRGltZW5zaW9ucyxcbiAgICBfc291cmNlUGF0aD86IHN0cmluZyxcbiAgKSB7XG4gICAgY29uc3QgcGFzdGVJZCA9IG5leHRQYXN0ZUlkUmVmLmN1cnJlbnQrK1xuICAgIGNvbnN0IG5ld0NvbnRlbnQ6IFBhc3RlZENvbnRlbnQgPSB7XG4gICAgICBpZDogcGFzdGVJZCxcbiAgICAgIHR5cGU6ICdpbWFnZScsXG4gICAgICBjb250ZW50OiBiYXNlNjRJbWFnZSxcbiAgICAgIG1lZGlhVHlwZTogbWVkaWFUeXBlIHx8ICdpbWFnZS9wbmcnLFxuICAgICAgZmlsZW5hbWU6IGZpbGVuYW1lIHx8ICdQYXN0ZWQgaW1hZ2UnLFxuICAgICAgZGltZW5zaW9ucyxcbiAgICB9XG4gICAgY2FjaGVJbWFnZVBhdGgobmV3Q29udGVudClcbiAgICB2b2lkIHN0b3JlSW1hZ2UobmV3Q29udGVudClcbiAgICBzZXRQYXN0ZWRDb250ZW50cyhwcmV2ID0+ICh7IC4uLnByZXYsIFtwYXN0ZUlkXTogbmV3Q29udGVudCB9KSlcbiAgfVxuXG4gIGNvbnN0IG9uUmVtb3ZlSW1hZ2UgPSB1c2VDYWxsYmFjaygoaWQ6IG51bWJlcikgPT4ge1xuICAgIHNldFBhc3RlZENvbnRlbnRzKHByZXYgPT4ge1xuICAgICAgY29uc3QgbmV4dCA9IHsgLi4ucHJldiB9XG4gICAgICBkZWxldGUgbmV4dFtpZF1cbiAgICAgIHJldHVybiBuZXh0XG4gICAgfSlcbiAgfSwgW10pXG5cbiAgY29uc3QgaW1hZ2VBdHRhY2htZW50cyA9IE9iamVjdC52YWx1ZXMocGFzdGVkQ29udGVudHMpLmZpbHRlcihcbiAgICBjID0+IGMudHlwZSA9PT0gJ2ltYWdlJyxcbiAgKVxuICBjb25zdCBoYXNJbWFnZXMgPSBpbWFnZUF0dGFjaG1lbnRzLmxlbmd0aCA+IDBcblxuICAvLyBUT0RPOiBEZWxldGUgdGhlIGJyYW5jaCBhZnRlciBtb3ZpbmcgdG8gVjJcbiAgLy8gVXNlIHRvb2wgbmFtZSB0byBkZXRlY3QgVjIgaW5zdGVhZCBvZiBjaGVja2luZyBpbnB1dC5wbGFuLCBiZWNhdXNlIFBSICMxMDM5NFxuICAvLyBpbmplY3RzIHBsYW4gY29udGVudCBpbnRvIGlucHV0LnBsYW4gZm9yIGhvb2tzL1NESywgd2hpY2ggYnJva2UgdGhlIG9sZCBkZXRlY3Rpb25cbiAgLy8gKHNlZSBpc3N1ZSAjMTA4NzgpXG4gIGNvbnN0IGlzVjIgPSB0b29sVXNlQ29uZmlybS50b29sLm5hbWUgPT09IEVYSVRfUExBTl9NT0RFX1YyX1RPT0xfTkFNRVxuICBjb25zdCBpbnB1dFBsYW4gPSBpc1YyXG4gICAgPyB1bmRlZmluZWRcbiAgICA6ICh0b29sVXNlQ29uZmlybS5pbnB1dC5wbGFuIGFzIHN0cmluZyB8IHVuZGVmaW5lZClcbiAgY29uc3QgcGxhbkZpbGVQYXRoID0gaXNWMiA/IGdldFBsYW5GaWxlUGF0aCgpIDogdW5kZWZpbmVkXG5cbiAgLy8gRXh0cmFjdCBhbGxvd2VkIHByb21wdHMgcmVxdWVzdGVkIGJ5IHRoZSBwbGFuIChBbnQtb25seSBmZWF0dXJlKVxuICBjb25zdCBhbGxvd2VkUHJvbXB0cyA9IHRvb2xVc2VDb25maXJtLmlucHV0LmFsbG93ZWRQcm9tcHRzIGFzXG4gICAgfCBBbGxvd2VkUHJvbXB0W11cbiAgICB8IHVuZGVmaW5lZFxuXG4gIC8vIEdldCB0aGUgcmF3IHBsYW4gdG8gY2hlY2sgaWYgaXQncyBlbXB0eVxuICBjb25zdCByYXdQbGFuID0gaW5wdXRQbGFuID8/IGdldFBsYW4oKVxuICBjb25zdCBpc0VtcHR5ID0gIXJhd1BsYW4gfHwgcmF3UGxhbi50cmltKCkgPT09ICcnXG5cbiAgLy8gQ2FwdHVyZSB0aGUgdmFyaWFudCBvbmNlIG9uIG1vdW50LiBHcm93dGhCb29rIHJlYWRzIGZyb20gYSBkaXNrIGNhY2hlXG4gIC8vIHNvIHRoZSB2YWx1ZSBpcyBzdGFibGUgYWNyb3NzIGEgc2luZ2xlIHBsYW5uaW5nIHNlc3Npb24uIHVuZGVmaW5lZCA9XG4gIC8vIGNvbnRyb2wgYXJtLiBUaGUgdmFyaWFudCBpcyBhIGZpeGVkIDMtdmFsdWUgZW51bSBvZiBzaG9ydCBsaXRlcmFscyxcbiAgLy8gbm90IHVzZXIgaW5wdXQuXG4gIGNvbnN0IFtwbGFuU3RydWN0dXJlVmFyaWFudF0gPSB1c2VTdGF0ZShcbiAgICAoKSA9PlxuICAgICAgKGdldFBld3RlckxlZGdlclZhcmlhbnQoKSA/P1xuICAgICAgICB1bmRlZmluZWQpIGFzIEFuYWx5dGljc01ldGFkYXRhX0lfVkVSSUZJRURfVEhJU19JU19OT1RfQ09ERV9PUl9GSUxFUEFUSFMsXG4gIClcblxuICBjb25zdCBbY3VycmVudFBsYW4sIHNldEN1cnJlbnRQbGFuXSA9IHVzZVN0YXRlKCgpID0+IHtcbiAgICBpZiAoaW5wdXRQbGFuKSByZXR1cm4gaW5wdXRQbGFuXG4gICAgY29uc3QgcGxhbiA9IGdldFBsYW4oKVxuICAgIHJldHVybiAoXG4gICAgICBwbGFuID8/ICdObyBwbGFuIGZvdW5kLiBQbGVhc2Ugd3JpdGUgeW91ciBwbGFuIHRvIHRoZSBwbGFuIGZpbGUgZmlyc3QuJ1xuICAgIClcbiAgfSlcbiAgY29uc3QgW3Nob3dTYXZlTWVzc2FnZSwgc2V0U2hvd1NhdmVNZXNzYWdlXSA9IHVzZVN0YXRlKGZhbHNlKVxuICAvLyBUcmFjayBDdHJsK0cgbG9jYWwgZWRpdHMgc28gdXBkYXRlZElucHV0IGNhbiBpbmNsdWRlIHRoZSBwbGFuICh0aGUgdG9vbFxuICAvLyBvbmx5IGVjaG9lcyB0aGUgcGxhbiBpbiB0b29sX3Jlc3VsdCB3aGVuIGlucHV0LnBsYW4gaXMgc2V0IOKAlCBvdGhlcndpc2VcbiAgLy8gdGhlIG1vZGVsIGFscmVhZHkgaGFzIGl0IGluIGNvbnRleHQgZnJvbSB3cml0aW5nIHRoZSBwbGFuIGZpbGUpLlxuICBjb25zdCBbcGxhbkVkaXRlZExvY2FsbHksIHNldFBsYW5FZGl0ZWRMb2NhbGx5XSA9IHVzZVN0YXRlKGZhbHNlKVxuXG4gIC8vIEF1dG8taGlkZSBzYXZlIG1lc3NhZ2UgYWZ0ZXIgNSBzZWNvbmRzXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKHNob3dTYXZlTWVzc2FnZSkge1xuICAgICAgY29uc3QgdGltZXIgPSBzZXRUaW1lb3V0KHNldFNob3dTYXZlTWVzc2FnZSwgNTAwMCwgZmFsc2UpXG4gICAgICByZXR1cm4gKCkgPT4gY2xlYXJUaW1lb3V0KHRpbWVyKVxuICAgIH1cbiAgfSwgW3Nob3dTYXZlTWVzc2FnZV0pXG5cbiAgLy8gSGFuZGxlIEN0cmwrRyB0byBlZGl0IHBsYW4gaW4gJEVESVRPUiwgU2hpZnQrVGFiIGZvciBhdXRvLWFjY2VwdCBlZGl0c1xuICBjb25zdCBoYW5kbGVLZXlEb3duID0gKGU6IEtleWJvYXJkRXZlbnQpOiB2b2lkID0+IHtcbiAgICBpZiAoZS5jdHJsICYmIGUua2V5ID09PSAnZycpIHtcbiAgICAgIGUucHJldmVudERlZmF1bHQoKVxuICAgICAgbG9nRXZlbnQoJ3Rlbmd1X3BsYW5fZXh0ZXJuYWxfZWRpdG9yX3VzZWQnLCB7fSlcblxuICAgICAgdm9pZCAoYXN5bmMgKCkgPT4ge1xuICAgICAgICBpZiAoaXNWMiAmJiBwbGFuRmlsZVBhdGgpIHtcbiAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBlZGl0RmlsZUluRWRpdG9yKHBsYW5GaWxlUGF0aClcbiAgICAgICAgICBpZiAocmVzdWx0LmVycm9yKSB7XG4gICAgICAgICAgICBhZGROb3RpZmljYXRpb24oe1xuICAgICAgICAgICAgICBrZXk6ICdleHRlcm5hbC1lZGl0b3ItZXJyb3InLFxuICAgICAgICAgICAgICB0ZXh0OiByZXN1bHQuZXJyb3IsXG4gICAgICAgICAgICAgIGNvbG9yOiAnd2FybmluZycsXG4gICAgICAgICAgICAgIHByaW9yaXR5OiAnaGlnaCcsXG4gICAgICAgICAgICB9KVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAocmVzdWx0LmNvbnRlbnQgIT09IG51bGwpIHtcbiAgICAgICAgICAgIGlmIChyZXN1bHQuY29udGVudCAhPT0gY3VycmVudFBsYW4pIHNldFBsYW5FZGl0ZWRMb2NhbGx5KHRydWUpXG4gICAgICAgICAgICBzZXRDdXJyZW50UGxhbihyZXN1bHQuY29udGVudClcbiAgICAgICAgICAgIHNldFNob3dTYXZlTWVzc2FnZSh0cnVlKVxuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBlZGl0UHJvbXB0SW5FZGl0b3IoY3VycmVudFBsYW4pXG4gICAgICAgICAgaWYgKHJlc3VsdC5lcnJvcikge1xuICAgICAgICAgICAgYWRkTm90aWZpY2F0aW9uKHtcbiAgICAgICAgICAgICAga2V5OiAnZXh0ZXJuYWwtZWRpdG9yLWVycm9yJyxcbiAgICAgICAgICAgICAgdGV4dDogcmVzdWx0LmVycm9yLFxuICAgICAgICAgICAgICBjb2xvcjogJ3dhcm5pbmcnLFxuICAgICAgICAgICAgICBwcmlvcml0eTogJ2hpZ2gnLFxuICAgICAgICAgICAgfSlcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHJlc3VsdC5jb250ZW50ICE9PSBudWxsICYmIHJlc3VsdC5jb250ZW50ICE9PSBjdXJyZW50UGxhbikge1xuICAgICAgICAgICAgc2V0Q3VycmVudFBsYW4ocmVzdWx0LmNvbnRlbnQpXG4gICAgICAgICAgICBzZXRTaG93U2F2ZU1lc3NhZ2UodHJ1ZSlcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pKClcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIC8vIFNoaWZ0K1RhYiBpbW1lZGlhdGVseSBzZWxlY3RzIFwiYXV0by1hY2NlcHQgZWRpdHNcIlxuICAgIGlmIChlLnNoaWZ0ICYmIGUua2V5ID09PSAndGFiJykge1xuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpXG4gICAgICB2b2lkIGhhbmRsZVJlc3BvbnNlKFxuICAgICAgICBzaG93Q2xlYXJDb250ZXh0ID8gJ3llcy1hY2NlcHQtZWRpdHMnIDogJ3llcy1hY2NlcHQtZWRpdHMta2VlcC1jb250ZXh0JyxcbiAgICAgIClcbiAgICAgIHJldHVyblxuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGZ1bmN0aW9uIGhhbmRsZVJlc3BvbnNlKHZhbHVlOiBSZXNwb25zZVZhbHVlKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgdHJpbW1lZEZlZWRiYWNrID0gcGxhbkZlZWRiYWNrLnRyaW0oKVxuICAgIGNvbnN0IGFjY2VwdEZlZWRiYWNrID0gdHJpbW1lZEZlZWRiYWNrIHx8IHVuZGVmaW5lZFxuXG4gICAgLy8gVWx0cmFwbGFuOiByZWplY3QgbG9jYWxseSwgdGVsZXBvcnQgdGhlIHBsYW4gdG8gQ0NSIGFzIGEgc2VlZCBkcmFmdC5cbiAgICAvLyBEaWFsb2cgZGlzbWlzc2VzIGltbWVkaWF0ZWx5IHNvIHRoZSBxdWVyeSBsb29wIHVuYmxvY2tzOyB0aGUgdGVsZXBvcnRcbiAgICAvLyBydW5zIGRldGFjaGVkIGFuZCBpdHMgbGF1bmNoIG1lc3NhZ2UgbGFuZHMgdmlhIHRoZSBjb21tYW5kIHF1ZXVlLlxuICAgIGlmICh2YWx1ZSA9PT0gJ3VsdHJhcGxhbicpIHtcbiAgICAgIGxvZ0V2ZW50KCd0ZW5ndV9wbGFuX2V4aXQnLCB7XG4gICAgICAgIHBsYW5MZW5ndGhDaGFyczogY3VycmVudFBsYW4ubGVuZ3RoLFxuICAgICAgICBvdXRjb21lOlxuICAgICAgICAgICd1bHRyYXBsYW4nIGFzIEFuYWx5dGljc01ldGFkYXRhX0lfVkVSSUZJRURfVEhJU19JU19OT1RfQ09ERV9PUl9GSUxFUEFUSFMsXG4gICAgICAgIGludGVydmlld1BoYXNlRW5hYmxlZDogaXNQbGFuTW9kZUludGVydmlld1BoYXNlRW5hYmxlZCgpLFxuICAgICAgICBwbGFuU3RydWN0dXJlVmFyaWFudCxcbiAgICAgIH0pXG4gICAgICBvbkRvbmUoKVxuICAgICAgb25SZWplY3QoKVxuICAgICAgdG9vbFVzZUNvbmZpcm0ub25SZWplY3QoXG4gICAgICAgICdQbGFuIGJlaW5nIHJlZmluZWQgdmlhIFVsdHJhcGxhbiDigJQgcGxlYXNlIHdhaXQgZm9yIHRoZSByZXN1bHQuJyxcbiAgICAgIClcbiAgICAgIHZvaWQgbGF1bmNoVWx0cmFwbGFuKHtcbiAgICAgICAgYmx1cmI6ICcnLFxuICAgICAgICBzZWVkUGxhbjogY3VycmVudFBsYW4sXG4gICAgICAgIGdldEFwcFN0YXRlOiBzdG9yZS5nZXRTdGF0ZSxcbiAgICAgICAgc2V0QXBwU3RhdGU6IHN0b3JlLnNldFN0YXRlLFxuICAgICAgICBzaWduYWw6IG5ldyBBYm9ydENvbnRyb2xsZXIoKS5zaWduYWwsXG4gICAgICB9KVxuICAgICAgICAudGhlbihtc2cgPT5cbiAgICAgICAgICBlbnF1ZXVlUGVuZGluZ05vdGlmaWNhdGlvbih7IHZhbHVlOiBtc2csIG1vZGU6ICd0YXNrLW5vdGlmaWNhdGlvbicgfSksXG4gICAgICAgIClcbiAgICAgICAgLmNhdGNoKGxvZ0Vycm9yKVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgLy8gVjE6IHBhc3MgcGxhbiBpbiBpbnB1dC4gVjI6IHBsYW4gaXMgb24gZGlzaywgYnV0IGlmIHRoZSB1c2VyIGVkaXRlZCBpdFxuICAgIC8vIHZpYSBDdHJsK0cgd2UgcGFzcyBpdCB0aHJvdWdoIHNvIHRoZSB0b29sIGVjaG9lcyB0aGUgZWRpdCBpbiB0b29sX3Jlc3VsdFxuICAgIC8vIChvdGhlcndpc2UgdGhlIG1vZGVsIG5ldmVyIHNlZXMgdGhlIHVzZXIncyBjaGFuZ2VzKS5cbiAgICBjb25zdCB1cGRhdGVkSW5wdXQgPSBpc1YyICYmICFwbGFuRWRpdGVkTG9jYWxseSA/IHt9IDogeyBwbGFuOiBjdXJyZW50UGxhbiB9XG5cbiAgICAvLyBJZiBhdXRvIHdhcyBhY3RpdmUgZHVyaW5nIHBsYW4gKGZyb20gYXV0byBtb2RlIG9yIG9wdC1pbikgYW5kIE5PVCBnb2luZ1xuICAgIC8vIHRvIGF1dG8sIGRlYWN0aXZhdGUgYXV0byArIHJlc3RvcmUgcGVybWlzc2lvbnMgKyBmaXJlIGV4aXQgYXR0YWNobWVudC5cbiAgICBpZiAoZmVhdHVyZSgnVFJBTlNDUklQVF9DTEFTU0lGSUVSJykpIHtcbiAgICAgIGNvbnN0IGdvaW5nVG9BdXRvID1cbiAgICAgICAgKHZhbHVlID09PSAneWVzLXJlc3VtZS1hdXRvLW1vZGUnIHx8XG4gICAgICAgICAgdmFsdWUgPT09ICd5ZXMtYXV0by1jbGVhci1jb250ZXh0JykgJiZcbiAgICAgICAgaXNBdXRvTW9kZUdhdGVFbmFibGVkKClcbiAgICAgIC8vIGlzQXV0b01vZGVBY3RpdmUoKSBpcyB0aGUgYXV0aG9yaXRhdGl2ZSBzaWduYWwg4oCUIHByZVBsYW5Nb2RlL1xuICAgICAgLy8gc3RyaXBwZWREYW5nZXJvdXNSdWxlcyBhcmUgc3RhbGUgYWZ0ZXIgdHJhbnNpdGlvblBsYW5BdXRvTW9kZVxuICAgICAgLy8gZGVhY3RpdmF0ZXMgbWlkLXBsYW4gKHdvdWxkIGNhdXNlIGR1cGxpY2F0ZSBleGl0IGF0dGFjaG1lbnQpLlxuICAgICAgY29uc3QgYXV0b1dhc1VzZWREdXJpbmdQbGFuID1cbiAgICAgICAgYXV0b01vZGVTdGF0ZU1vZHVsZT8uaXNBdXRvTW9kZUFjdGl2ZSgpID8/IGZhbHNlXG4gICAgICBpZiAodmFsdWUgIT09ICdubycgJiYgIWdvaW5nVG9BdXRvICYmIGF1dG9XYXNVc2VkRHVyaW5nUGxhbikge1xuICAgICAgICBhdXRvTW9kZVN0YXRlTW9kdWxlPy5zZXRBdXRvTW9kZUFjdGl2ZShmYWxzZSlcbiAgICAgICAgc2V0TmVlZHNBdXRvTW9kZUV4aXRBdHRhY2htZW50KHRydWUpXG4gICAgICAgIHNldEFwcFN0YXRlKHByZXYgPT4gKHtcbiAgICAgICAgICAuLi5wcmV2LFxuICAgICAgICAgIHRvb2xQZXJtaXNzaW9uQ29udGV4dDoge1xuICAgICAgICAgICAgLi4ucmVzdG9yZURhbmdlcm91c1Blcm1pc3Npb25zKHByZXYudG9vbFBlcm1pc3Npb25Db250ZXh0KSxcbiAgICAgICAgICAgIHByZVBsYW5Nb2RlOiB1bmRlZmluZWQsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSkpXG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gQ2xlYXItY29udGV4dCBvcHRpb25zOiBzZXQgcGVuZGluZyBwbGFuIGltcGxlbWVudGF0aW9uIGFuZCByZWplY3QgdGhlIGRpYWxvZ1xuICAgIC8vIFRoZSBSRVBMIHdpbGwgaGFuZGxlIGNvbnRleHQgY2xlYXIgYW5kIHRyaWdnZXIgYSBmcmVzaCBxdWVyeVxuICAgIC8vIEtlZXAtY29udGV4dCBvcHRpb25zIHNraXAgdGhpcyBibG9jayBhbmQgZ28gdGhyb3VnaCB0aGUgbm9ybWFsIGZsb3cgYmVsb3dcbiAgICBjb25zdCBpc1Jlc3VtZUF1dG9PcHRpb24gPSBmZWF0dXJlKCdUUkFOU0NSSVBUX0NMQVNTSUZJRVInKVxuICAgICAgPyB2YWx1ZSA9PT0gJ3llcy1yZXN1bWUtYXV0by1tb2RlJ1xuICAgICAgOiBmYWxzZVxuICAgIGNvbnN0IGlzS2VlcENvbnRleHRPcHRpb24gPVxuICAgICAgdmFsdWUgPT09ICd5ZXMtYWNjZXB0LWVkaXRzLWtlZXAtY29udGV4dCcgfHxcbiAgICAgIHZhbHVlID09PSAneWVzLWRlZmF1bHQta2VlcC1jb250ZXh0JyB8fFxuICAgICAgaXNSZXN1bWVBdXRvT3B0aW9uXG5cbiAgICBpZiAodmFsdWUgIT09ICdubycpIHtcbiAgICAgIGF1dG9OYW1lU2Vzc2lvbkZyb21QbGFuKGN1cnJlbnRQbGFuLCBzZXRBcHBTdGF0ZSwgIWlzS2VlcENvbnRleHRPcHRpb24pXG4gICAgfVxuXG4gICAgaWYgKHZhbHVlICE9PSAnbm8nICYmICFpc0tlZXBDb250ZXh0T3B0aW9uKSB7XG4gICAgICAvLyBEZXRlcm1pbmUgdGhlIHBlcm1pc3Npb24gbW9kZSBiYXNlZCBvbiB0aGUgc2VsZWN0ZWQgb3B0aW9uXG4gICAgICBsZXQgbW9kZTogUGVybWlzc2lvbk1vZGUgPSAnZGVmYXVsdCdcbiAgICAgIGlmICh2YWx1ZSA9PT0gJ3llcy1ieXBhc3MtcGVybWlzc2lvbnMnKSB7XG4gICAgICAgIG1vZGUgPSAnYnlwYXNzUGVybWlzc2lvbnMnXG4gICAgICB9IGVsc2UgaWYgKHZhbHVlID09PSAneWVzLWFjY2VwdC1lZGl0cycpIHtcbiAgICAgICAgbW9kZSA9ICdhY2NlcHRFZGl0cydcbiAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgIGZlYXR1cmUoJ1RSQU5TQ1JJUFRfQ0xBU1NJRklFUicpICYmXG4gICAgICAgIHZhbHVlID09PSAneWVzLWF1dG8tY2xlYXItY29udGV4dCcgJiZcbiAgICAgICAgaXNBdXRvTW9kZUdhdGVFbmFibGVkKClcbiAgICAgICkge1xuICAgICAgICAvLyBSRVBMJ3MgcHJvY2Vzc0luaXRpYWxNZXNzYWdlIGhhbmRsZXMgc3RyaXBEYW5nZXJvdXNQZXJtaXNzaW9ucyArIG1vZGUsXG4gICAgICAgIC8vIGJ1dCBkb2VzIE5PVCBzZXQgYXV0b01vZGVBY3RpdmUuIEdhdGUtb2ZmIGZhbGxzIHRocm91Z2ggdG8gJ2RlZmF1bHQnLlxuICAgICAgICBtb2RlID0gJ2F1dG8nXG4gICAgICAgIGF1dG9Nb2RlU3RhdGVNb2R1bGU/LnNldEF1dG9Nb2RlQWN0aXZlKHRydWUpXG4gICAgICB9XG5cbiAgICAgIC8vIExvZyBwbGFuIGV4aXQgZXZlbnRcbiAgICAgIGxvZ0V2ZW50KCd0ZW5ndV9wbGFuX2V4aXQnLCB7XG4gICAgICAgIHBsYW5MZW5ndGhDaGFyczogY3VycmVudFBsYW4ubGVuZ3RoLFxuICAgICAgICBvdXRjb21lOlxuICAgICAgICAgIHZhbHVlIGFzIEFuYWx5dGljc01ldGFkYXRhX0lfVkVSSUZJRURfVEhJU19JU19OT1RfQ09ERV9PUl9GSUxFUEFUSFMsXG4gICAgICAgIGNsZWFyQ29udGV4dDogdHJ1ZSxcbiAgICAgICAgaW50ZXJ2aWV3UGhhc2VFbmFibGVkOiBpc1BsYW5Nb2RlSW50ZXJ2aWV3UGhhc2VFbmFibGVkKCksXG4gICAgICAgIHBsYW5TdHJ1Y3R1cmVWYXJpYW50LFxuICAgICAgICBoYXNGZWVkYmFjazogISFhY2NlcHRGZWVkYmFjayxcbiAgICAgIH0pXG5cbiAgICAgIC8vIFNldCBpbml0aWFsIG1lc3NhZ2UgLSBSRVBMIHdpbGwgaGFuZGxlIGNvbnRleHQgY2xlYXIgYW5kIGZyZXNoIHF1ZXJ5XG4gICAgICAvLyBBZGQgdmVyaWZpY2F0aW9uIGluc3RydWN0aW9uIGlmIHRoZSBmZWF0dXJlIGlzIGVuYWJsZWRcbiAgICAgIC8vIERlYWQgY29kZSBlbGltaW5hdGlvbjogQ0xBVURFX0NPREVfVkVSSUZZX1BMQU49J2ZhbHNlJyBpbiBleHRlcm5hbCBidWlsZHMsIHNvID09PSAndHJ1ZScgY2hlY2sgYWxsb3dzIEJ1biB0byBlbGltaW5hdGUgdGhlIHN0cmluZ1xuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uSW5zdHJ1Y3Rpb24gPVxuICAgICAgICB1bmRlZmluZWQgPT09ICd0cnVlJ1xuICAgICAgICAgID8gYFxcblxcbklNUE9SVEFOVDogV2hlbiB5b3UgaGF2ZSBmaW5pc2hlZCBpbXBsZW1lbnRpbmcgdGhlIHBsYW4sIHlvdSBNVVNUIGNhbGwgdGhlIFwiVmVyaWZ5UGxhbkV4ZWN1dGlvblwiIHRvb2wgZGlyZWN0bHkgKE5PVCB0aGUgJHtBR0VOVF9UT09MX05BTUV9IHRvb2wgb3IgYW4gYWdlbnQpIHRvIHRyaWdnZXIgYmFja2dyb3VuZCB2ZXJpZmljYXRpb24uYFxuICAgICAgICAgIDogJydcblxuICAgICAgLy8gQ2FwdHVyZSB0aGUgdHJhbnNjcmlwdCBwYXRoIGJlZm9yZSBjb250ZXh0IGlzIGNsZWFyZWQgKHNlc3Npb24gSUQgd2lsbCBiZSByZWdlbmVyYXRlZClcbiAgICAgIGNvbnN0IHRyYW5zY3JpcHRQYXRoID0gZ2V0VHJhbnNjcmlwdFBhdGgoKVxuICAgICAgY29uc3QgdHJhbnNjcmlwdEhpbnQgPSBgXFxuXFxuSWYgeW91IG5lZWQgc3BlY2lmaWMgZGV0YWlscyBmcm9tIGJlZm9yZSBleGl0aW5nIHBsYW4gbW9kZSAobGlrZSBleGFjdCBjb2RlIHNuaXBwZXRzLCBlcnJvciBtZXNzYWdlcywgb3IgY29udGVudCB5b3UgZ2VuZXJhdGVkKSwgcmVhZCB0aGUgZnVsbCB0cmFuc2NyaXB0IGF0OiAke3RyYW5zY3JpcHRQYXRofWBcblxuICAgICAgY29uc3QgdGVhbUhpbnQgPSBpc0FnZW50U3dhcm1zRW5hYmxlZCgpXG4gICAgICAgID8gYFxcblxcbklmIHRoaXMgcGxhbiBjYW4gYmUgYnJva2VuIGRvd24gaW50byBtdWx0aXBsZSBpbmRlcGVuZGVudCB0YXNrcywgY29uc2lkZXIgdXNpbmcgdGhlICR7VEVBTV9DUkVBVEVfVE9PTF9OQU1FfSB0b29sIHRvIGNyZWF0ZSBhIHRlYW0gYW5kIHBhcmFsbGVsaXplIHRoZSB3b3JrLmBcbiAgICAgICAgOiAnJ1xuXG4gICAgICBjb25zdCBmZWVkYmFja1N1ZmZpeCA9IGFjY2VwdEZlZWRiYWNrXG4gICAgICAgID8gYFxcblxcblVzZXIgZmVlZGJhY2sgb24gdGhpcyBwbGFuOiAke2FjY2VwdEZlZWRiYWNrfWBcbiAgICAgICAgOiAnJ1xuXG4gICAgICBzZXRBcHBTdGF0ZShwcmV2ID0+ICh7XG4gICAgICAgIC4uLnByZXYsXG4gICAgICAgIGluaXRpYWxNZXNzYWdlOiB7XG4gICAgICAgICAgbWVzc2FnZToge1xuICAgICAgICAgICAgLi4uY3JlYXRlVXNlck1lc3NhZ2Uoe1xuICAgICAgICAgICAgICBjb250ZW50OiBgSW1wbGVtZW50IHRoZSBmb2xsb3dpbmcgcGxhbjpcXG5cXG4ke2N1cnJlbnRQbGFufSR7dmVyaWZpY2F0aW9uSW5zdHJ1Y3Rpb259JHt0cmFuc2NyaXB0SGludH0ke3RlYW1IaW50fSR7ZmVlZGJhY2tTdWZmaXh9YCxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgcGxhbkNvbnRlbnQ6IGN1cnJlbnRQbGFuLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgY2xlYXJDb250ZXh0OiB0cnVlLFxuICAgICAgICAgIG1vZGUsXG4gICAgICAgICAgYWxsb3dlZFByb21wdHMsXG4gICAgICAgIH0sXG4gICAgICB9KSlcblxuICAgICAgc2V0SGFzRXhpdGVkUGxhbk1vZGUodHJ1ZSlcbiAgICAgIG9uRG9uZSgpXG4gICAgICBvblJlamVjdCgpXG4gICAgICAvLyBSZWplY3QgdGhlIHRvb2wgdXNlIHRvIHVuYmxvY2sgdGhlIHF1ZXJ5IGxvb3BcbiAgICAgIC8vIFRoZSBSRVBMIHdpbGwgc2VlIHBlbmRpbmdJbml0aWFsUXVlcnkgYW5kIHRyaWdnZXIgZnJlc2ggcXVlcnlcbiAgICAgIHRvb2xVc2VDb25maXJtLm9uUmVqZWN0KClcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIC8vIEhhbmRsZSBhdXRvIGtlZXAtY29udGV4dCBvcHRpb24g4oCUIG5lZWRzIHNwZWNpYWwgaGFuZGxpbmcgYmVjYXVzZVxuICAgIC8vIGJ1aWxkUGVybWlzc2lvblVwZGF0ZXMgbWFwcyBhdXRvIHRvICdkZWZhdWx0JyB2aWEgdG9FeHRlcm5hbFBlcm1pc3Npb25Nb2RlLlxuICAgIC8vIFdlIHNldCB0aGUgbW9kZSBkaXJlY3RseSB2aWEgc2V0QXBwU3RhdGUgYW5kIHN5bmMgdGhlIGJvb3RzdHJhcCBzdGF0ZS5cbiAgICBpZiAoXG4gICAgICBmZWF0dXJlKCdUUkFOU0NSSVBUX0NMQVNTSUZJRVInKSAmJlxuICAgICAgdmFsdWUgPT09ICd5ZXMtcmVzdW1lLWF1dG8tbW9kZScgJiZcbiAgICAgIGlzQXV0b01vZGVHYXRlRW5hYmxlZCgpXG4gICAgKSB7XG4gICAgICBsb2dFdmVudCgndGVuZ3VfcGxhbl9leGl0Jywge1xuICAgICAgICBwbGFuTGVuZ3RoQ2hhcnM6IGN1cnJlbnRQbGFuLmxlbmd0aCxcbiAgICAgICAgb3V0Y29tZTpcbiAgICAgICAgICB2YWx1ZSBhcyBBbmFseXRpY3NNZXRhZGF0YV9JX1ZFUklGSUVEX1RISVNfSVNfTk9UX0NPREVfT1JfRklMRVBBVEhTLFxuICAgICAgICBjbGVhckNvbnRleHQ6IGZhbHNlLFxuICAgICAgICBpbnRlcnZpZXdQaGFzZUVuYWJsZWQ6IGlzUGxhbk1vZGVJbnRlcnZpZXdQaGFzZUVuYWJsZWQoKSxcbiAgICAgICAgcGxhblN0cnVjdHVyZVZhcmlhbnQsXG4gICAgICAgIGhhc0ZlZWRiYWNrOiAhIWFjY2VwdEZlZWRiYWNrLFxuICAgICAgfSlcbiAgICAgIHNldEhhc0V4aXRlZFBsYW5Nb2RlKHRydWUpXG4gICAgICBzZXROZWVkc1BsYW5Nb2RlRXhpdEF0dGFjaG1lbnQodHJ1ZSlcbiAgICAgIGF1dG9Nb2RlU3RhdGVNb2R1bGU/LnNldEF1dG9Nb2RlQWN0aXZlKHRydWUpXG4gICAgICBzZXRBcHBTdGF0ZShwcmV2ID0+ICh7XG4gICAgICAgIC4uLnByZXYsXG4gICAgICAgIHRvb2xQZXJtaXNzaW9uQ29udGV4dDogc3RyaXBEYW5nZXJvdXNQZXJtaXNzaW9uc0ZvckF1dG9Nb2RlKHtcbiAgICAgICAgICAuLi5wcmV2LnRvb2xQZXJtaXNzaW9uQ29udGV4dCxcbiAgICAgICAgICBtb2RlOiAnYXV0bycsXG4gICAgICAgICAgcHJlUGxhbk1vZGU6IHVuZGVmaW5lZCxcbiAgICAgICAgfSksXG4gICAgICB9KSlcbiAgICAgIG9uRG9uZSgpXG4gICAgICB0b29sVXNlQ29uZmlybS5vbkFsbG93KHVwZGF0ZWRJbnB1dCwgW10sIGFjY2VwdEZlZWRiYWNrKVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgLy8gSGFuZGxlIGtlZXAtY29udGV4dCBvcHRpb25zIChnb2VzIHRocm91Z2ggbm9ybWFsIG9uQWxsb3cgZmxvdylcbiAgICAvLyB5ZXMtcmVzdW1lLWF1dG8tbW9kZSBmYWxscyB0aHJvdWdoIGhlcmUgd2hlbiB0aGUgYXV0byBtb2RlIGdhdGUgaXNcbiAgICAvLyBkaXNhYmxlZCAoZS5nLiBjaXJjdWl0IGJyZWFrZXIgZmlyZWQgYWZ0ZXIgdGhlIGRpYWxvZyByZW5kZXJlZCkuXG4gICAgLy8gV2l0aG91dCB0aGlzIGZhbGxiYWNrIHRoZSBmdW5jdGlvbiB3b3VsZCByZXR1cm4gd2l0aG91dCByZXNvbHZpbmcgdGhlXG4gICAgLy8gZGlhbG9nLCBsZWF2aW5nIHRoZSBxdWVyeSBsb29wIGJsb2NrZWQgYW5kIHNhZmV0eSBzdGF0ZSBjb3JydXB0ZWQuXG4gICAgY29uc3Qga2VlcENvbnRleHRNb2RlczogUmVjb3JkPHN0cmluZywgUGVybWlzc2lvbk1vZGU+ID0ge1xuICAgICAgJ3llcy1hY2NlcHQtZWRpdHMta2VlcC1jb250ZXh0JzpcbiAgICAgICAgdG9vbFBlcm1pc3Npb25Db250ZXh0LmlzQnlwYXNzUGVybWlzc2lvbnNNb2RlQXZhaWxhYmxlXG4gICAgICAgICAgPyAnYnlwYXNzUGVybWlzc2lvbnMnXG4gICAgICAgICAgOiAnYWNjZXB0RWRpdHMnLFxuICAgICAgJ3llcy1kZWZhdWx0LWtlZXAtY29udGV4dCc6ICdkZWZhdWx0JyxcbiAgICAgIC4uLihmZWF0dXJlKCdUUkFOU0NSSVBUX0NMQVNTSUZJRVInKVxuICAgICAgICA/IHsgJ3llcy1yZXN1bWUtYXV0by1tb2RlJzogJ2RlZmF1bHQnIGFzIGNvbnN0IH1cbiAgICAgICAgOiB7fSksXG4gICAgfVxuICAgIGNvbnN0IGtlZXBDb250ZXh0TW9kZSA9IGtlZXBDb250ZXh0TW9kZXNbdmFsdWVdXG4gICAgaWYgKGtlZXBDb250ZXh0TW9kZSkge1xuICAgICAgbG9nRXZlbnQoJ3Rlbmd1X3BsYW5fZXhpdCcsIHtcbiAgICAgICAgcGxhbkxlbmd0aENoYXJzOiBjdXJyZW50UGxhbi5sZW5ndGgsXG4gICAgICAgIG91dGNvbWU6XG4gICAgICAgICAgdmFsdWUgYXMgQW5hbHl0aWNzTWV0YWRhdGFfSV9WRVJJRklFRF9USElTX0lTX05PVF9DT0RFX09SX0ZJTEVQQVRIUyxcbiAgICAgICAgY2xlYXJDb250ZXh0OiBmYWxzZSxcbiAgICAgICAgaW50ZXJ2aWV3UGhhc2VFbmFibGVkOiBpc1BsYW5Nb2RlSW50ZXJ2aWV3UGhhc2VFbmFibGVkKCksXG4gICAgICAgIHBsYW5TdHJ1Y3R1cmVWYXJpYW50LFxuICAgICAgICBoYXNGZWVkYmFjazogISFhY2NlcHRGZWVkYmFjayxcbiAgICAgIH0pXG4gICAgICBzZXRIYXNFeGl0ZWRQbGFuTW9kZSh0cnVlKVxuICAgICAgc2V0TmVlZHNQbGFuTW9kZUV4aXRBdHRhY2htZW50KHRydWUpXG4gICAgICBvbkRvbmUoKVxuICAgICAgdG9vbFVzZUNvbmZpcm0ub25BbGxvdyhcbiAgICAgICAgdXBkYXRlZElucHV0LFxuICAgICAgICBidWlsZFBlcm1pc3Npb25VcGRhdGVzKGtlZXBDb250ZXh0TW9kZSwgYWxsb3dlZFByb21wdHMpLFxuICAgICAgICBhY2NlcHRGZWVkYmFjayxcbiAgICAgIClcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIC8vIEhhbmRsZSBzdGFuZGFyZCBhcHByb3ZhbCBvcHRpb25zXG4gICAgY29uc3Qgc3RhbmRhcmRNb2RlczogUmVjb3JkPHN0cmluZywgUGVybWlzc2lvbk1vZGU+ID0ge1xuICAgICAgJ3llcy1ieXBhc3MtcGVybWlzc2lvbnMnOiAnYnlwYXNzUGVybWlzc2lvbnMnLFxuICAgICAgJ3llcy1hY2NlcHQtZWRpdHMnOiAnYWNjZXB0RWRpdHMnLFxuICAgIH1cbiAgICBjb25zdCBzdGFuZGFyZE1vZGUgPSBzdGFuZGFyZE1vZGVzW3ZhbHVlXVxuICAgIGlmIChzdGFuZGFyZE1vZGUpIHtcbiAgICAgIGxvZ0V2ZW50KCd0ZW5ndV9wbGFuX2V4aXQnLCB7XG4gICAgICAgIHBsYW5MZW5ndGhDaGFyczogY3VycmVudFBsYW4ubGVuZ3RoLFxuICAgICAgICBvdXRjb21lOlxuICAgICAgICAgIHZhbHVlIGFzIEFuYWx5dGljc01ldGFkYXRhX0lfVkVSSUZJRURfVEhJU19JU19OT1RfQ09ERV9PUl9GSUxFUEFUSFMsXG4gICAgICAgIGludGVydmlld1BoYXNlRW5hYmxlZDogaXNQbGFuTW9kZUludGVydmlld1BoYXNlRW5hYmxlZCgpLFxuICAgICAgICBwbGFuU3RydWN0dXJlVmFyaWFudCxcbiAgICAgICAgaGFzRmVlZGJhY2s6ICEhYWNjZXB0RmVlZGJhY2ssXG4gICAgICB9KVxuICAgICAgc2V0SGFzRXhpdGVkUGxhbk1vZGUodHJ1ZSlcbiAgICAgIHNldE5lZWRzUGxhbk1vZGVFeGl0QXR0YWNobWVudCh0cnVlKVxuICAgICAgb25Eb25lKClcbiAgICAgIHRvb2xVc2VDb25maXJtLm9uQWxsb3coXG4gICAgICAgIHVwZGF0ZWRJbnB1dCxcbiAgICAgICAgYnVpbGRQZXJtaXNzaW9uVXBkYXRlcyhzdGFuZGFyZE1vZGUsIGFsbG93ZWRQcm9tcHRzKSxcbiAgICAgICAgYWNjZXB0RmVlZGJhY2ssXG4gICAgICApXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICAvLyBIYW5kbGUgJ25vJyAtIHN0YXkgaW4gcGxhbiBtb2RlXG4gICAgaWYgKHZhbHVlID09PSAnbm8nKSB7XG4gICAgICBpZiAoIXRyaW1tZWRGZWVkYmFjayAmJiAhaGFzSW1hZ2VzKSB7XG4gICAgICAgIC8vIE5vIGZlZWRiYWNrIHlldCAtIHVzZXIgaXMgc3RpbGwgb24gdGhlIGlucHV0IGZpZWxkXG4gICAgICAgIHJldHVyblxuICAgICAgfVxuXG4gICAgICBsb2dFdmVudCgndGVuZ3VfcGxhbl9leGl0Jywge1xuICAgICAgICBwbGFuTGVuZ3RoQ2hhcnM6IGN1cnJlbnRQbGFuLmxlbmd0aCxcbiAgICAgICAgb3V0Y29tZTpcbiAgICAgICAgICAnbm8nIGFzIEFuYWx5dGljc01ldGFkYXRhX0lfVkVSSUZJRURfVEhJU19JU19OT1RfQ09ERV9PUl9GSUxFUEFUSFMsXG4gICAgICAgIGludGVydmlld1BoYXNlRW5hYmxlZDogaXNQbGFuTW9kZUludGVydmlld1BoYXNlRW5hYmxlZCgpLFxuICAgICAgICBwbGFuU3RydWN0dXJlVmFyaWFudCxcbiAgICAgIH0pXG5cbiAgICAgIC8vIENvbnZlcnQgcGFzdGVkIGltYWdlcyB0byBJbWFnZUJsb2NrUGFyYW1bXSB3aXRoIHJlc2l6aW5nXG4gICAgICBsZXQgaW1hZ2VCbG9ja3M6IEltYWdlQmxvY2tQYXJhbVtdIHwgdW5kZWZpbmVkXG4gICAgICBpZiAoaGFzSW1hZ2VzKSB7XG4gICAgICAgIGltYWdlQmxvY2tzID0gYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICAgICAgaW1hZ2VBdHRhY2htZW50cy5tYXAoYXN5bmMgaW1nID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGJsb2NrOiBJbWFnZUJsb2NrUGFyYW0gPSB7XG4gICAgICAgICAgICAgIHR5cGU6ICdpbWFnZScsXG4gICAgICAgICAgICAgIHNvdXJjZToge1xuICAgICAgICAgICAgICAgIHR5cGU6ICdiYXNlNjQnLFxuICAgICAgICAgICAgICAgIG1lZGlhX3R5cGU6IChpbWcubWVkaWFUeXBlIHx8XG4gICAgICAgICAgICAgICAgICAnaW1hZ2UvcG5nJykgYXMgQmFzZTY0SW1hZ2VTb3VyY2VbJ21lZGlhX3R5cGUnXSxcbiAgICAgICAgICAgICAgICBkYXRhOiBpbWcuY29udGVudCxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHJlc2l6ZWQgPSBhd2FpdCBtYXliZVJlc2l6ZUFuZERvd25zYW1wbGVJbWFnZUJsb2NrKGJsb2NrKVxuICAgICAgICAgICAgcmV0dXJuIHJlc2l6ZWQuYmxvY2tcbiAgICAgICAgICB9KSxcbiAgICAgICAgKVxuICAgICAgfVxuXG4gICAgICBvbkRvbmUoKVxuICAgICAgb25SZWplY3QoKVxuICAgICAgdG9vbFVzZUNvbmZpcm0ub25SZWplY3QoXG4gICAgICAgIHRyaW1tZWRGZWVkYmFjayB8fCAoaGFzSW1hZ2VzID8gJyhTZWUgYXR0YWNoZWQgaW1hZ2UpJyA6IHVuZGVmaW5lZCksXG4gICAgICAgIGltYWdlQmxvY2tzICYmIGltYWdlQmxvY2tzLmxlbmd0aCA+IDAgPyBpbWFnZUJsb2NrcyA6IHVuZGVmaW5lZCxcbiAgICAgIClcbiAgICB9XG4gIH1cblxuICBjb25zdCBlZGl0b3IgPSBnZXRFeHRlcm5hbEVkaXRvcigpXG4gIGNvbnN0IGVkaXRvck5hbWUgPSBlZGl0b3IgPyB0b0lERURpc3BsYXlOYW1lKGVkaXRvcikgOiBudWxsXG5cbiAgLy8gU3RpY2t5IGZvb3Rlcjogd2hlbiBzZXRTdGlja3lGb290ZXIgaXMgcHJvdmlkZWQgKGZ1bGxzY3JlZW4gbW9kZSksIHRoZVxuICAvLyBTZWxlY3Qgb3B0aW9ucyByZW5kZXIgaW4gRnVsbHNjcmVlbkxheW91dCdzIGBib3R0b21gIHNsb3Qgc28gdGhleSBzdGF5XG4gIC8vIHZpc2libGUgd2hpbGUgdGhlIHVzZXIgc2Nyb2xscyB0aHJvdWdoIGEgbG9uZyBwbGFuLiBoYW5kbGVSZXNwb25zZSBpc1xuICAvLyB3cmFwcGVkIGluIGEgcmVmIHNvIHRoZSBKU1ggKHNldCBvbmNlIHBlciBvcHRpb25zL2ltYWdlcyBjaGFuZ2UpIGNhbiBjYWxsXG4gIC8vIHRoZSBsYXRlc3QgY2xvc3VyZSB3aXRob3V0IHJlLXJlZ2lzdGVyaW5nIG9uIGV2ZXJ5IGtleXN0cm9rZS4gUmVhY3RcbiAgLy8gcmVjb25jaWxlcyB0aGUgc3RpY2t5LWZvb3RlciBTZWxlY3QgYnkgdHlwZSwgcHJlc2VydmluZyBmb2N1cy9pbnB1dCBzdGF0ZS5cbiAgY29uc3QgaGFuZGxlUmVzcG9uc2VSZWYgPSB1c2VSZWYoaGFuZGxlUmVzcG9uc2UpXG4gIGhhbmRsZVJlc3BvbnNlUmVmLmN1cnJlbnQgPSBoYW5kbGVSZXNwb25zZVxuICBjb25zdCBoYW5kbGVDYW5jZWxSZWYgPSB1c2VSZWY8KCkgPT4gdm9pZD4odW5kZWZpbmVkKVxuICBoYW5kbGVDYW5jZWxSZWYuY3VycmVudCA9ICgpID0+IHtcbiAgICBsb2dFdmVudCgndGVuZ3VfcGxhbl9leGl0Jywge1xuICAgICAgcGxhbkxlbmd0aENoYXJzOiBjdXJyZW50UGxhbi5sZW5ndGgsXG4gICAgICBvdXRjb21lOlxuICAgICAgICAnbm8nIGFzIEFuYWx5dGljc01ldGFkYXRhX0lfVkVSSUZJRURfVEhJU19JU19OT1RfQ09ERV9PUl9GSUxFUEFUSFMsXG4gICAgICBpbnRlcnZpZXdQaGFzZUVuYWJsZWQ6IGlzUGxhbk1vZGVJbnRlcnZpZXdQaGFzZUVuYWJsZWQoKSxcbiAgICAgIHBsYW5TdHJ1Y3R1cmVWYXJpYW50LFxuICAgIH0pXG4gICAgb25Eb25lKClcbiAgICBvblJlamVjdCgpXG4gICAgdG9vbFVzZUNvbmZpcm0ub25SZWplY3QoKVxuICB9XG4gIGNvbnN0IHVzZVN0aWNreUZvb3RlciA9ICFpc0VtcHR5ICYmICEhc2V0U3RpY2t5Rm9vdGVyXG4gIHVzZUxheW91dEVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKCF1c2VTdGlja3lGb290ZXIpIHJldHVyblxuICAgIHNldFN0aWNreUZvb3RlcihcbiAgICAgIDxCb3hcbiAgICAgICAgZmxleERpcmVjdGlvbj1cImNvbHVtblwiXG4gICAgICAgIGJvcmRlclN0eWxlPVwicm91bmRcIlxuICAgICAgICBib3JkZXJDb2xvcj1cInBsYW5Nb2RlXCJcbiAgICAgICAgYm9yZGVyTGVmdD17ZmFsc2V9XG4gICAgICAgIGJvcmRlclJpZ2h0PXtmYWxzZX1cbiAgICAgICAgYm9yZGVyQm90dG9tPXtmYWxzZX1cbiAgICAgICAgcGFkZGluZ1g9ezF9XG4gICAgICA+XG4gICAgICAgIDxUZXh0IGRpbUNvbG9yPldvdWxkIHlvdSBsaWtlIHRvIHByb2NlZWQ/PC9UZXh0PlxuICAgICAgICA8Qm94IG1hcmdpblRvcD17MX0+XG4gICAgICAgICAgPFNlbGVjdFxuICAgICAgICAgICAgb3B0aW9ucz17b3B0aW9uc31cbiAgICAgICAgICAgIG9uQ2hhbmdlPXt2ID0+IHZvaWQgaGFuZGxlUmVzcG9uc2VSZWYuY3VycmVudCh2KX1cbiAgICAgICAgICAgIG9uQ2FuY2VsPXsoKSA9PiBoYW5kbGVDYW5jZWxSZWYuY3VycmVudD8uKCl9XG4gICAgICAgICAgICBvbkltYWdlUGFzdGU9e29uSW1hZ2VQYXN0ZX1cbiAgICAgICAgICAgIHBhc3RlZENvbnRlbnRzPXtwYXN0ZWRDb250ZW50c31cbiAgICAgICAgICAgIG9uUmVtb3ZlSW1hZ2U9e29uUmVtb3ZlSW1hZ2V9XG4gICAgICAgICAgLz5cbiAgICAgICAgPC9Cb3g+XG4gICAgICAgIHtlZGl0b3JOYW1lICYmIChcbiAgICAgICAgICA8Qm94IGZsZXhEaXJlY3Rpb249XCJyb3dcIiBnYXA9ezF9IG1hcmdpblRvcD17MX0+XG4gICAgICAgICAgICA8VGV4dCBkaW1Db2xvcj5jdHJsLWcgdG8gZWRpdCBpbiA8L1RleHQ+XG4gICAgICAgICAgICA8VGV4dCBib2xkIGRpbUNvbG9yPlxuICAgICAgICAgICAgICB7ZWRpdG9yTmFtZX1cbiAgICAgICAgICAgIDwvVGV4dD5cbiAgICAgICAgICAgIHtpc1YyICYmIHBsYW5GaWxlUGF0aCAmJiAoXG4gICAgICAgICAgICAgIDxUZXh0IGRpbUNvbG9yPiDCtyB7Z2V0RGlzcGxheVBhdGgocGxhbkZpbGVQYXRoKX08L1RleHQ+XG4gICAgICAgICAgICApfVxuICAgICAgICAgICAge3Nob3dTYXZlTWVzc2FnZSAmJiAoXG4gICAgICAgICAgICAgIDw+XG4gICAgICAgICAgICAgICAgPFRleHQgZGltQ29sb3I+eycgwrcgJ308L1RleHQ+XG4gICAgICAgICAgICAgICAgPFRleHQgY29sb3I9XCJzdWNjZXNzXCI+e2ZpZ3VyZXMudGlja31QbGFuIHNhdmVkITwvVGV4dD5cbiAgICAgICAgICAgICAgPC8+XG4gICAgICAgICAgICApfVxuICAgICAgICAgIDwvQm94PlxuICAgICAgICApfVxuICAgICAgPC9Cb3g+LFxuICAgIClcbiAgICByZXR1cm4gKCkgPT4gc2V0U3RpY2t5Rm9vdGVyKG51bGwpXG4gICAgLy8gb25JbWFnZVBhc3RlL29uUmVtb3ZlSW1hZ2UgYXJlIHN0YWJsZSAodXNlQ2FsbGJhY2svdXNlUmVmLWJhY2tlZCBhYm92ZSlcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcmVhY3QtaG9va3MvZXhoYXVzdGl2ZS1kZXBzXG4gIH0sIFtcbiAgICB1c2VTdGlja3lGb290ZXIsXG4gICAgc2V0U3RpY2t5Rm9vdGVyLFxuICAgIG9wdGlvbnMsXG4gICAgcGFzdGVkQ29udGVudHMsXG4gICAgZWRpdG9yTmFtZSxcbiAgICBpc1YyLFxuICAgIHBsYW5GaWxlUGF0aCxcbiAgICBzaG93U2F2ZU1lc3NhZ2UsXG4gIF0pXG5cbiAgLy8gU2ltcGxpZmllZCBVSSBmb3IgZW1wdHkgcGxhbnNcbiAgaWYgKGlzRW1wdHkpIHtcbiAgICBmdW5jdGlvbiBoYW5kbGVFbXB0eVBsYW5SZXNwb25zZSh2YWx1ZTogJ3llcycgfCAnbm8nKTogdm9pZCB7XG4gICAgICBpZiAodmFsdWUgPT09ICd5ZXMnKSB7XG4gICAgICAgIGxvZ0V2ZW50KCd0ZW5ndV9wbGFuX2V4aXQnLCB7XG4gICAgICAgICAgcGxhbkxlbmd0aENoYXJzOiAwLFxuICAgICAgICAgIG91dGNvbWU6XG4gICAgICAgICAgICAneWVzLWRlZmF1bHQnIGFzIEFuYWx5dGljc01ldGFkYXRhX0lfVkVSSUZJRURfVEhJU19JU19OT1RfQ09ERV9PUl9GSUxFUEFUSFMsXG4gICAgICAgICAgaW50ZXJ2aWV3UGhhc2VFbmFibGVkOiBpc1BsYW5Nb2RlSW50ZXJ2aWV3UGhhc2VFbmFibGVkKCksXG4gICAgICAgICAgcGxhblN0cnVjdHVyZVZhcmlhbnQsXG4gICAgICAgIH0pXG4gICAgICAgIGlmIChmZWF0dXJlKCdUUkFOU0NSSVBUX0NMQVNTSUZJRVInKSkge1xuICAgICAgICAgIGNvbnN0IGF1dG9XYXNVc2VkRHVyaW5nUGxhbiA9XG4gICAgICAgICAgICBhdXRvTW9kZVN0YXRlTW9kdWxlPy5pc0F1dG9Nb2RlQWN0aXZlKCkgPz8gZmFsc2VcbiAgICAgICAgICBpZiAoYXV0b1dhc1VzZWREdXJpbmdQbGFuKSB7XG4gICAgICAgICAgICBhdXRvTW9kZVN0YXRlTW9kdWxlPy5zZXRBdXRvTW9kZUFjdGl2ZShmYWxzZSlcbiAgICAgICAgICAgIHNldE5lZWRzQXV0b01vZGVFeGl0QXR0YWNobWVudCh0cnVlKVxuICAgICAgICAgICAgc2V0QXBwU3RhdGUocHJldiA9PiAoe1xuICAgICAgICAgICAgICAuLi5wcmV2LFxuICAgICAgICAgICAgICB0b29sUGVybWlzc2lvbkNvbnRleHQ6IHtcbiAgICAgICAgICAgICAgICAuLi5yZXN0b3JlRGFuZ2Vyb3VzUGVybWlzc2lvbnMocHJldi50b29sUGVybWlzc2lvbkNvbnRleHQpLFxuICAgICAgICAgICAgICAgIHByZVBsYW5Nb2RlOiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9KSlcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgc2V0SGFzRXhpdGVkUGxhbk1vZGUodHJ1ZSlcbiAgICAgICAgc2V0TmVlZHNQbGFuTW9kZUV4aXRBdHRhY2htZW50KHRydWUpXG4gICAgICAgIG9uRG9uZSgpXG4gICAgICAgIHRvb2xVc2VDb25maXJtLm9uQWxsb3coe30sIFtcbiAgICAgICAgICB7IHR5cGU6ICdzZXRNb2RlJywgbW9kZTogJ2RlZmF1bHQnLCBkZXN0aW5hdGlvbjogJ3Nlc3Npb24nIH0sXG4gICAgICAgIF0pXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsb2dFdmVudCgndGVuZ3VfcGxhbl9leGl0Jywge1xuICAgICAgICAgIHBsYW5MZW5ndGhDaGFyczogMCxcbiAgICAgICAgICBvdXRjb21lOlxuICAgICAgICAgICAgJ25vJyBhcyBBbmFseXRpY3NNZXRhZGF0YV9JX1ZFUklGSUVEX1RISVNfSVNfTk9UX0NPREVfT1JfRklMRVBBVEhTLFxuICAgICAgICAgIGludGVydmlld1BoYXNlRW5hYmxlZDogaXNQbGFuTW9kZUludGVydmlld1BoYXNlRW5hYmxlZCgpLFxuICAgICAgICAgIHBsYW5TdHJ1Y3R1cmVWYXJpYW50LFxuICAgICAgICB9KVxuICAgICAgICBvbkRvbmUoKVxuICAgICAgICBvblJlamVjdCgpXG4gICAgICAgIHRvb2xVc2VDb25maXJtLm9uUmVqZWN0KClcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gKFxuICAgICAgPFBlcm1pc3Npb25EaWFsb2dcbiAgICAgICAgY29sb3I9XCJwbGFuTW9kZVwiXG4gICAgICAgIHRpdGxlPVwiRXhpdCBwbGFuIG1vZGU/XCJcbiAgICAgICAgd29ya2VyQmFkZ2U9e3dvcmtlckJhZGdlfVxuICAgICAgPlxuICAgICAgICA8Qm94IGZsZXhEaXJlY3Rpb249XCJjb2x1bW5cIiBwYWRkaW5nWD17MX0gbWFyZ2luVG9wPXsxfT5cbiAgICAgICAgICA8VGV4dD5DbGF1ZGUgd2FudHMgdG8gZXhpdCBwbGFuIG1vZGU8L1RleHQ+XG4gICAgICAgICAgPEJveCBtYXJnaW5Ub3A9ezF9PlxuICAgICAgICAgICAgPFNlbGVjdFxuICAgICAgICAgICAgICBvcHRpb25zPXtbXG4gICAgICAgICAgICAgICAgeyBsYWJlbDogJ1llcycsIHZhbHVlOiAneWVzJyBhcyBjb25zdCB9LFxuICAgICAgICAgICAgICAgIHsgbGFiZWw6ICdObycsIHZhbHVlOiAnbm8nIGFzIGNvbnN0IH0sXG4gICAgICAgICAgICAgIF19XG4gICAgICAgICAgICAgIG9uQ2hhbmdlPXtoYW5kbGVFbXB0eVBsYW5SZXNwb25zZX1cbiAgICAgICAgICAgICAgb25DYW5jZWw9eygpID0+IHtcbiAgICAgICAgICAgICAgICBsb2dFdmVudCgndGVuZ3VfcGxhbl9leGl0Jywge1xuICAgICAgICAgICAgICAgICAgcGxhbkxlbmd0aENoYXJzOiAwLFxuICAgICAgICAgICAgICAgICAgb3V0Y29tZTpcbiAgICAgICAgICAgICAgICAgICAgJ25vJyBhcyBBbmFseXRpY3NNZXRhZGF0YV9JX1ZFUklGSUVEX1RISVNfSVNfTk9UX0NPREVfT1JfRklMRVBBVEhTLFxuICAgICAgICAgICAgICAgICAgaW50ZXJ2aWV3UGhhc2VFbmFibGVkOiBpc1BsYW5Nb2RlSW50ZXJ2aWV3UGhhc2VFbmFibGVkKCksXG4gICAgICAgICAgICAgICAgICBwbGFuU3RydWN0dXJlVmFyaWFudCxcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIG9uRG9uZSgpXG4gICAgICAgICAgICAgICAgb25SZWplY3QoKVxuICAgICAgICAgICAgICAgIHRvb2xVc2VDb25maXJtLm9uUmVqZWN0KClcbiAgICAgICAgICAgICAgfX1cbiAgICAgICAgICAgIC8+XG4gICAgICAgICAgPC9Cb3g+XG4gICAgICAgIDwvQm94PlxuICAgICAgPC9QZXJtaXNzaW9uRGlhbG9nPlxuICAgIClcbiAgfVxuXG4gIHJldHVybiAoXG4gICAgPEJveFxuICAgICAgZmxleERpcmVjdGlvbj1cImNvbHVtblwiXG4gICAgICB0YWJJbmRleD17MH1cbiAgICAgIGF1dG9Gb2N1c1xuICAgICAgb25LZXlEb3duPXtoYW5kbGVLZXlEb3dufVxuICAgID5cbiAgICAgIDxQZXJtaXNzaW9uRGlhbG9nXG4gICAgICAgIGNvbG9yPVwicGxhbk1vZGVcIlxuICAgICAgICB0aXRsZT1cIlJlYWR5IHRvIGNvZGU/XCJcbiAgICAgICAgaW5uZXJQYWRkaW5nWD17MH1cbiAgICAgICAgd29ya2VyQmFkZ2U9e3dvcmtlckJhZGdlfVxuICAgICAgPlxuICAgICAgICA8Qm94IGZsZXhEaXJlY3Rpb249XCJjb2x1bW5cIiBtYXJnaW5Ub3A9ezF9PlxuICAgICAgICAgIDxCb3ggcGFkZGluZ1g9ezF9IGZsZXhEaXJlY3Rpb249XCJjb2x1bW5cIj5cbiAgICAgICAgICAgIDxUZXh0PkhlcmUgaXMgQ2xhdWRlJmFwb3M7cyBwbGFuOjwvVGV4dD5cbiAgICAgICAgICA8L0JveD5cbiAgICAgICAgICA8Qm94XG4gICAgICAgICAgICBib3JkZXJDb2xvcj1cInN1YnRsZVwiXG4gICAgICAgICAgICBib3JkZXJTdHlsZT1cImRhc2hlZFwiXG4gICAgICAgICAgICBmbGV4RGlyZWN0aW9uPVwiY29sdW1uXCJcbiAgICAgICAgICAgIGJvcmRlckxlZnQ9e2ZhbHNlfVxuICAgICAgICAgICAgYm9yZGVyUmlnaHQ9e2ZhbHNlfVxuICAgICAgICAgICAgcGFkZGluZ1g9ezF9XG4gICAgICAgICAgICBtYXJnaW5Cb3R0b209ezF9XG4gICAgICAgICAgICAvLyBOZWNlc3NhcnkgZm9yIFdpbmRvd3MgVGVybWluYWwgdG8gcmVuZGVyIHByb3Blcmx5XG4gICAgICAgICAgICBvdmVyZmxvdz1cImhpZGRlblwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPE1hcmtkb3duPntjdXJyZW50UGxhbn08L01hcmtkb3duPlxuICAgICAgICAgIDwvQm94PlxuICAgICAgICAgIDxCb3ggZmxleERpcmVjdGlvbj1cImNvbHVtblwiIHBhZGRpbmdYPXsxfT5cbiAgICAgICAgICAgIDxQZXJtaXNzaW9uUnVsZUV4cGxhbmF0aW9uXG4gICAgICAgICAgICAgIHBlcm1pc3Npb25SZXN1bHQ9e3Rvb2xVc2VDb25maXJtLnBlcm1pc3Npb25SZXN1bHR9XG4gICAgICAgICAgICAgIHRvb2xUeXBlPVwidG9vbFwiXG4gICAgICAgICAgICAvPlxuICAgICAgICAgICAge2lzQ2xhc3NpZmllclBlcm1pc3Npb25zRW5hYmxlZCgpICYmXG4gICAgICAgICAgICAgIGFsbG93ZWRQcm9tcHRzICYmXG4gICAgICAgICAgICAgIGFsbG93ZWRQcm9tcHRzLmxlbmd0aCA+IDAgJiYgKFxuICAgICAgICAgICAgICAgIDxCb3ggZmxleERpcmVjdGlvbj1cImNvbHVtblwiIG1hcmdpbkJvdHRvbT17MX0+XG4gICAgICAgICAgICAgICAgICA8VGV4dCBib2xkPlJlcXVlc3RlZCBwZXJtaXNzaW9uczo8L1RleHQ+XG4gICAgICAgICAgICAgICAgICB7YWxsb3dlZFByb21wdHMubWFwKChwLCBpKSA9PiAoXG4gICAgICAgICAgICAgICAgICAgIDxUZXh0IGtleT17aX0gZGltQ29sb3I+XG4gICAgICAgICAgICAgICAgICAgICAgeycgICd9wrcge3AudG9vbH0oe1BST01QVF9QUkVGSVh9IHtwLnByb21wdH0pXG4gICAgICAgICAgICAgICAgICAgIDwvVGV4dD5cbiAgICAgICAgICAgICAgICAgICkpfVxuICAgICAgICAgICAgICAgIDwvQm94PlxuICAgICAgICAgICAgICApfVxuICAgICAgICAgICAgeyF1c2VTdGlja3lGb290ZXIgJiYgKFxuICAgICAgICAgICAgICA8PlxuICAgICAgICAgICAgICAgIDxUZXh0IGRpbUNvbG9yPlxuICAgICAgICAgICAgICAgICAgQ2xhdWRlIGhhcyB3cml0dGVuIHVwIGEgcGxhbiBhbmQgaXMgcmVhZHkgdG8gZXhlY3V0ZS4gV291bGRcbiAgICAgICAgICAgICAgICAgIHlvdSBsaWtlIHRvIHByb2NlZWQ/XG4gICAgICAgICAgICAgICAgPC9UZXh0PlxuICAgICAgICAgICAgICAgIDxCb3ggbWFyZ2luVG9wPXsxfT5cbiAgICAgICAgICAgICAgICAgIDxTZWxlY3RcbiAgICAgICAgICAgICAgICAgICAgb3B0aW9ucz17b3B0aW9uc31cbiAgICAgICAgICAgICAgICAgICAgb25DaGFuZ2U9e2hhbmRsZVJlc3BvbnNlfVxuICAgICAgICAgICAgICAgICAgICBvbkNhbmNlbD17KCkgPT4gaGFuZGxlQ2FuY2VsUmVmLmN1cnJlbnQ/LigpfVxuICAgICAgICAgICAgICAgICAgICBvbkltYWdlUGFzdGU9e29uSW1hZ2VQYXN0ZX1cbiAgICAgICAgICAgICAgICAgICAgcGFzdGVkQ29udGVudHM9e3Bhc3RlZENvbnRlbnRzfVxuICAgICAgICAgICAgICAgICAgICBvblJlbW92ZUltYWdlPXtvblJlbW92ZUltYWdlfVxuICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICA8L0JveD5cbiAgICAgICAgICAgICAgPC8+XG4gICAgICAgICAgICApfVxuICAgICAgICAgIDwvQm94PlxuICAgICAgICA8L0JveD5cbiAgICAgIDwvUGVybWlzc2lvbkRpYWxvZz5cbiAgICAgIHshdXNlU3RpY2t5Rm9vdGVyICYmIGVkaXRvck5hbWUgJiYgKFxuICAgICAgICA8Qm94IGZsZXhEaXJlY3Rpb249XCJyb3dcIiBnYXA9ezF9IHBhZGRpbmdYPXsxfSBtYXJnaW5Ub3A9ezF9PlxuICAgICAgICAgIDxCb3g+XG4gICAgICAgICAgICA8VGV4dCBkaW1Db2xvcj5jdHJsLWcgdG8gZWRpdCBpbiA8L1RleHQ+XG4gICAgICAgICAgICA8VGV4dCBib2xkIGRpbUNvbG9yPlxuICAgICAgICAgICAgICB7ZWRpdG9yTmFtZX1cbiAgICAgICAgICAgIDwvVGV4dD5cbiAgICAgICAgICAgIHtpc1YyICYmIHBsYW5GaWxlUGF0aCAmJiAoXG4gICAgICAgICAgICAgIDxUZXh0IGRpbUNvbG9yPiDCtyB7Z2V0RGlzcGxheVBhdGgocGxhbkZpbGVQYXRoKX08L1RleHQ+XG4gICAgICAgICAgICApfVxuICAgICAgICAgIDwvQm94PlxuICAgICAgICAgIHtzaG93U2F2ZU1lc3NhZ2UgJiYgKFxuICAgICAgICAgICAgPEJveD5cbiAgICAgICAgICAgICAgPFRleHQgZGltQ29sb3I+eycgwrcgJ308L1RleHQ+XG4gICAgICAgICAgICAgIDxUZXh0IGNvbG9yPVwic3VjY2Vzc1wiPntmaWd1cmVzLnRpY2t9UGxhbiBzYXZlZCE8L1RleHQ+XG4gICAgICAgICAgICA8L0JveD5cbiAgICAgICAgICApfVxuICAgICAgICA8L0JveD5cbiAgICAgICl9XG4gICAgPC9Cb3g+XG4gIClcbn1cblxuLyoqIEBpbnRlcm5hbCBFeHBvcnRlZCBmb3IgdGVzdGluZy4gKi9cbmV4cG9ydCBmdW5jdGlvbiBidWlsZFBsYW5BcHByb3ZhbE9wdGlvbnMoe1xuICBzaG93Q2xlYXJDb250ZXh0LFxuICBzaG93VWx0cmFwbGFuLFxuICB1c2VkUGVyY2VudCxcbiAgaXNBdXRvTW9kZUF2YWlsYWJsZSxcbiAgaXNCeXBhc3NQZXJtaXNzaW9uc01vZGVBdmFpbGFibGUsXG4gIG9uRmVlZGJhY2tDaGFuZ2UsXG59OiB7XG4gIHNob3dDbGVhckNvbnRleHQ6IGJvb2xlYW5cbiAgc2hvd1VsdHJhcGxhbjogYm9vbGVhblxuICB1c2VkUGVyY2VudDogbnVtYmVyIHwgbnVsbFxuICBpc0F1dG9Nb2RlQXZhaWxhYmxlOiBib29sZWFuIHwgdW5kZWZpbmVkXG4gIGlzQnlwYXNzUGVybWlzc2lvbnNNb2RlQXZhaWxhYmxlOiBib29sZWFuIHwgdW5kZWZpbmVkXG4gIG9uRmVlZGJhY2tDaGFuZ2U6ICh2OiBzdHJpbmcpID0+IHZvaWRcbn0pOiBPcHRpb25XaXRoRGVzY3JpcHRpb248UmVzcG9uc2VWYWx1ZT5bXSB7XG4gIGNvbnN0IG9wdGlvbnM6IE9wdGlvbldpdGhEZXNjcmlwdGlvbjxSZXNwb25zZVZhbHVlPltdID0gW11cbiAgY29uc3QgdXNlZExhYmVsID0gdXNlZFBlcmNlbnQgIT09IG51bGwgPyBgICgke3VzZWRQZXJjZW50fSUgdXNlZClgIDogJydcblxuICBpZiAoc2hvd0NsZWFyQ29udGV4dCkge1xuICAgIGlmIChmZWF0dXJlKCdUUkFOU0NSSVBUX0NMQVNTSUZJRVInKSAmJiBpc0F1dG9Nb2RlQXZhaWxhYmxlKSB7XG4gICAgICBvcHRpb25zLnB1c2goe1xuICAgICAgICBsYWJlbDogYFllcywgY2xlYXIgY29udGV4dCR7dXNlZExhYmVsfSBhbmQgdXNlIGF1dG8gbW9kZWAsXG4gICAgICAgIHZhbHVlOiAneWVzLWF1dG8tY2xlYXItY29udGV4dCcsXG4gICAgICB9KVxuICAgIH0gZWxzZSBpZiAoaXNCeXBhc3NQZXJtaXNzaW9uc01vZGVBdmFpbGFibGUpIHtcbiAgICAgIG9wdGlvbnMucHVzaCh7XG4gICAgICAgIGxhYmVsOiBgWWVzLCBjbGVhciBjb250ZXh0JHt1c2VkTGFiZWx9IGFuZCBieXBhc3MgcGVybWlzc2lvbnNgLFxuICAgICAgICB2YWx1ZTogJ3llcy1ieXBhc3MtcGVybWlzc2lvbnMnLFxuICAgICAgfSlcbiAgICB9IGVsc2Uge1xuICAgICAgb3B0aW9ucy5wdXNoKHtcbiAgICAgICAgbGFiZWw6IGBZZXMsIGNsZWFyIGNvbnRleHQke3VzZWRMYWJlbH0gYW5kIGF1dG8tYWNjZXB0IGVkaXRzYCxcbiAgICAgICAgdmFsdWU6ICd5ZXMtYWNjZXB0LWVkaXRzJyxcbiAgICAgIH0pXG4gICAgfVxuICB9XG5cbiAgLy8gU2xvdCAyOiBrZWVwLWNvbnRleHQgd2l0aCBlbGV2YXRlZCBtb2RlIChzYW1lIHByaW9yaXR5OiBhdXRvID4gYnlwYXNzID4gZWRpdHMpLlxuICBpZiAoZmVhdHVyZSgnVFJBTlNDUklQVF9DTEFTU0lGSUVSJykgJiYgaXNBdXRvTW9kZUF2YWlsYWJsZSkge1xuICAgIG9wdGlvbnMucHVzaCh7XG4gICAgICBsYWJlbDogJ1llcywgYW5kIHVzZSBhdXRvIG1vZGUnLFxuICAgICAgdmFsdWU6ICd5ZXMtcmVzdW1lLWF1dG8tbW9kZScsXG4gICAgfSlcbiAgfSBlbHNlIGlmIChpc0J5cGFzc1Blcm1pc3Npb25zTW9kZUF2YWlsYWJsZSkge1xuICAgIG9wdGlvbnMucHVzaCh7XG4gICAgICBsYWJlbDogJ1llcywgYW5kIGJ5cGFzcyBwZXJtaXNzaW9ucycsXG4gICAgICB2YWx1ZTogJ3llcy1hY2NlcHQtZWRpdHMta2VlcC1jb250ZXh0JyxcbiAgICB9KVxuICB9IGVsc2Uge1xuICAgIG9wdGlvbnMucHVzaCh7XG4gICAgICBsYWJlbDogJ1llcywgYXV0by1hY2NlcHQgZWRpdHMnLFxuICAgICAgdmFsdWU6ICd5ZXMtYWNjZXB0LWVkaXRzLWtlZXAtY29udGV4dCcsXG4gICAgfSlcbiAgfVxuXG4gIG9wdGlvbnMucHVzaCh7XG4gICAgbGFiZWw6ICdZZXMsIG1hbnVhbGx5IGFwcHJvdmUgZWRpdHMnLFxuICAgIHZhbHVlOiAneWVzLWRlZmF1bHQta2VlcC1jb250ZXh0JyxcbiAgfSlcblxuICBpZiAoc2hvd1VsdHJhcGxhbikge1xuICAgIG9wdGlvbnMucHVzaCh7XG4gICAgICBsYWJlbDogJ05vLCByZWZpbmUgd2l0aCBVbHRyYXBsYW4gb24gQ2xhdWRlIENvZGUgb24gdGhlIHdlYicsXG4gICAgICB2YWx1ZTogJ3VsdHJhcGxhbicsXG4gICAgfSlcbiAgfVxuXG4gIG9wdGlvbnMucHVzaCh7XG4gICAgdHlwZTogJ2lucHV0JyxcbiAgICBsYWJlbDogJ05vLCBrZWVwIHBsYW5uaW5nJyxcbiAgICB2YWx1ZTogJ25vJyxcbiAgICBwbGFjZWhvbGRlcjogJ1RlbGwgQ2xhdWRlIHdoYXQgdG8gY2hhbmdlJyxcbiAgICBkZXNjcmlwdGlvbjogJ3NoaWZ0K3RhYiB0byBhcHByb3ZlIHdpdGggdGhpcyBmZWVkYmFjaycsXG4gICAgb25DaGFuZ2U6IG9uRmVlZGJhY2tDaGFuZ2UsXG4gIH0pXG5cbiAgcmV0dXJuIG9wdGlvbnNcbn1cblxuZnVuY3Rpb24gZ2V0Q29udGV4dFVzZWRQZXJjZW50KFxuICB1c2FnZTpcbiAgICB8IHtcbiAgICAgICAgaW5wdXRfdG9rZW5zOiBudW1iZXJcbiAgICAgICAgY2FjaGVfY3JlYXRpb25faW5wdXRfdG9rZW5zPzogbnVtYmVyIHwgbnVsbFxuICAgICAgICBjYWNoZV9yZWFkX2lucHV0X3Rva2Vucz86IG51bWJlciB8IG51bGxcbiAgICAgIH1cbiAgICB8IHVuZGVmaW5lZCxcbiAgcGVybWlzc2lvbk1vZGU6IFBlcm1pc3Npb25Nb2RlLFxuKTogbnVtYmVyIHwgbnVsbCB7XG4gIGlmICghdXNhZ2UpIHJldHVybiBudWxsXG4gIGNvbnN0IHJ1bnRpbWVNb2RlbCA9IGdldFJ1bnRpbWVNYWluTG9vcE1vZGVsKHtcbiAgICBwZXJtaXNzaW9uTW9kZSxcbiAgICBtYWluTG9vcE1vZGVsOiBnZXRNYWluTG9vcE1vZGVsKCksXG4gICAgZXhjZWVkczIwMGtUb2tlbnM6IGZhbHNlLFxuICB9KVxuICBjb25zdCBjb250ZXh0V2luZG93U2l6ZSA9IGdldENvbnRleHRXaW5kb3dGb3JNb2RlbChcbiAgICBydW50aW1lTW9kZWwsXG4gICAgZ2V0U2RrQmV0YXMoKSxcbiAgKVxuICBjb25zdCB7IHVzZWQgfSA9IGNhbGN1bGF0ZUNvbnRleHRQZXJjZW50YWdlcyhcbiAgICB7XG4gICAgICBpbnB1dF90b2tlbnM6IHVzYWdlLmlucHV0X3Rva2VucyxcbiAgICAgIGNhY2hlX2NyZWF0aW9uX2lucHV0X3Rva2VuczogdXNhZ2UuY2FjaGVfY3JlYXRpb25faW5wdXRfdG9rZW5zID8/IDAsXG4gICAgICBjYWNoZV9yZWFkX2lucHV0X3Rva2VuczogdXNhZ2UuY2FjaGVfcmVhZF9pbnB1dF90b2tlbnMgPz8gMCxcbiAgICB9LFxuICAgIGNvbnRleHRXaW5kb3dTaXplLFxuICApXG4gIHJldHVybiB1c2VkXG59XG4iXSwibWFwcGluZ3MiOiJBQUFBLFNBQVNBLE9BQU8sUUFBUSxZQUFZO0FBQ3BDLGNBQWNDLElBQUksUUFBUSxRQUFRO0FBQ2xDLE9BQU9DLE9BQU8sTUFBTSxTQUFTO0FBQzdCLE9BQU9DLEtBQUssSUFDVkMsV0FBVyxFQUNYQyxTQUFTLEVBQ1RDLGVBQWUsRUFDZkMsT0FBTyxFQUNQQyxNQUFNLEVBQ05DLFFBQVEsUUFDSCxPQUFPO0FBQ2QsU0FBU0MsZ0JBQWdCLFFBQVEsOEJBQThCO0FBQy9ELFNBQ0UsS0FBS0MsMERBQTBELEVBQy9EQyxRQUFRLFFBQ0gsaUNBQWlDO0FBQ3hDLFNBQ0VDLFdBQVcsRUFDWEMsZ0JBQWdCLEVBQ2hCQyxjQUFjLFFBQ1QsdUJBQXVCO0FBQzlCLFNBQ0VDLFdBQVcsRUFDWEMsWUFBWSxFQUNaQyw0QkFBNEIsRUFDNUJDLG9CQUFvQixFQUNwQkMsOEJBQThCLEVBQzlCQyw4QkFBOEIsUUFDekIsNkJBQTZCO0FBQ3BDLFNBQVNDLG1CQUFtQixRQUFRLGlEQUFpRDtBQUNyRixTQUFTQyxlQUFlLFFBQVEsZ0NBQWdDO0FBQ2hFLGNBQWNDLGFBQWEsUUFBUSx1Q0FBdUM7QUFDMUUsU0FBU0MsR0FBRyxFQUFFQyxJQUFJLFFBQVEsaUJBQWlCO0FBQzNDLGNBQWNDLFFBQVEsUUFBUSxpQ0FBaUM7QUFDL0QsU0FBU0MsZUFBZSxRQUFRLHVDQUF1QztBQUN2RSxTQUFTQywyQkFBMkIsUUFBUSw4Q0FBOEM7QUFDMUYsY0FBY0MsYUFBYSxRQUFRLHVEQUF1RDtBQUMxRixTQUFTQyxxQkFBcUIsUUFBUSw0Q0FBNEM7QUFDbEYsU0FBU0Msb0JBQW9CLFFBQVEsc0NBQXNDO0FBQzNFLFNBQ0VDLDJCQUEyQixFQUMzQkMsd0JBQXdCLFFBQ25CLDJCQUEyQjtBQUNsQyxTQUFTQyxpQkFBaUIsUUFBUSwwQkFBMEI7QUFDNUQsU0FBU0MsY0FBYyxRQUFRLHdCQUF3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 \ No newline at end of file +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJmZWF0dXJlIiwiVVVJRCIsImZpZ3VyZXMiLCJSZWFjdCIsInVzZUNhbGxiYWNrIiwidXNlRWZmZWN0IiwidXNlTGF5b3V0RWZmZWN0IiwidXNlTWVtbyIsInVzZVJlZiIsInVzZVN0YXRlIiwidXNlTm90aWZpY2F0aW9ucyIsIkFuYWx5dGljc01ldGFkYXRhX0lfVkVSSUZJRURfVEhJU19JU19OT1RfQ09ERV9PUl9GSUxFUEFUSFMiLCJsb2dFdmVudCIsInVzZUFwcFN0YXRlIiwidXNlQXBwU3RhdGVTdG9yZSIsInVzZVNldEFwcFN0YXRlIiwiZ2V0U2RrQmV0YXMiLCJnZXRTZXNzaW9uSWQiLCJpc1Nlc3Npb25QZXJzaXN0ZW5jZURpc2FibGVkIiwic2V0SGFzRXhpdGVkUGxhbk1vZGUiLCJzZXROZWVkc0F1dG9Nb2RlRXhpdEF0dGFjaG1lbnQiLCJzZXROZWVkc1BsYW5Nb2RlRXhpdEF0dGFjaG1lbnQiLCJnZW5lcmF0ZVNlc3Npb25OYW1lIiwibGF1bmNoVWx0cmFwbGFuIiwiS2V5Ym9hcmRFdmVudCIsIkJveCIsIlRleHQiLCJBcHBTdGF0ZSIsIkFHRU5UX1RPT0xfTkFNRSIsIkVYSVRfUExBTl9NT0RFX1YyX1RPT0xfTkFNRSIsIkFsbG93ZWRQcm9tcHQiLCJURUFNX0NSRUFURV9UT09MX05BTUUiLCJpc0FnZW50U3dhcm1zRW5hYmxlZCIsImNhbGN1bGF0ZUNvbnRleHRQZXJjZW50YWdlcyIsImdldENvbnRleHRXaW5kb3dGb3JNb2RlbCIsImdldEV4dGVybmFsRWRpdG9yIiwiZ2V0RGlzcGxheVBhdGgiLCJ0b0lERURpc3BsYXlOYW1lIiwibG9nRXJyb3IiLCJlbnF1ZXVlUGVuZGluZ05vdGlmaWNhdGlvbiIsImNyZWF0ZVVzZXJNZXNzYWdlIiwiZ2V0TWFpbkxvb3BNb2RlbCIsImdldFJ1bnRpbWVNYWluTG9vcE1vZGVsIiwiY3JlYXRlUHJvbXB0UnVsZUNvbnRlbnQiLCJpc0NsYXNzaWZpZXJQZXJtaXNzaW9uc0VuYWJsZWQiLCJQUk9NUFRfUFJFRklYIiwiUGVybWlzc2lvbk1vZGUiLCJ0b0V4dGVybmFsUGVybWlzc2lvbk1vZGUiLCJQZXJtaXNzaW9uVXBkYXRlIiwiaXNBdXRvTW9kZUdhdGVFbmFibGVkIiwicmVzdG9yZURhbmdlcm91c1Blcm1pc3Npb25zIiwic3RyaXBEYW5nZXJvdXNQZXJtaXNzaW9uc0ZvckF1dG9Nb2RlIiwiZ2V0UGV3dGVyTGVkZ2VyVmFyaWFudCIsImlzUGxhbk1vZGVJbnRlcnZpZXdQaGFzZUVuYWJsZWQiLCJnZXRQbGFuIiwiZ2V0UGxhbkZpbGVQYXRoIiwiZWRpdEZpbGVJbkVkaXRvciIsImVkaXRQcm9tcHRJbkVkaXRvciIsImdldEN1cnJlbnRTZXNzaW9uVGl0bGUiLCJnZXRUcmFuc2NyaXB0UGF0aCIsInNhdmVBZ2VudE5hbWUiLCJzYXZlQ3VzdG9tVGl0bGUiLCJnZXRTZXR0aW5nc19ERVBSRUNBVEVEIiwiT3B0aW9uV2l0aERlc2NyaXB0aW9uIiwiU2VsZWN0IiwiTWFya2Rvd24iLCJQZXJtaXNzaW9uRGlhbG9nIiwiUGVybWlzc2lvblJlcXVlc3RQcm9wcyIsIlBlcm1pc3Npb25SdWxlRXhwbGFuYXRpb24iLCJhdXRvTW9kZVN0YXRlTW9kdWxlIiwicmVxdWlyZSIsIkJhc2U2NEltYWdlU291cmNlIiwiSW1hZ2VCbG9ja1BhcmFtIiwiUGFzdGVkQ29udGVudCIsIkltYWdlRGltZW5zaW9ucyIsIm1heWJlUmVzaXplQW5kRG93bnNhbXBsZUltYWdlQmxvY2siLCJjYWNoZUltYWdlUGF0aCIsInN0b3JlSW1hZ2UiLCJSZXNwb25zZVZhbHVlIiwiYnVpbGRQZXJtaXNzaW9uVXBkYXRlcyIsIm1vZGUiLCJhbGxvd2VkUHJvbXB0cyIsInVwZGF0ZXMiLCJ0eXBlIiwiZGVzdGluYXRpb24iLCJsZW5ndGgiLCJwdXNoIiwicnVsZXMiLCJtYXAiLCJwIiwidG9vbE5hbWUiLCJ0b29sIiwicnVsZUNvbnRlbnQiLCJwcm9tcHQiLCJiZWhhdmlvciIsImF1dG9OYW1lU2Vzc2lvbkZyb21QbGFuIiwicGxhbiIsInNldEFwcFN0YXRlIiwidXBkYXRlciIsInByZXYiLCJpc0NsZWFyQ29udGV4dCIsImNsZWFudXBQZXJpb2REYXlzIiwiY29udGVudCIsInNsaWNlIiwiQWJvcnRDb250cm9sbGVyIiwic2lnbmFsIiwidGhlbiIsIm5hbWUiLCJzZXNzaW9uSWQiLCJmdWxsUGF0aCIsInN0YW5kYWxvbmVBZ2VudENvbnRleHQiLCJjYXRjaCIsIkV4aXRQbGFuTW9kZVBlcm1pc3Npb25SZXF1ZXN0IiwidG9vbFVzZUNvbmZpcm0iLCJvbkRvbmUiLCJvblJlamVjdCIsIndvcmtlckJhZGdlIiwic2V0U3RpY2t5Rm9vdGVyIiwiUmVhY3ROb2RlIiwidG9vbFBlcm1pc3Npb25Db250ZXh0IiwicyIsInN0b3JlIiwiYWRkTm90aWZpY2F0aW9uIiwicGxhbkZlZWRiYWNrIiwic2V0UGxhbkZlZWRiYWNrIiwicGFzdGVkQ29udGVudHMiLCJzZXRQYXN0ZWRDb250ZW50cyIsIlJlY29yZCIsIm5leHRQYXN0ZUlkUmVmIiwic2hvd0NsZWFyQ29udGV4dCIsInNldHRpbmdzIiwic2hvd0NsZWFyQ29udGV4dE9uUGxhbkFjY2VwdCIsInVsdHJhcGxhblNlc3Npb25VcmwiLCJ1bHRyYXBsYW5MYXVuY2hpbmciLCJzaG93VWx0cmFwbGFuIiwidXNhZ2UiLCJhc3Npc3RhbnRNZXNzYWdlIiwibWVzc2FnZSIsImlzQXV0b01vZGVBdmFpbGFibGUiLCJpc0J5cGFzc1Blcm1pc3Npb25zTW9kZUF2YWlsYWJsZSIsIm9wdGlvbnMiLCJidWlsZFBsYW5BcHByb3ZhbE9wdGlvbnMiLCJ1c2VkUGVyY2VudCIsImdldENvbnRleHRVc2VkUGVyY2VudCIsIm9uRmVlZGJhY2tDaGFuZ2UiLCJvbkltYWdlUGFzdGUiLCJiYXNlNjRJbWFnZSIsIm1lZGlhVHlwZSIsImZpbGVuYW1lIiwiZGltZW5zaW9ucyIsIl9zb3VyY2VQYXRoIiwicGFzdGVJZCIsImN1cnJlbnQiLCJuZXdDb250ZW50IiwiaWQiLCJvblJlbW92ZUltYWdlIiwibmV4dCIsImltYWdlQXR0YWNobWVudHMiLCJPYmplY3QiLCJ2YWx1ZXMiLCJmaWx0ZXIiLCJjIiwiaGFzSW1hZ2VzIiwiaXNWMiIsImlucHV0UGxhbiIsInVuZGVmaW5lZCIsImlucHV0IiwicGxhbkZpbGVQYXRoIiwicmF3UGxhbiIsImlzRW1wdHkiLCJ0cmltIiwicGxhblN0cnVjdHVyZVZhcmlhbnQiLCJjdXJyZW50UGxhbiIsInNldEN1cnJlbnRQbGFuIiwic2hvd1NhdmVNZXNzYWdlIiwic2V0U2hvd1NhdmVNZXNzYWdlIiwicGxhbkVkaXRlZExvY2FsbHkiLCJzZXRQbGFuRWRpdGVkTG9jYWxseSIsInRpbWVyIiwic2V0VGltZW91dCIsImNsZWFyVGltZW91dCIsImhhbmRsZUtleURvd24iLCJlIiwiY3RybCIsImtleSIsInByZXZlbnREZWZhdWx0IiwicmVzdWx0IiwiZXJyb3IiLCJ0ZXh0IiwiY29sb3IiLCJwcmlvcml0eSIsInNoaWZ0IiwiaGFuZGxlUmVzcG9uc2UiLCJ2YWx1ZSIsIlByb21pc2UiLCJ0cmltbWVkRmVlZGJhY2siLCJhY2NlcHRGZWVkYmFjayIsInBsYW5MZW5ndGhDaGFycyIsIm91dGNvbWUiLCJpbnRlcnZpZXdQaGFzZUVuYWJsZWQiLCJibHVyYiIsInNlZWRQbGFuIiwiZ2V0QXBwU3RhdGUiLCJnZXRTdGF0ZSIsInNldFN0YXRlIiwibXNnIiwidXBkYXRlZElucHV0IiwiZ29pbmdUb0F1dG8iLCJhdXRvV2FzVXNlZER1cmluZ1BsYW4iLCJpc0F1dG9Nb2RlQWN0aXZlIiwic2V0QXV0b01vZGVBY3RpdmUiLCJwcmVQbGFuTW9kZSIsImlzUmVzdW1lQXV0b09wdGlvbiIsImlzS2VlcENvbnRleHRPcHRpb24iLCJjbGVhckNvbnRleHQiLCJoYXNGZWVkYmFjayIsInZlcmlmaWNhdGlvbkluc3RydWN0aW9uIiwidHJhbnNjcmlwdFBhdGgiLCJ0cmFuc2NyaXB0SGludCIsInRlYW1IaW50IiwiZmVlZGJhY2tTdWZmaXgiLCJpbml0aWFsTWVzc2FnZSIsInBsYW5Db250ZW50Iiwib25BbGxvdyIsImtlZXBDb250ZXh0TW9kZXMiLCJjb25zdCIsImtlZXBDb250ZXh0TW9kZSIsInN0YW5kYXJkTW9kZXMiLCJzdGFuZGFyZE1vZGUiLCJpbWFnZUJsb2NrcyIsImFsbCIsImltZyIsImJsb2NrIiwic291cmNlIiwibWVkaWFfdHlwZSIsImRhdGEiLCJyZXNpemVkIiwiZWRpdG9yIiwiZWRpdG9yTmFtZSIsImhhbmRsZVJlc3BvbnNlUmVmIiwiaGFuZGxlQ2FuY2VsUmVmIiwidXNlU3RpY2t5Rm9vdGVyIiwidiIsInRpY2siLCJoYW5kbGVFbXB0eVBsYW5SZXNwb25zZSIsImxhYmVsIiwicGVybWlzc2lvblJlc3VsdCIsImkiLCJ1c2VkTGFiZWwiLCJwbGFjZWhvbGRlciIsImRlc2NyaXB0aW9uIiwib25DaGFuZ2UiLCJpbnB1dF90b2tlbnMiLCJjYWNoZV9jcmVhdGlvbl9pbnB1dF90b2tlbnMiLCJjYWNoZV9yZWFkX2lucHV0X3Rva2VucyIsInBlcm1pc3Npb25Nb2RlIiwicnVudGltZU1vZGVsIiwibWFpbkxvb3BNb2RlbCIsImV4Y2VlZHMyMDBrVG9rZW5zIiwiY29udGV4dFdpbmRvd1NpemUiLCJ1c2VkIl0sInNvdXJjZXMiOlsiRXhpdFBsYW5Nb2RlUGVybWlzc2lvblJlcXVlc3QudHN4Il0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGZlYXR1cmUgfSBmcm9tICdidW46YnVuZGxlJ1xuaW1wb3J0IHR5cGUgeyBVVUlEIH0gZnJvbSAnY3J5cHRvJ1xuaW1wb3J0IGZpZ3VyZXMgZnJvbSAnZmlndXJlcydcbmltcG9ydCBSZWFjdCwge1xuICB1c2VDYWxsYmFjayxcbiAgdXNlRWZmZWN0LFxuICB1c2VMYXlvdXRFZmZlY3QsXG4gIHVzZU1lbW8sXG4gIHVzZVJlZixcbiAgdXNlU3RhdGUsXG59IGZyb20gJ3JlYWN0J1xuaW1wb3J0IHsgdXNlTm90aWZpY2F0aW9ucyB9IGZyb20gJ3NyYy9jb250ZXh0L25vdGlmaWNhdGlvbnMuanMnXG5pbXBvcnQge1xuICB0eXBlIEFuYWx5dGljc01ldGFkYXRhX0lfVkVSSUZJRURfVEhJU19JU19OT1RfQ09ERV9PUl9GSUxFUEFUSFMsXG4gIGxvZ0V2ZW50LFxufSBmcm9tICdzcmMvc2VydmljZXMvYW5hbHl0aWNzL2luZGV4LmpzJ1xuaW1wb3J0IHtcbiAgdXNlQXBwU3RhdGUsXG4gIHVzZUFwcFN0YXRlU3RvcmUsXG4gIHVzZVNldEFwcFN0YXRlLFxufSBmcm9tICdzcmMvc3RhdGUvQXBwU3RhdGUuanMnXG5pbXBvcnQge1xuICBnZXRTZGtCZXRhcyxcbiAgZ2V0U2Vzc2lvbklkLFxuICBpc1Nlc3Npb25QZXJzaXN0ZW5jZURpc2FibGVkLFxuICBzZXRIYXNFeGl0ZWRQbGFuTW9kZSxcbiAgc2V0TmVlZHNBdXRvTW9kZUV4aXRBdHRhY2htZW50LFxuICBzZXROZWVkc1BsYW5Nb2RlRXhpdEF0dGFjaG1lbnQsXG59IGZyb20gJy4uLy4uLy4uL2Jvb3RzdHJhcC9zdGF0ZS5qcydcbmltcG9ydCB7IGdlbmVyYXRlU2Vzc2lvbk5hbWUgfSBmcm9tICcuLi8uLi8uLi9jb21tYW5kcy9yZW5hbWUvZ2VuZXJhdGVTZXNzaW9uTmFtZS5qcydcbmltcG9ydCB7IGxhdW5jaFVsdHJhcGxhbiB9IGZyb20gJy4uLy4uLy4uL2NvbW1hbmRzL3VsdHJhcGxhbi5qcydcbmltcG9ydCB0eXBlIHsgS2V5Ym9hcmRFdmVudCB9IGZyb20gJy4uLy4uLy4uL2luay9ldmVudHMva2V5Ym9hcmQtZXZlbnQuanMnXG5pbXBvcnQgeyBCb3gsIFRleHQgfSBmcm9tICcuLi8uLi8uLi9pbmsuanMnXG5pbXBvcnQgdHlwZSB7IEFwcFN0YXRlIH0gZnJvbSAnLi4vLi4vLi4vc3RhdGUvQXBwU3RhdGVTdG9yZS5qcydcbmltcG9ydCB7IEFHRU5UX1RPT0xfTkFNRSB9IGZyb20gJy4uLy4uLy4uL3Rvb2xzL0FnZW50VG9vbC9jb25zdGFudHMuanMnXG5pbXBvcnQgeyBFWElUX1BMQU5fTU9ERV9WMl9UT09MX05BTUUgfSBmcm9tICcuLi8uLi8uLi90b29scy9FeGl0UGxhbk1vZGVUb29sL2NvbnN0YW50cy5qcydcbmltcG9ydCB0eXBlIHsgQWxsb3dlZFByb21wdCB9IGZyb20gJy4uLy4uLy4uL3Rvb2xzL0V4aXRQbGFuTW9kZVRvb2wvRXhpdFBsYW5Nb2RlVjJUb29sLmpzJ1xuaW1wb3J0IHsgVEVBTV9DUkVBVEVfVE9PTF9OQU1FIH0gZnJvbSAnLi4vLi4vLi4vdG9vbHMvVGVhbUNyZWF0ZVRvb2wvY29uc3RhbnRzLmpzJ1xuaW1wb3J0IHsgaXNBZ2VudFN3YXJtc0VuYWJsZWQgfSBmcm9tICcuLi8uLi8uLi91dGlscy9hZ2VudFN3YXJtc0VuYWJsZWQuanMnXG5pbXBvcnQge1xuICBjYWxjdWxhdGVDb250ZXh0UGVyY2VudGFnZXMsXG4gIGdldENvbnRleHRXaW5kb3dGb3JNb2RlbCxcbn0gZnJvbSAnLi4vLi4vLi4vdXRpbHMvY29udGV4dC5qcydcbmltcG9ydCB7IGdldEV4dGVybmFsRWRpdG9yIH0gZnJvbSAnLi4vLi4vLi4vdXRpbHMvZWRpdG9yLmpzJ1xuaW1wb3J0IHsgZ2V0RGlzcGxheVBhdGggfSBmcm9tICcuLi8uLi8uLi91dGlscy9maWxlLmpzJ1xuaW1wb3J0IHsgdG9JREVEaXNwbGF5TmFtZSB9IGZyb20gJy4uLy4uLy4uL3V0aWxzL2lkZS5qcydcbmltcG9ydCB7IGxvZ0Vycm9yIH0gZnJvbSAnLi4vLi4vLi4vdXRpbHMvbG9nLmpzJ1xuaW1wb3J0IHsgZW5xdWV1ZVBlbmRpbmdOb3RpZmljYXRpb24gfSBmcm9tICcuLi8uLi8uLi91dGlscy9tZXNzYWdlUXVldWVNYW5hZ2VyLmpzJ1xuaW1wb3J0IHsgY3JlYXRlVXNlck1lc3NhZ2UgfSBmcm9tICcuLi8uLi8uLi91dGlscy9tZXNzYWdlcy5qcydcbmltcG9ydCB7XG4gIGdldE1haW5Mb29wTW9kZWwsXG4gIGdldFJ1bnRpbWVNYWluTG9vcE1vZGVsLFxufSBmcm9tICcuLi8uLi8uLi91dGlscy9tb2RlbC9tb2RlbC5qcydcbmltcG9ydCB7XG4gIGNyZWF0ZVByb21wdFJ1bGVDb250ZW50LFxuICBpc0NsYXNzaWZpZXJQZXJtaXNzaW9uc0VuYWJsZWQsXG4gIFBST01QVF9QUkVGSVgsXG59IGZyb20gJy4uLy4uLy4uL3V0aWxzL3Blcm1pc3Npb25zL2Jhc2hDbGFzc2lmaWVyLmpzJ1xuaW1wb3J0IHtcbiAgdHlwZSBQZXJtaXNzaW9uTW9kZSxcbiAgdG9FeHRlcm5hbFBlcm1pc3Npb25Nb2RlLFxufSBmcm9tICcuLi8uLi8uLi91dGlscy9wZXJtaXNzaW9ucy9QZXJtaXNzaW9uTW9kZS5qcydcbmltcG9ydCB0eXBlIHsgUGVybWlzc2lvblVwZGF0ZSB9IGZyb20gJy4uLy4uLy4uL3V0aWxzL3Blcm1pc3Npb25zL1Blcm1pc3Npb25VcGRhdGVTY2hlbWEuanMnXG5pbXBvcnQge1xuICBpc0F1dG9Nb2RlR2F0ZUVuYWJsZWQsXG4gIHJlc3RvcmVEYW5nZXJvdXNQZXJtaXNzaW9ucyxcbiAgc3RyaXBEYW5nZXJvdXNQZXJtaXNzaW9uc0ZvckF1dG9Nb2RlLFxufSBmcm9tICcuLi8uLi8uLi91dGlscy9wZXJtaXNzaW9ucy9wZXJtaXNzaW9uU2V0dXAuanMnXG5pbXBvcnQge1xuICBnZXRQZXd0ZXJMZWRnZXJWYXJpYW50LFxuICBpc1BsYW5Nb2RlSW50ZXJ2aWV3UGhhc2VFbmFibGVkLFxufSBmcm9tICcuLi8uLi8uLi91dGlscy9wbGFuTW9kZVYyLmpzJ1xuaW1wb3J0IHsgZ2V0UGxhbiwgZ2V0UGxhbkZpbGVQYXRoIH0gZnJvbSAnLi4vLi4vLi4vdXRpbHMvcGxhbnMuanMnXG5pbXBvcnQge1xuICBlZGl0RmlsZUluRWRpdG9yLFxuICBlZGl0UHJvbXB0SW5FZGl0b3IsXG59IGZyb20gJy4uLy4uLy4uL3V0aWxzL3Byb21wdEVkaXRvci5qcydcbmltcG9ydCB7XG4gIGdldEN1cnJlbnRTZXNzaW9uVGl0bGUsXG4gIGdldFRyYW5zY3JpcHRQYXRoLFxuICBzYXZlQWdlbnROYW1lLFxuICBzYXZlQ3VzdG9tVGl0bGUsXG59IGZyb20gJy4uLy4uLy4uL3V0aWxzL3Nlc3Npb25TdG9yYWdlLmpzJ1xuaW1wb3J0IHsgZ2V0U2V0dGluZ3NfREVQUkVDQVRFRCB9IGZyb20gJy4uLy4uLy4uL3V0aWxzL3NldHRpbmdzL3NldHRpbmdzLmpzJ1xuaW1wb3J0IHsgdHlwZSBPcHRpb25XaXRoRGVzY3JpcHRpb24sIFNlbGVjdCB9IGZyb20gJy4uLy4uL0N1c3RvbVNlbGVjdC9pbmRleC5qcydcbmltcG9ydCB7IE1hcmtkb3duIH0gZnJvbSAnLi4vLi4vTWFya2Rvd24uanMnXG5pbXBvcnQgeyBQZXJtaXNzaW9uRGlhbG9nIH0gZnJvbSAnLi4vUGVybWlzc2lvbkRpYWxvZy5qcydcbmltcG9ydCB0eXBlIHsgUGVybWlzc2lvblJlcXVlc3RQcm9wcyB9IGZyb20gJy4uL1Blcm1pc3Npb25SZXF1ZXN0LmpzJ1xuaW1wb3J0IHsgUGVybWlzc2lvblJ1bGVFeHBsYW5hdGlvbiB9IGZyb20gJy4uL1Blcm1pc3Npb25SdWxlRXhwbGFuYXRpb24uanMnXG5cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby1yZXF1aXJlLWltcG9ydHMgKi9cbmNvbnN0IGF1dG9Nb2RlU3RhdGVNb2R1bGUgPSBmZWF0dXJlKCdUUkFOU0NSSVBUX0NMQVNTSUZJRVInKVxuICA/IChyZXF1aXJlKCcuLi8uLi8uLi91dGlscy9wZXJtaXNzaW9ucy9hdXRvTW9kZVN0YXRlLmpzJykgYXMgdHlwZW9mIGltcG9ydCgnLi4vLi4vLi4vdXRpbHMvcGVybWlzc2lvbnMvYXV0b01vZGVTdGF0ZS5qcycpKVxuICA6IG51bGxcblxuaW1wb3J0IHR5cGUge1xuICBCYXNlNjRJbWFnZVNvdXJjZSxcbiAgSW1hZ2VCbG9ja1BhcmFtLFxufSBmcm9tICdAYW50aHJvcGljLWFpL3Nkay9yZXNvdXJjZXMvbWVzc2FnZXMubWpzJ1xuLyogZXNsaW50LWVuYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tcmVxdWlyZS1pbXBvcnRzICovXG5pbXBvcnQgdHlwZSB7IFBhc3RlZENvbnRlbnQgfSBmcm9tICcuLi8uLi8uLi91dGlscy9jb25maWcuanMnXG5pbXBvcnQgdHlwZSB7IEltYWdlRGltZW5zaW9ucyB9IGZyb20gJy4uLy4uLy4uL3V0aWxzL2ltYWdlUmVzaXplci5qcydcbmltcG9ydCB7IG1heWJlUmVzaXplQW5kRG93bnNhbXBsZUltYWdlQmxvY2sgfSBmcm9tICcuLi8uLi8uLi91dGlscy9pbWFnZVJlc2l6ZXIuanMnXG5pbXBvcnQgeyBjYWNoZUltYWdlUGF0aCwgc3RvcmVJbWFnZSB9IGZyb20gJy4uLy4uLy4uL3V0aWxzL2ltYWdlU3RvcmUuanMnXG5cbnR5cGUgUmVzcG9uc2VWYWx1ZSA9XG4gIHwgJ3llcy1ieXBhc3MtcGVybWlzc2lvbnMnXG4gIHwgJ3llcy1hY2NlcHQtZWRpdHMnXG4gIHwgJ3llcy1hY2NlcHQtZWRpdHMta2VlcC1jb250ZXh0J1xuICB8ICd5ZXMtZGVmYXVsdC1rZWVwLWNvbnRleHQnXG4gIHwgJ3llcy1yZXN1bWUtYXV0by1tb2RlJ1xuICB8ICd5ZXMtYXV0by1jbGVhci1jb250ZXh0J1xuICB8ICd1bHRyYXBsYW4nXG4gIHwgJ25vJ1xuXG4vKipcbiAqIEJ1aWxkIHBlcm1pc3Npb24gdXBkYXRlcyBmb3IgcGxhbiBhcHByb3ZhbCwgaW5jbHVkaW5nIHByb21wdC1iYXNlZCBydWxlcyBpZiBwcm92aWRlZC5cbiAqIFByb21wdC1iYXNlZCBydWxlcyBhcmUgb25seSBhZGRlZCB3aGVuIGNsYXNzaWZpZXIgcGVybWlzc2lvbnMgYXJlIGVuYWJsZWQgKEFudC1vbmx5KS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkUGVybWlzc2lvblVwZGF0ZXMoXG4gIG1vZGU6IFBlcm1pc3Npb25Nb2RlLFxuICBhbGxvd2VkUHJvbXB0cz86IEFsbG93ZWRQcm9tcHRbXSxcbik6IFBlcm1pc3Npb25VcGRhdGVbXSB7XG4gIGNvbnN0IHVwZGF0ZXM6IFBlcm1pc3Npb25VcGRhdGVbXSA9IFtcbiAgICB7XG4gICAgICB0eXBlOiAnc2V0TW9kZScsXG4gICAgICBtb2RlOiB0b0V4dGVybmFsUGVybWlzc2lvbk1vZGUobW9kZSksXG4gICAgICBkZXN0aW5hdGlvbjogJ3Nlc3Npb24nLFxuICAgIH0sXG4gIF1cblxuICAvLyBBZGQgcHJvbXB0LWJhc2VkIHBlcm1pc3Npb24gcnVsZXMgaWYgcHJvdmlkZWQgKEFudC1vbmx5IGZlYXR1cmUpXG4gIGlmIChcbiAgICBpc0NsYXNzaWZpZXJQZXJtaXNzaW9uc0VuYWJsZWQoKSAmJlxuICAgIGFsbG93ZWRQcm9tcHRzICYmXG4gICAgYWxsb3dlZFByb21wdHMubGVuZ3RoID4gMFxuICApIHtcbiAgICB1cGRhdGVzLnB1c2goe1xuICAgICAgdHlwZTogJ2FkZFJ1bGVzJyxcbiAgICAgIHJ1bGVzOiBhbGxvd2VkUHJvbXB0cy5tYXAocCA9PiAoe1xuICAgICAgICB0b29sTmFtZTogcC50b29sLFxuICAgICAgICBydWxlQ29udGVudDogY3JlYXRlUHJvbXB0UnVsZUNvbnRlbnQocC5wcm9tcHQpLFxuICAgICAgfSkpLFxuICAgICAgYmVoYXZpb3I6ICdhbGxvdycsXG4gICAgICBkZXN0aW5hdGlvbjogJ3Nlc3Npb24nLFxuICAgIH0pXG4gIH1cblxuICByZXR1cm4gdXBkYXRlc1xufVxuXG4vKipcbiAqIEF1dG8tbmFtZSB0aGUgc2Vzc2lvbiBmcm9tIHRoZSBwbGFuIGNvbnRlbnQgd2hlbiB0aGUgdXNlciBhY2NlcHRzIGEgcGxhbixcbiAqIGlmIHRoZXkgaGF2ZW4ndCBhbHJlYWR5IG5hbWVkIGl0IHZpYSAvcmVuYW1lIG9yIC0tbmFtZS4gRmlyZS1hbmQtZm9yZ2V0LlxuICogTWlycm9ycyAvcmVuYW1lOiBrZWJhYi1jYXNlIG5hbWUsIHVwZGF0ZXMgdGhlIHByb21wdC1ib3JkZXIgYmFkZ2UuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhdXRvTmFtZVNlc3Npb25Gcm9tUGxhbihcbiAgcGxhbjogc3RyaW5nLFxuICBzZXRBcHBTdGF0ZTogKHVwZGF0ZXI6IChwcmV2OiBBcHBTdGF0ZSkgPT4gQXBwU3RhdGUpID0+IHZvaWQsXG4gIGlzQ2xlYXJDb250ZXh0OiBib29sZWFuLFxuKTogdm9pZCB7XG4gIGlmIChcbiAgICBpc1Nlc3Npb25QZXJzaXN0ZW5jZURpc2FibGVkKCkgfHxcbiAgICBnZXRTZXR0aW5nc19ERVBSRUNBVEVEKCk/LmNsZWFudXBQZXJpb2REYXlzID09PSAwXG4gICkge1xuICAgIHJldHVyblxuICB9XG4gIC8vIE9uIGNsZWFyLWNvbnRleHQsIHRoZSBjdXJyZW50IHNlc3Npb24gaXMgYWJvdXQgdG8gYmUgYWJhbmRvbmVkIOKAlCBpdHNcbiAgLy8gdGl0bGUgKHdoaWNoIG1heSBoYXZlIGJlZW4gc2V0IGJ5IGEgUFJJT1IgYXV0by1uYW1lKSBpcyBpcnJlbGV2YW50LlxuICAvLyBDaGVja2luZyBpdCB3b3VsZCBtYWtlIHRoZSBmZWF0dXJlIHNlbGYtZGVmZWF0aW5nIGFmdGVyIGZpcnN0IHVzZS5cbiAgaWYgKCFpc0NsZWFyQ29udGV4dCAmJiBnZXRDdXJyZW50U2Vzc2lvblRpdGxlKGdldFNlc3Npb25JZCgpKSkgcmV0dXJuXG4gIHZvaWQgZ2VuZXJhdGVTZXNzaW9uTmFtZShcbiAgICAvLyBnZW5lcmF0ZVNlc3Npb25OYW1lIHRhaWwtc2xpY2VzIHRvIHRoZSBsYXN0IDEwMDAgY2hhcnMgKGNvcnJlY3QgZm9yXG4gICAgLy8gY29udmVyc2F0aW9ucywgd2hlcmUgcmVjZW5jeSBtYXR0ZXJzKS4gUGxhbnMgZnJvbnQtbG9hZCB0aGUgZ29hbCBhbmRcbiAgICAvLyBlbmQgd2l0aCB0ZXN0aW5nIHN0ZXBzIOKAlCBoZWFkLXNsaWNlIHNvIEhhaWt1IHNlZXMgdGhlIHN1bW1hcnkuXG4gICAgW2NyZWF0ZVVzZXJNZXNzYWdlKHsgY29udGVudDogcGxhbi5zbGljZSgwLCAxMDAwKSB9KV0sXG4gICAgbmV3IEFib3J0Q29udHJvbGxlcigpLnNpZ25hbCxcbiAgKVxuICAgIC50aGVuKGFzeW5jIG5hbWUgPT4ge1xuICAgICAgLy8gT24gY2xlYXItY29udGV4dCBhY2NlcHRhbmNlLCByZWdlbmVyYXRlU2Vzc2lvbklkKCkgaGFzIHJ1biBieSBub3cg4oCUXG4gICAgICAvLyB0aGlzIGludGVudGlvbmFsbHkgbmFtZXMgdGhlIE5FVyBleGVjdXRpb24gc2Vzc2lvbi4gRG8gbm90IFwiZml4XCIgYnlcbiAgICAgIC8vIGNhcHR1cmluZyBzZXNzaW9uSWQgb25jZTsgdGhhdCB3b3VsZCBuYW1lIHRoZSBhYmFuZG9uZWQgcGxhbm5pbmcgc2Vzc2lvbi5cbiAgICAgIGlmICghbmFtZSB8fCBnZXRDdXJyZW50U2Vzc2lvblRpdGxlKGdldFNlc3Npb25JZCgpKSkgcmV0dXJuXG4gICAgICBjb25zdCBzZXNzaW9uSWQgPSBnZXRTZXNzaW9uSWQoKSBhcyBVVUlEXG4gICAgICBjb25zdCBmdWxsUGF0aCA9IGdldFRyYW5zY3JpcHRQYXRoKClcbiAgICAgIGF3YWl0IHNhdmVDdXN0b21UaXRsZShzZXNzaW9uSWQsIG5hbWUsIGZ1bGxQYXRoLCAnYXV0bycpXG4gICAgICBhd2FpdCBzYXZlQWdlbnROYW1lKHNlc3Npb25JZCwgbmFtZSwgZnVsbFBhdGgsICdhdXRvJylcbiAgICAgIHNldEFwcFN0YXRlKHByZXYgPT4ge1xuICAgICAgICBpZiAocHJldi5zdGFuZGFsb25lQWdlbnRDb250ZXh0Py5uYW1lID09PSBuYW1lKSByZXR1cm4gcHJldlxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIC4uLnByZXYsXG4gICAgICAgICAgc3RhbmRhbG9uZUFnZW50Q29udGV4dDogeyAuLi5wcmV2LnN0YW5kYWxvbmVBZ2VudENvbnRleHQsIG5hbWUgfSxcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICB9KVxuICAgIC5jYXRjaChsb2dFcnJvcilcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIEV4aXRQbGFuTW9kZVBlcm1pc3Npb25SZXF1ZXN0KHtcbiAgdG9vbFVzZUNvbmZpcm0sXG4gIG9uRG9uZSxcbiAgb25SZWplY3QsXG4gIHdvcmtlckJhZGdlLFxuICBzZXRTdGlja3lGb290ZXIsXG59OiBQZXJtaXNzaW9uUmVxdWVzdFByb3BzKTogUmVhY3QuUmVhY3ROb2RlIHtcbiAgY29uc3QgdG9vbFBlcm1pc3Npb25Db250ZXh0ID0gdXNlQXBwU3RhdGUocyA9PiBzLnRvb2xQZXJtaXNzaW9uQ29udGV4dClcbiAgY29uc3Qgc2V0QXBwU3RhdGUgPSB1c2VTZXRBcHBTdGF0ZSgpXG4gIGNvbnN0IHN0b3JlID0gdXNlQXBwU3RhdGVTdG9yZSgpXG4gIGNvbnN0IHsgYWRkTm90aWZpY2F0aW9uIH0gPSB1c2VOb3RpZmljYXRpb25zKClcbiAgLy8gRmVlZGJhY2sgdGV4dCBmcm9tIHRoZSAnTm8nIG9wdGlvbidzIGlucHV0LiBUaHJlYWRlZCB0aHJvdWdoIG9uQWxsb3cgYXNcbiAgLy8gYWNjZXB0RmVlZGJhY2sgd2hlbiB0aGUgdXNlciBhcHByb3ZlcyDigJQgbGV0cyB1c2VycyBhbm5vdGF0ZSB0aGUgcGxhblxuICAvLyAoXCJhbHNvIHVwZGF0ZSB0aGUgUkVBRE1FXCIpIHdpdGhvdXQgYSByZWplY3QrcmUtcGxhbiByb3VuZC10cmlwLlxuICBjb25zdCBbcGxhbkZlZWRiYWNrLCBzZXRQbGFuRmVlZGJhY2tdID0gdXNlU3RhdGUoJycpXG4gIGNvbnN0IFtwYXN0ZWRDb250ZW50cywgc2V0UGFzdGVkQ29udGVudHNdID0gdXNlU3RhdGU8XG4gICAgUmVjb3JkPG51bWJlciwgUGFzdGVkQ29udGVudD5cbiAgPih7fSlcbiAgY29uc3QgbmV4dFBhc3RlSWRSZWYgPSB1c2VSZWYoMClcblxuICBjb25zdCBzaG93Q2xlYXJDb250ZXh0ID1cbiAgICB1c2VBcHBTdGF0ZShzID0+IHMuc2V0dGluZ3Muc2hvd0NsZWFyQ29udGV4dE9uUGxhbkFjY2VwdCkgPz8gZmFsc2VcbiAgY29uc3QgdWx0cmFwbGFuU2Vzc2lvblVybCA9IHVzZUFwcFN0YXRlKHMgPT4gcy51bHRyYXBsYW5TZXNzaW9uVXJsKVxuICBjb25zdCB1bHRyYXBsYW5MYXVuY2hpbmcgPSB1c2VBcHBTdGF0ZShzID0+IHMudWx0cmFwbGFuTGF1bmNoaW5nKVxuICAvLyBIaWRlIHRoZSBVbHRyYXBsYW4gYnV0dG9uIHdoaWxlIGEgc2Vzc2lvbiBpcyBhY3RpdmUgb3IgbGF1bmNoaW5nIOKAlFxuICAvLyBzZWxlY3RpbmcgaXQgd291bGQgZGlzbWlzcyB0aGUgZGlhbG9nIGFuZCByZWplY3QgbG9jYWxseSBiZWZvcmVcbiAgLy8gbGF1bmNoVWx0cmFwbGFuIGNhbiBub3RpY2UgdGhlIHNlc3Npb24gZXhpc3RzIGFuZCByZXR1cm4gXCJhbHJlYWR5IHBvbGxpbmdcIi5cbiAgLy8gZmVhdHVyZSgpIG11c3Qgc2l0IGRpcmVjdGx5IGluIGFuIGlmL3Rlcm5hcnkgKGJ1bjpidW5kbGUgRENFIGNvbnN0cmFpbnQpLlxuICBjb25zdCBzaG93VWx0cmFwbGFuID0gZmVhdHVyZSgnVUxUUkFQTEFOJylcbiAgICA/ICF1bHRyYXBsYW5TZXNzaW9uVXJsICYmICF1bHRyYXBsYW5MYXVuY2hpbmdcbiAgICA6IGZhbHNlXG4gIGNvbnN0IHVzYWdlID0gdG9vbFVzZUNvbmZpcm0uYXNzaXN0YW50TWVzc2FnZS5tZXNzYWdlLnVzYWdlXG4gIGNvbnN0IHsgbW9kZSwgaXNBdXRvTW9kZUF2YWlsYWJsZSwgaXNCeXBhc3NQZXJtaXNzaW9uc01vZGVBdmFpbGFibGUgfSA9XG4gICAgdG9vbFBlcm1pc3Npb25Db250ZXh0XG4gIGNvbnN0IG9wdGlvbnMgPSB1c2VNZW1vKFxuICAgICgpID0+XG4gICAgICBidWlsZFBsYW5BcHByb3ZhbE9wdGlvbnMoe1xuICAgICAgICBzaG93Q2xlYXJDb250ZXh0LFxuICAgICAgICBzaG93VWx0cmFwbGFuLFxuICAgICAgICB1c2VkUGVyY2VudDogc2hvd0NsZWFyQ29udGV4dFxuICAgICAgICAgID8gZ2V0Q29udGV4dFVzZWRQZXJjZW50KHVzYWdlLCBtb2RlKVxuICAgICAgICAgIDogbnVsbCxcbiAgICAgICAgaXNBdXRvTW9kZUF2YWlsYWJsZSxcbiAgICAgICAgaXNCeXBhc3NQZXJtaXNzaW9uc01vZGVBdmFpbGFibGUsXG4gICAgICAgIG9uRmVlZGJhY2tDaGFuZ2U6IHNldFBsYW5GZWVkYmFjayxcbiAgICAgIH0pLFxuICAgIFtcbiAgICAgIHNob3dDbGVhckNvbnRleHQsXG4gICAgICBzaG93VWx0cmFwbGFuLFxuICAgICAgdXNhZ2UsXG4gICAgICBtb2RlLFxuICAgICAgaXNBdXRvTW9kZUF2YWlsYWJsZSxcbiAgICAgIGlzQnlwYXNzUGVybWlzc2lvbnNNb2RlQXZhaWxhYmxlLFxuICAgIF0sXG4gIClcblxuICBmdW5jdGlvbiBvbkltYWdlUGFzdGUoXG4gICAgYmFzZTY0SW1hZ2U6IHN0cmluZyxcbiAgICBtZWRpYVR5cGU/OiBzdHJpbmcsXG4gICAgZmlsZW5hbWU/OiBzdHJpbmcsXG4gICAgZGltZW5zaW9ucz86IEltYWdlRGltZW5zaW9ucyxcbiAgICBfc291cmNlUGF0aD86IHN0cmluZyxcbiAgKSB7XG4gICAgY29uc3QgcGFzdGVJZCA9IG5leHRQYXN0ZUlkUmVmLmN1cnJlbnQrK1xuICAgIGNvbnN0IG5ld0NvbnRlbnQ6IFBhc3RlZENvbnRlbnQgPSB7XG4gICAgICBpZDogcGFzdGVJZCxcbiAgICAgIHR5cGU6ICdpbWFnZScsXG4gICAgICBjb250ZW50OiBiYXNlNjRJbWFnZSxcbiAgICAgIG1lZGlhVHlwZTogbWVkaWFUeXBlIHx8ICdpbWFnZS9wbmcnLFxuICAgICAgZmlsZW5hbWU6IGZpbGVuYW1lIHx8ICdQYXN0ZWQgaW1hZ2UnLFxuICAgICAgZGltZW5zaW9ucyxcbiAgICB9XG4gICAgY2FjaGVJbWFnZVBhdGgobmV3Q29udGVudClcbiAgICB2b2lkIHN0b3JlSW1hZ2UobmV3Q29udGVudClcbiAgICBzZXRQYXN0ZWRDb250ZW50cyhwcmV2ID0+ICh7IC4uLnByZXYsIFtwYXN0ZUlkXTogbmV3Q29udGVudCB9KSlcbiAgfVxuXG4gIGNvbnN0IG9uUmVtb3ZlSW1hZ2UgPSB1c2VDYWxsYmFjaygoaWQ6IG51bWJlcikgPT4ge1xuICAgIHNldFBhc3RlZENvbnRlbnRzKHByZXYgPT4ge1xuICAgICAgY29uc3QgbmV4dCA9IHsgLi4ucHJldiB9XG4gICAgICBkZWxldGUgbmV4dFtpZF1cbiAgICAgIHJldHVybiBuZXh0XG4gICAgfSlcbiAgfSwgW10pXG5cbiAgY29uc3QgaW1hZ2VBdHRhY2htZW50cyA9IE9iamVjdC52YWx1ZXMocGFzdGVkQ29udGVudHMpLmZpbHRlcihcbiAgICBjID0+IGMudHlwZSA9PT0gJ2ltYWdlJyxcbiAgKVxuICBjb25zdCBoYXNJbWFnZXMgPSBpbWFnZUF0dGFjaG1lbnRzLmxlbmd0aCA+IDBcblxuICAvLyBUT0RPOiBEZWxldGUgdGhlIGJyYW5jaCBhZnRlciBtb3ZpbmcgdG8gVjJcbiAgLy8gVXNlIHRvb2wgbmFtZSB0byBkZXRlY3QgVjIgaW5zdGVhZCBvZiBjaGVja2luZyBpbnB1dC5wbGFuLCBiZWNhdXNlIFBSICMxMDM5NFxuICAvLyBpbmplY3RzIHBsYW4gY29udGVudCBpbnRvIGlucHV0LnBsYW4gZm9yIGhvb2tzL1NESywgd2hpY2ggYnJva2UgdGhlIG9sZCBkZXRlY3Rpb25cbiAgLy8gKHNlZSBpc3N1ZSAjMTA4NzgpXG4gIGNvbnN0IGlzVjIgPSB0b29sVXNlQ29uZmlybS50b29sLm5hbWUgPT09IEVYSVRfUExBTl9NT0RFX1YyX1RPT0xfTkFNRVxuICBjb25zdCBpbnB1dFBsYW4gPSBpc1YyXG4gICAgPyB1bmRlZmluZWRcbiAgICA6ICh0b29sVXNlQ29uZmlybS5pbnB1dC5wbGFuIGFzIHN0cmluZyB8IHVuZGVmaW5lZClcbiAgY29uc3QgcGxhbkZpbGVQYXRoID0gaXNWMiA/IGdldFBsYW5GaWxlUGF0aCgpIDogdW5kZWZpbmVkXG5cbiAgLy8gRXh0cmFjdCBhbGxvd2VkIHByb21wdHMgcmVxdWVzdGVkIGJ5IHRoZSBwbGFuIChBbnQtb25seSBmZWF0dXJlKVxuICBjb25zdCBhbGxvd2VkUHJvbXB0cyA9IHRvb2xVc2VDb25maXJtLmlucHV0LmFsbG93ZWRQcm9tcHRzIGFzXG4gICAgfCBBbGxvd2VkUHJvbXB0W11cbiAgICB8IHVuZGVmaW5lZFxuXG4gIC8vIEdldCB0aGUgcmF3IHBsYW4gdG8gY2hlY2sgaWYgaXQncyBlbXB0eVxuICBjb25zdCByYXdQbGFuID0gaW5wdXRQbGFuID8/IGdldFBsYW4oKVxuICBjb25zdCBpc0VtcHR5ID0gIXJhd1BsYW4gfHwgcmF3UGxhbi50cmltKCkgPT09ICcnXG5cbiAgLy8gQ2FwdHVyZSB0aGUgdmFyaWFudCBvbmNlIG9uIG1vdW50LiBHcm93dGhCb29rIHJlYWRzIGZyb20gYSBkaXNrIGNhY2hlXG4gIC8vIHNvIHRoZSB2YWx1ZSBpcyBzdGFibGUgYWNyb3NzIGEgc2luZ2xlIHBsYW5uaW5nIHNlc3Npb24uIHVuZGVmaW5lZCA9XG4gIC8vIGNvbnRyb2wgYXJtLiBUaGUgdmFyaWFudCBpcyBhIGZpeGVkIDMtdmFsdWUgZW51bSBvZiBzaG9ydCBsaXRlcmFscyxcbiAgLy8gbm90IHVzZXIgaW5wdXQuXG4gIGNvbnN0IFtwbGFuU3RydWN0dXJlVmFyaWFudF0gPSB1c2VTdGF0ZShcbiAgICAoKSA9PlxuICAgICAgKGdldFBld3RlckxlZGdlclZhcmlhbnQoKSA/P1xuICAgICAgICB1bmRlZmluZWQpIGFzIEFuYWx5dGljc01ldGFkYXRhX0lfVkVSSUZJRURfVEhJU19JU19OT1RfQ09ERV9PUl9GSUxFUEFUSFMsXG4gIClcblxuICBjb25zdCBbY3VycmVudFBsYW4sIHNldEN1cnJlbnRQbGFuXSA9IHVzZVN0YXRlKCgpID0+IHtcbiAgICBpZiAoaW5wdXRQbGFuKSByZXR1cm4gaW5wdXRQbGFuXG4gICAgY29uc3QgcGxhbiA9IGdldFBsYW4oKVxuICAgIHJldHVybiAoXG4gICAgICBwbGFuID8/ICdObyBwbGFuIGZvdW5kLiBQbGVhc2Ugd3JpdGUgeW91ciBwbGFuIHRvIHRoZSBwbGFuIGZpbGUgZmlyc3QuJ1xuICAgIClcbiAgfSlcbiAgY29uc3QgW3Nob3dTYXZlTWVzc2FnZSwgc2V0U2hvd1NhdmVNZXNzYWdlXSA9IHVzZVN0YXRlKGZhbHNlKVxuICAvLyBUcmFjayBDdHJsK0cgbG9jYWwgZWRpdHMgc28gdXBkYXRlZElucHV0IGNhbiBpbmNsdWRlIHRoZSBwbGFuICh0aGUgdG9vbFxuICAvLyBvbmx5IGVjaG9lcyB0aGUgcGxhbiBpbiB0b29sX3Jlc3VsdCB3aGVuIGlucHV0LnBsYW4gaXMgc2V0IOKAlCBvdGhlcndpc2VcbiAgLy8gdGhlIG1vZGVsIGFscmVhZHkgaGFzIGl0IGluIGNvbnRleHQgZnJvbSB3cml0aW5nIHRoZSBwbGFuIGZpbGUpLlxuICBjb25zdCBbcGxhbkVkaXRlZExvY2FsbHksIHNldFBsYW5FZGl0ZWRMb2NhbGx5XSA9IHVzZVN0YXRlKGZhbHNlKVxuXG4gIC8vIEF1dG8taGlkZSBzYXZlIG1lc3NhZ2UgYWZ0ZXIgNSBzZWNvbmRzXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKHNob3dTYXZlTWVzc2FnZSkge1xuICAgICAgY29uc3QgdGltZXIgPSBzZXRUaW1lb3V0KHNldFNob3dTYXZlTWVzc2FnZSwgNTAwMCwgZmFsc2UpXG4gICAgICByZXR1cm4gKCkgPT4gY2xlYXJUaW1lb3V0KHRpbWVyKVxuICAgIH1cbiAgfSwgW3Nob3dTYXZlTWVzc2FnZV0pXG5cbiAgLy8gSGFuZGxlIEN0cmwrRyB0byBlZGl0IHBsYW4gaW4gJEVESVRPUiwgU2hpZnQrVGFiIGZvciBhdXRvLWFjY2VwdCBlZGl0c1xuICBjb25zdCBoYW5kbGVLZXlEb3duID0gKGU6IEtleWJvYXJkRXZlbnQpOiB2b2lkID0+IHtcbiAgICBpZiAoZS5jdHJsICYmIGUua2V5ID09PSAnZycpIHtcbiAgICAgIGUucHJldmVudERlZmF1bHQoKVxuICAgICAgbG9nRXZlbnQoJ3Rlbmd1X3BsYW5fZXh0ZXJuYWxfZWRpdG9yX3VzZWQnLCB7fSlcblxuICAgICAgdm9pZCAoYXN5bmMgKCkgPT4ge1xuICAgICAgICBpZiAoaXNWMiAmJiBwbGFuRmlsZVBhdGgpIHtcbiAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBlZGl0RmlsZUluRWRpdG9yKHBsYW5GaWxlUGF0aClcbiAgICAgICAgICBpZiAocmVzdWx0LmVycm9yKSB7XG4gICAgICAgICAgICBhZGROb3RpZmljYXRpb24oe1xuICAgICAgICAgICAgICBrZXk6ICdleHRlcm5hbC1lZGl0b3ItZXJyb3InLFxuICAgICAgICAgICAgICB0ZXh0OiByZXN1bHQuZXJyb3IsXG4gICAgICAgICAgICAgIGNvbG9yOiAnd2FybmluZycsXG4gICAgICAgICAgICAgIHByaW9yaXR5OiAnaGlnaCcsXG4gICAgICAgICAgICB9KVxuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAocmVzdWx0LmNvbnRlbnQgIT09IG51bGwpIHtcbiAgICAgICAgICAgIGlmIChyZXN1bHQuY29udGVudCAhPT0gY3VycmVudFBsYW4pIHNldFBsYW5FZGl0ZWRMb2NhbGx5KHRydWUpXG4gICAgICAgICAgICBzZXRDdXJyZW50UGxhbihyZXN1bHQuY29udGVudClcbiAgICAgICAgICAgIHNldFNob3dTYXZlTWVzc2FnZSh0cnVlKVxuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBlZGl0UHJvbXB0SW5FZGl0b3IoY3VycmVudFBsYW4pXG4gICAgICAgICAgaWYgKHJlc3VsdC5lcnJvcikge1xuICAgICAgICAgICAgYWRkTm90aWZpY2F0aW9uKHtcbiAgICAgICAgICAgICAga2V5OiAnZXh0ZXJuYWwtZWRpdG9yLWVycm9yJyxcbiAgICAgICAgICAgICAgdGV4dDogcmVzdWx0LmVycm9yLFxuICAgICAgICAgICAgICBjb2xvcjogJ3dhcm5pbmcnLFxuICAgICAgICAgICAgICBwcmlvcml0eTogJ2hpZ2gnLFxuICAgICAgICAgICAgfSlcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHJlc3VsdC5jb250ZW50ICE9PSBudWxsICYmIHJlc3VsdC5jb250ZW50ICE9PSBjdXJyZW50UGxhbikge1xuICAgICAgICAgICAgc2V0Q3VycmVudFBsYW4ocmVzdWx0LmNvbnRlbnQpXG4gICAgICAgICAgICBzZXRTaG93U2F2ZU1lc3NhZ2UodHJ1ZSlcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0pKClcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIC8vIFNoaWZ0K1RhYiBpbW1lZGlhdGVseSBzZWxlY3RzIFwiYXV0by1hY2NlcHQgZWRpdHNcIlxuICAgIGlmIChlLnNoaWZ0ICYmIGUua2V5ID09PSAndGFiJykge1xuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpXG4gICAgICB2b2lkIGhhbmRsZVJlc3BvbnNlKFxuICAgICAgICBzaG93Q2xlYXJDb250ZXh0ID8gJ3llcy1hY2NlcHQtZWRpdHMnIDogJ3llcy1hY2NlcHQtZWRpdHMta2VlcC1jb250ZXh0JyxcbiAgICAgIClcbiAgICAgIHJldHVyblxuICAgIH1cbiAgfVxuXG4gIGFzeW5jIGZ1bmN0aW9uIGhhbmRsZVJlc3BvbnNlKHZhbHVlOiBSZXNwb25zZVZhbHVlKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgdHJpbW1lZEZlZWRiYWNrID0gcGxhbkZlZWRiYWNrLnRyaW0oKVxuICAgIGNvbnN0IGFjY2VwdEZlZWRiYWNrID0gdHJpbW1lZEZlZWRiYWNrIHx8IHVuZGVmaW5lZFxuXG4gICAgLy8gVWx0cmFwbGFuOiByZWplY3QgbG9jYWxseSwgdGVsZXBvcnQgdGhlIHBsYW4gdG8gQ0NSIGFzIGEgc2VlZCBkcmFmdC5cbiAgICAvLyBEaWFsb2cgZGlzbWlzc2VzIGltbWVkaWF0ZWx5IHNvIHRoZSBxdWVyeSBsb29wIHVuYmxvY2tzOyB0aGUgdGVsZXBvcnRcbiAgICAvLyBydW5zIGRldGFjaGVkIGFuZCBpdHMgbGF1bmNoIG1lc3NhZ2UgbGFuZHMgdmlhIHRoZSBjb21tYW5kIHF1ZXVlLlxuICAgIGlmICh2YWx1ZSA9PT0gJ3VsdHJhcGxhbicpIHtcbiAgICAgIGxvZ0V2ZW50KCd0ZW5ndV9wbGFuX2V4aXQnLCB7XG4gICAgICAgIHBsYW5MZW5ndGhDaGFyczogY3VycmVudFBsYW4ubGVuZ3RoLFxuICAgICAgICBvdXRjb21lOlxuICAgICAgICAgICd1bHRyYXBsYW4nIGFzIEFuYWx5dGljc01ldGFkYXRhX0lfVkVSSUZJRURfVEhJU19JU19OT1RfQ09ERV9PUl9GSUxFUEFUSFMsXG4gICAgICAgIGludGVydmlld1BoYXNlRW5hYmxlZDogaXNQbGFuTW9kZUludGVydmlld1BoYXNlRW5hYmxlZCgpLFxuICAgICAgICBwbGFuU3RydWN0dXJlVmFyaWFudCxcbiAgICAgIH0pXG4gICAgICBvbkRvbmUoKVxuICAgICAgb25SZWplY3QoKVxuICAgICAgdG9vbFVzZUNvbmZpcm0ub25SZWplY3QoXG4gICAgICAgICdQbGFuIGJlaW5nIHJlZmluZWQgdmlhIFVsdHJhcGxhbiDigJQgcGxlYXNlIHdhaXQgZm9yIHRoZSByZXN1bHQuJyxcbiAgICAgIClcbiAgICAgIHZvaWQgbGF1bmNoVWx0cmFwbGFuKHtcbiAgICAgICAgYmx1cmI6ICcnLFxuICAgICAgICBzZWVkUGxhbjogY3VycmVudFBsYW4sXG4gICAgICAgIGdldEFwcFN0YXRlOiBzdG9yZS5nZXRTdGF0ZSxcbiAgICAgICAgc2V0QXBwU3RhdGU6IHN0b3JlLnNldFN0YXRlLFxuICAgICAgICBzaWduYWw6IG5ldyBBYm9ydENvbnRyb2xsZXIoKS5zaWduYWwsXG4gICAgICB9KVxuICAgICAgICAudGhlbihtc2cgPT5cbiAgICAgICAgICBlbnF1ZXVlUGVuZGluZ05vdGlmaWNhdGlvbih7IHZhbHVlOiBtc2csIG1vZGU6ICd0YXNrLW5vdGlmaWNhdGlvbicgfSksXG4gICAgICAgIClcbiAgICAgICAgLmNhdGNoKGxvZ0Vycm9yKVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgLy8gVjE6IHBhc3MgcGxhbiBpbiBpbnB1dC4gVjI6IHBsYW4gaXMgb24gZGlzaywgYnV0IGlmIHRoZSB1c2VyIGVkaXRlZCBpdFxuICAgIC8vIHZpYSBDdHJsK0cgd2UgcGFzcyBpdCB0aHJvdWdoIHNvIHRoZSB0b29sIGVjaG9lcyB0aGUgZWRpdCBpbiB0b29sX3Jlc3VsdFxuICAgIC8vIChvdGhlcndpc2UgdGhlIG1vZGVsIG5ldmVyIHNlZXMgdGhlIHVzZXIncyBjaGFuZ2VzKS5cbiAgICBjb25zdCB1cGRhdGVkSW5wdXQgPSBpc1YyICYmICFwbGFuRWRpdGVkTG9jYWxseSA/IHt9IDogeyBwbGFuOiBjdXJyZW50UGxhbiB9XG5cbiAgICAvLyBJZiBhdXRvIHdhcyBhY3RpdmUgZHVyaW5nIHBsYW4gKGZyb20gYXV0byBtb2RlIG9yIG9wdC1pbikgYW5kIE5PVCBnb2luZ1xuICAgIC8vIHRvIGF1dG8sIGRlYWN0aXZhdGUgYXV0byArIHJlc3RvcmUgcGVybWlzc2lvbnMgKyBmaXJlIGV4aXQgYXR0YWNobWVudC5cbiAgICBpZiAoZmVhdHVyZSgnVFJBTlNDUklQVF9DTEFTU0lGSUVSJykpIHtcbiAgICAgIGNvbnN0IGdvaW5nVG9BdXRvID1cbiAgICAgICAgKHZhbHVlID09PSAneWVzLXJlc3VtZS1hdXRvLW1vZGUnIHx8XG4gICAgICAgICAgdmFsdWUgPT09ICd5ZXMtYXV0by1jbGVhci1jb250ZXh0JykgJiZcbiAgICAgICAgaXNBdXRvTW9kZUdhdGVFbmFibGVkKClcbiAgICAgIC8vIGlzQXV0b01vZGVBY3RpdmUoKSBpcyB0aGUgYXV0aG9yaXRhdGl2ZSBzaWduYWwg4oCUIHByZVBsYW5Nb2RlL1xuICAgICAgLy8gc3RyaXBwZWREYW5nZXJvdXNSdWxlcyBhcmUgc3RhbGUgYWZ0ZXIgdHJhbnNpdGlvblBsYW5BdXRvTW9kZVxuICAgICAgLy8gZGVhY3RpdmF0ZXMgbWlkLXBsYW4gKHdvdWxkIGNhdXNlIGR1cGxpY2F0ZSBleGl0IGF0dGFjaG1lbnQpLlxuICAgICAgY29uc3QgYXV0b1dhc1VzZWREdXJpbmdQbGFuID1cbiAgICAgICAgYXV0b01vZGVTdGF0ZU1vZHVsZT8uaXNBdXRvTW9kZUFjdGl2ZSgpID8/IGZhbHNlXG4gICAgICBpZiAodmFsdWUgIT09ICdubycgJiYgIWdvaW5nVG9BdXRvICYmIGF1dG9XYXNVc2VkRHVyaW5nUGxhbikge1xuICAgICAgICBhdXRvTW9kZVN0YXRlTW9kdWxlPy5zZXRBdXRvTW9kZUFjdGl2ZShmYWxzZSlcbiAgICAgICAgc2V0TmVlZHNBdXRvTW9kZUV4aXRBdHRhY2htZW50KHRydWUpXG4gICAgICAgIHNldEFwcFN0YXRlKHByZXYgPT4gKHtcbiAgICAgICAgICAuLi5wcmV2LFxuICAgICAgICAgIHRvb2xQZXJtaXNzaW9uQ29udGV4dDoge1xuICAgICAgICAgICAgLi4ucmVzdG9yZURhbmdlcm91c1Blcm1pc3Npb25zKHByZXYudG9vbFBlcm1pc3Npb25Db250ZXh0KSxcbiAgICAgICAgICAgIHByZVBsYW5Nb2RlOiB1bmRlZmluZWQsXG4gICAgICAgICAgfSxcbiAgICAgICAgfSkpXG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gQ2xlYXItY29udGV4dCBvcHRpb25zOiBzZXQgcGVuZGluZyBwbGFuIGltcGxlbWVudGF0aW9uIGFuZCByZWplY3QgdGhlIGRpYWxvZ1xuICAgIC8vIFRoZSBSRVBMIHdpbGwgaGFuZGxlIGNvbnRleHQgY2xlYXIgYW5kIHRyaWdnZXIgYSBmcmVzaCBxdWVyeVxuICAgIC8vIEtlZXAtY29udGV4dCBvcHRpb25zIHNraXAgdGhpcyBibG9jayBhbmQgZ28gdGhyb3VnaCB0aGUgbm9ybWFsIGZsb3cgYmVsb3dcbiAgICBjb25zdCBpc1Jlc3VtZUF1dG9PcHRpb24gPSBmZWF0dXJlKCdUUkFOU0NSSVBUX0NMQVNTSUZJRVInKVxuICAgICAgPyB2YWx1ZSA9PT0gJ3llcy1yZXN1bWUtYXV0by1tb2RlJ1xuICAgICAgOiBmYWxzZVxuICAgIGNvbnN0IGlzS2VlcENvbnRleHRPcHRpb24gPVxuICAgICAgdmFsdWUgPT09ICd5ZXMtYWNjZXB0LWVkaXRzLWtlZXAtY29udGV4dCcgfHxcbiAgICAgIHZhbHVlID09PSAneWVzLWRlZmF1bHQta2VlcC1jb250ZXh0JyB8fFxuICAgICAgaXNSZXN1bWVBdXRvT3B0aW9uXG5cbiAgICBpZiAodmFsdWUgIT09ICdubycpIHtcbiAgICAgIGF1dG9OYW1lU2Vzc2lvbkZyb21QbGFuKGN1cnJlbnRQbGFuLCBzZXRBcHBTdGF0ZSwgIWlzS2VlcENvbnRleHRPcHRpb24pXG4gICAgfVxuXG4gICAgaWYgKHZhbHVlICE9PSAnbm8nICYmICFpc0tlZXBDb250ZXh0T3B0aW9uKSB7XG4gICAgICAvLyBEZXRlcm1pbmUgdGhlIHBlcm1pc3Npb24gbW9kZSBiYXNlZCBvbiB0aGUgc2VsZWN0ZWQgb3B0aW9uXG4gICAgICBsZXQgbW9kZTogUGVybWlzc2lvbk1vZGUgPSAnZGVmYXVsdCdcbiAgICAgIGlmICh2YWx1ZSA9PT0gJ3llcy1ieXBhc3MtcGVybWlzc2lvbnMnKSB7XG4gICAgICAgIG1vZGUgPSAnYnlwYXNzUGVybWlzc2lvbnMnXG4gICAgICB9IGVsc2UgaWYgKHZhbHVlID09PSAneWVzLWFjY2VwdC1lZGl0cycpIHtcbiAgICAgICAgbW9kZSA9ICdhY2NlcHRFZGl0cydcbiAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgIGZlYXR1cmUoJ1RSQU5TQ1JJUFRfQ0xBU1NJRklFUicpICYmXG4gICAgICAgIHZhbHVlID09PSAneWVzLWF1dG8tY2xlYXItY29udGV4dCcgJiZcbiAgICAgICAgaXNBdXRvTW9kZUdhdGVFbmFibGVkKClcbiAgICAgICkge1xuICAgICAgICAvLyBSRVBMJ3MgcHJvY2Vzc0luaXRpYWxNZXNzYWdlIGhhbmRsZXMgc3RyaXBEYW5nZXJvdXNQZXJtaXNzaW9ucyArIG1vZGUsXG4gICAgICAgIC8vIGJ1dCBkb2VzIE5PVCBzZXQgYXV0b01vZGVBY3RpdmUuIEdhdGUtb2ZmIGZhbGxzIHRocm91Z2ggdG8gJ2RlZmF1bHQnLlxuICAgICAgICBtb2RlID0gJ2F1dG8nXG4gICAgICAgIGF1dG9Nb2RlU3RhdGVNb2R1bGU/LnNldEF1dG9Nb2RlQWN0aXZlKHRydWUpXG4gICAgICB9XG5cbiAgICAgIC8vIExvZyBwbGFuIGV4aXQgZXZlbnRcbiAgICAgIGxvZ0V2ZW50KCd0ZW5ndV9wbGFuX2V4aXQnLCB7XG4gICAgICAgIHBsYW5MZW5ndGhDaGFyczogY3VycmVudFBsYW4ubGVuZ3RoLFxuICAgICAgICBvdXRjb21lOlxuICAgICAgICAgIHZhbHVlIGFzIEFuYWx5dGljc01ldGFkYXRhX0lfVkVSSUZJRURfVEhJU19JU19OT1RfQ09ERV9PUl9GSUxFUEFUSFMsXG4gICAgICAgIGNsZWFyQ29udGV4dDogdHJ1ZSxcbiAgICAgICAgaW50ZXJ2aWV3UGhhc2VFbmFibGVkOiBpc1BsYW5Nb2RlSW50ZXJ2aWV3UGhhc2VFbmFibGVkKCksXG4gICAgICAgIHBsYW5TdHJ1Y3R1cmVWYXJpYW50LFxuICAgICAgICBoYXNGZWVkYmFjazogISFhY2NlcHRGZWVkYmFjayxcbiAgICAgIH0pXG5cbiAgICAgIC8vIFNldCBpbml0aWFsIG1lc3NhZ2UgLSBSRVBMIHdpbGwgaGFuZGxlIGNvbnRleHQgY2xlYXIgYW5kIGZyZXNoIHF1ZXJ5XG4gICAgICAvLyBBZGQgdmVyaWZpY2F0aW9uIGluc3RydWN0aW9uIGlmIHRoZSBmZWF0dXJlIGlzIGVuYWJsZWRcbiAgICAgIC8vIERlYWQgY29kZSBlbGltaW5hdGlvbjogQ0xBVURFX0NPREVfVkVSSUZZX1BMQU49J2ZhbHNlJyBpbiBleHRlcm5hbCBidWlsZHMsIHNvID09PSAndHJ1ZScgY2hlY2sgYWxsb3dzIEJ1biB0byBlbGltaW5hdGUgdGhlIHN0cmluZ1xuICAgICAgY29uc3QgdmVyaWZpY2F0aW9uSW5zdHJ1Y3Rpb24gPVxuICAgICAgICB1bmRlZmluZWQgPT09ICd0cnVlJ1xuICAgICAgICAgID8gYFxcblxcbklNUE9SVEFOVDogV2hlbiB5b3UgaGF2ZSBmaW5pc2hlZCBpbXBsZW1lbnRpbmcgdGhlIHBsYW4sIHlvdSBNVVNUIGNhbGwgdGhlIFwiVmVyaWZ5UGxhbkV4ZWN1dGlvblwiIHRvb2wgZGlyZWN0bHkgKE5PVCB0aGUgJHtBR0VOVF9UT09MX05BTUV9IHRvb2wgb3IgYW4gYWdlbnQpIHRvIHRyaWdnZXIgYmFja2dyb3VuZCB2ZXJpZmljYXRpb24uYFxuICAgICAgICAgIDogJydcblxuICAgICAgLy8gQ2FwdHVyZSB0aGUgdHJhbnNjcmlwdCBwYXRoIGJlZm9yZSBjb250ZXh0IGlzIGNsZWFyZWQgKHNlc3Npb24gSUQgd2lsbCBiZSByZWdlbmVyYXRlZClcbiAgICAgIGNvbnN0IHRyYW5zY3JpcHRQYXRoID0gZ2V0VHJhbnNjcmlwdFBhdGgoKVxuICAgICAgY29uc3QgdHJhbnNjcmlwdEhpbnQgPSBgXFxuXFxuSWYgeW91IG5lZWQgc3BlY2lmaWMgZGV0YWlscyBmcm9tIGJlZm9yZSBleGl0aW5nIHBsYW4gbW9kZSAobGlrZSBleGFjdCBjb2RlIHNuaXBwZXRzLCBlcnJvciBtZXNzYWdlcywgb3IgY29udGVudCB5b3UgZ2VuZXJhdGVkKSwgcmVhZCB0aGUgZnVsbCB0cmFuc2NyaXB0IGF0OiAke3RyYW5zY3JpcHRQYXRofWBcblxuICAgICAgY29uc3QgdGVhbUhpbnQgPSBpc0FnZW50U3dhcm1zRW5hYmxlZCgpXG4gICAgICAgID8gYFxcblxcbklmIHRoaXMgcGxhbiBjYW4gYmUgYnJva2VuIGRvd24gaW50byBtdWx0aXBsZSBpbmRlcGVuZGVudCB0YXNrcywgY29uc2lkZXIgdXNpbmcgdGhlICR7VEVBTV9DUkVBVEVfVE9PTF9OQU1FfSB0b29sIHRvIGNyZWF0ZSBhIHRlYW0gYW5kIHBhcmFsbGVsaXplIHRoZSB3b3JrLmBcbiAgICAgICAgOiAnJ1xuXG4gICAgICBjb25zdCBmZWVkYmFja1N1ZmZpeCA9IGFjY2VwdEZlZWRiYWNrXG4gICAgICAgID8gYFxcblxcblVzZXIgZmVlZGJhY2sgb24gdGhpcyBwbGFuOiAke2FjY2VwdEZlZWRiYWNrfWBcbiAgICAgICAgOiAnJ1xuXG4gICAgICBzZXRBcHBTdGF0ZShwcmV2ID0+ICh7XG4gICAgICAgIC4uLnByZXYsXG4gICAgICAgIGluaXRpYWxNZXNzYWdlOiB7XG4gICAgICAgICAgbWVzc2FnZToge1xuICAgICAgICAgICAgLi4uY3JlYXRlVXNlck1lc3NhZ2Uoe1xuICAgICAgICAgICAgICBjb250ZW50OiBgSW1wbGVtZW50IHRoZSBmb2xsb3dpbmcgcGxhbjpcXG5cXG4ke2N1cnJlbnRQbGFufSR7dmVyaWZpY2F0aW9uSW5zdHJ1Y3Rpb259JHt0cmFuc2NyaXB0SGludH0ke3RlYW1IaW50fSR7ZmVlZGJhY2tTdWZmaXh9YCxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgcGxhbkNvbnRlbnQ6IGN1cnJlbnRQbGFuLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgY2xlYXJDb250ZXh0OiB0cnVlLFxuICAgICAgICAgIG1vZGUsXG4gICAgICAgICAgYWxsb3dlZFByb21wdHMsXG4gICAgICAgIH0sXG4gICAgICB9KSlcblxuICAgICAgc2V0SGFzRXhpdGVkUGxhbk1vZGUodHJ1ZSlcbiAgICAgIG9uRG9uZSgpXG4gICAgICBvblJlamVjdCgpXG4gICAgICAvLyBSZWplY3QgdGhlIHRvb2wgdXNlIHRvIHVuYmxvY2sgdGhlIHF1ZXJ5IGxvb3BcbiAgICAgIC8vIFRoZSBSRVBMIHdpbGwgc2VlIHBlbmRpbmdJbml0aWFsUXVlcnkgYW5kIHRyaWdnZXIgZnJlc2ggcXVlcnlcbiAgICAgIHRvb2xVc2VDb25maXJtLm9uUmVqZWN0KClcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIC8vIEhhbmRsZSBhdXRvIGtlZXAtY29udGV4dCBvcHRpb24g4oCUIG5lZWRzIHNwZWNpYWwgaGFuZGxpbmcgYmVjYXVzZVxuICAgIC8vIGJ1aWxkUGVybWlzc2lvblVwZGF0ZXMgbWFwcyBhdXRvIHRvICdkZWZhdWx0JyB2aWEgdG9FeHRlcm5hbFBlcm1pc3Npb25Nb2RlLlxuICAgIC8vIFdlIHNldCB0aGUgbW9kZSBkaXJlY3RseSB2aWEgc2V0QXBwU3RhdGUgYW5kIHN5bmMgdGhlIGJvb3RzdHJhcCBzdGF0ZS5cbiAgICBpZiAoXG4gICAgICBmZWF0dXJlKCdUUkFOU0NSSVBUX0NMQVNTSUZJRVInKSAmJlxuICAgICAgdmFsdWUgPT09ICd5ZXMtcmVzdW1lLWF1dG8tbW9kZScgJiZcbiAgICAgIGlzQXV0b01vZGVHYXRlRW5hYmxlZCgpXG4gICAgKSB7XG4gICAgICBsb2dFdmVudCgndGVuZ3VfcGxhbl9leGl0Jywge1xuICAgICAgICBwbGFuTGVuZ3RoQ2hhcnM6IGN1cnJlbnRQbGFuLmxlbmd0aCxcbiAgICAgICAgb3V0Y29tZTpcbiAgICAgICAgICB2YWx1ZSBhcyBBbmFseXRpY3NNZXRhZGF0YV9JX1ZFUklGSUVEX1RISVNfSVNfTk9UX0NPREVfT1JfRklMRVBBVEhTLFxuICAgICAgICBjbGVhckNvbnRleHQ6IGZhbHNlLFxuICAgICAgICBpbnRlcnZpZXdQaGFzZUVuYWJsZWQ6IGlzUGxhbk1vZGVJbnRlcnZpZXdQaGFzZUVuYWJsZWQoKSxcbiAgICAgICAgcGxhblN0cnVjdHVyZVZhcmlhbnQsXG4gICAgICAgIGhhc0ZlZWRiYWNrOiAhIWFjY2VwdEZlZWRiYWNrLFxuICAgICAgfSlcbiAgICAgIHNldEhhc0V4aXRlZFBsYW5Nb2RlKHRydWUpXG4gICAgICBzZXROZWVkc1BsYW5Nb2RlRXhpdEF0dGFjaG1lbnQodHJ1ZSlcbiAgICAgIGF1dG9Nb2RlU3RhdGVNb2R1bGU/LnNldEF1dG9Nb2RlQWN0aXZlKHRydWUpXG4gICAgICBzZXRBcHBTdGF0ZShwcmV2ID0+ICh7XG4gICAgICAgIC4uLnByZXYsXG4gICAgICAgIHRvb2xQZXJtaXNzaW9uQ29udGV4dDogc3RyaXBEYW5nZXJvdXNQZXJtaXNzaW9uc0ZvckF1dG9Nb2RlKHtcbiAgICAgICAgICAuLi5wcmV2LnRvb2xQZXJtaXNzaW9uQ29udGV4dCxcbiAgICAgICAgICBtb2RlOiAnYXV0bycsXG4gICAgICAgICAgcHJlUGxhbk1vZGU6IHVuZGVmaW5lZCxcbiAgICAgICAgfSksXG4gICAgICB9KSlcbiAgICAgIG9uRG9uZSgpXG4gICAgICB0b29sVXNlQ29uZmlybS5vbkFsbG93KHVwZGF0ZWRJbnB1dCwgW10sIGFjY2VwdEZlZWRiYWNrKVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgLy8gSGFuZGxlIGtlZXAtY29udGV4dCBvcHRpb25zIChnb2VzIHRocm91Z2ggbm9ybWFsIG9uQWxsb3cgZmxvdylcbiAgICAvLyB5ZXMtcmVzdW1lLWF1dG8tbW9kZSBmYWxscyB0aHJvdWdoIGhlcmUgd2hlbiB0aGUgYXV0byBtb2RlIGdhdGUgaXNcbiAgICAvLyBkaXNhYmxlZCAoZS5nLiBjaXJjdWl0IGJyZWFrZXIgZmlyZWQgYWZ0ZXIgdGhlIGRpYWxvZyByZW5kZXJlZCkuXG4gICAgLy8gV2l0aG91dCB0aGlzIGZhbGxiYWNrIHRoZSBmdW5jdGlvbiB3b3VsZCByZXR1cm4gd2l0aG91dCByZXNvbHZpbmcgdGhlXG4gICAgLy8gZGlhbG9nLCBsZWF2aW5nIHRoZSBxdWVyeSBsb29wIGJsb2NrZWQgYW5kIHNhZmV0eSBzdGF0ZSBjb3JydXB0ZWQuXG4gICAgY29uc3Qga2VlcENvbnRleHRNb2RlczogUmVjb3JkPHN0cmluZywgUGVybWlzc2lvbk1vZGU+ID0ge1xuICAgICAgJ3llcy1hY2NlcHQtZWRpdHMta2VlcC1jb250ZXh0JzpcbiAgICAgICAgdG9vbFBlcm1pc3Npb25Db250ZXh0LmlzQnlwYXNzUGVybWlzc2lvbnNNb2RlQXZhaWxhYmxlXG4gICAgICAgICAgPyAnYnlwYXNzUGVybWlzc2lvbnMnXG4gICAgICAgICAgOiAnYWNjZXB0RWRpdHMnLFxuICAgICAgJ3llcy1kZWZhdWx0LWtlZXAtY29udGV4dCc6ICdkZWZhdWx0JyxcbiAgICAgIC4uLihmZWF0dXJlKCdUUkFOU0NSSVBUX0NMQVNTSUZJRVInKVxuICAgICAgICA/IHsgJ3llcy1yZXN1bWUtYXV0by1tb2RlJzogJ2RlZmF1bHQnIGFzIGNvbnN0IH1cbiAgICAgICAgOiB7fSksXG4gICAgfVxuICAgIGNvbnN0IGtlZXBDb250ZXh0TW9kZSA9IGtlZXBDb250ZXh0TW9kZXNbdmFsdWVdXG4gICAgaWYgKGtlZXBDb250ZXh0TW9kZSkge1xuICAgICAgbG9nRXZlbnQoJ3Rlbmd1X3BsYW5fZXhpdCcsIHtcbiAgICAgICAgcGxhbkxlbmd0aENoYXJzOiBjdXJyZW50UGxhbi5sZW5ndGgsXG4gICAgICAgIG91dGNvbWU6XG4gICAgICAgICAgdmFsdWUgYXMgQW5hbHl0aWNzTWV0YWRhdGFfSV9WRVJJRklFRF9USElTX0lTX05PVF9DT0RFX09SX0ZJTEVQQVRIUyxcbiAgICAgICAgY2xlYXJDb250ZXh0OiBmYWxzZSxcbiAgICAgICAgaW50ZXJ2aWV3UGhhc2VFbmFibGVkOiBpc1BsYW5Nb2RlSW50ZXJ2aWV3UGhhc2VFbmFibGVkKCksXG4gICAgICAgIHBsYW5TdHJ1Y3R1cmVWYXJpYW50LFxuICAgICAgICBoYXNGZWVkYmFjazogISFhY2NlcHRGZWVkYmFjayxcbiAgICAgIH0pXG4gICAgICBzZXRIYXNFeGl0ZWRQbGFuTW9kZSh0cnVlKVxuICAgICAgc2V0TmVlZHNQbGFuTW9kZUV4aXRBdHRhY2htZW50KHRydWUpXG4gICAgICBvbkRvbmUoKVxuICAgICAgdG9vbFVzZUNvbmZpcm0ub25BbGxvdyhcbiAgICAgICAgdXBkYXRlZElucHV0LFxuICAgICAgICBidWlsZFBlcm1pc3Npb25VcGRhdGVzKGtlZXBDb250ZXh0TW9kZSwgYWxsb3dlZFByb21wdHMpLFxuICAgICAgICBhY2NlcHRGZWVkYmFjayxcbiAgICAgIClcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIC8vIEhhbmRsZSBzdGFuZGFyZCBhcHByb3ZhbCBvcHRpb25zXG4gICAgY29uc3Qgc3RhbmRhcmRNb2RlczogUmVjb3JkPHN0cmluZywgUGVybWlzc2lvbk1vZGU+ID0ge1xuICAgICAgJ3llcy1ieXBhc3MtcGVybWlzc2lvbnMnOiAnYnlwYXNzUGVybWlzc2lvbnMnLFxuICAgICAgJ3llcy1hY2NlcHQtZWRpdHMnOiAnYWNjZXB0RWRpdHMnLFxuICAgIH1cbiAgICBjb25zdCBzdGFuZGFyZE1vZGUgPSBzdGFuZGFyZE1vZGVzW3ZhbHVlXVxuICAgIGlmIChzdGFuZGFyZE1vZGUpIHtcbiAgICAgIGxvZ0V2ZW50KCd0ZW5ndV9wbGFuX2V4aXQnLCB7XG4gICAgICAgIHBsYW5MZW5ndGhDaGFyczogY3VycmVudFBsYW4ubGVuZ3RoLFxuICAgICAgICBvdXRjb21lOlxuICAgICAgICAgIHZhbHVlIGFzIEFuYWx5dGljc01ldGFkYXRhX0lfVkVSSUZJRURfVEhJU19JU19OT1RfQ09ERV9PUl9GSUxFUEFUSFMsXG4gICAgICAgIGludGVydmlld1BoYXNlRW5hYmxlZDogaXNQbGFuTW9kZUludGVydmlld1BoYXNlRW5hYmxlZCgpLFxuICAgICAgICBwbGFuU3RydWN0dXJlVmFyaWFudCxcbiAgICAgICAgaGFzRmVlZGJhY2s6ICEhYWNjZXB0RmVlZGJhY2ssXG4gICAgICB9KVxuICAgICAgc2V0SGFzRXhpdGVkUGxhbk1vZGUodHJ1ZSlcbiAgICAgIHNldE5lZWRzUGxhbk1vZGVFeGl0QXR0YWNobWVudCh0cnVlKVxuICAgICAgb25Eb25lKClcbiAgICAgIHRvb2xVc2VDb25maXJtLm9uQWxsb3coXG4gICAgICAgIHVwZGF0ZWRJbnB1dCxcbiAgICAgICAgYnVpbGRQZXJtaXNzaW9uVXBkYXRlcyhzdGFuZGFyZE1vZGUsIGFsbG93ZWRQcm9tcHRzKSxcbiAgICAgICAgYWNjZXB0RmVlZGJhY2ssXG4gICAgICApXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICAvLyBIYW5kbGUgJ25vJyAtIHN0YXkgaW4gcGxhbiBtb2RlXG4gICAgaWYgKHZhbHVlID09PSAnbm8nKSB7XG4gICAgICBpZiAoIXRyaW1tZWRGZWVkYmFjayAmJiAhaGFzSW1hZ2VzKSB7XG4gICAgICAgIC8vIE5vIGZlZWRiYWNrIHlldCAtIHVzZXIgaXMgc3RpbGwgb24gdGhlIGlucHV0IGZpZWxkXG4gICAgICAgIHJldHVyblxuICAgICAgfVxuXG4gICAgICBsb2dFdmVudCgndGVuZ3VfcGxhbl9leGl0Jywge1xuICAgICAgICBwbGFuTGVuZ3RoQ2hhcnM6IGN1cnJlbnRQbGFuLmxlbmd0aCxcbiAgICAgICAgb3V0Y29tZTpcbiAgICAgICAgICAnbm8nIGFzIEFuYWx5dGljc01ldGFkYXRhX0lfVkVSSUZJRURfVEhJU19JU19OT1RfQ09ERV9PUl9GSUxFUEFUSFMsXG4gICAgICAgIGludGVydmlld1BoYXNlRW5hYmxlZDogaXNQbGFuTW9kZUludGVydmlld1BoYXNlRW5hYmxlZCgpLFxuICAgICAgICBwbGFuU3RydWN0dXJlVmFyaWFudCxcbiAgICAgIH0pXG5cbiAgICAgIC8vIENvbnZlcnQgcGFzdGVkIGltYWdlcyB0byBJbWFnZUJsb2NrUGFyYW1bXSB3aXRoIHJlc2l6aW5nXG4gICAgICBsZXQgaW1hZ2VCbG9ja3M6IEltYWdlQmxvY2tQYXJhbVtdIHwgdW5kZWZpbmVkXG4gICAgICBpZiAoaGFzSW1hZ2VzKSB7XG4gICAgICAgIGltYWdlQmxvY2tzID0gYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICAgICAgaW1hZ2VBdHRhY2htZW50cy5tYXAoYXN5bmMgaW1nID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGJsb2NrOiBJbWFnZUJsb2NrUGFyYW0gPSB7XG4gICAgICAgICAgICAgIHR5cGU6ICdpbWFnZScsXG4gICAgICAgICAgICAgIHNvdXJjZToge1xuICAgICAgICAgICAgICAgIHR5cGU6ICdiYXNlNjQnLFxuICAgICAgICAgICAgICAgIG1lZGlhX3R5cGU6IChpbWcubWVkaWFUeXBlIHx8XG4gICAgICAgICAgICAgICAgICAnaW1hZ2UvcG5nJykgYXMgQmFzZTY0SW1hZ2VTb3VyY2VbJ21lZGlhX3R5cGUnXSxcbiAgICAgICAgICAgICAgICBkYXRhOiBpbWcuY29udGVudCxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IHJlc2l6ZWQgPSBhd2FpdCBtYXliZVJlc2l6ZUFuZERvd25zYW1wbGVJbWFnZUJsb2NrKGJsb2NrKVxuICAgICAgICAgICAgcmV0dXJuIHJlc2l6ZWQuYmxvY2tcbiAgICAgICAgICB9KSxcbiAgICAgICAgKVxuICAgICAgfVxuXG4gICAgICBvbkRvbmUoKVxuICAgICAgb25SZWplY3QoKVxuICAgICAgdG9vbFVzZUNvbmZpcm0ub25SZWplY3QoXG4gICAgICAgIHRyaW1tZWRGZWVkYmFjayB8fCAoaGFzSW1hZ2VzID8gJyhTZWUgYXR0YWNoZWQgaW1hZ2UpJyA6IHVuZGVmaW5lZCksXG4gICAgICAgIGltYWdlQmxvY2tzICYmIGltYWdlQmxvY2tzLmxlbmd0aCA+IDAgPyBpbWFnZUJsb2NrcyA6IHVuZGVmaW5lZCxcbiAgICAgIClcbiAgICB9XG4gIH1cblxuICBjb25zdCBlZGl0b3IgPSBnZXRFeHRlcm5hbEVkaXRvcigpXG4gIGNvbnN0IGVkaXRvck5hbWUgPSBlZGl0b3IgPyB0b0lERURpc3BsYXlOYW1lKGVkaXRvcikgOiBudWxsXG5cbiAgLy8gU3RpY2t5IGZvb3Rlcjogd2hlbiBzZXRTdGlja3lGb290ZXIgaXMgcHJvdmlkZWQgKGZ1bGxzY3JlZW4gbW9kZSksIHRoZVxuICAvLyBTZWxlY3Qgb3B0aW9ucyByZW5kZXIgaW4gRnVsbHNjcmVlbkxheW91dCdzIGBib3R0b21gIHNsb3Qgc28gdGhleSBzdGF5XG4gIC8vIHZpc2libGUgd2hpbGUgdGhlIHVzZXIgc2Nyb2xscyB0aHJvdWdoIGEgbG9uZyBwbGFuLiBoYW5kbGVSZXNwb25zZSBpc1xuICAvLyB3cmFwcGVkIGluIGEgcmVmIHNvIHRoZSBKU1ggKHNldCBvbmNlIHBlciBvcHRpb25zL2ltYWdlcyBjaGFuZ2UpIGNhbiBjYWxsXG4gIC8vIHRoZSBsYXRlc3QgY2xvc3VyZSB3aXRob3V0IHJlLXJlZ2lzdGVyaW5nIG9uIGV2ZXJ5IGtleXN0cm9rZS4gUmVhY3RcbiAgLy8gcmVjb25jaWxlcyB0aGUgc3RpY2t5LWZvb3RlciBTZWxlY3QgYnkgdHlwZSwgcHJlc2VydmluZyBmb2N1cy9pbnB1dCBzdGF0ZS5cbiAgY29uc3QgaGFuZGxlUmVzcG9uc2VSZWYgPSB1c2VSZWYoaGFuZGxlUmVzcG9uc2UpXG4gIGhhbmRsZVJlc3BvbnNlUmVmLmN1cnJlbnQgPSBoYW5kbGVSZXNwb25zZVxuICBjb25zdCBoYW5kbGVDYW5jZWxSZWYgPSB1c2VSZWY8KCkgPT4gdm9pZD4odW5kZWZpbmVkKVxuICBoYW5kbGVDYW5jZWxSZWYuY3VycmVudCA9ICgpID0+IHtcbiAgICBsb2dFdmVudCgndGVuZ3VfcGxhbl9leGl0Jywge1xuICAgICAgcGxhbkxlbmd0aENoYXJzOiBjdXJyZW50UGxhbi5sZW5ndGgsXG4gICAgICBvdXRjb21lOlxuICAgICAgICAnbm8nIGFzIEFuYWx5dGljc01ldGFkYXRhX0lfVkVSSUZJRURfVEhJU19JU19OT1RfQ09ERV9PUl9GSUxFUEFUSFMsXG4gICAgICBpbnRlcnZpZXdQaGFzZUVuYWJsZWQ6IGlzUGxhbk1vZGVJbnRlcnZpZXdQaGFzZUVuYWJsZWQoKSxcbiAgICAgIHBsYW5TdHJ1Y3R1cmVWYXJpYW50LFxuICAgIH0pXG4gICAgb25Eb25lKClcbiAgICBvblJlamVjdCgpXG4gICAgdG9vbFVzZUNvbmZpcm0ub25SZWplY3QoKVxuICB9XG4gIGNvbnN0IHVzZVN0aWNreUZvb3RlciA9ICFpc0VtcHR5ICYmICEhc2V0U3RpY2t5Rm9vdGVyXG4gIHVzZUxheW91dEVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKCF1c2VTdGlja3lGb290ZXIpIHJldHVyblxuICAgIHNldFN0aWNreUZvb3RlcihcbiAgICAgIDxCb3hcbiAgICAgICAgZmxleERpcmVjdGlvbj1cImNvbHVtblwiXG4gICAgICAgIGJvcmRlclN0eWxlPVwicm91bmRcIlxuICAgICAgICBib3JkZXJDb2xvcj1cInBsYW5Nb2RlXCJcbiAgICAgICAgYm9yZGVyTGVmdD17ZmFsc2V9XG4gICAgICAgIGJvcmRlclJpZ2h0PXtmYWxzZX1cbiAgICAgICAgYm9yZGVyQm90dG9tPXtmYWxzZX1cbiAgICAgICAgcGFkZGluZ1g9ezF9XG4gICAgICA+XG4gICAgICAgIDxUZXh0IGRpbUNvbG9yPldvdWxkIHlvdSBsaWtlIHRvIHByb2NlZWQ/PC9UZXh0PlxuICAgICAgICA8Qm94IG1hcmdpblRvcD17MX0+XG4gICAgICAgICAgPFNlbGVjdFxuICAgICAgICAgICAgb3B0aW9ucz17b3B0aW9uc31cbiAgICAgICAgICAgIG9uQ2hhbmdlPXt2ID0+IHZvaWQgaGFuZGxlUmVzcG9uc2VSZWYuY3VycmVudCh2KX1cbiAgICAgICAgICAgIG9uQ2FuY2VsPXsoKSA9PiBoYW5kbGVDYW5jZWxSZWYuY3VycmVudD8uKCl9XG4gICAgICAgICAgICBvbkltYWdlUGFzdGU9e29uSW1hZ2VQYXN0ZX1cbiAgICAgICAgICAgIHBhc3RlZENvbnRlbnRzPXtwYXN0ZWRDb250ZW50c31cbiAgICAgICAgICAgIG9uUmVtb3ZlSW1hZ2U9e29uUmVtb3ZlSW1hZ2V9XG4gICAgICAgICAgLz5cbiAgICAgICAgPC9Cb3g+XG4gICAgICAgIHtlZGl0b3JOYW1lICYmIChcbiAgICAgICAgICA8Qm94IGZsZXhEaXJlY3Rpb249XCJyb3dcIiBnYXA9ezF9IG1hcmdpblRvcD17MX0+XG4gICAgICAgICAgICA8VGV4dCBkaW1Db2xvcj5jdHJsLWcgdG8gZWRpdCBpbiA8L1RleHQ+XG4gICAgICAgICAgICA8VGV4dCBib2xkIGRpbUNvbG9yPlxuICAgICAgICAgICAgICB7ZWRpdG9yTmFtZX1cbiAgICAgICAgICAgIDwvVGV4dD5cbiAgICAgICAgICAgIHtpc1YyICYmIHBsYW5GaWxlUGF0aCAmJiAoXG4gICAgICAgICAgICAgIDxUZXh0IGRpbUNvbG9yPiDCtyB7Z2V0RGlzcGxheVBhdGgocGxhbkZpbGVQYXRoKX08L1RleHQ+XG4gICAgICAgICAgICApfVxuICAgICAgICAgICAge3Nob3dTYXZlTWVzc2FnZSAmJiAoXG4gICAgICAgICAgICAgIDw+XG4gICAgICAgICAgICAgICAgPFRleHQgZGltQ29sb3I+eycgwrcgJ308L1RleHQ+XG4gICAgICAgICAgICAgICAgPFRleHQgY29sb3I9XCJzdWNjZXNzXCI+e2ZpZ3VyZXMudGlja31QbGFuIHNhdmVkITwvVGV4dD5cbiAgICAgICAgICAgICAgPC8+XG4gICAgICAgICAgICApfVxuICAgICAgICAgIDwvQm94PlxuICAgICAgICApfVxuICAgICAgPC9Cb3g+LFxuICAgIClcbiAgICByZXR1cm4gKCkgPT4gc2V0U3RpY2t5Rm9vdGVyKG51bGwpXG4gICAgLy8gb25JbWFnZVBhc3RlL29uUmVtb3ZlSW1hZ2UgYXJlIHN0YWJsZSAodXNlQ2FsbGJhY2svdXNlUmVmLWJhY2tlZCBhYm92ZSlcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcmVhY3QtaG9va3MvZXhoYXVzdGl2ZS1kZXBzXG4gIH0sIFtcbiAgICB1c2VTdGlja3lGb290ZXIsXG4gICAgc2V0U3RpY2t5Rm9vdGVyLFxuICAgIG9wdGlvbnMsXG4gICAgcGFzdGVkQ29udGVudHMsXG4gICAgZWRpdG9yTmFtZSxcbiAgICBpc1YyLFxuICAgIHBsYW5GaWxlUGF0aCxcbiAgICBzaG93U2F2ZU1lc3NhZ2UsXG4gIF0pXG5cbiAgLy8gU2ltcGxpZmllZCBVSSBmb3IgZW1wdHkgcGxhbnNcbiAgaWYgKGlzRW1wdHkpIHtcbiAgICBmdW5jdGlvbiBoYW5kbGVFbXB0eVBsYW5SZXNwb25zZSh2YWx1ZTogJ3llcycgfCAnbm8nKTogdm9pZCB7XG4gICAgICBpZiAodmFsdWUgPT09ICd5ZXMnKSB7XG4gICAgICAgIGxvZ0V2ZW50KCd0ZW5ndV9wbGFuX2V4aXQnLCB7XG4gICAgICAgICAgcGxhbkxlbmd0aENoYXJzOiAwLFxuICAgICAgICAgIG91dGNvbWU6XG4gICAgICAgICAgICAneWVzLWRlZmF1bHQnIGFzIEFuYWx5dGljc01ldGFkYXRhX0lfVkVSSUZJRURfVEhJU19JU19OT1RfQ09ERV9PUl9GSUxFUEFUSFMsXG4gICAgICAgICAgaW50ZXJ2aWV3UGhhc2VFbmFibGVkOiBpc1BsYW5Nb2RlSW50ZXJ2aWV3UGhhc2VFbmFibGVkKCksXG4gICAgICAgICAgcGxhblN0cnVjdHVyZVZhcmlhbnQsXG4gICAgICAgIH0pXG4gICAgICAgIGlmIChmZWF0dXJlKCdUUkFOU0NSSVBUX0NMQVNTSUZJRVInKSkge1xuICAgICAgICAgIGNvbnN0IGF1dG9XYXNVc2VkRHVyaW5nUGxhbiA9XG4gICAgICAgICAgICBhdXRvTW9kZVN0YXRlTW9kdWxlPy5pc0F1dG9Nb2RlQWN0aXZlKCkgPz8gZmFsc2VcbiAgICAgICAgICBpZiAoYXV0b1dhc1VzZWREdXJpbmdQbGFuKSB7XG4gICAgICAgICAgICBhdXRvTW9kZVN0YXRlTW9kdWxlPy5zZXRBdXRvTW9kZUFjdGl2ZShmYWxzZSlcbiAgICAgICAgICAgIHNldE5lZWRzQXV0b01vZGVFeGl0QXR0YWNobWVudCh0cnVlKVxuICAgICAgICAgICAgc2V0QXBwU3RhdGUocHJldiA9PiAoe1xuICAgICAgICAgICAgICAuLi5wcmV2LFxuICAgICAgICAgICAgICB0b29sUGVybWlzc2lvbkNvbnRleHQ6IHtcbiAgICAgICAgICAgICAgICAuLi5yZXN0b3JlRGFuZ2Vyb3VzUGVybWlzc2lvbnMocHJldi50b29sUGVybWlzc2lvbkNvbnRleHQpLFxuICAgICAgICAgICAgICAgIHByZVBsYW5Nb2RlOiB1bmRlZmluZWQsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9KSlcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgc2V0SGFzRXhpdGVkUGxhbk1vZGUodHJ1ZSlcbiAgICAgICAgc2V0TmVlZHNQbGFuTW9kZUV4aXRBdHRhY2htZW50KHRydWUpXG4gICAgICAgIG9uRG9uZSgpXG4gICAgICAgIHRvb2xVc2VDb25maXJtLm9uQWxsb3coe30sIFtcbiAgICAgICAgICB7IHR5cGU6ICdzZXRNb2RlJywgbW9kZTogJ2RlZmF1bHQnLCBkZXN0aW5hdGlvbjogJ3Nlc3Npb24nIH0sXG4gICAgICAgIF0pXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsb2dFdmVudCgndGVuZ3VfcGxhbl9leGl0Jywge1xuICAgICAgICAgIHBsYW5MZW5ndGhDaGFyczogMCxcbiAgICAgICAgICBvdXRjb21lOlxuICAgICAgICAgICAgJ25vJyBhcyBBbmFseXRpY3NNZXRhZGF0YV9JX1ZFUklGSUVEX1RISVNfSVNfTk9UX0NPREVfT1JfRklMRVBBVEhTLFxuICAgICAgICAgIGludGVydmlld1BoYXNlRW5hYmxlZDogaXNQbGFuTW9kZUludGVydmlld1BoYXNlRW5hYmxlZCgpLFxuICAgICAgICAgIHBsYW5TdHJ1Y3R1cmVWYXJpYW50LFxuICAgICAgICB9KVxuICAgICAgICBvbkRvbmUoKVxuICAgICAgICBvblJlamVjdCgpXG4gICAgICAgIHRvb2xVc2VDb25maXJtLm9uUmVqZWN0KClcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gKFxuICAgICAgPFBlcm1pc3Npb25EaWFsb2dcbiAgICAgICAgY29sb3I9XCJwbGFuTW9kZVwiXG4gICAgICAgIHRpdGxlPVwiRXhpdCBwbGFuIG1vZGU/XCJcbiAgICAgICAgd29ya2VyQmFkZ2U9e3dvcmtlckJhZGdlfVxuICAgICAgPlxuICAgICAgICA8Qm94IGZsZXhEaXJlY3Rpb249XCJjb2x1bW5cIiBwYWRkaW5nWD17MX0gbWFyZ2luVG9wPXsxfT5cbiAgICAgICAgICA8VGV4dD5DbGF1ZGUgd2FudHMgdG8gZXhpdCBwbGFuIG1vZGU8L1RleHQ+XG4gICAgICAgICAgPEJveCBtYXJnaW5Ub3A9ezF9PlxuICAgICAgICAgICAgPFNlbGVjdFxuICAgICAgICAgICAgICBvcHRpb25zPXtbXG4gICAgICAgICAgICAgICAgeyBsYWJlbDogJ1llcycsIHZhbHVlOiAneWVzJyBhcyBjb25zdCB9LFxuICAgICAgICAgICAgICAgIHsgbGFiZWw6ICdObycsIHZhbHVlOiAnbm8nIGFzIGNvbnN0IH0sXG4gICAgICAgICAgICAgIF19XG4gICAgICAgICAgICAgIG9uQ2hhbmdlPXtoYW5kbGVFbXB0eVBsYW5SZXNwb25zZX1cbiAgICAgICAgICAgICAgb25DYW5jZWw9eygpID0+IHtcbiAgICAgICAgICAgICAgICBsb2dFdmVudCgndGVuZ3VfcGxhbl9leGl0Jywge1xuICAgICAgICAgICAgICAgICAgcGxhbkxlbmd0aENoYXJzOiAwLFxuICAgICAgICAgICAgICAgICAgb3V0Y29tZTpcbiAgICAgICAgICAgICAgICAgICAgJ25vJyBhcyBBbmFseXRpY3NNZXRhZGF0YV9JX1ZFUklGSUVEX1RISVNfSVNfTk9UX0NPREVfT1JfRklMRVBBVEhTLFxuICAgICAgICAgICAgICAgICAgaW50ZXJ2aWV3UGhhc2VFbmFibGVkOiBpc1BsYW5Nb2RlSW50ZXJ2aWV3UGhhc2VFbmFibGVkKCksXG4gICAgICAgICAgICAgICAgICBwbGFuU3RydWN0dXJlVmFyaWFudCxcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIG9uRG9uZSgpXG4gICAgICAgICAgICAgICAgb25SZWplY3QoKVxuICAgICAgICAgICAgICAgIHRvb2xVc2VDb25maXJtLm9uUmVqZWN0KClcbiAgICAgICAgICAgICAgfX1cbiAgICAgICAgICAgIC8+XG4gICAgICAgICAgPC9Cb3g+XG4gICAgICAgIDwvQm94PlxuICAgICAgPC9QZXJtaXNzaW9uRGlhbG9nPlxuICAgIClcbiAgfVxuXG4gIHJldHVybiAoXG4gICAgPEJveFxuICAgICAgZmxleERpcmVjdGlvbj1cImNvbHVtblwiXG4gICAgICB0YWJJbmRleD17MH1cbiAgICAgIGF1dG9Gb2N1c1xuICAgICAgb25LZXlEb3duPXtoYW5kbGVLZXlEb3dufVxuICAgID5cbiAgICAgIDxQZXJtaXNzaW9uRGlhbG9nXG4gICAgICAgIGNvbG9yPVwicGxhbk1vZGVcIlxuICAgICAgICB0aXRsZT1cIlJlYWR5IHRvIGNvZGU/XCJcbiAgICAgICAgaW5uZXJQYWRkaW5nWD17MH1cbiAgICAgICAgd29ya2VyQmFkZ2U9e3dvcmtlckJhZGdlfVxuICAgICAgPlxuICAgICAgICA8Qm94IGZsZXhEaXJlY3Rpb249XCJjb2x1bW5cIiBtYXJnaW5Ub3A9ezF9PlxuICAgICAgICAgIDxCb3ggcGFkZGluZ1g9ezF9IGZsZXhEaXJlY3Rpb249XCJjb2x1bW5cIj5cbiAgICAgICAgICAgIDxUZXh0PkhlcmUgaXMgQ2xhdWRlJmFwb3M7cyBwbGFuOjwvVGV4dD5cbiAgICAgICAgICA8L0JveD5cbiAgICAgICAgICA8Qm94XG4gICAgICAgICAgICBib3JkZXJDb2xvcj1cInN1YnRsZVwiXG4gICAgICAgICAgICBib3JkZXJTdHlsZT1cImRhc2hlZFwiXG4gICAgICAgICAgICBmbGV4RGlyZWN0aW9uPVwiY29sdW1uXCJcbiAgICAgICAgICAgIGJvcmRlckxlZnQ9e2ZhbHNlfVxuICAgICAgICAgICAgYm9yZGVyUmlnaHQ9e2ZhbHNlfVxuICAgICAgICAgICAgcGFkZGluZ1g9ezF9XG4gICAgICAgICAgICBtYXJnaW5Cb3R0b209ezF9XG4gICAgICAgICAgICAvLyBOZWNlc3NhcnkgZm9yIFdpbmRvd3MgVGVybWluYWwgdG8gcmVuZGVyIHByb3Blcmx5XG4gICAgICAgICAgICBvdmVyZmxvdz1cImhpZGRlblwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPE1hcmtkb3duPntjdXJyZW50UGxhbn08L01hcmtkb3duPlxuICAgICAgICAgIDwvQm94PlxuICAgICAgICAgIDxCb3ggZmxleERpcmVjdGlvbj1cImNvbHVtblwiIHBhZGRpbmdYPXsxfT5cbiAgICAgICAgICAgIDxQZXJtaXNzaW9uUnVsZUV4cGxhbmF0aW9uXG4gICAgICAgICAgICAgIHBlcm1pc3Npb25SZXN1bHQ9e3Rvb2xVc2VDb25maXJtLnBlcm1pc3Npb25SZXN1bHR9XG4gICAgICAgICAgICAgIHRvb2xUeXBlPVwidG9vbFwiXG4gICAgICAgICAgICAvPlxuICAgICAgICAgICAge2lzQ2xhc3NpZmllclBlcm1pc3Npb25zRW5hYmxlZCgpICYmXG4gICAgICAgICAgICAgIGFsbG93ZWRQcm9tcHRzICYmXG4gICAgICAgICAgICAgIGFsbG93ZWRQcm9tcHRzLmxlbmd0aCA+IDAgJiYgKFxuICAgICAgICAgICAgICAgIDxCb3ggZmxleERpcmVjdGlvbj1cImNvbHVtblwiIG1hcmdpbkJvdHRvbT17MX0+XG4gICAgICAgICAgICAgICAgICA8VGV4dCBib2xkPlJlcXVlc3RlZCBwZXJtaXNzaW9uczo8L1RleHQ+XG4gICAgICAgICAgICAgICAgICB7YWxsb3dlZFByb21wdHMubWFwKChwLCBpKSA9PiAoXG4gICAgICAgICAgICAgICAgICAgIDxUZXh0IGtleT17aX0gZGltQ29sb3I+XG4gICAgICAgICAgICAgICAgICAgICAgeycgICd9wrcge3AudG9vbH0oe1BST01QVF9QUkVGSVh9IHtwLnByb21wdH0pXG4gICAgICAgICAgICAgICAgICAgIDwvVGV4dD5cbiAgICAgICAgICAgICAgICAgICkpfVxuICAgICAgICAgICAgICAgIDwvQm94PlxuICAgICAgICAgICAgICApfVxuICAgICAgICAgICAgeyF1c2VTdGlja3lGb290ZXIgJiYgKFxuICAgICAgICAgICAgICA8PlxuICAgICAgICAgICAgICAgIDxUZXh0IGRpbUNvbG9yPlxuICAgICAgICAgICAgICAgICAgQ2xhdWRlIGhhcyB3cml0dGVuIHVwIGEgcGxhbiBhbmQgaXMgcmVhZHkgdG8gZXhlY3V0ZS4gV291bGRcbiAgICAgICAgICAgICAgICAgIHlvdSBsaWtlIHRvIHByb2NlZWQ/XG4gICAgICAgICAgICAgICAgPC9UZXh0PlxuICAgICAgICAgICAgICAgIDxCb3ggbWFyZ2luVG9wPXsxfT5cbiAgICAgICAgICAgICAgICAgIDxTZWxlY3RcbiAgICAgICAgICAgICAgICAgICAgb3B0aW9ucz17b3B0aW9uc31cbiAgICAgICAgICAgICAgICAgICAgb25DaGFuZ2U9e2hhbmRsZVJlc3BvbnNlfVxuICAgICAgICAgICAgICAgICAgICBvbkNhbmNlbD17KCkgPT4gaGFuZGxlQ2FuY2VsUmVmLmN1cnJlbnQ/LigpfVxuICAgICAgICAgICAgICAgICAgICBvbkltYWdlUGFzdGU9e29uSW1hZ2VQYXN0ZX1cbiAgICAgICAgICAgICAgICAgICAgcGFzdGVkQ29udGVudHM9e3Bhc3RlZENvbnRlbnRzfVxuICAgICAgICAgICAgICAgICAgICBvblJlbW92ZUltYWdlPXtvblJlbW92ZUltYWdlfVxuICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICA8L0JveD5cbiAgICAgICAgICAgICAgPC8+XG4gICAgICAgICAgICApfVxuICAgICAgICAgIDwvQm94PlxuICAgICAgICA8L0JveD5cbiAgICAgIDwvUGVybWlzc2lvbkRpYWxvZz5cbiAgICAgIHshdXNlU3RpY2t5Rm9vdGVyICYmIGVkaXRvck5hbWUgJiYgKFxuICAgICAgICA8Qm94IGZsZXhEaXJlY3Rpb249XCJyb3dcIiBnYXA9ezF9IHBhZGRpbmdYPXsxfSBtYXJnaW5Ub3A9ezF9PlxuICAgICAgICAgIDxCb3g+XG4gICAgICAgICAgICA8VGV4dCBkaW1Db2xvcj5jdHJsLWcgdG8gZWRpdCBpbiA8L1RleHQ+XG4gICAgICAgICAgICA8VGV4dCBib2xkIGRpbUNvbG9yPlxuICAgICAgICAgICAgICB7ZWRpdG9yTmFtZX1cbiAgICAgICAgICAgIDwvVGV4dD5cbiAgICAgICAgICAgIHtpc1YyICYmIHBsYW5GaWxlUGF0aCAmJiAoXG4gICAgICAgICAgICAgIDxUZXh0IGRpbUNvbG9yPiDCtyB7Z2V0RGlzcGxheVBhdGgocGxhbkZpbGVQYXRoKX08L1RleHQ+XG4gICAgICAgICAgICApfVxuICAgICAgICAgIDwvQm94PlxuICAgICAgICAgIHtzaG93U2F2ZU1lc3NhZ2UgJiYgKFxuICAgICAgICAgICAgPEJveD5cbiAgICAgICAgICAgICAgPFRleHQgZGltQ29sb3I+eycgwrcgJ308L1RleHQ+XG4gICAgICAgICAgICAgIDxUZXh0IGNvbG9yPVwic3VjY2Vzc1wiPntmaWd1cmVzLnRpY2t9UGxhbiBzYXZlZCE8L1RleHQ+XG4gICAgICAgICAgICA8L0JveD5cbiAgICAgICAgICApfVxuICAgICAgICA8L0JveD5cbiAgICAgICl9XG4gICAgPC9Cb3g+XG4gIClcbn1cblxuLyoqIEBpbnRlcm5hbCBFeHBvcnRlZCBmb3IgdGVzdGluZy4gKi9cbmV4cG9ydCBmdW5jdGlvbiBidWlsZFBsYW5BcHByb3ZhbE9wdGlvbnMoe1xuICBzaG93Q2xlYXJDb250ZXh0LFxuICBzaG93VWx0cmFwbGFuLFxuICB1c2VkUGVyY2VudCxcbiAgaXNBdXRvTW9kZUF2YWlsYWJsZSxcbiAgaXNCeXBhc3NQZXJtaXNzaW9uc01vZGVBdmFpbGFibGUsXG4gIG9uRmVlZGJhY2tDaGFuZ2UsXG59OiB7XG4gIHNob3dDbGVhckNvbnRleHQ6IGJvb2xlYW5cbiAgc2hvd1VsdHJhcGxhbjogYm9vbGVhblxuICB1c2VkUGVyY2VudDogbnVtYmVyIHwgbnVsbFxuICBpc0F1dG9Nb2RlQXZhaWxhYmxlOiBib29sZWFuIHwgdW5kZWZpbmVkXG4gIGlzQnlwYXNzUGVybWlzc2lvbnNNb2RlQXZhaWxhYmxlOiBib29sZWFuIHwgdW5kZWZpbmVkXG4gIG9uRmVlZGJhY2tDaGFuZ2U6ICh2OiBzdHJpbmcpID0+IHZvaWRcbn0pOiBPcHRpb25XaXRoRGVzY3JpcHRpb248UmVzcG9uc2VWYWx1ZT5bXSB7XG4gIGNvbnN0IG9wdGlvbnM6IE9wdGlvbldpdGhEZXNjcmlwdGlvbjxSZXNwb25zZVZhbHVlPltdID0gW11cbiAgY29uc3QgdXNlZExhYmVsID0gdXNlZFBlcmNlbnQgIT09IG51bGwgPyBgICgke3VzZWRQZXJjZW50fSUgdXNlZClgIDogJydcblxuICBpZiAoc2hvd0NsZWFyQ29udGV4dCkge1xuICAgIGlmIChmZWF0dXJlKCdUUkFOU0NSSVBUX0NMQVNTSUZJRVInKSAmJiBpc0F1dG9Nb2RlQXZhaWxhYmxlKSB7XG4gICAgICBvcHRpb25zLnB1c2goe1xuICAgICAgICBsYWJlbDogYFllcywgY2xlYXIgY29udGV4dCR7dXNlZExhYmVsfSBhbmQgdXNlIGF1dG8gbW9kZWAsXG4gICAgICAgIHZhbHVlOiAneWVzLWF1dG8tY2xlYXItY29udGV4dCcsXG4gICAgICB9KVxuICAgIH0gZWxzZSBpZiAoaXNCeXBhc3NQZXJtaXNzaW9uc01vZGVBdmFpbGFibGUpIHtcbiAgICAgIG9wdGlvbnMucHVzaCh7XG4gICAgICAgIGxhYmVsOiBgWWVzLCBjbGVhciBjb250ZXh0JHt1c2VkTGFiZWx9IGFuZCBieXBhc3MgcGVybWlzc2lvbnNgLFxuICAgICAgICB2YWx1ZTogJ3llcy1ieXBhc3MtcGVybWlzc2lvbnMnLFxuICAgICAgfSlcbiAgICB9IGVsc2Uge1xuICAgICAgb3B0aW9ucy5wdXNoKHtcbiAgICAgICAgbGFiZWw6IGBZZXMsIGNsZWFyIGNvbnRleHQke3VzZWRMYWJlbH0gYW5kIGF1dG8tYWNjZXB0IGVkaXRzYCxcbiAgICAgICAgdmFsdWU6ICd5ZXMtYWNjZXB0LWVkaXRzJyxcbiAgICAgIH0pXG4gICAgfVxuICB9XG5cbiAgLy8gU2xvdCAyOiBrZWVwLWNvbnRleHQgd2l0aCBlbGV2YXRlZCBtb2RlIChzYW1lIHByaW9yaXR5OiBhdXRvID4gYnlwYXNzID4gZWRpdHMpLlxuICBpZiAoZmVhdHVyZSgnVFJBTlNDUklQVF9DTEFTU0lGSUVSJykgJiYgaXNBdXRvTW9kZUF2YWlsYWJsZSkge1xuICAgIG9wdGlvbnMucHVzaCh7XG4gICAgICBsYWJlbDogJ1llcywgYW5kIHVzZSBhdXRvIG1vZGUnLFxuICAgICAgdmFsdWU6ICd5ZXMtcmVzdW1lLWF1dG8tbW9kZScsXG4gICAgfSlcbiAgfSBlbHNlIGlmIChpc0J5cGFzc1Blcm1pc3Npb25zTW9kZUF2YWlsYWJsZSkge1xuICAgIG9wdGlvbnMucHVzaCh7XG4gICAgICBsYWJlbDogJ1llcywgYW5kIGJ5cGFzcyBwZXJtaXNzaW9ucycsXG4gICAgICB2YWx1ZTogJ3llcy1hY2NlcHQtZWRpdHMta2VlcC1jb250ZXh0JyxcbiAgICB9KVxuICB9IGVsc2Uge1xuICAgIG9wdGlvbnMucHVzaCh7XG4gICAgICBsYWJlbDogJ1llcywgYXV0by1hY2NlcHQgZWRpdHMnLFxuICAgICAgdmFsdWU6ICd5ZXMtYWNjZXB0LWVkaXRzLWtlZXAtY29udGV4dCcsXG4gICAgfSlcbiAgfVxuXG4gIG9wdGlvbnMucHVzaCh7XG4gICAgbGFiZWw6ICdZZXMsIG1hbnVhbGx5IGFwcHJvdmUgZWRpdHMnLFxuICAgIHZhbHVlOiAneWVzLWRlZmF1bHQta2VlcC1jb250ZXh0JyxcbiAgfSlcblxuICBpZiAoc2hvd1VsdHJhcGxhbikge1xuICAgIG9wdGlvbnMucHVzaCh7XG4gICAgICBsYWJlbDogJ05vLCByZWZpbmUgd2l0aCBVbHRyYXBsYW4gb24gQ2xhdWRlIENvZGUgb24gdGhlIHdlYicsXG4gICAgICB2YWx1ZTogJ3VsdHJhcGxhbicsXG4gICAgfSlcbiAgfVxuXG4gIG9wdGlvbnMucHVzaCh7XG4gICAgdHlwZTogJ2lucHV0JyxcbiAgICBsYWJlbDogJ05vLCBrZWVwIHBsYW5uaW5nJyxcbiAgICB2YWx1ZTogJ25vJyxcbiAgICBwbGFjZWhvbGRlcjogJ1RlbGwgQ2xhdWRlIHdoYXQgdG8gY2hhbmdlJyxcbiAgICBkZXNjcmlwdGlvbjogJ3NoaWZ0K3RhYiB0byBhcHByb3ZlIHdpdGggdGhpcyBmZWVkYmFjaycsXG4gICAgb25DaGFuZ2U6IG9uRmVlZGJhY2tDaGFuZ2UsXG4gIH0pXG5cbiAgcmV0dXJuIG9wdGlvbnNcbn1cblxuZnVuY3Rpb24gZ2V0Q29udGV4dFVzZWRQZXJjZW50KFxuICB1c2FnZTpcbiAgICB8IHtcbiAgICAgICAgaW5wdXRfdG9rZW5zOiBudW1iZXJcbiAgICAgICAgY2FjaGVfY3JlYXRpb25faW5wdXRfdG9rZW5zPzogbnVtYmVyIHwgbnVsbFxuICAgICAgICBjYWNoZV9yZWFkX2lucHV0X3Rva2Vucz86IG51bWJlciB8IG51bGxcbiAgICAgIH1cbiAgICB8IHVuZGVmaW5lZCxcbiAgcGVybWlzc2lvbk1vZGU6IFBlcm1pc3Npb25Nb2RlLFxuKTogbnVtYmVyIHwgbnVsbCB7XG4gIGlmICghdXNhZ2UpIHJldHVybiBudWxsXG4gIGNvbnN0IHJ1bnRpbWVNb2RlbCA9IGdldFJ1bnRpbWVNYWluTG9vcE1vZGVsKHtcbiAgICBwZXJtaXNzaW9uTW9kZSxcbiAgICBtYWluTG9vcE1vZGVsOiBnZXRNYWluTG9vcE1vZGVsKCksXG4gICAgZXhjZWVkczIwMGtUb2tlbnM6IGZhbHNlLFxuICB9KVxuICBjb25zdCBjb250ZXh0V2luZG93U2l6ZSA9IGdldENvbnRleHRXaW5kb3dGb3JNb2RlbChcbiAgICBydW50aW1lTW9kZWwsXG4gICAgZ2V0U2RrQmV0YXMoKSxcbiAgKVxuICBjb25zdCB7IHVzZWQgfSA9IGNhbGN1bGF0ZUNvbnRleHRQZXJjZW50YWdlcyhcbiAgICB7XG4gICAgICBpbnB1dF90b2tlbnM6IHVzYWdlLmlucHV0X3Rva2VucyxcbiAgICAgIGNhY2hlX2NyZWF0aW9uX2lucHV0X3Rva2VuczogdXNhZ2UuY2FjaGVfY3JlYXRpb25faW5wdXRfdG9rZW5zID8/IDAsXG4gICAgICBjYWNoZV9yZWFkX2lucHV0X3Rva2VuczogdXNhZ2UuY2FjaGVfcmVhZF9pbnB1dF90b2tlbnMgPz8gMCxcbiAgICB9LFxuICAgIGNvbnRleHRXaW5kb3dTaXplLFxuICApXG4gIHJldHVybiB1c2VkXG59XG4iXSwibWFwcGluZ3MiOiJBQUFBLFNBQVNBLE9BQU8sUUFBUSxZQUFZO0FBQ3BDLGNBQWNDLElBQUksUUFBUSxRQUFRO0FBQ2xDLE9BQU9DLE9BQU8sTUFBTSxTQUFTO0FBQzdCLE9BQU9DLEtBQUssSUFDVkMsV0FBVyxFQUNYQyxTQUFTLEVBQ1RDLGVBQWUsRUFDZkMsT0FBTyxFQUNQQyxNQUFNLEVBQ05DLFFBQVEsUUFDSCxPQUFPO0FBQ2QsU0FBU0MsZ0JBQWdCLFFBQVEsOEJBQThCO0FBQy9ELFNBQ0UsS0FBS0MsMERBQTBELEVBQy9EQyxRQUFRLFFBQ0gsaUNBQWlDO0FBQ3hDLFNBQ0VDLFdBQVcsRUFDWEMsZ0JBQWdCLEVBQ2hCQyxjQUFjLFFBQ1QsdUJBQXVCO0FBQzlCLFNBQ0VDLFdBQVcsRUFDWEMsWUFBWSxFQUNaQyw0QkFBNEIsRUFDNUJDLG9CQUFvQixFQUNwQkMsOEJBQThCLEVBQzlCQyw4QkFBOEIsUUFDekIsNkJBQTZCO0FBQ3BDLFNBQVNDLG1CQUFtQixRQUFRLGlEQUFpRDtBQUNyRixTQUFTQyxlQUFlLFFBQVEsZ0NBQWdDO0FBQ2hFLGNBQWNDLGFBQWEsUUFBUSx1Q0FBdUM7QUFDMUUsU0FBU0MsR0FBRyxFQUFFQyxJQUFJLFFBQVEsaUJBQWlCO0FBQzNDLGNBQWNDLFFBQVEsUUFBUSxpQ0FBaUM7QUFDL0QsU0FBU0MsZUFBZSxRQUFRLHVDQUF1QztBQUN2RSxTQUFTQywyQkFBMkIsUUFBUSw4Q0FBOEM7QUFDMUYsY0FBY0MsYUFBYSxRQUFRLHVEQUF1RDtBQUMxRixTQUFTQyxxQkFBcUIsUUFBUSw0Q0FBNEM7QUFDbEYsU0FBU0Msb0JBQW9CLFFBQVEsc0NBQXNDO0FBQzNFLFNBQ0VDLDJCQUEyQixFQUMzQkMsd0JBQXdCLFFBQ25CLDJCQUEyQjtBQUNsQyxTQUFTQyxpQkFBaUIsUUFBUSwwQkFBMEI7QUFDNUQsU0FBU0MsY0FBYyxRQUFRLHdCQUF3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 diff --git a/src/server/__tests__/conversations.test.ts b/src/server/__tests__/conversations.test.ts index 3d55857a..84ae1429 100644 --- a/src/server/__tests__/conversations.test.ts +++ b/src/server/__tests__/conversations.test.ts @@ -529,6 +529,83 @@ describe('ConversationService', () => { await fs.rm(workDir, { recursive: true, force: true }) } }) + + it('should not report transcript context as full for low-trust media usage spikes', async () => { + const previousConfigDir = process.env.CLAUDE_CONFIG_DIR + const previousNodeEnv = process.env.NODE_ENV + const previousUseBedrock = process.env.CLAUDE_CODE_USE_BEDROCK + const tmpConfigDir = await fs.mkdtemp(path.join(os.tmpdir(), 'claude-transcript-media-')) + const workDir = await fs.mkdtemp(path.join(os.tmpdir(), 'claude-workdir-media-')) + process.env.CLAUDE_CONFIG_DIR = tmpConfigDir + process.env.NODE_ENV = 'development' + process.env.CLAUDE_CODE_USE_BEDROCK = '1' + + try { + const svc = new SessionService() + const { sessionId } = await svc.createSession(workDir) + const found = await svc.findSessionFile(sessionId) + expect(found).not.toBeNull() + + await fs.appendFile(found!.filePath, JSON.stringify({ + type: 'user', + uuid: crypto.randomUUID(), + timestamp: '2026-04-27T12:00:00.000Z', + cwd: workDir, + message: { + role: 'user', + content: [{ + type: 'image', + source: { + type: 'base64', + media_type: 'image/png', + data: 'a'.repeat(1024), + }, + }], + }, + }) + '\n') + await fs.appendFile(found!.filePath, JSON.stringify({ + type: 'assistant', + uuid: crypto.randomUUID(), + timestamp: '2026-04-27T12:00:01.000Z', + cwd: workDir, + version: '999.0.0-test', + message: { + role: 'assistant', + model: 'claude-sonnet-4-6', + content: [{ type: 'text', text: 'ok' }], + usage: { + input_tokens: 1_000_000, + output_tokens: 10, + }, + }, + }) + '\n') + + const contextEstimate = await svc.getTranscriptContextEstimate(sessionId) + + expect(contextEstimate?.rawMaxTokens).toBe(200_000) + expect(contextEstimate?.totalTokens).toBeLessThan(200_000) + expect(contextEstimate?.percentage).toBeLessThan(100) + expect(contextEstimate?.categories[0]?.name).toBe('Estimated context') + } finally { + if (previousConfigDir === undefined) { + delete process.env.CLAUDE_CONFIG_DIR + } else { + process.env.CLAUDE_CONFIG_DIR = previousConfigDir + } + if (previousNodeEnv === undefined) { + delete process.env.NODE_ENV + } else { + process.env.NODE_ENV = previousNodeEnv + } + if (previousUseBedrock === undefined) { + delete process.env.CLAUDE_CODE_USE_BEDROCK + } else { + process.env.CLAUDE_CODE_USE_BEDROCK = previousUseBedrock + } + await fs.rm(tmpConfigDir, { recursive: true, force: true }) + await fs.rm(workDir, { recursive: true, force: true }) + } + }) }) // ============================================================================ diff --git a/src/server/__tests__/provider-presets.test.ts b/src/server/__tests__/provider-presets.test.ts index 89c083b4..c916c8a2 100644 --- a/src/server/__tests__/provider-presets.test.ts +++ b/src/server/__tests__/provider-presets.test.ts @@ -195,4 +195,13 @@ describe('provider presets API', () => { const updatedRaw = await fs.readFile(path.join(tmpDir, 'cc-haha', 'settings.json'), 'utf-8') expect(JSON.parse(updatedRaw)).toEqual(updateBody) }) + + test('provider presets carry docs-backed context windows for current coding models', () => { + const byId = new Map(PROVIDER_PRESETS.map((preset) => [preset.id, preset])) + + for (const id of ['deepseek', 'zhipuglm', 'kimi', 'minimax']) { + const preset = byId.get(id)! + expect(preset.modelContextWindows?.[preset.defaultModels.main]).toBeGreaterThan(0) + } + }) }) diff --git a/src/server/services/sessionService.ts b/src/server/services/sessionService.ts index eb611d9e..86ebb9dc 100644 --- a/src/server/services/sessionService.ts +++ b/src/server/services/sessionService.ts @@ -16,12 +16,17 @@ import type { FileHistorySnapshot } from '../../utils/fileHistory.js' import { findCanonicalGitRoot } from '../../utils/git.js' import { calculateUSDCost, MODEL_COSTS } from '../../utils/modelCost.js' import { - calculateCurrentContextTokenTotal, MODEL_CONTEXT_WINDOW_DEFAULT, getContextWindowForModel, getModelMaxOutputTokens, } from '../../utils/context.js' +import { + calculateContextBudget, + getProviderUsageTrust, + hasMediaInput, +} from '../../utils/contextBudget.js' import { getCanonicalName } from '../../utils/model/model.js' +import { isFirstPartyAnthropicBaseUrl } from '../../utils/model/providers.js' import { resolveSessionWorkspaceLaunch, type CreateSessionRepositoryOptions, @@ -30,6 +35,7 @@ import { import { registerFilesystemAccessRoot } from './filesystemAccessRoots.js' import { normalizeDriveRootPathForPlatform } from './windowsDrivePath.js' import { cleanSessionTitleSource } from '../../utils/sessionTitleText.js' +import { roughTokenCountEstimationForMessages } from '../../services/tokenEstimation.js' // ============================================================================ // Types @@ -1358,18 +1364,39 @@ export class SessionService { const rawMaxTokens = this.getTranscriptContextWindow(latest.model) const promptTokens = latest.inputTokens + latest.cacheReadInputTokens + latest.cacheCreationInputTokens - const totalTokens = calculateCurrentContextTokenTotal(promptTokens, { - input_tokens: latest.inputTokens, - output_tokens: latest.outputTokens, - cache_read_input_tokens: latest.cacheReadInputTokens, - cache_creation_input_tokens: latest.cacheCreationInputTokens, - }, rawMaxTokens) + const transcriptMessages = entries.filter(entry => + entry.type === 'user' || entry.type === 'assistant' || entry.type === 'attachment', + ) as Parameters[0] + const estimatedTokens = + roughTokenCountEstimationForMessages(transcriptMessages) || promptTokens + const contextBudget = calculateContextBudget({ + estimatedTokens, + contextWindow: rawMaxTokens, + currentUsage: { + input_tokens: latest.inputTokens, + output_tokens: latest.outputTokens, + cache_read_input_tokens: latest.cacheReadInputTokens, + cache_creation_input_tokens: latest.cacheCreationInputTokens, + }, + usageTrust: getProviderUsageTrust({ + isFirstPartyAnthropic: isFirstPartyAnthropicBaseUrl(), + }), + hasMediaInput: hasMediaInput(transcriptMessages), + }) + const totalTokens = contextBudget.usedTokens const percentage = rawMaxTokens > 0 ? Math.round((totalTokens / rawMaxTokens) * 100) : 0 - const categories: TranscriptContextEstimate['categories'] = [ + const usageCategories: TranscriptContextEstimate['categories'] = [ { name: 'Input tokens', tokens: latest.inputTokens, color: '#8f3217' }, { name: 'Cache read', tokens: latest.cacheReadInputTokens, color: '#0f5c8f' }, { name: 'Cache write', tokens: latest.cacheCreationInputTokens, color: '#7c3aed' }, { name: 'Output tokens', tokens: latest.outputTokens, color: '#2f7d32' }, + ] + const contextCategories: TranscriptContextEstimate['categories'] = + contextBudget.ignoredUsageReason === 'low_trust_media_usage' + ? [{ name: 'Estimated context', tokens: totalTokens, color: '#8f3217' }] + : usageCategories + const categories: TranscriptContextEstimate['categories'] = [ + ...contextCategories, { name: 'Free space', tokens: Math.max(0, rawMaxTokens - totalTokens), color: '#a1a1aa', isDeferred: true }, ].filter((category) => category.tokens > 0) diff --git a/src/services/api/errors.test.ts b/src/services/api/errors.test.ts new file mode 100644 index 00000000..9c8c9e3f --- /dev/null +++ b/src/services/api/errors.test.ts @@ -0,0 +1,36 @@ +import { describe, expect, test } from 'bun:test' +import { + getAssistantMessageFromError, + getImageUnsupportedErrorMessage, + isUnsupportedImageInputErrorMessage, +} from './errors.js' + +describe('image unsupported API errors', () => { + test('detects provider-specific text-only model image rejections', () => { + expect( + isUnsupportedImageInputErrorMessage( + 'This model does not support image blocks', + ), + ).toBe(true) + expect( + isUnsupportedImageInputErrorMessage( + 'unsupported modality: image input is not available', + ), + ).toBe(true) + expect(isUnsupportedImageInputErrorMessage('image exceeds maximum')).toBe(false) + }) + + test('maps unsupported image rejections to a recoverable synthetic error', () => { + const msg = getAssistantMessageFromError( + new Error('This model does not support image blocks'), + 'mimo-v2.5-pro', + ) + + expect(msg.isApiErrorMessage).toBe(true) + expect(msg.errorDetails).toBe('This model does not support image blocks') + expect(msg.message.content[0]).toMatchObject({ + type: 'text', + text: getImageUnsupportedErrorMessage(), + }) + }) +}) diff --git a/src/services/api/errors.ts b/src/services/api/errors.ts index c9237ca0..c5df6dd1 100644 --- a/src/services/api/errors.ts +++ b/src/services/api/errors.ts @@ -188,6 +188,11 @@ export function getImageTooLargeErrorMessage(): string { ? 'Image was too large. Try resizing the image or using a different approach.' : 'Image was too large. Double press esc to go back and try again with a smaller image.' } +export function getImageUnsupportedErrorMessage(): string { + return getIsNonInteractiveSession() + ? 'This model does not support images. Continue with text, or switch to a vision-capable model and send the image again.' + : 'This model does not support images. Double press esc to go back, switch to a vision-capable model, or continue with text.' +} export function getRequestTooLargeErrorMessage(): string { const limits = `max ${formatFileSize(PDF_TARGET_RAW_SIZE)}` return getIsNonInteractiveSession() @@ -422,6 +427,20 @@ export function extractUnknownErrorFormat(value: unknown): string | undefined { return undefined } +export function isUnsupportedImageInputErrorMessage(message: string): boolean { + const raw = message.toLowerCase() + if (!raw.includes('image')) return false + return ( + raw.includes('not support') || + raw.includes('not supported') || + raw.includes('unsupported') || + raw.includes('vision') || + raw.includes('multimodal') || + raw.includes('multi-modal') || + raw.includes('modality') + ) +} + export function getAssistantMessageFromError( error: unknown, model: string, @@ -451,6 +470,22 @@ export function getAssistantMessageFromError( }) } + // Custom/Anthropic-compatible providers often reject image blocks with + // provider-specific wording when the selected model is text-only. Convert it + // to a known synthetic error so normalizeMessagesForAPI can strip the image + // from later turns instead of poisoning the whole session. + if ( + error instanceof Error && + isUnsupportedImageInputErrorMessage(error.message) && + (!(error instanceof APIError) || error.status === 400 || error.status === 422) + ) { + return createAssistantAPIErrorMessage({ + content: getImageUnsupportedErrorMessage(), + error: 'invalid_request', + errorDetails: error.message, + }) + } + // Check for emergency capacity off switch for Opus PAYG users if ( error instanceof Error && diff --git a/src/services/compact/autoCompact.test.ts b/src/services/compact/autoCompact.test.ts index 913f4ade..98e49ae5 100644 --- a/src/services/compact/autoCompact.test.ts +++ b/src/services/compact/autoCompact.test.ts @@ -1,6 +1,6 @@ import { describe, expect, test, beforeEach, afterEach } from 'bun:test' -import { getEffectiveContextWindowSize } from './autoCompact.js' +import { getAutoCompactThreshold, getEffectiveContextWindowSize } from './autoCompact.js' import { getContextWindowForModel } from '../../utils/context.js' import { MODEL_CONTEXT_WINDOWS_ENV_KEY } from '../../utils/model/modelContextWindows.js' @@ -58,4 +58,12 @@ describe('model context window resolution', () => { expect(getEffectiveContextWindowSize('unknown-future-model')).toBe(980_000) }) + + test('derives auto-compact thresholds from provider context windows', () => { + expect(getAutoCompactThreshold('deepseek-v4-pro')).toBe(967_000) + expect(getAutoCompactThreshold('glm-5.1')).toBe(167_000) + expect(getAutoCompactThreshold('glm-4.5-air')).toBe(95_000) + expect(getAutoCompactThreshold('kimi-k2.6')).toBe(229_144) + expect(getAutoCompactThreshold('MiniMax-M2.7')).toBe(171_800) + }) }) diff --git a/src/services/tokenEstimation.ts b/src/services/tokenEstimation.ts index acaef7a5..f4b6a20c 100644 --- a/src/services/tokenEstimation.ts +++ b/src/services/tokenEstimation.ts @@ -241,6 +241,24 @@ export function roughTokenCountEstimationForFileType( ) } +export function roughTokenCountEstimationForAPIRequest( + messages: readonly { + role?: string + content?: string | Array | Array + }[], + tools: readonly unknown[] = [], +): number { + let totalTokens = 0 + for (const message of messages) { + totalTokens += roughTokenCountEstimation(message.role ?? '') + totalTokens += roughTokenCountEstimationForContent(message.content) + } + if (tools.length > 0) { + totalTokens += roughTokenCountEstimation(jsonStringify({ tools })) + } + return totalTokens +} + /** * Estimates token count for a Message object by extracting and analyzing its text content. * This provides a more reliable estimate than getTokenUsage for messages that may have been compacted. @@ -368,7 +386,7 @@ export function roughTokenCountEstimationForMessage(message: { return 0 } -function roughTokenCountEstimationForContent( +export function roughTokenCountEstimationForContent( content: | string | Array diff --git a/src/utils/__tests__/context.test.ts b/src/utils/__tests__/context.test.ts index 2851de55..6dd3c04b 100644 --- a/src/utils/__tests__/context.test.ts +++ b/src/utils/__tests__/context.test.ts @@ -53,4 +53,22 @@ describe('calculateCurrentContextTokenTotal', () => { expect(calculateCurrentContextTokenTotal(50_000, null)).toBe(50_000) expect(calculateCurrentContextTokenTotal(50_000, null, 200_000)).toBe(50_000) }) + + test('ignores suspicious media usage that appears to count encoded bytes', () => { + expect(calculateCurrentContextTokenTotal(30_000, { + input_tokens: 220_000, + cache_creation_input_tokens: 0, + cache_read_input_tokens: 0, + output_tokens: 1_000, + }, 200_000, { hasMediaInput: true, usageTrust: 'low' })).toBe(30_000) + }) + + test('keeps high provider usage for media when it is close to local estimate', () => { + expect(calculateCurrentContextTokenTotal(180_000, { + input_tokens: 195_000, + cache_creation_input_tokens: 0, + cache_read_input_tokens: 0, + output_tokens: 5_000, + }, 200_000, { hasMediaInput: true, usageTrust: 'high' })).toBe(200_000) + }) }) diff --git a/src/utils/__tests__/contextBudget.test.ts b/src/utils/__tests__/contextBudget.test.ts new file mode 100644 index 00000000..bba57d90 --- /dev/null +++ b/src/utils/__tests__/contextBudget.test.ts @@ -0,0 +1,369 @@ +import { describe, expect, test } from 'bun:test' +import { + calculateContextBudget, + calculateContextPercentagesFromTokens, + getProviderUsageTrust, + getUsageTokenTotal, + hasMediaInput, + shouldIgnoreLowTrustUsage, +} from '../contextBudget.js' + +function restoreEnvVar(name: string, value: string | undefined): void { + if (value === undefined) { + delete process.env[name] + return + } + + process.env[name] = value +} + +describe('getProviderUsageTrust', () => { + test('returns high for first-party Anthropic direct usage', () => { + const originalUseBedrock = process.env.CLAUDE_CODE_USE_BEDROCK + const originalUseVertex = process.env.CLAUDE_CODE_USE_VERTEX + const originalUseFoundry = process.env.CLAUDE_CODE_USE_FOUNDRY + const originalUseAzureOpenAI = process.env.CLAUDE_CODE_USE_AZURE_OPENAI + + try { + delete process.env.CLAUDE_CODE_USE_BEDROCK + delete process.env.CLAUDE_CODE_USE_VERTEX + delete process.env.CLAUDE_CODE_USE_FOUNDRY + delete process.env.CLAUDE_CODE_USE_AZURE_OPENAI + + expect(getProviderUsageTrust({ isFirstPartyAnthropic: true })).toBe( + 'high', + ) + } finally { + restoreEnvVar('CLAUDE_CODE_USE_BEDROCK', originalUseBedrock) + restoreEnvVar('CLAUDE_CODE_USE_VERTEX', originalUseVertex) + restoreEnvVar('CLAUDE_CODE_USE_FOUNDRY', originalUseFoundry) + restoreEnvVar( + 'CLAUDE_CODE_USE_AZURE_OPENAI', + originalUseAzureOpenAI, + ) + } + }) + + test('returns low for non-first-party providers even if the Anthropic base URL looks first-party', () => { + const originalUseBedrock = process.env.CLAUDE_CODE_USE_BEDROCK + + try { + process.env.CLAUDE_CODE_USE_BEDROCK = '1' + + expect(getProviderUsageTrust({ isFirstPartyAnthropic: true })).toBe('low') + } finally { + restoreEnvVar('CLAUDE_CODE_USE_BEDROCK', originalUseBedrock) + } + }) + + test('returns low for non-first-party Anthropic endpoints', () => { + expect(getProviderUsageTrust({ isFirstPartyAnthropic: false })).toBe('low') + }) +}) + +describe('hasMediaInput', () => { + test('returns true for image file attachments', () => { + expect(hasMediaInput([ + { + type: 'attachment', + attachment: { + type: 'file', + content: { type: 'image', source: { type: 'base64', data: 'abc' } }, + }, + }, + ])).toBe(true) + }) + + test('returns true for pdf file attachments', () => { + expect(hasMediaInput([ + { + type: 'attachment', + attachment: { + type: 'file', + content: { type: 'pdf', pages: [] }, + }, + }, + ])).toBe(true) + }) + + test('returns true for user content with an image block', () => { + expect(hasMediaInput([ + { + type: 'user', + message: { + content: [ + { type: 'text', text: 'look at this' }, + { type: 'image', source: { type: 'base64', data: 'abc' } }, + ], + }, + }, + ])).toBe(true) + }) + + test('returns true for assistant content with a document block', () => { + expect(hasMediaInput([ + { + type: 'assistant', + message: { + content: [ + { type: 'document', source: { type: 'text', data: 'report' } }, + ], + }, + }, + ])).toBe(true) + }) + + test('returns false for plain text messages', () => { + expect(hasMediaInput([ + { type: 'user', message: { content: 'hello' } }, + { + type: 'assistant', + message: { content: [{ type: 'text', text: 'hello back' }] }, + }, + ])).toBe(false) + }) + + test('returns false for text-only teammate mailbox attachments', () => { + expect(hasMediaInput([ + { + type: 'attachment', + attachment: { + type: 'teammate_mailbox', + messages: [{ from: 'team-lead', text: 'status?', timestamp: 'now' }], + }, + }, + ])).toBe(false) + }) + + test('returns false for text-only team context attachments', () => { + expect(hasMediaInput([ + { + type: 'attachment', + attachment: { + type: 'team_context', + agentId: 'agent-1', + agentName: 'worker', + teamName: 'alpha', + teamConfigPath: '/tmp/team.json', + taskListPath: '/tmp/tasks.json', + }, + }, + ])).toBe(false) + }) + + test('returns false for text-only skill discovery attachments', () => { + expect(hasMediaInput([ + { + type: 'attachment', + attachment: { + type: 'skill_discovery', + skills: [{ name: 'foo', description: 'bar' }], + signal: 'manual', + source: 'native', + }, + }, + ])).toBe(false) + }) +}) + +describe('getUsageTokenTotal', () => { + test('includes input, cache, and output tokens by default', () => { + expect(getUsageTokenTotal({ + input_tokens: 20_000, + cache_creation_input_tokens: 1_000, + cache_read_input_tokens: 2_000, + output_tokens: 3_000, + })).toBe(26_000) + }) + + test('can exclude output tokens', () => { + expect(getUsageTokenTotal({ + input_tokens: 20_000, + cache_creation_input_tokens: 1_000, + cache_read_input_tokens: 2_000, + output_tokens: 3_000, + }, { includeOutput: false })).toBe(23_000) + }) +}) + +describe('shouldIgnoreLowTrustUsage', () => { + test('ignores suspicious low-trust media usage', () => { + expect(shouldIgnoreLowTrustUsage({ + usageTrust: 'low', + hasMediaInput: true, + usageTokens: 220_000, + estimatedTokens: 30_000, + contextWindow: 200_000, + })).toBe(true) + }) + + test('keeps high-trust usage', () => { + expect(shouldIgnoreLowTrustUsage({ + usageTrust: 'high', + hasMediaInput: true, + usageTokens: 220_000, + estimatedTokens: 30_000, + contextWindow: 200_000, + })).toBe(false) + }) + + test('keeps close-to-estimate usage', () => { + expect(shouldIgnoreLowTrustUsage({ + usageTrust: 'low', + hasMediaInput: true, + usageTokens: 200_000, + estimatedTokens: 180_000, + contextWindow: 200_000, + })).toBe(false) + }) + + test('keeps provider usage when there is no estimate to fall back to', () => { + expect(shouldIgnoreLowTrustUsage({ + usageTrust: 'low', + hasMediaInput: true, + usageTokens: 220_000, + estimatedTokens: 0, + contextWindow: 200_000, + })).toBe(false) + }) +}) + +describe('calculateContextBudget', () => { + test('uses larger trusted provider usage', () => { + expect(calculateContextBudget({ + estimatedTokens: 30_000, + contextWindow: 200_000, + currentUsage: { + input_tokens: 45_000, + cache_creation_input_tokens: 1_000, + cache_read_input_tokens: 2_000, + output_tokens: 3_000, + }, + usageTrust: 'high', + hasMediaInput: false, + })).toEqual({ + usedTokens: 51_000, + source: 'provider_usage', + providerUsageTokens: 51_000, + estimatedTokens: 30_000, + }) + }) + + test('ignores suspicious low-trust media usage', () => { + expect(calculateContextBudget({ + estimatedTokens: 30_000, + contextWindow: 200_000, + currentUsage: { + input_tokens: 220_000, + cache_creation_input_tokens: 0, + cache_read_input_tokens: 0, + output_tokens: 1_000, + }, + usageTrust: 'low', + hasMediaInput: true, + })).toEqual({ + usedTokens: 30_000, + source: 'estimate', + providerUsageTokens: 221_000, + estimatedTokens: 30_000, + ignoredUsageReason: 'low_trust_media_usage', + }) + }) + + test('does not force 100% display for low-trust media usage spikes', () => { + const budget = calculateContextBudget({ + estimatedTokens: 42_000, + currentUsage: { + input_tokens: 500_000, + cache_creation_input_tokens: 0, + cache_read_input_tokens: 0, + output_tokens: 2_000, + }, + contextWindow: 200_000, + usageTrust: 'low', + hasMediaInput: true, + }) + + expect(calculateContextPercentagesFromTokens( + budget.usedTokens, + 200_000, + )).toEqual({ + used: 21, + remaining: 79, + }) + }) + + test('does not fall back to zero tokens for low-trust media usage spikes', () => { + const budget = calculateContextBudget({ + estimatedTokens: 0, + currentUsage: { + input_tokens: 220_000, + cache_creation_input_tokens: 0, + cache_read_input_tokens: 0, + output_tokens: 1_000, + }, + contextWindow: 200_000, + usageTrust: 'low', + hasMediaInput: true, + }) + + expect(budget.source).toBe('provider_usage') + expect(budget.usedTokens).toBe(200_000) + expect(budget.ignoredUsageReason).toBeUndefined() + }) + + test('clamps to contextWindow', () => { + expect(calculateContextBudget({ + estimatedTokens: 990_000, + contextWindow: 1_000_000, + currentUsage: { + input_tokens: 995_000, + cache_creation_input_tokens: 0, + cache_read_input_tokens: 0, + output_tokens: 8_000, + }, + usageTrust: 'high', + hasMediaInput: false, + })).toEqual({ + usedTokens: 1_000_000, + source: 'provider_usage', + providerUsageTokens: 1_003_000, + estimatedTokens: 990_000, + }) + }) +}) + +describe('calculateContextPercentagesFromTokens', () => { + test('returns nulls for null usage', () => { + expect(calculateContextPercentagesFromTokens(null, 200_000)).toEqual({ + used: null, + remaining: null, + }) + }) + + test('returns nulls for invalid context windows', () => { + expect(calculateContextPercentagesFromTokens(50_000, 0)).toEqual({ + used: null, + remaining: null, + }) + expect(calculateContextPercentagesFromTokens(50_000, -1)).toEqual({ + used: null, + remaining: null, + }) + }) + + test('rounds and clamps percentages', () => { + expect(calculateContextPercentagesFromTokens(50_500, 200_000)).toEqual({ + used: 25, + remaining: 75, + }) + expect(calculateContextPercentagesFromTokens(220_000, 200_000)).toEqual({ + used: 100, + remaining: 0, + }) + expect(calculateContextPercentagesFromTokens(-1_000, 200_000)).toEqual({ + used: 0, + remaining: 100, + }) + }) +}) diff --git a/src/utils/analyzeContext.ts b/src/utils/analyzeContext.ts index 54606d48..505ed300 100644 --- a/src/utils/analyzeContext.ts +++ b/src/utils/analyzeContext.ts @@ -19,6 +19,8 @@ import { countMessagesTokensWithAPI, countTokensViaHaikuFallback, roughTokenCountEstimation, + roughTokenCountEstimationForAPIRequest, + roughTokenCountEstimationForContent, } from '../services/tokenEstimation.js' import { estimateSkillFrontmatterTokens } from '../skills/loadSkillsDir.js' import { @@ -52,6 +54,7 @@ import { calculateCurrentContextTokenTotal, getContextWindowForModel, } from './context.js' +import { getProviderUsageTrust, hasMediaInput } from './contextBudget.js' import { getCwd } from './cwd.js' import { logForDebugging } from './debug.js' import { isEnvTruthy } from './envUtils.js' @@ -59,6 +62,7 @@ import { errorMessage, toError } from './errors.js' import { logError } from './log.js' import { normalizeMessagesForAPI } from './messages.js' import { getRuntimeMainLoopModel } from './model/model.js' +import { isFirstPartyAnthropicBaseUrl } from './model/providers.js' import type { SettingSource } from './settings/constants.js' import { jsonStringify } from './slowOperations.js' import { buildEffectiveSystemPrompt } from './systemPrompt.js' @@ -83,7 +87,7 @@ async function countTokensWithFallback( estimateOnly = false, ): Promise { if (estimateOnly) { - return roughTokenCountEstimation(jsonStringify({ messages, tools })) + return roughTokenCountEstimationForAPIRequest(messages, tools) } try { @@ -810,8 +814,7 @@ function processAssistantMessage( ): void { // Process each content block individually for (const block of msg.message.content) { - const blockStr = jsonStringify(block) - const blockTokens = roughTokenCountEstimation(blockStr) + const blockTokens = roughTokenCountEstimationForContent([block]) if ('type' in block && block.type === 'tool_use') { breakdown.toolCallTokens += blockTokens @@ -842,8 +845,7 @@ function processUserMessage( // Process each content block individually for (const block of msg.message.content) { - const blockStr = jsonStringify(block) - const blockTokens = roughTokenCountEstimation(blockStr) + const blockTokens = roughTokenCountEstimationForContent([block]) if ('type' in block && block.type === 'tool_result') { breakdown.toolResultTokens += blockTokens @@ -865,8 +867,12 @@ function processAttachment( msg: AttachmentMessage, breakdown: MessageBreakdown, ): void { - const contentStr = jsonStringify(msg.attachment) - const tokens = roughTokenCountEstimation(contentStr) + const userMessages = normalizeAttachmentForAPI(msg.attachment) + const tokens = userMessages.reduce( + (total, userMsg) => + total + roughTokenCountEstimationForContent(userMsg.message.content), + 0, + ) breakdown.attachmentTokens += tokens const attachType = msg.attachment.type || 'unknown' breakdown.attachmentsByType.set( @@ -1208,6 +1214,12 @@ export async function analyzeContextUsage( totalIncludingReserved, apiUsage, contextWindow, + { + hasMediaInput: hasMediaInput(originalMessages ?? messages), + usageTrust: getProviderUsageTrust({ + isFirstPartyAnthropic: isFirstPartyAnthropicBaseUrl(), + }), + }, ) // Pre-calculate grid based on model context window and terminal width diff --git a/src/utils/context.ts b/src/utils/context.ts index 37045ed2..e99ac88a 100644 --- a/src/utils/context.ts +++ b/src/utils/context.ts @@ -2,6 +2,11 @@ import { CONTEXT_1M_BETA_HEADER } from '../constants/betas.js' import { getOpenAICodexContextWindowForModel } from '../services/openaiAuth/models.js' import { getGlobalConfig } from './config.js' +import { + calculateContextBudget, + calculateContextPercentagesFromTokens, + type ProviderUsageTrust, +} from './contextBudget.js' import { isEnvTruthy } from './envUtils.js' import { getCanonicalName } from './model/model.js' import { getModelCapability } from './model/modelCapabilities.js' @@ -145,20 +150,12 @@ export function calculateContextPercentages( return { used: null, remaining: null } } - const totalInputTokens = + return calculateContextPercentagesFromTokens( currentUsage.input_tokens + - currentUsage.cache_creation_input_tokens + - currentUsage.cache_read_input_tokens - - const usedPercentage = Math.round( - (totalInputTokens / contextWindowSize) * 100, + currentUsage.cache_creation_input_tokens + + currentUsage.cache_read_input_tokens, + contextWindowSize, ) - const clampedUsed = Math.min(100, Math.max(0, usedPercentage)) - - return { - used: clampedUsed, - remaining: 100 - clampedUsed, - } } /** @@ -184,7 +181,21 @@ export function calculateCurrentContextTokenTotal( cache_read_input_tokens: number } | null, contextWindow?: number, + options?: { hasMediaInput?: boolean; usageTrust?: ProviderUsageTrust }, ): number { + const hasMediaInput = options?.hasMediaInput ?? false + const usageTrust = options?.usageTrust ?? 'high' + + if (contextWindow !== undefined) { + return calculateContextBudget({ + estimatedTokens, + contextWindow, + currentUsage, + usageTrust, + hasMediaInput, + }).usedTokens + } + if (!currentUsage) return estimatedTokens const totalFromAPI = @@ -193,8 +204,7 @@ export function calculateCurrentContextTokenTotal( currentUsage.cache_read_input_tokens + (currentUsage.output_tokens ?? 0) - const total = Math.max(estimatedTokens, totalFromAPI) - return contextWindow !== undefined ? Math.min(total, contextWindow) : total + return Math.max(estimatedTokens, totalFromAPI) } /** diff --git a/src/utils/contextBudget.ts b/src/utils/contextBudget.ts new file mode 100644 index 00000000..c1734f8f --- /dev/null +++ b/src/utils/contextBudget.ts @@ -0,0 +1,178 @@ +import { getAPIProvider } from './model/providers.js' + +export type ProviderUsageTrust = 'high' | 'low' + +export type ContextUsageLike = { + input_tokens: number + output_tokens?: number + cache_creation_input_tokens: number + cache_read_input_tokens: number +} + +export type ContextBudgetSource = 'estimate' | 'provider_usage' + +export type ContextBudget = { + usedTokens: number + source: ContextBudgetSource + providerUsageTokens: number | null + estimatedTokens: number + ignoredUsageReason?: 'low_trust_media_usage' +} + +export function getProviderUsageTrust(args: { + isFirstPartyAnthropic: boolean +}): ProviderUsageTrust { + return getAPIProvider() === 'firstParty' && args.isFirstPartyAnthropic + ? 'high' + : 'low' +} + +function isMediaAttachment(attachment: unknown): boolean { + if (typeof attachment !== 'object' || attachment === null) return false + + const candidate = attachment as { + type?: unknown + content?: { type?: unknown } | null + } + + if (candidate.type !== 'file') return false + + return ( + candidate.content?.type === 'image' || candidate.content?.type === 'pdf' + ) +} + +export function hasMediaInput( + messages: readonly { + type: string + message?: { content?: unknown } + attachment?: unknown + }[], +): boolean { + return messages.some(message => { + if (message.type === 'attachment') { + return isMediaAttachment(message.attachment) + } + if (message.type !== 'user' && message.type !== 'assistant') return false + if (!Array.isArray(message.message?.content)) return false + + return message.message.content.some( + block => + typeof block === 'object' && + block !== null && + 'type' in block && + (block.type === 'image' || block.type === 'document'), + ) + }) +} + +type ShouldIgnoreLowTrustUsageArgs = { + usageTrust: ProviderUsageTrust + hasMediaInput: boolean + usageTokens: number + estimatedTokens: number + contextWindow: number +} + +type CalculateContextBudgetArgs = { + estimatedTokens: number + contextWindow: number + currentUsage: ContextUsageLike | null + usageTrust: ProviderUsageTrust + hasMediaInput: boolean +} + +export function getUsageTokenTotal( + usage: ContextUsageLike, + options?: { includeOutput?: boolean }, +): number { + const includeOutput = options?.includeOutput ?? true + + return ( + usage.input_tokens + + usage.cache_creation_input_tokens + + usage.cache_read_input_tokens + + (includeOutput ? usage.output_tokens ?? 0 : 0) + ) +} + +export function shouldIgnoreLowTrustUsage( + args: ShouldIgnoreLowTrustUsageArgs, +): boolean { + if (args.usageTrust === 'high') return false + if (!args.hasMediaInput) return false + if (args.estimatedTokens <= 0) return false + if (args.usageTokens < args.contextWindow) return false + if (args.estimatedTokens >= args.contextWindow) return false + + const suspiciousFloor = Math.max( + args.estimatedTokens * 4, + args.estimatedTokens + 50_000, + ) + return args.usageTokens > suspiciousFloor +} + +export function calculateContextBudget( + args: CalculateContextBudgetArgs, +): ContextBudget { + const estimatedTokens = Math.min(args.estimatedTokens, args.contextWindow) + + if (!args.currentUsage) { + return { + usedTokens: estimatedTokens, + source: 'estimate', + providerUsageTokens: null, + estimatedTokens: args.estimatedTokens, + } + } + + const providerUsageTokens = getUsageTokenTotal(args.currentUsage) + + if ( + shouldIgnoreLowTrustUsage({ + usageTrust: args.usageTrust, + hasMediaInput: args.hasMediaInput, + usageTokens: providerUsageTokens, + estimatedTokens: args.estimatedTokens, + contextWindow: args.contextWindow, + }) + ) { + return { + usedTokens: estimatedTokens, + source: 'estimate', + providerUsageTokens, + estimatedTokens: args.estimatedTokens, + ignoredUsageReason: 'low_trust_media_usage', + } + } + + const usedTokens = Math.min( + Math.max(args.estimatedTokens, providerUsageTokens), + args.contextWindow, + ) + + return { + usedTokens, + source: + providerUsageTokens >= args.estimatedTokens ? 'provider_usage' : 'estimate', + providerUsageTokens, + estimatedTokens: args.estimatedTokens, + } +} + +export function calculateContextPercentagesFromTokens( + usedTokens: number | null, + contextWindowSize: number, +): { used: number | null; remaining: number | null } { + if (usedTokens === null || contextWindowSize <= 0) { + return { used: null, remaining: null } + } + + const usedPercentage = Math.round((usedTokens / contextWindowSize) * 100) + const used = Math.min(100, Math.max(0, usedPercentage)) + + return { + used, + remaining: 100 - used, + } +} diff --git a/src/utils/messages.ts b/src/utils/messages.ts index c9bd5ca9..8ea0e002 100644 --- a/src/utils/messages.ts +++ b/src/utils/messages.ts @@ -31,6 +31,7 @@ import { } from '../services/analytics/growthbook.js' import { getImageTooLargeErrorMessage, + getImageUnsupportedErrorMessage, getPdfInvalidErrorMessage, getPdfPasswordProtectedErrorMessage, getPdfTooLargeErrorMessage, @@ -2006,6 +2007,7 @@ export function normalizeMessagesForAPI( [getPdfPasswordProtectedErrorMessage()]: new Set(['document']), [getPdfInvalidErrorMessage()]: new Set(['document']), [getImageTooLargeErrorMessage()]: new Set(['image']), + [getImageUnsupportedErrorMessage()]: new Set(['image']), [getRequestTooLargeErrorMessage()]: new Set(['document', 'image']), } @@ -2030,10 +2032,12 @@ export function normalizeMessagesForAPI( if (!blockTypesToStrip) { continue } - // Walk backward to find the nearest preceding isMeta user message + // Walk backward to find the nearest preceding user message. Normal pasted + // images are ordinary user turns, while attachment-derived media can be + // meta turns; both need to be stripped after a provider media rejection. for (let j = i - 1; j >= 0; j--) { const candidate = reorderedMessages[j]! - if (candidate.type === 'user' && candidate.isMeta) { + if (candidate.type === 'user') { const existing = stripTargets.get(candidate.uuid) if (existing) { for (const t of blockTypesToStrip) { @@ -2044,11 +2048,11 @@ export function normalizeMessagesForAPI( } break } - // Skip over other synthetic error messages or non-meta messages + // Skip over other synthetic error messages if (isSyntheticApiErrorMessage(candidate)) { continue } - // Stop if we hit an assistant message or non-meta user message + // Stop if we hit an assistant message or any other non-user message. break } } @@ -2110,11 +2114,11 @@ export function normalizeMessagesForAPI( ) } - // Strip document/image blocks from the specific meta user message that + // Strip document/image blocks from the specific user message that // preceded a PDF/image/request-too-large error, to prevent re-sending // the problematic content on every subsequent API call. const typesToStrip = stripTargets.get(normalizedMessage.uuid) - if (typesToStrip && normalizedMessage.isMeta) { + if (typesToStrip) { const content = normalizedMessage.message.content if (Array.isArray(content)) { const filtered = content.filter( diff --git a/tests/mediaRecoveryAndEstimation.test.ts b/tests/mediaRecoveryAndEstimation.test.ts new file mode 100644 index 00000000..ecc36f5e --- /dev/null +++ b/tests/mediaRecoveryAndEstimation.test.ts @@ -0,0 +1,67 @@ +import { describe, expect, test } from 'bun:test' +import { getImageUnsupportedErrorMessage } from '../src/services/api/errors.js' +import { roughTokenCountEstimationForAPIRequest } from '../src/services/tokenEstimation.js' +import type { UserMessage } from '../src/types/message.js' +import { + createAssistantAPIErrorMessage, + createUserMessage, + normalizeMessagesForAPI, +} from '../src/utils/messages.js' + +const imageBlock = (data: string) => ({ + type: 'image' as const, + source: { + type: 'base64' as const, + media_type: 'image/png' as const, + data, + }, +}) + +describe('media error recovery', () => { + test('strips images after an unsupported-image model error', () => { + const imageUser = createUserMessage({ + content: [ + { type: 'text', text: 'describe this screenshot' }, + imageBlock('base64-image-payload'), + { type: 'text', text: '[Image source: /tmp/screenshot.png]' }, + ], + uuid: '00000000-0000-4000-8000-000000000001', + }) + const unsupported = createAssistantAPIErrorMessage({ + content: getImageUnsupportedErrorMessage(), + error: 'invalid_request', + }) + const nextUser = createUserMessage({ + content: 'continue with text only', + uuid: '00000000-0000-4000-8000-000000000002', + }) + + const normalized = normalizeMessagesForAPI([imageUser, unsupported, nextUser]) + const serialized = JSON.stringify(normalized) + + expect(serialized).not.toContain('base64-image-payload') + expect(serialized).toContain('describe this screenshot') + expect(serialized).toContain('continue with text only') + }) +}) + +describe('media context estimation', () => { + test('does not count base64 image bytes as text tokens', () => { + const rawBase64 = 'a'.repeat(1_000_000) + const tokens = roughTokenCountEstimationForAPIRequest( + [ + { + role: 'user', + content: [ + { type: 'text', text: 'what is in this image?' }, + imageBlock(rawBase64), + ] as UserMessage['message']['content'], + }, + ], + [], + ) + + expect(tokens).toBeGreaterThanOrEqual(2_000) + expect(tokens).toBeLessThan(3_000) + }) +})