1.Quartiles
A common way to communicate a high-level overview of a dataset is to
find the values that split the data into four groups of equal size.
By doing this, we can then say whether a new datapoint falls in the
first, second, third, or fourth quarter of the data.
knitr::include_graphics("C:/Users/kuoan/Desktop/R Code/Quartiles.png")

Those values are called the first quartile (Q1), the second quartile
(Q2), and the third quartile (Q3)
In the image above, Q1 is 10, Q2 is 13, and Q3 is 22. Those three
values split the data into four groups that each contain five
datapoints.
In this lesson, you will learn to calculate the quartiles by hand,
and by using base R functions.
Instructions
In this lesson we’ll be looking at a dataset about music. We’ve
plotted a histogram of song lengths (measured in seconds) of 9,975
random songs.
Look up the length of a favorite song of yours. Do you think that
song falls in the first, second, third or fourth quarter of the
data?
For example, we’ve picked one of our favorite songs, Chicago by
Sufjan Stevens. Chicago is 364 seconds long — we’ve plotted it as a blue
vertical line. It looks like Chicago is in either the third or fourth
quarter of the data, but it’s hard to say for sure. Let’s find the
quartiles of the dataset!
# load song data
load("songs.Rda")
錯誤發生在 readChar(con, 5L, useBytes = TRUE): 無法開啟連接
2.The Second Quartile
We’ll come back to the music dataset in a bit, but let’s first
practice on a small dataset.
Let’s begin by finding the second quartile (Q2). Q2 happens to be
exactly the median. Half of the data falls below Q2 and half of the data
falls above Q2.
The first step in finding the quartiles of a dataset is to sort the
data from smallest to largest. For example, below is an unsorted
dataset:
c(8,15,4,−108,16,23,42)
After sorting the dataset, it looks like this:
c(−108,4,8,15,16,23,42)
Now that the list is sorted, we can find Q2. In the example dataset
above, Q2 (and the median) is 15 — there are three points below 15 and
three points above 15.
Even Number of Datapoints
You might be wondering what happens if there is an even number of
points in the dataset. For example, if we remove the -108 from our
dataset, it will now look like this:
c(4,8,15,16,23,42)
Q2 now falls somewhere between 15 and 16. There are a couple of
different strategies that you can use to calculate Q2 in this situation.
One of the more common ways is to take the average of those two numbers.
In this case, that would be 15.5.
Recall that you can find the average of two numbers by adding them
together and dividing by two.
Instructions
1.We’ve included two small unsorted datasets named dataset_one and
dataset_two.
We’ve also included, as a comment, the sorted version of the first
dataset.
By looking at sorted version of dataset_one, find the second quartile
of the dataset and store it in a variable named dataset_one_q2.
2.Find the second quartile of the dataset_two and store it in a
variable named dataset_two_q2.
Remember to sort the dataset. It might help to write out the sorted
dataset as a comment!
Since there are an even number of datapoints in this dataset, the
second quartile will fall between two points. The second quartile will
be the average of those two points.
dataset_two <- sort(dataset_two)
dataset_two
[1] -15 1 20 24 40 45
dataset_two_q2 <- 22
dataset_two_q2
[1] 22
3.Q1 and Q3
Now that we’ve found Q2, we can use that value to help us find Q1 and
Q3. Recall our demo dataset:
c(−108,4,8,15,16,23,42)
In this example, Q2 is 15. To find Q1, we take all of the data points
smaller than Q2 and find the median of those points. In this case, the
points smaller than Q2 are:
c(−108,4,8)
The median of that smaller dataset is 4. That’s Q1!
To find Q3, do the same process using the points that are larger than
Q2. We have the following points:
c(16,23,42)
The median of those points is 23. That’s Q3! We now have three points
that split the original dataset into groups of four equal sizes.
Instructions
1.Find the first quartile of dataset_one and store it in a variable
named dataset_one_q1.
dataset_one <- c(50, 10, 4, -3, 4, -20, 2)
# sorted dataset_one: [-20, -3, 2, 4, 4, 10, 50]
dataset_two <- c(24, 20, 1, 45, -15, 40)
dataset_one_q2 <- 4
dataset_two_q2 <- 22
# define the first and third quartile of both datasets here:
dataset_one_q1 <- -3
dataset_one_q1
[1] -3
2.Find the third quartile of dataset_one and store it in a variable
named dataset_one_q3.
dataset_one_q3 <- 10
dataset_one_q3
[1] 10
3.Find Q1 and Q3 of dataset_two. Store the values in variables named
dataset_two_q1 and dataset_two_q3.
dataset_two <- sort(dataset_two)
dataset_two
[1] -15 1 20 24 40 45
dataset_two_q1 <- 1
dataset_two_q3 <- 40
dataset_two_q1
[1] 1
dataset_two_q3
[1] 40
4.Method Two: Including Q2
You just learned a commonly used method to calculate the quartiles of
a dataset. However, there is another method that is equally accepted
that results in different values!
Note that there is no universally agreed upon method of calculating
quartiles, and as a result, two different tools might report different
results.
The second method includes Q2 when trying to calculate Q1 and Q3.
Let’s take a look at an example:
c(−108,4,8,15,16,23,42)
Using the first method, we found Q1 to be 4. When looking at all of
the points below Q2, we excluded Q2. Using this second method, we
include Q2 in each half.
For example, when calculating Q1 using this new method, we would now
find the median of this dataset:
c(−108,4,8,15)
Using this method, Q1 is 6.
Instructions
1.Create a variable named dataset_one_q1 and set it equal to the
first quartile of dataset one. This time, use the second method of
finding quartiles.
dataset_one <- c(50, 10, 4, -3, 4, -20, 2)
# sorted dataset_one: [-20, -3, 2, 4, 4, 10, 50]
dataset_two <- c(24, 20, 1, 45, -15, 40)
dataset_one_q2 <- 4
dataset_two_q2 <- 22
# define the first and third quartile of both datasets here:
dataset_one_q1 <- -0.5
dataset_one_q1
[1] -0.5
2.Create a variable named dataset_one_q3 and set it equal to the
third quartile of dataset one. Again, use the second method of finding
quartiles.
dataset_one_q3 <- 7
dataset_one_q3
[1] 7
3.Create two variables named dataset_two_q1 and dataset_two_q3 and
set them equal to the first and third quartile of dataset two.
Use the second method of calculating quartiles. Since Q2 fell between
two data points, this method is no different than the first method!
dataset_two <- sort(dataset_two)
dataset_two
[1] -15 1 20 24 40 45
dataset_two_q1 <- 1
dataset_two_q1
[1] 1
dataset_two_q3 <- 40
dataset_two_q3
[1] 40
5.Quartiles in R
We were able to find quartiles manually by looking at the dataset and
finding the correct division points. But that gets much harder when the
dataset starts to get bigger. Luckily, there is a function in base R
that will find the quartiles for you.
The base R function that we’ll be using is named quantile(). You can
learn more about quantiles in our quantiles lesson, but for right now
all you need to know is that a quartile is a specific kind of
quantile.
The code below calculates the third quartile of the given
dataset:
dataset <- c(50, 10, 4, -3, 4, -20, 2)
third_quartile <- quantile(dataset, 0.75)
third_quartile
75%
7
The quantile() function takes two parameters. The first is the
dataset you’re interested in. The second is a number between 0 and 1.
Since we calculated the third quartile, we used 0.75 — we want the point
that splits the first 75% of the data from the rest.
For the second quartile, we’d use 0.5. This will give you the point
that 50% of the data is below and 50% is above.
Notice that the dataset doesn’t need to be sorted for R’s function to
work!
Instructions
1.We’ve brought back our music dataset. The lengths of 9,975 songs
(in seconds) are stored in a variable named songs. Use the quantile()
function to find the first quartile. Store the result in a variable
named songs_q1.
25% 175.9342
2.Find the second and third quartile of the dataset and store the
values in two variables named songs_q2 and songs_q3.
50% 222.824
75% 275.4738
3.Look up the length of your favorite song in seconds. Store that
value in a variable named favorite_song.
Does that song fall in the first, second, third, or fourth quarter of
the data? Create a variable named quarter. Set quarter equal to 1 if
your favorite song falls in the first quarter of the data. Set it equal
to 2 if your song falls in the second fourth. Set it equal to 3 if your
song falls in the third fourth. And set it to 4 if your song falls in
the final fourth of the data.
# create the variables favorite_song and quarter here:
favorite_song <- 287
favorite_song
[1] 287
quarter <- 4
quarter
[1] 4
6.Quartiles Review
Great work! You now know how to calculate the quartiles of any
dataset by hand and with R.
Quartiles are some of the most commonly used descriptive statistics.
For example, You might see schools or universities think about quartiles
when considering which students to accept. Businesses might compare
their revenue to other companies by looking at quartiles.
In fact quartiles are so commonly used that the three quartiles,
along with the minimum and the maximum values of a dataset, are called
the five-number summary of the dataset. These five numbers help you
quickly get a sense of the range, centrality, and spread of the
dataset.
Instructions
We’ve plotted the first, second, and third quartiles on the histogram
for our music dataset. Are they where you expected to see them?
knitr::include_graphics("C:/Users/kuoan/Desktop/R Code/Quartiles3.png")

