mcp-docs-scraper 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +357 -0
  3. package/dist/index.d.ts +3 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +20 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/server.d.ts +6 -0
  8. package/dist/server.d.ts.map +1 -0
  9. package/dist/server.js +231 -0
  10. package/dist/server.js.map +1 -0
  11. package/dist/services/cache-manager.d.ts +100 -0
  12. package/dist/services/cache-manager.d.ts.map +1 -0
  13. package/dist/services/cache-manager.js +212 -0
  14. package/dist/services/cache-manager.js.map +1 -0
  15. package/dist/services/content-cleaner.d.ts +48 -0
  16. package/dist/services/content-cleaner.d.ts.map +1 -0
  17. package/dist/services/content-cleaner.js +295 -0
  18. package/dist/services/content-cleaner.js.map +1 -0
  19. package/dist/services/github-detector.d.ts +49 -0
  20. package/dist/services/github-detector.d.ts.map +1 -0
  21. package/dist/services/github-detector.js +276 -0
  22. package/dist/services/github-detector.js.map +1 -0
  23. package/dist/services/github-fetcher.d.ts +94 -0
  24. package/dist/services/github-fetcher.d.ts.map +1 -0
  25. package/dist/services/github-fetcher.js +393 -0
  26. package/dist/services/github-fetcher.js.map +1 -0
  27. package/dist/services/search-index.d.ts +106 -0
  28. package/dist/services/search-index.d.ts.map +1 -0
  29. package/dist/services/search-index.js +210 -0
  30. package/dist/services/search-index.js.map +1 -0
  31. package/dist/services/web-scraper.d.ts +88 -0
  32. package/dist/services/web-scraper.d.ts.map +1 -0
  33. package/dist/services/web-scraper.js +244 -0
  34. package/dist/services/web-scraper.js.map +1 -0
  35. package/dist/tools/clear-cache.d.ts +24 -0
  36. package/dist/tools/clear-cache.d.ts.map +1 -0
  37. package/dist/tools/clear-cache.js +29 -0
  38. package/dist/tools/clear-cache.js.map +1 -0
  39. package/dist/tools/detect-github.d.ts +21 -0
  40. package/dist/tools/detect-github.d.ts.map +1 -0
  41. package/dist/tools/detect-github.js +18 -0
  42. package/dist/tools/detect-github.js.map +1 -0
  43. package/dist/tools/get-content.d.ts +43 -0
  44. package/dist/tools/get-content.d.ts.map +1 -0
  45. package/dist/tools/get-content.js +84 -0
  46. package/dist/tools/get-content.js.map +1 -0
  47. package/dist/tools/get-tree.d.ts +31 -0
  48. package/dist/tools/get-tree.d.ts.map +1 -0
  49. package/dist/tools/get-tree.js +102 -0
  50. package/dist/tools/get-tree.js.map +1 -0
  51. package/dist/tools/index-docs.d.ts +63 -0
  52. package/dist/tools/index-docs.d.ts.map +1 -0
  53. package/dist/tools/index-docs.js +371 -0
  54. package/dist/tools/index-docs.js.map +1 -0
  55. package/dist/tools/index.d.ts +11 -0
  56. package/dist/tools/index.d.ts.map +1 -0
  57. package/dist/tools/index.js +11 -0
  58. package/dist/tools/index.js.map +1 -0
  59. package/dist/tools/list-cached.d.ts +19 -0
  60. package/dist/tools/list-cached.d.ts.map +1 -0
  61. package/dist/tools/list-cached.js +20 -0
  62. package/dist/tools/list-cached.js.map +1 -0
  63. package/dist/tools/search-docs.d.ts +31 -0
  64. package/dist/tools/search-docs.d.ts.map +1 -0
  65. package/dist/tools/search-docs.js +64 -0
  66. package/dist/tools/search-docs.js.map +1 -0
  67. package/dist/types/cache.d.ts +53 -0
  68. package/dist/types/cache.d.ts.map +1 -0
  69. package/dist/types/cache.js +2 -0
  70. package/dist/types/cache.js.map +1 -0
  71. package/dist/types/errors.d.ts +102 -0
  72. package/dist/types/errors.d.ts.map +1 -0
  73. package/dist/types/errors.js +216 -0
  74. package/dist/types/errors.js.map +1 -0
  75. package/dist/types/index.d.ts +6 -0
  76. package/dist/types/index.d.ts.map +1 -0
  77. package/dist/types/index.js +5 -0
  78. package/dist/types/index.js.map +1 -0
  79. package/dist/utils/fs.d.ts +45 -0
  80. package/dist/utils/fs.d.ts.map +1 -0
  81. package/dist/utils/fs.js +113 -0
  82. package/dist/utils/fs.js.map +1 -0
  83. package/dist/utils/rate-limit.d.ts +55 -0
  84. package/dist/utils/rate-limit.d.ts.map +1 -0
  85. package/dist/utils/rate-limit.js +89 -0
  86. package/dist/utils/rate-limit.js.map +1 -0
  87. package/dist/utils/url.d.ts +69 -0
  88. package/dist/utils/url.d.ts.map +1 -0
  89. package/dist/utils/url.js +251 -0
  90. package/dist/utils/url.js.map +1 -0
  91. package/package.json +58 -0
