Table of Contents

  1. Executive Summary
  2. Introduction
  3. Objectives
  4. Data cleaning and Description
  5. Statistical techniques employed / Results
  6. Conclusions and Business Recommendations
  7. Appendices
  8. APA References

Executive Summary

This report offers a detailed analysis of the characteristics of the most successful movies. Key aspects related to research and data analysis are addressed, with the aim of providing a clear and informed vision that supports strategic decision making.The main findings and recommendations derived from the results obtained from the analytical tools used are summarized below:

Main Findings:

  • Budget Allocation: The analysis reveals that successful movies often allocate substantial budgets to production and marketing, indicating a correlation between investment and success.

  • Audience Engagement: High levels of audience engagement, as evidenced by vote count and average ratings, are indicative of a film’s potential for success. Targeting audience preferences and maximizing engagement can significantly impact a movie’s performance.

  • Global Influence: English-language productions, particularly those originating from the United States, dominate the global film industry. However, opportunities exist for international collaborations and partnerships to diversify content and reach new markets.

  • Content Diversity: Successful films often explore diverse themes and narratives, resonating with a broad spectrum of audiences. Embracing diversity in storytelling and representation can enhance audience appeal and cultural relevance.

Recommendations:

  • Strategic Investment: Allocate resources strategically to fund high-quality productions and innovative marketing campaigns. Prioritize investments in talent, technology, and storytelling to maximize the potential for commercial success.

  • Audience-Centric Approach: Leverage audience data analytics to understand preferences, behaviors, and consumption patterns. Tailor marketing strategies and content offerings to target specific demographics and market segments effectively.

  • International Collaboration: Explore opportunities for international co-productions and partnerships to access new markets and cultural perspectives. Foster collaborations with diverse talent pools to create globally relevant content.

  • Diversification: Embrace diversity and inclusivity in content creation to appeal to a wide range of audiences. Represent diverse voices, experiences, and perspectives authentically to foster audience engagement and loyalty.

  • Adaptability and Innovation: Stay agile and adaptable in response to evolving industry trends and technological advancements. Embrace digital platforms, streaming services, and emerging technologies to expand distribution channels and enhance audience reach.

In conclusion, this report provides valuable insights and actionable recommendations for major production companies seeking to navigate the complexities of the modern film industry. By leveraging data-driven strategies and embracing innovation, companies can position themselves for success in an ever-changing landscape, driving growth, and fostering creativity and excellence in filmmaking.

Introduction

In today’s dynamic entertainment industry, decoding the formula for a successful movie has evolved into a multifaceted challenge for major production companies. The traditional markers of success have shifted amidst the proliferation of content across social media and streaming platforms, presenting a complex landscape to navigate.

As a Business Analytics Analyst tasked with strategic planning for a prominent film production company, the objective is clear: to unearth the underlying factors that differentiate successful movies from their less triumphant counterparts. Leveraging a comprehensive dataset aptly named “movies metadata”, rigorous analytical techniques have been employed to distill actionable insights.

This report delves into the culmination of meticulous data cleaning, diverse graphical representations, and sophisticated analytical tools, all aimed at unraveling the enigma of cinematic success. By scrutinizing patterns, trends, and correlations within the dataset, this analysis endeavors to shed light on the key determinants of a movie’s triumph or defeat.

Armed with these insights, the ultimate goal is to equip major production companies with strategic recommendations poised to catalyze the creation of the next blockbuster hit. Through a blend of data-driven strategies and industry acumen, this report aims to guide decision-makers towards a path of innovation and success in the ever-evolving world of film production.

Objectives of the report

These objectives will serve to guide the research, analysis, and final recommendations of this report. The fulfillment of these objectives will guarantee that the report provides valuable and decisive information for film production companies. The objectives of the report are the following:

  • Identify the key factors that contribute to the success or failure of a film.
  • Use data cleaning techniques to guarantee the quality and reliability of the information analyzed.
  • Apply various analytical tools, such as bar charts, histograms, densities, and dot plots, to better understand trends and patterns within the data set.
  • Analyze the relationships and correlations between different variables to discern the drivers of success in the film industry.
  • Generate strategic recommendations for major film production companies, based on the findings and conclusions obtained from data analysis.

Data cleaning and Description

Description of the data

The file from which the information analyzed in this report is being obtained is called “movies metadata” and is a database that contains metadata for all 45,000 movies listed in the Full MovieLens Dataset. This database has different columns of data such as budget, revenue, posters, release dates, languages, production companies, countries, etc. All this information can help us relate the similarities of good movies in order to discover the formula for a successful movie. Another thing to mention is that all this information was collected from the opinions of 270,000 real users.

Cleaning NA’s values

##                 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

The columns with NA’s are “runtime”, “revenue”, “vote count”, “vote average” so they must be modified by adding an average value.

##                 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 
##                     0                     0                     0 
##                status               tagline                 title 
##                     0                     0                     0 
##                 video          vote_average            vote_count 
##                     0                     0                     0

Text cleaning

In this part we are going to eliminate the desired text from certain columns to be left with only precise information.

##   adult   budget                             homepage  id   imdb_id
## 1 False 30000000 http://toystory.disney.com/toy-story 862 tt0114709
##   original_language original_title
## 1                en      Toy Story
##                                                                                                                                                                                                                                                                                                          overview
## 1 Led by Woody, Andy's toys live happily in his room until Andy's birthday brings Buzz Lightyear onto the scene. Afraid of losing his place in Andy's heart, Woody plots against Buzz. But when circumstances separate Buzz and Woody from their owner, the duo eventually learns to put aside their differences.
##   popularity                      poster_path release_date   revenue runtime
## 1  21.946943 /rhIRbceoE9lR4veEXuwCC2wARtG.jpg   1995-10-30 373554033      81
##     status tagline     title video vote_average vote_count
## 1 Released         Toy Story False          7.7       5415
##                        Genres           Collection Spoken_languages
## 1 [Animation, Comedy, Family] Toy Story Collection          English
##        Production_companies       Production_countries
## 1 [Pixar Animation Studios] [United States of America]

Modification of numerical data

In this part we are going to modify all those columns that have numerical values that require rounding or adding certain aspects.

## Warning: NAs introducidos por coerción

Data type verification

It is important to verify that the variables in our database are of the correct type to be able to work correctly with our analytical tools later.

## 'data.frame':    45466 obs. of  24 variables:
##  $ adult               : chr  "False" "False" "False" "False" ...
##  $ budget              : chr  "30000000" "65000000" "0" "16000000" ...
##  $ homepage            : chr  "http://toystory.disney.com/toy-story" "" "" "" ...
##  $ id                  : chr  "862" "8844" "15602" "31357" ...
##  $ imdb_id             : chr  "tt0114709" "tt0113497" "tt0113228" "tt0114885" ...
##  $ original_language   : chr  "en" "en" "en" "en" ...
##  $ original_title      : chr  "Toy Story" "Jumanji" "Grumpier Old Men" "Waiting to Exhale" ...
##  $ overview            : chr  "Led by Woody, Andy's toys live happily in his room until Andy's birthday brings Buzz Lightyear onto the scene. "| __truncated__ "When siblings Judy and Peter discover an enchanted board game that opens the door to a magical world, they unwi"| __truncated__ "A family wedding reignites the ancient feud between next-door neighbors and fishing buddies John and Max. Meanw"| __truncated__ "Cheated on, mistreated and stepped on, the women are holding their breath, waiting for the elusive \"good man\""| __truncated__ ...
##  $ popularity          : num  21.9 17 11.7 3.9 8.4 17.9 6.7 2.6 5.2 14.7 ...
##  $ poster_path         : chr  "/rhIRbceoE9lR4veEXuwCC2wARtG.jpg" "/vzmL6fP7aPKNKPRTFnZmiUfciyV.jpg" "/6ksm1sjKMFLbO7UY2i6G1ju9SML.jpg" "/16XOMpEaLWkrcPqSQqhTmeJuqQl.jpg" ...
##  $ release_date        : chr  "1995-10-30" "1995-12-15" "1995-12-22" "1995-12-22" ...
##  $ revenue             : num  3.74e+08 2.63e+08 6.87e+07 8.15e+07 7.66e+07 ...
##  $ runtime             : num  81 104 101 127 106 170 127 97 106 130 ...
##  $ status              : chr  "Released" "Released" "Released" "Released" ...
##  $ tagline             : chr  "" "Roll the dice and unleash the excitement!" "Still Yelling. Still Fighting. Still Ready for Love." "Friends are the people who let you be yourself... and never let you forget it." ...
##  $ title               : chr  "Toy Story" "Jumanji" "Grumpier Old Men" "Waiting to Exhale" ...
##  $ video               : chr  "False" "False" "False" "False" ...
##  $ vote_average        : num  7.7 6.9 6.5 6.1 5.7 7.7 6.2 5.4 5.5 6.6 ...
##  $ vote_count          : num  5415 2413 92 34 173 ...
##  $ Genres              : chr  "[Animation, Comedy, Family]" "[Adventure, Fantasy, Family]" "[Romance, Comedy]" "[Comedy, Drama, Romance]" ...
##  $ Collection          : chr  "Toy Story Collection" "" "Grumpy Old Men Collection" "" ...
##  $ Spoken_languages    : chr  "English" "English, Français" "English" "English" ...
##  $ Production_companies: chr  "[Pixar Animation Studios]" "[TriStar Pictures, Teitler Film, Interscope Communications]" "[Warner Bros., Lancaster Gate]" "[Twentieth Century Fox Film Corporation]" ...
##  $ Production_countries: chr  "[United States of America]" "[United States of America]" "[United States of America]" "[United States of America]" ...
## Warning: NAs introducidos por coerción
## 'data.frame':    45466 obs. of  24 variables:
##  $ adult               : logi  FALSE FALSE FALSE FALSE FALSE FALSE ...
##  $ budget              : num  3.0e+07 6.5e+07 0.0 1.6e+07 0.0 6.0e+07 5.8e+07 0.0 3.5e+07 5.8e+07 ...
##  $ homepage            : chr  "http://toystory.disney.com/toy-story" "" "" "" ...
##  $ id                  : chr  "862" "8844" "15602" "31357" ...
##  $ imdb_id             : chr  "tt0114709" "tt0113497" "tt0113228" "tt0114885" ...
##  $ original_language   : chr  "en" "en" "en" "en" ...
##  $ original_title      : chr  "Toy Story" "Jumanji" "Grumpier Old Men" "Waiting to Exhale" ...
##  $ overview            : chr  "Led by Woody, Andy's toys live happily in his room until Andy's birthday brings Buzz Lightyear onto the scene. "| __truncated__ "When siblings Judy and Peter discover an enchanted board game that opens the door to a magical world, they unwi"| __truncated__ "A family wedding reignites the ancient feud between next-door neighbors and fishing buddies John and Max. Meanw"| __truncated__ "Cheated on, mistreated and stepped on, the women are holding their breath, waiting for the elusive \"good man\""| __truncated__ ...
##  $ popularity          : num  21.9 17 11.7 3.9 8.4 17.9 6.7 2.6 5.2 14.7 ...
##  $ poster_path         : chr  "/rhIRbceoE9lR4veEXuwCC2wARtG.jpg" "/vzmL6fP7aPKNKPRTFnZmiUfciyV.jpg" "/6ksm1sjKMFLbO7UY2i6G1ju9SML.jpg" "/16XOMpEaLWkrcPqSQqhTmeJuqQl.jpg" ...
##  $ release_date        : Date, format: "1995-10-30" "1995-12-15" ...
##  $ revenue             : num  3.74e+08 2.63e+08 6.87e+07 8.15e+07 7.66e+07 ...
##  $ runtime             : num  81 104 101 127 106 170 127 97 106 130 ...
##  $ status              : chr  "Released" "Released" "Released" "Released" ...
##  $ tagline             : chr  "" "Roll the dice and unleash the excitement!" "Still Yelling. Still Fighting. Still Ready for Love." "Friends are the people who let you be yourself... and never let you forget it." ...
##  $ title               : chr  "Toy Story" "Jumanji" "Grumpier Old Men" "Waiting to Exhale" ...
##  $ video               : chr  "False" "False" "False" "False" ...
##  $ vote_average        : num  7.7 6.9 6.5 6.1 5.7 7.7 6.2 5.4 5.5 6.6 ...
##  $ vote_count          : num  5415 2413 92 34 173 ...
##  $ Genres              : chr  "[Animation, Comedy, Family]" "[Adventure, Fantasy, Family]" "[Romance, Comedy]" "[Comedy, Drama, Romance]" ...
##  $ Collection          : chr  "Toy Story Collection" "" "Grumpy Old Men Collection" "" ...
##  $ Spoken_languages    : chr  "English" "English, Français" "English" "English" ...
##  $ Production_companies: chr  "[Pixar Animation Studios]" "[TriStar Pictures, Teitler Film, Interscope Communications]" "[Warner Bros., Lancaster Gate]" "[Twentieth Century Fox Film Corporation]" ...
##  $ Production_countries: chr  "[United States of America]" "[United States of America]" "[United States of America]" "[United States of America]" ...

A ($) sign and commas (,) could be added to the “budget” and “revenue” columns where appropriate to give them better formatting, but R would not recognize these variables as numbers and therefore We could not use these variables in the following graphs.You could also add the word “minutes” to the runtime variable to specify that this data is represented in minutes but R would not identify these values as numeric so we cannot do it.

Principal Component Analysis (NOT SEEN IN CLASS)

Principal Component Analysis (PCA) is a dimensionality reduction technique that seeks to transform a set of correlated variables into a set of uncorrelated variables called principal components.

The PCA tool allows us to identify the variables that contribute most to the variability in our data by observing the loadings of each variable in the principal components.

The PCA tool can also help us analyze the correlations between variables by examining the structure of the covariance or correlation matrix. This helps us understand the relationships between different variables and how they contribute to the overall behavior of the data.

This represents each component based on our data

  • PC1 = budget
  • PC2 = Popularity
  • PC3 = revenue
  • PC4 = runtime
  • PC5 = Vote average
  • PC6 = Vote count

This analysis method helps us identify which variables vary the most with your data. We can observe that the PC1 (budget) component is above 2.5 which means that the budget of the films in the database varies too much and this may derive from their country of origin or the company that is financing it.

The popularity and revenue variables are very close to 1 in variance which means that the data in these variables tend to be very close to the average respectively.

The rest of the variables analyzed are below or very close to 0.5, which means that their values do not vary almost at all and are not so useful for finding atypical values that show us what makes successful films special.

Statistical techniques employed

Boxplots

Identifying outliers is very useful as it helps us find certain anomalies in our data that may affect the final result. Also, outliers can reveal unexpected patterns or trends in your data that may not be evident otherwise.

In the boxplot of the vote count variable we can see that the vast majority of the data is concentrated in the lower part of the graph, so we could reach the conclusion that all values above 10,000 are outliers and we must focus on them.

In this boxplot of the vote average variable we must focus specifically on the later outliers since these are the best ranked films and we must analyze why they were rated that way. Thanks to the graph we can reach the conclusion that all films rated higher than 8 are considered atypical and successful.

Histograms

Histograms are a useful visual tool for understanding the distribution of a numerical variable in a data set. This tool will help us better understand the distribution of different variables in our database such as budget, revenue, duration, average vote, etc. Additionally, the tool can help us find certain outliers.

## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

In the histogram of the budget variable we can see a right-skewed shape, which means that most of the films in the database were made with a low budget and little by little it shows us values that stand out in the histogram as for example the maximum value that is equal to $380,000,000 which could clearly be considered an outlier since the average budget is $4,224,579.

## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

In this histogram we can see that only very few films obtain a considerably high revenue since the average revenue is close to $6,870,000, although we can also observe that there are films with a revenue of up to $2,788,000,000 and we could consider these films as outliers.

## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

The runtime histogram shows us that the vast majority of movies last approximately 1 hour and 40 minutes, most likely because people do not last that long in movie theaters. We can also observe outliers on both sides of the histogram since we can observe a movie that is 1 minute long, which may mean that it is a short film or something like that or it is an error, and on the other side we can see a movie that lasts 1256 minutes ( 21 hours) which is extremely rare for a traditional film.

## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

The histogram of the vote_count variable tells us that most of the movies obtained a considerably low number of votes since the average number of votes was 117, this may mean that most of the movies are not that famous and there were not as many interested users. in voting for the most movies. This is why we must focus on the outliers of this histogram since these represent the movies with the most votes because users like them or at least watched them.

## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

