1.Quantiles in R
Quantiles are points that split a dataset into groups of equal size.
For example, let’s say you just took a test and wanted to know whether
you’re in the top 10% of the class. One way to determine this would be
to split the data into ten groups with an equal number of datapoints in
each group and see which group you fall into.
knitr::include_graphics("C:/Users/kuoan/Desktop/R Code/Quantiles1.png")

There are nine values that split the dataset into ten groups of equal
size — each group has 3 different test scores in it.
Those nine values that split the data are quantiles! Specifically,
they are the 10-quantiles, or deciles.
You can find any number of quantiles. For example, if you split the
dataset into 100 groups of equal size, the 99 values that split the data
are the 100-quantiles, or percentiles.
The quartiles are some of the most commonly used quantiles. The
quartiles split the data into four groups of equal size.
In this lesson, we’ll show you how to calculate quantiles using R and
discuss some of the most commonly used quantiles.
Instructions
We’ve imported a dataset of song lengths (measured in seconds). We’ve
drawn a few histograms showing different quantiles.
What do you think a histogram that shows the 100-quantiles would look
like?
# load libraries
library(ggplot2)
# load song data
load("songs.Rda")
錯誤發生在 readChar(con, 5L, useBytes = TRUE): 無法開啟連接
knitr::include_graphics("C:/Users/kuoan/Desktop/R Code/Quantiles2.png")

knitr::include_graphics("C:/Users/kuoan/Desktop/R Code/Quantiles3.png")

knitr::include_graphics("C:/Users/kuoan/Desktop/R Code/Quantiles4.png")

2.Quantiles in R
Base R has a function named quantile() that will quickly calculate
the quantiles of a dataset for you.
quantile() takes two parameters. The first is the dataset that you
are using. The second parameter is a single number or a vector of
numbers between 0 and 1. These numbers represent the places in the data
where you want to split.
For example, if you only wanted the value that split the first 10% of
the data apart from the remaining 90%, you could use this code:
dataset <- c(5, 10, -20, 42, -9, 10)
ten_percent <- quantile(dataset, 0.10)
ten_percent
10%
-14.5
ten_percent now holds the value -14.5. This result technically isn’t
a quantile, because it isn’t splitting the dataset into groups of equal
sizes — this value splits the data into one group with 10% of the data
and another with 90%.
However, it would still be useful if you were curious about whether a
data point was in the bottom 10% of the dataset.
Instructions
[1] “The value that splits 23% of the data is 171.7812924”
3.Many Quantiles
In the last exercise, we found a single “quantile” — we split the
first 23% of the data away from the remaining 77%.
However, quantiles are usually a set of values that split the data
into groups of equal size. For example, you wanted to get the
5-quantiles, or the four values that split the data into five groups of
equal size, you could use this code:
dataset <- c(5, 10, -20, 42, -9, 10)
ten_percent <- quantile(dataset, c(0.2, 0.4, 0.6, 0.8))
ten_percent
20% 40% 60% 80%
-9 5 10 10
Note that we had to do a little math in our head to make sure that
the values c(0.2, 0.4, 0.6, 0.8) split the data into groups of equal
size. Each group has 20% of the data.
knitr::include_graphics("C:/Users/kuoan/Desktop/R Code/Quantile5.png")

If we used the values c(0.2, 0.4, 0.7, 0.8), the function would
return the four values at those split points. However, those values
wouldn’t split the data into five equally sized groups. One group would
only have 10% of the data and another group would have 30% of the
data!
knitr::include_graphics("C:/Users/kuoan/Desktop/R Code/Quantiles6.png")

Instuctions
1.Create a variable named quartiles that contains the quartiles of
the songs dataset.
The quartiles of a dataset split the data into four groups of equal
size. Each group should have 25% of the data, so you’ll want to use
c(0.25, 0.5, 0.75) as the second parameter to the quantile()
function.
25% 50% 75%
175.9342 222.8240 275.4738
2.Create a variable named deciles. deciles should store the values
that split the dataset into ten groups of equal size. Each group should
have 10% of the data.
The first value should be at 10% of the data. The next value should
be at 20% of the data. The final value should be at 90% of the data.
# define deciles here:
deciles <- quantile(songs, c(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9))
deciles
10% 20% 30% 40% 50% 60% 70% 80%
135.1519 165.3755 185.9914 204.8152 222.8240 240.2216 262.4779
290.9514
90%
348.4939
3.Look at the printout of the deciles. If you had a song that was 170
seconds long, what tenth of the dataset would it fall in?
Create a variable named tenth and set it equal to the 1 if you think
the 170 second song would fall in the first tenth of the data. Set it
equal to 2 if you think the song would fall in the second tenth of the
data. If you think the song would fall in the final tenth of the data,
set tenth equal to 10.
# ignore the code below here:
tryCatch(print(paste(c("The quartiles are",quartiles,collapse=" "))), error=function(e) {print("You haven't defined quartiles.")})
tryCatch(print(paste(c("The deciles are",deciles,collapse=" "))), error=function(e) {print("You haven't defined deciles.")})
[1] “The quartiles are” “175.93424” “222.82404”
[4] “275.47383” ” ”
[1] “The deciles are” “135.151876” “165.375546” “185.99138”
[5] “204.815222” “222.82404” “240.22159” “262.47791”
4.Common Quantiles
One of the most common quantiles is the 2-quantile. This value splits
the data into two groups of equal size. Half the data will be above this
value, and half the data will be below it. This is also known as the
median!
knitr::include_graphics("C:/Users/kuoan/Desktop/R Code/Quantiles7.png")

The 4-quantiles, or the quartiles, split the data into four groups of
equal size. We found the quartiles in the previous exercise.
knitr::include_graphics("C:/Users/kuoan/Desktop/R Code/Quantiles8.png")

