mirror of
http://10.0.2.1:3031/sauer/claude-code.git
synced 2026-06-30 18:06:57 +10:00
269 lines
33 KiB
TypeScript
269 lines
33 KiB
TypeScript
|
|
import { c as _c } from "react/compiler-runtime";
|
||
|
|
import * as React from 'react';
|
||
|
|
import { useState } from 'react';
|
||
|
|
import type { CommandResultDisplay, LocalJSXCommandContext } from '../../commands.js';
|
||
|
|
import { Dialog } from '../../components/design-system/Dialog.js';
|
||
|
|
import { FastIcon, getFastIconString } from '../../components/FastIcon.js';
|
||
|
|
import { Box, Link, Text } from '../../ink.js';
|
||
|
|
import { useKeybindings } from '../../keybindings/useKeybinding.js';
|
||
|
|
import { type AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS, logEvent } from '../../services/analytics/index.js';
|
||
|
|
import { type AppState, useAppState, useSetAppState } from '../../state/AppState.js';
|
||
|
|
import type { LocalJSXCommandOnDone } from '../../types/command.js';
|
||
|
|
import { clearFastModeCooldown, FAST_MODE_MODEL_DISPLAY, getFastModeModel, getFastModeRuntimeState, getFastModeUnavailableReason, isFastModeEnabled, isFastModeSupportedByModel, prefetchFastModeStatus } from '../../utils/fastMode.js';
|
||
|
|
import { formatDuration } from '../../utils/format.js';
|
||
|
|
import { formatModelPricing, getOpus46CostTier } from '../../utils/modelCost.js';
|
||
|
|
import { updateSettingsForSource } from '../../utils/settings/settings.js';
|
||
|
|
function applyFastMode(enable: boolean, setAppState: (f: (prev: AppState) => AppState) => void): void {
|
||
|
|
clearFastModeCooldown();
|
||
|
|
updateSettingsForSource('userSettings', {
|
||
|
|
fastMode: enable ? true : undefined
|
||
|
|
});
|
||
|
|
if (enable) {
|
||
|
|
setAppState(prev => {
|
||
|
|
// Only switch model if current model doesn't support fast mode
|
||
|
|
const needsModelSwitch = !isFastModeSupportedByModel(prev.mainLoopModel);
|
||
|
|
return {
|
||
|
|
...prev,
|
||
|
|
...(needsModelSwitch ? {
|
||
|
|
mainLoopModel: getFastModeModel(),
|
||
|
|
mainLoopModelForSession: null
|
||
|
|
} : {}),
|
||
|
|
fastMode: true
|
||
|
|
};
|
||
|
|
});
|
||
|
|
} else {
|
||
|
|
setAppState(prev => ({
|
||
|
|
...prev,
|
||
|
|
fastMode: false
|
||
|
|
}));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
export function FastModePicker(t0) {
|
||
|
|
const $ = _c(30);
|
||
|
|
const {
|
||
|
|
onDone,
|
||
|
|
unavailableReason
|
||
|
|
} = t0;
|
||
|
|
const model = useAppState(_temp);
|
||
|
|
const initialFastMode = useAppState(_temp2);
|
||
|
|
const setAppState = useSetAppState();
|
||
|
|
const [enableFastMode, setEnableFastMode] = useState(initialFastMode ?? false);
|
||
|
|
let t1;
|
||
|
|
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
||
|
|
t1 = getFastModeRuntimeState();
|
||
|
|
$[0] = t1;
|
||
|
|
} else {
|
||
|
|
t1 = $[0];
|
||
|
|
}
|
||
|
|
const runtimeState = t1;
|
||
|
|
const isCooldown = runtimeState.status === "cooldown";
|
||
|
|
const isUnavailable = unavailableReason !== null;
|
||
|
|
let t2;
|
||
|
|
if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
|
||
|
|
t2 = formatModelPricing(getOpus46CostTier(true));
|
||
|
|
$[1] = t2;
|
||
|
|
} else {
|
||
|
|
t2 = $[1];
|
||
|
|
}
|
||
|
|
const pricing = t2;
|
||
|
|
let t3;
|
||
|
|
if ($[2] !== enableFastMode || $[3] !== isUnavailable || $[4] !== model || $[5] !== onDone || $[6] !== setAppState) {
|
||
|
|
t3 = function handleConfirm() {
|
||
|
|
if (isUnavailable) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
applyFastMode(enableFastMode, setAppState);
|
||
|
|
logEvent("tengu_fast_mode_toggled", {
|
||
|
|
enabled: enableFastMode,
|
||
|
|
source: "picker" as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS
|
||
|
|
});
|
||
|
|
if (enableFastMode) {
|
||
|
|
const fastIcon = getFastIconString(enableFastMode);
|
||
|
|
const modelUpdated = !isFastModeSupportedByModel(model) ? ` · model set to ${FAST_MODE_MODEL_DISPLAY}` : "";
|
||
|
|
onDone(`${fastIcon} Fast mode ON${modelUpdated} · ${pricing}`);
|
||
|
|
} else {
|
||
|
|
setAppState(_temp3);
|
||
|
|
onDone("Fast mode OFF");
|
||
|
|
}
|
||
|
|
};
|
||
|
|
$[2] = enableFastMode;
|
||
|
|
$[3] = isUnavailable;
|
||
|
|
$[4] = model;
|
||
|
|
$[5] = onDone;
|
||
|
|
$[6] = setAppState;
|
||
|
|
$[7] = t3;
|
||
|
|
} else {
|
||
|
|
t3 = $[7];
|
||
|
|
}
|
||
|
|
const handleConfirm = t3;
|
||
|
|
let t4;
|
||
|
|
if ($[8] !== initialFastMode || $[9] !== isUnavailable || $[10] !== onDone || $[11] !== setAppState) {
|
||
|
|
t4 = function handleCancel() {
|
||
|
|
if (isUnavailable) {
|
||
|
|
if (initialFastMode) {
|
||
|
|
applyFastMode(false, setAppState);
|
||
|
|
}
|
||
|
|
onDone("Fast mode OFF", {
|
||
|
|
display: "system"
|
||
|
|
});
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
const message = initialFastMode ? `${getFastIconString()} Kept Fast mode ON` : "Kept Fast mode OFF";
|
||
|
|
onDone(message, {
|
||
|
|
display: "system"
|
||
|
|
});
|
||
|
|
};
|
||
|
|
$[8] = initialFastMode;
|
||
|
|
$[9] = isUnavailable;
|
||
|
|
$[10] = onDone;
|
||
|
|
$[11] = setAppState;
|
||
|
|
$[12] = t4;
|
||
|
|
} else {
|
||
|
|
t4 = $[12];
|
||
|
|
}
|
||
|
|
const handleCancel = t4;
|
||
|
|
let t5;
|
||
|
|
if ($[13] !== isUnavailable) {
|
||
|
|
t5 = function handleToggle() {
|
||
|
|
if (isUnavailable) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
setEnableFastMode(_temp4);
|
||
|
|
};
|
||
|
|
$[13] = isUnavailable;
|
||
|
|
$[14] = t5;
|
||
|
|
} else {
|
||
|
|
t5 = $[14];
|
||
|
|
}
|
||
|
|
const handleToggle = t5;
|
||
|
|
let t6;
|
||
|
|
if ($[15] !== handleConfirm || $[16] !== handleToggle) {
|
||
|
|
t6 = {
|
||
|
|
"confirm:yes": handleConfirm,
|
||
|
|
"confirm:nextField": handleToggle,
|
||
|
|
"confirm:next": handleToggle,
|
||
|
|
"confirm:previous": handleToggle,
|
||
|
|
"confirm:cycleMode": handleToggle,
|
||
|
|
"confirm:toggle": handleToggle
|
||
|
|
};
|
||
|
|
$[15] = handleConfirm;
|
||
|
|
$[16] = handleToggle;
|
||
|
|
$[17] = t6;
|
||
|
|
} else {
|
||
|
|
t6 = $[17];
|
||
|
|
}
|
||
|
|
let t7;
|
||
|
|
if ($[18] === Symbol.for("react.memo_cache_sentinel")) {
|
||
|
|
t7 = {
|
||
|
|
context: "Confirmation"
|
||
|
|
};
|
||
|
|
$[18] = t7;
|
||
|
|
} else {
|
||
|
|
t7 = $[18];
|
||
|
|
}
|
||
|
|
useKeybindings(t6, t7);
|
||
|
|
let t8;
|
||
|
|
if ($[19] === Symbol.for("react.memo_cache_sentinel")) {
|
||
|
|
t8 = <Text><FastIcon cooldown={isCooldown} /> Fast mode (research preview)</Text>;
|
||
|
|
$[19] = t8;
|
||
|
|
} else {
|
||
|
|
t8 = $[19];
|
||
|
|
}
|
||
|
|
const title = t8;
|
||
|
|
let t9;
|
||
|
|
if ($[20] !== isUnavailable) {
|
||
|
|
t9 = exitState => exitState.pending ? <Text>Press {exitState.keyName} again to exit</Text> : isUnavailable ? <Text>Esc to cancel</Text> : <Text>Tab to toggle · Enter to confirm · Esc to cancel</Text>;
|
||
|
|
$[20] = isUnavailable;
|
||
|
|
$[21] = t9;
|
||
|
|
} else {
|
||
|
|
t9 = $[21];
|
||
|
|
}
|
||
|
|
let t10;
|
||
|
|
if ($[22] !== enableFastMode || $[23] !== unavailableReason) {
|
||
|
|
t10 = unavailableReason ? <Box marginLeft={2}><Text color="error">{unavailableReason}</Text></Box> : <><Box flexDirection="column" gap={0} marginLeft={2}><Box flexDirection="row" gap={2}><Text bold={true}>Fast mode</Text><Text color={enableFastMode ? "fastMode" : undefined} bold={enableFastMode}>{enableFastMode ? "ON " : "OFF"}</Text><Text dimColor={true}>{pricing}</Text></Box></Box>{isCooldown && runtimeState.status === "cooldown" && <Box marginLeft={2}><Text color="warning">{runtimeState.reason === "overloaded" ? "Fast mode overloaded and is temporarily unavailable" : "You've hit your fast limit"}{" \xB7 resets in "}{formatDuration(runtimeState.resetAt - Date.now(), {
|
||
|
|
hideTrailingZeros: true
|
||
|
|
})}</Text></Box>}</>;
|
||
|
|
$[22] = enableFastMode;
|
||
|
|
$[23] = unavailableReason;
|
||
|
|
$[24] = t10;
|
||
|
|
} else {
|
||
|
|
t10 = $[24];
|
||
|
|
}
|
||
|
|
let t11;
|
||
|
|
if ($[25] === Symbol.for("react.memo_cache_sentinel")) {
|
||
|
|
t11 = <Text dimColor={true}>Learn more:{" "}<Link url="https://code.claude.com/docs/en/fast-mode">https://code.claude.com/docs/en/fast-mode</Link></Text>;
|
||
|
|
$[25] = t11;
|
||
|
|
} else {
|
||
|
|
t11 = $[25];
|
||
|
|
}
|
||
|
|
let t12;
|
||
|
|
if ($[26] !== handleCancel || $[27] !== t10 || $[28] !== t9) {
|
||
|
|
t12 = <Dialog title={title} subtitle={`High-speed mode for ${FAST_MODE_MODEL_DISPLAY}. Billed as extra usage at a premium rate. Separate rate limits apply.`} onCancel={handleCancel} color="fastMode" inputGuide={t9}>{t10}{t11}</Dialog>;
|
||
|
|
$[26] = handleCancel;
|
||
|
|
$[27] = t10;
|
||
|
|
$[28] = t9;
|
||
|
|
$[29] = t12;
|
||
|
|
} else {
|
||
|
|
t12 = $[29];
|
||
|
|
}
|
||
|
|
return t12;
|
||
|
|
}
|
||
|
|
function _temp4(prev_0) {
|
||
|
|
return !prev_0;
|
||
|
|
}
|
||
|
|
function _temp3(prev) {
|
||
|
|
return {
|
||
|
|
...prev,
|
||
|
|
fastMode: false
|
||
|
|
};
|
||
|
|
}
|
||
|
|
function _temp2(s_0) {
|
||
|
|
return s_0.fastMode;
|
||
|
|
}
|
||
|
|
function _temp(s) {
|
||
|
|
return s.mainLoopModel;
|
||
|
|
}
|
||
|
|
async function handleFastModeShortcut(enable: boolean, getAppState: () => AppState, setAppState: (f: (prev: AppState) => AppState) => void): Promise<string> {
|
||
|
|
const unavailableReason = getFastModeUnavailableReason();
|
||
|
|
if (unavailableReason) {
|
||
|
|
return `Fast mode unavailable: ${unavailableReason}`;
|
||
|
|
}
|
||
|
|
const {
|
||
|
|
mainLoopModel
|
||
|
|
} = getAppState();
|
||
|
|
applyFastMode(enable, setAppState);
|
||
|
|
logEvent('tengu_fast_mode_toggled', {
|
||
|
|
enabled: enable,
|
||
|
|
source: 'shortcut' as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS
|
||
|
|
});
|
||
|
|
if (enable) {
|
||
|
|
const fastIcon = getFastIconString(true);
|
||
|
|
const modelUpdated = !isFastModeSupportedByModel(mainLoopModel) ? ` · model set to ${FAST_MODE_MODEL_DISPLAY}` : '';
|
||
|
|
const pricing = formatModelPricing(getOpus46CostTier(true));
|
||
|
|
return `${fastIcon} Fast mode ON${modelUpdated} · ${pricing}`;
|
||
|
|
} else {
|
||
|
|
return `Fast mode OFF`;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
export async function call(onDone: LocalJSXCommandOnDone, context: LocalJSXCommandContext, args?: string): Promise<React.ReactNode | null> {
|
||
|
|
if (!isFastModeEnabled()) {
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
|
||
|
|
// Fetch org fast mode status before showing the picker. We must know
|
||
|
|
// whether the org has disabled fast mode before allowing any toggle.
|
||
|
|
// If a startup prefetch is already in flight, this awaits it.
|
||
|
|
await prefetchFastModeStatus();
|
||
|
|
const arg = args?.trim().toLowerCase();
|
||
|
|
if (arg === 'on' || arg === 'off') {
|
||
|
|
const result = await handleFastModeShortcut(arg === 'on', context.getAppState, context.setAppState);
|
||
|
|
onDone(result);
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
const unavailableReason = getFastModeUnavailableReason();
|
||
|
|
logEvent('tengu_fast_mode_picker_shown', {
|
||
|
|
unavailable_reason: (unavailableReason ?? '') as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS
|
||
|
|
});
|
||
|
|
return <FastModePicker onDone={onDone} unavailableReason={unavailableReason} />;
|
||
|
|
}
|
||
|
|
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJSZWFjdCIsInVzZVN0YXRlIiwiQ29tbWFuZFJlc3VsdERpc3BsYXkiLCJMb2NhbEpTWENvbW1hbmRDb250ZXh0IiwiRGlhbG9nIiwiRmFzdEljb24iLCJnZXRGYXN0SWNvblN0cmluZyIsIkJveCIsIkxpbmsiLCJUZXh0IiwidXNlS2V5YmluZGluZ3MiLCJBbmFseXRpY3NNZXRhZGF0YV9JX1ZFUklGSUVEX1RISVNfSVNfTk9UX0NPREVfT1JfRklMRVBBVEhTIiwibG9nRXZlbnQiLCJBcHBTdGF0ZSIsInVzZUFwcFN0YXRlIiwidXNlU2V0QXBwU3RhdGUiLCJMb2NhbEpTWENvbW1hbmRPbkRvbmUiLCJjbGVhckZhc3RNb2RlQ29vbGRvd24iLCJGQVNUX01PREVfTU9ERUxfRElTUExBWSIsImdldEZhc3RNb2RlTW9kZWwiLCJnZXRGYXN0TW9kZVJ1bnRpbWVTdGF0ZSIsImdldEZhc3RNb2RlVW5hdmFpbGFibGVSZWFzb24iLCJpc0Zhc3RNb2RlRW5hYmxlZCIsImlzRmFzdE1vZGVTdXBwb3J0ZWRCeU1vZGVsIiwicHJlZmV0Y2hGYXN0TW9kZVN0YXR1cyIsImZvcm1hdER1cmF0aW9uIiwiZm9ybWF0TW9kZWxQcmljaW5nIiwiZ2V0T3B1czQ2Q29zdFRpZXIiLCJ1cGRhdGVTZXR0aW5nc0ZvclNvdXJjZSIsImFwcGx5RmFzdE1vZGUiLCJlbmFibGUiLCJzZXRBcHBTdGF0ZSIsImYiLCJwcmV2IiwiZmFzdE1vZGUiLCJ1bmRlZmluZWQiLCJuZWVkc01vZGVsU3dpdGNoIiwibWFpbkxvb3BNb2RlbCIsIm1haW5Mb29wTW9kZWxGb3JTZXNzaW9uIiwiRmFzdE1vZGVQaWNrZXIiLCJ0MCIsIiQiLCJfYyIsIm9uRG9uZSIsInVuYXZhaWxhYmxlUmVhc29uIiwibW9kZWwiLCJfdGVtcCIsImluaXRpYWxGYXN0TW9kZSIsIl90ZW1wMiIsImVuYWJsZUZhc3RNb2RlIiwic2V0RW5hYmxlRmFzdE1vZGUiLCJ0MSIsIlN5bWJvbCIsImZvciIsInJ1bnRpbWVTdGF0ZSIsImlzQ29vbGRvd24iLCJzdGF0dXMiLCJpc1VuYXZhaWxhYmxlIiwidDIiLCJwcmljaW5nIiwidDMiLCJoYW5kbGVDb25maXJtIiwiZW5hYmxlZCIsInNvdXJjZSIsImZhc3RJY29uIiwibW9kZWxVcGRhdGVkIiwiX3RlbXAzIiwidDQiLCJoYW5kbGVDYW5jZWwiLCJkaXNwbGF5IiwibWVzc2FnZSIsInQ1IiwiaGFuZGxlVG9nZ2xlIiwiX3RlbXA0IiwidDYiLCJ0NyIsImNvbnRleHQiLCJ0OCIsInRpdGxlIiwidDkiLCJleGl0U3RhdGUiLCJwZW5kaW5nIiwia2V5TmFtZSIsInQxMCIsInJlYXNvbiIsInJlc2V0QXQiLCJEYXRlIiwibm93IiwiaGlkZVRyYWlsaW5nWmVyb3MiLCJ0MTEiLCJ0MTIiLCJwcmV2XzAiLCJzXzAiLCJzIiwiaGFuZGxlRmFzdE1vZGVTaG9ydGN1dCIsImdldEFwcFN0YXRlIiwiUHJvbWlzZSIsImNhbGwiLCJhcmdzIiwiUmVhY3ROb2RlIiwiYXJnIiwidHJpbSIsInRvTG93ZXJDYXNlIiwicmVzdWx0IiwidW5hdmFpbGFibGVfcmVhc29uIl0sInNvdXJjZXMiOlsiZmFzdC50c3giXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnXG5pbXBvcnQgeyB1c2VTdGF0ZSB9IGZyb20gJ3JlYWN0J1xuaW1wb3J0IHR5cGUge1xuICBDb21tYW5kUmVzdWx0RGlzcGxheSxcbiAgTG9jYWxKU1hDb21tYW5kQ29udGV4dCxcbn0gZnJvbSAnLi4vLi4vY29tbWFuZHMuanMnXG5pbXBvcnQgeyBEaWFsb2cgfSBmcm9tICcuLi8uLi9jb21wb25lbnRzL2Rlc2lnbi1zeXN0ZW0vRGlhbG9nLmpzJ1xuaW1wb3J0IHsgRmFzdEljb24sIGdldEZhc3RJY29uU3RyaW5nIH0gZnJvbSAnLi4vLi4vY29tcG9uZW50cy9GYXN0SWNvbi5qcydcbmltcG9ydCB7IEJveCwgTGluaywgVGV4dCB9IGZyb20gJy4uLy4uL2luay5qcydcbmltcG9ydCB7IHVzZUtleWJpbmRpbmdzIH0gZnJvbSAnLi4vLi4va2V5YmluZGluZ3MvdXNlS2V5YmluZGluZy5qcydcbmltcG9ydCB7XG4gIHR5cGUgQW5hbHl0aWNzTWV0YWRhdGFfSV9WRVJJRklFRF9USElTX0lTX05PVF9DT0RFX09SX0ZJTEVQQVRIUyxcbiAgbG9nRXZlbnQsXG59IGZyb20gJy4uLy4uL3NlcnZpY2VzL2FuYWx5dGljcy9pbmRleC5qcydcbmltcG9ydCB7XG4gIHR5cGUgQXBwU3RhdGUsXG4gIHVzZUFwcFN0YXRlLFxuICB1c2VTZXRBcHBTdGF0ZSxcbn0gZnJvbSAnLi4vLi4vc3RhdGUvQXBwU3RhdGUuanMnXG5pbXBvcnQgdHlwZSB7IExvY2FsSlNYQ29tbWFuZE9uRG9uZSB9IGZyb20gJy4uLy4uL3R5cGVzL2NvbW1hbmQuanMnXG5pbXBvcnQge1xuICBjbGVhckZhc3RNb2RlQ29vbGRvd24sXG4gIEZBU1RfTU9ERV9NT0RFTF9ESVNQTEFZLFxuICBnZXRGYXN0TW9kZU1vZGVsLFxuICBnZXRGYXN0TW9kZVJ1bnRpbWVTdGF0ZSxcbiAgZ2V0RmFzdE1vZGVVbmF2YWlsYWJsZVJlYXNvbixcbiAgaXNGYXN0TW9kZUVuYWJsZWQsXG4gIGlzRmFzdE1vZGVTdXBwb3J0ZWRCeU1vZGVsLFxuICBwcmVmZXRjaEZhc3RNb2RlU3RhdHVzLFxufSBmcm9tICcuLi8uLi91dGlscy9mYXN0TW9kZS5qcydcbmltcG9ydCB7IGZvcm1hdER1cmF0aW9uIH0gZnJvbSAnLi4vLi4vdXRpbHMvZm9ybWF0LmpzJ1xuaW1wb3J0IHsgZm9ybWF0TW9kZWxQcmljaW5nLCBnZXRPcHVzNDZDb3N0VGllciB9IGZyb20gJy4uLy4uL3V0aWxzL21vZGVsQ29zdC5qcydcbmltcG9ydCB7IHVwZGF0ZVNldHRpbmdzRm9yU291cmNlIH0gZnJvbSAnLi4vLi4vdXRpbHMvc2V0dGluZ3Mvc2V0dGluZ3MuanMnXG5cbmZ1bmN0aW9uIGFwcGx5RmFzdE1vZGUoXG4gIGVuYWJsZTogYm9vbGVhbixcbiAgc2V0QXBwU3RhdGU6IChmOiAocHJldjogQXBwU3RhdGUpID0+IEFwcFN0YXRlKSA9PiB2b2lkLFxuKTogdm9pZCB7XG4gIGNsZWFyRmFzdE1vZGVDb29sZG93bigpXG4gIHVwZGF0ZVNldHRpbmdzRm9yU291cmNlKCd1c2VyU2V0dGluZ3MnLCB7XG4gICAgZmFzdE1vZGU6IGVuYWJsZSA/IHRydWUgOiB1bmRlZmluZWQsXG4gIH0pXG4gIGlmIChlbmFibGUpIHtcbiAgICBzZXRBcHBTdGF0ZShwcmV2ID0+IHtcbiAgICAgIC8vIE9ubHkgc3dpdGNoIG1vZGVsIGlmIGN1cnJlbnQgbW9kZWwgZG9lc24ndCBzdXBwb3J0IGZhc3QgbW9kZVxuICAgICAgY29uc3QgbmVlZHNNb2RlbFN3aXRjaCA9ICFpc0Zhc3RNb2RlU3VwcG9
|