Klastrová analýza ekonomických ukazovateľov - rok 2010
Úvod
Predkladaná analýza sa zameriava na skúmanie makroekonomických
ukazovateľov vybraných krajín za rok 2010 s cieľom identifikovať
prirodzené zoskupenia krajín podľa ich ekonomického profilu. Sledované
premenné zahŕňajú infláciu, tempo rastu HDP, mieru nezamestnanosti,
úrokovú sadzbu a hodnotu akciového indexu, ktoré spoločne charakterizujú
ekonomickú stabilitu a rastový potenciál krajiny.
Použitím zhlukovej analýzy je možné rozdeliť krajiny do homogénnych
skupín, odhaliť vzory podobnosti a identifikovať odlišné krajiny.
Výsledky poskytujú cenné informácie pre porovnávaciu ekonomickú
štatistiku, politické rozhodovanie a ďalšie ekonometrické
modelovanie.
Načítanie knižníc a príprava údajov
library(tidyverse)
library(cluster)
library(factoextra)
# Načítanie dát
data <- read.csv("economic_indicators_dataset_2010_2023.csv")
# Prehľad názvov stĺpcov
colnames(data) <- c("Date", "Country", "Inflation", "GDP_Growth", "Unemployment", "Interest", "StockIndex")
# Prevod Date na dátum
data$Date <- as.Date(data$Date)
# Výber dát za rok 2010
data_2010 <- data %>%
filter(format(Date, "%Y") == "2010")
Priemer za rok pre každú krajinu
Na základe údajov za rok 2010 sme vypočítali priemerné hodnoty
sledovaných ekonomických ukazovateľov pre jednotlivé krajiny. Napríklad
Austrália dosahuje infláciu 6,89%, rast HDP 6,38%, nezamestnanosť 9,17%,
úrokovú sadzbu 1,51% a hodnotu akciového indexu 17726,16. Podobne
Brazília má infláciu 6,26%, rast HDP 2,13% a nezamestnanosť 7,77%.
data_country <- data_2010 %>%
group_by(Country) %>%
summarise(
Inflation = round(mean(Inflation, na.rm = TRUE), 2),
GDP_Growth = round(mean(GDP_Growth, na.rm = TRUE), 2),
Unemployment = round(mean(Unemployment, na.rm = TRUE), 2),
Interest = round(mean(Interest, na.rm = TRUE), 2),
StockIndex = round(mean(StockIndex, na.rm = TRUE), 2)
)
print(data_country)
Analýza priemerov umožňuje rýchlo porovnať ekonomický stav krajín.
Vidíme, že krajiny ako India a Japonsko vykazujú vysoké hodnoty úrokovej
sadzby a rastu HDP, zatiaľ čo napríklad USA má relatívne nízku infláciu
a hodnotu akciového indexu. Tieto údaje slúžia ako podklad pre ďalšie
kroky analýzy, vrátane výpočtu korelačnej matice a zhlukovej analýzy,
ktoré odhalia vzájomné podobnosti a rozdiely medzi krajinami.
Korelačná matica
Korelačná matica vypočítaná pre vybrané ekonomické ukazovatele
ukazuje vzťahy medzi nimi. Hodnoty korelačných koeficientov sú
zaokrúhlené na dve desatinné miesta.
Z matice vyplýva, že inflácia je silne kladne korelovaná s mierou
nezamestnanosti (r = 0,70) a stredne s rastom HDP (r = 0,42). Naopak,
hodnota akciového indexu je relatívne nezávislá od ostatných premenných,
pričom najvyššia korelácia je so stock indexom a úrokovou sadzbou (r =
0,30). Rast HDP má mierne zápornú koreláciu so stock indexom (r = -0,33)
a takmer nulovú s úrokovou sadzbou.
cor_matrix <- cor(data_country[, -1])
cor_matrix_rounded <- round(cor_matrix, 2)
print(cor_matrix_rounded)
Inflation GDP_Growth Unemployment Interest StockIndex
Inflation 1.00 0.42 0.70 0.35 0.07
GDP_Growth 0.42 1.00 0.57 -0.01 -0.33
Unemployment 0.70 0.57 1.00 0.23 0.00
Interest 0.35 -0.01 0.23 1.00 0.30
StockIndex 0.07 -0.33 0.00 0.30 1.00
Celkovo korelačná matica indikuje, že medzi niektorými ukazovateľmi
existujú stredné až silné vzťahy, ale žiadna dvojica premenných nie je
extrémne vysoko korelovaná, čo umožňuje ich súčasné použitie pri
zhlukovej analýze bez potreby redukcie dimenzionality.
Matica vzdialenosti medzi krajinami
Matica vzdialeností ukazuje, do akej miery sa ekonomické profily
krajín navzájom líšia.
Najväčšia vzdialenosť je medzi Nemeckom a Čínou (23502,86), čo odráža
výrazné rozdiely v ekonomickej štruktúre, raste HDP a hodnote akciového
indexu. Naopak, relatívne malá vzdialenosť je medzi Brazíliou a
Japonskom (239,04), čo naznačuje podobnosť vybraných ukazovateľov medzi
týmito dvoma krajinami.
data_numeric <- data_country[, -1]
dist_matrix <- dist(data_numeric, method = "euclidean")
dist_matrix <- as.matrix(dist_matrix)
rownames(dist_matrix) <- data_country$Country
colnames(dist_matrix) <- data_country$Country
dist_matrix_rounded <- round(dist_matrix, 2)
print(dist_matrix_rounded)
Australia Brazil Canada China France Germany India Japan UK USA
Australia 0.00 3591.45 2993.00 10464.41 2190.82 14038.46 7990.54 3352.46 2598.60 9741.39
Brazil 3591.45 0.00 6584.44 14055.86 5782.26 10447.00 4399.09 239.05 992.85 13332.84
Canada 2993.00 6584.44 0.00 7471.42 802.19 17031.44 10983.53 6345.44 5591.59 6748.40
China 10464.41 14055.86 7471.42 0.00 8273.60 24502.86 18454.95 13816.86 13063.01 723.03
France 2190.82 5782.26 802.19 8273.60 0.00 16229.26 10181.35 5543.26 4789.41 7550.58
Germany 14038.46 10447.00 17031.44 24502.86 16229.26 0.00 6047.92 10686.01 11439.85 23779.84
India 7990.54 4399.09 10983.53 18454.95 10181.35 6047.92 0.00 4638.09 5391.94 17731.93
Japan 3352.46 239.05 6345.44 13816.86 5543.26 10686.01 4638.09 0.00 753.86 13093.84
UK 2598.60 992.85 5591.59 13063.01 4789.41 11439.85 5391.94 753.86 0.00 12339.99
USA 9741.39 13332.84 6748.40 723.03 7550.58 23779.84 17731.93 13093.84 12339.99 0.00
Matica vzdialeností poskytuje cenný podklad pre zhlukovú analýzu,
keďže krajiny s menšími vzdialenosťami sa pravdepodobne zoskupia do
rovnakých klastrov.
Hierarchické zhlukovanie (Wardova metóda)
Na základe dendrogramu hierarchického zhlukovania možno pozorovať
nasledujúce:
Krajiny sa rozdeľujú do triedy troch hlavných klastrov, čo je
vyznačené červenou rezacou čiarou.
Jeden klaster tvorí Nemecko samostatne, čo naznačuje, že jeho
ekonomický profil je výrazne odlišný od ostatných krajín.
Druhý klaster obsahuje Indiu a Japonsko, ktoré sú si navzájom
bližšie, pravdepodobne kvôli podobným hodnotám vybraných ekonomických
premenných (úrokové sadzby, HDP rast).
Tretí klaster zahŕňa Francúzsko, Kanadu, Brazíliu, UK, Austráliu,
Čínu a USA, pričom niektoré krajiny v tomto klasteri sú bližšie k sebe
(Brazilia a UK alebo China a USA), čo naznačuje väčšiu podobnosť v
ekonomickom profile.
# z-škálovanie
data_scaled <- scale(data_numeric)
hc <- hclust(dist(data_scaled, method = "euclidean"), method = "ward.D2")
plot(hc, labels = data_country$Country, main = "Hierarchické zhlukovanie - Wardova metóda (2010)", cex = 0.8)
rect.hclust(hc, k = 3, border = "red")

