ovtools 0.0.0-stage → 1.0.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 (198) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +121 -2
  3. package/assets/common/bond-inspect.sh +368 -0
  4. package/assets/common/config.sh +263 -0
  5. package/assets/common/extract-data.sh +197 -0
  6. package/assets/common/harden-host.sh +37 -0
  7. package/assets/common/install-deps.sh +93 -0
  8. package/assets/common/node-enroll.sh +65 -0
  9. package/assets/common/node-setup.sh +150 -0
  10. package/assets/common/node-start.sh +90 -0
  11. package/assets/common/node-stop.sh +18 -0
  12. package/assets/common/node-upgrade.sh +45 -0
  13. package/assets/common/pre-run.sh +497 -0
  14. package/assets/common/promote-validator.sh +104 -0
  15. package/assets/deploy/10-prepare-host.sh +98 -0
  16. package/assets/deploy/20-install-toolchain.sh +93 -0
  17. package/assets/deploy/30-setup-node.sh +82 -0
  18. package/assets/deploy/40-start-node.sh +75 -0
  19. package/assets/deploy/50-verify.sh +259 -0
  20. package/assets/deploy/60-enroll.sh +304 -0
  21. package/assets/deploy/70-promote.sh +152 -0
  22. package/assets/deploy/lib.sh +398 -0
  23. package/assets/manage/10-bond-increase.sh +149 -0
  24. package/assets/manage/10-diagnose-node.sh +169 -0
  25. package/assets/manage/20-exit-validator.sh +259 -0
  26. package/assets/manage/25-recover-node.sh +291 -0
  27. package/assets/manage/30-status.sh +64 -0
  28. package/assets/manage/40-exit-withdraw.sh +133 -0
  29. package/assets/manage/bond_inc.sh +318 -0
  30. package/assets/manage/dashboard_monitor/app.js +1544 -0
  31. package/assets/manage/dashboard_monitor/assets/v2.2/css/base.css +113 -0
  32. package/assets/manage/dashboard_monitor/assets/v2.2/css/components/content.css +133 -0
  33. package/assets/manage/dashboard_monitor/assets/v2.2/css/components/controls.css +229 -0
  34. package/assets/manage/dashboard_monitor/assets/v2.2/css/components/data.css +374 -0
  35. package/assets/manage/dashboard_monitor/assets/v2.2/css/components/icons.css +35 -0
  36. package/assets/manage/dashboard_monitor/assets/v2.2/css/components/motion.css +57 -0
  37. package/assets/manage/dashboard_monitor/assets/v2.2/css/components/shell.css +51 -0
  38. package/assets/manage/dashboard_monitor/assets/v2.2/css/components/sidebar.css +242 -0
  39. package/assets/manage/dashboard_monitor/assets/v2.2/css/components/topbar.css +138 -0
  40. package/assets/manage/dashboard_monitor/assets/v2.2/css/fonts.css +30 -0
  41. package/assets/manage/dashboard_monitor/assets/v2.2/css/synteq-ui-v2.css +25 -0
  42. package/assets/manage/dashboard_monitor/assets/v2.2/css/theme-dark.css +38 -0
  43. package/assets/manage/dashboard_monitor/assets/v2.2/css/theme-light.css +36 -0
  44. package/assets/manage/dashboard_monitor/assets/v2.2/css/tokens.css +61 -0
  45. package/assets/manage/dashboard_monitor/assets/v2.2/fonts/GoogleSansCode-Medium.ttf +0 -0
  46. package/assets/manage/dashboard_monitor/assets/v2.2/fonts/GoogleSansCode-Regular.ttf +0 -0
  47. package/assets/manage/dashboard_monitor/assets/v2.2/fonts/GoogleSansCode-SemiBold.ttf +0 -0
  48. package/assets/manage/dashboard_monitor/assets/v2.2/js/synteq-ui-v2.js +869 -0
  49. package/assets/manage/dashboard_monitor/deploy-dashboard.sh +230 -0
  50. package/assets/manage/dashboard_monitor/favicon.svg +13 -0
  51. package/assets/manage/dashboard_monitor/index.html +1197 -0
  52. package/assets/manage/dashboard_monitor/nginx-octra.conf +76 -0
  53. package/assets/manage/dashboard_monitor/octra-dashboard.service +29 -0
  54. package/assets/manage/dashboard_monitor/octra-node-prune.cron +12 -0
  55. package/assets/manage/dashboard_monitor/octra-node-prune.service +16 -0
  56. package/assets/manage/dashboard_monitor/octra-node-prune.timer +12 -0
  57. package/assets/manage/dashboard_monitor/prune-node-junk.sh +329 -0
  58. package/assets/manage/dashboard_monitor/server.py +1887 -0
  59. package/assets/manage/dashboard_monitor/ssl-certbot.sh +90 -0
  60. package/assets/manage/dashboard_monitor/styles.css +327 -0
  61. package/assets/manage/lib.sh +347 -0
  62. package/assets/manifest.json +143 -0
  63. package/assets/migrate/00-backup-identity.sh +67 -0
  64. package/assets/migrate/01-prepare-target.sh +145 -0
  65. package/assets/migrate/02-authorize-pull.sh +43 -0
  66. package/assets/migrate/03-pull-state.sh +102 -0
  67. package/assets/migrate/04-stop-source.sh +85 -0
  68. package/assets/migrate/05-finalize-target.sh +140 -0
  69. package/assets/migrate/06-start-target.sh +57 -0
  70. package/assets/migrate/07-verify.sh +237 -0
  71. package/assets/migrate/08-rollback.sh +54 -0
  72. package/assets/migrate/lib.sh +149 -0
  73. package/assets/upgrade/10-preflight.sh +120 -0
  74. package/assets/upgrade/20-upgrade.sh +142 -0
  75. package/assets/upgrade/30-manual-upgrade.sh +129 -0
  76. package/assets/upgrade/40-storage-prune.sh +65 -0
  77. package/assets/upgrade/50-status.sh +58 -0
  78. package/assets/upgrade/lib.sh +232 -0
  79. package/bin/ovtools.js +32 -0
  80. package/dist/api/checks.d.ts +6 -0
  81. package/dist/api/checks.d.ts.map +1 -0
  82. package/dist/api/checks.js +173 -0
  83. package/dist/api/checks.js.map +1 -0
  84. package/dist/api/hostkeys.d.ts +10 -0
  85. package/dist/api/hostkeys.d.ts.map +1 -0
  86. package/dist/api/hostkeys.js +58 -0
  87. package/dist/api/hostkeys.js.map +1 -0
  88. package/dist/api/jobs.d.ts +33 -0
  89. package/dist/api/jobs.d.ts.map +1 -0
  90. package/dist/api/jobs.js +483 -0
  91. package/dist/api/jobs.js.map +1 -0
  92. package/dist/api/nodes.d.ts +16 -0
  93. package/dist/api/nodes.d.ts.map +1 -0
  94. package/dist/api/nodes.js +126 -0
  95. package/dist/api/nodes.js.map +1 -0
  96. package/dist/api/server.d.ts +3 -0
  97. package/dist/api/server.d.ts.map +1 -0
  98. package/dist/api/server.js +443 -0
  99. package/dist/api/server.js.map +1 -0
  100. package/dist/cli.d.ts +3 -0
  101. package/dist/cli.d.ts.map +1 -0
  102. package/dist/cli.js +301 -0
  103. package/dist/cli.js.map +1 -0
  104. package/dist/constants.d.ts +76 -0
  105. package/dist/constants.d.ts.map +1 -0
  106. package/dist/constants.js +150 -0
  107. package/dist/constants.js.map +1 -0
  108. package/dist/index.d.ts +18 -0
  109. package/dist/index.d.ts.map +1 -0
  110. package/dist/index.js +60 -0
  111. package/dist/index.js.map +1 -0
  112. package/dist/orchestrator/base.d.ts +52 -0
  113. package/dist/orchestrator/base.d.ts.map +1 -0
  114. package/dist/orchestrator/base.js +219 -0
  115. package/dist/orchestrator/base.js.map +1 -0
  116. package/dist/orchestrator/deploy.d.ts +33 -0
  117. package/dist/orchestrator/deploy.d.ts.map +1 -0
  118. package/dist/orchestrator/deploy.js +313 -0
  119. package/dist/orchestrator/deploy.js.map +1 -0
  120. package/dist/orchestrator/manage.d.ts +28 -0
  121. package/dist/orchestrator/manage.d.ts.map +1 -0
  122. package/dist/orchestrator/manage.js +267 -0
  123. package/dist/orchestrator/manage.js.map +1 -0
  124. package/dist/orchestrator/migrate.d.ts +31 -0
  125. package/dist/orchestrator/migrate.d.ts.map +1 -0
  126. package/dist/orchestrator/migrate.js +442 -0
  127. package/dist/orchestrator/migrate.js.map +1 -0
  128. package/dist/ssh/client.d.ts +39 -0
  129. package/dist/ssh/client.d.ts.map +1 -0
  130. package/dist/ssh/client.js +418 -0
  131. package/dist/ssh/client.js.map +1 -0
  132. package/dist/test/core.test.d.ts +2 -0
  133. package/dist/test/core.test.d.ts.map +1 -0
  134. package/dist/test/core.test.js +188 -0
  135. package/dist/test/core.test.js.map +1 -0
  136. package/dist/types.d.ts +267 -0
  137. package/dist/types.d.ts.map +1 -0
  138. package/dist/types.js +3 -0
  139. package/dist/types.js.map +1 -0
  140. package/dist/utils/assets.d.ts +28 -0
  141. package/dist/utils/assets.d.ts.map +1 -0
  142. package/dist/utils/assets.js +583 -0
  143. package/dist/utils/assets.js.map +1 -0
  144. package/dist/utils/browser.d.ts +2 -0
  145. package/dist/utils/browser.d.ts.map +1 -0
  146. package/dist/utils/browser.js +23 -0
  147. package/dist/utils/browser.js.map +1 -0
  148. package/dist/utils/dashboard.d.ts +16 -0
  149. package/dist/utils/dashboard.d.ts.map +1 -0
  150. package/dist/utils/dashboard.js +177 -0
  151. package/dist/utils/dashboard.js.map +1 -0
  152. package/dist/utils/helpers.d.ts +29 -0
  153. package/dist/utils/helpers.d.ts.map +1 -0
  154. package/dist/utils/helpers.js +204 -0
  155. package/dist/utils/helpers.js.map +1 -0
  156. package/dist/utils/scripts.d.ts +60 -0
  157. package/dist/utils/scripts.d.ts.map +1 -0
  158. package/dist/utils/scripts.js +174 -0
  159. package/dist/utils/scripts.js.map +1 -0
  160. package/dist/utils/state.d.ts +12 -0
  161. package/dist/utils/state.d.ts.map +1 -0
  162. package/dist/utils/state.js +44 -0
  163. package/dist/utils/state.js.map +1 -0
  164. package/dist/utils/tar.d.ts +11 -0
  165. package/dist/utils/tar.d.ts.map +1 -0
  166. package/dist/utils/tar.js +93 -0
  167. package/dist/utils/tar.js.map +1 -0
  168. package/dist/utils/update.d.ts +9 -0
  169. package/dist/utils/update.d.ts.map +1 -0
  170. package/dist/utils/update.js +134 -0
  171. package/dist/utils/update.js.map +1 -0
  172. package/dist/utils/websocket.d.ts +10 -0
  173. package/dist/utils/websocket.d.ts.map +1 -0
  174. package/dist/utils/websocket.js +203 -0
  175. package/dist/utils/websocket.js.map +1 -0
  176. package/package.json +55 -4
  177. package/public/app.js +2712 -0
  178. package/public/assets/v2.2/css/base.css +113 -0
  179. package/public/assets/v2.2/css/components/content.css +133 -0
  180. package/public/assets/v2.2/css/components/controls.css +229 -0
  181. package/public/assets/v2.2/css/components/data.css +373 -0
  182. package/public/assets/v2.2/css/components/icons.css +35 -0
  183. package/public/assets/v2.2/css/components/motion.css +57 -0
  184. package/public/assets/v2.2/css/components/shell.css +51 -0
  185. package/public/assets/v2.2/css/components/sidebar.css +242 -0
  186. package/public/assets/v2.2/css/components/topbar.css +138 -0
  187. package/public/assets/v2.2/css/fonts.css +30 -0
  188. package/public/assets/v2.2/css/synteq-ui-v2.css +25 -0
  189. package/public/assets/v2.2/css/theme-dark.css +38 -0
  190. package/public/assets/v2.2/css/theme-light.css +36 -0
  191. package/public/assets/v2.2/css/tokens.css +61 -0
  192. package/public/assets/v2.2/fonts/GoogleSansCode-Medium.ttf +0 -0
  193. package/public/assets/v2.2/fonts/GoogleSansCode-Regular.ttf +0 -0
  194. package/public/assets/v2.2/fonts/GoogleSansCode-SemiBold.ttf +0 -0
  195. package/public/assets/v2.2/js/synteq-ui-v2.js +869 -0
  196. package/public/favicon.svg +7 -0
  197. package/public/index.html +1080 -0
  198. package/public/styles.css +552 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser.js","sourceRoot":"","sources":["../../src/utils/browser.ts"],"names":[],"mappings":";;AAEA,kCAeC;AAjBD,iDAAsC;AAEtC,SAAgB,WAAW,CAAC,GAAW;IACrC,IAAI,OAAO,CAAC,GAAG,CAAC,kBAAkB,KAAK,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,kBAAkB,KAAK,MAAM;QAAE,OAAO;IAChG,IAAI,CAAC;QACH,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;YACjC,IAAA,qBAAK,EAAC,cAAc,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC;YAC7F,OAAO;QACT,CAAC;QACD,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAClC,IAAA,qBAAK,EAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC;YAClE,OAAO;QACT,CAAC;QACD,IAAA,qBAAK,EAAC,UAAU,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC;IACxE,CAAC;IAAC,MAAM,CAAC;QACP,iEAAiE;IACnE,CAAC;AACH,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { SSHClient } from '../ssh/client';
