@yuihub/server 1.0.0-beta.10

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 (119) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +62 -0
  3. package/dist/api/text-process.d.ts +2 -0
  4. package/dist/api/text-process.d.ts.map +1 -0
  5. package/dist/api/text-process.js +48 -0
  6. package/dist/api/text-process.js.map +1 -0
  7. package/dist/auth.d.ts +30 -0
  8. package/dist/auth.d.ts.map +1 -0
  9. package/dist/auth.js +71 -0
  10. package/dist/auth.js.map +1 -0
  11. package/dist/cli/setup.d.ts +2 -0
  12. package/dist/cli/setup.d.ts.map +1 -0
  13. package/dist/cli/setup.js +120 -0
  14. package/dist/cli/setup.js.map +1 -0
  15. package/dist/config/schema.d.ts +334 -0
  16. package/dist/config/schema.d.ts.map +1 -0
  17. package/dist/config/schema.js +45 -0
  18. package/dist/config/schema.js.map +1 -0
  19. package/dist/config/service.d.ts +12 -0
  20. package/dist/config/service.d.ts.map +1 -0
  21. package/dist/config/service.js +81 -0
  22. package/dist/config/service.js.map +1 -0
  23. package/dist/engine/agent/context.d.ts +35 -0
  24. package/dist/engine/agent/context.d.ts.map +1 -0
  25. package/dist/engine/agent/context.js +72 -0
  26. package/dist/engine/agent/context.js.map +1 -0
  27. package/dist/engine/agent/core.d.ts +19 -0
  28. package/dist/engine/agent/core.d.ts.map +1 -0
  29. package/dist/engine/agent/core.js +67 -0
  30. package/dist/engine/agent/core.js.map +1 -0
  31. package/dist/engine/agent/live-context.d.ts +8 -0
  32. package/dist/engine/agent/live-context.d.ts.map +1 -0
  33. package/dist/engine/agent/live-context.js +19 -0
  34. package/dist/engine/agent/live-context.js.map +1 -0
  35. package/dist/engine/agent/tools/fs.d.ts +16 -0
  36. package/dist/engine/agent/tools/fs.d.ts.map +1 -0
  37. package/dist/engine/agent/tools/fs.js +78 -0
  38. package/dist/engine/agent/tools/fs.js.map +1 -0
  39. package/dist/engine/agent/tools/memory.d.ts +18 -0
  40. package/dist/engine/agent/tools/memory.d.ts.map +1 -0
  41. package/dist/engine/agent/tools/memory.js +51 -0
  42. package/dist/engine/agent/tools/memory.js.map +1 -0
  43. package/dist/engine/ai/local-genai-service.d.ts +22 -0
  44. package/dist/engine/ai/local-genai-service.d.ts.map +1 -0
  45. package/dist/engine/ai/local-genai-service.js +158 -0
  46. package/dist/engine/ai/local-genai-service.js.map +1 -0
  47. package/dist/engine/ai/registry.d.ts +16 -0
  48. package/dist/engine/ai/registry.d.ts.map +1 -0
  49. package/dist/engine/ai/registry.js +78 -0
  50. package/dist/engine/ai/registry.js.map +1 -0
  51. package/dist/engine/ai/tools.d.ts +7 -0
  52. package/dist/engine/ai/tools.d.ts.map +1 -0
  53. package/dist/engine/ai/tools.js +2 -0
  54. package/dist/engine/ai/tools.js.map +1 -0
  55. package/dist/engine/ai/types.d.ts +21 -0
  56. package/dist/engine/ai/types.d.ts.map +1 -0
  57. package/dist/engine/ai/types.js +2 -0
  58. package/dist/engine/ai/types.js.map +1 -0
  59. package/dist/engine/ai/vertex-genai-service.d.ts +13 -0
  60. package/dist/engine/ai/vertex-genai-service.d.ts.map +1 -0
  61. package/dist/engine/ai/vertex-genai-service.js +93 -0
  62. package/dist/engine/ai/vertex-genai-service.js.map +1 -0
  63. package/dist/engine/chunker.d.ts +19 -0
  64. package/dist/engine/chunker.d.ts.map +1 -0
  65. package/dist/engine/chunker.js +79 -0
  66. package/dist/engine/chunker.js.map +1 -0
  67. package/dist/engine/composite-vector-store.d.ts +21 -0
  68. package/dist/engine/composite-vector-store.d.ts.map +1 -0
  69. package/dist/engine/composite-vector-store.js +69 -0
  70. package/dist/engine/composite-vector-store.js.map +1 -0
  71. package/dist/engine/embeddings/local-service.d.ts +10 -0
  72. package/dist/engine/embeddings/local-service.d.ts.map +1 -0
  73. package/dist/engine/embeddings/local-service.js +37 -0
  74. package/dist/engine/embeddings/local-service.js.map +1 -0
  75. package/dist/engine/embeddings/types.d.ts +10 -0
  76. package/dist/engine/embeddings/types.d.ts.map +1 -0
  77. package/dist/engine/embeddings/types.js +2 -0
  78. package/dist/engine/embeddings/types.js.map +1 -0
  79. package/dist/engine/embeddings/vertex-service.d.ts +11 -0
  80. package/dist/engine/embeddings/vertex-service.d.ts.map +1 -0
  81. package/dist/engine/embeddings/vertex-service.js +45 -0
  82. package/dist/engine/embeddings/vertex-service.js.map +1 -0
  83. package/dist/engine/indexer.d.ts +12 -0
  84. package/dist/engine/indexer.d.ts.map +1 -0
  85. package/dist/engine/indexer.js +74 -0
  86. package/dist/engine/indexer.js.map +1 -0
  87. package/dist/engine/lock.d.ts +24 -0
  88. package/dist/engine/lock.d.ts.map +1 -0
  89. package/dist/engine/lock.js +58 -0
  90. package/dist/engine/lock.js.map +1 -0
  91. package/dist/engine/schema.d.ts +19 -0
  92. package/dist/engine/schema.d.ts.map +1 -0
  93. package/dist/engine/schema.js +18 -0
  94. package/dist/engine/schema.js.map +1 -0
  95. package/dist/engine/vector-store-types.d.ts +24 -0
  96. package/dist/engine/vector-store-types.d.ts.map +1 -0
  97. package/dist/engine/vector-store-types.js +2 -0
  98. package/dist/engine/vector-store-types.js.map +1 -0
  99. package/dist/engine/vector-store.d.ts +21 -0
  100. package/dist/engine/vector-store.d.ts.map +1 -0
  101. package/dist/engine/vector-store.js +105 -0
  102. package/dist/engine/vector-store.js.map +1 -0
  103. package/dist/engine/watcher.d.ts +16 -0
  104. package/dist/engine/watcher.d.ts.map +1 -0
  105. package/dist/engine/watcher.js +94 -0
  106. package/dist/engine/watcher.js.map +1 -0
  107. package/dist/server.d.ts +3 -0
  108. package/dist/server.d.ts.map +1 -0
  109. package/dist/server.js +361 -0
  110. package/dist/server.js.map +1 -0
  111. package/dist/sync/github-provider.d.ts +20 -0
  112. package/dist/sync/github-provider.d.ts.map +1 -0
  113. package/dist/sync/github-provider.js +80 -0
  114. package/dist/sync/github-provider.js.map +1 -0
  115. package/dist/sync/scheduler.d.ts +18 -0
  116. package/dist/sync/scheduler.d.ts.map +1 -0
  117. package/dist/sync/scheduler.js +67 -0
  118. package/dist/sync/scheduler.js.map +1 -0
  119. package/package.json +78 -0
