Wie bereits angekündigt, schließt sich dieses Kapitel deshalb nahtlos and das vorausgehende Kapitel 3 zur Sentimentanalyse an, weil wir im Prinzip nichts neues dazulernen müssen, jedenfalls nicht, was die Funktionalität von quanteda angeht. Mit der Funktion dictionary und dem Wissen darüber, wie wir ein Lexikon auf eine DFM anwenden, schlagen wir gewissenmaßen zwei Fliegen mit einer Klappe, denn die Logik hinter den Themen– oder Politikfeld–Lexika, die in diesem Kapitel zur Anwendung kommen, gleicht der Logik von Sentiment-Lexika. Der wichtigste Unterschied besteht darin, dass die in diesem Kapitel behandelten Lexika i.d.R. eine ganze Reihe von Kategorien kennen, nicht nur die Typen positiv und negativ.

Auch hier arbeiten wir wieder mit einer Reihe ganz unterschiedlicher Lexika und Korpora. Hier ein Überblick über die Lexika (die Korpora werden im Überblick genauer beschrieben), von denen alle bis auf das LIWC-Lexikon englischsprachig sind:

Wie die Namen und eine Lektüre der Datensatzdokumentationen verrät, bilden diesen Lexika unterschiedliche Themenbereiche und Politikfelder ab. Dieser Ansatz ist vielsprechender, als es möglicherweise zunächst erscheint: Makroökonomie oder Ortsnamen sind sehr kontrollierte semantische Bereiche, die sich relativ präzise und erschöpfend mit einem Lexikon abbilden lassen.

Wir starten mit dem EU–Speech–Korpus, an dem wir gleich mehrere politische Lexika ausprobieren, und machen dann weiter mit dem UN–Generaldebattenkorpus, welches wir anhand unterschiedlicher Policy–Lexika untersuchen. Schließlich analysieren wir deutschsprachige Facebook–Kommentare, auf die wir die deutsche Fassung des LIWC–Lexikons anwenden, vermutlich eines der umfangreichsten Inhaltsanalyse–Lexikon überhaupt.

Installation und Laden der benötigten R-Bibliotheken

Wieder werden zunächst die notwendigen Bibliotheken geladen.

if(!require("quanteda")) {install.packages("quanteda"); library("quanteda")}
if(!require("readtext")) {install.packages("readtext"); library("readtext")}
if(!require("tidyverse")) {install.packages("tidyverse"); library("tidyverse")}
if(!require("lubridate")) {install.packages("lubridate"); library("lubridate")}
theme_set(theme_minimal())

Anschließend wird das umfangreiche EU Speech-Korpus eingelesen, auf das sich die vorwiegend politischen Lexika auf unserer Liste gut anwenden lassen.

load("daten/euspeech/euspeech.korpus.RData")

Ein Blick in die Metadaten gibt uns einen Eindruck der Korpus-Zusammensetzung. Im EU Speech-Korpus sind Reden von hochrangigen Vetretern der EU-Mitgliedstaaten gespeichert, dazu Reden von Mitgliedern des Europaparlaments und von Vetretern der EU-Kommission und der EZB. Alle Reden sind in englischer Sprache gespeichert, zum Teil als Übersetzung. Zudem gibt es noch Metadaten zu Sprechern, Länge und Anlass der Reden. Die Variable Sentences ist hier nicht aussagekräftig, weil das Korpus bereits vor dem Einlesen in R in tokenisierter Form vorlag.

head(korpus.euspeech.stats)

Erstellung und Anwendung eines einfachen themenspezifischen Lexikons

Im vorausgehenden Kapitel haben wir eingangs ein sehr simples Lexikon definiert, um die Struktur dieses Objekts in quanteda zu erläutern. Wir haben dieses Lexikon allerdings nicht angewandt, sondern sind gleich dazu übergangen, ein bereits fertiges Sentimentlexikon zu laden. Jetzt ist es an der Zeit, ein wenig mehr Arbeit in ein Ad hoc-Lexikon zu investieren, und dabei die Tatsache auszunutzen, dass ein quanteda-dictionary aus einer Reihe von Begriffen zu ganz unterschiedlichen Kategorien bestehen kann. Die im folgenden Beispiel für die Kategorie Populismus verwendete Wortliste stammt aus Rooduijn und Pauwels (2011) und wird in dieser Übung von Ken Benoit (dem Erfinder von quanteda) herangezogen, während wir die zweite Wortliste zur Kategorie Liberalismus ad hoc selbst zusammengestellt haben.

populismus.liberalismus.lexikon <- dictionary(
  list(
    populism = c("elit*", "consensus*", "undemocratic*", "referend*", "corrupt*", "propagand", "politici*", "*deceit*", "*deceiv*", "*betray*", "shame*", "scandal*", "truth*", "dishonest*", "establishm*", "ruling*"),
    liberalism = c("liber*", "free*", "indiv*", "open*", "law*", "rules", "order", "rights", "trade", "global", "inter*", "trans*", "minori*", "exchange", "market*")))
populismus.liberalismus.lexikon
Dictionary object with 2 key entries.
- [populism]:
  - elit*, consensus*, undemocratic*, referend*, corrupt*, propagand, politici*, *deceit*, *deceiv*, *betray*, shame*, scandal*, truth*, dishonest*, establishm*, ruling*
- [liberalism]:
  - liber*, free*, indiv*, open*, law*, rules, order, rights, trade, global, inter*, trans*, minori*, exchange, market*

Wie zuvor wenden wir das Lexikon auf unsere Daten an, dabei gruppieren wir hier zunächst nach der Variable country (die EU-Kommission, das EU-Parlament, sowie die EZB werden hier der Einfachheit halber auch als “countries” behandelt).

meine.dfm.eu <- dfm(korpus.euspeech, groups = "country", dictionary = populismus.liberalismus.lexikon)
meine.dfm.eu.prop <- dfm_weight(meine.dfm.eu, scheme = "prop")
convert(meine.dfm.eu.prop, "data.frame")

Ein Plot sparen wir uns an dieser Stelle. Es ist auch so sofort offensichtlich, dass Treffer auf die Kategorie Liberalismus im Vergleich klar gegenüber der Kategorie Populismus überwiegen, was angesichts der Zusammensetzung der Daten kaum überrascht. Allerdings scheinen die Unterschiede zwischen den beiden EU-Behörden Kommission und EZB, gefolgt von Deutschland, den Niederlanden und Tschechien einerseits, und Griechenland, Spanien und dem EU-Parlament andererseits den (sehr hemdsärmeligen) Kontrast, den unser Lexikons unterstellt, grundsätzlich zu bestätigen. Ist die erste Gruppe sehr wenig populistisch (jedenfalls nach Definition dieses simplen Lexikons), sieht das für die zweite Gruppe bereits etwas anders aus.

Als nächstes berechnen wir den relativen Populismus-Anteil nach Jahren im Zeitrum von 2007-2015, und unterscheiden dabei zwischen zwei Typen von Akteuren: nationalen Regierungen (hier inkl. EU-Parlament) einerseits und EU-Behörden (EU–Kommission und EZB) andererseits.

meine.dfm.eu <- dfm(korpus.euspeech, groups = c("Typ", "Jahr"), dictionary = populismus.liberalismus.lexikon)
meine.dfm.eu.prop <- dfm_weight(meine.dfm.eu, scheme = "prop")
eu.themen <- convert(meine.dfm.eu.prop, "data.frame") %>% 
  mutate(Typ = str_split(doc_id, "\\.", simplify = T)[,1]) %>% 
  mutate(Jahr = str_split(doc_id, "\\.", simplify = T)[,2]) %>% 
  select(Typ, Jahr, populism, liberalism)
eu.themen

Auch hier überspringen wir das Plot. Während der Populismus-Anteil bei den EU–Behörden relativ konstant bei circa 2% liegt, ist er bei den Vertretern der EU-Mitgliedstaaten mit 7-9% deutlich höher.

Bevor wir uns im nächsten Schritt “richtigen” Lexika zuwenden, die deutlich umfangreicher sind als unser Populismus–Lexikon, betrachten wir noch kurz die Variation innerhalb der Reden, da diese relativ lang sind, und sich so auch eine Themenverteilung berechnen lässt, ohne dass man mithilfe von group die DFM nach einer bestimmten Variable zusammenfasst. Das folgende Plot (welches Boxplot und Scatterplot kombiniert) zeigt die Variation beim Populismus-Anteil nach Land innerhalb einzelner Reden.

meine.dfm.eu <- dfm(korpus.euspeech, dictionary = populismus.liberalismus.lexikon)
meine.dfm.eu.prop <- dfm_weight(meine.dfm.eu, scheme = "prop")
eu.poplib <- convert(meine.dfm.eu.prop, "data.frame") %>% 
  bind_cols(korpus.euspeech.stats) %>% 
  filter(length >= 1200, populism > 0 | liberalism > 0)
ggplot(eu.poplib, aes(country, populism)) + 
  geom_boxplot(outlier.size = 0) + 
  geom_jitter(aes(country,populism), position = position_jitter(width = 0.4, height = 0), alpha = 0.1, size = 0.2, show.legend = F) + 
  theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1)) + 
  xlab("") + ylab("Populismus-Anteil (%)") + 
  ggtitle("Populismus-Anteil in Reden des EU-Speech-Korpus")

Wie die Dichte der Punkte im Plot zeigt, ist der Anteil der Kommission am Korpus insgesamt groß, auch wenn das Populismus-Niveau (gemessen mit unserem primitiven Lexikon) insgesamt niedrig ist. Desweiteren erkennen wir eine größere Bandbreite bei den nationalen Regierungen (Griechenland vs. Deutschland) als bei den Behörden.

Hier sollte man Ausreißer (etwa bei der EU-Kommision) mit einem Populismus-Anteil von 100% nicht überschätzen. Zwar haben wir zuvor sehr kurze Reden ausgeschlossen (mit length >= 1200), aber es dürfte trotzdem solche Texte geben, die nur durch eine handvoll Treffer auf eine der beiden Kateogorien ein solches Ergebnis erreichen (dies gielt auch für einen Liberalismus–Anteil von 100%). Wie auch beim Sentiment gilt: Es handelt sich um heuristische Verfahren, und mit einem besseren Lexikon lässt sich die Genauigkeit leicht steigern.

Anwendung der Lexika Policy Agendas und Laver-Garry auf das EU Speech–Korpus

Es muss betont werden, dass unser Ad-hoc-Lexikon sicherlich nicht ausreicht, um den Stil oder das Themenspektrum politischer Debatten adäquat anzubilden. Wir erstellen deshalb jetzt zwei quanteda-Lexika auf Grundlage des Policy Agenda–Lexikons und auf Basis des Laver Garry-Lexikons. Bei beiden Lexika handelt es sich um in der Poltikwissenschaft vielfach eingesetzte Resourcen für die Bestimmung von Politikfeldern. Die Lexikon–Daten dazu kommen für Policy Agendas aus einer schon vorbereiteten RData-Datei und für Laver Garry aus einer Textdatei im Format “WordStat”, welches der dictionary-Befehl bereits kennt.

Wir schauen in beide Lexika mit dem Befehl head hinein – man erkennt gleich den großen Umfang.

load("lexika/policy_agendas_english.RData")
policyagendas.lexikon <- dictionary(dictLexic2Topics)
lavergarry.lexikon <- dictionary(file = "lexika/LaverGarry.cat", format = "wordstat")
head(policyagendas.lexikon, 2)
Dictionary object with 2 key entries.
- [macroeconomics]:
  - aggregate demand, aggregate supply, business cycle, demand shock, demand side, demand-side, econom, employment rate, full employment, food price, industr, keynes, bank of canada, bank of england, bear market, bretton woods, budget, bull market, changing demographic, coinage [ ... and 62 more ]
- [civil_rights]:
  - civil right, ableism, abortion, access to info, african american, anti-choice, anti-semit, bill 101, charter of the french language, biphobi, bisexual, charter of rights, civil libert, disabilit, discriminat, diversity, equal employm, equal opportunit, equal right, equalit [ ... and 65 more ]
head(lavergarry.lexikon, 2)
Dictionary object with 2 primary key entries and 2 nested levels.
- [CULTURE]:
  - people, war_in_iraq, civil_war
  - [CULTURE-HIGH]:
    - art, artistic, dance, galler*, museum*, music*, opera*, theatre*
  - [CULTURE-POPULAR]:
    - media
  - [SPORT]:
    - angler*
- [ECONOMY]:
  - [+STATE+]:
    - accommodation, age, ambulance, assist, benefit, care, carer*, child*, class, classes, clinics, collective*, contribution*, cooperative*, co-operative*, deprivation, disabilities, disadvantaged, educat*, elderly [ ... and 30 more ]
  - [=STATE=]:
    - accountant, accounting, accounts, advert*, airline*, airport*, audit*, bank*, bargaining, breadwinner*, budget*, buy*, cartel*, cash*, charge*, commerce*, compensat*, consum*, cost*, credit* [ ... and 51 more ]
  - [-STATE-]:
    - assets, autonomy, barrier*, bid, bidders, bidding, burden*, charit*, choice*, compet*, confidence, confiscatory, constrain*, contracting*, contractor*, controlled, controlling, controls, corporate, corporation* [ ... and 42 more ]

Die beiden Lexika zeichnen sich dafurch aus, dass sie geschachtelte Kategorien aufweisen, unter denen sich eine Reihe von Unterkategorien verbergen.

Nun berechnen wir je eine DFM für jedes Lexikon und gruppieren diese einmal nach Land und einmal nach Jahr.

meine.dfm.eu.pa <- dfm(korpus.euspeech, groups = "country", dictionary = policyagendas.lexikon)
meine.dfm.eu.lg <- dfm(korpus.euspeech, groups = "Jahr", dictionary = lavergarry.lexikon)

Das folgende Plot zeigt die Themenverteilung innerhalb des Korpus nach Land, auf Basis des Policy Agenda-Lexikons. Wir haben zuvor einige Themen ausgewählt und auf der Grundlage dieser Auswahl die Anteile berechnet. Andere Bereiche haben wir unter other zusammengefasst.

eu.themen.pa <- convert(meine.dfm.eu.pa, "data.frame") %>%
  rename(Land = doc_id) %>%
  select(Land, macroeconomics, finance, foreign_trade, labour, healthcare, immigration, education, intl_affairs, defence) %>%
  gather(macroeconomics:defence, key = "Thema", value = "Anteil") %>% 
  group_by(Land) %>% 
  mutate(Anteil = Anteil/sum(Anteil)) %>% 
  mutate(Thema = as_factor(Thema))
ggplot(eu.themen.pa, aes(Land, Anteil, colour = Thema, fill = Thema)) + 
  geom_bar(stat="identity") + 
  scale_colour_brewer(palette = "Set1") + 
  scale_fill_brewer(palette = "Pastel1") + 
  ggtitle("Themen im EU-Speech-Korpus auf Basis des Policy Agendas-Lexikons") + 
  xlab("") + ylab("Themen-Anteil (%)") + 
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

Die Anteilsverteilung dürfte in Teilen kaum überraschen. Die EZB und in einem etwas geringerem Umfang auch die Kommission beschäftigen sich viel mit Makroökonomie und Finanzen, Frankreich und Spanien mit dem Arbeitsmarkt, und Deutschland und die Niederlande viel mit Handel. Interessant sind die Themenfelder Verteididung (Niederlande, Frankreich, Großbritannien), Zuwanderung (Tschechien) und Bildung (Frankreich, Großbritannien). Die geringe Relevanz des Zuwanderungsthemas in Italien und Griechenland belegt vielleicht eine Diskrepanz zwischen öffentlicher Meinung und der Regierungsagenda –– jedenfalls im Zeitraum 2007–2015.

Wir wenden uns nun dem Laver-Garry-Lexikon zu, welches wir gezielt auf den Zeitverlauf 2007-2015 anwenden, um Veränderungen in den Blick zunehmen. Die vielen Umformungsschritte werden notwendig, weil das Lexikon stark geschachtelte Kategorien besitzt, die wir zur besseren Übersichtlichkeit zum Teil zusammenfassen und umbennnen.

eu.themen.lg <- dfm_weight(meine.dfm.eu.lg, scheme = "prop") %>% 
  convert("data.frame") %>% 
  rename(Jahr = doc_id) %>% 
  mutate(culture = `CULTURE` + `CULTURE.CULTURE-HIGH` + `CULTURE.CULTURE-POPULAR` + `CULTURE.SPORT`) %>% 
  mutate(economy = `ECONOMY.+STATE+` + `ECONOMY.=STATE=` + `ECONOMY.-STATE-`) %>% 
  mutate(environment = `ENVIRONMENT.CON ENVIRONMENT` + `ENVIRONMENT.PRO ENVIRONMENT`) %>% 
  mutate(institutions = `INSTITUTIONS.CONSERVATIVE` + `INSTITUTIONS.NEUTRAL` + `INSTITUTIONS.RADICAL`) %>%
  mutate(values = `VALUES.CONSERVATIVE` + `VALUES.LIBERAL`) %>%
  mutate(law_and_order = `LAW_AND_ORDER.LAW-CONSERVATIVE`) %>%
  mutate(rural = `RURAL`) %>%
  mutate(other = `GROUPS.ETHNIC` + `GROUPS.WOMEN` + `LAW_AND_ORDER.LAW-LIBERAL` + `URBAN`) %>% 
  select(Jahr, culture:other) %>% 
  gather(Thema, Prozent, culture:other) %>% 
  filter(!Thema %in% c("economy", "institutions", "values", "culture", "rural", "other"))
