1 Aufgaben

In diesem Teil wollen wir den Datensatz npk auswerten:

library(tidyverse)
Registered S3 methods overwritten by 'dbplyr':
  method         from
  print.tbl_lazy     
  print.tbl_sql      
── Attaching packages ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── tidyverse 1.3.2 ──✔ ggplot2 3.3.6      ✔ purrr   0.3.4 
✔ tibble  3.1.8      ✔ dplyr   1.0.10
✔ tidyr   1.2.1      ✔ stringr 1.4.1 
✔ readr   2.1.3      ✔ forcats 0.5.2 ── Conflicts ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
npk <- as_tibble(npk)
npk

Wie bereits erläutert handelt es sich bei dem Datensatz um ein typischen vollständigen Versuchsplan aus dem Bereich der Agrarwissenschaften. Der Datzensatz beschreibt den Einfluss des Einsatzes von Stickstoff (N), Phosphat (P) und Kalium (K) auf den Ertrag von Erbsen (yield).

1.1 Übungsaufgaben

  1. Werten Sie den Datzensatz npk mit einer passenden ANOVA aus.

    1. Verschaffen Sie sich eine (visuelle/statistische) Übersicht über die Daten.

    2. Prüfen Sie die Voraussetzungen der einfachen ANOVA.

    3. Wenden Sie das passende ANOVA-Modell an.

    4. Interpretieren Sie die Ergebnisse.

1.2 Lösungen

1.2.1 Werten Sie den Datzensatz npk mit einer passenden ANOVA aus.

1.2.1.1 Verschaffen Sie sich eine (visuelle/statistische) Übersicht über die Daten.

# Dimension, Datentypen:
npk
str(npk)
tibble [24 × 5] (S3: tbl_df/tbl/data.frame)
 $ block: Factor w/ 6 levels "1","2","3","4",..: 1 1 1 1 2 2 2 2 3 3 ...
 $ N    : Factor w/ 2 levels "0","1": 1 2 1 2 2 2 1 1 1 2 ...
 $ P    : Factor w/ 2 levels "0","1": 2 2 1 1 1 2 1 2 2 2 ...
 $ K    : Factor w/ 2 levels "0","1": 2 1 1 2 1 2 2 1 1 2 ...
 $ yield: num [1:24] 49.5 62.8 46.8 57 59.8 58.5 55.5 56 62.8 55.8 ...
dim(npk)
[1] 24  5
# Statistische Maßzahlen
summary(npk)
 block N      P      K          yield      
 1:4   0:12   0:12   0:12   Min.   :44.20  
 2:4   1:12   1:12   1:12   1st Qu.:49.73  
 3:4                        Median :55.65  
 4:4                        Mean   :54.88  
 5:4                        3rd Qu.:58.62  
 6:4                        Max.   :69.50  

Zuvor hatten wir bereits gesehen, dass der Versuch balanciert ist, d. h. jede Kombination von dem Einsatz von Stickstoff, Phosphat und Kalium liegt genau in dreifacher Wiederholung vor.

An dieser Stelle könnten wir den Ertrag noch zusätzlich visualisieren:

ggplot(npk) +
  geom_boxplot(aes(N, yield, color = P, fill = K)) +
  labs(y = "Ertrag") +
  scale_color_viridis_d()

  • Anhand der unterschiedlichen Gruppierung durch Aufteilung (x-Achse) sowie der Färbung (Füll-und Randfarbe).
  • Beispielsweise führt das Auslassen der Anwendung von Stickstoff sowie der Einsatz von Phosphat und Kalium zur kleinste Box (geringster Ertrag).
  • Der größte Ertrag scheint nur bei dem Einsatz von Stickstoff erzielt worden zu sein.
  • Die Boxen scheinen etwas zu variieren. Die Voraussetzungen testen wir in dem nächsten Schritt, um diesem auf den Grund zu gehen.

1.2.1.2 Prüfen Sie die Voraussetzungen der einfachen ANOVA.

Ausreißer: In dem vorherigen Boxplots schienen keine Ausreißer vorhanden zu sein.

library(rstatix)

Attache Paket: ‘rstatix’

Das folgende Objekt ist maskiert ‘package:stats’:

    filter
npk %>%
  group_by(N, P, K) %>%
  identify_outliers(yield)

Normalverteilung: Hierzu betrachten wir Histogramme sowie den Shapiro-Wilk-Test:

ggplot(npk, aes(yield, ..density..)) +
  geom_histogram(fill = "ForestGreen", alpha = 0.9, bins = 8) +
  geom_density(color = "tomato", fill = "tomato3", alpha = 0.2)

  • Die gesamte Tendenz der Variable yield könnte normalverteilt sein.

  • Einzelnen Gruppen können wir hier nur schwierig betrachten, da der Umfang zu gering ist:

ggplot(npk, aes(yield, ..density.., fill = N, color = N)) +
  geom_histogram( alpha = 0.7, bins = 6) +
  geom_density(alpha = 0.3) +
  facet_grid(P ~ K)

Shapiro-Wilk-Test für alle Gruppen:

shapiro.test(npk$yield)
npk %>%
  group_by(N, P, K) %>%
  shapiro_test(yield)
  • Der Shapiro-Wilk-Test für alle Gruppen gemeinsam gibt mit p = 0,87 (> ⍺) an, dass yield normalverteilt ist.

  • Wenn wir für jede einzelne Gruppe separat testen, scheint nur der Einsatz von Stickstoff und Kalium einen p-Wert unterhalb von 0,05 aufzuweisen. Somit sind die Daten tendenziell normalverteilt (wenn auch nicht perfekt, da wenig Daten pro Gruppe).

  • Falls mehrfaktorielle Daten vorliegen, die überhaupt nicht normalverteilt sind, kann man überlegen, diese zu transfomieren (log, Box-Cox, …).

Um genauer zu sein, sollten die Residuen des zugehörigen linearen Modells einer Normalverteilung folgen. Das ließe sich wie folgt bestimmen:

