dados_leniency = read_csv(here::here("data/leniency.csv"))

-- Column specification ------------------------------------------------------------------
cols(
  smile = col_character(),
  leniency = col_double(),
  with_smile = col_character()
)
glimpse(dados_leniency)
Rows: 136
Columns: 3
$ smile      <chr> "false smile", "false smile", "false smile", "false smile", "false sm~
$ leniency   <dbl> 2.5, 5.5, 6.5, 3.5, 3.0, 3.5, 6.0, 5.0, 4.0, 4.5, 5.0, 5.5, 3.5, 6.0,~
$ with_smile <chr> "yes", "yes", "yes", "yes", "yes", "yes", "yes", "yes", "yes", "yes",~
dados_leniency  %>% 
    skimr::skim()
-- Data Summary ------------------------
                           Values    
Name                       Piped data
Number of rows             136       
Number of columns          3         
_______________________              
Column type frequency:               
  character                2         
  numeric                  1         
________________________             
Group variables            None      

-- Variable type: character --------------------------------------------------------------
# A tibble: 2 x 8
  skim_variable n_missing complete_rate   min   max empty n_unique whitespace
* <chr>             <int>         <dbl> <int> <int> <int>    <int>      <int>
1 smile                 0             1    10    18     0        4          0
2 with_smile            0             1     2     3     0        2          0

-- Variable type: numeric ----------------------------------------------------------------
# A tibble: 1 x 11
  skim_variable n_missing complete_rate  mean    sd    p0   p25   p50   p75  p100 hist 
* <chr>             <int>         <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <chr>
1 leniency              0             1  4.83  1.67     2   3.5   4.5     6     9 ▅▇▆▃▂
dados_leniency %>% 
    drop_na() %>% 
  ggplot(aes(x = leniency)) + 
  facet_wrap(~ smile, ncol = 1) + 
  geom_histogram(binwidth = 0.4, boundary = 0, color = "darkblue", fill = "steelblue") + 
  geom_rug() +
  theme(text=element_text(size=16,  family="serif")) +
        labs(y = "", x = "leniency")

dados_leniency %>% 
    drop_na() %>% 
  ggplot(aes(x = leniency)) + 
  facet_wrap(~ smile, ncol = 1) + 
  geom_density(binwidth = 0.4, boundary = 0, color = "darkblue", fill = "steelblue") + 
  geom_rug() +
  theme(text=element_text(size=16,  family="serif")) +
        labs(y = "", x = "leniency")
Ignoring unknown parameters: binwidth, boundary

dados_leniency %>% 
  group_by(smile) %>% 
  summarise(media = mean(leniency))
dados_smile = dados_leniency %>% 
    filter(with_smile == "yes")
dados_no_smile = dados_leniency %>% 
    filter(with_smile == "no")

Fazendo as estimativas para fotos com sorriso

s <- function(d, i) {
    sumarizado = d %>% 
        slice(i) %>% 
        summarise(media_smile = mean(leniency))
    
    sumarizado %>% 
      pull(media_smile)
}

s(dados_smile, 1:(nrow(dados_smile))) # theta_chapeu
[1] 5.063725
booted <- boot(data = dados_smile, 
               statistic = s, 
               R = 2000)

ci_smile = tidy(booted, 
              conf.level = .95,
              conf.method = "basic",
              conf.int = TRUE)

ci_smile
ci_smile %>% 
  ggplot(aes(
            ymin = conf.low,
            y = statistic,
            ymax = conf.high,
            x = "With Smile"
        )) +
        geom_linerange() +
        geom_point(color = "coral", size = 2) +
        scale_y_continuous(limits = c(0, 10)) +
        labs(x = "", y = "Laninency para fotos com sorriso") +
        coord_flip()

Fazendo as estimativas para fotos sem sorriso

s <- function(d, i) {
    sumarizado = d %>% 
        slice(i) %>% 
        summarise(media_no_smile = mean(leniency))
    
    sumarizado %>% 
      pull(media_no_smile)
}

s(dados_no_smile, 1:(nrow(dados_no_smile))) # theta_chapeu
[1] 4.117647
booted <- boot(data = dados_no_smile, 
               statistic = s, 
               R = 2000)

ci_no_smile = tidy(booted, 
              conf.level = .95,
              conf.method = "basic",
              conf.int = TRUE)

ci_no_smile
ci_no_smile %>% 
  ggplot(aes(
            ymin = conf.low,
            y = statistic,
            ymax = conf.high,
            x = "No smile"
        )) +
        geom_linerange() +
        geom_point(color = "coral", size = 2) +
        scale_y_continuous(limits = c(0, 10)) +
        labs(x = "", y = "Laninency para fotos sem sorriso") +
        coord_flip()

juntando as visualizações

ics_smile_nosmile = rbind(ci_smile, ci_no_smile)
ics_smile_nosmile$smile = c("with_smile", "no_smile")

ics_smile_nosmile
ics_smile_nosmile %>% 
  ggplot(aes(
            ymin = conf.low,
            y = statistic,
            ymax = conf.high,
            x = reorder(smile, statistic)
        )) +
        geom_linerange() +
        geom_point(color = "coral", size = 3) +
        scale_y_continuous(limits = c(0, 10)) +
        labs(x = "", y = "Leniency") +
        coord_flip()

Comparação com e sem sorriso

Diferença

comparacao = dados_leniency 

theta <- function(d, i) {
    agrupado = d %>% 
        slice(i) %>% 
        group_by(with_smile) %>% 
        summarise(media = mean(leniency))
    b = agrupado %>% filter(with_smile == "yes") %>% pull(media)
    l = agrupado %>% filter(with_smile == "no") %>% pull(media)
    l - b
}


theta(comparacao, i = 1:NROW(comparacao))
[1] -0.9460784
ci_comp_smiles = boot(data = comparacao,
           statistic = theta,
           R = 2000) %>%
    tidy(conf.level = .95,
         conf.method = "bca",
         conf.int = TRUE)

