Due Date: Sunday, March 24th

Keyboard Shortcuts:

  1. Assignment operator (<-) is Alt+- for Windows and Option+- for Mac
  2. Insert new code chunk Ctrl+Alt+I for Windows and Command+Option+I for Mac
  3. Run a line of code Ctrl+Enter for Windows and Command+Enter for Mac
  4. Run all the code within a chunk Ctrl+Shift+Enter for Windows and Command+Shift+Enter for Mac
  5. Insert a pipe operator (%>%) Ctrl+Shift+M for Windows and Command+Shift+M for Mac

General Instructions

  1. Use the cheatsheets and the keyboard shortcuts as you work through the assignment.
  2. Each task should be answered right below the question.
  3. The assignment should be submitted via a shareable github link on the assignments channel in Slack.
  4. Make sure the notebook is neatly formatted and looks good when you preview it.

Task set 1: Data types and structures

  1. List the 4 most common (data) types of atomic vectors.
    • Answer: CHar, Int, Double, Logical
  2. Create atomic vectors of the 4 common types covered in class. Print their length and type.
typeof(vDoub)
[1] "double"
  1. List the heirarchy of data types for coercion
    • Answer: character, double, integer, logical
  2. Explain why the output of following bits of code is TRUE (explain what is happening in terms of coercion):
"1" == 1
[1] TRUE

Answer: == does a comparison and returns T/F. For coercion, 1 is converted to character.

FALSE == 0
[1] TRUE

Answer: FALSE is converted to 0

  1. Create a list that holds the 4 common types of atomic vectors you created in task 2.
lVectors
[[1]]
[1] "Hello" "Test" 

[[2]]
[1] 14 15

[[3]]
[1] 1 3

[[4]]
[1]  TRUE FALSE
  1. Create a data frame with 3 columns and 5 rows using the data.frame() function
  1. Create the same data frame as above using tibble() function
  1. Use the str(), class() and or glimpse() command to see the difference between the dataframe and tibble create in 4 and 5.
glimpse(dfTest)
Observations: 5
Variables: 3
$ x <int> 1, 2, 3, 4, 5
$ y <int> 11, 12, 13, 14, 15
$ z <int> 16, 17, 18, 19, 20
glimpse(tbTest)
Observations: 5
Variables: 3
$ x <int> 1, 2, 3, 4, 5
$ y <int> 11, 12, 13, 14, 15
$ z <int> 16, 17, 18, 19, 20
  1. Fill in the blanks.

    • A data frame is a 2__ dimensionsional data structure in R that consists of list__ of _equal__ length
  2. What is the difference between an atomic vector and a list?
    • Answer: atomic verctor is a 1 dimensional array of a single data type - homogeneous. List is also 1d but can be a combimation of different data types - heterogeneous.

Task set 2: Data manipulation using dplyr

INSTRUCTIONS: You will be using the tidyverse and nycflights13 packages for the next set of tasks. Refer to the documentation on tidyverse.org or use the help pages if you do not understand a function fully.

  1. Load the tidyverse and nycflights13 packages.
library(tidyverse)
library(nycflights13)
  1. Describe two ways in which you can use RStudio confirm that a package has been loaded into your current R session? (Hint: One of them is a dropdown menu and the other a list of checkboxes)

    • Answer: 1. Global enviroment dropdown. 2. installed.packages()
  2. Use the distinct() command to identify the unique combinations of airline carriers and origin airports in the flights data.

  1. Use the one_of() helper function to select the following columns - year, month, day, dep_time, sched_dep_time, dep_delay, arr_time, from the flights data.
  1. Use the slice() function to slice the first 10 rows in the flights data.
  1. Perform the same operation as the previous task but this time use filter(). (Hint: Search for how to get the row numbers of a tibble)
  1. Use the top_n() command to identify the top 5 flights out of NYC that experienced the greatest arrival delays in 2013.
  1. Use top_n() along with arrange() and slice() to pull out the 50th most delayed departure from NYC in 2013 (Not all 50, just the 50th).
  1. Do the same thing as the previous task using
    • row_number()
    • and dense_rank()
  1. The result from row_number() and top_n() are the same, while that from dense_rank() is different. Why?

    • Answer: dense rank assigns the same rank for the same value of dep_delay, whereas the others are sequentially ranked
  2. Find the top 10 airline carrier that had the highest average departure delays in 2013 using group_by(), summarise() and other functions you have learnt previously.

  1. Use group_by() with mutate() to create a new variable called comparativeDelay which is the difference between departure delay and the average delay in each origin airport for every hour in 2013 (checkout the time_hour variable in the flights data). Store the result in a variable called comparativeDelays.
