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

Correspondence: Jarosław Kotowicz <>

1 Bibliotek bdl i jej funkcje

1.1 Podczytanie biblioteki bdl (oraz bibliotek tidyverse)

library(bdl)
Registered S3 method overwritten by 'data.table':
  method           from
  print.data.table     
Registered S3 method overwritten by 'htmlwidgets':
  method           from         
  print.htmlwidget tools:rstudio
library(tidyverse)
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.4
<U+221A> tibble  3.0.1     <U+221A> dplyr   0.8.5
<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()

1.2 Czyszczenie zmiennych w środowisku

rm(list = ls())

1.3 Funkcje dostępne w bibliotece bdl

1.3.1 Funkcja get_levels

poziomy <- get_levels()
poziomy

1.3.2 Funkcja get_units

tree <- get_units()
Unit metadata has changed during searched year interval. Check description using `unit_info()` or `unit_locality_info()` for localities.
tree %>% colnames
[1] "id"             "name"           "level"          "unitHasChanged" "parentId"       "kind"          
tree
# tree %>% View

1.3.2.1 Wybór odpowiednich poziomów

tree %>% filter(level == 2) 
# %>% View

1.3.2.2 Województwa i dane dla nich

wojewodztwa <- tree %>% filter(level == 2)
unit_info("062000000000")
$id
[1] "062000000000"

$name
[1] "PODLASKIE"

$parentId
[1] "060000000000"

$level
[1] 2

$hasDescription
[1] FALSE

$years
 [1] 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016
[23] 2017 2018 2019 2020

1.3.2.3 Powiaty

powiaty <- tree %>% filter(level == 5)

1.3.2.4 Gminy

gminy <- tree %>% filter(level == 6)

1.3.2.5 Identyfikatory (id) województw, powiatów i gmin

wojewodztwa.id <- wojewodztwa %>% pull(id)
powiaty.id <- powiaty %>% pull(id)
gminy.id <- gminy %>% pull(id)

1.3.3 Funkcja get_subject

1.3.3.1 Podstawowe kategorie

subject <- get_subjects()
subject

1.3.4 Funkcja subject_info

1.3.4.1 Informacja o kategorii (m.in. zakres lat, grupy w kategorii itp.)

subject_info("K3")
$id
[1] "K3"

$name
[1] "LUDNOŚĆ"

$hasVariables
[1] FALSE

$children
[1] "G7"   "G8"   "G10"  "G534" "G535" "G557" "G564"

$years
 [1] 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016
[23] 2017 2018 2019 2020

$availability

$dimensions
list()

$lastUpdate
[1] "2020-05-07T08:37:43.133"

$description
[1] "Bilanse liczby i struktury ludności w gminach imiennie opracowane w oparciu o wyniki Narodowych Spisów Powszechnych z uwzględnieniem zmian spowodowanych ruchem naturalnym (urodzenia i zgony), migracjami ludności (na pobyt stały i czasowy) oraz przemieszczeniami związanymi ze zmianami administracyjnymi. Dane o ludności w miejscowościach na podstawie rejestru PESEL. Dane o zarejestrowanych małżeństwach, urodzeniach i zgonach pochodzące ze sprawozdawczości urzędów stanu cywilnego. Dane o orzeczonych rozwodach i separacjach pochodzące ze sprawozdawczości sądów. Dane o migracjach wewnętrznych i zagranicznych na pobyt stały pochodzą z Ministerstwa Spraw Wewnętrznych i Administracji. Prognoza ludności na podstawie badania GUS."

1.3.4.2 Informacja o kategorii w języku angielskim

subject_info("K3", lang = "en")
$id
[1] "K3"

$name
[1] "POPULATION"

$hasVariables
[1] FALSE

$children
[1] "G7"   "G8"   "G10"  "G534" "G535" "G557" "G564"

$years
 [1] 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016
[23] 2017 2018 2019 2020

$availability

$dimensions
list()

$lastUpdate
[1] "2020-05-07T08:37:43.133"

$description
[1] "Balance of size and structure of the population in gminas was prepared on the basis of the National Population Censuses including changes connected with vital statistics (births and deaths) and migration of the population (for permanent residence and for temporary stay) and changes caused by administrative changes. The data on population in localities based on PESEL register. The data on registered marriages, births and deaths based on the reports of civil status offices. The data on divorces and separations based on the reports of courts. The data on internal and international migration for permanent residence are obtained from the Ministry of the Interior and Administration. Population projection based the results of survey conducted by the Statistics Poland."
subject.ludosc <- get_subjects(parentId = "K3")

1.3.4.3 Informacja o grupie (m.in. zakres lat, grupy w kategorii itp.)

subject_info("G7")
$id
[1] "G7"

$parentId
[1] "K3"

$name
[1] "STAN LUDNOŚCI"

$hasVariables
[1] FALSE

$children
 [1] "P1336" "P1341" "P1342" "P2137" "P2425" "P2426" "P2427" "P2462" "P2463" "P2577" "P2730" "P2914" "P3361"