@@ -0,0 +1,393 @@
1
+ import { githubRateLimit } from "../utils/rate-limit.js";
2
+ import { GitHubRateLimitError, GitHubNotFoundError, GitHubAccessDeniedError, NetworkError, } from "../types/errors.js";
3
+ const GITHUB_API_BASE = "https://api.github.com";
4
+ const DEFAULT_EXTENSIONS = [".md", ".mdx", ".markdown"];
5
+ /**
6
+ * Parses "owner/repo" format into separate parts.
7
+ */
8
+ export function parseRepoString(repoString) {
9
+ const parts = repoString.split("/");
10
+ if (parts.length !== 2) {
11
+ throw new Error(`Invalid repo format: "${repoString}". Expected "owner/repo".`);
12
+ }
13
+ return { owner: parts[0], repo: parts[1] };
14
+ }
15
+ /**
16
+ * Gets GitHub API headers, including auth token if available.
17
+ */
18
+ function getGitHubHeaders() {
19
+ const headers = {
20
+ Accept: "application/vnd.github.v3+json",
21
+ "User-Agent": "mcp-docs-scraper",
22
+ };
23
+ // Use GITHUB_TOKEN if available (increases rate limit from 60 to 5000/hour)
24
+ const token = process.env.GITHUB_TOKEN;
25
+ if (token) {
26
+ headers.Authorization = `Bearer ${token}`;
27
+ }
28
+ return headers;
29
+ }
30
+ /**
31
+ * Checks if GitHub authentication is configured.
32
+ */
33
+ export function isAuthenticated() {
34
+ return !!process.env.GITHUB_TOKEN;
35
+ }
36
+ /**
37
+ * Makes a GitHub API request with proper headers and rate limit tracking.
38
+ */
39
+ async function githubFetch(url) {
40
+ const response = await fetch(url, {
41
+ headers: getGitHubHeaders(),
42
+ });
43
+ githubRateLimit.updateFromHeaders(response.headers);
44
+ return response;
45
+ }
46
+ /**
47
+ * Detects the default branch for a repository using the Git Trees API.
48
+ * Tries "main" first, then "master".
49
+ */
50
+ async function detectDefaultBranch(owner, repo) {
51
+ const repoString = `${owner}/${repo}`;
52
+ // Check rate limit before making requests
53
+ if (githubRateLimit.isExhausted()) {
54
+ throw new GitHubRateLimitError(githubRateLimit.getResetTime());
55
+ }
56
+ try {
57
+ // Try main first using Git Trees API
58
+ const mainUrl = `${GITHUB_API_BASE}/repos/${owner}/${repo}/git/trees/main`;
59
+ const mainResponse = await githubFetch(mainUrl);
60
+ if (mainResponse.ok) {
61
+ return "main";
62
+ }
63
+ // Check for specific error types
64
+ if (mainResponse.status === 403) {
65
+ throw new GitHubAccessDeniedError(repoString);
66
+ }
67
+ // Try master
68
+ const masterUrl = `${GITHUB_API_BASE}/repos/${owner}/${repo}/git/trees/master`;
69
+ const masterResponse = await githubFetch(masterUrl);
70
+ if (masterResponse.ok) {
71
+ return "master";
72
+ }
73
+ if (masterResponse.status === 403) {
74
+ throw new GitHubAccessDeniedError(repoString);
75
+ }
76
+ // Neither branch found - repo might not exist
77
+ throw new GitHubNotFoundError(repoString);
78
+ }
79
+ catch (error) {
80
+ if (error instanceof GitHubRateLimitError ||
81
+ error instanceof GitHubAccessDeniedError ||
82
+ error instanceof GitHubNotFoundError) {
83
+ throw error;
84
+ }
85
+ throw new NetworkError(`https://github.com/${repoString}`, error instanceof Error ? error : undefined);
86
+ }
87
+ }
88
+ /**
89
+ * Fetches the entire tree from GitHub using the Git Trees API.
90
+ * This uses only 1 API request instead of 1 per directory.
91
+ */
92
+ async function fetchGitTree(owner, repo, branch) {
93
+ const repoString = `${owner}/${repo}`;
94
+ // Check rate limit before making request
95
+ if (githubRateLimit.isExhausted()) {
96
+ throw new GitHubRateLimitError(githubRateLimit.getResetTime());
97
+ }
98
+ if (githubRateLimit.isLow()) {
99
+ console.error(`Warning: ${githubRateLimit.getStatusMessage()}`);
100
+ }
101
+ const url = `${GITHUB_API_BASE}/repos/${owner}/${repo}/git/trees/${branch}?recursive=1`;
102
+ try {
103
+ const response = await githubFetch(url);
104
+ if (!response.ok) {
105
+ if (response.status === 404) {
106
+ throw new GitHubNotFoundError(repoString);
107
+ }
108
+ if (response.status === 403) {
109
+ // Could be rate limit or access denied
110
+ if (githubRateLimit.isExhausted()) {
111
+ throw new GitHubRateLimitError(githubRateLimit.getResetTime());
112
+ }
113
+ throw new GitHubAccessDeniedError(repoString);
114
+ }
115
+ throw new Error(`GitHub API error: ${response.status} ${response.statusText}`);
116
+ }
117
+ return response.json();
118
+ }
119
+ catch (error) {
120
+ if (error instanceof GitHubRateLimitError ||
121
+ error instanceof GitHubNotFoundError ||
122
+ error instanceof GitHubAccessDeniedError) {
123
+ throw error;
124
+ }
125
+ if (error instanceof Error && error.message.includes("GitHub API error")) {
126
+ throw error;
127
+ }
128
+ throw new NetworkError(url, error instanceof Error ? error : undefined);
129
+ }
130
+ }
131
+ /**
132
+ * Checks if a file should be included based on extension filter.
133
+ */
134
+ function shouldIncludeFile(filename, extensions) {
135
+ if (extensions.length === 0)
136
+ return true;
137
+ const lowerName = filename.toLowerCase();
138
+ return extensions.some((ext) => lowerName.endsWith(ext.toLowerCase()));
139
+ }
140
+ /**
141
+ * Gets the depth of a path (number of directory levels).
142
+ */
143
+ function getPathDepth(path) {
144
+ if (!path)
145
+ return 0;
146
+ return path.split("/").length;
147
+ }
148
+ /**
149
+ * Gets the file/folder name from a path.
150
+ */
151
+ function getNameFromPath(path) {
152
+ const parts = path.split("/");
153
+ return parts[parts.length - 1];
154
+ }
155
+ /**
156
+ * Gets the parent path from a path.
157
+ */
158
+ function getParentPath(path) {
159
+ const parts = path.split("/");
160
+ parts.pop();
161
+ return parts.join("/");
162
+ }
163
+ /**
164
+ * Converts a flat list of tree items into a hierarchical DocsTreeNode structure.
165
+ */
166
+ function buildHierarchicalTree(items, basePath, extensions, maxDepth) {
167
+ // Filter items by base path and extensions
168
+ const filteredItems = items.filter((item) => {
169
+ // Must be under base path
170
+ if (basePath &&
171
+ !item.path.startsWith(basePath + "/") &&
172
+ item.path !== basePath) {
173
+ return false;
174
+ }
175
+ // Calculate relative depth
176
+ const relativePath = basePath
177
+ ? item.path.slice(basePath.length + 1)
178
+ : item.path;
179
+ const depth = getPathDepth(relativePath);
180
+ if (depth > maxDepth) {
181
+ return false;
182
+ }
183
+ // For files, check extension filter
184
+ if (item.type === "blob") {
185
+ return shouldIncludeFile(item.path, extensions);
186
+ }
187
+ return true; // Include directories for now, we'll filter empty ones later
188
+ });
189
+ // Build a map of path -> node for quick lookups
190
+ const nodeMap = new Map();
191
+ let fileCount = 0;
192
+ let totalSize = 0;
193
+ // First pass: create nodes for all matching files
194
+ for (const item of filteredItems) {
195
+ if (item.type === "blob") {
196
+ const node = {
197
+ name: getNameFromPath(item.path),
198
+ path: item.path,
199
+ type: "file",
200
+ size_bytes: item.size,
201
+ };
202
+ nodeMap.set(item.path, node);
203
+ fileCount++;
204
+ totalSize += item.size || 0;
205
+ }
206
+ }
207
+ // Second pass: create folder nodes for paths that have files under them
208
+ const folderPaths = new Set();
209
+ for (const item of filteredItems) {
210
+ if (item.type === "blob") {
211
+ // Walk up the path and add all parent folders
212
+ let parentPath = getParentPath(item.path);
213
+ while (parentPath &&
214
+ (!basePath ||
215
+ parentPath.startsWith(basePath) ||
216
+ parentPath === basePath)) {
217
+ // Don't add folders above basePath
218
+ if (basePath && parentPath.length < basePath.length)
219
+ break;
220
+ folderPaths.add(parentPath);
221
+ parentPath = getParentPath(parentPath);
222
+ }
223
+ }
224
+ }
225
+ // Create folder nodes
226
+ for (const folderPath of folderPaths) {
227
+ if (!nodeMap.has(folderPath)) {
228
+ nodeMap.set(folderPath, {
229
+ name: getNameFromPath(folderPath),
230
+ path: folderPath,
231
+ type: "folder",
232
+ children: [],
233
+ });
234
+ }
235
+ }
236
+ // Third pass: build the hierarchy
237
+ for (const [path, node] of nodeMap) {
238
+ const parentPath = getParentPath(path);
239
+ // Skip if this is at the root level (relative to basePath)
240
+ if (!parentPath || (basePath && parentPath.length < basePath.length)) {
241
+ continue;
242
+ }
243
+ const parent = nodeMap.get(parentPath);
244
+ if (parent && parent.type === "folder") {
245
+ parent.children = parent.children || [];
246
+ parent.children.push(node);
247
+ }
248
+ }
249
+ // Collect root-level nodes
250
+ const rootNodes = [];
251
+ for (const [path, node] of nodeMap) {
252
+ const parentPath = getParentPath(path);
253
+ const isRootLevel = basePath
254
+ ? path.startsWith(basePath + "/") &&
255
+ !parentPath.includes("/", basePath.length + 1) &&
256
+ parentPath === basePath
257
+ : !path.includes("/");
258
+ // For base path, check if direct child
259
+ if (basePath) {
260
+ const relativePath = path.slice(basePath.length + 1);
261
+ if (!relativePath.includes("/")) {
262
+ rootNodes.push(node);
263
+ }
264
+ }
265
+ else if (!path.includes("/")) {
266
+ rootNodes.push(node);
267
+ }
268
+ }
269
+ // Sort all nodes: folders first, then files, both alphabetically
270
+ const sortNodes = (nodes) => {
271
+ nodes.sort((a, b) => {
272
+ if (a.type !== b.type) {
273
+ return a.type === "folder" ? -1 : 1;
274
+ }
275
+ return a.name.localeCompare(b.name);
276
+ });
277
+ for (const node of nodes) {
278
+ if (node.children) {
279
+ sortNodes(node.children);
280
+ }
281
+ }
282
+ };
283
+ sortNodes(rootNodes);
284
+ return { tree: rootNodes, fileCount, totalSize };
285
+ }
286
+ /**
287
+ * Fetches the file tree from a GitHub repository.
288
+ * Uses the Git Trees API for efficiency (1 request for entire tree).
289
+ *
290
+ * @param repoString Repository in "owner/repo" format
291
+ * @param options Fetch options
292
+ * @returns Tree structure with metadata
293
+ */
294
+ export async function fetchRepoTree(repoString, options = {}) {
295
+ const { owner, repo } = parseRepoString(repoString);
296
+ const { path = "", branch: requestedBranch, extensions = DEFAULT_EXTENSIONS, maxDepth = 10, } = options;
297
+ // Detect or use specified branch
298
+ const branch = requestedBranch || (await detectDefaultBranch(owner, repo));
299
+ // Fetch the entire tree in one API call
300
+ const gitTree = await fetchGitTree(owner, repo, branch);
301
+ if (gitTree.truncated) {
302
+ console.error("Warning: Repository tree was truncated due to size. Some files may be missing.");
303
+ }
304
+ // Build hierarchical tree from flat list
305
+ const result = buildHierarchicalTree(gitTree.tree, path, extensions, maxDepth);
306
+ return {
307
+ repo: `${owner}/${repo}`,
308
+ branch,
309
+ tree: result.tree,
310
+ fileCount: result.fileCount,
311
+ totalSize: result.totalSize,
312
+ truncated: gitTree.truncated,
313
+ };
314
+ }
315
+ /**
316
+ * Fetches raw file content from GitHub via raw.githubusercontent.com.
317
+ * This endpoint has no rate limits (served from CDN).
318
+ *
319
+ * @param repoString Repository in "owner/repo" format
320
+ * @param branch Branch name
321
+ * @param filePath Path to the file within the repo
322
+ * @returns File content or null if not found
323
+ */
324
+ export async function fetchFileContent(repoString, branch, filePath) {
325
+ const { owner, repo } = parseRepoString(repoString);
326
+ // Use raw.githubusercontent.com - no rate limits, served from CDN
327
+ const url = `https://raw.githubusercontent.com/${owner}/${repo}/${branch}/${filePath}`;
328
+ const response = await fetch(url, {
329
+ headers: {
330
+ "User-Agent": "mcp-docs-scraper",
331
+ },
332
+ });
333
+ if (!response.ok) {
334
+ if (response.status === 404) {
335
+ // File not found - return null gracefully
336
+ return null;
337
+ }
338
+ throw new Error(`Failed to fetch file content: ${response.status} ${response.statusText}`);
339
+ }
340
+ const content = await response.text();
341
+ return {
342
+ path: filePath,
343
+ content,
344
+ size: new TextEncoder().encode(content).length,
345
+ };
346
+ }
347
+ /**
348
+ * Fetches multiple files from a repository.
349
+ * Handles 404s gracefully by skipping missing files.
350
+ *
351
+ * @param repoString Repository in "owner/repo" format
352
+ * @param branch Branch name
353
+ * @param filePaths Array of file paths to fetch
354
+ * @returns Array of successfully fetched files and array of not found paths
355
+ */
356
+ export async function fetchMultipleFiles(repoString, branch, filePaths) {
357
+ const files = [];
358
+ const notFound = [];
359
+ // Fetch files in parallel for better performance
360
+ const results = await Promise.all(filePaths.map(async (filePath) => {
361
+ try {
362
+ const result = await fetchFileContent(repoString, branch, filePath);
363
+ return { filePath, result };
364
+ }
365
+ catch (error) {
366
+ // Log error but don't fail the whole batch
367
+ console.error(`Error fetching ${filePath}:`, error);
368
+ return { filePath, result: null };
369
+ }
370
+ }));
371
+ for (const { filePath, result } of results) {
372
+ if (result) {
373
+ files.push(result);
374
+ }
375
+ else {
376
+ notFound.push(filePath);
377
+ }
378
+ }
379
+ return { files, notFound };
380
+ }
381
+ /**
382
+ * Gets the current GitHub API rate limit status.
383
+ */
384
+ export function getRateLimitStatus() {
385
+ return githubRateLimit.getStatusMessage();
386
+ }
387
+ /**
388
+ * Gets the raw rate limit info.
389
+ */
390
+ export function getRateLimitInfo() {
391
+ return githubRateLimit.getInfo();
392
+ }
393
+ //# sourceMappingURL=github-fetcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-fetcher.js","sourceRoot":"","sources":["../../src/services/github-fetcher.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,106 @@
1
+ /**
2
+ * Search index service - Full-text search using MiniSearch.
3
+ *
4
+ * Indexes documentation content for fast searching.
5
+ * Index is built during docs indexing and stored in cache.
6
+ */
7
+ import MiniSearch from "minisearch";
8
+ /**
9
+ * Document to be indexed.
10
+ */
11
+ export interface IndexableDocument {
12
+ /** File path (unique identifier) */
13
+ id: string;
14
+ /** Document title (from first H1 or filename) */
15
+ title: string;
16
+ /** All headings concatenated */
17
+ headings: string;
18
+ /** Full text content */
19
+ content: string;
20
+ }
21
+ /**
22
+ * Search result with snippet.
23
+ */
24
+ export interface SearchResult {
25
+ /** File path */
26
+ path: string;
27
+ /** Document title */
28
+ title: string;
29
+ /** Matching excerpt with context */
30
+ snippet: string;
31
+ /** Relevance score (higher = more relevant) */
32
+ score: number;
33
+ }
34
+ /**
35
+ * Serialized index format for storage.
36
+ */
37
+ export interface SerializedSearchIndex {
38
+ /** MiniSearch serialized index */
39
+ index: ReturnType<MiniSearch<IndexableDocument>["toJSON"]>;
40
+ /** Document metadata for generating snippets */
41
+ documents: Map<string, {
42
+ title: string;
43
+ content: string;
44
+ }>;
45
+ /** Version for future compatibility */
46
+ version: number;
47
+ }
48
+ /**
49
+ * Creates and manages a full-text search index for documentation.
50
+ */
51
+ export declare class SearchIndex {
52
+ private miniSearch;
53
+ private documents;
54
+ constructor();
55
+ /**
56
+ * Adds a document to the index.
57
+ */
58
+ addDocument(doc: IndexableDocument): void;
59
+ /**
60
+ * Adds multiple documents to the index.
61
+ */
62
+ addDocuments(docs: IndexableDocument[]): void;
63
+ /**
64
+ * Searches the index and returns results with snippets.
65
+ */
66
+ search(query: string, limit?: number): SearchResult[];
67
+ /**
68
+ * Converts a MiniSearch result to our SearchResult format.
69
+ */
70
+ private toSearchResult;
71
+ /**
72
+ * Generates a snippet with the matching text highlighted.
73
+ */
74
+ private generateSnippet;
75
+ /**
76
+ * Returns the number of indexed documents.
77
+ */
78
+ get documentCount(): number;
79
+ /**
80
+ * Serializes the index for storage.
81
+ */
82
+ toJSON(): string;
83
+ /**
84
+ * Creates a SearchIndex from serialized JSON.
85
+ */
86
+ static fromJSON(json: string): SearchIndex;
87
+ /**
88
+ * Clears the index.
89
+ */
90
+ clear(): void;
91
+ }
92
+ /**
93
+ * Extracts a title from markdown content.
94
+ * Returns the first H1 heading, or undefined if none found.
95
+ */
96
+ export declare function extractTitle(content: string): string | undefined;
97
+ /**
98
+ * Extracts all headings from markdown content.
99
+ * Returns a concatenated string of all headings.
100
+ */
101
+ export declare function extractHeadings(content: string): string;
102
+ /**
103
+ * Creates an indexable document from file content.
104
+ */
105
+ export declare function createIndexableDocument(path: string, content: string): IndexableDocument;
106
+ //# sourceMappingURL=search-index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-index.d.ts","sourceRoot":"","sources":["../../src/services/search-index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,UAAgD,MAAM,YAAY,CAAC;AAE1E;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,oCAAoC;IACpC,EAAE,EAAE,MAAM,CAAC;IACX,iDAAiD;IACjD,KAAK,EAAE,MAAM,CAAC;IACd,gCAAgC;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,wBAAwB;IACxB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,gBAAgB;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,qBAAqB;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,oCAAoC;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,+CAA+C;IAC/C,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,kCAAkC;IAClC,KAAK,EAAE,UAAU,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC3D,gDAAgD;IAChD,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC3D,uCAAuC;IACvC,OAAO,EAAE,MAAM,CAAC;CACjB;AASD;;GAEG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,UAAU,CAAgC;IAClD,OAAO,CAAC,SAAS,CAAkD;;IAenE;;OAEG;IACH,WAAW,CAAC,GAAG,EAAE,iBAAiB,GAAG,IAAI;IAWzC;;OAEG;IACH,YAAY,CAAC,IAAI,EAAE,iBAAiB,EAAE,GAAG,IAAI;IAM7C;;OAEG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,GAAE,MAAW,GAAG,YAAY,EAAE;IAazD;;OAEG;IACH,OAAO,CAAC,cAAc;IAgBtB;;OAEG;IACH,OAAO,CAAC,eAAe;IAmDvB;;OAEG;IACH,IAAI,aAAa,IAAI,MAAM,CAE1B;IAED;;OAEG;IACH,MAAM,IAAI,MAAM;IAchB;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW;IA6B1C;;OAEG;IACH,KAAK,IAAI,IAAI;CAId;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAGhE;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAUvD;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,GACd,iBAAiB,CAUnB"}