First steps

R as calculator

10+5 # Sum
[1] 15
10-5 # Subtraction
[1] 5
4*3  # Multiplication
[1] 12
5^2  # Powers
[1] 25
10/5 # Division
[1] 2
5%%2 # Integer division, remainder
[1] 1

Creating objects/variables

With = or with <-; the value on the right is assigned to the value on the left. - R is case sensitive (Sensible to lower and upper cases). - R does NOT require you to specify what kind of values the variables will contain.

(y = x+3)
[1] 7

Working directory

getwd returns an absolute filepath representing the current working directory of the R process; setwd(dir) is used to set the working directory to dir.

getwd() # returns an absolute filepath representing the current working directory of the R process;
[1] "C:/Users/crice/Box/TEAM-Folder/PAPERS/Mathematical Modeling and Wastewater-Based Epidemiology Public Health Applications"

Operators

# echo = F don't show code
colnames = c("ARITHMETIC","COMPARATIVE","LOGICAL")

ARITHMETIC = c("+","-","*","/","^","%%")
Description1 = c("Addition","Subtraction","Multiplication","Division","Power","Integer Div")
LOGICAL = c("==","!=","<",">","<=",">=")
Description2 = c("Equal to","Different from", "Less than", "Greater than","Less than o equal to",
                 "Greater than o equal to")
COMPARATIVE = c("&","!","","is.na(x)","is.null(x)","s.nan(x)")
Description3 = c("Logical and","Logical no","","Is NA?","Is it Null?","Is it NaN?")

table =  cbind(ARITHMETIC,Description1,LOGICAL,Description2,COMPARATIVE,Description3) #  combine by columns (or by rows with rbind)
print(data.frame(table)) # Convert to data frame
ABCDEFGHIJ0123456789
ARITHMETIC
<chr>
Description1
<chr>
LOGICAL
<chr>
Description2
<chr>
COMPARATIVE
<chr>
Description3
<chr>
+Addition==Equal to&Logical and
-Subtraction!=Different from!Logical no
*Multiplication<Less than
/Division>Greater thanis.na(x)Is NA?
^Power<=Less than o equal tois.null(x)Is it Null?
%%Integer Div>=Greater than o equal tos.nan(x)Is it NaN?
#library(DT)
#datatable(cbind(ARITHMETIC,description))
sprintf("x = %s  and X = %s",x,X) # Combine string and numeric values
[1] "x = 4  and X = 5"
x == X  # R is case sensitive
[1] FALSE
x != X
[1] TRUE
x <= X
[1] TRUE
x >= X
[1] FALSE

Vectors

# First way
X <- c(1,2,3) 
X 
[1] 1 2 3
# Second way
X <- 1:3
X
[1] 1 2 3
# Third  way
X1 = rep(1, times=3) # Repeat 1, 3 times
X1
[1] 1 1 1
vec = 1:3
X2 = rep(vec, times=5) # Repeat vec 5 times
X2
 [1] 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3
X3=rep(vec, each=3) # 
X3
[1] 1 1 1 2 2 2 3 3 3
# Other way
a <- seq(from=5, to=23, by=.5 )     #  a sequence of increase by
a
b <- seq(from=5, to=23, length=100) # a sequence of length 100
b
# Part I.- Basic objects
# Some objects: numbers, vector, matrices, data frames, array, lists
a <- 2                              # Number
b = c(4,8,0,16)                     # vector
c = 1:14                            # vector
d = matrix( 1:10, nrow=2, byrow=T ) # matrix
e = matrix( 1:10, ncol=2, byrow=F ) # matrix default by column
f = matrix( 1:10, ncol=5)
bm = matrix(b, nrow=2, byrow=T ) 
print(b)
[1]  4  8  0 16
dim(d)                # dimension of d matrix
[1] 2 5
remove(d)             # remove an object
ls()                  # lists all objects in the directory
 [1] "a"            "ARITHMETIC"   "b"            "bd"           "bm"           "c"           
 [7] "city"         "city_ww"      "colnames"     "COMPARATIVE"  "data"         "Description1"
[13] "Description2" "Description3" "e"            "f"            "greeting"     "LOGICAL"     
[19] "table"        "vec"          "x"            "X"            "X1"           "X2"          
[25] "X3"           "X4"           "X5"           "y"            "Y"           
remove(a,c)           # remove multiples objects
remove( list=ls() )   # remove all objects

a <- seq(from=5, to=23, by=.5 )     # a sequence wint increase by (o vector)
a <- seq(from=5, to=23, length=100) # a sequence of length 100
b <- rnorm(100)                     # generate random values of a normal distribution
b2 <- runif(100)                     # generate random values of a uniform distribution
hist(b)                             # to lot histograms

plot(b,b2)                          # simple plot