lm(yield ~ N * P * K, data = npk) %>%
    residuals() %>%
    shapiro.test()
  • Auch hier sehen wir (p > 0,05), dass eine Normalverteilung vorliegt

Varianzhomogenität: Hierzu könnten wir die Größen der Boxplots betrachten, welche einigermaßen gleich groß sein sollten. Einfacher ist es, den Levene-Test zu verwenden:

npk %>%
  levene_test(yield ~ N * P * K)
  • Bei dem Levene-Test wird immer das * zwischen den Faktoren verwendet, da auch die gemeinsamen Varianzen eine Rolle spielen

  • Da der p-Wert (~0,93) deutlich über dem üblichen Signifikanzniveau liegt, können wir hier auch von Varianzhomogenität ausgehen.

1.2.1.3 Wenden Sie das passende ANOVA-Modell an.

Da die Daten grob normalverteilt sind, es keine Ausreißer gibt und die Varianzhomogenität ebenfalls gegeben ist, können wir die mehrfaktorielle ANOVA anwenden:

npk %>%
  anova_test(yield ~ N * P * K)
  • Achten Sie darauf, dass zwischen jedem Faktor das * steht, sodass Interaktionen der Faktoren betrachtet werden.

  • Die p-Werte zeigen auf, dass nur der Haupteffekt von dem Stickstoffeinsatz einen signifikanten Einfluss aufweist (Unterschied zwischen Einsatz und keinem Stickstoffeinsatz auf den Ertrag).

  • Man könnte nun einen Post-Hoc-Test durchführen, jedoch wird dieser eine Menge an nicht-signifikanten Paaren anzeigen:

npk %>%
  tukey_hsd(yield ~ N * P * K) %>%
  filter(p.adj < 0.05)
  • Wir sehen erneut, dass sich die Gruppe mit dem Einsatz von Stickstoff und die Gruppe ohne dessen Einsatz (als Ganze) signifikant (p < 0,05) unterscheiden. Dem ergänzend scheint sich der Vergleich von dem Einsatz von Stickstoff und ohne Stickstoff bezüglich des Einsatzes von Kalium zu unterscheiden (N:K).

  • Ersteres scheint hierbei das hauptsächliche Ergebnis zu sein.

  • Übersichtlicher wäre unter Umständen hierbei die Fixierung der Kalium-und Phosphatgruppen:

npk %>%
  group_by(P , K) %>%
  anova_test(yield ~ N)
npk %>%
  group_by(P, K) %>%
  tukey_hsd(yield ~ N)

An dieser Stelle könnten wir bereits fertig sein, denn keine Interaktion ist signifikant und es gibt nur zwei Gruppen für jeden Faktor (Anwendung oder keine Anwendung)

Betrachten wir noch eine kleine Verfeinerung des Modells. Da der Block, in denen die Erbsen angebaut wurden ebenfalls einen Einfluss auf das Wachstum der Pflanze haben kann (z. B. durch leicht unterschiedliche Mineralstoffe, Wässerung, usw.) können wir die Variable block als “Störfaktor” in das Modell aufnehmen. Hierzu wird dieser einfach durch das + vor die anderen Faktoren gesetzt:

aov_ergebnis <- npk %>%
  anova_test(yield ~ block + N * P * K)
aov_ergebnis
  • Interessant ist hierbei, dass der Block einen signifikanten Einfluss hat (das interessiert uns im Gesamtbild des Versuchs eigentlich nicht) sowie zusätzlich Kalium.

  • Allerdings scheinen die gesamte Interaktion N:K:P sowie die Interaktionen N:P, N:K und P:K nicht signifikant zu sein.

  • Da keine Interaktionen signifikant sind, müssen wir uns keine paarweisen Vergleiche anschauen, da alle Faktoren nur zwei Ausprägungen haben:

# ANOVA und Tukey-Test erfüllen denselben Zweck (da nur zwei Ausprägungen vorhanden sind)
npk %>%
  group_by(P, K) %>%
  anova_test(yield ~ N)
npk %>%
  group_by(P, K) %>%
  tukey_hsd(yield ~ N)

1.2.1.4 Interpretieren Sie die Ergebnisse.

# Für die Grafik benötigen wir dennoch die Tabelle der paarweisen Vergleichen:
tukey_ergebnis <- npk %>%
  tukey_hsd(yield ~ block + N * P * K) %>%
    filter(term == "N")
ggplot(npk) +
  geom_boxplot(aes(N, yield, fill = N)) +
  ggpubr::stat_pvalue_manual(tukey_ergebnis, label = "p.adj.signif", y.position = 72) +
  theme(legend.position = NULL) +
  # Zusätzliche Information des Tests:
  labs(title = "Stickstoffbehandlung weist einen positiven Einfluss auf das Erbsenwachstum auf",
       subtitle = get_test_label(aov_ergebnis, detailed = TRUE, row = 2),
       y = "Ertrag")
  • Der Einsatz von Stickstoff hat einen signifikanten (positiven) Einfluss auf das Wachstum von Erbsen

  • Wenn wir zusätzlich den Block in dem Modell berücksichtigen (Störfaktor), dann hat ebenfalls Kalium einen signifikanten Einfluss auf das Wachstum von Erbsen.

tukey_ergebnis <- npk %>%
  tukey_hsd(yield ~ block + N * P * K) %>%
    filter(term == "K")
ggplot(npk) +
  geom_boxplot(aes(K, yield, fill = K)) +
  ggpubr::stat_pvalue_manual(tukey_ergebnis, label = "p.adj.signif", y.position = 72) +
  theme(legend.position = NULL) +
  # Zusätzliche Information des Tests:
  labs(title = "Kalium weist einen negativen Einfluss auf das Erbsenwachstum auf",
       subtitle = get_test_label(aov_ergebnis, detailed = TRUE, row = 4),
       y = "Ertrag")
  • Bei Kalium scheint dieser Trend jedoch negativ zu sein.

  • Theoretisch könnten wir uns genauer anschauen, welche Gruppen diese Unterschiede aufweisen, aber das ist nicht ganz so wichtig:

