@mclean-capital/neura 1.10.0

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 (127) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +90 -0
  3. package/dist/audio/capture.d.ts +19 -0
  4. package/dist/audio/capture.d.ts.map +1 -0
  5. package/dist/audio/capture.js +52 -0
  6. package/dist/audio/capture.js.map +1 -0
  7. package/dist/audio/install-hints.d.ts +12 -0
  8. package/dist/audio/install-hints.d.ts.map +1 -0
  9. package/dist/audio/install-hints.js +29 -0
  10. package/dist/audio/install-hints.js.map +1 -0
  11. package/dist/audio/playback.d.ts +33 -0
  12. package/dist/audio/playback.d.ts.map +1 -0
  13. package/dist/audio/playback.js +408 -0
  14. package/dist/audio/playback.js.map +1 -0
  15. package/dist/commands/backup.d.ts +5 -0
  16. package/dist/commands/backup.d.ts.map +1 -0
  17. package/dist/commands/backup.js +72 -0
  18. package/dist/commands/backup.js.map +1 -0
  19. package/dist/commands/chat.d.ts +4 -0
  20. package/dist/commands/chat.d.ts.map +1 -0
  21. package/dist/commands/chat.js +183 -0
  22. package/dist/commands/chat.js.map +1 -0
  23. package/dist/commands/config.d.ts +5 -0
  24. package/dist/commands/config.d.ts.map +1 -0
  25. package/dist/commands/config.js +36 -0
  26. package/dist/commands/config.js.map +1 -0
  27. package/dist/commands/install.d.ts +2 -0
  28. package/dist/commands/install.d.ts.map +1 -0
  29. package/dist/commands/install.js +158 -0
  30. package/dist/commands/install.js.map +1 -0
  31. package/dist/commands/listen.d.ts +5 -0
  32. package/dist/commands/listen.d.ts.map +1 -0
  33. package/dist/commands/listen.js +321 -0
  34. package/dist/commands/listen.js.map +1 -0
  35. package/dist/commands/logs.d.ts +5 -0
  36. package/dist/commands/logs.d.ts.map +1 -0
  37. package/dist/commands/logs.js +40 -0
  38. package/dist/commands/logs.js.map +1 -0
  39. package/dist/commands/open.d.ts +2 -0
  40. package/dist/commands/open.d.ts.map +1 -0
  41. package/dist/commands/open.js +43 -0
  42. package/dist/commands/open.js.map +1 -0
  43. package/dist/commands/restart.d.ts +2 -0
  44. package/dist/commands/restart.d.ts.map +1 -0
  45. package/dist/commands/restart.js +22 -0
  46. package/dist/commands/restart.js.map +1 -0
  47. package/dist/commands/start.d.ts +2 -0
  48. package/dist/commands/start.d.ts.map +1 -0
  49. package/dist/commands/start.js +28 -0
  50. package/dist/commands/start.js.map +1 -0
  51. package/dist/commands/status.d.ts +2 -0
  52. package/dist/commands/status.d.ts.map +1 -0
  53. package/dist/commands/status.js +36 -0
  54. package/dist/commands/status.js.map +1 -0
  55. package/dist/commands/stop.d.ts +2 -0
  56. package/dist/commands/stop.d.ts.map +1 -0
  57. package/dist/commands/stop.js +17 -0
  58. package/dist/commands/stop.js.map +1 -0
  59. package/dist/commands/uninstall.d.ts +4 -0
  60. package/dist/commands/uninstall.d.ts.map +1 -0
  61. package/dist/commands/uninstall.js +52 -0
  62. package/dist/commands/uninstall.js.map +1 -0
  63. package/dist/commands/update.d.ts +2 -0
  64. package/dist/commands/update.d.ts.map +1 -0
  65. package/dist/commands/update.js +25 -0
  66. package/dist/commands/update.js.map +1 -0
  67. package/dist/commands/version.d.ts +2 -0
  68. package/dist/commands/version.d.ts.map +1 -0
  69. package/dist/commands/version.js +25 -0
  70. package/dist/commands/version.js.map +1 -0
  71. package/dist/config.d.ts +12 -0
  72. package/dist/config.d.ts.map +1 -0
  73. package/dist/config.js +107 -0
  74. package/dist/config.js.map +1 -0
  75. package/dist/constants.d.ts +3 -0
  76. package/dist/constants.d.ts.map +1 -0
  77. package/dist/constants.js +3 -0
  78. package/dist/constants.js.map +1 -0
  79. package/dist/download.d.ts +28 -0
  80. package/dist/download.d.ts.map +1 -0
  81. package/dist/download.js +125 -0
  82. package/dist/download.js.map +1 -0
  83. package/dist/format/tools.d.ts +13 -0
  84. package/dist/format/tools.d.ts.map +1 -0
  85. package/dist/format/tools.js +48 -0
  86. package/dist/format/tools.js.map +1 -0
  87. package/dist/health.d.ts +15 -0
  88. package/dist/health.d.ts.map +1 -0
  89. package/dist/health.js +30 -0
  90. package/dist/health.js.map +1 -0
  91. package/dist/index.d.ts +3 -0
  92. package/dist/index.d.ts.map +1 -0
  93. package/dist/index.js +74 -0
  94. package/dist/index.js.map +1 -0
  95. package/dist/port.d.ts +10 -0
  96. package/dist/port.d.ts.map +1 -0
  97. package/dist/port.js +39 -0
  98. package/dist/port.js.map +1 -0
  99. package/dist/service/detect.d.ts +10 -0
  100. package/dist/service/detect.d.ts.map +1 -0
  101. package/dist/service/detect.js +38 -0
  102. package/dist/service/detect.js.map +1 -0
  103. package/dist/service/linux.d.ts +20 -0
  104. package/dist/service/linux.d.ts.map +1 -0
  105. package/dist/service/linux.js +91 -0
  106. package/dist/service/linux.js.map +1 -0
  107. package/dist/service/macos.d.ts +20 -0
  108. package/dist/service/macos.d.ts.map +1 -0
  109. package/dist/service/macos.js +118 -0
  110. package/dist/service/macos.js.map +1 -0
  111. package/dist/service/manager.d.ts +16 -0
  112. package/dist/service/manager.d.ts.map +1 -0
  113. package/dist/service/manager.js +16 -0
  114. package/dist/service/manager.js.map +1 -0
  115. package/dist/service/windows.d.ts +20 -0
  116. package/dist/service/windows.d.ts.map +1 -0
  117. package/dist/service/windows.js +103 -0
  118. package/dist/service/windows.js.map +1 -0
  119. package/dist/update-check.d.ts +7 -0
  120. package/dist/update-check.d.ts.map +1 -0
  121. package/dist/update-check.js +71 -0
  122. package/dist/update-check.js.map +1 -0
  123. package/dist/version.d.ts +12 -0
  124. package/dist/version.d.ts.map +1 -0
  125. package/dist/version.js +15 -0
  126. package/dist/version.js.map +1 -0
  127. package/package.json +59 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 McLean Capital
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,90 @@
1
+ # @mclean-capital/neura
2
+
3
+ > Neura CLI — install, manage, and talk to the Neura AI assistant from your terminal.
4
+
5
+ Neura is a proactive, autonomous AI operating system. It combines real-time voice conversation, continuous visual understanding, and autonomous worker agents. This CLI installs and manages the Neura core service, and also acts as a full client via `neura chat` and `neura listen`.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install -g @mclean-capital/neura
11
+ ```
12
+
13
+ Requires Node.js >= 22.
14
+
15
+ ## Quick start
16
+
17
+ ```bash
18
+ neura install # interactive setup: API keys, auto-port, service registration
19
+ neura start # start the core service
20
+ neura chat # text chat with Neura from your terminal
21
+ neura listen # voice chat (mic + speaker)
22
+ ```
23
+
24
+ ## Commands
25
+
26
+ ### Setup & service lifecycle
27
+
28
+ | Command | Description |
29
+ | ----------------- | ------------------------------------------ |
30
+ | `neura install` | Interactive setup wizard + service install |
31
+ | `neura start` | Start the core service |
32
+ | `neura stop` | Stop the core service |
33
+ | `neura restart` | Restart the core service |
34
+ | `neura status` | Show service status, port, uptime, health |
35
+ | `neura update` | Download the latest core binary |
36
+ | `neura uninstall` | Remove service and optionally clean data |
37
+
38
+ ### Client commands
39
+
40
+ | Command | Description |
41
+ | -------------- | ------------------------------------------- |
42
+ | `neura chat` | Interactive text chat over WebSocket |
43
+ | `neura listen` | Voice chat (mic capture + speaker playback) |
44
+ | `neura open` | Open the web UI in your default browser |
45
+
46
+ ### Configuration & data
47
+
48
+ | Command | Description |
49
+ | ------------------------------ | ---------------------------- |
50
+ | `neura config list` | Show all configuration |
51
+ | `neura config set <key> <val>` | Set a config value |
52
+ | `neura config get <key>` | Get a config value |
53
+ | `neura logs` | Tail core service logs |
54
+ | `neura backup` | Create a memory backup |
55
+ | `neura restore` | Restore memories from backup |
56
+
57
+ ## Voice client notes
58
+
59
+ `neura listen` uses optional native audio dependencies:
60
+
61
+ - **`decibri`** — microphone capture via PortAudio
62
+ - **`speaker`**, **`@picovoice/pvspeaker-node`**, or **`sox`** — speaker playback
63
+
64
+ These are marked as `optionalDependencies` so `npm install -g @mclean-capital/neura` won't fail if your platform lacks the required build tools. If audio init fails at runtime, `neura listen` will print install instructions for your platform.
65
+
66
+ ## API keys
67
+
68
+ Neura uses:
69
+
70
+ - **xAI (Grok)** — voice conversation. Get a key at [console.x.ai](https://console.x.ai/).
71
+ - **Google (Gemini)** — vision watcher, memory embeddings, wake word transcription. Get a key at [aistudio.google.com/apikey](https://aistudio.google.com/apikey).
72
+
73
+ Both keys are set during `neura install` and stored in `~/.neura/config.json` with restricted file permissions.
74
+
75
+ ## Security
76
+
77
+ - The core server binds to `localhost` only — not exposed on the LAN.
78
+ - All WebSocket and HTTP requests require a 256-bit bearer token auto-generated on install.
79
+ - The token is stored in `~/.neura/config.json` (Unix `0600` permissions).
80
+ - `neura chat`, `neura listen`, `neura open`, `neura backup`, and `neura restore` automatically load and pass the token.
81
+
82
+ ## Links
83
+
84
+ - **Full README**: https://github.com/mclean-capital/neura#readme
85
+ - **Roadmap**: https://github.com/mclean-capital/neura/blob/main/docs/roadmap.md
86
+ - **Issues**: https://github.com/mclean-capital/neura/issues
87
+
88
+ ## License
89
+
90
+ MIT © McLean Capital
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Audio capture abstraction for mic input.
3
+ *
4
+ * Primary: decibri (PortAudio, prebuilt arm64 binaries)
5
+ * The implementation lazy-loads decibri so `neura chat` works without it.
6
+ */
7
+ export interface AudioCapture {
8
+ start(): void;
9
+ stop(): void;
10
+ onData: ((base64Pcm: string) => void) | null;
11
+ }
12
+ export declare function createAudioCapture(): Promise<AudioCapture>;
13
+ /** List available audio input devices */
14
+ export declare function listInputDevices(): Promise<{
15
+ index: number;
16
+ name: string;
17
+ isDefault: boolean;
18
+ }[]>;
19
+ //# sourceMappingURL=capture.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capture.d.ts","sourceRoot":"","sources":["../../src/audio/capture.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,MAAM,WAAW,YAAY;IAC3B,KAAK,IAAI,IAAI,CAAC;IACd,IAAI,IAAI,IAAI,CAAC;IACb,MAAM,EAAE,CAAC,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;CAC9C;AAED,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,YAAY,CAAC,CAoChE;AAED,yCAAyC;AACzC,wBAAsB,gBAAgB,IAAI,OAAO,CAC/C;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,EAAE,CACtD,CAOA"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Audio capture abstraction for mic input.
3
+ *
4
+ * Primary: decibri (PortAudio, prebuilt arm64 binaries)
5
+ * The implementation lazy-loads decibri so `neura chat` works without it.
6
+ */
7
+ import { audioInstallHint } from './install-hints.js';
8
+ export async function createAudioCapture() {
9
+ try {
10
+ const { default: Decibri } = await import('decibri');
11
+ let onData = null;
12
+ let mic = null;
13
+ return {
14
+ get onData() {
15
+ return onData;
16
+ },
17
+ set onData(handler) {
18
+ onData = handler;
19
+ },
20
+ start() {
21
+ mic = new Decibri({ sampleRate: 24000, channels: 1, format: 'int16' });
22
+ mic.on('data', (chunk) => {
23
+ if (onData) {
24
+ onData(chunk.toString('base64'));
25
+ }
26
+ });
27
+ // Prevent unhandled 'error' from crashing the process
28
+ mic.on('error', (err) => {
29
+ console.error(`Mic error: ${err.message}`);
30
+ });
31
+ },
32
+ stop() {
33
+ mic?.stop();
34
+ mic = null;
35
+ },
36
+ };
37
+ }
38
+ catch {
39
+ throw new Error('Mic capture requires the "decibri" package.\n' + audioInstallHint('decibri'));
40
+ }
41
+ }
42
+ /** List available audio input devices */
43
+ export async function listInputDevices() {
44
+ try {
45
+ const { default: Decibri } = await import('decibri');
46
+ return Decibri.devices();
47
+ }
48
+ catch {
49
+ return [];
50
+ }
51
+ }
52
+ //# sourceMappingURL=capture.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capture.js","sourceRoot":"","sources":["../../src/audio/capture.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAQtD,MAAM,CAAC,KAAK,UAAU,kBAAkB;IACtC,IAAI,CAAC;QACH,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC;QAErD,IAAI,MAAM,GAAyC,IAAI,CAAC;QACxD,IAAI,GAAG,GAAwC,IAAI,CAAC;QAEpD,OAAO;YACL,IAAI,MAAM;gBACR,OAAO,MAAM,CAAC;YAChB,CAAC;YACD,IAAI,MAAM,CAAC,OAA6C;gBACtD,MAAM,GAAG,OAAO,CAAC;YACnB,CAAC;YAED,KAAK;gBACH,GAAG,GAAG,IAAI,OAAO,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;gBACvE,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;oBAC/B,IAAI,MAAM,EAAE,CAAC;wBACX,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;oBACnC,CAAC;gBACH,CAAC,CAAC,CAAC;gBACH,sDAAsD;gBACtD,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAU,EAAE,EAAE;oBAC7B,OAAO,CAAC,KAAK,CAAC,cAAc,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;gBAC7C,CAAC,CAAC,CAAC;YACL,CAAC;YAED,IAAI;gBACF,GAAG,EAAE,IAAI,EAAE,CAAC;gBACZ,GAAG,GAAG,IAAI,CAAC;YACb,CAAC;SACF,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,+CAA+C,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC,CAAC;IACjG,CAAC;AACH,CAAC;AAED,yCAAyC;AACzC,MAAM,CAAC,KAAK,UAAU,gBAAgB;IAGpC,IAAI,CAAC;QACH,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC;QACrD,OAAO,OAAO,CAAC,OAAO,EAA2D,CAAC;IACpF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Install hint helper for optional native audio dependencies.
3
+ *
4
+ * Detects whether the CLI is running from a global npm install or from a
5
+ * monorepo workspace, and returns the appropriate install instructions.
6
+ */
7
+ /**
8
+ * Build an install hint for a missing optional dependency.
9
+ * Shows instructions appropriate to the user's context (global vs workspace).
10
+ */
11
+ export declare function audioInstallHint(depName: string): string;
12
+ //# sourceMappingURL=install-hints.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install-hints.d.ts","sourceRoot":"","sources":["../../src/audio/install-hints.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAYH;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CASxD"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Install hint helper for optional native audio dependencies.
3
+ *
4
+ * Detects whether the CLI is running from a global npm install or from a
5
+ * monorepo workspace, and returns the appropriate install instructions.
6
+ */
7
+ function isGlobalInstall() {
8
+ try {
9
+ // If we're inside node_modules/@mclean-capital/*, we're an npm package.
10
+ // Otherwise we're running from the monorepo (tsx src/ or dist/).
11
+ return import.meta.url.includes('node_modules') && import.meta.url.includes('mclean-capital');
12
+ }
13
+ catch {
14
+ return false;
15
+ }
16
+ }
17
+ /**
18
+ * Build an install hint for a missing optional dependency.
19
+ * Shows instructions appropriate to the user's context (global vs workspace).
20
+ */
21
+ export function audioInstallHint(depName) {
22
+ if (isGlobalInstall()) {
23
+ return ('If installed globally via npm, retry with optional deps enabled:\n' +
24
+ ' npm install -g @mclean-capital/neura --include=optional\n' +
25
+ `This requires a C++ build toolchain for ${depName} (Python + gcc/clang/MSVC).`);
26
+ }
27
+ return `npm install ${depName} -w @mclean-capital/neura`;
28
+ }
29
+ //# sourceMappingURL=install-hints.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install-hints.js","sourceRoot":"","sources":["../../src/audio/install-hints.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,SAAS,eAAe;IACtB,IAAI,CAAC;QACH,wEAAwE;QACxE,iEAAiE;QACjE,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC;IAChG,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAe;IAC9C,IAAI,eAAe,EAAE,EAAE,CAAC;QACtB,OAAO,CACL,oEAAoE;YACpE,6DAA6D;YAC7D,2CAA2C,OAAO,6BAA6B,CAChF,CAAC;IACJ,CAAC;IACD,OAAO,eAAe,OAAO,2BAA2B,CAAC;AAC3D,CAAC"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Audio playback abstraction for speaker output.
3
+ *
4
+ * Primary: sox via child_process (universal, streaming stdin pipe)
5
+ * Fallback: @picovoice/pvspeaker-node (prebuilt binaries, no sox needed)
6
+ */
7
+ export interface AudioPlayback {
8
+ start(): void;
9
+ stop(): void;
10
+ play(base64Pcm: string): void;
11
+ }
12
+ /** Auto-detect and create the best available playback backend.
13
+ *
14
+ * Priority depends on platform:
15
+ *
16
+ * **macOS / Linux**:
17
+ * 1. `speaker` (node-speaker) — native Writable stream, automatic
18
+ * backpressure, holds audio device open across turns. Best for bursty
19
+ * streaming audio from a voice WebSocket.
20
+ * 2. `@picovoice/pvspeaker-node` — ring-buffer API, manual drain loop.
21
+ * 3. `sox` — universal but has tail-sample loss in long-lived bursty
22
+ * streams, used only if nothing else is available.
23
+ *
24
+ * **Windows**:
25
+ * 1. `@picovoice/pvspeaker-node` — preferred because node-speaker relies
26
+ * on mpg123's output layer, and its underflow warnings can't be
27
+ * reliably silenced on Windows (no `/dev/fd/2` trick). Pvspeaker uses
28
+ * WASAPI directly with a clean ring buffer and no noisy stderr.
29
+ * 2. `speaker` (node-speaker) — fallback if pvspeaker isn't available.
30
+ * 3. `sox` — last-resort fallback.
31
+ */
32
+ export declare function createAudioPlayback(): Promise<AudioPlayback>;
33
+ //# sourceMappingURL=playback.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"playback.d.ts","sourceRoot":"","sources":["../../src/audio/playback.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA8FH,MAAM,WAAW,aAAa;IAC5B,KAAK,IAAI,IAAI,CAAC;IACd,IAAI,IAAI,IAAI,CAAC;IACb,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AA2QD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,aAAa,CAAC,CAgDlE"}