Before we can start exploring data in R, there are some key concepts to understand first:
- What are R and RStudio?
- How do I code in R?
What are R and RStudio?
In this class, we will be using R via RStudio. First time users often confuse the two. At its simplest R is like a car’s engine while RStudio is like a car’s dashboard.
More precisely, R is a programming language that runs computations while RStudio is an integrated development environment (IDE) that provides an interface by adding many convenient features and tools. So just as the way of having access to a speedometer, rear-view mirrors, and a navigation system makes driving much easier, using RStudio’s interface makes using R much easier as well.
Since most have you have never used R, we are also using RStudio Cloud, meaning that you don’t have to install anything. Everything has already been set-up for you so that you can just log in and get started.
How do I code in R?
Now that you’re set up with R and RStudio, you are probably asking yourself “OK. Now how do I use R?” The first thing to note is that unlike other statistical software programs like Excel, STATA, or SAS that provide point-and-click interfaces, R is an interpreted language. This means you have to type in commands written in R code. In other words, you have to code/program in R. Note that we’ll use the terms “coding” and “programming” interchangeably in this course.
While it is not required to be a seasoned coder/computer programmer to use R, there is still a set of basic programming concepts that linguistics working with quantitative data need to understand. Consequently, while this course is not a course on programming, you will still learn just enough of these basic programming concepts needed to explore and analyze data effectively.
Tips on learning to code
Learning to code/program is very much like learning a foreign language. It can be very daunting and frustrating at first. Such frustrations are very common and it is very normal to feel discouraged as you learn. However just as with learning a foreign language, if you put in the effort and are not afraid to make mistakes, anybody can learn.
Here are a few useful tips to keep in mind as you learn to program:
- Remember that computers are not actually that smart: You may think your computer or smartphone are “smart,” but really people spent a lot of time and energy designing them to appear “smart.” In reality, you have to tell a computer everything it needs to do. Furthermore, the instructions you give your computer can’t have any mistakes in them nor can they be ambiguous in any way.
- Take the “copy, paste, and tweak” approach: Especially when you learn your first programming language or you need to understand particularly complicated code, it is often much easier to take existing code that you know works and modify it to suit your ends. This is opposed to trying to type out the code from scratch. We call this the “copy, paste, and tweak” approach. So early on, we suggest not trying to write code from memory, but rather take existing examples we have provided you, then copy, paste, and tweak them to suit your goals. After you start feeling more confident, you can slowly move away from this approach. Think of the “copy, paste, and tweak” approach as training wheels for a child learning to ride a bike. After getting comfortable, they won’t need them anymore.
- The best way to learn to code is by doing: Rather than learning to code for its own sake, we feel that learning to code goes much smoother when you have a goal in mind or when you are working on a particular project, like analyzing data that you are interested in.
- Practice is key: Just as the only method to improve your foreign language skills is through lots of practice, the only method to improving your coding skills is through lots of practice. Don’t worry however, we’ll give you plenty of opportunities to do so!
Getting started
After you log in, you will see two main windows on the left of the screen. * The window on top that contains the text and code from this section is called an R script (or sometimes an R notebook–but we’ll get to that later). * The window below, where all of the output is listed is called the R console.
The difference is that you can write and erase as much as you want inside the script, and it will not do anything until you transfer a line of code to the console. Inside the console window, you cannot change a line of code once it is entered; you instead have to re-enter the changed line of code. To run any line of code, you an do any of the following:
Type the line directly into the R console window followed by a carriage return (i.e. ENTER).
Use the keyboard or mouse to copy the line (including the carriage return at the end) from the script and paste it into the R console window.
Highlight the part of the code you want to use from the script by clicking and dragging your mouse over it. Then, for a Mac, hold down the key (the swirlygig button, formerly the apple button) on the left of the keyboard, and then also hit (as you are continuing to hold the key). If you use R on a PC running windows (or linux), you will highlight the code and press and the letter “r”.
The last option is the fastest way of getting a line of code to work because it transfers it to the console and executes the command all at once. Even if you are writing the commands or functions yourself, you should write them in a script window first and then execute them from the script. That way, it is easier to go back and make changes to your code (which you will probably have to do often at first).
Code vs. text
If you are using the .Rmd file, you’ll notice that this text is just written like normal text. In a notebook like this, you tell RStudio that you’re writing code (not text) by inserting a code chunk like this.
7 - 2
The code above subtracts 2 from 7.
The output (i.e. 5) is also shown below the code.
Arithmetic operators
Now the easiest thing to do in R is basic arithmetic operations. Basic operator signs are as follows:
Adding:
459 + 51
Subtracting:
459 - 51
Multiplying:
459 * 51
Dividing:
459 / 51
Exponentiation
51 ^ 3
51 * 51 * 51
Remember, to solve each of these equations, you could
- type it into the console then hit return
- copy and paste it into the console and press return, or
- highlight it from the portion of the notebook and press + (or + for a PC running windows).
Try executing the commands in each of the three ways.
If it has been a while since you have done a lot of this kind of arithmetic, it might be good to review some other basics, such as the difference between the following 2 commands.
(459 + 51) / 3
459 + (51 / 3)
The first line adds 51 to 459 and then divides the result by 3. The second line adds 459 plus the result of dividing 51 by 3.
Functions
Addition also can be performed using the R function sum(). A function is a named command that can stand for an arbitrarily long sequence of operations. That is, it is like a shortcut for more complicated mathematical functions or processes, including operating the graphical device, that have been pre-programmed into R. A function will be followed by parentheses where you will specify further bits of information that R needs in order to perform the selected function. Each bit of information is an argument.
If there are several arguments, they are separated from each other by commas. For example, the sum() function adds its arguments together, so the following two commands return the same result:
459 + 51 + 327
sum(459, 51, 327)
The R assignment operator
Another very important special symbol is =, the assignment operator. This operator tells R to assign to the thing on its left, the value to its right. In the simplest case, this is just like giving a name to the value.
So for example:
x1 = 459 + 51
adds 51 to 459 and assigns the result the name x1.
x2 = sum(459, 51, 327)
stores the sum of these 3 numbers in x2.
x3 = 7 - 2
takes 2 from 7 and stores the result in x3.
x4 = sum(7, -2)
stores the sum of 7 and -2 in x4 (same as x3).
Once you have stored the result of an operation in this way, you can retrieve the computed value just by typing the “name” that you’ve given to the value. So, for example, if you type x1 or x2 or x3 or x4 in the R console window after running the above four commands, the next line on the R console window is the same value that you would have got by running the original command again. This is especially convenient if you want to store more complicated values, such as a vector of numbers instead of a single number.
The R vector function
First of all, a vector is basically a single row of items. In R, you can specify that a set of values is a vector by typing them, separated by commas, as arguments to the c() function, like this:
c(459, 51, 327)
The c() part of this command is a function that tells R to “concatenate” the arguments, which means “to group these items together in order,” which is a simple definition of a vector. Again, a function is like a shortcut for more complicated mathematical functions or processes.
The name of the function will be followed by parentheses where you will specify further information that R needs in order to perform the selected function. In this case, the () parentheses enclose the items you want grouped together, and the items are separated by commas, to show where one item ends and the next begins. If you assign the vector a name, like this:
x5 = c(459, 51, 327)
you have a way of referring back to it, so that you don’t have to keep typing the same numbers in over and over again. So, after you run the above command, the following two lines of code return the same value.
sum(459, 51, 327)
sum(x5)
The length() function lets you count the number of items in a vector. So the value that is returned by the following command is the number of items in the vector x5 that you created earlier.
length(x5)
You can refer to a value at any position in a vector by following the vector with the position number enclosed in square brackets. So after you have defined x5 as above, the following three commands all return the same result.
Just type the number and R will echo it.
length(x5)
Specify the second item in the vector
c(459, 51, 327)[2]
x5[2]
The following three commands also are equivalent ways of adding 459 and 51.
459 + 51
x5[1] + x5[2]
sum(x5[1],x5[2])
This equivalence may seem a bit boring and trivial now, but wait until you see what this buys you when you’re dealing with longer vectors or more complicated items!
LS0tCnRpdGxlOiAiR2V0dGluZyBzdGFydGVkIgpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazogCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcwogICAgdGhlbWU6IHJlYWRhYmxlCiAgICB0b2M6IHllcwogIGh0bWxfZG9jdW1lbnQ6CiAgICBkZl9wcmludDogcGFnZWQKICBwZGZfZG9jdW1lbnQ6IGRlZmF1bHQKLS0tCgpgYGB7ciwgaW5jbHVkZT1GQUxTRX0KbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkoa25pdHIpCmxkdCA8LSByZWFkX3RzdigibGR0LnR4dCIpCmNsYXNzKGxkdFtbMl1dKQpgYGAKCgo8IS0tIChjKSAyMDE2IEJyaWRnZXQgU21pdGgsIE1hcnkgRS4gQmVja21hbiAmIEFub3VzY2hrYSBGb2x0eiwgIC0tPgo8IS0tICAgICAgICAgICBUaGUgT2hpbyBTdGF0ZSBVbml2ZXJzaXR5IC0tPgoKPCEtLSAgQ29kZSBmcm9tIHRoZSBSIGNvZGUgc2VjdGlvbiBvZiB0aGUgcHJlZmFjZSB0byBTbWl0aCwgIC0tPgo8IS0tICBCZWNrbWFuLCBhbmQgRm9sdHogMjAxNiwgIkFuYWx5emluZyB0aGUgU291bmRzIG9mIExhbmd1YWdlcy4iIC0tPgoKCkJlZm9yZSB3ZSBjYW4gc3RhcnQgZXhwbG9yaW5nIGRhdGEgaW4gUiwgdGhlcmUgYXJlIHNvbWUga2V5IGNvbmNlcHRzIHRvIHVuZGVyc3RhbmQgZmlyc3Q6CgoxLiBXaGF0IGFyZSBSIGFuZCBSU3R1ZGlvPwoyLiBIb3cgZG8gSSBjb2RlIGluIFI/CgojIFdoYXQgYXJlIFIgYW5kIFJTdHVkaW8/IHsjci1yc3R1ZGlvfQoKSW4gdGhpcyBjbGFzcywgd2Ugd2lsbCBiZSB1c2luZyBSIHZpYSBSU3R1ZGlvLiBGaXJzdCB0aW1lIHVzZXJzIG9mdGVuIGNvbmZ1c2UgdGhlIHR3by4gQXQgaXRzIHNpbXBsZXN0IFIgaXMgbGlrZSBhIGNhcidzIGVuZ2luZSB3aGlsZSBSU3R1ZGlvIGlzIGxpa2UgYSBjYXIncyBkYXNoYm9hcmQuCgoKIVtDYXB0aW9uIGZvciB0aGUgcGljdHVyZS5dKGh0dHBzOi8vZDMzd3VicmZraTBsNjguY2xvdWRmcm9udC5uZXQvMGI0ZDA1NjliMmRkZjYxNDdkYTkwYjExMGZiYjJhMTc2NTNjOGIwOC9mMDZmMy9pbWFnZXMvc2h1dHRlcnN0b2NrL3JfdnNfcnN0dWRpb18xLnBuZykKCk1vcmUgcHJlY2lzZWx5LCBSIGlzIGEgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2UgdGhhdCBydW5zIGNvbXB1dGF0aW9ucyB3aGlsZSBSU3R1ZGlvIGlzIGFuICppbnRlZ3JhdGVkIGRldmVsb3BtZW50IGVudmlyb25tZW50IChJREUpKiB0aGF0IHByb3ZpZGVzIGFuIGludGVyZmFjZSBieSBhZGRpbmcgbWFueSBjb252ZW5pZW50IGZlYXR1cmVzIGFuZCB0b29scy4gU28ganVzdCBhcyB0aGUgd2F5IG9mIGhhdmluZyBhY2Nlc3MgdG8gYSBzcGVlZG9tZXRlciwgcmVhci12aWV3IG1pcnJvcnMsIGFuZCBhIG5hdmlnYXRpb24gc3lzdGVtIG1ha2VzIGRyaXZpbmcgbXVjaCBlYXNpZXIsIHVzaW5nIFJTdHVkaW8ncyBpbnRlcmZhY2UgbWFrZXMgdXNpbmcgUiBtdWNoIGVhc2llciBhcyB3ZWxsLiAKClNpbmNlIG1vc3QgaGF2ZSB5b3UgaGF2ZSBuZXZlciB1c2VkIFIsIHdlIGFyZSBhbHNvIHVzaW5nIFJTdHVkaW8gQ2xvdWQsIG1lYW5pbmcgdGhhdCB5b3UgZG9uJ3QgaGF2ZSB0byBpbnN0YWxsIGFueXRoaW5nLiAgRXZlcnl0aGluZyBoYXMgYWxyZWFkeSBiZWVuIHNldC11cCBmb3IgeW91IHNvIHRoYXQgeW91IGNhbiBqdXN0IGxvZyBpbiBhbmQgZ2V0IHN0YXJ0ZWQuCgojIEhvdyBkbyBJIGNvZGUgaW4gUj8KCk5vdyB0aGF0IHlvdSdyZSBzZXQgdXAgd2l0aCBSIGFuZCBSU3R1ZGlvLCB5b3UgYXJlIHByb2JhYmx5IGFza2luZyB5b3Vyc2VsZiAiT0suIE5vdyBob3cgZG8gSSB1c2UgUj8iIFRoZSBmaXJzdCB0aGluZyB0byBub3RlIGlzIHRoYXQgdW5saWtlIG90aGVyIHN0YXRpc3RpY2FsIHNvZnR3YXJlIHByb2dyYW1zIGxpa2UgRXhjZWwsIFNUQVRBLCBvciBTQVMgdGhhdCBwcm92aWRlIFtwb2ludC1hbmQtY2xpY2tdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL1BvaW50X2FuZF9jbGljaykgaW50ZXJmYWNlcywgUiBpcyBhbiBbaW50ZXJwcmV0ZWQgbGFuZ3VhZ2VdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0ludGVycHJldGVkX2xhbmd1YWdlKS4gVGhpcyBtZWFucyB5b3UgaGF2ZSB0byB0eXBlIGluIGNvbW1hbmRzIHdyaXR0ZW4gaW4gKlIgY29kZSouIEluIG90aGVyIHdvcmRzLCB5b3UgaGF2ZSB0byBjb2RlL3Byb2dyYW0gaW4gUi4gTm90ZSB0aGF0IHdlJ2xsIHVzZSB0aGUgdGVybXMgImNvZGluZyIgYW5kICJwcm9ncmFtbWluZyIgaW50ZXJjaGFuZ2VhYmx5IGluIHRoaXMgY291cnNlLgoKV2hpbGUgaXQgaXMgbm90IHJlcXVpcmVkIHRvIGJlIGEgc2Vhc29uZWQgY29kZXIvY29tcHV0ZXIgcHJvZ3JhbW1lciB0byB1c2UgUiwgdGhlcmUgaXMgc3RpbGwgYSBzZXQgb2YgYmFzaWMgcHJvZ3JhbW1pbmcgY29uY2VwdHMgdGhhdCBsaW5ndWlzdGljcyB3b3JraW5nIHdpdGggcXVhbnRpdGF0aXZlIGRhdGEgbmVlZCB0byB1bmRlcnN0YW5kLiBDb25zZXF1ZW50bHksIHdoaWxlIHRoaXMgY291cnNlIGlzIG5vdCBhIGNvdXJzZSBvbiBwcm9ncmFtbWluZywgeW91IHdpbGwgc3RpbGwgbGVhcm4ganVzdCBlbm91Z2ggb2YgdGhlc2UgYmFzaWMgcHJvZ3JhbW1pbmcgY29uY2VwdHMgbmVlZGVkIHRvIGV4cGxvcmUgYW5kIGFuYWx5emUgZGF0YSBlZmZlY3RpdmVseS4KCiMgVGlwcyBvbiBsZWFybmluZyB0byBjb2RlCgpMZWFybmluZyB0byBjb2RlL3Byb2dyYW0gaXMgdmVyeSBtdWNoIGxpa2UgbGVhcm5pbmcgYSBmb3JlaWduIGxhbmd1YWdlLiBJdCBjYW4gYmUgdmVyeSBkYXVudGluZyBhbmQgZnJ1c3RyYXRpbmcgYXQgZmlyc3QuIFN1Y2ggZnJ1c3RyYXRpb25zIGFyZSB2ZXJ5IGNvbW1vbiBhbmQgaXQgaXMgdmVyeSBub3JtYWwgdG8gZmVlbCBkaXNjb3VyYWdlZCBhcyB5b3UgbGVhcm4uIEhvd2V2ZXIganVzdCBhcyB3aXRoIGxlYXJuaW5nIGEgZm9yZWlnbiBsYW5ndWFnZSwgaWYgeW91IHB1dCBpbiB0aGUgZWZmb3J0IGFuZCBhcmUgbm90IGFmcmFpZCB0byBtYWtlIG1pc3Rha2VzLCBhbnlib2R5IGNhbiBsZWFybi4gCgpIZXJlIGFyZSBhIGZldyB1c2VmdWwgdGlwcyB0byBrZWVwIGluIG1pbmQgYXMgeW91IGxlYXJuIHRvIHByb2dyYW06CgoqICoqUmVtZW1iZXIgdGhhdCBjb21wdXRlcnMgYXJlIG5vdCBhY3R1YWxseSB0aGF0IHNtYXJ0Kio6IFlvdSBtYXkgdGhpbmsgeW91ciBjb21wdXRlciBvciBzbWFydHBob25lIGFyZSAic21hcnQsIiBidXQgcmVhbGx5IHBlb3BsZSBzcGVudCBhIGxvdCBvZiB0aW1lIGFuZCBlbmVyZ3kgZGVzaWduaW5nIHRoZW0gdG8gYXBwZWFyICJzbWFydC4iIEluIHJlYWxpdHksIHlvdSBoYXZlIHRvIHRlbGwgYSBjb21wdXRlciBldmVyeXRoaW5nIGl0IG5lZWRzIHRvIGRvLiBGdXJ0aGVybW9yZSwgdGhlIGluc3RydWN0aW9ucyB5b3UgZ2l2ZSB5b3VyIGNvbXB1dGVyIGNhbid0IGhhdmUgYW55IG1pc3Rha2VzIGluIHRoZW0gbm9yIGNhbiB0aGV5IGJlIGFtYmlndW91cyBpbiBhbnkgd2F5LgoqICoqVGFrZSB0aGUgImNvcHksIHBhc3RlLCBhbmQgdHdlYWsiIGFwcHJvYWNoKio6IEVzcGVjaWFsbHkgd2hlbiB5b3UgbGVhcm4geW91ciBmaXJzdCBwcm9ncmFtbWluZyBsYW5ndWFnZSBvciB5b3UgbmVlZCB0byB1bmRlcnN0YW5kIHBhcnRpY3VsYXJseSBjb21wbGljYXRlZCBjb2RlLCBpdCBpcyBvZnRlbiBtdWNoIGVhc2llciB0byB0YWtlIGV4aXN0aW5nIGNvZGUgdGhhdCB5b3Uga25vdyB3b3JrcyBhbmQgbW9kaWZ5IGl0IHRvIHN1aXQgeW91ciBlbmRzLiBUaGlzIGlzIG9wcG9zZWQgdG8gdHJ5aW5nIHRvIHR5cGUgb3V0IHRoZSBjb2RlIGZyb20gc2NyYXRjaC4gV2UgY2FsbCB0aGlzIHRoZSAqImNvcHksIHBhc3RlLCBhbmQgdHdlYWsiKiBhcHByb2FjaC4gU28gZWFybHkgb24sIHdlIHN1Z2dlc3Qgbm90IHRyeWluZyB0byB3cml0ZSBjb2RlIGZyb20gbWVtb3J5LCBidXQgcmF0aGVyIHRha2UgZXhpc3RpbmcgZXhhbXBsZXMgd2UgaGF2ZSBwcm92aWRlZCB5b3UsIHRoZW4gY29weSwgcGFzdGUsIGFuZCB0d2VhayB0aGVtIHRvIHN1aXQgeW91ciBnb2Fscy4gQWZ0ZXIgeW91IHN0YXJ0IGZlZWxpbmcgbW9yZSBjb25maWRlbnQsIHlvdSBjYW4gc2xvd2x5IG1vdmUgYXdheSBmcm9tIHRoaXMgYXBwcm9hY2guIFRoaW5rIG9mIHRoZSAiY29weSwgcGFzdGUsIGFuZCB0d2VhayIgYXBwcm9hY2ggYXMgdHJhaW5pbmcgd2hlZWxzIGZvciBhIGNoaWxkIGxlYXJuaW5nIHRvIHJpZGUgYSBiaWtlLiBBZnRlciBnZXR0aW5nIGNvbWZvcnRhYmxlLCB0aGV5IHdvbid0IG5lZWQgdGhlbSBhbnltb3JlLiAKKiAqKlRoZSBiZXN0IHdheSB0byBsZWFybiB0byBjb2RlIGlzIGJ5IGRvaW5nKio6IFJhdGhlciB0aGFuIGxlYXJuaW5nIHRvIGNvZGUgZm9yIGl0cyBvd24gc2FrZSwgd2UgZmVlbCB0aGF0IGxlYXJuaW5nIHRvIGNvZGUgZ29lcyBtdWNoIHNtb290aGVyIHdoZW4geW91IGhhdmUgYSBnb2FsIGluIG1pbmQgb3Igd2hlbiB5b3UgYXJlIHdvcmtpbmcgb24gYSBwYXJ0aWN1bGFyIHByb2plY3QsIGxpa2UgYW5hbHl6aW5nIGRhdGEgdGhhdCB5b3UgYXJlIGludGVyZXN0ZWQgaW4uIAoqICoqUHJhY3RpY2UgaXMga2V5Kio6ICBKdXN0IGFzIHRoZSBvbmx5IG1ldGhvZCB0byBpbXByb3ZlIHlvdXIgZm9yZWlnbiBsYW5ndWFnZSBza2lsbHMgaXMgdGhyb3VnaCBsb3RzIG9mIHByYWN0aWNlLCB0aGUgb25seSBtZXRob2QgdG8gaW1wcm92aW5nIHlvdXIgY29kaW5nIHNraWxscyBpcyB0aHJvdWdoIGxvdHMgb2YgcHJhY3RpY2UuIERvbid0IHdvcnJ5IGhvd2V2ZXIsIHdlJ2xsIGdpdmUgeW91IHBsZW50eSBvZiBvcHBvcnR1bml0aWVzIHRvIGRvIHNvIQoKIyBHZXR0aW5nIHN0YXJ0ZWQKCkFmdGVyIHlvdSBsb2cgaW4sIHlvdSB3aWxsIHNlZSB0d28gbWFpbiB3aW5kb3dzIG9uIHRoZSBsZWZ0IG9mIHRoZSBzY3JlZW4uCiogVGhlIHdpbmRvdyBvbiB0b3AgdGhhdCBjb250YWlucyB0aGUgdGV4dCBhbmQgY29kZSBmcm9tIHRoaXMgc2VjdGlvbiBpcyBjYWxsZWQgYW4gKlIgc2NyaXB0KiAob3Igc29tZXRpbWVzIGFuIFIgbm90ZWJvb2stLWJ1dCB3ZSdsbCBnZXQgdG8gdGhhdCBsYXRlcikuIAoqIFRoZSB3aW5kb3cgYmVsb3csIHdoZXJlIGFsbCBvZiB0aGUgb3V0cHV0IGlzIGxpc3RlZCBpcyBjYWxsZWQgdGhlICpSIGNvbnNvbGUqLiAKClRoZSBkaWZmZXJlbmNlIGlzIHRoYXQgeW91IGNhbiB3cml0ZSBhbmQgZXJhc2UgYXMgbXVjaCBhcyB5b3Ugd2FudCBpbnNpZGUgdGhlIHNjcmlwdCwgYW5kIGl0IHdpbGwgbm90IGRvIGFueXRoaW5nIHVudGlsIHlvdSB0cmFuc2ZlciBhIGxpbmUgb2YgY29kZSB0byB0aGUgY29uc29sZS4gSW5zaWRlIHRoZSBjb25zb2xlIHdpbmRvdywgeW91IGNhbm5vdCBjaGFuZ2UgYQpsaW5lIG9mIGNvZGUgb25jZSBpdCBpcyBlbnRlcmVkOyB5b3UgaW5zdGVhZCBoYXZlIHRvIHJlLWVudGVyIHRoZSBjaGFuZ2VkIGxpbmUgb2YgY29kZS4gVG8gcnVuIGFueSBsaW5lIG9mIGNvZGUsIHlvdSBhbiBkbyBhbnkgb2YgdGhlIGZvbGxvd2luZzoKCjEuIFR5cGUgdGhlIGxpbmUgZGlyZWN0bHkgaW50byB0aGUgUiBjb25zb2xlIHdpbmRvdyBmb2xsb3dlZCBieSBhIGNhcnJpYWdlIHJldHVybiAoaS5lLiBFTlRFUikuCgoyLiBVc2UgdGhlIGtleWJvYXJkIG9yIG1vdXNlIHRvIGNvcHkgdGhlIGxpbmUgKGluY2x1ZGluZyB0aGUgY2FycmlhZ2UgcmV0dXJuIGF0IHRoZSBlbmQpIGZyb20gdGhlIHNjcmlwdCBhbmQgcGFzdGUgaXQgaW50byB0aGUgUiBjb25zb2xlIHdpbmRvdy4KCjMuIEhpZ2hsaWdodCB0aGUgcGFydCBvZiB0aGUgY29kZSB5b3Ugd2FudCB0byB1c2UgZnJvbSB0aGUgc2NyaXB0IGJ5IGNsaWNraW5nIGFuZCBkcmFnZ2luZyB5b3VyIG1vdXNlIG92ZXIgaXQuClRoZW4sIGZvciBhIE1hYywgaG9sZCBkb3duIHRoZSA8Y29tbWFuZD4ga2V5ICh0aGUgc3dpcmx5Z2lnIGJ1dHRvbiwgZm9ybWVybHkgdGhlIGFwcGxlIGJ1dHRvbikgb24gdGhlIGxlZnQgb2YgdGhlIGtleWJvYXJkLCBhbmQgdGhlbiBhbHNvIGhpdCA8cmV0dXJuPiAoYXMgeW91IGFyZSBjb250aW51aW5nIHRvIGhvbGQgdGhlIDxjb21tYW5kPiBrZXkpLiBJZiB5b3UgdXNlIFIgb24gYQpQQyBydW5uaW5nIHdpbmRvd3MgKG9yIGxpbnV4KSwgeW91IHdpbGwgaGlnaGxpZ2h0IHRoZSBjb2RlIGFuZCBwcmVzcyA8Y3RybD4gYW5kIHRoZSBsZXR0ZXIgInIiLgoKVGhlIGxhc3Qgb3B0aW9uIGlzIHRoZSBmYXN0ZXN0IHdheSBvZiBnZXR0aW5nIGEgbGluZSBvZiBjb2RlIHRvIHdvcmsgYmVjYXVzZSBpdCB0cmFuc2ZlcnMgaXQgdG8gdGhlIGNvbnNvbGUgYW5kCmV4ZWN1dGVzIHRoZSBjb21tYW5kIGFsbCBhdCBvbmNlLiBFdmVuIGlmIHlvdSBhcmUgd3JpdGluZyB0aGUgY29tbWFuZHMgb3IgZnVuY3Rpb25zIHlvdXJzZWxmLCB5b3Ugc2hvdWxkIHdyaXRlIHRoZW0gaW4gYSBzY3JpcHQgd2luZG93IGZpcnN0IGFuZCB0aGVuIGV4ZWN1dGUgdGhlbSBmcm9tIHRoZSBzY3JpcHQuIFRoYXQgd2F5LCBpdCBpcyBlYXNpZXIgdG8gZ28gYmFjayBhbmQgbWFrZSBjaGFuZ2VzIHRvIHlvdXIgY29kZSAod2hpY2ggeW91IHdpbGwgcHJvYmFibHkgaGF2ZSB0byBkbyBvZnRlbiBhdApmaXJzdCkuCgojIyBDb2RlIHZzLiB0ZXh0CgpJZiB5b3UgYXJlIHVzaW5nIHRoZSAuUm1kIGZpbGUsIHlvdSdsbCBub3RpY2UgdGhhdCB0aGlzIHRleHQgaXMganVzdCB3cml0dGVuIGxpa2Ugbm9ybWFsIHRleHQuICBJbiBhIG5vdGVib29rIGxpa2UgdGhpcywgeW91IHRlbGwgUlN0dWRpbyB0aGF0IHlvdSdyZSB3cml0aW5nIGNvZGUgKG5vdCB0ZXh0KSBieSBpbnNlcnRpbmcgYSBjb2RlIGNodW5rIGxpa2UgdGhpcy4KCgpgYGB7cn0KNyAtIDIKYGBgCgpUaGUgY29kZSBhYm92ZSBzdWJ0cmFjdHMgMiBmcm9tIDcuCgpUaGUgb3V0cHV0IChpLmUuIDUpIGlzIGFsc28gc2hvd24gYmVsb3cgdGhlIGNvZGUuCgojIEFyaXRobWV0aWMgb3BlcmF0b3JzCgpOb3cgdGhlIGVhc2llc3QgdGhpbmcgdG8gZG8gaW4gUiBpcyBiYXNpYyBhcml0aG1ldGljIG9wZXJhdGlvbnMuIEJhc2ljIG9wZXJhdG9yIHNpZ25zIGFyZSBhcyBmb2xsb3dzOgoKQWRkaW5nOgpgYGB7cn0KNDU5ICsgNTEKYGBgCgpTdWJ0cmFjdGluZzoKYGBge3J9CjQ1OSAtIDUxCmBgYAoKTXVsdGlwbHlpbmc6CmBgYHtyfQo0NTkgKiA1MQpgYGAKCkRpdmlkaW5nOgpgYGB7cn0KNDU5IC8gNTEKYGBgCgpFeHBvbmVudGlhdGlvbgpgYGB7cn0KNTEgXiAzCjUxICogNTEgKiA1MQpgYGAKClJlbWVtYmVyLCB0byBzb2x2ZSBlYWNoIG9mIHRoZXNlIGVxdWF0aW9ucywgeW91IGNvdWxkIAoKMS4gdHlwZSBpdCBpbnRvIHRoZSBjb25zb2xlIHRoZW4gaGl0IHJldHVybgoyLiBjb3B5IGFuZCBwYXN0ZSBpdCBpbnRvIHRoZSBjb25zb2xlIGFuZCBwcmVzcyByZXR1cm4sIG9yIAozLiBoaWdobGlnaHQgaXQgZnJvbSB0aGUgcG9ydGlvbiBvZiB0aGUgbm90ZWJvb2sgYW5kIHByZXNzIDxjb21tYW5kPis8cmV0dXJuPiAob3IgPGN0cmw+KzxSPiBmb3IgYSBQQwpydW5uaW5nIHdpbmRvd3MpLiAKCioqVHJ5IGV4ZWN1dGluZyB0aGUgY29tbWFuZHMgaW4gZWFjaCBvZiB0aGUgdGhyZWUgd2F5cy4qKgoKSWYgaXQgaGFzIGJlZW4gYSB3aGlsZSBzaW5jZSB5b3UgaGF2ZSBkb25lIGEgbG90IG9mIHRoaXMga2luZCBvZiBhcml0aG1ldGljLCBpdCBtaWdodCBiZSBnb29kIHRvIHJldmlldyBzb21lIG90aGVyIGJhc2ljcywgc3VjaCBhcyB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSBmb2xsb3dpbmcgMiBjb21tYW5kcy4KCmBgYHtyfQooNDU5ICsgNTEpIC8gMwo0NTkgKyAoNTEgLyAzKQpgYGAKClRoZSBmaXJzdCBsaW5lIGFkZHMgNTEgdG8gNDU5IGFuZCB0aGVuIGRpdmlkZXMgdGhlIHJlc3VsdCBieSAzLgpUaGUgc2Vjb25kIGxpbmUgYWRkcyA0NTkgcGx1cyB0aGUgcmVzdWx0IG9mIGRpdmlkaW5nIDUxIGJ5IDMuCgojIEZ1bmN0aW9ucwoKQWRkaXRpb24gYWxzbyBjYW4gYmUgcGVyZm9ybWVkIHVzaW5nIHRoZSBSIGZ1bmN0aW9uIGBzdW0oKWAuIEEgZnVuY3Rpb24gaXMgYSBuYW1lZCBjb21tYW5kIHRoYXQgY2FuIHN0YW5kIGZvciBhbiBhcmJpdHJhcmlseSBsb25nIHNlcXVlbmNlIG9mIG9wZXJhdGlvbnMuIFRoYXQgaXMsIGl0IGlzIGxpa2UgYSBzaG9ydGN1dCBmb3IgbW9yZSBjb21wbGljYXRlZCBtYXRoZW1hdGljYWwgZnVuY3Rpb25zIG9yIHByb2Nlc3NlcywgaW5jbHVkaW5nIG9wZXJhdGluZyB0aGUgZ3JhcGhpY2FsIGRldmljZSwKdGhhdCBoYXZlIGJlZW4gcHJlLXByb2dyYW1tZWQgaW50byBSLiAKQSBmdW5jdGlvbiB3aWxsIGJlIGZvbGxvd2VkIGJ5IHBhcmVudGhlc2VzIHdoZXJlIHlvdSB3aWxsIHNwZWNpZnkgZnVydGhlciBiaXRzIG9mIGluZm9ybWF0aW9uIHRoYXQgUiBuZWVkcyBpbiBvcmRlciB0byBwZXJmb3JtIHRoZSBzZWxlY3RlZCBmdW5jdGlvbi4gRWFjaCBiaXQgb2YgaW5mb3JtYXRpb24gaXMgYW4gYXJndW1lbnQuCgpJZiB0aGVyZSBhcmUgc2V2ZXJhbCBhcmd1bWVudHMsIHRoZXkgYXJlIHNlcGFyYXRlZCBmcm9tIGVhY2ggb3RoZXIgYnkgY29tbWFzLiBGb3IgZXhhbXBsZSwgdGhlIHN1bSgpIGZ1bmN0aW9uIGFkZHMgaXRzIGFyZ3VtZW50cyB0b2dldGhlciwgc28gdGhlIGZvbGxvd2luZyB0d28gY29tbWFuZHMgcmV0dXJuIHRoZSBzYW1lIHJlc3VsdDoKCmBgYHtyfQo0NTkgKyA1MSArIDMyNwpzdW0oNDU5LCA1MSwgMzI3KQpgYGAKCiMgVGhlIFIgYXNzaWdubWVudCBvcGVyYXRvcgoKQW5vdGhlciB2ZXJ5IGltcG9ydGFudCBzcGVjaWFsIHN5bWJvbCBpcyBgPWAsIHRoZSBhc3NpZ25tZW50IG9wZXJhdG9yLiBUaGlzIG9wZXJhdG9yIHRlbGxzIFIgdG8gYXNzaWduIHRvIHRoZQp0aGluZyBvbiBpdHMgbGVmdCwgdGhlIHZhbHVlIHRvIGl0cyByaWdodC4gSW4gdGhlIHNpbXBsZXN0IGNhc2UsIHRoaXMgaXMganVzdCBsaWtlIGdpdmluZyBhIG5hbWUgdG8gdGhlIHZhbHVlLiAKClNvIGZvciBleGFtcGxlOgoKYGBge3J9CngxID0gNDU5ICsgNTEKYGBgCmFkZHMgNTEgdG8gNDU5IGFuZCBhc3NpZ25zIHRoZSByZXN1bHQgdGhlIG5hbWUgYHgxYC4gCgoKYGBge3J9CngyID0gc3VtKDQ1OSwgNTEsIDMyNykKYGBgCnN0b3JlcyB0aGUgc3VtIG9mIHRoZXNlIDMgbnVtYmVycyBpbiBgeDJgLiAKCmBgYHtyfQp4MyA9IDcgLSAyCmBgYAp0YWtlcyAyIGZyb20gNyBhbmQgc3RvcmVzIHRoZSByZXN1bHQgaW4gYHgzYC4KCmBgYHtyfQp4NCA9IHN1bSg3LCAtMikKYGBgCnN0b3JlcyB0aGUgc3VtIG9mIDcgYW5kIC0yIGluIGB4NGAgKHNhbWUgYXMgYHgzYCkuIAoKCk9uY2UgeW91IGhhdmUgc3RvcmVkIHRoZSByZXN1bHQgb2YgYW4gb3BlcmF0aW9uIGluIHRoaXMgd2F5LCB5b3UgY2FuIHJldHJpZXZlIHRoZSBjb21wdXRlZCB2YWx1ZSBqdXN0IGJ5IHR5cGluZyB0aGUgIm5hbWUiIHRoYXQgeW914oCZdmUgZ2l2ZW4gdG8gdGhlIHZhbHVlLiAgU28sIGZvciBleGFtcGxlLCBpZiB5b3UgdHlwZSBgeDFgIG9yIGB4MmAgb3IgYHgzYCBvciBgeDRgIGluIHRoZSBSIGNvbnNvbGUgd2luZG93IGFmdGVyIHJ1bm5pbmcgdGhlIGFib3ZlIGZvdXIgY29tbWFuZHMsIHRoZSBuZXh0IGxpbmUgb24gdGhlIFIgY29uc29sZSB3aW5kb3cgaXMgdGhlIHNhbWUgdmFsdWUgdGhhdCB5b3Ugd291bGQgaGF2ZSBnb3QgYnkgcnVubmluZyB0aGUgb3JpZ2luYWwgY29tbWFuZCBhZ2Fpbi4gVGhpcyBpcyBlc3BlY2lhbGx5IGNvbnZlbmllbnQgaWYgeW91IHdhbnQgdG8gc3RvcmUgbW9yZSBjb21wbGljYXRlZCB2YWx1ZXMsIHN1Y2ggYXMgYSB2ZWN0b3Igb2YgbnVtYmVycyBpbnN0ZWFkIG9mIGEgc2luZ2xlIG51bWJlci4KCgojIFRoZSBSIHZlY3RvciBmdW5jdGlvbgoKRmlyc3Qgb2YgYWxsLCBhIHZlY3RvciBpcyBiYXNpY2FsbHkgYSBzaW5nbGUgcm93IG9mIGl0ZW1zLiBJbiBSLCB5b3UgY2FuIHNwZWNpZnkgdGhhdCBhIHNldCBvZiB2YWx1ZXMgaXMgYSB2ZWN0b3IgYnkgdHlwaW5nIHRoZW0sIHNlcGFyYXRlZCBieSBjb21tYXMsIGFzIGFyZ3VtZW50cyB0byB0aGUgYGMoKWAgZnVuY3Rpb24sIGxpa2UgdGhpczoKCmBgYHtyfQpjKDQ1OSwgNTEsIDMyNykKYGBgCgpUaGUgYGMoKWAgcGFydCBvZiB0aGlzIGNvbW1hbmQgaXMgYSBmdW5jdGlvbiB0aGF0IHRlbGxzIFIgdG8gImNvbmNhdGVuYXRlIiB0aGUgYXJndW1lbnRzLCB3aGljaCBtZWFucyAidG8gZ3JvdXAgdGhlc2UgaXRlbXMgdG9nZXRoZXIgaW4gb3JkZXIsIiB3aGljaCBpcyBhIHNpbXBsZSBkZWZpbml0aW9uIG9mIGEgdmVjdG9yLiBBZ2FpbiwgYSBmdW5jdGlvbiBpcyBsaWtlIGEgc2hvcnRjdXQgZm9yIG1vcmUgY29tcGxpY2F0ZWQgbWF0aGVtYXRpY2FsIGZ1bmN0aW9ucyBvciBwcm9jZXNzZXMuCgpUaGUgbmFtZSBvZiB0aGUgZnVuY3Rpb24gd2lsbCBiZSBmb2xsb3dlZCBieSBwYXJlbnRoZXNlcyB3aGVyZSB5b3Ugd2lsbCBzcGVjaWZ5IGZ1cnRoZXIgaW5mb3JtYXRpb24gdGhhdCBSIG5lZWRzIGluIG9yZGVyIHRvIHBlcmZvcm0gdGhlIHNlbGVjdGVkIGZ1bmN0aW9uLiBJbiB0aGlzIGNhc2UsIHRoZSBgKClgIHBhcmVudGhlc2VzIGVuY2xvc2UgdGhlIGl0ZW1zIHlvdSB3YW50IGdyb3VwZWQgdG9nZXRoZXIsIGFuZCB0aGUgaXRlbXMgYXJlIHNlcGFyYXRlZCBieSBjb21tYXMsIHRvIHNob3cgd2hlcmUgb25lIGl0ZW0gZW5kcyBhbmQgdGhlIG5leHQgYmVnaW5zLiBJZiB5b3UgYXNzaWduIHRoZSB2ZWN0b3IgYSBuYW1lLCBsaWtlIHRoaXM6CmBgYHtyfQp4NSA9IGMoNDU5LCA1MSwgMzI3KQpgYGAKeW91IGhhdmUgYSB3YXkgb2YgcmVmZXJyaW5nIGJhY2sgdG8gaXQsIHNvIHRoYXQgeW91IGRvbuKAmXQgaGF2ZSB0byBrZWVwIHR5cGluZyB0aGUgc2FtZSBudW1iZXJzIGluIG92ZXIgYW5kIG92ZXIgYWdhaW4uIFNvLCBhZnRlciB5b3UgcnVuIHRoZSBhYm92ZSBjb21tYW5kLCB0aGUgZm9sbG93aW5nIHR3byBsaW5lcyBvZiBjb2RlIHJldHVybiB0aGUgc2FtZSB2YWx1ZS4KCmBgYHtyfQpzdW0oNDU5LCA1MSwgMzI3KQpzdW0oeDUpCmBgYAoKVGhlIGBsZW5ndGgoKWAgZnVuY3Rpb24gbGV0cyB5b3UgY291bnQgdGhlIG51bWJlciBvZiBpdGVtcyBpbiBhIHZlY3Rvci4gU28gdGhlIHZhbHVlIHRoYXQgaXMgcmV0dXJuZWQgYnkgdGhlIGZvbGxvd2luZyBjb21tYW5kIGlzIHRoZSBudW1iZXIgb2YgaXRlbXMgaW4gdGhlIHZlY3RvciBgeDVgIHRoYXQgeW91IGNyZWF0ZWQgZWFybGllci4KCmBgYHtyfQpsZW5ndGgoeDUpCmBgYAoKWW91IGNhbiByZWZlciB0byBhIHZhbHVlIGF0IGFueSBwb3NpdGlvbiBpbiBhIHZlY3RvciBieSBmb2xsb3dpbmcgdGhlIHZlY3RvciB3aXRoIHRoZSBwb3NpdGlvbiBudW1iZXIgZW5jbG9zZWQgaW4gc3F1YXJlIGJyYWNrZXRzLiBTbyBhZnRlciB5b3UgaGF2ZSBkZWZpbmVkIGB4NWAgYXMgYWJvdmUsIHRoZSBmb2xsb3dpbmcgdGhyZWUgY29tbWFuZHMgYWxsIHJldHVybiB0aGUgc2FtZSByZXN1bHQuCgpKdXN0IHR5cGUgdGhlIG51bWJlciBhbmQgUiB3aWxsIGVjaG8gaXQuCmBgYHtyfQpsZW5ndGgoeDUpCmBgYAoKU3BlY2lmeSB0aGUgc2Vjb25kIGl0ZW0gaW4gdGhlIHZlY3RvcgpgYGB7cn0KYyg0NTksIDUxLCAzMjcpWzJdCng1WzJdCmBgYAoKVGhlIGZvbGxvd2luZyB0aHJlZSBjb21tYW5kcyBhbHNvIGFyZSBlcXVpdmFsZW50IHdheXMgb2YgYWRkaW5nIDQ1OSBhbmQgNTEuCgpgYGB7cn0KNDU5ICsgNTEKeDVbMV0gKyB4NVsyXQpzdW0oeDVbMV0seDVbMl0pCmBgYAoKVGhpcyBlcXVpdmFsZW5jZSBtYXkgc2VlbSBhIGJpdCBib3JpbmcgYW5kIHRyaXZpYWwgbm93LCBidXQgd2FpdCB1bnRpbCB5b3Ugc2VlIHdoYXQgdGhpcyBidXlzIHlvdSB3aGVuIHlvdeKAmXJlIGRlYWxpbmcgd2l0aCBsb25nZXIgdmVjdG9ycyBvciBtb3JlIGNvbXBsaWNhdGVkIGl0ZW1zIQ==