1 What is R ?

R is a free programming language and software environment for statistical computing and graphics. The R language is widely used among statisticians and data miners for developing statistical software and data analysis.

R and its libraries implement a wide variety of statistical and graphical techniques, including linear and nonlinear modeling, classical statistical tests, time-series analysis, classification, clustering, and others. R is easily extensible through functions and extensions, and the R community is noted for its active contributions in terms of packages.

R isn’t used as general programming language. It sees more usage in Data Analysis and Data Visualisation primarily because of the powerful libraries behind it.

2 Install R and RStudio

3 Scalars

3.1 Data Types

R works with numerous data types. Some of the most basic types to get started are:

  • Text (or string) values are called characters.
  • Decimals values like 4.5 are called numerics.
  • Natural numbers like 4 are called integers. Integers are also numerics.
  • Boolean values (TRUE or FALSE) are called logical.

3.2 Strings

As is customary with every new language one learns, let’s learn how to print “Hello world!”:

"Hello world!"
[1] "Hello world!"

3.3 Arithmetic

In its most basic form, R can be used as a simple calculator. Consider the following arithmetic operators:

  • Addition: +
  • Subtraction: -
  • Multiplication: *
  • Division: /
  • Exponentiation: ^
  • Modulo: %% For example:
# Remainder when 3 is divided by 2
3 %% 2
[1] 1

Another interesting thing to point out is that it inherently follows BODMAS:

# Inherently follows BODMAS
6 - 7 * 2 / 1 + 3
[1] -5

3.4 Logical Values

There are 3 logical operators:

  • &, && - and
  • |, || - or
  • ! - not

The (logical) comparison operators known to R are:

  • < for less than
  • > for greater than
  • <= for less than or equal to
  • >= for greater than or equal to
  • == for equal to each other
  • != not equal to each other

Most programming languages refer to logical values as boolean values. Some expressions can return True or False values:

# AND
1 & 0
[1] FALSE
# OR
0 | 1
[1] TRUE
# NOT
!0
[1] TRUE

Here’s an example of the comparison logical operator:

3 < 4
[1] TRUE

The == sign checks for equivalence of an expression:

# == sign checks for equivalence
2 + 2 == 5
[1] FALSE

Shorthand for TRUE and FALSE are given as T and F respectively:

T == TRUE
[1] TRUE

4 Variables

4.1 Assignment

As in other programming languages, you can store values into a variable to access it later:

# Assign the value 42 to x
x <- 42
# Print out the value of the variable x
x
[1] 42

Another way to assign a variable is by calling the assign(...) function:

# Call the assign function
assign('this_var_x',43210)
# Display 'this_var_x'
this_var_x
[1] 43210

4.2 Arithematic

Variable arithmetic also works but notice that it doesn’t change the original value of x:

# Divide x by 21
x/21
[1] 2
# Print x
x
[1] 42

To change the value of x, we’d have to do the following:

# Save the result of x/21 to a variable x
x <- x/21
# Print x
x
[1] 2

Let’s assume we have 3 variables where each variable here denotes the number of fruits we bought at the market:

# Fruits bought at the market
apples <- 5
oranges <- 6
tomatoes <- "ten"

Let’s find out the sum of the apples and oranges bought collectively:

# Sum of apples and oranges
apples + oranges
[1] 11

What about the sum of the apples and tomatoes ?

apples + tomatoes
Error in apples + tomatoes : non-numeric argument to binary operator

This doesn’t work as expected because the two variables(apples and tomatoes) are of different datatypes(integer and character).

4.3 Logical

Variables can be compared to scalars:

# Are the number of apples less than 2?
apples < 2
[1] FALSE

Variables can be compared to other vectors as well:

# Comparing vectors
apples == oranges
[1] FALSE

We can introduce complex logical expressions by linking them with either of the three logical operators(!,|,&):

apples > 2 & oranges < 7
[1] TRUE

5 Introduction to Functions and Helpers

5.1 Examples of functions

