TidyTuesday Project (210810)


This notebook is about Measuring Infrastructure in the Bureau of Economic Analytics National Economic Accounts.

Introduction

Infrastructure provides critical support for economic activity. Hence it contributes in a significant way to our living standards. This notebook will analyze the trends of infrastructure investment through the years (decades) using the measurements of infrastructure data in the U.S. National Economic Accounts(NEAs).

For this notebook, I will use the chain_investment.csv dataset. I think that using the chained dollars(*) will give us better insights about how important the investment was in that year(decade) comparing it with nowadays infrastructure investments.

Why is it important?

This study is a challenge that will provide a huge value in understanding the nature of the surrounding infrastructure and its behavior as a connected multi-network.

A glance to the data

Following the Bureau of Economic Analysis paper, there are three main categories of infrastructure: basic, social and digital.

That being said, let’s start working with those three main categories from the chain_investment.csv.

df_main_cat = chinvestment %>%
  filter(group_num == 1) %>%
  mutate(
    label = case_when(
      category == "Total basic infrastructure"~"Basic",
      category == "Total digital infrastructure"~"Digital",
      category == "Total social infrastructure"~"Social"
    ),
      colorL = case_when(
      category == "Total basic infrastructure"~"#ef476f",
      category == "Total digital infrastructure"~"#ffd166",
      category == "Total social infrastructure"~"#06d6a0"
    )
  )
chart_lines <- df_main_cat %>%
  ggplot(aes(x=year, y=gross_inv_chain)) +
  geom_line(aes(color=category))+
  geom_point(aes(color=category))+
  guides(fill=FALSE, color=FALSE)+
  theme_minimal()+
  scale_color_manual(breaks=df_main_cat$category,values=df_main_cat$colorL)+
  ylab("Total $ in Infrastructure Investment") +
  theme(legend.position="none", legend.title=element_blank())


chart_area <- df_main_cat %>%
  ggplot(aes(x=year, y=gross_inv_chain, fill=category)) +
  geom_area()+
  scale_fill_manual(breaks=df_main_cat$category,values=df_main_cat$colorL)+
  scale_color_manual(breaks=df_main_cat$category,values=df_main_cat$colorL)+
  ylab("Infrastructure Investment ($) per category") +
  guides(fill=FALSE, color=FALSE)+
  theme_minimal()+
  theme(legend.position="none", legend.title=element_blank())+
  annotate(geom = "segment", x=1947,xend=2017, y=600000,yend=600000, color="#343a40")+
  annotate(geom = "segment", x=1947,xend=2017, y=300000,yend=300000, color="#343a40")+
  annotate(geom = "text", x=1947, y=630000, label="600 billions $", color="#343a40",
            hjust=0, size=6,family=fontfamily)+
  annotate(geom = "text", x=1947, y=330000, label="300 billions $", color="#343a40",
            hjust=0, size=6,family=fontfamily)
  
  

ggarrange(chart_area, chart_lines, ncol = 2, heights = c(10, 10), align = "v")

Infrastructure Investment Breakdown (sankey)

We already know how the money is invested in the three main categories (basic, social and digital) so let’s break it down in order to see how much money is invested in each subcategory.

In order to do that, Sankey (*) charts are a viable option.

Following the Google Charts definition, a sankey diagram is a visualization used to depict a flow from one set of values to another. The things being connected are called nodes and the connections are called links. Sankeys are best used when you want to show a many-to-many mapping between two domains.

Splitting the dataset in different levels will be necessary for generating the Sankey chart (spoiler alert: There are three different levels regarding the investments). In order to do that:

options(dplyr.summarise.inform = FALSE)

# Remember: We need to remove the fund sources
dfch_grp <- chinvestment %>% 
  group_by(category, meta_cat, group_num) %>%
  filter(!(category %in% c("Federal", "S&L", "Private")) &(group_num!=14))   %>%
  summarise(inv = sum(gross_inv_chain))

dfch_grp <- dfch_grp %>%
      mutate(
        category = case_when(
        category == "Total basic infrastructure"~"Basic",
        category == "Total digital infrastructure"~"Digital",
        category == "Total social infrastructure"~"Social",
        TRUE ~category
        ), meta_cat =case_when(
          meta_cat == "Total basic infrastructure"~"Basic",
          TRUE ~meta_cat
        )
    )

