Tecnológico de Monterrey

Doctor Teófilo Ozuna

Alumna:

Avril Lobato Delgado A00833113

EDA de base de datos

Librerias

library(ggplot2)
library(dplyr)
library(tidyr)
library(lubridate)
library(purrr)
library(plotly)
library(forecast)
library(readxl)
library(DataExplorer)
library(dplyr)
library(ggplot2)
library(tm)
library(cluster)
library(factoextra) 
library(gridExtra)
library(purrr)
library(pROC)
library(rpart)
library(rpart.plot)
library(e1071)
library(ggpubr)
library(dlookr)
library(zoo)
library(caret)
library(stats)
library(tseries)
library(readr)
library(vars)
library(syuzhet)
library(kableExtra)
library(plotly)
library(scales)
library(knitr)
library(rmgarch)
library(devtools)
library(openxlsx)
library(relaimpo)
library(stargazer)
library(RColorBrewer)
library(PerformanceAnalytics)
library(ConnectednessApproach)
library(readr)
library(tseries)
library(forecast)
library(urca)
library(fGarch)
library(MTS)
library(MASS)
library(nortest)
library(outliers)
library(moments)
library(FinTS)
library(WeightedPortTest)

Carga de base de datos

# Lee el archivo CSV y selecciona las columnas relevantes
index_alt <- read_csv("C:/Users/AVRIL/Desktop/Spillovers/all_daily_index_returns.csv")
data_selected <- index_alt[, c("Date", "AI_INDEX", "Fintech_Index", "Blockchain_Index")]

Tests y Estadísticos de bd original

# Function for summary statistics
summary_stats <- function(data) {
  return(data.frame(
    Mean = mean(data, na.rm = TRUE),
    StdDev = sd(data, na.rm = TRUE),
    Min = min(data, na.rm = TRUE),
    P25 = quantile(data, 0.25, na.rm = TRUE),
    P50 = median(data, na.rm = TRUE),
    P75 = quantile(data, 0.75, na.rm = TRUE),
    Max = max(data, na.rm = TRUE),
    Skewness = skewness(data, na.rm = TRUE),
    Kurtosis = kurtosis(data, na.rm = TRUE)
  ))
}

# Calculate statistics and tests for each index
results <- data.frame(
  Test = c(
    "Mean", "Standard Deviation", "Minimum", "25th Percentile", "Median",
    "75th Percentile", "Maximum", "Skewness", "Kurtosis", "Jarque-Bera (p-value)",
    "ADF Test (p-value)", "KPSS Test (p-value)", "PP Test (p-value)", "ERS Test",
    "ARCH Test (p-value)", "Weighted Portmanteau Test (p-value)", "Q2(20) Test (p-value)",
    "Outlier detection (Chen and Liu)","Correlation Matrix and R-squared"
  ),
  AI_INDEX = NA, Fintech_Index = NA, Blockchain_Index = NA
)

# Populate the table with summary stats
stats_ai <- summary_stats(data_selected$AI_INDEX)
stats_fintech <- summary_stats(data_selected$Fintech_Index)
stats_blockchain <- summary_stats(data_selected$Blockchain_Index)
results$AI_INDEX[1:9] <- as.numeric(stats_ai)
results$Fintech_Index[1:9] <- as.numeric(stats_fintech)
results$Blockchain_Index[1:9] <- as.numeric(stats_blockchain)

# Normality and stationarity tests
results$AI_INDEX[10] <- jarque.bera.test(data_selected$AI_INDEX)$p.value
results$Fintech_Index[10] <- jarque.bera.test(data_selected$Fintech_Index)$p.value
results$Blockchain_Index[10] <- jarque.bera.test(data_selected$Blockchain_Index)$p.value

results$AI_INDEX[11] <- adf.test(data_selected$AI_INDEX)$p.value
results$Fintech_Index[11] <- adf.test(data_selected$Fintech_Index)$p.value
results$Blockchain_Index[11] <- adf.test(data_selected$Blockchain_Index)$p.value

results$AI_INDEX[12] <- kpss.test(data_selected$AI_INDEX)$p.value
results$Fintech_Index[12] <- kpss.test(data_selected$Fintech_Index)$p.value
results$Blockchain_Index[12] <- kpss.test(data_selected$Blockchain_Index)$p.value

results$AI_INDEX[13] <- pp.test(data_selected$AI_INDEX)$p.value
results$Fintech_Index[13] <- pp.test(data_selected$Fintech_Index)$p.value
results$Blockchain_Index[13] <- pp.test(data_selected$Blockchain_Index)$p.value

results$AI_INDEX[14] <- ur.ers(data_selected$AI_INDEX, type = "DF-GLS")@teststat
results$Fintech_Index[14] <- ur.ers(data_selected$Fintech_Index, type = "DF-GLS")@teststat
results$Blockchain_Index[14] <- ur.ers(data_selected$Blockchain_Index, type = "DF-GLS")@teststat

# ARCH test
results$AI_INDEX[15] <- ArchTest(data_selected$AI_INDEX)$p.value
results$Fintech_Index[15] <- ArchTest(data_selected$Fintech_Index)$p.value
results$Blockchain_Index[15] <- ArchTest(data_selected$Blockchain_Index)$p.value

# Portmanteau test
results$portmanteau_ai <- Weighted.Box.test(data_selected$AI_INDEX)$p.value
results$portmanteau_fintech <- Weighted.Box.test(data_selected$Fintech_Index)$p.value
results$portmanteau_blockchain <- Weighted.Box.test(data_selected$Blockchain_Index)$p.value

# Q2(20) test
results$AI_INDEX[17] <- Box.test(data_selected$AI_INDEX^2, lag = 20, type = "Ljung-Box")$p.value
results$Fintech_Index[17] <- Box.test(data_selected$Fintech_Index^2, lag = 20, type = "Ljung-Box")$p.value
results$Blockchain_Index[17] <- Box.test(data_selected$Blockchain_Index^2, lag = 20, type = "Ljung-Box")$p.value

# Outlier detection (Chen and Liu)
results$outliers_ai <- sum(scores(data_selected$AI_INDEX, type = "chisq", prob = 0.05) != 0)
results$outliers_fintech <- sum(scores(data_selected$Fintech_Index, type = "chisq", prob = 0.05) != 0)
results$outliers_blockchain <- sum(scores(data_selected$Blockchain_Index, type = "chisq", prob = 0.05) != 0)

# Correlation Matrix and R-squared
cor_matrix <- cor(data_selected[, -1], use = "complete.obs")
r_squared <- cor_matrix^2

print(results)
##                                   Test      AI_INDEX Fintech_Index
## 1                                 Mean  7.284978e-04  2.514532e-04
## 2                   Standard Deviation  5.997773e-03  1.886246e-03
## 3                              Minimum -1.803901e-02 -6.887190e-03
## 4                      25th Percentile -2.658939e-03 -9.810085e-04
## 5                               Median  1.024079e-03  2.999540e-04
## 6                      75th Percentile  5.001330e-03  1.530050e-03
## 7                              Maximum  1.653343e-02  5.406403e-03
## 8                             Skewness -3.676255e-01 -6.215113e-02
## 9                             Kurtosis  3.031592e+00  3.431835e+00
## 10               Jarque-Bera (p-value)  8.905365e-11  1.789472e-04
## 11                  ADF Test (p-value)  1.000000e-02  1.000000e-02
## 12                 KPSS Test (p-value)  1.000000e-01  1.000000e-01
## 13                   PP Test (p-value)  1.000000e-02  1.000000e-02
## 14                            ERS Test -8.226890e+00 -1.240032e+01
## 15                 ARCH Test (p-value)  0.000000e+00  0.000000e+00
## 16 Weighted Portmanteau Test (p-value)            NA            NA
## 17               Q2(20) Test (p-value)  0.000000e+00  0.000000e+00
## 18    Outlier detection (Chen and Liu)            NA            NA
## 19    Correlation Matrix and R-squared            NA            NA
##    Blockchain_Index portmanteau_ai portmanteau_fintech portmanteau_blockchain
## 1      4.414805e-04  2.791471e-321                   0                      0
## 2      5.269908e-03  2.791471e-321                   0                      0
## 3     -2.425996e-02  2.791471e-321                   0                      0
## 4     -2.095878e-03  2.791471e-321                   0                      0
## 5      7.566070e-04  2.791471e-321                   0                      0
## 6      3.584238e-03  2.791471e-321                   0                      0
## 7      2.091050e-02  2.791471e-321                   0                      0
## 8     -4.398032e-01  2.791471e-321                   0                      0
## 9      5.179150e+00  2.791471e-321                   0                      0
## 10     0.000000e+00  2.791471e-321                   0                      0
## 11     1.000000e-02  2.791471e-321                   0                      0
## 12     1.000000e-01  2.791471e-321                   0                      0
## 13     1.000000e-02  2.791471e-321                   0                      0
## 14    -1.321070e+01  2.791471e-321                   0                      0
## 15     0.000000e+00  2.791471e-321                   0                      0
## 16               NA  2.791471e-321                   0                      0
## 17     0.000000e+00  2.791471e-321                   0                      0
## 18               NA  2.791471e-321                   0                      0
## 19               NA  2.791471e-321                   0                      0
##    outliers_ai outliers_fintech outliers_blockchain
## 1         1890             1974                1904
## 2         1890             1974                1904
## 3         1890             1974                1904
## 4         1890             1974                1904
## 5         1890             1974                1904
## 6         1890             1974                1904
## 7         1890             1974                1904
## 8         1890             1974                1904
## 9         1890             1974                1904
## 10        1890             1974                1904
## 11        1890             1974                1904
## 12        1890             1974                1904
## 13        1890             1974                1904
## 14        1890             1974                1904
## 15        1890             1974                1904
## 16        1890             1974                1904
## 17        1890             1974                1904
## 18        1890             1974                1904
## 19        1890             1974                1904
# Convertir la columna `Date` a tipo Date si está en formato "dd/mm/yyyy"
index_alt$Date <- as.Date(index_alt$Date, format = "%d/%m/%Y")

# Mostrar estructura y resumen
str(index_alt)
## spc_tbl_ [2,051 × 12] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
##  $ Date                 : Date[1:2051], format: "2019-01-08" "2019-01-09" ...
##  $ AI_INDEX             : num [1:2051] 0.00865 0.00858 0.00851 0.00844 0.00836 ...
##  $ Cumulative return...3: num [1:2051] 101 102 103 103 104 ...
##  $ Fintech_Index        : num [1:2051] -0.000675 -0.000675 -0.000676 -0.000676 -0.000677 ...
##  $ Cumulative return...5: num [1:2051] 99.9 99.9 99.8 99.7 99.7 ...
##  $ Blockchain_Index     : num [1:2051] 0.00205 0.00204 0.00204 0.00203 0.00203 ...
##  $ Cumulative return...7: num [1:2051] 100 100 101 101 101 ...
##  $ Nasdaq Composite     : num [1:2051] 1005 1010 1015 1020 1025 ...
##  $ Dax 40               : num [1:2051] 1002 1003 1005 1006 1008 ...
##  $ Dow Jones Industrial : num [1:2051] 1003 1007 1010 1014 1017 ...
##  $ KFTX Index           : num [1:2051] 1012 1023 1029 1028 1027 ...
##  $ S&P Financials Index : num [1:2051] 1003 1005 1006 1008 1011 ...
##  - attr(*, "spec")=
##   .. cols(
##   ..   Date = col_character(),
##   ..   AI_INDEX = col_double(),
##   ..   `Cumulative return...3` = col_double(),
##   ..   Fintech_Index = col_double(),
##   ..   `Cumulative return...5` = col_double(),
##   ..   Blockchain_Index = col_double(),
##   ..   `Cumulative return...7` = col_double(),
##   ..   `Nasdaq Composite` = col_double(),
##   ..   `Dax 40` = col_double(),
##   ..   `Dow Jones Industrial` = col_double(),
##   ..   `KFTX Index` = col_double(),
##   ..   `S&P Financials Index` = col_double()
##   .. )
##  - attr(*, "problems")=<externalptr>
summary(index_alt)
##       Date               AI_INDEX          Cumulative return...3
##  Min.   :2019-01-08   Min.   :-0.0180390   Min.   :100.9        
##  1st Qu.:2020-06-03   1st Qu.:-0.0026589   1st Qu.:206.3        
##  Median :2021-10-29   Median : 0.0010241   Median :275.6        
##  Mean   :2021-10-29   Mean   : 0.0007285   Mean   :270.1        
##  3rd Qu.:2023-03-25   3rd Qu.: 0.0050013   3rd Qu.:332.3        
##  Max.   :2024-08-19   Max.   : 0.0165334   Max.   :439.8        
##  Fintech_Index        Cumulative return...5 Blockchain_Index    
##  Min.   :-0.0068872   Min.   : 91.42        Min.   :-0.0242600  
##  1st Qu.:-0.0009810   1st Qu.:105.21        1st Qu.:-0.0020959  
##  Median : 0.0003000   Median :116.09        Median : 0.0007566  
##  Mean   : 0.0002515   Mean   :120.99        Mean   : 0.0004415  
##  3rd Qu.: 0.0015301   3rd Qu.:127.90        3rd Qu.: 0.0035842  
##  Max.   : 0.0054064   Max.   :173.73        Max.   : 0.0209105  
##  Cumulative return...7 Nasdaq Composite     Dax 40       Dow Jones Industrial
##  Min.   : 95.04        Min.   :1005     Min.   : 829.2   Min.   : 818.2      
##  1st Qu.:136.66        1st Qu.:1435     1st Qu.:1184.8   1st Qu.:1186.1      
##  Median :168.18        Median :1810     Median :1320.5   Median :1409.5      
##  Mean   :176.21        Mean   :1798     Mean   :1329.6   Mean   :1357.7      
##  3rd Qu.:220.23        3rd Qu.:2098     3rd Qu.:1459.5   3rd Qu.:1482.5      
##  Max.   :276.64        Max.   :2723     Max.   :1743.4   Max.   :1757.1      
##    KFTX Index     S&P Financials Index
##  Min.   : 881.8   Min.   : 727.6      
##  1st Qu.:1289.6   1st Qu.:1153.5      
##  Median :1404.2   Median :1371.1      
##  Mean   :1466.7   Mean   :1348.0      
##  3rd Qu.:1680.7   3rd Qu.:1537.3      
##  Max.   :1925.3   Max.   :1811.6

Chatziantoniou, Gabauer & Gupta (2021): Integration and risk transmission in the market for crude oil: A time-varying parameter frequency connectedness approach

# Convertir a objeto zoo
data_selected <- index_alt[, c("Date","AI_INDEX", "Fintech_Index", "Blockchain_Index")]

data_matrix <- as.matrix(data_selected)

data_zoo <- zoo(data_selected[, -1], order.by = data_selected$Date)

# Instalar y cargar el paquete ConnectednessApproach, si no está ya instalado
if (!requireNamespace("ConnectednessApproach", quietly = TRUE)) {
  if (!requireNamespace("devtools", quietly = TRUE)) {
    install.packages("devtools")
  }
  devtools::install_github("GabauerDavid/ConnectednessApproach")
}
library(ConnectednessApproach)

# Configuración de parámetros para TVPVAR
nlag <- 2       # Orden del rezago
lambda <- c(0.99, 0.99)  # Valores de decaimiento para el filtro

# Crear la lista de configuración necesaria
config <- list(l = lambda, nlag = nlag)

# Estimar el modelo TVP-VAR con los parámetros especificados
tvpvar_model <- TVPVAR(data_zoo, configuration = config)

Table 2: Averaged Connectedness Table

partition = c(pi+0.00001, pi/5, 0)
dca = ConnectednessApproach(data_zoo, 
                            model="TVP-VAR",
                            connectedness="Frequency",
                            nlag=1,
                            nfore=100,
                            window.size=200,
                            VAR_config=list(TVPVAR=list(kappa1=0.99, kappa2=0.99, prior="BayesPrior")),
                            Connectedness_config = list(
                              FrequencyConnectedness=list(partition=partition, generalized=TRUE, scenario="ABS")
                            ))
kable(dca$TABLE)
AI_INDEX.Total Fintech_Index.Total Blockchain_Index.Total FROM.Total AI_INDEX.1-5 Fintech_Index.1-5 Blockchain_Index.1-5 FROM.1-5 AI_INDEX.5-Inf Fintech_Index.5-Inf Blockchain_Index.5-Inf FROM.5-Inf
AI_INDEX 79.76 6.87 13.37 20.24 10.44 0.87 1.13 2.00 69.32 6.00 12.24 18.24
Fintech_Index 8.56 84.40 7.04 15.60 0.75 10.89 0.53 1.28 7.81 73.51 6.51 14.32
Blockchain_Index 15.46 5.78 78.76 21.24 1.24 0.69 10.50 1.93 14.22 5.08 68.26 19.31
TO 24.02 12.64 20.41 57.07 1.99 1.56 1.65 5.20 22.03 11.08 18.76 51.87
Inc.Own 103.79 97.04 99.17 cTCI/TCI 12.43 12.44 12.15 cTCI/TCI 91.35 84.60 87.02 cTCI/TCI
Net 3.79 -2.96 -0.83 28.54/19.02 -0.01 0.28 -0.27 2.60/1.73 3.79 -3.24 -0.55 25.94/17.29
NPDC 2.00 0.00 1.00 1.00 2.00 0.00 2.00 0.00 1.00

Figure 4: Net Total Directional Connectedness

PlotNET(dca, ylim=c(-60,60))

Gabauer and Gupta (2018): On the transmission mechanism of country-specific and international economic uncertainty spillovers: Evidence from a TVP-VAR connectedness decomposition approach

