From 5801417a3b71562bcb494e441eb29e99074c471a Mon Sep 17 00:00:00 2001 From: francs99 Date: Wed, 20 Aug 2025 18:38:56 +0200 Subject: [PATCH] =?UTF-8?q?Create=20Olympics-Paralympics=5FBauer-PereiraMa?= =?UTF-8?q?rques-Kr=C3=A4mer?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Upload html --- ...ympics_Bauer-PereiraMarques-Kr\303\244mer" | 4250 +++++++++++++++++ 1 file changed, 4250 insertions(+) create mode 100644 "submissions/Olympics-Paralympics_Bauer-PereiraMarques-Kr\303\244mer" diff --git "a/submissions/Olympics-Paralympics_Bauer-PereiraMarques-Kr\303\244mer" "b/submissions/Olympics-Paralympics_Bauer-PereiraMarques-Kr\303\244mer" new file mode 100644 index 0000000..bd0b08a --- /dev/null +++ "b/submissions/Olympics-Paralympics_Bauer-PereiraMarques-Kr\303\244mer" @@ -0,0 +1,4250 @@ + + + + + + + + + + + + + + +Olympic and Paralympic Datensets + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+
+
+
+
+ +
+ + + + + + + +

Hypothese Länder, die in den olympischen Spielen +gut abschneiden, schneiden auch bei den paralympischen Spielen gut +ab. Es wurden nur Länder verglichen, die sowohl bei den +Paralympischen als auch Olympischen Spielen mitgemacht haben.

+
#here data is read in 
+
+library(tidytuesdayR)
+
+
+paralympics <- read_csv("data/athletes.csv")
+olympics    <- read_csv("data/olympics.csv")
+
+#rename and select data from olympic datafile
+olym2 <- olympics %>%
+  rename(
+    name    = name,
+    gender  = sex,
+    country = noc,
+    sport   = sport 
+  ) %>%
+  mutate(
+    gender = recode(gender,
+                    M = "male",
+                    F = "female"),
+  country = ifelse(country == "URS", "RUS", country), #becuase the dataset contains URS and RUS we have decided to combine both and label it as RUS
+  country = ifelse(country %in% c("GER", "GDR", "FRG"), "GER", country) #this dataset doesn't distinguish between GER, GDR, FRG but adding this line helps for the comparison of the datasets
+  ) %>%
+  filter(!is.na(medal)) %>%
+  select(name, gender, country, year, medal, sport) 
+ 
+# rename and select data from paralympic datafile
+para2 <- paralympics %>%
+  rename(
+    name    = athlete,
+    gender  = gender, 
+    country = abb,
+    sport   = type,
+    origin = country,
+  ) %>%
+  mutate(
+    gender = recode(gender,
+                    Men   = "male",
+                    Women = "female"),
+  country = ifelse(country %in% c("GER", "GDR", "FRG"), "GER", country), #combined all german datasets
+  country = ifelse(country == "URS", "RUS", country)#this dataset doesn't distinguish between USR and RUS but adding this line helps for the comparison of the datasets
+  ) %>%
+  filter(!is.na(medal)) %>%
+  select(name, gender, country, year, medal, sport)
+ 
+
+# 3. join into one dataset
+all_games <- bind_rows(
+  olym2 %>% mutate(origin = "Olympic"),
+  para2 %>% mutate(origin = "Paralympic")
+)
+
+

1 Olympic Datensatz

+

Hier haben wir uns den Olympic Datensatz angeschaut und die Top 10 +Länder mit den meisten Medaillen identifiziert. Hier war zu beachten, +dass der Datensatz olympics.csv sowohl Daten für Russland (RUS) als auch +UDSSR (USR) enthält. Hier wurden RUS und USR in einen Datensatz für +Russland kombiniert. Es sind Daten von 1896 bis 2016 enthalten

+
library(pander)
+
+olym2 %>% 
+ group_by(country) %>%
+  summarise(
+    gold   = sum(medal == "Gold"),
+    silver = sum(medal == "Silver"),
+    bronze = sum(medal == "Bronze"),
+    total  = n(),
+    .groups = "drop"
+  ) %>%
+  
+  # 3. take the top 10 by total
+  arrange(desc(total)) %>%
+  slice_head(n = 10) %>%
+  
+  # 4. pretty‐print as a markdown table
+  pander()
+ +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
countrygoldsilverbronzetotal
USA2638164113585637
GER1301119512603756
RUS1472109910973668
GBR6787396512068
FRA5016106661777
ITA5755315311637
SWE4795225351536
CAN4634384511352
AUS3484555171320
HUN4323323711135
+

In diesem Abschnitt sieht man einen Graphen mit den Top 10 Ländern +mit den meisten Medaillen. Außerdem wird dargestellt, wie viele Gold-, +Silber- und Bronze-Medaillen jedes Land jeweils gewonnen hat.

+
# 1. build a top10 summary from olym2 by total medals
+top10olymp <- olym2 %>%
+  count(country, name = "total") %>%
+  arrange(desc(total)) %>%
+  slice_head(n = 10) %>%
+  pull(country)
+
+#order of countries (decending based on total)
+countryorder <- olym2 %>%
+  filter(country %in% top10olymp) %>%
+  count(country, name = "total") %>%
+  arrange(desc(total)) %>%
+  pull(country)
+
+countryorder <- rev(countryorder) #added this so the top countries are on the top of the graph 
+
+#2. add a medal breakdown for stacked column chart 
+top10olympstacked <- olym2 %>%
+  filter(country %in% top10olymp) %>%
+  count(country, medal, name = "count") %>%
+  mutate(
+    medal = factor(medal, levels = c("Gold", "Silver", "Bronze")),
+    country = factor(country, levels = countryorder)
+  )
+
+# 23. plot it
+ggplot(top10olympstacked, aes(x = country, y = count, fill = medal)) +
+  geom_col() +
+  coord_flip() +
+    scale_fill_manual(values = c("Gold" = "goldenrod", "Silver" = "azure3", "Bronze" = "darkorange3")) +
+  labs(
+    title = "Top 10 Olympic Medal-Winning Countries",
+    subtitle = "Stacked by Medal Type",
+    x     = "Country (NOC)",
+    y     = "Total of Medals",
+    fill = "Medal"
+  )
+

+

Um darzustellen, welchen Anteil jedes Land von allen Medaillen in den +olympischen Spielen über die Zeit gewonnen hat, haben wir hier einen Pie +Chart zur Veranschaulichung erstellt.

+
piechart_df <- olym2 %>%
+  count(country, name = "count") %>%
+  mutate(country = if_else(country %in% top10olymp, country, "Other")) %>%
+  group_by(country) %>%
+  summarise(count = sum(count), .groups = "drop") %>%
+  mutate(
+    share   = count / sum(count),
+    label   = percent(share, accuracy = 0.1),
+    country = factor(country, levels = c(top10olymp, "Other"))
+  ) %>%
+  arrange(country)
+
+radius_factor <- 1.3 #factor to move percentage labels further from center to make them easier to read
+
+# pie chart
+ggplot(piechart_df, aes(x = 1, y = share, fill = country)) +
+  geom_col(width = 1, color = "white") +
+  coord_polar(theta = "y") +
+  geom_text(aes(x = radius_factor, label = label),
+            position = position_stack(vjust = 0.5),  # centers on each slice
+            size = 3, color = "black") +
+  labs(
+    title = "Share of Olympic Medals by Country",
+    fill = "Country"
+  ) +
+  theme_void()  #gets rid of axis and grid
+

+
+
+

2 Paralympic +Datensatz

+

Hier haben wir uns den Paralympics Datensatz angeschaut und die Top +10 Länder identifiziert, die die größte Gesamtanzahl an Medaillen +gewonnen haben. Hier ist zu beachten, dass die Daten für Westdeutschland +(FRG) und Ostdeutschland (GDR) mit den anderen Daten für ganz +Deutschland (GER) kombiniert wurden, um einen zusammengefügten Datensatz +für Deutschland zu erstellen.

+
library(pander)
+
+para2 %>% 
+ group_by(country) %>%
+  summarise(
+    gold   = sum(medal == "Gold"),
+    silver = sum(medal == "Silver"),
+    bronze = sum(medal == "Bronze"),
+    total  = n(),
+    .groups = "drop"
+  ) %>%
+  
+  # 3. take the top 10 by total
+  arrange(desc(total)) %>%
+  slice_head(n = 10) %>%
+  
+  # 4. pretty‐print as a markdown table
+  pander()
+ +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
countrygoldsilverbronzetotal
USA7015726281901
GER5595274811567
GBR4395024831424
CHN6593942661319
FRA3823804161178
AUS3614033361100
CAN4163113031030
POL231266232729
ESP208226234668
NED189239237665
+

Hier sieht man einen Graph, der die Top 10 Länder zeigt, die die +meisten Medaillen bei den Paralympics gewonnen haben. Außerdem wird +dargestellt, wie viele Gold-, Silber- und Bronzemedaillen die einzelnen +Länder jeweils gewonnen haben.

+
top10para <- para2 %>%
+  count(country, name = "total") %>%
+  arrange(desc(total)) %>%
+  slice_head(n = 10) %>%
+  pull(country)
+
+#order of countries (decending based on total)
+countryorderp <- para2 %>%
+  filter(country %in% top10para) %>%
+  count(country, name = "total") %>%
+  arrange(desc(total)) %>%
+  pull(country)
+
+countryorderp <- rev(countryorderp) #added this so the top countries are on the top of the graph like before 
+
+#2. add a medal breakdown for stacked column chart 
+top10parastacked <- para2 %>%
+  filter(country %in% top10para) %>%
+  count(country, medal, name = "count") %>%
+  mutate(
+    medal = factor(medal, levels = c("Gold", "Silver", "Bronze")),
+    country = factor(country, levels = countryorderp)
+  )
+
+# 23. plot it
+ggplot(top10parastacked, aes(x = country, y = count, fill = medal)) +
+  geom_col() +
+  coord_flip() +
+    scale_fill_manual(values = c("Gold" = "goldenrod", "Silver" = "azure3", "Bronze" = "darkorange3")) +
+  labs(
+    title = "Top 10 Paralympic Medal-Winning Countries",
+    subtitle = "Stacked by Medal Type",
+    x     = "Country (NOC)",
+    y     = "Total of Medals",
+    fill = "Medal"
+  )
+

+

Zur Veranschaulichung haben wir hier noch einmal einen Kreisdiagramm +erstellt, das den Anteil jedes Landes an allen Medaillen bei den +Paralympischen Spielen über die Zeit darstellt.

+
piechartp_df <- para2 %>%
+  count(country, name = "count") %>%
+  mutate(country = if_else(country %in% top10para, country, "Other")) %>%
+  group_by(country) %>%
+  summarise(count = sum(count), .groups = "drop") %>%
+  mutate(
+    share   = count / sum(count),
+    label   = percent(share, accuracy = 0.1),
+    country = factor(country, levels = c(top10para, "Other"))
+  ) %>%
+  arrange(country)
+
+radius_factor <- 1.3 #factor to move percentage labels further from center to make them easier to read
+
+# pie chart
+ggplot(piechartp_df, aes(x = 1, y = share, fill = country)) +
+  geom_col(width = 1, color = "white") +
+  coord_polar(theta = "y") +
+  geom_text(aes(x = radius_factor, label = label),
+            position = position_stack(vjust = 0.5),  # centers on each slice
+            size = 3, color = "black") +
+  labs(
+    title = "Share of Paralympic Medals by Country",
+    fill = "Country"
+  ) +
+  theme_void()  #gets rid of axis and grid
+

+
+
+

3 Paralympische vs +Olympische Spiele

+
+

3.1 +Datensatzvergleich

+

Im nächsten Schritt sollen die Datensätze der Olympischen und +Paralympischen Spiele miteinander verglichen werden. Um einen +aussagekräftigen Vergleich durchführen zu können, müssen wir zunächst +die Länder ermitteln, für die Daten sowohl für die Olympischen als auch +für die Paralympischen Spiele vorliegen.

+
# 1. get unique country lists from each Games
+oly_countries  <- olym2  %>% distinct(country) %>% pull()
+para_countries <- para2  %>% distinct(country) %>% pull()
+
+# 2. compute the “only” sets
+oly_only  <- setdiff(oly_countries, para_countries)
+para_only <- setdiff(para_countries, oly_countries)
+
+# 3. print them
+cat("Countries with Olympic but NO Paralympic data:\n",
+    paste(oly_only, collapse = ", "), "\n\n")
+
## Countries with Olympic but NO Paralympic data:
+##  CMR, TJK, ROU, GHA, IOA, ARM, NIG, PRK, GUY, GEO, HAI, ANZ, PAR, MNE, GUA, TAN, LIB, KGZ, AHO, TOG, NEP, SEN, UAR, LIE, WIF, BOH, BER, ISV, MKD, GRN, MRI, KOS, ZAM, MON, SUR, AFG, BDI, GAB, ECU, CRC, DJI, ERI, BAR, TGA
+
cat("Countries with Paralympic but NO Olympic data:\n",
+    paste(para_only, collapse = ", "), "\n\n")
+
## Countries with Paralympic but NO Olympic data:
+##  NA, BIR, IPP, PLE, ANG, RWA, PNG, CPV, -, LBA, LAO, FRO, BIH
+
# 4. filter to only those with both
+common_countries <- intersect(oly_countries, para_countries)
+all_games_common <- all_games %>%
+  filter(country %in% common_countries)
+

Mit dieser Liste können wir einen neuen Datensatz erstellen, der nur +Länder enthält, für die Daten für beide Events vorliegen.