LS0tDQp0aXRsZTogIlF1YXJ0aWxlcyINCmF1dGhvcjogIkFubmFiZWwgS3VvIg0KZGF0ZTogImByIGZvcm1hdChTeXMudGltZSgpLCAnJVktJW0tJWQgJUg6JU0nKWAiDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQojIDEuUXVhcnRpbGVzDQoNCkEgY29tbW9uIHdheSB0byBjb21tdW5pY2F0ZSBhIGhpZ2gtbGV2ZWwgb3ZlcnZpZXcgb2YgYSBkYXRhc2V0IGlzIHRvIGZpbmQgdGhlIHZhbHVlcyB0aGF0IHNwbGl0IHRoZSBkYXRhIGludG8gZm91ciBncm91cHMgb2YgZXF1YWwgc2l6ZS4NCg0KQnkgZG9pbmcgdGhpcywgd2UgY2FuIHRoZW4gc2F5IHdoZXRoZXIgYSBuZXcgZGF0YXBvaW50IGZhbGxzIGluIHRoZSBmaXJzdCwgc2Vjb25kLCB0aGlyZCwgb3IgZm91cnRoIHF1YXJ0ZXIgb2YgdGhlIGRhdGEuDQoNCg0KYGBge3IgUXVhcnRpbGVzLCBvdXQud2lkdGg9IjYwJSJ9DQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygiQzovVXNlcnMva3VvYW4vRGVza3RvcC9SIENvZGUvUXVhcnRpbGVzLnBuZyIpDQpgYGANCg0KVGhvc2UgdmFsdWVzIGFyZSBjYWxsZWQgdGhlIGZpcnN0IHF1YXJ0aWxlIChRMSksIHRoZSBzZWNvbmQgcXVhcnRpbGUgKFEyKSwgYW5kIHRoZSB0aGlyZCBxdWFydGlsZSAoUTMpDQoNCkluIHRoZSBpbWFnZSBhYm92ZSwgUTEgaXMgMTAsIFEyIGlzIDEzLCBhbmQgUTMgaXMgMjIuIFRob3NlIHRocmVlIHZhbHVlcyBzcGxpdCB0aGUgZGF0YSBpbnRvIGZvdXIgZ3JvdXBzIHRoYXQgZWFjaCBjb250YWluIGZpdmUgZGF0YXBvaW50cy4NCg0KSW4gdGhpcyBsZXNzb24sIHlvdSB3aWxsIGxlYXJuIHRvIGNhbGN1bGF0ZSB0aGUgcXVhcnRpbGVzIGJ5IGhhbmQsIGFuZCBieSB1c2luZyBiYXNlIFIgZnVuY3Rpb25zLg0KDQojIyBJbnN0cnVjdGlvbnMNCg0KSW4gdGhpcyBsZXNzb24gd2XigJlsbCBiZSBsb29raW5nIGF0IGEgZGF0YXNldCBhYm91dCBtdXNpYy4gV2XigJl2ZSBwbG90dGVkIGEgaGlzdG9ncmFtIG9mIHNvbmcgbGVuZ3RocyAobWVhc3VyZWQgaW4gc2Vjb25kcykgb2YgOSw5NzUgcmFuZG9tIHNvbmdzLg0KDQpMb29rIHVwIHRoZSBsZW5ndGggb2YgYSBmYXZvcml0ZSBzb25nIG9mIHlvdXJzLiBEbyB5b3UgdGhpbmsgdGhhdCBzb25nIGZhbGxzIGluIHRoZSBmaXJzdCwgc2Vjb25kLCB0aGlyZCBvciBmb3VydGggcXVhcnRlciBvZiB0aGUgZGF0YT8NCg0KRm9yIGV4YW1wbGUsIHdl4oCZdmUgcGlja2VkIG9uZSBvZiBvdXIgZmF2b3JpdGUgc29uZ3MsIENoaWNhZ28gYnkgU3VmamFuIFN0ZXZlbnMuIENoaWNhZ28gaXMgMzY0IHNlY29uZHMgbG9uZyDigJQgd2XigJl2ZSBwbG90dGVkIGl0IGFzIGEgYmx1ZSB2ZXJ0aWNhbCBsaW5lLiBJdCBsb29rcyBsaWtlIENoaWNhZ28gaXMgaW4gZWl0aGVyIHRoZSB0aGlyZCBvciBmb3VydGggcXVhcnRlciBvZiB0aGUgZGF0YSwgYnV0IGl04oCZcyBoYXJkIHRvIHNheSBmb3Igc3VyZS4gTGV04oCZcyBmaW5kIHRoZSBxdWFydGlsZXMgb2YgdGhlIGRhdGFzZXQhDQoNCmBgYHtyfQ0KIyBsb2FkIHNvbmcgZGF0YQ0KbG9hZCgic29uZ3MuUmRhIikNCmBgYA0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFfQ0KIyBwbG90IGhpc3RvZ3JhbQ0KaGlzdCA8LSBxcGxvdChzb25ncywNCiAgICAgICAgICAgICAgZ2VvbT0iaGlzdG9ncmFtIiwNCiAgICAgICAgICAgICAgbWFpbiA9ICdIaXN0b2dyYW0gb2YgU29uZyBMZW5ndGhzJywNCiAgICAgICAgICAgICAgeGxhYiA9ICdTb25nIExlbmd0aCAoU2Vjb25kcyknLA0KICAgICAgICAgICAgICB5bGFiID0gJ0NvdW50JywNCiAgICAgICAgICAgICAgZmlsbD1JKCJibHVlIiksDQogICAgICAgICAgICAgIGNvbD1JKCJyZWQiKSwNCiAgICAgICAgICAgICAgYWxwaGE9SSguMikpICsNCiAJCQkJZ2VvbV92bGluZShhZXMoeGludGVyY2VwdD0zNjQsDQogICAgICAgICAgICAgICAgICAgICAgIGNvbG9yPUkoImJsdWUiKSksDQogICAgICAgICAgICAgICAgICAgbGluZXR5cGU9InNvbGlkIiwNCiAgICAgICAgICAgICAgICAgICBzaXplPTEsDQogICAgICAgICAgICAgICAgICAgc2hvdy5sZWdlbmQ9VCkgKw0KCQkJCXNjYWxlX2NvbG91cl9tYW51YWwobmFtZSA9ICIiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9YygiQ2hpY2FnbyIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlcz1jKCJibHVlIikpDQoNCmhpc3QNCmBgYA0KDQpgYGB7ciBRdWFydGlsZXMyLCBvdXQud2lkdGg9IjYwJSJ9DQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygiQzovVXNlcnMva3VvYW4vRGVza3RvcC9SIENvZGUvUXVhcnRpbGVzMi5wbmciKQ0KYGBgDQoNCiMgMi5UaGUgU2Vjb25kIFF1YXJ0aWxlDQoNCldl4oCZbGwgY29tZSBiYWNrIHRvIHRoZSBtdXNpYyBkYXRhc2V0IGluIGEgYml0LCBidXQgbGV04oCZcyBmaXJzdCBwcmFjdGljZSBvbiBhIHNtYWxsIGRhdGFzZXQuDQoNCkxldOKAmXMgYmVnaW4gYnkgZmluZGluZyB0aGUgc2Vjb25kIHF1YXJ0aWxlIChRMikuIFEyIGhhcHBlbnMgdG8gYmUgZXhhY3RseSB0aGUgbWVkaWFuLiBIYWxmIG9mIHRoZSBkYXRhIGZhbGxzIGJlbG93IFEyIGFuZCBoYWxmIG9mIHRoZSBkYXRhIGZhbGxzIGFib3ZlIFEyLg0KDQpUaGUgZmlyc3Qgc3RlcCBpbiBmaW5kaW5nIHRoZSBxdWFydGlsZXMgb2YgYSBkYXRhc2V0IGlzIHRvIHNvcnQgdGhlIGRhdGEgZnJvbSBzbWFsbGVzdCB0byBsYXJnZXN0LiBGb3IgZXhhbXBsZSwgYmVsb3cgaXMgYW4gdW5zb3J0ZWQgZGF0YXNldDoNCg0KYyg4LDE1LDQs4oiSMTA4LDE2LDIzLDQyKQ0KDQpBZnRlciBzb3J0aW5nIHRoZSBkYXRhc2V0LCBpdCBsb29rcyBsaWtlIHRoaXM6DQoNCmMo4oiSMTA4LDQsOCwxNSwxNiwyMyw0MikNCg0KTm93IHRoYXQgdGhlIGxpc3QgaXMgc29ydGVkLCB3ZSBjYW4gZmluZCBRMi4gSW4gdGhlIGV4YW1wbGUgZGF0YXNldCBhYm92ZSwgUTIgKGFuZCB0aGUgbWVkaWFuKSBpcyAxNSDigJQgdGhlcmUgYXJlIHRocmVlIHBvaW50cyBiZWxvdyAxNSBhbmQgdGhyZWUgcG9pbnRzIGFib3ZlIDE1Lg0KDQojIyMgRXZlbiBOdW1iZXIgb2YgRGF0YXBvaW50cw0KDQpZb3UgbWlnaHQgYmUgd29uZGVyaW5nIHdoYXQgaGFwcGVucyBpZiB0aGVyZSBpcyBhbiBldmVuIG51bWJlciBvZiBwb2ludHMgaW4gdGhlIGRhdGFzZXQuIEZvciBleGFtcGxlLCBpZiB3ZSByZW1vdmUgdGhlIC0xMDggZnJvbSBvdXIgZGF0YXNldCwgaXQgd2lsbCBub3cgbG9vayBsaWtlIHRoaXM6DQoNCmMoNCw4LDE1LDE2LDIzLDQyKQ0KDQpRMiBub3cgZmFsbHMgc29tZXdoZXJlIGJldHdlZW4gMTUgYW5kIDE2LiBUaGVyZSBhcmUgYSBjb3VwbGUgb2YgZGlmZmVyZW50IHN0cmF0ZWdpZXMgdGhhdCB5b3UgY2FuIHVzZSB0byBjYWxjdWxhdGUgUTIgaW4gdGhpcyBzaXR1YXRpb24uIE9uZSBvZiB0aGUgbW9yZSBjb21tb24gd2F5cyBpcyB0byB0YWtlIHRoZSBhdmVyYWdlIG9mIHRob3NlIHR3byBudW1iZXJzLiBJbiB0aGlzIGNhc2UsIHRoYXQgd291bGQgYmUgMTUuNS4NCg0KUmVjYWxsIHRoYXQgeW91IGNhbiBmaW5kIHRoZSBhdmVyYWdlIG9mIHR3byBudW1iZXJzIGJ5IGFkZGluZyB0aGVtIHRvZ2V0aGVyIGFuZCBkaXZpZGluZyBieSB0d28uDQoNCiMjIEluc3RydWN0aW9ucw0KDQoxLldl4oCZdmUgaW5jbHVkZWQgdHdvIHNtYWxsIHVuc29ydGVkIGRhdGFzZXRzIG5hbWVkIGRhdGFzZXRfb25lIGFuZCBkYXRhc2V0X3R3by4NCg0KV2XigJl2ZSBhbHNvIGluY2x1ZGVkLCBhcyBhIGNvbW1lbnQsIHRoZSBzb3J0ZWQgdmVyc2lvbiBvZiB0aGUgZmlyc3QgZGF0YXNldC4NCg0KQnkgbG9va2luZyBhdCBzb3J0ZWQgdmVyc2lvbiBvZiBkYXRhc2V0X29uZSwgZmluZCB0aGUgc2Vjb25kIHF1YXJ0aWxlIG9mIHRoZSBkYXRhc2V0IGFuZCBzdG9yZSBpdCBpbiBhIHZhcmlhYmxlIG5hbWVkIGRhdGFzZXRfb25lX3EyLg0KDQpgYGB7cn0NCmRhdGFzZXRfb25lIDwtIGMoNTAsIDEwLCA0LCAtMywgNCwgLTIwLCAyKQ0KIyBzb3J0ZWQgZGF0YXNldF9vbmU6IGMoLTIwLCAtMywgMiwgNCwgNCwgMTAsIDUwKQ0KDQpkYXRhc2V0X3R3byA8LSBjKDI0LCAyMCwgMSwgNDUsIC0xNSwgNDApDQoNCiMgZGVmaW5lIHRoZSBzZWNvbmQgcXVhcnRpbGUgb2YgYm90aCBkYXRhc2V0cyBoZXJlOg0KZGF0YXNldF9vbmVfcTIgPC0gNA0KZGF0YXNldF9vbmVfcTINCmBgYA0KDQoyLkZpbmQgdGhlIHNlY29uZCBxdWFydGlsZSBvZiB0aGUgZGF0YXNldF90d28gYW5kIHN0b3JlIGl0IGluIGEgdmFyaWFibGUgbmFtZWQgZGF0YXNldF90d29fcTIuDQoNClJlbWVtYmVyIHRvIHNvcnQgdGhlIGRhdGFzZXQuIEl0IG1pZ2h0IGhlbHAgdG8gd3JpdGUgb3V0IHRoZSBzb3J0ZWQgZGF0YXNldCBhcyBhIGNvbW1lbnQhDQoNClNpbmNlIHRoZXJlIGFyZSBhbiBldmVuIG51bWJlciBvZiBkYXRhcG9pbnRzIGluIHRoaXMgZGF0YXNldCwgdGhlIHNlY29uZCBxdWFydGlsZSB3aWxsIGZhbGwgYmV0d2VlbiB0d28gcG9pbnRzLiBUaGUgc2Vjb25kIHF1YXJ0aWxlIHdpbGwgYmUgdGhlIGF2ZXJhZ2Ugb2YgdGhvc2UgdHdvIHBvaW50cy4NCg0KYGBge3J9DQpkYXRhc2V0X3R3byA8LSBzb3J0KGRhdGFzZXRfdHdvKQ0KZGF0YXNldF90d28NCmRhdGFzZXRfdHdvX3EyIDwtIDIyDQpkYXRhc2V0X3R3b19xMg0KYGBgDQoNCiMgMy5RMSBhbmQgUTMNCg0KTm93IHRoYXQgd2XigJl2ZSBmb3VuZCBRMiwgd2UgY2FuIHVzZSB0aGF0IHZhbHVlIHRvIGhlbHAgdXMgZmluZCBRMSBhbmQgUTMuIFJlY2FsbCBvdXIgZGVtbyBkYXRhc2V0Og0KDQpjKOKIkjEwOCw0LDgsMTUsMTYsMjMsNDIpDQoNCkluIHRoaXMgZXhhbXBsZSwgUTIgaXMgMTUuIFRvIGZpbmQgUTEsIHdlIHRha2UgYWxsIG9mIHRoZSBkYXRhIHBvaW50cyBzbWFsbGVyIHRoYW4gUTIgYW5kIGZpbmQgdGhlIG1lZGlhbiBvZiB0aG9zZSBwb2ludHMuIEluIHRoaXMgY2FzZSwgdGhlIHBvaW50cyBzbWFsbGVyIHRoYW4gUTIgYXJlOg0KDQpjKOKIkjEwOCw0LDgpDQoNClRoZSBtZWRpYW4gb2YgdGhhdCBzbWFsbGVyIGRhdGFzZXQgaXMgNC4gVGhhdOKAmXMgUTEhDQoNClRvIGZpbmQgUTMsIGRvIHRoZSBzYW1lIHByb2Nlc3MgdXNpbmcgdGhlIHBvaW50cyB0aGF0IGFyZSBsYXJnZXIgdGhhbiBRMi4gV2UgaGF2ZSB0aGUgZm9sbG93aW5nIHBvaW50czoNCg0KYygxNiwyMyw0MikNCg0KVGhlIG1lZGlhbiBvZiB0aG9zZSBwb2ludHMgaXMgMjMuIFRoYXTigJlzIFEzISBXZSBub3cgaGF2ZSB0aHJlZSBwb2ludHMgdGhhdCBzcGxpdCB0aGUgb3JpZ2luYWwgZGF0YXNldCBpbnRvIGdyb3VwcyBvZiBmb3VyIGVxdWFsIHNpemVzLg0KDQoNCiMjIEluc3RydWN0aW9ucw0KDQoxLkZpbmQgdGhlIGZpcnN0IHF1YXJ0aWxlIG9mIGRhdGFzZXRfb25lIGFuZCBzdG9yZSBpdCBpbiBhIHZhcmlhYmxlIG5hbWVkIGRhdGFzZXRfb25lX3ExLg0KDQpgYGB7cn0NCmRhdGFzZXRfb25lIDwtIGMoNTAsIDEwLCA0LCAtMywgNCwgLTIwLCAyKQ0KIyBzb3J0ZWQgZGF0YXNldF9vbmU6IFstMjAsIC0zLCAyLCA0LCA0LCAxMCwgNTBdDQoNCmRhdGFzZXRfdHdvIDwtIGMoMjQsIDIwLCAxLCA0NSwgLTE1LCA0MCkNCg0KZGF0YXNldF9vbmVfcTIgPC0gNA0KZGF0YXNldF90d29fcTIgPC0gMjINCg0KIyBkZWZpbmUgdGhlIGZpcnN0IGFuZCB0aGlyZCBxdWFydGlsZSBvZiBib3RoIGRhdGFzZXRzIGhlcmU6DQpkYXRhc2V0X29uZV9xMSA8LSAtMw0KZGF0YXNldF9vbmVfcTENCmBgYA0KDQoyLkZpbmQgdGhlIHRoaXJkIHF1YXJ0aWxlIG9mIGRhdGFzZXRfb25lIGFuZCBzdG9yZSBpdCBpbiBhIHZhcmlhYmxlIG5hbWVkIGRhdGFzZXRfb25lX3EzLg0KYGBge3J9DQpkYXRhc2V0X29uZV9xMyA8LSAxMA0KZGF0YXNldF9vbmVfcTMNCmBgYA0KDQozLkZpbmQgUTEgYW5kIFEzIG9mIGRhdGFzZXRfdHdvLiBTdG9yZSB0aGUgdmFsdWVzIGluIHZhcmlhYmxlcyBuYW1lZCBkYXRhc2V0X3R3b19xMSBhbmQgZGF0YXNldF90d29fcTMuDQoNCmBgYHtyfQ0KZGF0YXNldF90d28gPC0gc29ydChkYXRhc2V0X3R3bykNCmRhdGFzZXRfdHdvDQpkYXRhc2V0X3R3b19xMSA8LSAxDQpkYXRhc2V0X3R3b19xMyA8LSA0MA0KZGF0YXNldF90d29fcTENCmRhdGFzZXRfdHdvX3EzDQpgYGANCg0KIyA0Lk1ldGhvZCBUd286IEluY2x1ZGluZyBRMg0KDQpZb3UganVzdCBsZWFybmVkIGEgY29tbW9ubHkgdXNlZCBtZXRob2QgdG8gY2FsY3VsYXRlIHRoZSBxdWFydGlsZXMgb2YgYSBkYXRhc2V0LiBIb3dldmVyLCB0aGVyZSBpcyBhbm90aGVyIG1ldGhvZCB0aGF0IGlzIGVxdWFsbHkgYWNjZXB0ZWQgdGhhdCByZXN1bHRzIGluIGRpZmZlcmVudCB2YWx1ZXMhDQoNCk5vdGUgdGhhdCB0aGVyZSBpcyBubyB1bml2ZXJzYWxseSBhZ3JlZWQgdXBvbiBtZXRob2Qgb2YgY2FsY3VsYXRpbmcgcXVhcnRpbGVzLCBhbmQgYXMgYSByZXN1bHQsIHR3byBkaWZmZXJlbnQgdG9vbHMgbWlnaHQgcmVwb3J0IGRpZmZlcmVudCByZXN1bHRzLg0KDQpUaGUgc2Vjb25kIG1ldGhvZCBpbmNsdWRlcyBRMiB3aGVuIHRyeWluZyB0byBjYWxjdWxhdGUgUTEgYW5kIFEzLiBMZXTigJlzIHRha2UgYSBsb29rIGF0IGFuIGV4YW1wbGU6DQoNCmMo4oiSMTA4LDQsOCwxNSwxNiwyMyw0MikNCg0KVXNpbmcgdGhlIGZpcnN0IG1ldGhvZCwgd2UgZm91bmQgUTEgdG8gYmUgNC4gV2hlbiBsb29raW5nIGF0IGFsbCBvZiB0aGUgcG9pbnRzIGJlbG93IFEyLCB3ZSBleGNsdWRlZCBRMi4gVXNpbmcgdGhpcyBzZWNvbmQgbWV0aG9kLCB3ZSBpbmNsdWRlIFEyIGluIGVhY2ggaGFsZi4NCg0KRm9yIGV4YW1wbGUsIHdoZW4gY2FsY3VsYXRpbmcgUTEgdXNpbmcgdGhpcyBuZXcgbWV0aG9kLCB3ZSB3b3VsZCBub3cgZmluZCB0aGUgbWVkaWFuIG9mIHRoaXMgZGF0YXNldDoNCg0KYyjiiJIxMDgsNCw4LDE1KQ0KDQpVc2luZyB0aGlzIG1ldGhvZCwgUTEgaXMgNi4NCg0KIyMgSW5zdHJ1Y3Rpb25zDQoNCjEuQ3JlYXRlIGEgdmFyaWFibGUgbmFtZWQgZGF0YXNldF9vbmVfcTEgYW5kIHNldCBpdCBlcXVhbCB0byB0aGUgZmlyc3QgcXVhcnRpbGUgb2YgZGF0YXNldCBvbmUuIFRoaXMgdGltZSwgdXNlIHRoZSBzZWNvbmQgbWV0aG9kIG9mIGZpbmRpbmcgcXVhcnRpbGVzLg0KDQpgYGB7cn0NCmRhdGFzZXRfb25lIDwtIGMoNTAsIDEwLCA0LCAtMywgNCwgLTIwLCAyKQ0KIyBzb3J0ZWQgZGF0YXNldF9vbmU6IFstMjAsIC0zLCAyLCA0LCA0LCAxMCwgNTBdDQoNCmRhdGFzZXRfdHdvIDwtIGMoMjQsIDIwLCAxLCA0NSwgLTE1LCA0MCkNCg0KZGF0YXNldF9vbmVfcTIgPC0gNA0KZGF0YXNldF9vbmVfcTINCg0KZGF0YXNldF90d29fcTIgPC0gMjINCmRhdGFzZXRfdHdvX3EyDQpgYGANCg0KYGBge3J9DQojIGRlZmluZSB0aGUgZmlyc3QgYW5kIHRoaXJkIHF1YXJ0aWxlIG9mIGJvdGggZGF0YXNldHMgaGVyZToNCmRhdGFzZXRfb25lX3ExIDwtIC0wLjUNCmRhdGFzZXRfb25lX3ExDQpgYGANCg0KMi5DcmVhdGUgYSB2YXJpYWJsZSBuYW1lZCBkYXRhc2V0X29uZV9xMyBhbmQgc2V0IGl0IGVxdWFsIHRvIHRoZSB0aGlyZCBxdWFydGlsZSBvZiBkYXRhc2V0IG9uZS4gQWdhaW4sIHVzZSB0aGUgc2Vjb25kIG1ldGhvZCBvZiBmaW5kaW5nIHF1YXJ0aWxlcy4NCg0KYGBge3J9DQpkYXRhc2V0X29uZV9xMyA8LSA3DQpkYXRhc2V0X29uZV9xMw0KYGBgDQoNCjMuQ3JlYXRlIHR3byB2YXJpYWJsZXMgbmFtZWQgZGF0YXNldF90d29fcTEgYW5kIGRhdGFzZXRfdHdvX3EzIGFuZCBzZXQgdGhlbSBlcXVhbCB0byB0aGUgZmlyc3QgYW5kIHRoaXJkIHF1YXJ0aWxlIG9mIGRhdGFzZXQgdHdvLg0KDQpVc2UgdGhlIHNlY29uZCBtZXRob2Qgb2YgY2FsY3VsYXRpbmcgcXVhcnRpbGVzLiBTaW5jZSBRMiBmZWxsIGJldHdlZW4gdHdvIGRhdGEgcG9pbnRzLCB0aGlzIG1ldGhvZCBpcyBubyBkaWZmZXJlbnQgdGhhbiB0aGUgZmlyc3QgbWV0aG9kIQ0KYGBge3J9DQpkYXRhc2V0X3R3byA8LSBzb3J0KGRhdGFzZXRfdHdvKQ0KZGF0YXNldF90d28NCmRhdGFzZXRfdHdvX3ExIDwtIDENCmRhdGFzZXRfdHdvX3ExDQpkYXRhc2V0X3R3b19xMyA8LSA0MA0KZGF0YXNldF90d29fcTMNCmBgYA0KDQojIDUuUXVhcnRpbGVzIGluIFINCg0KV2Ugd2VyZSBhYmxlIHRvIGZpbmQgcXVhcnRpbGVzIG1hbnVhbGx5IGJ5IGxvb2tpbmcgYXQgdGhlIGRhdGFzZXQgYW5kIGZpbmRpbmcgdGhlIGNvcnJlY3QgZGl2aXNpb24gcG9pbnRzLiBCdXQgdGhhdCBnZXRzIG11Y2ggaGFyZGVyIHdoZW4gdGhlIGRhdGFzZXQgc3RhcnRzIHRvIGdldCBiaWdnZXIuIEx1Y2tpbHksIHRoZXJlIGlzIGEgZnVuY3Rpb24gaW4gYmFzZSBSIHRoYXQgd2lsbCBmaW5kIHRoZSBxdWFydGlsZXMgZm9yIHlvdS4NCg0KVGhlIGJhc2UgUiBmdW5jdGlvbiB0aGF0IHdl4oCZbGwgYmUgdXNpbmcgaXMgbmFtZWQgcXVhbnRpbGUoKS4gWW91IGNhbiBsZWFybiBtb3JlIGFib3V0IHF1YW50aWxlcyBpbiBvdXIgcXVhbnRpbGVzIGxlc3NvbiwgYnV0IGZvciByaWdodCBub3cgYWxsIHlvdSBuZWVkIHRvIGtub3cgaXMgdGhhdCBhIHF1YXJ0aWxlIGlzIGEgc3BlY2lmaWMga2luZCBvZiBxdWFudGlsZS4NCg0KVGhlIGNvZGUgYmVsb3cgY2FsY3VsYXRlcyB0aGUgdGhpcmQgcXVhcnRpbGUgb2YgdGhlIGdpdmVuIGRhdGFzZXQ6DQoNCmBgYHtyfQ0KZGF0YXNldCA8LSBjKDUwLCAxMCwgNCwgLTMsIDQsIC0yMCwgMikNCnRoaXJkX3F1YXJ0aWxlIDwtIHF1YW50aWxlKGRhdGFzZXQsIDAuNzUpDQp0aGlyZF9xdWFydGlsZQ0KYGBgDQoNClRoZSBxdWFudGlsZSgpIGZ1bmN0aW9uIHRha2VzIHR3byBwYXJhbWV0ZXJzLiBUaGUgZmlyc3QgaXMgdGhlIGRhdGFzZXQgeW914oCZcmUgaW50ZXJlc3RlZCBpbi4gVGhlIHNlY29uZCBpcyBhIG51bWJlciBiZXR3ZWVuIDAgYW5kIDEuIFNpbmNlIHdlIGNhbGN1bGF0ZWQgdGhlIHRoaXJkIHF1YXJ0aWxlLCB3ZSB1c2VkIDAuNzUg4oCUIHdlIHdhbnQgdGhlIHBvaW50IHRoYXQgc3BsaXRzIHRoZSBmaXJzdCA3NSUgb2YgdGhlIGRhdGEgZnJvbSB0aGUgcmVzdC4NCg0KRm9yIHRoZSBzZWNvbmQgcXVhcnRpbGUsIHdl4oCZZCB1c2UgMC41LiBUaGlzIHdpbGwgZ2l2ZSB5b3UgdGhlIHBvaW50IHRoYXQgNTAlIG9mIHRoZSBkYXRhIGlzIGJlbG93IGFuZCA1MCUgaXMgYWJvdmUuDQoNCk5vdGljZSB0aGF0IHRoZSBkYXRhc2V0IGRvZXNu4oCZdCBuZWVkIHRvIGJlIHNvcnRlZCBmb3IgUuKAmXMgZnVuY3Rpb24gdG8gd29yayENCg0KIyMgSW5zdHJ1Y3Rpb25zDQoNCjEuV2XigJl2ZSBicm91Z2h0IGJhY2sgb3VyIG11c2ljIGRhdGFzZXQuIFRoZSBsZW5ndGhzIG9mIDksOTc1IHNvbmdzIChpbiBzZWNvbmRzKSBhcmUgc3RvcmVkIGluIGEgdmFyaWFibGUgbmFtZWQgc29uZ3MuIFVzZSB0aGUgcXVhbnRpbGUoKSBmdW5jdGlvbiB0byBmaW5kIHRoZSBmaXJzdCBxdWFydGlsZS4gU3RvcmUgdGhlIHJlc3VsdCBpbiBhIHZhcmlhYmxlIG5hbWVkIHNvbmdzX3ExLg0KDQpgYGB7cn0NCiMgY3JlYXRlIHRoZSB2YXJpYWJsZXMgc29uZ3NfcTEsIHNvbmdzX3EyLCBhbmQgc29uZ3NfcTMgaGVyZToNCnNvbmdzX3ExIDwtIHF1YW50aWxlKHNvbmdzLCAwLjI1KQ0KYGBgDQoNCjI1JSANCjE3NS45MzQyIA0KDQoyLkZpbmQgdGhlIHNlY29uZCBhbmQgdGhpcmQgcXVhcnRpbGUgb2YgdGhlIGRhdGFzZXQgYW5kIHN0b3JlIHRoZSB2YWx1ZXMgaW4gdHdvIHZhcmlhYmxlcyBuYW1lZCBzb25nc19xMiBhbmQgc29uZ3NfcTMuDQoNCmBgYHtyfQ0Kc29uZ3NfcTIgPC0gcXVhbnRpbGUoc29uZ3MsIDAuNSkNCnNvbmdzX3EzIDwtIGF1YW50aWxlKGNvbmdzLCAwLjc1KQ0Kc29uZ3NfcTINCnNvbmdzX3EzDQpgYGANCjUwJSANCjIyMi44MjQgDQoNCjc1JSANCjI3NS40NzM4IA0KDQozLkxvb2sgdXAgdGhlIGxlbmd0aCBvZiB5b3VyIGZhdm9yaXRlIHNvbmcgaW4gc2Vjb25kcy4gU3RvcmUgdGhhdCB2YWx1ZSBpbiBhIHZhcmlhYmxlIG5hbWVkIGZhdm9yaXRlX3NvbmcuDQoNCkRvZXMgdGhhdCBzb25nIGZhbGwgaW4gdGhlIGZpcnN0LCBzZWNvbmQsIHRoaXJkLCBvciBmb3VydGggcXVhcnRlciBvZiB0aGUgZGF0YT8gQ3JlYXRlIGEgdmFyaWFibGUgbmFtZWQgcXVhcnRlci4gU2V0IHF1YXJ0ZXIgZXF1YWwgdG8gMSBpZiB5b3VyIGZhdm9yaXRlIHNvbmcgZmFsbHMgaW4gdGhlIGZpcnN0IHF1YXJ0ZXIgb2YgdGhlIGRhdGEuIFNldCBpdCBlcXVhbCB0byAyIGlmIHlvdXIgc29uZyBmYWxscyBpbiB0aGUgc2Vjb25kIGZvdXJ0aC4gU2V0IGl0IGVxdWFsIHRvIDMgaWYgeW91ciBzb25nIGZhbGxzIGluIHRoZSB0aGlyZCBmb3VydGguIEFuZCBzZXQgaXQgdG8gNCBpZiB5b3VyIHNvbmcgZmFsbHMgaW4gdGhlIGZpbmFsIGZvdXJ0aCBvZiB0aGUgZGF0YS4NCg0KYGBge3J9DQojIGNyZWF0ZSB0aGUgdmFyaWFibGVzIGZhdm9yaXRlX3NvbmcgYW5kIHF1YXJ0ZXIgaGVyZToNCmZhdm9yaXRlX3NvbmcgPC0gMjg3DQpmYXZvcml0ZV9zb25nDQpxdWFydGVyIDwtIDQNCnF1YXJ0ZXINCmBgYA0KDQpgYGB7cn0NCiMgaWdub3JlIHRoZSBjb2RlIGJlbG93IGhlcmU6DQpzb25nc19xMSA8LSAxNzUuOTMyNA0Kc29uZ3NfcTIgPC0gMjIyLjgyNA0Kc29uZ3NfcTMgPC0gMjc1LjQ3MzgNCg0KdHJ5Q2F0Y2gocHJpbnQocGFzdGUoIlRoZSBmaXJzdCBxdWFydGlsZSBvZiBkYXRhc2V0IG9uZSBpcyIsc29uZ3NfcTEpKSwgZXJyb3I9ZnVuY3Rpb24oZSkge3ByaW50KCJZb3UgaGF2ZW4ndCBkZWZpbmVkIHNvbmdzX3ExIil9KQ0KDQp0cnlDYXRjaChwcmludChwYXN0ZSgiVGhlIHNlY29uZCBxdWFydGlsZSBvZiBkYXRhc2V0IHR3byBpcyIsc29uZ3NfcTIpKSwgZXJyb3I9ZnVuY3Rpb24oZSkge3ByaW50KCJZb3UgaGF2ZW4ndCBkZWZpbmVkIHNvbmdzX3EyIil9KQ0KDQp0cnlDYXRjaChwcmludChwYXN0ZSgiVGhlIHRoaXJkIHF1YXJ0aWxlIG9mIGRhdGFzZXQgb25lIGlzIixzb25nc19xMykpLCBlcnJvcj1mdW5jdGlvbihlKSB7cHJpbnQoIllvdSBoYXZlbid0IGRlZmluZWQgc29uZ3NfcTMiKX0pDQpgYGANCg0KIyA2LlF1YXJ0aWxlcyBSZXZpZXcNCg0KR3JlYXQgd29yayEgWW91IG5vdyBrbm93IGhvdyB0byBjYWxjdWxhdGUgdGhlIHF1YXJ0aWxlcyBvZiBhbnkgZGF0YXNldCBieSBoYW5kIGFuZCB3aXRoIFIuDQoNClF1YXJ0aWxlcyBhcmUgc29tZSBvZiB0aGUgbW9zdCBjb21tb25seSB1c2VkIGRlc2NyaXB0aXZlIHN0YXRpc3RpY3MuIEZvciBleGFtcGxlLCBZb3UgbWlnaHQgc2VlIHNjaG9vbHMgb3IgdW5pdmVyc2l0aWVzIHRoaW5rIGFib3V0IHF1YXJ0aWxlcyB3aGVuIGNvbnNpZGVyaW5nIHdoaWNoIHN0dWRlbnRzIHRvIGFjY2VwdC4gQnVzaW5lc3NlcyBtaWdodCBjb21wYXJlIHRoZWlyIHJldmVudWUgdG8gb3RoZXIgY29tcGFuaWVzIGJ5IGxvb2tpbmcgYXQgcXVhcnRpbGVzLg0KDQpJbiBmYWN0IHF1YXJ0aWxlcyBhcmUgc28gY29tbW9ubHkgdXNlZCB0aGF0IHRoZSB0aHJlZSBxdWFydGlsZXMsIGFsb25nIHdpdGggdGhlIG1pbmltdW0gYW5kIHRoZSBtYXhpbXVtIHZhbHVlcyBvZiBhIGRhdGFzZXQsIGFyZSBjYWxsZWQgdGhlIGZpdmUtbnVtYmVyIHN1bW1hcnkgb2YgdGhlIGRhdGFzZXQuIFRoZXNlIGZpdmUgbnVtYmVycyBoZWxwIHlvdSBxdWlja2x5IGdldCBhIHNlbnNlIG9mIHRoZSByYW5nZSwgY2VudHJhbGl0eSwgYW5kIHNwcmVhZCBvZiB0aGUgZGF0YXNldC4NCg0KIyMgSW5zdHJ1Y3Rpb25zDQoNCldl4oCZdmUgcGxvdHRlZCB0aGUgZmlyc3QsIHNlY29uZCwgYW5kIHRoaXJkIHF1YXJ0aWxlcyBvbiB0aGUgaGlzdG9ncmFtIGZvciBvdXIgbXVzaWMgZGF0YXNldC4gQXJlIHRoZXkgd2hlcmUgeW91IGV4cGVjdGVkIHRvIHNlZSB0aGVtPw0KDQpgYGB7ciBtZXNzYWdlPUZBTFNFfQ0KIyBwbG90IGhpc3RvZ3JhbQ0KaGlzdCA8LSBxcGxvdChzb25ncywNCiAgICAgICAgICAgICAgZ2VvbT0iaGlzdG9ncmFtIiwNCiAgICAgICAgICAgICAgbWFpbiA9ICdIaXN0b2dyYW0gb2YgU29uZyBMZW5ndGhzJywNCiAgICAgICAgICAgICAgeGxhYiA9ICdTb25nIExlbmd0aCAoU2Vjb25kcyknLA0KICAgICAgICAgICAgICB5bGFiID0gJ0NvdW50JywNCiAgICAgICAgICAgICAgZmlsbD1JKCJibHVlIiksDQogICAgICAgICAgICAgIGNvbD1JKCJyZWQiKSwNCiAgICAgICAgICAgICAgYWxwaGE9SSguMikpICsNCiAgICAgICAgZ2VvbV92bGluZShhZXMoeGludGVyY2VwdD1xdWFudGlsZShzb25ncywwLjI1KSwNCiAgICAgICAgICAgICAgICAgICAgICAgY29sb3I9SSgiYmx1ZSIpKSwNCiAgICAgICAgICAgICAgICAgICBsaW5ldHlwZT0ic29saWQiLA0KICAgICAgICAgICAgICAgICAgIHNpemU9MSwNCiAgICAgICAgICAgICAgICAgICBzaG93LmxlZ2VuZD1UKSArDQoJCQkJZ2VvbV92bGluZShhZXMoeGludGVyY2VwdD1xdWFudGlsZShzb25ncywwLjUpLA0KICAgICAgICAgICAgICAgICAgICAgICBjb2xvcj1JKCJwdXJwbGUiKSksDQogICAgICAgICAgICAgICAgICAgbGluZXR5cGU9InNvbGlkIiwNCiAgICAgICAgICAgICAgICAgICBzaXplPTEsDQogICAgICAgICAgICAgICAgICAgc2hvdy5sZWdlbmQ9VCkgKw0KICAJCQlnZW9tX3ZsaW5lKGFlcyh4aW50ZXJjZXB0PXF1YW50aWxlKHNvbmdzLDAuNzUpLA0KICAgICAgICAgICAgICAgICAgICAgICBjb2xvcj1JKCJ5ZWxsb3ciKSksDQogICAgICAgICAgICAgICAgICAgbGluZXR5cGU9InNvbGlkIiwNCiAgICAgICAgICAgICAgICAgICBzaXplPTEsDQogICAgICAgICAgICAgICAgICAgc2hvdy5sZWdlbmQ9VCkgKyANCgkJCQlzY2FsZV9jb2xvdXJfbWFudWFsKG5hbWUgPSAiIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPWMoIlExIiwiUTIiLCJRMyIpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlcz1jKCJibHVlIiwicHVycGxlIiwieWVsbG93IikpDQoNCmhpc3QNCmBgYA0KDQpgYGB7ciBRdWFydGlsZXMzLCBvdXQud2lkdGg9IjYwJSJ9DQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygiQzovVXNlcnMva3VvYW4vRGVza3RvcC9SIENvZGUvUXVhcnRpbGVzMy5wbmciKQ0KYGBgDQo=