1 Aufgaben

1.1 Übungsaufgaben

  1. Erstellen Sie eine beliebige Grafik des diamonds Datensatzes und fügen Sie der Grafik einen Überschrift (title), einen Untertitel (subtitle), eine “Unterschrift” (caption) und Beschriftungen der x-und y-Achse (x und y) sowie ein Farblabel bei.

  2. Verwenden Sie geom_text(), um Text in jede Ecke dieser Grafik zu zeichnen.

  3. Schauen Sie in die Beispiele der ?annotate() Funktion und fügen Sie mit Hilfe dieser Text in eine Grafik ein ohne vorher einen zusätzlichen tibble zu erstellen.

  4. Erstellen Sie ein Streudiagramm von displ und hwy des mpg Datensatzes.

    1. Filtern Sie zusätzlich für jeden Autotyp class nach dem effizientesten Auto.

    2. Markieren Sie diese Autos farblich anders als den Rest.

    3. Fügen Sie mit geom_segment und arrow() Pfeile in die Grafik ein, die auf die Punkte zeigen.

    4. Fügen Sie zusätzlich Label an das Ende der Pfeile ein, die das Automodell beschreiben.

    5. Fügen Sie schlussendlich der Grafik aussagekräftige Beschriftungen, usw. bei.

  5. Warum funktioniert der folgende Befehl nicht?

df <- tibble(
  x = rnorm(10000),
  y = rnorm(10000)
)
ggplot(df, aes(x, y)) +
  geom_hex() +
  scale_color_gradient(low = "white", high = "red") +
  coord_fixed()

6. Überschreiben Sie die Aesthetics in dem folgenden Befehl, um die Legende anschaulicher zu machen.

ggplot(diamonds, aes(carat, price)) +
  geom_point(aes(colour = cut), alpha = 1/20)

  1. Zeichnen Sie ein Streudiagramm von Sepal.Width und Sepal.Length des iris Datensatzes.
    1. Färben Sie die Punkte gemäß der Spezies ein.

    2. Fügen Sie Linien für jede Spezies hinzu und ändern Sie die linetype.

    3. Markieren Sie die kleinste und größte Pflanze jeder Spezies mit Pfeilen und Label.

    4. Beschriften Sie die Legende, Achsen und Titel sinnvoll.

1.2 Lösungen

1.2.1 Erstellen Sie eine beliebige Grafik des diamonds Datensatzes und fügen Sie der Grafik einen Überschrift (title), einen Untertitel (subtitle), eine “Unterschrift” (caption) und Beschriftungen der x-und y-Achse (x und y) sowie ein Farblabel bei.

Im folgenden Beispiel sehen wir die x-und y-Werte der Diamanten, wobei Farbgradienten und Achsen angepasst wurden:

library(viridis)
ggplot(diamonds, aes(x, y)) + 
    geom_hex() +
    scale_fill_viridis(begin = 0.4, end = 0.8, option = "A") +
    scale_x_continuous(breaks = seq(3, 15, 3), limits = c(3, 12), name = "y-Dimension") +
    scale_y_continuous(breaks = seq(3, 12, 3), limits = c(3, 12), name = "x-Dimension") +
    labs(caption = "Vergrößerte Ansicht",
             title = "Die meisten Diamanten weisen einen x-und y-Werte zwischen 3 und 12 auf",
             subtitle = "Besonders interessant ist der scheinbar lineare Zusammenhang",
             fill = "Anzahl")

1.2.2 Verwenden Sie geom_text(), um Text in jede Ecke dieser Grafik zu zeichnen.

label <- tibble(
    x = c(Inf, Inf, -Inf, -Inf),
    y = c(Inf, -Inf, Inf, -Inf),
    label = c("RO", "RU", "LO", "LU"),
    vjust = c("top", "bottom", "top", "bottom"),
    hjust = c("right", "right", "left", "left")
)
ggplot(diamonds, aes(x, y)) + 
    geom_hex() +
    scale_fill_viridis(begin = 0.4, end = 0.8, option = "A") +
    scale_x_continuous(breaks = seq(3, 15, 3), limits = c(3, 12), name = "y-Dimension") +
    scale_y_continuous(breaks = seq(3, 12, 3), limits = c(3, 12), name = "x-Dimension") +
    labs(caption = "Vergrößerte Ansicht",
             title = "Die meisten Diamanten weisen einen x-und y-Werte zwischen 3 und 12 auf",
             subtitle = "Besonders interessant ist der scheinbar lineare Zusammenhang",
             fill = "Anzahl") +
    geom_text(data = label, mapping = aes(label = label, vjust = vjust, hjust = hjust))

1.2.3 Schauen Sie in die Beispiele der ?annotate() Funktion und fügen Sie mit Hilfe dieser Text in eine Grafik ein ohne vorher einen zusätzlichen tibble zu erstellen.

label <- tibble(
    x = c(Inf, Inf, -Inf, -Inf),
    y = c(Inf, -Inf, Inf, -Inf),
    label = c("RO", "RU", "LO", "LU"),
    vjust = c("top", "bottom", "top", "bottom"),
    hjust = c("right", "right", "left", "left")
)
ggplot(diamonds, aes(x, y)) + 
    geom_hex() +
    scale_fill_viridis(begin = 0.4, end = 0.8, option = "A") +
    scale_x_continuous(breaks = seq(3, 15, 3), limits = c(3, 12), name = "y-Dimension") +
    scale_y_continuous(breaks = seq(3, 12, 3), limits = c(3, 12), name = "x-Dimension") +
    labs(caption = "Vergrößerte Ansicht",
             title = "Die meisten Diamanten weisen einen x-und y-Werte zwischen 3 und 12 auf",
             subtitle = "Besonders interessant ist der scheinbar lineare Zusammenhang",
             fill = "Anzahl") +
    geom_text(data = label, mapping = aes(label = label, vjust = vjust, hjust = hjust)) +
    annotate("text", x = 7.5, y = 7.5, label = "Mittelpunkt")