data_zoo2 <- zoo(data_selected[, c("AI_INDEX", "Fintech_Index", "Blockchain_Index")], 
                 order.by = data_selected$Date)

# Configuración de parámetros para TVPVAR
nlag <- 2       # Orden del rezago
lambda <- c(0.99, 0.99)  # Valores de decaimiento para el filtro

# Crear la lista de configuración necesaria
config <- list(l = lambda, nlag = nlag)

# Estimar el modelo TVP-VAR con los parámetros especificados
tvpvar_model <- TVPVAR(data_zoo2, configuration = config)
dca = ConnectednessApproach(data_zoo2, 
                            nlag=1,
                            nfore=10,
                            model="TVP-VAR",
                            connectedness="Time",
                            window.size=200,
                            VAR_config=list(TVPVAR=list(kappa1=0.99, kappa2=0.99, prior="BayesPrior")))

Table 1: Connectedness table

kable(dca$TABLE)
AI_INDEX Fintech_Index Blockchain_Index FROM
AI_INDEX 81.70 6.65 11.65 18.30
Fintech_Index 7.31 86.71 5.98 13.29
Blockchain_Index 11.98 5.17 82.86 17.14
TO 19.29 11.82 17.63 48.73
Inc.Own 100.99 98.53 100.48 cTCI/TCI
NET 0.99 -1.47 0.48 24.37/16.24
NPT 2.00 0.00 1.00
# CONNECTEDNESS DECOMPOSITION
int = InternalConnectedness(dca, groups=list("Group1"=c(1), "Group2"=c(2), "Group3"=c(3)))
ext = ExternalConnectedness(dca, groups=list("Group1"=c(1), "Group2"=c(2), "Group3"=c(3)))
kable(int$TABLE)
AI_INDEX Fintech_Index Blockchain_Index FROM
AI_INDEX 81.70 0.00 0.00 0.00
Fintech_Index 0.00 86.71 0.00 0.00
Blockchain_Index 0.00 0.00 82.86 0.00
TO 0.00 0.00 0.00 0.00
Inc.Own 81.70 86.71 82.86 cTCI/TCI
NET 0.00 0.00 0.00 0.00/0.00
NPT 0.00 0.00 0.00
kable(ext$TABLE)
AI_INDEX Fintech_Index Blockchain_Index FROM
AI_INDEX 0.00 6.65 11.65 18.30
Fintech_Index 7.31 0.00 5.98 13.29
Blockchain_Index 11.98 5.17 0.00 17.14
TO 19.29 11.82 17.63 48.73
Inc.Own 19.29 11.82 17.63 cTCI/TCI
NET 0.99 -1.47 0.48 24.37/16.24
NPT 2.00 0.00 1.00
#Figure 3: Dynamic total connectedness
PlotTCI(dca, int, ylim=c(0, 40))

#Figure 4: Net total directional connectedness
PlotNET(dca, int, ylim=c(-10, 10))

#Figure 5: Total directional connectedness FROM others
PlotFROM(dca, int, ylim=c(0, 60))

#Figure 6: Total directional connectedness TO others
PlotTO(dca, int, ylim=c(0, 60))

#Figure 7: Internal net pairwise total directional connectedness
PlotNPDC(dca, int, ylim=c(-5, 5))

Cocca, Gabauer, and Pomberger (2024): Clean energy market connectedness and investment strategies: New evidence from DCC-GARCH R2 decomposed connectedness measures

# Convierte la columna 'Date' a formato Date
date <- as.Date(data_selected$Date, format="%d/%m/%Y")

# Crea la serie de tiempo (zoo) solo con las columnas seleccionadas
Y <- zoo(data_selected[, c("Fintech_Index", "AI_INDEX", "Blockchain_Index")], order.by = date)

# Asegúrate de que los datos sean numéricos y elimina valores NA
Y <- na.omit(zoo(data.frame(
  Fintech_Index_diff = as.numeric(data_selected$Fintech_Index),
  AI_INDEX_diff = as.numeric(data_selected$AI_INDEX),
  Blockchain_Index_diff = as.numeric(data_selected$Blockchain_Index)
), order.by = date))

# Reemplaza los valores NA restantes por 0
Y[is.na(Y)] <- 0

# Establece 'dimnames' de Y con números como índices (como en Y2) sin cambiar el índice de fecha
dimnames(Y) <- list(as.character(1:nrow(Y)), colnames(Y))

NAMES = colnames(Y)
k = ncol(Y)
t = nrow(Y)

# Verifica la estructura de Y
str(Y)
## 'zoo' series from 2019-01-08 to 2024-08-19
##   Data: num [1:2051, 1:3] -0.000675 -0.000675 -0.000676 -0.000676 -0.000677 ...
##  - attr(*, "dimnames")=List of 2
##   ..$ : chr [1:2051] "1" "2" "3" "4" ...
##   ..$ : chr [1:3] "Fintech_Index_diff" "AI_INDEX_diff" "Blockchain_Index_diff"
##   Index:  Date[1:2051], format: "2019-01-08" "2019-01-09" "2019-01-10" "2019-01-11" "2019-01-12" ...
kable(SummaryStatistics(Y, nlag=20))
Fintech_Index_diff AI_INDEX_diff Blockchain_Index_diff
Mean 0.000*** 0.001*** 0.000***
(0.000) (0.000) (0.000)
Variance 0 0 0
Skewness -0.062 -0.368*** -0.440***
(0.249) (0.000) (0.000)
Ex.Kurtosis 0.432*** 0.032 2.179***
(0.001) (0.712) (0.000)
JB 17.257*** 46.284*** 471.935***
(0.000) (0.000) (0.000)
ERS -12.400 -8.227 -13.211
(0.000) (0.000) (0.000)
Q(20) 3870.587*** 3338.261*** 3939.808***
(0.000) (0.000) (0.000)
Q2(20) 3413.861*** 5253.401*** 4241.131***
(0.000) (0.000) (0.000)
kendall Fintech_Index_diff AI_INDEX_diff Blockchain_Index_diff
Fintech_Index_diff 1.000*** -0.062*** 0.016
AI_INDEX_diff -0.062*** 1.000*** 0.144***
Blockchain_Index_diff 0.016 0.144*** 1.000***

Figure 0: Percentage changes

par(mfcol = c(ceiling(k/2),2), oma = c(0, 1, 0, 0) + 0.5, mar = c(1, 1, 1, 1) + 0.5, mgp = c(1, 0.4, 0))
for (i in 1:k) {
  plot(date,Y[,i],type='l',las=1,xaxs='i',yaxs='i',ylim=c(-0.1,0.1),xlab='',ylab='',main=paste(NAMES[i]),tck=-.02,col='steelblue4')
  grid(NA,NULL)
  lines(date,Y[,i],col='steelblue4')
  abline(h=0,lty=3)
  box()
}

spec <- list()

# Itera sobre cada columna de Y
for (i in 1:k) {
  # Intenta seleccionar el mejor modelo GARCH para cada serie
  u <- tryCatch({
    GARCHselection(Y[, i],
                   distributions = c("norm", "std", "sstd", "ged", "sged"),
                   models = c("sGARCH", "gjrGARCH", "eGARCH", "iGARCH", "AVGARCH", "TGARCH"))
  }, error = function(e) {
    warning(paste("Error al seleccionar modelo GARCH para la variable", i, ":", e$message))
    NULL
  })
  
  # Si 'u' no es NULL y tiene un mejor modelo, agrega a 'spec'
  if (!is.null(u) && !is.null(u$best_ugarch)) {
    spec[[i]] <- u$best_ugarch
  } else {
    # Si no se seleccionó un modelo, asigna un modelo GARCH(1,1) por defecto
    warning(paste("No se seleccionó ningún modelo GARCH para", NAMES[i], ". Usando modelo GARCH(1,1) con distribución normal"))
    spec[[i]] <- ugarchspec(variance.model = list(model = "sGARCH", garchOrder = c(1, 1)),
                            mean.model = list(armaOrder = c(0, 0)),
                            distribution.model = "norm")
  }
}

# Verifica que 'spec' tenga modelos para cada serie en Y
if (length(spec) != k) {
  stop("spec no contiene modelos válidos para todas las series de Y")
}

# Ejecuta el modelo DCC-GARCH si spec es válida
fit <- BivariateDCCGARCH(Y, spec)
## [1] "DCC-GARCH estimation based on Fintech_Index_diff and AI_INDEX_diff"
## [1] "DCC-GARCH estimation based on Fintech_Index_diff and Blockchain_Index_diff"
## [1] "DCC-GARCH estimation based on AI_INDEX_diff and Blockchain_Index_diff"

Table 4: Evaluation of univariate GARCH performance

H = fit$H_t
R = fit$R_t

uGARCH_table = NULL
for (i in 1:k) {
  fit = ugarchfit(spec[[i]], Y[,i])
  gt = GARCHtests(fit, lag=20)
  uGARCH_table = rbind(uGARCH_table, gt$TABLE)
}

kable(uGARCH_table)
SignBias WARCH(20) VaR CVaR VaR Dur.
statistics 0.6230910 1.9437522 113.69976 -93.6559 0.1666667
pvalues 0.5332942 0.9997909 0.00000 0.1730 0.1755157
statistics 0.8620658 1.1073277 76.58490 -148.2286 0.2843137
pvalues 0.3887523 0.9999953 0.00000 0.0000 0.3464012
statistics 1.4127318 13.8866627 74.01928 -152.5048 0.2941176
pvalues 0.1578867 0.1760766 0.00000 0.2180 0.1284943

Figure 3: Dynamic conditional correlations

par(mfcol = c(ceiling(k/2),2), oma = c(0, 1, 0, 0) + 0.5, mar = c(1, 1, 1, 1) + 0.5, mgp = c(1, 0.4, 0))
for (j in 1:k) {
  plot(date,R[j,j,],type='l',las=1,xaxs='i',yaxs='i',xlab='',ylab='',main=paste(NAMES[j]),tck=-.02,col=j,ylim=c(-1.1,1.1))
  grid(NA,NULL)
  for (i in 1:k) {
    lines(date,R[j,i,],col=i)
    abline(h=0,lty=3)
    box()
  }
  legend("bottom",NAMES[-j],fill=c(1:k)[-j],bty="n",cex=0.75,ncol=k)
}

Table 5: Averaged connectedness measures

dca = R2Correlations(R)
##   |                                                                              |                                                                      |   0%  |                                                                              |                                                                      |   1%  |                                                                              |=                                                                     |   1%  |                                                                              |=                                                                     |   2%  |                                                                              |==                                                                    |   2%  |                                                                              |==                                                                    |   3%  |                                                                              |==                                                                    |   4%  |                                                                              |===                                                                   |   4%  |                                                                              |===                                                                   |   5%  |                                                                              |====                                                                  |   5%  |                                                                              |====                                                                  |   6%  |                                                                              |=====                                                                 |   6%  |                                                                              |=====                                                                 |   7%  |                                                                              |=====                                                                 |   8%  |                                                                              |======                                                                |   8%  |                                                                              |======                                                                |   9%  |                                                                              |=======                                                               |   9%  |                                                                              |=======                                                               |  10%  |                                                                              |=======                                                               |  11%  |                                                                              |========                                                              |  11%  |                                                                              |========                                                              |  12%  |                                                                              |=========                                                             |  12%  |                                                                              |=========                                                             |  13%  |                                                                              |=========                                                             |  14%  |                                                                              |==========                                                            |  14%  |                                                                              |==========                                                            |  15%  |                                                                              |===========                                                           |  15%  |                                                                              |===========                                                           |  16%  |                                                                              |============                                                          |  16%  |                                                                              |============                                                          |  17%  |                                                                              |============                                                          |  18%  |                                                                              |=============                                                         |  18%  |                                                                              |=============                                                         |  19%  |                                                                              |==============                                                        |  19%  |                                                                              |==============                                                        |  20%  |                                                                              |==============                                                        |  21%  |                                                                              |===============                                                       |  21%  |                                                                              |===============                                                       |  22%  |                                                                              |================                                                      |  22%  |                                                                              |================                                                      |  23%  |                                                                              |================                                                      |  24%  |                                                                              |=================                                                     |  24%  |                                                                              |=================                                                     |  25%  |                                                                              |==================                                                    |  25%  |                                                                              |==================                                                    |  26%  |                                                                              |===================                                                   |  26%  |                                                                              |===================                                                   |  27%  |                                                                              |===================                                                   |  28%  |                                                                              |====================                                                  |  28%  |                                                                              |====================                                                  |  29%  |                                                                              |=====================                                                 |  29%  |                                                                              |=====================                                                 |  30%  |                                                                              |=====================                                                 |  31%  |                                                                              |======================                                                |  31%  |                                                                              |======================                                                |  32%  |                                                                              |=======================                                               |  32%  |                                                                              |=======================                                               |  33%  |                                                                              |=======================                                               |  34%  |                                                                              |========================                                              |  34%  |                                                                              |========================                                              |  35%  |                                                                              |=========================                                             |  35%  |                                                                              |=========================                                             |  36%  |                                                                              |==========================                                            |  36%  |                                                                              |==========================                                            |  37%  |                                                                              |==========================                                            |  38%  |                                                                              |===========================                                           |  38%  |                                                                              |===========================                                           |  39%  |                                                                              |============================                                          |  39%  |                                                                              |============================                                          |  40%  |                                                                              |============================                                          |  41%  |                                                                              |=============================                                         |  41%  |                                                                              |=============================                                         |  42%  |                                                                              |==============================                                        |  42%  |                                                                              |==============================                                        |  43%  |                                                                              |==============================                                        |  44%  |                                                                              |===============================                                       |  44%  |                                                                              |===============================                                       |  45%  |                                                                              |================================                                      |  45%  |                                                                              |================================                                      |  46%  |                                                                              |=================================                                     |  46%  |                                                                              |=================================                                     |  47%  |                                                                              |=================================                                     |  48%  |                                                                              |==================================                                    |  48%  |                                                                              |==================================                                    |  49%  |                                                                              |===================================                                   |  49%  |                                                                              |===================================                                   |  50%  |                                                                              |===================================                                   |  51%  |                                                                              |====================================                                  |  51%  |                                                                              |====================================                                  |  52%  |                                                                              |=====================================                                 |  52%  |                                                                              |=====================================                                 |  53%  |                                                                              |=====================================                                 |  54%  |                                                                              |======================================                                |  54%  |                                                                              |======================================                                |  55%  |                                                                              |=======================================                               |  55%  |                                                                              |=======================================                               |  56%  |                                                                              |========================================                              |  56%  |                                                                              |========================================                              |  57%  |                                                                              |========================================                              |  58%  |                                                                              |=========================================                             |  58%  |                                                                              |=========================================                             |  59%  |                                                                              |==========================================                            |  59%  |                                                                              |==========================================                            |  60%  |                                                                              |==========================================                            |  61%  |                                                                              |===========================================                           |  61%  |                                                                              |===========================================                           |  62%  |                                                                              |============================================                          |  62%  |                                                                              |============================================                          |  63%  |                                                                              |============================================                          |  64%  |                                                                              |=============================================                         |  64%  |                                                                              |=============================================                         |  65%  |                                                                              |==============================================                        |  65%  |                                                                              |==============================================                        |  66%  |                                                                              |===============================================                       |  66%  |                                                                              |===============================================                       |  67%  |                                                                              |===============================================                       |  68%  |                                                                              |================================================                      |  68%  |                                                                              |================================================                      |  69%  |                                                                              |=================================================                     |  69%  |                                                                              |=================================================                     |  70%  |                                                                              |=================================================                     |  71%  |                                                                              |==================================================                    |  71%  |                                                                              |==================================================                    |  72%  |                                                                              |===================================================                   |  72%  |                                                                              |===================================================                   |  73%  |                                                                              |===================================================                   |  74%  |                                                                              |====================================================                  |  74%  |                                                                              |====================================================                  |  75%  |                                                                              |=====================================================                 |  75%  |                                                                              |=====================================================                 |  76%  |                                                                              |======================================================                |  76%  |                                                                              |======================================================                |  77%  |                                                                              |======================================================                |  78%  |                                                                              |=======================================================               |  78%  |                                                                              |=======================================================               |  79%  |                                                                              |========================================================              |  79%  |                                                                              |========================================================              |  80%  |                                                                              |========================================================              |  81%  |                                                                              |=========================================================             |  81%  |                                                                              |=========================================================             |  82%  |                                                                              |==========================================================            |  82%  |                                                                              |==========================================================            |  83%  |                                                                              |==========================================================            |  84%  |                                                                              |===========================================================           |  84%  |                                                                              |===========================================================           |  85%  |                                                                              |============================================================          |  85%  |                                                                              |============================================================          |  86%  |                                                                              |=============================================================         |  86%  |                                                                              |=============================================================         |  87%  |                                                                              |=============================================================         |  88%  |                                                                              |==============================================================        |  88%  |                                                                              |==============================================================        |  89%  |                                                                              |===============================================================       |  89%  |                                                                              |===============================================================       |  90%  |                                                                              |===============================================================       |  91%  |                                                                              |================================================================      |  91%  |                                                                              |================================================================      |  92%  |                                                                              |=================================================================     |  92%  |                                                                              |=================================================================     |  93%  |                                                                              |=================================================================     |  94%  |                                                                              |==================================================================    |  94%  |                                                                              |==================================================================    |  95%  |                                                                              |===================================================================   |  95%  |                                                                              |===================================================================   |  96%  |                                                                              |====================================================================  |  96%  |                                                                              |====================================================================  |  97%  |                                                                              |====================================================================  |  98%  |                                                                              |===================================================================== |  98%  |                                                                              |===================================================================== |  99%  |                                                                              |======================================================================|  99%  |                                                                              |======================================================================| 100%
kable(dca$TABLE)
Fintech_Index_diff AI_INDEX_diff Blockchain_Index_diff FROM
Fintech_Index_diff 100.00 56.85 22.43 79.28
AI_INDEX_diff 52.51 100.00 31.81 84.33
Blockchain_Index_diff 23.42 37.14 100.00 60.56
TO 75.93 93.99 54.24 224.17
Inc.Own 175.93 193.99 154.24 cTCI/TCI
NET -3.35 9.67 -6.32 112.08/74.72
NPT 1.00 2.00 0.00

