suppressPackageStartupMessages(library("tidyverse"))
package 㤼㸱tidyverse㤼㸲 was built under R version 3.6.3
suppressPackageStartupMessages(library("nycflights13"))
package 㤼㸱nycflights13㤼㸲 was built under R version 3.6.3
suppressPackageStartupMessages(library("viridis"))
package 㤼㸱viridis㤼㸲 was built under R version 3.6.2
flights2 <- flights %>%
  select(year:day, hour, origin, dest, tailnum, carrier)

1. Compute the average delay by destination, then join on the airports data frame so you can show the spatial distribution of delays. Here’s an easy way to draw a map of the United States:

airports %>%
  semi_join(flights, c("faa" = "dest")) %>%
  ggplot(aes(lon, lat)) +
  borders("state") +
  geom_point() +
  coord_quickmap()

(Don’t worry if you don’t understand what semi_join() does — you’ll learn about it next.)

You might want to use the size or color of the points to display the average delay for each airport.

avg_dest_delays <-
  flights %>%
  group_by(dest) %>%
  # arrival delay NA's are cancelled flights
  summarise(delay = mean(arr_delay, na.rm = TRUE)) %>%
  inner_join(airports, by = c(dest = "faa"))
avg_dest_delays %>%
  ggplot(aes(lon, lat, colour = delay)) +
  borders("state") +
  geom_point() +
  coord_quickmap()

2. Add the location of the origin and destination (i.e. the lat and lon) to flights.

You can perform one join after another. If duplicate variables are found, by default, dplyr will distinguish the two by adding .x, and .y to the ends of the variable names to solve naming conflicts.

airport_locations <- airports %>%
  select(faa, lat, lon)

flights %>%
  select(year:day, hour, origin, dest) %>%
  left_join(
    airport_locations,
    by = c("origin" = "faa")
  ) %>%
  left_join(
    airport_locations,
    by = c("dest" = "faa")
  )

The suffix argument overrides this default behavior. Since is always good practice to have clear variable names, I will use the suffixes "_dest" and "_origin" to specify whether the column refers to the destination or origin airport.

airport_locations <- airports %>%
  select(faa, lat, lon)

flights %>%
  select(year:day, hour, origin, dest) %>%
  left_join(
    airport_locations,
    by = c("origin" = "faa")
  ) %>%
  left_join(
    airport_locations,
    by = c("dest" = "faa"),
    suffix = c("_origin", "_dest")
    # existing lat and lon variables in tibble gain the _origin suffix
    # new lat and lon variables are given _dest suffix
  )

3. Is there a relationship between the age of a plane and its delays?

The question does not specify whether the relationship is with departure delay or arrival delay. I will look at both.

To compare the age of the plane to flights delay, I merge flights with the planes, which contains a variable plane_year, with the year in which the plane was built. To look at the relationship between plane age and departure delay, I will calculate the average arrival and departure delay for each age of a flight. Since there are few planes older than 25 years, so I truncate age at 25 years.

plane_cohorts <- inner_join(flights,
  select(planes, tailnum, plane_year = year),
  by = "tailnum"
) %>%
  mutate(age = year - plane_year) %>%
  filter(!is.na(age)) %>%
  mutate(age = if_else(age > 25, 25L, age)) %>%
  group_by(age) %>%
  summarise(
    dep_delay_mean = mean(dep_delay, na.rm = TRUE),
    dep_delay_sd = sd(dep_delay, na.rm = TRUE),
    arr_delay_mean = mean(arr_delay, na.rm = TRUE),
    arr_delay_sd = sd(arr_delay, na.rm = TRUE),
    n_arr_delay = sum(!is.na(arr_delay)),
    n_dep_delay = sum(!is.na(dep_delay))
  )

I will look for a relationship between departure delay and age by plotting age against the average departure delay. The average departure delay is increasing for planes with ages up until 10 years. After that the departure delay decreases or levels off. The decrease in departure delay could be because older planes with many mechanical issues are removed from service or because air lines schedule these planes with enough time so that mechanical issues do not delay them.

ggplot(plane_cohorts, aes(x = age, y = dep_delay_mean)) +
  geom_point() +
  scale_x_continuous("Age of plane (years)", breaks = seq(0, 30, by = 10)) +
  scale_y_continuous("Mean Departure Delay (minutes)")

