Author: Kayla Keyue Chen

Last updated: 2024.4.28

Objectives

In this exercise, we will be recapping data manipulation and visualisation skills and check normality to prepare for inferential tests. We’ll also learn more functions to manipulate your dataset, which we don’t have time to cover in the lab: select() and mutate() from the tidyverse package.

Dataset

This exercise will use a R built in dataset called USJudgeRatings.

The data contains average ratings of 43 different judges’ abilities by lawyers in the US. Each row is a lawyer (i.e., the rater), and each column is a measure. You can type “USJudgeRatings” into the Help pane and read more about it. For example,

  • The first column CONT gives the mean number of contacts each judge has had with the lawyers doing the ratings.
  • The following columns give mean ratings out of 10 by the lawyers of the judge’s abilities in different areas of their job.
  • The final column RTEN gives the lawyers’ judgement about whether the judge is worthy of retention.

We will be recapping data manipulation and visualisation skills and check normality to prepare for inferential tests.

1. Set-up

Q1. Set working directory to your folder containing the files. Load in the tidyverse and USJudgeRatings dataset, saving it as data

HINT: setwd(), library(), read.csv()

#setwd("...")
library(tidyverse)

data <- read.csv("USJudgeRatings.csv")

Q2. Is the dataframe in WIDE or LONG format?

# type your answer here: wide

2. Data manipulation

Q3. First remove the column reflecting ‘Worthy of retention’ (i.e., RTEN) as we are not interested in that variable (save the new object as data)

HINT: Use select(dataframe_name, <column names>) to select the columns to keep. For exmaple, select(data, c("CONT", "INTG", "DMNR")). Alternatively, you can drop columns that you don’t need any more by using a minus symbol -. For example, to drop the INTG column, you can use select(data, -INTG).

data <- select(data, -RTEN)

Q4. Next create a new column ID so that we can identify the judges anonymously. The first row has ID of 1, the second has ID of 2, etc (recall that a row is a lawyer who rated the judge so ID is the participant ID).

HINT: Use mutate(column_name = ...) to create a new column or edit an existing column.

data <- data %>% mutate(ID=1:43)

Q5. Next we want to convert the table to a long format with three columns: ID, Variable and Score: save this as object data2

HINT: Use gather()

data2 <- data %>% gather(key=Variable, value=Score, CONT:PHYS)

2. Descriptive Statistics

Q6. Now we can summarise the data. Make a table of mean, SD, SE and 95% confidence intervals for each variable and save it as summary.

HINT: Use group_by(), summarise()

summary <- data2 %>% group_by(Variable) %>% 
  summarise(mean = mean(Score), 
            sd = sd(Score), 
            se = sd/sqrt(n()), 
            ci_lower = mean - 1.96*se, 
            ci_upper = mean + 1.96*se)

3. Further manipulation

Q7. Create a new dataframe (data3) that comprises ID and Total. Total is the sum score of all variables except number of contacts with judge (i.e., CONT).

HINT: Use filter(), group_by() and summarise()

data3 <- data2 %>% 
  filter(Variable != 'CONT') %>%
  group_by(ID) %>% 
  summarise(Total = sum(Score))

Q8. Now we will integrate the total (in data3) with all other measures (in data) and save it as data4.

HINT: Use inner_join()

data4 <- data3 %>% inner_join(data, by='ID')

Now we have ID, Number of contacts of lawyer with judge (CONT), 10 measures of the judge (from INTG to PHYS), and a total score of all measures. Take a look at first 6 rows of the dataframe.

HINT: Use head()

head(data4)
# A tibble: 6 × 13
     ID Total  CONT  INTG  DMNR  DILG  CFMG  DECI  PREP  FAMI  ORAL  WRIT  PHYS
  <int> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1     1  74     5.7   7.9   7.7   7.3   7.1   7.4   7.1   7.1   7.1   7     8.3
2     2  82.3   6.8   8.9   8.8   8.5   7.8   8.1   8     8     7.8   7.9   8.5
3     3  76.4   7.2   8.1   7.8   7.8   7.5   7.6   7.5   7.5   7.3   7.4   7.9
4     4  86     6.8   8.8   8.5   8.8   8.3   8.5   8.7   8.7   8.4   8.5   8.8
5     5  56.7   7.3   6.4   4.3   6.5   6     6.2   5.7   5.7   5.1   5.3   5.5
6     6  82.6   6.2   8.8   8.7   8.5   7.9   8     8.1   8     8     8     8.6