# dfch_grp$category <- as.factor(dfch_grp$category)
# dfch_grp$meta_cat <- as.factor(dfch_grp$meta_cat)
# Level 1: Total infrastructure => Total basic/social/digital infrastructure
lvl1 <- dfch_grp %>% 
      filter(meta_cat %in% "Total infrastructure")


lvl2 <- dfch_grp %>% filter(meta_cat %in% c(
      "Basic",
      "Digital",
      "Social"
  ))



lvl3 <- dfch_grp %>% filter(meta_cat %in% lvl2$category)
labelsV <- c(unique(lvl1$meta_cat), unique(lvl2$meta_cat), unique(lvl2$category),unique(lvl3$category))

sourceV <-c(match(lvl1$meta_cat, labels), match(lvl2$meta_cat,labels), match(lvl3$meta_cat,labels))
targetV <- c(match(lvl1$category, labels), match(lvl2$category,labels), match(lvl3$category,labels))
valueV <- c(lvl1$inv, lvl2$inv, lvl3$inv)
             

# lvl1
# lvl2
# lvl3
LS0tDQp0aXRsZTogIkJFQSBJbmZyYXN0cnVjdHVyZSBJbnZlc3RtZW50Ig0Kb3V0cHV0OiBodG1sX25vdGVib29rDQotLS0NCg0KDQoqKlRpZHlUdWVzZGF5IFByb2plY3QgKDIxMDgxMCkqKg0KDQotLS0tLS0NCg0KPiAgLSDwn5OxIExpbmtlZGluIFtKdWFuIEFudG9uaW8gQ2FiZXphIFNvdXNhDQpdKGh0dHBzOi8vd3d3LmxpbmtlZGluLmNvbS9pbi9qdWFuLWFudG9uaW8tY2FiZXphLXNvdXNhLTViOTU0OTY4LykNCj4gIC0g8J+TrCBFbWFpbDogIGp1YWFuY2Fic291QGdtYWlsLmNvbQ0KPiAgLSDwn5al77iPIFR3aXR0ZXI6IEBbQWNlY29uaGllbG9dKGh0dHBzOi8vdHdpdHRlci5jb20vQWNlY29uaGllbG8pDQoNCg0KVGhpcyBub3RlYm9vayBpcyBhYm91dCAqTWVhc3VyaW5nIEluZnJhc3RydWN0dXJlIGluIHRoZSBCdXJlYXUgb2YgRWNvbm9taWMgQW5hbHl0aWNzIE5hdGlvbmFsIEVjb25vbWljIEFjY291bnRzKi4NCg0KIyBJbnRyb2R1Y3Rpb24NCkluZnJhc3RydWN0dXJlIHByb3ZpZGVzIGNyaXRpY2FsIHN1cHBvcnQgZm9yIGVjb25vbWljIGFjdGl2aXR5LiBIZW5jZSBpdCBjb250cmlidXRlcyBpbiBhIHNpZ25pZmljYW50IHdheSB0byBvdXIgbGl2aW5nIHN0YW5kYXJkcy4gVGhpcyBub3RlYm9vayB3aWxsIGFuYWx5emUgdGhlIHRyZW5kcyBvZiBpbmZyYXN0cnVjdHVyZSBpbnZlc3RtZW50IHRocm91Z2ggdGhlIHllYXJzIChkZWNhZGVzKSB1c2luZyB0aGUgbWVhc3VyZW1lbnRzIG9mIGluZnJhc3RydWN0dXJlIGRhdGEgaW4gdGhlIFUuUy4gTmF0aW9uYWwgRWNvbm9taWMgQWNjb3VudHMoTkVBcykuDQoNCkZvciB0aGlzIG5vdGVib29rLCBJIHdpbGwgdXNlIHRoZSBjaGFpbl9pbnZlc3RtZW50LmNzdiBkYXRhc2V0LiBJIHRoaW5rIHRoYXQgdXNpbmcgdGhlIGNoYWluZWQgZG9sbGFycygqKSB3aWxsIGdpdmUgdXMgYmV0dGVyIGluc2lnaHRzIGFib3V0IGhvdyBpbXBvcnRhbnQgdGhlIGludmVzdG1lbnQgd2FzIGluIHRoYXQgeWVhcihkZWNhZGUpIGNvbXBhcmluZyBpdCB3aXRoIG5vd2FkYXlzIGluZnJhc3RydWN0dXJlIGludmVzdG1lbnRzLg0KDQoqICpDaGFpbmVkIGRvbGxhcnM6IENoYWluZWQgZG9sbGFycyBpcyBhIG1ldGhvZCBvZiBhZGp1c3RpbmcgcmVhbCBkb2xsYXIgYW1vdW50cyBmb3IgaW5mbGF0aW9uIG92ZXIgdGltZSwgdG8gYWxsb3cgdGhlIGNvbXBhcmlzb24gb2YgZmlndXJlcyBmcm9tIGRpZmZlcmVudCB5ZWFycy4gVGhlIFUuUy4gRGVwYXJ0bWVudCBvZiBDb21tZXJjZSBpbnRyb2R1Y2VkIHRoZSBjaGFpbmVkLWRvbGxhciBtZWFzdXJlIGluIDE5OTYqLg0KDQoqKldoeSBpcyBpdCBpbXBvcnRhbnQ/KioNCg0KVGhpcyBzdHVkeSBpcyBhIGNoYWxsZW5nZSB0aGF0IHdpbGwgcHJvdmlkZSBhIGh1Z2UgdmFsdWUgaW4gdW5kZXJzdGFuZGluZyB0aGUgbmF0dXJlIG9mIHRoZSBzdXJyb3VuZGluZyBpbmZyYXN0cnVjdHVyZSBhbmQgaXRzIGJlaGF2aW9yIGFzIGEgY29ubmVjdGVkIG11bHRpLW5ldHdvcmsuDQoNCg0KDQpgYGB7ciBMaWJyYXJpZXMsIGVjaG89RkFMU0UsIG1lc3NhZ2U9RkFMU0V9DQpsaWJyYXJ5KHRpZHl2ZXJzZSwgd2Fybi5jb25mbGljdHMgPSBGQUxTRSkNCmxpYnJhcnkoZ2dhbmltYXRlKQ0KbGlicmFyeShocmJydGhlbWVzKQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShnZ3B1YnIpDQpsaWJyYXJ5KHBsb3RseSkNCmZvbnRmYW1pbHkgPC0iT3BlbiBTYW5zIg0KDQpgYGANCg0KDQpgYGB7ciBEb3dubG9hZCB0aGUgZGF0YSwgbWVzc2FnZT1GQUxTRSwgaW5jbHVkZT1GQUxTRX0NCnR1ZXNkYXRhIDwtIHRpZHl0dWVzZGF5Ujo6dHRfbG9hZCgnMjAyMS0wOC0xMCcpDQp0dWVzZGF0YSA8LSB0aWR5dHVlc2RheVI6OnR0X2xvYWQoMjAyMSwgd2VlayA9IDMzKQ0KDQpjaGludmVzdG1lbnQgPC0gdHVlc2RhdGEkY2hhaW5faW52ZXN0bWVudA0KDQpgYGANCg0KDQojIEEgZ2xhbmNlIHRvIHRoZSBkYXRhDQpGb2xsb3dpbmcgdGhlIFtCdXJlYXUgb2YgRWNvbm9taWMgQW5hbHlzaXMgcGFwZXJdKGh0dHBzOi8vd3d3LmJlYS5nb3Yvc3lzdGVtL2ZpbGVzL3BhcGVycy9CRUEtV1AyMDIwLTEyLnBkZiksICoqdGhlcmUgYXJlIHRocmVlIG1haW4gY2F0ZWdvcmllcyBvZiBpbmZyYXN0cnVjdHVyZTogYmFzaWMsIHNvY2lhbCBhbmQgZGlnaXRhbCoqLiANCg0KKiAqKkJhc2ljIGluZnJhc3RydWN0dXJlKio6IE1haW5seSBkZXRlcm1pbmVkIGJ5IHRyZW5kcyBpbiB0cmFuc3BvcnRhdGlvbiBhbmQgcG93ZXIuIFdhdGVyLCBzZXdlciwgYW5kIGNvbnNlcnZhdGlvbiBhbmQgZGV2ZWxvcG1lbnQgKGRhbXMsIGxldmVlcywgc2VhIHdhbGxzLCBhbmQgcmVsYXRlZCBhc3NldHMpIG1ha2UgdXAgYSByZWxhdGl2ZWx5IHNtYWxsIHNoYXJlIG9mIGJhc2ljIGluZnJhc3RydWN0dXJlLg0KDQoqICoqU29jaWFsIGluZnJhc3RydWN0dXJlKio6IERldGVybWluZWQgYnkgdHJlbmRzIGluIGhlYWx0aCwgZWR1Y2F0aW9uLCBhbmQgcHVibGljIHNhZmV0eS4gRm9yIHNvY2lhbCBpbmZyYXN0cnVjdHVyZSwgdGhlIHNoYXJlIG9mIHByaXZhdGVseSBvd25lZCBuZXQgc3RvY2sgZ3JldyBvdmVyIHRpbWUgd2hpbGUgdGhlIHNoYXJlIG9mIHN0YXRlLg0KDQoqICoqRGlnaXRhbCBpbmZyYXN0cnVjdHVyZSoqOiBDb21tdW5pY2F0aW9ucywgc29mdHdhcmUuLi5ldGMuDQpgYGB7ciBHbGFuY2luZyB0aGUgZGF0YSwgZWNobz1GQUxTRX0NCmhlYWQoY2hpbnZlc3RtZW50KQ0KDQpgYGANCg0KVGhhdCBiZWluZyBzYWlkLCBsZXQncyBzdGFydCB3b3JraW5nIHdpdGggdGhvc2UgdGhyZWUgbWFpbiBjYXRlZ29yaWVzIGZyb20gdGhlIGBjaGFpbl9pbnZlc3RtZW50LmNzdmAuIA0KDQpgYGB7ciBNYWluQ2F0IC0gRGF0YSBXcmFuZ2xpbmcgSSB9DQpkZl9tYWluX2NhdCA9IGNoaW52ZXN0bWVudCAlPiUNCiAgZmlsdGVyKGdyb3VwX251bSA9PSAxKSAlPiUNCiAgbXV0YXRlKA0KICAgIGxhYmVsID0gY2FzZV93aGVuKA0KICAgICAgY2F0ZWdvcnkgPT0gIlRvdGFsIGJhc2ljIGluZnJhc3RydWN0dXJlIn4iQmFzaWMiLA0KICAgICAgY2F0ZWdvcnkgPT0gIlRvdGFsIGRpZ2l0YWwgaW5mcmFzdHJ1Y3R1cmUifiJEaWdpdGFsIiwNCiAgICAgIGNhdGVnb3J5ID09ICJUb3RhbCBzb2NpYWwgaW5mcmFzdHJ1Y3R1cmUifiJTb2NpYWwiDQogICAgKSwNCiAgICAgIGNvbG9yTCA9IGNhc2Vfd2hlbigNCiAgICAgIGNhdGVnb3J5ID09ICJUb3RhbCBiYXNpYyBpbmZyYXN0cnVjdHVyZSJ+IiNlZjQ3NmYiLA0KICAgICAgY2F0ZWdvcnkgPT0gIlRvdGFsIGRpZ2l0YWwgaW5mcmFzdHJ1Y3R1cmUifiIjZmZkMTY2IiwNCiAgICAgIGNhdGVnb3J5ID09ICJUb3RhbCBzb2NpYWwgaW5mcmFzdHJ1Y3R1cmUifiIjMDZkNmEwIg0KICAgICkNCiAgKQ0KDQoNCmBgYA0KDQoNCg0KDQoNCmBgYHtyIE1haW5DYXQgLSBEYXRhIFBsb3QgSSwgbWVzc2FnZT1GQUxTRSwgaW5jbHVkZT1GQUxTRSwgcmVzdWx0cz1GQUxTRSwgZmlnLndpZHRoID0gMTIsIGZpZy5oZWlnaHQgPSA1fQ0KIyBQbG90DQpjaGFydF90aSA8LSBkZl9tYWluX2NhdCAlPiUNCiAgZ2dwbG90KGFlcyh4PXllYXIsIHk9Z3Jvc3NfaW52X2NoYWluLCBmaWxsPWNhdGVnb3J5KSkgKw0KICBnZW9tX2FyZWEoKSsNCiAgZ2d0aXRsZSgiQmFzaWMgSW5mcmFzdHJ1Y3R1cmVzIEludmVzdG1lbnRzICgkKSIpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwoYnJlYWtzPWRmX21haW5fY2F0JGNhdGVnb3J5LHZhbHVlcz1kZl9tYWluX2NhdCRjb2xvckwpKw0KICBzY2FsZV9jb2xvcl9tYW51YWwoYnJlYWtzPWRmX21haW5fY2F0JGNhdGVnb3J5LHZhbHVlcz1kZl9tYWluX2NhdCRjb2xvckwpKw0KICB5bGFiKCJUb3RhbCAkIGluIEluZnJhc3RydWN0dXJlIEludmVzdG1lbnQiKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0idG9wIiwgbGVnZW5kLnRpdGxlPWVsZW1lbnRfYmxhbmsoKSkrDQogIGFubm90YXRlKGdlb20gPSAic2VnbWVudCIsIHg9MTk0Nyx4ZW5kPTIwMTcsIHk9NjAwMDAwLHllbmQ9NjAwMDAwLCBjb2xvcj0iIzM0M2E0MCIpKw0KICBhbm5vdGF0ZShnZW9tID0gInNlZ21lbnQiLCB4PTE5NDcseGVuZD0yMDE3LCB5PTMwMDAwMCx5ZW5kPTMwMDAwMCwgY29sb3I9IiMzNDNhNDAiKSsNCiAgYW5ub3RhdGUoZ2VvbSA9ICJ0ZXh0IiwgeD0xOTQ3LCB5PTYzMDAwMCwgbGFiZWw9IjYwMCBiaWxsaW9ucyAkIiwgY29sb3I9IiMzNDNhNDAiLA0KICAgICAgICAgICAgaGp1c3Q9MCwgc2l6ZT02LGZhbWlseT1mb250ZmFtaWx5KSsNCiAgYW5ub3RhdGUoZ2VvbSA9ICJ0ZXh0IiwgeD0xOTQ3LCB5PTMzMDAwMCwgbGFiZWw9IjMwMCBiaWxsaW9ucyAkIiwgY29sb3I9IiMzNDNhNDAiLA0KICAgICAgICAgICAgaGp1c3Q9MCwgc2l6ZT02LGZhbWlseT1mb250ZmFtaWx5KSsNCiAgdHJhbnNpdGlvbl9yZXZlYWwoeWVhcikNCg0KYW5pbWF0ZShjaGFydF90aSwgaGVpZ2h0ID0gNTAwLCB3aWR0aCA9OTAwKQ0KYW5pbV9zYXZlKCJjaGFydF90aS5naWYiKQ0KDQpgYGANCg0KDQoNCg0KDQpgYGB7ciBtZXNzYWdlPVRSVUUsIHdhcm5pbmc9RkFMU0UsIGZpZy53aWR0aCA9IDEyLCBmaWcuaGVpZ2h0ID0gNX0NCmNoYXJ0X2xpbmVzIDwtIGRmX21haW5fY2F0ICU+JQ0KICBnZ3Bsb3QoYWVzKHg9eWVhciwgeT1ncm9zc19pbnZfY2hhaW4pKSArDQogIGdlb21fbGluZShhZXMoY29sb3I9Y2F0ZWdvcnkpKSsNCiAgZ2VvbV9wb2ludChhZXMoY29sb3I9Y2F0ZWdvcnkpKSsNCiAgZ3VpZGVzKGZpbGw9RkFMU0UsIGNvbG9yPUZBTFNFKSsNCiAgdGhlbWVfbWluaW1hbCgpKw0KICBzY2FsZV9jb2xvcl9tYW51YWwoYnJlYWtzPWRmX21haW5fY2F0JGNhdGVnb3J5LHZhbHVlcz1kZl9tYWluX2NhdCRjb2xvckwpKw0KICB5bGFiKCJUb3RhbCAkIGluIEluZnJhc3RydWN0dXJlIEludmVzdG1lbnQiKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIsIGxlZ2VuZC50aXRsZT1lbGVtZW50X2JsYW5rKCkpDQoNCg0KY2hhcnRfYXJlYSA8LSBkZl9tYWluX2NhdCAlPiUNCiAgZ2dwbG90KGFlcyh4PXllYXIsIHk9Z3Jvc3NfaW52X2NoYWluLCBmaWxsPWNhdGVnb3J5KSkgKw0KICBnZW9tX2FyZWEoKSsNCiAgc2NhbGVfZmlsbF9tYW51YWwoYnJlYWtzPWRmX21haW5fY2F0JGNhdGVnb3J5LHZhbHVlcz1kZl9tYWluX2NhdCRjb2xvckwpKw0KICBzY2FsZV9jb2xvcl9tYW51YWwoYnJlYWtzPWRmX21haW5fY2F0JGNhdGVnb3J5LHZhbHVlcz1kZl9tYWluX2NhdCRjb2xvckwpKw0KICB5bGFiKCJJbmZyYXN0cnVjdHVyZSBJbnZlc3RtZW50ICgkKSBwZXIgY2F0ZWdvcnkiKSArDQogIGd1aWRlcyhmaWxsPUZBTFNFLCBjb2xvcj1GQUxTRSkrDQogIHRoZW1lX21pbmltYWwoKSsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIiwgbGVnZW5kLnRpdGxlPWVsZW1lbnRfYmxhbmsoKSkrDQogIGFubm90YXRlKGdlb20gPSAic2VnbWVudCIsIHg9MTk0Nyx4ZW5kPTIwMTcsIHk9NjAwMDAwLHllbmQ9NjAwMDAwLCBjb2xvcj0iIzM0M2E0MCIpKw0KICBhbm5vdGF0ZShnZW9tID0gInNlZ21lbnQiLCB4PTE5NDcseGVuZD0yMDE3LCB5PTMwMDAwMCx5ZW5kPTMwMDAwMCwgY29sb3I9IiMzNDNhNDAiKSsNCiAgYW5ub3RhdGUoZ2VvbSA9ICJ0ZXh0IiwgeD0xOTQ3LCB5PTYzMDAwMCwgbGFiZWw9IjYwMCBiaWxsaW9ucyAkIiwgY29sb3I9IiMzNDNhNDAiLA0KICAgICAgICAgICAgaGp1c3Q9MCwgc2l6ZT02LGZhbWlseT1mb250ZmFtaWx5KSsNCiAgYW5ub3RhdGUoZ2VvbSA9ICJ0ZXh0IiwgeD0xOTQ3LCB5PTMzMDAwMCwgbGFiZWw9IjMwMCBiaWxsaW9ucyAkIiwgY29sb3I9IiMzNDNhNDAiLA0KICAgICAgICAgICAgaGp1c3Q9MCwgc2l6ZT02LGZhbWlseT1mb250ZmFtaWx5KQ0KICANCiAgDQpgYGANCiMgIVtdKGNoYXJ0X3RpLmdpZikNCg0KYGBge3IgbWVzc2FnZT1UUlVFLCB3YXJuaW5nPUZBTFNFLCBmaWcud2lkdGggPSAxMiwgZmlnLmhlaWdodCA9IDV9DQpnZ2FycmFuZ2UoY2hhcnRfYXJlYSwgY2hhcnRfbGluZXMsIG5jb2wgPSAyLCBoZWlnaHRzID0gYygxMCwgMTApLCBhbGlnbiA9ICJ2IikNCmBgYA0KDQoNCiMgSW5mcmFzdHJ1Y3R1cmUgSW52ZXN0bWVudCBCcmVha2Rvd24gKHNhbmtleSkNCg0KV2UgYWxyZWFkeSBrbm93IGhvdyB0aGUgbW9uZXkgaXMgaW52ZXN0ZWQgaW4gdGhlIHRocmVlIG1haW4gY2F0ZWdvcmllcyAoYmFzaWMsIHNvY2lhbCBhbmQgZGlnaXRhbCkgc28gbGV0J3MgYnJlYWsgaXQgZG93biBpbiBvcmRlciB0byBzZWUgaG93IG11Y2ggbW9uZXkgaXMgaW52ZXN0ZWQgaW4gZWFjaCBzdWJjYXRlZ29yeS4gDQoNCkluIG9yZGVyIHRvIGRvIHRoYXQsIFNhbmtleSAoKikgY2hhcnRzIGFyZSBhIHZpYWJsZSBvcHRpb24uDQoNCkZvbGxvd2luZyB0aGUgR29vZ2xlIENoYXJ0cyBkZWZpbml0aW9uLCAqYSBzYW5rZXkgZGlhZ3JhbSBpcyBhIHZpc3VhbGl6YXRpb24gdXNlZCB0byBkZXBpY3QgYSBmbG93IGZyb20gb25lIHNldCBvZiB2YWx1ZXMgdG8gYW5vdGhlci4gVGhlIHRoaW5ncyBiZWluZyBjb25uZWN0ZWQgYXJlIGNhbGxlZCBub2RlcyBhbmQgdGhlIGNvbm5lY3Rpb25zIGFyZSBjYWxsZWQgbGlua3MuIFNhbmtleXMgYXJlIGJlc3QgdXNlZCB3aGVuIHlvdSB3YW50IHRvIHNob3cgYSBtYW55LXRvLW1hbnkgbWFwcGluZyBiZXR3ZWVuIHR3byBkb21haW5zLioNCg0KU3BsaXR0aW5nIHRoZSBkYXRhc2V0IGluIGRpZmZlcmVudCBsZXZlbHMgd2lsbCBiZSBuZWNlc3NhcnkgZm9yIGdlbmVyYXRpbmcgdGhlIFNhbmtleSBjaGFydCAoc3BvaWxlciBhbGVydDogVGhlcmUgYXJlIHRocmVlIGRpZmZlcmVudCBsZXZlbHMgcmVnYXJkaW5nIHRoZSBpbnZlc3RtZW50cykuIEluIG9yZGVyIHRvIGRvIHRoYXQ6DQoNCiogKipMZXZlbCAxOioqIFdlIHdpbGwgc3RhcnQgYW5hbHl6aW5nIGZyb20gdGhlIGBtZXRhX2NhdGAgdG8gdGhlIGBjYXRlZ29yeWAgd2hlbiBjYXRlZ29yeSBpcyBvbmUgb2YgdGhlIHRocmVlIG1haW4gY2F0ZWdvcmllczogQmFzaWMsIFNvY2lhbCBvciBEaWdpdGFsLiBUaGF0J3MgYmVjYXVzZSBgVG90YWwgaW5mcmFzdHJ1Y3R1cmVgIHdpbGwgYmUgb3VyIHJvb3Qgbm9kZS4NCg0KKiAqKkZyb20gTGV2ZWwgMiB0byBMZXZlbCAzOioqIFdlIHdpbGwgdXNlIGBtZXRhX2NhdGAgdXNpbmcgdGhlIGNhdGVnb3JpZXMgZnJvbSB0aGUgcHJldmlvdXMgbGV2ZWwgaW4gb3JkZXIgdG8gZ2V0IHRoZSBuZXcgbm9kZXMgYW5kIHNvIG9uIGFuZCAgc28gZm9ydGguDQoNCmBgYHtyIEludkJyZWFrZG93biAtIERhdGEgV3JhbmdsaW5nIEksIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpvcHRpb25zKGRwbHlyLnN1bW1hcmlzZS5pbmZvcm0gPSBGQUxTRSkNCg0KIyBSZW1lbWJlcjogV2UgbmVlZCB0byByZW1vdmUgdGhlIGZ1bmQgc291cmNlcw0KZGZjaF9ncnAgPC0gY2hpbnZlc3RtZW50ICU+JSANCiAgZ3JvdXBfYnkoY2F0ZWdvcnksIG1ldGFfY2F0LCBncm91cF9udW0pICU+JQ0KICBmaWx0ZXIoIShjYXRlZ29yeSAlaW4lIGMoIkZlZGVyYWwiLCAiUyZMIiwgIlByaXZhdGUiKSkgJihncm91cF9udW0hPTE0KSkgICAlPiUNCiAgc3VtbWFyaXNlKGludiA9IHN1bShncm9zc19pbnZfY2hhaW4pKQ0KDQpkZmNoX2dycCA8LSBkZmNoX2dycCAlPiUNCiAgICAgIG11dGF0ZSgNCiAgICAgICAgY2F0ZWdvcnkgPSBjYXNlX3doZW4oDQogICAgICAgIGNhdGVnb3J5ID09ICJUb3RhbCBiYXNpYyBpbmZyYXN0cnVjdHVyZSJ+IkJhc2ljIiwNCiAgICAgICAgY2F0ZWdvcnkgPT0gIlRvdGFsIGRpZ2l0YWwgaW5mcmFzdHJ1Y3R1cmUifiJEaWdpdGFsIiwNCiAgICAgICAgY2F0ZWdvcnkgPT0gIlRvdGFsIHNvY2lhbCBpbmZyYXN0cnVjdHVyZSJ+IlNvY2lhbCIsDQogICAgICAgIFRSVUUgfmNhdGVnb3J5DQogICAgICAgICksIG1ldGFfY2F0ID1jYXNlX3doZW4oDQogICAgICAgICAgbWV0YV9jYXQgPT0gIlRvdGFsIGJhc2ljIGluZnJhc3RydWN0dXJlIn4iQmFzaWMiLA0KICAgICAgICAgIFRSVUUgfm1ldGFfY2F0DQogICAgICAgICkNCiAgICApDQoNCiMgZGZjaF9ncnAkY2F0ZWdvcnkgPC0gYXMuZmFjdG9yKGRmY2hfZ3JwJGNhdGVnb3J5KQ0KIyBkZmNoX2dycCRtZXRhX2NhdCA8LSBhcy5mYWN0b3IoZGZjaF9ncnAkbWV0YV9jYXQpDQojIExldmVsIDE6IFRvdGFsIGluZnJhc3RydWN0dXJlID0+IFRvdGFsIGJhc2ljL3NvY2lhbC9kaWdpdGFsIGluZnJhc3RydWN0dXJlDQpsdmwxIDwtIGRmY2hfZ3JwICU+JSANCiAgICAgIGZpbHRlcihtZXRhX2NhdCAlaW4lICJUb3RhbCBpbmZyYXN0cnVjdHVyZSIpDQoNCg0KbHZsMiA8LSBkZmNoX2dycCAlPiUgZmlsdGVyKG1ldGFfY2F0ICVpbiUgYygNCiAgICAgICJCYXNpYyIsDQogICAgICAiRGlnaXRhbCIsDQogICAgICAiU29jaWFsIg0KICApKQ0KDQoNCg0KbHZsMyA8LSBkZmNoX2dycCAlPiUgZmlsdGVyKG1ldGFfY2F0ICVpbiUgbHZsMiRjYXRlZ29yeSkNCmxhYmVsc1YgPC0gYyh1bmlxdWUobHZsMSRtZXRhX2NhdCksIHVuaXF1ZShsdmwyJG1ldGFfY2F0KSwgdW5pcXVlKGx2bDIkY2F0ZWdvcnkpLHVuaXF1ZShsdmwzJGNhdGVnb3J5KSkNCg0Kc291cmNlViA8LWMobWF0Y2gobHZsMSRtZXRhX2NhdCwgbGFiZWxzKSwgbWF0Y2gobHZsMiRtZXRhX2NhdCxsYWJlbHMpLCBtYXRjaChsdmwzJG1ldGFfY2F0LGxhYmVscykpDQp0YXJnZXRWIDwtIGMobWF0Y2gobHZsMSRjYXRlZ29yeSwgbGFiZWxzKSwgbWF0Y2gobHZsMiRjYXRlZ29yeSxsYWJlbHMpLCBtYXRjaChsdmwzJGNhdGVnb3J5LGxhYmVscykpDQp2YWx1ZVYgPC0gYyhsdmwxJGludiwgbHZsMiRpbnYsIGx2bDMkaW52KQ0KICAgICAgICAgICAgIA0KDQojIGx2bDENCiMgbHZsMg0KIyBsdmwzDQoNCmBgYA0KDQoNCg0KYGBge3IgSW52QnJlYWtkb3duIC0gUGxvdHRpbmcsIGVjaG89RkFMU0UsIGZpZy5oZWlnaHQ9NiwgZmlnLndpZHRoPTgsIHdhcm5pbmc9RkFMU0V9DQoNCmZpZ19zYW5rZXkgPC0gcGxvdF9seSgNCiAgICB0eXBlID0gInNhbmtleSIsDQogICAgb3JpZW50YXRpb24gPSAiaCIsDQogIA0KICAgIG5vZGUgPSBsaXN0KA0KICAgICAgbGFiZWwgPSBsYWJlbHNWLA0KICAgICAgIyBjb2xvciA9IGMoImJsdWUiLCAiYmx1ZSIsICJibHVlIiwgImJsdWUiLCAiYmx1ZSIsICJibHVlIiksDQogICAgICBwYWQgPSAxNSwNCiAgICAgIHRoaWNrbmVzcyA9IDIwLA0KICAgICAgbGluZSA9IGxpc3QoDQogICAgICAgIGNvbG9yID0gImJsYWNrIiwNCiAgICAgICAgd2lkdGggPSAwLjUNCiAgICAgICkNCiAgICApLA0KICBsaW5rID0gbGlzdCgNCiAgICBzb3VyY2UgPSBzb3VyY2VWLTEsDQogICAgdGFyZ2V0ID0gdGFyZ2V0Vi0xLA0KICAgIHZhbHVlID0gdmFsdWVWDQogICkNCikNCg0KZmlnX3NhbmtleSA8LSBmaWdfc2Fua2V5ICU+JSBsYXlvdXQoDQogIHRpdGxlPSdVU0EgSW5mcmFlc3RydWN0dXJlIEludmVzdG1lbnQgQnJlYWtkb3duICgkKScsDQogIGZvbnQgPSBsaXN0KHNpemU9MTApDQopDQoNCmZpZ19zYW5rZXkNCg0KYGBgDQoNCg==