ggplot(eu.themen.lg, aes(Jahr, Prozent, group = Thema, col = Thema)) + 
  geom_line(size = 1) + 
  scale_colour_brewer(palette = "Set1") + 
  ggtitle("Themen im EU-Speech-Korpus auf Grundlage des Laver-Garry-Lexikons") + 
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) + 
  xlab("") + ylab("Themen-Anteil (%)")

Wieso haben wir so viele Kategorien ausgelassen? Die Themenfelder economy und institutions sind sehr stark ausgeprägt und verändern sich im Untersuchungszeitraum nicht allzu merklich, daher ist es hier interessanter, sich eher kleinere Themenfelder anzusehen. Auffällig ist u.a. ein Abfallen des Themenfeldes ländlicher Raum, ein sprunghafter Anstieg des Themas innere Sicherheit und ein Nachlassen der Relevanz des Themas Umwelt.

Die behandelten Lexika bilden beide Politikfelder ab. Durch die spezialisierte Begriffswelt von Themen wie Finanz- oder Umweltpoltik wird es möglich, die Konjunktur dieser Ressorts zu quantifizieren. Eine anderen Zugang zu der automatisierten Ermittlung von Thenen beschreiben wir im nächsten Kapitel. Was aber, wenn man sich weniger für Themen, sonder eher für abstrakte Kategorien wie autokratische Argumentationsmuster oder moralisch-philosophische Grundlagen politischen Handelns interessiert?

Anwendung der Lexika Moral Foundations Theory, Simulating Pluralism und NewsMap auf das UN General Debate Corpus

Laden wir nun also zwei weitere Lexika, die sich im Gegensatz zu Policy Agendas und Laver-Garry nicht Poltikfelder beschreiben, sondern sich mehr mit politischer Argumentation befassen, das Moral Foundations Theory-Lexikon und das “Language of Democracy in Hegemonic Authoritarianism”-Lexikon von Seraphine F. Maerz]. Hier machen wir uns ähnlich wir beim Laver Garry-Lexikon die Möglichkeit in quanteda zunutzte, Lexika in bestimmten Standardformaten (hier in den Formaten LIWC und yoshikoder) einzulesen. Das erspart uns komplizierte Syntax für die Interpretation der Lexikon-Struktur.

Wieso überhaupt so viele unterschiedliche Lexika? Wieso nicht einfach das beste Lexikon nutzen, und ausschließlich damit arbeiten? Leider ist die Frage, welches Lexikon man nutzen sollte, eng mit dem Forschungsinteresse verquickt. Will man also etwas über die Sprache autoritärer Regime oder moralische Appelle in politischen Reden erfahren, brauch man andere Lexika, als wenn man den Anteil von Politikfeldern beschreiben möchte. Daher stellen wir eine ganze Reihe von Lexika vor –– und tatsächlich wäre noch zahlreiche weitere durchaus interessant, die wir hier nicht vorstellen. Hinzu kommt noch der Aspekt der Verfügbarkeit: viele Lexika sind leider kostenpflichtig, nicht in offenen Formaten gespeichert, nur unzureichend dokumentiert, oder einfach schwer auffindbar.

mft.lexikon <- dictionary(file = "lexika/moral_foundations_dictionary.dic", format = "LIWC")
maerz.lexikon <- dictionary(file = "lexika/Authoritarianism_Maerz.ykd", format = "yoshikoder")
newsmap.lexikon <- dictionary(file = "lexika/newsmap.yml", format = "YAML")
newsmap.lexikon <- dictionary(list(africa = unname(unlist(newsmap.lexikon$AFRICA)), america = unname(unlist(newsmap.lexikon$AMERICA)), asia = unname(unlist(newsmap.lexikon$ASIA)), europe = unname(unlist(newsmap.lexikon$EUROPE)), oceania = unname(unlist(newsmap.lexikon$OCEANIA))))
str(mft.lexikon)
Formal class 'dictionary2' [package "quanteda"] with 2 slots
  ..@ .Data:List of 11
  .. ..$ :List of 1
  .. .. ..$ : chr [1:16] "amity" "benefit*" "care" "caring" ...
  .. ..$ :List of 1
  .. .. ..$ : chr [1:35] "abandon*" "abuse*" "annihilate*" "attack*" ...
  .. ..$ :List of 1
  .. .. ..$ : chr [1:26] "balance*" "constant" "egalitar*" "equable" ...
  .. ..$ :List of 1
  .. .. ..$ : chr [1:18] "bias*" "bigot*" "discriminat*" "dishonest" ...
  .. ..$ :List of 1
  .. .. ..$ : chr [1:29] "ally" "cadre" "cliqu*" "cohort" ...
  .. ..$ :List of 1
  .. .. ..$ : chr [1:23] "abandon*" "apostasy" "apostate" "betray*" ...
  .. ..$ :List of 1
  .. .. ..$ : chr [1:45] "abide" "allegian*" "authorit*" "bourgeoisie" ...
  .. ..$ :List of 1
  .. .. ..$ : chr [1:37] "agitat*" "alienate" "apostasy" "apostate" ...
  .. ..$ :List of 1
  .. .. ..$ : chr [1:35] "abstemiousness" "abstention" "abstinen*" "austerity" ...
  .. ..$ :List of 1
  .. .. ..$ : chr [1:54] "adulter*" "apostasy" "apostate" "blemish" ...
  .. ..$ :List of 1
  .. .. ..$ : chr [1:41] "bad" "blameless" "canon" "character" ...
  ..@ meta :List of 3
  .. ..$ system:List of 5
  .. .. ..$ package-version:Classes 'package_version', 'numeric_version'  hidden list of 1
  .. .. .. ..$ : int [1:3] 2 1 2
  .. .. ..$ r-version      :Classes 'R_system_version', 'package_version', 'numeric_version'  hidden list of 1
  .. .. .. ..$ : int [1:3] 4 0 2
  .. .. ..$ system         : Named chr [1:3] "Darwin" "x86_64" "cp"
  .. .. .. ..- attr(*, "names")= chr [1:3] "sysname" "machine" "user"
  .. .. ..$ directory      : chr "/Users/cp/Documents/GitHub/inhaltsanalyse-mit-r.de"
  .. .. ..$ created        : Date[1:1], format: "2021-01-23"
  .. ..$ object:List of 2
  .. .. ..$ valuetype: chr "glob"
  .. .. ..$ separator: chr " "
  .. ..$ user  : list()
str(maerz.lexikon)
Formal class 'dictionary2' [package "quanteda"] with 2 slots
  ..@ .Data:List of 1
  .. ..$ :List of 2
  .. .. ..$ autocratic:List of 2
  .. .. .. ..$ 1 autocratic procedures:List of 2
  .. .. .. .. ..$ authoritarian law and order:List of 1
  .. .. .. .. .. ..$ : chr [1:43] "anarch*" "assault*" "betrayal" "chaos" ...
  .. .. .. .. ..$ maintenance of power       :List of 1
  .. .. .. .. .. ..$ : chr [1:30] "authority" "continu*" "crown" "custod*" ...
  .. .. .. ..$ 2 illiberalism         :List of 3
  .. .. .. .. ..$ 1 autocratic procedures :List of 2
  .. .. .. .. .. ..$ authoritarian law and order:List of 1
  .. .. .. .. .. .. ..$ : chr [1:43] "anarch*" "assault*" "betrayal" "chaos" ...
  .. .. .. .. .. ..$ maintenance of power       :List of 1
  .. .. .. .. .. .. ..$ : chr [1:30] "authority" "continu*" "crown" "custod*" ...
  .. .. .. .. ..$ nationalism, paternalism:List of 1
  .. .. .. .. .. ..$ : chr [1:23] "allah" "almighty" "christ" "christianity" ...
  .. .. .. .. ..$ traditionalism          :List of 1
  .. .. .. .. .. ..$ : chr [1:25] "ancestors" "brothers" "discipline" "family" ...
  .. .. ..$ democratic:List of 3
  .. .. .. ..$ autocratic             :List of 2
  .. .. .. .. ..$ 1 autocratic procedures:List of 2
  .. .. .. .. .. ..$ authoritarian law and order:List of 1
  .. .. .. .. .. .. ..$ : chr [1:43] "anarch*" "assault*" "betrayal" "chaos" ...
  .. .. .. .. .. ..$ maintenance of power       :List of 1
  .. .. .. .. .. .. ..$ : chr [1:30] "authority" "continu*" "crown" "custod*" ...
  .. .. .. .. ..$ 2 illiberalism         :List of 3
  .. .. .. .. .. ..$ 1 autocratic procedures :List of 2
  .. .. .. .. .. .. ..$ authoritarian law and order:List of 1
  .. .. .. .. .. .. .. ..$ : chr [1:43] "anarch*" "assault*" "betrayal" "chaos" ...
  .. .. .. .. .. .. ..$ maintenance of power       :List of 1
  .. .. .. .. .. .. .. ..$ : chr [1:30] "authority" "continu*" "crown" "custod*" ...
  .. .. .. .. .. ..$ nationalism, paternalism:List of 1
  .. .. .. .. .. .. ..$ : chr [1:23] "allah" "almighty" "christ" "christianity" ...
  .. .. .. .. .. ..$ traditionalism          :List of 1
  .. .. .. .. .. .. ..$ : chr [1:25] "ancestors" "brothers" "discipline" "family" ...
  .. .. .. ..$ 3 liberalism           :List of 3
  .. .. .. .. ..$ autocratic       :List of 2
  .. .. .. .. .. ..$ 1 autocratic procedures:List of 2
  .. .. .. .. .. .. ..$ authoritarian law and order:List of 1
  .. .. .. .. .. .. .. ..$ : chr [1:43] "anarch*" "assault*" "betrayal" "chaos" ...
  .. .. .. .. .. .. ..$ maintenance of power       :List of 1
  .. .. .. .. .. .. .. ..$ : chr [1:30] "authority" "continu*" "crown" "custod*" ...
  .. .. .. .. .. ..$ 2 illiberalism         :List of 3
  .. .. .. .. .. .. ..$ 1 autocratic procedures :List of 2
  .. .. .. .. .. .. .. ..$ authoritarian law and order:List of 1
  .. .. .. .. .. .. .. .. ..$ : chr [1:43] "anarch*" "assault*" "betrayal" "chaos" ...
  .. .. .. .. .. .. .. ..$ maintenance of power       :List of 1
  .. .. .. .. .. .. .. .. ..$ : chr [1:30] "authority" "continu*" "crown" "custod*" ...
  .. .. .. .. .. .. ..$ nationalism, paternalism:List of 1
  .. .. .. .. .. .. .. ..$ : chr [1:23] "allah" "almighty" "christ" "christianity" ...
  .. .. .. .. .. .. ..$ traditionalism          :List of 1
  .. .. .. .. .. .. .. ..$ : chr [1:25] "ancestors" "brothers" "discipline" "family" ...
  .. .. .. .. ..$ liberal values   :List of 1
  .. .. .. .. .. ..$ : chr [1:26] "authoritarian*" "autocra*" "cruel*" "dictator*" ...
  .. .. .. .. ..$ woman, minorities:List of 1
  .. .. .. .. .. ..$ : chr [1:21] "dialect*" "ethni*" "gay*" "gender" ...
  .. .. .. ..$ 4 democratic procedures:List of 4
  .. .. .. .. ..$ autocratic           :List of 2
  .. .. .. .. .. ..$ 1 autocratic procedures:List of 2
  .. .. .. .. .. .. ..$ authoritarian law and order:List of 1
  .. .. .. .. .. .. .. ..$ : chr [1:43] "anarch*" "assault*" "betrayal" "chaos" ...
  .. .. .. .. .. .. ..$ maintenance of power       :List of 1
  .. .. .. .. .. .. .. ..$ : chr [1:30] "authority" "continu*" "crown" "custod*" ...
  .. .. .. .. .. ..$ 2 illiberalism         :List of 3
  .. .. .. .. .. .. ..$ 1 autocratic procedures :List of 2
  .. .. .. .. .. .. .. ..$ authoritarian law and order:List of 1
  .. .. .. .. .. .. .. .. ..$ : chr [1:43] "anarch*" "assault*" "betrayal" "chaos" ...
  .. .. .. .. .. .. .. ..$ maintenance of power       :List of 1
  .. .. .. .. .. .. .. .. ..$ : chr [1:30] "authority" "continu*" "crown" "custod*" ...
  .. .. .. .. .. .. ..$ nationalism, paternalism:List of 1
  .. .. .. .. .. .. .. ..$ : chr [1:23] "allah" "almighty" "christ" "christianity" ...
  .. .. .. .. .. .. ..$ traditionalism          :List of 1
  .. .. .. .. .. .. .. ..$ : chr [1:25] "ancestors" "brothers" "discipline" "family" ...
  .. .. .. .. ..$ 3 liberalism         :List of 3
  .. .. .. .. .. ..$ autocratic       :List of 2
  .. .. .. .. .. .. ..$ 1 autocratic procedures:List of 2
  .. .. .. .. .. .. .. ..$ authoritarian law and order:List of 1
  .. .. .. .. .. .. .. .. ..$ : chr [1:43] "anarch*" "assault*" "betrayal" "chaos" ...
  .. .. .. .. .. .. .. ..$ maintenance of power       :List of 1
  .. .. .. .. .. .. .. .. ..$ : chr [1:30] "authority" "continu*" "crown" "custod*" ...
  .. .. .. .. .. .. ..$ 2 illiberalism         :List of 3
  .. .. .. .. .. .. .. ..$ 1 autocratic procedures :List of 2
  .. .. .. .. .. .. .. .. ..$ authoritarian law and order:List of 1
  .. .. .. .. .. .. .. .. .. ..$ : chr [1:43] "anarch*" "assault*" "betrayal" "chaos" ...
  .. .. .. .. .. .. .. .. ..$ maintenance of power       :List of 1
  .. .. .. .. .. .. .. .. .. ..$ : chr [1:30] "authority" "continu*" "crown" "custod*" ...
  .. .. .. .. .. .. .. ..$ nationalism, paternalism:List of 1
  .. .. .. .. .. .. .. .. ..$ : chr [1:23] "allah" "almighty" "christ" "christianity" ...
  .. .. .. .. .. .. .. ..$ traditionalism          :List of 1
  .. .. .. .. .. .. .. .. ..$ : chr [1:25] "ancestors" "brothers" "discipline" "family" ...
  .. .. .. .. .. ..$ liberal values   :List of 1
  .. .. .. .. .. .. ..$ : chr [1:26] "authoritarian*" "autocra*" "cruel*" "dictator*" ...
  .. .. .. .. .. ..$ woman, minorities:List of 1
  .. .. .. .. .. .. ..$ : chr [1:21] "dialect*" "ethni*" "gay*" "gender" ...
  .. .. .. .. ..$ democracy            :List of 1
  .. .. .. .. .. ..$ : chr [1:43] "bargaining" "campaign" "choice" "commission" ...
  .. .. .. .. ..$ institutional reforms:List of 1
  .. .. .. .. .. ..$ : chr [1:30] "abolition" "change" "conciliation" "corrupt*" ...
  ..@ meta :List of 3
  .. ..$ system:List of 5
  .. .. ..$ package-version:Classes 'package_version', 'numeric_version'  hidden list of 1
  .. .. .. ..$ : int [1:3] 2 1 2
  .. .. ..$ r-version      :Classes 'R_system_version', 'package_version', 'numeric_version'  hidden list of 1
  .. .. .. ..$ : int [1:3] 4 0 2
  .. .. ..$ system         : Named chr [1:3] "Darwin" "x86_64" "cp"
  .. .. .. ..- attr(*, "names")= chr [1:3] "sysname" "machine" "user"
  .. .. ..$ directory      : chr "/Users/cp/Documents/GitHub/inhaltsanalyse-mit-r.de"
  .. .. ..$ created        : Date[1:1], format: "2021-01-23"
  .. ..$ object:List of 2
  .. .. ..$ valuetype: chr "glob"
  .. .. ..$ separator: chr " "
  .. ..$ user  : list()
str(newsmap.lexikon)
Formal class 'dictionary2' [package "quanteda"] with 2 slots
  ..@ .Data:List of 5
  .. ..$ :List of 1
  .. .. ..$ : chr [1:191] "burundi" "burundian*" "bujumbura" "comoros" ...
  .. ..$ :List of 1
  .. .. ..$ : chr [1:185] "anguilla" "anguillan*" "the valley" "antigua and barbuda" ...
  .. ..$ :List of 1
  .. .. ..$ : chr [1:174] "kazakhstan" "kazakh*" "astana" "kyrgyzstan" ...
  .. ..$ :List of 1
  .. .. ..$ : chr [1:168] "belarus" "belarusian*" "minsk" "bulgaria" ...
  .. ..$ :List of 1
  .. .. ..$ : chr [1:82] "australia" "australian*" "aussie*" "oz" ...
  ..@ meta :List of 3
  .. ..$ system:List of 5
  .. .. ..$ package-version:Classes 'package_version', 'numeric_version'  hidden list of 1
  .. .. .. ..$ : int [1:3] 2 1 2
  .. .. ..$ r-version      :Classes 'R_system_version', 'package_version', 'numeric_version'  hidden list of 1
  .. .. .. ..$ : int [1:3] 4 0 2
  .. .. ..$ system         : Named chr [1:3] "Darwin" "x86_64" "cp"
  .. .. .. ..- attr(*, "names")= chr [1:3] "sysname" "machine" "user"
  .. .. ..$ directory      : chr "/Users/cp/Documents/GitHub/inhaltsanalyse-mit-r.de"
  .. .. ..$ created        : Date[1:1], format: "2021-01-23"
  .. ..$ object:List of 2
  .. .. ..$ valuetype: chr "glob"
  .. .. ..$ separator: chr " "
  .. ..$ user  : list()

