Libraries and raw
data
library(tidyverse)
library(magrittr)
library(sf)
library(tmap)
library(spdep) # Spatial weights, Moran's I, and LISA
library(spatialreg) # Spatial Regression
library(spgwr) # GWR
load("../04_MexicoCity_HTS/Mexico_HTS.RData")
ls()
[1] "MexicoCity_HTS"
Remove districts
summary(MexicoCity_HTS$TotalPeople)
Min. 1st Qu. Median Mean 3rd Qu. Max. NA's
634 968 1035 1027 1103 1333 1
MexicoCity_HTS %>% filter(is.na(TotalPeople)) %>% select(Distrito)
Simple feature collection with 1 feature and 1 field
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: -99.09278 ymin: 19.41697 xmax: -99.04731 ymax: 19.45018
Geodetic CRS: WGS 84
Distrito geometry
1 034 MULTIPOLYGON (((-99.08461 1...
MexicoCity_HTS %<>% filter(Distrito != "034")
summary(MexicoCity_HTS$Total_Homes)
Min. 1st Qu. Median Mean 3rd Qu. Max.
272.0 285.0 293.0 293.7 301.0 352.0
Map preparation
MexicoCity_Fringe <- st_read("../04_MexicoCity_HTS/UrbanFringe_MexicoCity.shp")
Reading layer `UrbanFringe_MexicoCity' from data source
`C:\Users\Orlan\Dropbox\Teaching\SpatialAnalysis\Tutorials\04_MexicoCity_HTS\UrbanFringe_MexicoCity.shp'
using driver `ESRI Shapefile'
Simple feature collection with 1 feature and 5 fields
Geometry type: POLYGON
Dimension: XY
Bounding box: xmin: -99.36492 ymin: 19.04824 xmax: -98.9403 ymax: 19.59276
Geodetic CRS: WGS 84
BB_Districts <- st_bbox(MexicoCity_HTS)
BB_Districts[1] <- -99.8
BB_Districts
xmin ymin xmax ymax
-99.80000 18.93534 -98.59687 20.06826
GWR
MexicoCity_HTS %<>%
mutate(CarTrips_PerPopulation = Trips_Automovil/TotalPeople,
Prop_Male = Total_Male/TotalPeople,
Prop_HomesWithCars = Homes_With_Cars/Total_Homes,
Prop_HomesWithBicycles = Homes_With_Bicycles/Total_Homes,
Prop_Education_Low = TotalEducation_Low/TotalPeople,
Prop_Education_Medium = TotalEducation_Medium/TotalPeople,
Prop_Education_High = TotalEducation_High/TotalPeople)
ModelEquation <- "CarTrips_PerPopulation ~
Prop_Male +
Prop_HomesWithCars +
Prop_HomesWithBicycles +
# Prop_Education_Low +
Age"
st_is_longlat(MexicoCity_HTS)
[1] TRUE
Data_SP <- as(MexicoCity_HTS, "Spatial")
Data_Centroids <- st_centroid(MexicoCity_HTS)
Warning: st_centroid assumes attributes are constant over geometries of x
Data_Centroids_SP <- as(Data_Centroids, "Spatial")
Data_Centroids_SP <- as(Data_Centroids, "Spatial")
Bandwidth = gwr.sel(ModelEquation,
data = Data_SP, adapt = T)
Adaptive q: 0.381966 CV score: 15.79799
Adaptive q: 0.618034 CV score: 16.06607
Adaptive q: 0.236068 CV score: 15.58982
Adaptive q: 0.145898 CV score: 15.57813
Adaptive q: 0.1791799 CV score: 15.52235
Adaptive q: 0.1889397 CV score: 15.52933
Adaptive q: 0.1776273 CV score: 15.52027
Adaptive q: 0.1655078 CV score: 15.54149
Adaptive q: 0.1729981 CV score: 15.51867
Adaptive q: 0.1742408 CV score: 15.51841
Adaptive q: 0.1742815 CV score: 15.5184
Adaptive q: 0.1755595 CV score: 15.51829
Adaptive q: 0.1759044 CV score: 15.51828
Adaptive q: 0.1759451 CV score: 15.51828
Adaptive q: 0.1758637 CV score: 15.51828
Adaptive q: 0.1759044 CV score: 15.51828
Model_GWR = gwr(ModelEquation,
data = Data_SP,
adapt = Bandwidth,
hatmatrix = T,
se.fit = T)
Warning: CRS object has comment, which is lost in output; in tests, see
https://cran.r-project.org/web/packages/sp/vignettes/CRS_warnings.html
Model_GWR
Call:
gwr(formula = ModelEquation, data = Data_SP, adapt = Bandwidth,
hatmatrix = T, se.fit = T)
Kernel function: gwr.Gauss
Adaptive quantile: 0.1759044 (about 33 of 193 data points)
Summary of GWR coefficient estimates at data points:
Min. 1st Qu. Median 3rd Qu. Max. Global
X.Intercept. -4.596397 -3.308457 -2.509538 -1.814455 -1.476676 -1.9269
Prop_Male -0.610742 0.462755 0.909108 1.463229 2.486808 -0.1161
Prop_HomesWithCars 1.456090 1.636658 1.906816 2.131098 2.370322 1.8743
Prop_HomesWithBicycles -0.711226 -0.435152 -0.222469 -0.098109 -0.011571 -0.0213
Age 0.025141 0.042468 0.055391 0.069582 0.095840 0.0513
Number of data points: 193
Effective number of parameters (residual: 2traceS - traceS'S): 19.61997
Effective degrees of freedom (residual: 2traceS - traceS'S): 173.38
Sigma (residual: 2traceS - traceS'S): 0.2714758
Effective number of parameters (model: traceS): 14.23004
Effective degrees of freedom (model: traceS): 178.77
Sigma (model: traceS): 0.2673519
Sigma (ML): 0.2573072
AICc (GWR p. 61, eq 2.33; p. 96, eq. 4.21): 56.97799
AIC (GWR p. 96, eq. 4.22): 37.95128
Residual sum of squares: 12.77795
Quasi-global R2: 0.7102361
results <- as.data.frame(Model_GWR$SDF)
names(results)
[1] "sum.w" "X.Intercept."
[3] "Prop_Male" "Prop_HomesWithCars"
[5] "Prop_HomesWithBicycles" "Age"
[7] "X.Intercept._se" "Prop_Male_se"
[9] "Prop_HomesWithCars_se" "Prop_HomesWithBicycles_se"
[11] "Age_se" "gwr.e"
[13] "pred" "pred.se"
[15] "localR2" "X.Intercept._se_EDF"
[17] "Prop_Male_se_EDF" "Prop_HomesWithCars_se_EDF"
[19] "Prop_HomesWithBicycles_se_EDF" "Age_se_EDF"
[21] "pred.se.1"
Homes with cars
Temp <- results %>%
select(Variable = Prop_HomesWithCars, SE = Prop_HomesWithCars_se) %>%
mutate(T_value = Variable/SE) %>%
mutate(Significance = cut(T_value,
breaks = c(-0.01 + min(T_value),
-1.96, 1.96,
0.01 + max(T_value)),
labels = c("sig","nonsig", "sig")))
Temp_GWR_Coefficient <- Data_SP
Temp_GWR_Coefficient$Variable <- Temp$Variable
Temp_GWR_Coefficient$SE <- Temp$SE
Temp_GWR_Coefficient$T_value <- Temp$T_value
Temp_GWR_Coefficient$Significance <- Temp$Significance
Temp_GWR_Coefficient <- as(Temp_GWR_Coefficient,"sf")
Temp_GWR_Coefficient %<>% select(Variable, SE, T_value, Significance)
Temp_GWR_Coefficient_SIGNIGICANT <- Temp_GWR_Coefficient %>%
filter(Significance == "sig")
Temp_GWR_Coefficient_NON_SIGNIGICANT <- Temp_GWR_Coefficient %>%
filter(Significance != "sig")
summary(Temp_GWR_Coefficient_SIGNIGICANT$Variable)
Min. 1st Qu. Median Mean 3rd Qu. Max.
1.456 1.637 1.907 1.893 2.131 2.370
Q <- quantile(Temp_GWR_Coefficient_SIGNIGICANT$Variable,
probs = c(0, 0.2, 0.4, 0.6, 0.8, 1))
Q
0% 20% 40% 60% 80% 100%
1.456090 1.596206 1.755150 2.015792 2.165692 2.370322
Breaks <- c(
as.numeric(Q[1]), as.numeric(Q[2]),
as.numeric(Q[3]), as.numeric(Q[4]),
as.numeric(Q[5]), as.numeric(Q[6]))
Labels <- c(
paste(floor(Breaks[1]*1000)/1000, round(Breaks[2], 3), sep = " - "),
paste(round(Breaks[2], 3), round(Breaks[3], 3), sep = " - "),
paste(round(Breaks[3], 3), round(Breaks[4], 3), sep = " - "),
paste(round(Breaks[4], 3), round(Breaks[5], 3), sep = " - "),
paste(round(Breaks[5], 3), ceiling(Breaks[6]*1000)/1000, sep = " - "))
MyPalette <- c("#ffffcc", "#a1dab4", "#41b6c4", "#2c7fb8", "#253494")
GWR_Map_Cars <- tm_shape(MexicoCity_Fringe, bbox = BB_Districts) +
tm_polygons(lwd = 2.5, border.col = "black") +
tm_shape(Temp_GWR_Coefficient_SIGNIGICANT) +
tm_polygons("Variable",
palette = MyPalette, lwd = 0, border.col = "black", border.alpha = 0,
title = "Theft (quantiles)",
breaks = Breaks, labels = Labels) +
# tm_shape(Temp_GWR_Coefficient_NON_SIGNIGICANT) +
# tm_polygons(col = "white") +
tm_compass(size = 2, type = "arrow", position = c(0.85,0.87)) +
tm_scale_bar(position = c(0.2,0.02)) +
tm_layout(title = "Car ownership", legend.position = c(0.01, 0.58)) +
tm_add_legend(
type = c("fill"),
labels = c("Not significant"),
col = c("white"),
title = "")
GWR_Map_Cars
GWR_Map_Cars <- tm_shape(Temp_GWR_Coefficient_SIGNIGICANT) +
tm_polygons("Variable",
palette = MyPalette, lwd = 0, border.col = "black", border.alpha = 0,
title = "Quantiles",
breaks = Breaks, labels = Labels) +
tm_borders(alpha = 0.4) +
tm_shape(MexicoCity_Fringe) +
tm_polygons(alpha = 0, border.col = "black", lwd = 1.4, lty = "solid") +
tm_compass(size = 2, type = "arrow", position = c(0.85,0.87)) +
tm_scale_bar(position = c(0.4,0.02)) +
tm_layout(title = "Cars", legend.position = c(0.01,0.15), scale = 1)
GWR_Map_Cars
LS0tDQp0aXRsZTogIkdXUiINCmF1dGhvcjogIk9ybGFuZG8gU2Fib2dhbC1DYXJkb25hIg0KZGF0ZTogIlN1bW1lciAyMDIzIg0Kb3V0cHV0OiANCiAgaHRtbF9ub3RlYm9vazogDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZmxvYXQ6DQogICAgICBjb2xsYXBzZWQ6IHRydWUNCiAgICAgIHNtb290aF9zY3JvbGw6IGZhbHNlDQogICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlDQotLS0NCg0KIyBMaWJyYXJpZXMgYW5kIHJhdyBkYXRhDQoNCmBgYHtyIGxpYnJhcmllcyB1c2VkfQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpsaWJyYXJ5KG1hZ3JpdHRyKQ0KbGlicmFyeShzZikNCmxpYnJhcnkodG1hcCkNCg0KbGlicmFyeShzcGRlcCkgIyBTcGF0aWFsIHdlaWdodHMsIE1vcmFuJ3MgSSwgYW5kIExJU0ENCmxpYnJhcnkoc3BhdGlhbHJlZykgIyBTcGF0aWFsIFJlZ3Jlc3Npb24NCg0KbGlicmFyeShzcGd3cikgIyBHV1INCmBgYA0KDQpgYGB7cn0NCmxvYWQoIi4uLzA0X01leGljb0NpdHlfSFRTL01leGljb19IVFMuUkRhdGEiKQ0KbHMoKQ0KYGBgDQoNCiMjIFJlbW92ZSBkaXN0cmljdHMNCg0KYGBge3J9DQpzdW1tYXJ5KE1leGljb0NpdHlfSFRTJFRvdGFsUGVvcGxlKQ0KTWV4aWNvQ2l0eV9IVFMgJT4lIGZpbHRlcihpcy5uYShUb3RhbFBlb3BsZSkpICU+JSBzZWxlY3QoRGlzdHJpdG8pDQpgYGANCg0KYGBge3J9DQpNZXhpY29DaXR5X0hUUyAlPD4lIGZpbHRlcihEaXN0cml0byAhPSAiMDM0IikNCmBgYA0KDQpgYGB7cn0NCnN1bW1hcnkoTWV4aWNvQ2l0eV9IVFMkVG90YWxfSG9tZXMpDQpgYGANCg0KIyMgTWFwIHByZXBhcmF0aW9uDQogDQpgYGB7cn0NCk1leGljb0NpdHlfRnJpbmdlIDwtIHN0X3JlYWQoIi4uLzA0X01leGljb0NpdHlfSFRTL1VyYmFuRnJpbmdlX01leGljb0NpdHkuc2hwIikNCmBgYA0KDQpgYGB7cn0NCkJCX0Rpc3RyaWN0cyA8LSBzdF9iYm94KE1leGljb0NpdHlfSFRTKQ0KQkJfRGlzdHJpY3RzWzFdIDwtIC05OS44DQpCQl9EaXN0cmljdHMNCmBgYA0KDQojIEdXUg0KDQpgYGB7cn0NCk1leGljb0NpdHlfSFRTICU8PiUNCiAgbXV0YXRlKENhclRyaXBzX1BlclBvcHVsYXRpb24gPSBUcmlwc19BdXRvbW92aWwvVG90YWxQZW9wbGUsDQogICAgICAgICBQcm9wX01hbGUgPSBUb3RhbF9NYWxlL1RvdGFsUGVvcGxlLA0KICAgICAgICAgUHJvcF9Ib21lc1dpdGhDYXJzID0gSG9tZXNfV2l0aF9DYXJzL1RvdGFsX0hvbWVzLA0KICAgICAgICAgUHJvcF9Ib21lc1dpdGhCaWN5Y2xlcyA9IEhvbWVzX1dpdGhfQmljeWNsZXMvVG90YWxfSG9tZXMsDQogICAgICAgICBQcm9wX0VkdWNhdGlvbl9Mb3cgPSBUb3RhbEVkdWNhdGlvbl9Mb3cvVG90YWxQZW9wbGUsDQogICAgICAgICBQcm9wX0VkdWNhdGlvbl9NZWRpdW0gPSBUb3RhbEVkdWNhdGlvbl9NZWRpdW0vVG90YWxQZW9wbGUsDQogICAgICAgICBQcm9wX0VkdWNhdGlvbl9IaWdoID0gVG90YWxFZHVjYXRpb25fSGlnaC9Ub3RhbFBlb3BsZSkNCmBgYA0KDQpgYGB7cn0NCk1vZGVsRXF1YXRpb24gPC0gIkNhclRyaXBzX1BlclBvcHVsYXRpb24gfiANCiAgICAgICAgICAgICAgICAgICAgICAgICAgUHJvcF9NYWxlICsgDQogICAgICAgICAgICAgICAgICAgICAgICAgIFByb3BfSG9tZXNXaXRoQ2FycyArIA0KICAgICAgICAgICAgICAgICAgICAgICAgICBQcm9wX0hvbWVzV2l0aEJpY3ljbGVzICsNCiAgICAgICAgICAgICAgICAgICAgICAgICAgIyBQcm9wX0VkdWNhdGlvbl9Mb3cgKyANCiAgICAgICAgICAgICAgICAgICAgICAgICAgQWdlIg0KYGBgDQoNCmBgYHtyfQ0Kc3RfaXNfbG9uZ2xhdChNZXhpY29DaXR5X0hUUykNCmBgYA0KDQpgYGB7cn0NCkRhdGFfU1AgPC0gYXMoTWV4aWNvQ2l0eV9IVFMsICJTcGF0aWFsIikNCkRhdGFfQ2VudHJvaWRzIDwtIHN0X2NlbnRyb2lkKE1leGljb0NpdHlfSFRTKQ0KDQpEYXRhX0NlbnRyb2lkc19TUCA8LSBhcyhEYXRhX0NlbnRyb2lkcywgIlNwYXRpYWwiKQ0KYGBgDQoNCmBgYHtyfQ0KRGF0YV9DZW50cm9pZHNfU1AgPC0gYXMoRGF0YV9DZW50cm9pZHMsICJTcGF0aWFsIikNCmBgYA0KDQpgYGB7cn0NCkJhbmR3aWR0aCA9IGd3ci5zZWwoTW9kZWxFcXVhdGlvbiwgDQogICAgICAgICAgICAgICAgICAgIGRhdGEgPSBEYXRhX1NQLCBhZGFwdCA9IFQpDQpgYGANCg0KDQpgYGB7cn0NCk1vZGVsX0dXUiA9IGd3cihNb2RlbEVxdWF0aW9uLCANCiAgICAgICAgICAgICAgICBkYXRhID0gRGF0YV9TUCwgDQogICAgICAgICAgICAgICAgYWRhcHQgPSBCYW5kd2lkdGgsIA0KICAgICAgICAgICAgICAgIGhhdG1hdHJpeCA9IFQsIA0KICAgICAgICAgICAgICAgIHNlLmZpdCA9IFQpDQpgYGANCg0KYGBge3J9DQpNb2RlbF9HV1INCmBgYA0KDQpgYGB7cn0NCnJlc3VsdHMgPC0gYXMuZGF0YS5mcmFtZShNb2RlbF9HV1IkU0RGKQ0KbmFtZXMocmVzdWx0cykNCmBgYA0KIyMgSG9tZXMgd2l0aCBjYXJzDQoNCmBgYHtyfQ0KVGVtcCA8LSByZXN1bHRzICU+JSANCiAgc2VsZWN0KFZhcmlhYmxlID0gUHJvcF9Ib21lc1dpdGhDYXJzLCBTRSA9IFByb3BfSG9tZXNXaXRoQ2Fyc19zZSkgJT4lIA0KICBtdXRhdGUoVF92YWx1ZSA9IFZhcmlhYmxlL1NFKSAlPiUgDQogIG11dGF0ZShTaWduaWZpY2FuY2UgPSBjdXQoVF92YWx1ZSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVha3MgPSBjKC0wLjAxICsgbWluKFRfdmFsdWUpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0xLjk2LCAxLjk2LCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAuMDEgKyBtYXgoVF92YWx1ZSkpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoInNpZyIsIm5vbnNpZyIsICJzaWciKSkpDQoNClRlbXBfR1dSX0NvZWZmaWNpZW50IDwtIERhdGFfU1ANCg0KVGVtcF9HV1JfQ29lZmZpY2llbnQkVmFyaWFibGUgPC0gVGVtcCRWYXJpYWJsZQ0KVGVtcF9HV1JfQ29lZmZpY2llbnQkU0UgPC0gVGVtcCRTRQ0KVGVtcF9HV1JfQ29lZmZpY2llbnQkVF92YWx1ZSA8LSBUZW1wJFRfdmFsdWUNClRlbXBfR1dSX0NvZWZmaWNpZW50JFNpZ25pZmljYW5jZSA8LSBUZW1wJFNpZ25pZmljYW5jZQ0KDQpUZW1wX0dXUl9Db2VmZmljaWVudCA8LSBhcyhUZW1wX0dXUl9Db2VmZmljaWVudCwic2YiKQ0KDQpUZW1wX0dXUl9Db2VmZmljaWVudCAlPD4lIHNlbGVjdChWYXJpYWJsZSwgU0UsIFRfdmFsdWUsIFNpZ25pZmljYW5jZSkgDQoNClRlbXBfR1dSX0NvZWZmaWNpZW50X1NJR05JR0lDQU5UIDwtIFRlbXBfR1dSX0NvZWZmaWNpZW50ICU+JSANCiAgZmlsdGVyKFNpZ25pZmljYW5jZSA9PSAic2lnIikNClRlbXBfR1dSX0NvZWZmaWNpZW50X05PTl9TSUdOSUdJQ0FOVCA8LSBUZW1wX0dXUl9Db2VmZmljaWVudCAlPiUgDQogIGZpbHRlcihTaWduaWZpY2FuY2UgIT0gInNpZyIpDQpgYGANCg0KYGBge3J9DQpzdW1tYXJ5KFRlbXBfR1dSX0NvZWZmaWNpZW50X1NJR05JR0lDQU5UJFZhcmlhYmxlKQ0KYGBgDQoNCmBgYHtyfQ0KUSA8LSBxdWFudGlsZShUZW1wX0dXUl9Db2VmZmljaWVudF9TSUdOSUdJQ0FOVCRWYXJpYWJsZSwgDQogICAgICAgICBwcm9icyA9IGMoMCwgMC4yLCAwLjQsIDAuNiwgMC44LCAxKSkNClENCmBgYA0KDQpgYGB7cn0NCkJyZWFrcyA8LSBjKA0KICBhcy5udW1lcmljKFFbMV0pLCBhcy5udW1lcmljKFFbMl0pLA0KICBhcy5udW1lcmljKFFbM10pLCBhcy5udW1lcmljKFFbNF0pLA0KICBhcy5udW1lcmljKFFbNV0pLCBhcy5udW1lcmljKFFbNl0pKQ0KDQpMYWJlbHMgPC0gYygNCiAgcGFzdGUoZmxvb3IoQnJlYWtzWzFdKjEwMDApLzEwMDAsIHJvdW5kKEJyZWFrc1syXSwgMyksIHNlcCA9ICIgLSAiKSwNCiAgcGFzdGUocm91bmQoQnJlYWtzWzJdLCAzKSwgcm91bmQoQnJlYWtzWzNdLCAzKSwgc2VwID0gIiAtICIpLA0KICBwYXN0ZShyb3VuZChCcmVha3NbM10sIDMpLCByb3VuZChCcmVha3NbNF0sIDMpLCBzZXAgPSAiIC0gIiksDQogIHBhc3RlKHJvdW5kKEJyZWFrc1s0XSwgMyksIHJvdW5kKEJyZWFrc1s1XSwgMyksIHNlcCA9ICIgLSAiKSwNCiAgcGFzdGUocm91bmQoQnJlYWtzWzVdLCAzKSwgY2VpbGluZyhCcmVha3NbNl0qMTAwMCkvMTAwMCwgc2VwID0gIiAtICIpKQ0KDQpNeVBhbGV0dGUgPC0gYygiI2ZmZmZjYyIsICIjYTFkYWI0IiwgIiM0MWI2YzQiLCAiIzJjN2ZiOCIsICIjMjUzNDk0IikNCmBgYA0KDQpgYGB7cn0NCkdXUl9NYXBfQ2FycyA8LSB0bV9zaGFwZShNZXhpY29DaXR5X0ZyaW5nZSwgYmJveCA9IEJCX0Rpc3RyaWN0cykgKyANCiAgdG1fcG9seWdvbnMobHdkID0gMi41LCBib3JkZXIuY29sID0gImJsYWNrIikgKw0KICB0bV9zaGFwZShUZW1wX0dXUl9Db2VmZmljaWVudF9TSUdOSUdJQ0FOVCkgKyANCiAgdG1fcG9seWdvbnMoIlZhcmlhYmxlIiwNCiAgICAgICAgICBwYWxldHRlID0gTXlQYWxldHRlLCBsd2QgPSAwLCBib3JkZXIuY29sID0gImJsYWNrIiwgYm9yZGVyLmFscGhhID0gMCwNCiAgICAgICAgICB0aXRsZSA9ICJUaGVmdCAocXVhbnRpbGVzKSIsIA0KICAgICAgICAgIGJyZWFrcyA9IEJyZWFrcywgbGFiZWxzID0gTGFiZWxzKSArDQogICMgdG1fc2hhcGUoVGVtcF9HV1JfQ29lZmZpY2llbnRfTk9OX1NJR05JR0lDQU5UKSArDQogICMgdG1fcG9seWdvbnMoY29sID0gIndoaXRlIikgKw0KICB0bV9jb21wYXNzKHNpemUgPSAyLCB0eXBlID0gImFycm93IiwgcG9zaXRpb24gPSBjKDAuODUsMC44NykpICsNCiAgdG1fc2NhbGVfYmFyKHBvc2l0aW9uID0gYygwLjIsMC4wMikpICsNCiAgdG1fbGF5b3V0KHRpdGxlID0gIkNhciBvd25lcnNoaXAiLCBsZWdlbmQucG9zaXRpb24gPSBjKDAuMDEsIDAuNTgpKSArDQogIHRtX2FkZF9sZWdlbmQoDQogICAgdHlwZSA9IGMoImZpbGwiKSwNCiAgICBsYWJlbHMgPSBjKCJOb3Qgc2lnbmlmaWNhbnQiKSwgDQogICAgY29sID0gYygid2hpdGUiKSwNCiAgICB0aXRsZSA9ICIiKQ0KDQoNCkdXUl9NYXBfQ2Fycw0KYGBgDQoNCmBgYHtyfQ0KR1dSX01hcF9DYXJzIDwtIHRtX3NoYXBlKFRlbXBfR1dSX0NvZWZmaWNpZW50X1NJR05JR0lDQU5UKSArIA0KICB0bV9wb2x5Z29ucygiVmFyaWFibGUiLA0KICAgICAgICAgIHBhbGV0dGUgPSBNeVBhbGV0dGUsIGx3ZCA9IDAsIGJvcmRlci5jb2wgPSAiYmxhY2siLCBib3JkZXIuYWxwaGEgPSAwLA0KICAgICAgICAgIHRpdGxlID0gIlF1YW50aWxlcyIsIA0KICAgICAgICAgIGJyZWFrcyA9IEJyZWFrcywgbGFiZWxzID0gTGFiZWxzKSArDQogIHRtX2JvcmRlcnMoYWxwaGEgPSAwLjQpICsNCiAgdG1fc2hhcGUoTWV4aWNvQ2l0eV9GcmluZ2UpICsgDQogIHRtX3BvbHlnb25zKGFscGhhID0gMCwgYm9yZGVyLmNvbCA9ICJibGFjayIsIGx3ZCA9IDEuNCwgbHR5ID0gInNvbGlkIikgKw0KICB0bV9jb21wYXNzKHNpemUgPSAyLCB0eXBlID0gImFycm93IiwgcG9zaXRpb24gPSBjKDAuODUsMC44NykpICsgDQogIHRtX3NjYWxlX2Jhcihwb3NpdGlvbiA9IGMoMC40LDAuMDIpKSArDQogIHRtX2xheW91dCh0aXRsZSA9ICJDYXJzIiwgbGVnZW5kLnBvc2l0aW9uID0gYygwLjAxLDAuMTUpLCBzY2FsZSA9IDEpDQoNCg0KR1dSX01hcF9DYXJzDQpgYGANCg0K