Initial data load

data(nycflights)
names(nycflights)
##  [1] "year"      "month"     "day"       "dep_time"  "dep_delay" "arr_time" 
##  [7] "arr_delay" "carrier"   "tailnum"   "flight"    "origin"    "dest"     
## [13] "air_time"  "distance"  "hour"      "minute"
glimpse(nycflights)
## Rows: 32,735
## Columns: 16
## $ year      <int> 2013, 2013, 2013, 2013, 2013, 2013, 2013, 2013, 2013, 201...
## $ month     <int> 6, 5, 12, 5, 7, 1, 12, 8, 9, 4, 6, 11, 4, 3, 10, 1, 2, 8,...
## $ day       <int> 30, 7, 8, 14, 21, 1, 9, 13, 26, 30, 17, 22, 26, 25, 21, 2...
## $ dep_time  <int> 940, 1657, 859, 1841, 1102, 1817, 1259, 1920, 725, 1323, ...
## $ dep_delay <dbl> 15, -3, -1, -4, -3, -3, 14, 85, -10, 62, 5, 5, -2, 115, -...
## $ arr_time  <int> 1216, 2104, 1238, 2122, 1230, 2008, 1617, 2032, 1027, 154...
## $ arr_delay <dbl> -4, 10, 11, -34, -8, 3, 22, 71, -8, 60, -4, -2, 22, 91, -...
## $ carrier   <chr> "VX", "DL", "DL", "DL", "9E", "AA", "WN", "B6", "AA", "EV...
## $ tailnum   <chr> "N626VA", "N3760C", "N712TW", "N914DL", "N823AY", "N3AXAA...
## $ flight    <int> 407, 329, 422, 2391, 3652, 353, 1428, 1407, 2279, 4162, 2...
## $ origin    <chr> "JFK", "JFK", "JFK", "JFK", "LGA", "LGA", "EWR", "JFK", "...
## $ dest      <chr> "LAX", "SJU", "LAX", "TPA", "ORF", "ORD", "HOU", "IAD", "...
## $ air_time  <dbl> 313, 216, 376, 135, 50, 138, 240, 48, 148, 110, 50, 161, ...
## $ distance  <dbl> 2475, 1598, 2475, 1005, 296, 733, 1411, 228, 1096, 820, 2...
## $ hour      <dbl> 9, 16, 8, 18, 11, 18, 12, 19, 7, 13, 9, 13, 8, 20, 12, 20...
## $ minute    <dbl> 40, 57, 59, 41, 2, 17, 59, 20, 25, 23, 40, 20, 9, 54, 17,...

Plot Histogram

Analysis

Let’s start by examing the distribution of departure delays of all flights with a histogram.

Histogram 1

ggplot(data = nycflights, aes(x = dep_delay)) +
  geom_histogram()
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

Histogram 2

ggplot(data = nycflights, aes(x = dep_delay)) +
  geom_histogram(binwidth = 15)

Histogram 2

ggplot(data = nycflights, aes(x = dep_delay)) +
  geom_histogram(binwidth = 150)

Exercise 1

Look carefully at these three histograms. How do they compare? Are features revealed in one that are obscured in another?

We notice that the smaller the binwidth is, the finer the detail is. The second histogram has the smallest binwidth, so it displays the data in finer detail. The third histogram has the largest binwidth and clumps much of the data together, hiding lots of detail. The first histogram has a binwidth in between the other two and displays detail correspondingly. Though the second histogram shows the most detail, the binwidth of the first one seems to be just right and is more pleasing to the eye to visualize the data.

arbuthnot$girls
##  [1] 4683 4457 4102 4590 4839 4820 4928 4605 4457 4952 4784 5332 5200 4910 4617
## [16] 3997 3919 3395 3536 3181 2746 2722 2840 2908 2959 3179 3349 3382 3289 3013
## [31] 2781 3247 4107 4803 4881 5681 4858 4319 5322 5560 5829 5719 6061 6120 5822
## [46] 5738 5717 5847 6203 6033 6041 6299 6533 6744 7158 7127 7246 7119 7214 7101
## [61] 7167 7302 7392 7316 7483 6647 6713 7229 7767 7626 7452 7061 7514 7656 7683
## [76] 5738 7779 7417 7687 7623 7380 7288