[14] "P3429" "P3447" "P3472" "P3813" "P3814"

$years
 [1] 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016
[23] 2017 2018 2019 2020

$availability

$dimensions
list()

$lastUpdate
[1] "2020-01-28T13:56:22.94"

$description
[1] "Dane o liczbie i strukturze ludności dla okresów międzyspisowych są sporządzane poprzez przyjęcie wyników spisu powszechnego za bazę wyjściową dla gminy, a następnie naliczanie danych metodą bilansową według następującego schematu: stan ludności na początek okresu (roku, kwartału) w gminie + urodzenia żywe - zgony + zameldowania na pobyt stały (z innych gmin i z zagranicy) - wymeldowania z pobytu stałego do innych gmin i za granicę) +(-) przesunięcia ludności z tytułu zmian administracyjnych = stan ludności na końcu okresu (roku, kwartału) w gminie. <br />Bilans ludności sporządzany jest według wyżej przedstawionej metody do roku 2009 dla dwóch kategorii przebywania ludności: 1) faktycznie zamieszkałej, 2) zameldowanej na pobyt stały. Różnicę między tymi kategoriami zamieszkania stanowi saldo (+/-) ludności zameldowanej na pobyt czasowy ponad 3 miesiące (do 2005 r. - ponad 2 miesiące). Od roku 2010 bilans ludności sporządzany jest dla jednej kategorii ludności (dawniej nazywanej \"faktycznie zamieszkałej\"). <br />Uwaga: Wyniki spisu ludności z 2002 roku wykazały liczbę ludności Polski o ok. 392 tys. mniejszą w stosunku do prowadzonych wówczas bilansów ludności. W celu zniwelowania tej różnicy dane o ludności za lata 1989-1999 zostały ponownie opracowane przy uwzględnieniu wyników spisu z 2002 roku. Szacunkiem objęto wyłącznie dane ogólnopolskie w podziale na tereny miejskie i wiejskie (według płci i grup wieku) oraz współczynniki demograficzne - dane te stały się oficjalną informacją o liczbie i strukturze ludności dla tych lat (dane dla województw i gmin nie zostały przeszacowane). Zatem, prezentowane w BDL dane (dla gmin i sumarycznie dla województw i Polski ogółem) za lata 1995-1998 oraz wg stanu na 30 VI 1999 roku - stanowiąc bilans opracowany na podstawie wyników NSP-1988 - mają znaczenie jedynie historyczne. <br />Dane o ludności stałej (według stałego miejsca zamieszkania) od 30 VI 1999 r. do 31 XII 2009 r. zostały opracowane na podstawie wyników NSP-2002 (ludność stała była wykorzystywana wyłącznie na potrzeby obliczeń wskaźników demograficznych). Od 1999 do 2009 roku (według podziału administracyjnego w dniu 31 XII) - bilans liczby i struktury ludności był opracowywany na podstawie wyników NSP-2002.<br />Od 2010 roku bazą wyjściową bilansu stanu i struktury ludności są wyniki NSP 2011. Ponieważ nie jest już opracowywany bilans ludności zameldowanej na pobyt stały, uległa zmianie metodologia liczenia wszystkich współczynników demograficznych, poszczególne fakty demograficzne i z zakresu migracji zostały odniesione do ludności (dawniej nazywanej \"faktycznie zamieszkałą\"). Dane bilansowe dla ludności stałej i faktycznej oraz współczynniki za rok 2010, których bazą wyjściową były dane NSP 2002 mają wartość jedynie historyczną i są dostępne dla zainteresowanych w <a href=\"https://bdl.stat.gov.pl/BDL/archiwum\"target=\"_blank\"/>archiwum</a>.<br /><br/>Dane bilansowe ludności za rok 2010 opracowane zostały według podziału administracyjnego obowiązującego w dniu 1 I 2011 r., jednak ze względu na specyfikę Banku Danych Lokalnych zostały przeliczone zgodnie z obowiązującym w dniu 1 I 2010 roku podziałem administracyjnym kraju (bez zmian, które nie wpływają na identyfikatory i nazwę jednostek podziału terytorialnego kraju) wynika z tego różnica w stosunku do danych publikowanych w opracowaniach GUS. Dla porównania informacja wg podziału administracyjnego obowiązującego w dniu 1 stycznia 2011 r. o pięciu gminach (wiejskich w 2010 r. i miejsko-wiejskich w 2011 r.) za rok 2010 jest dostępna  w tym zestawieniu - <a href=\"http://bdl.stat.gov.pl/bdl/doc/Ludnosc2010.xls\">pobierz plik</a>.<br/>"
subject_info("G7", lang = "en")
$id
[1] "G7"

$parentId
[1] "K3"

$name
[1] "POPULATION"

$hasVariables
[1] FALSE

$children
 [1] "P1336" "P1341" "P1342" "P2137" "P2425" "P2426" "P2427" "P2462" "P2463" "P2577" "P2730" "P2914" "P3361"
[14] "P3429" "P3447" "P3472" "P3813" "P3814"

