library(tidyverse)
library(openintro)
data(nycflights)
Exercise 1:
Look carefully at these three histograms. How do they compare? Are features revealed in one that are obscured in another?
In the three histograms the bin sizes, that is the number of records that are grouped together, differ. Because of these differences the scale of the vertical y-axis also change.
The smaller bin sizes in histograms 1 and 2 allow for more detail to be shown that is hidden in the larger bin sizes in histogram 3. In this cases seeing that detail is important, particularly for histogram 2 where there is a number of records preceding the spike that could be important information, otherwise hidden in histograms 1 and 3, to better interpret these results.
# 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 3
ggplot(data = nycflights, aes(x = dep_delay)) +
geom_histogram(binwidth = 150)

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)
sfo_feb_flights %>%
summarise(mean_dd = mean(arr_delay),
median_dd = median(arr_delay),
n = n())
## # A tibble: 1 x 3
## mean_dd median_dd n
## <dbl> <dbl> <int>
## 1 -4.5 -11 68
Using the “summarise” function, there are 68 records with a destination as SFO in the month of February.
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 = arr_delay)) +
geom_histogram()
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

##
## Attaching package: 'psych'
## The following objects are masked from 'package:ggplot2':
##
## %+%, alpha
describe(sfo_feb_flights$arr_delay, skew = FALSE)
## vars n mean sd min max range se
## X1 1 68 -4.5 36.28 -66 196 262 4.4
The distribution of these data for arrival delays appears somewhat normal. There are a number of outliers of flights with extreme delays. So much so that it pulls the mean of the set (-4.5 minutes) away from the median (-11 minutes).
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_dd = median(arr_delay), iqr_dd = IQR(arr_delay), n_flights = n()) %>%
arrange(desc(iqr_dd))
## `summarise()` ungrouping output (override with `.groups` argument)
## # A tibble: 5 x 4
## carrier median_dd iqr_dd 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
Based on the table above the carriers from these data that have the highest variability are United Airlines and Delta. (As someone who would normally travel quite a bit for work and who uses UA as my carrier, I can attest to this variance!)
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?
nycflights %>%
group_by(month) %>%
summarise(mean_dd = mean(dep_delay)) %>%
arrange(mean_dd)
## `summarise()` ungrouping output (override with `.groups` argument)
## # A tibble: 12 x 2
## month mean_dd
## <int> <dbl>
## 1 10 5.88
## 2 11 6.10
## 3 9 6.87
## 4 1 10.2
## 5 2 10.7
## 6 8 12.6
## 7 5 13.3
## 8 3 13.5
## 9 4 14.6
## 10 12 17.4
## 11 6 20.4
## 12 7 20.8
nycflights %>%
group_by(month) %>%
summarise(median_dd = median(dep_delay)) %>%
arrange(median_dd)
## `summarise()` ungrouping output (override with `.groups` argument)
## # A tibble: 12 x 2
## month median_dd
## <int> <dbl>
## 1 9 -3
## 2 10 -3
## 3 1 -2
## 4 2 -2
## 5 4 -2
## 6 11 -2
## 7 3 -1
## 8 5 -1
## 9 8 -1
## 10 6 0
## 11 7 0
## 12 12 1
Arranging these data by month and by mean and median the outcome is that October has the lowest mean (5.9 minutes), while September has the lowest median (-3 minutes). Using the mean to make a determination on when to fly will be influenced more by outliers in the data set. As we’ve seen previously, there are a some really large delays, but also some really early departures. Using the median, by contrast, shows that 50% of the flights are below a certain point, in the case of September an arrival delay of -3 minutes. One has a 50% chance of being at or below -3 minutes. Airlines are not prone to leaving extraordinarily early, so using median, particularly with a number around zero minutes delayed, would seem to make a lot of sense as it shows more consistency.
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?
nycOrigin <- nycflights %>%
filter(origin == "EWR" | origin == "JFK" | origin == "LGA")
nycOrigin$onTimeFac <- ifelse(nycOrigin$dep_delay <= 0, "On Time", "Late")
prop.table(table(nycOrigin$origin, nycOrigin$onTimeFac))*100
##
## Late On Time
## EWR 16.22422 19.73423
## JFK 12.70200 20.58653
## LGA 10.17260 20.58042
Creating a new subset of the data to limit the view to NYC area airport, I also created a new column for on time and late flights, any flight at or below zero minutes delayed are labeled “On Time”, else they are “Late.”
Creating a proportional table by that new column and origin broke out the on time and late flights. An error I cannot seem to shake is that the rows do not add up to 100%. I tried a number of different checks, but it still persists.
Based on these data, JFK just slightly edges out LGA for more departures on time.
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)
Exercise 8:
Make a scatterplot of avg_speed vs. distance. Describe the relationship between average speed and distance. Hint: Use geom_point().
ggplot(nycflights, aes(x=distance, y=avg_speed)) +
geom_point()

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.
Ex9 <- nycflights %>%
filter(carrier == "AA" | carrier == "DL" | carrier == "UA")
ggplot(Ex9, aes(x=dep_delay, y=arr_delay, color=carrier)) +
geom_point()