Exercise 2

Create a new data frame that includes flights headed to SFO in February, and save this data frame as sfo_feb_flights. How many flights meet these criteria?

sfo_feb_flights <- nycflights %>%
  filter(dest == "SFO", month == 2)

Flights meet these criteria

nrow(sfo_feb_flights)
## [1] 68

Exercise 3

Describe the distribution of the arrival delays of these flights using a histogram and appropriate summary statistics. Hint: The summary statistics you use should depend on the shape of the distribution.

ggplot(data = sfo_feb_flights, aes(x = dep_delay)) +
  geom_histogram(binwidth = 15)


The histogram is right-skewed, so the standard deviation would not accurately represent the distribution of the data.

sfo_feb_flights %>%
  group_by(origin) %>%
  summarise(median_dd = median(dep_delay), 
            iqr_dd = IQR(dep_delay), 
            n_flights = n())
## # A tibble: 2 x 4
##   origin median_dd iqr_dd n_flights
## * <chr>      <dbl>  <dbl>     <int>
## 1 EWR          0.5   5.75         8
## 2 JFK         -2.5  15.2         60

Exercise 4

Calculate the median and interquartile range for arr_delays of flights in in the sfo_feb_flights data frame, grouped by carrier. Which carrier has the most variable arrival delays?

sfo_feb_flights %>%group_by(carrier) %>%
  summarise(median = median(arr_delay), 
            iqr = IQR(arr_delay), 
            n_flights = n()) %>%
  arrange(desc(iqr))
## # A tibble: 5 x 4
##   carrier median   iqr n_flights
##   <chr>    <dbl> <dbl>     <int>
## 1 DL       -15    22          19
## 2 UA       -10    22          21
## 3 VX       -22.5  21.2        12
## 4 AA         5    17.5        10
## 5 B6       -10.5  12.2         6

Carrier that has the most variable arrival delay

sfo_feb_flights %>%group_by(carrier) %>%
  summarise(iqr = IQR(arr_delay)) %>%
  arrange(desc(iqr))
## # A tibble: 5 x 2
##   carrier   iqr
##   <chr>   <dbl>
## 1 DL       22  
## 2 UA       22  
## 3 VX       21.2
## 4 AA       17.5
## 5 B6       12.2

Departure delays by month

nycflights %>%
  group_by(month) %>%
  summarise(mean_dd = mean(dep_delay)) %>%
  arrange(desc(mean_dd))
## # A tibble: 12 x 2
##    month mean_dd
##    <int>   <dbl>
##  1     7   20.8 
##  2     6   20.4 
##  3    12   17.4 
##  4     4   14.6 
##  5     3   13.5 
##  6     5   13.3 
##  7     8   12.6 
##  8     2   10.7 
##  9     1   10.2 
## 10     9    6.87
## 11    11    6.10
## 12    10    5.88

Exercise 5

Suppose you really dislike departure delays and you want to schedule your travel in a month that minimizes your potential departure delay leaving NYC. One option is to choose the month with the lowest mean departure delay. Another option is to choose the month with the lowest median departure delay. What are the pros and cons of these two choices?

The mean is the more reliable measure for deciding which month(s) to avoid flying if you really dislike delayed flights since it gives us the true average. That is even the pros of choosing the mean and the cons is just the measure is sensitive to extreme delays. The cons of choosing the median is that the measure doesn’t arise the true delay.

nycflights %>%
  group_by(month) %>%
  summarise(median = median(dep_delay)) %>%
  arrange(desc(median))
## # A tibble: 12 x 2
##    month median
##    <int>  <dbl>
##  1    12      1
##  2     6      0
##  3     7      0
##  4     3     -1
##  5     5     -1
##  6     8     -1
##  7     1     -2
##  8     2     -2
##  9     4     -2
## 10    11     -2
## 11     9     -3
## 12    10     -3

