openclaw-github-trending 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +480 -0
- package/dist/channels/email.d.ts +61 -0
- package/dist/channels/email.d.ts.map +1 -0
- package/dist/channels/email.js +599 -0
- package/dist/channels/email.js.map +1 -0
- package/dist/channels/feishu.d.ts +50 -0
- package/dist/channels/feishu.d.ts.map +1 -0
- package/dist/channels/feishu.js +322 -0
- package/dist/channels/feishu.js.map +1 -0
- package/dist/channels/types.d.ts +66 -0
- package/dist/channels/types.d.ts.map +1 -0
- package/dist/channels/types.js +12 -0
- package/dist/channels/types.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js.map +1 -0
- package/dist/core/config.d.ts +83 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +145 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/fetcher.d.ts +43 -0
- package/dist/core/fetcher.d.ts.map +1 -0
- package/dist/core/fetcher.js +306 -0
- package/dist/core/fetcher.js.map +1 -0
- package/dist/core/file-storage.d.ts +62 -0
- package/dist/core/file-storage.d.ts.map +1 -0
- package/dist/core/file-storage.js +253 -0
- package/dist/core/file-storage.js.map +1 -0
- package/dist/core/history.d.ts +71 -0
- package/dist/core/history.d.ts.map +1 -0
- package/dist/core/history.js +133 -0
- package/dist/core/history.js.map +1 -0
- package/dist/core/summarizer.d.ts +64 -0
- package/dist/core/summarizer.d.ts.map +1 -0
- package/dist/core/summarizer.js +324 -0
- package/dist/core/summarizer.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +668 -0
- package/dist/index.js.map +1 -0
- package/dist/models/config.d.ts +93 -0
- package/dist/models/config.d.ts.map +1 -0
- package/dist/models/config.js +3 -0
- package/dist/models/config.js.map +1 -0
- package/dist/models/history.d.ts +6 -0
- package/dist/models/history.d.ts.map +1 -0
- package/dist/models/history.js +7 -0
- package/dist/models/history.js.map +1 -0
- package/dist/models/repository.d.ts +28 -0
- package/dist/models/repository.d.ts.map +1 -0
- package/dist/models/repository.js +3 -0
- package/dist/models/repository.js.map +1 -0
- package/dist/models/service.types.d.ts +87 -0
- package/dist/models/service.types.d.ts.map +1 -0
- package/dist/models/service.types.js +3 -0
- package/dist/models/service.types.js.map +1 -0
- package/dist/services/trending.service.d.ts +29 -0
- package/dist/services/trending.service.d.ts.map +1 -0
- package/dist/services/trending.service.js +306 -0
- package/dist/services/trending.service.js.map +1 -0
- package/dist/tool.d.ts +47 -0
- package/dist/tool.d.ts.map +1 -0
- package/dist/tool.js +314 -0
- package/dist/tool.js.map +1 -0
- package/dist/utils/logger.d.ts +77 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +214 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/markdown.d.ts +9 -0
- package/dist/utils/markdown.d.ts.map +1 -0
- package/dist/utils/markdown.js +40 -0
- package/dist/utils/markdown.js.map +1 -0
- package/openclaw.plugin.json +152 -0
- package/package.json +78 -0
package/dist/tool.js
ADDED
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.githubTrendingTool = exports.HistoryManager = void 0;
|
|
4
|
+
const fetcher_1 = require("./core/fetcher");
|
|
5
|
+
const summarizer_1 = require("./core/summarizer");
|
|
6
|
+
const history_1 = require("./core/history");
|
|
7
|
+
Object.defineProperty(exports, "HistoryManager", { enumerable: true, get: function () { return history_1.HistoryManager; } });
|
|
8
|
+
const feishu_1 = require("./channels/feishu");
|
|
9
|
+
const email_1 = require("./channels/email");
|
|
10
|
+
const config_1 = require("./core/config");
|
|
11
|
+
/**
|
|
12
|
+
* Process repositories with AI summaries concurrently
|
|
13
|
+
* @param repositories Repositories to process
|
|
14
|
+
* @param summarizer AISummarizer instance
|
|
15
|
+
* @param maxWorkers Maximum concurrent workers
|
|
16
|
+
* @returns Repositories with AI summaries
|
|
17
|
+
*/
|
|
18
|
+
async function processRepositoriesWithAI(repositories, summarizer, maxWorkers = 5) {
|
|
19
|
+
const results = [];
|
|
20
|
+
// Use configured max workers, cap at 10 to avoid overwhelming the API
|
|
21
|
+
const actualMaxWorkers = Math.min(maxWorkers, 10);
|
|
22
|
+
// Process in batches to limit concurrency
|
|
23
|
+
for (let i = 0; i < repositories.length; i += actualMaxWorkers) {
|
|
24
|
+
const batch = repositories.slice(i, i + actualMaxWorkers);
|
|
25
|
+
console.log(`[AI Summarizer] Processing batch ${Math.floor(i / actualMaxWorkers) + 1}/${Math.ceil(repositories.length / actualMaxWorkers)} (${batch.length} repos with ${actualMaxWorkers} workers)...`);
|
|
26
|
+
// Use Promise.allSettled to handle individual failures gracefully
|
|
27
|
+
const batchResults = await Promise.allSettled(batch.map(async (repo) => {
|
|
28
|
+
try {
|
|
29
|
+
// Add timeout for each summary request (3 minutes max to match OpenClaw CLI limit)
|
|
30
|
+
const startTime = Date.now();
|
|
31
|
+
const summary = await Promise.race([
|
|
32
|
+
summarizer.generateSummary(repo),
|
|
33
|
+
new Promise((_, reject) => setTimeout(() => reject(new Error('Summary timeout')), 180000))
|
|
34
|
+
]);
|
|
35
|
+
const duration = Date.now() - startTime;
|
|
36
|
+
console.log(`✅ ${repo.full_name} summary generated (${duration}ms, ${summary.length} chars)`);
|
|
37
|
+
return { ...repo, ai_summary: summary };
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
console.log(`⚠️ ${repo.full_name} 摘要生成失败:${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
41
|
+
return { ...repo, ai_summary: '' };
|
|
42
|
+
}
|
|
43
|
+
}));
|
|
44
|
+
// Collect successful results
|
|
45
|
+
for (const result of batchResults) {
|
|
46
|
+
if (result.status === 'fulfilled') {
|
|
47
|
+
results.push(result.value);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return results;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Main handler for GitHub Trending Tool
|
|
55
|
+
*/
|
|
56
|
+
async function githubTrendingHandler(params, pluginConfig = {}, openclawConfig = {}, historyData) {
|
|
57
|
+
console.log('\n[GitHub Trending Tool] Handler called');
|
|
58
|
+
console.log('[GitHub Trending Tool] pluginConfig:', JSON.stringify(pluginConfig, null, 2));
|
|
59
|
+
console.log('[GitHub Trending Tool] pluginConfig.proxy:', pluginConfig.proxy);
|
|
60
|
+
console.log('[GitHub Trending Tool] params:', params);
|
|
61
|
+
console.log('[GitHub Trending Tool] openclawConfig available:', !!openclawConfig);
|
|
62
|
+
const { since, channels, email_to, feishu_webhook } = params;
|
|
63
|
+
// 解析通道配置(仅使用 channels 参数)
|
|
64
|
+
const targetChannels = channels || [];
|
|
65
|
+
if (targetChannels.length === 0) {
|
|
66
|
+
return {
|
|
67
|
+
success: false,
|
|
68
|
+
pushed_count: 0,
|
|
69
|
+
new_count: 0,
|
|
70
|
+
seen_count: 0,
|
|
71
|
+
total_count: 0,
|
|
72
|
+
pushed_to: '',
|
|
73
|
+
timestamp: new Date().toISOString(),
|
|
74
|
+
message: '请指定至少一个推送通道:channels 参数'
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
// Step 1: Resolve AI configuration with fallback logic
|
|
78
|
+
const aiConfig = config_1.ConfigManager.getAIConfig(pluginConfig, openclawConfig);
|
|
79
|
+
const summarizer = new summarizer_1.AISummarizer(aiConfig);
|
|
80
|
+
// Step 2: Initialize fetcher and fetch trending repositories
|
|
81
|
+
const fetcher = new fetcher_1.GitHubFetcher(pluginConfig);
|
|
82
|
+
let repositories;
|
|
83
|
+
try {
|
|
84
|
+
repositories = await fetcher.fetchTrending(since);
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
return {
|
|
88
|
+
success: false,
|
|
89
|
+
pushed_count: 0,
|
|
90
|
+
new_count: 0,
|
|
91
|
+
seen_count: 0,
|
|
92
|
+
total_count: 0,
|
|
93
|
+
pushed_to: targetChannels.join(','),
|
|
94
|
+
timestamp: new Date().toISOString(),
|
|
95
|
+
message: `Failed to fetch trending: ${error instanceof Error ? error.message : 'Unknown error'}`
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
// Step 3: Initialize history manager and separate new/seen repositories
|
|
99
|
+
const historyManager = new history_1.HistoryManager();
|
|
100
|
+
if (historyData) {
|
|
101
|
+
historyManager.importData(historyData);
|
|
102
|
+
}
|
|
103
|
+
// Categorize repositories with proper history config from plugin
|
|
104
|
+
const historyConfig = {
|
|
105
|
+
enabled: pluginConfig?.history?.enabled ?? true,
|
|
106
|
+
star_threshold: pluginConfig?.history?.star_threshold ?? 100
|
|
107
|
+
};
|
|
108
|
+
const historyStatsBefore = historyManager.getStats();
|
|
109
|
+
console.log('[History Manager] Configuration:', JSON.stringify(historyConfig, null, 2));
|
|
110
|
+
console.log('[History Manager] History loaded from storage:', historyData ? '✅ Yes' : '❌ No');
|
|
111
|
+
console.log('[History Manager] Total repositories in history:', Object.keys(historyManager['data'].repositories).length);
|
|
112
|
+
console.log('[History Manager] Statistics before processing:');
|
|
113
|
+
console.log(` - Total repositories tracked: ${historyStatsBefore.total_repositories}`);
|
|
114
|
+
console.log(` - Total pushes: ${historyStatsBefore.total_pushes}`);
|
|
115
|
+
console.log(` - Oldest entry: ${historyStatsBefore.oldest_entry || 'N/A'}`);
|
|
116
|
+
console.log(` - Newest entry: ${historyStatsBefore.newest_entry || 'N/A'}`);
|
|
117
|
+
const { newlySeen, shouldPush, alreadySeen } = historyManager.categorizeRepositories(repositories, historyConfig);
|
|
118
|
+
console.log(`[History Manager] Results - New: ${newlySeen.length}, Should Push: ${shouldPush.length}, Already Seen: ${alreadySeen.length}`);
|
|
119
|
+
if (newlySeen.length > 0) {
|
|
120
|
+
console.log('[History Manager] Newly seen repositories:');
|
|
121
|
+
newlySeen.forEach((repo, i) => console.log(` ${i + 1}. ${repo.full_name} (${repo.stars} stars)`));
|
|
122
|
+
}
|
|
123
|
+
if (alreadySeen.length > 0) {
|
|
124
|
+
console.log('[History Manager] Already seen repositories:');
|
|
125
|
+
alreadySeen.forEach((repo, i) => {
|
|
126
|
+
const history = historyManager.getProject(repo.full_name);
|
|
127
|
+
const starsDiff = repo.stars - (history?.last_stars || 0);
|
|
128
|
+
console.log(` ${i + 1}. ${repo.full_name} (${repo.stars} stars, +${starsDiff} since last push)`);
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
// Step 4: Get max workers from config and generate AI summaries for repositories to push
|
|
132
|
+
const maxWorkers = config_1.ConfigManager.getMaxWorkers(pluginConfig);
|
|
133
|
+
console.log(`[AI Summarizer] Using ${maxWorkers} concurrent workers for ${shouldPush.length} repositories`);
|
|
134
|
+
let processedRepositories = [];
|
|
135
|
+
const startTime = Date.now();
|
|
136
|
+
try {
|
|
137
|
+
processedRepositories = await processRepositoriesWithAI(shouldPush, summarizer, maxWorkers);
|
|
138
|
+
}
|
|
139
|
+
catch (error) {
|
|
140
|
+
// Continue with empty summaries if AI processing fails
|
|
141
|
+
processedRepositories = shouldPush.map((r) => ({ ...r, ai_summary: '' }));
|
|
142
|
+
}
|
|
143
|
+
const summaryDuration = Date.now() - startTime;
|
|
144
|
+
console.log(`[AI Summarizer] ✅ All summaries generated in ${summaryDuration}ms (${summaryDuration / shouldPush.length}ms per repo on average)`);
|
|
145
|
+
// Update history
|
|
146
|
+
historyManager.markPushed(processedRepositories);
|
|
147
|
+
// Prepare seen repositories with AI summaries from history (skip AI generation)
|
|
148
|
+
const seenReposWithSummary = alreadySeen.map((r) => {
|
|
149
|
+
const history = historyManager.getProject(r.full_name);
|
|
150
|
+
const summary = history?.ai_summary || '';
|
|
151
|
+
if (summary) {
|
|
152
|
+
console.log(`[History Manager] ✅ Using cached summary for ${r.full_name} (${summary.length} chars)`);
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
console.log(`[History Manager] ⚠️ No cached summary for ${r.full_name}`);
|
|
156
|
+
}
|
|
157
|
+
return {
|
|
158
|
+
...r,
|
|
159
|
+
ai_summary: summary
|
|
160
|
+
};
|
|
161
|
+
});
|
|
162
|
+
// Display summary statistics
|
|
163
|
+
console.log(`\n[Summary Statistics]`);
|
|
164
|
+
console.log(` - New repositories processed with AI: ${processedRepositories.length}`);
|
|
165
|
+
console.log(` - Already seen repositories (using cached summaries): ${alreadySeen.length}`);
|
|
166
|
+
console.log(` - Total repositories to push: ${processedRepositories.length}`);
|
|
167
|
+
console.log(` - Total repositories shown: ${processedRepositories.length + alreadySeen.length}`);
|
|
168
|
+
// Step 5: Push to each channel
|
|
169
|
+
const pushResults = [];
|
|
170
|
+
const pushLogs = []; // 收集推送日志
|
|
171
|
+
// Display history statistics
|
|
172
|
+
const historyStats = historyManager.getStats();
|
|
173
|
+
console.log('\n[History Statistics]');
|
|
174
|
+
console.log(` - Total repositories tracked: ${historyStats.total_repositories}`);
|
|
175
|
+
console.log(` - Total pushes: ${historyStats.total_pushes}`);
|
|
176
|
+
console.log(` - Oldest entry: ${historyStats.oldest_entry || 'N/A'}`);
|
|
177
|
+
console.log(` - Newest entry: ${historyStats.newest_entry || 'N/A'}`);
|
|
178
|
+
for (const targetChannel of targetChannels) {
|
|
179
|
+
try {
|
|
180
|
+
if (targetChannel === 'feishu') {
|
|
181
|
+
const webhookUrl = feishu_webhook || pluginConfig?.channels?.feishu?.webhook_url;
|
|
182
|
+
if (!webhookUrl) {
|
|
183
|
+
pushResults.push({ channel: 'feishu', success: false, error: 'Feishu webhook URL not provided' });
|
|
184
|
+
pushLogs.push('[Feishu Channel] ❌ 推送失败: Feishu webhook URL not provided');
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
187
|
+
const result = await feishu_1.FeishuChannel.push(webhookUrl, processedRepositories, seenReposWithSummary);
|
|
188
|
+
pushResults.push({
|
|
189
|
+
channel: 'feishu',
|
|
190
|
+
success: result.success,
|
|
191
|
+
messageId: result.messageId,
|
|
192
|
+
error: result.error
|
|
193
|
+
});
|
|
194
|
+
pushLogs.push(`[Feishu Channel] ${result.success ? '✅ 推送成功' : '❌ 推送失败'}${result.error ? ': ' + result.error : ''}`);
|
|
195
|
+
}
|
|
196
|
+
else if (targetChannel === 'email') {
|
|
197
|
+
const emailTo = email_to || pluginConfig?.channels?.email?.recipient || pluginConfig?.channels?.email?.sender;
|
|
198
|
+
if (!emailTo) {
|
|
199
|
+
pushResults.push({ channel: 'email', success: false, error: 'Email recipient not provided' });
|
|
200
|
+
pushLogs.push('[Email Channel] ❌ 推送失败: Email recipient not provided');
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
// Detect email configuration
|
|
204
|
+
const emailConfig = config_1.ConfigManager.getEmailConfig(emailTo, pluginConfig?.channels?.email?.password || '', pluginConfig?.channels?.email);
|
|
205
|
+
const internalEmailConfig = {
|
|
206
|
+
from: emailConfig.sender,
|
|
207
|
+
to: emailTo,
|
|
208
|
+
subject: `GitHub ${since === 'daily' ? '今日' : since === 'weekly' ? '本周' : '本月'}热榜推送`,
|
|
209
|
+
smtp: {
|
|
210
|
+
host: emailConfig.smtp_host,
|
|
211
|
+
port: emailConfig.smtp_port,
|
|
212
|
+
secure: false, // Use STARTTLS
|
|
213
|
+
auth: {
|
|
214
|
+
user: emailConfig.sender,
|
|
215
|
+
pass: emailConfig.password
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
const result = await email_1.EmailChannel.send(internalEmailConfig, processedRepositories, seenReposWithSummary, since);
|
|
220
|
+
pushResults.push({
|
|
221
|
+
channel: 'email',
|
|
222
|
+
success: result.success,
|
|
223
|
+
messageId: result.messageId,
|
|
224
|
+
error: result.error
|
|
225
|
+
});
|
|
226
|
+
pushLogs.push(`[Email Channel] ${result.success ? '✅ 推送成功' : '❌ 推送失败'}${result.error ? ': ' + result.error : ''}`);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
catch (error) {
|
|
230
|
+
pushResults.push({
|
|
231
|
+
channel: targetChannel,
|
|
232
|
+
success: false,
|
|
233
|
+
error: error instanceof Error ? error.message : 'Unknown error'
|
|
234
|
+
});
|
|
235
|
+
pushLogs.push(`[${targetChannel} Channel] ❌ 推送失败: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
// 统一输出推送日志在最后
|
|
239
|
+
console.log('\n========== 推送结果汇总 ==========');
|
|
240
|
+
pushLogs.forEach(log => console.log(log));
|
|
241
|
+
console.log('====================================\n');
|
|
242
|
+
// Step 6: Return result
|
|
243
|
+
const successCount = pushResults.filter(r => r.success).length;
|
|
244
|
+
const failedChannels = pushResults.filter(r => !r.success).map(r => r.channel);
|
|
245
|
+
const successChannels = pushResults.filter(r => r.success).map(r => r.channel);
|
|
246
|
+
// 构建详细的消息
|
|
247
|
+
let message = '';
|
|
248
|
+
if (successCount === targetChannels.length) {
|
|
249
|
+
message = `成功推送到所有 ${successCount} 个通道`;
|
|
250
|
+
}
|
|
251
|
+
else if (successCount > 0) {
|
|
252
|
+
const failedDetails = pushResults
|
|
253
|
+
.filter(r => !r.success)
|
|
254
|
+
.map(r => `${r.channel}: ${r.error}`)
|
|
255
|
+
.join(', ');
|
|
256
|
+
message = `部分成功:${successCount}/${targetChannels.length} 个通道推送成功,失败:${failedDetails}`;
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
259
|
+
const failedDetails = pushResults
|
|
260
|
+
.filter(r => !r.success)
|
|
261
|
+
.map(r => `${r.channel}: ${r.error}`)
|
|
262
|
+
.join(', ');
|
|
263
|
+
message = `所有通道推送失败:${failedDetails}`;
|
|
264
|
+
}
|
|
265
|
+
return {
|
|
266
|
+
success: successCount > 0,
|
|
267
|
+
pushed_count: processedRepositories.length,
|
|
268
|
+
new_count: newlySeen.length,
|
|
269
|
+
seen_count: alreadySeen.length,
|
|
270
|
+
total_count: repositories.length,
|
|
271
|
+
pushed_to: successChannels.join(','),
|
|
272
|
+
timestamp: new Date().toISOString(),
|
|
273
|
+
message,
|
|
274
|
+
history_data: historyManager.exportData() // Return updated history for persistence
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* Export the GitHub Trending Tool
|
|
279
|
+
*/
|
|
280
|
+
exports.githubTrendingTool = {
|
|
281
|
+
name: 'openclaw-github-trending',
|
|
282
|
+
description: 'Fetch GitHub trending repositories and push to Feishu or Email',
|
|
283
|
+
parameters: {
|
|
284
|
+
type: 'object',
|
|
285
|
+
properties: {
|
|
286
|
+
since: {
|
|
287
|
+
type: 'string',
|
|
288
|
+
enum: ['daily', 'weekly', 'monthly'],
|
|
289
|
+
description: 'Time period for trending'
|
|
290
|
+
},
|
|
291
|
+
channels: {
|
|
292
|
+
type: 'array',
|
|
293
|
+
items: {
|
|
294
|
+
type: 'string',
|
|
295
|
+
enum: ['feishu', 'email']
|
|
296
|
+
},
|
|
297
|
+
description: 'Push channels (array: ["email"], ["feishu"], or ["email", "feishu"])'
|
|
298
|
+
},
|
|
299
|
+
email_to: {
|
|
300
|
+
type: 'string',
|
|
301
|
+
format: 'email',
|
|
302
|
+
description: 'Email recipient (required for email channel)'
|
|
303
|
+
},
|
|
304
|
+
feishu_webhook: {
|
|
305
|
+
type: 'string',
|
|
306
|
+
description: 'Feishu webhook URL (required for feishu channel)'
|
|
307
|
+
}
|
|
308
|
+
},
|
|
309
|
+
required: ['since']
|
|
310
|
+
},
|
|
311
|
+
handler: githubTrendingHandler
|
|
312
|
+
};
|
|
313
|
+
exports.default = exports.githubTrendingTool;
|
|
314
|
+
//# sourceMappingURL=tool.js.map
|
package/dist/tool.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool.js","sourceRoot":"","sources":["../src/tool.ts"],"names":[],"mappings":";;;AAAA,4CAA+C;AAC/C,kDAAiD;AACjD,4CAAgD;AA+WvC,+FA/WA,wBAAc,OA+WA;AA9WvB,8CAAkD;AAClD,4CAAgD;AAChD,0CAAgF;AAiDhF;;;;;;GAMG;AACH,KAAK,UAAU,yBAAyB,CACtC,YAA8B,EAC9B,UAAwB,EACxB,aAAqB,CAAC;IAEtB,MAAM,OAAO,GAAqB,EAAE,CAAC;IAErC,sEAAsE;IACtE,MAAM,gBAAgB,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IAElD,0CAA0C;IAC1C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC,IAAI,gBAAgB,EAAE,CAAC;QAC/D,MAAM,KAAK,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,gBAAgB,CAAC,CAAC;QAE1D,OAAO,CAAC,GAAG,CAAC,oCAAoC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,gBAAgB,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,MAAM,GAAG,gBAAgB,CAAC,KAAK,KAAK,CAAC,MAAM,eAAe,gBAAgB,cAAc,CAAC,CAAC;QAEzM,kEAAkE;QAClE,MAAM,YAAY,GAAG,MAAM,OAAO,CAAC,UAAU,CAC3C,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,IAAoB,EAAE,EAAE;YACvC,IAAI,CAAC;gBACH,mFAAmF;gBACnF,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;gBAC7B,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC;oBACjC,UAAU,CAAC,eAAe,CAAC,IAAI,CAAC;oBAChC,IAAI,OAAO,CAAS,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAChC,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC,EAAE,MAAM,CAAC,CAC/D;iBACF,CAAC,CAAC;gBACH,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;gBAExC,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,SAAS,uBAAuB,QAAQ,OAAO,OAAO,CAAC,MAAM,SAAS,CAAC,CAAC;gBAC9F,OAAO,EAAE,GAAG,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC;YAC1C,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,CAAC,SAAS,WAAW,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,EAAE,CAAC,CAAC;gBACxG,OAAO,EAAE,GAAG,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;YACrC,CAAC;QACH,CAAC,CAAC,CACH,CAAC;QAEF,6BAA6B;QAC7B,KAAK,MAAM,MAAM,IAAI,YAAY,EAAE,CAAC;YAClC,IAAI,MAAM,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;gBAClC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC7B,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,qBAAqB,CAClC,MAA4B,EAC5B,eAA6B,EAAE,EAC/B,iBAAuC,EAAE,EACzC,WAAiB;IAEjB,OAAO,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAC;IACvD,OAAO,CAAC,GAAG,CAAC,sCAAsC,EAAE,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC3F,OAAO,CAAC,GAAG,CAAC,4CAA4C,EAAE,YAAY,CAAC,KAAK,CAAC,CAAC;IAC9E,OAAO,CAAC,GAAG,CAAC,gCAAgC,EAAE,MAAM,CAAC,CAAC;IACtD,OAAO,CAAC,GAAG,CAAC,kDAAkD,EAAE,CAAC,CAAC,cAAc,CAAC,CAAC;IAElF,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,cAAc,EAAE,GAAG,MAAM,CAAC;IAE7D,0BAA0B;IAC1B,MAAM,cAAc,GAA2B,QAAQ,IAAI,EAAE,CAAC;IAC9D,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChC,OAAO;YACL,OAAO,EAAE,KAAK;YACd,YAAY,EAAE,CAAC;YACf,SAAS,EAAE,CAAC;YACZ,UAAU,EAAE,CAAC;YACb,WAAW,EAAE,CAAC;YACd,SAAS,EAAE,EAAE;YACb,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,OAAO,EAAE,yBAAyB;SACnC,CAAC;IACJ,CAAC;IAED,uDAAuD;IACvD,MAAM,QAAQ,GAAG,sBAAa,CAAC,WAAW,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC;IACzE,MAAM,UAAU,GAAG,IAAI,yBAAY,CAAC,QAAQ,CAAC,CAAC;IAE9C,6DAA6D;IAC7D,MAAM,OAAO,GAAG,IAAI,uBAAa,CAAC,YAAY,CAAC,CAAC;IAChD,IAAI,YAA8B,CAAC;IAEnC,IAAI,CAAC;QACH,YAAY,GAAG,MAAM,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IACpD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,OAAO,EAAE,KAAK;YACd,YAAY,EAAE,CAAC;YACf,SAAS,EAAE,CAAC;YACZ,UAAU,EAAE,CAAC;YACb,WAAW,EAAE,CAAC;YACd,SAAS,EAAE,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC;YACnC,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,OAAO,EAAE,6BAA6B,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,EAAE;SACjG,CAAC;IACJ,CAAC;IAED,wEAAwE;IACxE,MAAM,cAAc,GAAG,IAAI,wBAAc,EAAE,CAAC;IAC5C,IAAI,WAAW,EAAE,CAAC;QAChB,cAAc,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;IACzC,CAAC;IAED,iEAAiE;IACjE,MAAM,aAAa,GAAG;QACpB,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,OAAO,IAAI,IAAI;QAC/C,cAAc,EAAE,YAAY,EAAE,OAAO,EAAE,cAAc,IAAI,GAAG;KAC7D,CAAC;IAEF,MAAM,kBAAkB,GAAG,cAAc,CAAC,QAAQ,EAAE,CAAC;IACrD,OAAO,CAAC,GAAG,CAAC,kCAAkC,EAAE,IAAI,CAAC,SAAS,CAAC,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACxF,OAAO,CAAC,GAAG,CAAC,gDAAgD,EAAE,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IAC9F,OAAO,CAAC,GAAG,CAAC,kDAAkD,EAAE,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC;IACzH,OAAO,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAC;IAC/D,OAAO,CAAC,GAAG,CAAC,mCAAmC,kBAAkB,CAAC,kBAAkB,EAAE,CAAC,CAAC;IACxF,OAAO,CAAC,GAAG,CAAC,qBAAqB,kBAAkB,CAAC,YAAY,EAAE,CAAC,CAAC;IACpE,OAAO,CAAC,GAAG,CAAC,qBAAqB,kBAAkB,CAAC,YAAY,IAAI,KAAK,EAAE,CAAC,CAAC;IAC7E,OAAO,CAAC,GAAG,CAAC,qBAAqB,kBAAkB,CAAC,YAAY,IAAI,KAAK,EAAE,CAAC,CAAC;IAE7E,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,GAAG,cAAc,CAAC,sBAAsB,CAClF,YAAY,EACZ,aAAa,CACd,CAAC;IAEF,OAAO,CAAC,GAAG,CAAC,oCAAoC,SAAS,CAAC,MAAM,kBAAkB,UAAU,CAAC,MAAM,mBAAmB,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC;IAC5I,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzB,OAAO,CAAC,GAAG,CAAC,4CAA4C,CAAC,CAAC;QAC1D,SAAS,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,SAAS,KAAK,IAAI,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC;IACrG,CAAC;IACD,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC3B,OAAO,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAC;QAC5D,WAAW,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE;YAC9B,MAAM,OAAO,GAAG,cAAc,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAC1D,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,OAAO,EAAE,UAAU,IAAI,CAAC,CAAC,CAAC;YAC1D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,SAAS,KAAK,IAAI,CAAC,KAAK,YAAY,SAAS,mBAAmB,CAAC,CAAC;QACpG,CAAC,CAAC,CAAC;IACL,CAAC;IAED,yFAAyF;IACzF,MAAM,UAAU,GAAG,sBAAa,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;IAC7D,OAAO,CAAC,GAAG,CAAC,yBAAyB,UAAU,2BAA2B,UAAU,CAAC,MAAM,eAAe,CAAC,CAAC;IAE5G,IAAI,qBAAqB,GAAqB,EAAE,CAAC;IACjD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAE7B,IAAI,CAAC;QACH,qBAAqB,GAAG,MAAM,yBAAyB,CAAC,UAAU,EAAE,UAAU,EAAE,UAAU,CAAC,CAAC;IAC9F,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,uDAAuD;QACvD,qBAAqB,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAiB,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;IAC5F,CAAC;IAED,MAAM,eAAe,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;IAC/C,OAAO,CAAC,GAAG,CAAC,gDAAgD,eAAe,OAAO,eAAe,GAAG,UAAU,CAAC,MAAM,yBAAyB,CAAC,CAAC;IAEhJ,iBAAiB;IACjB,cAAc,CAAC,UAAU,CAAC,qBAAqB,CAAC,CAAC;IAEjD,gFAAgF;IAChF,MAAM,oBAAoB,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAiB,EAAE,EAAE;QACjE,MAAM,OAAO,GAAG,cAAc,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QACvD,MAAM,OAAO,GAAG,OAAO,EAAE,UAAU,IAAI,EAAE,CAAC;QAC1C,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,CAAC,GAAG,CAAC,gDAAgD,CAAC,CAAC,SAAS,KAAK,OAAO,CAAC,MAAM,SAAS,CAAC,CAAC;QACvG,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,+CAA+C,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC;QAC5E,CAAC;QACD,OAAO;YACL,GAAG,CAAC;YACJ,UAAU,EAAE,OAAO;SACpB,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,6BAA6B;IAC7B,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;IACtC,OAAO,CAAC,GAAG,CAAC,2CAA2C,qBAAqB,CAAC,MAAM,EAAE,CAAC,CAAC;IACvF,OAAO,CAAC,GAAG,CAAC,2DAA2D,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC;IAC7F,OAAO,CAAC,GAAG,CAAC,mCAAmC,qBAAqB,CAAC,MAAM,EAAE,CAAC,CAAC;IAC/E,OAAO,CAAC,GAAG,CAAC,iCAAiC,qBAAqB,CAAC,MAAM,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC;IAElG,+BAA+B;IAC/B,MAAM,WAAW,GAAgF,EAAE,CAAC;IACpG,MAAM,QAAQ,GAAa,EAAE,CAAC,CAAC,SAAS;IAExC,6BAA6B;IAC7B,MAAM,YAAY,GAAG,cAAc,CAAC,QAAQ,EAAE,CAAC;IAC/C,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;IACtC,OAAO,CAAC,GAAG,CAAC,mCAAmC,YAAY,CAAC,kBAAkB,EAAE,CAAC,CAAC;IAClF,OAAO,CAAC,GAAG,CAAC,qBAAqB,YAAY,CAAC,YAAY,EAAE,CAAC,CAAC;IAC9D,OAAO,CAAC,GAAG,CAAC,qBAAqB,YAAY,CAAC,YAAY,IAAI,KAAK,EAAE,CAAC,CAAC;IACvE,OAAO,CAAC,GAAG,CAAC,qBAAqB,YAAY,CAAC,YAAY,IAAI,KAAK,EAAE,CAAC,CAAC;IAEvE,KAAK,MAAM,aAAa,IAAI,cAAc,EAAE,CAAC;QAC3C,IAAI,CAAC;YACH,IAAI,aAAa,KAAK,QAAQ,EAAE,CAAC;gBAC/B,MAAM,UAAU,GAAG,cAAc,IAAI,YAAY,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAC;gBACjF,IAAI,CAAC,UAAU,EAAE,CAAC;oBAChB,WAAW,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,iCAAiC,EAAE,CAAC,CAAC;oBAClG,QAAQ,CAAC,IAAI,CAAC,0DAA0D,CAAC,CAAC;oBAC1E,SAAS;gBACX,CAAC;gBAED,MAAM,MAAM,GAAG,MAAM,sBAAa,CAAC,IAAI,CAAC,UAAU,EAAE,qBAAqB,EAAE,oBAAoB,CAAC,CAAC;gBACjG,WAAW,CAAC,IAAI,CAAC;oBACf,OAAO,EAAE,QAAQ;oBACjB,OAAO,EAAE,MAAM,CAAC,OAAO;oBACvB,SAAS,EAAE,MAAM,CAAC,SAAS;oBAC3B,KAAK,EAAE,MAAM,CAAC,KAAK;iBACpB,CAAC,CAAC;gBACH,QAAQ,CAAC,IAAI,CAAC,oBAAoB,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACtH,CAAC;iBAAM,IAAI,aAAa,KAAK,OAAO,EAAE,CAAC;gBACrC,MAAM,OAAO,GAAG,QAAQ,IAAI,YAAY,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,IAAI,YAAY,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,CAAC;gBAC9G,IAAI,CAAC,OAAO,EAAE,CAAC;oBACb,WAAW,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,8BAA8B,EAAE,CAAC,CAAC;oBAC9F,QAAQ,CAAC,IAAI,CAAC,sDAAsD,CAAC,CAAC;oBACtE,SAAS;gBACX,CAAC;gBAED,6BAA6B;gBAC7B,MAAM,WAAW,GAAG,sBAAa,CAAC,cAAc,CAC9C,OAAO,EACP,YAAY,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,IAAI,EAAE,EAC7C,YAAY,EAAE,QAAQ,EAAE,KAAK,CAC9B,CAAC;gBACF,MAAM,mBAAmB,GAAoB;oBAC3C,IAAI,EAAE,WAAW,CAAC,MAAM;oBACxB,EAAE,EAAE,OAAO;oBACX,OAAO,EAAE,UAAU,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,MAAM;oBACpF,IAAI,EAAE;wBACJ,IAAI,EAAE,WAAW,CAAC,SAAS;wBAC3B,IAAI,EAAE,WAAW,CAAC,SAAS;wBAC3B,MAAM,EAAE,KAAK,EAAE,eAAe;wBAC9B,IAAI,EAAE;4BACJ,IAAI,EAAE,WAAW,CAAC,MAAM;4BACxB,IAAI,EAAE,WAAW,CAAC,QAAQ;yBAC3B;qBACF;iBACF,CAAC;gBAEF,MAAM,MAAM,GAAG,MAAM,oBAAY,CAAC,IAAI,CAAC,mBAAmB,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,KAAK,CAAC,CAAC;gBAChH,WAAW,CAAC,IAAI,CAAC;oBACf,OAAO,EAAE,OAAO;oBAChB,OAAO,EAAE,MAAM,CAAC,OAAO;oBACvB,SAAS,EAAE,MAAM,CAAC,SAAS;oBAC3B,KAAK,EAAE,MAAM,CAAC,KAAK;iBACpB,CAAC,CAAC;gBACH,QAAQ,CAAC,IAAI,CAAC,mBAAmB,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACrH,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,WAAW,CAAC,IAAI,CAAC;gBACf,OAAO,EAAE,aAAa;gBACtB,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe;aAChE,CAAC,CAAC;YACH,QAAQ,CAAC,IAAI,CAAC,IAAI,aAAa,qBAAqB,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,EAAE,CAAC,CAAC;QAClH,CAAC;IACH,CAAC;IAED,cAAc;IACd,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;IAC9C,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1C,OAAO,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAC;IAEtD,wBAAwB;IACxB,MAAM,YAAY,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;IAC/D,MAAM,cAAc,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IAC/E,MAAM,eAAe,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IAE/E,UAAU;IACV,IAAI,OAAO,GAAG,EAAE,CAAC;IACjB,IAAI,YAAY,KAAK,cAAc,CAAC,MAAM,EAAE,CAAC;QAC3C,OAAO,GAAG,WAAW,YAAY,MAAM,CAAC;IAC1C,CAAC;SAAM,IAAI,YAAY,GAAG,CAAC,EAAE,CAAC;QAC5B,MAAM,aAAa,GAAG,WAAW;aAC9B,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;aACvB,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC;aACpC,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,OAAO,GAAG,QAAQ,YAAY,IAAI,cAAc,CAAC,MAAM,eAAe,aAAa,EAAE,CAAC;IACxF,CAAC;SAAM,CAAC;QACN,MAAM,aAAa,GAAG,WAAW;aAC9B,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;aACvB,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC;aACpC,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,OAAO,GAAG,YAAY,aAAa,EAAE,CAAC;IACxC,CAAC;IAED,OAAO;QACL,OAAO,EAAE,YAAY,GAAG,CAAC;QACzB,YAAY,EAAE,qBAAqB,CAAC,MAAM;QAC1C,SAAS,EAAE,SAAS,CAAC,MAAM;QAC3B,UAAU,EAAE,WAAW,CAAC,MAAM;QAC9B,WAAW,EAAE,YAAY,CAAC,MAAM;QAChC,SAAS,EAAE,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC;QACpC,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,OAAO;QACP,YAAY,EAAE,cAAc,CAAC,UAAU,EAAE,CAAC,yCAAyC;KACpF,CAAC;AACJ,CAAC;AAKD;;GAEG;AACU,QAAA,kBAAkB,GAAuB;IACpD,IAAI,EAAE,0BAA0B;IAChC,WAAW,EAAE,gEAAgE;IAC7E,UAAU,EAAE;QACV,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,KAAK,EAAE;gBACL,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,SAAS,CAAC;gBACpC,WAAW,EAAE,0BAA0B;aACxC;YACD,QAAQ,EAAE;gBACR,IAAI,EAAE,OAAO;gBACb,KAAK,EAAE;oBACL,IAAI,EAAE,QAAQ;oBACd,IAAI,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC;iBAC1B;gBACD,WAAW,EAAE,sEAAsE;aACpF;YACD,QAAQ,EAAE;gBACR,IAAI,EAAE,QAAQ;gBACd,MAAM,EAAE,OAAO;gBACf,WAAW,EAAE,8CAA8C;aAC5D;YACD,cAAc,EAAE;gBACd,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,kDAAkD;aAChE;SACF;QACD,QAAQ,EAAE,CAAC,OAAO,CAAC;KACpB;IACD,OAAO,EAAE,qBAAqB;CAC/B,CAAC;AAEF,kBAAe,0BAAkB,CAAC"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unified Logger with Console + File support
|
|
3
|
+
*
|
|
4
|
+
* Features:
|
|
5
|
+
* - Console logging with timestamp, prefix, and level
|
|
6
|
+
* - File logging to ~/.openclaw/logs/github-trending/trending-YYYY-MM.log
|
|
7
|
+
* - Single instance per module (prefix-based)
|
|
8
|
+
* - Static methods for convenience
|
|
9
|
+
* - Unified log format
|
|
10
|
+
*/
|
|
11
|
+
export declare class Logger {
|
|
12
|
+
private static instances;
|
|
13
|
+
private prefix;
|
|
14
|
+
private logDir;
|
|
15
|
+
private enabled;
|
|
16
|
+
private logLevel;
|
|
17
|
+
constructor(prefix?: string);
|
|
18
|
+
/**
|
|
19
|
+
* Get logger instance for a specific module
|
|
20
|
+
* Singleton per prefix
|
|
21
|
+
*/
|
|
22
|
+
static get(prefix: string): Logger;
|
|
23
|
+
/**
|
|
24
|
+
* Set minimum log level (default: INFO)
|
|
25
|
+
*/
|
|
26
|
+
setLogLevel(level: LogLevel): void;
|
|
27
|
+
/**
|
|
28
|
+
* Get log file path (monthly rotation)
|
|
29
|
+
*/
|
|
30
|
+
private getLogFilePath;
|
|
31
|
+
/**
|
|
32
|
+
* Format argument for logging
|
|
33
|
+
*/
|
|
34
|
+
private formatArg;
|
|
35
|
+
/**
|
|
36
|
+
* Check if log level is enabled
|
|
37
|
+
*/
|
|
38
|
+
private isLevelEnabled;
|
|
39
|
+
/**
|
|
40
|
+
* Format message with timestamp and prefix
|
|
41
|
+
*/
|
|
42
|
+
private formatMessage;
|
|
43
|
+
/**
|
|
44
|
+
* Write to file
|
|
45
|
+
*/
|
|
46
|
+
private logToFile;
|
|
47
|
+
/**
|
|
48
|
+
* Internal log method
|
|
49
|
+
*/
|
|
50
|
+
private log;
|
|
51
|
+
debug(message: string, ...args: any[]): void;
|
|
52
|
+
info(message: string, ...args: any[]): void;
|
|
53
|
+
success(message: string, ...args: any[]): void;
|
|
54
|
+
warn(message: string, ...args: any[]): void;
|
|
55
|
+
error(message: string | Error, ...args: any[]): void;
|
|
56
|
+
/**
|
|
57
|
+
* Get the logger prefix (for testing)
|
|
58
|
+
*/
|
|
59
|
+
getPrefix(): string;
|
|
60
|
+
/**
|
|
61
|
+
* Create a timer function for measuring execution time
|
|
62
|
+
*/
|
|
63
|
+
timer(operation: string): () => number;
|
|
64
|
+
static debug(message: string, ...args: any[]): void;
|
|
65
|
+
static info(message: string, ...args: any[]): void;
|
|
66
|
+
static success(message: string, ...args: any[]): void;
|
|
67
|
+
static warn(message: string, ...args: any[]): void;
|
|
68
|
+
static error(message: string | Error, ...args: any[]): void;
|
|
69
|
+
}
|
|
70
|
+
export declare enum LogLevel {
|
|
71
|
+
DEBUG = "debug",
|
|
72
|
+
INFO = "info",
|
|
73
|
+
WARN = "warn",
|
|
74
|
+
ERROR = "error",
|
|
75
|
+
SUCCESS = "success"
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAIA;;;;;;;;;GASG;AACH,qBAAa,MAAM;IACjB,OAAO,CAAC,MAAM,CAAC,SAAS,CAAkC;IAC1D,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,QAAQ,CAA2B;gBAE/B,MAAM,GAAE,MAAc;IAkBlC;;;OAGG;IACH,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAOlC;;OAEG;IACH,WAAW,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI;IAIlC;;OAEG;IACH,OAAO,CAAC,cAAc;IAOtB;;OAEG;IACH,OAAO,CAAC,SAAS;IAajB;;OAEG;IACH,OAAO,CAAC,cAAc;IAWtB;;OAEG;IACH,OAAO,CAAC,aAAa;IAYrB;;OAEG;IACH,OAAO,CAAC,SAAS;IAWjB;;OAEG;IACH,OAAO,CAAC,GAAG;IA8BX,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;IAI5C,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;IAI3C,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;IAO9C,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;IAI3C,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,KAAK,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;IAQpD;;OAEG;IACH,SAAS,IAAI,MAAM;IAInB;;OAEG;IACH,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,MAAM;IAWtC,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;IAInD,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;IAIlD,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;IAIrD,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;IAIlD,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,KAAK,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;CAG5D;AAED,oBAAY,QAAQ;IAClB,KAAK,UAAU;IACf,IAAI,SAAS;IACb,IAAI,SAAS;IACb,KAAK,UAAU;IACf,OAAO,YAAY;CACpB"}
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.LogLevel = exports.Logger = void 0;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const os_1 = __importDefault(require("os"));
|
|
10
|
+
/**
|
|
11
|
+
* Unified Logger with Console + File support
|
|
12
|
+
*
|
|
13
|
+
* Features:
|
|
14
|
+
* - Console logging with timestamp, prefix, and level
|
|
15
|
+
* - File logging to ~/.openclaw/logs/github-trending/trending-YYYY-MM.log
|
|
16
|
+
* - Single instance per module (prefix-based)
|
|
17
|
+
* - Static methods for convenience
|
|
18
|
+
* - Unified log format
|
|
19
|
+
*/
|
|
20
|
+
class Logger {
|
|
21
|
+
constructor(prefix = 'App') {
|
|
22
|
+
this.enabled = true;
|
|
23
|
+
this.logLevel = LogLevel.INFO;
|
|
24
|
+
this.prefix = `[${prefix}]`;
|
|
25
|
+
this.logDir = ''; // Initialize
|
|
26
|
+
// Setup log directory (same as old FileLogger)
|
|
27
|
+
try {
|
|
28
|
+
const openclawDataDir = process.env.OPENCLAW_DATA_DIR || path_1.default.join(os_1.default.homedir(), '.openclaw');
|
|
29
|
+
this.logDir = path_1.default.join(openclawDataDir, 'logs', 'github-trending');
|
|
30
|
+
if (!fs_1.default.existsSync(this.logDir)) {
|
|
31
|
+
fs_1.default.mkdirSync(this.logDir, { recursive: true });
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
console.error('[Logger] Failed to create log directory:', error);
|
|
36
|
+
this.enabled = false;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Get logger instance for a specific module
|
|
41
|
+
* Singleton per prefix
|
|
42
|
+
*/
|
|
43
|
+
static get(prefix) {
|
|
44
|
+
if (!Logger.instances.has(prefix)) {
|
|
45
|
+
Logger.instances.set(prefix, new Logger(prefix));
|
|
46
|
+
}
|
|
47
|
+
return Logger.instances.get(prefix);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Set minimum log level (default: INFO)
|
|
51
|
+
*/
|
|
52
|
+
setLogLevel(level) {
|
|
53
|
+
this.logLevel = level;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Get log file path (monthly rotation)
|
|
57
|
+
*/
|
|
58
|
+
getLogFilePath() {
|
|
59
|
+
const date = new Date();
|
|
60
|
+
const year = date.getFullYear();
|
|
61
|
+
const month = String(date.getMonth() + 1).padStart(2, '0');
|
|
62
|
+
return path_1.default.join(this.logDir, `trending-${year}-${month}.log`);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Format argument for logging
|
|
66
|
+
*/
|
|
67
|
+
formatArg(arg) {
|
|
68
|
+
if (arg instanceof Error) {
|
|
69
|
+
return arg.message + (arg.stack ? `\n${arg.stack}` : '');
|
|
70
|
+
}
|
|
71
|
+
if (typeof arg === 'object') {
|
|
72
|
+
return JSON.stringify(arg, null, 2);
|
|
73
|
+
}
|
|
74
|
+
if (typeof arg === 'function') {
|
|
75
|
+
return '[Function]';
|
|
76
|
+
}
|
|
77
|
+
return String(arg);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Check if log level is enabled
|
|
81
|
+
*/
|
|
82
|
+
isLevelEnabled(level) {
|
|
83
|
+
const levelOrder = {
|
|
84
|
+
[LogLevel.DEBUG]: 0,
|
|
85
|
+
[LogLevel.INFO]: 1,
|
|
86
|
+
[LogLevel.WARN]: 2,
|
|
87
|
+
[LogLevel.ERROR]: 3,
|
|
88
|
+
[LogLevel.SUCCESS]: 1, // Same as INFO for filtering
|
|
89
|
+
};
|
|
90
|
+
return levelOrder[level] >= levelOrder[this.logLevel];
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Format message with timestamp and prefix
|
|
94
|
+
*/
|
|
95
|
+
formatMessage(level, message, args) {
|
|
96
|
+
const timestamp = new Date().toISOString();
|
|
97
|
+
const levelStr = level.toString().toUpperCase();
|
|
98
|
+
let formattedMessage = `${timestamp} ${this.prefix} [${levelStr}] ${message}`;
|
|
99
|
+
if (args && args.length > 0) {
|
|
100
|
+
formattedMessage += ' ' + args.map(arg => this.formatArg(arg)).join(' ');
|
|
101
|
+
}
|
|
102
|
+
return formattedMessage;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Write to file
|
|
106
|
+
*/
|
|
107
|
+
logToFile(message) {
|
|
108
|
+
if (!this.enabled)
|
|
109
|
+
return;
|
|
110
|
+
try {
|
|
111
|
+
const logFilePath = this.getLogFilePath();
|
|
112
|
+
fs_1.default.appendFileSync(logFilePath, message + '\n', 'utf8');
|
|
113
|
+
}
|
|
114
|
+
catch (error) {
|
|
115
|
+
// Fail silently - don't crash the app if logging fails
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Internal log method
|
|
120
|
+
*/
|
|
121
|
+
log(level, message, ...args) {
|
|
122
|
+
if (!this.isLevelEnabled(level))
|
|
123
|
+
return;
|
|
124
|
+
const formattedMessage = this.formatMessage(level, message, args);
|
|
125
|
+
// Console output with color
|
|
126
|
+
switch (level) {
|
|
127
|
+
case LogLevel.DEBUG:
|
|
128
|
+
console.log(formattedMessage);
|
|
129
|
+
break;
|
|
130
|
+
case LogLevel.INFO:
|
|
131
|
+
console.log(formattedMessage);
|
|
132
|
+
break;
|
|
133
|
+
case LogLevel.WARN:
|
|
134
|
+
console.warn(formattedMessage);
|
|
135
|
+
break;
|
|
136
|
+
case LogLevel.ERROR:
|
|
137
|
+
console.error(formattedMessage);
|
|
138
|
+
break;
|
|
139
|
+
case LogLevel.SUCCESS:
|
|
140
|
+
console.log(formattedMessage); // Green color in terminal
|
|
141
|
+
break;
|
|
142
|
+
}
|
|
143
|
+
// File logging
|
|
144
|
+
this.logToFile(formattedMessage);
|
|
145
|
+
}
|
|
146
|
+
// Public logging methods
|
|
147
|
+
debug(message, ...args) {
|
|
148
|
+
this.log(LogLevel.DEBUG, message, ...args);
|
|
149
|
+
}
|
|
150
|
+
info(message, ...args) {
|
|
151
|
+
this.log(LogLevel.INFO, message, ...args);
|
|
152
|
+
}
|
|
153
|
+
success(message, ...args) {
|
|
154
|
+
const successMsg = message.includes('✅') || message.includes('succeed')
|
|
155
|
+
? message
|
|
156
|
+
: `✅ ${message}`;
|
|
157
|
+
this.log(LogLevel.SUCCESS, successMsg, ...args);
|
|
158
|
+
}
|
|
159
|
+
warn(message, ...args) {
|
|
160
|
+
this.log(LogLevel.WARN, message, ...args);
|
|
161
|
+
}
|
|
162
|
+
error(message, ...args) {
|
|
163
|
+
if (message instanceof Error) {
|
|
164
|
+
this.log(LogLevel.ERROR, message.message, [message, ...args]);
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
this.log(LogLevel.ERROR, message, ...args);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Get the logger prefix (for testing)
|
|
172
|
+
*/
|
|
173
|
+
getPrefix() {
|
|
174
|
+
return this.prefix;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Create a timer function for measuring execution time
|
|
178
|
+
*/
|
|
179
|
+
timer(operation) {
|
|
180
|
+
const startTime = Date.now();
|
|
181
|
+
return () => {
|
|
182
|
+
const elapsed = Date.now() - startTime;
|
|
183
|
+
this.info(`${operation} completed in ${elapsed}ms`);
|
|
184
|
+
return elapsed;
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
// Static convenience methods (uses 'App' as default prefix)
|
|
188
|
+
static debug(message, ...args) {
|
|
189
|
+
Logger.get('App').debug(message, ...args);
|
|
190
|
+
}
|
|
191
|
+
static info(message, ...args) {
|
|
192
|
+
Logger.get('App').info(message, ...args);
|
|
193
|
+
}
|
|
194
|
+
static success(message, ...args) {
|
|
195
|
+
Logger.get('App').success(message, ...args);
|
|
196
|
+
}
|
|
197
|
+
static warn(message, ...args) {
|
|
198
|
+
Logger.get('App').warn(message, ...args);
|
|
199
|
+
}
|
|
200
|
+
static error(message, ...args) {
|
|
201
|
+
Logger.get('App').error(message, ...args);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
exports.Logger = Logger;
|
|
205
|
+
Logger.instances = new Map();
|
|
206
|
+
var LogLevel;
|
|
207
|
+
(function (LogLevel) {
|
|
208
|
+
LogLevel["DEBUG"] = "debug";
|
|
209
|
+
LogLevel["INFO"] = "info";
|
|
210
|
+
LogLevel["WARN"] = "warn";
|
|
211
|
+
LogLevel["ERROR"] = "error";
|
|
212
|
+
LogLevel["SUCCESS"] = "success";
|
|
213
|
+
})(LogLevel || (exports.LogLevel = LogLevel = {}));
|
|
214
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Convert markdown text to HTML
|
|
3
|
+
* This function sanitizes the output to prevent XSS attacks
|
|
4
|
+
*
|
|
5
|
+
* @param markdown - Markdown text to convert
|
|
6
|
+
* @returns Sanitized HTML string
|
|
7
|
+
*/
|
|
8
|
+
export declare function markdownToHTML(markdown: string): string;
|
|
9
|
+
//# sourceMappingURL=markdown.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/utils/markdown.ts"],"names":[],"mappings":"AAGA;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAyBvD"}
|