Figure 4: Dynamic conditional R2 decomposed measures

r2c = apply(dca$CT,c(1,3),sum)-1
par(mfcol = c(ceiling(k/2),2), oma = c(0, 1, 0, 0) + 0.5, mar = c(1, 1, 1, 1) + 0.5, mgp = c(1, 0.4, 0))
for (j in 1:k) {
  r2dd = matrix(0,ncol=k,nrow=t)
  for (i in 1:t) {
    ded = rep(0,k)
    ded[j] = 1
    r2dd[i,] = cumsum(dca$CT[j,,i]-ded)
  }
  plot(date,100*r2c[j,]*NA,type="l",las=1,xlab="",ylab="",ylim=c(0,100),xaxs="i",tck=-0.01,yaxs="i",main=NAMES[j])
  grid(NA,NULL)
  for (i in k:1) {
    polygon(c(date, rev(date)), c(c(rep(0, t)), rev(100*r2dd[,i])), col=i, border=i)
  }
  box()
  legend("topleft",NAMES[-j],fill=c(1:k)[-j],bty="n",cex=0.75,ncol=1)
}

Figure 5: Dynamic total connectedness

par(mfcol = c(1,1), oma = c(0, 1, 0, 0) + 0.5, mar = c(1, 1, 1, 1) + 0.5, mgp = c(1, 0.4, 0))
plot(date,dca$TCI*NA,type='l',las=1,xaxs='i',yaxs='i',xlab='',ylab='',main='',tck=-.01, ylim=c(0,110))#c(max(c(0,min(TCI)-10)),max(TCI)+10))
grid(NA,NULL)
polygon(c(date, rev(date)), c(c(rep(0, t)), rev(dca$TCI)), col=1, border=1)
box()

Figure 6: Net total directional connectedness

par(mfcol = c(ceiling(k/2),2), oma = c(0, 0, 0, 0) + 0.5, mar = c(1, 1, 1, 1) + 0.5, mgp = c(1, 0.4, 0))
for (i in 1:k) {
  plot(date,dca$NET[,i]*NA,type='l',las=1,xaxs='i',yaxs='i',ylim=c(-20,20),xlab='',ylab='',main=paste("NET",NAMES[i]),tck=-.025)
  grid(NA,NULL)
  polygon(c(date, rev(date)), c(c(rep(0, t)), rev(dca$NET[,i])), col=1, border=1)
  abline(h=0,lty=3)
  box()
}

Table 7: Hedge ratios

method = "cumsum"
statistics = "Fisher"
metric = "StdDev"
hr = HedgeRatio(Y/100, H, statistics=statistics, method=method, metric=metric, digit=3)
kable(hr$TABLE)
Mean Std.Dev. 5% 95% HE p-value Return Std.Dev SR
Fintech_Index_diff/AI_INDEX_diff -0.014 1.232 -1.342 1.608 -2.092 0.084 0.002 0.001 2.921
Fintech_Index_diff/Blockchain_Index_diff 0.043 0.600 -0.716 0.846 0.040 0.000 0.001 0.000 4.142
AI_INDEX_diff/Fintech_Index_diff 4.092 73.815 -17.305 19.783 -100.684 0.350 -0.003 0.010 -0.285
AI_INDEX_diff/Blockchain_Index_diff 0.236 1.892 -2.362 2.928 0.074 0.000 0.002 0.001 1.776
Blockchain_Index_diff/Fintech_Index_diff -3.450 72.603 -17.189 8.992 -126.712 0.350 0.008 0.009 0.862
Blockchain_Index_diff/AI_INDEX_diff 0.420 4.446 -2.162 3.944 -47.018 0.084 0.005 0.006 0.826

Table 8: Multivariate hedging portfolios

mhp = MultivariateHedgingPortfolio(Y/100, H, statistics=statistics, method=method, digit=3)
kable(mhp$TABLE)
Mean Std.Dev. 5% 95% HE p-value Return Risk SR
Fintech_Index_diff/AI_INDEX_diff -0.020 1.586 -1.585 1.692 -3.779 0.000 0.001 0.001 2.267
Fintech_Index_diff/Blockchain_Index_diff 0.031 0.518 -0.242 0.301 -3.779 0.000 0.001 0.001 2.267
AI_INDEX_diff/Fintech_Index_diff 2.927 54.692 -15.067 14.699 -54.608 0.000 -0.002 0.007 -0.290
AI_INDEX_diff/Blockchain_Index_diff 0.193 1.211 -0.928 1.570 -54.608 0.000 -0.002 0.007 -0.290
Blockchain_Index_diff/Fintech_Index_diff 0.292 38.048 -9.031 10.540 -78.478 0.000 0.006 0.007 0.742
Blockchain_Index_diff/AI_INDEX_diff 1.106 6.472 -2.225 6.007 -78.478 0.000 0.006 0.007 0.742

Figure 3: Dynamic conditional betas

par(mfcol = c(ceiling(k/2),2), oma = c(0, 1, 0, 0) + 0.5, mar = c(1, 1, 1, 1) + 0.5, mgp = c(1, 0.4, 0))
for (j in 1:k) {
  plot(date,mhp$Beta[j,j,]*NA,type='l',las=1,xaxs='i',yaxs='i',xlab='',ylab='',
       main=paste(NAMES[j]),tck=-.02,col=j,ylim=c(-0.5,70))
  grid(NA,NULL)
  coefs = lm(Y[,j]~Y[,-j])$coefficients[-1]
  for (i in 1:k) {
    if (i!=j) {
      lines(date,mhp$Beta[j,i,],col=i)
      abline(h=0,lty=3)
      box()
    }
  }
  col = 1:k
  col = col[-j]
  abline(h=coefs,lty=3,col=col)
  legend("bottom",NAMES[-j],fill=c(1:k)[-j],bty="n",cex=0.6,ncol=k)
}

Table 9: Optimal bivariate portfolio weights

bpw = BivariatePortfolio(Y/100, H, statistics=statistics, method=method, metric=metric, digit=3)
## The optimal bivariate portfolios are computed according to:
##  Kroner, K. F., & Ng, V. K. (1998). Modeling asymmetric comovements of asset returns. The Review of Financial Studies, 11(4), 817-844.
## 
##           Hedging effectiveness is calculated according to:
##  Ederington, L. H. (1979). The hedging performance of the new futures markets. The Journal of Finance, 34(1), 157-170.
## 
##           Statistics of the hedging effectiveness measure are implemented according to:
##  Antonakakis, N., Cunado, J., Filis, G., Gabauer, D., & de Gracia, F. P. (2020). Oil and asset classes implied volatilities: Investment strategies and hedging effectiveness. Energy Economics, 91, 104762.
kable(bpw$TABLE)
Mean Std.Dev. 5% 95% HE p-value SR
Fintech_Index_diff/AI_INDEX_diff 0.763 0.307 0.000 1.000 0.414 0.000 5.179
Fintech_Index_diff/Blockchain_Index_diff 0.789 0.279 0.101 1.000 0.408 0.000 4.959
AI_INDEX_diff/Fintech_Index_diff 0.237 0.307 0.000 1.000 0.942 0.000 5.179
AI_INDEX_diff/Blockchain_Index_diff 0.451 0.395 0.000 1.000 0.648 0.000 1.711
Blockchain_Index_diff/Fintech_Index_diff 0.211 0.279 0.000 0.899 0.924 0.000 4.959
Blockchain_Index_diff/AI_INDEX_diff 0.549 0.395 0.000 1.000 0.545 0.000 1.711

Table 10: Multivariate portfolio analysis

PCIc = dca$PCI
PCIg = dca$CT
for (l in 1:dim(dca$CT)[3]) {
  for (i in 1:k) {
    for (j in 1:k) {
      PCIg[i,j,l] = (2*R[i,j,l]^2)/(1+R[i,j,l]^2)
    }
  }
}
mvp = MinimumConnectednessPortfolio(Y/100, H, statistics=statistics, method=method, metric=metric, digit=3)
## The minimum connectedness portfolio is implemented according to:
##  Broadstock, D. C., Chatziantoniou, I., & Gabauer, D. (2022). Minimum connectedness portfolios and the market for green bonds: Advocating socially responsible investment (SRI) activity. In Applications in Energy Finance (pp. 217-253). Palgrave Macmillan, Cham.
## 
##           Hedging effectiveness is calculated according to:
##  Ederington, L. H. (1979). The hedging performance of the new futures markets. The Journal of Finance, 34(1), 157-170.
## 
##           Statistics of the hedging effectiveness measure are implemented according to:
##  Antonakakis, N., Cunado, J., Filis, G., Gabauer, D., & de Gracia, F. P. (2020). Oil and asset classes implied volatilities: Investment strategies and hedging effectiveness. Energy Economics, 91, 104762.
mcp = MinimumConnectednessPortfolio(Y/100, R, statistics=statistics, method=method, metric=metric, digit=3)
## The minimum connectedness portfolio is implemented according to:
##  Broadstock, D. C., Chatziantoniou, I., & Gabauer, D. (2022). Minimum connectedness portfolios and the market for green bonds: Advocating socially responsible investment (SRI) activity. In Applications in Energy Finance (pp. 217-253). Palgrave Macmillan, Cham.
## 
##           Hedging effectiveness is calculated according to:
##  Ederington, L. H. (1979). The hedging performance of the new futures markets. The Journal of Finance, 34(1), 157-170.
## 
##           Statistics of the hedging effectiveness measure are implemented according to:
##  Antonakakis, N., Cunado, J., Filis, G., Gabauer, D., & de Gracia, F. P. (2020). Oil and asset classes implied volatilities: Investment strategies and hedging effectiveness. Energy Economics, 91, 104762.
mpc = MinimumConnectednessPortfolio(Y/100, PCIc, statistics=statistics, method=method, metric=metric, digit=3)
## The minimum connectedness portfolio is implemented according to:
##  Broadstock, D. C., Chatziantoniou, I., & Gabauer, D. (2022). Minimum connectedness portfolios and the market for green bonds: Advocating socially responsible investment (SRI) activity. In Applications in Energy Finance (pp. 217-253). Palgrave Macmillan, Cham.
## 
##           Hedging effectiveness is calculated according to:
##  Ederington, L. H. (1979). The hedging performance of the new futures markets. The Journal of Finance, 34(1), 157-170.
## 
##           Statistics of the hedging effectiveness measure are implemented according to:
##  Antonakakis, N., Cunado, J., Filis, G., Gabauer, D., & de Gracia, F. P. (2020). Oil and asset classes implied volatilities: Investment strategies and hedging effectiveness. Energy Economics, 91, 104762.
mpg = MinimumConnectednessPortfolio(Y/100, PCIg, statistics=statistics, method=method, metric=metric, digit=3)
## The minimum connectedness portfolio is implemented according to:
##  Broadstock, D. C., Chatziantoniou, I., & Gabauer, D. (2022). Minimum connectedness portfolios and the market for green bonds: Advocating socially responsible investment (SRI) activity. In Applications in Energy Finance (pp. 217-253). Palgrave Macmillan, Cham.
## 
##           Hedging effectiveness is calculated according to:
##  Ederington, L. H. (1979). The hedging performance of the new futures markets. The Journal of Finance, 34(1), 157-170.
## 
##           Statistics of the hedging effectiveness measure are implemented according to:
##  Antonakakis, N., Cunado, J., Filis, G., Gabauer, D., & de Gracia, F. P. (2020). Oil and asset classes implied volatilities: Investment strategies and hedging effectiveness. Energy Economics, 91, 104762.
mrp = MinimumConnectednessPortfolio(Y/100, dca$CT, statistics=statistics, method=method, metric=metric, digit=3)
## The minimum connectedness portfolio is implemented according to:
##  Broadstock, D. C., Chatziantoniou, I., & Gabauer, D. (2022). Minimum connectedness portfolios and the market for green bonds: Advocating socially responsible investment (SRI) activity. In Applications in Energy Finance (pp. 217-253). Palgrave Macmillan, Cham.
## 
##           Hedging effectiveness is calculated according to:
##  Ederington, L. H. (1979). The hedging performance of the new futures markets. The Journal of Finance, 34(1), 157-170.
## 
##           Statistics of the hedging effectiveness measure are implemented according to:
##  Antonakakis, N., Cunado, J., Filis, G., Gabauer, D., & de Gracia, F. P. (2020). Oil and asset classes implied volatilities: Investment strategies and hedging effectiveness. Energy Economics, 91, 104762.
MVA = rbind(mvp$TABLE, mcp$TABLE, mpc$TABLE, mpg$TABLE, mrp$TABLE)
kable(MVA)
Mean Std.Dev. 5% 95% HE p-value SR
Fintech_Index_diff 0.674 0.307 0.000 0.999 0.375 0.000 5.182
AI_INDEX_diff 0.226 0.288 0.000 0.974 0.938 0.000 5.182
Blockchain_Index_diff 0.099 0.166 0.000 0.476 0.920 0.000 5.182
Fintech_Index_diff 0.390 0.171 0.000 0.555 -1.456 0.000 2.604
AI_INDEX_diff 0.365 0.220 0.000 0.569 0.757 0.000 2.604
Blockchain_Index_diff 0.245 0.217 0.000 0.498 0.685 0.000 2.604
Fintech_Index_diff 0.378 0.105 0.162 0.485 -1.286 0.000 2.160
AI_INDEX_diff 0.181 0.120 0.024 0.458 0.774 0.000 2.160
Blockchain_Index_diff 0.441 0.068 0.328 0.497 0.707 0.000 2.160
Fintech_Index_diff 0.452 0.179 0.000 0.580 -1.480 0.000 2.264
AI_INDEX_diff 0.114 0.199 0.000 0.505 0.755 0.000 2.264
Blockchain_Index_diff 0.434 0.121 0.000 0.500 0.682 0.000 2.264
Fintech_Index_diff 0.327 0.037 0.261 0.392 -1.483 0.000 2.485
AI_INDEX_diff 0.283 0.029 0.247 0.344 0.754 0.000 2.485
Blockchain_Index_diff 0.390 0.042 0.310 0.464 0.682 0.000 2.485

Table 11: Portfolio performance

library(PerformanceAnalytics)
library(xts)
port.mat = data.frame(
                     MVP=mvp$portfolio_return,
                     MCP=mcp$portfolio_return,
                     MPC=mpc$portfolio_return,
                     MPG=mpg$portfolio_return,
                     MRP=mrp$portfolio_return
                     )
port.xts = xts(port.mat, order.by=date)
ir = matrix(NA, nrow=1, ncol=ncol(port.xts))
colnames(ir) = colnames(port.xts)
rownames(ir) = "GRE"
for (i in 1:ncol(port.xts)) {
  ir[,i] = InformationRatio(Ra=port.xts[,i], Rb=Y[,1]/100)
}
k = ncol(port.xts)
table = matrix(NA, ncol=k, nrow=5)
for (i in 1:k) {
  table[,i] = c(
  # Retorno anualizado
  Return.annualized(port.xts[,i]),
  
  # Desviación estándar anualizada
  StdDev.annualized(port.xts[,i]),
  
  # Ratio de Sharpe anualizado
  SharpeRatio.annualized(port.xts[,i]),
  
  # Valor en Riesgo (VaR) con distribución normal y percentil del 95%
  VaR(as.numeric(port.xts[,i]), p=0.95, method="gaussian"),
  
  # Expectativa de Pérdida (ES) con distribución normal y percentil del 95%
  ES(as.numeric(port.xts[,i]), p=0.95, method="gaussian")
)
}
colnames(table) = colnames(port.xts)
rownames(table) = c("Return","StdDev","Sharpe Ratio (StdDev)","Sharpe Ratio (VaR)","Sharpe Ratio (CVaR)")
kable(rbind(table, ir))
MVP MCP MPC MPG MRP
Return 0.0012265 0.0012220 0.0009781 0.0010677 0.0011724
StdDev 0.0002367 0.0004693 0.0004527 0.0004716 0.0004719
Sharpe Ratio (StdDev) 5.1822047 2.6040207 2.1603544 2.2641097 2.4845743
Sharpe Ratio (VaR) -0.0000241 -0.0000460 -0.0000436 -0.0000475 -0.0000466
Sharpe Ratio (CVaR) -0.0000031 -0.0000017 -0.0000009 -0.0000009 -0.0000016
GRE 2.0556984 1.1172527 0.7210579 0.9113081 1.0528818

Antonakakis, Chatziantoniou and Gabauer (2020): Refined measures of dynamic connectedness based on time-varying parameter vector autoregressions

dca3 = ConnectednessApproach(data_zoo2, 
                            nlag=1, 
                            nfore=12,
                            window.size=200,
                            model="TVP-VAR",
                            connectedness="Time",
                            VAR_config=list(TVPVAR=list(kappa1=0.99, kappa2=0.96, prior="BayesPrior")))
## Estimating model
## Computing connectedness measures
## The TVP-VAR connectedness approach is implemented according to:
##  Antonakakis, N., Chatziantoniou, I., & Gabauer, D. (2020). Refined measures of dynamic connectedness based on time-varying parameter vector autoregressions. Journal of Risk and Financial Management, 13(4), 84.
DCA = list()
WINDOW.SIZE = c(50, 100, 200)
for (i in 1:length(WINDOW.SIZE)) {
  DCA[[i]] = suppressMessages(ConnectednessApproach(data_zoo2, 
                              nlag=1, 
                              nfore=12,
                              window.size=WINDOW.SIZE[i]))
}

