Population and Size of Cities Ca. 1800
Data used by Playfair on population and size of some major European
cities around 1800 is available in a file at https://stat.uiowa.edu/~luke/data/Playfair .
This file can be read using read.table.
We can read it directly from the web as
Playfair <- read.table("https://stat.uiowa.edu/~luke/data/Playfair")
In an Rmarkdown file you might want to work on when you are not
connected to the internet it might be a good idea to download a local
copy if you dont have one and then use the local copy:
if (! file.exists("Playfair.dat"))
download.file("https://stat.uiowa.edu/~luke/data/Playfair",
"Playfair.dat")
You can hide this chunk with the chunk option
include = FALSE.
Using the local file:
Playfair <- read.table("Playfair.dat")
names(Playfair)
## [1] "population" "diameter"
head(Playfair, 2)
## population diameter
## Edinburgh 60 9.144
## Stockholm 63 9.652
This data frame isn’t in tidy form if we want to be able to use the
city names as a variable since read.table stores these as
the row names.
One approach to tidying this data frame is to
use the row names to create a new city variable;
remove the now redundant row names:
Playfair$city <- rownames(Playfair)
rownames(Playfair) <- NULL
head(Playfair, 2)
## population diameter city
## 1 60 9.144 Edinburgh
## 2 63 9.652 Stockholm
Another option is to read the data as three variables by skipping the
first row and then adding the variable names:
Playfair <- read.table("Playfair.dat", skip = 1)
names(Playfair)
## [1] "V1" "V2" "V3"
names(Playfair) <- c("city", "population", "diameter")
A third option is to use the rownames_to_column()
function in the tibble package.
Useful checks:
make sure the beginning and end of the file match
head() and tail();
make sure the variable types are what they should be;
make sure the number of rows matches the number of lines in the
file.
str can help:
str(Playfair)
## 'data.frame': 22 obs. of 3 variables:
## $ city : chr "Edinburgh" "Stockholm" "Florence" "Genoa" ...
## $ population: int 60 63 75 80 80 80 90 120 130 140 ...
## $ diameter : num 9.14 9.65 10.16 10.67 10.16 ...
One way to find the number of lines in the file:
length(readLines("Playfair.dat"))
## [1] 23
The number of lines in the file should be one more than the number of
rows.
It is not a bad idea to put a check in your file:
stopifnot(nrow(Playfair) + 1 == length(readLines("Playfair.dat")))
City Temperatures
The website https://www.timeanddate.com/weather/ provides current
temperatures for a number of cities around the world.
Values from January 12, 2026, were saved in a file you can download
from https://stat.uiowa.edu/~luke/data/citytemps.dat .
citytemps <- read.table("citytemps.dat", header = TRUE)
dim(citytemps)
## [1] 141 2
head(citytemps)
## city temp
## 1 Accra 84
## 2 Addis Ababa 73
## 3 Adelaide 66
## 4 Algiers 63
## 5 Almaty 9
## 6 Amman 50
Gapminder Data
The gapminder variable from the gapminder
package contains select data from the GapMinder project.
Additional data is available from the GapMinder web site .
library(gapminder)
dim(gapminder)
## [1] 1704 6
head(gapminder)
## # A tibble: 6 × 6
## country continent year lifeExp pop gdpPercap
## <fct> <fct> <int> <dbl> <int> <dbl>
## 1 Afghanistan Asia 1952 28.8 8425333 779.
## 2 Afghanistan Asia 1957 30.3 9240934 821.
## 3 Afghanistan Asia 1962 32.0 10267083 853.
## 4 Afghanistan Asia 1967 34.0 11537966 836.
## 5 Afghanistan Asia 1972 36.1 13079460 740.
## 6 Afghanistan Asia 1977 38.4 14880372 786.
Barley
The barley data set available in the
lattice package records total yield in bushels per acre for
10 varieties at 6 experimental sites in Minnesota in each of two
years.
library(lattice)
dim(barley)
## [1] 120 4
head(barley)
## yield variety year site
## 1 27.00000 Manchuria 1931 University Farm
## 2 48.86667 Manchuria 1931 Waseca
## 3 27.43334 Manchuria 1931 Morris
## 4 39.93333 Manchuria 1931 Crookston
## 5 32.96667 Manchuria 1931 Grand Rapids
## 6 28.96667 Manchuria 1931 Duluth
Diamonds
The diamonds data set available in the
ggplot2 package contains prices and other attributes of
almost 54,000 diamonds.
library(ggplot2)
dim(diamonds)
## [1] 53940 10
head(diamonds)
## # A tibble: 6 × 10
## carat cut color clarity depth table price x y z
## <dbl> <ord> <ord> <ord> <dbl> <dbl> <int> <dbl> <dbl> <dbl>
## 1 0.23 Ideal E SI2 61.5 55 326 3.95 3.98 2.43
## 2 0.21 Premium E SI1 59.8 61 326 3.89 3.84 2.31
## 3 0.23 Good E VS1 56.9 65 327 4.05 4.07 2.31
## 4 0.29 Premium I VS2 62.4 58 334 4.2 4.23 2.63
## 5 0.31 Good J SI2 63.3 58 335 4.34 4.35 2.75
## 6 0.24 Very Good J VVS2 62.8 57 336 3.94 3.96 2.48
Palmer Penguins
The palmerpenguins
package includes data for adult foraging Adélie, Chinstrap, and
Gentoo penguins observed on islands in the Palmer Archipelago near
Palmer Station, Antarctica.
Data were collected and made available by Dr. Kristen Gorman and the
Palmer Station Long Term Ecological Research (LTER) Program.
library(palmerpenguins)
penguins
## # A tibble: 344 × 8
## species island bill_length_mm bill_depth_mm flipper_length_mm body_mass_g
## <fct> <fct> <dbl> <dbl> <int> <int>
## 1 Adelie Torgersen 39.1 18.7 181 3750
## 2 Adelie Torgersen 39.5 17.4 186 3800
## 3 Adelie Torgersen 40.3 18 195 3250
## 4 Adelie Torgersen NA NA NA NA
## 5 Adelie Torgersen 36.7 19.3 193 3450
## 6 Adelie Torgersen 39.3 20.6 190 3650
## 7 Adelie Torgersen 38.9 17.8 181 3625
## 8 Adelie Torgersen 39.2 19.6 195 4675
## 9 Adelie Torgersen 34.1 18.1 193 3475
## 10 Adelie Torgersen 42 20.2 190 4250
## # ℹ 334 more rows
## # ℹ 2 more variables: sex <fct>, year <int>
Other Sources and Forms of Data
The Data Sources link contains
pointers to a range of different data sources.
Data is available in many forms.
Some are intended for human reading or editing:
Other forms are designed for reading by programs but may still be
human readable:
CSV files.
Json and GeoJson files.
Web APIs.
In some cases data has been wrapped in R packages, or an R package is
available for working with a specific API.
Some tools that are available for human-friendly forms:
Text files: read.table, readr::read_table,
readLines.
Excel: readxl::read_xls
Web pages: rvest package.
Some tools for machine-friendly forms:
CSV files: read.csv, readr::read_csv.
Json: jsonlite::fromJSON.
Web APIs: httr package.
Example: Reading a table from Wikipedia
A Wikipedia page (permanent
link to an older version from 2017 ) contains a table with data on
gun murders in the US by states.
url <- paste0("https://en.wikipedia.org/w/index.php?title=",
"Gun_violence_in_the_United_States_by_state&",
"direction=prev&oldid=810166167")
library(tidyverse)
library(rvest)
h <- read_html(url)
tbs <- html_table(html_nodes(h, "table"))
murders <- tbs[[1]]
names(murders) <- c("state", "pop", "murders", "rate")
murders <- mutate(murders,
across(2 : 3, function(x) as.numeric(gsub(",", "", x))))
p <- ggplot(murders, aes(x = pop, y = murders))
p + geom_point()
library(plotly)
ggplotly(p + geom_point(aes(text = state)))
Example: Test Scores in an Excel Spreadsheet
A simple Excel file is available in the dslabs package
(GitHub
source ):
score_file <-
system.file("extdata", "2010_bigfive_regents.xls", package = "dslabs")
readxl::read_xls(score_file)
More
complicated files will need more processing.
Exercises
Read in the Playfair data using the read.table function
and tidy the result using the rownames_to_column function
from the tibble package.
The variables site, variety, and
year in the barley data set are
factors . How many levels do each of these variables
have? [You can use the functions levels and
length.]
LS0tCnRpdGxlOiAiU29tZSBVc2VmdWwgRGF0YSBTZXRzIgpvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDoKICAgIHRvYzogeWVzCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCi0tLQoKPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBocmVmPSJzdGF0NDU4MC5jc3MiIHR5cGU9InRleHQvY3NzIiAvPgoKYGBge3Igc2V0dXAsIGluY2x1ZGUgPSBGQUxTRX0Kc291cmNlKGhlcmU6OmhlcmUoInNldHVwLlIiKSkKa25pdHI6Om9wdHNfY2h1bmskc2V0KGNvbGxhcHNlID0gVFJVRSwgbWVzc2FnZSA9IEZBTFNFLAogICAgICAgICAgICAgICAgICAgICAgZmlnLmhlaWdodCA9IDUsIGZpZy53aWR0aCA9IDYsIGZpZy5hbGlnbiA9ICJjZW50ZXIiKQpgYGAKCgojIyBQb3B1bGF0aW9uIGFuZCBTaXplIG9mIENpdGllcyBDYS4gMTgwMAoKRGF0YSB1c2VkIGJ5IFBsYXlmYWlyIG9uIHBvcHVsYXRpb24gYW5kIHNpemUgb2Ygc29tZSBtYWpvciBFdXJvcGVhbgpjaXRpZXMgYXJvdW5kIDE4MDAgaXMgYXZhaWxhYmxlIGluIGEgZmlsZSBhdAo8aHR0cHM6Ly9zdGF0LnVpb3dhLmVkdS9+bHVrZS9kYXRhL1BsYXlmYWlyPi4KClRoaXMgZmlsZSBjYW4gYmUgcmVhZCB1c2luZyBgcmVhZC50YWJsZWAuCgpXZSBjYW4gcmVhZCBpdCBkaXJlY3RseSBmcm9tIHRoZSB3ZWIgYXMKCmBgYHtyLCBldmFsID0gRkFMU0V9ClBsYXlmYWlyIDwtIHJlYWQudGFibGUoImh0dHBzOi8vc3RhdC51aW93YS5lZHUvfmx1a2UvZGF0YS9QbGF5ZmFpciIpCmBgYAoKSW4gYW4gUm1hcmtkb3duIGZpbGUgeW91IG1pZ2h0IHdhbnQgdG8gd29yayBvbiB3aGVuIHlvdSBhcmUgbm90CmNvbm5lY3RlZCB0byB0aGUgaW50ZXJuZXQgaXQgbWlnaHQgYmUgYSBnb29kIGlkZWEgdG8gZG93bmxvYWQgYSBsb2NhbApjb3B5IGlmIHlvdSBkb250IGhhdmUgb25lIGFuZCB0aGVuIHVzZSB0aGUgbG9jYWwgY29weToKCmBgYHtyfQppZiAoISBmaWxlLmV4aXN0cygiUGxheWZhaXIuZGF0IikpCiAgICBkb3dubG9hZC5maWxlKCJodHRwczovL3N0YXQudWlvd2EuZWR1L35sdWtlL2RhdGEvUGxheWZhaXIiLAogICAgICAgICAgICAgICAgICAiUGxheWZhaXIuZGF0IikKYGBgCgpZb3UgY2FuIGhpZGUgdGhpcyBjaHVuayB3aXRoIHRoZSBjaHVuayBvcHRpb24gYGluY2x1ZGUgPSBGQUxTRWAuCgpVc2luZyB0aGUgbG9jYWwgZmlsZToKYGBge3J9ClBsYXlmYWlyIDwtIHJlYWQudGFibGUoIlBsYXlmYWlyLmRhdCIpCm5hbWVzKFBsYXlmYWlyKQpoZWFkKFBsYXlmYWlyLCAyKQpgYGAKClRoaXMgZGF0YSBmcmFtZSBpc24ndCBpbiB0aWR5IGZvcm0gaWYgd2Ugd2FudCB0byBiZSBhYmxlIHRvIHVzZSB0aGUKY2l0eSBuYW1lcyBhcyBhIHZhcmlhYmxlIHNpbmNlIGByZWFkLnRhYmxlYCBzdG9yZXMgdGhlc2UgYXMgdGhlIHJvdwpuYW1lcy4KCk9uZSBhcHByb2FjaCB0byB0aWR5aW5nIHRoaXMgZGF0YSBmcmFtZSBpcyB0bwoKKiB1c2UgdGhlIHJvdyBuYW1lcyB0byBjcmVhdGUgYSBuZXcgYGNpdHlgIHZhcmlhYmxlOwoqIHJlbW92ZSB0aGUgbm93IHJlZHVuZGFudCByb3cgbmFtZXM6CgpgYGB7cn0KUGxheWZhaXIkY2l0eSA8LSByb3duYW1lcyhQbGF5ZmFpcikKcm93bmFtZXMoUGxheWZhaXIpIDwtIE5VTEwKaGVhZChQbGF5ZmFpciwgMikKYGBgCgpBbm90aGVyIG9wdGlvbiBpcyB0byByZWFkIHRoZSBkYXRhIGFzIHRocmVlIHZhcmlhYmxlcyBieSBza2lwcGluZyB0aGUKZmlyc3Qgcm93IGFuZCB0aGVuIGFkZGluZyB0aGUgdmFyaWFibGUgbmFtZXM6CmBgYHtyfQpQbGF5ZmFpciA8LSByZWFkLnRhYmxlKCJQbGF5ZmFpci5kYXQiLCBza2lwID0gMSkKbmFtZXMoUGxheWZhaXIpCm5hbWVzKFBsYXlmYWlyKSA8LSBjKCJjaXR5IiwgInBvcHVsYXRpb24iLCAiZGlhbWV0ZXIiKQpgYGAKCkEgdGhpcmQgb3B0aW9uIGlzIHRvIHVzZSB0aGUgYHJvd25hbWVzX3RvX2NvbHVtbigpYCBmdW5jdGlvbiBpbiB0aGUKYHRpYmJsZWAgcGFja2FnZS4KClVzZWZ1bCBjaGVja3M6CgoqIG1ha2Ugc3VyZSB0aGUgYmVnaW5uaW5nIGFuZCBlbmQgb2YgdGhlIGZpbGUgbWF0Y2ggYGhlYWQoKWAgYW5kIGB0YWlsKClgOwoKKiBtYWtlIHN1cmUgdGhlIHZhcmlhYmxlIHR5cGVzIGFyZSB3aGF0IHRoZXkgc2hvdWxkIGJlOwoKKiBtYWtlIHN1cmUgdGhlIG51bWJlciBvZiByb3dzIG1hdGNoZXMgdGhlIG51bWJlciBvZiBsaW5lcyBpbiB0aGUgZmlsZS4KCmBzdHJgIGNhbiBoZWxwOgoKYGBge3J9CnN0cihQbGF5ZmFpcikKYGBgCgpPbmUgd2F5IHRvIGZpbmQgdGhlIG51bWJlciBvZiBsaW5lcyBpbiB0aGUgZmlsZToKYGBge3J9Cmxlbmd0aChyZWFkTGluZXMoIlBsYXlmYWlyLmRhdCIpKQpgYGAKClRoZSBudW1iZXIgb2YgbGluZXMgaW4gdGhlIGZpbGUgc2hvdWxkIGJlIG9uZSBtb3JlIHRoYW4gdGhlIG51bWJlciBvZiByb3dzLgoKSXQgaXMgbm90IGEgYmFkIGlkZWEgdG8gcHV0IGEgY2hlY2sgaW4geW91ciBmaWxlOgoKYGBge3J9CnN0b3BpZm5vdChucm93KFBsYXlmYWlyKSArIDEgPT0gbGVuZ3RoKHJlYWRMaW5lcygiUGxheWZhaXIuZGF0IikpKQpgYGAKCgojIyBDaXR5IFRlbXBlcmF0dXJlcwoKYGBge3IsIGVjaG8gPSBGQUxTRSwgZXZhbCA9IEZBTFNFfQojIyBzY3JhcGluZyBhbmQgY2xlYW5pbmcKbGlicmFyeShydmVzdCkKd2VhdGhlciA8LSByZWFkX2h0bWwoImh0dHBzOi8vd3d3LnRpbWVhbmRkYXRlLmNvbS93ZWF0aGVyLyIpCncgPC0gaHRtbF90YWJsZShodG1sX25vZGVzKHdlYXRoZXIsICJ0YWJsZSIpKVtbMV1dCgpuYW1lcyh3KSA8LSBwYXN0ZTAoIlYiLCAxIDogMTIpCncxIDwtIHdbMSA6IDRdCncyIDwtIHdbNSA6IDhdOyBuYW1lcyh3MikgPC0gcGFzdGUwKCJWIiwgMSA6IDQpCnczIDwtIHdbOSA6IDEyXTsgbmFtZXModzMpIDwtIHBhc3RlMCgiViIsIDEgOiA0KQp3dyA8LSByYmluZCh3MSwgdzIsIHczKQojIyBtYXliZSB0cnkgdG8gcGFyc2UgdGhlIGxvY2FsIHRpbWVzIGluIFYyPwojIyB0aGUgc3RhcnMgaW5kaWNhdGUgRFNUIC0tIHNvdXRoZXJuIGhlbWlzcGhlcmUgaW4gSmFudWFyeQp3d3cgPC0gZGF0YS5mcmFtZShjaXR5ID0gc3ViKCIgXFwqIiwgIiIsIHd3JFYxKSwKICAgICAgICAgICAgICAgICAgdGVtcCA9IGFzLm51bWVyaWMoc3ViKCIoWy0rXT9bWzpkaWdpdDpdXSspLioiLCAiXFwxIiwgd3ckVjQpKSkKd3d3IDwtIHd3d1tjb21wbGV0ZS5jYXNlcyh3d3cpLCBdCgp3cml0ZS50YWJsZSh3d3csIHJvdy5uYW1lcyA9IEZBTFNFLCBmaWxlID0gImNpdHl0ZW1wcy5kYXQiKQojIHNjcmFwZWQgZnJvbSBodHRwczovL3d3dy50aW1lYW5kZGF0ZS5jb20vd2VhdGhlci8gb24gMjAyNi0wMS0xMiAxMzowNSBDU1QKaGVhZChyZWFkLnRhYmxlKCJjaXR5dGVtcHMuZGF0IiwgaGVhZGVyID0gVFJVRSkpCmBgYAoKYGBge3IsIGVjaG8gPSBGQUxTRX0KaWYgKCEgZmlsZS5leGlzdHMoImNpdHl0ZW1wcy5kYXQiKSkKICAgIGRvd25sb2FkLmZpbGUoImh0dHBzOi8vc3RhdC51aW93YS5lZHUvfmx1a2UvZGF0YS9jaXR5dGVtcHMuZGF0IiwKICAgICAgICAgICAgICAgICAgImNpdHl0ZW1wcy5kYXQiKQpgYGAKClRoZSB3ZWJzaXRlIDxodHRwczovL3d3dy50aW1lYW5kZGF0ZS5jb20vd2VhdGhlci8+IHByb3ZpZGVzIGN1cnJlbnQKdGVtcGVyYXR1cmVzIGZvciBhIG51bWJlciBvZiBjaXRpZXMgYXJvdW5kIHRoZSB3b3JsZC4KClZhbHVlcyBmcm9tIEphbnVhcnkgMTIsIDIwMjYsIHdlcmUgc2F2ZWQgaW4gYSBmaWxlIHlvdSBjYW4gZG93bmxvYWQKZnJvbSA8aHR0cHM6Ly9zdGF0LnVpb3dhLmVkdS9+bHVrZS9kYXRhL2NpdHl0ZW1wcy5kYXQ+LgoKYGBge3J9CmNpdHl0ZW1wcyA8LSByZWFkLnRhYmxlKCJjaXR5dGVtcHMuZGF0IiwgaGVhZGVyID0gVFJVRSkKZGltKGNpdHl0ZW1wcykKaGVhZChjaXR5dGVtcHMpCmBgYAoKCiMjIEdhcG1pbmRlciBEYXRhCgpUaGUgYGdhcG1pbmRlcmAgdmFyaWFibGUgZnJvbSB0aGUgYGdhcG1pbmRlcmAgcGFja2FnZSBjb250YWlucyBzZWxlY3QKZGF0YSBmcm9tIHRoZSBbR2FwTWluZGVyXShodHRwczovL3d3dy5nYXBtaW5kZXIub3JnKSBwcm9qZWN0LgoKQWRkaXRpb25hbCBkYXRhIGlzIGF2YWlsYWJsZSBmcm9tIHRoZSBbR2FwTWluZGVyIHdlYgpzaXRlXShodHRwczovL3d3dy5nYXBtaW5kZXIub3JnKS4KCmBgYHtyfQpsaWJyYXJ5KGdhcG1pbmRlcikKZGltKGdhcG1pbmRlcikKaGVhZChnYXBtaW5kZXIpCmBgYAoKCiMjIEJhcmxleQoKVGhlIGBiYXJsZXlgIGRhdGEgc2V0IGF2YWlsYWJsZSBpbiB0aGUgYGxhdHRpY2VgIHBhY2thZ2UgcmVjb3JkcyB0b3RhbAp5aWVsZCBpbiBidXNoZWxzIHBlciBhY3JlIGZvciAxMCB2YXJpZXRpZXMgYXQgNiBleHBlcmltZW50YWwgc2l0ZXMgaW4KTWlubmVzb3RhIGluIGVhY2ggb2YgdHdvIHllYXJzLgoKYGBge3J9CmxpYnJhcnkobGF0dGljZSkKZGltKGJhcmxleSkKaGVhZChiYXJsZXkpCmBgYAoKCiMjIERpYW1vbmRzCgpUaGUgYGRpYW1vbmRzYCBkYXRhIHNldCBhdmFpbGFibGUgaW4gdGhlIGBnZ3Bsb3QyYCBwYWNrYWdlIGNvbnRhaW5zCnByaWNlcyBhbmQgb3RoZXIgYXR0cmlidXRlcyBvZiBhbG1vc3QgNTQsMDAwIGRpYW1vbmRzLgoKYGBge3J9CmxpYnJhcnkoZ2dwbG90MikKZGltKGRpYW1vbmRzKQpoZWFkKGRpYW1vbmRzKQpgYGAKCgojIyBQYWxtZXIgUGVuZ3VpbnMKClRoZSBbYHBhbG1lcnBlbmd1aW5zYApwYWNrYWdlXShodHRwczovL2FsbGlzb25ob3JzdC5naXRodWIuaW8vcGFsbWVycGVuZ3VpbnMvKSBpbmNsdWRlcyBkYXRhCmZvciBhZHVsdCBmb3JhZ2luZyBBZMOpbGllLCBDaGluc3RyYXAsIGFuZCBHZW50b28gcGVuZ3VpbnMgb2JzZXJ2ZWQgb24KaXNsYW5kcyBpbiB0aGUgUGFsbWVyIEFyY2hpcGVsYWdvIG5lYXIgUGFsbWVyIFN0YXRpb24sIEFudGFyY3RpY2EuCgpEYXRhIHdlcmUgY29sbGVjdGVkIGFuZCBtYWRlIGF2YWlsYWJsZSBieQpEci4gS3Jpc3RlbiBHb3JtYW4gYW5kIHRoZSBQYWxtZXIgU3RhdGlvbiBMb25nIFRlcm0gRWNvbG9naWNhbApSZXNlYXJjaCAoTFRFUikgUHJvZ3JhbS4KCmBgYHtyLCBlY2hvID0gVFJVRX0KbGlicmFyeShwYWxtZXJwZW5ndWlucykKcGVuZ3VpbnMKYGBgCgoKIyMgT3RoZXIgU291cmNlcyBhbmQgRm9ybXMgb2YgRGF0YQoKVGhlIFtEYXRhIFNvdXJjZXMgbGlua10oYHIgV0xOSygiZGF0YXNvdXJjZXMuaHRtbCIpYCkgY29udGFpbnMKcG9pbnRlcnMgdG8gYSByYW5nZSBvZiBkaWZmZXJlbnQgZGF0YSBzb3VyY2VzLgoKRGF0YSBpcyBhdmFpbGFibGUgaW4gbWFueSBmb3Jtcy4KClNvbWUgYXJlIGludGVuZGVkIGZvciBodW1hbiByZWFkaW5nIG9yIGVkaXRpbmc6CgoqIFRleHQgZmlsZXMgaW4gdmFyaW91cyBmb3JtYXRzLgoKKiBFeGNlbCBzcHJlYWRzaGVldHMuCgoqIFRhYmxlcyBpbiB3ZWIgcGFnZXMuCgoqIFRhYmxlcyBpbiBQREYgZmlsZXMuCgpPdGhlciBmb3JtcyBhcmUgZGVzaWduZWQgZm9yIHJlYWRpbmcgYnkgcHJvZ3JhbXMgYnV0IG1heSBzdGlsbCBiZQpodW1hbiByZWFkYWJsZToKCiogQ1NWIGZpbGVzLgoKKiBKc29uIGFuZCBHZW9Kc29uIGZpbGVzLgoKKiBXZWIgQVBJcy4KCkluIHNvbWUgY2FzZXMgZGF0YSBoYXMgYmVlbiB3cmFwcGVkIGluIFIgcGFja2FnZXMsIG9yIGFuIFIgcGFja2FnZSBpcwphdmFpbGFibGUgZm9yIHdvcmtpbmcgd2l0aCBhIHNwZWNpZmljIEFQSS4KClNvbWUgdG9vbHMgdGhhdCBhcmUgYXZhaWxhYmxlIGZvciBodW1hbi1mcmllbmRseSBmb3JtczoKCiogVGV4dCBmaWxlczogYHJlYWQudGFibGVgLCBgcmVhZHI6OnJlYWRfdGFibGVgLCBgcmVhZExpbmVzYC4KKiBFeGNlbDogYHJlYWR4bDo6cmVhZF94bHNgCiogV2ViIHBhZ2VzOiBgcnZlc3RgIHBhY2thZ2UuCgpTb21lIHRvb2xzIGZvciBtYWNoaW5lLWZyaWVuZGx5IGZvcm1zOgoKKiBDU1YgZmlsZXM6IGByZWFkLmNzdmAsIGByZWFkcjo6cmVhZF9jc3ZgLgoqIEpzb246IGBqc29ubGl0ZTo6ZnJvbUpTT05gLgoqIFdlYiBBUElzOiBgaHR0cmAgcGFja2FnZS4KCgojIyMgRXhhbXBsZTogUmVhZGluZyBhIHRhYmxlIGZyb20gV2lraXBlZGlhCgo8IS0tIGZyb20gUmFmYSdzIGJvb2sgLS0+CkEgV2lraXBlZGlhIHBhZ2UgKFtwZXJtYW5lbnQgbGluayB0byBhbiBvbGRlcgp2ZXJzaW9uIGZyb20gMjAxN10oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3cvaW5kZXgucGhwP3RpdGxlPUd1bl92aW9sZW5jZV9pbl90aGVfVW5pdGVkX1N0YXRlc19ieV9zdGF0ZSZkaXJlY3Rpb249cHJldiZvbGRpZD04MTAxNjYxNjcpKQpjb250YWlucyBhIHRhYmxlIHdpdGggZGF0YSBvbiBndW4gbXVyZGVycyBpbiB0aGUgVVMgYnkgc3RhdGVzLgoKYGBge3IsIGV2YWwgPSBGQUxTRX0KdXJsIDwtIHBhc3RlMCgiaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3cvaW5kZXgucGhwP3RpdGxlPSIsCiAgICAgICAgICAgICAgIkd1bl92aW9sZW5jZV9pbl90aGVfVW5pdGVkX1N0YXRlc19ieV9zdGF0ZSYiLAogICAgICAgICAgICAgICJkaXJlY3Rpb249cHJldiZvbGRpZD04MTAxNjYxNjciKQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShydmVzdCkKaCA8LSByZWFkX2h0bWwodXJsKQp0YnMgPC0gaHRtbF90YWJsZShodG1sX25vZGVzKGgsICJ0YWJsZSIpKQptdXJkZXJzIDwtIHRic1tbMV1dCm5hbWVzKG11cmRlcnMpIDwtIGMoInN0YXRlIiwgInBvcCIsICJtdXJkZXJzIiwgInJhdGUiKQptdXJkZXJzIDwtIG11dGF0ZShtdXJkZXJzLAogICAgICAgICAgICAgICAgICBhY3Jvc3MoMiA6IDMsIGZ1bmN0aW9uKHgpIGFzLm51bWVyaWMoZ3N1YigiLCIsICIiLCB4KSkpKQpwIDwtIGdncGxvdChtdXJkZXJzLCBhZXMoeCA9IHBvcCwgeSA9IG11cmRlcnMpKQpwICsgZ2VvbV9wb2ludCgpCmxpYnJhcnkocGxvdGx5KQpnZ3Bsb3RseShwICsgZ2VvbV9wb2ludChhZXModGV4dCA9IHN0YXRlKSkpCmBgYAoKCiMjIyBFeGFtcGxlOiBOYXRpb25hbCBXZWF0aGVyIFNlcnZpY2UgRGF0YSBmb3IgSW93YSBDaXR5CgpDdXJyZW50IHdlYXRoZXIgZGF0YSBpcyBhdmFpbGFibGUgaW4gSlNPTiBmb3JtYXQgZnJvbQoKPGh0dHBzOi8vZm9yZWNhc3Qud2VhdGhlci5nb3YvTWFwQ2xpY2sucGhwP2xhdD00MS43Jmxvbj0tOTEuNSZGY3N0VHlwZT1qc29uPgoKR2V0dGluZyBjdXJyZW50IHRlbXBlcmF0dXJlOgoKYGBge3IsIGV2YWwgPSBGQUxTRX0KaWN1cmwgPC0KICAgICJodHRwOi8vZm9yZWNhc3Qud2VhdGhlci5nb3YvTWFwQ2xpY2sucGhwP2xhdD00MS43Jmxvbj0tOTEuNSZGY3N0VHlwZT1qc29uIgppY2pzb24gPC0ganNvbmxpdGU6OmZyb21KU09OKGljdXJsKQppY2pzb24kY3VycmVudG9ic2VydmF0aW9uJFRlbXAKYGBgCgoKIyMjIEV4YW1wbGU6IExvY2FsIEFyZWEgVW5lbXBsb3ltZW50IFN0YXRpc3RpY3MKClRoZSBCdXJlYXUgb2YgTGFib3IgU3RhdGlzdGljcyBwcm92aWRlcyBbZGF0YSBvbgp1bmVtcGxveW1lbnRdKGh0dHBzOi8vd3d3LmJscy5nb3YvbGF1LykgYnkgY291bnR5IGZvciB0aGUgbW9zdCByZWNlbnQKMTQgbW9udGhzIGF0CgpQcmV2aW91c2x5IHRoZXNlIGRhdGEgd2VyZSBtYWRlIGF2YWlsYWJsZSBhcyB0ZXh0IGZpbGVzIHRoYXQgY2FuIGJlCnJlYWQgdXNpbmcgYSBgcmVhZC50YWJsZWA7IGRhdGEgZnJvbSAyMDIzIGlzIGF2YWlsYWJsZSBsb2NhbGx5IGF0Cgo8aHR0cHM6Ly9ob21lcGFnZS5kaXZtcy51aW93YS5lZHUvfmx1a2UvZGF0YS9sYXVzL2xhdWNudHljdXIxNC0yMDIzLnR4dD4KCkN1cnJlbnQgZGF0YSBpcyBhdmFpbGFibGUgYXQKCjxodHRwczovL3d3dy5ibHMuZ292L3dlYi9tZXRyby9sYXVjbnR5Y3VyMTQuemlwPgoKVGhpcyBjb250YWlucyBhbmQgRXhjZWwgc3ByZWFkc2hlZXQuCgoKIyMjIEV4YW1wbGU6IFRlc3QgU2NvcmVzIGluIGFuIEV4Y2VsIFNwcmVhZHNoZWV0CgpBIHNpbXBsZSBFeGNlbCBmaWxlIGlzIGF2YWlsYWJsZSBpbiB0aGUgYGRzbGFic2AgcGFja2FnZSAoW0dpdEh1Ygpzb3VyY2VdKGh0dHBzOi8vZ2l0aHViLmNvbS9yYWZhbGFiL2RzbGFicy9ibG9iL21hc3Rlci9pbnN0L2V4dGRhdGEvMjAxMF9iaWdmaXZlX3JlZ2VudHMueGxzP3Jhdz10cnVlKSk6CgpgYGB7ciwgZXZhbCA9IEZBTFNFfQpzY29yZV9maWxlIDwtCiAgICBzeXN0ZW0uZmlsZSgiZXh0ZGF0YSIsICIyMDEwX2JpZ2ZpdmVfcmVnZW50cy54bHMiLCBwYWNrYWdlID0gImRzbGFicyIpCnJlYWR4bDo6cmVhZF94bHMoc2NvcmVfZmlsZSkKYGBgCgpbTW9yZSBjb21wbGljYXRlZCBmaWxlc10oaHR0cHM6Ly9zdGF0LnVpb3dhLmVkdS9+bHVrZS9kYXRhL0Fycml2YWxzLTIwMTctMDEtMDYueGxzKSB3aWxsIG5lZWQgbW9yZSBwcm9jZXNzaW5nLgoKCiMjIFJlYWRpbmcKCk1vcmUgaW5mb3JtYXRpb24gb24gZGF0YSBpbXBvcnQgaXMgcHJvdmlkZWQgaW4gdGhlIGNoYXB0ZXIgW19EYXRhCkltcG9ydF9dKGh0dHBzOi8vcjRkcy5oYWRsZXkubnovZGF0YS1pbXBvcnQuaHRtbCkgb2YgW19SIGZvciBEYXRhClNjaWVuY2VfXShodHRwczovL3I0ZHMuaGFkbGV5Lm56KS4KCkFub3RoZXIgcmVmZXJlbmNlIGlzIHRoZSBjaGFwdGVyIFtfSW1wb3J0aW5nCkRhdGFfXShodHRwczovL3JhZmFsYWIuZGZjaS5oYXJ2YXJkLmVkdS9kc2Jvb2stcGFydC0xL1IvaW1wb3J0aW5nLWRhdGEuaHRtbCkgaW4KW19JbnRyb2R1Y3Rpb24gdG8gRGF0YSBTY2llbmNlOiBEYXRhIEFuYWx5c2lzIGFuZCBQcmVkaWN0aW9uCkFsZ29yaXRobXMgd2l0aCBSX10oaHR0cHM6Ly9yYWZhbGFiLmRmY2kuaGFydmFyZC5lZHUvZHNib29rLXBhcnQtMS8pLgoKCiMjIEV4ZXJjaXNlcwoKMS4gUmVhZCBpbiB0aGUgUGxheWZhaXIgZGF0YSB1c2luZyB0aGUgYHJlYWQudGFibGVgIGZ1bmN0aW9uIGFuZCB0aWR5CiAgIHRoZSByZXN1bHQgdXNpbmcgdGhlIGByb3duYW1lc190b19jb2x1bW5gIGZ1bmN0aW9uIGZyb20gdGhlCiAgIGB0aWJibGVgIHBhY2thZ2UuCgo8IS0tClBsYXlmYWlyIDwtIHJlYWQudGFibGUoImh0dHA6Ly93d3cuc3RhdC51aW93YS5lZHUvfmx1a2UvZGF0YS9QbGF5ZmFpciIpCnJvd25hbWVzX3RvX2NvbHVtbihQbGF5ZmFpciwgImNpdHkiKQotLT4KCjIuIFRoZSB2YXJpYWJsZXMgYHNpdGVgLCBgdmFyaWV0eWAsIGFuZCBgeWVhcmAgaW4gdGhlIGBiYXJsZXlgIGRhdGEKICAgc2V0IGFyZSBfZmFjdG9yc18uICBIb3cgbWFueSBfbGV2ZWxzXyBkbyBlYWNoIG9mIHRoZXNlIHZhcmlhYmxlcwogICBoYXZlPyBbWW91IGNhbiB1c2UgdGhlIGZ1bmN0aW9ucyBgbGV2ZWxzYCBhbmQgYGxlbmd0aGAuXQo=