General Data Preparation
Loading Libraries
suppressMessages(library(sna))
suppressMessages(library(dplyr))
suppressMessages(library(ggsci))
suppressMessages(library(plotly))
suppressMessages(library(igraph))
suppressMessages(library(network))
suppressMessages(library(kableExtra))
suppressMessages(library(igraphdata))
suppressMessages(library(intergraph))
suppressMessages(library(RColorBrewer))
Loading Dataset
load("res_sem.RData")
#sub stringing the IPC3 from IPC
IPC4 <- substr(joined_IPC_Inv$IPC, start = 1, stop = 4) #extracting the IPC3 from the original sorted dataset
IPC4 <- as.data.frame(IPC4) # defining it as a dataframe
data_final <- cbind(joined_IPC_Inv, IPC4) # combining the newly created IPC3 containing dataframe with the main dataframe
rm(joined_IPC_Inv) & rm(IPC4) # removing the dataset to free memory
## logical(0)
data_final <- subset(data_final, select = -c(IPC,ctry_code)) # dropping columns
Data Cleaning
data <- (data_final %>%
filter(IPC4=="F03D")) # creating subset of Wind Energy Industry (F03D)
rm(data_final)
data <- (data %>%
filter(app_year>= 1996 & app_year <= 2016)) # limiting years from 1996 to 2016
# now getting rid of empty city values
data <- (data %>%
mutate(city = replace(city, city == "", NA)))#making the empty values NA
data <- na.omit(data) #getting rid of NA values
# getting rid of duplicate values
data_main <- data[!duplicated(data),]
# ranking cities according to patents
data_main_city_rank <- (data_main %>%
group_by(city) %>%
count(city, sort = TRUE, name = "patents")) #ranking the cities according to the number of patent applications
data_main_15 <- head(data_main_city_rank,15) # keeping first 15 patent owning cities in ranked format
data_main_15_attr <- (data_main %>%
filter(city %in% c("Aurich","Hamburg","Berlin","Salzbergen","Rendsburg","Rheine","Kiel","Aachen","Munchen","Norderstedt","Osnabruck","Bremen","Erlangen","Dresden","Munster"))) # keeping the most 15 patent owning cities with all attributes
Network Data Preparation (Using igraph and sna packages)
N1. Inventor networks for all cities
inv_aff_all <- (data_main %>%
select(appln_id,person_id))
inv_aff_all_2mode <- table(inv_aff_all)
inv_aff_all_adj <- inv_aff_all_2mode %*% t(inv_aff_all_2mode)
diag(inv_aff_all_adj) <-0 # deleting the diagonals
inv_aff_all_ig <- graph.adjacency(inv_aff_all_adj, mode = "undirected", weight = TRUE)
print(inv_aff_all_ig) # Basic information about the network
## IGRAPH 1bd6ec3 UNW- 2129 15915 --
## + attr: name (v/c), weight (e/n)
## + edges from 1bd6ec3 (vertex names):
## [1] 146 --16300136 146 --16301200 146 --16389117 146 --313583480
## [5] 1040--57537 1042--124159 1042--165074 1042--184222
## [9] 1042--220266 1042--241948 1042--269684 1042--271952
## [13] 1042--342495 1042--374699 1042--397355 1042--412779
## [17] 1042--414426 1042--15756743 1042--15757619 1042--15764242
## [21] 1042--15765093 1042--15766246 1042--15777559 1042--15777598
## [25] 1042--15780371 1042--15780379 1042--15790852 1042--15796437
## [29] 1042--15796509 1042--15799148 1042--15800073 1042--15820220
## + ... omitted several edges
N2. City networks (for 15 most innovative cities)
inv_city <- (data_main_15_attr %>%
select(city, appln_id))
inv_city_2mode <- table(inv_city) # cross tabulate -> 2-mode sociomatrix
inv_city_adj <- inv_city_2mode %*% t(inv_city_2mode)
diag(inv_city_adj) <-0 # deleting the diagonals
inv_city_ig <- graph.adjacency(inv_city_adj, mode = "undirected", weight = TRUE)
print(inv_city_ig) # basic information about the network
## IGRAPH 1beb531 UNW- 15 34 --
## + attr: name (v/c), weight (e/n)
## + edges from 1beb531 (vertex names):
## [1] Aachen --Bremen Aachen --Rheine Aurich --Berlin
## [4] Aurich --Bremen Aurich --Hamburg Berlin --Erlangen
## [7] Berlin --Hamburg Berlin --Kiel Berlin --Norderstedt
## [10] Berlin --Rendsburg Berlin --Rheine Berlin --Salzbergen
## [13] Bremen --Hamburg Bremen --Rheine Dresden--Norderstedt
## [16] Hamburg--Kiel Hamburg--Munchen Hamburg--Norderstedt
## [19] Hamburg--Rendsburg Hamburg--Rheine Kiel --Norderstedt
## [22] Kiel --Osnabruck Kiel --Rendsburg Kiel --Rheine
## + ... omitted several edges
N3. Inventor’s network of top 15 cities
# inventor's data cleaning
inv_person <- (data_main_15_attr %>%
select(inv_name,appln_id)) # sub-setting the data for inventors with patents
inv_per_attr <- (data_main_15_attr %>%
select(appln_id, city))
# parsing the person's network data to have clean and non-duplicated values
inv_person_parsed <- inv_person
length(unique(inv_person_parsed$inv_name))
## [1] 630
inv_person_parsed$inv_name_small <- tolower(inv_person_parsed$inv_name)
inv_person_parsed$inv_name_small <- sub(", prof. dr.-ing.","", inv_person_parsed$inv_name_small)
length(unique(inv_person_parsed$inv_name_small))
## [1] 591
inv_person_parsed$inv_name_small <- sub(", dr.-ing.","", inv_person_parsed$inv_name_small)
length(unique(inv_person_parsed$inv_name_small))
## [1] 590
inv_person_parsed$inv_name_small <- sub(", dipl.-ing.","", inv_person_parsed$inv_name_small)
length(unique(inv_person_parsed$inv_name_small))
## [1] 588
inv_person_parsed$inv_name_small <- sub(", -ing.","", inv_person_parsed$inv_name_small)
length(unique(inv_person_parsed$inv_name_small))
## [1] 588
inv_person_parsed$inv_name_small <- sub(", dr.","", inv_person_parsed$inv_name_small)
length(unique(inv_person_parsed$inv_name_small))
## [1] 578
inv_person_parsed$inv_name_small <- sub(" dr.","", inv_person_parsed$inv_name_small)
length(unique(inv_person_parsed$inv_name_small))
## [1] 577
# new network changed size
length(unique(inv_person_parsed$inv_name_small))/length(unique(inv_person_parsed$inv_name))
## [1] 0.915873
# getting rid of original inventor names
inv_person_parsed$inv_name <- inv_person_parsed$inv_name_small
# removing third column
inv_person_parsed <- subset(inv_person_parsed, select = -c(inv_name_small))
# creating network with the cleaned data
inv_person_2mode <- table(inv_person_parsed) # making 2 mode sociomatrix
inv_person_adj <- inv_person_2mode %*% t(inv_person_2mode)
diag(inv_person_adj) <-0
inv_aff_ig <- graph.adjacency(inv_person_adj, mode = "undirected", weight = TRUE)
Creating Networks and Plotting Graphs
Detaching packages to avoid conflicts between package operations.
detach(package:sna)
detach(package:network)
suppressMessages(library(igraph))
N1. Creating the network for all the inventors
# matching the dataset with city and application ids
inv_person_parsed$city <- inv_per_attr$city[match(inv_person_parsed$appln_id, inv_person_parsed$appln_id)]
N1. Plotting
set.seed(100)
par(mar=c(0,0,1,0))
plot(inv_aff_all_ig,
vertex.label=NA,
vertex.size = 3,
vertex.color = V(inv_aff_all_ig),
main="Network of all the inventors")

N2. Creating network for 15 cities
inv_city_ig <- (inv_city_ig %>%
set_vertex_attr(
name = "vertex.names",
value = c("Aurich","Hamburg","Berlin","Salzbergen","Rendsburg","Rheine","Kiel","Aachen","Munchen","Norderstedt","Osnabruck","Bremen","Erlangen","Dresden","Munster") # modifying vertex names on the igraph object (as city names)
))
V(inv_city_ig)$label <- c("Aurich","Hamburg","Berlin","Salzbergen","Rendsburg","Rheine","Kiel","Aachen","Munchen","Norderstedt","Osnabruck","Bremen","Erlangen","Dresden","Munster") # changing the igraph object's labels also into the city names
N2. Centrality Measurement
centr_degree(
inv_city_ig,
mode = c("all", "out", "in", "total"),
loops = F,
normalized = TRUE)
## $res
## [1] 2 3 8 4 1 1 8 7 4 2 6 3 5 9 5
##
## $centralization
## [1] 0.3681319
##
## $theoretical_max
## [1] 182
N2. Plotting
par(mar=c(0,0,2,0))
set.seed(100)
plot(inv_city_ig,
vertex.label=V(inv_city_ig)$city,
vertex.color=V(inv_city_ig),
vertex.size= 10,
vertex.frame.color=NA,
vertex.label.family= "Cambria",
vertex.label.font=2,
main="Network of top 15 cities")

N3. Plotting and centrality measurement of inventor’s network (top
15 cities)
N3. Centrality Measurement
centr_degree(
inv_aff_ig,
mode = c("all", "out", "in", "total"),
loops = F,
normalized = TRUE)
## $res
## [1] 3 0 0 7 1 5 2 3 0 1 1 1 1 1 0 0 1 4 1 2 1 0 0 0 1 1 0 1 1 1 3 1 1 2 3 0 0
## [38] 0 0 1 0 0 0 0 1 0 3 4 1 2 0 1 0 3 4 1 0 0 2 1 3 1 0 2 0 1 1 1 1 2 6 0 1 1
## [75] 0 3 3 1 1 0 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 1 0 1 0 1 0 0 3 2 1 4 0 0 3 1 2
## [112] 1 0 1 0 0 1 0 1 1 1 1 0 2 2 0 0 0 2 0 3 1 0 2 0 1 0 0 4 1 0 5 0 0 1 1 2 0
## [149] 1 1 1 0 1 0 0 1 4 5 0 3 1 0 2 0 0 0 0 1 0 0 2 0 0 1 1 7 5 0 1 2 1 4 0 1 1
## [186] 1 1 3 3 0 5 1 0 0 0 1 1 0 0 0 2 3 3 1 1 0 0 0 1 0 0 1 4 0 1 0 0 0 0 1 1 1
## [223] 2 2 0 0 1 3 0 7 0 1 2 1 2 0 1 2 2 3 0 0 1 1 0 3 4 3 0 0 1 2 0 1 3 3 0 0 0
## [260] 1 0 1 1 2 1 0 1 1 2 0 0 0 0 0 0 3 0 0 1 2 0 1 0 1 1 2 2 3 0 1 1 4 0 2 0 1
## [297] 0 2 2 0 0 3 2 0 3 0 3 3 0 2 3 1 3 0 0 1 0 1 1 1 0 0 0 0 1 1 1 2 1 4 0 0 1
## [334] 1 0 1 1 0 0 4 4 4 1 1 3 2 0 4 1 0 2 3 2 1 3 0 2 3 5 2 0 3 0 0 2 2 2 4 1 0
## [371] 3 1 1 0 0 0 0 0 0 0 0 0 1 1 0 1 0 3 1 0 2 0 2 1 0 0 1 2 5 1 1 2 2 3 0 0 0
## [408] 1 0 2 2 3 1 1 0 1 2 1 0 0 0 1 1 0 1 2 2 0 0 3 0 1 0 1 0 0 3 1 3 1 1 2 2 2
## [445] 3 0 2 1 1 0 0 0 1 0 0 0 4 2 0 1 2 4 0 2 1 1 0 0 0 0 0 0 0 1 2 0 2 3 1 4 0
## [482] 4 0 2 0 1 1 0 2 0 0 5 0 1 2 1 4 2 2 0 0 0 1 0 2 1 0 0 2 3 3 1 0 0 0 1 0 0
## [519] 2 2 2 1 1 0 2 0 0 0 1 1 2 0 1 2 1 1 0 0 1 0 0 0 4 3 1 0 1 1 0 0 0 4 0 0 0
## [556] 1 3 1 1 3 0 0 1 0 0 0 1 1 0 1 0 3 0 1 0 3 2
##
## $centralization
## [1] 0.01025664
##
## $theoretical_max
## [1] 331200
N3. Plotting
General network graph
set.seed(100)
par(mar=c(0,0,2,0))
plot(inv_aff_ig,
vertex.label=NA,
vertex.size=1.5,
vertex.frame.color="black",
vertex.color = V(inv_aff_ig),
main="Inventor network of top 15 cities\nfor 1996-2016")

Plotting with density
set.seed(100)
par(mar=c(0,0,4,0))
plot(inv_aff_ig,
vertex.label=NA,
vertex.size=degree(inv_aff_ig)*1.5,
vertex.frame.color="black",
vertex.color = V(inv_aff_ig),
main="Inventor network of top 15 cities\nfor 1996-2016\nwith degree measurement")

Plotting with density and edge betweenness
set.seed(100)
par(mar=c(0,0,4,0))
plot(inv_aff_ig,
vertex.label=NA,
vertex.frame.color="black",
vertex.color=V(inv_aff_ig),
vertex.size=degree(inv_aff_ig)*1.5,
edge.curved=.1,
main="Inventor network of top 15 cities\nfor 1996-2016\nwith degree measurement and edge betweenness",
edge.width = edge_betweenness(inv_aff_ig)*.8)

