# Packages
library(tidyverse)
library(mosaic)

Research Question

How have the GDP rankings of African countries changed over time? And what has been the rate of change in Liberia’s GDP over time?


Data

This dataset features Gross Domestic Product (GDP) data from 1960 to 2020 for various countries and regions, highlighting economic trends and growth. As a key economic indicator, GDP measures the total value of goods and services produced, reflecting the economic health of a nation or region. Available on Kaggle, this dataset supports data science projects and encourages community engagement through sharing insights and methodologies.

Load data into R

gdp_1960_2020 <- read_csv("gdp_1960_2020.csv")
head(gdp_1960_2020)
year rank country state gdp gdp_percent
1960 1 the United States America 543300000000 0.4684827
1960 2 United Kingdom Europe 73233967692 0.0631490
1960 3 France Europe 62225478000 0.0536565
1960 4 China Asia 59716467625 0.0514930
1960 5 Japan Asia 44307342950 0.0382058
1960 6 Canada America 40461721692 0.0348898

Variables

names(gdp_1960_2020)
## [1] "year"        "rank"        "country"     "state"       "gdp"        
## [6] "gdp_percent"

The variables I used in my data visualization are:

Year, country, gdp, state, & gdp_percent


Data Analysis

# Filter data for African countries only
african_gdp_data <- filter(gdp_1960_2020, state == "Africa")
head(african_gdp_data)
year rank country state gdp gdp_percent
1960 19 South Africa Africa 7575396973 0.0065322
1960 29 Nigeria Africa 4196092258 0.0036183
1960 34 Congo (gold) Africa 3359404117 0.0028968
1960 37 Algeria Africa 2723593384 0.0023485
1960 40 Morocco Africa 2037150716 0.0017566
1960 47 Sudan Africa 1307333333 0.0011273

Summary Statistics

# Calculate summary statistics for GDP
summary_stats <- favstats(~ gdp, data = african_gdp_data)
summary_stats
min Q1 median Q3 max mean sd n missing
9122751 849963326 2934846651 10706395832 546676374567 16458827546 47668881356 2854 0

Interactive Presentation

This visualization traces the GDP growth of each African country from 1960 to 2020. It allows viewers to observe trends in economic development, identify periods of rapid growth or decline, and compare the trajectories of different countries. By examining the entire continent, we can see which countries have experienced significant economic advancements and start to think about how external factors like global oil prices or regional conflicts have impacted economies.

library(ggplot2)
library(plotly)
## 
## Attaching package: 'plotly'
## The following object is masked from 'package:mosaic':
## 
##     do
## The following object is masked from 'package:ggplot2':
## 
##     last_plot
## The following object is masked from 'package:stats':
## 
##     filter
## The following object is masked from 'package:graphics':
## 
##     layout
# Convert factors to ensure grouping works correctly
african_gdp_data$country <- as.factor(african_gdp_data$country)

p <- ggplot(african_gdp_data, aes(x = year, y = gdp, color = country, group = country, 
                                  text = paste("Country:", country, "<br>GDP:", gdp))) + 
    geom_line() + 
    theme_minimal() + 
    labs(title = "GDP Growth Over Time for All African Countries", 
         x = "Year", 
         y = "GDP")

# Convert to a plotly object
ggplotly(p, tooltip = "text")

####Top and Bottom Performers in GDP Growth

Provide a summary of what this visualization shows and how it helps to answer your research question.

The visualization showcases the top and bottom 5 GDP performers among African countries in the year 2020. I chose 2022 because it is the final year data are available to date. Each bar in the plot represents a country, with the height of the bar indicating its GDP value. The color gradient applied to the bars provides visual emphasis, with darker shades indicating higher GDP values. This visualization helps answer the research question by illustrating the economic disparities among African countries in terms of GDP performance. By identifying both the top and bottom performers, viewers can gain insights into the economic dynamics within the continent. Understanding which countries have the highest and lowest GDP values in 2020 contributes to a broader understanding of how economic resources are distributed across African nations and provides context for analyzing trends in GDP rankings over time.

library(dplyr)
library(scales)
## 
## Attaching package: 'scales'
## The following object is masked from 'package:mosaic':
## 
##     rescale
## The following object is masked from 'package:purrr':
## 
##     discard
## The following object is masked from 'package:readr':
## 
##     col_factor
# Define the color gradient function
get_gradient_color <- function(rank, total) {
  grDevices::colorRampPalette(c("blue", "lightblue"))(total)[rank]
}

# Filter for the top 5 GDP performers in 2020
top_2020 <- african_gdp_data %>%
  filter(year == 2020) %>%
  arrange(desc(gdp)) %>%
  slice(1:5)

# Add a color gradient based on rank
top_2020$color <- get_gradient_color(1:nrow(top_2020), nrow(top_2020))

# Filter for the bottom 5 GDP performers in 2020
bottom_2020 <- african_gdp_data %>%
  filter(year == 2020) %>%
  arrange(desc(gdp)) %>%
  slice((n()-4):n())

# Add a color gradient based on rank
bottom_2020$color <- get_gradient_color(1:nrow(bottom_2020), nrow(bottom_2020))

# Plot for top 5 performers
top_plot <- ggplot(top_2020, aes(x = reorder(country, gdp), y = gdp, fill = color)) + 
  geom_col(show.legend = FALSE) + 
  geom_text(aes(label = scales::comma(gdp)), hjust = 1.1, size = 3.5) +
  coord_flip() + 
  theme_minimal() + 
  labs(title = "Top 5 GDP Performers in 2020", 
       x = "", 
       y = "GDP")

# Plot for bottom 5 performers
bottom_plot <- ggplot(bottom_2020, aes(x = reorder(country, gdp), y = gdp, fill = color)) + 
  geom_col(show.legend = FALSE) + 
  geom_text(aes(label = scales::comma(gdp)), hjust = 1.1, size = 3.5) +
  coord_flip() + 
  theme_minimal() + 
  labs(title = "Bottom 5 GDP Performers in 2020", 
       x = "", 
       y = "GDP")

# Print the plots
print(top_plot)

print(bottom_plot)

Website Page 3: Africa Fastest Growing GDP as well as countries with the slowest growing economy

The code generates two visualizations: one showing the top 5 fastest-growing economies over time and the other displaying the top 5 slowest-growing economies. Each line represents a country’s GDP trend, with color indicating the country. Users can hover over lines for detailed GDP, year, and growth rate information. These visualizations directly address the research question by providing insights into African countries’ GDP growth rates over time, allowing users to identify trends and disparities in economic development.

# Calculate the growth rate for each country
growth_rates <- african_gdp_data %>%
  group_by(country) %>%
  summarize(start_gdp = first(gdp),
            end_gdp = last(gdp),
            growth_rate = (last(gdp) - first(gdp)) / first(gdp) * 100,
            .groups = 'drop') %>%
  arrange(desc(growth_rate))