2
+ import { Logger } from '../utils/helpers';
3
+ export interface DashboardOptions {
4
+ ip: string;
5
+ domain?: string;
6
+ sslMode?: 'auto' | 'cloudflare' | 'certbot';
7
+ certDir?: string;
8
+ email?: string;
9
+ reset?: boolean;
10
+ }
11
+ export declare function deployDashboard(client: SSHClient, logger: Logger, options: DashboardOptions, program?: string): Promise<{
12
+ healthy: boolean;
13
+ url: string;
14
+ host: string;
15
+ }>;
16
+ //# sourceMappingURL=dashboard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboard.d.ts","sourceRoot":"","sources":["../../src/utils/dashboard.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAc,MAAM,eAAe,CAAC;AAEtD,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAU1C,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAAC;IAC5C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,wBAAsB,eAAe,CACnC,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,gBAAgB,EACzB,OAAO,SAAW,GACjB,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CA0I1D"}
@@ -0,0 +1,177 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.deployDashboard = deployDashboard;
37
+ const path = __importStar(require("path"));
38
+ const fs = __importStar(require("fs/promises"));
39
+ const client_1 = require("../ssh/client");
40
+ const constants_1 = require("../constants");
41
+ const assets_1 = require("./assets");
42
+ const REQUIRED = [
43
+ 'server.py', 'index.html', 'app.js', 'styles.css', 'deploy-dashboard.sh',
44
+ 'ssl-certbot.sh', 'nginx-octra.conf', 'octra-dashboard.service',
45
+ 'prune-node-junk.sh', 'octra-node-prune.cron', 'octra-node-prune.service',
46
+ 'octra-node-prune.timer',
47
+ ];
48
+ async function deployDashboard(client, logger, options, program = 'manage') {
49
+ const log = (msg, level = 'info') => logger.log(msg, level, { host: client.host, program });
50
+ const domain = (options.domain || '').trim().toLowerCase();
51
+ if (domain && !/^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)+$/.test(domain)) {
52
+ throw new Error(`invalid domain '${domain}' (expected a host name such as node.example.com)`);
53
+ }
54
+ const sslMode = options.sslMode || 'auto';
55
+ if (sslMode === 'certbot' && !domain)
56
+ throw new Error("Let's Encrypt needs the domain (it must already point at the node)");
57
+ if (sslMode === 'cloudflare' && !options.certDir)
58
+ throw new Error('choose the folder that holds fullchain.pem and privkey.pem');
59
+ log('=== Deploy monitoring dashboard ===', 'step');
60
+ // --- TLS material ----------------------------------------------------
61
+ if (sslMode !== 'certbot' && options.certDir) {
62
+ for (const name of ['fullchain.pem', 'privkey.pem']) {
63
+ const file = path.join(options.certDir, name);
64
+ try {
65
+ await fs.access(file);
66
+ }
67
+ catch {
68
+ throw new Error(`certificate file missing: ${file}`);
69
+ }
70
+ }
71
+ const has = await client.exec('test -s /etc/ssl/octra/fullchain.pem && test -s /etc/ssl/octra/privkey.pem', { timeout: 60000 });
72
+ if (has.exitCode !== 0) {
73
+ log('Installing TLS material to /etc/ssl/octra/', 'step');
74
+ await client.exec('install -d -m 700 /etc/ssl/octra', { timeout: 60000 });
75
+ await client.uploadFile(path.join(options.certDir, 'fullchain.pem'), '/etc/ssl/octra/fullchain.pem', false);
76
+ await client.uploadFile(path.join(options.certDir, 'privkey.pem'), '/etc/ssl/octra/privkey.pem', false);
77
+ await client.exec('chmod 644 /etc/ssl/octra/fullchain.pem; chmod 600 /etc/ssl/octra/privkey.pem', { timeout: 60000 });
78
+ log('TLS material installed', 'ok');
79
+ }
80
+ else {
81
+ log('TLS material already present on the host - keeping it', 'info');
82
+ }
83
+ }
84
+ // --- sync assets (git bundle, single archive fallback) ---------------
85
+ const assets = new assets_1.AssetSync(client, logger, 'dashboard');
86
+ log('Syncing dashboard assets...', 'step');
87
+ const sync = await assets.syncDashboard(Boolean(options.reset));
88
+ log(sync.skipped
89
+ ? `dashboard files already up to date (${sync.head.slice(0, 12)}) - transfer skipped`
90
+ : `${sync.files} file(s) synced via ${sync.transport}`, 'ok');
91
+ const probeFiles = async () => client.exec(`for f in ${REQUIRED.map(client_1.shellQuote).join(' ')}; do test -f ${constants_1.REMOTE.dashboard}/$f || echo MISSING:$f; done`, { timeout: 60000 });
92
+ let probe = await probeFiles();
93
+ if (probe.stdout.includes('MISSING:')) {
94
+ log('dashboard files are incomplete after the checkpoint - forcing a full re-extract', 'warn');
95
+ await assets.syncDashboard(true);
96
+ probe = await probeFiles();
97
+ }
98
+ if (probe.stdout.includes('MISSING:')) {
99
+ throw new Error(`dashboard files are incomplete on ${client.host}: ${probe.stdout.trim()}`);
100
+ }
101
+ // --- force the published host name --------------------------------
102
+ // deploy-dashboard.sh keeps the server_name already live on the host, so a
103
+ // first deploy would stay on the template placeholder without this rewrite.
104
+ if (domain) {
105
+ const rewrite = [
106
+ `f=${constants_1.REMOTE.dashboard}/nginx-octra.conf`,
107
+ `[ -f "$f" ] || exit 2`,
108
+ `awk -v d=${(0, client_1.shellQuote)(domain)} '{ if ($0 ~ /^[[:space:]]*server_name[[:space:]]/) sub(/server_name[[:space:]]+[^;]+;/, "server_name " d ";"); print }' "$f" > "$f.tmp" && mv "$f.tmp" "$f"`,
109
+ `grep -qE '^[[:space:]]*server[[:space:]]*\\{' "$f" || exit 3`,
110
+ `s=/etc/nginx/sites-available/octra-dashboard`,
111
+ `if [ -f "$s" ]; then awk -v d=${(0, client_1.shellQuote)(domain)} '{ if ($0 ~ /^[[:space:]]*server_name[[:space:]]/) sub(/server_name[[:space:]]+[^;]+;/, "server_name " d ";"); print }' "$s" > "$s.tmp" && mv "$s.tmp" "$s"; fi`,
112
+ `sed -i "s|^# Domain : .*|# Domain : ${domain} (edit server_name to your domain)|" "$f" || true`,
113
+ ].join('; ');
114
+ const result = await client.exec(rewrite, { timeout: 120000 });
115
+ if (result.exitCode !== 0) {
116
+ throw new Error(`nginx template rewrite failed for ${domain} (exit ${result.exitCode})`);
117
+ }
118
+ log(`nginx server_name forced to ${domain}`, 'ok');
119
+ }
120
+ // --- Let's Encrypt (helper is on the host now) ----------------------
121
+ if (sslMode === 'certbot') {
122
+ log(`Requesting a Let's Encrypt certificate for ${domain}...`, 'step');
123
+ let cmd = `bash ${constants_1.REMOTE.dashboard}/ssl-certbot.sh --domain ${(0, client_1.shellQuote)(domain)}`;
124
+ if (options.email)
125
+ cmd += ` --email ${(0, client_1.shellQuote)(options.email)}`;
126
+ const ssl = await client.exec(cmd, { timeout: 900000 });
127
+ if (ssl.exitCode !== 0) {
128
+ throw new Error(`certbot could not issue a certificate for ${domain}: ${ssl.stderr || ssl.stdout}`);
129
+ }
130
+ }
131
+ // --- install / restart ----------------------------------------------
132
+ log('Installing nginx site + systemd backend...', 'step');
133
+ const install = await client.exec(`bash ${constants_1.REMOTE.dashboard}/deploy-dashboard.sh`, {
134
+ timeout: 900000,
135
+ onLine: line => {
136
+ if (line.trim())
137
+ log(` ${line}`, 'remote');
138
+ },
139
+ });
140
+ if (install.exitCode !== 0) {
141
+ const diag = await client.exec('systemctl status octra-dashboard --no-pager -n 20 || true; journalctl -u octra-dashboard -n 40 --no-pager || true', { timeout: 120000 });
142
+ for (const line of diag.stdout.split('\n'))
143
+ if (line.trim())
144
+ log(` ${line}`, 'remote');
145
+ throw new Error('deploy-dashboard.sh reported errors - see the lines above');
146
+ }
147
+ // --- health check ----------------------------------------------------
148
+ let healthy = false;
149
+ for (let attempt = 1; attempt <= 6; attempt++) {
150
+ const probe = await client.exec('systemctl is-active --quiet octra-dashboard && curl -fsS -m 5 -o /dev/null http://127.0.0.1:9090/api/ping && echo BACKEND_OK', { timeout: 60000 });
151
+ if (probe.exitCode === 0) {
152
+ healthy = true;
153
+ break;
154
+ }
155
+ log(`waiting for octra-dashboard to answer /api/ping (${attempt}/6)...`, 'warn');
156
+ await new Promise(resolve => setTimeout(resolve, 5000));
157
+ }
158
+ // --- remove the retired manage drop-in/token -------------------------
159
+ if (healthy) {
160
+ await client.exec('changed=0; if [ -f /etc/systemd/system/octra-dashboard.service.d/manage.conf ]; then rm -f /etc/systemd/system/octra-dashboard.service.d/manage.conf; changed=1; fi; ' +
161
+ 'if [ -f /opt/octra/dashboard/manage.token ]; then rm -f /opt/octra/dashboard/manage.token; changed=1; fi; ' +
162
+ 'if [ "$changed" -eq 1 ]; then systemctl daemon-reload; systemctl restart octra-dashboard; sleep 2; fi; echo MANAGE_CLEANUP=done', { timeout: 300000 });
163
+ }
164
+ const host = domain || options.ip;
165
+ const scheme = domain ? 'https' : 'http';
166
+ if (!healthy) {
167
+ const diag = await client.exec('systemctl status octra-dashboard --no-pager -n 30 || true; journalctl -u octra-dashboard -n 40 --no-pager || true', { timeout: 120000 });
168
+ for (const line of diag.stdout.split('\n'))
169
+ if (line.trim())
170
+ log(` ${line}`, 'remote');
171
+ throw new Error(`the dashboard backend did not answer /api/ping on ${client.host}`);
172
+ }
173
+ log(`monitoring dashboard live: ${scheme}://${host}/`, 'ok');
174
+ log(`API: ${scheme}://${host}/api/status`, 'info');
175
+ return { healthy, url: `${scheme}://${host}/`, host };
176
+ }
177
+ //# sourceMappingURL=dashboard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dashboard.js","sourceRoot":"","sources":["../../src/utils/dashboard.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import type { LogEntry, LogLevel } from '../types';
2
+ export declare function ensureDir(dirPath: string): Promise<void>;
3
+ export declare function readJSON<T>(filePath: string): Promise<T | null>;
4
+ export declare function writeJSON(filePath: string, data: unknown): Promise<void>;
5
+ export declare function cleanLine(line: string): string;
6
+ export declare function formatBytes(bytes: number): string;
7
+ export declare function formatDuration(seconds: number): string;
8
+ export declare function timestamp(): string;
9
+ export type LogListener = (entry: LogEntry) => void;
10
+ export declare class Logger {
11
+ private logFile;
12
+ private buffer;
13
+ private listeners;
14
+ private seq;
15
+ private writeChain;
16
+ private echo;
17
+ constructor(logFile: string, echo?: boolean);
18
+ log(message: string, level?: LogLevel, meta?: {
19
+ host?: string;
20
+ program?: string;
21
+ }): void;
22
+ private appendFile;
23
+ subscribe(listener: LogListener): () => void;
24
+ entriesSince(sinceSeq?: number, limit?: number): LogEntry[];
25
+ lastSeq(): number;
26
+ flush(): Promise<void>;
27
+ }
28
+ export declare function createLogger(name: string, echo?: boolean): Logger;
29
+ //# sourceMappingURL=helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/utils/helpers.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAGnD,wBAAsB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE9D;AAED,wBAAsB,QAAQ,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAQrE;AAED,wBAAsB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAgB9E;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAU9C;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMjD;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAMtD;AAED,wBAAgB,SAAS,IAAI,MAAM,CAElC;AAED,MAAM,MAAM,WAAW,GAAG,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,CAAC;AAsBpD,qBAAa,MAAM;IACjB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,SAAS,CAA0B;IAC3C,OAAO,CAAC,GAAG,CAAK;IAChB,OAAO,CAAC,UAAU,CAAoC;IACtD,OAAO,CAAC,IAAI,CAAU;gBAEV,OAAO,EAAE,MAAM,EAAE,IAAI,UAAO;IAKxC,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,GAAE,QAAiB,EAAE,IAAI,GAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,IAAI;IA6BpG,OAAO,CAAC,UAAU;IAUlB,SAAS,CAAC,QAAQ,EAAE,WAAW,GAAG,MAAM,IAAI;IAK5C,YAAY,CAAC,QAAQ,SAAI,EAAE,KAAK,SAAO,GAAG,QAAQ,EAAE;IAKpD,OAAO,IAAI,MAAM;IAIX,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAG7B;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,UAAO,GAAG,MAAM,CAG9D"}
@@ -0,0 +1,204 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.Logger = void 0;
37
+ exports.ensureDir = ensureDir;
38
+ exports.readJSON = readJSON;
39
+ exports.writeJSON = writeJSON;
40
+ exports.cleanLine = cleanLine;
41
+ exports.formatBytes = formatBytes;
42
+ exports.formatDuration = formatDuration;
43
+ exports.timestamp = timestamp;
44
+ exports.createLogger = createLogger;
45
+ const fs = __importStar(require("fs/promises"));
46
+ const path = __importStar(require("path"));
47
+ const constants_1 = require("../constants");
48
+ async function ensureDir(dirPath) {
49
+ await fs.mkdir(dirPath, { recursive: true });
50
+ }
51
+ async function readJSON(filePath) {
52
+ try {
53
+ const content = await fs.readFile(filePath, 'utf8');
54
+ return JSON.parse(content);
55
+ }
56
+ catch (err) {
57
+ if (err && err.code === 'ENOENT')
58
+ return null;
59
+ throw err;
60
+ }
61
+ }
62
+ async function writeJSON(filePath, data) {
63
+ await ensureDir(path.dirname(filePath));
64
+ const body = JSON.stringify(data, null, 2) + '\n';
65
+ const tmp = `${filePath}.tmp-${process.pid}-${Date.now()}`;
66
+ await fs.writeFile(tmp, body, 'utf8');
67
+ try {
68
+ await fs.rename(tmp, filePath);
69
+ }
70
+ catch (err) {
71
+ if (err && (err.code === 'EEXIST' || err.code === 'EPERM')) {
72
+ await fs.rm(filePath, { force: true });
73
+ await fs.rename(tmp, filePath);
74
+ }
75
+ else {
76
+ await fs.rm(tmp, { force: true });
77
+ throw err;
78
+ }
79
+ }
80
+ }
81
+ function cleanLine(line) {
82
+ let clean = String(line).replace(/\x1b\[[0-9;]*[A-Za-z]/g, '');
83
+ clean = clean.replace(/[─│┌┐└┘├┤┬┴┼]/g, '-');
84
+ clean = clean.replace(/[═║╔╗╚╝╠╣╦╩╬]/g, '=');
85
+ clean = clean.replace(/…/g, '...');
86
+ clean = clean.replace(/[\u2013\u2014\u2015\u2212\u00b7]/g, '-');
87
+ clean = clean.replace(/\u2192/g, '->');
88
+ clean = clean.replace(/[^\x09\x20-\x7E]/g, '');
89
+ clean = clean.replace(/[\x00-\x08\x0b-\x0c\x0e-\x1f\x7f]/g, '');
90
+ return clean.replace(/\r$/, '').trimEnd();
91
+ }
92
+ function formatBytes(bytes) {
93
+ if (!Number.isFinite(bytes) || bytes < 0)
94
+ return '?';
95
+ if (bytes < 1024)
96
+ return `${bytes} B`;
97
+ if (bytes < 1024 * 1024)
98
+ return `${(bytes / 1024).toFixed(1)} KB`;
99
+ if (bytes < 1024 * 1024 * 1024)
100
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
101
+ return `${(bytes / (1024 * 1024 * 1024)).toFixed(2)} GB`;
102
+ }
103
+ function formatDuration(seconds) {
104
+ if (!Number.isFinite(seconds) || seconds < 0)
105
+ return '-';
106
+ if (seconds < 90)
107
+ return `${Math.round(seconds)}s`;
108
+ const m = Math.round(seconds / 60);
109
+ if (m < 60)
110
+ return `${m}m`;
111
+ return `${Math.floor(m / 60)}h ${String(m % 60).padStart(2, '0')}m`;
112
+ }
113
+ function timestamp() {
114
+ return new Date().toISOString();
115
+ }
116
+ const LEVEL_TAG = {
117
+ info: 'INFO',
118
+ ok: 'OK',
119
+ warn: 'WARN',
120
+ error: 'ERROR',
121
+ step: 'STEP',
122
+ remote: 'REMO',
123
+ data: 'DATA',
124
+ };
125
+ const CONSOLE_COLOR = {
126
+ info: '\x1b[36m',
127
+ ok: '\x1b[32m',
128
+ warn: '\x1b[33m',
129
+ error: '\x1b[31m',
130
+ step: '\x1b[1;35m',
131
+ remote: '\x1b[90m',
132
+ data: '\x1b[37m',
133
+ };
134
+ class Logger {
135
+ logFile;
136
+ buffer = [];
137
+ listeners = new Set();
138
+ seq = 0;
139
+ writeChain = Promise.resolve();
140
+ echo;
141
+ constructor(logFile, echo = true) {
142
+ this.logFile = logFile;
143
+ this.echo = echo;
144
+ }
145
+ log(message, level = 'info', meta = {}) {
146
+ const line = cleanLine(message);
147
+ if (!line && level !== 'data')
148
+ return;
149
+ const entry = {
150
+ seq: ++this.seq,
151
+ ts: Date.now() / 1000,
152
+ level,
153
+ line,
154
+ host: meta.host,
155
+ program: meta.program,
156
+ };
157
+ this.buffer.push(entry);
158
+ if (this.buffer.length > 6000)
159
+ this.buffer.splice(0, this.buffer.length - 6000);
160
+ if (this.echo) {
161
+ const color = process.stdout.isTTY ? (CONSOLE_COLOR[level] || '') : '';
162
+ const reset = color ? '\x1b[0m' : '';
163
+ process.stdout.write(`${color}[${LEVEL_TAG[level]}]${reset} ${line}\n`);
164
+ }
165
+ for (const listener of this.listeners) {
166
+ try {
167
+ listener(entry);
168
+ }
169
+ catch {
170
+ // a broken subscriber must never break the run
171
+ }
172
+ }
173
+ this.appendFile(entry);
174
+ }
175
+ appendFile(entry) {
176
+ const text = `[${new Date(entry.ts * 1000).toISOString()}] [${LEVEL_TAG[entry.level]}] ${entry.line}\n`;
177
+ this.writeChain = this.writeChain
178
+ .then(async () => {
179
+ await ensureDir(path.dirname(this.logFile));
180
+ await fs.appendFile(this.logFile, text, 'utf8');
181
+ })
182
+ .catch(() => undefined);
183
+ }
184
+ subscribe(listener) {
185
+ this.listeners.add(listener);
186
+ return () => this.listeners.delete(listener);
187
+ }
188
+ entriesSince(sinceSeq = 0, limit = 3000) {
189
+ const rows = this.buffer.filter(e => e.seq > sinceSeq);
190
+ return rows.slice(Math.max(0, rows.length - limit));
191
+ }
192
+ lastSeq() {
193
+ return this.seq;
194
+ }
195
+ async flush() {
196
+ await this.writeChain;
197
+ }
198
+ }
199
+ exports.Logger = Logger;
200
+ function createLogger(name, echo = true) {
201
+ const stamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);
202
+ return new Logger(path.join(constants_1.LOGS_DIR, `${name}-${stamp}.log`), echo);
203
+ }
204
+ //# sourceMappingURL=helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/utils/helpers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ import { SSHClient } from '../ssh/client';
2
+ import { AssetLogger } from './assets';
3
+ export interface PushResult {
4
+ manifest: string;
5
+ skipped: boolean;
6
+ files: number;
7
+ transport: 'git' | 'tar' | 'clone';
8
+ }
9
+ export declare class ScriptManager {
10
+ private client;
11
+ private logger;
12
+ constructor(client: SSHClient, logger?: AssetLogger);
13
+ pushScripts(dirs?: string[]): Promise<PushResult>;
14
+ runDetached(options: {
15
+ program: 'deploy' | 'migrate' | 'manage' | 'upgrade';
16
+ unit: string;
17
+ script: string;
18
+ workDir?: string;
19
+ env?: Record<string, string>;
20
+ outFile?: string;
21
+ statusFile?: string;
22
+ label?: string;
23
+ onLog?: (line: string) => void;
24
+ }): Promise<string>;
25
+ followStatus(options: {
26
+ program: 'deploy' | 'migrate' | 'manage' | 'upgrade';
27
+ unit: string;
28
+ timeoutSec: number;
29
+ outFile?: string;
30
+ statusFile?: string;
31
+ onLine?: (line: string) => void;
32
+ progressRe?: RegExp;
33
+ pollSec?: number;
34
+ }): Promise<{
35
+ state: string;
36
+ detail: string;
37
+ soft: boolean;
38
+ }>;
39
+ waitForScript(options: {
40
+ program: 'deploy' | 'migrate' | 'manage' | 'upgrade';
41
+ script: string;
42
+ unit: string;
43
+ env?: Record<string, string>;
44
+ timeoutSec: number;
45
+ workDir?: string;
46
+ outFile?: string;
47
+ statusFile?: string;
48
+ onLine?: (line: string) => void;
49
+ }): Promise<{
50
+ state: string;
51
+ detail: string;
52
+ soft: boolean;
53
+ }>;
54
+ remoteStatus(program: 'deploy' | 'migrate' | 'manage' | 'upgrade'): Promise<{
55
+ state: string;
56
+ detail: string;
57
+ }>;
58
+ }
59
+ export declare function createScriptManager(client: SSHClient, logger?: AssetLogger): ScriptManager;
60
+ //# sourceMappingURL=scripts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scripts.d.ts","sourceRoot":"","sources":["../../src/utils/scripts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAc,MAAM,eAAe,CAAC;AAEtD,OAAO,EAAa,WAAW,EAAE,MAAM,UAAU,CAAC;AAElD,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,KAAK,GAAG,KAAK,GAAG,OAAO,CAAC;CACpC;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,MAAM,CAAc;gBAEhB,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,EAAE,WAAW;IAK7C,WAAW,CAAC,IAAI,GAAE,MAAM,EAAe,GAAG,OAAO,CAAC,UAAU,CAAC;IAY7D,WAAW,CAAC,OAAO,EAAE;QACzB,OAAO,EAAE,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;QACrD,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC7B,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;KAChC,GAAG,OAAO,CAAC,MAAM,CAAC;IA4Bb,YAAY,CAAC,OAAO,EAAE;QAC1B,OAAO,EAAE,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;QACrD,IAAI,EAAE,MAAM,CAAC;QACb,UAAU,EAAE,MAAM,CAAC;QACnB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;QAChC,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,CAAA;KAAE,CAAC;IAoGvD,aAAa,CAAC,OAAO,EAAE;QAC3B,OAAO,EAAE,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;QACrD,MAAM,EAAE,MAAM,CAAC;QACf,IAAI,EAAE,MAAM,CAAC;QACb,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC7B,UAAU,EAAE,MAAM,CAAC;QACnB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;KACjC,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,CAAA;KAAE,CAAC;IAKvD,YAAY,CAAC,OAAO,EAAE,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CAQrH;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,aAAa,CAE1F"}