rehydra 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 (155) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +615 -0
  3. package/dist/crypto/index.d.ts +6 -0
  4. package/dist/crypto/index.d.ts.map +1 -0
  5. package/dist/crypto/index.js +6 -0
  6. package/dist/crypto/index.js.map +1 -0
  7. package/dist/crypto/pii-map-crypto.d.ts +114 -0
  8. package/dist/crypto/pii-map-crypto.d.ts.map +1 -0
  9. package/dist/crypto/pii-map-crypto.js +228 -0
  10. package/dist/crypto/pii-map-crypto.js.map +1 -0
  11. package/dist/index.d.ts +180 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +384 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/ner/bio-decoder.d.ts +64 -0
  16. package/dist/ner/bio-decoder.d.ts.map +1 -0
  17. package/dist/ner/bio-decoder.js +216 -0
  18. package/dist/ner/bio-decoder.js.map +1 -0
  19. package/dist/ner/index.d.ts +10 -0
  20. package/dist/ner/index.d.ts.map +1 -0
  21. package/dist/ner/index.js +10 -0
  22. package/dist/ner/index.js.map +1 -0
  23. package/dist/ner/model-manager.d.ts +111 -0
  24. package/dist/ner/model-manager.d.ts.map +1 -0
  25. package/dist/ner/model-manager.js +325 -0
  26. package/dist/ner/model-manager.js.map +1 -0
  27. package/dist/ner/ner-model.d.ts +114 -0
  28. package/dist/ner/ner-model.d.ts.map +1 -0
  29. package/dist/ner/ner-model.js +253 -0
  30. package/dist/ner/ner-model.js.map +1 -0
  31. package/dist/ner/onnx-runtime.d.ts +46 -0
  32. package/dist/ner/onnx-runtime.d.ts.map +1 -0
  33. package/dist/ner/onnx-runtime.js +130 -0
  34. package/dist/ner/onnx-runtime.js.map +1 -0
  35. package/dist/ner/tokenizer.d.ts +118 -0
  36. package/dist/ner/tokenizer.d.ts.map +1 -0
  37. package/dist/ner/tokenizer.js +332 -0
  38. package/dist/ner/tokenizer.js.map +1 -0
  39. package/dist/pipeline/index.d.ts +12 -0
  40. package/dist/pipeline/index.d.ts.map +1 -0
  41. package/dist/pipeline/index.js +12 -0
  42. package/dist/pipeline/index.js.map +1 -0
  43. package/dist/pipeline/prenormalize.d.ts +48 -0
  44. package/dist/pipeline/prenormalize.d.ts.map +1 -0
  45. package/dist/pipeline/prenormalize.js +94 -0
  46. package/dist/pipeline/prenormalize.js.map +1 -0
  47. package/dist/pipeline/resolver.d.ts +56 -0
  48. package/dist/pipeline/resolver.d.ts.map +1 -0
  49. package/dist/pipeline/resolver.js +239 -0
  50. package/dist/pipeline/resolver.js.map +1 -0
  51. package/dist/pipeline/semantic-data-loader.d.ts +165 -0
  52. package/dist/pipeline/semantic-data-loader.d.ts.map +1 -0
  53. package/dist/pipeline/semantic-data-loader.js +655 -0
  54. package/dist/pipeline/semantic-data-loader.js.map +1 -0
  55. package/dist/pipeline/semantic-enricher.d.ts +112 -0
  56. package/dist/pipeline/semantic-enricher.d.ts.map +1 -0
  57. package/dist/pipeline/semantic-enricher.js +318 -0
  58. package/dist/pipeline/semantic-enricher.js.map +1 -0
  59. package/dist/pipeline/tagger.d.ts +114 -0
  60. package/dist/pipeline/tagger.d.ts.map +1 -0
  61. package/dist/pipeline/tagger.js +374 -0
  62. package/dist/pipeline/tagger.js.map +1 -0
  63. package/dist/pipeline/title-extractor.d.ts +79 -0
  64. package/dist/pipeline/title-extractor.d.ts.map +1 -0
  65. package/dist/pipeline/title-extractor.js +801 -0
  66. package/dist/pipeline/title-extractor.js.map +1 -0
  67. package/dist/pipeline/validator.d.ts +65 -0
  68. package/dist/pipeline/validator.d.ts.map +1 -0
  69. package/dist/pipeline/validator.js +264 -0
  70. package/dist/pipeline/validator.js.map +1 -0
  71. package/dist/recognizers/base.d.ts +78 -0
  72. package/dist/recognizers/base.d.ts.map +1 -0
  73. package/dist/recognizers/base.js +100 -0
  74. package/dist/recognizers/base.js.map +1 -0
  75. package/dist/recognizers/bic-swift.d.ts +10 -0
  76. package/dist/recognizers/bic-swift.d.ts.map +1 -0
  77. package/dist/recognizers/bic-swift.js +107 -0
  78. package/dist/recognizers/bic-swift.js.map +1 -0
  79. package/dist/recognizers/credit-card.d.ts +32 -0
  80. package/dist/recognizers/credit-card.d.ts.map +1 -0
  81. package/dist/recognizers/credit-card.js +160 -0
  82. package/dist/recognizers/credit-card.js.map +1 -0
  83. package/dist/recognizers/custom-id.d.ts +28 -0
  84. package/dist/recognizers/custom-id.d.ts.map +1 -0
  85. package/dist/recognizers/custom-id.js +116 -0
  86. package/dist/recognizers/custom-id.js.map +1 -0
  87. package/dist/recognizers/email.d.ts +10 -0
  88. package/dist/recognizers/email.d.ts.map +1 -0
  89. package/dist/recognizers/email.js +75 -0
  90. package/dist/recognizers/email.js.map +1 -0
  91. package/dist/recognizers/iban.d.ts +14 -0
  92. package/dist/recognizers/iban.d.ts.map +1 -0
  93. package/dist/recognizers/iban.js +67 -0
  94. package/dist/recognizers/iban.js.map +1 -0
  95. package/dist/recognizers/index.d.ts +20 -0
  96. package/dist/recognizers/index.d.ts.map +1 -0
  97. package/dist/recognizers/index.js +42 -0
  98. package/dist/recognizers/index.js.map +1 -0
  99. package/dist/recognizers/ip-address.d.ts +14 -0
  100. package/dist/recognizers/ip-address.d.ts.map +1 -0
  101. package/dist/recognizers/ip-address.js +183 -0
  102. package/dist/recognizers/ip-address.js.map +1 -0
  103. package/dist/recognizers/phone.d.ts +10 -0
  104. package/dist/recognizers/phone.d.ts.map +1 -0
  105. package/dist/recognizers/phone.js +145 -0
  106. package/dist/recognizers/phone.js.map +1 -0
  107. package/dist/recognizers/registry.d.ts +59 -0
  108. package/dist/recognizers/registry.d.ts.map +1 -0
  109. package/dist/recognizers/registry.js +113 -0
  110. package/dist/recognizers/registry.js.map +1 -0
  111. package/dist/recognizers/url.d.ts +14 -0
  112. package/dist/recognizers/url.d.ts.map +1 -0
  113. package/dist/recognizers/url.js +121 -0
  114. package/dist/recognizers/url.js.map +1 -0
  115. package/dist/types/index.d.ts +197 -0
  116. package/dist/types/index.d.ts.map +1 -0
  117. package/dist/types/index.js +80 -0
  118. package/dist/types/index.js.map +1 -0
  119. package/dist/types/pii-types.d.ts +50 -0
  120. package/dist/types/pii-types.d.ts.map +1 -0
  121. package/dist/types/pii-types.js +114 -0
  122. package/dist/types/pii-types.js.map +1 -0
  123. package/dist/utils/iban-checksum.d.ts +23 -0
  124. package/dist/utils/iban-checksum.d.ts.map +1 -0
  125. package/dist/utils/iban-checksum.js +106 -0
  126. package/dist/utils/iban-checksum.js.map +1 -0
  127. package/dist/utils/index.d.ts +10 -0
  128. package/dist/utils/index.d.ts.map +1 -0
  129. package/dist/utils/index.js +10 -0
  130. package/dist/utils/index.js.map +1 -0
  131. package/dist/utils/luhn.d.ts +17 -0
  132. package/dist/utils/luhn.d.ts.map +1 -0
  133. package/dist/utils/luhn.js +55 -0
  134. package/dist/utils/luhn.js.map +1 -0
  135. package/dist/utils/offsets.d.ts +86 -0
  136. package/dist/utils/offsets.d.ts.map +1 -0
  137. package/dist/utils/offsets.js +124 -0
  138. package/dist/utils/offsets.js.map +1 -0
  139. package/dist/utils/path.d.ts +34 -0
  140. package/dist/utils/path.d.ts.map +1 -0
  141. package/dist/utils/path.js +96 -0
  142. package/dist/utils/path.js.map +1 -0
  143. package/dist/utils/storage-browser.d.ts +51 -0
  144. package/dist/utils/storage-browser.d.ts.map +1 -0
  145. package/dist/utils/storage-browser.js +381 -0
  146. package/dist/utils/storage-browser.js.map +1 -0
  147. package/dist/utils/storage-node.d.ts +43 -0
  148. package/dist/utils/storage-node.d.ts.map +1 -0
  149. package/dist/utils/storage-node.js +93 -0
  150. package/dist/utils/storage-node.js.map +1 -0
  151. package/dist/utils/storage.d.ts +70 -0
  152. package/dist/utils/storage.d.ts.map +1 -0
  153. package/dist/utils/storage.js +69 -0
  154. package/dist/utils/storage.js.map +1 -0
  155. package/package.json +66 -0