#Figure 7: Dynamic Total Connectedness
PlotTCI(dca3, ca=DCA, ylim=c(20,80))

# Figure 8: Net Total and Net Pairwise Directional Connectedness Measures
PlotNET(dca3, ca=DCA, ylim=c(-20,20))

PlotNPDC(dca3, ca=DCA, ylim=c(-20,20))

# Función para crear la tabla con los cálculos dinámicos de conectividad
ConnectednessTableModified <- function(FEVD, digit = 2) {
  if (length(dim(FEVD)) <= 1) {
    stop("FEVD needs to be at least a 2-dimensional matrix")
  }
  
  # Nombres de los activos
  NAMES = colnames(FEVD)
  k = dim(FEVD)[1]
  if (is.null(NAMES)) {
    NAMES = 1:k
  }
  
  # Calcular las métricas principales
  CT = apply(FEVD, 1:2, mean) * 100  # De otros hacia un activo específico
  OWN = diag(diag(CT))
  TO = colSums(CT - OWN)  # Contribución hacia otros activos
  FROM = rowSums(CT - OWN)  # Contribución desde otros activos
  NET = TO - FROM  # Conectividad neta
  TCI = mean(TO)  # Índice total de conectividad
  cTCI = TCI * k / (k - 1)  # Índice corregido
  NPDC = CT - t(CT)  # Conectividad direccional neta par-a-par
  NPT = rowSums(NPDC < 0)  # Contador de transmisores netos
  INFLUENCE = 100 * abs(NPDC / t(t(CT) + CT))  # Influencia porcentual
  
  # Crear tabla final
  table = format(round(cbind(CT, FROM), digit), nsmall = digit)
  to = c(format(round(c(TO, sum(TO)), digit), nsmall = digit))
  inc = c(format(round(colSums(CT), digit), nsmall = digit), "cTCI/TCI")
  tci = paste0(format(round(cTCI, digit), nsmall = digit), "/", format(round(TCI, digit), nsmall = digit))
  net = c(format(round(NET, digit), nsmall = digit))
  net = c(net, tci)
  npdc = c(format(round(NPDC, digit), nsmall = digit))
  npt = c(format(round(NPT, digit), nsmall = digit), "")
  
  TABLE = rbind(table, to, inc, net, npt)
  colnames(TABLE) = c(NAMES, "FROM")
  rownames(TABLE) = c(NAMES, "TO", "Inc.Own", "NET", "NPT")
  
  PCI = matrix(NA, k, k)
  for (i in 1:k) {
    for (j in 1:k) {
      PCI[i, j] = 200 * (CT[i, j] + CT[j, i]) / (CT[i, i] + CT[i, j] + CT[j, i] + CT[j, j])
    }
  }
  
  return(list(
    FEVD = CT,
    TCI = TCI,
    cTCI = cTCI,
    PCI = PCI,
    TO = TO,
    FROM = FROM,
    NET = NET,
    NPDC = NPDC,
    TABLE = TABLE,
    NPT = NPT,
    INFLUENCE = INFLUENCE
  ))
}

