Introduction
In this section, we will see basic aspects of the logistic model to
analyze the relationship between a binary dependent variable and an
independent variable.
We continue to replicate the analysis of chapter “Social networks and
political attitudes” from the report The
Pulse of Democracy of the 2018/19 round. In this chapter, we analyze
a measure of support for democracy.
About the dataset
The data we are going to use should be cited as follows: Source:
AmericasBarometer by the Latin American Public Opinion Project (LAPOP),
wwww.LapopSurveys.org. You can download the data freely here.
It is recommended to clean the Environment before starting this
section. In this document, a database in RData format is again loaded.
This format is efficient in terms of storage space. This database is
hosted in the “materials_edu” repository of the LAPOP account on GitHub.
Using the rio
library and the import
command,
you can import this database from this repository, using the following
code.
library(rio)
lapop18 = import("https://raw.github.com/lapop-central/materials_edu/main/lapop18.RData")
lapop18 = subset(lapop18, pais<=35)
Determinants of use of social networks
The section about social networks presents results of a logistic
regression model in Figure 3.4. As report says, this figure “shows the
results of a logistic regression analysis that regress high use of
social media (vs. low use) on the same set of demographic and
socioeconomic factors” (p. 59).
As the report also indicates “the dependent variable, Social
Media User, is based on responses to the three questions about
holding accounts from Facebook, Twitter, and Whatsapp. This dichotomous
measure distinguishes between those individuals who use accounts from
one or more of these platforms, compared to those who do not engane with
any social media account” (p. 59).
In the section on descriptive
statistics we present the code to create users of each social
network using the commandifelse
.
lapop18$fb_user = ifelse(lapop18$smedia1==1 & lapop18$smedia2<=4, 1, 0)
lapop18$tw_user = ifelse(lapop18$smedia4==1 & lapop18$smedia5<=4, 1, 0)
lapop18$wa_user = ifelse(lapop18$smedia7==1 & lapop18$smedia8<=4, 1, 0)
Based on these variables, we create a variable for users of any
social network. This dichotomous variable has a value of 1 if
interviewee reports being user of any social network in the
questionnaire (Facebook or Twitter or Whatsapp).
lapop18$user = ifelse(lapop18$fb_user==1 | lapop18$wa_user==1 | lapop18$tw_user ==1, 1, 0)
table(lapop18$user)
##
## 0 1
## 8057 18973
Figure 3.4 shows the determinants of social media use. These
variables are:
Level of wealth: variable “quintall” in the dataset.
Years of education: variable “ed” in the dataset.
Age: variable “q2” in the dataset.
Female: variable “mujer” in the dataset.
Urban area: variable “ur” in the dataset.
Footnote 16 indicates that “Age and education are measured in years,
rescaled to 0 to 1, where 0 indicates the youngest or the lowest level
of education, and 1 the oldest or the highest level of education. Wealth
is an ordinal variable, rescaled to 0 to 1, where 0 indicates the lowest
level of wealth, and 1 the highest level of wealth. Place of residence
is coded 1 for urban and 0 for rural. Gender is coded 1 for female and 0
for male” (p. 64).
We proceed to recode variables “quintall”, “ed” and “q2” in variables
that vary between 0 and 1, called “wealth”, “educ” and “age”. Variables
“mujer” and “urban”, available in the dataset, are dichotomous
variables, so we do not have to recode.
lapop18$wealth = (lapop18$quintall - 1)/4
lapop18$educ = (lapop18$ed)/18
lapop18$age = (lapop18$q2 - 16)/83
summary(lapop18$wealth)
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## 0.0000 0.2500 0.5000 0.4935 0.7500 1.0000 423
summary(lapop18$educ)
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## 0.0000 0.3889 0.6111 0.5519 0.6667 1.0000 472
summary(lapop18$age)
## Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
## 0.0000 0.1205 0.2530 0.2891 0.4217 1.0000 16
With the command summary
we can evaluate if these
variables vary between 0 and 1. We should note that these variables have
missing values “NAs” that will not be included in calculations.
Logistic regression model
To evaluate factors associated to social media use, we can calculate
a regression model. In this case, different from the linear regression
model, the dependent variable is not of type numeric, but it is a
dichotomous variable, with value 0 to indicate not users and 1 to
identify social media users.
Linear regression models do not fit this type of variable. The
reasons are multiple. A linear regression to model the relationship
between a dichotomous dependent variables and an numeric independent
variable could results in predicted values higher than 1 o lower than 0.
So, it is not a good approach to calculate probabilities.
On the contrary, a logistic regression model restricts results
between 0 and 1, so we can interpret as a probability. In our example,
we calculate the probability of being a social media user for different
values of the independent variables.
Other reasons for not using a lineal regression model are more
technical and are related to residuals. If we use a linear regression
model to fit the relationship between a dichotomous dependent variable
and a numeric independent variable, the residuals would not be normally
distributed and would be heteroskedastic.
To calculate a model, we use the command glm
in which we
specify the variable Y and then the independent variables. Each
independent variable is summed to the model. The model in Figure 3.4
includes country fixed effects. In the section on multivariate
linear regression we explain the use of country fixed effects. Here,
we use the command factor()
to include dummy variables for
each country, taking Mexico (pais = 1) as reference.
This model is saved in an object “model1”. We can describe this model
with the command summary
.
model1 = glm(user ~ wealth + educ + age + mujer + urban + factor(pais), family = binomial, data=lapop18)
summary(model1)
##
## Call:
## glm(formula = user ~ wealth + educ + age + mujer + urban + factor(pais),
## family = binomial, data = lapop18)
##
## Deviance Residuals:
## Min 1Q Median 3Q Max
## -3.4629 -0.4583 0.2897 0.5852 2.9097
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -0.76385 0.09468 -8.068 7.15e-16 ***
## wealth 2.03825 0.05708 35.710 < 2e-16 ***
## educ 2.86594 0.09167 31.265 < 2e-16 ***
## age -5.69441 0.10458 -54.448 < 2e-16 ***
## mujer 0.14776 0.03556 4.155 3.25e-05 ***
## urban 0.74510 0.04060 18.353 < 2e-16 ***
## factor(pais)2 -0.20677 0.09583 -2.158 0.030965 *
## factor(pais)3 15.88183 85.89147 0.185 0.853303
## factor(pais)4 -0.26064 0.09604 -2.714 0.006649 **
## factor(pais)5 -0.54242 0.09522 -5.696 1.22e-08 ***
## factor(pais)6 1.92058 0.11207 17.137 < 2e-16 ***
## factor(pais)7 -0.44665 0.09503 -4.700 2.60e-06 ***
## factor(pais)8 0.51202 0.09770 5.241 1.60e-07 ***
## factor(pais)9 0.34890 0.10163 3.433 0.000597 ***
## factor(pais)10 0.09251 0.09715 0.952 0.340992
## factor(pais)11 -0.06467 0.09814 -0.659 0.509967
## factor(pais)12 0.88679 0.10191 8.702 < 2e-16 ***
## factor(pais)13 1.00887 0.10400 9.701 < 2e-16 ***
## factor(pais)14 1.89743 0.10781 17.600 < 2e-16 ***
## factor(pais)15 1.11293 0.10544 10.555 < 2e-16 ***
## factor(pais)17 1.41948 0.11000 12.905 < 2e-16 ***
## factor(pais)21 0.80326 0.10380 7.739 1.00e-14 ***
## factor(pais)23 0.54686 0.10213 5.354 8.58e-08 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 31852 on 26274 degrees of freedom
## Residual deviance: 20156 on 26252 degrees of freedom
## (1767 observations deleted due to missingness)
## AIC: 20202
##
## Number of Fisher Scoring iterations: 15
The results shows the coefficient, standard errors, the z statistic
and the linked p-value. With this information, we can conclude about the
direction of the relationship between each independent variable and the
dependent variable. For example, the relationship between wealth and the
probability of being a social media user is positive, indicating that
when wealth is higher, the probabilities of being a social media user
are higher. The relationship between age and the probability of being a
social media user is negative: when age is higher, there are less
probabilities of being a social media user. In both cases, we have
statistically significant relations because p-values are lower than
0.05.
The coefficients of the regression are interpreted as the change in
the log odds of the dependent variable for an unit change in the
independent variable. For example, for each additional year in age, the
log odds of being a social media user (versus not being a user)
decreases in 5.69.
Other way to present these coefficients is transforming them whit the
exponential function. In this way, we can interpret the results as a
rise in the probability in a factor according to this results.
With the following code, we can make this calculation for the main
independent variables, excluding the dummy variables for each
country.
exp(coef(model1)[1:6])
## (Intercept) wealth educ age mujer urban
## 0.465868370 7.677171277 17.565547484 0.003364729 1.159238630 2.106646383
In this manner, we can interpret that an increase of one unit in
wealth increases the probability of being a social media user in a
factor of 7.7. Because wealth was recoded to vary between 0 and 1, a
change of one unit is the maximum possible increase.
In the case of women, we can conclude that women have a 15.9% more
probabilities of being social media users than men.
To present the results more clearly, we can use several libraries and
commands. In this section we use the library jtools
and the
command summs
. This command brings statistics to evaluate
the model´s goodness of fit. For example, the statistic χ2 evaluates the
multivariate model versus the null model. Because we have a high
statistic and a p-value lower than 0.05, we conclude that the model fits
the data.
Other statistic is the Pseudo-\(R^2\), that we cannot interpret as the
determination coefficient in a lineal regression, it gives an idea of
the explanatory power of the model.
#library(stargazer)
#stargazer(modelo1[1:6], align=T, type = 'text')
library(jtools)
summ(model1)
## MODEL INFO:
## Observations: 26275 (1767 missing obs. deleted)
## Dependent Variable: user
## Type: Generalized linear model
## Family: binomial
## Link function: logit
##
## MODEL FIT:
## χ²(22) = 11696.30, p = 0.00
## Pseudo-R² (Cragg-Uhler) = 0.51
## Pseudo-R² (McFadden) = 0.37
## AIC = 20201.95, BIC = 20390.01
##
## Standard errors: MLE
## ----------------------------------------------------
## Est. S.E. z val. p
## -------------------- ------- ------- -------- ------
## (Intercept) -0.76 0.09 -8.07 0.00
## wealth 2.04 0.06 35.71 0.00
## educ 2.87 0.09 31.27 0.00
## age -5.69 0.10 -54.45 0.00
## mujer 0.15 0.04 4.16 0.00
## urban 0.75 0.04 18.35 0.00
## factor(pais)2 -0.21 0.10 -2.16 0.03
## factor(pais)3 15.88 85.89 0.18 0.85
## factor(pais)4 -0.26 0.10 -2.71 0.01
## factor(pais)5 -0.54 0.10 -5.70 0.00
## factor(pais)6 1.92 0.11 17.14 0.00
## factor(pais)7 -0.45 0.10 -4.70 0.00
## factor(pais)8 0.51 0.10 5.24 0.00
## factor(pais)9 0.35 0.10 3.43 0.00
## factor(pais)10 0.09 0.10 0.95 0.34
## factor(pais)11 -0.06 0.10 -0.66 0.51
## factor(pais)12 0.89 0.10 8.70 0.00
## factor(pais)13 1.01 0.10 9.70 0.00
## factor(pais)14 1.90 0.11 17.60 0.00
## factor(pais)15 1.11 0.11 10.56 0.00
## factor(pais)17 1.42 0.11 12.90 0.00
## factor(pais)21 0.80 0.10 7.74 0.00
## factor(pais)23 0.55 0.10 5.35 0.00
## ----------------------------------------------------
Figure 3.4 shows the coefficients for each variable and the 95%
confidence interval. A vertical line is included at point 0. If a
confidence interval crosses this vertical line, we can say that it does
not have a statistically significant relationship with the dependent
variable of being a social media user. Confidence intervals that do not
cross this line and that lie to the right (left) of this line have a
positive (negative) relationship with social media user, that is, when
this variable increases, the probability of being a social media user
increases (decreases). In this example, all five variables are
statistically significant and four show a positive relationship with
being a social media user. Age is the only independent variable that has
a negative relationship with being a social media user.
library(jtools)
plot_summs(model1, coefs=c("Level of wealth"="wealth", "Years of education"="educ",
"Age"="age", "Women"="mujer", "Urban area"="urban"))
This plot is similar and has the same tendencies as Figure 3.4.
However, it does not show the same results because, as the report
indicates “The dots in Figure 4 are the predicted changes in the
probability of the dependent variable taking on the value of”1” (social
media user), given a change from the minimum to maximum value on the
independent variable” (p. 59). In the figure above, we present the
coefficients of the logistic regression.
Summary
In this section, we have used a logistic regression to model the
relationship between independent variables and a dichotomous dependent
variable. In particular, we have presented a model with five predictors
of being a social media user. This model has been presented in a
standard way in a table of results and also with a plot similar to
Figure 3.4 in the report.
Including survey weights
The calculations made do not include the survey weights. An
introduction to the use of the survey weights was made here.
In this part we will use the library survey
.
We will use the command svydesign
(similar to the
command svyset in STATA). With this command, we create a new object
called “design18”, which saves the information of the variables
contained in the dataframe, including the survey weights in the
calculations. Therefore, if a new variable is created later, this
command would have to be calculated again so that this object “design18”
includes this new variable.
library(survey)
design18 = svydesign(ids = ~upm, strata = ~estratopri, weights = ~weight1500, nest=TRUE, data=lapop18)
The library survey
includes the command
svyglm
that allows to compute a logistic regression model.
We can include the same variables used in model 1 in this command. We
have to specify the design that is used and the treatment of missing
values. This calculation is saved in a object “model2”. The command
summ
from the library jtools
is used to
describe the model.
model2 = svyglm(user ~ wealth + educ + age + mujer + urban + factor(pais), family=quasibinomial, design=design18, na.action = na.omit)
summ(model2)
## MODEL INFO:
## Observations: 26275
## Dependent Variable: user
## Type: Analysis of complex survey design
## Family: quasibinomial
## Link function: logit
##
## MODEL FIT:
## Pseudo-R² (Cragg-Uhler) = 0.51
## Pseudo-R² (McFadden) = 0.37
## AIC = NA
##
## ---------------------------------------------------
## Est. S.E. t val. p
## -------------------- ------- ------ -------- ------
## (Intercept) -0.76 0.10 -7.37 0.00
## wealth 2.03 0.06 33.27 0.00
## educ 2.86 0.09 30.20 0.00
## age -5.69 0.11 -53.54 0.00
## mujer 0.15 0.04 4.33 0.00
## urban 0.75 0.05 15.81 0.00
## factor(pais)2 -0.21 0.11 -1.80 0.07
## factor(pais)3 15.89 0.15 103.41 0.00
## factor(pais)4 -0.26 0.09 -2.75 0.01
## factor(pais)5 -0.54 0.11 -5.03 0.00
## factor(pais)6 1.92 0.14 13.65 0.00
## factor(pais)7 -0.45 0.13 -3.56 0.00
## factor(pais)8 0.51 0.11 4.78 0.00
## factor(pais)9 0.35 0.11 3.27 0.00
## factor(pais)10 0.09 0.11 0.88 0.38
## factor(pais)11 -0.06 0.11 -0.59 0.55
## factor(pais)12 0.89 0.10 8.56 0.00
## factor(pais)13 1.01 0.11 8.81 0.00
## factor(pais)14 1.90 0.12 16.04 0.00
## factor(pais)15 1.16 0.13 9.27 0.00
## factor(pais)17 1.42 0.12 11.55 0.00
## factor(pais)21 0.80 0.12 6.93 0.00
## factor(pais)23 0.55 0.11 4.82 0.00
## ---------------------------------------------------
##
## Estimated dispersion parameter = 1.01
In the same way as with model 1, these results can also be plotted
using the command plot_summs
, selecting the variables to
display.
plot_summs(model2, coefs=c("Level of wealth"="wealth", "Years of education"="educ",
"Age"="age", "Mujer"="mujer", "Urban area"="urban"))
This plot is similar to the one reported in Figure 3.4. Differences
are due to the fact that this plot shows the coefficients whereas Figure
3.4 shows predicted changes in the probability of the dependent
variable.
LS0tCnRpdGxlOiAiTG9naXN0aWMgcmVncmVzc2lvbiB1c2luZyB0aGUgQW1lcmljYXNCYXJvbWV0ZXIiCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6IHRydWUKICAgIGNvbGxhcHNlZDogZmFsc2UKICAgIG51bWJlcl9zZWN0aW9uczogZmFsc2UKICAgIHRvY19kZXB0aDogMQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQogICAgdGhlbWU6IGZsYXRseQogICAgZGZfcHJpbnQ6IHBhZ2VkCiAgICBzZWxmX2NvbnRhaW5lZDogbm8KICAgIGtlZXBfbWQ6IHllcwplZGl0b3Jfb3B0aW9uczogCiAgbWFya2Rvd246IAogICAgd3JhcDogc2VudGVuY2UKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKQpgYGAKCiMgSW50cm9kdWN0aW9uCgpJbiB0aGlzIHNlY3Rpb24sIHdlIHdpbGwgc2VlIGJhc2ljIGFzcGVjdHMgb2YgdGhlIGxvZ2lzdGljIG1vZGVsIHRvIGFuYWx5emUgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIGEgYmluYXJ5IGRlcGVuZGVudCB2YXJpYWJsZSBhbmQgYW4gaW5kZXBlbmRlbnQgdmFyaWFibGUuCgpXZSBjb250aW51ZSB0byByZXBsaWNhdGUgdGhlIGFuYWx5c2lzIG9mIGNoYXB0ZXIgIlNvY2lhbCBuZXR3b3JrcyBhbmQgcG9saXRpY2FsIGF0dGl0dWRlcyIgZnJvbSB0aGUgcmVwb3J0IFtUaGUgUHVsc2Ugb2YgRGVtb2NyYWN5XShodHRwczovL3d3dy52YW5kZXJiaWx0LmVkdS9sYXBvcC9hYjIwMTgvMjAxOC0xOV9BbWVyaWNhc0Jhcm9tZXRlcl9SZWdpb25hbF9SZXBvcnRfMTAuMTMuMTkucGRmKSBvZiB0aGUgMjAxOC8xOSByb3VuZC4KSW4gdGhpcyBjaGFwdGVyLCB3ZSBhbmFseXplIGEgbWVhc3VyZSBvZiBzdXBwb3J0IGZvciBkZW1vY3JhY3kuCgojIEFib3V0IHRoZSBkYXRhc2V0CgpUaGUgZGF0YSB3ZSBhcmUgZ29pbmcgdG8gdXNlIHNob3VsZCBiZSBjaXRlZCBhcyBmb2xsb3dzOiBTb3VyY2U6IEFtZXJpY2FzQmFyb21ldGVyIGJ5IHRoZSBMYXRpbiBBbWVyaWNhbiBQdWJsaWMgT3BpbmlvbiBQcm9qZWN0IChMQVBPUCksIHd3d3cuTGFwb3BTdXJ2ZXlzLm9yZy4KWW91IGNhbiBkb3dubG9hZCB0aGUgZGF0YSBmcmVlbHkgW2hlcmVdKGh0dHA6Ly9kYXRhc2V0cy5hbWVyaWNhc2Jhcm9tZXRlci5vcmcvZGF0YWJhc2UvbG9naW4ucGhwKS4KCkl0IGlzIHJlY29tbWVuZGVkIHRvIGNsZWFuIHRoZSBFbnZpcm9ubWVudCBiZWZvcmUgc3RhcnRpbmcgdGhpcyBzZWN0aW9uLgpJbiB0aGlzIGRvY3VtZW50LCBhIGRhdGFiYXNlIGluIFJEYXRhIGZvcm1hdCBpcyBhZ2FpbiBsb2FkZWQuClRoaXMgZm9ybWF0IGlzIGVmZmljaWVudCBpbiB0ZXJtcyBvZiBzdG9yYWdlIHNwYWNlLgpUaGlzIGRhdGFiYXNlIGlzIGhvc3RlZCBpbiB0aGUgIm1hdGVyaWFsc19lZHUiIHJlcG9zaXRvcnkgb2YgdGhlIExBUE9QIGFjY291bnQgb24gR2l0SHViLgpVc2luZyB0aGUgYHJpb2AgbGlicmFyeSBhbmQgdGhlIGBpbXBvcnRgIGNvbW1hbmQsIHlvdSBjYW4gaW1wb3J0IHRoaXMgZGF0YWJhc2UgZnJvbSB0aGlzIHJlcG9zaXRvcnksIHVzaW5nIHRoZSBmb2xsb3dpbmcgY29kZS4KCmBgYHtyIGJhc2UsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmxpYnJhcnkocmlvKQpsYXBvcDE4ID0gaW1wb3J0KCJodHRwczovL3Jhdy5naXRodWIuY29tL2xhcG9wLWNlbnRyYWwvbWF0ZXJpYWxzX2VkdS9tYWluL2xhcG9wMTguUkRhdGEiKQpsYXBvcDE4ID0gc3Vic2V0KGxhcG9wMTgsIHBhaXM8PTM1KQpgYGAKCiMgRGV0ZXJtaW5hbnRzIG9mIHVzZSBvZiBzb2NpYWwgbmV0d29ya3MKClRoZSBzZWN0aW9uIGFib3V0IHNvY2lhbCBuZXR3b3JrcyBwcmVzZW50cyByZXN1bHRzIG9mIGEgbG9naXN0aWMgcmVncmVzc2lvbiBtb2RlbCBpbiBGaWd1cmUgMy40LgpBcyByZXBvcnQgc2F5cywgdGhpcyBmaWd1cmUgInNob3dzIHRoZSByZXN1bHRzIG9mIGEgbG9naXN0aWMgcmVncmVzc2lvbiBhbmFseXNpcyB0aGF0IHJlZ3Jlc3MgaGlnaCB1c2Ugb2Ygc29jaWFsIG1lZGlhICh2cy4gbG93IHVzZSkgb24gdGhlIHNhbWUgc2V0IG9mIGRlbW9ncmFwaGljIGFuZCBzb2Npb2Vjb25vbWljIGZhY3RvcnMiIChwLiA1OSkuCgohW10oRmlndXJlMy40LnBuZyl7d2lkdGg9IjQwOSJ9CgpBcyB0aGUgcmVwb3J0IGFsc28gaW5kaWNhdGVzICJ0aGUgZGVwZW5kZW50IHZhcmlhYmxlLCAqU29jaWFsIE1lZGlhIFVzZXIqLCBpcyBiYXNlZCBvbiByZXNwb25zZXMgdG8gdGhlIHRocmVlIHF1ZXN0aW9ucyBhYm91dCBob2xkaW5nIGFjY291bnRzIGZyb20gRmFjZWJvb2ssIFR3aXR0ZXIsIGFuZCBXaGF0c2FwcC4gVGhpcyBkaWNob3RvbW91cyBtZWFzdXJlIGRpc3Rpbmd1aXNoZXMgYmV0d2VlbiB0aG9zZSBpbmRpdmlkdWFscyB3aG8gdXNlIGFjY291bnRzIGZyb20gb25lIG9yIG1vcmUgb2YgdGhlc2UgcGxhdGZvcm1zLCBjb21wYXJlZCB0byB0aG9zZSB3aG8gZG8gbm90IGVuZ2FuZSB3aXRoIGFueSBzb2NpYWwgbWVkaWEgYWNjb3VudCIgKHAuIDU5KS4KCkluIHRoZSBzZWN0aW9uIG9uIFtkZXNjcmlwdGl2ZSBzdGF0aXN0aWNzXShodHRwczovL2FydHVyb21hbGRvbmFkby5naXRodWIuaW8vQmFyb21ldHJvRWR1X1dlYl9FbmcvRGVzY3JpcHRpdmVzLmh0bWwpIHdlIHByZXNlbnQgdGhlIGNvZGUgdG8gY3JlYXRlIHVzZXJzIG9mIGVhY2ggc29jaWFsIG5ldHdvcmsgdXNpbmcgdGhlIGNvbW1hbmRgaWZlbHNlYC4KCmBgYHtyIHVzZXJzfQpsYXBvcDE4JGZiX3VzZXIgPSBpZmVsc2UobGFwb3AxOCRzbWVkaWExPT0xICYgbGFwb3AxOCRzbWVkaWEyPD00LCAxLCAwKQpsYXBvcDE4JHR3X3VzZXIgPSBpZmVsc2UobGFwb3AxOCRzbWVkaWE0PT0xICYgbGFwb3AxOCRzbWVkaWE1PD00LCAxLCAwKQpsYXBvcDE4JHdhX3VzZXIgPSBpZmVsc2UobGFwb3AxOCRzbWVkaWE3PT0xICYgbGFwb3AxOCRzbWVkaWE4PD00LCAxLCAwKQpgYGAKCkJhc2VkIG9uIHRoZXNlIHZhcmlhYmxlcywgd2UgY3JlYXRlIGEgdmFyaWFibGUgZm9yIHVzZXJzIG9mIGFueSBzb2NpYWwgbmV0d29yay4KVGhpcyBkaWNob3RvbW91cyB2YXJpYWJsZSBoYXMgYSB2YWx1ZSBvZiAxIGlmIGludGVydmlld2VlIHJlcG9ydHMgYmVpbmcgdXNlciBvZiBhbnkgc29jaWFsIG5ldHdvcmsgaW4gdGhlIHF1ZXN0aW9ubmFpcmUgKEZhY2Vib29rIG9yIFR3aXR0ZXIgb3IgV2hhdHNhcHApLgoKYGBge3IgdXNlcmFueX0KbGFwb3AxOCR1c2VyID0gaWZlbHNlKGxhcG9wMTgkZmJfdXNlcj09MSB8IGxhcG9wMTgkd2FfdXNlcj09MSB8IGxhcG9wMTgkdHdfdXNlciA9PTEsIDEsIDApCnRhYmxlKGxhcG9wMTgkdXNlcikKYGBgCgpGaWd1cmUgMy40IHNob3dzIHRoZSBkZXRlcm1pbmFudHMgb2Ygc29jaWFsIG1lZGlhIHVzZS4KVGhlc2UgdmFyaWFibGVzIGFyZToKCi0gICBMZXZlbCBvZiB3ZWFsdGg6IHZhcmlhYmxlICJxdWludGFsbCIgaW4gdGhlIGRhdGFzZXQuCgotICAgWWVhcnMgb2YgZWR1Y2F0aW9uOiB2YXJpYWJsZSAiZWQiIGluIHRoZSBkYXRhc2V0LgoKLSAgIEFnZTogdmFyaWFibGUgInEyIiBpbiB0aGUgZGF0YXNldC4KCi0gICBGZW1hbGU6IHZhcmlhYmxlICJtdWplciIgaW4gdGhlIGRhdGFzZXQuCgotICAgVXJiYW4gYXJlYTogdmFyaWFibGUgInVyIiBpbiB0aGUgZGF0YXNldC4KCkZvb3Rub3RlIDE2IGluZGljYXRlcyB0aGF0ICJBZ2UgYW5kIGVkdWNhdGlvbiBhcmUgbWVhc3VyZWQgaW4geWVhcnMsIHJlc2NhbGVkIHRvIDAgdG8gMSwgd2hlcmUgMCBpbmRpY2F0ZXMgdGhlIHlvdW5nZXN0IG9yIHRoZSBsb3dlc3QgbGV2ZWwgb2YgZWR1Y2F0aW9uLCBhbmQgMSB0aGUgb2xkZXN0IG9yIHRoZSBoaWdoZXN0IGxldmVsIG9mIGVkdWNhdGlvbi4gV2VhbHRoIGlzIGFuIG9yZGluYWwgdmFyaWFibGUsIHJlc2NhbGVkIHRvIDAgdG8gMSwgd2hlcmUgMCBpbmRpY2F0ZXMgdGhlIGxvd2VzdCBsZXZlbCBvZiB3ZWFsdGgsIGFuZCAxIHRoZSBoaWdoZXN0IGxldmVsIG9mIHdlYWx0aC4gUGxhY2Ugb2YgcmVzaWRlbmNlIGlzIGNvZGVkIDEgZm9yIHVyYmFuIGFuZCAwIGZvciBydXJhbC4gR2VuZGVyIGlzIGNvZGVkIDEgZm9yIGZlbWFsZSBhbmQgMCBmb3IgbWFsZSIgKHAuIDY0KS4KCldlIHByb2NlZWQgdG8gcmVjb2RlIHZhcmlhYmxlcyAicXVpbnRhbGwiLCAiZWQiIGFuZCAicTIiIGluIHZhcmlhYmxlcyB0aGF0IHZhcnkgYmV0d2VlbiAwIGFuZCAxLCBjYWxsZWQgIndlYWx0aCIsICJlZHVjIiBhbmQgImFnZSIuClZhcmlhYmxlcyAibXVqZXIiIGFuZCAidXJiYW4iLCBhdmFpbGFibGUgaW4gdGhlIGRhdGFzZXQsIGFyZSBkaWNob3RvbW91cyB2YXJpYWJsZXMsIHNvIHdlIGRvIG5vdCBoYXZlIHRvIHJlY29kZS4KCmBgYHtyIHJlY29kZX0KbGFwb3AxOCR3ZWFsdGggPSAobGFwb3AxOCRxdWludGFsbCAtIDEpLzQKbGFwb3AxOCRlZHVjID0gKGxhcG9wMTgkZWQpLzE4CmxhcG9wMTgkYWdlID0gKGxhcG9wMTgkcTIgLSAxNikvODMKc3VtbWFyeShsYXBvcDE4JHdlYWx0aCkKc3VtbWFyeShsYXBvcDE4JGVkdWMpCnN1bW1hcnkobGFwb3AxOCRhZ2UpCmBgYAoKV2l0aCB0aGUgY29tbWFuZCBgc3VtbWFyeWAgd2UgY2FuIGV2YWx1YXRlIGlmIHRoZXNlIHZhcmlhYmxlcyB2YXJ5IGJldHdlZW4gMCBhbmQgMS4KV2Ugc2hvdWxkIG5vdGUgdGhhdCB0aGVzZSB2YXJpYWJsZXMgaGF2ZSBtaXNzaW5nIHZhbHVlcyAiTkFzIiB0aGF0IHdpbGwgbm90IGJlIGluY2x1ZGVkIGluIGNhbGN1bGF0aW9ucy4KCiMgTG9naXN0aWMgcmVncmVzc2lvbiBtb2RlbAoKVG8gZXZhbHVhdGUgZmFjdG9ycyBhc3NvY2lhdGVkIHRvIHNvY2lhbCBtZWRpYSB1c2UsIHdlIGNhbiBjYWxjdWxhdGUgYSByZWdyZXNzaW9uIG1vZGVsLgpJbiB0aGlzIGNhc2UsIGRpZmZlcmVudCBmcm9tIHRoZSBsaW5lYXIgcmVncmVzc2lvbiBtb2RlbCwgdGhlIGRlcGVuZGVudCB2YXJpYWJsZSBpcyBub3Qgb2YgdHlwZSBudW1lcmljLCBidXQgaXQgaXMgYSBkaWNob3RvbW91cyB2YXJpYWJsZSwgd2l0aCB2YWx1ZSAwIHRvIGluZGljYXRlIG5vdCB1c2VycyBhbmQgMSB0byBpZGVudGlmeSBzb2NpYWwgbWVkaWEgdXNlcnMuCgpMaW5lYXIgcmVncmVzc2lvbiBtb2RlbHMgZG8gbm90IGZpdCB0aGlzIHR5cGUgb2YgdmFyaWFibGUuClRoZSByZWFzb25zIGFyZSBtdWx0aXBsZS4KQSBsaW5lYXIgcmVncmVzc2lvbiB0byBtb2RlbCB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gYSBkaWNob3RvbW91cyBkZXBlbmRlbnQgdmFyaWFibGVzIGFuZCBhbiBudW1lcmljIGluZGVwZW5kZW50IHZhcmlhYmxlIGNvdWxkIHJlc3VsdHMgaW4gcHJlZGljdGVkIHZhbHVlcyBoaWdoZXIgdGhhbiAxIG8gbG93ZXIgdGhhbiAwLgpTbywgaXQgaXMgbm90IGEgZ29vZCBhcHByb2FjaCB0byBjYWxjdWxhdGUgcHJvYmFiaWxpdGllcy4KCk9uIHRoZSBjb250cmFyeSwgYSBsb2dpc3RpYyByZWdyZXNzaW9uIG1vZGVsIHJlc3RyaWN0cyByZXN1bHRzIGJldHdlZW4gMCBhbmQgMSwgc28gd2UgY2FuIGludGVycHJldCBhcyBhIHByb2JhYmlsaXR5LgpJbiBvdXIgZXhhbXBsZSwgd2UgY2FsY3VsYXRlIHRoZSBwcm9iYWJpbGl0eSBvZiBiZWluZyBhIHNvY2lhbCBtZWRpYSB1c2VyIGZvciBkaWZmZXJlbnQgdmFsdWVzIG9mIHRoZSBpbmRlcGVuZGVudCB2YXJpYWJsZXMuCgpPdGhlciByZWFzb25zIGZvciBub3QgdXNpbmcgYSBsaW5lYWwgcmVncmVzc2lvbiBtb2RlbCBhcmUgbW9yZSB0ZWNobmljYWwgYW5kIGFyZSByZWxhdGVkIHRvIHJlc2lkdWFscy4KSWYgd2UgdXNlIGEgbGluZWFyIHJlZ3Jlc3Npb24gbW9kZWwgdG8gZml0IHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBhIGRpY2hvdG9tb3VzIGRlcGVuZGVudCB2YXJpYWJsZSBhbmQgYSBudW1lcmljIGluZGVwZW5kZW50IHZhcmlhYmxlLCB0aGUgcmVzaWR1YWxzIHdvdWxkIG5vdCBiZSBub3JtYWxseSBkaXN0cmlidXRlZCBhbmQgd291bGQgYmUgaGV0ZXJvc2tlZGFzdGljLgoKVG8gY2FsY3VsYXRlIGEgbW9kZWwsIHdlIHVzZSB0aGUgY29tbWFuZCBgZ2xtYCBpbiB3aGljaCB3ZSBzcGVjaWZ5IHRoZSB2YXJpYWJsZSBZIGFuZCB0aGVuIHRoZSBpbmRlcGVuZGVudCB2YXJpYWJsZXMuCkVhY2ggaW5kZXBlbmRlbnQgdmFyaWFibGUgaXMgc3VtbWVkIHRvIHRoZSBtb2RlbC4KVGhlIG1vZGVsIGluIEZpZ3VyZSAzLjQgaW5jbHVkZXMgY291bnRyeSBmaXhlZCBlZmZlY3RzLgpJbiB0aGUgc2VjdGlvbiBvbiBbbXVsdGl2YXJpYXRlIGxpbmVhciByZWdyZXNzaW9uXShodHRwczovL2FydHVyb21hbGRvbmFkby5naXRodWIuaW8vQmFyb21ldHJvRWR1X1dlYl9FbmcvcmVncmVzaW9uMi5odG1sKSB3ZSBleHBsYWluIHRoZSB1c2Ugb2YgY291bnRyeSBmaXhlZCBlZmZlY3RzLgpIZXJlLCB3ZSB1c2UgdGhlIGNvbW1hbmQgYGZhY3RvcigpYCB0byBpbmNsdWRlIGR1bW15IHZhcmlhYmxlcyBmb3IgZWFjaCBjb3VudHJ5LCB0YWtpbmcgTWV4aWNvIChwYWlzID0gMSkgYXMgcmVmZXJlbmNlLgoKVGhpcyBtb2RlbCBpcyBzYXZlZCBpbiBhbiBvYmplY3QgIm1vZGVsMSIuCldlIGNhbiBkZXNjcmliZSB0aGlzIG1vZGVsIHdpdGggdGhlIGNvbW1hbmQgYHN1bW1hcnlgLgoKYGBge3IgbW9kZWx9Cm1vZGVsMSA9IGdsbSh1c2VyIH4gd2VhbHRoICsgZWR1YyArIGFnZSArIG11amVyICsgdXJiYW4gKyBmYWN0b3IocGFpcyksIGZhbWlseSA9IGJpbm9taWFsLCBkYXRhPWxhcG9wMTgpCnN1bW1hcnkobW9kZWwxKQpgYGAKClRoZSByZXN1bHRzIHNob3dzIHRoZSBjb2VmZmljaWVudCwgc3RhbmRhcmQgZXJyb3JzLCB0aGUgeiBzdGF0aXN0aWMgYW5kIHRoZSBsaW5rZWQgcC12YWx1ZS4KV2l0aCB0aGlzIGluZm9ybWF0aW9uLCB3ZSBjYW4gY29uY2x1ZGUgYWJvdXQgdGhlIGRpcmVjdGlvbiBvZiB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gZWFjaCBpbmRlcGVuZGVudCB2YXJpYWJsZSBhbmQgdGhlIGRlcGVuZGVudCB2YXJpYWJsZS4KRm9yIGV4YW1wbGUsIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiB3ZWFsdGggYW5kIHRoZSBwcm9iYWJpbGl0eSBvZiBiZWluZyBhIHNvY2lhbCBtZWRpYSB1c2VyIGlzIHBvc2l0aXZlLCBpbmRpY2F0aW5nIHRoYXQgd2hlbiB3ZWFsdGggaXMgaGlnaGVyLCB0aGUgcHJvYmFiaWxpdGllcyBvZiBiZWluZyBhIHNvY2lhbCBtZWRpYSB1c2VyIGFyZSBoaWdoZXIuClRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBhZ2UgYW5kIHRoZSBwcm9iYWJpbGl0eSBvZiBiZWluZyBhIHNvY2lhbCBtZWRpYSB1c2VyIGlzIG5lZ2F0aXZlOiB3aGVuIGFnZSBpcyBoaWdoZXIsIHRoZXJlIGFyZSBsZXNzIHByb2JhYmlsaXRpZXMgb2YgYmVpbmcgYSBzb2NpYWwgbWVkaWEgdXNlci4KSW4gYm90aCBjYXNlcywgd2UgaGF2ZSBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50IHJlbGF0aW9ucyBiZWNhdXNlIHAtdmFsdWVzIGFyZSBsb3dlciB0aGFuIDAuMDUuCgpUaGUgY29lZmZpY2llbnRzIG9mIHRoZSByZWdyZXNzaW9uIGFyZSBpbnRlcnByZXRlZCBhcyB0aGUgY2hhbmdlIGluIHRoZSBsb2cgb2RkcyBvZiB0aGUgZGVwZW5kZW50IHZhcmlhYmxlIGZvciBhbiB1bml0IGNoYW5nZSBpbiB0aGUgaW5kZXBlbmRlbnQgdmFyaWFibGUuCkZvciBleGFtcGxlLCBmb3IgZWFjaCBhZGRpdGlvbmFsIHllYXIgaW4gYWdlLCB0aGUgbG9nIG9kZHMgb2YgYmVpbmcgYSBzb2NpYWwgbWVkaWEgdXNlciAodmVyc3VzIG5vdCBiZWluZyBhIHVzZXIpIGRlY3JlYXNlcyBpbiA1LjY5LgoKT3RoZXIgd2F5IHRvIHByZXNlbnQgdGhlc2UgY29lZmZpY2llbnRzIGlzIHRyYW5zZm9ybWluZyB0aGVtIHdoaXQgdGhlIGV4cG9uZW50aWFsIGZ1bmN0aW9uLgpJbiB0aGlzIHdheSwgd2UgY2FuIGludGVycHJldCB0aGUgcmVzdWx0cyBhcyBhIHJpc2UgaW4gdGhlIHByb2JhYmlsaXR5IGluIGEgZmFjdG9yIGFjY29yZGluZyB0byB0aGlzIHJlc3VsdHMuCgpXaXRoIHRoZSBmb2xsb3dpbmcgY29kZSwgd2UgY2FuIG1ha2UgdGhpcyBjYWxjdWxhdGlvbiBmb3IgdGhlIG1haW4gaW5kZXBlbmRlbnQgdmFyaWFibGVzLCBleGNsdWRpbmcgdGhlIGR1bW15IHZhcmlhYmxlcyBmb3IgZWFjaCBjb3VudHJ5LgoKYGBge3Igb2Rkc30KZXhwKGNvZWYobW9kZWwxKVsxOjZdKQpgYGAKCkluIHRoaXMgbWFubmVyLCB3ZSBjYW4gaW50ZXJwcmV0IHRoYXQgYW4gaW5jcmVhc2Ugb2Ygb25lIHVuaXQgaW4gd2VhbHRoIGluY3JlYXNlcyB0aGUgcHJvYmFiaWxpdHkgb2YgYmVpbmcgYSBzb2NpYWwgbWVkaWEgdXNlciBpbiBhIGZhY3RvciBvZiA3LjcuCkJlY2F1c2Ugd2VhbHRoIHdhcyByZWNvZGVkIHRvIHZhcnkgYmV0d2VlbiAwIGFuZCAxLCBhIGNoYW5nZSBvZiBvbmUgdW5pdCBpcyB0aGUgbWF4aW11bSBwb3NzaWJsZSBpbmNyZWFzZS4KCkluIHRoZSBjYXNlIG9mIHdvbWVuLCB3ZSBjYW4gY29uY2x1ZGUgdGhhdCB3b21lbiBoYXZlIGEgMTUuOSUgbW9yZSBwcm9iYWJpbGl0aWVzIG9mIGJlaW5nIHNvY2lhbCBtZWRpYSB1c2VycyB0aGFuIG1lbi4KClRvIHByZXNlbnQgdGhlIHJlc3VsdHMgbW9yZSBjbGVhcmx5LCB3ZSBjYW4gdXNlIHNldmVyYWwgbGlicmFyaWVzIGFuZCBjb21tYW5kcy4KSW4gdGhpcyBzZWN0aW9uIHdlIHVzZSB0aGUgbGlicmFyeSBganRvb2xzYCBhbmQgdGhlIGNvbW1hbmQgYHN1bW1zYC4KVGhpcyBjb21tYW5kIGJyaW5ncyBzdGF0aXN0aWNzIHRvIGV2YWx1YXRlIHRoZSBtb2RlbMK0cyBnb29kbmVzcyBvZiBmaXQuCkZvciBleGFtcGxlLCB0aGUgc3RhdGlzdGljIM+HMiBldmFsdWF0ZXMgdGhlIG11bHRpdmFyaWF0ZSBtb2RlbCB2ZXJzdXMgdGhlIG51bGwgbW9kZWwuCkJlY2F1c2Ugd2UgaGF2ZSBhIGhpZ2ggc3RhdGlzdGljIGFuZCBhIHAtdmFsdWUgbG93ZXIgdGhhbiAwLjA1LCB3ZSBjb25jbHVkZSB0aGF0IHRoZSBtb2RlbCBmaXRzIHRoZSBkYXRhLgoKT3RoZXIgc3RhdGlzdGljIGlzIHRoZSBQc2V1ZG8tJFJeMiQsIHRoYXQgd2UgY2Fubm90IGludGVycHJldCBhcyB0aGUgZGV0ZXJtaW5hdGlvbiBjb2VmZmljaWVudCBpbiBhIGxpbmVhbCByZWdyZXNzaW9uLCBpdCBnaXZlcyBhbiBpZGVhIG9mIHRoZSBleHBsYW5hdG9yeSBwb3dlciBvZiB0aGUgbW9kZWwuCgpgYGB7ciB0YWJsZX0KI2xpYnJhcnkoc3RhcmdhemVyKQojc3RhcmdhemVyKG1vZGVsbzFbMTo2XSwgYWxpZ249VCwgdHlwZSA9ICd0ZXh0JykKbGlicmFyeShqdG9vbHMpCnN1bW0obW9kZWwxKQpgYGAKCkZpZ3VyZSAzLjQgc2hvd3MgdGhlIGNvZWZmaWNpZW50cyBmb3IgZWFjaCB2YXJpYWJsZSBhbmQgdGhlIDk1JSBjb25maWRlbmNlIGludGVydmFsLgpBIHZlcnRpY2FsIGxpbmUgaXMgaW5jbHVkZWQgYXQgcG9pbnQgMC4KSWYgYSBjb25maWRlbmNlIGludGVydmFsIGNyb3NzZXMgdGhpcyB2ZXJ0aWNhbCBsaW5lLCB3ZSBjYW4gc2F5IHRoYXQgaXQgZG9lcyBub3QgaGF2ZSBhIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQgcmVsYXRpb25zaGlwIHdpdGggdGhlIGRlcGVuZGVudCB2YXJpYWJsZSBvZiBiZWluZyBhIHNvY2lhbCBtZWRpYSB1c2VyLgpDb25maWRlbmNlIGludGVydmFscyB0aGF0IGRvIG5vdCBjcm9zcyB0aGlzIGxpbmUgYW5kIHRoYXQgbGllIHRvIHRoZSByaWdodCAobGVmdCkgb2YgdGhpcyBsaW5lIGhhdmUgYSBwb3NpdGl2ZSAobmVnYXRpdmUpIHJlbGF0aW9uc2hpcCB3aXRoIHNvY2lhbCBtZWRpYSB1c2VyLCB0aGF0IGlzLCB3aGVuIHRoaXMgdmFyaWFibGUgaW5jcmVhc2VzLCB0aGUgcHJvYmFiaWxpdHkgb2YgYmVpbmcgYSBzb2NpYWwgbWVkaWEgdXNlciBpbmNyZWFzZXMgKGRlY3JlYXNlcykuCkluIHRoaXMgZXhhbXBsZSwgYWxsIGZpdmUgdmFyaWFibGVzIGFyZSBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50IGFuZCBmb3VyIHNob3cgYSBwb3NpdGl2ZSByZWxhdGlvbnNoaXAgd2l0aCBiZWluZyBhIHNvY2lhbCBtZWRpYSB1c2VyLgpBZ2UgaXMgdGhlIG9ubHkgaW5kZXBlbmRlbnQgdmFyaWFibGUgdGhhdCBoYXMgYSBuZWdhdGl2ZSByZWxhdGlvbnNoaXAgd2l0aCBiZWluZyBhIHNvY2lhbCBtZWRpYSB1c2VyLgoKYGBge3IgcGxvdCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KbGlicmFyeShqdG9vbHMpCnBsb3Rfc3VtbXMobW9kZWwxLCBjb2Vmcz1jKCJMZXZlbCBvZiB3ZWFsdGgiPSJ3ZWFsdGgiLCAiWWVhcnMgb2YgZWR1Y2F0aW9uIj0iZWR1YyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQWdlIj0iYWdlIiwgIldvbWVuIj0ibXVqZXIiLCAiVXJiYW4gYXJlYSI9InVyYmFuIikpCmBgYAoKVGhpcyBwbG90IGlzIHNpbWlsYXIgYW5kIGhhcyB0aGUgc2FtZSB0ZW5kZW5jaWVzIGFzIEZpZ3VyZSAzLjQuCkhvd2V2ZXIsIGl0IGRvZXMgbm90IHNob3cgdGhlIHNhbWUgcmVzdWx0cyBiZWNhdXNlLCBhcyB0aGUgcmVwb3J0IGluZGljYXRlcyAiVGhlIGRvdHMgaW4gRmlndXJlIDQgYXJlIHRoZSBwcmVkaWN0ZWQgY2hhbmdlcyBpbiB0aGUgcHJvYmFiaWxpdHkgb2YgdGhlIGRlcGVuZGVudCB2YXJpYWJsZSB0YWtpbmcgb24gdGhlIHZhbHVlIG9mIjEiIChzb2NpYWwgbWVkaWEgdXNlciksIGdpdmVuIGEgY2hhbmdlIGZyb20gdGhlIG1pbmltdW0gdG8gbWF4aW11bSB2YWx1ZSBvbiB0aGUgaW5kZXBlbmRlbnQgdmFyaWFibGUiIChwLiA1OSkuCkluIHRoZSBmaWd1cmUgYWJvdmUsIHdlIHByZXNlbnQgdGhlIGNvZWZmaWNpZW50cyBvZiB0aGUgbG9naXN0aWMgcmVncmVzc2lvbi4KCiMgU3VtbWFyeQoKSW4gdGhpcyBzZWN0aW9uLCB3ZSBoYXZlIHVzZWQgYSBsb2dpc3RpYyByZWdyZXNzaW9uIHRvIG1vZGVsIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBpbmRlcGVuZGVudCB2YXJpYWJsZXMgYW5kIGEgZGljaG90b21vdXMgZGVwZW5kZW50IHZhcmlhYmxlLgpJbiBwYXJ0aWN1bGFyLCB3ZSBoYXZlIHByZXNlbnRlZCBhIG1vZGVsIHdpdGggZml2ZSBwcmVkaWN0b3JzIG9mIGJlaW5nIGEgc29jaWFsIG1lZGlhIHVzZXIuClRoaXMgbW9kZWwgaGFzIGJlZW4gcHJlc2VudGVkIGluIGEgc3RhbmRhcmQgd2F5IGluIGEgdGFibGUgb2YgcmVzdWx0cyBhbmQgYWxzbyB3aXRoIGEgcGxvdCBzaW1pbGFyIHRvIEZpZ3VyZSAzLjQgaW4gdGhlIHJlcG9ydC4KCiMgSW5jbHVkaW5nIHN1cnZleSB3ZWlnaHRzCgpUaGUgY2FsY3VsYXRpb25zIG1hZGUgZG8gbm90IGluY2x1ZGUgdGhlIHN1cnZleSB3ZWlnaHRzLgpBbiBpbnRyb2R1Y3Rpb24gdG8gdGhlIHVzZSBvZiB0aGUgc3VydmV5IHdlaWdodHMgd2FzIG1hZGUgW2hlcmVdKGh0dHBzOi8vYXJ0dXJvbWFsZG9uYWRvLmdpdGh1Yi5pby9CYXJvbWV0cm9FZHVfV2ViX0VuZy9FeHBhbnNpb24uaHRtbCkuCkluIHRoaXMgcGFydCB3ZSB3aWxsIHVzZSB0aGUgbGlicmFyeSBgc3VydmV5YC4KCldlIHdpbGwgdXNlIHRoZSBjb21tYW5kIGBzdnlkZXNpZ25gIChzaW1pbGFyIHRvIHRoZSBjb21tYW5kIHN2eXNldCBpbiBTVEFUQSkuCldpdGggdGhpcyBjb21tYW5kLCB3ZSBjcmVhdGUgYSBuZXcgb2JqZWN0IGNhbGxlZCAiZGVzaWduMTgiLCB3aGljaCBzYXZlcyB0aGUgaW5mb3JtYXRpb24gb2YgdGhlIHZhcmlhYmxlcyBjb250YWluZWQgaW4gdGhlIGRhdGFmcmFtZSwgaW5jbHVkaW5nIHRoZSBzdXJ2ZXkgd2VpZ2h0cyBpbiB0aGUgY2FsY3VsYXRpb25zLgpUaGVyZWZvcmUsIGlmIGEgbmV3IHZhcmlhYmxlIGlzIGNyZWF0ZWQgbGF0ZXIsIHRoaXMgY29tbWFuZCB3b3VsZCBoYXZlIHRvIGJlIGNhbGN1bGF0ZWQgYWdhaW4gc28gdGhhdCB0aGlzIG9iamVjdCAiZGVzaWduMTgiIGluY2x1ZGVzIHRoaXMgbmV3IHZhcmlhYmxlLgoKYGBge3IgZGlzZW5vLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpsaWJyYXJ5KHN1cnZleSkKZGVzaWduMTggPSBzdnlkZXNpZ24oaWRzID0gfnVwbSwgc3RyYXRhID0gfmVzdHJhdG9wcmksIHdlaWdodHMgPSB+d2VpZ2h0MTUwMCwgbmVzdD1UUlVFLCBkYXRhPWxhcG9wMTgpCmBgYAoKVGhlIGxpYnJhcnkgYHN1cnZleWAgaW5jbHVkZXMgdGhlIGNvbW1hbmQgYHN2eWdsbWAgdGhhdCBhbGxvd3MgdG8gY29tcHV0ZSBhIGxvZ2lzdGljIHJlZ3Jlc3Npb24gbW9kZWwuCldlIGNhbiBpbmNsdWRlIHRoZSBzYW1lIHZhcmlhYmxlcyB1c2VkIGluIG1vZGVsIDEgaW4gdGhpcyBjb21tYW5kLgpXZSBoYXZlIHRvIHNwZWNpZnkgdGhlIGRlc2lnbiB0aGF0IGlzIHVzZWQgYW5kIHRoZSB0cmVhdG1lbnQgb2YgbWlzc2luZyB2YWx1ZXMuClRoaXMgY2FsY3VsYXRpb24gaXMgc2F2ZWQgaW4gYSBvYmplY3QgIm1vZGVsMiIuClRoZSBjb21tYW5kIGBzdW1tYCBmcm9tIHRoZSBsaWJyYXJ5IGBqdG9vbHNgIGlzIHVzZWQgdG8gZGVzY3JpYmUgdGhlIG1vZGVsLgoKYGBge3IgbW9kZWxvdywgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KbW9kZWwyID0gc3Z5Z2xtKHVzZXIgfiB3ZWFsdGggKyBlZHVjICsgYWdlICsgbXVqZXIgKyB1cmJhbiArIGZhY3RvcihwYWlzKSwgZmFtaWx5PXF1YXNpYmlub21pYWwsIGRlc2lnbj1kZXNpZ24xOCwgbmEuYWN0aW9uID0gbmEub21pdCkKc3VtbShtb2RlbDIpCmBgYAoKSW4gdGhlIHNhbWUgd2F5IGFzIHdpdGggbW9kZWwgMSwgdGhlc2UgcmVzdWx0cyBjYW4gYWxzbyBiZSBwbG90dGVkIHVzaW5nIHRoZSBjb21tYW5kIGBwbG90X3N1bW1zYCwgc2VsZWN0aW5nIHRoZSB2YXJpYWJsZXMgdG8gZGlzcGxheS4KCmBgYHtyIGdyYWZpY293fQpwbG90X3N1bW1zKG1vZGVsMiwgY29lZnM9YygiTGV2ZWwgb2Ygd2VhbHRoIj0id2VhbHRoIiwgIlllYXJzIG9mIGVkdWNhdGlvbiI9ImVkdWMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIkFnZSI9ImFnZSIsICJNdWplciI9Im11amVyIiwgIlVyYmFuIGFyZWEiPSJ1cmJhbiIpKQpgYGAKClRoaXMgcGxvdCBpcyBzaW1pbGFyIHRvIHRoZSBvbmUgcmVwb3J0ZWQgaW4gRmlndXJlIDMuNC4KRGlmZmVyZW5jZXMgYXJlIGR1ZSB0byB0aGUgZmFjdCB0aGF0IHRoaXMgcGxvdCBzaG93cyB0aGUgY29lZmZpY2llbnRzIHdoZXJlYXMgRmlndXJlIDMuNCBzaG93cyBwcmVkaWN0ZWQgY2hhbmdlcyBpbiB0aGUgcHJvYmFiaWxpdHkgb2YgdGhlIGRlcGVuZGVudCB2YXJpYWJsZS4K