Functions exist to perform repeated tasks. You call a function by typing its name, followed by one or more arguments to that function in parenthesis. Let’s see an example of the sum(...) function:

# Sum of 1, 3, 5
sum(1,3,5)
[1] 9

Another example:

# Sum of apples and oranges
sum(apples, oranges)
[1] 11

Some arguments have names. For example, to repeat a value 3 times, you would call the rep(...) function and provide its times argument:

# Repeats "FIRE" 3 times
rep("FIRE", times = 3)
[1] "FIRE" "FIRE" "FIRE"

Most mathematical functions, like sqrt(...), have well defined functions:

# Square root of 16
sqrt(16)
[1] 4

5.2 Helpers

help(...) brings up help for the given function. Try displaying help for the sum function:

help(sum)
# We can also bring up the help file in this way
?sum

example(...) brings up examples of usage for the given function. Try displaying examples for the min function:

example(sum)

sum> ## Pass a vector to sum, and it will add the elements together.
sum> sum(1:5)
[1] 15

sum> ## Pass several numbers to sum, and it also adds the elements.
sum> sum(1, 2, 3, 4, 5)
[1] 15

sum> ## In fact, you can pass vectors into several arguments, and everything gets added.
sum> sum(1:2, 3:5)
[1] 15

sum> ## If there are missing values, the sum is unknown, i.e., also missing, ....
sum> sum(1:5, NA)
[1] NA

sum> ## ... unless  we exclude missing values explicitly:
sum> sum(1:5, NA, na.rm = TRUE)
[1] 15

5.3 Tests

One of the most important helper functions used is class(...). It helps us to determine the datatype of the variable:

# Returns the class of the object
class(apples)
[1] "numeric"

Another way to determine the class of an object follows:

# Returns a boolean value
is.numeric(tomatoes)
[1] FALSE

6 Miscellaneous

A syntactically valid variable name consists of letters, numbers and the dot or underline characters and starts with a letter or the dot not followed by a number. Names such as “.2way” are not valid, and neither are the reserved words. See ?make.names.