The vote_average histogram shows us the rating that users assigned to the movies depending on whether they are good or bad. We can see that most of the movies are rated with an average of 6 (in a range of 1 to 10). We can also observe that there are outliers on both sides of the histogram but we must focus on those films that obtained a rating of 10 since they are the ones that contain the characteristics to create the formula for cinematic success.

Bar graphs

Bar graphs are a powerful tool in data analysis since they help us compare different categories and give us a better visualization of the trends we want to analyze.

The graph shows the 10 movies with the highest number of votes in the database. Each bar represents the number of votes each film received, and the red dots at the top of each bar represent the average number of votes for that film.

We notice that the movies at the top of the graph have a significantly higher number of votes compared to those further down. This suggests that these films are very popular among viewers and have generated great interest and participation from the public.

Furthermore, by looking at the red dots, we can see that most of these movies also have a high average vote. This indicates that not only did they receive a large number of votes, but they were also rated positively by those who saw them. This suggests a high quality perceived by the public.

This graph tells us that the English language has a definitive dominance in the issue of language for the creation of films. We can reach the conclusion that a successful film must be able to be reproduced in English but that it is also important to consider its internalization in countries like France and China since their languages also have a great influence on the film industry.

In this bar graph we can see that the country of the United States of America has a huge difference in the number of films produced there compared to the UK and France, this shows that an important characteristic for a film to be successful is that it is produce in the United States due to the great cinematographic advances that are created in that country.

Understanding the importance of geographic location in the production of films can help us understand the trends and dynamics of the film industry.

Words cloud

The word cloud is a versatile tool that can help us have a better visualization of the key themes that people like to see in movies, it also helps us visualize our data in a much easier and more dynamic way.

## Loading required namespace: tm
## Warning in tm_map.SimpleCorpus(corpus, tm::removePunctuation): transformation
## drops documents
## Warning in tm_map.SimpleCorpus(corpus, function(x) tm::removeWords(x,
## tm::stopwords())): transformation drops documents

In this cloud of words we can see that there are different hierarchical levels in which we can find different key themes that can guide us to know what a movie should be about to be attractive to the public. We can see that some of the words that stand out the most in the word cloud are: Life, young, family, love, war, woman/girl, friends.

We can conclude that the most successful films usually focus on aspects related to everyday life, family relationships and love. Something that is also important is that successful films often use themes related to youth and friendship to attract a younger audience. The inclusion of words like “war” and “woman/girl” suggests that there are films that explore more serious themes such as war and also aspects related to the female experience, so it is important to consider the diversity of genders when making a movie.

Conclusions and Business Recommendations

By implementing these recommendations, major production companies can position themselves for success in an increasingly competitive and dynamic entertainment landscape, unlocking new opportunities for growth, innovation, and creative excellence.

Conclusions

  • Successful films tend to have higher budgets: The analysis of the budget variable revealed a right-skewed distribution, indicating that most films in the dataset were made with relatively low budgets. However, outliers with exceptionally high budgets, such as $380,000,000, were also observed. This suggests that while many films operate within modest budget constraints, a significant number of successful films invest heavily in production, marketing, and other resources.

  • High revenue potential exists, but is not guaranteed: The revenue histogram displayed a wide range of revenue values, with some films generating exceptionally high revenues exceeding $2.7 billion. However, the majority of films did not achieve such levels of success, with the average revenue hovering around $6.87 million. While there is potential for substantial revenue generation in the film industry, success is not guaranteed, and factors such as marketing, audience reception, and competition play critical roles.

  • Audience engagement drives success: The vote count histogram revealed that most films received a relatively low number of votes, suggesting limited audience engagement. However, outliers with significantly higher vote counts were observed, indicating strong audience interest and engagement. Successful films tend to attract larger audiences, leading to increased visibility, word-of-mouth promotion, and ultimately higher ratings and revenue.It is important that when creating a film they focus on topics related to everyday life, family relationships and love because these are things that interest the audience and hook them.

  • Language and geographic location influence success: The analysis of original language and production countries revealed key insights into the global landscape of film making. English emerged as the dominant language for successful films, highlighting the importance of accessibility and marketability in the English-speaking world. Additionally, production in the United States stood out significantly, underscoring the influence of Hollywood and the American film industry on global trends and standards.

Business Recommendations

  • Invest strategically in production and marketing: Major production companies should allocate resources strategically to fund high-quality productions with the potential for broad audience appeal. Investments in innovative storytelling, top-tier talent, and cutting-edge technology can enhance the quality and marketability of films, increasing the likelihood of commercial success.

  • Leverage audience data for targeted marketing: Utilize audience data analytics to identify and target specific demographics and market segments with tailored marketing campaigns. By understanding audience preferences, behaviors, and consumption patterns, companies can optimize marketing efforts to maximize reach, engagement, and conversion.

  • Cultivate international partnerships and collaborations: Explore opportunities for international co-productions, partnerships, and collaborations to leverage diverse talent pools, resources, and market opportunities. By collaborating with international filmmakers, production companies can access new markets, cultural perspectives, and creative insights, enhancing the global appeal and relevance of their films.

  • Diversify content and storytelling: Embrace diversity and inclusivity in content creation and storytelling to resonate with a broader range of audiences. By representing diverse voices, experiences, and perspectives on screen, companies can attract new audiences, foster greater audience engagement, and build brand loyalty and credibility.

  • Adapt to changing industry trends and technologies: Stay agile and adaptable in response to evolving industry trends, technologies, and consumer preferences. Embrace digital platforms, streaming services, and emerging technologies to reach audiences across multiple channels and devices, expanding distribution opportunities and revenue streams.

Appendices

You can find the original data base in the next link :

APA references