$years
 [1] 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016
[23] 2017 2018 2019 2020

$availability

$dimensions
list()

$lastUpdate
[1] "2020-01-28T13:56:22.94"

$description
[1] "For the intercensus periods data on size and structure of population are calculated for each gmina on the basis of results of completed census; then each year data are computed by balance method according to following schema: balance of population for gmina (for the beginning of year or quarter)+live births-deaths+registration of arrival for permanent stay (from other gminas or from abroad)-registration of departure for permanent stay (from other gminas or from abroad) +(-) modification of population size caused by changes in the administrative division of a country=balance of population for gmina (for the end of year or quarter). Balance of population according to above-mentioned method is compiled until 2009 for two categories of population: 1. de facto population (population actually residing/leaving in a given administrative unit - i.e. gmina), 2. de jure population (population registered for permanent stay in a given administrative unit - i.e. gmina). Difference between these two categories of residence is made by balance (+/-) of population registered for a temporary stay for 3 months and over (until 2005 - for 2 months and over).Since 2010 the balance of population was prepared for one category (formerly called \"de facto population\").<br/>Attention. The results of Census 2002 showed the number of Polish population of about 392 thous. smaller in relation to the population balances conducted. To bridge this gap data on population data for 1989-1999 have been recalculated taking into account the results of Census 2002. Estimate covers only nationwide data broken down by urban and rural areas (by sex and age groups), and demographic indicators - such data have become the official information on the number and structure of the population for these years (data for voivodships and gminas not had been overestimated). Therefore, the data presented (for gminas and globally for voivodships and the Polish total) for the years 1995-1998 and as at June 30 1999 - acting the balance developed on the basis of Census 1988 - have only historical meaning. However data for 1999 as of June, 30 de jure population (population registered for permanent residence) - was prepared based on the results of Census 2002 (data only for calculating demographic rates). Since 1999 to 2009 by territorial units as of 31 of December - data are based on the results of Census 2002. Since 1999 to 2009 by territorial units as of 31 of December - data are based on the results of the Census 2002.<br/>Since 2010, the results of the National Population and Housing Census 2011 have been the basis for the population balance and structure. As the population balance for persons registered for permanent stay is no longer prepared, the methodology for calculating all demographic indices has been altered, particular facts related to demography and migration have been presented in relation the population (formerly called \"de facto population\"). Balance data for permanent and de facto population as well as indices for 2010 that were based on the 2002 National Census, present only historical value are available in the <a href=\"https://bdl.stat.gov.pl/BDL/archiwum\">archives</a>.<br/>The 2010 population balance data have been prepared according to the administrative division of the country as at 1 January 2011, however due to the specificity of the Local Data Bank they have been recalculated according to the administrative division of the country as at 1 January 2010 (the changes that do not affect the indices or the names of territorial division units have not been taken into account). This has resulted in a difference relative to the data published in the Statistics Poland reports. For comparison, the information on five gminas (rural in 2010 and municipal-rural in 2011) according to the administrative division of the country as at l January 2011 for year 2010 is available in this report <a href=\"http://bdl.stat.gov.pl/bdl/doc/Population2010.xls \">download file</a>.<br/>"
subject.ludosc.G7 <- get_subjects(parentId = "G7")

1.3.4.4 Informacja o podgrupie

subject_info("P2137")
$id
[1] "P2137"

$parentId
[1] "G7"

$name
[1] "Ludność wg grup wieku i płci"

$hasVariables
[1] TRUE

$children
list()

$years
 [1] 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016
[23] 2017 2018 2019

$availability

$dimensions
[1] "Wiek" "Płeć"

$lastUpdate
[1] "2019-05-22T15:25:01.16"

$description
[1] "Dane wg podziału administracyjnego na dzień 31 XII."

1.3.5 Funkcja get_variables

dane <- get_variables("P2137")
variable_info("47693")
$id
[1] 47693

$subjectId
[1] "P2137"

$n1
[1] "60-64"

$n2
[1] "kobiety"

$level
[1] 6

$measureUnitId
[1] 26

$measureUnitName
[1] "osoba"

$years
 [1] 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016
[23] 2017 2018 2019

1.3.6 Funkcja get_data_by_unit

dane.id <- dane %>% pull(id)
dane.id.zmienne <- get_data_by_unit(unitId = "062000000000", varId = dane.id)

1.3.6.1 Niekompatybilność wyników funkcji get_data_by_unit i get_variables w wersji 1.0.2 bdl

wynik <- dane.id.zmienne %>%
  left_join(dane)