c <- cbind(b,b2) # matrix; vertical concatination
ct <- t(c)      # transpouse
c
                 b          b2
  [1,] -1.38088069 0.858264087
  [2,]  0.66437838 0.003903936
  [3,] -1.44192672 0.478081123
  [4,] -0.23257360 0.918456087
  [5,] -0.24671246 0.807689112
  [6,] -0.86522403 0.792330434
  [7,] -2.12005285 0.042114281
  [8,] -0.13144326 0.194970421
  [9,] -0.95537091 0.452283577
 [10,]  0.75321983 0.438737167
 [11,] -0.05489260 0.480610712
 [12,]  1.69562835 0.392007038
 [13,] -1.03830522 0.242866530
 [14,]  1.18681120 0.099108091
 [15,]  1.21178054 0.516976763
 [16,] -1.74898496 0.065540741
 [17,] -0.65038649 0.636335618
 [18,] -0.58804841 0.232607744
 [19,] -0.55933220 0.203854955
 [20,]  0.19256130 0.090373779
 [21,] -1.79065718 0.751115266
 [22,]  0.15805978 0.361704670
 [23,] -1.45530133 0.692347908
 [24,] -0.37164945 0.248734678
 [25,] -0.11791927 0.596868856
 [26,] -0.02536543 0.809549505
 [27,]  0.34387281 0.381528180
 [28,] -0.77575216 0.634686878
 [29,]  0.86905691 0.030431538
 [30,]  0.38581730 0.193273982
 [31,] -0.37279603 0.378746056
 [32,]  0.44998849 0.578904315
 [33,] -0.59157222 0.012211904
 [34,] -1.50530259 0.407359428
 [35,]  1.04699247 0.964360910
 [36,]  0.12685366 0.216363109
 [37,] -1.11519377 0.147212892
 [38,]  0.10811769 0.932043133
 [39,] -1.26673735 0.115032387
 [40,] -0.50714586 0.999853693
 [41,] -0.91868951 0.810800158
 [42,] -0.29731871 0.178087981
 [43,]  1.15975757 0.842401248
 [44,] -0.26018242 0.071121373
 [45,]  0.52578631 0.163020681
 [46,]  0.24438166 0.710500215
 [47,]  0.20889924 0.026670772
 [48,] -1.93744720 0.169773897
 [49,] -0.00695318 0.209948316
 [50,] -0.71452340 0.034671564
 [51,]  0.57562852 0.612801080
 [52,] -1.23572577 0.623946457
 [53,] -0.08100244 0.703801848
 [54,] -0.09862191 0.540504236
 [55,]  1.13933497 0.245369178
 [56,] -0.06682206 0.546186707
 [57,] -0.63028029 0.711188254
 [58,] -0.44492628 0.899419523
 [59,] -1.28421527 0.889601162
 [60,] -0.07741493 0.841342199
 [61,]  0.31113744 0.199085864
 [62,]  0.40124242 0.295827813
 [63,]  0.62060369 0.385276034
 [64,]  0.13618069 0.503965177
 [65,]  0.40326074 0.567528928
 [66,]  0.12652018 0.972277519
 [67,] -0.65713783 0.300787880
 [68,] -0.33685661 0.615531536
 [69,]  1.44036035 0.273717905
 [70,]  0.46136827 0.123578306
 [71,] -0.22996401 0.814653691
 [72,] -1.76062685 0.038490191
 [73,]  1.04426533 0.059043459
 [74,]  0.98493336 0.452822033
 [75,] -0.19937291 0.296500278
 [76,] -2.19153774 0.178488104
 [77,]  0.05498726 0.260125093
 [78,] -0.80456289 0.488688321
 [79,]  0.65374188 0.868612124
 [80,]  2.55209448 0.208544536
 [81,] -0.25933383 0.215808191
 [82,]  1.23347332 0.485450778
 [83,] -1.11345021 0.309516371
 [84,]  0.08112593 0.727236132
 [85,] -0.69672677 0.473619435
 [86,]  0.60107763 0.842930949
 [87,] -0.73421813 0.244173994
 [88,]  2.08255031 0.848972967
 [89,] -1.04482047 0.998221477
 [90,]  0.75542726 0.419006828
 [91,]  0.21755891 0.060381147
 [92,]  0.72899249 0.527818844
 [93,] -0.28522888 0.128960422
 [94,]  0.79269156 0.963665575
 [95,] -0.19227968 0.955944677
 [96,]  2.90598740 0.115874609
 [97,]  0.91663557 0.041463981
 [98,]  1.28927133 0.471626976
 [99,] -0.42781231 0.622513014
[100,]  0.35225873 0.151627695
ct
         [,1]        [,2]       [,3]       [,4]       [,5]       [,6]        [,7]       [,8]       [,9]
b  -1.3808807 0.664378379 -1.4419267 -0.2325736 -0.2467125 -0.8652240 -2.12005285 -0.1314433 -0.9553709
b2  0.8582641 0.003903936  0.4780811  0.9184561  0.8076891  0.7923304  0.04211428  0.1949704  0.4522836
       [,10]      [,11]    [,12]      [,13]      [,14]     [,15]       [,16]      [,17]      [,18]
