Introduction

Executive Summary

The world of the movie business is an area where there are a variety of variables to analyze and generate success in a series or movie for the next hit that people will be talking about, but you have to take into account the exact variables of a database and give a good analysis to see what strategy should be taken into account to take action.

Objectives

At the end of this evidence, several pre-established objectives will be resolved to provide greater transparency and quality data on what variables generate the success of a film, in order to reach this result:

  • Treatment to NAs

  • Information cleaning

  • Data organization

  • Information analysis

  • Answer to the main question

Body

Data description

First of all, it is to call the libraries, tools and database that we are going to realize to give different treatments, manipulate and organize information to have a visible result.

Libraries

#Calling Libraries
library(units)
## Warning: package 'units' was built under R version 4.3.3
## udunits database from C:/Users/Carlos/AppData/Local/R/win-library/4.3/units/share/udunits/udunits2.xml
library(visdat)
## Warning: package 'visdat' was built under R version 4.3.3
library(DataExplorer)
## Warning: package 'DataExplorer' was built under R version 4.3.3
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(janitor)
## Warning: package 'janitor' was built under R version 4.3.3
## 
## Attaching package: 'janitor'
## The following objects are masked from 'package:stats':
## 
##     chisq.test, fisher.test
library(tidyverse)
## Warning: package 'tidyverse' was built under R version 4.3.3
## Warning: package 'ggplot2' was built under R version 4.3.3
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ forcats   1.0.0     ✔ readr     2.1.5
## ✔ ggplot2   3.5.0     ✔ stringr   1.5.1
## ✔ lubridate 1.9.3     ✔ tibble    3.2.1
## ✔ purrr     1.0.2     ✔ tidyr     1.3.1
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(stringr)
library(tidyr)
library(readr)
library(ggplot2)

Database

#Callling Database
movies <- read.csv("C:\\Users\\Carlos\\Desktop\\movies_metadata.csv")

Data cleaning conducted

Treatment of NAs

#Search how many NAs are in the database
sum(is.na(movies))
## [1] 281
# Search in each column how many NAs exist to see what type of elimination to apply
sapply(movies, function(x) sum(is.na(x)))
##                 adult belongs_to_collection                budget 
##                     0                     0                     0 
##                genres              homepage                    id 
##                     0                     0                     0 
##               imdb_id     original_language        original_title 
##                     0                     0                     0 
##              overview            popularity           poster_path 
##                     0                     0                     0 
##  production_companies  production_countries          release_date 
##                     0                     0                     0 
##               revenue               runtime      spoken_languages 
##                     6                   263                     0 
##                status               tagline                 title 
##                     0                     0                     0 
##                 video          vote_average            vote_count 
##                     0                     6                     6
# Cleaning and summary of column "runtime"
movies2 <- movies

movies2$runtime[is.na(movies2$runtime)] <- mean(movies2$runtime, na.rm=TRUE)
summary(movies2$runtime)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    0.00   85.00   95.00   94.13  107.00 1256.00
# Cleaning and summary of column "revenue"
movies3 <- movies2

movies3$revenue[is.na(movies3$revenue)] <- mean(movies3$revenue, na.rm=TRUE)
summary(movies3$revenue)
##      Min.   1st Qu.    Median      Mean   3rd Qu.      Max. 
## 0.000e+00 0.000e+00 0.000e+00 1.121e+07 0.000e+00 2.788e+09
# Cleaning and summary of column "vote count"
movies4 <- movies3

movies4$vote_count[is.na(movies4$vote_count)] <- mean(movies4$vote_count, na.rm=TRUE)
summary(movies4$vote_count)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##     0.0     3.0    10.0   109.9    34.0 14075.0
# Cleaning and summary of column "vote average"
movies_wo_na <- movies4

movies_wo_na$vote_average[is.na(movies_wo_na$vote_average)] <- mean(movies_wo_na$vote_average, na.rm=TRUE)
summary(movies_wo_na$vote_average)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   0.000   5.000   6.000   5.618   6.800  10.000
#Verifying NAs
sum(is.na(movies_wo_na))
## [1] 0

Reasoning

The method of elimination used for the NAs was by taking the average, which was decided for two reasons.
- Because in the analysis of the columns it was possible to obtain that the values that contained NA were numeric and integers runtime, vote average, vote count, revenue.
- The missing values are important and it is desired to preserve the general structure of the data.

Treatment of duplicates and partially duplicates

# Check how many information are totally duplicated
sum(duplicated(movies_wo_na)) 
## [1] 17
# Eliminate information that is totally duplicated
movies_wo_dup <- movies_wo_na
movies_wo_dup <- distinct(movies_wo_dup)
# Check if duplicate information is eliminated
sum(duplicated(movies_wo_dup))
## [1] 0
# Check information that could be partially duplicated
movies_wo_dup %>% 
  count(id) %>%
  filter(n > 1)
##        id n
## 1   10991 2
## 2  109962 2
## 3  110428 2
## 4   12600 2
## 5   13209 2
## 6  132641 2
## 7   14788 2
## 8   15028 2
## 9   22649 2
## 10   4912 2
## 11  69234 2
## 12  77221 2
## 13  84198 2
# Check the rows for specific duplicates

id_values <- c("10991")

selected_rows <- movies_wo_dup[movies_wo_dup$id %in% id_values, ]

selected_rows # Differ in popularity
##       adult
## 4114  False
## 44806 False
##                                                                                                                                     belongs_to_collection
## 4114  {'id': 34055, 'name': 'Pokémon Collection', 'poster_path': '/j5te0YNZAMXDBnsqTUDKIBEt8iu.jpg', 'backdrop_path': '/iGoYKA0TFfgSoZpG2u5viTJMGfK.jpg'}
## 44806 {'id': 34055, 'name': 'Pokémon Collection', 'poster_path': '/j5te0YNZAMXDBnsqTUDKIBEt8iu.jpg', 'backdrop_path': '/iGoYKA0TFfgSoZpG2u5viTJMGfK.jpg'}
##         budget
## 4114  16000000
## 44806 16000000
##                                                                                                                                                                 genres
## 4114  [{'id': 12, 'name': 'Adventure'}, {'id': 14, 'name': 'Fantasy'}, {'id': 16, 'name': 'Animation'}, {'id': 28, 'name': 'Action'}, {'id': 10751, 'name': 'Family'}]
## 44806 [{'id': 12, 'name': 'Adventure'}, {'id': 14, 'name': 'Fantasy'}, {'id': 16, 'name': 'Animation'}, {'id': 28, 'name': 'Action'}, {'id': 10751, 'name': 'Family'}]
##                                homepage    id   imdb_id original_language
## 4114  http://movies.warnerbros.com/pk3/ 10991 tt0235679                ja
## 44806 http://movies.warnerbros.com/pk3/ 10991 tt0235679                ja
##             original_title
## 4114  Pokémon 3: The Movie
## 44806 Pokémon 3: The Movie
##                                                                                                                                                                                                                                                                                                                                                         overview
## 4114  When Molly Hale's sadness of her father's disappearance get to her, she unknowingly uses the Unown to create her own dream world along with Entei, who she believes to be her father. When Entei kidnaps Ash's mom, Ash along with Misty & Brock invade the mansion looking for his mom and trying to stop the mysteries of Molly's Dream World and Entei!
## 44806 When Molly Hale's sadness of her father's disappearance get to her, she unknowingly uses the Unown to create her own dream world along with Entei, who she believes to be her father. When Entei kidnaps Ash's mom, Ash along with Misty & Brock invade the mansion looking for his mom and trying to stop the mysteries of Molly's Dream World and Entei!
##       popularity                      poster_path
## 4114   10.264597 /5ILjS6XB5deiHop8SXPsYxXWVPE.jpg
## 44806   6.480376 /5ILjS6XB5deiHop8SXPsYxXWVPE.jpg
##                                                                                                                                                                                                                                                                                                                               production_companies
## 4114  [{'name': 'TV Tokyo', 'id': 3034}, {'name': '4 Kids Entertainment', 'id': 3035}, {'name': 'Nintendo', 'id': 12288}, {'name': 'Pikachu Project', 'id': 12653}, {'name': 'Oriental Light and Magic (OLM)', 'id': 66289}, {'name': "Kids' WB", 'id': 89163}, {'name': 'Pikachu Project 2001', 'id': 89164}, {'name': 'Shoakuken', 'id': 89165}]
## 44806 [{'name': 'TV Tokyo', 'id': 3034}, {'name': '4 Kids Entertainment', 'id': 3035}, {'name': 'Nintendo', 'id': 12288}, {'name': 'Pikachu Project', 'id': 12653}, {'name': 'Oriental Light and Magic (OLM)', 'id': 66289}, {'name': "Kids' WB", 'id': 89163}, {'name': 'Pikachu Project 2001', 'id': 89164}, {'name': 'Shoakuken', 'id': 89165}]
##                          production_countries release_date  revenue runtime
## 4114  [{'iso_3166_1': 'JP', 'name': 'Japan'}]   2000-07-08 68411275      93
## 44806 [{'iso_3166_1': 'JP', 'name': 'Japan'}]   2000-07-08 68411275      93
##                               spoken_languages   status
## 4114  [{'iso_639_1': 'en', 'name': 'English'}] Released
## 44806 [{'iso_639_1': 'en', 'name': 'English'}] Released
##                             tagline                         title video
## 4114  Pokémon: Spell of the Unknown Pokémon: Spell of the Unknown False
## 44806 Pokémon: Spell of the Unknown Pokémon: Spell of the Unknown False
##       vote_average vote_count
## 4114             6        143
## 44806            6        144
# Let's see with another parcial duplicate

id_values <- c("109962")

selected_rows <- movies_wo_dup[movies_wo_dup$id %in% id_values, ]

