Úvod

Klastrová (zhluková) analýza patrí medzi najpoužívanejšie metódy exploratívnej štatistiky. V praxi sa využíva všade tam, kde je potrebné rozdeliť pozorovania do homogénnych celkov - napríklad pri segmentácii zákazníkov v marketingu, identifikácii podobných krajín v makroekonomických ukazovateľoch, hodnotenízdravotných rizík, klasifikácii biologických vzoriek či v geoinformatike pri zoskupovaní priestorových sobjektov. Jej výhodou je, že pracuje s viacerými premennými naraz a dokáže odhaliť vzory, ktoré by pri samotnom hodnotení jednotlivých ukazovateľov zostali skryté. Správne zvolená metrika vzdialenosti a metóda zhlukovania umožňujú odhaliť skryté vzťahy v dátach, čím poskytujú cenný podklad pre rozhodovanie v rôznych oblastiach aplikovaného výskumu.

V našej analýze predstavíme využitie zhlukovej analýzy na spracovanie údajov o dopravných nehodách v Barcelone. Budeme využívať údaje za rok 2017. V Tab. 1. uvádzame celú nami používanú databázu.

Registered S3 methods overwritten by 'htmltools':
  method               from         
  print.html           tools:rstudio
  print.shiny.tag      tools:rstudio
  print.shiny.tag.list tools:rstudio
Registered S3 method overwritten by 'rmarkdown':
  method         from
  print.paged_df     
library(knitr)
library(kableExtra)
rm(list = ls())

udaje <- read.csv("barc_data.csv",
                  stringsAsFactors = FALSE,
                  sep = ";",
                  fileEncoding = "latin1")

udaje <- subset(udaje,
  District.Name %in% c(
    "Sants-Montjuïc", "Nou Barris", "Horta-Guinardó",
    "Sant Martí", "Ciutat Vella", "Les Corts"
  )
)

udaje <- udaje[, c("District.Name",
                   "Neighborhood.Name",
                   "Hour",
                   "Mild.injuries",
                   "Serious.injuries",
                   "Victims",
                   "Vehicles.involved")]

rownames(udaje) <- make.unique(udaje$District.Name)
udaje$District.Name <- NULL

Table 1.

udaje

Hierarchická zhluková analýza pracuje s mierami vzdialenosti medzi pozorovaniami. Aby boli tieto vzdialenosti porovnateľné, je potrebné, aby všetky premenné boli definované na rovnakejškále. Používame pritom tzv. z-škálovanie, pričom transformované \(z\) hodnoty (skóre) vypočítame nasledovne

\[z = \frac{x-\mu}{\sigma}\]

kde \(\mu\) je stredná hodnota a \(\sigma\) je štandardná odchýlka pozorovaní \(x\). Predpokladáme pritom, že súbor údajov už neobsahuje NA hodnoty, ktoré boli ošetrené v predchádzajúcich krokoch.

Touto operáciou získame škálované pozorovania, pričom ich rozloženie je znázornené nasledovne:

# =======================================================
## 1) Príprava údajov a data.frame so šlálovanými údajmi
## ======================================================
udaje_numeric <- udaje[, sapply(udaje, is.numeric)]
udaje_complete <- na.omit(udaje_numeric)
udaje_scaled <- scale(udaje_complete)

Obr. 1.

num_vars <- as.data.frame(udaje_scaled)
num_plots <- ncol(num_vars)

par(mfrow = c(ceiling(sqrt(num_plots)), ceiling(num_plots / ceiling(sqrt(num_plots)))))
par(mar = c(4, 4, 2, 1))

for (col in names(num_vars)) {
  boxplot(num_vars[[col]],
          main = col,
          col = "lightpink",
          horizontal = TRUE)
}

mtext("Boxploty numerických premenných (rok 2017)", outer = TRUE, cex = 1.3, font = 2)

Tentokrát odľahlé hodnoty nevylúčime, keďže predstavujú reálne výnimočné situácie v dopravných nehodách a sú dôležité pre pochopenie ich charakteru.

Interpretácia box-plotov numerických premenných (rok 2017)

Mild.injuries (ľahké zranenia)

Rozdelenie ľahkých zranení ukazuje, že väčšina nehôd vedie k najviac jednému ľahkému zraneniu. Medián je blízko hodnoty 0–1 a rozptyl nie je veľký. Vyskytujú sa však aj prípady s vyšším počtom ľahkých zranení, ktoré sa prejavujú ako odľahlejšie hodnoty, no vzhľadom na charakter dopravných nehôd sú pre túto premennú prirodzené.

Serious.injuries (vážne zranenia)

Premenná má veľmi nízke hodnoty s extrémne malým rozptylom. Vo väčšine nehôd sa nevyskytlo žiadne vážne zranenie (hodnota 0). Len niekoľko prípadov obsahuje vážnejšie následky, čo sa prejavuje ako odľahlé body na grafe. Táto premenná má výraznú šikmosť smerom k nule, čo odráža realitu, že vážne zranenia sú relatívne zriedkavé.

Victims (obete / zranené osoby celkovo)

Podobne ako pri ľahkých zraneniach, väčšina nehôd má nízky počet zasiahnutých osôb (medián je nízky, rozptyl mierny). Krabicový diagram ukazuje, že najčastejšie ide o 1–2 osoby. Odľahlé hodnoty predstavujú nehody s vyšším počtom účastníkov alebo zranených, ale vzhľadom na mestský charakter dopravných situácií sú tieto prípady pomerne výnimočné.

Vehicles.involved (počet zúčastnených vozidiel)

Počet zapojených vozidiel sa väčšinou pohybuje medzi 1 a 2 vozidlami. Medián je okolo hodnoty 1, čo potvrdzuje, že najčastejšie ide o kolízie jedného alebo dvoch vozidiel. Dlhší pravý chvost a odľahlé hodnoty ukazujú, že zriedkavo sa vyskytnú aj nehody s viacerými vozidlami, ktoré však tvoria malé percento.

Pri zhlukovej analýze je dôležitá korelačná matica premenných. Vysoká korelácia zvýhodňuje pri zhlukovej analýze korelované premenné. Preto pri korelácii nad 0,8 alebo 0.9 vylúčime jednu z korelovaných premenných. V Tab. 2. sa však takáto vysoká korelácia nenachádza, preto sa nemusíme ďalej s problémom zaoberať. > V prípade, ak máme väčší počet významne korelovaných premenných, sa odporúča i transformácia pomocou Analýzy hlavných komponentov (Principal Component Analysis)

Tab. 2

cor_mat <- cor(udaje_scaled, use="pairwise.complete.obs")
cor_mat <- round(cor_mat,2)
print(cor_mat)
                  Mild.injuries Serious.injuries Victims Vehicles.involved
Mild.injuries              1.00             0.23    0.97              0.28
Serious.injuries           0.23             1.00    0.39              0.13
Victims                    0.97             0.39    1.00              0.30
Vehicles.involved          0.28             0.13    0.30              1.00

Každej mestskej časti (štvrti) zodpovedá v databáze jeden riadok pozorovaní. Vzdialenosť medzi dvoma štvrťami \(i\) a \(j\) je:

\[ d^{ij} = \sqrt{\sum_k (x^i_k - x^j_k)^2} \] kde \(x^i_k\) je hodnota \(k\)-tej premennej vstupujúcej do výpočtu (Mild.injuries, Serious.injuries, Victims, Vehicles.involved) pre štvrť \(i\). Tento typ vzdialenosti nazývame aj Euklidovská vzdialenosť.

Vzdialenosti medzi jednotlivými štvrťami Barcelony sú súhrnne vyjadrené v Tab. 3, ktorá predstavuje maticu vzájomných vzdialeností. Analýzou tejto tabuľky vieme určiť, ktoré štvrte sú si podľa sledovaných ukazovateľov najviac podobné a ktoré sa naopak od seba výrazne líšia.

Nízke hodnoty vzdialenosti naznačujú, že dané štvrte majú podobný počet zranení a podobný počet zapojených vozidiel (napríklad viaceré časti Sant Martí alebo viaceré podskupiny Les Corts). Vysoké hodnoty vzdialenosti poukazujú na odlišné profily dopravných nehôd – napríklad rozdielny počet obetí, rôzny počet vozidiel alebo rozdielny výskyt vážnych zranení.

Tieto rozdiely sú prirodzené, pretože jednotlivé štvrte Barcelony sa líšia dopravnou zaťaženosťou, hustotou premávky, urbanistickou štruktúrou a typom ulíc, čo sa odráža aj v charaktere vzniknutých dopravných nehôd.

Tab. 3

## ============================
## 3) Distance matrix
## ============================
rownames(udaje_scaled) <- rownames(udaje_complete)

dist_mat <- round(dist(udaje_scaled, method = "euclidean"), 2)

dist_mat
                 Nou Barris Horta-Guinardó Sant Martí Sant Martí.1 Nou Barris.1