b  0.7532198 -0.0548926 1.695628 -1.0383052 1.18681120 1.2117805 -1.74898496 -0.6503865 -0.5880484
b2 0.4387372  0.4806107 0.392007  0.2428665 0.09910809 0.5169768  0.06554074  0.6363356  0.2326077
        [,19]      [,20]      [,21]     [,22]      [,23]      [,24]      [,25]       [,26]     [,27]
b  -0.5593322 0.19256130 -1.7906572 0.1580598 -1.4553013 -0.3716494 -0.1179193 -0.02536543 0.3438728
b2  0.2038550 0.09037378  0.7511153 0.3617047  0.6923479  0.2487347  0.5968689  0.80954950 0.3815282
        [,28]      [,29]     [,30]      [,31]     [,32]      [,33]      [,34]     [,35]     [,36]
b  -0.7757522 0.86905691 0.3858173 -0.3727960 0.4499885 -0.5915722 -1.5053026 1.0469925 0.1268537
b2  0.6346869 0.03043154 0.1932740  0.3787461 0.5789043  0.0122119  0.4073594 0.9643609 0.2163631
        [,37]     [,38]      [,39]      [,40]      [,41]      [,42]     [,43]       [,44]     [,45]
b  -1.1151938 0.1081177 -1.2667373 -0.5071459 -0.9186895 -0.2973187 1.1597576 -0.26018242 0.5257863
b2  0.1472129 0.9320431  0.1150324  0.9998537  0.8108002  0.1780880 0.8424012  0.07112137 0.1630207
       [,46]      [,47]      [,48]       [,49]       [,50]     [,51]      [,52]       [,53]       [,54]
b  0.2443817 0.20889924 -1.9374472 -0.00695318 -0.71452340 0.5756285 -1.2357258 -0.08100244 -0.09862191
b2 0.7105002 0.02667077  0.1697739  0.20994832  0.03467156 0.6128011  0.6239465  0.70380185  0.54050424
       [,55]       [,56]      [,57]      [,58]      [,59]       [,60]     [,61]     [,62]     [,63]
b  1.1393350 -0.06682206 -0.6302803 -0.4449263 -1.2842153 -0.07741493 0.3111374 0.4012424 0.6206037
b2 0.2453692  0.54618671  0.7111883  0.8994195  0.8896012  0.84134220 0.1990859 0.2958278 0.3852760
       [,64]     [,65]     [,66]      [,67]      [,68]     [,69]     [,70]      [,71]       [,72]
b  0.1361807 0.4032607 0.1265202 -0.6571378 -0.3368566 1.4403603 0.4613683 -0.2299640 -1.76062685
b2 0.5039652 0.5675289 0.9722775  0.3007879  0.6155315 0.2737179 0.1235783  0.8146537  0.03849019
        [,73]     [,74]      [,75]      [,76]      [,77]      [,78]     [,79]     [,80]      [,81]
b  1.04426533 0.9849334 -0.1993729 -2.1915377 0.05498726 -0.8045629 0.6537419 2.5520945 -0.2593338
b2 0.05904346 0.4528220  0.2965003  0.1784881 0.26012509  0.4886883 0.8686121 0.2085445  0.2158082
       [,82]      [,83]      [,84]      [,85]     [,86]      [,87]    [,88]      [,89]     [,90]
b  1.2334733 -1.1134502 0.08112593 -0.6967268 0.6010776 -0.7342181 2.082550 -1.0448205 0.7554273
b2 0.4854508  0.3095164 0.72723613  0.4736194 0.8429309  0.2441740 0.848973  0.9982215 0.4190068
        [,91]     [,92]      [,93]     [,94]      [,95]     [,96]      [,97]    [,98]      [,99]
b  0.21755891 0.7289925 -0.2852289 0.7926916 -0.1922797 2.9059874 0.91663557 1.289271 -0.4278123
b2 0.06038115 0.5278188  0.1289604 0.9636656  0.9559447 0.1158746 0.04146398 0.471627  0.6225130
      [,100]
b  0.3522587
b2 0.1516277
d <- rbind(a,b) # matrix; horizontal concatination


rownames(e) <- NULL # para poner nombre a renglones y cols de una matriz
Error in rownames(e) <- NULL : object 'e' not found

Packages installation

if (!require("dplyr")) install.packages("dplyr") # To install a package if is not unstalled
library(openxlsx) # on package
library(dplyr,here) # multiples packages

dplyr

dplyr is a grammar of data manipulation, providing a consistent set of verbs that help you solve the most common data manipulation challenges:

  • Rows:
    • filter() chooses rows based on column values.
    • slice() chooses rows based on location.
    • arrange() changes the ordering of the rows. arrange() changes the order of the rows.
  • Columns:
    • select() changes whether or not a column is included.
    • rename() changes the name of columns.
    • mutate() changes the values of columns and creates new columns.
    • relocate() changes the order of the columns.

-Groups of rows: -summarise() reduces multiple values down to a single summary; collapses a group into a single row.

city = "Davis"
#### Load data ####
#data <- read.csv(here("data/data_ww_cases.csv")) 
data <- read.csv("data/data_ww_cases.csv")

unique(data$City)
head(data,10)
tail(city_ww,5)

