Getting Started with R

You will familiarize yourself with the R computing language, R Studio environment, and R Markdown language. If you are already familiar with these, then lucky you, you are ahead of me! If not, read on.

There are two ways to complete this project: Downloading and installing R on your own machine (or using an already installed version of R on a campus computer), or running this notebook in the cloud version of R.

Installing R on Your Personal Machine

  • Download R and RStudio (recommended over using R alone)
  • (Windows) Install Rtools. Note that there are instructions on this page for creating a text file called .Renviron that identifies a path for R to use to find Rtools. It seemse complicated, but is fairly straightforward in practice.

Using R Studio in the Cloud - Preferred

  • I have set up a Jupyter Notebook for use in this class to make it really easy for you to run these programs in a cloud version of R Studio. The link is in the class navigation pane.

R Markdown and Notebooks

This is the html document produced by an R Markdown Notebook. You can download the code to run in R above (Code>Download Rmd). When you execute code within the notebook, the results appear beneath the code. You can download this file, experiment with it, and change it to suit your needs. When you are ready to finalize your results, make sure that you have run all of the relevant chunks of code and then click preview (do not knit!) above to create a html document of your own with code and results included.

The grey box below is called a chunk. Try executing this chunk by clicking the green arrow on the far left, the Run button within the chunk, or by placing your cursor inside it and pressing Ctrl+Shift+Enter.

## This is a comment and the # tells R not to read it.  Run the command below to print out the message "Hello World."
print ("Hello World")
[1] "Hello World"

Once you’ve installed RStudio, you have to install your packages (but only do this once). Open a script (File > New File > R Script) and type the commands below (or run them in the notebook).

If you use the class jupyterhub, you may not need to install any packages.

## Run this code if you haven't run it before, but only needs to be run once after you have installed R.Not needed in JupyterHub.
if (!require("pacman")) install.packages("pacman") #pacman is the package that installs packages nicely
Loading required package: pacman
Warning: there is no package called ‘pacman’trying URL 'https://cran.rstudio.com/src/contrib/pacman_0.5.1.tar.gz'
Content type 'application/x-gzip' length 274400 bytes (267 KB)
==================================================
downloaded 267 KB

* installing *source* package ‘pacman’ ...
** package ‘pacman’ successfully unpacked and MD5 sums checked
** using staged installation
** R
** inst
** byte-compile and prepare package for lazy loading
** help
*** installing help indices
** building package indices
** testing if installed package can be loaded from temporary location
** testing if installed package can be loaded from final location
** testing if installed package keeps a record of temporary installation path
* DONE (pacman)

The downloaded source packages are in
    ‘/tmp/RtmpXRhW6O/downloaded_packages’
Updating HTML index of packages in '.Library'
Making 'packages.html' ... done
pacman::p_load(rmarkdown, dplyr, gapminder, tidyverse, xml2, ggplot2, dplyr, lifecycle) #these are the packages you may need

After installing your packages, you need to load the ones you will be using in your program every time.

## Only needs to be run once per session.
library(ggplot2)
library(gapminder)
library(dplyr)

Attaching package: ‘dplyr’

The following objects are masked from ‘package:stats’:

    filter, lag

The following objects are masked from ‘package:base’:

    intersect, setdiff, setequal, union

Hint: You can also include the commands above at the start of a script if you decide to create and run your own code.

Introduction to Data Work in R

#Below, you can practice a calculation in R.  If you run the code below, R will output the sum.
3+1
[1] 4
#But maybe you want to perform an operation and save the results in a variable so that you can use them later in other calculations?
#This code shows you how to assign a value to a variable x using a calculation, and then prints the value of x.
x<-3+1
x
[1] 4
#In fact, R thinks in vectors and matrices works best when you assign a bunch of values to a variable.  
x1<-c(1,2,3,4) #This makes a 1 dimensional vector
x2<-matrix(c(1,2,3,4), nrow=2, ncol=2) #This makes a 2x2 matrix
x1
x2

You can try modifying the numbers above yourself and making different size matrices, etc.

Data Frames

Data frames are a useful way that R organizes data. These are flexible versions of matrices that have special properties that make them easy to work with. Later, you will import some actual data from the internet into a data frame, but for now we will use the gapminder data that is included in the package you loaded earlier.

Gapminder (gapminder.org) data is data on life expectancy and GDP by country over time. It can be used to calculate Preston Curves, as discussed in class. For now, let’s just perform a few operations on it.