ci_comp_smiles
ci_comp_smiles %>% 
  ggplot(aes(
            ymin = conf.low,
            y = statistic,
            ymax = conf.high,
            x = "no smile - with smile"
        )) +
        geom_linerange() +
        geom_point(color = "coral", size = 3) +
        scale_y_continuous(limits = c(-3, 3)) +
        labs(x = "", y = "Leniency") +
        coord_flip()


miserable_smile = dados_leniency %>% 
    filter(smile == "miserable smile")

felt_smile = dados_leniency %>% 
    filter(smile == "felt smile")

false_smile = dados_leniency %>% 
    filter(smile == "false smile")
miserable_smile

miserable

s <- function(d, i) {
    sumarizado = d %>% 
        slice(i) %>% 
        summarise(media = mean(leniency))
    
    sumarizado %>% 
      pull(media)
}

s(miserable_smile, 1:(nrow(miserable_smile))) # theta_chapeu
[1] 4.911765
booted <- boot(data = miserable_smile, 
               statistic = s, 
               R = 2000)

ci_miserable_smile = tidy(booted, 
              conf.level = .95,
              conf.method = "basic",
              conf.int = TRUE)

ci_miserable_smile

felt smile

s <- function(d, i) {
    sumarizado = d %>% 
        slice(i) %>% 
        summarise(media = mean(leniency))
    
    sumarizado %>% 
      pull(media)
}

s(felt_smile, 1:(nrow(felt_smile))) # theta_chapeu
[1] 4.911765
booted <- boot(data = felt_smile, 
               statistic = s, 
               R = 2000)

ci_felt_smile = tidy(booted, 
              conf.level = .95,
              conf.method = "basic",
              conf.int = TRUE)

ci_felt_smile

false smile

s <- function(d, i) {
    sumarizado = d %>% 
        slice(i) %>% 
        summarise(media = mean(leniency))
    
    sumarizado %>% 
      pull(media)
}

s(false_smile, 1:(nrow(false_smile))) # theta_chapeu
[1] 5.367647
booted <- boot(data = false_smile, 
               statistic = s, 
               R = 2000)

ci_false_smile = tidy(booted, 
              conf.level = .95,
              conf.method = "basic",
              conf.int = TRUE)

ci_false_smile

putting together

ics_all_smile = rbind(ci_no_smile, ci_false_smile, ci_felt_smile, ci_miserable_smile)
ics_all_smile$smile = c("no smile", "false smile", "felt smile", "miserable smile")

ics_all_smile
ics_all_smile %>% 
  ggplot(aes(
            ymin = conf.low,
            y = statistic,
            ymax = conf.high,
            x = reorder(smile, statistic)
        )) +
        geom_linerange() +
        geom_point(color = "coral", size = 3) +
        scale_y_continuous(limits = c(2, 7.5)) +
        labs(x = "", y = "Leniency") +
        coord_flip()

Fazendo a diferença

No smile - False Smile

Diferença

comparacao_false_smile = dados_leniency 

theta <- function(d, i) {
    agrupado = d %>% 
        slice(i) %>% 
        group_by(smile) %>% 
        summarise(media = mean(leniency))
    b = agrupado %>% filter(smile == "false smile") %>% pull(media)
    l = agrupado %>% filter(smile == "no smile (control)") %>% pull(media)
    l - b
}


theta(comparacao_false_smile, i = 1:NROW(comparacao_false_smile))
ci_comp_false_smile = boot(data = comparacao_false_smile,
           statistic = theta,
           R = 2000) %>%
    tidy(conf.level = .95,
         conf.method = "bca",
         conf.int = TRUE)

ci_comp_false_smile

No smile - Felt Smile

Diferença

comparacao_felt_smile = dados_leniency 

theta <- function(d, i) {
    agrupado = d %>% 
        slice(i) %>% 
        group_by(smile) %>% 
        summarise(media = mean(leniency))
    b = agrupado %>% filter(smile == "felt smile") %>% pull(media)
    l = agrupado %>% filter(smile == "no smile (control)") %>% pull(media)
    l - b
}


theta(comparacao_felt_smile, i = 1:NROW(comparacao_felt_smile))
ci_comp_felt_smile = boot(data = comparacao_felt_smile,
           statistic = theta,
           R = 2000) %>%
    tidy(conf.level = .95,
         conf.method = "bca",
         conf.int = TRUE)

ci_comp_felt_smile

No smile - Miserable Smile

Diferença

comparacao_miserable_smile = dados_leniency 

theta <- function(d, i) {
    agrupado = d %>% 
        slice(i) %>% 
        group_by(smile) %>% 
        summarise(media = mean(leniency))
    b = agrupado %>% filter(smile == "miserable smile") %>% pull(media)
    l = agrupado %>% filter(smile == "no smile (control)") %>% pull(media)
    l - b
}


theta(comparacao_miserable_smile, i = 1:NROW(comparacao_miserable_smile))
ci_comp_miserable_smile = boot(data = comparacao_miserable_smile,
           statistic = theta,
           R = 2000) %>%
    tidy(conf.level = .95,
         conf.method = "bca",
         conf.int = TRUE)

ci_comp_miserable_smile

visualizando as difereças

ics_diff_smile = rbind(ci_comp_false_smile, ci_comp_felt_smile, ci_comp_miserable_smile)
ics_diff_smile$diff = c("no smile - false smile", "no smile - felt smile", "no smile - miserable smile")

ics_diff_smile
ics_diff_smile %>% 
  ggplot(aes(
            ymin = conf.low,
            y = statistic,
            ymax = conf.high,
            x = reorder(diff, statistic)
        )) +
        geom_linerange() +
        geom_point(color = "coral", size = 3) +
        scale_y_continuous(limits = c(-3, 3)) +
        labs(x = "", y = "Leniency") +
        coord_flip()

Difference entre False smile e Felt smile No smile - Felt Smile

comparacao_felt_miseralbe = dados_leniency 