Im Vergleich fällt auf, dass die drei Lexika sehr elaboriert sind, mit umfassenden Begriffslisten für verschiedene Konzepte. Jetzt laden wie den nächsten Datensatz, nämlich das UN General Debate Korpus zusammengestellt von Slava Mikhaylov. Es umfasst die Transkripte der UN-Generaldebatte zwischen 1970 und 2017. Mit 24 Mio. Wörtern ist dies das umfangreichste Korpus, mit dem wir hier arbeiten, allerdings verteilt sich diese Wortzahl nur auf rund 7,900 Texte, d.h. die Texte sind im Mittel relativ lang.

load("daten/un/un.korpus.RData")
head(korpus.un.stats)

Wie man sieht, enthält auch dieses Korpus umfassende Metadaten. Zu Teil sind diese schon vorhanden, zum Teil wurden sie auf Grundlage weiterer Quellen angefügt. Dazu gehört der Landesname sowie Angaben zum politischen System.

Wieder bereiten wir mehrere DFMs vor, zweimal nach Ländern gruppiert und einmal nach Jahren. Wir filtern folgend etwas, so dass nicht die gesamten 47 Jahre ausgewertet werden, sondern nur die letzten 10 bis 35 Jahre.

meine.dfm.un.mft <- dfm_weight(dfm(corpus_subset(korpus.un, year >= 1992), groups = "country", dictionary = mft.lexikon), scheme = "prop")
meine.dfm.un.maerz <- dfm(corpus_subset(korpus.un, year >= 1982), groups = "year", dictionary = maerz.lexikon)
meine.dfm.un.newsmap <- dfm(corpus_subset(korpus.un, year >= 2007) , groups = "country", dictionary = newsmap.lexikon)

Zunächst sehen wir uns die Verteilung unterschiedlicher Kategorien im Moral Foundations Theory-Lexikon im Verlauf der letzten 25 Jahr an. Die Moral Foundations Theory postuliert wie der Name bereits nahelegt die Existenz moralischer Grundlagen, welche das politische Handeln unterfüttern. Opterationalisiert werden diese Grundlagen durch Begriffe, die typisch für eine Kategorie wie allgemeine Moralität sind. Da bietet es sich an, die Distribution dieser Kategorien im internationalen Vergleich zu analysieren. Nachstehend ziehen wir ein Zufallssample aus den 188 im Korpus vertretenen Länder und plotten für diese die Verteilung der elf Kategorien.

mft.laender <- sort(sample(unique(korpus.un.stats$country), size = 12))
un.mft <- convert(meine.dfm.un.mft, "data.frame") %>% 
  rename(Land = doc_id) %>% 
  filter(Land %in% mft.laender) %>% 
  gather(HarmVirtue:MoralityGeneral, key = "MF_Typ", value = "Anteil") %>% 
  mutate(Land = factor(Land, levels = rev(mft.laender)))
ggplot(un.mft, aes(Land, Anteil, fill = MF_Typ)) + 
  geom_bar(stat="identity") + 
  coord_flip() + 
  scale_fill_manual(values = c("#E5F5E0", "#A1D99B", "#DEEBF7", "#9ECAE1", "#FEE0D2", "#FC9272", "#FEE6CE", "#FDAE6B", "#FFFFFF", "#EFEDF5", "#BCBDDC")) + 
  ggtitle("Themen für zwölf Länder im UN-Korpus mit dem MFT–Lexikon") + 
  xlab("") + ylab("Themen-Anteil (%)") + 
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

Durch das Ziehen eines Zufallssamples erhalten wir einen Überblick über unterschiedliche Typen von (politischen) Argumentationskulturen, die zwar für Experten nicht überraschend sein dürften, aber doch interessante Ähnlichkeiten aufzeigen.

Wir belassen es bei diesem kurzen Eindruck und wenden uns dem Simulating Pluralism-Lexikon zu, welches Autokratien und Demokratien bezüglich bestimmter Argumentationsmuster vergleicht.

un.maerz <- convert(meine.dfm.un.maerz, "data.frame") %>% 
  mutate(Jahr = parse_date(doc_id, format = "%Y")) %>%
  rename(illiberalism = `autocratic vs. democratic.democratic.3 liberalism.autocratic.2 illiberalism`) %>%
  rename(democracy = `autocratic vs. democratic.democratic.4 democratic procedures.democracy`) %>%  
  rename(maintenance_of_power = `autocratic vs. democratic.autocratic.1 autocratic procedures.maintenance of power`) %>%  
  rename(reforms = `autocratic vs. democratic.democratic.4 democratic procedures.institutional reforms`) %>%  
  select(Jahr, illiberalism, democracy, maintenance_of_power, reforms) %>% 
  gather(illiberalism:reforms, key = "Maerz_Typ", value = "Begriffe") %>% 
  mutate(Maerz_Typ = factor(Maerz_Typ, levels = c("illiberalism", "democracy", "maintenance_of_power", "reforms")))
ggplot(un.maerz, aes(Jahr, Begriffe, group = Maerz_Typ, col = Maerz_Typ)) + 
  geom_line(size = 1) + 
  geom_point() + 
  scale_colour_brewer(palette = "Set1") + 
  scale_x_date(date_breaks = "3 years", date_labels = "%Y") + 
  ggtitle("Politische Dimensionen im UN-Korpus nach dem Maerz-Lexikon") + 
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) + 
  xlab("") + ylab("Wörter")

Wir gehen zwar auch auf diese Ergebnisse nicht genauer ein, aber sie belegen gut, wieso die Anwendung des passenden Lexikons einen echten Erkenntnisgewinn bringen kann, besonders wenn es darum geht, Kontraste zwischen Akteuren, Trends, oder Inflektionspunkte zeitlicher Entwicklungen herauszuarbeiten.

Wir wenden uns mit dem nächsten Lexikon einer weiteren Betrachtungsebene zu. Mit dem NewsMap-Lexikon lässt sich die Frage beantworten, über welche Weltregionen die untersuchten Länder im UN–Korpus vorwiegend sprechen. Das klingt zunächt trivial, wird aber interessanter, wenn man bedenkt, dass sich bestimmte Länder deutlich mehr ausserhalb ihrer direkten Nachbarschaft engagieren als andere. So lassen sich Länder etwa danach gruppieren, wie viel und über welche (anderen) Regionen sie sprechen.

newsmap.laender <- sort(sample(unique(korpus.un.stats$country), size = 6))
un.newsmap <- convert(meine.dfm.un.newsmap, "data.frame") %>% 
  rename(Land = doc_id) %>% 
  filter(Land %in% newsmap.laender) %>% 
  gather(africa:oceania, key = "NewsMap_Region", value = "Anteil") %>% 
  mutate(Land = factor(Land, levels = newsmap.laender))
ggplot(un.newsmap, aes(Land, Anteil, colour = NewsMap_Region, fill = NewsMap_Region)) + 
  geom_bar(stat="identity") + 
  scale_colour_brewer(palette = "Set1") + 
  scale_fill_brewer(palette = "Pastel1") + 
  ggtitle("Angesprochener Weltregionen im UN-Korpus nach dem NewsMap-Lexikon") + 
  xlab("") + ylab("Wörter") +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

Anwendung des deutschsprachigen LIWC-Lexikons auf Facebook-Kommentare

Zuletzt wechseln wir noch einmal die Perspektive bzw. das Korpus, und laden einen ganz aktuellen Datensatz, bestehend aus Facebook-Kommentaren von zwei politischen Facebook-Seiten (AfD und Pegida), sowie vier deutschen Nachrichenseiten, um einen Vergleich der Diskussionen, die auf diesen Seiten stattfinden durchzuführen. Dazu rufen wir zunächst das deutschsprachige LIWC-Lexikon auf.

load("daten/facebook/facebook.korpus.RData")

Wieder werfen wir einen qualitativen Blick auf die Daten, indem wir ein Zufallssample ziehen.

texts(corpus_sample(corpus_subset(korpus.facebook, corpus == "populism"), size = 2))
                                                                                                                                                                                                                            pegidaevdresden4289 
"XD ja also, was fällt ihm ein \nWer würde das nicht tun xD \nMal sehen wann die erste Feministin einen Kerl kaput schlägt weil er k.i.z. oder gar trailerpark hört *totlach*\nUnd eins noch, bitte nicht wehren. Das geht ja mal gar nicht ;)" 
                                                                                                                                                                                                                            pegidaevdresden4547 
                                                                "Die linken wollen noch mehr Flüchtlinge aufnehmen gerne doch wenn herr Gysi es aus eigener tascge bezahlt.  Es ist verwunderlich wie die.mit geld umgehen was nicht ihres ist" 
texts(corpus_sample(corpus_subset(korpus.facebook, corpus == "news"), size = 2))
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          welt2211 
"Es ist traurig das es sowas überhaupt gibt in der heutigen Zeit, das manche immer noch so denken. Der Mensch will hoch modern sein dennoch schafft er es nicht modern in seiner eigenen Welt zu sein ( geistig) \nAber selbst Deutschland hinkt hinterher wenn es zum Beispiel um adoptionsrecht oder Ehe geht und das gewaltig! Auch in der Hinsicht das es immer noch Menschen gibt die das als nicht natürlich oder als krank ansehen.... Das ist traurig in der heutigen Zeit! Wir leben im 21 Jahrhundert!\nIsrael und Schweden sind dort viel viel weiter!!! Warum schaffen wir das nicht?" 
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           zeit350 
                                                                                                                                                                                                                                                                                                                                   "Es gibt große Stadien und es gibt schöne, beides sehr unterschiedliche Kategorien. Man vergleiche doch nur mal die Spielertunnel von S04 und BVB, kreativ gelungene Ausgestaltung mit historischem Bezug gegen Betonschschacht mit Gigant-Logos. Glückwunsch." 

Wieder verschaffen wir uns auch einen quantitativen Überblick der Textmenge über die Zeit.

facebook.aktivitaet <- korpus.facebook.stats %>%
  mutate(Quelle = factor(source, levels = c("pegidaevdresden", "alternativefuerde", "FAZ", "SZ", "Welt", "Zeit"))) %>% 
  group_by(Datum = floor_date(created_time, "1 month"), Quelle) %>%
  summarise(Kommentare = n())
`summarise()` regrouping output by 'Datum' (override with `.groups` argument)
ggplot(facebook.aktivitaet, aes(as.Date(Datum), Kommentare, group = Quelle, col = Quelle)) + 
  geom_line(size = 1) + 
  scale_colour_brewer(palette = "Set1") + 
  scale_x_date(date_breaks = "2 months", date_labels = "%b %Y") + 
  ggtitle("Kommentare auf sechs Facebook-Seiten") + 
  xlab("Monat") + ylab("") + 
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

Wie man sieht, beinhaltet das Facebook-Korpus Kommentare, die zwischen 2015 und 2016 auf insgesamt sechs Facebook-Seiten veröffentlicht wurden, davon vier zu großen deutschen Tageszeitungen gehörend, und zwei zu rechtspopulistischen Bewegungen und Partein.

Wir laden zunächst LIWC. Einige der Begriffe sind Kategorien zugeordnet, die gar nicht im Anfangsteil des Lexikons definiert sind, was für quanteda allerdings keinerlei Probleme verursacht.

liwc.deutsch <- dictionary(file = "lexika/LIWC_German.dic", format = "LIWC")
note: ignoring undefined categories:
  27 for anhoer*
  29 for anhoer*
  27 for anhör*
  29 for anhör*
  27 for auge*
  28 for auge*
  27 for brenn*
  30 for brenn*
  27 for darbietung
  28 for darbietung
  27 for empfang*
  29 for empfang*
  27 for empfindung*
  30 for empfindung*
  27 for essen*
  27 for gefuttert*
  27 for gegessen*
  27 for geschmack*
  27 for geschmäck*
  27 for geschmaeck*
  27 for getraenk*
  27 for getränk*
  27 for hoer*
  29 for hoer*
  27 for hoerte*
  29 for hoerte*
  27 for hör*
  29 for hör*
  27 for hörte*
  29 for hörte*
  27 for isst*
  27 for juck*
  30 for juck*
  27 for knuddel*
  30 for knuddel*
  27 for ohr*
  29 for ohr*
  27 for schau
  28 for schau
  27 for schmackhaft*
  27 for schmerz*
  30 for schmerz*
  27 for show*
  28 for show*
  27 for sinnes*
  30 for sinnes*
  27 for trank*
  27 for trink*
  27 for umarm*
  30 for umarm*
  27 for zuhoer*
  29 for zuhoer*
  27 for zuhör*
  29 for zuhör*

Dann generieren wir einen DFM unter Anwendung des Lexikons, nachdem wir nach der Variable Korpus (also nach populism oder news) gruppiert haben.

meine.dfm.fb.liwc <- dfm(korpus.facebook, groups = "corpus", dictionary = liwc.deutsch)

Wieder plotten wir abschließend die Verteilung der Treffer auf das Lexikon, hier nach der Variable Korpus, die ja die Unterscheidung zwischen den populistischen Seiten und der Nachrichtenseiten ernhält. Wir verwenden deshalb absolute Token-Zahlen, weil unser Korpus exakt 50/50 aufgeteilt ist. Wir lassen eine Reihe von LIWC-Kategorien weg, da nicht alle für unsere Zwecke relevant sind.

liwc.anteile <- convert(meine.dfm.fb.liwc, "data.frame") %>%
  rename(Korpus = doc_id) %>% 
  gather(key = Kategorie, value = Wörter, -Korpus) %>% 
  filter(!Kategorie %in% c("Article", "Down", "Eat", "Fillers", "Grooming", "Humans", "Money", "Motion", "Music", "Nonfluency", "Numbers", "Physical", "Preps", "Relig", "Sex", "Sleep", "Sports", "Time", "Up")) %>% 
  mutate(Korpus = factor(Korpus, levels = c("populism", "news")))
ggplot(liwc.anteile, aes(Kategorie, Wörter, fill = Korpus)) + 
  geom_bar(stat = "identity", position = position_dodge()) + 
  scale_fill_brewer(palette = "Set1") + 
  ggtitle("Anteile von LIWC-Kategorien in Facebook-Kommentaren") + 
  xlab("LIWC-Kategorie") + 
  theme(axis.text.x = element_text(size = 7, angle = 45, hjust = 1))

Die Ergbnisse sind möglicherweise überraschend. So ist der Diskurs auf den Nachrichtenseiten affektiver, als der auf den populistischen Seiten. Er enthält auch mehr soziale Begriffe und mehr Ansprache anderer. Es wird aber auch mehr über das “wir” gesprochen, über “andere” und “Aussenstehende”, und es kommen häufiger tabuisierte Begriffe vor. Das Nachrichtenkorpus enthält zudem mehr kognitive Begriffe.

Zusammenfassend könnne wir festhalten, das Lexika sehr nützliche Werkzeuge für die Untersuchung von Inhalten sind. Dies gilt in besonderem Maße, wenn sie viele und geschachtelte Kategorien enthalten, und wenn ihre Abdeckung hinreichend ist (d.h. die Begriffe im Lexikon auch tatsächlich im Korpus vorkommen). Lexika stoßen schnell an ihre Grenzen, wenn sie zu klein oder zu grob strukturiert sind. Zudem muss man ein passendes Lexikon überhaupt erst einmal finden. Ohne Lexikon bleiben aber zum Glück nützliche induktive Methoden, auf die man zurückgreifen kann.

