@eightmedia/flightcheck 0.0.0-stage → 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 (127) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/LICENSE +691 -0
  3. package/README.md +106 -2
  4. package/dist/analyze/fixManifest.d.ts +65 -0
  5. package/dist/analyze/fixManifest.d.ts.map +1 -0
  6. package/dist/analyze/fixManifest.js +588 -0
  7. package/dist/analyze/report.d.ts +283 -0
  8. package/dist/analyze/report.d.ts.map +1 -0
  9. package/dist/analyze/report.js +726 -0
  10. package/dist/analyze/reportTier1.d.ts +46 -0
  11. package/dist/analyze/reportTier1.d.ts.map +1 -0
  12. package/dist/analyze/reportTier1.js +251 -0
  13. package/dist/analyze/stack.d.ts +33 -0
  14. package/dist/analyze/stack.d.ts.map +1 -0
  15. package/dist/analyze/stack.js +188 -0
  16. package/dist/analyze/structuredReport.d.ts +62 -0
  17. package/dist/analyze/structuredReport.d.ts.map +1 -0
  18. package/dist/analyze/structuredReport.js +524 -0
  19. package/dist/analyze.d.ts +3 -0
  20. package/dist/analyze.d.ts.map +1 -0
  21. package/dist/analyze.js +40 -0
  22. package/dist/checks/agent-ready.d.ts +63 -0
  23. package/dist/checks/agent-ready.d.ts.map +1 -0
  24. package/dist/checks/agent-ready.js +219 -0
  25. package/dist/checks/analyze.d.ts +15 -0
  26. package/dist/checks/analyze.d.ts.map +1 -0
  27. package/dist/checks/analyze.js +63 -0
  28. package/dist/checks/crawl.d.ts +28 -0
  29. package/dist/checks/crawl.d.ts.map +1 -0
  30. package/dist/checks/crawl.js +86 -0
  31. package/dist/checks/dns.d.ts +25 -0
  32. package/dist/checks/dns.d.ts.map +1 -0
  33. package/dist/checks/dns.js +80 -0
  34. package/dist/checks/index.d.ts +24 -0
  35. package/dist/checks/index.d.ts.map +1 -0
  36. package/dist/checks/index.js +12 -0
  37. package/dist/checks/issues.d.ts +8 -0
  38. package/dist/checks/issues.d.ts.map +1 -0
  39. package/dist/checks/issues.js +3 -0
  40. package/dist/checks/redirect.d.ts +38 -0
  41. package/dist/checks/redirect.d.ts.map +1 -0
  42. package/dist/checks/redirect.js +209 -0
  43. package/dist/checks/registry.d.ts +8 -0
  44. package/dist/checks/registry.d.ts.map +1 -0
  45. package/dist/checks/registry.js +275 -0
  46. package/dist/checks/robots-txt.d.ts +16 -0
  47. package/dist/checks/robots-txt.d.ts.map +1 -0
  48. package/dist/checks/robots-txt.js +99 -0
  49. package/dist/checks/runner.d.ts +9 -0
  50. package/dist/checks/runner.d.ts.map +1 -0
  51. package/dist/checks/runner.js +110 -0
  52. package/dist/checks/security-headers.d.ts +12 -0
  53. package/dist/checks/security-headers.d.ts.map +1 -0
  54. package/dist/checks/security-headers.js +53 -0
  55. package/dist/checks/sitemap.d.ts +36 -0
  56. package/dist/checks/sitemap.d.ts.map +1 -0
  57. package/dist/checks/sitemap.js +140 -0
  58. package/dist/checks/types.d.ts +72 -0
  59. package/dist/checks/types.d.ts.map +1 -0
  60. package/dist/checks/types.js +20 -0
  61. package/dist/cli.d.ts +3 -0
  62. package/dist/cli.d.ts.map +1 -0
  63. package/dist/cli.js +125 -0
  64. package/dist/crawler/checkGroups.d.ts +7 -0
  65. package/dist/crawler/checkGroups.d.ts.map +1 -0
  66. package/dist/crawler/checkGroups.js +29 -0
  67. package/dist/crawler/crawlState.d.ts +7 -0
  68. package/dist/crawler/crawlState.d.ts.map +1 -0
  69. package/dist/crawler/crawlState.js +6 -0
  70. package/dist/crawler/defaults.d.ts +11 -0
  71. package/dist/crawler/defaults.d.ts.map +1 -0
  72. package/dist/crawler/defaults.js +10 -0
  73. package/dist/crawler/extractors.d.ts +5 -0
  74. package/dist/crawler/extractors.d.ts.map +1 -0
  75. package/dist/crawler/extractors.js +169 -0
  76. package/dist/crawler/jsAssets.d.ts +2 -0
  77. package/dist/crawler/jsAssets.d.ts.map +1 -0
  78. package/dist/crawler/jsAssets.js +22 -0
  79. package/dist/crawler/outputPaths.d.ts +14 -0
  80. package/dist/crawler/outputPaths.d.ts.map +1 -0
  81. package/dist/crawler/outputPaths.js +51 -0
  82. package/dist/crawler/reporter.d.ts +3 -0
  83. package/dist/crawler/reporter.d.ts.map +1 -0
  84. package/dist/crawler/reporter.js +12 -0
  85. package/dist/crawler/robots.d.ts +5 -0
  86. package/dist/crawler/robots.d.ts.map +1 -0
  87. package/dist/crawler/robots.js +29 -0
  88. package/dist/crawler/runCrawler.d.ts +22 -0
  89. package/dist/crawler/runCrawler.d.ts.map +1 -0
  90. package/dist/crawler/runCrawler.js +172 -0
  91. package/dist/crawler/schema.d.ts +87 -0
  92. package/dist/crawler/schema.d.ts.map +1 -0
  93. package/dist/crawler/schema.js +44 -0
  94. package/dist/crawler/secrets.d.ts +4 -0
  95. package/dist/crawler/secrets.d.ts.map +1 -0
  96. package/dist/crawler/secrets.js +70 -0
  97. package/dist/crawler/sitemap.d.ts +8 -0
  98. package/dist/crawler/sitemap.d.ts.map +1 -0
  99. package/dist/crawler/sitemap.js +105 -0
  100. package/dist/crawler/stack.d.ts +3 -0
  101. package/dist/crawler/stack.d.ts.map +1 -0
  102. package/dist/crawler/stack.js +1 -0
  103. package/dist/crawler/stackDetect.d.ts +24 -0
  104. package/dist/crawler/stackDetect.d.ts.map +1 -0
  105. package/dist/crawler/stackDetect.js +604 -0
  106. package/dist/crawler/tier1Extractors.d.ts +5 -0
  107. package/dist/crawler/tier1Extractors.d.ts.map +1 -0
  108. package/dist/crawler/tier1Extractors.js +255 -0
  109. package/dist/crawler/tracking.d.ts +8 -0
  110. package/dist/crawler/tracking.d.ts.map +1 -0
  111. package/dist/crawler/tracking.js +50 -0
  112. package/dist/crawler/urlUtils.d.ts +12 -0
  113. package/dist/crawler/urlUtils.d.ts.map +1 -0
  114. package/dist/crawler/urlUtils.js +53 -0
  115. package/dist/index.d.ts +14 -0
  116. package/dist/index.d.ts.map +1 -0
  117. package/dist/index.js +7 -0
  118. package/docs/agent-fixes.md +17 -0
  119. package/docs/agent-ready.md +44 -0
  120. package/docs/analyze.md +103 -0
  121. package/docs/check-api.md +142 -0
  122. package/docs/checks.md +116 -0
  123. package/docs/crawler.md +158 -0
  124. package/docs/index.md +24 -0
  125. package/docs/qc-checks-plan.md +796 -0
  126. package/docs/stack.md +99 -0
  127. package/package.json +86 -4
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/crawler/schema.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ export function createEmptyVerificationRecord(url, status) {
2
+ return {
3
+ url,
4
+ status,
5
+ h1: "",
6
+ title: "",
7
+ metaTitle: "",
8
+ metaDescription: "",
9
+ robots: "",
10
+ template: "",
11
+ mainCount: null,
12
+ charset: "",
13
+ language: "",
14
+ colorScheme: "",
15
+ themeColor: "",
16
+ doctype: "",
17
+ viewport: "",
18
+ canonical: "",
19
+ favicon: "",
20
+ icons: [],
21
+ og: {
22
+ title: "",
23
+ description: "",
24
+ image: "",
25
+ url: "",
26
+ type: "",
27
+ siteName: "",
28
+ },
29
+ twitter: {
30
+ card: "",
31
+ title: "",
32
+ description: "",
33
+ image: "",
34
+ },
35
+ tracking: {
36
+ tagManager: [],
37
+ analytics: [],
38
+ },
39
+ security: {
40
+ secrets: [],
41
+ scannedAssets: 0,
42
+ },
43
+ };
44
+ }
@@ -0,0 +1,4 @@
1
+ import type { SecretFinding } from "./schema.js";
2
+ export declare function maskSecret(value: string): string;
3
+ export declare function scanText(text: string, source: string, reveal?: boolean): SecretFinding[];
4
+ //# sourceMappingURL=secrets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secrets.d.ts","sourceRoot":"","sources":["../../src/crawler/secrets.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAkB,MAAM,aAAa,CAAC;AA2CjE,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKhD;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,UAAQ,GAAG,aAAa,EAAE,CA8BtF"}
@@ -0,0 +1,70 @@
1
+ const PATTERNS = [
2
+ { type: "google-api-key", provider: "google", severity: "review", regex: /\bAIzaSy[0-9A-Za-z_-]{33}\b/g },
3
+ { type: "aws-access-key-id", provider: "aws", severity: "critical", regex: /\bAKIA[0-9A-Z]{16}\b/g },
4
+ { type: "stripe-secret-key", provider: "stripe", severity: "critical", regex: /\bsk_live_[0-9a-zA-Z]{24,}\b/g },
5
+ { type: "stripe-publishable-key", provider: "stripe", severity: "review", regex: /\bpk_live_[0-9a-zA-Z]{24,}\b/g },
6
+ { type: "github-token", provider: "github", severity: "critical", regex: /\bgh[posru]_[0-9A-Za-z]{36,}\b/g },
7
+ {
8
+ type: "private-key",
9
+ provider: "generic",
10
+ severity: "critical",
11
+ regex: /-----BEGIN (?:RSA |EC |OPENSSH |DSA |PGP )?PRIVATE KEY-----/g,
12
+ display: "[PRIVATE KEY BLOCK]",
13
+ },
14
+ {
15
+ type: "generic-secret",
16
+ provider: "generic",
17
+ severity: "critical",
18
+ regex: /["']?(?:secret|password|api[_-]?secret)["']?\s*[:=]\s*["']([^"'\s]{8,})["']/gi,
19
+ group: 1,
20
+ generic: true,
21
+ },
22
+ {
23
+ type: "generic-api-key",
24
+ provider: "generic",
25
+ severity: "review",
26
+ regex: /["']?(?:api[_-]?key|access[_-]?token|auth[_-]?token)["']?\s*[:=]\s*["']([^"'\s]{12,})["']/gi,
27
+ group: 1,
28
+ generic: true,
29
+ },
30
+ ];
31
+ export function maskSecret(value) {
32
+ if (value.length <= 10) {
33
+ return `${value.slice(0, 2)}…${value.slice(-2)}`;
34
+ }
35
+ return `${value.slice(0, 6)}…${value.slice(-4)}`;
36
+ }
37
+ export function scanText(text, source, reveal = false) {
38
+ const findings = [];
39
+ const seen = new Set(); // dedup: type + raw value
40
+ const specificValues = new Set(); // raw values from non-generic patterns
41
+ const collect = (pattern) => {
42
+ const re = new RegExp(pattern.regex.source, pattern.regex.flags);
43
+ let match;
44
+ while ((match = re.exec(text)) !== null) {
45
+ const raw = pattern.group ? match[pattern.group] : match[0];
46
+ if (!raw)
47
+ continue;
48
+ if (pattern.generic && specificValues.has(raw))
49
+ continue;
50
+ const key = `${pattern.type}:${raw}`;
51
+ if (seen.has(key))
52
+ continue;
53
+ seen.add(key);
54
+ if (!pattern.generic)
55
+ specificValues.add(raw);
56
+ findings.push({
57
+ type: pattern.type,
58
+ provider: pattern.provider,
59
+ severity: pattern.severity,
60
+ masked: pattern.display ?? (reveal ? raw : maskSecret(raw)),
61
+ source,
62
+ });
63
+ }
64
+ };
65
+ for (const pattern of PATTERNS.filter((p) => !p.generic))
66
+ collect(pattern);
67
+ for (const pattern of PATTERNS.filter((p) => p.generic))
68
+ collect(pattern);
69
+ return findings;
70
+ }
@@ -0,0 +1,8 @@
1
+ export type SitemapDocumentType = "index" | "urlset" | "unknown";
2
+ export declare function detectSitemapDocumentType(xml: string): SitemapDocumentType;
3
+ export declare function extractSitemapLocValues(xml: string): string[];
4
+ export declare function canonicalSiteHostname(hostname: string): string;
5
+ export declare function isRelatedSiteUrl(url: string, siteOrigin: string): boolean;
6
+ export declare function processSitemapLocations(xml: string, siteOrigin: string, visitedSitemaps: Set<string>, pageUrls: Set<string>, sitemapQueue: string[]): void;
7
+ export declare function collectUrlsFromSitemap(sitemapUrl: string, origin: string, timeoutMs: number): Promise<Set<string>>;
8
+ //# sourceMappingURL=sitemap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sitemap.d.ts","sourceRoot":"","sources":["../../src/crawler/sitemap.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,mBAAmB,GAAG,OAAO,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEjE,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,MAAM,GAAG,mBAAmB,CAI1E;AAED,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAW7D;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE9D;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAQzE;AAWD,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,MAAM,EAClB,eAAe,EAAE,GAAG,CAAC,MAAM,CAAC,EAC5B,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,EACrB,YAAY,EAAE,MAAM,EAAE,GACrB,IAAI,CA8BN;AAED,wBAAsB,sBAAsB,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAmCxH"}
@@ -0,0 +1,105 @@
1
+ import { DEFAULT_MAX_SITEMAPS, DEFAULT_MAX_SITEMAP_URLS, DEFAULT_USER_AGENT } from "./defaults.js";
2
+ import { normalizeUrl } from "./urlUtils.js";
3
+ export function detectSitemapDocumentType(xml) {
4
+ if (/<sitemapindex[\s>]/i.test(xml))
5
+ return "index";
6
+ if (/<urlset[\s>]/i.test(xml))
7
+ return "urlset";
8
+ return "unknown";
9
+ }
10
+ export function extractSitemapLocValues(xml) {
11
+ const values = [];
12
+ const locRegex = /<loc>\s*([\s\S]*?)\s*<\/loc>/gi;
13
+ let match;
14
+ while ((match = locRegex.exec(xml)) !== null) {
15
+ const locValue = (match[1] ?? "").trim();
16
+ if (locValue)
17
+ values.push(locValue);
18
+ }
19
+ return values;
20
+ }
21
+ export function canonicalSiteHostname(hostname) {
22
+ return hostname.toLowerCase().startsWith("www.") ? hostname.slice(4).toLowerCase() : hostname.toLowerCase();
23
+ }
24
+ export function isRelatedSiteUrl(url, siteOrigin) {
25
+ try {
26
+ const parsed = new URL(normalizeUrl(url));
27
+ const site = new URL(siteOrigin);
28
+ return canonicalSiteHostname(parsed.hostname) === canonicalSiteHostname(site.hostname);
29
+ }
30
+ catch {
31
+ return false;
32
+ }
33
+ }
34
+ function looksLikeSitemapFile(url) {
35
+ try {
36
+ const pathname = new URL(url).pathname.toLowerCase();
37
+ return pathname.endsWith(".xml") && pathname.includes("sitemap");
38
+ }
39
+ catch {
40
+ return false;
41
+ }
42
+ }
43
+ export function processSitemapLocations(xml, siteOrigin, visitedSitemaps, pageUrls, sitemapQueue) {
44
+ const docType = detectSitemapDocumentType(xml);
45
+ const locs = extractSitemapLocValues(xml);
46
+ for (const locValue of locs) {
47
+ try {
48
+ const normalizedLoc = normalizeUrl(locValue);
49
+ if (!isRelatedSiteUrl(normalizedLoc, siteOrigin))
50
+ continue;
51
+ if (docType === "index") {
52
+ if (!visitedSitemaps.has(normalizedLoc)) {
53
+ sitemapQueue.push(normalizedLoc);
54
+ }
55
+ continue;
56
+ }
57
+ if (docType === "urlset") {
58
+ pageUrls.add(normalizedLoc);
59
+ continue;
60
+ }
61
+ if (looksLikeSitemapFile(normalizedLoc) && !visitedSitemaps.has(normalizedLoc)) {
62
+ sitemapQueue.push(normalizedLoc);
63
+ }
64
+ else {
65
+ pageUrls.add(normalizedLoc);
66
+ }
67
+ }
68
+ catch {
69
+ // Ignore malformed loc values.
70
+ }
71
+ }
72
+ }
73
+ export async function collectUrlsFromSitemap(sitemapUrl, origin, timeoutMs) {
74
+ const urls = new Set();
75
+ const visitedSitemaps = new Set();
76
+ const queue = [normalizeUrl(sitemapUrl)];
77
+ while (queue.length > 0 &&
78
+ visitedSitemaps.size < DEFAULT_MAX_SITEMAPS &&
79
+ urls.size < DEFAULT_MAX_SITEMAP_URLS) {
80
+ const currentSitemap = queue.shift();
81
+ if (!currentSitemap || visitedSitemaps.has(currentSitemap))
82
+ continue;
83
+ visitedSitemaps.add(currentSitemap);
84
+ try {
85
+ const controller = new AbortController();
86
+ const timeout = setTimeout(() => controller.abort(), timeoutMs);
87
+ const response = await fetch(currentSitemap, {
88
+ redirect: "follow",
89
+ signal: controller.signal,
90
+ headers: {
91
+ "user-agent": DEFAULT_USER_AGENT,
92
+ },
93
+ });
94
+ clearTimeout(timeout);
95
+ if (!response.ok)
96
+ continue;
97
+ const text = await response.text();
98
+ processSitemapLocations(text, origin, visitedSitemaps, urls, queue);
99
+ }
100
+ catch {
101
+ // Ignore sitemap fetch errors and continue.
102
+ }
103
+ }
104
+ return urls;
105
+ }
@@ -0,0 +1,3 @@
1
+ export type { StackCategory, StackDetection } from "./stackDetect.js";
2
+ export { CURATED_STACK_NAMES, detectStackFromDns, detectStackFromHeaders, detectStackFromHtml, detectStackFromRobots, isCuratedStackName, } from "./stackDetect.js";
3
+ //# sourceMappingURL=stack.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stack.d.ts","sourceRoot":"","sources":["../../src/crawler/stack.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACtE,OAAO,EACL,mBAAmB,EACnB,kBAAkB,EAClB,sBAAsB,EACtB,mBAAmB,EACnB,qBAAqB,EACrB,kBAAkB,GACnB,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1 @@
1
+ export { CURATED_STACK_NAMES, detectStackFromDns, detectStackFromHeaders, detectStackFromHtml, detectStackFromRobots, isCuratedStackName, } from "./stackDetect.js";
@@ -0,0 +1,24 @@
1
+ export type StackCategory = "Platform" | "Framework" | "CMS" | "Search" | "Hosting" | "CDN";
2
+ export type StackDetection = {
3
+ name: string;
4
+ categories: string[];
5
+ confidence: "high" | "medium" | "low";
6
+ evidence: string[];
7
+ website?: string;
8
+ version?: string;
9
+ detector?: "flightcheck-v1";
10
+ };
11
+ export declare function detectStackFromHtml(html: string, pageUrl: string): StackDetection[];
12
+ export declare function detectStackFromHeaders(headers: Record<string, string>): StackDetection[];
13
+ export declare function detectStackFromDns(records: {
14
+ cname: string[];
15
+ ns: string[];
16
+ mx: Array<{
17
+ exchange: string;
18
+ }>;
19
+ txt: string[];
20
+ }): StackDetection[];
21
+ export declare function detectStackFromRobots(_body: string): StackDetection[];
22
+ export declare const CURATED_STACK_NAMES: Set<string>;
23
+ export declare function isCuratedStackName(name: string): boolean;
24
+ //# sourceMappingURL=stackDetect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stackDetect.d.ts","sourceRoot":"","sources":["../../src/crawler/stackDetect.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,WAAW,GAAG,KAAK,GAAG,QAAQ,GAAG,SAAS,GAAG,KAAK,CAAC;AAE5F,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,UAAU,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IACtC,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,gBAAgB,CAAC;CAC7B,CAAC;AA4gBF,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,cAAc,EAAE,CAgEnF;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,cAAc,EAAE,CAWxF;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE;IAC1C,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,EAAE,EAAE,MAAM,EAAE,CAAC;IACb,EAAE,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAChC,GAAG,EAAE,MAAM,EAAE,CAAC;CACf,GAAG,cAAc,EAAE,CAgBnB;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,EAAE,CAErE;AAED,eAAO,MAAM,mBAAmB,aAS9B,CAAC;AAEH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAExD"}