Joining, by = c("id", "measureUnitId")
BŁĄD: Can't join on 'id' x 'id' because of incompatible types (integer / character)
dane.id.zmienne
dane
dane.id.zmienne %>% pull(id) %>% class
[1] "character"
dane %>% pull(id) %>% class
[1] "character"
dane.id.zmienne %>% pull(id) %>% as.factor() %>% summary
454046 454047 454048  47693  47694  47695  47696  47698  47701  47702  47706  47707  47711  47712  47715  47716 
     6      6      6     24     24     24     24     24     24     24     24     24     24     24     24     24 
 47717  47721  47722  47723  47724  47725  47726  47727  47728  47732  47734  47736  47738  47739  72238  72239 
    24     24     24     24     24     24     24     24     24     24     24     24     24     24     24     24 
 72240  72241  72242  72243  72295  72296  72297  72298  72299  72300  72301  72302  72303  72304  72305  72306 
    24     24     24     24     24     24     24     24     24     24     24     24     24     24     24     24 
 72307  72308  72309  76014  76015  76016  76017  76018  76019  76020  76021  76022  76023  76024  76025 
    24     24     24     17     17     17     17     17     17     17     17     17     17     17     17 
dane <- dane %>%
  mutate(id = as.character(id))
wynik <- dane.id.zmienne %>%
  left_join(dane)
Joining, by = c("id", "measureUnitId")
wynik <- dane.id.zmienne %>%
  left_join(dane) %>%
  select(subjectId, id, n1, n2, level, measureUnitId, measureUnitName, year, val)
Joining, by = c("id", "measureUnitId")
wynik %>% colnames
[1] "subjectId"       "id"              "n1"              "n2"              "level"           "measureUnitId"  
[7] "measureUnitName" "year"            "val"            

1.3.7 Próbne wykresy

wynik %>%
  filter(n2  == "kobiety", n1 == "60-64") %>% 
  ggplot() +
  geom_point(aes(year, val, color = n1))

wynik %>%
Komunikaty ostrzegawcze:
1: W poleceniu 'readChar(file, size, TRUE)': truncating string with embedded nuls
2: W poleceniu 'readChar(file, size, TRUE)': truncating string with embedded nuls
  filter(n2  == "kobiety", n1 == "55-59" | n1 == "65-69" | n1 == "60-64" | n1 == "70-74") %>% 
  ggplot() +
  geom_point(aes(year, val, color = n1))

1.3.8 Funkcja get_data_by_variable

info <- get_data_by_variable("47693", unitLevel = "6")
# dane.old <- get_variables("P2798")
zmienne.old  <- get_variables("P2798") %>%
  pull(id) %>%
  as.character()
pobrane_zm.old <- get_data_by_unit(unitId = "062000000000", varId = zmienne.old)

1.3.9 Funkcja line_plot

line_plot(
  data_type = "unit",
  unitId = "000000000000",
  varId = c("415", "420")
)

1.3.10 Funkcja pie_plot

pie_plot(data_type ="variable" ,"1", "2018",unitParentId="042214300000", unitLevel = "6")

1.3.11 Funkcja scatter_2var_plot

scatter_2var_plot(data_type = "variable" ,c("415", "60559"), unitLevel = "2")

1.3.12 Funkcja get_panel_data i problemy z nią

get_panel_data(unitId = "030210101000", varId =  "60270")
get_panel_data(unitId = "030210101000", varId =  c("60270", "461668"))
ab <- get_panel_data(unitId = c("030210101000", "030210105000", "030210106000"), 
               varId =  c("60270", "461668"), year = c(2013:2016))
df <- get_panel_data(unitId = c("030210101000", "030210105000", "030210106000"), 
                     varId =  c("60270", "461668"), 
                     year = c(2015:2018), ggplot = TRUE)
BŁĄD: No common type for `attributeDescription` <character> and `60270` <double>.

1.3.12.1 Jak usunąć problemy

df <- ab %>% select(-3) %>% mutate(year = as.integer(year))
df$year <- paste0(df$year, "-01-01")
df$year <- as.Date(df$year)

df <- pivot_longer(df, cols = colnames(df[, 3:ncol(df)]), 
                          names_to = "variables", values_to = "values")
ab
ggplot(df,aes(x=year, y= values, color = unit)) + 
  geom_line(aes(linetype = variables)) + 
  scale_color_discrete(labels = c("A", "B", "C")) + 
  scale_linetype_discrete(labels = c("X", "Y"))

2 R Markdow wraz biblioteką shiny

2.1 Budowa pierwszej interaktywnej aplikacji z wykorzystaniem biblioteki shiny

RStudio zakładka Files -> New Files -> Shiny Web App

Gdzie szukać wskazówek i/lub pomocy

  1. strona Rstudio