npk %>%
  tukey_hsd(yield ~ block + N * P * K)

Insgesamt sehen wir signifikante Haupteffekte von Stickstoff (positiv) und Kalium (negativ), d. h. unabhängig der anderen Faktoren sorgen Stickstoff und Kalium durchschnittlich für einen signifikanten Einfluss auf das Erbsenwachstum.

Es gab (abhängig von der Betrachtungweise) keine signifikante Interaktion, d. h. eine Kombination der Anwendung der drei Faktoren scheint keinen signifikanten Einfluss auf das Erbsenwachstum zu haben.

Wir sehen zusätzlich, dass die unterschiedlichen Blöcke einen hohen Einfluss auf die anderen Faktoren haben und das Experiment “stören”.

Abschließend kann man überlegen, warum Kalium einen negativen Einfluss hat und die Interaktionen keine Signfikanz aufzeigen, da üblicherweise Kaliummangel schlecht für Pflanzen ist und das Verhältnis von NPK entscheidend ist für Düngemittel.

Es mag sein, dass der verwendete Dünger zu viel Kalium enthalten hat, der Boden bereits mit Kalium gesättigt war oder Erbsen keinen Zusatz von Kalium benötigen, sodass der zusätzliche Einsatz von Kalium einen negativen Effekt hatte.

Stickstoff hatte wie erwartet einen positiven Effekt, der unabhängig von Kalium und Phosphat ist.

Da Phosphat keinen Effekt aufzeigt, auch nicht in Kombination mit Stickstoff und Kalium, ist es möglich, dass Phosphat nicht im passenden Maße eingesetzt wurde oder tatsächlich keine Wirkung auf Erbsenwachstum hat.

Bei wiederholtem Experiment könnte auch überlegt werden, die Bedingungen der veschiedenen Blöcke gleichmäßiger zu halten (Bewässerung, Sonne, Erde, usw.).

Weitere Interpretationen obliegen dem Expertenwissen im Bereich der Pflanzenzucht rund um die Erbse. Eine Optimierung der Nährstoffanwendung