city_ww = data %>% filter(City == city & SampleDate >= "2021-07-02" & SampleDate <= "2022-06-01")
city_ww = city_ww %>% select(SampleDate,N_gene, PMMoV,Testing,positives_crude)
head(city_ww)
city_ww = city_ww %>% rename(Positives = positives_crude)

city_ww = data %>% filter(City == city)%>% #& SampleDate >= date_ini & SampleDate <= date_end)
  select(SampleDate,N_gene, PMMoV,Testing,positives_crude)%>%
  rename(Positives = positives_crude)

city_ww = city_ww %>% mutate(PR = 100*Positives/Testing)

city_ww = city_ww %>% mutate(Positives = ifelse(is.na(Testing),NA,Positives))
head(city_ww)

write.csv(city_ww,"data/ww_cases.csv",row.names = F) # To save the data
LS0tDQp0aXRsZTogSW50cm9kdWN0aW9uIHRvIFIgIzxicj4gQW5hbHl0aWNzICsgVmlzdWFsaXphdGlvbnMgPC9wPiA8L2NlbnRlcj4NCmF1dGhvcjogJ0NyaXMgYW5kIE1hcnknDQpkYXRlOiAiTGFzdCB1cGRhdGU6IEZlYiAxMCwgMjAyMyINCm5hbWU6ICIiDQpvdXRwdXQ6DQogIGh0bWxfbm90ZWJvb2s6IGRlZmF1bHQNCiAgcGRmX2RvY3VtZW50OiBkZWZhdWx0DQpmb250c2l6ZTogMTJwdA0KZ2VvbWV0cnk6IG1hcmdpbj0xaW4NCi0tLQ0KDQojIEZpcnN0IHN0ZXBzDQojIyBSIGFzIGNhbGN1bGF0b3INCmBgYHtyfQ0KMTArNSAjIFN1bQ0KMTAtNSAjIFN1YnRyYWN0aW9uDQo0KjMgICMgTXVsdGlwbGljYXRpb24NCjVeMiAgIyBQb3dlcnMNCjEwLzUgIyBEaXZpc2lvbg0KNSUlMiAjIEludGVnZXIgZGl2aXNpb24sIHJlbWFpbmRlcg0KYGBgDQojIENyZWF0aW5nIG9iamVjdHMvdmFyaWFibGVzDQpXaXRoID0gb3Igd2l0aCA8LTsgdGhlIHZhbHVlIG9uIHRoZSByaWdodCBpcyBhc3NpZ25lZCB0byB0aGUgdmFsdWUgb24gdGhlIGxlZnQuIA0KLSBSIGlzIGNhc2Ugc2Vuc2l0aXZlIChTZW5zaWJsZSB0byBsb3dlciBhbmQgdXBwZXIgY2FzZXMpLg0KLSBSIGRvZXMgTk9UIHJlcXVpcmUgeW91IHRvIHNwZWNpZnkgd2hhdCBraW5kIG9mIHZhbHVlcyB0aGUgdmFyaWFibGVzIHdpbGwgY29udGFpbi4NCmBgYHtyfQ0KWCA8LSA1ICMgRXF1YWwgdG8gWCA9IDUgDQooeCA9IDMpICN3aXRoIHRoZSBicmFja2V0cywgdGhlIHJlc3VsdCBpcyBwcmludGVkLg0KeSA9IHgrMw0KeQ0KKGdyZWV0aW5nID0gIkhlbGxvIHdvcmxkIikgIyB0ZXh0IHN0cmluZ3MNCmBgYA0KIyBXb3JraW5nIGRpcmVjdG9yeQ0KZ2V0d2QgcmV0dXJucyBhbiBhYnNvbHV0ZSBmaWxlcGF0aCByZXByZXNlbnRpbmcgdGhlIGN1cnJlbnQgd29ya2luZyBkaXJlY3Rvcnkgb2YgdGhlIFIgcHJvY2Vzczsgc2V0d2QoZGlyKSBpcyB1c2VkIHRvIHNldCB0aGUgd29ya2luZyBkaXJlY3RvcnkgdG8gZGlyLg0KDQpgYGB7cn0NCmdldHdkKCkgIyByZXR1cm5zIGFuIGFic29sdXRlIGZpbGVwYXRoIHJlcHJlc2VudGluZyB0aGUgY3VycmVudCB3b3JraW5nIGRpcmVjdG9yeSBvZiB0aGUgUiBwcm9jZXNzOw0Kc2V0d2QoIkM6L1VzZXJzL2NyaWNlL0JveC9URUFNLUZvbGRlci9QQVBFUlMvTWF0aGVtYXRpY2FsIE1vZGVsaW5nIGFuZCBXYXN0ZXdhdGVyLUJhc2VkIEVwaWRlbWlvbG9neSBQdWJsaWMgSGVhbHRoIEFwcGxpY2F0aW9ucyIpDQoNCmBgYA0KIyMgT3BlcmF0b3JzDQpgYGB7ciBlY2hvPVQsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQojIGVjaG8gPSBGIGRvbid0IHNob3cgY29kZQ0KY29sbmFtZXMgPSBjKCJBUklUSE1FVElDIiwiQ09NUEFSQVRJVkUiLCJMT0dJQ0FMIikNCg0KQVJJVEhNRVRJQyA9IGMoIisiLCItIiwiKiIsIi8iLCJeIiwiJSUiKQ0KRGVzY3JpcHRpb24xID0gYygiQWRkaXRpb24iLCJTdWJ0cmFjdGlvbiIsIk11bHRpcGxpY2F0aW9uIiwiRGl2aXNpb24iLCJQb3dlciIsIkludGVnZXIgRGl2IikNCkxPR0lDQUwgPSBjKCI9PSIsIiE9IiwiPCIsIj4iLCI8PSIsIj49IikNCkRlc2NyaXB0aW9uMiA9IGMoIkVxdWFsIHRvIiwiRGlmZmVyZW50IGZyb20iLCAiTGVzcyB0aGFuIiwgIkdyZWF0ZXIgdGhhbiIsIkxlc3MgdGhhbiBvIGVxdWFsIHRvIiwNCiAgICAgICAgICAgICAgICAgIkdyZWF0ZXIgdGhhbiBvIGVxdWFsIHRvIikNCkNPTVBBUkFUSVZFID0gYygiJiIsIiEiLCIiLCJpcy5uYSh4KSIsImlzLm51bGwoeCkiLCJzLm5hbih4KSIpDQpEZXNjcmlwdGlvbjMgPSBjKCJMb2dpY2FsIGFuZCIsIkxvZ2ljYWwgbm8iLCIiLCJJcyBOQT8iLCJJcyBpdCBOdWxsPyIsIklzIGl0IE5hTj8iKQ0KDQp0YWJsZSA9ICBjYmluZChBUklUSE1FVElDLERlc2NyaXB0aW9uMSxMT0dJQ0FMLERlc2NyaXB0aW9uMixDT01QQVJBVElWRSxEZXNjcmlwdGlvbjMpICMgIGNvbWJpbmUgYnkgY29sdW1ucyAob3IgYnkgcm93cyB3aXRoIHJiaW5kKQ0KcHJpbnQoZGF0YS5mcmFtZSh0YWJsZSkpICMgQ29udmVydCB0byBkYXRhIGZyYW1lDQojbGlicmFyeShEVCkNCiNkYXRhdGFibGUoY2JpbmQoQVJJVEhNRVRJQyxkZXNjcmlwdGlvbikpDQpgYGANCmBgYHtyIGVjaG89VCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0NCnNwcmludGYoInggPSAlcyAgYW5kIFggPSAlcyIseCxYKSAjIENvbWJpbmUgc3RyaW5nIGFuZCBudW1lcmljIHZhbHVlcw0KeCA9PSBYICAjIFIgaXMgY2FzZSBzZW5zaXRpdmUNCnggIT0gWA0KeCA8PSBYDQp4ID49IFgNCmBgYA0KIyBWZWN0b3JzDQpgYGB7cn0NCiMgRmlyc3Qgd2F5DQpYIDwtIGMoMSwyLDMpIA0KWCANCmBgYA0KDQpgYGB7cn0NCiMgU2Vjb25kIHdheQ0KWCA8LSAxOjMNClgNCmBgYA0KDQpgYGB7cn0NCiMgVGhpcmQgIHdheQ0KWDEgPSByZXAoMSwgdGltZXM9MykgIyBSZXBlYXQgMSwgMyB0aW1lcw0KWDENCnZlYyA9IDE6Mw0KWDIgPSByZXAodmVjLCB0aW1lcz01KSAjIFJlcGVhdCB2ZWMgNSB0aW1lcw0KWDINClgzPXJlcCh2ZWMsIGVhY2g9MykgIyANClgzDQpgYGANCmBgYHtyfQ0KIyBPdGhlciB3YXkNCmEgPC0gc2VxKGZyb209NSwgdG89MjMsIGJ5PS41ICkgICAgICMgIGEgc2VxdWVuY2Ugb2YgaW5jcmVhc2UgYnkNCmENCmIgPC0gc2VxKGZyb209NSwgdG89MjMsIGxlbmd0aD0xMDApICMgYSBzZXF1ZW5jZSBvZiBsZW5ndGggMTAwDQpiDQpgYGANCg0KYGBge3J9DQojIFBhcnQgSS4tIEJhc2ljIG9iamVjdHMNCiMgU29tZSBvYmplY3RzOiBudW1iZXJzLCB2ZWN0b3IsIG1hdHJpY2VzLCBkYXRhIGZyYW1lcywgYXJyYXksIGxpc3RzDQphIDwtIDIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIE51bWJlcg0KYiA9IGMoNCw4LDAsMTYpICAgICAgICAgICAgICAgICAgICAgIyB2ZWN0b3INCmMgPSAxOjE0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICMgdmVjdG9yDQpkID0gbWF0cml4KCAxOjEwLCBucm93PTIsIGJ5cm93PVQgKSAjIG1hdHJpeA0KZSA9IG1hdHJpeCggMToxMCwgbmNvbD0yLCBieXJvdz1GICkgIyBtYXRyaXggZGVmYXVsdCBieSBjb2x1bW4NCmYgPSBtYXRyaXgoIDE6MTAsIG5jb2w9NSkNCmJtID0gbWF0cml4KGIsIG5yb3c9MiwgYnlyb3c9VCApIA0KcHJpbnQoYikNCg0KZGltKGQpICAgICAgICAgICAgICAgICMgZGltZW5zaW9uIG9mIGQgbWF0cml4DQpyZW1vdmUoZCkgICAgICAgICAgICAgIyByZW1vdmUgYW4gb2JqZWN0DQpscygpICAgICAgICAgICAgICAgICAgIyBsaXN0cyBhbGwgb2JqZWN0cyBpbiB0aGUgZGlyZWN0b3J5DQpyZW1vdmUoYSxjKSAgICAgICAgICAgIyByZW1vdmUgbXVsdGlwbGVzIG9iamVjdHMNCnJlbW92ZSggbGlzdD1scygpICkgICAjIHJlbW92ZSBhbGwgb2JqZWN0cw0KDQphIDwtIHNlcShmcm9tPTUsIHRvPTIzLCBieT0uNSApICAgICAjIGEgc2VxdWVuY2Ugd2ludCBpbmNyZWFzZSBieSAobyB2ZWN0b3IpDQphIDwtIHNlcShmcm9tPTUsIHRvPTIzLCBsZW5ndGg9MTAwKSAjIGEgc2VxdWVuY2Ugb2YgbGVuZ3RoIDEwMA0KYiA8LSBybm9ybSgxMDApICAgICAgICAgICAgICAgICAgICAgIyBnZW5lcmF0ZSByYW5kb20gdmFsdWVzIG9mIGEgbm9ybWFsIGRpc3RyaWJ1dGlvbg0KYjIgPC0gcnVuaWYoMTAwKSAgICAgICAgICAgICAgICAgICAgICMgZ2VuZXJhdGUgcmFuZG9tIHZhbHVlcyBvZiBhIHVuaWZvcm0gZGlzdHJpYnV0aW9uDQpoaXN0KGIpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAjIHRvIGxvdCBoaXN0b2dyYW1zDQpwbG90KGIsYjIpICAgICAgICAgICAgICAgICAgICAgICAgICAjIHNpbXBsZSBwbG90DQoNCmMgPC0gY2JpbmQoYixiMikgIyBtYXRyaXg7IHZlcnRpY2FsIGNvbmNhdGluYXRpb24NCmN0IDwtIHQoYykgICAgICAjIHRyYW5zcG91c2UNCmMNCmN0DQpkIDwtIHJiaW5kKGEsYikgIyBtYXRyaXg7IGhvcml6b250YWwgY29uY2F0aW5hdGlvbg0KDQoNCnJvd25hbWVzKGUpIDwtIE5VTEwgIyBwYXJhIHBvbmVyIG5vbWJyZSBhIHJlbmdsb25lcyB5IGNvbHMgZGUgdW5hIG1hdHJpeg0KY29sbmFtZXMoYykgPC0gYygibm9tMSIsIm5vbTIiKQ0KDQpyb3duYW1lcyhlKSA8LSBwYXN0ZSgib2JzIiwxOm5jLCBzZXA9IiIpDQpkaW1uYW1lcyhlKSA8LSBsaXN0KCBwYXN0ZSgib2JzIiwxOm5jLCBzZXA9IiIpLGMoIm5vbTEiLCJub20yIiwibm9tMyIsIm5vbTQiKSkNCg0KZiA8LSBsZXR0ZXJzWzE6bmNdICAgICAgIyB2ZWN0b3Igb2YgY2FyYWN0ZXJzDQpnIDwtIExFVFRFUlNbMTpuY10NCmggPC0gZGF0YS5mcmFtZShlLGYsZykgICMgZGF0YSBmcmFtZQ0KZGltKGgpDQpuYW1lcyhoKSA8LSBjKCJ2YXIxIiwidmFyMiIsInZhcjMiLCJ2YXI0IiwidmFyNSIsInZhcjYiKQ0KaA0KcmVtb3ZlKGgpDQoNCiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjDQojIyMjIyMjIyMjIyBBbGd1bm9zIHJlc3VtZW5lcyBudW1lcmljb3MgIyMjIyMjIyMjIyMjIyMjIyMjIyMjIw0KIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMNCmFhIDwtICAxOjIwIA0Kc3VtbWFyeShhYSkgICAgICAgICAgICAgICAgICAgIyBudW1lcmljIHN1bW1hcnkNCm1pbihhYSkgICAgICAgICAgICAgICAgICAgICAgICMgbWluaW11bg0KbWVhbihhYSkgICAgICAgICAgICAgICAgICAgICAgIyAgbWVhbg0KbWVkaWFuKGFhKSAgICAgICAgICAgICAgICAgICAgIyAgbWVkaWFuDQptYXgoYWEpICAgICAgICAgICAgICAgICAgICAgICAjIG1heGltdW0NCnJhbmdlKGFhKSAgICAgICAgICAgICAgICAgICAgICMgcmFuZ2U6IG1pbiBhbmQgbWF4DQpzZChhYSkgICAgICAgICAgICAgICAgICAgICAgICAjIHN0YW5kYXIgZGVzdmlhdGlvbg0KcXVhbnRpbGUoYWEscHJvYnM9YyguMjUsLjUsLjc1KSkgIyBxdWFudGlsZXMNCnZhcihhYSkgICAgICAgICAgICAgICAgICAgICAgICMgdmFyaWFuY2UNCnN1bSgoYWEtbWVhbihhYSkpXjIgKS8obGVuZ3RoKGFhKS0xKSAjIGFub3RoZXIgd2F5IHRvIGNvbXB1dGUgdGhlIHZhcmlhbmNlLCBtYW51YWxseQ0KIyANCiMgc3VtKGFhKS9sZW5ndGgoYWEpICMgbWVhbg0KIyANCiMgIyBsaXN0YXMNCiMgYmIgPC0gbGlzdCggc3VtYXJpbz1zdW1tYXJ5KGFhKSwgbWVkaWE9bWVhbihhYSksDQojICAgICAgICAgICAgIGxldHJhcz1sZXR0ZXJzWzg6MTVdLCBiYXN1cmE9cnVuaWYoMjAwKSApDQojIGJiJGxldHJhcyAgICAjIGNvbW8gYWNjZWRlciBhIGxvcyBlbGVtZW50b3MgZGUgbGlzdGENCiMgYmJbWzNdXSAgICAgICMgbywgZXF1aXZhbGVudGVtZW50ZQ0KIyANCiMgZCA9IDQNCiMgZF4yDQojIA0KIyBwcm9tZWRpbyA9IGZ1bmN0aW9uKGRhdG9zKXsNCiMgICBzdW1hID0gMA0KIyAgIGZvcihpIGluIGRhdG9zKQ0KIyAgIHsNCiMgICAgIHN1bWEgPSBzdW1hICsgaQ0KIyAgIH0NCiMgICBwcm9tID0gc3VtYS9sZW5ndGgoZGF0b3MpIA0KIyAgIHJldHVybihwcm9tKQ0KIyB9DQojIHByb21lZGlvKGFhKQ0KIyANCiMgDQojIHZhcmlhbnphID0gMA0KIyBmb3IgKGkgaW4gYWEpew0KIyAgIHJlc3RhID0gKGkgLSBwcm9tZWRpbyleMiAvIChsZW5ndGgoYWEpLTEpDQojICAgdmFyaWFuemEgPSB2YXJpYW56YSArIHJlc3RhDQojIH0NCiMgdmFyaWFuemENCiMgdmFyKGFhKQ0KIyANCiMgDQojICN3cml0ZS50YWJsZShhYSwiRGF0b3MudHh0IikNCiMgI3dyaXRlLmNzdihhYSwgZmlsZSA9ICJmb28uY3N2IikNCiMgI2RhdCA9IHJlYWQudGFibGUoIkRhdG9zLnR4dCIpDQojIHNldC5zZWVkKDExMSkNCmBgYA0KDQoNCiMgUGFja2FnZXMgaW5zdGFsbGF0aW9uIA0KDQotIEZvciBvZmZpY2lhbCBDUkFOIHBhY2thZ2VzDQogIC0gaW5zdGFsbC5wYWNrYWdlcygicGFja2FnZV9uYW1lIikgDQogIC0gbGlicmFyeShwYWNrYWdlX25hbWUpICNQYXJhIHVzYXIgZWwgcGFxdWV0ZQ0KDQotIEZvciBHaXRIdWIgcGFja2FnZXMgDQogIC0gaW5zdGFsbC5wYWNrYWdlcygiZGV2dG9vbHMiKSAjIFJ1biBvbmx5IGlmIHlvdSBkbyBub3QgaGF2ZSB0aGUgImRldnRvb2xzIiBwYWNrYWdlIGluc3RhbGxlZC4NCiAgLSBkZXZ0b29sczo6aW5zdGFsbF9naXRodWIoInVzZXIvcmVwb3NpdG9yeSIpDQoNCmBgYHtyfQ0KaWYgKCFyZXF1aXJlKCJkcGx5ciIpKSBpbnN0YWxsLnBhY2thZ2VzKCJkcGx5ciIpICMgVG8gaW5zdGFsbCBhIHBhY2thZ2UgaWYgaXMgbm90IHVuc3RhbGxlZA0KbGlicmFyeShvcGVueGxzeCkgIyBvbiBwYWNrYWdlDQpsaWJyYXJ5KGRwbHlyLGhlcmUpICMgbXVsdGlwbGVzIHBhY2thZ2VzDQpgYGANCg0KIyMgZHBseXINCmRwbHlyIGlzIGEgZ3JhbW1hciBvZiBkYXRhIG1hbmlwdWxhdGlvbiwgcHJvdmlkaW5nIGEgY29uc2lzdGVudCBzZXQgb2YgdmVyYnMgdGhhdCBoZWxwIHlvdSBzb2x2ZSB0aGUgbW9zdCBjb21tb24gZGF0YSBtYW5pcHVsYXRpb24gY2hhbGxlbmdlczoNCg0KLSBSb3dzOg0KICAtIGZpbHRlcigpIGNob29zZXMgcm93cyBiYXNlZCBvbiBjb2x1bW4gdmFsdWVzLg0KICAtIHNsaWNlKCkgY2hvb3NlcyByb3dzIGJhc2VkIG9uIGxvY2F0aW9uLg0KICAtIGFycmFuZ2UoKSBjaGFuZ2VzIHRoZSBvcmRlcmluZyBvZiB0aGUgcm93cy4NCmFycmFuZ2UoKSBjaGFuZ2VzIHRoZSBvcmRlciBvZiB0aGUgcm93cy4NCg0KLSBDb2x1bW5zOg0KICAtIHNlbGVjdCgpIGNoYW5nZXMgd2hldGhlciBvciBub3QgYSBjb2x1bW4gaXMgaW5jbHVkZWQuDQogIC0gcmVuYW1lKCkgY2hhbmdlcyB0aGUgbmFtZSBvZiBjb2x1bW5zLg0KICAtIG11dGF0ZSgpIGNoYW5nZXMgdGhlIHZhbHVlcyBvZiBjb2x1bW5zIGFuZCBjcmVhdGVzIG5ldyBjb2x1bW5zLg0KICAtIHJlbG9jYXRlKCkgY2hhbmdlcyB0aGUgb3JkZXIgb2YgdGhlIGNvbHVtbnMuDQoNCi1Hcm91cHMgb2Ygcm93czoNCiAgLXN1bW1hcmlzZSgpIHJlZHVjZXMgbXVsdGlwbGUgdmFsdWVzIGRvd24gdG8gYSBzaW5nbGUgc3VtbWFyeTsgY29sbGFwc2VzIGEgZ3JvdXAgaW50byBhIHNpbmdsZSByb3cuDQpgYGB7cn0NCmNpdHkgPSAiRGF2aXMiDQojIyMjIExvYWQgZGF0YSAjIyMjDQojZGF0YSA8LSByZWFkLmNzdihoZXJlKCJkYXRhL2RhdGFfd3dfY2FzZXMuY3N2IikpIA0KZGF0YSA8LSByZWFkLmNzdigiZGF0YS9kYXRhX3d3X2Nhc2VzLmNzdiIpDQoNCnVuaXF1ZShkYXRhJENpdHkpDQpoZWFkKGRhdGEsMTApDQp0YWlsKGNpdHlfd3csNSkNCg0KY2l0eV93dyA9IGRhdGEgJT4lIGZpbHRlcihDaXR5ID09IGNpdHkgJiBTYW1wbGVEYXRlID49ICIyMDIxLTA3LTAyIiAmIFNhbXBsZURhdGUgPD0gIjIwMjItMDYtMDEiKQ0KY2l0eV93dyA9IGNpdHlfd3cgJT4lIHNlbGVjdChTYW1wbGVEYXRlLE5fZ2VuZSwgUE1Nb1YsVGVzdGluZyxwb3NpdGl2ZXNfY3J1ZGUpDQpoZWFkKGNpdHlfd3cpDQpjaXR5X3d3ID0gY2l0eV93dyAlPiUgcmVuYW1lKFBvc2l0aXZlcyA9IHBvc2l0aXZlc19jcnVkZSkNCg0KY2l0eV93dyA9IGRhdGEgJT4lIGZpbHRlcihDaXR5ID09IGNpdHkpJT4lICMmIFNhbXBsZURhdGUgPj0gZGF0ZV9pbmkgJiBTYW1wbGVEYXRlIDw9IGRhdGVfZW5kKQ0KICBzZWxlY3QoU2FtcGxlRGF0ZSxOX2dlbmUsIFBNTW9WLFRlc3RpbmcscG9zaXRpdmVzX2NydWRlKSU+JQ0KICByZW5hbWUoUG9zaXRpdmVzID0gcG9zaXRpdmVzX2NydWRlKQ0KDQpjaXR5X3d3ID0gY2l0eV93dyAlPiUgbXV0YXRlKFBSID0gMTAwKlBvc2l0aXZlcy9UZXN0aW5nKQ0KDQpjaXR5X3d3ID0gY2l0eV93dyAlPiUgbXV0YXRlKFBvc2l0aXZlcyA9IGlmZWxzZShpcy5uYShUZXN0aW5nKSxOQSxQb3NpdGl2ZXMpKQ0KaGVhZChjaXR5X3d3KQ0KDQp3cml0ZS5jc3YoY2l0eV93dywiZGF0YS93d19jYXNlcy5jc3YiLHJvdy5uYW1lcyA9IEYpICMgVG8gc2F2ZSB0aGUgZGF0YQ0KYGBg