Finally, the percentiles, or the values that split the data into 100
groups, are commonly used to compare new data points to the dataset. You
might hear statements like “You are above the 80th percentile in
height”. This means that your height is above whatever value splits the
first 80% of the data from the remaining 20%.
Instructions
1.We won’t make you calculate all 99 percentiles, but let’s take a
look at one. Find the value that separates the first 32% of the data
from the rest.
Store that value in a variable named percentile.
# define percentile and answer here:
percentile <- quantile(songs, 0.32)
錯誤: 找不到物件 'songs'
32%
189.9359
2.Look at the printout. If you had a song that was exactly three
minutes long, is that song above or below the 32nd percentile?
Create a variable named answer and set it equal to either “above” or
“below”. Don’t forget to include the quotes!
[1] “Your percentile is 189.93587”
5.Quantiles Review
Nice work! Here are some of the major takeaways about quantiles:
1.Quantiles are values that split a dataset into groups of equal
size.
2.If you have n quantiles, the dataset will be split into n+1 groups
of equal size.
3.The median is a quantile. It is the only 2-quantile. Half the data
falls below the median and half falls above the median.
4.Quartiles and percentiles are other common quantiles. Quartiles
split the data into 4 groups while percentiles split the data into 100
groups.
Instructions
To the right, we’ve shown three different histograms along with the
deciles. Each histogram shows the SAT scores of the students that a fake
university has accepted.
If you had an SAT score of 1350, which tenth of the data would you be
in for each school? Which schools should you apply to? Would any of the
schools be unrealistic options?
knitr::include_graphics("C:/Users/kuoan/Desktop/R Code/Quantiles9.png")

knitr::include_graphics("C:/Users/kuoan/Desktop/R Code/Quantiles10.png")

knitr::include_graphics("C:/Users/kuoan/Desktop/R Code/Quantiles11.png")

