1 Loading packages

## Use the code below to check if you have all required packages installed. If some are not installed already, the code below will install these. If you have all packages installed, then you could load them with the second code.
requiredPackages = c('tidyverse', 'languageR')
for(p in requiredPackages){
  if(!require(p,character.only = TRUE)) install.packages(p)
  library(p,character.only = TRUE)
}

2 The Tidyverse

2.1 Introduction

The Tidyverse is a family of packages used to speed up the use of R.

You need to first install it (if you haven’t already done so) and then load it. To install, use Tools > Install packages or install.packages() then add tidyverse. To load a package, use the library() function.

Look at how many packages are installed within the Tidyverse. The messages you see are telling you which packages are loaded and which functions are in conflict (i.e., these are functions from other packages that are found within the Tidyverse). If you want to use the original function, simply add package_name::function.

2.1.1 Using piping

The difference between base R and the Tidyverse’s way of doing things is that base R can sometimes be more complex, while tidyverse is more straightforward and allows you to “see” within a dataframe easily. You need to learn how to use the “pipe” in magrittr that is part of the Tidyverse.

Pipes are written in R as %>% (note you must use a percentage sign before and after the pipe). To demonstrate what pipes do, have a look at the following pseudocode. You can use a shortcut in your keyboard, type Ctrl+Shift+m to add a pipe (for mac users, it is Cmd+Shift+m).

Since R version 4.1.0, there is a native pipe |>. It seems to be doing almost the same thing as the %>%. We will still use %>% as this is integrated within the Tidyverse.

2.1.2 Demo subsetting

Below are two code lines for how to subset the dataframe using base R and piping from the magrittr package.

With base R, we always need to refer to the dataset twice: once at the beginning and then to look into the dataset to select a variable.

word <- c("a", "the", "lamp", "not", "jump", "it", "coffee", "walk", "on")
freq <- c(500, 600, 7, 200, 30, 450, 130, 33, 300)  # note this is completely made up!!
functionword <- c("y", "y", "n", "y", "n", "y", "n", "n", "y")
length <- c(1, 3, 4, 3, 4, 2, 6, 4, 2)
df <- as.data.frame(cbind(word,freq,functionword,length))
rm(word,freq,functionword,length)
df$functionword <- as.character(df$functionword)
df$functionword[df$functionword == "y"] <- "yes"
df$functionword[df$functionword == "no"] <- "no"
df$functionword <- as.factor(df$functionword)
df_Yes1 <- df[which(df$functionword == 'yes'),]
df_Yes1

With the pipe, you only need to specify the dataset once: By adding the pipe, you can already look into the dataset and select the variable you need.

df_Yes1_pipe_tidy <- df %>% filter(functionword =='yes')
df_Yes1_pipe_tidy

And this is with the base R pipe (combined with code from the Tidyverse family)

df_Yes1_pipe_base <- df |> filter(functionword =='yes')
df_Yes1_pipe_base

As you can see, using the pipe (either within the Tidyverse or with base R) is a quick and easy way to do various operations.

Out of convenience and because we will use other packages integrated within the Tidyverse, we will use its pipe.

ReCap:

  • %>% is called a “pipe”
  • It passes the previous line into the data argument of the next line
  • It does not save any changes after output
  • If you want to save the output of a particular manipulation, simply save it with xx <-

2.2 Basic manipulations

We will use the pipe with the Tidyverse to obtain summaries. We will use an R built-in dataset. Type data() to see the full list of datasets installed by default in R. You can use data(package = .packages(all.available = TRUE)) to see all datasets installed within all packages.

2.2.1 First steps

Here is a list of all available datasets

data()
data(package = .packages(all.available = TRUE))

2.2.2 Loading dataset

We will use the dataset english from the package languageR. This is a package that contains many linguistically-oriented datasets. See details of the dataset here. Or by typing ?languageR::english (or simply ?english if the package is already loaded) in the console.

You can load the dataset after loading the package. Simply refer to it by its name.

?english

2.2.3 View

To see the dataset, run the code below to visualise it.

english %>% 
  View()
# or without pipe
View(english)

2.2.4 Structure

We can use str() to look at the structure of the dataset. Here we have a relatively large dataset with 4568 observations (=rows) and 36 variables (=columns).

english %>% 
  str()
'data.frame':   4568 obs. of  36 variables:
 $ RTlexdec                       : num  6.54 6.4 6.3 6.42 6.45 ...
 $ RTnaming                       : num  6.15 6.25 6.14 6.13 6.2 ...
 $ Familiarity                    : num  2.37 4.43 5.6 3.87 3.93 3.27 3.73 5.67 3.1 4.43 ...
 $ Word                           : Factor w/ 2197 levels "ace","act","add",..: 467 2124 1838 1321 1302 1347 434 468 15 1632 ...
 $ AgeSubject                     : Factor w/ 2 levels "old","young": 2 2 2 2 2 2 2 2 2 2 ...
 $ WordCategory                   : Factor w/ 2 levels "N","V": 1 1 1 1 1 1 1 1 1 1 ...
 $ WrittenFrequency               : num  3.91 4.52 6.51 5.02 4.89 ...
 $ WrittenSpokenFrequencyRatio    : num  1.022 0.35 2.089 -0.526 -1.045 ...
 $ FamilySize                     : num  1.39 1.39 1.61 1.95 2.2 ...
 $ DerivationalEntropy            : num  0.141 0.427 0.062 0.43 0.359 ...
 $ InflectionalEntropy            : num  0.0211 0.942 1.4434 0 1.7539 ...
 $ NumberSimplexSynsets           : num  0.693 1.099 2.485 1.099 2.485 ...
 $ NumberComplexSynsets           : num  0 0 1.95 2.64 2.48 ...
 $ LengthInLetters                : int  3 5 6 4 4 4 4 3 3 5 ...
 $ Ncount                         : int  8 5 0 8 3 9 6 13 3 3 ...
 $ MeanBigramFrequency            : num  7.04 9.54 9.88 8.31 7.94 ...
 $ FrequencyInitialDiphone        : num  12 12.6 13.3 12.1 11.9 ...
 $ ConspelV                       : int  10 20 10 5 17 19 10 13 1 7 ...
 $ ConspelN                       : num  3.74 7.87 6.69 6.68 4.76 ...
 $ ConphonV                       : int  41 38 13 6 17 21 13 7 11 14 ...
 $ ConphonN                       : num  8.84 9.78 7.04 3.83 4.76 ...
 $ ConfriendsV                    : int  8 20 10 4 17 19 10 6 0 7 ...
 $ ConfriendsN                    : num  3.3 7.87 6.69 3.53 4.76 ...
 $ ConffV                         : num  0.693 0 0 0.693 0 ...
 $ ConffN                         : num  2.71 0 0 6.63 0 ...
 $ ConfbV                         : num  3.5 2.94 1.39 1.1 0 ...
 $ ConfbN                         : num  8.83 9.61 5.82 2.56 0 ...
 $ NounFrequency                  : int  49 142 565 150 170 125 582 2061 144 522 ...
 $ VerbFrequency                  : int  0 0 473 0 120 280 110 76 4 86 ...
 $ CV                             : Factor w/ 2 levels "C","V": 1 1 1 1 1 1 1 1 2 1 ...
 $ Obstruent                      : Factor w/ 2 levels "cont","obst": 2 2 2 2 2 2 2 2 1 2 ...
 $ Frication                      : Factor w/ 4 levels "burst","frication",..: 1 2 2 1 1 1 1 1 3 2 ...
 $ Voice                          : Factor w/ 2 levels "voiced","voiceless": 1 2 2 2 2 2 1 1 1 2 ...
 $ FrequencyInitialDiphoneWord    : num  10.13 9.05 12.42 10.05 11.8 ...
 $ FrequencyInitialDiphoneSyllable: num  10.41 9.15 13.13 11 12.16 ...
 $ CorrectLexdec                  : int  27 30 30 30 26 28 30 28 25 29 ...
# or without pipe
str(english)
'data.frame':   4568 obs. of  36 variables:
 $ RTlexdec                       : num  6.54 6.4 6.3 6.42 6.45 ...
 $ RTnaming                       : num  6.15 6.25 6.14 6.13 6.2 ...
 $ Familiarity                    : num  2.37 4.43 5.6 3.87 3.93 3.27 3.73 5.67 3.1 4.43 ...
 $ Word                           : Factor w/ 2197 levels "ace","act","add",..: 467 2124 1838 1321 1302 1347 434 468 15 1632 ...
 $ AgeSubject                     : Factor w/ 2 levels "old","young": 2 2 2 2 2 2 2 2 2 2 ...
 $ WordCategory                   : Factor w/ 2 levels "N","V": 1 1 1 1 1 1 1 1 1 1 ...
 $ WrittenFrequency               : num  3.91 4.52 6.51 5.02 4.89 ...
 $ WrittenSpokenFrequencyRatio    : num  1.022 0.35 2.089 -0.526 -1.045 ...
 $ FamilySize                     : num  1.39 1.39 1.61 1.95 2.2 ...
 $ DerivationalEntropy            : num  0.141 0.427 0.062 0.43 0.359 ...
 $ InflectionalEntropy            : num  0.0211 0.942 1.4434 0 1.7539 ...
 $ NumberSimplexSynsets           : num  0.693 1.099 2.485 1.099 2.485 ...
 $ NumberComplexSynsets           : num  0 0 1.95 2.64 2.48 ...
 $ LengthInLetters                : int  3 5 6 4 4 4 4 3 3 5 ...
 $ Ncount                         : int  8 5 0 8 3 9 6 13 3 3 ...
 $ MeanBigramFrequency            : num  7.04 9.54 9.88 8.31 7.94 ...
 $ FrequencyInitialDiphone        : num  12 12.6 13.3 12.1 11.9 ...
 $ ConspelV                       : int  10 20 10 5 17 19 10 13 1 7 ...
 $ ConspelN                       : num  3.74 7.87 6.69 6.68 4.76 ...
 $ ConphonV                       : int  41 38 13 6 17 21 13 7 11 14 ...
 $ ConphonN                       : num  8.84 9.78 7.04 3.83 4.76 ...
 $ ConfriendsV                    : int  8 20 10 4 17 19 10 6 0 7 ...
 $ ConfriendsN                    : num  3.3 7.87 6.69 3.53 4.76 ...
 $ ConffV                         : num  0.693 0 0 0.693 0 ...
 $ ConffN                         : num  2.71 0 0 6.63 0 ...
 $ ConfbV                         : num  3.5 2.94 1.39 1.1 0 ...
 $ ConfbN                         : num  8.83 9.61 5.82 2.56 0 ...
 $ NounFrequency                  : int  49 142 565 150 170 125 582 2061 144 522 ...
 $ VerbFrequency                  : int  0 0 473 0 120 280 110 76 4 86 ...
 $ CV                             : Factor w/ 2 levels "C","V": 1 1 1 1 1 1 1 1 2 1 ...
 $ Obstruent                      : Factor w/ 2 levels "cont","obst": 2 2 2 2 2 2 2 2 1 2 ...
 $ Frication                      : Factor w/ 4 levels "burst","frication",..: 1 2 2 1 1 1 1 1 3 2 ...
 $ Voice                          : Factor w/ 2 levels "voiced","voiceless": 1 2 2 2 2 2 1 1 1 2 ...
 $ FrequencyInitialDiphoneWord    : num  10.13 9.05 12.42 10.05 11.8 ...
 $ FrequencyInitialDiphoneSyllable: num  10.41 9.15 13.13 11 12.16 ...
 $ CorrectLexdec                  : int  27 30 30 30 26 28 30 28 25 29 ...