Top 5 City’s Innovation Scenario over the Time
Detaching packages to avoid conflicts between package operations
detach(package:igraph)
suppressMessages(library(network))
Aurich
## Aurich 1996:2006 network
aurich_data_06 <- (data_main_15_attr %>%
filter(city=="Aurich", app_year>=1996 & app_year<=2006) %>%
select(inv_name, appln_id))
aurich_data_06 <- table(aurich_data_06)
dim(aurich_data_06)
## [1] 4 170
aurich_adj_06 <- aurich_data_06 %*% t(aurich_data_06)
dim(aurich_adj_06)
## [1] 4 4
class(aurich_adj_06)
## [1] "matrix" "array"
aurich_nw_06 <- network(aurich_adj_06,
matrix.type="adjacency",
directed=F) # convert into 'network' format
## Aurich 2007:2016 network
aurich_data_16 <- (data_main_15_attr %>%
filter(city=="Aurich", app_year>=2007 & app_year<=2016) %>%
select(inv_name, appln_id))
aurich_data_16 <- table(aurich_data_16)
dim(aurich_data_16)
## [1] 50 101
aurich_adj_16 <- aurich_data_16 %*% t(aurich_data_16)
dim(aurich_adj_16)
## [1] 50 50
class(aurich_adj_16)
## [1] "matrix" "array"
aurich_nw_16 <- network(aurich_adj_16,
matrix.type="adjacency",
directed=F) # convert into 'network' format
Plotting
par(mfrow = c(1,2))
par(mar=c(3,0,1,0))
#plot for 1996:2006
plot.network(aurich_nw_06,
vertex.col="#7570B3",
vertex.cex=1,
vertex.border="black",
main="Inventors Network for Aurich 1996:2006",
pad=4,
frame = T,
sub=network.size(aurich_nw_06),
cex.main=.8)
# plot for 2007:2016
plot.network(aurich_nw_16,
vertex.col="#7570B3",
vertex.cex=1,
vertex.border="black",
main="Inventors Network for Aurich 2007:2016",
frame = T,
cex.main=.8)

cat("Total nodes 1996-2006:", network.size(aurich_nw_06),"\nTotal nodes 2007-2016:", network.size(aurich_nw_16))
## Total nodes 1996-2006: 4
## Total nodes 2007-2016: 50
Hamburg
## Hamburg 1996:2006 network
hamburg_data_06 <- (data_main_15_attr %>%
filter(city=="Hamburg", app_year>=1996 & app_year<=2006) %>%
select(inv_name, appln_id))
hamburg_data_06 <- table(hamburg_data_06)
dim(hamburg_data_06)
## [1] 12 14
hamburg_adj_06 <- hamburg_data_06 %*% t(hamburg_data_06)
dim(hamburg_adj_06)
## [1] 12 12
class(hamburg_adj_06)
## [1] "matrix" "array"
hamburg_nw_06 <- network(hamburg_adj_06,
matrix.type="adjacency",
directed=F) # convert into 'network' format
## Hamburg 2007:2006 network
hamburg_data_16 <- (data_main_15_attr %>%
filter(city=="Hamburg", app_year>=2007 & app_year<=2016) %>%
select(inv_name, appln_id))
hamburg_data_16 <- table(hamburg_data_16)
dim(hamburg_data_16)
## [1] 113 152
hamburg_adj_16 <- hamburg_data_16 %*% t(hamburg_data_16)
dim(hamburg_adj_16)
## [1] 113 113
class(hamburg_adj_16)
## [1] "matrix" "array"
hamburg_nw_16 <- network(hamburg_adj_16,
matrix.type="adjacency",
directed=F) # convert into 'network' format
Plotting
par(mfrow = c(1,2))
par(mar=c(0,0,1,0))
#plot for 1996:2006
plot.network(hamburg_nw_06,
vertex.col="#99B898",
vertex.cex=1,
vertex.border="black",
main="Inventors Network for Hamburg 1996:2006",
frame = T,
pad=4,
cex.main=.8)
# plot for 2007:2016
plot.network(hamburg_nw_16,
vertex.col="#99B898",
vertex.cex=1,
vertex.border="black",
main="Inventors Network for Hamburg 2007:2016",
frame = T,
cex.main=.8)

cat("Total nodes 1996-2006:", network.size(hamburg_nw_06),"\nTotal nodes 2007-2016:", network.size(hamburg_nw_16))
## Total nodes 1996-2006: 12
## Total nodes 2007-2016: 113
Berlin
## Berlin 1996:2006 network
berlin_data_06 <- (data_main_15_attr %>%
filter(city=="Berlin", app_year>=1996 & app_year<=2006) %>%
select(inv_name, appln_id))
berlin_data_06 <- table(berlin_data_06)
dim(berlin_data_06)
## [1] 25 21
berlin_adj_06 <- berlin_data_06 %*% t(berlin_data_06)
dim(berlin_adj_06)
## [1] 25 25
class(berlin_adj_06)
## [1] "matrix" "array"
berlin_nw_06 <- network(berlin_adj_06,
matrix.type="adjacency",
directed=F) # convert into 'network' format
## Berlin 2007:2016 network
berlin_data_16 <- (data_main_15_attr %>%
filter(city=="Berlin", app_year>=2007 & app_year<=2016) %>%
select(inv_name, appln_id))
berlin_data_16 <- table(berlin_data_16)
dim(berlin_data_16)
## [1] 75 89
berlin_adj_16 <- berlin_data_16 %*% t(berlin_data_16)
dim(berlin_adj_16)
## [1] 75 75
class(berlin_adj_16)
## [1] "matrix" "array"
berlin_nw_16 <- network(berlin_adj_16,
matrix.type="adjacency",
directed=F) # convert into 'network' format
Plotting
par(mfrow = c(1,2))
par(mar=c(0,0,1,0))
#plot for 1996:2006
plot.network(berlin_nw_06,
vertex.col="#F26B38",
vertex.cex=1,
vertex.border="black",
main="Inventors Network for Berlin 1996:2006",
frame = T,
pad=4,
cex.main=.8)
# plot for 2007:2016
plot.network(berlin_nw_16,
vertex.col="#F26B38",
vertex.cex=1,
vertex.border="black",
main="Inventors Network for Berlin 2007:2016",
frame = T,
cex.main=.8)

cat("Total nodes 1996-2006:", network.size(berlin_nw_06),"\nTotal nodes 2007-2016:", network.size(berlin_nw_16))
## Total nodes 1996-2006: 25
## Total nodes 2007-2016: 75
Salzbergen
## Salzbergen 1996:2006 network
salzbergen_data_06 <- (data_main_15_attr %>%
filter(city=="Salzbergen", app_year>=1996 & app_year<=2006) %>%
select(inv_name, appln_id))
salzbergen_data_06 <- table(salzbergen_data_06)
dim(salzbergen_data_06)
## [1] 2 4
salzbergen_adj_06 <- salzbergen_data_06 %*% t(salzbergen_data_06)
dim(salzbergen_adj_06)
## [1] 2 2
class(salzbergen_adj_06)
## [1] "matrix" "array"
salzbergen_nw_06 <- network(salzbergen_adj_06,
matrix.type="adjacency",
directed=F) # convert into 'network' format
## Salzbergen 2007:2017 network
salzbergen_data_16 <- (data_main_15_attr %>%
filter(city=="Salzbergen", app_year>=2007 & app_year<=2016) %>%
select(inv_name, appln_id))
salzbergen_data_16 <- table(salzbergen_data_16)
dim(salzbergen_data_16)
## [1] 86 97
salzbergen_adj_16 <- salzbergen_data_16 %*% t(salzbergen_data_16)
dim(salzbergen_adj_16)
## [1] 86 86
class(salzbergen_adj_16)
## [1] "matrix" "array"
salzbergen_nw_16 <- network(salzbergen_adj_16,
matrix.type="adjacency",
directed=F) # convert into 'network' format
Plotting
par(mfrow = c(1,2))
par(mar=c(0,0,1,0))
#plot for 1996:2006
plot.network(salzbergen_nw_06,
vertex.col="#594F4F",
vertex.cex=1,
vertex.border="black",
main="Inventors Network for Salzbergen 1996:2006",
frame = T,
pad=4,
cex.main=.8)
# plot for 2007:2016
plot.network(salzbergen_nw_16,
vertex.col="#594F4F",
vertex.cex=1,
vertex.border="black",
main="Inventors Network for Salzbergen 2007:2016",
frame = T,
cex.main=.8)

cat("Total nodes 1996-2006:", network.size(salzbergen_nw_06),"\nTotal nodes 2007-2016:", network.size(salzbergen_nw_16))
## Total nodes 1996-2006: 2
## Total nodes 2007-2016: 86
Rendsburg
## Rendsburg 1996:2006 network
rendsburg_data_06 <- (data_main_15_attr %>%
filter(city=="Rendsburg", app_year>=1996 & app_year<=2006) %>%
select(inv_name, appln_id))
rendsburg_data_06 <- table(rendsburg_data_06)
dim(rendsburg_data_06)
## [1] 10 25
rendsburg_adj_06 <- rendsburg_data_06 %*% t(rendsburg_data_06)
dim(rendsburg_adj_06)
## [1] 10 10
class(rendsburg_adj_06)
## [1] "matrix" "array"
rendsburg_nw_06 <- network(rendsburg_adj_06,
matrix.type="adjacency",
directed=F) # convert into 'network' format
## Rendsburg 200:2016 network
rendsburg_data_16 <- (data_main_15_attr %>%
filter(city=="Rendsburg", app_year>=2007 & app_year<=2016) %>%
select(inv_name, appln_id))
rendsburg_data_16 <- table(rendsburg_data_16)
dim(rendsburg_data_16)
## [1] 13 51
rendsburg_adj_16 <- rendsburg_data_16 %*% t(rendsburg_data_16)
dim(rendsburg_adj_16)
## [1] 13 13
class(rendsburg_adj_16)
## [1] "matrix" "array"
rendsburg_nw_16 <- network(rendsburg_adj_16,
matrix.type="adjacency",
directed=F) # convert into 'network' format
Plotting
par(mfrow = c(1,2))
par(mar=c(0,0,1,0))
#plot for 1996:2006
plot.network(rendsburg_nw_06,
vertex.col="#355C7D",
vertex.cex=1,
vertex.border="black",
main="Inventors Network for Rendsburg 1996:2006",
frame = T,
pad=4,
cex.main=.8)
# plot for 2007:2016
plot.network(rendsburg_nw_16,
vertex.col="#355C7D",
vertex.cex=1,
vertex.border="black",
main="Inventors Network for Rendsburg 2007:2016",
frame = T,
cex.main=.8)

cat("Total nodes 1996-2006:", network.size(rendsburg_nw_06),"\nTotal nodes 2007-2016:", network.size(rendsburg_nw_16))
## Total nodes 1996-2006: 10
## Total nodes 2007-2016: 13
Position of the Top 5 Cities in 15 City’s Network
Detaching packages to avoid conflicts between package operations.
detach(package:network)
suppressMessages(library(igraph))
Aurich
## position of the cities in the overall network
inv_person_parsed$city <- inv_per_attr$city[match(inv_person_parsed$appln_id, inv_person_parsed$appln_id)]
V(inv_aff_ig)$id <- colnames(inv_person_adj)
V(inv_aff_ig)$city_name <- inv_person_parsed$city[match(V(inv_aff_ig)$id, inv_person_parsed$inv_name)]
V(inv_aff_ig)$id <- colnames(inv_person_adj)
V(inv_aff_ig)$city_name_color <- ifelse(V(inv_aff_ig)$city_name == "Aurich", "red","azure1")
#V(inv_aff_ig)$id[degree(inv_aff_ig)>5]
#degree(inv_aff_ig)
set.seed(100)
par(mar=c(0,0,1,0))
plot(inv_aff_ig,
layout = layout.auto(inv_aff_ig),
vertex.size = 3,
vertex.frame.color="black",
vertex.color = V(inv_aff_ig)$city_name_color,
vertex.label = NA,
edge.color= "black",
main="Inventors from Aurich in top 15 city's network")

Hamburg
## position of the cities in the overall network
inv_person_parsed$city <- inv_per_attr$city[match(inv_person_parsed$appln_id, inv_person_parsed$appln_id)]
V(inv_aff_ig)$id <- colnames(inv_person_adj)
V(inv_aff_ig)$city_name <- inv_person_parsed$city[match(V(inv_aff_ig)$id, inv_person_parsed$inv_name)]
V(inv_aff_ig)$id <- colnames(inv_person_adj)
V(inv_aff_ig)$city_name_color <- ifelse(V(inv_aff_ig)$city_name == "Hamburg", "blue","azure1")
#V(inv_aff_ig)$id[degree(inv_aff_ig)>5]
#degree(inv_aff_ig)
set.seed(100)
par(mar=c(0,0,1,0))
plot(inv_aff_ig,
layout = layout.auto(inv_aff_ig),
vertex.size = 3,
vertex.frame.color="black",
vertex.color = V(inv_aff_ig)$city_name_color,
vertex.label = NA,
edge.color= "black",
main="Inventors from Hamburg in top 15 city's network")

