References: The information sources are coming from the blog of Maung Agus Sutikno: Value at Risk (VaR) in R Programming Language and Portfolio & Single Stock VAR and CVAR in R

Risk management using VaR method

What is Value at Risk?

Value at Risk (VaR) is the highest loss You get with the probalibilty of 5 (1) %.

Installation of the Libraries

#install.packages("PerformanceAnalytics", repos = "http://cran.us.r-project.org")
#install.packages("dplyr", repos = "http://cran.us.r-project.org")
#install.packages("tidyquant", repos = "http://cran.us.r-project.org")
#install.packages("quantmod", repos = "http://cran.us.r-project.org")
#install.packages("tseries", repos = "http://cran.us.r-project.org")
#install.packages("tidyverse", repos = "http://cran.us.r-project.org")
library(PerformanceAnalytics)
library(ggplot2)
library(dplyr)
library(tidyquant)
library(quantmod)
library(tseries)
library(tidyverse)
rm(list=ls())
#        Input parameters
symbol_name <<- c("AAPL", "GOOG", "AMZN", "F", "A", "TQQQ")  # try to put Your tickers!!
vahy <<- c(0.2,0.2,0.2,0.2,0.1,0.1)
FROM <<- "2020-01-01"   # change to Your dates!!!
TO <<- "2022-12-31"

Data download

In the following, we prepare data for later analysis. Let us choose som tickers like follows:


# preparing one table in common for all the downloaded tickers - You can change 
for (i in 1:length(symbol_name)) {
  prac <<- Ad(getSymbols(symbol_name[i], from = FROM, to = TO,auto.assign=FALSE))
  if (i==1) {
    price <<-prac
  } else{
    price <<- merge(price,prac)
  }
}
rm(prac)    # prac is just temporary variable to remove
colnames(price) <- symbol_name  #puting the names of the shares

Calculate daily returns

We will first calculate a table of daily returns from the daily Adjusted close prices of the selected stocks. Each return \(r_t\) is calculated as

\[r_t = \ln(p_t)-\ln(p_{t-1})\]

which, by multipyying by 100 provides us with the percentual daily return of the underlying stock. See the following code

return_a <<- CalculateReturns(price, method="log")
#hist(return_a$AAPL)

# next cycle imputes the missing data by the variable medians
for(i in 1:dim(return_a)[2]){
  return_a[,i][is.na(return_a[,i])] <- median(return_a[,i],na.rm = TRUE)
}

return2_a <<- return_a[-1,]

In the sorted file of the returns, the 5th percentile is identified. We need not to sort the returns, the quantmod package provides us with the command VaR, which runs as follows

Basics - VaR of one share - historical and variance-covariance method.

Let us take the first share from the list defined above (AAPL).

# compute the 95th percentile of each column
# historical method

Qh <<- VaR(return2_a[,1], p=0.95, method="gaussian")
Qh
           AAPL
VaR -0.03747265
#variance-covariance method
# set the parameters


# calculate the 5th percentile
Qv <<- VaR(return2_a[,1], p=0.95, method="historical")
Qv
           AAPL
VaR -0.03546487

We interpret the results as follows. There is a 5% chance that within one day, the prices will fall by -3.75 percentage according to the historical method. And, by -3.55 percentage by the variance-covariance method.

Sometimes, we are speaking about Expected shortfall - in other words about Conditional Value at Risk. It expresses the expected loss if the returns fall behind the VaR.

\[CVaR = \frac{1}{0.05}\int_{-\infty}^{VaR}r_t f(r_t)dr_t\]

# create a histogram
hist(return2_a[,1], 
     breaks = seq(min(return2_a[,1])-0.02, max(return2_a[,1])+0.02, by = 0.01), # specify the bin width
     main = paste(symbol_name[1]," VaR hist =", round(Qh,3), sep = " ", "VaR cov = ", round(Qv,3)),
     freq=FALSE,
     xlab = "returns", # add a label to the x-axis
     ylab = "Frequency", # add a label to the y-axis
     col = "blue", # specify the color of the bars
     border = "white", # specify the color of the border of the bars
     xlim = c(min(return2_a[,1]) - 0.05, max(return2_a[,1]) + 0.05) # set the x-axis limits
)

abline(v = Qh, col = "red", lwd = 2)
abline(v = Qv, col = "green", lwd = 2)

curve(dnorm(x, mean = mean(return2_a[,1]), sd = sd(return2_a[,1])), 
      col = "red", 
      add = TRUE)

Complex portfolio - get some impression about the data

Below, there are some basic statistics of the individual shares’ returns.