2.2.5 See first 6 rows

english %>% 
  head()
# or without pipe
head(english)

2.2.6 See last 6 rows

english %>% 
  tail()
# or without pipe
tail(english)

2.2.7 Selecting variables

Here, we select a few variables to use. For variables or columns, use the function select

english %>% 
  select(RTlexdec, RTnaming, Familiarity)
# or without pipe
select(english, RTlexdec, RTnaming, Familiarity)

2.2.8 Selecting observations

If we want to select observations, we use the function filter. We will use select to select particular variables and then use filter to select specific observations. This example shows how the pipe chain works, by combining multiple functions and using pipes

english %>% 
  select(RTlexdec, RTnaming, Familiarity, AgeSubject) %>% 
  filter(AgeSubject == "old")
# or without pipe
filter(select(english, RTlexdec, RTnaming, Familiarity, AgeSubject), AgeSubject == "old")

2.2.9 Changing order of levels

Use some of the code above to manipulate the dataframe but now using code from the Tidyverse. As you will see, once you know how to manipulate a dataset with base R, you can easily apply the same techniques with the Tidyverse. The Tidyverse provides additional ways to manipulate a dataframe.

For example, if I want to check levels of a variable and change the reference level, I will use the following code

levels(english$AgeSubject)
[1] "old"   "young"

To change levels of AgeSubject, we need to save a new dataset (do not override the original dataset!!). The mutate function means we are manipulating an object.

english2<- english %>% 
  mutate(AgeSubject = factor(AgeSubject, levels = c("young", "old")))
# or without pipe
english2 <- mutate(english, AgeSubject = factor(AgeSubject, levels = c("young", "old")))

levels(english2$AgeSubject)
[1] "young" "old"  

2.2.10 Changing reference value

You can change the reference value by using fct_relevel. This is useful if you have many levels in one of the factors you are working with and you simply need to change the reference.

english2<- english %>% 
  mutate(AgeSubject = fct_relevel(AgeSubject, "old"))
# or without pipe
english2 <- mutate(english, AgeSubject = fct_relevel(AgeSubject, "old"))

levels(english2$AgeSubject)
[1] "old"   "young"

The Tidyverse contains many functions that are useful for data manipulation. We will look at additional ones next week

2.2.11 Activity on your own 1

Use any of the other factors and try to change its levels and/or its reference level

2.3 Advanced manipulations

Sometimes, you may have a dataset that comes in a wide format (i.e., columns contain data from participants) and you want to change to long format (i.e., each row contains one observation with minimal number of columns). Let’s look at the functions pivot_longer and pivot_wider

2.3.1 Columns to rows

Let’s use the english dataset to transform it from wide to long.

english %>% 
  select(Word, RTlexdec, RTnaming, Familiarity) %>% 
  pivot_longer(cols = c(RTlexdec, RTnaming, Familiarity), # you can also add index, i.e., 2:4
               names_to = "variable",
               values_to = "values")
# or without pipe
pivot_longer(select(english, Word, RTlexdec, RTnaming, Familiarity),
             cols = c(RTlexdec, RTnaming, Familiarity), # you can also add index, i.e., 2:4
             names_to = "variable",
             values_to = "values")

2.3.2 Rows to columns

Let’s use the same code above and change the code from long format, back to wide format. Pivot_wider allows you to go back to the original dataset. You will need to use unnest to get all rows in the correct place. Try without it to see the result.

english %>% 
  select(Word, RTlexdec, RTnaming, Familiarity) %>% 
  pivot_longer(cols = c(RTlexdec, RTnaming, Familiarity), # you can also add index, i.e., 2:4
               names_to = "variable",
               values_to = "values") %>% 
  pivot_wider(names_from = "variable",
              values_from = "values")
Warning: Values are not uniquely identified; output will contain list-cols.
* Use `values_fn = list` to suppress this warning.
* Use `values_fn = length` to identify where the duplicates arise
* Use `values_fn = {summary_fun}` to summarise duplicates
# or without pipe
pivot_wider(pivot_longer(select(english, Word, RTlexdec, RTnaming, Familiarity),
                         cols = c(RTlexdec, RTnaming, Familiarity), # you can also add index, i.e., 2:4
                         names_to = "variable",
                         values_to = "values"),
            names_from = "variable",
            values_from = "values")
Warning: Values are not uniquely identified; output will contain list-cols.
* Use `values_fn = list` to suppress this warning.
* Use `values_fn = length` to identify where the duplicates arise
* Use `values_fn = {summary_fun}` to summarise duplicates

But wait, where are the results? They are added in lists. We need to use the function unnest() to obtain the full results.

english %>% 
  select(Word, RTlexdec, RTnaming, Familiarity) %>% 
  pivot_longer(cols = c(RTlexdec, RTnaming, Familiarity), # you can also add index, i.e., 2:4
               names_to = "variable",
               values_to = "values") %>% 
  pivot_wider(names_from = "variable",
              values_from = "values") %>% 
  unnest()
Warning: Values are not uniquely identified; output will contain list-cols.
* Use `values_fn = list` to suppress this warning.
* Use `values_fn = length` to identify where the duplicates arise
* Use `values_fn = {summary_fun}` to summarise duplicates
Warning: `cols` is now required when using unnest().
Please use `cols = c(RTlexdec, RTnaming, Familiarity)`
# or without pipe
unnest(pivot_wider(pivot_longer(select(english, Word, RTlexdec, RTnaming, Familiarity),
                                cols = c(RTlexdec, RTnaming, Familiarity), # you can also add index, i.e., 2:4
                                names_to = "variable",
                                values_to = "values"),
                   names_from = "variable",
                   values_from = "values"))
Warning: Values are not uniquely identified; output will contain list-cols.
* Use `values_fn = list` to suppress this warning.
* Use `values_fn = length` to identify where the duplicates arise
* Use `values_fn = {summary_fun}` to summarise duplicates
Warning: `cols` is now required when using unnest().
Please use `cols = c(RTlexdec, RTnaming, Familiarity)`

Ah that is better. But we get warnings. What does the warnings tell us? These are simple warnings and not errors. You can use the suggestions the Tidyverse makes. By default, we are told that the results are shown as lists of columns (what we are after). The second warning tells you to use a specific specification with unnest().

2.4 Basic descriptive statistics

2.4.1 Basic summaries

We can use summary() to obtain basic summaries of the dataset. For numeric variables, this will give you the minimum, maximum, mean, median, 1st and 3rd quartiles; for factors/characters, this will be the count. If there are missing values, you will get number of NAs. Look at the summaries of the dataset below.

