Introduction:

In this lab we will learn:

Part 1: Summary statistics

Exercise 1: Load the mouse.csv file (found on Canvas) in the code chunk below, call the data frame “mouse”:

mouse <- read.csv('~/Desktop/BIN510-files/mouse.csv')

The mouse dataset looks at how individual mice develop certain types of cancer based on treatments. The primary numerical variable is days until cancer appears.

Often, we work with data where we don’t necessarily know each column/variable or the types they are, we can write code to help provide insight into how these sets look.

str(mouse)
'data.frame':   181 obs. of  5 variables:
 $ rownames: int  1 2 3 4 5 6 7 8 9 10 ...
 $ trt     : chr  "Control" "Control" "Control" "Control" ...
 $ days    : int  159 189 191 198 200 207 220 235 245 250 ...
 $ outcome : chr  "thymic lymphoma" "thymic lymphoma" "thymic lymphoma" "thymic lymphoma" ...
 $ id      : int  1 2 3 4 5 6 7 8 9 10 ...

R also has many other built in tools to explore data, here are some examples:

Size: dim() - returns a vector with the number of rows in the first element, and the number of columns as the second element (the dimensions of the object) nrow() - returns the number of rows ncol() - returns the number of columns

Content: head() - shows the first 6 rows tail() - shows the last 6 rows

Names: names() - returns the column names (synonym of colnames() for data.frame objects) rownames() - returns the row names

Summary: str() - structure of the object and information about the class, length and content of each column summary() - summary statistics for each column

Exercise 1: for the mouse dataset, please use the code chunk below to use code and determine the following:

How many rows are in this dataset? How many columns are in this dataset? What type of variable is “trt”? What is the mean of the “days” column?

nrow(mouse)
[1] 181
ncol(mouse)
[1] 5
str(mouse$trt)
 chr [1:181] "Control" "Control" "Control" "Control" "Control" "Control" "Control" "Control" ...
mean(mouse$days)
[1] 514.768

Basic built-in functions in R also allow for calculating specific summary statistics: mean() - calculates the mean of a numerical/integer column median() - calculates the median of a numerical/integer column sd() - calculates the standard deviation of a numerical/integer column

Exercise 2:please use the code chunk below to use code and determine the following:

What is the median of the “days” column? What is the sd of the “days” column?

median(mouse$days)
[1] 554
sd(mouse$days)
[1] 232.6566

While calculating the mean of a column is useful, we often want to determine how summary statistics differ among variables or groups. We can create code that calculates the mean of a numerical variable by specific categorical variables using the tapply() code:

tapply(mouse$days, mouse$outcome, mean)
                 other reticulum cell sarcoma        thymic lymphoma 
              565.7792               631.1321               316.8235 

QUESTION: how would you describe what the code above does? Answer below:

The code above shows the means of days for each of the outcomes (other, reticulum, and thymic.)

Exercise 3: using the code chunk below, use the tapply() code to calculate the following:

What is the mean of the “days” column by the “trt” column? What is the sd of the “days” column by the “trt” column?

tapply(mouse$days, mouse$trt, mean)
  Control Germ-free 
  456.596   585.000 
tapply(mouse$days, mouse$trt, sd)
  Control Germ-free 
 195.9897  254.3301 

We can take tapply() a step further, what if we wanted to break up summary statistics by more than one group?? For this we would use the aggregate() code:

aggregate(mouse$days, by = list(mouse$outcome, mouse$trt), mean) 

NOTE: you can swap in other functions if needed

QUESTION: what do you notice about the output of the aggregate code? Answer below:

I noticed that the output table has both the means for outcome and trt based on days.

Exercise 4: can you turn the aggregate output into a new dataframe with new column names? HINT: step 1 would be give a variable name to the aggregate code (kind of like we do for the read.table() codes…)

newmouse <- aggregate(mouse$days, by = list(mouse$outcome, mouse$trt), mean) 

Why do we want to do this? We often need means and standard deviations to create certain types of plots, having these stored in their own dataframe makes this easy!

Quick visuals

R can also quickly generate visualizations using commands like hist(), boxplot(), and plot(). We will explore these, as well as more statistical summaries, over the next two weeks. For now, let’s try to develop an intuition via examples