LS0tCnRpdGxlOiAiw5xidW5nc3pldHRlbCA5IgpvdXRwdXQ6IAogIGh0bWxfbm90ZWJvb2s6IAogICAgaGlnaGxpZ2h0OiB0YW5nbwogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMKZWRpdG9yX29wdGlvbnM6IAogIG1hcmtkb3duOiAKICAgIHdyYXA6IDcyCi0tLQoKIyBBdWZnYWJlbgoKSW4gZGllc2VtIFRlaWwgd29sbGVuIHdpciBkZW4gRGF0ZW5zYXR6IGBucGtgIGF1c3dlcnRlbjoKCmBgYHtyfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbnBrIDwtIGFzX3RpYmJsZShucGspCm5wawpgYGAKCldpZSBiZXJlaXRzIGVybMOkdXRlcnQgaGFuZGVsdCBlcyBzaWNoIGJlaSBkZW0gRGF0ZW5zYXR6IHVtIGVpbiB0eXBpc2NoZW4Kdm9sbHN0w6RuZGlnZW4gVmVyc3VjaHNwbGFuIGF1cyBkZW0gQmVyZWljaCBkZXIgQWdyYXJ3aXNzZW5zY2hhZnRlbi4gRGVyCkRhdHplbnNhdHogYmVzY2hyZWlidCBkZW4gRWluZmx1c3MgZGVzIEVpbnNhdHplcyB2b24gU3RpY2tzdG9mZiAoYE5gKSwKUGhvc3BoYXQgKGBQYCkgdW5kIEthbGl1bSAoYEtgKSBhdWYgZGVuIEVydHJhZyB2b24gRXJic2VuIChgeWllbGRgKS4KCiMjIMOcYnVuZ3NhdWZnYWJlbgoKMS4gIFdlcnRlbiBTaWUgZGVuIERhdHplbnNhdHogYG5wa2AgbWl0IGVpbmVyIHBhc3NlbmRlbiBBTk9WQSBhdXMuCgogICAgMS4gIFZlcnNjaGFmZmVuIFNpZSBzaWNoIGVpbmUgKHZpc3VlbGxlL3N0YXRpc3Rpc2NoZSkgw5xiZXJzaWNodCDDvGJlcgogICAgICAgIGRpZSBEYXRlbi4KCiAgICAyLiAgUHLDvGZlbiBTaWUgZGllIFZvcmF1c3NldHp1bmdlbiBkZXIgZWluZmFjaGVuIEFOT1ZBLgoKICAgIDMuICBXZW5kZW4gU2llIGRhcyBwYXNzZW5kZSBBTk9WQS1Nb2RlbGwgYW4uCgogICAgNC4gIEludGVycHJldGllcmVuIFNpZSBkaWUgRXJnZWJuaXNzZS4KCiMjIEzDtnN1bmdlbgoKIyMjIFdlcnRlbiBTaWUgZGVuIERhdHplbnNhdHogYG5wa2AgbWl0IGVpbmVyIHBhc3NlbmRlbiBBTk9WQSBhdXMuCgojIyMjIFZlcnNjaGFmZmVuIFNpZSBzaWNoIGVpbmUgKHZpc3VlbGxlL3N0YXRpc3Rpc2NoZSkgw5xiZXJzaWNodCDDvGJlciBkaWUgRGF0ZW4uCgpgYGB7cn0KIyBEaW1lbnNpb24sIERhdGVudHlwZW46Cm5wawpzdHIobnBrKQpkaW0obnBrKQojIFN0YXRpc3Rpc2NoZSBNYcOfemFobGVuCnN1bW1hcnkobnBrKQpgYGAKClp1dm9yIGhhdHRlbiB3aXIgYmVyZWl0cyBnZXNlaGVuLCBkYXNzIGRlciBWZXJzdWNoIGJhbGFuY2llcnQgaXN0LCBkLiBoLgpqZWRlIEtvbWJpbmF0aW9uIHZvbiBkZW0gRWluc2F0eiB2b24gU3RpY2tzdG9mZiwgUGhvc3BoYXQgdW5kIEthbGl1bQpsaWVndCBnZW5hdSBpbiBkcmVpZmFjaGVyIFdpZWRlcmhvbHVuZyB2b3IuCgpBbiBkaWVzZXIgU3RlbGxlIGvDtm5udGVuIHdpciBkZW4gRXJ0cmFnIG5vY2ggenVzw6R0emxpY2ggdmlzdWFsaXNpZXJlbjoKCmBgYHtyfQpnZ3Bsb3QobnBrKSArCiAgZ2VvbV9ib3hwbG90KGFlcyhOLCB5aWVsZCwgY29sb3IgPSBQLCBmaWxsID0gSykpICsKICBsYWJzKHkgPSAiRXJ0cmFnIikgKwogIHNjYWxlX2NvbG9yX3ZpcmlkaXNfZCgpCmBgYAoKLSAgIEFuaGFuZCBkZXIgdW50ZXJzY2hpZWRsaWNoZW4gR3J1cHBpZXJ1bmcgZHVyY2ggQXVmdGVpbHVuZyAoeC1BY2hzZSkKICAgIHNvd2llIGRlciBGw6RyYnVuZyAoRsO8bGwtdW5kIFJhbmRmYXJiZSkuCi0gICBCZWlzcGllbHN3ZWlzZSBmw7xocnQgZGFzIEF1c2xhc3NlbiBkZXIgQW53ZW5kdW5nIHZvbiBTdGlja3N0b2ZmCiAgICBzb3dpZSBkZXIgRWluc2F0eiB2b24gUGhvc3BoYXQgdW5kIEthbGl1bSB6dXIga2xlaW5zdGUgQm94CiAgICAoZ2VyaW5nc3RlciBFcnRyYWcpLgotICAgRGVyIGdyw7bDn3RlIEVydHJhZyBzY2hlaW50IG51ciBiZWkgZGVtIEVpbnNhdHogdm9uIFN0aWNrc3RvZmYgZXJ6aWVsdAogICAgd29yZGVuIHp1IHNlaW4uCi0gICBEaWUgQm94ZW4gc2NoZWluZW4gZXR3YXMgenUgdmFyaWllcmVuLiBEaWUgVm9yYXVzc2V0enVuZ2VuIHRlc3RlbgogICAgd2lyIGluIGRlbSBuw6RjaHN0ZW4gU2Nocml0dCwgdW0gZGllc2VtIGF1ZiBkZW4gR3J1bmQgenUgZ2VoZW4uCgojIyMjIFByw7xmZW4gU2llIGRpZSBWb3JhdXNzZXR6dW5nZW4gZGVyIGVpbmZhY2hlbiBBTk9WQS4KCioqQXVzcmVpw59lcioqOiBJbiBkZW0gdm9yaGVyaWdlbiBCb3hwbG90cyBzY2hpZW5lbiBrZWluZSBBdXNyZWnDn2VyCnZvcmhhbmRlbiB6dSBzZWluLgoKYGBge3J9CmxpYnJhcnkocnN0YXRpeCkKbnBrICU+JQogIGdyb3VwX2J5KE4sIFAsIEspICU+JQogIGlkZW50aWZ5X291dGxpZXJzKHlpZWxkKQpgYGAKCioqTm9ybWFsdmVydGVpbHVuZyoqOiBIaWVyenUgYmV0cmFjaHRlbiB3aXIgSGlzdG9ncmFtbWUgc293aWUgZGVuClNoYXBpcm8tV2lsay1UZXN0OgoKYGBge3J9CmdncGxvdChucGssIGFlcyh5aWVsZCwgLi5kZW5zaXR5Li4pKSArCiAgZ2VvbV9oaXN0b2dyYW0oZmlsbCA9ICJGb3Jlc3RHcmVlbiIsIGFscGhhID0gMC45LCBiaW5zID0gOCkgKwogIGdlb21fZGVuc2l0eShjb2xvciA9ICJ0b21hdG8iLCBmaWxsID0gInRvbWF0bzMiLCBhbHBoYSA9IDAuMikKYGBgCgotICAgRGllIGdlc2FtdGUgVGVuZGVueiBkZXIgVmFyaWFibGUgYHlpZWxkYCBrw7ZubnRlIG5vcm1hbHZlcnRlaWx0IHNlaW4uCgotICAgRWluemVsbmVuIEdydXBwZW4ga8O2bm5lbiB3aXIgaGllciBudXIgc2Nod2llcmlnIGJldHJhY2h0ZW4sIGRhIGRlcgogICAgVW1mYW5nIHp1IGdlcmluZyBpc3Q6CgpgYGB7cn0KZ2dwbG90KG5waywgYWVzKHlpZWxkLCAuLmRlbnNpdHkuLiwgZmlsbCA9IE4sIGNvbG9yID0gTikpICsKICBnZW9tX2hpc3RvZ3JhbSggYWxwaGEgPSAwLjcsIGJpbnMgPSA2KSArCiAgZ2VvbV9kZW5zaXR5KGFscGhhID0gMC4zKSArCiAgZmFjZXRfZ3JpZChQIH4gSykKYGBgCgpTaGFwaXJvLVdpbGstVGVzdCBmw7xyIGFsbGUgR3J1cHBlbjoKCmBgYHtyfQpzaGFwaXJvLnRlc3QobnBrJHlpZWxkKQpucGsgJT4lCiAgZ3JvdXBfYnkoTiwgUCwgSykgJT4lCiAgc2hhcGlyb190ZXN0KHlpZWxkKQpgYGAKCi0gICBEZXIgU2hhcGlyby1XaWxrLVRlc3QgZsO8ciBhbGxlIEdydXBwZW4gZ2VtZWluc2FtIGdpYnQgbWl0IHAgPSAwLDg3CiAgICAoXD4g4o26KSBhbiwgZGFzcyBgeWllbGRgIG5vcm1hbHZlcnRlaWx0IGlzdC4KCi0gICBXZW5uIHdpciBmw7xyIGplZGUgZWluemVsbmUgR3J1cHBlIHNlcGFyYXQgdGVzdGVuLCBzY2hlaW50IG51ciBkZXIKICAgIEVpbnNhdHogdm9uIFN0aWNrc3RvZmYgdW5kIEthbGl1bSBlaW5lbiBwLVdlcnQgdW50ZXJoYWxiIHZvbiAwLDA1CiAgICBhdWZ6dXdlaXNlbi4gU29taXQgc2luZCBkaWUgRGF0ZW4gdGVuZGVuemllbGwgbm9ybWFsdmVydGVpbHQgKHdlbm4KICAgIGF1Y2ggbmljaHQgcGVyZmVrdCwgZGEgd2VuaWcgRGF0ZW4gcHJvIEdydXBwZSkuCgotICAgRmFsbHMgbWVocmZha3RvcmllbGxlIERhdGVuIHZvcmxpZWdlbiwgZGllIMO8YmVyaGF1cHQgbmljaHQKICAgIG5vcm1hbHZlcnRlaWx0IHNpbmQsIGthbm4gbWFuIMO8YmVybGVnZW4sIGRpZXNlIHp1IHRyYW5zZm9taWVyZW4KICAgIChsb2csIEJveC1Db3gsIC4uLikuCgpVbSBnZW5hdWVyIHp1IHNlaW4sIHNvbGx0ZW4gZGllIFJlc2lkdWVuIGRlcyB6dWdlaMO2cmlnZW4gbGluZWFyZW4KTW9kZWxscyBlaW5lciBOb3JtYWx2ZXJ0ZWlsdW5nIGZvbGdlbi4gRGFzIGxpZcOfZSBzaWNoIHdpZSBmb2xndApiZXN0aW1tZW46CgpgYGB7cn0KbG0oeWllbGQgfiBOICogUCAqIEssIGRhdGEgPSBucGspICU+JQoJcmVzaWR1YWxzKCkgJT4lCglzaGFwaXJvLnRlc3QoKQpgYGAKCi0gICBBdWNoIGhpZXIgc2VoZW4gd2lyIChwIFw+IDAsMDUpLCBkYXNzIGVpbmUgTm9ybWFsdmVydGVpbHVuZyB2b3JsaWVndAoKKipWYXJpYW56aG9tb2dlbml0w6R0Kio6IEhpZXJ6dSBrw7ZubnRlbiB3aXIgZGllIEdyw7bDn2VuIGRlciBCb3hwbG90cwpiZXRyYWNodGVuLCB3ZWxjaGUgZWluaWdlcm1hw59lbiBnbGVpY2ggZ3Jvw58gc2VpbiBzb2xsdGVuLiBFaW5mYWNoZXIgaXN0CmVzLCBkZW4gTGV2ZW5lLVRlc3QgenUgdmVyd2VuZGVuOgoKYGBge3J9Cm5wayAlPiUKICBsZXZlbmVfdGVzdCh5aWVsZCB+IE4gKiBQICogSykKYGBgCgotICAgQmVpIGRlbSBMZXZlbmUtVGVzdCB3aXJkIGltbWVyIGRhcyBgKmAgendpc2NoZW4gZGVuIEZha3RvcmVuCiAgICB2ZXJ3ZW5kZXQsIGRhIGF1Y2ggZGllIGdlbWVpbnNhbWVuIFZhcmlhbnplbiBlaW5lIFJvbGxlIHNwaWVsZW4KCi0gICBEYSBkZXIgcC1XZXJ0IChcfjAsOTMpIGRldXRsaWNoIMO8YmVyIGRlbSDDvGJsaWNoZW4gU2lnbmlmaWthbnpuaXZlYXUKICAgIGxpZWd0LCBrw7ZubmVuIHdpciBoaWVyIGF1Y2ggdm9uIFZhcmlhbnpob21vZ2VuaXTDpHQgYXVzZ2VoZW4uCgojIyMjIFdlbmRlbiBTaWUgZGFzIHBhc3NlbmRlIEFOT1ZBLU1vZGVsbCBhbi4KCkRhIGRpZSBEYXRlbiBncm9iIG5vcm1hbHZlcnRlaWx0IHNpbmQsIGVzIGtlaW5lIEF1c3JlacOfZXIgZ2lidCB1bmQgZGllClZhcmlhbnpob21vZ2VuaXTDpHQgZWJlbmZhbGxzIGdlZ2ViZW4gaXN0LCBrw7ZubmVuIHdpciBkaWUgbWVocmZha3RvcmllbGxlCkFOT1ZBIGFud2VuZGVuOgoKYGBge3J9Cm5wayAlPiUKICBhbm92YV90ZXN0KHlpZWxkIH4gTiAqIFAgKiBLKQpgYGAKCi0gICBBY2h0ZW4gU2llIGRhcmF1ZiwgZGFzcyB6d2lzY2hlbiBqZWRlbSBGYWt0b3IgZGFzIGAqYCBzdGVodCwgc29kYXNzCiAgICBJbnRlcmFrdGlvbmVuIGRlciBGYWt0b3JlbiBiZXRyYWNodGV0IHdlcmRlbi4KCi0gICBEaWUgcC1XZXJ0ZSB6ZWlnZW4gYXVmLCBkYXNzIG51ciBkZXIgSGF1cHRlZmZla3Qgdm9uIGRlbQogICAgU3RpY2tzdG9mZmVpbnNhdHogZWluZW4gc2lnbmlmaWthbnRlbiBFaW5mbHVzcyBhdWZ3ZWlzdCAoVW50ZXJzY2hpZWQKICAgIHp3aXNjaGVuIEVpbnNhdHogdW5kIGtlaW5lbSBTdGlja3N0b2ZmZWluc2F0eiBhdWYgZGVuIEVydHJhZykuCgotICAgTWFuIGvDtm5udGUgbnVuIGVpbmVuIFBvc3QtSG9jLVRlc3QgZHVyY2hmw7xocmVuLCBqZWRvY2ggd2lyZCBkaWVzZXIKICAgIGVpbmUgTWVuZ2UgYW4gbmljaHQtc2lnbmlmaWthbnRlbiBQYWFyZW4gYW56ZWlnZW46CgpgYGB7cn0KbnBrICU+JQogIHR1a2V5X2hzZCh5aWVsZCB+IE4gKiBQICogSykgJT4lCiAgZmlsdGVyKHAuYWRqIDwgMC4wNSkKYGBgCgotICAgV2lyIHNlaGVuIGVybmV1dCwgZGFzcyBzaWNoIGRpZSBHcnVwcGUgbWl0IGRlbSBFaW5zYXR6IHZvbgogICAgU3RpY2tzdG9mZiB1bmQgZGllIEdydXBwZSBvaG5lIGRlc3NlbiBFaW5zYXR6IChhbHMgR2FuemUpCiAgICBzaWduaWZpa2FudCAocCBcPCAwLDA1KSB1bnRlcnNjaGVpZGVuLiBEZW0gZXJnw6RuemVuZCBzY2hlaW50IHNpY2gKICAgIGRlciBWZXJnbGVpY2ggdm9uIGRlbSBFaW5zYXR6IHZvbiBTdGlja3N0b2ZmIHVuZCBvaG5lIFN0aWNrc3RvZmYKICAgIGJlesO8Z2xpY2ggZGVzIEVpbnNhdHplcyB2b24gS2FsaXVtIHp1IHVudGVyc2NoZWlkZW4gKGBOOktgKS4KCi0gICBFcnN0ZXJlcyBzY2hlaW50IGhpZXJiZWkgZGFzIGhhdXB0c8OkY2hsaWNoZSBFcmdlYm5pcyB6dSBzZWluLgoKLSAgIMOcYmVyc2ljaHRsaWNoZXIgd8OkcmUgdW50ZXIgVW1zdMOkbmRlbiBoaWVyYmVpIGRpZSBGaXhpZXJ1bmcgZGVyCiAgICBLYWxpdW0tdW5kIFBob3NwaGF0Z3J1cHBlbjoKCmBgYHtyfQpucGsgJT4lCiAgZ3JvdXBfYnkoUCAsIEspICU+JQogIGFub3ZhX3Rlc3QoeWllbGQgfiBOKQpucGsgJT4lCiAgZ3JvdXBfYnkoUCwgSykgJT4lCiAgdHVrZXlfaHNkKHlpZWxkIH4gTikKYGBgCgpBbiBkaWVzZXIgU3RlbGxlIGvDtm5udGVuIHdpciBiZXJlaXRzIGZlcnRpZyBzZWluLCBkZW5uIGtlaW5lIEludGVyYWt0aW9uCmlzdCBzaWduaWZpa2FudCB1bmQgZXMgZ2lidCBudXIgendlaSBHcnVwcGVuIGbDvHIgamVkZW4gRmFrdG9yIChBbndlbmR1bmcKb2RlciBrZWluZSBBbndlbmR1bmcpCgpCZXRyYWNodGVuIHdpciBub2NoIGVpbmUga2xlaW5lIFZlcmZlaW5lcnVuZyBkZXMgTW9kZWxscy4gRGEgZGVyIEJsb2NrLAppbiBkZW5lbiBkaWUgRXJic2VuIGFuZ2ViYXV0IHd1cmRlbiBlYmVuZmFsbHMgZWluZW4gRWluZmx1c3MgYXVmIGRhcwpXYWNoc3R1bSBkZXIgUGZsYW56ZSBoYWJlbiBrYW5uICh6LiBCLiBkdXJjaCBsZWljaHQgdW50ZXJzY2hpZWRsaWNoZQpNaW5lcmFsc3RvZmZlLCBXw6Rzc2VydW5nLCB1c3cuKSBrw7ZubmVuIHdpciBkaWUgVmFyaWFibGUgYGJsb2NrYCBhbHMKIlN0w7ZyZmFrdG9yIiBpbiBkYXMgTW9kZWxsIGF1Zm5laG1lbi4gSGllcnp1IHdpcmQgZGllc2VyIGVpbmZhY2ggZHVyY2gKZGFzIGArYCAqKnZvcioqIGRpZSBhbmRlcmVuIEZha3RvcmVuIGdlc2V0enQ6CgpgYGB7cn0KYW92X2VyZ2VibmlzIDwtIG5wayAlPiUKICBhbm92YV90ZXN0KHlpZWxkIH4gYmxvY2sgKyBOICogUCAqIEspCmFvdl9lcmdlYm5pcwpgYGAKCi0gICBJbnRlcmVzc2FudCBpc3QgaGllcmJlaSwgZGFzcyBkZXIgQmxvY2sgZWluZW4gc2lnbmlmaWthbnRlbiBFaW5mbHVzcwogICAgaGF0IChkYXMgaW50ZXJlc3NpZXJ0IHVucyBpbSBHZXNhbXRiaWxkIGRlcyBWZXJzdWNocyBlaWdlbnRsaWNoCiAgICBuaWNodCkgc293aWUgenVzw6R0emxpY2ggS2FsaXVtLgoKLSAgIEFsbGVyZGluZ3Mgc2NoZWluZW4gZGllIGdlc2FtdGUgSW50ZXJha3Rpb24gYE46SzpQYCBzb3dpZSBkaWUKICAgIEludGVyYWt0aW9uZW4gYE46UGAsIGBOOktgIHVuZCBgUDpLYCBuaWNodCBzaWduaWZpa2FudCB6dSBzZWluLgoKLSAgIERhIGtlaW5lIEludGVyYWt0aW9uZW4gc2lnbmlmaWthbnQgc2luZCwgbcO8c3NlbiB3aXIgdW5zIGtlaW5lCiAgICBwYWFyd2Vpc2VuIFZlcmdsZWljaGUgYW5zY2hhdWVuLCBkYSBhbGxlIEZha3RvcmVuIG51ciB6d2VpCiAgICBBdXNwcsOkZ3VuZ2VuIGhhYmVuOgoKYGBge3J9CiMgQU5PVkEgdW5kIFR1a2V5LVRlc3QgZXJmw7xsbGVuIGRlbnNlbGJlbiBad2VjayAoZGEgbnVyIHp3ZWkgQXVzcHLDpGd1bmdlbiB2b3JoYW5kZW4gc2luZCkKbnBrICU+JQogIGdyb3VwX2J5KFAsIEspICU+JQogIGFub3ZhX3Rlc3QoeWllbGQgfiBOKQpucGsgJT4lCiAgZ3JvdXBfYnkoUCwgSykgJT4lCiAgdHVrZXlfaHNkKHlpZWxkIH4gTikKYGBgCgojIyMjIEludGVycHJldGllcmVuIFNpZSBkaWUgRXJnZWJuaXNzZS4KCmBgYHtyfQojIEbDvHIgZGllIEdyYWZpayBiZW7DtnRpZ2VuIHdpciBkZW5ub2NoIGRpZSBUYWJlbGxlIGRlciBwYWFyd2Vpc2VuIFZlcmdsZWljaGVuOgp0dWtleV9lcmdlYm5pcyA8LSBucGsgJT4lCiAgdHVrZXlfaHNkKHlpZWxkIH4gYmxvY2sgKyBOICogUCAqIEspICU+JQoJZmlsdGVyKHRlcm0gPT0gIk4iKQpnZ3Bsb3QobnBrKSArCiAgZ2VvbV9ib3hwbG90KGFlcyhOLCB5aWVsZCwgZmlsbCA9IE4pKSArCiAgZ2dwdWJyOjpzdGF0X3B2YWx1ZV9tYW51YWwodHVrZXlfZXJnZWJuaXMsIGxhYmVsID0gInAuYWRqLnNpZ25pZiIsIHkucG9zaXRpb24gPSA3MikgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9IE5VTEwpICsKICAjIFp1c8OkdHpsaWNoZSBJbmZvcm1hdGlvbiBkZXMgVGVzdHM6CiAgbGFicyh0aXRsZSA9ICJTdGlja3N0b2ZmYmVoYW5kbHVuZyB3ZWlzdCBlaW5lbiBwb3NpdGl2ZW4gRWluZmx1c3MgYXVmIGRhcyBFcmJzZW53YWNoc3R1bSBhdWYiLAogICAgICAgc3VidGl0bGUgPSBnZXRfdGVzdF9sYWJlbChhb3ZfZXJnZWJuaXMsIGRldGFpbGVkID0gVFJVRSwgcm93ID0gMiksCiAgICAgICB5ID0gIkVydHJhZyIpCmBgYAoKLSAgIERlciBFaW5zYXR6IHZvbiBTdGlja3N0b2ZmIGhhdCBlaW5lbiBzaWduaWZpa2FudGVuIChwb3NpdGl2ZW4pCiAgICBFaW5mbHVzcyBhdWYgZGFzIFdhY2hzdHVtIHZvbiBFcmJzZW4KCi0gICBXZW5uIHdpciB6dXPDpHR6bGljaCBkZW4gQmxvY2sgaW4gZGVtIE1vZGVsbCBiZXLDvGNrc2ljaHRpZ2VuCiAgICAoU3TDtnJmYWt0b3IpLCBkYW5uIGhhdCBlYmVuZmFsbHMgS2FsaXVtIGVpbmVuIHNpZ25pZmlrYW50ZW4gRWluZmx1c3MKICAgIGF1ZiBkYXMgV2FjaHN0dW0gdm9uIEVyYnNlbi4KCmBgYHtyfQp0dWtleV9lcmdlYm5pcyA8LSBucGsgJT4lCiAgdHVrZXlfaHNkKHlpZWxkIH4gYmxvY2sgKyBOICogUCAqIEspICU+JQoJZmlsdGVyKHRlcm0gPT0gIksiKQpnZ3Bsb3QobnBrKSArCiAgZ2VvbV9ib3hwbG90KGFlcyhLLCB5aWVsZCwgZmlsbCA9IEspKSArCiAgZ2dwdWJyOjpzdGF0X3B2YWx1ZV9tYW51YWwodHVrZXlfZXJnZWJuaXMsIGxhYmVsID0gInAuYWRqLnNpZ25pZiIsIHkucG9zaXRpb24gPSA3MikgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9IE5VTEwpICsKICAjIFp1c8OkdHpsaWNoZSBJbmZvcm1hdGlvbiBkZXMgVGVzdHM6CiAgbGFicyh0aXRsZSA9ICJLYWxpdW0gd2Vpc3QgZWluZW4gbmVnYXRpdmVuIEVpbmZsdXNzIGF1ZiBkYXMgRXJic2Vud2FjaHN0dW0gYXVmIiwKICAgICAgIHN1YnRpdGxlID0gZ2V0X3Rlc3RfbGFiZWwoYW92X2VyZ2VibmlzLCBkZXRhaWxlZCA9IFRSVUUsIHJvdyA9IDQpLAogICAgICAgeSA9ICJFcnRyYWciKQpgYGAKCi0gICBCZWkgS2FsaXVtIHNjaGVpbnQgZGllc2VyIFRyZW5kIGplZG9jaCBuZWdhdGl2IHp1IHNlaW4uCgotICAgVGhlb3JldGlzY2gga8O2bm50ZW4gd2lyIHVucyBnZW5hdWVyIGFuc2NoYXVlbiwgd2VsY2hlIEdydXBwZW4gZGllc2UKICAgIFVudGVyc2NoaWVkZSBhdWZ3ZWlzZW4sIGFiZXIgZGFzIGlzdCBuaWNodCBnYW56IHNvIHdpY2h0aWc6CgpgYGB7cn0KbnBrICU+JQogIHR1a2V5X2hzZCh5aWVsZCB+IGJsb2NrICsgTiAqIFAgKiBLKQpgYGAKCkluc2dlc2FtdCBzZWhlbiB3aXIgc2lnbmlmaWthbnRlIEhhdXB0ZWZmZWt0ZSB2b24gU3RpY2tzdG9mZiAocG9zaXRpdikKdW5kIEthbGl1bSAobmVnYXRpdiksIGQuIGguIHVuYWJow6RuZ2lnIGRlciBhbmRlcmVuIEZha3RvcmVuIHNvcmdlbgpTdGlja3N0b2ZmIHVuZCBLYWxpdW0gZHVyY2hzY2huaXR0bGljaCBmw7xyIGVpbmVuIHNpZ25pZmlrYW50ZW4gRWluZmx1c3MKYXVmIGRhcyBFcmJzZW53YWNoc3R1bS4KCkVzIGdhYiAoYWJow6RuZ2lnIHZvbiBkZXIgQmV0cmFjaHR1bmd3ZWlzZSkga2VpbmUgc2lnbmlmaWthbnRlCkludGVyYWt0aW9uLCBkLiBoLiBlaW5lIEtvbWJpbmF0aW9uIGRlciBBbndlbmR1bmcgZGVyIGRyZWkgRmFrdG9yZW4Kc2NoZWludCBrZWluZW4gc2lnbmlmaWthbnRlbiBFaW5mbHVzcyBhdWYgZGFzIEVyYnNlbndhY2hzdHVtIHp1IGhhYmVuLgoKV2lyIHNlaGVuIHp1c8OkdHpsaWNoLCBkYXNzIGRpZSB1bnRlcnNjaGllZGxpY2hlbiBCbMO2Y2tlIGVpbmVuIGhvaGVuCkVpbmZsdXNzIGF1ZiBkaWUgYW5kZXJlbiBGYWt0b3JlbiBoYWJlbiB1bmQgZGFzIEV4cGVyaW1lbnQgInN0w7ZyZW4iLgoKQWJzY2hsaWXDn2VuZCBrYW5uIG1hbiDDvGJlcmxlZ2VuLCB3YXJ1bSBLYWxpdW0gZWluZW4gbmVnYXRpdmVuIEVpbmZsdXNzCmhhdCB1bmQgZGllIEludGVyYWt0aW9uZW4ga2VpbmUgU2lnbmZpa2FueiBhdWZ6ZWlnZW4sIGRhIMO8YmxpY2hlcndlaXNlCkthbGl1bW1hbmdlbCBzY2hsZWNodCBmw7xyIFBmbGFuemVuIGlzdCB1bmQgZGFzIFZlcmjDpGx0bmlzIHZvbiBOUEsKZW50c2NoZWlkZW5kIGlzdCBmw7xyIETDvG5nZW1pdHRlbC4KCkVzIG1hZyBzZWluLCBkYXNzIGRlciB2ZXJ3ZW5kZXRlIETDvG5nZXIgenUgdmllbCBLYWxpdW0gZW50aGFsdGVuIGhhdCwKZGVyIEJvZGVuIGJlcmVpdHMgbWl0IEthbGl1bSBnZXPDpHR0aWd0IHdhciBvZGVyIEVyYnNlbiBrZWluZW4gWnVzYXR6IHZvbgpLYWxpdW0gYmVuw7Z0aWdlbiwgc29kYXNzIGRlciB6dXPDpHR6bGljaGUgRWluc2F0eiB2b24gS2FsaXVtIGVpbmVuCm5lZ2F0aXZlbiBFZmZla3QgaGF0dGUuCgpTdGlja3N0b2ZmIGhhdHRlIHdpZSBlcndhcnRldCBlaW5lbiBwb3NpdGl2ZW4gRWZmZWt0LCBkZXIgdW5hYmjDpG5naWcgdm9uCkthbGl1bSB1bmQgUGhvc3BoYXQgaXN0LgoKRGEgUGhvc3BoYXQga2VpbmVuIEVmZmVrdCBhdWZ6ZWlndCwgYXVjaCBuaWNodCBpbiBLb21iaW5hdGlvbiBtaXQKU3RpY2tzdG9mZiB1bmQgS2FsaXVtLCBpc3QgZXMgbcO2Z2xpY2gsIGRhc3MgUGhvc3BoYXQgbmljaHQgaW0gcGFzc2VuZGVuCk1hw59lIGVpbmdlc2V0enQgd3VyZGUgb2RlciB0YXRzw6RjaGxpY2gga2VpbmUgV2lya3VuZyBhdWYgRXJic2Vud2FjaHN0dW0KaGF0LgoKQmVpIHdpZWRlcmhvbHRlbSBFeHBlcmltZW50IGvDtm5udGUgYXVjaCDDvGJlcmxlZ3Qgd2VyZGVuLCBkaWUgQmVkaW5ndW5nZW4KZGVyIHZlc2NoaWVkZW5lbiBCbMO2Y2tlIGdsZWljaG3DpMOfaWdlciB6dSBoYWx0ZW4gKEJld8Okc3NlcnVuZywgU29ubmUsCkVyZGUsIHVzdy4pLgoKV2VpdGVyZSBJbnRlcnByZXRhdGlvbmVuIG9ibGllZ2VuIGRlbSBFeHBlcnRlbndpc3NlbiBpbSBCZXJlaWNoIGRlcgpQZmxhbnplbnp1Y2h0IHJ1bmQgdW0gZGllIEVyYnNlLiBFaW5lIE9wdGltaWVydW5nIGRlciBOw6RocnN0b2ZmYW53ZW5kdW5nCg==