LS0tDQp0aXRsZTogIkZpbmFsIEV2aWRlbmNlIg0KYXV0aG9yOiAiQWRyacOhbiBHYXJ6YSAtIEEwMTI4NTQxMiINCmRhdGU6ICIyMDI0LTA0LTMwIg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIHRvYzogdHJ1ZQ0KICAgIHRvY19mbG9hdDogdHJ1ZQ0KICAgIGNvZGVfZG93bmxvYWQ6IHRydWUNCiAgICB0aGVtZTogY29zbW8NCi0tLQ0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gRkFMU0UpDQpgYGANCg0KIVtdKEM6XFxVc2Vyc1xcQm9vdENhbXBcXERvd25sb2Fkc1xcYXR0YWNobWVudC1lY2xpcHNlLW1vdmllcy5qcGcpDQoNCiMgPHNwYW4gc3R5bGUgPSAiY29sb3I6IEJsdWU7Ij5UYWJsZSBvZiBDb250ZW50czwvc3Bhbj4gDQoxLiBFeGVjdXRpdmUgU3VtbWFyeSANCjIuIEludHJvZHVjdGlvbiANCjMuIE9iamVjdGl2ZXMNCjQuIERhdGEgY2xlYW5pbmcgYW5kIERlc2NyaXB0aW9uIA0KNS4gU3RhdGlzdGljYWwgdGVjaG5pcXVlcyBlbXBsb3llZCAvIFJlc3VsdHMNCjYuIENvbmNsdXNpb25zIGFuZCBCdXNpbmVzcyBSZWNvbW1lbmRhdGlvbnMgDQo3LiBBcHBlbmRpY2VzDQo4LiBBUEEgUmVmZXJlbmNlcyANCg0KIyA8c3BhbiBzdHlsZSA9ICJjb2xvcjogQmx1ZTsiPkV4ZWN1dGl2ZSBTdW1tYXJ5PC9zcGFuPiANCg0KVGhpcyByZXBvcnQgb2ZmZXJzIGEgZGV0YWlsZWQgYW5hbHlzaXMgb2YgdGhlIGNoYXJhY3RlcmlzdGljcyBvZiAqKnRoZSBtb3N0IHN1Y2Nlc3NmdWwgbW92aWVzKiouIEtleSBhc3BlY3RzIHJlbGF0ZWQgdG8gcmVzZWFyY2ggYW5kIGRhdGEgYW5hbHlzaXMgYXJlIGFkZHJlc3NlZCwgd2l0aCB0aGUgYWltIG9mIHByb3ZpZGluZyBhIGNsZWFyIGFuZCBpbmZvcm1lZCB2aXNpb24gdGhhdCBzdXBwb3J0cyBzdHJhdGVnaWMgZGVjaXNpb24gbWFraW5nLlRoZSBtYWluIGZpbmRpbmdzIGFuZCByZWNvbW1lbmRhdGlvbnMgZGVyaXZlZCBmcm9tIHRoZSByZXN1bHRzIG9idGFpbmVkIGZyb20gdGhlIGFuYWx5dGljYWwgdG9vbHMgdXNlZCBhcmUgc3VtbWFyaXplZCBiZWxvdzogDQoNCk1haW4gRmluZGluZ3M6DQoNCi0gQnVkZ2V0IEFsbG9jYXRpb246IFRoZSBhbmFseXNpcyByZXZlYWxzIHRoYXQgc3VjY2Vzc2Z1bCBtb3ZpZXMgb2Z0ZW4gYWxsb2NhdGUgc3Vic3RhbnRpYWwgYnVkZ2V0cyB0byBwcm9kdWN0aW9uIGFuZCBtYXJrZXRpbmcsIGluZGljYXRpbmcgYSBjb3JyZWxhdGlvbiBiZXR3ZWVuIGludmVzdG1lbnQgYW5kIHN1Y2Nlc3MuDQoNCi0gQXVkaWVuY2UgRW5nYWdlbWVudDogSGlnaCBsZXZlbHMgb2YgYXVkaWVuY2UgZW5nYWdlbWVudCwgYXMgZXZpZGVuY2VkIGJ5IHZvdGUgY291bnQgYW5kIGF2ZXJhZ2UgcmF0aW5ncywgYXJlIGluZGljYXRpdmUgb2YgYSBmaWxtJ3MgcG90ZW50aWFsIGZvciBzdWNjZXNzLiBUYXJnZXRpbmcgYXVkaWVuY2UgcHJlZmVyZW5jZXMgYW5kIG1heGltaXppbmcgZW5nYWdlbWVudCBjYW4gc2lnbmlmaWNhbnRseSBpbXBhY3QgYSBtb3ZpZSdzIHBlcmZvcm1hbmNlLg0KDQotIEdsb2JhbCBJbmZsdWVuY2U6IEVuZ2xpc2gtbGFuZ3VhZ2UgcHJvZHVjdGlvbnMsIHBhcnRpY3VsYXJseSB0aG9zZSBvcmlnaW5hdGluZyBmcm9tIHRoZSBVbml0ZWQgU3RhdGVzLCBkb21pbmF0ZSB0aGUgZ2xvYmFsIGZpbG0gaW5kdXN0cnkuIEhvd2V2ZXIsIG9wcG9ydHVuaXRpZXMgZXhpc3QgZm9yIGludGVybmF0aW9uYWwgY29sbGFib3JhdGlvbnMgYW5kIHBhcnRuZXJzaGlwcyB0byBkaXZlcnNpZnkgY29udGVudCBhbmQgcmVhY2ggbmV3IG1hcmtldHMuDQoNCi0gQ29udGVudCBEaXZlcnNpdHk6IFN1Y2Nlc3NmdWwgZmlsbXMgb2Z0ZW4gZXhwbG9yZSBkaXZlcnNlIHRoZW1lcyBhbmQgbmFycmF0aXZlcywgcmVzb25hdGluZyB3aXRoIGEgYnJvYWQgc3BlY3RydW0gb2YgYXVkaWVuY2VzLiBFbWJyYWNpbmcgZGl2ZXJzaXR5IGluIHN0b3J5dGVsbGluZyBhbmQgcmVwcmVzZW50YXRpb24gY2FuIGVuaGFuY2UgYXVkaWVuY2UgYXBwZWFsIGFuZCBjdWx0dXJhbCByZWxldmFuY2UuDQoNClJlY29tbWVuZGF0aW9uczoNCg0KLSBTdHJhdGVnaWMgSW52ZXN0bWVudDogQWxsb2NhdGUgcmVzb3VyY2VzIHN0cmF0ZWdpY2FsbHkgdG8gZnVuZCBoaWdoLXF1YWxpdHkgcHJvZHVjdGlvbnMgYW5kIGlubm92YXRpdmUgbWFya2V0aW5nIGNhbXBhaWducy4gUHJpb3JpdGl6ZSBpbnZlc3RtZW50cyBpbiB0YWxlbnQsIHRlY2hub2xvZ3ksIGFuZCBzdG9yeXRlbGxpbmcgdG8gbWF4aW1pemUgdGhlIHBvdGVudGlhbCBmb3IgY29tbWVyY2lhbCBzdWNjZXNzLg0KDQotIEF1ZGllbmNlLUNlbnRyaWMgQXBwcm9hY2g6IExldmVyYWdlIGF1ZGllbmNlIGRhdGEgYW5hbHl0aWNzIHRvIHVuZGVyc3RhbmQgcHJlZmVyZW5jZXMsIGJlaGF2aW9ycywgYW5kIGNvbnN1bXB0aW9uIHBhdHRlcm5zLiBUYWlsb3IgbWFya2V0aW5nIHN0cmF0ZWdpZXMgYW5kIGNvbnRlbnQgb2ZmZXJpbmdzIHRvIHRhcmdldCBzcGVjaWZpYyBkZW1vZ3JhcGhpY3MgYW5kIG1hcmtldCBzZWdtZW50cyBlZmZlY3RpdmVseS4NCg0KLSBJbnRlcm5hdGlvbmFsIENvbGxhYm9yYXRpb246IEV4cGxvcmUgb3Bwb3J0dW5pdGllcyBmb3IgaW50ZXJuYXRpb25hbCBjby1wcm9kdWN0aW9ucyBhbmQgcGFydG5lcnNoaXBzIHRvIGFjY2VzcyBuZXcgbWFya2V0cyBhbmQgY3VsdHVyYWwgcGVyc3BlY3RpdmVzLiBGb3N0ZXIgY29sbGFib3JhdGlvbnMgd2l0aCBkaXZlcnNlIHRhbGVudCBwb29scyB0byBjcmVhdGUgZ2xvYmFsbHkgcmVsZXZhbnQgY29udGVudC4NCg0KLSBEaXZlcnNpZmljYXRpb246IEVtYnJhY2UgZGl2ZXJzaXR5IGFuZCBpbmNsdXNpdml0eSBpbiBjb250ZW50IGNyZWF0aW9uIHRvIGFwcGVhbCB0byBhIHdpZGUgcmFuZ2Ugb2YgYXVkaWVuY2VzLiBSZXByZXNlbnQgZGl2ZXJzZSB2b2ljZXMsIGV4cGVyaWVuY2VzLCBhbmQgcGVyc3BlY3RpdmVzIGF1dGhlbnRpY2FsbHkgdG8gZm9zdGVyIGF1ZGllbmNlIGVuZ2FnZW1lbnQgYW5kIGxveWFsdHkuDQoNCi0gQWRhcHRhYmlsaXR5IGFuZCBJbm5vdmF0aW9uOiBTdGF5IGFnaWxlIGFuZCBhZGFwdGFibGUgaW4gcmVzcG9uc2UgdG8gZXZvbHZpbmcgaW5kdXN0cnkgdHJlbmRzIGFuZCB0ZWNobm9sb2dpY2FsIGFkdmFuY2VtZW50cy4gRW1icmFjZSBkaWdpdGFsIHBsYXRmb3Jtcywgc3RyZWFtaW5nIHNlcnZpY2VzLCBhbmQgZW1lcmdpbmcgdGVjaG5vbG9naWVzIHRvIGV4cGFuZCBkaXN0cmlidXRpb24gY2hhbm5lbHMgYW5kIGVuaGFuY2UgYXVkaWVuY2UgcmVhY2guDQoNCkluIGNvbmNsdXNpb24sIHRoaXMgcmVwb3J0IHByb3ZpZGVzIHZhbHVhYmxlIGluc2lnaHRzIGFuZCBhY3Rpb25hYmxlIHJlY29tbWVuZGF0aW9ucyBmb3IgbWFqb3IgcHJvZHVjdGlvbiBjb21wYW5pZXMgc2Vla2luZyB0byBuYXZpZ2F0ZSB0aGUgY29tcGxleGl0aWVzIG9mIHRoZSBtb2Rlcm4gZmlsbSBpbmR1c3RyeS4gQnkgbGV2ZXJhZ2luZyBkYXRhLWRyaXZlbiBzdHJhdGVnaWVzIGFuZCBlbWJyYWNpbmcgaW5ub3ZhdGlvbiwgY29tcGFuaWVzIGNhbiBwb3NpdGlvbiB0aGVtc2VsdmVzIGZvciBzdWNjZXNzIGluIGFuIGV2ZXItY2hhbmdpbmcgbGFuZHNjYXBlLCBkcml2aW5nIGdyb3d0aCwgYW5kIGZvc3RlcmluZyBjcmVhdGl2aXR5IGFuZCBleGNlbGxlbmNlIGluIGZpbG1tYWtpbmcuDQoNCiMgPHNwYW4gc3R5bGUgPSAiY29sb3I6IEJsdWU7Ij5JbnRyb2R1Y3Rpb248L3NwYW4+IA0KDQpJbiB0b2RheSdzIGR5bmFtaWMgZW50ZXJ0YWlubWVudCBpbmR1c3RyeSwgZGVjb2RpbmcgdGhlIGZvcm11bGEgZm9yIGEgc3VjY2Vzc2Z1bCBtb3ZpZSBoYXMgZXZvbHZlZCBpbnRvIGEgbXVsdGlmYWNldGVkIGNoYWxsZW5nZSBmb3IgbWFqb3IgcHJvZHVjdGlvbiBjb21wYW5pZXMuIFRoZSB0cmFkaXRpb25hbCBtYXJrZXJzIG9mIHN1Y2Nlc3MgaGF2ZSBzaGlmdGVkIGFtaWRzdCB0aGUgcHJvbGlmZXJhdGlvbiBvZiBjb250ZW50IGFjcm9zcyBzb2NpYWwgbWVkaWEgYW5kIHN0cmVhbWluZyBwbGF0Zm9ybXMsIHByZXNlbnRpbmcgYSBjb21wbGV4IGxhbmRzY2FwZSB0byBuYXZpZ2F0ZS4NCg0KQXMgYSBCdXNpbmVzcyBBbmFseXRpY3MgQW5hbHlzdCB0YXNrZWQgd2l0aCBzdHJhdGVnaWMgcGxhbm5pbmcgZm9yIGEgcHJvbWluZW50IGZpbG0gcHJvZHVjdGlvbiBjb21wYW55LCB0aGUgb2JqZWN0aXZlIGlzIGNsZWFyOiB0byB1bmVhcnRoIHRoZSB1bmRlcmx5aW5nIGZhY3RvcnMgdGhhdCBkaWZmZXJlbnRpYXRlIHN1Y2Nlc3NmdWwgbW92aWVzIGZyb20gdGhlaXIgbGVzcyB0cml1bXBoYW50IGNvdW50ZXJwYXJ0cy4gTGV2ZXJhZ2luZyBhIGNvbXByZWhlbnNpdmUgZGF0YXNldCBhcHRseSBuYW1lZCAqIm1vdmllcyBtZXRhZGF0YSIqLCByaWdvcm91cyBhbmFseXRpY2FsIHRlY2huaXF1ZXMgaGF2ZSBiZWVuIGVtcGxveWVkIHRvIGRpc3RpbGwgYWN0aW9uYWJsZSBpbnNpZ2h0cy4NCg0KVGhpcyByZXBvcnQgZGVsdmVzIGludG8gdGhlIGN1bG1pbmF0aW9uIG9mIG1ldGljdWxvdXMgZGF0YSBjbGVhbmluZywgZGl2ZXJzZSBncmFwaGljYWwgcmVwcmVzZW50YXRpb25zLCBhbmQgc29waGlzdGljYXRlZCBhbmFseXRpY2FsIHRvb2xzLCBhbGwgYWltZWQgYXQgdW5yYXZlbGluZyB0aGUgZW5pZ21hIG9mIGNpbmVtYXRpYyBzdWNjZXNzLiBCeSBzY3J1dGluaXppbmcgcGF0dGVybnMsIHRyZW5kcywgYW5kIGNvcnJlbGF0aW9ucyB3aXRoaW4gdGhlIGRhdGFzZXQsIHRoaXMgYW5hbHlzaXMgZW5kZWF2b3JzIHRvIHNoZWQgbGlnaHQgb24gdGhlIGtleSBkZXRlcm1pbmFudHMgb2YgYSBtb3ZpZSdzIHRyaXVtcGggb3IgZGVmZWF0Lg0KDQpBcm1lZCB3aXRoIHRoZXNlIGluc2lnaHRzLCB0aGUgdWx0aW1hdGUgZ29hbCBpcyB0byBlcXVpcCBtYWpvciBwcm9kdWN0aW9uIGNvbXBhbmllcyB3aXRoIHN0cmF0ZWdpYyByZWNvbW1lbmRhdGlvbnMgcG9pc2VkIHRvIGNhdGFseXplIHRoZSBjcmVhdGlvbiBvZiB0aGUgbmV4dCBibG9ja2J1c3RlciBoaXQuIFRocm91Z2ggYSBibGVuZCBvZiBkYXRhLWRyaXZlbiBzdHJhdGVnaWVzIGFuZCBpbmR1c3RyeSBhY3VtZW4sIHRoaXMgcmVwb3J0IGFpbXMgdG8gZ3VpZGUgZGVjaXNpb24tbWFrZXJzIHRvd2FyZHMgYSBwYXRoIG9mIGlubm92YXRpb24gYW5kIHN1Y2Nlc3MgaW4gdGhlIGV2ZXItZXZvbHZpbmcgd29ybGQgb2YgZmlsbSBwcm9kdWN0aW9uLg0KDQojIDxzcGFuIHN0eWxlID0gImNvbG9yOiBCbHVlOyI+T2JqZWN0aXZlcyBvZiB0aGUgcmVwb3J0PC9zcGFuPiANCg0KVGhlc2Ugb2JqZWN0aXZlcyB3aWxsIHNlcnZlIHRvIGd1aWRlIHRoZSByZXNlYXJjaCwgYW5hbHlzaXMsIGFuZCBmaW5hbCByZWNvbW1lbmRhdGlvbnMgb2YgdGhpcyByZXBvcnQuIFRoZSBmdWxmaWxsbWVudCBvZiB0aGVzZSBvYmplY3RpdmVzIHdpbGwgZ3VhcmFudGVlIHRoYXQgdGhlIHJlcG9ydCBwcm92aWRlcyB2YWx1YWJsZSBhbmQgZGVjaXNpdmUgaW5mb3JtYXRpb24gZm9yIGZpbG0gcHJvZHVjdGlvbiBjb21wYW5pZXMuIFRoZSBvYmplY3RpdmVzIG9mIHRoZSByZXBvcnQgYXJlIHRoZSBmb2xsb3dpbmc6IA0KDQotIElkZW50aWZ5IHRoZSBrZXkgZmFjdG9ycyB0aGF0IGNvbnRyaWJ1dGUgdG8gdGhlIHN1Y2Nlc3Mgb3IgZmFpbHVyZSBvZiBhIGZpbG0uDQotIFVzZSBkYXRhIGNsZWFuaW5nIHRlY2huaXF1ZXMgdG8gZ3VhcmFudGVlIHRoZSBxdWFsaXR5IGFuZCByZWxpYWJpbGl0eSBvZiB0aGUgaW5mb3JtYXRpb24gYW5hbHl6ZWQuDQotIEFwcGx5IHZhcmlvdXMgYW5hbHl0aWNhbCB0b29scywgc3VjaCBhcyBiYXIgY2hhcnRzLCBoaXN0b2dyYW1zLCBkZW5zaXRpZXMsIGFuZCBkb3QgcGxvdHMsIHRvIGJldHRlciB1bmRlcnN0YW5kIHRyZW5kcyBhbmQgcGF0dGVybnMgd2l0aGluIHRoZSBkYXRhIHNldC4NCi0gQW5hbHl6ZSB0aGUgcmVsYXRpb25zaGlwcyBhbmQgY29ycmVsYXRpb25zIGJldHdlZW4gZGlmZmVyZW50IHZhcmlhYmxlcyB0byBkaXNjZXJuIHRoZSBkcml2ZXJzIG9mIHN1Y2Nlc3MgaW4gdGhlIGZpbG0gaW5kdXN0cnkuDQotIEdlbmVyYXRlIHN0cmF0ZWdpYyByZWNvbW1lbmRhdGlvbnMgZm9yIG1ham9yIGZpbG0gcHJvZHVjdGlvbiBjb21wYW5pZXMsIGJhc2VkIG9uIHRoZSBmaW5kaW5ncyBhbmQgY29uY2x1c2lvbnMgb2J0YWluZWQgZnJvbSBkYXRhIGFuYWx5c2lzLg0KDQojIDxzcGFuIHN0eWxlID0gImNvbG9yOiBCbHVlOyI+RGF0YSBjbGVhbmluZyBhbmQgRGVzY3JpcHRpb248L3NwYW4+IA0KDQpgYGB7ciwgaW5jbHVkZT1GQUxTRX0NCiNDYWxsaW5nIGxpYnJhcmllcw0KDQpsaWJyYXJ5KHVuaXRzKQ0KbGlicmFyeSh2aXNkYXQpDQpsaWJyYXJ5KERhdGFFeHBsb3JlcikNCmxpYnJhcnkoZHBseXIpDQpsaWJyYXJ5KGphbml0b3IpDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoc3RyaW5ncikNCmxpYnJhcnkodGlkeXIpDQpsaWJyYXJ5KHJlYWRyKQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShqc29ubGl0ZSkNCmxpYnJhcnkod29yZGNsb3VkKQ0KYGBgDQoNCmBgYHtyfQ0KRGF0YUJhc2UgPC0gcmVhZC5jc3YoIkM6XFxVc2Vyc1xcQm9vdENhbXBcXERvd25sb2Fkc1xcYXJjaGl2ZVxcbW92aWVzX21ldGFkYXRhLmNzdiIsKQ0KYGBgDQoNCiMjIDxzcGFuIHN0eWxlID0gImNvbG9yOiBHcmVlbjsiPkRlc2NyaXB0aW9uIG9mIHRoZSBkYXRhPC9zcGFuPiANCg0KVGhlIGZpbGUgZnJvbSB3aGljaCB0aGUgaW5mb3JtYXRpb24gYW5hbHl6ZWQgaW4gdGhpcyByZXBvcnQgaXMgYmVpbmcgb2J0YWluZWQgaXMgY2FsbGVkICJtb3ZpZXMgbWV0YWRhdGEiIGFuZCBpcyBhIGRhdGFiYXNlIHRoYXQgY29udGFpbnMgbWV0YWRhdGEgZm9yIGFsbCA0NSwwMDAgbW92aWVzIGxpc3RlZCBpbiB0aGUgRnVsbCBNb3ZpZUxlbnMgRGF0YXNldC4gVGhpcyBkYXRhYmFzZSBoYXMgZGlmZmVyZW50IGNvbHVtbnMgb2YgZGF0YSBzdWNoIGFzIGJ1ZGdldCwgcmV2ZW51ZSwgcG9zdGVycywgcmVsZWFzZSBkYXRlcywgbGFuZ3VhZ2VzLCBwcm9kdWN0aW9uIGNvbXBhbmllcywgY291bnRyaWVzLCBldGMuIEFsbCB0aGlzIGluZm9ybWF0aW9uIGNhbiBoZWxwIHVzIHJlbGF0ZSB0aGUgc2ltaWxhcml0aWVzIG9mIGdvb2QgbW92aWVzIGluIG9yZGVyIHRvIGRpc2NvdmVyIHRoZSBmb3JtdWxhIGZvciBhIHN1Y2Nlc3NmdWwgbW92aWUuIEFub3RoZXIgdGhpbmcgdG8gbWVudGlvbiBpcyB0aGF0IGFsbCB0aGlzIGluZm9ybWF0aW9uIHdhcyBjb2xsZWN0ZWQgZnJvbSB0aGUgb3BpbmlvbnMgb2YgMjcwLDAwMCByZWFsIHVzZXJzLg0KDQojIyA8c3BhbiBzdHlsZSA9ICJjb2xvcjogR3JlZW47Ij5DbGVhbmluZyBOQSdzIHZhbHVlczwvc3Bhbj4gDQoNCmBgYHtyfQ0KIyBGaW5kaW5nIGhvdyBtYW55IE5BIGFyZSBpbiB0aGUgZGF0YSBiYXNlDQpuYV9jb3VudHNfZGYxIDwtIGNvbFN1bXMoaXMubmEoRGF0YUJhc2UpKQ0KbmFfY291bnRzX2RmMQ0KYGBgDQoNClRoZSBjb2x1bW5zIHdpdGggTkEncyBhcmUgInJ1bnRpbWUiLCAicmV2ZW51ZSIsICJ2b3RlIGNvdW50IiwgInZvdGUgYXZlcmFnZSIgc28gdGhleSBtdXN0IGJlIG1vZGlmaWVkIGJ5IGFkZGluZyBhbiBhdmVyYWdlIHZhbHVlLg0KDQpgYGB7cn0NCiMgQ2xlYW5pbmcgYW5kIHN1bW1hcnkgb2YgY29sdW1uICJydW50aW1lIiwgInJldmVudWUiLCAidm90ZSBjb3VudCIsICJ2b3RlIGF2ZXJhZ2UiDQoNCiMgQ2xlYW5pbmcgdGhlICJydW50aW1lIiBjb2x1bW4NCkRhdGFCYXNlJHJ1bnRpbWVbaXMubmEoRGF0YUJhc2UkcnVudGltZSldIDwtIG1lYW4oRGF0YUJhc2UkcnVudGltZSwgbmEucm0gPSBUUlVFKQ0KRGF0YUJhc2UkcnVudGltZVtEYXRhQmFzZSRydW50aW1lID09IDBdIDwtIG1lYW4oRGF0YUJhc2UkcnVudGltZVtEYXRhQmFzZSRydW50aW1lICE9IDBdLCBuYS5ybSA9IFRSVUUpDQoNCiMgQ2xlYW5pbmcgdGhlICJyZXZlbnVlIiBjb2x1bW4NCkRhdGFCYXNlJHJldmVudWUgPC0gYXMubnVtZXJpYyhEYXRhQmFzZSRyZXZlbnVlKQ0KRGF0YUJhc2UkcmV2ZW51ZVtpcy5uYShEYXRhQmFzZSRyZXZlbnVlKV0gPC0gbWVhbihEYXRhQmFzZSRyZXZlbnVlLCBuYS5ybSA9IFRSVUUpDQpEYXRhQmFzZSRyZXZlbnVlW0RhdGFCYXNlJHJldmVudWUgPT0gMF0gPC0gbWVhbihEYXRhQmFzZSRyZXZlbnVlW0RhdGFCYXNlJHJldmVudWUgIT0gMF0sIG5hLnJtID0gVFJVRSkNCg0KIyBDbGVhbmluZyB0aGUgInZvdGVfY291bnQiIGNvbHVtbg0KRGF0YUJhc2Ukdm90ZV9jb3VudFtpcy5uYShEYXRhQmFzZSR2b3RlX2NvdW50KV0gPC0gbWVhbihEYXRhQmFzZSR2b3RlX2NvdW50LCBuYS5ybSA9IFRSVUUpDQpEYXRhQmFzZSR2b3RlX2NvdW50W0RhdGFCYXNlJHZvdGVfY291bnQgPT0gMF0gPC0gbWVhbihEYXRhQmFzZSR2b3RlX2NvdW50W0RhdGFCYXNlJHZvdGVfY291bnQgIT0gMF0sIG5hLnJtID0gVFJVRSkNCg0KIyBDbGVhbmluZyB0aGUgInZvdGVfYXZlcmFnZSIgY29sdW1uDQpEYXRhQmFzZSR2b3RlX2F2ZXJhZ2VbaXMubmEoRGF0YUJhc2Ukdm90ZV9hdmVyYWdlKV0gPC0gbWVhbihEYXRhQmFzZSR2b3RlX2F2ZXJhZ2UsIG5hLnJtID0gVFJVRSkNCkRhdGFCYXNlJHZvdGVfYXZlcmFnZVtEYXRhQmFzZSR2b3RlX2F2ZXJhZ2UgPT0gMF0gPC0gbWVhbihEYXRhQmFzZSR2b3RlX2F2ZXJhZ2VbRGF0YUJhc2Ukdm90ZV9hdmVyYWdlICE9IDBdLCBuYS5ybSA9IFRSVUUpDQoNCmBgYA0KDQpgYGB7cn0NCiMgTGV0J3MgY2hlY2sgaWYgdGhlcmUgYXJlIHN0aWxsIE5BJ3MgdmFsdWVzDQpuYV9jb3VudHNfZGYxIDwtIGNvbFN1bXMoaXMubmEoRGF0YUJhc2UpKQ0KbmFfY291bnRzX2RmMQ0KRGF0YWJhc2UgPC0gbmFfY291bnRzX2RmMQ0KYGBgDQoNCiMjIDxzcGFuIHN0eWxlID0gImNvbG9yOiBHcmVlbjsiPlRleHQgY2xlYW5pbmc8L3NwYW4+IA0KDQpJbiB0aGlzIHBhcnQgd2UgYXJlIGdvaW5nIHRvIGVsaW1pbmF0ZSB0aGUgZGVzaXJlZCB0ZXh0IGZyb20gY2VydGFpbiBjb2x1bW5zIHRvIGJlIGxlZnQgd2l0aCBvbmx5ICoqcHJlY2lzZSBpbmZvcm1hdGlvbioqLiANCg0KYGBge3J9DQojIEZpcnN0LCB3ZSBkZWZpbmUgYSBmdW5jdGlvbiB0byBleHRyYWN0IHRoZSBnZW5yZSBuYW1lcyBmcm9tIGEgSlNPTiBpbnB1dA0KZXh0cmFjdF9nZW5yZV9uYW1lcyA8LSBmdW5jdGlvbih4KSB7DQogIGlmICghaXMubnVsbCh4KSkgew0KICAgIGdlbnJlX25hbWVzIDwtIGdzdWIoIlxceydpZCc6IFxcZCssICduYW1lJzogJyhbXiddKyknXFx9IiwgIlxcMSIsIHgpDQogICAgZ2VucmVfbmFtZXMgPC0gZ3N1YigiJyIsICIiLCBnZW5yZV9uYW1lcykNCiAgICBnZW5yZV9uYW1lcyA8LSB0cmltd3MoZ2VucmVfbmFtZXMpDQogICAgcmV0dXJuKGdlbnJlX25hbWVzKQ0KICB9DQogIHJldHVybihOQSkNCn0NCg0KIyBXZSBhcHBseSB0aGUgZnVuY3Rpb24gdG8gZWFjaCBlbnRyeSBpbiB0aGUgImdlbnJlIiBjb2x1bW4gYW5kIGNvbmNhdGVuYXRlIHRoZSBuYW1lcyBvZiB0aGUgZ2VucmVzIGludG8gYSBjb21tYS1zZXBhcmF0ZWQgc3RyaW5nDQpEYXRhQmFzZSRHZW5yZXMgPC0gc2FwcGx5KERhdGFCYXNlJGdlbnJlLCBleHRyYWN0X2dlbnJlX25hbWVzKQ0KDQojIFdlIHJlbW92ZSB0aGUgb3JpZ2luYWwgY29sdW1uICJnZW5yZSINCkRhdGFCYXNlJGdlbnJlcyA8LSBOVUxMDQoNCiMgTm93LCB0aGUgbmV3ICJHZW5yZXMiIGNvbHVtbiB3aWxsIGNvbnRhaW4gdGhlIGNvbWJpbmVkIGdlbnJlIG5hbWVzIGluIGEgY29tbWEtc2VwYXJhdGVkIHN0cmluZywgYW5kIHRoZSBvcmlnaW5hbCAiZ2VucmUiIGNvbHVtbiB3aWxsIGhhdmUgYmVlbiByZW1vdmVkDQoNCmBgYA0KDQpgYGB7cn0NCiMgRGVmaW5lIGEgZnVuY3Rpb24gdG8gZXh0cmFjdCB0aGUgY29sbGVjdGlvbiBuYW1lIGZyb20gYSBKU09OIGlucHV0DQpleHRyYWN0X2NvbGxlY3Rpb25fbmFtZSA8LSBmdW5jdGlvbih4KSB7DQogIGlmICghaXMubnVsbCh4KSkgew0KICAgIGNvbGxlY3Rpb25fbmFtZSA8LSBnc3ViKCIuKiduYW1lJzogJyhbXiddKykuKiIsICJcXDEiLCB4KQ0KICAgIHJldHVybihjb2xsZWN0aW9uX25hbWUpDQogIH0NCiAgcmV0dXJuKE5BKQ0KfQ0KDQojIEFwcGx5IHRoZSBmdW5jdGlvbiB0byBlYWNoIGVudHJ5IGluIHRoZSAiYmVsb25nc190b19jb2xsZWN0aW9uIiBjb2x1bW4gYW5kIHN0b3JlIHRoZSBjb2xsZWN0aW9uIG5hbWVzIGluIHRoZSBuZXcgIkNvbGxlY3Rpb24iIGNvbHVtbg0KRGF0YUJhc2UkQ29sbGVjdGlvbiA8LSBzYXBwbHkoRGF0YUJhc2UkYmVsb25nc190b19jb2xsZWN0aW9uLCBleHRyYWN0X2NvbGxlY3Rpb25fbmFtZSkNCg0KIyBSZW1vdmUgdGhlIG9yaWdpbmFsIGNvbHVtbiAiYmVsb25nc190b19jb2xsZWN0aW9uIg0KRGF0YUJhc2UkYmVsb25nc190b19jb2xsZWN0aW9uIDwtIE5VTEwNCg0KIyBOb3csIHRoZSBuZXcgIkNvbGxlY3Rpb24iIGNvbHVtbiB3aWxsIGNvbnRhaW4gdGhlIGNvbGxlY3Rpb24gbmFtZXMgZXh0cmFjdGVkIGZyb20gdGhlICJiZWxvbmdzX3RvX2NvbGxlY3Rpb24iIGNvbHVtbg0KDQpgYGANCg0KYGBge3J9DQojIERlZmluZSBhIGZ1bmN0aW9uIHRvIGV4dHJhY3QgbGFuZ3VhZ2UgbmFtZXMgZnJvbSBhIEpTT04gaW5wdXQNCmV4dHJhY3RfbGFuZ3VhZ2VfbmFtZXMgPC0gZnVuY3Rpb24oeCkgew0KICBpZiAoIWlzLm51bGwoeCkpIHsNCiAgICAjIEV4dHJhY3QgbGFuZ3VhZ2UgbmFtZXMgdXNpbmcgcmVndWxhciBleHByZXNzaW9ucw0KICAgIGxhbmd1YWdlX25hbWVzIDwtIGdzdWIoIlxceydpc29fNjM5XzEnOiAnW14nXSsnLCAnbmFtZSc6ICcoW14nXSspJ30iLCAiXFwxIiwgeCkNCiAgICAjIFJlbW92ZSBlbXB0eSBsYW5ndWFnZSBuYW1lcw0KICAgIGxhbmd1YWdlX25hbWVzIDwtIGxhbmd1YWdlX25hbWVzW2xhbmd1YWdlX25hbWVzICE9ICIiXQ0KICAgIHJldHVybihwYXN0ZShsYW5ndWFnZV9uYW1lcywgY29sbGFwc2UgPSAiLCAiKSkgIyBDb21iaW5lIGxhbmd1YWdlIG5hbWVzIGludG8gYSBjb21tYS1zZXBhcmF0ZWQgc3RyaW5nDQogIH0NCiAgcmV0dXJuKE5BKQ0KfQ0KDQojIEFwcGx5IHRoZSBmdW5jdGlvbiB0byBlYWNoIGVudHJ5IGluIHRoZSAic3Bva2VuX2xhbmd1YWdlcyIgY29sdW1uIGFuZCBzdG9yZSB0aGUgbGFuZ3VhZ2UgbmFtZXMgaW4gdGhlIG5ldyAiU3Bva2VuX2xhbmd1YWdlcyIgY29sdW1uDQpEYXRhQmFzZSRTcG9rZW5fbGFuZ3VhZ2VzIDwtIHNhcHBseShEYXRhQmFzZSRzcG9rZW5fbGFuZ3VhZ2VzLCBleHRyYWN0X2xhbmd1YWdlX25hbWVzKQ0KDQojIFJlbW92ZSB0aGUgb3JpZ2luYWwgY29sdW1uICJzcG9rZW5fbGFuZ3VhZ2VzIg0KRGF0YUJhc2Ukc3Bva2VuX2xhbmd1YWdlcyA8LSBOVUxMDQoNCiMgUmVtb3ZlIGJyYWNrZXRzIGZyb20gdGhlIGxhbmd1YWdlIG5hbWVzIGluIHRoZSAiU3Bva2VuX2xhbmd1YWdlcyIgY29sdW1uDQpEYXRhQmFzZSRTcG9rZW5fbGFuZ3VhZ2VzIDwtIGdzdWIoIlxcW3xcXF0iLCAiIiwgRGF0YUJhc2UkU3Bva2VuX2xhbmd1YWdlcykNCg0KIyBOb3csIHRoZSBuZXcgIlNwb2tlbl9sYW5ndWFnZXMiIGNvbHVtbiB3aWxsIGNvbnRhaW4gdGhlIGNvbWJpbmVkIGxhbmd1YWdlIG5hbWVzIHdpdGhvdXQgYnJhY2tldHMsIGFuZCB0aGUgb3JpZ2luYWwgInNwb2tlbl9sYW5ndWFnZXMiIGNvbHVtbiB3aWxsIGhhdmUgYmVlbiByZW1vdmVkDQpgYGANCg0KYGBge3J9DQojIERlZmluZSBhIGZ1bmN0aW9uIHRvIGV4dHJhY3QgcHJvZHVjdGlvbiBjb21wYW55IG5hbWVzIGZyb20gYSBKU09OIGlucHV0DQpleHRyYWN0X3Byb2R1Y3Rpb25fY29tcGFueV9uYW1lcyA8LSBmdW5jdGlvbih4KSB7DQogIGlmICghaXMubnVsbCh4KSkgew0KICAgICMgRXh0cmFjdCBjb21wYW55IG5hbWVzIHVzaW5nIHJlZ3VsYXIgZXhwcmVzc2lvbnMNCiAgICBjb21wYW55X25hbWVzIDwtIGdzdWIoIlxceyduYW1lJzogJyhbXiddKyknLCAnaWQnOiBcXGQrXFx9IiwgIlxcMSIsIHgpDQogICAgIyBSZW1vdmUgZW1wdHkgY29tcGFueSBuYW1lcw0KICAgIGNvbXBhbnlfbmFtZXMgPC0gY29tcGFueV9uYW1lc1tjb21wYW55X25hbWVzICE9ICIiXQ0KICAgIHJldHVybihwYXN0ZShjb21wYW55X25hbWVzLCBjb2xsYXBzZSA9ICIsICIpKSAjIENvbWJpbmUgY29tcGFueSBuYW1lcyBpbnRvIGEgY29tbWEtc2VwYXJhdGVkIHN0cmluZw0KICB9DQogIHJldHVybihOQSkNCn0NCg0KIyBBcHBseSB0aGUgZnVuY3Rpb24gdG8gZWFjaCBlbnRyeSBpbiB0aGUgInByb2R1Y3Rpb25fY29tcGFuaWVzIiBjb2x1bW4gYW5kIHN0b3JlIHRoZSBjb21wYW55IG5hbWVzIGluIHRoZSBuZXcgIlByb2R1Y3Rpb25fY29tcGFuaWVzIiBjb2x1bW4NCkRhdGFCYXNlJFByb2R1Y3Rpb25fY29tcGFuaWVzIDwtIHNhcHBseShEYXRhQmFzZSRwcm9kdWN0aW9uX2NvbXBhbmllcywgZXh0cmFjdF9wcm9kdWN0aW9uX2NvbXBhbnlfbmFtZXMpDQoNCiMgTm93LCB0aGUgbmV3ICJQcm9kdWN0aW9uX2NvbXBhbmllcyIgY29sdW1uIHdpbGwgY29udGFpbiB0aGUgY29tYmluZWQgY29tcGFueSBuYW1lcw0KDQojIFJlbW92ZSB0aGUgb3JpZ2luYWwgY29sdW1uICJwcm9kdWN0aW9uX2NvbXBhbmllcyINCkRhdGFCYXNlJHByb2R1Y3Rpb25fY29tcGFuaWVzIDwtIE5VTEwNCmBgYA0KDQpgYGB7cn0NCiMgRGVmaW5lIGEgZnVuY3Rpb24gdG8gZXh0cmFjdCBwcm9kdWN0aW9uIGNvdW50cnkgbmFtZXMgZnJvbSBhIEpTT04gaW5wdXQNCmV4dHJhY3RfcHJvZHVjdGlvbl9jb3VudHJ5X25hbWVzIDwtIGZ1bmN0aW9uKHgpIHsNCiAgaWYgKCFpcy5udWxsKHgpKSB7DQogICAgIyBFeHRyYWN0IGNvdW50cnkgbmFtZXMgdXNpbmcgcmVndWxhciBleHByZXNzaW9ucw0KICAgIGNvdW50cnlfbmFtZXMgPC0gZ3N1YigiXFx7J2lzb18zMTY2XzEnOiAnW14nXSsnLCAnbmFtZSc6ICcoW14nXSspJ1xcfSIsICJcXDEiLCB4KQ0KICAgICMgUmVtb3ZlIGVtcHR5IGNvdW50cnkgbmFtZXMNCiAgICBjb3VudHJ5X25hbWVzIDwtIGNvdW50cnlfbmFtZXNbY291bnRyeV9uYW1lcyAhPSAiIl0NCiAgICByZXR1cm4ocGFzdGUoY291bnRyeV9uYW1lcywgY29sbGFwc2UgPSAiLCAiKSkgIyBDb21iaW5lIGNvdW50cnkgbmFtZXMgaW50byBhIGNvbW1hLXNlcGFyYXRlZCBzdHJpbmcNCiAgfQ0KICByZXR1cm4oTkEpDQp9DQoNCiMgQXBwbHkgdGhlIGZ1bmN0aW9uIHRvIGVhY2ggZW50cnkgaW4gdGhlICJwcm9kdWN0aW9uX2NvdW50cmllcyIgY29sdW1uIGFuZCBzdG9yZSB0aGUgY291bnRyeSBuYW1lcyBpbiB0aGUgbmV3ICJQcm9kdWN0aW9uX2NvdW50cmllcyIgY29sdW1uDQpEYXRhQmFzZSRQcm9kdWN0aW9uX2NvdW50cmllcyA8LSBzYXBwbHkoRGF0YUJhc2UkcHJvZHVjdGlvbl9jb3VudHJpZXMsIGV4dHJhY3RfcHJvZHVjdGlvbl9jb3VudHJ5X25hbWVzKQ0KDQojIE5vdywgdGhlIG5ldyAiUHJvZHVjdGlvbl9jb3VudHJpZXMiIGNvbHVtbiB3aWxsIGNvbnRhaW4gdGhlIGNvbWJpbmVkIGNvdW50cnkgbmFtZXMNCg0KIyBSZW1vdmUgdGhlIG9yaWdpbmFsIGNvbHVtbiAicHJvZHVjdGlvbl9jb3VudHJpZXMiDQpEYXRhQmFzZSRwcm9kdWN0aW9uX2NvdW50cmllcyA8LSBOVUxMDQoNCmhlYWQoRGF0YUJhc2UsIDEpDQpgYGANCg0KIyMgPHNwYW4gc3R5bGUgPSAiY29sb3I6IEdyZWVuOyI+TW9kaWZpY2F0aW9uIG9mIG51bWVyaWNhbCBkYXRhPC9zcGFuPiANCg0KSW4gdGhpcyBwYXJ0IHdlIGFyZSBnb2luZyB0byBtb2RpZnkgYWxsIHRob3NlIGNvbHVtbnMgdGhhdCBoYXZlIG51bWVyaWNhbCB2YWx1ZXMgdGhhdCByZXF1aXJlIHJvdW5kaW5nIG9yIGFkZGluZyBjZXJ0YWluIGFzcGVjdHMuDQoNCmBgYHtyfQ0KIyBSb3VuZCB0aGUgdmFsdWVzIGluIHRoZSAidm90ZV9hdmVyYWdlIiBjb2x1bW4gdG8gYSBkZWNpbWFsDQpEYXRhQmFzZSR2b3RlX2F2ZXJhZ2UgPC0gcm91bmQoYXMubnVtZXJpYyhEYXRhQmFzZSR2b3RlX2F2ZXJhZ2UpLCBkaWdpdHMgPSAxKQ0KDQojIFJvdW5kIHRoZSB2YWx1ZXMgaW4gdGhlICJ2b3RlX2NvdW50IiBjb2x1bW4gdG8gY29udmVydCB0aGVtIGluIGludGVnZXIgbnVtYmVycw0KRGF0YUJhc2Ukdm90ZV9jb3VudCA8LSByb3VuZChhcy5udW1lcmljKERhdGFCYXNlJHZvdGVfY291bnQpLCBkaWdpdHMgPSAwKQ0KDQojIFJvdW5kIHRoZSB2YWx1ZXMgaW4gdGhlICJwb3B1bGFyaXR5IiBjb2x1bW4gdG8gYSBkZWNpbWFsDQpEYXRhQmFzZSRwb3B1bGFyaXR5IDwtIHJvdW5kKGFzLm51bWVyaWMoRGF0YUJhc2UkcG9wdWxhcml0eSksIGRpZ2l0cyA9IDEpDQpgYGANCiMjIDxzcGFuIHN0eWxlID0gImNvbG9yOiBHcmVlbjsiPkRhdGEgdHlwZSB2ZXJpZmljYXRpb248L3NwYW4+DQoNCkl0IGlzIGltcG9ydGFudCB0byB2ZXJpZnkgdGhhdCB0aGUgdmFyaWFibGVzIGluIG91ciBkYXRhYmFzZSBhcmUgb2YgdGhlIGNvcnJlY3QgdHlwZSB0byBiZSBhYmxlIHRvIHdvcmsgY29ycmVjdGx5IHdpdGggb3VyIGFuYWx5dGljYWwgdG9vbHMgbGF0ZXIuDQoNCmBgYHtyfQ0KIyBDaGVjayB0aGUgZGF0YSBzdHJ1Y3R1cmUNCnN0cihEYXRhQmFzZSkNCmBgYA0KDQpgYGB7cn0NCiMgQ2hhbmdlIGRhdGEgdHlwZSBvZiBhZHVsdCB0byBsb2dpY2FsDQpEYXRhQmFzZSRhZHVsdCA8LSBhcy5sb2dpY2FsKERhdGFCYXNlJGFkdWx0KQ0KDQojIENoYW5nZSBkYXRhIHR5cGUgb2YgcG9wdWxhcml0eSB0byBudW1lcmljDQpEYXRhQmFzZSRwb3B1bGFyaXR5IDwtIGFzLm51bWVyaWMoRGF0YUJhc2UkcG9wdWxhcml0eSkNCg0KIyBDaGFuZ2UgZGF0YSB0eXBlIG9mIHJlbGVhc2VfZGF0ZSB0byBEYXRlDQpEYXRhQmFzZSRyZWxlYXNlX2RhdGUgPC0gYXMuRGF0ZShEYXRhQmFzZSRyZWxlYXNlX2RhdGUpDQoNCiMgQ2hhbmdlIGRhdGEgdHlwZSBvZiBCdWRnZXQgdG8gbnVtZXJpYw0KRGF0YUJhc2UkYnVkZ2V0IDwtIGFzLm51bWVyaWMoRGF0YUJhc2UkYnVkZ2V0KQ0KYGBgDQoNCmBgYHtyfQ0KIyBWZXJpZnkgdGhhdCBjaGFuZ2VzIGhhdmUgYmVlbiBtYWRlIHRvIHRoZSBkYXRhIHN0cnVjdHVyZQ0Kc3RyKERhdGFCYXNlKQ0KYGBgDQoNCkEgKCQpIHNpZ24gYW5kIGNvbW1hcyAoLCkgY291bGQgYmUgYWRkZWQgdG8gdGhlICJidWRnZXQiIGFuZCAicmV2ZW51ZSIgY29sdW1ucyB3aGVyZSBhcHByb3ByaWF0ZSB0byBnaXZlIHRoZW0gYmV0dGVyIGZvcm1hdHRpbmcsIGJ1dCAqKlIqKiB3b3VsZCBub3QgcmVjb2duaXplIHRoZXNlIHZhcmlhYmxlcyBhcyBudW1iZXJzIGFuZCB0aGVyZWZvcmUgV2UgY291bGQgbm90IHVzZSB0aGVzZSB2YXJpYWJsZXMgaW4gdGhlIGZvbGxvd2luZyBncmFwaHMuWW91IGNvdWxkIGFsc28gYWRkIHRoZSB3b3JkICJtaW51dGVzIiB0byB0aGUgcnVudGltZSB2YXJpYWJsZSB0byBzcGVjaWZ5IHRoYXQgdGhpcyBkYXRhIGlzIHJlcHJlc2VudGVkIGluIG1pbnV0ZXMgYnV0ICoqUioqIHdvdWxkIG5vdCBpZGVudGlmeSB0aGVzZSB2YWx1ZXMgYXMgbnVtZXJpYyBzbyB3ZSBjYW5ub3QgZG8gaXQuDQoNCiMgPHNwYW4gc3R5bGUgPSAiY29sb3I6IEJsdWU7Ij5QcmluY2lwYWwgQ29tcG9uZW50IEFuYWx5c2lzIChOT1QgU0VFTiBJTiBDTEFTUyk8L3NwYW4+DQoNClByaW5jaXBhbCBDb21wb25lbnQgQW5hbHlzaXMgKFBDQSkgaXMgYSBkaW1lbnNpb25hbGl0eSByZWR1Y3Rpb24gdGVjaG5pcXVlIHRoYXQgc2Vla3MgdG8gdHJhbnNmb3JtIGEgc2V0IG9mIGNvcnJlbGF0ZWQgdmFyaWFibGVzIGludG8gYSBzZXQgb2YgdW5jb3JyZWxhdGVkIHZhcmlhYmxlcyBjYWxsZWQgcHJpbmNpcGFsIGNvbXBvbmVudHMuDQoNClRoZSBQQ0EgdG9vbCBhbGxvd3MgdXMgdG8gaWRlbnRpZnkgdGhlIHZhcmlhYmxlcyB0aGF0IGNvbnRyaWJ1dGUgbW9zdCB0byB0aGUgdmFyaWFiaWxpdHkgaW4gb3VyIGRhdGEgYnkgb2JzZXJ2aW5nIHRoZSBsb2FkaW5ncyBvZiBlYWNoIHZhcmlhYmxlIGluIHRoZSBwcmluY2lwYWwgY29tcG9uZW50cy4NCg0KVGhlIFBDQSB0b29sIGNhbiBhbHNvIGhlbHAgdXMgYW5hbHl6ZSB0aGUgY29ycmVsYXRpb25zIGJldHdlZW4gdmFyaWFibGVzIGJ5IGV4YW1pbmluZyB0aGUgc3RydWN0dXJlIG9mIHRoZSBjb3ZhcmlhbmNlIG9yIGNvcnJlbGF0aW9uIG1hdHJpeC4gVGhpcyBoZWxwcyB1cyB1bmRlcnN0YW5kIHRoZSByZWxhdGlvbnNoaXBzIGJldHdlZW4gZGlmZmVyZW50IHZhcmlhYmxlcyBhbmQgaG93IHRoZXkgY29udHJpYnV0ZSB0byB0aGUgb3ZlcmFsbCBiZWhhdmlvciBvZiB0aGUgZGF0YS4NCg0KYGBge3J9DQojIE1lYW4gaW1wdXRhdGlvbiBmb3IgbnVtZXJpY2FsIHZhcmlhYmxlcw0KbnVtZXJpY19jb2xzIDwtIHNhcHBseShEYXRhQmFzZSwgaXMubnVtZXJpYykNCkRhdGFCYXNlW251bWVyaWNfY29sc10gPC0gbGFwcGx5KERhdGFCYXNlW251bWVyaWNfY29sc10sIGZ1bmN0aW9uKHgpIHsNCiAgcmVwbGFjZV9uYSh4LCBtZWFuKHgsIG5hLnJtID0gVFJVRSkpDQp9KQ0KDQoNCiMgSW1wdXRhdGlvbiBieSBtb2RlIGZvciBjYXRlZ29yaWNhbCB2YXJpYWJsZXMNCmNhdGVnb3JpY2FsX2NvbHMgPC0gc2FwcGx5KERhdGFCYXNlLCBpcy5mYWN0b3IpDQpEYXRhQmFzZVtjYXRlZ29yaWNhbF9jb2xzXVtpcy5uYShEYXRhQmFzZVtjYXRlZ29yaWNhbF9jb2xzXSldIDwtIGxhcHBseShEYXRhQmFzZVtjYXRlZ29yaWNhbF9jb2xzXSwgZnVuY3Rpb24oeCkgew0KICBsZXZlbHMgPC0gbGV2ZWxzKHgpDQogIG1vZGVfbGV2ZWwgPC0gbGV2ZWxzW3doaWNoLm1heCh0YWJ1bGF0ZShtYXRjaCh4LCBsZXZlbHMpKSldDQogIHhbaXMubmEoeCldIDwtIG1vZGVfbGV2ZWwNCiAgcmV0dXJuKHgpDQp9KQ0KDQojIFByaW5jaXBhbCBDb21wb25lbnQgQW5hbHlzaXMgKFBDQSkNCiMgU2VsZWN0IG9ubHkgbnVtZXJpYyB2YXJpYWJsZXMgZm9yIFBDQQ0KRGF0YUJhc2VfbnVtZXJpYyA8LSBEYXRhQmFzZVtzYXBwbHkoRGF0YUJhc2UsIGlzLm51bWVyaWMpXQ0KDQojIFBlcmZvcm0gdGhlIFBDQQ0KcGNhX3Jlc3VsdCA8LSBwcmNvbXAoRGF0YUJhc2VfbnVtZXJpYywgc2NhbGUuID0gVFJVRSkNCg0KIyBHcmFwaCBvZiB0aGUgdmFyaWFuY2UgZXhwbGFpbmVkIGJ5IGVhY2ggcHJpbmNpcGFsIGNvbXBvbmVudA0KcGxvdChwY2FfcmVzdWx0LCB0eXBlID0gImwiLCBtYWluID0gIkV4cGxhaW5lZCBWYXJpYW5jZSBieSBQcmluY2lwYWwgQ29tcG9uZW50IikNCmBgYA0KDQpUaGlzIHJlcHJlc2VudHMgZWFjaCBjb21wb25lbnQgYmFzZWQgb24gb3VyIGRhdGENCg0KLSBQQzEgPSBidWRnZXQNCi0gUEMyID0gUG9wdWxhcml0eQ0KLSBQQzMgPSByZXZlbnVlDQotIFBDNCA9IHJ1bnRpbWUgDQotIFBDNSA9IFZvdGUgYXZlcmFnZQ0KLSBQQzYgPSBWb3RlIGNvdW50IA0KDQpUaGlzIGFuYWx5c2lzIG1ldGhvZCBoZWxwcyB1cyBpZGVudGlmeSB3aGljaCB2YXJpYWJsZXMgdmFyeSB0aGUgbW9zdCB3aXRoIHlvdXIgZGF0YS4gV2UgY2FuIG9ic2VydmUgdGhhdCB0aGUgUEMxIChidWRnZXQpIGNvbXBvbmVudCBpcyBhYm92ZSAyLjUgd2hpY2ggbWVhbnMgdGhhdCB0aGUgYnVkZ2V0IG9mIHRoZSBmaWxtcyBpbiB0aGUgZGF0YWJhc2UgdmFyaWVzIHRvbyBtdWNoIGFuZCB0aGlzIG1heSBkZXJpdmUgZnJvbSB0aGVpciBjb3VudHJ5IG9mIG9yaWdpbiBvciB0aGUgY29tcGFueSB0aGF0IGlzIGZpbmFuY2luZyBpdC4NCg0KVGhlIHBvcHVsYXJpdHkgYW5kIHJldmVudWUgdmFyaWFibGVzIGFyZSB2ZXJ5IGNsb3NlIHRvIDEgaW4gdmFyaWFuY2Ugd2hpY2ggbWVhbnMgdGhhdCB0aGUgZGF0YSBpbiB0aGVzZSB2YXJpYWJsZXMgdGVuZCB0byBiZSB2ZXJ5IGNsb3NlIHRvIHRoZSBhdmVyYWdlIHJlc3BlY3RpdmVseS4NCg0KVGhlIHJlc3Qgb2YgdGhlIHZhcmlhYmxlcyBhbmFseXplZCBhcmUgYmVsb3cgb3IgdmVyeSBjbG9zZSB0byAwLjUsIHdoaWNoIG1lYW5zIHRoYXQgdGhlaXIgdmFsdWVzIGRvIG5vdCB2YXJ5IGFsbW9zdCBhdCBhbGwgYW5kIGFyZSBub3Qgc28gdXNlZnVsIGZvciBmaW5kaW5nIGF0eXBpY2FsIHZhbHVlcyB0aGF0IHNob3cgdXMgd2hhdCBtYWtlcyBzdWNjZXNzZnVsIGZpbG1zIHNwZWNpYWwuDQoNCiMgPHNwYW4gc3R5bGUgPSAiY29sb3I6IEJsdWU7Ij5TdGF0aXN0aWNhbCB0ZWNobmlxdWVzIGVtcGxveWVkPC9zcGFuPiANCg0KIyMgPHNwYW4gc3R5bGUgPSAiY29sb3I6IFB1cnBsZTsiPkJveHBsb3RzPC9zcGFuPg0KDQpJZGVudGlmeWluZyBvdXRsaWVycyBpcyB2ZXJ5IHVzZWZ1bCBhcyBpdCBoZWxwcyB1cyBmaW5kIGNlcnRhaW4gYW5vbWFsaWVzIGluIG91ciBkYXRhIHRoYXQgbWF5IGFmZmVjdCB0aGUgZmluYWwgcmVzdWx0LiBBbHNvLCBvdXRsaWVycyBjYW4gcmV2ZWFsIHVuZXhwZWN0ZWQgcGF0dGVybnMgb3IgdHJlbmRzIGluIHlvdXIgZGF0YSB0aGF0IG1heSBub3QgYmUgZXZpZGVudCBvdGhlcndpc2UuDQoNCmBgYHtyfQ0KIyBDcmVhdGUgYm94IGFuZCB3aGlza2VyIHBsb3QgZm9yIHZhcmlhYmxlICJ2b3RlX2NvdW50Ig0KZ2dwbG90KERhdGFCYXNlLCBhZXMoeCA9ICIiLCB5ID0gdm90ZV9jb3VudCkpICsNCiAgZ2VvbV9ib3hwbG90KGZpbGwgPSAibGlnaHRibHVlIiwgY29sb3IgPSAiYmxhY2siKSArDQogIGxhYnModGl0bGUgPSAiQm94cGxvdCBvZiBWb3RlIENvdW50IiwgeSA9ICJWb3RlIENvdW50IikgKw0KICB0aGVtZV9taW5pbWFsKCkNCmBgYA0KDQpJbiB0aGUgYm94cGxvdCBvZiB0aGUgdm90ZSBjb3VudCB2YXJpYWJsZSB3ZSBjYW4gc2VlIHRoYXQgdGhlIHZhc3QgbWFqb3JpdHkgb2YgdGhlIGRhdGEgaXMgY29uY2VudHJhdGVkIGluIHRoZSBsb3dlciBwYXJ0IG9mIHRoZSBncmFwaCwgc28gd2UgY291bGQgcmVhY2ggdGhlIGNvbmNsdXNpb24gdGhhdCBhbGwgdmFsdWVzIGFib3ZlIDEwLDAwMCBhcmUgb3V0bGllcnMgYW5kIHdlIG11c3QgZm9jdXMgb24gdGhlbS4NCg0KYGBge3J9DQojIENyZWF0ZSBib3ggYW5kIHdoaXNrZXIgcGxvdCBmb3IgdmFyaWFibGUgInZvdGVfYXZlcmFnZSINCmdncGxvdChEYXRhQmFzZSwgYWVzKHggPSAiIiwgeSA9IHZvdGVfYXZlcmFnZSkpICsNCiAgZ2VvbV9ib3hwbG90KGZpbGwgPSAibGlnaHRncmVlbiIsIGNvbG9yID0gImJsYWNrIikgKw0KICBsYWJzKHRpdGxlID0gIkJveHBsb3Qgb2YgVm90ZSBBdmVyYWdlIiwgeSA9ICJWb3RlIEF2ZXJhZ2UiKSArDQogIHRoZW1lX21pbmltYWwoKQ0KDQpgYGANCg0KSW4gdGhpcyBib3hwbG90IG9mIHRoZSB2b3RlIGF2ZXJhZ2UgdmFyaWFibGUgd2UgbXVzdCBmb2N1cyBzcGVjaWZpY2FsbHkgb24gdGhlIGxhdGVyIG91dGxpZXJzIHNpbmNlIHRoZXNlIGFyZSB0aGUgYmVzdCByYW5rZWQgZmlsbXMgYW5kIHdlIG11c3QgYW5hbHl6ZSB3aHkgdGhleSB3ZXJlIHJhdGVkIHRoYXQgd2F5LiBUaGFua3MgdG8gdGhlIGdyYXBoIHdlIGNhbiByZWFjaCB0aGUgY29uY2x1c2lvbiB0aGF0IGFsbCBmaWxtcyByYXRlZCBoaWdoZXIgdGhhbiA4IGFyZSBjb25zaWRlcmVkIGF0eXBpY2FsIGFuZCBzdWNjZXNzZnVsLg0KDQojIyA8c3BhbiBzdHlsZSA9ICJjb2xvcjogUHVycGxlOyI+SGlzdG9ncmFtczwvc3Bhbj4NCg0KSGlzdG9ncmFtcyBhcmUgYSB1c2VmdWwgdmlzdWFsIHRvb2wgZm9yIHVuZGVyc3RhbmRpbmcgdGhlIGRpc3RyaWJ1dGlvbiBvZiBhIG51bWVyaWNhbCB2YXJpYWJsZSBpbiBhIGRhdGEgc2V0LiBUaGlzIHRvb2wgd2lsbCBoZWxwIHVzIGJldHRlciB1bmRlcnN0YW5kIHRoZSBkaXN0cmlidXRpb24gb2YgZGlmZmVyZW50IHZhcmlhYmxlcyBpbiBvdXIgZGF0YWJhc2Ugc3VjaCBhcyBidWRnZXQsIHJldmVudWUsIGR1cmF0aW9uLCBhdmVyYWdlIHZvdGUsIGV0Yy4gQWRkaXRpb25hbGx5LCB0aGUgdG9vbCBjYW4gaGVscCB1cyBmaW5kIGNlcnRhaW4gb3V0bGllcnMuDQoNCmBgYHtyfQ0KIyBCdWRnZXQgaGlzdG9ncmFtDQpoaXN0b2dyYW1fYnVkZ2V0IDwtIGdncGxvdChEYXRhQmFzZSwgYWVzKHggPSBidWRnZXQpKSArDQogIGdlb21faGlzdG9ncmFtKGZpbGwgPSAiUmVkIiwgY29sb3IgPSAiQmxhY2siKSArDQogIGxhYnModGl0bGUgPSAiSGlzdG9ncmFtIG9mIEJ1ZGdldCIpDQoNCnByaW50KGhpc3RvZ3JhbV9idWRnZXQpDQpgYGANCg0KYGBge3IsaW5jbHVkZT1GQUxTRX0NCnN1bW1hcnkoRGF0YUJhc2UkYnVkZ2V0KQ0KYGBgDQoNCkluIHRoZSBoaXN0b2dyYW0gb2YgdGhlIGJ1ZGdldCB2YXJpYWJsZSB3ZSBjYW4gc2VlIGEgcmlnaHQtc2tld2VkIHNoYXBlLCB3aGljaCBtZWFucyB0aGF0ICoqbW9zdCBvZiB0aGUgZmlsbXMgaW4gdGhlIGRhdGFiYXNlIHdlcmUgbWFkZSB3aXRoIGEgbG93IGJ1ZGdldCoqIGFuZCBsaXR0bGUgYnkgbGl0dGxlIGl0IHNob3dzIHVzIHZhbHVlcyB0aGF0IHN0YW5kIG91dCBpbiB0aGUgaGlzdG9ncmFtIGFzIGZvciBleGFtcGxlIHRoZSBtYXhpbXVtIHZhbHVlIHRoYXQgaXMgZXF1YWwgdG8gJDM4MCwwMDAsMDAwIHdoaWNoIGNvdWxkIGNsZWFybHkgYmUgY29uc2lkZXJlZCBhbiBvdXRsaWVyIHNpbmNlIHRoZSBhdmVyYWdlIGJ1ZGdldCBpcyAkNCwyMjQsNTc5Lg0KDQpgYGB7cn0NCiMgUmV2ZW51ZSBoaXN0b2dyYW0NCmhpc3RvZ3JhbV9yZXZlbnVlIDwtIGdncGxvdChEYXRhQmFzZSwgYWVzKHggPSByZXZlbnVlKSkgKw0KICBnZW9tX2hpc3RvZ3JhbShmaWxsID0gIk9yYW5nZSIsIGNvbG9yID0gIkJsYWNrIikgKw0KICBsYWJzKHRpdGxlID0gIkhpc3RvZ3JhbSBvZiBSZXZlbnVlIikNCg0KcHJpbnQoaGlzdG9ncmFtX3JldmVudWUpDQpgYGANCg0KYGBge3IsaW5jbHVkZT1GQUxTRX0NCnN1bW1hcnkoRGF0YUJhc2UkcmV2ZW51ZSkNCmBgYA0KDQpJbiB0aGlzIGhpc3RvZ3JhbSB3ZSBjYW4gc2VlIHRoYXQgb25seSAqKnZlcnkgZmV3IGZpbG1zIG9idGFpbiBhIGNvbnNpZGVyYWJseSBoaWdoIHJldmVudWUqKiBzaW5jZSB0aGUgYXZlcmFnZSByZXZlbnVlIGlzIGNsb3NlIHRvICQ2LDg3MCwwMDAsIGFsdGhvdWdoIHdlIGNhbiBhbHNvIG9ic2VydmUgdGhhdCB0aGVyZSBhcmUgZmlsbXMgd2l0aCBhIHJldmVudWUgb2YgdXAgdG8gJDIsNzg4LDAwMCwwMDAgYW5kIHdlIGNvdWxkIGNvbnNpZGVyIHRoZXNlIGZpbG1zIGFzIG91dGxpZXJzLg0KDQpgYGB7cn0NCiMgUnVudGltZSBoaXN0b2dyYW0NCmhpc3RvZ3JhbV9ydW50aW1lIDwtIGdncGxvdChEYXRhQmFzZSwgYWVzKHggPSBydW50aW1lKSkgKw0KICBnZW9tX2hpc3RvZ3JhbShmaWxsID0gIlBpbmsiLCBjb2xvciA9ICJCbGFjayIpICsNCiAgbGFicyh0aXRsZSA9ICJIaXN0b2dyYW0gb2YgUnVudGltZSIpDQoNCnByaW50KGhpc3RvZ3JhbV9ydW50aW1lKQ0KYGBgDQoNCmBgYHtyLGluY2x1ZGU9RkFMU0V9DQpzdW1tYXJ5KERhdGFCYXNlJHJ1bnRpbWUpDQpgYGANCg0KVGhlIHJ1bnRpbWUgaGlzdG9ncmFtIHNob3dzIHVzIHRoYXQgdGhlIHZhc3QgbWFqb3JpdHkgb2YgbW92aWVzIGxhc3QgYXBwcm94aW1hdGVseSAxIGhvdXIgYW5kIDQwIG1pbnV0ZXMsIG1vc3QgbGlrZWx5IGJlY2F1c2UgcGVvcGxlIGRvIG5vdCBsYXN0IHRoYXQgbG9uZyBpbiBtb3ZpZSB0aGVhdGVycy4gV2UgY2FuIGFsc28gb2JzZXJ2ZSBvdXRsaWVycyBvbiBib3RoIHNpZGVzIG9mIHRoZSBoaXN0b2dyYW0gc2luY2Ugd2UgY2FuIG9ic2VydmUgYSBtb3ZpZSB0aGF0IGlzIDEgbWludXRlIGxvbmcsIHdoaWNoIG1heSBtZWFuIHRoYXQgaXQgaXMgYSBzaG9ydCBmaWxtIG9yIHNvbWV0aGluZyBsaWtlIHRoYXQgb3IgaXQgaXMgYW4gZXJyb3IsIGFuZCBvbiB0aGUgb3RoZXIgc2lkZSB3ZSBjYW4gc2VlIGEgbW92aWUgdGhhdCBsYXN0cyAxMjU2IG1pbnV0ZXMgKCAyMSBob3Vycykgd2hpY2ggaXMgZXh0cmVtZWx5IHJhcmUgZm9yIGEgdHJhZGl0aW9uYWwgZmlsbS4NCg0KYGBge3J9DQojIFZvdGUgY291bnQgaGlzdG9ncmFtDQpoaXN0b2dyYW1fdm90ZV9jb3VudCA8LSBnZ3Bsb3QoRGF0YUJhc2UsIGFlcyh4ID0gdm90ZV9jb3VudCkpICsNCiAgZ2VvbV9oaXN0b2dyYW0oZmlsbCA9ICJCcm93biIsIGNvbG9yID0gIkJsYWNrIikgKw0KICBsYWJzKHRpdGxlID0gIkhpc3RvZ3JhbSBvZiBWb3RlIGNvdW50IikNCg0KcHJpbnQoaGlzdG9ncmFtX3ZvdGVfY291bnQpDQpgYGANCg0KYGBge3IsaW5jbHVkZT1GQUxTRX0NCnN1bW1hcnkoRGF0YUJhc2Ukdm90ZV9jb3VudCkNCmBgYA0KDQpUaGUgaGlzdG9ncmFtIG9mIHRoZSB2b3RlX2NvdW50IHZhcmlhYmxlIHRlbGxzIHVzIHRoYXQgbW9zdCBvZiB0aGUgbW92aWVzIG9idGFpbmVkIGEgY29uc2lkZXJhYmx5IGxvdyBudW1iZXIgb2Ygdm90ZXMgc2luY2UgdGhlIGF2ZXJhZ2UgbnVtYmVyIG9mIHZvdGVzIHdhcyAxMTcsIHRoaXMgbWF5IG1lYW4gdGhhdCBtb3N0IG9mIHRoZSBtb3ZpZXMgYXJlIG5vdCB0aGF0IGZhbW91cyBhbmQgdGhlcmUgd2VyZSBub3QgYXMgbWFueSBpbnRlcmVzdGVkIHVzZXJzLiBpbiB2b3RpbmcgZm9yIHRoZSBtb3N0IG1vdmllcy4gVGhpcyBpcyB3aHkgd2UgbXVzdCBmb2N1cyBvbiB0aGUgb3V0bGllcnMgb2YgdGhpcyBoaXN0b2dyYW0gc2luY2UgdGhlc2UgcmVwcmVzZW50IHRoZSBtb3ZpZXMgd2l0aCB0aGUgbW9zdCB2b3RlcyBiZWNhdXNlIHVzZXJzIGxpa2UgdGhlbSBvciBhdCBsZWFzdCB3YXRjaGVkIHRoZW0uDQoNCmBgYHtyfQ0KIyBWb3RlIGF2ZXJhZ2UgaGlzdG9ncmFtDQpoaXN0b2dyYW1fdm90ZV9hdmVyYWdlIDwtIGdncGxvdChEYXRhQmFzZSwgYWVzKHggPSB2b3RlX2F2ZXJhZ2UpKSArDQogIGdlb21faGlzdG9ncmFtKGZpbGwgPSAiR3JlZW4iLCBjb2xvciA9ICJCbGFjayIpICsNCiAgbGFicyh0aXRsZSA9ICJIaXN0b2dyYW0gb2YgVm90ZSBhdmVyYWdlIikNCg0KcHJpbnQoaGlzdG9ncmFtX3ZvdGVfYXZlcmFnZSkNCmBgYA0KDQpgYGB7cixpbmNsdWRlPUZBTFNFfQ0Kc3VtbWFyeShEYXRhQmFzZSR2b3RlX2F2ZXJhZ2UpDQpgYGANCg0KVGhlIHZvdGVfYXZlcmFnZSBoaXN0b2dyYW0gc2hvd3MgdXMgdGhlIHJhdGluZyB0aGF0IHVzZXJzIGFzc2lnbmVkIHRvIHRoZSBtb3ZpZXMgZGVwZW5kaW5nIG9uIHdoZXRoZXIgdGhleSBhcmUgZ29vZCBvciBiYWQuIFdlIGNhbiBzZWUgdGhhdCBtb3N0IG9mIHRoZSBtb3ZpZXMgYXJlIHJhdGVkIHdpdGggYW4gYXZlcmFnZSBvZiA2IChpbiBhIHJhbmdlIG9mIDEgdG8gMTApLiBXZSBjYW4gYWxzbyBvYnNlcnZlIHRoYXQgdGhlcmUgYXJlIG91dGxpZXJzIG9uIGJvdGggc2lkZXMgb2YgdGhlIGhpc3RvZ3JhbSBidXQgd2UgbXVzdCBmb2N1cyBvbiB0aG9zZSBmaWxtcyB0aGF0IG9idGFpbmVkIGEgcmF0aW5nIG9mIDEwIHNpbmNlIHRoZXkgYXJlIHRoZSBvbmVzIHRoYXQgY29udGFpbiB0aGUgY2hhcmFjdGVyaXN0aWNzIHRvIGNyZWF0ZSB0aGUgZm9ybXVsYSBmb3IgY2luZW1hdGljIHN1Y2Nlc3MuDQoNCg0KIyMgPHNwYW4gc3R5bGUgPSAiY29sb3I6IFB1cnBsZTsiPkJhciBncmFwaHM8L3NwYW4+DQoNCkJhciBncmFwaHMgYXJlIGEgcG93ZXJmdWwgdG9vbCBpbiBkYXRhIGFuYWx5c2lzIHNpbmNlIHRoZXkgaGVscCB1cyBjb21wYXJlIGRpZmZlcmVudCBjYXRlZ29yaWVzIGFuZCBnaXZlIHVzIGEgYmV0dGVyIHZpc3VhbGl6YXRpb24gb2YgdGhlIHRyZW5kcyB3ZSB3YW50IHRvIGFuYWx5emUuDQoNCmBgYHtyfQ0KIyBTb3J0IHRoZSBkYXRhYmFzZSBieSB0aGUgdmFyaWFibGUgInZvdGVfY291bnQiIGluIGRlc2NlbmRpbmcgb3JkZXINCkRhdGFCYXNlX3NvcnRlZCA8LSBEYXRhQmFzZVtvcmRlcihEYXRhQmFzZSR2b3RlX2NvdW50LCBkZWNyZWFzaW5nID0gVFJVRSksIF0NCg0KIyBTZWxlY3QgdGhlIDEwIGZpbG1zIHdpdGggdGhlIGhpZ2hlc3QgbnVtYmVyIG9mIHZvdGVzDQp0b3BfMTBfbW92aWVzIDwtIGhlYWQoRGF0YUJhc2Vfc29ydGVkLCAxMCkNCg0KIyBDcmVhdGUgdGhlIGdyYXBoDQpnZ3Bsb3QodG9wXzEwX21vdmllcywgYWVzKHggPSByZW9yZGVyKHRpdGxlLCB2b3RlX2NvdW50KSwgeSA9IHZvdGVfY291bnQpKSArDQogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBmaWxsID0gInNreWJsdWUiKSArDQogIGdlb21fcG9pbnQoYWVzKHkgPSB2b3RlX2F2ZXJhZ2UgKiBtYXgodm90ZV9jb3VudCkgLyBtYXgodm90ZV9hdmVyYWdlKSksIGNvbG9yID0gInJlZCIsIHNpemUgPSAzKSArDQogIGxhYnModGl0bGUgPSAiVG9wIDEwIE1vdmllcyBieSBWb3RlIENvdW50IGFuZCBWb3RlIEF2ZXJhZ2UiLCB4ID0gIk1vdmllIFRpdGxlIiwgeSA9ICJWb3RlIENvdW50IikgKw0KICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKSArDQogIGdlb21fdGV4dChhZXMobGFiZWwgPSB2b3RlX2F2ZXJhZ2UpLCB2anVzdCA9IC0wLjUsIGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDQpICsNCiAgY29vcmRfZmxpcCgpDQpgYGANCg0KVGhlIGdyYXBoIHNob3dzIHRoZSAxMCBtb3ZpZXMgd2l0aCB0aGUgaGlnaGVzdCBudW1iZXIgb2Ygdm90ZXMgaW4gdGhlIGRhdGFiYXNlLiBFYWNoIGJhciByZXByZXNlbnRzIHRoZSBudW1iZXIgb2Ygdm90ZXMgZWFjaCBmaWxtIHJlY2VpdmVkLCBhbmQgdGhlIHJlZCBkb3RzIGF0IHRoZSB0b3Agb2YgZWFjaCBiYXIgcmVwcmVzZW50IHRoZSBhdmVyYWdlIG51bWJlciBvZiB2b3RlcyBmb3IgdGhhdCBmaWxtLg0KDQpXZSBub3RpY2UgdGhhdCB0aGUgbW92aWVzIGF0IHRoZSB0b3Agb2YgdGhlIGdyYXBoIGhhdmUgYSBzaWduaWZpY2FudGx5IGhpZ2hlciBudW1iZXIgb2Ygdm90ZXMgY29tcGFyZWQgdG8gdGhvc2UgZnVydGhlciBkb3duLiBUaGlzIHN1Z2dlc3RzIHRoYXQgdGhlc2UgZmlsbXMgYXJlIHZlcnkgcG9wdWxhciBhbW9uZyB2aWV3ZXJzIGFuZCBoYXZlIGdlbmVyYXRlZCBncmVhdCBpbnRlcmVzdCBhbmQgcGFydGljaXBhdGlvbiBmcm9tIHRoZSBwdWJsaWMuDQoNCkZ1cnRoZXJtb3JlLCBieSBsb29raW5nIGF0IHRoZSByZWQgZG90cywgd2UgY2FuIHNlZSB0aGF0IG1vc3Qgb2YgdGhlc2UgbW92aWVzIGFsc28gaGF2ZSBhIGhpZ2ggYXZlcmFnZSB2b3RlLiBUaGlzIGluZGljYXRlcyB0aGF0IG5vdCBvbmx5IGRpZCB0aGV5IHJlY2VpdmUgYSBsYXJnZSBudW1iZXIgb2Ygdm90ZXMsIGJ1dCB0aGV5IHdlcmUgYWxzbyByYXRlZCBwb3NpdGl2ZWx5IGJ5IHRob3NlIHdobyBzYXcgdGhlbS4gVGhpcyBzdWdnZXN0cyBhIGhpZ2ggcXVhbGl0eSBwZXJjZWl2ZWQgYnkgdGhlIHB1YmxpYy4NCg0KYGBge3J9DQojIEZpbHRlciBibGFuayB2YWx1ZXMgaW4gU3Bva2VuX2xhbmd1YWdlcyBjb2x1bW4NCkRhdGFCYXNlX25vX2JsYW5rIDwtIERhdGFCYXNlW0RhdGFCYXNlJFNwb2tlbl9sYW5ndWFnZXMgIT0gIiIsIF0NCg0KIyBDb3VudCB0aGUgZnJlcXVlbmN5IG9mIGVhY2ggbGFuZ3VhZ2UNCmxhbmd1YWdlX2ZyZXEgPC0gdGFibGUoRGF0YUJhc2Vfbm9fYmxhbmskU3Bva2VuX2xhbmd1YWdlcykNCg0KIyBTZWxlY3QgdGhlIHRocmVlIG1vc3QgY29tbW9uIGxhbmd1YWdlcw0KdG9wX2xhbmd1YWdlcyA8LSBuYW1lcyhzb3J0KGxhbmd1YWdlX2ZyZXEsIGRlY3JlYXNpbmcgPSBUUlVFKSlbMTozXQ0KDQojIEZpbHRlciB0aGUgZGF0YWJhc2UgdG8gaW5jbHVkZSBvbmx5IHJvd3Mgd2l0aCB0aGUgdGhyZWUgbW9zdCBjb21tb24gbGFuZ3VhZ2VzDQpEYXRhQmFzZV9maWx0ZXJlZCA8LSBEYXRhQmFzZV9ub19ibGFua1tEYXRhQmFzZV9ub19ibGFuayRTcG9rZW5fbGFuZ3VhZ2VzICVpbiUgdG9wX2xhbmd1YWdlcywgXQ0KDQojIEJhciBjaGFydCBmb3IgdGhlIHRocmVlIG1vc3QgY29tbW9uIGxhbmd1YWdlcw0KZ2dwbG90KERhdGFCYXNlX2ZpbHRlcmVkLCBhZXMoeCA9IFNwb2tlbl9sYW5ndWFnZXMpKSArDQogIGdlb21fYmFyKGZpbGwgPSAic2t5Ymx1ZSIsIGNvbG9yID0gImJsYWNrIikgKw0KICBsYWJzKHRpdGxlID0gIkRpc3RyaWJ1dGlvbiBvZiBUb3AgMyBPcmlnaW5hbCBMYW5ndWFnZXMiLA0KICAgICAgIHggPSAiT3JpZ2luYWwgTGFuZ3VhZ2UiLA0KICAgICAgIHkgPSAiRnJlcXVlbmN5IikNCg0KDQpgYGANCg0KVGhpcyBncmFwaCB0ZWxscyB1cyB0aGF0IHRoZSBFbmdsaXNoIGxhbmd1YWdlIGhhcyBhIGRlZmluaXRpdmUgZG9taW5hbmNlIGluIHRoZSBpc3N1ZSBvZiBsYW5ndWFnZSBmb3IgdGhlIGNyZWF0aW9uIG9mIGZpbG1zLiBXZSBjYW4gcmVhY2ggdGhlIGNvbmNsdXNpb24gdGhhdCBhIHN1Y2Nlc3NmdWwgZmlsbSBtdXN0IGJlIGFibGUgdG8gYmUgcmVwcm9kdWNlZCBpbiBFbmdsaXNoIGJ1dCB0aGF0IGl0IGlzIGFsc28gaW1wb3J0YW50IHRvIGNvbnNpZGVyIGl0cyBpbnRlcm5hbGl6YXRpb24gaW4gY291bnRyaWVzIGxpa2UgRnJhbmNlIGFuZCBDaGluYSBzaW5jZSB0aGVpciBsYW5ndWFnZXMgYWxzbyBoYXZlIGEgZ3JlYXQgaW5mbHVlbmNlIG9uIHRoZSBmaWxtIGluZHVzdHJ5Lg0KDQpgYGB7cn0NCiMgRmlsdGVyIGJsYW5rIHZhbHVlcyBhbmQgcmVtb3ZlIGJyYWNrZXRzIGZyb20gUHJvZHVjdGlvbl9jb3VudHJpZXMgY29sdW1uDQpEYXRhQmFzZV9jbGVhbmVkIDwtIERhdGFCYXNlW0RhdGFCYXNlJFByb2R1Y3Rpb25fY291bnRyaWVzICE9ICIiICYgRGF0YUJhc2UkUHJvZHVjdGlvbl9jb3VudHJpZXMgIT0gIltdIiwgXQ0KRGF0YUJhc2VfY2xlYW5lZCRQcm9kdWN0aW9uX2NvdW50cmllcyA8LSBnc3ViKCJcXFt8XFxdIiwgIiIsIERhdGFCYXNlX2NsZWFuZWQkUHJvZHVjdGlvbl9jb3VudHJpZXMpDQoNCiMgQ291bnQgdGhlIGZyZXF1ZW5jeSBvZiBlYWNoIGNvdW50cnkNCmNvdW50cmllc19mcmVxIDwtIHRhYmxlKHVubGlzdChzdHJzcGxpdChEYXRhQmFzZV9jbGVhbmVkJFByb2R1Y3Rpb25fY291bnRyaWVzLCAiLCAiKSkpDQoNCiMgU2VsZWN0IHRoZSB0aHJlZSBtb3N0IGNvbW1vbiBjb3VudHJpZXMNCnRvcF9jb3VudHJpZXMgPC0gbmFtZXMoc29ydChjb3VudHJpZXNfZnJlcSwgZGVjcmVhc2luZyA9IFRSVUUpKVsxOjNdDQoNCiMgRmlsdGVyIHRoZSBkYXRhYmFzZSB0byBpbmNsdWRlIG9ubHkgcm93cyB3aXRoIHRoZSB0aHJlZSBtb3N0IGNvbW1vbiBjb3VudHJpZXMNCkRCX2ZpbHRlcmVkIDwtIERhdGFCYXNlX2NsZWFuZWRbRGF0YUJhc2VfY2xlYW5lZCRQcm9kdWN0aW9uX2NvdW50cmllcyAlaW4lIHRvcF9jb3VudHJpZXMsIF0NCg0KIyBCYXIgY2hhcnQgZm9yIHRoZSB0aHJlZSBtb3N0IGNvbW1vbiBjb3VudHJpZXMNCmdncGxvdChEQl9maWx0ZXJlZCwgYWVzKHggPSBQcm9kdWN0aW9uX2NvdW50cmllcykpICsNCiAgZ2VvbV9iYXIoZmlsbCA9ICJQdXJwbGUiLCBjb2xvciA9ICJibGFjayIpICsNCiAgbGFicyh0aXRsZSA9ICJEaXN0cmlidXRpb24gb2YgVG9wIDMgUHJvZHVjdGlvbiBDb3VudHJpZXMiLA0KICAgICAgIHggPSAiUHJvZHVjdGlvbiBDb3VudHJ5IiwNCiAgICAgICB5ID0gIkZyZXF1ZW5jeSIpICsNCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSAwLCB2anVzdCA9IDAuNSwgaGp1c3QgPSAxKSkgICMgQWRqdXN0IGFuZ2xlIG9mIHgtYXhpcyBsYWJlbHMgZm9yIHJlYWRhYmlsaXR5DQpgYGANCg0KSW4gdGhpcyBiYXIgZ3JhcGggd2UgY2FuIHNlZSB0aGF0IHRoZSBjb3VudHJ5IG9mIHRoZSBVbml0ZWQgU3RhdGVzIG9mIEFtZXJpY2EgaGFzIGEgaHVnZSBkaWZmZXJlbmNlIGluIHRoZSBudW1iZXIgb2YgZmlsbXMgcHJvZHVjZWQgdGhlcmUgY29tcGFyZWQgdG8gdGhlIFVLIGFuZCBGcmFuY2UsIHRoaXMgc2hvd3MgdGhhdCBhbiBpbXBvcnRhbnQgY2hhcmFjdGVyaXN0aWMgZm9yIGEgZmlsbSB0byBiZSBzdWNjZXNzZnVsIGlzIHRoYXQgaXQgaXMgcHJvZHVjZSBpbiB0aGUgVW5pdGVkIFN0YXRlcyBkdWUgdG8gdGhlIGdyZWF0IGNpbmVtYXRvZ3JhcGhpYyBhZHZhbmNlcyB0aGF0IGFyZSBjcmVhdGVkIGluIHRoYXQgY291bnRyeS4NCg0KVW5kZXJzdGFuZGluZyB0aGUgaW1wb3J0YW5jZSBvZiBnZW9ncmFwaGljIGxvY2F0aW9uIGluIHRoZSBwcm9kdWN0aW9uIG9mIGZpbG1zIGNhbiBoZWxwIHVzIHVuZGVyc3RhbmQgdGhlIHRyZW5kcyBhbmQgZHluYW1pY3Mgb2YgdGhlIGZpbG0gaW5kdXN0cnkuDQoNCiMjIDxzcGFuIHN0eWxlID0gImNvbG9yOiBQdXJwbGU7Ij5Xb3JkcyBjbG91ZDwvc3Bhbj4NCg0KVGhlIHdvcmQgY2xvdWQgaXMgYSB2ZXJzYXRpbGUgdG9vbCB0aGF0IGNhbiBoZWxwIHVzIGhhdmUgYSBiZXR0ZXIgdmlzdWFsaXphdGlvbiBvZiB0aGUga2V5IHRoZW1lcyB0aGF0IHBlb3BsZSBsaWtlIHRvIHNlZSBpbiBtb3ZpZXMsIGl0IGFsc28gaGVscHMgdXMgdmlzdWFsaXplIG91ciBkYXRhIGluIGEgbXVjaCBlYXNpZXIgYW5kIG1vcmUgZHluYW1pYyB3YXkuDQoNCmBgYHtyfQ0KIyBDcmVhdGUgYSB3b3JkIGNsb3VkIGJhc2VkIG9uIHRoZSAib3ZlcnZpZXciIHZhcmlhYmxlDQp3b3JkY2xvdWQod29yZHMgPSBEYXRhQmFzZSRvdmVydmlldywNCiAgICAgICAgICBtaW4uZnJlcSA9IDUsICAgICAgICAgICMgRnJlY3VlbmNpYSBtw61uaW1hIHBhcmEgaW5jbHVpciB1bmEgcGFsYWJyYQ0KICAgICAgICAgIG1heC53b3JkcyA9IDc1LCAgICAgICMgTsO6bWVybyBtw6F4aW1vIGRlIHBhbGFicmFzIGVuIGxhIG51YmUNCiAgICAgICAgICByYW5kb20ub3JkZXIgPSBGQUxTRSwgIyBPcmRlbiBhbGVhdG9yaW8gZGUgbGFzIHBhbGFicmFzDQogICAgICAgICAgY29sb3JzID0gYnJld2VyLnBhbCg4LCAiRGFyazIiKSkgIyBQYWxldGEgZGUgY29sb3Jlcw0KDQojIFdvcmQgY2xvdWQgdGl0bGUNCnRpdGxlKCJXb3JkIENsb3VkIG9mIE1vdmllIE92ZXJ2aWV3cyIpDQpgYGANCg0KSW4gdGhpcyBjbG91ZCBvZiB3b3JkcyB3ZSBjYW4gc2VlIHRoYXQgdGhlcmUgYXJlIGRpZmZlcmVudCBoaWVyYXJjaGljYWwgbGV2ZWxzIGluIHdoaWNoIHdlIGNhbiBmaW5kIGRpZmZlcmVudCBrZXkgdGhlbWVzIHRoYXQgY2FuIGd1aWRlIHVzIHRvIGtub3cgd2hhdCBhIG1vdmllIHNob3VsZCBiZSBhYm91dCB0byBiZSBhdHRyYWN0aXZlIHRvIHRoZSBwdWJsaWMuIFdlIGNhbiBzZWUgdGhhdCBzb21lIG9mIHRoZSB3b3JkcyB0aGF0IHN0YW5kIG91dCB0aGUgbW9zdCBpbiB0aGUgd29yZCBjbG91ZCBhcmU6ICoqTGlmZSwgeW91bmcsIGZhbWlseSwgbG92ZSwgd2FyLCB3b21hbi9naXJsLCBmcmllbmRzKiouIA0KDQpXZSBjYW4gY29uY2x1ZGUgdGhhdCB0aGUgbW9zdCBzdWNjZXNzZnVsIGZpbG1zIHVzdWFsbHkgZm9jdXMgb24gYXNwZWN0cyByZWxhdGVkIHRvIGV2ZXJ5ZGF5IGxpZmUsIGZhbWlseSByZWxhdGlvbnNoaXBzIGFuZCBsb3ZlLiBTb21ldGhpbmcgdGhhdCBpcyBhbHNvIGltcG9ydGFudCBpcyB0aGF0IHN1Y2Nlc3NmdWwgZmlsbXMgb2Z0ZW4gdXNlIHRoZW1lcyByZWxhdGVkIHRvIHlvdXRoIGFuZCBmcmllbmRzaGlwIHRvIGF0dHJhY3QgYSB5b3VuZ2VyIGF1ZGllbmNlLiBUaGUgaW5jbHVzaW9uIG9mIHdvcmRzIGxpa2UgIndhciIgYW5kICJ3b21hbi9naXJsIiBzdWdnZXN0cyB0aGF0IHRoZXJlIGFyZSBmaWxtcyB0aGF0IGV4cGxvcmUgbW9yZSBzZXJpb3VzIHRoZW1lcyBzdWNoIGFzIHdhciBhbmQgYWxzbyBhc3BlY3RzIHJlbGF0ZWQgdG8gdGhlIGZlbWFsZSBleHBlcmllbmNlLCBzbyBpdCBpcyBpbXBvcnRhbnQgdG8gY29uc2lkZXIgdGhlIGRpdmVyc2l0eSBvZiBnZW5kZXJzIHdoZW4gbWFraW5nIGEgbW92aWUuDQoNCiMgPHNwYW4gc3R5bGUgPSAiY29sb3I6IEJsdWU7Ij5Db25jbHVzaW9ucyBhbmQgQnVzaW5lc3MgUmVjb21tZW5kYXRpb25zPC9zcGFuPiANCg0KQnkgaW1wbGVtZW50aW5nIHRoZXNlIHJlY29tbWVuZGF0aW9ucywgbWFqb3IgcHJvZHVjdGlvbiBjb21wYW5pZXMgY2FuIHBvc2l0aW9uIHRoZW1zZWx2ZXMgZm9yIHN1Y2Nlc3MgaW4gYW4gaW5jcmVhc2luZ2x5IGNvbXBldGl0aXZlIGFuZCBkeW5hbWljIGVudGVydGFpbm1lbnQgbGFuZHNjYXBlLCB1bmxvY2tpbmcgbmV3IG9wcG9ydHVuaXRpZXMgZm9yIGdyb3d0aCwgaW5ub3ZhdGlvbiwgYW5kIGNyZWF0aXZlIGV4Y2VsbGVuY2UuDQoNCiMjIDxzcGFuIHN0eWxlID0gImNvbG9yOiBSZWQ7Ij5Db25jbHVzaW9uczwvc3Bhbj4gIA0KDQotICoqU3VjY2Vzc2Z1bCBmaWxtcyB0ZW5kIHRvIGhhdmUgaGlnaGVyIGJ1ZGdldHMqKjogVGhlIGFuYWx5c2lzIG9mIHRoZSBidWRnZXQgdmFyaWFibGUgcmV2ZWFsZWQgYSByaWdodC1za2V3ZWQgZGlzdHJpYnV0aW9uLCBpbmRpY2F0aW5nIHRoYXQgbW9zdCBmaWxtcyBpbiB0aGUgZGF0YXNldCB3ZXJlIG1hZGUgd2l0aCByZWxhdGl2ZWx5IGxvdyBidWRnZXRzLiBIb3dldmVyLCBvdXRsaWVycyB3aXRoIGV4Y2VwdGlvbmFsbHkgaGlnaCBidWRnZXRzLCBzdWNoIGFzICQzODAsMDAwLDAwMCwgd2VyZSBhbHNvIG9ic2VydmVkLiBUaGlzIHN1Z2dlc3RzIHRoYXQgd2hpbGUgbWFueSBmaWxtcyBvcGVyYXRlIHdpdGhpbiBtb2Rlc3QgYnVkZ2V0IGNvbnN0cmFpbnRzLCBhIHNpZ25pZmljYW50IG51bWJlciBvZiBzdWNjZXNzZnVsIGZpbG1zIGludmVzdCBoZWF2aWx5IGluIHByb2R1Y3Rpb24sIG1hcmtldGluZywgYW5kIG90aGVyIHJlc291cmNlcy4NCg0KLSAqKkhpZ2ggcmV2ZW51ZSBwb3RlbnRpYWwgZXhpc3RzLCBidXQgaXMgbm90IGd1YXJhbnRlZWQqKjogVGhlIHJldmVudWUgaGlzdG9ncmFtIGRpc3BsYXllZCBhIHdpZGUgcmFuZ2Ugb2YgcmV2ZW51ZSB2YWx1ZXMsIHdpdGggc29tZSBmaWxtcyBnZW5lcmF0aW5nIGV4Y2VwdGlvbmFsbHkgaGlnaCByZXZlbnVlcyBleGNlZWRpbmcgJDIuNyBiaWxsaW9uLiBIb3dldmVyLCB0aGUgbWFqb3JpdHkgb2YgZmlsbXMgZGlkIG5vdCBhY2hpZXZlIHN1Y2ggbGV2ZWxzIG9mIHN1Y2Nlc3MsIHdpdGggdGhlIGF2ZXJhZ2UgcmV2ZW51ZSBob3ZlcmluZyBhcm91bmQgJDYuODcgbWlsbGlvbi4gV2hpbGUgdGhlcmUgaXMgcG90ZW50aWFsIGZvciBzdWJzdGFudGlhbCByZXZlbnVlIGdlbmVyYXRpb24gaW4gdGhlIGZpbG0gaW5kdXN0cnksIHN1Y2Nlc3MgaXMgbm90IGd1YXJhbnRlZWQsIGFuZCBmYWN0b3JzIHN1Y2ggYXMgbWFya2V0aW5nLCBhdWRpZW5jZSByZWNlcHRpb24sIGFuZCBjb21wZXRpdGlvbiBwbGF5IGNyaXRpY2FsIHJvbGVzLg0KDQotICoqQXVkaWVuY2UgZW5nYWdlbWVudCBkcml2ZXMgc3VjY2VzcyoqOiBUaGUgdm90ZSBjb3VudCBoaXN0b2dyYW0gcmV2ZWFsZWQgdGhhdCBtb3N0IGZpbG1zIHJlY2VpdmVkIGEgcmVsYXRpdmVseSBsb3cgbnVtYmVyIG9mIHZvdGVzLCBzdWdnZXN0aW5nIGxpbWl0ZWQgYXVkaWVuY2UgZW5nYWdlbWVudC4gSG93ZXZlciwgb3V0bGllcnMgd2l0aCBzaWduaWZpY2FudGx5IGhpZ2hlciB2b3RlIGNvdW50cyB3ZXJlIG9ic2VydmVkLCBpbmRpY2F0aW5nIHN0cm9uZyBhdWRpZW5jZSBpbnRlcmVzdCBhbmQgZW5nYWdlbWVudC4gU3VjY2Vzc2Z1bCBmaWxtcyB0ZW5kIHRvIGF0dHJhY3QgbGFyZ2VyIGF1ZGllbmNlcywgbGVhZGluZyB0byBpbmNyZWFzZWQgdmlzaWJpbGl0eSwgd29yZC1vZi1tb3V0aCBwcm9tb3Rpb24sIGFuZCB1bHRpbWF0ZWx5IGhpZ2hlciByYXRpbmdzIGFuZCByZXZlbnVlLkl0IGlzIGltcG9ydGFudCB0aGF0IHdoZW4gY3JlYXRpbmcgYSBmaWxtIHRoZXkgZm9jdXMgb24gdG9waWNzIHJlbGF0ZWQgdG8gZXZlcnlkYXkgbGlmZSwgZmFtaWx5IHJlbGF0aW9uc2hpcHMgYW5kIGxvdmUgYmVjYXVzZSB0aGVzZSBhcmUgdGhpbmdzIHRoYXQgaW50ZXJlc3QgdGhlIGF1ZGllbmNlIGFuZCBob29rIHRoZW0uDQoNCi0gKipMYW5ndWFnZSBhbmQgZ2VvZ3JhcGhpYyBsb2NhdGlvbiBpbmZsdWVuY2Ugc3VjY2VzcyoqOiBUaGUgYW5hbHlzaXMgb2Ygb3JpZ2luYWwgbGFuZ3VhZ2UgYW5kIHByb2R1Y3Rpb24gY291bnRyaWVzIHJldmVhbGVkIGtleSBpbnNpZ2h0cyBpbnRvIHRoZSBnbG9iYWwgbGFuZHNjYXBlIG9mIGZpbG0gbWFraW5nLiBFbmdsaXNoIGVtZXJnZWQgYXMgdGhlIGRvbWluYW50IGxhbmd1YWdlIGZvciBzdWNjZXNzZnVsIGZpbG1zLCBoaWdobGlnaHRpbmcgdGhlIGltcG9ydGFuY2Ugb2YgYWNjZXNzaWJpbGl0eSBhbmQgbWFya2V0YWJpbGl0eSBpbiB0aGUgRW5nbGlzaC1zcGVha2luZyB3b3JsZC4gQWRkaXRpb25hbGx5LCBwcm9kdWN0aW9uIGluIHRoZSBVbml0ZWQgU3RhdGVzIHN0b29kIG91dCBzaWduaWZpY2FudGx5LCB1bmRlcnNjb3JpbmcgdGhlIGluZmx1ZW5jZSBvZiBIb2xseXdvb2QgYW5kIHRoZSBBbWVyaWNhbiBmaWxtIGluZHVzdHJ5IG9uIGdsb2JhbCB0cmVuZHMgYW5kIHN0YW5kYXJkcy4NCg0KIyMgPHNwYW4gc3R5bGUgPSAiY29sb3I6IFJlZDsiPkJ1c2luZXNzIFJlY29tbWVuZGF0aW9uczwvc3Bhbj4gDQoNCi0gKipJbnZlc3Qgc3RyYXRlZ2ljYWxseSBpbiBwcm9kdWN0aW9uIGFuZCBtYXJrZXRpbmcqKjogTWFqb3IgcHJvZHVjdGlvbiBjb21wYW5pZXMgc2hvdWxkIGFsbG9jYXRlIHJlc291cmNlcyBzdHJhdGVnaWNhbGx5IHRvIGZ1bmQgaGlnaC1xdWFsaXR5IHByb2R1Y3Rpb25zIHdpdGggdGhlIHBvdGVudGlhbCBmb3IgYnJvYWQgYXVkaWVuY2UgYXBwZWFsLiBJbnZlc3RtZW50cyBpbiBpbm5vdmF0aXZlIHN0b3J5dGVsbGluZywgdG9wLXRpZXIgdGFsZW50LCBhbmQgY3V0dGluZy1lZGdlIHRlY2hub2xvZ3kgY2FuIGVuaGFuY2UgdGhlIHF1YWxpdHkgYW5kIG1hcmtldGFiaWxpdHkgb2YgZmlsbXMsIGluY3JlYXNpbmcgdGhlIGxpa2VsaWhvb2Qgb2YgY29tbWVyY2lhbCBzdWNjZXNzLg0KDQotICoqTGV2ZXJhZ2UgYXVkaWVuY2UgZGF0YSBmb3IgdGFyZ2V0ZWQgbWFya2V0aW5nKio6IFV0aWxpemUgYXVkaWVuY2UgZGF0YSBhbmFseXRpY3MgdG8gaWRlbnRpZnkgYW5kIHRhcmdldCBzcGVjaWZpYyBkZW1vZ3JhcGhpY3MgYW5kIG1hcmtldCBzZWdtZW50cyB3aXRoIHRhaWxvcmVkIG1hcmtldGluZyBjYW1wYWlnbnMuIEJ5IHVuZGVyc3RhbmRpbmcgYXVkaWVuY2UgcHJlZmVyZW5jZXMsIGJlaGF2aW9ycywgYW5kIGNvbnN1bXB0aW9uIHBhdHRlcm5zLCBjb21wYW5pZXMgY2FuIG9wdGltaXplIG1hcmtldGluZyBlZmZvcnRzIHRvIG1heGltaXplIHJlYWNoLCBlbmdhZ2VtZW50LCBhbmQgY29udmVyc2lvbi4NCg0KLSAqKkN1bHRpdmF0ZSBpbnRlcm5hdGlvbmFsIHBhcnRuZXJzaGlwcyBhbmQgY29sbGFib3JhdGlvbnMqKjogRXhwbG9yZSBvcHBvcnR1bml0aWVzIGZvciBpbnRlcm5hdGlvbmFsIGNvLXByb2R1Y3Rpb25zLCBwYXJ0bmVyc2hpcHMsIGFuZCBjb2xsYWJvcmF0aW9ucyB0byBsZXZlcmFnZSBkaXZlcnNlIHRhbGVudCBwb29scywgcmVzb3VyY2VzLCBhbmQgbWFya2V0IG9wcG9ydHVuaXRpZXMuIEJ5IGNvbGxhYm9yYXRpbmcgd2l0aCBpbnRlcm5hdGlvbmFsIGZpbG1tYWtlcnMsIHByb2R1Y3Rpb24gY29tcGFuaWVzIGNhbiBhY2Nlc3MgbmV3IG1hcmtldHMsIGN1bHR1cmFsIHBlcnNwZWN0aXZlcywgYW5kIGNyZWF0aXZlIGluc2lnaHRzLCBlbmhhbmNpbmcgdGhlIGdsb2JhbCBhcHBlYWwgYW5kIHJlbGV2YW5jZSBvZiB0aGVpciBmaWxtcy4NCg0KLSAqKkRpdmVyc2lmeSBjb250ZW50IGFuZCBzdG9yeXRlbGxpbmcqKjogRW1icmFjZSBkaXZlcnNpdHkgYW5kIGluY2x1c2l2aXR5IGluIGNvbnRlbnQgY3JlYXRpb24gYW5kIHN0b3J5dGVsbGluZyB0byByZXNvbmF0ZSB3aXRoIGEgYnJvYWRlciByYW5nZSBvZiBhdWRpZW5jZXMuIEJ5IHJlcHJlc2VudGluZyBkaXZlcnNlIHZvaWNlcywgZXhwZXJpZW5jZXMsIGFuZCBwZXJzcGVjdGl2ZXMgb24gc2NyZWVuLCBjb21wYW5pZXMgY2FuIGF0dHJhY3QgbmV3IGF1ZGllbmNlcywgZm9zdGVyIGdyZWF0ZXIgYXVkaWVuY2UgZW5nYWdlbWVudCwgYW5kIGJ1aWxkIGJyYW5kIGxveWFsdHkgYW5kIGNyZWRpYmlsaXR5Lg0KDQotICoqQWRhcHQgdG8gY2hhbmdpbmcgaW5kdXN0cnkgdHJlbmRzIGFuZCB0ZWNobm9sb2dpZXMqKjogU3RheSBhZ2lsZSBhbmQgYWRhcHRhYmxlIGluIHJlc3BvbnNlIHRvIGV2b2x2aW5nIGluZHVzdHJ5IHRyZW5kcywgdGVjaG5vbG9naWVzLCBhbmQgY29uc3VtZXIgcHJlZmVyZW5jZXMuIEVtYnJhY2UgZGlnaXRhbCBwbGF0Zm9ybXMsIHN0cmVhbWluZyBzZXJ2aWNlcywgYW5kIGVtZXJnaW5nIHRlY2hub2xvZ2llcyB0byByZWFjaCBhdWRpZW5jZXMgYWNyb3NzIG11bHRpcGxlIGNoYW5uZWxzIGFuZCBkZXZpY2VzLCBleHBhbmRpbmcgZGlzdHJpYnV0aW9uIG9wcG9ydHVuaXRpZXMgYW5kIHJldmVudWUgc3RyZWFtcy4NCg0KIyA8c3BhbiBzdHlsZSA9ICJjb2xvcjogQmx1ZTsiPkFwcGVuZGljZXM8L3NwYW4+IA0KDQpZb3UgY2FuIGZpbmQgdGhlIG9yaWdpbmFsIGRhdGEgYmFzZSBpbiB0aGUgbmV4dCBsaW5rIDogDQoNCi0gaHR0cHM6Ly93d3cua2FnZ2xlLmNvbS9kYXRhc2V0cy9yb3VuYWtiYW5pay90aGUtbW92aWVzLWRhdGFzZXQNCg0KIyA8c3BhbiBzdHlsZSA9ICJjb2xvcjogQmx1ZTsiPkFQQSByZWZlcmVuY2VzPC9zcGFuPiANCg0KLSBXaWxtYXIsIFMuICgyMDE5KS4gQW7DoWxpc2lzIGRlIGNvbXBvbmVudGVzIHByaW5jaXBhbGVzIFtZb3VUdWJlIFZpZGVvXS4gSW4gWW91VHViZS4gaHR0cHM6Ly93d3cueW91dHViZS5jb20vd2F0Y2g/dj16a3hpdnFQeC1iYw0KDQotIEdvbnrDoWxleiwgRi4gKDIwMjMsIE1heSA1KS4gSW50cm9kdWNjacOzbiBFbCBhbsOhbGlzaXMgZGUgY29tcG9uZW50ZXMgcHJpbmNpcGFsZXMgKFBDQSwgcG9yIHN1cyBzaWdsYXMgZW4gaW5nbMOpcykgZXMgdW5hIHTDqWNuaWNhIGVzdGFkw61zdGljYSBhbXBsaWFtZW50ZSB1dGlsaXphZGEgZW4gbGEgY2llbmNpYSBkZSBkYXRvcyB5IGVuIGRpdmVyc29zIGNhbXBvcyBkZSBlc3R1ZGlvLiBTdSBwcmluY2lwYWwgb2JqZXRpdm8gZXMgcmVkdWNpciBsYSBkaW1lbnNpb25hbGlkYWQgZGUgdW4gY29uanVudG8gZGUgZGF0b3MgbWllbnRyYXMgc2UgcHJlc2VydmEgbGEgbWF5b3IgY2FudGkuIExpbmtlZGluLmNvbS4gaHR0cHM6Ly9lcy5saW5rZWRpbi5jb20vcHVsc2UvYW4lQzMlQTFsaXNpcy1kZS1jb21wb25lbnRlcy1wcmluY2lwYWxlcy1wY2EtZnJhbmNpc2NvLWdvbnolQzMlQTFsZXojOn46dGV4dD1FbCUyMGFuJUMzJUExbGlzaXMlMjBkZSUyMGNvbXBvbmVudGVzJTIwcHJpbmNpcGFsZXMsbWF5b3IlMjBjYW50aWRhZCUyMGRlJTIwaW5mb3JtYWNpJUMzJUIzbiUyMHBvc2libGUuDQoNCi0gQmFuaWssIFIuICgyMDE3KS4gVGhlIE1vdmllcyBEYXRhc2V0LiBLYWdnbGUuY29tLiBodHRwczovL3d3dy5rYWdnbGUuY29tL2RhdGFzZXRzL3JvdW5ha2JhbmlrL3RoZS1tb3ZpZXMtZGF0YXNldA0KDQo=