Load the tidyverse package, as we’ll be doing for every project.

library(tidyverse)

Pew research data

Get free account at the Pew Research Center: http://www.pewresearch.org/download-datasets/

Once you have your account, from the main page (pewresearch.org) go to ‘datasets,’ and then ‘Internet, Science, and Tech,’ and download the ‘Jan. 3-10, 2018 - Core trends survey’. (Here’s the page it should be on: http://www.pewinternet.org/dataset/jan-3-10-2018-core-trends-survey/)

Click on “Download Dataset” and it should download a directory or a .zip file called “Jan. 3-10, 2018 - Core trends survey”.

Then upload the whole directory to the Files section of R Studio. Do this by clicking the ‘Upload’ button in the Files window pane on the right.

R Markdown

Before we get into the analysis, I want to go on a brief diversion into R Markdown.

Markdown is a way of using plain text to create the kind of advanced formatting you’d normally need a word processor like Microsoft Word to create. It is widely used by people who publish on the internet, like bloggers and web developers.

R Markdown is a variant of markdown that includes some additional functions to work with R. The text in these notebooks you are reading is in R Markdown, although we don’t use many of the features that are possible.

Here are some examples of how R Markdown is used to format the text in this notebook:

Symbols like the asterisk are used for italics and bold. Click Preview above and the text will be rendered in italics and bold and the asterisks will disappear.

  1. Do the following:

Put this text in italics.

Put the word bold in bold.

What if you want to show asterisks (or any other special markdown character) around a word? Put backslashes around the special characters, like this **this is not bold**.

  1. This text will normally create a new header:

## This is a header

Edit the above line so that it does not appear as a header, and the symbols are shown instead.

Here’s one that trips me up a lot:

When you hit return to create a new line, your text won’t appear on a new line unless you add two spaces to the end of the line.

  1. Make sure that the two lines below appear on different lines when previewed:

Line one.
Same line.

To make a table:

Column 1 Column 2
Content 1 Content 2
Content 3 Content 4

The plain text can be jagged but it will still format properly when rendered:

Group 1 Group 2
3.2 4.5

You can center or justify the table contents with colons in the second row:

Left Right Center
3.2 4.5 6.7
  1. Make a table below with 4 columns labeled Column 1, Column 2, etc., and 3 rows. Put the numbers 1-12 in the cells. Center all the content.
Column 1 Column 2 Column 3 Column 4
1 2 3 4
5 6 7 8
9 10 11 12

The code chunks we have been using are part of R markdown:

8 + 7
[1] 15

You can suppress the code so it runs and shows the output but does not display any R code when published by putting echo=FALSE in the brackets:

[1] 15

If you use include=FALSE in the brackets, it will run the code, but not show the output or the code. You might do that if you need to run some calculations for later use but don’t want to show those intermediate steps.

  1. Put x <- 3 into a code chunk below, use include=FALSE, and run it below:

You can insert R code without a chunk by surrounding it in backticks and using the letter r, like this: 13 squared = 169

  1. Type 116/7 = and then calculate the answer using the method above. 116/7 = `r 116/7

Those are some of the basics. See here for a whole book about R Markdown: https://bookdown.org/yihui/rmarkdown/

Now let’s get on with the analysis of the Pew data.

Analysis of the Pew data

This reads in the dataset after it has been uploaded to Files:

pew <- read_csv("January 3-10, 2018 - Core Trends Survey/January 3-10, 2018 - Core Trends Survey - CSV.csv")
Parsed with column specification:
cols(
  .default = col_double(),
  usr = col_character(),
  `pial11ao@` = col_character()
)
See spec(...) for full column specifications.

Use glimpse() on the pew dataset to get an overview of the data. Do that below:

glimpse(pew)

These variables correspond to questions on a survey, like the sex of the respondent. They are mostly coded as numbers, like sex: Male = 1, Female = 2.

Categorical variables like these are better represented as factors in R. You can convert a variable into a factor with mutate() and as.factor(). Notice that you need to use the arrow <- to put the new mutated variable back into the original.

Then you can use count() to see how many of each category appear in the variable:

pew <- pew %>% 
  mutate(sex = as.factor(sex))


pew %>% 
  count(sex)

Next, we want to change the level names to something more descriptive than 1 and 2. The codebook say that 1 = Male and 2 = Female. We use fct_recode() to do this.

pew <- pew %>% 
  mutate(sex = fct_recode(sex, "Male" = "1", "Female" = "2"))

pew %>% 
  count(sex)

Another variable, called intfreq, asked “About how often do you use the internet?” Possible responses are 1: Almost constantly, 2: Several times a day, 3: About once a day, 4: Several times a week, 5: Less often, 8: Don’t know, 9: Refused to answer. (Those are listed in the Questionnaire document.)

First, just convert it into a factor and look at the levels, and then count the levels. (Don’t recode yet, we’ll do that below.) Create a chunk below and use the same procedure as above to convert sex to a factor and count the levels:

pew <- pew %>% 
  mutate(intfreq = as.factor(intfreq))


pew %>% 
  count(intfreq)

Here is the code for converting each number to a verbal label. You don’t have to split the command onto multiple indented lines like I’ve done, but it makes it easier to read. There are two missing data numbers: 8 for “Don’t know” and 9 for “Refused to answer.” Let’s just get rid of both of those by setting them to NULL. They will appear as missing data which we can exclude later. In addition, let’s change the name of the variable to something more meaningful like internet_use.

pew <- pew %>%
  mutate(internet_use = fct_recode(intfreq,
                              "Almost constantly" = "1",
                              "Several times/day" = "2",
                              "Once per day" = "3",
                              "Several times/week" = "4",
                              "Less than once/day" = "5",
                              NULL = "8",
                              NULL = "9"))

pew %>% 
  count(internet_use)

A very common way to look at survey data is with crosstabs, i.e., one categorical variable crossed with another. If we want to see how often Males and Females say they use the internet, we can make a table of the counts in each category:

pew %>% 
  count(sex, internet_use)

To drop the missing data, use drop_na(). Copy and paste the code form the chunk above, and add the line drop_na(internet_use). Don’t forget the pipe:

pew %>% 
  count(sex, internet_use)
  drop_na(internet_use)
pew %>%

Graph variations

A graph would be much easier to read than a table.

pew %>% 
  drop_na(internet_use) %>% 
  ggplot(aes(x = internet_use, fill = sex)) +
  geom_bar()

The viridis color palette is considered by most people to be nicer than the default ggplot colors. Copy-paste the above code chunk below, and: 1. Add the line scale_fill_viridis_d() to the end of the above, and don’t forget to add + to the end of the previous line.
2. Flip it so the bars are horizontal by including the line coord_flip() as well.

pew %>% 
  drop_na(internet_use) %>% 
  ggplot(aes(x = internet_use, fill = sex)) +
  geom_bar()+
  scale_fill_viridis_d()+
  coord_flip()

Here’s another variation on a bar chart that makes it easy to compare the proportions of females and males in each group.

Copy-paste the above chunk, and then in the parentheses of geom_bar(), put position = “fill”.

pew %>% 
  drop_na(internet_use) %>% 
  ggplot(aes(x = internet_use, fill = sex)) +
  geom_bar(position = "fill")+
  scale_fill_viridis_d()+
  coord_flip()

Another variation is better for seeing raw numbers rather than proportions:

  1. In the parentheses of geom_bar(), put position = “dodge” to place the bars right next to one another.
  2. I don’t like the gray background in ggplots. To give it a white background, include the line theme_minimal().
pew %>% 
  drop_na(internet_use) %>% 
  ggplot(aes(x = internet_use, fill = sex)) +
  geom_bar(position = "dodge")+
  scale_fill_viridis_d()+
  coord_flip()+
  theme_minimal()

To create side-by-side graphs, one for men and one for women, use facet_wrap(vars(sex)). It creates side-by-side graphs based on whatever variable or variables you put into vars().

In addition, create some better labels with labs(). Include labs(y = “Number of people”, x = “How often do you use the internet”, title = “Frequency of Internet Usage”). Remember that we flipped the coordinates, so the x and y axes are flipped! Run the code below:

pew %>% 
  drop_na(internet_use) %>% 
  ggplot(aes(x = internet_use)) +
  geom_bar() +
  facet_wrap(vars(sex)) +
  coord_flip() +
  theme_minimal() +
  labs(y = "Number of people", 
       x = "How often do you use the internet", 
       title = "Frequency of Internet Usage")

Collapsing levels

You might also want to combine some of the levels. In our example, we might collapse the 5 leves of Internet use down to just 2: More than once per day vs. once per day or less. Use fct_collapse() to do that. The following code does this and puts it into a new variable called internet_use_simple.

pew <- pew %>% 
  mutate(internet_use_simple = fct_collapse(internet_use,
                                            daily_or_less = c("Once per day", 
                                                              "Several times/week", 
                                                              "Less than once/day"),
                                            more_than_daily = c("Several times/day", 
                                                                "Almost constantly")))

pew %>% 
  count(internet_use_simple)

Now re-create the position = “fill” graph from above, but with internet_use_simple.

pew %>% 
  drop_na(internet_use_simple) %>% 
  ggplot(aes(x = internet_use_simple, fill = sex)) +
  geom_bar(position = "dodge")+
  scale_fill_viridis_d()+
  coord_flip()+
  theme_minimal()

Assignment

The following variables are in the pew dataset:

web1a: Twitter web1b: Instagram web1c: Facebook web1d: Snapchat web1e: Youtube

They are all coded as to whether respondents use that social media site, with (“Yes” = “1”, “No” = “2”, “Don’t know” = “8”, “Refused” = “9”).

educ2 is the respondents’ education level (“Less than HS” = “1”, “Some HS” = “2”, “HS graduate” = “3”, “Some college” = “4”, “Associate degree” = “5”, “College degree” = “6”, “Some grad school” = “7”, “Grad degree” = “8”, “Don’t know” = “98”, “Refused” = “99”).

When you recode you can use the list of recodings in the parentheses above. I recommend changing the “Don’t know” and “Refused” to NULL.

  1. Choose one of the web1 variables, convert it to a factor, and recode it.
  2. Also convert and recode educ2.
  3. Create a table of the counts of each variable, and of both simultaneously.
  4. Create a graph of your choice showing the two variables.
  5. Collapse educ2 into just two categories of your choice, and re-run the table and graph.
  6. Publish to RPubs, making sure you present the results with explanation and in an understandable way, including graph titles and labeled axes.
pew <- pew %>% 
  mutate(twitter = as.factor(web1a))


pew %>% 
  count(twitter)
pew <- pew %>% 
  mutate(twitter = fct_recode(twitter, "yes" = "1", "no" = "2", NULL = "8", NULL = "9"))

pew %>% 
  count(twitter)

pew <- pew %>% 
  mutate(educ = as.factor(educ2))


pew %>% 
  count(educ)
pew <- pew %>% 
  mutate(educ = fct_recode(educ, "Less than HS" = "1", "Some HS" = "2", "HS graduate" = "3", "Some college" = "4", "Associate degree" = "5", "College degree" = "6", "Some grad school" = "7", "Grad degree" = "8", "Don't know" = "98", "Refused" = "99"))

pew %>% 
  count(educ)
pew %>% 
  drop_na(twitter) %>% 
  ggplot(aes(x = twitter)) +
  geom_bar() +
  facet_wrap(vars(sex)) +
  coord_flip() +
  theme_minimal() +
  labs(y = "Number of people", 
       x = "Do you use Twitter", 
       title = "Frequency of Twitter Usage")

pew %>% 
  drop_na(educ) %>% 
  ggplot(aes(x = educ, fill = twitter)) +
  geom_bar(position = "dodge")+
  scale_fill_viridis_d()+
  coord_flip()+
  theme_minimal()


<!-- rnb-source-end -->

<!-- rnb-output-begin eyJkYXRhIjoiRXJyb3I6IGF0dGVtcHQgdG8gdXNlIHplcm8tbGVuZ3RoIHZhcmlhYmxlIG5hbWVcbiJ9 -->

Error: attempt to use zero-length variable name ```

pew <- pew %>% 
  mutate(educ1 = fct_recode(educ, "Less than HS" = "1", "Some HS" = "2", NULL = "3", NULL = "4"))
Unknown levels in `f`: 1, 2
pew %>%
  count(educ1)
pew <- pew %>% 
  mutate(educ1 = fct_recode(educ, "Less than HS" = "1", "Some HS" = "2", NULL = "3", NULL = "4"))

pew %>%
  count(educ1)

Here are a few additional variables. You do not need to use these, but I had the coding for them so I thought I’d include them for completeness.

home4nw: Do you currently subscribe to internet service at home? 1 = Yes, 2 = No, 8 = Don’t know, 9 = Refused

Do you use the following social media sites: (1 = Yes, 2 = No) web1a: Twitter web1b: Instagram web1c: Facebook web1d: Snapchat web1e: Youtube

How hard would it be for you to give up…
1 = Very hard, 2 = Somewhat hard, 3 = Not too hard, 4 = Not hard at all, 5 = Impossible, 6 = Do not use, 8 = Don’t know, 9 = Refused pial5a: Television pial5b: Cell phone pial5c: Internet pial5d: Social media

pial11: Would you say the internet has mostly been a GOOD thing or a BAD thing for society? 1 = Good thing, 2 = Bad thing, 3 = Some of both, 8 = Don’t know, 9 = Refused

pial12 How about you, personally? Overall, when you add up all the advantages and disadvantages of the internet, would you say the internet has mostly been a GOOD thing or a BAD thing for you? 1 = Good thing, 2 = Bad thing, 3 = Some of both, 8 = Don’t know, 9 = Refused

marital 1 = Married, 2 = Living with a partner, 3 = Divorced, 4 = Separated, 5 = Widowed, 6 = Never married, 8 = Don’t know, 9 = Refused

emplnw 1 = Employed full time, 2 = Employed part-time, 3 = Retired, 4 = Not employed, 5 = Self-employed, 6 = Disabled, 7 = Student, 8 = Other, 98 = Don’t know, 99 = Refused

LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKTG9hZCB0aGUgdGlkeXZlcnNlIHBhY2thZ2UsIGFzIHdlJ2xsIGJlIGRvaW5nIGZvciBldmVyeSBwcm9qZWN0LgoKYGBge3J9CmxpYnJhcnkodGlkeXZlcnNlKQpgYGAKCiMjIyBQZXcgcmVzZWFyY2ggZGF0YQoKR2V0IGZyZWUgYWNjb3VudCBhdCB0aGUgUGV3IFJlc2VhcmNoIENlbnRlcjogaHR0cDovL3d3dy5wZXdyZXNlYXJjaC5vcmcvZG93bmxvYWQtZGF0YXNldHMvICAKCk9uY2UgeW91IGhhdmUgeW91ciBhY2NvdW50LCBmcm9tIHRoZSBtYWluIHBhZ2UgKHBld3Jlc2VhcmNoLm9yZykgZ28gdG8gJ2RhdGFzZXRzLCcgYW5kIHRoZW4gJ0ludGVybmV0LCBTY2llbmNlLCBhbmQgVGVjaCwnIGFuZCBkb3dubG9hZCB0aGUgJ0phbi4gMy0xMCwgMjAxOCAtIENvcmUgdHJlbmRzIHN1cnZleScuIChIZXJlJ3MgdGhlIHBhZ2UgaXQgc2hvdWxkIGJlIG9uOiBodHRwOi8vd3d3LnBld2ludGVybmV0Lm9yZy9kYXRhc2V0L2phbi0zLTEwLTIwMTgtY29yZS10cmVuZHMtc3VydmV5LykKCkNsaWNrIG9uICJEb3dubG9hZCBEYXRhc2V0IiBhbmQgaXQgc2hvdWxkIGRvd25sb2FkIGEgZGlyZWN0b3J5IG9yIGEgLnppcCBmaWxlIGNhbGxlZCAiSmFuLiAzLTEwLCAyMDE4IC0gQ29yZSB0cmVuZHMgc3VydmV5Ii4KClRoZW4gdXBsb2FkIHRoZSB3aG9sZSBkaXJlY3RvcnkgdG8gdGhlIEZpbGVzIHNlY3Rpb24gb2YgUiBTdHVkaW8uIERvIHRoaXMgYnkgY2xpY2tpbmcgdGhlICdVcGxvYWQnIGJ1dHRvbiBpbiB0aGUgRmlsZXMgd2luZG93IHBhbmUgb24gdGhlIHJpZ2h0LgoKCiMjIyBSIE1hcmtkb3duCgpCZWZvcmUgd2UgZ2V0IGludG8gdGhlIGFuYWx5c2lzLCBJIHdhbnQgdG8gZ28gb24gYSBicmllZiBkaXZlcnNpb24gaW50byBSIE1hcmtkb3duLiAKCk1hcmtkb3duIGlzIGEgd2F5IG9mIHVzaW5nIHBsYWluIHRleHQgdG8gY3JlYXRlIHRoZSBraW5kIG9mIGFkdmFuY2VkIGZvcm1hdHRpbmcgeW91J2Qgbm9ybWFsbHkgbmVlZCBhIHdvcmQgcHJvY2Vzc29yIGxpa2UgTWljcm9zb2Z0IFdvcmQgdG8gY3JlYXRlLiBJdCBpcyB3aWRlbHkgdXNlZCBieSBwZW9wbGUgd2hvIHB1Ymxpc2ggb24gdGhlIGludGVybmV0LCBsaWtlIGJsb2dnZXJzIGFuZCB3ZWIgZGV2ZWxvcGVycy4gCgpSIE1hcmtkb3duIGlzIGEgdmFyaWFudCBvZiBtYXJrZG93biB0aGF0IGluY2x1ZGVzIHNvbWUgYWRkaXRpb25hbCBmdW5jdGlvbnMgdG8gd29yayB3aXRoIFIuIFRoZSB0ZXh0IGluIHRoZXNlIG5vdGVib29rcyB5b3UgYXJlIHJlYWRpbmcgaXMgaW4gUiBNYXJrZG93biwgYWx0aG91Z2ggd2UgZG9uJ3QgdXNlIG1hbnkgb2YgdGhlIGZlYXR1cmVzIHRoYXQgYXJlIHBvc3NpYmxlLgoKSGVyZSBhcmUgc29tZSBleGFtcGxlcyBvZiBob3cgUiBNYXJrZG93biBpcyB1c2VkIHRvIGZvcm1hdCB0aGUgdGV4dCBpbiB0aGlzIG5vdGVib29rOgoKU3ltYm9scyBsaWtlIHRoZSBhc3RlcmlzayBhcmUgdXNlZCBmb3IgKml0YWxpY3MqIGFuZCAqKmJvbGQqKi4gQ2xpY2sgUHJldmlldyBhYm92ZSBhbmQgdGhlIHRleHQgd2lsbCBiZSByZW5kZXJlZCBpbiBpdGFsaWNzIGFuZCBib2xkIGFuZCB0aGUgYXN0ZXJpc2tzIHdpbGwgZGlzYXBwZWFyLgoKMS4gRG8gdGhlIGZvbGxvd2luZzoKCipQdXQgdGhpcyB0ZXh0IGluIGl0YWxpY3MuKgoKKipQdXQgdGhlIHdvcmQgYm9sZCBpbiBib2xkLioqCgoKCgpXaGF0IGlmIHlvdSB3YW50IHRvIHNob3cgYXN0ZXJpc2tzIChvciBhbnkgb3RoZXIgc3BlY2lhbCBtYXJrZG93biBjaGFyYWN0ZXIpIGFyb3VuZCBhIHdvcmQ/IFB1dCBiYWNrc2xhc2hlcyBhcm91bmQgdGhlIHNwZWNpYWwgY2hhcmFjdGVycywgbGlrZSB0aGlzIFwqKnRoaXMgaXMgbm90IGJvbGQqKlwuCgoyLiBUaGlzIHRleHQgd2lsbCBub3JtYWxseSBjcmVhdGUgYSBuZXcgaGVhZGVyOgoKXCMjIFRoaXMgaXMgYSBoZWFkZXJcCgpFZGl0IHRoZSBhYm92ZSBsaW5lIHNvIHRoYXQgaXQgZG9lcyBub3QgYXBwZWFyIGFzIGEgaGVhZGVyLCBhbmQgdGhlIHN5bWJvbHMgYXJlIHNob3duIGluc3RlYWQuCgoKCgpIZXJlJ3Mgb25lIHRoYXQgdHJpcHMgbWUgdXAgYSBsb3Q6CgpXaGVuIHlvdSBoaXQgcmV0dXJuIHRvIGNyZWF0ZSBhIG5ldyBsaW5lLCB5b3VyIHRleHQgd29uJ3QgYXBwZWFyIG9uIGEgbmV3IGxpbmUgdW5sZXNzIHlvdSBhZGQgdHdvIHNwYWNlcyB0byB0aGUgZW5kIG9mIHRoZSBsaW5lLgoKMy4gTWFrZSBzdXJlIHRoYXQgdGhlIHR3byBsaW5lcyBiZWxvdyBhcHBlYXIgb24gZGlmZmVyZW50IGxpbmVzIHdoZW4gcHJldmlld2VkOgoKTGluZSBvbmUuICAKU2FtZSBsaW5lLgoKCgpUbyBtYWtlIGEgdGFibGU6CgpDb2x1bW4gMSAgfCBDb2x1bW4gMgotLS0tLS0tLS0gfCAtLS0tLS0tLQpDb250ZW50IDEgfCBDb250ZW50IDIKQ29udGVudCAzIHwgQ29udGVudCA0CgoKVGhlIHBsYWluIHRleHQgY2FuIGJlIGphZ2dlZCBidXQgaXQgd2lsbCBzdGlsbCBmb3JtYXQgcHJvcGVybHkgd2hlbiByZW5kZXJlZDoKCiBHcm91cCAxICAgICAgICB8IEdyb3VwIDIgCi0tfCAtLS0tLS0tLS0tLS0tLQogICAgICAgICAgMy4yIHwgNC41IAoKCllvdSBjYW4gY2VudGVyIG9yIGp1c3RpZnkgdGhlIHRhYmxlIGNvbnRlbnRzIHdpdGggY29sb25zIGluIHRoZSBzZWNvbmQgcm93OgoKIExlZnQgfCBSaWdodCB8IENlbnRlciAgCiA6LS0tIHwgLS0tLTogfCA6LS0tOiAgIAogMy4yICB8IDQuNSAgIHwgNi43IAoKCjQuIE1ha2UgYSB0YWJsZSBiZWxvdyB3aXRoIDQgY29sdW1ucyBsYWJlbGVkIENvbHVtbiAxLCBDb2x1bW4gMiwgZXRjLiwgYW5kIDMgcm93cy4gUHV0IHRoZSBudW1iZXJzIDEtMTIgaW4gdGhlIGNlbGxzLiBDZW50ZXIgYWxsIHRoZSBjb250ZW50LgoKQ29sdW1uIDEgIHwgQ29sdW1uIDIgfCBDb2x1bW4gMyAgfCBDb2x1bW4gNAotLS0tLS0tLS0gfCAtLS0tLS0tLS0gIHwgLS0tLS0tLS0tIHwgLS0tLS0tLS0tIAoxfCAyICB8IDMgfCA0ICAKNSB8IDYgIHwgNyB8IDggCjkgfCAxMCAgfCAxMSB8IDEyIAoKVGhlIGNvZGUgY2h1bmtzIHdlIGhhdmUgYmVlbiB1c2luZyBhcmUgcGFydCBvZiBSIG1hcmtkb3duOgpgYGB7cn0KOCArIDcKYGBgCgpZb3UgY2FuIHN1cHByZXNzIHRoZSBjb2RlIHNvIGl0IHJ1bnMgYW5kIHNob3dzIHRoZSBvdXRwdXQgYnV0IGRvZXMgbm90IGRpc3BsYXkgYW55IFIgY29kZSB3aGVuIHB1Ymxpc2hlZCBieSBwdXR0aW5nIGVjaG89RkFMU0UgaW4gdGhlIGJyYWNrZXRzOgoKYGBge3IgZWNobz1GQUxTRX0KOCArIDcKYGBgCgpJZiB5b3UgdXNlIGluY2x1ZGU9RkFMU0UgaW4gdGhlIGJyYWNrZXRzLCBpdCB3aWxsIHJ1biB0aGUgY29kZSwgYnV0IG5vdCBzaG93IHRoZSBvdXRwdXQgb3IgdGhlIGNvZGUuIFlvdSBtaWdodCBkbyB0aGF0IGlmIHlvdSBuZWVkIHRvIHJ1biBzb21lIGNhbGN1bGF0aW9ucyBmb3IgbGF0ZXIgdXNlIGJ1dCBkb24ndCB3YW50IHRvIHNob3cgdGhvc2UgaW50ZXJtZWRpYXRlIHN0ZXBzLiAKCjUuIFB1dCB4IDwtIDMgaW50byBhIGNvZGUgY2h1bmsgYmVsb3csIHVzZSBpbmNsdWRlPUZBTFNFLCBhbmQgcnVuIGl0IGJlbG93OgoKYGBge3IgaW5jbHVkZT1GQUxTRX0KeCA8LSAzCmBgYAoKCgpZb3UgY2FuIGluc2VydCBSIGNvZGUgd2l0aG91dCBhIGNodW5rIGJ5IHN1cnJvdW5kaW5nIGl0IGluIGJhY2t0aWNrcyBhbmQgdXNpbmcgdGhlIGxldHRlciByLCBsaWtlIHRoaXM6IDEzIHNxdWFyZWQgPSBgciAxM14yYAoKCjYuIFR5cGUgMTE2LzcgPSBhbmQgdGhlbiBjYWxjdWxhdGUgdGhlIGFuc3dlciB1c2luZyB0aGUgbWV0aG9kIGFib3ZlLgoxMTYvNyA9IGByIDExNi83CgoKCgpUaG9zZSBhcmUgc29tZSBvZiB0aGUgYmFzaWNzLiBTZWUgaGVyZSBmb3IgYSB3aG9sZSBib29rIGFib3V0IFIgTWFya2Rvd246IGh0dHBzOi8vYm9va2Rvd24ub3JnL3lpaHVpL3JtYXJrZG93bi8KCgpOb3cgbGV0J3MgZ2V0IG9uIHdpdGggdGhlIGFuYWx5c2lzIG9mIHRoZSBQZXcgZGF0YS4KCgoKCgoKIyMjIEFuYWx5c2lzIG9mIHRoZSBQZXcgZGF0YQoKCgpUaGlzIHJlYWRzIGluIHRoZSBkYXRhc2V0IGFmdGVyIGl0IGhhcyBiZWVuIHVwbG9hZGVkIHRvIEZpbGVzOgoKYGBge3J9CnBldyA8LSByZWFkX2NzdigiSmFudWFyeSAzLTEwLCAyMDE4IC0gQ29yZSBUcmVuZHMgU3VydmV5L0phbnVhcnkgMy0xMCwgMjAxOCAtIENvcmUgVHJlbmRzIFN1cnZleSAtIENTVi5jc3YiKQpgYGAKCgoKVXNlIGdsaW1wc2UoKSBvbiB0aGUgcGV3IGRhdGFzZXQgdG8gZ2V0IGFuIG92ZXJ2aWV3IG9mIHRoZSBkYXRhLiBEbyB0aGF0IGJlbG93OgoKYGBge3J9CmdsaW1wc2UocGV3KQoKCmBgYAoKClRoZXNlIHZhcmlhYmxlcyBjb3JyZXNwb25kIHRvIHF1ZXN0aW9ucyBvbiBhIHN1cnZleSwgbGlrZSB0aGUgc2V4IG9mIHRoZSByZXNwb25kZW50LiBUaGV5IGFyZSBtb3N0bHkgY29kZWQgYXMgbnVtYmVycywgbGlrZSBzZXg6IE1hbGUgPSAxLCBGZW1hbGUgPSAyLiAgCgpDYXRlZ29yaWNhbCB2YXJpYWJsZXMgbGlrZSB0aGVzZSBhcmUgYmV0dGVyIHJlcHJlc2VudGVkIGFzIGZhY3RvcnMgaW4gUi4gWW91IGNhbiBjb252ZXJ0IGEgdmFyaWFibGUgaW50byBhIGZhY3RvciB3aXRoIG11dGF0ZSgpIGFuZCBhcy5mYWN0b3IoKS4gTm90aWNlIHRoYXQgeW91IG5lZWQgdG8gdXNlIHRoZSBhcnJvdyA8LSB0byBwdXQgdGhlIG5ldyBtdXRhdGVkIHZhcmlhYmxlIGJhY2sgaW50byB0aGUgb3JpZ2luYWwuCgpUaGVuIHlvdSBjYW4gdXNlIGNvdW50KCkgdG8gc2VlIGhvdyBtYW55IG9mIGVhY2ggY2F0ZWdvcnkgYXBwZWFyIGluIHRoZSB2YXJpYWJsZToKCmBgYHtyfQpwZXcgPC0gcGV3ICU+JSAKICBtdXRhdGUoc2V4ID0gYXMuZmFjdG9yKHNleCkpCgoKcGV3ICU+JSAKICBjb3VudChzZXgpCmBgYAoKTmV4dCwgd2Ugd2FudCB0byBjaGFuZ2UgdGhlIGxldmVsIG5hbWVzIHRvIHNvbWV0aGluZyBtb3JlIGRlc2NyaXB0aXZlIHRoYW4gMSBhbmQgMi4gVGhlIGNvZGVib29rIHNheSB0aGF0IDEgPSBNYWxlIGFuZCAyID0gRmVtYWxlLiBXZSB1c2UgZmN0X3JlY29kZSgpIHRvIGRvIHRoaXMuIAoKYGBge3J9CnBldyA8LSBwZXcgJT4lIAogIG11dGF0ZShzZXggPSBmY3RfcmVjb2RlKHNleCwgIk1hbGUiID0gIjEiLCAiRmVtYWxlIiA9ICIyIikpCgpwZXcgJT4lIAogIGNvdW50KHNleCkKYGBgCgoKQW5vdGhlciB2YXJpYWJsZSwgY2FsbGVkIGludGZyZXEsIGFza2VkICJBYm91dCBob3cgb2Z0ZW4gZG8geW91IHVzZSB0aGUgaW50ZXJuZXQ/IiBQb3NzaWJsZSByZXNwb25zZXMgYXJlIDE6IEFsbW9zdCBjb25zdGFudGx5LCAyOiBTZXZlcmFsIHRpbWVzIGEgZGF5LCAzOiBBYm91dCBvbmNlIGEgZGF5LCA0OiBTZXZlcmFsIHRpbWVzIGEgd2VlaywgNTogTGVzcyBvZnRlbiwgODogRG9uJ3Qga25vdywgOTogUmVmdXNlZCB0byBhbnN3ZXIuIChUaG9zZSBhcmUgbGlzdGVkIGluIHRoZSBRdWVzdGlvbm5haXJlIGRvY3VtZW50LikKCkZpcnN0LCBqdXN0IGNvbnZlcnQgaXQgaW50byBhIGZhY3RvciBhbmQgbG9vayBhdCB0aGUgbGV2ZWxzLCBhbmQgdGhlbiBjb3VudCB0aGUgbGV2ZWxzLiAoRG9uJ3QgcmVjb2RlIHlldCwgd2UnbGwgZG8gdGhhdCBiZWxvdy4pICBDcmVhdGUgYSBjaHVuayBiZWxvdyBhbmQgdXNlIHRoZSBzYW1lIHByb2NlZHVyZSBhcyBhYm92ZSB0byBjb252ZXJ0IHNleCB0byBhIGZhY3RvciBhbmQgY291bnQgdGhlIGxldmVsczogICAKCmBgYHtyfQpwZXcgPC0gcGV3ICU+JSAKICBtdXRhdGUoaW50ZnJlcSA9IGFzLmZhY3RvcihpbnRmcmVxKSkKCgpwZXcgJT4lIAogIGNvdW50KGludGZyZXEpCmBgYAoKCgoKCgoKCgpIZXJlIGlzIHRoZSBjb2RlIGZvciBjb252ZXJ0aW5nIGVhY2ggbnVtYmVyIHRvIGEgdmVyYmFsIGxhYmVsLiBZb3UgZG9uJ3QgaGF2ZSB0byBzcGxpdCB0aGUgY29tbWFuZCBvbnRvIG11bHRpcGxlIGluZGVudGVkIGxpbmVzIGxpa2UgSSd2ZSBkb25lLCBidXQgaXQgbWFrZXMgaXQgZWFzaWVyIHRvIHJlYWQuIFRoZXJlIGFyZSB0d28gbWlzc2luZyBkYXRhIG51bWJlcnM6IDggZm9yICJEb24ndCBrbm93IiBhbmQgOSBmb3IgIlJlZnVzZWQgdG8gYW5zd2VyLiIgTGV0J3MganVzdCBnZXQgcmlkIG9mIGJvdGggb2YgdGhvc2UgYnkgc2V0dGluZyB0aGVtIHRvIE5VTEwuIFRoZXkgd2lsbCBhcHBlYXIgYXMgbWlzc2luZyBkYXRhIHdoaWNoIHdlIGNhbiBleGNsdWRlIGxhdGVyLiBJbiBhZGRpdGlvbiwgbGV0J3MgY2hhbmdlIHRoZSBuYW1lIG9mIHRoZSB2YXJpYWJsZSB0byBzb21ldGhpbmcgbW9yZSBtZWFuaW5nZnVsIGxpa2UgaW50ZXJuZXRfdXNlLgoKYGBge3J9CnBldyA8LSBwZXcgJT4lCiAgbXV0YXRlKGludGVybmV0X3VzZSA9IGZjdF9yZWNvZGUoaW50ZnJlcSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkFsbW9zdCBjb25zdGFudGx5IiA9ICIxIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNldmVyYWwgdGltZXMvZGF5IiA9ICIyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk9uY2UgcGVyIGRheSIgPSAiMyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJTZXZlcmFsIHRpbWVzL3dlZWsiID0gIjQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTGVzcyB0aGFuIG9uY2UvZGF5IiA9ICI1IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCA9ICI4IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCA9ICI5IikpCgpwZXcgJT4lIAogIGNvdW50KGludGVybmV0X3VzZSkKYGBgCgoKQSB2ZXJ5IGNvbW1vbiB3YXkgdG8gbG9vayBhdCBzdXJ2ZXkgZGF0YSBpcyB3aXRoIGNyb3NzdGFicywgaS5lLiwgb25lIGNhdGVnb3JpY2FsIHZhcmlhYmxlIGNyb3NzZWQgd2l0aCBhbm90aGVyLiBJZiB3ZSB3YW50IHRvIHNlZSBob3cgb2Z0ZW4gTWFsZXMgYW5kIEZlbWFsZXMgc2F5IHRoZXkgdXNlIHRoZSBpbnRlcm5ldCwgd2UgY2FuIG1ha2UgYSB0YWJsZSBvZiB0aGUgY291bnRzIGluIGVhY2ggY2F0ZWdvcnk6CgpgYGB7cn0KcGV3ICU+JSAKICBjb3VudChzZXgsIGludGVybmV0X3VzZSkKYGBgCgpUbyBkcm9wIHRoZSBtaXNzaW5nIGRhdGEsIHVzZSBkcm9wX25hKCkuIENvcHkgYW5kIHBhc3RlIHRoZSBjb2RlIGZvcm0gdGhlIGNodW5rIGFib3ZlLCBhbmQgYWRkIHRoZSBsaW5lIGRyb3BfbmEoaW50ZXJuZXRfdXNlKS4gRG9uJ3QgZm9yZ2V0IHRoZSBwaXBlOgoKYGBge3J9CnBldyAlPiUgCiAgY291bnQoc2V4LCBpbnRlcm5ldF91c2UpCiAgZHJvcF9uYShpbnRlcm5ldF91c2UpCnBldyAlPiUKYGBgCgoKCgoKCgoKIyMjIEdyYXBoIHZhcmlhdGlvbnMKCkEgZ3JhcGggd291bGQgYmUgbXVjaCBlYXNpZXIgdG8gcmVhZCB0aGFuIGEgdGFibGUuIAoKYGBge3J9CnBldyAlPiUgCiAgZHJvcF9uYShpbnRlcm5ldF91c2UpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBpbnRlcm5ldF91c2UsIGZpbGwgPSBzZXgpKSArCiAgZ2VvbV9iYXIoKQpgYGAKClRoZSB2aXJpZGlzIGNvbG9yIHBhbGV0dGUgaXMgY29uc2lkZXJlZCBieSBtb3N0IHBlb3BsZSB0byBiZSBuaWNlciB0aGFuIHRoZSBkZWZhdWx0IGdncGxvdCBjb2xvcnMuIENvcHktcGFzdGUgdGhlIGFib3ZlIGNvZGUgY2h1bmsgYmVsb3csIGFuZDoKMS4gQWRkIHRoZSBsaW5lIHNjYWxlX2ZpbGxfdmlyaWRpc19kKCkgdG8gdGhlIGVuZCBvZiB0aGUgYWJvdmUsIGFuZCBkb24ndCBmb3JnZXQgdG8gYWRkICsgdG8gdGhlIGVuZCBvZiB0aGUgcHJldmlvdXMgbGluZS4gIAoyLiBGbGlwIGl0IHNvIHRoZSBiYXJzIGFyZSBob3Jpem9udGFsIGJ5IGluY2x1ZGluZyB0aGUgbGluZSBjb29yZF9mbGlwKCkgYXMgd2VsbC4KCmBgYHtyfQpwZXcgJT4lIAogIGRyb3BfbmEoaW50ZXJuZXRfdXNlKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gaW50ZXJuZXRfdXNlLCBmaWxsID0gc2V4KSkgKwogIGdlb21fYmFyKCkrCiAgc2NhbGVfZmlsbF92aXJpZGlzX2QoKSsKICBjb29yZF9mbGlwKCkKYGBgCgoKCgoKCgoKCgpIZXJlJ3MgYW5vdGhlciB2YXJpYXRpb24gb24gYSBiYXIgY2hhcnQgdGhhdCBtYWtlcyBpdCBlYXN5IHRvIGNvbXBhcmUgdGhlIHByb3BvcnRpb25zIG9mIGZlbWFsZXMgYW5kIG1hbGVzIGluIGVhY2ggZ3JvdXAuIAoKQ29weS1wYXN0ZSB0aGUgYWJvdmUgY2h1bmssIGFuZCB0aGVuIGluIHRoZSBwYXJlbnRoZXNlcyBvZiBnZW9tX2JhcigpLCBwdXQgcG9zaXRpb24gPSAiZmlsbCIuIAoKYGBge3J9CnBldyAlPiUgCiAgZHJvcF9uYShpbnRlcm5ldF91c2UpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBpbnRlcm5ldF91c2UsIGZpbGwgPSBzZXgpKSArCiAgZ2VvbV9iYXIocG9zaXRpb24gPSAiZmlsbCIpKwogIHNjYWxlX2ZpbGxfdmlyaWRpc19kKCkrCiAgY29vcmRfZmxpcCgpCmBgYAoKCgoKCgoKCgpBbm90aGVyIHZhcmlhdGlvbiBpcyBiZXR0ZXIgZm9yIHNlZWluZyByYXcgbnVtYmVycyByYXRoZXIgdGhhbiBwcm9wb3J0aW9uczoKCjEuIEluIHRoZSBwYXJlbnRoZXNlcyBvZiBnZW9tX2JhcigpLCBwdXQgcG9zaXRpb24gPSAiZG9kZ2UiIHRvIHBsYWNlIHRoZSBiYXJzIHJpZ2h0IG5leHQgdG8gb25lIGFub3RoZXIuIAoyLiBJIGRvbid0IGxpa2UgdGhlIGdyYXkgYmFja2dyb3VuZCBpbiBnZ3Bsb3RzLiBUbyBnaXZlIGl0IGEgd2hpdGUgYmFja2dyb3VuZCwgaW5jbHVkZSB0aGUgbGluZSB0aGVtZV9taW5pbWFsKCkuCgpgYGB7cn0KcGV3ICU+JSAKICBkcm9wX25hKGludGVybmV0X3VzZSkgJT4lIAogIGdncGxvdChhZXMoeCA9IGludGVybmV0X3VzZSwgZmlsbCA9IHNleCkpICsKICBnZW9tX2Jhcihwb3NpdGlvbiA9ICJkb2RnZSIpKwogIHNjYWxlX2ZpbGxfdmlyaWRpc19kKCkrCiAgY29vcmRfZmxpcCgpKwogIHRoZW1lX21pbmltYWwoKQpgYGAKCgoKCgoKVG8gY3JlYXRlIHNpZGUtYnktc2lkZSBncmFwaHMsIG9uZSBmb3IgbWVuIGFuZCBvbmUgZm9yIHdvbWVuLCB1c2UgZmFjZXRfd3JhcCh2YXJzKHNleCkpLiBJdCBjcmVhdGVzIHNpZGUtYnktc2lkZSBncmFwaHMgYmFzZWQgb24gd2hhdGV2ZXIgdmFyaWFibGUgb3IgdmFyaWFibGVzIHlvdSBwdXQgaW50byB2YXJzKCkuCgpJbiBhZGRpdGlvbiwgY3JlYXRlIHNvbWUgYmV0dGVyIGxhYmVscyB3aXRoIGxhYnMoKS4gSW5jbHVkZSBsYWJzKHkgPSAiTnVtYmVyIG9mIHBlb3BsZSIsIHggPSAiSG93IG9mdGVuIGRvIHlvdSB1c2UgdGhlIGludGVybmV0IiwgdGl0bGUgPSAiRnJlcXVlbmN5IG9mIEludGVybmV0IFVzYWdlIikuIFJlbWVtYmVyIHRoYXQgd2UgZmxpcHBlZCB0aGUgY29vcmRpbmF0ZXMsIHNvIHRoZSB4IGFuZCB5IGF4ZXMgYXJlIGZsaXBwZWQhIFJ1biB0aGUgY29kZSBiZWxvdzoKCmBgYHtyfQpwZXcgJT4lIAogIGRyb3BfbmEoaW50ZXJuZXRfdXNlKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gaW50ZXJuZXRfdXNlKSkgKwogIGdlb21fYmFyKCkgKwogIGZhY2V0X3dyYXAodmFycyhzZXgpKSArCiAgY29vcmRfZmxpcCgpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIGxhYnMoeSA9ICJOdW1iZXIgb2YgcGVvcGxlIiwgCiAgICAgICB4ID0gIkhvdyBvZnRlbiBkbyB5b3UgdXNlIHRoZSBpbnRlcm5ldCIsIAogICAgICAgdGl0bGUgPSAiRnJlcXVlbmN5IG9mIEludGVybmV0IFVzYWdlIikKYGBgCgoKCiMjIyBDb2xsYXBzaW5nIGxldmVscwoKWW91IG1pZ2h0IGFsc28gd2FudCB0byBjb21iaW5lIHNvbWUgb2YgdGhlIGxldmVscy4gSW4gb3VyIGV4YW1wbGUsIHdlIG1pZ2h0IGNvbGxhcHNlIHRoZSA1IGxldmVzIG9mIEludGVybmV0IHVzZSBkb3duIHRvIGp1c3QgMjogTW9yZSB0aGFuIG9uY2UgcGVyIGRheSB2cy4gb25jZSBwZXIgZGF5IG9yIGxlc3MuIFVzZSBmY3RfY29sbGFwc2UoKSB0byBkbyB0aGF0LiBUaGUgZm9sbG93aW5nIGNvZGUgZG9lcyB0aGlzIGFuZCBwdXRzIGl0IGludG8gYSBuZXcgdmFyaWFibGUgY2FsbGVkIGludGVybmV0X3VzZV9zaW1wbGUuIAoKYGBge3J9CnBldyA8LSBwZXcgJT4lIAogIG11dGF0ZShpbnRlcm5ldF91c2Vfc2ltcGxlID0gZmN0X2NvbGxhcHNlKGludGVybmV0X3VzZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYWlseV9vcl9sZXNzID0gYygiT25jZSBwZXIgZGF5IiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNldmVyYWwgdGltZXMvd2VlayIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJMZXNzIHRoYW4gb25jZS9kYXkiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtb3JlX3RoYW5fZGFpbHkgPSBjKCJTZXZlcmFsIHRpbWVzL2RheSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkFsbW9zdCBjb25zdGFudGx5IikpKQoKcGV3ICU+JSAKICBjb3VudChpbnRlcm5ldF91c2Vfc2ltcGxlKQpgYGAKCk5vdyByZS1jcmVhdGUgdGhlIHBvc2l0aW9uID0gImZpbGwiIGdyYXBoIGZyb20gYWJvdmUsIGJ1dCB3aXRoIGludGVybmV0X3VzZV9zaW1wbGUuCgpgYGB7cn0KcGV3ICU+JSAKICBkcm9wX25hKGludGVybmV0X3VzZV9zaW1wbGUpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBpbnRlcm5ldF91c2Vfc2ltcGxlLCBmaWxsID0gc2V4KSkgKwogIGdlb21fYmFyKHBvc2l0aW9uID0gImRvZGdlIikrCiAgc2NhbGVfZmlsbF92aXJpZGlzX2QoKSsKICBjb29yZF9mbGlwKCkrCiAgdGhlbWVfbWluaW1hbCgpCmBgYAoKCgoKCgoKCgoKCgoKCgoKCgoKCgojIyMgQXNzaWdubWVudAoKVGhlIGZvbGxvd2luZyB2YXJpYWJsZXMgYXJlIGluIHRoZSBwZXcgZGF0YXNldDoKCndlYjFhOiBUd2l0dGVyCndlYjFiOiBJbnN0YWdyYW0Kd2ViMWM6IEZhY2Vib29rCndlYjFkOiBTbmFwY2hhdAp3ZWIxZTogWW91dHViZQoKVGhleSBhcmUgYWxsIGNvZGVkIGFzIHRvIHdoZXRoZXIgcmVzcG9uZGVudHMgdXNlIHRoYXQgc29jaWFsIG1lZGlhIHNpdGUsIHdpdGggKCJZZXMiID0gIjEiLCAiTm8iID0gIjIiLCAiRG9uJ3Qga25vdyIgPSAiOCIsICJSZWZ1c2VkIiA9ICI5IikuCgplZHVjMiBpcyB0aGUgcmVzcG9uZGVudHMnIGVkdWNhdGlvbiBsZXZlbCAoIkxlc3MgdGhhbiBIUyIgPSAiMSIsICJTb21lIEhTIiA9ICIyIiwgIkhTIGdyYWR1YXRlIiA9ICIzIiwgIlNvbWUgY29sbGVnZSIgPSAiNCIsICJBc3NvY2lhdGUgZGVncmVlIiA9ICI1IiwgIkNvbGxlZ2UgZGVncmVlIiA9ICI2IiwgIlNvbWUgZ3JhZCBzY2hvb2wiID0gIjciLCAiR3JhZCBkZWdyZWUiID0gIjgiLCAiRG9uJ3Qga25vdyIgPSAiOTgiLCAiUmVmdXNlZCIgPSAiOTkiKS4KCldoZW4geW91IHJlY29kZSB5b3UgY2FuIHVzZSB0aGUgbGlzdCBvZiByZWNvZGluZ3MgaW4gdGhlIHBhcmVudGhlc2VzIGFib3ZlLiBJIHJlY29tbWVuZCBjaGFuZ2luZyB0aGUgIkRvbid0IGtub3ciIGFuZCAiUmVmdXNlZCIgdG8gTlVMTC4KCgoxLiBDaG9vc2Ugb25lIG9mIHRoZSB3ZWIxIHZhcmlhYmxlcywgY29udmVydCBpdCB0byBhIGZhY3RvciwgYW5kIHJlY29kZSBpdC4KMi4gQWxzbyBjb252ZXJ0IGFuZCByZWNvZGUgZWR1YzIuICAKMy4gQ3JlYXRlIGEgdGFibGUgb2YgdGhlIGNvdW50cyBvZiBlYWNoIHZhcmlhYmxlLCBhbmQgb2YgYm90aCBzaW11bHRhbmVvdXNseS4gICAgCjQuIENyZWF0ZSBhIGdyYXBoIG9mIHlvdXIgY2hvaWNlIHNob3dpbmcgdGhlIHR3byB2YXJpYWJsZXMuICAKNS4gQ29sbGFwc2UgZWR1YzIgaW50byBqdXN0IHR3byBjYXRlZ29yaWVzIG9mIHlvdXIgY2hvaWNlLCBhbmQgcmUtcnVuIHRoZSB0YWJsZSBhbmQgZ3JhcGguICAKNi4gUHVibGlzaCB0byBSUHVicywgbWFraW5nIHN1cmUgeW91IHByZXNlbnQgdGhlIHJlc3VsdHMgd2l0aCBleHBsYW5hdGlvbiBhbmQgaW4gYW4gdW5kZXJzdGFuZGFibGUgd2F5LCBpbmNsdWRpbmcgZ3JhcGggdGl0bGVzIGFuZCBsYWJlbGVkIGF4ZXMuCgpgYGB7cn0KcGV3IDwtIHBldyAlPiUgCiAgbXV0YXRlKHR3aXR0ZXIgPSBhcy5mYWN0b3Iod2ViMWEpKQoKCnBldyAlPiUgCiAgY291bnQodHdpdHRlcikKcGV3IDwtIHBldyAlPiUgCiAgbXV0YXRlKHR3aXR0ZXIgPSBmY3RfcmVjb2RlKHR3aXR0ZXIsICJ5ZXMiID0gIjEiLCAibm8iID0gIjIiLCBOVUxMID0gIjgiLCBOVUxMID0gIjkiKSkKCnBldyAlPiUgCiAgY291bnQodHdpdHRlcikKCnBldyA8LSBwZXcgJT4lIAogIG11dGF0ZShlZHVjID0gYXMuZmFjdG9yKGVkdWMyKSkKCgpwZXcgJT4lIAogIGNvdW50KGVkdWMpCnBldyA8LSBwZXcgJT4lIAogIG11dGF0ZShlZHVjID0gZmN0X3JlY29kZShlZHVjLCAiTGVzcyB0aGFuIEhTIiA9ICIxIiwgIlNvbWUgSFMiID0gIjIiLCAiSFMgZ3JhZHVhdGUiID0gIjMiLCAiU29tZSBjb2xsZWdlIiA9ICI0IiwgIkFzc29jaWF0ZSBkZWdyZWUiID0gIjUiLCAiQ29sbGVnZSBkZWdyZWUiID0gIjYiLCAiU29tZSBncmFkIHNjaG9vbCIgPSAiNyIsICJHcmFkIGRlZ3JlZSIgPSAiOCIsICJEb24ndCBrbm93IiA9ICI5OCIsICJSZWZ1c2VkIiA9ICI5OSIpKQoKcGV3ICU+JSAKICBjb3VudChlZHVjKQpwZXcgJT4lIAogIGRyb3BfbmEodHdpdHRlcikgJT4lIAogIGdncGxvdChhZXMoeCA9IHR3aXR0ZXIpKSArCiAgZ2VvbV9iYXIoKSArCiAgZmFjZXRfd3JhcCh2YXJzKHNleCkpICsKICBjb29yZF9mbGlwKCkgKwogIHRoZW1lX21pbmltYWwoKSArCiAgbGFicyh5ID0gIk51bWJlciBvZiBwZW9wbGUiLCAKICAgICAgIHggPSAiRG8geW91IHVzZSBUd2l0dGVyIiwgCiAgICAgICB0aXRsZSA9ICJGcmVxdWVuY3kgb2YgVHdpdHRlciBVc2FnZSIpCmBgYApgYGB7cn0KcGV3ICU+JSAKICBkcm9wX25hKGVkdWMpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBlZHVjLCBmaWxsID0gdHdpdHRlcikpICsKICBnZW9tX2Jhcihwb3NpdGlvbiA9ICJkb2RnZSIpKwogIHNjYWxlX2ZpbGxfdmlyaWRpc19kKCkrCiAgY29vcmRfZmxpcCgpKwogIHRoZW1lX21pbmltYWwoKQogIGBgYApgYGB7cn0KcGV3ICU+JSAKICBkcm9wX25hKGVkdWMpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBlZHVjKSkgKwogIGdlb21fYmFyKCkgKwogIGZhY2V0X3dyYXAodmFycyh0d2l0dGVyKSkgKwogIGNvb3JkX2ZsaXAoKSArCiAgdGhlbWVfbWluaW1hbCgpICsKICBsYWJzKHkgPSAiTnVtYmVyIG9mIHBlb3BsZSIsIAogICAgICAgeCA9ICJlZHVjYXRpb24gbGV2ZWwiLCAKICAgICAgIHRpdGxlID0gImVkdWNhdGlvbiBsZXZlbHMiKQoKYGBgCgpgYGB7cn0KcGV3IDwtIHBldyAlPiUgCiAgbXV0YXRlKGVkdWMxID0gZmN0X3JlY29kZShlZHVjLCAiTGVzcyB0aGFuIEhTIiA9ICIxIiwgIlNvbWUgSFMiID0gIjIiLCBOVUxMID0gIjMiLCBOVUxMID0gIjQiKSkKCnBldyAlPiUKICBjb3VudChlZHVjMSkKYGBgCgoKCgoKCgpIZXJlIGFyZSBhIGZldyBhZGRpdGlvbmFsIHZhcmlhYmxlcy4gWW91IGRvIG5vdCBuZWVkIHRvIHVzZSB0aGVzZSwgYnV0IEkgaGFkIHRoZSBjb2RpbmcgZm9yIHRoZW0gc28gSSB0aG91Z2h0IEknZCBpbmNsdWRlIHRoZW0gZm9yIGNvbXBsZXRlbmVzcy4KCmhvbWU0bnc6IERvIHlvdSBjdXJyZW50bHkgc3Vic2NyaWJlIHRvIGludGVybmV0IHNlcnZpY2UgYXQgaG9tZT8gMSA9IFllcywgMiA9IE5vLCA4ID0gRG9uJ3Qga25vdywgOSA9IFJlZnVzZWQKCgpEbyB5b3UgdXNlIHRoZSBmb2xsb3dpbmcgc29jaWFsIG1lZGlhIHNpdGVzOiAgICgxID0gWWVzLCAyID0gTm8pCndlYjFhOiBUd2l0dGVyCndlYjFiOiBJbnN0YWdyYW0Kd2ViMWM6IEZhY2Vib29rCndlYjFkOiBTbmFwY2hhdAp3ZWIxZTogWW91dHViZQoKCkhvdyBoYXJkIHdvdWxkIGl0IGJlIGZvciB5b3UgdG8gZ2l2ZSB1cC4uLiAgCjEgPSBWZXJ5IGhhcmQsIDIgPSBTb21ld2hhdCBoYXJkLCAzID0gTm90IHRvbyBoYXJkLCA0ID0gTm90IGhhcmQgYXQgYWxsLCA1ID0gSW1wb3NzaWJsZSwgNiA9IERvIG5vdCB1c2UsIDggPSBEb24ndCBrbm93LCA5ID0gUmVmdXNlZApwaWFsNWE6IFRlbGV2aXNpb24KcGlhbDViOiBDZWxsIHBob25lCnBpYWw1YzogSW50ZXJuZXQKcGlhbDVkOiBTb2NpYWwgbWVkaWEKCgpwaWFsMTE6CldvdWxkIHlvdSBzYXkgdGhlIGludGVybmV0IGhhcyBtb3N0bHkgYmVlbiBhIEdPT0QgdGhpbmcgb3IgYSBCQUQgdGhpbmcgZm9yIHNvY2lldHk/CjEgPSBHb29kIHRoaW5nLCAyID0gQmFkIHRoaW5nLCAzID0gU29tZSBvZiBib3RoLCA4ID0gRG9uJ3Qga25vdywgOSA9IFJlZnVzZWQKCgpwaWFsMTIKSG93IGFib3V0IHlvdSwgcGVyc29uYWxseT8gT3ZlcmFsbCwgd2hlbiB5b3UgYWRkIHVwIGFsbCB0aGUgYWR2YW50YWdlcyBhbmQgCWRpc2FkdmFudGFnZXMgb2YgdGhlIGludGVybmV0LCB3b3VsZCB5b3Ugc2F5IHRoZSBpbnRlcm5ldCBoYXMgbW9zdGx5IGJlZW4gYSBHT09EIHRoaW5nIG9yIGEgQkFEIHRoaW5nIGZvciAJeW91PyAKMSA9IEdvb2QgdGhpbmcsIDIgPSBCYWQgdGhpbmcsIDMgPSBTb21lIG9mIGJvdGgsIDggPSBEb24ndCBrbm93LCA5ID0gUmVmdXNlZAoKCm1hcml0YWwKMSA9IE1hcnJpZWQsIDIgPSBMaXZpbmcgd2l0aCBhIHBhcnRuZXIsIDMgPSBEaXZvcmNlZCwgNCA9IFNlcGFyYXRlZCwgNSA9IFdpZG93ZWQsIDYgPSBOZXZlciBtYXJyaWVkLCA4ID0gRG9uJ3Qga25vdywgOSA9IFJlZnVzZWQKCgplbXBsbncKMSA9IEVtcGxveWVkIGZ1bGwgdGltZSwgMiA9IEVtcGxveWVkIHBhcnQtdGltZSwgMyA9IFJldGlyZWQsIDQgPSBOb3QgZW1wbG95ZWQsIDUgPSBTZWxmLWVtcGxveWVkLCA2ID0gRGlzYWJsZWQsIDcgPSBTdHVkZW50LCA4ID0gT3RoZXIsIDk4ID0gRG9uJ3Qga25vdywgOTkgPSBSZWZ1c2Vk