@trillboards/edge-core 0.2.1 → 0.2.3

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 (40) hide show
  1. package/dist/JsonFileStore.d.ts +33 -0
  2. package/dist/JsonFileStore.d.ts.map +1 -0
  3. package/dist/JsonFileStore.js +210 -0
  4. package/dist/JsonFileStore.js.map +1 -0
  5. package/dist/MemoryAttenuationManager.d.ts +164 -0
  6. package/dist/MemoryAttenuationManager.d.ts.map +1 -0
  7. package/dist/MemoryAttenuationManager.js +400 -0
  8. package/dist/MemoryAttenuationManager.js.map +1 -0
  9. package/dist/ModelManager.d.ts +166 -0
  10. package/dist/ModelManager.d.ts.map +1 -0
  11. package/dist/ModelManager.js +580 -0
  12. package/dist/ModelManager.js.map +1 -0
  13. package/dist/SignalBuffer.d.ts +20 -12
  14. package/dist/SignalBuffer.d.ts.map +1 -1
  15. package/dist/SignalBuffer.js +56 -71
  16. package/dist/SignalBuffer.js.map +1 -1
  17. package/dist/SignalStore.d.ts +35 -0
  18. package/dist/SignalStore.d.ts.map +1 -0
  19. package/dist/SignalStore.js +13 -0
  20. package/dist/SignalStore.js.map +1 -0
  21. package/dist/SqliteStore.d.ts +41 -0
  22. package/dist/SqliteStore.d.ts.map +1 -0
  23. package/dist/SqliteStore.js +162 -0
  24. package/dist/SqliteStore.js.map +1 -0
  25. package/dist/StatusServer.d.ts +99 -0
  26. package/dist/StatusServer.d.ts.map +1 -0
  27. package/dist/StatusServer.js +262 -0
  28. package/dist/StatusServer.js.map +1 -0
  29. package/dist/ZKAudienceProver.d.ts +137 -0
  30. package/dist/ZKAudienceProver.d.ts.map +1 -0
  31. package/dist/ZKAudienceProver.js +321 -0
  32. package/dist/ZKAudienceProver.js.map +1 -0
  33. package/dist/index.d.ts +12 -0
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.js +15 -1
  36. package/dist/index.js.map +1 -1
  37. package/dist/types.d.ts +40 -0
  38. package/dist/types.d.ts.map +1 -1
  39. package/dist/types.js.map +1 -1
  40. package/package.json +4 -2