1.2.4 Erstellen Sie ein Streudiagramm von displ und hwy des mpg Datensatzes.

ggplot(mpg, aes(displ, hwy)) +
    geom_point()

1.2.4.1 Filtern Sie zusätzlich für jeden Autotyp class nach dem effizientesten Auto.

eff <- mpg %>%
    group_by(class) %>%
    slice_max(hwy)

1.2.4.2 Markieren Sie diese Autos farblich anders als den Rest.

ggplot(mpg, aes(displ, hwy)) +
    geom_point() +
    geom_point(data = eff, color = "red")

1.2.4.3 Fügen Sie mit geom_segment und arrow() Pfeile in die Grafik ein, die auf die Punkte zeigen.

ggplot(mpg, aes(displ, hwy)) +
    geom_point() +
    geom_point(data = eff, color = "red") +
    geom_segment(data = eff, mapping = aes(xend = displ + 0.3, yend = hwy + 1),
                             arrow = arrow(ends = "first", length = unit(0.1, "in"), type = "closed"))

1.2.4.4 Fügen Sie zusätzlich Label an das Ende der Pfeile ein, die das Automodell beschreiben.

# Zuerst muss definiert werden, wo die Label stehen sollen (z.B. am Ende der Pfeile)
label <- eff %>%
    mutate(hwy = hwy + 1.5,
                 displ = displ + 0.6)
ggplot(mpg, aes(displ, hwy)) +
    geom_point() +
    geom_point(data = eff, color = "red") +
    geom_segment(data = eff, mapping = aes(xend = displ + 0.3, yend = hwy + 1),
                             arrow = arrow(ends = "first", length = unit(0.1, "in"), type = "closed")) +
    geom_text(data = label, mapping = aes(label = model))

Hierbei überlappen sich die Label im oberen Bereich. Stattdessen kann auch geom_label_repel() aus ggrepel verwendet werden.

library(ggrepel)
ggplot(mpg, aes(displ, hwy)) +
    geom_point(aes(color = class)) +
    geom_point(data = eff, color = "black") +
    geom_label_repel(data = eff, aes(label = model),
    arrow = arrow(length = unit(0.02, "npc")),
    box.padding = 1, point.padding = 1
  )

1.2.4.5 Fügen Sie schlussendlich der Grafik aussagekräftige Beschriftungen, usw. bei.

In diesem Fall wurde die Legende noch unter die Grafik geschoben und die Transparenz angepast.

ggplot(mpg, aes(displ, hwy)) +
    geom_point(aes(color = class), alpha = 0.4) +
    geom_point(data = eff, color = "black", alpha = 0.4) +
    geom_label_repel(data = eff, aes(label = model),
    arrow = arrow(length = unit(0.02, "npc")),
    box.padding = 1, point.padding = 1
  ) +
    labs(x = "Hubraum (l)",
             y = "Kraftstoffverbrauch (Gallone pro Meile)",
             title = "Kraftstoffeffizienz fällt tendenziell mit steigendem Hubraum",
             subtitle = "Von jeder Autoklasse wurden die effizientesten Autos markiert") +
    guides(colour = guide_legend(nrow = 1, override.aes = list(size = 3, alpha = 1))) +
    theme(legend.position = "bottom")

1.2.5 Warum funktioniert der folgende Befehl nicht?

Bei dem Befehl wurde als Aesthetic color angegeben an Stelle von fill, sodass die Füllfarbe nicht verändert wurde. Wenn color durch fill in der Skalierung angepasst wird, funktioniert der Befehl wie erwartet:

1.2.6 Überschreiben Sie die Aesthetics in dem folgenden Befehl, um die Legende anschaulicher zu machen.

Durch das Setzen des alpha-Werts der Aesthetic sind die Punkte in der Legende ebenfalls transparent. Durch das Überschreiben der Legende durch guides() und dem Argument colour sowie override.aes lassen sich die Änderungen in der Grafik für die Legende anderweitig überschreiben (z. B. mit alpha = 1):

1.2.7 Zeichnen Sie ein Streudiagramm von Sepal.Width und Sepal.Length des iris Datensatzes.

1.2.7.1 Färben Sie die Punkte gemäß der Spezies ein.

1.2.7.2 Fügen Sie Linien für jede Spezies hinzu und ändern Sie die linetype.

1.2.7.3 Markieren Sie die kleinste und größte Pflanze (bezüglich Sepal) jeder Spezies mit Pfeilen und Label.

1.2.7.4 Beschriften Sie die Legende, Achsen und Titel sinnvoll.