#Some quick summary statistics
summary(gapminder)
        country        continent        year         lifeExp           pop           
 Afghanistan:  12   Africa  :624   Min.   :1952   Min.   :23.60   Min.   :6.001e+04  
 Albania    :  12   Americas:300   1st Qu.:1966   1st Qu.:48.20   1st Qu.:2.794e+06  
 Algeria    :  12   Asia    :396   Median :1980   Median :60.71   Median :7.024e+06  
 Angola     :  12   Europe  :360   Mean   :1980   Mean   :59.47   Mean   :2.960e+07  
 Argentina  :  12   Oceania : 24   3rd Qu.:1993   3rd Qu.:70.85   3rd Qu.:1.959e+07  
 Australia  :  12                  Max.   :2007   Max.   :82.60   Max.   :1.319e+09  
 (Other)    :1632                                                                    
   gdpPercap       
 Min.   :   241.2  
 1st Qu.:  1202.1  
 Median :  3531.8  
 Mean   :  7215.3  
 3rd Qu.:  9325.5  
 Max.   :113523.1  
                   
# Load relevant data into data frame DF_2007 for the year 2007 and the continent of Africa.
## What is the median life expectancy in the continent in 2007?
DF<-data.frame(gapminder)
DF_2007<-filter(DF, year==2007 & continent=="Africa")
summary(DF_2007)
         country      continent       year         lifeExp           pop           
 Algeria     : 1   Africa  :52   Min.   :2007   Min.   :39.61   Min.   :   199579  
 Angola      : 1   Americas: 0   1st Qu.:2007   1st Qu.:47.83   1st Qu.:  2909226  
 Benin       : 1   Asia    : 0   Median :2007   Median :52.93   Median : 10093310  
 Botswana    : 1   Europe  : 0   Mean   :2007   Mean   :54.81   Mean   : 17875763  
 Burkina Faso: 1   Oceania : 0   3rd Qu.:2007   3rd Qu.:59.44   3rd Qu.: 19363654  
 Burundi     : 1                 Max.   :2007   Max.   :76.44   Max.   :135031164  
 (Other)     :46                                                                   
   gdpPercap      
 Min.   :  277.6  
 1st Qu.:  863.0  
 Median : 1452.3  
 Mean   : 3089.0  
 3rd Qu.: 3993.5  
 Max.   :13206.5  
                  

Plot the relationship below. The plot represents the variation in life expectancy (within a single continent) in a single period in time. The level of health technology should be (approximately) the same across all points and so the plotted relationship is like a snapshot of the variation in life expectancy with income at that particular time and state of the world.

## Create a scatter plot of life expectancy and GDP per capita in 2007 for the continent of Africa.
ggplot(DF_2007, aes(x=gdpPercap, y=lifeExp, color=continent))+geom_point()

Now let’s look at life expectancy as a function of income for a single country at different periods of time.

# Load relevant data into data frame DF_country for a country of your choosing for all years of data.
DF_country<-filter(gapminder, country=="Japan")
summary(DF_country)
        country      continent       year         lifeExp           pop           
 Japan      :12   Africa  : 0   Min.   :1952   Min.   :63.03   Min.   : 86459025  
 Afghanistan: 0   Americas: 0   1st Qu.:1966   1st Qu.:70.75   1st Qu.: 99576898  
 Albania    : 0   Asia    :12   Median :1980   Median :76.25   Median :116163724  
 Algeria    : 0   Europe  : 0   Mean   :1980   Mean   :74.83   Mean   :111758808  
 Angola     : 0   Oceania : 0   3rd Qu.:1993   3rd Qu.:79.69   3rd Qu.:124736076  
 Argentina  : 0                 Max.   :2007   Max.   :82.60   Max.   :127467972  
 (Other)    : 0                                                                   
   gdpPercap    
 Min.   : 3217  
 1st Qu.: 9030  
 Median :17997  
 Mean   :17751  
 3rd Qu.:27270  
 Max.   :31656  
                

Plot the relationship below. The plot represents the evolution of life expectancy as the economy grows for one country, incorporating the social, political, and health contexts of that particular country, as well as changing health technology.

## Create a scatter plot of life expectancy and GDP per capita for the country of Japan.  
ggplot(DF_country, aes(x=gdpPercap, y=lifeExp, color=country))+geom_point()


To Do

To complete this assignment, answer the following questions. You can submit these results however you choose, but a simple option would be to modify this notebook to answer the questions above, execute the code, and hit “preview” in R Studio to create a html document that can be submitted with code and results.

  1. What is the median life expectancy in the world in 1952? In 2007?
DF_1952 <- filter(gapminder, year == 1952)
DF_2007 <- filter(gapminder, year == 2007)
med_1952_LF <- median(DF_1952$lifeExp)
med_2007_LF <- median(DF_2007$lifeExp)

The median life expectancy in the world in 1952 is 45.1355, and in 2007 is 71.9355.

  1. Choose one continent other than Africa. What is the median life expectancy in that continent in 1952 and 2007? Plot the life expectancy against GDP per capita for every country in that continent for the year 2007.