@@ -1 +1 @@
1
- {"version":3,"file":"SignalBuffer.d.ts","sourceRoot":"","sources":["../src/SignalBuffer.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,YAAY;IACvB,MAAM,CAAC,QAAQ,CAAC,YAAY,QAAQ;IACpC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,MAAM;IACtC,MAAM,CAAC,QAAQ,CAAC,UAAU,SAAuB;IACjD,MAAM,CAAC,QAAQ,CAAC,WAAW,KAAK;IAChC,MAAM,CAAC,QAAQ,CAAC,WAAW,OAAO;IAElC,OAAO,CAAC,EAAE,CAAe;IACzB,OAAO,CAAC,UAAU,CAAsC;IACxD,OAAO,CAAC,aAAa,CAAsC;IAC3D,OAAO,CAAC,cAAc,CAAsC;IAC5D,OAAO,CAAC,SAAS,CAAsC;IACvD,OAAO,CAAC,SAAS,CAAsC;IACvD,OAAO,CAAC,iBAAiB,CAAsC;IAC/D,OAAO,CAAC,kBAAkB,CAAsC;IAChE,OAAO,CAAC,oBAAoB,CAAsC;gBAEtD,MAAM,EAAE,MAAM;IAkD1B;;;OAGG;IACH,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAYpD;;;OAGG;IACH,WAAW,CACT,aAAa,EAAE,aAAa,EAC5B,KAAK,GAAE,MAAsC,GAC5C,MAAM;IA8BT;;OAEG;IACH,eAAe,IAAI,MAAM;IAMzB;;OAEG;IACH,KAAK,IAAI,MAAM;IAKf;;OAEG;IACH,QAAQ,IAAI,IAAI;CAGjB"}
1
+ {"version":3,"file":"SignalBuffer.d.ts","sourceRoot":"","sources":["../src/SignalBuffer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAe,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEnE,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,YAAY;IACvB,MAAM,CAAC,QAAQ,CAAC,YAAY,QAAQ;IACpC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,MAAM;IACtC,MAAM,CAAC,QAAQ,CAAC,UAAU,SAAuB;IACjD,MAAM,CAAC,QAAQ,CAAC,WAAW,KAAK;IAChC,MAAM,CAAC,QAAQ,CAAC,WAAW,OAAO;IAElC,OAAO,CAAC,KAAK,CAAc;IAC3B,QAAQ,CAAC,OAAO,EAAE,QAAQ,GAAG,MAAM,CAAC;gBAExB,MAAM,EAAE,MAAM;IAiC1B;;;OAGG;IACH,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAYpD;;;;OAIG;IACH,WAAW,CACT,aAAa,EAAE,aAAa,EAC5B,KAAK,GAAE,MAAsC,GAC5C,MAAM;IA8BT;;OAEG;IACH,eAAe,IAAI,MAAM;IAKzB;;OAEG;IACH,KAAK,IAAI,MAAM;IAIf;;OAEG;IACH,KAAK,IAAI,gBAAgB;IAIzB;;OAEG;IACH,QAAQ,IAAI,IAAI;CAGjB"}
@@ -1,92 +1,73 @@
1
1
  "use strict";
2
2
  /**
3
- * SignalBuffer — Offline signal buffering using better-sqlite3.
4
- * Port of SignalBuffer.kt (Room database) to cross-platform SQLite.
3
+ * SignalBuffer — Offline signal buffering with auto-detecting backend.
4
+ * Port of SignalBuffer.kt (Room database) to cross-platform storage.
5
+ *
6
+ * Backends:
7
+ * - SqliteStore (better-sqlite3 installed → WAL mode, prepared stmts)
8
+ * - JsonFileStore (fallback → zero deps, fs.renameSync atomic writes)
9
+ *
10
+ * Auto-detection: tries require('better-sqlite3') at construction time.
11
+ * If unavailable (native compilation failed, not installed), falls back
12
+ * to JsonFileStore — guaranteed to work on any Node.js >=18 platform.
5
13
  *
6
14
  * Capacity: 8,640 signals (24h at 6 signals/min)
7
15
  * Eviction: oldest 10% when at capacity
8
16
  * Flush: batch of 50, marks with _buffered and _bufferedAt
9
17
  * Pruning: signals older than 24h auto-deleted
18
+ * Priority: FACE_BACKED > PERSON_BACKED > SPEECH_ONLY > PROXY_ONLY > EMPTY
10
19
  */
11
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
12
- if (k2 === undefined) k2 = k;
13
- var desc = Object.getOwnPropertyDescriptor(m, k);
14
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
15
- desc = { enumerable: true, get: function() { return m[k]; } };
16
- }
17
- Object.defineProperty(o, k2, desc);
18
- }) : (function(o, m, k, k2) {
19
- if (k2 === undefined) k2 = k;
20
- o[k2] = m[k];
21
- }));
22
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
23
- Object.defineProperty(o, "default", { enumerable: true, value: v });
24
- }) : function(o, v) {
25
- o["default"] = v;
26
- });
27
- var __importStar = (this && this.__importStar) || function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- var __importDefault = (this && this.__importDefault) || function (mod) {
35
- return (mod && mod.__esModule) ? mod : { "default": mod };
36
- };
37
20
  Object.defineProperty(exports, "__esModule", { value: true });
38
21
  exports.SignalBuffer = void 0;