@@ -0,0 +1,655 @@
1
+ /**
2
+ * Semantic Data Loader
3
+ * Handles automatic downloading, caching, and parsing of semantic enrichment data.
4
+ * Browser-compatible using storage abstraction layer
5
+ *
6
+ * Data sources:
7
+ * - nam_dict.txt: Name-gender mappings from gender-guesser (~40K names)
8
+ * - cities15000.txt: GeoNames cities with population > 15,000 (~25K cities)
9
+ * - countryInfo.txt: Country names and codes (~250 countries)
10
+ * - admin1CodesASCII.txt: First-level admin divisions (~4K regions)
11
+ *
12
+ * Data is cached using the storage abstraction layer:
13
+ * - Node.js: Platform-specific cache directories
14
+ * - Browser: IndexedDB
15
+ */
16
+ import { getStorageProvider } from "../utils/storage.js";
17
+ import { join, basename } from "../utils/path.js";
18
+ /**
19
+ * Gender code mappings from nam_dict.txt format
20
+ */
21
+ const GENDER_CODE_MAP = {
22
+ M: "male",
23
+ "1M": "male",
24
+ "?M": "male", // mostly male
25
+ F: "female",
26
+ "1F": "female",
27
+ "?F": "female", // mostly female
28
+ "?": "neutral", // unisex
29
+ };
30
+ /**
31
+ * Country column positions in nam_dict.txt (0-indexed from column 30)
32
+ * These correspond to the frequency values for each country
33
+ */
34
+ const COUNTRY_COLUMNS = {
35
+ gb: 0, // Great Britain
36
+ ie: 1, // Ireland
37
+ us: 2, // USA
38
+ it: 3, // Italy
39
+ mt: 4, // Malta
40
+ pt: 5, // Portugal
41
+ es: 6, // Spain
42
+ fr: 7, // France
43
+ be: 8, // Belgium
44
+ lu: 9, // Luxembourg
45
+ nl: 10, // Netherlands
46
+ de: 11, // Germany (East Frisia at 10, Germany at 11)
47
+ at: 12, // Austria
48
+ ch: 13, // Swiss
49
+ is: 14, // Iceland
50
+ dk: 15, // Denmark
51
+ no: 16, // Norway
52
+ se: 17, // Sweden
53
+ fi: 18, // Finland
54
+ ee: 19, // Estonia
55
+ lv: 20, // Latvia
56
+ lt: 21, // Lithuania
57
+ pl: 22, // Poland
58
+ cz: 23, // Czech Republic
59
+ sk: 24, // Slovakia
60
+ hu: 25, // Hungary
61
+ ro: 26, // Romania
62
+ bg: 27, // Bulgaria
63
+ hr: 28, // Croatia (Bosnian)
64
+ si: 29, // Slovenia
65
+ rs: 30, // Serbia (Albanian)
66
+ mk: 31, // Macedonia
67
+ gr: 32, // Greece
68
+ ru: 33, // Russia
69
+ by: 34, // Belarus
70
+ md: 35, // Moldova
71
+ ua: 36, // Ukraine
72
+ am: 37, // Armenia
73
+ az: 38, // Azerbaijan
74
+ ge: 39, // Georgia
75
+ kz: 40, // Kazakhstan/Uzbekistan
76
+ tr: 41, // Turkey
77
+ sa: 42, // Arabia/Persia
78
+ il: 43, // Israel
79
+ cn: 44, // China
80
+ in: 45, // India/Sri Lanka
81
+ jp: 46, // Japan
82
+ kr: 47, // Korea
83
+ vn: 48, // Vietnam
84
+ };
85
+ // Keep COUNTRY_COLUMNS for future locale-specific gender lookups
86
+ void COUNTRY_COLUMNS;
87
+ // Global data store (lazily loaded)
88
+ let semanticData = null;
89
+ // Cached storage provider
90
+ let storageProvider = null;
91
+ /**
92
+ * Gets the storage provider (lazily initialized)
93
+ */
94
+ async function getStorage() {
95
+ if (storageProvider === null) {
96
+ storageProvider = await getStorageProvider();
97
+ }
98
+ return storageProvider;
99
+ }
100
+ // =============================================================================
101
+ // Cache Directory Management
102
+ // =============================================================================
103
+ /**
104
+ * Gets the cache directory for semantic data
105
+ * Uses platform-specific cache location (or virtual path in browser)
106
+ */
107
+ export async function getSemanticDataCacheDir() {
108
+ const storage = await getStorage();
109
+ return storage.getCacheDir("semantic-data");
110
+ }
111
+ /**
112
+ * Gets the path to the data directory (alias for backwards compatibility)
113
+ */
114
+ export async function getDataDirectory() {
115
+ return getSemanticDataCacheDir();
116
+ }
117
+ /**
118
+ * Base URL for semantic data files hosted on Hugging Face
119
+ */
120
+ const HUGGINGFACE_BASE_URL = "https://huggingface.co/datasets/tjruesch/rehydra-semantic/resolve/main";
121
+ /**
122
+ * Registry of semantic data files and their download URLs
123
+ */
124
+ export const SEMANTIC_DATA_FILES = [
125
+ {
126
+ filename: "nam_dict.txt",
127
+ url: `${HUGGINGFACE_BASE_URL}/nam_dict.txt`,
128
+ required: true,
129
+ description: "Name-gender mappings (~40K names)",
130
+ size: "~4.3 MB",
131
+ },
132
+ {
133
+ filename: "cities15000.txt",
134
+ url: `${HUGGINGFACE_BASE_URL}/cities15000.txt`,
135
+ required: true,
136
+ description: "GeoNames cities with population > 15,000",
137
+ size: "~7.8 MB",
138
+ },
139
+ {
140
+ filename: "countryInfo.txt",
141
+ url: `${HUGGINGFACE_BASE_URL}/countryInfo.txt`,
142
+ required: true,
143
+ description: "Country names and codes",
144
+ size: "~31 KB",
145
+ },
146
+ {
147
+ filename: "admin1CodesASCII.txt",
148
+ url: `${HUGGINGFACE_BASE_URL}/admin1CodesASCII.txt`,
149
+ required: false,
150
+ description: "First-level admin divisions (states/regions)",
151
+ size: "~146 KB",
152
+ },
153
+ ];
154
+ /**
155
+ * Checks if semantic data is already downloaded
156
+ */
157
+ export async function isSemanticDataDownloaded() {
158
+ const storage = await getStorage();
159
+ const dataDir = await getSemanticDataCacheDir();
160
+ try {
161
+ // Check all required files
162
+ for (const file of SEMANTIC_DATA_FILES) {
163
+ if (file.required) {
164
+ const exists = await storage.exists(join(dataDir, file.filename));
165
+ if (!exists)
166
+ return false;
167
+ }
168
+ }
169
+ return true;
170
+ }
171
+ catch {
172
+ return false;
173
+ }
174
+ }
175
+ /**
176
+ * Checks if the semantic data files are available
177
+ * Note: This is now async to work with browser storage
178
+ */
179
+ export async function isSemanticDataAvailable() {
180
+ return isSemanticDataDownloaded();
181
+ }
182
+ /**
183
+ * Downloads a file from URL and returns the data
184
+ */
185
+ async function downloadFileData(url, fileName, onProgress) {
186
+ const response = await fetch(url, {
187
+ headers: {
188
+ "User-Agent": "rehydra/1.0.0",
189
+ },
190
+ });
191
+ if (!response.ok) {
192
+ if (response.status === 404) {
193
+ throw new Error(`File not found: ${url}`);
194
+ }
195
+ throw new Error(`Failed to download ${url}: ${response.status} ${response.statusText}`);
196
+ }
197
+ const totalBytes = response.headers.get("content-length");
198
+ const total = totalBytes !== null && totalBytes !== "" ? parseInt(totalBytes, 10) : null;
199
+ const reader = response.body?.getReader();
200
+ if (reader === undefined) {
201
+ throw new Error("Response body is not readable");
202
+ }
203
+ const chunks = [];
204
+ let bytesDownloaded = 0;
205
+ // eslint-disable-next-line no-constant-condition
206
+ while (true) {
207
+ const result = await reader.read();
208
+ if (result.done)
209
+ break;
210
+ const value = result.value;
211
+ chunks.push(value);
212
+ bytesDownloaded += value.length;
213
+ if (onProgress) {
214
+ onProgress({
215
+ file: fileName,
216
+ bytesDownloaded,
217
+ totalBytes: total,
218
+ percent: total !== null && total > 0
219
+ ? Math.round((bytesDownloaded / total) * 100)
220
+ : null,
221
+ });
222
+ }
223
+ }
224
+ // Concatenate all chunks
225
+ const totalLength = chunks.reduce((acc, chunk) => acc + chunk.length, 0);
226
+ const result = new Uint8Array(totalLength);
227
+ let offset = 0;
228
+ for (const chunk of chunks) {
229
+ result.set(chunk, offset);
230
+ offset += chunk.length;
231
+ }
232
+ return result;
233
+ }
234
+ /**
235
+ * Downloads a file from URL to storage
236
+ */
237
+ async function downloadFile(url, destPath, onProgress) {
238
+ const storage = await getStorage();
239
+ const fileName = basename(destPath);
240
+ const data = await downloadFileData(url, fileName, onProgress);
241
+ await storage.writeFile(destPath, data);
242
+ }
243
+ /**
244
+ * Downloads all semantic data files
245
+ */
246
+ export async function downloadSemanticData(onProgress, onStatus) {
247
+ const storage = await getStorage();
248
+ const dataDir = await getSemanticDataCacheDir();
249
+ // Create directory
250
+ await storage.mkdir(dataDir);
251
+ onStatus?.("Downloading semantic enrichment data...");
252
+ onStatus?.(`Cache directory: ${dataDir}`);
253
+ for (const file of SEMANTIC_DATA_FILES) {
254
+ const destPath = join(dataDir, file.filename);
255
+ onStatus?.(`Downloading ${file.description}...`);
256
+ try {
257
+ await downloadFile(file.url, destPath, onProgress);
258
+ }
259
+ catch (e) {
260
+ if (file.required) {
261
+ throw new Error(`Failed to download required file ${file.filename}: ${String(e)}`);
262
+ }
263
+ // Optional files can fail silently
264
+ onStatus?.(`Skipping optional file ${file.filename}`);
265
+ }
266
+ }
267
+ onStatus?.("Semantic data download complete!");
268
+ return dataDir;
269
+ }
270
+ /**
271
+ * Ensures semantic data is available, downloading if needed
272
+ */
273
+ export async function ensureSemanticData(options = {}) {
274
+ const { autoDownload = true, onProgress, onStatus } = options;
275
+ const dataDir = await getSemanticDataCacheDir();
276
+ // Check if already downloaded
277
+ const isDownloaded = await isSemanticDataDownloaded();
278
+ if (!isDownloaded) {
279
+ if (!autoDownload) {
280
+ throw new Error(`Semantic data not found at ${dataDir}.\n\n` +
281
+ `To download automatically, use:\n` +
282
+ ` createAnonymizer({ semantic: { enabled: true, autoDownload: true } })\n\n` +
283
+ `Or disable semantic masking:\n` +
284
+ ` createAnonymizer({ semantic: { enabled: false } })`);
285
+ }
286
+ await downloadSemanticData(onProgress, onStatus);
287
+ }
288
+ else {
289
+ onStatus?.(`Using cached semantic data: ${dataDir}`);
290
+ }
291
+ return dataDir;
292
+ }
293
+ /**
294
+ * Clears cached semantic data
295
+ */
296
+ export async function clearSemanticDataCache() {
297
+ const storage = await getStorage();
298
+ const dataDir = await getSemanticDataCacheDir();
299
+ await storage.rm(dataDir, { recursive: true, force: true });
300
+ // Also clear in-memory data
301
+ clearSemanticData();
302
+ }
303
+ /**
304
+ * Gets info about semantic data files
305
+ */
306
+ export async function getSemanticDataInfo() {
307
+ const cacheDir = await getSemanticDataCacheDir();
308
+ return {
309
+ files: SEMANTIC_DATA_FILES,
310
+ cacheDir,
311
+ totalSize: "~4 MB",
312
+ };
313
+ }
314
+ // =============================================================================
315
+ // Data Parsing Functions
316
+ // =============================================================================
317
+ /**
318
+ * Parses nam_dict.txt content and extracts name-gender mappings
319
+ */
320
+ function parseNameDictContent(content) {
321
+ const names = new Map();
322
+ const lines = content.split("\n");
323
+ for (const line of lines) {
324
+ // Skip comments and empty lines
325
+ if (line.startsWith("#") || line.trim() === "")
326
+ continue;
327
+ // Skip lines with '+' in column 30 (expanded umlauts duplicates)
328
+ if (line.length > 29 && line[29] === "+")
329
+ continue;
330
+ // Parse gender code and name
331
+ // Format: <gender_code> <name> <spaces> <frequencies>
332
+ const match = line.match(/^(\?[MF]?|1[MF]|[MF])\s+(\S+)/);
333
+ if (!match)
334
+ continue;
335
+ const [, genderCode, name] = match;
336
+ if (genderCode === undefined ||
337
+ genderCode === "" ||
338
+ name === undefined ||
339
+ name === "")
340
+ continue;
341
+ const gender = GENDER_CODE_MAP[genderCode];
342
+ if (gender === undefined)
343
+ continue;
344
+ const normalizedName = name.toLowerCase();
345
+ // Check for locale-specific gender by looking at frequency columns
346
+ // If a name has frequency in certain countries but different gender elsewhere,
347
+ // we store locale overrides
348
+ const localeOverrides = {};
349
+ // For simplicity, we'll detect common locale-specific patterns
350
+ // The full implementation would parse frequency columns
351
+ // Store the entry
352
+ if (!names.has(normalizedName)) {
353
+ names.set(normalizedName, {
354
+ gender,
355
+ localeOverrides: Object.keys(localeOverrides).length > 0 ? localeOverrides : undefined,
356
+ });
357
+ }
358
+ else {
359
+ // If we see a name again with different gender, mark as locale-specific or neutral
360
+ const existing = names.get(normalizedName);
361
+ if (existing.gender !== gender) {
362
+ // Create locale overrides for the different gender
363
+ if (!existing.localeOverrides) {
364
+ existing.localeOverrides = {};
365
+ }
366
+ // This is a simplification - full implementation would use frequency data
367
+ }
368
+ }
369
+ }
370
+ return names;
371
+ }
372
+ /**
373
+ * Parses cities15000.txt content and extracts city data
374
+ * When multiple cities have the same name, keeps the one with highest population
375
+ */
376
+ function parseCitiesContent(content) {
377
+ const cities = new Map();
378
+ const lines = content.split("\n");
379
+ // Helper to add city only if population is higher than existing
380
+ const addCity = (name, entry) => {
381
+ const normalized = name.toLowerCase();
382
+ const existing = cities.get(normalized);
383
+ if (!existing || entry.population > existing.population) {
384
+ cities.set(normalized, entry);
385
+ }
386
+ };
387
+ for (const line of lines) {
388
+ if (line.trim() === "")
389
+ continue;
390
+ const parts = line.split("\t");
391
+ if (parts.length < 15)
392
+ continue;
393
+ const name = parts[1];
394
+ const asciiName = parts[2];
395
+ const alternateNames = parts[3]?.split(",") ?? [];
396
+ const countryCode = parts[8];
397
+ const population = parseInt(parts[14] ?? "0", 10);
398
+ if (name === undefined ||
399
+ name === "" ||
400
+ countryCode === undefined ||
401
+ countryCode === "")
402
+ continue;
403
+ const cityEntry = { country: countryCode, population };
404
+ // Add main name (prefer higher population)
405
+ addCity(name, cityEntry);
406
+ // Add ASCII name if different (prefer higher population)
407
+ if (asciiName !== undefined &&
408
+ asciiName !== "" &&
409
+ asciiName.toLowerCase() !== name.toLowerCase()) {
410
+ addCity(asciiName, cityEntry);
411
+ }
412
+ // Add alternate names (prefer higher population)
413
+ for (const altName of alternateNames) {
414
+ const trimmed = altName.trim();
415
+ if (trimmed && trimmed.length > 2 && !trimmed.includes(",")) {
416
+ addCity(trimmed, cityEntry);
417
+ }
418
+ }
419
+ }
420
+ return cities;
421
+ }
422
+ /**
423
+ * Generates common country name variations
424
+ */
425
+ function getCountryVariations(name, code) {
426
+ const variations = [code.toLowerCase()];
427
+ // Common abbreviations and variants
428
+ const variantMap = {
429
+ "United States": ["USA", "US", "America", "United States of America"],
430
+ "United Kingdom": ["UK", "Britain", "Great Britain", "England"],
431
+ Germany: ["Deutschland"],
432
+ France: ["Frankreich"],
433
+ Spain: ["España", "Espana", "Spanien"],
434
+ Italy: ["Italia", "Italien"],
435
+ Netherlands: ["Holland", "The Netherlands", "Niederlande"],
436
+ Switzerland: ["Schweiz", "Suisse", "Svizzera"],
437
+ Austria: ["Österreich", "Oesterreich"],
438
+ Belgium: ["Belgien", "Belgique"],
439
+ Russia: ["Russland", "Russian Federation"],
440
+ China: ["People's Republic of China", "PRC"],
441
+ Japan: ["Nippon"],
442
+ "South Korea": ["Korea", "Republic of Korea"],
443
+ "United Arab Emirates": ["UAE", "Emirates"],
444
+ "Czech Republic": ["Czechia", "Tschechien"],
445
+ };
446
+ if (variantMap[name]) {
447
+ variations.push(...variantMap[name]);
448
+ }
449
+ return variations;
450
+ }
451
+ /**
452
+ * Parses countryInfo.txt content and extracts country data
453
+ */
454
+ function parseCountriesContent(content) {
455
+ const countries = new Map();
456
+ const lines = content.split("\n");
457
+ for (const line of lines) {
458
+ // Skip comments and empty lines
459
+ if (line.startsWith("#") || line.trim() === "")
460
+ continue;
461
+ const parts = line.split("\t");
462
+ if (parts.length < 5)
463
+ continue;
464
+ const code = parts[0];
465
+ const name = parts[4];
466
+ if (code === undefined || code === "" || name === undefined || name === "")
467
+ continue;
468
+ // Add country name -> code mapping
469
+ countries.set(name.toLowerCase(), code);
470
+ // Add common variations
471
+ // E.g., "United States" also as "USA", "US", "America"
472
+ const variations = getCountryVariations(name, code);
473
+ for (const variation of variations) {
474
+ countries.set(variation.toLowerCase(), code);
475
+ }
476
+ }
477
+ return countries;
478
+ }
479
+ /**
480
+ * Parses admin1CodesASCII.txt content and extracts region data
481
+ */
482
+ function parseRegionsContent(content) {
483
+ const regions = new Map();
484
+ const lines = content.split("\n");
485
+ for (const line of lines) {
486
+ if (line.trim() === "")
487
+ continue;
488
+ const parts = line.split("\t");
489
+ if (parts.length < 2)
490
+ continue;
491
+ const code = parts[0]; // Format: "US.CA"
492
+ const name = parts[1];
493
+ const asciiName = parts[2];
494
+ if (code === undefined || code === "" || name === undefined || name === "")
495
+ continue;
496
+ const [countryCode] = code.split(".");
497
+ if (countryCode === undefined || countryCode === "")
498
+ continue;
499
+ const regionEntry = { country: countryCode, name };
500
+ // Add region name
501
+ regions.set(name.toLowerCase(), regionEntry);
502
+ // Add ASCII name if different
503
+ if (asciiName !== undefined &&
504
+ asciiName !== "" &&
505
+ asciiName.toLowerCase() !== name.toLowerCase()) {
506
+ regions.set(asciiName.toLowerCase(), regionEntry);
507
+ }
508
+ }
509
+ return regions;
510
+ }
511
+ // =============================================================================
512
+ // Data Loading and Lookup
513
+ // =============================================================================
514
+ /**
515
+ * Initializes semantic data (downloads if needed, then loads)
516
+ */
517
+ export async function initializeSemanticData(options = {}) {
518
+ // Ensure data is downloaded
519
+ await ensureSemanticData(options);
520
+ // Load the data
521
+ await loadSemanticData();
522
+ }
523
+ /**
524
+ * Loads semantic data from cached files
525
+ * @throws Error if required data files are not available
526
+ */
527
+ export async function loadSemanticData() {
528
+ if (semanticData !== null && semanticData.loaded === true) {
529
+ return semanticData;
530
+ }
531
+ const storage = await getStorage();
532
+ const dataDir = await getSemanticDataCacheDir();
533
+ const isAvailable = await isSemanticDataAvailable();
534
+ if (!isAvailable) {
535
+ throw new Error(`Semantic data files not found in ${dataDir}. ` +
536
+ `Use ensureSemanticData() or createAnonymizer({ semantic: { enabled: true, autoDownload: true } }) to download.`);
537
+ }
538
+ // Load and parse files
539
+ const nameDictContent = await storage.readTextFile(join(dataDir, "nam_dict.txt"), "latin1" // File uses ISO-8859-1 encoding
540
+ );
541
+ const names = parseNameDictContent(nameDictContent);
542
+ const citiesContent = await storage.readTextFile(join(dataDir, "cities15000.txt"));
543
+ const cities = parseCitiesContent(citiesContent);
544
+ const countriesContent = await storage.readTextFile(join(dataDir, "countryInfo.txt"));
545
+ const countries = parseCountriesContent(countriesContent);
546
+ // admin1 file is optional
547
+ let regions = new Map();
548
+ try {
549
+ const regionsContent = await storage.readTextFile(join(dataDir, "admin1CodesASCII.txt"));
550
+ regions = parseRegionsContent(regionsContent);
551
+ }
552
+ catch {
553
+ // admin1 file is optional
554
+ }
555
+ semanticData = {
556
+ names,
557
+ cities,
558
+ countries,
559
+ regions,
560
+ loaded: true,
561
+ };
562
+ return semanticData;
563
+ }
564
+ /**
565
+ * Gets the loaded semantic data (loads if not already loaded)
566
+ * Note: This is now async to work with browser storage
567
+ */
568
+ export async function getSemanticData() {
569
+ if (semanticData === null || semanticData.loaded !== true) {
570
+ return loadSemanticData();
571
+ }
572
+ return semanticData;
573
+ }
574
+ /**
575
+ * Gets the loaded semantic data synchronously
576
+ * Returns null if data is not yet loaded
577
+ * Use this for performance-critical code paths after initial loading
578
+ */
579
+ export function getSemanticDataSync() {
580
+ if (semanticData === null || semanticData.loaded !== true) {
581
+ return null;
582
+ }
583
+ return semanticData;
584
+ }
585
+ /**
586
+ * Clears the loaded semantic data (useful for testing)
587
+ */
588
+ export function clearSemanticData() {
589
+ semanticData = null;
590
+ }
591
+ /**
592
+ * Looks up gender for a name
593
+ */
594
+ export async function lookupGender(name, locale) {
595
+ const data = await getSemanticData();
596
+ const entry = data.names.get(name.toLowerCase());
597
+ if (entry === undefined)
598
+ return undefined;
599
+ // Check for locale-specific override
600
+ if (locale !== undefined &&
601
+ locale !== "" &&
602
+ entry.localeOverrides !== undefined &&
603
+ entry.localeOverrides[locale] !== undefined) {
604
+ return entry.localeOverrides[locale];
605
+ }
606
+ return entry.gender;
607
+ }
608
+ /**
609
+ * Population threshold for "major" cities that take precedence over regions
610
+ */
611
+ const MAJOR_CITY_POPULATION = 500000;
612
+ /**
613
+ * Looks up location type (city, country, or region)
614
+ * Priority: country > major city (pop > 500K) > region > other cities
615
+ */
616
+ export async function lookupLocationType(location) {
617
+ const data = await getSemanticData();
618
+ const normalized = location.toLowerCase().trim();
619
+ // Check countries FIRST (to avoid "USA" being matched as a city)
620
+ const countryCode = data.countries.get(normalized);
621
+ if (countryCode !== undefined) {
622
+ return { type: "country", countryCode };
623
+ }
624
+ // Check cities - if it's a major city (pop > 500K), prioritize it over regions
625
+ const city = data.cities.get(normalized);
626
+ if (city && city.population >= MAJOR_CITY_POPULATION) {
627
+ return { type: "city", countryCode: city.country };
628
+ }
629
+ // Check regions
630
+ const region = data.regions.get(normalized);
631
+ if (region) {
632
+ return { type: "region", countryCode: region.country };
633
+ }
634
+ // Check remaining cities (smaller cities)
635
+ if (city) {
636
+ return { type: "city", countryCode: city.country };
637
+ }
638
+ return undefined;
639
+ }
640
+ /**
641
+ * Gets statistics about loaded data
642
+ */
643
+ export function getDataStats() {
644
+ if (semanticData === null || semanticData.loaded !== true) {
645
+ return { names: 0, cities: 0, countries: 0, regions: 0, loaded: false };
646
+ }
647
+ return {
648
+ names: semanticData.names.size,
649
+ cities: semanticData.cities.size,
650
+ countries: semanticData.countries.size,
651
+ regions: semanticData.regions.size,
652
+ loaded: true,
653
+ };
654
+ }
655
+ //# sourceMappingURL=semantic-data-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semantic-data-loader.js","sourceRoot":"","sources":["../../src/pipeline/semantic-data-loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,kBAAkB,EAAwB,MAAM,qBAAqB,CAAC;AAC/E,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAElD;;GAEG;AACH,MAAM,eAAe,GAA2B;IAC9C,CAAC,EAAE,MAAM;IACT,IAAI,EAAE,MAAM;IACZ,IAAI,EAAE,MAAM,EAAE,cAAc;IAC5B,CAAC,EAAE,QAAQ;IACX,IAAI,EAAE,QAAQ;IACd,IAAI,EAAE,QAAQ,EAAE,gBAAgB;IAChC,GAAG,EAAE,SAAS,EAAE,SAAS;CAC1B,CAAC;AAEF;;;GAGG;AACH,MAAM,eAAe,GAA2B;IAC9C,EAAE,EAAE,CAAC,EAAE,gBAAgB;IACvB,EAAE,EAAE,CAAC,EAAE,UAAU;IACjB,EAAE,EAAE,CAAC,EAAE,MAAM;IACb,EAAE,EAAE,CAAC,EAAE,QAAQ;IACf,EAAE,EAAE,CAAC,EAAE,QAAQ;IACf,EAAE,EAAE,CAAC,EAAE,WAAW;IAClB,EAAE,EAAE,CAAC,EAAE,QAAQ;IACf,EAAE,EAAE,CAAC,EAAE,SAAS;IAChB,EAAE,EAAE,CAAC,EAAE,UAAU;IACjB,EAAE,EAAE,CAAC,EAAE,aAAa;IACpB,EAAE,EAAE,EAAE,EAAE,cAAc;IACtB,EAAE,EAAE,EAAE,EAAE,6CAA6C;IACrD,EAAE,EAAE,EAAE,EAAE,UAAU;IAClB,EAAE,EAAE,EAAE,EAAE,QAAQ;IAChB,EAAE,EAAE,EAAE,EAAE,UAAU;IAClB,EAAE,EAAE,EAAE,EAAE,UAAU;IAClB,EAAE,EAAE,EAAE,EAAE,SAAS;IACjB,EAAE,EAAE,EAAE,EAAE,SAAS;IACjB,EAAE,EAAE,EAAE,EAAE,UAAU;IAClB,EAAE,EAAE,EAAE,EAAE,UAAU;IAClB,EAAE,EAAE,EAAE,EAAE,SAAS;IACjB,EAAE,EAAE,EAAE,EAAE,YAAY;IACpB,EAAE,EAAE,EAAE,EAAE,SAAS;IACjB,EAAE,EAAE,EAAE,EAAE,iBAAiB;IACzB,EAAE,EAAE,EAAE,EAAE,WAAW;IACnB,EAAE,EAAE,EAAE,EAAE,UAAU;IAClB,EAAE,EAAE,EAAE,EAAE,UAAU;IAClB,EAAE,EAAE,EAAE,EAAE,WAAW;IACnB,EAAE,EAAE,EAAE,EAAE,oBAAoB;IAC5B,EAAE,EAAE,EAAE,EAAE,WAAW;IACnB,EAAE,EAAE,EAAE,EAAE,oBAAoB;IAC5B,EAAE,EAAE,EAAE,EAAE,YAAY;IACpB,EAAE,EAAE,EAAE,EAAE,SAAS;IACjB,EAAE,EAAE,EAAE,EAAE,SAAS;IACjB,EAAE,EAAE,EAAE,EAAE,UAAU;IAClB,EAAE,EAAE,EAAE,EAAE,UAAU;IAClB,EAAE,EAAE,EAAE,EAAE,UAAU;IAClB,EAAE,EAAE,EAAE,EAAE,UAAU;IAClB,EAAE,EAAE,EAAE,EAAE,aAAa;IACrB,EAAE,EAAE,EAAE,EAAE,UAAU;IAClB,EAAE,EAAE,EAAE,EAAE,wBAAwB;IAChC,EAAE,EAAE,EAAE,EAAE,SAAS;IACjB,EAAE,EAAE,EAAE,EAAE,gBAAgB;IACxB,EAAE,EAAE,EAAE,EAAE,SAAS;IACjB,EAAE,EAAE,EAAE,EAAE,QAAQ;IAChB,EAAE,EAAE,EAAE,EAAE,kBAAkB;IAC1B,EAAE,EAAE,EAAE,EAAE,QAAQ;IAChB,EAAE,EAAE,EAAE,EAAE,QAAQ;IAChB,EAAE,EAAE,EAAE,EAAE,UAAU;CACnB,CAAC;AAEF,iEAAiE;AACjE,KAAK,eAAe,CAAC;AAkCrB,oCAAoC;AACpC,IAAI,YAAY,GAAwB,IAAI,CAAC;AAE7C,0BAA0B;AAC1B,IAAI,eAAe,GAA2B,IAAI,CAAC;AAEnD;;GAEG;AACH,KAAK,UAAU,UAAU;IACvB,IAAI,eAAe,KAAK,IAAI,EAAE,CAAC;QAC7B,eAAe,GAAG,MAAM,kBAAkB,EAAE,CAAC;IAC/C,CAAC;IACD,OAAO,eAAe,CAAC;AACzB,CAAC;AAED,gFAAgF;AAChF,6BAA6B;AAC7B,gFAAgF;AAEhF;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB;IAC3C,MAAM,OAAO,GAAG,MAAM,UAAU,EAAE,CAAC;IACnC,OAAO,OAAO,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC;AAC9C,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,OAAO,uBAAuB,EAAE,CAAC;AACnC,CAAC;AAsBD;;GAEG;AACH,MAAM,oBAAoB,GACxB,wEAAwE,CAAC;AAE3E;;GAEG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAA2B;IACzD;QACE,QAAQ,EAAE,cAAc;QACxB,GAAG,EAAE,GAAG,oBAAoB,eAAe;QAC3C,QAAQ,EAAE,IAAI;QACd,WAAW,EAAE,mCAAmC;QAChD,IAAI,EAAE,SAAS;KAChB;IACD;QACE,QAAQ,EAAE,iBAAiB;QAC3B,GAAG,EAAE,GAAG,oBAAoB,kBAAkB;QAC9C,QAAQ,EAAE,IAAI;QACd,WAAW,EAAE,0CAA0C;QACvD,IAAI,EAAE,SAAS;KAChB;IACD;QACE,QAAQ,EAAE,iBAAiB;QAC3B,GAAG,EAAE,GAAG,oBAAoB,kBAAkB;QAC9C,QAAQ,EAAE,IAAI;QACd,WAAW,EAAE,yBAAyB;QACtC,IAAI,EAAE,QAAQ;KACf;IACD;QACE,QAAQ,EAAE,sBAAsB;QAChC,GAAG,EAAE,GAAG,oBAAoB,uBAAuB;QACnD,QAAQ,EAAE,KAAK;QACf,WAAW,EAAE,8CAA8C;QAC3D,IAAI,EAAE,SAAS;KAChB;CACF,CAAC;AAgBF;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB;IAC5C,MAAM,OAAO,GAAG,MAAM,UAAU,EAAE,CAAC;IACnC,MAAM,OAAO,GAAG,MAAM,uBAAuB,EAAE,CAAC;IAEhD,IAAI,CAAC;QACH,2BAA2B;QAC3B,KAAK,MAAM,IAAI,IAAI,mBAAmB,EAAE,CAAC;YACvC,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAClB,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;gBAClE,IAAI,CAAC,MAAM;oBAAE,OAAO,KAAK,CAAC;YAC5B,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB;IAC3C,OAAO,wBAAwB,EAAE,CAAC;AACpC,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,gBAAgB,CAC7B,GAAW,EACX,QAAgB,EAChB,UAA6C;IAE7C,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;QAChC,OAAO,EAAE;YACP,YAAY,EAAE,eAAe;SAC9B;KACF,CAAC,CAAC;IAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CAAC,mBAAmB,GAAG,EAAE,CAAC,CAAC;QAC5C,CAAC;QACD,MAAM,IAAI,KAAK,CACb,sBAAsB,GAAG,KAAK,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE,CACvE,CAAC;IACJ,CAAC;IAED,MAAM,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAC1D,MAAM,KAAK,GACT,UAAU,KAAK,IAAI,IAAI,UAAU,KAAK,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAE7E,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,EAAE,SAAS,EAAE,CAAC;IAC1C,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;IACnD,CAAC;IAED,MAAM,MAAM,GAAiB,EAAE,CAAC;IAChC,IAAI,eAAe,GAAG,CAAC,CAAC;IAExB,iDAAiD;IACjD,OAAO,IAAI,EAAE,CAAC;QACZ,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;QAEnC,IAAI,MAAM,CAAC,IAAI;YAAE,MAAM;QAEvB,MAAM,KAAK,GAAG,MAAM,CAAC,KAAmB,CAAC;QACzC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACnB,eAAe,IAAI,KAAK,CAAC,MAAM,CAAC;QAEhC,IAAI,UAAU,EAAE,CAAC;YACf,UAAU,CAAC;gBACT,IAAI,EAAE,QAAQ;gBACd,eAAe;gBACf,UAAU,EAAE,KAAK;gBACjB,OAAO,EACL,KAAK,KAAK,IAAI,IAAI,KAAK,GAAG,CAAC;oBACzB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,eAAe,GAAG,KAAK,CAAC,GAAG,GAAG,CAAC;oBAC7C,CAAC,CAAC,IAAI;aACX,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,yBAAyB;IACzB,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,GAAG,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACzE,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,WAAW,CAAC,CAAC;IAC3C,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC;IACzB,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,YAAY,CACzB,GAAW,EACX,QAAgB,EAChB,UAA6C;IAE7C,MAAM,OAAO,GAAG,MAAM,UAAU,EAAE,CAAC;IACnC,MAAM,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAEpC,MAAM,IAAI,GAAG,MAAM,gBAAgB,CAAC,GAAG,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;IAC/D,MAAM,OAAO,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;AAC1C,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,UAA6C,EAC7C,QAAmC;IAEnC,MAAM,OAAO,GAAG,MAAM,UAAU,EAAE,CAAC;IACnC,MAAM,OAAO,GAAG,MAAM,uBAAuB,EAAE,CAAC;IAEhD,mBAAmB;IACnB,MAAM,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAE7B,QAAQ,EAAE,CAAC,yCAAyC,CAAC,CAAC;IACtD,QAAQ,EAAE,CAAC,oBAAoB,OAAO,EAAE,CAAC,CAAC;IAE1C,KAAK,MAAM,IAAI,IAAI,mBAAmB,EAAE,CAAC;QACvC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QAE9C,QAAQ,EAAE,CAAC,eAAe,IAAI,CAAC,WAAW,KAAK,CAAC,CAAC;QAEjD,IAAI,CAAC;YACH,MAAM,YAAY,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC;QACrD,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAClB,MAAM,IAAI,KAAK,CACb,oCAAoC,IAAI,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,CAAC,EAAE,CAClE,CAAC;YACJ,CAAC;YACD,mCAAmC;YACnC,QAAQ,EAAE,CAAC,0BAA0B,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;QACxD,CAAC;IACH,CAAC;IAED,QAAQ,EAAE,CAAC,kCAAkC,CAAC,CAAC;IAE/C,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,UAII,EAAE;IAEN,MAAM,EAAE,YAAY,GAAG,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;IAE9D,MAAM,OAAO,GAAG,MAAM,uBAAuB,EAAE,CAAC;IAEhD,8BAA8B;IAC9B,MAAM,YAAY,GAAG,MAAM,wBAAwB,EAAE,CAAC;IAEtD,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CACb,8BAA8B,OAAO,OAAO;gBAC1C,mCAAmC;gBACnC,6EAA6E;gBAC7E,gCAAgC;gBAChC,sDAAsD,CACzD,CAAC;QACJ,CAAC;QAED,MAAM,oBAAoB,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IACnD,CAAC;SAAM,CAAC;QACN,QAAQ,EAAE,CAAC,+BAA+B,OAAO,EAAE,CAAC,CAAC;IACvD,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB;IAC1C,MAAM,OAAO,GAAG,MAAM,UAAU,EAAE,CAAC;IACnC,MAAM,OAAO,GAAG,MAAM,uBAAuB,EAAE,CAAC;IAChD,MAAM,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5D,4BAA4B;IAC5B,iBAAiB,EAAE,CAAC;AACtB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB;IAKvC,MAAM,QAAQ,GAAG,MAAM,uBAAuB,EAAE,CAAC;IACjD,OAAO;QACL,KAAK,EAAE,mBAAmB;QAC1B,QAAQ;QACR,SAAS,EAAE,OAAO;KACnB,CAAC;AACJ,CAAC;AAED,gFAAgF;AAChF,yBAAyB;AACzB,gFAAgF;AAEhF;;GAEG;AACH,SAAS,oBAAoB,CAAC,OAAe;IAC3C,MAAM,KAAK,GAAG,IAAI,GAAG,EAAqB,CAAC;IAC3C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAElC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,gCAAgC;QAChC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE;YAAE,SAAS;QAEzD,iEAAiE;QACjE,IAAI,IAAI,CAAC,MAAM,GAAG,EAAE,IAAI,IAAI,CAAC,EAAE,CAAC,KAAK,GAAG;YAAE,SAAS;QAEnD,6BAA6B;QAC7B,sDAAsD;QACtD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC;QAC1D,IAAI,CAAC,KAAK;YAAE,SAAS;QAErB,MAAM,CAAC,EAAE,UAAU,EAAE,IAAI,CAAC,GAAG,KAAK,CAAC;QACnC,IACE,UAAU,KAAK,SAAS;YACxB,UAAU,KAAK,EAAE;YACjB,IAAI,KAAK,SAAS;YAClB,IAAI,KAAK,EAAE;YAEX,SAAS;QAEX,MAAM,MAAM,GAAG,eAAe,CAAC,UAAU,CAAC,CAAC;QAC3C,IAAI,MAAM,KAAK,SAAS;YAAE,SAAS;QAEnC,MAAM,cAAc,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QAE1C,mEAAmE;QACnE,+EAA+E;QAC/E,4BAA4B;QAC5B,MAAM,eAAe,GAA2B,EAAE,CAAC;QAEnD,+DAA+D;QAC/D,wDAAwD;QAExD,kBAAkB;QAClB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE,CAAC;YAC/B,KAAK,CAAC,GAAG,CAAC,cAAc,EAAE;gBACxB,MAAM;gBACN,eAAe,EACb,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,SAAS;aACxE,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,mFAAmF;YACnF,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,cAAc,CAAE,CAAC;YAC5C,IAAI,QAAQ,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;gBAC/B,mDAAmD;gBACnD,IAAI,CAAC,QAAQ,CAAC,eAAe,EAAE,CAAC;oBAC9B,QAAQ,CAAC,eAAe,GAAG,EAAE,CAAC;gBAChC,CAAC;gBACD,0EAA0E;YAC5E,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;GAGG;AACH,SAAS,kBAAkB,CAAC,OAAe;IACzC,MAAM,MAAM,GAAG,IAAI,GAAG,EAAqB,CAAC;IAC5C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAElC,gEAAgE;IAChE,MAAM,OAAO,GAAG,CAAC,IAAY,EAAE,KAAgB,EAAQ,EAAE;QACvD,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QACtC,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACxC,IAAI,CAAC,QAAQ,IAAI,KAAK,CAAC,UAAU,GAAG,QAAQ,CAAC,UAAU,EAAE,CAAC;YACxD,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;QAChC,CAAC;IACH,CAAC,CAAC;IAEF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE;YAAE,SAAS;QAEjC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC/B,IAAI,KAAK,CAAC,MAAM,GAAG,EAAE;YAAE,SAAS;QAEhC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACtB,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QAC3B,MAAM,cAAc,GAAG,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QAClD,MAAM,WAAW,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QAC7B,MAAM,UAAU,GAAG,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,GAAG,EAAE,EAAE,CAAC,CAAC;QAElD,IACE,IAAI,KAAK,SAAS;YAClB,IAAI,KAAK,EAAE;YACX,WAAW,KAAK,SAAS;YACzB,WAAW,KAAK,EAAE;YAElB,SAAS;QAEX,MAAM,SAAS,GAAc,EAAE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC;QAElE,2CAA2C;QAC3C,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QAEzB,yDAAyD;QACzD,IACE,SAAS,KAAK,SAAS;YACvB,SAAS,KAAK,EAAE;YAChB,SAAS,CAAC,WAAW,EAAE,KAAK,IAAI,CAAC,WAAW,EAAE,EAC9C,CAAC;YACD,OAAO,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QAChC,CAAC;QAED,iDAAiD;QACjD,KAAK,MAAM,OAAO,IAAI,cAAc,EAAE,CAAC;YACrC,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;YAC/B,IAAI,OAAO,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC5D,OAAO,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;YAC9B,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,SAAS,oBAAoB,CAAC,IAAY,EAAE,IAAY;IACtD,MAAM,UAAU,GAAa,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;IAElD,oCAAoC;IACpC,MAAM,UAAU,GAA6B;QAC3C,eAAe,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,0BAA0B,CAAC;QACrE,gBAAgB,EAAE,CAAC,IAAI,EAAE,SAAS,EAAE,eAAe,EAAE,SAAS,CAAC;QAC/D,OAAO,EAAE,CAAC,aAAa,CAAC;QACxB,MAAM,EAAE,CAAC,YAAY,CAAC;QACtB,KAAK,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,CAAC;QACtC,KAAK,EAAE,CAAC,QAAQ,EAAE,SAAS,CAAC;QAC5B,WAAW,EAAE,CAAC,SAAS,EAAE,iBAAiB,EAAE,aAAa,CAAC;QAC1D,WAAW,EAAE,CAAC,SAAS,EAAE,QAAQ,EAAE,UAAU,CAAC;QAC9C,OAAO,EAAE,CAAC,YAAY,EAAE,aAAa,CAAC;QACtC,OAAO,EAAE,CAAC,SAAS,EAAE,UAAU,CAAC;QAChC,MAAM,EAAE,CAAC,UAAU,EAAE,oBAAoB,CAAC;QAC1C,KAAK,EAAE,CAAC,4BAA4B,EAAE,KAAK,CAAC;QAC5C,KAAK,EAAE,CAAC,QAAQ,CAAC;QACjB,aAAa,EAAE,CAAC,OAAO,EAAE,mBAAmB,CAAC;QAC7C,sBAAsB,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC;QAC3C,gBAAgB,EAAE,CAAC,SAAS,EAAE,YAAY,CAAC;KAC5C,CAAC;IAEF,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACrB,UAAU,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;IACvC,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;GAEG;AACH,SAAS,qBAAqB,CAAC,OAAe;IAC5C,MAAM,SAAS,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC5C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAElC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,gCAAgC;QAChC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE;YAAE,SAAS;QAEzD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC/B,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;YAAE,SAAS;QAE/B,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACtB,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QAEtB,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,EAAE,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,EAAE;YACxE,SAAS;QAEX,mCAAmC;QACnC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,IAAI,CAAC,CAAC;QAExC,wBAAwB;QACxB,uDAAuD;QACvD,MAAM,UAAU,GAAG,oBAAoB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACpD,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACnC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,WAAW,EAAE,EAAE,IAAI,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;GAEG;AACH,SAAS,mBAAmB,CAAC,OAAe;IAC1C,MAAM,OAAO,GAAG,IAAI,GAAG,EAAuB,CAAC;IAC/C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAElC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE;YAAE,SAAS;QAEjC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC/B,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;YAAE,SAAS;QAE/B,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,kBAAkB;QACzC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACtB,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QAE3B,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,EAAE,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,EAAE;YACxE,SAAS;QAEX,MAAM,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACtC,IAAI,WAAW,KAAK,SAAS,IAAI,WAAW,KAAK,EAAE;YAAE,SAAS;QAE9D,MAAM,WAAW,GAAgB,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;QAEhE,kBAAkB;QAClB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,WAAW,CAAC,CAAC;QAE7C,8BAA8B;QAC9B,IACE,SAAS,KAAK,SAAS;YACvB,SAAS,KAAK,EAAE;YAChB,SAAS,CAAC,WAAW,EAAE,KAAK,IAAI,CAAC,WAAW,EAAE,EAC9C,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,WAAW,EAAE,EAAE,WAAW,CAAC,CAAC;QACpD,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,gFAAgF;AAChF,0BAA0B;AAC1B,gFAAgF;AAEhF;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,UAII,EAAE;IAEN,4BAA4B;IAC5B,MAAM,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAElC,gBAAgB;IAChB,MAAM,gBAAgB,EAAE,CAAC;AAC3B,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,IAAI,YAAY,KAAK,IAAI,IAAI,YAAY,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;QAC1D,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,UAAU,EAAE,CAAC;IACnC,MAAM,OAAO,GAAG,MAAM,uBAAuB,EAAE,CAAC;IAEhD,MAAM,WAAW,GAAG,MAAM,uBAAuB,EAAE,CAAC;IACpD,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CACb,oCAAoC,OAAO,IAAI;YAC7C,gHAAgH,CACnH,CAAC;IACJ,CAAC;IAED,uBAAuB;IACvB,MAAM,eAAe,GAAG,MAAM,OAAO,CAAC,YAAY,CAChD,IAAI,CAAC,OAAO,EAAE,cAAc,CAAC,EAC7B,QAAQ,CAAC,gCAAgC;KAC1C,CAAC;IACF,MAAM,KAAK,GAAG,oBAAoB,CAAC,eAAe,CAAC,CAAC;IAEpD,MAAM,aAAa,GAAG,MAAM,OAAO,CAAC,YAAY,CAC9C,IAAI,CAAC,OAAO,EAAE,iBAAiB,CAAC,CACjC,CAAC;IACF,MAAM,MAAM,GAAG,kBAAkB,CAAC,aAAa,CAAC,CAAC;IAEjD,MAAM,gBAAgB,GAAG,MAAM,OAAO,CAAC,YAAY,CACjD,IAAI,CAAC,OAAO,EAAE,iBAAiB,CAAC,CACjC,CAAC;IACF,MAAM,SAAS,GAAG,qBAAqB,CAAC,gBAAgB,CAAC,CAAC;IAE1D,0BAA0B;IAC1B,IAAI,OAAO,GAAG,IAAI,GAAG,EAAuB,CAAC;IAC7C,IAAI,CAAC;QACH,MAAM,cAAc,GAAG,MAAM,OAAO,CAAC,YAAY,CAC/C,IAAI,CAAC,OAAO,EAAE,sBAAsB,CAAC,CACtC,CAAC;QACF,OAAO,GAAG,mBAAmB,CAAC,cAAc,CAAC,CAAC;IAChD,CAAC;IAAC,MAAM,CAAC;QACP,0BAA0B;IAC5B,CAAC;IAED,YAAY,GAAG;QACb,KAAK;QACL,MAAM;QACN,SAAS;QACT,OAAO;QACP,MAAM,EAAE,IAAI;KACb,CAAC;IAEF,OAAO,YAAY,CAAC;AACtB,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,IAAI,YAAY,KAAK,IAAI,IAAI,YAAY,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;QAC1D,OAAO,gBAAgB,EAAE,CAAC;IAC5B,CAAC;IACD,OAAO,YAAY,CAAC;AACtB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB;IACjC,IAAI,YAAY,KAAK,IAAI,IAAI,YAAY,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;QAC1D,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,YAAY,CAAC;AACtB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB;IAC/B,YAAY,GAAG,IAAI,CAAC;AACtB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,IAAY,EACZ,MAAe;IAEf,MAAM,IAAI,GAAG,MAAM,eAAe,EAAE,CAAC;IACrC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;IAEjD,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAE1C,qCAAqC;IACrC,IACE,MAAM,KAAK,SAAS;QACpB,MAAM,KAAK,EAAE;QACb,KAAK,CAAC,eAAe,KAAK,SAAS;QACnC,KAAK,CAAC,eAAe,CAAC,MAAM,CAAC,KAAK,SAAS,EAC3C,CAAC;QACD,OAAO,KAAK,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;IACvC,CAAC;IAED,OAAO,KAAK,CAAC,MAAM,CAAC;AACtB,CAAC;AAED;;GAEG;AACH,MAAM,qBAAqB,GAAG,MAAM,CAAC;AAErC;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,QAAgB;IAIhB,MAAM,IAAI,GAAG,MAAM,eAAe,EAAE,CAAC;IACrC,MAAM,UAAU,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC;IAEjD,iEAAiE;IACjE,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IACnD,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,CAAC;IAC1C,CAAC;IAED,+EAA+E;IAC/E,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IACzC,IAAI,IAAI,IAAI,IAAI,CAAC,UAAU,IAAI,qBAAqB,EAAE,CAAC;QACrD,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC;IACrD,CAAC;IAED,gBAAgB;IAChB,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IAC5C,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC;IACzD,CAAC;IAED,0CAA0C;IAC1C,IAAI,IAAI,EAAE,CAAC;QACT,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC;IACrD,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY;IAO1B,IAAI,YAAY,KAAK,IAAI,IAAI,YAAY,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;QAC1D,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAC1E,CAAC;IAED,OAAO;QACL,KAAK,EAAE,YAAY,CAAC,KAAK,CAAC,IAAI;QAC9B,MAAM,EAAE,YAAY,CAAC,MAAM,CAAC,IAAI;QAChC,SAAS,EAAE,YAAY,CAAC,SAAS,CAAC,IAAI;QACtC,OAAO,EAAE,YAAY,CAAC,OAAO,CAAC,IAAI;QAClC,MAAM,EAAE,IAAI;KACb,CAAC;AACJ,CAAC"}