@rulemetric/skills-registry 0.1.1 → 0.2.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.
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env tsx
2
+ export {};
3
+ //# sourceMappingURL=discover-sources.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discover-sources.d.ts","sourceRoot":"","sources":["../src/discover-sources.ts"],"names":[],"mappings":""}
@@ -0,0 +1,183 @@
1
+ #!/usr/bin/env tsx
2
+ /**
3
+ * Discover new skill repositories on GitHub by searching for relevant topics and keywords.
4
+ * Outputs candidate RegistrySource entries that can be added to sources.ts.
5
+ *
6
+ * Usage:
7
+ * GITHUB_TOKEN=ghp_xxx pnpm --filter @rulemetric/skills-registry discover
8
+ */
9
+ import * as fs from 'node:fs';
10
+ import * as path from 'node:path';
11
+ import { fileURLToPath } from 'node:url';
12
+ import { TIER_1_SOURCES, TIER_2_SOURCES } from './sources.js';
13
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
14
+ const GITHUB_API = 'https://api.github.com';
15
+ /** Topics and keywords to search for. */
16
+ const SEARCH_QUERIES = [
17
+ // Topic-based searches
18
+ 'topic:claude-code-skills',
19
+ 'topic:cursorrules',
20
+ 'topic:agents-md',
21
+ 'topic:ai-coding-rules',
22
+ 'topic:claude-code',
23
+ 'topic:copilot-instructions',
24
+ 'topic:ai-prompts',
25
+ 'topic:soul-md',
26
+ 'topic:openclaw',
27
+ // Keyword-based searches (in repo name or description)
28
+ 'claude-code skills in:name,description',
29
+ 'cursorrules in:name',
30
+ 'agents.md rules in:name,description',
31
+ 'copilot-instructions in:name',
32
+ 'ai coding rules in:name,description',
33
+ 'claude skills in:name',
34
+ 'windsurf rules in:name,description',
35
+ ];
36
+ /** Minimum quality thresholds. */
37
+ const MIN_STARS = 5;
38
+ const MIN_SIZE_KB = 1; // Skip near-empty repos
39
+ async function searchGitHub(query) {
40
+ const token = process.env.GITHUB_TOKEN;
41
+ const headers = {
42
+ 'Accept': 'application/vnd.github.v3+json',
43
+ 'User-Agent': 'rulemetric-skills-registry',
44
+ };
45
+ if (token)
46
+ headers['Authorization'] = `Bearer ${token}`;
47
+ const url = `${GITHUB_API}/search/repositories?q=${encodeURIComponent(query)}&sort=stars&order=desc&per_page=30`;
48
+ try {
49
+ const resp = await fetch(url, { headers, signal: AbortSignal.timeout(15000) });
50
+ if (!resp.ok) {
51
+ console.error(` Search failed (${resp.status}): ${query}`);
52
+ return [];
53
+ }
54
+ const data = await resp.json();
55
+ return data.items ?? [];
56
+ }
57
+ catch (err) {
58
+ console.error(` Search error: ${query}`, err);
59
+ return [];
60
+ }
61
+ }
62
+ /** Infer the default tool from repo name, topics, and description. */
63
+ function inferTool(repo) {
64
+ const text = `${repo.full_name} ${repo.description ?? ''} ${repo.topics.join(' ')}`.toLowerCase();
65
+ if (text.includes('claude-code') || text.includes('claude_code') || text.includes('claude-skills'))
66
+ return 'claude_code';
67
+ if (text.includes('cursor') || text.includes('cursorrules') || text.includes('.mdc'))
68
+ return 'cursor';
69
+ if (text.includes('copilot'))
70
+ return 'copilot';
71
+ if (text.includes('windsurf'))
72
+ return 'windsurf';
73
+ if (text.includes('cline'))
74
+ return 'cline';
75
+ if (text.includes('aider'))
76
+ return 'aider';
77
+ if (text.includes('openclaw') || text.includes('soul.md'))
78
+ return 'openclaw';
79
+ return 'universal';
80
+ }
81
+ /** Infer the default category. */
82
+ function inferCategory(repo) {
83
+ const text = `${repo.full_name} ${repo.description ?? ''} ${repo.topics.join(' ')}`.toLowerCase();
84
+ if (text.includes('security') || text.includes('owasp'))
85
+ return 'security';
86
+ if (text.includes('test') || text.includes('tdd'))
87
+ return 'testing';
88
+ if (text.includes('react') || text.includes('django') || text.includes('rails') || text.includes('flutter'))
89
+ return 'framework';
90
+ if (text.includes('typescript') || text.includes('python') || text.includes('rust') || text.includes('swift'))
91
+ return 'language';
92
+ if (text.includes('devops') || text.includes('docker') || text.includes('deploy'))
93
+ return 'devops';
94
+ if (text.includes('architect'))
95
+ return 'architecture';
96
+ return 'workflow';
97
+ }
98
+ /** Infer glob patterns for skill files. */
99
+ function inferPatterns(repo) {
100
+ const text = `${repo.full_name} ${repo.description ?? ''}`.toLowerCase();
101
+ const patterns = [];
102
+ if (text.includes('cursorrules') || text.includes('.mdc')) {
103
+ patterns.push('**/*.cursorrules', '**/*.mdc');
104
+ }
105
+ if (text.includes('skills')) {
106
+ patterns.push('skills/**/*.md');
107
+ }
108
+ if (text.includes('agents') || text.includes('agents.md')) {
109
+ patterns.push('agents/**/*.md', '**/AGENTS.md');
110
+ }
111
+ if (text.includes('rules') || text.includes('instructions') || text.includes('prompts')) {
112
+ patterns.push('**/*.md');
113
+ }
114
+ // Fallback: scan all markdown
115
+ if (patterns.length === 0) {
116
+ patterns.push('**/*.md');
117
+ }
118
+ return [...new Set(patterns)];
119
+ }
120
+ async function main() {
121
+ // Build set of already-known repos
122
+ const knownRepos = new Set();
123
+ for (const s of [...TIER_1_SOURCES, ...TIER_2_SOURCES]) {
124
+ knownRepos.add(s.repo.toLowerCase());
125
+ }
126
+ console.log(`Known repos: ${knownRepos.size}`);
127
+ console.log(`Running ${SEARCH_QUERIES.length} search queries...\n`);
128
+ const candidates = new Map();
129
+ for (const query of SEARCH_QUERIES) {
130
+ // Rate limit: 10 searches/min for authenticated, 5/min unauthenticated
131
+ await new Promise(r => setTimeout(r, 2000));
132
+ const results = await searchGitHub(query);
133
+ let newCount = 0;
134
+ for (const repo of results) {
135
+ const key = repo.full_name.toLowerCase();
136
+ if (knownRepos.has(key))
137
+ continue;
138
+ if (repo.stargazers_count < MIN_STARS)
139
+ continue;
140
+ if (repo.size < MIN_SIZE_KB)
141
+ continue;
142
+ if (!candidates.has(key)) {
143
+ candidates.set(key, repo);
144
+ newCount++;
145
+ }
146
+ }
147
+ console.log(` "${query}" → ${results.length} results, ${newCount} new candidates`);
148
+ }
149
+ console.log(`\nDiscovered ${candidates.size} candidate repos:\n`);
150
+ // Sort by stars descending
151
+ const sorted = [...candidates.values()].sort((a, b) => b.stargazers_count - a.stargazers_count);
152
+ // Generate RegistrySource entries
153
+ const discovered = [];
154
+ for (const repo of sorted) {
155
+ const tool = inferTool(repo);
156
+ const category = inferCategory(repo);
157
+ const patterns = inferPatterns(repo);
158
+ const license = repo.license?.spdx_id;
159
+ const source = {
160
+ repo: repo.full_name,
161
+ patterns,
162
+ defaultTool: tool,
163
+ defaultCategory: category,
164
+ ...(license ? { license } : {}),
165
+ };
166
+ discovered.push(source);
167
+ const stale = (Date.now() - new Date(repo.updated_at).getTime()) > 180 * 86400000;
168
+ console.log(` ${stale ? '⚠' : '✓'} ${repo.full_name} (${repo.stargazers_count}★)` +
169
+ ` [${tool}/${category}]` +
170
+ (repo.description ? ` — ${repo.description.slice(0, 80)}` : '') +
171
+ (stale ? ' (stale >6mo)' : ''));
172
+ }
173
+ // Write discovered sources to a file
174
+ const outputPath = path.resolve(__dirname, '..', 'discovered-sources.json');
175
+ fs.writeFileSync(outputPath, JSON.stringify(discovered, null, 2));
176
+ console.log(`\nWrote ${discovered.length} candidates to ${outputPath}`);
177
+ console.log('Review and add promising ones to sources.ts');
178
+ }
179
+ main().catch(err => {
180
+ console.error('Fatal:', err);
181
+ process.exit(1);
182
+ });
183
+ //# sourceMappingURL=discover-sources.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discover-sources.js","sourceRoot":"","sources":["../src/discover-sources.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { RegistrySource } from './types.js';
2
+ /**
3
+ * Load the build-time-discovered registry sources from
4
+ * `packages/skills-registry/discovered-sources.json`. Returns [] if the file
5
+ * is missing (e.g. running against a stripped install). Used by
6
+ * `cron_refresh_skills` so the cron's coverage matches the bundled registry.
7
+ *
8
+ * Path resolution: dist/discovered.js sits at packages/skills-registry/dist/,
9
+ * the JSON sits at packages/skills-registry/. So we walk up one level.
10
+ */
11
+ export declare function loadDiscoveredSources(): RegistrySource[];
12
+ //# sourceMappingURL=discovered.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discovered.d.ts","sourceRoot":"","sources":["../src/discovered.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAIjD;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,IAAI,cAAc,EAAE,CAcxD"}
@@ -0,0 +1,30 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import path from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
5
+ /**
6
+ * Load the build-time-discovered registry sources from
7
+ * `packages/skills-registry/discovered-sources.json`. Returns [] if the file
8
+ * is missing (e.g. running against a stripped install). Used by
9
+ * `cron_refresh_skills` so the cron's coverage matches the bundled registry.
10
+ *
11
+ * Path resolution: dist/discovered.js sits at packages/skills-registry/dist/,
12
+ * the JSON sits at packages/skills-registry/. So we walk up one level.
13
+ */
14
+ export function loadDiscoveredSources() {
15
+ const candidates = [
16
+ path.resolve(__dirname, '..', 'discovered-sources.json'),
17
+ path.resolve(__dirname, '..', '..', 'discovered-sources.json'),
18
+ ];
19
+ for (const p of candidates) {
20
+ try {
21
+ const raw = readFileSync(p, 'utf-8');
22
+ return JSON.parse(raw);
23
+ }
24
+ catch {
25
+ // try next candidate
26
+ }
27
+ }
28
+ return [];
29
+ }
30
+ //# sourceMappingURL=discovered.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"discovered.js","sourceRoot":"","sources":["../src/discovered.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAGzC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAE/D;;;;;;;;GAQG;AACH,MAAM,UAAU,qBAAqB;IACjC,MAAM,UAAU,GAAG;QACf,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,yBAAyB,CAAC;QACxD,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,yBAAyB,CAAC;KACjE,CAAC;IACF,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;QACzB,IAAI,CAAC;YACD,MAAM,GAAG,GAAG,YAAY,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;YACrC,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAqB,CAAC;QAC/C,CAAC;QAAC,MAAM,CAAC;YACL,qBAAqB;QACzB,CAAC;IACL,CAAC;IACD,OAAO,EAAE,CAAC;AACd,CAAC"}
@@ -12,14 +12,115 @@ import * as fs from 'node:fs';
12
12
  import * as path from 'node:path';