# Identify the  top 5 fastest growing economies
top_5_countries <- head(growth_rates, 5)$country

# Filter the data to only include the top 5 fastest growing countries and calculate percentage change for each year
top_5_data <- african_gdp_data %>%
  filter(country %in% top_5_countries) %>%
  arrange(country, year) %>%
  group_by(country) %>%
  mutate(percentage_change = (gdp - lag(gdp)) / lag(gdp) * 100) %>%
  ungroup()

# Create the ggplot with the text aesthetic for hover information
top_5_plot <- ggplot(top_5_data, aes(x = year, y = gdp, group = country, color = country,
                                     text = paste("Country:", country,
                                                  "<br>Year:", year,
                                                  "<br>GDP:", dollar(gdp),
                                                  "<br>Annual Growth:", round(percentage_change, 2), "%"))) +
  geom_line() +
  geom_point() +
  scale_y_continuous(labels = scales::dollar_format(prefix = "$", suffix = "", big.mark = ",", decimal.mark = ".", accuracy = 1)) +
  theme_minimal() +
  labs(title = "Top 5 Fastest Growing Economies Over Time", x = "Year", y = "GDP (in USD)", caption = "Data source: Your Source")

# Convert the ggplot object to plotly for interactivity
top_5_plotly <- ggplotly(top_5_plot, tooltip = "text")

# Print the interactive plot
top_5_plotly
# Calculate the growth rate for each country
growth_rates <- african_gdp_data %>%
  group_by(country) %>%
  summarize(start_gdp = first(gdp),
            end_gdp = last(gdp),
            growth_rate = (last(gdp) - first(gdp)) / first(gdp) * 100,
            .groups = 'drop') %>%
  arrange(desc(growth_rate))

# Identify the top 5 slowest growing economies
top_5_slowest_countries <- tail(growth_rates, 5)$country

# Filter the data to only include these countries and calculate percentage change
top_5_slowest_data <- african_gdp_data %>%
  filter(country %in% top_5_slowest_countries) %>%
  arrange(country, year) %>%
  mutate(perc_change = (gdp - lag(gdp)) / lag(gdp) * 100)

# Create the ggplot with hover text information
top_5_slowest_plot <- ggplot(top_5_slowest_data, aes(x = year, y = gdp, group = country, color = country,
                                                     text = paste("Year: ", year, 
                                                                  "<br>GDP: ", dollar(gdp, accuracy = 1),
                                                                  "<br>Annual Growth: ", round(perc_change, 2), "%"))) +
  geom_line() +
  geom_point() +
  theme_minimal() +
  labs(title = "Top 5 Slowest Growing Economies Over Time", x = "Year", y = "GDP (in USD)")

# Convert the ggplot object to plotly for interactivity
top_5_slowest_plotly <- ggplotly(top_5_slowest_plot, tooltip = "text")

# Print the interactive plot
top_5_slowest_plotly

Florish bar chat of Liberia ranking and rankings of the top 10 African

The Flourish visualization presents an animated bar chart race showcasing the GDP rankings of multiple countries over time. As the animation progresses, viewers can observe how the positions of different countries change relative to each other in terms of GDP ranking. The height of each bar represents the GDP value, and the bars move horizontally to reflect changes in ranking over time. In the context of the research question regarding the changes in GDP rankings of African countries over time, this visualization provides valuable insights into the comparative economic progress of these nations. It allows viewers to identify which countries have experienced improvements or declines in their GDP rankings over time and assess the relative economic competitiveness of different African economies.

The Flourish visualization presents an animated bar chart race comparing Liberia’s GDP ranking with that of 20 other African countries over time. Each bar represents the GDP ranking of a specific country, with Liberia’s position highlighted for comparison. As the animation progresses, viewers can observe the movement of the bars to see how Liberia’s GDP ranking fluctuates relative to other African nations. This visualization offers a dynamic way to analyze Liberia’s economic performance in comparison to its peers within the African continent. By tracking Liberia’s position in the GDP ranking over time, viewers can assess whether the country has experienced improvements, declines, or stability in its economic standing relative to other African countries.


References

  1. Wickham, H. (2016). ggplot2: Elegant Graphics for Data Analysis. Springer-Verlag New York. ISBN 978-3-319-24277-4.

  2. Kaggle. (n.d.). Gross Domestic Product (GDP) by Country 1960-2020. Retrieved from https://www.kaggle.com/World Bank Data/gdp-ranking.

  3. Class Lesson on Information Design & Visual Analytics.

  4. OpenAI. (2022). ChatGPT. https://openai.com/gpt

  5. Flourish Studio. (n.d.). Data Visualization Platform. Retrieved from https://flourish.studio/.


All done!