On time departure rate for NYC airports

nycflights <- nycflights %>%
  mutate(dep_type = ifelse(dep_delay < 5, "on time", "delayed"))

nycflights %>%
  group_by(origin) %>%
  summarise(ot_dep_rate = sum(dep_type == "on time") / n()) %>%
  arrange(desc(ot_dep_rate))
## # A tibble: 3 x 2
##   origin ot_dep_rate
##   <chr>        <dbl>
## 1 LGA          0.728
## 2 JFK          0.694
## 3 EWR          0.637

Exercise 6

If you were selecting an airport simply based on on time departure percentage, which NYC airport would you choose to fly out of?

ggplot(data = nycflights, aes(x = origin, fill = dep_type)) +
  geom_bar()

LGA has best time departure percentage of (72.8%). Thus correct choice should be LDA airport

Exercise 7

Mutate the data frame so that it includes a new variable that contains the average speed, avg_speed traveled by the plane for each flight (in mph). Hint: Average speed can be calculated as distance divided by number of hours of travel, and note that air_time is given in minutes.

nycflights <- nycflights %>%
  mutate(avg_speed = distance / (air_time / 60))
glimpse(nycflights)
## Rows: 32,735
## Columns: 18
## $ year      <int> 2013, 2013, 2013, 2013, 2013, 2013, 2013, 2013, 2013, 201...
## $ month     <int> 6, 5, 12, 5, 7, 1, 12, 8, 9, 4, 6, 11, 4, 3, 10, 1, 2, 8,...
## $ day       <int> 30, 7, 8, 14, 21, 1, 9, 13, 26, 30, 17, 22, 26, 25, 21, 2...
## $ dep_time  <int> 940, 1657, 859, 1841, 1102, 1817, 1259, 1920, 725, 1323, ...
## $ dep_delay <dbl> 15, -3, -1, -4, -3, -3, 14, 85, -10, 62, 5, 5, -2, 115, -...
## $ arr_time  <int> 1216, 2104, 1238, 2122, 1230, 2008, 1617, 2032, 1027, 154...
## $ arr_delay <dbl> -4, 10, 11, -34, -8, 3, 22, 71, -8, 60, -4, -2, 22, 91, -...
## $ carrier   <chr> "VX", "DL", "DL", "DL", "9E", "AA", "WN", "B6", "AA", "EV...
## $ tailnum   <chr> "N626VA", "N3760C", "N712TW", "N914DL", "N823AY", "N3AXAA...
## $ flight    <int> 407, 329, 422, 2391, 3652, 353, 1428, 1407, 2279, 4162, 2...
## $ origin    <chr> "JFK", "JFK", "JFK", "JFK", "LGA", "LGA", "EWR", "JFK", "...
## $ dest      <chr> "LAX", "SJU", "LAX", "TPA", "ORF", "ORD", "HOU", "IAD", "...
## $ air_time  <dbl> 313, 216, 376, 135, 50, 138, 240, 48, 148, 110, 50, 161, ...
## $ distance  <dbl> 2475, 1598, 2475, 1005, 296, 733, 1411, 228, 1096, 820, 2...
## $ hour      <dbl> 9, 16, 8, 18, 11, 18, 12, 19, 7, 13, 9, 13, 8, 20, 12, 20...
## $ minute    <dbl> 40, 57, 59, 41, 2, 17, 59, 20, 25, 23, 40, 20, 9, 54, 17,...
## $ dep_type  <chr> "delayed", "on time", "on time", "on time", "on time", "o...
## $ avg_speed <dbl> 474.4409, 443.8889, 394.9468, 446.6667, 355.2000, 318.695...

Exercise 8

Make a scatterplot of avg_speed vs. distance. Describe the relationship between average speed and distance. Hint: Use geom_point().

ggplot(data = nycflights, aes(x = distance, y = avg_speed)) + geom_point()

Above graph shows - as distance increases, the average speed increases as well. So average speed and distance maintain a positive relationship.

Exercise 9