Berlin
## position of the cities in the overall network
inv_person_parsed$city <- inv_per_attr$city[match(inv_person_parsed$appln_id, inv_person_parsed$appln_id)]
V(inv_aff_ig)$id <- colnames(inv_person_adj)
V(inv_aff_ig)$city_name <- inv_person_parsed$city[match(V(inv_aff_ig)$id, inv_person_parsed$inv_name)]
V(inv_aff_ig)$id <- colnames(inv_person_adj)
V(inv_aff_ig)$city_name_color <- ifelse(V(inv_aff_ig)$city_name == "Berlin", "darkslategray4","azure1")
#V(inv_aff_ig)$id[degree(inv_aff_ig)>5]
#degree(inv_aff_ig)
set.seed(100)
par(mar=c(0,0,1,0))
plot(inv_aff_ig,
layout = layout.auto(inv_aff_ig),
vertex.size = 3,
vertex.frame.color="black",
vertex.color = V(inv_aff_ig)$city_name_color,
vertex.label = NA,
edge.color= "black",
main="Inventors from Berlin in top 15 city's network")

Salzbergen
## position of the cities in the overall network
inv_person_parsed$city <- inv_per_attr$city[match(inv_person_parsed$appln_id, inv_person_parsed$appln_id)]
V(inv_aff_ig)$id <- colnames(inv_person_adj)
V(inv_aff_ig)$city_name <- inv_person_parsed$city[match(V(inv_aff_ig)$id, inv_person_parsed$inv_name)]
V(inv_aff_ig)$id <- colnames(inv_person_adj)
V(inv_aff_ig)$city_name_color <- ifelse(V(inv_aff_ig)$city_name == "Salzbergen", "darkorange1","azure1")
#V(inv_aff_ig)$id[degree(inv_aff_ig)>5]
#degree(inv_aff_ig)
set.seed(100)
par(mar=c(0,0,1,0))
plot(inv_aff_ig,
layout = layout.auto(inv_aff_ig),
vertex.size = 3,
vertex.frame.color="black",
vertex.color = V(inv_aff_ig)$city_name_color,
vertex.label = NA,
edge.color= "black",
main="Inventors from Salzbergen in top 15 city's network")

Rendsburg
## position of the cities in the overall network
inv_person_parsed$city <- inv_per_attr$city[match(inv_person_parsed$appln_id, inv_person_parsed$appln_id)]
V(inv_aff_ig)$id <- colnames(inv_person_adj)
V(inv_aff_ig)$city_name <- inv_person_parsed$city[match(V(inv_aff_ig)$id, inv_person_parsed$inv_name)]
V(inv_aff_ig)$id <- colnames(inv_person_adj)
V(inv_aff_ig)$city_name_color <- ifelse(V(inv_aff_ig)$city_name == "Rendsburg", "darkmagenta","azure1")
#V(inv_aff_ig)$id[degree(inv_aff_ig)>5]
#degree(inv_aff_ig)
set.seed(100)
par(mar=c(0,0,1,0))
plot(inv_aff_ig,
layout = layout.auto(inv_aff_ig),
vertex.size = 3,
vertex.frame.color="black",
vertex.color = V(inv_aff_ig)$city_name_color,
vertex.label = NA,
edge.color= "black",
main="Inventors from Rendsburg in top 15 city's network")

Inventors by Highest Degree (>6)
inv_person_parsed$city <- inv_per_attr$city[match(inv_person_parsed$appln_id, inv_person_parsed$appln_id)]
V(inv_aff_ig)$id <- colnames(inv_person_adj)
V(inv_aff_ig)$city_name <- inv_person_parsed$city[match(V(inv_aff_ig)$id, inv_person_parsed$inv_name)]
V(inv_aff_ig)$id <- colnames(inv_person_adj)
V(inv_aff_ig)$city_name_color <- ifelse(V(inv_aff_ig)$city_name == "Aurich", "yellow", "gray")
Position in the network
set.seed(100)
par(mar=c(0,0,1,0))
plot(inv_aff_ig,
layout = layout.auto(inv_aff_ig),
vertex.size = degree(inv_aff_ig),
vertex.color = NA,
vertex.label = ifelse(degree(inv_aff_ig)> 6, V(inv_aff_ig)$id, NA),
main="Higehst Degree Inventors")

