@nac3/forge-cli 0.2.0-alpha.1 → 0.2.0-alpha.11

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.
Files changed (74) hide show
  1. package/dist/bin/yf.d.ts.map +1 -1
  2. package/dist/bin/yf.js +9 -0
  3. package/dist/bin/yf.js.map +1 -1
  4. package/dist/chat/claude.d.ts +12 -15
  5. package/dist/chat/claude.d.ts.map +1 -1
  6. package/dist/chat/claude.js +60 -20
  7. package/dist/chat/claude.js.map +1 -1
  8. package/dist/chat/panel.d.ts.map +1 -1
  9. package/dist/chat/panel.js +90 -3
  10. package/dist/chat/panel.js.map +1 -1
  11. package/dist/chat/server.js +451 -32
  12. package/dist/chat/server.js.map +1 -1
  13. package/dist/chat/tools/audit_consumers.d.ts +66 -0
  14. package/dist/chat/tools/audit_consumers.d.ts.map +1 -0
  15. package/dist/chat/tools/audit_consumers.js +231 -0
  16. package/dist/chat/tools/audit_consumers.js.map +1 -0
  17. package/dist/chat/tools/git.js +4 -4
  18. package/dist/chat/tools/github.js +3 -3
  19. package/dist/chat/tools/lifecycle.js +3 -3
  20. package/dist/chat/tools/manual.js +1 -1
  21. package/dist/chat/tools/reader.js +8 -8
  22. package/dist/chat/tools.d.ts.map +1 -1
  23. package/dist/chat/tools.js +11 -4
  24. package/dist/chat/tools.js.map +1 -1
  25. package/dist/commands/chat.d.ts +3 -0
  26. package/dist/commands/chat.d.ts.map +1 -1
  27. package/dist/commands/chat.js +46 -1
  28. package/dist/commands/chat.js.map +1 -1
  29. package/dist/commands/discover.d.ts +30 -0
  30. package/dist/commands/discover.d.ts.map +1 -0
  31. package/dist/commands/discover.js +178 -0
  32. package/dist/commands/discover.js.map +1 -0
  33. package/dist/commands/doctor.js +94 -42
  34. package/dist/commands/doctor.js.map +1 -1
  35. package/dist/commands/keys_setup.d.ts +53 -0
  36. package/dist/commands/keys_setup.d.ts.map +1 -0
  37. package/dist/commands/keys_setup.js +487 -0
  38. package/dist/commands/keys_setup.js.map +1 -0
  39. package/dist/commands/triage.d.ts +34 -0
  40. package/dist/commands/triage.d.ts.map +1 -0
  41. package/dist/commands/triage.js +228 -0
  42. package/dist/commands/triage.js.map +1 -0
  43. package/dist/commands/voice.d.ts.map +1 -1
  44. package/dist/commands/voice.js +3 -0
  45. package/dist/commands/voice.js.map +1 -1
  46. package/dist/commands/voice_setup.d.ts +37 -0
  47. package/dist/commands/voice_setup.d.ts.map +1 -0
  48. package/dist/commands/voice_setup.js +308 -0
  49. package/dist/commands/voice_setup.js.map +1 -0
  50. package/dist/core/keys_envelope.d.ts +54 -0
  51. package/dist/core/keys_envelope.d.ts.map +1 -0
  52. package/dist/core/keys_envelope.js +135 -0
  53. package/dist/core/keys_envelope.js.map +1 -0
  54. package/dist/license/hito4_client.d.ts +17 -1
  55. package/dist/license/hito4_client.d.ts.map +1 -1
  56. package/dist/license/hito4_client.js +71 -10
  57. package/dist/license/hito4_client.js.map +1 -1
  58. package/dist/license/index.d.ts.map +1 -1
  59. package/dist/license/index.js +7 -0
  60. package/dist/license/index.js.map +1 -1
  61. package/dist/version.d.ts +1 -1
  62. package/dist/version.d.ts.map +1 -1
  63. package/dist/version.js +1 -1
  64. package/dist/version.js.map +1 -1
  65. package/dist/voice/intents.d.ts +1 -1
  66. package/dist/voice/intents.js +0 -0
  67. package/dist/voice/providers/google.d.ts.map +1 -1
  68. package/dist/voice/providers/google.js +129 -23
  69. package/dist/voice/providers/google.js.map +1 -1
  70. package/dist/workflow/state.d.ts +190 -0
  71. package/dist/workflow/state.d.ts.map +1 -0
  72. package/dist/workflow/state.js +119 -0
  73. package/dist/workflow/state.js.map +1 -0
  74. package/package.json +3 -3
