Chapter 2: Using the command line
Get comfortable using the terminal for navigation using commands
like: ls, cd, mkdir Reference
Chapter 3: Version Control
A closer look at git/GitHub, make a repo, commit to it Here’s My Github
Chapter 4: Using Markdown for
Documentation
All of the readmes for this project are made using markdown
Chapter 5: Introduction to R
print("Hello world!")
[1] "Hello world!"
Chapter 6: Functions
# Here's a function declaration
my_cool_function <- function(some_variable, another_variable){
value_to_return <- some_variable + another_variable
value_to_return # The value to be returned should be called as the last instruction
}
my_cool_function(10,5)
[1] 15
# Here is a function with a conditional statement
greet_user <- function(name){
if (name == "Tom"){
print("What is up, T-Dawg")
} else {
sprintf("Hello % s", name)
}
}
greet_user("Tom")
[1] "What is up, T-Dawg"
greet_user("Joe Bloggs")
[1] "Hello Joe Bloggs"
Chapter 7: Vectors
A vector is a collection of data, like a list of numbers or names or
dates of birth. R is a popular data science language as the majority of
functions and tools are built to work with vectorised data.
cat("A vector : ",a_vector, "\nA vector * 2: ", a_vector *2)
A vector : 1 2 3 4 5
A vector * 2: 2 4 6 8 10
This approach scales up very well for working with big databases!
It’s both easier to follow logically and more efficient in terms of
computer processing!
Chapter 8: Lists
Lists are essentially a vector that can hold multiple data types,
useful for working with related data.
some_employee <- list(
forename = "Joe",
surname = "Bloggs",
job = "CEO",
salary = 999999,
union_member = TRUE
)
some_employee$surname
[1] "Bloggs"
some_employee[2]
$surname
[1] "Bloggs"
some_employee[["surname"]]
[1] "Bloggs"
Chapter 9: Understanding Data
A more general topic about the world of data, covers topics such
as:
- Where data comes from:
- Sensors
- Surveys
- Record keeping
- Where to find data:
- Government publications (Big up the ONS)
- Newspapers/Journalists
- Scientific research
- Social media
- Online communities
- Different types of data:
- Nominal (apples and oranges)
- Ordinal (5 star rating, 4 star rating)
- Ratio/Continuous (Ordered with a fixed 0)
- Interval (Ordered but no fixed 0)
Chapter 10: Data Frames
Data frames are one of the most common ways to work with data, any
table is a data frame, an Excel spreadsheet is a data frame.
Chapter 11: Manipulating data with
dplyr
dplyr is a very useful and popular package for wrangling data, it has
a consistent “Grammar of data manipulation” * Select specific
features * Filter out what you don’t want * Mutate a
data set by creating new features * Arrange observations in
some way * Summarize data in terms of aggregates (e.g. mean,
median, range, max value) * Join data sets together
Chapter 12: Reshaping Data with tidyr
Tidy Data: 1. Each variable is in a column 2. Each observation is a
row 3. Each value is a cell
gather() # To make your data long
spread() # To make your data wide
Chapter 13: Accessing Databases
A little intro into using SQL and some info about relational
databases. Relational databases are pretty much a necessity for working
with more complex data structures, requiring information to be stored in
different places for different reasons. An example would be a music
library, it is much more scalable to have a big database of artists and
a separate big database of songs, pulling the necessary data as needed
rather than having it all in one huge mess. R can be used to work with
databases, like so:
Chapter 14: Accessing Web APIs
APIs are a very useful tool to access data, it allows companies to
share data in a secure way and allows developers to make specific data
requests instead of downloading entire databases systems to their local
machine and processing it from there! API data can be a bit fiddly, as
it may be in one of several different formats (commonly JSON or YAML)
and will likely arrive as nested dataframes which can be difficult to
keep track of.
```{r, echo=FALSE}
Error: attempt to use zero-length variable name
Once you have the data in a usable form, it’s business as usual.
Chapter 15: Designing Data
Visualisations
“The purpose of visualisation is insight, not pictures” -
Card, S.K., Mackinlay, J.D., & Shneiderman B. (1999)
As much as I like pretty graphs, they are in practice a means to an
end, and that end is communicating insights in an efficient manner.
It is important to remember what you are trying to do with a graph,
What is the specific question of interest you are attempting to
answer? What layout of data is most suitable for this? What graphical
encodings give the best perceptability to the data? (What colours show
the best?) Would a preattentive attribute work best? (Colour one point,
use a different shape, draw a box around an area etc.)
To make beautiful charts, remove clutter, don’t add design.
Chapter 16: Creating Visualisations with
ggplot2

There a bunch of different plotting styles and colour palettes and
co-ordinate systems, each graph will require consideration on how best
to display the data, then ggplot can be given the data and instructions
to produce that graph.
Chapter 17: Interactive Visualisation in
R
There are a few packages that give you “interactive” graphs very
easily! plotly, rbokeh and leaflet are covered in the book. In short:
plotly and rbokeh are pretty similar, leaflet is good for maps.
Chapter 18: Dynamic Reports with R
Markdown
This whole recap was written in R markdown! It can also do inline
commands too, for example:` 
becomes: I love exponents, 1024 is a great one!
Chapter 19: Building Interactive Web Applications with
Shiny
This was a fun chapter, shiny allows you to build simple websites
with code. The layouts are created with different objects like
titlePanel(), sidebarPanel() etc, then the content is rendered into a
webpage!
It’s considered best practice to split the website into separate
files, a UI file, a server file, and an app.R file that brings them
together.
setwd("~/GitHub/R-Practice")
# app.R
source("shiny/my_ui_file.R") # Creates "my_ui"
source("shiny/my_server_file.R") # Creates "my_server"
shinyApp(ui = my_ui, server = my_server)
# This website may be ugly, but it does work!
Here’s a demo of the website: 
LS0tDQp0aXRsZTogIk5vdmVtYmVyIFJlY2FwIg0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCg0KIyMjIyMgKioqQ2hhcHRlciAxOiBHZXR0aW5nIFN0YXJ0ZWQqKioNCkluc3RhbGwgW1JTdHVkaW9dKGh0dHBzOi8vcG9zaXQuY28vZG93bmxvYWRzLykgJiBbR2l0XShodHRwczovL2dpdGZvcndpbmRvd3Mub3JnLykNCg0KIyMjIyMgKioqQ2hhcHRlciAyOiBVc2luZyB0aGUgY29tbWFuZCBsaW5lKioqDQpHZXQgY29tZm9ydGFibGUgdXNpbmcgdGhlIHRlcm1pbmFsIGZvciBuYXZpZ2F0aW9uIHVzaW5nIGNvbW1hbmRzIGxpa2U6IGxzLCBjZCwgbWtkaXINCltSZWZlcmVuY2VdKGh0dHBzOi8vcmlwdHV0b3JpYWwuY29tL3Rlcm1pbmFsL2V4YW1wbGUvMjYwMjMvYmFzaWMtbmF2aWdhdGlvbi1jb21tYW5kcykNCg0KIyMjIyMgKioqQ2hhcHRlciAzOiBWZXJzaW9uIENvbnRyb2wqKioNCkEgY2xvc2VyIGxvb2sgYXQgZ2l0L0dpdEh1YiwgbWFrZSBhIHJlcG8sIGNvbW1pdCB0byBpdA0KSGVyZSdzIFtNeSBHaXRodWJdKGh0dHBzOi8vZ2l0aHViLmNvbS9Ub21qb2huc29uZWxsaXMpDQoNCiMjIyMjICoqKkNoYXB0ZXIgNDogVXNpbmcgTWFya2Rvd24gZm9yIERvY3VtZW50YXRpb24qKioNCkFsbCBvZiB0aGUgcmVhZG1lcyBmb3IgdGhpcyBwcm9qZWN0IGFyZSBtYWRlIHVzaW5nIG1hcmtkb3duDQoNCiMjIyMjICoqKkNoYXB0ZXIgNTogSW50cm9kdWN0aW9uIHRvIFIqKioNCg0KYGBge3J9DQpwcmludCgiSGVsbG8gd29ybGQhIikNCg0KP2Z1bmN0aW9uICMgQnJpbmdzIHVwIGhlbHBmdWwgaW5mbw0KVFJVRSArIEZBTFNFICMgQm9vbGVhbnMNCmBgYA0KDQojIyMjIyAqKipDaGFwdGVyIDY6IEZ1bmN0aW9ucyoqKg0KYGBge3J9DQojIEhlcmUncyBhIGZ1bmN0aW9uIGRlY2xhcmF0aW9uDQpteV9jb29sX2Z1bmN0aW9uIDwtIGZ1bmN0aW9uKHNvbWVfdmFyaWFibGUsIGFub3RoZXJfdmFyaWFibGUpew0KICB2YWx1ZV90b19yZXR1cm4gPC0gc29tZV92YXJpYWJsZSArIGFub3RoZXJfdmFyaWFibGUNCiAgdmFsdWVfdG9fcmV0dXJuICMgVGhlIHZhbHVlIHRvIGJlIHJldHVybmVkIHNob3VsZCBiZSBjYWxsZWQgYXMgdGhlIGxhc3QgaW5zdHJ1Y3Rpb24NCn0NCg0KbXlfY29vbF9mdW5jdGlvbigxMCw1KQ0KDQojIEhlcmUgaXMgYSBmdW5jdGlvbiB3aXRoIGEgY29uZGl0aW9uYWwgc3RhdGVtZW50DQpncmVldF91c2VyIDwtIGZ1bmN0aW9uKG5hbWUpew0KICBpZiAobmFtZSA9PSAiVG9tIil7DQogICAgcHJpbnQoIldoYXQgaXMgdXAsIFQtRGF3ZyIpDQogIH0gZWxzZSB7DQogICAgc3ByaW50ZigiSGVsbG8gJSBzIiwgbmFtZSkNCiAgfQ0KfQ0KDQpncmVldF91c2VyKCJUb20iKQ0KZ3JlZXRfdXNlcigiSm9lIEJsb2dncyIpDQpgYGANCg0KIyMjIyMgKioqQ2hhcHRlciA3OiBWZWN0b3JzKioqDQpBIHZlY3RvciBpcyBhIGNvbGxlY3Rpb24gb2YgZGF0YSwgbGlrZSBhIGxpc3Qgb2YgbnVtYmVycyBvciBuYW1lcyBvciBkYXRlcyBvZiBiaXJ0aC4NClIgaXMgYSBwb3B1bGFyIGRhdGEgc2NpZW5jZSBsYW5ndWFnZSBhcyB0aGUgbWFqb3JpdHkgb2YgZnVuY3Rpb25zIGFuZCB0b29scyBhcmUgYnVpbHQgdG8gd29yayB3aXRoIHZlY3RvcmlzZWQgZGF0YS4NCmBgYHtyfQ0KYV92ZWN0b3IgPC0gYygxLDIsMyw0LDUpDQphX3ZlY3Rvcg0KYV92ZWN0b3IgKiAyDQpgYGANClRoaXMgYXBwcm9hY2ggc2NhbGVzIHVwIHZlcnkgd2VsbCBmb3Igd29ya2luZyB3aXRoIGJpZyBkYXRhYmFzZXMhIEl0J3MgYm90aCBlYXNpZXIgdG8gZm9sbG93IGxvZ2ljYWxseSBhbmQgbW9yZSBlZmZpY2llbnQgaW4gdGVybXMgb2YgY29tcHV0ZXIgcHJvY2Vzc2luZyENCg0KIyMjIyMgKioqQ2hhcHRlciA4OiBMaXN0cyoqKg0KTGlzdHMgYXJlIGVzc2VudGlhbGx5IGEgdmVjdG9yIHRoYXQgY2FuIGhvbGQgbXVsdGlwbGUgZGF0YSB0eXBlcywgdXNlZnVsIGZvciB3b3JraW5nIHdpdGggcmVsYXRlZCBkYXRhLg0KYGBge3J9DQpzb21lX2VtcGxveWVlIDwtIGxpc3QoDQogIGZvcmVuYW1lID0gIkpvZSIsDQogIHN1cm5hbWUgPSAiQmxvZ2dzIiwNCiAgam9iID0gIkNFTyIsDQogIHNhbGFyeSA9IDk5OTk5OSwNCiAgdW5pb25fbWVtYmVyID0gVFJVRQ0KKQ0KDQpzb21lX2VtcGxveWVlJHN1cm5hbWUNCnNvbWVfZW1wbG95ZWVbMl0NCnNvbWVfZW1wbG95ZWVbWyJzdXJuYW1lIl1dDQpgYGANCg0KIyMjIyMgKioqQ2hhcHRlciA5OiBVbmRlcnN0YW5kaW5nIERhdGEqKioNCkEgbW9yZSBnZW5lcmFsIHRvcGljIGFib3V0IHRoZSB3b3JsZCBvZiBkYXRhLCBjb3ZlcnMgdG9waWNzIHN1Y2ggYXM6DQoNCiogV2hlcmUgZGF0YSBjb21lcyBmcm9tOg0KICArIFNlbnNvcnMNCiAgKyBTdXJ2ZXlzDQogICsgUmVjb3JkIGtlZXBpbmcNCiogV2hlcmUgdG8gZmluZCBkYXRhOg0KICArIEdvdmVybm1lbnQgcHVibGljYXRpb25zIChCaWcgdXAgdGhlIE9OUykNCiAgKyBOZXdzcGFwZXJzL0pvdXJuYWxpc3RzDQogICsgU2NpZW50aWZpYyByZXNlYXJjaA0KICArIFNvY2lhbCBtZWRpYQ0KICArIE9ubGluZSBjb21tdW5pdGllcw0KKiBEaWZmZXJlbnQgdHlwZXMgb2YgZGF0YToNCiAgKyBOb21pbmFsIChhcHBsZXMgYW5kIG9yYW5nZXMpDQogICsgT3JkaW5hbCAoNSBzdGFyIHJhdGluZywgNCBzdGFyIHJhdGluZykNCiAgKyBSYXRpby9Db250aW51b3VzIChPcmRlcmVkIHdpdGggYSBmaXhlZCAwKQ0KICArIEludGVydmFsIChPcmRlcmVkIGJ1dCBubyBmaXhlZCAwKQ0KDQojIyMjIyAqKipDaGFwdGVyIDEwOiBEYXRhIEZyYW1lcyoqKg0KRGF0YSBmcmFtZXMgYXJlIG9uZSBvZiB0aGUgbW9zdCBjb21tb24gd2F5cyB0byB3b3JrIHdpdGggZGF0YSwgYW55IHRhYmxlIGlzIGEgZGF0YSBmcmFtZSwgYW4gRXhjZWwgc3ByZWFkc2hlZXQgaXMgYSBkYXRhIGZyYW1lLg0KYGBge3J9DQpuYW1lIDwtIGMoIkFsaWNlIiwiQm9iIiwiQ2h1Y2tpZSIsIkR5bGFuIikNCmhlaWdodCA8LSBjKDEwMCwxNTAsMTc1LDc1KQ0Kd2VpZ2h0IDwtIGMoNTAsNzUsMTAwLDIwMCkNCg0KbXlfZGF0YWZyYW1lIDwtIGRhdGEuZnJhbWUobmFtZSwgaGVpZ2h0LCB3ZWlnaHQpDQpteV9kYXRhZnJhbWUNCg0KYGBgDQoNCiMjIyMjICoqKkNoYXB0ZXIgMTE6IE1hbmlwdWxhdGluZyBkYXRhIHdpdGggZHBseXIqKioNCmRwbHlyIGlzIGEgdmVyeSB1c2VmdWwgYW5kIHBvcHVsYXIgcGFja2FnZSBmb3Igd3JhbmdsaW5nIGRhdGEsIGl0IGhhcyBhIGNvbnNpc3RlbnQgIkdyYW1tYXIgb2YgZGF0YSBtYW5pcHVsYXRpb24iDQoqICpTZWxlY3QqIHNwZWNpZmljIGZlYXR1cmVzDQoqICpGaWx0ZXIqIG91dCB3aGF0IHlvdSBkb24ndCB3YW50DQoqICpNdXRhdGUqIGEgZGF0YSBzZXQgYnkgY3JlYXRpbmcgbmV3IGZlYXR1cmVzDQoqICpBcnJhbmdlKiBvYnNlcnZhdGlvbnMgaW4gc29tZSB3YXkNCiogKlN1bW1hcml6ZSogZGF0YSBpbiB0ZXJtcyBvZiBhZ2dyZWdhdGVzIChlLmcuIG1lYW4sIG1lZGlhbiwgcmFuZ2UsIG1heCB2YWx1ZSkNCiogKkpvaW4qIGRhdGEgc2V0cyB0b2dldGhlcg0KYGBge3J9DQpsaWJyYXJ5KGRwbHlyKQ0KbXlfZGF0YWZyYW1lICU+JQ0KICBmaWx0ZXIod2VpZ2h0IDwgMjAwKSAlPiUNCiAgbXV0YXRlKCJCTUkiID0gd2VpZ2h0IC8gKGhlaWdodC8xMDApXjIpICU+JQ0KICBzZWxlY3QobmFtZSwgQk1JKQ0KDQpgYGANCg0KIyMjIyMgKioqQ2hhcHRlciAxMjogUmVzaGFwaW5nIERhdGEgd2l0aCB0aWR5cioqKg0KVGlkeSBEYXRhOg0KMS4gRWFjaCB2YXJpYWJsZSBpcyBpbiBhIGNvbHVtbg0KMi4gRWFjaCBvYnNlcnZhdGlvbiBpcyBhIHJvdw0KMy4gRWFjaCB2YWx1ZSBpcyBhIGNlbGwNCmBgYHtyfQ0KZ2F0aGVyKCkgIyBUbyBtYWtlIHlvdXIgZGF0YSBsb25nDQpzcHJlYWQoKSAjIFRvIG1ha2UgeW91ciBkYXRhIHdpZGUNCmBgYA0KDQojIyMjIyAqKipDaGFwdGVyIDEzOiBBY2Nlc3NpbmcgRGF0YWJhc2VzKioqDQpBIGxpdHRsZSBpbnRybyBpbnRvIHVzaW5nIFNRTCBhbmQgc29tZSBpbmZvIGFib3V0IHJlbGF0aW9uYWwgZGF0YWJhc2VzLg0KUmVsYXRpb25hbCBkYXRhYmFzZXMgYXJlIHByZXR0eSBtdWNoIGEgbmVjZXNzaXR5IGZvciB3b3JraW5nIHdpdGggbW9yZSBjb21wbGV4IGRhdGEgc3RydWN0dXJlcywgcmVxdWlyaW5nIGluZm9ybWF0aW9uIHRvIGJlIHN0b3JlZCBpbiBkaWZmZXJlbnQgcGxhY2VzIGZvciBkaWZmZXJlbnQgcmVhc29ucy4gQW4gZXhhbXBsZSB3b3VsZCBiZSBhIG11c2ljIGxpYnJhcnksIGl0IGlzIG11Y2ggbW9yZSBzY2FsYWJsZSB0byBoYXZlIGEgYmlnIGRhdGFiYXNlIG9mIGFydGlzdHMgYW5kIGEgc2VwYXJhdGUgYmlnIGRhdGFiYXNlIG9mIHNvbmdzLCBwdWxsaW5nIHRoZSBuZWNlc3NhcnkgZGF0YSBhcyBuZWVkZWQgcmF0aGVyIHRoYW4gaGF2aW5nIGl0IGFsbCBpbiBvbmUgaHVnZSBtZXNzLg0KUiBjYW4gYmUgdXNlZCB0byB3b3JrIHdpdGggZGF0YWJhc2VzLCBsaWtlIHNvOg0KYGBge3J9DQpsaWJyYXJ5KCJSU1FMaXRlIikgIyBBbiBTUUwgcGFja2FnZQ0KbGlicmFyeSgiZHBseXIiKSAjIEdvb2Qgb2wnIGRwbHlyDQoNCiMgQ29ubmVjdCB0byBhIGRhdGFiYXNlDQpkYXRhYmFzZV9jb25uZWN0aW9uIDwtIGRiQ29ubmVjdChTUUxpdGUoKSwgZGJuYW1lID0gIn4vR2l0SHViL1ItUHJhY3RpY2UvRXhlcmNpc2VzL2NoYXB0ZXItMTMvZGF0YS9DaGlub29rX1NxbGl0ZS5zcWxpdGUiKQ0KDQojIEhhdmUgYSBsb29rIGF0IHRoZSBhdmFpbGFibGUgdGFibGVzDQojIGRiTGlzdFRhYmxlcyhkYXRhYmFzZV9jb25uZWN0aW9uKQ0KDQojICJjb2xsZWN0IiB0aGUgaW5mbyBpbiBhIHRhYmxlIGFuZCBwdXQgaXQgaW50byBhIGRhdGFmcmFtZSwgb3VyIHByZWZlcnJlZCB0aGluZyB0byB1c2UNCnRyYWNrX2RmIDwtIGNvbGxlY3QodGJsKGRhdGFiYXNlX2Nvbm5lY3Rpb24sICJUcmFjayIpKQ0KDQojIEhhdmUgYSBsb29rIGxpa2Ugbm9ybWFsIQ0KI2RmJE5hbWVbMTo1XQ0KDQojIExldCdzIGZpbmQgYWxsIHRoZSBzb25ncyBvZiBhIHBhcnRpY3VsYXIgZ2VucmUNCmdlbnJlX2RmIDwtIGNvbGxlY3QodGJsKGRhdGFiYXNlX2Nvbm5lY3Rpb24sICJHZW5yZSIpKQ0KIyBnZW5yZV9kZiROYW1lICMgVGhlcmUncyAyNSwgSSdsbCBwaWNrICJFbGVjdHJvbmljYS9EYW5jZSINCiMgV2UgbmVlZCB0byB1c2UgdGhlICJBcnRpc3QgSUQiIG9mIHRoaXMgYXJ0aXN0IHRvIGZpbmQgdGhlIHNvbmdzIHRoZXkgYXJlIGNyZWRpdGVkIHdpdGgNCmlkX3RvX3VzZSA8LSBnZW5yZV9kZiAlPiUNCiAgZmlsdGVyKE5hbWUgPT0gIkVsZWN0cm9uaWNhL0RhbmNlIikgJT4lDQogIHNlbGVjdChHZW5yZUlkKQ0KDQpyZXN1bHRzIDwtIHRyYWNrX2RmICU+JQ0KICBmaWx0ZXIoR2VucmVJZCA9PSBpZF90b191c2UkR2VucmVJZCkgJT4lDQogIGFycmFuZ2UoLU1pbGxpc2Vjb25kcykgJT4lICMgTG9uZ2VzdCBzb25nIHRvIHNob3J0ZXN0IHNvbmcNCiAgc2VsZWN0KE5hbWUsIENvbXBvc2VyKQ0KDQojIEhlcmUncyB0aGUgNSBsb25nZXN0IEVsZWN0cm9uaWMgc29uZ3MgaW4gdGhlIGRhdGFiYXNlDQpoZWFkKHJlc3VsdHMsIDUpDQojIFRoZXkncmUgYWxyaWdodCwgSSBsaXN0ZW5lZCB0byB0aGVtIHdoaWxlIHdyaXRpbmcgdGhlIG5leHQgY2hhcHRlciBvZiB0aGlzIHJlY2FwIQ0KDQojIEZpbmFsbHksIGNsb3NlIHRoZSBjb25uZWN0aW9uDQpkYkRpc2Nvbm5lY3QoZGF0YWJhc2VfY29ubmVjdGlvbikNCg0KYGBgDQoNCiMjIyMjICoqKkNoYXB0ZXIgMTQ6IEFjY2Vzc2luZyBXZWIgQVBJcyoqKg0KQVBJcyBhcmUgYSB2ZXJ5IHVzZWZ1bCB0b29sIHRvIGFjY2VzcyBkYXRhLCBpdCBhbGxvd3MgY29tcGFuaWVzIHRvIHNoYXJlIGRhdGEgaW4gYSBzZWN1cmUgd2F5IGFuZCBhbGxvd3MgZGV2ZWxvcGVycyB0byBtYWtlIHNwZWNpZmljIGRhdGEgcmVxdWVzdHMgaW5zdGVhZCBvZiBkb3dubG9hZGluZyBlbnRpcmUgZGF0YWJhc2VzIHN5c3RlbXMgdG8gdGhlaXIgbG9jYWwgbWFjaGluZSBhbmQgcHJvY2Vzc2luZyBpdCBmcm9tIHRoZXJlIQ0KQVBJIGRhdGEgY2FuIGJlIGEgYml0IGZpZGRseSwgYXMgaXQgbWF5IGJlIGluIG9uZSBvZiBzZXZlcmFsIGRpZmZlcmVudCBmb3JtYXRzIChjb21tb25seSBKU09OIG9yIFlBTUwpIGFuZCB3aWxsIGxpa2VseSBhcnJpdmUgYXMgbmVzdGVkIGRhdGFmcmFtZXMgd2hpY2ggY2FuIGJlIGRpZmZpY3VsdCB0byBrZWVwIHRyYWNrIG9mLg0KYGBge3J9DQpsaWJyYXJ5KCJqc29ubGl0ZSIpDQojIEEgdHlwaWNhbCByZXF1ZXN0IHdvdWxkIGxvb2sgbGlrZSB0aGlzOg0KIyBHRVQgc29tZSBkYXRhDQpyZXNwb25zZSA8LSBHRVQodXJpX29mX3RoZV9kYXRhLCBxdWVyeSA9IG15X3F1ZXJ5X3BhcmFtZXRlcnMpDQojIEV4dHJhY3QgdGhlIENPTlRFTlQgb2YgdGhlIHJlc3BvbnNlIHlvdSBnZXQNCnJlc3BvbnNlX3RleHQgPC0gY29udGVudChyZXNwb25zZSwgInRleHQiKQ0KIyBUdXJuIHRoZSBKU09OIGRhdGEgaW50byBhIGxpc3QNCnJlc3BvbnNlX2RhdGEgPC0gZnJvbUpTT04ocmVzcG9uc2VfdGV4dCkNCiMgWW91J2xsIGxpa2VseSBlbmQgdXAgd2l0aCBhIGRhdGFmcmFtZSBvZiBjb2x1bW5zIHdoaWNoIGFyZSBhbHNvIGRhdGFmcmFtZXMsIG1lc3N5IQ0KIyBTbyBGTEFUVEVOIGl0IQ0KZmxhdHRlbihyZXNwb25zZV9kYXRhKQ0KYGBgDQpPbmNlIHlvdSBoYXZlIHRoZSBkYXRhIGluIGEgdXNhYmxlIGZvcm0sIGl0J3MgYnVzaW5lc3MgYXMgdXN1YWwuDQoNCiMjIyMjICoqKkNoYXB0ZXIgMTU6IERlc2lnbmluZyBEYXRhIFZpc3VhbGlzYXRpb25zKioqDQpfIlRoZSBwdXJwb3NlIG9mIHZpc3VhbGlzYXRpb24gaXMgaW5zaWdodCwgbm90IHBpY3R1cmVzIl8NCi0gQ2FyZCwgUy5LLiwgTWFja2lubGF5LCBKLkQuLCAmIFNobmVpZGVybWFuIEIuICgxOTk5KQ0KDQpBcyBtdWNoIGFzIEkgbGlrZSBwcmV0dHkgZ3JhcGhzLCB0aGV5IGFyZSBpbiBwcmFjdGljZSBhIG1lYW5zIHRvIGFuIGVuZCwgYW5kIHRoYXQgZW5kIGlzIGNvbW11bmljYXRpbmcgaW5zaWdodHMgaW4gYW4gZWZmaWNpZW50IG1hbm5lci4NCg0KSXQgaXMgaW1wb3J0YW50IHRvIHJlbWVtYmVyIHdoYXQgeW91IGFyZSB0cnlpbmcgdG8gZG8gd2l0aCBhIGdyYXBoLA0KV2hhdCBpcyB0aGUgX3NwZWNpZmljXyBxdWVzdGlvbiBvZiBpbnRlcmVzdCB5b3UgYXJlIGF0dGVtcHRpbmcgdG8gYW5zd2VyPw0KV2hhdCBsYXlvdXQgb2YgZGF0YSBpcyBtb3N0IHN1aXRhYmxlIGZvciB0aGlzPw0KV2hhdCBncmFwaGljYWwgZW5jb2RpbmdzIGdpdmUgdGhlIGJlc3QgcGVyY2VwdGFiaWxpdHkgdG8gdGhlIGRhdGE/IChXaGF0IGNvbG91cnMgc2hvdyB0aGUgYmVzdD8pDQpXb3VsZCBhIHByZWF0dGVudGl2ZSBhdHRyaWJ1dGUgd29yayBiZXN0PyAoQ29sb3VyIG9uZSBwb2ludCwgdXNlIGEgZGlmZmVyZW50IHNoYXBlLCBkcmF3IGEgYm94IGFyb3VuZCBhbiBhcmVhIGV0Yy4pDQoNClRvIG1ha2UgYmVhdXRpZnVsIGNoYXJ0cywgcmVtb3ZlIGNsdXR0ZXIsIGRvbid0IGFkZCBkZXNpZ24uDQoNCiMjIyMjICoqKkNoYXB0ZXIgMTY6IENyZWF0aW5nIFZpc3VhbGlzYXRpb25zIHdpdGggZ2dwbG90MioqKg0KYGBge3J9DQpsaWJyYXJ5KCJnZ3Bsb3QyIikNCnggPC0gYygxLDIsMyw0LDUsNiw3LDgsOSwxMCkNCnkgPC0gYygxLDQsOSwxNiwyNSwzNiw0OSw2NCw4MSwxMDApDQpkZiA8LSBkYXRhLmZyYW1lKHgseSkNCg0KZ2dwbG90KGRhdGEgPSBkZiwgYWVzKHgseSkpICsNCiAgZ2VvbV9saW5lKGNvbG9yID0gInB1cnBsZSIsIGxpbmV3aWR0aD0yKSArDQogIGdlb21fcG9pbnQoc2l6ZSA9IDUsc2hhcGUgPSAxNikgKw0KICBnZ3RpdGxlKCJBbiB1Z2x5IGdyYXBoIG9mIHNxdWFyZSBudW1iZXJzIikgKw0KICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0geCkNCmBgYA0KDQpUaGVyZSBhIGJ1bmNoIG9mIGRpZmZlcmVudCBwbG90dGluZyBzdHlsZXMgYW5kIGNvbG91ciBwYWxldHRlcyBhbmQgY28tb3JkaW5hdGUgc3lzdGVtcywgZWFjaCBncmFwaCB3aWxsIHJlcXVpcmUgY29uc2lkZXJhdGlvbiBvbiBob3cgYmVzdCB0byBkaXNwbGF5IHRoZSBkYXRhLCB0aGVuIGdncGxvdCBjYW4gYmUgZ2l2ZW4gdGhlIGRhdGEgYW5kIGluc3RydWN0aW9ucyB0byBwcm9kdWNlIHRoYXQgZ3JhcGguDQoNCiMjIyMjICoqKkNoYXB0ZXIgMTc6IEludGVyYWN0aXZlIFZpc3VhbGlzYXRpb24gaW4gUioqKg0KVGhlcmUgYXJlIGEgZmV3IHBhY2thZ2VzIHRoYXQgZ2l2ZSB5b3UgImludGVyYWN0aXZlIiBncmFwaHMgdmVyeSBlYXNpbHkhDQpwbG90bHksIHJib2tlaCBhbmQgbGVhZmxldCBhcmUgY292ZXJlZCBpbiB0aGUgYm9vay4NCkluIHNob3J0OiBwbG90bHkgYW5kIHJib2tlaCBhcmUgcHJldHR5IHNpbWlsYXIsIGxlYWZsZXQgaXMgZ29vZCBmb3IgbWFwcy4NCg0KIyMjIyMgKioqQ2hhcHRlciAxODogRHluYW1pYyBSZXBvcnRzIHdpdGggUiBNYXJrZG93bioqKg0KVGhpcyB3aG9sZSByZWNhcCB3YXMgd3JpdHRlbiBpbiBSIG1hcmtkb3duIQ0KSXQgY2FuIGFsc28gZG8gaW5saW5lIGNvbW1hbmRzIHRvbywgZm9yIGV4YW1wbGU6YA0KIVtDb2RlXShpbWcvY29kZS5QTkcpDQoNCmJlY29tZXM6IEkgbG92ZSBleHBvbmVudHMsIGByIDJeMTBgIGlzIGEgZ3JlYXQgb25lIQ0KDQojIyMjIyAqKipDaGFwdGVyIDE5OiBCdWlsZGluZyBJbnRlcmFjdGl2ZSBXZWIgQXBwbGljYXRpb25zIHdpdGggU2hpbnkqKioNClRoaXMgd2FzIGEgZnVuIGNoYXB0ZXIsIHNoaW55IGFsbG93cyB5b3UgdG8gYnVpbGQgc2ltcGxlIHdlYnNpdGVzIHdpdGggY29kZS4NClRoZSBsYXlvdXRzIGFyZSBjcmVhdGVkIHdpdGggZGlmZmVyZW50IG9iamVjdHMgbGlrZSB0aXRsZVBhbmVsKCksIHNpZGViYXJQYW5lbCgpIGV0YywgdGhlbiB0aGUgY29udGVudCBpcyByZW5kZXJlZCBpbnRvIGEgd2VicGFnZSENCg0KSXQncyBjb25zaWRlcmVkIGJlc3QgcHJhY3RpY2UgdG8gc3BsaXQgdGhlIHdlYnNpdGUgaW50byBzZXBhcmF0ZSBmaWxlcywgYSBVSSBmaWxlLCBhIHNlcnZlciBmaWxlLCBhbmQgYW4gYXBwLlIgZmlsZSB0aGF0IGJyaW5ncyB0aGVtIHRvZ2V0aGVyLg0KDQpgYGB7cn0NCnNldHdkKCJ+L0dpdEh1Yi9SLVByYWN0aWNlIikNCiMgYXBwLlINCnNvdXJjZSgic2hpbnkvbXlfdWlfZmlsZS5SIikgIyBDcmVhdGVzICJteV91aSINCnNvdXJjZSgic2hpbnkvbXlfc2VydmVyX2ZpbGUuUiIpICMgQ3JlYXRlcyAibXlfc2VydmVyIg0Kc2hpbnlBcHAodWkgPSBteV91aSwgc2VydmVyID0gbXlfc2VydmVyKQ0KDQojIFRoaXMgd2Vic2l0ZSBtYXkgYmUgdWdseSwgYnV0IGl0IGRvZXMgd29yayENCg0KYGBgDQpIZXJlJ3MgYSBkZW1vIG9mIHRoZSB3ZWJzaXRlOg0KIVtXZWJzaXRlIERlbW9dKGltZy9zY3JlZW5ncmFiLmdpZikNCg==