bps-mcp-server 0.12.1 → 0.13.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.
- package/README.md +21 -5
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +3 -0
- package/dist/server.js.map +1 -1
- package/dist/services/learning.js +1 -1
- package/dist/services/learning.js.map +1 -1
- package/dist/tools/analysis.tools.d.ts +11 -0
- package/dist/tools/analysis.tools.d.ts.map +1 -0
- package/dist/tools/analysis.tools.js +647 -0
- package/dist/tools/analysis.tools.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@ MCP (Model Context Protocol) server untuk data statistik BPS (Badan Pusat Statis
|
|
|
8
8
|
|
|
9
9
|
## Fitur
|
|
10
10
|
|
|
11
|
-
- **
|
|
11
|
+
- **39 tools** mencakup seluruh endpoint BPS WebAPI v1 + AllStats Search + AI-friendly shortcuts
|
|
12
12
|
- **AI-friendly** — tool `find_data` memungkinkan AI mendapat data dalam 1 langkah (tanpa perlu navigasi hierarki BPS)
|
|
13
13
|
- **Integrasi AllStats Search** — pencarian unified + full-text PDF search (tanpa API key)
|
|
14
14
|
- **Smart fallback** — WebAPI search otomatis fallback ke AllStats jika tidak ada hasil
|
|
@@ -163,16 +163,19 @@ File `~/.cursor/mcp.json` atau `.vscode/mcp.json`:
|
|
|
163
163
|
}
|
|
164
164
|
```
|
|
165
165
|
|
|
166
|
-
## Tools (
|
|
166
|
+
## Tools (39)
|
|
167
167
|
|
|
168
|
-
### AI-Friendly Smart Tools (
|
|
168
|
+
### AI-Friendly Smart Tools (5)
|
|
169
169
|
|
|
170
170
|
| Tool | Deskripsi |
|
|
171
171
|
|------|-----------|
|
|
172
172
|
| `find_data` | **Recommended** — Cari & ambil data dalam satu langkah (resolve wilayah + cari variabel + ambil data) |
|
|
173
173
|
| `find_variable` | Cari variabel data berdasarkan kata kunci |
|
|
174
|
+
| `compare_data` | Bandingkan data antar wilayah (2+ wilayah sekaligus dalam 1 panggilan) |
|
|
175
|
+
| `get_trend` | Ambil data time-series/tren multi-tahun dalam 1 panggilan |
|
|
176
|
+
| `get_ranking` | Ranking/peringkat provinsi berdasarkan indikator (top-N) |
|
|
174
177
|
|
|
175
|
-
> **Untuk AI:** Gunakan `find_data`
|
|
178
|
+
> **Untuk AI:** Gunakan `find_data` untuk data 1 wilayah, `compare_data` untuk perbandingan, `get_trend` untuk tren, `get_ranking` untuk peringkat. Jika hasilnya kurang spesifik, gunakan `find_variable` lalu `get_dynamic_data`.
|
|
176
179
|
|
|
177
180
|
### WebAPI Tools (32)
|
|
178
181
|
|
|
@@ -236,6 +239,15 @@ Jika find_data gagal, AI bisa:
|
|
|
236
239
|
- find_variable(keyword="miskin") → lihat variabel yang tersedia
|
|
237
240
|
- list_strategic_indicators() → data headline terbaru
|
|
238
241
|
- search(keyword="kemiskinan") → cari tabel/publikasi terkait
|
|
242
|
+
|
|
243
|
+
User: "Bandingkan kemiskinan Jawa Timur dan Jawa Barat"
|
|
244
|
+
AI menggunakan: compare_data(query="kemiskinan", regions="Jawa Timur, Jawa Barat")
|
|
245
|
+
|
|
246
|
+
User: "Tren pengangguran Indonesia 2019-2024"
|
|
247
|
+
AI menggunakan: get_trend(query="pengangguran", region="Indonesia", start_year="2019", end_year="2024")
|
|
248
|
+
|
|
249
|
+
User: "10 provinsi termiskin"
|
|
250
|
+
AI menggunakan: get_ranking(query="kemiskinan", top_n=10, order="highest")
|
|
239
251
|
```
|
|
240
252
|
|
|
241
253
|
## Contoh Query
|
|
@@ -243,6 +255,9 @@ Jika find_data gagal, AI bisa:
|
|
|
243
255
|
```
|
|
244
256
|
"Berapa jumlah penduduk miskin Indonesia tahun 2023?"
|
|
245
257
|
"Bandingkan angka kemiskinan Jawa Timur vs Jawa Barat 2020-2023"
|
|
258
|
+
"Tren pengangguran Indonesia dari 2019 sampai 2024"
|
|
259
|
+
"10 provinsi dengan kemiskinan tertinggi"
|
|
260
|
+
"Peringkat IPM seluruh provinsi 2023"
|
|
246
261
|
"Cari BRS terbaru tentang inflasi"
|
|
247
262
|
"Data ekspor kopi Indonesia tahun 2024"
|
|
248
263
|
"Cari publikasi tentang statistik telekomunikasi"
|
|
@@ -361,8 +376,9 @@ src/
|
|
|
361
376
|
├── prompts/ # MCP prompt templates
|
|
362
377
|
├── resources/ # MCP resources (domain lists)
|
|
363
378
|
├── services/ # Cache, domain resolver, data formatter
|
|
364
|
-
├── tools/ # MCP tool definitions (
|
|
379
|
+
├── tools/ # MCP tool definitions (39 tools)
|
|
365
380
|
│ ├── smart.tools.ts # find_data, find_variable (AI shortcuts)
|
|
381
|
+
│ ├── analysis.tools.ts # compare_data, get_trend, get_ranking
|
|
366
382
|
│ ├── dynamic-data.tools.ts # Core data tools
|
|
367
383
|
│ ├── search.tools.ts # Search with AllStats fallback
|
|
368
384
|
│ ├── allstats.tools.ts # AllStats search & deep search
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAEnD,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAEnD,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAoB/D,wBAAgB,YAAY,CAC1B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,aAAa,EACnB,KAAK,EAAE,cAAc,GAAG,IAAI,EAC5B,KAAK,CAAC,EAAE,gBAAgB,GAAG,IAAI,EAC/B,OAAO,CAAC,EAAE,MAAM,GACf;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,SAAS,CAAC;IAAC,QAAQ,EAAE,cAAc,CAAA;CAAE,CA2CpE"}
|
package/dist/server.js
CHANGED
|
@@ -12,6 +12,7 @@ import { registerSearchTools } from "./tools/search.tools.js";
|
|
|
12
12
|
import { registerAllStatsTools } from "./tools/allstats.tools.js";
|
|
13
13
|
import { registerUtilityTools } from "./tools/utility.tools.js";
|
|
14
14
|
import { registerSmartTools } from "./tools/smart.tools.js";
|
|
15
|
+
import { registerAnalysisTools } from "./tools/analysis.tools.js";
|
|
15
16
|
import { registerInfographicTools } from "./tools/infographic.tools.js";
|
|
16
17
|
import { registerCensusTools } from "./tools/census.tools.js";
|
|
17
18
|
import { registerCsaTools } from "./tools/csa.tools.js";
|
|
@@ -45,6 +46,8 @@ export function createServer(config, auth, cache, store, version) {
|
|
|
45
46
|
registerAllStatsTools(server, allStatsClient);
|
|
46
47
|
// Smart AI-friendly tools (one-shot data retrieval)
|
|
47
48
|
registerSmartTools(server, client, resolver, config, store ?? null);
|
|
49
|
+
// Analysis tools (compare, trend, ranking)
|
|
50
|
+
registerAnalysisTools(server, client, resolver, config, store ?? null);
|
|
48
51
|
// Utility
|
|
49
52
|
registerUtilityTools(server, cache);
|
|
50
53
|
// Resources & Prompts
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,7 +10,7 @@ const KNOWN_VARS = {
|
|
|
10
10
|
{ var_id: 674, title: "Jumlah Pengangguran (jiwa)", sub_name: "Tenaga Kerja" },
|
|
11
11
|
],
|
|
12
12
|
ipm: [
|
|
13
|
-
{ var_id:
|
|
13
|
+
{ var_id: 413, title: "[Metode Baru] Indeks Pembangunan Manusia (IPM)", sub_name: "IPM" },
|
|
14
14
|
],
|
|
15
15
|
gini: [
|
|
16
16
|
{ var_id: 98, title: "Gini Rasio", sub_name: "Kemiskinan dan Ketimpangan" },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"learning.js","sourceRoot":"","sources":["../../src/services/learning.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAgB5C,+CAA+C;AAE/C,MAAM,UAAU,GAAiC;IAC/C,MAAM,EAAE;QACN,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,4BAA4B,EAAE,QAAQ,EAAE,4BAA4B,EAAE;QAC5F,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,oCAAoC,EAAE,QAAQ,EAAE,4BAA4B,EAAE;KACrG;IACD,YAAY,EAAE;QACZ,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,kCAAkC,EAAE,QAAQ,EAAE,cAAc,EAAE;QACpF,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,4BAA4B,EAAE,QAAQ,EAAE,cAAc,EAAE;KAC/E;IACD,GAAG,EAAE;QACH,EAAE,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"learning.js","sourceRoot":"","sources":["../../src/services/learning.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import type { BpsClient } from "../client/bps-client.js";
|
|
3
|
+
import type { Config } from "../config/index.js";
|
|
4
|
+
import type { DomainResolver } from "../services/domain-resolver.js";
|
|
5
|
+
import type { IPersistentStore } from "../services/persistent-store.js";
|
|
6
|
+
/**
|
|
7
|
+
* Multi-region comparison, trend, and ranking tools.
|
|
8
|
+
* Each handles a common multi-step query pattern in a single tool call.
|
|
9
|
+
*/
|
|
10
|
+
export declare function registerAnalysisTools(server: McpServer, client: BpsClient, resolver: DomainResolver, config: Config, store: IPersistentStore | null): void;
|
|
11
|
+
//# sourceMappingURL=analysis.tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analysis.tools.d.ts","sourceRoot":"","sources":["../../src/tools/analysis.tools.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACzD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAIxE;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,SAAS,EACjB,QAAQ,EAAE,cAAc,EACxB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,gBAAgB,GAAG,IAAI,GAC7B,IAAI,CA2XN"}
|
|
@@ -0,0 +1,647 @@
|
|
|
1
|
+
import { z } from "zod/v4";
|
|
2
|
+
import { appendAttribution } from "../services/attribution.js";
|
|
3
|
+
import { lookupVar, learnVar, invalidateVar, normalizeKeyword } from "../services/learning.js";
|
|
4
|
+
/**
|
|
5
|
+
* Multi-region comparison, trend, and ranking tools.
|
|
6
|
+
* Each handles a common multi-step query pattern in a single tool call.
|
|
7
|
+
*/
|
|
8
|
+
export function registerAnalysisTools(server, client, resolver, config, store) {
|
|
9
|
+
// ---------- compare_data ----------
|
|
10
|
+
server.tool("compare_data", `Bandingkan data statistik antar wilayah dalam 1 langkah.
|
|
11
|
+
Gunakan tool ini ketika user ingin membandingkan data antara 2 atau lebih wilayah.
|
|
12
|
+
|
|
13
|
+
Contoh query user yang cocok untuk tool ini:
|
|
14
|
+
- "bandingkan kemiskinan Jawa Timur dan Jawa Barat"
|
|
15
|
+
- "IPM DKI Jakarta vs Banten vs Jawa Barat"
|
|
16
|
+
- "perbandingan pengangguran antar provinsi di Jawa"
|
|
17
|
+
- "mana yang lebih tinggi kemiskinan Jatim atau Jabar?"`, {
|
|
18
|
+
query: z.string().describe("Indikator yang dibandingkan (misal: kemiskinan, pengangguran, IPM, penduduk)"),
|
|
19
|
+
regions: z.string().describe("Nama wilayah dipisah koma (misal: 'Jawa Timur, Jawa Barat, Jawa Tengah')"),
|
|
20
|
+
year: z.string().optional().describe("Tahun data (misal: '2023'). Kosongkan untuk data terbaru."),
|
|
21
|
+
}, async ({ query, regions, year }) => {
|
|
22
|
+
try {
|
|
23
|
+
const regionList = regions.split(",").map(r => r.trim()).filter(Boolean);
|
|
24
|
+
if (regionList.length < 2) {
|
|
25
|
+
return { content: [{ type: "text", text: "Minimal 2 wilayah untuk perbandingan." }], isError: true };
|
|
26
|
+
}
|
|
27
|
+
const results = [];
|
|
28
|
+
for (const regionName of regionList) {
|
|
29
|
+
const resolved = await resolver.resolve(regionName);
|
|
30
|
+
if (!resolved) {
|
|
31
|
+
results.push({ region: regionName, domain: "?", value: "Wilayah tidak ditemukan", varTitle: "" });
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
const { domainId, domainName } = resolved;
|
|
35
|
+
const data = await fetchDataForDomain(client, store, query, domainId, year);
|
|
36
|
+
results.push({
|
|
37
|
+
region: domainName,
|
|
38
|
+
domain: domainId,
|
|
39
|
+
value: data.value,
|
|
40
|
+
varTitle: data.varTitle,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
// Format output
|
|
44
|
+
const varTitle = results.find(r => r.varTitle)?.varTitle || query;
|
|
45
|
+
const lines = [
|
|
46
|
+
`## Perbandingan: ${varTitle}`,
|
|
47
|
+
year ? `**Tahun:** ${year}` : "**Tahun:** Terbaru",
|
|
48
|
+
"",
|
|
49
|
+
"| Wilayah | Nilai |",
|
|
50
|
+
"| --- | --- |",
|
|
51
|
+
];
|
|
52
|
+
for (const r of results) {
|
|
53
|
+
lines.push(`| ${r.region} | ${r.value} |`);
|
|
54
|
+
}
|
|
55
|
+
// Add analysis hint
|
|
56
|
+
const numericResults = results.filter(r => !isNaN(parseFloat(r.value.replace(",", "."))));
|
|
57
|
+
if (numericResults.length >= 2) {
|
|
58
|
+
const values = numericResults.map(r => ({ region: r.region, val: parseFloat(r.value.replace(",", ".")) }));
|
|
59
|
+
values.sort((a, b) => b.val - a.val);
|
|
60
|
+
lines.push("");
|
|
61
|
+
lines.push(`**Tertinggi:** ${values[0].region} (${values[0].val})`);
|
|
62
|
+
lines.push(`**Terendah:** ${values[values.length - 1].region} (${values[values.length - 1].val})`);
|
|
63
|
+
}
|
|
64
|
+
return { content: [{ type: "text", text: appendAttribution(lines.join("\n")) }] };
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
return { content: [{ type: "text", text: error instanceof Error ? error.message : "Gagal membandingkan data" }], isError: true };
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
// ---------- get_trend ----------
|
|
71
|
+
server.tool("get_trend", `Ambil data time-series (tren multi-tahun) dalam 1 langkah.
|
|
72
|
+
Gunakan tool ini ketika user ingin melihat perkembangan/tren data dari tahun ke tahun.
|
|
73
|
+
|
|
74
|
+
Contoh query user yang cocok untuk tool ini:
|
|
75
|
+
- "tren kemiskinan Indonesia 2019-2023"
|
|
76
|
+
- "perkembangan IPM Jawa Timur 5 tahun terakhir"
|
|
77
|
+
- "bagaimana pengangguran dari 2020 sampai 2024?"
|
|
78
|
+
- "data kemiskinan Jawa Barat dari tahun ke tahun"`, {
|
|
79
|
+
query: z.string().describe("Indikator yang dianalisis (misal: kemiskinan, pengangguran, IPM)"),
|
|
80
|
+
region: z.string().default("Indonesia").describe("Nama wilayah"),
|
|
81
|
+
start_year: z.string().default("2019").describe("Tahun awal"),
|
|
82
|
+
end_year: z.string().default("2024").describe("Tahun akhir"),
|
|
83
|
+
}, async ({ query, region, start_year, end_year }) => {
|
|
84
|
+
try {
|
|
85
|
+
// Resolve domain
|
|
86
|
+
let domain = "0000";
|
|
87
|
+
let domainName = "Indonesia";
|
|
88
|
+
if (region.toLowerCase() !== "indonesia" && region !== "0000") {
|
|
89
|
+
const resolved = await resolver.resolve(region);
|
|
90
|
+
if (!resolved) {
|
|
91
|
+
return { content: [{ type: "text", text: `Wilayah "${region}" tidak ditemukan.` }], isError: true };
|
|
92
|
+
}
|
|
93
|
+
domain = resolved.domainId;
|
|
94
|
+
domainName = resolved.domainName;
|
|
95
|
+
}
|
|
96
|
+
// Find variable
|
|
97
|
+
let varData = await resolveVariable(client, store, query, domain);
|
|
98
|
+
if (!varData) {
|
|
99
|
+
return { content: [{ type: "text", text: appendAttribution(`Tidak ditemukan variabel "${query}" untuk ${domainName}.`) }] };
|
|
100
|
+
}
|
|
101
|
+
// Build year range
|
|
102
|
+
const startNum = parseInt(start_year);
|
|
103
|
+
const endNum = parseInt(end_year);
|
|
104
|
+
const years = [];
|
|
105
|
+
for (let y = startNum; y <= endNum; y++)
|
|
106
|
+
years.push(String(y));
|
|
107
|
+
// Get periods for all years
|
|
108
|
+
let periods = await client.listPeriods(domain, varData.var_id);
|
|
109
|
+
// Fallback: if no periods found, invalidate cached var and do full search
|
|
110
|
+
if (periods.length === 0) {
|
|
111
|
+
await invalidateVar(query, domain, store);
|
|
112
|
+
varData = await resolveVariableFullSearch(client, store, query, domain);
|
|
113
|
+
if (!varData) {
|
|
114
|
+
return { content: [{ type: "text", text: appendAttribution(`Tidak ditemukan variabel "${query}" untuk ${domainName}.`) }] };
|
|
115
|
+
}
|
|
116
|
+
periods = await client.listPeriods(domain, varData.var_id);
|
|
117
|
+
}
|
|
118
|
+
const yearToPeriod = {};
|
|
119
|
+
for (const p of periods) {
|
|
120
|
+
const pAny = p;
|
|
121
|
+
const label = String(pAny.th_name || pAny.th || pAny.label || "");
|
|
122
|
+
const id = String(p.th_id ?? pAny.val);
|
|
123
|
+
for (const y of years) {
|
|
124
|
+
if (label.includes(y))
|
|
125
|
+
yearToPeriod[y] = id;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
const periodIds = years.map(y => yearToPeriod[y]).filter(Boolean);
|
|
129
|
+
if (periodIds.length === 0) {
|
|
130
|
+
return { content: [{ type: "text", text: appendAttribution(`Tidak ada data periode ${start_year}-${end_year} untuk variabel ini.`) }] };
|
|
131
|
+
}
|
|
132
|
+
// Fetch data
|
|
133
|
+
const result = await client.getDynamicData(domain, String(varData.var_id), periodIds.join(","));
|
|
134
|
+
if (!result.datacontent || Object.keys(result.datacontent).length === 0) {
|
|
135
|
+
return { content: [{ type: "text", text: appendAttribution(`Data tidak tersedia untuk periode ${start_year}-${end_year}.`) }] };
|
|
136
|
+
}
|
|
137
|
+
// Parse datacontent — match period IDs to values
|
|
138
|
+
// Build period label map from response
|
|
139
|
+
const periodLabels = {};
|
|
140
|
+
const responsePeriodIds = [];
|
|
141
|
+
if (result.tahun) {
|
|
142
|
+
for (const t of result.tahun) {
|
|
143
|
+
const tAny = t;
|
|
144
|
+
const id = String(t.th_id ?? tAny.val);
|
|
145
|
+
const label = String(t.th_name ?? tAny.label ?? id);
|
|
146
|
+
periodLabels[id] = label;
|
|
147
|
+
responsePeriodIds.push(id);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
// Find the aggregate vervar (national = 9999, or first bold entry for provincial)
|
|
151
|
+
let aggregateVervar = null;
|
|
152
|
+
if (result.vervar) {
|
|
153
|
+
for (const v of result.vervar) {
|
|
154
|
+
const vAny = v;
|
|
155
|
+
const vLabel = String(v.label_vervar ?? vAny.label ?? "");
|
|
156
|
+
const vId = String(v.kode_vervar ?? vAny.val);
|
|
157
|
+
// National aggregate is typically 9999 or has bold label matching domain
|
|
158
|
+
if (vId === "9999" || vLabel.toLowerCase().includes("indonesia")) {
|
|
159
|
+
aggregateVervar = vId;
|
|
160
|
+
break;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
// If no national aggregate found, try bold labels (provincial aggregate)
|
|
164
|
+
if (!aggregateVervar) {
|
|
165
|
+
for (const v of result.vervar) {
|
|
166
|
+
const vAny = v;
|
|
167
|
+
const vLabel = String(v.label_vervar ?? vAny.label ?? "");
|
|
168
|
+
if (vLabel.startsWith("<b>")) {
|
|
169
|
+
aggregateVervar = String(v.kode_vervar ?? vAny.val);
|
|
170
|
+
break;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
// Extract values using proper key matching
|
|
176
|
+
// Sort period IDs longest-first to avoid substring collisions
|
|
177
|
+
const sortedPeriodIds = responsePeriodIds.sort((a, b) => b.length - a.length);
|
|
178
|
+
const trendData = [];
|
|
179
|
+
for (const [key, value] of Object.entries(result.datacontent)) {
|
|
180
|
+
if (typeof value !== "number")
|
|
181
|
+
continue;
|
|
182
|
+
// If we have an aggregate vervar, only match keys containing it
|
|
183
|
+
if (aggregateVervar && !key.includes(aggregateVervar))
|
|
184
|
+
continue;
|
|
185
|
+
// Find which period this key belongs to (longest match first)
|
|
186
|
+
for (const pid of sortedPeriodIds) {
|
|
187
|
+
if (key.includes(pid)) {
|
|
188
|
+
const label = periodLabels[pid] || pid;
|
|
189
|
+
// Only keep periods in our requested year range
|
|
190
|
+
const yearNum = parseInt(label);
|
|
191
|
+
if (yearNum >= parseInt(start_year) && yearNum <= parseInt(end_year)) {
|
|
192
|
+
if (!trendData.some(d => d.year === label)) {
|
|
193
|
+
trendData.push({ year: label, value });
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
break;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
trendData.sort((a, b) => a.year.localeCompare(b.year));
|
|
201
|
+
if (trendData.length === 0) {
|
|
202
|
+
return { content: [{ type: "text", text: appendAttribution(`Data tren tidak dapat di-parse.`) }] };
|
|
203
|
+
}
|
|
204
|
+
// Format output
|
|
205
|
+
const unit = varData.unit && !varData.unit.toLowerCase().includes("tidak ada") ? ` (${varData.unit})` : "";
|
|
206
|
+
const lines = [
|
|
207
|
+
`## Tren ${varData.title}${unit}`,
|
|
208
|
+
`**Wilayah:** ${domainName} | **Periode:** ${start_year}–${end_year}`,
|
|
209
|
+
"",
|
|
210
|
+
"| Tahun | Nilai | Perubahan |",
|
|
211
|
+
"| --- | --- | --- |",
|
|
212
|
+
];
|
|
213
|
+
for (let i = 0; i < trendData.length; i++) {
|
|
214
|
+
const d = trendData[i];
|
|
215
|
+
let change = "-";
|
|
216
|
+
if (i > 0) {
|
|
217
|
+
const diff = d.value - trendData[i - 1].value;
|
|
218
|
+
const pct = ((diff / trendData[i - 1].value) * 100).toFixed(1);
|
|
219
|
+
change = `${diff > 0 ? "+" : ""}${pct}%`;
|
|
220
|
+
}
|
|
221
|
+
lines.push(`| ${d.year} | ${d.value.toLocaleString("id-ID")} | ${change} |`);
|
|
222
|
+
}
|
|
223
|
+
// Summary
|
|
224
|
+
if (trendData.length >= 2) {
|
|
225
|
+
const first = trendData[0].value;
|
|
226
|
+
const last = trendData[trendData.length - 1].value;
|
|
227
|
+
const totalChange = ((last - first) / first * 100).toFixed(1);
|
|
228
|
+
const trend = last > first ? "naik" : last < first ? "turun" : "stabil";
|
|
229
|
+
lines.push("");
|
|
230
|
+
lines.push(`**Tren:** ${trend} ${totalChange}% dari ${trendData[0].year} ke ${trendData[trendData.length - 1].year}`);
|
|
231
|
+
}
|
|
232
|
+
return { content: [{ type: "text", text: appendAttribution(lines.join("\n")) }] };
|
|
233
|
+
}
|
|
234
|
+
catch (error) {
|
|
235
|
+
return { content: [{ type: "text", text: error instanceof Error ? error.message : "Gagal mengambil data tren" }], isError: true };
|
|
236
|
+
}
|
|
237
|
+
});
|
|
238
|
+
// ---------- get_ranking ----------
|
|
239
|
+
server.tool("get_ranking", `Ambil peringkat/ranking provinsi berdasarkan indikator tertentu dalam 1 langkah.
|
|
240
|
+
Gunakan tool ini ketika user ingin melihat peringkat, top-N, atau perbandingan seluruh provinsi.
|
|
241
|
+
|
|
242
|
+
Contoh query user yang cocok untuk tool ini:
|
|
243
|
+
- "10 provinsi termiskin di Indonesia"
|
|
244
|
+
- "peringkat IPM seluruh provinsi"
|
|
245
|
+
- "provinsi dengan pengangguran tertinggi"
|
|
246
|
+
- "ranking kemiskinan per provinsi 2023"
|
|
247
|
+
- "5 provinsi dengan penduduk terbanyak"`, {
|
|
248
|
+
query: z.string().describe("Indikator untuk ranking (misal: kemiskinan, pengangguran, IPM, penduduk)"),
|
|
249
|
+
top_n: z.number().default(10).describe("Jumlah data yang ditampilkan (default 10, max 34 untuk semua provinsi)"),
|
|
250
|
+
order: z.enum(["highest", "lowest"]).default("highest").describe("Urutan: 'highest' (tertinggi dulu) atau 'lowest' (terendah dulu)"),
|
|
251
|
+
year: z.string().optional().describe("Tahun data. Kosongkan untuk terbaru."),
|
|
252
|
+
}, async ({ query, top_n, order, year }) => {
|
|
253
|
+
try {
|
|
254
|
+
// For ranking, we need national-level data that breaks down by province
|
|
255
|
+
// Prefer variables with "Provinsi" in title for proper provincial breakdown
|
|
256
|
+
const varData = await resolveVariableForRanking(client, store, query);
|
|
257
|
+
if (!varData) {
|
|
258
|
+
return { content: [{ type: "text", text: appendAttribution(`Tidak ditemukan variabel "${query}" untuk ranking nasional.`) }] };
|
|
259
|
+
}
|
|
260
|
+
// Get latest period
|
|
261
|
+
let periodParam;
|
|
262
|
+
if (year) {
|
|
263
|
+
const periods = await client.listPeriods("0000", varData.var_id);
|
|
264
|
+
for (const p of periods) {
|
|
265
|
+
const pAny = p;
|
|
266
|
+
const label = String(pAny.th_name || pAny.th || pAny.label || "");
|
|
267
|
+
if (label.includes(year)) {
|
|
268
|
+
periodParam = String(p.th_id ?? pAny.val);
|
|
269
|
+
break;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
if (!periodParam) {
|
|
274
|
+
const periods = await client.listPeriods("0000", varData.var_id);
|
|
275
|
+
if (periods.length > 0) {
|
|
276
|
+
const pAny = periods[0];
|
|
277
|
+
periodParam = String(periods[0].th_id ?? pAny.val);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
const result = await client.getDynamicData("0000", String(varData.var_id), periodParam);
|
|
281
|
+
if (!result.datacontent || Object.keys(result.datacontent).length === 0) {
|
|
282
|
+
return { content: [{ type: "text", text: appendAttribution(`Data ranking tidak tersedia.`) }] };
|
|
283
|
+
}
|
|
284
|
+
// Build vervar (province) label map — prefer provincial level only
|
|
285
|
+
const vervarLabels = {};
|
|
286
|
+
const allVervarLabels = {};
|
|
287
|
+
if (result.vervar) {
|
|
288
|
+
for (const v of result.vervar) {
|
|
289
|
+
const vAny = v;
|
|
290
|
+
const id = String(v.kode_vervar ?? vAny.val);
|
|
291
|
+
const label = String(v.label_vervar ?? vAny.label ?? id);
|
|
292
|
+
allVervarLabels[id] = label;
|
|
293
|
+
// Provincial entries have bold labels or are 4-digit codes ending in 00
|
|
294
|
+
if (label.startsWith("<b>") && !label.toLowerCase().includes("indonesia")) {
|
|
295
|
+
vervarLabels[id] = label.replace(/<\/?b>/g, "");
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
// If no bold entries found, use all (the variable is already at province level)
|
|
300
|
+
const useLabels = Object.keys(vervarLabels).length >= 10 ? vervarLabels : allVervarLabels;
|
|
301
|
+
// Extract province-level data
|
|
302
|
+
const rankings = [];
|
|
303
|
+
// Sort vervar IDs longest-first to avoid substring collisions
|
|
304
|
+
const vervarIds = Object.keys(useLabels).sort((a, b) => b.length - a.length);
|
|
305
|
+
for (const [key, value] of Object.entries(result.datacontent)) {
|
|
306
|
+
if (typeof value !== "number")
|
|
307
|
+
continue;
|
|
308
|
+
for (const vId of vervarIds) {
|
|
309
|
+
if (key.includes(vId) && !rankings.some(r => r.province === useLabels[vId])) {
|
|
310
|
+
const label = useLabels[vId].replace(/<\/?b>/g, "");
|
|
311
|
+
rankings.push({ province: label, value });
|
|
312
|
+
break;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
if (rankings.length === 0) {
|
|
317
|
+
return { content: [{ type: "text", text: appendAttribution(`Data ranking tidak dapat di-parse. Coba gunakan find_data untuk masing-masing wilayah.`) }] };
|
|
318
|
+
}
|
|
319
|
+
// Sort
|
|
320
|
+
rankings.sort((a, b) => order === "highest" ? b.value - a.value : a.value - b.value);
|
|
321
|
+
const display = rankings.slice(0, Math.min(top_n, rankings.length));
|
|
322
|
+
// Format
|
|
323
|
+
const unit = varData.unit && !varData.unit.toLowerCase().includes("tidak ada") ? ` (${varData.unit})` : "";
|
|
324
|
+
const lines = [
|
|
325
|
+
`## Ranking: ${varData.title}${unit}`,
|
|
326
|
+
`**Urutan:** ${order === "highest" ? "Tertinggi" : "Terendah"} | **Tahun:** ${year || "Terbaru"}`,
|
|
327
|
+
"",
|
|
328
|
+
"| # | Wilayah | Nilai |",
|
|
329
|
+
"| --- | --- | --- |",
|
|
330
|
+
];
|
|
331
|
+
for (let i = 0; i < display.length; i++) {
|
|
332
|
+
lines.push(`| ${i + 1} | ${display[i].province} | ${display[i].value.toLocaleString("id-ID")} |`);
|
|
333
|
+
}
|
|
334
|
+
if (rankings.length > display.length) {
|
|
335
|
+
lines.push("");
|
|
336
|
+
lines.push(`_Menampilkan ${display.length} dari ${rankings.length} wilayah._`);
|
|
337
|
+
}
|
|
338
|
+
return { content: [{ type: "text", text: appendAttribution(lines.join("\n")) }] };
|
|
339
|
+
}
|
|
340
|
+
catch (error) {
|
|
341
|
+
return { content: [{ type: "text", text: error instanceof Error ? error.message : "Gagal mengambil data ranking" }], isError: true };
|
|
342
|
+
}
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
// --- Helper functions ---
|
|
346
|
+
/** Resolve variable for a domain using learning store + full search fallback. */
|
|
347
|
+
async function resolveVariable(client, store, query, domain) {
|
|
348
|
+
// Try learning store first
|
|
349
|
+
const learned = await lookupVar(query, domain, store);
|
|
350
|
+
if (learned)
|
|
351
|
+
return learned;
|
|
352
|
+
// Full search
|
|
353
|
+
const kw = normalizeKeyword(query);
|
|
354
|
+
const KEYWORD_SUBJECTS = {
|
|
355
|
+
pengangguran: [6], tenaga: [6], kerja: [6], tpt: [6],
|
|
356
|
+
miskin: [23], kemiskinan: [23], gini: [23], ketimpangan: [23],
|
|
357
|
+
penduduk: [12], kependudukan: [12],
|
|
358
|
+
inflasi: [3], harga: [3], ihk: [3],
|
|
359
|
+
pdrb: [52], ekonomi: [52, 35], pertumbuhan: [52],
|
|
360
|
+
ipm: [26], pembangunan: [26],
|
|
361
|
+
ekspor: [8], impor: [8],
|
|
362
|
+
};
|
|
363
|
+
const subjectIds = [];
|
|
364
|
+
for (const [keyword, ids] of Object.entries(KEYWORD_SUBJECTS)) {
|
|
365
|
+
if (kw.includes(keyword))
|
|
366
|
+
subjectIds.push(...ids);
|
|
367
|
+
}
|
|
368
|
+
// Also match from subject titles
|
|
369
|
+
const subjects = await client.listSubjects(domain);
|
|
370
|
+
for (const s of subjects.data) {
|
|
371
|
+
if (kw.split(/\s+/).some(w => w.length > 2 && s.title.toLowerCase().includes(w))) {
|
|
372
|
+
if (!subjectIds.includes(s.sub_id))
|
|
373
|
+
subjectIds.push(s.sub_id);
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
// Expand search terms with synonyms
|
|
377
|
+
const SEARCH_SYNONYMS = {
|
|
378
|
+
ipm: ["ipm", "pembangunan manusia", "indeks pembangunan"],
|
|
379
|
+
tpt: ["tpt", "pengangguran terbuka"],
|
|
380
|
+
gini: ["gini", "gini rasio"],
|
|
381
|
+
};
|
|
382
|
+
const searchTerms = SEARCH_SYNONYMS[kw] || [kw];
|
|
383
|
+
for (const subId of subjectIds.slice(0, 3)) {
|
|
384
|
+
const result = await client.listVariables(domain, subId, undefined, 1, 100);
|
|
385
|
+
if (!result.data)
|
|
386
|
+
continue;
|
|
387
|
+
const candidates = [];
|
|
388
|
+
for (const v of result.data) {
|
|
389
|
+
const titleLower = v.title.toLowerCase();
|
|
390
|
+
const matches = searchTerms.some(term => titleLower.includes(term)) ||
|
|
391
|
+
kw.split(/\s+/).some(w => w.length > 2 && titleLower.includes(w));
|
|
392
|
+
if (matches) {
|
|
393
|
+
candidates.push({ var_id: v.var_id, title: v.title, sub_name: v.sub_name, unit: v.unit });
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
if (candidates.length > 0) {
|
|
397
|
+
// Score candidates: prefer non-lama, prefer kabupaten/provinsi, deprioritize disaggregated
|
|
398
|
+
candidates.sort((a, b) => {
|
|
399
|
+
const t = (x) => x.title.toLowerCase();
|
|
400
|
+
const score = (x) => {
|
|
401
|
+
let s = 0;
|
|
402
|
+
if (t(x).includes("metode lama"))
|
|
403
|
+
s += 10;
|
|
404
|
+
if (t(x).includes("metode baru"))
|
|
405
|
+
s -= 2;
|
|
406
|
+
// Prefer variables with kabupaten/kota or provinsi (have aggregate)
|
|
407
|
+
if (t(x).includes("kabupaten") || t(x).includes("provinsi"))
|
|
408
|
+
s -= 3;
|
|
409
|
+
// Deprioritize disaggregated variants
|
|
410
|
+
if (t(x).includes("golongan umur") || t(x).includes("lapangan usaha") || t(x).includes("klasifikasi") || t(x).includes("pendidikan tertinggi"))
|
|
411
|
+
s += 5;
|
|
412
|
+
return s;
|
|
413
|
+
};
|
|
414
|
+
return score(a) - score(b);
|
|
415
|
+
});
|
|
416
|
+
const found = candidates[0];
|
|
417
|
+
await learnVar(query, domain, found, store);
|
|
418
|
+
return found;
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
return null;
|
|
422
|
+
}
|
|
423
|
+
/** Fetch a single data value for a domain+query+year. */
|
|
424
|
+
async function fetchDataForDomain(client, store, query, domain, year) {
|
|
425
|
+
let varData = await resolveVariable(client, store, query, domain);
|
|
426
|
+
if (!varData)
|
|
427
|
+
return { value: "N/A", varTitle: "" };
|
|
428
|
+
// Resolve period
|
|
429
|
+
let periodParam;
|
|
430
|
+
let periods = await client.listPeriods(domain, varData.var_id);
|
|
431
|
+
// Fallback: if no periods, invalidate and do full search
|
|
432
|
+
if (periods.length === 0) {
|
|
433
|
+
await invalidateVar(query, domain, store);
|
|
434
|
+
varData = await resolveVariableFullSearch(client, store, query, domain);
|
|
435
|
+
if (!varData)
|
|
436
|
+
return { value: "N/A", varTitle: "" };
|
|
437
|
+
periods = await client.listPeriods(domain, varData.var_id);
|
|
438
|
+
}
|
|
439
|
+
if (year && periods.length > 0) {
|
|
440
|
+
for (const p of periods) {
|
|
441
|
+
const pAny = p;
|
|
442
|
+
const label = String(pAny.th_name || pAny.th || pAny.label || "");
|
|
443
|
+
if (label.includes(year)) {
|
|
444
|
+
periodParam = String(p.th_id ?? pAny.val);
|
|
445
|
+
break;
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
// If requested year not found, try full search for a variable that has it
|
|
449
|
+
if (!periodParam) {
|
|
450
|
+
await invalidateVar(query, domain, store);
|
|
451
|
+
varData = await resolveVariableFullSearch(client, store, query, domain);
|
|
452
|
+
if (!varData)
|
|
453
|
+
return { value: "N/A", varTitle: "" };
|
|
454
|
+
periods = await client.listPeriods(domain, varData.var_id);
|
|
455
|
+
for (const p of periods) {
|
|
456
|
+
const pAny = p;
|
|
457
|
+
const label = String(pAny.th_name || pAny.th || pAny.label || "");
|
|
458
|
+
if (label.includes(year)) {
|
|
459
|
+
periodParam = String(p.th_id ?? pAny.val);
|
|
460
|
+
break;
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
if (!periodParam && periods.length > 0) {
|
|
466
|
+
const pAny = periods[0];
|
|
467
|
+
periodParam = String(periods[0].th_id ?? pAny.val);
|
|
468
|
+
}
|
|
469
|
+
const result = await client.getDynamicData(domain, String(varData.var_id), periodParam);
|
|
470
|
+
if (!result.datacontent || Object.keys(result.datacontent).length === 0) {
|
|
471
|
+
return { value: "N/A", varTitle: varData.title };
|
|
472
|
+
}
|
|
473
|
+
// Find the aggregate vervar for this domain
|
|
474
|
+
let aggregateVervar = null;
|
|
475
|
+
if (result.vervar) {
|
|
476
|
+
for (const v of result.vervar) {
|
|
477
|
+
const vAny = v;
|
|
478
|
+
const vId = String(v.kode_vervar ?? vAny.val);
|
|
479
|
+
const vLabel = String(v.label_vervar ?? vAny.label ?? "");
|
|
480
|
+
// National: 9999 = INDONESIA
|
|
481
|
+
if (vId === "9999" || vLabel.toLowerCase().includes("indonesia")) {
|
|
482
|
+
aggregateVervar = vId;
|
|
483
|
+
break;
|
|
484
|
+
}
|
|
485
|
+
// Provincial: domain + "99" pattern (e.g., 3699 for domain 3600)
|
|
486
|
+
if (domain !== "0000" && (vId === domain.slice(0, 2) + "99" || vId === domain.slice(0, 4) + "0" || vLabel.startsWith("<b>") || vLabel.toLowerCase().includes("provinsi"))) {
|
|
487
|
+
aggregateVervar = vId;
|
|
488
|
+
break;
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
// Extract the aggregate value
|
|
493
|
+
let val = null;
|
|
494
|
+
if (aggregateVervar) {
|
|
495
|
+
for (const [key, value] of Object.entries(result.datacontent)) {
|
|
496
|
+
if (typeof value === "number" && key.includes(aggregateVervar)) {
|
|
497
|
+
val = value;
|
|
498
|
+
break;
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
// Fallback: first numeric value
|
|
503
|
+
if (val === null) {
|
|
504
|
+
const values = Object.values(result.datacontent).filter(v => typeof v === "number");
|
|
505
|
+
if (values.length === 0)
|
|
506
|
+
return { value: "N/A", varTitle: varData.title };
|
|
507
|
+
val = values[0];
|
|
508
|
+
}
|
|
509
|
+
const unit = varData.unit && !varData.unit.toLowerCase().includes("tidak ada") ? ` ${varData.unit}` : "";
|
|
510
|
+
return { value: `${val.toLocaleString("id-ID")}${unit}`, varTitle: varData.title };
|
|
511
|
+
}
|
|
512
|
+
/** Resolve variable bypassing KNOWN_VARS/store — full API search only. */
|
|
513
|
+
async function resolveVariableFullSearch(client, store, query, domain) {
|
|
514
|
+
const kw = normalizeKeyword(query);
|
|
515
|
+
const KEYWORD_SUBJECTS = {
|
|
516
|
+
pengangguran: [6], tenaga: [6], kerja: [6], tpt: [6],
|
|
517
|
+
miskin: [23], kemiskinan: [23], gini: [23], ketimpangan: [23],
|
|
518
|
+
penduduk: [12], kependudukan: [12],
|
|
519
|
+
inflasi: [3], harga: [3], ihk: [3],
|
|
520
|
+
pdrb: [52], ekonomi: [52, 35], pertumbuhan: [52],
|
|
521
|
+
ipm: [26], pembangunan: [26],
|
|
522
|
+
ekspor: [8], impor: [8],
|
|
523
|
+
};
|
|
524
|
+
const subjectIds = [];
|
|
525
|
+
for (const [keyword, ids] of Object.entries(KEYWORD_SUBJECTS)) {
|
|
526
|
+
if (kw.includes(keyword))
|
|
527
|
+
subjectIds.push(...ids);
|
|
528
|
+
}
|
|
529
|
+
const subjects = await client.listSubjects(domain);
|
|
530
|
+
for (const s of subjects.data) {
|
|
531
|
+
if (kw.split(/\s+/).some(w => w.length > 2 && s.title.toLowerCase().includes(w))) {
|
|
532
|
+
if (!subjectIds.includes(s.sub_id))
|
|
533
|
+
subjectIds.push(s.sub_id);
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
for (const subId of subjectIds.slice(0, 3)) {
|
|
537
|
+
const result = await client.listVariables(domain, subId, undefined, 1, 100);
|
|
538
|
+
if (!result.data)
|
|
539
|
+
continue;
|
|
540
|
+
const candidates = [];
|
|
541
|
+
const SEARCH_SYNONYMS = {
|
|
542
|
+
ipm: ["ipm", "pembangunan manusia", "indeks pembangunan"],
|
|
543
|
+
tpt: ["tpt", "pengangguran terbuka"],
|
|
544
|
+
gini: ["gini", "gini rasio"],
|
|
545
|
+
};
|
|
546
|
+
const searchTerms = SEARCH_SYNONYMS[kw] || [kw];
|
|
547
|
+
for (const v of result.data) {
|
|
548
|
+
const titleLower = v.title.toLowerCase();
|
|
549
|
+
const matches = searchTerms.some(term => titleLower.includes(term)) ||
|
|
550
|
+
kw.split(/\s+/).some(w => w.length > 2 && titleLower.includes(w));
|
|
551
|
+
if (matches && !titleLower.includes("metode lama")) {
|
|
552
|
+
candidates.push({ var_id: v.var_id, title: v.title, sub_name: v.sub_name, unit: v.unit });
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
// Pick the first candidate that has periods
|
|
556
|
+
for (const c of candidates) {
|
|
557
|
+
const periods = await client.listPeriods(domain, c.var_id);
|
|
558
|
+
if (periods.length === 0)
|
|
559
|
+
continue;
|
|
560
|
+
await learnVar(query, domain, c, store);
|
|
561
|
+
return c;
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
return null;
|
|
565
|
+
}
|
|
566
|
+
/** Resolve variable for ranking — prefer "Menurut Provinsi" variants at national level. */
|
|
567
|
+
async function resolveVariableForRanking(client, store, query) {
|
|
568
|
+
const kw = normalizeKeyword(query);
|
|
569
|
+
const kwWords = kw.split(/\s+/).filter(w => w.length > 2);
|
|
570
|
+
// Add root words for common Indonesian affixes: ke-...-an → root
|
|
571
|
+
const roots = [...kwWords];
|
|
572
|
+
for (const w of kwWords) {
|
|
573
|
+
if (w.startsWith("ke") && w.endsWith("an") && w.length > 6)
|
|
574
|
+
roots.push(w.slice(2, -2));
|
|
575
|
+
if (w.startsWith("pe") && w.endsWith("an") && w.length > 6)
|
|
576
|
+
roots.push(w.slice(2, -2));
|
|
577
|
+
if (w.endsWith("an") && w.length > 5)
|
|
578
|
+
roots.push(w.slice(0, -2));
|
|
579
|
+
}
|
|
580
|
+
// Add synonym expansions
|
|
581
|
+
const RANKING_SYNONYMS = {
|
|
582
|
+
ipm: ["ipm", "pembangunan manusia"],
|
|
583
|
+
tpt: ["tpt", "pengangguran terbuka"],
|
|
584
|
+
gini: ["gini", "gini rasio"],
|
|
585
|
+
};
|
|
586
|
+
const synonyms = RANKING_SYNONYMS[kw] || [];
|
|
587
|
+
const matchesTitle = (t) => roots.some(r => t.includes(r)) || synonyms.some(s => t.includes(s));
|
|
588
|
+
const KEYWORD_SUBJECTS = {
|
|
589
|
+
miskin: [23], kemiskinan: [23], gini: [23],
|
|
590
|
+
pengangguran: [6], tpt: [6],
|
|
591
|
+
penduduk: [12], ipm: [26],
|
|
592
|
+
};
|
|
593
|
+
const subjectIds = [];
|
|
594
|
+
for (const [keyword, ids] of Object.entries(KEYWORD_SUBJECTS)) {
|
|
595
|
+
if (kw.includes(keyword))
|
|
596
|
+
subjectIds.push(...ids);
|
|
597
|
+
}
|
|
598
|
+
if (subjectIds.length === 0)
|
|
599
|
+
subjectIds.push(23, 6, 12, 26);
|
|
600
|
+
// Search for variables with "Provinsi" in title
|
|
601
|
+
for (const subId of subjectIds.slice(0, 3)) {
|
|
602
|
+
const result = await client.listVariables("0000", subId, undefined, 1, 100);
|
|
603
|
+
if (!result.data)
|
|
604
|
+
continue;
|
|
605
|
+
// First pass: find one with "Provinsi" AND matching keyword AND recent data
|
|
606
|
+
for (const v of result.data) {
|
|
607
|
+
const t = v.title.toLowerCase();
|
|
608
|
+
if (t.includes("provinsi") && matchesTitle(t) && !t.includes("metode lama")) {
|
|
609
|
+
if (t.includes("persentase") || t.includes("tingkat") || t.includes("indeks")) {
|
|
610
|
+
// Validate has recent data (at least 2020+)
|
|
611
|
+
const periods = await client.listPeriods("0000", v.var_id);
|
|
612
|
+
const hasRecent = periods.some(p => {
|
|
613
|
+
const pAny = p;
|
|
614
|
+
const label = String(pAny.th_name || pAny.th || pAny.label || "");
|
|
615
|
+
return parseInt(label) >= 2020;
|
|
616
|
+
});
|
|
617
|
+
if (hasRecent)
|
|
618
|
+
return { var_id: v.var_id, title: v.title, sub_name: v.sub_name, unit: v.unit };
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
// Second pass: "Provinsi" + keyword match (any) with recent data
|
|
623
|
+
for (const v of result.data) {
|
|
624
|
+
const t = v.title.toLowerCase();
|
|
625
|
+
if (t.includes("provinsi") && matchesTitle(t) && !t.includes("metode lama")) {
|
|
626
|
+
const periods = await client.listPeriods("0000", v.var_id);
|
|
627
|
+
const hasRecent = periods.some(p => {
|
|
628
|
+
const pAny = p;
|
|
629
|
+
const label = String(pAny.th_name || pAny.th || pAny.label || "");
|
|
630
|
+
return parseInt(label) >= 2020;
|
|
631
|
+
});
|
|
632
|
+
if (hasRecent)
|
|
633
|
+
return { var_id: v.var_id, title: v.title, sub_name: v.sub_name, unit: v.unit };
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
// Second pass: any match without "Provinsi" requirement
|
|
637
|
+
for (const v of result.data) {
|
|
638
|
+
const t = v.title.toLowerCase();
|
|
639
|
+
if (t.includes(kw) || kw.split(/\s+/).some(w => w.length > 2 && t.includes(w))) {
|
|
640
|
+
return { var_id: v.var_id, title: v.title, sub_name: v.sub_name, unit: v.unit };
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
// Fallback to general resolver
|
|
645
|
+
return resolveVariable(client, store, query, "0000");
|
|
646
|
+
}
|
|
647
|
+
//# sourceMappingURL=analysis.tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analysis.tools.js","sourceRoot":"","sources":["../../src/tools/analysis.tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AAM3B,OAAO,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAE/F;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CACnC,MAAiB,EACjB,MAAiB,EACjB,QAAwB,EACxB,MAAc,EACd,KAA8B;IAE9B,qCAAqC;IACrC,MAAM,CAAC,IAAI,CACT,cAAc,EACd;;;;;;;wDAOoD,EACpD;QACE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,8EAA8E,CAAC;QAC1G,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,0EAA0E,CAAC;QACxG,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,2DAA2D,CAAC;KAClG,EACD,KAAK,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE;QACjC,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YACzE,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC1B,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,uCAAuC,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;YACvG,CAAC;YAED,MAAM,OAAO,GAA+E,EAAE,CAAC;YAE/F,KAAK,MAAM,UAAU,IAAI,UAAU,EAAE,CAAC;gBACpC,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;gBACpD,IAAI,CAAC,QAAQ,EAAE,CAAC;oBACd,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,yBAAyB,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;oBAClG,SAAS;gBACX,CAAC;gBAED,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,GAAG,QAAQ,CAAC;gBAC1C,MAAM,IAAI,GAAG,MAAM,kBAAkB,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;gBAC5E,OAAO,CAAC,IAAI,CAAC;oBACX,MAAM,EAAE,UAAU;oBAClB,MAAM,EAAE,QAAQ;oBAChB,KAAK,EAAE,IAAI,CAAC,KAAK;oBACjB,QAAQ,EAAE,IAAI,CAAC,QAAQ;iBACxB,CAAC,CAAC;YACL,CAAC;YAED,gBAAgB;YAChB,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,QAAQ,IAAI,KAAK,CAAC;YAClE,MAAM,KAAK,GAAG;gBACZ,oBAAoB,QAAQ,EAAE;gBAC9B,IAAI,CAAC,CAAC,CAAC,cAAc,IAAI,EAAE,CAAC,CAAC,CAAC,oBAAoB;gBAClD,EAAE;gBACF,qBAAqB;gBACrB,eAAe;aAChB,CAAC;YAEF,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;gBACxB,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,MAAM,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;YAC7C,CAAC;YAED,oBAAoB;YACpB,MAAM,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YAC1F,IAAI,cAAc,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;gBAC/B,MAAM,MAAM,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,GAAG,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;gBAC3G,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;gBACrC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBACf,KAAK,CAAC,IAAI,CAAC,kBAAkB,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;gBACpE,KAAK,CAAC,IAAI,CAAC,iBAAiB,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;YACrG,CAAC;YAED,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;QACpF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,0BAA0B,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QACnI,CAAC;IACH,CAAC,CACF,CAAC;IAEF,kCAAkC;IAClC,MAAM,CAAC,IAAI,CACT,WAAW,EACX;;;;;;;mDAO+C,EAC/C;QACE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,kEAAkE,CAAC;QAC9F,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,QAAQ,CAAC,cAAc,CAAC;QAChE,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC;QAC7D,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC;KAC7D,EACD,KAAK,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,EAAE;QAChD,IAAI,CAAC;YACH,iBAAiB;YACjB,IAAI,MAAM,GAAG,MAAM,CAAC;YACpB,IAAI,UAAU,GAAG,WAAW,CAAC;YAC7B,IAAI,MAAM,CAAC,WAAW,EAAE,KAAK,WAAW,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;gBAC9D,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;gBAChD,IAAI,CAAC,QAAQ,EAAE,CAAC;oBACd,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,MAAM,oBAAoB,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;gBACtG,CAAC;gBACD,MAAM,GAAG,QAAQ,CAAC,QAAQ,CAAC;gBAC3B,UAAU,GAAG,QAAQ,CAAC,UAAU,CAAC;YACnC,CAAC;YAED,gBAAgB;YAChB,IAAI,OAAO,GAAG,MAAM,eAAe,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;YAClE,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,CAAC,6BAA6B,KAAK,WAAW,UAAU,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;YAC9H,CAAC;YAED,mBAAmB;YACnB,MAAM,QAAQ,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC;YACtC,MAAM,MAAM,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;YAClC,MAAM,KAAK,GAAa,EAAE,CAAC;YAC3B,KAAK,IAAI,CAAC,GAAG,QAAQ,EAAE,CAAC,IAAI,MAAM,EAAE,CAAC,EAAE;gBAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;YAE/D,4BAA4B;YAC5B,IAAI,OAAO,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;YAE/D,0EAA0E;YAC1E,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACzB,MAAM,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;gBAC1C,OAAO,GAAG,MAAM,yBAAyB,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;gBACxE,IAAI,CAAC,OAAO,EAAE,CAAC;oBACb,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,CAAC,6BAA6B,KAAK,WAAW,UAAU,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;gBAC9H,CAAC;gBACD,OAAO,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;YAC7D,CAAC;YAED,MAAM,YAAY,GAA2B,EAAE,CAAC;YAChD,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;gBACxB,MAAM,IAAI,GAAG,CAAuC,CAAC;gBACrD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;gBAClE,MAAM,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;gBACvC,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;oBACtB,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;wBAAE,YAAY,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;gBAC9C,CAAC;YACH,CAAC;YAED,MAAM,SAAS,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YAClE,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC3B,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,CAAC,0BAA0B,UAAU,IAAI,QAAQ,sBAAsB,CAAC,EAAE,CAAC,EAAE,CAAC;YAC1I,CAAC;YAED,aAAa;YACb,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;YAChG,IAAI,CAAC,MAAM,CAAC,WAAW,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACxE,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,CAAC,qCAAqC,UAAU,IAAI,QAAQ,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;YAClI,CAAC;YAED,iDAAiD;YACjD,uCAAuC;YACvC,MAAM,YAAY,GAA2B,EAAE,CAAC;YAChD,MAAM,iBAAiB,GAAa,EAAE,CAAC;YACvC,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;gBACjB,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;oBAC7B,MAAM,IAAI,GAAG,CAAuC,CAAC;oBACrD,MAAM,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;oBACvC,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,OAAO,IAAI,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;oBACpD,YAAY,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC;oBACzB,iBAAiB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBAC7B,CAAC;YACH,CAAC;YAED,kFAAkF;YAClF,IAAI,eAAe,GAAkB,IAAI,CAAC;YAC1C,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;gBAClB,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;oBAC9B,MAAM,IAAI,GAAG,CAAuC,CAAC;oBACrD,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,YAAY,IAAI,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;oBAC1D,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,WAAW,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;oBAC9C,yEAAyE;oBACzE,IAAI,GAAG,KAAK,MAAM,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;wBACjE,eAAe,GAAG,GAAG,CAAC;wBACtB,MAAM;oBACR,CAAC;gBACH,CAAC;gBACD,yEAAyE;gBACzE,IAAI,CAAC,eAAe,EAAE,CAAC;oBACrB,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;wBAC9B,MAAM,IAAI,GAAG,CAAuC,CAAC;wBACrD,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,YAAY,IAAI,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;wBAC1D,IAAI,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;4BAC7B,eAAe,GAAG,MAAM,CAAC,CAAC,CAAC,WAAW,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;4BACpD,MAAM;wBACR,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC;YAED,2CAA2C;YAC3C,8DAA8D;YAC9D,MAAM,eAAe,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC;YAC9E,MAAM,SAAS,GAA2C,EAAE,CAAC;YAE7D,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC;gBAC9D,IAAI,OAAO,KAAK,KAAK,QAAQ;oBAAE,SAAS;gBACxC,gEAAgE;gBAChE,IAAI,eAAe,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,eAAe,CAAC;oBAAE,SAAS;gBAChE,8DAA8D;gBAC9D,KAAK,MAAM,GAAG,IAAI,eAAe,EAAE,CAAC;oBAClC,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;wBACtB,MAAM,KAAK,GAAG,YAAY,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC;wBACvC,gDAAgD;wBAChD,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;wBAChC,IAAI,OAAO,IAAI,QAAQ,CAAC,UAAU,CAAC,IAAI,OAAO,IAAI,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;4BACrE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;gCAC3C,SAAS,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;4BACzC,CAAC;wBACH,CAAC;wBACD,MAAM;oBACR,CAAC;gBACH,CAAC;YACH,CAAC;YAED,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;YAEvD,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC3B,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,CAAC,iCAAiC,CAAC,EAAE,CAAC,EAAE,CAAC;YACrG,CAAC;YAED,gBAAgB;YAChB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3G,MAAM,KAAK,GAAG;gBACZ,WAAW,OAAO,CAAC,KAAK,GAAG,IAAI,EAAE;gBACjC,gBAAgB,UAAU,mBAAmB,UAAU,IAAI,QAAQ,EAAE;gBACrE,EAAE;gBACF,+BAA+B;gBAC/B,qBAAqB;aACtB,CAAC;YAEF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC1C,MAAM,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;gBACvB,IAAI,MAAM,GAAG,GAAG,CAAC;gBACjB,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;oBACV,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,GAAG,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC;oBAC9C,MAAM,GAAG,GAAG,CAAC,CAAC,IAAI,GAAG,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;oBAC/D,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,GAAG,GAAG,CAAC;gBAC3C,CAAC;gBACD,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,MAAM,MAAM,IAAI,CAAC,CAAC;YAC/E,CAAC;YAED,UAAU;YACV,IAAI,SAAS,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;gBAC1B,MAAM,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;gBACjC,MAAM,IAAI,GAAG,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC;gBACnD,MAAM,WAAW,GAAG,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC,GAAG,KAAK,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;gBAC9D,MAAM,KAAK,GAAG,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC;gBACxE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBACf,KAAK,CAAC,IAAI,CAAC,aAAa,KAAK,IAAI,WAAW,UAAU,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,OAAO,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;YACxH,CAAC;YAED,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;QACpF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,2BAA2B,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QACpI,CAAC;IACH,CAAC,CACF,CAAC;IAEF,oCAAoC;IACpC,MAAM,CAAC,IAAI,CACT,aAAa,EACb;;;;;;;;yCAQqC,EACrC;QACE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,0EAA0E,CAAC;QACtG,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,wEAAwE,CAAC;QAChH,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,kEAAkE,CAAC;QACpI,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,sCAAsC,CAAC;KAC7E,EACD,KAAK,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE;QACtC,IAAI,CAAC;YACH,wEAAwE;YACxE,4EAA4E;YAC5E,MAAM,OAAO,GAAG,MAAM,yBAAyB,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;YACtE,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,CAAC,6BAA6B,KAAK,2BAA2B,CAAC,EAAE,CAAC,EAAE,CAAC;YACjI,CAAC;YAED,oBAAoB;YACpB,IAAI,WAA+B,CAAC;YACpC,IAAI,IAAI,EAAE,CAAC;gBACT,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;gBACjE,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;oBACxB,MAAM,IAAI,GAAG,CAAuC,CAAC;oBACrD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;oBAClE,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;wBACzB,WAAW,GAAG,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;wBAC1C,MAAM;oBACR,CAAC;gBACH,CAAC;YACH,CAAC;YACD,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;gBACjE,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBACvB,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAuC,CAAC;oBAC9D,WAAW,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;gBACrD,CAAC;YACH,CAAC;YAED,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC,CAAC;YACxF,IAAI,CAAC,MAAM,CAAC,WAAW,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACxE,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,CAAC,8BAA8B,CAAC,EAAE,CAAC,EAAE,CAAC;YAClG,CAAC;YAED,mEAAmE;YACnE,MAAM,YAAY,GAA2B,EAAE,CAAC;YAChD,MAAM,eAAe,GAA2B,EAAE,CAAC;YACnD,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;gBAClB,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;oBAC9B,MAAM,IAAI,GAAG,CAAuC,CAAC;oBACrD,MAAM,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC,WAAW,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;oBAC7C,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,YAAY,IAAI,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;oBACzD,eAAe,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC;oBAC5B,wEAAwE;oBACxE,IAAI,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;wBAC1E,YAAY,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;oBAClD,CAAC;gBACH,CAAC;YACH,CAAC;YACD,gFAAgF;YAChF,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,eAAe,CAAC;YAE1F,8BAA8B;YAC9B,MAAM,QAAQ,GAA+C,EAAE,CAAC;YAChE,8DAA8D;YAC9D,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC;YAC7E,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC;gBAC9D,IAAI,OAAO,KAAK,KAAK,QAAQ;oBAAE,SAAS;gBACxC,KAAK,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;oBAC5B,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,SAAS,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;wBAC5E,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;wBACpD,QAAQ,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;wBAC1C,MAAM;oBACR,CAAC;gBACH,CAAC;YACH,CAAC;YAED,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC1B,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,CAAC,wFAAwF,CAAC,EAAE,CAAC,EAAE,CAAC;YAC5J,CAAC;YAED,OAAO;YACP,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;YACrF,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;YAEpE,SAAS;YACT,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3G,MAAM,KAAK,GAAG;gBACZ,eAAe,OAAO,CAAC,KAAK,GAAG,IAAI,EAAE;gBACrC,eAAe,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,UAAU,iBAAiB,IAAI,IAAI,SAAS,EAAE;gBACjG,EAAE;gBACF,yBAAyB;gBACzB,qBAAqB;aACtB,CAAC;YAEF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACxC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,MAAM,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YACpG,CAAC;YAED,IAAI,QAAQ,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;gBACrC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBACf,KAAK,CAAC,IAAI,CAAC,gBAAgB,OAAO,CAAC,MAAM,SAAS,QAAQ,CAAC,MAAM,YAAY,CAAC,CAAC;YACjF,CAAC;YAED,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,iBAAiB,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;QACpF,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,8BAA8B,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QACvI,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC;AAED,2BAA2B;AAE3B,iFAAiF;AACjF,KAAK,UAAU,eAAe,CAC5B,MAAiB,EACjB,KAA8B,EAC9B,KAAa,EACb,MAAc;IAEd,2BAA2B;IAC3B,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;IACtD,IAAI,OAAO;QAAE,OAAO,OAAO,CAAC;IAE5B,cAAc;IACd,MAAM,EAAE,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;IACnC,MAAM,gBAAgB,GAA6B;QACjD,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;QACpD,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC;QAC7D,QAAQ,EAAE,CAAC,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,CAAC;QAClC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;QAClC,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC;QAChD,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC;QAC5B,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;KACxB,CAAC;IAEF,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,KAAK,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,EAAE,CAAC;QAC9D,IAAI,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC;YAAE,UAAU,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC;IACpD,CAAC;IAED,iCAAiC;IACjC,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;IACnD,KAAK,MAAM,CAAC,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC;QAC9B,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACjF,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC;gBAAE,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAChE,CAAC;IACH,CAAC;IAED,oCAAoC;IACpC,MAAM,eAAe,GAA6B;QAChD,GAAG,EAAE,CAAC,KAAK,EAAE,qBAAqB,EAAE,oBAAoB,CAAC;QACzD,GAAG,EAAE,CAAC,KAAK,EAAE,sBAAsB,CAAC;QACpC,IAAI,EAAE,CAAC,MAAM,EAAE,YAAY,CAAC;KAC7B,CAAC;IACF,MAAM,WAAW,GAAa,eAAe,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAE1D,KAAK,MAAM,KAAK,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;QAC3C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC;QAC5E,IAAI,CAAC,MAAM,CAAC,IAAI;YAAE,SAAS;QAC3B,MAAM,UAAU,GAA8E,EAAE,CAAC;QACjG,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;YAC5B,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;YACzC,MAAM,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;gBACjE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;YACpE,IAAI,OAAO,EAAE,CAAC;gBACZ,UAAU,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;YAC5F,CAAC;QACH,CAAC;QACD,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1B,2FAA2F;YAC3F,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;gBACvB,MAAM,CAAC,GAAG,CAAC,CAAW,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;gBACjD,MAAM,KAAK,GAAG,CAAC,CAAW,EAAE,EAAE;oBAC5B,IAAI,CAAC,GAAG,CAAC,CAAC;oBACV,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC;wBAAE,CAAC,IAAI,EAAE,CAAC;oBAC1C,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC;wBAAE,CAAC,IAAI,CAAC,CAAC;oBACzC,oEAAoE;oBACpE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC;wBAAE,CAAC,IAAI,CAAC,CAAC;oBACpE,sCAAsC;oBACtC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,sBAAsB,CAAC;wBAAE,CAAC,IAAI,CAAC,CAAC;oBACvJ,OAAO,CAAC,CAAC;gBACX,CAAC,CAAC;gBACF,OAAO,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YAC7B,CAAC,CAAC,CAAC;YACH,MAAM,KAAK,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;YAC5B,MAAM,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;YAC5C,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,yDAAyD;AACzD,KAAK,UAAU,kBAAkB,CAC/B,MAAiB,EACjB,KAA8B,EAC9B,KAAa,EACb,MAAc,EACd,IAAwB;IAExB,IAAI,OAAO,GAAG,MAAM,eAAe,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IAClE,IAAI,CAAC,OAAO;QAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;IAEpD,iBAAiB;IACjB,IAAI,WAA+B,CAAC;IACpC,IAAI,OAAO,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IAE/D,yDAAyD;IACzD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;QAC1C,OAAO,GAAG,MAAM,yBAAyB,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;QACxE,IAAI,CAAC,OAAO;YAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;QACpD,OAAO,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7D,CAAC;IAED,IAAI,IAAI,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACxB,MAAM,IAAI,GAAG,CAAuC,CAAC;YACrD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;YAClE,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;gBACzB,WAAW,GAAG,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;gBAC1C,MAAM;YACR,CAAC;QACH,CAAC;QACD,0EAA0E;QAC1E,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,MAAM,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;YAC1C,OAAO,GAAG,MAAM,yBAAyB,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;YACxE,IAAI,CAAC,OAAO;gBAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;YACpD,OAAO,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;YAC3D,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;gBACxB,MAAM,IAAI,GAAG,CAAuC,CAAC;gBACrD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;gBAClE,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;oBACzB,WAAW,GAAG,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;oBAC1C,MAAM;gBACR,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IACD,IAAI,CAAC,WAAW,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvC,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAuC,CAAC;QAC9D,WAAW,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;IACrD,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC,CAAC;IACxF,IAAI,CAAC,MAAM,CAAC,WAAW,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC;IACnD,CAAC;IAED,4CAA4C;IAC5C,IAAI,eAAe,GAAkB,IAAI,CAAC;IAC1C,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClB,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAC9B,MAAM,IAAI,GAAG,CAAuC,CAAC;YACrD,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,WAAW,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;YAC9C,MAAM,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,YAAY,IAAI,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;YAC1D,6BAA6B;YAC7B,IAAI,GAAG,KAAK,MAAM,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;gBACjE,eAAe,GAAG,GAAG,CAAC;gBAAC,MAAM;YAC/B,CAAC;YACD,iEAAiE;YACjE,IAAI,MAAM,KAAK,MAAM,IAAI,CAAC,GAAG,KAAK,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,IAAI,GAAG,KAAK,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,GAAG,IAAI,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC;gBAC1K,eAAe,GAAG,GAAG,CAAC;gBAAC,MAAM;YAC/B,CAAC;QACH,CAAC;IACH,CAAC;IAED,8BAA8B;IAC9B,IAAI,GAAG,GAAkB,IAAI,CAAC;IAC9B,IAAI,eAAe,EAAE,CAAC;QACpB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC;YAC9D,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,GAAG,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC;gBAC/D,GAAG,GAAG,KAAK,CAAC;gBAAC,MAAM;YACrB,CAAC;QACH,CAAC;IACH,CAAC;IACD,gCAAgC;IAChC,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;QACjB,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAa,CAAC;QAChG,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC;QAC1E,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACzG,OAAO,EAAE,KAAK,EAAE,GAAG,GAAG,CAAC,cAAc,CAAC,OAAO,CAAC,GAAG,IAAI,EAAE,EAAE,QAAQ,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC;AACrF,CAAC;AAED,0EAA0E;AAC1E,KAAK,UAAU,yBAAyB,CACtC,MAAiB,EACjB,KAA8B,EAC9B,KAAa,EACb,MAAc;IAEd,MAAM,EAAE,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;IACnC,MAAM,gBAAgB,GAA6B;QACjD,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;QACpD,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC;QAC7D,QAAQ,EAAE,CAAC,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,CAAC;QAClC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;QAClC,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC;QAChD,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,CAAC;QAC5B,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;KACxB,CAAC;IAEF,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,KAAK,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,EAAE,CAAC;QAC9D,IAAI,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC;YAAE,UAAU,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC;IACpD,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;IACnD,KAAK,MAAM,CAAC,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC;QAC9B,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACjF,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC;gBAAE,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAChE,CAAC;IACH,CAAC;IAED,KAAK,MAAM,KAAK,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;QAC3C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC;QAC5E,IAAI,CAAC,MAAM,CAAC,IAAI;YAAE,SAAS;QAC3B,MAAM,UAAU,GAA8E,EAAE,CAAC;QACjG,MAAM,eAAe,GAA6B;YAChD,GAAG,EAAE,CAAC,KAAK,EAAE,qBAAqB,EAAE,oBAAoB,CAAC;YACzD,GAAG,EAAE,CAAC,KAAK,EAAE,sBAAsB,CAAC;YACpC,IAAI,EAAE,CAAC,MAAM,EAAE,YAAY,CAAC;SAC7B,CAAC;QACF,MAAM,WAAW,GAAa,eAAe,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC1D,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;YAC5B,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;YACzC,MAAM,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;gBACjE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;YACpE,IAAI,OAAO,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;gBACnD,UAAU,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;YAC5F,CAAC;QACH,CAAC;QACD,4CAA4C;QAC5C,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;YAC3B,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;YAC3D,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;gBAAE,SAAS;YACnC,MAAM,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;YACxC,OAAO,CAAC,CAAC;QACX,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,2FAA2F;AAC3F,KAAK,UAAU,yBAAyB,CACtC,MAAiB,EACjB,KAA8B,EAC9B,KAAa;IAEb,MAAM,EAAE,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;IACnC,MAAM,OAAO,GAAG,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC1D,iEAAiE;IACjE,MAAM,KAAK,GAAa,CAAC,GAAG,OAAO,CAAC,CAAC;IACrC,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,IAAI,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC;YAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACvF,IAAI,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC;YAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QACvF,IAAI,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC;YAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACnE,CAAC;IACD,yBAAyB;IACzB,MAAM,gBAAgB,GAA6B;QACjD,GAAG,EAAE,CAAC,KAAK,EAAE,qBAAqB,CAAC;QACnC,GAAG,EAAE,CAAC,KAAK,EAAE,sBAAsB,CAAC;QACpC,IAAI,EAAE,CAAC,MAAM,EAAE,YAAY,CAAC;KAC7B,CAAC;IACF,MAAM,QAAQ,GAAa,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC;IACtD,MAAM,YAAY,GAAG,CAAC,CAAS,EAAE,EAAE,CACjC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IAEtE,MAAM,gBAAgB,GAA6B;QACjD,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;QAC1C,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;QAC3B,QAAQ,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;KAC1B,CAAC;IAEF,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,KAAK,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,EAAE,CAAC;QAC9D,IAAI,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC;YAAE,UAAU,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC;IACpD,CAAC;IACD,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;QAAE,UAAU,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;IAE5D,gDAAgD;IAChD,KAAK,MAAM,KAAK,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;QAC3C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC;QAC5E,IAAI,CAAC,MAAM,CAAC,IAAI;YAAE,SAAS;QAE3B,4EAA4E;QAC5E,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;YAC5B,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;YAChC,IAAI,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;gBAC5E,IAAI,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;oBAC9E,4CAA4C;oBAC5C,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;oBAC3D,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;wBACjC,MAAM,IAAI,GAAG,CAAuC,CAAC;wBACrD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;wBAClE,OAAO,QAAQ,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC;oBACjC,CAAC,CAAC,CAAC;oBACH,IAAI,SAAS;wBAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;gBACjG,CAAC;YACH,CAAC;QACH,CAAC;QAED,iEAAiE;QACjE,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;YAC5B,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;YAChC,IAAI,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;gBAC5E,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;gBAC3D,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;oBACjC,MAAM,IAAI,GAAG,CAAuC,CAAC;oBACrD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;oBAClE,OAAO,QAAQ,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC;gBACjC,CAAC,CAAC,CAAC;gBACH,IAAI,SAAS;oBAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;YACjG,CAAC;QACH,CAAC;QAED,wDAAwD;QACxD,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;YAC5B,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;YAChC,IAAI,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC/E,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;YAClF,CAAC;QACH,CAAC;IACH,CAAC;IAED,+BAA+B;IAC/B,OAAO,eAAe,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;AACvD,CAAC"}
|