flights %>% 
  group_by(origin, hour) %>% 
  mutate(avgDelay = mean(dep_delay, na.rm = T), 
         comparativeDelay = dep_delay - mean(dep_delay, na.rm = T)) %>% 
  select(1:3, carrier, hour, flight, tailnum, dep_delay, avgDelay, comparativeDelay)
Adding missing grouping variables: `origin`
  1. Now group the comparativeDelays tibble by carriers to print the top 10 airlines with the greatest average comparative delays.
flights %>% 
  group_by(origin, hour) %>% 
  mutate(avgDelay = mean(dep_delay, na.rm = T), 
         comparativeDelay = dep_delay - mean(dep_delay, na.rm = T)) %>% 
  select(1:3, carrier, hour, flight, tailnum, dep_delay, avgDelay, comparativeDelay) %>% 
  group_by(carrier) %>% 
  summarise(avgComparativeDelay = mean(comparativeDelay, na.rm = T)) %>% 
  top_n(10, avgComparativeDelay) %>% 
  arrange(desc(avgComparativeDelay))
Adding missing grouping variables: `origin`
  1. Use group_by() with filter to print the 5 most delayed flights from each origin. Your printed tibble should have 15 rows.
  1. The air authority in NY wants to penalize carriers for departure delays. Which of the three metrics (task 1, 3 or 4) would you recommend they use to identify the airlines to penalize. Why?

    • Answer: Average Comparative Delay seems to be the best, as it summarises by origin and hour

Task set 3: R markdown

  1. Modify the text below as per the prompt
    • Underline me
    • Make me bold
    • Make me a block quote

    • Make me italic
    • Strike through me
  2. Create a level three header called “My level 3 header” under this line ###My level 3 header

  3. Modify the content below so that the bullet points (unordered list) render correctly

Messy bullet points

  1. Use chunk options to hide the output and the code from the chunk below in the previewed notebook.