# Aplicar la función a las ventanas y mostrar las tablas
tables <- list()  # Lista vacía para almacenar las tablas
for (i in seq_along(DCA)) {
  result <- ConnectednessTableModified(DCA[[i]]$CT, digit = 2)  # Ajusta según tu estructura
  tables[[i]] <- result$TABLE  # Guardar la tabla en la lista
  cat(paste0("\nWindow Size: ", WINDOW.SIZE[i], "\n"))
  print(result$TABLE)  # Mostrar solo la tabla para cada ventana
}
## 
## Window Size: 50
##                  AI_INDEX Fintech_Index Blockchain_Index FROM         
## AI_INDEX         "72.20"  "12.04"       "15.77"          "27.80"      
## Fintech_Index    "11.31"  "75.95"       "12.73"          "24.05"      
## Blockchain_Index "16.73"  "12.67"       "70.60"          "29.40"      
## TO               "28.04"  "24.71"       "28.50"          "81.25"      
## Inc.Own          "100.24" "100.66"      " 99.10"         "cTCI/TCI"   
## NET              " 0.24"  " 0.66"       "-0.90"          "40.63/27.08"
## NPT              "1.00"   "1.00"        "1.00"           ""           
## 
## Window Size: 100
##                  AI_INDEX Fintech_Index Blockchain_Index FROM         
## AI_INDEX         "80.58"  " 6.93"       "12.49"          "19.42"      
## Fintech_Index    " 6.38"  "87.13"       " 6.49"          "12.87"      
## Blockchain_Index "13.60"  " 7.09"       "79.30"          "20.70"      
## TO               "19.98"  "14.02"       "18.97"          "52.98"      
## Inc.Own          "100.57" "101.16"      " 98.28"         "cTCI/TCI"   
## NET              " 0.57"  " 1.16"       "-1.72"          "26.49/17.66"
## NPT              "1.00"   "2.00"        "0.00"           ""           
## 
## Window Size: 200
##                  AI_INDEX Fintech_Index Blockchain_Index FROM         
## AI_INDEX         "84.66"  " 5.00"       "10.34"          "15.34"      
## Fintech_Index    " 4.14"  "93.01"       " 2.85"          " 6.99"      
## Blockchain_Index "11.66"  " 3.62"       "84.72"          "15.28"      
## TO               "15.80"  " 8.61"       "13.19"          "37.60"      
## Inc.Own          "100.46" "101.62"      " 97.92"         "cTCI/TCI"   
## NET              " 0.46"  " 1.62"       "-2.08"          "18.80/12.53"
## NPT              "1.00"   "2.00"        "0.00"           ""
LS0tDQp0aXRsZTogIlJldHVybiBhbmQgVm9sYXRpbGl0eSBTcGlsbG92ZXJzIEJldHdlZW4gRmluVGVjaCwgQmxvY2tjaGFpbiBhbmQgQUkgRmlybXMiDQpzdWJ0aXRsZTogIkVzdGFuY2lhIGRlIEludmVzdGlnYWNpw7NuIg0KYXV0aG9yOiAiQXZyaWwgTG9iYXRvIERlbGdhZG8iDQpkYXRlOiAiMjAyNC0xMS0wMSINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDoNCiAgICB0b2M6IHllcw0KICAgIHRvY19mbG9hdDogeWVzDQogICAgY29kZV9kb3dubG9hZDogeWVzDQogICAgdGhlbWU6IGNlcnVsZWFuDQogICAgaGlnaGxpZ2h0OiBweWdtZW50cw0KLS0tDQoNCiFbXShodHRwczovL2NpdHJpcy11Yy5vcmcvd3AtY29udGVudC91cGxvYWRzLzIwMTkvMTAvVGVjLWRlLU1vbnRlcnJleS1sb2dvLWhvcml6b250YWwtYmx1ZS5wbmcpDQoNCjxkaXYgc3R5bGU9InRleHQtYWxpZ246IGNlbnRlciI+DQogIDxwPjxzdHJvbmc+VGVjbm9sw7NnaWNvIGRlIE1vbnRlcnJleTwvc3Ryb25nPjwvcD4NCiAgPHA+PHN0cm9uZz5Eb2N0b3IgVGXDs2ZpbG8gT3p1bmE8L3N0cm9uZz48L3A+DQo8L2Rpdj4NCg0KPGRpdiBzdHlsZT0idGV4dC1hbGlnbjogY2VudGVyIj4NCiAgPHA+PHN0cm9uZz5BbHVtbmE6PC9zdHJvbmc+PC9wPg0KDQogIEF2cmlsIExvYmF0byBEZWxnYWRvIEEwMDgzMzExMw0KIA0KPC9kaXY+DQoNCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQppZiAocGFja2FnZVZlcnNpb24oInhmdW4iKSA8ICIwLjQ0Iikgew0KICBpbnN0YWxsLnBhY2thZ2VzKCJ4ZnVuIikNCn0NCg0KIyBDYXJnYSBlbCBwYXF1ZXRlIGFjdHVhbGl6YWRvDQpsaWJyYXJ5KHhmdW4pDQoNCiMgQ29uZmlndXJhY2nDs24gZGUgbG9zIGNodW5rcyBkZSBrbml0cg0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KA0KCWVjaG8gPSBUUlVFLA0KCW1lc3NhZ2UgPSBUUlVFLA0KCXdhcm5pbmcgPSBUUlVFDQopDQpgYGANCg0KIyBFREEgZGUgYmFzZSBkZSBkYXRvcw0KDQpMaWJyZXJpYXMNCmBgYHtyIGVjaG89VFJVRSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KHRpZHlyKQ0KbGlicmFyeShsdWJyaWRhdGUpDQpsaWJyYXJ5KHB1cnJyKQ0KbGlicmFyeShwbG90bHkpDQpsaWJyYXJ5KGZvcmVjYXN0KQ0KbGlicmFyeShyZWFkeGwpDQpsaWJyYXJ5KERhdGFFeHBsb3JlcikNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KHRtKQ0KbGlicmFyeShjbHVzdGVyKQ0KbGlicmFyeShmYWN0b2V4dHJhKSANCmxpYnJhcnkoZ3JpZEV4dHJhKQ0KbGlicmFyeShwdXJycikNCmxpYnJhcnkocFJPQykNCmxpYnJhcnkocnBhcnQpDQpsaWJyYXJ5KHJwYXJ0LnBsb3QpDQpsaWJyYXJ5KGUxMDcxKQ0KbGlicmFyeShnZ3B1YnIpDQpsaWJyYXJ5KGRsb29rcikNCmxpYnJhcnkoem9vKQ0KbGlicmFyeShjYXJldCkNCmxpYnJhcnkoc3RhdHMpDQpsaWJyYXJ5KHRzZXJpZXMpDQpsaWJyYXJ5KHJlYWRyKQ0KbGlicmFyeSh2YXJzKQ0KbGlicmFyeShzeXV6aGV0KQ0KbGlicmFyeShrYWJsZUV4dHJhKQ0KbGlicmFyeShwbG90bHkpDQpsaWJyYXJ5KHNjYWxlcykNCmxpYnJhcnkoa25pdHIpDQpsaWJyYXJ5KHJtZ2FyY2gpDQpsaWJyYXJ5KGRldnRvb2xzKQ0KbGlicmFyeShvcGVueGxzeCkNCmxpYnJhcnkocmVsYWltcG8pDQpsaWJyYXJ5KHN0YXJnYXplcikNCmxpYnJhcnkoUkNvbG9yQnJld2VyKQ0KbGlicmFyeShQZXJmb3JtYW5jZUFuYWx5dGljcykNCmxpYnJhcnkoQ29ubmVjdGVkbmVzc0FwcHJvYWNoKQ0KbGlicmFyeShyZWFkcikNCmxpYnJhcnkodHNlcmllcykNCmxpYnJhcnkoZm9yZWNhc3QpDQpsaWJyYXJ5KHVyY2EpDQpsaWJyYXJ5KGZHYXJjaCkNCmxpYnJhcnkoTVRTKQ0KbGlicmFyeShNQVNTKQ0KbGlicmFyeShub3J0ZXN0KQ0KbGlicmFyeShvdXRsaWVycykNCmxpYnJhcnkobW9tZW50cykNCmxpYnJhcnkoRmluVFMpDQpsaWJyYXJ5KFdlaWdodGVkUG9ydFRlc3QpDQpgYGANCg0KIyMgQ2FyZ2EgZGUgYmFzZSBkZSBkYXRvcw0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCiMgTGVlIGVsIGFyY2hpdm8gQ1NWIHkgc2VsZWNjaW9uYSBsYXMgY29sdW1uYXMgcmVsZXZhbnRlcw0KaW5kZXhfYWx0IDwtIHJlYWRfY3N2KCJDOi9Vc2Vycy9BVlJJTC9EZXNrdG9wL1NwaWxsb3ZlcnMvYWxsX2RhaWx5X2luZGV4X3JldHVybnMuY3N2IikNCmRhdGFfc2VsZWN0ZWQgPC0gaW5kZXhfYWx0WywgYygiRGF0ZSIsICJBSV9JTkRFWCIsICJGaW50ZWNoX0luZGV4IiwgIkJsb2NrY2hhaW5fSW5kZXgiKV0NCmBgYA0KDQojIyBUZXN0cyB5IEVzdGFkw61zdGljb3MgZGUgYmQgb3JpZ2luYWwNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQojIEZ1bmN0aW9uIGZvciBzdW1tYXJ5IHN0YXRpc3RpY3MNCnN1bW1hcnlfc3RhdHMgPC0gZnVuY3Rpb24oZGF0YSkgew0KICByZXR1cm4oZGF0YS5mcmFtZSgNCiAgICBNZWFuID0gbWVhbihkYXRhLCBuYS5ybSA9IFRSVUUpLA0KICAgIFN0ZERldiA9IHNkKGRhdGEsIG5hLnJtID0gVFJVRSksDQogICAgTWluID0gbWluKGRhdGEsIG5hLnJtID0gVFJVRSksDQogICAgUDI1ID0gcXVhbnRpbGUoZGF0YSwgMC4yNSwgbmEucm0gPSBUUlVFKSwNCiAgICBQNTAgPSBtZWRpYW4oZGF0YSwgbmEucm0gPSBUUlVFKSwNCiAgICBQNzUgPSBxdWFudGlsZShkYXRhLCAwLjc1LCBuYS5ybSA9IFRSVUUpLA0KICAgIE1heCA9IG1heChkYXRhLCBuYS5ybSA9IFRSVUUpLA0KICAgIFNrZXduZXNzID0gc2tld25lc3MoZGF0YSwgbmEucm0gPSBUUlVFKSwNCiAgICBLdXJ0b3NpcyA9IGt1cnRvc2lzKGRhdGEsIG5hLnJtID0gVFJVRSkNCiAgKSkNCn0NCg0KIyBDYWxjdWxhdGUgc3RhdGlzdGljcyBhbmQgdGVzdHMgZm9yIGVhY2ggaW5kZXgNCnJlc3VsdHMgPC0gZGF0YS5mcmFtZSgNCiAgVGVzdCA9IGMoDQogICAgIk1lYW4iLCAiU3RhbmRhcmQgRGV2aWF0aW9uIiwgIk1pbmltdW0iLCAiMjV0aCBQZXJjZW50aWxlIiwgIk1lZGlhbiIsDQogICAgIjc1dGggUGVyY2VudGlsZSIsICJNYXhpbXVtIiwgIlNrZXduZXNzIiwgIkt1cnRvc2lzIiwgIkphcnF1ZS1CZXJhIChwLXZhbHVlKSIsDQogICAgIkFERiBUZXN0IChwLXZhbHVlKSIsICJLUFNTIFRlc3QgKHAtdmFsdWUpIiwgIlBQIFRlc3QgKHAtdmFsdWUpIiwgIkVSUyBUZXN0IiwNCiAgICAiQVJDSCBUZXN0IChwLXZhbHVlKSIsICJXZWlnaHRlZCBQb3J0bWFudGVhdSBUZXN0IChwLXZhbHVlKSIsICJRMigyMCkgVGVzdCAocC12YWx1ZSkiLA0KICAgICJPdXRsaWVyIGRldGVjdGlvbiAoQ2hlbiBhbmQgTGl1KSIsIkNvcnJlbGF0aW9uIE1hdHJpeCBhbmQgUi1zcXVhcmVkIg0KICApLA0KICBBSV9JTkRFWCA9IE5BLCBGaW50ZWNoX0luZGV4ID0gTkEsIEJsb2NrY2hhaW5fSW5kZXggPSBOQQ0KKQ0KDQojIFBvcHVsYXRlIHRoZSB0YWJsZSB3aXRoIHN1bW1hcnkgc3RhdHMNCnN0YXRzX2FpIDwtIHN1bW1hcnlfc3RhdHMoZGF0YV9zZWxlY3RlZCRBSV9JTkRFWCkNCnN0YXRzX2ZpbnRlY2ggPC0gc3VtbWFyeV9zdGF0cyhkYXRhX3NlbGVjdGVkJEZpbnRlY2hfSW5kZXgpDQpzdGF0c19ibG9ja2NoYWluIDwtIHN1bW1hcnlfc3RhdHMoZGF0YV9zZWxlY3RlZCRCbG9ja2NoYWluX0luZGV4KQ0KcmVzdWx0cyRBSV9JTkRFWFsxOjldIDwtIGFzLm51bWVyaWMoc3RhdHNfYWkpDQpyZXN1bHRzJEZpbnRlY2hfSW5kZXhbMTo5XSA8LSBhcy5udW1lcmljKHN0YXRzX2ZpbnRlY2gpDQpyZXN1bHRzJEJsb2NrY2hhaW5fSW5kZXhbMTo5XSA8LSBhcy5udW1lcmljKHN0YXRzX2Jsb2NrY2hhaW4pDQoNCiMgTm9ybWFsaXR5IGFuZCBzdGF0aW9uYXJpdHkgdGVzdHMNCnJlc3VsdHMkQUlfSU5ERVhbMTBdIDwtIGphcnF1ZS5iZXJhLnRlc3QoZGF0YV9zZWxlY3RlZCRBSV9JTkRFWCkkcC52YWx1ZQ0KcmVzdWx0cyRGaW50ZWNoX0luZGV4WzEwXSA8LSBqYXJxdWUuYmVyYS50ZXN0KGRhdGFfc2VsZWN0ZWQkRmludGVjaF9JbmRleCkkcC52YWx1ZQ0KcmVzdWx0cyRCbG9ja2NoYWluX0luZGV4WzEwXSA8LSBqYXJxdWUuYmVyYS50ZXN0KGRhdGFfc2VsZWN0ZWQkQmxvY2tjaGFpbl9JbmRleCkkcC52YWx1ZQ0KDQpyZXN1bHRzJEFJX0lOREVYWzExXSA8LSBhZGYudGVzdChkYXRhX3NlbGVjdGVkJEFJX0lOREVYKSRwLnZhbHVlDQpyZXN1bHRzJEZpbnRlY2hfSW5kZXhbMTFdIDwtIGFkZi50ZXN0KGRhdGFfc2VsZWN0ZWQkRmludGVjaF9JbmRleCkkcC52YWx1ZQ0KcmVzdWx0cyRCbG9ja2NoYWluX0luZGV4WzExXSA8LSBhZGYudGVzdChkYXRhX3NlbGVjdGVkJEJsb2NrY2hhaW5fSW5kZXgpJHAudmFsdWUNCg0KcmVzdWx0cyRBSV9JTkRFWFsxMl0gPC0ga3Bzcy50ZXN0KGRhdGFfc2VsZWN0ZWQkQUlfSU5ERVgpJHAudmFsdWUNCnJlc3VsdHMkRmludGVjaF9JbmRleFsxMl0gPC0ga3Bzcy50ZXN0KGRhdGFfc2VsZWN0ZWQkRmludGVjaF9JbmRleCkkcC52YWx1ZQ0KcmVzdWx0cyRCbG9ja2NoYWluX0luZGV4WzEyXSA8LSBrcHNzLnRlc3QoZGF0YV9zZWxlY3RlZCRCbG9ja2NoYWluX0luZGV4KSRwLnZhbHVlDQoNCnJlc3VsdHMkQUlfSU5ERVhbMTNdIDwtIHBwLnRlc3QoZGF0YV9zZWxlY3RlZCRBSV9JTkRFWCkkcC52YWx1ZQ0KcmVzdWx0cyRGaW50ZWNoX0luZGV4WzEzXSA8LSBwcC50ZXN0KGRhdGFfc2VsZWN0ZWQkRmludGVjaF9JbmRleCkkcC52YWx1ZQ0KcmVzdWx0cyRCbG9ja2NoYWluX0luZGV4WzEzXSA8LSBwcC50ZXN0KGRhdGFfc2VsZWN0ZWQkQmxvY2tjaGFpbl9JbmRleCkkcC52YWx1ZQ0KDQpyZXN1bHRzJEFJX0lOREVYWzE0XSA8LSB1ci5lcnMoZGF0YV9zZWxlY3RlZCRBSV9JTkRFWCwgdHlwZSA9ICJERi1HTFMiKUB0ZXN0c3RhdA0KcmVzdWx0cyRGaW50ZWNoX0luZGV4WzE0XSA8LSB1ci5lcnMoZGF0YV9zZWxlY3RlZCRGaW50ZWNoX0luZGV4LCB0eXBlID0gIkRGLUdMUyIpQHRlc3RzdGF0DQpyZXN1bHRzJEJsb2NrY2hhaW5fSW5kZXhbMTRdIDwtIHVyLmVycyhkYXRhX3NlbGVjdGVkJEJsb2NrY2hhaW5fSW5kZXgsIHR5cGUgPSAiREYtR0xTIilAdGVzdHN0YXQNCg0KIyBBUkNIIHRlc3QNCnJlc3VsdHMkQUlfSU5ERVhbMTVdIDwtIEFyY2hUZXN0KGRhdGFfc2VsZWN0ZWQkQUlfSU5ERVgpJHAudmFsdWUNCnJlc3VsdHMkRmludGVjaF9JbmRleFsxNV0gPC0gQXJjaFRlc3QoZGF0YV9zZWxlY3RlZCRGaW50ZWNoX0luZGV4KSRwLnZhbHVlDQpyZXN1bHRzJEJsb2NrY2hhaW5fSW5kZXhbMTVdIDwtIEFyY2hUZXN0KGRhdGFfc2VsZWN0ZWQkQmxvY2tjaGFpbl9JbmRleCkkcC52YWx1ZQ0KDQojIFBvcnRtYW50ZWF1IHRlc3QNCnJlc3VsdHMkcG9ydG1hbnRlYXVfYWkgPC0gV2VpZ2h0ZWQuQm94LnRlc3QoZGF0YV9zZWxlY3RlZCRBSV9JTkRFWCkkcC52YWx1ZQ0KcmVzdWx0cyRwb3J0bWFudGVhdV9maW50ZWNoIDwtIFdlaWdodGVkLkJveC50ZXN0KGRhdGFfc2VsZWN0ZWQkRmludGVjaF9JbmRleCkkcC52YWx1ZQ0KcmVzdWx0cyRwb3J0bWFudGVhdV9ibG9ja2NoYWluIDwtIFdlaWdodGVkLkJveC50ZXN0KGRhdGFfc2VsZWN0ZWQkQmxvY2tjaGFpbl9JbmRleCkkcC52YWx1ZQ0KDQojIFEyKDIwKSB0ZXN0DQpyZXN1bHRzJEFJX0lOREVYWzE3XSA8LSBCb3gudGVzdChkYXRhX3NlbGVjdGVkJEFJX0lOREVYXjIsIGxhZyA9IDIwLCB0eXBlID0gIkxqdW5nLUJveCIpJHAudmFsdWUNCnJlc3VsdHMkRmludGVjaF9JbmRleFsxN10gPC0gQm94LnRlc3QoZGF0YV9zZWxlY3RlZCRGaW50ZWNoX0luZGV4XjIsIGxhZyA9IDIwLCB0eXBlID0gIkxqdW5nLUJveCIpJHAudmFsdWUNCnJlc3VsdHMkQmxvY2tjaGFpbl9JbmRleFsxN10gPC0gQm94LnRlc3QoZGF0YV9zZWxlY3RlZCRCbG9ja2NoYWluX0luZGV4XjIsIGxhZyA9IDIwLCB0eXBlID0gIkxqdW5nLUJveCIpJHAudmFsdWUNCg0KIyBPdXRsaWVyIGRldGVjdGlvbiAoQ2hlbiBhbmQgTGl1KQ0KcmVzdWx0cyRvdXRsaWVyc19haSA8LSBzdW0oc2NvcmVzKGRhdGFfc2VsZWN0ZWQkQUlfSU5ERVgsIHR5cGUgPSAiY2hpc3EiLCBwcm9iID0gMC4wNSkgIT0gMCkNCnJlc3VsdHMkb3V0bGllcnNfZmludGVjaCA8LSBzdW0oc2NvcmVzKGRhdGFfc2VsZWN0ZWQkRmludGVjaF9JbmRleCwgdHlwZSA9ICJjaGlzcSIsIHByb2IgPSAwLjA1KSAhPSAwKQ0KcmVzdWx0cyRvdXRsaWVyc19ibG9ja2NoYWluIDwtIHN1bShzY29yZXMoZGF0YV9zZWxlY3RlZCRCbG9ja2NoYWluX0luZGV4LCB0eXBlID0gImNoaXNxIiwgcHJvYiA9IDAuMDUpICE9IDApDQoNCiMgQ29ycmVsYXRpb24gTWF0cml4IGFuZCBSLXNxdWFyZWQNCmNvcl9tYXRyaXggPC0gY29yKGRhdGFfc2VsZWN0ZWRbLCAtMV0sIHVzZSA9ICJjb21wbGV0ZS5vYnMiKQ0Kcl9zcXVhcmVkIDwtIGNvcl9tYXRyaXheMg0KDQpwcmludChyZXN1bHRzKQ0KYGBgDQoNCmBgYHtyfQ0KIyBDb252ZXJ0aXIgbGEgY29sdW1uYSBgRGF0ZWAgYSB0aXBvIERhdGUgc2kgZXN0w6EgZW4gZm9ybWF0byAiZGQvbW0veXl5eSINCmluZGV4X2FsdCREYXRlIDwtIGFzLkRhdGUoaW5kZXhfYWx0JERhdGUsIGZvcm1hdCA9ICIlZC8lbS8lWSIpDQoNCiMgTW9zdHJhciBlc3RydWN0dXJhIHkgcmVzdW1lbg0Kc3RyKGluZGV4X2FsdCkNCnN1bW1hcnkoaW5kZXhfYWx0KQ0KYGBgDQoNCiMgKipDaGF0emlhbnRvbmlvdSwgR2FiYXVlciAmIEd1cHRhICgyMDIxKToqKiBJbnRlZ3JhdGlvbiBhbmQgcmlzayB0cmFuc21pc3Npb24gaW4gdGhlIG1hcmtldCBmb3IgY3J1ZGUgb2lsOiBBIHRpbWUtdmFyeWluZyBwYXJhbWV0ZXIgZnJlcXVlbmN5IGNvbm5lY3RlZG5lc3MgYXBwcm9hY2gNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQojIENvbnZlcnRpciBhIG9iamV0byB6b28NCmRhdGFfc2VsZWN0ZWQgPC0gaW5kZXhfYWx0WywgYygiRGF0ZSIsIkFJX0lOREVYIiwgIkZpbnRlY2hfSW5kZXgiLCAiQmxvY2tjaGFpbl9JbmRleCIpXQ0KDQpkYXRhX21hdHJpeCA8LSBhcy5tYXRyaXgoZGF0YV9zZWxlY3RlZCkNCg0KZGF0YV96b28gPC0gem9vKGRhdGFfc2VsZWN0ZWRbLCAtMV0sIG9yZGVyLmJ5ID0gZGF0YV9zZWxlY3RlZCREYXRlKQ0KDQojIEluc3RhbGFyIHkgY2FyZ2FyIGVsIHBhcXVldGUgQ29ubmVjdGVkbmVzc0FwcHJvYWNoLCBzaSBubyBlc3TDoSB5YSBpbnN0YWxhZG8NCmlmICghcmVxdWlyZU5hbWVzcGFjZSgiQ29ubmVjdGVkbmVzc0FwcHJvYWNoIiwgcXVpZXRseSA9IFRSVUUpKSB7DQogIGlmICghcmVxdWlyZU5hbWVzcGFjZSgiZGV2dG9vbHMiLCBxdWlldGx5ID0gVFJVRSkpIHsNCiAgICBpbnN0YWxsLnBhY2thZ2VzKCJkZXZ0b29scyIpDQogIH0NCiAgZGV2dG9vbHM6Omluc3RhbGxfZ2l0aHViKCJHYWJhdWVyRGF2aWQvQ29ubmVjdGVkbmVzc0FwcHJvYWNoIikNCn0NCmxpYnJhcnkoQ29ubmVjdGVkbmVzc0FwcHJvYWNoKQ0KDQojIENvbmZpZ3VyYWNpw7NuIGRlIHBhcsOhbWV0cm9zIHBhcmEgVFZQVkFSDQpubGFnIDwtIDIgICAgICAgIyBPcmRlbiBkZWwgcmV6YWdvDQpsYW1iZGEgPC0gYygwLjk5LCAwLjk5KSAgIyBWYWxvcmVzIGRlIGRlY2FpbWllbnRvIHBhcmEgZWwgZmlsdHJvDQoNCiMgQ3JlYXIgbGEgbGlzdGEgZGUgY29uZmlndXJhY2nDs24gbmVjZXNhcmlhDQpjb25maWcgPC0gbGlzdChsID0gbGFtYmRhLCBubGFnID0gbmxhZykNCg0KIyBFc3RpbWFyIGVsIG1vZGVsbyBUVlAtVkFSIGNvbiBsb3MgcGFyw6FtZXRyb3MgZXNwZWNpZmljYWRvcw0KdHZwdmFyX21vZGVsIDwtIFRWUFZBUihkYXRhX3pvbywgY29uZmlndXJhdGlvbiA9IGNvbmZpZykNCmBgYA0KDQojIyBUYWJsZSAyOiBBdmVyYWdlZCBDb25uZWN0ZWRuZXNzIFRhYmxlDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KcGFydGl0aW9uID0gYyhwaSswLjAwMDAxLCBwaS81LCAwKQ0KZGNhID0gQ29ubmVjdGVkbmVzc0FwcHJvYWNoKGRhdGFfem9vLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb2RlbD0iVFZQLVZBUiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29ubmVjdGVkbmVzcz0iRnJlcXVlbmN5IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBubGFnPTEsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgbmZvcmU9MTAwLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpbmRvdy5zaXplPTIwMCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBWQVJfY29uZmlnPWxpc3QoVFZQVkFSPWxpc3Qoa2FwcGExPTAuOTksIGthcHBhMj0wLjk5LCBwcmlvcj0iQmF5ZXNQcmlvciIpKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb25uZWN0ZWRuZXNzX2NvbmZpZyA9IGxpc3QoDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGcmVxdWVuY3lDb25uZWN0ZWRuZXNzPWxpc3QocGFydGl0aW9uPXBhcnRpdGlvbiwgZ2VuZXJhbGl6ZWQ9VFJVRSwgc2NlbmFyaW89IkFCUyIpDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgKSkNCmBgYA0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0Ka2FibGUoZGNhJFRBQkxFKQ0KYGBgDQoNCiMjIEZpZ3VyZSA0OiBOZXQgVG90YWwgRGlyZWN0aW9uYWwgQ29ubmVjdGVkbmVzcw0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NClBsb3RORVQoZGNhLCB5bGltPWMoLTYwLDYwKSkNCmBgYA0KDQoNCg0KIyAqKkdhYmF1ZXIgYW5kIEd1cHRhICgyMDE4KTogKiogT24gdGhlIHRyYW5zbWlzc2lvbiBtZWNoYW5pc20gb2YgY291bnRyeS1zcGVjaWZpYyBhbmQgaW50ZXJuYXRpb25hbCBlY29ub21pYyB1bmNlcnRhaW50eSBzcGlsbG92ZXJzOiBFdmlkZW5jZSBmcm9tIGEgVFZQLVZBUiBjb25uZWN0ZWRuZXNzIGRlY29tcG9zaXRpb24gYXBwcm9hY2gNCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmRhdGFfem9vMiA8LSB6b28oZGF0YV9zZWxlY3RlZFssIGMoIkFJX0lOREVYIiwgIkZpbnRlY2hfSW5kZXgiLCAiQmxvY2tjaGFpbl9JbmRleCIpXSwgDQogICAgICAgICAgICAgICAgIG9yZGVyLmJ5ID0gZGF0YV9zZWxlY3RlZCREYXRlKQ0KDQojIENvbmZpZ3VyYWNpw7NuIGRlIHBhcsOhbWV0cm9zIHBhcmEgVFZQVkFSDQpubGFnIDwtIDIgICAgICAgIyBPcmRlbiBkZWwgcmV6YWdvDQpsYW1iZGEgPC0gYygwLjk5LCAwLjk5KSAgIyBWYWxvcmVzIGRlIGRlY2FpbWllbnRvIHBhcmEgZWwgZmlsdHJvDQoNCiMgQ3JlYXIgbGEgbGlzdGEgZGUgY29uZmlndXJhY2nDs24gbmVjZXNhcmlhDQpjb25maWcgPC0gbGlzdChsID0gbGFtYmRhLCBubGFnID0gbmxhZykNCg0KIyBFc3RpbWFyIGVsIG1vZGVsbyBUVlAtVkFSIGNvbiBsb3MgcGFyw6FtZXRyb3MgZXNwZWNpZmljYWRvcw0KdHZwdmFyX21vZGVsIDwtIFRWUFZBUihkYXRhX3pvbzIsIGNvbmZpZ3VyYXRpb24gPSBjb25maWcpDQpgYGANCg0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmRjYSA9IENvbm5lY3RlZG5lc3NBcHByb2FjaChkYXRhX3pvbzIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5sYWc9MSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZm9yZT0xMCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb2RlbD0iVFZQLVZBUiIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgY29ubmVjdGVkbmVzcz0iVGltZSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgd2luZG93LnNpemU9MjAwLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZBUl9jb25maWc9bGlzdChUVlBWQVI9bGlzdChrYXBwYTE9MC45OSwga2FwcGEyPTAuOTksIHByaW9yPSJCYXllc1ByaW9yIikpKQ0KYGBgDQoNCiMjIFRhYmxlIDE6IENvbm5lY3RlZG5lc3MgdGFibGUNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQprYWJsZShkY2EkVEFCTEUpDQojIENPTk5FQ1RFRE5FU1MgREVDT01QT1NJVElPTg0KaW50ID0gSW50ZXJuYWxDb25uZWN0ZWRuZXNzKGRjYSwgZ3JvdXBzPWxpc3QoIkdyb3VwMSI9YygxKSwgIkdyb3VwMiI9YygyKSwgIkdyb3VwMyI9YygzKSkpDQpleHQgPSBFeHRlcm5hbENvbm5lY3RlZG5lc3MoZGNhLCBncm91cHM9bGlzdCgiR3JvdXAxIj1jKDEpLCAiR3JvdXAyIj1jKDIpLCAiR3JvdXAzIj1jKDMpKSkNCmthYmxlKGludCRUQUJMRSkNCmthYmxlKGV4dCRUQUJMRSkNCmBgYA0KDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQojRmlndXJlIDM6IER5bmFtaWMgdG90YWwgY29ubmVjdGVkbmVzcw0KUGxvdFRDSShkY2EsIGludCwgeWxpbT1jKDAsIDQwKSkNCg0KI0ZpZ3VyZSA0OiBOZXQgdG90YWwgZGlyZWN0aW9uYWwgY29ubmVjdGVkbmVzcw0KUGxvdE5FVChkY2EsIGludCwgeWxpbT1jKC0xMCwgMTApKQ0KDQojRmlndXJlIDU6IFRvdGFsIGRpcmVjdGlvbmFsIGNvbm5lY3RlZG5lc3MgRlJPTSBvdGhlcnMNClBsb3RGUk9NKGRjYSwgaW50LCB5bGltPWMoMCwgNjApKQ0KDQojRmlndXJlIDY6IFRvdGFsIGRpcmVjdGlvbmFsIGNvbm5lY3RlZG5lc3MgVE8gb3RoZXJzDQpQbG90VE8oZGNhLCBpbnQsIHlsaW09YygwLCA2MCkpDQoNCiNGaWd1cmUgNzogSW50ZXJuYWwgbmV0IHBhaXJ3aXNlIHRvdGFsIGRpcmVjdGlvbmFsIGNvbm5lY3RlZG5lc3MNClBsb3ROUERDKGRjYSwgaW50LCB5bGltPWMoLTUsIDUpKQ0KYGBgDQoNCiMgKipDb2NjYSwgR2FiYXVlciwgYW5kIFBvbWJlcmdlciAoMjAyNCk6KiogQ2xlYW4gZW5lcmd5IG1hcmtldCBjb25uZWN0ZWRuZXNzIGFuZCBpbnZlc3RtZW50IHN0cmF0ZWdpZXM6IE5ldyBldmlkZW5jZSBmcm9tIERDQy1HQVJDSCBSMiBkZWNvbXBvc2VkIGNvbm5lY3RlZG5lc3MgbWVhc3VyZXMNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQojIENvbnZpZXJ0ZSBsYSBjb2x1bW5hICdEYXRlJyBhIGZvcm1hdG8gRGF0ZQ0KZGF0ZSA8LSBhcy5EYXRlKGRhdGFfc2VsZWN0ZWQkRGF0ZSwgZm9ybWF0PSIlZC8lbS8lWSIpDQoNCiMgQ3JlYSBsYSBzZXJpZSBkZSB0aWVtcG8gKHpvbykgc29sbyBjb24gbGFzIGNvbHVtbmFzIHNlbGVjY2lvbmFkYXMNClkgPC0gem9vKGRhdGFfc2VsZWN0ZWRbLCBjKCJGaW50ZWNoX0luZGV4IiwgIkFJX0lOREVYIiwgIkJsb2NrY2hhaW5fSW5kZXgiKV0sIG9yZGVyLmJ5ID0gZGF0ZSkNCg0KIyBBc2Vnw7pyYXRlIGRlIHF1ZSBsb3MgZGF0b3Mgc2VhbiBudW3DqXJpY29zIHkgZWxpbWluYSB2YWxvcmVzIE5BDQpZIDwtIG5hLm9taXQoem9vKGRhdGEuZnJhbWUoDQogIEZpbnRlY2hfSW5kZXhfZGlmZiA9IGFzLm51bWVyaWMoZGF0YV9zZWxlY3RlZCRGaW50ZWNoX0luZGV4KSwNCiAgQUlfSU5ERVhfZGlmZiA9IGFzLm51bWVyaWMoZGF0YV9zZWxlY3RlZCRBSV9JTkRFWCksDQogIEJsb2NrY2hhaW5fSW5kZXhfZGlmZiA9IGFzLm51bWVyaWMoZGF0YV9zZWxlY3RlZCRCbG9ja2NoYWluX0luZGV4KQ0KKSwgb3JkZXIuYnkgPSBkYXRlKSkNCg0KIyBSZWVtcGxhemEgbG9zIHZhbG9yZXMgTkEgcmVzdGFudGVzIHBvciAwDQpZW2lzLm5hKFkpXSA8LSAwDQoNCiMgRXN0YWJsZWNlICdkaW1uYW1lcycgZGUgWSBjb24gbsO6bWVyb3MgY29tbyDDrW5kaWNlcyAoY29tbyBlbiBZMikgc2luIGNhbWJpYXIgZWwgw61uZGljZSBkZSBmZWNoYQ0KZGltbmFtZXMoWSkgPC0gbGlzdChhcy5jaGFyYWN0ZXIoMTpucm93KFkpKSwgY29sbmFtZXMoWSkpDQoNCk5BTUVTID0gY29sbmFtZXMoWSkNCmsgPSBuY29sKFkpDQp0ID0gbnJvdyhZKQ0KDQojIFZlcmlmaWNhIGxhIGVzdHJ1Y3R1cmEgZGUgWQ0Kc3RyKFkpDQoNCmBgYA0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0Ka2FibGUoU3VtbWFyeVN0YXRpc3RpY3MoWSwgbmxhZz0yMCkpDQpgYGANCg0KIyMgRmlndXJlIDA6IFBlcmNlbnRhZ2UgY2hhbmdlcw0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCnBhcihtZmNvbCA9IGMoY2VpbGluZyhrLzIpLDIpLCBvbWEgPSBjKDAsIDEsIDAsIDApICsgMC41LCBtYXIgPSBjKDEsIDEsIDEsIDEpICsgMC41LCBtZ3AgPSBjKDEsIDAuNCwgMCkpDQpmb3IgKGkgaW4gMTprKSB7DQogIHBsb3QoZGF0ZSxZWyxpXSx0eXBlPSdsJyxsYXM9MSx4YXhzPSdpJyx5YXhzPSdpJyx5bGltPWMoLTAuMSwwLjEpLHhsYWI9JycseWxhYj0nJyxtYWluPXBhc3RlKE5BTUVTW2ldKSx0Y2s9LS4wMixjb2w9J3N0ZWVsYmx1ZTQnKQ0KICBncmlkKE5BLE5VTEwpDQogIGxpbmVzKGRhdGUsWVssaV0sY29sPSdzdGVlbGJsdWU0JykNCiAgYWJsaW5lKGg9MCxsdHk9MykNCiAgYm94KCkNCn0NCmBgYA0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0Kc3BlYyA8LSBsaXN0KCkNCg0KIyBJdGVyYSBzb2JyZSBjYWRhIGNvbHVtbmEgZGUgWQ0KZm9yIChpIGluIDE6aykgew0KICAjIEludGVudGEgc2VsZWNjaW9uYXIgZWwgbWVqb3IgbW9kZWxvIEdBUkNIIHBhcmEgY2FkYSBzZXJpZQ0KICB1IDwtIHRyeUNhdGNoKHsNCiAgICBHQVJDSHNlbGVjdGlvbihZWywgaV0sDQogICAgICAgICAgICAgICAgICAgZGlzdHJpYnV0aW9ucyA9IGMoIm5vcm0iLCAic3RkIiwgInNzdGQiLCAiZ2VkIiwgInNnZWQiKSwNCiAgICAgICAgICAgICAgICAgICBtb2RlbHMgPSBjKCJzR0FSQ0giLCAiZ2pyR0FSQ0giLCAiZUdBUkNIIiwgImlHQVJDSCIsICJBVkdBUkNIIiwgIlRHQVJDSCIpKQ0KICB9LCBlcnJvciA9IGZ1bmN0aW9uKGUpIHsNCiAgICB3YXJuaW5nKHBhc3RlKCJFcnJvciBhbCBzZWxlY2Npb25hciBtb2RlbG8gR0FSQ0ggcGFyYSBsYSB2YXJpYWJsZSIsIGksICI6IiwgZSRtZXNzYWdlKSkNCiAgICBOVUxMDQogIH0pDQogIA0KICAjIFNpICd1JyBubyBlcyBOVUxMIHkgdGllbmUgdW4gbWVqb3IgbW9kZWxvLCBhZ3JlZ2EgYSAnc3BlYycNCiAgaWYgKCFpcy5udWxsKHUpICYmICFpcy5udWxsKHUkYmVzdF91Z2FyY2gpKSB7DQogICAgc3BlY1tbaV1dIDwtIHUkYmVzdF91Z2FyY2gNCiAgfSBlbHNlIHsNCiAgICAjIFNpIG5vIHNlIHNlbGVjY2lvbsOzIHVuIG1vZGVsbywgYXNpZ25hIHVuIG1vZGVsbyBHQVJDSCgxLDEpIHBvciBkZWZlY3RvDQogICAgd2FybmluZyhwYXN0ZSgiTm8gc2Ugc2VsZWNjaW9uw7MgbmluZ8O6biBtb2RlbG8gR0FSQ0ggcGFyYSIsIE5BTUVTW2ldLCAiLiBVc2FuZG8gbW9kZWxvIEdBUkNIKDEsMSkgY29uIGRpc3RyaWJ1Y2nDs24gbm9ybWFsIikpDQogICAgc3BlY1tbaV1dIDwtIHVnYXJjaHNwZWModmFyaWFuY2UubW9kZWwgPSBsaXN0KG1vZGVsID0gInNHQVJDSCIsIGdhcmNoT3JkZXIgPSBjKDEsIDEpKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZWFuLm1vZGVsID0gbGlzdChhcm1hT3JkZXIgPSBjKDAsIDApKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaXN0cmlidXRpb24ubW9kZWwgPSAibm9ybSIpDQogIH0NCn0NCg0KIyBWZXJpZmljYSBxdWUgJ3NwZWMnIHRlbmdhIG1vZGVsb3MgcGFyYSBjYWRhIHNlcmllIGVuIFkNCmlmIChsZW5ndGgoc3BlYykgIT0gaykgew0KICBzdG9wKCJzcGVjIG5vIGNvbnRpZW5lIG1vZGVsb3MgdsOhbGlkb3MgcGFyYSB0b2RhcyBsYXMgc2VyaWVzIGRlIFkiKQ0KfQ0KDQojIEVqZWN1dGEgZWwgbW9kZWxvIERDQy1HQVJDSCBzaSBzcGVjIGVzIHbDoWxpZGENCmZpdCA8LSBCaXZhcmlhdGVEQ0NHQVJDSChZLCBzcGVjKQ0KYGBgDQoNCiMjIFRhYmxlIDQ6IEV2YWx1YXRpb24gb2YgdW5pdmFyaWF0ZSBHQVJDSCBwZXJmb3JtYW5jZQ0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCkggPSBmaXQkSF90DQpSID0gZml0JFJfdA0KDQp1R0FSQ0hfdGFibGUgPSBOVUxMDQpmb3IgKGkgaW4gMTprKSB7DQogIGZpdCA9IHVnYXJjaGZpdChzcGVjW1tpXV0sIFlbLGldKQ0KICBndCA9IEdBUkNIdGVzdHMoZml0LCBsYWc9MjApDQogIHVHQVJDSF90YWJsZSA9IHJiaW5kKHVHQVJDSF90YWJsZSwgZ3QkVEFCTEUpDQp9DQoNCmthYmxlKHVHQVJDSF90YWJsZSkNCmBgYA0KDQoNCiMjIEZpZ3VyZSAzOiBEeW5hbWljIGNvbmRpdGlvbmFsIGNvcnJlbGF0aW9ucw0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCnBhcihtZmNvbCA9IGMoY2VpbGluZyhrLzIpLDIpLCBvbWEgPSBjKDAsIDEsIDAsIDApICsgMC41LCBtYXIgPSBjKDEsIDEsIDEsIDEpICsgMC41LCBtZ3AgPSBjKDEsIDAuNCwgMCkpDQpmb3IgKGogaW4gMTprKSB7DQogIHBsb3QoZGF0ZSxSW2osaixdLHR5cGU9J2wnLGxhcz0xLHhheHM9J2knLHlheHM9J2knLHhsYWI9JycseWxhYj0nJyxtYWluPXBhc3RlKE5BTUVTW2pdKSx0Y2s9LS4wMixjb2w9aix5bGltPWMoLTEuMSwxLjEpKQ0KICBncmlkKE5BLE5VTEwpDQogIGZvciAoaSBpbiAxOmspIHsNCiAgICBsaW5lcyhkYXRlLFJbaixpLF0sY29sPWkpDQogICAgYWJsaW5lKGg9MCxsdHk9MykNCiAgICBib3goKQ0KICB9DQogIGxlZ2VuZCgiYm90dG9tIixOQU1FU1stal0sZmlsbD1jKDE6aylbLWpdLGJ0eT0ibiIsY2V4PTAuNzUsbmNvbD1rKQ0KfQ0KYGBgDQoNCg0KIyMgVGFibGUgNTogQXZlcmFnZWQgY29ubmVjdGVkbmVzcyBtZWFzdXJlcw0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmRjYSA9IFIyQ29ycmVsYXRpb25zKFIpDQprYWJsZShkY2EkVEFCTEUpDQpgYGANCg0KIyMgRmlndXJlIDQ6IER5bmFtaWMgY29uZGl0aW9uYWwgUjIgZGVjb21wb3NlZCBtZWFzdXJlcw0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCnIyYyA9IGFwcGx5KGRjYSRDVCxjKDEsMyksc3VtKS0xDQpwYXIobWZjb2wgPSBjKGNlaWxpbmcoay8yKSwyKSwgb21hID0gYygwLCAxLCAwLCAwKSArIDAuNSwgbWFyID0gYygxLCAxLCAxLCAxKSArIDAuNSwgbWdwID0gYygxLCAwLjQsIDApKQ0KZm9yIChqIGluIDE6aykgew0KICByMmRkID0gbWF0cml4KDAsbmNvbD1rLG5yb3c9dCkNCiAgZm9yIChpIGluIDE6dCkgew0KICAgIGRlZCA9IHJlcCgwLGspDQogICAgZGVkW2pdID0gMQ0KICAgIHIyZGRbaSxdID0gY3Vtc3VtKGRjYSRDVFtqLCxpXS1kZWQpDQogIH0NCiAgcGxvdChkYXRlLDEwMCpyMmNbaixdKk5BLHR5cGU9ImwiLGxhcz0xLHhsYWI9IiIseWxhYj0iIix5bGltPWMoMCwxMDApLHhheHM9ImkiLHRjaz0tMC4wMSx5YXhzPSJpIixtYWluPU5BTUVTW2pdKQ0KICBncmlkKE5BLE5VTEwpDQogIGZvciAoaSBpbiBrOjEpIHsNCiAgICBwb2x5Z29uKGMoZGF0ZSwgcmV2KGRhdGUpKSwgYyhjKHJlcCgwLCB0KSksIHJldigxMDAqcjJkZFssaV0pKSwgY29sPWksIGJvcmRlcj1pKQ0KICB9DQogIGJveCgpDQogIGxlZ2VuZCgidG9wbGVmdCIsTkFNRVNbLWpdLGZpbGw9YygxOmspWy1qXSxidHk9Im4iLGNleD0wLjc1LG5jb2w9MSkNCn0NCmBgYA0KDQojIyBGaWd1cmUgNTogRHluYW1pYyB0b3RhbCBjb25uZWN0ZWRuZXNzDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KcGFyKG1mY29sID0gYygxLDEpLCBvbWEgPSBjKDAsIDEsIDAsIDApICsgMC41LCBtYXIgPSBjKDEsIDEsIDEsIDEpICsgMC41LCBtZ3AgPSBjKDEsIDAuNCwgMCkpDQpwbG90KGRhdGUsZGNhJFRDSSpOQSx0eXBlPSdsJyxsYXM9MSx4YXhzPSdpJyx5YXhzPSdpJyx4bGFiPScnLHlsYWI9JycsbWFpbj0nJyx0Y2s9LS4wMSwgeWxpbT1jKDAsMTEwKSkjYyhtYXgoYygwLG1pbihUQ0kpLTEwKSksbWF4KFRDSSkrMTApKQ0KZ3JpZChOQSxOVUxMKQ0KcG9seWdvbihjKGRhdGUsIHJldihkYXRlKSksIGMoYyhyZXAoMCwgdCkpLCByZXYoZGNhJFRDSSkpLCBjb2w9MSwgYm9yZGVyPTEpDQpib3goKQ0KYGBgDQoNCiMjIEZpZ3VyZSA2OiBOZXQgdG90YWwgZGlyZWN0aW9uYWwgY29ubmVjdGVkbmVzcw0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCnBhcihtZmNvbCA9IGMoY2VpbGluZyhrLzIpLDIpLCBvbWEgPSBjKDAsIDAsIDAsIDApICsgMC41LCBtYXIgPSBjKDEsIDEsIDEsIDEpICsgMC41LCBtZ3AgPSBjKDEsIDAuNCwgMCkpDQpmb3IgKGkgaW4gMTprKSB7DQogIHBsb3QoZGF0ZSxkY2EkTkVUWyxpXSpOQSx0eXBlPSdsJyxsYXM9MSx4YXhzPSdpJyx5YXhzPSdpJyx5bGltPWMoLTIwLDIwKSx4bGFiPScnLHlsYWI9JycsbWFpbj1wYXN0ZSgiTkVUIixOQU1FU1tpXSksdGNrPS0uMDI1KQ0KICBncmlkKE5BLE5VTEwpDQogIHBvbHlnb24oYyhkYXRlLCByZXYoZGF0ZSkpLCBjKGMocmVwKDAsIHQpKSwgcmV2KGRjYSRORVRbLGldKSksIGNvbD0xLCBib3JkZXI9MSkNCiAgYWJsaW5lKGg9MCxsdHk9MykNCiAgYm94KCkNCn0NCmBgYA0KDQoNCiMjIFRhYmxlIDc6IEhlZGdlIHJhdGlvcw0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCm1ldGhvZCA9ICJjdW1zdW0iDQpzdGF0aXN0aWNzID0gIkZpc2hlciINCm1ldHJpYyA9ICJTdGREZXYiDQpociA9IEhlZGdlUmF0aW8oWS8xMDAsIEgsIHN0YXRpc3RpY3M9c3RhdGlzdGljcywgbWV0aG9kPW1ldGhvZCwgbWV0cmljPW1ldHJpYywgZGlnaXQ9MykNCmthYmxlKGhyJFRBQkxFKQ0KYGBgDQoNCiMjIFRhYmxlIDg6IE11bHRpdmFyaWF0ZSBoZWRnaW5nIHBvcnRmb2xpb3MNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQptaHAgPSBNdWx0aXZhcmlhdGVIZWRnaW5nUG9ydGZvbGlvKFkvMTAwLCBILCBzdGF0aXN0aWNzPXN0YXRpc3RpY3MsIG1ldGhvZD1tZXRob2QsIGRpZ2l0PTMpDQprYWJsZShtaHAkVEFCTEUpDQpgYGANCg0KIyMgRmlndXJlIDM6IER5bmFtaWMgY29uZGl0aW9uYWwgYmV0YXMNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpwYXIobWZjb2wgPSBjKGNlaWxpbmcoay8yKSwyKSwgb21hID0gYygwLCAxLCAwLCAwKSArIDAuNSwgbWFyID0gYygxLCAxLCAxLCAxKSArIDAuNSwgbWdwID0gYygxLCAwLjQsIDApKQ0KZm9yIChqIGluIDE6aykgew0KICBwbG90KGRhdGUsbWhwJEJldGFbaixqLF0qTkEsdHlwZT0nbCcsbGFzPTEseGF4cz0naScseWF4cz0naScseGxhYj0nJyx5bGFiPScnLA0KICAgICAgIG1haW49cGFzdGUoTkFNRVNbal0pLHRjaz0tLjAyLGNvbD1qLHlsaW09YygtMC41LDcwKSkNCiAgZ3JpZChOQSxOVUxMKQ0KICBjb2VmcyA9IGxtKFlbLGpdfllbLC1qXSkkY29lZmZpY2llbnRzWy0xXQ0KICBmb3IgKGkgaW4gMTprKSB7DQogICAgaWYgKGkhPWopIHsNCiAgICAgIGxpbmVzKGRhdGUsbWhwJEJldGFbaixpLF0sY29sPWkpDQogICAgICBhYmxpbmUoaD0wLGx0eT0zKQ0KICAgICAgYm94KCkNCiAgICB9DQogIH0NCiAgY29sID0gMTprDQogIGNvbCA9IGNvbFstal0NCiAgYWJsaW5lKGg9Y29lZnMsbHR5PTMsY29sPWNvbCkNCiAgbGVnZW5kKCJib3R0b20iLE5BTUVTWy1qXSxmaWxsPWMoMTprKVstal0sYnR5PSJuIixjZXg9MC42LG5jb2w9aykNCn0NCmBgYA0KDQojIyBUYWJsZSA5OiBPcHRpbWFsIGJpdmFyaWF0ZSBwb3J0Zm9saW8gd2VpZ2h0cw0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmJwdyA9IEJpdmFyaWF0ZVBvcnRmb2xpbyhZLzEwMCwgSCwgc3RhdGlzdGljcz1zdGF0aXN0aWNzLCBtZXRob2Q9bWV0aG9kLCBtZXRyaWM9bWV0cmljLCBkaWdpdD0zKQ0KIyMgVGhlIG9wdGltYWwgYml2YXJpYXRlIHBvcnRmb2xpb3MgYXJlIGNvbXB1dGVkIGFjY29yZGluZyB0bzoNCiMjICBLcm9uZXIsIEsuIEYuLCAmIE5nLCBWLiBLLiAoMTk5OCkuIE1vZGVsaW5nIGFzeW1tZXRyaWMgY29tb3ZlbWVudHMgb2YgYXNzZXQgcmV0dXJucy4gVGhlIFJldmlldyBvZiBGaW5hbmNpYWwgU3R1ZGllcywgMTEoNCksIDgxNy04NDQuDQojIyANCiMjICAgICAgICAgICBIZWRnaW5nIGVmZmVjdGl2ZW5lc3MgaXMgY2FsY3VsYXRlZCBhY2NvcmRpbmcgdG86DQojIyAgRWRlcmluZ3RvbiwgTC4gSC4gKDE5NzkpLiBUaGUgaGVkZ2luZyBwZXJmb3JtYW5jZSBvZiB0aGUgbmV3IGZ1dHVyZXMgbWFya2V0cy4gVGhlIEpvdXJuYWwgb2YgRmluYW5jZSwgMzQoMSksIDE1Ny0xNzAuDQojIyANCiMjICAgICAgICAgICBTdGF0aXN0aWNzIG9mIHRoZSBoZWRnaW5nIGVmZmVjdGl2ZW5lc3MgbWVhc3VyZSBhcmUgaW1wbGVtZW50ZWQgYWNjb3JkaW5nIHRvOg0KIyMgIEFudG9uYWtha2lzLCBOLiwgQ3VuYWRvLCBKLiwgRmlsaXMsIEcuLCBHYWJhdWVyLCBELiwgJiBkZSBHcmFjaWEsIEYuIFAuICgyMDIwKS4gT2lsIGFuZCBhc3NldCBjbGFzc2VzIGltcGxpZWQgdm9sYXRpbGl0aWVzOiBJbnZlc3RtZW50IHN0cmF0ZWdpZXMgYW5kIGhlZGdpbmcgZWZmZWN0aXZlbmVzcy4gRW5lcmd5IEVjb25vbWljcywgOTEsIDEwNDc2Mi4NCmthYmxlKGJwdyRUQUJMRSkNCmBgYA0KDQojIyBUYWJsZSAxMDogTXVsdGl2YXJpYXRlIHBvcnRmb2xpbyBhbmFseXNpcw0KYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NClBDSWMgPSBkY2EkUENJDQpQQ0lnID0gZGNhJENUDQpmb3IgKGwgaW4gMTpkaW0oZGNhJENUKVszXSkgew0KICBmb3IgKGkgaW4gMTprKSB7DQogICAgZm9yIChqIGluIDE6aykgew0KICAgICAgUENJZ1tpLGosbF0gPSAoMipSW2ksaixsXV4yKS8oMStSW2ksaixsXV4yKQ0KICAgIH0NCiAgfQ0KfQ0KbXZwID0gTWluaW11bUNvbm5lY3RlZG5lc3NQb3J0Zm9saW8oWS8xMDAsIEgsIHN0YXRpc3RpY3M9c3RhdGlzdGljcywgbWV0aG9kPW1ldGhvZCwgbWV0cmljPW1ldHJpYywgZGlnaXQ9MykNCiMjIFRoZSBtaW5pbXVtIGNvbm5lY3RlZG5lc3MgcG9ydGZvbGlvIGlzIGltcGxlbWVudGVkIGFjY29yZGluZyB0bzoNCiMjICBCcm9hZHN0b2NrLCBELiBDLiwgQ2hhdHppYW50b25pb3UsIEkuLCAmIEdhYmF1ZXIsIEQuICgyMDIyKS4gTWluaW11bSBjb25uZWN0ZWRuZXNzIHBvcnRmb2xpb3MgYW5kIHRoZSBtYXJrZXQgZm9yIGdyZWVuIGJvbmRzOiBBZHZvY2F0aW5nIHNvY2lhbGx5IHJlc3BvbnNpYmxlIGludmVzdG1lbnQgKFNSSSkgYWN0aXZpdHkuIEluIEFwcGxpY2F0aW9ucyBpbiBFbmVyZ3kgRmluYW5jZSAocHAuIDIxNy0yNTMpLiBQYWxncmF2ZSBNYWNtaWxsYW4sIENoYW0uDQojIyANCiMjICAgICAgICAgICBIZWRnaW5nIGVmZmVjdGl2ZW5lc3MgaXMgY2FsY3VsYXRlZCBhY2NvcmRpbmcgdG86DQojIyAgRWRlcmluZ3RvbiwgTC4gSC4gKDE5NzkpLiBUaGUgaGVkZ2luZyBwZXJmb3JtYW5jZSBvZiB0aGUgbmV3IGZ1dHVyZXMgbWFya2V0cy4gVGhlIEpvdXJuYWwgb2YgRmluYW5jZSwgMzQoMSksIDE1Ny0xNzAuDQojIyANCiMjICAgICAgICAgICBTdGF0aXN0aWNzIG9mIHRoZSBoZWRnaW5nIGVmZmVjdGl2ZW5lc3MgbWVhc3VyZSBhcmUgaW1wbGVtZW50ZWQgYWNjb3JkaW5nIHRvOg0KIyMgIEFudG9uYWtha2lzLCBOLiwgQ3VuYWRvLCBKLiwgRmlsaXMsIEcuLCBHYWJhdWVyLCBELiwgJiBkZSBHcmFjaWEsIEYuIFAuICgyMDIwKS4gT2lsIGFuZCBhc3NldCBjbGFzc2VzIGltcGxpZWQgdm9sYXRpbGl0aWVzOiBJbnZlc3RtZW50IHN0cmF0ZWdpZXMgYW5kIGhlZGdpbmcgZWZmZWN0aXZlbmVzcy4gRW5lcmd5IEVjb25vbWljcywgOTEsIDEwNDc2Mi4NCm1jcCA9IE1pbmltdW1Db25uZWN0ZWRuZXNzUG9ydGZvbGlvKFkvMTAwLCBSLCBzdGF0aXN0aWNzPXN0YXRpc3RpY3MsIG1ldGhvZD1tZXRob2QsIG1ldHJpYz1tZXRyaWMsIGRpZ2l0PTMpDQojIyBUaGUgbWluaW11bSBjb25uZWN0ZWRuZXNzIHBvcnRmb2xpbyBpcyBpbXBsZW1lbnRlZCBhY2NvcmRpbmcgdG86DQojIyAgQnJvYWRzdG9jaywgRC4gQy4sIENoYXR6aWFudG9uaW91LCBJLiwgJiBHYWJhdWVyLCBELiAoMjAyMikuIE1pbmltdW0gY29ubmVjdGVkbmVzcyBwb3J0Zm9saW9zIGFuZCB0aGUgbWFya2V0IGZvciBncmVlbiBib25kczogQWR2b2NhdGluZyBzb2NpYWxseSByZXNwb25zaWJsZSBpbnZlc3RtZW50IChTUkkpIGFjdGl2aXR5LiBJbiBBcHBsaWNhdGlvbnMgaW4gRW5lcmd5IEZpbmFuY2UgKHBwLiAyMTctMjUzKS4gUGFsZ3JhdmUgTWFjbWlsbGFuLCBDaGFtLg0KIyMgDQojIyAgICAgICAgICAgSGVkZ2luZyBlZmZlY3RpdmVuZXNzIGlzIGNhbGN1bGF0ZWQgYWNjb3JkaW5nIHRvOg0KIyMgIEVkZXJpbmd0b24sIEwuIEguICgxOTc5KS4gVGhlIGhlZGdpbmcgcGVyZm9ybWFuY2Ugb2YgdGhlIG5ldyBmdXR1cmVzIG1hcmtldHMuIFRoZSBKb3VybmFsIG9mIEZpbmFuY2UsIDM0KDEpLCAxNTctMTcwLg0KIyMgDQojIyAgICAgICAgICAgU3RhdGlzdGljcyBvZiB0aGUgaGVkZ2luZyBlZmZlY3RpdmVuZXNzIG1lYXN1cmUgYXJlIGltcGxlbWVudGVkIGFjY29yZGluZyB0bzoNCiMjICBBbnRvbmFrYWtpcywgTi4sIEN1bmFkbywgSi4sIEZpbGlzLCBHLiwgR2FiYXVlciwgRC4sICYgZGUgR3JhY2lhLCBGLiBQLiAoMjAyMCkuIE9pbCBhbmQgYXNzZXQgY2xhc3NlcyBpbXBsaWVkIHZvbGF0aWxpdGllczogSW52ZXN0bWVudCBzdHJhdGVnaWVzIGFuZCBoZWRnaW5nIGVmZmVjdGl2ZW5lc3MuIEVuZXJneSBFY29ub21pY3MsIDkxLCAxMDQ3NjIuDQptcGMgPSBNaW5pbXVtQ29ubmVjdGVkbmVzc1BvcnRmb2xpbyhZLzEwMCwgUENJYywgc3RhdGlzdGljcz1zdGF0aXN0aWNzLCBtZXRob2Q9bWV0aG9kLCBtZXRyaWM9bWV0cmljLCBkaWdpdD0zKQ0KIyMgVGhlIG1pbmltdW0gY29ubmVjdGVkbmVzcyBwb3J0Zm9saW8gaXMgaW1wbGVtZW50ZWQgYWNjb3JkaW5nIHRvOg0KIyMgIEJyb2Fkc3RvY2ssIEQuIEMuLCBDaGF0emlhbnRvbmlvdSwgSS4sICYgR2FiYXVlciwgRC4gKDIwMjIpLiBNaW5pbXVtIGNvbm5lY3RlZG5lc3MgcG9ydGZvbGlvcyBhbmQgdGhlIG1hcmtldCBmb3IgZ3JlZW4gYm9uZHM6IEFkdm9jYXRpbmcgc29jaWFsbHkgcmVzcG9uc2libGUgaW52ZXN0bWVudCAoU1JJKSBhY3Rpdml0eS4gSW4gQXBwbGljYXRpb25zIGluIEVuZXJneSBGaW5hbmNlIChwcC4gMjE3LTI1MykuIFBhbGdyYXZlIE1hY21pbGxhbiwgQ2hhbS4NCiMjIA0KIyMgICAgICAgICAgIEhlZGdpbmcgZWZmZWN0aXZlbmVzcyBpcyBjYWxjdWxhdGVkIGFjY29yZGluZyB0bzoNCiMjICBFZGVyaW5ndG9uLCBMLiBILiAoMTk3OSkuIFRoZSBoZWRnaW5nIHBlcmZvcm1hbmNlIG9mIHRoZSBuZXcgZnV0dXJlcyBtYXJrZXRzLiBUaGUgSm91cm5hbCBvZiBGaW5hbmNlLCAzNCgxKSwgMTU3LTE3MC4NCiMjIA0KIyMgICAgICAgICAgIFN0YXRpc3RpY3Mgb2YgdGhlIGhlZGdpbmcgZWZmZWN0aXZlbmVzcyBtZWFzdXJlIGFyZSBpbXBsZW1lbnRlZCBhY2NvcmRpbmcgdG86DQojIyAgQW50b25ha2FraXMsIE4uLCBDdW5hZG8sIEouLCBGaWxpcywgRy4sIEdhYmF1ZXIsIEQuLCAmIGRlIEdyYWNpYSwgRi4gUC4gKDIwMjApLiBPaWwgYW5kIGFzc2V0IGNsYXNzZXMgaW1wbGllZCB2b2xhdGlsaXRpZXM6IEludmVzdG1lbnQgc3RyYXRlZ2llcyBhbmQgaGVkZ2luZyBlZmZlY3RpdmVuZXNzLiBFbmVyZ3kgRWNvbm9taWNzLCA5MSwgMTA0NzYyLg0KbXBnID0gTWluaW11bUNvbm5lY3RlZG5lc3NQb3J0Zm9saW8oWS8xMDAsIFBDSWcsIHN0YXRpc3RpY3M9c3RhdGlzdGljcywgbWV0aG9kPW1ldGhvZCwgbWV0cmljPW1ldHJpYywgZGlnaXQ9MykNCiMjIFRoZSBtaW5pbXVtIGNvbm5lY3RlZG5lc3MgcG9ydGZvbGlvIGlzIGltcGxlbWVudGVkIGFjY29yZGluZyB0bzoNCiMjICBCcm9hZHN0b2NrLCBELiBDLiwgQ2hhdHppYW50b25pb3UsIEkuLCAmIEdhYmF1ZXIsIEQuICgyMDIyKS4gTWluaW11bSBjb25uZWN0ZWRuZXNzIHBvcnRmb2xpb3MgYW5kIHRoZSBtYXJrZXQgZm9yIGdyZWVuIGJvbmRzOiBBZHZvY2F0aW5nIHNvY2lhbGx5IHJlc3BvbnNpYmxlIGludmVzdG1lbnQgKFNSSSkgYWN0aXZpdHkuIEluIEFwcGxpY2F0aW9ucyBpbiBFbmVyZ3kgRmluYW5jZSAocHAuIDIxNy0yNTMpLiBQYWxncmF2ZSBNYWNtaWxsYW4sIENoYW0uDQojIyANCiMjICAgICAgICAgICBIZWRnaW5nIGVmZmVjdGl2ZW5lc3MgaXMgY2FsY3VsYXRlZCBhY2NvcmRpbmcgdG86DQojIyAgRWRlcmluZ3RvbiwgTC4gSC4gKDE5NzkpLiBUaGUgaGVkZ2luZyBwZXJmb3JtYW5jZSBvZiB0aGUgbmV3IGZ1dHVyZXMgbWFya2V0cy4gVGhlIEpvdXJuYWwgb2YgRmluYW5jZSwgMzQoMSksIDE1Ny0xNzAuDQojIyANCiMjICAgICAgICAgICBTdGF0aXN0aWNzIG9mIHRoZSBoZWRnaW5nIGVmZmVjdGl2ZW5lc3MgbWVhc3VyZSBhcmUgaW1wbGVtZW50ZWQgYWNjb3JkaW5nIHRvOg0KIyMgIEFudG9uYWtha2lzLCBOLiwgQ3VuYWRvLCBKLiwgRmlsaXMsIEcuLCBHYWJhdWVyLCBELiwgJiBkZSBHcmFjaWEsIEYuIFAuICgyMDIwKS4gT2lsIGFuZCBhc3NldCBjbGFzc2VzIGltcGxpZWQgdm9sYXRpbGl0aWVzOiBJbnZlc3RtZW50IHN0cmF0ZWdpZXMgYW5kIGhlZGdpbmcgZWZmZWN0aXZlbmVzcy4gRW5lcmd5IEVjb25vbWljcywgOTEsIDEwNDc2Mi4NCm1ycCA9IE1pbmltdW1Db25uZWN0ZWRuZXNzUG9ydGZvbGlvKFkvMTAwLCBkY2EkQ1QsIHN0YXRpc3RpY3M9c3RhdGlzdGljcywgbWV0aG9kPW1ldGhvZCwgbWV0cmljPW1ldHJpYywgZGlnaXQ9MykNCiMjIFRoZSBtaW5pbXVtIGNvbm5lY3RlZG5lc3MgcG9ydGZvbGlvIGlzIGltcGxlbWVudGVkIGFjY29yZGluZyB0bzoNCiMjICBCcm9hZHN0b2NrLCBELiBDLiwgQ2hhdHppYW50b25pb3UsIEkuLCAmIEdhYmF1ZXIsIEQuICgyMDIyKS4gTWluaW11bSBjb25uZWN0ZWRuZXNzIHBvcnRmb2xpb3MgYW5kIHRoZSBtYXJrZXQgZm9yIGdyZWVuIGJvbmRzOiBBZHZvY2F0aW5nIHNvY2lhbGx5IHJlc3BvbnNpYmxlIGludmVzdG1lbnQgKFNSSSkgYWN0aXZpdHkuIEluIEFwcGxpY2F0aW9ucyBpbiBFbmVyZ3kgRmluYW5jZSAocHAuIDIxNy0yNTMpLiBQYWxncmF2ZSBNYWNtaWxsYW4sIENoYW0uDQojIyANCiMjICAgICAgICAgICBIZWRnaW5nIGVmZmVjdGl2ZW5lc3MgaXMgY2FsY3VsYXRlZCBhY2NvcmRpbmcgdG86DQojIyAgRWRlcmluZ3RvbiwgTC4gSC4gKDE5NzkpLiBUaGUgaGVkZ2luZyBwZXJmb3JtYW5jZSBvZiB0aGUgbmV3IGZ1dHVyZXMgbWFya2V0cy4gVGhlIEpvdXJuYWwgb2YgRmluYW5jZSwgMzQoMSksIDE1Ny0xNzAuDQojIyANCiMjICAgICAgICAgICBTdGF0aXN0aWNzIG9mIHRoZSBoZWRnaW5nIGVmZmVjdGl2ZW5lc3MgbWVhc3VyZSBhcmUgaW1wbGVtZW50ZWQgYWNjb3JkaW5nIHRvOg0KIyMgIEFudG9uYWtha2lzLCBOLiwgQ3VuYWRvLCBKLiwgRmlsaXMsIEcuLCBHYWJhdWVyLCBELiwgJiBkZSBHcmFjaWEsIEYuIFAuICgyMDIwKS4gT2lsIGFuZCBhc3NldCBjbGFzc2VzIGltcGxpZWQgdm9sYXRpbGl0aWVzOiBJbnZlc3RtZW50IHN0cmF0ZWdpZXMgYW5kIGhlZGdpbmcgZWZmZWN0aXZlbmVzcy4gRW5lcmd5IEVjb25vbWljcywgOTEsIDEwNDc2Mi4NCk1WQSA9IHJiaW5kKG12cCRUQUJMRSwgbWNwJFRBQkxFLCBtcGMkVEFCTEUsIG1wZyRUQUJMRSwgbXJwJFRBQkxFKQ0Ka2FibGUoTVZBKQ0KYGBgDQoNCiMjIFRhYmxlIDExOiBQb3J0Zm9saW8gcGVyZm9ybWFuY2UNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpsaWJyYXJ5KFBlcmZvcm1hbmNlQW5hbHl0aWNzKQ0KbGlicmFyeSh4dHMpDQpwb3J0Lm1hdCA9IGRhdGEuZnJhbWUoDQogICAgICAgICAgICAgICAgICAgICBNVlA9bXZwJHBvcnRmb2xpb19yZXR1cm4sDQogICAgICAgICAgICAgICAgICAgICBNQ1A9bWNwJHBvcnRmb2xpb19yZXR1cm4sDQogICAgICAgICAgICAgICAgICAgICBNUEM9bXBjJHBvcnRmb2xpb19yZXR1cm4sDQogICAgICAgICAgICAgICAgICAgICBNUEc9bXBnJHBvcnRmb2xpb19yZXR1cm4sDQogICAgICAgICAgICAgICAgICAgICBNUlA9bXJwJHBvcnRmb2xpb19yZXR1cm4NCiAgICAgICAgICAgICAgICAgICAgICkNCnBvcnQueHRzID0geHRzKHBvcnQubWF0LCBvcmRlci5ieT1kYXRlKQ0KaXIgPSBtYXRyaXgoTkEsIG5yb3c9MSwgbmNvbD1uY29sKHBvcnQueHRzKSkNCmNvbG5hbWVzKGlyKSA9IGNvbG5hbWVzKHBvcnQueHRzKQ0Kcm93bmFtZXMoaXIpID0gIkdSRSINCmZvciAoaSBpbiAxOm5jb2wocG9ydC54dHMpKSB7DQogIGlyWyxpXSA9IEluZm9ybWF0aW9uUmF0aW8oUmE9cG9ydC54dHNbLGldLCBSYj1ZWywxXS8xMDApDQp9DQprID0gbmNvbChwb3J0Lnh0cykNCnRhYmxlID0gbWF0cml4KE5BLCBuY29sPWssIG5yb3c9NSkNCmZvciAoaSBpbiAxOmspIHsNCiAgdGFibGVbLGldID0gYygNCiAgIyBSZXRvcm5vIGFudWFsaXphZG8NCiAgUmV0dXJuLmFubnVhbGl6ZWQocG9ydC54dHNbLGldKSwNCiAgDQogICMgRGVzdmlhY2nDs24gZXN0w6FuZGFyIGFudWFsaXphZGENCiAgU3RkRGV2LmFubnVhbGl6ZWQocG9ydC54dHNbLGldKSwNCiAgDQogICMgUmF0aW8gZGUgU2hhcnBlIGFudWFsaXphZG8NCiAgU2hhcnBlUmF0aW8uYW5udWFsaXplZChwb3J0Lnh0c1ssaV0pLA0KICANCiAgIyBWYWxvciBlbiBSaWVzZ28gKFZhUikgY29uIGRpc3RyaWJ1Y2nDs24gbm9ybWFsIHkgcGVyY2VudGlsIGRlbCA5NSUNCiAgVmFSKGFzLm51bWVyaWMocG9ydC54dHNbLGldKSwgcD0wLjk1LCBtZXRob2Q9ImdhdXNzaWFuIiksDQogIA0KICAjIEV4cGVjdGF0aXZhIGRlIFDDqXJkaWRhIChFUykgY29uIGRpc3RyaWJ1Y2nDs24gbm9ybWFsIHkgcGVyY2VudGlsIGRlbCA5NSUNCiAgRVMoYXMubnVtZXJpYyhwb3J0Lnh0c1ssaV0pLCBwPTAuOTUsIG1ldGhvZD0iZ2F1c3NpYW4iKQ0KKQ0KfQ0KY29sbmFtZXModGFibGUpID0gY29sbmFtZXMocG9ydC54dHMpDQpyb3duYW1lcyh0YWJsZSkgPSBjKCJSZXR1cm4iLCJTdGREZXYiLCJTaGFycGUgUmF0aW8gKFN0ZERldikiLCJTaGFycGUgUmF0aW8gKFZhUikiLCJTaGFycGUgUmF0aW8gKENWYVIpIikNCmthYmxlKHJiaW5kKHRhYmxlLCBpcikpDQpgYGANCg0KIyAqKkFudG9uYWtha2lzLCBDaGF0emlhbnRvbmlvdSBhbmQgR2FiYXVlciAoMjAyMCk6ICoqIFJlZmluZWQgbWVhc3VyZXMgb2YgZHluYW1pYyBjb25uZWN0ZWRuZXNzIGJhc2VkIG9uIHRpbWUtdmFyeWluZyBwYXJhbWV0ZXIgdmVjdG9yIGF1dG9yZWdyZXNzaW9ucw0KYGBge3J9DQpkY2EzID0gQ29ubmVjdGVkbmVzc0FwcHJvYWNoKGRhdGFfem9vMiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgbmxhZz0xLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZm9yZT0xMiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aW5kb3cuc2l6ZT0yMDAsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9kZWw9IlRWUC1WQVIiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbm5lY3RlZG5lc3M9IlRpbWUiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZBUl9jb25maWc9bGlzdChUVlBWQVI9bGlzdChrYXBwYTE9MC45OSwga2FwcGEyPTAuOTYsIHByaW9yPSJCYXllc1ByaW9yIikpKQ0KDQpEQ0EgPSBsaXN0KCkNCldJTkRPVy5TSVpFID0gYyg1MCwgMTAwLCAyMDApDQpmb3IgKGkgaW4gMTpsZW5ndGgoV0lORE9XLlNJWkUpKSB7DQogIERDQVtbaV1dID0gc3VwcHJlc3NNZXNzYWdlcyhDb25uZWN0ZWRuZXNzQXBwcm9hY2goZGF0YV96b28yLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5sYWc9MSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZm9yZT0xMiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdpbmRvdy5zaXplPVdJTkRPVy5TSVpFW2ldKSkNCn0NCg0KI0ZpZ3VyZSA3OiBEeW5hbWljIFRvdGFsIENvbm5lY3RlZG5lc3MNClBsb3RUQ0koZGNhMywgY2E9RENBLCB5bGltPWMoMjAsODApKQ0KDQojIEZpZ3VyZSA4OiBOZXQgVG90YWwgYW5kIE5ldCBQYWlyd2lzZSBEaXJlY3Rpb25hbCBDb25uZWN0ZWRuZXNzIE1lYXN1cmVzDQpQbG90TkVUKGRjYTMsIGNhPURDQSwgeWxpbT1jKC0yMCwyMCkpDQpQbG90TlBEQyhkY2EzLCBjYT1EQ0EsIHlsaW09YygtMjAsMjApKQ0KDQpgYGANCg0KDQpgYGB7cn0NCiMgRnVuY2nDs24gcGFyYSBjcmVhciBsYSB0YWJsYSBjb24gbG9zIGPDoWxjdWxvcyBkaW7DoW1pY29zIGRlIGNvbmVjdGl2aWRhZA0KQ29ubmVjdGVkbmVzc1RhYmxlTW9kaWZpZWQgPC0gZnVuY3Rpb24oRkVWRCwgZGlnaXQgPSAyKSB7DQogIGlmIChsZW5ndGgoZGltKEZFVkQpKSA8PSAxKSB7DQogICAgc3RvcCgiRkVWRCBuZWVkcyB0byBiZSBhdCBsZWFzdCBhIDItZGltZW5zaW9uYWwgbWF0cml4IikNCiAgfQ0KICANCiAgIyBOb21icmVzIGRlIGxvcyBhY3Rpdm9zDQogIE5BTUVTID0gY29sbmFtZXMoRkVWRCkNCiAgayA9IGRpbShGRVZEKVsxXQ0KICBpZiAoaXMubnVsbChOQU1FUykpIHsNCiAgICBOQU1FUyA9IDE6aw0KICB9DQogIA0KICAjIENhbGN1bGFyIGxhcyBtw6l0cmljYXMgcHJpbmNpcGFsZXMNCiAgQ1QgPSBhcHBseShGRVZELCAxOjIsIG1lYW4pICogMTAwICAjIERlIG90cm9zIGhhY2lhIHVuIGFjdGl2byBlc3BlY8OtZmljbw0KICBPV04gPSBkaWFnKGRpYWcoQ1QpKQ0KICBUTyA9IGNvbFN1bXMoQ1QgLSBPV04pICAjIENvbnRyaWJ1Y2nDs24gaGFjaWEgb3Ryb3MgYWN0aXZvcw0KICBGUk9NID0gcm93U3VtcyhDVCAtIE9XTikgICMgQ29udHJpYnVjacOzbiBkZXNkZSBvdHJvcyBhY3Rpdm9zDQogIE5FVCA9IFRPIC0gRlJPTSAgIyBDb25lY3RpdmlkYWQgbmV0YQ0KICBUQ0kgPSBtZWFuKFRPKSAgIyDDjW5kaWNlIHRvdGFsIGRlIGNvbmVjdGl2aWRhZA0KICBjVENJID0gVENJICogayAvIChrIC0gMSkgICMgw41uZGljZSBjb3JyZWdpZG8NCiAgTlBEQyA9IENUIC0gdChDVCkgICMgQ29uZWN0aXZpZGFkIGRpcmVjY2lvbmFsIG5ldGEgcGFyLWEtcGFyDQogIE5QVCA9IHJvd1N1bXMoTlBEQyA8IDApICAjIENvbnRhZG9yIGRlIHRyYW5zbWlzb3JlcyBuZXRvcw0KICBJTkZMVUVOQ0UgPSAxMDAgKiBhYnMoTlBEQyAvIHQodChDVCkgKyBDVCkpICAjIEluZmx1ZW5jaWEgcG9yY2VudHVhbA0KICANCiAgIyBDcmVhciB0YWJsYSBmaW5hbA0KICB0YWJsZSA9IGZvcm1hdChyb3VuZChjYmluZChDVCwgRlJPTSksIGRpZ2l0KSwgbnNtYWxsID0gZGlnaXQpDQogIHRvID0gYyhmb3JtYXQocm91bmQoYyhUTywgc3VtKFRPKSksIGRpZ2l0KSwgbnNtYWxsID0gZGlnaXQpKQ0KICBpbmMgPSBjKGZvcm1hdChyb3VuZChjb2xTdW1zKENUKSwgZGlnaXQpLCBuc21hbGwgPSBkaWdpdCksICJjVENJL1RDSSIpDQogIHRjaSA9IHBhc3RlMChmb3JtYXQocm91bmQoY1RDSSwgZGlnaXQpLCBuc21hbGwgPSBkaWdpdCksICIvIiwgZm9ybWF0KHJvdW5kKFRDSSwgZGlnaXQpLCBuc21hbGwgPSBkaWdpdCkpDQogIG5ldCA9IGMoZm9ybWF0KHJvdW5kKE5FVCwgZGlnaXQpLCBuc21hbGwgPSBkaWdpdCkpDQogIG5ldCA9IGMobmV0LCB0Y2kpDQogIG5wZGMgPSBjKGZvcm1hdChyb3VuZChOUERDLCBkaWdpdCksIG5zbWFsbCA9IGRpZ2l0KSkNCiAgbnB0ID0gYyhmb3JtYXQocm91bmQoTlBULCBkaWdpdCksIG5zbWFsbCA9IGRpZ2l0KSwgIiIpDQogIA0KICBUQUJMRSA9IHJiaW5kKHRhYmxlLCB0bywgaW5jLCBuZXQsIG5wdCkNCiAgY29sbmFtZXMoVEFCTEUpID0gYyhOQU1FUywgIkZST00iKQ0KICByb3duYW1lcyhUQUJMRSkgPSBjKE5BTUVTLCAiVE8iLCAiSW5jLk93biIsICJORVQiLCAiTlBUIikNCiAgDQogIFBDSSA9IG1hdHJpeChOQSwgaywgaykNCiAgZm9yIChpIGluIDE6aykgew0KICAgIGZvciAoaiBpbiAxOmspIHsNCiAgICAgIFBDSVtpLCBqXSA9IDIwMCAqIChDVFtpLCBqXSArIENUW2osIGldKSAvIChDVFtpLCBpXSArIENUW2ksIGpdICsgQ1RbaiwgaV0gKyBDVFtqLCBqXSkNCiAgICB9DQogIH0NCiAgDQogIHJldHVybihsaXN0KA0KICAgIEZFVkQgPSBDVCwNCiAgICBUQ0kgPSBUQ0ksDQogICAgY1RDSSA9IGNUQ0ksDQogICAgUENJID0gUENJLA0KICAgIFRPID0gVE8sDQogICAgRlJPTSA9IEZST00sDQogICAgTkVUID0gTkVULA0KICAgIE5QREMgPSBOUERDLA0KICAgIFRBQkxFID0gVEFCTEUsDQogICAgTlBUID0gTlBULA0KICAgIElORkxVRU5DRSA9IElORkxVRU5DRQ0KICApKQ0KfQ0KDQojIEFwbGljYXIgbGEgZnVuY2nDs24gYSBsYXMgdmVudGFuYXMgeSBtb3N0cmFyIGxhcyB0YWJsYXMNCnRhYmxlcyA8LSBsaXN0KCkgICMgTGlzdGEgdmFjw61hIHBhcmEgYWxtYWNlbmFyIGxhcyB0YWJsYXMNCmZvciAoaSBpbiBzZXFfYWxvbmcoRENBKSkgew0KICByZXN1bHQgPC0gQ29ubmVjdGVkbmVzc1RhYmxlTW9kaWZpZWQoRENBW1tpXV0kQ1QsIGRpZ2l0ID0gMikgICMgQWp1c3RhIHNlZ8O6biB0dSBlc3RydWN0dXJhDQogIHRhYmxlc1tbaV1dIDwtIHJlc3VsdCRUQUJMRSAgIyBHdWFyZGFyIGxhIHRhYmxhIGVuIGxhIGxpc3RhDQogIGNhdChwYXN0ZTAoIlxuV2luZG93IFNpemU6ICIsIFdJTkRPVy5TSVpFW2ldLCAiXG4iKSkNCiAgcHJpbnQocmVzdWx0JFRBQkxFKSAgIyBNb3N0cmFyIHNvbG8gbGEgdGFibGEgcGFyYSBjYWRhIHZlbnRhbmENCn0NCmBgYA0KDQo=