summary(return2_a)
     Index                 AAPL                 GOOG                 AMZN           
 Min.   :2020-01-03   Min.   :-0.1377079   Min.   :-0.1176673   Min.   :-0.1513979  
 1st Qu.:2020-10-01   1st Qu.:-0.0111651   1st Qu.:-0.0097694   1st Qu.:-0.0129398  
 Median :2021-07-02   Median : 0.0006126   Median : 0.0011651   Median : 0.0005542  
 Mean   :2021-07-02   Mean   : 0.0007535   Mean   : 0.0003453   Mean   :-0.0001616  
 3rd Qu.:2022-03-31   3rd Qu.: 0.0140544   3rd Qu.: 0.0112562   3rd Qu.: 0.0121654  
 Max.   :2022-12-30   Max.   : 0.1131574   Max.   : 0.0898559   Max.   : 0.1269489  
       F                    A                  TQQQ           
 Min.   :-0.1315241   Min.   :-0.104710   Min.   :-0.4225883  
 1st Qu.:-0.0168221   1st Qu.:-0.008749   1st Qu.:-0.0256063  
 Median :-0.0010818   Median : 0.001437   Median : 0.0040550  
 Mean   : 0.0003506   Mean   : 0.000761   Mean   :-0.0003535  
 3rd Qu.: 0.0174348   3rd Qu.: 0.011432   3rd Qu.: 0.0305508  
 Max.   : 0.2105962   Max.   : 0.093849   Max.   : 0.2389255  

Find the share, which provides us with the highes interquartile range (3rd Qu.-1st Qu), which seems to be the main soruce of risks. (in our case it is TQQQ)

The below given Figure depicts pairwise correlations and some graphical information about corresponding pairs of the returns.


chart.Correlation(return_a[2:ncol(return_a)])

We see that the linear relationships are rather rare, however, the correlations depicted above the main diagonal express just linear relationship (as given by definition of the correlations). Anyway TQQQ demonstrates rather high degree of correlations with the other shares in portfolio.

Computation of VaR

The 5th percentile of the returns is a 5 % VaR. Look the following, where TQQQ seems to be most risky (has the lowest value of VaR)

Historical method

The historical method enables VaR computation also in the case of normality assumption volatility, or stric violation of the linear relationships between the returns pairs.

hist_var_2 <- VaR(return2_a, p=0.95, method="historical")
hist_var_2
           AAPL        GOOG        AMZN           F           A        TQQQ
VaR -0.03546487 -0.03586591 -0.03779691 -0.04427009 -0.03219257 -0.09413376

Variance-covariance method

Is based on the assumption, tha returns follow the normal distribution, and linear correlations. In this case the VaR is tabulated quantile of the normal distribution.

varcovar_var_2 <- VaR(return2_a, p=0.95, method="gaussian")
varcovar_var_2
           AAPL        GOOG        AMZN           F           A        TQQQ
VaR -0.03747265 -0.03528208 -0.04064733 -0.05067211 -0.03203609 -0.09287575

VaR of Portfolio

#symbol_name <<- c("AAPL", "GOOG", "AMZN", "F", "A", "TQQQ")  # try to put Your tickers!!
vahy <<- c(0.2,0.2,0.2,0.2,0.1,0.1)

# preparing one table in common for all the downloaded tickers - You can change 

valueAtRisk <-VaR(return2_a, weights = vahy, p=0.95, portfolio_method = "component", method = "gaussian")

valueAtRisk
$VaR
[1] 0.03723484

$contribution
       AAPL        GOOG        AMZN           F           A        TQQQ 
0.006547591 0.006128861 0.006523205 0.006746761 0.002336600 0.008951819 

$pct_contrib_VaR
      AAPL       GOOG       AMZN          F          A       TQQQ 
0.17584584 0.16460019 0.17519091 0.18119486 0.06275305 0.24041515 

It means, that the Value at Risk of the entire portfolio (respecting the defined weights) is 0.0372348 with the vector of the contribution of each involved assets 0.0065476, 0.0061289, 0.0065232, 0.0067468, 0.0023366, 0.0089518 which in the percentage form is given as 0.1758458, 0.1646002, 0.1751909, 0.1811949, 0.0627531, 0.2404151. We see, that despite small representance (i.e. 10 percent) of the TQQQ share in the portfolio, the contribution to the total Value At Risk is the highest

Expected shortfall of the portfolio

#symbol_name <<- c("AAPL", "GOOG", "AMZN", "F", "A", "TQQQ")  # try to put Your tickers!!

# preparing one table in common for all the downloaded tickers - You can change 

ExpectedShortFall <-ETL(return2_a, weights = vahy, p=0.95, portfolio_method = "component", method = "historical")  # probe to change "historical" to "gauss"

ExpectedShortFall
$`-r_exceed/c_exceed`
[1] 0.05142899

$c_exceed
[1] 48

$pct_contrib_hES
      AAPL       GOOG       AMZN          F          A       TQQQ 
0.16471573 0.16695479 0.17429127 0.18278132 0.06346735 0.24778955 

We get the similar results, if speaking about Expected Shorfall. It means, that the Expected shortfall of the entire portfolio (respecting the defined weights) is with the vector of the contribution of each involved assets which in the percentage form is given as . We see again, that despite small representance (i.e. 10 percent) of the TQQQ share in the portfolio, the contribution to the total Value At Risk is the highest

Note:

If computing of the particular share’s VaR contribution to the portfolio VaR, the Euler theorem is effectively used. Look at the following

The Value at risk of the portfolio is given as follows:

\[VaR_p = \sqrt(\sum_i \alpha_i^2 VaR_i + \sum_{i \neq j}\rho_{ij}\alpha_i VaR_i \alpha_j VaR_j)\] which is homogeneous function of the 1st degree, as

