library(tidyverse)
library(here)
library(cluster)
library(plotly)
library(factoextra)
source(here::here("code/lib.R"))
theme_set(theme_report())

knitr::opts_chunk$set(tidy = FALSE,
                      fig.width = 6,
                      fig.height = 5,
                      echo = TRUE)

paleta = c("#404E4D",
           "#92DCE5",
           "#938BA1",
           "#2D3142",
           "#F4743B")
tops <- read_csv("../data/tops.csv")

Introdução

Descobrir o gosto musical de uma pessoa nos faz entender um pouco mais sobre ela, sobre suas características e personalidade. Goste ela de uma música mais ou menos dançante, mais enérgica ou mais calma, mais positiva ou triste, tudo isso pode nos dizer muito sobre essa pessoa e a nova descoberta que estamos fazendo sobre ela. Tendo isso em mente, por que não entender melhor o gosto musical de um país inteiro? Ou do mundo?

Com esse objetivo, essa análise se utiliza dos dados fornecidos pela API do Spotify das suas playlists semanais criadas para as Top 50 músicas mais ouvidas no Brasil e as Top 50 músicas mais ouvidas globalmente – nesse caso as Top 50 da primeira semana de outubro de 2021. Para estudar o perfil brasileiro e global nas músicas mais tocadas, inicialmente será realizada uma análise exploratória dos dados coletados e, em seguida, entender possíveis grupos presentes nesses perfis musicais.

Os dados

Tendo os dados sido coletados através da API do Spotify e do pacote spotifyr em R, foram obtidas 56 variáveis, algumas as quais valem uma breve explicação:

danceability: a partir da combinação de elementos musicais como andamento, ritmo, batida e regularidade, essa medida descreve o quanto a música é adequada para dançar. Um valor de 0.0 é o menos “dançável” e um valor de 1.0 é o mais “dançável”.

energy: energia é uma medida de 0.0 a 1.0 que representa uma medida percentual de intensidade e atividade – tipicamente músicas enérgicas passam uma sensação de serem mais rápidas e agitadas.

valence: uma medida que vai de 0.0 a 1.0 para descrever a positividade presente em uma música, ou seja, uma música de valência mais alta soa mais positiva, alegre, eufórica, enquanto músicas com valência mais baixa soam mais tristes, depressivas, irritadas.

popularity: representa a popularidade da música. essa medida vai de 0 a 100, sendo 100 a mais popular.

Tendo em vista a quantidade de variáveis obtidas com esses dados, apenas as medidas citadas acima serão utilizadas para a análise exploratória.

A análise

Exploratória

Para começar a entender os gostos musicais do Brasil e do mundo, temos um gráfico de distribuição com a valência das músicas mais ouvidas e, a partir dele e das medianas, podemos perceber que a positividade das músicas ouvidas no Brasil tem uma mediana de valor 0.223 superior ao valor da mediana global. Estaria o brasileiro então ouvindo músicas mais positivas que os demais?

sumarios <- tops %>% 
    group_by(playlist_name) %>% 
    summarise(valence_median = median(valence), 
              danceability_median = median(danceability),
              .groups = "drop")
eda_valence <- tops %>% 
  ggplot(aes(x = valence, y = playlist_name)) +
  geom_jitter(height = .1, alpha = 0.7, size = 2, color = "orchid4") +
  geom_point(data = sumarios, aes(x = valence_median), size = 2, color = "red") +
  labs(
    title = "Distribuição de valência",
    x = "Valência",
    y = "Playlist"
  )
ggplotly(eda_valence)

Na distribuição seguinte temos a dançabilidade presente nessas músicas mais ouvidas, que, apesar de haver uma diferença entre as playlists, esta diferença é de apenas 0.093 (o que a torna um pouco relevante, já que o intervalo da medida vai de 0 a 1). Com poucos outliers, podemos dizer que tanto o Brasil como o mundo escutam músicas bem dançantes (acima de 0.5). Povo animado.

eda_danceability <- tops %>% 
  ggplot(aes(x = danceability, y = playlist_name)) +
  geom_jitter(height = .1, alpha = 0.7, size = 2, color = "skyblue3") +
  geom_point(data = sumarios, aes(x = danceability_median), size = 2, color = "red") +
  labs(
    title = "Distribuição de dançabilidade",
    x = "Dançabilidade",
    y = "Playlist"
  )
ggplotly(eda_danceability)

Algo que valeu a curiosidade foi entender se existe relação entre a valência (ou seja, sua positividade) e a energia (agitação e intensidade) de uma música – já que não necessariamente uma música agitada poderia ser positiva. Através do gráfico abaixo é possível observar a existência de uma relação linear entre essas duas variáveis.

eda_energy <- tops %>% 
  ggplot(aes(x = energy, y = valence, color = playlist_name)) +
  geom_jitter(height = .1, alpha = 0.7, size = 2) +
  labs(
    title = "Relação entre energia e valência",
    x = "Energia",
    y = "Valência",
    color = "Playlist"
  )
