1 Zakład Bioinformatyki, Instytut Informatyki, Uniwersytet w Białymstoku

Correspondence: Jarosław Kotowicz <>

1 Grupy 3 i 4 (prowadzący mgr R. Jankowski) zajęcia pierwsze (zastępstwo dr J. Kotowicz)

2 Przygotowanie do pracy

2.1 Instalacja oprogramowania

  1. R strona domowa www.r-project.org
  • wybieramy download
  • wybieramy mirror np. serwer niemiecki
  • ściągamy plik instalacyjny
  1. Rstudio (GUI) dla R RStudio
  • należy pobrać system opensource
  1. Przeglądarka plików pdf natywna dla RStudio (pod Windows) sumatra (opensource)
  1. Instalujemy w kolejności R, sumatra, RStudio

2.2 Przygotowanie do pracy

  1. W katalagu dokumenty tworzymy folder (nazwa zgodnie z zasadą Inf_xxxxx, gdzie xxxxx to numer albumu).
  2. Uruchamiamy RSudio
  3. Zachowujemy porządek. Tworzymy nowy projekt
  • Files -> New Project… -> Existing Directory -> Browse… i wybieramy folder, który utworzyliśmy oraz zaznaczamy Open in new session.
    Uwaga: Zawsze na koniec pracy/zajęć należy zamknąć projekt. Files -> Close Project
    Uwaga: Zawsze na początku pracy/zajęć należy otworzyć projekt. Files -> Recent Projects i wybrać swój (będzie miał on taką nazwę, jak nasz katalog).
  1. Dostosowujem RSudio do następujących wymagań:
  • Tools -> Project Options ->
    1. Code Editing -> Text encoding wybór UTF-8
    2. Sweave -> PDF Generaion wybór knitr
      Uwaga: Jeżeli chcemy korzystać z TeX (LaTeX), to musimy mieć zaistalowny system/program np. MikTeX.
  • Tools -> Global Options ->
    1. Appearance wybór wyglądu RSudion np. ambiance (ciemny motyw).

  1. W domu instalujemy konieczne biblioteki R nazywane package
  • dolne prawe okienko - okno Packages -> Install wpisujemy tidyverse
  1. Otwieramy pliki
  • R Script: Files -> New File -> R Script
  • R Notebook: Files -> New File -> R Notebook
  • R Markdown: Files -> New File -> R Markdown i wybieramy rodzaj dokumentu np. Document lub Presentation.
    Uwaga: Wszystkie pliki podpisujemy zgodnie ze schematem Inf_xxxxx.

  1. Będziemy zawsze pracować albo w pliku skryptowym R albo w R Notebook.
  2. Informacje dla pliku skryptowego
  • wywołanie aktualnej linii w konsoli CTRL+ENTER
  • odwołanie się do funkcji z danej biblioteki package::function np. stats::filter
  • podczytanie biblioteki library(nazwa bibilioteki)
  • znak komentarza hashtag tzn. #

  1. Import danych
  • korzystamy z danych dostępnych na stronie Jareda P. Landera
  • plik csv (textowe) import: File -> Import Dataset -> From Text (readr) (w polu File/URL kopiujemy adres https://jaredlander.com/data/ i dopisujemy nazwę pliku np. acs_ny.csv) -> Update
  • wykorzystujemy opcje Import Options aby wybrać np. znak rozdzielający dane średnik to semicolon itd.
  • możemy zmienić też typy kolumn wybierając dla kolumny z menu rozwijalnego wartość Uwaga: W przypadku typu factor (zmienna czynnikowa) należy wskazać wszystkie poziomy (wartości.
  • kopiujemy z okienka Code Preview do pliku skryptowego polecenie poczytując wcześniej bibliotekę readr, ja tutaj podczytuję tidyverse.
  • braki danych NA (skrót od not available), nieliczby NaN (not a number)
  • typ numeric w R identyczny jak double w C++ i co więcej używane też jest równoważnie numeric i double
library(tidyverse)
Registered S3 method overwritten by 'dplyr':
  method           from
  print.rowwise_df     
Registered S3 methods overwritten by 'dbplyr':
  method         from
  print.tbl_lazy     
  print.tbl_sql      
-- Attaching packages --------------------------------------- tidyverse 1.3.0 --
<U+221A> ggplot2 3.3.0     <U+221A> purrr   0.3.3
<U+221A> tibble  2.1.3     <U+221A> dplyr   0.8.4
<U+221A> tidyr   1.0.2     <U+221A> stringr 1.4.0
<U+221A> readr   1.3.1     <U+221A> forcats 0.5.0
-- Conflicts ------------------------------------------ tidyverse_conflicts() --
x dplyr::filter() masks stats::filter()
x dplyr::lag()    masks stats::lag()

Przykład (skopiowany kod i następnie uporządkowany)

acsNY <- read_csv("https://jaredlander.com/data/acs_ny.csv", 
                  col_types = cols(ElectricBill = col_integer(), 
                                   FamilyIncome = col_integer(), 
                                   FamilyType = col_factor(levels = c("Married", "Female Head", "Male Head")), 
                                   HouseCosts = col_integer(), 
                                   Insurance = col_integer(), 
                                   NumBedrooms = col_integer(), 
                                   NumChildren = col_integer(), 
                                   NumPeople = col_integer(), 
                                   NumRooms = col_integer(), 
                                   NumVehicles = col_integer(), 
                                   NumWorkers = col_integer()))

  1. Przetwarzanie potokowe tzw. pipe (biblioteka magrittr) Uwaga: Użycie biblioteki dplyr powoduje możliwość korzystania z przetwarzania potokowego. Używając biblioteki tidyverse podczytuję również dplyr.
    co wysyłam %>% gdzie wysyłam
    Zasada przetwarzania potkowego f(a) jest to a %>% f

f(a,b) jest to a %>% f(b)

f(a,b) jest to b %>% f(a,.) f(a,b) Uwaga: Kropka wskazuje miejsca wstawienia zmiennej.

g(f(a)) jest to a %>% f %>% g

  1. Reguła wcięć poprawny zapis zgodny z regułą wcięć to
acsNY %>%
  filter(NumChildren == 0) %>%
  select(c(1:6)) %>%
  head()
save(acsNY, file = "acsNY.RData")
rm(list = ls())
load("acsNY.RData")
summary(acsNY)
    Acres            FamilyIncome           FamilyType     NumBedrooms     NumChildren        NumPeople        NumRooms     
 Length:22745       Min.   :     50   Married    :18326   Min.   :0.000   Min.   : 0.0000   Min.   : 2.00   Min.   : 1.000  
 Class :character   1st Qu.:  52540   Female Head: 3266   1st Qu.:3.000   1st Qu.: 0.0000   1st Qu.: 2.00   1st Qu.: 6.000  
 Mode  :character   Median :  87000   Male Head  : 1153   Median :3.000   Median : 0.0000   Median : 3.00   Median : 7.000  
                    Mean   : 110281                       Mean   :3.385   Mean   : 0.9012   Mean   : 3.39   Mean   : 7.175  
                    3rd Qu.: 133800                       3rd Qu.:4.000   3rd Qu.: 2.0000   3rd Qu.: 4.00   3rd Qu.: 8.000  
                    Max.   :1605000                       Max.   :8.000   Max.   :12.0000   Max.   :18.00   Max.   :21.000  
   NumUnits          NumVehicles      NumWorkers      OwnRent           YearBuilt           HouseCosts    ElectricBill
 Length:22745       Min.   :0.000   Min.   :0.000   Length:22745       Length:22745       Min.   :   4   Min.   :  1  
 Class :character   1st Qu.:2.000   1st Qu.:1.000   Class :character   Class :character   1st Qu.: 650   1st Qu.:100  
 Mode  :character   Median :2.000   Median :2.000   Mode  :character   Mode  :character   Median :1200   Median :150  
                    Mean   :2.113   Mean   :1.745                                         Mean   :1480   Mean   :175  
                    3rd Qu.:3.000   3rd Qu.:2.000                                         3rd Qu.:2000   3rd Qu.:220  
                    Max.   :6.000   Max.   :3.000                                         Max.   :7090   Max.   :580  
  FoodStamp         HeatingFuel          Insurance        Language        
 Length:22745       Length:22745       Min.   :   0.0   Length:22745      
 Class :character   Class :character   1st Qu.: 400.0   Class :character  
 Mode  :character   Mode  :character   Median : 720.0   Mode  :character  
                                       Mean   : 960.9                     
                                       3rd Qu.:1200.0                     
                                       Max.   :6600.0                     
acsNew <- read_csv("https://www.jaredlander.com/data/acsNew.csv", 
                   col_types = cols(ElectricBill = col_integer(), 
                                    FamilyIncome = col_integer(),
                                    FamilyType = col_factor(levels = c("Married", "Female Head", "Male Head")),
                                    HeatingFuel = col_factor(levels = c("Wood", "Oil", "Electricity", "Gas", "Coal", "Other", "None")),
                                    HouseCosts = col_integer(),
                                    Income = col_factor(levels = c("Below", "Above")),
                                    Insurance = col_integer(), 
                                    NumBedrooms = col_integer(), 
                                    NumChildren = col_integer(), 
                                    NumPeople = col_integer(), 
                                    NumRooms = col_integer(), 
                                    NumVehicles = col_integer(), 
                                    NumWorkers = col_integer()))
summary(acsNew)
    Acres            FamilyIncome           FamilyType    NumBedrooms     NumChildren       NumPeople         NumRooms     
 Length:2273        Min.   :   1125   Married    :1831   Min.   :0.000   Min.   :0.0000   Min.   : 2.000   Min.   : 1.000  
 Class :character   1st Qu.:  53700   Female Head: 327   1st Qu.:3.000   1st Qu.:0.0000   1st Qu.: 2.000   1st Qu.: 6.000  
 Mode  :character   Median :  89200   Male Head  : 115   Median :3.000   Median :0.0000   Median : 3.000   Median : 7.000  
                    Mean   : 110982                      Mean   :3.404   Mean   :0.8847   Mean   : 3.401   Mean   : 7.241  
                    3rd Qu.: 136630                      3rd Qu.:4.000   3rd Qu.:2.0000   3rd Qu.: 4.000   3rd Qu.: 8.000  
                    Max.   :1014000                      Max.   :8.000   Max.   :8.0000   Max.   :12.000   Max.   :21.000  
                                                                                                                           
   NumUnits          NumVehicles      NumWorkers      OwnRent           YearBuilt           HouseCosts    ElectricBill  
 Length:2273        Min.   :0.000   Min.   :0.000   Length:2273        Length:2273        Min.   :   4   Min.   :  1.0  
 Class :character   1st Qu.:2.000   1st Qu.:1.000   Class :character   Class :character   1st Qu.: 670   1st Qu.:100.0  
 Mode  :character   Median :2.000   Median :2.000   Mode  :character   Mode  :character   Median :1200   Median :150.0  
                    Mean   :2.118   Mean   :1.778                                         Mean   :1488   Mean   :176.6  
                    3rd Qu.:3.000   3rd Qu.:2.000                                         3rd Qu.:2000   3rd Qu.:220.0  
                    Max.   :6.000   Max.   :3.000                                         Max.   :6500   Max.   :580.0  
                                                                                                                        
  FoodStamp              HeatingFuel     Insurance        Language           Income    
 Length:2273        Wood       : 117   Min.   :   0.0   Length:2273        Below:1817  
 Class :character   Oil        : 622   1st Qu.: 400.0   Class :character   Above: 456  
 Mode  :character   Electricity: 109   Median : 720.0   Mode  :character               
                    Gas        :1387   Mean   : 968.1                                  
                    Coal       :  16   3rd Qu.:1200.0                                  
                    Other      :  18   Max.   :6600.0                                  
                    None       :   4                                                   
acsNY %>% summary
    Acres            FamilyIncome           FamilyType     NumBedrooms     NumChildren        NumPeople        NumRooms     
 Length:22745       Min.   :     50   Married    :18326   Min.   :0.000   Min.   : 0.0000   Min.   : 2.00   Min.   : 1.000  
 Class :character   1st Qu.:  52540   Female Head: 3266   1st Qu.:3.000   1st Qu.: 0.0000   1st Qu.: 2.00   1st Qu.: 6.000  
 Mode  :character   Median :  87000   Male Head  : 1153   Median :3.000   Median : 0.0000   Median : 3.00   Median : 7.000  
                    Mean   : 110281                       Mean   :3.385   Mean   : 0.9012   Mean   : 3.39   Mean   : 7.175  
                    3rd Qu.: 133800                       3rd Qu.:4.000   3rd Qu.: 2.0000   3rd Qu.: 4.00   3rd Qu.: 8.000  
                    Max.   :1605000                       Max.   :8.000   Max.   :12.0000   Max.   :18.00   Max.   :21.000  
   NumUnits          NumVehicles      NumWorkers      OwnRent           YearBuilt           HouseCosts    ElectricBill
 Length:22745       Min.   :0.000   Min.   :0.000   Length:22745       Length:22745       Min.   :   4   Min.   :  1  
 Class :character   1st Qu.:2.000   1st Qu.:1.000   Class :character   Class :character   1st Qu.: 650   1st Qu.:100  
 Mode  :character   Median :2.000   Median :2.000   Mode  :character   Mode  :character   Median :1200   Median :150  
                    Mean   :2.113   Mean   :1.745                                         Mean   :1480   Mean   :175  
                    3rd Qu.:3.000   3rd Qu.:2.000                                         3rd Qu.:2000   3rd Qu.:220  
                    Max.   :6.000   Max.   :3.000                                         Max.   :7090   Max.   :580  
  FoodStamp         HeatingFuel          Insurance        Language        
 Length:22745       Length:22745       Min.   :   0.0   Length:22745      
 Class :character   Class :character   1st Qu.: 400.0   Class :character  
 Mode  :character   Mode  :character   Median : 720.0   Mode  :character  
                                       Mean   : 960.9                     
                                       3rd Qu.:1200.0                     
                                       Max.   :6600.0                     

W razie pytań porszę o kontak e-mailowy.

3 Praca domowa z dnia 18 marca 2020r. (do laboratorium)

  1. Proszę przeczytać R Notebooki na mojej stronie.
LS0tDQp0aXRsZTogIk1ldG9keSBwcm9iYWJpbGlzdHljem5lIGkgc3RhdHlzdHlrYSAoaW5mb3JtYXR5a2EpIC0gbGFib3JhdG9yaXVtIChncnVweSAzIGkgNCkiDQphdXRob3I6DQotIEphcm9zxYJhdyBLb3Rvd2ljejoNCiAgICBjb3JyZXNwb25kZW5jZTogbm8NCiAgICBlbWFpbDogai5rb3Rvd2ljekB1d2IuZWR1LnBsDQogICAgaW5zdGl0dXRlOiBJSVV3Qg0KZGF0ZTogIjE4IG1hcmNhIDIwMjAiDQpvdXRwdXQ6DQogIGh0bWxfbm90ZWJvb2s6DQogICAgZmlnX2NhcHRpb246IHllcw0KICAgIGhpZ2hsaWdodDogaGFkZG9jaw0KICAgIG51bWJlcl9zZWN0aW9uczogeWVzDQogICAgcGFuZG9jX2FyZ3M6DQogICAgLSAtLWx1YS1maWx0ZXI9c2Nob2xhcmx5LW1ldGFkYXRhLmx1YQ0KICAgIC0gLS1sdWEtZmlsdGVyPWF1dGhvci1pbmZvLWJsb2Nrcy5sdWENCiAgICB0aGVtZTogY2VydWxlYW4NCiAgICB0b2M6IHllcw0KaW5zdGl0dXRlOg0KLSBJSVV3QjogWmFrxYJhZCBCaW9pbmZvcm1hdHlraSwgSW5zdHl0dXQgSW5mb3JtYXR5a2ksIFVuaXdlcnN5dGV0IHcgQmlhxYJ5bXN0b2t1DQpjc2w6IGJpZy1kYXRhLWFuZC1pbmZvcm1hdGlvbi1hbmFseXRpY3MuY3NsDQphbHdheXNfYWxsb3dfaHRtbDogeWVzDQotLS0NCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpDQpgYGANCg0KIyBHcnVweSAzIGkgNCAocHJvd2FkesSFY3kgbWdyIFIuIEphbmtvd3NraSkgemFqxJljaWEgcGllcndzemUgKHphc3TEmXBzdHdvICBkciBKLiBLb3Rvd2ljeikNCg0KIyBQcnp5Z290b3dhbmllIGRvIHByYWN5DQoNCiMjIEluc3RhbGFjamEgb3Byb2dyYW1vd2FuaWENCjEuIFIgIFtzdHJvbmEgZG9tb3dhIHd3dy5yLXByb2plY3Qub3JnXShodHRwczovL3d3dy5yLXByb2plY3Qub3JnKQ0KICAtIHd5YmllcmFteSBkb3dubG9hZA0KICAtIHd5YmllcmFteSBtaXJyb3IgbnAuIHNlcndlciBuaWVtaWVja2kNCiAgLSDFm2NpxIVnYW15IHBsaWsgaW5zdGFsYWN5am55DQoyLiBSc3R1ZGlvIChHVUkpIGRsYSBSIFtSU3R1ZGlvXShodHRwczovL3d3dy5yLnN0dWRpby5jb20vKQ0KICAtIG5hbGXFvHkgcG9icmHEhyBzeXN0ZW0gb3BlbnNvdXJjZQ0KMy4gUHJ6ZWdsxIVkYXJrYSBwbGlrw7N3ICoqcGRmKiogbmF0eXduYSBkbGEgUlN0dWRpbyAocG9kIFdpbmRvd3MpICoqc3VtYXRyYSoqIChvcGVuc291cmNlKQ0KICAtIHBvYmllcmFteSB6ZSBzdHJvbnkgW1N1bWF0cmFdKGh0dHBzOi8vd3d3LnN1bWF0cmFwZGZyZWFkZXIub3JnL2ZyZWUtcGRmLXJlYWRlci5odG1sKQ0KNC4gSW5zdGFsdWplbXkgdyBrb2xlam5vxZtjaSBSLCBzdW1hdHJhLCBSU3R1ZGlvICANCiAgDQojIyBQcnp5Z290b3dhbmllIGRvIHByYWN5DQoxLiBXIGthdGFsYWd1IGRva3VtZW50eSB0d29yenlteSBmb2xkZXIgKG5hendhIHpnb2RuaWUgeiB6YXNhZMSFICoqSW5mX3h4eHh4KiosIGdkemllICp4eHh4eCogdG8gbnVtZXIgYWxidW11KS4NCjIuIFVydWNoYW1pYW15ICpSU3VkaW8qDQozLiBaYWNob3d1amVteSBwb3J6xIVkZWsuIFR3b3J6eW15IG5vd3kgcHJvamVrdA0KICAtICpGaWxlcyogLT4gKk5ldyBQcm9qZWN0Li4uKiAtPiAqRXhpc3RpbmcgRGlyZWN0b3J5KiAtPiAqQnJvd3NlLi4uKiBpIHd5YmllcmFteSBmb2xkZXIsIGt0w7NyeSB1dHdvcnp5bGnFm215IG9yYXogemF6bmFjemFteSAqT3BlbiBpbiBuZXcgc2Vzc2lvbiouIDxCUj4NCjxzcGFuIHN0eWxlID0gImNvbG9yOiAgcmVkIj4gVXdhZ2E6IFphd3N6ZSBuYSBrb25pZWMgcHJhY3kvemFqxJnEhyBuYWxlxbx5IHphbWtuxIXEhyBwcm9qZWt0Ljwvc3Bhbj4gDQogICpGaWxlcyogLT4gKkNsb3NlIFByb2plY3QqICA8QlI+DQo8c3BhbiBzdHlsZSA9ICJjb2xvcjogIHJlZCI+IFV3YWdhOiBaYXdzemUgbmEgcG9jesSFdGt1IHByYWN5L3phasSZxIcgbmFsZcW8eSBvdHdvcnp5xIcgcHJvamVrdC48L3NwYW4+IA0KICAqRmlsZXMqIC0+ICpSZWNlbnQgUHJvamVjdHMqICBpIHd5YnJhxIcgc3fDs2ogKCpixJlkemllIG1pYcWCIG9uIHRha8SFIG5henfEmSwgamFrIG5hc3oga2F0YWxvZyopLg0KNC4gRG9zdG9zb3d1amVtICpSU3VkaW8qIGRvIG5hc3TEmXB1asSFY3ljaCB3eW1hZ2HFhDoNCiAgLSAgKlRvb2xzKiAtPiAgKlByb2plY3QgT3B0aW9ucyogLT4gDQogIDxvbD4NCiAgICA8bGk+ICpDb2RlIEVkaXRpbmcqIC0+ICAqVGV4dCBlbmNvZGluZyogd3liw7NyICoqVVRGLTgqKiA8L2xpPg0KICAgIDxsaT4gKlN3ZWF2ZSogLT4gICpQREYgR2VuZXJhaW9uKiAgd3liw7NyICoqa25pdHIqKjxCUj4NCjxzcGFuIHN0eWxlID0gImNvbG9yOiAgcmVkIj4gVXdhZ2E6IEplxbxlbGkgY2hjZW15IGtvcnp5c3RhxIcgeiBUZVggKExhVGVYKSwgdG8gbXVzaW15IG1pZcSHIHphaXN0YWxvd255IHN5c3RlbS9wcm9ncmFtIG5wLiBNaWtUZVguPC9zcGFuPiA8L2xpPg0KICA8L29sPg0KICAtICAqVG9vbHMqIC0+ICAqR2xvYmFsIE9wdGlvbnMqIC0+DQogIDxvbD4NCiAgICA8bGk+ICpBcHBlYXJhbmNlKiB3eWLDs3Igd3lnbMSFZHUgKlJTdWRpb24qIG5wLiAqKmFtYmlhbmNlKiogKCpjaWVtbnkgbW90eXcqKS4gPC9saT4NCiAgPC9vbD4NCg0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KNC4gVyBkb211IGluc3RhbHVqZW15IGtvbmllY3puZSBiaWJsaW90ZWtpICoqUioqIG5henl3YW5lICoqcGFja2FnZSoqDQogIC0gZG9sbmUgcHJhd2Ugb2tpZW5rbyAtIG9rbm8gKlBhY2thZ2VzKiAtPiAqSW5zdGFsbCogIHdwaXN1amVteSAqKnRpZHl2ZXJzZSoqDQo1LiBPdHdpZXJhbXkgcGxpa2kgDQogIC0gKipSIFNjcmlwdCoqOiAqRmlsZXMqIC0+ICpOZXcgRmlsZSogLT4gKlIgU2NyaXB0Kg0KICAtICoqUiBOb3RlYm9vayoqOiAgKkZpbGVzKiAtPiAqTmV3IEZpbGUqIC0+ICpSIE5vdGVib29rKg0KICAtICoqUiBNYXJrZG93bioqOiAqRmlsZXMqIC0+ICpOZXcgRmlsZSogLT4gKlIgTWFya2Rvd24qIGkgd3liaWVyYW15IHJvZHphaiBkb2t1bWVudHUgbnAuICpEb2N1bWVudCogbHViICpQcmVzZW50YXRpb24qLiAgIDxCUj4NCjxzcGFuIHN0eWxlID0gImNvbG9yOiAgcmVkIj4gVXdhZ2E6IFdzenlzdGtpZSBwbGlraSBwb2RwaXN1amVteSB6Z29kbmllIHplIHNjaGVtYXRlbSAqSW5mX3h4eHh4Ki48L3NwYW4+DQoNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCjYuIELEmWR6aWVteSB6YXdzemUgcHJhY293YcSHIGFsYm8gdyBwbGlrdSBza3J5cHRvd3ltICpSKiBhbGJvIHcgKlIgTm90ZWJvb2sqLg0KNy4gSW5mb3JtYWNqZSBkbGEgcGxpa3Ugc2tyeXB0b3dlZ28gDQogIC0gd3l3b8WCYW5pZSBha3R1YWxuZWogbGluaWkgdyBrb25zb2xpICpDVFJMK0VOVEVSKg0KICAtIG9kd2/FgmFuaWUgc2nEmSBkbyBmdW5rY2ppIHogZGFuZWogYmlibGlvdGVraSAqcGFja2FnZTo6ZnVuY3Rpb24qIG5wLiAqc3RhdHM6OmZpbHRlcioNCiAgLSBwb2Rjenl0YW5pZSBiaWJsaW90ZWtpICpsaWJyYXJ5KG5hendhIGJpYmlsaW90ZWtpKSoNCiAgLSB6bmFrIGtvbWVudGFyemEgaGFzaHRhZyB0em4uICMNCg0KLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0NCg0KOC4gSW1wb3J0IGRhbnljaCANCiAgLSBrb3J6eXN0YW15IHogZGFueWNoIGRvc3TEmXBueWNoIG5hIHN0cm9uaWUgW0phcmVkYSBQLiBMYW5kZXJhXShodHRwczovL2phcmVkbGFuZGVyLmNvbS9kYXRhLykNCiAgLSBwbGlrICpjc3YqICh0ZXh0b3dlKSBpbXBvcnQ6ICpGaWxlKiAtPiAqSW1wb3J0IERhdGFzZXQqIC0+ICpGcm9tIFRleHQgKHJlYWRyKSogICh3IHBvbHUgKkZpbGUvVVJMKg0KICBrb3BpdWplbXkgYWRyZXMgKmh0dHBzOi8vamFyZWRsYW5kZXIuY29tL2RhdGEvKiBpIGRvcGlzdWplbXkgbmF6d8SZIHBsaWt1IG5wLiAqYWNzX255LmNzdiopIC0+ICpVcGRhdGUqDQogIC0gd3lrb3J6eXN0dWplbXkgb3BjamUgKkltcG9ydCBPcHRpb25zKglhYnkgd3licmHEhyBucC4gem5hayByb3pkemllbGFqxIVjeSBkYW5lIMWbcmVkbmlrIHRvICpzZW1pY29sb24qIGl0ZC4NCiAgLSBtb8W8ZW15IHptaWVuacSHIHRlxbwgdHlweSBrb2x1bW4gd3liaWVyYWrEhWMgZGxhIGtvbHVtbnkgeiBtZW51IHJvendpamFsbmVnbyB3YXJ0b8WbxIcgPHNwYW4gc3R5bGUgPSAiY29sb3I6ICByZWQiPiBVd2FnYTogVyBwcnp5cGFka3UgdHlwdSAqZmFjdG9yKiAoem1pZW5uYSBjenlubmlrb3dhKSBuYWxlxbx5IHdza2F6YcSHIHdzenlzdGtpZSBwb3ppb215ICh3YXJ0b8WbY2kuPC9zcGFuPiANCiAgLSBrb3BpdWplbXkgeiBva2llbmthICpDb2RlIFByZXZpZXcqIGRvIHBsaWt1IHNrcnlwdG93ZWdvIHBvbGVjZW5pZSBwb2N6eXR1asSFYyB3Y3plxZtuaWVqIGJpYmxpb3Rla8SZICpyZWFkciosIGphIHR1dGFqIHBvZGN6eXR1asSZICp0aWR5dmVyc2UqLg0KICAtIGJyYWtpIGRhbnljaCAqKk5BKiogIChza3LDs3Qgb2QgKm5vdCBhdmFpbGFibGUqKSwgbmllbGljemJ5ICoqTmFOKiogKCpub3QgYSBudW1iZXIqKQ0KICAtIHR5cCAqbnVtZXJpYyogdyBSIGlkZW50eWN6bnkgamFrICpkb3VibGUqIHcgQysrIGkgY28gd2nEmWNlaiB1xbx5d2FuZSB0ZcW8IGplc3QgcsOzd25vd2HFvG5pZSAqbnVtZXJpYyogaSAqZG91YmxlKg0KDQpgYGB7cn0NCmxpYnJhcnkodGlkeXZlcnNlKQ0KYGBgDQoJDQpQcnp5a8WCYWQgKHNrb3Bpb3dhbnkga29kIGkgbmFzdMSZcG5pZSB1cG9yesSFZGtvd2FueSkNCmBgYHtyfQ0KYWNzTlkgPC0gcmVhZF9jc3YoImh0dHBzOi8vamFyZWRsYW5kZXIuY29tL2RhdGEvYWNzX255LmNzdiIsIA0KICAgICAgICAgICAgICAgICAgY29sX3R5cGVzID0gY29scyhFbGVjdHJpY0JpbGwgPSBjb2xfaW50ZWdlcigpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmFtaWx5SW5jb21lID0gY29sX2ludGVnZXIoKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZhbWlseVR5cGUgPSBjb2xfZmFjdG9yKGxldmVscyA9IGMoIk1hcnJpZWQiLCAiRmVtYWxlIEhlYWQiLCAiTWFsZSBIZWFkIikpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSG91c2VDb3N0cyA9IGNvbF9pbnRlZ2VyKCksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbnN1cmFuY2UgPSBjb2xfaW50ZWdlcigpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTnVtQmVkcm9vbXMgPSBjb2xfaW50ZWdlcigpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTnVtQ2hpbGRyZW4gPSBjb2xfaW50ZWdlcigpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTnVtUGVvcGxlID0gY29sX2ludGVnZXIoKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE51bVJvb21zID0gY29sX2ludGVnZXIoKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE51bVZlaGljbGVzID0gY29sX2ludGVnZXIoKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE51bVdvcmtlcnMgPSBjb2xfaW50ZWdlcigpKSkNCg0KYGBgDQoNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tDQoNCjkuIFByemV0d2FyemFuaWUgcG90b2tvd2UgdHp3LiAqcGlwZSogKGJpYmxpb3Rla2EgKm1hZ3JpdHRyKikgPHNwYW4gc3R5bGUgPSAiY29sb3I6ICByZWQiPiBVd2FnYTogVcW8eWNpZSBiaWJsaW90ZWtpICpkcGx5ciogcG93b2R1amUgbW/FvGxpd2/Fm8SHIGtvcnp5c3RhbmlhIHogcHJ6ZXR3YXJ6YW5pYSBwb3Rva293ZWdvLiBVxbx5d2FqxIVjIGJpYmxpb3Rla2kgKnRpZHl2ZXJzZSogcG9kY3p5dHVqxJkgcsOzd25pZcW8ICpkcGx5ciouPC9zcGFuPg0KPGNlbnRlcj4NCioqY28gd3lzecWCYW0gJT4lIGdkemllIHd5c3nFgmFtKioNCjwvY2VudGVyPg0KWmFzYWRhICBwcnpldHdhcnphbmlhIHBvdGtvd2Vnbw0KKipmKGEpKiogamVzdCB0byAgKiphICU+JSBmKioNCg0KKipmKGEsYikqKiBqZXN0IHRvICoqYSAlPiUgZihiKSoqDQoNCioqZihhLGIpKiogamVzdCB0byAqKmIgJT4lIGYoYSwuKSoqICoqZihhLGIpKiogPHNwYW4gc3R5bGUgPSAiY29sb3I6ICByZWQiPiBVd2FnYTogKipLcm9wa2EqKiB3c2thenVqZSBtaWVqc2NhIHdzdGF3aWVuaWEgem1pZW5uZWouPC9zcGFuPg0KDQoqKmcoZihhKSkqKiBqZXN0IHRvICoqYSAlPiUgZiAlPiUgZyoqDQoNCjEwLiBSZWd1xYJhIHdjacSZxIcgcG9wcmF3bnkgemFwaXMgemdvZG55IHogcmVndcWCxIUgd2NpxJnEhyB0bw0KDQpgYGB7cn0NCmFjc05ZICU+JQ0KICBmaWx0ZXIoTnVtQ2hpbGRyZW4gPT0gMCkgJT4lDQogIHNlbGVjdChjKDE6NikpICU+JQ0KICBoZWFkKCkNCmBgYA0KDQpgYGB7cn0NCg0Kc2F2ZShhY3NOWSwgZmlsZSA9ICJhY3NOWS5SRGF0YSIpDQpgYGANCg0KYGBge3J9DQpybShsaXN0ID0gbHMoKSkNCmBgYA0KDQpgYGB7cn0NCmxvYWQoImFjc05ZLlJEYXRhIikNCmBgYA0KDQpgYGB7cn0NCnN1bW1hcnkoYWNzTlkpDQpgYGANCg0KYGBge3J9DQphY3NOZXcgPC0gcmVhZF9jc3YoImh0dHBzOi8vd3d3LmphcmVkbGFuZGVyLmNvbS9kYXRhL2Fjc05ldy5jc3YiLCANCiAgICAgICAgICAgICAgICAgICBjb2xfdHlwZXMgPSBjb2xzKEVsZWN0cmljQmlsbCA9IGNvbF9pbnRlZ2VyKCksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmFtaWx5SW5jb21lID0gY29sX2ludGVnZXIoKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZhbWlseVR5cGUgPSBjb2xfZmFjdG9yKGxldmVscyA9IGMoIk1hcnJpZWQiLCAiRmVtYWxlIEhlYWQiLCAiTWFsZSBIZWFkIikpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSGVhdGluZ0Z1ZWwgPSBjb2xfZmFjdG9yKGxldmVscyA9IGMoIldvb2QiLCAiT2lsIiwgIkVsZWN0cmljaXR5IiwgIkdhcyIsICJDb2FsIiwgIk90aGVyIiwgIk5vbmUiKSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBIb3VzZUNvc3RzID0gY29sX2ludGVnZXIoKSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEluY29tZSA9IGNvbF9mYWN0b3IobGV2ZWxzID0gYygiQmVsb3ciLCAiQWJvdmUiKSksDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbnN1cmFuY2UgPSBjb2xfaW50ZWdlcigpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE51bUJlZHJvb21zID0gY29sX2ludGVnZXIoKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOdW1DaGlsZHJlbiA9IGNvbF9pbnRlZ2VyKCksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTnVtUGVvcGxlID0gY29sX2ludGVnZXIoKSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOdW1Sb29tcyA9IGNvbF9pbnRlZ2VyKCksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTnVtVmVoaWNsZXMgPSBjb2xfaW50ZWdlcigpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE51bVdvcmtlcnMgPSBjb2xfaW50ZWdlcigpKSkNCmBgYA0KDQpgYGB7cn0NCnN1bW1hcnkoYWNzTmV3KQ0KYGBgDQoNCmBgYHtyfQ0KYWNzTlkgJT4lIHN1bW1hcnkNCmBgYA0KDQpXIHJhemllIHB5dGHFhCBwb3JzesSZIG8ga29udGFrIGUtbWFpbG93eS4NCg0KIyBQcmFjYSBkb21vd2EgeiBkbmlhIDE4IG1hcmNhIDIwMjByLiAoZG8gbGFib3JhdG9yaXVtKQ0KDQoxLiBQcm9zesSZIHByemVjenl0YcSHICpSIE5vdGVib29raSogbmEgbW9qZWogc3Ryb25pZS4NCiA=