english %>% 
  summary()
    RTlexdec        RTnaming      Familiarity         Word     
 Min.   :6.205   Min.   :6.022   Min.   :1.100   arm    :   4  
 1st Qu.:6.426   1st Qu.:6.149   1st Qu.:3.000   barge  :   4  
 Median :6.550   Median :6.342   Median :3.700   bark   :   4  
 Mean   :6.550   Mean   :6.323   Mean   :3.796   bear   :   4  
 3rd Qu.:6.653   3rd Qu.:6.490   3rd Qu.:4.570   beef   :   4  
 Max.   :7.188   Max.   :6.696   Max.   :6.970   bind   :   4  
                                                 (Other):4544  
 AgeSubject   WordCategory WrittenFrequency WrittenSpokenFrequencyRatio
 old  :2284   N:2904       Min.   : 0.000   Min.   :-6.55393           
 young:2284   V:1664       1st Qu.: 3.761   1st Qu.:-0.07402           
                           Median : 4.832   Median : 0.68118           
                           Mean   : 5.021   Mean   : 0.67763           
                           3rd Qu.: 6.247   3rd Qu.: 1.44146           
                           Max.   :11.357   Max.   : 5.63071           
                                                                       
   FamilySize     DerivationalEntropy InflectionalEntropy
 Min.   :0.6931   Min.   :0.00000     Min.   :0.0000     
 1st Qu.:1.0986   1st Qu.:0.03932     1st Qu.:0.7442     
 Median :1.7918   Median :0.41097     Median :1.0982     
 Mean   :1.8213   Mean   :0.54089     Mean   :1.1186     
 3rd Qu.:2.3026   3rd Qu.:0.89323     3rd Qu.:1.6325     
 Max.   :5.5175   Max.   :5.20728     Max.   :2.4514     
                                                         
 NumberSimplexSynsets NumberComplexSynsets LengthInLetters
 Min.   :0.000        Min.   :0.000        Min.   :2.000  
 1st Qu.:1.099        1st Qu.:0.000        1st Qu.:4.000  
 Median :1.609        Median :1.386        Median :4.000  
 Mean   :1.708        Mean   :1.568        Mean   :4.342  
 3rd Qu.:2.197        3rd Qu.:2.565        3rd Qu.:5.000  
 Max.   :4.357        Max.   :6.111        Max.   :7.000  
                                                          
     Ncount       MeanBigramFrequency FrequencyInitialDiphone
 Min.   : 0.000   Min.   : 5.390      Min.   : 4.143         
 1st Qu.: 2.000   1st Qu.: 8.100      1st Qu.:11.277         
 Median : 5.000   Median : 8.559      Median :12.023         
 Mean   : 6.266   Mean   : 8.490      Mean   :11.963         
 3rd Qu.: 9.000   3rd Qu.: 8.973      3rd Qu.:12.697         
 Max.   :22.000   Max.   :10.283      Max.   :14.654         
                                                             
    ConspelV        ConspelN         ConphonV        ConphonN     
 Min.   : 0.00   Min.   : 0.000   Min.   : 0.00   Min.   : 0.000  
 1st Qu.: 6.00   1st Qu.: 4.519   1st Qu.:10.00   1st Qu.: 5.268  
 Median :11.00   Median : 5.710   Median :16.00   Median : 6.340  
 Mean   :11.71   Mean   : 5.605   Mean   :18.26   Mean   : 6.318  
 3rd Qu.:17.00   3rd Qu.: 6.997   3rd Qu.:24.00   3rd Qu.: 7.491  
 Max.   :32.00   Max.   :10.492   Max.   :66.00   Max.   :10.600  
                                                                  
  ConfriendsV     ConfriendsN         ConffV           ConffN      
 Min.   : 0.00   Min.   : 0.000   Min.   :0.0000   Min.   : 0.000  
 1st Qu.: 4.00   1st Qu.: 4.159   1st Qu.:0.0000   1st Qu.: 0.000  
 Median :10.00   Median : 5.487   Median :0.0000   Median : 0.000  
 Mean   :10.42   Mean   : 5.265   Mean   :0.4109   Mean   : 1.308  
 3rd Qu.:15.00   3rd Qu.: 6.642   3rd Qu.:0.6931   3rd Qu.: 1.386  
 Max.   :31.00   Max.   :10.303   Max.   :3.3322   Max.   :10.347  
                                                                   
     ConfbV           ConfbN       NounFrequency     
 Min.   :0.0000   Min.   : 0.000   Min.   :    0.00  
 1st Qu.:0.6931   1st Qu.: 0.000   1st Qu.:   28.75  
 Median :1.3863   Median : 4.143   Median :  108.00  
 Mean   :1.5570   Mean   : 3.890   Mean   :  600.19  
 3rd Qu.:2.5649   3rd Qu.: 6.242   3rd Qu.:  424.75  
 Max.   :4.1897   Max.   :10.600   Max.   :35351.00  
                                                     
 VerbFrequency      CV       Obstruent       Frication   
 Min.   :     0.0   C:4446   cont:1068   burst    :1840  
 1st Qu.:     0.0   V: 122   obst:3500   frication:1660  
 Median :    30.0                        long     :  88  
 Mean   :   881.0                        short    : 980  
 3rd Qu.:   164.2                                        
 Max.   :242066.0                                        
                                                         
       Voice      FrequencyInitialDiphoneWord
 voiced   :2060   Min.   : 3.091             
 voiceless:2508   1st Qu.: 9.557             
                  Median :10.517             
                  Mean   :10.359             
                  3rd Qu.:11.320             
                  Max.   :13.925             
                                             
 FrequencyInitialDiphoneSyllable CorrectLexdec  
 Min.   : 3.367                  Min.   : 1.00  
 1st Qu.:10.000                  1st Qu.:27.00  
 Median :10.972                  Median :29.00  
 Mean   :10.789                  Mean   :27.05  
 3rd Qu.:11.703                  3rd Qu.:30.00  
 Max.   :13.930                  Max.   :30.00  
                                                

2.4.2 Summary for a specific variable

english %>% 
  summarise(count = n(),
            range_RTlexdec = range(RTlexdec),
            mean_RTlexdec = mean(RTlexdec),
            sd_RTlexdec = sd(RTlexdec),
            var_RTlexdec = var(RTlexdec),
            min_RTlexdec = min(RTlexdec),
            max_RTlexdec = max(RTlexdec),
            quart1_RTlexdec = quantile(RTlexdec, 0.25),
            quart1_RTlexdec = quantile(RTlexdec, 0.75),
            median_RTlexdec = median(RTlexdec))

As you can see, we can add use summarise to obtain summaries of the dataset. We asked here for the mean, sd, variance, minimum and maximum values, etc.. In the dataset english, we have many numeric variables, and if we want to obtain summaries for all of numeric variables, we can use summarise_all.

2.4.3 Summarise_all

If you want to add another level of summaries, e.g., for length, you can either add them as another level (with a new variable name) or use summarise_all to do that for you. We need to select only numeric variables to do that. This is the function to only select numeric variables where(is.numeric). If you do not use it, you will get an error message

english %>% 
  select(where(is.numeric)) %>% 
  summarise_all(funs(mean = mean, sd = sd, var = var, min = min, max = max,
                     range = range, median = median, Q1 = quantile(., probs = 0.25), Q3 = quantile(., probs = 0.75)))
Warning: `funs()` was deprecated in dplyr 0.8.0.
Please use a list of either functions or lambdas: 

  # Simple named list: 
  list(mean = mean, median = median)

  # Auto named with `tibble::lst()`: 
  tibble::lst(mean, median)

  # Using lambdas
  list(~ mean(., trim = .2), ~ median(., na.rm = TRUE))
This warning is displayed once every 8 hours.
Call `lifecycle::last_lifecycle_warnings()` to see where this warning was generated.

As you can see, in this example, we see the chains of commands in the Tidyverse. We can continue to add commands each time we want to investigate something in particular. Keep adding pipes and commands. The most important point is that the dataset english did not change at all. If oyu want to create a new dataset with the results, simply use the assignment function <- at the beginning or -> at the end and give a name to the new dataset.

2.4.4 Group_by

2.4.4.1 One variable

What if you want to obtain all results summarised by a specific grouping? Let’s obtain the results grouped by the levels of AgeSubject.

english %>% 
  group_by(AgeSubject) %>% 
  summarise(count = n(),
            range_RTlexdec = range(RTlexdec),
            mean_RTlexdec = mean(RTlexdec),
            sd_RTlexdec = sd(RTlexdec),
            var_RTlexdec = var(RTlexdec),
            min_RTlexdec = min(RTlexdec),
            max_RTlexdec = max(RTlexdec),
            quart1_RTlexdec = quantile(RTlexdec, 0.25),
            quart1_RTlexdec = quantile(RTlexdec, 0.75),
            median_RTlexdec = median(RTlexdec))
`summarise()` has grouped output by 'AgeSubject'. You can override using the `.groups` argument.

2.4.4.2 Multiple variables

What if you want to obtain all results summarised by multiple groupings? Let’s obtain the results grouped by the levels of AgeSubject, WordCategory and Voice and we want to save the output.

english %>% 
  group_by(AgeSubject, WordCategory, Voice) %>% 
  summarise(count = n(),
            range_RTlexdec = range(RTlexdec),
            mean_RTlexdec = mean(RTlexdec),
            sd_RTlexdec = sd(RTlexdec),
            var_RTlexdec = var(RTlexdec),
            min_RTlexdec = min(RTlexdec),
            max_RTlexdec = max(RTlexdec),
            quart1_RTlexdec = quantile(RTlexdec, 0.25),
            quart1_RTlexdec = quantile(RTlexdec, 0.75),
            median_RTlexdec = median(RTlexdec)) -> dfMeans
`summarise()` has grouped output by 'AgeSubject', 'WordCategory', 'Voice'. You can override using the `.groups` argument.
dfMeans

2.4.5 Activity on your own 2

Use any of the numeric values in the dataset and obtain summaries

3 End of the session

This is the end of the second session. We looked at the various object types, and created a dataframe from scratch. We did some manipulations of the dataframe, by creating a new variable, renaming a column, deleting one, and changing the levels of a variable. We use the package Tidyverse to manipulate objects. We obtained then basic summaries and basic plots.

Next week, we will continue with the package Tidyverse to manipulate the data more and obtain additional plots.

4 session info

sessionInfo()
R version 4.1.2 (2021-11-01)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 19044)

Matrix products: default

locale:
[1] LC_COLLATE=English_United Kingdom.1252 
[2] LC_CTYPE=English_United Kingdom.1252   
[3] LC_MONETARY=English_United Kingdom.1252
[4] LC_NUMERIC=C                           
[5] LC_TIME=English_United Kingdom.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods  
[7] base     

other attached packages:
 [1] languageR_1.5.0 forcats_0.5.1   stringr_1.4.0   dplyr_1.0.7    
 [5] purrr_0.3.4     readr_2.0.2     tidyr_1.1.4     tibble_3.1.5   
 [9] ggplot2_3.3.5   tidyverse_1.3.1

loaded via a namespace (and not attached):
 [1] Rcpp_1.0.7            lubridate_1.8.0       lattice_0.20-45      
 [4] assertthat_0.2.1      digest_0.6.28         utf8_1.2.2           
 [7] R6_2.5.1              cellranger_1.1.0      backports_1.3.0      
