1 Zadanie 1

2 Wczytanie danych

library(car)
## Ładowanie wymaganego pakietu: carData
library(KernSmooth)
## KernSmooth 2.23 załadowane
## Prawa autorskie M. P. Wand 1997-2009
library(tidyverse)
## Warning: pakiet 'ggplot2' został zbudowany w wersji R 4.3.3
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.4
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ ggplot2   3.5.1     ✔ tibble    3.2.1
## ✔ lubridate 1.9.3     ✔ tidyr     1.3.0
## ✔ purrr     1.0.2
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ✖ dplyr::recode() masks car::recode()
## ✖ purrr::some()   masks car::some()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
data("Prestige")

3 Usuwamy brakujące dane

Prestige <- na.omit(Prestige)

4 Wykres relacji między dochodem a prestiżem

ggplot(Prestige)+
  geom_point(aes(x=income, y=prestige))

Związek raczej nieliniowy. Do pewnego poziomu można się doszukiwac liniowości, ta granica jest przy zarobkach około 10k USD.

5 1. Kernel smoothing

library(KernSmooth)

5.1 Porównanie pasm (brandwith)

5.2 1.1 Brandwith=1

ker1 <- locpoly(Prestige$prestige, Prestige$income,
                degree = 0, bandwidth = 1) %>% 
  as_tibble()

ggplot(Prestige) +
  geom_point(aes(x = prestige, y = income)) +
  geom_line(data = ker1, aes(x = x, y = y), col = 'red') +
  ggtitle("Kernel smoothing - szerokość pasma równa 1")

5.3 1.2 Brandwith=4

ker4 <- locpoly(Prestige$prestige, Prestige$income,
                degree = 0, bandwidth = 4) %>% 
  as_tibble()

ggplot(Prestige) +
  geom_point(aes(x = prestige, y = income)) +
  geom_line(data = ker4, aes(x = x, y = y), col = 'green') +
  ggtitle("Kernel smoothing - szerokość pasma równa 4")

6 2. Model Loess kwadratowy

loess_model <- loess(income ~ prestige, data = Prestige, span = 0.75, degree = 2)
ggplot(Prestige, aes(x = prestige, y = income)) +
  geom_point(color = "blue", size = 2) +  
  geom_smooth(method = "loess", span = 0.75, color = "red", fill = "darkgreen", alpha = 0.2) +
  ggtitle("LOESS (degree = 2) z przedzałem ufności") +
  xlab("Prestiż") +
  ylab("Dochód") +
  theme_minimal()
## `geom_smooth()` using formula = 'y ~ x'

Bardzo dużo obserwacji odstaję od przedziału ufności. Szczególnie powyżej 10k USD.

7 3. Sploty interpolujące

spline_model <- smooth.spline(Prestige$income, Prestige$prestige, cv=TRUE)
## Warning in smooth.spline(Prestige$income, Prestige$prestige, cv = TRUE):
## krzyżowa walidacja z nieunikalnymi wartościami 'x' wydaje się wątpliwa
spline_data <- data.frame(x = spline_model$x, y = spline_model$y)


ggplot(Prestige, aes(x = income, y = prestige)) +
  geom_point(color = "blue", size = 2) +  
  geom_line(data = spline_data, aes(x = x, y = y), color = "red", size = 1.2) + 
  ggtitle("Sploty interpolujące (lambda wybrana przez CV)") +
  xlab("Dochód") +
  ylab("Prestiż") +
  theme_minimal()
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

8 4. Sploty naturalne

library(splines)
nat1 <- lm(income ~ ns(prestige, df = 6), data = Prestige)
nat2 <- lm(income ~ ns(prestige, df = 12), data = Prestige)

ggplot(Prestige) +
  geom_point(aes(x = prestige, y = income)) +
  ggtitle("Naturalne sploty, 6 df (niebieski) i 12 df (czerwony)") +
  geom_line(aes(x = prestige, y = fitted(nat1)), col = 'darkblue', size = 0.7) + 
  geom_line(aes(x = prestige, y = fitted(nat2)), col = 'pink', size = 0.7) +
  xlab("Prestiż") +
  ylab("Dochód") +
  theme_minimal()