Horta-Guinardó         1.67                                                    
Sant Martí             0.00           1.67                                     
Sant Martí.1           2.56           3.86       2.56                          
Nou Barris.1           0.00           1.67       0.00         2.56             
Sant Martí.2           2.56           3.86       2.56         0.00         2.56
Les Corts              1.94           2.56       1.94         1.67         1.94
Les Corts.1            0.00           1.67       0.00         2.56         0.00
Horta-Guinardó.1       2.56           3.86       2.56         0.00         2.56
Les Corts.2            5.33           6.50       5.33         4.04         5.33
Horta-Guinardó.2       2.56           1.94       2.56         3.33         2.56
Ciutat Vella           1.94           2.56       1.94         1.67         1.94
Sant Martí.3           2.56           1.94       2.56         3.33         2.56
Les Corts.3            1.94           2.56       1.94         1.67         1.94
Horta-Guinardó.3       4.23           5.12       4.23         1.94         4.23
Les Corts.4            2.56           3.86       2.56         0.00         2.56
Sant Martí.4           1.94           2.56       1.94         1.67         1.94
Les Corts.5            3.86           5.36       3.86         1.67         3.86
Horta-Guinardó.4       1.94           2.56       1.94         1.67         1.94
Les Corts.6            1.94           2.56       1.94         1.67         1.94
Nou Barris.2           3.86           5.36       3.86         1.67         3.86
Sant Martí.5           1.94           2.56       1.94         1.67         1.94
Nou Barris.3           1.94           2.56       1.94         1.67         1.94
Horta-Guinardó.5       0.00           1.67       0.00         2.56         0.00
Horta-Guinardó.6       4.32           4.92       4.32         3.87         4.32
Horta-Guinardó.7       1.67           3.33       1.67         1.94         1.67
                 Sant Martí.2 Les Corts Les Corts.1 Horta-Guinardó.1 Les Corts.2
Horta-Guinardó                                                                  
Sant Martí                                                                      
Sant Martí.1                                                                    
Nou Barris.1                                                                    
Sant Martí.2                                                                    
Les Corts                1.67                                                   
Les Corts.1              2.56      1.94                                         
Horta-Guinardó.1         0.00      1.67        2.56                             
Les Corts.2              4.04      4.96        5.33             4.04            
Horta-Guinardó.2         3.33      1.67        2.56             3.33        6.21
Ciutat Vella             1.67      0.00        1.94             1.67        4.96
Sant Martí.3             3.33      1.67        2.56             3.33        6.21
Les Corts.3              1.67      0.00        1.94             1.67        4.96
Horta-Guinardó.3         1.94      2.56        4.23             1.94        4.48
Les Corts.4              0.00      1.67        2.56             0.00        4.04
Sant Martí.4             1.67      0.00        1.94             1.67        4.96
Les Corts.5              1.67      3.33        3.86             1.67        3.68
Horta-Guinardó.4         1.67      0.00        1.94             1.67        4.96
Les Corts.6              1.67      0.00        1.94             1.67        4.96
Nou Barris.2             1.67      3.33        3.86             1.67        3.68
Sant Martí.5             1.67      0.00        1.94             1.67        4.96
Nou Barris.3             1.67      0.00        1.94             1.67        4.96
Horta-Guinardó.5         2.56      1.94        0.00             2.56        5.33
Horta-Guinardó.6         3.87      3.86        4.32             3.87        2.64
Horta-Guinardó.7         1.94      2.56        1.67             1.94        4.48
                 Horta-Guinardó.2 Ciutat Vella Sant Martí.3 Les Corts.3
Horta-Guinardó                                                         
Sant Martí                                                             
Sant Martí.1                                                           
Nou Barris.1                                                           
Sant Martí.2                                                           
Les Corts                                                              
Les Corts.1                                                            
Horta-Guinardó.1                                                       
Les Corts.2                                                            
Horta-Guinardó.2                                                       
Ciutat Vella                 1.67                                      
Sant Martí.3                 0.00         1.67                         
Les Corts.3                  1.67         0.00         1.67            
Horta-Guinardó.3             3.86         2.56         3.86        2.56
Les Corts.4                  3.33         1.67         3.33        1.67
Sant Martí.4                 1.67         0.00         1.67        0.00
Les Corts.5                  5.00         3.33         5.00        3.33
Horta-Guinardó.4             1.67         0.00         1.67        0.00
Les Corts.6                  1.67         0.00         1.67        0.00
Nou Barris.2                 5.00         3.33         5.00        3.33
Sant Martí.5                 1.67         0.00         1.67        0.00
Nou Barris.3                 1.67         0.00         1.67        0.00
Horta-Guinardó.5             2.56         1.94         2.56        1.94
Horta-Guinardó.6             4.52         3.86         4.52        3.86
Horta-Guinardó.7             3.86         2.56         3.86        2.56
                 Horta-Guinardó.3 Les Corts.4 Sant Martí.4 Les Corts.5
Horta-Guinardó                                                        
Sant Martí                                                            
Sant Martí.1                                                          
Nou Barris.1                                                          
Sant Martí.2                                                          
Les Corts                                                             
Les Corts.1                                                           
Horta-Guinardó.1                                                      
Les Corts.2                                                           
Horta-Guinardó.2                                                      
Ciutat Vella                                                          
Sant Martí.3                                                          
Les Corts.3                                                           
Horta-Guinardó.3                                                      
Les Corts.4                  1.94                                     
Sant Martí.4                 2.56        1.67                         
Les Corts.5                  2.56        1.67         3.33            
Horta-Guinardó.4             2.56        1.67         0.00        3.33
Les Corts.6                  2.56        1.67         0.00        3.33
Nou Barris.2                 2.56        1.67         3.33        0.00
Sant Martí.5                 2.56        1.67         0.00        3.33
Nou Barris.3                 2.56        1.67         0.00        3.33
Horta-Guinardó.5             4.23        2.56         1.94        3.86
Horta-Guinardó.6             4.33        3.87         3.86        4.53
Horta-Guinardó.7             3.89        1.94         2.56        2.56
                 Horta-Guinardó.4 Les Corts.6 Nou Barris.2 Sant Martí.5
Horta-Guinardó                                                         
Sant Martí                                                             
Sant Martí.1                                                           
Nou Barris.1                                                           
Sant Martí.2                                                           
Les Corts                                                              
Les Corts.1                                                            
Horta-Guinardó.1                                                       
Les Corts.2                                                            
Horta-Guinardó.2                                                       
Ciutat Vella                                                           
Sant Martí.3                                                           
Les Corts.3                                                            
Horta-Guinardó.3                                                       
Les Corts.4                                                            
Sant Martí.4                                                           
Les Corts.5                                                            
Horta-Guinardó.4                                                       
Les Corts.6                  0.00                                      
Nou Barris.2                 3.33        3.33                          
Sant Martí.5                 0.00        0.00         3.33             
Nou Barris.3                 0.00        0.00         3.33         0.00
Horta-Guinardó.5             1.94        1.94         3.86         1.94
Horta-Guinardó.6             3.86        3.86         4.53         3.86
Horta-Guinardó.7             2.56        2.56         2.56         2.56
                 Nou Barris.3 Horta-Guinardó.5 Horta-Guinardó.6
Horta-Guinardó                                                 
Sant Martí                                                     
Sant Martí.1                                                   
Nou Barris.1                                                   
Sant Martí.2                                                   
Les Corts                                                      
Les Corts.1                                                    
Horta-Guinardó.1                                               
Les Corts.2                                                    
Horta-Guinardó.2                                               
Ciutat Vella                                                   
Sant Martí.3                                                   
Les Corts.3                                                    
Horta-Guinardó.3                                               
Les Corts.4                                                    
Sant Martí.4                                                   
Les Corts.5                                                    
Horta-Guinardó.4                                               
Les Corts.6                                                    
Nou Barris.2                                                   
Sant Martí.5                                                   
Nou Barris.3                                                   
Horta-Guinardó.5         1.94                                  
Horta-Guinardó.6         3.86             4.32                 
Horta-Guinardó.7         2.56             1.67             4.33

Princíp hierarchického zhlukovania (Wardova metóda)

Zhlukovanie v prípade Wardovej metódy prebieha zdola smerom nahor, t.j. začíname s jednočlennými klastrami, ktoré postupne zlučujeme. Táto metóda patrí teda medzi aglomeratívne hierarchické metódy. Minimalizuje nárast vnútornej variability pri spojení dvoch klastrov, pričom využíva nasledovné výpočty:

Wardová metóda minimalizuje sumu štvorcov chýb (Error sum of Squares - ESS)

\[ESS(C) = \sum_{i \in C} \lVert x_i - \bar{x}_C \rVert^2\] kde \(C\) je zvažovaný klaster (zhluk). V každom kroku zlučovania dvoch klasterov, Wardova metóda hľadá minimálny prírastok sumy štvorcov chýb (\(\Delta ESS\)), pričom

\[\Delta ESS = ESS(A \cup B) - ESS(A) - ESS(B)\] Dvojica zhlukov, ktoré tejto podmienke o minimalizácii vyhovuje, je následne zlúčená a prechádza sa k ďalšiemu kkroku. To spravidla vedie k vytváraniu homogénnych zhlukov, pričom nedochádza k odtrhávaniu odľahlých hodnôt tak, ako pri iných zhlukovacích metódach.

Obr. 2. Hierarchické zhlukovanie - dendogram. Červená čiara určuje rez definujúci tri klastre.

## ============================
## 4) Hierarchical klastering
## ============================
hc <- hclust(dist_mat, method = "ward.D2")

plot(hc,
     labels = rownames(udaje_scaled),
     main = "Hierarchical clustering (Ward.D2) – barc_data",
     xlab = "", sub = "")