selected_rows # Also differs in popularity
##       adult belongs_to_collection budget                        genres homepage
## 5710  False                            0 [{'id': 18, 'name': 'Drama'}]         
## 20895 False                            0 [{'id': 18, 'name': 'Drama'}]         
##           id   imdb_id original_language  original_title
## 5710  109962 tt0082992                en Rich and Famous
## 20895 109962 tt0082992                en Rich and Famous
##                                                                                               overview
## 5710  Two literary women compete for 20 years: one writes for the critics; the other one, to get rich.
## 20895 Two literary women compete for 20 years: one writes for the critics; the other one, to get rich.
##       popularity                      poster_path
## 5710   12.180836 /tOflyY8eUFWubLKJH7fKg4KwpCl.jpg
## 20895  10.396878 /tOflyY8eUFWubLKJH7fKg4KwpCl.jpg
##                                                                       production_companies
## 5710  [{'name': 'Metro-Goldwyn-Mayer (MGM)', 'id': 8411}, {'name': 'Jaquet', 'id': 16778}]
## 20895 [{'name': 'Metro-Goldwyn-Mayer (MGM)', 'id': 8411}, {'name': 'Jaquet', 'id': 16778}]
##                                             production_countries release_date
## 5710  [{'iso_3166_1': 'US', 'name': 'United States of America'}]   1981-09-23
## 20895 [{'iso_3166_1': 'US', 'name': 'United States of America'}]   1981-09-23
##       revenue runtime                         spoken_languages   status
## 5710        0     115 [{'iso_639_1': 'en', 'name': 'English'}] Released
## 20895       0     115 [{'iso_639_1': 'en', 'name': 'English'}] Released
##                                                                                                                     tagline
## 5710  From the very beginning, they knew they'd be friends to the end. What they didn't count on was everything in between.
## 20895 From the very beginning, they knew they'd be friends to the end. What they didn't count on was everything in between.
##                 title video vote_average vote_count
## 5710  Rich and Famous False          4.9          7
## 20895 Rich and Famous False          4.9          7
# Apply a condition where only those with the lower popularity stay

movies_wo_dup <- movies_wo_dup %>% group_by(id) %>% filter(popularity == min(popularity))

movies_wo_dup %>% 
  count(id) %>%
  filter(n > 1) # Verification for no partial duplicates
## # A tibble: 0 × 2
## # Groups:   id [0]
## # ℹ 2 variables: id <chr>, n <int>

- Reasoning -

When collecting information there may be missing data such as NAs, but there is also information that is repeated either partially or totally, for each situation it is important to give a different treatment, in the case of the totally duplicated data we first checked the database that had already given treatment to the NAs, then we used the function distinct that its mechanics is the elimination of rows in which it sees that there is duplicated information and at the end we verified that the duplicated rows have been eliminated.

In the case of the partially duplicated rows, something similar was done but with the exception of using the count function on id to see how many of these are duplicated because there cannot be two of the same id and they differ in popularity, so the filter function was used to eliminate the partially duplicated rows.

Organization of information

Genres

# Splitting each string into a character vector, returns a df

# Use a regular expression to match the genre names
genre_pattern <- "(?<=name': ')[^']*(?=')"

# Apply the extraction to the entire column and store the result in a new object
genre_data <- lapply(movies_wo_dup$genres, function(x) {
  genres <- str_extract_all(x, genre_pattern)[[1]]
  split_genres <- strsplit(genres, ", ")
  unlist(split_genres)
})
# Calculate the maximum number of genres a movie can have
max_genre <- max(sapply(genre_data, length))

# Convert the list to a data frame
genre_df <- do.call(rbind, lapply(genre_data, function(x) {
  tmp <- rep(NA, max_genre)
  tmp[seq_along(x)] <- x
  as.data.frame(t(tmp))
}))

# Rename the columns
names(genre_df) <- paste0("genre", seq_len(ncol(genre_df)))
# Join the new genre data frame with the original data frame
movies_wo_dup <- cbind(movies_wo_dup, genre_df)

# Delete the genres column
movies_w_genres <- subset(movies_wo_dup, select = -genres)

Production Companies

# Feature to clear production company names
clean_production_companies <- function(companies) {
  # Apply regular expression to extract company name
  cleaned_names <- str_extract(companies, "'name': '([^']+)'")
  # Delete the extra part
  cleaned_names <- gsub("'name': '", "", cleaned_names)
  cleaned_names <- gsub("'", "", cleaned_names)
  return(cleaned_names)
}

# Apply the function to the production_companies column and store the results in a new column
movies_w_genres$Clean_production_companies <- clean_production_companies(movies_w_genres$production_companies)

# Delete the production companies column
movies_w_prodcom <- subset(movies_w_genres, select = -production_companies)

Production Countries

# Function to clear the names of the countries of production
clean_production_countries <- function(countries) {
  # Apply regular expression to extract country name
  cleaned_names <- str_extract(countries, "'name': '([^']+)'")
  # Delete the extra part
  cleaned_names <- gsub("'name': '", "", cleaned_names)
  cleaned_names <- gsub("'", "", cleaned_names)
  return(cleaned_names)
}

# Apply the function to the production_countries column and store the results in a new column
movies_w_prodcom$Clean_production_countries <- clean_production_countries(movies_w_prodcom$production_countries)

# Delete the production companies column
movies_w_prodcoun <- subset(movies_w_prodcom, select = -production_countries)

Spoken Languages

# Use a regular expression to match the language names
language_pattern <- "(?<=name': ')[^']*(?=')"

# Apply the extraction to the entire column and store the result in a new object
language_data <- lapply(movies_w_prodcoun$spoken_languages, function(x) {
  languages <- str_extract_all(x, language_pattern)[[1]]
  split_languages <- strsplit(languages, ", ")
  unlist(split_languages)
})
# Calculate the maximum number of languages a movie can have
max_language <- max(sapply(language_data, length))

# Convert the list to a data frame
language_df <- do.call(rbind, lapply(language_data, function(x) {
  tmp <- rep(NA, max_language)
  tmp[seq_along(x)] <- x
  as.data.frame(t(tmp))
}))

# Rename the columns
names(language_df) <- paste("spoken_lang", seq_len(ncol(language_df)), sep = "_")
# Join the new language data frame with the original data frame
movies_w_lang <- cbind(movies_w_prodcoun, language_df)

# Eliminate original column
movies_w_lang$spoken_languages <- NULL

Belongs to collection

# Function to separate the 'belongs_to_collection' column
separate_belongs_to_collection <- function(movies_w_lang) {
  # Create a new DataFrame to perform separation
  collection_data <- movies_w_lang

  # Apply regular expression to extract collection name
  collection_names <- str_extract(collection_data$belongs_to_collection, "'name': '([^']+)'")

  # Delete the extra part
  collection_names <- gsub("'name': '", "", collection_names)
  collection_names <- gsub("'", "", collection_names)

  # Create a new column in the new DataFrame with the extracted collection names
  collection_data$Collection <- collection_names

  # Remove the original 'belongs_to_collection' column from the new DataFrame
  collection_data$belongs_to_collection <- NULL

  return(collection_data)
}

# Create a new DataFrame for separation
collection_data <- movies_w_lang

# Apply the function to the new DataFrame
collection_data <- separate_belongs_to_collection(collection_data)

- Reasoning -

Several actions were carried out to better organize the information we are dealing with because we have to separate, correct and place text information for the dataframe so that it makes sense and so that functions or tables of answers can be applied to give greater clarity, several dataframes were created with new columns in which the language , generos , belong to collection , clean production companies and clean production countries were treated and the new information was put together in a new dataframe called collection_data.

Identifying out of range data

Out of value runtime

summary(collection_data$runtime)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    0.00   85.00   95.00   94.12  107.00 1256.00

Out of value revenue

summary(collection_data$revenue)
##      Min.   1st Qu.    Median      Mean   3rd Qu.      Max. 
## 0.000e+00 0.000e+00 0.000e+00 1.121e+07 0.000e+00 2.788e+09

Out of value vote count

summary(collection_data$vote_count)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##     0.0     3.0    10.0   109.9    34.0 14075.0

Out of value vote average

# Vote Average histogram
histogram_vote_average <- ggplot(collection_data, aes(x = vote_average)) +
  geom_histogram(fill = "black", color = "red") +
  labs(title = "Histogram of Vote Average")

# Display histogram 
print(histogram_vote_average)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

Out of value Budget

collection_data$budget <- as.integer(collection_data$budget)
## Warning: NAs introducidos por coerción
# Create the histogram
histogram_budget <- ggplot(collection_data, aes(x = budget)) +
  geom_histogram(fill = "black", color = "blue") +
  labs(title = "Histogram of Budget")

# Display the histogram
print(histogram_budget)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
## Warning: Removed 3 rows containing non-finite outside the scale range
## (`stat_bin()`).

### - Reasoning -

We took into account the analysis of the out of range values of collection_data to know if a treatment of such data is needed to see if it coincides with its own nature and that in turn makes sense such information.

Which in this case should only have the visibility of them but not the elimination because this may alter the data set and that in turn are intiger class data which in turn makes sense that certain values can be radically different from the others.

Converting information

Factors

# Identify categorical variables and convert them to factors
cols_to_factor <- c("adult", paste0("genre", 1:8), "Clean_production_companies", 
                    "Clean_production_countries", paste0("spoken_lang_", 1:18))

# # Convert columns to factors
collection_data[cols_to_factor] <- lapply(collection_data[cols_to_factor], factor)

Intiger & Numeric

#Verfying columns that has numbers that matches with their category
class(collection_data$budget)
## [1] "integer"
class(collection_data$id)
## [1] "character"
class(collection_data$popularity)
## [1] "character"
class(collection_data$revenue)
## [1] "numeric"
class(collection_data$vote_average)
## [1] "numeric"
class(collection_data$vote_count)
## [1] "numeric"
#Treatment for popularity
collection_data$popularity <- as.numeric(collection_data$popularity)
## Warning: NAs introducidos por coerción
# Round popularity to whole numbers
collection_data$round_popularity <- round(collection_data$popularity)

# Show results
class(collection_data$popularity)
## [1] "numeric"

- Reasoning -

It was verified that from collection_data the columns had their correct class and those that did not were given a treatment to manipulate the information so that it was correct.

Applying tool Data explorer

report_data <- collection_data[-c(22:27, 32:47)]
#create_report(collection_data, y = "revenue")
#create_report(report_data, y = "revenue")

- Reasoning -

After visualizing the information, an alarming detail was the excessive amount of NAs, which was 49%, so it is not possible to give an exact interpretation of what we are looking for, so we will eliminate the columns that have enough lack of information and once that is done we can give more accurate conclusions.

Deleting columns of genre

collection_data <- subset(collection_data, select = -c(22:27))

Deleting columns of speak lang

collection_data <- subset(collection_data, select = -c(26:41))

Verfying NAs

# Instalar la biblioteca
#install.packages("heatmaply")

# Cargar la biblioteca
#library(heatmaply)

# Visualizar los datos faltantes
#heatmaply_na(collection_data, showticklabels = c(TRUE, FALSE))

Hi teacher, I just wanna to comment you that in this part of the evidence I try to use a different library as is mention in the evidence but I dont why it runs the library and function but it takes to much time, but what I try to do is to replace the library of visdat to see the the missing information with a different table I saw it on google and I like it.

Conclusion

Results

Bar Chart

# Create a backup df
copy_data <- collection_data
# Calculate the frequencies of each production company
company_frequencies <- copy_data %>%
  count(Clean_production_companies) %>%
  arrange(desc(n))  # Sort in descending order of frequency

