Then run the following lines
set.seed(char2seed(myname)) rod.inspection = sample_frac(rod.inspection, .8) rod.inspection = rod.inspection[, sample(1:ncol(rod.inspection))]
r
r library(magrittr) install.packages() library(tidyverse) install.packages() library(lubridate) install.packages(2) library(ggplot2) install.packages() library(magrittr) install.packages() library(dplyr)
Part 1a)
r
r #Converting the given date to separate values for date, month, and year findMonths = as.data.frame(select(rod.inspection, INSPECTION_DATE, BOROUGH, RESULT, ZIP_CODE)) findMonths\(dates = sub(\ .*\, \\, findMonths\)INSPECTION_DATE) findMonths\(dates = mdy(findMonths\)dates) findMonths\(month_year = paste(month(findMonths\)dates), year(findMonths\(dates), 1, sep = \/\) findMonths\)month = month(findMonths\(dates) findMonths\)year = year(findMonths$dates)
#For Bronx bronx_df = filter(findMonths, BOROUGH == & RESULT == Rat Signs, year >= 2012) bronx = as.data.frame(table(bronx_df\(month_year)) bronx\)my = as.Date(bronx$Var1, %m/%Y/%d) bronx_plot = ggplot(bronx, aes(my, Freq)) + geom_line() + geom_point() + ylim(0, 900) print(bronx_plot + ggtitle(Sighting in Bronx over 5 Years) + labs(y=of Sighting, x = ))

r
r
#For Manhattan man_df = filter(findMonths, BOROUGH == & RESULT == Rat Signs, year >= 2012) man_df = as.data.frame(table(man_df\(month_year)) man_df\)my = as.Date(man_df$Var1, %m/%Y/%d) man_plot = ggplot(man_df, aes(my, Freq)) + geom_line() + geom_point() + ylim(0, 900) print(man_plot + ggtitle(Sighting in Manhattan over 5 Years) + labs(y=of Sighting, x = ))

r
r
#For Brooklyn brook_df = filter(findMonths, BOROUGH == & RESULT == Rat Signs, year >= 2012) brook_df = as.data.frame(table(brook_df\(month_year)) brook_df\)my = as.Date(brook_df$Var1, %m/%Y/%d) brook_plot = ggplot(brook_df, aes(my, Freq)) + geom_line() + geom_point() + ylim(0, 900) print(brook_plot + ggtitle(Sighting in Brooklyn over 5 Years) + labs(y=of Sighting, x = ))

r
r
#For Queens queens_df = filter(findMonths, BOROUGH == & RESULT == Rat Signs, year >= 2012) queens_df = as.data.frame(table(queens_df\(month_year)) queens_df\)my = as.Date(queens_df$Var1, %m/%Y/%d) queens_plot = ggplot(queens_df, aes(my, Freq)) + geom_line() + geom_point() + ylim(0, 200) print(queens_plot + ggtitle(Sighting in Queens over 5 Years) + labs(y=of Sighting, x = ))

r
r
#For Staten Island stat_df = filter(findMonths, BOROUGH == Island & RESULT == Rat Signs, year >= 2012) stat_df = as.data.frame(table(stat_df\(month_year)) stat_df\)my = as.Date(stat_df$Var1, %m/%Y/%d) stat_plot = ggplot(stat_df, aes(my, Freq)) + geom_line() + geom_point() + ylim(0, 100) print(stat_plot + ggtitle(Sighting in Staten Island over 5 Years) + labs(y=of Sighting, x = ))

Part 1b)
Based on the 5 graphs across the 5 different Boroughs, it appears that rat sightings have generally stayed the same, though they spike/dip in certains months.
Part 1c)
Yes there does appear to be seasonal rat sightings. From the 5 graphs, it appears that rat sightings tend to be higher during the Spring time, from March to May. On the other hand, the rat sightings tend to be lower during the Winter time, from October/November to February.
Part 1d)
r
r #Number to indicate if there are rat signs findMonths\(rat_count = ifelse(findMonths\)RESULT == Rat Signs,1,0)
#Check efficiency by summing rat signs over total efficiency = findMonths %>% group_by(month, year, BOROUGH) %>% summarize(eff = (sum(rat_count == \1) / n()))
efficiency\(ym = paste(as.character(efficiency\)year), . ,as.character(efficiency$month),sep = \) efficiency = filter(efficiency, ym >= 2012.03)
#Plot the graph library(ggplot2) ggplot(efficiency, aes(x = ym, y = eff, group = BOROUGH, color = BOROUGH)) + geom_line() + geom_point() + theme(plot.title = element_text(hjust = 0.5), axis.text.x = element_text(vjust = 1, size = 5, angle = 90)) + ggtitle(of rat inspections) + labs(y=, x = and Year)

Part 1e)
The top 10 zip codes of rat sightings are (in descending order): 10457, 10458, 10456, 10468, 11221, 10453, 10452, 11237, 10467, 11206
r
r #Find the top zip codes with rat sightings findMonths\(rat_count = ifelse(findMonths\)RESULT == Rat Signs,1,0) Top_zips = findMonths %>%
#Group by zipcode and check the number of rat counts group_by(ZIP_CODE) %>% filter(year >= 2012 & RESULT == Rat Signs) %>% summarize(rat_sightings = (sum(rat_count == \1))) Top_zips = Top_zips[order(Top_zips$rat_sightings,decreasing = TRUE),][1:10,] Top_zips
Part 2
r
r #Import data sandy_calls = read.csv(/Users/yuyangwang 1/Desktop/OIDD 245/Rats/sandyrelated.csv)
Part 2a)
It is difficult to say given the limited amount of data for the days preceding Hurrican Sandy. However, during Sandy, sighting were very low but after, there is a general increase in rat sightings.
r
r #Create data frame with complaint type and dates + modify the dates as above sandyRodentChange = as.data.frame(select(sandy_calls, Created.Date, Complaint.Type)) sandyRodentChange\(dates = sub(\ .*\, \\, sandyRodentChange\)Created.Date) sandyRodentChange\(dates = mdy(sandyRodentChange\)dates) sandyRodentChange\(month_year = paste(month(sandyRodentChange\)dates), year(sandyRodentChange\(dates), 1, sep = \/\) sandyRodentChange\)month = month(sandyRodentChange\(dates) sandyRodentChange\)year = year(sandyRodentChange\(dates) sandyRodentChange\)dates = as.Date(sandyRodentChange$dates)
#Choose dates of the 1 week periods before and after Sandy rodent_obs = sandyRodentChange[sandyRodentChange\(dates >= as.Date(\2012-10-22\) & sandyRodentChange\)dates <= as.Date(\2012-11-05),] rodent_obs = rodent_obs %>% group_by(dates) %>% summarize(Freq = (sum(Complaint.Type == )))
#Show before and after plot before_after_plot = ggplot(rodent_obs, aes(dates, Freq)) + geom_line() print(before_after_plot + ggtitle(Complaints Before/After Hurricane Sandy Ocuurence) + labs(y=of Sighting, x = ))