PS: You can always name the dataframe data instead of data2, data3, data4 to avoid too many (useless) objects in your environment. However, this would overwrite your original data dataframe, so you won’t be able to come back to it. There is a balance between creating new objects and keeping the environment tidy…

4. Data visualisation

Q9. Make a graph to help you decide whether the total ratings are normally distributed, check the Q-Q plot, Skewness and Kurtosis values, and test normality using Shapiro-Wilk test.

HINT: Histogram, qqnorm(), qqline(), describe() (from the psych package), shapiro.test()

# histogram
ggplot(data4, aes(x = Total)) + 
  geom_histogram(binwidth = 5, fill = "white", color = "black")

# Q-Q plot
qqnorm(data4$Total)
qqline(data4$Total)

# skewness and kurtosis
library(psych)
describe(data4$Total)
   vars  n  mean   sd median trimmed  mad  min  max range  skew kurtosis   se
X1    1 43 75.84 8.89   77.4   76.73 7.71 53.5 89.2  35.7 -0.76    -0.07 1.36
# skewness = -0.76, kurtosis = -0.07

# shapiro-wilk test
shapiro.test(data4$Total)

    Shapiro-Wilk normality test

data:  data4$Total
W = 0.93925, p-value = 0.02444
# p value = 0.024

Is the Shapiro-Wilk test significant? What does it mean?

# type your answer here: It is significant so the Total score is not normally distributed. 

Q10. Next plot the relationship between number of contacts and total rating (add an estimated regression line).

HINT: scatter plot

ggplot(data4, aes(x=CONT, y=Total)) + 
  geom_point() + 
  geom_smooth(method = "lm")

Q11. Create a bar plot of Judicial integrity (INTG), Demeanor (DMNR), Diligence (DILG), including mean, SD, and CI.

HINT: Use the summary dataframe, filter relevant variables, use stat = "identity" in the geom_bar() function, add CI with geom_errorbar()

ggplot(filter(summary, Variable %in% c("INTG", "DMNR", "DILG")), aes(x = Variable, y = mean)) + 
  geom_bar(stat = "identity", fill = "white", color = "black") + 
  geom_errorbar(aes(ymin = ci_lower, ymax = ci_upper)) + 
  ylim(0, 10)

