1 Initial Data Preparation in RStudio

1.1 Obtaining Data for Analysis

The National Health and Nutrition Survey data as subsetted for use in Hosmer and Lemeshow’s (2000) Applied Logistic Regression: Second edition was obtained for use in this analysis. This data has been compiled by the Centers for Disease Control (CDC) with the intent to assess the health and nutritional status of both adults and children in the United States. Additional information regarding the NHANES can be found at https://www.cdc.gov/nchs/nhanes/about_nhanes.htm.


1.2 Reviewing the Data Structure

Prior to reading the data into RStudio, the accompanying data definitions were reviewed to obtain a preliminary understanding of the data type (categorical, numerical, logical). A copy of the category definitions and data details are included below for easy reference.

include_url("https://nlepera.github.io/sta553/w10_tableau_dashboard/data/nhanes_details.pdf")


1.3 Preparing the Data

Once the preliminary definitions were reviewed, the NHANES data was downloaded and read into RStudio to create a data frame entitled NHANES.raw.

NHANES.raw <- read.csv("https://nlepera.github.io/sta553/w10_tableau_dashboard/data/nhanes.csv")

str(NHANES.raw)
'data.frame':   7927 obs. of  16 variables:
 $ X          : int  3 5 6 7 10 12 15 19 20 22 ...
 $ obs        : int  9 11 19 34 48 51 55 70 71 73 ...
 $ psu        : int  2 2 1 1 1 1 2 1 1 1 ...
 $ stratum    : int  43 40 35 13 24 28 44 9 43 29 ...
 $ stat.weight: num  19452 1246 3861 5032 26919 ...
 $ age        : int  48 48 44 42 56 44 48 63 37 42 ...
 $ sex        : int  0 1 1 0 0 1 1 1 0 1 ...
 $ race       : int  1 1 2 2 1 1 1 2 1 3 ...
 $ body.weight: num  150 155 190 126 240 ...
 $ height     : num  61.8 66.2 70.2 62.6 67.6 71.1 68 67.8 61.7 68.4 ...
 $ avg.sbp    : int  131 120 133 100 128 130 155 137 128 148 ...
 $ avg.dbp    : int  73 70 85 67 73 86 91 68 70 83 ...
 $ past.smk   : int  1 1 1 1 1 1 1 1 1 1 ...
 $ current.smk: int  2 2 1 1 2 1 1 1 1 1 ...
 $ cholestrol : int  236 260 187 216 156 162 212 186 212 267 ...
 $ hbp        : int  0 0 0 0 0 0 1 0 0 1 ...
DT::datatable(NHANES.raw, fillContainer = TRUE, options = list(pageLength = 10, scrollY = "100eh"))



As described in the data definitions document, the first two columns of NHANES.raw, entitled NHANES.raw$X and NHANES.raw$obs include junk data that must be removed. Both columns are observation IDs which will serve no analytic purpose. A new data frame entitled NHANES was created as as subset of NHANES.raw without the observation IDs and junk values removed.

NHANES <- subset(NHANES.raw, select = -c(X, obs)) %>% 
  mutate(sex = 
           case_when(sex == 0 ~ 'Female',
                     sex == 1 ~ 'Male'),
         race = 
           case_when(race == 1 ~ 'White',
                     race == 2 ~ 'Black',
                     race == 3 ~ 'Other'),
         past.smk = 
           case_when(past.smk == 1 ~ 'Yes',
                     past.smk == 2 ~ 'No'),
         current.smk = 
           case_when(current.smk == 1 ~ 'Yes',
                     current.smk == 2 ~ 'No'),
         hbp = 
           case_when(hbp == 0 ~ 'No',
                     hbp == 1 ~ 'Yes'))

