In this section, we’ll step back into theory for a bit to talk about where the “tidy” in tidyverse comes from and why it is an important feature of data. We’ll also see how to transform data from “messy”/wide to “tidy”/long and vice versa.

What is Tidy Data?

Why Tidy Data?

Tidy data enables us to do lots of things!

  1. Great ggplots
  2. Summarize/slice the data in multiple ways
  3. Enable Exploratory Data Analysis
  4. Ensure assumptions are met for methods
  5. Enable Confirmatory Data Analysis

Beware of columns masquerading as variables!

library(tidyverse)
library(readr)
fertility_data <- read_csv("data/total_fertility.csv")
## Parsed with column specification:
## cols(
##   .default = col_double(),
##   `Total fertility rate` = col_character()
## )
## See spec(...) for full column specifications.
fertility_data

These columns are actually categories! 1800 doesn’t correspond to the values that follow below it. The same is true for any of the other column headers here. They correspond to the year in which the data is measured. That data is on fertility rate.

Ask yourself: do these columns go together as a single observation for your analysis?

Also ask yourself: What is the unit of observation?

Making data tidy: gather()

Use gather() when you need to make a bunch of columns into one column. In other words, when you want to convert “wide data” to “long data.”

# gather() has three standard arguments: data, key, and value
# data is usually loaded via the %>%
# key is what you want your new categorical column to be named
# value is for the actual values in the columns

# We don't want the `Total fertility rate` column to be included as part of the
# gather() operation, so we use the `-` notation to exclude it.

fertility_tidy <- fertility_data %>% 
  gather(key = "Year", value = "fertilityRate", -`Total fertility rate`) %>% 
  # Re-arrange and rename columns
  select(Country = `Total fertility rate`, Year, fertilityRate) %>% 
  # Remove rows with missing values 
  # (there are countries that have little to no information)
  na.omit()

fertility_tidy

Your Task: using this tidy data

Exercise 3.1

As a refresher from earlier in the workshop, how would we find the average fertility for each year?

# Write and check your answer here
# ONE SOLUTION
fertility_tidy %>% 
  group_by(Year) %>% 
  summarize(mean_fert = mean(fertilityRate))

How about from 1860 on?

fertility_tidy %>% 
  filter(Year >= 1860) %>% 
  summarize(mean_fert = mean(fertilityRate))

Making one column into many: spread()

Sometimes, you will need to go the other direction: take a long format dataset and make it into a more matrix-like format. This is necessary for such functions such as heatmap().

Let’s change things around and make the Country column into the variables (columns) in the dataset.

fertility_wide <- fertility_tidy %>% 
  # spread() takes a key (Country) and value (fertilityRate) argument
  # Note that we don't quote here, whereas we do in gather()
  spread(key = Country, value = fertilityRate) 

fertility_wide

Your Task - Who is the most democratic?

Exercise 3.2

Load the dem_score.csv dataset in the data folder. Tidy it up. Which countries had the highest democracy score in 2007?

Hint: you’ll have to use your dplyr skills as well.

#enter your answer here
# ONE SOLUTION
dem_score <- read_csv("data/dem_score.csv")
## Parsed with column specification:
## cols(
##   country = col_character(),
##   `1952` = col_integer(),
##   `1957` = col_integer(),
##   `1962` = col_integer(),
##   `1967` = col_integer(),
##   `1972` = col_integer(),
##   `1977` = col_integer(),
##   `1982` = col_integer(),
##   `1987` = col_integer(),
##   `1992` = col_integer(),
##   `1997` = col_integer(),
##   `2002` = col_integer(),
##   `2007` = col_integer()
## )
dem_score_tidy <- dem_score %>% 
  gather(key = "year", value = "democracy_score", -country)
dem_score_tidy %>% 
  filter(year == 2007) %>% 
  top_n(1, democracy_score)

What you learned in this section

How to convert


What’s Next?

We’ve showed you the bare basics of data wrangling in the tidyverse. There’s a ton more!

Where to go next?


Closing project


Conclusion

Data importing, wrangling, and tidying are often forgotten as being important parts of the data analysis pipeline. The tidyverse packages as designed to work together to import, tidy, and wrangle all in a consistent framework working with data frames.