39
- const better_sqlite3_1 = __importDefault(require("better-sqlite3"));
40
- const path = __importStar(require("path"));
41
- const fs = __importStar(require("fs"));
22
+ const JsonFileStore_1 = require("./JsonFileStore");
42
23
  class SignalBuffer {
43
24
  constructor(dbPath) {
44
- const dir = path.dirname(dbPath);
45
- if (!fs.existsSync(dir)) {
46
- fs.mkdirSync(dir, { recursive: true });
25
+ let store = null;
26
+ let backend = 'json';
27
+ // Try SQLite first (high-performance, optional)
28
+ try {
29
+ // Dynamic require — only resolves if better-sqlite3 is installed + compiled
30
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
31
+ const Database = require('better-sqlite3');
32
+ const { SqliteStore } = require('./SqliteStore');
33
+ store = new SqliteStore(dbPath, Database);
34
+ backend = 'sqlite';
35
+ }
36
+ catch {
37
+ // better-sqlite3 not available — fall back to JSON file store
47
38
  }
48
- this.db = new better_sqlite3_1.default(dbPath);
49
- this.db.pragma('journal_mode = WAL');
50
- this.db.pragma('synchronous = NORMAL');
51
- this.db.exec(`
52
- CREATE TABLE IF NOT EXISTS buffered_signals (
53
- id INTEGER PRIMARY KEY AUTOINCREMENT,
54
- payload TEXT NOT NULL,
55
- timestamp INTEGER NOT NULL DEFAULT (strftime('%s','now') * 1000),
56
- retry_count INTEGER NOT NULL DEFAULT 0
57
- )
58
- `);
59
- this.db.exec(`
60
- CREATE INDEX IF NOT EXISTS idx_signals_timestamp ON buffered_signals(timestamp)
61
- `);
62
- // Prepared statements for performance
63
- this.insertStmt = this.db.prepare('INSERT INTO buffered_signals (payload, timestamp, retry_count) VALUES (?, ?, 0)');
64
- this.getOldestStmt = this.db.prepare('SELECT id, payload, timestamp, retry_count FROM buffered_signals ORDER BY timestamp ASC LIMIT ?');
65
- this.deleteByIdStmt = this.db.prepare('DELETE FROM buffered_signals WHERE id = ?');
66
- this.countStmt = this.db.prepare('SELECT COUNT(*) as count FROM buffered_signals');
67
- this.pruneStmt = this.db.prepare('DELETE FROM buffered_signals WHERE timestamp < ?');
68
- this.deleteOldestNStmt = this.db.prepare('DELETE FROM buffered_signals WHERE id IN (SELECT id FROM buffered_signals ORDER BY timestamp ASC LIMIT ?)');
69
- this.incrementRetryStmt = this.db.prepare('UPDATE buffered_signals SET retry_count = retry_count + 1 WHERE id = ?');
70
- this.deleteMaxRetriesStmt = this.db.prepare('DELETE FROM buffered_signals WHERE retry_count >= ?');
39
+ if (!store) {
40
+ // Use JSON file store — zero dependencies, universal
41
+ const jsonPath = dbPath.replace(/\.db$/, '.json');
42
+ store = new JsonFileStore_1.JsonFileStore(jsonPath);
43
+ backend = 'json';
44
+ }
45
+ this.store = store;
46
+ this.backend = backend;
47
+ const label = backend === 'sqlite'
48
+ ? 'SQLite (disk-persistent, WAL mode)'
49
+ : 'JSON file (disk-persistent, atomic writes)';
50
+ console.log(`[SignalBuffer] Initialized: ${label}`);
71
51
  }
72
52
  /**
73
53
  * Buffer a signal for later sending.
74
54
  * If at capacity, evicts oldest 10% first.
75
55
  */
76
56
  bufferSignal(payload) {
77
- const count = this.count();
57
+ const count = this.store.count();
78
58
  if (count >= SignalBuffer.MAX_CAPACITY) {
79
59
  const evictCount = Math.ceil(SignalBuffer.MAX_CAPACITY * SignalBuffer.EVICT_RATIO);
80
- this.deleteOldestNStmt.run(evictCount);
60
+ this.store.deleteOldestN(evictCount);
81
61
  }
82
- this.insertStmt.run(JSON.stringify(payload), Date.now());
62
+ this.store.insert(JSON.stringify(payload), Date.now());
83
63
  }
84
64
  /**
85
65
  * Flush buffered signals via socket.
86
66
  * Returns number of successfully sent signals.
67
+ * Signals are flushed in priority order — highest evidence grade first.
87
68
  */
88
69
  flushBuffer(socketManager, limit = SignalBuffer.FLUSH_BATCH_SIZE) {
89
- const signals = this.getOldestStmt.all(limit);
70
+ const signals = this.store.getOldest(limit);
90
71
  let sent = 0;
91
72
  for (const signal of signals) {
92
73
  try {
@@ -96,20 +77,20 @@ class SignalBuffer {
96
77
  payload._bufferedAt = signal.timestamp;
97
78
  const success = socketManager.emitAudienceSignal(payload);
98
79
  if (success) {
99
- this.deleteByIdStmt.run(signal.id);
80
+ this.store.deleteById(signal.id);
100
81
  sent++;
101
82
  }
102
83
  else {
103
- this.incrementRetryStmt.run(signal.id);
84
+ this.store.incrementRetry(signal.id);
104
85
  }
105
86
  }
106
87
  catch {
107
88
  // Corrupted payload — remove it
108
- this.deleteByIdStmt.run(signal.id);
89
+ this.store.deleteById(signal.id);
109
90
  }
110
91
  }
111
92
  // Clean up signals that have exceeded max retries
112
- this.deleteMaxRetriesStmt.run(SignalBuffer.MAX_RETRIES);
93
+ this.store.deleteExceedingRetries(SignalBuffer.MAX_RETRIES);
113
94
  return sent;
114
95
  }
115
96
  /**
@@ -117,21 +98,25 @@ class SignalBuffer {
117
98
  */
118
99
  pruneOldSignals() {
119
100
  const cutoff = Date.now() - SignalBuffer.MAX_AGE_MS;
120
- const result = this.pruneStmt.run(cutoff);
121
- return result.changes;
101
+ return this.store.deleteOlderThan(cutoff);
122
102
  }
123
103
  /**
124
104
  * Current number of buffered signals.
125
105
  */
126
106
  count() {
127
- const row = this.countStmt.get();
128
- return row.count;
107
+ return this.store.count();
108
+ }
109
+ /**
110
+ * Signal buffer statistics — count by evidence grade, oldest timestamp.
111
+ */
112
+ stats() {
113
+ return this.store.stats();
129
114
  }
130
115
  /**
131
- * Close the database connection.
116
+ * Close the store connection.
132
117
  */
133
118
  shutdown() {
134
- this.db.close();
119
+ this.store.close();
135
120
  }
136
121
  }
137
122
  exports.SignalBuffer = SignalBuffer;
@@ -1 +1 @@
1
- {"version":3,"file":"SignalBuffer.js","sourceRoot":"","sources":["../src/SignalBuffer.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,oEAAoE;AACpE,2CAA6B;AAC7B,uCAAyB;AAUzB,MAAa,YAAY;IAiBvB,YAAY,MAAc;QACxB,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACjC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACxB,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACzC,CAAC;QAED,IAAI,CAAC,EAAE,GAAG,IAAI,wBAAQ,CAAC,MAAM,CAAC,CAAC;QAC/B,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;QACrC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC;QAEvC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC;;;;;;;KAOZ,CAAC,CAAC;QAEH,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC;;KAEZ,CAAC,CAAC;QAEH,sCAAsC;QACtC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAC/B,iFAAiF,CAClF,CAAC;QACF,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAClC,iGAAiG,CAClG,CAAC;QACF,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CACnC,2CAA2C,CAC5C,CAAC;QACF,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAC9B,gDAAgD,CACjD,CAAC;QACF,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAC9B,kDAAkD,CACnD,CAAC;QACF,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CACtC,2GAA2G,CAC5G,CAAC;QACF,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CACvC,wEAAwE,CACzE,CAAC;QACF,IAAI,CAAC,oBAAoB,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CACzC,qDAAqD,CACtD,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,YAAY,CAAC,OAAgC;QAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;QAC3B,IAAI,KAAK,IAAI,YAAY,CAAC,YAAY,EAAE,CAAC;YACvC,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAC1B,YAAY,CAAC,YAAY,GAAG,YAAY,CAAC,WAAW,CACrD,CAAC;YACF,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACzC,CAAC;QAEA,IAAI,CAAC,UAAkB,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IACpE,CAAC;IAED;;;OAGG;IACH,WAAW,CACT,aAA4B,EAC5B,QAAgB,YAAY,CAAC,gBAAgB;QAE7C,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,KAAK,CAAqB,CAAC;QAClE,IAAI,IAAI,GAAG,CAAC,CAAC;QAEb,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;gBAC3C,wCAAwC;gBACxC,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC;gBACzB,OAAO,CAAC,WAAW,GAAG,MAAM,CAAC,SAAS,CAAC;gBAEvC,MAAM,OAAO,GAAG,aAAa,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;gBAC1D,IAAI,OAAO,EAAE,CAAC;oBACZ,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;oBACnC,IAAI,EAAE,CAAC;gBACT,CAAC;qBAAM,CAAC;oBACN,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBACzC,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,gCAAgC;gBAChC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YACrC,CAAC;QACH,CAAC;QAED,kDAAkD;QAClD,IAAI,CAAC,oBAAoB,CAAC,GAAG,CAAC,YAAY,CAAC,WAAW,CAAC,CAAC;QAExD,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACH,eAAe;QACb,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,YAAY,CAAC,UAAU,CAAC;QACpD,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC1C,OAAO,MAAM,CAAC,OAAO,CAAC;IACxB,CAAC;IAED;;OAEG;IACH,KAAK;QACH,MAAM,GAAG,GAAI,IAAI,CAAC,SAAiB,CAAC,GAAG,EAAuB,CAAC;QAC/D,OAAO,GAAG,CAAC,KAAK,CAAC;IACnB,CAAC;IAED;;OAEG;IACH,QAAQ;QACN,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;IAClB,CAAC;;AA9IH,oCA+IC;AA9IiB,yBAAY,GAAG,IAAI,CAAC;AACpB,6BAAgB,GAAG,EAAE,CAAC;AACtB,uBAAU,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AACjC,wBAAW,GAAG,CAAC,CAAC;AAChB,wBAAW,GAAG,GAAG,CAAC"}
1
+ {"version":3,"file":"SignalBuffer.js","sourceRoot":"","sources":["../src/SignalBuffer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * SignalStore — Internal interface for signal-aware persistence backends.
3
+ *
4
+ * The SignalBuffer delegates all storage operations to a SignalStore implementation.
5
+ * Two built-in implementations:
6
+ * - JsonFileStore (zero dependencies, universal default)
7
+ * - SqliteStore (optional, high-throughput upgrade via better-sqlite3)
8
+ *
9
+ * Advanced users can implement this interface for custom backends (Redis, IndexedDB, etc.)
10
+ */
11
+ export interface StoredSignal {
12
+ id: number;
13
+ payload: string;
14
+ timestamp: number;
15
+ retryCount: number;
16
+ evidenceGrade?: string;
17
+ }
18
+ export interface SignalStoreStats {
19
+ total: number;
20
+ byEvidenceGrade: Record<string, number>;
21
+ oldestTimestampMs: number | null;
22
+ }
23
+ export interface SignalStore {
24
+ insert(payload: string, timestamp: number): void;
25
+ getOldest(limit: number): StoredSignal[];
26
+ deleteById(id: number): void;
27
+ deleteOlderThan(cutoffMs: number): number;
28
+ deleteOldestN(n: number): void;
29
+ deleteExceedingRetries(maxRetries: number): void;
30
+ incrementRetry(id: number): void;
31
+ count(): number;
32
+ stats(): SignalStoreStats;
33
+ close(): void;
34
+ }
35
+ //# sourceMappingURL=SignalStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SignalStore.d.ts","sourceRoot":"","sources":["../src/SignalStore.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACjD,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,EAAE,CAAC;IACzC,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;IAC1C,aAAa,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,sBAAsB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACjD,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,KAAK,IAAI,MAAM,CAAC;IAChB,KAAK,IAAI,gBAAgB,CAAC;IAC1B,KAAK,IAAI,IAAI,CAAC;CACf"}
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ /**
3
+ * SignalStore — Internal interface for signal-aware persistence backends.
4
+ *
5
+ * The SignalBuffer delegates all storage operations to a SignalStore implementation.
6
+ * Two built-in implementations:
7
+ * - JsonFileStore (zero dependencies, universal default)
8
+ * - SqliteStore (optional, high-throughput upgrade via better-sqlite3)
9
+ *
10
+ * Advanced users can implement this interface for custom backends (Redis, IndexedDB, etc.)
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ //# sourceMappingURL=SignalStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SignalStore.js","sourceRoot":"","sources":["../src/SignalStore.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * SqliteStore — High-performance signal store using better-sqlite3.
3
+ * Extracted from the original SignalBuffer implementation.
4
+ *
5
+ * WAL journal mode, prepared statements, evidence_grade column + index
6
+ * for priority-aware flushing (FACE_BACKED sent first).
7
+ *
8
+ * Only loaded when better-sqlite3 is available (optional dependency).
9
+ */
10
+ import type { SignalStore, StoredSignal, SignalStoreStats } from './SignalStore';
11
+ import type { Database as DatabaseType } from 'better-sqlite3';
12
+ export declare class SqliteStore implements SignalStore {
13
+ private db;
14
+ private insertStmt;
15
+ private getOldestStmt;
16
+ private deleteByIdStmt;
17
+ private countStmt;
18
+ private pruneStmt;
19
+ private deleteOldestNStmt;
20
+ private incrementRetryStmt;
21
+ private deleteMaxRetriesStmt;
22
+ private statsStmt;
23
+ private oldestStmt;
24
+ /**
25
+ * @param dbPath - Path to the SQLite database file
26
+ * @param DatabaseConstructor - The better-sqlite3 Database constructor (injected to avoid top-level require)
27
+ */
28
+ constructor(dbPath: string, DatabaseConstructor: new (filename: string) => DatabaseType);
29
+ private extractEvidenceGrade;
30
+ insert(payload: string, timestamp: number): void;
31
+ getOldest(limit: number): StoredSignal[];
32
+ deleteById(id: number): void;
33
+ deleteOlderThan(cutoffMs: number): number;
34
+ deleteOldestN(n: number): void;
35
+ deleteExceedingRetries(maxRetries: number): void;
36
+ incrementRetry(id: number): void;
37
+ count(): number;
38
+ stats(): SignalStoreStats;
39
+ close(): void;
40
+ }
41
+ //# sourceMappingURL=SqliteStore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SqliteStore.d.ts","sourceRoot":"","sources":["../src/SqliteStore.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAGjF,OAAO,KAAK,EAAE,QAAQ,IAAI,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE/D,qBAAa,WAAY,YAAW,WAAW;IAC7C,OAAO,CAAC,EAAE,CAAe;IACzB,OAAO,CAAC,UAAU,CAAsC;IACxD,OAAO,CAAC,aAAa,CAAsC;IAC3D,OAAO,CAAC,cAAc,CAAsC;IAC5D,OAAO,CAAC,SAAS,CAAsC;IACvD,OAAO,CAAC,SAAS,CAAsC;IACvD,OAAO,CAAC,iBAAiB,CAAsC;IAC/D,OAAO,CAAC,kBAAkB,CAAsC;IAChE,OAAO,CAAC,oBAAoB,CAAsC;IAClE,OAAO,CAAC,SAAS,CAAsC;IACvD,OAAO,CAAC,UAAU,CAAsC;IAExD;;;OAGG;gBAED,MAAM,EAAE,MAAM,EACd,mBAAmB,EAAE,KAAK,QAAQ,EAAE,MAAM,KAAK,YAAY;IA4F7D,OAAO,CAAC,oBAAoB;IAW5B,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAKhD,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,EAAE;IAIxC,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAI5B,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;IAKzC,aAAa,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI;IAI9B,sBAAsB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAIhD,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAIhC,KAAK,IAAI,MAAM;IAKf,KAAK,IAAI,gBAAgB;IAoBzB,KAAK,IAAI,IAAI;CAGd"}
@@ -0,0 +1,162 @@
1
+ "use strict";
2
+ /**
3
+ * SqliteStore — High-performance signal store using better-sqlite3.
4
+ * Extracted from the original SignalBuffer implementation.
5
+ *
6
+ * WAL journal mode, prepared statements, evidence_grade column + index
7
+ * for priority-aware flushing (FACE_BACKED sent first).
8
+ *
9
+ * Only loaded when better-sqlite3 is available (optional dependency).
10
+ */
11
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
12
+ if (k2 === undefined) k2 = k;
13
+ var desc = Object.getOwnPropertyDescriptor(m, k);
14
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
15
+ desc = { enumerable: true, get: function() { return m[k]; } };
16
+ }
17
+ Object.defineProperty(o, k2, desc);
18
+ }) : (function(o, m, k, k2) {
19
+ if (k2 === undefined) k2 = k;
20
+ o[k2] = m[k];
21
+ }));
22
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
23
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
24
+ }) : function(o, v) {
25
+ o["default"] = v;
26
+ });
27
+ var __importStar = (this && this.__importStar) || function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ Object.defineProperty(exports, "__esModule", { value: true });
35
+ exports.SqliteStore = void 0;
36
+ const path = __importStar(require("path"));
37
+ const fs = __importStar(require("fs"));
38
+ class SqliteStore {
39
+ /**
40
+ * @param dbPath - Path to the SQLite database file
41
+ * @param DatabaseConstructor - The better-sqlite3 Database constructor (injected to avoid top-level require)
42
+ */
43
+ constructor(dbPath, DatabaseConstructor) {
44
+ const dir = path.dirname(dbPath);
45
+ if (!fs.existsSync(dir)) {
46
+ fs.mkdirSync(dir, { recursive: true });
47
+ }
48
+ this.db = new DatabaseConstructor(dbPath);
49
+ this.db.pragma('journal_mode = WAL');
50
+ this.db.pragma('synchronous = NORMAL');
51
+ this.db.exec(`
52
+ CREATE TABLE IF NOT EXISTS buffered_signals (
53
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
54
+ payload TEXT NOT NULL,
55
+ timestamp INTEGER NOT NULL DEFAULT (strftime('%s','now') * 1000),
56
+ retry_count INTEGER NOT NULL DEFAULT 0,
57
+ evidence_grade TEXT NOT NULL DEFAULT 'EMPTY'
58
+ )
59
+ `);
60
+ this.db.exec(`
61
+ CREATE INDEX IF NOT EXISTS idx_signals_timestamp ON buffered_signals(timestamp)
62
+ `);
63
+ this.db.exec(`
64
+ CREATE INDEX IF NOT EXISTS idx_signals_evidence_grade ON buffered_signals(evidence_grade)
65
+ `);
66
+ // Migrate existing rows that lack evidence_grade (from pre-0.2.2 databases)
67
+ try {
68
+ // Check if evidence_grade column exists by querying pragma
69
+ const columns = this.db
70
+ .prepare("PRAGMA table_info('buffered_signals')")
71
+ .all();
72
+ const hasGradeCol = columns.some((c) => c.name === 'evidence_grade');
73
+ if (!hasGradeCol) {
74
+ this.db.exec("ALTER TABLE buffered_signals ADD COLUMN evidence_grade TEXT NOT NULL DEFAULT 'EMPTY'");
75
+ this.db.exec("CREATE INDEX IF NOT EXISTS idx_signals_evidence_grade ON buffered_signals(evidence_grade)");
76
+ }
77
+ }
78
+ catch {
79
+ // Column already exists or migration not needed
80
+ }
81
+ // Prepared statements
82
+ this.insertStmt = this.db.prepare('INSERT INTO buffered_signals (payload, timestamp, retry_count, evidence_grade) VALUES (?, ?, 0, ?)');
83
+ this.getOldestStmt = this.db.prepare(`
84
+ SELECT id, payload, timestamp, retry_count as retryCount, evidence_grade as evidenceGrade
85
+ FROM buffered_signals
86
+ ORDER BY
87
+ CASE evidence_grade
88
+ WHEN 'FACE_BACKED' THEN 1
89
+ WHEN 'PERSON_BACKED' THEN 2
90
+ WHEN 'SPEECH_ONLY' THEN 3
91
+ WHEN 'PROXY_ONLY' THEN 4
92
+ ELSE 5
93
+ END,
94
+ timestamp ASC
95
+ LIMIT ?
96
+ `);
97
+ this.deleteByIdStmt = this.db.prepare('DELETE FROM buffered_signals WHERE id = ?');
98
+ this.countStmt = this.db.prepare('SELECT COUNT(*) as count FROM buffered_signals');
99
+ this.pruneStmt = this.db.prepare('DELETE FROM buffered_signals WHERE timestamp < ?');
100
+ this.deleteOldestNStmt = this.db.prepare('DELETE FROM buffered_signals WHERE id IN (SELECT id FROM buffered_signals ORDER BY timestamp ASC LIMIT ?)');
101
+ this.incrementRetryStmt = this.db.prepare('UPDATE buffered_signals SET retry_count = retry_count + 1 WHERE id = ?');
102
+ this.deleteMaxRetriesStmt = this.db.prepare('DELETE FROM buffered_signals WHERE retry_count >= ?');
103
+ this.statsStmt = this.db.prepare('SELECT evidence_grade as grade, COUNT(*) as cnt FROM buffered_signals GROUP BY evidence_grade');
104
+ this.oldestStmt = this.db.prepare('SELECT MIN(timestamp) as oldest FROM buffered_signals');
105
+ }
106
+ extractEvidenceGrade(payload) {
107
+ try {
108
+ const parsed = JSON.parse(payload);
109
+ return typeof parsed.evidenceGrade === 'string'
110
+ ? parsed.evidenceGrade
111
+ : 'EMPTY';
112
+ }
113
+ catch {
114
+ return 'EMPTY';
115
+ }
116
+ }
117
+ insert(payload, timestamp) {
118
+ const grade = this.extractEvidenceGrade(payload);
119
+ this.insertStmt.run(payload, timestamp, grade);
120
+ }
121
+ getOldest(limit) {
122
+ return this.getOldestStmt.all(limit);
123
+ }
124
+ deleteById(id) {
125
+ this.deleteByIdStmt.run(id);
126
+ }
127
+ deleteOlderThan(cutoffMs) {
128
+ const result = this.pruneStmt.run(cutoffMs);
129
+ return result.changes;
130
+ }
131
+ deleteOldestN(n) {
132
+ this.deleteOldestNStmt.run(n);
133
+ }
134
+ deleteExceedingRetries(maxRetries) {
135
+ this.deleteMaxRetriesStmt.run(maxRetries);
136
+ }
137
+ incrementRetry(id) {
138
+ this.incrementRetryStmt.run(id);
139
+ }
140
+ count() {
141
+ const row = this.countStmt.get();
142
+ return row.count;
143
+ }
144
+ stats() {
145
+ const rows = this.statsStmt.all();
146
+ const byGrade = {};
147
+ for (const row of rows) {
148
+ byGrade[row.grade] = row.cnt;
149
+ }
150
+ const oldestRow = this.oldestStmt.get();
151
+ return {
152
+ total: this.count(),
153
+ byEvidenceGrade: byGrade,
154
+ oldestTimestampMs: oldestRow.oldest,
155
+ };
156
+ }
157
+ close() {
158
+ this.db.close();
159
+ }
160
+ }
161
+ exports.SqliteStore = SqliteStore;
162
+ //# sourceMappingURL=SqliteStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SqliteStore.js","sourceRoot":"","sources":["../src/SqliteStore.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,99 @@
1
+ /**
2
+ * StatusServer — HTTP server exposing device status, health, and Prometheus metrics.
3
+ *
4
+ * Runs inside the EdgeAgent process on a configurable port (default 9090).
5
+ * Uses ONLY Node.js built-in `http` module — zero external dependencies.
6
+ *
7
+ * Endpoints:
8
+ * GET /status — Full JSON status snapshot
9
+ * GET /health — Simple health probe (200 OK / 503 degraded)
10
+ * GET /metrics — Prometheus-format text metrics
11
+ */
12
+ export interface StatusServerOptions {
13
+ /** HTTP listen port. Default: 9090 */
14
+ port?: number;
15
+ /** HTTP listen host. Default: '0.0.0.0' */
16
+ host?: string;
17
+ }
18
+ export interface StatusData {
19
+ /** Device fingerprint */
20
+ fingerprint: string;
21
+ /** Assigned screen ID, or null if unassigned */
22
+ screenId: string | null;
23
+ /** Capability tier (1-4) */
24
+ tier: number;
25
+ /** Platform string, e.g. 'linux x64' */
26
+ platform: string;
27
+ /** Seconds since agent start (computed on read) */
28
+ uptime: number;
29
+ /** SDK version string */
30
+ sdkVersion: string;
31
+ /** Health snapshot from SubsystemHealthRegistry.toHeartbeatPayload() */
32
+ subsystemHealth: Record<string, unknown>;
33
+ /** Current sensing mode, e.g. 'edge_onnx', 'cloud', 'proxy_only' */
34
+ sensingMode: string;
35
+ /** Current detected face count */
36
+ currentFaceCount: number;
37
+ /** Average attention score (0-1) */
38
+ avgAttention: number;
39
+ /** Weighted VAS score (0-1) */
40
+ avgVAS: number;
41
+ /** Evidence grade, e.g. 'FACE_BACKED' */
42
+ evidenceGrade: string;
43
+ /** Number of signals currently buffered */
44
+ signalBufferCount: number;
45
+ /** Maximum buffer capacity */
46
+ signalBufferCapacity: number;
47
+ /** Whether the Socket.io connection is live */
48
+ socketConnected: boolean;
49
+ /** Epoch ms of last signal emit */
50
+ lastSignalTimestamp: number;
51
+ /** Total RSS memory usage in MB */
52
+ memoryUsageMb: number;
53
+ /** V8 heap used in MB */
54
+ heapUsedMb: number;
55
+ /** List of loaded model names, e.g. ['blazeFace', 'yamnet'] */
56
+ modelsLoaded: string[];
57
+ /** ONNX execution provider, e.g. 'cpu', 'openvino' */
58
+ executionProvider: string;
59
+ /** Whether federated learning is enabled */
60
+ federatedEnabled: boolean;
61
+ /** Epoch ms of last gradient upload */
62
+ lastGradientUpload: number;
63
+ }
64
+ export declare class StatusServer {
65
+ private server;
66
+ private statusData;
67
+ private startTime;
68
+ private port;
69
+ private host;
70
+ constructor(options?: StatusServerOptions);
71
+ /**
72
+ * Merge partial updates into the status snapshot.
73
+ * Call this from EdgeAgent whenever subsystem state changes.
74
+ */
75
+ updateStatus(partial: Partial<StatusData>): void;
76
+ /**
77
+ * Start the HTTP server. Resolves once the server is listening.
78
+ * If the port is already in use, logs a warning and resolves without starting.
79
+ */
80
+ start(): Promise<void>;
81
+ /**
82
+ * Stop the HTTP server gracefully. Resolves once all connections are closed.
83
+ */
84
+ stop(): Promise<void>;
85
+ /**
86
+ * Get the current status snapshot with computed fields (uptime, memory).
87
+ * Also used by the status CLI command via the /status HTTP endpoint.
88
+ */
89
+ getStatus(): StatusData & {
90
+ uptime: number;
91
+ memoryUsageMb: number;
92
+ heapUsedMb: number;
93
+ };
94
+ private handleRequest;
95
+ private handleStatus;
96
+ private handleHealth;
97
+ private handleMetrics;
98
+ }
99
+ //# sourceMappingURL=StatusServer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StatusServer.d.ts","sourceRoot":"","sources":["../src/StatusServer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,MAAM,WAAW,mBAAmB;IAClC,sCAAsC;IACtC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,2CAA2C;IAC3C,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,UAAU;IAGzB,yBAAyB;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,gDAAgD;IAChD,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,4BAA4B;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,wCAAwC;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,mDAAmD;IACnD,MAAM,EAAE,MAAM,CAAC;IACf,yBAAyB;IACzB,UAAU,EAAE,MAAM,CAAC;IAInB,wEAAwE;IACxE,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAIzC,oEAAoE;IACpE,WAAW,EAAE,MAAM,CAAC;IACpB,kCAAkC;IAClC,gBAAgB,EAAE,MAAM,CAAC;IACzB,oCAAoC;IACpC,YAAY,EAAE,MAAM,CAAC;IACrB,+BAA+B;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,yCAAyC;IACzC,aAAa,EAAE,MAAM,CAAC;IAItB,2CAA2C;IAC3C,iBAAiB,EAAE,MAAM,CAAC;IAC1B,8BAA8B;IAC9B,oBAAoB,EAAE,MAAM,CAAC;IAI7B,+CAA+C;IAC/C,eAAe,EAAE,OAAO,CAAC;IACzB,mCAAmC;IACnC,mBAAmB,EAAE,MAAM,CAAC;IAI5B,mCAAmC;IACnC,aAAa,EAAE,MAAM,CAAC;IACtB,yBAAyB;IACzB,UAAU,EAAE,MAAM,CAAC;IAInB,+DAA+D;IAC/D,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,sDAAsD;IACtD,iBAAiB,EAAE,MAAM,CAAC;IAI1B,4CAA4C;IAC5C,gBAAgB,EAAE,OAAO,CAAC;IAC1B,uCAAuC;IACvC,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AA2BD,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,IAAI,CAAS;gBAET,OAAO,CAAC,EAAE,mBAAmB;IAOzC;;;OAGG;IACH,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,IAAI;IAIhD;;;OAGG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAkC5B;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAW3B;;;OAGG;IACH,SAAS,IAAI,UAAU,GAAG;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE;IAcvF,OAAO,CAAC,aAAa;IAgCrB,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,YAAY;IAoBpB,OAAO,CAAC,aAAa;CAyDtB"}