k <- 3
h_cut <- hc$height[length(hc$height) - (k - 1)]
abline(h = h_cut, col = "red", lwd = 2, lty = 2)


klaster_membership <- cutree(hc, k = k)

udaje_klasters <- data.frame(
  Row = rownames(udaje_scaled),   # R1, R2, R3...
  udaje_complete,                 
  klaster = factor(klaster_membership)
)

Tab.4. Príslušnosť mestských častí do klastrov.

data_prac <- data.frame(District.Name = rownames(udaje_klasters),
  klaster     = udaje_klasters$klaster)
colnames(data_prac) <- c("District.Name","klaster")
data_prac

Vykonaná klastrová analýza zatriedila jednotlivé mestské časti Barcelony do troch klastrov.

Klaster 1 tvorí najväčší počet štvr­tí. Ide najmä o časti, ktoré majú podobné hodnoty sledovaných ukazovateľov – relatívne nízky počet vážnych aj ľahkých zranení a podobný počet účastných vozidiel. Patria sem napríklad Nou Barris, Horta-Guinardó, viacero častí Sant Martí či väčšina podjednotiek štvrte Les Corts. Tieto mestské časti majú stabilný a pomerne homogénny profil dopravných nehôd.

Klaster 2 združuje štvrte, ktoré sa od prvej skupiny mierne odlišujú vyššími hodnotami niektorých premenných – napríklad väčším počtom zranení alebo vyšším počtom zúčastnených vozidiel. Do tejto skupiny patria niektoré podčasti Sant Martí a Les Corts. Tieto územia sa vyznačujú o niečo výraznejším dopravným zaťažením alebo špecifickými lokálnymi podmienkami.

Klaster 3 je najmenší a tvoria ho len niektoré časti, ktoré sa od ostatných štvrtí líšia výraznejším profilom dopravných nehôd – napríklad vyšším počtom obetí, vyšším podielom vážnych zranení alebo špecifickými dopravnými situáciami. Tento klaster reprezentuje anomálne alebo štatisticky výnimočné oblasti v rámci dopravnej bezpečnosti Barcelony.

Celkovo klastrová analýza umožnila identifikovať skupiny mestských častí, ktoré majú podobný charakter dopravných nehôd. Rozdelenie na tri klastre zodpovedá rozdielom v intenzite premávky, urbanistickej štruktúre ako aj v typických dopravných situáciách jednotlivých častí mesta.

Deskriptívne štatistiky výsledkov

Na základe Tab. 5 môžeme konštatovať, že vnútroklastrová variabilita je pri väčšine premenných relatívne nízka, čo znamená, že klastre sú z hľadiska sledovaných charakteristík pomerne homogénne.

Premenné Mild.injuries, Serious.injuries a Victims vykazujú vysoký podiel medziklastrovej variability (Prop_Between), čo naznačuje, že dobre prispievajú k separácii jednotlivých klastrov a majú výrazný vplyv na výslednú klasifikáciu mestských častí.

Naopak premenná Vehicles.involved má výrazne nižší podiel medziklastrovej variability. To znamená, že počet zapojených vozidiel sa medzi klastrami líši menej ako ostatné premenné, a teda nie je takým silným separátorom. Jej prípadné vylúčenie by však zásadne neovplyvnilo kvalitu klastrovej analýzy, keďže ostatné premenné nesú dominantnú časť informácie.

Tab. 5. Vysvetlenie vnútroklastrovej variability z hľadiska jednotlivých premenných

## ============================
## 5) Variability measures
## ============================

ssq <- function(x, m) sum((x - m)^2)

var_names <- colnames(udaje_scaled)

TSS <- sapply(var_names, function(v) ssq(udaje_scaled[, v], mean(udaje_scaled[, v])))

WSS <- sapply(var_names, function(v) {
  x <- udaje_scaled[, v]
  tapply(x, klaster_membership, function(z) ssq(z, mean(z))) |> sum()
})

BSS <- TSS - WSS

ss_table <- data.frame(
  Variable = var_names,
  TSS = TSS,
  WSS = WSS,
  BSS = BSS,
  Prop_Between = BSS / TSS
)

ss_table
attach(udaje)
udaje <- data.frame(cbind(udaje,udaje_klasters$klaster))
colnames(udaje) <- c("Mild_injuries",
                     "Serious_injuries",
                     "Victims",
                     "Vehicles_involved",
                     "Hour",
                     "klaster")

Tab. 6. Centroidy - priemerné hodnoty sledovaných premenných

library(dplyr)

names(udaje) <- make.names(names(udaje), unique = TRUE)

descriptives <- udaje %>%
  group_by(klaster) %>%
  summarise(
    across(
      .cols = where(is.numeric),
      .fns = list(
        mean = ~mean(.x, na.rm = TRUE)
      ),
      .names = "{.col}_{.fn}"
    )
  )

descriptives

Klaster 1 má najnižšie priemerné hodnoty premenných. Štvrte v tomto klastri majú priemerne 1 obeť, veľmi nízky počet zapojených vozidiel a nehody sa vyskytujú skôr v skorších hodinách dňa. Tento klaster predstavuje relatívne menej závažné nehody s jednoduchou štruktúrou.

Klaster 2 má priemerné hodnoty mierne vyššie než klaster 1. Pre tento klaster je typické, že priemerne sa vyskytuje viac obetí (1,44) a zároveň aj mierne vyšší počet zapojených vozidiel. Hodina výskytu nehôd je tu tiež o niečo vyššia. Tento klaster reprezentuje mestské časti s o niečo komplikovanejšími nehodami.

Klaster 3 má najvyššie priemerné hodnoty pre premennú Victims_mean, kde priemer dosahuje 2 obete na nehodu. Na druhej strane však nevykazuje zvýšený počet zapojených vozidiel – ten ostáva nízky ako v klastri 1. Nehody v tomto klastri sa typicky odohrávajú v neskorších hodinách. Klaster 3 teda predstavuje oblasti s menej častými, ale závažnejšími následkami nehôd.

Celkovo centroidy ukazujú, že klastre sa odlišujú najmä podľa počtu obetí, v menšej miere podľa počtu zapojených vozidiel a čiastočne podľa času, v ktorom nehody vznikajú.

Záver

Predložená analýza sa zaoberala charakteristikou dopravných nehôd v jednotlivých mestských častiach Barcelony na základe priemerných hodnôt vybraných premenných, ako sú počet obetí, počet zapojených vozidiel či čas vzniku nehody. Na základe zhlukovej analýzy boli mestské časti rozdelené do troch klastrov, pričom jednotlivé klastre odrážajú rozdiely v závažnosti nehôd, ich typickom priebehu a časovom rozložení.

Výsledky analýzy ukazujú, že niektoré mestské časti majú veľmi podobný profil nehôd, zatiaľ čo iné sa vyznačujú výrazne odlišnými charakteristikami. Takéto poznatky môžu byť užitočné pre mestské plánovanie, dopravné riadenie aj preventívne politiky zamerané na zvýšenie bezpečnosti v konkrétnych lokalitách Barcelony. Na základe príslušnosti ku klastrom je možné lepšie identifikovať oblasti, ktoré si vyžadujú cielené opatrenia, úpravu dopravnej infraštruktúry alebo zvýšenú pozornosť zo strany miestnych orgánov.

