knitr::opts_chunk$set(
 echo = TRUE,
 message = FALSE,
 warning = FALSE
)

Module 1: Getting Started with R

This module will cover: - Introduction to R and RStudio - Basic R operations and syntax - Working with different types of data (vectors and data frames) - Simple calculations in R - Installing and using R packages - Creating R Notebooks for reproducible research

What is R?

R is a powerful programming language designed specifically for statistical computing and data visualization. It’s:

  • Free and open-source
  • Has extensive package support (18,000+ packages)
  • Strong community, especially in research
  • Excellent for data analysis and visualization
  • Works on all major platforms

Why R for Education Research?

  • Reproducible research (literate programming)
  • Compartmentalize work (e.g., accessing data, preparing data, reporting)
  • Publication-quality reporting
  • Handles large datasets efficiently
  • Integrates with other tools (PowerBI, Alchemer, databases)
  • Active community

Let’s start with a simple command:

print("Hello Education Researchers!")
[1] "Hello Education Researchers!"

The RStudio Interface

RStudio is distinct from the language R. Both need to be installed on your computer. R alone can only run scripts or provide a very simple command line interface. RStudio provides a modern software environment to complete all of your analytics work.

RStudio has four main panes: 1. Source Editor (top left) - where we write our code 2. Console (bottom left) - where code runs and we see output 3. Environment/History (top right) - shows what data is currently loaded 4. Files/Plots/Help (bottom right) - for file management, viewing plots, and getting help

R Projects in RStudio

Think of an R Project like a folder that keeps all your work organized. Just like you might have different folders for different work tasks, R Projects help you keep your R work tidy and in one place.

To create a new project: 1. Click File > New Project 2. Choose “New Directory” 3. Select “New Project” 4. Pick a name and where to save it -something like “R Workshop” 5. Click “Create Project”

Your new project folder will store: - The R work we do today - Any data files we use - Settings specific to this project

When you open your project later: - RStudio remembers where all your files are - Opens the files you were working on - Keeps everything together

Let’s create a new project now to store the work we’ll do in this workshop.

Basic R Operations

R as a Calculator

5 + 3
[1] 8
10 / 2
[1] 5
3 * 4
[1] 12
2^3  # Exponents (2 raised to power of 3)
[1] 8

Basic R Syntax

Let’s start with the simplest possible R commands:

# This line is a comment - R ignores anything after #
2 + 2    # Basic math works just like a calculator
[1] 4
# We can save values by giving them names (no spaces allowed in names!)
my_number <- 5
another_number <- 10

# Now we can use those names in calculations
my_number + another_number
[1] 15
# We can save the result too
total <- my_number + another_number
total    # Type the name to see what's stored in it
[1] 15
# Multiple values can be combined into a list called a "vector" in R
numbers <- c(8, 9, 15)  # The c() function combines values

# Functions take inputs inside round brackets
mean(numbers)  # Calculates the average
[1] 10.66667
# Functions can be used inside other functions
round(mean(numbers)) # First calculates mean, then rounds the result
[1] 11

A few important things to remember: - R is case sensitive (“Number” and “number” are different) - Use <- to save values (this is called “assignment”) - Type a variable name to see what’s stored in it - Functions always use round brackets () - Use # for comments that R will ignore

Don’t worry if you make mistakes! Everyone does when learning R. We’ll practice these basics together.

Creating and Working with Vectors

Vectors are how R stores data in its most basic form. In social sciences, we might call what they contain variables. A vector is a list of one type of data - it could be numbers (like student grades), text (like student names), or TRUE/FALSE values (like whether a student passed).

# Different types of vectors
# Numeric (decimal numbers of any precision)
scores <- c(75, 82.3, 90.01, 68.7, 95.2)
print(scores)  # Fixed variable name from test_scores to scores
[1] 75.00 82.30 90.01 68.70 95.20
# Character (text)
student_names <- c("Alice", "Bob", "Charlie", "David", "Emma")
print(student_names)
[1] "Alice"   "Bob"     "Charlie" "David"   "Emma"   
# Logical (TRUE/FALSE)
passed_course <- c(TRUE, TRUE, FALSE, TRUE, FALSE)
print(passed_course)
[1]  TRUE  TRUE FALSE  TRUE FALSE
# Factor (categorical data - like grade levels)
grade_levels <- factor(c("9", "10th", "9th", "10th", "9th"))
print(grade_levels)
[1] 9    10th 9th  10th 9th 
Levels: 10th 9 9th
length(levels(grade_levels)) # Shows we have 3 different categories! Why?
[1] 3
summary(grade_levels)        # Shows how many students in each category
10th    9  9th 
   2    1    2 

With numeric data, we can calculate various statistics:

# Basic statistics
mean(scores)    # Average
[1] 82.242
median(scores)  # Middle value
[1] 82.3
sd(scores)      # Standard deviation
[1] 10.77134
min(scores)     # Minimum
[1] 68.7
max(scores)     # Maximum
[1] 95.2
quantile(scores)  # Quartiles (0%, 25%, 50%, 75%, 100%)
   0%   25%   50%   75%  100% 
68.70 75.00 82.30 90.01 95.20 
quantile(scores, probs = c(.1, .9))  # 10th and 90th percentiles
   10%    90% 
71.220 93.124 
IQR(scores)     # Interquartile range (75th - 25th percentile)
[1] 15.01

Working with Different Types of Data: The Data Frame

A data frame combines multiple vectors of the same length. Think of it like a spreadsheet table where each column can contain a different type of data.

# Numeric data
math_scores <- c(85, 92, 78, 95, 88)

# Character data (text)
student_names <- c("Alice", "Bob", "Charlie", "David", "Emma")

# Logical data (TRUE/FALSE)
passed <- math_scores >= 80  # Creates TRUE for scores 80 or above

# Create a data frame
student_data <- data.frame(
  student_names,
  math_scores,
  passed
)

# View the data
student_data

# Access a single column (variable)
student_data$math_scores
[1] 85 92 78 95 88
# Alternative way to access a column
student_data[["math_scores"]]
[1] 85 92 78 95 88
# You can also click on "student_data" in the environment pane to view it