\[kVaR_p = \sqrt(\sum_i (k\alpha_i)^2 VaR_i + \sum_{i \neq j}\rho_{ij}(k\alpha_i) VaR_i (k\alpha_j) VaR_j)\] That is, why we can apply the Euler theorem leading to

\[VaR_p = \sum_i \frac{\partial VaR}{\partial \alpha_i}\alpha_i\] which is VaR decomposition given above.

Expected shortfall (= Conditional VaR)

The same formula and Euler theorem can be used also for computation of the Expected ShorFall of the portfolio:

\[ESF_p = \sqrt(\sum_i \alpha_i^2 ESF_i + \sum_{i \neq j}\rho_{ij}\alpha_i ESF_i \alpha_j ESF_j)\] which is homogeneous function of the 1st degree, as

\[kESF_p = \sqrt(\sum_i (k\alpha_i)^2 ESF_i + \sum_{i \neq j}\rho_{ij}(k\alpha_i) ESF_i (k\alpha_j) ESF_j)\]

If applying the Euler Theorem, then

\[ESF_p = \sum_i \frac{\partial ESF}{\partial \alpha_i}\alpha_i\] which is VaR decomposition given above.

LS0tCnRpdGxlOiAiVmFsdWUgYXQgUmlzayAoVmFSKSIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKUmVmZXJlbmNlczogVGhlIGluZm9ybWF0aW9uIHNvdXJjZXMgYXJlIGNvbWluZyBmcm9tIHRoZSBibG9nIG9mIE1hdW5nIEFndXMgU3V0aWtubzogW1ZhbHVlIGF0IFJpc2sgKFZhUikgaW4gUiBQcm9ncmFtbWluZyBMYW5ndWFnZV0oaHR0cHM6Ly9tYXVuZy1zdXRpa25vLm1lZGl1bS5jb20vdmFsdWUtYXQtcmlzay12YXItaW4tci1wcm9ncmFtbWluZy1sYW5ndWFnZS0yYzI4Y2M5MmZiYzIjOn46dGV4dD1WYWx1ZSUyMGF0JTIwcmlzayUyQyUyMG9yJTIwVmFSLGZyYW1lJTIwKEludmVzdG9wZWRpYSUyQyUyMDIwMjIpLikgYW5kIFtQb3J0Zm9saW8gJiBTaW5nbGUgU3RvY2sgVkFSIGFuZCBDVkFSIGluIFJdKGh0dHBzOi8vd3d3LnlvdXR1YmUuY29tL3dhdGNoP3Y9ME43WEJrN1lBNUEmbGlzdD1QTEpxcE1BQXdjTHV1czBGcUdCeXE4RkMzdWt3WWNKejdBJmluZGV4PTIzJnQ9MTUxcykKCiMjIFJpc2sgbWFuYWdlbWVudCB1c2luZyBWYVIgbWV0aG9kCgpXaGF0IGlzICpWYWx1ZSBhdCBSaXNrKj8KCioqVmFsdWUgYXQgUmlzayAoVmFSKSBpcyB0aGUgaGlnaGVzdCBsb3NzIFlvdSBnZXQgd2l0aCB0aGUgcHJvYmFsaWJpbHR5IG9mIDUgKDEpIFwlLioqCgoKCiMjIyBJbnN0YWxsYXRpb24gb2YgdGhlIExpYnJhcmllcwpgYGB7cn0KI2luc3RhbGwucGFja2FnZXMoIlBlcmZvcm1hbmNlQW5hbHl0aWNzIiwgcmVwb3MgPSAiaHR0cDovL2NyYW4udXMuci1wcm9qZWN0Lm9yZyIpCiNpbnN0YWxsLnBhY2thZ2VzKCJkcGx5ciIsIHJlcG9zID0gImh0dHA6Ly9jcmFuLnVzLnItcHJvamVjdC5vcmciKQojaW5zdGFsbC5wYWNrYWdlcygidGlkeXF1YW50IiwgcmVwb3MgPSAiaHR0cDovL2NyYW4udXMuci1wcm9qZWN0Lm9yZyIpCiNpbnN0YWxsLnBhY2thZ2VzKCJxdWFudG1vZCIsIHJlcG9zID0gImh0dHA6Ly9jcmFuLnVzLnItcHJvamVjdC5vcmciKQojaW5zdGFsbC5wYWNrYWdlcygidHNlcmllcyIsIHJlcG9zID0gImh0dHA6Ly9jcmFuLnVzLnItcHJvamVjdC5vcmciKQojaW5zdGFsbC5wYWNrYWdlcygidGlkeXZlcnNlIiwgcmVwb3MgPSAiaHR0cDovL2NyYW4udXMuci1wcm9qZWN0Lm9yZyIpCmxpYnJhcnkoUGVyZm9ybWFuY2VBbmFseXRpY3MpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShkcGx5cikKbGlicmFyeSh0aWR5cXVhbnQpCmxpYnJhcnkocXVhbnRtb2QpCmxpYnJhcnkodHNlcmllcykKbGlicmFyeSh0aWR5dmVyc2UpCnJtKGxpc3Q9bHMoKSkKYGBgCgpgYGB7cn0KIyAgICAgICAgSW5wdXQgcGFyYW1ldGVycwpzeW1ib2xfbmFtZSA8PC0gYygiQUFQTCIsICJHT09HIiwgIkFNWk4iLCAiRiIsICJBIiwgIlRRUVEiKSAgIyB0cnkgdG8gcHV0IFlvdXIgdGlja2VycyEhCnZhaHkgPDwtIGMoMC4yLDAuMiwwLjIsMC4yLDAuMSwwLjEpCkZST00gPDwtICIyMDIwLTAxLTAxIiAgICMgY2hhbmdlIHRvIFlvdXIgZGF0ZXMhISEKVE8gPDwtICIyMDIyLTEyLTMxIgpgYGAKCgoKCiMjIERhdGEgZG93bmxvYWQKCkluIHRoZSBmb2xsb3dpbmcsIHdlIHByZXBhcmUgZGF0YSBmb3IgbGF0ZXIgYW5hbHlzaXMuIExldCB1cyBjaG9vc2Ugc29tIHRpY2tlcnMgbGlrZSBmb2xsb3dzOgoKYGBge3IgZG93bmxvYWRfZGF0YSxtZXNzYWdlPUZBTFNFfQoKIyBwcmVwYXJpbmcgb25lIHRhYmxlIGluIGNvbW1vbiBmb3IgYWxsIHRoZSBkb3dubG9hZGVkIHRpY2tlcnMgLSBZb3UgY2FuIGNoYW5nZSAKZm9yIChpIGluIDE6bGVuZ3RoKHN5bWJvbF9uYW1lKSkgewogIHByYWMgPDwtIEFkKGdldFN5bWJvbHMoc3ltYm9sX25hbWVbaV0sIGZyb20gPSBGUk9NLCB0byA9IFRPLGF1dG8uYXNzaWduPUZBTFNFKSkKICBpZiAoaT09MSkgewogICAgcHJpY2UgPDwtcHJhYwogIH0gZWxzZXsKICAgIHByaWNlIDw8LSBtZXJnZShwcmljZSxwcmFjKQogIH0KfQpybShwcmFjKSAgICAjIHByYWMgaXMganVzdCB0ZW1wb3JhcnkgdmFyaWFibGUgdG8gcmVtb3ZlCmNvbG5hbWVzKHByaWNlKSA8LSBzeW1ib2xfbmFtZSAgI3B1dGluZyB0aGUgbmFtZXMgb2YgdGhlIHNoYXJlcwpgYGAKCgoKCiMjIyBDYWxjdWxhdGUgZGFpbHkgcmV0dXJucwpXZSB3aWxsIGZpcnN0IGNhbGN1bGF0ZSBhIHRhYmxlIG9mIGRhaWx5IHJldHVybnMgZnJvbSB0aGUgZGFpbHkgQWRqdXN0ZWQgY2xvc2UgcHJpY2VzIG9mIHRoZSBzZWxlY3RlZCBzdG9ja3MuICBFYWNoIHJldHVybiAkcl90JCBpcyBjYWxjdWxhdGVkIGFzCgokJHJfdCA9IFxsbihwX3QpLVxsbihwX3t0LTF9KSQkCgp3aGljaCwgYnkgbXVsdGlweXlpbmcgYnkgMTAwIHByb3ZpZGVzIHVzIHdpdGggdGhlIHBlcmNlbnR1YWwgZGFpbHkgcmV0dXJuIG9mIHRoZSB1bmRlcmx5aW5nIHN0b2NrLiBTZWUgdGhlIGZvbGxvd2luZyBjb2RlCgpgYGB7cn0KcmV0dXJuX2EgPDwtIENhbGN1bGF0ZVJldHVybnMocHJpY2UsIG1ldGhvZD0ibG9nIikKI2hpc3QocmV0dXJuX2EkQUFQTCkKCiMgbmV4dCBjeWNsZSBpbXB1dGVzIHRoZSBtaXNzaW5nIGRhdGEgYnkgdGhlIHZhcmlhYmxlIG1lZGlhbnMKZm9yKGkgaW4gMTpkaW0ocmV0dXJuX2EpWzJdKXsKICByZXR1cm5fYVssaV1baXMubmEocmV0dXJuX2FbLGldKV0gPC0gbWVkaWFuKHJldHVybl9hWyxpXSxuYS5ybSA9IFRSVUUpCn0KCnJldHVybjJfYSA8PC0gcmV0dXJuX2FbLTEsXQoKYGBgCkluIHRoZSBzb3J0ZWQgZmlsZSBvZiB0aGUgcmV0dXJucywgdGhlIDV0aCBwZXJjZW50aWxlIGlzIGlkZW50aWZpZWQuIFdlIG5lZWQgbm90IHRvIHNvcnQgdGhlIHJldHVybnMsIHRoZSBxdWFudG1vZCBwYWNrYWdlIHByb3ZpZGVzIHVzIHdpdGggdGhlIGNvbW1hbmQgVmFSLCB3aGljaCBydW5zIGFzIGZvbGxvd3MKCgoKIyMgQmFzaWNzIC0gVmFSIG9mIG9uZSBzaGFyZSAtIGhpc3RvcmljYWwgYW5kIHZhcmlhbmNlLWNvdmFyaWFuY2UgbWV0aG9kLgoKTGV0IHVzIHRha2UgdGhlIGZpcnN0IHNoYXJlIGZyb20gdGhlIGxpc3QgZGVmaW5lZCBhYm92ZSAoYHIgY29sbmFtZXMocmV0dXJuMl9hKVsxXWApLiAKCmBgYHtyIEhpc3RvcmljYWxfbWV0aG9kX2FuZF92YXJpYW5jZV9jb3ZhcmlhbmNlX21ldGhvZDJ9CiMgY29tcHV0ZSB0aGUgOTV0aCBwZXJjZW50aWxlIG9mIGVhY2ggY29sdW1uCiMgaGlzdG9yaWNhbCBtZXRob2QKClFoIDw8LSBWYVIocmV0dXJuMl9hWywxXSwgcD0wLjk1LCBtZXRob2Q9ImdhdXNzaWFuIikKUWgKCiN2YXJpYW5jZS1jb3ZhcmlhbmNlIG1ldGhvZAojIHNldCB0aGUgcGFyYW1ldGVycwoKCiMgY2FsY3VsYXRlIHRoZSA1dGggcGVyY2VudGlsZQpRdiA8PC0gVmFSKHJldHVybjJfYVssMV0sIHA9MC45NSwgbWV0aG9kPSJoaXN0b3JpY2FsIikKUXYKYGBgCldlIGludGVycHJldCB0aGUgcmVzdWx0cyBhcyBmb2xsb3dzLiBUaGVyZSBpcyBhIDUlIGNoYW5jZSB0aGF0IHdpdGhpbiBvbmUgZGF5LCB0aGUgcHJpY2VzIHdpbGwgZmFsbCBieSBgciByb3VuZChRaCw0KSoxMDBgIHBlcmNlbnRhZ2UgYWNjb3JkaW5nIHRvIHRoZSBoaXN0b3JpY2FsIG1ldGhvZC4gCkFuZCwgYnkgYHIgcm91bmQoUXYsNCkqMTAwYCBwZXJjZW50YWdlIGJ5IHRoZSB2YXJpYW5jZS1jb3ZhcmlhbmNlIG1ldGhvZC4gCgpTb21ldGltZXMsIHdlIGFyZSBzcGVha2luZyBhYm91dCBFeHBlY3RlZCBzaG9ydGZhbGwgLSBpbiBvdGhlciB3b3JkcyBhYm91dCBDb25kaXRpb25hbCBWYWx1ZSBhdCBSaXNrLiBJdCBleHByZXNzZXMgdGhlIGV4cGVjdGVkIGxvc3MgaWYgdGhlIHJldHVybnMgZmFsbCBiZWhpbmQgdGhlIFZhUi4KCiQkQ1ZhUiA9IFxmcmFjezF9ezAuMDV9XGludF97LVxpbmZ0eX1ee1ZhUn1yX3QgZihyX3QpZHJfdCQkCgoKCgoKCmBgYHtyIEhpc3RvcmljYWxfbWV0aG9kX2FuZF92YXJpYW5jZV9jb3ZhcmlhbmNlX21ldGhvZDN9CiMgY3JlYXRlIGEgaGlzdG9ncmFtCmhpc3QocmV0dXJuMl9hWywxXSwgCiAgICAgYnJlYWtzID0gc2VxKG1pbihyZXR1cm4yX2FbLDFdKS0wLjAyLCBtYXgocmV0dXJuMl9hWywxXSkrMC4wMiwgYnkgPSAwLjAxKSwgIyBzcGVjaWZ5IHRoZSBiaW4gd2lkdGgKICAgICBtYWluID0gcGFzdGUoc3ltYm9sX25hbWVbMV0sIiBWYVIgaGlzdCA9Iiwgcm91bmQoUWgsMyksIHNlcCA9ICIgIiwgIlZhUiBjb3YgPSAiLCByb3VuZChRdiwzKSksCiAgICAgZnJlcT1GQUxTRSwKICAgICB4bGFiID0gInJldHVybnMiLCAjIGFkZCBhIGxhYmVsIHRvIHRoZSB4LWF4aXMKICAgICB5bGFiID0gIkZyZXF1ZW5jeSIsICMgYWRkIGEgbGFiZWwgdG8gdGhlIHktYXhpcwogICAgIGNvbCA9ICJibHVlIiwgIyBzcGVjaWZ5IHRoZSBjb2xvciBvZiB0aGUgYmFycwogICAgIGJvcmRlciA9ICJ3aGl0ZSIsICMgc3BlY2lmeSB0aGUgY29sb3Igb2YgdGhlIGJvcmRlciBvZiB0aGUgYmFycwogICAgIHhsaW0gPSBjKG1pbihyZXR1cm4yX2FbLDFdKSAtIDAuMDUsIG1heChyZXR1cm4yX2FbLDFdKSArIDAuMDUpICMgc2V0IHRoZSB4LWF4aXMgbGltaXRzCikKCmFibGluZSh2ID0gUWgsIGNvbCA9ICJyZWQiLCBsd2QgPSAyKQphYmxpbmUodiA9IFF2LCBjb2wgPSAiZ3JlZW4iLCBsd2QgPSAyKQoKY3VydmUoZG5vcm0oeCwgbWVhbiA9IG1lYW4ocmV0dXJuMl9hWywxXSksIHNkID0gc2QocmV0dXJuMl9hWywxXSkpLCAKICAgICAgY29sID0gInJlZCIsIAogICAgICBhZGQgPSBUUlVFKQoKYGBgCgoKIyMjIENvbXBsZXggcG9ydGZvbGlvIC0gZ2V0IHNvbWUgaW1wcmVzc2lvbiBhYm91dCB0aGUgZGF0YQoKQmVsb3csIHRoZXJlIGFyZSBzb21lIGJhc2ljIHN0YXRpc3RpY3Mgb2YgdGhlIGluZGl2aWR1YWwgc2hhcmVzJyByZXR1cm5zLgoKYGBge3IgZmlnNmEsIGVycm9yPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpzdW1tYXJ5KHJldHVybjJfYSkKCmBgYApGaW5kIHRoZSBzaGFyZSwgd2hpY2ggcHJvdmlkZXMgdXMgd2l0aCB0aGUgaGlnaGVzIGludGVycXVhcnRpbGUgcmFuZ2UgKDNyZCBRdS4tMXN0IFF1KSwgd2hpY2ggc2VlbXMgdG8gYmUgdGhlIG1haW4gc29ydWNlIG9mIHJpc2tzLiAoaW4gb3VyIGNhc2UgaXQgaXMgVFFRUSkKClRoZSBiZWxvdyBnaXZlbiBGaWd1cmUgZGVwaWN0cyBwYWlyd2lzZSBjb3JyZWxhdGlvbnMgYW5kIHNvbWUgZ3JhcGhpY2FsIGluZm9ybWF0aW9uIGFib3V0IGNvcnJlc3BvbmRpbmcgcGFpcnMgb2YgdGhlIHJldHVybnMuCgpgYGB7ciBmaWc2YiwgZXJyb3I9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CgpjaGFydC5Db3JyZWxhdGlvbihyZXR1cm5fYVsyOm5jb2wocmV0dXJuX2EpXSkKCmBgYAoKV2Ugc2VlIHRoYXQgdGhlIGxpbmVhciByZWxhdGlvbnNoaXBzIGFyZSByYXRoZXIgcmFyZSwgaG93ZXZlciwgdGhlIGNvcnJlbGF0aW9ucyBkZXBpY3RlZCBhYm92ZSB0aGUgbWFpbiBkaWFnb25hbCBleHByZXNzIGp1c3QgbGluZWFyIHJlbGF0aW9uc2hpcCAoYXMgZ2l2ZW4gYnkgZGVmaW5pdGlvbiBvZiB0aGUgY29ycmVsYXRpb25zKS4gQW55d2F5IFRRUVEgZGVtb25zdHJhdGVzIHJhdGhlciBoaWdoIGRlZ3JlZSBvZiBjb3JyZWxhdGlvbnMgd2l0aCB0aGUgb3RoZXIgc2hhcmVzIGluIHBvcnRmb2xpby4KCiMjIyBDb21wdXRhdGlvbiBvZiBWYVIKClRoZSA1dGggcGVyY2VudGlsZSBvZiB0aGUgcmV0dXJucyBpcyBhIDUgXCUgVmFSLiBMb29rIHRoZSBmb2xsb3dpbmcsIHdoZXJlIFRRUVEgc2VlbXMgdG8gYmUgbW9zdCByaXNreSAoaGFzIHRoZSBsb3dlc3QgdmFsdWUgb2YgVmFSKQoKIyMjIyBIaXN0b3JpY2FsIG1ldGhvZAoKVGhlIGhpc3RvcmljYWwgbWV0aG9kIGVuYWJsZXMgVmFSIGNvbXB1dGF0aW9uIGFsc28gaW4gdGhlIGNhc2Ugb2Ygbm9ybWFsaXR5IGFzc3VtcHRpb24gdm9sYXRpbGl0eSwgb3Igc3RyaWMgdmlvbGF0aW9uIG9mIHRoZSBsaW5lYXIgcmVsYXRpb25zaGlwcyBiZXR3ZWVuIHRoZSByZXR1cm5zIHBhaXJzLgoKYGBge3J9Cmhpc3RfdmFyXzIgPC0gVmFSKHJldHVybjJfYSwgcD0wLjk1LCBtZXRob2Q9Imhpc3RvcmljYWwiKQpoaXN0X3Zhcl8yCmBgYAoKIyMjIyBWYXJpYW5jZS1jb3ZhcmlhbmNlIG1ldGhvZAoKSXMgYmFzZWQgb24gdGhlIGFzc3VtcHRpb24sIHRoYSByZXR1cm5zIGZvbGxvdyB0aGUgbm9ybWFsIGRpc3RyaWJ1dGlvbiwgYW5kIGxpbmVhciBjb3JyZWxhdGlvbnMuIEluIHRoaXMgY2FzZSB0aGUgVmFSIGlzIHRhYnVsYXRlZCBxdWFudGlsZSBvZiB0aGUgbm9ybWFsIGRpc3RyaWJ1dGlvbi4KCmBgYHtyfQp2YXJjb3Zhcl92YXJfMiA8LSBWYVIocmV0dXJuMl9hLCBwPTAuOTUsIG1ldGhvZD0iZ2F1c3NpYW4iKQp2YXJjb3Zhcl92YXJfMgpgYGAKCgoKIyMgVmFSIG9mIFBvcnRmb2xpbwoKYGBge3IgcG9ydGZvbGlvMX0KI3N5bWJvbF9uYW1lIDw8LSBjKCJBQVBMIiwgIkdPT0ciLCAiQU1aTiIsICJGIiwgIkEiLCAiVFFRUSIpICAjIHRyeSB0byBwdXQgWW91ciB0aWNrZXJzISEKdmFoeSA8PC0gYygwLjIsMC4yLDAuMiwwLjIsMC4xLDAuMSkKCiMgcHJlcGFyaW5nIG9uZSB0YWJsZSBpbiBjb21tb24gZm9yIGFsbCB0aGUgZG93bmxvYWRlZCB0aWNrZXJzIC0gWW91IGNhbiBjaGFuZ2UgCgp2YWx1ZUF0UmlzayA8LVZhUihyZXR1cm4yX2EsIHdlaWdodHMgPSB2YWh5LCBwPTAuOTUsIHBvcnRmb2xpb19tZXRob2QgPSAiY29tcG9uZW50IiwgbWV0aG9kID0gImdhdXNzaWFuIikKCnZhbHVlQXRSaXNrCgpgYGAKCkl0IG1lYW5zLCB0aGF0IHRoZSBWYWx1ZSBhdCBSaXNrIG9mIHRoZSBlbnRpcmUgcG9ydGZvbGlvIChyZXNwZWN0aW5nIHRoZSBkZWZpbmVkIHdlaWdodHMpIGlzIGByICB2YWx1ZUF0UmlzayRWYVJgIHdpdGggdGhlIHZlY3RvciBvZiB0aGUgY29udHJpYnV0aW9uIG9mIGVhY2ggaW52b2x2ZWQgYXNzZXRzIGByICB2YWx1ZUF0UmlzayRjb250cmlidXRpb25gIHdoaWNoIGluIHRoZSBwZXJjZW50YWdlIGZvcm0gaXMgZ2l2ZW4gYXMgICBgciB2YWx1ZUF0UmlzayRwY3RfY29udHJpYl9WYVJgLgpXZSBzZWUsIHRoYXQgZGVzcGl0ZSBzbWFsbCByZXByZXNlbnRhbmNlIChpLmUuIDEwIHBlcmNlbnQpIG9mIHRoZSBUUVFRIHNoYXJlIGluIHRoZSBwb3J0Zm9saW8sIHRoZSBjb250cmlidXRpb24gdG8gdGhlIHRvdGFsIFZhbHVlIEF0IFJpc2sgaXMgdGhlIGhpZ2hlc3QKCiMjIyMgRXhwZWN0ZWQgc2hvcnRmYWxsIG9mIHRoZSBwb3J0Zm9saW8KCmBgYHtyIHBvcnRmb2xpbzJ9CiNzeW1ib2xfbmFtZSA8PC0gYygiQUFQTCIsICJHT09HIiwgIkFNWk4iLCAiRiIsICJBIiwgIlRRUVEiKSAgIyB0cnkgdG8gcHV0IFlvdXIgdGlja2VycyEhCgojIHByZXBhcmluZyBvbmUgdGFibGUgaW4gY29tbW9uIGZvciBhbGwgdGhlIGRvd25sb2FkZWQgdGlja2VycyAtIFlvdSBjYW4gY2hhbmdlIAoKRXhwZWN0ZWRTaG9ydEZhbGwgPC1FVEwocmV0dXJuMl9hLCB3ZWlnaHRzID0gdmFoeSwgcD0wLjk1LCBwb3J0Zm9saW9fbWV0aG9kID0gImNvbXBvbmVudCIsIG1ldGhvZCA9ICJoaXN0b3JpY2FsIikgICMgcHJvYmUgdG8gY2hhbmdlICJoaXN0b3JpY2FsIiB0byAiZ2F1c3MiCgpFeHBlY3RlZFNob3J0RmFsbAoKYGBgCgpXZSBnZXQgdGhlIHNpbWlsYXIgcmVzdWx0cywgaWYgc3BlYWtpbmcgYWJvdXQgRXhwZWN0ZWQgU2hvcmZhbGwuIEl0IG1lYW5zLCB0aGF0IHRoZSBFeHBlY3RlZCBzaG9ydGZhbGwgb2YgdGhlIGVudGlyZSBwb3J0Zm9saW8gKHJlc3BlY3RpbmcgdGhlIGRlZmluZWQgd2VpZ2h0cykgaXMgYHIgIEV4cGVjdGVkU2hvcnRGYWxsJEVTYCB3aXRoIHRoZSB2ZWN0b3Igb2YgdGhlIGNvbnRyaWJ1dGlvbiBvZiBlYWNoIGludm9sdmVkIGFzc2V0cyBgciAgRXhwZWN0ZWRTaG9ydEZhbGwkY29udHJpYnV0aW9uYCB3aGljaCBpbiB0aGUgcGVyY2VudGFnZSBmb3JtIGlzIGdpdmVuIGFzICAgYHIgRXhwZWN0ZWRTaG9ydEZhbGwkcGN0X2NvbnRyaWJfRVNgLgpXZSBzZWUgYWdhaW4sIHRoYXQgZGVzcGl0ZSBzbWFsbCByZXByZXNlbnRhbmNlIChpLmUuIDEwIHBlcmNlbnQpIG9mIHRoZSBUUVFRIHNoYXJlIGluIHRoZSBwb3J0Zm9saW8sIHRoZSBjb250cmlidXRpb24gdG8gdGhlIHRvdGFsIFZhbHVlIEF0IFJpc2sgaXMgdGhlIGhpZ2hlc3QKCk5vdGU6CgpJZiBjb21wdXRpbmcgb2YgdGhlIHBhcnRpY3VsYXIgc2hhcmUncyBWYVIgY29udHJpYnV0aW9uIHRvIHRoZSBwb3J0Zm9saW8gVmFSLCB0aGUgKkV1bGVyIHRoZW9yZW0qIGlzIGVmZmVjdGl2ZWx5IHVzZWQuIExvb2sgYXQgdGhlIGZvbGxvd2luZwoKVGhlIFZhbHVlIGF0IHJpc2sgb2YgdGhlIHBvcnRmb2xpbyBpcyBnaXZlbiBhcyBmb2xsb3dzOgoKJCRWYVJfcCA9IFxzcXJ0KFxzdW1faSBcYWxwaGFfaV4yIFZhUl9pICsgXHN1bV97aSBcbmVxIGp9XHJob197aWp9XGFscGhhX2kgVmFSX2kgXGFscGhhX2ogVmFSX2opJCQKd2hpY2ggaXMgaG9tb2dlbmVvdXMgZnVuY3Rpb24gb2YgdGhlIDFzdCBkZWdyZWUsIGFzIAoKJCRrVmFSX3AgPSBcc3FydChcc3VtX2kgKGtcYWxwaGFfaSleMiBWYVJfaSArIFxzdW1fe2kgXG5lcSBqfVxyaG9fe2lqfShrXGFscGhhX2kpIFZhUl9pIChrXGFscGhhX2opIFZhUl9qKSQkClRoYXQgaXMsIHdoeSB3ZSBjYW4gYXBwbHkgdGhlIFtFdWxlciB0aGVvcmVtXShodHRwczovL3lvdXR1LmJlL2otOHg1LWd5WHBJP3Q9NjE0KSBsZWFkaW5nIHRvIAoKJCRWYVJfcCA9IFxzdW1faSBcZnJhY3tccGFydGlhbCBWYVJ9e1xwYXJ0aWFsIFxhbHBoYV9pfVxhbHBoYV9pJCQKd2hpY2ggaXMgVmFSIGRlY29tcG9zaXRpb24gZ2l2ZW4gYWJvdmUuCgojIyMjIEV4cGVjdGVkIHNob3J0ZmFsbCAoPSBDb25kaXRpb25hbCBWYVIpCgpUaGUgc2FtZSBmb3JtdWxhIGFuZCBFdWxlciB0aGVvcmVtIGNhbiBiZSB1c2VkIGFsc28gZm9yIGNvbXB1dGF0aW9uIG9mIHRoZSBFeHBlY3RlZCBTaG9yRmFsbCBvZiB0aGUgcG9ydGZvbGlvOgoKJCRFU0ZfcCA9IFxzcXJ0KFxzdW1faSBcYWxwaGFfaV4yIEVTRl9pICsgXHN1bV97aSBcbmVxIGp9XHJob197aWp9XGFscGhhX2kgRVNGX2kgXGFscGhhX2ogRVNGX2opJCQKd2hpY2ggaXMgaG9tb2dlbmVvdXMgZnVuY3Rpb24gb2YgdGhlIDFzdCBkZWdyZWUsIGFzIAoKJCRrRVNGX3AgPSBcc3FydChcc3VtX2kgKGtcYWxwaGFfaSleMiBFU0ZfaSArIFxzdW1fe2kgXG5lcSBqfVxyaG9fe2lqfShrXGFscGhhX2kpIEVTRl9pIChrXGFscGhhX2opIEVTRl9qKSQkCgpJZiBhcHBseWluZyB0aGUgRXVsZXIgVGhlb3JlbSwgdGhlbiAKCiQkRVNGX3AgPSBcc3VtX2kgXGZyYWN7XHBhcnRpYWwgRVNGfXtccGFydGlhbCBcYWxwaGFfaX1cYWxwaGFfaSQkCndoaWNoIGlzIFZhUiBkZWNvbXBvc2l0aW9uIGdpdmVuIGFib3ZlLgoKCgoKCgoKCg==