LS0tCnRpdGxlOiAiWmhsdWtvdsOhIGFuYWzDvXphIChrbGFzdGVyIEFuYWx5c2lzKSIKYXV0aG9yOiAiTW9uaWthIFN6xbFjc292w6EgKHphIHBvbW9jaSBDaGF0R1BUKSIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKLS0tLS0tLS0tCgpgYGB7ciBzZXR1cDEsIGluY2x1ZGU9RkFMU0V9CmtuaXRyOjpvcHRzX2NodW5rJHNldCgKICBlY2hvICAgID0gVFJVRSwgICAjIGRvIG5vdCBzaG93IGNvZGUKICBtZXNzYWdlID0gVFJVRSwgICAjIHN1cHByZXNzIHBhY2thZ2Uvc3lzdGVtIG1lc3NhZ2VzCiAgd2FybmluZyA9IEZBTFNFLCAgICMgc3VwcHJlc3Mgd2FybmluZ3MKICBlcnJvciAgID0gRkFMU0UgICAgIyBzdXBwcmVzcyBlcnJvciBvdXRwdXQKKQpgYGAKCiMjIMOadm9kCgpLbGFzdHJvdsOhICh6aGx1a292w6EpIGFuYWzDvXphIHBhdHLDrSBtZWR6aSBuYWpwb3XFvsOtdmFuZWrFoWllIG1ldMOzZHkgZXhwbG9yYXTDrXZuZWogxaF0YXRpc3Rpa3kuIFYgcHJheGkgc2Egdnl1xb7DrXZhIHbFoWFkZSB0YW0sIGtkZSBqZSBwb3RyZWJuw6kgcm96ZGVsacWlIHBvem9yb3ZhbmlhIGRvIGhvbW9nw6lubnljaCBjZWxrb3YgLSBuYXByw61rbGFkIHByaSBzZWdtZW50w6FjaWkgesOha2F6bsOta292IHYgbWFya2V0aW5ndSwgaWRlbnRpZmlrw6FjaWkgcG9kb2Juw71jaCBrcmFqw61uIHYgbWFrcm9la29ub21pY2vDvWNoIHVrYXpvdmF0ZcS+b2NoLCBob2Rub3RlbsOtemRyYXZvdG7DvWNoIHJpesOtaywga2xhc2lmaWvDoWNpaSBiaW9sb2dpY2vDvWNoIHZ6b3JpZWsgxI1pIHYgZ2VvaW5mb3JtYXRpa2UgcHJpIHpvc2t1cG92YW7DrSBwcmllc3Rvcm92w71jaCBzb2JqZWt0b3YuIEplaiB2w71ob2RvdSBqZSwgxb5lIHByYWN1amUgcyB2aWFjZXLDvW1pIHByZW1lbm7DvW1pIG5hcmF6IGEgZG9rw6HFvmUgb2RoYWxpxaUgdnpvcnksIGt0b3LDqSBieSBwcmkgc2Ftb3Rub20gaG9kbm90ZW7DrSBqZWRub3RsaXbDvWNoIHVrYXpvdmF0ZcS+b3Ygem9zdGFsaSBza3J5dMOpLiBTcHLDoXZuZSB6dm9sZW7DoSBtZXRyaWthIHZ6ZGlhbGVub3N0aSBhIG1ldMOzZGEgemhsdWtvdmFuaWEgdW1vxb7FiHVqw7ogb2RoYWxpxaUgc2tyeXTDqSB2esWlYWh5IHYgZMOhdGFjaCwgxI3DrW0gcG9za3l0dWrDuiBjZW5uw70gcG9ka2xhZCBwcmUgcm96aG9kb3ZhbmllIHYgcsO0em55Y2ggb2JsYXN0aWFjaCBhcGxpa292YW7DqWhvIHbDvXNrdW11LgoKViBuYcWhZWogYW5hbMO9emUgcHJlZHN0YXbDrW1lIHZ5dcW+aXRpZSB6aGx1a292ZWogYW5hbMO9enkgbmEgc3ByYWNvdmFuaWUgw7pkYWpvdiBvIGRvcHJhdm7DvWNoIG5laG9kw6FjaCB2IEJhcmNlbG9uZS4gQnVkZW1lIHZ5dcW+w612YcWlIMO6ZGFqZSB6YSByb2sgMjAxNy4gViAqKlRhYi4gMS4qKiB1dsOhZHphbWUgY2Vsw7ogbmFtaSBwb3XFvsOtdmFuw7ogZGF0YWLDoXp1LgoKYGBge3Igc2V0dXAyLCBtZXNzYWdlPUZBTFNFfQpsaWJyYXJ5KGtuaXRyKQpsaWJyYXJ5KGthYmxlRXh0cmEpCmBgYAoKCmBgYHtyfQpybShsaXN0ID0gbHMoKSkKCnVkYWplIDwtIHJlYWQuY3N2KCJiYXJjX2RhdGEuY3N2IiwKICAgICAgICAgICAgICAgICAgc3RyaW5nc0FzRmFjdG9ycyA9IEZBTFNFLAogICAgICAgICAgICAgICAgICBzZXAgPSAiOyIsCiAgICAgICAgICAgICAgICAgIGZpbGVFbmNvZGluZyA9ICJsYXRpbjEiKQoKdWRhamUgPC0gc3Vic2V0KHVkYWplLAogIERpc3RyaWN0Lk5hbWUgJWluJSBjKAogICAgIlNhbnRzLU1vbnRqdcOvYyIsICJOb3UgQmFycmlzIiwgIkhvcnRhLUd1aW5hcmTDsyIsCiAgICAiU2FudCBNYXJ0w60iLCAiQ2l1dGF0IFZlbGxhIiwgIkxlcyBDb3J0cyIKICApCikKCnVkYWplIDwtIHVkYWplWywgYygiRGlzdHJpY3QuTmFtZSIsCiAgICAgICAgICAgICAgICAgICAiTmVpZ2hib3Job29kLk5hbWUiLAogICAgICAgICAgICAgICAgICAgIkhvdXIiLAogICAgICAgICAgICAgICAgICAgIk1pbGQuaW5qdXJpZXMiLAogICAgICAgICAgICAgICAgICAgIlNlcmlvdXMuaW5qdXJpZXMiLAogICAgICAgICAgICAgICAgICAgIlZpY3RpbXMiLAogICAgICAgICAgICAgICAgICAgIlZlaGljbGVzLmludm9sdmVkIildCgpyb3duYW1lcyh1ZGFqZSkgPC0gbWFrZS51bmlxdWUodWRhamUkRGlzdHJpY3QuTmFtZSkKdWRhamUkRGlzdHJpY3QuTmFtZSA8LSBOVUxMCmBgYAoKKipUYWJsZSAxLioqCmBgYHtyfQp1ZGFqZQpgYGAKCkhpZXJhcmNoaWNrw6EgemhsdWtvdsOhIGFuYWzDvXphIHByYWN1amUgcyBtaWVyYW1pIHZ6ZGlhbGVub3N0aSBtZWR6aSBwb3pvcm92YW5pYW1pLiBBYnkgYm9saSB0aWV0byB2emRpYWxlbm9zdGkgcG9yb3ZuYXRlxL5uw6ksIGplIHBvdHJlYm7DqSwgYWJ5IHbFoWV0a3kgcHJlbWVubsOpIGJvbGkgZGVmaW5vdmFuw6kgbmEgcm92bmFrZWrFoWvDoWxlLiBQb3XFvsOtdmFtZSBwcml0b20gdHp2LiB6LcWha8OhbG92YW5pZSwgcHJpxI1vbSB0cmFuc2Zvcm1vdmFuw6kgJHokIGhvZG5vdHkgKHNrw7NyZSkgdnlwb8SNw610YW1lIG5hc2xlZG92bmUKCiQkeiA9IFxmcmFje3gtXG11fXtcc2lnbWF9JCQKCmtkZSAkXG11JCBqZSBzdHJlZG7DoSBob2Rub3RhIGEgJFxzaWdtYSQgamUgxaF0YW5kYXJkbsOhIG9kY2jDvWxrYSBwb3pvcm92YW7DrSAkeCQuIFByZWRwb2tsYWTDoW1lIHByaXRvbSwgxb5lIHPDumJvciDDumRham92IHXFviBuZW9ic2FodWplIE5BIGhvZG5vdHksIGt0b3LDqSBib2xpIG/FoWV0cmVuw6kgdiBwcmVkY2jDoWR6YWrDumNpY2gga3Jva29jaC4KClRvdXRvIG9wZXLDoWNpb3UgesOtc2thbWUgxaFrw6Fsb3ZhbsOpIHBvem9yb3ZhbmlhLCBwcmnEjW9tIGljaCByb3psb8W+ZW5pZSBqZSB6bsOhem9ybmVuw6kgbmFzbGVkb3ZuZToKCgpgYGB7cn0KIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiMjIDEpIFByw61wcmF2YSDDumRham92IGEgZGF0YS5mcmFtZSBzbyDFoWzDoWxvdmFuw71taSDDumRham1pCiMjID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQp1ZGFqZV9udW1lcmljIDwtIHVkYWplWywgc2FwcGx5KHVkYWplLCBpcy5udW1lcmljKV0KdWRhamVfY29tcGxldGUgPC0gbmEub21pdCh1ZGFqZV9udW1lcmljKQp1ZGFqZV9zY2FsZWQgPC0gc2NhbGUodWRhamVfY29tcGxldGUpCmBgYAoKCioqT2JyLiAxLioqCmBgYHtyIGJveHBsb3RzLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBmaWcuc2hvdz0naG9sZCd9Cm51bV92YXJzIDwtIGFzLmRhdGEuZnJhbWUodWRhamVfc2NhbGVkKQpudW1fcGxvdHMgPC0gbmNvbChudW1fdmFycykKCnBhcihtZnJvdyA9IGMoY2VpbGluZyhzcXJ0KG51bV9wbG90cykpLCBjZWlsaW5nKG51bV9wbG90cyAvIGNlaWxpbmcoc3FydChudW1fcGxvdHMpKSkpKQpwYXIobWFyID0gYyg0LCA0LCAyLCAxKSkKCmZvciAoY29sIGluIG5hbWVzKG51bV92YXJzKSkgewogIGJveHBsb3QobnVtX3ZhcnNbW2NvbF1dLAogICAgICAgICAgbWFpbiA9IGNvbCwKICAgICAgICAgIGNvbCA9ICJsaWdodHBpbmsiLAogICAgICAgICAgaG9yaXpvbnRhbCA9IFRSVUUpCn0KCm10ZXh0KCJCb3hwbG90eSBudW1lcmlja8O9Y2ggcHJlbWVubsO9Y2ggKHJvayAyMDE3KSIsIG91dGVyID0gVFJVRSwgY2V4ID0gMS4zLCBmb250ID0gMikKYGBgCgoKVGVudG9rcsOhdCBvZMS+YWhsw6kgaG9kbm90eSBuZXZ5bMO6xI1pbWUsIGtlxI/FvmUgcHJlZHN0YXZ1asO6IHJlw6FsbmUgdsO9bmltb8SNbsOpIHNpdHXDoWNpZSB2IGRvcHJhdm7DvWNoIG5laG9kw6FjaCBhIHPDuiBkw7RsZcW+aXTDqSBwcmUgcG9jaG9wZW5pZSBpY2ggY2hhcmFrdGVydS4gCgojIyBJbnRlcnByZXTDoWNpYSBib3gtcGxvdG92IG51bWVyaWNrw71jaCBwcmVtZW5uw71jaCAocm9rIDIwMTcpCgojIyMgTWlsZC5pbmp1cmllcyAoxL5haGvDqSB6cmFuZW5pYSkKUm96ZGVsZW5pZSDEvmFoa8O9Y2ggenJhbmVuw60gdWthenVqZSwgxb5lIHbDpMSNxaFpbmEgbmVow7RkIHZlZGllIGsgbmFqdmlhYyBqZWRuw6ltdSDEvmFoa8OpbXUgenJhbmVuaXUuIE1lZGnDoW4gamUgYmzDrXprbyBob2Rub3R5IDDigJMxIGEgcm96cHR5bCBuaWUgamUgdmXEvmvDvS4gVnlza3l0dWrDuiBzYSB2xaFhayBhaiBwcsOtcGFkeSBzIHZ5xaHFocOtbSBwb8SNdG9tIMS+YWhrw71jaCB6cmFuZW7DrSwga3RvcsOpIHNhIHByZWphdnVqw7ogYWtvIG9kxL5haGxlasWhaWUgaG9kbm90eSwgbm8gdnpoxL5hZG9tIG5hIGNoYXJha3RlciBkb3ByYXZuw71jaCBuZWjDtGQgc8O6IHByZSB0w7p0byBwcmVtZW5uw7ogcHJpcm9kemVuw6kuCgojIyMgU2VyaW91cy5pbmp1cmllcyAodsOhxb5uZSB6cmFuZW5pYSkKUHJlbWVubsOhIG3DoSB2ZcS+bWkgbsOtemtlIGhvZG5vdHkgcyBleHRyw6ltbmUgbWFsw71tIHJvenB0eWxvbS4gVm8gdsOkxI3FoWluZSBuZWjDtGQgc2EgbmV2eXNreXRsbyDFvmlhZG5lIHbDocW+bmUgenJhbmVuaWUgKGhvZG5vdGEgMCkuIExlbiBuaWVrb8S+a28gcHLDrXBhZG92IG9ic2FodWplIHbDocW+bmVqxaFpZSBuw6FzbGVka3ksIMSNbyBzYSBwcmVqYXZ1amUgYWtvIG9kxL5haGzDqSBib2R5IG5hIGdyYWZlLiBUw6F0byBwcmVtZW5uw6EgbcOhIHbDvXJhem7DuiDFoWlrbW9zxaUgc21lcm9tIGsgbnVsZSwgxI1vIG9kcsOhxb5hIHJlYWxpdHUsIMW+ZSB2w6HFvm5lIHpyYW5lbmlhIHPDuiByZWxhdMOtdm5lIHpyaWVka2F2w6kuCgojIyMgVmljdGltcyAob2JldGUgLyB6cmFuZW7DqSBvc29ieSBjZWxrb3ZvKQpQb2RvYm5lIGFrbyBwcmkgxL5haGvDvWNoIHpyYW5lbmlhY2gsIHbDpMSNxaFpbmEgbmVow7RkIG3DoSBuw616a3kgcG/EjWV0IHphc2lhaG51dMO9Y2ggb3PDtGIgKG1lZGnDoW4gamUgbsOtemt5LCByb3pwdHlsIG1pZXJueSkuIEtyYWJpY292w70gZGlhZ3JhbSB1a2F6dWplLCDFvmUgbmFqxI1hc3RlasWhaWUgaWRlIG8gMeKAkzIgb3NvYnkuIE9kxL5haGzDqSBob2Rub3R5IHByZWRzdGF2dWrDuiBuZWhvZHkgcyB2ecWhxaHDrW0gcG/EjXRvbSDDusSNYXN0bsOta292IGFsZWJvIHpyYW5lbsO9Y2gsIGFsZSB2emjEvmFkb20gbmEgbWVzdHNrw70gY2hhcmFrdGVyIGRvcHJhdm7DvWNoIHNpdHXDoWNpw60gc8O6IHRpZXRvIHByw61wYWR5IHBvbWVybmUgdsO9bmltb8SNbsOpLgoKIyMjIFZlaGljbGVzLmludm9sdmVkIChwb8SNZXQgesO6xI1hc3RuZW7DvWNoIHZvemlkaWVsKQpQb8SNZXQgemFwb2plbsO9Y2ggdm96aWRpZWwgc2EgdsOkxI3FoWlub3UgcG9oeWJ1amUgbWVkemkgMSBhIDIgdm96aWRsYW1pLiBNZWRpw6FuIGplIG9rb2xvIGhvZG5vdHkgMSwgxI1vIHBvdHZyZHp1amUsIMW+ZSBuYWrEjWFzdGVqxaFpZSBpZGUgbyBrb2zDrXppZSBqZWRuw6lobyBhbGVibyBkdm9jaCB2b3ppZGllbC4gRGxoxaHDrSBwcmF2w70gY2h2b3N0IGEgb2TEvmFobMOpIGhvZG5vdHkgdWthenVqw7osIMW+ZSB6cmllZGthdm8gc2Egdnlza3l0bsO6IGFqIG5laG9keSBzIHZpYWNlcsO9bWkgdm96aWRsYW1pLCBrdG9yw6kgdsWhYWsgdHZvcmlhIG1hbMOpIHBlcmNlbnRvLgoKUHJpIHpobHVrb3ZlaiBhbmFsw716ZSBqZSBkw7RsZcW+aXTDoSBrb3JlbGHEjW7DoSBtYXRpY2EgcHJlbWVubsO9Y2guIFZ5c29rw6Ega29yZWzDoWNpYSB6dsO9aG9kxYh1amUgcHJpIHpobHVrb3ZlaiBhbmFsw716ZSBrb3JlbG92YW7DqSBwcmVtZW5uw6kuIFByZXRvIHByaSBrb3JlbMOhY2lpIG5hZCAwLDggYWxlYm8gMC45IHZ5bMO6xI1pbWUgamVkbnUgeiBrb3JlbG92YW7DvWNoIHByZW1lbm7DvWNoLiBWICoqVGFiLiAyLioqIHNhIHbFoWFrIHRha8OhdG8gdnlzb2vDoSBrb3JlbMOhY2lhIG5lbmFjaMOhZHphLCBwcmV0byBzYSBuZW11c8OtbWUgxI9hbGVqIHMgcHJvYmzDqW1vbSB6YW9iZXJhxaUuIAo+IFYgcHLDrXBhZGUsIGFrIG3DoW1lIHbDpMSNxaHDrSBwb8SNZXQgdsO9em5hbW5lIGtvcmVsb3ZhbsO9Y2ggcHJlbWVubsO9Y2gsIHNhIG9kcG9yw7rEjWEgaSB0cmFuc2Zvcm3DoWNpYSBwb21vY291IEFuYWzDvXp5IGhsYXZuw71jaCBrb21wb25lbnRvdiAoUHJpbmNpcGFsIENvbXBvbmVudCBBbmFseXNpcykgCgoqKlRhYi4gMioqCmBgYHtyfQpjb3JfbWF0IDwtIGNvcih1ZGFqZV9zY2FsZWQsIHVzZT0icGFpcndpc2UuY29tcGxldGUub2JzIikKY29yX21hdCA8LSByb3VuZChjb3JfbWF0LDIpCnByaW50KGNvcl9tYXQpCmBgYAoKS2HFvmRlaiBtZXN0c2tlaiDEjWFzdGkgKMWhdHZydGkpIHpvZHBvdmVkw6EgdiBkYXRhYsOhemUgamVkZW4gcmlhZG9rIHBvem9yb3ZhbsOtLiBWemRpYWxlbm9zxaUgbWVkemkgZHZvbWEgxaF0dnLFpWFtaSAkaSQgYSAkaiQgamU6CgokJApkXntpan0gPSBcc3FydHtcc3VtX2sgKHheaV9rIC0geF5qX2spXjJ9CiQkCmtkZSAkeF5pX2skIGplIGhvZG5vdGEgJGskLXRlaiBwcmVtZW5uZWogdnN0dXB1asO6Y2VqIGRvIHbDvXBvxI10dSAoTWlsZC5pbmp1cmllcywgU2VyaW91cy5pbmp1cmllcywgVmljdGltcywgVmVoaWNsZXMuaW52b2x2ZWQpIHByZSDFoXR2csWlICRpJC4gVGVudG8gdHlwIHZ6ZGlhbGVub3N0aSBuYXrDvXZhbWUgYWogKkV1a2xpZG92c2vDoSB2emRpYWxlbm9zxaUqLiAKClZ6ZGlhbGVub3N0aSBtZWR6aSBqZWRub3RsaXbDvW1pIMWhdHZyxaVhbWkgQmFyY2Vsb255IHPDuiBzw7pocm5uZSB2eWphZHJlbsOpIHYgKipUYWIuIDMqKiwga3RvcsOhIHByZWRzdGF2dWplIG1hdGljdSB2esOham9tbsO9Y2ggdnpkaWFsZW5vc3TDrS4gQW5hbMO9em91IHRlanRvIHRhYnXEvmt5IHZpZW1lIHVyxI1pxaUsIGt0b3LDqSDFoXR2cnRlIHPDuiBzaSBwb2TEvmEgc2xlZG92YW7DvWNoIHVrYXpvdmF0ZcS+b3YgbmFqdmlhYyBwb2RvYm7DqSBhIGt0b3LDqSBzYSBuYW9wYWsgb2Qgc2ViYSB2w71yYXpuZSBsw63FoWlhLgoKTsOtemtlIGhvZG5vdHkgdnpkaWFsZW5vc3RpIG5hem5hxI11asO6LCDFvmUgZGFuw6kgxaF0dnJ0ZSBtYWrDuiBwb2RvYm7DvSBwb8SNZXQgenJhbmVuw60gYSBwb2RvYm7DvSBwb8SNZXQgemFwb2plbsO9Y2ggdm96aWRpZWwgKG5hcHLDrWtsYWQgdmlhY2Vyw6kgxI1hc3RpIFNhbnQgTWFydMOtIGFsZWJvIHZpYWNlcsOpIHBvZHNrdXBpbnkgTGVzIENvcnRzKS4KVnlzb2vDqSBob2Rub3R5IHZ6ZGlhbGVub3N0aSBwb3VrYXp1asO6IG5hIG9kbGnFoW7DqSBwcm9maWx5IGRvcHJhdm7DvWNoIG5laMO0ZCDigJMgbmFwcsOta2xhZCByb3pkaWVsbnkgcG/EjWV0IG9iZXTDrSwgcsO0em55IHBvxI1ldCB2b3ppZGllbCBhbGVibyByb3pkaWVsbnkgdsO9c2t5dCB2w6HFvm55Y2ggenJhbmVuw60uCgpUaWV0byByb3pkaWVseSBzw7ogcHJpcm9kemVuw6ksIHByZXRvxb5lIGplZG5vdGxpdsOpIMWhdHZydGUgQmFyY2Vsb255IHNhIGzDrcWhaWEgZG9wcmF2bm91IHphxaVhxb5lbm9zxaVvdSwgaHVzdG90b3UgcHJlbcOhdmt5LCB1cmJhbmlzdGlja291IMWhdHJ1a3TDunJvdSBhIHR5cG9tIHVsw61jLCDEjW8gc2Egb2Ryw6HFvmEgYWogdiBjaGFyYWt0ZXJlIHZ6bmlrbnV0w71jaCBkb3ByYXZuw71jaCBuZWjDtGQuCgoqKlRhYi4gMyoqCgpgYGB7cn0KIyMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PQojIyAzKSBEaXN0YW5jZSBtYXRyaXgKIyMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PQpyb3duYW1lcyh1ZGFqZV9zY2FsZWQpIDwtIHJvd25hbWVzKHVkYWplX2NvbXBsZXRlKQoKZGlzdF9tYXQgPC0gcm91bmQoZGlzdCh1ZGFqZV9zY2FsZWQsIG1ldGhvZCA9ICJldWNsaWRlYW4iKSwgMikKCmRpc3RfbWF0CmBgYAoKIyMgUHJpbmPDrXAgaGllcmFyY2hpY2vDqWhvIHpobHVrb3ZhbmlhIChXYXJkb3ZhIG1ldMOzZGEpCgpaaGx1a292YW5pZSB2IHByw61wYWRlIFdhcmRvdmVqIG1ldMOzZHkgcHJlYmllaGEgemRvbGEgc21lcm9tIG5haG9yLCB0LmouIHphxI3DrW5hbWUgcyBqZWRub8SNbGVubsO9bWkga2xhc3RyYW1pLCBrdG9yw6kgcG9zdHVwbmUgemx1xI11amVtZS4gVMOhdG8gbWV0w7NkYSBwYXRyw60gdGVkYSBtZWR6aSBhZ2xvbWVyYXTDrXZuZSBoaWVyYXJjaGlja8OpIG1ldMOzZHkuIE1pbmltYWxpenVqZSBuw6FyYXN0IHZuw7p0b3JuZWogdmFyaWFiaWxpdHkgcHJpIHNwb2plbsOtIGR2b2NoIGtsYXN0cm92LCBwcmnEjW9tIHZ5dcW+w612YSBuYXNsZWRvdm7DqSB2w71wb8SNdHk6CgpXYXJkb3bDoSBtZXTDs2RhIG1pbmltYWxpenVqZSBzdW11IMWhdHZvcmNvdiBjaMO9YiAoRXJyb3Igc3VtIG9mIFNxdWFyZXMgLSBFU1MpCgokJEVTUyhDKSA9IFxzdW1fe2kgXGluIEN9IFxsVmVydCB4X2kgLSBcYmFye3h9X0MgXHJWZXJ0XjIkJAprZGUgJEMkIGplIHp2YcW+b3ZhbsO9IGtsYXN0ZXIgKHpobHVrKS4gViBrYcW+ZG9tIGtyb2t1IHpsdcSNb3ZhbmlhIGR2b2NoIGtsYXN0ZXJvdiwgV2FyZG92YSBtZXTDs2RhIGjEvmFkw6EgbWluaW3DoWxueSBwcsOtcmFzdG9rIHN1bXkgxaF0dm9yY292IGNow71iICgkXERlbHRhIEVTUyQpLCBwcmnEjW9tCgokJFxEZWx0YSBFU1MgPSBFU1MoQSBcY3VwIEIpIC0gRVNTKEEpIC0gRVNTKEIpJCQKRHZvamljYSB6aGx1a292LCBrdG9yw6kgdGVqdG8gcG9kbWllbmtlIG8gbWluaW1hbGl6w6FjaWkgdnlob3Z1amUsIGplIG7DoXNsZWRuZSB6bMO6xI1lbsOhIGEgcHJlY2jDoWR6YSBzYSBrIMSPYWzFoWllbXUga2tyb2t1LiBUbyBzcHJhdmlkbGEgdmVkaWUgayB2eXR2w6FyYW5pdSBob21vZ8Opbm55Y2ggemhsdWtvdiwgcHJpxI1vbSBuZWRvY2jDoWR6YSBrIG9kdHJow6F2YW5pdSBvZMS+YWhsw71jaCBob2Ruw7R0IHRhaywgYWtvIHByaSBpbsO9Y2ggemhsdWtvdmFjw61jaCBtZXTDs2RhY2guCgoKKipPYnIuIDIuKiogSGllcmFyY2hpY2vDqSB6aGx1a292YW5pZSAtIGRlbmRvZ3JhbS4gxIxlcnZlbsOhIMSNaWFyYSB1csSNdWplIHJleiBkZWZpbnVqw7pjaSB0cmkga2xhc3RyZS4KYGBge3J9CiMjID09PT09PT09PT09PT09PT09PT09PT09PT09PT0KIyMgNCkgSGllcmFyY2hpY2FsIGtsYXN0ZXJpbmcKIyMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PQpoYyA8LSBoY2x1c3QoZGlzdF9tYXQsIG1ldGhvZCA9ICJ3YXJkLkQyIikKCnBsb3QoaGMsCiAgICAgbGFiZWxzID0gcm93bmFtZXModWRhamVfc2NhbGVkKSwKICAgICBtYWluID0gIkhpZXJhcmNoaWNhbCBjbHVzdGVyaW5nIChXYXJkLkQyKSDigJMgYmFyY19kYXRhIiwKICAgICB4bGFiID0gIiIsIHN1YiA9ICIiKQoKayA8LSAzCmhfY3V0IDwtIGhjJGhlaWdodFtsZW5ndGgoaGMkaGVpZ2h0KSAtIChrIC0gMSldCmFibGluZShoID0gaF9jdXQsIGNvbCA9ICJyZWQiLCBsd2QgPSAyLCBsdHkgPSAyKQoKa2xhc3Rlcl9tZW1iZXJzaGlwIDwtIGN1dHJlZShoYywgayA9IGspCgp1ZGFqZV9rbGFzdGVycyA8LSBkYXRhLmZyYW1lKAogIFJvdyA9IHJvd25hbWVzKHVkYWplX3NjYWxlZCksICAgIyBSMSwgUjIsIFIzLi4uCiAgdWRhamVfY29tcGxldGUsICAgICAgICAgICAgICAgICAKICBrbGFzdGVyID0gZmFjdG9yKGtsYXN0ZXJfbWVtYmVyc2hpcCkKKQoKYGBgCgoKKipUYWIuNC4qKiAgUHLDrXNsdcWhbm9zxaUgbWVzdHNrw71jaCDEjWFzdMOtIGRvIGtsYXN0cm92LgoKYGBge3J9CmRhdGFfcHJhYyA8LSBkYXRhLmZyYW1lKERpc3RyaWN0Lk5hbWUgPSByb3duYW1lcyh1ZGFqZV9rbGFzdGVycyksCiAga2xhc3RlciAgICAgPSB1ZGFqZV9rbGFzdGVycyRrbGFzdGVyKQpjb2xuYW1lcyhkYXRhX3ByYWMpIDwtIGMoIkRpc3RyaWN0Lk5hbWUiLCJrbGFzdGVyIikKZGF0YV9wcmFjCmBgYAoKVnlrb25hbsOhIGtsYXN0cm92w6EgYW5hbMO9emEgemF0cmllZGlsYSBqZWRub3RsaXbDqSBtZXN0c2vDqSDEjWFzdGkgQmFyY2Vsb255IGRvIHRyb2NoIGtsYXN0cm92LgoKS2xhc3RlciAxIHR2b3LDrSBuYWp2w6TEjcWhw60gcG/EjWV0IMWhdHZywq10w60uIElkZSBuYWptw6QgbyDEjWFzdGksIGt0b3LDqSBtYWrDuiBwb2RvYm7DqSBob2Rub3R5IHNsZWRvdmFuw71jaCB1a2F6b3ZhdGXEvm92IOKAkyByZWxhdMOtdm5lIG7DrXpreSBwb8SNZXQgdsOhxb5ueWNoIGFqIMS+YWhrw71jaCB6cmFuZW7DrSBhIHBvZG9ibsO9IHBvxI1ldCDDusSNYXN0bsO9Y2ggdm96aWRpZWwuIFBhdHJpYSBzZW0gbmFwcsOta2xhZCBOb3UgQmFycmlzLCBIb3J0YS1HdWluYXJkw7MsIHZpYWNlcm8gxI1hc3TDrSBTYW50IE1hcnTDrSDEjWkgdsOkxI3FoWluYSBwb2RqZWRub3RpZWsgxaF0dnJ0ZSBMZXMgQ29ydHMuIFRpZXRvIG1lc3Rza8OpIMSNYXN0aSBtYWrDuiBzdGFiaWxuw70gYSBwb21lcm5lIGhvbW9nw6lubnkgcHJvZmlsIGRvcHJhdm7DvWNoIG5laMO0ZC4KCktsYXN0ZXIgMiB6ZHJ1xb51amUgxaF0dnJ0ZSwga3RvcsOpIHNhIG9kIHBydmVqIHNrdXBpbnkgbWllcm5lIG9kbGnFoXVqw7ogdnnFocWhw61taSBob2Rub3RhbWkgbmlla3RvcsO9Y2ggcHJlbWVubsO9Y2gg4oCTIG5hcHLDrWtsYWQgdsOkxI3FocOtbSBwb8SNdG9tIHpyYW5lbsOtIGFsZWJvIHZ5xaHFocOtbSBwb8SNdG9tIHrDusSNYXN0bmVuw71jaCB2b3ppZGllbC4gRG8gdGVqdG8gc2t1cGlueSBwYXRyaWEgbmlla3RvcsOpIHBvZMSNYXN0aSBTYW50IE1hcnTDrSBhIExlcyBDb3J0cy4gVGlldG8gw7p6ZW1pYSBzYSB2eXpuYcSNdWrDuiBvIG5pZcSNbyB2w71yYXpuZWrFocOtbSBkb3ByYXZuw71tIHphxaVhxb5lbsOtbSBhbGVibyDFoXBlY2lmaWNrw71taSBsb2vDoWxueW1pIHBvZG1pZW5rYW1pLgoKS2xhc3RlciAzIGplIG5ham1lbsWhw60gYSB0dm9yaWEgaG8gbGVuIG5pZWt0b3LDqSDEjWFzdGksIGt0b3LDqSBzYSBvZCBvc3RhdG7DvWNoIMWhdHZydMOtIGzDrcWhaWEgdsO9cmF6bmVqxaHDrW0gcHJvZmlsb20gZG9wcmF2bsO9Y2ggbmVow7RkIOKAkyBuYXByw61rbGFkIHZ5xaHFocOtbSBwb8SNdG9tIG9iZXTDrSwgdnnFocWhw61tIHBvZGllbG9tIHbDocW+bnljaCB6cmFuZW7DrSBhbGVibyDFoXBlY2lmaWNrw71taSBkb3ByYXZuw71taSBzaXR1w6FjaWFtaS4gVGVudG8ga2xhc3RlciByZXByZXplbnR1amUgYW5vbcOhbG5lIGFsZWJvIMWhdGF0aXN0aWNreSB2w71uaW1vxI1uw6kgb2JsYXN0aSB2IHLDoW1jaSBkb3ByYXZuZWogYmV6cGXEjW5vc3RpIEJhcmNlbG9ueS4KCkNlbGtvdm8ga2xhc3Ryb3bDoSBhbmFsw716YSB1bW/Fvm5pbGEgaWRlbnRpZmlrb3ZhxaUgc2t1cGlueSBtZXN0c2vDvWNoIMSNYXN0w60sIGt0b3LDqSBtYWrDuiBwb2RvYm7DvSBjaGFyYWt0ZXIgZG9wcmF2bsO9Y2ggbmVow7RkLiBSb3pkZWxlbmllIG5hIHRyaSBrbGFzdHJlIHpvZHBvdmVkw6Egcm96ZGllbG9tIHYgaW50ZW56aXRlIHByZW3DoXZreSwgdXJiYW5pc3RpY2tlaiDFoXRydWt0w7pyZSBha28gYWogdiB0eXBpY2vDvWNoIGRvcHJhdm7DvWNoIHNpdHXDoWNpw6FjaCBqZWRub3RsaXbDvWNoIMSNYXN0w60gbWVzdGEuCgojIyBEZXNrcmlwdMOtdm5lIMWhdGF0aXN0aWt5IHbDvXNsZWRrb3YKCk5hIHrDoWtsYWRlICoqVGFiLiA1KiogbcO0xb5lbWUga29uxaF0YXRvdmHFpSwgxb5lIHZuw7p0cm9rbGFzdHJvdsOhIHZhcmlhYmlsaXRhIGplIHByaSB2w6TEjcWhaW5lIHByZW1lbm7DvWNoIHJlbGF0w612bmUgbsOtemthLCDEjW8gem5hbWVuw6EsIMW+ZSBrbGFzdHJlIHPDuiB6IGjEvmFkaXNrYSBzbGVkb3ZhbsO9Y2ggY2hhcmFrdGVyaXN0w61rIHBvbWVybmUgaG9tb2fDqW5uZS4KClByZW1lbm7DqSBNaWxkLmluanVyaWVzLCBTZXJpb3VzLmluanVyaWVzIGEgVmljdGltcyB2eWthenVqw7ogdnlzb2vDvSBwb2RpZWwgbWVkemlrbGFzdHJvdmVqIHZhcmlhYmlsaXR5IChQcm9wX0JldHdlZW4pLCDEjW8gbmF6bmHEjXVqZSwgxb5lIGRvYnJlIHByaXNwaWV2YWrDuiBrIHNlcGFyw6FjaWkgamVkbm90bGl2w71jaCBrbGFzdHJvdiBhIG1hasO6IHbDvXJhem7DvSB2cGx5diBuYSB2w71zbGVkbsO6IGtsYXNpZmlrw6FjaXUgbWVzdHNrw71jaCDEjWFzdMOtLgoKTmFvcGFrIHByZW1lbm7DoSBWZWhpY2xlcy5pbnZvbHZlZCBtw6EgdsO9cmF6bmUgbmnFvsWhw60gcG9kaWVsIG1lZHppa2xhc3Ryb3ZlaiB2YXJpYWJpbGl0eS4gVG8gem5hbWVuw6EsIMW+ZSBwb8SNZXQgemFwb2plbsO9Y2ggdm96aWRpZWwgc2EgbWVkemkga2xhc3RyYW1pIGzDrcWhaSBtZW5laiBha28gb3N0YXRuw6kgcHJlbWVubsOpLCBhIHRlZGEgbmllIGplIHRha8O9bSBzaWxuw71tIHNlcGFyw6F0b3JvbS4gSmVqIHByw61wYWRuw6kgdnlsw7rEjWVuaWUgYnkgdsWhYWsgesOhc2FkbmUgbmVvdnBseXZuaWxvIGt2YWxpdHUga2xhc3Ryb3ZlaiBhbmFsw716eSwga2XEj8W+ZSBvc3RhdG7DqSBwcmVtZW5uw6kgbmVzw7ogZG9taW5hbnRuw7ogxI1hc8WlIGluZm9ybcOhY2llLgoKKipUYWIuIDUuKiogVnlzdmV0bGVuaWUgdm7DunRyb2tsYXN0cm92ZWogdmFyaWFiaWxpdHkgeiBoxL5hZGlza2EgamVkbm90bGl2w71jaCBwcmVtZW5uw71jaAoKYGBge3J9CiMjID09PT09PT09PT09PT09PT09PT09PT09PT09PT0KIyMgNSkgVmFyaWFiaWxpdHkgbWVhc3VyZXMKIyMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKc3NxIDwtIGZ1bmN0aW9uKHgsIG0pIHN1bSgoeCAtIG0pXjIpCgp2YXJfbmFtZXMgPC0gY29sbmFtZXModWRhamVfc2NhbGVkKQoKVFNTIDwtIHNhcHBseSh2YXJfbmFtZXMsIGZ1bmN0aW9uKHYpIHNzcSh1ZGFqZV9zY2FsZWRbLCB2XSwgbWVhbih1ZGFqZV9zY2FsZWRbLCB2XSkpKQoKV1NTIDwtIHNhcHBseSh2YXJfbmFtZXMsIGZ1bmN0aW9uKHYpIHsKICB4IDwtIHVkYWplX3NjYWxlZFssIHZdCiAgdGFwcGx5KHgsIGtsYXN0ZXJfbWVtYmVyc2hpcCwgZnVuY3Rpb24oeikgc3NxKHosIG1lYW4oeikpKSB8PiBzdW0oKQp9KQoKQlNTIDwtIFRTUyAtIFdTUwoKc3NfdGFibGUgPC0gZGF0YS5mcmFtZSgKICBWYXJpYWJsZSA9IHZhcl9uYW1lcywKICBUU1MgPSBUU1MsCiAgV1NTID0gV1NTLAogIEJTUyA9IEJTUywKICBQcm9wX0JldHdlZW4gPSBCU1MgLyBUU1MKKQoKc3NfdGFibGUKYGBgCgoKCgpgYGB7cn0KYXR0YWNoKHVkYWplKQp1ZGFqZSA8LSBkYXRhLmZyYW1lKGNiaW5kKHVkYWplLHVkYWplX2tsYXN0ZXJzJGtsYXN0ZXIpKQpjb2xuYW1lcyh1ZGFqZSkgPC0gYygiTWlsZF9pbmp1cmllcyIsCiAgICAgICAgICAgICAgICAgICAgICJTZXJpb3VzX2luanVyaWVzIiwKICAgICAgICAgICAgICAgICAgICAgIlZpY3RpbXMiLAogICAgICAgICAgICAgICAgICAgICAiVmVoaWNsZXNfaW52b2x2ZWQiLAogICAgICAgICAgICAgICAgICAgICAiSG91ciIsCiAgICAgICAgICAgICAgICAgICAgICJrbGFzdGVyIikKYGBgCgoKKipUYWIuIDYuKiogQ2VudHJvaWR5IC0gcHJpZW1lcm7DqSBob2Rub3R5IHNsZWRvdmFuw71jaCBwcmVtZW5uw71jaAoKYGBge3J9CmxpYnJhcnkoZHBseXIpCgpuYW1lcyh1ZGFqZSkgPC0gbWFrZS5uYW1lcyhuYW1lcyh1ZGFqZSksIHVuaXF1ZSA9IFRSVUUpCgpkZXNjcmlwdGl2ZXMgPC0gdWRhamUgJT4lCiAgZ3JvdXBfYnkoa2xhc3RlcikgJT4lCiAgc3VtbWFyaXNlKAogICAgYWNyb3NzKAogICAgICAuY29scyA9IHdoZXJlKGlzLm51bWVyaWMpLAogICAgICAuZm5zID0gbGlzdCgKICAgICAgICBtZWFuID0gfm1lYW4oLngsIG5hLnJtID0gVFJVRSkKICAgICAgKSwKICAgICAgLm5hbWVzID0gInsuY29sfV97LmZufSIKICAgICkKICApCgpkZXNjcmlwdGl2ZXMKYGBgCgpLbGFzdGVyIDEgbcOhIG5ham5pxb7FoWllIHByaWVtZXJuw6kgaG9kbm90eSBwcmVtZW5uw71jaC4gxaB0dnJ0ZSB2IHRvbXRvIGtsYXN0cmkgbWFqw7ogcHJpZW1lcm5lIDEgb2JlxaUsIHZlxL5taSBuw616a3kgcG/EjWV0IHphcG9qZW7DvWNoIHZvemlkaWVsIGEgbmVob2R5IHNhIHZ5c2t5dHVqw7ogc2vDtHIgdiBza29yxaHDrWNoIGhvZGluw6FjaCBkxYhhLiBUZW50byBrbGFzdGVyIHByZWRzdGF2dWplIHJlbGF0w612bmUgbWVuZWogesOhdmHFvm7DqSBuZWhvZHkgcyBqZWRub2R1Y2hvdSDFoXRydWt0w7pyb3UuCgpLbGFzdGVyIDIgbcOhIHByaWVtZXJuw6kgaG9kbm90eSBtaWVybmUgdnnFocWhaWUgbmXFviBrbGFzdGVyIDEuIFByZSB0ZW50byBrbGFzdGVyIGplIHR5cGlja8OpLCDFvmUgcHJpZW1lcm5lIHNhIHZ5c2t5dHVqZSB2aWFjIG9iZXTDrSAoMSw0NCkgYSB6w6Fyb3ZlxYggYWogbWllcm5lIHZ5xaHFocOtIHBvxI1ldCB6YXBvamVuw71jaCB2b3ppZGllbC4gSG9kaW5hIHbDvXNreXR1IG5laMO0ZCBqZSB0dSB0aWXFviBvIG5pZcSNbyB2ecWhxaFpYS4gVGVudG8ga2xhc3RlciByZXByZXplbnR1amUgbWVzdHNrw6kgxI1hc3RpIHMgbyBuaWXEjW8ga29tcGxpa292YW5lasWhw61taSBuZWhvZGFtaS4KCktsYXN0ZXIgMyBtw6EgbmFqdnnFocWhaWUgcHJpZW1lcm7DqSBob2Rub3R5IHByZSBwcmVtZW5uw7ogVmljdGltc19tZWFuLCBrZGUgcHJpZW1lciBkb3NhaHVqZSAyIG9iZXRlIG5hIG5laG9kdS4gTmEgZHJ1aGVqIHN0cmFuZSB2xaFhayBuZXZ5a2F6dWplIHp2w73FoWVuw70gcG/EjWV0IHphcG9qZW7DvWNoIHZvemlkaWVsIOKAkyB0ZW4gb3N0w6F2YSBuw616a3kgYWtvIHYga2xhc3RyaSAxLiBOZWhvZHkgdiB0b210byBrbGFzdHJpIHNhIHR5cGlja3kgb2RvaHLDoXZhasO6IHYgbmVza29yxaHDrWNoIGhvZGluw6FjaC4gS2xhc3RlciAzIHRlZGEgcHJlZHN0YXZ1amUgb2JsYXN0aSBzIG1lbmVqIMSNYXN0w71taSwgYWxlIHrDoXZhxb5uZWrFocOtbWkgbsOhc2xlZGthbWkgbmVow7RkLgoKQ2Vsa292byBjZW50cm9pZHkgdWthenVqw7osIMW+ZSBrbGFzdHJlIHNhIG9kbGnFoXVqw7ogbmFqbcOkIHBvZMS+YSBwb8SNdHUgb2JldMOtLCB2IG1lbsWhZWogbWllcmUgcG9kxL5hIHBvxI10dSB6YXBvamVuw71jaCB2b3ppZGllbCBhIMSNaWFzdG/EjW5lIHBvZMS+YSDEjWFzdSwgdiBrdG9yb20gbmVob2R5IHZ6bmlrYWrDui4gCgojIyBaw6F2ZXIKClByZWRsb8W+ZW7DoSBhbmFsw716YSBzYSB6YW9iZXJhbGEgY2hhcmFrdGVyaXN0aWtvdSBkb3ByYXZuw71jaCBuZWjDtGQgdiBqZWRub3RsaXbDvWNoIG1lc3Rza8O9Y2ggxI1hc3RpYWNoIEJhcmNlbG9ueSBuYSB6w6FrbGFkZSBwcmllbWVybsO9Y2ggaG9kbsO0dCB2eWJyYW7DvWNoIHByZW1lbm7DvWNoLCBha28gc8O6IHBvxI1ldCBvYmV0w60sIHBvxI1ldCB6YXBvamVuw71jaCB2b3ppZGllbCDEjWkgxI1hcyB2em5pa3UgbmVob2R5LgpOYSB6w6FrbGFkZSB6aGx1a292ZWogYW5hbMO9enkgYm9saSBtZXN0c2vDqSDEjWFzdGkgcm96ZGVsZW7DqSBkbyB0cm9jaCBrbGFzdHJvdiwgcHJpxI1vbSBqZWRub3RsaXbDqSBrbGFzdHJlIG9kcsOhxb5hasO6IHJvemRpZWx5IHYgesOhdmHFvm5vc3RpIG5laMO0ZCwgaWNoIHR5cGlja29tIHByaWViZWh1IGEgxI1hc292b20gcm96bG/FvmVuw60uCgpWw71zbGVka3kgYW5hbMO9enkgdWthenVqw7osIMW+ZSBuaWVrdG9yw6kgbWVzdHNrw6kgxI1hc3RpIG1hasO6IHZlxL5taSBwb2RvYm7DvSBwcm9maWwgbmVow7RkLCB6YXRpYcS+IMSNbyBpbsOpIHNhIHZ5em5hxI11asO6IHbDvXJhem5lIG9kbGnFoW7DvW1pIGNoYXJha3RlcmlzdGlrYW1pLiBUYWvDqXRvIHBvem5hdGt5IG3DtMW+dSBiecWlIHXFvml0b8SNbsOpIHByZSBtZXN0c2vDqSBwbMOhbm92YW5pZSwgZG9wcmF2bsOpIHJpYWRlbmllIGFqIHByZXZlbnTDrXZuZSBwb2xpdGlreSB6YW1lcmFuw6kgbmEgenbDvcWhZW5pZSBiZXpwZcSNbm9zdGkgdiBrb25rcsOpdG55Y2ggbG9rYWxpdMOhY2ggQmFyY2Vsb255LiBOYSB6w6FrbGFkZSBwcsOtc2x1xaFub3N0aSBrdSBrbGFzdHJvbSBqZSBtb8W+bsOpIGxlcMWhaWUgaWRlbnRpZmlrb3ZhxaUgb2JsYXN0aSwga3RvcsOpIHNpIHZ5xb5hZHVqw7ogY2llbGVuw6kgb3BhdHJlbmlhLCDDunByYXZ1IGRvcHJhdm5laiBpbmZyYcWhdHJ1a3TDunJ5IGFsZWJvIHp2w73FoWVuw7ogcG96b3Jub3PFpSB6byBzdHJhbnkgbWllc3RueWNoIG9yZ8Ohbm92Lg==