There is a similar relationship in arrival delays. Delays increase with the age of the plane until ten years, then it declines and flattens out.

ggplot(plane_cohorts, aes(x = age, y = arr_delay_mean)) +
  geom_point() +
  scale_x_continuous("Age of Plane (years)", breaks = seq(0, 30, by = 10)) +
  scale_y_continuous("Mean Arrival Delay (minutes)")

4. What weather conditions make it more likely to see a delay?

Almost any amount of precipitation is associated with a delay. However, there is not a strong a trend above 0.02 in. of precipitation.

flight_weather <-
  flights %>%
  inner_join(weather, by = c(
    "origin" = "origin",
    "year" = "year",
    "month" = "month",
    "day" = "day",
    "hour" = "hour"
  ))

flight_weather %>%
  group_by(precip) %>%
  summarise(delay = mean(dep_delay, na.rm = TRUE)) %>%
  ggplot(aes(x = precip, y = delay)) +
  geom_line() + geom_point()

5 What happened on June 13, 2013? Display the spatial pattern of delays, and then use Google to cross-reference with the weather.

There was a large series of storms (derechos) in the southeastern US (see June 12-13, 2013 derecho series). The following plot show that the largest delays were in Tennessee (Nashville), the Southeast, and the Midwest, which were the locations of the derechos.

flights %>%
  filter(year == 2013, month == 6, day == 13) %>%
  group_by(dest) %>%
  summarise(delay = mean(arr_delay, na.rm = TRUE)) %>%
  inner_join(airports, by = c("dest" = "faa")) %>%
  ggplot(aes(y = lat, x = lon, size = delay, colour = delay)) +
  borders("state") +
  geom_point() +
  coord_quickmap() +
  scale_colour_viridis()