theta <- function(d, i) {
    agrupado = d %>% 
        slice(i) %>% 
        group_by(smile) %>% 
        summarise(media = mean(leniency))
    b = agrupado %>% filter(smile == "felt smile") %>% pull(media)
    l = agrupado %>% filter(smile == "miserable smile") %>% pull(media)
    l - b
}


theta(comparacao_felt_miseralbe, i = 1:NROW(comparacao_felt_miseralbe))
ci_comparacao_felt_miseralbe = boot(data = comparacao_felt_miseralbe,
           statistic = theta,
           R = 2000) %>%
    tidy(conf.level = .95,
         conf.method = "bca",
         conf.int = TRUE)

ci_comparacao_felt_miseralbe
ci_comparacao_felt_miseralbe%>% 
  ggplot(aes(
            ymin = conf.low,
            y = statistic,
            ymax = conf.high,
            x = "Miserable - Felt"
        )) +
        geom_linerange() +
        geom_point(color = "coral", size = 2) +
        scale_y_continuous(limits = c(-2, 2)) +
        labs(x = "", y = "Leniency") +
        coord_flip()
LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQpgYGB7ciBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KdGhlbWVfc2V0KHRoZW1lX2J3KCkpDQoNCmxpYnJhcnkoYm9vdCkNCmxpYnJhcnkoYnJvb20pDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoaHJicnRoZW1lcykNCg0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KHRpZHkgPSBGQUxTRSwNCiAgICAgICAgICAgICAgICAgICAgICBmaWcud2lkdGggPSA2LA0KICAgICAgICAgICAgICAgICAgICAgIGZpZy5oZWlnaHQgPSA1KQ0KYGBgDQoNCmBgYHtyfQ0KZGFkb3NfbGVuaWVuY3kgPSByZWFkX2NzdihoZXJlOjpoZXJlKCJkYXRhL2xlbmllbmN5LmNzdiIpKQ0KDQpnbGltcHNlKGRhZG9zX2xlbmllbmN5KQ0KYGBgDQoNCmBgYHtyfQ0KZGFkb3NfbGVuaWVuY3kgICU+JSANCiAgICBza2ltcjo6c2tpbSgpDQpgYGANCg0KDQoNCmBgYHtyfQ0KZGFkb3NfbGVuaWVuY3kgJT4lIA0KICAgIGRyb3BfbmEoKSAlPiUgDQogIGdncGxvdChhZXMoeCA9IGxlbmllbmN5KSkgKyANCiAgZmFjZXRfd3JhcCh+IHNtaWxlLCBuY29sID0gMSkgKyANCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAwLjQsIGJvdW5kYXJ5ID0gMCwgY29sb3IgPSAiZGFya2JsdWUiLCBmaWxsID0gInN0ZWVsYmx1ZSIpICsgDQogIGdlb21fcnVnKCkgKw0KICB0aGVtZSh0ZXh0PWVsZW1lbnRfdGV4dChzaXplPTE2LCAgZmFtaWx5PSJzZXJpZiIpKSArDQogICAgICAgIGxhYnMoeSA9ICIiLCB4ID0gImxlbmllbmN5IikNCmBgYA0KDQoNCg0KYGBge3J9DQpkYWRvc19sZW5pZW5jeSAlPiUgDQogICAgZHJvcF9uYSgpICU+JSANCiAgZ2dwbG90KGFlcyh4ID0gbGVuaWVuY3kpKSArIA0KICBmYWNldF93cmFwKH4gc21pbGUsIG5jb2wgPSAxKSArIA0KICBnZW9tX2RlbnNpdHkoYmlud2lkdGggPSAwLjQsIGJvdW5kYXJ5ID0gMCwgY29sb3IgPSAiZGFya2JsdWUiLCBmaWxsID0gInN0ZWVsYmx1ZSIpICsgDQogIGdlb21fcnVnKCkgKw0KICB0aGVtZSh0ZXh0PWVsZW1lbnRfdGV4dChzaXplPTE2LCAgZmFtaWx5PSJzZXJpZiIpKSArDQogICAgICAgIGxhYnMoeSA9ICIiLCB4ID0gImxlbmllbmN5IikNCmBgYA0KDQpgYGB7cn0NCmRhZG9zX2xlbmllbmN5ICU+JSANCiAgZ3JvdXBfYnkoc21pbGUpICU+JSANCiAgc3VtbWFyaXNlKG1lZGlhID0gbWVhbihsZW5pZW5jeSkpDQpgYGANCg0KDQoNCg0KYGBge3J9DQpkYWRvc19zbWlsZSA9IGRhZG9zX2xlbmllbmN5ICU+JSANCiAgICBmaWx0ZXIod2l0aF9zbWlsZSA9PSAieWVzIikNCmBgYA0KDQoNCg0KYGBge3J9DQpkYWRvc19ub19zbWlsZSA9IGRhZG9zX2xlbmllbmN5ICU+JSANCiAgICBmaWx0ZXIod2l0aF9zbWlsZSA9PSAibm8iKQ0KYGBgDQoNCg0KIyMgRmF6ZW5kbyBhcyBlc3RpbWF0aXZhcyBwYXJhIGZvdG9zIGNvbSBzb3JyaXNvDQoNCg0KYGBge3J9DQpzIDwtIGZ1bmN0aW9uKGQsIGkpIHsNCiAgICBzdW1hcml6YWRvID0gZCAlPiUgDQogICAgICAgIHNsaWNlKGkpICU+JSANCiAgICAgICAgc3VtbWFyaXNlKG1lZGlhX3NtaWxlID0gbWVhbihsZW5pZW5jeSkpDQogICAgDQogICAgc3VtYXJpemFkbyAlPiUgDQogICAgICBwdWxsKG1lZGlhX3NtaWxlKQ0KfQ0KDQpzKGRhZG9zX3NtaWxlLCAxOihucm93KGRhZG9zX3NtaWxlKSkpICMgdGhldGFfY2hhcGV1DQpgYGANCg0KYGBge3J9DQpib290ZWQgPC0gYm9vdChkYXRhID0gZGFkb3Nfc21pbGUsIA0KICAgICAgICAgICAgICAgc3RhdGlzdGljID0gcywgDQogICAgICAgICAgICAgICBSID0gMjAwMCkNCg0KY2lfc21pbGUgPSB0aWR5KGJvb3RlZCwgDQogICAgICAgICAgICAgIGNvbmYubGV2ZWwgPSAuOTUsDQogICAgICAgICAgICAgIGNvbmYubWV0aG9kID0gImJhc2ljIiwNCiAgICAgICAgICAgICAgY29uZi5pbnQgPSBUUlVFKQ0KDQpjaV9zbWlsZQ0KYGBgDQoNCg0KDQpgYGB7cn0NCmNpX3NtaWxlICU+JSANCiAgZ2dwbG90KGFlcygNCiAgICAgICAgICAgIHltaW4gPSBjb25mLmxvdywNCiAgICAgICAgICAgIHkgPSBzdGF0aXN0aWMsDQogICAgICAgICAgICB5bWF4ID0gY29uZi5oaWdoLA0KICAgICAgICAgICAgeCA9ICJXaXRoIFNtaWxlIg0KICAgICAgICApKSArDQogICAgICAgIGdlb21fbGluZXJhbmdlKCkgKw0KICAgICAgICBnZW9tX3BvaW50KGNvbG9yID0gImNvcmFsIiwgc2l6ZSA9IDIpICsNCiAgICAgICAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoMCwgMTApKSArDQogICAgICAgIGxhYnMoeCA9ICIiLCB5ID0gIkxhbmluZW5jeSBwYXJhIGZvdG9zIGNvbSBzb3JyaXNvIikgKw0KICAgICAgICBjb29yZF9mbGlwKCkNCmBgYA0KDQoNCiMjIEZhemVuZG8gYXMgZXN0aW1hdGl2YXMgcGFyYSBmb3RvcyBzZW0gc29ycmlzbw0KDQoNCmBgYHtyfQ0KcyA8LSBmdW5jdGlvbihkLCBpKSB7DQogICAgc3VtYXJpemFkbyA9IGQgJT4lIA0KICAgICAgICBzbGljZShpKSAlPiUgDQogICAgICAgIHN1bW1hcmlzZShtZWRpYV9ub19zbWlsZSA9IG1lYW4obGVuaWVuY3kpKQ0KICAgIA0KICAgIHN1bWFyaXphZG8gJT4lIA0KICAgICAgcHVsbChtZWRpYV9ub19zbWlsZSkNCn0NCg0KcyhkYWRvc19ub19zbWlsZSwgMToobnJvdyhkYWRvc19ub19zbWlsZSkpKSAjIHRoZXRhX2NoYXBldQ0KYGBgDQoNCmBgYHtyfQ0KYm9vdGVkIDwtIGJvb3QoZGF0YSA9IGRhZG9zX25vX3NtaWxlLCANCiAgICAgICAgICAgICAgIHN0YXRpc3RpYyA9IHMsIA0KICAgICAgICAgICAgICAgUiA9IDIwMDApDQoNCmNpX25vX3NtaWxlID0gdGlkeShib290ZWQsIA0KICAgICAgICAgICAgICBjb25mLmxldmVsID0gLjk1LA0KICAgICAgICAgICAgICBjb25mLm1ldGhvZCA9ICJiYXNpYyIsDQogICAgICAgICAgICAgIGNvbmYuaW50ID0gVFJVRSkNCg0KY2lfbm9fc21pbGUNCmBgYA0KDQoNCg0KYGBge3J9DQpjaV9ub19zbWlsZSAlPiUgDQogIGdncGxvdChhZXMoDQogICAgICAgICAgICB5bWluID0gY29uZi5sb3csDQogICAgICAgICAgICB5ID0gc3RhdGlzdGljLA0KICAgICAgICAgICAgeW1heCA9IGNvbmYuaGlnaCwNCiAgICAgICAgICAgIHggPSAiTm8gc21pbGUiDQogICAgICAgICkpICsNCiAgICAgICAgZ2VvbV9saW5lcmFuZ2UoKSArDQogICAgICAgIGdlb21fcG9pbnQoY29sb3IgPSAiY29yYWwiLCBzaXplID0gMikgKw0KICAgICAgICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygwLCAxMCkpICsNCiAgICAgICAgbGFicyh4ID0gIiIsIHkgPSAiTGFuaW5lbmN5IHBhcmEgZm90b3Mgc2VtIHNvcnJpc28iKSArDQogICAgICAgIGNvb3JkX2ZsaXAoKQ0KYGBgDQoNCiMjIyBqdW50YW5kbyBhcyB2aXN1YWxpemHDp8O1ZXMNCg0KDQoNCmBgYHtyfQ0KaWNzX3NtaWxlX25vc21pbGUgPSByYmluZChjaV9zbWlsZSwgY2lfbm9fc21pbGUpDQppY3Nfc21pbGVfbm9zbWlsZSRzbWlsZSA9IGMoIndpdGhfc21pbGUiLCAibm9fc21pbGUiKQ0KDQppY3Nfc21pbGVfbm9zbWlsZQ0KYGBgDQoNCg0KYGBge3J9DQppY3Nfc21pbGVfbm9zbWlsZSAlPiUgDQogIGdncGxvdChhZXMoDQogICAgICAgICAgICB5bWluID0gY29uZi5sb3csDQogICAgICAgICAgICB5ID0gc3RhdGlzdGljLA0KICAgICAgICAgICAgeW1heCA9IGNvbmYuaGlnaCwNCiAgICAgICAgICAgIHggPSByZW9yZGVyKHNtaWxlLCBzdGF0aXN0aWMpDQogICAgICAgICkpICsNCiAgICAgICAgZ2VvbV9saW5lcmFuZ2UoKSArDQogICAgICAgIGdlb21fcG9pbnQoY29sb3IgPSAiY29yYWwiLCBzaXplID0gMykgKw0KICAgICAgICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygwLCAxMCkpICsNCiAgICAgICAgbGFicyh4ID0gIiIsIHkgPSAiTGVuaWVuY3kiKSArDQogICAgICAgIGNvb3JkX2ZsaXAoKQ0KYGBgDQoNCg0KDQoNCg0KDQojIyBDb21wYXJhw6fDo28gY29tIGUgc2VtIHNvcnJpc28NCg0KDQpEaWZlcmVuw6dhDQoNCmBgYHtyfQ0KY29tcGFyYWNhbyA9IGRhZG9zX2xlbmllbmN5IA0KDQp0aGV0YSA8LSBmdW5jdGlvbihkLCBpKSB7DQogICAgYWdydXBhZG8gPSBkICU+JSANCiAgICAgICAgc2xpY2UoaSkgJT4lIA0KICAgICAgICBncm91cF9ieSh3aXRoX3NtaWxlKSAlPiUgDQogICAgICAgIHN1bW1hcmlzZShtZWRpYSA9IG1lYW4obGVuaWVuY3kpKQ0KICAgIGIgPSBhZ3J1cGFkbyAlPiUgZmlsdGVyKHdpdGhfc21pbGUgPT0gInllcyIpICU+JSBwdWxsKG1lZGlhKQ0KICAgIGwgPSBhZ3J1cGFkbyAlPiUgZmlsdGVyKHdpdGhfc21pbGUgPT0gIm5vIikgJT4lIHB1bGwobWVkaWEpDQogICAgbCAtIGINCn0NCg0KDQp0aGV0YShjb21wYXJhY2FvLCBpID0gMTpOUk9XKGNvbXBhcmFjYW8pKQ0KYGBgDQoNCg0KDQoNCmBgYHtyfQ0KY2lfY29tcF9zbWlsZXMgPSBib290KGRhdGEgPSBjb21wYXJhY2FvLA0KICAgICAgICAgICBzdGF0aXN0aWMgPSB0aGV0YSwNCiAgICAgICAgICAgUiA9IDIwMDApICU+JQ0KICAgIHRpZHkoY29uZi5sZXZlbCA9IC45NSwNCiAgICAgICAgIGNvbmYubWV0aG9kID0gImJjYSIsDQogICAgICAgICBjb25mLmludCA9IFRSVUUpDQoNCmNpX2NvbXBfc21pbGVzDQpgYGANCg0KDQpgYGB7cn0NCmNpX2NvbXBfc21pbGVzICU+JSANCiAgZ2dwbG90KGFlcygNCiAgICAgICAgICAgIHltaW4gPSBjb25mLmxvdywNCiAgICAgICAgICAgIHkgPSBzdGF0aXN0aWMsDQogICAgICAgICAgICB5bWF4ID0gY29uZi5oaWdoLA0KICAgICAgICAgICAgeCA9ICJubyBzbWlsZSAtIHdpdGggc21pbGUiDQogICAgICAgICkpICsNCiAgICAgICAgZ2VvbV9saW5lcmFuZ2UoKSArDQogICAgICAgIGdlb21fcG9pbnQoY29sb3IgPSAiY29yYWwiLCBzaXplID0gMykgKw0KICAgICAgICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygtMywgMykpICsNCiAgICAgICAgbGFicyh4ID0gIiIsIHkgPSAiTGVuaWVuY3kiKSArDQogICAgICAgIGNvb3JkX2ZsaXAoKQ0KYGBgDQoNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KDQoNCg0KYGBge3J9DQptaXNlcmFibGVfc21pbGUgPSBkYWRvc19sZW5pZW5jeSAlPiUgDQogICAgZmlsdGVyKHNtaWxlID09ICJtaXNlcmFibGUgc21pbGUiKQ0KDQpmZWx0X3NtaWxlID0gZGFkb3NfbGVuaWVuY3kgJT4lIA0KICAgIGZpbHRlcihzbWlsZSA9PSAiZmVsdCBzbWlsZSIpDQoNCmZhbHNlX3NtaWxlID0gZGFkb3NfbGVuaWVuY3kgJT4lIA0KICAgIGZpbHRlcihzbWlsZSA9PSAiZmFsc2Ugc21pbGUiKQ0KYGBgDQoNCg0KYGBge3J9DQptaXNlcmFibGVfc21pbGUNCmBgYA0KDQoNCg0KDQoNCg0KIyMgbWlzZXJhYmxlDQoNCg0KDQpgYGB7cn0NCnMgPC0gZnVuY3Rpb24oZCwgaSkgew0KICAgIHN1bWFyaXphZG8gPSBkICU+JSANCiAgICAgICAgc2xpY2UoaSkgJT4lIA0KICAgICAgICBzdW1tYXJpc2UobWVkaWEgPSBtZWFuKGxlbmllbmN5KSkNCiAgICANCiAgICBzdW1hcml6YWRvICU+JSANCiAgICAgIHB1bGwobWVkaWEpDQp9DQoNCnMobWlzZXJhYmxlX3NtaWxlLCAxOihucm93KG1pc2VyYWJsZV9zbWlsZSkpKSAjIHRoZXRhX2NoYXBldQ0KYGBgDQoNCmBgYHtyfQ0KYm9vdGVkIDwtIGJvb3QoZGF0YSA9IG1pc2VyYWJsZV9zbWlsZSwgDQogICAgICAgICAgICAgICBzdGF0aXN0aWMgPSBzLCANCiAgICAgICAgICAgICAgIFIgPSAyMDAwKQ0KDQpjaV9taXNlcmFibGVfc21pbGUgPSB0aWR5KGJvb3RlZCwgDQogICAgICAgICAgICAgIGNvbmYubGV2ZWwgPSAuOTUsDQogICAgICAgICAgICAgIGNvbmYubWV0aG9kID0gImJhc2ljIiwNCiAgICAgICAgICAgICAgY29uZi5pbnQgPSBUUlVFKQ0KDQpjaV9taXNlcmFibGVfc21pbGUNCmBgYA0KDQoNCg0KDQojIyMgZmVsdCBzbWlsZQ0KDQpgYGB7cn0NCnMgPC0gZnVuY3Rpb24oZCwgaSkgew0KICAgIHN1bWFyaXphZG8gPSBkICU+JSANCiAgICAgICAgc2xpY2UoaSkgJT4lIA0KICAgICAgICBzdW1tYXJpc2UobWVkaWEgPSBtZWFuKGxlbmllbmN5KSkNCiAgICANCiAgICBzdW1hcml6YWRvICU+JSANCiAgICAgIHB1bGwobWVkaWEpDQp9DQoNCnMoZmVsdF9zbWlsZSwgMToobnJvdyhmZWx0X3NtaWxlKSkpICMgdGhldGFfY2hhcGV1DQpgYGANCg0KYGBge3J9DQpib290ZWQgPC0gYm9vdChkYXRhID0gZmVsdF9zbWlsZSwgDQogICAgICAgICAgICAgICBzdGF0aXN0aWMgPSBzLCANCiAgICAgICAgICAgICAgIFIgPSAyMDAwKQ0KDQpjaV9mZWx0X3NtaWxlID0gdGlkeShib290ZWQsIA0KICAgICAgICAgICAgICBjb25mLmxldmVsID0gLjk1LA0KICAgICAgICAgICAgICBjb25mLm1ldGhvZCA9ICJiYXNpYyIsDQogICAgICAgICAgICAgIGNvbmYuaW50ID0gVFJVRSkNCg0KY2lfZmVsdF9zbWlsZQ0KYGBgDQoNCg0KIyMjIGZhbHNlIHNtaWxlDQoNCmBgYHtyfQ0KcyA8LSBmdW5jdGlvbihkLCBpKSB7DQogICAgc3VtYXJpemFkbyA9IGQgJT4lIA0KICAgICAgICBzbGljZShpKSAlPiUgDQogICAgICAgIHN1bW1hcmlzZShtZWRpYSA9IG1lYW4obGVuaWVuY3kpKQ0KICAgIA0KICAgIHN1bWFyaXphZG8gJT4lIA0KICAgICAgcHVsbChtZWRpYSkNCn0NCg0KcyhmYWxzZV9zbWlsZSwgMToobnJvdyhmYWxzZV9zbWlsZSkpKSAjIHRoZXRhX2NoYXBldQ0KYGBgDQoNCmBgYHtyfQ0KYm9vdGVkIDwtIGJvb3QoZGF0YSA9IGZhbHNlX3NtaWxlLCANCiAgICAgICAgICAgICAgIHN0YXRpc3RpYyA9IHMsIA0KICAgICAgICAgICAgICAgUiA9IDIwMDApDQoNCmNpX2ZhbHNlX3NtaWxlID0gdGlkeShib290ZWQsIA0KICAgICAgICAgICAgICBjb25mLmxldmVsID0gLjk1LA0KICAgICAgICAgICAgICBjb25mLm1ldGhvZCA9ICJiYXNpYyIsDQogICAgICAgICAgICAgIGNvbmYuaW50ID0gVFJVRSkNCg0KY2lfZmFsc2Vfc21pbGUNCmBgYA0KDQoNCg0KIyMjIHB1dHRpbmcgdG9nZXRoZXINCg0KDQoNCg0KYGBge3J9DQppY3NfYWxsX3NtaWxlID0gcmJpbmQoY2lfbm9fc21pbGUsIGNpX2ZhbHNlX3NtaWxlLCBjaV9mZWx0X3NtaWxlLCBjaV9taXNlcmFibGVfc21pbGUpDQppY3NfYWxsX3NtaWxlJHNtaWxlID0gYygibm8gc21pbGUiLCAiZmFsc2Ugc21pbGUiLCAiZmVsdCBzbWlsZSIsICJtaXNlcmFibGUgc21pbGUiKQ0KDQppY3NfYWxsX3NtaWxlDQpgYGANCg0KDQpgYGB7cn0NCmljc19hbGxfc21pbGUgJT4lIA0KICBnZ3Bsb3QoYWVzKA0KICAgICAgICAgICAgeW1pbiA9IGNvbmYubG93LA0KICAgICAgICAgICAgeSA9IHN0YXRpc3RpYywNCiAgICAgICAgICAgIHltYXggPSBjb25mLmhpZ2gsDQogICAgICAgICAgICB4ID0gcmVvcmRlcihzbWlsZSwgc3RhdGlzdGljKQ0KICAgICAgICApKSArDQogICAgICAgIGdlb21fbGluZXJhbmdlKCkgKw0KICAgICAgICBnZW9tX3BvaW50KGNvbG9yID0gImNvcmFsIiwgc2l6ZSA9IDMpICsNCiAgICAgICAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoMiwgNy41KSkgKw0KICAgICAgICBsYWJzKHggPSAiIiwgeSA9ICJMZW5pZW5jeSIpICsNCiAgICAgICAgY29vcmRfZmxpcCgpDQpgYGANCg0KDQojIyMgRmF6ZW5kbyBhIGRpZmVyZW7Dp2ENCk5vIHNtaWxlIC0gRmFsc2UgU21pbGUNCg0KRGlmZXJlbsOnYQ0KDQpgYGB7cn0NCmNvbXBhcmFjYW9fZmFsc2Vfc21pbGUgPSBkYWRvc19sZW5pZW5jeSANCg0KdGhldGEgPC0gZnVuY3Rpb24oZCwgaSkgew0KICAgIGFncnVwYWRvID0gZCAlPiUgDQogICAgICAgIHNsaWNlKGkpICU+JSANCiAgICAgICAgZ3JvdXBfYnkoc21pbGUpICU+JSANCiAgICAgICAgc3VtbWFyaXNlKG1lZGlhID0gbWVhbihsZW5pZW5jeSkpDQogICAgYiA9IGFncnVwYWRvICU+JSBmaWx0ZXIoc21pbGUgPT0gImZhbHNlIHNtaWxlIikgJT4lIHB1bGwobWVkaWEpDQogICAgbCA9IGFncnVwYWRvICU+JSBmaWx0ZXIoc21pbGUgPT0gIm5vIHNtaWxlIChjb250cm9sKSIpICU+JSBwdWxsKG1lZGlhKQ0KICAgIGwgLSBiDQp9DQoNCg0KdGhldGEoY29tcGFyYWNhb19mYWxzZV9zbWlsZSwgaSA9IDE6TlJPVyhjb21wYXJhY2FvX2ZhbHNlX3NtaWxlKSkNCmBgYA0KDQoNCg0KDQpgYGB7cn0NCmNpX2NvbXBfZmFsc2Vfc21pbGUgPSBib290KGRhdGEgPSBjb21wYXJhY2FvX2ZhbHNlX3NtaWxlLA0KICAgICAgICAgICBzdGF0aXN0aWMgPSB0aGV0YSwNCiAgICAgICAgICAgUiA9IDIwMDApICU+JQ0KICAgIHRpZHkoY29uZi5sZXZlbCA9IC45NSwNCiAgICAgICAgIGNvbmYubWV0aG9kID0gImJjYSIsDQogICAgICAgICBjb25mLmludCA9IFRSVUUpDQoNCmNpX2NvbXBfZmFsc2Vfc21pbGUNCmBgYA0KDQoNCg0KTm8gc21pbGUgLSBGZWx0IFNtaWxlDQoNCkRpZmVyZW7Dp2ENCg0KYGBge3J9DQpjb21wYXJhY2FvX2ZlbHRfc21pbGUgPSBkYWRvc19sZW5pZW5jeSANCg0KdGhldGEgPC0gZnVuY3Rpb24oZCwgaSkgew0KICAgIGFncnVwYWRvID0gZCAlPiUgDQogICAgICAgIHNsaWNlKGkpICU+JSANCiAgICAgICAgZ3JvdXBfYnkoc21pbGUpICU+JSANCiAgICAgICAgc3VtbWFyaXNlKG1lZGlhID0gbWVhbihsZW5pZW5jeSkpDQogICAgYiA9IGFncnVwYWRvICU+JSBmaWx0ZXIoc21pbGUgPT0gImZlbHQgc21pbGUiKSAlPiUgcHVsbChtZWRpYSkNCiAgICBsID0gYWdydXBhZG8gJT4lIGZpbHRlcihzbWlsZSA9PSAibm8gc21pbGUgKGNvbnRyb2wpIikgJT4lIHB1bGwobWVkaWEpDQogICAgbCAtIGINCn0NCg0KDQp0aGV0YShjb21wYXJhY2FvX2ZlbHRfc21pbGUsIGkgPSAxOk5ST1coY29tcGFyYWNhb19mZWx0X3NtaWxlKSkNCmBgYA0KDQoNCg0KDQpgYGB7cn0NCmNpX2NvbXBfZmVsdF9zbWlsZSA9IGJvb3QoZGF0YSA9IGNvbXBhcmFjYW9fZmVsdF9zbWlsZSwNCiAgICAgICAgICAgc3RhdGlzdGljID0gdGhldGEsDQogICAgICAgICAgIFIgPSAyMDAwKSAlPiUNCiAgICB0aWR5KGNvbmYubGV2ZWwgPSAuOTUsDQogICAgICAgICBjb25mLm1ldGhvZCA9ICJiY2EiLA0KICAgICAgICAgY29uZi5pbnQgPSBUUlVFKQ0KDQpjaV9jb21wX2ZlbHRfc21pbGUNCmBgYA0KDQoNCk5vIHNtaWxlIC0gTWlzZXJhYmxlIFNtaWxlDQoNCkRpZmVyZW7Dp2ENCg0KYGBge3J9DQpjb21wYXJhY2FvX21pc2VyYWJsZV9zbWlsZSA9IGRhZG9zX2xlbmllbmN5IA0KDQp0aGV0YSA8LSBmdW5jdGlvbihkLCBpKSB7DQogICAgYWdydXBhZG8gPSBkICU+JSANCiAgICAgICAgc2xpY2UoaSkgJT4lIA0KICAgICAgICBncm91cF9ieShzbWlsZSkgJT4lIA0KICAgICAgICBzdW1tYXJpc2UobWVkaWEgPSBtZWFuKGxlbmllbmN5KSkNCiAgICBiID0gYWdydXBhZG8gJT4lIGZpbHRlcihzbWlsZSA9PSAibWlzZXJhYmxlIHNtaWxlIikgJT4lIHB1bGwobWVkaWEpDQogICAgbCA9IGFncnVwYWRvICU+JSBmaWx0ZXIoc21pbGUgPT0gIm5vIHNtaWxlIChjb250cm9sKSIpICU+JSBwdWxsKG1lZGlhKQ0KICAgIGwgLSBiDQp9DQoNCg0KdGhldGEoY29tcGFyYWNhb19taXNlcmFibGVfc21pbGUsIGkgPSAxOk5ST1coY29tcGFyYWNhb19taXNlcmFibGVfc21pbGUpKQ0KYGBgDQoNCg0KDQoNCmBgYHtyfQ0KY2lfY29tcF9taXNlcmFibGVfc21pbGUgPSBib290KGRhdGEgPSBjb21wYXJhY2FvX21pc2VyYWJsZV9zbWlsZSwNCiAgICAgICAgICAgc3RhdGlzdGljID0gdGhldGEsDQogICAgICAgICAgIFIgPSAyMDAwKSAlPiUNCiAgICB0aWR5KGNvbmYubGV2ZWwgPSAuOTUsDQogICAgICAgICBjb25mLm1ldGhvZCA9ICJiY2EiLA0KICAgICAgICAgY29uZi5pbnQgPSBUUlVFKQ0KDQpjaV9jb21wX21pc2VyYWJsZV9zbWlsZQ0KYGBgDQoNCg0KDQoNCiMjIyMgdmlzdWFsaXphbmRvIGFzIGRpZmVyZcOnYXMNCg0KYGBge3J9DQppY3NfZGlmZl9zbWlsZSA9IHJiaW5kKGNpX2NvbXBfZmFsc2Vfc21pbGUsIGNpX2NvbXBfZmVsdF9zbWlsZSwgY2lfY29tcF9taXNlcmFibGVfc21pbGUpDQppY3NfZGlmZl9zbWlsZSRkaWZmID0gYygibm8gc21pbGUgLSBmYWxzZSBzbWlsZSIsICJubyBzbWlsZSAtIGZlbHQgc21pbGUiLCAibm8gc21pbGUgLSBtaXNlcmFibGUgc21pbGUiKQ0KDQppY3NfZGlmZl9zbWlsZQ0KYGBgDQoNCg0KYGBge3J9DQppY3NfZGlmZl9zbWlsZSAlPiUgDQogIGdncGxvdChhZXMoDQogICAgICAgICAgICB5bWluID0gY29uZi5sb3csDQogICAgICAgICAgICB5ID0gc3RhdGlzdGljLA0KICAgICAgICAgICAgeW1heCA9IGNvbmYuaGlnaCwNCiAgICAgICAgICAgIHggPSByZW9yZGVyKGRpZmYsIHN0YXRpc3RpYykNCiAgICAgICAgKSkgKw0KICAgICAgICBnZW9tX2xpbmVyYW5nZSgpICsNCiAgICAgICAgZ2VvbV9wb2ludChjb2xvciA9ICJjb3JhbCIsIHNpemUgPSAzKSArDQogICAgICAgIHNjYWxlX3lfY29udGludW91cyhsaW1pdHMgPSBjKC0zLCAzKSkgKw0KICAgICAgICBsYWJzKHggPSAiIiwgeSA9ICJMZW5pZW5jeSIpICsNCiAgICAgICAgY29vcmRfZmxpcCgpDQpgYGANCg0KDQotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCkRpZmZlcmVuY2UgZW50cmUgRmFsc2Ugc21pbGUgZSBGZWx0IHNtaWxlDQpObyBzbWlsZSAtIEZlbHQgU21pbGUNCg0KDQoNCmBgYHtyfQ0KY29tcGFyYWNhb19mZWx0X21pc2VyYWxiZSA9IGRhZG9zX2xlbmllbmN5IA0KDQp0aGV0YSA8LSBmdW5jdGlvbihkLCBpKSB7DQogICAgYWdydXBhZG8gPSBkICU+JSANCiAgICAgICAgc2xpY2UoaSkgJT4lIA0KICAgICAgICBncm91cF9ieShzbWlsZSkgJT4lIA0KICAgICAgICBzdW1tYXJpc2UobWVkaWEgPSBtZWFuKGxlbmllbmN5KSkNCiAgICBiID0gYWdydXBhZG8gJT4lIGZpbHRlcihzbWlsZSA9PSAiZmVsdCBzbWlsZSIpICU+JSBwdWxsKG1lZGlhKQ0KICAgIGwgPSBhZ3J1cGFkbyAlPiUgZmlsdGVyKHNtaWxlID09ICJtaXNlcmFibGUgc21pbGUiKSAlPiUgcHVsbChtZWRpYSkNCiAgICBsIC0gYg0KfQ0KDQoNCnRoZXRhKGNvbXBhcmFjYW9fZmVsdF9taXNlcmFsYmUsIGkgPSAxOk5ST1coY29tcGFyYWNhb19mZWx0X21pc2VyYWxiZSkpDQpgYGANCg0KDQoNCg0KYGBge3J9DQpjaV9jb21wYXJhY2FvX2ZlbHRfbWlzZXJhbGJlID0gYm9vdChkYXRhID0gY29tcGFyYWNhb19mZWx0X21pc2VyYWxiZSwNCiAgICAgICAgICAgc3RhdGlzdGljID0gdGhldGEsDQogICAgICAgICAgIFIgPSAyMDAwKSAlPiUNCiAgICB0aWR5KGNvbmYubGV2ZWwgPSAuOTUsDQogICAgICAgICBjb25mLm1ldGhvZCA9ICJiY2EiLA0KICAgICAgICAgY29uZi5pbnQgPSBUUlVFKQ0KDQpjaV9jb21wYXJhY2FvX2ZlbHRfbWlzZXJhbGJlDQpgYGANCg0KDQoNCg0KYGBge3J9DQpjaV9jb21wYXJhY2FvX2ZlbHRfbWlzZXJhbGJlJT4lIA0KICBnZ3Bsb3QoYWVzKA0KICAgICAgICAgICAgeW1pbiA9IGNvbmYubG93LA0KICAgICAgICAgICAgeSA9IHN0YXRpc3RpYywNCiAgICAgICAgICAgIHltYXggPSBjb25mLmhpZ2gsDQogICAgICAgICAgICB4ID0gIk1pc2VyYWJsZSAtIEZlbHQiDQogICAgICAgICkpICsNCiAgICAgICAgZ2VvbV9saW5lcmFuZ2UoKSArDQogICAgICAgIGdlb21fcG9pbnQoY29sb3IgPSAiY29yYWwiLCBzaXplID0gMikgKw0KICAgICAgICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygtMiwgMikpICsNCiAgICAgICAgbGFicyh4ID0gIiIsIHkgPSAiTGVuaWVuY3kiKSArDQogICAgICAgIGNvb3JkX2ZsaXAoKQ0KYGBgDQoNCg0KDQoNCg0KDQoNCg0KDQoNCg0KDQo=