@@ -0,0 +1,228 @@
1
+ /**
2
+ * `yf triage` -- Phase I step 1 of PRODUCT_WORKFLOW.md.
3
+ *
4
+ * Asks the user 5 questions, classifies the project into one of
5
+ * three complexity tiers (Simple / Medium / Full), and persists
6
+ * the decision to yujin.forge.json::workflow. The result drives
7
+ * which subsequent phases apply (see PRODUCT_WORKFLOW.md sec 1).
8
+ *
9
+ * Questions:
10
+ * 1. Output type (landing / blog / CRUD app / SaaS / regulated system)
11
+ * 2. Volumetria 12m (numeric: expected concurrent users at 12 months)
12
+ * 3. Industry context (general / health / finance / education / government)
13
+ * 4. Region (LATAM / US / EU / global)
14
+ * 5. Team maintaining (solo / pair / team)
15
+ *
16
+ * Classification rules:
17
+ * Simple = output in {landing, blog, demo} OR volumetria < 50 AND
18
+ * industry = general AND team = solo
19
+ * Full = industry in {health, finance, government} OR volumetria > 5000
20
+ * OR output = regulated_system OR (region = EU AND volumetria > 100)
21
+ * Medium = everything else
22
+ *
23
+ * User can override the auto-tier in the final confirmation.
24
+ *
25
+ * ASCII-only.
26
+ */
27
+ import path from 'node:path';
28
+ import prompts from 'prompts';
29
+ import { c, header } from '../ui/colors.js';
30
+ import { writeWorkflow, readWorkflow, } from '../workflow/state.js';
31
+ function classify(a) {
32
+ const simpleOutputs = ['landing', 'blog'];
33
+ const regulated = ['health', 'finance', 'government'];
34
+ if (simpleOutputs.includes(a.output)
35
+ || (a.volumetria < 50 && a.industry === 'general' && a.team === 'solo')) {
36
+ return {
37
+ tier: 'simple',
38
+ reason: a.output === 'landing' ? 'landing page'
39
+ : a.output === 'blog' ? 'blog'
40
+ : 'small single-user project (< 50 users / 12m, general industry, solo team)',
41
+ };
42
+ }
43
+ if (regulated.includes(a.industry)
44
+ || a.volumetria > 5000
45
+ || a.output === 'regulated'
46
+ || (a.region === 'eu' && a.volumetria > 100)) {
47
+ const reasons = [];
48
+ if (regulated.includes(a.industry))
49
+ reasons.push('regulated industry (' + a.industry + ')');
50
+ if (a.volumetria > 5000)
51
+ reasons.push('volumetria > 5000');
52
+ if (a.output === 'regulated')
53
+ reasons.push('output = regulated system');
54
+ if (a.region === 'eu' && a.volumetria > 100)
55
+ reasons.push('EU + > 100 users (GDPR compliance)');
56
+ return {
57
+ tier: 'full',
58
+ reason: reasons.join(' + '),
59
+ };
60
+ }
61
+ return {
62
+ tier: 'medium',
63
+ reason: 'CRUD/SaaS app with moderate volumetria, non-regulated industry',
64
+ };
65
+ }
66
+ function describeAlcance(tier) {
67
+ switch (tier) {
68
+ case 'simple':
69
+ return [
70
+ ' Phase I (intake) -> Phase II step 9 (blocks) -> Phase V (build) -> Phase VI (ship)',
71
+ ' Skips: full clarification rounds, RFP+arch+design docs, approval gate',
72
+ ].join('\n');
73
+ case 'medium':
74
+ return [
75
+ ' Phase I + Phase II + Phase III (compact) + Phase IV gate + Phase V + Phase VI',
76
+ ' Light RFP+arch+design; explicit approval before build starts',
77
+ ].join('\n');
78
+ case 'full':
79
+ return [
80
+ ' ALL 18 steps, all 4 NFR rounds, full RFP+arch+design,',
81
+ ' hard approval gate, NAC-3 compliance auditing per block',
82
+ ].join('\n');
83
+ }
84
+ }
85
+ export async function runTriage(opts) {
86
+ header('Yujin Forge -- triage');
87
+ console.log('');
88
+ const projectRoot = opts.cwd ? path.resolve(opts.cwd) : process.cwd();
89
+ const existing = await readWorkflow(projectRoot);
90
+ if (existing.tier && !opts.yes) {
91
+ console.log(c.dim('Triage previo: ') + c.brand(existing.tier)
92
+ + c.dim(' (' + (existing.tier_reason ?? 'no reason') + ')'));
93
+ console.log(c.dim('Para volver a clasificar, corre `yf triage --yes`.'));
94
+ return;
95
+ }
96
+ console.log(c.dim('5 preguntas para clasificar la complejidad del proyecto.'));
97
+ console.log(c.dim('La clasificacion determina que fases del workflow se aplican.'));
98
+ console.log('');
99
+ const answers = await prompts([
100
+ {
101
+ type: 'select',
102
+ name: 'output',
103
+ message: 'Tipo de output:',
104
+ choices: [
105
+ { title: 'Landing page', value: 'landing' },
106
+ { title: 'Blog / sitio de contenido', value: 'blog' },
107
+ { title: 'App CRUD con auth (multi-user)', value: 'crud' },
108
+ { title: 'SaaS multi-tenant', value: 'saas' },
109
+ { title: 'Sistema regulado / compliance critica', value: 'regulated' },
110
+ ],
111
+ },
112
+ {
113
+ type: 'number',
114
+ name: 'volumetria',
115
+ message: 'Usuarios concurrentes esperados a 12 meses (entero):',
116
+ initial: 100,
117
+ min: 0,
118
+ },
119
+ {
120
+ type: 'select',
121
+ name: 'industry',
122
+ message: 'Industria:',
123
+ choices: [
124
+ { title: 'General', value: 'general' },
125
+ { title: 'Salud (HIPAA / privacidad medica)', value: 'health' },
126
+ { title: 'Finanzas (PCI / regulacion bancaria)', value: 'finance' },
127
+ { title: 'Educacion', value: 'education' },
128
+ { title: 'Gobierno / sector publico', value: 'government' },
129
+ ],
130
+ },
131
+ {
132
+ type: 'select',
133
+ name: 'region',
134
+ message: 'Region de usuarios:',
135
+ choices: [
136
+ { title: 'LATAM', value: 'latam' },
137
+ { title: 'US', value: 'us' },
138
+ { title: 'EU (aplican GDPR)', value: 'eu' },
139
+ { title: 'Global', value: 'global' },
140
+ ],
141
+ },
142
+ {
143
+ type: 'select',
144
+ name: 'team',
145
+ message: 'Equipo que mantiene:',
146
+ choices: [
147
+ { title: 'Solo (vos)', value: 'solo' },
148
+ { title: 'En pareja (2)', value: 'pair' },
149
+ { title: 'Equipo (3 o mas)', value: 'team' },
150
+ ],
151
+ },
152
+ ]);
153
+ if (!answers.output || answers.volumetria === undefined || !answers.industry
154
+ || !answers.region || !answers.team) {
155
+ console.log(c.warn('Triage abortado (faltan respuestas).'));
156
+ return;
157
+ }
158
+ const { tier, reason } = classify(answers);
159
+ console.log('');
160
+ console.log(c.brand('Tier propuesto: ') + c.brand(tier.toUpperCase()));
161
+ console.log(c.dim(' Razon: ') + reason);
162
+ console.log('');
163
+ console.log(c.brand('Alcance del workflow para este tier:'));
164
+ console.log(describeAlcance(tier));
165
+ console.log('');
166
+ const confirm = await prompts({
167
+ type: 'select',
168
+ name: 'choice',
169
+ message: 'Confirmar tier?',
170
+ choices: [
171
+ { title: 'Confirmar ' + tier, value: 'confirm' },
172
+ { title: 'Override a SIMPLE (forzar workflow minimo)', value: 'simple' },
173
+ { title: 'Override a MEDIUM', value: 'medium' },
174
+ { title: 'Override a FULL (forzar workflow completo)', value: 'full' },
175
+ { title: 'Cancelar', value: 'cancel' },
176
+ ],
177
+ });
178
+ let finalTier;
179
+ let finalReason;
180
+ switch (confirm.choice) {
181
+ case 'confirm':
182
+ finalTier = tier;
183
+ finalReason = reason;
184
+ break;
185
+ case 'simple':
186
+ finalTier = 'simple';
187
+ finalReason = 'user override after auto: ' + tier;
188
+ break;
189
+ case 'medium':
190
+ finalTier = 'medium';
191
+ finalReason = 'user override after auto: ' + tier;
192
+ break;
193
+ case 'full':
194
+ finalTier = 'full';
195
+ finalReason = 'user override after auto: ' + tier;
196
+ break;
197
+ default:
198
+ console.log(c.warn('Triage cancelado.'));
199
+ return;
200
+ }
201
+ await writeWorkflow(projectRoot, {
202
+ tier: finalTier,
203
+ tier_reason: finalReason,
204
+ tier_decided_at: new Date().toISOString(),
205
+ });
206
+ console.log('');
207
+ console.log(c.success('Triage persistido. Tier: ' + c.brand(finalTier)));
208
+ console.log(c.dim(' Estado guardado en yujin.forge.json'));
209
+ console.log('');
210
+ console.log(c.dim('Siguiente paso: ') + c.code('yf discover'));
211
+ }
212
+ export function registerTriageCommand(program) {
213
+ program
214
+ .command('triage')
215
+ .description('Phase I step 1: classify project complexity (Simple / Medium / Full).')
216
+ .option('--cwd <path>', 'project root (default: current directory)')
217
+ .option('--yes', 'overwrite a prior triage decision without prompting')
218
+ .action(async (opts) => {
219
+ try {
220
+ await runTriage(opts);
221
+ }
222
+ catch (err) {
223
+ console.error(c.error(err instanceof Error ? err.message : String(err)));
224
+ process.exitCode = 1;
225
+ }
226
+ });
227
+ }
228
+ //# sourceMappingURL=triage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"triage.js","sourceRoot":"","sources":["../../src/commands/triage.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"voice.d.ts","sourceRoot":"","sources":["../../src/commands/voice.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQzC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAkE3D"}
1
+ {"version":3,"file":"voice.d.ts","sourceRoot":"","sources":["../../src/commands/voice.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AASzC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAqE3D"}
@@ -1,5 +1,6 @@
1
1
  import { readVoiceConfig, writeVoiceConfig, matchConfiguredWakeWord } from '../voice/config.js';
2
2
  import { DEFAULT_WAKE_ALIASES, mergeAliases } from '../voice/wake.js';
3
+ import { registerVoiceSetupCommand } from './keys_setup.js';
3
4
  function splitCsv(s) {
4
5
  return s.split(',').map((x) => x.trim()).filter((x) => x.length > 0);
5
6
  }
@@ -64,6 +65,8 @@ export function registerVoiceCommand(program) {
64
65
  if (!r.hit)
65
66
  process.exitCode = 1;
66
67
  });
