Introduction
This section presents basic aspect of the use of R and RStudio.
Objects
In the previous section we mentioned that the Environment shows
produced and loaded objects. In R, we can create objects and then
manipulate them. For example, the Figure 1.1 shows the percentage of
people who support democracy by country. If we want to save result for
Uruguay (UY), we can create an object.
The following line of code creates an object called “UY”, which saves
the number 80. This object is shown in the Environment, both the name,
as the value it saves.
UY = 80
If we want to calculate the difference in percentage point between
Uruguay, the country with the highest support for democracy, and Haiti,
the one that shows the lowest percentage, we can rest the object minus
the value of Haiti´s percentage. When we run this code, RStudio shows
the result (34 percentage points).
UY - 46
## [1] 34
Objects in R not only can save numbers, but also can save characters
(or string of characters). The AmericasBarometer collects information
from almost all countries in the Americas. The following table shows
countries in which LAPOP has collected information in some wave of the
AmericasBarometer.
If we want to save a country´s name in an object, we can name the
object “country1” and write the name of the country (a string of
characters) in between quotation marks.
country1 = "Mexico"
This new object appears in the Envorinment.
Vectors
A vector is an object that contain a set of elements, such as numbers
or string of characters, among other types. This data has to be
concatenated. For this reason, the function c(…)
appears
before this series of numbers.
For example, we can create a vector called “support” that saves all
the percentages of the Figure 1.1.
support = c(80, 73, 71, 69, 68, 67, 66, 63, 63, 63, 62, 61, 61, 57, 53, 52, 50, 50, 49, 46)
In a similar way, we can create a vector with the names (or acronyms)
of all countries, in quotation marks and within the function
c(…)
.
country = c("UY", "SV", "CR", "AR", "CL", "BR", "GY", "MX", "EC", "NI", "DO", "PN", "BO", "JA", "CO", "GT", "PY", "PE", "HN", "HT")
It is not necessary to follow the same order of Figure 1.1; however,
it is suggested for reasons explained below.
We can select particular elements of a vector using […]
.
For example, if we want to recall Argentina, both its name and
percentage, we can write the position of that country in brackets.
country[4]
## [1] "AR"
support[4]
## [1] 69
Functions
A function is a procedure that receives an input and produces an
output. For example, the function Y = X^2 gets a value for X, for
example 2, and returns a value for Y, in this case 4. R has algebraic
functions, such as square root or logarithm. For example, the function
log(…)
receives a value for X and returns a value for Y
equals to the logarithm of X.
sqrt(36)
## [1] 6
log(20)
## [1] 2.995732
Also, we can apply a function to a set of data, such as those saved
in a vector. For example, if we want to calculate the rate of people who
support democracy per 1000 people in all countries, we hace to multiply
the vector “country” by 10. In this case, the function of multiplication
is applied to each element of the vector.
support2 = support*10
support2
## [1] 800 730 710 690 680 670 660 630 630 630 620 610 610 570 530 520 500 500 490
## [20] 460
There are more useful function for our goals because they work over a
set of values, such as those saved in a vector, calculating a single
value. For example, if we want to calculate the average support for
democracy in all countries shown in Figure 1.1, we can use the function
mean(…)
.
mean(support)
## [1] 61.2
This function gets all the values in a vector, sum all of them and
divide by the number of observations, resulting in the average.
Other functions useful for statistics are the median, the standard
deviation, minimum, maximum and sum.
median(support)
## [1] 62.5
sd(support)
## [1] 9.070484
min(support)
## [1] 46
max(support)
## [1] 80
sum(support)
## [1] 1224
Figure 1.1 shows results for countries where the AmericasBarometer
has information. However, in some cases, a vector can include a missing
value. For example, this figure does not show information for Venezuela,
country where LAPOP did not do fieldwork for security reasons. If we
want to create a vector that includes a missing value, we can run this
code:
support2 = c(support, NA)
support2
## [1] 80 73 71 69 68 67 66 63 63 63 62 61 61 57 53 52 50 50 49 46 NA
We have used the same name “support2”, so we have overwrited this
vector with the new values. This vector, that includes only numbers, now
contain a last value NA.
Some functions cannot calculate their procedures if vectors contain
values NA. For example, the function mean
.
mean(support2)
## [1] NA
The direct calculation of the mean of vector “support2” give a
results NA. To be able to calculate, we have to indicate that the
function does not have to take into account this value NA. We have to
use the specification na.rm=True
.
mean(support2, na.rm=T)
## [1] 61.2
Packages
R is a collaborative project. Many developers produce new packages
that are administered by the same R project. This packages can include
many functions that help to manipulate data.
For example, R have native functions to import dataset from a variety
of formats, such as Excel, SPPS or STATA. Each format has an specific
function, such as read_csv
or read_dta
.
However, developers have produced a package called “rio”, that includes
a function import
, which allows to import every type of
dataset. This package does not come with the standard installation of R,
so, we have to install this package to be able to use it.
For installing a package, we use the command
install.packages
with the name of the needed package
between quotation marks.
R es un proyecto colaborativo. Muchos desarrolladores producen nuevos
paquetes que son administrados por el mismo proyecto de R. Estos
paquetes pueden incluir muchas funciones que ayudan a manejar datos. In
this case, we have used a # before the code because we have installed
this package previously. The # serves to show comments of lines of code
that we want to show, but not run.
# install.packages("rio")
Once installed, We have to activate this package to be able to use
its functions. This is done with the command library
. We do
not need quotation marks in this case. Once activated, we can use every
function of this library, such as the function import
. We
can check this procedure in the bottom right panel, in the “Packages”
tab. The package “rio” appears with a check.
library(rio)
Dataframes
Dataframes are rectangular data structures. As convention, dataframes
have vectors in columns and observations in rows. To create a dataframe,
we can use the command data.frame(...)
.
For example, we can create a dataframe that joins data from vector
“country” and vector “support”. Both vectors have the same dimensions.
We see in the Environmet that both vectors have dimension [1:20]. We can
save this dataframe in an object “supportLA”.
supportLA = data.frame(country, support)
supportLA
## country support
## 1 UY 80
## 2 SV 73
## 3 CR 71
## 4 AR 69
## 5 CL 68
## 6 BR 67
## 7 GY 66
## 8 MX 63
## 9 EC 63
## 10 NI 63
## 11 DO 62
## 12 PN 61
## 13 BO 61
## 14 JA 57
## 15 CO 53
## 16 GT 52
## 17 PY 50
## 18 PE 50
## 19 HN 49
## 20 HT 46
We see that the object “supportLA” is saved in a separated section in
the Environment called “Data”. This objects has 20 observations (that
is, 20 rows or countries) and two variables (that is, two vectors or two
columns). We can click in this object and see the data in a separate
tab.
If we would want to create a dataframe with vectors “country” and
“support2”, R gives an error message because these vectors have
different dimensions.
Now, the vector “support” is part of the dataframe “supportLA”. To be
able to use the functions in a dataframe, we should specify the column,
from which we want to apply the function. For example, if we want to
calculate the average support of democracy from the dataframe
“supportLA”, we have to specify the columns with “$”.
mean(supportLA$support)
## [1] 61.2
In general, every dataset is a rectangular structure where we have
observations in rows and variables in columns; what changes is the
number of rows and columns.
For example, an AmericasBarometer dataset in a country may have 1,500
observations (1,500 rows) and more than 100 variables (more than 100
columns). In that case, every observation is a person that responded the
survey and a columns (or vector) recorded responses of all respondents
in a question from the questionnaire.
Further, a join dataset (a merged data) is a dataset of all
countries. This dataset may have more than 30 thousand observations
(that is, all respondents in every countri in a particular wave of the
AmericasBarometer) and more that 100 columns.
Going beyond the size of the dataset, columns are vector to which we
can apply functions.
In the following section about importing the AmericasBarometer data
in RStudio, we will see ways to download a dataset from this project and
upload it in RStudio.
Summary
In this section, we have reviewed basic aspect of R, such as objects
and vectors, basic functions that we can apply to these objects. Also,
we have reviewed a way to install libraries, to activate them and be
able to use their functions. Finally, the idea of a dataframe was
explained.
LS0tCnRpdGxlOiAiQmFzaWMgcHJvY2VkdXJlcyIKb3V0cHV0OgogIGh0bWxfZG9jdW1lbnQ6CiAgICB0b2M6IHRydWUKICAgIHRvY19mbG9hdDogdHJ1ZQogICAgY29sbGFwc2VkOiBmYWxzZQogICAgbnVtYmVyX3NlY3Rpb25zOiBmYWxzZQogICAgdG9jX2RlcHRoOiAxCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICB0aGVtZTogZmxhdGx5CiAgICAjY29kZV9mb2xkaW5nOiBoaWRlCmVkaXRvcl9vcHRpb25zOiAKICBtYXJrZG93bjogCiAgICB3cmFwOiBzZW50ZW5jZQotLS0KCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQobWVzc2FnZT1GQUxTRSx3YXJuaW5nPUZBTFNFLCBjYWNoZT1UUlVFKQpgYGAKCmBgYHtjc3MgY29sb3IsIGVjaG89RkFMU0V9Ci5jb2x1bW5zIHtkaXNwbGF5OiBmbGV4O30KaDEge2NvbG9yOiAjMzM2NkNDO30KYGBgCgojIEludHJvZHVjdGlvbgoKVGhpcyBzZWN0aW9uIHByZXNlbnRzIGJhc2ljIGFzcGVjdCBvZiB0aGUgdXNlIG9mIFIgYW5kIFJTdHVkaW8uCgojIE9iamVjdHMKCkluIHRoZSBwcmV2aW91cyBzZWN0aW9uIHdlIG1lbnRpb25lZCB0aGF0IHRoZSBFbnZpcm9ubWVudCBzaG93cyBwcm9kdWNlZCBhbmQgbG9hZGVkIG9iamVjdHMuCkluIFIsIHdlIGNhbiBjcmVhdGUgb2JqZWN0cyBhbmQgdGhlbiBtYW5pcHVsYXRlIHRoZW0uCkZvciBleGFtcGxlLCB0aGUgRmlndXJlIDEuMSBzaG93cyB0aGUgcGVyY2VudGFnZSBvZiBwZW9wbGUgd2hvIHN1cHBvcnQgZGVtb2NyYWN5IGJ5IGNvdW50cnkuCklmIHdlIHdhbnQgdG8gc2F2ZSByZXN1bHQgZm9yIFVydWd1YXkgKFVZKSwgd2UgY2FuIGNyZWF0ZSBhbiBvYmplY3QuCgohW10oRmlndXJlMS4xLnBuZyl7d2lkdGg9IjUzOSJ9CgpUaGUgZm9sbG93aW5nIGxpbmUgb2YgY29kZSBjcmVhdGVzIGFuIG9iamVjdCBjYWxsZWQgIlVZIiwgd2hpY2ggc2F2ZXMgdGhlIG51bWJlciA4MC4KVGhpcyBvYmplY3QgaXMgc2hvd24gaW4gdGhlIEVudmlyb25tZW50LCBib3RoIHRoZSBuYW1lLCBhcyB0aGUgdmFsdWUgaXQgc2F2ZXMuCgpgYGB7ciBvYmplY3R9ClVZID0gODAKYGBgCgpJZiB3ZSB3YW50IHRvIGNhbGN1bGF0ZSB0aGUgZGlmZmVyZW5jZSBpbiBwZXJjZW50YWdlIHBvaW50IGJldHdlZW4gVXJ1Z3VheSwgdGhlIGNvdW50cnkgd2l0aCB0aGUgaGlnaGVzdCBzdXBwb3J0IGZvciBkZW1vY3JhY3ksIGFuZCBIYWl0aSwgdGhlIG9uZSB0aGF0IHNob3dzIHRoZSBsb3dlc3QgcGVyY2VudGFnZSwgd2UgY2FuIHJlc3QgdGhlIG9iamVjdCBtaW51cyB0aGUgdmFsdWUgb2YgSGFpdGnCtHMgcGVyY2VudGFnZS4KV2hlbiB3ZSBydW4gdGhpcyBjb2RlLCBSU3R1ZGlvIHNob3dzIHRoZSByZXN1bHQgKDM0IHBlcmNlbnRhZ2UgcG9pbnRzKS4KCmBgYHtyIHJlc3R9ClVZIC0gNDYKYGBgCgpPYmplY3RzIGluIFIgbm90IG9ubHkgY2FuIHNhdmUgbnVtYmVycywgYnV0IGFsc28gY2FuIHNhdmUgY2hhcmFjdGVycyAob3Igc3RyaW5nIG9mIGNoYXJhY3RlcnMpLgpUaGUgQW1lcmljYXNCYXJvbWV0ZXIgY29sbGVjdHMgaW5mb3JtYXRpb24gZnJvbSBhbG1vc3QgYWxsIGNvdW50cmllcyBpbiB0aGUgQW1lcmljYXMuClRoZSBmb2xsb3dpbmcgdGFibGUgc2hvd3MgY291bnRyaWVzIGluIHdoaWNoIExBUE9QIGhhcyBjb2xsZWN0ZWQgaW5mb3JtYXRpb24gaW4gc29tZSB3YXZlIG9mIHRoZSBBbWVyaWNhc0Jhcm9tZXRlci4KCiFbXShjb3VudHJ5LnBuZykKCklmIHdlIHdhbnQgdG8gc2F2ZSBhIGNvdW50cnnCtHMgbmFtZSBpbiBhbiBvYmplY3QsIHdlIGNhbiBuYW1lIHRoZSBvYmplY3QgImNvdW50cnkxIiBhbmQgd3JpdGUgdGhlIG5hbWUgb2YgdGhlIGNvdW50cnkgKGEgc3RyaW5nIG9mIGNoYXJhY3RlcnMpIGluIGJldHdlZW4gcXVvdGF0aW9uIG1hcmtzLgoKYGBge3IgY291bnRyeX0KY291bnRyeTEgPSAiTWV4aWNvIgpgYGAKClRoaXMgbmV3IG9iamVjdCBhcHBlYXJzIGluIHRoZSBFbnZvcmlubWVudC4KCiMgVmVjdG9ycwoKQSB2ZWN0b3IgaXMgYW4gb2JqZWN0IHRoYXQgY29udGFpbiBhIHNldCBvZiBlbGVtZW50cywgc3VjaCBhcyBudW1iZXJzIG9yIHN0cmluZyBvZiBjaGFyYWN0ZXJzLCBhbW9uZyBvdGhlciB0eXBlcy4KVGhpcyBkYXRhIGhhcyB0byBiZSBjb25jYXRlbmF0ZWQuCkZvciB0aGlzIHJlYXNvbiwgdGhlIGZ1bmN0aW9uIGBjKOKApilgIGFwcGVhcnMgYmVmb3JlIHRoaXMgc2VyaWVzIG9mIG51bWJlcnMuCgpGb3IgZXhhbXBsZSwgd2UgY2FuIGNyZWF0ZSBhIHZlY3RvciBjYWxsZWQgInN1cHBvcnQiIHRoYXQgc2F2ZXMgYWxsIHRoZSBwZXJjZW50YWdlcyBvZiB0aGUgRmlndXJlIDEuMS4KCmBgYHtyIHZlY3RvciBwZXJjZW50YWdlc30Kc3VwcG9ydCA9IGMoODAsIDczLCA3MSwgNjksIDY4LCA2NywgNjYsIDYzLCA2MywgNjMsIDYyLCA2MSwgNjEsIDU3LCA1MywgNTIsIDUwLCA1MCwgNDksIDQ2KQpgYGAKCkluIGEgc2ltaWxhciB3YXksIHdlIGNhbiBjcmVhdGUgYSB2ZWN0b3Igd2l0aCB0aGUgbmFtZXMgKG9yIGFjcm9ueW1zKSBvZiBhbGwgY291bnRyaWVzLCBpbiBxdW90YXRpb24gbWFya3MgYW5kIHdpdGhpbiB0aGUgZnVuY3Rpb24gYGMo4oCmKWAuCgpgYGB7ciB2ZWN0b3IgcGFpc30KY291bnRyeSA9IGMoIlVZIiwgIlNWIiwgIkNSIiwgIkFSIiwgIkNMIiwgIkJSIiwgIkdZIiwgIk1YIiwgIkVDIiwgIk5JIiwgIkRPIiwgIlBOIiwgIkJPIiwgIkpBIiwgIkNPIiwgIkdUIiwgIlBZIiwgIlBFIiwgIkhOIiwgIkhUIikKYGBgCgpJdCBpcyBub3QgbmVjZXNzYXJ5IHRvIGZvbGxvdyB0aGUgc2FtZSBvcmRlciBvZiBGaWd1cmUgMS4xOyBob3dldmVyLCBpdCBpcyBzdWdnZXN0ZWQgZm9yIHJlYXNvbnMgZXhwbGFpbmVkIGJlbG93LgoKV2UgY2FuIHNlbGVjdCBwYXJ0aWN1bGFyIGVsZW1lbnRzIG9mIGEgdmVjdG9yIHVzaW5nIGBb4oCmXWAuCkZvciBleGFtcGxlLCBpZiB3ZSB3YW50IHRvIHJlY2FsbCBBcmdlbnRpbmEsIGJvdGggaXRzIG5hbWUgYW5kIHBlcmNlbnRhZ2UsIHdlIGNhbiB3cml0ZSB0aGUgcG9zaXRpb24gb2YgdGhhdCBjb3VudHJ5IGluIGJyYWNrZXRzLgoKYGBge3Igc2VsZWN0IHZlY3Rvcn0KY291bnRyeVs0XQpzdXBwb3J0WzRdCmBgYAoKIyBGdW5jdGlvbnMKCkEgZnVuY3Rpb24gaXMgYSBwcm9jZWR1cmUgdGhhdCByZWNlaXZlcyBhbiBpbnB1dCBhbmQgcHJvZHVjZXMgYW4gb3V0cHV0LgpGb3IgZXhhbXBsZSwgdGhlIGZ1bmN0aW9uIFkgPSBYXF4yIGdldHMgYSB2YWx1ZSBmb3IgWCwgZm9yIGV4YW1wbGUgMiwgYW5kIHJldHVybnMgYSB2YWx1ZSBmb3IgWSwgaW4gdGhpcyBjYXNlIDQuClIgaGFzIGFsZ2VicmFpYyBmdW5jdGlvbnMsIHN1Y2ggYXMgc3F1YXJlIHJvb3Qgb3IgbG9nYXJpdGhtLgpGb3IgZXhhbXBsZSwgdGhlIGZ1bmN0aW9uIGBsb2co4oCmKWAgcmVjZWl2ZXMgYSB2YWx1ZSBmb3IgWCBhbmQgcmV0dXJucyBhIHZhbHVlIGZvciBZIGVxdWFscyB0byB0aGUgbG9nYXJpdGhtIG9mIFguCgpgYGB7ciByb290fQpzcXJ0KDM2KQpsb2coMjApCmBgYAoKQWxzbywgd2UgY2FuIGFwcGx5IGEgZnVuY3Rpb24gdG8gYSBzZXQgb2YgZGF0YSwgc3VjaCBhcyB0aG9zZSBzYXZlZCBpbiBhIHZlY3Rvci4KRm9yIGV4YW1wbGUsIGlmIHdlIHdhbnQgdG8gY2FsY3VsYXRlIHRoZSByYXRlIG9mIHBlb3BsZSB3aG8gc3VwcG9ydCBkZW1vY3JhY3kgcGVyIDEwMDAgcGVvcGxlIGluIGFsbCBjb3VudHJpZXMsIHdlIGhhY2UgdG8gbXVsdGlwbHkgdGhlIHZlY3RvciAiY291bnRyeSIgYnkgMTAuCkluIHRoaXMgY2FzZSwgdGhlIGZ1bmN0aW9uIG9mIG11bHRpcGxpY2F0aW9uIGlzIGFwcGxpZWQgdG8gZWFjaCBlbGVtZW50IG9mIHRoZSB2ZWN0b3IuCgpgYGB7ciBzdXBwb3J0Mn0Kc3VwcG9ydDIgPSBzdXBwb3J0KjEwCnN1cHBvcnQyCmBgYAoKVGhlcmUgYXJlIG1vcmUgdXNlZnVsIGZ1bmN0aW9uIGZvciBvdXIgZ29hbHMgYmVjYXVzZSB0aGV5IHdvcmsgb3ZlciBhIHNldCBvZiB2YWx1ZXMsIHN1Y2ggYXMgdGhvc2Ugc2F2ZWQgaW4gYSB2ZWN0b3IsIGNhbGN1bGF0aW5nIGEgc2luZ2xlIHZhbHVlLgpGb3IgZXhhbXBsZSwgaWYgd2Ugd2FudCB0byBjYWxjdWxhdGUgdGhlIGF2ZXJhZ2Ugc3VwcG9ydCBmb3IgZGVtb2NyYWN5IGluIGFsbCBjb3VudHJpZXMgc2hvd24gaW4gRmlndXJlIDEuMSwgd2UgY2FuIHVzZSB0aGUgZnVuY3Rpb24gYG1lYW4o4oCmKWAuCgpgYGB7ciBtZWFufQptZWFuKHN1cHBvcnQpCmBgYAoKVGhpcyBmdW5jdGlvbiBnZXRzIGFsbCB0aGUgdmFsdWVzIGluIGEgdmVjdG9yLCBzdW0gYWxsIG9mIHRoZW0gYW5kIGRpdmlkZSBieSB0aGUgbnVtYmVyIG9mIG9ic2VydmF0aW9ucywgcmVzdWx0aW5nIGluIHRoZSBhdmVyYWdlLgoKT3RoZXIgZnVuY3Rpb25zIHVzZWZ1bCBmb3Igc3RhdGlzdGljcyBhcmUgdGhlIG1lZGlhbiwgdGhlIHN0YW5kYXJkIGRldmlhdGlvbiwgbWluaW11bSwgbWF4aW11bSBhbmQgc3VtLgoKYGBge3Igb3RoZXIgZnVuY3Rpb25zfQptZWRpYW4oc3VwcG9ydCkKc2Qoc3VwcG9ydCkKbWluKHN1cHBvcnQpCm1heChzdXBwb3J0KQpzdW0oc3VwcG9ydCkKYGBgCgpGaWd1cmUgMS4xIHNob3dzIHJlc3VsdHMgZm9yIGNvdW50cmllcyB3aGVyZSB0aGUgQW1lcmljYXNCYXJvbWV0ZXIgaGFzIGluZm9ybWF0aW9uLgpIb3dldmVyLCBpbiBzb21lIGNhc2VzLCBhIHZlY3RvciBjYW4gaW5jbHVkZSBhIG1pc3NpbmcgdmFsdWUuCkZvciBleGFtcGxlLCB0aGlzIGZpZ3VyZSBkb2VzIG5vdCBzaG93IGluZm9ybWF0aW9uIGZvciBWZW5lenVlbGEsIGNvdW50cnkgd2hlcmUgTEFQT1AgZGlkIG5vdCBkbyBmaWVsZHdvcmsgZm9yIHNlY3VyaXR5IHJlYXNvbnMuCklmIHdlIHdhbnQgdG8gY3JlYXRlIGEgdmVjdG9yIHRoYXQgaW5jbHVkZXMgYSBtaXNzaW5nIHZhbHVlLCB3ZSBjYW4gcnVuIHRoaXMgY29kZToKCmBgYHtyIGFwb3lvIGNvbiBOQX0Kc3VwcG9ydDIgPSBjKHN1cHBvcnQsIE5BKQpzdXBwb3J0MgpgYGAKCldlIGhhdmUgdXNlZCB0aGUgc2FtZSBuYW1lICJzdXBwb3J0MiIsIHNvIHdlIGhhdmUgb3ZlcndyaXRlZCB0aGlzIHZlY3RvciB3aXRoIHRoZSBuZXcgdmFsdWVzLgpUaGlzIHZlY3RvciwgdGhhdCBpbmNsdWRlcyBvbmx5IG51bWJlcnMsIG5vdyBjb250YWluIGEgbGFzdCB2YWx1ZSBOQS4KClNvbWUgZnVuY3Rpb25zIGNhbm5vdCBjYWxjdWxhdGUgdGhlaXIgcHJvY2VkdXJlcyBpZiB2ZWN0b3JzIGNvbnRhaW4gdmFsdWVzIE5BLgpGb3IgZXhhbXBsZSwgdGhlIGZ1bmN0aW9uIGBtZWFuYC4KCmBgYHtyIG1lYW4gc3VwcG9ydDJ9Cm1lYW4oc3VwcG9ydDIpCmBgYAoKVGhlIGRpcmVjdCBjYWxjdWxhdGlvbiBvZiB0aGUgbWVhbiBvZiB2ZWN0b3IgInN1cHBvcnQyIiBnaXZlIGEgcmVzdWx0cyBOQS4KVG8gYmUgYWJsZSB0byBjYWxjdWxhdGUsIHdlIGhhdmUgdG8gaW5kaWNhdGUgdGhhdCB0aGUgZnVuY3Rpb24gZG9lcyBub3QgaGF2ZSB0byB0YWtlIGludG8gYWNjb3VudCB0aGlzIHZhbHVlIE5BLgpXZSBoYXZlIHRvIHVzZSB0aGUgc3BlY2lmaWNhdGlvbiBgbmEucm09VHJ1ZWAuCgpgYGB7ciBtZWFuIHN1cHBvcnQgbmEucm19Cm1lYW4oc3VwcG9ydDIsIG5hLnJtPVQpCmBgYAoKIyBQYWNrYWdlcwoKUiBpcyBhIGNvbGxhYm9yYXRpdmUgcHJvamVjdC4KTWFueSBkZXZlbG9wZXJzIHByb2R1Y2UgbmV3IHBhY2thZ2VzIHRoYXQgYXJlIGFkbWluaXN0ZXJlZCBieSB0aGUgc2FtZSBSIHByb2plY3QuClRoaXMgcGFja2FnZXMgY2FuIGluY2x1ZGUgbWFueSBmdW5jdGlvbnMgdGhhdCBoZWxwIHRvIG1hbmlwdWxhdGUgZGF0YS4KCkZvciBleGFtcGxlLCBSIGhhdmUgbmF0aXZlIGZ1bmN0aW9ucyB0byBpbXBvcnQgZGF0YXNldCBmcm9tIGEgdmFyaWV0eSBvZiBmb3JtYXRzLCBzdWNoIGFzIEV4Y2VsLCBTUFBTIG9yIFNUQVRBLgpFYWNoIGZvcm1hdCBoYXMgYW4gc3BlY2lmaWMgZnVuY3Rpb24sIHN1Y2ggYXMgYHJlYWRfY3N2YCBvciBgcmVhZF9kdGFgLgpIb3dldmVyLCBkZXZlbG9wZXJzIGhhdmUgcHJvZHVjZWQgYSBwYWNrYWdlIGNhbGxlZCAicmlvIiwgdGhhdCBpbmNsdWRlcyBhIGZ1bmN0aW9uIGBpbXBvcnRgLCB3aGljaCBhbGxvd3MgdG8gaW1wb3J0IGV2ZXJ5IHR5cGUgb2YgZGF0YXNldC4KVGhpcyBwYWNrYWdlIGRvZXMgbm90IGNvbWUgd2l0aCB0aGUgc3RhbmRhcmQgaW5zdGFsbGF0aW9uIG9mIFIsIHNvLCB3ZSBoYXZlIHRvIGluc3RhbGwgdGhpcyBwYWNrYWdlIHRvIGJlIGFibGUgdG8gdXNlIGl0LgoKRm9yIGluc3RhbGxpbmcgYSBwYWNrYWdlLCB3ZSB1c2UgdGhlIGNvbW1hbmQgYGluc3RhbGwucGFja2FnZXNgIHdpdGggdGhlIG5hbWUgb2YgdGhlIG5lZWRlZCBwYWNrYWdlIGJldHdlZW4gcXVvdGF0aW9uIG1hcmtzLgoKUiBlcyB1biBwcm95ZWN0byBjb2xhYm9yYXRpdm8uCk11Y2hvcyBkZXNhcnJvbGxhZG9yZXMgcHJvZHVjZW4gbnVldm9zIHBhcXVldGVzIHF1ZSBzb24gYWRtaW5pc3RyYWRvcyBwb3IgZWwgbWlzbW8gcHJveWVjdG8gZGUgUi4KRXN0b3MgcGFxdWV0ZXMgcHVlZGVuIGluY2x1aXIgbXVjaGFzIGZ1bmNpb25lcyBxdWUgYXl1ZGFuIGEgbWFuZWphciBkYXRvcy4KSW4gdGhpcyBjYXNlLCB3ZSBoYXZlIHVzZWQgYSBcIyBiZWZvcmUgdGhlIGNvZGUgYmVjYXVzZSB3ZSBoYXZlIGluc3RhbGxlZCB0aGlzIHBhY2thZ2UgcHJldmlvdXNseS4KVGhlIFwjIHNlcnZlcyB0byBzaG93IGNvbW1lbnRzIG9mIGxpbmVzIG9mIGNvZGUgdGhhdCB3ZSB3YW50IHRvIHNob3csIGJ1dCBub3QgcnVuLgoKYGBge3IgaW5zdGFsYXIgcGFxdWV0ZXN9CiMgaW5zdGFsbC5wYWNrYWdlcygicmlvIikKYGBgCgpPbmNlIGluc3RhbGxlZCwgV2UgaGF2ZSB0byBhY3RpdmF0ZSB0aGlzIHBhY2thZ2UgdG8gYmUgYWJsZSB0byB1c2UgaXRzIGZ1bmN0aW9ucy4KVGhpcyBpcyBkb25lIHdpdGggdGhlIGNvbW1hbmQgYGxpYnJhcnlgLgpXZSBkbyBub3QgbmVlZCBxdW90YXRpb24gbWFya3MgaW4gdGhpcyBjYXNlLgpPbmNlIGFjdGl2YXRlZCwgd2UgY2FuIHVzZSBldmVyeSBmdW5jdGlvbiBvZiB0aGlzIGxpYnJhcnksIHN1Y2ggYXMgdGhlIGZ1bmN0aW9uIGBpbXBvcnRgLgpXZSBjYW4gY2hlY2sgdGhpcyBwcm9jZWR1cmUgaW4gdGhlIGJvdHRvbSByaWdodCBwYW5lbCwgaW4gdGhlICJQYWNrYWdlcyIgdGFiLgpUaGUgcGFja2FnZSAicmlvIiBhcHBlYXJzIHdpdGggYSBjaGVjay4KCmBgYHtyIGFjdGl2YXJ9CmxpYnJhcnkocmlvKQpgYGAKCiMgRGF0YWZyYW1lcwoKRGF0YWZyYW1lcyBhcmUgcmVjdGFuZ3VsYXIgZGF0YSBzdHJ1Y3R1cmVzLgpBcyBjb252ZW50aW9uLCBkYXRhZnJhbWVzIGhhdmUgdmVjdG9ycyBpbiBjb2x1bW5zIGFuZCBvYnNlcnZhdGlvbnMgaW4gcm93cy4KVG8gY3JlYXRlIGEgZGF0YWZyYW1lLCB3ZSBjYW4gdXNlIHRoZSBjb21tYW5kIGBkYXRhLmZyYW1lKC4uLilgLgoKRm9yIGV4YW1wbGUsIHdlIGNhbiBjcmVhdGUgYSBkYXRhZnJhbWUgdGhhdCBqb2lucyBkYXRhIGZyb20gdmVjdG9yICJjb3VudHJ5IiBhbmQgdmVjdG9yICJzdXBwb3J0Ii4KQm90aCB2ZWN0b3JzIGhhdmUgdGhlIHNhbWUgZGltZW5zaW9ucy4KV2Ugc2VlIGluIHRoZSBFbnZpcm9ubWV0IHRoYXQgYm90aCB2ZWN0b3JzIGhhdmUgZGltZW5zaW9uIFsxOjIwXS4KV2UgY2FuIHNhdmUgdGhpcyBkYXRhZnJhbWUgaW4gYW4gb2JqZWN0ICJzdXBwb3J0TEEiLgoKYGBge3IgZGF0YWZyYW1lfQpzdXBwb3J0TEEgPSBkYXRhLmZyYW1lKGNvdW50cnksIHN1cHBvcnQpCnN1cHBvcnRMQQpgYGAKCldlIHNlZSB0aGF0IHRoZSBvYmplY3QgInN1cHBvcnRMQSIgaXMgc2F2ZWQgaW4gYSBzZXBhcmF0ZWQgc2VjdGlvbiBpbiB0aGUgRW52aXJvbm1lbnQgY2FsbGVkICJEYXRhIi4KVGhpcyBvYmplY3RzIGhhcyAyMCBvYnNlcnZhdGlvbnMgKHRoYXQgaXMsIDIwIHJvd3Mgb3IgY291bnRyaWVzKSBhbmQgdHdvIHZhcmlhYmxlcyAodGhhdCBpcywgdHdvIHZlY3RvcnMgb3IgdHdvIGNvbHVtbnMpLgpXZSBjYW4gY2xpY2sgaW4gdGhpcyBvYmplY3QgYW5kIHNlZSB0aGUgZGF0YSBpbiBhIHNlcGFyYXRlIHRhYi4KCklmIHdlIHdvdWxkIHdhbnQgdG8gY3JlYXRlIGEgZGF0YWZyYW1lIHdpdGggdmVjdG9ycyAiY291bnRyeSIgYW5kICJzdXBwb3J0MiIsIFIgZ2l2ZXMgYW4gZXJyb3IgbWVzc2FnZSBiZWNhdXNlIHRoZXNlIHZlY3RvcnMgaGF2ZSBkaWZmZXJlbnQgZGltZW5zaW9ucy4KCk5vdywgdGhlIHZlY3RvciAic3VwcG9ydCIgaXMgcGFydCBvZiB0aGUgZGF0YWZyYW1lICJzdXBwb3J0TEEiLgpUbyBiZSBhYmxlIHRvIHVzZSB0aGUgZnVuY3Rpb25zIGluIGEgZGF0YWZyYW1lLCB3ZSBzaG91bGQgc3BlY2lmeSB0aGUgY29sdW1uLCBmcm9tIHdoaWNoIHdlIHdhbnQgdG8gYXBwbHkgdGhlIGZ1bmN0aW9uLgpGb3IgZXhhbXBsZSwgaWYgd2Ugd2FudCB0byBjYWxjdWxhdGUgdGhlIGF2ZXJhZ2Ugc3VwcG9ydCBvZiBkZW1vY3JhY3kgZnJvbSB0aGUgZGF0YWZyYW1lICJzdXBwb3J0TEEiLCB3ZSBoYXZlIHRvIHNwZWNpZnkgdGhlIGNvbHVtbnMgd2l0aCAiXCQiLgoKYGBge3Igc3VwcG9ydCBkYXRhfQptZWFuKHN1cHBvcnRMQSRzdXBwb3J0KQpgYGAKCkluIGdlbmVyYWwsIGV2ZXJ5IGRhdGFzZXQgaXMgYSByZWN0YW5ndWxhciBzdHJ1Y3R1cmUgd2hlcmUgd2UgaGF2ZSBvYnNlcnZhdGlvbnMgaW4gcm93cyBhbmQgdmFyaWFibGVzIGluIGNvbHVtbnM7IHdoYXQgY2hhbmdlcyBpcyB0aGUgbnVtYmVyIG9mIHJvd3MgYW5kIGNvbHVtbnMuCgpGb3IgZXhhbXBsZSwgYW4gQW1lcmljYXNCYXJvbWV0ZXIgZGF0YXNldCBpbiBhIGNvdW50cnkgbWF5IGhhdmUgMSw1MDAgb2JzZXJ2YXRpb25zICgxLDUwMCByb3dzKSBhbmQgbW9yZSB0aGFuIDEwMCB2YXJpYWJsZXMgKG1vcmUgdGhhbiAxMDAgY29sdW1ucykuCkluIHRoYXQgY2FzZSwgZXZlcnkgb2JzZXJ2YXRpb24gaXMgYSBwZXJzb24gdGhhdCByZXNwb25kZWQgdGhlIHN1cnZleSBhbmQgYSBjb2x1bW5zIChvciB2ZWN0b3IpIHJlY29yZGVkIHJlc3BvbnNlcyBvZiBhbGwgcmVzcG9uZGVudHMgaW4gYSBxdWVzdGlvbiBmcm9tIHRoZSBxdWVzdGlvbm5haXJlLgoKRnVydGhlciwgYSBqb2luIGRhdGFzZXQgKGEgbWVyZ2VkIGRhdGEpIGlzIGEgZGF0YXNldCBvZiBhbGwgY291bnRyaWVzLgpUaGlzIGRhdGFzZXQgbWF5IGhhdmUgbW9yZSB0aGFuIDMwIHRob3VzYW5kIG9ic2VydmF0aW9ucyAodGhhdCBpcywgYWxsIHJlc3BvbmRlbnRzIGluIGV2ZXJ5IGNvdW50cmkgaW4gYSBwYXJ0aWN1bGFyIHdhdmUgb2YgdGhlIEFtZXJpY2FzQmFyb21ldGVyKSBhbmQgbW9yZSB0aGF0IDEwMCBjb2x1bW5zLgoKR29pbmcgYmV5b25kIHRoZSBzaXplIG9mIHRoZSBkYXRhc2V0LCBjb2x1bW5zIGFyZSB2ZWN0b3IgdG8gd2hpY2ggd2UgY2FuIGFwcGx5IGZ1bmN0aW9ucy4KCkluIHRoZSBmb2xsb3dpbmcgc2VjdGlvbiBhYm91dCBpbXBvcnRpbmcgdGhlIEFtZXJpY2FzQmFyb21ldGVyIGRhdGEgaW4gUlN0dWRpbywgd2Ugd2lsbCBzZWUgd2F5cyB0byBkb3dubG9hZCBhIGRhdGFzZXQgZnJvbSB0aGlzIHByb2plY3QgYW5kIHVwbG9hZCBpdCBpbiBSU3R1ZGlvLgoKIyBTdW1tYXJ5CgpJbiB0aGlzIHNlY3Rpb24sIHdlIGhhdmUgcmV2aWV3ZWQgYmFzaWMgYXNwZWN0IG9mIFIsIHN1Y2ggYXMgb2JqZWN0cyBhbmQgdmVjdG9ycywgYmFzaWMgZnVuY3Rpb25zIHRoYXQgd2UgY2FuIGFwcGx5IHRvIHRoZXNlIG9iamVjdHMuCkFsc28sIHdlIGhhdmUgcmV2aWV3ZWQgYSB3YXkgdG8gaW5zdGFsbCBsaWJyYXJpZXMsIHRvIGFjdGl2YXRlIHRoZW0gYW5kIGJlIGFibGUgdG8gdXNlIHRoZWlyIGZ1bmN0aW9ucy4KRmluYWxseSwgdGhlIGlkZWEgb2YgYSBkYXRhZnJhbWUgd2FzIGV4cGxhaW5lZC4K