LS0tCnRpdGxlOiAiQXV0b21hdGlzaWVydGUgSW5oYWx0c2FuYWx5c2UgbWl0IFIiCmF1dGhvcjogIkNvcm5lbGl1cyBQdXNjaG1hbm4iCnN1YnRpdGxlOiBTcGV6aWFsaXNpZXJ0ZSBMZXhpa2EKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKPCEtLS0KVG9kb3MKKiBaZWl0LVNNTDogVGl0ZWwgZHVyY2ggVm9sbHRleHRlIGVyc2V0emVuPwoqIE1kQi1TTUw6IFNwbGl0IGluIFRyYWluZ3MtIHVuZCBUZXN0c2V0PwoqIC4uLgotLT4KCldpZSBiZXJlaXRzIGFuZ2Vrw7xuZGlndCwgc2NobGllw590IHNpY2ggZGllc2VzIEthcGl0ZWwgZGVzaGFsYiBuYWh0bG9zIGFuZCBkYXMgdm9yYXVzZ2VoZW5kZSBLYXBpdGVsIDMgenVyIFNlbnRpbWVudGFuYWx5c2UgYW4sIHdlaWwgd2lyIGltIFByaW56aXAgbmljaHRzIG5ldWVzIGRhenVsZXJuZW4gbcO8c3NlbiwgamVkZW5mYWxscyBuaWNodCwgd2FzIGRpZSBGdW5rdGlvbmFsaXTDpHQgdm9uIHF1YW50ZWRhIGFuZ2VodC4gTWl0IGRlciBGdW5rdGlvbiBbZGljdGlvbmFyeV0oaHR0cHM6Ly9kb2NzLnF1YW50ZWRhLmlvL3JlZmVyZW5jZS9kaWN0aW9uYXJ5Lmh0bWwpIHVuZCBkZW0gV2lzc2VuIGRhcsO8YmVyLCB3aWUgd2lyIGVpbiBMZXhpa29uIGF1ZiBlaW5lIERGTSBhbndlbmRlbiwgc2NobGFnZW4gd2lyIGdld2lzc2VubWHDn2VuIHp3ZWkgRmxpZWdlbiBtaXQgZWluZXIgS2xhcHBlLCBkZW5uIGRpZSBMb2dpayBoaW50ZXIgZGVuIFRoZW1lbuKAkyBvZGVyIFBvbGl0aWtmZWxk4oCTTGV4aWthLCBkaWUgaW4gZGllc2VtIEthcGl0ZWwgenVyIEFud2VuZHVuZyBrb21tZW4sIGdsZWljaHQgZGVyIExvZ2lrIHZvbiBTZW50aW1lbnQtTGV4aWthLiBEZXIgd2ljaHRpZ3N0ZSBVbnRlcnNjaGllZCBiZXN0ZWh0IGRhcmluLCBkYXNzIGRpZSBpbiBkaWVzZW0gS2FwaXRlbCBiZWhhbmRlbHRlbiBMZXhpa2EgaS5kLlIuIGVpbmUgZ2FuemUgUmVpaGUgdm9uIEthdGVnb3JpZW4ga2VubmVuLCBuaWNodCBudXIgZGllIFR5cGVuICpwb3NpdGl2KiB1bmQgKm5lZ2F0aXYqLgoKQXVjaCBoaWVyIGFyYmVpdGVuIHdpciB3aWVkZXIgbWl0IGVpbmVyIFJlaWhlIGdhbnogdW50ZXJzY2hpZWRsaWNoZXIgTGV4aWthIHVuZCBLb3Jwb3JhLiBIaWVyIGVpbiDDnGJlcmJsaWNrIMO8YmVyIGRpZSBMZXhpa2EgKGRpZSBLb3Jwb3JhIHdlcmRlbiBpbSBbw5xiZXJibGlja10oaW5oYWx0c2FuYWx5c2VfMF91ZWJlcmJsaWNrLmh0bWwpIGdlbmF1ZXIgYmVzY2hyaWViZW4pLCB2b24gZGVuZW4gYWxsZSBiaXMgYXVmIGRhcyBMSVdDLUxleGlrb24gZW5nbGlzY2hzcHJhY2hpZyBzaW5kOgoKKiBbTGV4aWNvZGVyIFBvbGljeSBBZ2VuZGFzXShodHRwOi8vd3d3LmxleGljb2Rlci5jb20vZG93bmxvYWQuaHRtbCkKKiBbTGF2ZXItR2FycnkgUG9saWN5IFBvc2l0aW9uc10oaHR0cHM6Ly9wcm92YWxpc3Jlc2VhcmNoLmNvbS9wcm9kdWN0cy9jb250ZW50LWFuYWx5c2lzLXNvZnR3YXJlL3dvcmRzdGF0LWRpY3Rpb25hcnkvbGF2ZXItZ2FycnktZGljdGlvbmFyeS1vZi1wb2xpY3ktcG9zaXRpb24vKQoqIFtNb3JhbCBGb3VuZGF0aW9ucyBUaGVvcnldKGh0dHBzOi8vZG9pLm9yZy8xMC43OTEwL0RWTi9XSlhDVDgpCiogW1NpbXVsYXRpbmcgUGx1cmFsaXNtXShodHRwczovL2RvaS5vcmcvMTAuNzkxMC9EVk4vQUZUSE1LKQoqIFtOZXdzTWFwXShodHRwczovL2dpdGh1Yi5jb20vcXVhbnRlZGEvcXVhbnRlZGFfdHV0b3JpYWxzL2Jsb2IvbWFzdGVyL2NvbnRlbnQvZGljdGlvbmFyeS9uZXdzbWFwLnltbCkKKiBbTElXQyBEZXV0c2NoXShodHRwczovL3d3dy5rbGluaWt1bS51bmktaGVpZGVsYmVyZy5kZS9MSVdDLjEzNzc5OS4wLmh0bWwpCgpXaWUgZGllIE5hbWVuIHVuZCBlaW5lIExla3TDvHJlIGRlciBEYXRlbnNhdHpkb2t1bWVudGF0aW9uZW4gdmVycsOkdCwgYmlsZGVuIGRpZXNlbiBMZXhpa2EgdW50ZXJzY2hpZWRsaWNoZSBUaGVtZW5iZXJlaWNoZSB1bmQgUG9saXRpa2ZlbGRlciBhYi4gRGllc2VyIEFuc2F0eiBpc3QgdmllbHNwcmVjaGVuZGVyLCBhbHMgZXMgbcO2Z2xpY2hlcndlaXNlIHp1bsOkY2hzdCBlcnNjaGVpbnQ6IE1ha3Jvw7Zrb25vbWllIG9kZXIgT3J0c25hbWVuIHNpbmQgc2VociBrb250cm9sbGllcnRlIHNlbWFudGlzY2hlIEJlcmVpY2hlLCBkaWUgc2ljaCByZWxhdGl2IHByw6R6aXNlIHVuZCBlcnNjaMO2cGZlbmQgbWl0IGVpbmVtIExleGlrb24gYWJiaWxkZW4gbGFzc2VuLgoKV2lyIHN0YXJ0ZW4gbWl0IGRlbSBFVeKAk1NwZWVjaOKAk0tvcnB1cywgYW4gZGVtIHdpciBnbGVpY2ggbWVocmVyZSBwb2xpdGlzY2hlIExleGlrYSBhdXNwcm9iaWVyZW4sIHVuZCBtYWNoZW4gZGFubiB3ZWl0ZXIgbWl0IGRlbSBVTuKAk0dlbmVyYWxkZWJhdHRlbmtvcnB1cywgd2VsY2hlcyB3aXIgYW5oYW5kIHVudGVyc2NoaWVkbGljaGVyIFBvbGljeeKAk0xleGlrYSB1bnRlcnN1Y2hlbi4gU2NobGllw59saWNoIGFuYWx5c2llcmVuIHdpciBkZXV0c2Noc3ByYWNoaWdlIEZhY2Vib29r4oCTS29tbWVudGFyZSwgYXVmIGRpZSB3aXIgZGllIGRldXRzY2hlIEZhc3N1bmcgZGVzIExJV0PigJNMZXhpa29ucyBhbndlbmRlbiwgdmVybXV0bGljaCBlaW5lcyBkZXIgdW1mYW5ncmVpY2hzdGVuIEluaGFsdHNhbmFseXNl4oCTTGV4aWtvbiDDvGJlcmhhdXB0LgoKIyMjIEluc3RhbGxhdGlvbiB1bmQgTGFkZW4gZGVyIGJlbsO2dGlndGVuIFItQmlibGlvdGhla2VuCgpXaWVkZXIgd2VyZGVuIHp1bsOkY2hzdCBkaWUgbm90d2VuZGlnZW4gQmlibGlvdGhla2VuIGdlbGFkZW4uIAoKYGBge3IgSW5zdGFsbGF0aW9uIHVuZCBMYWRlbiBkZXIgYmVuw7Z0aWd0ZW4gUi1CaWJsaW90aGVrZW4sIG1lc3NhZ2UgPSBGQUxTRX0KaWYoIXJlcXVpcmUoInF1YW50ZWRhIikpIHtpbnN0YWxsLnBhY2thZ2VzKCJxdWFudGVkYSIpOyBsaWJyYXJ5KCJxdWFudGVkYSIpfQppZighcmVxdWlyZSgicmVhZHRleHQiKSkge2luc3RhbGwucGFja2FnZXMoInJlYWR0ZXh0Iik7IGxpYnJhcnkoInJlYWR0ZXh0Iil9CmlmKCFyZXF1aXJlKCJ0aWR5dmVyc2UiKSkge2luc3RhbGwucGFja2FnZXMoInRpZHl2ZXJzZSIpOyBsaWJyYXJ5KCJ0aWR5dmVyc2UiKX0KaWYoIXJlcXVpcmUoImx1YnJpZGF0ZSIpKSB7aW5zdGFsbC5wYWNrYWdlcygibHVicmlkYXRlIik7IGxpYnJhcnkoImx1YnJpZGF0ZSIpfQp0aGVtZV9zZXQodGhlbWVfbWluaW1hbCgpKQpgYGAKCkFuc2NobGllw59lbmQgd2lyZCBkYXMgdW1mYW5ncmVpY2hlIEVVIFNwZWVjaC1Lb3JwdXMgZWluZ2VsZXNlbiwgYXVmIGRhcyBzaWNoIGRpZSB2b3J3aWVnZW5kIHBvbGl0aXNjaGVuIExleGlrYSBhdWYgdW5zZXJlciBMaXN0ZSBndXQgYW53ZW5kZW4gbGFzc2VuLiAKCmBgYHtyIEVVIFNwZWVjaC1Lb3JwdXMgbGFkZW59CmxvYWQoImRhdGVuL2V1c3BlZWNoL2V1c3BlZWNoLmtvcnB1cy5SRGF0YSIpCmBgYAoKRWluIEJsaWNrIGluIGRpZSBNZXRhZGF0ZW4gZ2lidCB1bnMgZWluZW4gRWluZHJ1Y2sgZGVyIEtvcnB1cy1adXNhbW1lbnNldHp1bmcuIEltIEVVIFNwZWVjaC1Lb3JwdXMgc2luZCBSZWRlbiB2b24gaG9jaHJhbmdpZ2VuIFZldHJldGVybiBkZXIgRVUtTWl0Z2xpZWRzdGFhdGVuIGdlc3BlaWNoZXJ0LCBkYXp1IFJlZGVuIHZvbiBNaXRnbGllZGVybiBkZXMgRXVyb3BhcGFybGFtZW50cyB1bmQgdm9uIFZldHJldGVybiBkZXIgRVUtS29tbWlzc2lvbiB1bmQgZGVyIEVaQi4gQWxsZSBSZWRlbiBzaW5kIGluIGVuZ2xpc2NoZXIgU3ByYWNoZSBnZXNwZWljaGVydCwgenVtIFRlaWwgYWxzIMOcYmVyc2V0enVuZy4gWnVkZW0gZ2lidCBlcyBub2NoIE1ldGFkYXRlbiB6dSBTcHJlY2hlcm4sIEzDpG5nZSB1bmQgQW5sYXNzIGRlciBSZWRlbi4gRGllIFZhcmlhYmxlICpTZW50ZW5jZXMqIGlzdCBoaWVyIG5pY2h0IGF1c3NhZ2VrcsOkZnRpZywgd2VpbCBkYXMgS29ycHVzIGJlcmVpdHMgdm9yIGRlbSBFaW5sZXNlbiBpbiBSIGluIHRva2VuaXNpZXJ0ZXIgRm9ybSB2b3JsYWcuIAoKYGBge3IgTWV0YWRhdGVuIGRlcyBFVSBTcGVlY2gtS29ycHVzIGluc3BpemllcmVufQpoZWFkKGtvcnB1cy5ldXNwZWVjaC5zdGF0cykKYGBgCgoKIyMjIEVyc3RlbGx1bmcgdW5kIEFud2VuZHVuZyBlaW5lcyBlaW5mYWNoZW4gdGhlbWVuc3BlemlmaXNjaGVuIExleGlrb25zCgpJbSB2b3JhdXNnZWhlbmRlbiBLYXBpdGVsIGhhYmVuIHdpciBlaW5nYW5ncyBlaW4gc2VociBzaW1wbGVzIExleGlrb24gZGVmaW5pZXJ0LCB1bSBkaWUgU3RydWt0dXIgZGllc2VzIE9iamVrdHMgaW4gcXVhbnRlZGEgenUgZXJsw6R1dGVybi4gV2lyIGhhYmVuIGRpZXNlcyBMZXhpa29uIGFsbGVyZGluZ3MgbmljaHQgYW5nZXdhbmR0LCBzb25kZXJuIHNpbmQgZ2xlaWNoIGRhenUgw7xiZXJnYW5nZW4sIGVpbiBiZXJlaXRzIGZlcnRpZ2VzIFNlbnRpbWVudGxleGlrb24genUgbGFkZW4uIEpldHp0IGlzdCBlcyBhbiBkZXIgWmVpdCwgZWluIHdlbmlnIG1laHIgQXJiZWl0IGluIGVpbiBBZCBob2MtTGV4aWtvbiB6dSBpbnZlc3RpZXJlbiwgdW5kIGRhYmVpIGRpZSBUYXRzYWNoZSBhdXN6dW51dHplbiwgZGFzcyBlaW4gcXVhbnRlZGEtZGljdGlvbmFyeSBhdXMgZWluZXIgUmVpaGUgdm9uIEJlZ3JpZmZlbiB6dSBnYW56IHVudGVyc2NoaWVkbGljaGVuIEthdGVnb3JpZW4gYmVzdGVoZW4ga2Fubi4gRGllIGltIGZvbGdlbmRlbiBCZWlzcGllbCBmw7xyIGRpZSBLYXRlZ29yaWUgUG9wdWxpc211cyB2ZXJ3ZW5kZXRlIFdvcnRsaXN0ZSBzdGFtbXQgYXVzIFtSb29kdWlqbiB1bmQgUGF1d2VscyAoMjAxMSldKGh0dHBzOi8vZG9pLm9yZy8xMC4xMDgwLzAxNDAyMzgyLjIwMTEuNjE2NjY1KSB1bmQgd2lyZCBpbiBbZGllc2VyIMOcYnVuZ10oaHR0cDovL2tlbmJlbm9pdC5uZXQvYXNzZXRzL2NvdXJzZXMvZXNzZXgyMDE0cXRhL2V4ZXJjaXNlNS5wZGYpIHZvbiBLZW4gQmVub2l0IChkZW0gRXJmaW5kZXIgdm9uIHF1YW50ZWRhKSBoZXJhbmdlem9nZW4sIHfDpGhyZW5kIHdpciBkaWUgendlaXRlIFdvcnRsaXN0ZSB6dXIgS2F0ZWdvcmllIExpYmVyYWxpc211cyBhZCBob2Mgc2VsYnN0IHp1c2FtbWVuZ2VzdGVsbHQgaGFiZW4uIAoKYGBge3IgRWluZmFjaGVzIExleGlrb24gZsO8ciBkaWUgVGhlbWVuYmVyZWljaGUgUG9wdWxpc211cy9MaWJlcmFsaXNtdXMgdm9uIEhhbmQgZXJzdGVsbGVufQpwb3B1bGlzbXVzLmxpYmVyYWxpc211cy5sZXhpa29uIDwtIGRpY3Rpb25hcnkoCiAgbGlzdCgKICAgIHBvcHVsaXNtID0gYygiZWxpdCoiLCAiY29uc2Vuc3VzKiIsICJ1bmRlbW9jcmF0aWMqIiwgInJlZmVyZW5kKiIsICJjb3JydXB0KiIsICJwcm9wYWdhbmQiLCAicG9saXRpY2kqIiwgIipkZWNlaXQqIiwgIipkZWNlaXYqIiwgIipiZXRyYXkqIiwgInNoYW1lKiIsICJzY2FuZGFsKiIsICJ0cnV0aCoiLCAiZGlzaG9uZXN0KiIsICJlc3RhYmxpc2htKiIsICJydWxpbmcqIiksCiAgICBsaWJlcmFsaXNtID0gYygibGliZXIqIiwgImZyZWUqIiwgImluZGl2KiIsICJvcGVuKiIsICJsYXcqIiwgInJ1bGVzIiwgIm9yZGVyIiwgInJpZ2h0cyIsICJ0cmFkZSIsICJnbG9iYWwiLCAiaW50ZXIqIiwgInRyYW5zKiIsICJtaW5vcmkqIiwgImV4Y2hhbmdlIiwgIm1hcmtldCoiKSkpCnBvcHVsaXNtdXMubGliZXJhbGlzbXVzLmxleGlrb24KYGBgCgpXaWUgenV2b3Igd2VuZGVuIHdpciBkYXMgTGV4aWtvbiBhdWYgdW5zZXJlIERhdGVuIGFuLCBkYWJlaSBncnVwcGllcmVuIHdpciBoaWVyIHp1bsOkY2hzdCBuYWNoIGRlciBWYXJpYWJsZSAqY291bnRyeSogKGRpZSBFVS1Lb21taXNzaW9uLCBkYXMgRVUtUGFybGFtZW50LCBzb3dpZSBkaWUgRVpCIHdlcmRlbiBoaWVyIGRlciBFaW5mYWNoaGVpdCBoYWxiZXIgYXVjaCBhbHMgImNvdW50cmllcyIgYmVoYW5kZWx0KS4KCmBgYHtyIE5hY2ggTGFuZCBncnVwcGllcnRlIERGTSBlcnN0ZWxsZW4gdW5kIExleGlrb24gYW53ZW5kZW59Cm1laW5lLmRmbS5ldSA8LSBkZm0oa29ycHVzLmV1c3BlZWNoLCBncm91cHMgPSAiY291bnRyeSIsIGRpY3Rpb25hcnkgPSBwb3B1bGlzbXVzLmxpYmVyYWxpc211cy5sZXhpa29uKQptZWluZS5kZm0uZXUucHJvcCA8LSBkZm1fd2VpZ2h0KG1laW5lLmRmbS5ldSwgc2NoZW1lID0gInByb3AiKQpjb252ZXJ0KG1laW5lLmRmbS5ldS5wcm9wLCAiZGF0YS5mcmFtZSIpCmBgYAoKRWluIFBsb3Qgc3BhcmVuIHdpciB1bnMgYW4gZGllc2VyIFN0ZWxsZS4gRXMgaXN0IGF1Y2ggc28gc29mb3J0IG9mZmVuc2ljaHRsaWNoLCBkYXNzIFRyZWZmZXIgYXVmIGRpZSBLYXRlZ29yaWUgTGliZXJhbGlzbXVzIGltIFZlcmdsZWljaCBrbGFyIGdlZ2Vuw7xiZXIgZGVyIEthdGVnb3JpZSBQb3B1bGlzbXVzIMO8YmVyd2llZ2VuLCB3YXMgYW5nZXNpY2h0cyBkZXIgWnVzYW1tZW5zZXR6dW5nIGRlciBEYXRlbiBrYXVtIMO8YmVycmFzY2h0LiBBbGxlcmRpbmdzIHNjaGVpbmVuIGRpZSBVbnRlcnNjaGllZGUgendpc2NoZW4gZGVuIGJlaWRlbiBFVS1CZWjDtnJkZW4gS29tbWlzc2lvbiB1bmQgRVpCLCBnZWZvbGd0IHZvbiBEZXV0c2NobGFuZCwgZGVuIE5pZWRlcmxhbmRlbiB1bmQgVHNjaGVjaGllbiBlaW5lcnNlaXRzLCB1bmQgR3JpZWNoZW5sYW5kLCBTcGFuaWVuIHVuZCBkZW0gRVUtUGFybGFtZW50IGFuZGVyZXJzZWl0cyBkZW4gKHNlaHIgaGVtZHPDpHJtZWxpZ2VuKSBLb250cmFzdCwgZGVuIHVuc2VyIExleGlrb25zIHVudGVyc3RlbGx0LCBncnVuZHPDpHR6bGljaCB6dSBiZXN0w6R0aWdlbi4gSXN0IGRpZSBlcnN0ZSBHcnVwcGUgc2VociB3ZW5pZyBwb3B1bGlzdGlzY2ggKGplZGVuZmFsbHMgbmFjaCBEZWZpbml0aW9uIGRpZXNlcyBzaW1wbGVuIExleGlrb25zKSwgc2llaHQgZGFzIGbDvHIgZGllIHp3ZWl0ZSBHcnVwcGUgYmVyZWl0cyBldHdhcyBhbmRlcnMgYXVzLgoKQWxzIG7DpGNoc3RlcyBiZXJlY2huZW4gd2lyIGRlbiByZWxhdGl2ZW4gUG9wdWxpc211cy1BbnRlaWwgbmFjaCBKYWhyZW4gaW0gWmVpdHJ1bSB2b24gMjAwNy0yMDE1LCB1bmQgdW50ZXJzY2hlaWRlbiBkYWJlaSB6d2lzY2hlbiB6d2VpIFR5cGVuIHZvbiBBa3RldXJlbjogbmF0aW9uYWxlbiBSZWdpZXJ1bmdlbiAoaGllciBpbmtsLiBFVS1QYXJsYW1lbnQpIGVpbmVyc2VpdHMgdW5kIEVVLUJlaMO2cmRlbiAoRVXigJNLb21taXNzaW9uIHVuZCBFWkIpIGFuZGVyZXJzZWl0cy4KCmBgYHtyIE5hY2ggTGFuZCB1bmQgSmFociBncnVwcGllcnRlIERGTSB1bnRlciBBbndlbmR1bmcgZGVzIExleGlrb25zIGVyc3RlbGxlbn0KbWVpbmUuZGZtLmV1IDwtIGRmbShrb3JwdXMuZXVzcGVlY2gsIGdyb3VwcyA9IGMoIlR5cCIsICJKYWhyIiksIGRpY3Rpb25hcnkgPSBwb3B1bGlzbXVzLmxpYmVyYWxpc211cy5sZXhpa29uKQptZWluZS5kZm0uZXUucHJvcCA8LSBkZm1fd2VpZ2h0KG1laW5lLmRmbS5ldSwgc2NoZW1lID0gInByb3AiKQpldS50aGVtZW4gPC0gY29udmVydChtZWluZS5kZm0uZXUucHJvcCwgImRhdGEuZnJhbWUiKSAlPiUgCiAgbXV0YXRlKFR5cCA9IHN0cl9zcGxpdChkb2NfaWQsICJcXC4iLCBzaW1wbGlmeSA9IFQpWywxXSkgJT4lIAogIG11dGF0ZShKYWhyID0gc3RyX3NwbGl0KGRvY19pZCwgIlxcLiIsIHNpbXBsaWZ5ID0gVClbLDJdKSAlPiUgCiAgc2VsZWN0KFR5cCwgSmFociwgcG9wdWxpc20sIGxpYmVyYWxpc20pCmV1LnRoZW1lbgpgYGAKCkF1Y2ggaGllciDDvGJlcnNwcmluZ2VuIHdpciBkYXMgUGxvdC4gV8OkaHJlbmQgZGVyIFBvcHVsaXNtdXMtQW50ZWlsIGJlaSBkZW4gRVXigJNCZWjDtnJkZW4gcmVsYXRpdiBrb25zdGFudCBiZWkgY2lyY2EgMiUgbGllZ3QsIGlzdCBlciBiZWkgZGVuIFZlcnRyZXRlcm4gZGVyIEVVLU1pdGdsaWVkc3RhYXRlbiBtaXQgNy05JSBkZXV0bGljaCBow7ZoZXIuCgpCZXZvciB3aXIgdW5zIGltIG7DpGNoc3RlbiBTY2hyaXR0ICJyaWNodGlnZW4iIExleGlrYSB6dXdlbmRlbiwgZGllIGRldXRsaWNoIHVtZmFuZ3JlaWNoZXIgc2luZCBhbHMgdW5zZXIgUG9wdWxpc211c+KAk0xleGlrb24sIGJldHJhY2h0ZW4gd2lyIG5vY2gga3VyeiBkaWUgVmFyaWF0aW9uICppbm5lcmhhbGIqIGRlciBSZWRlbiwgZGEgZGllc2UgcmVsYXRpdiBsYW5nIHNpbmQsIHVuZCBzaWNoIHNvIGF1Y2ggZWluZSBUaGVtZW52ZXJ0ZWlsdW5nIGJlcmVjaG5lbiBsw6Rzc3QsICpvaG5lKiBkYXNzIG1hbiBtaXRoaWxmZSB2b24gKmdyb3VwKiBkaWUgREZNIG5hY2ggZWluZXIgYmVzdGltbXRlbiBWYXJpYWJsZSB6dXNhbW1lbmZhc3N0LiBEYXMgZm9sZ2VuZGUgUGxvdCAod2VsY2hlcyBCb3hwbG90IHVuZCBTY2F0dGVycGxvdCBrb21iaW5pZXJ0KSB6ZWlndCBkaWUgVmFyaWF0aW9uIGJlaW0gUG9wdWxpc211cy1BbnRlaWwgbmFjaCBMYW5kIGlubmVyaGFsYiBlaW56ZWxuZXIgUmVkZW4uIAoKYGBge3IgREZNIGJlcmVjaG5lbiwgZ2V3aWNodGVuIHVuZCBCb3hwbG90IGRlcyBQb3B1bGlzbXVzLUFudGVpbHMgbmFjaCBMYW5kIGVyc3RlbGxlbn0KbWVpbmUuZGZtLmV1IDwtIGRmbShrb3JwdXMuZXVzcGVlY2gsIGRpY3Rpb25hcnkgPSBwb3B1bGlzbXVzLmxpYmVyYWxpc211cy5sZXhpa29uKQptZWluZS5kZm0uZXUucHJvcCA8LSBkZm1fd2VpZ2h0KG1laW5lLmRmbS5ldSwgc2NoZW1lID0gInByb3AiKQpldS5wb3BsaWIgPC0gY29udmVydChtZWluZS5kZm0uZXUucHJvcCwgImRhdGEuZnJhbWUiKSAlPiUgCiAgYmluZF9jb2xzKGtvcnB1cy5ldXNwZWVjaC5zdGF0cykgJT4lIAogIGZpbHRlcihsZW5ndGggPj0gMTIwMCwgcG9wdWxpc20gPiAwIHwgbGliZXJhbGlzbSA+IDApCmdncGxvdChldS5wb3BsaWIsIGFlcyhjb3VudHJ5LCBwb3B1bGlzbSkpICsgCiAgZ2VvbV9ib3hwbG90KG91dGxpZXIuc2l6ZSA9IDApICsgCiAgZ2VvbV9qaXR0ZXIoYWVzKGNvdW50cnkscG9wdWxpc20pLCBwb3NpdGlvbiA9IHBvc2l0aW9uX2ppdHRlcih3aWR0aCA9IDAuNCwgaGVpZ2h0ID0gMCksIGFscGhhID0gMC4xLCBzaXplID0gMC4yLCBzaG93LmxlZ2VuZCA9IEYpICsgCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgdmp1c3QgPSAxLCBoanVzdCA9IDEpKSArIAogIHhsYWIoIiIpICsgeWxhYigiUG9wdWxpc211cy1BbnRlaWwgKCUpIikgKyAKICBnZ3RpdGxlKCJQb3B1bGlzbXVzLUFudGVpbCBpbiBSZWRlbiBkZXMgRVUtU3BlZWNoLUtvcnB1cyIpCmBgYAoKV2llIGRpZSBEaWNodGUgZGVyIFB1bmt0ZSBpbSBQbG90IHplaWd0LCBpc3QgZGVyIEFudGVpbCBkZXIgS29tbWlzc2lvbiBhbSBLb3JwdXMgaW5zZ2VzYW10IGdyb8OfLCBhdWNoIHdlbm4gZGFzIFBvcHVsaXNtdXMtTml2ZWF1IChnZW1lc3NlbiBtaXQgdW5zZXJlbSBwcmltaXRpdmVuIExleGlrb24pIGluc2dlc2FtdCBuaWVkcmlnIGlzdC4gRGVzd2VpdGVyZW4gZXJrZW5uZW4gd2lyIGVpbmUgZ3LDtsOfZXJlIEJhbmRicmVpdGUgYmVpIGRlbiBuYXRpb25hbGVuIFJlZ2llcnVuZ2VuIChHcmllY2hlbmxhbmQgdnMuIERldXRzY2hsYW5kKSBhbHMgYmVpIGRlbiBCZWjDtnJkZW4uIAoKSGllciBzb2xsdGUgbWFuIEF1c3JlacOfZXIgKGV0d2EgYmVpIGRlciBFVS1Lb21taXNpb24pIG1pdCBlaW5lbSBQb3B1bGlzbXVzLUFudGVpbCB2b24gMTAwJSBuaWNodCDDvGJlcnNjaMOkdHplbi4gWndhciBoYWJlbiB3aXIgenV2b3Igc2VociBrdXJ6ZSBSZWRlbiBhdXNnZXNjaGxvc3NlbiAobWl0ICpsZW5ndGggPj0gMTIwMCopLCBhYmVyIGVzIGTDvHJmdGUgdHJvdHpkZW0gc29sY2hlIFRleHRlIGdlYmVuLCBkaWUgbnVyIGR1cmNoIGVpbmUgaGFuZHZvbGwgVHJlZmZlciBhdWYgZWluZSBkZXIgYmVpZGVuIEthdGVvZ29yaWVuIGVpbiBzb2xjaGVzIEVyZ2VibmlzIGVycmVpY2hlbiAoZGllcyBnaWVsdCBhdWNoIGbDvHIgZWluZW4gTGliZXJhbGlzbXVz4oCTQW50ZWlsIHZvbiAxMDAlKS4gV2llIGF1Y2ggYmVpbSBTZW50aW1lbnQgZ2lsdDogRXMgaGFuZGVsdCBzaWNoIHVtIGhldXJpc3Rpc2NoZSBWZXJmYWhyZW4sIHVuZCBtaXQgZWluZW0gYmVzc2VyZW4gTGV4aWtvbiBsw6Rzc3Qgc2ljaCBkaWUgR2VuYXVpZ2tlaXQgbGVpY2h0IHN0ZWlnZXJuLgoKIyMjIEFud2VuZHVuZyBkZXIgTGV4aWthIFBvbGljeSBBZ2VuZGFzIHVuZCBMYXZlci1HYXJyeSBhdWYgZGFzIEVVIFNwZWVjaOKAk0tvcnB1cwoKRXMgbXVzcyBiZXRvbnQgd2VyZGVuLCBkYXNzIHVuc2VyIEFkLWhvYy1MZXhpa29uIHNpY2hlcmxpY2ggbmljaHQgYXVzcmVpY2h0LCB1bSBkZW4gU3RpbCBvZGVyIGRhcyBUaGVtZW5zcGVrdHJ1bSBwb2xpdGlzY2hlciBEZWJhdHRlbiBhZMOkcXVhdCBhbnp1YmlsZGVuLiBXaXIgZXJzdGVsbGVuIGRlc2hhbGIgamV0enQgendlaSBxdWFudGVkYS1MZXhpa2EgYXVmIEdydW5kbGFnZSBkZXMgUG9saWN5IEFnZW5kYeKAk0xleGlrb25zIHVuZCBhdWYgQmFzaXMgZGVzIExhdmVyIEdhcnJ5LUxleGlrb25zLiBCZWkgYmVpZGVuIExleGlrYSBoYW5kZWx0IGVzIHNpY2ggdW0gaW4gZGVyIFBvbHRpa3dpc3NlbnNjaGFmdCB2aWVsZmFjaCBlaW5nZXNldHp0ZSBSZXNvdXJjZW4gZsO8ciBkaWUgQmVzdGltbXVuZyB2b24gUG9saXRpa2ZlbGRlcm4uIERpZSBMZXhpa29u4oCTRGF0ZW4gZGF6dSBrb21tZW4gZsO8ciBQb2xpY3kgQWdlbmRhcyBhdXMgZWluZXIgc2Nob24gdm9yYmVyZWl0ZXRlbiBSRGF0YS1EYXRlaSB1bmQgZsO8ciBMYXZlciBHYXJyeSBhdXMgZWluZXIgVGV4dGRhdGVpIGltIEZvcm1hdCAiV29yZFN0YXQiLCB3ZWxjaGVzIGRlciBkaWN0aW9uYXJ5LUJlZmVobCBiZXJlaXRzIGtlbm50LiAKCldpciBzY2hhdWVuIGluIGJlaWRlIExleGlrYSBtaXQgZGVtIEJlZmVobCBoZWFkIGhpbmVpbiAtLSBtYW4gZXJrZW5udCBnbGVpY2ggZGVuIGdyb8OfZW4gVW1mYW5nLgoKYGBge3IgTGV4aWNvZGVyIFBvbGljeSBBZ2VuZGFzIHVuZCBMYXZlciBHYXJyeSBMZXhpa2EgbGFkZW59CmxvYWQoImxleGlrYS9wb2xpY3lfYWdlbmRhc19lbmdsaXNoLlJEYXRhIikKcG9saWN5YWdlbmRhcy5sZXhpa29uIDwtIGRpY3Rpb25hcnkoZGljdExleGljMlRvcGljcykKbGF2ZXJnYXJyeS5sZXhpa29uIDwtIGRpY3Rpb25hcnkoZmlsZSA9ICJsZXhpa2EvTGF2ZXJHYXJyeS5jYXQiLCBmb3JtYXQgPSAid29yZHN0YXQiKQpoZWFkKHBvbGljeWFnZW5kYXMubGV4aWtvbiwgMikKaGVhZChsYXZlcmdhcnJ5LmxleGlrb24sIDIpCmBgYAoKRGllIGJlaWRlbiBMZXhpa2EgemVpY2huZW4gc2ljaCBkYWZ1cmNoIGF1cywgZGFzcyBzaWUgZ2VzY2hhY2h0ZWx0ZSBLYXRlZ29yaWVuIGF1ZndlaXNlbiwgdW50ZXIgZGVuZW4gc2ljaCBlaW5lIFJlaWhlIHZvbiBVbnRlcmthdGVnb3JpZW4gdmVyYmVyZ2VuLiAKCk51biBiZXJlY2huZW4gd2lyIGplIGVpbmUgREZNIGbDvHIgamVkZXMgTGV4aWtvbiB1bmQgZ3J1cHBpZXJlbiBkaWVzZSBlaW5tYWwgbmFjaCBMYW5kIHVuZCBlaW5tYWwgbmFjaCBKYWhyLgoKYGBge3IgREZNIGdydXBwaWVydCBuYWNoIExhbmQgYnp3LiBKYWhyIGJlcmVjaG5lbn0KbWVpbmUuZGZtLmV1LnBhIDwtIGRmbShrb3JwdXMuZXVzcGVlY2gsIGdyb3VwcyA9ICJjb3VudHJ5IiwgZGljdGlvbmFyeSA9IHBvbGljeWFnZW5kYXMubGV4aWtvbikKbWVpbmUuZGZtLmV1LmxnIDwtIGRmbShrb3JwdXMuZXVzcGVlY2gsIGdyb3VwcyA9ICJKYWhyIiwgZGljdGlvbmFyeSA9IGxhdmVyZ2FycnkubGV4aWtvbikKYGBgCgpEYXMgZm9sZ2VuZGUgUGxvdCB6ZWlndCBkaWUgVGhlbWVudmVydGVpbHVuZyBpbm5lcmhhbGIgZGVzIEtvcnB1cyBuYWNoIExhbmQsIGF1ZiBCYXNpcyBkZXMgUG9saWN5IEFnZW5kYS1MZXhpa29ucy4gV2lyIGhhYmVuIHp1dm9yIGVpbmlnZSBUaGVtZW4gYXVzZ2V3w6RobHQgdW5kIGF1ZiBkZXIgR3J1bmRsYWdlIGRpZXNlciBBdXN3YWhsIGRpZSBBbnRlaWxlIGJlcmVjaG5ldC4gQW5kZXJlIEJlcmVpY2hlIGhhYmVuIHdpciB1bnRlciAqb3RoZXIqIHp1c2FtbWVuZ2VmYXNzdC4KCmBgYHtyIFRoZW1lbnZlcnRlaWx1bmcgaW0gRVUtU3BlZWNoLUtvcnB1cyBqZSBMYW5kIG5hY2ggZGVtIFBvbGljeSBBZ2VuZGFzIExleGlrb259CmV1LnRoZW1lbi5wYSA8LSBjb252ZXJ0KG1laW5lLmRmbS5ldS5wYSwgImRhdGEuZnJhbWUiKSAlPiUKICByZW5hbWUoTGFuZCA9IGRvY19pZCkgJT4lCiAgc2VsZWN0KExhbmQsIG1hY3JvZWNvbm9taWNzLCBmaW5hbmNlLCBmb3JlaWduX3RyYWRlLCBsYWJvdXIsIGhlYWx0aGNhcmUsIGltbWlncmF0aW9uLCBlZHVjYXRpb24sIGludGxfYWZmYWlycywgZGVmZW5jZSkgJT4lCiAgZ2F0aGVyKG1hY3JvZWNvbm9taWNzOmRlZmVuY2UsIGtleSA9ICJUaGVtYSIsIHZhbHVlID0gIkFudGVpbCIpICU+JSAKICBncm91cF9ieShMYW5kKSAlPiUgCiAgbXV0YXRlKEFudGVpbCA9IEFudGVpbC9zdW0oQW50ZWlsKSkgJT4lIAogIG11dGF0ZShUaGVtYSA9IGFzX2ZhY3RvcihUaGVtYSkpCmdncGxvdChldS50aGVtZW4ucGEsIGFlcyhMYW5kLCBBbnRlaWwsIGNvbG91ciA9IFRoZW1hLCBmaWxsID0gVGhlbWEpKSArIAogIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IikgKyAKICBzY2FsZV9jb2xvdXJfYnJld2VyKHBhbGV0dGUgPSAiU2V0MSIpICsgCiAgc2NhbGVfZmlsbF9icmV3ZXIocGFsZXR0ZSA9ICJQYXN0ZWwxIikgKyAKICBnZ3RpdGxlKCJUaGVtZW4gaW0gRVUtU3BlZWNoLUtvcnB1cyBhdWYgQmFzaXMgZGVzIFBvbGljeSBBZ2VuZGFzLUxleGlrb25zIikgKyAKICB4bGFiKCIiKSArIHlsYWIoIlRoZW1lbi1BbnRlaWwgKCUpIikgKyAKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKQpgYGAKCkRpZSBBbnRlaWxzdmVydGVpbHVuZyBkw7xyZnRlIGluIFRlaWxlbiBrYXVtIMO8YmVycmFzY2hlbi4gRGllIEVaQiB1bmQgaW4gZWluZW0gZXR3YXMgZ2VyaW5nZXJlbSBVbWZhbmcgYXVjaCBkaWUgS29tbWlzc2lvbiBiZXNjaMOkZnRpZ2VuIHNpY2ggdmllbCBtaXQgTWFrcm/Dtmtvbm9taWUgdW5kIEZpbmFuemVuLCBGcmFua3JlaWNoIHVuZCBTcGFuaWVuIG1pdCBkZW0gQXJiZWl0c21hcmt0LCB1bmQgRGV1dHNjaGxhbmQgdW5kIGRpZSBOaWVkZXJsYW5kZSB2aWVsIG1pdCBIYW5kZWwuIEludGVyZXNzYW50IHNpbmQgZGllIFRoZW1lbmZlbGRlciBWZXJ0ZWlkaWR1bmcgKE5pZWRlcmxhbmRlLCBGcmFua3JlaWNoLCBHcm/Dn2JyaXRhbm5pZW4pLCBadXdhbmRlcnVuZyAoVHNjaGVjaGllbikgdW5kIEJpbGR1bmcgKEZyYW5rcmVpY2gsIEdyb8OfYnJpdGFubmllbikuIERpZSBnZXJpbmdlIFJlbGV2YW56IGRlcyBadXdhbmRlcnVuZ3N0aGVtYXMgaW4gSXRhbGllbiB1bmQgR3JpZWNoZW5sYW5kIGJlbGVndCB2aWVsbGVpY2h0IGVpbmUgRGlza3JlcGFueiB6d2lzY2hlbiDDtmZmZW50bGljaGVyIE1laW51bmcgdW5kIGRlciBSZWdpZXJ1bmdzYWdlbmRhIOKAk+KAkyBqZWRlbmZhbGxzIGltIFplaXRyYXVtIDIwMDfigJMyMDE1LgoKV2lyIHdlbmRlbiB1bnMgbnVuIGRlbSBMYXZlci1HYXJyeS1MZXhpa29uIHp1LCB3ZWxjaGVzIHdpciBnZXppZWx0IGF1ZiBkZW4gWmVpdHZlcmxhdWYgMjAwNy0yMDE1IGFud2VuZGVuLCB1bSBWZXLDpG5kZXJ1bmdlbiBpbiBkZW4gQmxpY2sgenVuZWhtZW4uIERpZSB2aWVsZW4gVW1mb3JtdW5nc3NjaHJpdHRlIHdlcmRlbiBub3R3ZW5kaWcsIHdlaWwgZGFzIExleGlrb24gc3RhcmsgZ2VzY2hhY2h0ZWx0ZSBLYXRlZ29yaWVuIGJlc2l0enQsIGRpZSB3aXIgenVyIGJlc3NlcmVuIMOcYmVyc2ljaHRsaWNoa2VpdCB6dW0gVGVpbCB6dXNhbW1lbmZhc3NlbiB1bmQgdW1iZW5ubmVuLiAKCmBgYHtyIFRoZW1lbnZlcnRlaWx1bmcgaW0gRVUtU3BlZWNoLUtvcnB1cyB6d2lzY2hlbiAyMDA3IHVuZCAyMDE1IG5hY2ggZGVtIExhdmVyIEdhcnJ5LUxleGlrb259CmV1LnRoZW1lbi5sZyA8LSBkZm1fd2VpZ2h0KG1laW5lLmRmbS5ldS5sZywgc2NoZW1lID0gInByb3AiKSAlPiUgCiAgY29udmVydCgiZGF0YS5mcmFtZSIpICU+JSAKICByZW5hbWUoSmFociA9IGRvY19pZCkgJT4lIAogIG11dGF0ZShjdWx0dXJlID0gYENVTFRVUkVgICsgYENVTFRVUkUuQ1VMVFVSRS1ISUdIYCArIGBDVUxUVVJFLkNVTFRVUkUtUE9QVUxBUmAgKyBgQ1VMVFVSRS5TUE9SVGApICU+JSAKICBtdXRhdGUoZWNvbm9teSA9IGBFQ09OT01ZLitTVEFURStgICsgYEVDT05PTVkuPVNUQVRFPWAgKyBgRUNPTk9NWS4tU1RBVEUtYCkgJT4lIAogIG11dGF0ZShlbnZpcm9ubWVudCA9IGBFTlZJUk9OTUVOVC5DT04gRU5WSVJPTk1FTlRgICsgYEVOVklST05NRU5ULlBSTyBFTlZJUk9OTUVOVGApICU+JSAKICBtdXRhdGUoaW5zdGl0dXRpb25zID0gYElOU1RJVFVUSU9OUy5DT05TRVJWQVRJVkVgICsgYElOU1RJVFVUSU9OUy5ORVVUUkFMYCArIGBJTlNUSVRVVElPTlMuUkFESUNBTGApICU+JQogIG11dGF0ZSh2YWx1ZXMgPSBgVkFMVUVTLkNPTlNFUlZBVElWRWAgKyBgVkFMVUVTLkxJQkVSQUxgKSAlPiUKICBtdXRhdGUobGF3X2FuZF9vcmRlciA9IGBMQVdfQU5EX09SREVSLkxBVy1DT05TRVJWQVRJVkVgKSAlPiUKICBtdXRhdGUocnVyYWwgPSBgUlVSQUxgKSAlPiUKICBtdXRhdGUob3RoZXIgPSBgR1JPVVBTLkVUSE5JQ2AgKyBgR1JPVVBTLldPTUVOYCArIGBMQVdfQU5EX09SREVSLkxBVy1MSUJFUkFMYCArIGBVUkJBTmApICU+JSAKICBzZWxlY3QoSmFociwgY3VsdHVyZTpvdGhlcikgJT4lIAogIGdhdGhlcihUaGVtYSwgUHJvemVudCwgY3VsdHVyZTpvdGhlcikgJT4lIAogIGZpbHRlcighVGhlbWEgJWluJSBjKCJlY29ub215IiwgImluc3RpdHV0aW9ucyIsICJ2YWx1ZXMiLCAiY3VsdHVyZSIsICJydXJhbCIsICJvdGhlciIpKQpnZ3Bsb3QoZXUudGhlbWVuLmxnLCBhZXMoSmFociwgUHJvemVudCwgZ3JvdXAgPSBUaGVtYSwgY29sID0gVGhlbWEpKSArIAogIGdlb21fbGluZShzaXplID0gMSkgKyAKICBzY2FsZV9jb2xvdXJfYnJld2VyKHBhbGV0dGUgPSAiU2V0MSIpICsgCiAgZ2d0aXRsZSgiVGhlbWVuIGltIEVVLVNwZWVjaC1Lb3JwdXMgYXVmIEdydW5kbGFnZSBkZXMgTGF2ZXItR2FycnktTGV4aWtvbnMiKSArIAogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpICsgCiAgeGxhYigiIikgKyB5bGFiKCJUaGVtZW4tQW50ZWlsICglKSIpCmBgYAoKV2llc28gaGFiZW4gd2lyIHNvIHZpZWxlIEthdGVnb3JpZW4gYXVzZ2VsYXNzZW4/IERpZSBUaGVtZW5mZWxkZXIgKmVjb25vbXkqIHVuZCAqaW5zdGl0dXRpb25zKiBzaW5kIHNlaHIgc3RhcmsgYXVzZ2VwcsOkZ3QgdW5kIHZlcsOkbmRlcm4gc2ljaCBpbSBVbnRlcnN1Y2h1bmdzemVpdHJhdW0gbmljaHQgYWxsenUgbWVya2xpY2gsIGRhaGVyIGlzdCBlcyBoaWVyIGludGVyZXNzYW50ZXIsIHNpY2ggZWhlciBrbGVpbmVyZSBUaGVtZW5mZWxkZXIgYW56dXNlaGVuLiBBdWZmw6RsbGlnIGlzdCB1LmEuIGVpbiBBYmZhbGxlbiBkZXMgVGhlbWVuZmVsZGVzICpsw6RuZGxpY2hlciBSYXVtKiwgZWluIHNwcnVuZ2hhZnRlciBBbnN0aWVnIGRlcyBUaGVtYXMgKmlubmVyZSBTaWNoZXJoZWl0KiB1bmQgZWluIE5hY2hsYXNzZW4gZGVyIFJlbGV2YW56IGRlcyBUaGVtYXMgKlVtd2VsdCouCgpEaWUgYmVoYW5kZWx0ZW4gTGV4aWthIGJpbGRlbiBiZWlkZSBQb2xpdGlrZmVsZGVyIGFiLiBEdXJjaCBkaWUgc3BlemlhbGlzaWVydGUgQmVncmlmZnN3ZWx0IHZvbiBUaGVtZW4gd2llIEZpbmFuei0gb2RlciBVbXdlbHRwb2x0aWsgd2lyZCBlcyBtw7ZnbGljaCwgZGllIEtvbmp1bmt0dXIgZGllc2VyIFJlc3NvcnRzIHp1IHF1YW50aWZpemllcmVuLiBFaW5lIGFuZGVyZW4gWnVnYW5nIHp1IGRlciBhdXRvbWF0aXNpZXJ0ZW4gRXJtaXR0bHVuZyB2b24gVGhlbmVuIGJlc2NocmVpYmVuIHdpciBpbSBuw6RjaHN0ZW4gS2FwaXRlbC4gV2FzIGFiZXIsIHdlbm4gbWFuIHNpY2ggd2VuaWdlciBmw7xyIFRoZW1lbiwgc29uZGVyIGVoZXIgZsO8ciBhYnN0cmFrdGUgS2F0ZWdvcmllbiB3aWUgYXV0b2tyYXRpc2NoZSBBcmd1bWVudGF0aW9uc211c3RlciBvZGVyIG1vcmFsaXNjaC1waGlsb3NvcGhpc2NoZSBHcnVuZGxhZ2VuIHBvbGl0aXNjaGVuIEhhbmRlbG5zIGludGVyZXNzaWVydD8KCgojIyMgQW53ZW5kdW5nIGRlciBMZXhpa2EgTW9yYWwgRm91bmRhdGlvbnMgVGhlb3J5LCBTaW11bGF0aW5nIFBsdXJhbGlzbSB1bmQgTmV3c01hcCBhdWYgZGFzIFVOIEdlbmVyYWwgRGViYXRlIENvcnB1cyAKCkxhZGVuIHdpciBudW4gYWxzbyB6d2VpIHdlaXRlcmUgTGV4aWthLCBkaWUgc2ljaCBpbSBHZWdlbnNhdHogenUgUG9saWN5IEFnZW5kYXMgdW5kIExhdmVyLUdhcnJ5IG5pY2h0IFBvbHRpa2ZlbGRlciBiZXNjaHJlaWJlbiwgc29uZGVybiBzaWNoIG1laHIgbWl0IHBvbGl0aXNjaGVyIEFyZ3VtZW50YXRpb24gYmVmYXNzZW4sIGRhcyBbTW9yYWwgRm91bmRhdGlvbnMgVGhlb3J5XShodHRwOi8vbW9yYWxmb3VuZGF0aW9ucy5vcmcvKS1MZXhpa29uIHVuZCBkYXMgIkxhbmd1YWdlIG9mIERlbW9jcmFjeSBpbiBIZWdlbW9uaWMgQXV0aG9yaXRhcmlhbmlzbSItTGV4aWtvbiB2b24gW1NlcmFwaGluZSBGLiBNYWVyel0oaHR0cHM6Ly9zaXRlcy5nb29nbGUuY29tL3ZpZXcvc2VyYXBoaW5lbWFlcnovYWJvdXQpXS4gSGllciBtYWNoZW4gd2lyIHVucyDDpGhubGljaCB3aXIgYmVpbSBMYXZlciBHYXJyeS1MZXhpa29uIGRpZSBNw7ZnbGljaGtlaXQgaW4gcXVhbnRlZGEgenVudXR6dGUsIExleGlrYSBpbiBiZXN0aW1tdGVuIFN0YW5kYXJkZm9ybWF0ZW4gKGhpZXIgaW4gZGVuIEZvcm1hdGVuIExJV0MgdW5kIHlvc2hpa29kZXIpIGVpbnp1bGVzZW4uIERhcyBlcnNwYXJ0IHVucyBrb21wbGl6aWVydGUgU3ludGF4IGbDvHIgZGllIEludGVycHJldGF0aW9uIGRlciBMZXhpa29uLVN0cnVrdHVyLgoKV2llc28gw7xiZXJoYXVwdCBzbyB2aWVsZSB1bnRlcnNjaGllZGxpY2hlIExleGlrYT8gV2llc28gbmljaHQgZWluZmFjaCBkYXMgYmVzdGUgTGV4aWtvbiBudXR6ZW4sIHVuZCBhdXNzY2hsaWXDn2xpY2ggZGFtaXQgYXJiZWl0ZW4/IExlaWRlciBpc3QgZGllIEZyYWdlLCB3ZWxjaGVzIExleGlrb24gbWFuIG51dHplbiBzb2xsdGUsIGVuZyBtaXQgZGVtIEZvcnNjaHVuZ3NpbnRlcmVzc2UgdmVycXVpY2t0LiBXaWxsIG1hbiBhbHNvIGV0d2FzIMO8YmVyIGRpZSBTcHJhY2hlIGF1dG9yaXTDpHJlciBSZWdpbWUgb2RlciBtb3JhbGlzY2hlIEFwcGVsbGUgaW4gcG9saXRpc2NoZW4gUmVkZW4gZXJmYWhyZW4sIGJyYXVjaCBtYW4gYW5kZXJlIExleGlrYSwgYWxzIHdlbm4gbWFuIGRlbiBBbnRlaWwgdm9uIFBvbGl0aWtmZWxkZXJuIGJlc2NocmVpYmVuIG3DtmNodGUuIERhaGVyIHN0ZWxsZW4gd2lyIGVpbmUgZ2FuemUgUmVpaGUgdm9uIExleGlrYSB2b3Ig4oCT4oCTIHVuZCB0YXRzw6RjaGxpY2ggd8OkcmUgbm9jaCB6YWhscmVpY2hlIHdlaXRlcmUgZHVyY2hhdXMgaW50ZXJlc3NhbnQsIGRpZSB3aXIgaGllciBuaWNodCB2b3JzdGVsbGVuLiBIaW56dSBrb21tdCBub2NoIGRlciBBc3Bla3QgZGVyIFZlcmbDvGdiYXJrZWl0OiB2aWVsZSBMZXhpa2Egc2luZCBsZWlkZXIga29zdGVucGZsaWNodGlnLCBuaWNodCBpbiBvZmZlbmVuIEZvcm1hdGVuIGdlc3BlaWNoZXJ0LCBudXIgdW56dXJlaWNoZW5kIGRva3VtZW50aWVydCwgb2RlciBlaW5mYWNoIHNjaHdlciBhdWZmaW5kYmFyLgoKYGBge3IgTGFkZW4gdm9uIGRyZWkgd2VpdGVyZW4gTGV4aWthfQptZnQubGV4aWtvbiA8LSBkaWN0aW9uYXJ5KGZpbGUgPSAibGV4aWthL21vcmFsX2ZvdW5kYXRpb25zX2RpY3Rpb25hcnkuZGljIiwgZm9ybWF0ID0gIkxJV0MiKQptYWVyei5sZXhpa29uIDwtIGRpY3Rpb25hcnkoZmlsZSA9ICJsZXhpa2EvQXV0aG9yaXRhcmlhbmlzbV9NYWVyei55a2QiLCBmb3JtYXQgPSAieW9zaGlrb2RlciIpCm5ld3NtYXAubGV4aWtvbiA8LSBkaWN0aW9uYXJ5KGZpbGUgPSAibGV4aWthL25ld3NtYXAueW1sIiwgZm9ybWF0ID0gIllBTUwiKQpuZXdzbWFwLmxleGlrb24gPC0gZGljdGlvbmFyeShsaXN0KGFmcmljYSA9IHVubmFtZSh1bmxpc3QobmV3c21hcC5sZXhpa29uJEFGUklDQSkpLCBhbWVyaWNhID0gdW5uYW1lKHVubGlzdChuZXdzbWFwLmxleGlrb24kQU1FUklDQSkpLCBhc2lhID0gdW5uYW1lKHVubGlzdChuZXdzbWFwLmxleGlrb24kQVNJQSkpLCBldXJvcGUgPSB1bm5hbWUodW5saXN0KG5ld3NtYXAubGV4aWtvbiRFVVJPUEUpKSwgb2NlYW5pYSA9IHVubmFtZSh1bmxpc3QobmV3c21hcC5sZXhpa29uJE9DRUFOSUEpKSkpCnN0cihtZnQubGV4aWtvbikKc3RyKG1hZXJ6LmxleGlrb24pCnN0cihuZXdzbWFwLmxleGlrb24pCmBgYAoKSW0gVmVyZ2xlaWNoIGbDpGxsdCBhdWYsIGRhc3MgZGllIGRyZWkgTGV4aWthIHNlaHIgZWxhYm9yaWVydCBzaW5kLCBtaXQgdW1mYXNzZW5kZW4gQmVncmlmZnNsaXN0ZW4gZsO8ciB2ZXJzY2hpZWRlbmUgS29uemVwdGUuIEpldHp0IGxhZGVuIHdpZSBkZW4gbsOkY2hzdGVuIERhdGVuc2F0eiwgbsOkbWxpY2ggZGFzIFtVTiBHZW5lcmFsIERlYmF0ZSBLb3JwdXNdKGh0dHA6Ly93d3cuc21pa2hheWxvdi5uZXQvdW5nZGMvKSB6dXNhbW1lbmdlc3RlbGx0IHZvbiBTbGF2YSBNaWtoYXlsb3YuIEVzIHVtZmFzc3QgZGllIFRyYW5za3JpcHRlIGRlciBVTi1HZW5lcmFsZGViYXR0ZSB6d2lzY2hlbiAxOTcwIHVuZCAyMDE3LiBNaXQgMjQgTWlvLiBXw7ZydGVybiBpc3QgZGllcyBkYXMgdW1mYW5ncmVpY2hzdGUgS29ycHVzLCBtaXQgZGVtIHdpciBoaWVyIGFyYmVpdGVuLCBhbGxlcmRpbmdzIHZlcnRlaWx0IHNpY2ggZGllc2UgV29ydHphaGwgbnVyIGF1ZiBydW5kIDcsOTAwIFRleHRlLCBkLmguIGRpZSBUZXh0ZSBzaW5kIGltIE1pdHRlbCByZWxhdGl2IGxhbmcuIAoKYGBge3IgVU4tS29ycHVzIGxhZGVufQpsb2FkKCJkYXRlbi91bi91bi5rb3JwdXMuUkRhdGEiKQpoZWFkKGtvcnB1cy51bi5zdGF0cykKYGBgCgpXaWUgbWFuIHNpZWh0LCBlbnRow6RsdCBhdWNoIGRpZXNlcyBLb3JwdXMgdW1mYXNzZW5kZSBNZXRhZGF0ZW4uIFp1IFRlaWwgc2luZCBkaWVzZSBzY2hvbiB2b3JoYW5kZW4sIHp1bSBUZWlsIHd1cmRlbiBzaWUgYXVmIEdydW5kbGFnZSB3ZWl0ZXJlciBRdWVsbGVuIGFuZ2Vmw7xndC4gRGF6dSBnZWjDtnJ0IGRlciBMYW5kZXNuYW1lIHNvd2llIEFuZ2FiZW4genVtIHBvbGl0aXNjaGVuIFN5c3RlbS4KCldpZWRlciBiZXJlaXRlbiB3aXIgbWVocmVyZSBERk1zIHZvciwgendlaW1hbCBuYWNoIEzDpG5kZXJuIGdydXBwaWVydCB1bmQgZWlubWFsIG5hY2ggSmFocmVuLiBXaXIgZmlsdGVybiBmb2xnZW5kIGV0d2FzLCBzbyBkYXNzIG5pY2h0IGRpZSBnZXNhbXRlbiA0NyBKYWhyZSBhdXNnZXdlcnRldCB3ZXJkZW4sIHNvbmRlcm4gbnVyIGRpZSBsZXR6dGVuIDEwIGJpcyAzNSBKYWhyZS4KCmBgYHtyIERGTXMgbWl0IGRyZWkgTGV4aWthIHJlY2huZW59Cm1laW5lLmRmbS51bi5tZnQgPC0gZGZtX3dlaWdodChkZm0oY29ycHVzX3N1YnNldChrb3JwdXMudW4sIHllYXIgPj0gMTk5MiksIGdyb3VwcyA9ICJjb3VudHJ5IiwgZGljdGlvbmFyeSA9IG1mdC5sZXhpa29uKSwgc2NoZW1lID0gInByb3AiKQptZWluZS5kZm0udW4ubWFlcnogPC0gZGZtKGNvcnB1c19zdWJzZXQoa29ycHVzLnVuLCB5ZWFyID49IDE5ODIpLCBncm91cHMgPSAieWVhciIsIGRpY3Rpb25hcnkgPSBtYWVyei5sZXhpa29uKQptZWluZS5kZm0udW4ubmV3c21hcCA8LSBkZm0oY29ycHVzX3N1YnNldChrb3JwdXMudW4sIHllYXIgPj0gMjAwNykgLCBncm91cHMgPSAiY291bnRyeSIsIGRpY3Rpb25hcnkgPSBuZXdzbWFwLmxleGlrb24pCmBgYAoKWnVuw6RjaHN0IHNlaGVuIHdpciB1bnMgZGllIFZlcnRlaWx1bmcgdW50ZXJzY2hpZWRsaWNoZXIgS2F0ZWdvcmllbiBpbSBNb3JhbCBGb3VuZGF0aW9ucyBUaGVvcnktTGV4aWtvbiBpbSBWZXJsYXVmIGRlciBsZXR6dGVuIDI1IEphaHIgYW4uIERpZSBNb3JhbCBGb3VuZGF0aW9ucyBUaGVvcnkgcG9zdHVsaWVydCB3aWUgZGVyIE5hbWUgYmVyZWl0cyBuYWhlbGVndCBkaWUgRXhpc3RlbnogbW9yYWxpc2NoZXIgR3J1bmRsYWdlbiwgd2VsY2hlIGRhcyBwb2xpdGlzY2hlIEhhbmRlbG4gdW50ZXJmw7x0dGVybi4gT3B0ZXJhdGlvbmFsaXNpZXJ0IHdlcmRlbiBkaWVzZSBHcnVuZGxhZ2VuIGR1cmNoIEJlZ3JpZmZlLCBkaWUgdHlwaXNjaCBmw7xyIGVpbmUgS2F0ZWdvcmllIHdpZSAqYWxsZ2VtZWluZSBNb3JhbGl0w6R0KiBzaW5kLiBEYSBiaWV0ZXQgZXMgc2ljaCBhbiwgZGllIERpc3RyaWJ1dGlvbiBkaWVzZXIgS2F0ZWdvcmllbiBpbSBpbnRlcm5hdGlvbmFsZW4gVmVyZ2xlaWNoIHp1IGFuYWx5c2llcmVuLiBOYWNoc3RlaGVuZCB6aWVoZW4gd2lyIGVpbiBadWZhbGxzc2FtcGxlIGF1cyBkZW4gMTg4IGltIEtvcnB1cyB2ZXJ0cmV0ZW5lbiBMw6RuZGVyIHVuZCBwbG90dGVuIGbDvHIgZGllc2UgZGllIFZlcnRlaWx1bmcgZGVyIGVsZiBLYXRlZ29yaWVuLgoKYGBge3IgVmVydGVpbHVuZyBkZXIgTUZULVRoZW1lbiBmw7xyIHp3w7ZsZiBMw6RuZGVyIHBsb3R0ZW59Cm1mdC5sYWVuZGVyIDwtIHNvcnQoc2FtcGxlKHVuaXF1ZShrb3JwdXMudW4uc3RhdHMkY291bnRyeSksIHNpemUgPSAxMikpCnVuLm1mdCA8LSBjb252ZXJ0KG1laW5lLmRmbS51bi5tZnQsICJkYXRhLmZyYW1lIikgJT4lIAogIHJlbmFtZShMYW5kID0gZG9jX2lkKSAlPiUgCiAgZmlsdGVyKExhbmQgJWluJSBtZnQubGFlbmRlcikgJT4lIAogIGdhdGhlcihIYXJtVmlydHVlOk1vcmFsaXR5R2VuZXJhbCwga2V5ID0gIk1GX1R5cCIsIHZhbHVlID0gIkFudGVpbCIpICU+JSAKICBtdXRhdGUoTGFuZCA9IGZhY3RvcihMYW5kLCBsZXZlbHMgPSByZXYobWZ0LmxhZW5kZXIpKSkKZ2dwbG90KHVuLm1mdCwgYWVzKExhbmQsIEFudGVpbCwgZmlsbCA9IE1GX1R5cCkpICsgCiAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiKSArIAogIGNvb3JkX2ZsaXAoKSArIAogIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGMoIiNFNUY1RTAiLCAiI0ExRDk5QiIsICIjREVFQkY3IiwgIiM5RUNBRTEiLCAiI0ZFRTBEMiIsICIjRkM5MjcyIiwgIiNGRUU2Q0UiLCAiI0ZEQUU2QiIsICIjRkZGRkZGIiwgIiNFRkVERjUiLCAiI0JDQkREQyIpKSArIAogIGdndGl0bGUoIlRoZW1lbiBmw7xyIHp3w7ZsZiBMw6RuZGVyIGltIFVOLUtvcnB1cyBtaXQgZGVtIE1GVOKAk0xleGlrb24iKSArIAogIHhsYWIoIiIpICsgeWxhYigiVGhlbWVuLUFudGVpbCAoJSkiKSArIAogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpCmBgYAoKRHVyY2ggZGFzIFppZWhlbiBlaW5lcyBadWZhbGxzc2FtcGxlcyBlcmhhbHRlbiB3aXIgZWluZW4gw5xiZXJibGljayDDvGJlciB1bnRlcnNjaGllZGxpY2hlIFR5cGVuIHZvbiAocG9saXRpc2NoZW4pIEFyZ3VtZW50YXRpb25za3VsdHVyZW4sIGRpZSB6d2FyIGbDvHIgRXhwZXJ0ZW4gbmljaHQgw7xiZXJyYXNjaGVuZCBzZWluIGTDvHJmdGVuLCBhYmVyIGRvY2ggaW50ZXJlc3NhbnRlIMOEaG5saWNoa2VpdGVuIGF1ZnplaWdlbi4KCldpciBiZWxhc3NlbiBlcyBiZWkgZGllc2VtIGt1cnplbiBFaW5kcnVjayB1bmQgd2VuZGVuIHVucyBkZW0gU2ltdWxhdGluZyBQbHVyYWxpc20tTGV4aWtvbiB6dSwgd2VsY2hlcyBBdXRva3JhdGllbiB1bmQgRGVtb2tyYXRpZW4gYmV6w7xnbGljaCBiZXN0aW1tdGVyIEFyZ3VtZW50YXRpb25zbXVzdGVyIHZlcmdsZWljaHQuCgpgYGB7ciBEaXN0cmlidXRpb24gZGVyIE1hZXJ6LUthdGVnb3JpZW4gw7xiZXIgZGllIFplaXQgcGxvdHRlbn0KdW4ubWFlcnogPC0gY29udmVydChtZWluZS5kZm0udW4ubWFlcnosICJkYXRhLmZyYW1lIikgJT4lIAogIG11dGF0ZShKYWhyID0gcGFyc2VfZGF0ZShkb2NfaWQsIGZvcm1hdCA9ICIlWSIpKSAlPiUKICByZW5hbWUoaWxsaWJlcmFsaXNtID0gYGF1dG9jcmF0aWMgdnMuIGRlbW9jcmF0aWMuZGVtb2NyYXRpYy4zIGxpYmVyYWxpc20uYXV0b2NyYXRpYy4yIGlsbGliZXJhbGlzbWApICU+JQogIHJlbmFtZShkZW1vY3JhY3kgPSBgYXV0b2NyYXRpYyB2cy4gZGVtb2NyYXRpYy5kZW1vY3JhdGljLjQgZGVtb2NyYXRpYyBwcm9jZWR1cmVzLmRlbW9jcmFjeWApICU+JSAgCiAgcmVuYW1lKG1haW50ZW5hbmNlX29mX3Bvd2VyID0gYGF1dG9jcmF0aWMgdnMuIGRlbW9jcmF0aWMuYXV0b2NyYXRpYy4xIGF1dG9jcmF0aWMgcHJvY2VkdXJlcy5tYWludGVuYW5jZSBvZiBwb3dlcmApICU+JSAgCiAgcmVuYW1lKHJlZm9ybXMgPSBgYXV0b2NyYXRpYyB2cy4gZGVtb2NyYXRpYy5kZW1vY3JhdGljLjQgZGVtb2NyYXRpYyBwcm9jZWR1cmVzLmluc3RpdHV0aW9uYWwgcmVmb3Jtc2ApICU+JSAgCiAgc2VsZWN0KEphaHIsIGlsbGliZXJhbGlzbSwgZGVtb2NyYWN5LCBtYWludGVuYW5jZV9vZl9wb3dlciwgcmVmb3JtcykgJT4lIAogIGdhdGhlcihpbGxpYmVyYWxpc206cmVmb3Jtcywga2V5ID0gIk1hZXJ6X1R5cCIsIHZhbHVlID0gIkJlZ3JpZmZlIikgJT4lIAogIG11dGF0ZShNYWVyel9UeXAgPSBmYWN0b3IoTWFlcnpfVHlwLCBsZXZlbHMgPSBjKCJpbGxpYmVyYWxpc20iLCAiZGVtb2NyYWN5IiwgIm1haW50ZW5hbmNlX29mX3Bvd2VyIiwgInJlZm9ybXMiKSkpCmdncGxvdCh1bi5tYWVyeiwgYWVzKEphaHIsIEJlZ3JpZmZlLCBncm91cCA9IE1hZXJ6X1R5cCwgY29sID0gTWFlcnpfVHlwKSkgKyAKICBnZW9tX2xpbmUoc2l6ZSA9IDEpICsgCiAgZ2VvbV9wb2ludCgpICsgCiAgc2NhbGVfY29sb3VyX2JyZXdlcihwYWxldHRlID0gIlNldDEiKSArIAogIHNjYWxlX3hfZGF0ZShkYXRlX2JyZWFrcyA9ICIzIHllYXJzIiwgZGF0ZV9sYWJlbHMgPSAiJVkiKSArIAogIGdndGl0bGUoIlBvbGl0aXNjaGUgRGltZW5zaW9uZW4gaW0gVU4tS29ycHVzIG5hY2ggZGVtIE1hZXJ6LUxleGlrb24iKSArIAogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpICsgCiAgeGxhYigiIikgKyB5bGFiKCJXw7ZydGVyIikKYGBgCgpXaXIgZ2VoZW4gendhciBhdWNoIGF1ZiBkaWVzZSBFcmdlYm5pc3NlIG5pY2h0IGdlbmF1ZXIgZWluLCBhYmVyIHNpZSBiZWxlZ2VuIGd1dCwgd2llc28gZGllIEFud2VuZHVuZyBkZXMgcGFzc2VuZGVuIExleGlrb25zIGVpbmVuIGVjaHRlbiBFcmtlbm50bmlzZ2V3aW5uIGJyaW5nZW4ga2FubiwgYmVzb25kZXJzIHdlbm4gZXMgZGFydW0gZ2VodCwgS29udHJhc3RlIHp3aXNjaGVuIEFrdGV1cmVuLCBUcmVuZHMsIG9kZXIgSW5mbGVrdGlvbnNwdW5rdGUgemVpdGxpY2hlciBFbnR3aWNrbHVuZ2VuIGhlcmF1c3p1YXJiZWl0ZW4uCgpXaXIgd2VuZGVuIHVucyBtaXQgZGVtIG7DpGNoc3RlbiBMZXhpa29uIGVpbmVyIHdlaXRlcmVuIEJldHJhY2h0dW5nc2ViZW5lIHp1LiBNaXQgZGVtIE5ld3NNYXAtTGV4aWtvbiBsw6Rzc3Qgc2ljaCBkaWUgRnJhZ2UgYmVhbnR3b3J0ZW4sIMO8YmVyIHdlbGNoZSBXZWx0cmVnaW9uZW4gZGllIHVudGVyc3VjaHRlbiBMw6RuZGVyIGltIFVO4oCTS29ycHVzIHZvcndpZWdlbmQgc3ByZWNoZW4uIERhcyBrbGluZ3QgenVuw6RjaHQgdHJpdmlhbCwgd2lyZCBhYmVyIGludGVyZXNzYW50ZXIsIHdlbm4gbWFuIGJlZGVua3QsIGRhc3Mgc2ljaCBiZXN0aW1tdGUgTMOkbmRlciBkZXV0bGljaCBtZWhyIGF1c3NlcmhhbGIgaWhyZXIgZGlyZWt0ZW4gTmFjaGJhcnNjaGFmdCBlbmdhZ2llcmVuIGFscyBhbmRlcmUuIFNvIGxhc3NlbiBzaWNoIEzDpG5kZXIgZXR3YSBkYW5hY2ggZ3J1cHBpZXJlbiwgd2llIHZpZWwgdW5kIMO8YmVyIHdlbGNoZSAoYW5kZXJlbikgUmVnaW9uZW4gc2llIHNwcmVjaGVuLgoKYGBge3IgVmVydGVpbHVuZyBkZXIgTmV3c01hcC1LYXRlZ29yaWVuIGbDvHIgZsO8bmYgTMOkbmRlciBwbG90dGVufQpuZXdzbWFwLmxhZW5kZXIgPC0gc29ydChzYW1wbGUodW5pcXVlKGtvcnB1cy51bi5zdGF0cyRjb3VudHJ5KSwgc2l6ZSA9IDYpKQp1bi5uZXdzbWFwIDwtIGNvbnZlcnQobWVpbmUuZGZtLnVuLm5ld3NtYXAsICJkYXRhLmZyYW1lIikgJT4lIAogIHJlbmFtZShMYW5kID0gZG9jX2lkKSAlPiUgCiAgZmlsdGVyKExhbmQgJWluJSBuZXdzbWFwLmxhZW5kZXIpICU+JSAKICBnYXRoZXIoYWZyaWNhOm9jZWFuaWEsIGtleSA9ICJOZXdzTWFwX1JlZ2lvbiIsIHZhbHVlID0gIkFudGVpbCIpICU+JSAKICBtdXRhdGUoTGFuZCA9IGZhY3RvcihMYW5kLCBsZXZlbHMgPSBuZXdzbWFwLmxhZW5kZXIpKQpnZ3Bsb3QodW4ubmV3c21hcCwgYWVzKExhbmQsIEFudGVpbCwgY29sb3VyID0gTmV3c01hcF9SZWdpb24sIGZpbGwgPSBOZXdzTWFwX1JlZ2lvbikpICsgCiAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiKSArIAogIHNjYWxlX2NvbG91cl9icmV3ZXIocGFsZXR0ZSA9ICJTZXQxIikgKyAKICBzY2FsZV9maWxsX2JyZXdlcihwYWxldHRlID0gIlBhc3RlbDEiKSArIAogIGdndGl0bGUoIkFuZ2VzcHJvY2hlbmVyIFdlbHRyZWdpb25lbiBpbSBVTi1Lb3JwdXMgbmFjaCBkZW0gTmV3c01hcC1MZXhpa29uIikgKyAKICB4bGFiKCIiKSArIHlsYWIoIlfDtnJ0ZXIiKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkKYGBgCgoKIyMjIEFud2VuZHVuZyBkZXMgZGV1dHNjaHNwcmFjaGlnZW4gTElXQy1MZXhpa29ucyBhdWYgRmFjZWJvb2stS29tbWVudGFyZQoKWnVsZXR6dCB3ZWNoc2VsbiB3aXIgbm9jaCBlaW5tYWwgZGllIFBlcnNwZWt0aXZlIGJ6dy4gZGFzIEtvcnB1cywgdW5kIGxhZGVuIGVpbmVuIGdhbnogYWt0dWVsbGVuIERhdGVuc2F0eiwgYmVzdGVoZW5kIGF1cyBGYWNlYm9vay1Lb21tZW50YXJlbiB2b24gendlaSBwb2xpdGlzY2hlbiBGYWNlYm9vay1TZWl0ZW4gKEFmRCB1bmQgUGVnaWRhKSwgc293aWUgdmllciBkZXV0c2NoZW4gTmFjaHJpY2hlbnNlaXRlbiwgdW0gZWluZW4gVmVyZ2xlaWNoIGRlciBEaXNrdXNzaW9uZW4sIGRpZSBhdWYgZGllc2VuIFNlaXRlbiBzdGF0dGZpbmRlbiBkdXJjaHp1ZsO8aHJlbi4gRGF6dSBydWZlbiB3aXIgenVuw6RjaHN0IGRhcyBkZXV0c2Noc3ByYWNoaWdlIExJV0MtTGV4aWtvbiBhdWYuIAoKYGBge3IgRmFjZWJvb2stS29ycHVzIGxhZGVufQpsb2FkKCJkYXRlbi9mYWNlYm9vay9mYWNlYm9vay5rb3JwdXMuUkRhdGEiKQpgYGAKCldpZWRlciB3ZXJmZW4gd2lyIGVpbmVuIHF1YWxpdGF0aXZlbiBCbGljayBhdWYgZGllIERhdGVuLCBpbmRlbSB3aXIgZWluIFp1ZmFsbHNzYW1wbGUgemllaGVuLiAKCmBgYHtyIFppZWhlbiBlaW5lcyBadWZhbGxzc2FtcGxlc30KdGV4dHMoY29ycHVzX3NhbXBsZShjb3JwdXNfc3Vic2V0KGtvcnB1cy5mYWNlYm9vaywgY29ycHVzID09ICJwb3B1bGlzbSIpLCBzaXplID0gMikpCnRleHRzKGNvcnB1c19zYW1wbGUoY29ycHVzX3N1YnNldChrb3JwdXMuZmFjZWJvb2ssIGNvcnB1cyA9PSAibmV3cyIpLCBzaXplID0gMikpCmBgYAoKV2llZGVyIHZlcnNjaGFmZmVuIHdpciB1bnMgYXVjaCBlaW5lbiBxdWFudGl0YXRpdmVuIMOcYmVyYmxpY2sgZGVyIFRleHRtZW5nZSDDvGJlciBkaWUgWmVpdC4KCmBgYHtyIEFrdGl2aXTDpHQgaW0gRmFjZWJvb2stS29ycHVzIMO8YmVyIGRpZSBaZWl0IHBsb3R0ZW59CmZhY2Vib29rLmFrdGl2aXRhZXQgPC0ga29ycHVzLmZhY2Vib29rLnN0YXRzICU+JQogIG11dGF0ZShRdWVsbGUgPSBmYWN0b3Ioc291cmNlLCBsZXZlbHMgPSBjKCJwZWdpZGFldmRyZXNkZW4iLCAiYWx0ZXJuYXRpdmVmdWVyZGUiLCAiRkFaIiwgIlNaIiwgIldlbHQiLCAiWmVpdCIpKSkgJT4lIAogIGdyb3VwX2J5KERhdHVtID0gZmxvb3JfZGF0ZShjcmVhdGVkX3RpbWUsICIxIG1vbnRoIiksIFF1ZWxsZSkgJT4lCiAgc3VtbWFyaXNlKEtvbW1lbnRhcmUgPSBuKCkpCmdncGxvdChmYWNlYm9vay5ha3Rpdml0YWV0LCBhZXMoYXMuRGF0ZShEYXR1bSksIEtvbW1lbnRhcmUsIGdyb3VwID0gUXVlbGxlLCBjb2wgPSBRdWVsbGUpKSArIAogIGdlb21fbGluZShzaXplID0gMSkgKyAKICBzY2FsZV9jb2xvdXJfYnJld2VyKHBhbGV0dGUgPSAiU2V0MSIpICsgCiAgc2NhbGVfeF9kYXRlKGRhdGVfYnJlYWtzID0gIjIgbW9udGhzIiwgZGF0ZV9sYWJlbHMgPSAiJWIgJVkiKSArIAogIGdndGl0bGUoIktvbW1lbnRhcmUgYXVmIHNlY2hzIEZhY2Vib29rLVNlaXRlbiIpICsgCiAgeGxhYigiTW9uYXQiKSArIHlsYWIoIiIpICsgCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0NSwgaGp1c3QgPSAxKSkKYGBgCgpXaWUgbWFuIHNpZWh0LCBiZWluaGFsdGV0IGRhcyBGYWNlYm9vay1Lb3JwdXMgS29tbWVudGFyZSwgZGllIHp3aXNjaGVuIDIwMTUgdW5kIDIwMTYgYXVmIGluc2dlc2FtdCBzZWNocyBGYWNlYm9vay1TZWl0ZW4gdmVyw7ZmZmVudGxpY2h0IHd1cmRlbiwgZGF2b24gdmllciB6dSBncm/Dn2VuIGRldXRzY2hlbiBUYWdlc3plaXR1bmdlbiBnZWjDtnJlbmQsIHVuZCB6d2VpIHp1IHJlY2h0c3BvcHVsaXN0aXNjaGVuIEJld2VndW5nZW4gdW5kIFBhcnRlaW4uCgpXaXIgbGFkZW4genVuw6RjaHN0IExJV0MuIEVpbmlnZSBkZXIgQmVncmlmZmUgc2luZCBLYXRlZ29yaWVuIHp1Z2VvcmRuZXQsIGRpZSBnYXIgbmljaHQgaW0gQW5mYW5nc3RlaWwgZGVzIExleGlrb25zIGRlZmluaWVydCBzaW5kLCB3YXMgZsO8ciBxdWFudGVkYSBhbGxlcmRpbmdzIGtlaW5lcmxlaSBQcm9ibGVtZSB2ZXJ1cnNhY2h0LiAKCmBgYHtyIERldXRzY2hzcHJhY2hpZ2VzIExJV0MgbGFkZW59Cmxpd2MuZGV1dHNjaCA8LSBkaWN0aW9uYXJ5KGZpbGUgPSAibGV4aWthL0xJV0NfR2VybWFuLmRpYyIsIGZvcm1hdCA9ICJMSVdDIikKYGBgCgpEYW5uIGdlbmVyaWVyZW4gd2lyIGVpbmVuIERGTSB1bnRlciBBbndlbmR1bmcgZGVzIExleGlrb25zLCBuYWNoZGVtIHdpciBuYWNoIGRlciBWYXJpYWJsZSAqS29ycHVzKiAoYWxzbyBuYWNoICpwb3B1bGlzbSogb2RlciAqbmV3cyopIGdydXBwaWVydCBoYWJlbi4KCmBgYHtyIERGTSBmw7xyIGRhcyBGYWNlYm9vay1Lb3JwdXMgcmVjaG5lbn0KbWVpbmUuZGZtLmZiLmxpd2MgPC0gZGZtKGtvcnB1cy5mYWNlYm9vaywgZ3JvdXBzID0gImNvcnB1cyIsIGRpY3Rpb25hcnkgPSBsaXdjLmRldXRzY2gpCmBgYAoKV2llZGVyIHBsb3R0ZW4gd2lyIGFic2NobGllw59lbmQgZGllIFZlcnRlaWx1bmcgZGVyIFRyZWZmZXIgYXVmIGRhcyBMZXhpa29uLCBoaWVyIG5hY2ggZGVyIFZhcmlhYmxlICpLb3JwdXMqLCBkaWUgamEgZGllIFVudGVyc2NoZWlkdW5nIHp3aXNjaGVuIGRlbiBwb3B1bGlzdGlzY2hlbiBTZWl0ZW4gdW5kIGRlciBOYWNocmljaHRlbnNlaXRlbiBlcm5ow6RsdC4gV2lyIHZlcndlbmRlbiBkZXNoYWxiIGFic29sdXRlIFRva2VuLVphaGxlbiwgd2VpbCB1bnNlciBLb3JwdXMgZXhha3QgNTAvNTAgYXVmZ2V0ZWlsdCBpc3QuIFdpciBsYXNzZW4gZWluZSBSZWloZSB2b24gTElXQy1LYXRlZ29yaWVuIHdlZywgZGEgbmljaHQgYWxsZSBmw7xyIHVuc2VyZSBad2Vja2UgcmVsZXZhbnQgc2luZC4gCgpgYGB7ciBMSVdDLUFudGVpbGUgZsO8ciBkYXMgRmFjZWJvb2stS29ycHVzIHBsb3R0ZW59Cmxpd2MuYW50ZWlsZSA8LSBjb252ZXJ0KG1laW5lLmRmbS5mYi5saXdjLCAiZGF0YS5mcmFtZSIpICU+JQogIHJlbmFtZShLb3JwdXMgPSBkb2NfaWQpICU+JSAKICBnYXRoZXIoa2V5ID0gS2F0ZWdvcmllLCB2YWx1ZSA9IFfDtnJ0ZXIsIC1Lb3JwdXMpICU+JSAKICBmaWx0ZXIoIUthdGVnb3JpZSAlaW4lIGMoIkFydGljbGUiLCAiRG93biIsICJFYXQiLCAiRmlsbGVycyIsICJHcm9vbWluZyIsICJIdW1hbnMiLCAiTW9uZXkiLCAiTW90aW9uIiwgIk11c2ljIiwgIk5vbmZsdWVuY3kiLCAiTnVtYmVycyIsICJQaHlzaWNhbCIsICJQcmVwcyIsICJSZWxpZyIsICJTZXgiLCAiU2xlZXAiLCAiU3BvcnRzIiwgIlRpbWUiLCAiVXAiKSkgJT4lIAogIG11dGF0ZShLb3JwdXMgPSBmYWN0b3IoS29ycHVzLCBsZXZlbHMgPSBjKCJwb3B1bGlzbSIsICJuZXdzIikpKQpnZ3Bsb3QobGl3Yy5hbnRlaWxlLCBhZXMoS2F0ZWdvcmllLCBXw7ZydGVyLCBmaWxsID0gS29ycHVzKSkgKyAKICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZSgpKSArIAogIHNjYWxlX2ZpbGxfYnJld2VyKHBhbGV0dGUgPSAiU2V0MSIpICsgCiAgZ2d0aXRsZSgiQW50ZWlsZSB2b24gTElXQy1LYXRlZ29yaWVuIGluIEZhY2Vib29rLUtvbW1lbnRhcmVuIikgKyAKICB4bGFiKCJMSVdDLUthdGVnb3JpZSIpICsgCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDcsIGFuZ2xlID0gNDUsIGhqdXN0ID0gMSkpCmBgYAoKRGllIEVyZ2JuaXNzZSBzaW5kIG3DtmdsaWNoZXJ3ZWlzZSDDvGJlcnJhc2NoZW5kLiBTbyBpc3QgZGVyIERpc2t1cnMgYXVmIGRlbiBOYWNocmljaHRlbnNlaXRlbiBhZmZla3RpdmVyLCBhbHMgZGVyIGF1ZiBkZW4gcG9wdWxpc3Rpc2NoZW4gU2VpdGVuLiBFciBlbnRow6RsdCBhdWNoIG1laHIgc296aWFsZSBCZWdyaWZmZSB1bmQgbWVociBBbnNwcmFjaGUgYW5kZXJlci4gRXMgd2lyZCBhYmVyIGF1Y2ggbWVociDDvGJlciBkYXMgIndpciIgZ2VzcHJvY2hlbiwgw7xiZXIgImFuZGVyZSIgdW5kICJBdXNzZW5zdGVoZW5kZSIsIHVuZCBlcyBrb21tZW4gaMOkdWZpZ2VyIHRhYnVpc2llcnRlIEJlZ3JpZmZlIHZvci4gRGFzIE5hY2hyaWNodGVua29ycHVzIGVudGjDpGx0IHp1ZGVtIG1laHIga29nbml0aXZlIEJlZ3JpZmZlLgoKWnVzYW1tZW5mYXNzZW5kIGvDtm5ubmUgd2lyIGZlc3RoYWx0ZW4sIGRhcyBMZXhpa2Egc2VociBuw7x0emxpY2hlIFdlcmt6ZXVnZSBmw7xyIGRpZSBVbnRlcnN1Y2h1bmcgdm9uIEluaGFsdGVuIHNpbmQuIERpZXMgZ2lsdCBpbiBiZXNvbmRlcmVtIE1hw59lLCB3ZW5uIHNpZSB2aWVsZSB1bmQgZ2VzY2hhY2h0ZWx0ZSBLYXRlZ29yaWVuIGVudGhhbHRlbiwgdW5kIHdlbm4gaWhyZSBBYmRlY2t1bmcgaGlucmVpY2hlbmQgaXN0IChkLmguIGRpZSBCZWdyaWZmZSBpbSBMZXhpa29uIGF1Y2ggdGF0c8OkY2hsaWNoIGltIEtvcnB1cyB2b3Jrb21tZW4pLiBMZXhpa2Egc3Rvw59lbiBzY2huZWxsIGFuIGlocmUgR3Jlbnplbiwgd2VubiBzaWUgenUga2xlaW4gb2RlciB6dSBncm9iIHN0cnVrdHVyaWVydCBzaW5kLiBadWRlbSBtdXNzIG1hbiBlaW4gcGFzc2VuZGVzIExleGlrb24gw7xiZXJoYXVwdCBlcnN0IGVpbm1hbCBmaW5kZW4uIE9obmUgTGV4aWtvbiBibGVpYmVuIGFiZXIgenVtIEdsw7xjayBuw7x0emxpY2hlIGluZHVrdGl2ZSBNZXRob2RlbiwgYXVmIGRpZSBtYW4genVyw7xja2dyZWlmZW4ga2Fubi4KCgo=