+
+
+

3.2 Side-by-Side +Balkendiagramm

+

Um die Olympischen und die Paralympischen Spiele zu vergleichen, +betrachten wir, wie viele Medaillen jedes Land prozentual zur Gesamtzahl +der bei den jeweiligen Spielen vergebenen Medaillen gewonnen hat. Wir +verwenden einen prozentualen Vergleich, da die Olympischen Spiele und +die Paralympics unterschiedliche Teilnahmequoten haben, seit +unterschiedlicher Zeit bestehen (die Olympischen Spiele gibt es schon +länger) und unterschiedliche Disziplinen haben.

+
# finding the top country list for comparison between olympics and paralympics
+top10_both <- all_games_common %>%
+  count(country, origin, name = "n") %>%
+  group_by(country) %>% summarise(overall = sum(n), .groups = "drop") %>%
+  slice_max(overall, n = 10) %>%
+  pull(country)
+
+# find total medals per game
+totals_per_game <- all_games_common %>%
+  count(origin, name = "N_total")
+
+share_df <- all_games_common %>%
+  filter(country %in% top10_both) %>%
+  count(country, origin, name = "n") %>%
+  left_join(totals_per_game, by = "origin") %>%
+  mutate(share = n / N_total) %>%                 # % of all medals in that Games
+  group_by(country) %>% mutate(overall = sum(n)) %>% ungroup() %>%
+  mutate(country = reorder(country, overall))     
+
+#plot: side-by-side % bars
+ggplot(share_df, aes(x = country, y = share, fill = origin)) +
+  geom_col(position = position_dodge(width = 0.8), width = 0.7) +
+  coord_flip() +
+  scale_y_continuous(labels = scales::percent_format()) +
+  labs(
+    title = "Top 10 Countries: Share of Medals (Olympics vs Paralympics)",
+    x = "Country",
+    y = "Share of all medals in that Games (percentage)",
+    fill = ""
+  ) +
+  theme_minimal()
+

+

Aus diesem Column Chart kann entnommen werden, dass Länder wie die +USA, Deutschland, Großbritannien, Frankreich, Australien und Kanada die +Top 10 Länder sowohl bei den paralympischen als auch bei den olympischen +Spielen sind. Das spricht dafür, dass Länder, die gut in den Olympischen +Spielen abschneiden, auch gut bei den Paralympischen Spielen +abschneiden. Allerdings sieht man auch, dass Länder wie Russland und +Italien deutlich besser in den Olympischen Spielen und umso schlechter +in den Paralympischen Spielen abschneiden. In China wird das Gegenteil +ersichtlich. Um herauszufinden, ob der Erfolg in den Olympischen Spielen +im Zusammenhang steht mit dem in den Paralympischen Spielen bzw. ob hier +eine Korrelation zu erkennen ist, haben wir noch einen Scatter- und +Regression-Plot erstellt.

+
+
+

3.3 Regressionsdiagramme +und Korrelations-Tests

+

Hier sieht man nun den Scatterplott und eine Pearson Korrelation.

+
country_perc <- all_games_common %>%
+  count(country, origin, name = "n") %>%
+  left_join(totals_per_game, by = "origin") %>%
+  mutate(share = n / N_total) %>%
+  select(country, origin, share) %>%
+  pivot_wider(
+    names_from  = origin,
+    values_from = share,
+    values_fill = list(share = 0)
+  ) %>%
+  rename(
+    olyperc  = Olympic,
+    paraperc = Paralympic
+  )
+
+# 3) Scatter (percent vs percent)
+ggplot(country_perc, aes(x = olyperc, y = paraperc)) +
+  geom_point(size = 2) +
+  geom_smooth(method = "lm", se = TRUE) +
+  scale_x_continuous(labels = percent_format()) +
+  scale_y_continuous(labels = percent_format()) +
+  labs(
+    title = "Paralympic vs Olympic Medal Share by Country\n(only countries in both)",
+    x     = "Olympic share of all Olympic medals",
+    y     = "Paralympic share of all Paralympic medals"
+  ) +
+  theme_minimal()
+

+
# 4) Pearson correlation on shares
+cor_test <- cor.test(
+  country_perc$olyperc,
+  country_perc$paraperc,
+  method = "pearson"
+)
+#estimate = r (pearson correlation coefficient, 1 = perfect linear relationship, 0 = no relationship), statistic = t statisitic,  p value < 0.05 = statistically significant, parameter = degrees of freedom, alternative two.sided just means we tested for positive and negative correlations
+
+# 5) Tidy + print
+cor_res <- tidy(cor_test)
+pander(cor_res)
+ + ++++++++ + + + + + + + + + + + + + + + + + + + + +
Table continues below
estimatestatisticp.valueparameterconf.lowconf.high
0.816414.141.389e-251000.73930.8724
+ ++++ + + + + + + + + + + + + +
methodalternative
Pearson’s product-moment correlationtwo.sided
+

Von unserem Streudiagramm geht hervor, dass eine starke lineare +Korrelation zwischen Ländern besteht, die bei den Olympischen Spielen +gut abschneiden, und Ländern, die bei den Paralympics gut abschneiden. +Aus dem Pearson-Korrelationstest geht hervor, dass der +Pearson-Korrelationskoeffizient r (hier als Schätzung bezeichnet) 0,814 +beträgt, was nahe bei 1 liegt und auf eine starke lineare Beziehung +hindeutet. Darüber hinaus liegt der p-Wert unter 0,05, was darauf +hindeutet, dass die Korrelation statistisch signifikant ist. Um die +Korrelation weiter zu untersuchen, haben wir auch ein +Rangkorrelationsdiagramm erstellt und einen +Spearman-Rangkorrelationstest durchgeführt. Hier werden die Länder in +eine Rangfolge gebracht und dann verglichen.

+
country_ranks <- country_perc %>%
+  mutate(
+    olyrank  = dense_rank(desc(olyperc)),
+    pararank = dense_rank(desc(paraperc))
+  )
+
+
+max_rank <- max(country_ranks$olyrank, country_ranks$pararank, na.rm = TRUE)
+
+
+tick_by <- if (max_rank > 30) 5 else 1 #makes it so not every tick is shown on the axis
+rank_breaks <- seq(1, max_rank, by = tick_by)
+
+ggplot(country_ranks, aes(x = olyrank, y = pararank, label = country)) +
+  geom_point(color = "steelblue", size = 2) +
+  geom_text(vjust = -0.5, size = 2.8) +
+  geom_smooth(method = "lm", se = FALSE, color = "red", linetype = "dashed") +
+  scale_x_reverse(limits = c(max_rank, 1), breaks = rank_breaks) +
+  scale_y_reverse(limits = c(max_rank, 1), breaks = rank_breaks) +
+  labs(
+    title = "Rank Correlation: Olympic vs Paralympic Medal Share",
+    x = "Olympic Rank (1 = Highest Share)",
+    y = "Paralympic Rank (1 = Highest Share)"
+  ) +
+  theme_minimal()
+

+
# Spearman rank correlation test
+spearman_test <- cor.test(
+  country_ranks$olyrank,
+  country_ranks$pararank,
+  method = "spearman"
+)
+#estimate = rho (1 = strong correlation, 0 = no correlation), stastic value is used to calculate b value, p value < 0.05 = statistically significant, alternative two.sided just means we tested for positive and negative correlations
+
+pander(tidy(spearman_test))
+ +++++++ + + + + + + + + + + + + + + + + + + +
estimatestatisticp.valuemethodalternative
0.7429454663.929e-19Spearman’s rank correlation rhotwo.sided
+

Aus dem obigen Diagramm und dem Korrelationstest geht erneut hervor, +dass eine starke Korrelation zwischen Ländern besteht, die bei den +Olympischen Spielen gut abschneiden, und Ländern, die bei den +Paralypischen Spielen gut abschneiden. Hier hat der +Korrelationskoeffizient Rho einen Wert von 0,7429, der wiederum nahe bei +1 liegt, was darauf hindeutet, dass eine Korrelation vorliegt. Auch hier +ist der p-Wert sehr klein und liegt unter 0,05.

+

Eine weitere Frage, die wir untersuchen möchten, ist, wie das +Geschlecht die Korrelation zwischen Olympischen Spielen und +Paralympischen Spielen beeinflusst.

+

Eine Hypothese lautet, dass unabhängig vom +Geschlecht ähnliche Korrelationen zu beobachten sind. Allerdings +könnte aufgrund der potenziell unzureichenden Finanzierung von +Frauensport und medizinischer Forschung, die für die Forschung zu Frauen +mit körperlichen Behinderungen eine Rolle spielt, eine schwächere +Korrelation zwischen olympischen und paralympischen Erfolgen +bestehen.

+
+
+

3.4 Korrelation basierend +auf dem Geschlecht

+
+

3.4.1 Streudiagramm und +Pearson test

+
df_games <- all_games_common %>% 
+  filter(gender %in% c("female", "male"))
+
+
+totals_per_game_gender <- df_games %>%
+  count(origin, gender, name = "N_total")
+
+
+country_perc_gender <- df_games %>%
+  count(country, origin, gender, name = "n") %>%
+  left_join(totals_per_game_gender, by = c("origin","gender")) %>%
+  mutate(share = n / N_total) %>%
+  select(country, gender, origin, share) %>%
+  pivot_wider(
+    names_from  = origin,
+    values_from = share,
+    values_fill = list(share = 0)
+  ) %>%
+  rename(
+    olyperc  = Olympic,
+    paraperc = Paralympic
+  )
+
+ggplot(country_perc_gender, aes(x = olyperc, y = paraperc)) +
+  geom_point(size = 2) +
+  geom_smooth(method = "lm", se = TRUE) +
+  scale_x_continuous(labels = percent_format()) +
+  scale_y_continuous(labels = percent_format()) +
+  labs(
+    title = "Paralympic vs Olympic Medal Share by Country",
+    subtitle = "Plotted seperately for female and male participants",
+    x = "Olympic share of all Olympic medals",
+    y = "Paralympic share of all Paralympic medals"
+  ) +
+  theme_minimal() +
+  facet_wrap(~ gender, ncol = 2)
+

+
# 5) Pearson correlations per gender (tidy table)
+cors_by_gender <- country_perc_gender %>%
+  group_by(gender) %>%
+  summarise(tidy(cor.test(olyperc, paraperc, method = "pearson")), .groups = "drop")
+
+pander(cors_by_gender)
+ + +++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table continues below
genderestimatestatisticp.valueparameterconf.lowconf.high
female0.81513.344.793e-23900.73250.8739
male0.776712.271.367e-21990.68530.844
+ ++++ + + + + + + + + + + + + + + + + +
methodalternative
Pearson’s product-moment correlationtwo.sided
Pearson’s product-moment correlationtwo.sided
+
+
+

3.4.2 Rank Correlation +Plot and Spearman test

+
country_ranks_gender <- country_perc_gender %>%
+  group_by(gender) %>%
+  mutate(
+    olyrank  = dense_rank(desc(olyperc)),
+    pararank = dense_rank(desc(paraperc))
+  ) %>%
+  ungroup()
+
+p_female <- country_ranks_gender %>%
+  filter(gender == "female") %>%
+  ggplot(aes(x = olyrank, y = pararank, label = country)) +
+  geom_point(color = "steelblue", size = 2) +
+  geom_text(vjust = -0.5, size = 2.6) +
+  geom_smooth(method = "lm", se = FALSE, color = "red", linetype = "dashed") +
+  scale_x_reverse(limits = c(61, 1)) +
+  scale_y_reverse(limits = c(56, 1)) +
+  labs(title = "female", x = "Olympic Rank (1 = Highest Share)",
+       y = "Paralympic Rank (1 = Highest Share)") +
+  theme_minimal()
+
+# cant use one max for both male and female cause it looks to messy
+max_x_male <- max(country_ranks_gender$olyrank[country_ranks_gender$gender=="male"], na.rm = TRUE)
+
+p_male <- country_ranks_gender %>%
+  filter(gender == "male") %>%
+  ggplot(aes(x = olyrank, y = pararank, label = country)) +
+  geom_point(color = "steelblue", size = 2) +
+  geom_text(vjust = -0.5, size = 2.6) +
+  geom_smooth(method = "lm", se = FALSE, color = "red", linetype = "dashed") +
+  scale_x_reverse(limits = c(max_x_male, 1)) +
+  scale_y_reverse(limits = c(66, 1)) +
+  labs(title = "male", x = "Olympic Rank (1 = Highest Share)",
+       y = "Paralympic Rank (1 = Highest Share)") +
+  theme_minimal()
+
+p_female + p_male + plot_annotation(title = "Plotted separately for female and male participants")
+

+
# Spearman correlation by gender 
+spearman_by_gender <- country_ranks_gender %>%
+  group_by(gender) %>%
+  summarise(tidy(cor.test(olyrank, pararank, method = "spearman")), .groups = "drop")
+
+pander(spearman_by_gender)
+ + +++++++ + + + + + + + + + + + + + + + + + + + + + + + + + +
Table continues below
genderestimatestatisticp.valuemethod
female0.7311348991.3e-16Spearman’s rank correlation rho
male0.7156488304.14e-17Spearman’s rank correlation rho
+ +++ + + + + + + + + + + + + + +
alternative
two.sided
two.sided
+

Anhand der obigen Korrelationsdiagramme und der Werte im +Korrelationstest lässt sich erkennen, dass tatsächlich eine etwas +stärkere Korrelation zwischen olympischem Erfolg und paralympischem +Erfolg in der Frauengruppe besteht, was die frühere Hypothese widerlegen +würde.

+
+
+
+