# Select the top 10 production companies
top_10_companies <- head(company_frequencies, 10)

top_10_companies
## # A tibble: 10 × 3
## # Groups:   id [10]
##    id     Clean_production_companies                        n
##    <chr>  <fct>                                         <int>
##  1 100    Handmade Films Ltd.                               1
##  2 10000  Ministère de la Culture et de la Francophonie     1
##  3 10001  Warner Bros.                                      1
##  4 100010 Metro-Goldwyn-Mayer (MGM)                         1
##  5 100017 MMM Film Zimmermann & Co                          1
##  6 10002  The Criterion Collection                          1
##  7 100024 <NA>                                              1
##  8 10003  Paramount Pictures                                1
##  9 100032 Von Zerneck Sertner Films                         1
## 10 100033 Shochiku Ofuna                                    1
# Calculate the count of each company
company_counts <- table(copy_data$Clean_production_companies)

# Sort the companies by count in descending order and select the top five
top_companies <- names(sort(company_counts, decreasing = TRUE)[1:8])

# Filter the dataset to include only the top five most important companies
filtered_data <- copy_data[collection_data$Clean_production_companies %in% top_companies, ]

# Create the bar plot
ggplot(filtered_data, aes(x = Clean_production_companies)) +
  geom_bar() +
  theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1))

Density Plot

# Calculate the count of each country
country_counts <- table(collection_data$Clean_production_countries)

# Sort the countries by count in descending order and select the top five
top_countries <- names(sort(country_counts, decreasing = TRUE)[1:8])

# Filter the dataset to include only the top five most important countries
filtered_data <- collection_data[collection_data$Clean_production_countries %in% top_countries, ]

# Create the density plot
ggplot(filtered_data, aes(x = Clean_production_countries)) +
  geom_density() +
  theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1))

Scatter Graph

ggplot(data = collection_data, aes(x = collection_data$genre2, y = collection_data$popularity)) +
  geom_point() +
  labs(title = "Relation beteween genre2 and popularity", x = "genre2", y = "popularity") +
  theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1))
## Warning: Removed 6 rows containing missing values or values outside the scale range
## (`geom_point()`).

Interpretation of the results

By conducting a long research of information different types of graphs were used in the conclusion to give a visualization of the data and the frequency in which it is used, what this can tell us that using the variable that has the highest frequency what this would guarantee that it will be successful film.

The first table the most successful company is Paramount Pictures, this may be due to its good management, logistics or development of films and this attracts the public reaching the value 1000

In the density plot shows us that Canada is the country that has the highest Density in terms of film viewing which means that we must pay attention to what the public wants from Canada, of course we also take into account the other countries, but we must take the most for Canada because its value is 1.8.

Finally, the genre that has the greatest recognition and success is animation, which has a value of more than 500

This leads us as a conclusion to take these variables and merge them to have a successful result.

Reference

The movies dataset. (2017, 10 noviembre). Kaggle. https://www.kaggle.com/datasets/rounakbanik/the-movies-dataset