Exercise 4:

For each code chunk below, run the code and look at the output. Try to explain how the code works in your own words, as well as what the code generates.

hist(mouse$days,col='red')


Answer:

This code creates a histogram based on the number of mice that survived a certain number of days. ****

boxplot(days~ trt, data = mouse, col='blue')

boxplot(days~ trt, data = mouse, col=c('blue', "green"))


Answer:

This code creates a boxplot comparing the number of days for each of the treatment types; control (blue), and Germ-free (green).This can show if treatments effect how long the mice survived. ****

plot(days ~ id, data = mouse, col='black',
     main="Days by ID")

plot(days ~ id, data = mouse, pch = 4, col='black',
     main="Days by ID")


Answer:

The first code is used to show how long each mouse (by id) survived. The second code just changes the circles into an X. ****

Exercise 5: create a boxplot for “days” by “outcome”, this plot should include the following

unique colors for each outcome a plot title

boxplot(days~outcome,
        data= mouse,
        col= c("pink","turquoise", "skyblue"),
        main= "Number of Days by Outcome",
        xlab="Outcome",
        ylab="Days")

Exercise 6: looking at summaries of categorical variables

We previously looked at the mean, median, and standard deviation of the numerical “days” variable, but other variables are still of interest to researchers, such as cancer type or “outcome”, we can’t however, calculate means of categories, so instead let’s look at some other summary information we can obtain…

The code chunk below shows how we can extract a table of counts/frequencies for cancer outcomes:

table(mouse$outcome)

                 other reticulum cell sarcoma        thymic lymphoma 
                    77                     53                     51 

One common practice in biological statistics is to standardize values (usually done by creating percentages), this allows us to better make comparisons between groups or data. In order for us to take the counts that are output in the code above and turn them into percentages or proportions, we need to divide by the total number of cases, in this case, that’s the total number of rows in the dataset.

The code below does the following: it creates and stores a variable to represent the total number of rows, then it divides our table counts by that value - what gets output is the proportion.

n <- length(mouse$outcome)
table(mouse$outcome)/n

                 other reticulum cell sarcoma        thymic lymphoma 
             0.4254144              0.2928177              0.2817680 

CHALLENGE: create a code that calculates the PERCENT of each cancer type - use the code chunk below:

prop.table(table(mouse$outcome)) * 100

                 other reticulum cell sarcoma        thymic lymphoma 
              42.54144               29.28177               28.17680 

Exercise 7: parsing out counts/frequencies by another variable

Above we used the tapply() and aggregate() codes to calculate means by different groups or variables, what if we wanted to do the same for our categorical variable “outcome”?

The code below creates a table of “outcome” by “trt”, this will allow us to see if there seems to be certain cancer types more associated with certain treatments

cancer_developed<-table(mouse$outcome,
                           mouse$trt)
cancer_developed
                        
                         Control Germ-free
  other                       39        38
  reticulum cell sarcoma      38        15
  thymic lymphoma             22        29

What patterns do you notice from the table that gets outputted by the code?


Answer:I noticed that for “other” and “thymic lymphoma” categories there werea close number of mice in both outcome groups. There was a major difference between the control and germ-free numbers with the “reticulum cell sarcoma”. It seemed like the reticulum was more common in the control group.


PLEASE CONVERT THIS TO AN HTML FILE AND UPLOAD IT TO CANVAS!