More resources

  • Ted and Jessica Minnier created a free DataCamp course covering many of the topics covered here if you’d like to go back and practice on your own.
  • Chester and Albert Kim wrote a free introductory textbook to help beginners get going with R.
  • We’re biased but we also highly recommend Dave Robinson’s Introduction to the Tidyverse course on DataCamp that Chester helped to author in his role at DataCamp.
  • Alison Hill will also be launching a follow-up DataCamp course on data importing, data taming, and data tidying tentatively titled “Working with Data in the Tidyverse” later this summer. You can track its progress here.

Post-session survey

We appreciate and yearn for your constructive and descriptive feedback so that we can improve as educators. To further support this, please feel out this brief survey.

LS0tCnRpdGxlOiAiVGlkeSBEYXRhOiBXaHkgYW5kIEhvdyBTT0xVVElPTlMiCmF1dGhvcjogIlRlZCBMYWRlcmFzIGFuZCBDaGVzdGVyIElzbWF5IgpvdXRwdXQ6IAogIGh0bWxfZG9jdW1lbnQ6CiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICBjb2RlX2ZvbGRpbmc6IHNob3cKICAgIGRmX3ByaW50OiBwYWdlZAotLS0KCkluIHRoaXMgc2VjdGlvbiwgd2UnbGwgc3RlcCBiYWNrIGludG8gdGhlb3J5IGZvciBhIGJpdCB0byB0YWxrIGFib3V0IHdoZXJlIHRoZSAidGlkeSIgaW4gYHRpZHl2ZXJzZWAgY29tZXMgZnJvbSBhbmQgd2h5IGl0IGlzIGFuIGltcG9ydGFudCBmZWF0dXJlIG9mIGRhdGEuIFdlJ2xsIGFsc28gc2VlIGhvdyB0byB0cmFuc2Zvcm0gZGF0YSBmcm9tICJtZXNzeSIvd2lkZSB0byAidGlkeSIvbG9uZyBhbmQgdmljZSB2ZXJzYS4KCiMjIFdoYXQgaXMgVGlkeSBEYXRhPwoKLSBlYWNoIHJvdyBjb3JyZXNwb25kcyB0byBhbiBvYnNlcnZhdGlvbgotIGVhY2ggdmFyaWFibGUgaXMgYSBjb2x1bW4KLSBlYWNoIHR5cGUgb2Ygb2JzZXJ2YXRpb24gaXMgaW4gYSBkaWZmZXJlbnQgdGFibGUKCiFbXShmaWdzL3RpZHktMS5wbmcpCgojIyBXaHkgVGlkeSBEYXRhPwoKVGlkeSBkYXRhIGVuYWJsZXMgdXMgdG8gZG8gbG90cyBvZiB0aGluZ3MhCgoxKSBHcmVhdCBnZ3Bsb3RzCjIpIFN1bW1hcml6ZS9zbGljZSB0aGUgZGF0YSBpbiBtdWx0aXBsZSB3YXlzCjMpIEVuYWJsZSBFeHBsb3JhdG9yeSBEYXRhIEFuYWx5c2lzCjQpIEVuc3VyZSBhc3N1bXB0aW9ucyBhcmUgbWV0IGZvciBtZXRob2RzCjUpIEVuYWJsZSBDb25maXJtYXRvcnkgRGF0YSBBbmFseXNpcwoKIyMgQmV3YXJlIG9mIGNvbHVtbnMgbWFzcXVlcmFkaW5nIGFzIHZhcmlhYmxlcyEKCgpgYGB7cn0KbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkocmVhZHIpCmZlcnRpbGl0eV9kYXRhIDwtIHJlYWRfY3N2KCJkYXRhL3RvdGFsX2ZlcnRpbGl0eS5jc3YiKQpmZXJ0aWxpdHlfZGF0YQpgYGAKClRoZXNlIGNvbHVtbnMgYXJlIGFjdHVhbGx5IGNhdGVnb3JpZXMhIGAxODAwYCBkb2Vzbid0IGNvcnJlc3BvbmQgdG8gdGhlIHZhbHVlcyB0aGF0IGZvbGxvdyBiZWxvdyBpdC4gVGhlIHNhbWUgaXMgdHJ1ZSBmb3IgYW55IG9mIHRoZSBvdGhlciBjb2x1bW4gaGVhZGVycyBoZXJlLiBUaGV5IGNvcnJlc3BvbmQgdG8gdGhlIHllYXIgaW4gd2hpY2ggdGhlIGRhdGEgaXMgbWVhc3VyZWQuIFRoYXQgZGF0YSBpcyBvbiBmZXJ0aWxpdHkgcmF0ZS4KCkFzayB5b3Vyc2VsZjogZG8gdGhlc2UgY29sdW1ucyBnbyB0b2dldGhlciBhcyBhIHNpbmdsZSBvYnNlcnZhdGlvbiBmb3IgeW91ciBhbmFseXNpcz8KCkFsc28gYXNrIHlvdXJzZWxmOiBXaGF0IGlzIHRoZSB1bml0IG9mIG9ic2VydmF0aW9uPwoKCiMjIE1ha2luZyBkYXRhIHRpZHk6IGBnYXRoZXIoKWAKClVzZSBgZ2F0aGVyKClgIHdoZW4geW91IG5lZWQgdG8gbWFrZSBhIGJ1bmNoIG9mIGNvbHVtbnMgaW50byBvbmUgY29sdW1uLiBJbiBvdGhlciB3b3Jkcywgd2hlbiB5b3Ugd2FudCB0byBjb252ZXJ0ICJ3aWRlIGRhdGEiIHRvICJsb25nIGRhdGEuIgoKYGBge3J9CiMgZ2F0aGVyKCkgaGFzIHRocmVlIHN0YW5kYXJkIGFyZ3VtZW50czogZGF0YSwga2V5LCBhbmQgdmFsdWUKIyBkYXRhIGlzIHVzdWFsbHkgbG9hZGVkIHZpYSB0aGUgJT4lCiMga2V5IGlzIHdoYXQgeW91IHdhbnQgeW91ciBuZXcgY2F0ZWdvcmljYWwgY29sdW1uIHRvIGJlIG5hbWVkCiMgdmFsdWUgaXMgZm9yIHRoZSBhY3R1YWwgdmFsdWVzIGluIHRoZSBjb2x1bW5zCgojIFdlIGRvbid0IHdhbnQgdGhlIGBUb3RhbCBmZXJ0aWxpdHkgcmF0ZWAgY29sdW1uIHRvIGJlIGluY2x1ZGVkIGFzIHBhcnQgb2YgdGhlCiMgZ2F0aGVyKCkgb3BlcmF0aW9uLCBzbyB3ZSB1c2UgdGhlIGAtYCBub3RhdGlvbiB0byBleGNsdWRlIGl0LgoKZmVydGlsaXR5X3RpZHkgPC0gZmVydGlsaXR5X2RhdGEgJT4lIAogIGdhdGhlcihrZXkgPSAiWWVhciIsIHZhbHVlID0gImZlcnRpbGl0eVJhdGUiLCAtYFRvdGFsIGZlcnRpbGl0eSByYXRlYCkgJT4lIAogICMgUmUtYXJyYW5nZSBhbmQgcmVuYW1lIGNvbHVtbnMKICBzZWxlY3QoQ291bnRyeSA9IGBUb3RhbCBmZXJ0aWxpdHkgcmF0ZWAsIFllYXIsIGZlcnRpbGl0eVJhdGUpICU+JSAKICAjIFJlbW92ZSByb3dzIHdpdGggbWlzc2luZyB2YWx1ZXMgCiAgIyAodGhlcmUgYXJlIGNvdW50cmllcyB0aGF0IGhhdmUgbGl0dGxlIHRvIG5vIGluZm9ybWF0aW9uKQogIG5hLm9taXQoKQoKZmVydGlsaXR5X3RpZHkKYGBgCgojIyBZb3VyIFRhc2s6IHVzaW5nIHRoaXMgdGlkeSBkYXRhCgojIyMgRXhlcmNpc2UgMy4xCgpBcyBhIHJlZnJlc2hlciBmcm9tIGVhcmxpZXIgaW4gdGhlIHdvcmtzaG9wLCBob3cgd291bGQgd2UgZmluZCB0aGUgYXZlcmFnZSBmZXJ0aWxpdHkgZm9yIGVhY2ggeWVhcj8gCgpgYGB7cn0KIyBXcml0ZSBhbmQgY2hlY2sgeW91ciBhbnN3ZXIgaGVyZQojIE9ORSBTT0xVVElPTgpmZXJ0aWxpdHlfdGlkeSAlPiUgCiAgZ3JvdXBfYnkoWWVhcikgJT4lIAogIHN1bW1hcml6ZShtZWFuX2ZlcnQgPSBtZWFuKGZlcnRpbGl0eVJhdGUpKQpgYGAKCkhvdyBhYm91dCBmcm9tIDE4NjAgb24/CgpgYGB7cn0KZmVydGlsaXR5X3RpZHkgJT4lIAogIGZpbHRlcihZZWFyID49IDE4NjApICU+JSAKICBzdW1tYXJpemUobWVhbl9mZXJ0ID0gbWVhbihmZXJ0aWxpdHlSYXRlKSkKYGBgCgojIyBNYWtpbmcgb25lIGNvbHVtbiBpbnRvIG1hbnk6IGBzcHJlYWQoKWAKClNvbWV0aW1lcywgeW91IHdpbGwgbmVlZCB0byBnbyB0aGUgb3RoZXIgZGlyZWN0aW9uOiB0YWtlIGEgbG9uZyBmb3JtYXQgZGF0YXNldCBhbmQgbWFrZSBpdCBpbnRvIGEgbW9yZSBtYXRyaXgtbGlrZSBmb3JtYXQuIFRoaXMgaXMgbmVjZXNzYXJ5IGZvciBzdWNoIGZ1bmN0aW9ucyBzdWNoIGFzIGBoZWF0bWFwKClgLgoKTGV0J3MgY2hhbmdlIHRoaW5ncyBhcm91bmQgYW5kIG1ha2UgdGhlIGBDb3VudHJ5YCBjb2x1bW4gaW50byB0aGUgdmFyaWFibGVzIChjb2x1bW5zKSBpbiB0aGUgZGF0YXNldC4gCgpgYGB7cn0KZmVydGlsaXR5X3dpZGUgPC0gZmVydGlsaXR5X3RpZHkgJT4lIAogICMgc3ByZWFkKCkgdGFrZXMgYSBrZXkgKENvdW50cnkpIGFuZCB2YWx1ZSAoZmVydGlsaXR5UmF0ZSkgYXJndW1lbnQKICAjIE5vdGUgdGhhdCB3ZSBkb24ndCBxdW90ZSBoZXJlLCB3aGVyZWFzIHdlIGRvIGluIGdhdGhlcigpCiAgc3ByZWFkKGtleSA9IENvdW50cnksIHZhbHVlID0gZmVydGlsaXR5UmF0ZSkgCgpmZXJ0aWxpdHlfd2lkZQpgYGAKCiMjIFlvdXIgVGFzayAtIFdobyBpcyB0aGUgbW9zdCBkZW1vY3JhdGljPwoKIyMjIEV4ZXJjaXNlIDMuMgoKTG9hZCB0aGUgYGRlbV9zY29yZS5jc3ZgIGRhdGFzZXQgaW4gdGhlIGBkYXRhYCBmb2xkZXIuIFRpZHkgaXQgdXAuIFdoaWNoIGNvdW50cmllcyBoYWQgdGhlIGhpZ2hlc3QgZGVtb2NyYWN5IHNjb3JlIGluIDIwMDc/CgpIaW50OiB5b3UnbGwgaGF2ZSB0byB1c2UgeW91ciBgZHBseXJgIHNraWxscyBhcyB3ZWxsLgoKYGBge3J9CiNlbnRlciB5b3VyIGFuc3dlciBoZXJlCiMgT05FIFNPTFVUSU9OCmRlbV9zY29yZSA8LSByZWFkX2NzdigiZGF0YS9kZW1fc2NvcmUuY3N2IikKZGVtX3Njb3JlX3RpZHkgPC0gZGVtX3Njb3JlICU+JSAKICBnYXRoZXIoa2V5ID0gInllYXIiLCB2YWx1ZSA9ICJkZW1vY3JhY3lfc2NvcmUiLCAtY291bnRyeSkKZGVtX3Njb3JlX3RpZHkgJT4lIAogIGZpbHRlcih5ZWFyID09IDIwMDcpICU+JSAKICB0b3BfbigxLCBkZW1vY3JhY3lfc2NvcmUpCmBgYAoKIyMgV2hhdCB5b3UgbGVhcm5lZCBpbiB0aGlzIHNlY3Rpb24KCkhvdyB0byBjb252ZXJ0CgotIHdpZGUvbWVzc3kgZGF0YSBpbnRvIGxvbmcvdGlkeSBkYXRhIHVzaW5nIHRoZSBgZ2F0aGVyKClgIGZ1bmN0aW9uIGluIHRoZSBgdGlkeXJgIHBhY2thZ2UKLSBsb25nIGRhdGEgaW50byB3aWRlIGRhdGEgdXNpbmcgdGhlIGBzcHJlYWQoKWAgZnVuY3Rpb24gaW4gdGhlIGB0aWR5cmAgcGFja2FnZQoKLS0tCgojIyBXaGF0J3MgTmV4dD8KCldlJ3ZlIHNob3dlZCB5b3UgdGhlIGJhcmUgYmFzaWNzIG9mIGRhdGEgd3JhbmdsaW5nIGluIHRoZSB0aWR5dmVyc2UuIFRoZXJlJ3MgYSB0b24gbW9yZSEKCldoZXJlIHRvIGdvIG5leHQ/CgotIE1vcmUgY29vbCBmdW5jdGlvbnMgaW4gW2B0aWR5cmBdKGh0dHA6Ly90aWR5ci50aWR5dmVyc2Uub3JnLykKICAgIC0gVGhlIFtEYXRhIEltcG9ydF0oaHR0cHM6Ly9naXRodWIuY29tL3JzdHVkaW8vY2hlYXRzaGVldHMvcmF3L21hc3Rlci9kYXRhLWltcG9ydC5wZGYpIFJTdHVkaW8gY2hlYXRzaGVldCBhbHNvIGhhcyBhIHNlY3Rpb24gb24gYHRpZHlyYAotIDxodHRwOi8vdGlkeXZlcnNlLm9yZz4KICAgIC0gYGx1YnJpZGF0ZWAgZm9yIGRlYWxpbmcgd2l0aCBkYXRlcwogICAgLSBgc3RyaW5ncmAgZm9yIG1hbmlwdWxhdGluZyBzdHJpbmdzCiAgICAtIGBmb3JjYXRzYCBmb3Igd29ya2luZyB3aXRoIGNhdGVnb3JpY2FsIGRhdGEKLSBUaWR5dmVyc2UgY29tbXVuaXR5IHBhY2thZ2VzCiAgICAtIFtgbmFuaWFyYF0oaHR0cDovL25hbmlhci5uanRpZXJuZXkuY29tLykgZm9yIHRpZHkgaGFuZGxpbmcgb2YgbWlzc2luZyBkYXRhCiAgICAtIFtgaW5mZXJgXShodHRwczovL2luZmVyLm5ldGxpZnkuY29tKSBmb3IgdGlkeSBzdGF0aXN0aWNhbCBpbmZlcmVuY2UgICAgCi0gTW9kZXJuRGl2ZSAoYnkgQ2hlc3RlciBhbmQgQWxiZXJ0IEtpbSk6IGh0dHA6Ly93d3cubW9kZXJuZGl2ZS5jb20KLSBSIGZvciBEYXRhIFNjaWVuY2U6IGh0dHA6Ly9yNGRzLmhhZC5jby5uegotIFtWYXJpZXR5IG9mIGNvdXJzZXMgb24gRGF0YUNhbXBdKGh0dHBzOi8vd3d3LmRhdGFjYW1wLmNvbS9jb3Vyc2VzL3RlY2g6cikgCgotLS0KCiMgQ2xvc2luZyBwcm9qZWN0CgotIFRyeSB0byBsb2FkIGluIHlvdXIgb3duIGRhdGEgYW5kIHVzZSBgdGlkeXJgIHRvIGdldCBpdCBpbnRvIHRoZSByaWdodCBmb3JtYXQgaWYgbmVlZGVkIHRvIHVzZSBgZHBseXJgIHRvIGRvIHNvbWUgZGF0YSB3cmFuZ2xpbmcuIElmIHlvdSBkb24ndCBoYXZlIHlvdXIgb3duIGRhdGEsIGRvIHNvbWUgYW5hbHlzZXMgb24gdGhlIGBwZXJpb2RpY190YWJsZWAgZGF0YSB5b3UgbG9hZGVkIGluIGJlZm9yZSB1c2luZyBgZHBseXJgLiBXZSdsbCBiZSBhcm91bmQgdG8gYW5zd2VyIHF1ZXN0aW9ucy4gVGhhbmtzIG11Y2ghCgotLS0KCiMjIEtlZXAgaW4gVG91Y2ghCgotIFRlZDogW0B0bGFkZXJhc10oaHR0cHM6Ly90d2l0dGVyLmNvbS90bGFkZXJhcykgaHR0cHM6Ly9sYWRlcmFzdC5naXRodWIuaW8KLSBDaGVzdGVyOiBbQG9sZF9tYW5fY2hlc3Rlcl0oaHR0cHM6Ly90d2l0dGVyLmNvbS9vbGRfbWFuX2NoZXN0ZXIpIGh0dHBzOi8vY2hlc3Rlci5yYmluZC5pbwoKIyMgQ29uY2x1c2lvbgoKRGF0YSBpbXBvcnRpbmcsIHdyYW5nbGluZywgYW5kIHRpZHlpbmcgYXJlIG9mdGVuIGZvcmdvdHRlbiBhcyBiZWluZyBpbXBvcnRhbnQgcGFydHMgb2YgdGhlIGRhdGEgYW5hbHlzaXMgcGlwZWxpbmUuIFRoZSBgdGlkeXZlcnNlYCBwYWNrYWdlcyBhcyBkZXNpZ25lZCB0byB3b3JrIHRvZ2V0aGVyIHRvIGltcG9ydCwgdGlkeSwgYW5kIHdyYW5nbGUgYWxsIGluIGEgY29uc2lzdGVudCBmcmFtZXdvcmsgd29ya2luZyB3aXRoIGRhdGEgZnJhbWVzLgoKIyMgTW9yZSByZXNvdXJjZXMKCi0gVGVkIGFuZCBbSmVzc2ljYSBNaW5uaWVyXShodHRwOi8vamVzc2ljYW1pbm5pZXIuY29tLykgY3JlYXRlZCBhIGZyZWUgRGF0YUNhbXAgY291cnNlIGNvdmVyaW5nIG1hbnkgb2YgdGhlIHRvcGljcyBjb3ZlcmVkIGhlcmUgaWYgeW91J2QgbGlrZSB0byBnbyBiYWNrIGFuZCBwcmFjdGljZSBvbiB5b3VyIG93bi4gCi0gQ2hlc3RlciBhbmQgW0FsYmVydCBLaW1dKGh0dHA6Ly9ydWRlYm95YmVydC5yYmluZC5pby8pIHdyb3RlIGEgW2ZyZWUgaW50cm9kdWN0b3J5IHRleHRib29rXShodHRwczovL21vZGVybmRpdmUubmV0bGlmeS5jb20pIHRvIGhlbHAgYmVnaW5uZXJzIGdldCBnb2luZyB3aXRoIFIuIAotIFdlJ3JlIGJpYXNlZCBidXQgd2UgYWxzbyBoaWdobHkgcmVjb21tZW5kIERhdmUgUm9iaW5zb24ncyBbSW50cm9kdWN0aW9uIHRvIHRoZSBUaWR5dmVyc2VdKGh0dHBzOi8vd3d3LmRhdGFjYW1wLmNvbS9jb3Vyc2VzL2ludHJvZHVjdGlvbi10by10aGUtdGlkeXZlcnNlKSBjb3Vyc2Ugb24gRGF0YUNhbXAgdGhhdCBDaGVzdGVyIGhlbHBlZCB0byBhdXRob3IgaW4gaGlzIHJvbGUgYXQgRGF0YUNhbXAuIAotIEFsaXNvbiBIaWxsIHdpbGwgYWxzbyBiZSBsYXVuY2hpbmcgYSBmb2xsb3ctdXAgRGF0YUNhbXAgY291cnNlIG9uIGRhdGEgaW1wb3J0aW5nLCBkYXRhIHRhbWluZywgYW5kIGRhdGEgdGlkeWluZyB0ZW50YXRpdmVseSB0aXRsZWQgIldvcmtpbmcgd2l0aCBEYXRhIGluIHRoZSBUaWR5dmVyc2UiIGxhdGVyIHRoaXMgc3VtbWVyLiBZb3UgY2FuIHRyYWNrIGl0cyBwcm9ncmVzcyBbaGVyZV0oaHR0cHM6Ly90cmVsbG8uY29tL2IvSlNMYkJxV0IvZGF0YWNhbXAtY291cnNlLXJvYWRtYXApLgoKIyMjIFBvc3Qtc2Vzc2lvbiBzdXJ2ZXkKCldlIGFwcHJlY2lhdGUgYW5kIHllYXJuIGZvciB5b3VyIGNvbnN0cnVjdGl2ZSBhbmQgZGVzY3JpcHRpdmUgZmVlZGJhY2sgc28gdGhhdCB3ZSBjYW4gaW1wcm92ZSBhcyBlZHVjYXRvcnMuIFRvIGZ1cnRoZXIgc3VwcG9ydCB0aGlzLCBwbGVhc2UgZmVlbCBvdXQgdGhpcyBbYnJpZWYgc3VydmV5XShodHRwczovL2dvby5nbC9mb3Jtcy96MTg2SXJFZklMeFlwZW9wMikuCg==