Commands are separated either by a semi-colon (;), or by a newline. Elementary commands can be grouped together into one compound expression by braces ({ and }). Comments can be put almost anywhere, starting with a hashmark (#), everything to the end of the line is a comment. Finally, print(...) prints a message.

# Commands seperated by ;
x <- 1; y <- 2; print(x + y)
[1] 3
LS0tCnRpdGxlOiAiSW50cm9kdWN0aW9uIHRvIFIiCmF1dGhvcjogIkljM2ZyMGciCmRhdGU6ICdgciBTeXMuRGF0ZSgpYCcKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6CiAgICBjb2RlX2ZvbGRpbmc6IHNob3cKICAgIGZpZ19jYXB0aW9uOiB5ZXMKICAgIGZpZ19oZWlnaHQ6IDQuNQogICAgZmlnX3dpZHRoOiA3CiAgICBoaWdobGlnaHQ6IHRhbmdvCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcwogICAgdGhlbWU6IGNvc21vCiAgICB0b2M6IHllcwogIGh0bWxfZG9jdW1lbnQ6CiAgICBjb2RlX2ZvbGRpbmc6IHNob3cKICAgIGZpZ19jYXB0aW9uOiB5ZXMKICAgIGZpZ19oZWlnaHQ6IDQuNQogICAgZmlnX3dpZHRoOiA3CiAgICBoaWdobGlnaHQ6IHRhbmdvCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcwogICAgdGhlbWU6IGNvc21vCiAgICB0b2M6IHllcwotLS0KCgojIFdoYXQgaXMgUiA/CgpSIGlzIGEgZnJlZSBwcm9ncmFtbWluZyBsYW5ndWFnZSBhbmQgc29mdHdhcmUgZW52aXJvbm1lbnQgZm9yIHN0YXRpc3RpY2FsIGNvbXB1dGluZyBhbmQgZ3JhcGhpY3MuIFRoZSBSIGxhbmd1YWdlIGlzIHdpZGVseSB1c2VkIGFtb25nIHN0YXRpc3RpY2lhbnMgYW5kIGRhdGEgbWluZXJzIGZvciBkZXZlbG9waW5nIHN0YXRpc3RpY2FsIHNvZnR3YXJlIGFuZCBkYXRhIGFuYWx5c2lzLgoKUiBhbmQgaXRzIGxpYnJhcmllcyBpbXBsZW1lbnQgYSB3aWRlIHZhcmlldHkgb2Ygc3RhdGlzdGljYWwgYW5kIGdyYXBoaWNhbCB0ZWNobmlxdWVzLCBpbmNsdWRpbmcgbGluZWFyIGFuZCBub25saW5lYXIgbW9kZWxpbmcsIGNsYXNzaWNhbCBzdGF0aXN0aWNhbCB0ZXN0cywgdGltZS1zZXJpZXMgYW5hbHlzaXMsIGNsYXNzaWZpY2F0aW9uLCBjbHVzdGVyaW5nLCBhbmQgb3RoZXJzLiBSIGlzIGVhc2lseSBleHRlbnNpYmxlIHRocm91Z2ggZnVuY3Rpb25zIGFuZCBleHRlbnNpb25zLCBhbmQgdGhlIFIgY29tbXVuaXR5IGlzIG5vdGVkIGZvciBpdHMgYWN0aXZlIGNvbnRyaWJ1dGlvbnMgaW4gdGVybXMgb2YgcGFja2FnZXMuCgpSIGlzbid0IHVzZWQgYXMgZ2VuZXJhbCBwcm9ncmFtbWluZyBsYW5ndWFnZS4gSXQgc2VlcyBtb3JlIHVzYWdlIGluIERhdGEgQW5hbHlzaXMgYW5kIERhdGEgVmlzdWFsaXNhdGlvbiBwcmltYXJpbHkgYmVjYXVzZSBvZiB0aGUgcG93ZXJmdWwgbGlicmFyaWVzIGJlaGluZCBpdC4KCgojIEluc3RhbGwgUiBhbmQgUlN0dWRpbwoKLSBbRG93bmxvYWQgYW5kIGluc3RhbGwgUl0oaHR0cHM6Ly9mdHAuaWl0bS5hYy5pbi9jcmFuLykKLSBbRG93bmxvYWQgYW5kIGluc3RhbGwgUlN0dWRpb10oaHR0cHM6Ly93d3cucnN0dWRpby5jb20vcHJvZHVjdHMvcnN0dWRpby9kb3dubG9hZC8pCgoKIyBTY2FsYXJzIHsudGFic2V0IC50YWJzZXQtZmFkZSAudGFic2V0LXBpbGxzfQoKIyMgRGF0YSBUeXBlcwpSIHdvcmtzIHdpdGggbnVtZXJvdXMgZGF0YSB0eXBlcy4gU29tZSBvZiB0aGUgbW9zdCBiYXNpYyB0eXBlcyB0byBnZXQgc3RhcnRlZCBhcmU6CgotIFRleHQgKG9yIHN0cmluZykgdmFsdWVzIGFyZSBjYWxsZWQgKipjaGFyYWN0ZXJzKiouCi0gRGVjaW1hbHMgdmFsdWVzIGxpa2UgYDQuNWAgYXJlIGNhbGxlZCAqKm51bWVyaWNzKiouCi0gTmF0dXJhbCBudW1iZXJzIGxpa2UgYDRgIGFyZSBjYWxsZWQgKippbnRlZ2VycyoqLiBJbnRlZ2VycyBhcmUgYWxzbyBudW1lcmljcy4KLSBCb29sZWFuIHZhbHVlcyAoYFRSVUVgIG9yIGBGQUxTRWApIGFyZSBjYWxsZWQgKipsb2dpY2FsKiouCgojIyBTdHJpbmdzCkFzIGlzIGN1c3RvbWFyeSB3aXRoIGV2ZXJ5IG5ldyBsYW5ndWFnZSBvbmUgbGVhcm5zLCBsZXQncyBsZWFybiBob3cgdG8gcHJpbnQgKioiSGVsbG8gd29ybGQhIioqOgpgYGB7cn0KIkhlbGxvIHdvcmxkISIKYGBgCgojIyBBcml0aG1ldGljCkluIGl0cyBtb3N0IGJhc2ljIGZvcm0sIFIgY2FuIGJlIHVzZWQgYXMgYSBzaW1wbGUgY2FsY3VsYXRvci4gQ29uc2lkZXIgdGhlIGZvbGxvd2luZyBhcml0aG1ldGljIG9wZXJhdG9yczoKCi0gQWRkaXRpb246ICsKLSBTdWJ0cmFjdGlvbjogLQotIE11bHRpcGxpY2F0aW9uOiAqCi0gRGl2aXNpb246IC8KLSBFeHBvbmVudGlhdGlvbjogXgotIE1vZHVsbzogJSUKRm9yIGV4YW1wbGU6CmBgYHtyfQojIFJlbWFpbmRlciB3aGVuIDMgaXMgZGl2aWRlZCBieSAyCjMgJSUgMgpgYGAKQW5vdGhlciBpbnRlcmVzdGluZyB0aGluZyB0byBwb2ludCBvdXQgaXMgdGhhdCBpdCBpbmhlcmVudGx5IGZvbGxvd3MgQk9ETUFTOgpgYGB7cn0KIyBJbmhlcmVudGx5IGZvbGxvd3MgQk9ETUFTCjYgLSA3ICogMiAvIDEgKyAzCmBgYAoKIyMgTG9naWNhbCBWYWx1ZXMKVGhlcmUgYXJlIDMgbG9naWNhbCBvcGVyYXRvcnM6CgotIGAmYCwgYCYmYCAtIGFuZAotIGB8YCwgYHx8YCAtIG9yCi0gYCFgIC0gbm90CgpUaGUgKGxvZ2ljYWwpIGNvbXBhcmlzb24gb3BlcmF0b3JzIGtub3duIHRvIFIgYXJlOgoKLSBgPGAgZm9yIGxlc3MgdGhhbgotIGA+YCBmb3IgZ3JlYXRlciB0aGFuCi0gYDw9YCBmb3IgbGVzcyB0aGFuIG9yIGVxdWFsIHRvCi0gYD49YCBmb3IgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvCi0gYD09YCBmb3IgZXF1YWwgdG8gZWFjaCBvdGhlcgotIGAhPWAgbm90IGVxdWFsIHRvIGVhY2ggb3RoZXIKCk1vc3QgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2VzIHJlZmVyIHRvIGxvZ2ljYWwgdmFsdWVzIGFzICoqYm9vbGVhbiB2YWx1ZXMqKi4gU29tZSBleHByZXNzaW9ucyBjYW4gcmV0dXJuIGBUcnVlYCBvciBgRmFsc2VgIHZhbHVlczoKYGBge3J9CiMgQU5ECjEgJiAwCmBgYApgYGB7cn0KIyBPUgowIHwgMQpgYGAKYGBge3J9CiMgTk9UCiEwCmBgYApIZXJlJ3MgYW4gZXhhbXBsZSBvZiB0aGUgY29tcGFyaXNvbiBsb2dpY2FsIG9wZXJhdG9yOgpgYGB7cn0KMyA8IDQKYGBgClRoZSBgPT1gIHNpZ24gY2hlY2tzIGZvciBlcXVpdmFsZW5jZSBvZiBhbiBleHByZXNzaW9uOgpgYGB7cn0KIyA9PSBzaWduIGNoZWNrcyBmb3IgZXF1aXZhbGVuY2UKMiArIDIgPT0gNQpgYGAKU2hvcnRoYW5kIGZvciBgVFJVRWAgYW5kIGBGQUxTRWAgYXJlIGdpdmVuIGFzIGBUYCBhbmQgYEZgIHJlc3BlY3RpdmVseToKYGBge3J9ClQgPT0gVFJVRQpgYGAKCgojIFZhcmlhYmxlcyB7LnRhYnNldCAudGFic2V0LWZhZGUgLnRhYnNldC1waWxsc30KCiMjIEFzc2lnbm1lbnQKQXMgaW4gb3RoZXIgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2VzLCB5b3UgY2FuIHN0b3JlIHZhbHVlcyBpbnRvIGEgdmFyaWFibGUgdG8gYWNjZXNzIGl0IGxhdGVyOgpgYGB7cn0KIyBBc3NpZ24gdGhlIHZhbHVlIDQyIHRvIHgKeCA8LSA0MgojIFByaW50IG91dCB0aGUgdmFsdWUgb2YgdGhlIHZhcmlhYmxlIHgKeApgYGAKQW5vdGhlciB3YXkgdG8gYXNzaWduIGEgdmFyaWFibGUgaXMgYnkgY2FsbGluZyB0aGUgYGFzc2lnbiguLi4pYCBmdW5jdGlvbjoKYGBge3J9CiMgQ2FsbCB0aGUgYXNzaWduIGZ1bmN0aW9uCmFzc2lnbigndGhpc192YXJfeCcsNDMyMTApCiMgRGlzcGxheSAndGhpc192YXJfeCcKdGhpc192YXJfeApgYGAKCiMjIEFyaXRoZW1hdGljClZhcmlhYmxlIGFyaXRobWV0aWMgYWxzbyB3b3JrcyBidXQgbm90aWNlIHRoYXQgaXQgZG9lc24ndCBjaGFuZ2UgdGhlIG9yaWdpbmFsIHZhbHVlIG9mIGB4YDoKYGBge3J9CiMgRGl2aWRlIHggYnkgMjEKeC8yMQojIFByaW50IHgKeApgYGAKVG8gY2hhbmdlIHRoZSB2YWx1ZSBvZiBgeGAsIHdlJ2QgaGF2ZSB0byBkbyB0aGUgZm9sbG93aW5nOgpgYGB7cn0KIyBTYXZlIHRoZSByZXN1bHQgb2YgeC8yMSB0byBhIHZhcmlhYmxlIHgKeCA8LSB4LzIxCiMgUHJpbnQgeAp4CmBgYApMZXQncyBhc3N1bWUgd2UgaGF2ZSAzIHZhcmlhYmxlcyB3aGVyZSBlYWNoIHZhcmlhYmxlIGhlcmUgZGVub3RlcyB0aGUgbnVtYmVyIG9mIGZydWl0cyB3ZSBib3VnaHQgYXQgdGhlIG1hcmtldDoKYGBge3J9CiMgRnJ1aXRzIGJvdWdodCBhdCB0aGUgbWFya2V0CmFwcGxlcyA8LSA1Cm9yYW5nZXMgPC0gNgp0b21hdG9lcyA8LSAidGVuIgpgYGAKTGV0J3MgZmluZCBvdXQgdGhlIHN1bSBvZiB0aGUgYXBwbGVzIGFuZCBvcmFuZ2VzIGJvdWdodCBjb2xsZWN0aXZlbHk6CmBgYHtyfQojIFN1bSBvZiBhcHBsZXMgYW5kIG9yYW5nZXMKYXBwbGVzICsgb3JhbmdlcwpgYGAKV2hhdCBhYm91dCB0aGUgc3VtIG9mIHRoZSBhcHBsZXMgYW5kIHRvbWF0b2VzID8KYGBge3IsZXJyb3I9VH0KYXBwbGVzICsgdG9tYXRvZXMKYGBgCioqVGhpcyBkb2Vzbid0IHdvcmsgYXMgZXhwZWN0ZWQgYmVjYXVzZSB0aGUgdHdvIHZhcmlhYmxlcyhgYXBwbGVzYCBhbmQgYHRvbWF0b2VzYCkgYXJlIG9mIGRpZmZlcmVudCBkYXRhdHlwZXMoYGludGVnZXJgIGFuZCBgY2hhcmFjdGVyYCkuKioKCiMjIExvZ2ljYWwKVmFyaWFibGVzIGNhbiBiZSBjb21wYXJlZCB0byBzY2FsYXJzOgpgYGB7cn0KIyBBcmUgdGhlIG51bWJlciBvZiBhcHBsZXMgbGVzcyB0aGFuIDI/CmFwcGxlcyA8IDIKYGBgClZhcmlhYmxlcyBjYW4gYmUgY29tcGFyZWQgdG8gb3RoZXIgdmVjdG9ycyBhcyB3ZWxsOgpgYGB7cn0KIyBDb21wYXJpbmcgdmVjdG9ycwphcHBsZXMgPT0gb3JhbmdlcwpgYGAKV2UgY2FuIGludHJvZHVjZSBjb21wbGV4IGxvZ2ljYWwgZXhwcmVzc2lvbnMgYnkgbGlua2luZyB0aGVtIHdpdGggZWl0aGVyIG9mIHRoZSB0aHJlZSBsb2dpY2FsIG9wZXJhdG9ycyhgIWAsYHxgLGAmYCk6CmBgYHtyfQphcHBsZXMgPiAyICYgb3JhbmdlcyA8IDcKYGBgCgoKIyBJbnRyb2R1Y3Rpb24gdG8gRnVuY3Rpb25zIGFuZCBIZWxwZXJzIHsudGFic2V0IC50YWJzZXQtZmFkZSAudGFic2V0LXBpbGxzfQoKIyMgRXhhbXBsZXMgb2YgZnVuY3Rpb25zCkZ1bmN0aW9ucyBleGlzdCB0byBwZXJmb3JtIHJlcGVhdGVkIHRhc2tzLiBZb3UgY2FsbCBhIGZ1bmN0aW9uIGJ5IHR5cGluZyBpdHMgbmFtZSwgZm9sbG93ZWQgYnkgb25lIG9yIG1vcmUgYXJndW1lbnRzIHRvIHRoYXQgZnVuY3Rpb24gaW4gcGFyZW50aGVzaXMuIExldCdzIHNlZSBhbiBleGFtcGxlIG9mIHRoZSBgc3VtKC4uLilgIGZ1bmN0aW9uOgpgYGB7cn0KIyBTdW0gb2YgMSwgMywgNQpzdW0oMSwzLDUpCmBgYApBbm90aGVyIGV4YW1wbGU6CmBgYHtyfQojIFN1bSBvZiBhcHBsZXMgYW5kIG9yYW5nZXMKc3VtKGFwcGxlcywgb3JhbmdlcykKYGBgClNvbWUgYXJndW1lbnRzIGhhdmUgbmFtZXMuIEZvciBleGFtcGxlLCB0byByZXBlYXQgYSB2YWx1ZSAzIHRpbWVzLCB5b3Ugd291bGQgY2FsbCB0aGUgYHJlcCguLi4pYCBmdW5jdGlvbiBhbmQgcHJvdmlkZSBpdHMgYHRpbWVzYCBhcmd1bWVudDoKYGBge3J9CiMgUmVwZWF0cyAiRklSRSIgMyB0aW1lcwpyZXAoIkZJUkUiLCB0aW1lcyA9IDMpCmBgYApNb3N0IG1hdGhlbWF0aWNhbCBmdW5jdGlvbnMsIGxpa2UgYHNxcnQoLi4uKWAsIGhhdmUgd2VsbCBkZWZpbmVkIGZ1bmN0aW9uczoKYGBge3J9CiMgU3F1YXJlIHJvb3Qgb2YgMTYKc3FydCgxNikKYGBgCgojIyBIZWxwZXJzCmBoZWxwKC4uLilgIGJyaW5ncyB1cCBoZWxwIGZvciB0aGUgZ2l2ZW4gZnVuY3Rpb24uIFRyeSBkaXNwbGF5aW5nIGhlbHAgZm9yIHRoZSBzdW0gZnVuY3Rpb246CmBgYHtyfQpoZWxwKHN1bSkKIyBXZSBjYW4gYWxzbyBicmluZyB1cCB0aGUgaGVscCBmaWxlIGluIHRoaXMgd2F5Cj9zdW0KYGBgCmBleGFtcGxlKC4uLilgIGJyaW5ncyB1cCBleGFtcGxlcyBvZiB1c2FnZSBmb3IgdGhlIGdpdmVuIGZ1bmN0aW9uLiBUcnkgZGlzcGxheWluZyBleGFtcGxlcyBmb3IgdGhlIG1pbiBmdW5jdGlvbjoKYGBge3J9CmV4YW1wbGUoc3VtKQpgYGAKCiMjIFRlc3RzCk9uZSBvZiB0aGUgbW9zdCBpbXBvcnRhbnQgaGVscGVyIGZ1bmN0aW9ucyB1c2VkIGlzIGBjbGFzcyguLi4pYC4gSXQgaGVscHMgdXMgdG8gZGV0ZXJtaW5lIHRoZSBkYXRhdHlwZSBvZiB0aGUgdmFyaWFibGU6CmBgYHtyfQojIFJldHVybnMgdGhlIGNsYXNzIG9mIHRoZSBvYmplY3QKY2xhc3MoYXBwbGVzKQpgYGAKQW5vdGhlciB3YXkgdG8gZGV0ZXJtaW5lIHRoZSBjbGFzcyBvZiBhbiBvYmplY3QgZm9sbG93czoKYGBge3J9CiMgUmV0dXJucyBhIGJvb2xlYW4gdmFsdWUKaXMubnVtZXJpYyh0b21hdG9lcykKYGBgCgoKIyBNaXNjZWxsYW5lb3VzCgpBICoqc3ludGFjdGljYWxseSB2YWxpZCB2YXJpYWJsZSBuYW1lKiogY29uc2lzdHMgb2YgbGV0dGVycywgbnVtYmVycyBhbmQgdGhlIGRvdCBvciB1bmRlcmxpbmUgY2hhcmFjdGVycyBhbmQgc3RhcnRzIHdpdGggYSBsZXR0ZXIgb3IgdGhlIGRvdCBub3QgZm9sbG93ZWQgYnkgYSBudW1iZXIuIE5hbWVzIHN1Y2ggYXMgIi4yd2F5IiBhcmUgbm90IHZhbGlkLCBhbmQgbmVpdGhlciBhcmUgdGhlIHJlc2VydmVkIHdvcmRzLiBTZWUgYD9tYWtlLm5hbWVzYC4KCkNvbW1hbmRzIGFyZSBzZXBhcmF0ZWQgZWl0aGVyIGJ5IGEgc2VtaS1jb2xvbiAoYDtgKSwgb3IgYnkgYSBuZXdsaW5lLiBFbGVtZW50YXJ5IGNvbW1hbmRzIGNhbiBiZSBncm91cGVkIHRvZ2V0aGVyIGludG8gb25lIGNvbXBvdW5kIGV4cHJlc3Npb24gYnkgYnJhY2VzIChge2AgYW5kIGB9YCkuIENvbW1lbnRzIGNhbiBiZSBwdXQgYWxtb3N0IGFueXdoZXJlLCBzdGFydGluZyB3aXRoIGEgaGFzaG1hcmsgKGAjYCksIGV2ZXJ5dGhpbmcgdG8gdGhlIGVuZCBvZiB0aGUgbGluZSBpcyBhIGNvbW1lbnQuIEZpbmFsbHksIGBwcmludCguLi4pYCBwcmludHMgYSBtZXNzYWdlLgpgYGB7cn0KIyBDb21tYW5kcyBzZXBlcmF0ZWQgYnkgOwp4IDwtIDE7IHkgPC0gMjsgcHJpbnQoeCArIHkpCmBgYAoK