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==