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=