Note: While column names in a data frame can include spaces, it’s best to avoid them as they make your code more complicated.

The Pipe Operator

The pipe operator (|> or %>%) makes code easier to read by passing data through a sequence of operations. Think of it as saying “then”:

# Without pipe
mean(scores)
[1] 82.242
# With pipe: "Start with scores THEN calculate the mean"
scores |> mean()
[1] 82.242

You may see both |> and %>% online - they work similarly. We’ll use |> as it’s built into R.

Exercise: Try the Pipe

# Create some test data
test_scores <- c(65, 72, 88, 95, 78, 84)

# Use the pipe to:
# 1. Start with test_scores THEN
# 2. Calculate the average with mean() THEN
# 3. Round to whole numbers with round()

Later, this pipe workflow will help us make complex, step-by-step changes to data frames in a way that’s easier to write and understand.

R Libraries and Packages

R’s power comes from its extensive ecosystem of packages. These packages add new tools and capabilities to R.

Installing Packages

The simplest way to install packages is through the “Tools” menu in RStudio.

All packages are available from CRAN (Comprehensive R Archive Network). You can browse packages at https://cran.r-project.org/web/packages/ or search for specific tasks at https://rseek.org/.

Packages can also be installed using code:

# Install a single package
install.packages("dplyr")

# Install multiple packages at once (uncomment to run)
#install.packages(c("dplyr", "ggplot2", "tidyr"))

You only need to install a package once, but you need to load it each time you start R. It’s helpful to keep installation commands (commented out) at the start of your project files.

Loading Packages

After installation, packages must be loaded to use them. Load only what you need for your current project to keep R running efficiently.

The dplyr package is particularly useful for working with data:

# Load dplyr
library(dplyr)

Throughout this course, we’ll use dplyr functions like summarize(), filter(), and rename(). If these don’t work, make sure you’ve loaded dplyr with the library() command above.

Creating Your First R Notebook

An R Notebook combines: - Text explanations (in Markdown format) - R code (in special code sections) - Output (tables, plots, statistics)