[10] reprex_2.0.1          evaluate_0.14         httr_1.4.2           
[13] pillar_1.6.4          rlang_0.4.12          readxl_1.3.1         
[16] rstudioapi_0.13       minqa_1.2.4           jquerylib_0.1.4      
[19] nloptr_1.2.2.2        Matrix_1.3-4          rmarkdown_2.11       
[22] labeling_0.4.2        splines_4.1.2         lme4_1.1-27.1        
[25] munsell_0.5.0         broom_0.7.10          compiler_4.1.2       
[28] modelr_0.1.8          xfun_0.27             pkgconfig_2.0.3      
[31] PresenceAbsence_1.1.9 mgcv_1.8-38           htmltools_0.5.2      
[34] tidyselect_1.1.1      fansi_0.5.0           crayon_1.4.2         
[37] tzdb_0.2.0            dbplyr_2.1.1          withr_2.4.2          
[40] MASS_7.3-54           psycho_0.6.1          grid_4.1.2           
[43] nlme_3.1-153          jsonlite_1.7.2        gtable_0.3.0         
[46] lifecycle_1.0.1       DBI_1.1.1             magrittr_2.0.1       
[49] scales_1.1.1          cli_3.1.0             stringi_1.7.5        
[52] farver_2.1.0          fs_1.5.0              xml2_1.3.2           
[55] bslib_0.3.1           ellipsis_0.3.2        generics_0.1.1       
[58] vctrs_0.3.8           boot_1.3-28           tools_4.1.2          
[61] glue_1.4.2            hms_1.1.1             fastmap_1.1.0        
[64] yaml_2.2.1            colorspace_2.0-2      rvest_1.0.2          
[67] knitr_1.36            haven_2.4.3           sass_0.4.0           
LS0tDQp0aXRsZTogIlNlc3Npb24gMiAtIEludHJvZHVjdGlvbiB0byB0aGUgVGlkeXZlcnNlIg0KYXV0aG9yOg0KICBuYW1lOiBKYWxhbCBBbC1UYW1pbWkNCiAgYWZmaWxpYXRpb246IFVuaXZlcnNpdMOpIGRlIFBhcmlzDQpkYXRlOiAiYHIgZm9ybWF0KFN5cy50aW1lKCksICclZCAlQiAlWScpYCINCm91dHB1dDoNCiAgaHRtbF9ub3RlYm9vazoNCiAgICBoaWdobGlnaHQ6IHB5Z21lbnRzDQogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMNCiAgICB0b2M6IHllcw0KICAgIHRvY19kZXB0aDogNg0KICAgIHRvY19mbG9hdDoNCiAgICAgIGNvbGxhcHNlZDogeWVzDQogDQotLS0NCg0KIyBMb2FkaW5nIHBhY2thZ2VzIA0KDQpgYGB7ciB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCBlcnJvcj1GQUxTRX0NCiMjIFVzZSB0aGUgY29kZSBiZWxvdyB0byBjaGVjayBpZiB5b3UgaGF2ZSBhbGwgcmVxdWlyZWQgcGFja2FnZXMgaW5zdGFsbGVkLiBJZiBzb21lIGFyZSBub3QgaW5zdGFsbGVkIGFscmVhZHksIHRoZSBjb2RlIGJlbG93IHdpbGwgaW5zdGFsbCB0aGVzZS4gSWYgeW91IGhhdmUgYWxsIHBhY2thZ2VzIGluc3RhbGxlZCwgdGhlbiB5b3UgY291bGQgbG9hZCB0aGVtIHdpdGggdGhlIHNlY29uZCBjb2RlLg0KcmVxdWlyZWRQYWNrYWdlcyA9IGMoJ3RpZHl2ZXJzZScsICdsYW5ndWFnZVInKQ0KZm9yKHAgaW4gcmVxdWlyZWRQYWNrYWdlcyl7DQogIGlmKCFyZXF1aXJlKHAsY2hhcmFjdGVyLm9ubHkgPSBUUlVFKSkgaW5zdGFsbC5wYWNrYWdlcyhwKQ0KICBsaWJyYXJ5KHAsY2hhcmFjdGVyLm9ubHkgPSBUUlVFKQ0KfQ0KYGBgDQoNCg0KIyBUaGUgYFRpZHl2ZXJzZWANCg0KIyMgSW50cm9kdWN0aW9uDQoNClRoZSBgVGlkeXZlcnNlYCBpcyBhIGZhbWlseSBvZiBwYWNrYWdlcyB1c2VkIHRvIHNwZWVkIHVwIHRoZSB1c2Ugb2YgUi4gDQoNCiFbXShpbWFnZXMvdGlkeXZlcnNlLnBuZykNCg0KWW91IG5lZWQgdG8gZmlyc3QgaW5zdGFsbCBpdCAoaWYgeW91IGhhdmVuJ3QgYWxyZWFkeSBkb25lIHNvKSBhbmQgdGhlbiBsb2FkIGl0LiBUbyBpbnN0YWxsLCB1c2UgYFRvb2xzID4gSW5zdGFsbCBwYWNrYWdlc2Agb3IgYGluc3RhbGwucGFja2FnZXMoKWAgdGhlbiBhZGQgdGlkeXZlcnNlLiBUbyBsb2FkIGEgcGFja2FnZSwgdXNlIHRoZSBgbGlicmFyeSgpYCBmdW5jdGlvbi4NCg0KDQpMb29rIGF0IGhvdyBtYW55IHBhY2thZ2VzIGFyZSBpbnN0YWxsZWQgd2l0aGluIHRoZSBgVGlkeXZlcnNlYC4gVGhlIG1lc3NhZ2VzIHlvdSBzZWUgYXJlIHRlbGxpbmcgeW91IHdoaWNoIHBhY2thZ2VzIGFyZSBsb2FkZWQgYW5kIHdoaWNoIGZ1bmN0aW9ucyBhcmUgaW4gY29uZmxpY3QgKGkuZS4sIHRoZXNlIGFyZSBmdW5jdGlvbnMgZnJvbSBvdGhlciBwYWNrYWdlcyB0aGF0IGFyZSBmb3VuZCB3aXRoaW4gdGhlIGBUaWR5dmVyc2VgKS4gSWYgeW91IHdhbnQgdG8gdXNlIHRoZSBvcmlnaW5hbCBmdW5jdGlvbiwgc2ltcGx5IGFkZCBgcGFja2FnZV9uYW1lOjpmdW5jdGlvbmAuDQoNCg0KIyMjIFVzaW5nIHBpcGluZw0KDQpUaGUgZGlmZmVyZW5jZSBiZXR3ZWVuIGJhc2UgUiBhbmQgdGhlIFRpZHl2ZXJzZSdzIHdheSBvZiBkb2luZyB0aGluZ3MgaXMgdGhhdCBiYXNlIFIgY2FuIHNvbWV0aW1lcyBiZSBtb3JlIGNvbXBsZXgsIHdoaWxlIHRpZHl2ZXJzZSBpcyBtb3JlIHN0cmFpZ2h0Zm9yd2FyZCBhbmQgYWxsb3dzIHlvdSB0byAic2VlIiB3aXRoaW4gYSBkYXRhZnJhbWUgZWFzaWx5LiANCllvdSBuZWVkIHRvIGxlYXJuIGhvdyB0byB1c2UgdGhlICJwaXBlIiBpbiBgbWFncml0dHJgIHRoYXQgaXMgcGFydCBvZiB0aGUgYFRpZHl2ZXJzZWAuIA0KDQohW10oaW1hZ2VzL01hZ3JpdHRlUGlwZS5qcGcpDQoNClBpcGVzIGFyZSB3cml0dGVuIGluIFIgYXMgYCU+JWAgKG5vdGUgeW91IG11c3QgdXNlIGEgcGVyY2VudGFnZSBzaWduIGJlZm9yZSBhbmQgYWZ0ZXIgdGhlIHBpcGUpLiBUbyBkZW1vbnN0cmF0ZSB3aGF0IHBpcGVzIGRvLCBoYXZlIGEgbG9vayBhdCB0aGUgZm9sbG93aW5nIHBzZXVkb2NvZGUuIFlvdSBjYW4gdXNlIGEgc2hvcnRjdXQgaW4geW91ciBrZXlib2FyZCwgdHlwZSBDdHJsK1NoaWZ0K20gdG8gYWRkIGEgYHBpcGVgIChmb3IgbWFjIHVzZXJzLCBpdCBpcyBDbWQrU2hpZnQrbSkuDQoNCg0KIVtdKGltYWdlcy9waXBpbmcucG5nKQ0KDQoNClNpbmNlIGBSYCB2ZXJzaW9uIGA0LjEuMGAsIHRoZXJlIGlzIGEgbmF0aXZlIHBpcGUgYHw+YC4gSXQgc2VlbXMgdG8gYmUgZG9pbmcgYWxtb3N0IHRoZSBzYW1lIHRoaW5nIGFzIHRoZSBgJT4lYC4gV2Ugd2lsbCBzdGlsbCB1c2UgYCU+JWAgYXMgdGhpcyBpcyBpbnRlZ3JhdGVkIHdpdGhpbiB0aGUgYFRpZHl2ZXJzZWAuDQoNCiMjIyBEZW1vIHN1YnNldHRpbmcNCg0KQmVsb3cgYXJlIHR3byBjb2RlIGxpbmVzIGZvciBob3cgdG8gc3Vic2V0IHRoZSBkYXRhZnJhbWUgdXNpbmcgYmFzZSBgUmAgYW5kIHBpcGluZyBmcm9tIHRoZSBgbWFncml0dHJgIHBhY2thZ2UuIA0KDQpXaXRoIGJhc2UgUiwgd2UgYWx3YXlzIG5lZWQgdG8gcmVmZXIgdG8gdGhlIGRhdGFzZXQgdHdpY2U6IG9uY2UgYXQgdGhlIGJlZ2lubmluZyBhbmQgdGhlbiB0byBsb29rIGludG8gdGhlIGRhdGFzZXQgdG8gc2VsZWN0IGEgdmFyaWFibGUuDQoNCg0KYGBge3J9DQp3b3JkIDwtIGMoImEiLCAidGhlIiwgImxhbXAiLCAibm90IiwgImp1bXAiLCAiaXQiLCAiY29mZmVlIiwgIndhbGsiLCAib24iKQ0KZnJlcSA8LSBjKDUwMCwgNjAwLCA3LCAyMDAsIDMwLCA0NTAsIDEzMCwgMzMsIDMwMCkgICMgbm90ZSB0aGlzIGlzIGNvbXBsZXRlbHkgbWFkZSB1cCEhDQpmdW5jdGlvbndvcmQgPC0gYygieSIsICJ5IiwgIm4iLCAieSIsICJuIiwgInkiLCAibiIsICJuIiwgInkiKQ0KbGVuZ3RoIDwtIGMoMSwgMywgNCwgMywgNCwgMiwgNiwgNCwgMikNCmRmIDwtIGFzLmRhdGEuZnJhbWUoY2JpbmQod29yZCxmcmVxLGZ1bmN0aW9ud29yZCxsZW5ndGgpKQ0Kcm0od29yZCxmcmVxLGZ1bmN0aW9ud29yZCxsZW5ndGgpDQpkZiRmdW5jdGlvbndvcmQgPC0gYXMuY2hhcmFjdGVyKGRmJGZ1bmN0aW9ud29yZCkNCmRmJGZ1bmN0aW9ud29yZFtkZiRmdW5jdGlvbndvcmQgPT0gInkiXSA8LSAieWVzIg0KZGYkZnVuY3Rpb253b3JkW2RmJGZ1bmN0aW9ud29yZCA9PSAibm8iXSA8LSAibm8iDQpkZiRmdW5jdGlvbndvcmQgPC0gYXMuZmFjdG9yKGRmJGZ1bmN0aW9ud29yZCkNCmBgYA0KDQoNCg0KYGBge3J9DQpkZl9ZZXMxIDwtIGRmW3doaWNoKGRmJGZ1bmN0aW9ud29yZCA9PSAneWVzJyksXQ0KZGZfWWVzMQ0KYGBgDQoNCg0KV2l0aCB0aGUgcGlwZSwgeW91IG9ubHkgbmVlZCB0byBzcGVjaWZ5IHRoZSBkYXRhc2V0IG9uY2U6IEJ5IGFkZGluZyB0aGUgcGlwZSwgeW91IGNhbiBhbHJlYWR5IGxvb2sgaW50byB0aGUgZGF0YXNldCBhbmQgc2VsZWN0IHRoZSB2YXJpYWJsZSB5b3UgbmVlZC4NCg0KYGBge3J9DQpkZl9ZZXMxX3BpcGVfdGlkeSA8LSBkZiAlPiUgZmlsdGVyKGZ1bmN0aW9ud29yZCA9PSd5ZXMnKQ0KZGZfWWVzMV9waXBlX3RpZHkNCmBgYA0KDQoNCkFuZCB0aGlzIGlzIHdpdGggdGhlIGJhc2UgUiBwaXBlIChjb21iaW5lZCB3aXRoIGNvZGUgZnJvbSB0aGUgYFRpZHl2ZXJzZWAgZmFtaWx5KQ0KDQoNCmBgYHtyfQ0KZGZfWWVzMV9waXBlX2Jhc2UgPC0gZGYgfD4gZmlsdGVyKGZ1bmN0aW9ud29yZCA9PSd5ZXMnKQ0KZGZfWWVzMV9waXBlX2Jhc2UNCmBgYA0KDQoNCkFzIHlvdSBjYW4gc2VlLCB1c2luZyB0aGUgcGlwZSAoZWl0aGVyIHdpdGhpbiB0aGUgYFRpZHl2ZXJzZWAgb3Igd2l0aCBiYXNlIFIpIGlzIGEgcXVpY2sgYW5kIGVhc3kgd2F5IHRvIGRvIHZhcmlvdXMgb3BlcmF0aW9ucy4NCg0KT3V0IG9mIGNvbnZlbmllbmNlIGFuZCBiZWNhdXNlIHdlIHdpbGwgdXNlIG90aGVyIHBhY2thZ2VzIGludGVncmF0ZWQgd2l0aGluIHRoZSBgVGlkeXZlcnNlYCwgd2Ugd2lsbCB1c2UgaXRzIHBpcGUuDQoNClJlQ2FwOg0KDQotIGAlPiVgIGlzIGNhbGxlZCBhICJwaXBlIiAgDQotIEl0IHBhc3NlcyB0aGUgcHJldmlvdXMgbGluZSBpbnRvIHRoZSBgZGF0YWAgYXJndW1lbnQgb2YgdGhlIG5leHQgbGluZSAgDQotIEl0ICoqZG9lcyBub3Qgc2F2ZSBhbnkgY2hhbmdlcyoqIGFmdGVyIG91dHB1dCANCi0gSWYgeW91IHdhbnQgdG8gc2F2ZSB0aGUgb3V0cHV0IG9mIGEgcGFydGljdWxhciBtYW5pcHVsYXRpb24sIHNpbXBseSBzYXZlIGl0IHdpdGggeHggPC0gDQoNCg0KIyMgQmFzaWMgbWFuaXB1bGF0aW9ucw0KDQpXZSB3aWxsIHVzZSB0aGUgcGlwZSB3aXRoIHRoZSBgVGlkeXZlcnNlYCB0byBvYnRhaW4gc3VtbWFyaWVzLiBXZSB3aWxsIHVzZSBhbiBgUmAgYnVpbHQtaW4gZGF0YXNldC4gVHlwZSBgZGF0YSgpYCB0byBzZWUgdGhlIGZ1bGwgbGlzdCBvZiBkYXRhc2V0cyBpbnN0YWxsZWQgYnkgZGVmYXVsdCBpbiBgUmAuIFlvdSBjYW4gdXNlIGBkYXRhKHBhY2thZ2UgPSAucGFja2FnZXMoYWxsLmF2YWlsYWJsZSA9IFRSVUUpKWAgdG8gc2VlIGFsbCBkYXRhc2V0cyBpbnN0YWxsZWQgd2l0aGluIGFsbCBwYWNrYWdlcy4NCg0KDQoNCiMjIyBGaXJzdCBzdGVwcw0KDQpIZXJlIGlzIGEgbGlzdCBvZiBhbGwgYXZhaWxhYmxlIGRhdGFzZXRzDQoNCg0KYGBge3J9DQpkYXRhKCkNCmRhdGEocGFja2FnZSA9IC5wYWNrYWdlcyhhbGwuYXZhaWxhYmxlID0gVFJVRSkpDQpgYGANCg0KIyMjIExvYWRpbmcgZGF0YXNldA0KDQpXZSB3aWxsIHVzZSB0aGUgZGF0YXNldCBgZW5nbGlzaGAgZnJvbSB0aGUgcGFja2FnZSBgbGFuZ3VhZ2VSYC4gVGhpcyBpcyBhIHBhY2thZ2UgdGhhdCBjb250YWlucyBtYW55IGxpbmd1aXN0aWNhbGx5LW9yaWVudGVkIGRhdGFzZXRzLg0KU2VlIGRldGFpbHMgb2YgdGhlIGRhdGFzZXQgW2hlcmVdKGh0dHBzOi8vd3d3LnJkb2N1bWVudGF0aW9uLm9yZy9wYWNrYWdlcy9sYW5ndWFnZVIvdmVyc2lvbnMvMS41LjAvdG9waWNzL2VuZ2xpc2gpLiBPciBieSB0eXBpbmcgYD9sYW5ndWFnZVI6OmVuZ2xpc2hgIChvciBzaW1wbHkgYD9lbmdsaXNoYCBpZiB0aGUgcGFja2FnZSBpcyBhbHJlYWR5IGxvYWRlZCkgaW4gdGhlIGNvbnNvbGUuDQoNCllvdSBjYW4gbG9hZCB0aGUgZGF0YXNldCBhZnRlciBsb2FkaW5nIHRoZSBwYWNrYWdlLiBTaW1wbHkgcmVmZXIgdG8gaXQgYnkgaXRzIG5hbWUuIA0KDQpgYGB7cn0NCj9lbmdsaXNoDQpgYGANCg0KDQojIyMgVmlldw0KDQpUbyBzZWUgdGhlIGRhdGFzZXQsIHJ1biB0aGUgY29kZSBiZWxvdyB0byB2aXN1YWxpc2UgaXQuIA0KDQpgYGB7cn0NCmVuZ2xpc2ggJT4lIA0KICBWaWV3KCkNCiMgb3Igd2l0aG91dCBwaXBlDQpWaWV3KGVuZ2xpc2gpDQpgYGANCg0KDQoNCiMjIyBTdHJ1Y3R1cmUNCg0KDQpXZSBjYW4gdXNlIGBzdHIoKWAgdG8gbG9vayBhdCB0aGUgc3RydWN0dXJlIG9mIHRoZSBkYXRhc2V0LiBIZXJlIHdlIGhhdmUgYSByZWxhdGl2ZWx5IGxhcmdlIGRhdGFzZXQgd2l0aCA0NTY4IG9ic2VydmF0aW9ucyAoPXJvd3MpIGFuZCAzNiB2YXJpYWJsZXMgKD1jb2x1bW5zKS4NCg0KYGBge3J9DQplbmdsaXNoICU+JSANCiAgc3RyKCkNCiMgb3Igd2l0aG91dCBwaXBlDQpzdHIoZW5nbGlzaCkNCmBgYA0KDQoNCiMjIyBTZWUgZmlyc3QgNiByb3dzDQoNCmBgYHtyfQ0KZW5nbGlzaCAlPiUgDQogIGhlYWQoKQ0KIyBvciB3aXRob3V0IHBpcGUNCmhlYWQoZW5nbGlzaCkNCmBgYA0KDQojIyMgU2VlIGxhc3QgNiByb3dzDQoNCmBgYHtyfQ0KZW5nbGlzaCAlPiUgDQogIHRhaWwoKQ0KIyBvciB3aXRob3V0IHBpcGUNCnRhaWwoZW5nbGlzaCkNCmBgYA0KDQojIyMgU2VsZWN0aW5nIHZhcmlhYmxlcw0KDQpIZXJlLCB3ZSBzZWxlY3QgYSBmZXcgdmFyaWFibGVzIHRvIHVzZS4gRm9yIGB2YXJpYWJsZXNgIG9yIGBjb2x1bW5zYCwgdXNlIHRoZSBmdW5jdGlvbiBgc2VsZWN0YA0KDQpgYGB7cn0NCmVuZ2xpc2ggJT4lIA0KICBzZWxlY3QoUlRsZXhkZWMsIFJUbmFtaW5nLCBGYW1pbGlhcml0eSkNCiMgb3Igd2l0aG91dCBwaXBlDQpzZWxlY3QoZW5nbGlzaCwgUlRsZXhkZWMsIFJUbmFtaW5nLCBGYW1pbGlhcml0eSkNCmBgYA0KDQoNCiMjIyBTZWxlY3Rpbmcgb2JzZXJ2YXRpb25zDQoNCklmIHdlIHdhbnQgdG8gc2VsZWN0IG9ic2VydmF0aW9ucywgd2UgdXNlIHRoZSBmdW5jdGlvbiBgZmlsdGVyYC4gV2Ugd2lsbCB1c2UgYHNlbGVjdGAgdG8gc2VsZWN0IHBhcnRpY3VsYXIgdmFyaWFibGVzIGFuZCB0aGVuIHVzZSBgZmlsdGVyYCB0byBzZWxlY3Qgc3BlY2lmaWMgb2JzZXJ2YXRpb25zLiBUaGlzIGV4YW1wbGUgc2hvd3MgaG93IHRoZSBwaXBlIGNoYWluIHdvcmtzLCBieSBjb21iaW5pbmcgbXVsdGlwbGUgZnVuY3Rpb25zIGFuZCB1c2luZyBwaXBlcw0KDQpgYGB7cn0NCmVuZ2xpc2ggJT4lIA0KICBzZWxlY3QoUlRsZXhkZWMsIFJUbmFtaW5nLCBGYW1pbGlhcml0eSwgQWdlU3ViamVjdCkgJT4lIA0KICBmaWx0ZXIoQWdlU3ViamVjdCA9PSAib2xkIikNCiMgb3Igd2l0aG91dCBwaXBlDQpmaWx0ZXIoc2VsZWN0KGVuZ2xpc2gsIFJUbGV4ZGVjLCBSVG5hbWluZywgRmFtaWxpYXJpdHksIEFnZVN1YmplY3QpLCBBZ2VTdWJqZWN0ID09ICJvbGQiKQ0KYGBgDQoNCg0KDQojIyMgQ2hhbmdpbmcgb3JkZXIgb2YgbGV2ZWxzDQoNClVzZSBzb21lIG9mIHRoZSBjb2RlIGFib3ZlIHRvIG1hbmlwdWxhdGUgdGhlIGRhdGFmcmFtZSBidXQgbm93IHVzaW5nIGNvZGUgZnJvbSB0aGUgYFRpZHl2ZXJzZWAuIEFzIHlvdSB3aWxsIHNlZSwgb25jZSB5b3Uga25vdyBob3cgdG8gbWFuaXB1bGF0ZSBhIGRhdGFzZXQgd2l0aCBiYXNlIGBSYCwgeW91IGNhbiBlYXNpbHkgYXBwbHkgdGhlIHNhbWUgdGVjaG5pcXVlcyB3aXRoIHRoZSBgVGlkeXZlcnNlYC4gVGhlIGBUaWR5dmVyc2VgIHByb3ZpZGVzIGFkZGl0aW9uYWwgd2F5cyB0byBtYW5pcHVsYXRlIGEgZGF0YWZyYW1lLg0KDQpGb3IgZXhhbXBsZSwgaWYgSSB3YW50IHRvIGNoZWNrIGxldmVscyBvZiBhIHZhcmlhYmxlIGFuZCBjaGFuZ2UgdGhlIHJlZmVyZW5jZSBsZXZlbCwgSSB3aWxsIHVzZSB0aGUgZm9sbG93aW5nIGNvZGUNCg0KYGBge3J9DQpsZXZlbHMoZW5nbGlzaCRBZ2VTdWJqZWN0KQ0KYGBgDQoNCg0KVG8gY2hhbmdlIGxldmVscyBvZiBgQWdlU3ViamVjdGAsIHdlIG5lZWQgdG8gc2F2ZSBhIG5ldyBkYXRhc2V0IChkbyBub3Qgb3ZlcnJpZGUgdGhlIG9yaWdpbmFsIGRhdGFzZXQhISkuIFRoZSBgbXV0YXRlYCBmdW5jdGlvbiBtZWFucyB3ZSBhcmUgbWFuaXB1bGF0aW5nIGFuIG9iamVjdC4NCg0KYGBge3J9DQplbmdsaXNoMjwtIGVuZ2xpc2ggJT4lIA0KICBtdXRhdGUoQWdlU3ViamVjdCA9IGZhY3RvcihBZ2VTdWJqZWN0LCBsZXZlbHMgPSBjKCJ5b3VuZyIsICJvbGQiKSkpDQojIG9yIHdpdGhvdXQgcGlwZQ0KZW5nbGlzaDIgPC0gbXV0YXRlKGVuZ2xpc2gsIEFnZVN1YmplY3QgPSBmYWN0b3IoQWdlU3ViamVjdCwgbGV2ZWxzID0gYygieW91bmciLCAib2xkIikpKQ0KDQpsZXZlbHMoZW5nbGlzaDIkQWdlU3ViamVjdCkNCmBgYA0KDQojIyMgQ2hhbmdpbmcgcmVmZXJlbmNlIHZhbHVlDQoNCllvdSBjYW4gY2hhbmdlIHRoZSByZWZlcmVuY2UgdmFsdWUgYnkgdXNpbmcgYGZjdF9yZWxldmVsYC4gVGhpcyBpcyB1c2VmdWwgaWYgeW91IGhhdmUgbWFueSBsZXZlbHMgaW4gb25lIG9mIHRoZSBmYWN0b3JzIHlvdSBhcmUgd29ya2luZyB3aXRoIGFuZCB5b3Ugc2ltcGx5IG5lZWQgdG8gY2hhbmdlIHRoZSByZWZlcmVuY2UuDQoNCmBgYHtyfQ0KZW5nbGlzaDI8LSBlbmdsaXNoICU+JSANCiAgbXV0YXRlKEFnZVN1YmplY3QgPSBmY3RfcmVsZXZlbChBZ2VTdWJqZWN0LCAib2xkIikpDQojIG9yIHdpdGhvdXQgcGlwZQ0KZW5nbGlzaDIgPC0gbXV0YXRlKGVuZ2xpc2gsIEFnZVN1YmplY3QgPSBmY3RfcmVsZXZlbChBZ2VTdWJqZWN0LCAib2xkIikpDQoNCmxldmVscyhlbmdsaXNoMiRBZ2VTdWJqZWN0KQ0KYGBgDQoNClRoZSBgVGlkeXZlcnNlYCBjb250YWlucyBtYW55IGZ1bmN0aW9ucyB0aGF0IGFyZSB1c2VmdWwgZm9yIGRhdGEgbWFuaXB1bGF0aW9uLiBXZSB3aWxsIGxvb2sgYXQgYWRkaXRpb25hbCBvbmVzIG5leHQgd2Vlaw0KDQoNCiMjIyBBY3Rpdml0eSBvbiB5b3VyIG93biAxDQoNClVzZSBhbnkgb2YgdGhlIG90aGVyIGZhY3RvcnMgYW5kIHRyeSB0byBjaGFuZ2UgaXRzIGxldmVscyBhbmQvb3IgaXRzIHJlZmVyZW5jZSBsZXZlbA0KDQpgYGB7cn0NCg0KYGBgDQoNCg0KIyMgQWR2YW5jZWQgbWFuaXB1bGF0aW9ucw0KDQpTb21ldGltZXMsIHlvdSBtYXkgaGF2ZSBhIGRhdGFzZXQgdGhhdCBjb21lcyBpbiBhIHdpZGUgZm9ybWF0IChpLmUuLCBjb2x1bW5zIGNvbnRhaW4gZGF0YSBmcm9tIHBhcnRpY2lwYW50cykgYW5kIHlvdSB3YW50IHRvIGNoYW5nZSB0byBsb25nIGZvcm1hdCAoaS5lLiwgZWFjaCByb3cgY29udGFpbnMgb25lIG9ic2VydmF0aW9uIHdpdGggbWluaW1hbCBudW1iZXIgb2YgY29sdW1ucykuIExldCdzIGxvb2sgYXQgdGhlIGZ1bmN0aW9ucyBgcGl2b3RfbG9uZ2VyYCBhbmQgYHBpdm90X3dpZGVyYA0KDQojIyMgQ29sdW1ucyB0byByb3dzDQoNCkxldCdzIHVzZSB0aGUgYGVuZ2xpc2hgIGRhdGFzZXQgdG8gdHJhbnNmb3JtIGl0IGZyb20gd2lkZSB0byBsb25nLg0KDQpgYGB7cn0NCmVuZ2xpc2ggJT4lIA0KICBzZWxlY3QoV29yZCwgUlRsZXhkZWMsIFJUbmFtaW5nLCBGYW1pbGlhcml0eSkgJT4lIA0KICBwaXZvdF9sb25nZXIoY29scyA9IGMoUlRsZXhkZWMsIFJUbmFtaW5nLCBGYW1pbGlhcml0eSksICMgeW91IGNhbiBhbHNvIGFkZCBpbmRleCwgaS5lLiwgMjo0DQogICAgICAgICAgICAgICBuYW1lc190byA9ICJ2YXJpYWJsZSIsDQogICAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAidmFsdWVzIikNCiMgb3Igd2l0aG91dCBwaXBlDQpwaXZvdF9sb25nZXIoc2VsZWN0KGVuZ2xpc2gsIFdvcmQsIFJUbGV4ZGVjLCBSVG5hbWluZywgRmFtaWxpYXJpdHkpLA0KICAgICAgICAgICAgIGNvbHMgPSBjKFJUbGV4ZGVjLCBSVG5hbWluZywgRmFtaWxpYXJpdHkpLCAjIHlvdSBjYW4gYWxzbyBhZGQgaW5kZXgsIGkuZS4sIDI6NA0KICAgICAgICAgICAgIG5hbWVzX3RvID0gInZhcmlhYmxlIiwNCiAgICAgICAgICAgICB2YWx1ZXNfdG8gPSAidmFsdWVzIikNCmBgYA0KDQoNCiMjIyBSb3dzIHRvIGNvbHVtbnMNCg0KTGV0J3MgdXNlIHRoZSBzYW1lIGNvZGUgYWJvdmUgYW5kIGNoYW5nZSB0aGUgY29kZSBmcm9tIGxvbmcgZm9ybWF0LCBiYWNrIHRvIHdpZGUgZm9ybWF0LiBQaXZvdF93aWRlciBhbGxvd3MgeW91IHRvIGdvIGJhY2sgdG8gdGhlIG9yaWdpbmFsIGRhdGFzZXQuIFlvdSB3aWxsIG5lZWQgdG8gdXNlIGB1bm5lc3RgIHRvIGdldCBhbGwgcm93cyBpbiB0aGUgY29ycmVjdCBwbGFjZS4gVHJ5IHdpdGhvdXQgaXQgdG8gc2VlIHRoZSByZXN1bHQuDQoNCg0KYGBge3J9DQplbmdsaXNoICU+JSANCiAgc2VsZWN0KFdvcmQsIFJUbGV4ZGVjLCBSVG5hbWluZywgRmFtaWxpYXJpdHkpICU+JSANCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKFJUbGV4ZGVjLCBSVG5hbWluZywgRmFtaWxpYXJpdHkpLCAjIHlvdSBjYW4gYWxzbyBhZGQgaW5kZXgsIGkuZS4sIDI6NA0KICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAidmFyaWFibGUiLA0KICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gInZhbHVlcyIpICU+JSANCiAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9ICJ2YXJpYWJsZSIsDQogICAgICAgICAgICAgIHZhbHVlc19mcm9tID0gInZhbHVlcyIpDQojIG9yIHdpdGhvdXQgcGlwZQ0KcGl2b3Rfd2lkZXIocGl2b3RfbG9uZ2VyKHNlbGVjdChlbmdsaXNoLCBXb3JkLCBSVGxleGRlYywgUlRuYW1pbmcsIEZhbWlsaWFyaXR5KSwNCiAgICAgICAgICAgICAgICAgICAgICAgICBjb2xzID0gYyhSVGxleGRlYywgUlRuYW1pbmcsIEZhbWlsaWFyaXR5KSwgIyB5b3UgY2FuIGFsc28gYWRkIGluZGV4LCBpLmUuLCAyOjQNCiAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lc190byA9ICJ2YXJpYWJsZSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gInZhbHVlcyIpLA0KICAgICAgICAgICAgbmFtZXNfZnJvbSA9ICJ2YXJpYWJsZSIsDQogICAgICAgICAgICB2YWx1ZXNfZnJvbSA9ICJ2YWx1ZXMiKQ0KYGBgDQoNCg0KQnV0IHdhaXQsIHdoZXJlIGFyZSB0aGUgcmVzdWx0cz8gVGhleSBhcmUgYWRkZWQgaW4gbGlzdHMuIFdlIG5lZWQgdG8gdXNlIHRoZSBmdW5jdGlvbiBgdW5uZXN0KClgIHRvIG9idGFpbiB0aGUgZnVsbCByZXN1bHRzLiANCg0KYGBge3J9DQplbmdsaXNoICU+JSANCiAgc2VsZWN0KFdvcmQsIFJUbGV4ZGVjLCBSVG5hbWluZywgRmFtaWxpYXJpdHkpICU+JSANCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKFJUbGV4ZGVjLCBSVG5hbWluZywgRmFtaWxpYXJpdHkpLCAjIHlvdSBjYW4gYWxzbyBhZGQgaW5kZXgsIGkuZS4sIDI6NA0KICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAidmFyaWFibGUiLA0KICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gInZhbHVlcyIpICU+JSANCiAgcGl2b3Rfd2lkZXIobmFtZXNfZnJvbSA9ICJ2YXJpYWJsZSIsDQogICAgICAgICAgICAgIHZhbHVlc19mcm9tID0gInZhbHVlcyIpICU+JSANCiAgdW5uZXN0KCkNCiMgb3Igd2l0aG91dCBwaXBlDQp1bm5lc3QocGl2b3Rfd2lkZXIocGl2b3RfbG9uZ2VyKHNlbGVjdChlbmdsaXNoLCBXb3JkLCBSVGxleGRlYywgUlRuYW1pbmcsIEZhbWlsaWFyaXR5KSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29scyA9IGMoUlRsZXhkZWMsIFJUbmFtaW5nLCBGYW1pbGlhcml0eSksICMgeW91IGNhbiBhbHNvIGFkZCBpbmRleCwgaS5lLiwgMjo0DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5hbWVzX3RvID0gInZhcmlhYmxlIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gInZhbHVlcyIpLA0KICAgICAgICAgICAgICAgICAgIG5hbWVzX2Zyb20gPSAidmFyaWFibGUiLA0KICAgICAgICAgICAgICAgICAgIHZhbHVlc19mcm9tID0gInZhbHVlcyIpKQ0KYGBgDQoNCg0KICANCkFoIHRoYXQgaXMgYmV0dGVyLiBCdXQgd2UgZ2V0IHdhcm5pbmdzLiBXaGF0IGRvZXMgdGhlIHdhcm5pbmdzIHRlbGwgdXM/DQpUaGVzZSBhcmUgc2ltcGxlIHdhcm5pbmdzIGFuZCBub3QgZXJyb3JzLiBZb3UgY2FuIHVzZSB0aGUgc3VnZ2VzdGlvbnMgdGhlIGBUaWR5dmVyc2VgIG1ha2VzLiBCeSBkZWZhdWx0LCB3ZSBhcmUgdG9sZCB0aGF0IHRoZSByZXN1bHRzIGFyZSBzaG93biBhcyBsaXN0cyBvZiBjb2x1bW5zICh3aGF0IHdlIGFyZSBhZnRlcikuIFRoZSBzZWNvbmQgd2FybmluZyB0ZWxscyB5b3UgdG8gdXNlIGEgc3BlY2lmaWMgc3BlY2lmaWNhdGlvbiB3aXRoIHVubmVzdCgpLg0KDQoNCiMjIEJhc2ljIGRlc2NyaXB0aXZlIHN0YXRpc3RpY3MNCg0KDQojIyMgQmFzaWMgc3VtbWFyaWVzIA0KDQoNCldlIGNhbiB1c2UgYHN1bW1hcnkoKWAgdG8gb2J0YWluIGJhc2ljIHN1bW1hcmllcyBvZiB0aGUgZGF0YXNldC4gRm9yIG51bWVyaWMgdmFyaWFibGVzLCB0aGlzIHdpbGwgZ2l2ZSB5b3UgdGhlIG1pbmltdW0sIG1heGltdW0sIG1lYW4sIG1lZGlhbiwgMXN0IGFuZCAzcmQgcXVhcnRpbGVzOyBmb3IgZmFjdG9ycy9jaGFyYWN0ZXJzLCB0aGlzIHdpbGwgYmUgdGhlIGNvdW50LiBJZiB0aGVyZSBhcmUgbWlzc2luZyB2YWx1ZXMsIHlvdSB3aWxsIGdldCBudW1iZXIgb2YgTkFzLiBMb29rIGF0IHRoZSBzdW1tYXJpZXMgb2YgdGhlIGRhdGFzZXQgYmVsb3cuIA0KDQoNCmBgYHtyfQ0KZW5nbGlzaCAlPiUgDQogIHN1bW1hcnkoKQ0KYGBgDQoNCiMjIyBTdW1tYXJ5IGZvciBhIHNwZWNpZmljIHZhcmlhYmxlDQoNCmBgYHtyfQ0KZW5nbGlzaCAlPiUgDQogIHN1bW1hcmlzZShjb3VudCA9IG4oKSwNCiAgICAgICAgICAgIHJhbmdlX1JUbGV4ZGVjID0gcmFuZ2UoUlRsZXhkZWMpLA0KICAgICAgICAgICAgbWVhbl9SVGxleGRlYyA9IG1lYW4oUlRsZXhkZWMpLA0KICAgICAgICAgICAgc2RfUlRsZXhkZWMgPSBzZChSVGxleGRlYyksDQogICAgICAgICAgICB2YXJfUlRsZXhkZWMgPSB2YXIoUlRsZXhkZWMpLA0KICAgICAgICAgICAgbWluX1JUbGV4ZGVjID0gbWluKFJUbGV4ZGVjKSwNCiAgICAgICAgICAgIG1heF9SVGxleGRlYyA9IG1heChSVGxleGRlYyksDQogICAgICAgICAgICBxdWFydDFfUlRsZXhkZWMgPSBxdWFudGlsZShSVGxleGRlYywgMC4yNSksDQogICAgICAgICAgICBxdWFydDFfUlRsZXhkZWMgPSBxdWFudGlsZShSVGxleGRlYywgMC43NSksDQogICAgICAgICAgICBtZWRpYW5fUlRsZXhkZWMgPSBtZWRpYW4oUlRsZXhkZWMpKQ0KYGBgDQoNCkFzIHlvdSBjYW4gc2VlLCB3ZSBjYW4gYWRkIHVzZSBgc3VtbWFyaXNlYCB0byBvYnRhaW4gc3VtbWFyaWVzIG9mIHRoZSBkYXRhc2V0LiBXZSBhc2tlZCBoZXJlIGZvciB0aGUgbWVhbiwgc2QsIHZhcmlhbmNlLCBtaW5pbXVtIGFuZCBtYXhpbXVtIHZhbHVlcywgZXRjLi4gSW4gdGhlIGRhdGFzZXQgYGVuZ2xpc2hgLCB3ZSBoYXZlIG1hbnkgbnVtZXJpYyB2YXJpYWJsZXMsIGFuZCBpZiB3ZSB3YW50IHRvIG9idGFpbiBzdW1tYXJpZXMgZm9yIGFsbCBvZiBudW1lcmljIHZhcmlhYmxlcywgd2UgY2FuIHVzZSBgc3VtbWFyaXNlX2FsbGAuIA0KDQoNCiMjIyBTdW1tYXJpc2VfYWxsDQoNCklmIHlvdSB3YW50IHRvIGFkZCBhbm90aGVyIGxldmVsIG9mIHN1bW1hcmllcywgZS5nLiwgZm9yIGxlbmd0aCwgeW91IGNhbiBlaXRoZXIgYWRkIHRoZW0gYXMgYW5vdGhlciBsZXZlbCAod2l0aCBhIG5ldyB2YXJpYWJsZSBuYW1lKSBvciB1c2UgYHN1bW1hcmlzZV9hbGxgIHRvIGRvIHRoYXQgZm9yIHlvdS4gV2UgbmVlZCB0byBzZWxlY3Qgb25seSBudW1lcmljIHZhcmlhYmxlcyB0byBkbyB0aGF0LiBUaGlzIGlzIHRoZSBmdW5jdGlvbiB0byBvbmx5IHNlbGVjdCBudW1lcmljIHZhcmlhYmxlcyBgd2hlcmUoaXMubnVtZXJpYylgLiBJZiB5b3UgZG8gbm90IHVzZSBpdCwgeW91IHdpbGwgZ2V0IGFuIGVycm9yIG1lc3NhZ2UNCg0KDQpgYGB7cn0NCmVuZ2xpc2ggJT4lIA0KICBzZWxlY3Qod2hlcmUoaXMubnVtZXJpYykpICU+JSANCiAgc3VtbWFyaXNlX2FsbChmdW5zKG1lYW4gPSBtZWFuLCBzZCA9IHNkLCB2YXIgPSB2YXIsIG1pbiA9IG1pbiwgbWF4ID0gbWF4LA0KICAgICAgICAgICAgICAgICAgICAgcmFuZ2UgPSByYW5nZSwgbWVkaWFuID0gbWVkaWFuLCBRMSA9IHF1YW50aWxlKC4sIHByb2JzID0gMC4yNSksIFEzID0gcXVhbnRpbGUoLiwgcHJvYnMgPSAwLjc1KSkpDQpgYGANCg0KQXMgeW91IGNhbiBzZWUsIGluIHRoaXMgZXhhbXBsZSwgd2Ugc2VlIHRoZSBjaGFpbnMgb2YgY29tbWFuZHMgaW4gdGhlIGBUaWR5dmVyc2VgLiBXZSBjYW4gY29udGludWUgdG8gYWRkIGNvbW1hbmRzIGVhY2ggdGltZSB3ZSB3YW50IHRvIGludmVzdGlnYXRlIHNvbWV0aGluZyBpbiBwYXJ0aWN1bGFyLiBLZWVwIGFkZGluZyBwaXBlcyBhbmQgY29tbWFuZHMuIFRoZSBtb3N0IGltcG9ydGFudCBwb2ludCBpcyB0aGF0IHRoZSBkYXRhc2V0IGBlbmdsaXNoYCBkaWQgbm90IGNoYW5nZSBhdCBhbGwuIElmIG95dSB3YW50IHRvIGNyZWF0ZSBhIG5ldyBkYXRhc2V0IHdpdGggdGhlIHJlc3VsdHMsIHNpbXBseSB1c2UgdGhlIGFzc2lnbm1lbnQgZnVuY3Rpb24gYDwtYCBhdCB0aGUgYmVnaW5uaW5nIG9yIGAtPmAgYXQgdGhlIGVuZCBhbmQgZ2l2ZSBhIG5hbWUgdG8gdGhlIG5ldyBkYXRhc2V0Lg0KDQoNCiMjIyBHcm91cF9ieQ0KDQojIyMjIE9uZSB2YXJpYWJsZQ0KDQpXaGF0IGlmIHlvdSB3YW50IHRvIG9idGFpbiBhbGwgcmVzdWx0cyBzdW1tYXJpc2VkIGJ5IGEgc3BlY2lmaWMgZ3JvdXBpbmc/IExldCdzIG9idGFpbiB0aGUgcmVzdWx0cyBncm91cGVkIGJ5IHRoZSBsZXZlbHMgb2YgYEFnZVN1YmplY3RgLg0KDQoNCmBgYHtyfQ0KZW5nbGlzaCAlPiUgDQogIGdyb3VwX2J5KEFnZVN1YmplY3QpICU+JSANCiAgc3VtbWFyaXNlKGNvdW50ID0gbigpLA0KICAgICAgICAgICAgcmFuZ2VfUlRsZXhkZWMgPSByYW5nZShSVGxleGRlYyksDQogICAgICAgICAgICBtZWFuX1JUbGV4ZGVjID0gbWVhbihSVGxleGRlYyksDQogICAgICAgICAgICBzZF9SVGxleGRlYyA9IHNkKFJUbGV4ZGVjKSwNCiAgICAgICAgICAgIHZhcl9SVGxleGRlYyA9IHZhcihSVGxleGRlYyksDQogICAgICAgICAgICBtaW5fUlRsZXhkZWMgPSBtaW4oUlRsZXhkZWMpLA0KICAgICAgICAgICAgbWF4X1JUbGV4ZGVjID0gbWF4KFJUbGV4ZGVjKSwNCiAgICAgICAgICAgIHF1YXJ0MV9SVGxleGRlYyA9IHF1YW50aWxlKFJUbGV4ZGVjLCAwLjI1KSwNCiAgICAgICAgICAgIHF1YXJ0MV9SVGxleGRlYyA9IHF1YW50aWxlKFJUbGV4ZGVjLCAwLjc1KSwNCiAgICAgICAgICAgIG1lZGlhbl9SVGxleGRlYyA9IG1lZGlhbihSVGxleGRlYykpDQpgYGANCg0KDQojIyMjIE11bHRpcGxlIHZhcmlhYmxlcw0KDQpXaGF0IGlmIHlvdSB3YW50IHRvIG9idGFpbiBhbGwgcmVzdWx0cyBzdW1tYXJpc2VkIGJ5IG11bHRpcGxlIGdyb3VwaW5ncz8gTGV0J3Mgb2J0YWluIHRoZSByZXN1bHRzIGdyb3VwZWQgYnkgdGhlIGxldmVscyBvZiBgQWdlU3ViamVjdGAsIGBXb3JkQ2F0ZWdvcnlgIGFuZCBgVm9pY2VgIGFuZCB3ZSB3YW50IHRvIHNhdmUgdGhlIG91dHB1dC4gDQoNCg0KYGBge3J9DQplbmdsaXNoICU+JSANCiAgZ3JvdXBfYnkoQWdlU3ViamVjdCwgV29yZENhdGVnb3J5LCBWb2ljZSkgJT4lIA0KICBzdW1tYXJpc2UoY291bnQgPSBuKCksDQogICAgICAgICAgICByYW5nZV9SVGxleGRlYyA9IHJhbmdlKFJUbGV4ZGVjKSwNCiAgICAgICAgICAgIG1lYW5fUlRsZXhkZWMgPSBtZWFuKFJUbGV4ZGVjKSwNCiAgICAgICAgICAgIHNkX1JUbGV4ZGVjID0gc2QoUlRsZXhkZWMpLA0KICAgICAgICAgICAgdmFyX1JUbGV4ZGVjID0gdmFyKFJUbGV4ZGVjKSwNCiAgICAgICAgICAgIG1pbl9SVGxleGRlYyA9IG1pbihSVGxleGRlYyksDQogICAgICAgICAgICBtYXhfUlRsZXhkZWMgPSBtYXgoUlRsZXhkZWMpLA0KICAgICAgICAgICAgcXVhcnQxX1JUbGV4ZGVjID0gcXVhbnRpbGUoUlRsZXhkZWMsIDAuMjUpLA0KICAgICAgICAgICAgcXVhcnQxX1JUbGV4ZGVjID0gcXVhbnRpbGUoUlRsZXhkZWMsIDAuNzUpLA0KICAgICAgICAgICAgbWVkaWFuX1JUbGV4ZGVjID0gbWVkaWFuKFJUbGV4ZGVjKSkgLT4gZGZNZWFucw0KZGZNZWFucw0KYGBgDQoNCg0KDQojIyMgQWN0aXZpdHkgb24geW91ciBvd24gMg0KDQpVc2UgYW55IG9mIHRoZSBudW1lcmljIHZhbHVlcyBpbiB0aGUgZGF0YXNldCBhbmQgb2J0YWluIHN1bW1hcmllcw0KDQpgYGB7cn0NCg0KYGBgDQoNCg0KDQoNCiMgRW5kIG9mIHRoZSBzZXNzaW9uDQoNClRoaXMgaXMgdGhlIGVuZCBvZiB0aGUgc2Vjb25kIHNlc3Npb24uIFdlIGxvb2tlZCBhdCB0aGUgdmFyaW91cyBvYmplY3QgdHlwZXMsIGFuZCBjcmVhdGVkIGEgZGF0YWZyYW1lIGZyb20gc2NyYXRjaC4gV2UgZGlkIHNvbWUgbWFuaXB1bGF0aW9ucyBvZiB0aGUgZGF0YWZyYW1lLCBieSBjcmVhdGluZyBhIG5ldyB2YXJpYWJsZSwgcmVuYW1pbmcgYSBjb2x1bW4sIGRlbGV0aW5nIG9uZSwgYW5kIGNoYW5naW5nIHRoZSBsZXZlbHMgb2YgYSB2YXJpYWJsZS4gV2UgdXNlIHRoZSBwYWNrYWdlIGBUaWR5dmVyc2VgIHRvIG1hbmlwdWxhdGUgb2JqZWN0cy4gV2Ugb2J0YWluZWQgdGhlbiBiYXNpYyBzdW1tYXJpZXMgYW5kIGJhc2ljIHBsb3RzLiANCg0KTmV4dCB3ZWVrLCB3ZSB3aWxsIGNvbnRpbnVlIHdpdGggdGhlIHBhY2thZ2UgYFRpZHl2ZXJzZWAgdG8gbWFuaXB1bGF0ZSB0aGUgZGF0YSBtb3JlIGFuZCBvYnRhaW4gYWRkaXRpb25hbCBwbG90cy4gDQoNCg0KIyBzZXNzaW9uIGluZm8NCg0KYGBge3Igd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgZXJyb3I9RkFMU0V9DQpzZXNzaW9uSW5mbygpDQpgYGANCg0KDQo=