Exercise 1.

Using data on credit card applications’ status please present the frequency table with the nice, kable format for average monthly credit card expenditures of applicants.

library(dplyr)
library(knitr)
library(ggplot2)
library(tidyr)

df <- read.csv(file = "https://raw.githubusercontent.com/nnaemeka-git/payment/268bd51d03488e5c388231fa038fe0f86635433b/CreditCard.csv")

# Displaying the first rows:
head(df)
##   X card reports      age income       share expenditure owner selfemp
## 1 1  yes       0 37.66667 4.5200 0.033269910  124.983300   yes      no
## 2 2  yes       0 33.25000 2.4200 0.005216942    9.854167    no      no
## 3 3  yes       0 33.66667 4.5000 0.004155556   15.000000   yes      no
## 4 4  yes       0 30.50000 2.5400 0.065213780  137.869200    no      no
## 5 5  yes       0 32.16667 9.7867 0.067050590  546.503300   yes      no
## 6 6  yes       0 23.25000 2.5000 0.044438400   91.996670    no      no
##   dependents months majorcards active
## 1          3     54          1     12
## 2          3     34          1     13
## 3          4     58          1      5
## 4          0     25          1      7
## 5          2     64          1      5
## 6          0     54          1      1
# Creating a Frequency Table with Cases:
freq_table <- df %>%
  group_by(card) %>%
  summarize(
    yes_count = sum(case_when(owner == "yes" ~ 1, owner == "no" ~ 0)),
    no_count = sum(case_when(owner == "yes" ~ 0, owner == "no" ~ 1))
  )

# Displaying the Frequency Table with Kable Method
knitr::kable(freq_table, format = "markdown", col.names = c("Card Situation", "OWNER:Y", "OWNER:N"))
Card Situation OWNER:Y OWNER:N
no 90 206
yes 491 532

Exercise 2.

The data comes from https://flixgem.com/ (dataset version as of March 12, 2021). The data contains information on 9425 movies and series available on Netlix.

Answer with the most appropriate data visualization for the following questions:

  1. What is the distribution of Imdb scores for Polish movies and movie-series?
#Create Polsih Movies
polish_movies <- netflixData %>%
  filter(Languages == "Polish", Series.or.Movie == "Movie")

#Create Polsih Series
polish_series <- netflixData %>%
  filter(Languages == "Polish", Series.or.Movie == "Series")


# Plot histograms for IMDb scores for Polish movies and series
ggplot() +
  geom_histogram(data = polish_movies, aes(x = IMDb.Score), fill = "skyblue", alpha = 0.7) +
  geom_histogram(data = polish_series, aes(x = IMDb.Score), fill = "darkgreen", alpha = 0.7) +
  labs(title = "IMDb Scores for Polish Movies and Series",
       x = "IMDb Scores",
       y = "Frequency") +
  theme_minimal()

  1. What is the density function of Imdb scores for Polish movies and movie-series?
# Plot density for IMDb scores for Polish movies and series
ggplot() +
  geom_density(data = polish_movies, aes(x = IMDb.Score, fill = "Polish Movie"), alpha = 0.7) +
  geom_density(data = polish_series, aes(x = IMDb.Score, fill = "Polish Series"), alpha = 0.7) +
  labs(title = "Density Function of IMDb Scores for Polish Movies and Series",
       x = "IMDb Scores",
       y = "Density") +
  scale_fill_manual(values = c("darkred", "cyan")) +
  theme_minimal()

  1. What are the most popular languages available on Netflix?

We added a photo created on https://flixgem.com/

For extra credits:

Extra challenge 1.: Create a chart showing actors starring in the most popular productions.

# Filter out non-actor entries and aggregate data by actors
actor_popularity <- netflixData %>%
  filter(!is.na(Actors) & !Actors %in% c("", "111")) %>% # there was an error that i don't know how not otherwise resolve that a bar "111" would appear out of nowhere...
  separate_rows(Actors, sep = ", ") %>%
  group_by(Actors) %>%
  summarise(count = n()) %>%
  arrange(desc(count)) %>%
  slice_head(n = 10)

