You will find here a very quick introduction to R for beginners.

Installing R

R is a free open-source statistical software for various platforms such as Windows, Mac OS and Linux. To find out what is the latest version of R, you can look at the CRAN (Comprehensive R Network) website, http://cran.r-project.org/. Binaries are available for Linux, Mac and Windows.

An additional tutorial may be found here or you may to refer to the CRAN page, R Installation and Administration.

What is a R session?

When opening the R console, you see: “>”. This is the R prompt. The commands needed for a particular task are to be typed after this prompt. The command is executed after pressing Enter. Throughout this document, examples of submitted R code are presented in code blocks such as this one:

print("Hello world")
[1] "Hello world"

The output of the submitted R code is printed in the console after execution. The number in brackets “[1]” is the index of the first vector component on the output line. It turns out that R considers the character string “Hello word” as a vector of length one. It is not useful here, but it is part of R’s way of printing vectors.

You can insert comments in your R code which are not run by R. To this aim, start each line to be commented with a hash “#”.

# a comment
2+3
[1] 5

As a matter of fact, R is a functional, object-based language. Objects can be of many types and classes. We investigate a little further three object classes, vector, matrix and list, in section More on data types below. The type of a basic element can be one of integer (the values 0, +/-1, +/-2, …) , double (for real numbers), character (any text that is wrapped within pairs of " or ’) or logical (for the values TRUE and FALSE). The assignment operator is “<-”. It is often useful to store object values and then do calculations on these stored values. Obviously, you can also store the result of your calculations.

# create an object named as x
x <- 5
# check the value of x
x
[1] 5
# ask for the value of x
x+2
[1] 7

When you quit R, you are asked if you want to save the workspace. If you choose “no”, then all your stored values will be lost. If you choose “yes”, then your stored values are saved in your workspace. This means that next time you launch R, you can work with your stored values.

Rather than saving the workspace when you quit R, a recommanded practice consists of saving your R commands in a script. Basically, an R script is a text file which is preferably written in an external text editor. We recommand the use of RStudio (see next subsection) but Emacs or Notepad++ would also do. The extension for R code files is .R. To run instructions written in a script, copy and paste them from the editor to the R console, or run the command source("script.R") in order to execute the file script.R (provided that the file script.R is in R working directory).

Installing RStudio

Once R is installed, you can choose to work either with the basic R console, or within an integrated development environment (IDE). RStudio is a popular IDE for R and supports debugging, workspace management and plotting.

Start an R session

Set R working directory

It turns out that the files identified simply by their names (ie without specifying any path) refer to files in R working directory on your system.
To see where R is currently working on your system, you can use the command getwd() in the R console which prints R current working directory. Usually, the default R working directory is not a convenient repertory. In order to read files from a specific location or to write files to a specific location, it is recommanded to set R working directory as a convenient repertory rather than having file names preceeded by a (long) path.
The command setwd("path to workDir") sets R working directory as “workDir”.

Loading additional packages

A package is a collection of R functions, data, documentation and compiled code designed to address a specific problem. The directory where a package is stored is called a library. R comes with some standard packages which are automatically installed when you install R. To run our code, additional R packages are needed, such as the png package. These additional packages do not come with the standard installation of R, so you need to install them (with the command install.package). Once the package is installed, you have to load it (with the command load) at each R session.

# Installing a package with root access using a local mirror 
# NB: you are actually using the local mirror server to download the package.
install.packages("png")
# loading the package
library(png)

# Installing a package without root access:
# - choose a directory where the downloaded packages will be stored
# NB: in this tutorial, we have chosen "/data/Rpackages/" 
# - download png_0.1-7.tar.gz on https://cran.r-project.org/web/packages/png/index.html
install.packages("png", lib="/data/Rpackages/")
# loading the package
library(png, lib.loc="/data/Rpackages/")

Online help

Numerous R tutorials may be found online. The CRAN website provides some official documentation here, and additional contributed manuals here. You can also ask for R’s built-in help associated to any of the R functions. For example, to ask about the mean function, enter ?mean.

More on data types

Vector

A vector is a finite sequence of elements of a single basic type (integer, numeric, character, logical …). In particular, a scalar is a numerical vector of size one. The construct operator c(...) is used to define vectors.

# define a vector x of length 2 having components "5" and "10"
x <- c(5,10)
x
[1]  5 10

To create a vector from a simple sequence of integers, use the colon “:”.

# the integer number from 5 to 11
x <- 6:11
x
[1]  6  7  8  9 10 11

Specific values of a vector x can be accessed through their index placed inside a single square bracket “[]”.

# print the second component of x
x[2]
[1] 7
## print the components of x from index 3 to 5
x[3:5]
[1]  8  9 10

To get the number of components of a vector, use the function length.

length(x)
[1] 6

Matrix

A matrix is a collection of elements of a single basic type which are arranged in a two-dimensional rectangular array. To create a matrix from a vector x, use the function matrix.

# create a matrix called A with 2 rows and 3 columns, the components of which are those stored in x
A <- matrix(x,nrow=2,ncol=3)
# print A
A
     [,1] [,2] [,3]
[1,]    6    8   10
[2,]    7    9   11

To get the number of rows and columns of a matrix, use the function dim.

# print the dimension of A
dim(A)
[1] 2 3
# print the number of rows of A
dim(A)[1]
[1] 2
# print the number of columns of A
dim(A)[2]
[1] 3

The element at the mth row and nth column of A can be accessed through the expression A[m,n].

# print the element at the second row and third column of A
A[2,3]
[1] 11
# print the second row of A
A[2,]
[1]  7  9 11
# print the third column of A
A[,3]
[1] 10 11

List

A list is an ordered collection of R objects. The elements of a list can be of different types or classes. In the example below, mylist is a list having four components. Its first component is the vector x, the second component is the matrix A, the third component is a logical vector of length 4, the last one is a list of length 2. The function str prints the structure of any R object.

# print the second component of x
mylist <- list(myvector=x, mymatrix=A, c(TRUE,FALSE,FALSE,FALSE), list('cat','dog'))
str(mylist)
List of 4
 $ myvector: int [1:6] 6 7 8 9 10 11
 $ mymatrix: int [1:2, 1:3] 6 7 8 9 10 11
 $         : logi [1:4] TRUE FALSE FALSE FALSE
 $         :List of 2
  ..$ : chr "cat"
  ..$ : chr "dog"

The length of a list is the number of objects in that list. To get the number of objects in a list, use the function length.

# print the length of the list called "mylist"
length(mylist)
[1] 4

The object of the list mylist at position m can be accessed through the expression mylist[[m]].

# print the third object of the list called "mylist"
mylist[[3]]
[1]  TRUE FALSE FALSE FALSE

Some objects of the list mylist have a name. For instance, the first object of mylist is named as myvector. The third object of mylist has no name. The object of the list mylist the name of which is myvector can be accessed through the expression mylist$myvector.

# print the object of the list called "mylist" the name of which is "myvector"
mylist$myvector
[1]  6  7  8  9 10 11

LS0tCnRpdGxlOiAiSG93IHRvIGdldCBSIHdvcmtpbmcgb24geW91ciBzeXN0ZW0gYW5kIHRvIHVzZSBpdCAocXVpdGUpIHF1aWNrbHk/IgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgpZb3Ugd2lsbCBmaW5kIGhlcmUgYSB2ZXJ5IHF1aWNrIGludHJvZHVjdGlvbiB0byBSIGZvciBiZWdpbm5lcnMuCgojI0luc3RhbGxpbmcgUgoKUiBpcyBhIGZyZWUgb3Blbi1zb3VyY2Ugc3RhdGlzdGljYWwgc29mdHdhcmUgZm9yIHZhcmlvdXMgcGxhdGZvcm1zIHN1Y2ggYXMgV2luZG93cywgTWFjIE9TIGFuZCBMaW51eC4gVG8gZmluZCBvdXQgd2hhdCBpcyB0aGUgbGF0ZXN0IHZlcnNpb24gb2YgUiwgeW91IGNhbiBsb29rIGF0IHRoZSBDUkFOIChDb21wcmVoZW5zaXZlIFIgTmV0d29yaykgd2Vic2l0ZSwgPGEgaHJlZj0iaHR0cDovL2NyYW4uci1wcm9qZWN0Lm9yZy8iIHRhcmdldD0iX2JsYW5rIj5odHRwOi8vY3Jhbi5yLXByb2plY3Qub3JnLy48L2E+IEJpbmFyaWVzIGFyZSBhdmFpbGFibGUgZm9yIExpbnV4LCBNYWMgYW5kIFdpbmRvd3MuCgoqIEdvIHRvIDxhIGhyZWY9Imh0dHA6Ly9jcmFuLnItcHJvamVjdC5vcmcvIiB0YXJnZXQ9Il9ibGFuayI+Y3Jhbi5yLXByb2plY3Qub3JnLzwvYT4uIAoqIElmIFdpbmRvd3MgaXMgeW91ciBvcGVyYXRpbmcgc3lzdGVtLCB0aGUgcHJvY2VkdXJlIGlzIGFzIGZvbGxvdy4gCiAgICArIENsaWNrIG9uICJEb3dubG9hZCBSIGZvciBXaW5kb3dzIi4gCiAgICArIENsaWMgb24gImJhc2UiLiAKICAgICsgQ2xpYyBvbiAiRG93bmxvYWQgUiAzLjMuMSBmb3IgV2luZG93cyIgKE5vdGUgdGhhdCAzLjMuMSBpcyB0aGUgY3VycmVudCB2ZXJzaW9uIG9mIFIgYXMgb2YgSnVseSA1LCAyMDE2LCBidXQgdXNlIHdoYXRldmVyIHNob3dzIHVwIGFzIGN1cnJlbnQpLgogICAgKyBTYXZlIHRoZSBmaWxlICJSLTMuMy4xLXdpbi5leGUiLgogICAgKyBEb3VibGUtY2xpY2sgb24gaXQgdG8gZXhlY3V0ZSBpdC4gQSBTZXR1cCBXaXphcmQgc2hvdWxkIGFwcGVhci4gS2VlcCBjbGlja2luZyAiTmV4dCIgKG9yIGNoYW5nZSBmZWF0dXJlcyBpZiB5b3UgdW5kZXJzdGFuZCB0aGVtKSwgdW50aWwgaXQgaXMgZmluaXNoZWQuCllvdSBzaG91bGQgbm93IHNlZSBhbiBpY29uIG9uIHlvdXIgZGVza3RvcCwgd2l0aCBhIGxhcmdlIGNhcGl0YWwgUi4KICAgICsgQ2xpY2sgb24gdGhlICJTdGFydCIgbWVudSBhdCB0aGUgYm90dG9tIGxlZnQgb2YgeW91ciBXaW5kb3dzIGRlc2t0b3AsIGFuZCB0aGVuIG1vdmUgeW91ciBtb3VzZSBvdmVyICJBbGwgUHJvZ3JhbXMiIGluIHRoZSBtZW51IHRoYXQgcG9wcyB1cC4gQ2hlY2sgdGhhdCAiUiIgYXBwZWFycyBpbiB0aGUgbGlzdCBvZiBwcm9ncmFtcy4gQ2xpY2sgb24gUi4gVGhlIGJhc2ljIFIgY29uc29sZSBzaG91bGQgb3Blbi4KKiBJZiBMaW51eCBpcyB5b3VyIG9wZXJhdGluZyBzeXN0ZW0sIHRoZSBwcm9jZWR1cmUgaXMgYXMgZm9sbG93LgogICAgKyBDbGljayBvbiAiRG93bmxvYWQgUiBmb3IgTGludXgiLiAKICAgICsgQ2xpYyBvbiB5b3VyIExpbnV4IGRpc3RyaWJ1dGlvbi4gCiAgICArIE9wZW4gYSBUZXJtaW5hbCAoQ3RybCtBbHQrVCkuIAogICAgKyBBZGQgUiByZXBvc2l0b3J5IHRvIG9idGFpbiB0aGUgY3VycmVudCBSIHZlcnNpb24uIFRvIHRoaXMgYWltLCBlbnRlciBlaXRoZXIKICAkXHNtYWxse1x0ZXh0e2RlYiBodHRwczovLzxteS5mYXZvcml0ZS5jcmFuLm1pcnJvcj4vYmluL2xpbnV4L3VidW50dSB4ZW5pYWwvfX0kCiAgb3IKICAkXHNtYWxse1x0ZXh0e2RlYiBodHRwczovLzxteS5mYXZvcml0ZS5jcmFuLm1pcnJvcj4vYmluL2xpbnV4L3VidW50dSB3aWx5L319JAogIG9yCiAgJFxzbWFsbHtcdGV4dHtkZWIgaHR0cHM6Ly88bXkuZmF2b3JpdGUuY3Jhbi5taXJyb3I+L2Jpbi9saW51eC91YnVudHUgdHJ1c3R5L319JAogIG9yCiAgJFxzbWFsbHtcdGV4dHtkZWIgaHR0cHM6Ly88bXkuZmF2b3JpdGUuY3Jhbi5taXJyb3I+L2Jpbi9saW51eC91YnVudHUgcHJlY2lzZS99fSQsCiAgICArIEluc3RhbGwgUi1CYXNlLiBUbyB0aGlzIGFpbSwgZXhlY3V0ZSBzdWRvIGFwdC1nZXQgdXBkYXRlLCB0aGVuIGFmdGVyIHRoYXQsIHN1ZG8gYXB0LWdldCBpbnN0YWxsIHItYmFzZS4KICAgICsgRW50ZXIgUiBpbiB5b3VyIHRlcm1pbmFsLiBUaGUgYmFzaWMgUiBjb25zb2xlIHNob3VsZCBvcGVuLgoqIElmIE1hYyBPUyBpcyB5b3VyIG9wZXJhdGluZyBzeXN0ZW0sIHRoZSBwcm9jZWR1cmUgaXMgYXMgZm9sbG93LgogICAgKyBDbGljayBvbiAiRG93bmxvYWQgUiBmb3IgKE1hYykgT1MgWCIuIAogICAgKyBDaG9vc2UgYW4gUiB2ZXJzaW9uIGFjY29yZGluZyB0byB5b3VyIE1hYyBkaXN0cmlidXRpb24uIAogICAgKyBEb3VibGUgY2xpY2sgb24gdGhlIGRvd25sb2FkZWQgLnBrZyBmaWxlLiAgCiAgICArIEZvbGxvdyB0aGUgaW5zdGFsbGF0aW9uIGluc3RydWN0aW9ucy4KICAgIApBbiBhZGRpdGlvbmFsIHR1dG9yaWFsIG1heSBiZSBmb3VuZCBoZXJlIG9yIHlvdSBtYXkgdG8gcmVmZXIgdG8gdGhlIENSQU4gcGFnZSwgUiBJbnN0YWxsYXRpb24gYW5kIEFkbWluaXN0cmF0aW9uLgoKIyMjIFdoYXQgaXMgYSBSIHNlc3Npb24/CldoZW4gb3BlbmluZyB0aGUgUiBjb25zb2xlLCB5b3Ugc2VlOiAiYGBgPmBgYCIuClRoaXMgaXMgdGhlIFIgcHJvbXB0LiAKVGhlIGNvbW1hbmRzIG5lZWRlZCBmb3IgYSBwYXJ0aWN1bGFyIHRhc2sgYXJlIHRvIGJlIHR5cGVkIGFmdGVyIHRoaXMgcHJvbXB0LiAKVGhlIGNvbW1hbmQgaXMgZXhlY3V0ZWQgYWZ0ZXIgcHJlc3NpbmcgKkVudGVyKi4gClRocm91Z2hvdXQgdGhpcyBkb2N1bWVudCwgZXhhbXBsZXMgb2Ygc3VibWl0dGVkIFIgY29kZSBhcmUgcHJlc2VudGVkIGluIGNvZGUgYmxvY2tzIHN1Y2ggYXMgdGhpcyBvbmU6CmBgYHtyfQpwcmludCgiSGVsbG8gd29ybGQiKQpgYGAKVGhlIG91dHB1dCBvZiB0aGUgc3VibWl0dGVkIFIgY29kZSBpcyBwcmludGVkIGluIHRoZSBjb25zb2xlIGFmdGVyIGV4ZWN1dGlvbi4gVGhlIG51bWJlciBpbiBicmFja2V0cyAiWzFdIiBpcyB0aGUgaW5kZXggb2YgdGhlIGZpcnN0IHZlY3RvciBjb21wb25lbnQgb24gdGhlIG91dHB1dCBsaW5lLiBJdCB0dXJucyBvdXQgdGhhdCBSIGNvbnNpZGVycyB0aGUgY2hhcmFjdGVyIHN0cmluZyAiSGVsbG8gd29yZCIgYXMgYSB2ZWN0b3Igb2YgbGVuZ3RoIG9uZS4gSXQgaXMgbm90IHVzZWZ1bCBoZXJlLCBidXQgaXQgaXMgcGFydCBvZiBSJ3Mgd2F5IG9mIHByaW50aW5nIHZlY3RvcnMuICAKCllvdSBjYW4gaW5zZXJ0IGNvbW1lbnRzIGluIHlvdXIgUiBjb2RlIHdoaWNoIGFyZSBub3QgcnVuIGJ5IFIuClRvIHRoaXMgYWltLCBzdGFydCBlYWNoIGxpbmUgdG8gYmUgY29tbWVudGVkIHdpdGggYSBoYXNoICJgYGAjYGBgIi4KYGBge3J9CiMgYSBjb21tZW50CjIrMwpgYGAKQXMgYSBtYXR0ZXIgb2YgZmFjdCwgUiBpcyBhIGZ1bmN0aW9uYWwsIG9iamVjdC1iYXNlZCBsYW5ndWFnZS4gCk9iamVjdHMgY2FuIGJlIG9mIG1hbnkgdHlwZXMgYW5kIGNsYXNzZXMuIApXZSBpbnZlc3RpZ2F0ZSBhIGxpdHRsZSBmdXJ0aGVyIHRocmVlIG9iamVjdCBjbGFzc2VzLCB2ZWN0b3IsIG1hdHJpeCBhbmQgbGlzdCwgaW4gc2VjdGlvbiBbTW9yZSBvbiBkYXRhIHR5cGVzXSgjTW9yZSBvbiBkYXRhIHR5cGVzKSBiZWxvdy4KVGhlIHR5cGUgb2YgYSBiYXNpYyBlbGVtZW50IGNhbiBiZSBvbmUgb2YgKmludGVnZXIqICh0aGUgdmFsdWVzIDAsICsvLTEsICsvLTIsIC4uLikgLCAqZG91YmxlKiAoZm9yIHJlYWwgbnVtYmVycyksICpjaGFyYWN0ZXIqIChhbnkgdGV4dCB0aGF0IGlzIHdyYXBwZWQgd2l0aGluIHBhaXJzIG9mICIgb3IgJykgb3IgKmxvZ2ljYWwqIChmb3IgdGhlIHZhbHVlcyBgYGBUUlVFYGBgIGFuZCBgYGBGQUxTRWBgYCkuIApUaGUgYXNzaWdubWVudCBvcGVyYXRvciBpcyAiYGBgPC1gYGAiLgpJdCBpcyBvZnRlbiB1c2VmdWwgdG8gc3RvcmUgb2JqZWN0IHZhbHVlcyBhbmQgdGhlbiBkbyBjYWxjdWxhdGlvbnMgb24gdGhlc2Ugc3RvcmVkIHZhbHVlcy4KT2J2aW91c2x5LCB5b3UgY2FuIGFsc28gc3RvcmUgdGhlIHJlc3VsdCBvZiB5b3VyIGNhbGN1bGF0aW9ucy4KYGBge3J9CiMgY3JlYXRlIGFuIG9iamVjdCBuYW1lZCBhcyB4CnggPC0gNQojIGNoZWNrIHRoZSB2YWx1ZSBvZiB4CngKIyBhc2sgZm9yIHRoZSB2YWx1ZSBvZiB4CngrMgpgYGAKV2hlbiB5b3UgcXVpdCBSLCB5b3UgYXJlIGFza2VkIGlmIHlvdSB3YW50IHRvIHNhdmUgdGhlIHdvcmtzcGFjZS4KSWYgeW91IGNob29zZSAibm8iLCB0aGVuIGFsbCB5b3VyIHN0b3JlZCB2YWx1ZXMgd2lsbCBiZSBsb3N0LgpJZiB5b3UgY2hvb3NlICJ5ZXMiLCB0aGVuIHlvdXIgc3RvcmVkIHZhbHVlcyBhcmUgc2F2ZWQgaW4geW91ciB3b3Jrc3BhY2UuIApUaGlzIG1lYW5zIHRoYXQgbmV4dCB0aW1lIHlvdSBsYXVuY2ggUiwgeW91IGNhbiB3b3JrIHdpdGggeW91ciBzdG9yZWQgdmFsdWVzLgoKUmF0aGVyIHRoYW4gc2F2aW5nIHRoZSB3b3Jrc3BhY2Ugd2hlbiB5b3UgcXVpdCBSLCBhIHJlY29tbWFuZGVkIHByYWN0aWNlIGNvbnNpc3RzIG9mIHNhdmluZyB5b3VyIFIgY29tbWFuZHMgaW4gYSBzY3JpcHQuCkJhc2ljYWxseSwgYW4gUiBzY3JpcHQgaXMgYSB0ZXh0IGZpbGUgd2hpY2ggaXMgcHJlZmVyYWJseSB3cml0dGVuIGluIGFuIGV4dGVybmFsIHRleHQgZWRpdG9yLgpXZSByZWNvbW1hbmQgdGhlIHVzZSBvZiBSU3R1ZGlvIChzZWUgbmV4dCBzdWJzZWN0aW9uKSBidXQgRW1hY3Mgb3IgTm90ZXBhZCsrIHdvdWxkIGFsc28gZG8uClRoZSBleHRlbnNpb24gZm9yIFIgY29kZSBmaWxlcyBpcyAuUi4KVG8gcnVuIGluc3RydWN0aW9ucyB3cml0dGVuIGluIGEgc2NyaXB0LCBjb3B5IGFuZCBwYXN0ZSB0aGVtIGZyb20gdGhlIGVkaXRvciB0byB0aGUgUiBjb25zb2xlLCBvciBydW4gdGhlIGNvbW1hbmQgYGBgc291cmNlKCJzY3JpcHQuUiIpYGBgIGluIG9yZGVyIHRvIGV4ZWN1dGUgdGhlIGZpbGUgYGBgc2NyaXB0LlJgYGAgKHByb3ZpZGVkIHRoYXQgdGhlIGZpbGUgYGBgc2NyaXB0LlJgYGAgaXMgaW4gUiB3b3JraW5nIGRpcmVjdG9yeSkuCgojIyNJbnN0YWxsaW5nIFJTdHVkaW8KT25jZSBSIGlzIGluc3RhbGxlZCwgeW91IGNhbiBjaG9vc2UgdG8gd29yayBlaXRoZXIgd2l0aCB0aGUgYmFzaWMgUiBjb25zb2xlLCBvciB3aXRoaW4gYW4gaW50ZWdyYXRlZCBkZXZlbG9wbWVudCBlbnZpcm9ubWVudCAoSURFKS4KPGEgaHJlZj0iaHR0cHM6Ly93d3cucnN0dWRpby5jb20vcHJvZHVjdHMvcnN0dWRpby8iIHRhcmdldD0iX2JsYW5rIj5SU3R1ZGlvPC9hPgppcyBhIHBvcHVsYXIgSURFIGZvciBSIGFuZCBzdXBwb3J0cyBkZWJ1Z2dpbmcsIHdvcmtzcGFjZSBtYW5hZ2VtZW50IGFuZCBwbG90dGluZy4KCiogR28gdG8gdGhlIGRvd25sb2FkIHBhZ2Ugb2YgdGhlIG9wZW4gc291cmNlIGVkaXRpb24gb2YgUlN0dWRpbyBkZXNrdG9wCjxhIGhyZWY9Imh0dHBzOi8vd3d3LnJzdHVkaW8uY29tL3Byb2R1Y3RzL3JzdHVkaW8vZG93bmxvYWQvIiB0YXJnZXQ9Il9ibGFuayI+aHR0cHM6Ly93d3cucnN0dWRpby5jb20vcHJvZHVjdHMvcnN0dWRpby9kb3dubG9hZC88L2E+IC4KKiBQcm9jZWVkIGFjY29yZGluZyB0byB5b3VyIE9TLjwvbGk+CgojI1N0YXJ0IGFuIFIgc2Vzc2lvbgojIyMjU2V0IFIgd29ya2luZyBkaXJlY3RvcnkKSXQgdHVybnMgb3V0IHRoYXQgdGhlIGZpbGVzIGlkZW50aWZpZWQgc2ltcGx5IGJ5IHRoZWlyIG5hbWVzIChpZSB3aXRob3V0IHNwZWNpZnlpbmcgYW55IHBhdGgpIHJlZmVyIHRvIGZpbGVzIGluIFIgd29ya2luZyBkaXJlY3Rvcnkgb24geW91ciBzeXN0ZW0uICAKVG8gc2VlIHdoZXJlIFIgaXMgY3VycmVudGx5IHdvcmtpbmcgb24geW91ciBzeXN0ZW0sIHlvdSBjYW4gdXNlIHRoZSBjb21tYW5kIGBgYGdldHdkKClgYGAgaW4gdGhlIFIgY29uc29sZSB3aGljaCBwcmludHMgUiBjdXJyZW50IHdvcmtpbmcgZGlyZWN0b3J5LiAKVXN1YWxseSwgdGhlIGRlZmF1bHQgUiB3b3JraW5nIGRpcmVjdG9yeSBpcyBub3QgYSBjb252ZW5pZW50IHJlcGVydG9yeS4KSW4gb3JkZXIgdG8gcmVhZCBmaWxlcyBmcm9tIGEgc3BlY2lmaWMgbG9jYXRpb24gb3IgdG8gd3JpdGUgZmlsZXMgdG8gYSBzcGVjaWZpYyBsb2NhdGlvbiwgaXQgaXMgcmVjb21tYW5kZWQgdG8gc2V0IFIgd29ya2luZyBkaXJlY3RvcnkgYXMgYSBjb252ZW5pZW50IHJlcGVydG9yeSByYXRoZXIgdGhhbiBoYXZpbmcgZmlsZSBuYW1lcyBwcmVjZWVkZWQgYnkgYSAobG9uZykgcGF0aC4gIApUaGUgY29tbWFuZCBgYGBzZXR3ZCgicGF0aCB0byB3b3JrRGlyIilgYGAgc2V0cyBSIHdvcmtpbmcgZGlyZWN0b3J5IGFzICJ3b3JrRGlyIi4KCiMjIyNMb2FkaW5nIGFkZGl0aW9uYWwgcGFja2FnZXMKQSBwYWNrYWdlIGlzIGEgY29sbGVjdGlvbiBvZiBSIGZ1bmN0aW9ucywgZGF0YSwgZG9jdW1lbnRhdGlvbiBhbmQgY29tcGlsZWQgY29kZSBkZXNpZ25lZCB0byBhZGRyZXNzIGEgc3BlY2lmaWMgcHJvYmxlbS4KVGhlIGRpcmVjdG9yeSB3aGVyZSBhIHBhY2thZ2UgaXMgc3RvcmVkIGlzIGNhbGxlZCBhIGxpYnJhcnkuClIgY29tZXMgd2l0aCBzb21lIHN0YW5kYXJkIHBhY2thZ2VzIHdoaWNoIGFyZSBhdXRvbWF0aWNhbGx5IGluc3RhbGxlZCB3aGVuIHlvdSBpbnN0YWxsIFIuClRvIHJ1biBvdXIgY29kZSwgYWRkaXRpb25hbCBSIHBhY2thZ2VzIGFyZSBuZWVkZWQsIHN1Y2ggYXMgdGhlICoqcG5nKiogcGFja2FnZS4KVGhlc2UgYWRkaXRpb25hbCBwYWNrYWdlcyBkbyBub3QgY29tZSB3aXRoIHRoZSBzdGFuZGFyZCBpbnN0YWxsYXRpb24gb2YgUiwgc28geW91IG5lZWQgdG8gaW5zdGFsbCB0aGVtICh3aXRoIHRoZSBjb21tYW5kIGBgYGluc3RhbGwucGFja2FnZWBgYCkuCk9uY2UgdGhlIHBhY2thZ2UgaXMgaW5zdGFsbGVkLCB5b3UgaGF2ZSB0byBsb2FkIGl0ICh3aXRoIHRoZSBjb21tYW5kIGBgYGxvYWRgYGApIGF0ICoqZWFjaCoqIFIgc2Vzc2lvbi4KYGBge3IgZXZhbD1GQUxTRX0KIyBJbnN0YWxsaW5nIGEgcGFja2FnZSB3aXRoIHJvb3QgYWNjZXNzIHVzaW5nIGEgbG9jYWwgbWlycm9yIAojIE5COiB5b3UgYXJlIGFjdHVhbGx5IHVzaW5nIHRoZSBsb2NhbCBtaXJyb3Igc2VydmVyIHRvIGRvd25sb2FkIHRoZSBwYWNrYWdlLgppbnN0YWxsLnBhY2thZ2VzKCJwbmciKQojIGxvYWRpbmcgdGhlIHBhY2thZ2UKbGlicmFyeShwbmcpCgojIEluc3RhbGxpbmcgYSBwYWNrYWdlIHdpdGhvdXQgcm9vdCBhY2Nlc3M6CiMgLSBjaG9vc2UgYSBkaXJlY3Rvcnkgd2hlcmUgdGhlIGRvd25sb2FkZWQgcGFja2FnZXMgd2lsbCBiZSBzdG9yZWQKIyBOQjogaW4gdGhpcyB0dXRvcmlhbCwgd2UgaGF2ZSBjaG9zZW4gIi9kYXRhL1JwYWNrYWdlcy8iIAojIC0gZG93bmxvYWQgcG5nXzAuMS03LnRhci5neiBvbiBodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy93ZWIvcGFja2FnZXMvcG5nL2luZGV4Lmh0bWwKaW5zdGFsbC5wYWNrYWdlcygicG5nIiwgbGliPSIvZGF0YS9ScGFja2FnZXMvIikKIyBsb2FkaW5nIHRoZSBwYWNrYWdlCmxpYnJhcnkocG5nLCBsaWIubG9jPSIvZGF0YS9ScGFja2FnZXMvIikKYGBgCgojIyMjT25saW5lIGhlbHAKCk51bWVyb3VzIFIgdHV0b3JpYWxzIG1heSBiZSBmb3VuZCBvbmxpbmUuClRoZSBDUkFOIHdlYnNpdGUgcHJvdmlkZXMgc29tZSBvZmZpY2lhbCBkb2N1bWVudGF0aW9uIDxhIGhyZWY9Imh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL21hbnVhbHMuaHRtbCIgdGFyZ2V0PSJfYmxhbmsiPmhlcmU8L2E+LCBhbmQgYWRkaXRpb25hbCBjb250cmlidXRlZCBtYW51YWxzIDxhIGhyZWY9Imh0dHBzOi8vY3Jhbi5yLXByb2plY3Qub3JnL290aGVyLWRvY3MuaHRtbCIgdGFyZ2V0PSJfYmxhbmsiPmhlcmU8L2E+LgpZb3UgY2FuIGFsc28gYXNrIGZvciBSJ3MgYnVpbHQtaW4gaGVscCBhc3NvY2lhdGVkIHRvIGFueSBvZiB0aGUgUiBmdW5jdGlvbnMuCkZvciBleGFtcGxlLCB0byBhc2sgYWJvdXQgdGhlIGBgYG1lYW5gYGAgZnVuY3Rpb24sIGVudGVyIGBgYD9tZWFuYGBgLiAKCgojIzxhIGlkPSdNb3JlIG9uIGRhdGEgdHlwZXMnPk1vcmUgb24gZGF0YSB0eXBlczwvYT4KIyMjI1ZlY3RvcgpBIHZlY3RvciBpcyBhIGZpbml0ZSBzZXF1ZW5jZSBvZiBlbGVtZW50cyBvZiBhIHNpbmdsZSBiYXNpYyB0eXBlIChpbnRlZ2VyLCBudW1lcmljLCBjaGFyYWN0ZXIsIGxvZ2ljYWwgLi4uKS4gCkluIHBhcnRpY3VsYXIsIGEgc2NhbGFyIGlzIGEgbnVtZXJpY2FsIHZlY3RvciBvZiBzaXplIG9uZS4gClRoZSBjb25zdHJ1Y3Qgb3BlcmF0b3IgYGBgYyguLi4pYGBgIGlzIHVzZWQgdG8gZGVmaW5lIHZlY3RvcnMuCmBgYHtyfQojIGRlZmluZSBhIHZlY3RvciB4IG9mIGxlbmd0aCAyIGhhdmluZyBjb21wb25lbnRzICI1IiBhbmQgIjEwIgp4IDwtIGMoNSwxMCkKeApgYGAKVG8gY3JlYXRlIGEgdmVjdG9yIGZyb20gYSBzaW1wbGUgc2VxdWVuY2Ugb2YgaW50ZWdlcnMsIHVzZSB0aGUgY29sb24gImBgYDpgYGAiLgpgYGB7cn0KIyB0aGUgaW50ZWdlciBudW1iZXIgZnJvbSA1IHRvIDExCnggPC0gNjoxMQp4CmBgYApTcGVjaWZpYyB2YWx1ZXMgb2YgYSB2ZWN0b3IgYGBgeGBgYCBjYW4gYmUgYWNjZXNzZWQgdGhyb3VnaCB0aGVpciBpbmRleCBwbGFjZWQgaW5zaWRlIGEgc2luZ2xlIHNxdWFyZSBicmFja2V0ICJgYGBbXWBgYCIuCmBgYHtyfQojIHByaW50IHRoZSBzZWNvbmQgY29tcG9uZW50IG9mIHgKeFsyXQojIyBwcmludCB0aGUgY29tcG9uZW50cyBvZiB4IGZyb20gaW5kZXggMyB0byA1CnhbMzo1XQpgYGAKVG8gZ2V0IHRoZSBudW1iZXIgb2YgY29tcG9uZW50cyBvZiBhIHZlY3RvciwgdXNlIHRoZSBmdW5jdGlvbiBgYGBsZW5ndGhgYGAuIApgYGB7cn0KbGVuZ3RoKHgpCmBgYAoKIyMjI01hdHJpeApBIG1hdHJpeCBpcyBhIGNvbGxlY3Rpb24gb2YgZWxlbWVudHMgb2YgYSBzaW5nbGUgYmFzaWMgdHlwZSB3aGljaCBhcmUgYXJyYW5nZWQgaW4gYSB0d28tZGltZW5zaW9uYWwgcmVjdGFuZ3VsYXIgYXJyYXkuClRvIGNyZWF0ZSBhIG1hdHJpeCBmcm9tIGEgdmVjdG9yIGBgYHhgYGAsIHVzZSB0aGUgZnVuY3Rpb24gYGBgbWF0cml4YGBgLgpgYGB7cn0KIyBjcmVhdGUgYSBtYXRyaXggY2FsbGVkIEEgd2l0aCAyIHJvd3MgYW5kIDMgY29sdW1ucywgdGhlIGNvbXBvbmVudHMgb2Ygd2hpY2ggYXJlIHRob3NlIHN0b3JlZCBpbiB4CkEgPC0gbWF0cml4KHgsbnJvdz0yLG5jb2w9MykKIyBwcmludCBBCkEKYGBgClRvIGdldCB0aGUgbnVtYmVyIG9mIHJvd3MgYW5kIGNvbHVtbnMgb2YgYSBtYXRyaXgsIHVzZSB0aGUgZnVuY3Rpb24gYGBgZGltYGBgLiAKYGBge3J9CiMgcHJpbnQgdGhlIGRpbWVuc2lvbiBvZiBBCmRpbShBKQojIHByaW50IHRoZSBudW1iZXIgb2Ygcm93cyBvZiBBCmRpbShBKVsxXQojIHByaW50IHRoZSBudW1iZXIgb2YgY29sdW1ucyBvZiBBCmRpbShBKVsyXQpgYGAKVGhlIGVsZW1lbnQgYXQgdGhlIG08c3VwPnRoPC9zdXA+IHJvdyBhbmQgbjxzdXA+dGg8L3N1cD4gY29sdW1uIG9mIGBgYEFgYGAgY2FuIGJlIGFjY2Vzc2VkIHRocm91Z2ggdGhlIGV4cHJlc3Npb24gYGBgQVttLG5dYGBgLiAKYGBge3J9CiMgcHJpbnQgdGhlIGVsZW1lbnQgYXQgdGhlIHNlY29uZCByb3cgYW5kIHRoaXJkIGNvbHVtbiBvZiBBCkFbMiwzXQojIHByaW50IHRoZSBzZWNvbmQgcm93IG9mIEEKQVsyLF0KIyBwcmludCB0aGUgdGhpcmQgY29sdW1uIG9mIEEKQVssM10KYGBgCiMjIyNMaXN0CkEgbGlzdCBpcyBhbiBvcmRlcmVkIGNvbGxlY3Rpb24gb2YgUiBvYmplY3RzLgpUaGUgZWxlbWVudHMgb2YgYSBsaXN0IGNhbiBiZSBvZiBkaWZmZXJlbnQgdHlwZXMgb3IgY2xhc3Nlcy4KSW4gdGhlIGV4YW1wbGUgYmVsb3csIGBgYG15bGlzdGBgYCBpcyBhIGxpc3QgaGF2aW5nIGZvdXIgY29tcG9uZW50cy4KSXRzIGZpcnN0IGNvbXBvbmVudCBpcyB0aGUgdmVjdG9yIGBgYHhgYGAsIHRoZSBzZWNvbmQgY29tcG9uZW50IGlzIHRoZSBtYXRyaXggYGBgQWBgYCwgdGhlIHRoaXJkIGNvbXBvbmVudCBpcyBhIGxvZ2ljYWwgdmVjdG9yIG9mIGxlbmd0aCA0LCB0aGUgbGFzdCBvbmUgaXMgYSBsaXN0IG9mIGxlbmd0aCAyLgpUaGUgZnVuY3Rpb24gYGBgc3RyYGBgIHByaW50cyB0aGUgc3RydWN0dXJlIG9mIGFueSBSIG9iamVjdC4KYGBge3J9CiMgcHJpbnQgdGhlIHNlY29uZCBjb21wb25lbnQgb2YgeApteWxpc3QgPC0gbGlzdChteXZlY3Rvcj14LCBteW1hdHJpeD1BLCBjKFRSVUUsRkFMU0UsRkFMU0UsRkFMU0UpLCBsaXN0KCdjYXQnLCdkb2cnKSkKc3RyKG15bGlzdCkKCmBgYApUaGUgbGVuZ3RoIG9mIGEgbGlzdCBpcyB0aGUgbnVtYmVyIG9mIG9iamVjdHMgaW4gdGhhdCBsaXN0LgpUbyBnZXQgdGhlIG51bWJlciBvZiBvYmplY3RzIGluIGEgbGlzdCwgdXNlIHRoZSBmdW5jdGlvbiBgYGBsZW5ndGhgYGAuIApgYGB7cn0KIyBwcmludCB0aGUgbGVuZ3RoIG9mIHRoZSBsaXN0IGNhbGxlZCAibXlsaXN0IgpsZW5ndGgobXlsaXN0KQpgYGAKVGhlIG9iamVjdCBvZiB0aGUgbGlzdCBgYGBteWxpc3RgYGAgYXQgcG9zaXRpb24gbSBjYW4gYmUgYWNjZXNzZWQgdGhyb3VnaCB0aGUgZXhwcmVzc2lvbiBgYGBteWxpc3RbW21dXWBgYC4gCmBgYHtyfQojIHByaW50IHRoZSB0aGlyZCBvYmplY3Qgb2YgdGhlIGxpc3QgY2FsbGVkICJteWxpc3QiCm15bGlzdFtbM11dCmBgYApTb21lIG9iamVjdHMgb2YgdGhlIGxpc3QgYGBgbXlsaXN0YGBgIGhhdmUgYSBuYW1lLiAKRm9yIGluc3RhbmNlLCB0aGUgZmlyc3Qgb2JqZWN0IG9mIGBgYG15bGlzdGBgYCBpcyBuYW1lZCBhcyBgYGBteXZlY3RvcmBgYC4KVGhlIHRoaXJkIG9iamVjdCBvZiBgYGBteWxpc3RgYGAgaGFzIG5vIG5hbWUuClRoZSBvYmplY3Qgb2YgdGhlIGxpc3QgYGBgbXlsaXN0YGBgIHRoZSBuYW1lIG9mIHdoaWNoIGlzIGBgYG15dmVjdG9yYGBgIGNhbiBiZSBhY2Nlc3NlZCB0aHJvdWdoIHRoZSBleHByZXNzaW9uIGBgYG15bGlzdCRteXZlY3RvcmBgYC4gCmBgYHtyfQojIHByaW50IHRoZSBvYmplY3Qgb2YgdGhlIGxpc3QgY2FsbGVkICJteWxpc3QiIHRoZSBuYW1lIG9mIHdoaWNoIGlzICJteXZlY3RvciIKbXlsaXN0JG15dmVjdG9yCmBgYAoKKioqCjxkaXYgaWQ9ImZvb3RlciI+CiAgPHA+CiAgQXV0aG9yczogPGEgaHJlZj0iaHR0cDovL3d3dy1pcm1hLnUtc3RyYXNiZy5mci9+Z2VmZnJheS8iIHRhcmdldD0iX2JsYW5rIj5HZWZmcmF5IFMuPC9hPiwgCiAgPGEgaHJlZj0iaHR0cHM6Ly93d3cudW5pdi1yZW5uZXMyLmZyL2lybWFyLXJlbm5lcy0yL21lbWJyZXMiIHRhcmdldD0iX2JsYW5rIj5LbHV0Y2huaWtvZmYgTi48L2E+LCAKICA8YSBocmVmPSJodHRwOi8vd3d3LmVuc2FpLmZyL2Vuc2VpZ25hbnQvYWxpYXMvbXlyaWFtLXZpbW9uZC5odG1sIiB0YXJnZXQ9Il9ibGFuayI+Vmltb25kIE0uPC9hPgogIDwvcD4gIAogIDxwPiAgCiAgTGFzdCBtb2RpZmljYXRpb246IDA3LTIyLTIwMTYKICA8L3A+CjwvZGl2Pgo=