LS0tDQp0aXRsZTogIlBMSU5TVEFUIGxhYiAyIGV4ZXJjaXNlIg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50OiANCiAgICB0b2M6IHRydWUNCiAgICB0b2NfZmxvYXQ6IHRydWUNCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlDQpwYXJhbXM6DQogIGZsZXg6IFRSVUUNCi0tLQ0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCiNzdHVkZW50czogdGhpcyBpcyB0aGUgc2V0IHVwIGNodW5rLCBpdCBjYW4gYmUgaWdub3JlZA0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0UsIGNvbW1lbnQgPSAiIikNCmxpYnJhcnkoa25pdHIpDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkocHN5Y2gpDQpgYGANCg0KQXV0aG9yOiBLYXlsYSBLZXl1ZSBDaGVuDQoNCkxhc3QgdXBkYXRlZDogMjAyNC40LjI4DQoNCiMjIE9iamVjdGl2ZXMNCg0KSW4gdGhpcyBleGVyY2lzZSwgd2Ugd2lsbCBiZSByZWNhcHBpbmcgZGF0YSBtYW5pcHVsYXRpb24gYW5kIHZpc3VhbGlzYXRpb24gc2tpbGxzIGFuZCBjaGVjayBub3JtYWxpdHkgdG8gcHJlcGFyZSBmb3IgaW5mZXJlbnRpYWwgdGVzdHMuICoqV2UnbGwgYWxzbyBsZWFybiBtb3JlIGZ1bmN0aW9ucyB0byBtYW5pcHVsYXRlIHlvdXIgZGF0YXNldCwgd2hpY2ggd2UgZG9uJ3QgaGF2ZSB0aW1lIHRvIGNvdmVyIGluIHRoZSBsYWI6KiogYHNlbGVjdCgpYCBhbmQgYG11dGF0ZSgpYCBmcm9tIHRoZSB0aWR5dmVyc2UgcGFja2FnZS4gDQoNCiMjIERhdGFzZXQNCg0KVGhpcyBleGVyY2lzZSB3aWxsIHVzZSBhIFIgYnVpbHQgaW4gZGF0YXNldCBjYWxsZWQgVVNKdWRnZVJhdGluZ3MuDQoNClRoZSBkYXRhIGNvbnRhaW5zIGF2ZXJhZ2UgcmF0aW5ncyBvZiA0MyBkaWZmZXJlbnQganVkZ2VzJyBhYmlsaXRpZXMgYnkgbGF3eWVycyBpbiB0aGUgVVMuIEVhY2ggcm93IGlzIGEgbGF3eWVyIChpLmUuLCB0aGUgcmF0ZXIpLCBhbmQgZWFjaCBjb2x1bW4gaXMgYSBtZWFzdXJlLiBZb3UgY2FuIHR5cGUgIlVTSnVkZ2VSYXRpbmdzIiBpbnRvIHRoZSBIZWxwIHBhbmUgYW5kIHJlYWQgbW9yZSBhYm91dCBpdC4gRm9yIGV4YW1wbGUsIA0KDQoqIFRoZSBmaXJzdCBjb2x1bW4gKipDT05UKiogZ2l2ZXMgdGhlIG1lYW4gbnVtYmVyIG9mIGNvbnRhY3RzIGVhY2gganVkZ2UgaGFzIGhhZCB3aXRoIHRoZSBsYXd5ZXJzIGRvaW5nIHRoZSByYXRpbmdzLiANCiogVGhlIGZvbGxvd2luZyBjb2x1bW5zIGdpdmUgbWVhbiByYXRpbmdzIG91dCBvZiAxMCBieSB0aGUgbGF3eWVycyBvZiB0aGUganVkZ2XigJlzIGFiaWxpdGllcyBpbiBkaWZmZXJlbnQgYXJlYXMgb2YgdGhlaXIgam9iLiANCiogVGhlIGZpbmFsIGNvbHVtbiAqKlJURU4qKiBnaXZlcyB0aGUgbGF3eWVycycganVkZ2VtZW50IGFib3V0IHdoZXRoZXIgdGhlIGp1ZGdlIGlzIHdvcnRoeSBvZiByZXRlbnRpb24uDQoNCldlIHdpbGwgYmUgcmVjYXBwaW5nIGRhdGEgbWFuaXB1bGF0aW9uIGFuZCB2aXN1YWxpc2F0aW9uIHNraWxscyBhbmQgY2hlY2sgbm9ybWFsaXR5IHRvIHByZXBhcmUgZm9yIGluZmVyZW50aWFsIHRlc3RzLiANCg0KIyMgMS4gU2V0LXVwDQoNClExLiBTZXQgd29ya2luZyBkaXJlY3RvcnkgdG8geW91ciBmb2xkZXIgY29udGFpbmluZyB0aGUgZmlsZXMuIExvYWQgaW4gdGhlIHRpZHl2ZXJzZSBhbmQgYFVTSnVkZ2VSYXRpbmdzYCBkYXRhc2V0LCBzYXZpbmcgaXQgYXMgYGRhdGFgDQoNCkhJTlQ6IGBzZXR3ZCgpYCwgYGxpYnJhcnkoKWAsIGByZWFkLmNzdigpYA0KDQpgYGB7ciwgZXZhbD1GQUxTRX0NCiNzZXR3ZCgiLi4uIikNCmBgYA0KDQpgYGB7cn0NCmxpYnJhcnkodGlkeXZlcnNlKQ0KDQpkYXRhIDwtIHJlYWQuY3N2KCJVU0p1ZGdlUmF0aW5ncy5jc3YiKQ0KYGBgDQoNClEyLiBJcyB0aGUgZGF0YWZyYW1lIGluIFdJREUgb3IgTE9ORyBmb3JtYXQ/DQoNCmBgYHtyfQ0KIyB0eXBlIHlvdXIgYW5zd2VyIGhlcmU6IHdpZGUNCmBgYA0KDQojIyAyLiBEYXRhIG1hbmlwdWxhdGlvbg0KDQpRMy4gRmlyc3QgcmVtb3ZlIHRoZSBjb2x1bW4gcmVmbGVjdGluZyAnV29ydGh5IG9mIHJldGVudGlvbicgKGkuZS4sIFJURU4pIGFzIHdlIGFyZSBub3QgaW50ZXJlc3RlZCBpbiB0aGF0IHZhcmlhYmxlIChzYXZlIHRoZSBuZXcgb2JqZWN0IGFzIGBkYXRhYCkNCg0KSElOVDogVXNlIGBzZWxlY3QoZGF0YWZyYW1lX25hbWUsIDxjb2x1bW4gbmFtZXM+KWAgdG8gc2VsZWN0IHRoZSBjb2x1bW5zIHRvIGtlZXAuIEZvciBleG1hcGxlLCBgc2VsZWN0KGRhdGEsIGMoIkNPTlQiLCAiSU5URyIsICJETU5SIikpYC4gQWx0ZXJuYXRpdmVseSwgeW91IGNhbiBkcm9wIGNvbHVtbnMgdGhhdCB5b3UgZG9uJ3QgbmVlZCBhbnkgbW9yZSBieSB1c2luZyBhIG1pbnVzIHN5bWJvbCBgLWAuIEZvciBleGFtcGxlLCB0byBkcm9wIHRoZSBJTlRHIGNvbHVtbiwgeW91IGNhbiB1c2UgYHNlbGVjdChkYXRhLCAtSU5URylgLiANCg0KYGBge3J9DQpkYXRhIDwtIHNlbGVjdChkYXRhLCAtUlRFTikNCmBgYA0KDQpRNC4gTmV4dCBjcmVhdGUgYSBuZXcgY29sdW1uIGBJRGAgc28gdGhhdCB3ZSBjYW4gaWRlbnRpZnkgdGhlIGp1ZGdlcyBhbm9ueW1vdXNseS4gVGhlIGZpcnN0IHJvdyBoYXMgSUQgb2YgMSwgdGhlIHNlY29uZCBoYXMgSUQgb2YgMiwgZXRjIChyZWNhbGwgdGhhdCBhIHJvdyBpcyBhIGxhd3llciB3aG8gcmF0ZWQgdGhlIGp1ZGdlIHNvIElEIGlzIHRoZSBwYXJ0aWNpcGFudCBJRCkuIA0KDQpISU5UOiBVc2UgYG11dGF0ZShjb2x1bW5fbmFtZSA9IC4uLilgIHRvIGNyZWF0ZSBhIG5ldyBjb2x1bW4gb3IgZWRpdCBhbiBleGlzdGluZyBjb2x1bW4uIA0KDQpgYGB7cn0NCmRhdGEgPC0gZGF0YSAlPiUgbXV0YXRlKElEPTE6NDMpDQpgYGANCg0KUTUuIE5leHQgd2Ugd2FudCB0byBjb252ZXJ0IHRoZSB0YWJsZSB0byBhIGxvbmcgZm9ybWF0IHdpdGggdGhyZWUgY29sdW1uczogYElEYCwgYFZhcmlhYmxlYCBhbmQgYFNjb3JlYDogc2F2ZSB0aGlzIGFzIG9iamVjdCBkYXRhMg0KDQpISU5UOiBVc2UgYGdhdGhlcigpYA0KDQpgYGB7cn0NCmRhdGEyIDwtIGRhdGEgJT4lIGdhdGhlcihrZXk9VmFyaWFibGUsIHZhbHVlPVNjb3JlLCBDT05UOlBIWVMpDQpgYGANCg0KIyMgMi4gRGVzY3JpcHRpdmUgU3RhdGlzdGljcw0KDQpRNi4gTm93IHdlIGNhbiBzdW1tYXJpc2UgdGhlIGRhdGEuIE1ha2UgYSB0YWJsZSBvZiBtZWFuLCBTRCwgU0UgYW5kIDk1JSBjb25maWRlbmNlIGludGVydmFscyBmb3IgZWFjaCB2YXJpYWJsZSBhbmQgc2F2ZSBpdCBhcyBgc3VtbWFyeWAuDQoNCkhJTlQ6IFVzZSBgZ3JvdXBfYnkoKWAsIGBzdW1tYXJpc2UoKWANCg0KYGBge3J9DQpzdW1tYXJ5IDwtIGRhdGEyICU+JSBncm91cF9ieShWYXJpYWJsZSkgJT4lIA0KICBzdW1tYXJpc2UobWVhbiA9IG1lYW4oU2NvcmUpLCANCiAgICAgICAgICAgIHNkID0gc2QoU2NvcmUpLCANCiAgICAgICAgICAgIHNlID0gc2Qvc3FydChuKCkpLCANCiAgICAgICAgICAgIGNpX2xvd2VyID0gbWVhbiAtIDEuOTYqc2UsIA0KICAgICAgICAgICAgY2lfdXBwZXIgPSBtZWFuICsgMS45NipzZSkNCmBgYA0KDQojIyAzLiBGdXJ0aGVyIG1hbmlwdWxhdGlvbg0KDQpRNy4gQ3JlYXRlIGEgbmV3IGRhdGFmcmFtZSAoYGRhdGEzYCkgdGhhdCBjb21wcmlzZXMgYElEYCBhbmQgYFRvdGFsYC4gVG90YWwgaXMgdGhlICoqc3VtIHNjb3JlKiogb2YgYWxsIHZhcmlhYmxlcyBleGNlcHQgbnVtYmVyIG9mIGNvbnRhY3RzIHdpdGgganVkZ2UgKGkuZS4sIENPTlQpLg0KDQpISU5UOiBVc2UgYGZpbHRlcigpYCwgYGdyb3VwX2J5KClgIGFuZCBgc3VtbWFyaXNlKClgDQoNCmBgYHtyfQ0KZGF0YTMgPC0gZGF0YTIgJT4lIA0KICBmaWx0ZXIoVmFyaWFibGUgIT0gJ0NPTlQnKSAlPiUNCiAgZ3JvdXBfYnkoSUQpICU+JSANCiAgc3VtbWFyaXNlKFRvdGFsID0gc3VtKFNjb3JlKSkNCmBgYA0KDQpROC4gTm93IHdlIHdpbGwgaW50ZWdyYXRlIHRoZSB0b3RhbCAoaW4gYGRhdGEzYCkgd2l0aCBhbGwgb3RoZXIgbWVhc3VyZXMgKGluIGBkYXRhYCkgYW5kIHNhdmUgaXQgYXMgYGRhdGE0YC4NCg0KSElOVDogVXNlIGBpbm5lcl9qb2luKClgDQoNCmBgYHtyfQ0KZGF0YTQgPC0gZGF0YTMgJT4lIGlubmVyX2pvaW4oZGF0YSwgYnk9J0lEJykNCmBgYA0KDQpOb3cgd2UgaGF2ZSBJRCwgTnVtYmVyIG9mIGNvbnRhY3RzIG9mIGxhd3llciB3aXRoIGp1ZGdlIChDT05UKSwgMTAgbWVhc3VyZXMgb2YgdGhlIGp1ZGdlIChmcm9tIElOVEcgdG8gUEhZUyksIGFuZCBhIHRvdGFsIHNjb3JlIG9mIGFsbCBtZWFzdXJlcy4gVGFrZSBhIGxvb2sgYXQgZmlyc3QgNiByb3dzIG9mIHRoZSBkYXRhZnJhbWUuIA0KDQpISU5UOiBVc2UgYGhlYWQoKWANCg0KYGBge3J9DQpoZWFkKGRhdGE0KQ0KYGBgDQoNClBTOiBZb3UgY2FuIGFsd2F5cyBuYW1lIHRoZSBkYXRhZnJhbWUgYGRhdGFgIGluc3RlYWQgb2YgYGRhdGEyYCwgYGRhdGEzYCwgYGRhdGE0YCB0byBhdm9pZCB0b28gbWFueSAodXNlbGVzcykgb2JqZWN0cyBpbiB5b3VyIGVudmlyb25tZW50LiBIb3dldmVyLCB0aGlzIHdvdWxkIG92ZXJ3cml0ZSB5b3VyIG9yaWdpbmFsIGBkYXRhYCBkYXRhZnJhbWUsIHNvIHlvdSB3b24ndCBiZSBhYmxlIHRvIGNvbWUgYmFjayB0byBpdC4gVGhlcmUgaXMgYSBiYWxhbmNlIGJldHdlZW4gY3JlYXRpbmcgbmV3IG9iamVjdHMgYW5kIGtlZXBpbmcgdGhlIGVudmlyb25tZW50IHRpZHkuLi4gDQoNCiMjIDQuIERhdGEgdmlzdWFsaXNhdGlvbg0KDQpROS4gTWFrZSBhIGdyYXBoIHRvIGhlbHAgeW91IGRlY2lkZSB3aGV0aGVyIHRoZSB0b3RhbCByYXRpbmdzIGFyZSBub3JtYWxseSBkaXN0cmlidXRlZCwgY2hlY2sgdGhlIFEtUSBwbG90LCBTa2V3bmVzcyBhbmQgS3VydG9zaXMgdmFsdWVzLCBhbmQgdGVzdCBub3JtYWxpdHkgdXNpbmcgU2hhcGlyby1XaWxrIHRlc3QuIA0KDQpISU5UOiBIaXN0b2dyYW0sIGBxcW5vcm0oKWAsIGBxcWxpbmUoKWAsIGBkZXNjcmliZSgpYCAoZnJvbSB0aGUgcHN5Y2ggcGFja2FnZSksIGBzaGFwaXJvLnRlc3QoKWANCg0KYGBge3J9DQojIGhpc3RvZ3JhbQ0KZ2dwbG90KGRhdGE0LCBhZXMoeCA9IFRvdGFsKSkgKyANCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSA1LCBmaWxsID0gIndoaXRlIiwgY29sb3IgPSAiYmxhY2siKQ0KDQojIFEtUSBwbG90DQpxcW5vcm0oZGF0YTQkVG90YWwpDQpxcWxpbmUoZGF0YTQkVG90YWwpDQoNCiMgc2tld25lc3MgYW5kIGt1cnRvc2lzDQpsaWJyYXJ5KHBzeWNoKQ0KZGVzY3JpYmUoZGF0YTQkVG90YWwpDQojIHNrZXduZXNzID0gLTAuNzYsIGt1cnRvc2lzID0gLTAuMDcNCg0KIyBzaGFwaXJvLXdpbGsgdGVzdA0Kc2hhcGlyby50ZXN0KGRhdGE0JFRvdGFsKQ0KIyBwIHZhbHVlID0gMC4wMjQNCmBgYA0KDQpJcyB0aGUgU2hhcGlyby1XaWxrIHRlc3Qgc2lnbmlmaWNhbnQ/IFdoYXQgZG9lcyBpdCBtZWFuPyANCg0KYGBge3J9DQojIHR5cGUgeW91ciBhbnN3ZXIgaGVyZTogSXQgaXMgc2lnbmlmaWNhbnQgc28gdGhlIFRvdGFsIHNjb3JlIGlzIG5vdCBub3JtYWxseSBkaXN0cmlidXRlZC4gDQpgYGANCg0KDQpRMTAuIE5leHQgcGxvdCB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gbnVtYmVyIG9mIGNvbnRhY3RzIGFuZCB0b3RhbCByYXRpbmcgKGFkZCBhbiBlc3RpbWF0ZWQgcmVncmVzc2lvbiBsaW5lKS4NCg0KSElOVDogc2NhdHRlciBwbG90DQoNCmBgYHtyfQ0KZ2dwbG90KGRhdGE0LCBhZXMoeD1DT05ULCB5PVRvdGFsKSkgKyANCiAgZ2VvbV9wb2ludCgpICsgDQogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIpDQpgYGANCg0KUTExLiBDcmVhdGUgYSBiYXIgcGxvdCBvZiBKdWRpY2lhbCBpbnRlZ3JpdHkgKElOVEcpLCBEZW1lYW5vciAoRE1OUiksIERpbGlnZW5jZSAoRElMRyksIGluY2x1ZGluZyBtZWFuLCBTRCwgYW5kIENJLiANCg0KSElOVDogVXNlIHRoZSBgc3VtbWFyeWAgZGF0YWZyYW1lLCBmaWx0ZXIgcmVsZXZhbnQgdmFyaWFibGVzLCB1c2UgYHN0YXQgPSAiaWRlbnRpdHkiYCBpbiB0aGUgYGdlb21fYmFyKClgIGZ1bmN0aW9uLCBhZGQgQ0kgd2l0aCBgZ2VvbV9lcnJvcmJhcigpYA0KDQpgYGB7ciwgZmlnLndpZHRoPTUsIGZpZy5oZWlnaHQ9NH0NCmdncGxvdChmaWx0ZXIoc3VtbWFyeSwgVmFyaWFibGUgJWluJSBjKCJJTlRHIiwgIkRNTlIiLCAiRElMRyIpKSwgYWVzKHggPSBWYXJpYWJsZSwgeSA9IG1lYW4pKSArIA0KICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgZmlsbCA9ICJ3aGl0ZSIsIGNvbG9yID0gImJsYWNrIikgKyANCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbiA9IGNpX2xvd2VyLCB5bWF4ID0gY2lfdXBwZXIpKSArIA0KICB5bGltKDAsIDEwKQ0KYGBgDQoNCg==