package/dist/server.js ADDED
@@ -0,0 +1,361 @@
1
+ #!/usr/bin/env node
2
+ import Fastify from 'fastify';
3
+ import { serializerCompiler, validatorCompiler } from 'fastify-type-provider-zod';
4
+ import rateLimit from '@fastify/rate-limit';
5
+ import bearerAuth from '@fastify/bearer-auth';
6
+ import z from 'zod';
7
+ import { LanceVectorStore } from './engine/vector-store.js';
8
+ import { CompositeVectorStore } from './engine/composite-vector-store.js';
9
+ import { Indexer } from './engine/indexer.js';
10
+ import { SafeWatcher } from './engine/watcher.js';
11
+ import { withWriteLock, withReadLock, withRetry } from './engine/lock.js';
12
+ import { extractTerms } from './api/text-process.js';
13
+ import { GitHubSyncProvider } from './sync/github-provider.js';
14
+ import { SyncScheduler } from './sync/scheduler.js';
15
+ import { ConfigService } from './config/service.js';
16
+ import { AppConfigUpdateSchema } from './config/schema.js';
17
+ import { AIProviderRegistry } from './engine/ai/registry.js';
18
+ import path from 'path';
19
+ import fs from 'fs-extra';
20
+ import { randomUUID } from 'crypto';
21
+ import os from 'os';
22
+ import { ulid } from 'ulid';
23
+ import { initAuth } from './auth.js';
24
+ const server = Fastify({
25
+ logger: true
26
+ }).withTypeProvider();
27
+ // Zod Type Provider Setup
28
+ server.setValidatorCompiler(validatorCompiler);
29
+ server.setSerializerCompiler(serializerCompiler);
30
+ // --- Config & Engine Setup ---
31
+ const workspaceRoot = path.resolve(process.cwd(), '../../../');
32
+ const DEFAULT_DATA_DIR = path.join(os.homedir(), '.yuihub');
33
+ const DATA_DIR = process.env.DATA_DIR || DEFAULT_DATA_DIR;
34
+ const STORAGE_VERSION = '1.0.0-rc1';
35
+ // 1. Initialize Config Service
36
+ const configService = new ConfigService(DATA_DIR);
37
+ let config = configService.get();
38
+ // 2. Initialize AI Registry & Services
39
+ const aiRegistry = new AIProviderRegistry(config.ai);
40
+ // Initialize Composite Vector Store (Dual Embedding)
41
+ const embeddingServices = await aiRegistry.getAllEmbeddingServices();
42
+ if (embeddingServices.length === 0) {
43
+ throw new Error('No embedding services configured or initialized.');
44
+ }
45
+ const stores = embeddingServices.map(({ id, service }) => {
46
+ // Store name = provider id (e.g. 'local', 'vertex')
47
+ // Table name defaults to `entries_${id}` inside LanceVectorStore
48
+ return new LanceVectorStore(DATA_DIR, service, id);
49
+ });
50
+ console.log(`[AI] Initialized ${stores.length} Vector Stores: ${stores.map(s => s.name).join(', ')}`);
51
+ const vectorStore = new CompositeVectorStore(stores);
52
+ await vectorStore.init(); // Init all underlying stores
53
+ const indexer = new Indexer(vectorStore);
54
+ const watcher = new SafeWatcher(indexer);
55
+ // 3. Sync Setup
56
+ const syncProvider = new GitHubSyncProvider(DATA_DIR);
57
+ const syncScheduler = new SyncScheduler(syncProvider, config.sync.interval);
58
+ // --- Security (File-based Handshake) ---
59
+ const authData = await initAuth(DATA_DIR);
60
+ const AUTH_TOKEN = process.env.YUIHUB_TOKEN || authData.token;
61
+ console.log(`[Auth] Token initialized (file-based handshake)`);
62
+ server.register(rateLimit, {
63
+ max: 100,
64
+ timeWindow: '1 minute'
65
+ });
66
+ server.register(bearerAuth, {
67
+ keys: new Set([AUTH_TOKEN]),
68
+ errorResponse: (err) => {
69
+ return { error: 'Unauthorized', message: err.message };
70
+ }
71
+ });
72
+ // --- API Schema ---
73
+ const SaveBodySchema = z.object({
74
+ entries: z.array(z.object({
75
+ id: z.string().optional(),
76
+ text: z.string(),
77
+ mode: z.enum(['private', 'public']),
78
+ tags: z.array(z.string()).optional(),
79
+ session_id: z.string().optional(),
80
+ source: z.string().optional()
81
+ }))
82
+ });
83
+ const SearchQuerySchema = z.object({
84
+ q: z.string(),
85
+ limit: z.coerce.number().optional().default(10),
86
+ tag: z.string().optional(),
87
+ session: z.string().optional()
88
+ });
89
+ const ExportQuerySchema = z.object({
90
+ q: z.string().optional(), // Intent
91
+ session: z.string().optional()
92
+ });
93
+ const ConfigUpdateSchema = AppConfigUpdateSchema;
94
+ // --- Lifecycle ---
95
+ server.addHook('onReady', async () => {
96
+ server.log.info({ config: configService.get() }, 'Initializing Engine with Config...');
97
+ // Storage Version Check
98
+ const versionPath = path.join(DATA_DIR, 'VERSION');
99
+ if (config.sync.enabled || await fs.pathExists(versionPath)) {
100
+ // If sync enabled or version file exists, check it.
101
+ if (await fs.pathExists(versionPath)) {
102
+ const version = (await fs.readFile(versionPath, 'utf-8')).trim();
103
+ if (version !== STORAGE_VERSION) {
104
+ server.log.warn(`⚠️ Storage Version Mismatch! Expected ${STORAGE_VERSION}, found ${version}. Compatibility issues may occur.`);
105
+ }
106
+ }
107
+ else {
108
+ // If no version file but data exists... write it? or warn?
109
+ // Write it for now to migrate.
110
+ await fs.writeFile(versionPath, STORAGE_VERSION);
111
+ }
112
+ }
113
+ await vectorStore.init();
114
+ server.log.info('Engine initialized.');
115
+ // Start Watcher
116
+ const notesDir = path.join(DATA_DIR, 'notes');
117
+ await fs.ensureDir(notesDir);
118
+ watcher.start(notesDir);
119
+ // Initialize & Start Sync if Enabled
120
+ if (config.sync.enabled) {
121
+ server.log.info('Initializing Sync...');
122
+ await syncProvider.init(config.sync.remoteUrl);
123
+ syncScheduler.start();
124
+ }
125
+ // Bootstrap Indexing: If DB empty but files exist, scan!
126
+ if (await vectorStore.isEmpty()) {
127
+ const hasFiles = await fs.pathExists(notesDir) && (await fs.readdir(notesDir)).length > 0;
128
+ if (hasFiles) {
129
+ server.log.info('🚀 Empty Index detected with existing notes. Starting Initial Scan...');
130
+ // Don't await scan fully to allow server start? Or await?
131
+ // Await is safer to ensure index is ready.
132
+ await watcher.scan(notesDir);
133
+ server.log.info('✅ Initial Scan queued.');
134
+ }
135
+ }
136
+ });
137
+ server.addHook('onClose', async () => {
138
+ server.log.info('Shutting down...');
139
+ await watcher.close();
140
+ syncScheduler.stop();
141
+ });
142
+ // --- Endpoints ---
143
+ server.get('/health', async () => {
144
+ return { status: 'ok', version: 'v1' };
145
+ });
146
+ // System API: Get Config
147
+ server.get('/system/config', async () => {
148
+ return { ok: true, config: configService.get() };
149
+ });
150
+ // System API: Update Config (Hot Reload-ish)
151
+ server.patch('/system/config', {
152
+ schema: {
153
+ body: ConfigUpdateSchema
154
+ }
155
+ }, async (req, reply) => {
156
+ try {
157
+ const body = req.body;
158
+ const newConfig = await configService.update(body);
159
+ config = newConfig; // Update local ref
160
+ // Apply specific changes dynamically
161
+ if (body.sync) {
162
+ if (newConfig.sync.enabled && !syncScheduler['isSchedulerActive']) {
163
+ // If enabled and not running, start
164
+ // Re-init provider if remote url changed?
165
+ if (body.sync.remoteUrl)
166
+ await syncProvider.init(newConfig.sync.remoteUrl);
167
+ syncScheduler.start();
168
+ }
169
+ else if (!newConfig.sync.enabled) {
170
+ syncScheduler.stop();
171
+ }
172
+ // Update interval if changed
173
+ if (body.sync.interval) {
174
+ syncScheduler.updateInterval(newConfig.sync.interval);
175
+ }
176
+ }
177
+ // Note: Deep reconfiguration (e.g. port change, model change) might require restart.
178
+ // For now we just return the new config.
179
+ return { ok: true, config: newConfig, message: 'Config updated. Some changes may require restart.' };
180
+ }
181
+ catch (err) {
182
+ server.log.error(err);
183
+ reply.code(500);
184
+ return { ok: false, error: err.message };
185
+ }
186
+ });
187
+ // 1. SAVE Endpoint
188
+ server.post('/save', {
189
+ schema: {
190
+ body: SaveBodySchema
191
+ }
192
+ }, async (req, reply) => {
193
+ const { entries } = req.body;
194
+ // Write Lock with Retry for LanceDB safety
195
+ try {
196
+ await withWriteLock(() => withRetry(async () => {
197
+ // Process each entry
198
+ for (const entry of entries) {
199
+ // Enhanced Logic: Japanese Terms Extraction
200
+ const extractedTerms = extractTerms(entry.text);
201
+ const tags = new Set([...(entry.tags || []), ...extractedTerms]);
202
+ const finalEntry = {
203
+ ...entry,
204
+ id: entry.id || randomUUID(), // Generate ID if atomic entry
205
+ tags: Array.from(tags),
206
+ date: new Date().toISOString()
207
+ };
208
+ // Physical Save (Markdown)
209
+ const filename = finalEntry.session_id ? `${finalEntry.session_id}.md` : `entry-${finalEntry.id}.md`;
210
+ const filePath = path.join(DATA_DIR, 'notes', filename);
211
+ const fileContent = `\n\n---\nid: ${finalEntry.id}\ndate: ${finalEntry.date}\ntags: [${finalEntry.tags.join(', ')}]\n---\n\n${finalEntry.text}`;
212
+ await fs.appendFile(filePath, fileContent);
213
+ }
214
+ }));
215
+ // Lock released, Watcher picks up changes.
216
+ return { ok: true, count: entries.length };
217
+ }
218
+ catch (err) {
219
+ server.log.error(err);
220
+ reply.code(500);
221
+ return { ok: false, error: 'Save failed' };
222
+ }
223
+ });
224
+ // 2. SEARCH Endpoint (Read Lock)
225
+ server.get('/search', {
226
+ schema: {
227
+ querystring: SearchQuerySchema
228
+ }
229
+ }, async (req, reply) => {
230
+ const { q, limit, tag, session } = req.query;
231
+ const results = await withReadLock(() => vectorStore.search(q, limit, { tag, session }));
232
+ return { ok: true, results };
233
+ });
234
+ // 3. TRIGGER Endpoint (Mock / Private Mode)
235
+ server.post('/trigger', async (req, reply) => {
236
+ // Logic: In Private Mode, we don't send to external agent actually.
237
+ // We just return OK.
238
+ return { ok: true, ref: 'mock-private-ref', status: 'ignored_in_private_mode' };
239
+ });
240
+ // --- MCP Support Endpoints ---
241
+ // 3.1 THREADS/NEW - Create new session
242
+ const ThreadsNewSchema = z.object({
243
+ title: z.string().optional()
244
+ });
245
+ server.post('/threads/new', {
246
+ schema: { body: ThreadsNewSchema }
247
+ }, async (req, reply) => {
248
+ const { title } = req.body;
249
+ const session = {
250
+ id: `th-${ulid()}`,
251
+ title: title || `Session ${new Date().toLocaleDateString()}`,
252
+ created_at: new Date().toISOString()
253
+ };
254
+ return { ok: true, session };
255
+ });
256
+ // 3.2 CHECKPOINTS - Create decision checkpoint
257
+ const CheckpointSchema = z.object({
258
+ session_id: z.string(),
259
+ summary: z.string(),
260
+ intent: z.string(),
261
+ working_memory: z.record(z.unknown()).optional(),
262
+ entry_ids: z.array(z.string()).optional()
263
+ });
264
+ server.post('/checkpoints', {
265
+ schema: { body: CheckpointSchema }
266
+ }, async (req, reply) => {
267
+ const { session_id, summary, intent, working_memory, entry_ids } = req.body;
268
+ const checkpoint = {
269
+ id: `cp-${ulid()}`,
270
+ session_id,
271
+ snapshot: {
272
+ working_memory: JSON.stringify(working_memory || {}),
273
+ decision_rationale: summary
274
+ },
275
+ intent,
276
+ entry_ids: entry_ids || [],
277
+ created_at: new Date().toISOString()
278
+ };
279
+ // Write Lock with Retry for file safety
280
+ await withWriteLock(() => withRetry(async () => {
281
+ const checkpointDir = path.join(DATA_DIR, 'checkpoints');
282
+ await fs.ensureDir(checkpointDir);
283
+ await fs.writeJson(path.join(checkpointDir, `${checkpoint.id}.json`), checkpoint, { spaces: 2 });
284
+ }));
285
+ return { ok: true, checkpoint };
286
+ });
287
+ server.get('/export/context', {
288
+ schema: {
289
+ querystring: ExportQuerySchema
290
+ }
291
+ }, async (req, reply) => {
292
+ const { q, session } = req.query;
293
+ // 1. Retrieve Recent Context
294
+ const longTermResults = q ? await vectorStore.search(q, 5) : [];
295
+ // Construct Context Packet
296
+ const packet = {
297
+ intent: q || 'No specific intent',
298
+ session_id: session,
299
+ working_memory: {
300
+ recent_summary: '...'
301
+ },
302
+ long_term_memory: longTermResults.map(r => ({
303
+ text: r.text,
304
+ relevance: r.score, // Use normalized score from Composite Store
305
+ source_store: r._source_store
306
+ })),
307
+ meta: {
308
+ mode: 'private'
309
+ }
310
+ };
311
+ return { ok: true, packet };
312
+ });
313
+ // 5. AGENT Endpoint
314
+ import { Agent } from './engine/agent/core.js';
315
+ import { LiveContextService } from './engine/agent/live-context.js';
316
+ const liveContextService = new LiveContextService();
317
+ watcher.onActivity((path, type) => liveContextService.addEvent(type, path));
318
+ const AgentPromptSchema = z.object({
319
+ prompt: z.string(),
320
+ context: z.string().optional()
321
+ });
322
+ server.post('/agent', {
323
+ schema: {
324
+ body: AgentPromptSchema
325
+ }
326
+ }, async (req, reply) => {
327
+ const { prompt, context } = req.body;
328
+ try {
329
+ const providerId = config.ai.defaults.agent;
330
+ const genAIService = await aiRegistry.getGenAIService(providerId);
331
+ const agent = new Agent({
332
+ genAI: genAIService,
333
+ rootDir: workspaceRoot,
334
+ dataDir: DATA_DIR
335
+ });
336
+ const fullContext = (context || '') + '\n\n' + liveContextService.getSnapshot();
337
+ const answer = await agent.run(prompt, fullContext);
338
+ return { ok: true, answer };
339
+ }
340
+ catch (err) {
341
+ server.log.error(err);
342
+ reply.code(500);
343
+ return { ok: false, error: err.message };
344
+ }
345
+ });
346
+ const start = async () => {
347
+ try {
348
+ const port = config.server.port;
349
+ const host = config.server.host;
350
+ await server.listen({ port, host });
351
+ console.log(`Server listening on ${host}:${port}`);
352
+ }
353
+ catch (err) {
354
+ server.log.error(err);
355
+ process.exit(1);
356
+ }
357
+ };
358
+ if (import.meta.url === `file://${process.argv[1]}`) {
359
+ start();
360
+ }
361
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":";AACA,OAAO,OAA2B,MAAM,SAAS,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAmB,MAAM,2BAA2B,CAAC;AACnG,OAAO,SAAS,MAAM,qBAAqB,CAAC;AAC5C,OAAO,UAAU,MAAM,sBAAsB,CAAC;AAC9C,OAAO,CAAC,MAAM,KAAK,CAAC;AACpB,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAC1E,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,UAAU,CAAC;AAC1B,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACpC,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAErC,MAAM,MAAM,GAAG,OAAO,CAAC;IACrB,MAAM,EAAE,IAAI;CACb,CAAC,CAAC,gBAAgB,EAAmB,CAAC;AAEvC,0BAA0B;AAC1B,MAAM,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,CAAC;AAC/C,MAAM,CAAC,qBAAqB,CAAC,kBAAkB,CAAC,CAAC;AAEjD,gCAAgC;AAChC,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,WAAW,CAAC,CAAC;AAC/D,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC;AAC5D,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,gBAAgB,CAAC;AAC1D,MAAM,eAAe,GAAG,WAAW,CAAC;AAEpC,+BAA+B;AAC/B,MAAM,aAAa,GAAG,IAAI,aAAa,CAAC,QAAQ,CAAC,CAAC;AAClD,IAAI,MAAM,GAAG,aAAa,CAAC,GAAG,EAAE,CAAC;AAEjC,uCAAuC;AACvC,MAAM,UAAU,GAAG,IAAI,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AAErD,qDAAqD;AACrD,MAAM,iBAAiB,GAAG,MAAM,UAAU,CAAC,uBAAuB,EAAE,CAAC;AACrE,IAAI,iBAAiB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;IACjC,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;AACxE,CAAC;AAED,MAAM,MAAM,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;IACrD,oDAAoD;IACpD,iEAAiE;IACjE,OAAO,IAAI,gBAAgB,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC;AACvD,CAAC,CAAC,CAAC;AAEH,OAAO,CAAC,GAAG,CAAC,oBAAoB,MAAM,CAAC,MAAM,mBAAmB,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAEtG,MAAM,WAAW,GAAG,IAAI,oBAAoB,CAAC,MAAM,CAAC,CAAC;AACrD,MAAM,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,6BAA6B;AAEvD,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,WAAW,CAAC,CAAC;AACzC,MAAM,OAAO,GAAG,IAAI,WAAW,CAAC,OAAO,CAAC,CAAC;AAEzC,gBAAgB;AAChB,MAAM,YAAY,GAAG,IAAI,kBAAkB,CAAC,QAAQ,CAAC,CAAC;AACtD,MAAM,aAAa,GAAG,IAAI,aAAa,CAAC,YAAY,EAAE,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AAE5E,0CAA0C;AAC1C,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,CAAC;AAC1C,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,QAAQ,CAAC,KAAK,CAAC;AAC9D,OAAO,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAC;AAE/D,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAE;IACzB,GAAG,EAAE,GAAG;IACR,UAAU,EAAE,UAAU;CACvB,CAAC,CAAC;AAEH,MAAM,CAAC,QAAQ,CAAC,UAAU,EAAE;IAC1B,IAAI,EAAE,IAAI,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC;IAC3B,aAAa,EAAE,CAAC,GAAG,EAAE,EAAE;QACrB,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC;IACzD,CAAC;CACF,CAAC,CAAC;AAEH,qBAAqB;AACrB,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9B,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;QACxB,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QACzB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;QAChB,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;QACnC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;QACpC,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;QACjC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;KAC9B,CAAC,CAAC;CACJ,CAAC,CAAC;AAEH,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACjC,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE;IACb,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;IAC/C,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC1B,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC/B,CAAC,CAAC;AAEH,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACjC,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,SAAS;IACnC,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC/B,CAAC,CAAC;AAEH,MAAM,kBAAkB,GAAG,qBAAqB,CAAC;AAOjD,oBAAoB;AACpB,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE;IACnC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,aAAa,CAAC,GAAG,EAAE,EAAE,EAAE,oCAAoC,CAAC,CAAC;IAEvF,wBAAwB;IACxB,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IACnD,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,IAAI,MAAM,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC1D,oDAAoD;QACpD,IAAI,MAAM,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YACnC,MAAM,OAAO,GAAG,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YACjE,IAAI,OAAO,KAAK,eAAe,EAAE,CAAC;gBAC9B,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,yCAAyC,eAAe,WAAW,OAAO,mCAAmC,CAAC,CAAC;YACnI,CAAC;QACL,CAAC;aAAM,CAAC;YACJ,2DAA2D;YAC3D,+BAA+B;YAC/B,MAAM,EAAE,CAAC,SAAS,CAAC,WAAW,EAAE,eAAe,CAAC,CAAC;QACrD,CAAC;IACL,CAAC;IAED,MAAM,WAAW,CAAC,IAAI,EAAE,CAAC;IACzB,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;IAEvC,gBAAgB;IAChB,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC9C,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IAC7B,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAExB,qCAAqC;IACrC,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;QACvB,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;QACxC,MAAM,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC/C,aAAa,CAAC,KAAK,EAAE,CAAC;IACzB,CAAC;IAED,yDAAyD;IACzD,IAAI,MAAM,WAAW,CAAC,OAAO,EAAE,EAAE,CAAC;QAC9B,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;QAC1F,IAAI,QAAQ,EAAE,CAAC;YACX,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,uEAAuE,CAAC,CAAC;YACzF,0DAA0D;YAC1D,2CAA2C;YAC3C,MAAM,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC7B,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;QAC9C,CAAC;IACL,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE;IACnC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IACpC,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;IACtB,aAAa,CAAC,IAAI,EAAE,CAAC;AACvB,CAAC,CAAC,CAAC;AAEH,oBAAoB;AAEpB,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE;IAC/B,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AACzC,CAAC,CAAC,CAAC;AAEH,yBAAyB;AACzB,MAAM,CAAC,GAAG,CAAC,gBAAgB,EAAE,KAAK,IAAI,EAAE;IACtC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,CAAC,GAAG,EAAE,EAAE,CAAC;AACnD,CAAC,CAAC,CAAC;AAEH,6CAA6C;AAC7C,MAAM,CAAC,KAAK,CAAC,gBAAgB,EAAE;IAC7B,MAAM,EAAE;QACN,IAAI,EAAE,kBAAkB;KACzB;CACF,EAAE,KAAK,EAAE,GAA+C,EAAE,KAAK,EAAE,EAAE;IAClE,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,GAAG,CAAC,IAAwB,CAAC;QAC1C,MAAM,SAAS,GAAG,MAAM,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACnD,MAAM,GAAG,SAAS,CAAC,CAAC,mBAAmB;QAEvC,qCAAqC;QACrC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,IAAI,SAAS,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,aAAa,CAAC,mBAAmB,CAAC,EAAE,CAAC;gBACjE,oCAAoC;gBACpC,0CAA0C;gBAC1C,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS;oBAAE,MAAM,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBAC3E,aAAa,CAAC,KAAK,EAAE,CAAC;YACzB,CAAC;iBAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;gBAClC,aAAa,CAAC,IAAI,EAAE,CAAC;YACxB,CAAC;YACD,6BAA6B;YAC7B,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACtB,aAAa,CAAC,cAAc,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACzD,CAAC;QACH,CAAC;QAED,qFAAqF;QACrF,yCAAyC;QACzC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,mDAAmD,EAAE,CAAC;IACvG,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACtB,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAChB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC;IAC3C,CAAC;AACH,CAAC,CAAC,CAAC;AAGH,mBAAmB;AACnB,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE;IACnB,MAAM,EAAE;QACN,IAAI,EAAE,cAAc;KACrB;CACF,EAAE,KAAK,EAAE,GAA2C,EAAE,KAAK,EAAE,EAAE;IAC9D,MAAM,EAAE,OAAO,EAAE,GAAG,GAAG,CAAC,IAAI,CAAC;IAE7B,2CAA2C;IAC3C,IAAI,CAAC;QACH,MAAM,aAAa,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,KAAK,IAAI,EAAE;YAC7C,qBAAqB;YACrB,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;gBAC3B,4CAA4C;gBAC5C,MAAM,cAAc,GAAG,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAChD,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC,EAAE,GAAG,cAAc,CAAC,CAAC,CAAC;gBAEjE,MAAM,UAAU,GAAG;oBAClB,GAAG,KAAK;oBACR,EAAE,EAAE,KAAK,CAAC,EAAE,IAAI,UAAU,EAAE,EAAE,8BAA8B;oBAC5D,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC;oBACtB,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;iBAC9B,CAAC;gBAEF,2BAA2B;gBAC3B,MAAM,QAAQ,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,UAAU,KAAK,CAAC,CAAC,CAAC,SAAS,UAAU,CAAC,EAAE,KAAK,CAAC;gBACrG,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;gBAExD,MAAM,WAAW,GAAG,gBAAgB,UAAU,CAAC,EAAE,WAAW,UAAU,CAAC,IAAI,YAAY,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,UAAU,CAAC,IAAI,EAAE,CAAC;gBAEhJ,MAAM,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;YAC9C,CAAC;QACH,CAAC,CAAC,CAAC,CAAC;QAEJ,2CAA2C;QAC3C,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC;IAE7C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACtB,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAChB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC;IAC7C,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,iCAAiC;AACjC,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE;IACpB,MAAM,EAAE;QACN,WAAW,EAAE,iBAAiB;KAC/B;CACF,EAAE,KAAK,EAAE,GAAqD,EAAE,KAAK,EAAE,EAAE;IACxE,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,GAAG,CAAC,KAAK,CAAC;IAC7C,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;IACzF,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AAC/B,CAAC,CAAC,CAAC;AAEH,4CAA4C;AAC5C,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE;IAC3C,oEAAoE;IACpE,qBAAqB;IACrB,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,kBAAkB,EAAE,MAAM,EAAE,yBAAyB,EAAE,CAAC;AAClF,CAAC,CAAC,CAAC;AAEH,gCAAgC;AAEhC,uCAAuC;AACvC,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IAChC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC7B,CAAC,CAAC;AAGH,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE;IAC1B,MAAM,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE;CACnC,EAAE,KAAK,EAAE,GAA6C,EAAE,KAAK,EAAE,EAAE;IAChE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,CAAC,IAAI,CAAC;IAE3B,MAAM,OAAO,GAAG;QACd,EAAE,EAAE,MAAM,IAAI,EAAE,EAAE;QAClB,KAAK,EAAE,KAAK,IAAI,WAAW,IAAI,IAAI,EAAE,CAAC,kBAAkB,EAAE,EAAE;QAC5D,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACrC,CAAC;IAEF,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AAC/B,CAAC,CAAC,CAAC;AAEH,+CAA+C;AAC/C,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC;IAChC,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE;IACtB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;IAClB,cAAc,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE;IAChD,SAAS,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE;CAC1C,CAAC,CAAC;AAGH,MAAM,CAAC,IAAI,CAAC,cAAc,EAAE;IAC1B,MAAM,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE;CACnC,EAAE,KAAK,EAAE,GAA6C,EAAE,KAAK,EAAE,EAAE;IAChE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,SAAS,EAAE,GAAG,GAAG,CAAC,IAAI,CAAC;IAE5E,MAAM,UAAU,GAAG;QACjB,EAAE,EAAE,MAAM,IAAI,EAAE,EAAE;QAClB,UAAU;QACV,QAAQ,EAAE;YACR,cAAc,EAAE,IAAI,CAAC,SAAS,CAAC,cAAc,IAAI,EAAE,CAAC;YACpD,kBAAkB,EAAE,OAAO;SAC5B;QACD,MAAM;QACN,SAAS,EAAE,SAAS,IAAI,EAAE;QAC1B,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACrC,CAAC;IAEF,wCAAwC;IACxC,MAAM,aAAa,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,KAAK,IAAI,EAAE;QAC7C,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;QACzD,MAAM,EAAE,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;QAClC,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,GAAG,UAAU,CAAC,EAAE,OAAO,CAAC,EAAE,UAAU,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;IACnG,CAAC,CAAC,CAAC,CAAC;IAEJ,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;AAClC,CAAC,CAAC,CAAC;AACH,MAAM,CAAC,GAAG,CAAC,iBAAiB,EAAE;IAC5B,MAAM,EAAE;QACN,WAAW,EAAE,iBAAiB;KAC/B;CACF,EAAE,KAAK,EAAE,GAAqD,EAAE,KAAK,EAAE,EAAE;IACxE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,GAAG,GAAG,CAAC,KAAK,CAAC;IAEjC,6BAA6B;IAC7B,MAAM,eAAe,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,WAAW,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAEhE,2BAA2B;IAC3B,MAAM,MAAM,GAAG;QACb,MAAM,EAAE,CAAC,IAAI,oBAAoB;QACjC,UAAU,EAAE,OAAO;QACnB,cAAc,EAAE;YACZ,cAAc,EAAE,KAAK;SACxB;QACD,gBAAgB,EAAE,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACzC,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,SAAS,EAAE,CAAC,CAAC,KAAK,EAAE,4CAA4C;YAChE,YAAY,EAAE,CAAC,CAAC,aAAa;SAC/B,CAAC,CAAC;QACH,IAAI,EAAE;YACJ,IAAI,EAAE,SAAS;SAChB;KACF,CAAC;IAEF,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AAC9B,CAAC,CAAC,CAAC;AAGH,oBAAoB;AACpB,OAAO,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAEpE,MAAM,kBAAkB,GAAG,IAAI,kBAAkB,EAAE,CAAC;AACpD,OAAO,CAAC,UAAU,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,kBAAkB,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;AAE5E,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACjC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE;IAClB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC/B,CAAC,CAAC;AAGH,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE;IACpB,MAAM,EAAE;QACN,IAAI,EAAE,iBAAiB;KACxB;CACF,EAAE,KAAK,EAAE,GAA8C,EAAE,KAAK,EAAE,EAAE;IACjE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,GAAG,CAAC,IAAI,CAAC;IAErC,IAAI,CAAC;QACD,MAAM,UAAU,GAAG,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC;QAC5C,MAAM,YAAY,GAAG,MAAM,UAAU,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC;QAElE,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC;YACpB,KAAK,EAAE,YAAY;YACnB,OAAO,EAAE,aAAa;YACtB,OAAO,EAAE,QAAQ;SACpB,CAAC,CAAC;QAEH,MAAM,WAAW,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC,GAAG,MAAM,GAAG,kBAAkB,CAAC,WAAW,EAAE,CAAC;QAEhF,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;QACpD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAChC,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAChB,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACtB,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAChB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC;IAC7C,CAAC;AACH,CAAC,CAAC,CAAC;AAGH,MAAM,KAAK,GAAG,KAAK,IAAI,EAAE;IAEvB,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;QAChC,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;QAChC,MAAM,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QACpC,OAAO,CAAC,GAAG,CAAC,uBAAuB,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC;IACrD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACtB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC;AAEF,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,UAAU,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IACpD,KAAK,EAAE,CAAC;AACV,CAAC"}
@@ -0,0 +1,20 @@
1
+ import { ISyncProvider } from '@yuihub/core';
2
+ export declare class GitHubSyncProvider implements ISyncProvider {
3
+ readonly name: "github";
4
+ private git;
5
+ private repoPath;
6
+ constructor(repoPath: string);
7
+ init(remoteUrl?: string): Promise<void>;
8
+ /**
9
+ * Exponential Backoff Retry Wrapper for Git Operations
10
+ */
11
+ private withRetry;
12
+ push(message?: string): Promise<void>;
13
+ pull(): Promise<void>;
14
+ status(): Promise<{
15
+ dirty: boolean;
16
+ ahead: number;
17
+ behind: number;
18
+ }>;
19
+ }
20
+ //# sourceMappingURL=github-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-provider.d.ts","sourceRoot":"","sources":["../../src/sync/github-provider.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAG7C,qBAAa,kBAAmB,YAAW,aAAa;IACtD,QAAQ,CAAC,IAAI,EAAG,QAAQ,CAAU;IAClC,OAAO,CAAC,GAAG,CAAY;IACvB,OAAO,CAAC,QAAQ,CAAS;gBAEb,QAAQ,EAAE,MAAM;IAKtB,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM;IAS7B;;OAEG;YACW,SAAS;IAsBjB,IAAI,CAAC,OAAO,GAAE,MAAkC,GAAG,OAAO,CAAC,IAAI,CAAC;IAmBhE,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IASrB,MAAM;;;;;CAUb"}
@@ -0,0 +1,80 @@
1
+ import { simpleGit } from 'simple-git';
2
+ import fs from 'fs-extra';
3
+ import path from 'path';
4
+ export class GitHubSyncProvider {
5
+ name = 'github';
6
+ git;
7
+ repoPath;
8
+ constructor(repoPath) {
9
+ this.repoPath = repoPath;
10
+ this.git = simpleGit(repoPath);
11
+ }
12
+ async init(remoteUrl) {
13
+ if (!await fs.pathExists(path.join(this.repoPath, '.git'))) {
14
+ await this.git.init();
15
+ if (remoteUrl) {
16
+ await this.git.addRemote('origin', remoteUrl);
17
+ }
18
+ }
19
+ }
20
+ /**
21
+ * Exponential Backoff Retry Wrapper for Git Operations
22
+ */
23
+ async withRetry(operation, retries = 5, baseDelay = 1000) {
24
+ for (let i = 0; i < retries; i++) {
25
+ try {
26
+ return await operation();
27
+ }
28
+ catch (e) {
29
+ const isLockError = e.message?.includes('index.lock') || e.message?.includes('Unable to create');
30
+ if (isLockError && i < retries - 1) {
31
+ const delay = baseDelay * Math.pow(2, i); // 1s, 2s, 4s, 8s, 16s
32
+ console.warn(`[Sync] Git lock detected. Retrying in ${delay}ms... (Attempt ${i + 1}/${retries})`);
33
+ await new Promise(r => setTimeout(r, delay));
34
+ // Attempt to clean stale lock?
35
+ // CAUTION: Removing lock blindly is dangerous, but common in automated environments strictly controlled by one process.
36
+ // Here we are potentially competing with user. Better to just wait.
37
+ continue;
38
+ }
39
+ throw e;
40
+ }
41
+ }
42
+ throw new Error('Unreachable');
43
+ }
44
+ async push(message = 'chore: sync from yuihub') {
45
+ await this.withRetry(async () => {
46
+ // Check status first
47
+ const status = await this.git.status();
48
+ if (status.isClean())
49
+ return;
50
+ await this.git.add('.');
51
+ await this.git.commit(message);
52
+ // Check if remote exists before pushing
53
+ const remotes = await this.git.getRemotes();
54
+ if (remotes.some(r => r.name === 'origin')) {
55
+ // Pull with rebase first to avoid non-fast-forward?
56
+ // await this.git.pull('origin', 'main', { '--rebase': 'true' });
57
+ await this.git.push('origin', 'main');
58
+ }
59
+ });
60
+ }
61
+ async pull() {
62
+ await this.withRetry(async () => {
63
+ const remotes = await this.git.getRemotes();
64
+ if (remotes.some(r => r.name === 'origin')) {
65
+ await this.git.pull('origin', 'main');
66
+ }
67
+ });
68
+ }
69
+ async status() {
70
+ return this.withRetry(async () => {
71
+ const s = await this.git.status();
72
+ return {
73
+ dirty: !s.isClean(),
74
+ ahead: s.ahead,
75
+ behind: s.behind
76
+ };
77
+ });
78
+ }
79
+ }
80
+ //# sourceMappingURL=github-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-provider.js","sourceRoot":"","sources":["../../src/sync/github-provider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import { ISyncProvider } from '@yuihub/core';
2
+ export declare class SyncScheduler {
3
+ private job;
4
+ private provider;
5
+ private isRunning;
6
+ private isSchedulerActive;
7
+ private cronExpression;
8
+ constructor(provider: ISyncProvider, cronExpression?: string);
9
+ private createJob;
10
+ start(): void;
11
+ stop(): void;
12
+ /**
13
+ * Update the sync interval dynamically (hot reload)
14
+ */
15
+ updateInterval(newCronExpression: string): void;
16
+ runSync(): Promise<void>;
17
+ }
18
+ //# sourceMappingURL=scheduler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../../src/sync/scheduler.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C,qBAAa,aAAa;IACxB,OAAO,CAAC,GAAG,CAAwB;IACnC,OAAO,CAAC,QAAQ,CAAgB;IAChC,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,iBAAiB,CAAkB;IAC3C,OAAO,CAAC,cAAc,CAAS;gBAEnB,QAAQ,EAAE,aAAa,EAAE,cAAc,GAAE,MAAsB;IAM3E,OAAO,CAAC,SAAS;IAMjB,KAAK;IAQL,IAAI;IAOJ;;OAEG;IACH,cAAc,CAAC,iBAAiB,EAAE,MAAM;IAmBlC,OAAO;CAcd"}
@@ -0,0 +1,67 @@
1
+ import { CronJob } from 'cron';
2
+ export class SyncScheduler {
3
+ job = null;
4
+ provider;
5
+ isRunning = false;
6
+ isSchedulerActive = false;
7
+ cronExpression;
8
+ constructor(provider, cronExpression = '*/5 * * * *') {
9
+ this.provider = provider;
10
+ this.cronExpression = cronExpression;
11
+ this.job = this.createJob(cronExpression);
12
+ }
13
+ createJob(cronExpression) {
14
+ return new CronJob(cronExpression, async () => {
15
+ await this.runSync();
16
+ });
17
+ }
18
+ start() {
19
+ if (this.job) {
20
+ this.job.start();
21
+ this.isSchedulerActive = true;
22
+ console.log(`[Sync] Scheduler started (${this.provider.name})`);
23
+ }
24
+ }
25
+ stop() {
26
+ if (this.job) {
27
+ this.job.stop();
28
+ this.isSchedulerActive = false;
29
+ }
30
+ }
31
+ /**
32
+ * Update the sync interval dynamically (hot reload)
33
+ */
34
+ updateInterval(newCronExpression) {
35
+ if (newCronExpression === this.cronExpression)
36
+ return;
37
+ const wasRunning = this.isSchedulerActive;
38
+ // Stop existing job
39
+ this.stop();
40
+ // Create new job with updated interval
41
+ this.cronExpression = newCronExpression;
42
+ this.job = this.createJob(newCronExpression);
43
+ // Restart if it was running
44
+ if (wasRunning) {
45
+ this.start();
46
+ console.log(`[Sync] Interval updated to: ${newCronExpression}`);
47
+ }
48
+ }
49
+ async runSync() {
50
+ if (this.isRunning)
51
+ return;
52
+ this.isRunning = true;
53
+ try {
54
+ console.log('[Sync] Starting sync...');
55
+ await this.provider.push(`sync: auto backup ${new Date().toISOString()}`);
56
+ // await this.provider.pull(); // Pull strategy?
57
+ console.log('[Sync] Sync completed.');
58
+ }
59
+ catch (e) {
60
+ console.error('[Sync] Error:', e);
61
+ }
62
+ finally {
63
+ this.isRunning = false;
64
+ }
65
+ }
66
+ }
67
+ //# sourceMappingURL=scheduler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../../src/sync/scheduler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAG/B,MAAM,OAAO,aAAa;IAChB,GAAG,GAAmB,IAAI,CAAC;IAC3B,QAAQ,CAAgB;IACxB,SAAS,GAAY,KAAK,CAAC;IAC3B,iBAAiB,GAAY,KAAK,CAAC;IACnC,cAAc,CAAS;IAE/B,YAAY,QAAuB,EAAE,iBAAyB,aAAa;QACzE,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;QACrC,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;IAC5C,CAAC;IAEO,SAAS,CAAC,cAAsB;QACtC,OAAO,IAAI,OAAO,CAAC,cAAc,EAAE,KAAK,IAAI,EAAE;YAC5C,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;QACvB,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK;QACH,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;YACjB,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;YAC9B,OAAO,CAAC,GAAG,CAAC,6BAA6B,IAAI,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,CAAC;QAClE,CAAC;IACH,CAAC;IAED,IAAI;QACF,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;YAChB,IAAI,CAAC,iBAAiB,GAAG,KAAK,CAAC;QACjC,CAAC;IACH,CAAC;IAED;;OAEG;IACH,cAAc,CAAC,iBAAyB;QACtC,IAAI,iBAAiB,KAAK,IAAI,CAAC,cAAc;YAAE,OAAO;QAEtD,MAAM,UAAU,GAAG,IAAI,CAAC,iBAAiB,CAAC;QAE1C,oBAAoB;QACpB,IAAI,CAAC,IAAI,EAAE,CAAC;QAEZ,uCAAuC;QACvC,IAAI,CAAC,cAAc,GAAG,iBAAiB,CAAC;QACxC,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC;QAE7C,4BAA4B;QAC5B,IAAI,UAAU,EAAE,CAAC;YACf,IAAI,CAAC,KAAK,EAAE,CAAC;YACb,OAAO,CAAC,GAAG,CAAC,+BAA+B,iBAAiB,EAAE,CAAC,CAAC;QAClE,CAAC;IACH,CAAC;IAED,KAAK,CAAC,OAAO;QACX,IAAI,IAAI,CAAC,SAAS;YAAE,OAAO;QAC3B,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,IAAI,CAAC;YACH,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;YACvC,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,qBAAqB,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;YAC1E,gDAAgD;YAChD,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;QACxC,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,CAAC,KAAK,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC;QACpC,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;QACzB,CAAC;IACH,CAAC;CACF"}