DF_1952_Asia <- filter(DF_1952, continent == "Asia")
DF_2007_Asia <- filter(DF_2007, continent == "Asia")
med_1952_Asia_LF <- median(DF_1952_Asia$lifeExp)
med_2007_Asia_LF <- median(DF_2007_Asia$lifeExp)

I chose Asia. The median life expectancy in Asia in 1952 is 44.869 and in 2007 is 72.396.

Then the life expectancy against GDP per capita for every country in Asia in 2007 is below.

ggplot(DF_2007_Asia, aes(x=gdpPercap, y=lifeExp, color=country))+geom_point()

  1. Choose a country other than Japan. Plot the life expectancy against GDP per capita from 1952 to 2007.

I chose Vietnam. Here is the plot of the life expectancty against GDP per caipta from 1952 to 2007 in Vietnam.

DF_Vietnam <- filter(gapminder, country == "Vietnam")
ggplot(DF_Vietnam, aes(x=gdpPercap, y=lifeExp, color=country))+geom_point()

  1. What is your experience with R? If you haven’t used R before, do you have experience with any other programming languages or statistical software (SPSS, SAS, Stata, etc.) or Excel?

I have taken some statistics courses and learned how to use R in those courses. So, I know fundamental knowledge about R and can write easy and unsophisticated code in R. In addition, I took some CS courses and learned Python, Java, and Matlab. However, I already forgot how to code in those languages.