ggplotly(eda_energy)

Dessa relação linear podemos então realizar o cálculo do coefiente de Pearson e, com o resultado de 0.63, podemos dizer que há então uma relação linear forte e positiva entre valência e energia. Músicas mais enérgicas podem ser mais positivas!

tops %>% 
  summarise(correlacao = cor(valence, energy, method = "pearson"))

Também buscamos entender se há relação entre a valência de uma música e sua popularidade, relação essa que, a partir do seguinte gráfico, não pode ser considerada linear.

eda_popularity <- tops %>% 
  ggplot(aes(x = track.popularity, y = valence, color = playlist_name)) +
  geom_jitter(height = .1, alpha = 0.7, size = 2) +
  labs(
    title = "Relação entre a popularidade da música e valência",
    x = "Popularidade da música",
    y = "Valência",
    color = "Playlist"
  )
ggplotly(eda_popularity)

Por não ser linear, para o cálculo dessa relação nos utilizamos dos coeficientes de Spearman e Kendall. Através desses resultados, podemos dizer que há uma relação fraca negativa entre essas variáveis.

tops %>% 
  summarise(spearman = cor(valence, track.popularity, method = "spearman"),
            kendall = cor(valence, track.popularity, method = "kendall"), )

Com k-means

Ainda mantendo a curiosidade em relação às variáveis valência e popularidade da música, agora queremos entender possíveis grupos presentes nesses dados. Para isso, trabalhamos com k-means e os gráficos gerados foram através do ggplotly para que se pudesse ter uma maior interação com cada um dos grupos encontrados.

Para as mais ouvidas do Brasil, um número de grupos a que se chegou um resultado interessante foi de 5. Dessa forma, os grupos observados se dividiram em: músicas muito positivas e pouco populares, músicas pouco positivas e pouco populares, músicas pouco positivas e médio populares, músicas muito positivas e médio populares, músicas médio positivas e muito populares, o que mostra o quanto o gosto dos brasileiros é diverso no que diz respeito à positividade de uma música.

topsbrasil <- tops %>%  filter(playlist_name == "Top Songs - Brazil")

gruposbr <- topsbrasil %>%
    select(valence, track.popularity) %>%
    filter(!is.na(valence + track.popularity))
rownames(gruposbr) <- make.names(topsbrasil$track.name, unique = T)

gruposbr <- scale(gruposbr)
set.seed(1234)
res <- kmeans(gruposbr, 5)
gruposbrasil <- fviz_cluster(res, data = gruposbr) +
  theme_report() +
  labs(
    title = "Grupos presentes nas mais ouvidas do Brasil",
    x = "Valência",
    y = "Popularidade da música"
  )
ggplotly(gruposbrasil)

Já em relação às mais ouvidas do mundo, a quantidade apropriada de grupos não foi a mesma do Brasil. Aqui tivemos a presença de 3 grupos mais distintos, que se dividiram apenas entre pouco popular, médio popular e muito popular, já que em todos a valência se dispersa bastante. Dessa forma, o mundo não apresenta tanta distinção entre a positividade de uma música para torná-la mais popular ou não.

topsglobal <- tops %>%  filter(playlist_name == "Top Songs - Global")

gruposgb <- topsglobal %>%
    select(valence, track.popularity) %>%
    filter(!is.na(valence + track.popularity))
rownames(gruposgb) <- make.names(topsglobal$track.name, unique = T)

grupos <- scale(gruposgb)
set.seed(1234)
res <- kmeans(gruposgb, 3)
gruposglobal <- fviz_cluster(res, data = gruposgb) +
  theme_report() +
  labs(
    title = "Grupos presentes nas mais ouvidas do mundo",
    x = "Valência",
    y = "Popularidade da música"
  )
ggplotly(gruposglobal)

Conclusão

Diante do que foi visto, foi possível perceber quantas diferentes análises podemos realizar a partir dos dados fornecidos pelo Spotify e o quanto os gostos de um país podem diferir quando comparados com o resto do mundo. É importante lembrar que esta é uma base limitada de dados, restringida a uma semana de coleta apenas, já que o Spotify não disponibiliza playlists das mais tocadas de um período maior de tempo. Uma proposta interessante para a continuação desta análise seria a de semanalmente repetir essa coleta por um maior período de tempo, de forma a trazer uma maior riqueza de detalhes e de observações em relação aos possíveis gostos musicais do Brasil, do mundo e até mesmo de outros países separadamente.