LS0tCnRpdGxlOiAiVmlzdWFsaXppbmcgRWNvbm9taWMgQ2hhbmdlOiBHRFAgVHJlbmRzIGFuZCBSYW5raW5ncyBBY3Jvc3MgQWZyaWNhbiBDb3VudHJpZXMgKDE5NjDigJMyMDIwKSIKc3VidGl0bGU6ICJJbmZvcm1hdGlvbiBEZXNpZ24gJiBWaXN1YWwgQW5hbHl0aWNzIgphdXRob3I6ICJFdHRhIEJyb29rcyIKZGF0ZTogIkFwciA3LCAyMDI1IgpvdXRwdXQ6CiAgaHRtbF9kb2N1bWVudDoKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKICAgIGZpZ19jYXB0aW9uOiB5ZXMKICAgIHRoZW1lOiBsdW1lbgogICAgdG9jOiB5ZXMKICAgIHRvY19kZXB0aDogMgogICAgZGZfcHJpbnQ6IGthYmxlCiAgICB0b2NfZmxvYXQ6CiAgICAgIGNvbGxhcHNlZDogbm8KLS0tCgpgYGB7ciwgbWVzc2FnZT1GQUxTRX0KIyBQYWNrYWdlcwpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShtb3NhaWMpCmBgYAoKCiMjIFJlc2VhcmNoIFF1ZXN0aW9uCgo+IEhvdyBoYXZlIHRoZSBHRFAgcmFua2luZ3Mgb2YgQWZyaWNhbiBjb3VudHJpZXMgY2hhbmdlZCBvdmVyIHRpbWU/IEFuZCB3aGF0IGhhcyBiZWVuIHRoZSByYXRlIG9mIGNoYW5nZSBpbiBMaWJlcmlh4oCZcyBHRFAgb3ZlciB0aW1lPwoKKiAqICoKCiMgRGF0YQoKPiBUaGlzIGRhdGFzZXQgZmVhdHVyZXMgR3Jvc3MgRG9tZXN0aWMgUHJvZHVjdCAoR0RQKSBkYXRhIGZyb20gMTk2MCB0byAyMDIwIGZvciB2YXJpb3VzIGNvdW50cmllcyBhbmQgcmVnaW9ucywgaGlnaGxpZ2h0aW5nIGVjb25vbWljIHRyZW5kcyBhbmQgZ3Jvd3RoLiBBcyBhIGtleSBlY29ub21pYyBpbmRpY2F0b3IsIEdEUCBtZWFzdXJlcyB0aGUgdG90YWwgdmFsdWUgb2YgZ29vZHMgYW5kIHNlcnZpY2VzIHByb2R1Y2VkLCByZWZsZWN0aW5nIHRoZSBlY29ub21pYyBoZWFsdGggb2YgYSBuYXRpb24gb3IgcmVnaW9uLiBBdmFpbGFibGUgb24gS2FnZ2xlLCB0aGlzIGRhdGFzZXQgc3VwcG9ydHMgZGF0YSBzY2llbmNlIHByb2plY3RzIGFuZCBlbmNvdXJhZ2VzIGNvbW11bml0eSBlbmdhZ2VtZW50IHRocm91Z2ggc2hhcmluZyBpbnNpZ2h0cyBhbmQgbWV0aG9kb2xvZ2llcy4KCiMjIExvYWQgZGF0YSBpbnRvIFIKCmBgYHtyLCBtZXNzYWdlID0gRkFMU0UsIHdhcm5pbmcgPSBGQUxTRX0KZ2RwXzE5NjBfMjAyMCA8LSByZWFkX2NzdigiZ2RwXzE5NjBfMjAyMC5jc3YiKQpoZWFkKGdkcF8xOTYwXzIwMjApCmBgYAoKKiAqICoKCiMgVmFyaWFibGVzCgpgYGB7ciwgbWVzc2FnZSA9IEZBTFNFLCB3YXJuaW5nID0gRkFMU0V9Cm5hbWVzKGdkcF8xOTYwXzIwMjApCmBgYAoKVGhlIHZhcmlhYmxlcyBJIHVzZWQgaW4gbXkgZGF0YSB2aXN1YWxpemF0aW9uIGFyZToKCj5ZZWFyLCBjb3VudHJ5LCBnZHAsIHN0YXRlLCAmIGdkcF9wZXJjZW50CgoqICogKgoKCiMgRGF0YSBBbmFseXNpcwoKYGBge3J9CiMgRmlsdGVyIGRhdGEgZm9yIEFmcmljYW4gY291bnRyaWVzIG9ubHkKYWZyaWNhbl9nZHBfZGF0YSA8LSBmaWx0ZXIoZ2RwXzE5NjBfMjAyMCwgc3RhdGUgPT0gIkFmcmljYSIpCmhlYWQoYWZyaWNhbl9nZHBfZGF0YSkKYGBgCgoKCgoKIyMgU3VtbWFyeSBTdGF0aXN0aWNzCgpgYGB7ciwgbWVzc2FnZSA9IEZBTFNFLCB3YXJuaW5nID0gRkFMU0V9CiMgQ2FsY3VsYXRlIHN1bW1hcnkgc3RhdGlzdGljcyBmb3IgR0RQCnN1bW1hcnlfc3RhdHMgPC0gZmF2c3RhdHMofiBnZHAsIGRhdGEgPSBhZnJpY2FuX2dkcF9kYXRhKQpzdW1tYXJ5X3N0YXRzCgpgYGAKCiogKiAqCgoKIyMgSW50ZXJhY3RpdmUgUHJlc2VudGF0aW9uIAoKPiBUaGlzIHZpc3VhbGl6YXRpb24gdHJhY2VzIHRoZSBHRFAgZ3Jvd3RoIG9mIGVhY2ggQWZyaWNhbiBjb3VudHJ5IGZyb20gMTk2MCB0byAyMDIwLiBJdCBhbGxvd3Mgdmlld2VycyB0byBvYnNlcnZlIHRyZW5kcyBpbiBlY29ub21pYyBkZXZlbG9wbWVudCwgaWRlbnRpZnkgcGVyaW9kcyBvZiByYXBpZCBncm93dGggb3IgZGVjbGluZSwgYW5kIGNvbXBhcmUgdGhlIHRyYWplY3RvcmllcyBvZiBkaWZmZXJlbnQgY291bnRyaWVzLiBCeSBleGFtaW5pbmcgdGhlIGVudGlyZSBjb250aW5lbnQsIHdlIGNhbiBzZWUgd2hpY2ggY291bnRyaWVzIGhhdmUgZXhwZXJpZW5jZWQgc2lnbmlmaWNhbnQgZWNvbm9taWMgYWR2YW5jZW1lbnRzIGFuZCBzdGFydCB0byB0aGluayBhYm91dCBob3cgZXh0ZXJuYWwgZmFjdG9ycyBsaWtlIGdsb2JhbCBvaWwgcHJpY2VzIG9yIHJlZ2lvbmFsIGNvbmZsaWN0cyBoYXZlIGltcGFjdGVkIGVjb25vbWllcy4KCmBgYHtyfQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkocGxvdGx5KQoKIyBDb252ZXJ0IGZhY3RvcnMgdG8gZW5zdXJlIGdyb3VwaW5nIHdvcmtzIGNvcnJlY3RseQphZnJpY2FuX2dkcF9kYXRhJGNvdW50cnkgPC0gYXMuZmFjdG9yKGFmcmljYW5fZ2RwX2RhdGEkY291bnRyeSkKCnAgPC0gZ2dwbG90KGFmcmljYW5fZ2RwX2RhdGEsIGFlcyh4ID0geWVhciwgeSA9IGdkcCwgY29sb3IgPSBjb3VudHJ5LCBncm91cCA9IGNvdW50cnksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4dCA9IHBhc3RlKCJDb3VudHJ5OiIsIGNvdW50cnksICI8YnI+R0RQOiIsIGdkcCkpKSArIAogICAgZ2VvbV9saW5lKCkgKyAKICAgIHRoZW1lX21pbmltYWwoKSArIAogICAgbGFicyh0aXRsZSA9ICJHRFAgR3Jvd3RoIE92ZXIgVGltZSBmb3IgQWxsIEFmcmljYW4gQ291bnRyaWVzIiwgCiAgICAgICAgIHggPSAiWWVhciIsIAogICAgICAgICB5ID0gIkdEUCIpCgojIENvbnZlcnQgdG8gYSBwbG90bHkgb2JqZWN0CmdncGxvdGx5KHAsIHRvb2x0aXAgPSAidGV4dCIpCgpgYGAKCgoKCgoKIyMjI1RvcCBhbmQgQm90dG9tIFBlcmZvcm1lcnMgaW4gR0RQIEdyb3d0aAoKPiBQcm92aWRlIGEgc3VtbWFyeSBvZiB3aGF0IHRoaXMgdmlzdWFsaXphdGlvbiBzaG93cyBhbmQgaG93IGl0IGhlbHBzIHRvIGFuc3dlciB5b3VyIHJlc2VhcmNoIHF1ZXN0aW9uLiAKCj5UaGUgdmlzdWFsaXphdGlvbiBzaG93Y2FzZXMgdGhlIHRvcCBhbmQgYm90dG9tIDUgR0RQIHBlcmZvcm1lcnMgYW1vbmcgQWZyaWNhbiBjb3VudHJpZXMgaW4gdGhlIHllYXIgMjAyMC4gSSBjaG9zZSAyMDIyIGJlY2F1c2UgaXQgaXMgdGhlIGZpbmFsIHllYXIgZGF0YSBhcmUgYXZhaWxhYmxlIHRvIGRhdGUuIEVhY2ggYmFyIGluIHRoZSBwbG90IHJlcHJlc2VudHMgYSBjb3VudHJ5LCB3aXRoIHRoZSBoZWlnaHQgb2YgdGhlIGJhciBpbmRpY2F0aW5nIGl0cyBHRFAgdmFsdWUuIFRoZSBjb2xvciBncmFkaWVudCBhcHBsaWVkIHRvIHRoZSBiYXJzIHByb3ZpZGVzIHZpc3VhbCBlbXBoYXNpcywgd2l0aCBkYXJrZXIgc2hhZGVzIGluZGljYXRpbmcgaGlnaGVyIEdEUCB2YWx1ZXMuIFRoaXMgdmlzdWFsaXphdGlvbiBoZWxwcyBhbnN3ZXIgdGhlIHJlc2VhcmNoIHF1ZXN0aW9uIGJ5IGlsbHVzdHJhdGluZyB0aGUgZWNvbm9taWMgZGlzcGFyaXRpZXMgYW1vbmcgQWZyaWNhbiBjb3VudHJpZXMgaW4gdGVybXMgb2YgR0RQIHBlcmZvcm1hbmNlLiBCeSBpZGVudGlmeWluZyBib3RoIHRoZSB0b3AgYW5kIGJvdHRvbSBwZXJmb3JtZXJzLCB2aWV3ZXJzIGNhbiBnYWluIGluc2lnaHRzIGludG8gdGhlIGVjb25vbWljIGR5bmFtaWNzIHdpdGhpbiB0aGUgY29udGluZW50LiBVbmRlcnN0YW5kaW5nIHdoaWNoIGNvdW50cmllcyBoYXZlIHRoZSBoaWdoZXN0IGFuZCBsb3dlc3QgR0RQIHZhbHVlcyBpbiAyMDIwIGNvbnRyaWJ1dGVzIHRvIGEgYnJvYWRlciB1bmRlcnN0YW5kaW5nIG9mIGhvdyBlY29ub21pYyByZXNvdXJjZXMgYXJlIGRpc3RyaWJ1dGVkIGFjcm9zcyBBZnJpY2FuIG5hdGlvbnMgYW5kIHByb3ZpZGVzIGNvbnRleHQgZm9yIGFuYWx5emluZyB0cmVuZHMgaW4gR0RQIHJhbmtpbmdzIG92ZXIgdGltZS4KCgpgYGB7cn0KbGlicmFyeShkcGx5cikKbGlicmFyeShzY2FsZXMpCgoKIyBEZWZpbmUgdGhlIGNvbG9yIGdyYWRpZW50IGZ1bmN0aW9uCmdldF9ncmFkaWVudF9jb2xvciA8LSBmdW5jdGlvbihyYW5rLCB0b3RhbCkgewogIGdyRGV2aWNlczo6Y29sb3JSYW1wUGFsZXR0ZShjKCJibHVlIiwgImxpZ2h0Ymx1ZSIpKSh0b3RhbClbcmFua10KfQoKIyBGaWx0ZXIgZm9yIHRoZSB0b3AgNSBHRFAgcGVyZm9ybWVycyBpbiAyMDIwCnRvcF8yMDIwIDwtIGFmcmljYW5fZ2RwX2RhdGEgJT4lCiAgZmlsdGVyKHllYXIgPT0gMjAyMCkgJT4lCiAgYXJyYW5nZShkZXNjKGdkcCkpICU+JQogIHNsaWNlKDE6NSkKCiMgQWRkIGEgY29sb3IgZ3JhZGllbnQgYmFzZWQgb24gcmFuawp0b3BfMjAyMCRjb2xvciA8LSBnZXRfZ3JhZGllbnRfY29sb3IoMTpucm93KHRvcF8yMDIwKSwgbnJvdyh0b3BfMjAyMCkpCgojIEZpbHRlciBmb3IgdGhlIGJvdHRvbSA1IEdEUCBwZXJmb3JtZXJzIGluIDIwMjAKYm90dG9tXzIwMjAgPC0gYWZyaWNhbl9nZHBfZGF0YSAlPiUKICBmaWx0ZXIoeWVhciA9PSAyMDIwKSAlPiUKICBhcnJhbmdlKGRlc2MoZ2RwKSkgJT4lCiAgc2xpY2UoKG4oKS00KTpuKCkpCgojIEFkZCBhIGNvbG9yIGdyYWRpZW50IGJhc2VkIG9uIHJhbmsKYm90dG9tXzIwMjAkY29sb3IgPC0gZ2V0X2dyYWRpZW50X2NvbG9yKDE6bnJvdyhib3R0b21fMjAyMCksIG5yb3coYm90dG9tXzIwMjApKQoKIyBQbG90IGZvciB0b3AgNSBwZXJmb3JtZXJzCnRvcF9wbG90IDwtIGdncGxvdCh0b3BfMjAyMCwgYWVzKHggPSByZW9yZGVyKGNvdW50cnksIGdkcCksIHkgPSBnZHAsIGZpbGwgPSBjb2xvcikpICsgCiAgZ2VvbV9jb2woc2hvdy5sZWdlbmQgPSBGQUxTRSkgKyAKICBnZW9tX3RleHQoYWVzKGxhYmVsID0gc2NhbGVzOjpjb21tYShnZHApKSwgaGp1c3QgPSAxLjEsIHNpemUgPSAzLjUpICsKICBjb29yZF9mbGlwKCkgKyAKICB0aGVtZV9taW5pbWFsKCkgKyAKICBsYWJzKHRpdGxlID0gIlRvcCA1IEdEUCBQZXJmb3JtZXJzIGluIDIwMjAiLCAKICAgICAgIHggPSAiIiwgCiAgICAgICB5ID0gIkdEUCIpCgojIFBsb3QgZm9yIGJvdHRvbSA1IHBlcmZvcm1lcnMKYm90dG9tX3Bsb3QgPC0gZ2dwbG90KGJvdHRvbV8yMDIwLCBhZXMoeCA9IHJlb3JkZXIoY291bnRyeSwgZ2RwKSwgeSA9IGdkcCwgZmlsbCA9IGNvbG9yKSkgKyAKICBnZW9tX2NvbChzaG93LmxlZ2VuZCA9IEZBTFNFKSArIAogIGdlb21fdGV4dChhZXMobGFiZWwgPSBzY2FsZXM6OmNvbW1hKGdkcCkpLCBoanVzdCA9IDEuMSwgc2l6ZSA9IDMuNSkgKwogIGNvb3JkX2ZsaXAoKSArIAogIHRoZW1lX21pbmltYWwoKSArIAogIGxhYnModGl0bGUgPSAiQm90dG9tIDUgR0RQIFBlcmZvcm1lcnMgaW4gMjAyMCIsIAogICAgICAgeCA9ICIiLCAKICAgICAgIHkgPSAiR0RQIikKCiMgUHJpbnQgdGhlIHBsb3RzCnByaW50KHRvcF9wbG90KQpwcmludChib3R0b21fcGxvdCkKCmBgYAoKCgoKCiMjIyMgV2Vic2l0ZSBQYWdlIDM6IEFmcmljYSBGYXN0ZXN0IEdyb3dpbmcgR0RQIGFzIHdlbGwgYXMgY291bnRyaWVzIHdpdGggdGhlIHNsb3dlc3QgZ3Jvd2luZyBlY29ub215Cgo+VGhlIGNvZGUgZ2VuZXJhdGVzIHR3byB2aXN1YWxpemF0aW9uczogb25lIHNob3dpbmcgdGhlIHRvcCA1IGZhc3Rlc3QtZ3Jvd2luZyBlY29ub21pZXMgb3ZlciB0aW1lIGFuZCB0aGUgb3RoZXIgZGlzcGxheWluZyB0aGUgdG9wIDUgc2xvd2VzdC1ncm93aW5nIGVjb25vbWllcy4gRWFjaCBsaW5lIHJlcHJlc2VudHMgYSBjb3VudHJ5J3MgR0RQIHRyZW5kLCB3aXRoIGNvbG9yIGluZGljYXRpbmcgdGhlIGNvdW50cnkuIFVzZXJzIGNhbiBob3ZlciBvdmVyIGxpbmVzIGZvciBkZXRhaWxlZCBHRFAsIHllYXIsIGFuZCBncm93dGggcmF0ZSBpbmZvcm1hdGlvbi4gVGhlc2UgdmlzdWFsaXphdGlvbnMgZGlyZWN0bHkgYWRkcmVzcyB0aGUgcmVzZWFyY2ggcXVlc3Rpb24gYnkgcHJvdmlkaW5nIGluc2lnaHRzIGludG8gQWZyaWNhbiBjb3VudHJpZXMnIEdEUCBncm93dGggcmF0ZXMgb3ZlciB0aW1lLCBhbGxvd2luZyB1c2VycyB0byBpZGVudGlmeSB0cmVuZHMgYW5kIGRpc3Bhcml0aWVzIGluIGVjb25vbWljIGRldmVsb3BtZW50LgoKYGBge3J9CiMgQ2FsY3VsYXRlIHRoZSBncm93dGggcmF0ZSBmb3IgZWFjaCBjb3VudHJ5Cmdyb3d0aF9yYXRlcyA8LSBhZnJpY2FuX2dkcF9kYXRhICU+JQogIGdyb3VwX2J5KGNvdW50cnkpICU+JQogIHN1bW1hcml6ZShzdGFydF9nZHAgPSBmaXJzdChnZHApLAogICAgICAgICAgICBlbmRfZ2RwID0gbGFzdChnZHApLAogICAgICAgICAgICBncm93dGhfcmF0ZSA9IChsYXN0KGdkcCkgLSBmaXJzdChnZHApKSAvIGZpcnN0KGdkcCkgKiAxMDAsCiAgICAgICAgICAgIC5ncm91cHMgPSAnZHJvcCcpICU+JQogIGFycmFuZ2UoZGVzYyhncm93dGhfcmF0ZSkpCgojIElkZW50aWZ5IHRoZSAgdG9wIDUgZmFzdGVzdCBncm93aW5nIGVjb25vbWllcwp0b3BfNV9jb3VudHJpZXMgPC0gaGVhZChncm93dGhfcmF0ZXMsIDUpJGNvdW50cnkKCiMgRmlsdGVyIHRoZSBkYXRhIHRvIG9ubHkgaW5jbHVkZSB0aGUgdG9wIDUgZmFzdGVzdCBncm93aW5nIGNvdW50cmllcyBhbmQgY2FsY3VsYXRlIHBlcmNlbnRhZ2UgY2hhbmdlIGZvciBlYWNoIHllYXIKdG9wXzVfZGF0YSA8LSBhZnJpY2FuX2dkcF9kYXRhICU+JQogIGZpbHRlcihjb3VudHJ5ICVpbiUgdG9wXzVfY291bnRyaWVzKSAlPiUKICBhcnJhbmdlKGNvdW50cnksIHllYXIpICU+JQogIGdyb3VwX2J5KGNvdW50cnkpICU+JQogIG11dGF0ZShwZXJjZW50YWdlX2NoYW5nZSA9IChnZHAgLSBsYWcoZ2RwKSkgLyBsYWcoZ2RwKSAqIDEwMCkgJT4lCiAgdW5ncm91cCgpCgojIENyZWF0ZSB0aGUgZ2dwbG90IHdpdGggdGhlIHRleHQgYWVzdGhldGljIGZvciBob3ZlciBpbmZvcm1hdGlvbgp0b3BfNV9wbG90IDwtIGdncGxvdCh0b3BfNV9kYXRhLCBhZXMoeCA9IHllYXIsIHkgPSBnZHAsIGdyb3VwID0gY291bnRyeSwgY29sb3IgPSBjb3VudHJ5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGV4dCA9IHBhc3RlKCJDb3VudHJ5OiIsIGNvdW50cnksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjxicj5ZZWFyOiIsIHllYXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjxicj5HRFA6IiwgZG9sbGFyKGdkcCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIjxicj5Bbm51YWwgR3Jvd3RoOiIsIHJvdW5kKHBlcmNlbnRhZ2VfY2hhbmdlLCAyKSwgIiUiKSkpICsKICBnZW9tX2xpbmUoKSArCiAgZ2VvbV9wb2ludCgpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gc2NhbGVzOjpkb2xsYXJfZm9ybWF0KHByZWZpeCA9ICIkIiwgc3VmZml4ID0gIiIsIGJpZy5tYXJrID0gIiwiLCBkZWNpbWFsLm1hcmsgPSAiLiIsIGFjY3VyYWN5ID0gMSkpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIGxhYnModGl0bGUgPSAiVG9wIDUgRmFzdGVzdCBHcm93aW5nIEVjb25vbWllcyBPdmVyIFRpbWUiLCB4ID0gIlllYXIiLCB5ID0gIkdEUCAoaW4gVVNEKSIsIGNhcHRpb24gPSAiRGF0YSBzb3VyY2U6IFlvdXIgU291cmNlIikKCiMgQ29udmVydCB0aGUgZ2dwbG90IG9iamVjdCB0byBwbG90bHkgZm9yIGludGVyYWN0aXZpdHkKdG9wXzVfcGxvdGx5IDwtIGdncGxvdGx5KHRvcF81X3Bsb3QsIHRvb2x0aXAgPSAidGV4dCIpCgojIFByaW50IHRoZSBpbnRlcmFjdGl2ZSBwbG90CnRvcF81X3Bsb3RseQoKYGBgCgoKCgpgYGB7cn0KIyBDYWxjdWxhdGUgdGhlIGdyb3d0aCByYXRlIGZvciBlYWNoIGNvdW50cnkKZ3Jvd3RoX3JhdGVzIDwtIGFmcmljYW5fZ2RwX2RhdGEgJT4lCiAgZ3JvdXBfYnkoY291bnRyeSkgJT4lCiAgc3VtbWFyaXplKHN0YXJ0X2dkcCA9IGZpcnN0KGdkcCksCiAgICAgICAgICAgIGVuZF9nZHAgPSBsYXN0KGdkcCksCiAgICAgICAgICAgIGdyb3d0aF9yYXRlID0gKGxhc3QoZ2RwKSAtIGZpcnN0KGdkcCkpIC8gZmlyc3QoZ2RwKSAqIDEwMCwKICAgICAgICAgICAgLmdyb3VwcyA9ICdkcm9wJykgJT4lCiAgYXJyYW5nZShkZXNjKGdyb3d0aF9yYXRlKSkKCiMgSWRlbnRpZnkgdGhlIHRvcCA1IHNsb3dlc3QgZ3Jvd2luZyBlY29ub21pZXMKdG9wXzVfc2xvd2VzdF9jb3VudHJpZXMgPC0gdGFpbChncm93dGhfcmF0ZXMsIDUpJGNvdW50cnkKCiMgRmlsdGVyIHRoZSBkYXRhIHRvIG9ubHkgaW5jbHVkZSB0aGVzZSBjb3VudHJpZXMgYW5kIGNhbGN1bGF0ZSBwZXJjZW50YWdlIGNoYW5nZQp0b3BfNV9zbG93ZXN0X2RhdGEgPC0gYWZyaWNhbl9nZHBfZGF0YSAlPiUKICBmaWx0ZXIoY291bnRyeSAlaW4lIHRvcF81X3Nsb3dlc3RfY291bnRyaWVzKSAlPiUKICBhcnJhbmdlKGNvdW50cnksIHllYXIpICU+JQogIG11dGF0ZShwZXJjX2NoYW5nZSA9IChnZHAgLSBsYWcoZ2RwKSkgLyBsYWcoZ2RwKSAqIDEwMCkKCiMgQ3JlYXRlIHRoZSBnZ3Bsb3Qgd2l0aCBob3ZlciB0ZXh0IGluZm9ybWF0aW9uCnRvcF81X3Nsb3dlc3RfcGxvdCA8LSBnZ3Bsb3QodG9wXzVfc2xvd2VzdF9kYXRhLCBhZXMoeCA9IHllYXIsIHkgPSBnZHAsIGdyb3VwID0gY291bnRyeSwgY29sb3IgPSBjb3VudHJ5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRleHQgPSBwYXN0ZSgiWWVhcjogIiwgeWVhciwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICI8YnI+R0RQOiAiLCBkb2xsYXIoZ2RwLCBhY2N1cmFjeSA9IDEpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiPGJyPkFubnVhbCBHcm93dGg6ICIsIHJvdW5kKHBlcmNfY2hhbmdlLCAyKSwgIiUiKSkpICsKICBnZW9tX2xpbmUoKSArCiAgZ2VvbV9wb2ludCgpICsKICB0aGVtZV9taW5pbWFsKCkgKwogIGxhYnModGl0bGUgPSAiVG9wIDUgU2xvd2VzdCBHcm93aW5nIEVjb25vbWllcyBPdmVyIFRpbWUiLCB4ID0gIlllYXIiLCB5ID0gIkdEUCAoaW4gVVNEKSIpCgojIENvbnZlcnQgdGhlIGdncGxvdCBvYmplY3QgdG8gcGxvdGx5IGZvciBpbnRlcmFjdGl2aXR5CnRvcF81X3Nsb3dlc3RfcGxvdGx5IDwtIGdncGxvdGx5KHRvcF81X3Nsb3dlc3RfcGxvdCwgdG9vbHRpcCA9ICJ0ZXh0IikKCiMgUHJpbnQgdGhlIGludGVyYWN0aXZlIHBsb3QKdG9wXzVfc2xvd2VzdF9wbG90bHkKCmBgYAoKCgoKCgoKCgojIyMjIExpYmVyaWEgR0RQIHRyZW5kcyBvdmVyIHRpbWUKCj5UaGlzIHZpc3VhbGl6YXRpb24gaWxsdXN0cmF0ZXMgdGhlIEdEUCB0cmVuZHMgb2YgTGliZXJpYSBvdmVyIHRpbWUsIHNob3djYXNpbmcgaG93IGl0cyBlY29ub21pYyBwZXJmb3JtYW5jZSBoYXMgZXZvbHZlZC4gVGhlIGxpbmUgcGxvdCBkZXBpY3RzIExpYmVyaWEncyBHRFAgdHJhamVjdG9yeSBhY3Jvc3MgZGlmZmVyZW50IHllYXJzLCBoaWdobGlnaHRpbmcgZmx1Y3R1YXRpb25zIGFuZCBvdmVyYWxsIHRyZW5kcyBpbiBlY29ub21pYyBncm93dGguIEJ5IGludGVyYWN0aW5nIHdpdGggdGhlIHBsb3QsIHVzZXJzIGNhbiBob3ZlciBvdmVyIGRhdGEgcG9pbnRzIHRvIHZpZXcgc3BlY2lmaWMgZGV0YWlscyBzdWNoIGFzIEdEUCB2YWx1ZXMsIGNvcnJlc3BvbmRpbmcgeWVhcnMsIGFuZCB0aGUgcGVyY2VudGFnZSBjaGFuZ2UgaW4gR0RQIGZyb20gdGhlIHByZXZpb3VzIHllYXIuIEluIHRoZSBjb250ZXh0IG9mIHRoZSByZXNlYXJjaCBxdWVzdGlvbiwgd2hpY2ggcGVydGFpbnMgdG8gdW5kZXJzdGFuZGluZyB0aGUgY2hhbmdlcyBpbiBHRFAgcmFua2luZ3Mgb2YgQWZyaWNhbiBjb3VudHJpZXMgb3ZlciB0aW1lLCB0aGlzIHZpc3VhbGl6YXRpb24gY29udHJpYnV0ZXMgYnkgcHJvdmlkaW5nIGEgZm9jdXNlZCBhbmFseXNpcyBvZiBMaWJlcmlhJ3MgZWNvbm9taWMgcGVyZm9ybWFuY2UuIEJ5IGV4YW1pbmluZyBMaWJlcmlhJ3MgR0RQIHRyZW5kcywgcG9saWN5bWFrZXJzLCBlY29ub21pc3RzLCBhbmQgcmVzZWFyY2hlcnMgY2FuIGdhaW4gaW5zaWdodHMgaW50byB0aGUgY291bnRyeSdzIGVjb25vbWljIGRldmVsb3BtZW50IHRyYWplY3RvcnksIGlkZW50aWZ5IHBlcmlvZHMgb2YgZ3Jvd3RoIG9yIGRlY2xpbmUsIGFuZCBhc3Nlc3MgdGhlIGZhY3RvcnMgaW5mbHVlbmNpbmcgaXRzIEdEUCBmbHVjdHVhdGlvbnMuIFRoaXMgdW5kZXJzdGFuZGluZyBvZiBMaWJlcmlhJ3MgZWNvbm9taWMgZHluYW1pY3MgY29udHJpYnV0ZXMgdG8gYSBicm9hZGVyIGNvbXByZWhlbnNpb24gb2YgdGhlIG92ZXJhbGwgZWNvbm9taWMgbGFuZHNjYXBlIGluIEFmcmljYSBhbmQgYWlkcyBpbiBpZGVudGlmeWluZyBwYXR0ZXJucyBhbmQgdHJlbmRzIHRoYXQgbWF5IGluZm9ybSBmdXR1cmUgcG9saWN5IGRlY2lzaW9ucyBhbmQgcmVzZWFyY2ggZGlyZWN0aW9ucwoKYGBge3J9CiMgRmlsdGVyIHRoZSBkYXRhIGZvciBMaWJlcmlhIGFuZCBjYWxjdWxhdGUgcGVyY2VudGFnZSBjaGFuZ2UKbGliZXJpYV9nZHAgPC0gYWZyaWNhbl9nZHBfZGF0YSAlPiUgCiAgZmlsdGVyKGNvdW50cnkgPT0gIkxpYmVyaWEiKSAlPiUKICBhcnJhbmdlKHllYXIpICU+JQogIG11dGF0ZShwZXJjX2NoYW5nZSA9IChnZHAgLSBsYWcoZ2RwKSkgLyBsYWcoZ2RwKSAqIDEwMCkKCiMgQ3JlYXRlIHRoZSBnZ3Bsb3QKZ2RwX3Bsb3QgPC0gZ2dwbG90KGxpYmVyaWFfZ2RwLCBhZXMoeCA9IHllYXIsIHkgPSBnZHApKSArCiAgZ2VvbV9saW5lKCkgKyAKICBnZW9tX3BvaW50KCkgKwogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OmRvbGxhcl9mb3JtYXQocHJlZml4ID0gIiQiLCBzdWZmaXggPSAiIiwgYmlnLm1hcmsgPSAiLCIsIGRlY2ltYWwubWFyayA9ICIuIiwgYWNjdXJhY3kgPSAxKSkgKwogIHRoZW1lX21pbmltYWwoKSArCiAgbGFicyh0aXRsZSA9ICJHRFAgb2YgTGliZXJpYSBPdmVyIFRpbWUiLCB4ID0gIlllYXIiLCB5ID0gIkdEUCAoaW4gVVNEKSIsIGNhcHRpb24gPSAiRGF0YSBzb3VyY2U6IFlvdXIgU291cmNlIikKCiMgQ29udmVydCB0byBhIHBsb3RseSBvYmplY3Qgd2l0aCBjdXN0b20gaG92ZXIgdGV4dApnZHBfcGxvdGx5IDwtIGdncGxvdGx5KGdkcF9wbG90KSAlPiUKICBsYXlvdXQoaG92ZXJtb2RlID0gJ2Nsb3Nlc3QnKSAlPiUKICBhZGRfdHJhY2UoCiAgICBkYXRhID0gbGliZXJpYV9nZHAsIAogICAgdHlwZSA9ICdzY2F0dGVyJywgCiAgICBtb2RlID0gJ21hcmtlcnMnLAogICAgeCA9IH55ZWFyLCAKICAgIHkgPSB+Z2RwLAogICAgdGV4dCA9IH5wYXN0ZSgiWWVhcjogIiwgeWVhciwgIjxicj5HRFA6ICIsIHNjYWxlczo6ZG9sbGFyKGdkcCwgcHJlZml4ID0gIiQiLCBzdWZmaXggPSAiIiwgYmlnLm1hcmsgPSAiLCIsIGRlY2ltYWwubWFyayA9ICIuIiwgYWNjdXJhY3kgPSAxKSwgIjxicj4lIENoYW5nZTogIiwgcm91bmQocGVyY19jaGFuZ2UsIDIpLCAiJSIpLAogICAgaG92ZXJpbmZvID0gJ3RleHQnCiAgKQoKIyBQcmludCB0aGUgaW50ZXJhY3RpdmUgcGxvdApnZHBfcGxvdGx5CgpgYGAKCgoKCgoKIyMjIyBGbG9yaXNoIGJhciBjaGF0IG9mIExpYmVyaWEgcmFua2luZyBhbmQgcmFua2luZ3Mgb2YgdGhlIHRvcCAxMCAgQWZyaWNhbgoKPiBUaGUgRmxvdXJpc2ggdmlzdWFsaXphdGlvbiBwcmVzZW50cyBhbiBhbmltYXRlZCBiYXIgY2hhcnQgcmFjZSBzaG93Y2FzaW5nIHRoZSBHRFAgcmFua2luZ3Mgb2YgbXVsdGlwbGUgY291bnRyaWVzIG92ZXIgdGltZS4gQXMgdGhlIGFuaW1hdGlvbiBwcm9ncmVzc2VzLCB2aWV3ZXJzIGNhbiBvYnNlcnZlIGhvdyB0aGUgcG9zaXRpb25zIG9mIGRpZmZlcmVudCBjb3VudHJpZXMgY2hhbmdlIHJlbGF0aXZlIHRvIGVhY2ggb3RoZXIgaW4gdGVybXMgb2YgR0RQIHJhbmtpbmcuIFRoZSBoZWlnaHQgb2YgZWFjaCBiYXIgcmVwcmVzZW50cyB0aGUgR0RQIHZhbHVlLCBhbmQgdGhlIGJhcnMgbW92ZSBob3Jpem9udGFsbHkgdG8gcmVmbGVjdCBjaGFuZ2VzIGluIHJhbmtpbmcgb3ZlciB0aW1lLiBJbiB0aGUgY29udGV4dCBvZiB0aGUgcmVzZWFyY2ggcXVlc3Rpb24gcmVnYXJkaW5nIHRoZSBjaGFuZ2VzIGluIEdEUCByYW5raW5ncyBvZiBBZnJpY2FuIGNvdW50cmllcyBvdmVyIHRpbWUsIHRoaXMgdmlzdWFsaXphdGlvbiBwcm92aWRlcyB2YWx1YWJsZSBpbnNpZ2h0cyBpbnRvIHRoZSBjb21wYXJhdGl2ZSBlY29ub21pYyBwcm9ncmVzcyBvZiB0aGVzZSBuYXRpb25zLiBJdCBhbGxvd3Mgdmlld2VycyB0byBpZGVudGlmeSB3aGljaCBjb3VudHJpZXMgaGF2ZSBleHBlcmllbmNlZCBpbXByb3ZlbWVudHMgb3IgZGVjbGluZXMgaW4gdGhlaXIgR0RQIHJhbmtpbmdzIG92ZXIgdGltZSBhbmQgYXNzZXNzIHRoZSByZWxhdGl2ZSBlY29ub21pYyBjb21wZXRpdGl2ZW5lc3Mgb2YgZGlmZmVyZW50IEFmcmljYW4gZWNvbm9taWVzLiAgIAoKCjxpZnJhbWUgc3JjPSJodHRwczovL3B1YmxpYy5mbG91cmlzaC5zdHVkaW8vdmlzdWFsaXNhdGlvbi8xNzM2MjM0OS9lbWJlZCIgZnJhbWVib3JkZXI9IjAiIHNjcm9sbGluZz0ibm8iIHN0eWxlPSJ3aWR0aDoxMDAlO2hlaWdodDo2MDBweDsiIGRhdGEtZXh0ZXJuYWw9IjEiPjwvaWZyYW1lPgoKCj5UaGUgRmxvdXJpc2ggdmlzdWFsaXphdGlvbiBwcmVzZW50cyBhbiBhbmltYXRlZCBiYXIgY2hhcnQgcmFjZSBjb21wYXJpbmcgTGliZXJpYSdzIEdEUCByYW5raW5nIHdpdGggdGhhdCBvZiAyMCBvdGhlciBBZnJpY2FuIGNvdW50cmllcyBvdmVyIHRpbWUuIEVhY2ggYmFyIHJlcHJlc2VudHMgdGhlIEdEUCByYW5raW5nIG9mIGEgc3BlY2lmaWMgY291bnRyeSwgd2l0aCBMaWJlcmlhJ3MgcG9zaXRpb24gaGlnaGxpZ2h0ZWQgZm9yIGNvbXBhcmlzb24uIEFzIHRoZSBhbmltYXRpb24gcHJvZ3Jlc3Nlcywgdmlld2VycyBjYW4gb2JzZXJ2ZSB0aGUgbW92ZW1lbnQgb2YgdGhlIGJhcnMgdG8gc2VlIGhvdyBMaWJlcmlhJ3MgR0RQIHJhbmtpbmcgZmx1Y3R1YXRlcyByZWxhdGl2ZSB0byBvdGhlciBBZnJpY2FuIG5hdGlvbnMuClRoaXMgdmlzdWFsaXphdGlvbiBvZmZlcnMgYSBkeW5hbWljIHdheSB0byBhbmFseXplIExpYmVyaWEncyBlY29ub21pYyBwZXJmb3JtYW5jZSBpbiBjb21wYXJpc29uIHRvIGl0cyBwZWVycyB3aXRoaW4gdGhlIEFmcmljYW4gY29udGluZW50LiBCeSB0cmFja2luZyBMaWJlcmlhJ3MgcG9zaXRpb24gaW4gdGhlIEdEUCByYW5raW5nIG92ZXIgdGltZSwgdmlld2VycyBjYW4gYXNzZXNzIHdoZXRoZXIgdGhlIGNvdW50cnkgaGFzIGV4cGVyaWVuY2VkIGltcHJvdmVtZW50cywgZGVjbGluZXMsIG9yIHN0YWJpbGl0eSBpbiBpdHMgZWNvbm9taWMgc3RhbmRpbmcgcmVsYXRpdmUgdG8gb3RoZXIgQWZyaWNhbiBjb3VudHJpZXMuCgo8aWZyYW1lIHNyYz0iaHR0cHM6Ly9wdWJsaWMuZmxvdXJpc2guc3R1ZGlvL3Zpc3VhbGlzYXRpb24vMTczNjE5MTMvZW1iZWQiIGZyYW1lYm9yZGVyPSIwIiBzY3JvbGxpbmc9Im5vIiBzdHlsZT0id2lkdGg6MTAwJTtoZWlnaHQ6NjAwcHg7IiBkYXRhLWV4dGVybmFsPSIxIj48L2lmcmFtZT4KCiogKiAqCgoKCgoKIyBSZWZlcmVuY2VzCgoxLiBXaWNraGFtLCBILiAoMjAxNikuIGdncGxvdDI6IEVsZWdhbnQgR3JhcGhpY3MgZm9yIERhdGEgQW5hbHlzaXMuIFNwcmluZ2VyLVZlcmxhZyBOZXcgWW9yay4gSVNCTiA5NzgtMy0zMTktMjQyNzctNC4KCjIuIEthZ2dsZS4gKG4uZC4pLiBHcm9zcyBEb21lc3RpYyBQcm9kdWN0IChHRFApIGJ5IENvdW50cnkgMTk2MC0yMDIwLiBSZXRyaWV2ZWQgZnJvbSBodHRwczovL3d3dy5rYWdnbGUuY29tL1dvcmxkIEJhbmsgRGF0YS9nZHAtcmFua2luZy4KCjMuIENsYXNzIExlc3NvbiBvbiBJbmZvcm1hdGlvbiBEZXNpZ24gJiBWaXN1YWwgQW5hbHl0aWNzLgoKNC4gT3BlbkFJLiAoMjAyMikuIENoYXRHUFQuIGh0dHBzOi8vb3BlbmFpLmNvbS9ncHQKCjUuIEZsb3VyaXNoIFN0dWRpby4gKG4uZC4pLiBEYXRhIFZpc3VhbGl6YXRpb24gUGxhdGZvcm0uIFJldHJpZXZlZCBmcm9tIGh0dHBzOi8vZmxvdXJpc2guc3R1ZGlvLy4KCiogKiAqCgojIyBBbGwgZG9uZSEK