LS0tDQp0aXRsZTogIkV2aWRlbmNlIg0KYXV0aG9yOiAiRGFyaW8gR2FsbGFyZG8iDQpkYXRlOiAiMjAyNC0wNS0wMyINCm91dHB1dDoNCiAgaHRtbF9kb2N1bWVudDoNCiAgICB0b2M6IHRydWUNCiAgICB0b2NfZmxvYXQ6IHRydWUNCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlDQogICAgdGhlbWU6IGx1bWVuDQotLS0NCg0KIyA8c3BhbiBzdHlsZSA9ICJjb2xvcjogcHVycGxlOyI+IEludHJvZHVjdGlvbiA8L3NwYW4+DQoNCiFbXShDOlxcVXNlcnNcXENhcmxvc1xcRG93bmxvYWRzXFxmaWxtLTEwMjY4MV8xMjgwLmpwZykNCg0KIyMgPHNwYW4gc3R5bGUgPSAiY29sb3I6IGdyZWVuOyI+IEV4ZWN1dGl2ZSBTdW1tYXJ5IDwvc3Bhbj4NCg0KVGhlIHdvcmxkIG9mIHRoZSBtb3ZpZSBidXNpbmVzcyBpcyBhbiBhcmVhIHdoZXJlIHRoZXJlIGFyZSBhIHZhcmlldHkgb2YgdmFyaWFibGVzIHRvIGFuYWx5emUgYW5kIGdlbmVyYXRlIHN1Y2Nlc3MgaW4gYSBzZXJpZXMgb3IgbW92aWUgZm9yIHRoZSBuZXh0IGhpdCB0aGF0IHBlb3BsZSB3aWxsIGJlIHRhbGtpbmcgYWJvdXQsIGJ1dCB5b3UgaGF2ZSB0byB0YWtlIGludG8gYWNjb3VudCB0aGUgZXhhY3QgdmFyaWFibGVzIG9mIGEgKmRhdGFiYXNlKiBhbmQgZ2l2ZSBhIGdvb2QgYW5hbHlzaXMgdG8gc2VlIHdoYXQgc3RyYXRlZ3kgc2hvdWxkIGJlIHRha2VuIGludG8gYWNjb3VudCB0byB0YWtlIGFjdGlvbi4NCg0KDQojIyA8c3BhbiBzdHlsZSA9ICJjb2xvcjogZ3JlZW47Ij4gT2JqZWN0aXZlcyA8L3NwYW4+DQoNCkF0IHRoZSBlbmQgb2YgdGhpcyBldmlkZW5jZSwgc2V2ZXJhbCBwcmUtZXN0YWJsaXNoZWQgb2JqZWN0aXZlcyB3aWxsIGJlIHJlc29sdmVkIHRvIHByb3ZpZGUgZ3JlYXRlciB0cmFuc3BhcmVuY3kgYW5kIHF1YWxpdHkgZGF0YSBvbiB3aGF0IHZhcmlhYmxlcyBnZW5lcmF0ZSB0aGUgc3VjY2VzcyBvZiBhIGZpbG0sIGluIG9yZGVyIHRvIHJlYWNoIHRoaXMgcmVzdWx0Og0KDQotIFRyZWF0bWVudCB0byBOQXMNCg0KLSBJbmZvcm1hdGlvbiBjbGVhbmluZw0KDQotIERhdGEgb3JnYW5pemF0aW9uDQoNCi0gSW5mb3JtYXRpb24gYW5hbHlzaXMNCg0KLSBBbnN3ZXIgdG8gdGhlIG1haW4gcXVlc3Rpb24NCg0KDQojIDxzcGFuIHN0eWxlID0gImNvbG9yOiBwdXJwbGU7Ij4gQm9keSA8L3NwYW4+DQoNCiMjIDxzcGFuIHN0eWxlID0gImNvbG9yOiBncmVlbjsiPiBEYXRhIGRlc2NyaXB0aW9uIDwvc3Bhbj4NCg0KRmlyc3Qgb2YgYWxsLCBpdCBpcyB0byBjYWxsIHRoZSBsaWJyYXJpZXMsIHRvb2xzIGFuZCBkYXRhYmFzZSB0aGF0IHdlIGFyZSBnb2luZyB0byByZWFsaXplIHRvIGdpdmUgZGlmZmVyZW50ICoqdHJlYXRtZW50cyoqLCAqKm1hbmlwdWxhdGUqKiBhbmQgKipvcmdhbml6ZSoqIGluZm9ybWF0aW9uIHRvIGhhdmUgYSB2aXNpYmxlIHJlc3VsdC4NCg0KIyMjIDxzcGFuIHN0eWxlID0gImNvbG9yOiBibGFjazsiPiBMaWJyYXJpZXMgPC9zcGFuPg0KDQpgYGB7cn0NCiNDYWxsaW5nIExpYnJhcmllcw0KbGlicmFyeSh1bml0cykNCmxpYnJhcnkodmlzZGF0KQ0KbGlicmFyeShEYXRhRXhwbG9yZXIpDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeShqYW5pdG9yKQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KHN0cmluZ3IpDQpsaWJyYXJ5KHRpZHlyKQ0KbGlicmFyeShyZWFkcikNCmxpYnJhcnkoZ2dwbG90MikNCmBgYA0KIyMjIDxzcGFuIHN0eWxlID0gImNvbG9yOiBibGFjazsiPiBEYXRhYmFzZSA8L3NwYW4+DQpgYGB7cn0NCiNDYWxsbGluZyBEYXRhYmFzZQ0KbW92aWVzIDwtIHJlYWQuY3N2KCJDOlxcVXNlcnNcXENhcmxvc1xcRGVza3RvcFxcbW92aWVzX21ldGFkYXRhLmNzdiIpDQpgYGANCg0KIyMgPHNwYW4gc3R5bGUgPSAiY29sb3I6IGdyZWVuOyI+IERhdGEgY2xlYW5pbmcgY29uZHVjdGVkIDwvc3Bhbj4NCg0KIyMjIDxzcGFuIHN0eWxlID0gImNvbG9yOiBibGFjazsiPiBUcmVhdG1lbnQgb2YgTkFzIDwvc3Bhbj4NCmBgYHtyfQ0KI1NlYXJjaCBob3cgbWFueSBOQXMgYXJlIGluIHRoZSBkYXRhYmFzZQ0Kc3VtKGlzLm5hKG1vdmllcykpDQpgYGANCmBgYHtyfQ0KIyBTZWFyY2ggaW4gZWFjaCBjb2x1bW4gaG93IG1hbnkgTkFzIGV4aXN0IHRvIHNlZSB3aGF0IHR5cGUgb2YgZWxpbWluYXRpb24gdG8gYXBwbHkNCnNhcHBseShtb3ZpZXMsIGZ1bmN0aW9uKHgpIHN1bShpcy5uYSh4KSkpDQpgYGANCg0KYGBge3J9DQojIENsZWFuaW5nIGFuZCBzdW1tYXJ5IG9mIGNvbHVtbiAicnVudGltZSINCm1vdmllczIgPC0gbW92aWVzDQoNCm1vdmllczIkcnVudGltZVtpcy5uYShtb3ZpZXMyJHJ1bnRpbWUpXSA8LSBtZWFuKG1vdmllczIkcnVudGltZSwgbmEucm09VFJVRSkNCnN1bW1hcnkobW92aWVzMiRydW50aW1lKQ0KYGBgDQoNCmBgYHtyfQ0KIyBDbGVhbmluZyBhbmQgc3VtbWFyeSBvZiBjb2x1bW4gInJldmVudWUiDQptb3ZpZXMzIDwtIG1vdmllczINCg0KbW92aWVzMyRyZXZlbnVlW2lzLm5hKG1vdmllczMkcmV2ZW51ZSldIDwtIG1lYW4obW92aWVzMyRyZXZlbnVlLCBuYS5ybT1UUlVFKQ0Kc3VtbWFyeShtb3ZpZXMzJHJldmVudWUpDQpgYGANCg0KYGBge3J9DQojIENsZWFuaW5nIGFuZCBzdW1tYXJ5IG9mIGNvbHVtbiAidm90ZSBjb3VudCINCm1vdmllczQgPC0gbW92aWVzMw0KDQptb3ZpZXM0JHZvdGVfY291bnRbaXMubmEobW92aWVzNCR2b3RlX2NvdW50KV0gPC0gbWVhbihtb3ZpZXM0JHZvdGVfY291bnQsIG5hLnJtPVRSVUUpDQpzdW1tYXJ5KG1vdmllczQkdm90ZV9jb3VudCkNCmBgYA0KDQpgYGB7cn0NCiMgQ2xlYW5pbmcgYW5kIHN1bW1hcnkgb2YgY29sdW1uICJ2b3RlIGF2ZXJhZ2UiDQptb3ZpZXNfd29fbmEgPC0gbW92aWVzNA0KDQptb3ZpZXNfd29fbmEkdm90ZV9hdmVyYWdlW2lzLm5hKG1vdmllc193b19uYSR2b3RlX2F2ZXJhZ2UpXSA8LSBtZWFuKG1vdmllc193b19uYSR2b3RlX2F2ZXJhZ2UsIG5hLnJtPVRSVUUpDQpzdW1tYXJ5KG1vdmllc193b19uYSR2b3RlX2F2ZXJhZ2UpDQpgYGANCmBgYHtyfQ0KI1ZlcmlmeWluZyBOQXMNCnN1bShpcy5uYShtb3ZpZXNfd29fbmEpKQ0KYGBgDQojIyMgPHNwYW4gc3R5bGUgPSAiY29sb3I6IGJsYWNrOyI+IFJlYXNvbmluZyA8L3NwYW4+DQpUaGUgbWV0aG9kIG9mIGVsaW1pbmF0aW9uIHVzZWQgZm9yIHRoZSBOQXMgd2FzIGJ5ICoqdGFraW5nIHRoZSBhdmVyYWdlKiosIHdoaWNoIHdhcyBkZWNpZGVkIGZvciB0d28gcmVhc29ucy4gIA0KLSBCZWNhdXNlIGluIHRoZSBhbmFseXNpcyBvZiB0aGUgY29sdW1ucyBpdCB3YXMgcG9zc2libGUgdG8gb2J0YWluIHRoYXQgdGhlIHZhbHVlcyB0aGF0IGNvbnRhaW5lZCBOQSB3ZXJlIG51bWVyaWMgYW5kIGludGVnZXJzICpydW50aW1lKiwgKnZvdGUgYXZlcmFnZSosICp2b3RlIGNvdW50KiwgKnJldmVudWUqLiAgDQotIFRoZSBtaXNzaW5nIHZhbHVlcyBhcmUgaW1wb3J0YW50IGFuZCBpdCBpcyBkZXNpcmVkIHRvIHByZXNlcnZlIHRoZSBnZW5lcmFsIHN0cnVjdHVyZSBvZiB0aGUgZGF0YS4gIA0KDQojIyMgPHNwYW4gc3R5bGUgPSAiY29sb3I6IGJsYWNrOyI+IFRyZWF0bWVudCBvZiBkdXBsaWNhdGVzIGFuZCBwYXJ0aWFsbHkgZHVwbGljYXRlcyA8L3NwYW4+DQpgYGB7cn0NCiMgQ2hlY2sgaG93IG1hbnkgaW5mb3JtYXRpb24gYXJlIHRvdGFsbHkgZHVwbGljYXRlZA0Kc3VtKGR1cGxpY2F0ZWQobW92aWVzX3dvX25hKSkgDQpgYGANCg0KYGBge3J9DQojIEVsaW1pbmF0ZSBpbmZvcm1hdGlvbiB0aGF0IGlzIHRvdGFsbHkgZHVwbGljYXRlZA0KbW92aWVzX3dvX2R1cCA8LSBtb3ZpZXNfd29fbmENCm1vdmllc193b19kdXAgPC0gZGlzdGluY3QobW92aWVzX3dvX2R1cCkNCmBgYA0KDQpgYGB7cn0NCiMgQ2hlY2sgaWYgZHVwbGljYXRlIGluZm9ybWF0aW9uIGlzIGVsaW1pbmF0ZWQNCnN1bShkdXBsaWNhdGVkKG1vdmllc193b19kdXApKQ0KYGBgDQoNCg0KYGBge3J9DQojIENoZWNrIGluZm9ybWF0aW9uIHRoYXQgY291bGQgYmUgcGFydGlhbGx5IGR1cGxpY2F0ZWQNCm1vdmllc193b19kdXAgJT4lIA0KICBjb3VudChpZCkgJT4lDQogIGZpbHRlcihuID4gMSkNCmBgYA0KYGBge3J9DQojIENoZWNrIHRoZSByb3dzIGZvciBzcGVjaWZpYyBkdXBsaWNhdGVzDQoNCmlkX3ZhbHVlcyA8LSBjKCIxMDk5MSIpDQoNCnNlbGVjdGVkX3Jvd3MgPC0gbW92aWVzX3dvX2R1cFttb3ZpZXNfd29fZHVwJGlkICVpbiUgaWRfdmFsdWVzLCBdDQoNCnNlbGVjdGVkX3Jvd3MgIyBEaWZmZXIgaW4gcG9wdWxhcml0eQ0KYGBgDQpgYGB7cn0NCiMgTGV0J3Mgc2VlIHdpdGggYW5vdGhlciBwYXJjaWFsIGR1cGxpY2F0ZQ0KDQppZF92YWx1ZXMgPC0gYygiMTA5OTYyIikNCg0Kc2VsZWN0ZWRfcm93cyA8LSBtb3ZpZXNfd29fZHVwW21vdmllc193b19kdXAkaWQgJWluJSBpZF92YWx1ZXMsIF0NCg0Kc2VsZWN0ZWRfcm93cyAjIEFsc28gZGlmZmVycyBpbiBwb3B1bGFyaXR5DQpgYGANCg0KYGBge3J9DQojIEFwcGx5IGEgY29uZGl0aW9uIHdoZXJlIG9ubHkgdGhvc2Ugd2l0aCB0aGUgbG93ZXIgcG9wdWxhcml0eSBzdGF5DQoNCm1vdmllc193b19kdXAgPC0gbW92aWVzX3dvX2R1cCAlPiUgZ3JvdXBfYnkoaWQpICU+JSBmaWx0ZXIocG9wdWxhcml0eSA9PSBtaW4ocG9wdWxhcml0eSkpDQoNCm1vdmllc193b19kdXAgJT4lIA0KICBjb3VudChpZCkgJT4lDQogIGZpbHRlcihuID4gMSkgIyBWZXJpZmljYXRpb24gZm9yIG5vIHBhcnRpYWwgZHVwbGljYXRlcw0KDQpgYGANCiMjIyA8c3BhbiBzdHlsZSA9ICJjb2xvcjogYmxhY2s7Ij4gLSBSZWFzb25pbmcgLSA8L3NwYW4+DQpXaGVuIGNvbGxlY3RpbmcgaW5mb3JtYXRpb24gdGhlcmUgbWF5IGJlIG1pc3NpbmcgZGF0YSBzdWNoIGFzIE5BcywgYnV0IHRoZXJlIGlzIGFsc28gaW5mb3JtYXRpb24gdGhhdCBpcyByZXBlYXRlZCBlaXRoZXIgcGFydGlhbGx5IG9yIHRvdGFsbHksIGZvciBlYWNoIHNpdHVhdGlvbiBpdCBpcyBpbXBvcnRhbnQgdG8gZ2l2ZSBhIGRpZmZlcmVudCB0cmVhdG1lbnQsIGluIHRoZSBjYXNlIG9mIHRoZSB0b3RhbGx5IGR1cGxpY2F0ZWQgZGF0YSB3ZSBmaXJzdCBjaGVja2VkIHRoZSBkYXRhYmFzZSB0aGF0IGhhZCBhbHJlYWR5IGdpdmVuIHRyZWF0bWVudCB0byB0aGUgTkFzLCB0aGVuIHdlIHVzZWQgdGhlIGZ1bmN0aW9uICoqZGlzdGluY3QqKiB0aGF0IGl0cyBtZWNoYW5pY3MgaXMgdGhlIGVsaW1pbmF0aW9uIG9mIHJvd3MgaW4gd2hpY2ggaXQgc2VlcyB0aGF0IHRoZXJlIGlzIGR1cGxpY2F0ZWQgaW5mb3JtYXRpb24gYW5kIGF0IHRoZSBlbmQgd2UgdmVyaWZpZWQgdGhhdCB0aGUgZHVwbGljYXRlZCByb3dzIGhhdmUgYmVlbiBlbGltaW5hdGVkLiANCg0KSW4gdGhlIGNhc2Ugb2YgdGhlIHBhcnRpYWxseSBkdXBsaWNhdGVkIHJvd3MsIHNvbWV0aGluZyBzaW1pbGFyIHdhcyBkb25lIGJ1dCB3aXRoIHRoZSBleGNlcHRpb24gb2YgdXNpbmcgdGhlICoqY291bnQqKiBmdW5jdGlvbiBvbiAqaWQqIHRvIHNlZSBob3cgbWFueSBvZiB0aGVzZSBhcmUgZHVwbGljYXRlZCBiZWNhdXNlIHRoZXJlIGNhbm5vdCBiZSB0d28gb2YgdGhlIHNhbWUgKmlkKiBhbmQgdGhleSBkaWZmZXIgaW4gcG9wdWxhcml0eSwgc28gdGhlICoqZmlsdGVyKiogZnVuY3Rpb24gd2FzIHVzZWQgdG8gZWxpbWluYXRlIHRoZSBwYXJ0aWFsbHkgZHVwbGljYXRlZCByb3dzLg0KDQojIyA8c3BhbiBzdHlsZSA9ICJjb2xvcjogZ3JlZW47Ij4gT3JnYW5pemF0aW9uIG9mIGluZm9ybWF0aW9uIDwvc3Bhbj4NCg0KIyMjIDxzcGFuIHN0eWxlID0gImNvbG9yOiBibGFjazsiPkdlbnJlczwvc3Bhbj4NCmBgYHtyfQ0KIyBTcGxpdHRpbmcgZWFjaCBzdHJpbmcgaW50byBhIGNoYXJhY3RlciB2ZWN0b3IsIHJldHVybnMgYSBkZg0KDQojIFVzZSBhIHJlZ3VsYXIgZXhwcmVzc2lvbiB0byBtYXRjaCB0aGUgZ2VucmUgbmFtZXMNCmdlbnJlX3BhdHRlcm4gPC0gIig/PD1uYW1lJzogJylbXiddKig/PScpIg0KDQojIEFwcGx5IHRoZSBleHRyYWN0aW9uIHRvIHRoZSBlbnRpcmUgY29sdW1uIGFuZCBzdG9yZSB0aGUgcmVzdWx0IGluIGEgbmV3IG9iamVjdA0KZ2VucmVfZGF0YSA8LSBsYXBwbHkobW92aWVzX3dvX2R1cCRnZW5yZXMsIGZ1bmN0aW9uKHgpIHsNCiAgZ2VucmVzIDwtIHN0cl9leHRyYWN0X2FsbCh4LCBnZW5yZV9wYXR0ZXJuKVtbMV1dDQogIHNwbGl0X2dlbnJlcyA8LSBzdHJzcGxpdChnZW5yZXMsICIsICIpDQogIHVubGlzdChzcGxpdF9nZW5yZXMpDQp9KQ0KYGBgDQoNCmBgYHtyfQ0KIyBDYWxjdWxhdGUgdGhlIG1heGltdW0gbnVtYmVyIG9mIGdlbnJlcyBhIG1vdmllIGNhbiBoYXZlDQptYXhfZ2VucmUgPC0gbWF4KHNhcHBseShnZW5yZV9kYXRhLCBsZW5ndGgpKQ0KDQojIENvbnZlcnQgdGhlIGxpc3QgdG8gYSBkYXRhIGZyYW1lDQpnZW5yZV9kZiA8LSBkby5jYWxsKHJiaW5kLCBsYXBwbHkoZ2VucmVfZGF0YSwgZnVuY3Rpb24oeCkgew0KICB0bXAgPC0gcmVwKE5BLCBtYXhfZ2VucmUpDQogIHRtcFtzZXFfYWxvbmcoeCldIDwtIHgNCiAgYXMuZGF0YS5mcmFtZSh0KHRtcCkpDQp9KSkNCg0KIyBSZW5hbWUgdGhlIGNvbHVtbnMNCm5hbWVzKGdlbnJlX2RmKSA8LSBwYXN0ZTAoImdlbnJlIiwgc2VxX2xlbihuY29sKGdlbnJlX2RmKSkpDQpgYGANCg0KYGBge3J9DQojIEpvaW4gdGhlIG5ldyBnZW5yZSBkYXRhIGZyYW1lIHdpdGggdGhlIG9yaWdpbmFsIGRhdGEgZnJhbWUNCm1vdmllc193b19kdXAgPC0gY2JpbmQobW92aWVzX3dvX2R1cCwgZ2VucmVfZGYpDQoNCiMgRGVsZXRlIHRoZSBnZW5yZXMgY29sdW1uDQptb3ZpZXNfd19nZW5yZXMgPC0gc3Vic2V0KG1vdmllc193b19kdXAsIHNlbGVjdCA9IC1nZW5yZXMpDQpgYGANCg0KIyMjIDxzcGFuIHN0eWxlID0gImNvbG9yOiBibGFjazsiPlByb2R1Y3Rpb24gQ29tcGFuaWVzPC9zcGFuPg0KYGBge3J9DQojIEZlYXR1cmUgdG8gY2xlYXIgcHJvZHVjdGlvbiBjb21wYW55IG5hbWVzDQpjbGVhbl9wcm9kdWN0aW9uX2NvbXBhbmllcyA8LSBmdW5jdGlvbihjb21wYW5pZXMpIHsNCiAgIyBBcHBseSByZWd1bGFyIGV4cHJlc3Npb24gdG8gZXh0cmFjdCBjb21wYW55IG5hbWUNCiAgY2xlYW5lZF9uYW1lcyA8LSBzdHJfZXh0cmFjdChjb21wYW5pZXMsICInbmFtZSc6ICcoW14nXSspJyIpDQogICMgRGVsZXRlIHRoZSBleHRyYSBwYXJ0DQogIGNsZWFuZWRfbmFtZXMgPC0gZ3N1YigiJ25hbWUnOiAnIiwgIiIsIGNsZWFuZWRfbmFtZXMpDQogIGNsZWFuZWRfbmFtZXMgPC0gZ3N1YigiJyIsICIiLCBjbGVhbmVkX25hbWVzKQ0KICByZXR1cm4oY2xlYW5lZF9uYW1lcykNCn0NCg0KIyBBcHBseSB0aGUgZnVuY3Rpb24gdG8gdGhlIHByb2R1Y3Rpb25fY29tcGFuaWVzIGNvbHVtbiBhbmQgc3RvcmUgdGhlIHJlc3VsdHMgaW4gYSBuZXcgY29sdW1uDQptb3ZpZXNfd19nZW5yZXMkQ2xlYW5fcHJvZHVjdGlvbl9jb21wYW5pZXMgPC0gY2xlYW5fcHJvZHVjdGlvbl9jb21wYW5pZXMobW92aWVzX3dfZ2VucmVzJHByb2R1Y3Rpb25fY29tcGFuaWVzKQ0KDQojIERlbGV0ZSB0aGUgcHJvZHVjdGlvbiBjb21wYW5pZXMgY29sdW1uDQptb3ZpZXNfd19wcm9kY29tIDwtIHN1YnNldChtb3ZpZXNfd19nZW5yZXMsIHNlbGVjdCA9IC1wcm9kdWN0aW9uX2NvbXBhbmllcykNCmBgYA0KDQojIyMgPHNwYW4gc3R5bGUgPSAiY29sb3I6IGJsYWNrOyI+UHJvZHVjdGlvbiBDb3VudHJpZXM8L3NwYW4+DQpgYGB7cn0NCiMgRnVuY3Rpb24gdG8gY2xlYXIgdGhlIG5hbWVzIG9mIHRoZSBjb3VudHJpZXMgb2YgcHJvZHVjdGlvbg0KY2xlYW5fcHJvZHVjdGlvbl9jb3VudHJpZXMgPC0gZnVuY3Rpb24oY291bnRyaWVzKSB7DQogICMgQXBwbHkgcmVndWxhciBleHByZXNzaW9uIHRvIGV4dHJhY3QgY291bnRyeSBuYW1lDQogIGNsZWFuZWRfbmFtZXMgPC0gc3RyX2V4dHJhY3QoY291bnRyaWVzLCAiJ25hbWUnOiAnKFteJ10rKSciKQ0KICAjIERlbGV0ZSB0aGUgZXh0cmEgcGFydA0KICBjbGVhbmVkX25hbWVzIDwtIGdzdWIoIiduYW1lJzogJyIsICIiLCBjbGVhbmVkX25hbWVzKQ0KICBjbGVhbmVkX25hbWVzIDwtIGdzdWIoIiciLCAiIiwgY2xlYW5lZF9uYW1lcykNCiAgcmV0dXJuKGNsZWFuZWRfbmFtZXMpDQp9DQoNCiMgQXBwbHkgdGhlIGZ1bmN0aW9uIHRvIHRoZSBwcm9kdWN0aW9uX2NvdW50cmllcyBjb2x1bW4gYW5kIHN0b3JlIHRoZSByZXN1bHRzIGluIGEgbmV3IGNvbHVtbg0KbW92aWVzX3dfcHJvZGNvbSRDbGVhbl9wcm9kdWN0aW9uX2NvdW50cmllcyA8LSBjbGVhbl9wcm9kdWN0aW9uX2NvdW50cmllcyhtb3ZpZXNfd19wcm9kY29tJHByb2R1Y3Rpb25fY291bnRyaWVzKQ0KDQojIERlbGV0ZSB0aGUgcHJvZHVjdGlvbiBjb21wYW5pZXMgY29sdW1uDQptb3ZpZXNfd19wcm9kY291biA8LSBzdWJzZXQobW92aWVzX3dfcHJvZGNvbSwgc2VsZWN0ID0gLXByb2R1Y3Rpb25fY291bnRyaWVzKQ0KYGBgDQoNCiMjIyA8c3BhbiBzdHlsZSA9ICJjb2xvcjogYmxhY2s7Ij5TcG9rZW4gTGFuZ3VhZ2VzPC9zcGFuPg0KYGBge3J9DQojIFVzZSBhIHJlZ3VsYXIgZXhwcmVzc2lvbiB0byBtYXRjaCB0aGUgbGFuZ3VhZ2UgbmFtZXMNCmxhbmd1YWdlX3BhdHRlcm4gPC0gIig/PD1uYW1lJzogJylbXiddKig/PScpIg0KDQojIEFwcGx5IHRoZSBleHRyYWN0aW9uIHRvIHRoZSBlbnRpcmUgY29sdW1uIGFuZCBzdG9yZSB0aGUgcmVzdWx0IGluIGEgbmV3IG9iamVjdA0KbGFuZ3VhZ2VfZGF0YSA8LSBsYXBwbHkobW92aWVzX3dfcHJvZGNvdW4kc3Bva2VuX2xhbmd1YWdlcywgZnVuY3Rpb24oeCkgew0KICBsYW5ndWFnZXMgPC0gc3RyX2V4dHJhY3RfYWxsKHgsIGxhbmd1YWdlX3BhdHRlcm4pW1sxXV0NCiAgc3BsaXRfbGFuZ3VhZ2VzIDwtIHN0cnNwbGl0KGxhbmd1YWdlcywgIiwgIikNCiAgdW5saXN0KHNwbGl0X2xhbmd1YWdlcykNCn0pDQpgYGANCg0KYGBge3J9DQojIENhbGN1bGF0ZSB0aGUgbWF4aW11bSBudW1iZXIgb2YgbGFuZ3VhZ2VzIGEgbW92aWUgY2FuIGhhdmUNCm1heF9sYW5ndWFnZSA8LSBtYXgoc2FwcGx5KGxhbmd1YWdlX2RhdGEsIGxlbmd0aCkpDQoNCiMgQ29udmVydCB0aGUgbGlzdCB0byBhIGRhdGEgZnJhbWUNCmxhbmd1YWdlX2RmIDwtIGRvLmNhbGwocmJpbmQsIGxhcHBseShsYW5ndWFnZV9kYXRhLCBmdW5jdGlvbih4KSB7DQogIHRtcCA8LSByZXAoTkEsIG1heF9sYW5ndWFnZSkNCiAgdG1wW3NlcV9hbG9uZyh4KV0gPC0geA0KICBhcy5kYXRhLmZyYW1lKHQodG1wKSkNCn0pKQ0KDQojIFJlbmFtZSB0aGUgY29sdW1ucw0KbmFtZXMobGFuZ3VhZ2VfZGYpIDwtIHBhc3RlKCJzcG9rZW5fbGFuZyIsIHNlcV9sZW4obmNvbChsYW5ndWFnZV9kZikpLCBzZXAgPSAiXyIpDQpgYGANCg0KYGBge3J9DQojIEpvaW4gdGhlIG5ldyBsYW5ndWFnZSBkYXRhIGZyYW1lIHdpdGggdGhlIG9yaWdpbmFsIGRhdGEgZnJhbWUNCm1vdmllc193X2xhbmcgPC0gY2JpbmQobW92aWVzX3dfcHJvZGNvdW4sIGxhbmd1YWdlX2RmKQ0KDQojIEVsaW1pbmF0ZSBvcmlnaW5hbCBjb2x1bW4NCm1vdmllc193X2xhbmckc3Bva2VuX2xhbmd1YWdlcyA8LSBOVUxMDQpgYGANCg0KIyMjIDxzcGFuIHN0eWxlID0gImNvbG9yOiBibGFjazsiPkJlbG9uZ3MgdG8gY29sbGVjdGlvbjwvc3Bhbj4NCmBgYHtyfQ0KIyBGdW5jdGlvbiB0byBzZXBhcmF0ZSB0aGUgJ2JlbG9uZ3NfdG9fY29sbGVjdGlvbicgY29sdW1uDQpzZXBhcmF0ZV9iZWxvbmdzX3RvX2NvbGxlY3Rpb24gPC0gZnVuY3Rpb24obW92aWVzX3dfbGFuZykgew0KICAjIENyZWF0ZSBhIG5ldyBEYXRhRnJhbWUgdG8gcGVyZm9ybSBzZXBhcmF0aW9uDQogIGNvbGxlY3Rpb25fZGF0YSA8LSBtb3ZpZXNfd19sYW5nDQoNCiAgIyBBcHBseSByZWd1bGFyIGV4cHJlc3Npb24gdG8gZXh0cmFjdCBjb2xsZWN0aW9uIG5hbWUNCiAgY29sbGVjdGlvbl9uYW1lcyA8LSBzdHJfZXh0cmFjdChjb2xsZWN0aW9uX2RhdGEkYmVsb25nc190b19jb2xsZWN0aW9uLCAiJ25hbWUnOiAnKFteJ10rKSciKQ0KDQogICMgRGVsZXRlIHRoZSBleHRyYSBwYXJ0DQogIGNvbGxlY3Rpb25fbmFtZXMgPC0gZ3N1YigiJ25hbWUnOiAnIiwgIiIsIGNvbGxlY3Rpb25fbmFtZXMpDQogIGNvbGxlY3Rpb25fbmFtZXMgPC0gZ3N1YigiJyIsICIiLCBjb2xsZWN0aW9uX25hbWVzKQ0KDQogICMgQ3JlYXRlIGEgbmV3IGNvbHVtbiBpbiB0aGUgbmV3IERhdGFGcmFtZSB3aXRoIHRoZSBleHRyYWN0ZWQgY29sbGVjdGlvbiBuYW1lcw0KICBjb2xsZWN0aW9uX2RhdGEkQ29sbGVjdGlvbiA8LSBjb2xsZWN0aW9uX25hbWVzDQoNCiAgIyBSZW1vdmUgdGhlIG9yaWdpbmFsICdiZWxvbmdzX3RvX2NvbGxlY3Rpb24nIGNvbHVtbiBmcm9tIHRoZSBuZXcgRGF0YUZyYW1lDQogIGNvbGxlY3Rpb25fZGF0YSRiZWxvbmdzX3RvX2NvbGxlY3Rpb24gPC0gTlVMTA0KDQogIHJldHVybihjb2xsZWN0aW9uX2RhdGEpDQp9DQoNCiMgQ3JlYXRlIGEgbmV3IERhdGFGcmFtZSBmb3Igc2VwYXJhdGlvbg0KY29sbGVjdGlvbl9kYXRhIDwtIG1vdmllc193X2xhbmcNCg0KIyBBcHBseSB0aGUgZnVuY3Rpb24gdG8gdGhlIG5ldyBEYXRhRnJhbWUNCmNvbGxlY3Rpb25fZGF0YSA8LSBzZXBhcmF0ZV9iZWxvbmdzX3RvX2NvbGxlY3Rpb24oY29sbGVjdGlvbl9kYXRhKQ0KYGBgDQojIyMgPHNwYW4gc3R5bGUgPSAiY29sb3I6IGJsYWNrOyI+IC0gUmVhc29uaW5nIC0gPC9zcGFuPg0KDQpTZXZlcmFsIGFjdGlvbnMgd2VyZSBjYXJyaWVkIG91dCB0byBiZXR0ZXIgb3JnYW5pemUgdGhlIGluZm9ybWF0aW9uIHdlIGFyZSBkZWFsaW5nIHdpdGggYmVjYXVzZSB3ZSBoYXZlIHRvICoqc2VwYXJhdGUqKiwgKipjb3JyZWN0KiogYW5kICoqcGxhY2UqKiB0ZXh0IGluZm9ybWF0aW9uIGZvciB0aGUgKipkYXRhZnJhbWUqKiBzbyB0aGF0IGl0IG1ha2VzIHNlbnNlIGFuZCBzbyB0aGF0IGZ1bmN0aW9ucyBvciB0YWJsZXMgb2YgYW5zd2VycyBjYW4gYmUgYXBwbGllZCB0byBnaXZlIGdyZWF0ZXIgY2xhcml0eSwgc2V2ZXJhbCAqKmRhdGFmcmFtZXMqKiB3ZXJlIGNyZWF0ZWQgd2l0aCBuZXcgY29sdW1ucyBpbiB3aGljaCB0aGUgKmxhbmd1YWdlKiAsICpnZW5lcm9zKiAsICpiZWxvbmcgdG8gY29sbGVjdGlvbiogLCAqY2xlYW4gcHJvZHVjdGlvbiBjb21wYW5pZXMqIGFuZCAqY2xlYW4gcHJvZHVjdGlvbiBjb3VudHJpZXMqIHdlcmUgdHJlYXRlZCBhbmQgdGhlIG5ldyBpbmZvcm1hdGlvbiB3YXMgcHV0IHRvZ2V0aGVyIGluIGEgbmV3IGRhdGFmcmFtZSBjYWxsZWQgKipjb2xsZWN0aW9uX2RhdGEqKi4NCg0KIyMgPHNwYW4gc3R5bGUgPSAiY29sb3I6IGdyZWVuOyI+IElkZW50aWZ5aW5nIG91dCBvZiByYW5nZSBkYXRhIDwvc3Bhbj4NCg0KIyMjIDxzcGFuIHN0eWxlID0gImNvbG9yOiBibGFjazsiPiBPdXQgb2YgdmFsdWUgcnVudGltZSA8L3NwYW4+DQpgYGB7cn0NCnN1bW1hcnkoY29sbGVjdGlvbl9kYXRhJHJ1bnRpbWUpDQpgYGANCg0KIyMjIDxzcGFuIHN0eWxlID0gImNvbG9yOiBibGFjazsiPiBPdXQgb2YgdmFsdWUgcmV2ZW51ZSA8L3NwYW4+DQpgYGB7cn0NCnN1bW1hcnkoY29sbGVjdGlvbl9kYXRhJHJldmVudWUpDQpgYGANCiMjIyA8c3BhbiBzdHlsZSA9ICJjb2xvcjogYmxhY2s7Ij4gT3V0IG9mIHZhbHVlIHZvdGUgY291bnQgPC9zcGFuPg0KYGBge3J9DQpzdW1tYXJ5KGNvbGxlY3Rpb25fZGF0YSR2b3RlX2NvdW50KQ0KYGBgDQojIyMgPHNwYW4gc3R5bGUgPSAiY29sb3I6IGJsYWNrOyI+IE91dCBvZiB2YWx1ZSB2b3RlIGF2ZXJhZ2UgPC9zcGFuPg0KYGBge3J9DQojIFZvdGUgQXZlcmFnZSBoaXN0b2dyYW0NCmhpc3RvZ3JhbV92b3RlX2F2ZXJhZ2UgPC0gZ2dwbG90KGNvbGxlY3Rpb25fZGF0YSwgYWVzKHggPSB2b3RlX2F2ZXJhZ2UpKSArDQogIGdlb21faGlzdG9ncmFtKGZpbGwgPSAiYmxhY2siLCBjb2xvciA9ICJyZWQiKSArDQogIGxhYnModGl0bGUgPSAiSGlzdG9ncmFtIG9mIFZvdGUgQXZlcmFnZSIpDQoNCiMgRGlzcGxheSBoaXN0b2dyYW0gDQpwcmludChoaXN0b2dyYW1fdm90ZV9hdmVyYWdlKQ0KYGBgDQoNCiMjIyA8c3BhbiBzdHlsZSA9ICJjb2xvcjogYmxhY2s7Ij4gT3V0IG9mIHZhbHVlIEJ1ZGdldCA8L3NwYW4+DQpgYGB7cn0NCmNvbGxlY3Rpb25fZGF0YSRidWRnZXQgPC0gYXMuaW50ZWdlcihjb2xsZWN0aW9uX2RhdGEkYnVkZ2V0KQ0KDQojIENyZWF0ZSB0aGUgaGlzdG9ncmFtDQpoaXN0b2dyYW1fYnVkZ2V0IDwtIGdncGxvdChjb2xsZWN0aW9uX2RhdGEsIGFlcyh4ID0gYnVkZ2V0KSkgKw0KICBnZW9tX2hpc3RvZ3JhbShmaWxsID0gImJsYWNrIiwgY29sb3IgPSAiYmx1ZSIpICsNCiAgbGFicyh0aXRsZSA9ICJIaXN0b2dyYW0gb2YgQnVkZ2V0IikNCg0KIyBEaXNwbGF5IHRoZSBoaXN0b2dyYW0NCnByaW50KGhpc3RvZ3JhbV9idWRnZXQpDQpgYGANCiMjIyA8c3BhbiBzdHlsZSA9ICJjb2xvcjogYmxhY2s7Ij4gLSBSZWFzb25pbmcgLSA8L3NwYW4+DQoNCldlIHRvb2sgaW50byBhY2NvdW50IHRoZSBhbmFseXNpcyBvZiB0aGUgb3V0IG9mIHJhbmdlIHZhbHVlcyBvZiAqKmNvbGxlY3Rpb25fZGF0YSoqIHRvIGtub3cgaWYgYSB0cmVhdG1lbnQgb2Ygc3VjaCBkYXRhIGlzIG5lZWRlZCB0byBzZWUgaWYgaXQgY29pbmNpZGVzIHdpdGggaXRzIG93biBuYXR1cmUgYW5kIHRoYXQgaW4gdHVybiBtYWtlcyBzZW5zZSBzdWNoIGluZm9ybWF0aW9uLg0KDQpXaGljaCBpbiB0aGlzIGNhc2Ugc2hvdWxkIG9ubHkgaGF2ZSB0aGUgdmlzaWJpbGl0eSBvZiB0aGVtIGJ1dCBub3QgdGhlIGVsaW1pbmF0aW9uIGJlY2F1c2UgdGhpcyBtYXkgYWx0ZXIgdGhlIGRhdGEgc2V0IGFuZCB0aGF0IGluIHR1cm4gYXJlICppbnRpZ2VyKiBjbGFzcyBkYXRhIHdoaWNoIGluIHR1cm4gbWFrZXMgc2Vuc2UgdGhhdCBjZXJ0YWluIHZhbHVlcyBjYW4gYmUgcmFkaWNhbGx5IGRpZmZlcmVudCBmcm9tIHRoZSBvdGhlcnMuDQoNCiMjIDxzcGFuIHN0eWxlID0gImNvbG9yOiBncmVlbjsiPiBDb252ZXJ0aW5nIGluZm9ybWF0aW9uIDwvc3Bhbj4NCg0KIyMjIDxzcGFuIHN0eWxlID0gImNvbG9yOiBibGFjazsiPiBGYWN0b3JzIDwvc3Bhbj4NCg0KYGBge3J9DQojIElkZW50aWZ5IGNhdGVnb3JpY2FsIHZhcmlhYmxlcyBhbmQgY29udmVydCB0aGVtIHRvIGZhY3RvcnMNCmNvbHNfdG9fZmFjdG9yIDwtIGMoImFkdWx0IiwgcGFzdGUwKCJnZW5yZSIsIDE6OCksICJDbGVhbl9wcm9kdWN0aW9uX2NvbXBhbmllcyIsIA0KICAgICAgICAgICAgICAgICAgICAiQ2xlYW5fcHJvZHVjdGlvbl9jb3VudHJpZXMiLCBwYXN0ZTAoInNwb2tlbl9sYW5nXyIsIDE6MTgpKQ0KDQojICMgQ29udmVydCBjb2x1bW5zIHRvIGZhY3RvcnMNCmNvbGxlY3Rpb25fZGF0YVtjb2xzX3RvX2ZhY3Rvcl0gPC0gbGFwcGx5KGNvbGxlY3Rpb25fZGF0YVtjb2xzX3RvX2ZhY3Rvcl0sIGZhY3RvcikNCmBgYA0KDQojIyMgPHNwYW4gc3R5bGUgPSAiY29sb3I6IGJsYWNrOyI+IEludGlnZXIgJiBOdW1lcmljIDwvc3Bhbj4NCmBgYHtyfQ0KI1ZlcmZ5aW5nIGNvbHVtbnMgdGhhdCBoYXMgbnVtYmVycyB0aGF0IG1hdGNoZXMgd2l0aCB0aGVpciBjYXRlZ29yeQ0KY2xhc3MoY29sbGVjdGlvbl9kYXRhJGJ1ZGdldCkNCmNsYXNzKGNvbGxlY3Rpb25fZGF0YSRpZCkNCmNsYXNzKGNvbGxlY3Rpb25fZGF0YSRwb3B1bGFyaXR5KQ0KY2xhc3MoY29sbGVjdGlvbl9kYXRhJHJldmVudWUpDQpjbGFzcyhjb2xsZWN0aW9uX2RhdGEkdm90ZV9hdmVyYWdlKQ0KY2xhc3MoY29sbGVjdGlvbl9kYXRhJHZvdGVfY291bnQpDQpgYGANCmBgYHtyfQ0KI1RyZWF0bWVudCBmb3IgcG9wdWxhcml0eQ0KY29sbGVjdGlvbl9kYXRhJHBvcHVsYXJpdHkgPC0gYXMubnVtZXJpYyhjb2xsZWN0aW9uX2RhdGEkcG9wdWxhcml0eSkNCg0KIyBSb3VuZCBwb3B1bGFyaXR5IHRvIHdob2xlIG51bWJlcnMNCmNvbGxlY3Rpb25fZGF0YSRyb3VuZF9wb3B1bGFyaXR5IDwtIHJvdW5kKGNvbGxlY3Rpb25fZGF0YSRwb3B1bGFyaXR5KQ0KDQojIFNob3cgcmVzdWx0cw0KY2xhc3MoY29sbGVjdGlvbl9kYXRhJHBvcHVsYXJpdHkpDQpgYGANCiMjIyA8c3BhbiBzdHlsZSA9ICJjb2xvcjogYmxhY2s7Ij4gLSBSZWFzb25pbmcgLSA8L3NwYW4+DQoNCkl0IHdhcyB2ZXJpZmllZCB0aGF0IGZyb20gKipjb2xsZWN0aW9uX2RhdGEqKiB0aGUgY29sdW1ucyBoYWQgdGhlaXIgY29ycmVjdCAqY2xhc3MqIGFuZCB0aG9zZSB0aGF0IGRpZCBub3Qgd2VyZSBnaXZlbiBhIHRyZWF0bWVudCB0byBtYW5pcHVsYXRlIHRoZSBpbmZvcm1hdGlvbiBzbyB0aGF0IGl0IHdhcyBjb3JyZWN0Lg0KDQojIyA8c3BhbiBzdHlsZSA9ICJjb2xvcjogZ3JlZW47Ij5BcHBseWluZyB0b29sIERhdGEgZXhwbG9yZXIgPC9zcGFuPg0KDQpgYGB7cn0NCnJlcG9ydF9kYXRhIDwtIGNvbGxlY3Rpb25fZGF0YVstYygyMjoyNywgMzI6NDcpXQ0KI2NyZWF0ZV9yZXBvcnQoY29sbGVjdGlvbl9kYXRhLCB5ID0gInJldmVudWUiKQ0KI2NyZWF0ZV9yZXBvcnQocmVwb3J0X2RhdGEsIHkgPSAicmV2ZW51ZSIpDQpgYGANCiMjIyA8c3BhbiBzdHlsZSA9ICJjb2xvcjogYmxhY2s7Ij4gLSBSZWFzb25pbmcgLSA8L3NwYW4+DQoNCkFmdGVyIHZpc3VhbGl6aW5nIHRoZSBpbmZvcm1hdGlvbiwgYW4gYWxhcm1pbmcgZGV0YWlsIHdhcyB0aGUgZXhjZXNzaXZlIGFtb3VudCBvZiBOQXMsIHdoaWNoIHdhcyAqNDklKiwgc28gaXQgaXMgbm90IHBvc3NpYmxlIHRvIGdpdmUgYW4gZXhhY3QgaW50ZXJwcmV0YXRpb24gb2Ygd2hhdCB3ZSBhcmUgbG9va2luZyBmb3IsIHNvIHdlIHdpbGwgZWxpbWluYXRlIHRoZSBjb2x1bW5zIHRoYXQgaGF2ZSBlbm91Z2ggbGFjayBvZiBpbmZvcm1hdGlvbiBhbmQgb25jZSB0aGF0IGlzIGRvbmUgd2UgY2FuIGdpdmUgbW9yZSBhY2N1cmF0ZSBjb25jbHVzaW9ucy4NCg0KIyMjIDxzcGFuIHN0eWxlID0gImNvbG9yOiBibGFjazsiPiBEZWxldGluZyBjb2x1bW5zIG9mIGdlbnJlICA8L3NwYW4+DQpgYGB7cn0NCmNvbGxlY3Rpb25fZGF0YSA8LSBzdWJzZXQoY29sbGVjdGlvbl9kYXRhLCBzZWxlY3QgPSAtYygyMjoyNykpDQpgYGANCg0KIyMjIDxzcGFuIHN0eWxlID0gImNvbG9yOiBibGFjazsiPiAgRGVsZXRpbmcgY29sdW1ucyBvZiBzcGVhayBsYW5nICA8L3NwYW4+DQpgYGB7cn0NCmNvbGxlY3Rpb25fZGF0YSA8LSBzdWJzZXQoY29sbGVjdGlvbl9kYXRhLCBzZWxlY3QgPSAtYygyNjo0MSkpDQpgYGANCg0KIyMjIDxzcGFuIHN0eWxlID0gImNvbG9yOiBibGFjazsiPiBWZXJmeWluZyBOQXMgIDwvc3Bhbj4NCmBgYHtyfQ0KIyBJbnN0YWxhciBsYSBiaWJsaW90ZWNhDQojaW5zdGFsbC5wYWNrYWdlcygiaGVhdG1hcGx5IikNCg0KIyBDYXJnYXIgbGEgYmlibGlvdGVjYQ0KI2xpYnJhcnkoaGVhdG1hcGx5KQ0KDQojIFZpc3VhbGl6YXIgbG9zIGRhdG9zIGZhbHRhbnRlcw0KI2hlYXRtYXBseV9uYShjb2xsZWN0aW9uX2RhdGEsIHNob3d0aWNrbGFiZWxzID0gYyhUUlVFLCBGQUxTRSkpDQpgYGANCkhpIHRlYWNoZXIsIEkganVzdCB3YW5uYSB0byBjb21tZW50IHlvdSB0aGF0IGluIHRoaXMgcGFydCBvZiB0aGUgZXZpZGVuY2UgSSB0cnkgdG8gdXNlIGEgZGlmZmVyZW50IGxpYnJhcnkgYXMgaXMgbWVudGlvbiBpbiB0aGUgZXZpZGVuY2UgYnV0IEkgZG9udCB3aHkgaXQgcnVucyB0aGUgbGlicmFyeSBhbmQgZnVuY3Rpb24gYnV0IGl0IHRha2VzIHRvIG11Y2ggdGltZSwgYnV0IHdoYXQgSSB0cnkgdG8gZG8gaXMgdG8gcmVwbGFjZSB0aGUgbGlicmFyeSBvZiB2aXNkYXQgdG8gc2VlIHRoZSB0aGUgbWlzc2luZyBpbmZvcm1hdGlvbiB3aXRoIGEgZGlmZmVyZW50IHRhYmxlIEkgc2F3IGl0IG9uIGdvb2dsZSBhbmQgSSBsaWtlIGl0LiANCg0KIyA8c3BhbiBzdHlsZSA9ICJjb2xvcjogcHVycGxlOyI+IENvbmNsdXNpb24gPC9zcGFuPg0KDQojIyA8c3BhbiBzdHlsZSA9ICJjb2xvcjogZ3JlZW47Ij4gUmVzdWx0cyA8L3NwYW4+DQoNCiMjIyA8c3BhbiBzdHlsZSA9ICJjb2xvcjogYmxhY2s7Ij4gQmFyIENoYXJ0ICA8L3NwYW4+DQoNCmBgYHtyfQ0KIyBDcmVhdGUgYSBiYWNrdXAgZGYNCmNvcHlfZGF0YSA8LSBjb2xsZWN0aW9uX2RhdGENCmBgYA0KDQpgYGB7cn0NCiMgQ2FsY3VsYXRlIHRoZSBmcmVxdWVuY2llcyBvZiBlYWNoIHByb2R1Y3Rpb24gY29tcGFueQ0KY29tcGFueV9mcmVxdWVuY2llcyA8LSBjb3B5X2RhdGEgJT4lDQogIGNvdW50KENsZWFuX3Byb2R1Y3Rpb25fY29tcGFuaWVzKSAlPiUNCiAgYXJyYW5nZShkZXNjKG4pKSAgIyBTb3J0IGluIGRlc2NlbmRpbmcgb3JkZXIgb2YgZnJlcXVlbmN5DQoNCiMgU2VsZWN0IHRoZSB0b3AgMTAgcHJvZHVjdGlvbiBjb21wYW5pZXMNCnRvcF8xMF9jb21wYW5pZXMgPC0gaGVhZChjb21wYW55X2ZyZXF1ZW5jaWVzLCAxMCkNCg0KdG9wXzEwX2NvbXBhbmllcw0KYGBgDQoNCmBgYHtyfQ0KIyBDYWxjdWxhdGUgdGhlIGNvdW50IG9mIGVhY2ggY29tcGFueQ0KY29tcGFueV9jb3VudHMgPC0gdGFibGUoY29weV9kYXRhJENsZWFuX3Byb2R1Y3Rpb25fY29tcGFuaWVzKQ0KDQojIFNvcnQgdGhlIGNvbXBhbmllcyBieSBjb3VudCBpbiBkZXNjZW5kaW5nIG9yZGVyIGFuZCBzZWxlY3QgdGhlIHRvcCBmaXZlDQp0b3BfY29tcGFuaWVzIDwtIG5hbWVzKHNvcnQoY29tcGFueV9jb3VudHMsIGRlY3JlYXNpbmcgPSBUUlVFKVsxOjhdKQ0KDQojIEZpbHRlciB0aGUgZGF0YXNldCB0byBpbmNsdWRlIG9ubHkgdGhlIHRvcCBmaXZlIG1vc3QgaW1wb3J0YW50IGNvbXBhbmllcw0KZmlsdGVyZWRfZGF0YSA8LSBjb3B5X2RhdGFbY29sbGVjdGlvbl9kYXRhJENsZWFuX3Byb2R1Y3Rpb25fY29tcGFuaWVzICVpbiUgdG9wX2NvbXBhbmllcywgXQ0KDQojIENyZWF0ZSB0aGUgYmFyIHBsb3QNCmdncGxvdChmaWx0ZXJlZF9kYXRhLCBhZXMoeCA9IENsZWFuX3Byb2R1Y3Rpb25fY29tcGFuaWVzKSkgKw0KICBnZW9tX2JhcigpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgdmp1c3QgPSAwLjUsIGhqdXN0PTEpKQ0KYGBgDQoNCiMjIyA8c3BhbiBzdHlsZSA9ICJjb2xvcjogYmxhY2s7Ij4gRGVuc2l0eSBQbG90ICA8L3NwYW4+DQpgYGB7cn0NCiMgQ2FsY3VsYXRlIHRoZSBjb3VudCBvZiBlYWNoIGNvdW50cnkNCmNvdW50cnlfY291bnRzIDwtIHRhYmxlKGNvbGxlY3Rpb25fZGF0YSRDbGVhbl9wcm9kdWN0aW9uX2NvdW50cmllcykNCg0KIyBTb3J0IHRoZSBjb3VudHJpZXMgYnkgY291bnQgaW4gZGVzY2VuZGluZyBvcmRlciBhbmQgc2VsZWN0IHRoZSB0b3AgZml2ZQ0KdG9wX2NvdW50cmllcyA8LSBuYW1lcyhzb3J0KGNvdW50cnlfY291bnRzLCBkZWNyZWFzaW5nID0gVFJVRSlbMTo4XSkNCg0KIyBGaWx0ZXIgdGhlIGRhdGFzZXQgdG8gaW5jbHVkZSBvbmx5IHRoZSB0b3AgZml2ZSBtb3N0IGltcG9ydGFudCBjb3VudHJpZXMNCmZpbHRlcmVkX2RhdGEgPC0gY29sbGVjdGlvbl9kYXRhW2NvbGxlY3Rpb25fZGF0YSRDbGVhbl9wcm9kdWN0aW9uX2NvdW50cmllcyAlaW4lIHRvcF9jb3VudHJpZXMsIF0NCg0KIyBDcmVhdGUgdGhlIGRlbnNpdHkgcGxvdA0KZ2dwbG90KGZpbHRlcmVkX2RhdGEsIGFlcyh4ID0gQ2xlYW5fcHJvZHVjdGlvbl9jb3VudHJpZXMpKSArDQogIGdlb21fZGVuc2l0eSgpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwgdmp1c3QgPSAwLjUsIGhqdXN0PTEpKQ0KYGBgDQoNCiMjIyA8c3BhbiBzdHlsZSA9ICJjb2xvcjogYmxhY2s7Ij4gU2NhdHRlciBHcmFwaCAgPC9zcGFuPg0KYGBge3J9DQpnZ3Bsb3QoZGF0YSA9IGNvbGxlY3Rpb25fZGF0YSwgYWVzKHggPSBjb2xsZWN0aW9uX2RhdGEkZ2VucmUyLCB5ID0gY29sbGVjdGlvbl9kYXRhJHBvcHVsYXJpdHkpKSArDQogIGdlb21fcG9pbnQoKSArDQogIGxhYnModGl0bGUgPSAiUmVsYXRpb24gYmV0ZXdlZW4gZ2VucmUyIGFuZCBwb3B1bGFyaXR5IiwgeCA9ICJnZW5yZTIiLCB5ID0gInBvcHVsYXJpdHkiKSArDQogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIHZqdXN0ID0gMC41LCBoanVzdD0xKSkNCmBgYA0KDQojIyMgPHNwYW4gc3R5bGUgPSAiY29sb3I6IGJsYWNrOyI+IEludGVycHJldGF0aW9uIG9mIHRoZSByZXN1bHRzICA8L3NwYW4+DQoNCkJ5IGNvbmR1Y3RpbmcgYSBsb25nIHJlc2VhcmNoIG9mIGluZm9ybWF0aW9uIGRpZmZlcmVudCB0eXBlcyBvZiBncmFwaHMgd2VyZSB1c2VkIGluIHRoZSBjb25jbHVzaW9uIHRvIGdpdmUgYSB2aXN1YWxpemF0aW9uIG9mIHRoZSBkYXRhIGFuZCB0aGUgZnJlcXVlbmN5IGluIHdoaWNoIGl0IGlzIHVzZWQsIHdoYXQgdGhpcyBjYW4gdGVsbCB1cyB0aGF0IHVzaW5nIHRoZSB2YXJpYWJsZSB0aGF0IGhhcyB0aGUgaGlnaGVzdCBmcmVxdWVuY3kgd2hhdCB0aGlzIHdvdWxkIGd1YXJhbnRlZSB0aGF0IGl0IHdpbGwgYmUgc3VjY2Vzc2Z1bCBmaWxtLg0KDQpUaGUgZmlyc3QgdGFibGUgdGhlIG1vc3Qgc3VjY2Vzc2Z1bCBjb21wYW55IGlzIFBhcmFtb3VudCBQaWN0dXJlcywgdGhpcyBtYXkgYmUgZHVlIHRvIGl0cyBnb29kIG1hbmFnZW1lbnQsIGxvZ2lzdGljcyBvciBkZXZlbG9wbWVudCBvZiBmaWxtcyBhbmQgdGhpcyBhdHRyYWN0cyB0aGUgcHVibGljIHJlYWNoaW5nIHRoZSB2YWx1ZSAxMDAwDQoNCkluIHRoZSBkZW5zaXR5IHBsb3Qgc2hvd3MgdXMgdGhhdCBDYW5hZGEgaXMgdGhlIGNvdW50cnkgdGhhdCBoYXMgdGhlIGhpZ2hlc3QgRGVuc2l0eSBpbiB0ZXJtcyBvZiBmaWxtIHZpZXdpbmcgd2hpY2ggbWVhbnMgdGhhdCB3ZSBtdXN0IHBheSBhdHRlbnRpb24gdG8gd2hhdCB0aGUgcHVibGljIHdhbnRzIGZyb20gQ2FuYWRhLCBvZiBjb3Vyc2Ugd2UgYWxzbyB0YWtlIGludG8gYWNjb3VudCB0aGUgb3RoZXIgY291bnRyaWVzLCBidXQgd2UgbXVzdCB0YWtlIHRoZSBtb3N0IGZvciBDYW5hZGEgYmVjYXVzZSBpdHMgdmFsdWUgaXMgMS44Lg0KDQpGaW5hbGx5LCB0aGUgZ2VucmUgdGhhdCBoYXMgdGhlIGdyZWF0ZXN0IHJlY29nbml0aW9uIGFuZCBzdWNjZXNzIGlzIGFuaW1hdGlvbiwgd2hpY2ggaGFzIGEgdmFsdWUgb2YgbW9yZSB0aGFuIDUwMA0KDQpUaGlzIGxlYWRzIHVzIGFzIGEgY29uY2x1c2lvbiB0byB0YWtlIHRoZXNlIHZhcmlhYmxlcyBhbmQgbWVyZ2UgdGhlbSB0byBoYXZlIGEgc3VjY2Vzc2Z1bCByZXN1bHQuDQoNCiMjIyA8c3BhbiBzdHlsZSA9ICJjb2xvcjogYmxhY2s7Ij4gUmVmZXJlbmNlIDwvc3Bhbj4NCg0KVGhlIG1vdmllcyBkYXRhc2V0LiAoMjAxNywgMTAgbm92aWVtYnJlKS4gS2FnZ2xlLiBodHRwczovL3d3dy5rYWdnbGUuY29tL2RhdGFzZXRzL3JvdW5ha2JhbmlrL3RoZS1tb3ZpZXMtZGF0YXNldA0KDQoNCg0KDQoNCg0KDQo=