From the scatter plot above, I would say at roughly a hour (60 minutes) would be the cutoff point for a departure delay that would not affect arrival time.
LS0tDQp0aXRsZTogIkxhYiBXZWVrIDI6IEludHJvIHRvIERhdGEiDQphdXRob3I6ICJJYW4gQ29zdGVsbG8iDQpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiDQpvdXRwdXQ6IG9wZW5pbnRybzo6bGFiX3JlcG9ydA0KLS0tDQoNCmBgYHtyIGxvYWQtcGFja2FnZXMsIG1lc3NhZ2U9RkFMU0V9DQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkob3BlbmludHJvKQ0KZGF0YShueWNmbGlnaHRzKQ0KYGBgDQoNCiMjIyBFeGVyY2lzZSAxOg0KDQoqTG9vayBjYXJlZnVsbHkgYXQgdGhlc2UgdGhyZWUgaGlzdG9ncmFtcy4gSG93IGRvIHRoZXkgY29tcGFyZT8gQXJlIGZlYXR1cmVzIHJldmVhbGVkIGluIG9uZSB0aGF0IGFyZSBvYnNjdXJlZCBpbiBhbm90aGVyPyoNCg0KSW4gdGhlIHRocmVlIGhpc3RvZ3JhbXMgdGhlIGJpbiBzaXplcywgdGhhdCBpcyB0aGUgbnVtYmVyIG9mIHJlY29yZHMgdGhhdCBhcmUgZ3JvdXBlZCB0b2dldGhlciwgZGlmZmVyLiBCZWNhdXNlIG9mIHRoZXNlIGRpZmZlcmVuY2VzIHRoZSBzY2FsZSBvZiB0aGUgdmVydGljYWwgeS1heGlzIGFsc28gY2hhbmdlLiANCg0KVGhlIHNtYWxsZXIgYmluIHNpemVzIGluIGhpc3RvZ3JhbXMgMSBhbmQgMiBhbGxvdyBmb3IgbW9yZSBkZXRhaWwgdG8gYmUgc2hvd24gdGhhdCBpcyBoaWRkZW4gaW4gdGhlIGxhcmdlciBiaW4gc2l6ZXMgaW4gaGlzdG9ncmFtIDMuIEluIHRoaXMgY2FzZXMgc2VlaW5nIHRoYXQgZGV0YWlsIGlzIGltcG9ydGFudCwgcGFydGljdWxhcmx5IGZvciBoaXN0b2dyYW0gMiB3aGVyZSB0aGVyZSBpcyBhIG51bWJlciBvZiByZWNvcmRzIHByZWNlZGluZyB0aGUgc3Bpa2UgdGhhdCBjb3VsZCBiZSBpbXBvcnRhbnQgaW5mb3JtYXRpb24sIG90aGVyd2lzZSBoaWRkZW4gaW4gaGlzdG9ncmFtcyAxIGFuZCAzLCB0byBiZXR0ZXIgaW50ZXJwcmV0IHRoZXNlIHJlc3VsdHMuIA0KDQoNCmBgYHtyIGZsaWdodHMgZGlzdH0NCg0KIyBIaXN0b2dyYW0gMQ0KZ2dwbG90KGRhdGEgPSBueWNmbGlnaHRzLCBhZXMoeCA9IGRlcF9kZWxheSkpICsNCiAgZ2VvbV9oaXN0b2dyYW0oKQ0KDQojIEhpc3RvZ3JhbSAyDQpnZ3Bsb3QoZGF0YSA9IG55Y2ZsaWdodHMsIGFlcyh4ID0gZGVwX2RlbGF5KSkgKw0KICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDE1KQ0KDQojSGlzdG9ncmFtIDMNCmdncGxvdChkYXRhID0gbnljZmxpZ2h0cywgYWVzKHggPSBkZXBfZGVsYXkpKSArDQogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMTUwKQ0KYGBgDQoNCiMjIyBFeGVyY2lzZSAyOg0KDQoqQ3JlYXRlIGEgbmV3IGRhdGEgZnJhbWUgdGhhdCBpbmNsdWRlcyBmbGlnaHRzIGhlYWRlZCB0byBTRk8gaW4gRmVicnVhcnksIGFuZCBzYXZlIHRoaXMgZGF0YSBmcmFtZSBhcyBzZm9fZmViX2ZsaWdodHMuIEhvdyBtYW55IGZsaWdodHMgbWVldCB0aGVzZSBjcml0ZXJpYT8qDQoNCmBgYHtyIGZlYiBmbGlnaHRzIGNyZWF0ZX0NCnNmb19mZWJfZmxpZ2h0cyA8LSBueWNmbGlnaHRzICU+JQ0KICBmaWx0ZXIoZGVzdCA9PSAiU0ZPIiwgbW9udGggPT0gMikNCg0Kc2ZvX2ZlYl9mbGlnaHRzICU+JQ0KICBzdW1tYXJpc2UobWVhbl9kZCAgID0gbWVhbihhcnJfZGVsYXkpLCANCiAgICAgIG1lZGlhbl9kZCAgICAgICA9IG1lZGlhbihhcnJfZGVsYXkpLCANCiAgICAgIG4gICAgICAgICAgICAgICA9IG4oKSkNCmBgYA0KVXNpbmcgdGhlICJzdW1tYXJpc2UiIGZ1bmN0aW9uLCB0aGVyZSBhcmUgNjggcmVjb3JkcyB3aXRoIGEgZGVzdGluYXRpb24gYXMgU0ZPIGluIHRoZSBtb250aCBvZiBGZWJydWFyeS4NCg0KIyMjIEV4ZXJjaXNlIDM6DQoNCipEZXNjcmliZSB0aGUgZGlzdHJpYnV0aW9uIG9mIHRoZSBhcnJpdmFsIGRlbGF5cyBvZiB0aGVzZSBmbGlnaHRzIHVzaW5nIGEgaGlzdG9ncmFtIGFuZCBhcHByb3ByaWF0ZSBzdW1tYXJ5IHN0YXRpc3RpY3MuIEhpbnQ6IFRoZSBzdW1tYXJ5IHN0YXRpc3RpY3MgeW91IHVzZSBzaG91bGQgZGVwZW5kIG9uIHRoZSBzaGFwZSBvZiB0aGUgZGlzdHJpYnV0aW9uLioNCg0KYGBge3IgZmViIHN1bSB2aXp9DQpnZ3Bsb3QoZGF0YSA9IHNmb19mZWJfZmxpZ2h0cywgYWVzKHggPSBhcnJfZGVsYXkpKSArDQogIGdlb21faGlzdG9ncmFtKCkNCg0KbGlicmFyeShwc3ljaCkNCmRlc2NyaWJlKHNmb19mZWJfZmxpZ2h0cyRhcnJfZGVsYXksIHNrZXcgPSBGQUxTRSkNCg0KYGBgDQoNClRoZSBkaXN0cmlidXRpb24gb2YgdGhlc2UgZGF0YSBmb3IgYXJyaXZhbCBkZWxheXMgYXBwZWFycyBzb21ld2hhdCBub3JtYWwuIFRoZXJlIGFyZSBhIG51bWJlciBvZiBvdXRsaWVycyBvZiBmbGlnaHRzIHdpdGggZXh0cmVtZSBkZWxheXMuIFNvIG11Y2ggc28gdGhhdCBpdCBwdWxscyB0aGUgbWVhbiBvZiB0aGUgc2V0ICgtNC41IG1pbnV0ZXMpIGF3YXkgZnJvbSB0aGUgbWVkaWFuICgtMTEgbWludXRlcykuIA0KDQojIyMgRXhlcmNpc2UgNDoNCg0KKkNhbGN1bGF0ZSB0aGUgbWVkaWFuIGFuZCBpbnRlcnF1YXJ0aWxlIHJhbmdlIGZvciBhcnJfZGVsYXlzIG9mIGZsaWdodHMgaW4gaW4gdGhlIHNmb19mZWJfZmxpZ2h0cyBkYXRhIGZyYW1lLCBncm91cGVkIGJ5IGNhcnJpZXIuIFdoaWNoIGNhcnJpZXIgaGFzIHRoZSBtb3N0IHZhcmlhYmxlIGFycml2YWwgZGVsYXlzPyogDQpgYGB7ciBmZWIgY2FycmllciBzdW1tYXJ5fQ0Kc2ZvX2ZlYl9mbGlnaHRzICU+JQ0KICBncm91cF9ieShjYXJyaWVyKSAlPiUNCiAgc3VtbWFyaXNlKG1lZGlhbl9kZCA9IG1lZGlhbihhcnJfZGVsYXkpLCBpcXJfZGQgPSBJUVIoYXJyX2RlbGF5KSwgbl9mbGlnaHRzID0gbigpKSAlPiUNCiAgYXJyYW5nZShkZXNjKGlxcl9kZCkpDQpgYGANCg0KQmFzZWQgb24gdGhlIHRhYmxlIGFib3ZlICB0aGUgY2FycmllcnMgZnJvbSB0aGVzZSBkYXRhIHRoYXQgaGF2ZSB0aGUgaGlnaGVzdCB2YXJpYWJpbGl0eSBhcmUgVW5pdGVkIEFpcmxpbmVzIGFuZCBEZWx0YS4gKEFzIHNvbWVvbmUgd2hvIHdvdWxkIG5vcm1hbGx5IHRyYXZlbCBxdWl0ZSBhIGJpdCBmb3Igd29yayBhbmQgd2hvIHVzZXMgVUEgYXMgbXkgY2FycmllciwgSSBjYW4gYXR0ZXN0IHRvIHRoaXMgdmFyaWFuY2UhKQ0KDQojIyMgRXhlcmNpc2UgNToNCg0KKlN1cHBvc2UgeW91IHJlYWxseSBkaXNsaWtlIGRlcGFydHVyZSBkZWxheXMgYW5kIHlvdSB3YW50IHRvIHNjaGVkdWxlIHlvdXIgdHJhdmVsIGluIGEgbW9udGggdGhhdCBtaW5pbWl6ZXMgeW91ciBwb3RlbnRpYWwgZGVwYXJ0dXJlIGRlbGF5IGxlYXZpbmcgTllDLiBPbmUgb3B0aW9uIGlzIHRvIGNob29zZSB0aGUgbW9udGggd2l0aCB0aGUgbG93ZXN0IG1lYW4gZGVwYXJ0dXJlIGRlbGF5LiBBbm90aGVyIG9wdGlvbiBpcyB0byBjaG9vc2UgdGhlIG1vbnRoIHdpdGggdGhlIGxvd2VzdCBtZWRpYW4gZGVwYXJ0dXJlIGRlbGF5LiBXaGF0IGFyZSB0aGUgcHJvcyBhbmQgY29ucyBvZiB0aGVzZSB0d28gY2hvaWNlcz8qDQoNCmBgYHtyIG55YyBtb250aCBkZWxheXN9DQpueWNmbGlnaHRzICU+JQ0KICBncm91cF9ieShtb250aCkgJT4lDQogIHN1bW1hcmlzZShtZWFuX2RkID0gbWVhbihkZXBfZGVsYXkpKSAlPiUNCiAgYXJyYW5nZShtZWFuX2RkKQ0KDQpueWNmbGlnaHRzICU+JQ0KICBncm91cF9ieShtb250aCkgJT4lDQogIHN1bW1hcmlzZShtZWRpYW5fZGQgPSBtZWRpYW4oZGVwX2RlbGF5KSkgJT4lDQogIGFycmFuZ2UobWVkaWFuX2RkKQ0KYGBgDQoNCkFycmFuZ2luZyB0aGVzZSBkYXRhIGJ5IG1vbnRoIGFuZCBieSBtZWFuIGFuZCBtZWRpYW4gdGhlIG91dGNvbWUgaXMgdGhhdCBPY3RvYmVyIGhhcyB0aGUgbG93ZXN0IG1lYW4gKDUuOSBtaW51dGVzKSwgd2hpbGUgU2VwdGVtYmVyIGhhcyB0aGUgbG93ZXN0IG1lZGlhbiAoLTMgbWludXRlcykuIFVzaW5nIHRoZSBtZWFuIHRvIG1ha2UgYSBkZXRlcm1pbmF0aW9uIG9uIHdoZW4gdG8gZmx5IHdpbGwgYmUgaW5mbHVlbmNlZCBtb3JlIGJ5IG91dGxpZXJzIGluIHRoZSBkYXRhIHNldC4gQXMgd2UndmUgc2VlbiBwcmV2aW91c2x5LCB0aGVyZSBhcmUgYSBzb21lIHJlYWxseSBsYXJnZSBkZWxheXMsIGJ1dCBhbHNvIHNvbWUgcmVhbGx5IGVhcmx5IGRlcGFydHVyZXMuIFVzaW5nIHRoZSBtZWRpYW4sIGJ5IGNvbnRyYXN0LCBzaG93cyB0aGF0IDUwJSBvZiB0aGUgZmxpZ2h0cyBhcmUgYmVsb3cgYSBjZXJ0YWluIHBvaW50LCBpbiB0aGUgY2FzZSBvZiBTZXB0ZW1iZXIgYW4gYXJyaXZhbCBkZWxheSBvZiAtMyBtaW51dGVzLiBPbmUgaGFzIGEgNTAlIGNoYW5jZSBvZiBiZWluZyBhdCBvciBiZWxvdyAtMyBtaW51dGVzLiBBaXJsaW5lcyBhcmUgbm90IHByb25lIHRvIGxlYXZpbmcgZXh0cmFvcmRpbmFyaWx5IGVhcmx5LCBzbyB1c2luZyBtZWRpYW4sIHBhcnRpY3VsYXJseSB3aXRoIGEgbnVtYmVyIGFyb3VuZCB6ZXJvIG1pbnV0ZXMgZGVsYXllZCwgd291bGQgc2VlbSB0byBtYWtlIGEgbG90IG9mIHNlbnNlIGFzIGl0IHNob3dzIG1vcmUgY29uc2lzdGVuY3kuDQoNCiMjIyBFeGVyY2lzZSA2Og0KDQoqSWYgeW91IHdlcmUgc2VsZWN0aW5nIGFuIGFpcnBvcnQgc2ltcGx5IGJhc2VkIG9uIG9uIHRpbWUgZGVwYXJ0dXJlIHBlcmNlbnRhZ2UsIHdoaWNoIE5ZQyBhaXJwb3J0IHdvdWxkIHlvdSBjaG9vc2UgdG8gZmx5IG91dCBvZj8qDQoNCmBgYHtyIG55YyBvcmdpbiBzdWJzZXR9DQpueWNPcmlnaW4gPC0gbnljZmxpZ2h0cyAlPiUNCiAgZmlsdGVyKG9yaWdpbiA9PSAiRVdSIiB8IG9yaWdpbiA9PSAiSkZLIiB8IG9yaWdpbiA9PSAiTEdBIikNCg0KbnljT3JpZ2luJG9uVGltZUZhYyA8LSBpZmVsc2UobnljT3JpZ2luJGRlcF9kZWxheSA8PSAwLCAiT24gVGltZSIsICJMYXRlIikNCg0KcHJvcC50YWJsZSh0YWJsZShueWNPcmlnaW4kb3JpZ2luLCBueWNPcmlnaW4kb25UaW1lRmFjKSkqMTAwDQoNCmBgYA0KQ3JlYXRpbmcgYSBuZXcgc3Vic2V0IG9mIHRoZSBkYXRhIHRvIGxpbWl0IHRoZSB2aWV3IHRvIE5ZQyBhcmVhIGFpcnBvcnQsIEkgYWxzbyBjcmVhdGVkIGEgbmV3IGNvbHVtbiBmb3Igb24gdGltZSBhbmQgbGF0ZSBmbGlnaHRzLCBhbnkgZmxpZ2h0IGF0IG9yIGJlbG93IHplcm8gbWludXRlcyBkZWxheWVkIGFyZSBsYWJlbGVkICJPbiBUaW1lIiwgZWxzZSB0aGV5IGFyZSAiTGF0ZS4iDQoNCkNyZWF0aW5nIGEgcHJvcG9ydGlvbmFsIHRhYmxlIGJ5IHRoYXQgbmV3IGNvbHVtbiBhbmQgb3JpZ2luIGJyb2tlIG91dCB0aGUgb24gdGltZSBhbmQgbGF0ZSBmbGlnaHRzLiBBbiBlcnJvciBJIGNhbm5vdCBzZWVtIHRvIHNoYWtlIGlzIHRoYXQgdGhlIHJvd3MgZG8gbm90IGFkZCB1cCB0byAxMDAlLiBJIHRyaWVkIGEgbnVtYmVyIG9mIGRpZmZlcmVudCBjaGVja3MsIGJ1dCBpdCBzdGlsbCBwZXJzaXN0cy4gDQoNCkJhc2VkIG9uIHRoZXNlIGRhdGEsIEpGSyBqdXN0IHNsaWdodGx5IGVkZ2VzIG91dCBMR0EgZm9yIG1vcmUgZGVwYXJ0dXJlcyBvbiB0aW1lLiANCg0KIyMjIEV4ZXJjaXNlIDc6DQoNCipNdXRhdGUgdGhlIGRhdGEgZnJhbWUgc28gdGhhdCBpdCBpbmNsdWRlcyBhIG5ldyB2YXJpYWJsZSB0aGF0IGNvbnRhaW5zIHRoZSBhdmVyYWdlIHNwZWVkLCBhdmdfc3BlZWQgdHJhdmVsZWQgYnkgdGhlIHBsYW5lIGZvciBlYWNoIGZsaWdodCAoaW4gbXBoKS4gSGludDogQXZlcmFnZSBzcGVlZCBjYW4gYmUgY2FsY3VsYXRlZCBhcyBkaXN0YW5jZSBkaXZpZGVkIGJ5IG51bWJlciBvZiBob3VycyBvZiB0cmF2ZWwsIGFuZCBub3RlIHRoYXQgYWlyX3RpbWUgaXMgZ2l2ZW4gaW4gbWludXRlcy4qDQoNCmBgYHtyfQ0KbnljZmxpZ2h0cyA8LSBueWNmbGlnaHRzICU+JQ0KICBtdXRhdGUoYXZnX3NwZWVkID0gZGlzdGFuY2UgLyBhaXJfdGltZSkNCmBgYA0KDQoNCiMjIyBFeGVyY2lzZSA4Og0KDQoqTWFrZSBhIHNjYXR0ZXJwbG90IG9mIGF2Z19zcGVlZCB2cy4gZGlzdGFuY2UuIERlc2NyaWJlIHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBhdmVyYWdlIHNwZWVkIGFuZCBkaXN0YW5jZS4gSGludDogVXNlIGdlb21fcG9pbnQoKS4qDQoNCmBgYHtyfQ0KZ2dwbG90KG55Y2ZsaWdodHMsIGFlcyh4PWRpc3RhbmNlLCB5PWF2Z19zcGVlZCkpICsNCiAgZ2VvbV9wb2ludCgpDQpgYGANCg0KIyMjIEV4ZXJjaXNlIDk6DQoNCipSZXBsaWNhdGUgdGhlIGZvbGxvd2luZyBwbG90LiBIaW50OiBUaGUgZGF0YSBmcmFtZSBwbG90dGVkIG9ubHkgY29udGFpbnMgZmxpZ2h0cyBmcm9tIEFtZXJpY2FuIEFpcmxpbmVzLCBEZWx0YSBBaXJsaW5lcywgYW5kIFVuaXRlZCBBaXJsaW5lcywgYW5kIHRoZSBwb2ludHMgYXJlIGNvbG9yZWQgYnkgY2Fycmllci4gT25jZSB5b3UgcmVwbGljYXRlIHRoZSBwbG90LCBkZXRlcm1pbmUgKHJvdWdobHkpIHdoYXQgdGhlIGN1dG9mZiBwb2ludCBpcyBmb3IgZGVwYXJ0dXJlIGRlbGF5cyB3aGVyZSB5b3UgY2FuIHN0aWxsIGV4cGVjdCB0byBnZXQgdG8geW91ciBkZXN0aW5hdGlvbiBvbiB0aW1lLioNCg0KYGBge3J9DQpFeDkgPC0gbnljZmxpZ2h0cyAlPiUNCiAgZmlsdGVyKGNhcnJpZXIgPT0gIkFBIiB8IGNhcnJpZXIgPT0gIkRMIiB8IGNhcnJpZXIgPT0gIlVBIikNCg0KZ2dwbG90KEV4OSwgYWVzKHg9ZGVwX2RlbGF5LCB5PWFycl9kZWxheSwgY29sb3I9Y2FycmllcikpICsNCiAgZ2VvbV9wb2ludCgpDQpgYGANCg0KRnJvbSB0aGUgc2NhdHRlciBwbG90IGFib3ZlLCBJIHdvdWxkIHNheSBhdCByb3VnaGx5IGEgaG91ciAoNjAgbWludXRlcykgd291bGQgYmUgdGhlIGN1dG9mZiBwb2ludCBmb3IgYSBkZXBhcnR1cmUgZGVsYXkgdGhhdCB3b3VsZCBub3QgYWZmZWN0IGFycml2YWwgdGltZS4gIA==