# Create a bar chart
ggplot(actor_popularity, aes(x = reorder(Actors, -count), y = count, fill = Actors)) +
  geom_bar(stat = "identity") +
  labs(title = "Top 10 Actors Starring in popular productions on Netflix",
       x = "Actor",
       y = "Number of Productions") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

Extra challenge 2.: For movies and series, create rating charts from the various portals (Hidden Gem, IMDb, Rotten Tomatoes, Metacritic). Hint: it’s a good idea to reshape the data to long format.

# Filtering out movies and series
netflix_filtered <- netflixData %>%
  filter(Series.or.Movie %in% c("Movie", "Series"))

# Reshaping the data to long format for ratings
ratings_long <- netflix_filtered %>%
  select(Title, Series.or.Movie, Hidden.Gem.Score, IMDb.Score, `Rotten.Tomatoes.Score`, `Metacritic.Score`) %>%
  pivot_longer(cols = c(Hidden.Gem.Score, IMDb.Score, `Rotten.Tomatoes.Score`, `Metacritic.Score`), 
               names_to = "Rating_Source", 
               values_to = "Rating") %>%
  filter(!is.na(Rating))

# Hidden Gem Score chart
ggplot(ratings_long %>% filter(Rating_Source == "Hidden.Gem.Score"), 
       aes(x = Rating, fill = Rating_Source)) +
  geom_histogram(binwidth = 0.5, alpha = 0.7) +
  scale_fill_manual(values = c("Hidden.Gem.Score" = "blue")) +
  facet_wrap(~Series.or.Movie, scales = "free", nrow = 2) +
  labs(title = "Hidden Gem Score Distribution",
       x = "Hidden Gem Score",
       y = "Count") +
  theme_minimal()

# IMDb Score chart with unique color
ggplot(ratings_long %>% filter(Rating_Source == "IMDb.Score"), 
       aes(x = Rating, fill = Rating_Source)) +
  geom_histogram(binwidth = 0.5, alpha = 0.7) +
  scale_fill_manual(values = c("IMDb.Score" = "green")) +
  facet_wrap(~Series.or.Movie, scales = "free", nrow = 2) +
  labs(title = "IMDb Score Distribution",
       x = "IMDb Score",
       y = "Count") +
  theme_minimal()

# Rotten Tomatoes Score chart 
ggplot(ratings_long %>% filter(Rating_Source == "Rotten.Tomatoes.Score"), 
       aes(x = Rating, fill = Rating_Source)) +
  geom_histogram(binwidth = 0.5, alpha = 0.7) +
  scale_fill_manual(values = c("Rotten.Tomatoes.Score" = "red")) +
  facet_wrap(~Series.or.Movie, scales = "free", nrow = 2) +
  labs(title = "Rotten Tomatoes Score Distribution",
       x = "Rotten Tomatoes Score",
       y = "Count") +
  theme_minimal()

# Metacritic Score chart 
ggplot(ratings_long %>% filter(Rating_Source == "Metacritic.Score"), 
       aes(x = Rating, fill = Rating_Source)) +
  geom_histogram(binwidth = 0.5, alpha = 0.7) +
  scale_fill_manual(values = c("Metacritic.Score" = "purple")) +
  facet_wrap(~Series.or.Movie, scales = "free", nrow = 2) +
  labs(title = "Metacritic Score Distribution",
       x = "Metacritic Score",
       y = "Count") +
  theme_minimal()

Extra challenge 3.: Which film studios produce the most and how has this changed over the years?

Comment from Stanisław: unfortunately not done to well, because the individual Production.House is overshadoved by the overall count and I dont know how to fix it. I tried finding the most dominant house first then plotting just it, but it didn’t quite work, so I left this because it at least shows that netflix was dominant.

# Aggregating data by Production.House
production_studios <- netflix_filtered %>%
  group_by(Production.House, Release.Year = lubridate::year(as.Date(Release.Date))) %>%
  summarise(count = n()) %>%
  filter(!is.na(Release.Year)) %>%
  arrange(desc(count))

