Welcome to my very first Tidy Tuesday!

I hope you enjoy this journey from a very terrible graph to a beautiful plot. Maybe my notes and workflow help you learn a thing or two, I know I had to learn a few tricks today!

What I learned today that I didnt already know:

Manipulating the facet labels: this is one thing I’ve not done before.
I also got more familiar with mutate in the tidyverse.
And playing around with adding text outside of the plot, such as customize labels and notes.


The github README and data can be found here

The Economist Article on “Greying of the Nobel laureates: Over the years, the committee has been bestowing the honour on older and older recipients” was published on Oct 3rd 2016.

My TidyTuesday goal is to recreate The Economists graph:


Lets load the data

library(tidyverse)
library(here)
library(janitor)

nobel_winners <- readr::read_csv("https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2019/2019-05-14/nobel_winners.csv")
nobel_winner_all_pubs <- readr::read_csv("https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2019/2019-05-14/nobel_winner_all_pubs.csv")

Since I want the x axis to be year awarded and the y axis to be the age of the laureate, I need to calculate age.

First stab at a plot

nobel_winners %>% 
  mutate(birth_year = substring(nobel_winners$birth_date, 1, 4), birth_year = as.integer(birth_year)) %>%
  mutate(laureate_age = prize_year - birth_year) %>%
  ggplot() +
  geom_point(aes(x=prize_year, y=laureate_age))

Facet by Category

In the correct order that The Economist listed. And also add the smooth line.

require(gdata)
target <- c("Medicine", "Physics", "Chemistry","Economics","Literature","Peace") #Order defined

nobel_winners %>% 
  mutate(birth_year = substring(nobel_winners$birth_date, 1, 4), birth_year = as.integer(birth_year)) %>%
  mutate(laureate_age = prize_year - birth_year) %>%
  mutate(category = reorder.factor(category, new.order=target)) %>%  #reorder by defined order
  ggplot() +
    geom_point(aes(x=prize_year, y=laureate_age))+
    facet_grid(.~category)+
    geom_smooth(aes(x=prize_year, y=laureate_age),se=FALSE)

Im getting closer!

Now I just need to tidy up the axis

  ggplot() +
    geom_point(aes(x=prize_year, y=laureate_age))+
    facet_grid(.~category)+
    geom_smooth(aes(x=prize_year, y=laureate_age),se=FALSE)+
    scale_y_continuous(position = "right", limits = c(15,100)) +   #update y axis 
    theme(panel.grid.major.x = element_blank(), panel.grid.minor = element_blank(), axis.title.y=element_blank()) #edit grid background and rm y axis label

Adjusting the facet labels

To blend in with plot + changes to the x axis

    theme(panel.grid.major.x = element_blank(), panel.grid.minor = element_blank(),
          axis.title.y=element_blank(),axis.title.x=element_blank(),
          strip.background =element_rect(fill="grey92"), #change facet label background color 
          strip.text.x = element_text(angle = 0, hjust = 0)) + #move labelled text to the left
    scale_x_continuous(limits = c(1900,2016), breaks = c(1900, 1950, 2000)) #adjust x axis increments 


Colors Anyone?

I found this article on The Economist color schemes, but I still had to eyeball it for a couple, using this handy dandy color chart.

    geom_point(aes(x=prize_year, y=laureate_age, colour = category), shape = 1)+  #add color and hollow point 
    geom_smooth(aes(x=prize_year, y=laureate_age, colour = category),se=FALSE, lwd=1.5)+ #add color and thicken line
    theme(panel.grid.major.x = element_blank(), panel.grid.minor = element_blank(),
          axis.title.y=element_blank(),axis.title.x=element_blank(),
          strip.background =element_rect(fill="grey92"), 
          strip.text.x = element_text(angle = 0, hjust = 0),
          legend.position="none") , #remove legend
          strip.text = element_text(colour = "grey25")) + # change facet text color
    scale_colour_manual(values = c("#014d64","#90353B","#EE6A50","#2D6D66","#EE9A00","#01A2D9")) #manual color

Unfortanetly, ggplot does not easily change the facet text colors by category. I read a forum post on this if you want to really change the plotting, however I decided to take the hit and not do it.

What one could try to do is make the text “invisible” by making it the same color as the background, and they overlay individually the category text with the correct color.

Adding additional text

The tricky part….. adding text of the oldest and youngest winners with a little line to the point. hmmmmmm

    theme(panel.grid.major.x = element_blank(), panel.grid.minor = element_blank(),
          axis.title.y=element_blank(),axis.title.x=element_blank(),
          strip.background =element_rect(fill="grey92"), 
          strip.text.x = element_text(angle = 0, hjust = 0),
          legend.position="none", 
          strip.text = element_text(colour = "grey24", face = 'bold'), #bold facet labels
          plot.title = element_text(face = 'bold', hjust = 0),  #change title to left align
          plot.caption = element_text(hjust = 0), #change caption to left align
          axis.text =  element_text(face = 'bold')) +
    labs(title = 'Senescience',  subtitle ='Age of Nobel laureates, at date of award ', caption ='Source: Nobelprize.org ') + #add labels
    annotate("text", x= Inf, y= 96, label = "Oldest winner \n Leonid Hurwicz, 90", hjust = 1, size = 2.5, colour = c("grey92","grey92","grey92","#2D6D66","grey92","grey92")) + #add Oldest
    annotate("text", x= Inf, y= 25, label = "Youngest winner \n Malala Yousafzai, 17", hjust = 1, size = 2.5, colour = c("grey92","grey92","grey92","grey92","grey92","#01A2D9")) #add youngest

I cant get all the text outside of the plot, buts its very close. Also the legend is a little tricky


Not bad, not bad

S.MARTINEZ