LS0tDQp0aXRsZTogIlF1YW50aWxlcyINCmF1dGhvcjogIkFubmFiZWwgS3VvIg0KZGF0ZTogImByIGZvcm1hdChTeXMudGltZSgpLCAnJVktJW0tJWQgJUg6JU0nKWAiDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQojIDEuUXVhbnRpbGVzIGluIFINCg0KUXVhbnRpbGVzIGFyZSBwb2ludHMgdGhhdCBzcGxpdCBhIGRhdGFzZXQgaW50byBncm91cHMgb2YgZXF1YWwgc2l6ZS4gRm9yIGV4YW1wbGUsIGxldOKAmXMgc2F5IHlvdSBqdXN0IHRvb2sgYSB0ZXN0IGFuZCB3YW50ZWQgdG8ga25vdyB3aGV0aGVyIHlvdeKAmXJlIGluIHRoZSB0b3AgMTAlIG9mIHRoZSBjbGFzcy4gT25lIHdheSB0byBkZXRlcm1pbmUgdGhpcyB3b3VsZCBiZSB0byBzcGxpdCB0aGUgZGF0YSBpbnRvIHRlbiBncm91cHMgd2l0aCBhbiBlcXVhbCBudW1iZXIgb2YgZGF0YXBvaW50cyBpbiBlYWNoIGdyb3VwIGFuZCBzZWUgd2hpY2ggZ3JvdXAgeW91IGZhbGwgaW50by4NCg0KYGBge3IgUXVhbnRpbGVzMSwgb3V0LndpZHRoPSI2MCUifQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoIkM6L1VzZXJzL2t1b2FuL0Rlc2t0b3AvUiBDb2RlL1F1YW50aWxlczEucG5nIikNCmBgYA0KDQpUaGVyZSBhcmUgbmluZSB2YWx1ZXMgdGhhdCBzcGxpdCB0aGUgZGF0YXNldCBpbnRvIHRlbiBncm91cHMgb2YgZXF1YWwgc2l6ZSDigJQgZWFjaCBncm91cCBoYXMgMyBkaWZmZXJlbnQgdGVzdCBzY29yZXMgaW4gaXQuDQoNClRob3NlIG5pbmUgdmFsdWVzIHRoYXQgc3BsaXQgdGhlIGRhdGEgYXJlIHF1YW50aWxlcyEgU3BlY2lmaWNhbGx5LCB0aGV5IGFyZSB0aGUgMTAtcXVhbnRpbGVzLCBvciBkZWNpbGVzLg0KDQpZb3UgY2FuIGZpbmQgYW55IG51bWJlciBvZiBxdWFudGlsZXMuIEZvciBleGFtcGxlLCBpZiB5b3Ugc3BsaXQgdGhlIGRhdGFzZXQgaW50byAxMDAgZ3JvdXBzIG9mIGVxdWFsIHNpemUsIHRoZSA5OSB2YWx1ZXMgdGhhdCBzcGxpdCB0aGUgZGF0YSBhcmUgdGhlIDEwMC1xdWFudGlsZXMsIG9yIHBlcmNlbnRpbGVzLg0KDQpUaGUgcXVhcnRpbGVzIGFyZSBzb21lIG9mIHRoZSBtb3N0IGNvbW1vbmx5IHVzZWQgcXVhbnRpbGVzLiBUaGUgcXVhcnRpbGVzIHNwbGl0IHRoZSBkYXRhIGludG8gZm91ciBncm91cHMgb2YgZXF1YWwgc2l6ZS4NCg0KSW4gdGhpcyBsZXNzb24sIHdl4oCZbGwgc2hvdyB5b3UgaG93IHRvIGNhbGN1bGF0ZSBxdWFudGlsZXMgdXNpbmcgUiBhbmQgZGlzY3VzcyBzb21lIG9mIHRoZSBtb3N0IGNvbW1vbmx5IHVzZWQgcXVhbnRpbGVzLg0KDQojIyBJbnN0cnVjdGlvbnMNCg0KV2XigJl2ZSBpbXBvcnRlZCBhIGRhdGFzZXQgb2Ygc29uZyBsZW5ndGhzIChtZWFzdXJlZCBpbiBzZWNvbmRzKS4gV2XigJl2ZSBkcmF3biBhIGZldyBoaXN0b2dyYW1zIHNob3dpbmcgZGlmZmVyZW50IHF1YW50aWxlcy4NCg0KV2hhdCBkbyB5b3UgdGhpbmsgYSBoaXN0b2dyYW0gdGhhdCBzaG93cyB0aGUgMTAwLXF1YW50aWxlcyB3b3VsZCBsb29rIGxpa2U/DQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQojIGxvYWQgbGlicmFyaWVzDQpsaWJyYXJ5KGdncGxvdDIpDQpgYGANCg0KYGBge3J9DQojIGxvYWQgc29uZyBkYXRhDQpsb2FkKCJzb25ncy5SZGEiKQ0KYGBgDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIGVjaG89RkFMU0V9DQojIDQgcXVhbnRpbGVzDQpoaXN0IDwtIHFwbG90KHNvbmdzLA0KICAgICAgICAgICAgICBnZW9tPSJoaXN0b2dyYW0iLA0KICAgICAgICAgICAgICBtYWluID0gJzQtUXVhbnRpbGVzJywNCiAgICAgICAgICAgICAgeGxhYiA9ICdTb25nIExlbmd0aCAoU2Vjb25kcyknLA0KICAgICAgICAgICAgICB5bGFiID0gJ0NvdW50JywNCiAgICAgICAgICAgICAgZmlsbD1JKCJibHVlIiksDQogICAgICAgICAgICAgIGNvbD1JKCJyZWQiKSwNCiAgICAgICAgICAgICAgYWxwaGE9SSguMikpICsNCiAgICAgICAgZ2VvbV92bGluZShhZXMoeGludGVyY2VwdD1xdWFudGlsZShzb25ncywwLjI1KSwNCiAgICAgICAgICAgICAgICAgICAgICAgY29sb3I9SSgiYmx1ZSIpKSwNCiAgICAgICAgICAgICAgICAgICBsaW5ldHlwZT0ic29saWQiLA0KICAgICAgICAgICAgICAgICAgIHNpemU9MSwNCiAgICAgICAgICAgICAgICAgICBzaG93LmxlZ2VuZD1UKSArDQoJCQkJZ2VvbV92bGluZShhZXMoeGludGVyY2VwdD1xdWFudGlsZShzb25ncywwLjUpLA0KICAgICAgICAgICAgICAgICAgICAgICBjb2xvcj1JKCJibHVlIikpLA0KICAgICAgICAgICAgICAgICAgIGxpbmV0eXBlPSJzb2xpZCIsDQogICAgICAgICAgICAgICAgICAgc2l6ZT0xLA0KICAgICAgICAgICAgICAgICAgIHNob3cubGVnZW5kPVQpICsNCiAgCQkJZ2VvbV92bGluZShhZXMoeGludGVyY2VwdD1xdWFudGlsZShzb25ncywwLjc1KSwNCiAgICAgICAgICAgICAgICAgICAgICAgY29sb3I9SSgiYmx1ZSIpKSwNCiAgICAgICAgICAgICAgICAgICBsaW5ldHlwZT0ic29saWQiLA0KICAgICAgICAgICAgICAgICAgIHNpemU9MSwNCiAgICAgICAgICAgICAgICAgICBzaG93LmxlZ2VuZD1UKQ0KDQpoaXN0DQpgYGANCg0KYGBge3IgUXVhbnRpbGVzMiwgb3V0LndpZHRoPSI2MCUifQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoIkM6L1VzZXJzL2t1b2FuL0Rlc2t0b3AvUiBDb2RlL1F1YW50aWxlczIucG5nIikNCmBgYA0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFLCBlY2hvPUZBTFNFfQ0KIyA1IHF1YW50aWxlcw0KaGlzdCA8LSBxcGxvdChzb25ncywNCiAgICAgICAgICAgICAgZ2VvbT0iaGlzdG9ncmFtIiwNCiAgICAgICAgICAgICAgbWFpbiA9ICc1LVF1YW50aWxlcycsDQogICAgICAgICAgICAgIHhsYWIgPSAnU29uZyBMZW5ndGggKFNlY29uZHMpJywNCiAgICAgICAgICAgICAgeWxhYiA9ICdDb3VudCcsDQogICAgICAgICAgICAgIGZpbGw9SSgiYmx1ZSIpLA0KICAgICAgICAgICAgICBjb2w9SSgicmVkIiksDQogICAgICAgICAgICAgIGFscGhhPUkoLjIpKSArDQogICAgICAgIGdlb21fdmxpbmUoYWVzKHhpbnRlcmNlcHQ9cXVhbnRpbGUoc29uZ3MsMC4yKSwNCiAgICAgICAgICAgICAgICAgICAgICAgY29sb3I9SSgiYmx1ZSIpKSwNCiAgICAgICAgICAgICAgICAgICBsaW5ldHlwZT0ic29saWQiLA0KICAgICAgICAgICAgICAgICAgIHNpemU9MSwNCiAgICAgICAgICAgICAgICAgICBzaG93LmxlZ2VuZD1UKSArDQoJCQkJZ2VvbV92bGluZShhZXMoeGludGVyY2VwdD1xdWFudGlsZShzb25ncywwLjQpLA0KICAgICAgICAgICAgICAgICAgICAgICBjb2xvcj1JKCJibHVlIikpLA0KICAgICAgICAgICAgICAgICAgIGxpbmV0eXBlPSJzb2xpZCIsDQogICAgICAgICAgICAgICAgICAgc2l6ZT0xLA0KICAgICAgICAgICAgICAgICAgIHNob3cubGVnZW5kPVQpICsNCiAgCQkJZ2VvbV92bGluZShhZXMoeGludGVyY2VwdD1xdWFudGlsZShzb25ncywwLjYpLA0KICAgICAgICAgICAgICAgICAgICAgICBjb2xvcj1JKCJibHVlIikpLA0KICAgICAgICAgICAgICAgICAgIGxpbmV0eXBlPSJzb2xpZCIsDQogICAgICAgICAgICAgICAgICAgc2l6ZT0xLA0KICAgICAgICAgICAgICAgICAgIHNob3cubGVnZW5kPVQpICsNCiAgCQkJZ2VvbV92bGluZShhZXMoeGludGVyY2VwdD1xdWFudGlsZShzb25ncywwLjgpLA0KICAgICAgICAgICAgICAgICAgICAgICBjb2xvcj1JKCJibHVlIikpLA0KICAgICAgICAgICAgICAgICAgIGxpbmV0eXBlPSJzb2xpZCIsDQogICAgICAgICAgICAgICAgICAgc2l6ZT0xLA0KICAgICAgICAgICAgICAgICAgIHNob3cubGVnZW5kPVQpDQoNCmhpc3QNCmBgYA0KDQpgYGB7ciBRdWFudGlsZXMzLCBvdXQud2lkdGg9IjYwJSJ9DQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygiQzovVXNlcnMva3VvYW4vRGVza3RvcC9SIENvZGUvUXVhbnRpbGVzMy5wbmciKQ0KYGBgDQoNCmBgYHtyIG1lc3NhZ2U9RkFMU0UsIGVjaG89RkFMU0V9DQojIDEwIHF1YW50aWxlcw0KaGlzdCA8LSBxcGxvdChzb25ncywNCiAgICAgICAgICAgICAgZ2VvbT0iaGlzdG9ncmFtIiwNCiAgICAgICAgICAgICAgbWFpbiA9ICcxMC1RdWFudGlsZXMnLA0KICAgICAgICAgICAgICB4bGFiID0gJ1NvbmcgTGVuZ3RoIChTZWNvbmRzKScsDQogICAgICAgICAgICAgIHlsYWIgPSAnQ291bnQnLA0KICAgICAgICAgICAgICBmaWxsPUkoImJsdWUiKSwNCiAgICAgICAgICAgICAgY29sPUkoInJlZCIpLA0KICAgICAgICAgICAgICBhbHBoYT1JKC4yKSkgKw0KICAgICAgICBnZW9tX3ZsaW5lKGFlcyh4aW50ZXJjZXB0PXF1YW50aWxlKHNvbmdzLDAuMSksDQogICAgICAgICAgICAgICAgICAgICAgIGNvbG9yPUkoImJsdWUiKSksDQogICAgICAgICAgICAgICAgICAgbGluZXR5cGU9InNvbGlkIiwNCiAgICAgICAgICAgICAgICAgICBzaXplPTEsDQogICAgICAgICAgICAgICAgICAgc2hvdy5sZWdlbmQ9VCkgKw0KCQkJCWdlb21fdmxpbmUoYWVzKHhpbnRlcmNlcHQ9cXVhbnRpbGUoc29uZ3MsMC4yKSwNCiAgICAgICAgICAgICAgICAgICAgICAgY29sb3I9SSgiYmx1ZSIpKSwNCiAgICAgICAgICAgICAgICAgICBsaW5ldHlwZT0ic29saWQiLA0KICAgICAgICAgICAgICAgICAgIHNpemU9MSwNCiAgICAgICAgICAgICAgICAgICBzaG93LmxlZ2VuZD1UKSArDQogIAkJCWdlb21fdmxpbmUoYWVzKHhpbnRlcmNlcHQ9cXVhbnRpbGUoc29uZ3MsMC4zKSwNCiAgICAgICAgICAgICAgICAgICAgICAgY29sb3I9SSgiYmx1ZSIpKSwNCiAgICAgICAgICAgICAgICAgICBsaW5ldHlwZT0ic29saWQiLA0KICAgICAgICAgICAgICAgICAgIHNpemU9MSwNCiAgICAgICAgICAgICAgICAgICBzaG93LmxlZ2VuZD1UKSArDQogIAkJCWdlb21fdmxpbmUoYWVzKHhpbnRlcmNlcHQ9cXVhbnRpbGUoc29uZ3MsMC40KSwNCiAgICAgICAgICAgICAgICAgICAgICAgY29sb3I9SSgiYmx1ZSIpKSwNCiAgICAgICAgICAgICAgICAgICBsaW5ldHlwZT0ic29saWQiLA0KICAgICAgICAgICAgICAgICAgIHNpemU9MSwNCiAgICAgICAgICAgICAgICAgICBzaG93LmxlZ2VuZD1UKSArDQogICAgICAgIGdlb21fdmxpbmUoYWVzKHhpbnRlcmNlcHQ9cXVhbnRpbGUoc29uZ3MsMC41KSwNCiAgICAgICAgICAgICAgICAgICAgICAgY29sb3I9SSgiYmx1ZSIpKSwNCiAgICAgICAgICAgICAgICAgICBsaW5ldHlwZT0ic29saWQiLA0KICAgICAgICAgICAgICAgICAgIHNpemU9MSwNCiAgICAgICAgICAgICAgICAgICBzaG93LmxlZ2VuZD1UKSArDQoJCQkJZ2VvbV92bGluZShhZXMoeGludGVyY2VwdD1xdWFudGlsZShzb25ncywwLjYpLA0KICAgICAgICAgICAgICAgICAgICAgICBjb2xvcj1JKCJibHVlIikpLA0KICAgICAgICAgICAgICAgICAgIGxpbmV0eXBlPSJzb2xpZCIsDQogICAgICAgICAgICAgICAgICAgc2l6ZT0xLA0KICAgICAgICAgICAgICAgICAgIHNob3cubGVnZW5kPVQpICsNCiAgCQkJZ2VvbV92bGluZShhZXMoeGludGVyY2VwdD1xdWFudGlsZShzb25ncywwLjcpLA0KICAgICAgICAgICAgICAgICAgICAgICBjb2xvcj1JKCJibHVlIikpLA0KICAgICAgICAgICAgICAgICAgIGxpbmV0eXBlPSJzb2xpZCIsDQogICAgICAgICAgICAgICAgICAgc2l6ZT0xLA0KICAgICAgICAgICAgICAgICAgIHNob3cubGVnZW5kPVQpICsNCiAgCQkJZ2VvbV92bGluZShhZXMoeGludGVyY2VwdD1xdWFudGlsZShzb25ncywwLjgpLA0KICAgICAgICAgICAgICAgICAgICAgICBjb2xvcj1JKCJibHVlIikpLA0KICAgICAgICAgICAgICAgICAgIGxpbmV0eXBlPSJzb2xpZCIsDQogICAgICAgICAgICAgICAgICAgc2l6ZT0xLA0KICAgICAgICAgICAgICAgICAgIHNob3cubGVnZW5kPVQpICsNCiAgCQkJZ2VvbV92bGluZShhZXMoeGludGVyY2VwdD1xdWFudGlsZShzb25ncywwLjkpLA0KICAgICAgICAgICAgICAgICAgICAgICBjb2xvcj1JKCJibHVlIikpLA0KICAgICAgICAgICAgICAgICAgIGxpbmV0eXBlPSJzb2xpZCIsDQogICAgICAgICAgICAgICAgICAgc2l6ZT0xLA0KICAgICAgICAgICAgICAgICAgIHNob3cubGVnZW5kPVQpDQoNCmhpc3QNCmBgYA0KDQpgYGB7ciBRdWFudGlsZXM0LCBvdXQud2lkdGg9IjYwJSJ9DQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygiQzovVXNlcnMva3VvYW4vRGVza3RvcC9SIENvZGUvUXVhbnRpbGVzNC5wbmciKQ0KYGBgDQoNCiMgMi5RdWFudGlsZXMgaW4gUg0KDQpCYXNlIFIgaGFzIGEgZnVuY3Rpb24gbmFtZWQgcXVhbnRpbGUoKSB0aGF0IHdpbGwgcXVpY2tseSBjYWxjdWxhdGUgdGhlIHF1YW50aWxlcyBvZiBhIGRhdGFzZXQgZm9yIHlvdS4NCg0KcXVhbnRpbGUoKSB0YWtlcyB0d28gcGFyYW1ldGVycy4gVGhlIGZpcnN0IGlzIHRoZSBkYXRhc2V0IHRoYXQgeW91IGFyZSB1c2luZy4gVGhlIHNlY29uZCBwYXJhbWV0ZXIgaXMgYSBzaW5nbGUgbnVtYmVyIG9yIGEgdmVjdG9yIG9mIG51bWJlcnMgYmV0d2VlbiAwIGFuZCAxLiBUaGVzZSBudW1iZXJzIHJlcHJlc2VudCB0aGUgcGxhY2VzIGluIHRoZSBkYXRhIHdoZXJlIHlvdSB3YW50IHRvIHNwbGl0Lg0KDQpGb3IgZXhhbXBsZSwgaWYgeW91IG9ubHkgd2FudGVkIHRoZSB2YWx1ZSB0aGF0IHNwbGl0IHRoZSBmaXJzdCAxMCUgb2YgdGhlIGRhdGEgYXBhcnQgZnJvbSB0aGUgcmVtYWluaW5nIDkwJSwgeW91IGNvdWxkIHVzZSB0aGlzIGNvZGU6DQoNCmBgYHtyfQ0KZGF0YXNldCA8LSBjKDUsIDEwLCAtMjAsIDQyLCAtOSwgMTApDQp0ZW5fcGVyY2VudCA8LSBxdWFudGlsZShkYXRhc2V0LCAwLjEwKQ0KdGVuX3BlcmNlbnQNCmBgYA0KDQp0ZW5fcGVyY2VudCBub3cgaG9sZHMgdGhlIHZhbHVlIC0xNC41LiBUaGlzIHJlc3VsdCB0ZWNobmljYWxseSBpc27igJl0IGEgcXVhbnRpbGUsIGJlY2F1c2UgaXQgaXNu4oCZdCBzcGxpdHRpbmcgdGhlIGRhdGFzZXQgaW50byBncm91cHMgb2YgZXF1YWwgc2l6ZXMg4oCUIHRoaXMgdmFsdWUgc3BsaXRzIHRoZSBkYXRhIGludG8gb25lIGdyb3VwIHdpdGggMTAlIG9mIHRoZSBkYXRhIGFuZCBhbm90aGVyIHdpdGggOTAlLg0KDQpIb3dldmVyLCBpdCB3b3VsZCBzdGlsbCBiZSB1c2VmdWwgaWYgeW91IHdlcmUgY3VyaW91cyBhYm91dCB3aGV0aGVyIGEgZGF0YSBwb2ludCB3YXMgaW4gdGhlIGJvdHRvbSAxMCUgb2YgdGhlIGRhdGFzZXQuDQoNCiMjIEluc3RydWN0aW9ucw0KDQpgYGB7cn0NCiMgZGVmaW5lIHR3ZW50eV90aGlyZF9wZXJjZW50aWxlIGhlcmU6DQp0d2VudHlfdGhpcmRfcGVyY2VudGlsZSA8LSBxdWFudGlsZShzb25ncywgMC4yMykNCmBgYA0KDQpgYGB7cn0NCiMgaWdub3JlIHRoZSBjb2RlIGJlbG93IGhlcmU6DQoNCnRyeUNhdGNoKHByaW50KHBhc3RlKCJUaGUgdmFsdWUgdGhhdCBzcGxpdHMgMjMlIG9mIHRoZSBkYXRhIGlzIix0d2VudHlfdGhpcmRfcGVyY2VudGlsZSkpLCBlcnJvcj1mdW5jdGlvbihlKSB7cHJpbnQoIllvdSBoYXZlbid0IGRlZmluZWQgdHdlbnR5X3RoaXJkX3BlcmNlbnRpbGUuIil9KQ0KYGBgDQoNClsxXSAiVGhlIHZhbHVlIHRoYXQgc3BsaXRzIDIzJSBvZiB0aGUgZGF0YSBpcyAxNzEuNzgxMjkyNCINCg0KIyAzLk1hbnkgUXVhbnRpbGVzDQoNCkluIHRoZSBsYXN0IGV4ZXJjaXNlLCB3ZSBmb3VuZCBhIHNpbmdsZSDigJxxdWFudGlsZeKAnSDigJQgd2Ugc3BsaXQgdGhlIGZpcnN0IDIzJSBvZiB0aGUgZGF0YSBhd2F5IGZyb20gdGhlIHJlbWFpbmluZyA3NyUuDQoNCkhvd2V2ZXIsIHF1YW50aWxlcyBhcmUgdXN1YWxseSBhIHNldCBvZiB2YWx1ZXMgdGhhdCBzcGxpdCB0aGUgZGF0YSBpbnRvIGdyb3VwcyBvZiBlcXVhbCBzaXplLiBGb3IgZXhhbXBsZSwgeW91IHdhbnRlZCB0byBnZXQgdGhlIDUtcXVhbnRpbGVzLCBvciB0aGUgZm91ciB2YWx1ZXMgdGhhdCBzcGxpdCB0aGUgZGF0YSBpbnRvIGZpdmUgZ3JvdXBzIG9mIGVxdWFsIHNpemUsIHlvdSBjb3VsZCB1c2UgdGhpcyBjb2RlOg0KDQpgYGB7cn0NCmRhdGFzZXQgPC0gYyg1LCAxMCwgLTIwLCA0MiwgLTksIDEwKQ0KdGVuX3BlcmNlbnQgPC0gcXVhbnRpbGUoZGF0YXNldCwgYygwLjIsIDAuNCwgMC42LCAwLjgpKQ0KdGVuX3BlcmNlbnQNCmBgYA0KTm90ZSB0aGF0IHdlIGhhZCB0byBkbyBhIGxpdHRsZSBtYXRoIGluIG91ciBoZWFkIHRvIG1ha2Ugc3VyZSB0aGF0IHRoZSB2YWx1ZXMgYygwLjIsIDAuNCwgMC42LCAwLjgpIHNwbGl0IHRoZSBkYXRhIGludG8gZ3JvdXBzIG9mIGVxdWFsIHNpemUuIEVhY2ggZ3JvdXAgaGFzIDIwJSBvZiB0aGUgZGF0YS4NCg0KYGBge3IgUXVhbnRpbGU1LCBvdXQud2lkdGg9IjYwJSJ9DQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygiQzovVXNlcnMva3VvYW4vRGVza3RvcC9SIENvZGUvUXVhbnRpbGU1LnBuZyIpDQpgYGANCg0KDQpJZiB3ZSB1c2VkIHRoZSB2YWx1ZXMgYygwLjIsIDAuNCwgMC43LCAwLjgpLCB0aGUgZnVuY3Rpb24gd291bGQgcmV0dXJuIHRoZSBmb3VyIHZhbHVlcyBhdCB0aG9zZSBzcGxpdCBwb2ludHMuIEhvd2V2ZXIsIHRob3NlIHZhbHVlcyB3b3VsZG7igJl0IHNwbGl0IHRoZSBkYXRhIGludG8gZml2ZSBlcXVhbGx5IHNpemVkIGdyb3Vwcy4gT25lIGdyb3VwIHdvdWxkIG9ubHkgaGF2ZSAxMCUgb2YgdGhlIGRhdGEgYW5kIGFub3RoZXIgZ3JvdXAgd291bGQgaGF2ZSAzMCUgb2YgdGhlIGRhdGEhDQoNCmBgYHtyIFF1YW50aWxlczYsIG91dC53aWR0aD0iNjAlIn0NCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCJDOi9Vc2Vycy9rdW9hbi9EZXNrdG9wL1IgQ29kZS9RdWFudGlsZXM2LnBuZyIpDQpgYGANCg0KIyMgSW5zdHVjdGlvbnMNCg0KMS5DcmVhdGUgYSB2YXJpYWJsZSBuYW1lZCBxdWFydGlsZXMgdGhhdCBjb250YWlucyB0aGUgcXVhcnRpbGVzIG9mIHRoZSBzb25ncyBkYXRhc2V0Lg0KDQpUaGUgcXVhcnRpbGVzIG9mIGEgZGF0YXNldCBzcGxpdCB0aGUgZGF0YSBpbnRvIGZvdXIgZ3JvdXBzIG9mIGVxdWFsIHNpemUuIEVhY2ggZ3JvdXAgc2hvdWxkIGhhdmUgMjUlIG9mIHRoZSBkYXRhLCBzbyB5b3XigJlsbCB3YW50IHRvIHVzZSBjKDAuMjUsIDAuNSwgMC43NSkgYXMgdGhlIHNlY29uZCBwYXJhbWV0ZXIgdG8gdGhlIHF1YW50aWxlKCkgZnVuY3Rpb24uDQoNCmBgYHtyfQ0KIyBkZWZpbmUgcXVhcnRpbGVzIGhlcmU6DQpxdWFydGlsZXMgPC0gcXVhbnRpbGUoc29uZ3MsIGMoMC4yNSwgMC41MCwgMC43NSkpDQpxdWFydGlsZXMNCmBgYA0KDQogICAgIDI1JSAgICAgIDUwJSAgICAgIDc1JSANCjE3NS45MzQyIDIyMi44MjQwIDI3NS40NzM4IA0KDQoyLkNyZWF0ZSBhIHZhcmlhYmxlIG5hbWVkIGRlY2lsZXMuIGRlY2lsZXMgc2hvdWxkIHN0b3JlIHRoZSB2YWx1ZXMgdGhhdCBzcGxpdCB0aGUgZGF0YXNldCBpbnRvIHRlbiBncm91cHMgb2YgZXF1YWwgc2l6ZS4gRWFjaCBncm91cCBzaG91bGQgaGF2ZSAxMCUgb2YgdGhlIGRhdGEuDQoNClRoZSBmaXJzdCB2YWx1ZSBzaG91bGQgYmUgYXQgMTAlIG9mIHRoZSBkYXRhLiBUaGUgbmV4dCB2YWx1ZSBzaG91bGQgYmUgYXQgMjAlIG9mIHRoZSBkYXRhLiBUaGUgZmluYWwgdmFsdWUgc2hvdWxkIGJlIGF0IDkwJSBvZiB0aGUgZGF0YS4NCg0KYGBge3J9DQojIGRlZmluZSBkZWNpbGVzIGhlcmU6DQpkZWNpbGVzIDwtIHF1YW50aWxlKHNvbmdzLCBjKDAuMSwgMC4yLCAwLjMsIDAuNCwgMC41LCAwLjYsIDAuNywgMC44LCAwLjkpKQ0KZGVjaWxlcw0KYGBgDQoNCiAgICAgMTAlICAgICAgMjAlICAgICAgMzAlICAgICAgNDAlICAgICAgNTAlICAgICAgNjAlICAgICAgNzAlICAgICAgODAlIA0KMTM1LjE1MTkgMTY1LjM3NTUgMTg1Ljk5MTQgMjA0LjgxNTIgMjIyLjgyNDAgMjQwLjIyMTYgMjYyLjQ3NzkgMjkwLjk1MTQgDQoNCiAgICAgOTAlIA0KMzQ4LjQ5MzkgDQoNCjMuTG9vayBhdCB0aGUgcHJpbnRvdXQgb2YgdGhlIGRlY2lsZXMuIElmIHlvdSBoYWQgYSBzb25nIHRoYXQgd2FzIDE3MCBzZWNvbmRzIGxvbmcsIHdoYXQgdGVudGggb2YgdGhlIGRhdGFzZXQgd291bGQgaXQgZmFsbCBpbj8NCg0KQ3JlYXRlIGEgdmFyaWFibGUgbmFtZWQgdGVudGggYW5kIHNldCBpdCBlcXVhbCB0byB0aGUgMSBpZiB5b3UgdGhpbmsgdGhlIDE3MCBzZWNvbmQgc29uZyB3b3VsZCBmYWxsIGluIHRoZSBmaXJzdCB0ZW50aCBvZiB0aGUgZGF0YS4gU2V0IGl0IGVxdWFsIHRvIDIgaWYgeW91IHRoaW5rIHRoZSBzb25nIHdvdWxkIGZhbGwgaW4gdGhlIHNlY29uZCB0ZW50aCBvZiB0aGUgZGF0YS4gSWYgeW91IHRoaW5rIHRoZSBzb25nIHdvdWxkIGZhbGwgaW4gdGhlIGZpbmFsIHRlbnRoIG9mIHRoZSBkYXRhLCBzZXQgdGVudGggZXF1YWwgdG8gMTAuDQoNCmBgYHtyfQ0KIyBkZWZpbmUgdGVudGggaGVyZToNCnRlbnRoIDwtIDMNCmBgYA0KDQpgYGB7cn0NCiMgaWdub3JlIHRoZSBjb2RlIGJlbG93IGhlcmU6DQoNCnRyeUNhdGNoKHByaW50KHBhc3RlKGMoIlRoZSBxdWFydGlsZXMgYXJlIixxdWFydGlsZXMsY29sbGFwc2U9IiAiKSkpLCBlcnJvcj1mdW5jdGlvbihlKSB7cHJpbnQoIllvdSBoYXZlbid0IGRlZmluZWQgcXVhcnRpbGVzLiIpfSkNCg0KdHJ5Q2F0Y2gocHJpbnQocGFzdGUoYygiVGhlIGRlY2lsZXMgYXJlIixkZWNpbGVzLGNvbGxhcHNlPSIgIikpKSwgZXJyb3I9ZnVuY3Rpb24oZSkge3ByaW50KCJZb3UgaGF2ZW4ndCBkZWZpbmVkIGRlY2lsZXMuIil9KQ0KYGBgDQoNClsxXSAiVGhlIHF1YXJ0aWxlcyBhcmUiICIxNzUuOTM0MjQiICAgICAgICAgIjIyMi44MjQwNCIgICAgICAgDQoNCls0XSAiMjc1LjQ3MzgzIiAgICAgICAgICIgIiAgICAgICAgICAgICAgICANCg0KDQpbMV0gIlRoZSBkZWNpbGVzIGFyZSIgIjEzNS4xNTE4NzYiICAgICAgIjE2NS4zNzU1NDYiICAgICAgIjE4NS45OTEzOCIgICAgIA0KDQpbNV0gIjIwNC44MTUyMjIiICAgICAgIjIyMi44MjQwNCIgICAgICAgIjI0MC4yMjE1OSIgICAgICAgIjI2Mi40Nzc5MSIgIA0KDQoNCiMgNC5Db21tb24gUXVhbnRpbGVzDQoNCk9uZSBvZiB0aGUgbW9zdCBjb21tb24gcXVhbnRpbGVzIGlzIHRoZSAyLXF1YW50aWxlLiBUaGlzIHZhbHVlIHNwbGl0cyB0aGUgZGF0YSBpbnRvIHR3byBncm91cHMgb2YgZXF1YWwgc2l6ZS4gSGFsZiB0aGUgZGF0YSB3aWxsIGJlIGFib3ZlIHRoaXMgdmFsdWUsIGFuZCBoYWxmIHRoZSBkYXRhIHdpbGwgYmUgYmVsb3cgaXQuIFRoaXMgaXMgYWxzbyBrbm93biBhcyB0aGUgbWVkaWFuIQ0KDQoNCmBgYHtyIFF1YW50aWxlczcsIG91dC53aWR0aD0iNjAlIn0NCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCJDOi9Vc2Vycy9rdW9hbi9EZXNrdG9wL1IgQ29kZS9RdWFudGlsZXM3LnBuZyIpDQpgYGAgICAgICAgICAgICANCg0KVGhlIDQtcXVhbnRpbGVzLCBvciB0aGUgcXVhcnRpbGVzLCBzcGxpdCB0aGUgZGF0YSBpbnRvIGZvdXIgZ3JvdXBzIG9mIGVxdWFsIHNpemUuIFdlIGZvdW5kIHRoZSBxdWFydGlsZXMgaW4gdGhlIHByZXZpb3VzIGV4ZXJjaXNlLg0KDQpgYGB7ciBRdWFudGlsZXM4LCBvdXQud2lkdGg9IjYwJSJ9DQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygiQzovVXNlcnMva3VvYW4vRGVza3RvcC9SIENvZGUvUXVhbnRpbGVzOC5wbmciKQ0KYGBgIA0KDQpGaW5hbGx5LCB0aGUgcGVyY2VudGlsZXMsIG9yIHRoZSB2YWx1ZXMgdGhhdCBzcGxpdCB0aGUgZGF0YSBpbnRvIDEwMCBncm91cHMsIGFyZSBjb21tb25seSB1c2VkIHRvIGNvbXBhcmUgbmV3IGRhdGEgcG9pbnRzIHRvIHRoZSBkYXRhc2V0LiBZb3UgbWlnaHQgaGVhciBzdGF0ZW1lbnRzIGxpa2Ug4oCcWW91IGFyZSBhYm92ZSB0aGUgODB0aCBwZXJjZW50aWxlIGluIGhlaWdodOKAnS4gVGhpcyBtZWFucyB0aGF0IHlvdXIgaGVpZ2h0IGlzIGFib3ZlIHdoYXRldmVyIHZhbHVlIHNwbGl0cyB0aGUgZmlyc3QgODAlIG9mIHRoZSBkYXRhIGZyb20gdGhlIHJlbWFpbmluZyAyMCUuDQoNCiMjIEluc3RydWN0aW9ucw0KDQoxLldlIHdvbuKAmXQgbWFrZSB5b3UgY2FsY3VsYXRlIGFsbCA5OSBwZXJjZW50aWxlcywgYnV0IGxldOKAmXMgdGFrZSBhIGxvb2sgYXQgb25lLiBGaW5kIHRoZSB2YWx1ZSB0aGF0IHNlcGFyYXRlcyB0aGUgZmlyc3QgMzIlIG9mIHRoZSBkYXRhIGZyb20gdGhlIHJlc3QuDQoNClN0b3JlIHRoYXQgdmFsdWUgaW4gYSB2YXJpYWJsZSBuYW1lZCBwZXJjZW50aWxlLg0KDQpgYGB7cn0NCiMgZGVmaW5lIHBlcmNlbnRpbGUgYW5kIGFuc3dlciBoZXJlOg0KcGVyY2VudGlsZSA8LSBxdWFudGlsZShzb25ncywgMC4zMikNCnBlcmNlbnRpbGUNCmBgYA0KDQogICAgIDMyJSANCjE4OS45MzU5IA0KDQoyLkxvb2sgYXQgdGhlIHByaW50b3V0LiBJZiB5b3UgaGFkIGEgc29uZyB0aGF0IHdhcyBleGFjdGx5IHRocmVlIG1pbnV0ZXMgbG9uZywgaXMgdGhhdCBzb25nIGFib3ZlIG9yIGJlbG93IHRoZSAzMm5kIHBlcmNlbnRpbGU/DQoNCkNyZWF0ZSBhIHZhcmlhYmxlIG5hbWVkIGFuc3dlciBhbmQgc2V0IGl0IGVxdWFsIHRvIGVpdGhlciAiYWJvdmUiIG9yICJiZWxvdyIuIERvbuKAmXQgZm9yZ2V0IHRvIGluY2x1ZGUgdGhlIHF1b3RlcyENCg0KYGBge3J9DQphbnN3ZXIgPC0gImJlbG93Ig0KYGBgDQoNCmBgYHtyfQ0KIyBpZ25vcmUgdGhlIGNvZGUgYmVsb3cgaGVyZToNCg0KdHJ5Q2F0Y2gocHJpbnQocGFzdGUoIllvdXIgcGVyY2VudGlsZSBpcyIscGVyY2VudGlsZSkpLCBlcnJvcj1mdW5jdGlvbihlKSB7cHJpbnQoIllvdSBoYXZlbid0IGRlZmluZWQgcGVyY2VudGlsZSIpfSkNCmBgYA0KDQpbMV0gIllvdXIgcGVyY2VudGlsZSBpcyAxODkuOTM1ODciDQoNCiMgNS5RdWFudGlsZXMgUmV2aWV3DQoNCk5pY2Ugd29yayEgSGVyZSBhcmUgc29tZSBvZiB0aGUgbWFqb3IgdGFrZWF3YXlzIGFib3V0IHF1YW50aWxlczoNCg0KMS5RdWFudGlsZXMgYXJlIHZhbHVlcyB0aGF0IHNwbGl0IGEgZGF0YXNldCBpbnRvIGdyb3VwcyBvZiBlcXVhbCBzaXplLg0KDQoyLklmIHlvdSBoYXZlIG4gcXVhbnRpbGVzLCB0aGUgZGF0YXNldCB3aWxsIGJlIHNwbGl0IGludG8gbisxIGdyb3VwcyBvZiBlcXVhbCBzaXplLg0KDQozLlRoZSBtZWRpYW4gaXMgYSBxdWFudGlsZS4gSXQgaXMgdGhlIG9ubHkgMi1xdWFudGlsZS4gSGFsZiB0aGUgZGF0YSBmYWxscyBiZWxvdyB0aGUgbWVkaWFuIGFuZCBoYWxmIGZhbGxzIGFib3ZlIHRoZSBtZWRpYW4uDQoNCjQuUXVhcnRpbGVzIGFuZCBwZXJjZW50aWxlcyBhcmUgb3RoZXIgY29tbW9uIHF1YW50aWxlcy4gUXVhcnRpbGVzIHNwbGl0IHRoZSBkYXRhIGludG8gNCBncm91cHMgd2hpbGUgcGVyY2VudGlsZXMgc3BsaXQgdGhlIGRhdGEgaW50byAxMDAgZ3JvdXBzLg0KDQojIyBJbnN0cnVjdGlvbnMNCg0KVG8gdGhlIHJpZ2h0LCB3ZeKAmXZlIHNob3duIHRocmVlIGRpZmZlcmVudCBoaXN0b2dyYW1zIGFsb25nIHdpdGggdGhlIGRlY2lsZXMuIEVhY2ggaGlzdG9ncmFtIHNob3dzIHRoZSBTQVQgc2NvcmVzIG9mIHRoZSBzdHVkZW50cyB0aGF0IGEgZmFrZSB1bml2ZXJzaXR5IGhhcyBhY2NlcHRlZC4NCg0KSWYgeW91IGhhZCBhbiBTQVQgc2NvcmUgb2YgMTM1MCwgd2hpY2ggdGVudGggb2YgdGhlIGRhdGEgd291bGQgeW91IGJlIGluIGZvciBlYWNoIHNjaG9vbD8gV2hpY2ggc2Nob29scyBzaG91bGQgeW91IGFwcGx5IHRvPyBXb3VsZCBhbnkgb2YgdGhlIHNjaG9vbHMgYmUgdW5yZWFsaXN0aWMgb3B0aW9ucz8NCg0KYGBge3IgUXVhbnRpbGVzOSwgb3V0LndpZHRoPSI2MCUifQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoIkM6L1VzZXJzL2t1b2FuL0Rlc2t0b3AvUiBDb2RlL1F1YW50aWxlczkucG5nIikNCmBgYA0KYGBge3IgUXVhbnRpbGVzMTAsIG91dC53aWR0aD0iNjAlIn0NCmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCJDOi9Vc2Vycy9rdW9hbi9EZXNrdG9wL1IgQ29kZS9RdWFudGlsZXMxMC5wbmciKQ0KYGBgDQpgYGB7ciBRdWFudGlsZXMxMSwgb3V0LndpZHRoPSI2MCUifQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoIkM6L1VzZXJzL2t1b2FuL0Rlc2t0b3AvUiBDb2RlL1F1YW50aWxlczExLnBuZyIpDQpgYGA=