1 Exploration

1.1 Database import

  • Import of database LandWorm_dataset_site_V1.9.xlsx version V1.9 (february 22, 2024)
chemin_fichier_excel = "C:/Users/diall/Downloads/datas/LandWorm_dataset_site_V1.9.xlsx"
bdd <- read.xlsx(chemin_fichier_excel, sheet = "Sheet1")
  • The database contains 8019 rows and 481 columns

1.2 Porgrame

bdd$Programme=as.factor(bdd$Programme)
sort(levels(bdd$Programme))
##  [1] "#Vers2022"             "AF"                    "AF-SMART-SO"          
##  [4] "AgrHys"                "AgrInnov"              "AGRIVAIR-VITTEL"      
##  [7] "Beaujolais-SICAREX"    "BFF-Brami"             "BFF-Brami-Bioferme"   
## [10] "Bio1"                  "BIO2"                  "Bio2_ANDRA"           
## [13] "biobio"                "BioGeoSTIB"            "Breizh Sukr"          
## [16] "CA 45"                 "CA_41"                 "CA_45"                
## [19] "CAPAMIN"               "CEREMA"                "Cerema / ARB"         
## [22] "CN"                    "DATASOL"               "Dephy"                
## [25] "Dephy Bio"             "DIAMS"                 "DYNABIO"              
## [28] "ECLAS"                 "ECO_IMPACT"            "GARGAMEL"             
## [31] "HOP!"                  "INPN"                  "JASSUR"               
## [34] "Kerguéhennec"          "LaCage"                "Life-PTD"             
## [37] "Macon-Davayé"          "MONS"                  "OASYS"                
## [40] "OBL"                   "Optim'yst"             "OPVT"                 
## [43] "OPVT_BZH"              "OPVT_IDF"              "Orchamp"              
## [46] "PSDR"                  "RESACOR"               "RESCAPE"              
## [49] "REVA"                  "RMQS"                  "RMQS_BioDiv"          
## [52] "SBT-ENI-M"             "SBT-ENI-TB"            "SHR"                  
## [55] "SOERE-ACBB-Lusignan"   "SOERE-ACBB-Theix"      "SOERE-PRO-EFELE-PROs" 
## [58] "SOERE-PRO-EFELE-TS-MO" "SOERE PRO"             "SOFIA"                
## [61] "SoilMan-Farm Network"  "SOLIVITI"              "Sols de Bretagne"     
## [64] "SUSTAIN reseau"        "thèse MH"              "thèse NC"             
## [67] "TIGA"                  "TRAMBIOSOIL"           "TSE"                  
## [70] "Vadebio"               "VADEBIO"               "VADETOX-Biotechnosol" 
## [73] "VIFLORHUM"             "VineDivers"            "VitiEcobioSol-CIBC"   
## [76] "VITTEL - AGRIVAIR"     "ZAA"                   "ZAA_HR"
levels(bdd$Programme)[levels(bdd$Programme) == "CA 45"] <- "CA_45"

1.3 Focus on years

  • Cleaning the Annee column: parfois années + jours et ou + mois
bdd$Annee= as.factor(bdd$Annee)
levels(bdd$Annee)
##   [1] "1821"       "1960"       "1978"       "1982"       "1983"      
##   [6] "1984"       "1986"       "1988"       "1989"       "1990"      
##  [11] "1991"       "1992"       "1993"       "1994"       "1995"      
##  [16] "1996"       "1997"       "1998"       "1999"       "2000"      
##  [21] "2001"       "2002"       "2003"       "2003_04"    "2004"      
##  [26] "2005"       "2005_05"    "2006"       "2006_04"    "2007"      
##  [31] "2007_04"    "2008"       "2008_05"    "2009"       "2009_04"   
##  [36] "2010"       "2010_03"    "2010_04"    "2011"       "2011_03"   
##  [41] "2011_05"    "2011_10"    "2011_11"    "2012"       "2012_03"   
##  [46] "2012_04"    "2012_11"    "2013"       "2013_03"    "2013_04"   
##  [51] "2013_11"    "2014"       "2014_03"    "2014_04"    "2014_10"   
##  [56] "2015"       "2015_11"    "2016"       "2016_03"    "2016_04"   
##  [61] "2017"       "2017.04"    "2017.11"    "2018"       "2018.03"   
##  [66] "2018.04"    "2019"       "2019.03"    "2019.04"    "2019/10"   
##  [71] "2020"       "2020-11-27" "2020-12-11" "2020_02"    "2021"      
##  [76] "2021-01-14" "2021-03-02" "2021-03-17" "2021-03-30" "2021-04-14"
##  [81] "2021-05-06" "2021-05-11" "2021-05-26" "2021-06-08" "2021-06-22"
##  [86] "2021-06-23" "2021-07-27" "2021-09-09" "2021-10-14" "2021-10-30"
##  [91] "2021-11-04" "2021-11-23" "2021-11-25" "2021-11-29" "2021-12-09"
##  [96] "2021-12-14" "2021.03"    "2021.04"    "2021_03"    "2021_04"   
## [101] "2021_10"    "2022"       "2022-01-11" "2022-01-25" "2022-01-26"
## [106] "2022-02-08" "2022-02-22" "2022-03-22" "2022_02"    "2022_03"   
## [111] "2022_09"    "2022_10"    "2023"       "2023_03"
  • Pour le moment, je prend a chaque fois les 4 chiffre de l’année