3.5 Korrelation basierend +auf Sport

+

Um die Leistungen der Länder bei den Paralympics und Olympischen +Spielen in einer bestimmten Sportart vergleichen zu können, müssen wir +zunächst ermitteln, welche Sportarten bei beiden Spielen vertreten +sind:

+
#matching the sports
+same_name_sport <- function(x) {
+  x <- str_to_lower(str_trim(x))
+  x <- str_replace_all(x, "[–—-]", "-")       
+  x <- str_replace_all(x, "\\s+", " ")        
+  x <- str_remove(x, "^para\\s*-\\s*")        
+  x <- str_remove(x, "^wheelchair\\s+")       
+  x <- str_remove(x, "\\s*\\(.*\\)$")       
+  
+  case_when(
+    str_detect(x, "athletics|track\\s*&\\s*field") ~ "athletics",
+    str_detect(x, "^cycling|bmx|mountain bike|track cycling|road cycling") ~ "cycling",
+    str_detect(x, "canoe slalom|canoe sprint|canoeing|paracanoe|canoe\\b") ~ "canoe",
+    str_detect(x, "equestrianism|equestrian") ~ "equestrian",
+    TRUE ~ x
+  )
+}
+
+
+olym2_norm <- olym2 %>% mutate(snsport = same_name_sport(sport))
+para2_norm <- para2 %>% mutate(snsport = same_name_sport(sport))
+
+# Compute sets on normalized names
+oly_sports  <- olym2_norm %>% distinct(snsport) %>% pull()
+para_sports <- para2_norm %>% distinct(snsport) %>% pull()
+
+oly_sport_only  <- setdiff(oly_sports,  para_sports)
+para_sport_only <- setdiff(para_sports, oly_sports)
+common_sports   <- intersect(oly_sports, para_sports)
+
+cat("Sportarten bei den Olympischen aber NICHT bei den Paralympischen Spielen:\n",
+    if (length(oly_sport_only)) paste(sort(oly_sport_only), collapse = ", ") else "(none)", "\n\n")
+
## Sportarten bei den Olympischen aber NICHT bei den Paralympischen Spielen:
+##  aeronautics, alpine skiing, alpinism, art competitions, badminton, baseball, basque pelota, beach volleyball, biathlon, bobsleigh, boxing, canoe, cricket, croquet, cross country skiing, curling, cycling, diving, equestrian, figure skating, football, freestyle skiing, golf, gymnastics, handball, hockey, ice hockey, jeu de paume, judo, lacrosse, luge, military ski patrol, modern pentathlon, motorboating, nordic combined, polo, racquets, rhythmic gymnastics, roque, rowing, rugby sevens, sailing, shooting, short track speed skating, skeleton, ski jumping, snowboarding, softball, speed skating, synchronized swimming, taekwondo, trampolining, tug-of-war, water polo, weightlifting, wrestling
+
cat("Sportarten bei den Paralympischen Spielen enthalten aber NICHT bei den Olympischen:\n",
+    if (length(para_sport_only)) paste(sort(para_sport_only), collapse = ", ") else "(none)", "\n\n")
+
## Sportarten bei den Paralympischen Spielen enthalten aber NICHT bei den Olympischen:
+##  powerlifting
+
cat("Sportarten präsent bei den Olympischen und Paralympischen Spielen:\n",
+    if (length(common_sports)) paste(sort(common_sports), collapse = ", ") else "(none)", "\n\n")
+
## Sportarten präsent bei den Olympischen und Paralympischen Spielen:
+##  archery, athletics, basketball, fencing, rugby, swimming, table tennis, tennis, triathlon, volleyball
+
all_games_common_sports <- all_games %>%
+  mutate(snsport_std = same_name_sport(sport)) %>%
+  filter(snsport_std %in% common_sports)
+

Um festzustellen, ob es einen Zusammenhang zwischen den +Paralympischen und den Olympischen Spielen in einer bestimmten Sportart +gibt, haben wir für jede Sportart den Pearson-Korrelationskoeffizienten +berechnet.

+
cors_by_sport <- all_games_common_sports %>%
+  count(snsport_std, country, origin, name = "n") %>%
+  group_by(snsport_std, origin) %>%
+  mutate(N_total = sum(n)) %>%
+  ungroup() %>%
+  mutate(share = n / N_total) %>%
+  select(snsport_std, country, origin, share) %>%
+  pivot_wider(names_from = origin, values_from = share, values_fill = 0) %>%
+  rename(olyperc = Olympic, paraperc = Paralympic) %>%
+  group_by(snsport_std) %>%
+  filter(
+    n() >= 3,                      
+    sd(olyperc) > 0,              
+    sd(paraperc) > 0
+  ) %>%
+  summarise(
+    n_countries = n(),
+    broom::tidy(cor.test(olyperc, paraperc, method = "pearson")),
+    .groups = "drop"
+  ) %>%
+  # nicer column names
+  rename(
+    sport = snsport_std,
+    r      = estimate,
+    t      = statistic,
+    df     = parameter,
+    p      = p.value
+  ) %>%
+  arrange(desc(r))
+
+pander(cors_by_sport)
+ + +++++++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table continues below
sportn_countriesrtpdfconf.low
athletics1230.789814.161.875e-271210.7124
fencing390.67945.6321.977e-06370.4632
swimming740.66997.6566.712e-11720.5212
archery350.60424.3560.0001212330.3393
table tennis540.58825.2452.904e-06520.3804
basketball270.4172.2940.03045250.044
tennis640.3813.2450.001894620.1492
triathlon170.17150.67420.510415-0.3369
volleyball32-0.01482-0.081190.935830-0.3616
rugby12-0.06472-0.20510.841610-0.6157
+ +++++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
conf.highmethodalternative
0.8482Pearson’s product-moment correlationtwo.sided
0.8193Pearson’s product-moment correlationtwo.sided
0.7791Pearson’s product-moment correlationtwo.sided
0.7803Pearson’s product-moment correlationtwo.sided
0.7395Pearson’s product-moment correlationtwo.sided
0.688Pearson’s product-moment correlationtwo.sided
0.5732Pearson’s product-moment correlationtwo.sided
0.6025Pearson’s product-moment correlationtwo.sided
0.3356Pearson’s product-moment correlationtwo.sided
0.5288Pearson’s product-moment correlationtwo.sided
+

Aus diesen Korrelationskoeffizienten lässt sich erkennen, dass es +eine starke Korrelation in der Leichtathletik und eine moderate +Korrelation im Fechten, Schwimmen, Bogenschießen und Tischtennis gibt. +Die anderen Sportarten weisen eine sehr schwache oder gar keine +Korrelation auf.