ggplot(Prestige) +
    geom_point(aes(x=prestige,y=income)) +
    geom_smooth(aes(x=prestige,y=income), method='gam',
      formula = y ~ s(x,k=12))

9 Zadanie 2

10 1. Kernel smoothing

library(MASS)
## 
## Dołączanie pakietu: 'MASS'
## Następujący obiekt został zakryty z 'package:dplyr':
## 
##     select
data(mycycle)
## Warning in data(mycycle): zbiór danych 'mycycle' nie został znaleziony
ggplot(mcycle)+
  geom_point(aes(x=times,y=accel))

10.1 Porównanie pasm (brandwith)

10.2 1.1 Brandwith=1

ker1 <- locpoly(mcycle$times, mcycle$accel,
                degree = 0, bandwidth = 1) %>% as.tibble
## Warning: `as.tibble()` was deprecated in tibble 2.0.0.
## ℹ Please use `as_tibble()` instead.
## ℹ The signature and semantics have changed, see `?as_tibble`.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
ggplot(mcycle) +
  geom_point(aes(x=times, y=accel)) +
  geom_line(data = ker1, aes(x = x, y = y), col = 'red') +
  ggtitle("Kernel smoothing - szerokość pasma równa 1")

10.3 1.2 Brandwith=4

ker4 <- locpoly(mcycle$times, mcycle$accel,
                degree = 0, bandwidth = 4) %>% as.tibble

ggplot(mcycle) +
  geom_point(aes(x = times, y = accel)) +
  geom_line(data = ker4, aes(x = x, y = y), col = 'green') +
  ggtitle("Kernel smoothing - szerokość pasma równa 4")

Szerokość pasma równa 1 lepiej odwzorowuje, szczególnie to widać przy łapaniu górek i dołków.

11 2. Model Loess kwadratowy

loess_model2 <- loess(accel ~ times, data = mcycle, span = 0.25, degree = 2)
ggplot(mcycle, aes(x = times, y = accel)) +
  geom_point(color = "blue", size = 2) +  
  geom_smooth(method = "loess", span = 0.75, color = "red", fill = "darkgreen", alpha = 0.2) +
  ggtitle("LOESS (degree = 2) z przedziałem ufności") +
  xlab("Czas (ms)") +
  ylab("Przyspieszenie (g)") +
  theme_minimal()
## `geom_smooth()` using formula = 'y ~ x'

ggplot(mcycle, aes(x = times, y = accel)) +
  geom_point(color = "blue", size = 2) +  
  geom_smooth(method = "loess", span = 0.25, color = "red", fill = "darkgreen", alpha = 0.2) +
  ggtitle("LOESS (degree = 2) z przedziałem ufności") +
  xlab("Czas (ms)") +
  ylab("Przyspieszenie (g)") +
  theme_minimal()
## `geom_smooth()` using formula = 'y ~ x'

Span=0,75 bardzo słabo odwzorowywał zmienne, więc słusznym była zmiana na span=0,25.

12 3. Sploty interpolujące

spline <- smooth.spline(mcycle$times, mcycle$accel, cv=TRUE)
## Warning in smooth.spline(mcycle$times, mcycle$accel, cv = TRUE): krzyżowa
## walidacja z nieunikalnymi wartościami 'x' wydaje się wątpliwa
spline_data2 <- data.frame(x = spline$x, y = spline$y)


ggplot(mcycle, aes(x = times, y = accel)) +
  geom_point(color = "blue", size = 2) +  
  geom_line(data = spline_data2, aes(x = x, y = y), color = "red", size = 1.2) + 
  ggtitle("Sploty interpolujące (lambda wybrana przez CV)") +
  xlab("Czas (ms)") +
  ylab("Przyspieszenie (g)") +
  theme_minimal()

13 4. Sploty naturalne

library(splines)
nat3 <- lm(accel ~ ns(times, df = 6), data = mcycle)
nat4 <- lm(accel ~ ns(times, df = 12), data = mcycle)