str(NHANES)
'data.frame':   7927 obs. of  14 variables:
 $ psu        : int  2 2 1 1 1 1 2 1 1 1 ...
 $ stratum    : int  43 40 35 13 24 28 44 9 43 29 ...
 $ stat.weight: num  19452 1246 3861 5032 26919 ...
 $ age        : int  48 48 44 42 56 44 48 63 37 42 ...
 $ sex        : chr  "Female" "Male" "Male" "Female" ...
 $ race       : chr  "White" "White" "Black" "Black" ...
 $ body.weight: num  150 155 190 126 240 ...
 $ height     : num  61.8 66.2 70.2 62.6 67.6 71.1 68 67.8 61.7 68.4 ...
 $ avg.sbp    : int  131 120 133 100 128 130 155 137 128 148 ...
 $ avg.dbp    : int  73 70 85 67 73 86 91 68 70 83 ...
 $ past.smk   : chr  "Yes" "Yes" "Yes" "Yes" ...
 $ current.smk: chr  "No" "No" "Yes" "Yes" ...
 $ cholestrol : int  236 260 187 216 156 162 212 186 212 267 ...
 $ hbp        : chr  "No" "No" "No" "No" ...



DT::datatable(NHANES, fillContainer = TRUE, options = list(pageLength = 10, scrollY = "100eh"))


This cleaned data was then exported and uploaded to both Github for retention and Tableau for transformation into a dashboard and story point.


write.xlsx(NHANES, "C:/Users/natal/OneDrive/Documents/School Files/Spring 2024/STA553 - Data Visualization/sta553/w10_tableau_dashboard/data/NHANES_clean.xlsx", row.names=FALSE )


2 Tableau

2.1 Additional Data Cleaning and Preparation

Prior to creating any form of data visualization from the NHANES data loaded into Tableau, the associated column names were manually updated per the data definitions outlined in section 1.2. A custom column entitled Smoker Status was created utilizing the conditional outcomes as outlined in item 14 of the data definitions.

2.2 Dashboard

include_url("https://prod-useast-b.online.tableau.com/t/nl10316570740a22d2e/views/NHANESHealthData/SmokingDashboard")

backup link: https://prod-useast-b.online.tableau.com/t/nl10316570740a22d2e/views/NHANESHealthData/SmokingDashboard


2.3 Story Point

include_url("https://prod-useast-b.online.tableau.com/t/nl10316570740a22d2e/views/NHANESHealthData/SmokingHealth/cb399a51-270e-4a8f-bd5a-f823c572f2ba/4832462d-0878-4cb4-84c1-8180523a00de")

backup link: https://prod-useast-b.online.tableau.com/t/nl10316570740a22d2e/views/NHANESHealthData/SmokingHealth/6f718b87-b23d-47d4-a3bd-658d75f4911a/ac3a98ef-a991-482e-a889-fca8e3de9bc2