City affiliation of the inventors
high_degree_inv <- as.data.frame(unique(high_degree_inv <- (inv_person_parsed %>%
filter(inv_name %in% c("altemark, jens","harms, ulrich","jurkat, mark")) %>%
select(inv_name, city))))
high_degree_inv %>%
knitr::kable(caption = "Inventors with Highest Degree and Their City Affilitions") %>%
kable_styling(bootstrap_options = c("striped","responsive", "hover"), full_width = F)
Inventors with Highest Degree and Their City Affilitions
|
inv_name
|
city
|
|
jurkat, mark
|
Norderstedt
|
|
harms, ulrich
|
Norderstedt
|
|
altemark, jens
|
Rendsburg
|
|
altemark, jens
|
Berlin
|
|
harms, ulrich
|
Hamburg
|
|
altemark, jens
|
Kiel
|
LS0tDQp0aXRsZTogIklubm92YXRpb24gU2NlbmFyaW8gaW4gR2VybWFuIFdpbmQgTW90b3IgSW5kdXN0cnkgKDE5OTYtMjAxNikiDQpzdWJ0aXRsZTogIkEgU29jaWFsIE5ldHdvcmsgQW5hbHlzaXMgQXBwcm9hY2giDQphdXRob3I6ICJKaGFsYWsgR29wZSINCmRhdGU6ICcyMDIyLTA3LTEzJw0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIGNvZGVfZG93bmxvYWQ6IHRydWUNCiAgICBjc3M6IGNzc19iYWNrLmNzcw0KICAgIHRoZW1lOiB5ZXRpDQogICAgdG9jX2RlcHRoOiA1DQogICAgdG9jOiB0cnVlDQogICAgdG9jX2Zsb2F0OiB0cnVlDQotLS0NCg0KYGBge3Igc2V0dXAsIGluY2x1ZGU9VFJVRX0NCmtuaXRyOjpvcHRzX2NodW5rJHNldCh3YXJuaW5nID0gRkFMU0UpDQpgYGANCg0KIyBHZW5lcmFsIERhdGEgUHJlcGFyYXRpb24NCg0KIyMgTG9hZGluZyBMaWJyYXJpZXMNCg0KYGBge3IgbG9hZGluZyBsaWJyYXJpZXMsIHdhcm5pbmc9RkFMU0UsIHJlc3VsdHM9ImhpZGUifQ0Kc3VwcHJlc3NNZXNzYWdlcyhsaWJyYXJ5KHNuYSkpDQpzdXBwcmVzc01lc3NhZ2VzKGxpYnJhcnkoZHBseXIpKQ0Kc3VwcHJlc3NNZXNzYWdlcyhsaWJyYXJ5KGdnc2NpKSkNCnN1cHByZXNzTWVzc2FnZXMobGlicmFyeShwbG90bHkpKQ0Kc3VwcHJlc3NNZXNzYWdlcyhsaWJyYXJ5KGlncmFwaCkpDQpzdXBwcmVzc01lc3NhZ2VzKGxpYnJhcnkobmV0d29yaykpDQpzdXBwcmVzc01lc3NhZ2VzKGxpYnJhcnkoa2FibGVFeHRyYSkpDQpzdXBwcmVzc01lc3NhZ2VzKGxpYnJhcnkoaWdyYXBoZGF0YSkpDQpzdXBwcmVzc01lc3NhZ2VzKGxpYnJhcnkoaW50ZXJncmFwaCkpDQpzdXBwcmVzc01lc3NhZ2VzKGxpYnJhcnkoUkNvbG9yQnJld2VyKSkNCmBgYA0KDQojIyBMb2FkaW5nIERhdGFzZXQNCg0KYGBge3IgbG9hZGluZyBkYXRhc2V0fQ0KbG9hZCgicmVzX3NlbS5SRGF0YSIpDQojc3ViIHN0cmluZ2luZyB0aGUgSVBDMyBmcm9tIElQQw0KSVBDNCA8LSBzdWJzdHIoam9pbmVkX0lQQ19JbnYkSVBDLCBzdGFydCA9IDEsIHN0b3AgPSA0KSAjZXh0cmFjdGluZyB0aGUgSVBDMyBmcm9tIHRoZSBvcmlnaW5hbCBzb3J0ZWQgZGF0YXNldA0KSVBDNCA8LSBhcy5kYXRhLmZyYW1lKElQQzQpICMgZGVmaW5pbmcgaXQgYXMgYSBkYXRhZnJhbWUNCmRhdGFfZmluYWwgPC0gY2JpbmQoam9pbmVkX0lQQ19JbnYsIElQQzQpICMgY29tYmluaW5nIHRoZSBuZXdseSBjcmVhdGVkIElQQzMgY29udGFpbmluZyBkYXRhZnJhbWUgd2l0aCB0aGUgbWFpbiBkYXRhZnJhbWUNCnJtKGpvaW5lZF9JUENfSW52KSAmIHJtKElQQzQpICMgcmVtb3ZpbmcgdGhlIGRhdGFzZXQgdG8gZnJlZSBtZW1vcnkNCmRhdGFfZmluYWwgPC0gc3Vic2V0KGRhdGFfZmluYWwsIHNlbGVjdCA9IC1jKElQQyxjdHJ5X2NvZGUpKSAjIGRyb3BwaW5nIGNvbHVtbnMNCmBgYA0KDQojIyBEYXRhIENsZWFuaW5nDQoNCmBgYHtyIGRhdGEgY2xlYW5pbmd9DQpkYXRhIDwtIChkYXRhX2ZpbmFsICU+JSANCiAgICAgICAgICAgICAgICAgZmlsdGVyKElQQzQ9PSJGMDNEIikpICMgY3JlYXRpbmcgc3Vic2V0IG9mIFdpbmQgRW5lcmd5IEluZHVzdHJ5IChGMDNEKQ0Kcm0oZGF0YV9maW5hbCkNCmRhdGEgPC0gKGRhdGEgJT4lIA0KICAgICAgICAgICBmaWx0ZXIoYXBwX3llYXI+PSAxOTk2ICYgYXBwX3llYXIgPD0gMjAxNikpICMgbGltaXRpbmcgeWVhcnMgZnJvbSAxOTk2IHRvIDIwMTYNCg0KIyBub3cgZ2V0dGluZyByaWQgb2YgZW1wdHkgY2l0eSB2YWx1ZXMNCmRhdGEgPC0gKGRhdGEgJT4lDQogICAgICAgICAgIG11dGF0ZShjaXR5ID0gcmVwbGFjZShjaXR5LCBjaXR5ID09ICIiLCBOQSkpKSNtYWtpbmcgdGhlIGVtcHR5IHZhbHVlcyBOQQ0KZGF0YSA8LSBuYS5vbWl0KGRhdGEpICNnZXR0aW5nIHJpZCBvZiBOQSB2YWx1ZXMNCg0KIyBnZXR0aW5nIHJpZCBvZiBkdXBsaWNhdGUgdmFsdWVzDQpkYXRhX21haW4gPC0gZGF0YVshZHVwbGljYXRlZChkYXRhKSxdDQoNCiMgcmFua2luZyBjaXRpZXMgYWNjb3JkaW5nIHRvIHBhdGVudHMNCmRhdGFfbWFpbl9jaXR5X3JhbmsgPC0gKGRhdGFfbWFpbiAlPiUgDQogICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwX2J5KGNpdHkpICU+JQ0KICAgICAgICAgICAgICAgICAgICAgICAgICBjb3VudChjaXR5LCBzb3J0ID0gVFJVRSwgIG5hbWUgPSAicGF0ZW50cyIpKSAjcmFua2luZyB0aGUgY2l0aWVzIGFjY29yZGluZyB0byB0aGUgbnVtYmVyIG9mIHBhdGVudCBhcHBsaWNhdGlvbnMNCg0KZGF0YV9tYWluXzE1IDwtIGhlYWQoZGF0YV9tYWluX2NpdHlfcmFuaywxNSkgIyBrZWVwaW5nIGZpcnN0IDE1IHBhdGVudCBvd25pbmcgY2l0aWVzIGluIHJhbmtlZCBmb3JtYXQNCmRhdGFfbWFpbl8xNV9hdHRyIDwtIChkYXRhX21haW4gJT4lDQogICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoY2l0eSAlaW4lIGMoIkF1cmljaCIsIkhhbWJ1cmciLCJCZXJsaW4iLCJTYWx6YmVyZ2VuIiwiUmVuZHNidXJnIiwiUmhlaW5lIiwiS2llbCIsIkFhY2hlbiIsIk11bmNoZW4iLCJOb3JkZXJzdGVkdCIsIk9zbmFicnVjayIsIkJyZW1lbiIsIkVybGFuZ2VuIiwiRHJlc2RlbiIsIk11bnN0ZXIiKSkpICMga2VlcGluZyB0aGUgbW9zdCAxNSBwYXRlbnQgb3duaW5nIGNpdGllcyB3aXRoIGFsbCBhdHRyaWJ1dGVzDQpgYGANCg0KIyBHZW5lcmFsIEluc2lnaHRzIGZyb20gdGhlIERhdGENCg0KIyMgVG9wIDE1IG1vc3QgcGF0ZW50IG93bmluZyBjaXRpZXMNCg0KYGBge3IgdG9wIG1vc3QgaW5ub3ZhdGl2ZSBjaXRpZXMsIGVjaG89RkFMU0UsIGZpZy5oZWlnaHQ9NywgZmlnLndpZHRoPTgsIHJlc3VsdHM9ImFzaXMifQ0KcGxvdF9seShkYXRhX21haW5fMTUsDQogICAgICAgIHggPSBkYXRhX21haW5fMTUkY2l0eSwNCiAgICAgICAgeSA9IGRhdGFfbWFpbl8xNSRwYXRlbnRzLA0KICAgICAgICB0eXBlID0gImJhciIsDQogICAgICAgIGNvbG9yID0gZGF0YV9tYWluXzE1JGNpdHksDQogICAgICAgIHNob3dsZWdlbmQgPSBGQUxTRSwNCiAgICAgICAgY29sb3JzPXBhbF9qY28oKSgxMCkpICU+JSANCiAgbGF5b3V0KHRpdGxlID0gIlRvcCAxNSBHZXJtYW4gQ2l0aWVzIGluIFdpbmQgTW90b3IgSW5ub3ZhdGlvbiIsDQogICAgICAgICB4YXhpcyA9IGxpc3QodGl0bGUgPSAiIiwNCiAgICAgICAgICAgICAgICAgICAgICBjYXRlZ29yeW9yZGVyID0gImFycmF5IiwNCiAgICAgICAgICAgICAgICAgICAgICBjYXRlZ29yeWFycmF5ID0gfmNpdHkpLA0KICAgICAgICAgeWF4aXMgPSBsaXN0KHRpdGxlID0gIk51bWJlciBvZiBwYXRlbnRzIikNCiAgICAgICAgICkNCmBgYA0KDQojIE5ldHdvcmsgRGF0YSBQcmVwYXJhdGlvbiAoVXNpbmcgaWdyYXBoIGFuZCBzbmEgcGFja2FnZXMpDQoNCiMjIE4xLiBJbnZlbnRvciBuZXR3b3JrcyBmb3IgYWxsIGNpdGllcw0KDQpgYGB7ciBpbnYgbmV0IGFsbCBjaXRpZXN9DQppbnZfYWZmX2FsbCA8LSAoZGF0YV9tYWluICU+JSANCiAgICAgICAgICAgICAgc2VsZWN0KGFwcGxuX2lkLHBlcnNvbl9pZCkpDQppbnZfYWZmX2FsbF8ybW9kZSA8LSB0YWJsZShpbnZfYWZmX2FsbCkNCmludl9hZmZfYWxsX2FkaiA8LSBpbnZfYWZmX2FsbF8ybW9kZSAlKiUgdChpbnZfYWZmX2FsbF8ybW9kZSkNCmRpYWcoaW52X2FmZl9hbGxfYWRqKSA8LTAgIyBkZWxldGluZyB0aGUgZGlhZ29uYWxzDQppbnZfYWZmX2FsbF9pZyA8LSBncmFwaC5hZGphY2VuY3koaW52X2FmZl9hbGxfYWRqLCBtb2RlID0gInVuZGlyZWN0ZWQiLCB3ZWlnaHQgPSBUUlVFKQ0KcHJpbnQoaW52X2FmZl9hbGxfaWcpICMgQmFzaWMgaW5mb3JtYXRpb24gYWJvdXQgdGhlIG5ldHdvcmsNCmBgYA0KDQojIyBOMi4gQ2l0eSBuZXR3b3JrcyAoZm9yIDE1IG1vc3QgaW5ub3ZhdGl2ZSBjaXRpZXMpDQoNCmBgYHtyIGNpdHkgbmV0IDE1IGNpdGllc30NCmludl9jaXR5IDwtIChkYXRhX21haW5fMTVfYXR0ciAlPiUgDQogICAgICAgICAgICAgICBzZWxlY3QoY2l0eSwgYXBwbG5faWQpKQ0KaW52X2NpdHlfMm1vZGUgPC0gIHRhYmxlKGludl9jaXR5KSAgICMgY3Jvc3MgdGFidWxhdGUgLT4gMi1tb2RlIHNvY2lvbWF0cml4DQppbnZfY2l0eV9hZGogPC0gaW52X2NpdHlfMm1vZGUgJSolIHQoaW52X2NpdHlfMm1vZGUpDQpkaWFnKGludl9jaXR5X2FkaikgPC0wICMgZGVsZXRpbmcgdGhlIGRpYWdvbmFscw0KaW52X2NpdHlfaWcgPC0gZ3JhcGguYWRqYWNlbmN5KGludl9jaXR5X2FkaiwgbW9kZSA9ICJ1bmRpcmVjdGVkIiwgd2VpZ2h0ID0gVFJVRSkNCnByaW50KGludl9jaXR5X2lnKSAjIGJhc2ljIGluZm9ybWF0aW9uIGFib3V0IHRoZSBuZXR3b3JrDQoNCmBgYA0KDQojIyBOMy4gSW52ZW50b3IncyBuZXR3b3JrIG9mIHRvcCAxNSBjaXRpZXMNCg0KYGBge3IgaW52IG5ldH0NCiMgaW52ZW50b3IncyBkYXRhIGNsZWFuaW5nDQppbnZfcGVyc29uIDwtIChkYXRhX21haW5fMTVfYXR0ciAlPiUgDQogICAgICAgICAgICAgICAgIHNlbGVjdChpbnZfbmFtZSxhcHBsbl9pZCkpICMgc3ViLXNldHRpbmcgdGhlIGRhdGEgZm9yIGludmVudG9ycyB3aXRoIHBhdGVudHMNCmludl9wZXJfYXR0ciA8LSAoZGF0YV9tYWluXzE1X2F0dHIgJT4lIA0KICAgICAgICAgICAgICAgICAgIHNlbGVjdChhcHBsbl9pZCwgY2l0eSkpDQoNCiMgcGFyc2luZyB0aGUgcGVyc29uJ3MgbmV0d29yayBkYXRhIHRvIGhhdmUgY2xlYW4gYW5kIG5vbi1kdXBsaWNhdGVkIHZhbHVlcw0KaW52X3BlcnNvbl9wYXJzZWQgPC0gaW52X3BlcnNvbg0KbGVuZ3RoKHVuaXF1ZShpbnZfcGVyc29uX3BhcnNlZCRpbnZfbmFtZSkpDQppbnZfcGVyc29uX3BhcnNlZCRpbnZfbmFtZV9zbWFsbCA8LSB0b2xvd2VyKGludl9wZXJzb25fcGFyc2VkJGludl9uYW1lKQ0KaW52X3BlcnNvbl9wYXJzZWQkaW52X25hbWVfc21hbGwgPC0gc3ViKCIsIHByb2YuIGRyLi1pbmcuIiwiIiwgaW52X3BlcnNvbl9wYXJzZWQkaW52X25hbWVfc21hbGwpDQpsZW5ndGgodW5pcXVlKGludl9wZXJzb25fcGFyc2VkJGludl9uYW1lX3NtYWxsKSkNCmludl9wZXJzb25fcGFyc2VkJGludl9uYW1lX3NtYWxsIDwtIHN1YigiLCBkci4taW5nLiIsIiIsIGludl9wZXJzb25fcGFyc2VkJGludl9uYW1lX3NtYWxsKQ0KbGVuZ3RoKHVuaXF1ZShpbnZfcGVyc29uX3BhcnNlZCRpbnZfbmFtZV9zbWFsbCkpDQppbnZfcGVyc29uX3BhcnNlZCRpbnZfbmFtZV9zbWFsbCA8LSBzdWIoIiwgZGlwbC4taW5nLiIsIiIsIGludl9wZXJzb25fcGFyc2VkJGludl9uYW1lX3NtYWxsKQ0KbGVuZ3RoKHVuaXF1ZShpbnZfcGVyc29uX3BhcnNlZCRpbnZfbmFtZV9zbWFsbCkpDQppbnZfcGVyc29uX3BhcnNlZCRpbnZfbmFtZV9zbWFsbCA8LSBzdWIoIiwgLWluZy4iLCIiLCBpbnZfcGVyc29uX3BhcnNlZCRpbnZfbmFtZV9zbWFsbCkNCmxlbmd0aCh1bmlxdWUoaW52X3BlcnNvbl9wYXJzZWQkaW52X25hbWVfc21hbGwpKQ0KaW52X3BlcnNvbl9wYXJzZWQkaW52X25hbWVfc21hbGwgPC0gc3ViKCIsIGRyLiIsIiIsIGludl9wZXJzb25fcGFyc2VkJGludl9uYW1lX3NtYWxsKQ0KbGVuZ3RoKHVuaXF1ZShpbnZfcGVyc29uX3BhcnNlZCRpbnZfbmFtZV9zbWFsbCkpDQppbnZfcGVyc29uX3BhcnNlZCRpbnZfbmFtZV9zbWFsbCA8LSBzdWIoIiBkci4iLCIiLCBpbnZfcGVyc29uX3BhcnNlZCRpbnZfbmFtZV9zbWFsbCkNCmxlbmd0aCh1bmlxdWUoaW52X3BlcnNvbl9wYXJzZWQkaW52X25hbWVfc21hbGwpKQ0KDQojIG5ldyBuZXR3b3JrIGNoYW5nZWQgc2l6ZQ0KbGVuZ3RoKHVuaXF1ZShpbnZfcGVyc29uX3BhcnNlZCRpbnZfbmFtZV9zbWFsbCkpL2xlbmd0aCh1bmlxdWUoaW52X3BlcnNvbl9wYXJzZWQkaW52X25hbWUpKQ0KDQojIGdldHRpbmcgcmlkIG9mIG9yaWdpbmFsIGludmVudG9yIG5hbWVzDQppbnZfcGVyc29uX3BhcnNlZCRpbnZfbmFtZSA8LSBpbnZfcGVyc29uX3BhcnNlZCRpbnZfbmFtZV9zbWFsbA0KDQojIHJlbW92aW5nIHRoaXJkIGNvbHVtbg0KaW52X3BlcnNvbl9wYXJzZWQgPC0gc3Vic2V0KGludl9wZXJzb25fcGFyc2VkLCBzZWxlY3QgPSAtYyhpbnZfbmFtZV9zbWFsbCkpDQoNCiMgY3JlYXRpbmcgbmV0d29yayB3aXRoIHRoZSBjbGVhbmVkIGRhdGENCmludl9wZXJzb25fMm1vZGUgPC0gdGFibGUoaW52X3BlcnNvbl9wYXJzZWQpICMgbWFraW5nIDIgbW9kZSBzb2Npb21hdHJpeA0KaW52X3BlcnNvbl9hZGogPC0gaW52X3BlcnNvbl8ybW9kZSAlKiUgdChpbnZfcGVyc29uXzJtb2RlKQ0KZGlhZyhpbnZfcGVyc29uX2FkaikgPC0wDQppbnZfYWZmX2lnIDwtIGdyYXBoLmFkamFjZW5jeShpbnZfcGVyc29uX2FkaiwgbW9kZSA9ICJ1bmRpcmVjdGVkIiwgd2VpZ2h0ID0gVFJVRSkNCg0KDQpgYGANCg0KIyBDcmVhdGluZyBOZXR3b3JrcyBhbmQgUGxvdHRpbmcgR3JhcGhzDQoNCkRldGFjaGluZyBwYWNrYWdlcyB0byBhdm9pZCBjb25mbGljdHMgYmV0d2VlbiBwYWNrYWdlIG9wZXJhdGlvbnMuDQoNCmBgYHtyIGxpYnJhcnkgZGV0YWNoaW5nLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KZGV0YWNoKHBhY2thZ2U6c25hKQ0KZGV0YWNoKHBhY2thZ2U6bmV0d29yaykNCnN1cHByZXNzTWVzc2FnZXMobGlicmFyeShpZ3JhcGgpKQ0KYGBgDQoNCiMjIE4xLiBDcmVhdGluZyB0aGUgbmV0d29yayBmb3IgYWxsIHRoZSBpbnZlbnRvcnMNCg0KYGBge3IgY29udi4gbjF9DQojIG1hdGNoaW5nIHRoZSBkYXRhc2V0IHdpdGggY2l0eSBhbmQgYXBwbGljYXRpb24gaWRzDQppbnZfcGVyc29uX3BhcnNlZCRjaXR5IDwtIGludl9wZXJfYXR0ciRjaXR5W21hdGNoKGludl9wZXJzb25fcGFyc2VkJGFwcGxuX2lkLCBpbnZfcGVyc29uX3BhcnNlZCRhcHBsbl9pZCldDQpgYGANCg0KIyMjIE4xLiBQbG90dGluZw0KDQpgYGB7ciBuMSBwbG90LCBmaWcuaGVpZ2h0PTcsIGZpZy53aWR0aD03fQ0Kc2V0LnNlZWQoMTAwKQ0KcGFyKG1hcj1jKDAsMCwxLDApKQ0KcGxvdChpbnZfYWZmX2FsbF9pZywNCiAgICAgdmVydGV4LmxhYmVsPU5BLA0KICAgICB2ZXJ0ZXguc2l6ZSA9IDMsDQogICAgIHZlcnRleC5jb2xvciA9IFYoaW52X2FmZl9hbGxfaWcpLA0KICAgICBtYWluPSJOZXR3b3JrIG9mIGFsbCB0aGUgaW52ZW50b3JzIikNCmBgYA0KDQojIyBOMi4gQ3JlYXRpbmcgbmV0d29yayBmb3IgMTUgY2l0aWVzDQoNCmBgYHtyIGNvbnYuIG4yfQ0KaW52X2NpdHlfaWcgPC0gKGludl9jaXR5X2lnICU+JSANCiAgICAgICAgICAgICAgICAgIHNldF92ZXJ0ZXhfYXR0cigNCiAgICAgICAgICAgICAgICAgICAgbmFtZSA9ICJ2ZXJ0ZXgubmFtZXMiLA0KICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IGMoIkF1cmljaCIsIkhhbWJ1cmciLCJCZXJsaW4iLCJTYWx6YmVyZ2VuIiwiUmVuZHNidXJnIiwiUmhlaW5lIiwiS2llbCIsIkFhY2hlbiIsIk11bmNoZW4iLCJOb3JkZXJzdGVkdCIsIk9zbmFicnVjayIsIkJyZW1lbiIsIkVybGFuZ2VuIiwiRHJlc2RlbiIsIk11bnN0ZXIiKSAjIG1vZGlmeWluZyB2ZXJ0ZXggbmFtZXMgb24gdGhlIGlncmFwaCBvYmplY3QgKGFzIGNpdHkgbmFtZXMpDQogICAgICAgICAgICAgICAgICApKQ0KVihpbnZfY2l0eV9pZykkbGFiZWwgPC0gYygiQXVyaWNoIiwiSGFtYnVyZyIsIkJlcmxpbiIsIlNhbHpiZXJnZW4iLCJSZW5kc2J1cmciLCJSaGVpbmUiLCJLaWVsIiwiQWFjaGVuIiwiTXVuY2hlbiIsIk5vcmRlcnN0ZWR0IiwiT3NuYWJydWNrIiwiQnJlbWVuIiwiRXJsYW5nZW4iLCJEcmVzZGVuIiwiTXVuc3RlciIpICMgY2hhbmdpbmcgdGhlIGlncmFwaCBvYmplY3QncyBsYWJlbHMgYWxzbyBpbnRvIHRoZSBjaXR5IG5hbWVzDQpgYGANCg0KIyMjIE4yLiBDZW50cmFsaXR5IE1lYXN1cmVtZW50DQoNCmBgYHtyIG4yIGNlbnRyYWxpdHl9DQpjZW50cl9kZWdyZWUoDQogIGludl9jaXR5X2lnLA0KICBtb2RlID0gYygiYWxsIiwgIm91dCIsICJpbiIsICJ0b3RhbCIpLA0KICBsb29wcyA9IEYsDQogIG5vcm1hbGl6ZWQgPSBUUlVFKQ0KYGBgDQoNCiMjIyBOMi4gUGxvdHRpbmcNCg0KYGBge3IgbjIgcGxvdCwgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9Nn0NCnBhcihtYXI9YygwLDAsMiwwKSkNCnNldC5zZWVkKDEwMCkNCnBsb3QoaW52X2NpdHlfaWcsDQogICAgIHZlcnRleC5sYWJlbD1WKGludl9jaXR5X2lnKSRjaXR5LA0KICAgICB2ZXJ0ZXguY29sb3I9VihpbnZfY2l0eV9pZyksDQogICAgIHZlcnRleC5zaXplPSAxMCwNCiAgICAgdmVydGV4LmZyYW1lLmNvbG9yPU5BLA0KICAgICB2ZXJ0ZXgubGFiZWwuZmFtaWx5PSAiQ2FtYnJpYSIsDQogICAgIHZlcnRleC5sYWJlbC5mb250PTIsDQogICAgIG1haW49Ik5ldHdvcmsgb2YgdG9wIDE1IGNpdGllcyIpDQpgYGANCg0KIyMgTjMuIFBsb3R0aW5nIGFuZCBjZW50cmFsaXR5IG1lYXN1cmVtZW50IG9mIGludmVudG9yJ3MgbmV0d29yayAodG9wIDE1IGNpdGllcykgDQojIyMgTjMuIENlbnRyYWxpdHkgTWVhc3VyZW1lbnQNCg0KYGBge3IgbjMgY2VudHJhbGl0eX0NCmNlbnRyX2RlZ3JlZSgNCiAgaW52X2FmZl9pZywNCiAgbW9kZSA9IGMoImFsbCIsICJvdXQiLCAiaW4iLCAidG90YWwiKSwNCiAgbG9vcHMgPSBGLA0KICBub3JtYWxpemVkID0gVFJVRSkNCmBgYA0KDQojIyMgTjMuIFBsb3R0aW5nDQoNCiMjIyMgR2VuZXJhbCBuZXR3b3JrIGdyYXBoDQoNCmBgYHtyIGdlbmVyYWwgbmV0IHBsb3QsIGZpZy5oZWlnaHQ9NiwgZmlnLndpZHRoPTZ9DQpzZXQuc2VlZCgxMDApDQpwYXIobWFyPWMoMCwwLDIsMCkpDQpwbG90KGludl9hZmZfaWcsDQogICAgIHZlcnRleC5sYWJlbD1OQSwNCiAgICAgdmVydGV4LnNpemU9MS41LA0KICAgICB2ZXJ0ZXguZnJhbWUuY29sb3I9ImJsYWNrIiwNCiAgICAgdmVydGV4LmNvbG9yID0gVihpbnZfYWZmX2lnKSwNCiAgICAgbWFpbj0iSW52ZW50b3IgbmV0d29yayBvZiB0b3AgMTUgY2l0aWVzXG5mb3IgMTk5Ni0yMDE2IikNCmBgYA0KDQojIyMjIFBsb3R0aW5nIHdpdGggZGVuc2l0eQ0KDQpgYGB7ciAgZGVuc2l0eSBwbG90LCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD02fQ0Kc2V0LnNlZWQoMTAwKQ0KcGFyKG1hcj1jKDAsMCw0LDApKQ0KcGxvdChpbnZfYWZmX2lnLA0KICAgICB2ZXJ0ZXgubGFiZWw9TkEsDQogICAgIHZlcnRleC5zaXplPWRlZ3JlZShpbnZfYWZmX2lnKSoxLjUsDQogICAgIHZlcnRleC5mcmFtZS5jb2xvcj0iYmxhY2siLA0KICAgICB2ZXJ0ZXguY29sb3IgPSBWKGludl9hZmZfaWcpLA0KICAgICBtYWluPSJJbnZlbnRvciBuZXR3b3JrIG9mIHRvcCAxNSBjaXRpZXNcbmZvciAxOTk2LTIwMTZcbndpdGggZGVncmVlIG1lYXN1cmVtZW50IikNCmBgYA0KDQojIyMjIFBsb3R0aW5nIHdpdGggZGVuc2l0eSBhbmQgZWRnZSBiZXR3ZWVubmVzcw0KDQpgYGB7ciAgZGVuc2l0eSwgZWIgcGxvdCwgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9Nn0NCnNldC5zZWVkKDEwMCkNCnBhcihtYXI9YygwLDAsNCwwKSkNCnBsb3QoaW52X2FmZl9pZywNCiAgICAgdmVydGV4LmxhYmVsPU5BLA0KICAgICB2ZXJ0ZXguZnJhbWUuY29sb3I9ImJsYWNrIiwNCiAgICAgdmVydGV4LmNvbG9yPVYoaW52X2FmZl9pZyksDQogICAgIHZlcnRleC5zaXplPWRlZ3JlZShpbnZfYWZmX2lnKSoxLjUsDQogICAgIGVkZ2UuY3VydmVkPS4xLA0KICAgICBtYWluPSJJbnZlbnRvciBuZXR3b3JrIG9mIHRvcCAxNSBjaXRpZXNcbmZvciAxOTk2LTIwMTZcbndpdGggZGVncmVlIG1lYXN1cmVtZW50IGFuZCBlZGdlIGJldHdlZW5uZXNzIiwNCiAgICAgZWRnZS53aWR0aCA9IGVkZ2VfYmV0d2Vlbm5lc3MoaW52X2FmZl9pZykqLjgpDQpgYGANCg0KIyBUb3AgNSBDaXR5J3MgSW5ub3ZhdGlvbiBTY2VuYXJpbyBvdmVyIHRoZSBUaW1lDQoNCkRldGFjaGluZyBwYWNrYWdlcyB0byBhdm9pZCBjb25mbGljdHMgYmV0d2VlbiBwYWNrYWdlIG9wZXJhdGlvbnMNCg0KYGBge3IgcGNrZyBkZXRhY2h9DQpkZXRhY2gocGFja2FnZTppZ3JhcGgpDQpzdXBwcmVzc01lc3NhZ2VzKGxpYnJhcnkobmV0d29yaykpDQpgYGANCg0KIyMgQXVyaWNoDQoNCmBgYHtyIGF1cmljaCBuZXR9DQojIyBBdXJpY2ggMTk5NjoyMDA2IG5ldHdvcmsNCmF1cmljaF9kYXRhXzA2IDwtIChkYXRhX21haW5fMTVfYXR0ciAlPiUNCiAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKGNpdHk9PSJBdXJpY2giLCBhcHBfeWVhcj49MTk5NiAmIGFwcF95ZWFyPD0yMDA2KSAlPiUNCiAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0KGludl9uYW1lLCBhcHBsbl9pZCkpDQoNCmF1cmljaF9kYXRhXzA2IDwtIHRhYmxlKGF1cmljaF9kYXRhXzA2KQ0KZGltKGF1cmljaF9kYXRhXzA2KQ0KYXVyaWNoX2Fkal8wNiA8LSBhdXJpY2hfZGF0YV8wNiAlKiUgdChhdXJpY2hfZGF0YV8wNikNCmRpbShhdXJpY2hfYWRqXzA2KQ0KY2xhc3MoYXVyaWNoX2Fkal8wNikNCmF1cmljaF9ud18wNiA8LSAgbmV0d29yayhhdXJpY2hfYWRqXzA2LA0KICAgICAgICAgICAgICAgICAgICAgIG1hdHJpeC50eXBlPSJhZGphY2VuY3kiLA0KICAgICAgICAgICAgICAgICAgICAgIGRpcmVjdGVkPUYpICAjIGNvbnZlcnQgaW50byAnbmV0d29yaycgZm9ybWF0DQoNCg0KIyMgQXVyaWNoIDIwMDc6MjAxNiBuZXR3b3JrDQphdXJpY2hfZGF0YV8xNiA8LSAoZGF0YV9tYWluXzE1X2F0dHIgJT4lDQogICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoY2l0eT09IkF1cmljaCIsIGFwcF95ZWFyPj0yMDA3ICYgYXBwX3llYXI8PTIwMTYpICU+JQ0KICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0KGludl9uYW1lLCBhcHBsbl9pZCkpDQoNCmF1cmljaF9kYXRhXzE2IDwtIHRhYmxlKGF1cmljaF9kYXRhXzE2KQ0KZGltKGF1cmljaF9kYXRhXzE2KQ0KYXVyaWNoX2Fkal8xNiA8LSBhdXJpY2hfZGF0YV8xNiAlKiUgdChhdXJpY2hfZGF0YV8xNikNCmRpbShhdXJpY2hfYWRqXzE2KQ0KY2xhc3MoYXVyaWNoX2Fkal8xNikNCmF1cmljaF9ud18xNiA8LSAgbmV0d29yayhhdXJpY2hfYWRqXzE2LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0cml4LnR5cGU9ImFkamFjZW5jeSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICBkaXJlY3RlZD1GKSAgIyBjb252ZXJ0IGludG8gJ25ldHdvcmsnIGZvcm1hdA0KDQpgYGANCg0KIyMjIFBsb3R0aW5nDQoNCmBgYHtyIGF1cmljaCBwbG90LCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD04fQ0KcGFyKG1mcm93ID0gYygxLDIpKQ0KcGFyKG1hcj1jKDMsMCwxLDApKQ0KDQojcGxvdCBmb3IgMTk5NjoyMDA2DQpwbG90Lm5ldHdvcmsoYXVyaWNoX253XzA2LA0KICAgICAgICAgICAgIHZlcnRleC5jb2w9IiM3NTcwQjMiLA0KICAgICAgICAgICAgIHZlcnRleC5jZXg9MSwNCiAgICAgICAgICAgICB2ZXJ0ZXguYm9yZGVyPSJibGFjayIsDQogICAgICAgICAgICAgbWFpbj0iSW52ZW50b3JzIE5ldHdvcmsgZm9yIEF1cmljaCAxOTk2OjIwMDYiLA0KICAgICAgICAgICAgIHBhZD00LA0KICAgICAgICAgICAgIGZyYW1lID0gVCwNCiAgICAgICAgICAgICBzdWI9bmV0d29yay5zaXplKGF1cmljaF9ud18wNiksDQogICAgICAgICAgICAgY2V4Lm1haW49LjgpDQoNCiMgcGxvdCBmb3IgMjAwNzoyMDE2DQpwbG90Lm5ldHdvcmsoYXVyaWNoX253XzE2LA0KICAgICAgICAgICAgIHZlcnRleC5jb2w9IiM3NTcwQjMiLA0KICAgICAgICAgICAgIHZlcnRleC5jZXg9MSwNCiAgICAgICAgICAgICB2ZXJ0ZXguYm9yZGVyPSJibGFjayIsDQogICAgICAgICAgICAgbWFpbj0iSW52ZW50b3JzIE5ldHdvcmsgZm9yIEF1cmljaCAyMDA3OjIwMTYiLA0KICAgICAgICAgICAgIGZyYW1lID0gVCwNCiAgICAgICAgICAgICBjZXgubWFpbj0uOCkNCmNhdCgiVG90YWwgbm9kZXMgMTk5Ni0yMDA2OiIsIG5ldHdvcmsuc2l6ZShhdXJpY2hfbndfMDYpLCJcblRvdGFsIG5vZGVzIDIwMDctMjAxNjoiLCBuZXR3b3JrLnNpemUoYXVyaWNoX253XzE2KSkNCmBgYA0KDQojIyBIYW1idXJnDQoNCmBgYHtyIGhhbWJ1cmcgbmV0fQ0KIyMgSGFtYnVyZyAxOTk2OjIwMDYgbmV0d29yaw0KaGFtYnVyZ19kYXRhXzA2IDwtIChkYXRhX21haW5fMTVfYXR0ciAlPiUNCiAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKGNpdHk9PSJIYW1idXJnIiwgYXBwX3llYXI+PTE5OTYgJiBhcHBfeWVhcjw9MjAwNikgJT4lDQogICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdChpbnZfbmFtZSwgYXBwbG5faWQpKQ0KDQpoYW1idXJnX2RhdGFfMDYgPC0gdGFibGUoaGFtYnVyZ19kYXRhXzA2KQ0KZGltKGhhbWJ1cmdfZGF0YV8wNikNCmhhbWJ1cmdfYWRqXzA2IDwtIGhhbWJ1cmdfZGF0YV8wNiAlKiUgdChoYW1idXJnX2RhdGFfMDYpDQpkaW0oaGFtYnVyZ19hZGpfMDYpDQpjbGFzcyhoYW1idXJnX2Fkal8wNikNCmhhbWJ1cmdfbndfMDYgPC0gIG5ldHdvcmsoaGFtYnVyZ19hZGpfMDYsDQogICAgICAgICAgICAgICAgICAgICAgICAgbWF0cml4LnR5cGU9ImFkamFjZW5jeSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgZGlyZWN0ZWQ9RikgICMgY29udmVydCBpbnRvICduZXR3b3JrJyBmb3JtYXQNCg0KDQojIyBIYW1idXJnIDIwMDc6MjAwNiBuZXR3b3JrDQpoYW1idXJnX2RhdGFfMTYgPC0gKGRhdGFfbWFpbl8xNV9hdHRyICU+JQ0KICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoY2l0eT09IkhhbWJ1cmciLCBhcHBfeWVhcj49MjAwNyAmIGFwcF95ZWFyPD0yMDE2KSAlPiUNCiAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0KGludl9uYW1lLCBhcHBsbl9pZCkpDQoNCmhhbWJ1cmdfZGF0YV8xNiA8LSB0YWJsZShoYW1idXJnX2RhdGFfMTYpDQpkaW0oaGFtYnVyZ19kYXRhXzE2KQ0KaGFtYnVyZ19hZGpfMTYgPC0gaGFtYnVyZ19kYXRhXzE2ICUqJSB0KGhhbWJ1cmdfZGF0YV8xNikNCmRpbShoYW1idXJnX2Fkal8xNikNCmNsYXNzKGhhbWJ1cmdfYWRqXzE2KQ0KaGFtYnVyZ19ud18xNiA8LSAgbmV0d29yayhoYW1idXJnX2Fkal8xNiwNCiAgICAgICAgICAgICAgICAgICAgICBtYXRyaXgudHlwZT0iYWRqYWNlbmN5IiwNCiAgICAgICAgICAgICAgICAgICAgICBkaXJlY3RlZD1GKSAgIyBjb252ZXJ0IGludG8gJ25ldHdvcmsnIGZvcm1hdA0KDQpgYGANCg0KIyMjIFBsb3R0aW5nDQoNCmBgYHtyIGhhbWJ1cmcgcGxvdCwgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9OH0NCnBhcihtZnJvdyA9IGMoMSwyKSkNCnBhcihtYXI9YygwLDAsMSwwKSkNCg0KI3Bsb3QgZm9yIDE5OTY6MjAwNg0KcGxvdC5uZXR3b3JrKGhhbWJ1cmdfbndfMDYsDQogICAgICAgICAgICAgdmVydGV4LmNvbD0iIzk5Qjg5OCIsDQogICAgICAgICAgICAgdmVydGV4LmNleD0xLA0KICAgICAgICAgICAgIHZlcnRleC5ib3JkZXI9ImJsYWNrIiwNCiAgICAgICAgICAgICBtYWluPSJJbnZlbnRvcnMgTmV0d29yayBmb3IgSGFtYnVyZyAxOTk2OjIwMDYiLA0KICAgICAgICAgICAgIGZyYW1lID0gVCwNCiAgICAgICAgICAgICBwYWQ9NCwNCiAgICAgICAgICAgICBjZXgubWFpbj0uOCkNCiMgcGxvdCBmb3IgMjAwNzoyMDE2DQpwbG90Lm5ldHdvcmsoaGFtYnVyZ19ud18xNiwNCiAgICAgICAgICAgICB2ZXJ0ZXguY29sPSIjOTlCODk4IiwNCiAgICAgICAgICAgICB2ZXJ0ZXguY2V4PTEsDQogICAgICAgICAgICAgdmVydGV4LmJvcmRlcj0iYmxhY2siLA0KICAgICAgICAgICAgIG1haW49IkludmVudG9ycyBOZXR3b3JrIGZvciBIYW1idXJnIDIwMDc6MjAxNiIsDQogICAgICAgICAgICAgZnJhbWUgPSBULA0KICAgICAgICAgICAgIGNleC5tYWluPS44KQ0KY2F0KCJUb3RhbCBub2RlcyAxOTk2LTIwMDY6IiwgbmV0d29yay5zaXplKGhhbWJ1cmdfbndfMDYpLCJcblRvdGFsIG5vZGVzIDIwMDctMjAxNjoiLCBuZXR3b3JrLnNpemUoaGFtYnVyZ19ud18xNikpDQpgYGANCg0KIyMgQmVybGluDQoNCmBgYHtyIGJlcmxpbiBuZXR9DQojIyBCZXJsaW4gMTk5NjoyMDA2IG5ldHdvcmsNCmJlcmxpbl9kYXRhXzA2IDwtIChkYXRhX21haW5fMTVfYXR0ciAlPiUNCiAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXIoY2l0eT09IkJlcmxpbiIsIGFwcF95ZWFyPj0xOTk2ICYgYXBwX3llYXI8PTIwMDYpICU+JQ0KICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdChpbnZfbmFtZSwgYXBwbG5faWQpKQ0KDQpiZXJsaW5fZGF0YV8wNiA8LSB0YWJsZShiZXJsaW5fZGF0YV8wNikNCmRpbShiZXJsaW5fZGF0YV8wNikNCmJlcmxpbl9hZGpfMDYgPC0gYmVybGluX2RhdGFfMDYgJSolIHQoYmVybGluX2RhdGFfMDYpDQpkaW0oYmVybGluX2Fkal8wNikNCmNsYXNzKGJlcmxpbl9hZGpfMDYpDQpiZXJsaW5fbndfMDYgPC0gIG5ldHdvcmsoYmVybGluX2Fkal8wNiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0cml4LnR5cGU9ImFkamFjZW5jeSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgIGRpcmVjdGVkPUYpICAjIGNvbnZlcnQgaW50byAnbmV0d29yaycgZm9ybWF0DQoNCg0KIyMgQmVybGluIDIwMDc6MjAxNiBuZXR3b3JrDQpiZXJsaW5fZGF0YV8xNiA8LSAoZGF0YV9tYWluXzE1X2F0dHIgJT4lDQogICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKGNpdHk9PSJCZXJsaW4iLCBhcHBfeWVhcj49MjAwNyAmIGFwcF95ZWFyPD0yMDE2KSAlPiUNCiAgICAgICAgICAgICAgICAgICAgICBzZWxlY3QoaW52X25hbWUsIGFwcGxuX2lkKSkNCg0KYmVybGluX2RhdGFfMTYgPC0gdGFibGUoYmVybGluX2RhdGFfMTYpDQpkaW0oYmVybGluX2RhdGFfMTYpDQpiZXJsaW5fYWRqXzE2IDwtIGJlcmxpbl9kYXRhXzE2ICUqJSB0KGJlcmxpbl9kYXRhXzE2KQ0KZGltKGJlcmxpbl9hZGpfMTYpDQpjbGFzcyhiZXJsaW5fYWRqXzE2KQ0KYmVybGluX253XzE2IDwtICBuZXR3b3JrKGJlcmxpbl9hZGpfMTYsDQogICAgICAgICAgICAgICAgICAgICAgICAgIG1hdHJpeC50eXBlPSJhZGphY2VuY3kiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICBkaXJlY3RlZD1GKSAgIyBjb252ZXJ0IGludG8gJ25ldHdvcmsnIGZvcm1hdA0KDQpgYGANCg0KIyMjIFBsb3R0aW5nDQoNCmBgYHtyIGJlcmxpbiBwbG90LCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD04fQ0KcGFyKG1mcm93ID0gYygxLDIpKQ0KcGFyKG1hcj1jKDAsMCwxLDApKQ0KDQojcGxvdCBmb3IgMTk5NjoyMDA2DQpwbG90Lm5ldHdvcmsoYmVybGluX253XzA2LA0KICAgICAgICAgICAgIHZlcnRleC5jb2w9IiNGMjZCMzgiLA0KICAgICAgICAgICAgIHZlcnRleC5jZXg9MSwNCiAgICAgICAgICAgICB2ZXJ0ZXguYm9yZGVyPSJibGFjayIsDQogICAgICAgICAgICAgbWFpbj0iSW52ZW50b3JzIE5ldHdvcmsgZm9yIEJlcmxpbiAxOTk2OjIwMDYiLA0KICAgICAgICAgICAgIGZyYW1lID0gVCwNCiAgICAgICAgICAgICBwYWQ9NCwNCiAgICAgICAgICAgICBjZXgubWFpbj0uOCkNCiMgcGxvdCBmb3IgMjAwNzoyMDE2DQpwbG90Lm5ldHdvcmsoYmVybGluX253XzE2LA0KICAgICAgICAgICAgIHZlcnRleC5jb2w9IiNGMjZCMzgiLA0KICAgICAgICAgICAgIHZlcnRleC5jZXg9MSwNCiAgICAgICAgICAgICB2ZXJ0ZXguYm9yZGVyPSJibGFjayIsDQogICAgICAgICAgICAgbWFpbj0iSW52ZW50b3JzIE5ldHdvcmsgZm9yIEJlcmxpbiAyMDA3OjIwMTYiLA0KICAgICAgICAgICAgIGZyYW1lID0gVCwNCiAgICAgICAgICAgICBjZXgubWFpbj0uOCkNCmNhdCgiVG90YWwgbm9kZXMgMTk5Ni0yMDA2OiIsIG5ldHdvcmsuc2l6ZShiZXJsaW5fbndfMDYpLCJcblRvdGFsIG5vZGVzIDIwMDctMjAxNjoiLCBuZXR3b3JrLnNpemUoYmVybGluX253XzE2KSkNCg0KYGBgDQoNCiMjIFNhbHpiZXJnZW4NCg0KYGBge3Igc2FsemJlcmdlbiBuZXR9DQojIyBTYWx6YmVyZ2VuIDE5OTY6MjAwNiBuZXR3b3JrDQpzYWx6YmVyZ2VuX2RhdGFfMDYgPC0gKGRhdGFfbWFpbl8xNV9hdHRyICU+JQ0KICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcihjaXR5PT0iU2FsemJlcmdlbiIsIGFwcF95ZWFyPj0xOTk2ICYgYXBwX3llYXI8PTIwMDYpICU+JQ0KICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdChpbnZfbmFtZSwgYXBwbG5faWQpKQ0KDQpzYWx6YmVyZ2VuX2RhdGFfMDYgPC0gdGFibGUoc2FsemJlcmdlbl9kYXRhXzA2KQ0KZGltKHNhbHpiZXJnZW5fZGF0YV8wNikNCnNhbHpiZXJnZW5fYWRqXzA2IDwtIHNhbHpiZXJnZW5fZGF0YV8wNiAlKiUgdChzYWx6YmVyZ2VuX2RhdGFfMDYpDQpkaW0oc2FsemJlcmdlbl9hZGpfMDYpDQpjbGFzcyhzYWx6YmVyZ2VuX2Fkal8wNikNCnNhbHpiZXJnZW5fbndfMDYgPC0gIG5ldHdvcmsoc2FsemJlcmdlbl9hZGpfMDYsDQogICAgICAgICAgICAgICAgICAgICAgICAgbWF0cml4LnR5cGU9ImFkamFjZW5jeSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgZGlyZWN0ZWQ9RikgICMgY29udmVydCBpbnRvICduZXR3b3JrJyBmb3JtYXQNCg0KDQojIyBTYWx6YmVyZ2VuIDIwMDc6MjAxNyBuZXR3b3JrDQpzYWx6YmVyZ2VuX2RhdGFfMTYgPC0gKGRhdGFfbWFpbl8xNV9hdHRyICU+JQ0KICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcihjaXR5PT0iU2FsemJlcmdlbiIsIGFwcF95ZWFyPj0yMDA3ICYgYXBwX3llYXI8PTIwMTYpICU+JQ0KICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdChpbnZfbmFtZSwgYXBwbG5faWQpKQ0KDQpzYWx6YmVyZ2VuX2RhdGFfMTYgPC0gdGFibGUoc2FsemJlcmdlbl9kYXRhXzE2KQ0KZGltKHNhbHpiZXJnZW5fZGF0YV8xNikNCnNhbHpiZXJnZW5fYWRqXzE2IDwtIHNhbHpiZXJnZW5fZGF0YV8xNiAlKiUgdChzYWx6YmVyZ2VuX2RhdGFfMTYpDQpkaW0oc2FsemJlcmdlbl9hZGpfMTYpDQpjbGFzcyhzYWx6YmVyZ2VuX2Fkal8xNikNCnNhbHpiZXJnZW5fbndfMTYgPC0gIG5ldHdvcmsoc2FsemJlcmdlbl9hZGpfMTYsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdHJpeC50eXBlPSJhZGphY2VuY3kiLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaXJlY3RlZD1GKSAgIyBjb252ZXJ0IGludG8gJ25ldHdvcmsnIGZvcm1hdA0KDQpgYGANCg0KIyMjIFBsb3R0aW5nDQoNCmBgYHtyIHNhbHpiZXJnZW4gcGxvdCwgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9OH0NCnBhcihtZnJvdyA9IGMoMSwyKSkNCnBhcihtYXI9YygwLDAsMSwwKSkNCg0KI3Bsb3QgZm9yIDE5OTY6MjAwNg0KcGxvdC5uZXR3b3JrKHNhbHpiZXJnZW5fbndfMDYsDQogICAgICAgICAgICAgdmVydGV4LmNvbD0iIzU5NEY0RiIsDQogICAgICAgICAgICAgdmVydGV4LmNleD0xLA0KICAgICAgICAgICAgIHZlcnRleC5ib3JkZXI9ImJsYWNrIiwNCiAgICAgICAgICAgICBtYWluPSJJbnZlbnRvcnMgTmV0d29yayBmb3IgU2FsemJlcmdlbiAxOTk2OjIwMDYiLA0KICAgICAgICAgICAgIGZyYW1lID0gVCwNCiAgICAgICAgICAgICBwYWQ9NCwNCiAgICAgICAgICAgICBjZXgubWFpbj0uOCkNCiMgcGxvdCBmb3IgMjAwNzoyMDE2DQpwbG90Lm5ldHdvcmsoc2FsemJlcmdlbl9ud18xNiwNCiAgICAgICAgICAgICB2ZXJ0ZXguY29sPSIjNTk0RjRGIiwNCiAgICAgICAgICAgICB2ZXJ0ZXguY2V4PTEsDQogICAgICAgICAgICAgdmVydGV4LmJvcmRlcj0iYmxhY2siLA0KICAgICAgICAgICAgIG1haW49IkludmVudG9ycyBOZXR3b3JrIGZvciBTYWx6YmVyZ2VuIDIwMDc6MjAxNiIsDQogICAgICAgICAgICAgZnJhbWUgPSBULA0KICAgICAgICAgICAgIGNleC5tYWluPS44KQ0KY2F0KCJUb3RhbCBub2RlcyAxOTk2LTIwMDY6IiwgbmV0d29yay5zaXplKHNhbHpiZXJnZW5fbndfMDYpLCJcblRvdGFsIG5vZGVzIDIwMDctMjAxNjoiLCBuZXR3b3JrLnNpemUoc2FsemJlcmdlbl9ud18xNikpDQoNCmBgYA0KDQojIyBSZW5kc2J1cmcNCg0KYGBge3IgcmVuZHNidXJnIG5ldH0NCiMjIFJlbmRzYnVyZyAxOTk2OjIwMDYgbmV0d29yaw0KcmVuZHNidXJnX2RhdGFfMDYgPC0gKGRhdGFfbWFpbl8xNV9hdHRyICU+JQ0KICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcihjaXR5PT0iUmVuZHNidXJnIiwgYXBwX3llYXI+PTE5OTYgJiBhcHBfeWVhcjw9MjAwNikgJT4lDQogICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0KGludl9uYW1lLCBhcHBsbl9pZCkpDQoNCnJlbmRzYnVyZ19kYXRhXzA2IDwtIHRhYmxlKHJlbmRzYnVyZ19kYXRhXzA2KQ0KZGltKHJlbmRzYnVyZ19kYXRhXzA2KQ0KcmVuZHNidXJnX2Fkal8wNiA8LSByZW5kc2J1cmdfZGF0YV8wNiAlKiUgdChyZW5kc2J1cmdfZGF0YV8wNikNCmRpbShyZW5kc2J1cmdfYWRqXzA2KQ0KY2xhc3MocmVuZHNidXJnX2Fkal8wNikNCnJlbmRzYnVyZ19ud18wNiA8LSAgbmV0d29yayhyZW5kc2J1cmdfYWRqXzA2LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRyaXgudHlwZT0iYWRqYWNlbmN5IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlyZWN0ZWQ9RikgICMgY29udmVydCBpbnRvICduZXR3b3JrJyBmb3JtYXQNCg0KDQojIyBSZW5kc2J1cmcgMjAwOjIwMTYgbmV0d29yaw0KcmVuZHNidXJnX2RhdGFfMTYgPC0gKGRhdGFfbWFpbl8xNV9hdHRyICU+JQ0KICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcihjaXR5PT0iUmVuZHNidXJnIiwgYXBwX3llYXI+PTIwMDcgJiBhcHBfeWVhcjw9MjAxNikgJT4lDQogICAgICAgICAgICAgICAgICAgICAgICAgc2VsZWN0KGludl9uYW1lLCBhcHBsbl9pZCkpDQoNCnJlbmRzYnVyZ19kYXRhXzE2IDwtIHRhYmxlKHJlbmRzYnVyZ19kYXRhXzE2KQ0KZGltKHJlbmRzYnVyZ19kYXRhXzE2KQ0KcmVuZHNidXJnX2Fkal8xNiA8LSByZW5kc2J1cmdfZGF0YV8xNiAlKiUgdChyZW5kc2J1cmdfZGF0YV8xNikNCmRpbShyZW5kc2J1cmdfYWRqXzE2KQ0KY2xhc3MocmVuZHNidXJnX2Fkal8xNikNCnJlbmRzYnVyZ19ud18xNiA8LSAgbmV0d29yayhyZW5kc2J1cmdfYWRqXzE2LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXRyaXgudHlwZT0iYWRqYWNlbmN5IiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlyZWN0ZWQ9RikgICMgY29udmVydCBpbnRvICduZXR3b3JrJyBmb3JtYXQNCg0KDQpgYGANCg0KIyMjIFBsb3R0aW5nDQoNCmBgYHtyIHJlbmRzYnVyZyBwbG90LCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD04fQ0KcGFyKG1mcm93ID0gYygxLDIpKQ0KcGFyKG1hcj1jKDAsMCwxLDApKQ0KDQojcGxvdCBmb3IgMTk5NjoyMDA2DQpwbG90Lm5ldHdvcmsocmVuZHNidXJnX253XzA2LA0KICAgICAgICAgICAgIHZlcnRleC5jb2w9IiMzNTVDN0QiLA0KICAgICAgICAgICAgIHZlcnRleC5jZXg9MSwNCiAgICAgICAgICAgICB2ZXJ0ZXguYm9yZGVyPSJibGFjayIsDQogICAgICAgICAgICAgbWFpbj0iSW52ZW50b3JzIE5ldHdvcmsgZm9yIFJlbmRzYnVyZyAxOTk2OjIwMDYiLA0KICAgICAgICAgICAgIGZyYW1lID0gVCwNCiAgICAgICAgICAgICBwYWQ9NCwNCiAgICAgICAgICAgICBjZXgubWFpbj0uOCkNCiMgcGxvdCBmb3IgMjAwNzoyMDE2DQpwbG90Lm5ldHdvcmsocmVuZHNidXJnX253XzE2LA0KICAgICAgICAgICAgIHZlcnRleC5jb2w9IiMzNTVDN0QiLA0KICAgICAgICAgICAgIHZlcnRleC5jZXg9MSwNCiAgICAgICAgICAgICB2ZXJ0ZXguYm9yZGVyPSJibGFjayIsDQogICAgICAgICAgICAgbWFpbj0iSW52ZW50b3JzIE5ldHdvcmsgZm9yIFJlbmRzYnVyZyAyMDA3OjIwMTYiLA0KICAgICAgICAgICAgIGZyYW1lID0gVCwNCiAgICAgICAgICAgICBjZXgubWFpbj0uOCkNCmNhdCgiVG90YWwgbm9kZXMgMTk5Ni0yMDA2OiIsIG5ldHdvcmsuc2l6ZShyZW5kc2J1cmdfbndfMDYpLCJcblRvdGFsIG5vZGVzIDIwMDctMjAxNjoiLCBuZXR3b3JrLnNpemUocmVuZHNidXJnX253XzE2KSkNCmBgYA0KDQojIFBvc2l0aW9uIG9mIHRoZSBUb3AgNSBDaXRpZXMgaW4gMTUgQ2l0eSdzIE5ldHdvcmsNCg0KRGV0YWNoaW5nIHBhY2thZ2VzIHRvIGF2b2lkIGNvbmZsaWN0cyBiZXR3ZWVuIHBhY2thZ2Ugb3BlcmF0aW9ucy4NCg0KYGBge3IgZGV0YWNoaW5nIGxpYnJhcmllc30NCmRldGFjaChwYWNrYWdlOm5ldHdvcmspDQpzdXBwcmVzc01lc3NhZ2VzKGxpYnJhcnkoaWdyYXBoKSkNCmBgYA0KDQojIyBBdXJpY2gNCg0KYGBge3IgYXVyaWNoIHBvc2l0aW9ufQ0KIyMgcG9zaXRpb24gb2YgdGhlIGNpdGllcyBpbiB0aGUgb3ZlcmFsbCBuZXR3b3JrDQppbnZfcGVyc29uX3BhcnNlZCRjaXR5IDwtIGludl9wZXJfYXR0ciRjaXR5W21hdGNoKGludl9wZXJzb25fcGFyc2VkJGFwcGxuX2lkLCBpbnZfcGVyc29uX3BhcnNlZCRhcHBsbl9pZCldDQpWKGludl9hZmZfaWcpJGlkIDwtIGNvbG5hbWVzKGludl9wZXJzb25fYWRqKQ0KVihpbnZfYWZmX2lnKSRjaXR5X25hbWUgPC0gaW52X3BlcnNvbl9wYXJzZWQkY2l0eVttYXRjaChWKGludl9hZmZfaWcpJGlkLCBpbnZfcGVyc29uX3BhcnNlZCRpbnZfbmFtZSldDQpWKGludl9hZmZfaWcpJGlkIDwtIGNvbG5hbWVzKGludl9wZXJzb25fYWRqKQ0KDQpWKGludl9hZmZfaWcpJGNpdHlfbmFtZV9jb2xvciA8LSBpZmVsc2UoVihpbnZfYWZmX2lnKSRjaXR5X25hbWUgPT0gIkF1cmljaCIsICJyZWQiLCJhenVyZTEiKQ0KI1YoaW52X2FmZl9pZykkaWRbZGVncmVlKGludl9hZmZfaWcpPjVdDQojZGVncmVlKGludl9hZmZfaWcpDQoNCnNldC5zZWVkKDEwMCkNCnBhcihtYXI9YygwLDAsMSwwKSkNCnBsb3QoaW52X2FmZl9pZywNCiAgICAgbGF5b3V0ID0gbGF5b3V0LmF1dG8oaW52X2FmZl9pZyksDQogICAgIHZlcnRleC5zaXplID0gMywNCiAgICAgdmVydGV4LmZyYW1lLmNvbG9yPSJibGFjayIsDQogICAgIHZlcnRleC5jb2xvciA9IFYoaW52X2FmZl9pZykkY2l0eV9uYW1lX2NvbG9yLA0KICAgICB2ZXJ0ZXgubGFiZWwgPSBOQSwNCiAgICAgZWRnZS5jb2xvcj0gImJsYWNrIiwNCiAgICAgbWFpbj0iSW52ZW50b3JzIGZyb20gQXVyaWNoIGluIHRvcCAxNSBjaXR5J3MgbmV0d29yayIpDQoNCmBgYA0KDQojIyBIYW1idXJnDQoNCmBgYHtyIGhhbWJ1cmcgcG9zaXRpb259DQojIyBwb3NpdGlvbiBvZiB0aGUgY2l0aWVzIGluIHRoZSBvdmVyYWxsIG5ldHdvcmsNCmludl9wZXJzb25fcGFyc2VkJGNpdHkgPC0gaW52X3Blcl9hdHRyJGNpdHlbbWF0Y2goaW52X3BlcnNvbl9wYXJzZWQkYXBwbG5faWQsIGludl9wZXJzb25fcGFyc2VkJGFwcGxuX2lkKV0NClYoaW52X2FmZl9pZykkaWQgPC0gY29sbmFtZXMoaW52X3BlcnNvbl9hZGopDQpWKGludl9hZmZfaWcpJGNpdHlfbmFtZSA8LSBpbnZfcGVyc29uX3BhcnNlZCRjaXR5W21hdGNoKFYoaW52X2FmZl9pZykkaWQsIGludl9wZXJzb25fcGFyc2VkJGludl9uYW1lKV0NClYoaW52X2FmZl9pZykkaWQgPC0gY29sbmFtZXMoaW52X3BlcnNvbl9hZGopDQoNClYoaW52X2FmZl9pZykkY2l0eV9uYW1lX2NvbG9yIDwtIGlmZWxzZShWKGludl9hZmZfaWcpJGNpdHlfbmFtZSA9PSAiSGFtYnVyZyIsICJibHVlIiwiYXp1cmUxIikNCiNWKGludl9hZmZfaWcpJGlkW2RlZ3JlZShpbnZfYWZmX2lnKT41XQ0KI2RlZ3JlZShpbnZfYWZmX2lnKQ0KDQpzZXQuc2VlZCgxMDApDQpwYXIobWFyPWMoMCwwLDEsMCkpDQpwbG90KGludl9hZmZfaWcsDQogICAgIGxheW91dCA9IGxheW91dC5hdXRvKGludl9hZmZfaWcpLA0KICAgICB2ZXJ0ZXguc2l6ZSA9IDMsDQogICAgIHZlcnRleC5mcmFtZS5jb2xvcj0iYmxhY2siLA0KICAgICB2ZXJ0ZXguY29sb3IgPSBWKGludl9hZmZfaWcpJGNpdHlfbmFtZV9jb2xvciwNCiAgICAgdmVydGV4LmxhYmVsID0gTkEsDQogICAgIGVkZ2UuY29sb3I9ICJibGFjayIsDQogICAgIG1haW49IkludmVudG9ycyBmcm9tIEhhbWJ1cmcgaW4gdG9wIDE1IGNpdHkncyBuZXR3b3JrIikNCg0KYGBgDQoNCiMjIEJlcmxpbg0KDQpgYGB7ciBiZXJsaW4gcG9zaXRpb259DQojIyBwb3NpdGlvbiBvZiB0aGUgY2l0aWVzIGluIHRoZSBvdmVyYWxsIG5ldHdvcmsNCmludl9wZXJzb25fcGFyc2VkJGNpdHkgPC0gaW52X3Blcl9hdHRyJGNpdHlbbWF0Y2goaW52X3BlcnNvbl9wYXJzZWQkYXBwbG5faWQsIGludl9wZXJzb25fcGFyc2VkJGFwcGxuX2lkKV0NClYoaW52X2FmZl9pZykkaWQgPC0gY29sbmFtZXMoaW52X3BlcnNvbl9hZGopDQpWKGludl9hZmZfaWcpJGNpdHlfbmFtZSA8LSBpbnZfcGVyc29uX3BhcnNlZCRjaXR5W21hdGNoKFYoaW52X2FmZl9pZykkaWQsIGludl9wZXJzb25fcGFyc2VkJGludl9uYW1lKV0NClYoaW52X2FmZl9pZykkaWQgPC0gY29sbmFtZXMoaW52X3BlcnNvbl9hZGopDQoNClYoaW52X2FmZl9pZykkY2l0eV9uYW1lX2NvbG9yIDwtIGlmZWxzZShWKGludl9hZmZfaWcpJGNpdHlfbmFtZSA9PSAiQmVybGluIiwgImRhcmtzbGF0ZWdyYXk0IiwiYXp1cmUxIikNCiNWKGludl9hZmZfaWcpJGlkW2RlZ3JlZShpbnZfYWZmX2lnKT41XQ0KI2RlZ3JlZShpbnZfYWZmX2lnKQ0KDQpzZXQuc2VlZCgxMDApDQpwYXIobWFyPWMoMCwwLDEsMCkpDQpwbG90KGludl9hZmZfaWcsDQogICAgIGxheW91dCA9IGxheW91dC5hdXRvKGludl9hZmZfaWcpLA0KICAgICB2ZXJ0ZXguc2l6ZSA9IDMsDQogICAgIHZlcnRleC5mcmFtZS5jb2xvcj0iYmxhY2siLA0KICAgICB2ZXJ0ZXguY29sb3IgPSBWKGludl9hZmZfaWcpJGNpdHlfbmFtZV9jb2xvciwNCiAgICAgdmVydGV4LmxhYmVsID0gTkEsDQogICAgIGVkZ2UuY29sb3I9ICJibGFjayIsDQogICAgIG1haW49IkludmVudG9ycyBmcm9tIEJlcmxpbiBpbiB0b3AgMTUgY2l0eSdzIG5ldHdvcmsiKQ0KYGBgDQoNCiMjIFNhbHpiZXJnZW4NCg0KYGBge3Igc2FsemJlcmdlbiBwb3NpdGlvbn0NCiMjIHBvc2l0aW9uIG9mIHRoZSBjaXRpZXMgaW4gdGhlIG92ZXJhbGwgbmV0d29yaw0KaW52X3BlcnNvbl9wYXJzZWQkY2l0eSA8LSBpbnZfcGVyX2F0dHIkY2l0eVttYXRjaChpbnZfcGVyc29uX3BhcnNlZCRhcHBsbl9pZCwgaW52X3BlcnNvbl9wYXJzZWQkYXBwbG5faWQpXQ0KVihpbnZfYWZmX2lnKSRpZCA8LSBjb2xuYW1lcyhpbnZfcGVyc29uX2FkaikNClYoaW52X2FmZl9pZykkY2l0eV9uYW1lIDwtIGludl9wZXJzb25fcGFyc2VkJGNpdHlbbWF0Y2goVihpbnZfYWZmX2lnKSRpZCwgaW52X3BlcnNvbl9wYXJzZWQkaW52X25hbWUpXQ0KVihpbnZfYWZmX2lnKSRpZCA8LSBjb2xuYW1lcyhpbnZfcGVyc29uX2FkaikNCg0KVihpbnZfYWZmX2lnKSRjaXR5X25hbWVfY29sb3IgPC0gaWZlbHNlKFYoaW52X2FmZl9pZykkY2l0eV9uYW1lID09ICJTYWx6YmVyZ2VuIiwgImRhcmtvcmFuZ2UxIiwiYXp1cmUxIikNCiNWKGludl9hZmZfaWcpJGlkW2RlZ3JlZShpbnZfYWZmX2lnKT41XQ0KI2RlZ3JlZShpbnZfYWZmX2lnKQ0KDQpzZXQuc2VlZCgxMDApDQpwYXIobWFyPWMoMCwwLDEsMCkpDQpwbG90KGludl9hZmZfaWcsDQogICAgIGxheW91dCA9IGxheW91dC5hdXRvKGludl9hZmZfaWcpLA0KICAgICB2ZXJ0ZXguc2l6ZSA9IDMsDQogICAgIHZlcnRleC5mcmFtZS5jb2xvcj0iYmxhY2siLA0KICAgICB2ZXJ0ZXguY29sb3IgPSBWKGludl9hZmZfaWcpJGNpdHlfbmFtZV9jb2xvciwNCiAgICAgdmVydGV4LmxhYmVsID0gTkEsDQogICAgIGVkZ2UuY29sb3I9ICJibGFjayIsDQogICAgIG1haW49IkludmVudG9ycyBmcm9tIFNhbHpiZXJnZW4gaW4gdG9wIDE1IGNpdHkncyBuZXR3b3JrIikNCmBgYA0KDQojIyBSZW5kc2J1cmcNCg0KYGBge3IgcmVuZHNidXJnIHBvc2l0aW9ufQ0KIyMgcG9zaXRpb24gb2YgdGhlIGNpdGllcyBpbiB0aGUgb3ZlcmFsbCBuZXR3b3JrDQppbnZfcGVyc29uX3BhcnNlZCRjaXR5IDwtIGludl9wZXJfYXR0ciRjaXR5W21hdGNoKGludl9wZXJzb25fcGFyc2VkJGFwcGxuX2lkLCBpbnZfcGVyc29uX3BhcnNlZCRhcHBsbl9pZCldDQpWKGludl9hZmZfaWcpJGlkIDwtIGNvbG5hbWVzKGludl9wZXJzb25fYWRqKQ0KVihpbnZfYWZmX2lnKSRjaXR5X25hbWUgPC0gaW52X3BlcnNvbl9wYXJzZWQkY2l0eVttYXRjaChWKGludl9hZmZfaWcpJGlkLCBpbnZfcGVyc29uX3BhcnNlZCRpbnZfbmFtZSldDQpWKGludl9hZmZfaWcpJGlkIDwtIGNvbG5hbWVzKGludl9wZXJzb25fYWRqKQ0KDQpWKGludl9hZmZfaWcpJGNpdHlfbmFtZV9jb2xvciA8LSBpZmVsc2UoVihpbnZfYWZmX2lnKSRjaXR5X25hbWUgPT0gIlJlbmRzYnVyZyIsICJkYXJrbWFnZW50YSIsImF6dXJlMSIpDQojVihpbnZfYWZmX2lnKSRpZFtkZWdyZWUoaW52X2FmZl9pZyk+NV0NCiNkZWdyZWUoaW52X2FmZl9pZykNCg0Kc2V0LnNlZWQoMTAwKQ0KcGFyKG1hcj1jKDAsMCwxLDApKQ0KcGxvdChpbnZfYWZmX2lnLA0KICAgICBsYXlvdXQgPSBsYXlvdXQuYXV0byhpbnZfYWZmX2lnKSwNCiAgICAgdmVydGV4LnNpemUgPSAzLA0KICAgICB2ZXJ0ZXguZnJhbWUuY29sb3I9ImJsYWNrIiwNCiAgICAgdmVydGV4LmNvbG9yID0gVihpbnZfYWZmX2lnKSRjaXR5X25hbWVfY29sb3IsDQogICAgIHZlcnRleC5sYWJlbCA9IE5BLA0KICAgICBlZGdlLmNvbG9yPSAiYmxhY2siLA0KICAgICBtYWluPSJJbnZlbnRvcnMgZnJvbSBSZW5kc2J1cmcgaW4gdG9wIDE1IGNpdHkncyBuZXR3b3JrIikNCmBgYA0KDQojIEludmVudG9ycyBieSBIaWdoZXN0IERlZ3JlZSAoPjYpDQoNCmBgYHtyIGludiBkZWdyZWV9DQppbnZfcGVyc29uX3BhcnNlZCRjaXR5IDwtIGludl9wZXJfYXR0ciRjaXR5W21hdGNoKGludl9wZXJzb25fcGFyc2VkJGFwcGxuX2lkLCBpbnZfcGVyc29uX3BhcnNlZCRhcHBsbl9pZCldDQpWKGludl9hZmZfaWcpJGlkIDwtIGNvbG5hbWVzKGludl9wZXJzb25fYWRqKQ0KVihpbnZfYWZmX2lnKSRjaXR5X25hbWUgPC0gaW52X3BlcnNvbl9wYXJzZWQkY2l0eVttYXRjaChWKGludl9hZmZfaWcpJGlkLCBpbnZfcGVyc29uX3BhcnNlZCRpbnZfbmFtZSldDQpWKGludl9hZmZfaWcpJGlkIDwtIGNvbG5hbWVzKGludl9wZXJzb25fYWRqKQ0KVihpbnZfYWZmX2lnKSRjaXR5X25hbWVfY29sb3IgPC0gaWZlbHNlKFYoaW52X2FmZl9pZykkY2l0eV9uYW1lID09ICJBdXJpY2giLCAieWVsbG93IiwgImdyYXkiKQ0KYGBgDQoNCiMjIFBvc2l0aW9uIGluIHRoZSBuZXR3b3JrDQoNCmBgYHtyIGhpZ2ggZGVnIGludiBwbG90fQ0Kc2V0LnNlZWQoMTAwKQ0KcGFyKG1hcj1jKDAsMCwxLDApKQ0KcGxvdChpbnZfYWZmX2lnLA0KICAgICBsYXlvdXQgPSBsYXlvdXQuYXV0byhpbnZfYWZmX2lnKSwNCiAgICAgdmVydGV4LnNpemUgPSBkZWdyZWUoaW52X2FmZl9pZyksDQogICAgIHZlcnRleC5jb2xvciA9IE5BLA0KICAgICB2ZXJ0ZXgubGFiZWwgPSBpZmVsc2UoZGVncmVlKGludl9hZmZfaWcpPiA2LCBWKGludl9hZmZfaWcpJGlkLCBOQSksDQogICAgIG1haW49IkhpZ2Voc3QgRGVncmVlIEludmVudG9ycyIpDQoNCmBgYA0KDQojIyBDaXR5IGFmZmlsaWF0aW9uIG9mIHRoZSBpbnZlbnRvcnMNCg0KYGBge3IgaGlnaCBkZWcgaW52IGluIHRhYmxlfQ0KaGlnaF9kZWdyZWVfaW52IDwtIGFzLmRhdGEuZnJhbWUodW5pcXVlKGhpZ2hfZGVncmVlX2ludiA8LSAoaW52X3BlcnNvbl9wYXJzZWQgJT4lDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcihpbnZfbmFtZSAlaW4lIGMoImFsdGVtYXJrLCBqZW5zIiwiaGFybXMsIHVscmljaCIsImp1cmthdCwgbWFyayIpKSAlPiUgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGVjdChpbnZfbmFtZSwgY2l0eSkpKSkNCmhpZ2hfZGVncmVlX2ludiAlPiUgDQogIGtuaXRyOjprYWJsZShjYXB0aW9uID0gIkludmVudG9ycyB3aXRoIEhpZ2hlc3QgRGVncmVlIGFuZCBUaGVpciBDaXR5IEFmZmlsaXRpb25zIikgJT4lIA0KICBrYWJsZV9zdHlsaW5nKGJvb3RzdHJhcF9vcHRpb25zID0gYygic3RyaXBlZCIsInJlc3BvbnNpdmUiLCAiaG92ZXIiKSwgZnVsbF93aWR0aCA9IEYpDQpgYGA=