@tocharianou/mcp-server-kibana 0.6.1
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 +201 -0
- package/README.md +530 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +417 -0
- package/dist/index.js.map +1 -0
- package/dist/kibana-openapi-source.yaml +52597 -0
- package/dist/src/analysis-tools.d.ts +6 -0
- package/dist/src/analysis-tools.js +134 -0
- package/dist/src/analysis-tools.js.map +1 -0
- package/dist/src/base-tools.d.ts +2 -0
- package/dist/src/base-tools.js +349 -0
- package/dist/src/base-tools.js.map +1 -0
- package/dist/src/dependency-analyzer.d.ts +65 -0
- package/dist/src/dependency-analyzer.js +233 -0
- package/dist/src/dependency-analyzer.js.map +1 -0
- package/dist/src/health-analyzer.d.ts +60 -0
- package/dist/src/health-analyzer.js +301 -0
- package/dist/src/health-analyzer.js.map +1 -0
- package/dist/src/kibana-openapi-source.yaml +52597 -0
- package/dist/src/openapi-simplifier.d.ts +33 -0
- package/dist/src/openapi-simplifier.js +122 -0
- package/dist/src/openapi-simplifier.js.map +1 -0
- package/dist/src/prompts.d.ts +2 -0
- package/dist/src/prompts.js +91 -0
- package/dist/src/prompts.js.map +1 -0
- package/dist/src/resources.d.ts +2 -0
- package/dist/src/resources.js +125 -0
- package/dist/src/resources.js.map +1 -0
- package/dist/src/types.d.ts +150 -0
- package/dist/src/types.js +38 -0
- package/dist/src/types.js.map +1 -0
- package/dist/src/vl_create_tools.d.ts +5 -0
- package/dist/src/vl_create_tools.js +264 -0
- package/dist/src/vl_create_tools.js.map +1 -0
- package/dist/src/vl_delete_tools.d.ts +5 -0
- package/dist/src/vl_delete_tools.js +158 -0
- package/dist/src/vl_delete_tools.js.map +1 -0
- package/dist/src/vl_get_tools.d.ts +5 -0
- package/dist/src/vl_get_tools.js +201 -0
- package/dist/src/vl_get_tools.js.map +1 -0
- package/dist/src/vl_search_tools.d.ts +9 -0
- package/dist/src/vl_search_tools.js +290 -0
- package/dist/src/vl_search_tools.js.map +1 -0
- package/dist/src/vl_update_tools.d.ts +5 -0
- package/dist/src/vl_update_tools.js +372 -0
- package/dist/src/vl_update_tools.js.map +1 -0
- package/kibana-openapi-source.yaml +52597 -0
- package/package.json +95 -0
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Saved Object Dependency Analyzer
|
|
3
|
+
* Analyzes reference relationships between Kibana objects (Dashboard, Visualization, Index Pattern, etc.)
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Build dependency tree
|
|
7
|
+
*/
|
|
8
|
+
export async function buildDependencyTree(kibanaClient, rootId, rootType, space, maxDepth = 5) {
|
|
9
|
+
const allNodes = new Map();
|
|
10
|
+
const visited = new Set();
|
|
11
|
+
// Recursively traverse dependencies
|
|
12
|
+
async function traverse(id, type, depth) {
|
|
13
|
+
const key = `${type}:${id}`;
|
|
14
|
+
if (visited.has(key) || depth > maxDepth) {
|
|
15
|
+
return allNodes.get(key) || { id, type, referencedBy: [], references: [], depth };
|
|
16
|
+
}
|
|
17
|
+
visited.add(key);
|
|
18
|
+
try {
|
|
19
|
+
// Get object details
|
|
20
|
+
const obj = await kibanaClient.get(`/api/saved_objects/${type}/${id}`, { space });
|
|
21
|
+
const node = {
|
|
22
|
+
id,
|
|
23
|
+
type,
|
|
24
|
+
title: obj.attributes?.title || obj.attributes?.name,
|
|
25
|
+
referencedBy: [],
|
|
26
|
+
references: obj.references || [],
|
|
27
|
+
depth
|
|
28
|
+
};
|
|
29
|
+
allNodes.set(key, node);
|
|
30
|
+
// Recursively process referenced objects
|
|
31
|
+
if (obj.references && obj.references.length > 0) {
|
|
32
|
+
for (const ref of obj.references) {
|
|
33
|
+
const childNode = await traverse(ref.id, ref.type, depth + 1);
|
|
34
|
+
// Record reverse reference
|
|
35
|
+
const childKey = `${ref.type}:${ref.id}`;
|
|
36
|
+
const existingChild = allNodes.get(childKey);
|
|
37
|
+
if (existingChild) {
|
|
38
|
+
existingChild.referencedBy.push({ id, type, name: node.title || id });
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return node;
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
console.error(`Failed to fetch ${type}:${id}`, error);
|
|
46
|
+
return { id, type, referencedBy: [], references: [], depth };
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
const root = await traverse(rootId, rootType, 0);
|
|
50
|
+
// Calculate statistics
|
|
51
|
+
let maxDepthFound = 0;
|
|
52
|
+
const referenceCounts = new Map();
|
|
53
|
+
const orphans = [];
|
|
54
|
+
for (const [key, node] of allNodes.entries()) {
|
|
55
|
+
maxDepthFound = Math.max(maxDepthFound, node.depth);
|
|
56
|
+
const refCount = node.referencedBy.length;
|
|
57
|
+
referenceCounts.set(key, refCount);
|
|
58
|
+
if (refCount === 0 && key !== `${rootType}:${rootId}`) {
|
|
59
|
+
orphans.push({ id: node.id, type: node.type, title: node.title });
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
const topReferenced = Array.from(referenceCounts.entries())
|
|
63
|
+
.sort((a, b) => b[1] - a[1])
|
|
64
|
+
.slice(0, 10)
|
|
65
|
+
.map(([key, count]) => {
|
|
66
|
+
const node = allNodes.get(key);
|
|
67
|
+
return { id: node.id, type: node.type, title: node.title, count };
|
|
68
|
+
});
|
|
69
|
+
return {
|
|
70
|
+
root,
|
|
71
|
+
allNodes,
|
|
72
|
+
summary: {
|
|
73
|
+
total_objects: allNodes.size,
|
|
74
|
+
max_depth: maxDepthFound,
|
|
75
|
+
top_referenced: topReferenced,
|
|
76
|
+
orphans: orphans.slice(0, 5)
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Analyze impact scope of deleting/modifying an object
|
|
82
|
+
*/
|
|
83
|
+
export async function analyzeImpact(kibanaClient, targetId, targetType, space) {
|
|
84
|
+
// Reverse search: find all objects that reference this object
|
|
85
|
+
try {
|
|
86
|
+
const searchResult = await kibanaClient.post('/api/saved_objects/_find', {
|
|
87
|
+
type: ['dashboard', 'visualization', 'lens', 'search', 'map'],
|
|
88
|
+
hasReference: { type: targetType, id: targetId },
|
|
89
|
+
perPage: 100
|
|
90
|
+
}, { space });
|
|
91
|
+
const directDeps = searchResult.saved_objects || [];
|
|
92
|
+
const affectedDashboards = directDeps
|
|
93
|
+
.filter((obj) => obj.type === 'dashboard')
|
|
94
|
+
.map((obj) => ({
|
|
95
|
+
id: obj.id,
|
|
96
|
+
type: obj.type,
|
|
97
|
+
name: obj.attributes?.title || obj.id
|
|
98
|
+
}));
|
|
99
|
+
// Recursively find indirect dependencies (what references the dependent objects)
|
|
100
|
+
let indirectCount = 0;
|
|
101
|
+
for (const dep of directDeps) {
|
|
102
|
+
if (dep.type !== 'dashboard') {
|
|
103
|
+
const secondLevel = await kibanaClient.post('/api/saved_objects/_find', {
|
|
104
|
+
type: ['dashboard'],
|
|
105
|
+
hasReference: { type: dep.type, id: dep.id },
|
|
106
|
+
perPage: 100
|
|
107
|
+
}, { space });
|
|
108
|
+
indirectCount += (secondLevel.saved_objects || []).length;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
// Risk assessment
|
|
112
|
+
let riskLevel = 'Low';
|
|
113
|
+
if (affectedDashboards.length > 10)
|
|
114
|
+
riskLevel = 'Critical';
|
|
115
|
+
else if (affectedDashboards.length > 5)
|
|
116
|
+
riskLevel = 'High';
|
|
117
|
+
else if (affectedDashboards.length > 0)
|
|
118
|
+
riskLevel = 'Medium';
|
|
119
|
+
let recommendation = '';
|
|
120
|
+
if (riskLevel === 'Critical') {
|
|
121
|
+
recommendation = 'â ī¸ Warning: Object is heavily referenced by Dashboards. Deletion/modification may cause severe impact. Recommend testing in test space first.';
|
|
122
|
+
}
|
|
123
|
+
else if (riskLevel === 'High') {
|
|
124
|
+
recommendation = 'â ī¸ Notice: Object is used by multiple Dashboards. Recommend notifying relevant users.';
|
|
125
|
+
}
|
|
126
|
+
else if (riskLevel === 'Medium') {
|
|
127
|
+
recommendation = 'đ Note: Object has some dependencies. Confirm if referencing parties need synchronous updates.';
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
recommendation = 'â
Safe: Object is not referenced by other objects, can be safely deleted/modified.';
|
|
131
|
+
}
|
|
132
|
+
// Get target object info
|
|
133
|
+
const targetObj = await kibanaClient.get(`/api/saved_objects/${targetType}/${targetId}`, { space });
|
|
134
|
+
return {
|
|
135
|
+
target: {
|
|
136
|
+
id: targetId,
|
|
137
|
+
type: targetType,
|
|
138
|
+
title: targetObj.attributes?.title || targetObj.attributes?.name
|
|
139
|
+
},
|
|
140
|
+
direct_dependencies: directDeps.length,
|
|
141
|
+
indirect_dependencies: indirectCount,
|
|
142
|
+
affected_dashboards: affectedDashboards,
|
|
143
|
+
risk_level: riskLevel,
|
|
144
|
+
recommendation
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
catch (error) {
|
|
148
|
+
throw new Error(`Impact analysis failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Format dependency tree to Markdown
|
|
153
|
+
*/
|
|
154
|
+
export function formatDependencyTreeToMarkdown(tree) {
|
|
155
|
+
let md = `# Dependency Analysis\n\n`;
|
|
156
|
+
md += `## đ Statistics Summary\n`;
|
|
157
|
+
md += `- Total Objects: ${tree.summary.total_objects}\n`;
|
|
158
|
+
md += `- Max Dependency Depth: ${tree.summary.max_depth}\n`;
|
|
159
|
+
md += `- Orphan Objects: ${tree.summary.orphans.length}\n\n`;
|
|
160
|
+
if (tree.summary.top_referenced.length > 0) {
|
|
161
|
+
md += `## đĨ Most Referenced Objects\n`;
|
|
162
|
+
tree.summary.top_referenced.forEach((item, index) => {
|
|
163
|
+
md += `${index + 1}. **${item.title || item.id}** (${item.type}) - Referenced ${item.count} times\n`;
|
|
164
|
+
});
|
|
165
|
+
md += '\n';
|
|
166
|
+
}
|
|
167
|
+
if (tree.summary.orphans.length > 0) {
|
|
168
|
+
md += `## đ Orphan Objects (Not Referenced)\n`;
|
|
169
|
+
tree.summary.orphans.forEach(item => {
|
|
170
|
+
md += `- ${item.title || item.id} (${item.type})\n`;
|
|
171
|
+
});
|
|
172
|
+
md += '\n';
|
|
173
|
+
}
|
|
174
|
+
// Tree diagram
|
|
175
|
+
md += `## đŗ Dependency Tree\n`;
|
|
176
|
+
md += formatNodeTree(tree.root, tree.allNodes, '', new Set());
|
|
177
|
+
return md;
|
|
178
|
+
}
|
|
179
|
+
function formatNodeTree(node, allNodes, prefix, visited) {
|
|
180
|
+
const key = `${node.type}:${node.id}`;
|
|
181
|
+
let result = `${prefix}đĻ **${node.title || node.id}** (${node.type})\n`;
|
|
182
|
+
if (visited.has(key)) {
|
|
183
|
+
result += `${prefix} âģ (Circular Reference)\n`;
|
|
184
|
+
return result;
|
|
185
|
+
}
|
|
186
|
+
visited.add(key);
|
|
187
|
+
if (node.references.length > 0) {
|
|
188
|
+
node.references.forEach((ref, index) => {
|
|
189
|
+
const isLast = index === node.references.length - 1;
|
|
190
|
+
const childKey = `${ref.type}:${ref.id}`;
|
|
191
|
+
const childNode = allNodes.get(childKey);
|
|
192
|
+
if (childNode) {
|
|
193
|
+
const childPrefix = prefix + (isLast ? ' ââ ' : ' ââ ');
|
|
194
|
+
const nextPrefix = prefix + (isLast ? ' ' : ' â ');
|
|
195
|
+
result += formatNodeTree(childNode, allNodes, childPrefix, new Set(visited));
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
result += `${prefix}${isLast ? ' ââ ' : ' ââ '}đ ${ref.name || ref.id} (${ref.type})\n`;
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
return result;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Format impact analysis to Markdown
|
|
206
|
+
*/
|
|
207
|
+
export function formatImpactAnalysisToMarkdown(analysis) {
|
|
208
|
+
let md = `# Impact Analysis\n\n`;
|
|
209
|
+
md += `## đ¯ Target Object\n`;
|
|
210
|
+
md += `- **Name**: ${analysis.target.title || analysis.target.id}\n`;
|
|
211
|
+
md += `- **Type**: ${analysis.target.type}\n`;
|
|
212
|
+
md += `- **ID**: ${analysis.target.id}\n\n`;
|
|
213
|
+
md += `## đ Dependency Statistics\n`;
|
|
214
|
+
md += `- Direct Dependencies: ${analysis.direct_dependencies} objects\n`;
|
|
215
|
+
md += `- Indirect Dependencies: ${analysis.indirect_dependencies} objects\n`;
|
|
216
|
+
md += `- Affected Dashboards: ${analysis.affected_dashboards.length}\n\n`;
|
|
217
|
+
const riskEmoji = {
|
|
218
|
+
'Low': 'â
',
|
|
219
|
+
'Medium': 'â ī¸',
|
|
220
|
+
'High': 'đĨ',
|
|
221
|
+
'Critical': 'đ¨'
|
|
222
|
+
};
|
|
223
|
+
md += `## ${riskEmoji[analysis.risk_level]} Risk Assessment: ${analysis.risk_level}\n`;
|
|
224
|
+
md += `${analysis.recommendation}\n\n`;
|
|
225
|
+
if (analysis.affected_dashboards.length > 0) {
|
|
226
|
+
md += `## đ Affected Dashboard List\n`;
|
|
227
|
+
analysis.affected_dashboards.forEach((dash, index) => {
|
|
228
|
+
md += `${index + 1}. ${dash.name} (ID: ${dash.id})\n`;
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
return md;
|
|
232
|
+
}
|
|
233
|
+
//# sourceMappingURL=dependency-analyzer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dependency-analyzer.js","sourceRoot":"","sources":["../../src/dependency-analyzer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dashboard Health Analyzer
|
|
3
|
+
* Detects potential issues in Dashboards (broken references, performance issues, etc.)
|
|
4
|
+
*/
|
|
5
|
+
import type { KibanaClient } from "./types";
|
|
6
|
+
export interface HealthIssue {
|
|
7
|
+
severity: 'info' | 'warning' | 'error' | 'critical';
|
|
8
|
+
category: 'broken_reference' | 'performance' | 'configuration' | 'data_quality';
|
|
9
|
+
message: string;
|
|
10
|
+
details?: any;
|
|
11
|
+
suggestion?: string;
|
|
12
|
+
}
|
|
13
|
+
export interface PanelHealth {
|
|
14
|
+
panel_id: string;
|
|
15
|
+
panel_type: string;
|
|
16
|
+
title?: string;
|
|
17
|
+
issues: HealthIssue[];
|
|
18
|
+
status: 'healthy' | 'warning' | 'unhealthy';
|
|
19
|
+
}
|
|
20
|
+
export interface DashboardHealth {
|
|
21
|
+
id: string;
|
|
22
|
+
title: string;
|
|
23
|
+
overall_status: 'healthy' | 'warning' | 'unhealthy';
|
|
24
|
+
overall_score: number;
|
|
25
|
+
panel_count: number;
|
|
26
|
+
panels: PanelHealth[];
|
|
27
|
+
global_issues: HealthIssue[];
|
|
28
|
+
summary: {
|
|
29
|
+
healthy_panels: number;
|
|
30
|
+
warning_panels: number;
|
|
31
|
+
unhealthy_panels: number;
|
|
32
|
+
total_issues: number;
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
export interface BatchHealthReport {
|
|
36
|
+
dashboards: DashboardHealth[];
|
|
37
|
+
summary: {
|
|
38
|
+
total_dashboards: number;
|
|
39
|
+
healthy: number;
|
|
40
|
+
warning: number;
|
|
41
|
+
unhealthy: number;
|
|
42
|
+
critical_issues: number;
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Analyze health status of a single Dashboard
|
|
47
|
+
*/
|
|
48
|
+
export declare function analyzeDashboardHealth(kibanaClient: KibanaClient, dashboardId: string, space?: string, checkESIndices?: boolean): Promise<DashboardHealth>;
|
|
49
|
+
/**
|
|
50
|
+
* Batch analyze health of multiple Dashboards
|
|
51
|
+
*/
|
|
52
|
+
export declare function batchAnalyzeDashboards(kibanaClient: KibanaClient, space?: string, maxDashboards?: number): Promise<BatchHealthReport>;
|
|
53
|
+
/**
|
|
54
|
+
* Format health report to Markdown
|
|
55
|
+
*/
|
|
56
|
+
export declare function formatHealthReportToMarkdown(health: DashboardHealth): string;
|
|
57
|
+
/**
|
|
58
|
+
* Format batch health report to Markdown
|
|
59
|
+
*/
|
|
60
|
+
export declare function formatBatchHealthReportToMarkdown(report: BatchHealthReport): string;
|
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dashboard Health Analyzer
|
|
3
|
+
* Detects potential issues in Dashboards (broken references, performance issues, etc.)
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Analyze health status of a single Dashboard
|
|
7
|
+
*/
|
|
8
|
+
export async function analyzeDashboardHealth(kibanaClient, dashboardId, space, checkESIndices = false) {
|
|
9
|
+
try {
|
|
10
|
+
// Get Dashboard details
|
|
11
|
+
const dashboard = await kibanaClient.get(`/api/saved_objects/dashboard/${dashboardId}`, { space });
|
|
12
|
+
const title = dashboard.attributes?.title || dashboardId;
|
|
13
|
+
const panelsJSON = dashboard.attributes?.panelsJSON;
|
|
14
|
+
if (!panelsJSON) {
|
|
15
|
+
return {
|
|
16
|
+
id: dashboardId,
|
|
17
|
+
title,
|
|
18
|
+
overall_status: 'unhealthy',
|
|
19
|
+
overall_score: 0,
|
|
20
|
+
panel_count: 0,
|
|
21
|
+
panels: [],
|
|
22
|
+
global_issues: [{
|
|
23
|
+
severity: 'error',
|
|
24
|
+
category: 'configuration',
|
|
25
|
+
message: 'Dashboard has no panels configured',
|
|
26
|
+
suggestion: 'Add at least one visualization panel'
|
|
27
|
+
}],
|
|
28
|
+
summary: {
|
|
29
|
+
healthy_panels: 0,
|
|
30
|
+
warning_panels: 0,
|
|
31
|
+
unhealthy_panels: 0,
|
|
32
|
+
total_issues: 1
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
const panels = JSON.parse(panelsJSON);
|
|
37
|
+
const references = dashboard.references || [];
|
|
38
|
+
const panelHealths = [];
|
|
39
|
+
const globalIssues = [];
|
|
40
|
+
// Check each Panel
|
|
41
|
+
for (const panel of panels) {
|
|
42
|
+
const panelIssues = [];
|
|
43
|
+
// 1. Check if Panel reference exists
|
|
44
|
+
const panelRefId = panel.panelRefName || panel.id;
|
|
45
|
+
const reference = references.find((ref) => ref.name === panelRefId);
|
|
46
|
+
if (!reference) {
|
|
47
|
+
panelIssues.push({
|
|
48
|
+
severity: 'error',
|
|
49
|
+
category: 'broken_reference',
|
|
50
|
+
message: `Panel missing reference definition`,
|
|
51
|
+
details: { panelId: panel.id },
|
|
52
|
+
suggestion: 'This Panel may have been deleted, recommend removing it from Dashboard'
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
// 2. Check if referenced object exists
|
|
57
|
+
try {
|
|
58
|
+
await kibanaClient.get(`/api/saved_objects/${reference.type}/${reference.id}`, { space });
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
if (error.response?.status === 404) {
|
|
62
|
+
panelIssues.push({
|
|
63
|
+
severity: 'critical',
|
|
64
|
+
category: 'broken_reference',
|
|
65
|
+
message: `Referenced ${reference.type} object does not exist`,
|
|
66
|
+
details: { referenceId: reference.id, referenceType: reference.type },
|
|
67
|
+
suggestion: `Restore deleted object or remove this Panel from Dashboard`
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
// 3. Performance check (Panel size)
|
|
73
|
+
const gridData = panel.gridData || {};
|
|
74
|
+
const panelArea = (gridData.w || 0) * (gridData.h || 0);
|
|
75
|
+
if (panelArea > 48) {
|
|
76
|
+
panelIssues.push({
|
|
77
|
+
severity: 'warning',
|
|
78
|
+
category: 'performance',
|
|
79
|
+
message: 'Panel size too large may affect performance',
|
|
80
|
+
details: { width: gridData.w, height: gridData.h },
|
|
81
|
+
suggestion: 'Consider splitting into multiple smaller Panels'
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
// 4. Check Panel type
|
|
85
|
+
const panelType = panel.type;
|
|
86
|
+
if (!panelType) {
|
|
87
|
+
panelIssues.push({
|
|
88
|
+
severity: 'error',
|
|
89
|
+
category: 'configuration',
|
|
90
|
+
message: 'Panel missing type definition',
|
|
91
|
+
suggestion: 'Reconfigure Panel'
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
const panelStatus = panelIssues.some(i => i.severity === 'error' || i.severity === 'critical')
|
|
95
|
+
? 'unhealthy'
|
|
96
|
+
: panelIssues.length > 0
|
|
97
|
+
? 'warning'
|
|
98
|
+
: 'healthy';
|
|
99
|
+
panelHealths.push({
|
|
100
|
+
panel_id: panel.id,
|
|
101
|
+
panel_type: panelType || 'unknown',
|
|
102
|
+
title: panel.title,
|
|
103
|
+
issues: panelIssues,
|
|
104
|
+
status: panelStatus
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
// Global checks
|
|
108
|
+
// 1. Check if Dashboard is too complex
|
|
109
|
+
if (panels.length > 20) {
|
|
110
|
+
globalIssues.push({
|
|
111
|
+
severity: 'warning',
|
|
112
|
+
category: 'performance',
|
|
113
|
+
message: `Dashboard contains ${panels.length} Panels, may cause slow loading`,
|
|
114
|
+
suggestion: 'Consider splitting into multiple themed Dashboards'
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
// 2. Check index pattern references
|
|
118
|
+
if (checkESIndices) {
|
|
119
|
+
const indexPatternRefs = references.filter((ref) => ref.type === 'index-pattern');
|
|
120
|
+
for (const indexPatternRef of indexPatternRefs) {
|
|
121
|
+
try {
|
|
122
|
+
const indexPattern = await kibanaClient.get(`/api/saved_objects/index-pattern/${indexPatternRef.id}`, { space });
|
|
123
|
+
// Could further call ES API to check if index exists
|
|
124
|
+
// Skipped for now as it requires ES Client
|
|
125
|
+
}
|
|
126
|
+
catch (error) {
|
|
127
|
+
if (error.response?.status === 404) {
|
|
128
|
+
globalIssues.push({
|
|
129
|
+
severity: 'critical',
|
|
130
|
+
category: 'broken_reference',
|
|
131
|
+
message: `Referenced index pattern does not exist: ${indexPatternRef.id}`,
|
|
132
|
+
suggestion: 'Recreate index pattern or update Dashboard reference'
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
// Calculate overall health
|
|
139
|
+
const healthyCount = panelHealths.filter(p => p.status === 'healthy').length;
|
|
140
|
+
const warningCount = panelHealths.filter(p => p.status === 'warning').length;
|
|
141
|
+
const unhealthyCount = panelHealths.filter(p => p.status === 'unhealthy').length;
|
|
142
|
+
const totalIssues = panelHealths.reduce((sum, p) => sum + p.issues.length, 0) + globalIssues.length;
|
|
143
|
+
// Health scoring algorithm
|
|
144
|
+
const healthScore = Math.max(0, Math.min(100, 100 - (unhealthyCount * 20) - (warningCount * 5) - (globalIssues.length * 10)));
|
|
145
|
+
let overallStatus = 'healthy';
|
|
146
|
+
if (unhealthyCount > 0 || globalIssues.some(i => i.severity === 'critical')) {
|
|
147
|
+
overallStatus = 'unhealthy';
|
|
148
|
+
}
|
|
149
|
+
else if (warningCount > 0 || globalIssues.length > 0) {
|
|
150
|
+
overallStatus = 'warning';
|
|
151
|
+
}
|
|
152
|
+
return {
|
|
153
|
+
id: dashboardId,
|
|
154
|
+
title,
|
|
155
|
+
overall_status: overallStatus,
|
|
156
|
+
overall_score: healthScore,
|
|
157
|
+
panel_count: panels.length,
|
|
158
|
+
panels: panelHealths,
|
|
159
|
+
global_issues: globalIssues,
|
|
160
|
+
summary: {
|
|
161
|
+
healthy_panels: healthyCount,
|
|
162
|
+
warning_panels: warningCount,
|
|
163
|
+
unhealthy_panels: unhealthyCount,
|
|
164
|
+
total_issues: totalIssues
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
catch (error) {
|
|
169
|
+
throw new Error(`Health analysis failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Batch analyze health of multiple Dashboards
|
|
174
|
+
*/
|
|
175
|
+
export async function batchAnalyzeDashboards(kibanaClient, space, maxDashboards = 50) {
|
|
176
|
+
try {
|
|
177
|
+
// Search all Dashboards
|
|
178
|
+
const searchResult = await kibanaClient.post('/api/saved_objects/_find', {
|
|
179
|
+
type: 'dashboard',
|
|
180
|
+
perPage: maxDashboards,
|
|
181
|
+
fields: ['title']
|
|
182
|
+
}, { space });
|
|
183
|
+
const dashboards = searchResult.saved_objects || [];
|
|
184
|
+
const healthReports = [];
|
|
185
|
+
for (const dashboard of dashboards) {
|
|
186
|
+
try {
|
|
187
|
+
const health = await analyzeDashboardHealth(kibanaClient, dashboard.id, space, false);
|
|
188
|
+
healthReports.push(health);
|
|
189
|
+
}
|
|
190
|
+
catch (error) {
|
|
191
|
+
console.error(`Failed to analyze dashboard ${dashboard.id}:`, error);
|
|
192
|
+
// Continue analyzing other Dashboards
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
const summary = {
|
|
196
|
+
total_dashboards: healthReports.length,
|
|
197
|
+
healthy: healthReports.filter(h => h.overall_status === 'healthy').length,
|
|
198
|
+
warning: healthReports.filter(h => h.overall_status === 'warning').length,
|
|
199
|
+
unhealthy: healthReports.filter(h => h.overall_status === 'unhealthy').length,
|
|
200
|
+
critical_issues: healthReports.reduce((sum, h) => sum + h.global_issues.filter(i => i.severity === 'critical').length +
|
|
201
|
+
h.panels.reduce((pSum, p) => pSum + p.issues.filter(i => i.severity === 'critical').length, 0), 0)
|
|
202
|
+
};
|
|
203
|
+
return {
|
|
204
|
+
dashboards: healthReports,
|
|
205
|
+
summary
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
catch (error) {
|
|
209
|
+
throw new Error(`Batch health analysis failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Format health report to Markdown
|
|
214
|
+
*/
|
|
215
|
+
export function formatHealthReportToMarkdown(health) {
|
|
216
|
+
const statusEmoji = {
|
|
217
|
+
'healthy': 'â
',
|
|
218
|
+
'warning': 'â ī¸',
|
|
219
|
+
'unhealthy': 'đ´'
|
|
220
|
+
};
|
|
221
|
+
let md = `# Dashboard Health Report\n\n`;
|
|
222
|
+
md += `## ${statusEmoji[health.overall_status]} Overall Status: ${health.overall_status.toUpperCase()}\n`;
|
|
223
|
+
md += `- **Dashboard**: ${health.title}\n`;
|
|
224
|
+
md += `- **Health Score**: ${health.overall_score}/100\n`;
|
|
225
|
+
md += `- **Total Panels**: ${health.panel_count}\n\n`;
|
|
226
|
+
md += `## đ Panel Statistics\n`;
|
|
227
|
+
md += `- â
Healthy: ${health.summary.healthy_panels}\n`;
|
|
228
|
+
md += `- â ī¸ Warning: ${health.summary.warning_panels}\n`;
|
|
229
|
+
md += `- đ´ Unhealthy: ${health.summary.unhealthy_panels}\n`;
|
|
230
|
+
md += `- đ Total Issues: ${health.summary.total_issues}\n\n`;
|
|
231
|
+
if (health.global_issues.length > 0) {
|
|
232
|
+
md += `## đ¨ Global Issues\n`;
|
|
233
|
+
health.global_issues.forEach((issue, index) => {
|
|
234
|
+
const severityEmoji = { info: 'âšī¸', warning: 'â ī¸', error: 'â', critical: 'đ¨' };
|
|
235
|
+
md += `${index + 1}. ${severityEmoji[issue.severity]} **[${issue.severity.toUpperCase()}]** ${issue.message}\n`;
|
|
236
|
+
if (issue.suggestion) {
|
|
237
|
+
md += ` đĄ ${issue.suggestion}\n`;
|
|
238
|
+
}
|
|
239
|
+
});
|
|
240
|
+
md += '\n';
|
|
241
|
+
}
|
|
242
|
+
const unhealthyPanels = health.panels.filter(p => p.status === 'unhealthy');
|
|
243
|
+
if (unhealthyPanels.length > 0) {
|
|
244
|
+
md += `## đ´ Unhealthy Panel Details\n`;
|
|
245
|
+
unhealthyPanels.forEach(panel => {
|
|
246
|
+
md += `### Panel: ${panel.title || panel.panel_id} (${panel.panel_type})\n`;
|
|
247
|
+
panel.issues.forEach(issue => {
|
|
248
|
+
md += `- â ${issue.message}\n`;
|
|
249
|
+
if (issue.suggestion) {
|
|
250
|
+
md += ` đĄ ${issue.suggestion}\n`;
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
md += '\n';
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
const warningPanels = health.panels.filter(p => p.status === 'warning');
|
|
257
|
+
if (warningPanels.length > 0) {
|
|
258
|
+
md += `## â ī¸ Warning Panels (top 5)\n`;
|
|
259
|
+
warningPanels.slice(0, 5).forEach(panel => {
|
|
260
|
+
md += `- **${panel.title || panel.panel_id}**: ${panel.issues[0]?.message}\n`;
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
return md;
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Format batch health report to Markdown
|
|
267
|
+
*/
|
|
268
|
+
export function formatBatchHealthReportToMarkdown(report) {
|
|
269
|
+
let md = `# Dashboard Batch Health Report\n\n`;
|
|
270
|
+
md += `## đ Overall Summary\n`;
|
|
271
|
+
md += `- Total Dashboards: ${report.summary.total_dashboards}\n`;
|
|
272
|
+
md += `- â
Healthy: ${report.summary.healthy} (${Math.round(report.summary.healthy / report.summary.total_dashboards * 100)}%)\n`;
|
|
273
|
+
md += `- â ī¸ Warning: ${report.summary.warning} (${Math.round(report.summary.warning / report.summary.total_dashboards * 100)}%)\n`;
|
|
274
|
+
md += `- đ´ Unhealthy: ${report.summary.unhealthy} (${Math.round(report.summary.unhealthy / report.summary.total_dashboards * 100)}%)\n`;
|
|
275
|
+
md += `- đ¨ Critical Issues: ${report.summary.critical_issues}\n\n`;
|
|
276
|
+
// Sort by health score, show most problematic first
|
|
277
|
+
const sortedDashboards = [...report.dashboards].sort((a, b) => a.overall_score - b.overall_score);
|
|
278
|
+
if (report.summary.unhealthy > 0) {
|
|
279
|
+
md += `## đ´ Dashboards Requiring Urgent Fix\n`;
|
|
280
|
+
sortedDashboards
|
|
281
|
+
.filter(d => d.overall_status === 'unhealthy')
|
|
282
|
+
.slice(0, 10)
|
|
283
|
+
.forEach((dashboard, index) => {
|
|
284
|
+
md += `${index + 1}. **${dashboard.title}** (Score: ${dashboard.overall_score}/100)\n`;
|
|
285
|
+
md += ` - Unhealthy Panels: ${dashboard.summary.unhealthy_panels}/${dashboard.panel_count}\n`;
|
|
286
|
+
md += ` - Total Issues: ${dashboard.summary.total_issues}\n`;
|
|
287
|
+
});
|
|
288
|
+
md += '\n';
|
|
289
|
+
}
|
|
290
|
+
if (report.summary.warning > 0) {
|
|
291
|
+
md += `## â ī¸ Dashboards Recommended for Optimization (top 5)\n`;
|
|
292
|
+
sortedDashboards
|
|
293
|
+
.filter(d => d.overall_status === 'warning')
|
|
294
|
+
.slice(0, 5)
|
|
295
|
+
.forEach((dashboard, index) => {
|
|
296
|
+
md += `${index + 1}. **${dashboard.title}** (Score: ${dashboard.overall_score}/100)\n`;
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
return md;
|
|
300
|
+
}
|
|
301
|
+
//# sourceMappingURL=health-analyzer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health-analyzer.js","sourceRoot":"","sources":["../../src/health-analyzer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA+CH;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,YAA0B,EAC1B,WAAmB,EACnB,KAAc,EACd,iBAA0B,KAAK;IAE/B,IAAI,CAAC;QACH,wBAAwB;QACxB,MAAM,SAAS,GAAG,MAAM,YAAY,CAAC,GAAG,CAAC,gCAAgC,WAAW,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QACnG,MAAM,KAAK,GAAG,SAAS,CAAC,UAAU,EAAE,KAAK,IAAI,WAAW,CAAC;QACzD,MAAM,UAAU,GAAG,SAAS,CAAC,UAAU,EAAE,UAAU,CAAC;QAEpD,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,OAAO;gBACL,EAAE,EAAE,WAAW;gBACf,KAAK;gBACL,cAAc,EAAE,WAAW;gBAC3B,aAAa,EAAE,CAAC;gBAChB,WAAW,EAAE,CAAC;gBACd,MAAM,EAAE,EAAE;gBACV,aAAa,EAAE,CAAC;wBACd,QAAQ,EAAE,OAAO;wBACjB,QAAQ,EAAE,eAAe;wBACzB,OAAO,EAAE,oCAAoC;wBAC7C,UAAU,EAAE,sCAAsC;qBACnD,CAAC;gBACF,OAAO,EAAE;oBACP,cAAc,EAAE,CAAC;oBACjB,cAAc,EAAE,CAAC;oBACjB,gBAAgB,EAAE,CAAC;oBACnB,YAAY,EAAE,CAAC;iBAChB;aACF,CAAC;QACJ,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QACtC,MAAM,UAAU,GAAG,SAAS,CAAC,UAAU,IAAI,EAAE,CAAC;QAC9C,MAAM,YAAY,GAAkB,EAAE,CAAC;QACvC,MAAM,YAAY,GAAkB,EAAE,CAAC;QAEvC,mBAAmB;QACnB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,MAAM,WAAW,GAAkB,EAAE,CAAC;YAEtC,qCAAqC;YACrC,MAAM,UAAU,GAAG,KAAK,CAAC,YAAY,IAAI,KAAK,CAAC,EAAE,CAAC;YAClD,MAAM,SAAS,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,GAAQ,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;YAEzE,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,WAAW,CAAC,IAAI,CAAC;oBACf,QAAQ,EAAE,OAAO;oBACjB,QAAQ,EAAE,kBAAkB;oBAC5B,OAAO,EAAE,oCAAoC;oBAC7C,OAAO,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,EAAE;oBAC9B,UAAU,EAAE,wEAAwE;iBACrF,CAAC,CAAC;YACL,CAAC;iBAAM,CAAC;gBACN,uCAAuC;gBACvC,IAAI,CAAC;oBACH,MAAM,YAAY,CAAC,GAAG,CAAC,sBAAsB,SAAS,CAAC,IAAI,IAAI,SAAS,CAAC,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;gBAC5F,CAAC;gBAAC,OAAO,KAAU,EAAE,CAAC;oBACpB,IAAI,KAAK,CAAC,QAAQ,EAAE,MAAM,KAAK,GAAG,EAAE,CAAC;wBACnC,WAAW,CAAC,IAAI,CAAC;4BACf,QAAQ,EAAE,UAAU;4BACpB,QAAQ,EAAE,kBAAkB;4BAC5B,OAAO,EAAE,cAAc,SAAS,CAAC,IAAI,wBAAwB;4BAC7D,OAAO,EAAE,EAAE,WAAW,EAAE,SAAS,CAAC,EAAE,EAAE,aAAa,EAAE,SAAS,CAAC,IAAI,EAAE;4BACrE,UAAU,EAAE,4DAA4D;yBACzE,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;YACH,CAAC;YAED,oCAAoC;YACpC,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,IAAI,EAAE,CAAC;YACtC,MAAM,SAAS,GAAG,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;YACxD,IAAI,SAAS,GAAG,EAAE,EAAE,CAAC;gBACnB,WAAW,CAAC,IAAI,CAAC;oBACf,QAAQ,EAAE,SAAS;oBACnB,QAAQ,EAAE,aAAa;oBACvB,OAAO,EAAE,6CAA6C;oBACtD,OAAO,EAAE,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,EAAE;oBAClD,UAAU,EAAE,iDAAiD;iBAC9D,CAAC,CAAC;YACL,CAAC;YAED,sBAAsB;YACtB,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC;YAC7B,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,WAAW,CAAC,IAAI,CAAC;oBACf,QAAQ,EAAE,OAAO;oBACjB,QAAQ,EAAE,eAAe;oBACzB,OAAO,EAAE,+BAA+B;oBACxC,UAAU,EAAE,mBAAmB;iBAChC,CAAC,CAAC;YACL,CAAC;YAED,MAAM,WAAW,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,OAAO,IAAI,CAAC,CAAC,QAAQ,KAAK,UAAU,CAAC;gBAC5F,CAAC,CAAC,WAAW;gBACb,CAAC,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC;oBACtB,CAAC,CAAC,SAAS;oBACX,CAAC,CAAC,SAAS,CAAC;YAEhB,YAAY,CAAC,IAAI,CAAC;gBAChB,QAAQ,EAAE,KAAK,CAAC,EAAE;gBAClB,UAAU,EAAE,SAAS,IAAI,SAAS;gBAClC,KAAK,EAAE,KAAK,CAAC,KAAK;gBAClB,MAAM,EAAE,WAAW;gBACnB,MAAM,EAAE,WAAW;aACpB,CAAC,CAAC;QACL,CAAC;QAED,gBAAgB;QAEhB,uCAAuC;QACvC,IAAI,MAAM,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;YACvB,YAAY,CAAC,IAAI,CAAC;gBAChB,QAAQ,EAAE,SAAS;gBACnB,QAAQ,EAAE,aAAa;gBACvB,OAAO,EAAE,sBAAsB,MAAM,CAAC,MAAM,iCAAiC;gBAC7E,UAAU,EAAE,oDAAoD;aACjE,CAAC,CAAC;QACL,CAAC;QAED,oCAAoC;QACpC,IAAI,cAAc,EAAE,CAAC;YACnB,MAAM,gBAAgB,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,GAAQ,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,eAAe,CAAC,CAAC;YACvF,KAAK,MAAM,eAAe,IAAI,gBAAgB,EAAE,CAAC;gBAC/C,IAAI,CAAC;oBACH,MAAM,YAAY,GAAG,MAAM,YAAY,CAAC,GAAG,CACzC,oCAAoC,eAAe,CAAC,EAAE,EAAE,EACxD,EAAE,KAAK,EAAE,CACV,CAAC;oBAEF,qDAAqD;oBACrD,2CAA2C;gBAE7C,CAAC;gBAAC,OAAO,KAAU,EAAE,CAAC;oBACpB,IAAI,KAAK,CAAC,QAAQ,EAAE,MAAM,KAAK,GAAG,EAAE,CAAC;wBACnC,YAAY,CAAC,IAAI,CAAC;4BAChB,QAAQ,EAAE,UAAU;4BACpB,QAAQ,EAAE,kBAAkB;4BAC5B,OAAO,EAAE,4CAA4C,eAAe,CAAC,EAAE,EAAE;4BACzE,UAAU,EAAE,sDAAsD;yBACnE,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAED,2BAA2B;QAC3B,MAAM,YAAY,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,MAAM,CAAC;QAC7E,MAAM,YAAY,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,MAAM,CAAC;QAC7E,MAAM,cAAc,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,MAAM,CAAC;QACjF,MAAM,WAAW,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,YAAY,CAAC,MAAM,CAAC;QAEpG,2BAA2B;QAC3B,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAC1C,GAAG,GAAG,CAAC,cAAc,GAAG,EAAE,CAAC,GAAG,CAAC,YAAY,GAAG,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,GAAG,EAAE,CAAC,CAC9E,CAAC,CAAC;QAEH,IAAI,aAAa,GAAsC,SAAS,CAAC;QACjE,IAAI,cAAc,GAAG,CAAC,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,UAAU,CAAC,EAAE,CAAC;YAC5E,aAAa,GAAG,WAAW,CAAC;QAC9B,CAAC;aAAM,IAAI,YAAY,GAAG,CAAC,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvD,aAAa,GAAG,SAAS,CAAC;QAC5B,CAAC;QAED,OAAO;YACL,EAAE,EAAE,WAAW;YACf,KAAK;YACL,cAAc,EAAE,aAAa;YAC7B,aAAa,EAAE,WAAW;YAC1B,WAAW,EAAE,MAAM,CAAC,MAAM;YAC1B,MAAM,EAAE,YAAY;YACpB,aAAa,EAAE,YAAY;YAC3B,OAAO,EAAE;gBACP,cAAc,EAAE,YAAY;gBAC5B,cAAc,EAAE,YAAY;gBAC5B,gBAAgB,EAAE,cAAc;gBAChC,YAAY,EAAE,WAAW;aAC1B;SACF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,2BAA2B,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACvG,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,YAA0B,EAC1B,KAAc,EACd,gBAAwB,EAAE;IAE1B,IAAI,CAAC;QACH,wBAAwB;QACxB,MAAM,YAAY,GAAG,MAAM,YAAY,CAAC,IAAI,CAC1C,0BAA0B,EAC1B;YACE,IAAI,EAAE,WAAW;YACjB,OAAO,EAAE,aAAa;YACtB,MAAM,EAAE,CAAC,OAAO,CAAC;SAClB,EACD,EAAE,KAAK,EAAE,CACV,CAAC;QAEF,MAAM,UAAU,GAAG,YAAY,CAAC,aAAa,IAAI,EAAE,CAAC;QACpD,MAAM,aAAa,GAAsB,EAAE,CAAC;QAE5C,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACnC,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,sBAAsB,CAAC,YAAY,EAAE,SAAS,CAAC,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;gBACtF,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC7B,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,KAAK,CAAC,+BAA+B,SAAS,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;gBACrE,sCAAsC;YACxC,CAAC;QACH,CAAC;QAED,MAAM,OAAO,GAAG;YACd,gBAAgB,EAAE,aAAa,CAAC,MAAM;YACtC,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,cAAc,KAAK,SAAS,CAAC,CAAC,MAAM;YACzE,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,cAAc,KAAK,SAAS,CAAC,CAAC,MAAM;YACzE,SAAS,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,cAAc,KAAK,WAAW,CAAC,CAAC,MAAM;YAC7E,eAAe,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAC/C,GAAG,GAAG,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,UAAU,CAAC,CAAC,MAAM;gBACnE,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,UAAU,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,EAC9F,CAAC,CAAC;SACL,CAAC;QAEF,OAAO;YACL,UAAU,EAAE,aAAa;YACzB,OAAO;SACR,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,iCAAiC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC7G,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,4BAA4B,CAAC,MAAuB;IAClE,MAAM,WAAW,GAAG;QAClB,SAAS,EAAE,GAAG;QACd,SAAS,EAAE,IAAI;QACf,WAAW,EAAE,IAAI;KAClB,CAAC;IAEF,IAAI,EAAE,GAAG,+BAA+B,CAAC;IACzC,EAAE,IAAI,MAAM,WAAW,CAAC,MAAM,CAAC,cAAc,CAAC,oBAAoB,MAAM,CAAC,cAAc,CAAC,WAAW,EAAE,IAAI,CAAC;IAC1G,EAAE,IAAI,oBAAoB,MAAM,CAAC,KAAK,IAAI,CAAC;IAC3C,EAAE,IAAI,uBAAuB,MAAM,CAAC,aAAa,QAAQ,CAAC;IAC1D,EAAE,IAAI,uBAAuB,MAAM,CAAC,WAAW,MAAM,CAAC;IAEtD,EAAE,IAAI,0BAA0B,CAAC;IACjC,EAAE,IAAI,gBAAgB,MAAM,CAAC,OAAO,CAAC,cAAc,IAAI,CAAC;IACxD,EAAE,IAAI,iBAAiB,MAAM,CAAC,OAAO,CAAC,cAAc,IAAI,CAAC;IACzD,EAAE,IAAI,mBAAmB,MAAM,CAAC,OAAO,CAAC,gBAAgB,IAAI,CAAC;IAC7D,EAAE,IAAI,sBAAsB,MAAM,CAAC,OAAO,CAAC,YAAY,MAAM,CAAC;IAE9D,IAAI,MAAM,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpC,EAAE,IAAI,uBAAuB,CAAC;QAC9B,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;YAC5C,MAAM,aAAa,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;YAChF,EAAE,IAAI,GAAG,KAAK,GAAG,CAAC,KAAK,aAAa,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,KAAK,CAAC,QAAQ,CAAC,WAAW,EAAE,OAAO,KAAK,CAAC,OAAO,IAAI,CAAC;YAChH,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;gBACrB,EAAE,IAAI,SAAS,KAAK,CAAC,UAAU,IAAI,CAAC;YACtC,CAAC;QACH,CAAC,CAAC,CAAC;QACH,EAAE,IAAI,IAAI,CAAC;IACb,CAAC;IAED,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC;IAC5E,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,EAAE,IAAI,iCAAiC,CAAC;QACxC,eAAe,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;YAC9B,EAAE,IAAI,cAAc,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,QAAQ,KAAK,KAAK,CAAC,UAAU,KAAK,CAAC;YAC5E,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;gBAC3B,EAAE,IAAI,OAAO,KAAK,CAAC,OAAO,IAAI,CAAC;gBAC/B,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;oBACrB,EAAE,IAAI,QAAQ,KAAK,CAAC,UAAU,IAAI,CAAC;gBACrC,CAAC;YACH,CAAC,CAAC,CAAC;YACH,EAAE,IAAI,IAAI,CAAC;QACb,CAAC,CAAC,CAAC;IACL,CAAC;IAED,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC;IACxE,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7B,EAAE,IAAI,gCAAgC,CAAC;QACvC,aAAa,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;YACxC,EAAE,IAAI,OAAO,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,QAAQ,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO,IAAI,CAAC;QAChF,CAAC,CAAC,CAAC;IACL,CAAC;IAED,OAAO,EAAE,CAAC;AACZ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iCAAiC,CAAC,MAAyB;IACzE,IAAI,EAAE,GAAG,qCAAqC,CAAC;IAC/C,EAAE,IAAI,yBAAyB,CAAC;IAChC,EAAE,IAAI,uBAAuB,MAAM,CAAC,OAAO,CAAC,gBAAgB,IAAI,CAAC;IACjE,EAAE,IAAI,gBAAgB,MAAM,CAAC,OAAO,CAAC,OAAO,KAAK,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,gBAAgB,GAAG,GAAG,CAAC,MAAM,CAAC;IAClI,EAAE,IAAI,iBAAiB,MAAM,CAAC,OAAO,CAAC,OAAO,KAAK,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,gBAAgB,GAAG,GAAG,CAAC,MAAM,CAAC;IACnI,EAAE,IAAI,mBAAmB,MAAM,CAAC,OAAO,CAAC,SAAS,KAAK,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,gBAAgB,GAAG,GAAG,CAAC,MAAM,CAAC;IACzI,EAAE,IAAI,yBAAyB,MAAM,CAAC,OAAO,CAAC,eAAe,MAAM,CAAC;IAEpE,oDAAoD;IACpD,MAAM,gBAAgB,GAAG,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,GAAG,CAAC,CAAC,aAAa,CAAC,CAAC;IAElG,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,GAAG,CAAC,EAAE,CAAC;QACjC,EAAE,IAAI,yCAAyC,CAAC;QAChD,gBAAgB;aACb,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,cAAc,KAAK,WAAW,CAAC;aAC7C,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;aACZ,OAAO,CAAC,CAAC,SAAS,EAAE,KAAK,EAAE,EAAE;YAC5B,EAAE,IAAI,GAAG,KAAK,GAAG,CAAC,OAAO,SAAS,CAAC,KAAK,cAAc,SAAS,CAAC,aAAa,SAAS,CAAC;YACvF,EAAE,IAAI,0BAA0B,SAAS,CAAC,OAAO,CAAC,gBAAgB,IAAI,SAAS,CAAC,WAAW,IAAI,CAAC;YAChG,EAAE,IAAI,sBAAsB,SAAS,CAAC,OAAO,CAAC,YAAY,IAAI,CAAC;QACjE,CAAC,CAAC,CAAC;QACL,EAAE,IAAI,IAAI,CAAC;IACb,CAAC;IAED,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,GAAG,CAAC,EAAE,CAAC;QAC/B,EAAE,IAAI,yDAAyD,CAAC;QAChE,gBAAgB;aACb,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,cAAc,KAAK,SAAS,CAAC;aAC3C,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;aACX,OAAO,CAAC,CAAC,SAAS,EAAE,KAAK,EAAE,EAAE;YAC5B,EAAE,IAAI,GAAG,KAAK,GAAG,CAAC,OAAO,SAAS,CAAC,KAAK,cAAc,SAAS,CAAC,aAAa,SAAS,CAAC;QACzF,CAAC,CAAC,CAAC;IACP,CAAC;IAED,OAAO,EAAE,CAAC;AACZ,CAAC"}
|