ggplot(mcycle) +
  geom_point(aes(x = times, y = accel)) +
  ggtitle("Naturalne sploty, 6 df (niebieski) i 12 df (czerwony)") +
  geom_line(aes(x = times, y = fitted(nat3)), col = 'darkblue', size = 0.7) + 
  geom_line(aes(x = times, y = fitted(nat4)), col = 'pink', size = 0.7) +
  xlab("Czas (ms)") +
  ylab("Przyspieszenie (g)") +
  theme_minimal()

LS0tDQp0aXRsZTogIlJhcG9ydCAzIg0KYXV0aG9yOiAiQ2V6YXJ5IFNhd2N6dWsiDQpkYXRlOiAiYHIgU3lzLkRhdGUoKWAiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6DQogICAgdGhlbWU6IGNlcnVsZWFuDQogICAgaGlnaGxpZ2h0OiB0ZXh0bWF0ZQ0KICAgIGZvbnRzaXplOiA4cHQNCiAgICB0b2M6IHllcw0KICAgIG51bWJlcl9zZWN0aW9uczogeWVzDQogICAgY29kZV9kb3dubG9hZDogeWVzDQogICAgdG9jX2Zsb2F0Og0KICAgICAgY29sbGFwc2VkOiBubw0KICBwZGZfZG9jdW1lbnQ6DQogICAgdG9jOiB5ZXMNCnN1YnRpdGxlOiBSYXBvcnQzDQplZGl0b3Jfb3B0aW9uczoNCiAgbWFya2Rvd246DQogICAgd3JhcDogNzINCi0tLQ0KDQpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0NCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSkNCmBgYA0KDQojIFphZGFuaWUgMQ0KDQojIFdjenl0YW5pZSBkYW55Y2gNCmBgYHtyfQ0KbGlicmFyeShjYXIpDQpsaWJyYXJ5KEtlcm5TbW9vdGgpDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmRhdGEoIlByZXN0aWdlIikNCmBgYA0KDQojIFVzdXdhbXkgYnJha3VqxIVjZSBkYW5lDQpgYGB7cn0NClByZXN0aWdlIDwtIG5hLm9taXQoUHJlc3RpZ2UpDQpgYGANCg0KIyBXeWtyZXMgcmVsYWNqaSBtacSZZHp5IGRvY2hvZGVtIGEgcHJlc3RpxbxlbQ0KYGBge3IgY2Fyc30NCmdncGxvdChQcmVzdGlnZSkrDQogIGdlb21fcG9pbnQoYWVzKHg9aW5jb21lLCB5PXByZXN0aWdlKSkNCmBgYA0KWndpxIV6ZWsgcmFjemVqIG5pZWxpbmlvd3kuIERvIHBld25lZ28gcG96aW9tdSBtb8W8bmEgc2nEmSBkb3N6dWtpd2FjIGxpbmlvd2/Fm2NpLCB0YSBncmFuaWNhIGplc3QgcHJ6eSB6YXJvYmthY2ggb2tvxYJvIDEwayBVU0QuDQoNCiMgMS4gS2VybmVsIHNtb290aGluZyANCg0KYGBge3J9DQpsaWJyYXJ5KEtlcm5TbW9vdGgpDQpgYGANCg0KIyMgUG9yw7N3bmFuaWUgcGFzbSAoYnJhbmR3aXRoKQ0KDQojIyAxLjEgQnJhbmR3aXRoPTENCmBgYHtyfQ0Ka2VyMSA8LSBsb2Nwb2x5KFByZXN0aWdlJHByZXN0aWdlLCBQcmVzdGlnZSRpbmNvbWUsDQogICAgICAgICAgICAgICAgZGVncmVlID0gMCwgYmFuZHdpZHRoID0gMSkgJT4lIA0KICBhc190aWJibGUoKQ0KDQpnZ3Bsb3QoUHJlc3RpZ2UpICsNCiAgZ2VvbV9wb2ludChhZXMoeCA9IHByZXN0aWdlLCB5ID0gaW5jb21lKSkgKw0KICBnZW9tX2xpbmUoZGF0YSA9IGtlcjEsIGFlcyh4ID0geCwgeSA9IHkpLCBjb2wgPSAncmVkJykgKw0KICBnZ3RpdGxlKCJLZXJuZWwgc21vb3RoaW5nIC0gc3plcm9rb8WbxIcgcGFzbWEgcsOzd25hIDEiKQ0KYGBgDQoNCiMjIDEuMiBCcmFuZHdpdGg9NA0KYGBge3J9DQprZXI0IDwtIGxvY3BvbHkoUHJlc3RpZ2UkcHJlc3RpZ2UsIFByZXN0aWdlJGluY29tZSwNCiAgICAgICAgICAgICAgICBkZWdyZWUgPSAwLCBiYW5kd2lkdGggPSA0KSAlPiUgDQogIGFzX3RpYmJsZSgpDQoNCmdncGxvdChQcmVzdGlnZSkgKw0KICBnZW9tX3BvaW50KGFlcyh4ID0gcHJlc3RpZ2UsIHkgPSBpbmNvbWUpKSArDQogIGdlb21fbGluZShkYXRhID0ga2VyNCwgYWVzKHggPSB4LCB5ID0geSksIGNvbCA9ICdncmVlbicpICsNCiAgZ2d0aXRsZSgiS2VybmVsIHNtb290aGluZyAtIHN6ZXJva2/Fm8SHIHBhc21hIHLDs3duYSA0IikNCmBgYA0KDQojIDIuIE1vZGVsIExvZXNzIGt3YWRyYXRvd3kNCg0KYGBge3J9DQpsb2Vzc19tb2RlbCA8LSBsb2VzcyhpbmNvbWUgfiBwcmVzdGlnZSwgZGF0YSA9IFByZXN0aWdlLCBzcGFuID0gMC43NSwgZGVncmVlID0gMikNCmBgYA0KDQpgYGB7cn0NCmdncGxvdChQcmVzdGlnZSwgYWVzKHggPSBwcmVzdGlnZSwgeSA9IGluY29tZSkpICsNCiAgZ2VvbV9wb2ludChjb2xvciA9ICJibHVlIiwgc2l6ZSA9IDIpICsgIA0KICBnZW9tX3Ntb290aChtZXRob2QgPSAibG9lc3MiLCBzcGFuID0gMC43NSwgY29sb3IgPSAicmVkIiwgZmlsbCA9ICJkYXJrZ3JlZW4iLCBhbHBoYSA9IDAuMikgKw0KICBnZ3RpdGxlKCJMT0VTUyAoZGVncmVlID0gMikgeiBwcnplZHphxYJlbSB1Zm5vxZtjaSIpICsNCiAgeGxhYigiUHJlc3RpxbwiKSArDQogIHlsYWIoIkRvY2jDs2QiKSArDQogIHRoZW1lX21pbmltYWwoKQ0KYGBgDQpCYXJkem8gZHXFvG8gb2JzZXJ3YWNqaSBvZHN0YWrEmSBvZCBwcnplZHppYcWCdSB1Zm5vxZtjaS4gU3pjemVnw7NsbmllIHBvd3nFvGVqIDEwayBVU0QuDQoNCiMgMy4gU3Bsb3R5IGludGVycG9sdWrEhWNlDQoNCmBgYHtyfQ0Kc3BsaW5lX21vZGVsIDwtIHNtb290aC5zcGxpbmUoUHJlc3RpZ2UkaW5jb21lLCBQcmVzdGlnZSRwcmVzdGlnZSwgY3Y9VFJVRSkNCg0Kc3BsaW5lX2RhdGEgPC0gZGF0YS5mcmFtZSh4ID0gc3BsaW5lX21vZGVsJHgsIHkgPSBzcGxpbmVfbW9kZWwkeSkNCg0KDQpnZ3Bsb3QoUHJlc3RpZ2UsIGFlcyh4ID0gaW5jb21lLCB5ID0gcHJlc3RpZ2UpKSArDQogIGdlb21fcG9pbnQoY29sb3IgPSAiYmx1ZSIsIHNpemUgPSAyKSArICANCiAgZ2VvbV9saW5lKGRhdGEgPSBzcGxpbmVfZGF0YSwgYWVzKHggPSB4LCB5ID0geSksIGNvbG9yID0gInJlZCIsIHNpemUgPSAxLjIpICsgDQogIGdndGl0bGUoIlNwbG90eSBpbnRlcnBvbHVqxIVjZSAobGFtYmRhIHd5YnJhbmEgcHJ6ZXogQ1YpIikgKw0KICB4bGFiKCJEb2Now7NkIikgKw0KICB5bGFiKCJQcmVzdGnFvCIpICsNCiAgdGhlbWVfbWluaW1hbCgpDQpgYGANCg0KIyA0LiBTcGxvdHkgbmF0dXJhbG5lDQoNCmBgYHtyfQ0KbGlicmFyeShzcGxpbmVzKQ0KYGBgDQoNCmBgYHtyfQ0KbmF0MSA8LSBsbShpbmNvbWUgfiBucyhwcmVzdGlnZSwgZGYgPSA2KSwgZGF0YSA9IFByZXN0aWdlKQ0KbmF0MiA8LSBsbShpbmNvbWUgfiBucyhwcmVzdGlnZSwgZGYgPSAxMiksIGRhdGEgPSBQcmVzdGlnZSkNCg0KZ2dwbG90KFByZXN0aWdlKSArDQogIGdlb21fcG9pbnQoYWVzKHggPSBwcmVzdGlnZSwgeSA9IGluY29tZSkpICsNCiAgZ2d0aXRsZSgiTmF0dXJhbG5lIHNwbG90eSwgNiBkZiAobmllYmllc2tpKSBpIDEyIGRmIChjemVyd29ueSkiKSArDQogIGdlb21fbGluZShhZXMoeCA9IHByZXN0aWdlLCB5ID0gZml0dGVkKG5hdDEpKSwgY29sID0gJ2RhcmtibHVlJywgc2l6ZSA9IDAuNykgKyANCiAgZ2VvbV9saW5lKGFlcyh4ID0gcHJlc3RpZ2UsIHkgPSBmaXR0ZWQobmF0MikpLCBjb2wgPSAncGluaycsIHNpemUgPSAwLjcpICsNCiAgeGxhYigiUHJlc3RpxbwiKSArDQogIHlsYWIoIkRvY2jDs2QiKSArDQogIHRoZW1lX21pbmltYWwoKQ0KYGBgDQoNCmBgYHtyfQ0KZ2dwbG90KFByZXN0aWdlKSArDQogICAgZ2VvbV9wb2ludChhZXMoeD1wcmVzdGlnZSx5PWluY29tZSkpICsNCiAgICBnZW9tX3Ntb290aChhZXMoeD1wcmVzdGlnZSx5PWluY29tZSksIG1ldGhvZD0nZ2FtJywNCiAgICAgIGZvcm11bGEgPSB5IH4gcyh4LGs9MTIpKQ0KYGBgDQoNCiMgWmFkYW5pZSAyDQoNCiMgMS4gS2VybmVsIHNtb290aGluZyANCg0KYGBge3J9DQpsaWJyYXJ5KE1BU1MpDQpkYXRhKG15Y3ljbGUpDQoNCmdncGxvdChtY3ljbGUpKw0KICBnZW9tX3BvaW50KGFlcyh4PXRpbWVzLHk9YWNjZWwpKQ0KYGBgDQoNCiMjIFBvcsOzd25hbmllIHBhc20gKGJyYW5kd2l0aCkNCg0KIyMgMS4xIEJyYW5kd2l0aD0xDQpgYGB7cn0NCmtlcjEgPC0gbG9jcG9seShtY3ljbGUkdGltZXMsIG1jeWNsZSRhY2NlbCwNCiAgICAgICAgICAgICAgICBkZWdyZWUgPSAwLCBiYW5kd2lkdGggPSAxKSAlPiUgYXMudGliYmxlDQoNCmdncGxvdChtY3ljbGUpICsNCiAgZ2VvbV9wb2ludChhZXMoeD10aW1lcywgeT1hY2NlbCkpICsNCiAgZ2VvbV9saW5lKGRhdGEgPSBrZXIxLCBhZXMoeCA9IHgsIHkgPSB5KSwgY29sID0gJ3JlZCcpICsNCiAgZ2d0aXRsZSgiS2VybmVsIHNtb290aGluZyAtIHN6ZXJva2/Fm8SHIHBhc21hIHLDs3duYSAxIikNCmBgYA0KDQojIyAxLjIgQnJhbmR3aXRoPTQNCmBgYHtyfQ0Ka2VyNCA8LSBsb2Nwb2x5KG1jeWNsZSR0aW1lcywgbWN5Y2xlJGFjY2VsLA0KICAgICAgICAgICAgICAgIGRlZ3JlZSA9IDAsIGJhbmR3aWR0aCA9IDQpICU+JSBhcy50aWJibGUNCg0KZ2dwbG90KG1jeWNsZSkgKw0KICBnZW9tX3BvaW50KGFlcyh4ID0gdGltZXMsIHkgPSBhY2NlbCkpICsNCiAgZ2VvbV9saW5lKGRhdGEgPSBrZXI0LCBhZXMoeCA9IHgsIHkgPSB5KSwgY29sID0gJ2dyZWVuJykgKw0KICBnZ3RpdGxlKCJLZXJuZWwgc21vb3RoaW5nIC0gc3plcm9rb8WbxIcgcGFzbWEgcsOzd25hIDQiKQ0KYGBgDQpTemVyb2tvxZvEhyBwYXNtYSByw7N3bmEgMSBsZXBpZWogb2R3em9yb3d1amUsIHN6Y3plZ8OzbG5pZSB0byB3aWRhxIcgcHJ6eSDFgmFwYW5pdSBnw7NyZWsgaSBkb8WCa8Ozdy4NCg0KIyAyLiBNb2RlbCBMb2VzcyBrd2FkcmF0b3d5DQoNCmBgYHtyfQ0KbG9lc3NfbW9kZWwyIDwtIGxvZXNzKGFjY2VsIH4gdGltZXMsIGRhdGEgPSBtY3ljbGUsIHNwYW4gPSAwLjI1LCBkZWdyZWUgPSAyKQ0KYGBgDQoNCmBgYHtyfQ0KZ2dwbG90KG1jeWNsZSwgYWVzKHggPSB0aW1lcywgeSA9IGFjY2VsKSkgKw0KICBnZW9tX3BvaW50KGNvbG9yID0gImJsdWUiLCBzaXplID0gMikgKyAgDQogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsb2VzcyIsIHNwYW4gPSAwLjc1LCBjb2xvciA9ICJyZWQiLCBmaWxsID0gImRhcmtncmVlbiIsIGFscGhhID0gMC4yKSArDQogIGdndGl0bGUoIkxPRVNTIChkZWdyZWUgPSAyKSB6IHByemVkemlhxYJlbSB1Zm5vxZtjaSIpICsNCiAgeGxhYigiQ3phcyAobXMpIikgKw0KICB5bGFiKCJQcnp5c3BpZXN6ZW5pZSAoZykiKSArDQogIHRoZW1lX21pbmltYWwoKQ0KYGBgDQoNCmBgYHtyfQ0KZ2dwbG90KG1jeWNsZSwgYWVzKHggPSB0aW1lcywgeSA9IGFjY2VsKSkgKw0KICBnZW9tX3BvaW50KGNvbG9yID0gImJsdWUiLCBzaXplID0gMikgKyAgDQogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsb2VzcyIsIHNwYW4gPSAwLjI1LCBjb2xvciA9ICJyZWQiLCBmaWxsID0gImRhcmtncmVlbiIsIGFscGhhID0gMC4yKSArDQogIGdndGl0bGUoIkxPRVNTIChkZWdyZWUgPSAyKSB6IHByemVkemlhxYJlbSB1Zm5vxZtjaSIpICsNCiAgeGxhYigiQ3phcyAobXMpIikgKw0KICB5bGFiKCJQcnp5c3BpZXN6ZW5pZSAoZykiKSArDQogIHRoZW1lX21pbmltYWwoKQ0KYGBgDQpTcGFuPTAsNzUgYmFyZHpvIHPFgmFibyBvZHd6b3Jvd3l3YcWCIHptaWVubmUsIHdpxJljIHPFgnVzem55bSBiecWCYSB6bWlhbmEgbmEgc3Bhbj0wLDI1Lg0KDQojIDMuIFNwbG90eSBpbnRlcnBvbHVqxIVjZQ0KDQpgYGB7cn0NCnNwbGluZSA8LSBzbW9vdGguc3BsaW5lKG1jeWNsZSR0aW1lcywgbWN5Y2xlJGFjY2VsLCBjdj1UUlVFKQ0KDQpzcGxpbmVfZGF0YTIgPC0gZGF0YS5mcmFtZSh4ID0gc3BsaW5lJHgsIHkgPSBzcGxpbmUkeSkNCg0KDQpnZ3Bsb3QobWN5Y2xlLCBhZXMoeCA9IHRpbWVzLCB5ID0gYWNjZWwpKSArDQogIGdlb21fcG9pbnQoY29sb3IgPSAiYmx1ZSIsIHNpemUgPSAyKSArICANCiAgZ2VvbV9saW5lKGRhdGEgPSBzcGxpbmVfZGF0YTIsIGFlcyh4ID0geCwgeSA9IHkpLCBjb2xvciA9ICJyZWQiLCBzaXplID0gMS4yKSArIA0KICBnZ3RpdGxlKCJTcGxvdHkgaW50ZXJwb2x1asSFY2UgKGxhbWJkYSB3eWJyYW5hIHByemV6IENWKSIpICsNCiAgeGxhYigiQ3phcyAobXMpIikgKw0KICB5bGFiKCJQcnp5c3BpZXN6ZW5pZSAoZykiKSArDQogIHRoZW1lX21pbmltYWwoKQ0KYGBgDQoNCiMgNC4gU3Bsb3R5IG5hdHVyYWxuZQ0KDQpgYGB7cn0NCmxpYnJhcnkoc3BsaW5lcykNCmBgYA0KDQpgYGB7cn0NCm5hdDMgPC0gbG0oYWNjZWwgfiBucyh0aW1lcywgZGYgPSA2KSwgZGF0YSA9IG1jeWNsZSkNCm5hdDQgPC0gbG0oYWNjZWwgfiBucyh0aW1lcywgZGYgPSAxMiksIGRhdGEgPSBtY3ljbGUpDQoNCg0KZ2dwbG90KG1jeWNsZSkgKw0KICBnZW9tX3BvaW50KGFlcyh4ID0gdGltZXMsIHkgPSBhY2NlbCkpICsNCiAgZ2d0aXRsZSgiTmF0dXJhbG5lIHNwbG90eSwgNiBkZiAobmllYmllc2tpKSBpIDEyIGRmIChjemVyd29ueSkiKSArDQogIGdlb21fbGluZShhZXMoeCA9IHRpbWVzLCB5ID0gZml0dGVkKG5hdDMpKSwgY29sID0gJ2RhcmtibHVlJywgc2l6ZSA9IDAuNykgKyANCiAgZ2VvbV9saW5lKGFlcyh4ID0gdGltZXMsIHkgPSBmaXR0ZWQobmF0NCkpLCBjb2wgPSAncGluaycsIHNpemUgPSAwLjcpICsNCiAgeGxhYigiQ3phcyAobXMpIikgKw0KICB5bGFiKCJQcnp5c3BpZXN6ZW5pZSAoZykiKSArDQogIHRoZW1lX21pbmltYWwoKQ0KYGBgDQoNCg==