LS0tCnRpdGxlOiAiQklONTEwX0xhYjIiCnN1YnRpdGxlOiBTdW1tYXJ5IHN0YXRpc3RpY3MgYW5kIGJhc2ljIHZpc3VhbGl6YXRpb25zCm91dHB1dDoKICBodG1sX25vdGVib29rOiBkZWZhdWx0CiAgaHRtbF9kb2N1bWVudDoKICAgIGRmX3ByaW50OiBwYWdlZAogIHBkZl9kb2N1bWVudDogZGVmYXVsdAotLS0KCiMjIEludHJvZHVjdGlvbjoKSW4gdGhpcyBsYWIgd2Ugd2lsbCBsZWFybjoKCiogaG93IHRvIGNvbXB1dGUgYW5kIGludGVycHJldCBzdW1tYXJ5IHN0YXRpc3RpY3MKKiBob3cgdG8gY3JlYXRlIGJhc2ljIHZpc3VhbHMvZ3JhcGhzICAKCiMjIFBhcnQgMTogU3VtbWFyeSBzdGF0aXN0aWNzCgpFeGVyY2lzZSAxOiBMb2FkIHRoZSBtb3VzZS5jc3YgZmlsZSAoZm91bmQgb24gQ2FudmFzKSBpbiB0aGUgY29kZSBjaHVuayBiZWxvdywgY2FsbCB0aGUgZGF0YSBmcmFtZSAibW91c2UiOgoKYGBge3J9Cm1vdXNlIDwtIHJlYWQuY3N2KCd+L0Rlc2t0b3AvQklONTEwLWZpbGVzL21vdXNlLmNzdicpCmBgYApUaGUgbW91c2UgZGF0YXNldCBsb29rcyBhdCBob3cgaW5kaXZpZHVhbCBtaWNlIGRldmVsb3AgY2VydGFpbiB0eXBlcyBvZiBjYW5jZXIgYmFzZWQgb24gdHJlYXRtZW50cy4gVGhlIHByaW1hcnkgbnVtZXJpY2FsIHZhcmlhYmxlIGlzIGRheXMgdW50aWwgY2FuY2VyIGFwcGVhcnMuCgpPZnRlbiwgd2Ugd29yayB3aXRoIGRhdGEgd2hlcmUgd2UgZG9uJ3QgbmVjZXNzYXJpbHkga25vdyBlYWNoIGNvbHVtbi92YXJpYWJsZSBvciB0aGUgdHlwZXMgdGhleSBhcmUsIHdlIGNhbiB3cml0ZSBjb2RlIHRvIGhlbHAgcHJvdmlkZSBpbnNpZ2h0IGludG8gaG93IHRoZXNlIHNldHMgbG9vay4KYGBge3J9CnN0cihtb3VzZSkKYGBgCgpSIGFsc28gaGFzIG1hbnkgb3RoZXIgYnVpbHQgaW4gdG9vbHMgdG8gZXhwbG9yZSBkYXRhLCBoZXJlIGFyZSBzb21lIGV4YW1wbGVzOgoKU2l6ZToKZGltKCkgLSByZXR1cm5zIGEgdmVjdG9yIHdpdGggdGhlIG51bWJlciBvZiByb3dzIGluIHRoZSBmaXJzdCBlbGVtZW50LCBhbmQgdGhlIG51bWJlciBvZiBjb2x1bW5zIGFzIHRoZSBzZWNvbmQgZWxlbWVudCAodGhlIGRpbWVuc2lvbnMgb2YgdGhlIG9iamVjdCkKbnJvdygpIC0gcmV0dXJucyB0aGUgbnVtYmVyIG9mIHJvd3MKbmNvbCgpIC0gcmV0dXJucyB0aGUgbnVtYmVyIG9mIGNvbHVtbnMKCkNvbnRlbnQ6CmhlYWQoKSAtIHNob3dzIHRoZSBmaXJzdCA2IHJvd3MKdGFpbCgpIC0gc2hvd3MgdGhlIGxhc3QgNiByb3dzCgpOYW1lczoKbmFtZXMoKSAtIHJldHVybnMgdGhlIGNvbHVtbiBuYW1lcyAoc3lub255bSBvZiBjb2xuYW1lcygpIGZvciBkYXRhLmZyYW1lIG9iamVjdHMpCnJvd25hbWVzKCkgLSByZXR1cm5zIHRoZSByb3cgbmFtZXMKClN1bW1hcnk6CnN0cigpIC0gc3RydWN0dXJlIG9mIHRoZSBvYmplY3QgYW5kIGluZm9ybWF0aW9uIGFib3V0IHRoZSBjbGFzcywgbGVuZ3RoIGFuZCBjb250ZW50IG9mIGVhY2ggY29sdW1uCnN1bW1hcnkoKSAtIHN1bW1hcnkgc3RhdGlzdGljcyBmb3IgZWFjaCBjb2x1bW4KCiMjIEV4ZXJjaXNlIDE6IGZvciB0aGUgbW91c2UgZGF0YXNldCwgcGxlYXNlIHVzZSB0aGUgY29kZSBjaHVuayBiZWxvdyB0byB1c2UgY29kZSBhbmQgZGV0ZXJtaW5lIHRoZSBmb2xsb3dpbmc6CipIb3cgbWFueSByb3dzIGFyZSBpbiB0aGlzIGRhdGFzZXQ/CipIb3cgbWFueSBjb2x1bW5zIGFyZSBpbiB0aGlzIGRhdGFzZXQ/CipXaGF0IHR5cGUgb2YgdmFyaWFibGUgaXMgInRydCI/CipXaGF0IGlzIHRoZSBtZWFuIG9mIHRoZSAiZGF5cyIgY29sdW1uPwoKYGBge3J9Cm5yb3cobW91c2UpCm5jb2wobW91c2UpCnN0cihtb3VzZSR0cnQpCm1lYW4obW91c2UkZGF5cykKYGBgCgpCYXNpYyBidWlsdC1pbiBmdW5jdGlvbnMgaW4gUiBhbHNvIGFsbG93IGZvciBjYWxjdWxhdGluZyBzcGVjaWZpYyBzdW1tYXJ5IHN0YXRpc3RpY3M6Cm1lYW4oKSAtIGNhbGN1bGF0ZXMgdGhlIG1lYW4gb2YgYSBudW1lcmljYWwvaW50ZWdlciBjb2x1bW4KbWVkaWFuKCkgLSBjYWxjdWxhdGVzIHRoZSBtZWRpYW4gb2YgYSBudW1lcmljYWwvaW50ZWdlciBjb2x1bW4Kc2QoKSAtIGNhbGN1bGF0ZXMgdGhlIHN0YW5kYXJkIGRldmlhdGlvbiBvZiBhIG51bWVyaWNhbC9pbnRlZ2VyIGNvbHVtbgoKCiMjIEV4ZXJjaXNlIDI6cGxlYXNlIHVzZSB0aGUgY29kZSBjaHVuayBiZWxvdyB0byB1c2UgY29kZSBhbmQgZGV0ZXJtaW5lIHRoZSBmb2xsb3dpbmc6CipXaGF0IGlzIHRoZSBtZWRpYW4gb2YgdGhlICJkYXlzIiBjb2x1bW4/CipXaGF0IGlzIHRoZSBzZCBvZiB0aGUgImRheXMiIGNvbHVtbj8KCmBgYHtyfQptZWRpYW4obW91c2UkZGF5cykKc2QobW91c2UkZGF5cykKCmBgYAoKV2hpbGUgY2FsY3VsYXRpbmcgdGhlIG1lYW4gb2YgYSBjb2x1bW4gaXMgdXNlZnVsLCB3ZSBvZnRlbiB3YW50IHRvIGRldGVybWluZSBob3cgc3VtbWFyeSBzdGF0aXN0aWNzIGRpZmZlciBhbW9uZyB2YXJpYWJsZXMgb3IgZ3JvdXBzLiBXZSBjYW4gY3JlYXRlIGNvZGUgdGhhdCBjYWxjdWxhdGVzIHRoZSBtZWFuIG9mIGEgbnVtZXJpY2FsIHZhcmlhYmxlIGJ5IHNwZWNpZmljIGNhdGVnb3JpY2FsIHZhcmlhYmxlcyB1c2luZyB0aGUgdGFwcGx5KCkgY29kZToKCmBgYHtyfQp0YXBwbHkobW91c2UkZGF5cywgbW91c2Ukb3V0Y29tZSwgbWVhbikKYGBgCgojIyBRVUVTVElPTjogaG93IHdvdWxkIHlvdSBkZXNjcmliZSB3aGF0IHRoZSBjb2RlIGFib3ZlIGRvZXM/IEFuc3dlciBiZWxvdzoKIFRoZSBjb2RlIGFib3ZlIHNob3dzIHRoZSBtZWFucyBvZiBkYXlzIGZvciBlYWNoIG9mIHRoZSBvdXRjb21lcyAob3RoZXIsIHJldGljdWx1bSwgYW5kIHRoeW1pYy4pCgojIyBFeGVyY2lzZSAzOiB1c2luZyB0aGUgY29kZSBjaHVuayBiZWxvdywgdXNlIHRoZSB0YXBwbHkoKSBjb2RlIHRvIGNhbGN1bGF0ZSB0aGUgZm9sbG93aW5nOgoqV2hhdCBpcyB0aGUgbWVhbiBvZiB0aGUgImRheXMiIGNvbHVtbiBieSB0aGUgInRydCIgY29sdW1uPwoqV2hhdCBpcyB0aGUgc2Qgb2YgdGhlICJkYXlzIiBjb2x1bW4gYnkgdGhlICJ0cnQiIGNvbHVtbj8KCmBgYHtyfQp0YXBwbHkobW91c2UkZGF5cywgbW91c2UkdHJ0LCBtZWFuKQp0YXBwbHkobW91c2UkZGF5cywgbW91c2UkdHJ0LCBzZCkKYGBgCgpXZSBjYW4gdGFrZSB0YXBwbHkoKSBhIHN0ZXAgZnVydGhlciwgd2hhdCBpZiB3ZSB3YW50ZWQgdG8gYnJlYWsgdXAgc3VtbWFyeSBzdGF0aXN0aWNzIGJ5IG1vcmUgdGhhbiBvbmUgZ3JvdXA/PyBGb3IgdGhpcyB3ZSB3b3VsZCB1c2UgdGhlIGFnZ3JlZ2F0ZSgpIGNvZGU6CgpgYGB7cn0KYWdncmVnYXRlKG1vdXNlJGRheXMsIGJ5ID0gbGlzdChtb3VzZSRvdXRjb21lLCBtb3VzZSR0cnQpLCBtZWFuKSAKYGBgCk5PVEU6IHlvdSBjYW4gc3dhcCBpbiBvdGhlciBmdW5jdGlvbnMgaWYgbmVlZGVkCgojIyBRVUVTVElPTjogd2hhdCBkbyB5b3Ugbm90aWNlIGFib3V0IHRoZSBvdXRwdXQgb2YgdGhlIGFnZ3JlZ2F0ZSBjb2RlPyBBbnN3ZXIgYmVsb3c6Ckkgbm90aWNlZCB0aGF0IHRoZSBvdXRwdXQgdGFibGUgaGFzIGJvdGggdGhlIG1lYW5zIGZvciBvdXRjb21lIGFuZCB0cnQgYmFzZWQgb24gZGF5cy4gCgojIyBFeGVyY2lzZSA0OiBjYW4geW91IHR1cm4gdGhlIGFnZ3JlZ2F0ZSBvdXRwdXQgaW50byBhIG5ldyBkYXRhZnJhbWUgd2l0aCBuZXcgY29sdW1uIG5hbWVzPyBISU5UOiBzdGVwIDEgd291bGQgYmUgZ2l2ZSBhIHZhcmlhYmxlIG5hbWUgdG8gdGhlIGFnZ3JlZ2F0ZSBjb2RlIChraW5kIG9mIGxpa2Ugd2UgZG8gZm9yIHRoZSByZWFkLnRhYmxlKCkgY29kZXMuLi4pCgpgYGB7cn0KbmV3bW91c2UgPC0gYWdncmVnYXRlKG1vdXNlJGRheXMsIGJ5ID0gbGlzdChtb3VzZSRvdXRjb21lLCBtb3VzZSR0cnQpLCBtZWFuKSAKYGBgCgpXaHkgZG8gd2Ugd2FudCB0byBkbyB0aGlzPyBXZSBvZnRlbiBuZWVkIG1lYW5zIGFuZCBzdGFuZGFyZCBkZXZpYXRpb25zIHRvIGNyZWF0ZSBjZXJ0YWluIHR5cGVzIG9mIHBsb3RzLCBoYXZpbmcgdGhlc2Ugc3RvcmVkIGluIHRoZWlyIG93biBkYXRhZnJhbWUgbWFrZXMgdGhpcyBlYXN5IQoKCgoKIyMgUXVpY2sgdmlzdWFscwoKUiBjYW4gYWxzbyBxdWlja2x5IGdlbmVyYXRlIHZpc3VhbGl6YXRpb25zIHVzaW5nIGNvbW1hbmRzIGxpa2UgYGhpc3QoKWAsIGBib3hwbG90KClgLCBhbmQgYHBsb3QoKWAuICBXZSB3aWxsIGV4cGxvcmUgdGhlc2UsIGFzIHdlbGwgYXMgbW9yZSBzdGF0aXN0aWNhbCBzdW1tYXJpZXMsIG92ZXIgdGhlIG5leHQgdHdvIHdlZWtzLiBGb3Igbm93LCBsZXQncyB0cnkgdG8gZGV2ZWxvcCBhbiBpbnR1aXRpb24gdmlhIGV4YW1wbGVzCgojIyMjIEV4ZXJjaXNlIDQ6CipGb3IgZWFjaCBjb2RlIGNodW5rIGJlbG93LCBydW4gdGhlIGNvZGUgYW5kIGxvb2sgYXQgdGhlIG91dHB1dC4gVHJ5IHRvIGV4cGxhaW4gaG93IHRoZSBjb2RlIHdvcmtzIGluIHlvdXIgb3duIHdvcmRzLCBhcyB3ZWxsIGFzIHdoYXQgdGhlIGNvZGUgZ2VuZXJhdGVzLioKCmBgYHtyfQpoaXN0KG1vdXNlJGRheXMsY29sPSdyZWQnKQpgYGAKKioqKgojIyMjIEFuc3dlcjoKVGhpcyBjb2RlIGNyZWF0ZXMgYSBoaXN0b2dyYW0gYmFzZWQgb24gdGhlIG51bWJlciBvZiBtaWNlIHRoYXQgc3Vydml2ZWQgYSBjZXJ0YWluIG51bWJlciBvZiBkYXlzLiAKKioqKgoKYGBge3J9CmJveHBsb3QoZGF5c34gdHJ0LCBkYXRhID0gbW91c2UsIGNvbD0nYmx1ZScpCmBgYAoKYGBge3J9CmJveHBsb3QoZGF5c34gdHJ0LCBkYXRhID0gbW91c2UsIGNvbD1jKCdibHVlJywgImdyZWVuIikpCmBgYAoKKioqKgojIyMjIEFuc3dlcjoKVGhpcyBjb2RlIGNyZWF0ZXMgYSBib3hwbG90IGNvbXBhcmluZyB0aGUgbnVtYmVyIG9mIGRheXMgZm9yIGVhY2ggb2YgdGhlIHRyZWF0bWVudCB0eXBlczsgY29udHJvbCAoYmx1ZSksIGFuZCBHZXJtLWZyZWUgKGdyZWVuKS5UaGlzIGNhbiBzaG93IGlmIHRyZWF0bWVudHMgZWZmZWN0IGhvdyBsb25nIHRoZSBtaWNlIHN1cnZpdmVkLiAKKioqKgoKYGBge3J9CnBsb3QoZGF5cyB+IGlkLCBkYXRhID0gbW91c2UsIGNvbD0nYmxhY2snLAogICAgIG1haW49IkRheXMgYnkgSUQiKQpgYGAKCmBgYHtyfQpwbG90KGRheXMgfiBpZCwgZGF0YSA9IG1vdXNlLCBwY2ggPSA0LCBjb2w9J2JsYWNrJywKICAgICBtYWluPSJEYXlzIGJ5IElEIikKYGBgCgoKKioqKgojIyMjIEFuc3dlcjoKVGhlIGZpcnN0IGNvZGUgaXMgdXNlZCB0byBzaG93IGhvdyBsb25nIGVhY2ggbW91c2UgKGJ5IGlkKSBzdXJ2aXZlZC4gVGhlIHNlY29uZCBjb2RlIGp1c3QgY2hhbmdlcyB0aGUgY2lyY2xlcyBpbnRvIGFuIFguIAoqKioqCgojIyMjIEV4ZXJjaXNlIDU6IGNyZWF0ZSBhIGJveHBsb3QgZm9yICJkYXlzIiBieSAib3V0Y29tZSIsIHRoaXMgcGxvdCBzaG91bGQgaW5jbHVkZSB0aGUgZm9sbG93aW5nCip1bmlxdWUgY29sb3JzIGZvciBlYWNoIG91dGNvbWUKKmEgcGxvdCB0aXRsZQoKYGBge3J9CmJveHBsb3QoZGF5c35vdXRjb21lLAogICAgICAgIGRhdGE9IG1vdXNlLAogICAgICAgIGNvbD0gYygicGluayIsInR1cnF1b2lzZSIsICJza3libHVlIiksCiAgICAgICAgbWFpbj0gIk51bWJlciBvZiBEYXlzIGJ5IE91dGNvbWUiLAogICAgICAgIHhsYWI9Ik91dGNvbWUiLAogICAgICAgIHlsYWI9IkRheXMiKQpgYGAKCiMjIyMgRXhlcmNpc2UgNjogbG9va2luZyBhdCBzdW1tYXJpZXMgb2YgY2F0ZWdvcmljYWwgdmFyaWFibGVzCldlIHByZXZpb3VzbHkgbG9va2VkIGF0IHRoZSBtZWFuLCBtZWRpYW4sIGFuZCBzdGFuZGFyZCBkZXZpYXRpb24gb2YgdGhlIG51bWVyaWNhbCAiZGF5cyIgdmFyaWFibGUsIGJ1dCBvdGhlciB2YXJpYWJsZXMgYXJlIHN0aWxsIG9mIGludGVyZXN0IHRvIHJlc2VhcmNoZXJzLCBzdWNoIGFzIGNhbmNlciB0eXBlIG9yICJvdXRjb21lIiwgd2UgY2FuJ3QgaG93ZXZlciwgY2FsY3VsYXRlIG1lYW5zIG9mIGNhdGVnb3JpZXMsIHNvIGluc3RlYWQgbGV0J3MgbG9vayBhdCBzb21lIG90aGVyIHN1bW1hcnkgaW5mb3JtYXRpb24gd2UgY2FuIG9idGFpbi4uLgoKVGhlIGNvZGUgY2h1bmsgYmVsb3cgc2hvd3MgaG93IHdlIGNhbiBleHRyYWN0IGEgdGFibGUgb2YgY291bnRzL2ZyZXF1ZW5jaWVzIGZvciBjYW5jZXIgb3V0Y29tZXM6CmBgYHtyfQp0YWJsZShtb3VzZSRvdXRjb21lKQpgYGAKCk9uZSBjb21tb24gcHJhY3RpY2UgaW4gYmlvbG9naWNhbCBzdGF0aXN0aWNzIGlzIHRvIHN0YW5kYXJkaXplIHZhbHVlcyAodXN1YWxseSBkb25lIGJ5IGNyZWF0aW5nIHBlcmNlbnRhZ2VzKSwgdGhpcyBhbGxvd3MgdXMgdG8gYmV0dGVyIG1ha2UgY29tcGFyaXNvbnMgYmV0d2VlbiBncm91cHMgb3IgZGF0YS4gSW4gb3JkZXIgZm9yIHVzIHRvIHRha2UgdGhlIGNvdW50cyB0aGF0IGFyZSBvdXRwdXQgaW4gdGhlIGNvZGUgYWJvdmUgYW5kIHR1cm4gdGhlbSBpbnRvIHBlcmNlbnRhZ2VzIG9yIHByb3BvcnRpb25zLCB3ZSBuZWVkIHRvIGRpdmlkZSBieSB0aGUgdG90YWwgbnVtYmVyIG9mIGNhc2VzLCBpbiB0aGlzIGNhc2UsIHRoYXQncyB0aGUgdG90YWwgbnVtYmVyIG9mIHJvd3MgaW4gdGhlIGRhdGFzZXQuCgpUaGUgY29kZSBiZWxvdyBkb2VzIHRoZSBmb2xsb3dpbmc6IGl0IGNyZWF0ZXMgYW5kIHN0b3JlcyBhIHZhcmlhYmxlIHRvIHJlcHJlc2VudCB0aGUgdG90YWwgbnVtYmVyIG9mIHJvd3MsIHRoZW4gaXQgZGl2aWRlcyBvdXIgdGFibGUgY291bnRzIGJ5IHRoYXQgdmFsdWUgLSB3aGF0IGdldHMgb3V0cHV0IGlzIHRoZSBwcm9wb3J0aW9uLgoKYGBge3J9Cm4gPC0gbGVuZ3RoKG1vdXNlJG91dGNvbWUpCnRhYmxlKG1vdXNlJG91dGNvbWUpL24KYGBgCgojIyMjIENIQUxMRU5HRTogY3JlYXRlIGEgY29kZSB0aGF0IGNhbGN1bGF0ZXMgdGhlIFBFUkNFTlQgb2YgZWFjaCBjYW5jZXIgdHlwZSAtIHVzZSB0aGUgY29kZSBjaHVuayBiZWxvdzoKCmBgYHtyfQpwcm9wLnRhYmxlKHRhYmxlKG1vdXNlJG91dGNvbWUpKSAqIDEwMApgYGAKCiMjIyMgRXhlcmNpc2UgNzogcGFyc2luZyBvdXQgY291bnRzL2ZyZXF1ZW5jaWVzIGJ5IGFub3RoZXIgdmFyaWFibGUKQWJvdmUgd2UgdXNlZCB0aGUgdGFwcGx5KCkgYW5kIGFnZ3JlZ2F0ZSgpIGNvZGVzIHRvIGNhbGN1bGF0ZSBtZWFucyBieSBkaWZmZXJlbnQgZ3JvdXBzIG9yIHZhcmlhYmxlcywgd2hhdCBpZiB3ZSB3YW50ZWQgdG8gZG8gdGhlIHNhbWUgZm9yIG91ciBjYXRlZ29yaWNhbCB2YXJpYWJsZSAib3V0Y29tZSI/CgpUaGUgY29kZSBiZWxvdyBjcmVhdGVzIGEgdGFibGUgb2YgIm91dGNvbWUiIGJ5ICJ0cnQiLCB0aGlzIHdpbGwgYWxsb3cgdXMgdG8gc2VlIGlmIHRoZXJlIHNlZW1zIHRvIGJlIGNlcnRhaW4gY2FuY2VyIHR5cGVzIG1vcmUgYXNzb2NpYXRlZCB3aXRoIGNlcnRhaW4gdHJlYXRtZW50cwoKYGBge3J9CmNhbmNlcl9kZXZlbG9wZWQ8LXRhYmxlKG1vdXNlJG91dGNvbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIG1vdXNlJHRydCkKY2FuY2VyX2RldmVsb3BlZApgYGAKCldoYXQgcGF0dGVybnMgZG8geW91IG5vdGljZSBmcm9tIHRoZSB0YWJsZSB0aGF0IGdldHMgb3V0cHV0dGVkIGJ5IHRoZSBjb2RlPwoKKioqKgojIyMjIEFuc3dlcjpJIG5vdGljZWQgdGhhdCBmb3IgIm90aGVyIiBhbmQgInRoeW1pYyBseW1waG9tYSIgY2F0ZWdvcmllcyB0aGVyZSB3ZXJlYSBjbG9zZSBudW1iZXIgb2YgbWljZSBpbiBib3RoIG91dGNvbWUgZ3JvdXBzLiBUaGVyZSB3YXMgYSBtYWpvciBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIGNvbnRyb2wgYW5kIGdlcm0tZnJlZSBudW1iZXJzIHdpdGggdGhlICJyZXRpY3VsdW0gY2VsbCBzYXJjb21hIi4gSXQgc2VlbWVkIGxpa2UgdGhlIHJldGljdWx1bSB3YXMgbW9yZSBjb21tb24gaW4gdGhlIGNvbnRyb2wgZ3JvdXAuIAoKCioqKioKCgpQTEVBU0UgQ09OVkVSVCBUSElTIFRPIEFOIEhUTUwgRklMRSBBTkQgVVBMT0FEIElUIFRPIENBTlZBUyEKCg==