bdd$Annee <- gsub("^(\\d{4}).*$", "\\1", bdd$Annee) # on prend uniquement les 04 premier chiffre
bdd$Annee= as.factor(bdd$Annee)

1.4 Date de prevelment

# bdd$Date_Prelevement

filtre_date <- subset(bdd, !is.na(Date_Prelevement) & !grepl("^\\d{2}/\\d{2}/\\d{4}$", Date_Prelevement))$Date_Prelevement

filtre_date[c(1,5,10,79,101,112,195,240,243,454,473,475,485,627,655,680)]
##  [1] "2022-04-19"                                        
##  [2] "42818"                                             
##  [3] "lundi 9 mars 2020"                                 
##  [4] "2020-10-26"                                        
##  [5] "18/03/15"                                          
##  [6] "43889"                                             
##  [7] "29/032021"                                         
##  [8] "23/02/2021 (bloc 1 à 4)\n24/02/2021 ( bloc 5 et 6)"
##  [9] "08/03/2021\n09/03/2021"                            
## [10] "2020-02-06"                                        
## [11] "?"                                                 
## [12] "2019"                                              
## [13] "2021-03-01"                                        
## [14] "13 et 15/04/2015"                                  
## [15] "2021-04-06"                                        
## [16] "2022-03-25"

1.5 Focus on clcm_lvl1

bdd$clcm_lvl1= as.factor(bdd$clcm_lvl1)
summary_df <- as.data.frame(summary(bdd$clcm_lvl1))
colnames(summary_df) <- c("Numbers")
kable(summary_df,padding = 5)
Numbers
1_Naturel 1
2_Agricole 3
Agricultural areas 4939
Artificial surfaces 956
Forest and semi natural areas 587
Wetlands 37
NA’s 1496
  • Merging levels
levels(bdd$clcm_lvl1)[levels(bdd$clcm_lvl1) == "1_Naturel"] <- "Forest and semi natural areas"
levels(bdd$clcm_lvl1)[levels(bdd$clcm_lvl1) == "2_Agricole"] <- "Agricultural areas"

bdd$clcm_lvl1= as.factor(bdd$clcm_lvl1)
summary_df <- as.data.frame(summary(bdd$clcm_lvl1))
colnames(summary_df) <- c("Numbers")
kable(summary_df,padding = 5)
Numbers
Forest and semi natural areas 588
Agricultural areas 4942
Artificial surfaces 956
Wetlands 37
NA’s 1496
  • Update code_clcm_lvl1
bdd$code_clcm_lvl1 <- ifelse(bdd$clcm_lvl1 == "Forest and semi natural areas", 3, bdd$code_clcm_lvl1)

bdd$code_clcm_lvl1 <- ifelse(bdd$clcm_lvl1 == "Agricultural areas", 2, bdd$code_clcm_lvl1)

1.6 Focus on clcm_lvl2

bdd$clcm_lvl2= as.factor(bdd$clcm_lvl2)
summary_df <- as.data.frame(summary(bdd$clcm_lvl2))
colnames(summary_df) <- c("Numbers")
kable(summary_df,padding = 8)
Numbers
21_Agricole ouvert 3
Arable land 2915
Artificial, non-agricultural vegetated areas 750
Forests 273
Heterogeneous agricultural areas 223
Industrial, commercial and transport units 181
Inland wetlands 37
Mine, dump and construction sites 25
Open spaces with little or no vegetation 9
Pastures 729
Permanent crops 1072
Scrub and/or herbaceous vegetation associations 305
NA’s 1497
  • Merging levels
levels(bdd$clcm_lvl2)[levels(bdd$clcm_lvl2) == "21_Agricole ouvert"] <- "Arable land"

bdd$clcm_lvl2= as.factor(bdd$clcm_lvl2)
summary_df <- as.data.frame(summary(bdd$clcm_lvl2))
colnames(summary_df) <- c("Numbers")
kable(summary_df,padding = 5)
Numbers
Arable land 2918
Artificial, non-agricultural vegetated areas 750
Forests 273
Heterogeneous agricultural areas 223
Industrial, commercial and transport units 181
Inland wetlands 37
Mine, dump and construction sites 25
Open spaces with little or no vegetation 9
Pastures 729
Permanent crops 1072
Scrub and/or herbaceous vegetation associations 305
NA’s 1497
  • Update code_clcm_lvl2
bdd$code_clcm_lvl2 <- ifelse(bdd$clcm_lvl2 == "Arable land", 21, bdd$code_clcm_lvl2)

1.7 Focus on clcm_lvl3

bdd$clcm_lvl3= as.factor(bdd$clcm_lvl3)
summary_df <- as.data.frame(summary(bdd$clcm_lvl3))
colnames(summary_df) <- c("Numbers")
kable(summary_df,padding = 5)
Numbers
Agro-forestry areas 117
Airports 44
Beaches, dunes, sands 1
Broad-leaved forest 29
Complex cultivation patterns 88
Coniferous forest 4
Construction sites 21
Fruit trees and berry plantations 18
Green urban areas 676
Humid zone 1
Indetermined forest 2
Industrial or commercial units and public facilities 12
Mixed forest 88
Moors and heathland 13
Natural grasslands 144
Non-irrigated arable land 2840
Other arable land 72
Other artificial, non-agricultural vegetated areas 13
Other heterogeneous agricultural areas 18
Other mine, dump and construction sites 4
Other scrub and/or herbaceous vegetation associations 8
Pastures, meadows and other permanent grasslands under agricultural use 521
Road and rail networks and associated land 124
Sport and leisure facilities 59
Transitional woodland-shrub 14
Vineyards 1044
NA’s 2044