Part 2b)
The two other complaints most correlated with rodent sightings are NONCOST and PLUMBING.
r
r #Find top15 complaints + rodent tally = tally(group_by(sandy_calls, Complaint.Type)) tally1 = tally[order(tally$n, decreasing = TRUE),] tally2 = head(tally1, 15) tally2 = rbind(tally2, c(, ))
#Create another table that is grouped by incident zip and complaint types comp_zip = sandy_calls %>% group_by(Incident.Zip, Complaint.Type) %>% summarize(complaint_number= n())
#Filter down to the top 15 complaints + Rodent comp_zip = filter(comp_zip, Complaint.Type %in% tally2$Complaint.Type)
#Transpose this dataframe library(reshape2) trans_df = dcast(comp_zip, Incident.Zip ~ Complaint.Type, value.var=_number)
#Change all the null values to 0 trans_df[is.na(trans_df)] = 0
#Create a correlation dataframe correlation = as.data.frame(cor(trans_df[2:16]))
#Delete all other columns except the column with Rodents. Create new names for the rows and columns rodent_correlation = correlation[] rodent_correlation\(Complaint.Type = rownames(rodent_correlation) colnames(rodent_correlation) = c(\correlation\, \complaints\) rodent_correlation = rodent_correlation[order(rodent_correlation\)correlation,decreasing = TRUE),] rodent_correlation
Part 3)
The relationship is statitistically significant because the p value is < 0.05 and that based on the Signif codes denoted by the number of ’*’s, there is a high significance.
r
r Resto = read.csv(/Users/yuyangwang 1/Desktop/OIDD 245/Rats/DOHMH_New_York_City_Restaurant_Inspection_Results.csv)
#From the date column, create separate columns of month and year Resto\(INSPECTION.DATE = as.character(Resto\)INSPECTION.DATE) Resto\(date.month = sapply(strsplit(Resto\)INSPECTION.DATE,/),[,1) Resto\(date.year = sapply(strsplit(Resto\)INSPECTION.DATE,/),[,3)
#Check if there are rat violations Resto\(Rest_Rat = ifelse(Resto\)VIOLATION.CODE == \04L| Resto\(VIOLATION.CODE == \04K\ | Resto\)VIOLATION.CODE == \08A, 1, 0)
RestaurantRatViolations = Resto %>% group_by(ZIPCODE, date.month, date.year)%>% summarize(Resto_Rats = sum(Rest_Rat))
#Merging Restaurant Inspection with Rodent Inspection Data with a left join rod.inspection
\(INSPECTION_DATE = as.character(rod.inspection\)INSPECTION_DATE) rod.inspection
\(inspect_d = sapply(strsplit(rod.inspection\)INSPECTION_DATE, ),[,1) rod.inspection
\(inspect_dm =sapply(strsplit(rod.inspection\)inspect_d,/),[,1) rod.inspection
\(inspect_dy =sapply(strsplit(rod.inspection\)inspect_d,/),[,3) merged_df = merge(rod.inspection, RestaurantRatViolations, by.x = c(_dy,_dm, _CODE), by.y = c(
year,
month,), all.x = TRUE)
#Convert any missing restaurant violation numbers to 0. Add 1 and Log this measure merged_df\(Resto_Rats[is.na(merged_df\)Resto_Rats)] = 0 merged_df\(Resto_Rats = log(merged_df\)Resto_Rats+1)
#Again check if there are Active Rat Signs merged_df\(Active_Rats = as.integer(merged_df\)RESULT == Rat Signs) answer = filter(merged_df, inspect_dy >= 2012)
#Convert month and year into factor variables answer\(inspect_dy = as.factor(answer\)inspect_dy) answer\(inspect_dm = as.factor(answer\)inspect_dm)
#Step 4 Run a logistic regression on the new data set to test whether the estimated coefficient on the restaurant sightings variable has a statistically significant relationship with whether or not an inspection yields Active Rat Signs and–if it is significant–whether the relationship is positive or negative. summary(glm(data = answer, Active_Rats ~ Resto_Rats + inspect_dm + inspect_dy, family=binomial))
Call:
glm(formula = Active_Rats ~ Resto_Rats + inspect_dm + inspect_dy,
family = binomial, data = answer)
Deviance Residuals:
Min 1Q Median 3Q Max
-0.6235 -0.5246 -0.4980 -0.4498 2.2447
Coefficients:
Estimate Std. Error z value Pr(>|z|)
(Intercept) -2.133907 0.018645 -114.449 < 2e-16 ***
Resto_Rats 0.081518 0.005363 15.200 < 2e-16 ***
inspect_dm02 -0.207287 0.021836 -9.493 < 2e-16 ***
inspect_dm03 -0.156715 0.020698 -7.572 3.69e-14 ***
inspect_dm04 -0.247597 0.021746 -11.386 < 2e-16 ***
inspect_dm05 -0.237991 0.022145 -10.747 < 2e-16 ***
inspect_dm06 -0.145503 0.022772 -6.390 1.66e-10 ***
inspect_dm07 -0.055295 0.022228 -2.488 0.01286 *
inspect_dm08 -0.070489 0.022622 -3.116 0.00183 **
inspect_dm09 -0.183835 0.022954 -8.009 1.16e-15 ***
inspect_dm10 -0.123898 0.022850 -5.422 5.89e-08 ***
inspect_dm11 -0.194290 0.024724 -7.859 3.89e-15 ***
inspect_dm12 -0.301560 0.024244 -12.439 < 2e-16 ***
inspect_dy2013 0.152147 0.014867 10.234 < 2e-16 ***
inspect_dy2014 0.123170 0.015170 8.120 4.68e-16 ***
inspect_dy2015 0.188986 0.015466 12.219 < 2e-16 ***
inspect_dy2016 0.254372 0.023876 10.654 < 2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
(Dispersion parameter for binomial family taken to be 1)
Null deviance: 355102 on 488234 degrees of freedom
Residual deviance: 353665 on 488218 degrees of freedom
(2 observations deleted due to missingness)
AIC: 353699
Number of Fisher Scoring iterations: 4
Part 4
One question that I may still want to answer regarding rodents is that are locations closer to garbage locations more prone to rodent sightings?
A specific data set that can be used to answer this question is a data set provided Open Data NYC, which lists the Food Scrap drop-off locations in New York City. It contains information on the location (longitude, latitude, zip code, borough) as well as the days of the week that those drop-off spots are open. This can be joined with the current data based on either zip code, borough, or coordinates.
https://data.cityofnewyork.us/Environment/Food-Scrap-Drop-Off-Locations-in-NYC/if26-z6xq
Finally, the analysis we could conduct is using geo spatial data and mapping this drop-off locations on a map. Then, using the current rodent sighting data, we can create visuals (such as heat maps) to see if these locations do have the highest densities of sightings. Moreover, we can see how these sightings differ among days of the week depending on which days they are open.
LS0tCnRpdGxlOiAiTllDIFJhdHMgQW5hbHlzaXMgYnkgWXV5YW5nIFdhbmciCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCmBgYHtyfQppbnN0YWxsLnBhY2thZ2VzKCJUZWFjaGluZ0RlbW9zIikKaW5zdGFsbC5wYWNrYWdlcygicmVhZHIiKQoKbGlicmFyeSgiVGVhY2hpbmdEZW1vcyIpCmxpYnJhcnkoImRwbHlyIikKbGlicmFyeSgicmVhZHIiKQoKcm9kLmluc3BlY3Rpb24gPSByZWFkX2NzdigieHh4IikKCiMgSW4gdGhlIGxpbmUgYmVsb3csIGNoYW5nZSAiSmFjayBCbGFjayIgdG8geW91ciBvd24gbmFtZQpteW5hbWUgPSAiWXV5YW5nIFdhbmciCgojIFRoZW4gcnVuIHRoZSBmb2xsb3dpbmcgbGluZXMKc2V0LnNlZWQoY2hhcjJzZWVkKG15bmFtZSkpCnJvZC5pbnNwZWN0aW9uID0gc2FtcGxlX2ZyYWMocm9kLmluc3BlY3Rpb24sIC44KQpyb2QuaW5zcGVjdGlvbiA9IHJvZC5pbnNwZWN0aW9uWywgc2FtcGxlKDE6bmNvbChyb2QuaW5zcGVjdGlvbikpXSAKYGBgCgpgYGB7cn0KbGlicmFyeShtYWdyaXR0cikKaW5zdGFsbC5wYWNrYWdlcygidGlkeXZlcnNlIikKbGlicmFyeSh0aWR5dmVyc2UpCmluc3RhbGwucGFja2FnZXMoImx1YnJpZGF0ZSIpCmxpYnJhcnkobHVicmlkYXRlKQppbnN0YWxsLnBhY2thZ2VzKCJnZ3Bsb3QyIikgCmxpYnJhcnkoZ2dwbG90MikKaW5zdGFsbC5wYWNrYWdlcygibWFncml0dHIiKQpsaWJyYXJ5KG1hZ3JpdHRyKQppbnN0YWxsLnBhY2thZ2VzKCJkcGx5ciIpCmxpYnJhcnkoZHBseXIpCgpgYGAKClBhcnQgMWEpCgpgYGB7cn0KI0NvbnZlcnRpbmcgdGhlIGdpdmVuIGRhdGUgdG8gc2VwYXJhdGUgdmFsdWVzIGZvciBkYXRlLCBtb250aCwgYW5kIHllYXIKZmluZE1vbnRocyA9IGFzLmRhdGEuZnJhbWUoc2VsZWN0KHJvZC5pbnNwZWN0aW9uLCBJTlNQRUNUSU9OX0RBVEUsIEJPUk9VR0gsIFJFU1VMVCwgWklQX0NPREUpKQpmaW5kTW9udGhzJGRhdGVzID0gc3ViKCIgLioiLCAiIiwgZmluZE1vbnRocyRJTlNQRUNUSU9OX0RBVEUpCmZpbmRNb250aHMkZGF0ZXMgPSBtZHkoZmluZE1vbnRocyRkYXRlcykKZmluZE1vbnRocyRtb250aF95ZWFyID0gcGFzdGUobW9udGgoZmluZE1vbnRocyRkYXRlcyksIHllYXIoZmluZE1vbnRocyRkYXRlcyksIDEsIHNlcCA9ICIvIikKZmluZE1vbnRocyRtb250aCA9IG1vbnRoKGZpbmRNb250aHMkZGF0ZXMpCmZpbmRNb250aHMkeWVhciA9IHllYXIoZmluZE1vbnRocyRkYXRlcykKCiNGb3IgQnJvbngKYnJvbnhfZGYgPSBmaWx0ZXIoZmluZE1vbnRocywgQk9ST1VHSCA9PSAiQnJvbngiICYgUkVTVUxUID09ICJBY3RpdmUgUmF0IFNpZ25zIiwgeWVhciA+PSAyMDEyKQpicm9ueCA9IGFzLmRhdGEuZnJhbWUodGFibGUoYnJvbnhfZGYkbW9udGhfeWVhcikpCmJyb254JG15ID0gYXMuRGF0ZShicm9ueCRWYXIxLCAiJW0vJVkvJWQiKQpicm9ueF9wbG90ID0gZ2dwbG90KGJyb254LCBhZXMobXksIEZyZXEpKSArIGdlb21fbGluZSgpICsgZ2VvbV9wb2ludCgpICsgeWxpbSgwLCA5MDApCnByaW50KGJyb254X3Bsb3QgKyBnZ3RpdGxlKCJSYXQgU2lnaHRpbmcgaW4gQnJvbnggb3ZlciA1IFllYXJzIikgKyBsYWJzKHk9Ik51bWJlciBvZiBTaWdodGluZyIsIHggPSAiWWVhciIpKSAKCiNGb3IgTWFuaGF0dGFuCm1hbl9kZiA9IGZpbHRlcihmaW5kTW9udGhzLCBCT1JPVUdIID09ICJNYW5oYXR0YW4iICYgUkVTVUxUID09ICJBY3RpdmUgUmF0IFNpZ25zIiwgeWVhciA+PSAyMDEyKQptYW5fZGYgPSBhcy5kYXRhLmZyYW1lKHRhYmxlKG1hbl9kZiRtb250aF95ZWFyKSkKbWFuX2RmJG15ID0gYXMuRGF0ZShtYW5fZGYkVmFyMSwgIiVtLyVZLyVkIikKbWFuX3Bsb3QgPSBnZ3Bsb3QobWFuX2RmLCBhZXMobXksIEZyZXEpKSArIGdlb21fbGluZSgpICsgZ2VvbV9wb2ludCgpICsgeWxpbSgwLCA5MDApCnByaW50KG1hbl9wbG90ICsgZ2d0aXRsZSgiUmF0IFNpZ2h0aW5nIGluIE1hbmhhdHRhbiBvdmVyIDUgWWVhcnMiKSArIGxhYnMoeT0iTnVtYmVyIG9mIFNpZ2h0aW5nIiwgeCA9ICJZZWFyIikpCgojRm9yIEJyb29rbHluCmJyb29rX2RmID0gZmlsdGVyKGZpbmRNb250aHMsIEJPUk9VR0ggPT0gIkJyb29rbHluIiAmIFJFU1VMVCA9PSAiQWN0aXZlIFJhdCBTaWducyIsIHllYXIgPj0gMjAxMikKYnJvb2tfZGYgPSBhcy5kYXRhLmZyYW1lKHRhYmxlKGJyb29rX2RmJG1vbnRoX3llYXIpKQpicm9va19kZiRteSA9IGFzLkRhdGUoYnJvb2tfZGYkVmFyMSwgIiVtLyVZLyVkIikKYnJvb2tfcGxvdCA9IGdncGxvdChicm9va19kZiwgYWVzKG15LCBGcmVxKSkgKyBnZW9tX2xpbmUoKSArIGdlb21fcG9pbnQoKSArIHlsaW0oMCwgOTAwKQpwcmludChicm9va19wbG90ICsgZ2d0aXRsZSgiUmF0IFNpZ2h0aW5nIGluIEJyb29rbHluIG92ZXIgNSBZZWFycyIpICsgbGFicyh5PSJOdW1iZXIgb2YgU2lnaHRpbmciLCB4ID0gIlllYXIiKSkKCgojRm9yIFF1ZWVucwpxdWVlbnNfZGYgPSBmaWx0ZXIoZmluZE1vbnRocywgQk9ST1VHSCA9PSAiUXVlZW5zIiAmIFJFU1VMVCA9PSAiQWN0aXZlIFJhdCBTaWducyIsIHllYXIgPj0gMjAxMikKcXVlZW5zX2RmID0gYXMuZGF0YS5mcmFtZSh0YWJsZShxdWVlbnNfZGYkbW9udGhfeWVhcikpCnF1ZWVuc19kZiRteSA9IGFzLkRhdGUocXVlZW5zX2RmJFZhcjEsICIlbS8lWS8lZCIpCnF1ZWVuc19wbG90ID0gZ2dwbG90KHF1ZWVuc19kZiwgYWVzKG15LCBGcmVxKSkgKyBnZW9tX2xpbmUoKSArIGdlb21fcG9pbnQoKSArIHlsaW0oMCwgMjAwKQpwcmludChxdWVlbnNfcGxvdCArIGdndGl0bGUoIlJhdCBTaWdodGluZyBpbiBRdWVlbnMgb3ZlciA1IFllYXJzIikgKyBsYWJzKHk9Ik51bWJlciBvZiBTaWdodGluZyIsIHggPSAiWWVhciIpKQoKCiNGb3IgU3RhdGVuIElzbGFuZApzdGF0X2RmID0gZmlsdGVyKGZpbmRNb250aHMsIEJPUk9VR0ggPT0gIlN0YXRlbiBJc2xhbmQiICYgUkVTVUxUID09ICJBY3RpdmUgUmF0IFNpZ25zIiwgeWVhciA+PSAyMDEyKQpzdGF0X2RmID0gYXMuZGF0YS5mcmFtZSh0YWJsZShzdGF0X2RmJG1vbnRoX3llYXIpKQpzdGF0X2RmJG15ID0gYXMuRGF0ZShzdGF0X2RmJFZhcjEsICIlbS8lWS8lZCIpCnN0YXRfcGxvdCA9IGdncGxvdChzdGF0X2RmLCBhZXMobXksIEZyZXEpKSArIGdlb21fbGluZSgpICsgZ2VvbV9wb2ludCgpICsgeWxpbSgwLCAxMDApCnByaW50KHN0YXRfcGxvdCArIGdndGl0bGUoIlJhdCBTaWdodGluZyBpbiBTdGF0ZW4gSXNsYW5kIG92ZXIgNSBZZWFycyIpICsgbGFicyh5PSJOdW1iZXIgb2YgU2lnaHRpbmciLCB4ID0gIlllYXIiKSkKCmBgYAoKUGFydCAxYikKCkJhc2VkIG9uIHRoZSA1IGdyYXBocyBhY3Jvc3MgdGhlIDUgZGlmZmVyZW50IEJvcm91Z2hzLCBpdCBhcHBlYXJzIHRoYXQgcmF0IHNpZ2h0aW5ncyBoYXZlIGdlbmVyYWxseSBzdGF5ZWQgdGhlIHNhbWUsIHRob3VnaCB0aGV5IHNwaWtlL2RpcCBpbiBjZXJ0YWlucyBtb250aHMuCgpQYXJ0IDFjKQoKWWVzIHRoZXJlIGRvZXMgYXBwZWFyIHRvIGJlIHNlYXNvbmFsIHJhdCBzaWdodGluZ3MuIEZyb20gdGhlIDUgZ3JhcGhzLCBpdCBhcHBlYXJzIHRoYXQgcmF0IHNpZ2h0aW5ncyB0ZW5kIHRvIGJlIGhpZ2hlciBkdXJpbmcgdGhlIFNwcmluZyB0aW1lLCBmcm9tIE1hcmNoIHRvIE1heS4gT24gdGhlIG90aGVyIGhhbmQsIHRoZSByYXQgc2lnaHRpbmdzIHRlbmQgdG8gYmUgbG93ZXIgZHVyaW5nIHRoZSBXaW50ZXIgdGltZSwgZnJvbSBPY3RvYmVyL05vdmVtYmVyIHRvIEZlYnJ1YXJ5LgoKUGFydCAxZCkKCmBgYHtyfQojTnVtYmVyIHRvIGluZGljYXRlIGlmIHRoZXJlIGFyZSByYXQgc2lnbnMKZmluZE1vbnRocyRyYXRfY291bnQgPSBpZmVsc2UoZmluZE1vbnRocyRSRVNVTFQgPT0gIkFjdGl2ZSBSYXQgU2lnbnMiLDEsMCkKCiNDaGVjayBlZmZpY2llbmN5IGJ5IHN1bW1pbmcgcmF0IHNpZ25zIG92ZXIgdG90YWwgCmVmZmljaWVuY3kgPSBmaW5kTW9udGhzICU+JQogIGdyb3VwX2J5KG1vbnRoLCB5ZWFyLCBCT1JPVUdIKSAlPiUKICBzdW1tYXJpemUoZWZmID0gKHN1bShyYXRfY291bnQgPT0gIjEiKSAvIG4oKSkpCgplZmZpY2llbmN5JHltID0gcGFzdGUoYXMuY2hhcmFjdGVyKGVmZmljaWVuY3kkeWVhciksICIuIiAsYXMuY2hhcmFjdGVyKGVmZmljaWVuY3kkbW9udGgpLHNlcCA9ICIiKQplZmZpY2llbmN5ID0gZmlsdGVyKGVmZmljaWVuY3ksIHltID49IDIwMTIuMDMpCgojUGxvdCB0aGUgZ3JhcGggCmxpYnJhcnkoZ2dwbG90MikKZ2dwbG90KGVmZmljaWVuY3ksIGFlcyh4ID0geW0sIHkgPSBlZmYsIGdyb3VwID0gQk9ST1VHSCwgY29sb3IgPSBCT1JPVUdIKSkgKyBnZW9tX2xpbmUoKSArIGdlb21fcG9pbnQoKSArIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpLCBheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dCh2anVzdCA9IDEsIHNpemUgPSA1LCBhbmdsZSA9IDkwKSkgKyBnZ3RpdGxlKCJFZmZpY2llbmN5IG9mIHJhdCBpbnNwZWN0aW9ucyIpICsgIGxhYnMoeT0iRWZmaWNpZW5jeSIsIHggPSAiTW9udGggYW5kIFllYXIiKQpgYGAKClBhcnQgMWUpCgpUaGUgdG9wIDEwIHppcCBjb2RlcyBvZiByYXQgc2lnaHRpbmdzIGFyZSAoaW4gZGVzY2VuZGluZyBvcmRlcik6CjEwNDU3LCAxMDQ1OCwgMTA0NTYsIDEwNDY4LCAxMTIyMSwgMTA0NTMsIDEwNDUyLCAxMTIzNywgMTA0NjcsIDExMjA2CQoKYGBge3J9CiNGaW5kIHRoZSB0b3AgemlwIGNvZGVzIHdpdGggcmF0IHNpZ2h0aW5ncwpmaW5kTW9udGhzJHJhdF9jb3VudCA9IGlmZWxzZShmaW5kTW9udGhzJFJFU1VMVCA9PSAiQWN0aXZlIFJhdCBTaWducyIsMSwwKQpUb3BfemlwcyA9IGZpbmRNb250aHMgJT4lIAogIAojR3JvdXAgYnkgemlwY29kZSBhbmQgY2hlY2sgdGhlIG51bWJlciBvZiByYXQgY291bnRzCmdyb3VwX2J5KFpJUF9DT0RFKSAlPiUKICBmaWx0ZXIoeWVhciA+PSAyMDEyICYgUkVTVUxUID09ICJBY3RpdmUgUmF0IFNpZ25zIikgJT4lIAogIHN1bW1hcml6ZShyYXRfc2lnaHRpbmdzID0gKHN1bShyYXRfY291bnQgPT0gIjEiKSkpClRvcF96aXBzID0gVG9wX3ppcHNbb3JkZXIoVG9wX3ppcHMkcmF0X3NpZ2h0aW5ncyxkZWNyZWFzaW5nID0gVFJVRSksXVsxOjEwLF0KVG9wX3ppcHMKYGBgCgpQYXJ0IDIKCmBgYHtyfQojSW1wb3J0IGRhdGEKc2FuZHlfY2FsbHMgPSByZWFkLmNzdigiL1VzZXJzL3l1eWFuZ3dhbmcgMS9EZXNrdG9wL09JREQgMjQ1L1JhdHMvc2FuZHlyZWxhdGVkLmNzdiIpCmBgYAoKUGFydCAyYSkKCkl0IGlzIGRpZmZpY3VsdCB0byBzYXkgZ2l2ZW4gdGhlIGxpbWl0ZWQgYW1vdW50IG9mIGRhdGEgZm9yIHRoZSBkYXlzIHByZWNlZGluZyBIdXJyaWNhbiBTYW5keS4gSG93ZXZlciwgZHVyaW5nIFNhbmR5LCBzaWdodGluZyB3ZXJlIHZlcnkgbG93IGJ1dCBhZnRlciwgdGhlcmUgaXMgYSBnZW5lcmFsIGluY3JlYXNlIGluIHJhdCBzaWdodGluZ3MuIAoKYGBge3J9CiNDcmVhdGUgZGF0YSBmcmFtZSB3aXRoIGNvbXBsYWludCB0eXBlIGFuZCBkYXRlcyArIG1vZGlmeSB0aGUgZGF0ZXMgYXMgYWJvdmUKc2FuZHlSb2RlbnRDaGFuZ2UgPSBhcy5kYXRhLmZyYW1lKHNlbGVjdChzYW5keV9jYWxscywgQ3JlYXRlZC5EYXRlLCBDb21wbGFpbnQuVHlwZSkpCnNhbmR5Um9kZW50Q2hhbmdlJGRhdGVzID0gc3ViKCIgLioiLCAiIiwgc2FuZHlSb2RlbnRDaGFuZ2UkQ3JlYXRlZC5EYXRlKQpzYW5keVJvZGVudENoYW5nZSRkYXRlcyA9IG1keShzYW5keVJvZGVudENoYW5nZSRkYXRlcykKc2FuZHlSb2RlbnRDaGFuZ2UkbW9udGhfeWVhciA9IHBhc3RlKG1vbnRoKHNhbmR5Um9kZW50Q2hhbmdlJGRhdGVzKSwgeWVhcihzYW5keVJvZGVudENoYW5nZSRkYXRlcyksIDEsIHNlcCA9ICIvIikKc2FuZHlSb2RlbnRDaGFuZ2UkbW9udGggPSBtb250aChzYW5keVJvZGVudENoYW5nZSRkYXRlcykKc2FuZHlSb2RlbnRDaGFuZ2UkeWVhciA9IHllYXIoc2FuZHlSb2RlbnRDaGFuZ2UkZGF0ZXMpCnNhbmR5Um9kZW50Q2hhbmdlJGRhdGVzID0gYXMuRGF0ZShzYW5keVJvZGVudENoYW5nZSRkYXRlcykKCiNDaG9vc2UgZGF0ZXMgb2YgdGhlIDEgd2VlayBwZXJpb2RzIGJlZm9yZSBhbmQgYWZ0ZXIgU2FuZHkKcm9kZW50X29icyA9IHNhbmR5Um9kZW50Q2hhbmdlW3NhbmR5Um9kZW50Q2hhbmdlJGRhdGVzID49IGFzLkRhdGUoIjIwMTItMTAtMjIiKSAmIHNhbmR5Um9kZW50Q2hhbmdlJGRhdGVzIDw9IGFzLkRhdGUoIjIwMTItMTEtMDUiKSxdCnJvZGVudF9vYnMgPSByb2RlbnRfb2JzICU+JSAKZ3JvdXBfYnkoZGF0ZXMpICU+JQogIHN1bW1hcml6ZShGcmVxID0gKHN1bShDb21wbGFpbnQuVHlwZSA9PSAiUm9kZW50IikpKQoKI1Nob3cgYmVmb3JlIGFuZCBhZnRlciBwbG90CmJlZm9yZV9hZnRlcl9wbG90ID0gZ2dwbG90KHJvZGVudF9vYnMsIGFlcyhkYXRlcywgRnJlcSkpICsgZ2VvbV9saW5lKCkKcHJpbnQoYmVmb3JlX2FmdGVyX3Bsb3QgKyBnZ3RpdGxlKCJSYXQgQ29tcGxhaW50cyBCZWZvcmUvQWZ0ZXIgSHVycmljYW5lIFNhbmR5IE9jdXVyZW5jZSIpICsgbGFicyh5PSJOdW1iZXIgb2YgU2lnaHRpbmciLCB4ID0gIlRpbWUiKSkKYGBgCgpQYXJ0IDJiKQoKVGhlIHR3byBvdGhlciBjb21wbGFpbnRzIG1vc3QgY29ycmVsYXRlZCB3aXRoIHJvZGVudCBzaWdodGluZ3MgYXJlIE5PTkNPU1QgYW5kIFBMVU1CSU5HLgoKYGBge3J9CiNGaW5kIHRvcDE1IGNvbXBsYWludHMgKyByb2RlbnQgCnRhbGx5ID0gdGFsbHkoZ3JvdXBfYnkoc2FuZHlfY2FsbHMsIENvbXBsYWludC5UeXBlKSkKdGFsbHkxID0gdGFsbHlbb3JkZXIodGFsbHkkbiwgZGVjcmVhc2luZyA9IFRSVUUpLF0KdGFsbHkyID0gaGVhZCh0YWxseTEsIDE1KQp0YWxseTIgPSByYmluZCh0YWxseTIsIGMoIlJvZGVudCIsICIgIikpCgojQ3JlYXRlIGFub3RoZXIgdGFibGUgdGhhdCBpcyBncm91cGVkIGJ5IGluY2lkZW50IHppcCBhbmQgY29tcGxhaW50IHR5cGVzCmNvbXBfemlwID0gc2FuZHlfY2FsbHMgJT4lIAogIGdyb3VwX2J5KEluY2lkZW50LlppcCwgQ29tcGxhaW50LlR5cGUpICU+JSAKICBzdW1tYXJpemUoY29tcGxhaW50X251bWJlcj0gbigpKSAKCiNGaWx0ZXIgZG93biB0byB0aGUgdG9wIDE1IGNvbXBsYWludHMgKyBSb2RlbnQKY29tcF96aXAgPSBmaWx0ZXIoY29tcF96aXAsIENvbXBsYWludC5UeXBlICVpbiUgdGFsbHkyJENvbXBsYWludC5UeXBlKQoKI1RyYW5zcG9zZSB0aGlzIGRhdGFmcmFtZQpsaWJyYXJ5KHJlc2hhcGUyKQp0cmFuc19kZiA9IGRjYXN0KGNvbXBfemlwLCBJbmNpZGVudC5aaXAgfiBDb21wbGFpbnQuVHlwZSwgdmFsdWUudmFyPSJjb21wbGFpbnRfbnVtYmVyIikKCiNDaGFuZ2UgYWxsIHRoZSBudWxsIHZhbHVlcyB0byAwIAp0cmFuc19kZltpcy5uYSh0cmFuc19kZildID0gMAoKI0NyZWF0ZSBhIGNvcnJlbGF0aW9uIGRhdGFmcmFtZQpjb3JyZWxhdGlvbiA9IGFzLmRhdGEuZnJhbWUoY29yKHRyYW5zX2RmWzI6MTZdKSkKCiNEZWxldGUgYWxsIG90aGVyIGNvbHVtbnMgZXhjZXB0IHRoZSBjb2x1bW4gd2l0aCBSb2RlbnRzLiBDcmVhdGUgbmV3IG5hbWVzIGZvciB0aGUgcm93cyBhbmQgY29sdW1ucwpyb2RlbnRfY29ycmVsYXRpb24gPSBjb3JyZWxhdGlvblsiUm9kZW50Il0Kcm9kZW50X2NvcnJlbGF0aW9uJENvbXBsYWludC5UeXBlID0gcm93bmFtZXMocm9kZW50X2NvcnJlbGF0aW9uKQpjb2xuYW1lcyhyb2RlbnRfY29ycmVsYXRpb24pID0gYygiY29ycmVsYXRpb24iLCAiY29tcGxhaW50cyIpCnJvZGVudF9jb3JyZWxhdGlvbiA9IHJvZGVudF9jb3JyZWxhdGlvbltvcmRlcihyb2RlbnRfY29ycmVsYXRpb24kY29ycmVsYXRpb24sZGVjcmVhc2luZyA9IFRSVUUpLF0Kcm9kZW50X2NvcnJlbGF0aW9uCmBgYAoKUGFydCAzKQoKVGhlIHJlbGF0aW9uc2hpcCBpcyBzdGF0aXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQgYmVjYXVzZSB0aGUgcCB2YWx1ZSBpcyA8IDAuMDUgYW5kIHRoYXQgYmFzZWQgb24gdGhlIFNpZ25pZiBjb2RlcyBkZW5vdGVkIGJ5IHRoZSBudW1iZXIgb2YgJyoncywgdGhlcmUgaXMgYSBoaWdoIHNpZ25pZmljYW5jZS4KCmBgYHtyfQpSZXN0byA9IHJlYWQuY3N2KCIvVXNlcnMveXV5YW5nd2FuZyAxL0Rlc2t0b3AvT0lERCAyNDUvUmF0cy9ET0hNSF9OZXdfWW9ya19DaXR5X1Jlc3RhdXJhbnRfSW5zcGVjdGlvbl9SZXN1bHRzLmNzdiIpCgojRnJvbSB0aGUgZGF0ZSBjb2x1bW4sIGNyZWF0ZSBzZXBhcmF0ZSBjb2x1bW5zIG9mIG1vbnRoIGFuZCB5ZWFyIApSZXN0byRJTlNQRUNUSU9OLkRBVEUgPSBhcy5jaGFyYWN0ZXIoUmVzdG8kSU5TUEVDVElPTi5EQVRFKQpSZXN0byRkYXRlLm1vbnRoID0gc2FwcGx5KHN0cnNwbGl0KFJlc3RvJElOU1BFQ1RJT04uREFURSwiLyIpLCJbIiwxKQpSZXN0byRkYXRlLnllYXIgPSBzYXBwbHkoc3Ryc3BsaXQoUmVzdG8kSU5TUEVDVElPTi5EQVRFLCIvIiksIlsiLDMpCgojQ2hlY2sgaWYgdGhlcmUgYXJlIHJhdCB2aW9sYXRpb25zClJlc3RvJFJlc3RfUmF0ID0gaWZlbHNlKFJlc3RvJFZJT0xBVElPTi5DT0RFID09ICIwNEwifCBSZXN0byRWSU9MQVRJT04uQ09ERSA9PSAiMDRLIiB8IFJlc3RvJFZJT0xBVElPTi5DT0RFID09ICIwOEEiLCAxLCAwKQoKUmVzdGF1cmFudFJhdFZpb2xhdGlvbnMgPSBSZXN0byAlPiUgCmdyb3VwX2J5KFpJUENPREUsIGRhdGUubW9udGgsIGRhdGUueWVhciklPiUKICBzdW1tYXJpemUoUmVzdG9fUmF0cyA9IHN1bShSZXN0X1JhdCkpCgojTWVyZ2luZyBSZXN0YXVyYW50IEluc3BlY3Rpb24gd2l0aCBSb2RlbnQgSW5zcGVjdGlvbiBEYXRhIHdpdGggYSBsZWZ0IGpvaW4gCnJvZC5pbnNwZWN0aW9uJElOU1BFQ1RJT05fREFURSA9IGFzLmNoYXJhY3Rlcihyb2QuaW5zcGVjdGlvbiRJTlNQRUNUSU9OX0RBVEUpCnJvZC5pbnNwZWN0aW9uJGluc3BlY3RfZCA9IHNhcHBseShzdHJzcGxpdChyb2QuaW5zcGVjdGlvbiRJTlNQRUNUSU9OX0RBVEUsIiAiKSwiWyIsMSkKcm9kLmluc3BlY3Rpb24kaW5zcGVjdF9kbSA9c2FwcGx5KHN0cnNwbGl0KHJvZC5pbnNwZWN0aW9uJGluc3BlY3RfZCwiLyIpLCJbIiwxKQpyb2QuaW5zcGVjdGlvbiRpbnNwZWN0X2R5ID1zYXBwbHkoc3Ryc3BsaXQocm9kLmluc3BlY3Rpb24kaW5zcGVjdF9kLCIvIiksIlsiLDMpCm1lcmdlZF9kZiA9IG1lcmdlKHJvZC5pbnNwZWN0aW9uLCBSZXN0YXVyYW50UmF0VmlvbGF0aW9ucywgYnkueCA9IGMoImluc3BlY3RfZHkiLCJpbnNwZWN0X2RtIiwgIlpJUF9DT0RFIiksIGJ5LnkgPSBjKCJkYXRlLnllYXIiLCJkYXRlLm1vbnRoIiwiWklQQ09ERSIpLCBhbGwueCA9ICBUUlVFKQoKI0NvbnZlcnQgYW55IG1pc3NpbmcgcmVzdGF1cmFudCB2aW9sYXRpb24gbnVtYmVycyB0byAwLiBBZGQgMSBhbmQgTG9nIHRoaXMgbWVhc3VyZQptZXJnZWRfZGYkUmVzdG9fUmF0c1tpcy5uYShtZXJnZWRfZGYkUmVzdG9fUmF0cyldID0gMAptZXJnZWRfZGYkUmVzdG9fUmF0cyA9IGxvZyhtZXJnZWRfZGYkUmVzdG9fUmF0cysxKQoKI0FnYWluIGNoZWNrIGlmIHRoZXJlIGFyZSBBY3RpdmUgUmF0IFNpZ25zCm1lcmdlZF9kZiRBY3RpdmVfUmF0cyA9IGFzLmludGVnZXIobWVyZ2VkX2RmJFJFU1VMVCA9PSAiQWN0aXZlIFJhdCBTaWducyIpCmFuc3dlciA9IGZpbHRlcihtZXJnZWRfZGYsIGluc3BlY3RfZHkgPj0gMjAxMikKCiNDb252ZXJ0IG1vbnRoIGFuZCB5ZWFyIGludG8gZmFjdG9yIHZhcmlhYmxlcyAKYW5zd2VyJGluc3BlY3RfZHkgPSBhcy5mYWN0b3IoYW5zd2VyJGluc3BlY3RfZHkpCmFuc3dlciRpbnNwZWN0X2RtID0gYXMuZmFjdG9yKGFuc3dlciRpbnNwZWN0X2RtKQoKI1N0ZXAgNCBSdW4gYSBsb2dpc3RpYyByZWdyZXNzaW9uIG9uIHRoZSBuZXcgZGF0YSBzZXQgdG8gdGVzdCB3aGV0aGVyIHRoZSBlc3RpbWF0ZWQgY29lZmZpY2llbnQgb24gdGhlIHJlc3RhdXJhbnQgc2lnaHRpbmdzIHZhcmlhYmxlIGhhcyBhIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQgcmVsYXRpb25zaGlwIHdpdGggd2hldGhlciBvciBub3QgYW4gaW5zcGVjdGlvbiB5aWVsZHMgQWN0aXZlIFJhdCBTaWducyBhbmTigJNpZiBpdCBpcyBzaWduaWZpY2FudOKAk3doZXRoZXIgdGhlIHJlbGF0aW9uc2hpcCBpcyBwb3NpdGl2ZSBvciBuZWdhdGl2ZS4gCnN1bW1hcnkoZ2xtKGRhdGEgPSBhbnN3ZXIsIEFjdGl2ZV9SYXRzIH4gUmVzdG9fUmF0cyArIGluc3BlY3RfZG0gKyBpbnNwZWN0X2R5LCBmYW1pbHk9Ymlub21pYWwpKQpgYGAKClBhcnQgNAoKT25lIHF1ZXN0aW9uIHRoYXQgSSBtYXkgc3RpbGwgd2FudCB0byBhbnN3ZXIgcmVnYXJkaW5nIHJvZGVudHMgaXMgdGhhdCBhcmUgbG9jYXRpb25zIGNsb3NlciB0byBnYXJiYWdlIGxvY2F0aW9ucyBtb3JlIHByb25lIHRvIHJvZGVudCBzaWdodGluZ3M/CgpBIHNwZWNpZmljIGRhdGEgc2V0IHRoYXQgY2FuIGJlIHVzZWQgdG8gYW5zd2VyIHRoaXMgcXVlc3Rpb24gaXMgYSBkYXRhIHNldCBwcm92aWRlZCBPcGVuIERhdGEgTllDLCB3aGljaCBsaXN0cyB0aGUgRm9vZCBTY3JhcCBkcm9wLW9mZiBsb2NhdGlvbnMgaW4gTmV3IFlvcmsgQ2l0eS4gSXQgY29udGFpbnMgaW5mb3JtYXRpb24gb24gdGhlIGxvY2F0aW9uIChsb25naXR1ZGUsIGxhdGl0dWRlLCB6aXAgY29kZSwgYm9yb3VnaCkgYXMgd2VsbCBhcyB0aGUgZGF5cyBvZiB0aGUgd2VlayB0aGF0IHRob3NlIGRyb3Atb2ZmIHNwb3RzIGFyZSBvcGVuLiBUaGlzIGNhbiBiZSBqb2luZWQgd2l0aCB0aGUgY3VycmVudCBkYXRhIGJhc2VkIG9uIGVpdGhlciB6aXAgY29kZSwgYm9yb3VnaCwgb3IgY29vcmRpbmF0ZXMuCgpodHRwczovL2RhdGEuY2l0eW9mbmV3eW9yay51cy9FbnZpcm9ubWVudC9Gb29kLVNjcmFwLURyb3AtT2ZmLUxvY2F0aW9ucy1pbi1OWUMvaWYyNi16NnhxCgpGaW5hbGx5LCB0aGUgYW5hbHlzaXMgd2UgY291bGQgY29uZHVjdCBpcyB1c2luZyBnZW8gc3BhdGlhbCBkYXRhIGFuZCBtYXBwaW5nIHRoaXMgZHJvcC1vZmYgbG9jYXRpb25zIG9uIGEgbWFwLiBUaGVuLCB1c2luZyB0aGUgY3VycmVudCByb2RlbnQgc2lnaHRpbmcgZGF0YSwgd2UgY2FuIGNyZWF0ZSB2aXN1YWxzIChzdWNoIGFzIGhlYXQgbWFwcykgdG8gc2VlIGlmIHRoZXNlIGxvY2F0aW9ucyBkbyBoYXZlIHRoZSBoaWdoZXN0IGRlbnNpdGllcyBvZiBzaWdodGluZ3MuIE1vcmVvdmVyLCB3ZSBjYW4gc2VlIGhvdyB0aGVzZSBzaWdodGluZ3MgZGlmZmVyIGFtb25nIGRheXMgb2YgdGhlIHdlZWsgZGVwZW5kaW5nIG9uIHdoaWNoIGRheXMgdGhleSBhcmUgb3Blbi4KCgo=