@debriefer/sources 1.0.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.
Files changed (194) hide show
  1. package/README.md +59 -0
  2. package/dist/__tests__/archives/chronicling-america.test.d.ts +8 -0
  3. package/dist/__tests__/archives/chronicling-america.test.d.ts.map +1 -0
  4. package/dist/__tests__/archives/chronicling-america.test.js +151 -0
  5. package/dist/__tests__/archives/chronicling-america.test.js.map +1 -0
  6. package/dist/__tests__/archives/europeana.test.d.ts +8 -0
  7. package/dist/__tests__/archives/europeana.test.d.ts.map +1 -0
  8. package/dist/__tests__/archives/europeana.test.js +200 -0
  9. package/dist/__tests__/archives/europeana.test.js.map +1 -0
  10. package/dist/__tests__/archives/internet-archive.test.d.ts +8 -0
  11. package/dist/__tests__/archives/internet-archive.test.d.ts.map +1 -0
  12. package/dist/__tests__/archives/internet-archive.test.js +189 -0
  13. package/dist/__tests__/archives/internet-archive.test.js.map +1 -0
  14. package/dist/__tests__/archives/trove.test.d.ts +8 -0
  15. package/dist/__tests__/archives/trove.test.d.ts.map +1 -0
  16. package/dist/__tests__/archives/trove.test.js +202 -0
  17. package/dist/__tests__/archives/trove.test.js.map +1 -0
  18. package/dist/__tests__/books/google-books.test.d.ts +8 -0
  19. package/dist/__tests__/books/google-books.test.d.ts.map +1 -0
  20. package/dist/__tests__/books/google-books.test.js +221 -0
  21. package/dist/__tests__/books/google-books.test.js.map +1 -0
  22. package/dist/__tests__/books/open-library.test.d.ts +8 -0
  23. package/dist/__tests__/books/open-library.test.d.ts.map +1 -0
  24. package/dist/__tests__/books/open-library.test.js +159 -0
  25. package/dist/__tests__/books/open-library.test.js.map +1 -0
  26. package/dist/__tests__/news/guardian.test.d.ts +9 -0
  27. package/dist/__tests__/news/guardian.test.d.ts.map +1 -0
  28. package/dist/__tests__/news/guardian.test.js +224 -0
  29. package/dist/__tests__/news/guardian.test.js.map +1 -0
  30. package/dist/__tests__/news/nytimes.test.d.ts +9 -0
  31. package/dist/__tests__/news/nytimes.test.d.ts.map +1 -0
  32. package/dist/__tests__/news/nytimes.test.js +271 -0
  33. package/dist/__tests__/news/nytimes.test.js.map +1 -0
  34. package/dist/__tests__/news/site-search-source.test.d.ts +9 -0
  35. package/dist/__tests__/news/site-search-source.test.d.ts.map +1 -0
  36. package/dist/__tests__/news/site-search-source.test.js +342 -0
  37. package/dist/__tests__/news/site-search-source.test.js.map +1 -0
  38. package/dist/__tests__/obituary/find-a-grave.test.d.ts +8 -0
  39. package/dist/__tests__/obituary/find-a-grave.test.d.ts.map +1 -0
  40. package/dist/__tests__/obituary/find-a-grave.test.js +238 -0
  41. package/dist/__tests__/obituary/find-a-grave.test.js.map +1 -0
  42. package/dist/__tests__/shared/duckduckgo-search.test.d.ts +9 -0
  43. package/dist/__tests__/shared/duckduckgo-search.test.d.ts.map +1 -0
  44. package/dist/__tests__/shared/duckduckgo-search.test.js +218 -0
  45. package/dist/__tests__/shared/duckduckgo-search.test.js.map +1 -0
  46. package/dist/__tests__/shared/fetch-page.test.d.ts +9 -0
  47. package/dist/__tests__/shared/fetch-page.test.d.ts.map +1 -0
  48. package/dist/__tests__/shared/fetch-page.test.js +281 -0
  49. package/dist/__tests__/shared/fetch-page.test.js.map +1 -0
  50. package/dist/__tests__/shared/html-utils.test.d.ts +2 -0
  51. package/dist/__tests__/shared/html-utils.test.d.ts.map +1 -0
  52. package/dist/__tests__/shared/html-utils.test.js +169 -0
  53. package/dist/__tests__/shared/html-utils.test.js.map +1 -0
  54. package/dist/__tests__/shared/readability-extract.test.d.ts +2 -0
  55. package/dist/__tests__/shared/readability-extract.test.d.ts.map +1 -0
  56. package/dist/__tests__/shared/readability-extract.test.js +107 -0
  57. package/dist/__tests__/shared/readability-extract.test.js.map +1 -0
  58. package/dist/__tests__/shared/sanitize-text.test.d.ts +2 -0
  59. package/dist/__tests__/shared/sanitize-text.test.d.ts.map +1 -0
  60. package/dist/__tests__/shared/sanitize-text.test.js +77 -0
  61. package/dist/__tests__/shared/sanitize-text.test.js.map +1 -0
  62. package/dist/__tests__/shared/search-utils.test.d.ts +2 -0
  63. package/dist/__tests__/shared/search-utils.test.d.ts.map +1 -0
  64. package/dist/__tests__/shared/search-utils.test.js +26 -0
  65. package/dist/__tests__/shared/search-utils.test.js.map +1 -0
  66. package/dist/__tests__/structured/wikidata.test.d.ts +9 -0
  67. package/dist/__tests__/structured/wikidata.test.d.ts.map +1 -0
  68. package/dist/__tests__/structured/wikidata.test.js +509 -0
  69. package/dist/__tests__/structured/wikidata.test.js.map +1 -0
  70. package/dist/__tests__/structured/wikipedia.test.d.ts +9 -0
  71. package/dist/__tests__/structured/wikipedia.test.d.ts.map +1 -0
  72. package/dist/__tests__/structured/wikipedia.test.js +643 -0
  73. package/dist/__tests__/structured/wikipedia.test.js.map +1 -0
  74. package/dist/__tests__/web-search/base.test.d.ts +9 -0
  75. package/dist/__tests__/web-search/base.test.d.ts.map +1 -0
  76. package/dist/__tests__/web-search/base.test.js +622 -0
  77. package/dist/__tests__/web-search/base.test.js.map +1 -0
  78. package/dist/__tests__/web-search/bing.test.d.ts +10 -0
  79. package/dist/__tests__/web-search/bing.test.d.ts.map +1 -0
  80. package/dist/__tests__/web-search/bing.test.js +277 -0
  81. package/dist/__tests__/web-search/bing.test.js.map +1 -0
  82. package/dist/__tests__/web-search/brave.test.d.ts +10 -0
  83. package/dist/__tests__/web-search/brave.test.d.ts.map +1 -0
  84. package/dist/__tests__/web-search/brave.test.js +264 -0
  85. package/dist/__tests__/web-search/brave.test.js.map +1 -0
  86. package/dist/__tests__/web-search/duckduckgo.test.d.ts +10 -0
  87. package/dist/__tests__/web-search/duckduckgo.test.d.ts.map +1 -0
  88. package/dist/__tests__/web-search/duckduckgo.test.js +107 -0
  89. package/dist/__tests__/web-search/duckduckgo.test.js.map +1 -0
  90. package/dist/__tests__/web-search/google.test.d.ts +9 -0
  91. package/dist/__tests__/web-search/google.test.d.ts.map +1 -0
  92. package/dist/__tests__/web-search/google.test.js +189 -0
  93. package/dist/__tests__/web-search/google.test.js.map +1 -0
  94. package/dist/archives/chronicling-america.d.ts +33 -0
  95. package/dist/archives/chronicling-america.d.ts.map +1 -0
  96. package/dist/archives/chronicling-america.js +85 -0
  97. package/dist/archives/chronicling-america.js.map +1 -0
  98. package/dist/archives/europeana.d.ts +37 -0
  99. package/dist/archives/europeana.d.ts.map +1 -0
  100. package/dist/archives/europeana.js +92 -0
  101. package/dist/archives/europeana.js.map +1 -0
  102. package/dist/archives/internet-archive.d.ts +32 -0
  103. package/dist/archives/internet-archive.d.ts.map +1 -0
  104. package/dist/archives/internet-archive.js +90 -0
  105. package/dist/archives/internet-archive.js.map +1 -0
  106. package/dist/archives/trove.d.ts +37 -0
  107. package/dist/archives/trove.d.ts.map +1 -0
  108. package/dist/archives/trove.js +97 -0
  109. package/dist/archives/trove.js.map +1 -0
  110. package/dist/books/google-books.d.ts +48 -0
  111. package/dist/books/google-books.d.ts.map +1 -0
  112. package/dist/books/google-books.js +111 -0
  113. package/dist/books/google-books.js.map +1 -0
  114. package/dist/books/open-library.d.ts +44 -0
  115. package/dist/books/open-library.d.ts.map +1 -0
  116. package/dist/books/open-library.js +103 -0
  117. package/dist/books/open-library.js.map +1 -0
  118. package/dist/index.d.ts +45 -0
  119. package/dist/index.d.ts.map +1 -0
  120. package/dist/index.js +35 -0
  121. package/dist/index.js.map +1 -0
  122. package/dist/news/guardian.d.ts +51 -0
  123. package/dist/news/guardian.d.ts.map +1 -0
  124. package/dist/news/guardian.js +131 -0
  125. package/dist/news/guardian.js.map +1 -0
  126. package/dist/news/nytimes.d.ts +27 -0
  127. package/dist/news/nytimes.d.ts.map +1 -0
  128. package/dist/news/nytimes.js +104 -0
  129. package/dist/news/nytimes.js.map +1 -0
  130. package/dist/news/site-search-source.d.ts +89 -0
  131. package/dist/news/site-search-source.d.ts.map +1 -0
  132. package/dist/news/site-search-source.js +182 -0
  133. package/dist/news/site-search-source.js.map +1 -0
  134. package/dist/news/sources.d.ts +52 -0
  135. package/dist/news/sources.d.ts.map +1 -0
  136. package/dist/news/sources.js +276 -0
  137. package/dist/news/sources.js.map +1 -0
  138. package/dist/obituary/find-a-grave.d.ts +43 -0
  139. package/dist/obituary/find-a-grave.d.ts.map +1 -0
  140. package/dist/obituary/find-a-grave.js +173 -0
  141. package/dist/obituary/find-a-grave.js.map +1 -0
  142. package/dist/shared/duckduckgo-search.d.ts +86 -0
  143. package/dist/shared/duckduckgo-search.d.ts.map +1 -0
  144. package/dist/shared/duckduckgo-search.js +218 -0
  145. package/dist/shared/duckduckgo-search.js.map +1 -0
  146. package/dist/shared/fetch-page.d.ts +50 -0
  147. package/dist/shared/fetch-page.d.ts.map +1 -0
  148. package/dist/shared/fetch-page.js +212 -0
  149. package/dist/shared/fetch-page.js.map +1 -0
  150. package/dist/shared/html-utils.d.ts +99 -0
  151. package/dist/shared/html-utils.d.ts.map +1 -0
  152. package/dist/shared/html-utils.js +246 -0
  153. package/dist/shared/html-utils.js.map +1 -0
  154. package/dist/shared/readability-extract.d.ts +33 -0
  155. package/dist/shared/readability-extract.d.ts.map +1 -0
  156. package/dist/shared/readability-extract.js +45 -0
  157. package/dist/shared/readability-extract.js.map +1 -0
  158. package/dist/shared/sanitize-text.d.ts +24 -0
  159. package/dist/shared/sanitize-text.d.ts.map +1 -0
  160. package/dist/shared/sanitize-text.js +49 -0
  161. package/dist/shared/sanitize-text.js.map +1 -0
  162. package/dist/shared/search-utils.d.ts +18 -0
  163. package/dist/shared/search-utils.d.ts.map +1 -0
  164. package/dist/shared/search-utils.js +20 -0
  165. package/dist/shared/search-utils.js.map +1 -0
  166. package/dist/structured/wikidata.d.ts +128 -0
  167. package/dist/structured/wikidata.d.ts.map +1 -0
  168. package/dist/structured/wikidata.js +361 -0
  169. package/dist/structured/wikidata.js.map +1 -0
  170. package/dist/structured/wikipedia.d.ts +184 -0
  171. package/dist/structured/wikipedia.d.ts.map +1 -0
  172. package/dist/structured/wikipedia.js +275 -0
  173. package/dist/structured/wikipedia.js.map +1 -0
  174. package/dist/web-search/base.d.ts +128 -0
  175. package/dist/web-search/base.d.ts.map +1 -0
  176. package/dist/web-search/base.js +251 -0
  177. package/dist/web-search/base.js.map +1 -0
  178. package/dist/web-search/bing.d.ts +21 -0
  179. package/dist/web-search/bing.d.ts.map +1 -0
  180. package/dist/web-search/bing.js +53 -0
  181. package/dist/web-search/bing.js.map +1 -0
  182. package/dist/web-search/brave.d.ts +21 -0
  183. package/dist/web-search/brave.d.ts.map +1 -0
  184. package/dist/web-search/brave.js +56 -0
  185. package/dist/web-search/brave.js.map +1 -0
  186. package/dist/web-search/duckduckgo.d.ts +15 -0
  187. package/dist/web-search/duckduckgo.d.ts.map +1 -0
  188. package/dist/web-search/duckduckgo.js +21 -0
  189. package/dist/web-search/duckduckgo.js.map +1 -0
  190. package/dist/web-search/google.d.ts +24 -0
  191. package/dist/web-search/google.d.ts.map +1 -0
  192. package/dist/web-search/google.js +48 -0
  193. package/dist/web-search/google.js.map +1 -0
  194. package/package.json +58 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"europeana.js","sourceRoot":"","sources":["../../src/archives/europeana.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Internet Archive source.
3
+ *
4
+ * Queries the Internet Archive advanced search API for books, documents,
5
+ * and media about a research subject. No authentication required.
6
+ */
7
+ import { BaseResearchSource, ReliabilityTier, type BaseSourceOptions, type ResearchSubject, type RawFinding } from "@debriefer/core";
8
+ export type InternetArchiveOptions = BaseSourceOptions;
9
+ /**
10
+ * Research source backed by the Internet Archive advanced search API.
11
+ *
12
+ * Searches for books, documents, and media about a subject.
13
+ * Free, no API key required.
14
+ */
15
+ export declare class InternetArchiveSource extends BaseResearchSource<ResearchSubject> {
16
+ readonly name = "Internet Archive";
17
+ readonly type = "internet-archive";
18
+ readonly reliabilityTier = ReliabilityTier.ARCHIVE_MIRROR;
19
+ readonly domain = "archive.org";
20
+ readonly isFree = true;
21
+ readonly estimatedCostPerQuery = 0;
22
+ constructor(options?: InternetArchiveOptions);
23
+ protected fetchResult(subject: ResearchSubject, signal: AbortSignal): Promise<RawFinding | null>;
24
+ }
25
+ /**
26
+ * Create an Internet Archive source instance.
27
+ *
28
+ * @param options - Source options (rateLimitMs, etc.)
29
+ * @returns A configured InternetArchiveSource
30
+ */
31
+ export declare function internetArchive(options?: InternetArchiveOptions): InternetArchiveSource;
32
+ //# sourceMappingURL=internet-archive.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"internet-archive.d.ts","sourceRoot":"","sources":["../../src/archives/internet-archive.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,UAAU,EAChB,MAAM,iBAAiB,CAAA;AAcxB,MAAM,MAAM,sBAAsB,GAAG,iBAAiB,CAAA;AAqBtD;;;;;GAKG;AACH,qBAAa,qBAAsB,SAAQ,kBAAkB,CAAC,eAAe,CAAC;IAC5E,QAAQ,CAAC,IAAI,sBAAqB;IAClC,QAAQ,CAAC,IAAI,sBAAqB;IAClC,QAAQ,CAAC,eAAe,kCAAiC;IACzD,QAAQ,CAAC,MAAM,iBAAgB;IAC/B,QAAQ,CAAC,MAAM,QAAO;IACtB,QAAQ,CAAC,qBAAqB,KAAI;gBAEtB,OAAO,GAAE,sBAA2B;cAIhC,WAAW,CACzB,OAAO,EAAE,eAAe,EACxB,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;CAgD9B;AAMD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,OAAO,CAAC,EAAE,sBAAsB,GAAG,qBAAqB,CAEvF"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Internet Archive source.
3
+ *
4
+ * Queries the Internet Archive advanced search API for books, documents,
5
+ * and media about a research subject. No authentication required.
6
+ */
7
+ import { BaseResearchSource, ReliabilityTier, } from "@debriefer/core";
8
+ import { sanitizeSourceText } from "../shared/sanitize-text.js";
9
+ // ============================================================================
10
+ // Constants
11
+ // ============================================================================
12
+ const IA_API_URL = "https://archive.org/advancedsearch.php";
13
+ const IA_DETAILS_BASE = "https://archive.org/details/";
14
+ // ============================================================================
15
+ // InternetArchiveSource
16
+ // ============================================================================
17
+ /**
18
+ * Research source backed by the Internet Archive advanced search API.
19
+ *
20
+ * Searches for books, documents, and media about a subject.
21
+ * Free, no API key required.
22
+ */
23
+ export class InternetArchiveSource extends BaseResearchSource {
24
+ name = "Internet Archive";
25
+ type = "internet-archive";
26
+ reliabilityTier = ReliabilityTier.ARCHIVE_MIRROR;
27
+ domain = "archive.org";
28
+ isFree = true;
29
+ estimatedCostPerQuery = 0;
30
+ constructor(options = {}) {
31
+ super({ rateLimitMs: 1000, ...options });
32
+ }
33
+ async fetchResult(subject, signal) {
34
+ const url = new URL(IA_API_URL);
35
+ url.searchParams.set("q", `"${subject.name}" AND (biography OR memoir)`);
36
+ url.searchParams.append("fl[]", "identifier");
37
+ url.searchParams.append("fl[]", "title");
38
+ url.searchParams.append("fl[]", "description");
39
+ url.searchParams.append("fl[]", "creator");
40
+ url.searchParams.append("sort[]", "downloads desc");
41
+ url.searchParams.set("rows", "5");
42
+ url.searchParams.set("output", "json");
43
+ const response = await fetch(url.toString(), { signal });
44
+ if (!response.ok) {
45
+ throw new Error(`Internet Archive API error: HTTP ${response.status} ${response.statusText}`);
46
+ }
47
+ const data = (await response.json());
48
+ if (!data.response?.docs?.length)
49
+ return null;
50
+ // Combine title + description from all docs
51
+ const parts = [];
52
+ for (const doc of data.response.docs) {
53
+ if (doc.title)
54
+ parts.push(doc.title);
55
+ if (doc.description)
56
+ parts.push(doc.description);
57
+ }
58
+ const text = parts.join("\n\n");
59
+ if (!text.trim())
60
+ return null;
61
+ const sanitized = sanitizeSourceText(text);
62
+ if (!sanitized)
63
+ return null;
64
+ const firstDoc = data.response.docs[0];
65
+ const resultUrl = firstDoc?.identifier ? `${IA_DETAILS_BASE}${firstDoc.identifier}` : undefined;
66
+ return {
67
+ text: sanitized,
68
+ confidence: -1,
69
+ costUsd: 0,
70
+ url: resultUrl,
71
+ publication: "Internet Archive",
72
+ metadata: {
73
+ title: firstDoc?.title ?? "",
74
+ },
75
+ };
76
+ }
77
+ }
78
+ // ============================================================================
79
+ // Factory
80
+ // ============================================================================
81
+ /**
82
+ * Create an Internet Archive source instance.
83
+ *
84
+ * @param options - Source options (rateLimitMs, etc.)
85
+ * @returns A configured InternetArchiveSource
86
+ */
87
+ export function internetArchive(options) {
88
+ return new InternetArchiveSource(options);
89
+ }
90
+ //# sourceMappingURL=internet-archive.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"internet-archive.js","sourceRoot":"","sources":["../../src/archives/internet-archive.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Trove (National Library of Australia) source.
3
+ *
4
+ * Queries the Trove API v3 for newspaper articles about a research subject.
5
+ * Requires a free API key from the National Library of Australia.
6
+ */
7
+ import { BaseResearchSource, ReliabilityTier, type BaseSourceOptions, type ResearchSubject, type RawFinding } from "@debriefer/core";
8
+ export interface TroveOptions extends BaseSourceOptions {
9
+ /** Trove API key. Defaults to process.env.TROVE_API_KEY. */
10
+ apiKey?: string;
11
+ }
12
+ /**
13
+ * Research source backed by the Trove API (National Library of Australia).
14
+ *
15
+ * Searches digitized Australian newspapers for biographical content
16
+ * about a subject. Requires a free API key.
17
+ */
18
+ export declare class TroveSource extends BaseResearchSource<ResearchSubject> {
19
+ readonly name = "Trove";
20
+ readonly type = "trove";
21
+ readonly reliabilityTier = ReliabilityTier.ARCHIVAL;
22
+ readonly domain = "api.trove.nla.gov.au";
23
+ readonly isFree = true;
24
+ readonly estimatedCostPerQuery = 0;
25
+ private apiKey;
26
+ constructor(options?: TroveOptions);
27
+ isAvailable(): boolean;
28
+ protected fetchResult(subject: ResearchSubject, signal: AbortSignal): Promise<RawFinding | null>;
29
+ }
30
+ /**
31
+ * Create a Trove source instance.
32
+ *
33
+ * @param options - Trove-specific options (apiKey, rateLimitMs, etc.)
34
+ * @returns A configured TroveSource
35
+ */
36
+ export declare function trove(options?: TroveOptions): TroveSource;
37
+ //# sourceMappingURL=trove.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trove.d.ts","sourceRoot":"","sources":["../../src/archives/trove.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,UAAU,EAChB,MAAM,iBAAiB,CAAA;AAaxB,MAAM,WAAW,YAAa,SAAQ,iBAAiB;IACrD,4DAA4D;IAC5D,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AA0BD;;;;;GAKG;AACH,qBAAa,WAAY,SAAQ,kBAAkB,CAAC,eAAe,CAAC;IAClE,QAAQ,CAAC,IAAI,WAAU;IACvB,QAAQ,CAAC,IAAI,WAAU;IACvB,QAAQ,CAAC,eAAe,4BAA2B;IACnD,QAAQ,CAAC,MAAM,0BAAyB;IACxC,QAAQ,CAAC,MAAM,QAAO;IACtB,QAAQ,CAAC,qBAAqB,KAAI;IAElC,OAAO,CAAC,MAAM,CAAoB;gBAEtB,OAAO,GAAE,YAAiB;IAK7B,WAAW,IAAI,OAAO;cAIf,WAAW,CACzB,OAAO,EAAE,eAAe,EACxB,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;CAmD9B;AAMD;;;;;GAKG;AACH,wBAAgB,KAAK,CAAC,OAAO,CAAC,EAAE,YAAY,GAAG,WAAW,CAEzD"}
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Trove (National Library of Australia) source.
3
+ *
4
+ * Queries the Trove API v3 for newspaper articles about a research subject.
5
+ * Requires a free API key from the National Library of Australia.
6
+ */
7
+ import { BaseResearchSource, ReliabilityTier, } from "@debriefer/core";
8
+ import { sanitizeSourceText } from "../shared/sanitize-text.js";
9
+ // ============================================================================
10
+ // Constants
11
+ // ============================================================================
12
+ const TROVE_API_URL = "https://api.trove.nla.gov.au/v3/result";
13
+ // ============================================================================
14
+ // TroveSource
15
+ // ============================================================================
16
+ /**
17
+ * Research source backed by the Trove API (National Library of Australia).
18
+ *
19
+ * Searches digitized Australian newspapers for biographical content
20
+ * about a subject. Requires a free API key.
21
+ */
22
+ export class TroveSource extends BaseResearchSource {
23
+ name = "Trove";
24
+ type = "trove";
25
+ reliabilityTier = ReliabilityTier.ARCHIVAL;
26
+ domain = "api.trove.nla.gov.au";
27
+ isFree = true;
28
+ estimatedCostPerQuery = 0;
29
+ apiKey;
30
+ constructor(options = {}) {
31
+ super({ rateLimitMs: 1000, ...options });
32
+ this.apiKey = options.apiKey ?? process.env.TROVE_API_KEY;
33
+ }
34
+ isAvailable() {
35
+ return Boolean(this.apiKey);
36
+ }
37
+ async fetchResult(subject, signal) {
38
+ if (!this.apiKey)
39
+ return null;
40
+ const url = new URL(TROVE_API_URL);
41
+ url.searchParams.set("key", this.apiKey);
42
+ url.searchParams.set("q", `"${subject.name}" biography`);
43
+ url.searchParams.set("category", "newspaper");
44
+ url.searchParams.set("encoding", "json");
45
+ url.searchParams.set("n", "5");
46
+ const response = await fetch(url.toString(), { signal });
47
+ if (!response.ok) {
48
+ throw new Error(`Trove API error: HTTP ${response.status} ${response.statusText}`);
49
+ }
50
+ const data = (await response.json());
51
+ const articles = data.category?.[0]?.records?.article;
52
+ if (!articles?.length)
53
+ return null;
54
+ // Combine heading + cleaned snippet from all articles
55
+ const parts = [];
56
+ for (const article of articles) {
57
+ if (article.heading)
58
+ parts.push(article.heading);
59
+ if (article.snippet) {
60
+ // Strip HTML tags from snippets
61
+ const cleaned = article.snippet.replace(/<[^>]+>/g, "");
62
+ if (cleaned.trim())
63
+ parts.push(cleaned);
64
+ }
65
+ }
66
+ const text = parts.join("\n\n");
67
+ if (!text.trim())
68
+ return null;
69
+ const sanitized = sanitizeSourceText(text);
70
+ if (!sanitized)
71
+ return null;
72
+ const firstWithUrl = articles.find((a) => a.troveUrl);
73
+ return {
74
+ text: sanitized,
75
+ confidence: -1,
76
+ costUsd: 0,
77
+ url: firstWithUrl?.troveUrl,
78
+ publication: "Trove (National Library of Australia)",
79
+ metadata: {
80
+ title: articles[0]?.heading ?? "",
81
+ },
82
+ };
83
+ }
84
+ }
85
+ // ============================================================================
86
+ // Factory
87
+ // ============================================================================
88
+ /**
89
+ * Create a Trove source instance.
90
+ *
91
+ * @param options - Trove-specific options (apiKey, rateLimitMs, etc.)
92
+ * @returns A configured TroveSource
93
+ */
94
+ export function trove(options) {
95
+ return new TroveSource(options);
96
+ }
97
+ //# sourceMappingURL=trove.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trove.js","sourceRoot":"","sources":["../../src/archives/trove.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Google Books API source.
3
+ *
4
+ * Searches Google Books for volumes matching the research subject,
5
+ * extracts text snippets and descriptions, and returns the best
6
+ * match as a finding.
7
+ *
8
+ * Requires a Google Books API key (https://developers.google.com/books).
9
+ */
10
+ import { BaseResearchSource, ReliabilityTier, type BaseSourceOptions, type ResearchSubject, type RawFinding } from "@debriefer/core";
11
+ export interface GoogleBooksOptions extends BaseSourceOptions {
12
+ /** Google Books API key. Defaults to process.env.GOOGLE_BOOKS_API_KEY. */
13
+ apiKey?: string;
14
+ }
15
+ /**
16
+ * Research source backed by the Google Books API.
17
+ *
18
+ * Searches for volumes about a subject, picks the first item with
19
+ * enough combined text (snippet + description), and returns the
20
+ * sanitized result.
21
+ */
22
+ export declare class GoogleBooksSource extends BaseResearchSource<ResearchSubject> {
23
+ readonly name = "Google Books";
24
+ readonly type = "google-books";
25
+ readonly reliabilityTier = ReliabilityTier.SECONDARY_COMPILATION;
26
+ readonly domain = "www.googleapis.com";
27
+ readonly isFree = true;
28
+ readonly estimatedCostPerQuery = 0;
29
+ private apiKey;
30
+ constructor(options?: GoogleBooksOptions);
31
+ isAvailable(): boolean;
32
+ protected fetchResult(subject: ResearchSubject, signal: AbortSignal): Promise<RawFinding | null>;
33
+ /**
34
+ * Extract and combine text from a Google Books volume.
35
+ *
36
+ * Combines the text snippet (with HTML tags stripped and entities decoded)
37
+ * and the description into a single string.
38
+ */
39
+ private extractText;
40
+ }
41
+ /**
42
+ * Create a Google Books API source instance.
43
+ *
44
+ * @param options - Google Books-specific options (apiKey, rateLimitMs, etc.)
45
+ * @returns A configured GoogleBooksSource
46
+ */
47
+ export declare function googleBooks(options?: GoogleBooksOptions): GoogleBooksSource;
48
+ //# sourceMappingURL=google-books.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"google-books.d.ts","sourceRoot":"","sources":["../../src/books/google-books.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,UAAU,EAChB,MAAM,iBAAiB,CAAA;AAcxB,MAAM,WAAW,kBAAmB,SAAQ,iBAAiB;IAC3D,0EAA0E;IAC1E,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AA0BD;;;;;;GAMG;AACH,qBAAa,iBAAkB,SAAQ,kBAAkB,CAAC,eAAe,CAAC;IACxE,QAAQ,CAAC,IAAI,kBAAiB;IAC9B,QAAQ,CAAC,IAAI,kBAAiB;IAC9B,QAAQ,CAAC,eAAe,yCAAwC;IAChE,QAAQ,CAAC,MAAM,wBAAuB;IACtC,QAAQ,CAAC,MAAM,QAAO;IACtB,QAAQ,CAAC,qBAAqB,KAAI;IAElC,OAAO,CAAC,MAAM,CAAoB;gBAEtB,OAAO,GAAE,kBAAuB;IAKnC,WAAW,IAAI,OAAO;cAIf,WAAW,CACzB,OAAO,EAAE,eAAe,EACxB,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IA6C7B;;;;;OAKG;IACH,OAAO,CAAC,WAAW;CAepB;AAMD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,OAAO,CAAC,EAAE,kBAAkB,GAAG,iBAAiB,CAE3E"}
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Google Books API source.
3
+ *
4
+ * Searches Google Books for volumes matching the research subject,
5
+ * extracts text snippets and descriptions, and returns the best
6
+ * match as a finding.
7
+ *
8
+ * Requires a Google Books API key (https://developers.google.com/books).
9
+ */
10
+ import { BaseResearchSource, ReliabilityTier, } from "@debriefer/core";
11
+ import { decodeHtmlEntities } from "../shared/html-utils.js";
12
+ import { sanitizeSourceText } from "../shared/sanitize-text.js";
13
+ // ============================================================================
14
+ // Constants
15
+ // ============================================================================
16
+ const GOOGLE_BOOKS_API_URL = "https://www.googleapis.com/books/v1/volumes";
17
+ // ============================================================================
18
+ // GoogleBooksSource
19
+ // ============================================================================
20
+ /**
21
+ * Research source backed by the Google Books API.
22
+ *
23
+ * Searches for volumes about a subject, picks the first item with
24
+ * enough combined text (snippet + description), and returns the
25
+ * sanitized result.
26
+ */
27
+ export class GoogleBooksSource extends BaseResearchSource {
28
+ name = "Google Books";
29
+ type = "google-books";
30
+ reliabilityTier = ReliabilityTier.SECONDARY_COMPILATION;
31
+ domain = "www.googleapis.com";
32
+ isFree = true;
33
+ estimatedCostPerQuery = 0;
34
+ apiKey;
35
+ constructor(options = {}) {
36
+ super({ rateLimitMs: 1000, ...options });
37
+ this.apiKey = options.apiKey ?? process.env.GOOGLE_BOOKS_API_KEY;
38
+ }
39
+ isAvailable() {
40
+ return Boolean(this.apiKey);
41
+ }
42
+ async fetchResult(subject, signal) {
43
+ if (!this.apiKey)
44
+ return null;
45
+ const query = `"${subject.name}" biography`;
46
+ const url = new URL(GOOGLE_BOOKS_API_URL);
47
+ url.searchParams.set("q", query);
48
+ url.searchParams.set("key", this.apiKey);
49
+ url.searchParams.set("maxResults", "5");
50
+ const response = await fetch(url.toString(), { signal });
51
+ if (!response.ok) {
52
+ throw new Error(`Google Books API error: HTTP ${response.status} ${response.statusText}`);
53
+ }
54
+ const data = (await response.json());
55
+ if (!data.items?.length)
56
+ return null;
57
+ // Pick first item with enough combined text
58
+ for (const item of data.items) {
59
+ const combined = this.extractText(item);
60
+ if (combined.length >= 100) {
61
+ const sanitized = sanitizeSourceText(combined);
62
+ if (sanitized.length < 50)
63
+ continue;
64
+ return {
65
+ text: sanitized,
66
+ confidence: -1,
67
+ costUsd: 0,
68
+ url: item.volumeInfo.infoLink,
69
+ publication: "Google Books",
70
+ metadata: {
71
+ title: item.volumeInfo.title,
72
+ authors: item.volumeInfo.authors,
73
+ publishedDate: item.volumeInfo.publishedDate,
74
+ },
75
+ };
76
+ }
77
+ }
78
+ return null;
79
+ }
80
+ /**
81
+ * Extract and combine text from a Google Books volume.
82
+ *
83
+ * Combines the text snippet (with HTML tags stripped and entities decoded)
84
+ * and the description into a single string.
85
+ */
86
+ extractText(item) {
87
+ const parts = [];
88
+ if (item.searchInfo?.textSnippet) {
89
+ // Strip <b> and other HTML tags, then decode entities
90
+ const stripped = item.searchInfo.textSnippet.replace(/<[^>]+>/g, "");
91
+ parts.push(decodeHtmlEntities(stripped));
92
+ }
93
+ if (item.volumeInfo.description) {
94
+ parts.push(item.volumeInfo.description);
95
+ }
96
+ return parts.join(" ").trim();
97
+ }
98
+ }
99
+ // ============================================================================
100
+ // Factory
101
+ // ============================================================================
102
+ /**
103
+ * Create a Google Books API source instance.
104
+ *
105
+ * @param options - Google Books-specific options (apiKey, rateLimitMs, etc.)
106
+ * @returns A configured GoogleBooksSource
107
+ */
108
+ export function googleBooks(options) {
109
+ return new GoogleBooksSource(options);
110
+ }
111
+ //# sourceMappingURL=google-books.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"google-books.js","sourceRoot":"","sources":["../../src/books/google-books.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Open Library search source.
3
+ *
4
+ * Queries the Open Library Search API for books matching the research
5
+ * subject. Returns book metadata (title, authors, publication year)
6
+ * as a finding. No API key required.
7
+ *
8
+ * https://openlibrary.org/dev/docs/api/search
9
+ */
10
+ import { BaseResearchSource, ReliabilityTier, type BaseSourceOptions, type ResearchSubject, type RawFinding } from "@debriefer/core";
11
+ export type OpenLibraryOptions = BaseSourceOptions;
12
+ /**
13
+ * Research source backed by the Open Library Search API.
14
+ *
15
+ * Searches for books about a subject, picks the first result with
16
+ * a title, and returns a combined attribution string (including any
17
+ * available authors and publication year) as the finding text.
18
+ */
19
+ export declare class OpenLibrarySource extends BaseResearchSource<ResearchSubject> {
20
+ readonly name = "Open Library";
21
+ readonly type = "open-library";
22
+ readonly reliabilityTier = ReliabilityTier.SECONDARY_COMPILATION;
23
+ readonly domain = "openlibrary.org";
24
+ readonly isFree = true;
25
+ readonly estimatedCostPerQuery = 0;
26
+ constructor(options?: OpenLibraryOptions);
27
+ isAvailable(): boolean;
28
+ protected fetchResult(subject: ResearchSubject, signal: AbortSignal): Promise<RawFinding | null>;
29
+ /**
30
+ * Build attribution text from an Open Library document.
31
+ *
32
+ * Combines title, author names, and publication year into a
33
+ * human-readable string.
34
+ */
35
+ private buildText;
36
+ }
37
+ /**
38
+ * Create an Open Library source instance.
39
+ *
40
+ * @param options - Open Library-specific options (rateLimitMs, etc.)
41
+ * @returns A configured OpenLibrarySource
42
+ */
43
+ export declare function openLibrary(options?: OpenLibraryOptions): OpenLibrarySource;
44
+ //# sourceMappingURL=open-library.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"open-library.d.ts","sourceRoot":"","sources":["../../src/books/open-library.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,UAAU,EAChB,MAAM,iBAAiB,CAAA;AAYxB,MAAM,MAAM,kBAAkB,GAAG,iBAAiB,CAAA;AAqBlD;;;;;;GAMG;AACH,qBAAa,iBAAkB,SAAQ,kBAAkB,CAAC,eAAe,CAAC;IACxE,QAAQ,CAAC,IAAI,kBAAiB;IAC9B,QAAQ,CAAC,IAAI,kBAAiB;IAC9B,QAAQ,CAAC,eAAe,yCAAwC;IAChE,QAAQ,CAAC,MAAM,qBAAoB;IACnC,QAAQ,CAAC,MAAM,QAAO;IACtB,QAAQ,CAAC,qBAAqB,KAAI;gBAEtB,OAAO,GAAE,kBAAuB;IAInC,WAAW,IAAI,OAAO;cAIf,WAAW,CACzB,OAAO,EAAE,eAAe,EACxB,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAwC7B;;;;;OAKG;IACH,OAAO,CAAC,SAAS;CAiBlB;AAMD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,OAAO,CAAC,EAAE,kBAAkB,GAAG,iBAAiB,CAE3E"}
@@ -0,0 +1,103 @@
1
+ /**
2
+ * Open Library search source.
3
+ *
4
+ * Queries the Open Library Search API for books matching the research
5
+ * subject. Returns book metadata (title, authors, publication year)
6
+ * as a finding. No API key required.
7
+ *
8
+ * https://openlibrary.org/dev/docs/api/search
9
+ */
10
+ import { BaseResearchSource, ReliabilityTier, } from "@debriefer/core";
11
+ // ============================================================================
12
+ // Constants
13
+ // ============================================================================
14
+ const OPEN_LIBRARY_SEARCH_URL = "https://openlibrary.org/search.json";
15
+ // ============================================================================
16
+ // OpenLibrarySource
17
+ // ============================================================================
18
+ /**
19
+ * Research source backed by the Open Library Search API.
20
+ *
21
+ * Searches for books about a subject, picks the first result with
22
+ * a title, and returns a combined attribution string (including any
23
+ * available authors and publication year) as the finding text.
24
+ */
25
+ export class OpenLibrarySource extends BaseResearchSource {
26
+ name = "Open Library";
27
+ type = "open-library";
28
+ reliabilityTier = ReliabilityTier.SECONDARY_COMPILATION;
29
+ domain = "openlibrary.org";
30
+ isFree = true;
31
+ estimatedCostPerQuery = 0;
32
+ constructor(options = {}) {
33
+ super({ rateLimitMs: 350, ...options });
34
+ }
35
+ isAvailable() {
36
+ return true;
37
+ }
38
+ async fetchResult(subject, signal) {
39
+ const query = `"${subject.name}" biography`;
40
+ const url = new URL(OPEN_LIBRARY_SEARCH_URL);
41
+ url.searchParams.set("q", query);
42
+ url.searchParams.set("limit", "5");
43
+ const response = await fetch(url.toString(), { signal });
44
+ if (!response.ok) {
45
+ throw new Error(`Open Library API error: HTTP ${response.status} ${response.statusText}`);
46
+ }
47
+ const data = (await response.json());
48
+ if (!data.docs?.length)
49
+ return null;
50
+ // Pick the first doc with a title
51
+ const doc = data.docs.find((d) => d.title);
52
+ if (!doc)
53
+ return null;
54
+ const text = this.buildText(doc);
55
+ if (!text)
56
+ return null;
57
+ const docUrl = doc.key ? `https://openlibrary.org${doc.key}` : undefined;
58
+ return {
59
+ text,
60
+ confidence: -1,
61
+ costUsd: 0,
62
+ url: docUrl,
63
+ publication: "Open Library",
64
+ metadata: {
65
+ title: doc.title,
66
+ authors: doc.author_name,
67
+ firstPublishYear: doc.first_publish_year,
68
+ },
69
+ };
70
+ }
71
+ /**
72
+ * Build attribution text from an Open Library document.
73
+ *
74
+ * Combines title, author names, and publication year into a
75
+ * human-readable string.
76
+ */
77
+ buildText(doc) {
78
+ const parts = [];
79
+ if (doc.title) {
80
+ parts.push(doc.title);
81
+ }
82
+ if (doc.author_name?.length) {
83
+ parts.push(`by ${doc.author_name.join(", ")}`);
84
+ }
85
+ if (doc.first_publish_year) {
86
+ parts.push(`(${doc.first_publish_year})`);
87
+ }
88
+ return parts.length > 0 ? parts.join(" ") : null;
89
+ }
90
+ }
91
+ // ============================================================================
92
+ // Factory
93
+ // ============================================================================
94
+ /**
95
+ * Create an Open Library source instance.
96
+ *
97
+ * @param options - Open Library-specific options (rateLimitMs, etc.)
98
+ * @returns A configured OpenLibrarySource
99
+ */
100
+ export function openLibrary(options) {
101
+ return new OpenLibrarySource(options);
102
+ }
103
+ //# sourceMappingURL=open-library.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"open-library.js","sourceRoot":"","sources":["../../src/books/open-library.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EACL,kBAAkB,EAClB,eAAe,GAIhB,MAAM,iBAAiB,CAAA;AAExB,+EAA+E;AAC/E,YAAY;AACZ,+EAA+E;AAE/E,MAAM,uBAAuB,GAAG,qCAAqC,CAAA;AAuBrE,+EAA+E;AAC/E,oBAAoB;AACpB,+EAA+E;AAE/E;;;;;;GAMG;AACH,MAAM,OAAO,iBAAkB,SAAQ,kBAAmC;IAC/D,IAAI,GAAG,cAAc,CAAA;IACrB,IAAI,GAAG,cAAc,CAAA;IACrB,eAAe,GAAG,eAAe,CAAC,qBAAqB,CAAA;IACvD,MAAM,GAAG,iBAAiB,CAAA;IAC1B,MAAM,GAAG,IAAI,CAAA;IACb,qBAAqB,GAAG,CAAC,CAAA;IAElC,YAAY,UAA8B,EAAE;QAC1C,KAAK,CAAC,EAAE,WAAW,EAAE,GAAG,EAAE,GAAG,OAAO,EAAE,CAAC,CAAA;IACzC,CAAC;IAEQ,WAAW;QAClB,OAAO,IAAI,CAAA;IACb,CAAC;IAES,KAAK,CAAC,WAAW,CACzB,OAAwB,EACxB,MAAmB;QAEnB,MAAM,KAAK,GAAG,IAAI,OAAO,CAAC,IAAI,aAAa,CAAA;QAE3C,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,uBAAuB,CAAC,CAAA;QAC5C,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAA;QAChC,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,CAAA;QAElC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAA;QAExD,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,KAAK,CAAC,gCAAgC,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAA;QAC3F,CAAC;QAED,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAA8B,CAAA;QAEjE,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM;YAAE,OAAO,IAAI,CAAA;QAEnC,kCAAkC;QAClC,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAA;QAC1C,IAAI,CAAC,GAAG;YAAE,OAAO,IAAI,CAAA;QAErB,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;QAChC,IAAI,CAAC,IAAI;YAAE,OAAO,IAAI,CAAA;QAEtB,MAAM,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,0BAA0B,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,SAAS,CAAA;QAExE,OAAO;YACL,IAAI;YACJ,UAAU,EAAE,CAAC,CAAC;YACd,OAAO,EAAE,CAAC;YACV,GAAG,EAAE,MAAM;YACX,WAAW,EAAE,cAAc;YAC3B,QAAQ,EAAE;gBACR,KAAK,EAAE,GAAG,CAAC,KAAK;gBAChB,OAAO,EAAE,GAAG,CAAC,WAAW;gBACxB,gBAAgB,EAAE,GAAG,CAAC,kBAAkB;aACzC;SACF,CAAA;IACH,CAAC;IAED;;;;;OAKG;IACK,SAAS,CAAC,GAAmB;QACnC,MAAM,KAAK,GAAa,EAAE,CAAA;QAE1B,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;YACd,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;QACvB,CAAC;QAED,IAAI,GAAG,CAAC,WAAW,EAAE,MAAM,EAAE,CAAC;YAC5B,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QAChD,CAAC;QAED,IAAI,GAAG,CAAC,kBAAkB,EAAE,CAAC;YAC3B,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,kBAAkB,GAAG,CAAC,CAAA;QAC3C,CAAC;QAED,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;IAClD,CAAC;CACF;AAED,+EAA+E;AAC/E,UAAU;AACV,+EAA+E;AAE/E;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,OAA4B;IACtD,OAAO,IAAI,iBAAiB,CAAC,OAAO,CAAC,CAAA;AACvC,CAAC"}