1.8 Focus on protocols

  • List of protocols available on the database
bdd$Protocole = as.factor(bdd$Protocole)
summary_df <- as.data.frame(summary(bdd$Protocole))
colnames(summary_df) <- c("Numbers")
kable(summary_df,padding = 5)
Numbers
AITC_HS 231
AITCTM 227
F 51
F_HS 970
FHS 46
hand sorting 357
HS 3281
HS_16 216
HS_4 396
HS_biodiv 32
HS_biodiv? 2
HS_F_16 24
HS_M_16 151
HS_M_25 29
HSAITC_16 1
HSAITC_4 123
HSAITC_6.25 56
HSAITC_7.95775385 10
M 1238
M_HS 70
Unknown 320
visual_hunting 188
  • Merging levels :

    • HS \(=\) HS \(+\) hand sorting
    levels(bdd$Protocole)[levels(bdd$Protocole) == "hand sorting"] <- "HS"
    bdd$Protocole = as.factor(bdd$Protocole)
    summary_df <- as.data.frame(summary(bdd$Protocole))
    colnames(summary_df) <- c("Numbers")
    #kable(summary_df,padding = 5)

1.9 Total abundance

summary(bdd$AB_tot) 
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
##    0.00   22.67   96.00  173.28  250.00 2875.00     320
#bdd <- subset(bdd, AB_tot <= 800)
par(mfrow=c(1,2))

# Boxplot
  boxplot(bdd$AB_tot, col = 'blue', ylab = "Total abundance")
  # Cleveland plot
  dotchart(bdd$AB_tot, pch = 16, col = 'blue', xlab = "Total abundance")

Quelques parcelles ont des valeurs un peu douteux

1.10 Total biomass

summary(bdd$BM_tot) 
##     Min.  1st Qu.   Median     Mean  3rd Qu.     Max.     NA's 
##     0.00    16.97    53.81    90.89   107.13 19962.47     4282
#bdd <- subset(bdd, AB_tot <= 800)
par(mfrow=c(1,2))

# Boxplot
  boxplot(bdd$BM_tot, col = 'blue', ylab = "Total biomass")
  # Cleveland plot
  dotchart(bdd$BM_tot, pch = 16, col = 'blue', xlab = "Total biomass")

Quelques parcelles ont des valeurs un peu douteux

1.11 sand

bdd$sand=as.numeric(bdd$sand)
summary(bdd$sand) 
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
##    0.15   13.90   22.77   29.45   42.80   96.20    6001
#bdd <- subset(bdd, AB_tot <= 800)
par(mfrow=c(1,2))

# Boxplot
  boxplot(bdd$sand, col = 'blue', ylab = "sand")
  # Cleveland plot
  dotchart(bdd$sand, pch = 16, col = 'blue', xlab = "sand")

1.12 clay

bdd$clay=as.numeric(bdd$clay)
summary(bdd$clay) 
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
##    0.02   19.10   82.00  139.07  224.75  667.00    3469
#bdd <- subset(bdd, AB_tot <= 800)
par(mfrow=c(1,2))

# Boxplot
  boxplot(bdd$clay, col = 'blue', ylab = "clay")
  # Cleveland plot
  dotchart(bdd$clay, pch = 16, col = 'blue', xlab = "clay")

A verifier ?, beaucoup de valeur sont superieur a 100

1.13 silt

bdd$silt=as.numeric(bdd$silt)
summary(bdd$silt) 
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
##    0.05   30.15   42.60   44.23   59.00   81.20    6001
#bdd <- subset(bdd, AB_tot <= 800)
par(mfrow=c(1,2))

# Boxplot
  boxplot(bdd$silt, col = 'blue', ylab = "silt")
  # Cleveland plot
  dotchart(bdd$silt, pch = 16, col = 'blue', xlab = "silt")

1.14 pH

  • Hors chiffre
# les valeurs de la colonne ph_eau qui ne sont pas des chiffres ou supérieures à 14

valeurs_bizarres <- subset(bdd, !(grepl("^\\d*\\.?\\d+$", ph_eau) | as.numeric(ph_eau) > 14 & is.na(ph_eau)))$ph_eau
valeurs_bizarres
##  [1] ">8"             ">9"             "Entre 5 et 6"   "Entre 6 et 7"  
##  [5] "Entre 6 et 7"   "de 6 à 6,9"     "de 6 à 6,9"     "de 6 à 6,9"    
##  [9] "je ne sais pas" "je ne sais pas" "Entre 6 et 7"   "entre 5 et 6"  
## [13] "<5"             "je ne sais pas" "je ne sais pas" "5 à 5,9"       
## [17] "DE 7 A 7,9"     "DE 5 A 5,9"     "DE 6 A 6,9"
df_comp=bdd
df_comp <- df_comp[!grepl("[^0-9.]", df_comp$ph_eau), ]
df_comp$ph_eau <- as.numeric(df_comp$ph_eau)

Il y a 19 parcelles qui ont des pH qui ne sont pas des chiffre. Dans mon cas, j’ai enlever ces 19 lignes.

  • Valeurs superieur a 14
summary(as.numeric(bdd$ph_eau))
##     Min.  1st Qu.   Median     Mean  3rd Qu.     Max.     NA's 
##     2.09     6.50     7.60    18.35     8.11 44140.00     4042
df_comp = df_comp[!df_comp$ph_eau== 44140.00,]

