Introduction
In this section we will start with the basics of how to use the LAPOP
AmericasBarometer dataset for statistical purposes. First, we will look
at the basics of how to describe a variable using a frequency
distribution table and how to graph that variable using pie or bar
charts. For that, we are going to use the latest regional report “The
pulse of democracy”, available here,
where the main findings of the 2018/19 round of the AmericasBarometer
are presented. One of the sections of this document, reports data on
social networks and political attitudes. In this section, data on the
use of the internet and the use of social networks are presented, in
general and by country. With the data from the AmericasBarometer, it is
possible to know the percentage of households with cell phone access,
with internet access, as well as the percentage of people who use
WhatsApp, Facebook or Twitter. In this document we are going to
reproduce these results.
About the dataset
The data that we are going to use should be cited as follows: Source:
AmericasBarometer by the Latin American Public Opinion Project (LAPOP),
wwww.LapopSurveys.org. In this document a trimmed dataset is reloaded
from scratch. It is recommended again to clean the Environment of the
objects used in previous modules.
This dataset is hosted in the “materials_edu” repository of LAPOP’s
GitHub account. Using the library rio
and the
commandimport
, this dataset can be imported from this
repository. In addition, the data for countries with codes less than or
equal to 35 are selected, it means that observations for the United
States and Canada are eliminated.
library(rio)
lapop18 = import("https://raw.github.com/lapop-central/materials_edu/main/LAPOP_AB_Merge_2018_v1.0.sav")
lapop18 = subset(lapop18, pais<=35)
We also load the 2021 round dataset.
lapop21 = import("https://raw.github.com/lapop-central/materials_edu/main/lapop21.RData")
lapop21 = subset(lapop21, pais<=35)
Support for democracy
The report The Pulse of Democracy 2021 shows the results for support
for democracy by country. Figure 1.1 shows the percentage of people who
support democracy in abstract in each country.
In a previous section, we explain how to recode variable ING4,
originally measured in a 1-7 scale, where 1 means “Strongly diesagree”
and 7 means “Strongly agree”. Values between 5 and 7 are recoded as “1”
and this value identifies those who support democracy. The rest are
recoded as “0”, those who do not support democracy. The new recoded
variable are saved in a new variable “ing4rec”.
library(car)
lapop21$ing4rec = car::recode(lapop21$ing4, "1:4=0; 5:7=1")
In strict sense, this variable is not numeric even though it is
defined as “dbl” in the dataset, which is a type of numeric variable.
This variable is qualitative, nominal, that is defined as factor in R.
For correctly defined and labelled, we have to transform this variable.
First, we have to define as factor with the command
as.factor
.
lapop21$ing4rec = as.factor(lapop21$ing4rec)
A factor variable can have levels for each numeric value. The
definition of levels has the goal that tables of figures do not show
numeric codes, but the corresponding label. We can do this using the
command levels
. Then, we can describe this variable with
the command table
that gives absolute frequencies for each
category of this variable.
levels(lapop21$ing4rec) = c("No", "Yes")
table(lapop21$ing4rec)
##
## No Yes
## 20523 36240
Describe variables
As we see in the section Manipulation, we can use the command
prop.table
to obtain relative frequencies and the command
round
to show just one decimal.
round(prop.table(table(lapop21$ing4rec))*100, 1)
##
## No Yes
## 36.2 63.8
Results show two categories in the variable “support for democracy”.
However, this variable has missing values. For getting a table showing
missing values, we can use the command table
with the
specification useNA = "always"
.
round(prop.table(table(lapop21$ing4rec, useNA = "always"))*100, 1)
##
## No Yes <NA>
## 33.8 59.7 6.4
This table shows that we have 6.4% of missing cases of the total
observations. The presentation of missing values in tables or figures
depends of the researcher.
Plot a variable
We can plot a variable of type “factor” in multiple ways. A
possibility is by a circular graph. We can use the command
pie
, which is part of the basic syntax of R. Within this
command, we can nest the command table
to plot values of a
contingency table.
pie(table(lapop21$ing4rec))
This figure has some option to customization. For example, the
specification labels = …
serves to include the number of
observation in each sector, and the specification col =…
works to define colors of sectors.
pie(table(lapop21$ing4rec), labels=table(lapop21$ing4rec), col=1:2)
Other option is using a bar plot. Using the basic command of R, we
can use barplot
. We nest the commands table
and prop.table
within barplot
.
barplot(prop.table(table(lapop21$ing4rec))*100, col=1:2)
The base commands in R have a level of customization, but we have a
specialized library to produce a graph with more customization options
called ggplot
. For example, to reproduce a bar plot of the
variable support for democracy, we call the library
ggplot2
.
In this example, we have to define the basic specification within the
command ggplot
. This command works by layers. First, we
specify the data to be used with data=lapop
. Then, the
specification aes
defines the aesthetic of the plot.
Generally, it is used to indicate what variables are plotted in what
axis (x or y). In this case, we are working with the data from scratch,
from the original dataset “lapop21”. This option obliges to “calculate”
the percentages within the specification aes
with
y =..prop..*100
. Also, we should use the specification
fill =
to define that bars should present a percentage.
Other easier option is to create before a table from the original
data that captures percentages and to use this table in the
specification aes
. Below, we present examples using this
option.
After the specification of data and axis, we have to define the type
of plot we want to use. We do this with geometries (“geom”). We define a
basic bar plot using the command geom_bar( )
, where we
define internally the width of bars. With the specification
labs
we define the labels of axis and the “caption”.
Finally, with the specification coord_cartesian
we define
limits for x axis from 0 to 80.
library(ggplot2)
ggplot(data=lapop21, aes(x=ing4rec))+
geom_bar(aes(y=..prop..*100, group=1), width=0.5)+
labs(x="Support for democracy", y="Percentage",
caption="AmericasBarometer by LAPOP, 2021")+
coord_cartesian(ylim=c(0, 80))
As we say, this plot presents a bar for the percentage of missing
values. If a researcher would like to present a plot with percentages of
valid cases, missing values should be dropped. We can use the command
subset
again, but within ggplot
for the
command (internally) works with the variable no considering the missing
values. The syntax !is.na( )
makes the command to not
include missing values of a variable in calculations. If we would have
used !is.na( )
out of ggplot
, we would have
dropped all observations with missing values in the dataset, decreasing
the N and affecting next calculations.
ggplot(data=subset(lapop21, !is.na(ing4rec)), aes(x=ing4rec))+
geom_bar(aes(y=..prop..*100, group=1), width=0.5)+
labs(x="Support for democracy", y="Percentage",
caption="AmericasBarometer by LAPOP, 2021")+
coord_cartesian(ylim=c(0, 80))
Up to this point, we have presented a bar plot of a single variable,
support for democracy, for the whole sample, that includes all
countries. Figure 1.1 shows the percentage of support for democracy by
country. We will see this type of plot in a following section.
Calculating the variables of social network users
As we saw in a previous module, you can calculate new variables with
conditional values of other variables using the ifelse
command. In this way, we calculate the variables of social network
users.
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)
Describing the variables
With the variables ready, we now proceed to make the general tables
with the table
command. Note the use of #
as a
way of making annotations, which are not R code.
table(lapop18$smedia1r) #Facebook
##
## Yes No
## 15389 11573
table(lapop18$smedia4r) #Twitter
##
## Yes No
## 2363 24558
table(lapop18$smedia7r) #Whatsapp
##
## Yes No
## 17446 9569
This table
command gives us the absolute frequencies
(number of observations) for each category of variables (in this case
Yes and No). To get the relative frequencies, we will use the command
prop.table
, where the previous command table
is nested.
prop.table(table(lapop18$smedia1r))
##
## Yes No
## 0.5707663 0.4292337
prop.table(table(lapop18$smedia4r))
##
## Yes No
## 0.08777534 0.91222466
prop.table(table(lapop18$smedia7r))
##
## Yes No
## 0.6457894 0.3542106
However, the command prop.table
returns us too many
decimal places and the relative frequencies on a scale of 0 to 1. To
round this figure we use the round
command, which allows us
to specify the number of decimal places to be displayed. Both the
table
command and the prop.table
are nested
within this new command. In this case, we use 3 decimals, so when it is
multiplied by 100, it remains in the form of a percentage with 1 decimal
place.
round(prop.table(table(lapop18$smedia1r)), 3)*100
##
## Yes No
## 57.1 42.9
round(prop.table(table(lapop18$smedia4r)), 3)*100
##
## Yes No
## 8.8 91.2
round(prop.table(table(lapop18$smedia7r)), 3)*100
##
## Yes No
## 64.6 35.4
It is not practical to present 3 tables when the variables have the
same response categories. For presentation purposes it might be better
to build a single table. You can save the partial tables in new objects
with the operator =
and then join them as rows with the
command rbind
in a new dataframe “table” with the command
as.data.frame
, in such a way that the responses to each
social network appear in rows.
Facebook = round(prop.table(table(lapop18$smedia1r)), 3)*100
Twitter = round(prop.table(table(lapop18$smedia4r)), 3)*100
Whatsapp = round(prop.table(table(lapop18$smedia7r)), 3)*100
tabla = as.data.frame(rbind(Facebook, Twitter, Whatsapp))
tabla
## Yes No
## Facebook 57.1 42.9
## Twitter 8.8 91.2
## Whatsapp 64.6 35.4
To have a better presentation of the table, you can use the
kable
command from the knitr
package, using
the table built above.
library(knitr)
knitr::kable(tabla, format="markdown")
Facebook |
57.1 |
42.9 |
Twitter |
8.8 |
91.2 |
Whatsapp |
64.6 |
35.4 |
Plotting the variables
In Graph 3.1 of the report it is observed that these data are
reported through a pie chart.
We can reproduce that graph using the pie
command which
is part of the basic R syntax. Within this command you can nest the
table
command to graph these values.
pie(table(lapop18$smedia1r))
You could also think of a bar chart. Using the basic R commands, you
can use the barplot
command.
barplot(prop.table(table(lapop18$smedia1r)))
These graphical commands have options to adjust the graph, for
example to include percentages and adjust scales. But, to have more
graphical options, we can use the ggplot
package to
reproduce the pie chart.
In this example, we have to define first the data to be used. The
subset
command has been used again, but inside
ggplot
so that the command (internally) works with the
variable but without the missing values. The !is.na ()
syntax prevents the command from including missing values of a variable
in calculations. If data = lapop
had been used the graph
would have included a large sector corresponding to the proportion of
NA. If !is.na ()
had been used outside of
ggplot
creating a new variable, all observations with
missing values would have been removed, which would decrease the N,
affecting future calculations.
The ggplot
command works by adding layers. The
aes
specification is used to define the “aesthetics” of the
graph. It is generally used to indicate which variable is going to be
graphed on which axis (x or y). You can also use the fill =
specification to define the groups to be generated.
After specifying the data and the axes, you have to specify the type
of graph you want to make. This is done with geometries (“geom”). There
is no direct geometry to make a pie chart, so you have to initially use
a simple bar chart, using the command geom_bar ()
, where
the width of the bar is defined internally. If we left the syntax at
this point, a bar would be generated that would be divided by the values
of the variable “smedia1r”. To generate the pie chart, you have to add
another command coord_polar
, which transforms the bar to
polar coordinates, creating a pie chart.
library(ggplot2) #librería especializada en gráficos
ggplot(data=subset(lapop18, !is.na(smedia1r)), aes(x="", fill=smedia1r))+
geom_bar(width=1) +
coord_polar("y", start=0)
The above graph has started from the same dataframe “lapop18”, using
the data from “smedia1r”. However, to better manipulate the graph it is
easier to create a new dataframe with the aggregated data (frequencies
and %). In other words, save the results data from the “smedia1r” table
in a new dataframe. Then that new dataframe is used to make the pie
graph with ggplot
.
One aspect to note is that in this case the tidyverse is being used,
which includes the pipe %>%
command from the
dplyr
library, which is a (slightly) different way of
writing code in R, in a concatenated way, step by step. A simple
explanation of how the pipe is used can be found here.
The first thing to notice is that a new object called “df” is going
to be created. Information coming from the dataframe “lapop18” will be
stored in this object. The subset
command is used to remove
the missing values of “smedia1r” from the calculation of the
percentages. Then (%>%
), this data will be grouped by
categories of the variable “smedia1r”. Next (%>%
), in
each group the total number of observations is calculated with the
command summarise(n = n())
. Finally (last step with
%>%
), with this total by groups the percentages are
calculated and these percentages are saved in a new column “per”.
library(dplyr)
df = subset(lapop18, !is.na(smedia1r)) %>%
group_by(smedia1r) %>%
dplyr::summarise(n = n()) %>%
mutate(per=round(n/sum(n), 3)*100)
df
## # A tibble: 2 × 3
## smedia1r n per
## <fct> <int> <dbl>
## 1 Yes 15389 57.1
## 2 No 11573 42.9
With this syntax, a table is created containing the total number of
observations and the percentage for each category of the variable
“smedia1r”. A more direct way to create the same data is to use the
janitor
library and the tabyl
command. In R
there are multiple ways to get to the same results.
library(janitor)
subset(lapop18, !is.na(smedia1r)) %>%
tabyl(smedia1r)
## smedia1r n percent
## Yes 15389 0.5707663
## No 11573 0.4292337
Once we have the table, we can use it to produce the pie chart with
ggplot
. Note that in this case the data used comes from the
dataframe df (not from lapop18). This dataframe has a column called
“per” with the respective percentages, which should be plotted on the
Y-axis. As in the previous case, to make the pie chart, we start from
the bar chart (hence geom_bar
), which is then passed to
polar coordinates (hence coord_polar
).
A text layer is added, with the specification geom_text
.
Within this specification, an “aesthetic” is determined with the data
label aes(label=...)
, where the percentage data “per” and
the symbol “%” are joined with the paste
command, with a
space (sep=...
) between them. Set the font color with
color="..."
, sets to white to contrast with the colors of
the pie chart. With the command hjust=...
the horizontal
position of this text is adjusted. The ggplot
command can
include various “themes” for the plot. In this case,
theme_void()
has been used, which indicates an empty
background. Finally, with the specification
scale_fill_discrete(name=...)
you can change the title of
the legend so that it does not show the name of the variable, but a more
suitable label.
ggplot(data=df, aes(x="", y=per, fill=smedia1r))+
geom_bar(width=1, stat="identity")+
geom_text(aes(label=paste(per, "%", sep="")), color="white",
position=position_stack(vjust=0.5), size=3)+
coord_polar("y")+
theme_void()+
scale_fill_discrete(name="Do you have a Facebook account?")
If instead of a pie chart you want to display a bar chart, with the
data from the “lapop18” dataframe you can use the following code. Unlike
the first pie chart, the aes(..)
specification now includes
the variable “smedia1r” as the variable to be plotted on the X-axis.
Inside the geometric object geom_bar()
it is indicated that
the bar must represent the proportions in percentages
aes(y=..prop..*100, group=1)
. In this example, a general
label for the graph and for the axes has been included with the
labs(...)
command. In this command you can also add a
“caption” to indicate the source of the data. Finally, the specification
coord_cartesian(ylim=c(0,60))
limits the Y axis to values
between 0 and 60.
ggplot(data=subset(lapop18, !is.na(smedia1r)), aes(x=smedia1r))+
geom_bar(aes(y=..prop..*100, group=1), width=0.5)+
labs(title="Do you have a Facebook account?", x="Facebook user", y="Percentage", caption="AmericasBarometer by LAPOP, 2018/19")+
coord_cartesian(ylim=c(0, 60))
In this case you can also use the grouped data of the “df” dataframe.
Unlike the previous option, in “df” there is the percentage data, so it
should not be calculated in the code, so in the aesthetics specification
it indicates that the alternatives should be shown on the X axis of the
variable “smedia1r” and on the Y axis the percentage, in this way
aes(x=media1r, y=per)
. For this reason also in the
geom_bar
specification, now instead of requiring the
calculation of the percentage, it is only indicated to replicate the
data (with stat="identity"
) from aes
. Finally,
in this case we add the text layer to include the percentages in each
column, with the geom_text
specification.
ggplot(df, aes(x=smedia1r, y=per))+
geom_bar(stat="identity", width=0.5)+
geom_text(aes(label=paste(per, "%", sep="")), color="black", vjust=-0.5)+
labs(title="Do you have a Facebook account?", x="Facebook user", y="Percentage", caption="AmericasBarometer by LAPOP, 2018/19")+
coord_cartesian(ylim=c(0, 60))
We consider this option a easier way to work with this data. First,
we have to create a dataframe with the percentages and the labels. Then,
we have to use this dataframe in ggplot
. In the following
sections, we will use this way.
Summary
In this document we have worked with nominal categorical variables,
such as whether or not you suppport democracy or whether or not you use
social networks. We present several ways to describe these variables in
frequency tables and to plot these variables, using circular or bar
graphs.
Calculations including design effect
The results for the 2018/19 wave are not exactly the same as those in
the report, since LAPOP includes the effect of the sample design in its
calculations. According to this syntax, it is found that 57.1% of
interviewees report being a Facebook user, when 56.2% appear in the
report. The same with Twitter, which here is calculated at 8.8% and in
the report 7.9%; and with WhatsApp that appears here with 64.6% and in
the report with 64.4%. As indicated in the section on the use of survey
weights using data from the AmericasBarometer (available here),
there are several ways to reproduce the results by incorporating the
survey weights. A first option is to use the command freq
,
which allows the inclusion of a weighting variable, such as
“weight1500”. The plot=F
specification is included to not
produce the bar graphs.
library(descr)
descr::freq(lapop18$fb_user, lapop18$weight1500, plot = F)
## lapop18$fb_user
## Frequency Percent Valid Percent
## 0 11337 41.988 43.77
## 1 14564 53.939 56.23
## NA's 1100 4.073
## Total 27000 100.000 100.00
descr::freq(lapop18$tw_user, lapop18$weight1500, plot = F)
## lapop18$tw_user
## Frequency Percent Valid Percent
## 0 23819 88.220 92.023
## 1 2065 7.647 7.977
## NA's 1116 4.133
## Total 27000 100.000 100.000
descr::freq(lapop18$wa_user, lapop18$weight1500, plot = F)
## lapop18$wa_user
## Frequency Percent Valid Percent
## 0 9252 34.266 35.63
## 1 16714 61.903 64.37
## NA's 1035 3.832
## Total 27000 100.000 100.00
Without considering the survey weights, 57.1% of the interviewees
have a Facebook account. This percentage varies to 55.2% if the
expansion variable is included, which is the value shown in the report.
These weighted results can also be saved to objects and then graphed in
the same way as the unweighted results.
In the case of Facebook, the table can be saved as a dataframe, using
the command as.data.frame
. This table includes data that we
do not require, such as the NA’s and Total row and the Percent column.
These rows and this column are deleted using the specification
[-c(3,4), -2]
.
The columns are then renamed to avoid the “Valid Percent” name. They
are simply named “freq” and “per”. This column “per” is the one that has
the data that we will graph. Finally, a “lab” column is added with the
labels of each row of results.
fb <- as.data.frame(descr::freq(lapop18$fb_user, lapop18$weight1500, plot = F))
fb = fb[-c(3,4), -2]
colnames(fb) = c("freq", "per")
fb$lab = c("No", "Yes")
fb
## freq per lab
## 0 11336.69 43.77052 No
## 1 14563.60 56.22948 Yes
With this new dataframe we can replicate the same codes used above to
make a bar chart or a pie chart. The following code displays the bar
chart. Note that now the “fb” dataframe is used and that in aes it is
specified that the data from the “lab” column must be on the X axis and
the data from the “per” column must be on the Y axis.
ggplot(data=fb, aes(x=lab, y=per))+
geom_bar(stat="identity", width=0.5)+
geom_text(aes(label=paste(round(per, 1), "%", sep="")), color="black", vjust=-0.5)+
labs(title="Do you have a Facebook account?", x="Facebook user",
y="Percentage", caption="AmericasBarometer by LAPOP, 2018/19")+
coord_cartesian(ylim=c(0, 60))
The same can be done to create a pie chart. This graph reproduces the
results found in Graph 3.1 of the report.
ggplot(data=fb, aes(x=2, y=per, fill=lab))+
geom_bar(stat="identity")+
geom_text(aes(label=paste(round(per, 1), "%", sep="")), color="white",
position=position_stack(vjust=0.5), size=3)+
coord_polar("y")+
theme_void()+
labs(caption="AméricasBarometer by LAPOP, 2018/19")+
scale_fill_discrete(name="Do you have a Facebook account?")+
xlim(0.5, 2.5)
The second option to reproduce the results in the report is using the
package survey
. As we indicate in this section,
we have to define first the sample design with the command
svydesign
.
library(survey)
lapop.design = svydesign(ids = ~upm, strata = ~estratopri, weights = ~weight1500, nest=TRUE, data=lapop18)
Once you have created the data with the expansion factor in the
“lapop.design” object, you can use the native commands of the package
survey
to perform calculations. For example, to calculate
the frequency distribution table you can use the svytable
command.
svytable(~fb_user, design=lapop.design)
## fb_user
## 0 1
## 11336.69 14563.60
These frequencies can be nested in the prop.table
command to calculate the percentages of social network users. These
results are the same as those shown in the previous graphs and those
that appear in the report.
These data can also be saved in a dataframe that is adapted for
graphing, following the same procedure as in the previous graphs.
prop.table(svytable(~fb_user, design=lapop.design))
## fb_user
## 0 1
## 0.4377052 0.5622948
prop.table(svytable(~tw_user, design=lapop.design))
## tw_user
## 0 1
## 0.92023002 0.07976998
prop.table(svytable(~wa_user, design=lapop.design))
## wa_user
## 0 1
## 0.3563091 0.6436909
LS0tCnRpdGxlOiAiRGVzY3JpcHRpdmUgc3RhdGlzdGljcyB1c2luZyB0aGUgQW1lcmljYXNCYXJvbWV0ZXIgKDEpIgpvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDoKICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OiB0cnVlCiAgICBjb2xsYXBzZWQ6IGZhbHNlCiAgICBudW1iZXJfc2VjdGlvbnM6IGZhbHNlCiAgICB0b2NfZGVwdGg6IDEKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKICAgIHRoZW1lOiBmbGF0bHkKICAgICNjb2RlX2ZvbGRpbmc6IGhpZGUKZWRpdG9yX29wdGlvbnM6IAogIG1hcmtkb3duOiAKICAgIHdyYXA6IHNlbnRlbmNlCi0tLQoKYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9CmtuaXRyOjpvcHRzX2NodW5rJHNldChtZXNzYWdlPUZBTFNFLHdhcm5pbmc9RkFMU0UsIGNhY2hlPVRSVUUpCmBgYAoKYGBge2NzcyBjb2xvciwgZWNobz1GQUxTRX0KLmNvbHVtbnMge2Rpc3BsYXk6IGZsZXg7fQpoMSB7Y29sb3I6ICMzMzY2Q0M7fQpgYGAKCiMgSW50cm9kdWN0aW9uCgpJbiB0aGlzIHNlY3Rpb24gd2Ugd2lsbCBzdGFydCB3aXRoIHRoZSBiYXNpY3Mgb2YgaG93IHRvIHVzZSB0aGUgTEFQT1AgQW1lcmljYXNCYXJvbWV0ZXIgZGF0YXNldCBmb3Igc3RhdGlzdGljYWwgcHVycG9zZXMuCkZpcnN0LCB3ZSB3aWxsIGxvb2sgYXQgdGhlIGJhc2ljcyBvZiBob3cgdG8gZGVzY3JpYmUgYSB2YXJpYWJsZSB1c2luZyBhIGZyZXF1ZW5jeSBkaXN0cmlidXRpb24gdGFibGUgYW5kIGhvdyB0byBncmFwaCB0aGF0IHZhcmlhYmxlIHVzaW5nIHBpZSBvciBiYXIgY2hhcnRzLgpGb3IgdGhhdCwgd2UgYXJlIGdvaW5nIHRvIHVzZSB0aGUgbGF0ZXN0IHJlZ2lvbmFsIHJlcG9ydCAiVGhlIHB1bHNlIG9mIGRlbW9jcmFjeSIsIGF2YWlsYWJsZSBbaGVyZV0oaHR0cHM6Ly93d3cudmFuZGVyYmlsdC5lZHUvbGFwb3AvYWIyMDIxLzIwMjFfTEFQT1BfQW1lcmljYXNCYXJvbWV0ZXJfMjAyMV9QdWxzZV9vZl9EZW1vY3JhY3kucGRmKSwgd2hlcmUgdGhlIG1haW4gZmluZGluZ3Mgb2YgdGhlIDIwMTgvMTkgcm91bmQgb2YgdGhlIEFtZXJpY2FzQmFyb21ldGVyIGFyZSBwcmVzZW50ZWQuCk9uZSBvZiB0aGUgc2VjdGlvbnMgb2YgdGhpcyBkb2N1bWVudCwgcmVwb3J0cyBkYXRhIG9uIHNvY2lhbCBuZXR3b3JrcyBhbmQgcG9saXRpY2FsIGF0dGl0dWRlcy4KSW4gdGhpcyBzZWN0aW9uLCBkYXRhIG9uIHRoZSB1c2Ugb2YgdGhlIGludGVybmV0IGFuZCB0aGUgdXNlIG9mIHNvY2lhbCBuZXR3b3JrcyBhcmUgcHJlc2VudGVkLCBpbiBnZW5lcmFsIGFuZCBieSBjb3VudHJ5LgpXaXRoIHRoZSBkYXRhIGZyb20gdGhlIEFtZXJpY2FzQmFyb21ldGVyLCBpdCBpcyBwb3NzaWJsZSB0byBrbm93IHRoZSBwZXJjZW50YWdlIG9mIGhvdXNlaG9sZHMgd2l0aCBjZWxsIHBob25lIGFjY2Vzcywgd2l0aCBpbnRlcm5ldCBhY2Nlc3MsIGFzIHdlbGwgYXMgdGhlIHBlcmNlbnRhZ2Ugb2YgcGVvcGxlIHdobyB1c2UgV2hhdHNBcHAsIEZhY2Vib29rIG9yIFR3aXR0ZXIuCkluIHRoaXMgZG9jdW1lbnQgd2UgYXJlIGdvaW5nIHRvIHJlcHJvZHVjZSB0aGVzZSByZXN1bHRzLgoKIyBBYm91dCB0aGUgZGF0YXNldAoKVGhlIGRhdGEgdGhhdCB3ZSBhcmUgZ29pbmcgdG8gdXNlIHNob3VsZCBiZSBjaXRlZCBhcyBmb2xsb3dzOiBTb3VyY2U6IEFtZXJpY2FzQmFyb21ldGVyIGJ5IHRoZSBMYXRpbiBBbWVyaWNhbiBQdWJsaWMgT3BpbmlvbiBQcm9qZWN0IChMQVBPUCksIHd3d3cuTGFwb3BTdXJ2ZXlzLm9yZy4KSW4gdGhpcyBkb2N1bWVudCBhIHRyaW1tZWQgZGF0YXNldCBpcyByZWxvYWRlZCBmcm9tIHNjcmF0Y2guCkl0IGlzIHJlY29tbWVuZGVkIGFnYWluIHRvIGNsZWFuIHRoZSBFbnZpcm9ubWVudCBvZiB0aGUgb2JqZWN0cyB1c2VkIGluIHByZXZpb3VzIG1vZHVsZXMuCgpUaGlzIGRhdGFzZXQgaXMgaG9zdGVkIGluIHRoZSAibWF0ZXJpYWxzX2VkdSIgcmVwb3NpdG9yeSBvZiBMQVBPUCdzIEdpdEh1YiBhY2NvdW50LgpVc2luZyB0aGUgbGlicmFyeSBgcmlvYCBhbmQgdGhlIGNvbW1hbmRgaW1wb3J0YCwgdGhpcyBkYXRhc2V0IGNhbiBiZSBpbXBvcnRlZCBmcm9tIHRoaXMgcmVwb3NpdG9yeS4KSW4gYWRkaXRpb24sIHRoZSBkYXRhIGZvciBjb3VudHJpZXMgd2l0aCBjb2RlcyBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gMzUgYXJlIHNlbGVjdGVkLCBpdCBtZWFucyB0aGF0IG9ic2VydmF0aW9ucyBmb3IgdGhlIFVuaXRlZCBTdGF0ZXMgYW5kIENhbmFkYSBhcmUgZWxpbWluYXRlZC4KCmBgYHtyIGJhc2UxOCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KbGlicmFyeShyaW8pCmxhcG9wMTggPSBpbXBvcnQoImh0dHBzOi8vcmF3LmdpdGh1Yi5jb20vbGFwb3AtY2VudHJhbC9tYXRlcmlhbHNfZWR1L21haW4vTEFQT1BfQUJfTWVyZ2VfMjAxOF92MS4wLnNhdiIpCmxhcG9wMTggPSBzdWJzZXQobGFwb3AxOCwgcGFpczw9MzUpCmBgYAoKV2UgYWxzbyBsb2FkIHRoZSAyMDIxIHJvdW5kIGRhdGFzZXQuCgpgYGB7ciBiYXNlMjF9CmxhcG9wMjEgPSBpbXBvcnQoImh0dHBzOi8vcmF3LmdpdGh1Yi5jb20vbGFwb3AtY2VudHJhbC9tYXRlcmlhbHNfZWR1L21haW4vbGFwb3AyMS5SRGF0YSIpCmxhcG9wMjEgPSBzdWJzZXQobGFwb3AyMSwgcGFpczw9MzUpCmBgYAoKIyBTdXBwb3J0IGZvciBkZW1vY3JhY3kKClRoZSByZXBvcnQgVGhlIFB1bHNlIG9mIERlbW9jcmFjeSAyMDIxIHNob3dzIHRoZSByZXN1bHRzIGZvciBzdXBwb3J0IGZvciBkZW1vY3JhY3kgYnkgY291bnRyeS4KRmlndXJlIDEuMSBzaG93cyB0aGUgcGVyY2VudGFnZSBvZiBwZW9wbGUgd2hvIHN1cHBvcnQgZGVtb2NyYWN5IGluIGFic3RyYWN0IGluIGVhY2ggY291bnRyeS4KCiFbXShGaWd1cmUxLjEucG5nKXt3aWR0aD0iNTA4In0KCkluIGEgcHJldmlvdXMgc2VjdGlvbiwgd2UgZXhwbGFpbiBob3cgdG8gcmVjb2RlIHZhcmlhYmxlIElORzQsIG9yaWdpbmFsbHkgbWVhc3VyZWQgaW4gYSAxLTcgc2NhbGUsIHdoZXJlIDEgbWVhbnMgIlN0cm9uZ2x5IGRpZXNhZ3JlZSIgYW5kIDcgbWVhbnMgIlN0cm9uZ2x5IGFncmVlIi4KVmFsdWVzIGJldHdlZW4gNSBhbmQgNyBhcmUgcmVjb2RlZCBhcyAiMSIgYW5kIHRoaXMgdmFsdWUgaWRlbnRpZmllcyB0aG9zZSB3aG8gc3VwcG9ydCBkZW1vY3JhY3kuClRoZSByZXN0IGFyZSByZWNvZGVkIGFzICIwIiwgdGhvc2Ugd2hvIGRvIG5vdCBzdXBwb3J0IGRlbW9jcmFjeS4KVGhlIG5ldyByZWNvZGVkIHZhcmlhYmxlIGFyZSBzYXZlZCBpbiBhIG5ldyB2YXJpYWJsZSAiaW5nNHJlYyIuCgpgYGB7ciByZWNvZGV9CmxpYnJhcnkoY2FyKQpsYXBvcDIxJGluZzRyZWMgPSBjYXI6OnJlY29kZShsYXBvcDIxJGluZzQsICIxOjQ9MDsgNTo3PTEiKQpgYGAKCkluIHN0cmljdCBzZW5zZSwgdGhpcyB2YXJpYWJsZSBpcyBub3QgbnVtZXJpYyBldmVuIHRob3VnaCBpdCBpcyBkZWZpbmVkIGFzICJkYmwiIGluIHRoZSBkYXRhc2V0LCB3aGljaCBpcyBhIHR5cGUgb2YgbnVtZXJpYyB2YXJpYWJsZS4KVGhpcyB2YXJpYWJsZSBpcyBxdWFsaXRhdGl2ZSwgbm9taW5hbCwgdGhhdCBpcyBkZWZpbmVkIGFzIGZhY3RvciBpbiBSLgpGb3IgY29ycmVjdGx5IGRlZmluZWQgYW5kIGxhYmVsbGVkLCB3ZSBoYXZlIHRvIHRyYW5zZm9ybSB0aGlzIHZhcmlhYmxlLgpGaXJzdCwgd2UgaGF2ZSB0byBkZWZpbmUgYXMgZmFjdG9yIHdpdGggdGhlIGNvbW1hbmQgYGFzLmZhY3RvcmAuCgpgYGB7ciBmYWN0b3J9CmxhcG9wMjEkaW5nNHJlYyA9IGFzLmZhY3RvcihsYXBvcDIxJGluZzRyZWMpCmBgYAoKQSBmYWN0b3IgdmFyaWFibGUgY2FuIGhhdmUgbGV2ZWxzIGZvciBlYWNoIG51bWVyaWMgdmFsdWUuClRoZSBkZWZpbml0aW9uIG9mIGxldmVscyBoYXMgdGhlIGdvYWwgdGhhdCB0YWJsZXMgb2YgZmlndXJlcyBkbyBub3Qgc2hvdyBudW1lcmljIGNvZGVzLCBidXQgdGhlIGNvcnJlc3BvbmRpbmcgbGFiZWwuCldlIGNhbiBkbyB0aGlzIHVzaW5nIHRoZSBjb21tYW5kIGBsZXZlbHNgLgpUaGVuLCB3ZSBjYW4gZGVzY3JpYmUgdGhpcyB2YXJpYWJsZSB3aXRoIHRoZSBjb21tYW5kIGB0YWJsZWAgdGhhdCBnaXZlcyBhYnNvbHV0ZSBmcmVxdWVuY2llcyBmb3IgZWFjaCBjYXRlZ29yeSBvZiB0aGlzIHZhcmlhYmxlLgoKYGBge3IgbGV2ZWxzfQpsZXZlbHMobGFwb3AyMSRpbmc0cmVjKSA9IGMoIk5vIiwgIlllcyIpCnRhYmxlKGxhcG9wMjEkaW5nNHJlYykKYGBgCgojIERlc2NyaWJlIHZhcmlhYmxlcwoKQXMgd2Ugc2VlIGluIHRoZSBzZWN0aW9uIE1hbmlwdWxhdGlvbiwgd2UgY2FuIHVzZSB0aGUgY29tbWFuZCBgcHJvcC50YWJsZWAgdG8gb2J0YWluIHJlbGF0aXZlIGZyZXF1ZW5jaWVzIGFuZCB0aGUgY29tbWFuZCBgcm91bmRgIHRvIHNob3cganVzdCBvbmUgZGVjaW1hbC4KCmBgYHtyIHJvdW5kfQpyb3VuZChwcm9wLnRhYmxlKHRhYmxlKGxhcG9wMjEkaW5nNHJlYykpKjEwMCwgMSkKYGBgCgpSZXN1bHRzIHNob3cgdHdvIGNhdGVnb3JpZXMgaW4gdGhlIHZhcmlhYmxlICJzdXBwb3J0IGZvciBkZW1vY3JhY3kiLgpIb3dldmVyLCB0aGlzIHZhcmlhYmxlIGhhcyBtaXNzaW5nIHZhbHVlcy4KRm9yIGdldHRpbmcgYSB0YWJsZSBzaG93aW5nIG1pc3NpbmcgdmFsdWVzLCB3ZSBjYW4gdXNlIHRoZSBjb21tYW5kIGB0YWJsZWAgd2l0aCB0aGUgc3BlY2lmaWNhdGlvbiBgdXNlTkEgPSAiYWx3YXlzImAuCgpgYGB7ciBOQXN9CnJvdW5kKHByb3AudGFibGUodGFibGUobGFwb3AyMSRpbmc0cmVjLCB1c2VOQSA9ICJhbHdheXMiKSkqMTAwLCAxKQpgYGAKClRoaXMgdGFibGUgc2hvd3MgdGhhdCB3ZSBoYXZlIDYuNCUgb2YgbWlzc2luZyBjYXNlcyBvZiB0aGUgdG90YWwgb2JzZXJ2YXRpb25zLgpUaGUgcHJlc2VudGF0aW9uIG9mIG1pc3NpbmcgdmFsdWVzIGluIHRhYmxlcyBvciBmaWd1cmVzIGRlcGVuZHMgb2YgdGhlIHJlc2VhcmNoZXIuCgojIFBsb3QgYSB2YXJpYWJsZQoKV2UgY2FuIHBsb3QgYSB2YXJpYWJsZSBvZiB0eXBlICJmYWN0b3IiIGluIG11bHRpcGxlIHdheXMuCkEgcG9zc2liaWxpdHkgaXMgYnkgYSBjaXJjdWxhciBncmFwaC4KV2UgY2FuIHVzZSB0aGUgY29tbWFuZCBgcGllYCwgd2hpY2ggaXMgcGFydCBvZiB0aGUgYmFzaWMgc3ludGF4IG9mIFIuCldpdGhpbiB0aGlzIGNvbW1hbmQsIHdlIGNhbiBuZXN0IHRoZSBjb21tYW5kIGB0YWJsZWAgdG8gcGxvdCB2YWx1ZXMgb2YgYSBjb250aW5nZW5jeSB0YWJsZS4KCmBgYHtyIHBpZTF9CnBpZSh0YWJsZShsYXBvcDIxJGluZzRyZWMpKQpgYGAKClRoaXMgZmlndXJlIGhhcyBzb21lIG9wdGlvbiB0byBjdXN0b21pemF0aW9uLgpGb3IgZXhhbXBsZSwgdGhlIHNwZWNpZmljYXRpb24gYGxhYmVscyA9IOKApmAgc2VydmVzIHRvIGluY2x1ZGUgdGhlIG51bWJlciBvZiBvYnNlcnZhdGlvbiBpbiBlYWNoIHNlY3RvciwgYW5kIHRoZSBzcGVjaWZpY2F0aW9uIGBjb2wgPeKApmAgd29ya3MgdG8gZGVmaW5lIGNvbG9ycyBvZiBzZWN0b3JzLgoKYGBge3IgcGllMn0KcGllKHRhYmxlKGxhcG9wMjEkaW5nNHJlYyksIGxhYmVscz10YWJsZShsYXBvcDIxJGluZzRyZWMpLCBjb2w9MToyKQpgYGAKCk90aGVyIG9wdGlvbiBpcyB1c2luZyBhIGJhciBwbG90LgpVc2luZyB0aGUgYmFzaWMgY29tbWFuZCBvZiBSLCB3ZSBjYW4gdXNlIGBiYXJwbG90YC4KV2UgbmVzdCB0aGUgY29tbWFuZHMgYHRhYmxlYCBhbmQgYHByb3AudGFibGVgIHdpdGhpbiBgYmFycGxvdGAuCgpgYGB7ciBiYXIxfQpiYXJwbG90KHByb3AudGFibGUodGFibGUobGFwb3AyMSRpbmc0cmVjKSkqMTAwLCBjb2w9MToyKQpgYGAKClRoZSBiYXNlIGNvbW1hbmRzIGluIFIgaGF2ZSBhIGxldmVsIG9mIGN1c3RvbWl6YXRpb24sIGJ1dCB3ZSBoYXZlIGEgc3BlY2lhbGl6ZWQgbGlicmFyeSB0byBwcm9kdWNlIGEgZ3JhcGggd2l0aCBtb3JlIGN1c3RvbWl6YXRpb24gb3B0aW9ucyBjYWxsZWQgYGdncGxvdGAuCkZvciBleGFtcGxlLCB0byByZXByb2R1Y2UgYSBiYXIgcGxvdCBvZiB0aGUgdmFyaWFibGUgc3VwcG9ydCBmb3IgZGVtb2NyYWN5LCB3ZSBjYWxsIHRoZSBsaWJyYXJ5IGBnZ3Bsb3QyYC4KCkluIHRoaXMgZXhhbXBsZSwgd2UgaGF2ZSB0byBkZWZpbmUgdGhlIGJhc2ljIHNwZWNpZmljYXRpb24gd2l0aGluIHRoZSBjb21tYW5kIGBnZ3Bsb3RgLgpUaGlzIGNvbW1hbmQgd29ya3MgYnkgbGF5ZXJzLgpGaXJzdCwgd2Ugc3BlY2lmeSB0aGUgZGF0YSB0byBiZSB1c2VkIHdpdGggYGRhdGE9bGFwb3BgLgpUaGVuLCB0aGUgc3BlY2lmaWNhdGlvbiBgYWVzYCBkZWZpbmVzIHRoZSBhZXN0aGV0aWMgb2YgdGhlIHBsb3QuCkdlbmVyYWxseSwgaXQgaXMgdXNlZCB0byBpbmRpY2F0ZSB3aGF0IHZhcmlhYmxlcyBhcmUgcGxvdHRlZCBpbiB3aGF0IGF4aXMgKHggb3IgeSkuCkluIHRoaXMgY2FzZSwgd2UgYXJlIHdvcmtpbmcgd2l0aCB0aGUgZGF0YSBmcm9tIHNjcmF0Y2gsIGZyb20gdGhlIG9yaWdpbmFsIGRhdGFzZXQgImxhcG9wMjEiLgpUaGlzIG9wdGlvbiBvYmxpZ2VzIHRvICJjYWxjdWxhdGUiIHRoZSBwZXJjZW50YWdlcyB3aXRoaW4gdGhlIHNwZWNpZmljYXRpb24gYGFlc2Agd2l0aCBgeSA9Li5wcm9wLi4qMTAwYC4KQWxzbywgd2Ugc2hvdWxkIHVzZSB0aGUgc3BlY2lmaWNhdGlvbiBgZmlsbCA9YCB0byBkZWZpbmUgdGhhdCBiYXJzIHNob3VsZCBwcmVzZW50IGEgcGVyY2VudGFnZS4KCk90aGVyIGVhc2llciBvcHRpb24gaXMgdG8gY3JlYXRlIGJlZm9yZSBhIHRhYmxlIGZyb20gdGhlIG9yaWdpbmFsIGRhdGEgdGhhdCBjYXB0dXJlcyBwZXJjZW50YWdlcyBhbmQgdG8gdXNlIHRoaXMgdGFibGUgaW4gdGhlIHNwZWNpZmljYXRpb24gYGFlc2AuCkJlbG93LCB3ZSBwcmVzZW50IGV4YW1wbGVzIHVzaW5nIHRoaXMgb3B0aW9uLgoKQWZ0ZXIgdGhlIHNwZWNpZmljYXRpb24gb2YgZGF0YSBhbmQgYXhpcywgd2UgaGF2ZSB0byBkZWZpbmUgdGhlIHR5cGUgb2YgcGxvdCB3ZSB3YW50IHRvIHVzZS4KV2UgZG8gdGhpcyB3aXRoIGdlb21ldHJpZXMgKCJnZW9tIikuCldlIGRlZmluZSBhIGJhc2ljIGJhciBwbG90IHVzaW5nIHRoZSBjb21tYW5kIGBnZW9tX2JhciggKWAsIHdoZXJlIHdlIGRlZmluZSBpbnRlcm5hbGx5IHRoZSB3aWR0aCBvZiBiYXJzLgpXaXRoIHRoZSBzcGVjaWZpY2F0aW9uIGBsYWJzYCB3ZSBkZWZpbmUgdGhlIGxhYmVscyBvZiBheGlzIGFuZCB0aGUgImNhcHRpb24iLgpGaW5hbGx5LCB3aXRoIHRoZSBzcGVjaWZpY2F0aW9uIGBjb29yZF9jYXJ0ZXNpYW5gIHdlIGRlZmluZSBsaW1pdHMgZm9yIHggYXhpcyBmcm9tIDAgdG8gODAuCgpgYGB7ciBnZ2JhcjF9CmxpYnJhcnkoZ2dwbG90MikKZ2dwbG90KGRhdGE9bGFwb3AyMSwgYWVzKHg9aW5nNHJlYykpKwogIGdlb21fYmFyKGFlcyh5PS4ucHJvcC4uKjEwMCwgZ3JvdXA9MSksIHdpZHRoPTAuNSkrCiAgbGFicyh4PSJTdXBwb3J0IGZvciBkZW1vY3JhY3kiLCB5PSJQZXJjZW50YWdlIiwgCiAgICAgICBjYXB0aW9uPSJBbWVyaWNhc0Jhcm9tZXRlciBieSBMQVBPUCwgMjAyMSIpKwogIGNvb3JkX2NhcnRlc2lhbih5bGltPWMoMCwgODApKQpgYGAKCkFzIHdlIHNheSwgdGhpcyBwbG90IHByZXNlbnRzIGEgYmFyIGZvciB0aGUgcGVyY2VudGFnZSBvZiBtaXNzaW5nIHZhbHVlcy4KSWYgYSByZXNlYXJjaGVyIHdvdWxkIGxpa2UgdG8gcHJlc2VudCBhIHBsb3Qgd2l0aCBwZXJjZW50YWdlcyBvZiB2YWxpZCBjYXNlcywgbWlzc2luZyB2YWx1ZXMgc2hvdWxkIGJlIGRyb3BwZWQuCldlIGNhbiB1c2UgdGhlIGNvbW1hbmQgYHN1YnNldGAgYWdhaW4sIGJ1dCB3aXRoaW4gYGdncGxvdGAgZm9yIHRoZSBjb21tYW5kIChpbnRlcm5hbGx5KSB3b3JrcyB3aXRoIHRoZSB2YXJpYWJsZSBubyBjb25zaWRlcmluZyB0aGUgbWlzc2luZyB2YWx1ZXMuClRoZSBzeW50YXggYCFpcy5uYSggKWAgbWFrZXMgdGhlIGNvbW1hbmQgdG8gbm90IGluY2x1ZGUgbWlzc2luZyB2YWx1ZXMgb2YgYSB2YXJpYWJsZSBpbiBjYWxjdWxhdGlvbnMuCklmIHdlIHdvdWxkIGhhdmUgdXNlZCBgIWlzLm5hKCApYCBvdXQgb2YgYGdncGxvdGAsIHdlIHdvdWxkIGhhdmUgZHJvcHBlZCBhbGwgb2JzZXJ2YXRpb25zIHdpdGggbWlzc2luZyB2YWx1ZXMgaW4gdGhlIGRhdGFzZXQsIGRlY3JlYXNpbmcgdGhlIE4gYW5kIGFmZmVjdGluZyBuZXh0IGNhbGN1bGF0aW9ucy4KCmBgYHtyIGdnYmFyMn0KZ2dwbG90KGRhdGE9c3Vic2V0KGxhcG9wMjEsICFpcy5uYShpbmc0cmVjKSksIGFlcyh4PWluZzRyZWMpKSsKICBnZW9tX2JhcihhZXMoeT0uLnByb3AuLioxMDAsIGdyb3VwPTEpLCB3aWR0aD0wLjUpKwogIGxhYnMoeD0iU3VwcG9ydCBmb3IgZGVtb2NyYWN5IiwgeT0iUGVyY2VudGFnZSIsIAogICAgICAgY2FwdGlvbj0iQW1lcmljYXNCYXJvbWV0ZXIgYnkgTEFQT1AsIDIwMjEiKSsKICBjb29yZF9jYXJ0ZXNpYW4oeWxpbT1jKDAsIDgwKSkKYGBgCgpVcCB0byB0aGlzIHBvaW50LCB3ZSBoYXZlIHByZXNlbnRlZCBhIGJhciBwbG90IG9mIGEgc2luZ2xlIHZhcmlhYmxlLCBzdXBwb3J0IGZvciBkZW1vY3JhY3ksIGZvciB0aGUgd2hvbGUgc2FtcGxlLCB0aGF0IGluY2x1ZGVzIGFsbCBjb3VudHJpZXMuCkZpZ3VyZSAxLjEgc2hvd3MgdGhlIHBlcmNlbnRhZ2Ugb2Ygc3VwcG9ydCBmb3IgZGVtb2NyYWN5IGJ5IGNvdW50cnkuCldlIHdpbGwgc2VlIHRoaXMgdHlwZSBvZiBwbG90IGluIGEgZm9sbG93aW5nIHNlY3Rpb24uCgojIFNvY2lhbCBtZWRpYSB1c2VycwoKTm93LCB3ZSBhcmUgcHJlc2VudGluZyBhbiBleGFtcGxlIG9mIHRoZSByZXBvcnQgVGhlIFB1bHNlIG9mIERlbW9jcmFjeSBmb3IgdGhlIDIwMTgvMTkgcm91bmQuCldlIGZvbGxvdyBzaW1pbGFyIHByb2NlZHVyZXMgYXMgdGhlIHNlY3Rpb24gYWJvdmUgYW5kIHdlIHdpbGwgcmVwbGljYXRlIHNvbWUgZmlndXJlcyBvZiB0aGUgcmVwb3J0IGZvciB0aGUgMjAxOC8xOSByb3VuZC4KV2UgYXJlIGdvaW5nIHRvIHdvcmsgd2l0aCB0aGVzZSB2YXJpYWJsZXM6IFNNRURJQTEuCkRvIHlvdSBoYXZlIGEgRmFjZWJvb2sgYWNjb3VudD87ClNNRURJQTQuCkRvIHlvdSBoYXZlIGEgVHdpdHRlciBhY2NvdW50PzsKU01FRElBNy4KRG8geW91IGhhdmUgYSBXaGF0c0FwcCBhY2NvdW50Py4KVGhlc2UgcXVlc3Rpb25zIGhhdmUgYXMgYW5zd2VyIG9wdGlvbnM6CgoxLiAgWWVzCgoyLiAgTm8KCldoZW4gcmVhZGluZyB0aGUgZGF0YWJhc2UgaW4gUiwgdGhpcyBwcm9ncmFtIGltcG9ydHMgdGhlIHZhcmlhYmxlcyBhcyAibnVtIiwgd2hpY2ggbW9zdCBmdW5jdGlvbnMgaW4gUiB0cmVhdCBhcyBudW1lcmljLgpUaGVzZSB2YXJpYWJsZXMgaGF2ZSB0byBiZSBjb252ZXJ0ZWQgdG8gdmFyaWFibGVzIG9mIHR5cGUgImZhY3RvciIgd2l0aCB0aGUgY29tbWFuZCBgYXMuZmFjdG9yYCwgc2luY2UgdGhleSBhcmUgY2F0ZWdvcmljYWwgdmFyaWFibGVzLgpXZSBzYXZlIHRoZXNlIG5ldyB2YXJpYWJsZXMgaW4gdGhlIGRhdGFmcmFtZS4KSGVyZSB3ZSBoYXZlIHVzZWQgdGhlIGA9YCBvcGVyYXRvciB3aGljaCBpcyBzaW1pbGFyIHRvIHRoZSBgPC1gIG9wZXJhdG9yIHRoYXQgYXNzaWducyBhIHByb2NlZHVyZSB0byBhIG5ldyBvYmplY3Qgb2YgYW4gUiBkYXRhZnJhbWUuCgpgYGB7ciBmYWN0b3IyfQpsYXBvcDE4JHNtZWRpYTFyID0gYXMuZmFjdG9yKGxhcG9wMTgkc21lZGlhMSkKbGFwb3AxOCRzbWVkaWE0ciA9IGFzLmZhY3RvcihsYXBvcDE4JHNtZWRpYTQpCmxhcG9wMTgkc21lZGlhN3IgPSBhcy5mYWN0b3IobGFwb3AxOCRzbWVkaWE3KQpgYGAKClRoZXNlIG5ldyB2YXJpYWJsZXMgb2YgdHlwZSBmYWN0b3IgaGF2ZSB0byBiZSBsYWJlbGVkIHdpdGggdGhlIGNvbW1hbmQgYGxldmVsc2AuCkEgdmVjdG9yIHdpdGggY29uY2F0ZW5hdGVkIGxhYmVscyBpcyB1c2VkLCB1c2luZyB0aGUgY29tbWFuZCBgYyggKWAuCgpgYGB7ciBsZXZlbDJ9CmxldmVscyhsYXBvcDE4JHNtZWRpYTFyKSA8LSBjKCJZZXMiLCAiTm8iKQpsZXZlbHMobGFwb3AxOCRzbWVkaWE0cikgPC0gYygiWWVzIiwgIk5vIikKbGV2ZWxzKGxhcG9wMTgkc21lZGlhN3IpIDwtIGMoIlllcyIsICJObyIpCmBgYAoKIyBDYWxjdWxhdGluZyB0aGUgdmFyaWFibGVzIG9mIHNvY2lhbCBuZXR3b3JrIHVzZXJzCgpBcyB3ZSBzYXcgaW4gYSBwcmV2aW91cyBtb2R1bGUsIHlvdSBjYW4gY2FsY3VsYXRlIG5ldyB2YXJpYWJsZXMgd2l0aCBjb25kaXRpb25hbCB2YWx1ZXMgb2Ygb3RoZXIgdmFyaWFibGVzIHVzaW5nIHRoZSBgaWZlbHNlYCBjb21tYW5kLgpJbiB0aGlzIHdheSwgd2UgY2FsY3VsYXRlIHRoZSB2YXJpYWJsZXMgb2Ygc29jaWFsIG5ldHdvcmsgdXNlcnMuCgpgYGB7ciB1c2VyfQpsYXBvcDE4JGZiX3VzZXIgPC0gaWZlbHNlKGxhcG9wMTgkc21lZGlhMT09MSAmIGxhcG9wMTgkc21lZGlhMjw9NCwgMSwgMCkKbGFwb3AxOCR0d191c2VyIDwtIGlmZWxzZShsYXBvcDE4JHNtZWRpYTQ9PTEgJiBsYXBvcDE4JHNtZWRpYTU8PTQsIDEsIDApCmxhcG9wMTgkd2FfdXNlciA8LSBpZmVsc2UobGFwb3AxOCRzbWVkaWE3PT0xICYgbGFwb3AxOCRzbWVkaWE4PD00LCAxLCAwKQpgYGAKCiMgRGVzY3JpYmluZyB0aGUgdmFyaWFibGVzCgpXaXRoIHRoZSB2YXJpYWJsZXMgcmVhZHksIHdlIG5vdyBwcm9jZWVkIHRvIG1ha2UgdGhlIGdlbmVyYWwgdGFibGVzIHdpdGggdGhlIGB0YWJsZWAgY29tbWFuZC4KTm90ZSB0aGUgdXNlIG9mIGAjYCBhcyBhIHdheSBvZiBtYWtpbmcgYW5ub3RhdGlvbnMsIHdoaWNoIGFyZSBub3QgUiBjb2RlLgoKYGBge3IgdGFibGVzfQp0YWJsZShsYXBvcDE4JHNtZWRpYTFyKSAjRmFjZWJvb2sKdGFibGUobGFwb3AxOCRzbWVkaWE0cikgI1R3aXR0ZXIKdGFibGUobGFwb3AxOCRzbWVkaWE3cikgI1doYXRzYXBwCmBgYAoKVGhpcyBgdGFibGVgIGNvbW1hbmQgZ2l2ZXMgdXMgdGhlIGFic29sdXRlIGZyZXF1ZW5jaWVzIChudW1iZXIgb2Ygb2JzZXJ2YXRpb25zKSBmb3IgZWFjaCBjYXRlZ29yeSBvZiB2YXJpYWJsZXMgKGluIHRoaXMgY2FzZSBZZXMgYW5kIE5vKS4KVG8gZ2V0IHRoZSByZWxhdGl2ZSBmcmVxdWVuY2llcywgd2Ugd2lsbCB1c2UgdGhlIGNvbW1hbmQgYHByb3AudGFibGVgLCB3aGVyZSB0aGUgcHJldmlvdXMgY29tbWFuZCBgdGFibGVgIGlzIG5lc3RlZC4KCmBgYHtyIHByb3BvcnRpb25zfQpwcm9wLnRhYmxlKHRhYmxlKGxhcG9wMTgkc21lZGlhMXIpKQpwcm9wLnRhYmxlKHRhYmxlKGxhcG9wMTgkc21lZGlhNHIpKQpwcm9wLnRhYmxlKHRhYmxlKGxhcG9wMTgkc21lZGlhN3IpKQpgYGAKCkhvd2V2ZXIsIHRoZSBjb21tYW5kIGBwcm9wLnRhYmxlYCByZXR1cm5zIHVzIHRvbyBtYW55IGRlY2ltYWwgcGxhY2VzIGFuZCB0aGUgcmVsYXRpdmUgZnJlcXVlbmNpZXMgb24gYSBzY2FsZSBvZiAwIHRvIDEuClRvIHJvdW5kIHRoaXMgZmlndXJlIHdlIHVzZSB0aGUgYHJvdW5kYCBjb21tYW5kLCB3aGljaCBhbGxvd3MgdXMgdG8gc3BlY2lmeSB0aGUgbnVtYmVyIG9mIGRlY2ltYWwgcGxhY2VzIHRvIGJlIGRpc3BsYXllZC4KQm90aCB0aGUgYHRhYmxlYCBjb21tYW5kIGFuZCB0aGUgYHByb3AudGFibGVgIGFyZSBuZXN0ZWQgd2l0aGluIHRoaXMgbmV3IGNvbW1hbmQuCkluIHRoaXMgY2FzZSwgd2UgdXNlIDMgZGVjaW1hbHMsIHNvIHdoZW4gaXQgaXMgbXVsdGlwbGllZCBieSAxMDAsIGl0IHJlbWFpbnMgaW4gdGhlIGZvcm0gb2YgYSBwZXJjZW50YWdlIHdpdGggMSBkZWNpbWFsIHBsYWNlLgoKYGBge3IgdGFibGV9CnJvdW5kKHByb3AudGFibGUodGFibGUobGFwb3AxOCRzbWVkaWExcikpLCAzKSoxMDAKcm91bmQocHJvcC50YWJsZSh0YWJsZShsYXBvcDE4JHNtZWRpYTRyKSksIDMpKjEwMApyb3VuZChwcm9wLnRhYmxlKHRhYmxlKGxhcG9wMTgkc21lZGlhN3IpKSwgMykqMTAwCmBgYAoKSXQgaXMgbm90IHByYWN0aWNhbCB0byBwcmVzZW50IDMgdGFibGVzIHdoZW4gdGhlIHZhcmlhYmxlcyBoYXZlIHRoZSBzYW1lIHJlc3BvbnNlIGNhdGVnb3JpZXMuCkZvciBwcmVzZW50YXRpb24gcHVycG9zZXMgaXQgbWlnaHQgYmUgYmV0dGVyIHRvIGJ1aWxkIGEgc2luZ2xlIHRhYmxlLgpZb3UgY2FuIHNhdmUgdGhlIHBhcnRpYWwgdGFibGVzIGluIG5ldyBvYmplY3RzIHdpdGggdGhlIG9wZXJhdG9yIGA9YCBhbmQgdGhlbiBqb2luIHRoZW0gYXMgcm93cyB3aXRoIHRoZSBjb21tYW5kIGByYmluZGAgaW4gYSBuZXcgZGF0YWZyYW1lICJ0YWJsZSIgd2l0aCB0aGUgY29tbWFuZCBgYXMuZGF0YS5mcmFtZWAsIGluIHN1Y2ggYSB3YXkgdGhhdCB0aGUgcmVzcG9uc2VzIHRvIGVhY2ggc29jaWFsIG5ldHdvcmsgYXBwZWFyIGluIHJvd3MuCgpgYGB7ciBmdWxsIHRhYmxlfQpGYWNlYm9vayA9IHJvdW5kKHByb3AudGFibGUodGFibGUobGFwb3AxOCRzbWVkaWExcikpLCAzKSoxMDAKVHdpdHRlciA9IHJvdW5kKHByb3AudGFibGUodGFibGUobGFwb3AxOCRzbWVkaWE0cikpLCAzKSoxMDAKV2hhdHNhcHAgPSByb3VuZChwcm9wLnRhYmxlKHRhYmxlKGxhcG9wMTgkc21lZGlhN3IpKSwgMykqMTAwCnRhYmxhID0gYXMuZGF0YS5mcmFtZShyYmluZChGYWNlYm9vaywgVHdpdHRlciwgV2hhdHNhcHApKQp0YWJsYQpgYGAKClRvIGhhdmUgYSBiZXR0ZXIgcHJlc2VudGF0aW9uIG9mIHRoZSB0YWJsZSwgeW91IGNhbiB1c2UgdGhlIGBrYWJsZWAgY29tbWFuZCBmcm9tIHRoZSBga25pdHJgIHBhY2thZ2UsIHVzaW5nIHRoZSB0YWJsZSBidWlsdCBhYm92ZS4KCmBgYHtyIHRhYmxhbWVqb3JhZGEsIHJlc3VsdHM9J2FzaXMnfQpsaWJyYXJ5KGtuaXRyKQprbml0cjo6a2FibGUodGFibGEsIGZvcm1hdD0ibWFya2Rvd24iKQpgYGAKCiMgUGxvdHRpbmcgdGhlIHZhcmlhYmxlcwoKSW4gR3JhcGggMy4xIG9mIHRoZSByZXBvcnQgaXQgaXMgb2JzZXJ2ZWQgdGhhdCB0aGVzZSBkYXRhIGFyZSByZXBvcnRlZCB0aHJvdWdoIGEgcGllIGNoYXJ0LgoKIVtdKEZpZ3VyZTMuMS5wbmcpe3dpZHRoPSI0NTEifQoKV2UgY2FuIHJlcHJvZHVjZSB0aGF0IGdyYXBoIHVzaW5nIHRoZSBgcGllYCBjb21tYW5kIHdoaWNoIGlzIHBhcnQgb2YgdGhlIGJhc2ljIFIgc3ludGF4LgpXaXRoaW4gdGhpcyBjb21tYW5kIHlvdSBjYW4gbmVzdCB0aGUgYHRhYmxlYCBjb21tYW5kIHRvIGdyYXBoIHRoZXNlIHZhbHVlcy4KCmBgYHtyIHBpZTN9CnBpZSh0YWJsZShsYXBvcDE4JHNtZWRpYTFyKSkKYGBgCgpZb3UgY291bGQgYWxzbyB0aGluayBvZiBhIGJhciBjaGFydC4KVXNpbmcgdGhlIGJhc2ljIFIgY29tbWFuZHMsIHlvdSBjYW4gdXNlIHRoZSBgYmFycGxvdGAgY29tbWFuZC4KCmBgYHtyIGJhcjJ9CmJhcnBsb3QocHJvcC50YWJsZSh0YWJsZShsYXBvcDE4JHNtZWRpYTFyKSkpCmBgYAoKVGhlc2UgZ3JhcGhpY2FsIGNvbW1hbmRzIGhhdmUgb3B0aW9ucyB0byBhZGp1c3QgdGhlIGdyYXBoLCBmb3IgZXhhbXBsZSB0byBpbmNsdWRlIHBlcmNlbnRhZ2VzIGFuZCBhZGp1c3Qgc2NhbGVzLgpCdXQsIHRvIGhhdmUgbW9yZSBncmFwaGljYWwgb3B0aW9ucywgd2UgY2FuIHVzZSB0aGUgYGdncGxvdGAgcGFja2FnZSB0byByZXByb2R1Y2UgdGhlIHBpZSBjaGFydC4KCkluIHRoaXMgZXhhbXBsZSwgd2UgaGF2ZSB0byBkZWZpbmUgZmlyc3QgdGhlIGRhdGEgdG8gYmUgdXNlZC4KVGhlIGBzdWJzZXRgIGNvbW1hbmQgaGFzIGJlZW4gdXNlZCBhZ2FpbiwgYnV0IGluc2lkZSBgZ2dwbG90YCBzbyB0aGF0IHRoZSBjb21tYW5kIChpbnRlcm5hbGx5KSB3b3JrcyB3aXRoIHRoZSB2YXJpYWJsZSBidXQgd2l0aG91dCB0aGUgbWlzc2luZyB2YWx1ZXMuClRoZSBgIWlzLm5hICgpYCBzeW50YXggcHJldmVudHMgdGhlIGNvbW1hbmQgZnJvbSBpbmNsdWRpbmcgbWlzc2luZyB2YWx1ZXMgb2YgYSB2YXJpYWJsZSBpbiBjYWxjdWxhdGlvbnMuCklmIGBkYXRhID0gbGFwb3BgIGhhZCBiZWVuIHVzZWQgdGhlIGdyYXBoIHdvdWxkIGhhdmUgaW5jbHVkZWQgYSBsYXJnZSBzZWN0b3IgY29ycmVzcG9uZGluZyB0byB0aGUgcHJvcG9ydGlvbiBvZiBOQS4KSWYgYCFpcy5uYSAoKWAgaGFkIGJlZW4gdXNlZCBvdXRzaWRlIG9mIGBnZ3Bsb3RgIGNyZWF0aW5nIGEgbmV3IHZhcmlhYmxlLCBhbGwgb2JzZXJ2YXRpb25zIHdpdGggbWlzc2luZyB2YWx1ZXMgd291bGQgaGF2ZSBiZWVuIHJlbW92ZWQsIHdoaWNoIHdvdWxkIGRlY3JlYXNlIHRoZSBOLCBhZmZlY3RpbmcgZnV0dXJlIGNhbGN1bGF0aW9ucy4KClRoZSBgZ2dwbG90YCBjb21tYW5kIHdvcmtzIGJ5IGFkZGluZyBsYXllcnMuClRoZSBgYWVzYCBzcGVjaWZpY2F0aW9uIGlzIHVzZWQgdG8gZGVmaW5lIHRoZSAiYWVzdGhldGljcyIgb2YgdGhlIGdyYXBoLgpJdCBpcyBnZW5lcmFsbHkgdXNlZCB0byBpbmRpY2F0ZSB3aGljaCB2YXJpYWJsZSBpcyBnb2luZyB0byBiZSBncmFwaGVkIG9uIHdoaWNoIGF4aXMgKHggb3IgeSkuCllvdSBjYW4gYWxzbyB1c2UgdGhlIGBmaWxsID1gIHNwZWNpZmljYXRpb24gdG8gZGVmaW5lIHRoZSBncm91cHMgdG8gYmUgZ2VuZXJhdGVkLgoKQWZ0ZXIgc3BlY2lmeWluZyB0aGUgZGF0YSBhbmQgdGhlIGF4ZXMsIHlvdSBoYXZlIHRvIHNwZWNpZnkgdGhlIHR5cGUgb2YgZ3JhcGggeW91IHdhbnQgdG8gbWFrZS4KVGhpcyBpcyBkb25lIHdpdGggZ2VvbWV0cmllcyAoImdlb20iKS4KVGhlcmUgaXMgbm8gZGlyZWN0IGdlb21ldHJ5IHRvIG1ha2UgYSBwaWUgY2hhcnQsIHNvIHlvdSBoYXZlIHRvIGluaXRpYWxseSB1c2UgYSBzaW1wbGUgYmFyIGNoYXJ0LCB1c2luZyB0aGUgY29tbWFuZCBgZ2VvbV9iYXIgKClgLCB3aGVyZSB0aGUgd2lkdGggb2YgdGhlIGJhciBpcyBkZWZpbmVkIGludGVybmFsbHkuCklmIHdlIGxlZnQgdGhlIHN5bnRheCBhdCB0aGlzIHBvaW50LCBhIGJhciB3b3VsZCBiZSBnZW5lcmF0ZWQgdGhhdCB3b3VsZCBiZSBkaXZpZGVkIGJ5IHRoZSB2YWx1ZXMgb2YgdGhlIHZhcmlhYmxlICJzbWVkaWExciIuClRvIGdlbmVyYXRlIHRoZSBwaWUgY2hhcnQsIHlvdSBoYXZlIHRvIGFkZCBhbm90aGVyIGNvbW1hbmQgYGNvb3JkX3BvbGFyYCwgd2hpY2ggdHJhbnNmb3JtcyB0aGUgYmFyIHRvIHBvbGFyIGNvb3JkaW5hdGVzLCBjcmVhdGluZyBhIHBpZSBjaGFydC4KCmBgYHtyIGdncGllLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpsaWJyYXJ5KGdncGxvdDIpICNsaWJyZXLDrWEgZXNwZWNpYWxpemFkYSBlbiBncsOhZmljb3MKZ2dwbG90KGRhdGE9c3Vic2V0KGxhcG9wMTgsICFpcy5uYShzbWVkaWExcikpLCBhZXMoeD0iIiwgZmlsbD1zbWVkaWExcikpKwogIGdlb21fYmFyKHdpZHRoPTEpICsKICBjb29yZF9wb2xhcigieSIsIHN0YXJ0PTApCmBgYAoKVGhlIGFib3ZlIGdyYXBoIGhhcyBzdGFydGVkIGZyb20gdGhlIHNhbWUgZGF0YWZyYW1lICJsYXBvcDE4IiwgdXNpbmcgdGhlIGRhdGEgZnJvbSAic21lZGlhMXIiLgpIb3dldmVyLCB0byBiZXR0ZXIgbWFuaXB1bGF0ZSB0aGUgZ3JhcGggaXQgaXMgZWFzaWVyIHRvIGNyZWF0ZSBhIG5ldyBkYXRhZnJhbWUgd2l0aCB0aGUgYWdncmVnYXRlZCBkYXRhIChmcmVxdWVuY2llcyBhbmQgJSkuCkluIG90aGVyIHdvcmRzLCBzYXZlIHRoZSByZXN1bHRzIGRhdGEgZnJvbSB0aGUgInNtZWRpYTFyIiB0YWJsZSBpbiBhIG5ldyBkYXRhZnJhbWUuClRoZW4gdGhhdCBuZXcgZGF0YWZyYW1lIGlzIHVzZWQgdG8gbWFrZSB0aGUgcGllIGdyYXBoIHdpdGggYGdncGxvdGAuCgpPbmUgYXNwZWN0IHRvIG5vdGUgaXMgdGhhdCBpbiB0aGlzIGNhc2UgdGhlIHRpZHl2ZXJzZSBpcyBiZWluZyB1c2VkLCB3aGljaCBpbmNsdWRlcyB0aGUgcGlwZSBgJT4lYCBjb21tYW5kIGZyb20gdGhlIGBkcGx5cmAgbGlicmFyeSwgd2hpY2ggaXMgYSAoc2xpZ2h0bHkpIGRpZmZlcmVudCB3YXkgb2Ygd3JpdGluZyBjb2RlIGluIFIsIGluIGEgY29uY2F0ZW5hdGVkIHdheSwgc3RlcCBieSBzdGVwLgpBIHNpbXBsZSBleHBsYW5hdGlvbiBvZiBob3cgdGhlIHBpcGUgaXMgdXNlZCBjYW4gYmUgZm91bmQgW2hlcmVdKGh0dHBzOi8vcHN5ci5kam5hdmFycm8ubmV0L3ByZWx1ZGUtdG8tZGF0YS5odG1sIzEyNF90aGVfcGlwZSxfJSUpLgoKVGhlIGZpcnN0IHRoaW5nIHRvIG5vdGljZSBpcyB0aGF0IGEgbmV3IG9iamVjdCBjYWxsZWQgImRmIiBpcyBnb2luZyB0byBiZSBjcmVhdGVkLgpJbmZvcm1hdGlvbiBjb21pbmcgZnJvbSB0aGUgZGF0YWZyYW1lICJsYXBvcDE4IiB3aWxsIGJlIHN0b3JlZCBpbiB0aGlzIG9iamVjdC4KVGhlIGBzdWJzZXRgIGNvbW1hbmQgaXMgdXNlZCB0byByZW1vdmUgdGhlIG1pc3NpbmcgdmFsdWVzIG9mICJzbWVkaWExciIgZnJvbSB0aGUgY2FsY3VsYXRpb24gb2YgdGhlIHBlcmNlbnRhZ2VzLgpUaGVuIChgJT4lYCksIHRoaXMgZGF0YSB3aWxsIGJlIGdyb3VwZWQgYnkgY2F0ZWdvcmllcyBvZiB0aGUgdmFyaWFibGUgInNtZWRpYTFyIi4KTmV4dCAoYCU+JWApLCBpbiBlYWNoIGdyb3VwIHRoZSB0b3RhbCBudW1iZXIgb2Ygb2JzZXJ2YXRpb25zIGlzIGNhbGN1bGF0ZWQgd2l0aCB0aGUgY29tbWFuZCBgc3VtbWFyaXNlKG4gPSBuKCkpYC4KRmluYWxseSAobGFzdCBzdGVwIHdpdGggYCU+JWApLCB3aXRoIHRoaXMgdG90YWwgYnkgZ3JvdXBzIHRoZSBwZXJjZW50YWdlcyBhcmUgY2FsY3VsYXRlZCBhbmQgdGhlc2UgcGVyY2VudGFnZXMgYXJlIHNhdmVkIGluIGEgbmV3IGNvbHVtbiAicGVyIi4KCmBgYHtyIHN1bW1hcnl0YWJsZSwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KbGlicmFyeShkcGx5cikKZGYgPSBzdWJzZXQobGFwb3AxOCwgIWlzLm5hKHNtZWRpYTFyKSkgJT4lCiAgICAgIGdyb3VwX2J5KHNtZWRpYTFyKSAlPiUgCiAgICAgIGRwbHlyOjpzdW1tYXJpc2UobiA9IG4oKSkgJT4lCiAgICAgIG11dGF0ZShwZXI9cm91bmQobi9zdW0obiksIDMpKjEwMCkKZGYKYGBgCgpXaXRoIHRoaXMgc3ludGF4LCBhIHRhYmxlIGlzIGNyZWF0ZWQgY29udGFpbmluZyB0aGUgdG90YWwgbnVtYmVyIG9mIG9ic2VydmF0aW9ucyBhbmQgdGhlIHBlcmNlbnRhZ2UgZm9yIGVhY2ggY2F0ZWdvcnkgb2YgdGhlIHZhcmlhYmxlICJzbWVkaWExciIuCkEgbW9yZSBkaXJlY3Qgd2F5IHRvIGNyZWF0ZSB0aGUgc2FtZSBkYXRhIGlzIHRvIHVzZSB0aGUgYGphbml0b3JgIGxpYnJhcnkgYW5kIHRoZSBgdGFieWxgIGNvbW1hbmQuCkluIFIgdGhlcmUgYXJlIG11bHRpcGxlIHdheXMgdG8gZ2V0IHRvIHRoZSBzYW1lIHJlc3VsdHMuCgpgYGB7ciBzdW1tYXJ5dGFibGUyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpsaWJyYXJ5KGphbml0b3IpCnN1YnNldChsYXBvcDE4LCAhaXMubmEoc21lZGlhMXIpKSAlPiUKICB0YWJ5bChzbWVkaWExcikKYGBgCgpPbmNlIHdlIGhhdmUgdGhlIHRhYmxlLCB3ZSBjYW4gdXNlIGl0IHRvIHByb2R1Y2UgdGhlIHBpZSBjaGFydCB3aXRoIGBnZ3Bsb3RgLgpOb3RlIHRoYXQgaW4gdGhpcyBjYXNlIHRoZSBkYXRhIHVzZWQgY29tZXMgZnJvbSB0aGUgZGF0YWZyYW1lIGRmIChub3QgZnJvbSBsYXBvcDE4KS4KVGhpcyBkYXRhZnJhbWUgaGFzIGEgY29sdW1uIGNhbGxlZCAicGVyIiB3aXRoIHRoZSByZXNwZWN0aXZlIHBlcmNlbnRhZ2VzLCB3aGljaCBzaG91bGQgYmUgcGxvdHRlZCBvbiB0aGUgWS1heGlzLgpBcyBpbiB0aGUgcHJldmlvdXMgY2FzZSwgdG8gbWFrZSB0aGUgcGllIGNoYXJ0LCB3ZSBzdGFydCBmcm9tIHRoZSBiYXIgY2hhcnQgKGhlbmNlIGBnZW9tX2JhcmApLCB3aGljaCBpcyB0aGVuIHBhc3NlZCB0byBwb2xhciBjb29yZGluYXRlcyAoaGVuY2UgYGNvb3JkX3BvbGFyYCkuCgpBIHRleHQgbGF5ZXIgaXMgYWRkZWQsIHdpdGggdGhlIHNwZWNpZmljYXRpb24gYGdlb21fdGV4dGAuCldpdGhpbiB0aGlzIHNwZWNpZmljYXRpb24sIGFuICJhZXN0aGV0aWMiIGlzIGRldGVybWluZWQgd2l0aCB0aGUgZGF0YSBsYWJlbCBgYWVzKGxhYmVsPS4uLilgLCB3aGVyZSB0aGUgcGVyY2VudGFnZSBkYXRhICJwZXIiIGFuZCB0aGUgc3ltYm9sICIlIiBhcmUgam9pbmVkIHdpdGggdGhlIGBwYXN0ZWAgY29tbWFuZCwgd2l0aCBhIHNwYWNlIChgc2VwPS4uLmApIGJldHdlZW4gdGhlbS4KU2V0IHRoZSBmb250IGNvbG9yIHdpdGggYGNvbG9yPSIuLi4iYCwgc2V0cyB0byB3aGl0ZSB0byBjb250cmFzdCB3aXRoIHRoZSBjb2xvcnMgb2YgdGhlIHBpZSBjaGFydC4KV2l0aCB0aGUgY29tbWFuZCBgaGp1c3Q9Li4uYCB0aGUgaG9yaXpvbnRhbCBwb3NpdGlvbiBvZiB0aGlzIHRleHQgaXMgYWRqdXN0ZWQuClRoZSBgZ2dwbG90YCBjb21tYW5kIGNhbiBpbmNsdWRlIHZhcmlvdXMgInRoZW1lcyIgZm9yIHRoZSBwbG90LgpJbiB0aGlzIGNhc2UsIGB0aGVtZV92b2lkKClgIGhhcyBiZWVuIHVzZWQsIHdoaWNoIGluZGljYXRlcyBhbiBlbXB0eSBiYWNrZ3JvdW5kLgpGaW5hbGx5LCB3aXRoIHRoZSBzcGVjaWZpY2F0aW9uIGBzY2FsZV9maWxsX2Rpc2NyZXRlKG5hbWU9Li4uKWAgeW91IGNhbiBjaGFuZ2UgdGhlIHRpdGxlIG9mIHRoZSBsZWdlbmQgc28gdGhhdCBpdCBkb2VzIG5vdCBzaG93IHRoZSBuYW1lIG9mIHRoZSB2YXJpYWJsZSwgYnV0IGEgbW9yZSBzdWl0YWJsZSBsYWJlbC4KCmBgYHtyIGdncGllMn0KZ2dwbG90KGRhdGE9ZGYsIGFlcyh4PSIiLCB5PXBlciwgZmlsbD1zbWVkaWExcikpKwogIGdlb21fYmFyKHdpZHRoPTEsIHN0YXQ9ImlkZW50aXR5IikrCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1wYXN0ZShwZXIsICIlIiwgc2VwPSIiKSksIGNvbG9yPSJ3aGl0ZSIsCiAgICAgICAgICAgIHBvc2l0aW9uPXBvc2l0aW9uX3N0YWNrKHZqdXN0PTAuNSksIHNpemU9MykrCiAgY29vcmRfcG9sYXIoInkiKSsKICB0aGVtZV92b2lkKCkrCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZShuYW1lPSJEbyB5b3UgaGF2ZSBhIEZhY2Vib29rIGFjY291bnQ/IikKYGBgCgpJZiBpbnN0ZWFkIG9mIGEgcGllIGNoYXJ0IHlvdSB3YW50IHRvIGRpc3BsYXkgYSBiYXIgY2hhcnQsIHdpdGggdGhlIGRhdGEgZnJvbSB0aGUgImxhcG9wMTgiIGRhdGFmcmFtZSB5b3UgY2FuIHVzZSB0aGUgZm9sbG93aW5nIGNvZGUuClVubGlrZSB0aGUgZmlyc3QgcGllIGNoYXJ0LCB0aGUgYGFlcyguLilgIHNwZWNpZmljYXRpb24gbm93IGluY2x1ZGVzIHRoZSB2YXJpYWJsZSAic21lZGlhMXIiIGFzIHRoZSB2YXJpYWJsZSB0byBiZSBwbG90dGVkIG9uIHRoZSBYLWF4aXMuCkluc2lkZSB0aGUgZ2VvbWV0cmljIG9iamVjdCBgZ2VvbV9iYXIoKWAgaXQgaXMgaW5kaWNhdGVkIHRoYXQgdGhlIGJhciBtdXN0IHJlcHJlc2VudCB0aGUgcHJvcG9ydGlvbnMgaW4gcGVyY2VudGFnZXMgYGFlcyh5PS4ucHJvcC4uKjEwMCwgZ3JvdXA9MSlgLgpJbiB0aGlzIGV4YW1wbGUsIGEgZ2VuZXJhbCBsYWJlbCBmb3IgdGhlIGdyYXBoIGFuZCBmb3IgdGhlIGF4ZXMgaGFzIGJlZW4gaW5jbHVkZWQgd2l0aCB0aGUgYGxhYnMoLi4uKWAgY29tbWFuZC4KSW4gdGhpcyBjb21tYW5kIHlvdSBjYW4gYWxzbyBhZGQgYSAiY2FwdGlvbiIgdG8gaW5kaWNhdGUgdGhlIHNvdXJjZSBvZiB0aGUgZGF0YS4KRmluYWxseSwgdGhlIHNwZWNpZmljYXRpb24gYGNvb3JkX2NhcnRlc2lhbih5bGltPWMoMCw2MCkpYCBsaW1pdHMgdGhlIFkgYXhpcyB0byB2YWx1ZXMgYmV0d2VlbiAwIGFuZCA2MC4KCmBgYHtyIGdnYmFyM30KZ2dwbG90KGRhdGE9c3Vic2V0KGxhcG9wMTgsICFpcy5uYShzbWVkaWExcikpLCBhZXMoeD1zbWVkaWExcikpKwogIGdlb21fYmFyKGFlcyh5PS4ucHJvcC4uKjEwMCwgZ3JvdXA9MSksIHdpZHRoPTAuNSkrCiAgbGFicyh0aXRsZT0iRG8geW91IGhhdmUgYSBGYWNlYm9vayBhY2NvdW50PyIsIHg9IkZhY2Vib29rIHVzZXIiLCB5PSJQZXJjZW50YWdlIiwgY2FwdGlvbj0iQW1lcmljYXNCYXJvbWV0ZXIgYnkgTEFQT1AsIDIwMTgvMTkiKSsKICBjb29yZF9jYXJ0ZXNpYW4oeWxpbT1jKDAsIDYwKSkKYGBgCgpJbiB0aGlzIGNhc2UgeW91IGNhbiBhbHNvIHVzZSB0aGUgZ3JvdXBlZCBkYXRhIG9mIHRoZSAiZGYiIGRhdGFmcmFtZS4KVW5saWtlIHRoZSBwcmV2aW91cyBvcHRpb24sIGluICJkZiIgdGhlcmUgaXMgdGhlIHBlcmNlbnRhZ2UgZGF0YSwgc28gaXQgc2hvdWxkIG5vdCBiZSBjYWxjdWxhdGVkIGluIHRoZSBjb2RlLCBzbyBpbiB0aGUgYWVzdGhldGljcyBzcGVjaWZpY2F0aW9uIGl0IGluZGljYXRlcyB0aGF0IHRoZSBhbHRlcm5hdGl2ZXMgc2hvdWxkIGJlIHNob3duIG9uIHRoZSBYIGF4aXMgb2YgdGhlIHZhcmlhYmxlICJzbWVkaWExciIgYW5kIG9uIHRoZSBZIGF4aXMgdGhlIHBlcmNlbnRhZ2UsIGluIHRoaXMgd2F5IGBhZXMoeD1tZWRpYTFyLCB5PXBlcilgLgpGb3IgdGhpcyByZWFzb24gYWxzbyBpbiB0aGUgYGdlb21fYmFyYCBzcGVjaWZpY2F0aW9uLCBub3cgaW5zdGVhZCBvZiByZXF1aXJpbmcgdGhlIGNhbGN1bGF0aW9uIG9mIHRoZSBwZXJjZW50YWdlLCBpdCBpcyBvbmx5IGluZGljYXRlZCB0byByZXBsaWNhdGUgdGhlIGRhdGEgKHdpdGggYHN0YXQ9ImlkZW50aXR5ImApIGZyb20gYGFlc2AuCkZpbmFsbHksIGluIHRoaXMgY2FzZSB3ZSBhZGQgdGhlIHRleHQgbGF5ZXIgdG8gaW5jbHVkZSB0aGUgcGVyY2VudGFnZXMgaW4gZWFjaCBjb2x1bW4sIHdpdGggdGhlIGBnZW9tX3RleHRgIHNwZWNpZmljYXRpb24uCgpgYGB7ciB9CmdncGxvdChkZiwgYWVzKHg9c21lZGlhMXIsIHk9cGVyKSkrCiAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiLCAgd2lkdGg9MC41KSsKICBnZW9tX3RleHQoYWVzKGxhYmVsPXBhc3RlKHBlciwgIiUiLCBzZXA9IiIpKSwgY29sb3I9ImJsYWNrIiwgdmp1c3Q9LTAuNSkrCiAgbGFicyh0aXRsZT0iRG8geW91IGhhdmUgYSBGYWNlYm9vayBhY2NvdW50PyIsIHg9IkZhY2Vib29rIHVzZXIiLCB5PSJQZXJjZW50YWdlIiwgY2FwdGlvbj0iQW1lcmljYXNCYXJvbWV0ZXIgYnkgTEFQT1AsIDIwMTgvMTkiKSsKICBjb29yZF9jYXJ0ZXNpYW4oeWxpbT1jKDAsIDYwKSkKYGBgCgpXZSBjb25zaWRlciB0aGlzIG9wdGlvbiBhIGVhc2llciB3YXkgdG8gd29yayB3aXRoIHRoaXMgZGF0YS4KRmlyc3QsIHdlIGhhdmUgdG8gY3JlYXRlIGEgZGF0YWZyYW1lIHdpdGggdGhlIHBlcmNlbnRhZ2VzIGFuZCB0aGUgbGFiZWxzLgpUaGVuLCB3ZSBoYXZlIHRvIHVzZSB0aGlzIGRhdGFmcmFtZSBpbiBgZ2dwbG90YC4KSW4gdGhlIGZvbGxvd2luZyBzZWN0aW9ucywgd2Ugd2lsbCB1c2UgdGhpcyB3YXkuCgojIFN1bW1hcnkKCkluIHRoaXMgZG9jdW1lbnQgd2UgaGF2ZSB3b3JrZWQgd2l0aCBub21pbmFsIGNhdGVnb3JpY2FsIHZhcmlhYmxlcywgc3VjaCBhcyB3aGV0aGVyIG9yIG5vdCB5b3Ugc3VwcHBvcnQgZGVtb2NyYWN5IG9yIHdoZXRoZXIgb3Igbm90IHlvdSB1c2Ugc29jaWFsIG5ldHdvcmtzLgpXZSBwcmVzZW50IHNldmVyYWwgd2F5cyB0byBkZXNjcmliZSB0aGVzZSB2YXJpYWJsZXMgaW4gZnJlcXVlbmN5IHRhYmxlcyBhbmQgdG8gcGxvdCB0aGVzZSB2YXJpYWJsZXMsIHVzaW5nIGNpcmN1bGFyIG9yIGJhciBncmFwaHMuCgojIENhbGN1bGF0aW9ucyBpbmNsdWRpbmcgZGVzaWduIGVmZmVjdAoKVGhlIHJlc3VsdHMgZm9yIHRoZSAyMDE4LzE5IHdhdmUgYXJlIG5vdCBleGFjdGx5IHRoZSBzYW1lIGFzIHRob3NlIGluIHRoZSByZXBvcnQsIHNpbmNlIExBUE9QIGluY2x1ZGVzIHRoZSBlZmZlY3Qgb2YgdGhlIHNhbXBsZSBkZXNpZ24gaW4gaXRzIGNhbGN1bGF0aW9ucy4KQWNjb3JkaW5nIHRvIHRoaXMgc3ludGF4LCBpdCBpcyBmb3VuZCB0aGF0IDU3LjElIG9mIGludGVydmlld2VlcyByZXBvcnQgYmVpbmcgYSBGYWNlYm9vayB1c2VyLCB3aGVuIDU2LjIlIGFwcGVhciBpbiB0aGUgcmVwb3J0LgpUaGUgc2FtZSB3aXRoIFR3aXR0ZXIsIHdoaWNoIGhlcmUgaXMgY2FsY3VsYXRlZCBhdCA4LjglIGFuZCBpbiB0aGUgcmVwb3J0IDcuOSU7IGFuZCB3aXRoIFdoYXRzQXBwIHRoYXQgYXBwZWFycyBoZXJlIHdpdGggNjQuNiUgYW5kIGluIHRoZSByZXBvcnQgd2l0aCA2NC40JS4KQXMgaW5kaWNhdGVkIGluIHRoZSBzZWN0aW9uIG9uIHRoZSB1c2Ugb2Ygc3VydmV5IHdlaWdodHMgdXNpbmcgZGF0YSBmcm9tIHRoZSBBbWVyaWNhc0Jhcm9tZXRlciAoYXZhaWxhYmxlIFtoZXJlXShodHRwczovL2FydHVyb21hbGRvbmFkby5naXRodWIuaW8vQmFyb21ldHJvRWR1X1dlYl9FbmcvRXhwYW5zaW9uLmh0bWwpKSwgdGhlcmUgYXJlIHNldmVyYWwgd2F5cyB0byByZXByb2R1Y2UgdGhlIHJlc3VsdHMgYnkgaW5jb3Jwb3JhdGluZyB0aGUgc3VydmV5IHdlaWdodHMuCkEgZmlyc3Qgb3B0aW9uIGlzIHRvIHVzZSB0aGUgY29tbWFuZCBgZnJlcWAsIHdoaWNoIGFsbG93cyB0aGUgaW5jbHVzaW9uIG9mIGEgd2VpZ2h0aW5nIHZhcmlhYmxlLCBzdWNoIGFzICJ3ZWlnaHQxNTAwIi4KVGhlIGBwbG90PUZgIHNwZWNpZmljYXRpb24gaXMgaW5jbHVkZWQgdG8gbm90IHByb2R1Y2UgdGhlIGJhciBncmFwaHMuCgpgYGB7ciB3ZWlnaHRlZCBkZXNjcmlwdGl2ZX0KbGlicmFyeShkZXNjcikKZGVzY3I6OmZyZXEobGFwb3AxOCRmYl91c2VyLCBsYXBvcDE4JHdlaWdodDE1MDAsIHBsb3QgPSBGKQpkZXNjcjo6ZnJlcShsYXBvcDE4JHR3X3VzZXIsIGxhcG9wMTgkd2VpZ2h0MTUwMCwgcGxvdCA9IEYpCmRlc2NyOjpmcmVxKGxhcG9wMTgkd2FfdXNlciwgbGFwb3AxOCR3ZWlnaHQxNTAwLCBwbG90ID0gRikKYGBgCgpXaXRob3V0IGNvbnNpZGVyaW5nIHRoZSBzdXJ2ZXkgd2VpZ2h0cywgNTcuMSUgb2YgdGhlIGludGVydmlld2VlcyBoYXZlIGEgRmFjZWJvb2sgYWNjb3VudC4KVGhpcyBwZXJjZW50YWdlIHZhcmllcyB0byA1NS4yJSBpZiB0aGUgZXhwYW5zaW9uIHZhcmlhYmxlIGlzIGluY2x1ZGVkLCB3aGljaCBpcyB0aGUgdmFsdWUgc2hvd24gaW4gdGhlIHJlcG9ydC4KVGhlc2Ugd2VpZ2h0ZWQgcmVzdWx0cyBjYW4gYWxzbyBiZSBzYXZlZCB0byBvYmplY3RzIGFuZCB0aGVuIGdyYXBoZWQgaW4gdGhlIHNhbWUgd2F5IGFzIHRoZSB1bndlaWdodGVkIHJlc3VsdHMuCgpJbiB0aGUgY2FzZSBvZiBGYWNlYm9vaywgdGhlIHRhYmxlIGNhbiBiZSBzYXZlZCBhcyBhIGRhdGFmcmFtZSwgdXNpbmcgdGhlIGNvbW1hbmQgYGFzLmRhdGEuZnJhbWVgLgpUaGlzIHRhYmxlIGluY2x1ZGVzIGRhdGEgdGhhdCB3ZSBkbyBub3QgcmVxdWlyZSwgc3VjaCBhcyB0aGUgTkEncyBhbmQgVG90YWwgcm93IGFuZCB0aGUgUGVyY2VudCBjb2x1bW4uClRoZXNlIHJvd3MgYW5kIHRoaXMgY29sdW1uIGFyZSBkZWxldGVkIHVzaW5nIHRoZSBzcGVjaWZpY2F0aW9uIGBbLWMoMyw0KSwgLTJdYC4KClRoZSBjb2x1bW5zIGFyZSB0aGVuIHJlbmFtZWQgdG8gYXZvaWQgdGhlICJWYWxpZCBQZXJjZW50IiBuYW1lLgpUaGV5IGFyZSBzaW1wbHkgbmFtZWQgImZyZXEiIGFuZCAicGVyIi4KVGhpcyBjb2x1bW4gInBlciIgaXMgdGhlIG9uZSB0aGF0IGhhcyB0aGUgZGF0YSB0aGF0IHdlIHdpbGwgZ3JhcGguCkZpbmFsbHksIGEgImxhYiIgY29sdW1uIGlzIGFkZGVkIHdpdGggdGhlIGxhYmVscyBvZiBlYWNoIHJvdyBvZiByZXN1bHRzLgoKYGBge3IgdGFibGUgZmJ9CmZiIDwtIGFzLmRhdGEuZnJhbWUoZGVzY3I6OmZyZXEobGFwb3AxOCRmYl91c2VyLCBsYXBvcDE4JHdlaWdodDE1MDAsIHBsb3QgPSBGKSkKZmIgPSBmYlstYygzLDQpLCAtMl0KY29sbmFtZXMoZmIpID0gYygiZnJlcSIsICJwZXIiKQpmYiRsYWIgPSBjKCJObyIsICJZZXMiKQpmYgpgYGAKCldpdGggdGhpcyBuZXcgZGF0YWZyYW1lIHdlIGNhbiByZXBsaWNhdGUgdGhlIHNhbWUgY29kZXMgdXNlZCBhYm92ZSB0byBtYWtlIGEgYmFyIGNoYXJ0IG9yIGEgcGllIGNoYXJ0LgpUaGUgZm9sbG93aW5nIGNvZGUgZGlzcGxheXMgdGhlIGJhciBjaGFydC4KTm90ZSB0aGF0IG5vdyB0aGUgImZiIiBkYXRhZnJhbWUgaXMgdXNlZCBhbmQgdGhhdCBpbiBhZXMgaXQgaXMgc3BlY2lmaWVkIHRoYXQgdGhlIGRhdGEgZnJvbSB0aGUgImxhYiIgY29sdW1uIG11c3QgYmUgb24gdGhlIFggYXhpcyBhbmQgdGhlIGRhdGEgZnJvbSB0aGUgInBlciIgY29sdW1uIG11c3QgYmUgb24gdGhlIFkgYXhpcy4KCmBgYHtyIHdlaWdodGVkIGJhcnN9CmdncGxvdChkYXRhPWZiLCBhZXMoeD1sYWIsIHk9cGVyKSkrCiAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiLCAgd2lkdGg9MC41KSsKICBnZW9tX3RleHQoYWVzKGxhYmVsPXBhc3RlKHJvdW5kKHBlciwgMSksICIlIiwgc2VwPSIiKSksIGNvbG9yPSJibGFjayIsIHZqdXN0PS0wLjUpKwogIGxhYnModGl0bGU9IkRvIHlvdSBoYXZlIGEgRmFjZWJvb2sgYWNjb3VudD8iLCB4PSJGYWNlYm9vayB1c2VyIiwgCiAgICAgICB5PSJQZXJjZW50YWdlIiwgY2FwdGlvbj0iQW1lcmljYXNCYXJvbWV0ZXIgYnkgTEFQT1AsIDIwMTgvMTkiKSsKICBjb29yZF9jYXJ0ZXNpYW4oeWxpbT1jKDAsIDYwKSkKYGBgCgpUaGUgc2FtZSBjYW4gYmUgZG9uZSB0byBjcmVhdGUgYSBwaWUgY2hhcnQuClRoaXMgZ3JhcGggcmVwcm9kdWNlcyB0aGUgcmVzdWx0cyBmb3VuZCBpbiBHcmFwaCAzLjEgb2YgdGhlIHJlcG9ydC4KCmBgYHtyIHdlaWdodGVkIHBpZX0KZ2dwbG90KGRhdGE9ZmIsIGFlcyh4PTIsIHk9cGVyLCBmaWxsPWxhYikpKwogIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IikrCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1wYXN0ZShyb3VuZChwZXIsIDEpLCAiJSIsIHNlcD0iIikpLCBjb2xvcj0id2hpdGUiLCAKICAgICAgICAgICAgcG9zaXRpb249cG9zaXRpb25fc3RhY2sodmp1c3Q9MC41KSwgc2l6ZT0zKSsKICBjb29yZF9wb2xhcigieSIpKwogIHRoZW1lX3ZvaWQoKSsKICBsYWJzKGNhcHRpb249IkFtw6lyaWNhc0Jhcm9tZXRlciBieSBMQVBPUCwgMjAxOC8xOSIpKwogIHNjYWxlX2ZpbGxfZGlzY3JldGUobmFtZT0iRG8geW91IGhhdmUgYSBGYWNlYm9vayBhY2NvdW50PyIpKwogIHhsaW0oMC41LCAyLjUpCmBgYAoKVGhlIHNlY29uZCBvcHRpb24gdG8gcmVwcm9kdWNlIHRoZSByZXN1bHRzIGluIHRoZSByZXBvcnQgaXMgdXNpbmcgdGhlIHBhY2thZ2UgYHN1cnZleWAuCkFzIHdlIGluZGljYXRlIGluIHRoaXMgW3NlY3Rpb25dKGh0dHBzOi8vYXJ0dXJvbWFsZG9uYWRvLmdpdGh1Yi5pby9CYXJvbWV0cm9FZHVfV2ViX0VuZy9FeHBhbnNpb24uaHRtbCksIHdlIGhhdmUgdG8gZGVmaW5lIGZpcnN0IHRoZSBzYW1wbGUgZGVzaWduIHdpdGggdGhlIGNvbW1hbmQgYHN2eWRlc2lnbmAuCgpgYGB7ciBzdXJ2ZXl9CmxpYnJhcnkoc3VydmV5KQpsYXBvcC5kZXNpZ24gPSBzdnlkZXNpZ24oaWRzID0gfnVwbSwgc3RyYXRhID0gfmVzdHJhdG9wcmksIHdlaWdodHMgPSB+d2VpZ2h0MTUwMCwgbmVzdD1UUlVFLCBkYXRhPWxhcG9wMTgpCmBgYAoKT25jZSB5b3UgaGF2ZSBjcmVhdGVkIHRoZSBkYXRhIHdpdGggdGhlIGV4cGFuc2lvbiBmYWN0b3IgaW4gdGhlICJsYXBvcC5kZXNpZ24iIG9iamVjdCwgeW91IGNhbiB1c2UgdGhlIG5hdGl2ZSBjb21tYW5kcyBvZiB0aGUgcGFja2FnZSBgc3VydmV5YCB0byBwZXJmb3JtIGNhbGN1bGF0aW9ucy4KRm9yIGV4YW1wbGUsIHRvIGNhbGN1bGF0ZSB0aGUgZnJlcXVlbmN5IGRpc3RyaWJ1dGlvbiB0YWJsZSB5b3UgY2FuIHVzZSB0aGUgYHN2eXRhYmxlYCBjb21tYW5kLgoKYGBge3Igc3Z5dGFibGV9CnN2eXRhYmxlKH5mYl91c2VyLCBkZXNpZ249bGFwb3AuZGVzaWduKQpgYGAKClRoZXNlIGZyZXF1ZW5jaWVzIGNhbiBiZSBuZXN0ZWQgaW4gdGhlIGBwcm9wLnRhYmxlYCBjb21tYW5kIHRvIGNhbGN1bGF0ZSB0aGUgcGVyY2VudGFnZXMgb2Ygc29jaWFsIG5ldHdvcmsgdXNlcnMuClRoZXNlIHJlc3VsdHMgYXJlIHRoZSBzYW1lIGFzIHRob3NlIHNob3duIGluIHRoZSBwcmV2aW91cyBncmFwaHMgYW5kIHRob3NlIHRoYXQgYXBwZWFyIGluIHRoZSByZXBvcnQuCgpUaGVzZSBkYXRhIGNhbiBhbHNvIGJlIHNhdmVkIGluIGEgZGF0YWZyYW1lIHRoYXQgaXMgYWRhcHRlZCBmb3IgZ3JhcGhpbmcsIGZvbGxvd2luZyB0aGUgc2FtZSBwcm9jZWR1cmUgYXMgaW4gdGhlIHByZXZpb3VzIGdyYXBocy4KCmBgYHtyIHN2eXRhYmxlIHByb3B9CnByb3AudGFibGUoc3Z5dGFibGUofmZiX3VzZXIsIGRlc2lnbj1sYXBvcC5kZXNpZ24pKQpwcm9wLnRhYmxlKHN2eXRhYmxlKH50d191c2VyLCBkZXNpZ249bGFwb3AuZGVzaWduKSkKcHJvcC50YWJsZShzdnl0YWJsZSh+d2FfdXNlciwgZGVzaWduPWxhcG9wLmRlc2lnbikpCmBgYAo=
Social media users
Now, we are presenting an example of the report The Pulse of Democracy for the 2018/19 round. We follow similar procedures as the section above and we will replicate some figures of the report for the 2018/19 round. We are going to work with these variables: SMEDIA1. Do you have a Facebook account?; SMEDIA4. Do you have a Twitter account?; SMEDIA7. Do you have a WhatsApp account?. These questions have as answer options:
Yes
No
When reading the database in R, this program imports the variables as “num”, which most functions in R treat as numeric. These variables have to be converted to variables of type “factor” with the command
as.factor
, since they are categorical variables. We save these new variables in the dataframe. Here we have used the=
operator which is similar to the<-
operator that assigns a procedure to a new object of an R dataframe.These new variables of type factor have to be labeled with the command
levels
. A vector with concatenated labels is used, using the commandc( )
.