LS0tDQp0aXRsZTogIlRoZSBTbW9raW5nIEd1bjogTkhBTkVTIEhlYWx0aCBEYXRhIg0KYXV0aG9yOiAiTmF0YWxpZSBMZVBlcmEiDQpkYXRlOiAiU1RBIDU1MyA8YnI+IFdlc3QgQ2hlc3RlciBVbml2ZXJzaXR5Ig0Kb3V0cHV0OiANCiAgaHRtbF9kb2N1bWVudDogDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6IDQNCiAgICB0b2NfZmxvYXQ6IHllcw0KICAgIHRvY19jb2xsYXBzZWQ6IHllcw0KICAgIGNvZGVfZm9sZGluZzogaGlkZQ0KICAgIGNvZGVfZG93bmxvYWQ6IHllcw0KICAgIHNtb290aF9zY3JvbGw6IHllcw0KICAgIG51bWJlcl9zZWN0aW9uczogeWVzDQogICAgdGhlbWU6IHJlYWRhYmxlDQotLS0NCiAgICAgIA0KDQo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPg0KZGl2I1RPQyBsaSB7DQogICAgbGlzdC1zdHlsZTpub25lOw0KICAgIGJhY2tncm91bmQtaW1hZ2U6bm9uZTsNCiAgICBiYWNrZ3JvdW5kLXJlcGVhdDpub25lOw0KICAgIGJhY2tncm91bmQtcG9zaXRpb246MDsNCn0NCmgxLnRpdGxlIHsNCiAgZm9udC1zaXplOiAyNHB4Ow0KICBjb2xvcjogRGFya1JlZDsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KaDQuYXV0aG9yIHsgDQogIC8qIEhlYWRlciA0IC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogIGZvbnQtc2l6ZTogMThweDsNCiAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogIGNvbG9yOiBEYXJrUmVkOw0KICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQpoNC5kYXRlIHsgDQogIC8qIEhlYWRlciA0IC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogIGZvbnQtc2l6ZTogMThweDsNCiAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogIGNvbG9yOiBEYXJrQmx1ZTsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KaDEgeyANCiAgICAvKiBIZWFkZXIgMyAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICAgIGZvbnQtc2l6ZTogMjJweDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogZGFya3JlZDsNCiAgICB0ZXh0LWFsaWduOiBjZW50ZXI7DQp9DQpoMiB7IA0KICAgIC8qIEhlYWRlciAzIC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAxOHB4Ow0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBuYXZ5Ow0KICAgIHRleHQtYWxpZ246IGxlZnQ7DQp9DQpoMyB7IA0KICAgIC8qIEhlYWRlciAzIC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAxNXB4Ow0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBkYXJrcmVkOw0KICAgIGZvbnQtZmFjZTogYm9sZDsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KaDQgeyANCiAgICAvKiBIZWFkZXIgNCAtIGFuZCB0aGUgYXV0aG9yIGFuZCBkYXRhIGhlYWRlcnMgdXNlIHRoaXMgdG9vICAqLw0KICAgIGZvbnQtc2l6ZTogMThweDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogZGFya3JlZDsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KICAgLyogY2VudGVyIG1hcHMgdXNpbmcgY2h1bmsgb3B0aW9uOiBmaWcuYWxpZ249J2NlbnRlcicgKi8NCi5odG1sLXdpZGdldCB7DQogICAgbWFyZ2luOiBhdXRvOw0KfQ0KPC9zdHlsZT4NCg0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCiMgY29kZSBjaHVuayBzcGVjaWZpZXMgd2hldGhlciB0aGUgUiBjb2RlLCB3YXJuaW5ncywgYW5kIG91dHB1dCANCiMgd2lsbCBiZSBpbmNsdWRlZCBpbiB0aGUgb3V0cHV0IGZpbGVzLg0Kb3B0aW9ucyhyZXBvcyA9IGxpc3QoQ1JBTj0iaHR0cDovL2NyYW4ucnN0dWRpby5jb20vIikpDQppZiAoIXJlcXVpcmUoInRpZHl2ZXJzZSIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJ0aWR5dmVyc2UiKQ0KICAgbGlicmFyeSh0aWR5dmVyc2UpDQp9DQppZiAoIXJlcXVpcmUoImtuaXRyIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoImtuaXRyIikNCiAgIGxpYnJhcnkoa25pdHIpDQp9DQppZiAoIXJlcXVpcmUoInNmIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoInNmIikNCiAgIGxpYnJhcnkoc2YpDQp9DQppZiAoIXJlcXVpcmUoImNvd3Bsb3QiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygiY293cGxvdCIpDQogICBsaWJyYXJ5KGNvd3Bsb3QpDQp9DQppZiAoIXJlcXVpcmUoImxhdGV4MmV4cCIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJsYXRleDJleHAiKQ0KICAgbGlicmFyeShsYXRleDJleHApDQp9DQppZiAoIXJlcXVpcmUoInBsb3RseSIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJwbG90bHkiKQ0KICAgbGlicmFyeShwbG90bHkpDQp9DQppZiAoIXJlcXVpcmUoImdhcG1pbmRlciIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJnYXBtaW5kZXIiKQ0KICAgbGlicmFyeShnYXBtaW5kZXIpDQp9DQppZiAoIXJlcXVpcmUoInBuZyIpKSB7DQogICAgaW5zdGFsbC5wYWNrYWdlcygicG5nIikgICAgICAgICAgICAgIyBJbnN0YWxsIHBuZyBwYWNrYWdlDQogICAgbGlicmFyeSgicG5nIikNCn0NCmlmICghcmVxdWlyZSgiUkN1cmwiKSkgew0KICAgIGluc3RhbGwucGFja2FnZXMoIlJDdXJsIikgICAgICAgICAgICMgSW5zdGFsbCBSQ3VybCBwYWNrYWdlDQogICAgbGlicmFyeSgiUkN1cmwiKQ0KfQ0KaWYgKCFyZXF1aXJlKCJjb2xvdXJwaWNrZXIiKSkgew0KICAgIGluc3RhbGwucGFja2FnZXMoImNvbG91cnBpY2tlciIpICAgICAgICAgICAgICANCiAgICBsaWJyYXJ5KCJjb2xvdXJwaWNrZXIiKQ0KfQ0KaWYgKCFyZXF1aXJlKCJnaWZza2kiKSkgew0KICAgIGluc3RhbGwucGFja2FnZXMoImdpZnNraSIpICAgICAgICAgICAgICANCiAgICBsaWJyYXJ5KCJnaWZza2kiKQ0KfQ0KaWYgKCFyZXF1aXJlKCJtYWdpY2siKSkgew0KICAgIGluc3RhbGwucGFja2FnZXMoIm1hZ2ljayIpICAgICAgICAgICAgICANCiAgICBsaWJyYXJ5KCJtYWdpY2siKQ0KfQ0KaWYgKCFyZXF1aXJlKCJnckRldmljZXMiKSkgew0KICAgIGluc3RhbGwucGFja2FnZXMoImdyRGV2aWNlcyIpICAgICAgICAgICAgICANCiAgICBsaWJyYXJ5KCJnckRldmljZXMiKQ0KfQ0KIyMjIGdncGxvdCBhbmQgZXh0ZW5zaW9ucw0KaWYgKCFyZXF1aXJlKCJnZ3Bsb3QyIikpIHsNCiAgICBpbnN0YWxsLnBhY2thZ2VzKCJnZ3Bsb3QyIikgICAgICAgICAgICAgIA0KICAgIGxpYnJhcnkoImdncGxvdDIiKQ0KfQ0KaWYgKCFyZXF1aXJlKCJnZ2FuaW1hdGUiKSkgew0KICAgIGluc3RhbGwucGFja2FnZXMoImdnYW5pbWF0ZSIpICAgICAgICAgICAgICANCiAgICBsaWJyYXJ5KCJnZ2FuaW1hdGUiKQ0KfQ0KaWYgKCFyZXF1aXJlKCJnZ3JpZGdlcyIpKSB7DQogICAgaW5zdGFsbC5wYWNrYWdlcygiZ2dyaWRnZXMiKSAgICAgICAgICAgICAgDQogICAgbGlicmFyeSgiZ2dyaWRnZXMiKQ0KfQ0KaWYgKCFyZXF1aXJlKCJncmFwaGljcyIpKSB7DQogICAgaW5zdGFsbC5wYWNrYWdlcygiZ3JhcGhpY3MiKSAgICAgICAgICAgICAgDQogICAgbGlicmFyeSgiZ3JhcGhpY3MiKQ0KfQ0KaWYgKCFyZXF1aXJlKCJvcGVueGxzeCIpKSB7DQogICAgaW5zdGFsbC5wYWNrYWdlcygib3Blbnhsc3giKSAgICAgICAgICAgICAgDQogICAgbGlicmFyeSgib3Blbnhsc3giKQ0KfQ0KDQppZiAoIXJlcXVpcmUoImx1YnJpZGF0ZSIpKSB7DQogICAgaW5zdGFsbC5wYWNrYWdlcygibHVicmlkYXRlIikgICAgICAgICAgICAgIA0KICAgIGxpYnJhcnkoImx1YnJpZGF0ZSIpDQp9DQppZiAoIXJlcXVpcmUoInJqc29uIikpIHsNCiAgICBpbnN0YWxsLnBhY2thZ2VzKCJyanNvbiIpICAgICAgICAgICAgICANCiAgICBsaWJyYXJ5KCJyanNvbiIpDQp9DQppZiAoIXJlcXVpcmUoImxlYWZsZXQiKSkgew0KICAgIGluc3RhbGwucGFja2FnZXMoImxlYWZsZXQiKSAgICAgICAgICAgICAgDQogICAgbGlicmFyeSgibGVhZmxldCIpDQp9DQppZiAoIXJlcXVpcmUoImxlYWZwb3AiKSkgew0KICAgIGluc3RhbGwucGFja2FnZXMoImxlYWZwb3AiKSAgICAgICAgICAgICAgDQogICAgbGlicmFyeSgibGVhZnBvcCIpDQp9DQppZiAoIXJlcXVpcmUoImh0bWx3aWRnZXRzIikpIHsNCiAgICBpbnN0YWxsLnBhY2thZ2VzKCJodG1sd2lkZ2V0cyIpICAgICAgICAgICAgICANCiAgICBsaWJyYXJ5KCJodG1sd2lkZ2V0cyIpDQp9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsICAgICAgIA0KICAgICAgICAgICAgICAgICAgICAgIHdhcm5pbmcgPSBGQUxTRSwgICANCiAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBUUlVFLCAgIA0KICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBGQUxTRSwNCiAgICAgICAgICAgICAgICAgICAgICBjb21tZW50ID0gTkEpDQpgYGANCg0KIyBJbml0aWFsIERhdGEgUHJlcGFyYXRpb24gaW4gUlN0dWRpbw0KDQojIyBPYnRhaW5pbmcgRGF0YSBmb3IgQW5hbHlzaXMNCg0KVGhlIE5hdGlvbmFsIEhlYWx0aCBhbmQgTnV0cml0aW9uIFN1cnZleSBkYXRhIGFzIHN1YnNldHRlZCBmb3IgdXNlIGluIEhvc21lciBhbmQgTGVtZXNob3figJlzICgyMDAwKSBBcHBsaWVkIExvZ2lzdGljIFJlZ3Jlc3Npb246IFNlY29uZCBlZGl0aW9uIHdhcyBvYnRhaW5lZCBmb3IgdXNlIGluIHRoaXMgYW5hbHlzaXMuICBUaGlzIGRhdGEgaGFzIGJlZW4gY29tcGlsZWQgYnkgdGhlIENlbnRlcnMgZm9yIERpc2Vhc2UgQ29udHJvbCAoQ0RDKSB3aXRoIHRoZSBpbnRlbnQgdG8gYXNzZXNzIHRoZSBoZWFsdGggYW5kIG51dHJpdGlvbmFsIHN0YXR1cyBvZiBib3RoIGFkdWx0cyBhbmQgY2hpbGRyZW4gaW4gdGhlIFVuaXRlZCBTdGF0ZXMuIEFkZGl0aW9uYWwgaW5mb3JtYXRpb24gcmVnYXJkaW5nIHRoZSBOSEFORVMgY2FuIGJlIGZvdW5kIGF0IDxhIGhyZWY9Imh0dHBzOi8vd3d3LmNkYy5nb3YvbmNocy9uaGFuZXMvYWJvdXRfbmhhbmVzLmh0bSI+aHR0cHM6Ly93d3cuY2RjLmdvdi9uY2hzL25oYW5lcy9hYm91dF9uaGFuZXMuaHRtPC9hPi4NCg0KPGJyPg0KDQojIyBSZXZpZXdpbmcgdGhlIERhdGEgU3RydWN0dXJlDQoNClByaW9yIHRvIHJlYWRpbmcgdGhlIGRhdGEgaW50byBSU3R1ZGlvLCB0aGUgYWNjb21wYW55aW5nIGRhdGEgZGVmaW5pdGlvbnMgd2VyZSByZXZpZXdlZCB0byBvYnRhaW4gYSBwcmVsaW1pbmFyeSB1bmRlcnN0YW5kaW5nIG9mIHRoZSBkYXRhIHR5cGUgKGNhdGVnb3JpY2FsLCBudW1lcmljYWwsIGxvZ2ljYWwpLiAgQSBjb3B5IG9mIHRoZSBjYXRlZ29yeSBkZWZpbml0aW9ucyBhbmQgZGF0YSBkZXRhaWxzIGFyZSBpbmNsdWRlZCBiZWxvdyBmb3IgZWFzeSByZWZlcmVuY2UuICANCg0KYGBge3Igb3V0LndpZHRoPSIxMDAlIn0NCmluY2x1ZGVfdXJsKCJodHRwczovL25sZXBlcmEuZ2l0aHViLmlvL3N0YTU1My93MTBfdGFibGVhdV9kYXNoYm9hcmQvZGF0YS9uaGFuZXNfZGV0YWlscy5wZGYiKQ0KYGBgDQoNCjxicj4NCg0KIyMgUHJlcGFyaW5nIHRoZSBEYXRhDQoNCk9uY2UgdGhlIHByZWxpbWluYXJ5IGRlZmluaXRpb25zIHdlcmUgcmV2aWV3ZWQsIHRoZSBOSEFORVMgZGF0YSB3YXMgZG93bmxvYWRlZCBhbmQgcmVhZCBpbnRvIFJTdHVkaW8gdG8gY3JlYXRlIGEgZGF0YSBmcmFtZSBlbnRpdGxlZCBgTkhBTkVTLnJhd2AuDQoNCmBgYHtyfQ0KTkhBTkVTLnJhdyA8LSByZWFkLmNzdigiaHR0cHM6Ly9ubGVwZXJhLmdpdGh1Yi5pby9zdGE1NTMvdzEwX3RhYmxlYXVfZGFzaGJvYXJkL2RhdGEvbmhhbmVzLmNzdiIpDQoNCnN0cihOSEFORVMucmF3KQ0KDQpEVDo6ZGF0YXRhYmxlKE5IQU5FUy5yYXcsIGZpbGxDb250YWluZXIgPSBUUlVFLCBvcHRpb25zID0gbGlzdChwYWdlTGVuZ3RoID0gMTAsIHNjcm9sbFkgPSAiMTAwZWgiKSkNCg0KYGBgDQoNCjxicj4NCjxicj4NCg0KQXMgZGVzY3JpYmVkIGluIHRoZSBkYXRhIGRlZmluaXRpb25zIGRvY3VtZW50LCB0aGUgZmlyc3QgdHdvIGNvbHVtbnMgb2YgYE5IQU5FUy5yYXdgLCBlbnRpdGxlZCBgTkhBTkVTLnJhdyRYYCBhbmQgYE5IQU5FUy5yYXckb2JzYCBpbmNsdWRlIGp1bmsgZGF0YSB0aGF0IG11c3QgYmUgcmVtb3ZlZC4gQm90aCBjb2x1bW5zIGFyZSBvYnNlcnZhdGlvbiBJRHMgd2hpY2ggd2lsbCBzZXJ2ZSBubyBhbmFseXRpYyBwdXJwb3NlLiBBIG5ldyBkYXRhIGZyYW1lIGVudGl0bGVkIGBOSEFORVNgIHdhcyBjcmVhdGVkIGFzIGFzIHN1YnNldCBvZiBgTkhBTkVTLnJhd2Agd2l0aG91dCB0aGUgb2JzZXJ2YXRpb24gSURzIGFuZCBqdW5rIHZhbHVlcyByZW1vdmVkLiAgDQo8YnI+DQoNCmBgYHtyfQ0KTkhBTkVTIDwtIHN1YnNldChOSEFORVMucmF3LCBzZWxlY3QgPSAtYyhYLCBvYnMpKSAlPiUgDQogIG11dGF0ZShzZXggPSANCiAgICAgICAgICAgY2FzZV93aGVuKHNleCA9PSAwIH4gJ0ZlbWFsZScsDQogICAgICAgICAgICAgICAgICAgICBzZXggPT0gMSB+ICdNYWxlJyksDQogICAgICAgICByYWNlID0gDQogICAgICAgICAgIGNhc2Vfd2hlbihyYWNlID09IDEgfiAnV2hpdGUnLA0KICAgICAgICAgICAgICAgICAgICAgcmFjZSA9PSAyIH4gJ0JsYWNrJywNCiAgICAgICAgICAgICAgICAgICAgIHJhY2UgPT0gMyB+ICdPdGhlcicpLA0KICAgICAgICAgcGFzdC5zbWsgPSANCiAgICAgICAgICAgY2FzZV93aGVuKHBhc3Quc21rID09IDEgfiAnWWVzJywNCiAgICAgICAgICAgICAgICAgICAgIHBhc3Quc21rID09IDIgfiAnTm8nKSwNCiAgICAgICAgIGN1cnJlbnQuc21rID0gDQogICAgICAgICAgIGNhc2Vfd2hlbihjdXJyZW50LnNtayA9PSAxIH4gJ1llcycsDQogICAgICAgICAgICAgICAgICAgICBjdXJyZW50LnNtayA9PSAyIH4gJ05vJyksDQogICAgICAgICBoYnAgPSANCiAgICAgICAgICAgY2FzZV93aGVuKGhicCA9PSAwIH4gJ05vJywNCiAgICAgICAgICAgICAgICAgICAgIGhicCA9PSAxIH4gJ1llcycpKQ0KDQpzdHIoTkhBTkVTKQ0KYGBgDQo8YnI+DQo8YnI+DQpgYGB7cn0NCg0KRFQ6OmRhdGF0YWJsZShOSEFORVMsIGZpbGxDb250YWluZXIgPSBUUlVFLCBvcHRpb25zID0gbGlzdChwYWdlTGVuZ3RoID0gMTAsIHNjcm9sbFkgPSAiMTAwZWgiKSkNCg0KYGBgDQoNCjxicj4NCg0KVGhpcyBjbGVhbmVkIGRhdGEgd2FzIHRoZW4gZXhwb3J0ZWQgYW5kIHVwbG9hZGVkIHRvIGJvdGggPGEgaHJlZj0iaHR0cHM6Ly9naXRodWIuY29tL25sZXBlcmEvc3RhNTUzL3RyZWUvbWFpbi93MTBfdGFibGVhdV9kYXNoYm9hcmQvZGF0YSI+R2l0aHViPC9hPiBmb3IgcmV0ZW50aW9uIGFuZCBUYWJsZWF1IGZvciB0cmFuc2Zvcm1hdGlvbiBpbnRvIGEgZGFzaGJvYXJkIGFuZCBzdG9yeSBwb2ludC4gDQoNCjxicj4NCg0KYGBge3IgZWNobz1UUlVFLCBldmFsPUZBTFNFfQ0Kd3JpdGUueGxzeChOSEFORVMsICJDOi9Vc2Vycy9uYXRhbC9PbmVEcml2ZS9Eb2N1bWVudHMvU2Nob29sIEZpbGVzL1NwcmluZyAyMDI0L1NUQTU1MyAtIERhdGEgVmlzdWFsaXphdGlvbi9zdGE1NTMvdzEwX3RhYmxlYXVfZGFzaGJvYXJkL2RhdGEvTkhBTkVTX2NsZWFuLnhsc3giLCByb3cubmFtZXM9RkFMU0UgKQ0KYGBgDQoNCg0KPGJyPg0KDQojIFRhYmxlYXUNCg0KIyMgQWRkaXRpb25hbCBEYXRhIENsZWFuaW5nIGFuZCBQcmVwYXJhdGlvbg0KDQpQcmlvciB0byBjcmVhdGluZyBhbnkgZm9ybSBvZiBkYXRhIHZpc3VhbGl6YXRpb24gZnJvbSB0aGUgYE5IQU5FU2AgZGF0YSBsb2FkZWQgaW50byBUYWJsZWF1LCB0aGUgYXNzb2NpYXRlZCBjb2x1bW4gbmFtZXMgd2VyZSBtYW51YWxseSB1cGRhdGVkIHBlciB0aGUgZGF0YSBkZWZpbml0aW9ucyBvdXRsaW5lZCBpbiBzZWN0aW9uIDEuMi4gIEEgY3VzdG9tIGNvbHVtbiBlbnRpdGxlZCBgU21va2VyIFN0YXR1c2Agd2FzIGNyZWF0ZWQgdXRpbGl6aW5nIHRoZSBjb25kaXRpb25hbCBvdXRjb21lcyBhcyBvdXRsaW5lZCBpbiBpdGVtIDE0IG9mIHRoZSBkYXRhIGRlZmluaXRpb25zLiANCg0KIyMgRGFzaGJvYXJkDQoNCg0KYGBgIHtyLCBvdXQud2lkdGggPSAiMTAwJSJ9DQoNCmluY2x1ZGVfdXJsKCJodHRwczovL3Byb2QtdXNlYXN0LWIub25saW5lLnRhYmxlYXUuY29tL3QvbmwxMDMxNjU3MDc0MGEyMmQyZS92aWV3cy9OSEFORVNIZWFsdGhEYXRhL1Ntb2tpbmdEYXNoYm9hcmQiKQ0KYGBgDQoNCmJhY2t1cCBsaW5rOiA8YSBocmVmPSJodHRwczovL3Byb2QtdXNlYXN0LWIub25saW5lLnRhYmxlYXUuY29tL3QvbmwxMDMxNjU3MDc0MGEyMmQyZS92aWV3cy9OSEFORVNIZWFsdGhEYXRhL1Ntb2tpbmdEYXNoYm9hcmQiPmh0dHBzOi8vcHJvZC11c2Vhc3QtYi5vbmxpbmUudGFibGVhdS5jb20vdC9ubDEwMzE2NTcwNzQwYTIyZDJlL3ZpZXdzL05IQU5FU0hlYWx0aERhdGEvU21va2luZ0Rhc2hib2FyZDwvYT4NCg0KDQoNCjxicj4NCg0KIyMgU3RvcnkgUG9pbnQNCg0KYGBgIHtyLCBvdXQud2lkdGggPSAiMTAwJSJ9DQppbmNsdWRlX3VybCgiaHR0cHM6Ly9wcm9kLXVzZWFzdC1iLm9ubGluZS50YWJsZWF1LmNvbS90L25sMTAzMTY1NzA3NDBhMjJkMmUvdmlld3MvTkhBTkVTSGVhbHRoRGF0YS9TbW9raW5nSGVhbHRoL2NiMzk5YTUxLTI3MGUtNGE4Zi1iZDVhLWY4MjNjNTcyZjJiYS80ODMyNDYyZC0wODc4LTRjYjQtODRjMS04MTgwNTIzYTAwZGUiKQ0KYGBgDQoNCmJhY2t1cCBsaW5rOiA8YSBocmVmPSJodHRwczovL3Byb2QtdXNlYXN0LWIub25saW5lLnRhYmxlYXUuY29tL3QvbmwxMDMxNjU3MDc0MGEyMmQyZS92aWV3cy9OSEFORVNIZWFsdGhEYXRhL1Ntb2tpbmdIZWFsdGgvNmY3MThiODctYjIzZC00N2Q0LWEzYmQtNjU4ZDc1ZjQ5MTFhL2FjM2E5OGVmLWE5OTEtNDgyZS1hODg5LWZjYThlM2RlOWJjMiI+aHR0cHM6Ly9wcm9kLXVzZWFzdC1iLm9ubGluZS50YWJsZWF1LmNvbS90L25sMTAzMTY1NzA3NDBhMjJkMmUvdmlld3MvTkhBTkVTSGVhbHRoRGF0YS9TbW9raW5nSGVhbHRoLzZmNzE4Yjg3LWIyM2QtNDdkNC1hM2JkLTY1OGQ3NWY0OTExYS9hYzNhOThlZi1hOTkxLTQ4MmUtYTg4OS1mY2E4ZTNkZTliYzI8L2E+