Une parcelle est à \(44140.00\).

par(mfrow=c(1,2))

# Boxplot
  boxplot(df_comp$ph_eau, col = 'blue', ylab = "ph_eau")
  # Cleveland plot
  dotchart(df_comp$ph_eau, pch = 16, col = 'blue', xlab = "ph_eau")

1.15 C_tot

summary(as.numeric(bdd$c_tot))
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
##    0.00   12.60   23.06   34.30   51.26  162.04    7148
#plot(as.numeric(bdd$c_tot))
par(mfrow=c(1,2))

# Boxplot
  boxplot(as.numeric(bdd$c_tot), col = 'blue', ylab = "c_tot")
  # Cleveland plot
  dotchart(as.numeric(bdd$c_tot), pch = 16, col = 'blue', xlab = "c_tot")

Valeurs superieurs à 100 ?, unités ?,…

1.16 C_org

summary(as.numeric(bdd$c_org))
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
##   0.520   9.553  14.300  18.220  23.632 156.200    4659
#plot(as.numeric(bdd$c_org))
par(mfrow=c(1,2))

# Boxplot
  boxplot(as.numeric(bdd$c_org), col = 'blue', ylab = "c_org")
  # Cleveland plot
  dotchart(as.numeric(bdd$c_org), pch = 16, col = 'blue', xlab = "c_org")

Valeurs superieurs à 100 ?, unités ?,…

1.17 om

summary(as.numeric(bdd$om))
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
##    0.00   16.14   24.65   33.36   40.26  631.00    4132
#plot(as.numeric(bdd$om))
par(mfrow=c(1,2))

# Boxplot
  boxplot(as.numeric(bdd$om), col = 'blue', ylab = "om")
  # Cleveland plot
  dotchart(as.numeric(bdd$om), pch = 16, col = 'blue', xlab = "om")

Valeurs superieurs à 100 ?, unités ?,…

1.18 ID

