@advicenxt/sbp-server 0.1.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.
- package/benchmarks/bench.ts +272 -0
- package/dist/auth.d.ts +20 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +69 -0
- package/dist/auth.js.map +1 -0
- package/dist/blackboard.d.ts +84 -0
- package/dist/blackboard.d.ts.map +1 -0
- package/dist/blackboard.js +502 -0
- package/dist/blackboard.js.map +1 -0
- package/dist/cli.d.ts +7 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +102 -0
- package/dist/cli.js.map +1 -0
- package/dist/conditions.d.ts +27 -0
- package/dist/conditions.d.ts.map +1 -0
- package/dist/conditions.js +240 -0
- package/dist/conditions.js.map +1 -0
- package/dist/decay.d.ts +21 -0
- package/dist/decay.d.ts.map +1 -0
- package/dist/decay.js +88 -0
- package/dist/decay.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/rate-limiter.d.ts +21 -0
- package/dist/rate-limiter.d.ts.map +1 -0
- package/dist/rate-limiter.js +75 -0
- package/dist/rate-limiter.js.map +1 -0
- package/dist/server.d.ts +63 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +401 -0
- package/dist/server.js.map +1 -0
- package/dist/store.d.ts +54 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +55 -0
- package/dist/store.js.map +1 -0
- package/dist/types.d.ts +247 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +26 -0
- package/dist/types.js.map +1 -0
- package/dist/validation.d.ts +296 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +205 -0
- package/dist/validation.js.map +1 -0
- package/eslint.config.js +26 -0
- package/package.json +66 -0
- package/src/auth.ts +89 -0
- package/src/blackboard.test.ts +287 -0
- package/src/blackboard.ts +651 -0
- package/src/cli.ts +116 -0
- package/src/conditions.ts +305 -0
- package/src/conformance.test.ts +686 -0
- package/src/decay.ts +103 -0
- package/src/index.ts +24 -0
- package/src/rate-limiter.ts +104 -0
- package/src/server.integration.test.ts +436 -0
- package/src/server.ts +500 -0
- package/src/store.ts +108 -0
- package/src/types.ts +314 -0
- package/src/validation.ts +251 -0
- package/tsconfig.eslint.json +5 -0
- package/tsconfig.json +20 -0
package/dist/server.js
ADDED
|
@@ -0,0 +1,401 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SBP HTTP Server
|
|
3
|
+
* Streamable HTTP with SSE (following MCP transport patterns)
|
|
4
|
+
*/
|
|
5
|
+
import Fastify from "fastify";
|
|
6
|
+
import { Blackboard } from "./blackboard.js";
|
|
7
|
+
import { v7 as uuidv7 } from "uuid";
|
|
8
|
+
import { validateEnvelope, validateParams } from "./validation.js";
|
|
9
|
+
import { createAuthHook } from "./auth.js";
|
|
10
|
+
import { createRateLimitHook } from "./rate-limiter.js";
|
|
11
|
+
export class SbpServer {
|
|
12
|
+
app;
|
|
13
|
+
blackboard;
|
|
14
|
+
options;
|
|
15
|
+
sseClients = new Map();
|
|
16
|
+
sessions = new Map();
|
|
17
|
+
eventCounter = 0;
|
|
18
|
+
constructor(options = {}) {
|
|
19
|
+
this.options = {
|
|
20
|
+
port: options.port ?? 3000,
|
|
21
|
+
host: options.host ?? "localhost",
|
|
22
|
+
cors: options.cors ?? true,
|
|
23
|
+
logging: options.logging ?? false,
|
|
24
|
+
evaluationInterval: options.evaluationInterval ?? 100,
|
|
25
|
+
defaultDecay: options.defaultDecay ?? { type: "exponential", half_life_ms: 300000 },
|
|
26
|
+
defaultTtlFloor: options.defaultTtlFloor ?? 0.01,
|
|
27
|
+
maxPheromones: options.maxPheromones ?? 100000,
|
|
28
|
+
trackEmissionHistory: options.trackEmissionHistory ?? true,
|
|
29
|
+
emissionHistoryWindow: options.emissionHistoryWindow ?? 60000,
|
|
30
|
+
auth: options.auth,
|
|
31
|
+
rateLimit: options.rateLimit,
|
|
32
|
+
};
|
|
33
|
+
this.blackboard = new Blackboard(this.options);
|
|
34
|
+
this.app = Fastify({ logger: this.options.logging });
|
|
35
|
+
this.setupRoutes();
|
|
36
|
+
}
|
|
37
|
+
setupRoutes() {
|
|
38
|
+
// Authentication hook
|
|
39
|
+
if (this.options.auth?.requireAuth) {
|
|
40
|
+
this.app.addHook("onRequest", createAuthHook(this.options.auth));
|
|
41
|
+
}
|
|
42
|
+
// Rate limiting hook
|
|
43
|
+
if (this.options.rateLimit) {
|
|
44
|
+
this.app.addHook("onRequest", createRateLimitHook(this.options.rateLimit));
|
|
45
|
+
}
|
|
46
|
+
// CORS
|
|
47
|
+
if (this.options.cors) {
|
|
48
|
+
this.app.addHook("onRequest", async (request, reply) => {
|
|
49
|
+
reply.header("Access-Control-Allow-Origin", "*");
|
|
50
|
+
reply.header("Access-Control-Allow-Methods", "POST, GET, DELETE, OPTIONS");
|
|
51
|
+
reply.header("Access-Control-Allow-Headers", "Content-Type, Accept, Authorization, Sbp-Protocol-Version, Sbp-Session-Id, Sbp-Agent-Id, Last-Event-ID");
|
|
52
|
+
if (request.method === "OPTIONS") {
|
|
53
|
+
reply.status(204).send();
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
// Health check
|
|
58
|
+
this.app.get("/health", async () => {
|
|
59
|
+
const stats = this.blackboard.inspect({ include: ["stats"] });
|
|
60
|
+
return {
|
|
61
|
+
status: "ok",
|
|
62
|
+
version: "0.1.0",
|
|
63
|
+
transport: "streamable-http-sse",
|
|
64
|
+
...stats.stats,
|
|
65
|
+
};
|
|
66
|
+
});
|
|
67
|
+
// Main SBP endpoint - POST for client->server messages
|
|
68
|
+
this.app.post("/sbp", async (request, reply) => {
|
|
69
|
+
return this.handlePost(request, reply);
|
|
70
|
+
});
|
|
71
|
+
// Main SBP endpoint - GET for SSE stream (server->client)
|
|
72
|
+
this.app.get("/sbp", async (request, reply) => {
|
|
73
|
+
return this.handleSSE(request, reply);
|
|
74
|
+
});
|
|
75
|
+
// Legacy JSON-RPC endpoint (for backwards compatibility)
|
|
76
|
+
this.app.post("/rpc", async (request, reply) => {
|
|
77
|
+
const body = request.body;
|
|
78
|
+
const response = await this.handleRpc(body, request);
|
|
79
|
+
reply.header("Content-Type", "application/json");
|
|
80
|
+
return response;
|
|
81
|
+
});
|
|
82
|
+
// Convenience REST endpoints
|
|
83
|
+
this.app.post("/emit", async (request) => {
|
|
84
|
+
const params = request.body;
|
|
85
|
+
return this.blackboard.emit(params);
|
|
86
|
+
});
|
|
87
|
+
this.app.post("/sniff", async (request) => {
|
|
88
|
+
const params = request.body;
|
|
89
|
+
return this.blackboard.sniff(params);
|
|
90
|
+
});
|
|
91
|
+
this.app.post("/scents", async (request) => {
|
|
92
|
+
const params = request.body;
|
|
93
|
+
return this.blackboard.registerScent(params);
|
|
94
|
+
});
|
|
95
|
+
this.app.delete("/scents/:scent_id", async (request) => {
|
|
96
|
+
const { scent_id } = request.params;
|
|
97
|
+
return this.blackboard.deregisterScent({ scent_id });
|
|
98
|
+
});
|
|
99
|
+
this.app.get("/inspect", async (request) => {
|
|
100
|
+
const query = request.query;
|
|
101
|
+
const include = query.include?.split(",");
|
|
102
|
+
return this.blackboard.inspect({ include });
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Handle POST requests (client -> server messages)
|
|
107
|
+
*/
|
|
108
|
+
async handlePost(request, reply) {
|
|
109
|
+
// Validate JSON-RPC envelope
|
|
110
|
+
const envelopeResult = validateEnvelope(request.body);
|
|
111
|
+
if (!envelopeResult.ok) {
|
|
112
|
+
reply.header("Content-Type", "application/json");
|
|
113
|
+
return {
|
|
114
|
+
jsonrpc: "2.0",
|
|
115
|
+
id: null,
|
|
116
|
+
error: envelopeResult.error,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
const body = envelopeResult.request;
|
|
120
|
+
// Validate method-specific params
|
|
121
|
+
const paramsResult = validateParams(body.method, body.params);
|
|
122
|
+
if (!paramsResult.ok) {
|
|
123
|
+
reply.header("Content-Type", "application/json");
|
|
124
|
+
return {
|
|
125
|
+
jsonrpc: "2.0",
|
|
126
|
+
id: body.id,
|
|
127
|
+
error: paramsResult.error,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
// Replace params with validated (parsed) params
|
|
131
|
+
const validatedRequest = {
|
|
132
|
+
...body,
|
|
133
|
+
params: paramsResult.params,
|
|
134
|
+
};
|
|
135
|
+
// Get or create session
|
|
136
|
+
let sessionId = request.headers["sbp-session-id"];
|
|
137
|
+
if (!sessionId) {
|
|
138
|
+
sessionId = uuidv7();
|
|
139
|
+
this.sessions.set(sessionId, {
|
|
140
|
+
agentId: request.headers["sbp-agent-id"] || "unknown",
|
|
141
|
+
createdAt: Date.now(),
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
// Handle JSON-RPC request
|
|
145
|
+
const response = await this.handleRpc(validatedRequest, request);
|
|
146
|
+
// Set session header
|
|
147
|
+
reply.header("Sbp-Session-Id", sessionId);
|
|
148
|
+
reply.header("Content-Type", "application/json");
|
|
149
|
+
return response;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Handle GET requests - open SSE stream for triggers
|
|
153
|
+
*/
|
|
154
|
+
async handleSSE(request, reply) {
|
|
155
|
+
const accept = request.headers.accept || "";
|
|
156
|
+
if (!accept.includes("text/event-stream")) {
|
|
157
|
+
reply.status(406).send({ error: "Accept header must include text/event-stream" });
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
const sessionId = request.headers["sbp-session-id"] || uuidv7();
|
|
161
|
+
const lastEventId = request.headers["last-event-id"];
|
|
162
|
+
const clientId = uuidv7();
|
|
163
|
+
// Set up SSE headers
|
|
164
|
+
reply.raw.writeHead(200, {
|
|
165
|
+
"Content-Type": "text/event-stream",
|
|
166
|
+
"Cache-Control": "no-cache",
|
|
167
|
+
Connection: "keep-alive",
|
|
168
|
+
"Sbp-Session-Id": sessionId,
|
|
169
|
+
"Access-Control-Allow-Origin": "*",
|
|
170
|
+
});
|
|
171
|
+
// Register SSE client
|
|
172
|
+
const client = {
|
|
173
|
+
id: clientId,
|
|
174
|
+
sessionId,
|
|
175
|
+
reply,
|
|
176
|
+
scents: new Set(),
|
|
177
|
+
lastEventId: lastEventId ? parseInt(lastEventId, 10) : 0,
|
|
178
|
+
};
|
|
179
|
+
this.sseClients.set(clientId, client);
|
|
180
|
+
// Send initial connection event
|
|
181
|
+
this.sendSSEEvent(client, "connected", { client_id: clientId, session_id: sessionId });
|
|
182
|
+
// Handle client disconnect
|
|
183
|
+
request.raw.on("close", () => {
|
|
184
|
+
this.sseClients.delete(clientId);
|
|
185
|
+
// Unregister scent handlers for this client
|
|
186
|
+
for (const scentId of client.scents) {
|
|
187
|
+
this.blackboard.offTrigger(scentId);
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
// Keep connection alive with periodic comments
|
|
191
|
+
const keepAlive = setInterval(() => {
|
|
192
|
+
if (reply.raw.writable) {
|
|
193
|
+
reply.raw.write(": keepalive\n\n");
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
clearInterval(keepAlive);
|
|
197
|
+
}
|
|
198
|
+
}, 30000);
|
|
199
|
+
request.raw.on("close", () => clearInterval(keepAlive));
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Send an SSE event to a client
|
|
203
|
+
*/
|
|
204
|
+
sendSSEEvent(client, event, data) {
|
|
205
|
+
if (!client.reply.raw.writable)
|
|
206
|
+
return;
|
|
207
|
+
const eventId = ++this.eventCounter;
|
|
208
|
+
const payload = JSON.stringify(data);
|
|
209
|
+
client.reply.raw.write(`event: ${event}\n`);
|
|
210
|
+
client.reply.raw.write(`id: ${eventId}\n`);
|
|
211
|
+
client.reply.raw.write(`data: ${payload}\n\n`);
|
|
212
|
+
client.lastEventId = eventId;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Send a JSON-RPC notification via SSE
|
|
216
|
+
*/
|
|
217
|
+
sendSSENotification(client, method, params) {
|
|
218
|
+
const message = {
|
|
219
|
+
jsonrpc: "2.0",
|
|
220
|
+
method,
|
|
221
|
+
params,
|
|
222
|
+
};
|
|
223
|
+
this.sendSSEEvent(client, "message", message);
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Handle JSON-RPC requests
|
|
227
|
+
*/
|
|
228
|
+
async handleRpc(request, httpRequest) {
|
|
229
|
+
const { id, method, params } = request;
|
|
230
|
+
const sessionId = httpRequest.headers["sbp-session-id"];
|
|
231
|
+
try {
|
|
232
|
+
let result;
|
|
233
|
+
switch (method) {
|
|
234
|
+
case "sbp/emit":
|
|
235
|
+
result = this.blackboard.emit(params);
|
|
236
|
+
break;
|
|
237
|
+
case "sbp/sniff":
|
|
238
|
+
result = this.blackboard.sniff(params);
|
|
239
|
+
break;
|
|
240
|
+
case "sbp/register_scent": {
|
|
241
|
+
const scentParams = params;
|
|
242
|
+
result = this.blackboard.registerScent(scentParams);
|
|
243
|
+
// Set up trigger forwarding
|
|
244
|
+
if (sessionId) {
|
|
245
|
+
this.setupSSETrigger(scentParams.scent_id, sessionId);
|
|
246
|
+
}
|
|
247
|
+
// If agent_endpoint is provided, set up webhook delivery
|
|
248
|
+
if (scentParams.agent_endpoint) {
|
|
249
|
+
this.setupWebhookTrigger(scentParams.scent_id, scentParams.agent_endpoint);
|
|
250
|
+
}
|
|
251
|
+
break;
|
|
252
|
+
}
|
|
253
|
+
case "sbp/deregister_scent":
|
|
254
|
+
result = this.blackboard.deregisterScent(params);
|
|
255
|
+
break;
|
|
256
|
+
case "sbp/evaporate":
|
|
257
|
+
result = this.blackboard.evaporate(params);
|
|
258
|
+
break;
|
|
259
|
+
case "sbp/inspect":
|
|
260
|
+
result = this.blackboard.inspect(params);
|
|
261
|
+
break;
|
|
262
|
+
case "sbp/subscribe": {
|
|
263
|
+
// Subscribe to scent triggers (used after SSE stream is open)
|
|
264
|
+
const { scent_id } = params;
|
|
265
|
+
if (sessionId) {
|
|
266
|
+
this.setupSSETrigger(scent_id, sessionId);
|
|
267
|
+
// Mark scent subscription for all clients in this session
|
|
268
|
+
for (const client of this.sseClients.values()) {
|
|
269
|
+
if (client.sessionId === sessionId) {
|
|
270
|
+
client.scents.add(scent_id);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
result = { subscribed: scent_id };
|
|
275
|
+
break;
|
|
276
|
+
}
|
|
277
|
+
case "sbp/unsubscribe": {
|
|
278
|
+
const { scent_id } = params;
|
|
279
|
+
this.blackboard.offTrigger(scent_id);
|
|
280
|
+
// Remove from client scent sets
|
|
281
|
+
for (const client of this.sseClients.values()) {
|
|
282
|
+
if (client.sessionId === sessionId) {
|
|
283
|
+
client.scents.delete(scent_id);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
result = { unsubscribed: scent_id };
|
|
287
|
+
break;
|
|
288
|
+
}
|
|
289
|
+
default:
|
|
290
|
+
return {
|
|
291
|
+
jsonrpc: "2.0",
|
|
292
|
+
id,
|
|
293
|
+
error: {
|
|
294
|
+
code: -32601,
|
|
295
|
+
message: "Method not found",
|
|
296
|
+
data: { method },
|
|
297
|
+
},
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
return {
|
|
301
|
+
jsonrpc: "2.0",
|
|
302
|
+
id,
|
|
303
|
+
result,
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
catch (err) {
|
|
307
|
+
const error = err;
|
|
308
|
+
return {
|
|
309
|
+
jsonrpc: "2.0",
|
|
310
|
+
id,
|
|
311
|
+
error: {
|
|
312
|
+
code: -32603,
|
|
313
|
+
message: error.message,
|
|
314
|
+
},
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Set up trigger forwarding to SSE clients
|
|
320
|
+
*/
|
|
321
|
+
setupSSETrigger(scentId, sessionId) {
|
|
322
|
+
this.blackboard.onTrigger(scentId, async (payload) => {
|
|
323
|
+
// Send to all SSE clients in this session
|
|
324
|
+
for (const client of this.sseClients.values()) {
|
|
325
|
+
if (client.sessionId === sessionId || client.scents.has(scentId)) {
|
|
326
|
+
this.sendSSENotification(client, "sbp/trigger", payload);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Set up webhook trigger delivery to an agent endpoint
|
|
333
|
+
*/
|
|
334
|
+
setupWebhookTrigger(scentId, endpoint) {
|
|
335
|
+
this.blackboard.onTrigger(scentId, async (payload) => {
|
|
336
|
+
// Attempt webhook delivery with one retry
|
|
337
|
+
for (let attempt = 0; attempt < 2; attempt++) {
|
|
338
|
+
try {
|
|
339
|
+
const response = await fetch(endpoint, {
|
|
340
|
+
method: "POST",
|
|
341
|
+
headers: {
|
|
342
|
+
"Content-Type": "application/json",
|
|
343
|
+
"Sbp-Protocol-Version": "0.1",
|
|
344
|
+
},
|
|
345
|
+
body: JSON.stringify({
|
|
346
|
+
jsonrpc: "2.0",
|
|
347
|
+
method: "sbp/trigger",
|
|
348
|
+
params: payload,
|
|
349
|
+
}),
|
|
350
|
+
signal: AbortSignal.timeout(10000),
|
|
351
|
+
});
|
|
352
|
+
if (response.ok)
|
|
353
|
+
return; // Success
|
|
354
|
+
// Retry on 5xx
|
|
355
|
+
if (response.status >= 500 && attempt === 0) {
|
|
356
|
+
await new Promise((r) => setTimeout(r, 1000));
|
|
357
|
+
continue;
|
|
358
|
+
}
|
|
359
|
+
break; // Don't retry on 4xx
|
|
360
|
+
}
|
|
361
|
+
catch {
|
|
362
|
+
// Network error — retry once
|
|
363
|
+
if (attempt === 0) {
|
|
364
|
+
await new Promise((r) => setTimeout(r, 1000));
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
async start() {
|
|
371
|
+
// Start blackboard evaluation loop
|
|
372
|
+
this.blackboard.start();
|
|
373
|
+
// Start HTTP server
|
|
374
|
+
await this.app.listen({ port: this.options.port, host: this.options.host });
|
|
375
|
+
console.log(`[SBP] Server listening on http://${this.options.host}:${this.options.port}`);
|
|
376
|
+
console.log(`[SBP] Streamable HTTP endpoint: POST/GET ${this.address}/sbp`);
|
|
377
|
+
console.log(`[SBP] Transport: SSE (Server-Sent Events)`);
|
|
378
|
+
if (this.options.auth?.requireAuth) {
|
|
379
|
+
console.log(`[SBP] Authentication: API key required`);
|
|
380
|
+
}
|
|
381
|
+
if (this.options.rateLimit) {
|
|
382
|
+
console.log(`[SBP] Rate limiting: ${this.options.rateLimit.maxRequests ?? 1000} req/${(this.options.rateLimit.windowMs ?? 60000) / 1000}s`);
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
async stop() {
|
|
386
|
+
this.blackboard.stop();
|
|
387
|
+
// Close all SSE connections
|
|
388
|
+
for (const client of this.sseClients.values()) {
|
|
389
|
+
if (client.reply.raw.writable) {
|
|
390
|
+
client.reply.raw.end();
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
this.sseClients.clear();
|
|
394
|
+
await this.app.close();
|
|
395
|
+
console.log("[SBP] Server stopped");
|
|
396
|
+
}
|
|
397
|
+
get address() {
|
|
398
|
+
return `http://${this.options.host}:${this.options.port}`;
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,OAA0D,MAAM,SAAS,CAAC;AACjF,OAAO,EAAE,UAAU,EAAqB,MAAM,iBAAiB,CAAC;AAYhE,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,MAAM,CAAC;AACpC,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAE,cAAc,EAAoB,MAAM,WAAW,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAyB,MAAM,mBAAmB,CAAC;AAyB/E,MAAM,OAAO,SAAS;IACZ,GAAG,CAAkB;IACb,UAAU,CAAa;IAC/B,OAAO,CAGb;IACM,UAAU,GAAG,IAAI,GAAG,EAAqB,CAAC;IAC1C,QAAQ,GAAG,IAAI,GAAG,EAAkD,CAAC;IACrE,YAAY,GAAG,CAAC,CAAC;IAEzB,YAAY,UAAyB,EAAE;QACrC,IAAI,CAAC,OAAO,GAAG;YACb,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,IAAI;YAC1B,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,WAAW;YACjC,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,IAAI;YAC1B,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,KAAK;YACjC,kBAAkB,EAAE,OAAO,CAAC,kBAAkB,IAAI,GAAG;YACrD,YAAY,EAAE,OAAO,CAAC,YAAY,IAAI,EAAE,IAAI,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,EAAE;YACnF,eAAe,EAAE,OAAO,CAAC,eAAe,IAAI,IAAI;YAChD,aAAa,EAAE,OAAO,CAAC,aAAa,IAAI,MAAM;YAC9C,oBAAoB,EAAE,OAAO,CAAC,oBAAoB,IAAI,IAAI;YAC1D,qBAAqB,EAAE,OAAO,CAAC,qBAAqB,IAAI,KAAK;YAC7D,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,SAAS,EAAE,OAAO,CAAC,SAAS;SAC7B,CAAC;QAEF,IAAI,CAAC,UAAU,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC/C,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;QAErD,IAAI,CAAC,WAAW,EAAE,CAAC;IACrB,CAAC;IAEO,WAAW;QACjB,sBAAsB;QACtB,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,WAAW,EAAE,CAAC;YACnC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QACnE,CAAC;QAED,qBAAqB;QACrB,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;YAC3B,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;QAC7E,CAAC;QAED,OAAO;QACP,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YACtB,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;gBACrD,KAAK,CAAC,MAAM,CAAC,6BAA6B,EAAE,GAAG,CAAC,CAAC;gBACjD,KAAK,CAAC,MAAM,CAAC,8BAA8B,EAAE,4BAA4B,CAAC,CAAC;gBAC3E,KAAK,CAAC,MAAM,CACV,8BAA8B,EAC9B,wGAAwG,CACzG,CAAC;gBAEF,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;oBACjC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;gBAC3B,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC;QAED,eAAe;QACf,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE;YACjC,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YAC9D,OAAO;gBACL,MAAM,EAAE,IAAI;gBACZ,OAAO,EAAE,OAAO;gBAChB,SAAS,EAAE,qBAAqB;gBAChC,GAAG,KAAK,CAAC,KAAK;aACf,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,uDAAuD;QACvD,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,OAAuB,EAAE,KAAmB,EAAE,EAAE;YAC3E,OAAO,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;QAEH,0DAA0D;QAC1D,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,OAAuB,EAAE,KAAmB,EAAE,EAAE;YAC1E,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;QAEH,yDAAyD;QACzD,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,OAAuB,EAAE,KAAmB,EAAE,EAAE;YAC3E,MAAM,IAAI,GAAG,OAAO,CAAC,IAAsB,CAAC;YAC5C,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YACrD,KAAK,CAAC,MAAM,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAC;YACjD,OAAO,QAAQ,CAAC;QAClB,CAAC,CAAC,CAAC;QAEH,6BAA6B;QAC7B,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;YACvC,MAAM,MAAM,GAAG,OAAO,CAAC,IAAkB,CAAC;YAC1C,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;YACxC,MAAM,MAAM,GAAG,OAAO,CAAC,IAAmB,CAAC;YAC3C,OAAO,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;YACzC,MAAM,MAAM,GAAG,OAAO,CAAC,IAA2B,CAAC;YACnD,OAAO,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QAC/C,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,mBAAmB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;YACrD,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,MAA8B,CAAC;YAC5D,OAAO,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;QACvD,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;YACzC,MAAM,KAAK,GAAG,OAAO,CAAC,KAA6B,CAAC;YACpD,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,GAAG,CAA6B,CAAC;YACtE,OAAO,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;QAC9C,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,UAAU,CAAC,OAAuB,EAAE,KAAmB;QACnE,6BAA6B;QAC7B,MAAM,cAAc,GAAG,gBAAgB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACtD,IAAI,CAAC,cAAc,CAAC,EAAE,EAAE,CAAC;YACvB,KAAK,CAAC,MAAM,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAC;YACjD,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,EAAE,EAAE,IAAI;gBACR,KAAK,EAAE,cAAc,CAAC,KAAK;aAC5B,CAAC;QACJ,CAAC;QAED,MAAM,IAAI,GAAG,cAAc,CAAC,OAAO,CAAC;QAEpC,kCAAkC;QAClC,MAAM,YAAY,GAAG,cAAc,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QAC9D,IAAI,CAAC,YAAY,CAAC,EAAE,EAAE,CAAC;YACrB,KAAK,CAAC,MAAM,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAC;YACjD,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,EAAE,EAAE,IAAI,CAAC,EAAE;gBACX,KAAK,EAAE,YAAY,CAAC,KAAK;aAC1B,CAAC;QACJ,CAAC;QAED,gDAAgD;QAChD,MAAM,gBAAgB,GAAmB;YACvC,GAAG,IAAI;YACP,MAAM,EAAE,YAAY,CAAC,MAAM;SAC5B,CAAC;QAEF,wBAAwB;QACxB,IAAI,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,gBAAgB,CAAuB,CAAC;QACxE,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,SAAS,GAAG,MAAM,EAAE,CAAC;YACrB,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,EAAE;gBAC3B,OAAO,EAAG,OAAO,CAAC,OAAO,CAAC,cAAc,CAAY,IAAI,SAAS;gBACjE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;aACtB,CAAC,CAAC;QACL,CAAC;QAED,0BAA0B;QAC1B,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;QAEjE,qBAAqB;QACrB,KAAK,CAAC,MAAM,CAAC,gBAAgB,EAAE,SAAS,CAAC,CAAC;QAC1C,KAAK,CAAC,MAAM,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAC;QAEjD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,SAAS,CAAC,OAAuB,EAAE,KAAmB;QAClE,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC;QAE5C,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC;YAC1C,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,8CAA8C,EAAE,CAAC,CAAC;YAClF,OAAO;QACT,CAAC;QAED,MAAM,SAAS,GAAI,OAAO,CAAC,OAAO,CAAC,gBAAgB,CAAY,IAAI,MAAM,EAAE,CAAC;QAC5E,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,eAAe,CAAuB,CAAC;QAC3E,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAC;QAE1B,qBAAqB;QACrB,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE;YACvB,cAAc,EAAE,mBAAmB;YACnC,eAAe,EAAE,UAAU;YAC3B,UAAU,EAAE,YAAY;YACxB,gBAAgB,EAAE,SAAS;YAC3B,6BAA6B,EAAE,GAAG;SACnC,CAAC,CAAC;QAEH,sBAAsB;QACtB,MAAM,MAAM,GAAc;YACxB,EAAE,EAAE,QAAQ;YACZ,SAAS;YACT,KAAK;YACL,MAAM,EAAE,IAAI,GAAG,EAAE;YACjB,WAAW,EAAE,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;SACzD,CAAC;QACF,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAEtC,gCAAgC;QAChC,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,WAAW,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC,CAAC;QAEvF,2BAA2B;QAC3B,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;YAC3B,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YACjC,4CAA4C;YAC5C,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;gBACpC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;YACtC,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,+CAA+C;QAC/C,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE;YACjC,IAAI,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;gBACvB,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;YACrC,CAAC;iBAAM,CAAC;gBACN,aAAa,CAAC,SAAS,CAAC,CAAC;YAC3B,CAAC;QACH,CAAC,EAAE,KAAK,CAAC,CAAC;QAEV,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,CAAC;IAC1D,CAAC;IAED;;OAEG;IACK,YAAY,CAAC,MAAiB,EAAE,KAAa,EAAE,IAAa;QAClE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ;YAAE,OAAO;QAEvC,MAAM,OAAO,GAAG,EAAE,IAAI,CAAC,YAAY,CAAC;QACpC,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QAErC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC,CAAC;QAC5C,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,OAAO,IAAI,CAAC,CAAC;QAC3C,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,OAAO,MAAM,CAAC,CAAC;QAE/C,MAAM,CAAC,WAAW,GAAG,OAAO,CAAC;IAC/B,CAAC;IAED;;OAEG;IACK,mBAAmB,CAAC,MAAiB,EAAE,MAAc,EAAE,MAAe;QAC5E,MAAM,OAAO,GAAG;YACd,OAAO,EAAE,KAAK;YACd,MAAM;YACN,MAAM;SACP,CAAC;QACF,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IAChD,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,SAAS,CAAC,OAAuB,EAAE,WAA2B;QAC1E,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;QACvC,MAAM,SAAS,GAAG,WAAW,CAAC,OAAO,CAAC,gBAAgB,CAAuB,CAAC;QAE9E,IAAI,CAAC;YACH,IAAI,MAAe,CAAC;YAEpB,QAAQ,MAAM,EAAE,CAAC;gBACf,KAAK,UAAU;oBACb,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,MAAoB,CAAC,CAAC;oBACpD,MAAM;gBAER,KAAK,WAAW;oBACd,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,MAAqB,CAAC,CAAC;oBACtD,MAAM;gBAER,KAAK,oBAAoB,CAAC,CAAC,CAAC;oBAC1B,MAAM,WAAW,GAAG,MAA6B,CAAC;oBAClD,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,WAAW,CAAC,CAAC;oBAEpD,4BAA4B;oBAC5B,IAAI,SAAS,EAAE,CAAC;wBACd,IAAI,CAAC,eAAe,CAAC,WAAW,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;oBACxD,CAAC;oBAED,yDAAyD;oBACzD,IAAI,WAAW,CAAC,cAAc,EAAE,CAAC;wBAC/B,IAAI,CAAC,mBAAmB,CAAC,WAAW,CAAC,QAAQ,EAAE,WAAW,CAAC,cAAc,CAAC,CAAC;oBAC7E,CAAC;oBACD,MAAM;gBACR,CAAC;gBAED,KAAK,sBAAsB;oBACzB,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC,MAA+B,CAAC,CAAC;oBAC1E,MAAM;gBAER,KAAK,eAAe;oBAClB,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,MAAyB,CAAC,CAAC;oBAC9D,MAAM;gBAER,KAAK,aAAa;oBAChB,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,MAAuB,CAAC,CAAC;oBAC1D,MAAM;gBAER,KAAK,eAAe,CAAC,CAAC,CAAC;oBACrB,8DAA8D;oBAC9D,MAAM,EAAE,QAAQ,EAAE,GAAG,MAA8B,CAAC;oBACpD,IAAI,SAAS,EAAE,CAAC;wBACd,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;wBAC1C,0DAA0D;wBAC1D,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC;4BAC9C,IAAI,MAAM,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;gCACnC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;4BAC9B,CAAC;wBACH,CAAC;oBACH,CAAC;oBACD,MAAM,GAAG,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC;oBAClC,MAAM;gBACR,CAAC;gBAED,KAAK,iBAAiB,CAAC,CAAC,CAAC;oBACvB,MAAM,EAAE,QAAQ,EAAE,GAAG,MAA8B,CAAC;oBACpD,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;oBACrC,gCAAgC;oBAChC,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC;wBAC9C,IAAI,MAAM,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;4BACnC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;wBACjC,CAAC;oBACH,CAAC;oBACD,MAAM,GAAG,EAAE,YAAY,EAAE,QAAQ,EAAE,CAAC;oBACpC,MAAM;gBACR,CAAC;gBAED;oBACE,OAAO;wBACL,OAAO,EAAE,KAAK;wBACd,EAAE;wBACF,KAAK,EAAE;4BACL,IAAI,EAAE,CAAC,KAAK;4BACZ,OAAO,EAAE,kBAAkB;4BAC3B,IAAI,EAAE,EAAE,MAAM,EAAE;yBACjB;qBACF,CAAC;YACN,CAAC;YAED,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,EAAE;gBACF,MAAM;aACP,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,KAAK,GAAG,GAAY,CAAC;YAC3B,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,EAAE;gBACF,KAAK,EAAE;oBACL,IAAI,EAAE,CAAC,KAAK;oBACZ,OAAO,EAAE,KAAK,CAAC,OAAO;iBACvB;aACF,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;OAEG;IACK,eAAe,CAAC,OAAe,EAAE,SAAiB;QACxD,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,OAAO,EAAE,KAAK,EAAE,OAAuB,EAAE,EAAE;YACnE,0CAA0C;YAC1C,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC;gBAC9C,IAAI,MAAM,CAAC,SAAS,KAAK,SAAS,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;oBACjE,IAAI,CAAC,mBAAmB,CAAC,MAAM,EAAE,aAAa,EAAE,OAAO,CAAC,CAAC;gBAC3D,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACK,mBAAmB,CAAC,OAAe,EAAE,QAAgB;QAC3D,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,OAAO,EAAE,KAAK,EAAE,OAAuB,EAAE,EAAE;YACnE,0CAA0C;YAC1C,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC;gBAC7C,IAAI,CAAC;oBACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,QAAQ,EAAE;wBACrC,MAAM,EAAE,MAAM;wBACd,OAAO,EAAE;4BACP,cAAc,EAAE,kBAAkB;4BAClC,sBAAsB,EAAE,KAAK;yBAC9B;wBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;4BACnB,OAAO,EAAE,KAAK;4BACd,MAAM,EAAE,aAAa;4BACrB,MAAM,EAAE,OAAO;yBAChB,CAAC;wBACF,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC;qBACnC,CAAC,CAAC;oBAEH,IAAI,QAAQ,CAAC,EAAE;wBAAE,OAAO,CAAC,UAAU;oBAEnC,eAAe;oBACf,IAAI,QAAQ,CAAC,MAAM,IAAI,GAAG,IAAI,OAAO,KAAK,CAAC,EAAE,CAAC;wBAC5C,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;wBAC9C,SAAS;oBACX,CAAC;oBACD,MAAM,CAAC,qBAAqB;gBAC9B,CAAC;gBAAC,MAAM,CAAC;oBACP,6BAA6B;oBAC7B,IAAI,OAAO,KAAK,CAAC,EAAE,CAAC;wBAClB,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;oBAChD,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,KAAK;QACT,mCAAmC;QACnC,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;QAExB,oBAAoB;QACpB,MAAM,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QAE5E,OAAO,CAAC,GAAG,CAAC,oCAAoC,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QAC1F,OAAO,CAAC,GAAG,CAAC,4CAA4C,IAAI,CAAC,OAAO,MAAM,CAAC,CAAC;QAC5E,OAAO,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAC;QACzD,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,WAAW,EAAE,CAAC;YACnC,OAAO,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAC;QACxD,CAAC;QACD,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;YAC3B,OAAO,CAAC,GAAG,CAAC,wBAAwB,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,WAAW,IAAI,IAAI,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,QAAQ,IAAI,KAAK,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC;QAC9I,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAI;QACR,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;QAEvB,4BAA4B;QAC5B,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC;YAC9C,IAAI,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;gBAC9B,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;YACzB,CAAC;QACH,CAAC;QACD,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;QAExB,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;QACvB,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;IACtC,CAAC;IAED,IAAI,OAAO;QACT,OAAO,UAAU,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;IAC5D,CAAC;CACF"}
|
package/dist/store.d.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SBP Pheromone Store - Persistence Adapter Interface
|
|
3
|
+
*
|
|
4
|
+
* Abstraction layer for pluggable storage backends.
|
|
5
|
+
* Default implementation: MemoryStore (in-process Map).
|
|
6
|
+
*/
|
|
7
|
+
import type { Pheromone } from "./types.js";
|
|
8
|
+
/**
|
|
9
|
+
* Abstract storage interface for pheromones.
|
|
10
|
+
* Implementations MUST be synchronous-safe for the core Blackboard operations.
|
|
11
|
+
* Async-capable stores (Redis, SQLite) should pre-load into a local cache.
|
|
12
|
+
*/
|
|
13
|
+
export interface PheromoneStore {
|
|
14
|
+
/** Get a pheromone by ID. Returns undefined if not found. */
|
|
15
|
+
get(id: string): Pheromone | undefined;
|
|
16
|
+
/** Store or update a pheromone. */
|
|
17
|
+
set(id: string, pheromone: Pheromone): void;
|
|
18
|
+
/** Delete a pheromone by ID. Returns true if existed. */
|
|
19
|
+
delete(id: string): boolean;
|
|
20
|
+
/** Check if a pheromone exists. */
|
|
21
|
+
has(id: string): boolean;
|
|
22
|
+
/** Iterate over all stored pheromones. */
|
|
23
|
+
values(): IterableIterator<Pheromone>;
|
|
24
|
+
/** Iterate over all [id, pheromone] pairs. */
|
|
25
|
+
entries(): IterableIterator<[string, Pheromone]>;
|
|
26
|
+
/** Number of stored pheromones. */
|
|
27
|
+
readonly size: number;
|
|
28
|
+
/** Remove all pheromones. */
|
|
29
|
+
clear(): void;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* In-memory pheromone store backed by a Map.
|
|
33
|
+
* This is the default store and provides the fastest access.
|
|
34
|
+
* Data is lost on process restart — acceptable for ephemeral signals.
|
|
35
|
+
*/
|
|
36
|
+
export declare class MemoryStore implements PheromoneStore {
|
|
37
|
+
private data;
|
|
38
|
+
get(id: string): Pheromone | undefined;
|
|
39
|
+
set(id: string, pheromone: Pheromone): void;
|
|
40
|
+
delete(id: string): boolean;
|
|
41
|
+
has(id: string): boolean;
|
|
42
|
+
values(): IterableIterator<Pheromone>;
|
|
43
|
+
entries(): IterableIterator<[string, Pheromone]>;
|
|
44
|
+
get size(): number;
|
|
45
|
+
clear(): void;
|
|
46
|
+
}
|
|
47
|
+
export type StoreType = "memory";
|
|
48
|
+
/**
|
|
49
|
+
* Create a pheromone store of the specified type.
|
|
50
|
+
* Currently only "memory" is built-in. Additional stores (Redis, SQLite)
|
|
51
|
+
* can be added by implementing the PheromoneStore interface.
|
|
52
|
+
*/
|
|
53
|
+
export declare function createStore(type?: StoreType): PheromoneStore;
|
|
54
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAM5C;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC3B,6DAA6D;IAC7D,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAAC;IAEvC,mCAAmC;IACnC,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,GAAG,IAAI,CAAC;IAE5C,yDAAyD;IACzD,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;IAE5B,mCAAmC;IACnC,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;IAEzB,0CAA0C;IAC1C,MAAM,IAAI,gBAAgB,CAAC,SAAS,CAAC,CAAC;IAEtC,8CAA8C;IAC9C,OAAO,IAAI,gBAAgB,CAAC,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;IAEjD,mCAAmC;IACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,6BAA6B;IAC7B,KAAK,IAAI,IAAI,CAAC;CACjB;AAMD;;;;GAIG;AACH,qBAAa,WAAY,YAAW,cAAc;IAC9C,OAAO,CAAC,IAAI,CAAgC;IAE5C,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS;IAItC,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,GAAG,IAAI;IAI3C,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAI3B,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAIxB,MAAM,IAAI,gBAAgB,CAAC,SAAS,CAAC;IAIrC,OAAO,IAAI,gBAAgB,CAAC,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAIhD,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,KAAK,IAAI,IAAI;CAGhB;AAMD,MAAM,MAAM,SAAS,GAAG,QAAQ,CAAC;AAEjC;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,IAAI,GAAE,SAAoB,GAAG,cAAc,CAOtE"}
|
package/dist/store.js
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SBP Pheromone Store - Persistence Adapter Interface
|
|
3
|
+
*
|
|
4
|
+
* Abstraction layer for pluggable storage backends.
|
|
5
|
+
* Default implementation: MemoryStore (in-process Map).
|
|
6
|
+
*/
|
|
7
|
+
// ============================================================================
|
|
8
|
+
// MEMORY STORE
|
|
9
|
+
// ============================================================================
|
|
10
|
+
/**
|
|
11
|
+
* In-memory pheromone store backed by a Map.
|
|
12
|
+
* This is the default store and provides the fastest access.
|
|
13
|
+
* Data is lost on process restart — acceptable for ephemeral signals.
|
|
14
|
+
*/
|
|
15
|
+
export class MemoryStore {
|
|
16
|
+
data = new Map();
|
|
17
|
+
get(id) {
|
|
18
|
+
return this.data.get(id);
|
|
19
|
+
}
|
|
20
|
+
set(id, pheromone) {
|
|
21
|
+
this.data.set(id, pheromone);
|
|
22
|
+
}
|
|
23
|
+
delete(id) {
|
|
24
|
+
return this.data.delete(id);
|
|
25
|
+
}
|
|
26
|
+
has(id) {
|
|
27
|
+
return this.data.has(id);
|
|
28
|
+
}
|
|
29
|
+
values() {
|
|
30
|
+
return this.data.values();
|
|
31
|
+
}
|
|
32
|
+
entries() {
|
|
33
|
+
return this.data.entries();
|
|
34
|
+
}
|
|
35
|
+
get size() {
|
|
36
|
+
return this.data.size;
|
|
37
|
+
}
|
|
38
|
+
clear() {
|
|
39
|
+
this.data.clear();
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Create a pheromone store of the specified type.
|
|
44
|
+
* Currently only "memory" is built-in. Additional stores (Redis, SQLite)
|
|
45
|
+
* can be added by implementing the PheromoneStore interface.
|
|
46
|
+
*/
|
|
47
|
+
export function createStore(type = "memory") {
|
|
48
|
+
switch (type) {
|
|
49
|
+
case "memory":
|
|
50
|
+
return new MemoryStore();
|
|
51
|
+
default:
|
|
52
|
+
throw new Error(`Unknown store type: ${type}`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAuCH,+EAA+E;AAC/E,eAAe;AACf,+EAA+E;AAE/E;;;;GAIG;AACH,MAAM,OAAO,WAAW;IACZ,IAAI,GAAG,IAAI,GAAG,EAAqB,CAAC;IAE5C,GAAG,CAAC,EAAU;QACV,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC7B,CAAC;IAED,GAAG,CAAC,EAAU,EAAE,SAAoB;QAChC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;IACjC,CAAC;IAED,MAAM,CAAC,EAAU;QACb,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAChC,CAAC;IAED,GAAG,CAAC,EAAU;QACV,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC7B,CAAC;IAED,MAAM;QACF,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;IAC9B,CAAC;IAED,OAAO;QACH,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;IAC/B,CAAC;IAED,IAAI,IAAI;QACJ,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;IAC1B,CAAC;IAED,KAAK;QACD,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;IACtB,CAAC;CACJ;AAQD;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,OAAkB,QAAQ;IAClD,QAAQ,IAAI,EAAE,CAAC;QACX,KAAK,QAAQ;YACT,OAAO,IAAI,WAAW,EAAE,CAAC;QAC7B;YACI,MAAM,IAAI,KAAK,CAAC,uBAAuB,IAAI,EAAE,CAAC,CAAC;IACvD,CAAC;AACL,CAAC"}
|