+
+
+ +
LS0tCnRpdGxlOiAiT2x5bXBpYyBhbmQgUGFyYWx5bXBpYyBEYXRlbnNldHMiCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgdG9jOiB0cnVlICNhZGRzIHRhYmxlIG9mIGNvbnRlbnRzCiAgICB0b2NfZGVwdGg6IDMKICAgIG51bWJlcl9zZWN0aW9uczogdHJ1ZQogICAgdG9jX2Zsb2F0OiB0cnVlCiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUKICAgIHRoZW1lOiBmbGF0bHkKICAgIGhpZ2hsaWdodDogdGFuZ28KICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKICAgIGRmX3ByaW50OiBwYWdlZAoKZGF0ZTogImByIFN5cy5EYXRlKClgIgotLS0KKipIeXBvdGhlc2UqKgoqTMOkbmRlciwgZGllIGluIGRlbiBvbHltcGlzY2hlbiBTcGllbGVuIGd1dCBhYnNjaG5laWRlbiwgc2NobmVpZGVuIGF1Y2ggYmVpIGRlbiBwYXJhbHltcGlzY2hlbiBTcGllbGVuIGd1dCBhYi4qCkVzIHd1cmRlbiBudXIgTMOkbmRlciB2ZXJnbGljaGVuLCBkaWUgc293b2hsIGJlaSBkZW4gUGFyYWx5bXBpc2NoZW4gYWxzIGF1Y2ggT2x5bXBpc2NoZW4gU3BpZWxlbiBtaXRnZW1hY2h0IGhhYmVuLgoKCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsIHdhcm5pbmcgPSBGQUxTRSwgbWVzc2FnZSA9IEZBTFNFKQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkocGFuZGVyKQpsaWJyYXJ5KHJlYWRyKQpsaWJyYXJ5KHRpZHlyKQpsaWJyYXJ5KGJyb29tKQpsaWJyYXJ5KGdnYWx0KSAgCmxpYnJhcnkodGliYmxlKQpsaWJyYXJ5KHNjYWxlcykKbGlicmFyeShzdHJpbmdyKQpsaWJyYXJ5KHBhdGNod29yaykKYGBgCgpgYGB7ciByZWFkaW5nIGRhdGF9CiNoZXJlIGRhdGEgaXMgcmVhZCBpbiAKCmxpYnJhcnkodGlkeXR1ZXNkYXlSKQoKCnBhcmFseW1waWNzIDwtIHJlYWRfY3N2KCJkYXRhL2F0aGxldGVzLmNzdiIpCm9seW1waWNzICAgIDwtIHJlYWRfY3N2KCJkYXRhL29seW1waWNzLmNzdiIpCgojcmVuYW1lIGFuZCBzZWxlY3QgZGF0YSBmcm9tIG9seW1waWMgZGF0YWZpbGUKb2x5bTIgPC0gb2x5bXBpY3MgJT4lCiAgcmVuYW1lKAogICAgbmFtZSAgICA9IG5hbWUsCiAgICBnZW5kZXIgID0gc2V4LAogICAgY291bnRyeSA9IG5vYywKICAgIHNwb3J0ICAgPSBzcG9ydCAKICApICU+JQogIG11dGF0ZSgKICAgIGdlbmRlciA9IHJlY29kZShnZW5kZXIsCiAgICAgICAgICAgICAgICAgICAgTSA9ICJtYWxlIiwKICAgICAgICAgICAgICAgICAgICBGID0gImZlbWFsZSIpLAogIGNvdW50cnkgPSBpZmVsc2UoY291bnRyeSA9PSAiVVJTIiwgIlJVUyIsIGNvdW50cnkpLCAjYmVjdWFzZSB0aGUgZGF0YXNldCBjb250YWlucyBVUlMgYW5kIFJVUyB3ZSBoYXZlIGRlY2lkZWQgdG8gY29tYmluZSBib3RoIGFuZCBsYWJlbCBpdCBhcyBSVVMKICBjb3VudHJ5ID0gaWZlbHNlKGNvdW50cnkgJWluJSBjKCJHRVIiLCAiR0RSIiwgIkZSRyIpLCAiR0VSIiwgY291bnRyeSkgI3RoaXMgZGF0YXNldCBkb2Vzbid0IGRpc3Rpbmd1aXNoIGJldHdlZW4gR0VSLCBHRFIsIEZSRyBidXQgYWRkaW5nIHRoaXMgbGluZSBoZWxwcyBmb3IgdGhlIGNvbXBhcmlzb24gb2YgdGhlIGRhdGFzZXRzCiAgKSAlPiUKICBmaWx0ZXIoIWlzLm5hKG1lZGFsKSkgJT4lCiAgc2VsZWN0KG5hbWUsIGdlbmRlciwgY291bnRyeSwgeWVhciwgbWVkYWwsIHNwb3J0KSAKIAojIHJlbmFtZSBhbmQgc2VsZWN0IGRhdGEgZnJvbSBwYXJhbHltcGljIGRhdGFmaWxlCnBhcmEyIDwtIHBhcmFseW1waWNzICU+JQogIHJlbmFtZSgKICAgIG5hbWUgICAgPSBhdGhsZXRlLAogICAgZ2VuZGVyICA9IGdlbmRlciwgCiAgICBjb3VudHJ5ID0gYWJiLAogICAgc3BvcnQgICA9IHR5cGUsCiAgICBvcmlnaW4gPSBjb3VudHJ5LAogICkgJT4lCiAgbXV0YXRlKAogICAgZ2VuZGVyID0gcmVjb2RlKGdlbmRlciwKICAgICAgICAgICAgICAgICAgICBNZW4gICA9ICJtYWxlIiwKICAgICAgICAgICAgICAgICAgICBXb21lbiA9ICJmZW1hbGUiKSwKICBjb3VudHJ5ID0gaWZlbHNlKGNvdW50cnkgJWluJSBjKCJHRVIiLCAiR0RSIiwgIkZSRyIpLCAiR0VSIiwgY291bnRyeSksICNjb21iaW5lZCBhbGwgZ2VybWFuIGRhdGFzZXRzCiAgY291bnRyeSA9IGlmZWxzZShjb3VudHJ5ID09ICJVUlMiLCAiUlVTIiwgY291bnRyeSkjdGhpcyBkYXRhc2V0IGRvZXNuJ3QgZGlzdGluZ3Vpc2ggYmV0d2VlbiBVU1IgYW5kIFJVUyBidXQgYWRkaW5nIHRoaXMgbGluZSBoZWxwcyBmb3IgdGhlIGNvbXBhcmlzb24gb2YgdGhlIGRhdGFzZXRzCiAgKSAlPiUKICBmaWx0ZXIoIWlzLm5hKG1lZGFsKSkgJT4lCiAgc2VsZWN0KG5hbWUsIGdlbmRlciwgY291bnRyeSwgeWVhciwgbWVkYWwsIHNwb3J0KQogCgojIDMuIGpvaW4gaW50byBvbmUgZGF0YXNldAphbGxfZ2FtZXMgPC0gYmluZF9yb3dzKAogIG9seW0yICU+JSBtdXRhdGUob3JpZ2luID0gIk9seW1waWMiKSwKICBwYXJhMiAlPiUgbXV0YXRlKG9yaWdpbiA9ICJQYXJhbHltcGljIikKKQoKYGBgCgojIE9seW1waWMgRGF0ZW5zYXR6CgoKSGllciBoYWJlbiB3aXIgdW5zIGRlbiBPbHltcGljIERhdGVuc2F0eiBhbmdlc2NoYXV0IHVuZCBkaWUgVG9wIDEwIEzDpG5kZXIgbWl0IGRlbiBtZWlzdGVuIE1lZGFpbGxlbiBpZGVudGlmaXppZXJ0LiBIaWVyIHdhciB6dSBiZWFjaHRlbiwgZGFzcyBkZXIgRGF0ZW5zYXR6IG9seW1waWNzLmNzdiBzb3dvaGwgRGF0ZW4gZsO8ciBSdXNzbGFuZCAoUlVTKSBhbHMgYXVjaCBVRFNTUiAoVVNSKSBlbnRow6RsdC4gSGllciB3dXJkZW4gUlVTIHVuZCBVU1IgaW4gZWluZW4gRGF0ZW5zYXR6IGbDvHIgUnVzc2xhbmQga29tYmluaWVydC4gRXMgc2luZCBEYXRlbiB2b24gMTg5NiBiaXMgMjAxNiBlbnRoYWx0ZW4KCgpgYGB7ciB0b3Agb2x5bXBpYyBjb3VudHJpZXN9CmxpYnJhcnkocGFuZGVyKQoKb2x5bTIgJT4lIAogZ3JvdXBfYnkoY291bnRyeSkgJT4lCiAgc3VtbWFyaXNlKAogICAgZ29sZCAgID0gc3VtKG1lZGFsID09ICJHb2xkIiksCiAgICBzaWx2ZXIgPSBzdW0obWVkYWwgPT0gIlNpbHZlciIpLAogICAgYnJvbnplID0gc3VtKG1lZGFsID09ICJCcm9uemUiKSwKICAgIHRvdGFsICA9IG4oKSwKICAgIC5ncm91cHMgPSAiZHJvcCIKICApICU+JQogIAogICMgMy4gdGFrZSB0aGUgdG9wIDEwIGJ5IHRvdGFsCiAgYXJyYW5nZShkZXNjKHRvdGFsKSkgJT4lCiAgc2xpY2VfaGVhZChuID0gMTApICU+JQogIAogICMgNC4gcHJldHR54oCQcHJpbnQgYXMgYSBtYXJrZG93biB0YWJsZQogIHBhbmRlcigpCmBgYAoKCkluIGRpZXNlbSBBYnNjaG5pdHQgc2llaHQgbWFuIGVpbmVuIEdyYXBoZW4gbWl0IGRlbiBUb3AgMTAgTMOkbmRlcm4gbWl0IGRlbiBtZWlzdGVuIE1lZGFpbGxlbi4gQXXDn2VyZGVtIHdpcmQgZGFyZ2VzdGVsbHQsIHdpZSB2aWVsZSBHb2xkLSwgU2lsYmVyLSB1bmQgQnJvbnplLU1lZGFpbGxlbiBqZWRlcyBMYW5kIGpld2VpbHMgZ2V3b25uZW4gaGF0LiAKCmBgYHtyIHRvcCBvbHltcGljIGNvdW50cmllcyBwbG90fQojIDEuIGJ1aWxkIGEgdG9wMTAgc3VtbWFyeSBmcm9tIG9seW0yIGJ5IHRvdGFsIG1lZGFscwp0b3AxMG9seW1wIDwtIG9seW0yICU+JQogIGNvdW50KGNvdW50cnksIG5hbWUgPSAidG90YWwiKSAlPiUKICBhcnJhbmdlKGRlc2ModG90YWwpKSAlPiUKICBzbGljZV9oZWFkKG4gPSAxMCkgJT4lCiAgcHVsbChjb3VudHJ5KQoKI29yZGVyIG9mIGNvdW50cmllcyAoZGVjZW5kaW5nIGJhc2VkIG9uIHRvdGFsKQpjb3VudHJ5b3JkZXIgPC0gb2x5bTIgJT4lCiAgZmlsdGVyKGNvdW50cnkgJWluJSB0b3AxMG9seW1wKSAlPiUKICBjb3VudChjb3VudHJ5LCBuYW1lID0gInRvdGFsIikgJT4lCiAgYXJyYW5nZShkZXNjKHRvdGFsKSkgJT4lCiAgcHVsbChjb3VudHJ5KQoKY291bnRyeW9yZGVyIDwtIHJldihjb3VudHJ5b3JkZXIpICNhZGRlZCB0aGlzIHNvIHRoZSB0b3AgY291bnRyaWVzIGFyZSBvbiB0aGUgdG9wIG9mIHRoZSBncmFwaCAKCiMyLiBhZGQgYSBtZWRhbCBicmVha2Rvd24gZm9yIHN0YWNrZWQgY29sdW1uIGNoYXJ0IAp0b3AxMG9seW1wc3RhY2tlZCA8LSBvbHltMiAlPiUKICBmaWx0ZXIoY291bnRyeSAlaW4lIHRvcDEwb2x5bXApICU+JQogIGNvdW50KGNvdW50cnksIG1lZGFsLCBuYW1lID0gImNvdW50IikgJT4lCiAgbXV0YXRlKAogICAgbWVkYWwgPSBmYWN0b3IobWVkYWwsIGxldmVscyA9IGMoIkdvbGQiLCAiU2lsdmVyIiwgIkJyb256ZSIpKSwKICAgIGNvdW50cnkgPSBmYWN0b3IoY291bnRyeSwgbGV2ZWxzID0gY291bnRyeW9yZGVyKQogICkKCiMgMjMuIHBsb3QgaXQKZ2dwbG90KHRvcDEwb2x5bXBzdGFja2VkLCBhZXMoeCA9IGNvdW50cnksIHkgPSBjb3VudCwgZmlsbCA9IG1lZGFsKSkgKwogIGdlb21fY29sKCkgKwogIGNvb3JkX2ZsaXAoKSArCiAgICBzY2FsZV9maWxsX21hbnVhbCh2YWx1ZXMgPSBjKCJHb2xkIiA9ICJnb2xkZW5yb2QiLCAiU2lsdmVyIiA9ICJhenVyZTMiLCAiQnJvbnplIiA9ICJkYXJrb3JhbmdlMyIpKSArCiAgbGFicygKICAgIHRpdGxlID0gIlRvcCAxMCBPbHltcGljIE1lZGFsLVdpbm5pbmcgQ291bnRyaWVzIiwKICAgIHN1YnRpdGxlID0gIlN0YWNrZWQgYnkgTWVkYWwgVHlwZSIsCiAgICB4ICAgICA9ICJDb3VudHJ5IChOT0MpIiwKICAgIHkgICAgID0gIlRvdGFsIG9mIE1lZGFscyIsCiAgICBmaWxsID0gIk1lZGFsIgogICkKCmBgYAoKClVtIGRhcnp1c3RlbGxlbiwgd2VsY2hlbiBBbnRlaWwgamVkZXMgTGFuZCB2b24gYWxsZW4gTWVkYWlsbGVuIGluIGRlbiBvbHltcGlzY2hlbiBTcGllbGVuIMO8YmVyIGRpZSBaZWl0IGdld29ubmVuIGhhdCwgaGFiZW4gd2lyIGhpZXIgZWluZW4gUGllIENoYXJ0IHp1ciBWZXJhbnNjaGF1bGljaHVuZyBlcnN0ZWxsdC4KCmBgYHtyIG9seW1waWNzIHBlcmNlbnRhZ2UgZ3JhcGh9CgoKcGllY2hhcnRfZGYgPC0gb2x5bTIgJT4lCiAgY291bnQoY291bnRyeSwgbmFtZSA9ICJjb3VudCIpICU+JQogIG11dGF0ZShjb3VudHJ5ID0gaWZfZWxzZShjb3VudHJ5ICVpbiUgdG9wMTBvbHltcCwgY291bnRyeSwgIk90aGVyIikpICU+JQogIGdyb3VwX2J5KGNvdW50cnkpICU+JQogIHN1bW1hcmlzZShjb3VudCA9IHN1bShjb3VudCksIC5ncm91cHMgPSAiZHJvcCIpICU+JQogIG11dGF0ZSgKICAgIHNoYXJlICAgPSBjb3VudCAvIHN1bShjb3VudCksCiAgICBsYWJlbCAgID0gcGVyY2VudChzaGFyZSwgYWNjdXJhY3kgPSAwLjEpLAogICAgY291bnRyeSA9IGZhY3Rvcihjb3VudHJ5LCBsZXZlbHMgPSBjKHRvcDEwb2x5bXAsICJPdGhlciIpKQogICkgJT4lCiAgYXJyYW5nZShjb3VudHJ5KQoKcmFkaXVzX2ZhY3RvciA8LSAxLjMgI2ZhY3RvciB0byBtb3ZlIHBlcmNlbnRhZ2UgbGFiZWxzIGZ1cnRoZXIgZnJvbSBjZW50ZXIgdG8gbWFrZSB0aGVtIGVhc2llciB0byByZWFkCgojIHBpZSBjaGFydApnZ3Bsb3QocGllY2hhcnRfZGYsIGFlcyh4ID0gMSwgeSA9IHNoYXJlLCBmaWxsID0gY291bnRyeSkpICsKICBnZW9tX2NvbCh3aWR0aCA9IDEsIGNvbG9yID0gIndoaXRlIikgKwogIGNvb3JkX3BvbGFyKHRoZXRhID0gInkiKSArCiAgZ2VvbV90ZXh0KGFlcyh4ID0gcmFkaXVzX2ZhY3RvciwgbGFiZWwgPSBsYWJlbCksCiAgICAgICAgICAgIHBvc2l0aW9uID0gcG9zaXRpb25fc3RhY2sodmp1c3QgPSAwLjUpLCAgIyBjZW50ZXJzIG9uIGVhY2ggc2xpY2UKICAgICAgICAgICAgc2l6ZSA9IDMsIGNvbG9yID0gImJsYWNrIikgKwogIGxhYnMoCiAgICB0aXRsZSA9ICJTaGFyZSBvZiBPbHltcGljIE1lZGFscyBieSBDb3VudHJ5IiwKICAgIGZpbGwgPSAiQ291bnRyeSIKICApICsKICB0aGVtZV92b2lkKCkgICNnZXRzIHJpZCBvZiBheGlzIGFuZCBncmlkCgpgYGAKCiMgUGFyYWx5bXBpYyBEYXRlbnNhdHoKCgpIaWVyIGhhYmVuIHdpciB1bnMgZGVuIFBhcmFseW1waWNzIERhdGVuc2F0eiBhbmdlc2NoYXV0IHVuZCBkaWUgVG9wIDEwIEzDpG5kZXIgaWRlbnRpZml6aWVydCwgZGllIGRpZSBncsO2w590ZSBHZXNhbXRhbnphaGwgYW4gTWVkYWlsbGVuIGdld29ubmVuIGhhYmVuLiBIaWVyIGlzdCB6dSBiZWFjaHRlbiwgZGFzcyBkaWUgRGF0ZW4gZsO8ciBXZXN0ZGV1dHNjaGxhbmQgKEZSRykgdW5kIE9zdGRldXRzY2hsYW5kIChHRFIpIG1pdCBkZW4gYW5kZXJlbiBEYXRlbiBmw7xyIGdhbnogRGV1dHNjaGxhbmQgKEdFUikga29tYmluaWVydCB3dXJkZW4sIHVtIGVpbmVuIHp1c2FtbWVuZ2Vmw7xndGVuIERhdGVuc2F0eiBmw7xyIERldXRzY2hsYW5kIHp1IGVyc3RlbGxlbi4KCmBgYGAge3IgdG9wIHBhcmFseW1waWMgY291bnRyaWVzfQpsaWJyYXJ5KHBhbmRlcikKCnBhcmEyICU+JSAKIGdyb3VwX2J5KGNvdW50cnkpICU+JQogIHN1bW1hcmlzZSgKICAgIGdvbGQgICA9IHN1bShtZWRhbCA9PSAiR29sZCIpLAogICAgc2lsdmVyID0gc3VtKG1lZGFsID09ICJTaWx2ZXIiKSwKICAgIGJyb256ZSA9IHN1bShtZWRhbCA9PSAiQnJvbnplIiksCiAgICB0b3RhbCAgPSBuKCksCiAgICAuZ3JvdXBzID0gImRyb3AiCiAgKSAlPiUKICAKICAjIDMuIHRha2UgdGhlIHRvcCAxMCBieSB0b3RhbAogIGFycmFuZ2UoZGVzYyh0b3RhbCkpICU+JQogIHNsaWNlX2hlYWQobiA9IDEwKSAlPiUKICAKICAjIDQuIHByZXR0eeKAkHByaW50IGFzIGEgbWFya2Rvd24gdGFibGUKICBwYW5kZXIoKQoKCgoKYGBgYAoKSGllciBzaWVodCBtYW4gZWluZW4gR3JhcGgsIGRlciBkaWUgVG9wIDEwIEzDpG5kZXIgemVpZ3QsIGRpZSBkaWUgbWVpc3RlbiBNZWRhaWxsZW4gYmVpIGRlbiBQYXJhbHltcGljcyBnZXdvbm5lbiBoYWJlbi4gQXXDn2VyZGVtIHdpcmQgZGFyZ2VzdGVsbHQsIHdpZSB2aWVsZSBHb2xkLSwgU2lsYmVyLSB1bmQgQnJvbnplbWVkYWlsbGVuIGRpZSBlaW56ZWxuZW4gTMOkbmRlciBqZXdlaWxzIGdld29ubmVuIGhhYmVuLgogCmBgYGB7ciB0b3AgcGFyYWx5bXBpYyBjb3VudHJpZXMgcGxvdH0KCnRvcDEwcGFyYSA8LSBwYXJhMiAlPiUKICBjb3VudChjb3VudHJ5LCBuYW1lID0gInRvdGFsIikgJT4lCiAgYXJyYW5nZShkZXNjKHRvdGFsKSkgJT4lCiAgc2xpY2VfaGVhZChuID0gMTApICU+JQogIHB1bGwoY291bnRyeSkKCiNvcmRlciBvZiBjb3VudHJpZXMgKGRlY2VuZGluZyBiYXNlZCBvbiB0b3RhbCkKY291bnRyeW9yZGVycCA8LSBwYXJhMiAlPiUKICBmaWx0ZXIoY291bnRyeSAlaW4lIHRvcDEwcGFyYSkgJT4lCiAgY291bnQoY291bnRyeSwgbmFtZSA9ICJ0b3RhbCIpICU+JQogIGFycmFuZ2UoZGVzYyh0b3RhbCkpICU+JQogIHB1bGwoY291bnRyeSkKCmNvdW50cnlvcmRlcnAgPC0gcmV2KGNvdW50cnlvcmRlcnApICNhZGRlZCB0aGlzIHNvIHRoZSB0b3AgY291bnRyaWVzIGFyZSBvbiB0aGUgdG9wIG9mIHRoZSBncmFwaCBsaWtlIGJlZm9yZSAKCiMyLiBhZGQgYSBtZWRhbCBicmVha2Rvd24gZm9yIHN0YWNrZWQgY29sdW1uIGNoYXJ0IAp0b3AxMHBhcmFzdGFja2VkIDwtIHBhcmEyICU+JQogIGZpbHRlcihjb3VudHJ5ICVpbiUgdG9wMTBwYXJhKSAlPiUKICBjb3VudChjb3VudHJ5LCBtZWRhbCwgbmFtZSA9ICJjb3VudCIpICU+JQogIG11dGF0ZSgKICAgIG1lZGFsID0gZmFjdG9yKG1lZGFsLCBsZXZlbHMgPSBjKCJHb2xkIiwgIlNpbHZlciIsICJCcm9uemUiKSksCiAgICBjb3VudHJ5ID0gZmFjdG9yKGNvdW50cnksIGxldmVscyA9IGNvdW50cnlvcmRlcnApCiAgKQoKIyAyMy4gcGxvdCBpdApnZ3Bsb3QodG9wMTBwYXJhc3RhY2tlZCwgYWVzKHggPSBjb3VudHJ5LCB5ID0gY291bnQsIGZpbGwgPSBtZWRhbCkpICsKICBnZW9tX2NvbCgpICsKICBjb29yZF9mbGlwKCkgKwogICAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYygiR29sZCIgPSAiZ29sZGVucm9kIiwgIlNpbHZlciIgPSAiYXp1cmUzIiwgIkJyb256ZSIgPSAiZGFya29yYW5nZTMiKSkgKwogIGxhYnMoCiAgICB0aXRsZSA9ICJUb3AgMTAgUGFyYWx5bXBpYyBNZWRhbC1XaW5uaW5nIENvdW50cmllcyIsCiAgICBzdWJ0aXRsZSA9ICJTdGFja2VkIGJ5IE1lZGFsIFR5cGUiLAogICAgeCAgICAgPSAiQ291bnRyeSAoTk9DKSIsCiAgICB5ICAgICA9ICJUb3RhbCBvZiBNZWRhbHMiLAogICAgZmlsbCA9ICJNZWRhbCIKICApCgoKCgpgYGBgCgoKWnVyIFZlcmFuc2NoYXVsaWNodW5nIGhhYmVuIHdpciBoaWVyIG5vY2ggZWlubWFsIGVpbmVuIEtyZWlzZGlhZ3JhbW0gZXJzdGVsbHQsIGRhcyBkZW4gQW50ZWlsIGplZGVzIExhbmRlcyBhbiBhbGxlbiBNZWRhaWxsZW4gYmVpIGRlbiBQYXJhbHltcGlzY2hlbiBTcGllbGVuIMO8YmVyIGRpZSBaZWl0IGRhcnN0ZWxsdC4KIAoKYGBge3IgcGFyYWx5bXBpY3MgcGVyY2VudGFnZSBncmFwaH0KCnBpZWNoYXJ0cF9kZiA8LSBwYXJhMiAlPiUKICBjb3VudChjb3VudHJ5LCBuYW1lID0gImNvdW50IikgJT4lCiAgbXV0YXRlKGNvdW50cnkgPSBpZl9lbHNlKGNvdW50cnkgJWluJSB0b3AxMHBhcmEsIGNvdW50cnksICJPdGhlciIpKSAlPiUKICBncm91cF9ieShjb3VudHJ5KSAlPiUKICBzdW1tYXJpc2UoY291bnQgPSBzdW0oY291bnQpLCAuZ3JvdXBzID0gImRyb3AiKSAlPiUKICBtdXRhdGUoCiAgICBzaGFyZSAgID0gY291bnQgLyBzdW0oY291bnQpLAogICAgbGFiZWwgICA9IHBlcmNlbnQoc2hhcmUsIGFjY3VyYWN5ID0gMC4xKSwKICAgIGNvdW50cnkgPSBmYWN0b3IoY291bnRyeSwgbGV2ZWxzID0gYyh0b3AxMHBhcmEsICJPdGhlciIpKQogICkgJT4lCiAgYXJyYW5nZShjb3VudHJ5KQoKcmFkaXVzX2ZhY3RvciA8LSAxLjMgI2ZhY3RvciB0byBtb3ZlIHBlcmNlbnRhZ2UgbGFiZWxzIGZ1cnRoZXIgZnJvbSBjZW50ZXIgdG8gbWFrZSB0aGVtIGVhc2llciB0byByZWFkCgojIHBpZSBjaGFydApnZ3Bsb3QocGllY2hhcnRwX2RmLCBhZXMoeCA9IDEsIHkgPSBzaGFyZSwgZmlsbCA9IGNvdW50cnkpKSArCiAgZ2VvbV9jb2wod2lkdGggPSAxLCBjb2xvciA9ICJ3aGl0ZSIpICsKICBjb29yZF9wb2xhcih0aGV0YSA9ICJ5IikgKwogIGdlb21fdGV4dChhZXMoeCA9IHJhZGl1c19mYWN0b3IsIGxhYmVsID0gbGFiZWwpLAogICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX3N0YWNrKHZqdXN0ID0gMC41KSwgICMgY2VudGVycyBvbiBlYWNoIHNsaWNlCiAgICAgICAgICAgIHNpemUgPSAzLCBjb2xvciA9ICJibGFjayIpICsKICBsYWJzKAogICAgdGl0bGUgPSAiU2hhcmUgb2YgUGFyYWx5bXBpYyBNZWRhbHMgYnkgQ291bnRyeSIsCiAgICBmaWxsID0gIkNvdW50cnkiCiAgKSArCiAgdGhlbWVfdm9pZCgpICAjZ2V0cyByaWQgb2YgYXhpcyBhbmQgZ3JpZAoKYGBgCgojIFBhcmFseW1waXNjaGUgdnMgT2x5bXBpc2NoZSBTcGllbGUKCiMjIERhdGVuc2F0enZlcmdsZWljaAoKSW0gbsOkY2hzdGVuIFNjaHJpdHQgc29sbGVuIGRpZSBEYXRlbnPDpHR6ZSBkZXIgT2x5bXBpc2NoZW4gdW5kIFBhcmFseW1waXNjaGVuIFNwaWVsZSBtaXRlaW5hbmRlciB2ZXJnbGljaGVuIHdlcmRlbi4gVW0gZWluZW4gYXVzc2FnZWtyw6RmdGlnZW4gVmVyZ2xlaWNoIGR1cmNoZsO8aHJlbiB6dSBrw7ZubmVuLCBtw7xzc2VuIHdpciB6dW7DpGNoc3QgZGllIEzDpG5kZXIgZXJtaXR0ZWxuLCBmw7xyIGRpZSBEYXRlbiBzb3dvaGwgZsO8ciBkaWUgT2x5bXBpc2NoZW4gYWxzIGF1Y2ggZsO8ciBkaWUgUGFyYWx5bXBpc2NoZW4gU3BpZWxlIHZvcmxpZWdlbi4KCgpgYGB7ciBjb21wYXJlIGRhdGFzZXRzfQoKCiMgMS4gZ2V0IHVuaXF1ZSBjb3VudHJ5IGxpc3RzIGZyb20gZWFjaCBHYW1lcwpvbHlfY291bnRyaWVzICA8LSBvbHltMiAgJT4lIGRpc3RpbmN0KGNvdW50cnkpICU+JSBwdWxsKCkKcGFyYV9jb3VudHJpZXMgPC0gcGFyYTIgICU+JSBkaXN0aW5jdChjb3VudHJ5KSAlPiUgcHVsbCgpCgojIDIuIGNvbXB1dGUgdGhlIOKAnG9ubHnigJ0gc2V0cwpvbHlfb25seSAgPC0gc2V0ZGlmZihvbHlfY291bnRyaWVzLCBwYXJhX2NvdW50cmllcykKcGFyYV9vbmx5IDwtIHNldGRpZmYocGFyYV9jb3VudHJpZXMsIG9seV9jb3VudHJpZXMpCgojIDMuIHByaW50IHRoZW0KY2F0KCJDb3VudHJpZXMgd2l0aCBPbHltcGljIGJ1dCBOTyBQYXJhbHltcGljIGRhdGE6XG4iLAogICAgcGFzdGUob2x5X29ubHksIGNvbGxhcHNlID0gIiwgIiksICJcblxuIikKY2F0KCJDb3VudHJpZXMgd2l0aCBQYXJhbHltcGljIGJ1dCBOTyBPbHltcGljIGRhdGE6XG4iLAogICAgcGFzdGUocGFyYV9vbmx5LCBjb2xsYXBzZSA9ICIsICIpLCAiXG5cbiIpCgojIDQuIGZpbHRlciB0byBvbmx5IHRob3NlIHdpdGggYm90aApjb21tb25fY291bnRyaWVzIDwtIGludGVyc2VjdChvbHlfY291bnRyaWVzLCBwYXJhX2NvdW50cmllcykKYWxsX2dhbWVzX2NvbW1vbiA8LSBhbGxfZ2FtZXMgJT4lCiAgZmlsdGVyKGNvdW50cnkgJWluJSBjb21tb25fY291bnRyaWVzKQpgYGAKCk1pdCBkaWVzZXIgTGlzdGUga8O2bm5lbiB3aXIgZWluZW4gbmV1ZW4gRGF0ZW5zYXR6IGVyc3RlbGxlbiwgZGVyIG51ciBMw6RuZGVyIGVudGjDpGx0LCBmw7xyIGRpZSBEYXRlbiBmw7xyIGJlaWRlIEV2ZW50cyB2b3JsaWVnZW4uCgojIyBTaWRlLWJ5LVNpZGUgQmFsa2VuZGlhZ3JhbW0gCgoKVW0gZGllIE9seW1waXNjaGVuIHVuZCBkaWUgUGFyYWx5bXBpc2NoZW4gU3BpZWxlIHp1IHZlcmdsZWljaGVuLCBiZXRyYWNodGVuIHdpciwgd2llIHZpZWxlIE1lZGFpbGxlbiBqZWRlcyBMYW5kIHByb3plbnR1YWwgenVyIEdlc2FtdHphaGwgZGVyIGJlaSBkZW4gamV3ZWlsaWdlbiBTcGllbGVuIHZlcmdlYmVuZW4gTWVkYWlsbGVuIGdld29ubmVuIGhhdC4gV2lyIHZlcndlbmRlbiBlaW5lbiBwcm96ZW50dWFsZW4gVmVyZ2xlaWNoLCBkYSBkaWUgT2x5bXBpc2NoZW4gU3BpZWxlIHVuZCBkaWUgUGFyYWx5bXBpY3MgdW50ZXJzY2hpZWRsaWNoZSBUZWlsbmFobWVxdW90ZW4gaGFiZW4sIHNlaXQgdW50ZXJzY2hpZWRsaWNoZXIgWmVpdCBiZXN0ZWhlbiAoZGllIE9seW1waXNjaGVuIFNwaWVsZSBnaWJ0IGVzIHNjaG9uIGzDpG5nZXIpIHVuZCB1bnRlcnNjaGllZGxpY2hlIERpc3ppcGxpbmVuIGhhYmVuLgoKCmBgYHtyIHRvcCAxMCBzaWRlIGJ5IHNpZGUgYmFyIGNoYXJ0fSAKIyBmaW5kaW5nIHRoZSB0b3AgY291bnRyeSBsaXN0IGZvciBjb21wYXJpc29uIGJldHdlZW4gb2x5bXBpY3MgYW5kIHBhcmFseW1waWNzCnRvcDEwX2JvdGggPC0gYWxsX2dhbWVzX2NvbW1vbiAlPiUKICBjb3VudChjb3VudHJ5LCBvcmlnaW4sIG5hbWUgPSAibiIpICU+JQogIGdyb3VwX2J5KGNvdW50cnkpICU+JSBzdW1tYXJpc2Uob3ZlcmFsbCA9IHN1bShuKSwgLmdyb3VwcyA9ICJkcm9wIikgJT4lCiAgc2xpY2VfbWF4KG92ZXJhbGwsIG4gPSAxMCkgJT4lCiAgcHVsbChjb3VudHJ5KQoKIyBmaW5kIHRvdGFsIG1lZGFscyBwZXIgZ2FtZQp0b3RhbHNfcGVyX2dhbWUgPC0gYWxsX2dhbWVzX2NvbW1vbiAlPiUKICBjb3VudChvcmlnaW4sIG5hbWUgPSAiTl90b3RhbCIpCgpzaGFyZV9kZiA8LSBhbGxfZ2FtZXNfY29tbW9uICU+JQogIGZpbHRlcihjb3VudHJ5ICVpbiUgdG9wMTBfYm90aCkgJT4lCiAgY291bnQoY291bnRyeSwgb3JpZ2luLCBuYW1lID0gIm4iKSAlPiUKICBsZWZ0X2pvaW4odG90YWxzX3Blcl9nYW1lLCBieSA9ICJvcmlnaW4iKSAlPiUKICBtdXRhdGUoc2hhcmUgPSBuIC8gTl90b3RhbCkgJT4lICAgICAgICAgICAgICAgICAjICUgb2YgYWxsIG1lZGFscyBpbiB0aGF0IEdhbWVzCiAgZ3JvdXBfYnkoY291bnRyeSkgJT4lIG11dGF0ZShvdmVyYWxsID0gc3VtKG4pKSAlPiUgdW5ncm91cCgpICU+JQogIG11dGF0ZShjb3VudHJ5ID0gcmVvcmRlcihjb3VudHJ5LCBvdmVyYWxsKSkgICAgIAoKI3Bsb3Q6IHNpZGUtYnktc2lkZSAlIGJhcnMKZ2dwbG90KHNoYXJlX2RmLCBhZXMoeCA9IGNvdW50cnksIHkgPSBzaGFyZSwgZmlsbCA9IG9yaWdpbikpICsKICBnZW9tX2NvbChwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKHdpZHRoID0gMC44KSwgd2lkdGggPSAwLjcpICsKICBjb29yZF9mbGlwKCkgKwogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBzY2FsZXM6OnBlcmNlbnRfZm9ybWF0KCkpICsKICBsYWJzKAogICAgdGl0bGUgPSAiVG9wIDEwIENvdW50cmllczogU2hhcmUgb2YgTWVkYWxzIChPbHltcGljcyB2cyBQYXJhbHltcGljcykiLAogICAgeCA9ICJDb3VudHJ5IiwKICAgIHkgPSAiU2hhcmUgb2YgYWxsIG1lZGFscyBpbiB0aGF0IEdhbWVzIChwZXJjZW50YWdlKSIsCiAgICBmaWxsID0gIiIKICApICsKICB0aGVtZV9taW5pbWFsKCkKCmBgYAoKCkF1cyBkaWVzZW0gQ29sdW1uIENoYXJ0IGthbm4gZW50bm9tbWVuIHdlcmRlbiwgZGFzcyBMw6RuZGVyIHdpZSBkaWUgVVNBLCBEZXV0c2NobGFuZCwgR3Jvw59icml0YW5uaWVuLCBGcmFua3JlaWNoLCBBdXN0cmFsaWVuIHVuZCBLYW5hZGEgZGllIFRvcCAxMCBMw6RuZGVyIHNvd29obCBiZWkgZGVuIHBhcmFseW1waXNjaGVuIGFscyBhdWNoIGJlaSBkZW4gb2x5bXBpc2NoZW4gU3BpZWxlbiBzaW5kLiBEYXMgc3ByaWNodCBkYWbDvHIsIGRhc3MgTMOkbmRlciwgZGllIGd1dCBpbiBkZW4gT2x5bXBpc2NoZW4gU3BpZWxlbiBhYnNjaG5laWRlbiwgYXVjaCBndXQgYmVpIGRlbiBQYXJhbHltcGlzY2hlbiBTcGllbGVuIGFic2NobmVpZGVuLiBBbGxlcmRpbmdzIHNpZWh0IG1hbiBhdWNoLCBkYXNzIEzDpG5kZXIgd2llIFJ1c3NsYW5kIHVuZCBJdGFsaWVuIGRldXRsaWNoIGJlc3NlciBpbiBkZW4gT2x5bXBpc2NoZW4gU3BpZWxlbiB1bmQgdW1zbyBzY2hsZWNodGVyIGluIGRlbiBQYXJhbHltcGlzY2hlbiBTcGllbGVuIGFic2NobmVpZGVuLiBJbiBDaGluYSB3aXJkIGRhcyBHZWdlbnRlaWwgZXJzaWNodGxpY2guIFVtIGhlcmF1c3p1ZmluZGVuLCBvYiBkZXIgRXJmb2xnIGluIGRlbiBPbHltcGlzY2hlbiBTcGllbGVuIGltIFp1c2FtbWVuaGFuZyBzdGVodCBtaXQgZGVtIGluIGRlbiBQYXJhbHltcGlzY2hlbiBTcGllbGVuIGJ6dy4gb2IgaGllciBlaW5lIEtvcnJlbGF0aW9uIHp1IGVya2VubmVuIGlzdCwgaGFiZW4gd2lyIG5vY2ggZWluZW4gU2NhdHRlci0gdW5kIFJlZ3Jlc3Npb24tUGxvdCBlcnN0ZWxsdC4KCgojIyBSZWdyZXNzaW9uc2RpYWdyYW1tZSB1bmQgS29ycmVsYXRpb25zLVRlc3RzCgpIaWVyIHNpZWh0IG1hbiBudW4gZGVuIFNjYXR0ZXJwbG90dCB1bmQgZWluZSBQZWFyc29uIEtvcnJlbGF0aW9uLiAKCgpgYGB7ciByZWdyZXNzaW9uIGFuZCBwZWFyc29uIHRlc3R9Cgpjb3VudHJ5X3BlcmMgPC0gYWxsX2dhbWVzX2NvbW1vbiAlPiUKICBjb3VudChjb3VudHJ5LCBvcmlnaW4sIG5hbWUgPSAibiIpICU+JQogIGxlZnRfam9pbih0b3RhbHNfcGVyX2dhbWUsIGJ5ID0gIm9yaWdpbiIpICU+JQogIG11dGF0ZShzaGFyZSA9IG4gLyBOX3RvdGFsKSAlPiUKICBzZWxlY3QoY291bnRyeSwgb3JpZ2luLCBzaGFyZSkgJT4lCiAgcGl2b3Rfd2lkZXIoCiAgICBuYW1lc19mcm9tICA9IG9yaWdpbiwKICAgIHZhbHVlc19mcm9tID0gc2hhcmUsCiAgICB2YWx1ZXNfZmlsbCA9IGxpc3Qoc2hhcmUgPSAwKQogICkgJT4lCiAgcmVuYW1lKAogICAgb2x5cGVyYyAgPSBPbHltcGljLAogICAgcGFyYXBlcmMgPSBQYXJhbHltcGljCiAgKQoKIyAzKSBTY2F0dGVyIChwZXJjZW50IHZzIHBlcmNlbnQpCmdncGxvdChjb3VudHJ5X3BlcmMsIGFlcyh4ID0gb2x5cGVyYywgeSA9IHBhcmFwZXJjKSkgKwogIGdlb21fcG9pbnQoc2l6ZSA9IDIpICsKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzZSA9IFRSVUUpICsKICBzY2FsZV94X2NvbnRpbnVvdXMobGFiZWxzID0gcGVyY2VudF9mb3JtYXQoKSkgKwogIHNjYWxlX3lfY29udGludW91cyhsYWJlbHMgPSBwZXJjZW50X2Zvcm1hdCgpKSArCiAgbGFicygKICAgIHRpdGxlID0gIlBhcmFseW1waWMgdnMgT2x5bXBpYyBNZWRhbCBTaGFyZSBieSBDb3VudHJ5XG4ob25seSBjb3VudHJpZXMgaW4gYm90aCkiLAogICAgeCAgICAgPSAiT2x5bXBpYyBzaGFyZSBvZiBhbGwgT2x5bXBpYyBtZWRhbHMiLAogICAgeSAgICAgPSAiUGFyYWx5bXBpYyBzaGFyZSBvZiBhbGwgUGFyYWx5bXBpYyBtZWRhbHMiCiAgKSArCiAgdGhlbWVfbWluaW1hbCgpCgojIDQpIFBlYXJzb24gY29ycmVsYXRpb24gb24gc2hhcmVzCmNvcl90ZXN0IDwtIGNvci50ZXN0KAogIGNvdW50cnlfcGVyYyRvbHlwZXJjLAogIGNvdW50cnlfcGVyYyRwYXJhcGVyYywKICBtZXRob2QgPSAicGVhcnNvbiIKKQojZXN0aW1hdGUgPSByIChwZWFyc29uIGNvcnJlbGF0aW9uIGNvZWZmaWNpZW50LCAxID0gcGVyZmVjdCBsaW5lYXIgcmVsYXRpb25zaGlwLCAwID0gbm8gcmVsYXRpb25zaGlwKSwgc3RhdGlzdGljID0gdCBzdGF0aXNpdGljLCAgcCB2YWx1ZSA8IDAuMDUgPSBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50LCBwYXJhbWV0ZXIgPSBkZWdyZWVzIG9mIGZyZWVkb20sIGFsdGVybmF0aXZlIHR3by5zaWRlZCBqdXN0IG1lYW5zIHdlIHRlc3RlZCBmb3IgcG9zaXRpdmUgYW5kIG5lZ2F0aXZlIGNvcnJlbGF0aW9ucwoKIyA1KSBUaWR5ICsgcHJpbnQKY29yX3JlcyA8LSB0aWR5KGNvcl90ZXN0KQpwYW5kZXIoY29yX3JlcykKCmBgYAoKVm9uIHVuc2VyZW0gU3RyZXVkaWFncmFtbSBnZWh0IGhlcnZvciwgZGFzcyBlaW5lIHN0YXJrZSBsaW5lYXJlIEtvcnJlbGF0aW9uIHp3aXNjaGVuIEzDpG5kZXJuIGJlc3RlaHQsIGRpZSBiZWkgZGVuIE9seW1waXNjaGVuIFNwaWVsZW4gZ3V0IGFic2NobmVpZGVuLCB1bmQgTMOkbmRlcm4sIGRpZSBiZWkgZGVuIFBhcmFseW1waWNzIGd1dCBhYnNjaG5laWRlbi4gQXVzIGRlbSBQZWFyc29uLUtvcnJlbGF0aW9uc3Rlc3QgZ2VodCBoZXJ2b3IsIGRhc3MgZGVyIFBlYXJzb24tS29ycmVsYXRpb25za29lZmZpemllbnQgciAoaGllciBhbHMgU2Now6R0enVuZyBiZXplaWNobmV0KSAwLDgxNCBiZXRyw6RndCwgd2FzIG5haGUgYmVpIDEgbGllZ3QgdW5kIGF1ZiBlaW5lIHN0YXJrZSBsaW5lYXJlIEJlemllaHVuZyBoaW5kZXV0ZXQuIERhcsO8YmVyIGhpbmF1cyBsaWVndCBkZXIgcC1XZXJ0IHVudGVyIDAsMDUsIHdhcyBkYXJhdWYgaGluZGV1dGV0LCBkYXNzIGRpZSBLb3JyZWxhdGlvbiBzdGF0aXN0aXNjaCBzaWduaWZpa2FudCBpc3QuIFVtIGRpZSBLb3JyZWxhdGlvbiB3ZWl0ZXIgenUgdW50ZXJzdWNoZW4sIGhhYmVuIHdpciBhdWNoIGVpbiBSYW5na29ycmVsYXRpb25zZGlhZ3JhbW0gZXJzdGVsbHQgdW5kIGVpbmVuIFNwZWFybWFuLVJhbmdrb3JyZWxhdGlvbnN0ZXN0IGR1cmNoZ2Vmw7xocnQuIEhpZXIgd2VyZGVuIGRpZSBMw6RuZGVyIGluIGVpbmUgUmFuZ2ZvbGdlIGdlYnJhY2h0IHVuZCBkYW5uIHZlcmdsaWNoZW4uCgoKYGBge3IgcmFuayBjb3JyZWxhdGlvbiBwbG90fQoKY291bnRyeV9yYW5rcyA8LSBjb3VudHJ5X3BlcmMgJT4lCiAgbXV0YXRlKAogICAgb2x5cmFuayAgPSBkZW5zZV9yYW5rKGRlc2Mob2x5cGVyYykpLAogICAgcGFyYXJhbmsgPSBkZW5zZV9yYW5rKGRlc2MocGFyYXBlcmMpKQogICkKCgptYXhfcmFuayA8LSBtYXgoY291bnRyeV9yYW5rcyRvbHlyYW5rLCBjb3VudHJ5X3JhbmtzJHBhcmFyYW5rLCBuYS5ybSA9IFRSVUUpCgoKdGlja19ieSA8LSBpZiAobWF4X3JhbmsgPiAzMCkgNSBlbHNlIDEgI21ha2VzIGl0IHNvIG5vdCBldmVyeSB0aWNrIGlzIHNob3duIG9uIHRoZSBheGlzCnJhbmtfYnJlYWtzIDwtIHNlcSgxLCBtYXhfcmFuaywgYnkgPSB0aWNrX2J5KQoKZ2dwbG90KGNvdW50cnlfcmFua3MsIGFlcyh4ID0gb2x5cmFuaywgeSA9IHBhcmFyYW5rLCBsYWJlbCA9IGNvdW50cnkpKSArCiAgZ2VvbV9wb2ludChjb2xvciA9ICJzdGVlbGJsdWUiLCBzaXplID0gMikgKwogIGdlb21fdGV4dCh2anVzdCA9IC0wLjUsIHNpemUgPSAyLjgpICsKICBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzZSA9IEZBTFNFLCBjb2xvciA9ICJyZWQiLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArCiAgc2NhbGVfeF9yZXZlcnNlKGxpbWl0cyA9IGMobWF4X3JhbmssIDEpLCBicmVha3MgPSByYW5rX2JyZWFrcykgKwogIHNjYWxlX3lfcmV2ZXJzZShsaW1pdHMgPSBjKG1heF9yYW5rLCAxKSwgYnJlYWtzID0gcmFua19icmVha3MpICsKICBsYWJzKAogICAgdGl0bGUgPSAiUmFuayBDb3JyZWxhdGlvbjogT2x5bXBpYyB2cyBQYXJhbHltcGljIE1lZGFsIFNoYXJlIiwKICAgIHggPSAiT2x5bXBpYyBSYW5rICgxID0gSGlnaGVzdCBTaGFyZSkiLAogICAgeSA9ICJQYXJhbHltcGljIFJhbmsgKDEgPSBIaWdoZXN0IFNoYXJlKSIKICApICsKICB0aGVtZV9taW5pbWFsKCkKCgojIFNwZWFybWFuIHJhbmsgY29ycmVsYXRpb24gdGVzdApzcGVhcm1hbl90ZXN0IDwtIGNvci50ZXN0KAogIGNvdW50cnlfcmFua3Mkb2x5cmFuaywKICBjb3VudHJ5X3JhbmtzJHBhcmFyYW5rLAogIG1ldGhvZCA9ICJzcGVhcm1hbiIKKQojZXN0aW1hdGUgPSByaG8gKDEgPSBzdHJvbmcgY29ycmVsYXRpb24sIDAgPSBubyBjb3JyZWxhdGlvbiksIHN0YXN0aWMgdmFsdWUgaXMgdXNlZCB0byBjYWxjdWxhdGUgYiB2YWx1ZSwgcCB2YWx1ZSA8IDAuMDUgPSBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50LCBhbHRlcm5hdGl2ZSB0d28uc2lkZWQganVzdCBtZWFucyB3ZSB0ZXN0ZWQgZm9yIHBvc2l0aXZlIGFuZCBuZWdhdGl2ZSBjb3JyZWxhdGlvbnMKCnBhbmRlcih0aWR5KHNwZWFybWFuX3Rlc3QpKQoKYGBgCgpBdXMgZGVtIG9iaWdlbiBEaWFncmFtbSB1bmQgZGVtIEtvcnJlbGF0aW9uc3Rlc3QgZ2VodCBlcm5ldXQgaGVydm9yLCBkYXNzIGVpbmUgc3RhcmtlIEtvcnJlbGF0aW9uIHp3aXNjaGVuIEzDpG5kZXJuIGJlc3RlaHQsIGRpZSBiZWkgZGVuIE9seW1waXNjaGVuIFNwaWVsZW4gZ3V0IGFic2NobmVpZGVuLCB1bmQgTMOkbmRlcm4sIGRpZSBiZWkgZGVuIFBhcmFseXBpc2NoZW4gU3BpZWxlbiBndXQgYWJzY2huZWlkZW4uIEhpZXIgaGF0IGRlciBLb3JyZWxhdGlvbnNrb2VmZml6aWVudCBSaG8gZWluZW4gV2VydCB2b24gMCw3NDI5LCBkZXIgd2llZGVydW0gbmFoZSBiZWkgMSBsaWVndCwgd2FzIGRhcmF1ZiBoaW5kZXV0ZXQsIGRhc3MgZWluZSBLb3JyZWxhdGlvbiB2b3JsaWVndC4gQXVjaCBoaWVyIGlzdCBkZXIgcC1XZXJ0IHNlaHIga2xlaW4gdW5kIGxpZWd0IHVudGVyIDAsMDUuIAoKRWluZSB3ZWl0ZXJlIEZyYWdlLCBkaWUgd2lyIHVudGVyc3VjaGVuIG3DtmNodGVuLCBpc3QsIHdpZSBkYXMgR2VzY2hsZWNodCBkaWUgS29ycmVsYXRpb24gendpc2NoZW4gT2x5bXBpc2NoZW4gU3BpZWxlbiB1bmQgUGFyYWx5bXBpc2NoZW4gU3BpZWxlbiBiZWVpbmZsdXNzdC4gCgpFaW5lICoqSHlwb3RoZXNlKiogbGF1dGV0LCBkYXNzICp1bmFiaMOkbmdpZyB2b20gR2VzY2hsZWNodCDDpGhubGljaGUgS29ycmVsYXRpb25lbiB6dSBiZW9iYWNodGVuIHNpbmQqLiBBbGxlcmRpbmdzIGvDtm5udGUgYXVmZ3J1bmQgZGVyIHBvdGVuemllbGwgdW56dXJlaWNoZW5kZW4gRmluYW56aWVydW5nIHZvbiBGcmF1ZW5zcG9ydCB1bmQgbWVkaXppbmlzY2hlciBGb3JzY2h1bmcsIGRpZSBmw7xyIGRpZSBGb3JzY2h1bmcgenUgRnJhdWVuIG1pdCBrw7ZycGVybGljaGVuIEJlaGluZGVydW5nZW4gZWluZSBSb2xsZSBzcGllbHQsIGVpbmUgc2Nod8OkY2hlcmUgS29ycmVsYXRpb24gendpc2NoZW4gb2x5bXBpc2NoZW4gdW5kIHBhcmFseW1waXNjaGVuIEVyZm9sZ2VuIGJlc3RlaGVuLiAKCgojIyBLb3JyZWxhdGlvbiBiYXNpZXJlbmQgYXVmIGRlbSBHZXNjaGxlY2h0CgojIyMgU3RyZXVkaWFncmFtbSB1bmQgUGVhcnNvbiB0ZXN0CgpgYGB7ciBnZW5kZXIgY29tcGFyaXNvbiBwZWFyc29ufQoKZGZfZ2FtZXMgPC0gYWxsX2dhbWVzX2NvbW1vbiAlPiUgCiAgZmlsdGVyKGdlbmRlciAlaW4lIGMoImZlbWFsZSIsICJtYWxlIikpCgoKdG90YWxzX3Blcl9nYW1lX2dlbmRlciA8LSBkZl9nYW1lcyAlPiUKICBjb3VudChvcmlnaW4sIGdlbmRlciwgbmFtZSA9ICJOX3RvdGFsIikKCgpjb3VudHJ5X3BlcmNfZ2VuZGVyIDwtIGRmX2dhbWVzICU+JQogIGNvdW50KGNvdW50cnksIG9yaWdpbiwgZ2VuZGVyLCBuYW1lID0gIm4iKSAlPiUKICBsZWZ0X2pvaW4odG90YWxzX3Blcl9nYW1lX2dlbmRlciwgYnkgPSBjKCJvcmlnaW4iLCJnZW5kZXIiKSkgJT4lCiAgbXV0YXRlKHNoYXJlID0gbiAvIE5fdG90YWwpICU+JQogIHNlbGVjdChjb3VudHJ5LCBnZW5kZXIsIG9yaWdpbiwgc2hhcmUpICU+JQogIHBpdm90X3dpZGVyKAogICAgbmFtZXNfZnJvbSAgPSBvcmlnaW4sCiAgICB2YWx1ZXNfZnJvbSA9IHNoYXJlLAogICAgdmFsdWVzX2ZpbGwgPSBsaXN0KHNoYXJlID0gMCkKICApICU+JQogIHJlbmFtZSgKICAgIG9seXBlcmMgID0gT2x5bXBpYywKICAgIHBhcmFwZXJjID0gUGFyYWx5bXBpYwogICkKCmdncGxvdChjb3VudHJ5X3BlcmNfZ2VuZGVyLCBhZXMoeCA9IG9seXBlcmMsIHkgPSBwYXJhcGVyYykpICsKICBnZW9tX3BvaW50KHNpemUgPSAyKSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBUUlVFKSArCiAgc2NhbGVfeF9jb250aW51b3VzKGxhYmVscyA9IHBlcmNlbnRfZm9ybWF0KCkpICsKICBzY2FsZV95X2NvbnRpbnVvdXMobGFiZWxzID0gcGVyY2VudF9mb3JtYXQoKSkgKwogIGxhYnMoCiAgICB0aXRsZSA9ICJQYXJhbHltcGljIHZzIE9seW1waWMgTWVkYWwgU2hhcmUgYnkgQ291bnRyeSIsCiAgICBzdWJ0aXRsZSA9ICJQbG90dGVkIHNlcGVyYXRlbHkgZm9yIGZlbWFsZSBhbmQgbWFsZSBwYXJ0aWNpcGFudHMiLAogICAgeCA9ICJPbHltcGljIHNoYXJlIG9mIGFsbCBPbHltcGljIG1lZGFscyIsCiAgICB5ID0gIlBhcmFseW1waWMgc2hhcmUgb2YgYWxsIFBhcmFseW1waWMgbWVkYWxzIgogICkgKwogIHRoZW1lX21pbmltYWwoKSArCiAgZmFjZXRfd3JhcCh+IGdlbmRlciwgbmNvbCA9IDIpCgojIDUpIFBlYXJzb24gY29ycmVsYXRpb25zIHBlciBnZW5kZXIgKHRpZHkgdGFibGUpCmNvcnNfYnlfZ2VuZGVyIDwtIGNvdW50cnlfcGVyY19nZW5kZXIgJT4lCiAgZ3JvdXBfYnkoZ2VuZGVyKSAlPiUKICBzdW1tYXJpc2UodGlkeShjb3IudGVzdChvbHlwZXJjLCBwYXJhcGVyYywgbWV0aG9kID0gInBlYXJzb24iKSksIC5ncm91cHMgPSAiZHJvcCIpCgpwYW5kZXIoY29yc19ieV9nZW5kZXIpCmBgYAoKIyMjIFJhbmsgQ29ycmVsYXRpb24gUGxvdCBhbmQgU3BlYXJtYW4gdGVzdAoKYGBge3IgZ2VuZWRlciBjb21wYXJpc29uIHJhbmsgY29ycmVsYXRpb259CmNvdW50cnlfcmFua3NfZ2VuZGVyIDwtIGNvdW50cnlfcGVyY19nZW5kZXIgJT4lCiAgZ3JvdXBfYnkoZ2VuZGVyKSAlPiUKICBtdXRhdGUoCiAgICBvbHlyYW5rICA9IGRlbnNlX3JhbmsoZGVzYyhvbHlwZXJjKSksCiAgICBwYXJhcmFuayA9IGRlbnNlX3JhbmsoZGVzYyhwYXJhcGVyYykpCiAgKSAlPiUKICB1bmdyb3VwKCkKCnBfZmVtYWxlIDwtIGNvdW50cnlfcmFua3NfZ2VuZGVyICU+JQogIGZpbHRlcihnZW5kZXIgPT0gImZlbWFsZSIpICU+JQogIGdncGxvdChhZXMoeCA9IG9seXJhbmssIHkgPSBwYXJhcmFuaywgbGFiZWwgPSBjb3VudHJ5KSkgKwogIGdlb21fcG9pbnQoY29sb3IgPSAic3RlZWxibHVlIiwgc2l6ZSA9IDIpICsKICBnZW9tX3RleHQodmp1c3QgPSAtMC41LCBzaXplID0gMi42KSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBGQUxTRSwgY29sb3IgPSAicmVkIiwgbGluZXR5cGUgPSAiZGFzaGVkIikgKwogIHNjYWxlX3hfcmV2ZXJzZShsaW1pdHMgPSBjKDYxLCAxKSkgKwogIHNjYWxlX3lfcmV2ZXJzZShsaW1pdHMgPSBjKDU2LCAxKSkgKwogIGxhYnModGl0bGUgPSAiZmVtYWxlIiwgeCA9ICJPbHltcGljIFJhbmsgKDEgPSBIaWdoZXN0IFNoYXJlKSIsCiAgICAgICB5ID0gIlBhcmFseW1waWMgUmFuayAoMSA9IEhpZ2hlc3QgU2hhcmUpIikgKwogIHRoZW1lX21pbmltYWwoKQoKIyBjYW50IHVzZSBvbmUgbWF4IGZvciBib3RoIG1hbGUgYW5kIGZlbWFsZSBjYXVzZSBpdCBsb29rcyB0byBtZXNzeQptYXhfeF9tYWxlIDwtIG1heChjb3VudHJ5X3JhbmtzX2dlbmRlciRvbHlyYW5rW2NvdW50cnlfcmFua3NfZ2VuZGVyJGdlbmRlcj09Im1hbGUiXSwgbmEucm0gPSBUUlVFKQoKcF9tYWxlIDwtIGNvdW50cnlfcmFua3NfZ2VuZGVyICU+JQogIGZpbHRlcihnZW5kZXIgPT0gIm1hbGUiKSAlPiUKICBnZ3Bsb3QoYWVzKHggPSBvbHlyYW5rLCB5ID0gcGFyYXJhbmssIGxhYmVsID0gY291bnRyeSkpICsKICBnZW9tX3BvaW50KGNvbG9yID0gInN0ZWVsYmx1ZSIsIHNpemUgPSAyKSArCiAgZ2VvbV90ZXh0KHZqdXN0ID0gLTAuNSwgc2l6ZSA9IDIuNikgKwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlID0gRkFMU0UsIGNvbG9yID0gInJlZCIsIGxpbmV0eXBlID0gImRhc2hlZCIpICsKICBzY2FsZV94X3JldmVyc2UobGltaXRzID0gYyhtYXhfeF9tYWxlLCAxKSkgKwogIHNjYWxlX3lfcmV2ZXJzZShsaW1pdHMgPSBjKDY2LCAxKSkgKwogIGxhYnModGl0bGUgPSAibWFsZSIsIHggPSAiT2x5bXBpYyBSYW5rICgxID0gSGlnaGVzdCBTaGFyZSkiLAogICAgICAgeSA9ICJQYXJhbHltcGljIFJhbmsgKDEgPSBIaWdoZXN0IFNoYXJlKSIpICsKICB0aGVtZV9taW5pbWFsKCkKCnBfZmVtYWxlICsgcF9tYWxlICsgcGxvdF9hbm5vdGF0aW9uKHRpdGxlID0gIlBsb3R0ZWQgc2VwYXJhdGVseSBmb3IgZmVtYWxlIGFuZCBtYWxlIHBhcnRpY2lwYW50cyIpCgojIFNwZWFybWFuIGNvcnJlbGF0aW9uIGJ5IGdlbmRlciAKc3BlYXJtYW5fYnlfZ2VuZGVyIDwtIGNvdW50cnlfcmFua3NfZ2VuZGVyICU+JQogIGdyb3VwX2J5KGdlbmRlcikgJT4lCiAgc3VtbWFyaXNlKHRpZHkoY29yLnRlc3Qob2x5cmFuaywgcGFyYXJhbmssIG1ldGhvZCA9ICJzcGVhcm1hbiIpKSwgLmdyb3VwcyA9ICJkcm9wIikKCnBhbmRlcihzcGVhcm1hbl9ieV9nZW5kZXIpCmBgYAoKQW5oYW5kIGRlciBvYmlnZW4gS29ycmVsYXRpb25zZGlhZ3JhbW1lIHVuZCBkZXIgV2VydGUgaW0gS29ycmVsYXRpb25zdGVzdCBsw6Rzc3Qgc2ljaCBlcmtlbm5lbiwgZGFzcyB0YXRzw6RjaGxpY2ggZWluZSBldHdhcyBzdMOkcmtlcmUgS29ycmVsYXRpb24gendpc2NoZW4gb2x5bXBpc2NoZW0gRXJmb2xnIHVuZCBwYXJhbHltcGlzY2hlbSBFcmZvbGcgaW4gZGVyIEZyYXVlbmdydXBwZSBiZXN0ZWh0LCB3YXMgZGllIGZyw7xoZXJlIEh5cG90aGVzZSB3aWRlcmxlZ2VuIHfDvHJkZS4KCiMjIEtvcnJlbGF0aW9uIGJhc2llcmVuZCBhdWYgU3BvcnQKClVtIGRpZSBMZWlzdHVuZ2VuIGRlciBMw6RuZGVyIGJlaSBkZW4gUGFyYWx5bXBpY3MgdW5kIE9seW1waXNjaGVuIFNwaWVsZW4gaW4gZWluZXIgYmVzdGltbXRlbiBTcG9ydGFydCB2ZXJnbGVpY2hlbiB6dSBrw7ZubmVuLCBtw7xzc2VuIHdpciB6dW7DpGNoc3QgZXJtaXR0ZWxuLCB3ZWxjaGUgU3BvcnRhcnRlbiBiZWkgYmVpZGVuIFNwaWVsZW4gdmVydHJldGVuIHNpbmQ6IAoKYGBge3IgY29tcGFyaXNvbiBieSBzcG9ydH0KI21hdGNoaW5nIHRoZSBzcG9ydHMKc2FtZV9uYW1lX3Nwb3J0IDwtIGZ1bmN0aW9uKHgpIHsKICB4IDwtIHN0cl90b19sb3dlcihzdHJfdHJpbSh4KSkKICB4IDwtIHN0cl9yZXBsYWNlX2FsbCh4LCAiW+KAk+KAlC1dIiwgIi0iKSAgICAgICAKICB4IDwtIHN0cl9yZXBsYWNlX2FsbCh4LCAiXFxzKyIsICIgIikgICAgICAgIAogIHggPC0gc3RyX3JlbW92ZSh4LCAiXnBhcmFcXHMqLVxccyoiKSAgICAgICAgCiAgeCA8LSBzdHJfcmVtb3ZlKHgsICJed2hlZWxjaGFpclxccysiKSAgICAgICAKICB4IDwtIHN0cl9yZW1vdmUoeCwgIlxccypcXCguKlxcKSQiKSAgICAgICAKICAKICBjYXNlX3doZW4oCiAgICBzdHJfZGV0ZWN0KHgsICJhdGhsZXRpY3N8dHJhY2tcXHMqJlxccypmaWVsZCIpIH4gImF0aGxldGljcyIsCiAgICBzdHJfZGV0ZWN0KHgsICJeY3ljbGluZ3xibXh8bW91bnRhaW4gYmlrZXx0cmFjayBjeWNsaW5nfHJvYWQgY3ljbGluZyIpIH4gImN5Y2xpbmciLAogICAgc3RyX2RldGVjdCh4LCAiY2Fub2Ugc2xhbG9tfGNhbm9lIHNwcmludHxjYW5vZWluZ3xwYXJhY2Fub2V8Y2Fub2VcXGIiKSB+ICJjYW5vZSIsCiAgICBzdHJfZGV0ZWN0KHgsICJlcXVlc3RyaWFuaXNtfGVxdWVzdHJpYW4iKSB+ICJlcXVlc3RyaWFuIiwKICAgIFRSVUUgfiB4CiAgKQp9CgoKb2x5bTJfbm9ybSA8LSBvbHltMiAlPiUgbXV0YXRlKHNuc3BvcnQgPSBzYW1lX25hbWVfc3BvcnQoc3BvcnQpKQpwYXJhMl9ub3JtIDwtIHBhcmEyICU+JSBtdXRhdGUoc25zcG9ydCA9IHNhbWVfbmFtZV9zcG9ydChzcG9ydCkpCgojIENvbXB1dGUgc2V0cyBvbiBub3JtYWxpemVkIG5hbWVzCm9seV9zcG9ydHMgIDwtIG9seW0yX25vcm0gJT4lIGRpc3RpbmN0KHNuc3BvcnQpICU+JSBwdWxsKCkKcGFyYV9zcG9ydHMgPC0gcGFyYTJfbm9ybSAlPiUgZGlzdGluY3Qoc25zcG9ydCkgJT4lIHB1bGwoKQoKb2x5X3Nwb3J0X29ubHkgIDwtIHNldGRpZmYob2x5X3Nwb3J0cywgIHBhcmFfc3BvcnRzKQpwYXJhX3Nwb3J0X29ubHkgPC0gc2V0ZGlmZihwYXJhX3Nwb3J0cywgb2x5X3Nwb3J0cykKY29tbW9uX3Nwb3J0cyAgIDwtIGludGVyc2VjdChvbHlfc3BvcnRzLCBwYXJhX3Nwb3J0cykKCmNhdCgiU3BvcnRhcnRlbiBiZWkgZGVuIE9seW1waXNjaGVuIGFiZXIgTklDSFQgYmVpIGRlbiBQYXJhbHltcGlzY2hlbiBTcGllbGVuOlxuIiwKICAgIGlmIChsZW5ndGgob2x5X3Nwb3J0X29ubHkpKSBwYXN0ZShzb3J0KG9seV9zcG9ydF9vbmx5KSwgY29sbGFwc2UgPSAiLCAiKSBlbHNlICIobm9uZSkiLCAiXG5cbiIpCmNhdCgiU3BvcnRhcnRlbiBiZWkgZGVuIFBhcmFseW1waXNjaGVuIFNwaWVsZW4gZW50aGFsdGVuIGFiZXIgTklDSFQgYmVpIGRlbiBPbHltcGlzY2hlbjpcbiIsCiAgICBpZiAobGVuZ3RoKHBhcmFfc3BvcnRfb25seSkpIHBhc3RlKHNvcnQocGFyYV9zcG9ydF9vbmx5KSwgY29sbGFwc2UgPSAiLCAiKSBlbHNlICIobm9uZSkiLCAiXG5cbiIpCmNhdCgiU3BvcnRhcnRlbiBwcsOkc2VudCBiZWkgZGVuIE9seW1waXNjaGVuIHVuZCBQYXJhbHltcGlzY2hlbiBTcGllbGVuOlxuIiwKICAgIGlmIChsZW5ndGgoY29tbW9uX3Nwb3J0cykpIHBhc3RlKHNvcnQoY29tbW9uX3Nwb3J0cyksIGNvbGxhcHNlID0gIiwgIikgZWxzZSAiKG5vbmUpIiwgIlxuXG4iKQoKYWxsX2dhbWVzX2NvbW1vbl9zcG9ydHMgPC0gYWxsX2dhbWVzICU+JQogIG11dGF0ZShzbnNwb3J0X3N0ZCA9IHNhbWVfbmFtZV9zcG9ydChzcG9ydCkpICU+JQogIGZpbHRlcihzbnNwb3J0X3N0ZCAlaW4lIGNvbW1vbl9zcG9ydHMpCgpgYGAKClVtIGZlc3R6dXN0ZWxsZW4sIG9iIGVzIGVpbmVuIFp1c2FtbWVuaGFuZyB6d2lzY2hlbiBkZW4gUGFyYWx5bXBpc2NoZW4gdW5kIGRlbiBPbHltcGlzY2hlbiBTcGllbGVuIGluIGVpbmVyIGJlc3RpbW10ZW4gU3BvcnRhcnQgZ2lidCwgaGFiZW4gd2lyIGbDvHIgamVkZSBTcG9ydGFydCBkZW4gUGVhcnNvbi1Lb3JyZWxhdGlvbnNrb2VmZml6aWVudGVuIGJlcmVjaG5ldC4KCmBgYHtyIGNvcnJlbGF0aW9uIHBsb3RzIGJ5IHNwb3J0IGV2ZW50fQoKY29yc19ieV9zcG9ydCA8LSBhbGxfZ2FtZXNfY29tbW9uX3Nwb3J0cyAlPiUKICBjb3VudChzbnNwb3J0X3N0ZCwgY291bnRyeSwgb3JpZ2luLCBuYW1lID0gIm4iKSAlPiUKICBncm91cF9ieShzbnNwb3J0X3N0ZCwgb3JpZ2luKSAlPiUKICBtdXRhdGUoTl90b3RhbCA9IHN1bShuKSkgJT4lCiAgdW5ncm91cCgpICU+JQogIG11dGF0ZShzaGFyZSA9IG4gLyBOX3RvdGFsKSAlPiUKICBzZWxlY3Qoc25zcG9ydF9zdGQsIGNvdW50cnksIG9yaWdpbiwgc2hhcmUpICU+JQogIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBvcmlnaW4sIHZhbHVlc19mcm9tID0gc2hhcmUsIHZhbHVlc19maWxsID0gMCkgJT4lCiAgcmVuYW1lKG9seXBlcmMgPSBPbHltcGljLCBwYXJhcGVyYyA9IFBhcmFseW1waWMpICU+JQogIGdyb3VwX2J5KHNuc3BvcnRfc3RkKSAlPiUKICBmaWx0ZXIoCiAgICBuKCkgPj0gMywgICAgICAgICAgICAgICAgICAgICAgCiAgICBzZChvbHlwZXJjKSA+IDAsICAgICAgICAgICAgICAKICAgIHNkKHBhcmFwZXJjKSA+IDAKICApICU+JQogIHN1bW1hcmlzZSgKICAgIG5fY291bnRyaWVzID0gbigpLAogICAgYnJvb206OnRpZHkoY29yLnRlc3Qob2x5cGVyYywgcGFyYXBlcmMsIG1ldGhvZCA9ICJwZWFyc29uIikpLAogICAgLmdyb3VwcyA9ICJkcm9wIgogICkgJT4lCiAgIyBuaWNlciBjb2x1bW4gbmFtZXMKICByZW5hbWUoCiAgICBzcG9ydCA9IHNuc3BvcnRfc3RkLAogICAgciAgICAgID0gZXN0aW1hdGUsCiAgICB0ICAgICAgPSBzdGF0aXN0aWMsCiAgICBkZiAgICAgPSBwYXJhbWV0ZXIsCiAgICBwICAgICAgPSBwLnZhbHVlCiAgKSAlPiUKICBhcnJhbmdlKGRlc2MocikpCgpwYW5kZXIoY29yc19ieV9zcG9ydCkKCmBgYAoKQXVzIGRpZXNlbiBLb3JyZWxhdGlvbnNrb2VmZml6aWVudGVuIGzDpHNzdCBzaWNoIGVya2VubmVuLCBkYXNzIGVzIGVpbmUgc3RhcmtlIEtvcnJlbGF0aW9uIGluIGRlciBMZWljaHRhdGhsZXRpayB1bmQgZWluZSBtb2RlcmF0ZSBLb3JyZWxhdGlvbiBpbSBGZWNodGVuLCBTY2h3aW1tZW4sIEJvZ2Vuc2NoaWXDn2VuIHVuZCBUaXNjaHRlbm5pcyBnaWJ0LiBEaWUgYW5kZXJlbiBTcG9ydGFydGVuIHdlaXNlbiBlaW5lIHNlaHIgc2Nod2FjaGUgb2RlciBnYXIga2VpbmUgS29ycmVsYXRpb24gYXVmLgoK
+ + +
+
+ +
+ + + + + + + + + + + + + + + + +