LS0tCnRpdGxlOiAiw5xidW5nc3pldHRlbCA3IgpvdXRwdXQ6IAogIGh0bWxfbm90ZWJvb2s6IAogICAgaGlnaGxpZ2h0OiB0YW5nbwogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMKLS0tCgojIEF1ZmdhYmVuCgojIyDDnGJ1bmdzYXVmZ2FiZW4KCjEuICBFcnN0ZWxsZW4gU2llIGVpbmUgYmVsaWViaWdlIEdyYWZpayBkZXMgYGRpYW1vbmRzYCBEYXRlbnNhdHplcyB1bmQKICAgIGbDvGdlbiBTaWUgZGVyIEdyYWZpayBlaW5lbiDDnGJlcnNjaHJpZnQgKGB0aXRsZSlgLCBlaW5lbiBVbnRlcnRpdGVsCiAgICAoYHN1YnRpdGxlYCksIGVpbmUgIlVudGVyc2NocmlmdCIgKGBjYXB0aW9uYCkgdW5kIEJlc2NocmlmdHVuZ2VuIGRlcgogICAgeC11bmQgeS1BY2hzZSAoYHhgIHVuZCBgeWApIHNvd2llIGVpbiBGYXJibGFiZWwgYmVpLgoKMi4gIFZlcndlbmRlbiBTaWUgYGdlb21fdGV4dCgpYCwgdW0gVGV4dCBpbiBqZWRlIEVja2UgZGllc2VyIEdyYWZpayB6dQogICAgemVpY2huZW4uCgozLiAgU2NoYXVlbiBTaWUgaW4gZGllIEJlaXNwaWVsZSBkZXIgYD9hbm5vdGF0ZSgpYCBGdW5rdGlvbiB1bmQgZsO8Z2VuCiAgICBTaWUgbWl0IEhpbGZlIGRpZXNlciBUZXh0IGluIGVpbmUgR3JhZmlrIGVpbiBvaG5lIHZvcmhlciBlaW5lbgogICAgenVzw6R0emxpY2hlbiBgdGliYmxlYCB6dSBlcnN0ZWxsZW4uCgo0LiAgRXJzdGVsbGVuIFNpZSBlaW4gU3RyZXVkaWFncmFtbSB2b24gYGRpc3BsYCB1bmQgYGh3eWAgZGVzIGBtcGdgCiAgICBEYXRlbnNhdHplcy4KCiAgICAxLiAgRmlsdGVybiBTaWUgenVzw6R0emxpY2ggZsO8ciBqZWRlbiBBdXRvdHlwIGBjbGFzc2AgbmFjaCBkZW0KICAgICAgICBlZmZpemllbnRlc3RlbiBBdXRvLgoKICAgIDIuICBNYXJraWVyZW4gU2llIGRpZXNlIEF1dG9zIGZhcmJsaWNoIGFuZGVycyBhbHMgZGVuIFJlc3QuCgogICAgMy4gIEbDvGdlbiBTaWUgbWl0IGBnZW9tX3NlZ21lbnRgIHVuZCBgYXJyb3coKWAgUGZlaWxlIGluIGRpZSBHcmFmaWsKICAgICAgICBlaW4sIGRpZSBhdWYgZGllIFB1bmt0ZSB6ZWlnZW4uCgogICAgNC4gIEbDvGdlbiBTaWUgenVzw6R0emxpY2ggTGFiZWwgYW4gZGFzIEVuZGUgZGVyIFBmZWlsZSBlaW4sIGRpZSBkYXMKICAgICAgICBBdXRvbW9kZWxsIGJlc2NocmVpYmVuLgoKICAgIDUuICBGw7xnZW4gU2llIHNjaGx1c3NlbmRsaWNoIGRlciBHcmFmaWsgYXVzc2FnZWtyw6RmdGlnZQogICAgICAgIEJlc2NocmlmdHVuZ2VuLCB1c3cuIGJlaS4KCjUuICBXYXJ1bSBmdW5rdGlvbmllcnQgZGVyIGZvbGdlbmRlIEJlZmVobCBuaWNodD8KCmBgYHtyfQpkZiA8LSB0aWJibGUoCiAgeCA9IHJub3JtKDEwMDAwKSwKICB5ID0gcm5vcm0oMTAwMDApCikKZ2dwbG90KGRmLCBhZXMoeCwgeSkpICsKICBnZW9tX2hleCgpICsKICBzY2FsZV9jb2xvcl9ncmFkaWVudChsb3cgPSAid2hpdGUiLCBoaWdoID0gInJlZCIpICsKICBjb29yZF9maXhlZCgpCmBgYAoKNlwuIMOcYmVyc2NocmVpYmVuIFNpZSBkaWUgQWVzdGhldGljcyBpbiBkZW0gZm9sZ2VuZGVuIEJlZmVobCwgdW0gZGllCkxlZ2VuZGUgYW5zY2hhdWxpY2hlciB6dSBtYWNoZW4uCgpgYGB7cn0KZ2dwbG90KGRpYW1vbmRzLCBhZXMoY2FyYXQsIHByaWNlKSkgKwogIGdlb21fcG9pbnQoYWVzKGNvbG91ciA9IGN1dCksIGFscGhhID0gMS8yMCkKYGBgCgo3LiAgWmVpY2huZW4gU2llIGVpbiBTdHJldWRpYWdyYW1tIHZvbiBgU2VwYWwuV2lkdGhgIHVuZCBgU2VwYWwuTGVuZ3RoYAogICAgZGVzIGBpcmlzYCBEYXRlbnNhdHplcy4KICAgIDEuICBGw6RyYmVuIFNpZSBkaWUgUHVua3RlIGdlbcOkw58gZGVyIFNwZXppZXMgZWluLgoKICAgIDIuICBGw7xnZW4gU2llIExpbmllbiBmw7xyIGplZGUgU3BlemllcyBoaW56dSB1bmQgw6RuZGVybiBTaWUgZGllCiAgICAgICAgYGxpbmV0eXBlYC4KCiAgICAzLiAgTWFya2llcmVuIFNpZSBkaWUga2xlaW5zdGUgdW5kIGdyw7bDn3RlIFBmbGFuemUgamVkZXIgU3BlemllcyBtaXQKICAgICAgICBQZmVpbGVuIHVuZCBMYWJlbC4KCiAgICA0LiAgQmVzY2hyaWZ0ZW4gU2llIGRpZSBMZWdlbmRlLCBBY2hzZW4gdW5kIFRpdGVsIHNpbm52b2xsLgoKIyMgTMO2c3VuZ2VuCgojIyMgRXJzdGVsbGVuIFNpZSBlaW5lIGJlbGllYmlnZSBHcmFmaWsgZGVzIGBkaWFtb25kc2AgRGF0ZW5zYXR6ZXMgdW5kIGbDvGdlbiBTaWUgZGVyIEdyYWZpayBlaW5lbiDDnGJlcnNjaHJpZnQgKGB0aXRsZSlgLCBlaW5lbiBVbnRlcnRpdGVsIChgc3VidGl0bGVgKSwgZWluZSAiVW50ZXJzY2hyaWZ0IiAoYGNhcHRpb25gKSB1bmQgQmVzY2hyaWZ0dW5nZW4gZGVyIHgtdW5kIHktQWNoc2UgKGB4YCB1bmQgYHlgKSBzb3dpZSBlaW4gRmFyYmxhYmVsIGJlaS4KCkltIGZvbGdlbmRlbiBCZWlzcGllbCBzZWhlbiB3aXIgZGllIGB4YC11bmQgYHlgLVdlcnRlIGRlciBEaWFtYW50ZW4sCndvYmVpIEZhcmJncmFkaWVudGVuIHVuZCBBY2hzZW4gYW5nZXBhc3N0IHd1cmRlbjoKCmBgYHtyfQpsaWJyYXJ5KHZpcmlkaXMpCmdncGxvdChkaWFtb25kcywgYWVzKHgsIHkpKSArIAoJZ2VvbV9oZXgoKSArCglzY2FsZV9maWxsX3ZpcmlkaXMoYmVnaW4gPSAwLjQsIGVuZCA9IDAuOCwgb3B0aW9uID0gIkEiKSArCglzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDMsIDE1LCAzKSwgbGltaXRzID0gYygzLCAxMiksIG5hbWUgPSAieS1EaW1lbnNpb24iKSArCglzY2FsZV95X2NvbnRpbnVvdXMoYnJlYWtzID0gc2VxKDMsIDEyLCAzKSwgbGltaXRzID0gYygzLCAxMiksIG5hbWUgPSAieC1EaW1lbnNpb24iKSArCglsYWJzKGNhcHRpb24gPSAiVmVyZ3LDtsOfZXJ0ZSBBbnNpY2h0IiwKCQkJIHRpdGxlID0gIkRpZSBtZWlzdGVuIERpYW1hbnRlbiB3ZWlzZW4gZWluZW4geC11bmQgeS1XZXJ0ZSB6d2lzY2hlbiAzIHVuZCAxMiBhdWYiLAoJCQkgc3VidGl0bGUgPSAiQmVzb25kZXJzIGludGVyZXNzYW50IGlzdCBkZXIgc2NoZWluYmFyIGxpbmVhcmUgWnVzYW1tZW5oYW5nIiwKCQkJIGZpbGwgPSAiQW56YWhsIikKYGBgCgojIyMgVmVyd2VuZGVuIFNpZSBgZ2VvbV90ZXh0KClgLCB1bSBUZXh0IGluIGplZGUgRWNrZSBkaWVzZXIgR3JhZmlrIHp1IHplaWNobmVuLgoKYGBge3J9CmxhYmVsIDwtIHRpYmJsZSgKCXggPSBjKEluZiwgSW5mLCAtSW5mLCAtSW5mKSwKCXkgPSBjKEluZiwgLUluZiwgSW5mLCAtSW5mKSwKCWxhYmVsID0gYygiUk8iLCAiUlUiLCAiTE8iLCAiTFUiKSwKCXZqdXN0ID0gYygidG9wIiwgImJvdHRvbSIsICJ0b3AiLCAiYm90dG9tIiksCgloanVzdCA9IGMoInJpZ2h0IiwgInJpZ2h0IiwgImxlZnQiLCAibGVmdCIpCikKZ2dwbG90KGRpYW1vbmRzLCBhZXMoeCwgeSkpICsgCglnZW9tX2hleCgpICsKCXNjYWxlX2ZpbGxfdmlyaWRpcyhiZWdpbiA9IDAuNCwgZW5kID0gMC44LCBvcHRpb24gPSAiQSIpICsKCXNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBzZXEoMywgMTUsIDMpLCBsaW1pdHMgPSBjKDMsIDEyKSwgbmFtZSA9ICJ5LURpbWVuc2lvbiIpICsKCXNjYWxlX3lfY29udGludW91cyhicmVha3MgPSBzZXEoMywgMTIsIDMpLCBsaW1pdHMgPSBjKDMsIDEyKSwgbmFtZSA9ICJ4LURpbWVuc2lvbiIpICsKCWxhYnMoY2FwdGlvbiA9ICJWZXJncsO2w59lcnRlIEFuc2ljaHQiLAoJCQkgdGl0bGUgPSAiRGllIG1laXN0ZW4gRGlhbWFudGVuIHdlaXNlbiBlaW5lbiB4LXVuZCB5LVdlcnRlIHp3aXNjaGVuIDMgdW5kIDEyIGF1ZiIsCgkJCSBzdWJ0aXRsZSA9ICJCZXNvbmRlcnMgaW50ZXJlc3NhbnQgaXN0IGRlciBzY2hlaW5iYXIgbGluZWFyZSBadXNhbW1lbmhhbmciLAoJCQkgZmlsbCA9ICJBbnphaGwiKSArCglnZW9tX3RleHQoZGF0YSA9IGxhYmVsLCBtYXBwaW5nID0gYWVzKGxhYmVsID0gbGFiZWwsIHZqdXN0ID0gdmp1c3QsIGhqdXN0ID0gaGp1c3QpKQpgYGAKCiMjIyBTY2hhdWVuIFNpZSBpbiBkaWUgQmVpc3BpZWxlIGRlciBgP2Fubm90YXRlKClgIEZ1bmt0aW9uIHVuZCBmw7xnZW4gU2llIG1pdCBIaWxmZSBkaWVzZXIgVGV4dCBpbiBlaW5lIEdyYWZpayBlaW4gb2huZSB2b3JoZXIgZWluZW4genVzw6R0emxpY2hlbiBgdGliYmxlYCB6dSBlcnN0ZWxsZW4uCgpgYGB7cn0KbGFiZWwgPC0gdGliYmxlKAoJeCA9IGMoSW5mLCBJbmYsIC1JbmYsIC1JbmYpLAoJeSA9IGMoSW5mLCAtSW5mLCBJbmYsIC1JbmYpLAoJbGFiZWwgPSBjKCJSTyIsICJSVSIsICJMTyIsICJMVSIpLAoJdmp1c3QgPSBjKCJ0b3AiLCAiYm90dG9tIiwgInRvcCIsICJib3R0b20iKSwKCWhqdXN0ID0gYygicmlnaHQiLCAicmlnaHQiLCAibGVmdCIsICJsZWZ0IikKKQpnZ3Bsb3QoZGlhbW9uZHMsIGFlcyh4LCB5KSkgKyAKCWdlb21faGV4KCkgKwoJc2NhbGVfZmlsbF92aXJpZGlzKGJlZ2luID0gMC40LCBlbmQgPSAwLjgsIG9wdGlvbiA9ICJBIikgKwoJc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgzLCAxNSwgMyksIGxpbWl0cyA9IGMoMywgMTIpLCBuYW1lID0gInktRGltZW5zaW9uIikgKwoJc2NhbGVfeV9jb250aW51b3VzKGJyZWFrcyA9IHNlcSgzLCAxMiwgMyksIGxpbWl0cyA9IGMoMywgMTIpLCBuYW1lID0gIngtRGltZW5zaW9uIikgKwoJbGFicyhjYXB0aW9uID0gIlZlcmdyw7bDn2VydGUgQW5zaWNodCIsCgkJCSB0aXRsZSA9ICJEaWUgbWVpc3RlbiBEaWFtYW50ZW4gd2Vpc2VuIGVpbmVuIHgtdW5kIHktV2VydGUgendpc2NoZW4gMyB1bmQgMTIgYXVmIiwKCQkJIHN1YnRpdGxlID0gIkJlc29uZGVycyBpbnRlcmVzc2FudCBpc3QgZGVyIHNjaGVpbmJhciBsaW5lYXJlIFp1c2FtbWVuaGFuZyIsCgkJCSBmaWxsID0gIkFuemFobCIpICsKCWdlb21fdGV4dChkYXRhID0gbGFiZWwsIG1hcHBpbmcgPSBhZXMobGFiZWwgPSBsYWJlbCwgdmp1c3QgPSB2anVzdCwgaGp1c3QgPSBoanVzdCkpICsKCWFubm90YXRlKCJ0ZXh0IiwgeCA9IDcuNSwgeSA9IDcuNSwgbGFiZWwgPSAiTWl0dGVscHVua3QiKQpgYGAKCiMjIyBFcnN0ZWxsZW4gU2llIGVpbiBTdHJldWRpYWdyYW1tIHZvbiBgZGlzcGxgIHVuZCBgaHd5YCBkZXMgYG1wZ2AgRGF0ZW5zYXR6ZXMuCgpgYGB7cn0KZ2dwbG90KG1wZywgYWVzKGRpc3BsLCBod3kpKSArCglnZW9tX3BvaW50KCkKYGBgCgojIyMjIEZpbHRlcm4gU2llIHp1c8OkdHpsaWNoIGbDvHIgamVkZW4gQXV0b3R5cCBgY2xhc3NgIG5hY2ggZGVtIGVmZml6aWVudGVzdGVuIEF1dG8uCgpgYGB7cn0KZWZmIDwtIG1wZyAlPiUKICAgIGdyb3VwX2J5KGNsYXNzKSAlPiUKICAgIHNsaWNlX21heChod3kpCmBgYAoKIyMjIyBNYXJraWVyZW4gU2llIGRpZXNlIEF1dG9zIGZhcmJsaWNoIGFuZGVycyBhbHMgZGVuIFJlc3QuCgpgYGB7cn0KZ2dwbG90KG1wZywgYWVzKGRpc3BsLCBod3kpKSArCglnZW9tX3BvaW50KCkgKwoJZ2VvbV9wb2ludChkYXRhID0gZWZmLCBjb2xvciA9ICJyZWQiKQpgYGAKCiMjIyMgRsO8Z2VuIFNpZSBtaXQgYGdlb21fc2VnbWVudGAgdW5kIGBhcnJvdygpYCBQZmVpbGUgaW4gZGllIEdyYWZpayBlaW4sIGRpZSBhdWYgZGllIFB1bmt0ZSB6ZWlnZW4uCgpgYGB7cn0KZ2dwbG90KG1wZywgYWVzKGRpc3BsLCBod3kpKSArCglnZW9tX3BvaW50KCkgKwoJZ2VvbV9wb2ludChkYXRhID0gZWZmLCBjb2xvciA9ICJyZWQiKSArCglnZW9tX3NlZ21lbnQoZGF0YSA9IGVmZiwgbWFwcGluZyA9IGFlcyh4ZW5kID0gZGlzcGwgKyAwLjMsIHllbmQgPSBod3kgKyAxKSwKCQkJCQkJCSBhcnJvdyA9IGFycm93KGVuZHMgPSAiZmlyc3QiLCBsZW5ndGggPSB1bml0KDAuMSwgImluIiksIHR5cGUgPSAiY2xvc2VkIikpCmBgYAoKIyMjIyBGw7xnZW4gU2llIHp1c8OkdHpsaWNoIExhYmVsIGFuIGRhcyBFbmRlIGRlciBQZmVpbGUgZWluLCBkaWUgZGFzIEF1dG9tb2RlbGwgYmVzY2hyZWliZW4uCgpgYGB7cn0KIyBadWVyc3QgbXVzcyBkZWZpbmllcnQgd2VyZGVuLCB3byBkaWUgTGFiZWwgc3RlaGVuIHNvbGxlbiAoei5CLiBhbSBFbmRlIGRlciBQZmVpbGUpCmxhYmVsIDwtIGVmZiAlPiUKCW11dGF0ZShod3kgPSBod3kgKyAxLjUsCgkJCQkgZGlzcGwgPSBkaXNwbCArIDAuNikKZ2dwbG90KG1wZywgYWVzKGRpc3BsLCBod3kpKSArCglnZW9tX3BvaW50KCkgKwoJZ2VvbV9wb2ludChkYXRhID0gZWZmLCBjb2xvciA9ICJyZWQiKSArCglnZW9tX3NlZ21lbnQoZGF0YSA9IGVmZiwgbWFwcGluZyA9IGFlcyh4ZW5kID0gZGlzcGwgKyAwLjMsIHllbmQgPSBod3kgKyAxKSwKCQkJCQkJCSBhcnJvdyA9IGFycm93KGVuZHMgPSAiZmlyc3QiLCBsZW5ndGggPSB1bml0KDAuMSwgImluIiksIHR5cGUgPSAiY2xvc2VkIikpICsKCWdlb21fdGV4dChkYXRhID0gbGFiZWwsIG1hcHBpbmcgPSBhZXMobGFiZWwgPSBtb2RlbCkpCmBgYAoKSGllcmJlaSDDvGJlcmxhcHBlbiBzaWNoIGRpZSBMYWJlbCBpbSBvYmVyZW4gQmVyZWljaC4gU3RhdHRkZXNzZW4ga2FubgphdWNoIGBnZW9tX2xhYmVsX3JlcGVsKClgIGF1cyBgZ2dyZXBlbGAgdmVyd2VuZGV0IHdlcmRlbi4KCmBgYHtyfQpsaWJyYXJ5KGdncmVwZWwpCmdncGxvdChtcGcsIGFlcyhkaXNwbCwgaHd5KSkgKwoJZ2VvbV9wb2ludChhZXMoY29sb3IgPSBjbGFzcykpICsKCWdlb21fcG9pbnQoZGF0YSA9IGVmZiwgY29sb3IgPSAiYmxhY2siKSArCglnZW9tX2xhYmVsX3JlcGVsKGRhdGEgPSBlZmYsIGFlcyhsYWJlbCA9IG1vZGVsKSwKICAgIGFycm93ID0gYXJyb3cobGVuZ3RoID0gdW5pdCgwLjAyLCAibnBjIikpLAogICAgYm94LnBhZGRpbmcgPSAxLCBwb2ludC5wYWRkaW5nID0gMQogICkKYGBgCgojIyMjIEbDvGdlbiBTaWUgc2NobHVzc2VuZGxpY2ggZGVyIEdyYWZpayBhdXNzYWdla3LDpGZ0aWdlIEJlc2NocmlmdHVuZ2VuLCB1c3cuIGJlaS4KCkluIGRpZXNlbSBGYWxsIHd1cmRlIGRpZSBMZWdlbmRlIG5vY2ggdW50ZXIgZGllIEdyYWZpayBnZXNjaG9iZW4gdW5kIGRpZQpUcmFuc3BhcmVueiBhbmdlcGFzdC4KCmBgYHtyfQpnZ3Bsb3QobXBnLCBhZXMoZGlzcGwsIGh3eSkpICsKCWdlb21fcG9pbnQoYWVzKGNvbG9yID0gY2xhc3MpLCBhbHBoYSA9IDAuNCkgKwoJZ2VvbV9wb2ludChkYXRhID0gZWZmLCBjb2xvciA9ICJibGFjayIsIGFscGhhID0gMC40KSArCglnZW9tX2xhYmVsX3JlcGVsKGRhdGEgPSBlZmYsIGFlcyhsYWJlbCA9IG1vZGVsKSwKICAgIGFycm93ID0gYXJyb3cobGVuZ3RoID0gdW5pdCgwLjAyLCAibnBjIikpLAogICAgYm94LnBhZGRpbmcgPSAxLCBwb2ludC5wYWRkaW5nID0gMQogICkgKwoJbGFicyh4ID0gIkh1YnJhdW0gKGwpIiwKCQkJIHkgPSAiS3JhZnRzdG9mZnZlcmJyYXVjaCAoR2FsbG9uZSBwcm8gTWVpbGUpIiwKCQkJIHRpdGxlID0gIktyYWZ0c3RvZmZlZmZpemllbnogZsOkbGx0IHRlbmRlbnppZWxsIG1pdCBzdGVpZ2VuZGVtIEh1YnJhdW0iLAoJCQkgc3VidGl0bGUgPSAiVm9uIGplZGVyIEF1dG9rbGFzc2Ugd3VyZGVuIGRpZSBlZmZpemllbnRlc3RlbiBBdXRvcyBtYXJraWVydCIpICsKCWd1aWRlcyhjb2xvdXIgPSBndWlkZV9sZWdlbmQobnJvdyA9IDEsIG92ZXJyaWRlLmFlcyA9IGxpc3Qoc2l6ZSA9IDMsIGFscGhhID0gMSkpKSArCgl0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikKYGBgCgojIyMgV2FydW0gZnVua3Rpb25pZXJ0IGRlciBmb2xnZW5kZSBCZWZlaGwgbmljaHQ/CgpCZWkgZGVtIEJlZmVobCB3dXJkZSBhbHMgQWVzdGhldGljIGBjb2xvcmAgYW5nZWdlYmVuIGFuIFN0ZWxsZSB2b24KYGZpbGxgLCBzb2Rhc3MgZGllIEbDvGxsZmFyYmUgbmljaHQgdmVyw6RuZGVydCB3dXJkZS4gV2VubiBgY29sb3JgIGR1cmNoCmBmaWxsYCBpbiBkZXIgU2thbGllcnVuZyBhbmdlcGFzc3Qgd2lyZCwgZnVua3Rpb25pZXJ0IGRlciBCZWZlaGwgd2llCmVyd2FydGV0OgoKYGBge3J9CmRmIDwtIHRpYmJsZSgKICB4ID0gcm5vcm0oMTAwMDApLAogIHkgPSBybm9ybSgxMDAwMCkKKQpnZ3Bsb3QoZGYsIGFlcyh4LCB5KSkgKwogIGdlb21faGV4KCkgKwogIHNjYWxlX2ZpbGxfZ3JhZGllbnQobG93ID0gIndoaXRlIiwgaGlnaCA9ICJyZWQiKSArCiAgY29vcmRfZml4ZWQoKQpgYGAKCiMjIyDDnGJlcnNjaHJlaWJlbiBTaWUgZGllIEFlc3RoZXRpY3MgaW4gZGVtIGZvbGdlbmRlbiBCZWZlaGwsIHVtIGRpZSBMZWdlbmRlIGFuc2NoYXVsaWNoZXIgenUgbWFjaGVuLgoKRHVyY2ggZGFzIFNldHplbiBkZXMgYGFscGhhYC1XZXJ0cyBkZXIgQWVzdGhldGljIHNpbmQgZGllIFB1bmt0ZSBpbiBkZXIKTGVnZW5kZSBlYmVuZmFsbHMgdHJhbnNwYXJlbnQuIER1cmNoIGRhcyDDnGJlcnNjaHJlaWJlbiBkZXIgTGVnZW5kZSBkdXJjaApgZ3VpZGVzKClgIHVuZCBkZW0gQXJndW1lbnQgYGNvbG91cmAgc293aWUgYG92ZXJyaWRlLmFlc2AgbGFzc2VuIHNpY2gKZGllIMOEbmRlcnVuZ2VuIGluIGRlciBHcmFmaWsgZsO8ciBkaWUgTGVnZW5kZSBhbmRlcndlaXRpZyDDvGJlcnNjaHJlaWJlbgooei4gQi4gbWl0IGBhbHBoYSA9IDFgKToKCmBgYHtyfQpnZ3Bsb3QoZGlhbW9uZHMsIGFlcyhjYXJhdCwgcHJpY2UpKSArCiAgZ2VvbV9wb2ludChhZXMoY29sb3VyID0gY3V0KSwgYWxwaGEgPSAxLzIwKSArCglndWlkZXMoY29sb3VyID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3QoYWxwaGEgPSAxKSkpCmBgYAoKIyMjIFplaWNobmVuIFNpZSBlaW4gU3RyZXVkaWFncmFtbSB2b24gYFNlcGFsLldpZHRoYCB1bmQgYFNlcGFsLkxlbmd0aGAgZGVzIGBpcmlzYCBEYXRlbnNhdHplcy4KCmBgYHtyfQpnZ3Bsb3QoaXJpcywgYWVzKFNlcGFsLldpZHRoLCBTZXBhbC5MZW5ndGgpKSArCglnZW9tX3BvaW50KCkKYGBgCgojIyMjIEbDpHJiZW4gU2llIGRpZSBQdW5rdGUgZ2Vtw6TDnyBkZXIgU3BlemllcyBlaW4uCgpgYGB7cn0KZ2dwbG90KGlyaXMsIGFlcyhTZXBhbC5XaWR0aCwgU2VwYWwuTGVuZ3RoLCBjb2xvciA9IFNwZWNpZXMpKSArCglnZW9tX3BvaW50KCkKYGBgCgojIyMjIEbDvGdlbiBTaWUgTGluaWVuIGbDvHIgamVkZSBTcGV6aWVzIGhpbnp1IHVuZCDDpG5kZXJuIFNpZSBkaWUgYGxpbmV0eXBlYC4KCmBgYHtyfQpnZ3Bsb3QoaXJpcywgYWVzKFNlcGFsLldpZHRoLCBTZXBhbC5MZW5ndGgsIGNvbG9yID0gU3BlY2llcykpICsKCWdlb21fcG9pbnQoKSArCglnZW9tX3Ntb290aChhZXMobGluZXR5cGUgPSBTcGVjaWVzKSwgc2UgPSBGQUxTRSkKYGBgCgojIyMjIE1hcmtpZXJlbiBTaWUgZGllIGtsZWluc3RlIHVuZCBncsO2w590ZSBQZmxhbnplIChiZXrDvGdsaWNoIFNlcGFsKSBqZWRlciBTcGV6aWVzIG1pdCBQZmVpbGVuIHVuZCBMYWJlbC4KCmBgYHtyfQojIEVudHdlZGVyIG5hY2ggU2VwYWwuV2lkdGggb2RlciBTZXBhbC5MZW5ndGggZmlsdGVybgojIEFsdGVybmF0aXYga2FubiBhdWNoIHZlcnN1Y2h0IHdlcmRlbiwgZGllIGdyw7bDn3RlL2tsZWluc3RlIFN1bW1lIHp1IHN1Y2hlbgptYXggPC0gaXJpcyAlPiUKCWdyb3VwX2J5KFNwZWNpZXMpICU+JQoJc2xpY2VfbWF4KFNlcGFsLldpZHRoICsgU2VwYWwuTGVuZ3RoKQptaW4gPC0gaXJpcyAlPiUKCWdyb3VwX2J5KFNwZWNpZXMpICU+JQoJc2xpY2VfbWluKFNlcGFsLldpZHRoICsgU2VwYWwuTGVuZ3RoKQpnZ3Bsb3QoaXJpcywgYWVzKFNlcGFsLldpZHRoLCBTZXBhbC5MZW5ndGgsIGNvbG9yID0gU3BlY2llcykpICsKCWdlb21fcG9pbnQoKSArCglnZW9tX3Ntb290aChhZXMobGluZXR5cGUgPSBTcGVjaWVzKSwgc2UgPSBGQUxTRSkgKwoJZ2VvbV9sYWJlbF9yZXBlbChkYXRhID0gbWF4LCBtYXBwaW5nID0gYWVzKGxhYmVsID0gIk1heCIpLAoJCQkJCQkJCQkgYXJyb3cgPSBhcnJvdyh0eXBlID0gImNsb3NlZCIsIGxlbmd0aCA9IHVuaXQoMC4yLCAiY20iKSksCgkJCQkJCQkJCSBib3gucGFkZGluZyA9IDEsIHBvaW50LnBhZGRpbmcgPSAxKSArCglnZW9tX2xhYmVsX3JlcGVsKGRhdGEgPSBtaW4sIG1hcHBpbmcgPSBhZXMobGFiZWwgPSAiTWluIiksCgkJCQkJCQkJCSBhcnJvdyA9IGFycm93KHR5cGUgPSAiY2xvc2VkIiwgbGVuZ3RoID0gdW5pdCgwLjIsICJjbSIpKSwKCQkJCQkJCQkJIGJveC5wYWRkaW5nID0gMSwgcG9pbnQucGFkZGluZyA9IDEpCmBgYAoKIyMjIyBCZXNjaHJpZnRlbiBTaWUgZGllIExlZ2VuZGUsIEFjaHNlbiB1bmQgVGl0ZWwgc2lubnZvbGwuCgpgYGB7cn0KZ2dwbG90KGlyaXMsIGFlcyhTZXBhbC5XaWR0aCwgU2VwYWwuTGVuZ3RoLCBjb2xvciA9IFNwZWNpZXMpKSArCglnZW9tX3BvaW50KCkgKwoJZ2VvbV9zbW9vdGgoYWVzKGxpbmV0eXBlID0gU3BlY2llcyksIHNlID0gRkFMU0UpICsKCWdlb21fbGFiZWxfcmVwZWwoZGF0YSA9IG1heCwgbWFwcGluZyA9IGFlcyhsYWJlbCA9ICJNYXhpbXVtIiksCgkJCQkJCQkJCSBhcnJvdyA9IGFycm93KHR5cGUgPSAiY2xvc2VkIiwgbGVuZ3RoID0gdW5pdCgwLjIsICJjbSIpKSwKCQkJCQkJCQkJIGJveC5wYWRkaW5nID0gMSwgcG9pbnQucGFkZGluZyA9IDEpICsKCWdlb21fbGFiZWxfcmVwZWwoZGF0YSA9IG1pbiwgbWFwcGluZyA9IGFlcyhsYWJlbCA9ICJNaW5pbXVtIiksCgkJCQkJCQkJCSBhcnJvdyA9IGFycm93KHR5cGUgPSAiY2xvc2VkIiwgbGVuZ3RoID0gdW5pdCgwLjIsICJjbSIpKSwKCQkJCQkJCQkJIGJveC5wYWRkaW5nID0gMSwgcG9pbnQucGFkZGluZyA9IDEpICsKCXRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKSArCglsYWJzKHggPSAiS2VsY2hibGF0dGJyZWl0ZSIsIHkgPSAiS2VsY2hibGF0dGzDpG5nZSIsIAoJCQkgdGl0bGUgPSAiRGllIHVudGVyc2NoaWVkbGljaGVuIElyaXNhcnRlbiB3ZWlzZW4gYWJ3ZWljaGVuZGUgKGxpbmVhcmUpIEdyw7bDn2VudmVyaMOkbHRuaXNzZSBhdWYiLAoJCQkgc3VidGl0bGUgPSAiU2V0b3NhIHNjaGVpbnQga2xlaW5lciBhbHMgZGllIGFuZGVyZW4gSXJpc2FydGVuIHp1IHNlaW4iLCAKCQkJIGNvbG91ciA9ICJTcGV6aWVzIiwgbGluZXR5cGUgPSAiU3BlemllcyIpCmBgYAo=