Celková interpretácia ukazuje, že dendrogram efektívne oddeľuje
krajiny s výrazne odlišnými ekonomickými charakteristikami a zoskupuje
krajiny s podobnými ukazovateľmi do spoločných klastrov.
Príslušnosť krajín do klastrov
Klaster 1 tvoria hlavne rozvinuté krajiny Západu a ďalšie
významné ekonomiky ako Austrália, Brazília, Kanada, Čína, Francúzsko,
Veľká Británia a USA. Tento klaster predstavuje krajiny s vysokou
ekonomickou vyspelosťou alebo veľkým globálnym významom.
Klaster 2 obsahuje Nemecko, ktoré je zároveň vyspelou západnou
ekonomikou, ale odlišuje sa od väčšiny ostatných krajín západu,
pravdepodobne kvôli špecifickým ekonomickým alebo štrukturálnym
faktorom.
Klaster 3 tvoria India a Japonsko, krajiny, ktoré sú buď
rozvíjajúce sa ekonomiky s vysokým rastovým potenciálom (India), alebo
vysoko vyspelé, ale odlišné ekonomické systémy a kultúrne štruktúry
(Japonsko).
clusters <- cutree(hc, k = 3)
data_country$cluster <- as.factor(clusters)
print(data_country[, c("Country", "cluster")])
Deskriptívne štatistiky výsledkov
Vnútro- a medziklastrová variabilita
Na základe výsledkov môžeme konštatovať, že vnútroklastrová
variabilita je relatívne nízka u väčšiny premenných, čo naznačuje dobrú
homogenitu v rámci klastrov. Výnimku tvorí premenná Unemployment, ktorá
má vyššiu vnútroklastrovú variabilitu a nižšiu medzi-klastrovú
variabilitu (Prop_Between = 0,44), čo znamená, že nie je tak dobrým
separátorom ako ostatné premenné. Naopak, premenné StockIndex,
GDP_Growth a Inflation vykazujú vyššiu medzi-klastrovú variabilitu
(Prop_Between ≥ 0,57), čo indikuje ich silnú schopnosť rozlišovať
jednotlivé klastry.
tss <- apply(data_scaled, 2, function(x) sum((x - mean(x))^2))
wss <- sapply(1:3, function(k) {
cluster_data <- data_scaled[data_country$cluster == k, , drop = FALSE]
apply(cluster_data, 2, function(x) sum((x - mean(x))^2))
})
if (is.vector(wss)) wss <- matrix(wss, nrow = 1)
bss <- tss - rowSums(wss)
prop_between <- bss / tss
vn_deskriptiv <- data.frame(
Variable = colnames(data_scaled),
TSS = round(tss, 2),
WSS = round(rowSums(wss), 2),
BSS = round(bss, 2),
Prop_Between = round(prop_between, 2)
)
print(vn_deskriptiv)
Centroidy klastrov
Na základe Centroidy klastrov môžeme pozorovať charakteristiky
jednotlivých klastrov:
Klastre sú relatívne odlišné vo všetkých premenných, čo
potvrdzuje predchádzajúci výsledok Prop_Between.
Klaster 1: stredná inflácia (6,08%), mierny rast HDP (3,18%),
vysoká nezamestnanosť (7,49%), úroková miera 4,04% a najnižšia hodnota
StockIndex (14983,37).
Klaster 2: nižšia inflácia (4,44%), záporný rast HDP (-3,83%),
najnižšia nezamestnanosť (4,07%), úrok 3,92% a najvyšší StockIndex
(31764,61).
Klaster 3: najvyššia inflácia (7,81%), vysoký rast HDP (5,56%),
vysoká nezamestnanosť (8,97%), úrok 6,61% a stredný StockIndex
(23397,65).
centroids <- data_country %>%
group_by(cluster) %>%
summarise(
Inflation_mean = mean(Inflation),
GDP_Growth_mean = mean(GDP_Growth),
Unemployment_mean = mean(Unemployment),
Interest_mean = mean(Interest),
StockIndex_mean = mean(StockIndex)
)
print(centroids)
Celkovo je zrejmé, že jednotlivé klastry sa odlišujú predovšetkým v
GDP_Growth, Unemployment a StockIndex, pričom klaster 2 predstavuje
negatívny ekonomický rast s nízkou nezamestnanosťou, klaster 1 stabilnú
ekonomiku s vysokou nezamestnanosťou a klaster 3 dynamickú ekonomiku s
vysokou infláciou a úrokmi.
Záver
Na základe vykonanej analýzy makroekonomických ukazovateľov možno
konštatovať, že sledované premenné Inflation, GDP_Growth, Unemployment,
Interest a StockIndex poskytujú cenné informácie o ekonomickej stabilite
a raste krajín.
Analýza odhalila významné vzory a rozdiely medzi ekonomikami, čo
umožňuje lepšie porozumenie ich ekonomického profilu a poskytuje
podklady pre porovnávaciu štatistiku, politické rozhodovanie a ďalšie
ekonometrické modelovanie.
LS0tDQp0aXRsZTogIsOabG9oYV84Ig0KYXV0aG9yOiAiWXVsaWlhIEx5c3l0c2lhIg0KZGF0ZTogIk5vdmVtYmVyIDIwMjUiDQpvdXRwdXQ6DQogIGh0bWxfbm90ZWJvb2s6DQogICAgdG9jOiB0cnVlDQogICAgdG9jX2Zsb2F0OiB0cnVlDQogICAgdGhlbWU6IHVuaXRlZA0KICAgIGhpZ2hsaWdodDogdGFuZ28NCiAgcGRmX2RvY3VtZW50Og0KICAgIHRvYzogdHJ1ZQ0KICBodG1sX2RvY3VtZW50Og0KICAgIHRvYzogdHJ1ZQ0KICAgIGRmX3ByaW50OiBwYWdlZA0KZWRpdG9yX29wdGlvbnM6DQogIG1hcmtkb3duOg0KICAgIHdyYXA6IDcyDQotLS0NCg0KIyBLbGFzdHJvdsOhIGFuYWzDvXphIGVrb25vbWlja8O9Y2ggdWthem92YXRlxL5vdiAtIHJvayAyMDEwDQoNCiMjIMOadm9kDQoNClByZWRrbGFkYW7DoSBhbmFsw716YSBzYSB6YW1lcmlhdmEgbmEgc2vDum1hbmllIG1ha3JvZWtvbm9taWNrw71jaCB1a2F6b3ZhdGXEvm92IHZ5YnJhbsO9Y2gga3JhasOtbiB6YSByb2sgMjAxMCBzIGNpZcS+b20gaWRlbnRpZmlrb3ZhxaUgcHJpcm9kemVuw6kgem9za3VwZW5pYSBrcmFqw61uIHBvZMS+YSBpY2ggZWtvbm9taWNrw6lobyBwcm9maWx1LiBTbGVkb3ZhbsOpIHByZW1lbm7DqSB6YWjFlcWIYWrDuiBpbmZsw6FjaXUsIHRlbXBvIHJhc3R1IEhEUCwgbWllcnUgbmV6YW1lc3RuYW5vc3RpLCDDunJva292w7ogc2FkemJ1IGEgaG9kbm90dSBha2Npb3bDqWhvIGluZGV4dSwga3RvcsOpIHNwb2xvxI1uZSBjaGFyYWt0ZXJpenVqw7ogZWtvbm9taWNrw7ogc3RhYmlsaXR1IGEgcmFzdG92w70gcG90ZW5jacOhbCBrcmFqaW55Lg0KDQpQb3XFvml0w61tIHpobHVrb3ZlaiBhbmFsw716eSBqZSBtb8W+bsOpIHJvemRlbGnFpSBrcmFqaW55IGRvIGhvbW9nw6lubnljaCBza3Vww61uLCBvZGhhbGnFpSB2em9yeSBwb2RvYm5vc3RpIGEgaWRlbnRpZmlrb3ZhxaUgb2RsacWhbsOpIGtyYWppbnkuIFbDvXNsZWRreSBwb3NreXR1asO6IGNlbm7DqSBpbmZvcm3DoWNpZSBwcmUgcG9yb3Zuw6F2YWNpdSBla29ub21pY2vDuiDFoXRhdGlzdGlrdSwgcG9saXRpY2vDqSByb3pob2RvdmFuaWUgYSDEj2FsxaFpZSBla29ub21ldHJpY2vDqSBtb2RlbG92YW5pZS4NCg0KIyMjIE5hxI3DrXRhbmllIGtuacW+bsOtYyBhIHByw61wcmF2YSDDumRham92DQpgYGB7cn0NCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShjbHVzdGVyKQ0KbGlicmFyeShmYWN0b2V4dHJhKQ0KDQojIE5hxI3DrXRhbmllIGTDoXQNCmRhdGEgPC0gcmVhZC5jc3YoImVjb25vbWljX2luZGljYXRvcnNfZGF0YXNldF8yMDEwXzIwMjMuY3N2IikNCg0KIyBQcmVoxL5hZCBuw6F6dm92IHN0xLpwY292DQpjb2xuYW1lcyhkYXRhKSA8LSBjKCJEYXRlIiwgIkNvdW50cnkiLCAiSW5mbGF0aW9uIiwgIkdEUF9Hcm93dGgiLCAiVW5lbXBsb3ltZW50IiwgIkludGVyZXN0IiwgIlN0b2NrSW5kZXgiKQ0KDQojIFByZXZvZCBEYXRlIG5hIGTDoXR1bQ0KZGF0YSREYXRlIDwtIGFzLkRhdGUoZGF0YSREYXRlKQ0KDQojIFbDvWJlciBkw6F0IHphIHJvayAyMDEwDQpkYXRhXzIwMTAgPC0gZGF0YSAlPiUNCiAgZmlsdGVyKGZvcm1hdChEYXRlLCAiJVkiKSA9PSAiMjAxMCIpDQpgYGANCg0KIyMjIFByaWVtZXIgemEgcm9rIHByZSBrYcW+ZMO6IGtyYWppbnUNCg0KTmEgesOha2xhZGUgw7pkYWpvdiB6YSByb2sgMjAxMCBzbWUgdnlwb8SNw610YWxpIHByaWVtZXJuw6kgaG9kbm90eSBzbGVkb3ZhbsO9Y2ggZWtvbm9taWNrw71jaCB1a2F6b3ZhdGXEvm92IHByZSBqZWRub3RsaXbDqSBrcmFqaW55LiBOYXByw61rbGFkIEF1c3Ryw6FsaWEgZG9zYWh1amUgaW5mbMOhY2l1IDYsODklLCByYXN0IEhEUCA2LDM4JSwgbmV6YW1lc3RuYW5vc8WlIDksMTclLCDDunJva292w7ogc2FkemJ1IDEsNTElIGEgaG9kbm90dSBha2Npb3bDqWhvIGluZGV4dSAxNzcyNiwxNi4gUG9kb2JuZSBCcmF6w61saWEgbcOhIGluZmzDoWNpdSA2LDI2JSwgcmFzdCBIRFAgMiwxMyUgYSBuZXphbWVzdG5hbm9zxaUgNyw3NyUuDQpgYGB7cn0NCmRhdGFfY291bnRyeSA8LSBkYXRhXzIwMTAgJT4lDQogIGdyb3VwX2J5KENvdW50cnkpICU+JQ0KICBzdW1tYXJpc2UoDQogICAgSW5mbGF0aW9uID0gcm91bmQobWVhbihJbmZsYXRpb24sIG5hLnJtID0gVFJVRSksIDIpLA0KICAgIEdEUF9Hcm93dGggPSByb3VuZChtZWFuKEdEUF9Hcm93dGgsIG5hLnJtID0gVFJVRSksIDIpLA0KICAgIFVuZW1wbG95bWVudCA9IHJvdW5kKG1lYW4oVW5lbXBsb3ltZW50LCBuYS5ybSA9IFRSVUUpLCAyKSwNCiAgICBJbnRlcmVzdCA9IHJvdW5kKG1lYW4oSW50ZXJlc3QsIG5hLnJtID0gVFJVRSksIDIpLA0KICAgIFN0b2NrSW5kZXggPSByb3VuZChtZWFuKFN0b2NrSW5kZXgsIG5hLnJtID0gVFJVRSksIDIpDQogICkNCnByaW50KGRhdGFfY291bnRyeSkNCmBgYA0KQW5hbMO9emEgcHJpZW1lcm92IHVtb8W+xYh1amUgcsO9Y2hsbyBwb3Jvdm5hxaUgZWtvbm9taWNrw70gc3RhdiBrcmFqw61uLiBWaWTDrW1lLCDFvmUga3JhamlueSBha28gSW5kaWEgYSBKYXBvbnNrbyB2eWthenVqw7ogdnlzb2vDqSBob2Rub3R5IMO6cm9rb3ZlaiBzYWR6YnkgYSByYXN0dSBIRFAsIHphdGlhxL4gxI1vIG5hcHLDrWtsYWQgVVNBIG3DoSByZWxhdMOtdm5lIG7DrXprdSBpbmZsw6FjaXUgYSBob2Rub3R1IGFrY2lvdsOpaG8gaW5kZXh1LiBUaWV0byDDumRhamUgc2zDusW+aWEgYWtvIHBvZGtsYWQgcHJlIMSPYWzFoWllIGtyb2t5IGFuYWzDvXp5LCB2csOhdGFuZSB2w71wb8SNdHUga29yZWxhxI1uZWogbWF0aWNlIGEgemhsdWtvdmVqIGFuYWzDvXp5LCBrdG9yw6kgb2RoYWxpYSB2esOham9tbsOpIHBvZG9ibm9zdGkgYSByb3pkaWVseSBtZWR6aSBrcmFqaW5hbWkuDQoNCiMjIEtvcmVsYcSNbsOhIG1hdGljYQ0KDQpLb3JlbGHEjW7DoSBtYXRpY2Egdnlwb8SNw610YW7DoSBwcmUgdnlicmFuw6kgZWtvbm9taWNrw6kgdWthem92YXRlbGUgdWthenVqZSB2esWlYWh5IG1lZHppIG5pbWkuIEhvZG5vdHkga29yZWxhxI1uw71jaCBrb2VmaWNpZW50b3Ygc8O6IHphb2tyw7pobGVuw6kgbmEgZHZlIGRlc2F0aW5uw6kgbWllc3RhLg0KDQpaIG1hdGljZSB2eXBsw712YSwgxb5lIGluZmzDoWNpYSBqZSBzaWxuZSBrbGFkbmUga29yZWxvdmFuw6EgcyBtaWVyb3UgbmV6YW1lc3RuYW5vc3RpIChyID0gMCw3MCkgYSBzdHJlZG5lIHMgcmFzdG9tIEhEUCAociA9IDAsNDIpLiBOYW9wYWssIGhvZG5vdGEgYWtjaW92w6lobyBpbmRleHUgamUgcmVsYXTDrXZuZSBuZXrDoXZpc2zDoSBvZCBvc3RhdG7DvWNoIHByZW1lbm7DvWNoLCBwcmnEjW9tIG5hanZ5xaHFoWlhIGtvcmVsw6FjaWEgamUgc28gc3RvY2sgaW5kZXhvbSBhIMO6cm9rb3ZvdSBzYWR6Ym91IChyID0gMCwzMCkuIFJhc3QgSERQIG3DoSBtaWVybmUgesOhcG9ybsO6IGtvcmVsw6FjaXUgc28gc3RvY2sgaW5kZXhvbSAociA9IC0wLDMzKSBhIHRha21lciBudWxvdsO6IHMgw7pyb2tvdm91IHNhZHpib3UuDQpgYGB7cn0NCmNvcl9tYXRyaXggPC0gY29yKGRhdGFfY291bnRyeVssIC0xXSkgDQpjb3JfbWF0cml4X3JvdW5kZWQgPC0gcm91bmQoY29yX21hdHJpeCwgMikNCg0KcHJpbnQoY29yX21hdHJpeF9yb3VuZGVkKQ0KYGBgDQpDZWxrb3ZvIGtvcmVsYcSNbsOhIG1hdGljYSBpbmRpa3VqZSwgxb5lIG1lZHppIG5pZWt0b3LDvW1pIHVrYXpvdmF0ZcS+bWkgZXhpc3R1asO6IHN0cmVkbsOpIGHFviBzaWxuw6kgdnrFpWFoeSwgYWxlIMW+aWFkbmEgZHZvamljYSBwcmVtZW5uw71jaCBuaWUgamUgZXh0csOpbW5lIHZ5c29rbyBrb3JlbG92YW7DoSwgxI1vIHVtb8W+xYh1amUgaWNoIHPDusSNYXNuw6kgcG91xb5pdGllIHByaSB6aGx1a292ZWogYW5hbMO9emUgYmV6IHBvdHJlYnkgcmVkdWtjaWUgZGltZW56aW9uYWxpdHkuDQoNCiMjIE1hdGljYSB2emRpYWxlbm9zdGkgbWVkemkga3JhamluYW1pDQoNCk1hdGljYSB2emRpYWxlbm9zdMOtIHVrYXp1amUsIGRvIGFrZWogbWllcnkgc2EgZWtvbm9taWNrw6kgcHJvZmlseSBrcmFqw61uIG5hdnrDoWpvbSBsw63FoWlhLg0KDQpOYWp2w6TEjcWhaWEgdnpkaWFsZW5vc8WlIGplIG1lZHppIE5lbWVja29tIGEgxIzDrW5vdSAoMjM1MDIsODYpLCDEjW8gb2Ryw6HFvmEgdsO9cmF6bsOpIHJvemRpZWx5IHYgZWtvbm9taWNrZWogxaF0cnVrdMO6cmUsIHJhc3RlIEhEUCBhIGhvZG5vdGUgYWtjaW92w6lobyBpbmRleHUuIE5hb3BhaywgcmVsYXTDrXZuZSBtYWzDoSB2emRpYWxlbm9zxaUgamUgbWVkemkgQnJhesOtbGlvdSBhIEphcG9uc2tvbSAoMjM5LDA0KSwgxI1vIG5hem5hxI11amUgcG9kb2Jub3PFpSB2eWJyYW7DvWNoIHVrYXpvdmF0ZcS+b3YgbWVkemkgdMO9bWl0byBkdm9tYSBrcmFqaW5hbWkuDQpgYGB7cn0NCmRhdGFfbnVtZXJpYyA8LSBkYXRhX2NvdW50cnlbLCAtMV0gDQpkaXN0X21hdHJpeCA8LSBkaXN0KGRhdGFfbnVtZXJpYywgbWV0aG9kID0gImV1Y2xpZGVhbiIpDQpkaXN0X21hdHJpeCA8LSBhcy5tYXRyaXgoZGlzdF9tYXRyaXgpDQpyb3duYW1lcyhkaXN0X21hdHJpeCkgPC0gZGF0YV9jb3VudHJ5JENvdW50cnkNCmNvbG5hbWVzKGRpc3RfbWF0cml4KSA8LSBkYXRhX2NvdW50cnkkQ291bnRyeQ0KZGlzdF9tYXRyaXhfcm91bmRlZCA8LSByb3VuZChkaXN0X21hdHJpeCwgMikNCg0KcHJpbnQoZGlzdF9tYXRyaXhfcm91bmRlZCkNCmBgYA0KTWF0aWNhIHZ6ZGlhbGVub3N0w60gcG9za3l0dWplIGNlbm7DvSBwb2RrbGFkIHByZSB6aGx1a292w7ogYW5hbMO9enUsIGtlxI/FvmUga3JhamlueSBzIG1lbsWhw61taSB2emRpYWxlbm9zxaVhbWkgc2EgcHJhdmRlcG9kb2JuZSB6b3NrdXBpYSBkbyByb3ZuYWvDvWNoIGtsYXN0cm92Lg0KDQojIyBIaWVyYXJjaGlja8OpIHpobHVrb3ZhbmllIChXYXJkb3ZhIG1ldMOzZGEpDQoNCk5hIHrDoWtsYWRlIGRlbmRyb2dyYW11IGhpZXJhcmNoaWNrw6lobyB6aGx1a292YW5pYSBtb8W+bm8gcG96b3JvdmHFpSBuYXNsZWR1asO6Y2U6DQoNCi0gS3JhamlueSBzYSByb3pkZcS+dWrDuiBkbyB0cmllZHkgdHJvY2ggaGxhdm7DvWNoIGtsYXN0cm92LCDEjW8gamUgdnl6bmHEjWVuw6kgxI1lcnZlbm91IHJlemFjb3UgxI1pYXJvdS4NCg0KLSBKZWRlbiBrbGFzdGVyIHR2b3LDrSBOZW1lY2tvIHNhbW9zdGF0bmUsIMSNbyBuYXpuYcSNdWplLCDFvmUgamVobyBla29ub21pY2vDvSBwcm9maWwgamUgdsO9cmF6bmUgb2RsacWhbsO9IG9kIG9zdGF0bsO9Y2gga3JhasOtbi4NCg0KLSBEcnVow70ga2xhc3RlciBvYnNhaHVqZSBJbmRpdSBhIEphcG9uc2tvLCBrdG9yw6kgc8O6IHNpIG5hdnrDoWpvbSBibGnFvsWhaWUsIHByYXZkZXBvZG9ibmUga3bDtGxpIHBvZG9ibsO9bSBob2Rub3TDoW0gdnlicmFuw71jaCBla29ub21pY2vDvWNoIHByZW1lbm7DvWNoICjDunJva292w6kgc2FkemJ5LCBIRFAgcmFzdCkuDQoNCi0gVHJldMOtIGtsYXN0ZXIgemFoxZXFiGEgRnJhbmPDunpza28sIEthbmFkdSwgQnJhesOtbGl1LCBVSywgQXVzdHLDoWxpdSwgxIzDrW51IGEgVVNBLCBwcmnEjW9tIG5pZWt0b3LDqSBrcmFqaW55IHYgdG9tdG8ga2xhc3Rlcmkgc8O6IGJsacW+xaFpZSBrIHNlYmUgKEJyYXppbGlhIGEgVUsgYWxlYm8gQ2hpbmEgYSBVU0EpLCDEjW8gbmF6bmHEjXVqZSB2w6TEjcWhaXUgcG9kb2Jub3PFpSB2IGVrb25vbWlja29tIHByb2ZpbGUuDQpgYGB7cn0NCiMgei3FoWvDoWxvdmFuaWUNCmRhdGFfc2NhbGVkIDwtIHNjYWxlKGRhdGFfbnVtZXJpYykgIA0KDQpoYyA8LSBoY2x1c3QoZGlzdChkYXRhX3NjYWxlZCwgbWV0aG9kID0gImV1Y2xpZGVhbiIpLCBtZXRob2QgPSAid2FyZC5EMiIpDQoNCnBsb3QoaGMsIGxhYmVscyA9IGRhdGFfY291bnRyeSRDb3VudHJ5LCBtYWluID0gIkhpZXJhcmNoaWNrw6kgemhsdWtvdmFuaWUgLSBXYXJkb3ZhIG1ldMOzZGEgKDIwMTApIiwgY2V4ID0gMC44KQ0KcmVjdC5oY2x1c3QoaGMsIGsgPSAzLCBib3JkZXIgPSAicmVkIikgIA0KYGBgDQpDZWxrb3bDoSBpbnRlcnByZXTDoWNpYSB1a2F6dWplLCDFvmUgZGVuZHJvZ3JhbSBlZmVrdMOtdm5lIG9kZGXEvnVqZSBrcmFqaW55IHMgdsO9cmF6bmUgb2RsacWhbsO9bWkgZWtvbm9taWNrw71taSBjaGFyYWt0ZXJpc3Rpa2FtaSBhIHpvc2t1cHVqZSBrcmFqaW55IHMgcG9kb2Juw71taSB1a2F6b3ZhdGXEvm1pIGRvIHNwb2xvxI1uw71jaCBrbGFzdHJvdi4NCg0KIyMgUHLDrXNsdcWhbm9zxaUga3JhasOtbiBkbyBrbGFzdHJvdg0KDQotIEtsYXN0ZXIgMSB0dm9yaWEgaGxhdm5lIHJvenZpbnV0w6kga3JhamlueSBaw6FwYWR1IGEgxI9hbMWhaWUgdsO9em5hbW7DqSBla29ub21pa3kgYWtvIEF1c3Ryw6FsaWEsIEJyYXrDrWxpYSwgS2FuYWRhLCDEjMOtbmEsIEZyYW5jw7p6c2tvLCBWZcS+a8OhIEJyaXTDoW5pYSBhIFVTQS4gVGVudG8ga2xhc3RlciBwcmVkc3RhdnVqZSBrcmFqaW55IHMgdnlzb2tvdSBla29ub21pY2tvdSB2eXNwZWxvc8Wlb3UgYWxlYm8gdmXEvmvDvW0gZ2xvYsOhbG55bSB2w716bmFtb20uDQoNCi0gS2xhc3RlciAyIG9ic2FodWplIE5lbWVja28sIGt0b3LDqSBqZSB6w6Fyb3ZlxYggdnlzcGVsb3UgesOhcGFkbm91IGVrb25vbWlrb3UsIGFsZSBvZGxpxaF1amUgc2Egb2QgdsOkxI3FoWlueSBvc3RhdG7DvWNoIGtyYWrDrW4gesOhcGFkdSwgcHJhdmRlcG9kb2JuZSBrdsO0bGkgxaFwZWNpZmlja8O9bSBla29ub21pY2vDvW0gYWxlYm8gxaF0cnVrdHVyw6FsbnltIGZha3Rvcm9tLg0KDQotIEtsYXN0ZXIgMyB0dm9yaWEgSW5kaWEgYSBKYXBvbnNrbywga3JhamlueSwga3RvcsOpIHPDuiBidcSPIHJvenbDrWphasO6Y2Ugc2EgZWtvbm9taWt5IHMgdnlzb2vDvW0gcmFzdG92w71tIHBvdGVuY2nDoWxvbSAoSW5kaWEpLCBhbGVibyB2eXNva28gdnlzcGVsw6ksIGFsZSBvZGxpxaFuw6kgZWtvbm9taWNrw6kgc3lzdMOpbXkgYSBrdWx0w7pybmUgxaF0cnVrdMO6cnkgKEphcG9uc2tvKS4NCmBgYHtyfQ0KY2x1c3RlcnMgPC0gY3V0cmVlKGhjLCBrID0gMykNCmRhdGFfY291bnRyeSRjbHVzdGVyIDwtIGFzLmZhY3RvcihjbHVzdGVycykNCg0KcHJpbnQoZGF0YV9jb3VudHJ5WywgYygiQ291bnRyeSIsICJjbHVzdGVyIildKQ0KYGBgDQoNCiMjIERlc2tyaXB0w612bmUgxaF0YXRpc3Rpa3kgdsO9c2xlZGtvdg0KDQojIyMgVm7DunRyby0gYSBtZWR6aWtsYXN0cm92w6EgdmFyaWFiaWxpdGENCg0KTmEgesOha2xhZGUgdsO9c2xlZGtvdiBtw7TFvmVtZSBrb27FoXRhdG92YcWlLCDFvmUgdm7DunRyb2tsYXN0cm92w6EgdmFyaWFiaWxpdGEgamUgcmVsYXTDrXZuZSBuw616a2EgdSB2w6TEjcWhaW55IHByZW1lbm7DvWNoLCDEjW8gbmF6bmHEjXVqZSBkb2Jyw7ogaG9tb2dlbml0dSB2IHLDoW1jaSBrbGFzdHJvdi4gVsO9bmlta3UgdHZvcsOtIHByZW1lbm7DoSBVbmVtcGxveW1lbnQsIGt0b3LDoSBtw6EgdnnFocWhaXUgdm7DunRyb2tsYXN0cm92w7ogdmFyaWFiaWxpdHUgYSBuacW+xaFpdSBtZWR6aS1rbGFzdHJvdsO6IHZhcmlhYmlsaXR1IChQcm9wX0JldHdlZW4gPSAwLDQ0KSwgxI1vIHpuYW1lbsOhLCDFvmUgbmllIGplIHRhayBkb2Jyw71tIHNlcGFyw6F0b3JvbSBha28gb3N0YXRuw6kgcHJlbWVubsOpLiBOYW9wYWssIHByZW1lbm7DqSBTdG9ja0luZGV4LCBHRFBfR3Jvd3RoIGEgSW5mbGF0aW9uIHZ5a2F6dWrDuiB2ecWhxaFpdSBtZWR6aS1rbGFzdHJvdsO6IHZhcmlhYmlsaXR1IChQcm9wX0JldHdlZW4g4omlIDAsNTcpLCDEjW8gaW5kaWt1amUgaWNoIHNpbG7DuiBzY2hvcG5vc8WlIHJvemxpxaFvdmHFpSBqZWRub3RsaXbDqSBrbGFzdHJ5Lg0KYGBge3J9DQp0c3MgPC0gYXBwbHkoZGF0YV9zY2FsZWQsIDIsIGZ1bmN0aW9uKHgpIHN1bSgoeCAtIG1lYW4oeCkpXjIpKQ0KDQp3c3MgPC0gc2FwcGx5KDE6MywgZnVuY3Rpb24oaykgew0KICBjbHVzdGVyX2RhdGEgPC0gZGF0YV9zY2FsZWRbZGF0YV9jb3VudHJ5JGNsdXN0ZXIgPT0gaywgLCBkcm9wID0gRkFMU0VdDQogIGFwcGx5KGNsdXN0ZXJfZGF0YSwgMiwgZnVuY3Rpb24oeCkgc3VtKCh4IC0gbWVhbih4KSleMikpDQp9KQ0KDQppZiAoaXMudmVjdG9yKHdzcykpIHdzcyA8LSBtYXRyaXgod3NzLCBucm93ID0gMSkNCg0KYnNzIDwtIHRzcyAtIHJvd1N1bXMod3NzKQ0KDQpwcm9wX2JldHdlZW4gPC0gYnNzIC8gdHNzDQoNCnZuX2Rlc2tyaXB0aXYgPC0gZGF0YS5mcmFtZSgNCiAgVmFyaWFibGUgPSBjb2xuYW1lcyhkYXRhX3NjYWxlZCksDQogIFRTUyA9IHJvdW5kKHRzcywgMiksDQogIFdTUyA9IHJvdW5kKHJvd1N1bXMod3NzKSwgMiksDQogIEJTUyA9IHJvdW5kKGJzcywgMiksDQogIFByb3BfQmV0d2VlbiA9IHJvdW5kKHByb3BfYmV0d2VlbiwgMikNCikNCg0KcHJpbnQodm5fZGVza3JpcHRpdikNCmBgYA0KDQojIyBDZW50cm9pZHkga2xhc3Ryb3YNCg0KTmEgesOha2xhZGUgQ2VudHJvaWR5IGtsYXN0cm92IG3DtMW+ZW1lIHBvem9yb3ZhxaUgY2hhcmFrdGVyaXN0aWt5IGplZG5vdGxpdsO9Y2gga2xhc3Ryb3Y6DQoNCi0gS2xhc3RyZSBzw7ogcmVsYXTDrXZuZSBvZGxpxaFuw6kgdm8gdsWhZXRrw71jaCBwcmVtZW5uw71jaCwgxI1vIHBvdHZyZHp1amUgcHJlZGNow6FkemFqw7pjaSB2w71zbGVkb2sgUHJvcF9CZXR3ZWVuLg0KDQotIEtsYXN0ZXIgMTogc3RyZWRuw6EgaW5mbMOhY2lhICg2LDA4JSksIG1pZXJueSByYXN0IEhEUCAoMywxOCUpLCB2eXNva8OhIG5lemFtZXN0bmFub3PFpSAoNyw0OSUpLCDDunJva292w6EgbWllcmEgNCwwNCUgYSBuYWpuacW+xaFpYSBob2Rub3RhIFN0b2NrSW5kZXggKDE0OTgzLDM3KS4NCg0KLSBLbGFzdGVyIDI6IG5pxb7FoWlhIGluZmzDoWNpYSAoNCw0NCUpLCB6w6Fwb3Juw70gcmFzdCBIRFAgKC0zLDgzJSksIG5ham5pxb7FoWlhIG5lemFtZXN0bmFub3PFpSAoNCwwNyUpLCDDunJvayAzLDkyJSBhIG5hanZ5xaHFocOtIFN0b2NrSW5kZXggKDMxNzY0LDYxKS4NCg0KLSBLbGFzdGVyIDM6IG5hanZ5xaHFoWlhIGluZmzDoWNpYSAoNyw4MSUpLCB2eXNva8O9IHJhc3QgSERQICg1LDU2JSksIHZ5c29rw6EgbmV6YW1lc3RuYW5vc8WlICg4LDk3JSksIMO6cm9rIDYsNjElIGEgc3RyZWRuw70gU3RvY2tJbmRleCAoMjMzOTcsNjUpLg0KYGBge3J9DQpjZW50cm9pZHMgPC0gZGF0YV9jb3VudHJ5ICU+JQ0KICBncm91cF9ieShjbHVzdGVyKSAlPiUNCiAgc3VtbWFyaXNlKA0KICAgIEluZmxhdGlvbl9tZWFuID0gbWVhbihJbmZsYXRpb24pLA0KICAgIEdEUF9Hcm93dGhfbWVhbiA9IG1lYW4oR0RQX0dyb3d0aCksDQogICAgVW5lbXBsb3ltZW50X21lYW4gPSBtZWFuKFVuZW1wbG95bWVudCksDQogICAgSW50ZXJlc3RfbWVhbiA9IG1lYW4oSW50ZXJlc3QpLA0KICAgIFN0b2NrSW5kZXhfbWVhbiA9IG1lYW4oU3RvY2tJbmRleCkNCiAgKQ0KDQpwcmludChjZW50cm9pZHMpDQpgYGANCkNlbGtvdm8gamUgenJlam3DqSwgxb5lIGplZG5vdGxpdsOpIGtsYXN0cnkgc2Egb2RsacWhdWrDuiBwcmVkb3bFoWV0a8O9bSB2IEdEUF9Hcm93dGgsIFVuZW1wbG95bWVudCBhIFN0b2NrSW5kZXgsIHByacSNb20ga2xhc3RlciAyIHByZWRzdGF2dWplIG5lZ2F0w612bnkgZWtvbm9taWNrw70gcmFzdCBzIG7DrXprb3UgbmV6YW1lc3RuYW5vc8Wlb3UsIGtsYXN0ZXIgMSBzdGFiaWxuw7ogZWtvbm9taWt1IHMgdnlzb2tvdSBuZXphbWVzdG5hbm9zxaVvdSBhIGtsYXN0ZXIgMyBkeW5hbWlja8O6IGVrb25vbWlrdSBzIHZ5c29rb3UgaW5mbMOhY2lvdSBhIMO6cm9rbWkuDQoNCiMjIFrDoXZlcg0KDQpOYSB6w6FrbGFkZSB2eWtvbmFuZWogYW5hbMO9enkgbWFrcm9la29ub21pY2vDvWNoIHVrYXpvdmF0ZcS+b3YgbW/Fvm5vIGtvbsWhdGF0b3ZhxaUsIMW+ZSBzbGVkb3ZhbsOpIHByZW1lbm7DqSBJbmZsYXRpb24sIEdEUF9Hcm93dGgsIFVuZW1wbG95bWVudCwgSW50ZXJlc3QgYSBTdG9ja0luZGV4IHBvc2t5dHVqw7ogY2VubsOpIGluZm9ybcOhY2llIG8gZWtvbm9taWNrZWogc3RhYmlsaXRlIGEgcmFzdGUga3JhasOtbi4NCg0KQW5hbMO9emEgb2RoYWxpbGEgdsO9em5hbW7DqSB2em9yeSBhIHJvemRpZWx5IG1lZHppIGVrb25vbWlrYW1pLCDEjW8gdW1vxb7FiHVqZSBsZXDFoWllIHBvcm96dW1lbmllIGljaCBla29ub21pY2vDqWhvIHByb2ZpbHUgYSBwb3NreXR1amUgcG9ka2xhZHkgcHJlIHBvcm92bsOhdmFjaXUgxaF0YXRpc3Rpa3UsIHBvbGl0aWNrw6kgcm96aG9kb3ZhbmllIGEgxI9hbMWhaWUgZWtvbm9tZXRyaWNrw6kgbW9kZWxvdmFuaWUuDQoNCg==