LS0tCnRpdGxlOiAiRWNvbiA0NDggRmlyc3QgV2VlayBFeGVyY2lzZSIKYXV0aG9yOiAiTWVsaXNzYSBLbm94IgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCiMjIEdldHRpbmcgU3RhcnRlZCB3aXRoIFIKWW91IHdpbGwgZmFtaWxpYXJpemUgeW91cnNlbGYgd2l0aCB0aGUgUiBjb21wdXRpbmcgbGFuZ3VhZ2UsIFIgU3R1ZGlvIGVudmlyb25tZW50LCBhbmQgUiBNYXJrZG93biBsYW5ndWFnZS4gSWYgeW91IGFyZSBhbHJlYWR5IGZhbWlsaWFyIHdpdGggdGhlc2UsIHRoZW4gbHVja3kgeW91LCB5b3UgYXJlIGFoZWFkIG9mIG1lISBJZiBub3QsIHJlYWQgb24uCgpUaGVyZSBhcmUgdHdvIHdheXMgdG8gY29tcGxldGUgdGhpcyBwcm9qZWN0OiBEb3dubG9hZGluZyBhbmQgaW5zdGFsbGluZyBSIG9uIHlvdXIgb3duIG1hY2hpbmUgKG9yIHVzaW5nIGFuIGFscmVhZHkgaW5zdGFsbGVkIHZlcnNpb24gb2YgUiBvbiBhIGNhbXB1cyBjb21wdXRlciksIG9yIHJ1bm5pbmcgdGhpcyBub3RlYm9vayBpbiB0aGUgY2xvdWQgdmVyc2lvbiBvZiBSLiAgCgojIyMgSW5zdGFsbGluZyBSIG9uIFlvdXIgUGVyc29uYWwgTWFjaGluZQoqIERvd25sb2FkIFtSXShodHRwczovL2NyYW4uci1wcm9qZWN0Lm9yZy8pIGFuZCBbUlN0dWRpb10oaHR0cHM6Ly93d3cucnN0dWRpby5jb20vcHJvZHVjdHMvcnN0dWRpby9kb3dubG9hZC8pIChyZWNvbW1lbmRlZCBvdmVyIHVzaW5nIFIgYWxvbmUpCiogKFdpbmRvd3MpIEluc3RhbGwgW1J0b29sc10oaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvYmluL3dpbmRvd3MvUnRvb2xzLykuICBOb3RlIHRoYXQgdGhlcmUgYXJlIGluc3RydWN0aW9ucyBvbiB0aGlzIHBhZ2UgZm9yIGNyZWF0aW5nIGEgdGV4dCBmaWxlIGNhbGxlZCAuUmVudmlyb24gdGhhdCBpZGVudGlmaWVzIGEgcGF0aCBmb3IgUiB0byB1c2UgdG8gZmluZCBSdG9vbHMuICBJdCBzZWVtc2UgY29tcGxpY2F0ZWQsIGJ1dCBpcyBmYWlybHkgc3RyYWlnaHRmb3J3YXJkIGluIHByYWN0aWNlLgoKIyMjIFVzaW5nIFIgU3R1ZGlvIGluIHRoZSBDbG91ZCAtIFByZWZlcnJlZAoqIEkgaGF2ZSBzZXQgdXAgYSBKdXB5dGVyIE5vdGVib29rIGZvciB1c2UgaW4gdGhpcyBjbGFzcyB0byBtYWtlIGl0IHJlYWxseSBlYXN5IGZvciB5b3UgdG8gcnVuIHRoZXNlIHByb2dyYW1zIGluIGEgY2xvdWQgdmVyc2lvbiBvZiBSIFN0dWRpby4gIFRoZSBsaW5rIGlzIGluIHRoZSBjbGFzcyBuYXZpZ2F0aW9uIHBhbmUuICAKCiMjIFIgTWFya2Rvd24gYW5kIE5vdGVib29rcwpUaGlzIGlzIHRoZSBodG1sIGRvY3VtZW50IHByb2R1Y2VkIGJ5IGFuIFtSIE1hcmtkb3duXShodHRwOi8vcm1hcmtkb3duLnJzdHVkaW8uY29tKSBOb3RlYm9vay4gWW91IGNhbiBkb3dubG9hZCB0aGUgY29kZSB0byBydW4gaW4gUiBhYm92ZSAoQ29kZT5Eb3dubG9hZCBSbWQpLiBXaGVuIHlvdSBleGVjdXRlIGNvZGUgd2l0aGluIHRoZSBub3RlYm9vaywgdGhlIHJlc3VsdHMgYXBwZWFyIGJlbmVhdGggdGhlIGNvZGUuIFlvdSBjYW4gZG93bmxvYWQgdGhpcyBmaWxlLCBleHBlcmltZW50IHdpdGggaXQsIGFuZCBjaGFuZ2UgaXQgdG8gc3VpdCB5b3VyIG5lZWRzLiBXaGVuIHlvdSBhcmUgcmVhZHkgdG8gZmluYWxpemUgeW91ciByZXN1bHRzLCBtYWtlIHN1cmUgdGhhdCB5b3UgaGF2ZSBydW4gYWxsIG9mIHRoZSByZWxldmFudCBjaHVua3Mgb2YgY29kZSBhbmQgdGhlbiBjbGljayBwcmV2aWV3IChkbyBub3Qga25pdCEpIGFib3ZlIHRvIGNyZWF0ZSBhIGh0bWwgZG9jdW1lbnQgb2YgeW91ciBvd24gd2l0aCBjb2RlIGFuZCByZXN1bHRzIGluY2x1ZGVkLgoKVGhlIGdyZXkgYm94IGJlbG93IGlzIGNhbGxlZCBhIGNodW5rLiAgVHJ5IGV4ZWN1dGluZyB0aGlzIGNodW5rIGJ5IGNsaWNraW5nIHRoZSBncmVlbiBhcnJvdyBvbiB0aGUgZmFyIGxlZnQsIHRoZSAqUnVuKiBidXR0b24gd2l0aGluIHRoZSBjaHVuaywgb3IgYnkgcGxhY2luZyB5b3VyIGN1cnNvciBpbnNpZGUgaXQgYW5kIHByZXNzaW5nICpDdHJsK1NoaWZ0K0VudGVyKi4KCmBgYHtyfQojIyBUaGlzIGlzIGEgY29tbWVudCBhbmQgdGhlICMgdGVsbHMgUiBub3QgdG8gcmVhZCBpdC4gIFJ1biB0aGUgY29tbWFuZCBiZWxvdyB0byBwcmludCBvdXQgdGhlIG1lc3NhZ2UgIkhlbGxvIFdvcmxkLiIKcHJpbnQgKCJIZWxsbyBXb3JsZCIpCmBgYAoKT25jZSB5b3UndmUgaW5zdGFsbGVkIFJTdHVkaW8sIHlvdSBoYXZlIHRvIGluc3RhbGwgeW91ciBwYWNrYWdlcyAoYnV0IG9ubHkgZG8gdGhpcyBvbmNlKS4gT3BlbiBhIHNjcmlwdCAoRmlsZSA+IE5ldyBGaWxlID4gUiBTY3JpcHQpIGFuZCB0eXBlIHRoZSBjb21tYW5kcyBiZWxvdyAob3IgcnVuIHRoZW0gaW4gdGhlIG5vdGVib29rKS4KCklmIHlvdSB1c2UgdGhlIGNsYXNzIGp1cHl0ZXJodWIsIHlvdSBtYXkgbm90IG5lZWQgdG8gaW5zdGFsbCBhbnkgcGFja2FnZXMuCmBgYHtyfQojIyBSdW4gdGhpcyBjb2RlIGlmIHlvdSBoYXZlbid0IHJ1biBpdCBiZWZvcmUsIGJ1dCBvbmx5IG5lZWRzIHRvIGJlIHJ1biBvbmNlIGFmdGVyIHlvdSBoYXZlIGluc3RhbGxlZCBSLk5vdCBuZWVkZWQgaW4gSnVweXRlckh1Yi4KaWYgKCFyZXF1aXJlKCJwYWNtYW4iKSkgaW5zdGFsbC5wYWNrYWdlcygicGFjbWFuIikgI3BhY21hbiBpcyB0aGUgcGFja2FnZSB0aGF0IGluc3RhbGxzIHBhY2thZ2VzIG5pY2VseQpwYWNtYW46OnBfbG9hZChybWFya2Rvd24sIGRwbHlyLCBnYXBtaW5kZXIsIHRpZHl2ZXJzZSwgeG1sMiwgZ2dwbG90MiwgZHBseXIsIGxpZmVjeWNsZSkgI3RoZXNlIGFyZSB0aGUgcGFja2FnZXMgeW91IG1heSBuZWVkCmBgYAoKQWZ0ZXIgaW5zdGFsbGluZyB5b3VyIHBhY2thZ2VzLCB5b3UgbmVlZCB0byBsb2FkIHRoZSBvbmVzIHlvdSB3aWxsIGJlIHVzaW5nIGluIHlvdXIgcHJvZ3JhbSBldmVyeSB0aW1lLiAgCmBgYHtyLCB3YXJuaW5nPUZhbHNlfQojIyBPbmx5IG5lZWRzIHRvIGJlIHJ1biBvbmNlIHBlciBzZXNzaW9uLgpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoZ2FwbWluZGVyKQpsaWJyYXJ5KGRwbHlyKQpgYGAKCkhpbnQ6IFlvdSBjYW4gYWxzbyBpbmNsdWRlIHRoZSBjb21tYW5kcyBhYm92ZSBhdCB0aGUgc3RhcnQgb2YgYSBzY3JpcHQgaWYgeW91IGRlY2lkZSB0byBjcmVhdGUgYW5kIHJ1biB5b3VyIG93biBjb2RlLgoKIyMgSW50cm9kdWN0aW9uIHRvIERhdGEgV29yayBpbiBSCiAKYGBge3J9CiNCZWxvdywgeW91IGNhbiBwcmFjdGljZSBhIGNhbGN1bGF0aW9uIGluIFIuICBJZiB5b3UgcnVuIHRoZSBjb2RlIGJlbG93LCBSIHdpbGwgb3V0cHV0IHRoZSBzdW0uCjMrMQpgYGAKCmBgYHtyfQojQnV0IG1heWJlIHlvdSB3YW50IHRvIHBlcmZvcm0gYW4gb3BlcmF0aW9uIGFuZCBzYXZlIHRoZSByZXN1bHRzIGluIGEgdmFyaWFibGUgc28gdGhhdCB5b3UgY2FuIHVzZSB0aGVtIGxhdGVyIGluIG90aGVyIGNhbGN1bGF0aW9ucz8KI1RoaXMgY29kZSBzaG93cyB5b3UgaG93IHRvIGFzc2lnbiBhIHZhbHVlIHRvIGEgdmFyaWFibGUgeCB1c2luZyBhIGNhbGN1bGF0aW9uLCBhbmQgdGhlbiBwcmludHMgdGhlIHZhbHVlIG9mIHguCng8LTMrMQp4CmBgYAoKCmBgYHtyfQojSW4gZmFjdCwgUiB0aGlua3MgaW4gdmVjdG9ycyBhbmQgbWF0cmljZXMgd29ya3MgYmVzdCB3aGVuIHlvdSBhc3NpZ24gYSBidW5jaCBvZiB2YWx1ZXMgdG8gYSB2YXJpYWJsZS4gIAp4MTwtYygxLDIsMyw0KSAjVGhpcyBtYWtlcyBhIDEgZGltZW5zaW9uYWwgdmVjdG9yCngyPC1tYXRyaXgoYygxLDIsMyw0KSwgbnJvdz0yLCBuY29sPTIpICNUaGlzIG1ha2VzIGEgMngyIG1hdHJpeAp4MQp4MgpgYGAKWW91IGNhbiB0cnkgbW9kaWZ5aW5nIHRoZSBudW1iZXJzIGFib3ZlIHlvdXJzZWxmIGFuZCBtYWtpbmcgZGlmZmVyZW50IHNpemUgbWF0cmljZXMsIGV0Yy4KCiMjIERhdGEgRnJhbWVzCkRhdGEgZnJhbWVzIGFyZSBhIHVzZWZ1bCB3YXkgdGhhdCBSIG9yZ2FuaXplcyBkYXRhLiAgVGhlc2UgYXJlIGZsZXhpYmxlIHZlcnNpb25zIG9mIG1hdHJpY2VzIHRoYXQgaGF2ZSBzcGVjaWFsIHByb3BlcnRpZXMgdGhhdCBtYWtlIHRoZW0gZWFzeSB0byB3b3JrIHdpdGguICBMYXRlciwgeW91IHdpbGwgaW1wb3J0IHNvbWUgYWN0dWFsIGRhdGEgZnJvbSB0aGUgaW50ZXJuZXQgaW50byBhIGRhdGEgZnJhbWUsIGJ1dCBmb3Igbm93IHdlIHdpbGwgdXNlIHRoZSBnYXBtaW5kZXIgZGF0YSB0aGF0IGlzIGluY2x1ZGVkIGluIHRoZSBwYWNrYWdlIHlvdSBsb2FkZWQgZWFybGllci4gIAoKR2FwbWluZGVyIChnYXBtaW5kZXIub3JnKSBkYXRhIGlzIGRhdGEgb24gbGlmZSBleHBlY3RhbmN5IGFuZCBHRFAgYnkgY291bnRyeSBvdmVyIHRpbWUuICBJdCBjYW4gYmUgdXNlZCB0byBjYWxjdWxhdGUgUHJlc3RvbiBDdXJ2ZXMsIGFzIGRpc2N1c3NlZCBpbiBjbGFzcy4gIEZvciBub3csIGxldCdzIGp1c3QgcGVyZm9ybSBhIGZldyBvcGVyYXRpb25zIG9uIGl0LgoKYGBge3J9CiNTb21lIHF1aWNrIHN1bW1hcnkgc3RhdGlzdGljcwpzdW1tYXJ5KGdhcG1pbmRlcikKYGBgCgpgYGB7cn0KIyBMb2FkIHJlbGV2YW50IGRhdGEgaW50byBkYXRhIGZyYW1lIERGXzIwMDcgZm9yIHRoZSB5ZWFyIDIwMDcgYW5kIHRoZSBjb250aW5lbnQgb2YgQWZyaWNhLgojIyBXaGF0IGlzIHRoZSBtZWRpYW4gbGlmZSBleHBlY3RhbmN5IGluIHRoZSBjb250aW5lbnQgaW4gMjAwNz8KREY8LWRhdGEuZnJhbWUoZ2FwbWluZGVyKQpERl8yMDA3PC1maWx0ZXIoREYsIHllYXI9PTIwMDcgJiBjb250aW5lbnQ9PSJBZnJpY2EiKQpzdW1tYXJ5KERGXzIwMDcpCmBgYAoKUGxvdCB0aGUgcmVsYXRpb25zaGlwIGJlbG93LiAgVGhlIHBsb3QgcmVwcmVzZW50cyB0aGUgdmFyaWF0aW9uIGluIGxpZmUgZXhwZWN0YW5jeSAod2l0aGluIGEgc2luZ2xlIGNvbnRpbmVudCkgaW4gYSBzaW5nbGUgcGVyaW9kIGluIHRpbWUuICBUaGUgbGV2ZWwgb2YgaGVhbHRoIHRlY2hub2xvZ3kgc2hvdWxkIGJlIChhcHByb3hpbWF0ZWx5KSB0aGUgc2FtZSBhY3Jvc3MgYWxsIHBvaW50cyBhbmQgc28gdGhlIHBsb3R0ZWQgcmVsYXRpb25zaGlwIGlzIGxpa2UgYSBzbmFwc2hvdCBvZiB0aGUgdmFyaWF0aW9uIGluIGxpZmUgZXhwZWN0YW5jeSB3aXRoIGluY29tZSBhdCB0aGF0IHBhcnRpY3VsYXIgdGltZSBhbmQgc3RhdGUgb2YgdGhlIHdvcmxkLgpgYGB7cn0KIyMgQ3JlYXRlIGEgc2NhdHRlciBwbG90IG9mIGxpZmUgZXhwZWN0YW5jeSBhbmQgR0RQIHBlciBjYXBpdGEgaW4gMjAwNyBmb3IgdGhlIGNvbnRpbmVudCBvZiBBZnJpY2EuCmdncGxvdChERl8yMDA3LCBhZXMoeD1nZHBQZXJjYXAsIHk9bGlmZUV4cCwgY29sb3I9Y29udGluZW50KSkrZ2VvbV9wb2ludCgpCgpgYGAKCk5vdyBsZXQncyBsb29rIGF0IGxpZmUgZXhwZWN0YW5jeSBhcyBhIGZ1bmN0aW9uIG9mIGluY29tZSBmb3IgYSBzaW5nbGUgY291bnRyeSBhdCBkaWZmZXJlbnQgcGVyaW9kcyBvZiB0aW1lLiAgCmBgYHtyfQojIExvYWQgcmVsZXZhbnQgZGF0YSBpbnRvIGRhdGEgZnJhbWUgREZfY291bnRyeSBmb3IgYSBjb3VudHJ5IG9mIHlvdXIgY2hvb3NpbmcgZm9yIGFsbCB5ZWFycyBvZiBkYXRhLgpERl9jb3VudHJ5PC1maWx0ZXIoZ2FwbWluZGVyLCBjb3VudHJ5PT0iSmFwYW4iKQpzdW1tYXJ5KERGX2NvdW50cnkpCmBgYAoKUGxvdCB0aGUgcmVsYXRpb25zaGlwIGJlbG93LiAgVGhlIHBsb3QgcmVwcmVzZW50cyB0aGUgZXZvbHV0aW9uIG9mIGxpZmUgZXhwZWN0YW5jeSBhcyB0aGUgZWNvbm9teSBncm93cyBmb3Igb25lIGNvdW50cnksIGluY29ycG9yYXRpbmcgdGhlIHNvY2lhbCwgcG9saXRpY2FsLCBhbmQgaGVhbHRoIGNvbnRleHRzIG9mIHRoYXQgcGFydGljdWxhciBjb3VudHJ5LCBhcyB3ZWxsIGFzIGNoYW5naW5nIGhlYWx0aCB0ZWNobm9sb2d5LgpgYGB7cn0KIyMgQ3JlYXRlIGEgc2NhdHRlciBwbG90IG9mIGxpZmUgZXhwZWN0YW5jeSBhbmQgR0RQIHBlciBjYXBpdGEgZm9yIHRoZSBjb3VudHJ5IG9mIEphcGFuLiAgCmdncGxvdChERl9jb3VudHJ5LCBhZXMoeD1nZHBQZXJjYXAsIHk9bGlmZUV4cCwgY29sb3I9Y291bnRyeSkpK2dlb21fcG9pbnQoKQpgYGAKKioqKgojIyBUbyBEbwpUbyBjb21wbGV0ZSB0aGlzIGFzc2lnbm1lbnQsIGFuc3dlciB0aGUgZm9sbG93aW5nIHF1ZXN0aW9ucy4gWW91IGNhbiBzdWJtaXQgdGhlc2UgcmVzdWx0cyBob3dldmVyIHlvdSBjaG9vc2UsIGJ1dCBhIHNpbXBsZSBvcHRpb24gd291bGQgYmUgdG8gbW9kaWZ5IHRoaXMgbm90ZWJvb2sgdG8gYW5zd2VyIHRoZSBxdWVzdGlvbnMgYWJvdmUsIGV4ZWN1dGUgdGhlIGNvZGUsIGFuZCBoaXQgInByZXZpZXciIGluIFIgU3R1ZGlvIHRvIGNyZWF0ZSBhIGh0bWwgZG9jdW1lbnQgdGhhdCBjYW4gYmUgc3VibWl0dGVkIHdpdGggY29kZSBhbmQgcmVzdWx0cy4KCjEuIFdoYXQgaXMgdGhlIG1lZGlhbiBsaWZlIGV4cGVjdGFuY3kgaW4gdGhlIHdvcmxkIGluIDE5NTI/IEluIDIwMDc/CmBgYHtyfQpERl8xOTUyIDwtIGZpbHRlcihnYXBtaW5kZXIsIHllYXIgPT0gMTk1MikKREZfMjAwNyA8LSBmaWx0ZXIoZ2FwbWluZGVyLCB5ZWFyID09IDIwMDcpCm1lZF8xOTUyX0xGIDwtIG1lZGlhbihERl8xOTUyJGxpZmVFeHApCm1lZF8yMDA3X0xGIDwtIG1lZGlhbihERl8yMDA3JGxpZmVFeHApCmBgYApUaGUgbWVkaWFuIGxpZmUgZXhwZWN0YW5jeSBpbiB0aGUgd29ybGQgaW4gMTk1MiBpcyBgciBtZWRfMTk1Ml9MRmAsIGFuZCBpbiAyMDA3IGlzIGByIG1lZF8yMDA3X0xGYC4KCjIuIENob29zZSBvbmUgY29udGluZW50IG90aGVyIHRoYW4gQWZyaWNhLiAgV2hhdCBpcyB0aGUgbWVkaWFuIGxpZmUgZXhwZWN0YW5jeSBpbiB0aGF0IGNvbnRpbmVudCBpbiAxOTUyIGFuZCAyMDA3PyBQbG90IHRoZSBsaWZlIGV4cGVjdGFuY3kgYWdhaW5zdCBHRFAgcGVyIGNhcGl0YSBmb3IgZXZlcnkgY291bnRyeSBpbiB0aGF0IGNvbnRpbmVudCBmb3IgdGhlIHllYXIgMjAwNy4KYGBge3J9CkRGXzE5NTJfQXNpYSA8LSBmaWx0ZXIoREZfMTk1MiwgY29udGluZW50ID09ICJBc2lhIikKREZfMjAwN19Bc2lhIDwtIGZpbHRlcihERl8yMDA3LCBjb250aW5lbnQgPT0gIkFzaWEiKQptZWRfMTk1Ml9Bc2lhX0xGIDwtIG1lZGlhbihERl8xOTUyX0FzaWEkbGlmZUV4cCkKbWVkXzIwMDdfQXNpYV9MRiA8LSBtZWRpYW4oREZfMjAwN19Bc2lhJGxpZmVFeHApCmBgYApJIGNob3NlIEFzaWEuIApUaGUgbWVkaWFuIGxpZmUgZXhwZWN0YW5jeSBpbiBBc2lhIGluIDE5NTIgaXMgYHIgbWVkXzE5NTJfQXNpYV9MRmAgYW5kIGluIDIwMDcgaXMgYHIgbWVkXzIwMDdfQXNpYV9MRmAuCgpUaGVuIHRoZSBsaWZlIGV4cGVjdGFuY3kgYWdhaW5zdCBHRFAgcGVyIGNhcGl0YSBmb3IgZXZlcnkgY291bnRyeSBpbiBBc2lhIGluIDIwMDcgaXMgYmVsb3cuCmBgYHtyfQpnZ3Bsb3QoREZfMjAwN19Bc2lhLCBhZXMoeD1nZHBQZXJjYXAsIHk9bGlmZUV4cCwgY29sb3I9Y291bnRyeSkpK2dlb21fcG9pbnQoKQpgYGAKCgozLiBDaG9vc2UgYSBjb3VudHJ5IG90aGVyIHRoYW4gSmFwYW4uICBQbG90IHRoZSBsaWZlIGV4cGVjdGFuY3kgYWdhaW5zdCBHRFAgcGVyIGNhcGl0YSBmcm9tIDE5NTIgdG8gMjAwNy4KCkkgY2hvc2UgVmlldG5hbS4gSGVyZSBpcyB0aGUgcGxvdCBvZiB0aGUgbGlmZSBleHBlY3RhbmN0eSBhZ2FpbnN0IEdEUCBwZXIgY2FpcHRhIGZyb20gMTk1MiB0byAyMDA3IGluIFZpZXRuYW0uCgpgYGB7cn0KREZfVmlldG5hbSA8LSBmaWx0ZXIoZ2FwbWluZGVyLCBjb3VudHJ5ID09ICJWaWV0bmFtIikKZ2dwbG90KERGX1ZpZXRuYW0sIGFlcyh4PWdkcFBlcmNhcCwgeT1saWZlRXhwLCBjb2xvcj1jb3VudHJ5KSkrZ2VvbV9wb2ludCgpCmBgYAoKCjQuIFdoYXQgaXMgeW91ciBleHBlcmllbmNlIHdpdGggUj8gSWYgeW91IGhhdmVuJ3QgdXNlZCBSIGJlZm9yZSwgZG8geW91IGhhdmUgZXhwZXJpZW5jZSB3aXRoIGFueSBvdGhlciBwcm9ncmFtbWluZyBsYW5ndWFnZXMgb3Igc3RhdGlzdGljYWwgc29mdHdhcmUgKFNQU1MsIFNBUywgU3RhdGEsIGV0Yy4pIG9yIEV4Y2VsPwoKSSBoYXZlIHRha2VuIHNvbWUgc3RhdGlzdGljcyBjb3Vyc2VzIGFuZCBsZWFybmVkIGhvdyB0byB1c2UgUiBpbiB0aG9zZSBjb3Vyc2VzLiBTbywgSSBrbm93IGZ1bmRhbWVudGFsIGtub3dsZWRnZSBhYm91dCBSIGFuZCBjYW4gd3JpdGUgZWFzeSBhbmQgdW5zb3BoaXN0aWNhdGVkIGNvZGUgaW4gUi4gSW4gYWRkaXRpb24sIEkgdG9vayBzb21lIENTIGNvdXJzZXMgYW5kIGxlYXJuZWQgUHl0aG9uLCBKYXZhLCBhbmQgTWF0bGFiLiBIb3dldmVyLCBJIGFscmVhZHkgZm9yZ290IGhvdyB0byBjb2RlIGluIHRob3NlIGxhbmd1YWdlcy4gCgoqKioqCg==