Replicate the following plot. Hint: The data frame plotted only contains flights from American Airlines, Delta Airlines, and United Airlines, and the points are colored by carrier. Once you replicate the plot, determine (roughly) what the cutoff point is for departure delays where you can still expect to get to your destination on time.

nycflights_3carriers <- nycflights %>%
  filter(carrier == "AA" | carrier == "DL" | carrier == "UA")
ggplot(data = nycflights_3carriers, aes(x = dep_delay, y = arr_delay, color= carrier)) + geom_point()

LS0tDQp0aXRsZTogIkxhYiAyIDogSW50cm9kdWN0aW9uIHRvIGRhdGEiDQphdXRob3I6ICJSYW1uaXZhcyBTaW5naCINCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCINCm91dHB1dDogb3BlbmludHJvOjpsYWJfcmVwb3J0DQotLS0NCg0KYGBge3IgZ2xvYmFsX29wdGlvbnMsIGluY2x1ZGU9RkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZXZhbCA9IFRSVUUsIHJlc3VsdHMgPSBUUlVFLCBmaWcuc2hvdyA9ICJzaG93IiwgbWVzc2FnZSA9IFRSVUUsIHdhcm5pbmcgPSBGQUxTRSkNCmxpYnJhcnkodGlkeXZlcnNlKQ0KbGlicmFyeShvcGVuaW50cm8pDQpgYGANClwNCg0KIyBJbml0aWFsIGRhdGEgbG9hZA0KYGBge3IgbG9hZC1kYXRhfQ0KZGF0YShueWNmbGlnaHRzKQ0KYGBgDQoNCmBgYHtyIG5hbWVzfQ0KbmFtZXMobnljZmxpZ2h0cykNCmBgYA0KYGBge3J9DQpnbGltcHNlKG55Y2ZsaWdodHMpDQpgYGANCg0KIyBQbG90IEhpc3RvZ3JhbQ0KDQojIEFuYWx5c2lzDQoNCkxldCdzIHN0YXJ0IGJ5IGV4YW1pbmcgdGhlIGRpc3RyaWJ1dGlvbiBvZiBkZXBhcnR1cmUgZGVsYXlzIG9mIGFsbCBmbGlnaHRzIHdpdGggYSANCmhpc3RvZ3JhbS4NCg0KIyMgSGlzdG9ncmFtIDENCmBgYHtyIGhpc3QtZGVwLWRlbGF5fQ0KZ2dwbG90KGRhdGEgPSBueWNmbGlnaHRzLCBhZXMoeCA9IGRlcF9kZWxheSkpICsNCiAgZ2VvbV9oaXN0b2dyYW0oKQ0KYGBgDQoNCiMjIEhpc3RvZ3JhbSAyDQpgYGB7ciBoaXN0LWRlcC1kZWxheS1iaW5zMTV9DQpnZ3Bsb3QoZGF0YSA9IG55Y2ZsaWdodHMsIGFlcyh4ID0gZGVwX2RlbGF5KSkgKw0KICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDE1KQ0KYGBgDQoNCiMjIEhpc3RvZ3JhbSAyDQpgYGB7ciBoaXN0LWRlcC1kZWxheS1iaW5zMTUwfQ0KZ2dwbG90KGRhdGEgPSBueWNmbGlnaHRzLCBhZXMoeCA9IGRlcF9kZWxheSkpICsNCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAxNTApDQpgYGANCg0KIyMgRXhlcmNpc2UgMQ0KTG9vayBjYXJlZnVsbHkgYXQgdGhlc2UgdGhyZWUgaGlzdG9ncmFtcy4gSG93IGRvIHRoZXkgY29tcGFyZT8gQXJlIGZlYXR1cmVzDQpyZXZlYWxlZCBpbiBvbmUgdGhhdCBhcmUgb2JzY3VyZWQgaW4gYW5vdGhlcj8NCg0KV2Ugbm90aWNlIHRoYXQgdGhlIHNtYWxsZXIgdGhlIGJpbndpZHRoIGlzLCB0aGUgZmluZXIgdGhlIGRldGFpbCBpcy4gVGhlIHNlY29uZCBoaXN0b2dyYW0gaGFzIHRoZSBzbWFsbGVzdCBiaW53aWR0aCwgc28gaXQgZGlzcGxheXMgdGhlIGRhdGEgaW4gZmluZXIgZGV0YWlsLiBUaGUgdGhpcmQgaGlzdG9ncmFtIGhhcyB0aGUgbGFyZ2VzdCBiaW53aWR0aCBhbmQgY2x1bXBzIG11Y2ggb2YgdGhlIGRhdGEgdG9nZXRoZXIsIGhpZGluZyBsb3RzIG9mIGRldGFpbC4gVGhlIGZpcnN0IGhpc3RvZ3JhbSBoYXMgYSBiaW53aWR0aCBpbiBiZXR3ZWVuIHRoZSBvdGhlciB0d28gYW5kIGRpc3BsYXlzIGRldGFpbCBjb3JyZXNwb25kaW5nbHkuIFRob3VnaCB0aGUgc2Vjb25kIGhpc3RvZ3JhbSBzaG93cyB0aGUgbW9zdCBkZXRhaWwsIHRoZSBiaW53aWR0aCBvZiB0aGUgZmlyc3Qgb25lIHNlZW1zIHRvIGJlIGp1c3QgcmlnaHQgYW5kIGlzIG1vcmUgcGxlYXNpbmcgdG8gdGhlIGV5ZSB0byB2aXN1YWxpemUgdGhlIGRhdGEuDQoNCmBgYHtyIHZpZXctZ2lybHMtY291bnRzfQ0KYXJidXRobm90JGdpcmxzDQpgYGANCg0KDQojIyBFeGVyY2lzZSAyDQpDcmVhdGUgYSBuZXcgZGF0YSBmcmFtZSB0aGF0IGluY2x1ZGVzIGZsaWdodHMgaGVhZGVkIHRvIFNGTyBpbiBGZWJydWFyeSwgYW5kIHNhdmUgdGhpcyBkYXRhIGZyYW1lIGFzIHNmb19mZWJfZmxpZ2h0cy4gSG93IG1hbnkgZmxpZ2h0cyBtZWV0IHRoZXNlIGNyaXRlcmlhPw0KYGBge3Igc2ZvX2ZlYl9mbGlnaHRzfQ0Kc2ZvX2ZlYl9mbGlnaHRzIDwtIG55Y2ZsaWdodHMgJT4lDQogIGZpbHRlcihkZXN0ID09ICJTRk8iLCBtb250aCA9PSAyKQ0KYGBgDQoqKkZsaWdodHMgbWVldCB0aGVzZSBjcml0ZXJpYSoqDQpgYGB7cn0NCm5yb3coc2ZvX2ZlYl9mbGlnaHRzKQ0KYGBgDQoNCiMjIEV4ZXJjaXNlIDMNCkRlc2NyaWJlIHRoZSBkaXN0cmlidXRpb24gb2YgdGhlIGFycml2YWwgZGVsYXlzIG9mIHRoZXNlIGZsaWdodHMgdXNpbmcgYSBoaXN0b2dyYW0gYW5kIGFwcHJvcHJpYXRlIHN1bW1hcnkgc3RhdGlzdGljcy4gSGludDogVGhlIHN1bW1hcnkgc3RhdGlzdGljcyB5b3UgdXNlIHNob3VsZCBkZXBlbmQgb24gdGhlIHNoYXBlIG9mIHRoZSBkaXN0cmlidXRpb24uXA0KDQpgYGB7ciBwbG90LXNmb19mZWJfZmxpZ2h0c30NCmdncGxvdChkYXRhID0gc2ZvX2ZlYl9mbGlnaHRzLCBhZXMoeCA9IGRlcF9kZWxheSkpICsNCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAxNSkNCg0KYGBgDQpcDQpUaGUgaGlzdG9ncmFtIGlzIHJpZ2h0LXNrZXdlZCwgc28gdGhlIHN0YW5kYXJkIGRldmlhdGlvbiB3b3VsZCBub3QgYWNjdXJhdGVseSByZXByZXNlbnQgdGhlIGRpc3RyaWJ1dGlvbiBvZiB0aGUgZGF0YS4NCmBgYHtyfQ0Kc2ZvX2ZlYl9mbGlnaHRzICU+JQ0KICBncm91cF9ieShvcmlnaW4pICU+JQ0KICBzdW1tYXJpc2UobWVkaWFuX2RkID0gbWVkaWFuKGRlcF9kZWxheSksIA0KICAgICAgICAgICAgaXFyX2RkID0gSVFSKGRlcF9kZWxheSksIA0KICAgICAgICAgICAgbl9mbGlnaHRzID0gbigpKQ0KYGBgDQojIyBFeGVyY2lzZSA0DQpDYWxjdWxhdGUgdGhlIG1lZGlhbiBhbmQgaW50ZXJxdWFydGlsZSByYW5nZSBmb3IgYXJyX2RlbGF5cyBvZiBmbGlnaHRzIGluIGluIHRoZSBzZm9fZmViX2ZsaWdodHMgZGF0YSBmcmFtZSwgZ3JvdXBlZCBieSBjYXJyaWVyLiBXaGljaCBjYXJyaWVyIGhhcyB0aGUgbW9zdCB2YXJpYWJsZSBhcnJpdmFsIGRlbGF5cz8NCmBgYHtyfQ0Kc2ZvX2ZlYl9mbGlnaHRzICU+JWdyb3VwX2J5KGNhcnJpZXIpICU+JQ0KICBzdW1tYXJpc2UobWVkaWFuID0gbWVkaWFuKGFycl9kZWxheSksIA0KICAgICAgICAgICAgaXFyID0gSVFSKGFycl9kZWxheSksIA0KICAgICAgICAgICAgbl9mbGlnaHRzID0gbigpKSAlPiUNCiAgYXJyYW5nZShkZXNjKGlxcikpDQpgYGANCkNhcnJpZXIgdGhhdCBoYXMgdGhlIG1vc3QgdmFyaWFibGUgYXJyaXZhbCBkZWxheQ0KYGBge3J9DQpzZm9fZmViX2ZsaWdodHMgJT4lZ3JvdXBfYnkoY2FycmllcikgJT4lDQogIHN1bW1hcmlzZShpcXIgPSBJUVIoYXJyX2RlbGF5KSkgJT4lDQogIGFycmFuZ2UoZGVzYyhpcXIpKQ0KDQpgYGANCkRlcGFydHVyZSBkZWxheXMgYnkgbW9udGgNCg0KYGBge3J9DQpueWNmbGlnaHRzICU+JQ0KICBncm91cF9ieShtb250aCkgJT4lDQogIHN1bW1hcmlzZShtZWFuX2RkID0gbWVhbihkZXBfZGVsYXkpKSAlPiUNCiAgYXJyYW5nZShkZXNjKG1lYW5fZGQpKQ0KDQpgYGANCg0KIyMgRXhlcmNpc2UgNQ0KU3VwcG9zZSB5b3UgcmVhbGx5IGRpc2xpa2UgZGVwYXJ0dXJlIGRlbGF5cyBhbmQgeW91IHdhbnQgdG8gc2NoZWR1bGUgeW91ciB0cmF2ZWwgaW4gYSBtb250aCB0aGF0IG1pbmltaXplcyB5b3VyIHBvdGVudGlhbCBkZXBhcnR1cmUgZGVsYXkgbGVhdmluZyBOWUMuIE9uZSBvcHRpb24gaXMgdG8gY2hvb3NlIHRoZSBtb250aCB3aXRoIHRoZSBsb3dlc3QgbWVhbiBkZXBhcnR1cmUgZGVsYXkuIEFub3RoZXIgb3B0aW9uIGlzIHRvIGNob29zZSB0aGUgbW9udGggd2l0aCB0aGUgbG93ZXN0IG1lZGlhbiBkZXBhcnR1cmUgZGVsYXkuIFdoYXQgYXJlIHRoZSBwcm9zIGFuZCBjb25zIG9mIHRoZXNlIHR3byBjaG9pY2VzPw0KDQpUaGUgbWVhbiBpcyB0aGUgbW9yZSByZWxpYWJsZSBtZWFzdXJlIGZvciBkZWNpZGluZyB3aGljaCBtb250aChzKSB0byBhdm9pZCBmbHlpbmcgaWYgeW91IHJlYWxseSBkaXNsaWtlIGRlbGF5ZWQgZmxpZ2h0cyBzaW5jZSBpdCBnaXZlcyB1cyB0aGUgdHJ1ZSBhdmVyYWdlLiBUaGF0IGlzIGV2ZW4gdGhlIHByb3Mgb2YgY2hvb3NpbmcgdGhlIG1lYW4gYW5kIHRoZSBjb25zIGlzIGp1c3QgdGhlIG1lYXN1cmUgaXMgc2Vuc2l0aXZlIHRvIGV4dHJlbWUgZGVsYXlzLiBUaGUgY29ucyBvZiBjaG9vc2luZyB0aGUgbWVkaWFuIGlzIHRoYXQgdGhlIG1lYXN1cmUgZG9lc27igJl0IGFyaXNlIHRoZSB0cnVlIGRlbGF5Lg0KYGBge3J9DQpueWNmbGlnaHRzICU+JQ0KICBncm91cF9ieShtb250aCkgJT4lDQogIHN1bW1hcmlzZShtZWRpYW4gPSBtZWRpYW4oZGVwX2RlbGF5KSkgJT4lDQogIGFycmFuZ2UoZGVzYyhtZWRpYW4pKQ0KDQpgYGANCk9uIHRpbWUgZGVwYXJ0dXJlIHJhdGUgZm9yIE5ZQyBhaXJwb3J0cw0KYGBge3J9DQpueWNmbGlnaHRzIDwtIG55Y2ZsaWdodHMgJT4lDQogIG11dGF0ZShkZXBfdHlwZSA9IGlmZWxzZShkZXBfZGVsYXkgPCA1LCAib24gdGltZSIsICJkZWxheWVkIikpDQoNCm55Y2ZsaWdodHMgJT4lDQogIGdyb3VwX2J5KG9yaWdpbikgJT4lDQogIHN1bW1hcmlzZShvdF9kZXBfcmF0ZSA9IHN1bShkZXBfdHlwZSA9PSAib24gdGltZSIpIC8gbigpKSAlPiUNCiAgYXJyYW5nZShkZXNjKG90X2RlcF9yYXRlKSkNCmBgYA0KIyMgRXhlcmNpc2UgNg0KSWYgeW91IHdlcmUgc2VsZWN0aW5nIGFuIGFpcnBvcnQgc2ltcGx5IGJhc2VkIG9uIG9uIHRpbWUgZGVwYXJ0dXJlIHBlcmNlbnRhZ2UsIHdoaWNoIE5ZQyBhaXJwb3J0IHdvdWxkIHlvdSBjaG9vc2UgdG8gZmx5IG91dCBvZj8NCmBgYHtyfQ0KZ2dwbG90KGRhdGEgPSBueWNmbGlnaHRzLCBhZXMoeCA9IG9yaWdpbiwgZmlsbCA9IGRlcF90eXBlKSkgKw0KICBnZW9tX2JhcigpDQpgYGANCkxHQSBoYXMgYmVzdCB0aW1lIGRlcGFydHVyZSBwZXJjZW50YWdlIG9mICg3Mi44JSkuIFRodXMgY29ycmVjdCBjaG9pY2Ugc2hvdWxkIGJlIExEQSBhaXJwb3J0XA0KDQojIyBFeGVyY2lzZSA3DQpNdXRhdGUgdGhlIGRhdGEgZnJhbWUgc28gdGhhdCBpdCBpbmNsdWRlcyBhIG5ldyB2YXJpYWJsZSB0aGF0IGNvbnRhaW5zIHRoZSBhdmVyYWdlIHNwZWVkLCBhdmdfc3BlZWQgdHJhdmVsZWQgYnkgdGhlIHBsYW5lIGZvciBlYWNoIGZsaWdodCAoaW4gbXBoKS4gSGludDogQXZlcmFnZSBzcGVlZCBjYW4gYmUgY2FsY3VsYXRlZCBhcyBkaXN0YW5jZSBkaXZpZGVkIGJ5IG51bWJlciBvZiBob3VycyBvZiB0cmF2ZWwsIGFuZCBub3RlIHRoYXQgYWlyX3RpbWUgaXMgZ2l2ZW4gaW4gbWludXRlcy4NCg0KYGBge3J9DQpueWNmbGlnaHRzIDwtIG55Y2ZsaWdodHMgJT4lDQogIG11dGF0ZShhdmdfc3BlZWQgPSBkaXN0YW5jZSAvIChhaXJfdGltZSAvIDYwKSkNCmdsaW1wc2UobnljZmxpZ2h0cykNCg0KYGBgDQoNCiMjIEV4ZXJjaXNlIDgNCk1ha2UgYSBzY2F0dGVycGxvdCBvZiBhdmdfc3BlZWQgdnMuIGRpc3RhbmNlLiBEZXNjcmliZSB0aGUgcmVsYXRpb25zaGlwIGJldHdlZW4gYXZlcmFnZSBzcGVlZCBhbmQgZGlzdGFuY2UuIEhpbnQ6IFVzZSBnZW9tX3BvaW50KCkuDQoNCmBgYHtyfQ0KZ2dwbG90KGRhdGEgPSBueWNmbGlnaHRzLCBhZXMoeCA9IGRpc3RhbmNlLCB5ID0gYXZnX3NwZWVkKSkgKyBnZW9tX3BvaW50KCkNCg0KYGBgDQpBYm92ZSBncmFwaCBzaG93cyAtIGFzIGRpc3RhbmNlIGluY3JlYXNlcywgdGhlIGF2ZXJhZ2Ugc3BlZWQgaW5jcmVhc2VzIGFzIHdlbGwuIFNvIGF2ZXJhZ2Ugc3BlZWQgYW5kIGRpc3RhbmNlIG1haW50YWluIGEgcG9zaXRpdmUgcmVsYXRpb25zaGlwLg0KDQojIyBFeGVyY2lzZSA5DQoNClJlcGxpY2F0ZSB0aGUgZm9sbG93aW5nIHBsb3QuIEhpbnQ6IFRoZSBkYXRhIGZyYW1lIHBsb3R0ZWQgb25seSBjb250YWlucyBmbGlnaHRzIGZyb20gQW1lcmljYW4gQWlybGluZXMsIERlbHRhIEFpcmxpbmVzLCBhbmQgVW5pdGVkIEFpcmxpbmVzLCBhbmQgdGhlIHBvaW50cyBhcmUgY29sb3JlZCBieSBjYXJyaWVyLiBPbmNlIHlvdSByZXBsaWNhdGUgdGhlIHBsb3QsIGRldGVybWluZSAocm91Z2hseSkgd2hhdCB0aGUgY3V0b2ZmIHBvaW50IGlzIGZvciBkZXBhcnR1cmUgZGVsYXlzIHdoZXJlIHlvdSBjYW4gc3RpbGwgZXhwZWN0IHRvIGdldCB0byB5b3VyIGRlc3RpbmF0aW9uIG9uIHRpbWUuDQpgYGB7cn0NCm55Y2ZsaWdodHNfM2NhcnJpZXJzIDwtIG55Y2ZsaWdodHMgJT4lDQogIGZpbHRlcihjYXJyaWVyID09ICJBQSIgfCBjYXJyaWVyID09ICJETCIgfCBjYXJyaWVyID09ICJVQSIpDQpnZ3Bsb3QoZGF0YSA9IG55Y2ZsaWdodHNfM2NhcnJpZXJzLCBhZXMoeCA9IGRlcF9kZWxheSwgeSA9IGFycl9kZWxheSwgY29sb3I9IGNhcnJpZXIpKSArIGdlb21fcG9pbnQoKQ0KYGBgDQoNCg==