To create code sections (called “chunks”): - Click the “Insert” button or press Ctrl+Alt+I - Type your R code between the ``` marks - Run code with the green “play” button or Ctrl+Shift+Enter

Try creating a notebook: 1. Click File > New File > R Notebook 2. Save the example notebook that opens 3. Click Preview to see how it looks

Things to try: [] Change the output format to PDF or Word [] Add section headers and see how they appear in the preview [] Create and run a new code chunk

Common Mistakes to Watch Out For

Case Sensitivity

# These are different variables
score <- 85
SCORE <- 95
print(score)  # Shows 85
[1] 85
# This would cause an error because Score (capital S) doesn't exist
# print(Score)

Assignment vs. Equality Testing

# Use <- for assignment (storing values)
x <- 10

# Use == to test if things are equal
x == 10  # Returns TRUE
[1] TRUE
x = 10   # This works but <- is preferred in R

Getting Help

# Add # for comments that R ignores
# Use help() or ? to get documentation
?mean
help(mean)

Different Coding Styles

There are often several ways to do the same thing in R. Here are three ways to find students with math scores over 80:

# Base R style using subset()
subset(student_data, math_scores > 80)

# Base R with brackets
student_data[student_data$math_scores > 80,]

# Modern tidyverse style
library(dplyr)
student_data |>
  filter(math_scores > 80)

save.image()

All three give the same result. The tidyverse style is often easier to read and understand.

Exercise

Create your own notebook and try these basic operations:

  1. Create a vector of 10 test scores
  2. Calculate the mean and standard deviation
  3. Create a data frame with student names and scores
  4. Use summary() to explore your data
# Your code here:
# scores <- c(85, 92, 78, 88, 95, 82, 90, 85, 89, 91)

Practice Time

Let’s review what we’ve covered so far:

  • We learned about R and RStudio:
    • R is a powerful programming language for statistics and data
    • RStudio provides a user-friendly environment with helpful features
    • Projects help keep our work organized
  • We practiced basic R operations:
    • Using R as a calculator
    • Creating variables with <-
    • Building vectors with c()
    • Working with different data types (numbers, text, TRUE/FALSE)
    • Creating data frames to organize multiple variables
    • Installing and loading packages
    • Using the pipe operator |>
  • We started working with R Notebooks:
    • Combining text, code, and output
    • Creating code chunks
    • Running code and seeing results
    • Adding explanatory text
  • We learned about common pitfalls:
    • R is case sensitive
    • Different ways to write the same operation
    • How to get help when stuck

Now let’s put these skills into practice!

Take 10 minutes to:

  • Explore the RStudio interface:
    • Environment pane (where your data lives)
    • Console pane (where you can type commands)
    • Source Pane (where you write your code)
      • Try the Outline button
      • Use the Preview button
      • Practice with the Run button
  • Create and run your own code chunks
  • Try some basic R commands
  • Ask questions - we’re here to help!
LS0tCnRpdGxlOiAiTW9kdWxlIDE6IEludHJvZHVjdGlvbiB0byBSIGFuZCBCYXNpYyBTdGF0aXN0aWNzIgphdXRob3I6ICJKYXNvbiBMb2NrbGluIgpkYXRlOiAiTm92ZW1iZXIgMTIsIDIwMjQiCm91dHB1dDoKICBodG1sX25vdGVib29rOgogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6IHRydWUKICAgIHRoZW1lOiB1bml0ZWQKICAgIGhpZ2hsaWdodDogdGFuZ28KZWRpdG9yX29wdGlvbnM6CiAgbWFya2Rvd246CiAgICB3cmFwOiA3MgotLS0KCmBgYHtyIHNldHVwfQprbml0cjo6b3B0c19jaHVuayRzZXQoCiBlY2hvID0gVFJVRSwKIG1lc3NhZ2UgPSBGQUxTRSwKIHdhcm5pbmcgPSBGQUxTRQopCmBgYAojIE1vZHVsZSAxOiBHZXR0aW5nIFN0YXJ0ZWQgd2l0aCBSCgpUaGlzIG1vZHVsZSB3aWxsIGNvdmVyOgotIEludHJvZHVjdGlvbiB0byBSIGFuZCBSU3R1ZGlvCi0gQmFzaWMgUiBvcGVyYXRpb25zIGFuZCBzeW50YXgKLSBXb3JraW5nIHdpdGggZGlmZmVyZW50IHR5cGVzIG9mIGRhdGEgKHZlY3RvcnMgYW5kIGRhdGEgZnJhbWVzKQotIFNpbXBsZSBjYWxjdWxhdGlvbnMgaW4gUgotIEluc3RhbGxpbmcgYW5kIHVzaW5nIFIgcGFja2FnZXMKLSBDcmVhdGluZyBSIE5vdGVib29rcyBmb3IgcmVwcm9kdWNpYmxlIHJlc2VhcmNoCgojIyBXaGF0IGlzIFI/CgpSIGlzIGEgcG93ZXJmdWwgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2UgZGVzaWduZWQgc3BlY2lmaWNhbGx5IGZvciBzdGF0aXN0aWNhbCBjb21wdXRpbmcgYW5kIGRhdGEgdmlzdWFsaXphdGlvbi4gSXQnczoKCi0gRnJlZSBhbmQgb3Blbi1zb3VyY2UKLSBIYXMgZXh0ZW5zaXZlIHBhY2thZ2Ugc3VwcG9ydCAoMTgsMDAwKyBwYWNrYWdlcykKLSBTdHJvbmcgY29tbXVuaXR5LCBlc3BlY2lhbGx5IGluIHJlc2VhcmNoCi0gRXhjZWxsZW50IGZvciBkYXRhIGFuYWx5c2lzIGFuZCB2aXN1YWxpemF0aW9uCi0gV29ya3Mgb24gYWxsIG1ham9yIHBsYXRmb3JtcwoKIyMjIFdoeSBSIGZvciBFZHVjYXRpb24gUmVzZWFyY2g/CgotIFJlcHJvZHVjaWJsZSByZXNlYXJjaCAobGl0ZXJhdGUgcHJvZ3JhbW1pbmcpCi0gQ29tcGFydG1lbnRhbGl6ZSB3b3JrIChlLmcuLCBhY2Nlc3NpbmcgZGF0YSwgcHJlcGFyaW5nIGRhdGEsIHJlcG9ydGluZykKLSBQdWJsaWNhdGlvbi1xdWFsaXR5IHJlcG9ydGluZwotIEhhbmRsZXMgbGFyZ2UgZGF0YXNldHMgZWZmaWNpZW50bHkKLSBJbnRlZ3JhdGVzIHdpdGggb3RoZXIgdG9vbHMgKFBvd2VyQkksIEFsY2hlbWVyLCBkYXRhYmFzZXMpCi0gQWN0aXZlIGNvbW11bml0eQoKTGV0J3Mgc3RhcnQgd2l0aCBhIHNpbXBsZSBjb21tYW5kOgoKYGBge3J9CnByaW50KCJIZWxsbyBFZHVjYXRpb24gUmVzZWFyY2hlcnMhIikKYGBgCgojIyBUaGUgUlN0dWRpbyBJbnRlcmZhY2UKClJTdHVkaW8gaXMgZGlzdGluY3QgZnJvbSB0aGUgbGFuZ3VhZ2UgUi4gQm90aCBuZWVkIHRvIGJlIGluc3RhbGxlZCBvbiB5b3VyIGNvbXB1dGVyLiBSIGFsb25lIGNhbiBvbmx5IHJ1biBzY3JpcHRzIG9yIHByb3ZpZGUgYSB2ZXJ5IHNpbXBsZSBjb21tYW5kIGxpbmUgaW50ZXJmYWNlLiBSU3R1ZGlvIHByb3ZpZGVzIGEgbW9kZXJuIHNvZnR3YXJlIGVudmlyb25tZW50IHRvIGNvbXBsZXRlIGFsbCBvZiB5b3VyIGFuYWx5dGljcyB3b3JrLgoKUlN0dWRpbyBoYXMgZm91ciBtYWluIHBhbmVzOgoxLiBTb3VyY2UgRWRpdG9yICh0b3AgbGVmdCkgLSB3aGVyZSB3ZSB3cml0ZSBvdXIgY29kZQoyLiBDb25zb2xlIChib3R0b20gbGVmdCkgLSB3aGVyZSBjb2RlIHJ1bnMgYW5kIHdlIHNlZSBvdXRwdXQKMy4gRW52aXJvbm1lbnQvSGlzdG9yeSAodG9wIHJpZ2h0KSAtIHNob3dzIHdoYXQgZGF0YSBpcyBjdXJyZW50bHkgbG9hZGVkCjQuIEZpbGVzL1Bsb3RzL0hlbHAgKGJvdHRvbSByaWdodCkgLSBmb3IgZmlsZSBtYW5hZ2VtZW50LCB2aWV3aW5nIHBsb3RzLCBhbmQgZ2V0dGluZyBoZWxwCgojIyBSIFByb2plY3RzIGluIFJTdHVkaW8KClRoaW5rIG9mIGFuIFIgUHJvamVjdCBsaWtlIGEgZm9sZGVyIHRoYXQga2VlcHMgYWxsIHlvdXIgd29yayBvcmdhbml6ZWQuIEp1c3QgbGlrZSB5b3UgbWlnaHQgaGF2ZSBkaWZmZXJlbnQgZm9sZGVycyBmb3IgZGlmZmVyZW50IHdvcmsgdGFza3MsIFIgUHJvamVjdHMgaGVscCB5b3Uga2VlcCB5b3VyIFIgd29yayB0aWR5IGFuZCBpbiBvbmUgcGxhY2UuCgpUbyBjcmVhdGUgYSBuZXcgcHJvamVjdDoKMS4gQ2xpY2sgRmlsZSA+IE5ldyBQcm9qZWN0CjIuIENob29zZSAiTmV3IERpcmVjdG9yeSIKMy4gU2VsZWN0ICJOZXcgUHJvamVjdCIKNC4gUGljayBhIG5hbWUgYW5kIHdoZXJlIHRvIHNhdmUgaXQgLXNvbWV0aGluZyBsaWtlICJSIFdvcmtzaG9wIgo1LiBDbGljayAiQ3JlYXRlIFByb2plY3QiCgpZb3VyIG5ldyBwcm9qZWN0IGZvbGRlciB3aWxsIHN0b3JlOgotIFRoZSBSIHdvcmsgd2UgZG8gdG9kYXkKLSBBbnkgZGF0YSBmaWxlcyB3ZSB1c2UKLSBTZXR0aW5ncyBzcGVjaWZpYyB0byB0aGlzIHByb2plY3QKCldoZW4geW91IG9wZW4geW91ciBwcm9qZWN0IGxhdGVyOgotIFJTdHVkaW8gcmVtZW1iZXJzIHdoZXJlIGFsbCB5b3VyIGZpbGVzIGFyZQotIE9wZW5zIHRoZSBmaWxlcyB5b3Ugd2VyZSB3b3JraW5nIG9uCi0gS2VlcHMgZXZlcnl0aGluZyB0b2dldGhlcgoKCkxldCdzIGNyZWF0ZSBhIG5ldyBwcm9qZWN0IG5vdyB0byBzdG9yZSB0aGUgd29yayB3ZSdsbCBkbyBpbiB0aGlzIHdvcmtzaG9wLgoKCiMjIEJhc2ljIFIgT3BlcmF0aW9ucwoKIyMjIFIgYXMgYSBDYWxjdWxhdG9yCgpgYGB7cn0KNSArIDMKMTAgLyAyCjMgKiA0CjJeMyAgIyBFeHBvbmVudHMgKDIgcmFpc2VkIHRvIHBvd2VyIG9mIDMpCmBgYAoKIyMjIEJhc2ljIFIgU3ludGF4CgpMZXQncyBzdGFydCB3aXRoIHRoZSBzaW1wbGVzdCBwb3NzaWJsZSBSIGNvbW1hbmRzOgoKYGBge3J9CiMgVGhpcyBsaW5lIGlzIGEgY29tbWVudCAtIFIgaWdub3JlcyBhbnl0aGluZyBhZnRlciAjCjIgKyAyICAgICMgQmFzaWMgbWF0aCB3b3JrcyBqdXN0IGxpa2UgYSBjYWxjdWxhdG9yCgojIFdlIGNhbiBzYXZlIHZhbHVlcyBieSBnaXZpbmcgdGhlbSBuYW1lcyAobm8gc3BhY2VzIGFsbG93ZWQgaW4gbmFtZXMhKQpteV9udW1iZXIgPC0gNQphbm90aGVyX251bWJlciA8LSAxMAoKIyBOb3cgd2UgY2FuIHVzZSB0aG9zZSBuYW1lcyBpbiBjYWxjdWxhdGlvbnMKbXlfbnVtYmVyICsgYW5vdGhlcl9udW1iZXIKCiMgV2UgY2FuIHNhdmUgdGhlIHJlc3VsdCB0b28KdG90YWwgPC0gbXlfbnVtYmVyICsgYW5vdGhlcl9udW1iZXIKdG90YWwgICAgIyBUeXBlIHRoZSBuYW1lIHRvIHNlZSB3aGF0J3Mgc3RvcmVkIGluIGl0CgojIE11bHRpcGxlIHZhbHVlcyBjYW4gYmUgY29tYmluZWQgaW50byBhIGxpc3QgY2FsbGVkIGEgInZlY3RvciIgaW4gUgpudW1iZXJzIDwtIGMoOCwgOSwgMTUpICAjIFRoZSBjKCkgZnVuY3Rpb24gY29tYmluZXMgdmFsdWVzCgojIEZ1bmN0aW9ucyB0YWtlIGlucHV0cyBpbnNpZGUgcm91bmQgYnJhY2tldHMKbWVhbihudW1iZXJzKSAgIyBDYWxjdWxhdGVzIHRoZSBhdmVyYWdlCgojIEZ1bmN0aW9ucyBjYW4gYmUgdXNlZCBpbnNpZGUgb3RoZXIgZnVuY3Rpb25zCnJvdW5kKG1lYW4obnVtYmVycykpICMgRmlyc3QgY2FsY3VsYXRlcyBtZWFuLCB0aGVuIHJvdW5kcyB0aGUgcmVzdWx0CmBgYAoKQSBmZXcgaW1wb3J0YW50IHRoaW5ncyB0byByZW1lbWJlcjoKLSBSIGlzIGNhc2Ugc2Vuc2l0aXZlICgiTnVtYmVyIiBhbmQgIm51bWJlciIgYXJlIGRpZmZlcmVudCkKLSBVc2UgPC0gdG8gc2F2ZSB2YWx1ZXMgKHRoaXMgaXMgY2FsbGVkICJhc3NpZ25tZW50IikKLSBUeXBlIGEgdmFyaWFibGUgbmFtZSB0byBzZWUgd2hhdCdzIHN0b3JlZCBpbiBpdAotIEZ1bmN0aW9ucyBhbHdheXMgdXNlIHJvdW5kIGJyYWNrZXRzICgpCi0gVXNlICMgZm9yIGNvbW1lbnRzIHRoYXQgUiB3aWxsIGlnbm9yZQoKRG9uJ3Qgd29ycnkgaWYgeW91IG1ha2UgbWlzdGFrZXMhIEV2ZXJ5b25lIGRvZXMgd2hlbiBsZWFybmluZyBSLiBXZSdsbCBwcmFjdGljZSB0aGVzZSBiYXNpY3MgdG9nZXRoZXIuCgojIyMgQ3JlYXRpbmcgYW5kIFdvcmtpbmcgd2l0aCBWZWN0b3JzCgpWZWN0b3JzIGFyZSBob3cgUiBzdG9yZXMgZGF0YSBpbiBpdHMgbW9zdCBiYXNpYyBmb3JtLiBJbiBzb2NpYWwgc2NpZW5jZXMsIHdlIG1pZ2h0IGNhbGwgd2hhdCB0aGV5IGNvbnRhaW4gdmFyaWFibGVzLiBBIHZlY3RvciBpcyBhIGxpc3Qgb2Ygb25lIHR5cGUgb2YgZGF0YSAtIGl0IGNvdWxkIGJlIG51bWJlcnMgKGxpa2Ugc3R1ZGVudCBncmFkZXMpLCB0ZXh0IChsaWtlIHN0dWRlbnQgbmFtZXMpLCBvciBUUlVFL0ZBTFNFIHZhbHVlcyAobGlrZSB3aGV0aGVyIGEgc3R1ZGVudCBwYXNzZWQpLgoKYGBge3J9CiMgRGlmZmVyZW50IHR5cGVzIG9mIHZlY3RvcnMKIyBOdW1lcmljIChkZWNpbWFsIG51bWJlcnMgb2YgYW55IHByZWNpc2lvbikKc2NvcmVzIDwtIGMoNzUsIDgyLjMsIDkwLjAxLCA2OC43LCA5NS4yKQpwcmludChzY29yZXMpICAjIEZpeGVkIHZhcmlhYmxlIG5hbWUgZnJvbSB0ZXN0X3Njb3JlcyB0byBzY29yZXMKCiMgQ2hhcmFjdGVyICh0ZXh0KQpzdHVkZW50X25hbWVzIDwtIGMoIkFsaWNlIiwgIkJvYiIsICJDaGFybGllIiwgIkRhdmlkIiwgIkVtbWEiKQpwcmludChzdHVkZW50X25hbWVzKQoKIyBMb2dpY2FsIChUUlVFL0ZBTFNFKQpwYXNzZWRfY291cnNlIDwtIGMoVFJVRSwgVFJVRSwgRkFMU0UsIFRSVUUsIEZBTFNFKQpwcmludChwYXNzZWRfY291cnNlKQoKIyBGYWN0b3IgKGNhdGVnb3JpY2FsIGRhdGEgLSBsaWtlIGdyYWRlIGxldmVscykKZ3JhZGVfbGV2ZWxzIDwtIGZhY3RvcihjKCI5IiwgIjEwdGgiLCAiOXRoIiwgIjEwdGgiLCAiOXRoIikpCnByaW50KGdyYWRlX2xldmVscykKbGVuZ3RoKGxldmVscyhncmFkZV9sZXZlbHMpKSAjIFNob3dzIHdlIGhhdmUgMyBkaWZmZXJlbnQgY2F0ZWdvcmllcyEgV2h5PwpzdW1tYXJ5KGdyYWRlX2xldmVscykgICAgICAgICMgU2hvd3MgaG93IG1hbnkgc3R1ZGVudHMgaW4gZWFjaCBjYXRlZ29yeQpgYGAKCldpdGggbnVtZXJpYyBkYXRhLCB3ZSBjYW4gY2FsY3VsYXRlIHZhcmlvdXMgc3RhdGlzdGljczoKYGBge3J9CiMgQmFzaWMgc3RhdGlzdGljcwptZWFuKHNjb3JlcykgICAgIyBBdmVyYWdlCm1lZGlhbihzY29yZXMpICAjIE1pZGRsZSB2YWx1ZQpzZChzY29yZXMpICAgICAgIyBTdGFuZGFyZCBkZXZpYXRpb24KbWluKHNjb3JlcykgICAgICMgTWluaW11bQptYXgoc2NvcmVzKSAgICAgIyBNYXhpbXVtCnF1YW50aWxlKHNjb3JlcykgICMgUXVhcnRpbGVzICgwJSwgMjUlLCA1MCUsIDc1JSwgMTAwJSkKcXVhbnRpbGUoc2NvcmVzLCBwcm9icyA9IGMoLjEsIC45KSkgICMgMTB0aCBhbmQgOTB0aCBwZXJjZW50aWxlcwpJUVIoc2NvcmVzKSAgICAgIyBJbnRlcnF1YXJ0aWxlIHJhbmdlICg3NXRoIC0gMjV0aCBwZXJjZW50aWxlKQpgYGAKCiMjIyBXb3JraW5nIHdpdGggRGlmZmVyZW50IFR5cGVzIG9mIERhdGE6IFRoZSBEYXRhIEZyYW1lCgpBIGRhdGEgZnJhbWUgY29tYmluZXMgbXVsdGlwbGUgdmVjdG9ycyBvZiB0aGUgc2FtZSBsZW5ndGguIFRoaW5rIG9mIGl0IGxpa2UgYSBzcHJlYWRzaGVldCB0YWJsZSB3aGVyZSBlYWNoIGNvbHVtbiBjYW4gY29udGFpbiBhIGRpZmZlcmVudCB0eXBlIG9mIGRhdGEuCgpgYGB7cn0KIyBOdW1lcmljIGRhdGEKbWF0aF9zY29yZXMgPC0gYyg4NSwgOTIsIDc4LCA5NSwgODgpCgojIENoYXJhY3RlciBkYXRhICh0ZXh0KQpzdHVkZW50X25hbWVzIDwtIGMoIkFsaWNlIiwgIkJvYiIsICJDaGFybGllIiwgIkRhdmlkIiwgIkVtbWEiKQoKIyBMb2dpY2FsIGRhdGEgKFRSVUUvRkFMU0UpCnBhc3NlZCA8LSBtYXRoX3Njb3JlcyA+PSA4MCAgIyBDcmVhdGVzIFRSVUUgZm9yIHNjb3JlcyA4MCBvciBhYm92ZQoKIyBDcmVhdGUgYSBkYXRhIGZyYW1lCnN0dWRlbnRfZGF0YSA8LSBkYXRhLmZyYW1lKAogIHN0dWRlbnRfbmFtZXMsCiAgbWF0aF9zY29yZXMsCiAgcGFzc2VkCikKCiMgVmlldyB0aGUgZGF0YQpzdHVkZW50X2RhdGEKCiMgQWNjZXNzIGEgc2luZ2xlIGNvbHVtbiAodmFyaWFibGUpCnN0dWRlbnRfZGF0YSRtYXRoX3Njb3JlcwoKIyBBbHRlcm5hdGl2ZSB3YXkgdG8gYWNjZXNzIGEgY29sdW1uCnN0dWRlbnRfZGF0YVtbIm1hdGhfc2NvcmVzIl1dCgojIFlvdSBjYW4gYWxzbyBjbGljayBvbiAic3R1ZGVudF9kYXRhIiBpbiB0aGUgZW52aXJvbm1lbnQgcGFuZSB0byB2aWV3IGl0CmBgYAoKTm90ZTogV2hpbGUgY29sdW1uIG5hbWVzIGluIGEgZGF0YSBmcmFtZSBjYW4gaW5jbHVkZSBzcGFjZXMsIGl0J3MgYmVzdCB0byBhdm9pZCB0aGVtIGFzIHRoZXkgbWFrZSB5b3VyIGNvZGUgbW9yZSBjb21wbGljYXRlZC4KCiMjIFRoZSBQaXBlIE9wZXJhdG9yCgpUaGUgcGlwZSBvcGVyYXRvciAoYHw+YCBvciBgJT4lYCkgbWFrZXMgY29kZSBlYXNpZXIgdG8gcmVhZCBieSBwYXNzaW5nIGRhdGEgdGhyb3VnaCBhIHNlcXVlbmNlIG9mIG9wZXJhdGlvbnMuIFRoaW5rIG9mIGl0IGFzIHNheWluZyAidGhlbiI6CgpgYGB7cn0KIyBXaXRob3V0IHBpcGUKbWVhbihzY29yZXMpCgojIFdpdGggcGlwZTogIlN0YXJ0IHdpdGggc2NvcmVzIFRIRU4gY2FsY3VsYXRlIHRoZSBtZWFuIgpzY29yZXMgfD4gbWVhbigpCmBgYAoKWW91IG1heSBzZWUgYm90aCBgfD5gIGFuZCBgJT4lYCBvbmxpbmUgLSB0aGV5IHdvcmsgc2ltaWxhcmx5LiBXZSdsbCB1c2UgYHw+YCBhcyBpdCdzIGJ1aWx0IGludG8gUi4KCiMjIyBFeGVyY2lzZTogVHJ5IHRoZSBQaXBlCgpgYGB7cn0KIyBDcmVhdGUgc29tZSB0ZXN0IGRhdGEKdGVzdF9zY29yZXMgPC0gYyg2NSwgNzIsIDg4LCA5NSwgNzgsIDg0KQoKIyBVc2UgdGhlIHBpcGUgdG86CiMgMS4gU3RhcnQgd2l0aCB0ZXN0X3Njb3JlcyBUSEVOCiMgMi4gQ2FsY3VsYXRlIHRoZSBhdmVyYWdlIHdpdGggbWVhbigpIFRIRU4KIyAzLiBSb3VuZCB0byB3aG9sZSBudW1iZXJzIHdpdGggcm91bmQoKQoKCmBgYAoKTGF0ZXIsIHRoaXMgcGlwZSB3b3JrZmxvdyB3aWxsIGhlbHAgdXMgbWFrZSBjb21wbGV4LCBzdGVwLWJ5LXN0ZXAgY2hhbmdlcyB0byBkYXRhIGZyYW1lcyBpbiBhIHdheSB0aGF0J3MgZWFzaWVyIHRvIHdyaXRlIGFuZCB1bmRlcnN0YW5kLgoKIyMgUiBMaWJyYXJpZXMgYW5kIFBhY2thZ2VzCgpSJ3MgcG93ZXIgY29tZXMgZnJvbSBpdHMgZXh0ZW5zaXZlIGVjb3N5c3RlbSBvZiBwYWNrYWdlcy4gVGhlc2UgcGFja2FnZXMgYWRkIG5ldyB0b29scyBhbmQgY2FwYWJpbGl0aWVzIHRvIFIuCgojIyMgSW5zdGFsbGluZyBQYWNrYWdlcwoKVGhlIHNpbXBsZXN0IHdheSB0byBpbnN0YWxsIHBhY2thZ2VzIGlzIHRocm91Z2ggdGhlICJUb29scyIgbWVudSBpbiBSU3R1ZGlvLgoKQWxsIHBhY2thZ2VzIGFyZSBhdmFpbGFibGUgZnJvbSBDUkFOIChDb21wcmVoZW5zaXZlIFIgQXJjaGl2ZSBOZXR3b3JrKS4gWW91IGNhbiBicm93c2UgcGFja2FnZXMgYXQgaHR0cHM6Ly9jcmFuLnItcHJvamVjdC5vcmcvd2ViL3BhY2thZ2VzLyBvciBzZWFyY2ggZm9yIHNwZWNpZmljIHRhc2tzIGF0IGh0dHBzOi8vcnNlZWsub3JnLy4KClBhY2thZ2VzIGNhbiBhbHNvIGJlIGluc3RhbGxlZCB1c2luZyBjb2RlOgoKYGBge3IgZXZhbD1GQUxTRX0KIyBJbnN0YWxsIGEgc2luZ2xlIHBhY2thZ2UKaW5zdGFsbC5wYWNrYWdlcygiZHBseXIiKQoKIyBJbnN0YWxsIG11bHRpcGxlIHBhY2thZ2VzIGF0IG9uY2UgKHVuY29tbWVudCB0byBydW4pCiNpbnN0YWxsLnBhY2thZ2VzKGMoImRwbHlyIiwgImdncGxvdDIiLCAidGlkeXIiKSkKYGBgCgpZb3Ugb25seSBuZWVkIHRvIGluc3RhbGwgYSBwYWNrYWdlIG9uY2UsIGJ1dCB5b3UgbmVlZCB0byBsb2FkIGl0IGVhY2ggdGltZSB5b3Ugc3RhcnQgUi4gSXQncyBoZWxwZnVsIHRvIGtlZXAgaW5zdGFsbGF0aW9uIGNvbW1hbmRzIChjb21tZW50ZWQgb3V0KSBhdCB0aGUgc3RhcnQgb2YgeW91ciBwcm9qZWN0IGZpbGVzLgoKIyMjIExvYWRpbmcgUGFja2FnZXMKCkFmdGVyIGluc3RhbGxhdGlvbiwgcGFja2FnZXMgbXVzdCBiZSBsb2FkZWQgdG8gdXNlIHRoZW0uIExvYWQgb25seSB3aGF0IHlvdSBuZWVkIGZvciB5b3VyIGN1cnJlbnQgcHJvamVjdCB0byBrZWVwIFIgcnVubmluZyBlZmZpY2llbnRseS4KClRoZSBgZHBseXJgIHBhY2thZ2UgaXMgcGFydGljdWxhcmx5IHVzZWZ1bCBmb3Igd29ya2luZyB3aXRoIGRhdGE6CgpgYGB7cn0KIyBMb2FkIGRwbHlyCmxpYnJhcnkoZHBseXIpCmBgYAoKVGhyb3VnaG91dCB0aGlzIGNvdXJzZSwgd2UnbGwgdXNlIGRwbHlyIGZ1bmN0aW9ucyBsaWtlIGBzdW1tYXJpemUoKWAsIGBmaWx0ZXIoKWAsIGFuZCBgcmVuYW1lKClgLiBJZiB0aGVzZSBkb24ndCB3b3JrLCBtYWtlIHN1cmUgeW91J3ZlIGxvYWRlZCBkcGx5ciB3aXRoIHRoZSBgbGlicmFyeSgpYCBjb21tYW5kIGFib3ZlLgoKIyMgQ3JlYXRpbmcgWW91ciBGaXJzdCBSIE5vdGVib29rCgpBbiBSIE5vdGVib29rIGNvbWJpbmVzOgotIFRleHQgZXhwbGFuYXRpb25zIChpbiBNYXJrZG93biBmb3JtYXQpCi0gUiBjb2RlIChpbiBzcGVjaWFsIGNvZGUgc2VjdGlvbnMpCi0gT3V0cHV0ICh0YWJsZXMsIHBsb3RzLCBzdGF0aXN0aWNzKQoKVG8gY3JlYXRlIGNvZGUgc2VjdGlvbnMgKGNhbGxlZCAiY2h1bmtzIik6Ci0gQ2xpY2sgdGhlICJJbnNlcnQiIGJ1dHRvbiBvciBwcmVzcyBDdHJsK0FsdCtJCi0gVHlwZSB5b3VyIFIgY29kZSBiZXR3ZWVuIHRoZSBgYGAgbWFya3MKLSBSdW4gY29kZSB3aXRoIHRoZSBncmVlbiAicGxheSIgYnV0dG9uIG9yIEN0cmwrU2hpZnQrRW50ZXIKClRyeSBjcmVhdGluZyBhIG5vdGVib29rOgoxLiBDbGljayBGaWxlID4gTmV3IEZpbGUgPiBSIE5vdGVib29rCjIuIFNhdmUgdGhlIGV4YW1wbGUgbm90ZWJvb2sgdGhhdCBvcGVucwozLiBDbGljayBQcmV2aWV3IHRvIHNlZSBob3cgaXQgbG9va3MKClRoaW5ncyB0byB0cnk6CltdIENoYW5nZSB0aGUgb3V0cHV0IGZvcm1hdCB0byBQREYgb3IgV29yZApbXSBBZGQgc2VjdGlvbiBoZWFkZXJzIGFuZCBzZWUgaG93IHRoZXkgYXBwZWFyIGluIHRoZSBwcmV2aWV3CltdIENyZWF0ZSBhbmQgcnVuIGEgbmV3IGNvZGUgY2h1bmsKCiMjIENvbW1vbiBNaXN0YWtlcyB0byBXYXRjaCBPdXQgRm9yCgojIyMgQ2FzZSBTZW5zaXRpdml0eQpgYGB7cn0KIyBUaGVzZSBhcmUgZGlmZmVyZW50IHZhcmlhYmxlcwpzY29yZSA8LSA4NQpTQ09SRSA8LSA5NQpwcmludChzY29yZSkgICMgU2hvd3MgODUKCiMgVGhpcyB3b3VsZCBjYXVzZSBhbiBlcnJvciBiZWNhdXNlIFNjb3JlIChjYXBpdGFsIFMpIGRvZXNuJ3QgZXhpc3QKIyBwcmludChTY29yZSkKYGBgCgojIyMgQXNzaWdubWVudCB2cy4gRXF1YWxpdHkgVGVzdGluZwpgYGB7cn0KIyBVc2UgPC0gZm9yIGFzc2lnbm1lbnQgKHN0b3JpbmcgdmFsdWVzKQp4IDwtIDEwCgojIFVzZSA9PSB0byB0ZXN0IGlmIHRoaW5ncyBhcmUgZXF1YWwKeCA9PSAxMCAgIyBSZXR1cm5zIFRSVUUKCnggPSAxMCAgICMgVGhpcyB3b3JrcyBidXQgPC0gaXMgcHJlZmVycmVkIGluIFIKYGBgCgojIyMgR2V0dGluZyBIZWxwCmBgYHtyfQojIEFkZCAjIGZvciBjb21tZW50cyB0aGF0IFIgaWdub3JlcwojIFVzZSBoZWxwKCkgb3IgPyB0byBnZXQgZG9jdW1lbnRhdGlvbgo/bWVhbgpoZWxwKG1lYW4pCmBgYAoKIyMjIERpZmZlcmVudCBDb2RpbmcgU3R5bGVzClRoZXJlIGFyZSBvZnRlbiBzZXZlcmFsIHdheXMgdG8gZG8gdGhlIHNhbWUgdGhpbmcgaW4gUi4gSGVyZSBhcmUgdGhyZWUgd2F5cyB0byBmaW5kIHN0dWRlbnRzIHdpdGggbWF0aCBzY29yZXMgb3ZlciA4MDoKCmBgYHtyfQojIEJhc2UgUiBzdHlsZSB1c2luZyBzdWJzZXQoKQpzdWJzZXQoc3R1ZGVudF9kYXRhLCBtYXRoX3Njb3JlcyA+IDgwKQoKIyBCYXNlIFIgd2l0aCBicmFja2V0cwpzdHVkZW50X2RhdGFbc3R1ZGVudF9kYXRhJG1hdGhfc2NvcmVzID4gODAsXQoKIyBNb2Rlcm4gdGlkeXZlcnNlIHN0eWxlCmxpYnJhcnkoZHBseXIpCnN0dWRlbnRfZGF0YSB8PgogIGZpbHRlcihtYXRoX3Njb3JlcyA+IDgwKQoKc2F2ZS5pbWFnZSgpCmBgYAoKQWxsIHRocmVlIGdpdmUgdGhlIHNhbWUgcmVzdWx0LiBUaGUgdGlkeXZlcnNlIHN0eWxlIGlzIG9mdGVuIGVhc2llciB0byByZWFkIGFuZCB1bmRlcnN0YW5kLgoKIyMgRXhlcmNpc2UKCkNyZWF0ZSB5b3VyIG93biBub3RlYm9vayBhbmQgdHJ5IHRoZXNlIGJhc2ljIG9wZXJhdGlvbnM6CgoxLiBDcmVhdGUgYSB2ZWN0b3Igb2YgMTAgdGVzdCBzY29yZXMKMi4gQ2FsY3VsYXRlIHRoZSBtZWFuIGFuZCBzdGFuZGFyZCBkZXZpYXRpb24KMy4gQ3JlYXRlIGEgZGF0YSBmcmFtZSB3aXRoIHN0dWRlbnQgbmFtZXMgYW5kIHNjb3Jlcwo0LiBVc2Ugc3VtbWFyeSgpIHRvIGV4cGxvcmUgeW91ciBkYXRhCgpgYGB7cn0KIyBZb3VyIGNvZGUgaGVyZToKIyBzY29yZXMgPC0gYyg4NSwgOTIsIDc4LCA4OCwgOTUsIDgyLCA5MCwgODUsIDg5LCA5MSkKYGBgCgojIyBQcmFjdGljZSBUaW1lCgpMZXQncyByZXZpZXcgd2hhdCB3ZSd2ZSBjb3ZlcmVkIHNvIGZhcjoKCi0gV2UgbGVhcm5lZCBhYm91dCBSIGFuZCBSU3R1ZGlvOgogICAgLSBSIGlzIGEgcG93ZXJmdWwgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2UgZm9yIHN0YXRpc3RpY3MgYW5kIGRhdGEKICAgIC0gUlN0dWRpbyBwcm92aWRlcyBhIHVzZXItZnJpZW5kbHkgZW52aXJvbm1lbnQgd2l0aCBoZWxwZnVsIGZlYXR1cmVzCiAgICAtIFByb2plY3RzIGhlbHAga2VlcCBvdXIgd29yayBvcmdhbml6ZWQKCi0gV2UgcHJhY3RpY2VkIGJhc2ljIFIgb3BlcmF0aW9uczoKICAgIC0gVXNpbmcgUiBhcyBhIGNhbGN1bGF0b3IKICAgIC0gQ3JlYXRpbmcgdmFyaWFibGVzIHdpdGggPC0KICAgIC0gQnVpbGRpbmcgdmVjdG9ycyB3aXRoIGMoKQogICAgLSBXb3JraW5nIHdpdGggZGlmZmVyZW50IGRhdGEgdHlwZXMgKG51bWJlcnMsIHRleHQsIFRSVUUvRkFMU0UpCiAgICAtIENyZWF0aW5nIGRhdGEgZnJhbWVzIHRvIG9yZ2FuaXplIG11bHRpcGxlIHZhcmlhYmxlcwogICAgLSBJbnN0YWxsaW5nIGFuZCBsb2FkaW5nIHBhY2thZ2VzCiAgICAtIFVzaW5nIHRoZSBwaXBlIG9wZXJhdG9yIHw+CgotIFdlIHN0YXJ0ZWQgd29ya2luZyB3aXRoIFIgTm90ZWJvb2tzOgogICAgLSBDb21iaW5pbmcgdGV4dCwgY29kZSwgYW5kIG91dHB1dAogICAgLSBDcmVhdGluZyBjb2RlIGNodW5rcwogICAgLSBSdW5uaW5nIGNvZGUgYW5kIHNlZWluZyByZXN1bHRzCiAgICAtIEFkZGluZyBleHBsYW5hdG9yeSB0ZXh0CgotIFdlIGxlYXJuZWQgYWJvdXQgY29tbW9uIHBpdGZhbGxzOgogICAgLSBSIGlzIGNhc2Ugc2Vuc2l0aXZlCiAgICAtIERpZmZlcmVudCB3YXlzIHRvIHdyaXRlIHRoZSBzYW1lIG9wZXJhdGlvbgogICAgLSBIb3cgdG8gZ2V0IGhlbHAgd2hlbiBzdHVjawoKTm93IGxldCdzIHB1dCB0aGVzZSBza2lsbHMgaW50byBwcmFjdGljZSEKCgpUYWtlIDEwIG1pbnV0ZXMgdG86CgotIEV4cGxvcmUgdGhlIFJTdHVkaW8gaW50ZXJmYWNlOgogICAgLSBFbnZpcm9ubWVudCBwYW5lICh3aGVyZSB5b3VyIGRhdGEgbGl2ZXMpCiAgICAtIENvbnNvbGUgcGFuZSAod2hlcmUgeW91IGNhbiB0eXBlIGNvbW1hbmRzKQogICAgLSBTb3VyY2UgUGFuZSAod2hlcmUgeW91IHdyaXRlIHlvdXIgY29kZSkKICAgICAgICAtIFRyeSB0aGUgT3V0bGluZSBidXR0b24KICAgICAgICAtIFVzZSB0aGUgUHJldmlldyBidXR0b24KICAgICAgICAtIFByYWN0aWNlIHdpdGggdGhlIFJ1biBidXR0b24KLSBDcmVhdGUgYW5kIHJ1biB5b3VyIG93biBjb2RlIGNodW5rcwotIFRyeSBzb21lIGJhc2ljIFIgY29tbWFuZHMKLSBBc2sgcXVlc3Rpb25zIC0gd2UncmUgaGVyZSB0byBoZWxwIQo=