LS0tCnRpdGxlOiAiQXMgbWFpcyBvdXZpZGFzIG5vIEJyYXNpbCBlIG5vIG11bmRvIgphdXRob3I6ICJNYXJjZWxsYSBTaXF1ZWlyYSIKb3V0cHV0OiAKICBodG1sX25vdGVib29rOgogICAgdGhlbWU6IHJlYWRhYmxlCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUKLS0tCgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShoZXJlKQpsaWJyYXJ5KGNsdXN0ZXIpCmxpYnJhcnkocGxvdGx5KQpsaWJyYXJ5KGZhY3RvZXh0cmEpCnNvdXJjZShoZXJlOjpoZXJlKCJjb2RlL2xpYi5SIikpCnRoZW1lX3NldCh0aGVtZV9yZXBvcnQoKSkKCmtuaXRyOjpvcHRzX2NodW5rJHNldCh0aWR5ID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgICBmaWcud2lkdGggPSA2LAogICAgICAgICAgICAgICAgICAgICAgZmlnLmhlaWdodCA9IDUsCiAgICAgICAgICAgICAgICAgICAgICBlY2hvID0gVFJVRSkKCnBhbGV0YSA9IGMoIiM0MDRFNEQiLAogICAgICAgICAgICIjOTJEQ0U1IiwKICAgICAgICAgICAiIzkzOEJBMSIsCiAgICAgICAgICAgIiMyRDMxNDIiLAogICAgICAgICAgICIjRjQ3NDNCIikKYGBgCgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQp0b3BzIDwtIHJlYWRfY3N2KCIuLi9kYXRhL3RvcHMuY3N2IikKYGBgCgojIyMgSW50cm9kdcOnw6NvCgpEZXNjb2JyaXIgbyBnb3N0byBtdXNpY2FsIGRlIHVtYSBwZXNzb2Egbm9zIGZheiBlbnRlbmRlciB1bSBwb3VjbyBtYWlzIHNvYnJlIGVsYSwgc29icmUgc3VhcyBjYXJhY3RlcsOtc3RpY2FzIGUgcGVyc29uYWxpZGFkZS4gR29zdGUgZWxhIGRlIHVtYSBtw7pzaWNhIG1haXMgb3UgbWVub3MgZGFuw6dhbnRlLCBtYWlzIGVuw6lyZ2ljYSBvdSBtYWlzIGNhbG1hLCBtYWlzIHBvc2l0aXZhIG91IHRyaXN0ZSwgdHVkbyBpc3NvIHBvZGUgbm9zIGRpemVyIG11aXRvIHNvYnJlIGVzc2EgcGVzc29hIGUgYSBub3ZhIGRlc2NvYmVydGEgcXVlIGVzdGFtb3MgZmF6ZW5kbyBzb2JyZSBlbGEuIFRlbmRvIGlzc28gZW0gbWVudGUsIHBvciBxdWUgbsOjbyBlbnRlbmRlciBtZWxob3IgbyBnb3N0byBtdXNpY2FsIGRlIHVtIHBhw61zIGludGVpcm8/IE91IGRvIG11bmRvPwoKQ29tIGVzc2Ugb2JqZXRpdm8sIGVzc2EgYW7DoWxpc2Ugc2UgdXRpbGl6YSBkb3MgZGFkb3MgZm9ybmVjaWRvcyBwZWxhIEFQSSBkbyBTcG90aWZ5IGRhcyBzdWFzIHBsYXlsaXN0cyBzZW1hbmFpcyBjcmlhZGFzIHBhcmEgYXMgVG9wIDUwIG3DunNpY2FzIG1haXMgb3V2aWRhcyBubyBCcmFzaWwgZSBhcyBUb3AgNTAgbcO6c2ljYXMgbWFpcyBvdXZpZGFzIGdsb2JhbG1lbnRlIOKAkyBuZXNzZSBjYXNvIGFzIFRvcCA1MCBkYSBwcmltZWlyYSBzZW1hbmEgZGUgb3V0dWJybyBkZSAyMDIxLiBQYXJhIGVzdHVkYXIgbyBwZXJmaWwgYnJhc2lsZWlybyBlIGdsb2JhbCBuYXMgbcO6c2ljYXMgbWFpcyB0b2NhZGFzLCBpbmljaWFsbWVudGUgc2Vyw6EgcmVhbGl6YWRhIHVtYSBhbsOhbGlzZSBleHBsb3JhdMOzcmlhIGRvcyBkYWRvcyBjb2xldGFkb3MgZSwgZW0gc2VndWlkYSwgZW50ZW5kZXIgcG9zc8OtdmVpcyBncnVwb3MgcHJlc2VudGVzIG5lc3NlcyBwZXJmaXMgbXVzaWNhaXMuCgojIyMgT3MgZGFkb3MKClRlbmRvIG9zIGRhZG9zIHNpZG8gY29sZXRhZG9zIGF0cmF2w6lzIGRhIEFQSSBkbyBTcG90aWZ5IGUgZG8gcGFjb3RlIHNwb3RpZnlyIGVtIFIsIGZvcmFtIG9idGlkYXMgNTYgdmFyacOhdmVpcywgYWxndW1hcyBhcyBxdWFpcyB2YWxlbSB1bWEgYnJldmUgZXhwbGljYcOnw6NvOgoKKipkYW5jZWFiaWxpdHk6KiogYSBwYXJ0aXIgZGEgY29tYmluYcOnw6NvIGRlIGVsZW1lbnRvcyBtdXNpY2FpcyBjb21vIGFuZGFtZW50bywgcml0bW8sIGJhdGlkYSBlIHJlZ3VsYXJpZGFkZSwgZXNzYSBtZWRpZGEgZGVzY3JldmUgbyBxdWFudG8gYSBtw7pzaWNhIMOpIGFkZXF1YWRhIHBhcmEgZGFuw6dhci4gVW0gdmFsb3IgZGUgMC4wIMOpIG8gbWVub3MgImRhbsOnw6F2ZWwiIGUgdW0gdmFsb3IgZGUgMS4wIMOpIG8gbWFpcyAiZGFuw6fDoXZlbCIuCgoqKmVuZXJneToqKiBlbmVyZ2lhIMOpIHVtYSBtZWRpZGEgZGUgMC4wIGEgMS4wIHF1ZSByZXByZXNlbnRhIHVtYSBtZWRpZGEgcGVyY2VudHVhbCBkZSBpbnRlbnNpZGFkZSBlIGF0aXZpZGFkZSDigJMgdGlwaWNhbWVudGUgbcO6c2ljYXMgZW7DqXJnaWNhcyBwYXNzYW0gdW1hIHNlbnNhw6fDo28gZGUgc2VyZW0gbWFpcyByw6FwaWRhcyBlIGFnaXRhZGFzLgoKKip2YWxlbmNlOioqIHVtYSBtZWRpZGEgcXVlIHZhaSBkZSAwLjAgYSAxLjAgcGFyYSBkZXNjcmV2ZXIgYSBwb3NpdGl2aWRhZGUgcHJlc2VudGUgZW0gdW1hIG3DunNpY2EsIG91IHNlamEsIHVtYSBtw7pzaWNhIGRlIHZhbMOqbmNpYSBtYWlzIGFsdGEgc29hIG1haXMgcG9zaXRpdmEsIGFsZWdyZSwgZXVmw7NyaWNhLCBlbnF1YW50byBtw7pzaWNhcyBjb20gdmFsw6puY2lhIG1haXMgYmFpeGEgc29hbSBtYWlzIHRyaXN0ZXMsIGRlcHJlc3NpdmFzLCBpcnJpdGFkYXMuCgoqKnBvcHVsYXJpdHk6KiogcmVwcmVzZW50YSBhIHBvcHVsYXJpZGFkZSBkYSBtw7pzaWNhLiBlc3NhIG1lZGlkYSB2YWkgZGUgMCBhIDEwMCwgc2VuZG8gMTAwIGEgbWFpcyBwb3B1bGFyLgoKVGVuZG8gZW0gdmlzdGEgYSBxdWFudGlkYWRlIGRlIHZhcmnDoXZlaXMgb2J0aWRhcyBjb20gZXNzZXMgZGFkb3MsIGFwZW5hcyBhcyBtZWRpZGFzIGNpdGFkYXMgYWNpbWEgc2Vyw6NvIHV0aWxpemFkYXMgcGFyYSBhIGFuw6FsaXNlIGV4cGxvcmF0w7NyaWEuIAoKIyMjIEEgYW7DoWxpc2UKCiMjIyMgRXhwbG9yYXTDs3JpYQoKUGFyYSBjb21lw6dhciBhIGVudGVuZGVyIG9zIGdvc3RvcyBtdXNpY2FpcyBkbyBCcmFzaWwgZSBkbyBtdW5kbywgdGVtb3MgdW0gZ3LDoWZpY28gZGUgZGlzdHJpYnVpw6fDo28gY29tIGEgdmFsw6puY2lhIGRhcyBtw7pzaWNhcyBtYWlzIG91dmlkYXMgZSwgYSBwYXJ0aXIgZGVsZSBlIGRhcyBtZWRpYW5hcywgcG9kZW1vcyBwZXJjZWJlciBxdWUgYSBwb3NpdGl2aWRhZGUgZGFzIG3DunNpY2FzIG91dmlkYXMgbm8gQnJhc2lsIHRlbSB1bWEgbWVkaWFuYSBkZSB2YWxvciAwLjIyMyBzdXBlcmlvciBhbyB2YWxvciBkYSBtZWRpYW5hIGdsb2JhbC4gRXN0YXJpYSBvIGJyYXNpbGVpcm8gZW50w6NvIG91dmluZG8gbcO6c2ljYXMgbWFpcyBwb3NpdGl2YXMgcXVlIG9zIGRlbWFpcz8KCmBgYHtyfQpzdW1hcmlvcyA8LSB0b3BzICU+JSAKICAgIGdyb3VwX2J5KHBsYXlsaXN0X25hbWUpICU+JSAKICAgIHN1bW1hcmlzZSh2YWxlbmNlX21lZGlhbiA9IG1lZGlhbih2YWxlbmNlKSwgCiAgICAgICAgICAgICAgZGFuY2VhYmlsaXR5X21lZGlhbiA9IG1lZGlhbihkYW5jZWFiaWxpdHkpLAogICAgICAgICAgICAgIC5ncm91cHMgPSAiZHJvcCIpCmBgYAoKYGBge3J9CmVkYV92YWxlbmNlIDwtIHRvcHMgJT4lIAogIGdncGxvdChhZXMoeCA9IHZhbGVuY2UsIHkgPSBwbGF5bGlzdF9uYW1lKSkgKwogIGdlb21faml0dGVyKGhlaWdodCA9IC4xLCBhbHBoYSA9IDAuNywgc2l6ZSA9IDIsIGNvbG9yID0gIm9yY2hpZDQiKSArCiAgZ2VvbV9wb2ludChkYXRhID0gc3VtYXJpb3MsIGFlcyh4ID0gdmFsZW5jZV9tZWRpYW4pLCBzaXplID0gMiwgY29sb3IgPSAicmVkIikgKwogIGxhYnMoCiAgICB0aXRsZSA9ICJEaXN0cmlidWnDp8OjbyBkZSB2YWzDqm5jaWEiLAogICAgeCA9ICJWYWzDqm5jaWEiLAogICAgeSA9ICJQbGF5bGlzdCIKICApCmdncGxvdGx5KGVkYV92YWxlbmNlKQpgYGAKCk5hIGRpc3RyaWJ1acOnw6NvIHNlZ3VpbnRlIHRlbW9zIGEgZGFuw6dhYmlsaWRhZGUgcHJlc2VudGUgbmVzc2FzIG3DunNpY2FzIG1haXMgb3V2aWRhcywgcXVlLCBhcGVzYXIgZGUgaGF2ZXIgdW1hIGRpZmVyZW7Dp2EgZW50cmUgYXMgcGxheWxpc3RzLCBlc3RhIGRpZmVyZW7Dp2Egw6kgZGUgYXBlbmFzIDAuMDkzIChvIHF1ZSBhIHRvcm5hIHVtIHBvdWNvIHJlbGV2YW50ZSwgasOhIHF1ZSBvIGludGVydmFsbyBkYSBtZWRpZGEgdmFpIGRlIDAgYSAxKS4gQ29tIHBvdWNvcyBvdXRsaWVycywgcG9kZW1vcyBkaXplciBxdWUgdGFudG8gbyBCcmFzaWwgY29tbyBvIG11bmRvIGVzY3V0YW0gbcO6c2ljYXMgYmVtIGRhbsOnYW50ZXMgKGFjaW1hIGRlIDAuNSkuIFBvdm8gYW5pbWFkby4KCmBgYHtyfQplZGFfZGFuY2VhYmlsaXR5IDwtIHRvcHMgJT4lIAogIGdncGxvdChhZXMoeCA9IGRhbmNlYWJpbGl0eSwgeSA9IHBsYXlsaXN0X25hbWUpKSArCiAgZ2VvbV9qaXR0ZXIoaGVpZ2h0ID0gLjEsIGFscGhhID0gMC43LCBzaXplID0gMiwgY29sb3IgPSAic2t5Ymx1ZTMiKSArCiAgZ2VvbV9wb2ludChkYXRhID0gc3VtYXJpb3MsIGFlcyh4ID0gZGFuY2VhYmlsaXR5X21lZGlhbiksIHNpemUgPSAyLCBjb2xvciA9ICJyZWQiKSArCiAgbGFicygKICAgIHRpdGxlID0gIkRpc3RyaWJ1acOnw6NvIGRlIGRhbsOnYWJpbGlkYWRlIiwKICAgIHggPSAiRGFuw6dhYmlsaWRhZGUiLAogICAgeSA9ICJQbGF5bGlzdCIKICApCmdncGxvdGx5KGVkYV9kYW5jZWFiaWxpdHkpCmBgYAoKQWxnbyBxdWUgdmFsZXUgYSBjdXJpb3NpZGFkZSBmb2kgZW50ZW5kZXIgc2UgZXhpc3RlIHJlbGHDp8OjbyBlbnRyZSBhIHZhbMOqbmNpYSAob3Ugc2VqYSwgc3VhIHBvc2l0aXZpZGFkZSkgZSBhIGVuZXJnaWEgKGFnaXRhw6fDo28gZSBpbnRlbnNpZGFkZSkgZGUgdW1hIG3DunNpY2Eg4oCTIGrDoSBxdWUgbsOjbyBuZWNlc3NhcmlhbWVudGUgdW1hIG3DunNpY2EgYWdpdGFkYSBwb2RlcmlhIHNlciBwb3NpdGl2YS4gQXRyYXbDqXMgZG8gZ3LDoWZpY28gYWJhaXhvIMOpIHBvc3PDrXZlbCBvYnNlcnZhciBhIGV4aXN0w6puY2lhIGRlIHVtYSByZWxhw6fDo28gbGluZWFyIGVudHJlIGVzc2FzIGR1YXMgdmFyacOhdmVpcy4KCmBgYHtyfQplZGFfZW5lcmd5IDwtIHRvcHMgJT4lIAogIGdncGxvdChhZXMoeCA9IGVuZXJneSwgeSA9IHZhbGVuY2UsIGNvbG9yID0gcGxheWxpc3RfbmFtZSkpICsKICBnZW9tX2ppdHRlcihoZWlnaHQgPSAuMSwgYWxwaGEgPSAwLjcsIHNpemUgPSAyKSArCiAgbGFicygKICAgIHRpdGxlID0gIlJlbGHDp8OjbyBlbnRyZSBlbmVyZ2lhIGUgdmFsw6puY2lhIiwKICAgIHggPSAiRW5lcmdpYSIsCiAgICB5ID0gIlZhbMOqbmNpYSIsCiAgICBjb2xvciA9ICJQbGF5bGlzdCIKICApCmdncGxvdGx5KGVkYV9lbmVyZ3kpCmBgYAoKRGVzc2EgcmVsYcOnw6NvIGxpbmVhciBwb2RlbW9zIGVudMOjbyByZWFsaXphciBvIGPDoWxjdWxvIGRvIGNvZWZpZW50ZSBkZSBQZWFyc29uIGUsIGNvbSBvIHJlc3VsdGFkbyBkZSAwLjYzLCBwb2RlbW9zIGRpemVyIHF1ZSBow6EgZW50w6NvIHVtYSByZWxhw6fDo28gbGluZWFyIGZvcnRlIGUgcG9zaXRpdmEgZW50cmUgdmFsw6puY2lhIGUgZW5lcmdpYS4gTcO6c2ljYXMgbWFpcyBlbsOpcmdpY2FzIHBvZGVtIHNlciBtYWlzIHBvc2l0aXZhcyEKCmBgYHtyfQp0b3BzICU+JSAKICBzdW1tYXJpc2UoY29ycmVsYWNhbyA9IGNvcih2YWxlbmNlLCBlbmVyZ3ksIG1ldGhvZCA9ICJwZWFyc29uIikpCmBgYAoKVGFtYsOpbSBidXNjYW1vcyBlbnRlbmRlciBzZSBow6EgcmVsYcOnw6NvIGVudHJlIGEgdmFsw6puY2lhIGRlIHVtYSBtw7pzaWNhIGUgc3VhIHBvcHVsYXJpZGFkZSwgcmVsYcOnw6NvIGVzc2EgcXVlLCBhIHBhcnRpciBkbyBzZWd1aW50ZSBncsOhZmljbywgbsOjbyBwb2RlIHNlciBjb25zaWRlcmFkYSBsaW5lYXIuCgpgYGB7cn0KZWRhX3BvcHVsYXJpdHkgPC0gdG9wcyAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gdHJhY2sucG9wdWxhcml0eSwgeSA9IHZhbGVuY2UsIGNvbG9yID0gcGxheWxpc3RfbmFtZSkpICsKICBnZW9tX2ppdHRlcihoZWlnaHQgPSAuMSwgYWxwaGEgPSAwLjcsIHNpemUgPSAyKSArCiAgbGFicygKICAgIHRpdGxlID0gIlJlbGHDp8OjbyBlbnRyZSBhIHBvcHVsYXJpZGFkZSBkYSBtw7pzaWNhIGUgdmFsw6puY2lhIiwKICAgIHggPSAiUG9wdWxhcmlkYWRlIGRhIG3DunNpY2EiLAogICAgeSA9ICJWYWzDqm5jaWEiLAogICAgY29sb3IgPSAiUGxheWxpc3QiCiAgKQpnZ3Bsb3RseShlZGFfcG9wdWxhcml0eSkKYGBgCgpQb3IgbsOjbyBzZXIgbGluZWFyLCBwYXJhIG8gY8OhbGN1bG8gZGVzc2EgcmVsYcOnw6NvIG5vcyB1dGlsaXphbW9zIGRvcyBjb2VmaWNpZW50ZXMgZGUgU3BlYXJtYW4gZSBLZW5kYWxsLiBBdHJhdsOpcyBkZXNzZXMgcmVzdWx0YWRvcywgcG9kZW1vcyBkaXplciBxdWUgaMOhIHVtYSByZWxhw6fDo28gZnJhY2EgbmVnYXRpdmEgZW50cmUgZXNzYXMgdmFyacOhdmVpcy4gCgpgYGB7cn0KdG9wcyAlPiUgCiAgc3VtbWFyaXNlKHNwZWFybWFuID0gY29yKHZhbGVuY2UsIHRyYWNrLnBvcHVsYXJpdHksIG1ldGhvZCA9ICJzcGVhcm1hbiIpLAogICAgICAgICAgICBrZW5kYWxsID0gY29yKHZhbGVuY2UsIHRyYWNrLnBvcHVsYXJpdHksIG1ldGhvZCA9ICJrZW5kYWxsIiksICkKYGBgCgoKIyMjIyBDb20gay1tZWFucwoKQWluZGEgbWFudGVuZG8gYSBjdXJpb3NpZGFkZSBlbSByZWxhw6fDo28gw6BzIHZhcmnDoXZlaXMgdmFsw6puY2lhIGUgcG9wdWxhcmlkYWRlIGRhIG3DunNpY2EsIGFnb3JhIHF1ZXJlbW9zIGVudGVuZGVyIHBvc3PDrXZlaXMgZ3J1cG9zIHByZXNlbnRlcyBuZXNzZXMgZGFkb3MuIFBhcmEgaXNzbywgdHJhYmFsaGFtb3MgY29tIGstbWVhbnMgZSBvcyBncsOhZmljb3MgZ2VyYWRvcyBmb3JhbSBhdHJhdsOpcyBkbyBnZ3Bsb3RseSBwYXJhIHF1ZSBzZSBwdWRlc3NlIHRlciB1bWEgbWFpb3IgaW50ZXJhw6fDo28gY29tIGNhZGEgdW0gZG9zIGdydXBvcyBlbmNvbnRyYWRvcy4KClBhcmEgYXMgbWFpcyBvdXZpZGFzIGRvIEJyYXNpbCwgdW0gbsO6bWVybyBkZSBncnVwb3MgYSBxdWUgc2UgY2hlZ291IHVtIHJlc3VsdGFkbyBpbnRlcmVzc2FudGUgZm9pIGRlIDUuIERlc3NhIGZvcm1hLCBvcyBncnVwb3Mgb2JzZXJ2YWRvcyBzZSBkaXZpZGlyYW0gZW06ICoqbcO6c2ljYXMgbXVpdG8gcG9zaXRpdmFzIGUgcG91Y28gcG9wdWxhcmVzKiosICoqbcO6c2ljYXMgcG91Y28gcG9zaXRpdmFzIGUgcG91Y28gcG9wdWxhcmVzKiosICoqbcO6c2ljYXMgcG91Y28gcG9zaXRpdmFzIGUgbcOpZGlvIHBvcHVsYXJlcyoqLCAqKm3DunNpY2FzIG11aXRvIHBvc2l0aXZhcyBlIG3DqWRpbyBwb3B1bGFyZXMqKiwgKiptw7pzaWNhcyBtw6lkaW8gcG9zaXRpdmFzIGUgbXVpdG8gcG9wdWxhcmVzKiosIG8gcXVlIG1vc3RyYSBvIHF1YW50byBvIGdvc3RvIGRvcyBicmFzaWxlaXJvcyDDqSBkaXZlcnNvIG5vIHF1ZSBkaXogcmVzcGVpdG8gw6AgcG9zaXRpdmlkYWRlIGRlIHVtYSBtw7pzaWNhLgoKYGBge3IgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KdG9wc2JyYXNpbCA8LSB0b3BzICU+JSAgZmlsdGVyKHBsYXlsaXN0X25hbWUgPT0gIlRvcCBTb25ncyAtIEJyYXppbCIpCgpncnVwb3NiciA8LSB0b3BzYnJhc2lsICU+JQogICAgc2VsZWN0KHZhbGVuY2UsIHRyYWNrLnBvcHVsYXJpdHkpICU+JQogICAgZmlsdGVyKCFpcy5uYSh2YWxlbmNlICsgdHJhY2sucG9wdWxhcml0eSkpCnJvd25hbWVzKGdydXBvc2JyKSA8LSBtYWtlLm5hbWVzKHRvcHNicmFzaWwkdHJhY2submFtZSwgdW5pcXVlID0gVCkKCmdydXBvc2JyIDwtIHNjYWxlKGdydXBvc2JyKQpgYGAKCmBgYHtyfQpzZXQuc2VlZCgxMjM0KQpyZXMgPC0ga21lYW5zKGdydXBvc2JyLCA1KQpncnVwb3NicmFzaWwgPC0gZnZpel9jbHVzdGVyKHJlcywgZGF0YSA9IGdydXBvc2JyKSArCiAgdGhlbWVfcmVwb3J0KCkgKwogIGxhYnMoCiAgICB0aXRsZSA9ICJHcnVwb3MgcHJlc2VudGVzIG5hcyBtYWlzIG91dmlkYXMgZG8gQnJhc2lsIiwKICAgIHggPSAiVmFsw6puY2lhIiwKICAgIHkgPSAiUG9wdWxhcmlkYWRlIGRhIG3DunNpY2EiCiAgKQpnZ3Bsb3RseShncnVwb3NicmFzaWwpCmBgYAoKSsOhIGVtIHJlbGHDp8OjbyDDoHMgbWFpcyBvdXZpZGFzIGRvIG11bmRvLCBhIHF1YW50aWRhZGUgYXByb3ByaWFkYSBkZSBncnVwb3MgbsOjbyBmb2kgYSBtZXNtYSBkbyBCcmFzaWwuIEFxdWkgdGl2ZW1vcyBhIHByZXNlbsOnYSBkZSAzIGdydXBvcyBtYWlzIGRpc3RpbnRvcywgcXVlIHNlIGRpdmlkaXJhbSBhcGVuYXMgZW50cmUgKipwb3VjbyBwb3B1bGFyKiosICoqbcOpZGlvIHBvcHVsYXIqKiBlICoqbXVpdG8gcG9wdWxhcioqLCBqw6EgcXVlIGVtIHRvZG9zIGEgdmFsw6puY2lhIHNlIGRpc3BlcnNhIGJhc3RhbnRlLiBEZXNzYSBmb3JtYSwgbyBtdW5kbyBuw6NvIGFwcmVzZW50YSB0YW50YSBkaXN0aW7Dp8OjbyBlbnRyZSBhIHBvc2l0aXZpZGFkZSBkZSB1bWEgbcO6c2ljYSBwYXJhIHRvcm7DoS1sYSBtYWlzIHBvcHVsYXIgb3UgbsOjby4gCgpgYGB7ciBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQp0b3BzZ2xvYmFsIDwtIHRvcHMgJT4lICBmaWx0ZXIocGxheWxpc3RfbmFtZSA9PSAiVG9wIFNvbmdzIC0gR2xvYmFsIikKCmdydXBvc2diIDwtIHRvcHNnbG9iYWwgJT4lCiAgICBzZWxlY3QodmFsZW5jZSwgdHJhY2sucG9wdWxhcml0eSkgJT4lCiAgICBmaWx0ZXIoIWlzLm5hKHZhbGVuY2UgKyB0cmFjay5wb3B1bGFyaXR5KSkKcm93bmFtZXMoZ3J1cG9zZ2IpIDwtIG1ha2UubmFtZXModG9wc2dsb2JhbCR0cmFjay5uYW1lLCB1bmlxdWUgPSBUKQoKZ3J1cG9zIDwtIHNjYWxlKGdydXBvc2diKQpgYGAKCmBgYHtyfQpzZXQuc2VlZCgxMjM0KQpyZXMgPC0ga21lYW5zKGdydXBvc2diLCAzKQpncnVwb3NnbG9iYWwgPC0gZnZpel9jbHVzdGVyKHJlcywgZGF0YSA9IGdydXBvc2diKSArCiAgdGhlbWVfcmVwb3J0KCkgKwogIGxhYnMoCiAgICB0aXRsZSA9ICJHcnVwb3MgcHJlc2VudGVzIG5hcyBtYWlzIG91dmlkYXMgZG8gbXVuZG8iLAogICAgeCA9ICJWYWzDqm5jaWEiLAogICAgeSA9ICJQb3B1bGFyaWRhZGUgZGEgbcO6c2ljYSIKICApCmdncGxvdGx5KGdydXBvc2dsb2JhbCkKYGBgCgojIyMgQ29uY2x1c8OjbwoKRGlhbnRlIGRvIHF1ZSBmb2kgdmlzdG8sIGZvaSBwb3Nzw612ZWwgcGVyY2ViZXIgcXVhbnRhcyBkaWZlcmVudGVzIGFuw6FsaXNlcyBwb2RlbW9zIHJlYWxpemFyIGEgcGFydGlyIGRvcyBkYWRvcyBmb3JuZWNpZG9zIHBlbG8gU3BvdGlmeSBlIG8gcXVhbnRvIG9zIGdvc3RvcyBkZSB1bSBwYcOtcyBwb2RlbSBkaWZlcmlyIHF1YW5kbyBjb21wYXJhZG9zIGNvbSBvIHJlc3RvIGRvIG11bmRvLiDDiSBpbXBvcnRhbnRlIGxlbWJyYXIgcXVlIGVzdGEgw6kgdW1hIGJhc2UgbGltaXRhZGEgZGUgZGFkb3MsIHJlc3RyaW5naWRhIGEgdW1hIHNlbWFuYSBkZSBjb2xldGEgYXBlbmFzLCBqw6EgcXVlIG8gU3BvdGlmeSBuw6NvIGRpc3BvbmliaWxpemEgcGxheWxpc3RzIGRhcyBtYWlzIHRvY2FkYXMgZGUgdW0gcGVyw61vZG8gbWFpb3IgZGUgdGVtcG8uIFVtYSBwcm9wb3N0YSBpbnRlcmVzc2FudGUgcGFyYSBhIGNvbnRpbnVhw6fDo28gZGVzdGEgYW7DoWxpc2Ugc2VyaWEgYSBkZSBzZW1hbmFsbWVudGUgcmVwZXRpciBlc3NhIGNvbGV0YSBwb3IgdW0gbWFpb3IgcGVyw61vZG8gZGUgdGVtcG8sIGRlIGZvcm1hIGEgdHJhemVyIHVtYSBtYWlvciByaXF1ZXphIGRlIGRldGFsaGVzIGUgZGUgb2JzZXJ2YcOnw7VlcyBlbSByZWxhw6fDo28gYW9zIHBvc3PDrXZlaXMgZ29zdG9zIG11c2ljYWlzIGRvIEJyYXNpbCwgZG8gbXVuZG8gZSBhdMOpIG1lc21vIGRlIG91dHJvcyBwYcOtc2VzIHNlcGFyYWRhbWVudGUu