68
+ /* `yf voice setup` -- BYOK provider keys + sync to mobile. */
69
+ registerVoiceSetupCommand(voice);
67
70
  void config;
68
71
  }
69
72
  //# sourceMappingURL=voice.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"voice.js","sourceRoot":"","sources":["../../src/commands/voice.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"voice.js","sourceRoot":"","sources":["../../src/commands/voice.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * `yf voice setup` -- interactive BYOK provider configuration.
3
+ *
4
+ * The user chooses one or more providers (OpenAI / Google /
5
+ * ElevenLabs), pastes the API keys, and this command:
6
+ *
7
+ * 1. Reads the current local provider keys from disk
8
+ * (~/.yujin-forge/provider_keys.json), if any.
9
+ * 2. Merges the new values on top.
10
+ * 3. Encrypts the merged payload with the SERVER_API_KEY
11
+ * from the vault (the same secret used for HMAC signing).
12
+ * 4. POSTs the encrypted blob to /v1/keys-sync/<handle> so
13
+ * the user's mobile + other paired devices pull it.
14
+ * 5. Writes the plaintext locally so subsequent voice calls
15
+ * can read it without re-prompting.
16
+ *
17
+ * Server never sees plaintext -- only the ciphertext blob.
18
+ *
19
+ * Subcommands:
20
+ * yf voice setup Interactive prompts.
21
+ * yf voice setup --show Print current local config (keys masked).
22
+ * yf voice setup --pull Pull the server copy + overwrite local.
23
+ * yf voice setup --provider openai --key sk-xxx
24
+ * Non-interactive single-provider set.
25
+ *
26
+ * ASCII-only.
27
+ */
28
+ import type { Command } from 'commander';
29
+ export interface VoiceSetupOptions {
30
+ show?: boolean;
31
+ pull?: boolean;
32
+ provider?: string;
33
+ key?: string;
34
+ }
35
+ export declare function registerVoiceSetupCommand(parent: Command): void;
36
+ export declare function runVoiceSetup(opts: VoiceSetupOptions): Promise<void>;
37
+ //# sourceMappingURL=voice_setup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"voice_setup.d.ts","sourceRoot":"","sources":["../../src/commands/voice_setup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA8HzC,MAAM,WAAW,iBAAiB;IAChC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAU/D;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAuK1E"}
@@ -0,0 +1,308 @@
1
+ import { promises as fs } from 'node:fs';
2
+ import path from 'node:path';
3
+ import os from 'node:os';
4
+ import prompts from 'prompts';
5
+ import { c, header } from '../ui/colors.js';
6
+ import { Vault } from '../vault/store.js';
7
+ import { configDir } from '../license/index.js';
8
+ import { readLicense } from '../core/polar.js';
9
+ import { signBearer, HITO4_BASE_URL } from '../license/hito4_client.js';
10
+ import { encryptUserKeys, decryptUserKeys, envelopeToBlob, envelopeFromBlob, } from '../core/keys_envelope.js';
11
+ const VAULT_SECRET_SLOT = 'yf_server_api_key';
12
+ const LOCAL_KEYS_FILE = 'provider_keys.json';
13
+ function localKeysPath() {
14
+ const home = process.env.HOME || process.env.USERPROFILE || os.homedir();
15
+ return path.join(home, '.yujin-forge', LOCAL_KEYS_FILE);
16
+ }
17
+ async function readLocalKeys() {
18
+ try {
19
+ const raw = await fs.readFile(localKeysPath(), 'utf-8');
20
+ const parsed = JSON.parse(raw);
21
+ if (parsed && parsed.v === 1)
22
+ return parsed;
23
+ }
24
+ catch { /* missing or malformed -- treat as empty */ }
25
+ return { v: 1, updated_at: '1970-01-01T00:00:00Z' };
26
+ }
27
+ async function writeLocalKeys(payload) {
28
+ const p = localKeysPath();
29
+ await fs.mkdir(path.dirname(p), { recursive: true });
30
+ const tmp = p + '.tmp';
31
+ await fs.writeFile(tmp, JSON.stringify(payload, null, 2), 'utf-8');
32
+ await fs.rename(tmp, p);
33
+ }
34
+ function maskKey(k) {
35
+ if (!k)
36
+ return '(none)';
37
+ if (k.length <= 8)
38
+ return '****';
39
+ return k.slice(0, 4) + '...' + k.slice(-4);
40
+ }
41
+ async function loadServerSecret() {
42
+ const vault = await Vault.open({ configDir: configDir() });
43
+ if (!vault.has(VAULT_SECRET_SLOT)) {
44
+ throw new Error('voice setup: vault slot "' + VAULT_SECRET_SLOT + '" is empty. '
45
+ + 'Run `yf vault set ' + VAULT_SECRET_SLOT + '` with the value '
46
+ + 'provided at signup (or your tenant admin) before configuring '
47
+ + 'voice providers.');
48
+ }
49
+ return vault.get(VAULT_SECRET_SLOT);
50
+ }
51
+ async function loadUserHandle() {
52
+ const lic = await readLicense();
53
+ if (!lic.user_handle) {
54
+ throw new Error('voice setup: no user_handle on the local license cache. '
55
+ + 'Run `yf license activate --user-handle <you@example.com>` first.');
56
+ }
57
+ return lic.user_handle;
58
+ }
59
+ async function pushToServer(payload) {
60
+ const secret = await loadServerSecret();
61
+ const handle = await loadUserHandle();
62
+ const env = await encryptUserKeys(payload, secret);
63
+ const blob = envelopeToBlob(env);
64
+ const bearer = signBearer(secret, handle);
65
+ const url = HITO4_BASE_URL.replace(/\/+$/, '') + '/v1/keys-sync/' + encodeURIComponent(handle);
66
+ const r = await fetch(url, {
67
+ method: 'POST',
68
+ headers: {
69
+ Authorization: 'Bearer ' + bearer,
70
+ 'content-type': 'application/json',
71
+ },
72
+ body: JSON.stringify({ blob, ts: payload.updated_at }),
73
+ });
74
+ if (!r.ok) {
75
+ let detail = '';
76
+ try {
77
+ detail = await r.text();
78
+ }
79
+ catch { /* */ }
80
+ throw new Error('voice setup: server push failed (HTTP ' + r.status + '): ' + detail.slice(0, 200));
81
+ }
82
+ }
83
+ async function pullFromServer() {
84
+ const secret = await loadServerSecret();
85
+ const handle = await loadUserHandle();
86
+ const bearer = signBearer(secret, handle);
87
+ const url = HITO4_BASE_URL.replace(/\/+$/, '') + '/v1/keys-sync/' + encodeURIComponent(handle);
88
+ const r = await fetch(url, {
89
+ method: 'GET',
90
+ headers: { Authorization: 'Bearer ' + bearer },
91
+ });
92
+ if (!r.ok) {
93
+ let detail = '';
94
+ try {
95
+ detail = await r.text();
96
+ }
97
+ catch { /* */ }
98
+ throw new Error('voice setup: server pull failed (HTTP ' + r.status + '): ' + detail.slice(0, 200));
99
+ }
100
+ const body = await r.json();
101
+ if (!body.blob)
102
+ return null;
103
+ const env = envelopeFromBlob(body.blob);
104
+ return decryptUserKeys(env, secret);
105
+ }
106
+ function printCurrent(p) {
107
+ header('Yujin Forge -- voice setup (current local)');
108
+ console.log('');
109
+ console.log(' OpenAI API key: ' + c.dim(maskKey(p.openai_api_key)));
110
+ console.log(' Google STT key: ' + c.dim(maskKey(p.google_stt_key)));
111
+ console.log(' Google TTS key: ' + c.dim(maskKey(p.google_tts_key)));
112
+ console.log(' ElevenLabs API key: ' + c.dim(maskKey(p.elevenlabs_api_key)));
113
+ console.log('');
114
+ console.log(' STT preference: ' + c.brand(p.stt_provider_preference ?? '(not set)'));
115
+ console.log(' TTS preference: ' + c.brand(p.tts_provider_preference ?? '(not set)'));
116
+ console.log(' STT language: ' + (p.stt_language ?? c.dim('(default)')));
117
+ console.log(' TTS voice: ' + (p.tts_voice ?? c.dim('(default)')));
118
+ console.log(' Last updated: ' + c.dim(p.updated_at));
119
+ }
120
+ export function registerVoiceSetupCommand(parent) {
121
+ parent
122
+ .command('setup')
123
+ .description('Configure voice provider API keys (OpenAI / Google / ElevenLabs). '
124
+ + 'Encrypts + syncs to your other devices automatically.')
125
+ .option('--show', 'print current local config (keys masked)')
126
+ .option('--pull', 'pull the server copy + overwrite local')
127
+ .option('--provider <name>', 'non-interactive: set this provider')
128
+ .option('--key <value>', 'non-interactive: the API key value for --provider')
129
+ .action(async (opts) => { await runVoiceSetup(opts); });
130
+ }
131
+ export async function runVoiceSetup(opts) {
132
+ /* --show: print current + exit. */
133
+ if (opts.show) {
134
+ const current = await readLocalKeys();
135
+ printCurrent(current);
136
+ return;
137
+ }
138
+ /* --pull: server -> local. */
139
+ if (opts.pull) {
140
+ let pulled;
141
+ try {
142
+ pulled = await pullFromServer();
143
+ }
144
+ catch (err) {
145
+ console.error(c.error(err instanceof Error ? err.message : String(err)));
146
+ process.exitCode = 1;
147
+ return;
148
+ }
149
+ if (!pulled) {
150
+ console.log(c.dim('Server has no provider keys for this user yet.'));
151
+ return;
152
+ }
153
+ await writeLocalKeys(pulled);
154
+ header('Yujin Forge -- voice setup (pulled from server)');
155
+ console.log('');
156
+ printCurrent(pulled);
157
+ return;
158
+ }
159
+ /* --provider / --key: non-interactive single set. */
160
+ if (opts.provider || opts.key) {
161
+ if (!opts.provider || !opts.key) {
162
+ console.error(c.error('--provider and --key must be used together.'));
163
+ process.exitCode = 1;
164
+ return;
165
+ }
166
+ const merged = await readLocalKeys();
167
+ const ts = new Date().toISOString();
168
+ const p = opts.provider.toLowerCase();
169
+ if (p === 'openai')
170
+ merged.openai_api_key = opts.key;
171
+ else if (p === 'google-stt')
172
+ merged.google_stt_key = opts.key;
173
+ else if (p === 'google-tts')
174
+ merged.google_tts_key = opts.key;
175
+ else if (p === 'elevenlabs')
176
+ merged.elevenlabs_api_key = opts.key;
177
+ else {
178
+ console.error(c.error('--provider must be one of: openai, google-stt, google-tts, elevenlabs'));
179
+ process.exitCode = 1;
180
+ return;
181
+ }
182
+ merged.updated_at = ts;
183
+ try {
184
+ await pushToServer(merged);
185
+ await writeLocalKeys(merged);
186
+ header('Yujin Forge -- voice setup (saved)');
187
+ console.log('');
188
+ printCurrent(merged);
189
+ }
190
+ catch (err) {
191
+ console.error(c.error(err instanceof Error ? err.message : String(err)));
192
+ process.exitCode = 1;
193
+ }
194
+ return;
195
+ }
196
+ /* Interactive flow. */
197
+ const current = await readLocalKeys();
198
+ header('Yujin Forge -- voice setup');
199
+ console.log('');
200
+ console.log(c.dim('Configure the API keys for your chosen voice providers. The keys are'));
201
+ console.log(c.dim('encrypted with your account secret + synced to your mobile + other'));
202
+ console.log(c.dim('paired devices automatically. The server never sees plaintext.'));
203
+ console.log('');
204
+ console.log(c.dim('Press Enter on any field to keep its current value.'));
205
+ console.log('');
206
+ const answers = await prompts([
207
+ {
208
+ type: 'multiselect',
209
+ name: 'providers',
210
+ message: 'Which providers do you want to configure?',
211
+ choices: [
212
+ { title: 'OpenAI (Whisper for STT + tts-1 for TTS)', value: 'openai' },
213
+ { title: 'Google Cloud (Speech-to-Text + Text-to-Speech)', value: 'google' },
214
+ { title: 'ElevenLabs (TTS only -- higher quality voice)', value: 'elevenlabs' },
215
+ ],
216
+ min: 1,
217
+ hint: 'Space to select, Enter to confirm.',
218
+ },
219
+ ]);
220
+ if (!answers.providers || answers.providers.length === 0) {
221
+ console.log(c.dim('No providers selected. Aborting.'));
222
+ return;
223
+ }
224
+ const merged = { ...current };
225
+ if (answers.providers.includes('openai')) {
226
+ const r = await prompts({
227
+ type: 'password',
228
+ name: 'k',
229
+ message: 'OpenAI API key (sk-...). Current: ' + maskKey(current.openai_api_key),
230
+ });
231
+ if (r.k)
232
+ merged.openai_api_key = r.k;
233
+ }
234
+ if (answers.providers.includes('google')) {
235
+ const sttR = await prompts({
236
+ type: 'password',
237
+ name: 'k',
238
+ message: 'Google Cloud Speech-to-Text API key. Current: ' + maskKey(current.google_stt_key),
239
+ });
240
+ if (sttR.k)
241
+ merged.google_stt_key = sttR.k;
242
+ const ttsR = await prompts({
243
+ type: 'password',
244
+ name: 'k',
245
+ message: 'Google Cloud Text-to-Speech API key (can be same as STT). Current: ' + maskKey(current.google_tts_key),
246
+ });
247
+ if (ttsR.k)
248
+ merged.google_tts_key = ttsR.k;
249
+ }
250
+ if (answers.providers.includes('elevenlabs')) {
251
+ const r = await prompts({
252
+ type: 'password',
253
+ name: 'k',
254
+ message: 'ElevenLabs API key. Current: ' + maskKey(current.elevenlabs_api_key),
255
+ });
256
+ if (r.k)
257
+ merged.elevenlabs_api_key = r.k;
258
+ }
259
+ /* Preferences (which provider to USE for each direction). */
260
+ const sttCandidates = [];
261
+ if (merged.openai_api_key)
262
+ sttCandidates.push({ title: 'OpenAI (Whisper)', value: 'openai' });
263
+ if (merged.google_stt_key)
264
+ sttCandidates.push({ title: 'Google', value: 'google' });
265
+ if (sttCandidates.length > 0) {
266
+ const pref = await prompts({
267
+ type: 'select',
268
+ name: 'p',
269
+ message: 'Preferred STT provider',
270
+ choices: sttCandidates,
271
+ initial: 0,
272
+ });
273
+ if (pref.p)
274
+ merged.stt_provider_preference = pref.p;
275
+ }
276
+ const ttsCandidates = [];
277
+ if (merged.openai_api_key)
278
+ ttsCandidates.push({ title: 'OpenAI (tts-1)', value: 'openai' });
279
+ if (merged.google_tts_key)
280
+ ttsCandidates.push({ title: 'Google', value: 'google' });
281
+ if (merged.elevenlabs_api_key)
282
+ ttsCandidates.push({ title: 'ElevenLabs', value: 'elevenlabs' });
283
+ if (ttsCandidates.length > 0) {
284
+ const pref = await prompts({
285
+ type: 'select',
286
+ name: 'p',
287
+ message: 'Preferred TTS provider',
288
+ choices: ttsCandidates,
289
+ initial: 0,
290
+ });
291
+ if (pref.p)
292
+ merged.tts_provider_preference = pref.p;
293
+ }
294
+ merged.updated_at = new Date().toISOString();
295
+ try {
296
+ await pushToServer(merged);
297
+ await writeLocalKeys(merged);
298
+ console.log('');
299
+ console.log(c.success('Voice config saved + synced.'));
300
+ console.log('');
301
+ printCurrent(merged);
302
+ }
303
+ catch (err) {
304
+ console.error(c.error(err instanceof Error ? err.message : String(err)));
305
+ process.exitCode = 1;
306
+ }
307
+ }
308
+ //# sourceMappingURL=voice_setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"voice_setup.js","sourceRoot":"","sources":["../../src/commands/voice_setup.ts"],"names":[],"mappings":"AA4BA,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AACxE,OAAO,EACL,eAAe,EAAE,eAAe,EAChC,cAAc,EAAE,gBAAgB,GAEjC,MAAM,0BAA0B,CAAC;AAElC,MAAM,iBAAiB,GAAG,mBAAmB,CAAC;AAC9C,MAAM,eAAe,GAAG,oBAAoB,CAAC;AAE7C,SAAS,aAAa;IACpB,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC;IACzE,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,EAAE,eAAe,CAAC,CAAC;AAC1D,CAAC;AAED,KAAK,UAAU,aAAa;IAC1B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,aAAa,EAAE,EAAE,OAAO,CAAC,CAAC;QACxD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAA0B,CAAC;QACxD,IAAI,MAAM,IAAI,MAAM,CAAC,CAAC,KAAK,CAAC;YAAE,OAAO,MAAM,CAAC;IAC9C,CAAC;IAAC,MAAM,CAAC,CAAC,4CAA4C,CAAC,CAAC;IACxD,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,UAAU,EAAE,sBAAsB,EAAE,CAAC;AACtD,CAAC;AAED,KAAK,UAAU,cAAc,CAAC,OAA8B;IAC1D,MAAM,CAAC,GAAG,aAAa,EAAE,CAAC;IAC1B,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACrD,MAAM,GAAG,GAAG,CAAC,GAAG,MAAM,CAAC;IACvB,MAAM,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IACnE,MAAM,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;AAC1B,CAAC;AAED,SAAS,OAAO,CAAC,CAAqB;IACpC,IAAI,CAAC,CAAC;QAAE,OAAO,QAAQ,CAAC;IACxB,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC;QAAE,OAAO,MAAM,CAAC;IACjC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAC7C,CAAC;AAED,KAAK,UAAU,gBAAgB;IAC7B,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;IAC3D,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CACb,2BAA2B,GAAG,iBAAiB,GAAG,cAAc;cAC9D,oBAAoB,GAAG,iBAAiB,GAAG,mBAAmB;cAC9D,+DAA+D;cAC/D,kBAAkB,CACrB,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;AACtC,CAAC;AAED,KAAK,UAAU,cAAc;IAC3B,MAAM,GAAG,GAAG,MAAM,WAAW,EAAE,CAAC;IAChC,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CACb,0DAA0D;cACxD,kEAAkE,CACrE,CAAC;IACJ,CAAC;IACD,OAAO,GAAG,CAAC,WAAW,CAAC;AACzB,CAAC;AAED,KAAK,UAAU,YAAY,CAAC,OAA8B;IACxD,MAAM,MAAM,GAAG,MAAM,gBAAgB,EAAE,CAAC;IACxC,MAAM,MAAM,GAAG,MAAM,cAAc,EAAE,CAAC;IACtC,MAAM,GAAG,GAAG,MAAM,eAAe,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IACnD,MAAM,IAAI,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;IACjC,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,MAAM,GAAG,GAAG,cAAc,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,gBAAgB,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAC/F,MAAM,CAAC,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;QACzB,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACP,aAAa,EAAE,SAAS,GAAG,MAAM;YACjC,cAAc,EAAE,kBAAkB;SACnC;QACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC;KACvD,CAAC,CAAC;IACH,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QACV,IAAI,MAAM,GAAG,EAAE,CAAC;QAAC,IAAI,CAAC;YAAC,MAAM,GAAG,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC;QACjE,MAAM,IAAI,KAAK,CAAC,wCAAwC,GAAG,CAAC,CAAC,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;IACtG,CAAC;AACH,CAAC;AAED,KAAK,UAAU,cAAc;IAC3B,MAAM,MAAM,GAAG,MAAM,gBAAgB,EAAE,CAAC;IACxC,MAAM,MAAM,GAAG,MAAM,cAAc,EAAE,CAAC;IACtC,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,MAAM,GAAG,GAAG,cAAc,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,gBAAgB,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAC/F,MAAM,CAAC,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;QACzB,MAAM,EAAE,KAAK;QACb,OAAO,EAAE,EAAE,aAAa,EAAE,SAAS,GAAG,MAAM,EAAE;KAC/C,CAAC,CAAC;IACH,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QACV,IAAI,MAAM,GAAG,EAAE,CAAC;QAAC,IAAI,CAAC;YAAC,MAAM,GAAG,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC;QACjE,MAAM,IAAI,KAAK,CAAC,wCAAwC,GAAG,CAAC,CAAC,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;IACtG,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,IAAI,EAA4C,CAAC;IACtE,IAAI,CAAC,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IAC5B,MAAM,GAAG,GAAG,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACxC,OAAO,eAAe,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;AACtC,CAAC;AAED,SAAS,YAAY,CAAC,CAAwB;IAC5C,MAAM,CAAC,4CAA4C,CAAC,CAAC;IACrD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,2BAA2B,GAAG,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;IAC5E,OAAO,CAAC,GAAG,CAAC,2BAA2B,GAAG,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;IAC5E,OAAO,CAAC,GAAG,CAAC,2BAA2B,GAAG,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;IAC5E,OAAO,CAAC,GAAG,CAAC,2BAA2B,GAAG,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC;IAChF,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,2BAA2B,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,uBAAuB,IAAI,WAAW,CAAC,CAAC,CAAC;IAC7F,OAAO,CAAC,GAAG,CAAC,2BAA2B,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,uBAAuB,IAAI,WAAW,CAAC,CAAC,CAAC;IAC7F,OAAO,CAAC,GAAG,CAAC,2BAA2B,GAAG,CAAC,CAAC,CAAC,YAAY,IAAI,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAClF,OAAO,CAAC,GAAG,CAAC,2BAA2B,GAAG,CAAC,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAC/E,OAAO,CAAC,GAAG,CAAC,2BAA2B,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;AACjE,CAAC;AASD,MAAM,UAAU,yBAAyB,CAAC,MAAe;IACvD,MAAM;SACH,OAAO,CAAC,OAAO,CAAC;SAChB,WAAW,CAAC,oEAAoE;UAClE,uDAAuD,CAAC;SACtE,MAAM,CAAC,QAAQ,EAAE,0CAA0C,CAAC;SAC5D,MAAM,CAAC,QAAQ,EAAE,wCAAwC,CAAC;SAC1D,MAAM,CAAC,mBAAmB,EAAE,oCAAoC,CAAC;SACjE,MAAM,CAAC,eAAe,EAAM,mDAAmD,CAAC;SAChF,MAAM,CAAC,KAAK,EAAE,IAAuB,EAAE,EAAE,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/E,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAAuB;IACzD,mCAAmC;IACnC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,MAAM,OAAO,GAAG,MAAM,aAAa,EAAE,CAAC;QACtC,YAAY,CAAC,OAAO,CAAC,CAAC;QACtB,OAAO;IACT,CAAC;IAED,8BAA8B;IAC9B,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,IAAI,MAAoC,CAAC;QACzC,IAAI,CAAC;YACH,MAAM,GAAG,MAAM,cAAc,EAAE,CAAC;QAClC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YACzE,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACrB,OAAO;QACT,CAAC;QACD,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,gDAAgD,CAAC,CAAC,CAAC;YACrE,OAAO;QACT,CAAC;QACD,MAAM,cAAc,CAAC,MAAM,CAAC,CAAC;QAC7B,MAAM,CAAC,iDAAiD,CAAC,CAAC;QAC1D,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,YAAY,CAAC,MAAM,CAAC,CAAC;QACrB,OAAO;IACT,CAAC;IAED,qDAAqD;IACrD,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;QAC9B,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;YAChC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAC,CAAC;YACtE,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACrB,OAAO;QACT,CAAC;QACD,MAAM,MAAM,GAAG,MAAM,aAAa,EAAE,CAAC;QACrC,MAAM,EAAE,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACpC,MAAM,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;QACtC,IAAS,CAAC,KAAK,QAAQ;YAAM,MAAM,CAAC,cAAc,GAAO,IAAI,CAAC,GAAG,CAAC;aAC7D,IAAI,CAAC,KAAK,YAAY;YAAE,MAAM,CAAC,cAAc,GAAO,IAAI,CAAC,GAAG,CAAC;aAC7D,IAAI,CAAC,KAAK,YAAY;YAAE,MAAM,CAAC,cAAc,GAAO,IAAI,CAAC,GAAG,CAAC;aAC7D,IAAI,CAAC,KAAK,YAAY;YAAE,MAAM,CAAC,kBAAkB,GAAG,IAAI,CAAC,GAAG,CAAC;aAC7D,CAAC;YACJ,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,uEAAuE,CAAC,CAAC,CAAC;YAChG,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;YACrB,OAAO;QACT,CAAC;QACD,MAAM,CAAC,UAAU,GAAG,EAAE,CAAC;QACvB,IAAI,CAAC;YACH,MAAM,YAAY,CAAC,MAAM,CAAC,CAAC;YAC3B,MAAM,cAAc,CAAC,MAAM,CAAC,CAAC;YAC7B,MAAM,CAAC,oCAAoC,CAAC,CAAC;YAC7C,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAChB,YAAY,CAAC,MAAM,CAAC,CAAC;QACvB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YACzE,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACvB,CAAC;QACD,OAAO;IACT,CAAC;IAED,uBAAuB;IACvB,MAAM,OAAO,GAAG,MAAM,aAAa,EAAE,CAAC;IACtC,MAAM,CAAC,4BAA4B,CAAC,CAAC;IACrC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,sEAAsE,CAAC,CAAC,CAAC;IAC3F,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,oEAAoE,CAAC,CAAC,CAAC;IACzF,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,gEAAgE,CAAC,CAAC,CAAC;IACrF,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,qDAAqD,CAAC,CAAC,CAAC;IAC1E,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC;QAC5B;YACE,IAAI,EAAE,aAAa;YACnB,IAAI,EAAE,WAAW;YACjB,OAAO,EAAE,2CAA2C;YACpD,OAAO,EAAE;gBACP,EAAE,KAAK,EAAE,0CAA0C,EAAE,KAAK,EAAE,QAAQ,EAAE;gBACtE,EAAE,KAAK,EAAE,gDAAgD,EAAE,KAAK,EAAE,QAAQ,EAAE;gBAC5E,EAAE,KAAK,EAAE,+CAA+C,EAAE,KAAK,EAAE,YAAY,EAAE;aAChF;YACD,GAAG,EAAE,CAAC;YACN,IAAI,EAAE,oCAAoC;SAC3C;KACF,CAAC,CAAC;IACH,IAAI,CAAC,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzD,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC,CAAC;QACvD,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAA0B,EAAE,GAAG,OAAO,EAAE,CAAC;IACrD,IAAI,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QACzC,MAAM,CAAC,GAAG,MAAM,OAAO,CAAC;YACtB,IAAI,EAAE,UAAU;YAChB,IAAI,EAAE,GAAG;YACT,OAAO,EAAE,oCAAoC,GAAG,OAAO,CAAC,OAAO,CAAC,cAAc,CAAC;SAChF,CAAC,CAAC;QACH,IAAI,CAAC,CAAC,CAAC;YAAE,MAAM,CAAC,cAAc,GAAG,CAAC,CAAC,CAAC,CAAC;IACvC,CAAC;IACD,IAAI,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QACzC,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC;YACzB,IAAI,EAAE,UAAU;YAChB,IAAI,EAAE,GAAG;YACT,OAAO,EAAE,gDAAgD,GAAG,OAAO,CAAC,OAAO,CAAC,cAAc,CAAC;SAC5F,CAAC,CAAC;QACH,IAAI,IAAI,CAAC,CAAC;YAAE,MAAM,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC,CAAC;QAC3C,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC;YACzB,IAAI,EAAE,UAAU;YAChB,IAAI,EAAE,GAAG;YACT,OAAO,EAAE,qEAAqE,GAAG,OAAO,CAAC,OAAO,CAAC,cAAc,CAAC;SACjH,CAAC,CAAC;QACH,IAAI,IAAI,CAAC,CAAC;YAAE,MAAM,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC,CAAC;IAC7C,CAAC;IACD,IAAI,OAAO,CAAC,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;QAC7C,MAAM,CAAC,GAAG,MAAM,OAAO,CAAC;YACtB,IAAI,EAAE,UAAU;YAChB,IAAI,EAAE,GAAG;YACT,OAAO,EAAE,+BAA+B,GAAG,OAAO,CAAC,OAAO,CAAC,kBAAkB,CAAC;SAC/E,CAAC,CAAC;QACH,IAAI,CAAC,CAAC,CAAC;YAAE,MAAM,CAAC,kBAAkB,GAAG,CAAC,CAAC,CAAC,CAAC;IAC3C,CAAC;IAED,6DAA6D;IAC7D,MAAM,aAAa,GAAyD,EAAE,CAAC;IAC/E,IAAI,MAAM,CAAC,cAAc;QAAM,aAAa,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,kBAAkB,EAAG,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;IACnG,IAAI,MAAM,CAAC,cAAc;QAAM,aAAa,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAa,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;IACnG,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC;YACzB,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,GAAG;YACT,OAAO,EAAE,wBAAwB;YACjC,OAAO,EAAE,aAAa;YACtB,OAAO,EAAE,CAAC;SACX,CAAC,CAAC;QACH,IAAI,IAAI,CAAC,CAAC;YAAE,MAAM,CAAC,uBAAuB,GAAG,IAAI,CAAC,CAAC,CAAC;IACtD,CAAC;IAED,MAAM,aAAa,GAAwE,EAAE,CAAC;IAC9F,IAAI,MAAM,CAAC,cAAc;QAAM,aAAa,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,gBAAgB,EAAK,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;IACnG,IAAI,MAAM,CAAC,cAAc;QAAM,aAAa,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAa,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;IACnG,IAAI,MAAM,CAAC,kBAAkB;QAAE,aAAa,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,YAAY,EAAS,KAAK,EAAE,YAAY,EAAE,CAAC,CAAC;IACvG,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC;YACzB,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,GAAG;YACT,OAAO,EAAE,wBAAwB;YACjC,OAAO,EAAE,aAAa;YACtB,OAAO,EAAE,CAAC;SACX,CAAC,CAAC;QACH,IAAI,IAAI,CAAC,CAAC;YAAE,MAAM,CAAC,uBAAuB,GAAG,IAAI,CAAC,CAAC,CAAC;IACtD,CAAC;IAED,MAAM,CAAC,UAAU,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAE7C,IAAI,CAAC;QACH,MAAM,YAAY,CAAC,MAAM,CAAC,CAAC;QAC3B,MAAM,cAAc,CAAC,MAAM,CAAC,CAAC;QAC7B,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,8BAA8B,CAAC,CAAC,CAAC;QACvD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,YAAY,CAAC,MAAM,CAAC,CAAC;IACvB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACzE,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACvB,CAAC;AACH,CAAC"}