13
13
  import { fileURLToPath } from 'node:url';
14
14
  import { fetchAllSources } from './github-fetcher.js';
15
- import { TIER_1_SOURCES } from './sources.js';
15
+ import { computeQualityScore } from './scoring.js';
16
+ import { TIER_1_SOURCES, TIER_2_SOURCES } from './sources.js';
16
17
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
17
18
  const OUTPUT_PATH = path.resolve(__dirname, '..', 'registry.json');
19
+ const DISCOVERED_PATH = path.resolve(__dirname, '..', 'discovered-sources.json');
20
+ const COMMUNITY_PATH = path.resolve(__dirname, '..', 'community-skills.json');
21
+ const TREE_SHAS_PATH = path.resolve(__dirname, '..', 'tree-shas.json');
22
+ function loadPreviousShas() {
23
+ if (!fs.existsSync(TREE_SHAS_PATH))
24
+ return new Map();
25
+ try {
26
+ const obj = JSON.parse(fs.readFileSync(TREE_SHAS_PATH, 'utf-8'));
27
+ return new Map(Object.entries(obj));
28
+ }
29
+ catch {
30
+ return new Map();
31
+ }
32
+ }
33
+ function loadPreviousEntriesByRepo() {
34
+ if (!fs.existsSync(OUTPUT_PATH))
35
+ return new Map();
36
+ try {
37
+ const reg = JSON.parse(fs.readFileSync(OUTPUT_PATH, 'utf-8'));
38
+ const byRepo = new Map();
39
+ for (const s of reg.skills) {
40
+ const list = byRepo.get(s.source.repo) ?? [];
41
+ list.push(s);
42
+ byRepo.set(s.source.repo, list);
43
+ }
44
+ return byRepo;
45
+ }
46
+ catch {
47
+ return new Map();
48
+ }
49
+ }
18
50
  async function main() {
19
- console.log(`Fetching skills from ${TIER_1_SOURCES.length} Tier 1 sources...\n`);
20
- const entries = await fetchAllSources(TIER_1_SOURCES, (source, count) => {
21
- console.log(` ${source}: ${count} skills`);
51
+ const includeAll = process.argv.includes('--all');
52
+ const includeDiscovered = process.argv.includes('--discovered');
53
+ let sources = includeAll
54
+ ? [...TIER_1_SOURCES, ...TIER_2_SOURCES]
55
+ : TIER_1_SOURCES;
56
+ // Optionally include discovered sources from the last discovery run
57
+ if (includeDiscovered && fs.existsSync(DISCOVERED_PATH)) {
58
+ try {
59
+ const discovered = JSON.parse(fs.readFileSync(DISCOVERED_PATH, 'utf-8'));
60
+ console.log(`Including ${discovered.length} discovered sources\n`);
61
+ sources = [...sources, ...discovered];
62
+ }
63
+ catch {
64
+ console.warn('Warning: could not parse discovered-sources.json, skipping');
65
+ }
66
+ }
67
+ console.log(`Fetching skills from ${sources.length} sources${includeAll ? ' (Tier 1 + 2)' : ' (Tier 1)'}...\n`);
68
+ const previousShas = loadPreviousShas();
69
+ const previousEntriesByRepo = loadPreviousEntriesByRepo();
70
+ const { entries: freshEntries, treeShas } = await fetchAllSources(sources, {
71
+ previousShas,
72
+ onProgress: (source, count, skipped) => {
73
+ if (skipped) {
74
+ const prior = previousEntriesByRepo.get(source)?.length ?? 0;
75
+ console.log(` ${source}: skipped (unchanged, ${prior} cached)`);
76
+ }
77
+ else {
78
+ console.log(` ${source}: ${count} skills`);
79
+ }
80
+ },
22
81
  });
82
+ // Carry forward entries from sources that were skipped (tree SHA unchanged).
83
+ const entries = [...freshEntries];
84
+ const seenIds = new Set(entries.map(e => e.id));
85
+ for (const source of sources) {
86
+ const newSha = treeShas.get(source.repo);
87
+ const oldSha = previousShas.get(source.repo);
88
+ if (newSha && newSha === oldSha) {
89
+ for (const cached of previousEntriesByRepo.get(source.repo) ?? []) {
90
+ if (!seenIds.has(cached.id)) {
91
+ entries.push(cached);
92
+ seenIds.add(cached.id);
93
+ }
94
+ }
95
+ }
96
+ }
97
+ // Merge approved community submissions if the file exists
98
+ if (fs.existsSync(COMMUNITY_PATH)) {
99
+ try {
100
+ const community = JSON.parse(fs.readFileSync(COMMUNITY_PATH, 'utf-8'));
101
+ let merged = 0;
102
+ for (const skill of community) {
103
+ if (!seenIds.has(skill.id)) {
104
+ entries.push(skill);
105
+ seenIds.add(skill.id);
106
+ merged++;
107
+ }
108
+ }
109
+ if (merged > 0)
110
+ console.log(`\nMerged ${merged} community-submitted skills`);
111
+ }
112
+ catch {
113
+ console.warn('Warning: could not parse community-skills.json, skipping');
114
+ }
115
+ }
116
+ // Persist tree SHAs for next run's incremental skip.
117
+ fs.writeFileSync(TREE_SHAS_PATH, JSON.stringify(Object.fromEntries(treeShas), null, 2));
118
+ // Precompute quality scores once, with full content. Listing endpoints strip
119
+ // content but keep this score, so the badge in the listing matches the badge
120
+ // in the modal — and clients don't have to recompute on every render.
121
+ for (const entry of entries) {
122
+ entry.qualityScore = computeQualityScore(entry);
123
+ }
23
124
  const registry = {
24
125
  version: '1.0.0',
25
126
  generatedAt: new Date().toISOString(),
@@ -1 +1 @@
1
- {"version":3,"file":"fetch-registry.js","sourceRoot":"","sources":["../src/fetch-registry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fetch-registry.js","sourceRoot":"","sources":["../src/fetch-registry.ts"],"names":[],"mappings":"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"}
@@ -1,11 +1,48 @@
1
1
  import type { RegistrySource, SkillEntry } from './types.js';
2
2
  /**
3
- * Fetch all skills from a single registry source.
4
- * Returns parsed SkillEntry objects.
3
+ * Decide whether Octokit's primary-rate-limit retry is worth waiting for.
4
+ *
5
+ * Exported for unit testing — the function is pure (no I/O), so the test
6
+ * can assert the boundary cases without running the full crawl.
7
+ */
8
+ export declare function shouldRetryRateLimit(retryAfterSeconds: number, retryCount: number): boolean;
9
+ /**
10
+ * Decide whether Octokit's secondary-rate-limit retry is worth waiting for.
11
+ * Secondary limits are GitHub's abuse-detection cooldowns (multi-minute,
12
+ * sometimes longer). Same 5-min cap as primary.
5
13
  */
6
- export declare function fetchSource(source: RegistrySource): Promise<SkillEntry[]>;
14
+ export declare function shouldRetrySecondaryRateLimit(retryAfterSeconds: number): boolean;
7
15
  /**
8
- * Fetch skills from multiple sources and deduplicate.
16
+ * Reset the cached Octokit instance. Test-only hook so a test that mutates
17
+ * `process.env.GITHUB_TOKEN` can force a fresh client on the next call —
18
+ * otherwise the singleton above pins the auth value from first use.
19
+ */
20
+ export declare function _resetOctokitForTests(): void;
21
+ export interface FetchSourceResult {
22
+ entries: SkillEntry[];
23
+ treeSha: string | null;
24
+ skipped: boolean;
25
+ }
26
+ /**
27
+ * Fetch all skills from a single registry source.
28
+ *
29
+ * `previousTreeSha` is an optimization: if the repo's current tree SHA matches,
30
+ * the function returns early with `skipped: true` and no entries. The caller is
31
+ * expected to keep its existing entries for that source. Pass `undefined` to
32
+ * always fetch.
9
33
  */
10
- export declare function fetchAllSources(sources: RegistrySource[], onProgress?: (source: string, count: number) => void): Promise<SkillEntry[]>;
34
+ export declare function fetchSource(source: RegistrySource, previousTreeSha?: string): Promise<FetchSourceResult>;
35
+ export interface FetchAllOptions {
36
+ /** Map of repo → previous tree SHA. Sources with matching SHA are skipped. */
37
+ previousShas?: Map<string, string>;
38
+ /** Called after each source completes (successful or not). */
39
+ onProgress?: (source: string, count: number, skipped: boolean) => void;
40
+ }
41
+ export interface FetchAllResult {
42
+ entries: SkillEntry[];
43
+ /** Map of repo → current tree SHA, for caching across runs. */
44
+ treeShas: Map<string, string>;
45
+ }
46
+ /** Fetch skills from multiple sources, in parallel, deduplicating by id. */
47
+ export declare function fetchAllSources(sources: RegistrySource[], options?: FetchAllOptions): Promise<FetchAllResult>;
11
48
  //# sourceMappingURL=github-fetcher.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"github-fetcher.d.ts","sourceRoot":"","sources":["../src/github-fetcher.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAyB,MAAM,YAAY,CAAC;AAiNpF;;;GAGG;AACH,wBAAsB,WAAW,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAiE/E;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,cAAc,EAAE,EACzB,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,GACnD,OAAO,CAAC,UAAU,EAAE,CAAC,CAoBvB"}
1
+ {"version":3,"file":"github-fetcher.d.ts","sourceRoot":"","sources":["../src/github-fetcher.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAiB,MAAM,YAAY,CAAC;AAqC5E;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,iBAAiB,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAG3F;AAED;;;;GAIG;AACH,wBAAgB,6BAA6B,CAAC,iBAAiB,EAAE,MAAM,GAAG,OAAO,CAEhF;AA8BD;;;;GAIG;AACH,wBAAgB,qBAAqB,IAAI,IAAI,CAE5C;AAyMD,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;GAOG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,cAAc,EACtB,eAAe,CAAC,EAAE,MAAM,GACvB,OAAO,CAAC,iBAAiB,CAAC,CA4D5B;AAID,MAAM,WAAW,eAAe;IAC9B,8EAA8E;IAC9E,YAAY,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,8DAA8D;IAC9D,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;CACxE;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,+DAA+D;IAC/D,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/B;AAED,4EAA4E;AAC5E,wBAAsB,eAAe,CACnC,OAAO,EAAE,cAAc,EAAE,EACzB,OAAO,GAAE,eAAoB,GAC5B,OAAO,CAAC,cAAc,CAAC,CA4BzB"}