# Check des doublons
duplicated_rows <- subset(bdd, duplicated(bdd[, c("ID", "AB_tot", "BM_tot")]) | duplicated(bdd[, c("ID", "AB_tot", "BM_tot")], fromLast = TRUE))
LS0tDQp0aXRsZTogJ0NoZWNrIEJERCBMYW5kV29ybSBWMS45Jw0KYXV0aG9yOiAiQWJkb3VyYWhtYW5lIERpYWxsbyINCmRhdGU6ICIyMDI0LTIyLTAyIg0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIGNvZGVfZG93bmxvYWQ6IHllcw0KICAgIHRvYzogeWVzDQogICAgdG9jX2Zsb2F0OiB5ZXMNCiAgICBjb2RlX2ZvbGQ6IGhpZGUNCiAgICB3YXJuaW5nOiBubw0KICAgIG1lc3NhZ2U6IG5vDQogICAgdGhlbWU6IHVuaXRlZA0KICAgIG51bWJlcl9zZWN0aW9uczogeWVzDQogICAgc2VjX251bWJlcl9zdWZmaXg6ICcuICAgJw0KICAgIGNhY2hlOiB0cnVlDQogIHBkZl9kb2N1bWVudDoNCiAgICB0b2M6IHllcw0KLS0tDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFLCB3YXJuaW5nID0gRkFMU0UsIG1lc3NhZ2UgPSBGQUxTRSwNCiAgICAgICAgICAgICAgICAgICAgICBmaWcuYWxpZ249J2NlbnRlcicsZmlnLmhlaWdodD00KQ0Kcm0obGlzdD1scyhhbGw9VFJVRSkpICAjIFJlc2V0IHRoZSB3b3JraW5nIGVudmlyb25tZW50DQpsaWJyYXJ5KG9wZW54bHN4KQ0KbGlicmFyeShyZWFkeGwpDQpsaWJyYXJ5KGtuaXRyKQ0KYGBgDQoNCg0KIyBFeHBsb3JhdGlvbg0KDQojIyBEYXRhYmFzZSBpbXBvcnQNCg0KLSAgIEltcG9ydCBvZiBkYXRhYmFzZSAqKkxhbmRXb3JtX2RhdGFzZXRfc2l0ZV9WMS45Lnhsc3gqKiB2ZXJzaW9uICoqVjEuOSoqIChmZWJydWFyeSAyMiwgMjAyNCkNCg0KYGBge3IsZWNobz1UUlVFfQ0KY2hlbWluX2ZpY2hpZXJfZXhjZWwgPSAiQzovVXNlcnMvZGlhbGwvRG93bmxvYWRzL2RhdGFzL0xhbmRXb3JtX2RhdGFzZXRfc2l0ZV9WMS45Lnhsc3giDQpiZGQgPC0gcmVhZC54bHN4KGNoZW1pbl9maWNoaWVyX2V4Y2VsLCBzaGVldCA9ICJTaGVldDEiKQ0KYGBgDQoNCi0gICBUaGUgZGF0YWJhc2UgY29udGFpbnMgKipgciBucm93KGJkZClgKiogcm93cyBhbmQgKipgciBuY29sKGJkZClgKiogY29sdW1ucw0KDQoNCiMjIFBvcmdyYW1lDQoNCmBgYHtyLGVjaG89VFJVRX0NCmJkZCRQcm9ncmFtbWU9YXMuZmFjdG9yKGJkZCRQcm9ncmFtbWUpDQpzb3J0KGxldmVscyhiZGQkUHJvZ3JhbW1lKSkNCmxldmVscyhiZGQkUHJvZ3JhbW1lKVtsZXZlbHMoYmRkJFByb2dyYW1tZSkgPT0gIkNBIDQ1Il0gPC0gIkNBXzQ1Ig0KYGBgDQoNCiMjIEZvY3VzIG9uIHllYXJzDQoNCi0gICBDbGVhbmluZyB0aGUgQW5uZWUgY29sdW1uOiBwYXJmb2lzIGFubsOpZXMgKyBqb3VycyBldCBvdSArIG1vaXMNCg0KYGBge3IgLCBlY2hvPVRSVUV9DQpiZGQkQW5uZWU9IGFzLmZhY3RvcihiZGQkQW5uZWUpDQpsZXZlbHMoYmRkJEFubmVlKQ0KYGBgDQotICAgUG91ciBsZSBtb21lbnQsIGplIHByZW5kIGEgY2hhcXVlIGZvaXMgbGVzIDQgY2hpZmZyZSBkZSBsJ2FubsOpZQ0KYGBge3J9DQpiZGQkQW5uZWUgPC0gZ3N1YigiXihcXGR7NH0pLiokIiwgIlxcMSIsIGJkZCRBbm5lZSkgIyBvbiBwcmVuZCB1bmlxdWVtZW50IGxlcyAwNCBwcmVtaWVyIGNoaWZmcmUNCmJkZCRBbm5lZT0gYXMuZmFjdG9yKGJkZCRBbm5lZSkNCmBgYA0KDQoNCg0KDQoNCiMjIERhdGUgZGUgcHJldmVsbWVudA0KDQpgYGB7cn0NCiMgYmRkJERhdGVfUHJlbGV2ZW1lbnQNCg0KZmlsdHJlX2RhdGUgPC0gc3Vic2V0KGJkZCwgIWlzLm5hKERhdGVfUHJlbGV2ZW1lbnQpICYgIWdyZXBsKCJeXFxkezJ9L1xcZHsyfS9cXGR7NH0kIiwgRGF0ZV9QcmVsZXZlbWVudCkpJERhdGVfUHJlbGV2ZW1lbnQNCg0KZmlsdHJlX2RhdGVbYygxLDUsMTAsNzksMTAxLDExMiwxOTUsMjQwLDI0Myw0NTQsNDczLDQ3NSw0ODUsNjI3LDY1NSw2ODApXQ0KDQpgYGANCg0KIyMgRm9jdXMgb24gY2xjbV9sdmwxDQoNCg0KYGBge3IsIGVjaG89VFJVRX0NCmJkZCRjbGNtX2x2bDE9IGFzLmZhY3RvcihiZGQkY2xjbV9sdmwxKQ0Kc3VtbWFyeV9kZiA8LSBhcy5kYXRhLmZyYW1lKHN1bW1hcnkoYmRkJGNsY21fbHZsMSkpDQpjb2xuYW1lcyhzdW1tYXJ5X2RmKSA8LSBjKCJOdW1iZXJzIikNCmthYmxlKHN1bW1hcnlfZGYscGFkZGluZyA9IDUpDQpgYGANCg0KLSAgIE1lcmdpbmcgbGV2ZWxzDQpgYGB7ciwgZWNobz1UUlVFfQ0KbGV2ZWxzKGJkZCRjbGNtX2x2bDEpW2xldmVscyhiZGQkY2xjbV9sdmwxKSA9PSAiMV9OYXR1cmVsIl0gPC0gIkZvcmVzdCBhbmQgc2VtaSBuYXR1cmFsIGFyZWFzIg0KbGV2ZWxzKGJkZCRjbGNtX2x2bDEpW2xldmVscyhiZGQkY2xjbV9sdmwxKSA9PSAiMl9BZ3JpY29sZSJdIDwtICJBZ3JpY3VsdHVyYWwgYXJlYXMiDQoNCmJkZCRjbGNtX2x2bDE9IGFzLmZhY3RvcihiZGQkY2xjbV9sdmwxKQ0Kc3VtbWFyeV9kZiA8LSBhcy5kYXRhLmZyYW1lKHN1bW1hcnkoYmRkJGNsY21fbHZsMSkpDQpjb2xuYW1lcyhzdW1tYXJ5X2RmKSA8LSBjKCJOdW1iZXJzIikNCmthYmxlKHN1bW1hcnlfZGYscGFkZGluZyA9IDUpDQpgYGANCg0KLSAgIFVwZGF0ZSAqKmNvZGVfY2xjbV9sdmwxKioNCmBgYHtyfQ0KYmRkJGNvZGVfY2xjbV9sdmwxIDwtIGlmZWxzZShiZGQkY2xjbV9sdmwxID09ICJGb3Jlc3QgYW5kIHNlbWkgbmF0dXJhbCBhcmVhcyIsIDMsIGJkZCRjb2RlX2NsY21fbHZsMSkNCg0KYmRkJGNvZGVfY2xjbV9sdmwxIDwtIGlmZWxzZShiZGQkY2xjbV9sdmwxID09ICJBZ3JpY3VsdHVyYWwgYXJlYXMiLCAyLCBiZGQkY29kZV9jbGNtX2x2bDEpDQpgYGANCg0KDQoNCg0KDQojIyBGb2N1cyBvbiBjbGNtX2x2bDINCg0KDQpgYGB7ciwgZWNobz1UUlVFfQ0KYmRkJGNsY21fbHZsMj0gYXMuZmFjdG9yKGJkZCRjbGNtX2x2bDIpDQpzdW1tYXJ5X2RmIDwtIGFzLmRhdGEuZnJhbWUoc3VtbWFyeShiZGQkY2xjbV9sdmwyKSkNCmNvbG5hbWVzKHN1bW1hcnlfZGYpIDwtIGMoIk51bWJlcnMiKQ0Ka2FibGUoc3VtbWFyeV9kZixwYWRkaW5nID0gOCkNCmBgYA0KDQotICAgTWVyZ2luZyBsZXZlbHMNCmBgYHtyLCBlY2hvPVRSVUV9DQpsZXZlbHMoYmRkJGNsY21fbHZsMilbbGV2ZWxzKGJkZCRjbGNtX2x2bDIpID09ICIyMV9BZ3JpY29sZSBvdXZlcnQiXSA8LSAiQXJhYmxlIGxhbmQiDQoNCmJkZCRjbGNtX2x2bDI9IGFzLmZhY3RvcihiZGQkY2xjbV9sdmwyKQ0Kc3VtbWFyeV9kZiA8LSBhcy5kYXRhLmZyYW1lKHN1bW1hcnkoYmRkJGNsY21fbHZsMikpDQpjb2xuYW1lcyhzdW1tYXJ5X2RmKSA8LSBjKCJOdW1iZXJzIikNCmthYmxlKHN1bW1hcnlfZGYscGFkZGluZyA9IDUpDQpgYGANCg0KLSAgIFVwZGF0ZSAqKmNvZGVfY2xjbV9sdmwyKioNCmBgYHtyfQ0KDQpiZGQkY29kZV9jbGNtX2x2bDIgPC0gaWZlbHNlKGJkZCRjbGNtX2x2bDIgPT0gIkFyYWJsZSBsYW5kIiwgMjEsIGJkZCRjb2RlX2NsY21fbHZsMikNCg0KYGBgDQoNCg0KDQoNCiMjIEZvY3VzIG9uIGNsY21fbHZsMw0KDQoNCmBgYHtyLCBlY2hvPVRSVUUsIHNjcm9sbGFibGUgPSBUUlVFfQ0KYmRkJGNsY21fbHZsMz0gYXMuZmFjdG9yKGJkZCRjbGNtX2x2bDMpDQpzdW1tYXJ5X2RmIDwtIGFzLmRhdGEuZnJhbWUoc3VtbWFyeShiZGQkY2xjbV9sdmwzKSkNCmNvbG5hbWVzKHN1bW1hcnlfZGYpIDwtIGMoIk51bWJlcnMiKQ0Ka2FibGUoc3VtbWFyeV9kZixwYWRkaW5nID0gNSkNCg0KYGBgDQoNCg0KDQojIyBGb2N1cyBvbiBwcm90b2NvbHMNCg0KLSAgIExpc3Qgb2YgcHJvdG9jb2xzIGF2YWlsYWJsZSBvbiB0aGUgZGF0YWJhc2UNCg0KYGBge3IsZWNobz1UUlVFfQ0KYmRkJFByb3RvY29sZSA9IGFzLmZhY3RvcihiZGQkUHJvdG9jb2xlKQ0Kc3VtbWFyeV9kZiA8LSBhcy5kYXRhLmZyYW1lKHN1bW1hcnkoYmRkJFByb3RvY29sZSkpDQpjb2xuYW1lcyhzdW1tYXJ5X2RmKSA8LSBjKCJOdW1iZXJzIikNCmthYmxlKHN1bW1hcnlfZGYscGFkZGluZyA9IDUpDQpgYGANCg0KLSAgICoqTWVyZ2luZyBsZXZlbHMqKiA6DQoNCiAgICAtICAgSFMgJD0kIEhTICQrJCBoYW5kIHNvcnRpbmcNCg0KICAgIGBgYHtyLGVjaG89VFJVRSwgcmVzdWx0PSdoaWRlJ30NCiAgICBsZXZlbHMoYmRkJFByb3RvY29sZSlbbGV2ZWxzKGJkZCRQcm90b2NvbGUpID09ICJoYW5kIHNvcnRpbmciXSA8LSAiSFMiDQogICAgYmRkJFByb3RvY29sZSA9IGFzLmZhY3RvcihiZGQkUHJvdG9jb2xlKQ0KICAgIHN1bW1hcnlfZGYgPC0gYXMuZGF0YS5mcmFtZShzdW1tYXJ5KGJkZCRQcm90b2NvbGUpKQ0KICAgIGNvbG5hbWVzKHN1bW1hcnlfZGYpIDwtIGMoIk51bWJlcnMiKQ0KICAgICNrYWJsZShzdW1tYXJ5X2RmLHBhZGRpbmcgPSA1KQ0KICAgIGBgYA0KDQoNCiMjIFRvdGFsIGFidW5kYW5jZQ0KDQpgYGB7cix9DQpzdW1tYXJ5KGJkZCRBQl90b3QpIA0KI2JkZCA8LSBzdWJzZXQoYmRkLCBBQl90b3QgPD0gODAwKQ0KcGFyKG1mcm93PWMoMSwyKSkNCg0KIyBCb3hwbG90DQogIGJveHBsb3QoYmRkJEFCX3RvdCwgY29sID0gJ2JsdWUnLCB5bGFiID0gIlRvdGFsIGFidW5kYW5jZSIpDQogICMgQ2xldmVsYW5kIHBsb3QNCiAgZG90Y2hhcnQoYmRkJEFCX3RvdCwgcGNoID0gMTYsIGNvbCA9ICdibHVlJywgeGxhYiA9ICJUb3RhbCBhYnVuZGFuY2UiKQ0KDQpgYGANCioqUXVlbHF1ZXMgcGFyY2VsbGVzIG9udCBkZXMgdmFsZXVycyB1biBwZXUgZG91dGV1eCoqDQoNCiMjIFRvdGFsIGJpb21hc3MNCg0KYGBge3J9DQpzdW1tYXJ5KGJkZCRCTV90b3QpIA0KI2JkZCA8LSBzdWJzZXQoYmRkLCBBQl90b3QgPD0gODAwKQ0KcGFyKG1mcm93PWMoMSwyKSkNCg0KIyBCb3hwbG90DQogIGJveHBsb3QoYmRkJEJNX3RvdCwgY29sID0gJ2JsdWUnLCB5bGFiID0gIlRvdGFsIGJpb21hc3MiKQ0KICAjIENsZXZlbGFuZCBwbG90DQogIGRvdGNoYXJ0KGJkZCRCTV90b3QsIHBjaCA9IDE2LCBjb2wgPSAnYmx1ZScsIHhsYWIgPSAiVG90YWwgYmlvbWFzcyIpDQoNCmBgYA0KKipRdWVscXVlcyBwYXJjZWxsZXMgb250IGRlcyB2YWxldXJzIHVuIHBldSBkb3V0ZXV4KioNCg0KDQojIyBzYW5kDQoNCmBgYHtyfQ0KYmRkJHNhbmQ9YXMubnVtZXJpYyhiZGQkc2FuZCkNCnN1bW1hcnkoYmRkJHNhbmQpIA0KI2JkZCA8LSBzdWJzZXQoYmRkLCBBQl90b3QgPD0gODAwKQ0KcGFyKG1mcm93PWMoMSwyKSkNCg0KIyBCb3hwbG90DQogIGJveHBsb3QoYmRkJHNhbmQsIGNvbCA9ICdibHVlJywgeWxhYiA9ICJzYW5kIikNCiAgIyBDbGV2ZWxhbmQgcGxvdA0KICBkb3RjaGFydChiZGQkc2FuZCwgcGNoID0gMTYsIGNvbCA9ICdibHVlJywgeGxhYiA9ICJzYW5kIikNCg0KYGBgDQoNCiMjIGNsYXkNCg0KYGBge3J9DQpiZGQkY2xheT1hcy5udW1lcmljKGJkZCRjbGF5KQ0Kc3VtbWFyeShiZGQkY2xheSkgDQojYmRkIDwtIHN1YnNldChiZGQsIEFCX3RvdCA8PSA4MDApDQpwYXIobWZyb3c9YygxLDIpKQ0KDQojIEJveHBsb3QNCiAgYm94cGxvdChiZGQkY2xheSwgY29sID0gJ2JsdWUnLCB5bGFiID0gImNsYXkiKQ0KICAjIENsZXZlbGFuZCBwbG90DQogIGRvdGNoYXJ0KGJkZCRjbGF5LCBwY2ggPSAxNiwgY29sID0gJ2JsdWUnLCB4bGFiID0gImNsYXkiKQ0KDQpgYGANCioqQSB2ZXJpZmllciA/LCBiZWF1Y291cCBkZSB2YWxldXIgc29udCBzdXBlcmlldXIgYSAxMDAgKioNCg0KIyMgc2lsdA0KDQpgYGB7cn0NCmJkZCRzaWx0PWFzLm51bWVyaWMoYmRkJHNpbHQpDQpzdW1tYXJ5KGJkZCRzaWx0KSANCiNiZGQgPC0gc3Vic2V0KGJkZCwgQUJfdG90IDw9IDgwMCkNCnBhcihtZnJvdz1jKDEsMikpDQoNCiMgQm94cGxvdA0KICBib3hwbG90KGJkZCRzaWx0LCBjb2wgPSAnYmx1ZScsIHlsYWIgPSAic2lsdCIpDQogICMgQ2xldmVsYW5kIHBsb3QNCiAgZG90Y2hhcnQoYmRkJHNpbHQsIHBjaCA9IDE2LCBjb2wgPSAnYmx1ZScsIHhsYWIgPSAic2lsdCIpDQoNCmBgYA0KDQoNCg0KIyMgcEgNCg0KLSAgIEhvcnMgY2hpZmZyZSANCmBgYHtyfQ0KIyBsZXMgdmFsZXVycyBkZSBsYSBjb2xvbm5lIHBoX2VhdSBxdWkgbmUgc29udCBwYXMgZGVzIGNoaWZmcmVzIG91IHN1cMOpcmlldXJlcyDDoCAxNA0KDQp2YWxldXJzX2JpemFycmVzIDwtIHN1YnNldChiZGQsICEoZ3JlcGwoIl5cXGQqXFwuP1xcZCskIiwgcGhfZWF1KSB8IGFzLm51bWVyaWMocGhfZWF1KSA+IDE0ICYgaXMubmEocGhfZWF1KSkpJHBoX2VhdQ0KdmFsZXVyc19iaXphcnJlcw0KZGZfY29tcD1iZGQNCmRmX2NvbXAgPC0gZGZfY29tcFshZ3JlcGwoIlteMC05Ll0iLCBkZl9jb21wJHBoX2VhdSksIF0NCmRmX2NvbXAkcGhfZWF1IDwtIGFzLm51bWVyaWMoZGZfY29tcCRwaF9lYXUpDQpgYGANCioqSWwgeSBhIGByIGxlbmd0aCh2YWxldXJzX2JpemFycmVzKWAgcGFyY2VsbGVzIHF1aSBvbnQgZGVzIHBIIHF1aSBuZSBzb250IHBhcyBkZXMgY2hpZmZyZSoqLg0KXG4NCkRhbnMgbW9uIGNhcywgaidhaSBlbmxldmVyIGNlcyAxOSBsaWduZXMuDQoNCi0gICBWYWxldXJzIHN1cGVyaWV1ciBhIDE0DQpgYGB7cn0NCnN1bW1hcnkoYXMubnVtZXJpYyhiZGQkcGhfZWF1KSkNCmRmX2NvbXAgPSBkZl9jb21wWyFkZl9jb21wJHBoX2VhdT09IDQ0MTQwLjAwLF0NCmBgYA0KKipVbmUgcGFyY2VsbGUgZXN0IMOgICQ0NDE0MC4wMCQqKi4gDQoNCg0KYGBge3J9DQpwYXIobWZyb3c9YygxLDIpKQ0KDQojIEJveHBsb3QNCiAgYm94cGxvdChkZl9jb21wJHBoX2VhdSwgY29sID0gJ2JsdWUnLCB5bGFiID0gInBoX2VhdSIpDQogICMgQ2xldmVsYW5kIHBsb3QNCiAgZG90Y2hhcnQoZGZfY29tcCRwaF9lYXUsIHBjaCA9IDE2LCBjb2wgPSAnYmx1ZScsIHhsYWIgPSAicGhfZWF1IikNCg0KYGBgDQoNCiMjIENfdG90DQpgYGB7cn0NCnN1bW1hcnkoYXMubnVtZXJpYyhiZGQkY190b3QpKQ0KI3Bsb3QoYXMubnVtZXJpYyhiZGQkY190b3QpKQ0KcGFyKG1mcm93PWMoMSwyKSkNCg0KIyBCb3hwbG90DQogIGJveHBsb3QoYXMubnVtZXJpYyhiZGQkY190b3QpLCBjb2wgPSAnYmx1ZScsIHlsYWIgPSAiY190b3QiKQ0KICAjIENsZXZlbGFuZCBwbG90DQogIGRvdGNoYXJ0KGFzLm51bWVyaWMoYmRkJGNfdG90KSwgcGNoID0gMTYsIGNvbCA9ICdibHVlJywgeGxhYiA9ICJjX3RvdCIpDQoNCmBgYA0KKipWYWxldXJzIHN1cGVyaWV1cnMgw6AgMTAwID8sIHVuaXTDqXMgPywuLi4gKioNCg0KIyMgQ19vcmcNCmBgYHtyfQ0Kc3VtbWFyeShhcy5udW1lcmljKGJkZCRjX29yZykpDQojcGxvdChhcy5udW1lcmljKGJkZCRjX29yZykpDQpwYXIobWZyb3c9YygxLDIpKQ0KDQojIEJveHBsb3QNCiAgYm94cGxvdChhcy5udW1lcmljKGJkZCRjX29yZyksIGNvbCA9ICdibHVlJywgeWxhYiA9ICJjX29yZyIpDQogICMgQ2xldmVsYW5kIHBsb3QNCiAgZG90Y2hhcnQoYXMubnVtZXJpYyhiZGQkY19vcmcpLCBwY2ggPSAxNiwgY29sID0gJ2JsdWUnLCB4bGFiID0gImNfb3JnIikNCg0KYGBgDQoNCioqVmFsZXVycyBzdXBlcmlldXJzIMOgIDEwMCA/LCB1bml0w6lzID8sLi4uICoqDQoNCg0KIyMgb20NCmBgYHtyfQ0Kc3VtbWFyeShhcy5udW1lcmljKGJkZCRvbSkpDQojcGxvdChhcy5udW1lcmljKGJkZCRvbSkpDQpwYXIobWZyb3c9YygxLDIpKQ0KDQojIEJveHBsb3QNCiAgYm94cGxvdChhcy5udW1lcmljKGJkZCRvbSksIGNvbCA9ICdibHVlJywgeWxhYiA9ICJvbSIpDQogICMgQ2xldmVsYW5kIHBsb3QNCiAgZG90Y2hhcnQoYXMubnVtZXJpYyhiZGQkb20pLCBwY2ggPSAxNiwgY29sID0gJ2JsdWUnLCB4bGFiID0gIm9tIikNCg0KYGBgDQoNCioqVmFsZXVycyBzdXBlcmlldXJzIMOgIDEwMCA/LCB1bml0w6lzID8sLi4uICoqDQoNCiMjIElEDQpgYGB7cn0NCiMgQ2hlY2sgZGVzIGRvdWJsb25zDQpkdXBsaWNhdGVkX3Jvd3MgPC0gc3Vic2V0KGJkZCwgZHVwbGljYXRlZChiZGRbLCBjKCJJRCIsICJBQl90b3QiLCAiQk1fdG90IildKSB8IGR1cGxpY2F0ZWQoYmRkWywgYygiSUQiLCAiQUJfdG90IiwgIkJNX3RvdCIpXSwgZnJvbUxhc3QgPSBUUlVFKSkNCg0KYGBgDQoNCg==