LS0tDQp0aXRsZTogIkluZm9ybWF0eWthIGVrb25vbWljem5hIC0gd3lrxYJhZCA1IChraWVydW5layBpbmZvcm1hdHlrYSBpIGVrb25vbWV0cmlhKSINCnN1YnRpdGxlOiAiQmlibGlvdGVrYSBiZGwsIGpha28gbmFyesSZZHppZSBkb3N0xJlwdSBkbyBiYXp5IGJkbCBHVVMuIDxCUj4gV3N0xJlwIGRvIHB1Ymxpa293YW5pYSB3eW5pa8OzdyB3IHNwb3PDs2IgaW50ZXJha3R5d255IC0gYmlibGlvdGVrYSBzaGlueSINCmF1dGhvcjoNCi0gSmFyb3PFgmF3IEtvdG93aWN6Og0KICAgIGNvcnJlc3BvbmRlbmNlOiBubw0KICAgIGVtYWlsOiBqLmtvdG93aWN6QHV3Yi5lZHUucGwNCiAgICBpbnN0aXR1dGU6IElJVXdCDQpkYXRlOiAiMTIgbWFqYSAyMDIwci4iDQpvdXRwdXQ6DQogIGh0bWxfbm90ZWJvb2s6DQogICAgZmlnX2NhcHRpb246IHllcw0KICAgIGhpZ2hsaWdodDogaGFkZG9jaw0KICAgIG51bWJlcl9zZWN0aW9uczogeWVzDQogICAgcGFuZG9jX2FyZ3M6DQogICAgLSAtLWx1YS1maWx0ZXI9c2Nob2xhcmx5LW1ldGFkYXRhLmx1YQ0KICAgIC0gLS1sdWEtZmlsdGVyPWF1dGhvci1pbmZvLWJsb2Nrcy5sdWENCiAgICB0aGVtZTogY2VydWxlYW4NCiAgICB0b2M6IHllcw0KaW5zdGl0dXRlOg0KLSBJSVV3QjogWmFrxYJhZCBCaW9pbmZvcm1hdHlraSwgSW5zdHl0dXQgSW5mb3JtYXR5a2ksIFVuaXdlcnN5dGV0IHcgQmlhxYJ5bXN0b2t1DQpjc2w6IGJpZy1kYXRhLWFuZC1pbmZvcm1hdGlvbi1hbmFseXRpY3MuY3NsDQphbHdheXNfYWxsb3dfaHRtbDogeWVzDQotLS0NCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpDQpgYGANCiMgQmlibGlvdGVrIGJkbCBpIGplaiBmdW5rY2plDQoNCiMjIFBvZGN6eXRhbmllIGJpYmxpb3Rla2kgKipiZGwqKiAob3JheiBiaWJsaW90ZWsgKnRpZHl2ZXJzZSopDQpgYGB7cn0NCmxpYnJhcnkoYmRsKQ0KYGBgDQoNCmBgYHtyfQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpgYGANCiMjIEN6eXN6Y3plbmllIHptaWVubnljaCB3IMWbcm9kb3dpc2t1DQpgYGB7cn0NCnJtKGxpc3QgPSBscygpKQ0KYGBgDQoNCiMjIEZ1bmtjamUgZG9zdMSZcG5lIHcgYmlibGlvdGVjZSAqYmRsKg0KDQojIyMgRnVua2NqYSAqZ2V0X2xldmVscyoNCmBgYHtyfQ0KcG96aW9teSA8LSBnZXRfbGV2ZWxzKCkNCnBvemlvbXkNCmBgYA0KIyMjIEZ1bmtjamEgKmdldF91bml0cyoNCmBgYHtyfQ0KdHJlZSA8LSBnZXRfdW5pdHMoKQ0KdHJlZSAlPiUgY29sbmFtZXMNCmBgYA0KDQpgYGB7cn0NCnRyZWUNCiMgdHJlZSAlPiUgVmlldw0KYGBgDQojIyMjIFd5YsOzciBvZHBvd2llZG5pY2ggcG96aW9tw7N3DQpgYGB7cn0NCnRyZWUgJT4lIGZpbHRlcihsZXZlbCA9PSAyKSANCiMgJT4lIFZpZXcNCmBgYA0KIyMjIyBXb2pld8OzZHp0d2EgaSBkYW5lIGRsYSBuaWNoDQpgYGB7cn0NCndvamV3b2R6dHdhIDwtIHRyZWUgJT4lIGZpbHRlcihsZXZlbCA9PSAyKQ0KYGBgDQoNCmBgYHtyfQ0KdW5pdF9pbmZvKCIwNjIwMDAwMDAwMDAiKQ0KYGBgDQojIyMjIFBvd2lhdHkNCmBgYHtyfQ0KcG93aWF0eSA8LSB0cmVlICU+JSBmaWx0ZXIobGV2ZWwgPT0gNSkNCmBgYA0KDQojIyMjIEdtaW55DQpgYGB7cn0NCmdtaW55IDwtIHRyZWUgJT4lIGZpbHRlcihsZXZlbCA9PSA2KQ0KYGBgDQoNCiMjIyMgSWRlbnR5ZmlrYXRvcnkgKCppZCopIHdvamV3w7NkenR3LCBwb3dpYXTDs3cgaSBnbWluDQpgYGB7cn0NCndvamV3b2R6dHdhLmlkIDwtIHdvamV3b2R6dHdhICU+JSBwdWxsKGlkKQ0KcG93aWF0eS5pZCA8LSBwb3dpYXR5ICU+JSBwdWxsKGlkKQ0KZ21pbnkuaWQgPC0gZ21pbnkgJT4lIHB1bGwoaWQpDQpgYGANCiMjIyBGdW5rY2phICpnZXRfc3ViamVjdCoNCiMjIyMgUG9kc3Rhd293ZSBrYXRlZ29yaWUNCmBgYHtyfQ0Kc3ViamVjdCA8LSBnZXRfc3ViamVjdHMoKQ0Kc3ViamVjdA0KYGBgDQojIyMgRnVua2NqYSAqc3ViamVjdF9pbmZvKg0KIyMjIyBJbmZvcm1hY2phIG8ga2F0ZWdvcmlpIChtLmluLiB6YWtyZXMgbGF0LCBncnVweSB3IGthdGVnb3JpaSBpdHAuKQ0KYGBge3J9DQpzdWJqZWN0X2luZm8oIkszIikNCmBgYA0KIyMjIyBJbmZvcm1hY2phIG8ga2F0ZWdvcmlpIHcgasSZenlrdSBhbmdpZWxza2ltDQpgYGB7cn0NCnN1YmplY3RfaW5mbygiSzMiLCBsYW5nID0gImVuIikNCmBgYA0KDQpgYGB7cn0NCnN1YmplY3QubHVkb3NjIDwtIGdldF9zdWJqZWN0cyhwYXJlbnRJZCA9ICJLMyIpDQpgYGANCiMjIyMgSW5mb3JtYWNqYSBvIGdydXBpZSAobS5pbi4gemFrcmVzIGxhdCwgZ3J1cHkgdyBrYXRlZ29yaWkgaXRwLikNCmBgYHtyfQ0Kc3ViamVjdF9pbmZvKCJHNyIpDQpgYGANCg0KYGBge3J9DQpzdWJqZWN0X2luZm8oIkc3IiwgbGFuZyA9ICJlbiIpDQpgYGANCg0KYGBge3J9DQpzdWJqZWN0Lmx1ZG9zYy5HNyA8LSBnZXRfc3ViamVjdHMocGFyZW50SWQgPSAiRzciKQ0KYGBgDQojIyMjIEluZm9ybWFjamEgbyBwb2RncnVwaWUNCmBgYHtyfQ0Kc3ViamVjdF9pbmZvKCJQMjEzNyIpDQpgYGANCiMjIyBGdW5rY2phICpnZXRfdmFyaWFibGVzKg0KYGBge3J9DQpkYW5lIDwtIGdldF92YXJpYWJsZXMoIlAyMTM3IikNCnZhcmlhYmxlX2luZm8oIjQ3NjkzIikNCmBgYA0KIyMjIEZ1bmtjamEgKmdldF9kYXRhX2J5X3VuaXQqDQpgYGB7cn0NCmRhbmUuaWQgPC0gZGFuZSAlPiUgcHVsbChpZCkNCmBgYA0KDQpgYGB7cn0NCmRhbmUuaWQuem1pZW5uZSA8LSBnZXRfZGF0YV9ieV91bml0KHVuaXRJZCA9ICIwNjIwMDAwMDAwMDAiLCB2YXJJZCA9IGRhbmUuaWQpDQpgYGANCg0KIyMjIyBOaWVrb21wYXR5Ymlsbm/Fm8SHIHd5bmlrw7N3IGZ1bmtjamkgKmdldF9kYXRhX2J5X3VuaXQqIGkgKmdldF92YXJpYWJsZXMqIHcgd2Vyc2ppIDEuMC4yIGJkbA0KYGBge3J9DQp3eW5payA8LSBkYW5lLmlkLnptaWVubmUgJT4lDQogIGxlZnRfam9pbihkYW5lKQ0KYGBgDQoNCmBgYHtyfQ0KZGFuZS5pZC56bWllbm5lDQpgYGANCg0KYGBge3J9DQpkYW5lDQpgYGANCg0KYGBge3J9DQpkYW5lLmlkLnptaWVubmUgJT4lIHB1bGwoaWQpICU+JSBjbGFzcw0KYGBgDQoNCmBgYHtyfQ0KZGFuZSAlPiUgcHVsbChpZCkgJT4lIGNsYXNzDQpgYGANCg0KYGBge3J9DQpkYW5lLmlkLnptaWVubmUgJT4lIHB1bGwoaWQpICU+JSBhcy5mYWN0b3IoKSAlPiUgc3VtbWFyeQ0KYGBgDQoNCmBgYHtyfQ0KZGFuZSA8LSBkYW5lICU+JQ0KICBtdXRhdGUoaWQgPSBhcy5jaGFyYWN0ZXIoaWQpKQ0KYGBgDQoNCmBgYHtyfQ0Kd3luaWsgPC0gZGFuZS5pZC56bWllbm5lICU+JQ0KICBsZWZ0X2pvaW4oZGFuZSkNCmBgYA0KDQpgYGB7cn0NCnd5bmlrIDwtIGRhbmUuaWQuem1pZW5uZSAlPiUNCiAgbGVmdF9qb2luKGRhbmUpICU+JQ0KICBzZWxlY3Qoc3ViamVjdElkLCBpZCwgbjEsIG4yLCBsZXZlbCwgbWVhc3VyZVVuaXRJZCwgbWVhc3VyZVVuaXROYW1lLCB5ZWFyLCB2YWwpDQoNCnd5bmlrICU+JSBjb2xuYW1lcw0KYGBgDQojIyMgUHLDs2JuZSB3eWtyZXN5DQoNCmBgYHtyIGZpZy5oZWlnaHQ9MTAsIGZpZy53aWR0aD0xMH0NCnd5bmlrICU+JQ0KICBmaWx0ZXIobjIgID09ICJrb2JpZXR5IiwgbjEgPT0gIjYwLTY0IikgJT4lIA0KICBnZ3Bsb3QoKSArDQogIGdlb21fcG9pbnQoYWVzKHllYXIsIHZhbCwgY29sb3IgPSBuMSkpDQpgYGANCg0KYGBge3IgZmlnLmhlaWdodD0xMCwgZmlnLndpZHRoPTEwfQ0Kd3luaWsgJT4lDQogIGZpbHRlcihuMiAgPT0gImtvYmlldHkiLCBuMSA9PSAiNTUtNTkiIHwgbjEgPT0gIjY1LTY5IiB8IG4xID09ICI2MC02NCIgfCBuMSA9PSAiNzAtNzQiKSAlPiUgDQogIGdncGxvdCgpICsNCiAgZ2VvbV9wb2ludChhZXMoeWVhciwgdmFsLCBjb2xvciA9IG4xKSkNCmBgYA0KIyMjIEZ1bmtjamEgKmdldF9kYXRhX2J5X3ZhcmlhYmxlKg0KYGBge3J9DQppbmZvIDwtIGdldF9kYXRhX2J5X3ZhcmlhYmxlKCI0NzY5MyIsIHVuaXRMZXZlbCA9ICI2IikNCmBgYA0KDQpgYGB7cn0NCiMgZGFuZS5vbGQgPC0gZ2V0X3ZhcmlhYmxlcygiUDI3OTgiKQ0Kem1pZW5uZS5vbGQgIDwtIGdldF92YXJpYWJsZXMoIlAyNzk4IikgJT4lDQogIHB1bGwoaWQpICU+JQ0KICBhcy5jaGFyYWN0ZXIoKQ0KcG9icmFuZV96bS5vbGQgPC0gZ2V0X2RhdGFfYnlfdW5pdCh1bml0SWQgPSAiMDYyMDAwMDAwMDAwIiwgdmFySWQgPSB6bWllbm5lLm9sZCkNCmBgYA0KDQojIyMgRnVua2NqYSAqbGluZV9wbG90Kg0KYGBge3IgZmlnLmhlaWdodD0xMCwgZmlnLndpZHRoPTEwfQ0KbGluZV9wbG90KA0KICBkYXRhX3R5cGUgPSAidW5pdCIsDQogIHVuaXRJZCA9ICIwMDAwMDAwMDAwMDAiLA0KICB2YXJJZCA9IGMoIjQxNSIsICI0MjAiKQ0KKQ0KYGBgDQojIyMgRnVua2NqYSAqcGllX3Bsb3QqDQoNCmBgYHtyIGZpZy5oZWlnaHQ9MTAsIGZpZy53aWR0aD0xMH0NCnBpZV9wbG90KGRhdGFfdHlwZSA9InZhcmlhYmxlIiAsIjEiLCAiMjAxOCIsdW5pdFBhcmVudElkPSIwNDIyMTQzMDAwMDAiLCB1bml0TGV2ZWwgPSAiNiIpDQpgYGANCiMjIyBGdW5rY2phICpzY2F0dGVyXzJ2YXJfcGxvdCoNCg0KYGBge3IgZmlnLmhlaWdodD0xMCwgZmlnLndpZHRoPTEwfQ0Kc2NhdHRlcl8ydmFyX3Bsb3QoZGF0YV90eXBlID0gInZhcmlhYmxlIiAsYygiNDE1IiwgIjYwNTU5IiksIHVuaXRMZXZlbCA9ICIyIikNCmBgYA0KDQojIyMgRnVua2NqYSAqZ2V0X3BhbmVsX2RhdGEqIGkgcHJvYmxlbXkgeiBuacSFDQoNCmBgYHtyfQ0KZ2V0X3BhbmVsX2RhdGEodW5pdElkID0gIjAzMDIxMDEwMTAwMCIsIHZhcklkID0gICI2MDI3MCIpDQpgYGANCg0KYGBge3J9DQpnZXRfcGFuZWxfZGF0YSh1bml0SWQgPSAiMDMwMjEwMTAxMDAwIiwgdmFySWQgPSAgYygiNjAyNzAiLCAiNDYxNjY4IikpDQpgYGANCg0KYGBge3J9DQphYiA8LSBnZXRfcGFuZWxfZGF0YSh1bml0SWQgPSBjKCIwMzAyMTAxMDEwMDAiLCAiMDMwMjEwMTA1MDAwIiwgIjAzMDIxMDEwNjAwMCIpLCANCiAgICAgICAgICAgICAgIHZhcklkID0gIGMoIjYwMjcwIiwgIjQ2MTY2OCIpLCB5ZWFyID0gYygyMDEzOjIwMTYpKQ0KYGBgDQoNCmBgYHtyfQ0KZGYgPC0gZ2V0X3BhbmVsX2RhdGEodW5pdElkID0gYygiMDMwMjEwMTAxMDAwIiwgIjAzMDIxMDEwNTAwMCIsICIwMzAyMTAxMDYwMDAiKSwgDQogICAgICAgICAgICAgICAgICAgICB2YXJJZCA9ICBjKCI2MDI3MCIsICI0NjE2NjgiKSwgDQogICAgICAgICAgICAgICAgICAgICB5ZWFyID0gYygyMDE1OjIwMTgpLCBnZ3Bsb3QgPSBUUlVFKQ0KYGBgDQojIyMjIEphayB1c3VuxIXEhyBwcm9ibGVteQ0KYGBge3J9DQpkZiA8LSBhYiAlPiUgc2VsZWN0KC0zKSAlPiUgbXV0YXRlKHllYXIgPSBhcy5pbnRlZ2VyKHllYXIpKQ0KZGYkeWVhciA8LSBwYXN0ZTAoZGYkeWVhciwgIi0wMS0wMSIpDQpkZiR5ZWFyIDwtIGFzLkRhdGUoZGYkeWVhcikNCg0KZGYgPC0gcGl2b3RfbG9uZ2VyKGRmLCBjb2xzID0gY29sbmFtZXMoZGZbLCAzOm5jb2woZGYpXSksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lc190byA9ICJ2YXJpYWJsZXMiLCB2YWx1ZXNfdG8gPSAidmFsdWVzIikNCmBgYA0KDQpgYGB7cn0NCmFiDQpgYGANCg0KYGBge3IgZmlnLmhlaWdodD0xMCwgZmlnLndpZHRoPTEwfQ0KZ2dwbG90KGRmLGFlcyh4PXllYXIsIHk9IHZhbHVlcywgY29sb3IgPSB1bml0KSkgKyANCiAgZ2VvbV9saW5lKGFlcyhsaW5ldHlwZSA9IHZhcmlhYmxlcykpICsgDQogIHNjYWxlX2NvbG9yX2Rpc2NyZXRlKGxhYmVscyA9IGMoIkEiLCAiQiIsICJDIikpICsgDQogIHNjYWxlX2xpbmV0eXBlX2Rpc2NyZXRlKGxhYmVscyA9IGMoIlgiLCAiWSIpKQ0KYGBgDQojIFIgTWFya2RvdyB3cmF6IGJpYmxpb3Rla8SFICoqc2hpbnkqKg0KDQojIyBCdWRvd2EgcGllcndzemVqIGludGVyYWt0eXduZWogYXBsaWthY2ppIHogd3lrb3J6eXN0YW5pZW0gYmlibGlvdGVraSAqc2hpbnkqDQoNClJTdHVkaW8gemFrxYJhZGthICpGaWxlcyogLT4gKk5ldyBGaWxlcyogLT4gKlNoaW55IFdlYiBBcHAqDQoNCkdkemllIHN6dWthxIcgd3NrYXrDs3dlayBpL2x1YiBwb21vY3kNCg0KMS4gW3N0cm9uYSBSc3R1ZGlvXShodHRwczovL3NoaW55LnJzdHVkaW8uY29tLykgIA0KICAtIFtzaGlueWRhc2hib2FyZF0oaHR0cDovL3JzdHVkaW8uZ2l0aHViLmlvL3NoaW55ZGFzaGJvYXJkL2dldF9zdGFydGVkLmh0bWwpDQogIC0gW1IgbWFya2Rvd24gKGtzacSFxbxrYSBSIE1hcmtkb3duOiBUaGUgRGVmaW5pdGl2ZSBHdWlkZSldKGh0dHBzOi8vYm9va2Rvd24ub3JnL3lpaHVpL3JtYXJrZG93bi8pDQogIC0gW1NoaW55IEdhbGxlcnldKGh0dHBzOi8vc2hpbnkucnN0dWRpby5jb20vZ2FsbGVyeS8pDQoNCg0KYGBge3J9DQpkZXRhY2gocGFja2FnZTpiZGwpDQoNCmRldGFjaChwYWNrYWdlOnRpZHl2ZXJzZSkNCmRldGFjaChwYWNrYWdlOmdncGxvdDIpDQpkZXRhY2gocGFja2FnZTp0aWJibGUpDQpkZXRhY2gocGFja2FnZTp0aWR5cikNCmRldGFjaChwYWNrYWdlOnJlYWRyKQ0KZGV0YWNoKHBhY2thZ2U6cHVycnIpDQpkZXRhY2gocGFja2FnZTpkcGx5cikNCmRldGFjaChwYWNrYWdlOnN0cmluZ3IpDQpkZXRhY2gocGFja2FnZTpmb3JjYXRzKQ0KDQpgYGANCg==