LS0tDQp0aXRsZTogIkFzc2lnbm1lbnQgMSINCmF1dGhvcjogVmluUGhpbA0KZGF0ZTogIkRhdGUgY3JlYXRlZDogYHIgU3lzLkRhdGUoKWAiDQpvdXRwdXQ6DQogIGh0bWxfbm90ZWJvb2s6DQogICAgaGlnaGxpZ2h0OiBrYXRlDQogICAgc21hcnQ6IHllcw0KICAgIHRoZW1lOiBjb3Ntbw0KICAgIGNvZGVfZm9sZGluZzogc2hvdw0KICAgIGRmX3ByaW50OiBwYWdlZA0KLS0tDQoNCioqRHVlIERhdGUqKjogU3VuZGF5LCBNYXJjaCAyNHRoDQoNCioqS2V5Ym9hcmQgU2hvcnRjdXRzKio6DQoNCjEuIEFzc2lnbm1lbnQgb3BlcmF0b3IgKDwtKSBpcyBgQWx0Ky1gIGZvciBXaW5kb3dzIGFuZCBgT3B0aW9uKy1gIGZvciBNYWMNCjIuIEluc2VydCBuZXcgY29kZSBjaHVuayBgQ3RybCtBbHQrSWAgZm9yIFdpbmRvd3MgYW5kIGBDb21tYW5kK09wdGlvbitJYCBmb3IgTWFjDQozLiBSdW4gYSBsaW5lIG9mIGNvZGUgYEN0cmwrRW50ZXJgIGZvciBXaW5kb3dzIGFuZCBgQ29tbWFuZCtFbnRlcmAgZm9yIE1hYw0KNC4gUnVuIGFsbCB0aGUgY29kZSB3aXRoaW4gYSBjaHVuayBgQ3RybCtTaGlmdCtFbnRlcmAgZm9yIFdpbmRvd3MgYW5kIGBDb21tYW5kK1NoaWZ0K0VudGVyYCBmb3IgTWFjDQo1LiBJbnNlcnQgYSBwaXBlIG9wZXJhdG9yICglPiUpIGBDdHJsK1NoaWZ0K01gIGZvciBXaW5kb3dzIGFuZCBgQ29tbWFuZCtTaGlmdCtNYCBmb3IgTWFjDQoNCioqR2VuZXJhbCBJbnN0cnVjdGlvbnMqKg0KDQoxLiBVc2UgdGhlIGNoZWF0c2hlZXRzIGFuZCB0aGUga2V5Ym9hcmQgc2hvcnRjdXRzIGFzIHlvdSB3b3JrIHRocm91Z2ggdGhlIGFzc2lnbm1lbnQuDQoyLiBFYWNoIHRhc2sgc2hvdWxkIGJlIGFuc3dlcmVkIHJpZ2h0IGJlbG93IHRoZSBxdWVzdGlvbi4NCjMuIFRoZSBhc3NpZ25tZW50IHNob3VsZCBiZSBzdWJtaXR0ZWQgdmlhIGEgc2hhcmVhYmxlIGdpdGh1YiBsaW5rIG9uIHRoZSBhc3NpZ25tZW50cyBjaGFubmVsIGluIFNsYWNrLg0KNC4gTWFrZSBzdXJlIHRoZSBub3RlYm9vayBpcyBuZWF0bHkgZm9ybWF0dGVkIGFuZCBsb29rcyBnb29kIHdoZW4geW91IHByZXZpZXcgaXQuDQoNCiMjVGFzayBzZXQgMTogRGF0YSB0eXBlcyBhbmQgc3RydWN0dXJlcw0KMS4gTGlzdCB0aGUgNCBtb3N0IGNvbW1vbiAoZGF0YSkgdHlwZXMgb2YgYXRvbWljIHZlY3RvcnMuDQogICAgKyBBbnN3ZXI6IENIYXIsIEludCwgRG91YmxlLCBMb2dpY2FsDQoNCjIuIENyZWF0ZSBhdG9taWMgdmVjdG9ycyBvZiB0aGUgNCBjb21tb24gdHlwZXMgY292ZXJlZCBpbiBjbGFzcy4gUHJpbnQgdGhlaXIgbGVuZ3RoIGFuZCB0eXBlLg0KDQpgYGB7cn0NCnZDaGFyIDwtIGMoIkhlbGxvIiwgIlRlc3QiKQ0KdkludCA8LSBjKDFMLCAzTCkNCnZEb3ViIDwtIGMoMTQsIDE1KQ0KdkxvZyA8LSBjKFQsRikNCg0KdHlwZW9mKHZDaGFyKQ0KdHlwZW9mKHZJbnQpDQp0eXBlb2YodkRvdWIpDQp0eXBlb2YodkxvZykNCg0KbGVuZ3RoKHZDaGFyKQ0KbGVuZ3RoKHZJbnQpDQpsZW5ndGgodkRvdWIpDQpsZW5ndGgodkxvZykNCmBgYA0KDQozLiBMaXN0IHRoZSBoZWlyYXJjaHkgb2YgZGF0YSB0eXBlcyBmb3IgY29lcmNpb24NCiAgICArIEFuc3dlcjogY2hhcmFjdGVyLCBkb3VibGUsIGludGVnZXIsIGxvZ2ljYWwNCg0KNC4gRXhwbGFpbiB3aHkgdGhlIG91dHB1dCBvZiBmb2xsb3dpbmcgYml0cyBvZiBjb2RlIGlzIFRSVUUgKGV4cGxhaW4gd2hhdCBpcyBoYXBwZW5pbmcgaW4gdGVybXMgb2YgY29lcmNpb24pOiANCg0KYGBge3J9DQoiMSIgPT0gMQ0KYGBgDQpBbnN3ZXI6ID09IGRvZXMgYSBjb21wYXJpc29uIGFuZCByZXR1cm5zIFQvRi4gDQpGb3IgY29lcmNpb24sIDEgaXMgY29udmVydGVkIHRvIGNoYXJhY3Rlci4NCg0KYGBge3J9DQpGQUxTRSA9PSAwDQpgYGANCkFuc3dlcjogRkFMU0UgaXMgY29udmVydGVkIHRvIDANCg0KMy4gQ3JlYXRlIGEgbGlzdCB0aGF0IGhvbGRzIHRoZSA0IGNvbW1vbiB0eXBlcyBvZiBhdG9taWMgdmVjdG9ycyB5b3UgY3JlYXRlZCBpbiB0YXNrIDIuDQoNCmBgYHtyfQ0KbFZlY3RvcnMgPC0gbGlzdCh2Q2hhciwgdkRvdWIsIHZJbnQsIHZMb2cpDQpsVmVjdG9ycw0KYGBgDQo0LiBDcmVhdGUgYSBkYXRhIGZyYW1lIHdpdGggMyBjb2x1bW5zIGFuZCA1IHJvd3MgdXNpbmcgdGhlIGBkYXRhLmZyYW1lKClgIGZ1bmN0aW9uDQoNCmBgYHtyfQ0KZGZUZXN0IDwtIGRhdGEuZnJhbWUoeD1jKDE6NSksIHk9YygxMToxNSksIHo9YygxNjoyMCkpDQpkZlRlc3QNCmBgYA0KNS4gQ3JlYXRlIHRoZSBzYW1lIGRhdGEgZnJhbWUgYXMgYWJvdmUgdXNpbmcgYHRpYmJsZSgpYCBmdW5jdGlvbg0KDQpgYGB7cn0NCnRiVGVzdCA8LSB0aWJibGUoeCA9IDE6NSwgeSA9IDExOjE1LCB6ID0gMTY6MjApDQp0YlRlc3QNCmBgYA0KDQo2LiBVc2UgdGhlIGBzdHIoKWAsIGBjbGFzcygpYCBhbmQgb3IgYGdsaW1wc2UoKWAgY29tbWFuZCB0byBzZWUgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiB0aGUgZGF0YWZyYW1lIGFuZCB0aWJibGUgY3JlYXRlIGluIDQgYW5kIDUuDQoNCmBgYHtyfQ0Kc3RyKGRmVGVzdCkNCnN0cih0YlRlc3QpDQoNCmNsYXNzKGRmVGVzdCkNCmNsYXNzKHRiVGVzdCkNCg0KZ2xpbXBzZShkZlRlc3QpDQpnbGltcHNlKHRiVGVzdCkNCmBgYA0KDQo3LiBGaWxsIGluIHRoZSBibGFua3MuIA0KDQogICAgKyBBIGRhdGEgZnJhbWUgaXMgYSBfMl9fXyBkaW1lbnNpb25zaW9uYWwgZGF0YSBzdHJ1Y3R1cmUgaW4gUiB0aGF0IGNvbnNpc3RzIG9mIF9saXN0X19fIG9mIF9lcXVhbF9fIGxlbmd0aA0KDQo4LiBXaGF0IGlzIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gYW4gYXRvbWljIHZlY3RvciBhbmQgYSBsaXN0Pw0KICAgICsgQW5zd2VyOiBhdG9taWMgdmVyY3RvciBpcyBhIDEgZGltZW5zaW9uYWwgYXJyYXkgb2YgYSBzaW5nbGUgZGF0YSB0eXBlIC0gaG9tb2dlbmVvdXMuIExpc3QgaXMgYWxzbyAxZCBidXQgY2FuIGJlIGEgY29tYmltYXRpb24gb2YgZGlmZmVyZW50IGRhdGEgdHlwZXMgLSBoZXRlcm9nZW5lb3VzLg0KDQoNCiMjVGFzayBzZXQgMjogRGF0YSBtYW5pcHVsYXRpb24gdXNpbmcgZHBseXINCg0KKipJTlNUUlVDVElPTlMqKjogWW91IHdpbGwgYmUgdXNpbmcgdGhlIHRpZHl2ZXJzZSBhbmQgbnljZmxpZ2h0czEzIHBhY2thZ2VzIGZvciB0aGUgbmV4dCBzZXQgb2YgdGFza3MuIFJlZmVyIHRvIHRoZSBkb2N1bWVudGF0aW9uIG9uIHRpZHl2ZXJzZS5vcmcgb3IgdXNlIHRoZSBoZWxwIHBhZ2VzIGlmIHlvdSBkbyBub3QgdW5kZXJzdGFuZCBhIGZ1bmN0aW9uIGZ1bGx5Lg0KDQoxLiBMb2FkIHRoZSB0aWR5dmVyc2UgYW5kIG55Y2ZsaWdodHMxMyBwYWNrYWdlcy4NCg0KYGBge3J9DQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkobnljZmxpZ2h0czEzKQ0KYGBgDQoNCjIuIERlc2NyaWJlIHR3byB3YXlzIGluIHdoaWNoIHlvdSBjYW4gdXNlIFJTdHVkaW8gY29uZmlybSB0aGF0IGEgcGFja2FnZSBoYXMgYmVlbiBsb2FkZWQgaW50byB5b3VyIGN1cnJlbnQgUiBzZXNzaW9uPyAoSGludDogT25lIG9mIHRoZW0gaXMgYSBkcm9wZG93biBtZW51IGFuZCB0aGUgb3RoZXIgYSBsaXN0IG9mIGNoZWNrYm94ZXMpDQoNCiAgICArIEFuc3dlcjogMS4gR2xvYmFsIGVudmlyb21lbnQgZHJvcGRvd24uIDIuIGluc3RhbGxlZC5wYWNrYWdlcygpDQoNCjMuIFVzZSB0aGUgYGRpc3RpbmN0KClgIGNvbW1hbmQgdG8gaWRlbnRpZnkgdGhlIHVuaXF1ZSBjb21iaW5hdGlvbnMgb2YgYWlybGluZSBjYXJyaWVycyBhbmQgb3JpZ2luIGFpcnBvcnRzIGluIHRoZSBmbGlnaHRzIGRhdGEuDQoNCmBgYHtyfQ0KZmxpZ2h0cw0KZGlzdGluY3QoZmxpZ2h0cywgY2Fycmllciwgb3JpZ2luICkgJT4lDQogIGFycmFuZ2UoY2Fycmllciwgb3JpZ2luKQ0KYGBgDQoNCjQuIFVzZSB0aGUgYG9uZV9vZigpYCBoZWxwZXIgZnVuY3Rpb24gdG8gc2VsZWN0IHRoZSBmb2xsb3dpbmcgY29sdW1ucyAtICB5ZWFyLCBtb250aCwgZGF5LCBkZXBfdGltZSwgc2NoZWRfZGVwX3RpbWUsIGRlcF9kZWxheSwgYXJyX3RpbWUsIGZyb20gdGhlIGZsaWdodHMgZGF0YS4NCg0KYGBge3J9DQpmbGlnaHRzICU+JSANCiAgc2VsZWN0KG9uZV9vZihjKCJ5ZWFyIiwgIm1vbnRoIiwgImRheSIsICJkZXBfdGltZSIsICJzY2hlZF9kZXBfdGltZSIsICJkZXBfZGVsYXkiLCAiYXJyX3RpbWUiKSkpDQoNCmBgYA0KDQo1LiBVc2UgdGhlIGBzbGljZSgpYCBmdW5jdGlvbiB0byBzbGljZSB0aGUgZmlyc3QgMTAgcm93cyBpbiB0aGUgZmxpZ2h0cyBkYXRhLg0KDQpgYGB7cn0NCmZsaWdodHMgJT4lIA0KICBzbGljZSgxOjEwKQ0KYGBgDQoNCjYuIFBlcmZvcm0gdGhlIHNhbWUgb3BlcmF0aW9uIGFzIHRoZSBwcmV2aW91cyB0YXNrIGJ1dCB0aGlzIHRpbWUgdXNlIGBmaWx0ZXIoKWAuIChIaW50OiBTZWFyY2ggZm9yIGhvdyB0byBnZXQgdGhlIHJvdyBudW1iZXJzIG9mIGEgdGliYmxlKQ0KDQpgYGB7cn0NCmZsaWdodHMgJT4lIA0KICBmaWx0ZXIoYmV0d2Vlbihyb3dfbnVtYmVyKCksIDEsIDEwKSkNCmBgYA0KDQo3LiBVc2UgdGhlIGB0b3BfbigpYCBjb21tYW5kIHRvIGlkZW50aWZ5IHRoZSB0b3AgNSBmbGlnaHRzIG91dCBvZiBOWUMgdGhhdCBleHBlcmllbmNlZCB0aGUgZ3JlYXRlc3QgYXJyaXZhbCBkZWxheXMgaW4gMjAxMy4NCg0KYGBge3J9DQpmbGlnaHRzICU+JSANCiAgdG9wX24oNSwgYXJyX2RlbGF5KSAlPiUgDQogIGFycmFuZ2UoZGVzYyhhcnJfZGVsYXkpKQ0KYGBgDQoNCjguIFVzZSBgdG9wX24oKWAgYWxvbmcgd2l0aCBgYXJyYW5nZSgpYCBhbmQgYHNsaWNlKClgIHRvIHB1bGwgb3V0IHRoZSA1MHRoIG1vc3QgZGVsYXllZCBkZXBhcnR1cmUgZnJvbSBOWUMgaW4gMjAxMyAoTm90IGFsbCA1MCwganVzdCB0aGUgNTB0aCkuIA0KYGBge3J9DQpmbGlnaHRzICU+JSANCiAgdG9wX24oNTAsIGRlcF9kZWxheSkgJT4lIA0KICBhcnJhbmdlKGRlc2MoZGVwX2RlbGF5KSkgJT4lIA0KICBzbGljZSg1MCkNCmBgYA0KDQo5LiBEbyB0aGUgc2FtZSB0aGluZyBhcyB0aGUgcHJldmlvdXMgdGFzayB1c2luZyANCiAgICArIGByb3dfbnVtYmVyKClgDQogICAgKyBhbmQgYGRlbnNlX3JhbmsoKWANCmBgYHtyfQ0KZmxpZ2h0cyAlPiUgDQogIGFycmFuZ2UoZGVzYyhkZXBfZGVsYXkpKSAlPiUgDQogIGZpbHRlcihyb3dfbnVtYmVyKCkgPT0gNTApDQpgYGANCg0KYGBge3J9DQpmbGlnaHRzICU+JSANCiAgZmlsdGVyKGRlbnNlX3JhbmsoZGVzYyhkZXBfZGVsYXkpKSA9PSA1MCkNCmBgYA0KDQoNCjEwLiBUaGUgcmVzdWx0IGZyb20gYHJvd19udW1iZXIoKWAgYW5kIGB0b3BfbigpYCBhcmUgdGhlIHNhbWUsIHdoaWxlIHRoYXQgZnJvbSBgZGVuc2VfcmFuaygpYCBpcyBkaWZmZXJlbnQuIFdoeT8NCg0KICAgICsgQW5zd2VyOiBkZW5zZSByYW5rIGFzc2lnbnMgdGhlIHNhbWUgcmFuayBmb3IgdGhlIHNhbWUgdmFsdWUgb2YgZGVwX2RlbGF5LCB3aGVyZWFzIHRoZSBvdGhlcnMgYXJlIHNlcXVlbnRpYWxseSByYW5rZWQNCg0KMTEuIEZpbmQgdGhlIHRvcCAxMCBhaXJsaW5lIGNhcnJpZXIgdGhhdCBoYWQgdGhlIGhpZ2hlc3QgYXZlcmFnZSBkZXBhcnR1cmUgZGVsYXlzIGluIDIwMTMgdXNpbmcgYGdyb3VwX2J5KClgLCBgc3VtbWFyaXNlKClgIGFuZCBvdGhlciBmdW5jdGlvbnMgeW91IGhhdmUgbGVhcm50IHByZXZpb3VzbHkuDQpgYGB7cn0NCmZsaWdodHMgJT4lIA0KICBncm91cF9ieShjYXJyaWVyKSAlPiUgDQogIHN1bW1hcmlzZShhdmdEZXBEZWxheSA9IG1lYW4oZGVwX2RlbGF5LCBuYS5ybSA9IFQpKSAlPiUgDQogIHRvcF9uKDEwLCBhdmdEZXBEZWxheSkgJT4lIA0KICBhcnJhbmdlKGRlc2MoYXZnRGVwRGVsYXkpKSANCiAgDQpgYGANCg0KMTIuIFVzZSBgZ3JvdXBfYnkoKWAgd2l0aCBgbXV0YXRlKClgIHRvIGNyZWF0ZSBhIG5ldyB2YXJpYWJsZSBjYWxsZWQgYGNvbXBhcmF0aXZlRGVsYXlgIHdoaWNoIGlzIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gZGVwYXJ0dXJlIGRlbGF5IGFuZCB0aGUgYXZlcmFnZSBkZWxheSBpbiBlYWNoIG9yaWdpbiBhaXJwb3J0IGZvciBldmVyeSBob3VyIGluIDIwMTMgKGNoZWNrb3V0IHRoZSBgdGltZV9ob3VyYCB2YXJpYWJsZSBpbiB0aGUgZmxpZ2h0cyBkYXRhKS4gU3RvcmUgdGhlIHJlc3VsdCBpbiBhIHZhcmlhYmxlIGNhbGxlZCBgY29tcGFyYXRpdmVEZWxheXNgLg0KYGBge3J9DQpmbGlnaHRzICU+JSANCiAgZ3JvdXBfYnkob3JpZ2luLCBob3VyKSAlPiUgDQogIG11dGF0ZShhdmdEZWxheSA9IG1lYW4oZGVwX2RlbGF5LCBuYS5ybSA9IFQpLCANCiAgICAgICAgIGNvbXBhcmF0aXZlRGVsYXkgPSBkZXBfZGVsYXkgLSBtZWFuKGRlcF9kZWxheSwgbmEucm0gPSBUKSkgJT4lIA0KICBzZWxlY3QoMTozLCBjYXJyaWVyLCBob3VyLCBmbGlnaHQsIHRhaWxudW0sIGRlcF9kZWxheSwgYXZnRGVsYXksIGNvbXBhcmF0aXZlRGVsYXkpDQoNCmBgYA0KDQoxMy4gTm93IGdyb3VwIHRoZSBgY29tcGFyYXRpdmVEZWxheXNgIHRpYmJsZSBieSBjYXJyaWVycyB0byBwcmludCB0aGUgdG9wIDEwIGFpcmxpbmVzIHdpdGggdGhlIGdyZWF0ZXN0IGF2ZXJhZ2UgY29tcGFyYXRpdmUgZGVsYXlzLg0KYGBge3J9DQpmbGlnaHRzICU+JSANCiAgZ3JvdXBfYnkob3JpZ2luLCBob3VyKSAlPiUgDQogIG11dGF0ZShhdmdEZWxheSA9IG1lYW4oZGVwX2RlbGF5LCBuYS5ybSA9IFQpLCANCiAgICAgICAgIGNvbXBhcmF0aXZlRGVsYXkgPSBkZXBfZGVsYXkgLSBtZWFuKGRlcF9kZWxheSwgbmEucm0gPSBUKSkgJT4lIA0KICBzZWxlY3QoMTozLCBjYXJyaWVyLCBob3VyLCBmbGlnaHQsIHRhaWxudW0sIGRlcF9kZWxheSwgYXZnRGVsYXksIGNvbXBhcmF0aXZlRGVsYXkpICU+JSANCiAgZ3JvdXBfYnkoY2FycmllcikgJT4lIA0KICBzdW1tYXJpc2UoYXZnQ29tcGFyYXRpdmVEZWxheSA9IG1lYW4oY29tcGFyYXRpdmVEZWxheSwgbmEucm0gPSBUKSkgJT4lIA0KICB0b3BfbigxMCwgYXZnQ29tcGFyYXRpdmVEZWxheSkgJT4lIA0KICBhcnJhbmdlKGRlc2MoYXZnQ29tcGFyYXRpdmVEZWxheSkpDQpgYGANCg0KMTQuIFVzZSBgZ3JvdXBfYnkoKWAgd2l0aCBmaWx0ZXIgdG8gcHJpbnQgdGhlIDUgbW9zdCBkZWxheWVkIGZsaWdodHMgZnJvbSBlYWNoIG9yaWdpbi4gWW91ciBwcmludGVkIHRpYmJsZSBzaG91bGQgaGF2ZSAxNSByb3dzLg0KYGBge3J9DQpmbGlnaHRzICU+JQ0KICBncm91cF9ieShvcmlnaW4pICU+JSANCiAgZmlsdGVyKGJldHdlZW4oZGVuc2VfcmFuayhkZXNjKGRlcF9kZWxheSkpLDEsIDUpKSAlPiUgDQogIGFycmFuZ2Uob3JpZ2luLCBkZXNjKGRlcF9kZWxheSkpDQoNCmBgYA0KDQoxNS4gVGhlIGFpciBhdXRob3JpdHkgaW4gTlkgd2FudHMgdG8gcGVuYWxpemUgY2FycmllcnMgZm9yIGRlcGFydHVyZSBkZWxheXMuIFdoaWNoIG9mIHRoZSB0aHJlZSBtZXRyaWNzICh0YXNrIDEsIDMgb3IgNCkgd291bGQgeW91IHJlY29tbWVuZCB0aGV5IHVzZSB0byBpZGVudGlmeSB0aGUgYWlybGluZXMgdG8gcGVuYWxpemUuIFdoeT8NCg0KICAgICsgQW5zd2VyOiBBdmVyYWdlIENvbXBhcmF0aXZlIERlbGF5IHNlZW1zIHRvIGJlIHRoZSBiZXN0LCBhcyBpdCBzdW1tYXJpc2VzIGJ5IG9yaWdpbiBhbmQgaG91ciANCiAgICANCiMjVGFzayBzZXQgMzogUiBtYXJrZG93bg0KDQoxLiBNb2RpZnkgdGhlIHRleHQgYmVsb3cgYXMgcGVyIHRoZSBwcm9tcHQNCiAgICArIFVuZGVybGluZSBtZQ0KICAgICsgKipNYWtlIG1lIGJvbGQqKg0KICAgICsgPk1ha2UgbWUgYSBibG9jayBxdW90ZQ0KICAgICsgKk1ha2UgbWUgaXRhbGljKg0KICAgICsgfn5TdHJpa2UgdGhyb3VnaCBtZX5+DQoNCjIuIENyZWF0ZSBhIGxldmVsIHRocmVlIGhlYWRlciBjYWxsZWQgIk15IGxldmVsIDMgaGVhZGVyIiB1bmRlciB0aGlzIGxpbmUgDQojIyNNeSBsZXZlbCAzIGhlYWRlcg0KDQozLiBNb2RpZnkgdGhlIGNvbnRlbnQgYmVsb3cgc28gdGhhdCB0aGUgYnVsbGV0IHBvaW50cyAodW5vcmRlcmVkIGxpc3QpIHJlbmRlciBjb3JyZWN0bHkNCg0KKipNZXNzeSBidWxsZXQgcG9pbnRzKioNCg0KLSBvbmUNCi0gdHdvDQotIHRocmVlDQoNCjQuIFVzZSBjaHVuayBvcHRpb25zIHRvIGhpZGUgdGhlIG91dHB1dCBhbmQgdGhlIGNvZGUgZnJvbSB0aGUgY2h1bmsgYmVsb3cgaW4gdGhlIHByZXZpZXdlZCBub3RlYm9vay4NCg0KYGBge3IsIHJlc3VsdHM9J2hpZGUnLCBlY2hvPUZBTFNFfQ0KcHJpbnQoIkhpZGUgbWUgYW5kIHRoZSBjb2RlIHRoYXQgY3JlYXRlZCBtZSIpDQpgYGA=