# Creating a line chart to show the trend with labels for each production house
ggplot(production_studios, aes(x = Release.Year, y = count, group = Production.House, color = Production.House, label = Production.House)) +
  geom_line() +
  geom_text(aes(label = Production.House), hjust = -0.2, vjust = 0.5, size = 3, color = "black", check_overlap = TRUE) +
  labs(title = "Production Trend by Film Studios Over Years",
       x = "Release Year",
       y = "Number of Productions") +
  theme_minimal() +
  theme(legend.position = "none")

LS0tDQp0aXRsZTogIkRhdGEgVmlzdWFsaXphdGlvbiINCmF1dGhvcjogIlRvbWFzeiBLcnVjemFsYWssIEtyenlzaWNhIFN0YW5pc8WCYXcsIEhhdGljZSBUYXRsaSINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDogDQogICAgdGhlbWU6IGNlcnVsZWFuDQogICAgaGlnaGxpZ2h0OiB0ZXh0bWF0ZQ0KICAgIGZvbnRzaXplOiA4cHQNCiAgICB0b2M6IHllcw0KICAgIGNvZGVfZG93bmxvYWQ6IHllcw0KICAgIHRvY19mbG9hdDoNCiAgICAgIGNvbGxhcHNlZDogbm8NCiAgICBkZl9wcmludDogZGVmYXVsdA0KICAgIHRvY19kZXB0aDogNQ0KZWRpdG9yX29wdGlvbnM6IA0KICBtYXJrZG93bjogDQogICAgd3JhcDogNzINCi0tLQ0KDQoNCg0KYGBge3IsIGluY2x1ZGU9RkFMU0V9DQojIyBHbG9iYWwgb3B0aW9ucw0Kb3B0aW9ucyhxd3JhcHMyX21hcmt1cCA9ICJtYXJrZG93biIpDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeShrbml0cikNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkodGlkeXIpDQprbml0cjo6b3B0c19jaHVuayRzZXQod2FybmluZyA9IEZBTFNFLCBtZXNzYWdlID0gRkFMU0UpDQpgYGANCg0KIyMgRXhlcmNpc2UgMS4gDQoNClVzaW5nIGRhdGEgb24gY3JlZGl0IGNhcmQgYXBwbGljYXRpb25zJyBzdGF0dXMgcGxlYXNlIHByZXNlbnQgdGhlIGZyZXF1ZW5jeSB0YWJsZSB3aXRoIHRoZSBuaWNlLCBrYWJsZSBmb3JtYXQgZm9yIGF2ZXJhZ2UgbW9udGhseSBjcmVkaXQgY2FyZCBleHBlbmRpdHVyZXMgb2YgYXBwbGljYW50cy4NCg0KYGBge3IgZXgxfQ0KbGlicmFyeShkcGx5cikNCmxpYnJhcnkoa25pdHIpDQpsaWJyYXJ5KGdncGxvdDIpDQpsaWJyYXJ5KHRpZHlyKQ0KDQpkZiA8LSByZWFkLmNzdihmaWxlID0gImh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9ubmFlbWVrYS1naXQvcGF5bWVudC8yNjhiZDUxZDAzNDg4ZTVjMzg4MjMxZmEwMzhmZTBmODY2MzU0MzNiL0NyZWRpdENhcmQuY3N2IikNCg0KIyBEaXNwbGF5aW5nIHRoZSBmaXJzdCByb3dzOg0KaGVhZChkZikNCg0KIyBDcmVhdGluZyBhIEZyZXF1ZW5jeSBUYWJsZSB3aXRoIENhc2VzOg0KZnJlcV90YWJsZSA8LSBkZiAlPiUNCiAgZ3JvdXBfYnkoY2FyZCkgJT4lDQogIHN1bW1hcml6ZSgNCiAgICB5ZXNfY291bnQgPSBzdW0oY2FzZV93aGVuKG93bmVyID09ICJ5ZXMiIH4gMSwgb3duZXIgPT0gIm5vIiB+IDApKSwNCiAgICBub19jb3VudCA9IHN1bShjYXNlX3doZW4ob3duZXIgPT0gInllcyIgfiAwLCBvd25lciA9PSAibm8iIH4gMSkpDQogICkNCg0KIyBEaXNwbGF5aW5nIHRoZSBGcmVxdWVuY3kgVGFibGUgd2l0aCBLYWJsZSBNZXRob2QNCmtuaXRyOjprYWJsZShmcmVxX3RhYmxlLCBmb3JtYXQgPSAibWFya2Rvd24iLCBjb2wubmFtZXMgPSBjKCJDYXJkIFNpdHVhdGlvbiIsICJPV05FUjpZIiwgIk9XTkVSOk4iKSkNCg0KYGBgDQoNCg0KIyMgRXhlcmNpc2UgMi4NCg0KVGhlIGRhdGEgY29tZXMgZnJvbSBbaHR0cHM6Ly9mbGl4Z2VtLmNvbS9dKGh0dHBzOi8vZmxpeGdlbS5jb20vKSAoZGF0YXNldCB2ZXJzaW9uIGFzIG9mIE1hcmNoIDEyLCAyMDIxKS4gVGhlIGRhdGEgY29udGFpbnMgaW5mb3JtYXRpb24gb24gOTQyNSBtb3ZpZXMgYW5kIHNlcmllcyBhdmFpbGFibGUgb24gTmV0bGl4Lg0KDQpgYGB7ciBleDIsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGluY2x1ZGU9RkFMU0V9DQpkb3dubG9hZC5maWxlKCJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20va2ZsaXNpa293c2tpL2RzL21hc3Rlci9uZXRmbGl4LWRhdGFzZXQuY3N2P3Jhdz10cnVlIiwgZGVzdGZpbGUgPSJkYW5lLmNzdiIsbW9kZT0id2IiKQ0KbmV0ZmxpeERhdGE8LXJlYWQuY3N2KGZpbGU9ImRhbmUuY3N2IixlbmNvZGluZyA9IlVURi04IixoZWFkZXI9VFJVRSxzZXAgPSAiLCIpDQphdHRhY2gobmV0ZmxpeERhdGEpDQoNCmBgYA0KDQpBbnN3ZXIgd2l0aCB0aGUgbW9zdCBhcHByb3ByaWF0ZSBkYXRhIHZpc3VhbGl6YXRpb24gZm9yIHRoZSBmb2xsb3dpbmcgcXVlc3Rpb25zOg0KDQoxLiBXaGF0IGlzIHRoZSBkaXN0cmlidXRpb24gb2YgSW1kYiBzY29yZXMgZm9yIFBvbGlzaCBtb3ZpZXMgYW5kIG1vdmllLXNlcmllcz8NCg0KYGBge3IgZXgyXzF9DQojQ3JlYXRlIFBvbHNpaCBNb3ZpZXMNCnBvbGlzaF9tb3ZpZXMgPC0gbmV0ZmxpeERhdGEgJT4lDQogIGZpbHRlcihMYW5ndWFnZXMgPT0gIlBvbGlzaCIsIFNlcmllcy5vci5Nb3ZpZSA9PSAiTW92aWUiKQ0KDQojQ3JlYXRlIFBvbHNpaCBTZXJpZXMNCnBvbGlzaF9zZXJpZXMgPC0gbmV0ZmxpeERhdGEgJT4lDQogIGZpbHRlcihMYW5ndWFnZXMgPT0gIlBvbGlzaCIsIFNlcmllcy5vci5Nb3ZpZSA9PSAiU2VyaWVzIikNCg0KDQojIFBsb3QgaGlzdG9ncmFtcyBmb3IgSU1EYiBzY29yZXMgZm9yIFBvbGlzaCBtb3ZpZXMgYW5kIHNlcmllcw0KZ2dwbG90KCkgKw0KICBnZW9tX2hpc3RvZ3JhbShkYXRhID0gcG9saXNoX21vdmllcywgYWVzKHggPSBJTURiLlNjb3JlKSwgZmlsbCA9ICJza3libHVlIiwgYWxwaGEgPSAwLjcpICsNCiAgZ2VvbV9oaXN0b2dyYW0oZGF0YSA9IHBvbGlzaF9zZXJpZXMsIGFlcyh4ID0gSU1EYi5TY29yZSksIGZpbGwgPSAiZGFya2dyZWVuIiwgYWxwaGEgPSAwLjcpICsNCiAgbGFicyh0aXRsZSA9ICJJTURiIFNjb3JlcyBmb3IgUG9saXNoIE1vdmllcyBhbmQgU2VyaWVzIiwNCiAgICAgICB4ID0gIklNRGIgU2NvcmVzIiwNCiAgICAgICB5ID0gIkZyZXF1ZW5jeSIpICsNCiAgdGhlbWVfbWluaW1hbCgpDQpgYGANCg0KMi4gV2hhdCBpcyB0aGUgZGVuc2l0eSBmdW5jdGlvbiBvZiBJbWRiIHNjb3JlcyBmb3IgUG9saXNoIG1vdmllcyBhbmQgbW92aWUtc2VyaWVzPw0KDQpgYGB7ciBleDJfMn0NCiMgUGxvdCBkZW5zaXR5IGZvciBJTURiIHNjb3JlcyBmb3IgUG9saXNoIG1vdmllcyBhbmQgc2VyaWVzDQpnZ3Bsb3QoKSArDQogIGdlb21fZGVuc2l0eShkYXRhID0gcG9saXNoX21vdmllcywgYWVzKHggPSBJTURiLlNjb3JlLCBmaWxsID0gIlBvbGlzaCBNb3ZpZSIpLCBhbHBoYSA9IDAuNykgKw0KICBnZW9tX2RlbnNpdHkoZGF0YSA9IHBvbGlzaF9zZXJpZXMsIGFlcyh4ID0gSU1EYi5TY29yZSwgZmlsbCA9ICJQb2xpc2ggU2VyaWVzIiksIGFscGhhID0gMC43KSArDQogIGxhYnModGl0bGUgPSAiRGVuc2l0eSBGdW5jdGlvbiBvZiBJTURiIFNjb3JlcyBmb3IgUG9saXNoIE1vdmllcyBhbmQgU2VyaWVzIiwNCiAgICAgICB4ID0gIklNRGIgU2NvcmVzIiwNCiAgICAgICB5ID0gIkRlbnNpdHkiKSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoImRhcmtyZWQiLCAiY3lhbiIpKSArDQogIHRoZW1lX21pbmltYWwoKQ0KYGBgDQoNCjMuIFdoYXQgYXJlIHRoZSBtb3N0IHBvcHVsYXIgbGFuZ3VhZ2VzIGF2YWlsYWJsZSBvbiBOZXRmbGl4Pw0KDQpXZSBhZGRlZCBhIHBob3RvIGNyZWF0ZWQgb24gaHR0cHM6Ly9mbGl4Z2VtLmNvbS8NCg0KRm9yIGV4dHJhIGNyZWRpdHM6DQoNCipFeHRyYSBjaGFsbGVuZ2UgMS4qOiBDcmVhdGUgYSBjaGFydCBzaG93aW5nIGFjdG9ycyBzdGFycmluZyBpbiB0aGUgbW9zdCBwb3B1bGFyIHByb2R1Y3Rpb25zLg0KDQpgYGB7ciBjaGFsbGVuZ2UxfQ0KIyBGaWx0ZXIgb3V0IG5vbi1hY3RvciBlbnRyaWVzIGFuZCBhZ2dyZWdhdGUgZGF0YSBieSBhY3RvcnMNCmFjdG9yX3BvcHVsYXJpdHkgPC0gbmV0ZmxpeERhdGEgJT4lDQogIGZpbHRlcighaXMubmEoQWN0b3JzKSAmICFBY3RvcnMgJWluJSBjKCIiLCAiMTExIikpICU+JSAjIHRoZXJlIHdhcyBhbiBlcnJvciB0aGF0IGkgZG9uJ3Qga25vdyBob3cgbm90IG90aGVyd2lzZSByZXNvbHZlIHRoYXQgYSBiYXIgIjExMSIgd291bGQgYXBwZWFyIG91dCBvZiBub3doZXJlLi4uDQogIHNlcGFyYXRlX3Jvd3MoQWN0b3JzLCBzZXAgPSAiLCAiKSAlPiUNCiAgZ3JvdXBfYnkoQWN0b3JzKSAlPiUNCiAgc3VtbWFyaXNlKGNvdW50ID0gbigpKSAlPiUNCiAgYXJyYW5nZShkZXNjKGNvdW50KSkgJT4lDQogIHNsaWNlX2hlYWQobiA9IDEwKQ0KDQojIENyZWF0ZSBhIGJhciBjaGFydA0KZ2dwbG90KGFjdG9yX3BvcHVsYXJpdHksIGFlcyh4ID0gcmVvcmRlcihBY3RvcnMsIC1jb3VudCksIHkgPSBjb3VudCwgZmlsbCA9IEFjdG9ycykpICsNCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIpICsNCiAgbGFicyh0aXRsZSA9ICJUb3AgMTAgQWN0b3JzIFN0YXJyaW5nIGluIHBvcHVsYXIgcHJvZHVjdGlvbnMgb24gTmV0ZmxpeCIsDQogICAgICAgeCA9ICJBY3RvciIsDQogICAgICAgeSA9ICJOdW1iZXIgb2YgUHJvZHVjdGlvbnMiKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpDQpgYGANCg0KDQoqRXh0cmEgY2hhbGxlbmdlIDIuKjogRm9yIG1vdmllcyBhbmQgc2VyaWVzLCBjcmVhdGUgcmF0aW5nIGNoYXJ0cyBmcm9tIHRoZSB2YXJpb3VzIHBvcnRhbHMgKEhpZGRlbiBHZW0sIElNRGIsIFJvdHRlbiBUb21hdG9lcywgTWV0YWNyaXRpYykuIEhpbnQ6IGl0J3MgYSBnb29kIGlkZWEgdG8gcmVzaGFwZSB0aGUgZGF0YSB0byAqbG9uZyogZm9ybWF0Lg0KDQpgYGB7ciBjaGFsbGVuZ2UyfQ0KIyBGaWx0ZXJpbmcgb3V0IG1vdmllcyBhbmQgc2VyaWVzDQpuZXRmbGl4X2ZpbHRlcmVkIDwtIG5ldGZsaXhEYXRhICU+JQ0KICBmaWx0ZXIoU2VyaWVzLm9yLk1vdmllICVpbiUgYygiTW92aWUiLCAiU2VyaWVzIikpDQoNCiMgUmVzaGFwaW5nIHRoZSBkYXRhIHRvIGxvbmcgZm9ybWF0IGZvciByYXRpbmdzDQpyYXRpbmdzX2xvbmcgPC0gbmV0ZmxpeF9maWx0ZXJlZCAlPiUNCiAgc2VsZWN0KFRpdGxlLCBTZXJpZXMub3IuTW92aWUsIEhpZGRlbi5HZW0uU2NvcmUsIElNRGIuU2NvcmUsIGBSb3R0ZW4uVG9tYXRvZXMuU2NvcmVgLCBgTWV0YWNyaXRpYy5TY29yZWApICU+JQ0KICBwaXZvdF9sb25nZXIoY29scyA9IGMoSGlkZGVuLkdlbS5TY29yZSwgSU1EYi5TY29yZSwgYFJvdHRlbi5Ub21hdG9lcy5TY29yZWAsIGBNZXRhY3JpdGljLlNjb3JlYCksIA0KICAgICAgICAgICAgICAgbmFtZXNfdG8gPSAiUmF0aW5nX1NvdXJjZSIsIA0KICAgICAgICAgICAgICAgdmFsdWVzX3RvID0gIlJhdGluZyIpICU+JQ0KICBmaWx0ZXIoIWlzLm5hKFJhdGluZykpDQoNCiMgSGlkZGVuIEdlbSBTY29yZSBjaGFydA0KZ2dwbG90KHJhdGluZ3NfbG9uZyAlPiUgZmlsdGVyKFJhdGluZ19Tb3VyY2UgPT0gIkhpZGRlbi5HZW0uU2NvcmUiKSwgDQogICAgICAgYWVzKHggPSBSYXRpbmcsIGZpbGwgPSBSYXRpbmdfU291cmNlKSkgKw0KICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDAuNSwgYWxwaGEgPSAwLjcpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiSGlkZGVuLkdlbS5TY29yZSIgPSAiYmx1ZSIpKSArDQogIGZhY2V0X3dyYXAoflNlcmllcy5vci5Nb3ZpZSwgc2NhbGVzID0gImZyZWUiLCBucm93ID0gMikgKw0KICBsYWJzKHRpdGxlID0gIkhpZGRlbiBHZW0gU2NvcmUgRGlzdHJpYnV0aW9uIiwNCiAgICAgICB4ID0gIkhpZGRlbiBHZW0gU2NvcmUiLA0KICAgICAgIHkgPSAiQ291bnQiKSArDQogIHRoZW1lX21pbmltYWwoKQ0KDQojIElNRGIgU2NvcmUgY2hhcnQgd2l0aCB1bmlxdWUgY29sb3INCmdncGxvdChyYXRpbmdzX2xvbmcgJT4lIGZpbHRlcihSYXRpbmdfU291cmNlID09ICJJTURiLlNjb3JlIiksIA0KICAgICAgIGFlcyh4ID0gUmF0aW5nLCBmaWxsID0gUmF0aW5nX1NvdXJjZSkpICsNCiAgZ2VvbV9oaXN0b2dyYW0oYmlud2lkdGggPSAwLjUsIGFscGhhID0gMC43KSArDQogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIklNRGIuU2NvcmUiID0gImdyZWVuIikpICsNCiAgZmFjZXRfd3JhcCh+U2VyaWVzLm9yLk1vdmllLCBzY2FsZXMgPSAiZnJlZSIsIG5yb3cgPSAyKSArDQogIGxhYnModGl0bGUgPSAiSU1EYiBTY29yZSBEaXN0cmlidXRpb24iLA0KICAgICAgIHggPSAiSU1EYiBTY29yZSIsDQogICAgICAgeSA9ICJDb3VudCIpICsNCiAgdGhlbWVfbWluaW1hbCgpDQoNCiMgUm90dGVuIFRvbWF0b2VzIFNjb3JlIGNoYXJ0IA0KZ2dwbG90KHJhdGluZ3NfbG9uZyAlPiUgZmlsdGVyKFJhdGluZ19Tb3VyY2UgPT0gIlJvdHRlbi5Ub21hdG9lcy5TY29yZSIpLCANCiAgICAgICBhZXMoeCA9IFJhdGluZywgZmlsbCA9IFJhdGluZ19Tb3VyY2UpKSArDQogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMC41LCBhbHBoYSA9IDAuNykgKw0KICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCJSb3R0ZW4uVG9tYXRvZXMuU2NvcmUiID0gInJlZCIpKSArDQogIGZhY2V0X3dyYXAoflNlcmllcy5vci5Nb3ZpZSwgc2NhbGVzID0gImZyZWUiLCBucm93ID0gMikgKw0KICBsYWJzKHRpdGxlID0gIlJvdHRlbiBUb21hdG9lcyBTY29yZSBEaXN0cmlidXRpb24iLA0KICAgICAgIHggPSAiUm90dGVuIFRvbWF0b2VzIFNjb3JlIiwNCiAgICAgICB5ID0gIkNvdW50IikgKw0KICB0aGVtZV9taW5pbWFsKCkNCg0KIyBNZXRhY3JpdGljIFNjb3JlIGNoYXJ0IA0KZ2dwbG90KHJhdGluZ3NfbG9uZyAlPiUgZmlsdGVyKFJhdGluZ19Tb3VyY2UgPT0gIk1ldGFjcml0aWMuU2NvcmUiKSwgDQogICAgICAgYWVzKHggPSBSYXRpbmcsIGZpbGwgPSBSYXRpbmdfU291cmNlKSkgKw0KICBnZW9tX2hpc3RvZ3JhbShiaW53aWR0aCA9IDAuNSwgYWxwaGEgPSAwLjcpICsNCiAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiTWV0YWNyaXRpYy5TY29yZSIgPSAicHVycGxlIikpICsNCiAgZmFjZXRfd3JhcCh+U2VyaWVzLm9yLk1vdmllLCBzY2FsZXMgPSAiZnJlZSIsIG5yb3cgPSAyKSArDQogIGxhYnModGl0bGUgPSAiTWV0YWNyaXRpYyBTY29yZSBEaXN0cmlidXRpb24iLA0KICAgICAgIHggPSAiTWV0YWNyaXRpYyBTY29yZSIsDQogICAgICAgeSA9ICJDb3VudCIpICsNCiAgdGhlbWVfbWluaW1hbCgpDQpgYGANCg0KKkV4dHJhIGNoYWxsZW5nZSAzLio6IFdoaWNoIGZpbG0gc3R1ZGlvcyBwcm9kdWNlIHRoZSBtb3N0IGFuZCBob3cgaGFzIHRoaXMgY2hhbmdlZCBvdmVyIHRoZSB5ZWFycz8NCg0KQ29tbWVudCBmcm9tIFN0YW5pc8WCYXc6IHVuZm9ydHVuYXRlbHkgbm90IGRvbmUgdG8gd2VsbCwgYmVjYXVzZSB0aGUgaW5kaXZpZHVhbCBQcm9kdWN0aW9uLkhvdXNlIGlzIG92ZXJzaGFkb3ZlZCBieSB0aGUgb3ZlcmFsbCBjb3VudCBhbmQgSSBkb250IGtub3cgaG93IHRvIGZpeCBpdC4gSSB0cmllZCBmaW5kaW5nIHRoZSBtb3N0IGRvbWluYW50IGhvdXNlIGZpcnN0IHRoZW4gcGxvdHRpbmcganVzdCBpdCwgYnV0IGl0IGRpZG4ndCBxdWl0ZSB3b3JrLCBzbyBJIGxlZnQgdGhpcyBiZWNhdXNlIGl0IGF0IGxlYXN0IHNob3dzIHRoYXQgbmV0ZmxpeCB3YXMgZG9taW5hbnQuDQoNCmBgYHtyIGNoYWxsZW5nZTN9DQoNCiMgQWdncmVnYXRpbmcgZGF0YSBieSBQcm9kdWN0aW9uLkhvdXNlDQpwcm9kdWN0aW9uX3N0dWRpb3MgPC0gbmV0ZmxpeF9maWx0ZXJlZCAlPiUNCiAgZ3JvdXBfYnkoUHJvZHVjdGlvbi5Ib3VzZSwgUmVsZWFzZS5ZZWFyID0gbHVicmlkYXRlOjp5ZWFyKGFzLkRhdGUoUmVsZWFzZS5EYXRlKSkpICU+JQ0KICBzdW1tYXJpc2UoY291bnQgPSBuKCkpICU+JQ0KICBmaWx0ZXIoIWlzLm5hKFJlbGVhc2UuWWVhcikpICU+JQ0KICBhcnJhbmdlKGRlc2MoY291bnQpKQ0KDQojIENyZWF0aW5nIGEgbGluZSBjaGFydCB0byBzaG93IHRoZSB0cmVuZCB3aXRoIGxhYmVscyBmb3IgZWFjaCBwcm9kdWN0aW9uIGhvdXNlDQpnZ3Bsb3QocHJvZHVjdGlvbl9zdHVkaW9zLCBhZXMoeCA9IFJlbGVhc2UuWWVhciwgeSA9IGNvdW50LCBncm91cCA9IFByb2R1Y3Rpb24uSG91c2UsIGNvbG9yID0gUHJvZHVjdGlvbi5Ib3VzZSwgbGFiZWwgPSBQcm9kdWN0aW9uLkhvdXNlKSkgKw0KICBnZW9tX2xpbmUoKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSBQcm9kdWN0aW9uLkhvdXNlKSwgaGp1c3QgPSAtMC4yLCB2anVzdCA9IDAuNSwgc2l6ZSA9IDMsIGNvbG9yID0gImJsYWNrIiwgY2hlY2tfb3ZlcmxhcCA9IFRSVUUpICsNCiAgbGFicyh0aXRsZSA9ICJQcm9kdWN0aW9uIFRyZW5kIGJ5IEZpbG0gU3R1ZGlvcyBPdmVyIFllYXJzIiwNCiAgICAgICB4ID0gIlJlbGVhc2UgWWVhciIsDQogICAgICAgeSA9ICJOdW1iZXIgb2YgUHJvZHVjdGlvbnMiKSArDQogIHRoZW1lX21pbmltYWwoKSArDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikNCg0KYGBg