THE ECONOMIST


Side note: our own favorite wheat hero, Norman E. Borlaug’s laureate_id is 528.

library(kableExtra)
nobel_winners %>% 
  filter(laureate_id == '528') %>%
  kable(caption = "Table 1: Summary Norman E. Borlougs Nobel Peace Prize") %>%
  kable_styling(bootstrap_options = c("striped", "hover"), full_width = F) 
Table 1: Summary Norman E. Borlougs Nobel Peace Prize
prize_year category prize motivation prize_share laureate_id laureate_type full_name birth_date birth_city birth_country gender organization_name organization_city organization_country death_date death_city death_country
1970 Peace The Nobel Peace Prize 1970 NA 1/1 528 Individual Norman E. Borlaug 1914-03-25 Cresco, IA United States of America Male NA NA NA 2009-09-12 Dallas, TX United States of America
LS0tDQp0aXRsZTogIlRpZHlUdWVzZGF5V2syMCINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDoNCiAgICBjb2RlX2Rvd25sb2FkOiB5ZXMNCiAgICB0b2M6IHRydWUNCiAgICB0b2NfZGVwdGg6IDUNCiAgICB0b2NfZmxvYXQ6IHRydWUNCiAgICB0aGVtZTogZmxhdGx5DQogIHBkZl9kb2N1bWVudDogZGVmYXVsdA0KZGF0ZTogImByIGZvcm1hdChTeXMudGltZSgpLCAnJVkuJW0uJWQnKWAiDQphdXRob3I6IFMuQS4gTWFydGluZXoNCg0KLS0tDQoNCioqV2VsY29tZSB0byBteSB2ZXJ5IGZpcnN0IFRpZHkgVHVlc2RheSEqKiAgIA0KDQpJIGhvcGUgeW91IGVuam95IHRoaXMgam91cm5leSBmcm9tIGEgdmVyeSB0ZXJyaWJsZSBncmFwaCB0byBhIGJlYXV0aWZ1bCBwbG90LiBNYXliZSBteSBub3RlcyBhbmQgd29ya2Zsb3cgaGVscCB5b3UgbGVhcm4gYSB0aGluZyBvciB0d28sIEkga25vdyBJIGhhZCB0byBsZWFybiBhIGZldyB0cmlja3MgdG9kYXkhDQoNCioqV2hhdCBJIGxlYXJuZWQgdG9kYXkgdGhhdCBJIGRpZG50IGFscmVhZHkga25vdzoqKiAgDQoNCj4gTWFuaXB1bGF0aW5nIHRoZSBmYWNldCBsYWJlbHM6IHRoaXMgaXMgb25lIHRoaW5nIEkndmUgbm90IGRvbmUgYmVmb3JlLiAgDQo+IEkgYWxzbyBnb3QgbW9yZSBmYW1pbGlhciB3aXRoIGBtdXRhdGVgIGluIHRoZSB0aWR5dmVyc2UuICANCj4gQW5kIHBsYXlpbmcgYXJvdW5kIHdpdGggYWRkaW5nIHRleHQgb3V0c2lkZSBvZiB0aGUgcGxvdCwgc3VjaCBhcyBjdXN0b21pemUgbGFiZWxzIGFuZCBub3Rlcy4gIA0KDQotLS0tLQ0KDQpUaGUgZ2l0aHViIFtSRUFETUVdKGh0dHBzOi8vZ2l0aHViLmNvbS9yZm9yZGF0YXNjaWVuY2UvdGlkeXR1ZXNkYXkvYmxvYi9tYXN0ZXIvZGF0YS8yMDE5LzIwMTktMDUtMTQvcmVhZG1lLm1kKSBhbmQgZGF0YSBjYW4gYmUgZm91bmQgW2hlcmVdKGh0dHBzOi8vZ2l0aHViLmNvbS9yZm9yZGF0YXNjaWVuY2UvdGlkeXR1ZXNkYXkvdHJlZS9tYXN0ZXIvZGF0YS8yMDE5LzIwMTktMDUtMTQpICANCg0KVGhlIFtFY29ub21pc3QgQXJ0aWNsZV0oaHR0cHM6Ly93d3cuZWNvbm9taXN0LmNvbS9ncmFwaGljLWRldGFpbC8yMDE2LzEwLzAzL2dyZXlpbmctb2YtdGhlLW5vYmVsLWxhdXJlYXRlcykgb24gIkdyZXlpbmcgb2YgdGhlIE5vYmVsIGxhdXJlYXRlczogT3ZlciB0aGUgeWVhcnMsIHRoZSBjb21taXR0ZWUgaGFzIGJlZW4gYmVzdG93aW5nIHRoZSBob25vdXIgb24gb2xkZXIgYW5kIG9sZGVyIHJlY2lwaWVudHMiIHdhcyBwdWJsaXNoZWQgb24gT2N0IDNyZCAyMDE2LiAgDQoNCioqTXkgVGlkeVR1ZXNkYXkgZ29hbCBpcyB0byByZWNyZWF0ZSBUaGUgRWNvbm9taXN0cyBncmFwaDoqKiAgIA0KDQohW10oVGlkeVR1ZXNkYXlXazIwX0Vjb25vbWlzdFBsb3QucG5nKQ0KDQotLS0tLS0tDQoNCiMjIyBMZXRzIGxvYWQgdGhlIGRhdGEgIA0KYGBge3IgIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UgfQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KGhlcmUpDQpsaWJyYXJ5KGphbml0b3IpDQoNCm5vYmVsX3dpbm5lcnMgPC0gcmVhZHI6OnJlYWRfY3N2KCJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vcmZvcmRhdGFzY2llbmNlL3RpZHl0dWVzZGF5L21hc3Rlci9kYXRhLzIwMTkvMjAxOS0wNS0xNC9ub2JlbF93aW5uZXJzLmNzdiIpDQpub2JlbF93aW5uZXJfYWxsX3B1YnMgPC0gcmVhZHI6OnJlYWRfY3N2KCJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vcmZvcmRhdGFzY2llbmNlL3RpZHl0dWVzZGF5L21hc3Rlci9kYXRhLzIwMTkvMjAxOS0wNS0xNC9ub2JlbF93aW5uZXJfYWxsX3B1YnMuY3N2IikNCmBgYA0KDQpTaW5jZSBJIHdhbnQgdGhlIHggYXhpcyB0byBiZSB5ZWFyIGF3YXJkZWQgYW5kIHRoZSB5IGF4aXMgdG8gYmUgdGhlIGFnZSBvZiB0aGUgbGF1cmVhdGUsIEkgbmVlZCB0byBjYWxjdWxhdGUgYWdlLg0KDQojIyMgRmlyc3Qgc3RhYiBhdCBhIHBsb3QgDQpgYGB7ciB3YXJuaW5nPUZBTFNFfQ0Kbm9iZWxfd2lubmVycyAlPiUgDQogIG11dGF0ZShiaXJ0aF95ZWFyID0gc3Vic3RyaW5nKG5vYmVsX3dpbm5lcnMkYmlydGhfZGF0ZSwgMSwgNCksIGJpcnRoX3llYXIgPSBhcy5pbnRlZ2VyKGJpcnRoX3llYXIpKSAlPiUNCiAgbXV0YXRlKGxhdXJlYXRlX2FnZSA9IHByaXplX3llYXIgLSBiaXJ0aF95ZWFyKSAlPiUNCiAgZ2dwbG90KCkgKw0KICBnZW9tX3BvaW50KGFlcyh4PXByaXplX3llYXIsIHk9bGF1cmVhdGVfYWdlKSkNCg0KYGBgDQoNCiMjIyBGYWNldCBieSBgQ2F0ZWdvcnlgIA0KSW4gdGhlIGNvcnJlY3Qgb3JkZXIgdGhhdCBUaGUgRWNvbm9taXN0IGxpc3RlZC4gQW5kIGFsc28gYWRkIHRoZSBzbW9vdGggbGluZS4gIA0KDQpgYGB7ciAgZXZhbD1GQUxTRX0NCnJlcXVpcmUoZ2RhdGEpDQp0YXJnZXQgPC0gYygiTWVkaWNpbmUiLCAiUGh5c2ljcyIsICJDaGVtaXN0cnkiLCJFY29ub21pY3MiLCJMaXRlcmF0dXJlIiwiUGVhY2UiKSAjT3JkZXIgZGVmaW5lZA0KDQpub2JlbF93aW5uZXJzICU+JSANCiAgbXV0YXRlKGJpcnRoX3llYXIgPSBzdWJzdHJpbmcobm9iZWxfd2lubmVycyRiaXJ0aF9kYXRlLCAxLCA0KSwgYmlydGhfeWVhciA9IGFzLmludGVnZXIoYmlydGhfeWVhcikpICU+JQ0KICBtdXRhdGUobGF1cmVhdGVfYWdlID0gcHJpemVfeWVhciAtIGJpcnRoX3llYXIpICU+JQ0KICBtdXRhdGUoY2F0ZWdvcnkgPSByZW9yZGVyLmZhY3RvcihjYXRlZ29yeSwgbmV3Lm9yZGVyPXRhcmdldCkpICU+JSAgI3Jlb3JkZXIgYnkgZGVmaW5lZCBvcmRlcg0KICBnZ3Bsb3QoKSArDQogICAgZ2VvbV9wb2ludChhZXMoeD1wcml6ZV95ZWFyLCB5PWxhdXJlYXRlX2FnZSkpKw0KICAgIGZhY2V0X2dyaWQoLn5jYXRlZ29yeSkrDQogICAgZ2VvbV9zbW9vdGgoYWVzKHg9cHJpemVfeWVhciwgeT1sYXVyZWF0ZV9hZ2UpLHNlPUZBTFNFKQ0KYGBgDQoNCmBgYHtyICBlY2hvPUZBTFNFLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQ0KcmVxdWlyZShnZGF0YSkNCnRhcmdldCA8LSBjKCJNZWRpY2luZSIsICJQaHlzaWNzIiwgIkNoZW1pc3RyeSIsIkVjb25vbWljcyIsIkxpdGVyYXR1cmUiLCJQZWFjZSIpICNPcmRlciBkZWZpbmVkDQoNCm5vYmVsX3dpbm5lcnMgJT4lIA0KICBtdXRhdGUoYmlydGhfeWVhciA9IHN1YnN0cmluZyhub2JlbF93aW5uZXJzJGJpcnRoX2RhdGUsIDEsIDQpLCBiaXJ0aF95ZWFyID0gYXMuaW50ZWdlcihiaXJ0aF95ZWFyKSkgJT4lDQogIG11dGF0ZShsYXVyZWF0ZV9hZ2UgPSBwcml6ZV95ZWFyIC0gYmlydGhfeWVhcikgJT4lDQogIG11dGF0ZShjYXRlZ29yeSA9IHJlb3JkZXIuZmFjdG9yKGNhdGVnb3J5LCBuZXcub3JkZXI9dGFyZ2V0KSkgJT4lICAjcmVvcmRlciBieSBkZWZpbmVkIG9yZGVyDQogIGdncGxvdCgpICsNCiAgICBnZW9tX3BvaW50KGFlcyh4PXByaXplX3llYXIsIHk9bGF1cmVhdGVfYWdlKSkrDQogICAgZmFjZXRfZ3JpZCgufmNhdGVnb3J5KSsNCiAgICBnZW9tX3Ntb290aChhZXMoeD1wcml6ZV95ZWFyLCB5PWxhdXJlYXRlX2FnZSksc2U9RkFMU0UpDQpgYGANCg0KIyMjIEltIGdldHRpbmcgY2xvc2VyISAgIA0KDQpOb3cgSSBqdXN0IG5lZWQgdG8gdGlkeSB1cCB0aGUgYXhpcw0KYGBge3IgZXZhbCA9IEZBTFNFfQ0KICBnZ3Bsb3QoKSArDQogICAgZ2VvbV9wb2ludChhZXMoeD1wcml6ZV95ZWFyLCB5PWxhdXJlYXRlX2FnZSkpKw0KICAgIGZhY2V0X2dyaWQoLn5jYXRlZ29yeSkrDQogICAgZ2VvbV9zbW9vdGgoYWVzKHg9cHJpemVfeWVhciwgeT1sYXVyZWF0ZV9hZ2UpLHNlPUZBTFNFKSsNCiAgICBzY2FsZV95X2NvbnRpbnVvdXMocG9zaXRpb24gPSAicmlnaHQiLCBsaW1pdHMgPSBjKDE1LDEwMCkpICsgICAjdXBkYXRlIHkgYXhpcyANCiAgICB0aGVtZShwYW5lbC5ncmlkLm1ham9yLnggPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksIGF4aXMudGl0bGUueT1lbGVtZW50X2JsYW5rKCkpICNlZGl0IGdyaWQgYmFja2dyb3VuZCBhbmQgcm0geSBheGlzIGxhYmVsDQpgYGANCg0KYGBge3IgZWNobyA9IEZBTFNFLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQ0KcmVxdWlyZShnZGF0YSkNCnRhcmdldCA8LSBjKCJNZWRpY2luZSIsICJQaHlzaWNzIiwgIkNoZW1pc3RyeSIsIkVjb25vbWljcyIsIkxpdGVyYXR1cmUiLCJQZWFjZSIpIA0KDQpub2JlbF93aW5uZXJzICU+JSANCiAgbXV0YXRlKGJpcnRoX3llYXIgPSBzdWJzdHJpbmcobm9iZWxfd2lubmVycyRiaXJ0aF9kYXRlLCAxLCA0KSwgYmlydGhfeWVhciA9IGFzLmludGVnZXIoYmlydGhfeWVhcikpICU+JQ0KICBtdXRhdGUobGF1cmVhdGVfYWdlID0gcHJpemVfeWVhciAtIGJpcnRoX3llYXIpICU+JQ0KICBtdXRhdGUoY2F0ZWdvcnkgPSByZW9yZGVyLmZhY3RvcihjYXRlZ29yeSwgbmV3Lm9yZGVyPXRhcmdldCkpICU+JSAgDQogIGdncGxvdCgpICsNCiAgICBnZW9tX3BvaW50KGFlcyh4PXByaXplX3llYXIsIHk9bGF1cmVhdGVfYWdlKSkrDQogICAgZmFjZXRfZ3JpZCgufmNhdGVnb3J5KSsNCiAgICBnZW9tX3Ntb290aChhZXMoeD1wcml6ZV95ZWFyLCB5PWxhdXJlYXRlX2FnZSksc2U9RkFMU0UpKw0KICAgIHNjYWxlX3lfY29udGludW91cyhwb3NpdGlvbiA9ICJyaWdodCIsIGxpbWl0cyA9IGMoMTUsMTAwKSkgKyAgICN1cGRhdGUgeSBheGlzIA0KICAgIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueCA9IGVsZW1lbnRfYmxhbmsoKSwgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwgYXhpcy50aXRsZS55PWVsZW1lbnRfYmxhbmsoKSkgI2VkaXQgZ3JpZCBiYWNrZ3JvdW5kIGFuZCBybSB5IGF4aXMgbGFiZWwNCmBgYA0KDQoNCiMjIyBBZGp1c3RpbmcgdGhlIGZhY2V0IGxhYmVscw0KVG8gYmxlbmQgaW4gd2l0aCBwbG90ICsgY2hhbmdlcyB0byB0aGUgeCBheGlzIA0KYGBge3IgZXZhbCA9IEZBTFNFfQ0KICAgIHRoZW1lKHBhbmVsLmdyaWQubWFqb3IueCA9IGVsZW1lbnRfYmxhbmsoKSwgcGFuZWwuZ3JpZC5taW5vciA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgICBheGlzLnRpdGxlLnk9ZWxlbWVudF9ibGFuaygpLGF4aXMudGl0bGUueD1lbGVtZW50X2JsYW5rKCksDQogICAgICAgICAgc3RyaXAuYmFja2dyb3VuZCA9ZWxlbWVudF9yZWN0KGZpbGw9ImdyZXk5MiIpLCAjY2hhbmdlIGZhY2V0IGxhYmVsIGJhY2tncm91bmQgY29sb3IgDQogICAgICAgICAgc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMCwgaGp1c3QgPSAwKSkgKyAjbW92ZSBsYWJlbGxlZCB0ZXh0IHRvIHRoZSBsZWZ0DQogICAgc2NhbGVfeF9jb250aW51b3VzKGxpbWl0cyA9IGMoMTkwMCwyMDE2KSwgYnJlYWtzID0gYygxOTAwLCAxOTUwLCAyMDAwKSkgI2FkanVzdCB4IGF4aXMgaW5jcmVtZW50cyANCmBgYA0KDQpgYGB7ciBlY2hvID0gRkFMU0UsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9DQpyZXF1aXJlKGdkYXRhKQ0KdGFyZ2V0IDwtIGMoIk1lZGljaW5lIiwgIlBoeXNpY3MiLCAiQ2hlbWlzdHJ5IiwiRWNvbm9taWNzIiwiTGl0ZXJhdHVyZSIsIlBlYWNlIikgDQoNCm5vYmVsX3dpbm5lcnMgJT4lIA0KICBtdXRhdGUoYmlydGhfeWVhciA9IHN1YnN0cmluZyhub2JlbF93aW5uZXJzJGJpcnRoX2RhdGUsIDEsIDQpLCBiaXJ0aF95ZWFyID0gYXMuaW50ZWdlcihiaXJ0aF95ZWFyKSkgJT4lDQogIG11dGF0ZShsYXVyZWF0ZV9hZ2UgPSBwcml6ZV95ZWFyIC0gYmlydGhfeWVhcikgJT4lDQogIG11dGF0ZShjYXRlZ29yeSA9IHJlb3JkZXIuZmFjdG9yKGNhdGVnb3J5LCBuZXcub3JkZXI9dGFyZ2V0KSkgJT4lICANCiAgZ2dwbG90KCkgKw0KICAgIGdlb21fcG9pbnQoYWVzKHg9cHJpemVfeWVhciwgeT1sYXVyZWF0ZV9hZ2UpKSsNCiAgICBmYWNldF9ncmlkKC5+Y2F0ZWdvcnkpKw0KICAgIGdlb21fc21vb3RoKGFlcyh4PXByaXplX3llYXIsIHk9bGF1cmVhdGVfYWdlKSxzZT1GQUxTRSkrDQogICAgc2NhbGVfeV9jb250aW51b3VzKHBvc2l0aW9uID0gInJpZ2h0IiwgbGltaXRzID0gYygxNSwxMDApKSArICANCiAgICB0aGVtZShwYW5lbC5ncmlkLm1ham9yLnggPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgICAgYXhpcy50aXRsZS55PWVsZW1lbnRfYmxhbmsoKSxheGlzLnRpdGxlLng9ZWxlbWVudF9ibGFuaygpLA0KICAgICAgICAgIHN0cmlwLmJhY2tncm91bmQgPWVsZW1lbnRfcmVjdChmaWxsPSJncmV5OTIiKSwgI2NoYW5nZSBmYWNldCBsYWJlbCBiYWNrZ3JvdW5kIGNvbG9yIA0KICAgICAgICAgIHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDAsIGhqdXN0ID0gMCkpICsgI21vdmUgbGFiZWxsZWQgdGV4dCB0byB0aGUgbGVmdA0KICAgIHNjYWxlX3hfY29udGludW91cyhsaW1pdHMgPSBjKDE5MDAsMjAxNiksIGJyZWFrcyA9IGMoMTkwMCwgMTk1MCwgMjAwMCkpICNhZGp1c3QgeCBheGlzIGluY3JlbWVudHMgDQpgYGANCg0KLS0tLS0NCg0KIyMjIENvbG9ycyBBbnlvbmU/ICAgICANCkkgZm91bmQgdGhpcyBbYXJ0aWNsZV0oaHR0cHM6Ly95dXRhbm5paGlsYXRpb24uZ2l0aHViLmlvL2FsbFlvdXJGaWd1cmVBcmVCZWxvbmdUb1VzL2dndGhlbWVzL2Vjb25vbWlzdF9wYWwvKSBvbiBUaGUgRWNvbm9taXN0IGNvbG9yIHNjaGVtZXMsIGJ1dCBJIHN0aWxsIGhhZCB0byBleWViYWxsIGl0IGZvciBhIGNvdXBsZSwgdXNpbmcgdGhpcyBoYW5keSBkYW5keSBbY29sb3IgY2hhcnRdKGh0dHA6Ly9yZXNlYXJjaC5zdG93ZXJzLm9yZy9tY20vZWZnL1IvQ29sb3IvQ2hhcnQvQ29sb3JDaGFydC5wZGYpLiAgDQoNCmBgYHtyIGV2YWw9IEZBTFNFLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQ0KICAgIGdlb21fcG9pbnQoYWVzKHg9cHJpemVfeWVhciwgeT1sYXVyZWF0ZV9hZ2UsIGNvbG91ciA9IGNhdGVnb3J5KSwgc2hhcGUgPSAxKSsgICNhZGQgY29sb3IgYW5kIGhvbGxvdyBwb2ludCANCiAgICBnZW9tX3Ntb290aChhZXMoeD1wcml6ZV95ZWFyLCB5PWxhdXJlYXRlX2FnZSwgY29sb3VyID0gY2F0ZWdvcnkpLHNlPUZBTFNFLCBsd2Q9MS41KSsgI2FkZCBjb2xvciBhbmQgdGhpY2tlbiBsaW5lDQogICAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci54ID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICAgIGF4aXMudGl0bGUueT1lbGVtZW50X2JsYW5rKCksYXhpcy50aXRsZS54PWVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgICBzdHJpcC5iYWNrZ3JvdW5kID1lbGVtZW50X3JlY3QoZmlsbD0iZ3JleTkyIiksIA0KICAgICAgICAgIHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDAsIGhqdXN0ID0gMCksDQogICAgICAgICAgbGVnZW5kLnBvc2l0aW9uPSJub25lIikgLCAjcmVtb3ZlIGxlZ2VuZA0KICAgICAgICAgIHN0cmlwLnRleHQgPSBlbGVtZW50X3RleHQoY29sb3VyID0gImdyZXkyNSIpKSArICMgY2hhbmdlIGZhY2V0IHRleHQgY29sb3INCiAgICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGMoIiMwMTRkNjQiLCIjOTAzNTNCIiwiI0VFNkE1MCIsIiMyRDZENjYiLCIjRUU5QTAwIiwiIzAxQTJEOSIpKSAjbWFudWFsIGNvbG9yDQpgYGANCg0KYGBge3IgZWNobyAgPSBGQUxTRSwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRX0NCnJlcXVpcmUoZ2RhdGEpDQp0YXJnZXQgPC0gYygiTWVkaWNpbmUiLCAiUGh5c2ljcyIsICJDaGVtaXN0cnkiLCJFY29ub21pY3MiLCJMaXRlcmF0dXJlIiwiUGVhY2UiKSANCg0KbGlicmFyeShleHRyYWZvbnQpDQpub2JlbF93aW5uZXJzICU+JSANCiAgbXV0YXRlKGJpcnRoX3llYXIgPSBzdWJzdHJpbmcobm9iZWxfd2lubmVycyRiaXJ0aF9kYXRlLCAxLCA0KSwgYmlydGhfeWVhciA9IGFzLmludGVnZXIoYmlydGhfeWVhcikpICU+JQ0KICBtdXRhdGUobGF1cmVhdGVfYWdlID0gcHJpemVfeWVhciAtIGJpcnRoX3llYXIpICU+JQ0KICBtdXRhdGUoY2F0ZWdvcnkgPSByZW9yZGVyLmZhY3RvcihjYXRlZ29yeSwgbmV3Lm9yZGVyPXRhcmdldCkpICU+JSAgDQogIGdncGxvdCgpICsNCiAgICBnZW9tX3BvaW50KGFlcyh4PXByaXplX3llYXIsIHk9bGF1cmVhdGVfYWdlLCBjb2xvdXIgPSBjYXRlZ29yeSksIHNoYXBlID0gMSkrICAjYWRkIGNvbG9yIGFuZCBob2xsb3cgcG9pbnQgDQogICAgZmFjZXRfZ3JpZCgufmNhdGVnb3J5KSsNCiAgICBnZW9tX3Ntb290aChhZXMoeD1wcml6ZV95ZWFyLCB5PWxhdXJlYXRlX2FnZSwgY29sb3VyID0gY2F0ZWdvcnkpLHNlPUZBTFNFLCBsd2Q9MS41KSsgI2FkZCBjb2xvciBhbmQgdGhpY2tlbiBsaW5lDQogICAgc2NhbGVfeV9jb250aW51b3VzKHBvc2l0aW9uID0gInJpZ2h0IiwgbGltaXRzID0gYygxNSwxMDApKSArICANCiAgICB0aGVtZShwYW5lbC5ncmlkLm1ham9yLnggPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgICAgYXhpcy50aXRsZS55PWVsZW1lbnRfYmxhbmsoKSxheGlzLnRpdGxlLng9ZWxlbWVudF9ibGFuaygpLA0KICAgICAgICAgIHN0cmlwLmJhY2tncm91bmQgPWVsZW1lbnRfcmVjdChmaWxsPSJncmV5OTIiKSwgDQogICAgICAgICAgc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMCwgaGp1c3QgPSAwKSwNCiAgICAgICAgICBsZWdlbmQucG9zaXRpb249Im5vbmUiLCAjcmVtb3ZlIGxlZ2VuZA0KICAgICAgICAgIHN0cmlwLnRleHQgPSBlbGVtZW50X3RleHQoY29sb3VyID0gImdyZXkyNSIpKSArICMgY2hhbmdlIGZhY2V0IHRleHQgY29sb3INCiAgICBzY2FsZV94X2NvbnRpbnVvdXMobGltaXRzID0gYygxOTAwLDIwMTYpLCBicmVha3MgPSBjKDE5MDAsIDE5NTAsIDIwMDApKSsgDQogICAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBjKCIjMDE0ZDY0IiwiIzkwMzUzQiIsIiNFRTZBNTAiLCIjMkQ2RDY2IiwiI0VFOUEwMCIsIiMwMUEyRDkiKSkgDQpgYGANCg0KVW5mb3J0YW5ldGx5LCBnZ3Bsb3QgZG9lcyBub3QgZWFzaWx5IGNoYW5nZSB0aGUgZmFjZXQgdGV4dCBjb2xvcnMgYnkgY2F0ZWdvcnkuIEkgcmVhZCBhIFtmb3J1bSBwb3N0XShodHRwczovL2dpdGh1Yi5jb20vdGlkeXZlcnNlL2dncGxvdDIvaXNzdWVzLzIwOTYpIG9uIHRoaXMgaWYgeW91IHdhbnQgdG8gcmVhbGx5IGNoYW5nZSB0aGUgcGxvdHRpbmcsIGhvd2V2ZXIgSSBkZWNpZGVkIHRvIHRha2UgdGhlIGhpdCBhbmQgbm90IGRvIGl0LiAgDQoNCldoYXQgb25lIGNvdWxkIHRyeSB0byBkbyBpcyBtYWtlIHRoZSB0ZXh0ICJpbnZpc2libGUiIGJ5IG1ha2luZyBpdCB0aGUgc2FtZSBjb2xvciBhcyB0aGUgYmFja2dyb3VuZCwgYW5kIHRoZXkgb3ZlcmxheSBpbmRpdmlkdWFsbHkgdGhlIGNhdGVnb3J5IHRleHQgd2l0aCB0aGUgY29ycmVjdCBjb2xvci4gIA0KDQojIyMgQWRkaW5nIGFkZGl0aW9uYWwgdGV4dCAgDQpUaGUgdHJpY2t5IHBhcnQuLi4uLiBhZGRpbmcgdGV4dCBvZiB0aGUgb2xkZXN0IGFuZCB5b3VuZ2VzdCB3aW5uZXJzIHdpdGggYSBsaXR0bGUgbGluZSB0byB0aGUgcG9pbnQuIGhtbW1tbW0NCg0KYGBge3IgZXZhbD0gRkFMU0UsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9DQogICAgdGhlbWUocGFuZWwuZ3JpZC5tYWpvci54ID0gZWxlbWVudF9ibGFuaygpLCBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICAgIGF4aXMudGl0bGUueT1lbGVtZW50X2JsYW5rKCksYXhpcy50aXRsZS54PWVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgICBzdHJpcC5iYWNrZ3JvdW5kID1lbGVtZW50X3JlY3QoZmlsbD0iZ3JleTkyIiksIA0KICAgICAgICAgIHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDAsIGhqdXN0ID0gMCksDQogICAgICAgICAgbGVnZW5kLnBvc2l0aW9uPSJub25lIiwgDQogICAgICAgICAgc3RyaXAudGV4dCA9IGVsZW1lbnRfdGV4dChjb2xvdXIgPSAiZ3JleTI0IiwgZmFjZSA9ICdib2xkJyksICNib2xkIGZhY2V0IGxhYmVscw0KICAgICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoZmFjZSA9ICdib2xkJywgaGp1c3QgPSAwKSwgICNjaGFuZ2UgdGl0bGUgdG8gbGVmdCBhbGlnbg0KICAgICAgICAgIHBsb3QuY2FwdGlvbiA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDApLCAjY2hhbmdlIGNhcHRpb24gdG8gbGVmdCBhbGlnbg0KICAgICAgICAgIGF4aXMudGV4dCA9ICBlbGVtZW50X3RleHQoZmFjZSA9ICdib2xkJykpICsNCiAgICBsYWJzKHRpdGxlID0gJ1NlbmVzY2llbmNlJywgIHN1YnRpdGxlID0nQWdlIG9mIE5vYmVsIGxhdXJlYXRlcywgYXQgZGF0ZSBvZiBhd2FyZCAnLCBjYXB0aW9uID0nU291cmNlOiBOb2JlbHByaXplLm9yZyAnKSArICNhZGQgbGFiZWxzDQogICAgYW5ub3RhdGUoInRleHQiLCB4PSBJbmYsIHk9IDk2LCBsYWJlbCA9ICJPbGRlc3Qgd2lubmVyIFxuIExlb25pZCBIdXJ3aWN6LCA5MCIsIGhqdXN0ID0gMSwgc2l6ZSA9IDIuNSwgY29sb3VyID0gYygiZ3JleTkyIiwiZ3JleTkyIiwiZ3JleTkyIiwiIzJENkQ2NiIsImdyZXk5MiIsImdyZXk5MiIpKSArICNhZGQgT2xkZXN0DQogICAgYW5ub3RhdGUoInRleHQiLCB4PSBJbmYsIHk9IDI1LCBsYWJlbCA9ICJZb3VuZ2VzdCB3aW5uZXIgXG4gTWFsYWxhIFlvdXNhZnphaSwgMTciLCBoanVzdCA9IDEsIHNpemUgPSAyLjUsIGNvbG91ciA9IGMoImdyZXk5MiIsImdyZXk5MiIsImdyZXk5MiIsImdyZXk5MiIsImdyZXk5MiIsIiMwMUEyRDkiKSkgI2FkZCB5b3VuZ2VzdA0KICANCmBgYA0KDQpgYGB7ciBlY2hvICA9IEZBTFNFLCB3YXJuaW5nPUZBTFNFLCBtZXNzYWdlPUZBTFNFfQ0KcmVxdWlyZShnZGF0YSkNCnRhcmdldCA8LSBjKCJNZWRpY2luZSIsICJQaHlzaWNzIiwgIkNoZW1pc3RyeSIsIkVjb25vbWljcyIsIkxpdGVyYXR1cmUiLCJQZWFjZSIpIA0KDQpsaWJyYXJ5KGV4dHJhZm9udCkNCg0Kbm9iZWxfd2lubmVycyAlPiUgDQogIG11dGF0ZShiaXJ0aF95ZWFyID0gc3Vic3RyaW5nKG5vYmVsX3dpbm5lcnMkYmlydGhfZGF0ZSwgMSwgNCksIGJpcnRoX3llYXIgPSBhcy5pbnRlZ2VyKGJpcnRoX3llYXIpKSAlPiUNCiAgbXV0YXRlKGxhdXJlYXRlX2FnZSA9IHByaXplX3llYXIgLSBiaXJ0aF95ZWFyKSAlPiUNCiAgbXV0YXRlKGNhdGVnb3J5ID0gcmVvcmRlci5mYWN0b3IoY2F0ZWdvcnksIG5ldy5vcmRlcj10YXJnZXQpKSAlPiUgIA0KICBnZ3Bsb3QoKSArDQogICAgZ2VvbV9wb2ludChhZXMoeD1wcml6ZV95ZWFyLCB5PWxhdXJlYXRlX2FnZSwgY29sb3VyID0gY2F0ZWdvcnkpLCBzaGFwZSA9IDEpKyAgDQogICAgZmFjZXRfZ3JpZCgufmNhdGVnb3J5KSsNCiAgICBnZW9tX3Ntb290aChhZXMoeD1wcml6ZV95ZWFyLCB5PWxhdXJlYXRlX2FnZSwgY29sb3VyID0gY2F0ZWdvcnkpLHNlPUZBTFNFLCBsd2Q9MS41KSsgDQogICAgc2NhbGVfeV9jb250aW51b3VzKHBvc2l0aW9uID0gInJpZ2h0IiwgbGltaXRzID0gYygxNSwxMDApKSArICANCiAgICB0aGVtZShwYW5lbC5ncmlkLm1ham9yLnggPSBlbGVtZW50X2JsYW5rKCksIHBhbmVsLmdyaWQubWlub3IgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgICAgYXhpcy50aXRsZS55PWVsZW1lbnRfYmxhbmsoKSxheGlzLnRpdGxlLng9ZWxlbWVudF9ibGFuaygpLA0KICAgICAgICAgIHN0cmlwLmJhY2tncm91bmQgPWVsZW1lbnRfcmVjdChmaWxsPSJncmV5OTIiKSwgDQogICAgICAgICAgc3RyaXAudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMCwgaGp1c3QgPSAwKSwNCiAgICAgICAgICBsZWdlbmQucG9zaXRpb249Im5vbmUiLCANCiAgICAgICAgICBzdHJpcC50ZXh0ID0gZWxlbWVudF90ZXh0KGNvbG91ciA9ICJncmV5MjQiLCBmYWNlID0gJ2JvbGQnKSwgI2JvbGQgZmFjZXQgbGFiZWxzDQogICAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChmYWNlID0gJ2JvbGQnLCBoanVzdCA9IDApLCAgI2NoYW5nZSB0aXRsZSB0byBsZWZ0IGFsaWduDQogICAgICAgICAgcGxvdC5jYXB0aW9uID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMCksICNjaGFuZ2UgY2FwdGlvbiB0byBsZWZ0IGFsaWduDQogICAgICAgICAgYXhpcy50ZXh0ID0gIGVsZW1lbnRfdGV4dChmYWNlID0gJ2JvbGQnKSkgKyANCiAgICBzY2FsZV94X2NvbnRpbnVvdXMobGltaXRzID0gYygxOTAwLDIwMTYpLCBicmVha3MgPSBjKDE5MDAsIDE5NTAsIDIwMDApKSsgDQogICAgc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBjKCIjMDE0ZDY0IiwiIzkwMzUzQiIsIiNFRTZBNTAiLCIjMkQ2RDY2IiwiI0VFOUEwMCIsIiMwMUEyRDkiKSkgKw0KICBsYWJzKHRpdGxlID0gJ1NlbmVzY2llbmNlJywgIHN1YnRpdGxlID0nQWdlIG9mIE5vYmVsIGxhdXJlYXRlcywgYXQgZGF0ZSBvZiBhd2FyZCAnLCBjYXB0aW9uID0nU291cmNlOiBOb2JlbHByaXplLm9yZyAnKSArICNhZGQgbGFiZWxzDQogIGFubm90YXRlKCJ0ZXh0IiwgeD0gSW5mLCB5PSA5NiwgbGFiZWwgPSAiT2xkZXN0IHdpbm5lciBcbiBMZW9uaWQgSHVyd2ljeiwgOTAiLCBoanVzdCA9IDEsIHNpemUgPSAyLjUsIGNvbG91ciA9IGMoImdyZXk5MiIsImdyZXk5MiIsImdyZXk5MiIsIiMyRDZENjYiLCJncmV5OTIiLCJncmV5OTIiKSkgKyAjYWRkIE9sZGVzdA0KICBhbm5vdGF0ZSgidGV4dCIsIHg9IEluZiwgeT0gMjUsIGxhYmVsID0gIllvdW5nZXN0IHdpbm5lciBcbiBNYWxhbGEgWW91c2FmemFpLCAxNyIsIGhqdXN0ID0gMSwgc2l6ZSA9IDIuNSwgY29sb3VyID0gYygiZ3JleTkyIiwiZ3JleTkyIiwiZ3JleTkyIiwiZ3JleTkyIiwiZ3JleTkyIiwiIzAxQTJEOSIpKSsgI2FkZCB5b3VuZ2VzdA0KICBnZ3NhdmUoIlRpZHlUdWVzZGF5V2syMF9QbG90LnBuZyIpDQogICANCmBgYA0KDQoNCkkgY2FudCBnZXQgYWxsIHRoZSB0ZXh0IG91dHNpZGUgb2YgdGhlIHBsb3QsIGJ1dHMgaXRzIHZlcnkgY2xvc2UuIEFsc28gdGhlIGxlZ2VuZCBpcyBhIGxpdHRsZSB0cmlja3kgIA0KDQotLS0tLQ0KDQojIyMgTm90IGJhZCwgbm90IGJhZCAgIA0KDQoqKlMuTUFSVElORVoqKg0KIVtdKFRpZHlUdWVzZGF5V2syMF9QbG90LnBuZykgDQoNCioqVEhFIEVDT05PTUlTVCoqICANCiFbXShUaWR5VHVlc2RheVdrMjBfRWNvbm9taXN0UGxvdC5wbmcpIA0KDQoNCi0tLS0tLS0NCg0KU2lkZSBub3RlOiBvdXIgb3duIGZhdm9yaXRlIHdoZWF0IGhlcm8sIE5vcm1hbiBFLiBCb3JsYXVnJ3MgYGxhdXJlYXRlX2lkYCBpcyBgNTI4YC4gIA0KDQpgYGB7ciAgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRSB9DQpsaWJyYXJ5KGthYmxlRXh0cmEpDQpub2JlbF93aW5uZXJzICU+JSANCiAgZmlsdGVyKGxhdXJlYXRlX2lkID09ICc1MjgnKSAlPiUNCiAga2FibGUoY2FwdGlvbiA9ICJUYWJsZSAxOiBTdW1tYXJ5IE5vcm1hbiBFLiBCb3Jsb3VncyBOb2JlbCBQZWFjZSBQcml6ZSIpICU+JQ0KICBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gYygic3RyaXBlZCIsICJob3ZlciIpLCBmdWxsX3dpZHRoID0gRikgDQpgYGA=