LS0tDQp0aXRsZTogIk11dGF0aW5nIGpvaW5zIg0Kb3V0cHV0OiANCiAgaHRtbF9ub3RlYm9vazoNCiAgICB0b2M6IHRydWUNCiAgICB0b2NfZmxvYXQ6IHRydWUNCi0tLQ0KDQpgYGB7cn0NCnN1cHByZXNzUGFja2FnZVN0YXJ0dXBNZXNzYWdlcyhsaWJyYXJ5KCJ0aWR5dmVyc2UiKSkNCnN1cHByZXNzUGFja2FnZVN0YXJ0dXBNZXNzYWdlcyhsaWJyYXJ5KCJueWNmbGlnaHRzMTMiKSkNCnN1cHByZXNzUGFja2FnZVN0YXJ0dXBNZXNzYWdlcyhsaWJyYXJ5KCJ2aXJpZGlzIikpDQpgYGANCg0KYGBge3J9DQpmbGlnaHRzMiA8LSBmbGlnaHRzICU+JQ0KICBzZWxlY3QoeWVhcjpkYXksIGhvdXIsIG9yaWdpbiwgZGVzdCwgdGFpbG51bSwgY2FycmllcikNCmBgYA0KDQojIyMgMS4gQ29tcHV0ZSB0aGUgYXZlcmFnZSBkZWxheSBieSBkZXN0aW5hdGlvbiwgdGhlbiBqb2luIG9uIHRoZSBgYWlycG9ydHNgIGRhdGEgZnJhbWUgc28geW91IGNhbiBzaG93IHRoZSBzcGF0aWFsIGRpc3RyaWJ1dGlvbiBvZiBkZWxheXMuIEhlcmXigJlzIGFuIGVhc3kgd2F5IHRvIGRyYXcgYSBtYXAgb2YgdGhlIFVuaXRlZCBTdGF0ZXM6DQoNCmBgYHtyfQ0KYWlycG9ydHMgJT4lDQogIHNlbWlfam9pbihmbGlnaHRzLCBjKCJmYWEiID0gImRlc3QiKSkgJT4lDQogIGdncGxvdChhZXMobG9uLCBsYXQpKSArDQogIGJvcmRlcnMoInN0YXRlIikgKw0KICBnZW9tX3BvaW50KCkgKw0KICBjb29yZF9xdWlja21hcCgpDQpgYGANCg0KKERvbuKAmXQgd29ycnkgaWYgeW91IGRvbuKAmXQgdW5kZXJzdGFuZCB3aGF0IGBzZW1pX2pvaW4oKWAgZG9lcyDigJQgeW914oCZbGwgbGVhcm4gYWJvdXQgaXQgbmV4dC4pDQoNCllvdSBtaWdodCB3YW50IHRvIHVzZSB0aGUgc2l6ZSBvciBjb2xvciBvZiB0aGUgcG9pbnRzIHRvIGRpc3BsYXkgdGhlIGF2ZXJhZ2UgZGVsYXkgZm9yIGVhY2ggYWlycG9ydC4NCg0KYGBge3J9DQphdmdfZGVzdF9kZWxheXMgPC0NCiAgZmxpZ2h0cyAlPiUNCiAgZ3JvdXBfYnkoZGVzdCkgJT4lDQogICMgYXJyaXZhbCBkZWxheSBOQSdzIGFyZSBjYW5jZWxsZWQgZmxpZ2h0cw0KICBzdW1tYXJpc2UoZGVsYXkgPSBtZWFuKGFycl9kZWxheSwgbmEucm0gPSBUUlVFKSkgJT4lDQogIGlubmVyX2pvaW4oYWlycG9ydHMsIGJ5ID0gYyhkZXN0ID0gImZhYSIpKQ0KYXZnX2Rlc3RfZGVsYXlzICU+JQ0KICBnZ3Bsb3QoYWVzKGxvbiwgbGF0LCBjb2xvdXIgPSBkZWxheSkpICsNCiAgYm9yZGVycygic3RhdGUiKSArDQogIGdlb21fcG9pbnQoKSArDQogIGNvb3JkX3F1aWNrbWFwKCkNCmBgYA0KDQojIyMgMi4gQWRkIHRoZSBsb2NhdGlvbiBvZiB0aGUgb3JpZ2luIGFuZCBkZXN0aW5hdGlvbiAoaS5lLiB0aGUgYGxhdGAgYW5kIGBsb25gKSB0byBgZmxpZ2h0c2AuDQoNCllvdSBjYW4gcGVyZm9ybSBvbmUgam9pbiBhZnRlciBhbm90aGVyLiBJZiBkdXBsaWNhdGUgdmFyaWFibGVzIGFyZSBmb3VuZCwgYnkgZGVmYXVsdCwgZHBseXIgd2lsbCBkaXN0aW5ndWlzaCB0aGUgdHdvIGJ5IGFkZGluZyBgLnhgLCBhbmQgYC55YCB0byB0aGUgZW5kcyBvZiB0aGUgdmFyaWFibGUgbmFtZXMgdG8gc29sdmUgbmFtaW5nIGNvbmZsaWN0cy4NCg0KYGBge3J9DQphaXJwb3J0X2xvY2F0aW9ucyA8LSBhaXJwb3J0cyAlPiUNCiAgc2VsZWN0KGZhYSwgbGF0LCBsb24pDQoNCmZsaWdodHMgJT4lDQogIHNlbGVjdCh5ZWFyOmRheSwgaG91ciwgb3JpZ2luLCBkZXN0KSAlPiUNCiAgbGVmdF9qb2luKA0KICAgIGFpcnBvcnRfbG9jYXRpb25zLA0KICAgIGJ5ID0gYygib3JpZ2luIiA9ICJmYWEiKQ0KICApICU+JQ0KICBsZWZ0X2pvaW4oDQogICAgYWlycG9ydF9sb2NhdGlvbnMsDQogICAgYnkgPSBjKCJkZXN0IiA9ICJmYWEiKQ0KICApDQpgYGANCg0KVGhlIGBzdWZmaXhgIGFyZ3VtZW50IG92ZXJyaWRlcyB0aGlzIGRlZmF1bHQgYmVoYXZpb3IuIFNpbmNlIGlzIGFsd2F5cyBnb29kIHByYWN0aWNlIHRvIGhhdmUgY2xlYXIgdmFyaWFibGUgbmFtZXMsIEkgd2lsbCB1c2UgdGhlIHN1ZmZpeGVzIGAiX2Rlc3QiYCBhbmQgYCJfb3JpZ2luImAgdG8gc3BlY2lmeSB3aGV0aGVyIHRoZSBjb2x1bW4gcmVmZXJzIHRvIHRoZSBkZXN0aW5hdGlvbiBvciBvcmlnaW4gYWlycG9ydC4NCg0KYGBge3J9DQphaXJwb3J0X2xvY2F0aW9ucyA8LSBhaXJwb3J0cyAlPiUNCiAgc2VsZWN0KGZhYSwgbGF0LCBsb24pDQoNCmZsaWdodHMgJT4lDQogIHNlbGVjdCh5ZWFyOmRheSwgaG91ciwgb3JpZ2luLCBkZXN0KSAlPiUNCiAgbGVmdF9qb2luKA0KICAgIGFpcnBvcnRfbG9jYXRpb25zLA0KICAgIGJ5ID0gYygib3JpZ2luIiA9ICJmYWEiKQ0KICApICU+JQ0KICBsZWZ0X2pvaW4oDQogICAgYWlycG9ydF9sb2NhdGlvbnMsDQogICAgYnkgPSBjKCJkZXN0IiA9ICJmYWEiKSwNCiAgICBzdWZmaXggPSBjKCJfb3JpZ2luIiwgIl9kZXN0IikNCiAgICAjIGV4aXN0aW5nIGxhdCBhbmQgbG9uIHZhcmlhYmxlcyBpbiB0aWJibGUgZ2FpbiB0aGUgX29yaWdpbiBzdWZmaXgNCiAgICAjIG5ldyBsYXQgYW5kIGxvbiB2YXJpYWJsZXMgYXJlIGdpdmVuIF9kZXN0IHN1ZmZpeA0KICApDQpgYGANCg0KIyMjIDMuIElzIHRoZXJlIGEgcmVsYXRpb25zaGlwIGJldHdlZW4gdGhlIGFnZSBvZiBhIHBsYW5lIGFuZCBpdHMgZGVsYXlzPw0KDQpUaGUgcXVlc3Rpb24gZG9lcyBub3Qgc3BlY2lmeSB3aGV0aGVyIHRoZSByZWxhdGlvbnNoaXAgaXMgd2l0aCBkZXBhcnR1cmUgZGVsYXkgb3IgYXJyaXZhbCBkZWxheS4gSSB3aWxsIGxvb2sgYXQgYm90aC4NCg0KVG8gY29tcGFyZSB0aGUgYWdlIG9mIHRoZSBwbGFuZSB0byBmbGlnaHRzIGRlbGF5LCBJIG1lcmdlIGBmbGlnaHRzYCB3aXRoIHRoZSBgcGxhbmVzYCwgd2hpY2ggY29udGFpbnMgYSB2YXJpYWJsZSBgcGxhbmVfeWVhcmAsIHdpdGggdGhlIGB5ZWFyYCBpbiB3aGljaCB0aGUgcGxhbmUgd2FzIGJ1aWx0LiBUbyBsb29rIGF0IHRoZSByZWxhdGlvbnNoaXAgYmV0d2VlbiBwbGFuZSBhZ2UgYW5kIGRlcGFydHVyZSBkZWxheSwgSSB3aWxsIGNhbGN1bGF0ZSB0aGUgYXZlcmFnZSBhcnJpdmFsIGFuZCBkZXBhcnR1cmUgZGVsYXkgZm9yIGVhY2ggYWdlIG9mIGEgZmxpZ2h0LiBTaW5jZSB0aGVyZSBhcmUgZmV3IHBsYW5lcyBvbGRlciB0aGFuIDI1IHllYXJzLCBzbyBJIHRydW5jYXRlIGBhZ2VgIGF0IDI1IHllYXJzLg0KDQpgYGB7cn0NCnBsYW5lX2NvaG9ydHMgPC0gaW5uZXJfam9pbihmbGlnaHRzLA0KICBzZWxlY3QocGxhbmVzLCB0YWlsbnVtLCBwbGFuZV95ZWFyID0geWVhciksDQogIGJ5ID0gInRhaWxudW0iDQopICU+JQ0KICBtdXRhdGUoYWdlID0geWVhciAtIHBsYW5lX3llYXIpICU+JQ0KICBmaWx0ZXIoIWlzLm5hKGFnZSkpICU+JQ0KICBtdXRhdGUoYWdlID0gaWZfZWxzZShhZ2UgPiAyNSwgMjVMLCBhZ2UpKSAlPiUNCiAgZ3JvdXBfYnkoYWdlKSAlPiUNCiAgc3VtbWFyaXNlKA0KICAgIGRlcF9kZWxheV9tZWFuID0gbWVhbihkZXBfZGVsYXksIG5hLnJtID0gVFJVRSksDQogICAgZGVwX2RlbGF5X3NkID0gc2QoZGVwX2RlbGF5LCBuYS5ybSA9IFRSVUUpLA0KICAgIGFycl9kZWxheV9tZWFuID0gbWVhbihhcnJfZGVsYXksIG5hLnJtID0gVFJVRSksDQogICAgYXJyX2RlbGF5X3NkID0gc2QoYXJyX2RlbGF5LCBuYS5ybSA9IFRSVUUpLA0KICAgIG5fYXJyX2RlbGF5ID0gc3VtKCFpcy5uYShhcnJfZGVsYXkpKSwNCiAgICBuX2RlcF9kZWxheSA9IHN1bSghaXMubmEoZGVwX2RlbGF5KSkNCiAgKQ0KYGBgDQoNCkkgd2lsbCBsb29rIGZvciBhIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIGRlcGFydHVyZSBkZWxheSBhbmQgYWdlIGJ5IHBsb3R0aW5nIGFnZSBhZ2FpbnN0IHRoZSBhdmVyYWdlIGRlcGFydHVyZSBkZWxheS4gVGhlIGF2ZXJhZ2UgZGVwYXJ0dXJlIGRlbGF5IGlzIGluY3JlYXNpbmcgZm9yIHBsYW5lcyB3aXRoIGFnZXMgdXAgdW50aWwgMTAgeWVhcnMuIEFmdGVyIHRoYXQgdGhlIGRlcGFydHVyZSBkZWxheSBkZWNyZWFzZXMgb3IgbGV2ZWxzIG9mZi4gVGhlIGRlY3JlYXNlIGluIGRlcGFydHVyZSBkZWxheSBjb3VsZCBiZSBiZWNhdXNlIG9sZGVyIHBsYW5lcyB3aXRoIG1hbnkgbWVjaGFuaWNhbCBpc3N1ZXMgYXJlIHJlbW92ZWQgZnJvbSBzZXJ2aWNlIG9yIGJlY2F1c2UgYWlyIGxpbmVzIHNjaGVkdWxlIHRoZXNlIHBsYW5lcyB3aXRoIGVub3VnaCB0aW1lIHNvIHRoYXQgbWVjaGFuaWNhbCBpc3N1ZXMgZG8gbm90IGRlbGF5IHRoZW0uDQoNCmBgYHtyfQ0KZ2dwbG90KHBsYW5lX2NvaG9ydHMsIGFlcyh4ID0gYWdlLCB5ID0gZGVwX2RlbGF5X21lYW4pKSArDQogIGdlb21fcG9pbnQoKSArDQogIHNjYWxlX3hfY29udGludW91cygiQWdlIG9mIHBsYW5lICh5ZWFycykiLCBicmVha3MgPSBzZXEoMCwgMzAsIGJ5ID0gMTApKSArDQogIHNjYWxlX3lfY29udGludW91cygiTWVhbiBEZXBhcnR1cmUgRGVsYXkgKG1pbnV0ZXMpIikNCmBgYA0KDQpUaGVyZSBpcyBhIHNpbWlsYXIgcmVsYXRpb25zaGlwIGluIGFycml2YWwgZGVsYXlzLiBEZWxheXMgaW5jcmVhc2Ugd2l0aCB0aGUgYWdlIG9mIHRoZSBwbGFuZSB1bnRpbCB0ZW4geWVhcnMsIHRoZW4gaXQgZGVjbGluZXMgYW5kIGZsYXR0ZW5zIG91dC4NCg0KYGBge3J9DQpnZ3Bsb3QocGxhbmVfY29ob3J0cywgYWVzKHggPSBhZ2UsIHkgPSBhcnJfZGVsYXlfbWVhbikpICsNCiAgZ2VvbV9wb2ludCgpICsNCiAgc2NhbGVfeF9jb250aW51b3VzKCJBZ2Ugb2YgUGxhbmUgKHllYXJzKSIsIGJyZWFrcyA9IHNlcSgwLCAzMCwgYnkgPSAxMCkpICsNCiAgc2NhbGVfeV9jb250aW51b3VzKCJNZWFuIEFycml2YWwgRGVsYXkgKG1pbnV0ZXMpIikNCmBgYA0KDQojIyMgNC4gV2hhdCB3ZWF0aGVyIGNvbmRpdGlvbnMgbWFrZSBpdCBtb3JlIGxpa2VseSB0byBzZWUgYSBkZWxheT8NCg0KQWxtb3N0IGFueSBhbW91bnQgb2YgcHJlY2lwaXRhdGlvbiBpcyBhc3NvY2lhdGVkIHdpdGggYSBkZWxheS4gSG93ZXZlciwgdGhlcmUgaXMgbm90IGEgc3Ryb25nIGEgdHJlbmQgYWJvdmUgMC4wMiBpbi4gb2YgcHJlY2lwaXRhdGlvbi4NCg0KYGBge3J9DQpmbGlnaHRfd2VhdGhlciA8LQ0KICBmbGlnaHRzICU+JQ0KICBpbm5lcl9qb2luKHdlYXRoZXIsIGJ5ID0gYygNCiAgICAib3JpZ2luIiA9ICJvcmlnaW4iLA0KICAgICJ5ZWFyIiA9ICJ5ZWFyIiwNCiAgICAibW9udGgiID0gIm1vbnRoIiwNCiAgICAiZGF5IiA9ICJkYXkiLA0KICAgICJob3VyIiA9ICJob3VyIg0KICApKQ0KDQpmbGlnaHRfd2VhdGhlciAlPiUNCiAgZ3JvdXBfYnkocHJlY2lwKSAlPiUNCiAgc3VtbWFyaXNlKGRlbGF5ID0gbWVhbihkZXBfZGVsYXksIG5hLnJtID0gVFJVRSkpICU+JQ0KICBnZ3Bsb3QoYWVzKHggPSBwcmVjaXAsIHkgPSBkZWxheSkpICsNCiAgZ2VvbV9saW5lKCkgKyBnZW9tX3BvaW50KCkNCmBgYA0KDQojIyMgNSBXaGF0IGhhcHBlbmVkIG9uIEp1bmUgMTMsIDIwMTM/IERpc3BsYXkgdGhlIHNwYXRpYWwgcGF0dGVybiBvZiBkZWxheXMsIGFuZCB0aGVuIHVzZSBHb29nbGUgdG8gY3Jvc3MtcmVmZXJlbmNlIHdpdGggdGhlIHdlYXRoZXIuDQoNClRoZXJlIHdhcyBhIGxhcmdlIHNlcmllcyBvZiBzdG9ybXMgKGRlcmVjaG9zKSBpbiB0aGUgc291dGhlYXN0ZXJuIFVTIChzZWUgW0p1bmUgMTItMTMsIDIwMTMgZGVyZWNobyBzZXJpZXNdKGh0dHBzOi8vZW4ud2lraXBlZGlhLm9yZy93aWtpL0p1bmVfMTIlRTIlODAlOTMxMyxfMjAxM19kZXJlY2hvX3NlcmllcykpLiBUaGUgZm9sbG93aW5nIHBsb3Qgc2hvdyB0aGF0IHRoZSBsYXJnZXN0IGRlbGF5cyB3ZXJlIGluIFRlbm5lc3NlZSAoTmFzaHZpbGxlKSwgdGhlIFNvdXRoZWFzdCwgYW5kIHRoZSBNaWR3ZXN0LCB3aGljaCB3ZXJlIHRoZSBsb2NhdGlvbnMgb2YgdGhlIGRlcmVjaG9zLg0KDQpgYGB7cn0NCmZsaWdodHMgJT4lDQogIGZpbHRlcih5ZWFyID09IDIwMTMsIG1vbnRoID09IDYsIGRheSA9PSAxMykgJT4lDQogIGdyb3VwX2J5KGRlc3QpICU+JQ0KICBzdW1tYXJpc2UoZGVsYXkgPSBtZWFuKGFycl9kZWxheSwgbmEucm0gPSBUUlVFKSkgJT4lDQogIGlubmVyX2pvaW4oYWlycG9ydHMsIGJ5ID0gYygiZGVzdCIgPSAiZmFhIikpICU+JQ0KICBnZ3Bsb3QoYWVzKHkgPSBsYXQsIHggPSBsb24sIHNpemUgPSBkZWxheSwgY29sb3VyID0gZGVsYXkpKSArDQogIGJvcmRlcnMoInN0YXRlIikgKw0KICBnZW9tX3BvaW50KCkgKw0KICBjb29yZF9xdWlja21hcCgpICsNCiAgc2NhbGVfY29sb3VyX3ZpcmlkaXMoKQ0KYGBgDQoNCg==