@franzzemen/brokenstock-shell 0.9.0 → 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -3010,8 +3010,64 @@ const HELP_USAGE = 'help [command]\n\n' +
|
|
|
3010
3010
|
' Arguments:\n' +
|
|
3011
3011
|
' [command] Optional command name to show detailed help for';
|
|
3012
3012
|
|
|
3013
|
+
/*
|
|
3014
|
+
Created by Franz Zemen 2026-10-18
|
|
3015
|
+
License Type: UNLICENSED
|
|
3016
|
+
|
|
3017
|
+
A question a command leaves open in the terminal (live-trading-foundation.prd.md D24).
|
|
3018
|
+
|
|
3019
|
+
A command can ask instead of acting: "Send SIM · Buy 100 NVDA? (Enter or yes to send, Esc to
|
|
3020
|
+
cancel)". The next line typed — including a bare Enter — is the answer and goes to the command,
|
|
3021
|
+
not to the command parser. Esc cancels. The arming code is asked the same way, with the input
|
|
3022
|
+
masked so the code never appears on screen or in the terminal's history.
|
|
3023
|
+
|
|
3024
|
+
Plain logic, no Angular: `CommandService` holds one of these and the terminal reads it.
|
|
3025
|
+
*/
|
|
3026
|
+
/** True for the answers that mean yes: a bare Enter, `y`, `yes`. */
|
|
3027
|
+
function isYes(text) {
|
|
3028
|
+
const t = text.trim().toLowerCase();
|
|
3029
|
+
return t === '' || t === 'y' || t === 'yes';
|
|
3030
|
+
}
|
|
3031
|
+
/** What the history shows for an answer: the text, a masked run, or "(Enter)". */
|
|
3032
|
+
function answerEcho(prompt, text) {
|
|
3033
|
+
if (text === '')
|
|
3034
|
+
return '(Enter)';
|
|
3035
|
+
return prompt.masked ? '•'.repeat(text.length) : text;
|
|
3036
|
+
}
|
|
3037
|
+
/** Holds at most one open question. Asking again cancels the one before it. */
|
|
3038
|
+
class PendingPromptState {
|
|
3039
|
+
#current = null;
|
|
3040
|
+
get current() {
|
|
3041
|
+
return this.#current;
|
|
3042
|
+
}
|
|
3043
|
+
ask(prompt) {
|
|
3044
|
+
const before = this.#current;
|
|
3045
|
+
this.#current = prompt;
|
|
3046
|
+
if (before && before !== prompt)
|
|
3047
|
+
before.cancel?.();
|
|
3048
|
+
}
|
|
3049
|
+
/**
|
|
3050
|
+
* Takes the open question and closes it, so an answer that asks again opens a fresh one rather
|
|
3051
|
+
* than being closed afterwards.
|
|
3052
|
+
*/
|
|
3053
|
+
take() {
|
|
3054
|
+
const p = this.#current;
|
|
3055
|
+
this.#current = null;
|
|
3056
|
+
return p;
|
|
3057
|
+
}
|
|
3058
|
+
cancel() {
|
|
3059
|
+
const p = this.#current;
|
|
3060
|
+
if (!p)
|
|
3061
|
+
return false;
|
|
3062
|
+
this.#current = null;
|
|
3063
|
+
p.cancel?.();
|
|
3064
|
+
return true;
|
|
3065
|
+
}
|
|
3066
|
+
}
|
|
3067
|
+
|
|
3013
3068
|
const CommandInputSchema = z.string().trim().min(1, 'Command cannot be empty');
|
|
3014
3069
|
class CommandService {
|
|
3070
|
+
#prompts;
|
|
3015
3071
|
constructor() {
|
|
3016
3072
|
this.history = signal([], /* @ts-ignore */
|
|
3017
3073
|
...(ngDevMode ? [{ debugName: "history" }] : /* istanbul ignore next */ []));
|
|
@@ -3021,6 +3077,13 @@ class CommandService {
|
|
|
3021
3077
|
...(ngDevMode ? [{ debugName: "isProcessing" }] : /* istanbul ignore next */ []));
|
|
3022
3078
|
this.helpOverlay = signal(null, /* @ts-ignore */
|
|
3023
3079
|
...(ngDevMode ? [{ debugName: "helpOverlay" }] : /* istanbul ignore next */ []));
|
|
3080
|
+
/**
|
|
3081
|
+
* The question a command left open, or null (live-trading-foundation.prd.md D24). While set, the
|
|
3082
|
+
* next line — a bare Enter included — is its answer, not a command; Esc cancels.
|
|
3083
|
+
*/
|
|
3084
|
+
this.pending = signal(null, /* @ts-ignore */
|
|
3085
|
+
...(ngDevMode ? [{ debugName: "pending" }] : /* istanbul ignore next */ []));
|
|
3086
|
+
this.#prompts = new PendingPromptState();
|
|
3024
3087
|
this.authService = inject(AuthenticationService);
|
|
3025
3088
|
this.registry = inject(CommandRegistryService);
|
|
3026
3089
|
this.router = inject(Router);
|
|
@@ -3032,12 +3095,68 @@ class CommandService {
|
|
|
3032
3095
|
effect(() => {
|
|
3033
3096
|
if (!this.authService.authenticated()) {
|
|
3034
3097
|
this.history.set([]);
|
|
3098
|
+
// A question asked for a session that has ended must not be answerable by the next one.
|
|
3099
|
+
this.#prompts.cancel();
|
|
3100
|
+
this.pending.set(null);
|
|
3035
3101
|
}
|
|
3036
3102
|
});
|
|
3037
3103
|
}
|
|
3038
3104
|
dismissHelp() {
|
|
3039
3105
|
this.helpOverlay.set(null);
|
|
3040
3106
|
}
|
|
3107
|
+
/** Leaves a question open; the next line typed answers it. A question already open is cancelled. */
|
|
3108
|
+
ask(prompt) {
|
|
3109
|
+
this.#prompts.ask(prompt);
|
|
3110
|
+
this.pending.set(prompt);
|
|
3111
|
+
this.history.update(h => [...h, {
|
|
3112
|
+
input: '',
|
|
3113
|
+
result: { success: true, message: prompt.question, timestamp: new Date(), severity: 'info' },
|
|
3114
|
+
}]);
|
|
3115
|
+
}
|
|
3116
|
+
/** Esc: closes the open question, if any. True when there was one. */
|
|
3117
|
+
cancelPending() {
|
|
3118
|
+
if (!this.#prompts.cancel())
|
|
3119
|
+
return false;
|
|
3120
|
+
this.pending.set(null);
|
|
3121
|
+
this.currentInput.set('');
|
|
3122
|
+
this.history.update(h => [...h, {
|
|
3123
|
+
input: '',
|
|
3124
|
+
result: { success: true, message: 'Cancelled — nothing was sent.', timestamp: new Date(), severity: 'info' },
|
|
3125
|
+
}]);
|
|
3126
|
+
return true;
|
|
3127
|
+
}
|
|
3128
|
+
#answer(rawInput) {
|
|
3129
|
+
const prompt = this.#prompts.take();
|
|
3130
|
+
if (!prompt)
|
|
3131
|
+
return;
|
|
3132
|
+
this.pending.set(null);
|
|
3133
|
+
const text = rawInput.trim();
|
|
3134
|
+
const echo = answerEcho(prompt, text);
|
|
3135
|
+
this.currentInput.set('');
|
|
3136
|
+
const record = (result) => {
|
|
3137
|
+
this.history.update(h => [...h, { input: echo, result }]);
|
|
3138
|
+
// An answer may ask again; show the new question after the answer's line.
|
|
3139
|
+
const next = this.#prompts.current;
|
|
3140
|
+
if (next && next !== this.pending())
|
|
3141
|
+
this.pending.set(next);
|
|
3142
|
+
};
|
|
3143
|
+
let out;
|
|
3144
|
+
try {
|
|
3145
|
+
out = prompt.answer(text);
|
|
3146
|
+
}
|
|
3147
|
+
catch (err) {
|
|
3148
|
+
out = { success: false, message: err?.message ?? String(err), timestamp: new Date() };
|
|
3149
|
+
}
|
|
3150
|
+
if (out instanceof Promise) {
|
|
3151
|
+
this.isProcessing.set(true);
|
|
3152
|
+
out
|
|
3153
|
+
.then(record, err => record({ success: false, message: err?.message ?? String(err), timestamp: new Date() }))
|
|
3154
|
+
.finally(() => this.isProcessing.set(false));
|
|
3155
|
+
}
|
|
3156
|
+
else {
|
|
3157
|
+
record(out);
|
|
3158
|
+
}
|
|
3159
|
+
}
|
|
3041
3160
|
echoCommand(input) {
|
|
3042
3161
|
if (this.#coalesce(input))
|
|
3043
3162
|
return;
|
|
@@ -3059,6 +3178,11 @@ class CommandService {
|
|
|
3059
3178
|
}]);
|
|
3060
3179
|
}
|
|
3061
3180
|
execute(rawInput) {
|
|
3181
|
+
// An open question takes the line, a bare Enter included (D24).
|
|
3182
|
+
if (this.#prompts.current) {
|
|
3183
|
+
this.#answer(rawInput);
|
|
3184
|
+
return;
|
|
3185
|
+
}
|
|
3062
3186
|
const validation = CommandInputSchema.safeParse(rawInput);
|
|
3063
3187
|
if (!validation.success) {
|
|
3064
3188
|
this.history.update(h => [...h, {
|
|
@@ -3480,6 +3604,8 @@ class CommandTerminal {
|
|
|
3480
3604
|
...(ngDevMode ? [{ debugName: "history" }] : /* istanbul ignore next */ []));
|
|
3481
3605
|
this.currentInput = this.commandService.currentInput;
|
|
3482
3606
|
this.isProcessing = this.commandService.isProcessing;
|
|
3607
|
+
/** The question a command left open (D24): the input answers it; Esc cancels. */
|
|
3608
|
+
this.pending = this.commandService.pending;
|
|
3483
3609
|
this.inputEl = viewChild('terminalInput', /* @ts-ignore */
|
|
3484
3610
|
...(ngDevMode ? [{ debugName: "inputEl" }] : /* istanbul ignore next */ []));
|
|
3485
3611
|
this.tabCycleIndex = -1;
|
|
@@ -3524,7 +3650,8 @@ class CommandTerminal {
|
|
|
3524
3650
|
}
|
|
3525
3651
|
onSubmit() {
|
|
3526
3652
|
const input = this.currentInput();
|
|
3527
|
-
|
|
3653
|
+
// With a question open, a bare Enter is an answer.
|
|
3654
|
+
if (!input.trim() && !this.pending())
|
|
3528
3655
|
return;
|
|
3529
3656
|
this.commandService.execute(input);
|
|
3530
3657
|
this.tabCycleIndex = -1;
|
|
@@ -3542,6 +3669,11 @@ class CommandTerminal {
|
|
|
3542
3669
|
dismissHelp() {
|
|
3543
3670
|
this.commandService.dismissHelp();
|
|
3544
3671
|
}
|
|
3672
|
+
/** Esc: cancels an open question first, otherwise closes the help overlay. */
|
|
3673
|
+
onEscape() {
|
|
3674
|
+
if (!this.commandService.cancelPending())
|
|
3675
|
+
this.dismissHelp();
|
|
3676
|
+
}
|
|
3545
3677
|
onTab(event) {
|
|
3546
3678
|
event.preventDefault();
|
|
3547
3679
|
const input = this.currentInput().trim();
|
|
@@ -3591,11 +3723,11 @@ class CommandTerminal {
|
|
|
3591
3723
|
this.inputEl()?.nativeElement.focus();
|
|
3592
3724
|
}
|
|
3593
3725
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: CommandTerminal, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
3594
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.2", type: CommandTerminal, isStandalone: true, selector: "shell-command-terminal", inputs: { focusOnAppear: { classPropertyName: "focusOnAppear", publicName: "focusOnAppear", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "inputEl", first: true, predicate: ["terminalInput"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"terminal\">\n <div class=\"terminal-input-row\">\n <span class=\"prompt\">$</span>\n <div class=\"input-wrapper\">\n @if (ghostText()) {\n <input\n class=\"ghost-input\"\n type=\"text\"\n [value]=\"ghostText()\"\n disabled\n tabindex=\"-1\"\n aria-hidden=\"true\"\n />\n }\n <input\n #terminalInput\n class=\"terminal-input\"\n type=\"text\"\n [ngModel]=\"currentInput()\"\n (ngModelChange)=\"onInputChange($event)\"\n (keydown.enter)=\"onSubmit()\"\n (keydown.tab)=\"onTab($any($event))\"\n (keydown.escape)=\"
|
|
3726
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.2", type: CommandTerminal, isStandalone: true, selector: "shell-command-terminal", inputs: { focusOnAppear: { classPropertyName: "focusOnAppear", publicName: "focusOnAppear", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "inputEl", first: true, predicate: ["terminalInput"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"terminal\">\n <div class=\"terminal-input-row\">\n <span class=\"prompt\">$</span>\n <div class=\"input-wrapper\">\n @if (ghostText() && !pending()) {\n <input\n class=\"ghost-input\"\n type=\"text\"\n [value]=\"ghostText()\"\n disabled\n tabindex=\"-1\"\n aria-hidden=\"true\"\n />\n }\n <input\n #terminalInput\n class=\"terminal-input\"\n [type]=\"pending()?.masked ? 'password' : 'text'\"\n [class.answering]=\"!!pending()\"\n [ngModel]=\"currentInput()\"\n (ngModelChange)=\"onInputChange($event)\"\n (keydown.enter)=\"onSubmit()\"\n (keydown.tab)=\"onTab($any($event))\"\n (keydown.escape)=\"onEscape()\"\n [placeholder]=\"pending()?.question ?? 'Type a command...'\"\n [attr.autocomplete]=\"pending()?.masked ? 'one-time-code' : 'off'\"\n [disabled]=\"isProcessing()\"\n spellcheck=\"false\"\n />\n </div>\n </div>\n <div class=\"terminal-output\">\n @for (entry of history(); track entry.result.timestamp) {\n @if (entry.input) {\n <div class=\"terminal-line\">\n <span class=\"prompt\">$</span>\n <span class=\"command-text\">{{ entry.input }}@if ((entry.repeatCount ?? 1) > 1) { <span class=\"repeat-count\">(\u00D7{{ entry.repeatCount }})</span>}</span>\n </div>\n }\n @if (entry.result.message) {\n <div class=\"terminal-line\" [class]=\"getSeverityClass(entry.result)\">{{ entry.result.message }}</div>\n }\n }\n </div>\n</div>\n", styles: [".terminal{display:flex;flex-direction:column;height:100%;background-color:var(--color-terminal-bg);border-top:1px solid var(--color-surface-border);font-family:Roboto Mono,Courier New,monospace;font-size:.85rem}.terminal-output{flex:1;overflow-y:auto;padding:8px 12px;display:flex;flex-direction:column}.terminal-line{line-height:1.6;color:var(--color-text-primary);white-space:pre-wrap}.terminal-line.error{color:var(--color-loss)}.terminal-line.warning{color:var(--color-warning)}.terminal-line.info{color:var(--color-info)}.prompt{color:var(--color-terminal-prompt);margin-right:8px;font-weight:700}.command-text{color:var(--color-terminal-text)}.repeat-count{color:var(--color-secondary-info);opacity:.6;margin-left:4px}.terminal-input-row{display:flex;align-items:center;padding:8px 12px;border-bottom:1px solid var(--color-surface-border)}.input-wrapper{flex:1;display:grid}.ghost-input,.terminal-input{grid-area:1 / 1;font-family:inherit;font-size:inherit;line-height:normal;margin:0;padding:0;border:none;background:transparent;outline:none;-webkit-appearance:none;appearance:none;width:100%}.ghost-input{color:var(--color-secondary-info);opacity:.3;pointer-events:none}.terminal-input{color:var(--color-terminal-text);caret-color:var(--color-terminal-prompt)}.terminal-input::placeholder{color:var(--color-secondary-info);opacity:.5}.terminal-input.answering::placeholder{color:var(--color-neutral);opacity:1}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$2.DefaultValueAccessor, selector: "input:not([type=checkbox]):not([ngNoCva])[formControlName],textarea:not([ngNoCva])[formControlName],input:not([type=checkbox]):not([ngNoCva])[formControl],textarea:not([ngNoCva])[formControl],input:not([type=checkbox]):not([ngNoCva])[ngModel],textarea:not([ngNoCva])[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1$2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], changeDetection: i0.ChangeDetectionStrategy.Eager }); }
|
|
3595
3727
|
}
|
|
3596
3728
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImport: i0, type: CommandTerminal, decorators: [{
|
|
3597
3729
|
type: Component,
|
|
3598
|
-
args: [{ selector: 'shell-command-terminal', imports: [FormsModule], changeDetection: ChangeDetectionStrategy.Eager, template: "<div class=\"terminal\">\n <div class=\"terminal-input-row\">\n <span class=\"prompt\">$</span>\n <div class=\"input-wrapper\">\n @if (ghostText()) {\n <input\n class=\"ghost-input\"\n type=\"text\"\n [value]=\"ghostText()\"\n disabled\n tabindex=\"-1\"\n aria-hidden=\"true\"\n />\n }\n <input\n #terminalInput\n class=\"terminal-input\"\n type=\"text\"\n [ngModel]=\"currentInput()\"\n (ngModelChange)=\"onInputChange($event)\"\n (keydown.enter)=\"onSubmit()\"\n (keydown.tab)=\"onTab($any($event))\"\n (keydown.escape)=\"
|
|
3730
|
+
args: [{ selector: 'shell-command-terminal', imports: [FormsModule], changeDetection: ChangeDetectionStrategy.Eager, template: "<div class=\"terminal\">\n <div class=\"terminal-input-row\">\n <span class=\"prompt\">$</span>\n <div class=\"input-wrapper\">\n @if (ghostText() && !pending()) {\n <input\n class=\"ghost-input\"\n type=\"text\"\n [value]=\"ghostText()\"\n disabled\n tabindex=\"-1\"\n aria-hidden=\"true\"\n />\n }\n <input\n #terminalInput\n class=\"terminal-input\"\n [type]=\"pending()?.masked ? 'password' : 'text'\"\n [class.answering]=\"!!pending()\"\n [ngModel]=\"currentInput()\"\n (ngModelChange)=\"onInputChange($event)\"\n (keydown.enter)=\"onSubmit()\"\n (keydown.tab)=\"onTab($any($event))\"\n (keydown.escape)=\"onEscape()\"\n [placeholder]=\"pending()?.question ?? 'Type a command...'\"\n [attr.autocomplete]=\"pending()?.masked ? 'one-time-code' : 'off'\"\n [disabled]=\"isProcessing()\"\n spellcheck=\"false\"\n />\n </div>\n </div>\n <div class=\"terminal-output\">\n @for (entry of history(); track entry.result.timestamp) {\n @if (entry.input) {\n <div class=\"terminal-line\">\n <span class=\"prompt\">$</span>\n <span class=\"command-text\">{{ entry.input }}@if ((entry.repeatCount ?? 1) > 1) { <span class=\"repeat-count\">(\u00D7{{ entry.repeatCount }})</span>}</span>\n </div>\n }\n @if (entry.result.message) {\n <div class=\"terminal-line\" [class]=\"getSeverityClass(entry.result)\">{{ entry.result.message }}</div>\n }\n }\n </div>\n</div>\n", styles: [".terminal{display:flex;flex-direction:column;height:100%;background-color:var(--color-terminal-bg);border-top:1px solid var(--color-surface-border);font-family:Roboto Mono,Courier New,monospace;font-size:.85rem}.terminal-output{flex:1;overflow-y:auto;padding:8px 12px;display:flex;flex-direction:column}.terminal-line{line-height:1.6;color:var(--color-text-primary);white-space:pre-wrap}.terminal-line.error{color:var(--color-loss)}.terminal-line.warning{color:var(--color-warning)}.terminal-line.info{color:var(--color-info)}.prompt{color:var(--color-terminal-prompt);margin-right:8px;font-weight:700}.command-text{color:var(--color-terminal-text)}.repeat-count{color:var(--color-secondary-info);opacity:.6;margin-left:4px}.terminal-input-row{display:flex;align-items:center;padding:8px 12px;border-bottom:1px solid var(--color-surface-border)}.input-wrapper{flex:1;display:grid}.ghost-input,.terminal-input{grid-area:1 / 1;font-family:inherit;font-size:inherit;line-height:normal;margin:0;padding:0;border:none;background:transparent;outline:none;-webkit-appearance:none;appearance:none;width:100%}.ghost-input{color:var(--color-secondary-info);opacity:.3;pointer-events:none}.terminal-input{color:var(--color-terminal-text);caret-color:var(--color-terminal-prompt)}.terminal-input::placeholder{color:var(--color-secondary-info);opacity:.5}.terminal-input.answering::placeholder{color:var(--color-neutral);opacity:1}\n"] }]
|
|
3599
3731
|
}], ctorParameters: () => [], propDecorators: { focusOnAppear: [{ type: i0.Input, args: [{ isSignal: true, alias: "focusOnAppear", required: false }] }], inputEl: [{ type: i0.ViewChild, args: ['terminalInput', { isSignal: true }] }] } });
|
|
3600
3732
|
|
|
3601
3733
|
const MIN_TERMINAL_HEIGHT = 80;
|
|
@@ -4324,5 +4456,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.2", ngImpor
|
|
|
4324
4456
|
* Generated bundle index. Do not edit.
|
|
4325
4457
|
*/
|
|
4326
4458
|
|
|
4327
|
-
export { AuthenticationService, AuthenticatorError, AuthenticatorSettings, CLEAR_USAGE, CODE_STEP, CodeDialog, CommandRegistryService, CommandService, CommandTerminal, ConfirmDialog, FAQ_CONTENT_LOADER, FAQ_DEV_EDITOR, FAQ_DEV_MODE, FAQ_DEV_WORKSPACE_ROOT, FAQ_PUBLIC_PUBLISHER, FAQ_PUBLIC_SITE_BASE_URL, FaqAuthoringPanel, FaqHistoryService, FaqMarkdownRendererService, FaqModal, FaqService, HELP_USAGE, HttpFaqContentLoader, KeyboardShortcutService, Login, MainContent, PhoneLayoutService, PublicFaqIndex, PublicFaqPage, PublicFaqToc, RecoveryCodes, RegexValidatorDirective, SESSION_TOKEN_KEY, SHELL_APP_NAME, SHELL_AUTH_URLS, SHELL_COMMANDS, SHELL_MENU_ITEMS, SHELL_PHONE_MEDIA_QUERY, SHELL_POST_LOGIN_ROUTE, SHELL_SHARED_SESSION, SessionTokenStore, Shell, SideMenu, StatusBar, TOO_MANY_ATTEMPTS, TerminalFocusService, TerminalVisibilityService, ThemeService, ThinkingService, audienceAllowed, authGuard, authInterceptor, authenticatorMessage, buildFallbackChain, buildLoginBody, decideRenewal, guestGuard, matchesRoute, openCodeDialog, provideShellConfig, recoveryCodesFile, tokenize };
|
|
4459
|
+
export { AuthenticationService, AuthenticatorError, AuthenticatorSettings, CLEAR_USAGE, CODE_STEP, CodeDialog, CommandRegistryService, CommandService, CommandTerminal, ConfirmDialog, FAQ_CONTENT_LOADER, FAQ_DEV_EDITOR, FAQ_DEV_MODE, FAQ_DEV_WORKSPACE_ROOT, FAQ_PUBLIC_PUBLISHER, FAQ_PUBLIC_SITE_BASE_URL, FaqAuthoringPanel, FaqHistoryService, FaqMarkdownRendererService, FaqModal, FaqService, HELP_USAGE, HttpFaqContentLoader, KeyboardShortcutService, Login, MainContent, PendingPromptState, PhoneLayoutService, PublicFaqIndex, PublicFaqPage, PublicFaqToc, RecoveryCodes, RegexValidatorDirective, SESSION_TOKEN_KEY, SHELL_APP_NAME, SHELL_AUTH_URLS, SHELL_COMMANDS, SHELL_MENU_ITEMS, SHELL_PHONE_MEDIA_QUERY, SHELL_POST_LOGIN_ROUTE, SHELL_SHARED_SESSION, SessionTokenStore, Shell, SideMenu, StatusBar, TOO_MANY_ATTEMPTS, TerminalFocusService, TerminalVisibilityService, ThemeService, ThinkingService, answerEcho, audienceAllowed, authGuard, authInterceptor, authenticatorMessage, buildFallbackChain, buildLoginBody, decideRenewal, guestGuard, isYes, matchesRoute, openCodeDialog, provideShellConfig, recoveryCodesFile, tokenize };
|
|
4328
4460
|
//# sourceMappingURL=franzzemen-brokenstock-shell.mjs.map
|