Setup
Load required libraries for wrangling data, charting, and mapping #+ setup, message=F, warning=F library(plyr,quietly = T) # data wrangling library(dplyr,quietly = T) # data wrangling library(ggplot2, quietly = T) # charting library(ggthemes,quietly = T) # so I can add the highcharts theme and palette library(scales,quietly = T) # to load the percent function when labeling plots library(caret,quietly = T) # classification and regression training library(foreach,quietly = T) # parallel processing to speed up the model training library(doMC,quietly = T) # parallel processing to speed up the model training library(lubridate,quietly = T) # for timing models Set our preferred charting theme theme_set(theme_minimal()+theme_hc()+theme(legend.key.width = unit(1.5, “cm”))) Run script to get hunter data #+ source_harvest, message=F, warning=F source(’~/_code/colorado-dow/datasets/Colorado Elk Harvest Data.R’, echo=F)
Table of the harvest data COElkRifleAll
Run script to get draw data #+ source_draw, message=F, warning=F source(’~/_code/colorado-dow/datasets/Elk Drawing Summaries.R’, echo=F)
Table of the data COElkDrawAll
+ source_geodata, message=F, warning=F
source(’~/_code/colorado-dow/datasets/Colorado GMUnit and Road data.R’, echo=F) Take a peak at the boundary data head(Unitboundaries2)
Set to predictive analytics directory setwd(“~/_code/colorado-dow/phase III - predictive analytics“) *** ## Organize data Will start by grouping all of the seasons together, and modeling the number of hunters per Year and Unit Group Draw results data by Year and Unit COElkDraw <- summarise(group_by(COElkDrawAll,Year,Unit), Quota = sum(Orig_Quota,na.rm = T), Drawn = sum(Chcs_Drawn,na.rm = T))
Appropriate field classes for model training COElkDraw\(Year <- as.numeric(COElkDraw\)Year)
Group Hunter data by Year and Unit COElkHunters <- summarise(group_by(COElkRifleAll,Year,Unit), Hunters = sum(c(Hunters.Antlered,Hunters.Antlerless,Hunters.Either),na.rm = T))
COElkHunters\(Year <- as.numeric(COElkHunters\)Year)
Join in Hunter and Draw data together COElkHunters <- left_join(COElkHunters, COElkDraw, by = c(“Year”,“Unit”))
Replace the draw data that don’t have entries with 0 COElkHunters\(Drawn[is.na(COElkHunters\)Drawn)] <- 0 COElkHunters\(Quota[is.na(COElkHunters\)Quota)] <- 0
Split into train and test sets. Will use 75% of the data to train on. Be sure to include each unit in the split. … so do the split for each unit, first make sure each Unit has at least three entries
COElkHunters <- mutate(group_by(COElkHunters,Unit), numentries = n()) COElkHunters <- filter(COElkHunters, numentries >= 3) COElkHunters\(UnitYear <- paste(COElkHunters\)Unit, COElkHunters$Year)
traindata <- COElkHunters %>% group_by(Unit) %>% sample_frac(size = .75, replace = F) testdata <- COElkHunters[!COElkHunters\(UnitYear %in% traindata\)UnitYear,]
COElkHunters <- select(COElkHunters, -UnitYear, -numentries)
traindata <- select(traindata, -UnitYear, -numentries) testdata <- select(testdata, -UnitYear, -numentries)
Save off for importing into AzureML write.csv(COElkHunters,file = “~/_code/colorado-dow/datasets/COElkHunters.csv“,row.names = F)
notice that the number of hunters data is skewed.
ggplot(COElkHunters, aes(Hunters)) +
geom_density() +
xlab("Hunters in Unit") +
ylab("Number of Units") +
theme(axis.text.y = element_blank()) +
labs(title="Distribution of Hunters in each Unit", subtitle="2006-2017", caption="source: cpw.state.co.us")

A general rule of thumb to consider is that skewed data whose ratio of the highest value to the lowest value is greater than 20 have significant skewness. Also, the skewness statistic can be used as a diagnostic. If the predictor distribution is roughly symmetric, the skewness values will be close to zero. As the distribution becomes more right skewed, the skewness statistic becomes larger. Similarly, as the distribution becomes more left skewed, the value becomes negative. Replacing the data with the log, square root, or inverse may help to remove the skew.
Example of how BoxCox can redistribute the data preProcValues2 <- preProcess(as.data.frame(traindata), method = “BoxCox”) trainBC <- predict(preProcValues2, as.data.frame(traindata))
ggplot(trainBC, aes(Hunters)) + geom_density() + xlab(“BoxCox Hunters in Unit”) + ylab(“Number of Units”) + theme(axis.text.y = element_blank()) + labs(title=“BoxCox Distribution of Hunters in each Unit”, subtitle=“2006-2017”, caption=“source: cpw.state.co.us”)
Try executing this chunk by clicking the Run button within the chunk or by placing your cursor inside it and pressing Cmd+Shift+Enter.
plot(cars)
Add a new chunk by clicking the Insert Chunk button on the toolbar or by pressing Cmd+Option+I.
quickmethods <- c("lm",'svmLinear',"svmRadial","knn","cubist","kknn","glm.nb")
step1_all <- NULL
for (imethod in quickmethods) {
step1 <- NULL
start <- now()
if (imethod == "lm") {
controlmethod <- "repeatedcv"
} else {controlmethod <- "adaptive_cv"}
fitControl <- trainControl(
method = controlmethod,
# search = 'random',
number = 4,
repeats = 4,
allowParallel = TRUE,
summaryFunction = defaultSummary)
registerDoSEQ()
registerDoMC(cores = 6)
HuntersModel_1 = train(Hunters ~ ., data = traindata,
method = imethod,
preProc = c("center","scale"),
tuneLength = 15,
trControl = fitControl)
HuntersModel_1
# measure performance
predictdata <- predict(HuntersModel_1, testdata)
step1$method <- imethod
step1$RMSE <- postResample(pred = predictdata, obs = testdata$Hunters)[1]
step1$duration <- now() - start
step1 <- as.data.frame(step1)
step1_all <- rbind(step1_all,step1)
}
step1_all
When you save the notebook, an HTML file containing the code and output will be saved alongside it (click the Preview button or press Cmd+Shift+K to preview the HTML file).
The preview shows you a rendered HTML copy of the contents of the editor. Consequently, unlike Knit, Preview does not run any R code chunks. Instead, the output of the chunk when it was last run in the editor is displayed.
LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKVGhpcyBpcyBhbiBbUiBNYXJrZG93bl0oaHR0cDovL3JtYXJrZG93bi5yc3R1ZGlvLmNvbSkgTm90ZWJvb2suIFdoZW4geW91IGV4ZWN1dGUgY29kZSB3aXRoaW4gdGhlIG5vdGVib29rLCB0aGUgcmVzdWx0cyBhcHBlYXIgYmVuZWF0aCB0aGUgY29kZS4gCgoKKioqCiMjIERlc2NyaXB0aW9uClVzZSBoaXN0b3JpY2FsIGRyYXcgcmVzdWx0cywgYW5kIG51bWJlciBvZiBodW50ZXJzIHRvIHRyYWluIGEgbW9kZWwgd2UgY2FuIHVzZSB0byAKcHJlZGljdCB0aGUgbnVtYmVyIG9mIGh1bnRlcnMgaW4gZnV0dXJlIHllYXJzLgoKVE9ETyAtIEluY2x1ZGUgb3RoZXIgcG90ZW50aWFsIGlucHV0cyB0aGF0IGNvdWxkIGltcGFjdCBob3cgbWFueSBodW50ZXJzIGdldCBhIGxpY2Vuc2UKYW5kIHNob3cgdXAuIFRob3NlIGNvdWxkIGluY2x1ZGUgZWNvbm9taWMgaW5kaWNhdG9ycywgYW5kIGNvc3RzIGFzc29jaWF0ZWQgd2l0aCBodW50aW5nCih0cmFuc3BvcnRhdGlvbiwgbG9kZ2luZykuCiMnCipfX05PVElDRV9fIHRoYXQgSSBhbSBvbmx5IGxvb2tpbmcgYXQgdGhlIGdlbmVyYWwgcmlmbGUgaHVudGluZyBzZWFzb25zIG9uIHB1YmxpYyBsYW5kLiBUaGVyZSBhcmUgYWxzbyAKaHVudGVycyBmb3IgQXJjaGVyeSwgTXV6emxlbG9hZGVyLCBQcml2YXRlIExhbmQsIFJhbmNoaW5nIGZvciBXaWxkbGlmZSwgZXRjLioKCioqKgojIyBTZXR1cApMb2FkIHJlcXVpcmVkIGxpYnJhcmllcyBmb3Igd3JhbmdsaW5nIGRhdGEsIGNoYXJ0aW5nLCBhbmQgbWFwcGluZwojKyBzZXR1cCwgbWVzc2FnZT1GLCB3YXJuaW5nPUYKbGlicmFyeShwbHlyLHF1aWV0bHkgPSBUKSAjIGRhdGEgd3JhbmdsaW5nCmxpYnJhcnkoZHBseXIscXVpZXRseSA9IFQpICMgZGF0YSB3cmFuZ2xpbmcKbGlicmFyeShnZ3Bsb3QyLCBxdWlldGx5ID0gVCkgIyBjaGFydGluZwpsaWJyYXJ5KGdndGhlbWVzLHF1aWV0bHkgPSBUKSAjIHNvIEkgY2FuIGFkZCB0aGUgaGlnaGNoYXJ0cyB0aGVtZSBhbmQgcGFsZXR0ZQpsaWJyYXJ5KHNjYWxlcyxxdWlldGx5ID0gVCkgIyB0byBsb2FkIHRoZSBwZXJjZW50IGZ1bmN0aW9uIHdoZW4gbGFiZWxpbmcgcGxvdHMKbGlicmFyeShjYXJldCxxdWlldGx5ID0gVCkgIyBjbGFzc2lmaWNhdGlvbiBhbmQgcmVncmVzc2lvbiB0cmFpbmluZwpsaWJyYXJ5KGZvcmVhY2gscXVpZXRseSA9IFQpICMgcGFyYWxsZWwgcHJvY2Vzc2luZyB0byBzcGVlZCB1cCB0aGUgbW9kZWwgdHJhaW5pbmcKbGlicmFyeShkb01DLHF1aWV0bHkgPSBUKSAjIHBhcmFsbGVsIHByb2Nlc3NpbmcgdG8gc3BlZWQgdXAgdGhlIG1vZGVsIHRyYWluaW5nCmxpYnJhcnkobHVicmlkYXRlLHF1aWV0bHkgPSBUKSAjIGZvciB0aW1pbmcgbW9kZWxzClNldCBvdXIgcHJlZmVycmVkIGNoYXJ0aW5nIHRoZW1lCnRoZW1lX3NldCh0aGVtZV9taW5pbWFsKCkrdGhlbWVfaGMoKSt0aGVtZShsZWdlbmQua2V5LndpZHRoID0gdW5pdCgxLjUsICJjbSIpKSkKUnVuIHNjcmlwdCB0byBnZXQgaHVudGVyIGRhdGEKIysgc291cmNlX2hhcnZlc3QsIG1lc3NhZ2U9Riwgd2FybmluZz1GCnNvdXJjZSgnfi9fY29kZS9jb2xvcmFkby1kb3cvZGF0YXNldHMvQ29sb3JhZG8gRWxrIEhhcnZlc3QgRGF0YS5SJywgZWNobz1GKQoKVGFibGUgb2YgdGhlIGhhcnZlc3QgZGF0YQpDT0Vsa1JpZmxlQWxsCgpSdW4gc2NyaXB0IHRvIGdldCBkcmF3IGRhdGEKIysgc291cmNlX2RyYXcsIG1lc3NhZ2U9Riwgd2FybmluZz1GCnNvdXJjZSgnfi9fY29kZS9jb2xvcmFkby1kb3cvZGF0YXNldHMvRWxrIERyYXdpbmcgU3VtbWFyaWVzLlInLCBlY2hvPUYpCgpUYWJsZSBvZiB0aGUgZGF0YQpDT0Vsa0RyYXdBbGwKCiMrIHNvdXJjZV9nZW9kYXRhLCBtZXNzYWdlPUYsIHdhcm5pbmc9Rgpzb3VyY2UoJ34vX2NvZGUvY29sb3JhZG8tZG93L2RhdGFzZXRzL0NvbG9yYWRvIEdNVW5pdCBhbmQgUm9hZCBkYXRhLlInLCBlY2hvPUYpClRha2UgYSBwZWFrIGF0IHRoZSBib3VuZGFyeSBkYXRhCmhlYWQoVW5pdGJvdW5kYXJpZXMyKQoKU2V0IHRvIHByZWRpY3RpdmUgYW5hbHl0aWNzIGRpcmVjdG9yeQpzZXR3ZCgifi9fY29kZS9jb2xvcmFkby1kb3cvcGhhc2UgSUlJIC0gcHJlZGljdGl2ZSBhbmFseXRpY3MiKQoqKioKIyMgT3JnYW5pemUgZGF0YQpXaWxsIHN0YXJ0IGJ5IGdyb3VwaW5nIGFsbCBvZiB0aGUgc2Vhc29ucyB0b2dldGhlciwgYW5kIG1vZGVsaW5nIHRoZSBudW1iZXIgb2YgaHVudGVycyBwZXIKWWVhciBhbmQgVW5pdApHcm91cCBEcmF3IHJlc3VsdHMgZGF0YSBieSBZZWFyIGFuZCBVbml0CkNPRWxrRHJhdyA8LSBzdW1tYXJpc2UoZ3JvdXBfYnkoQ09FbGtEcmF3QWxsLFllYXIsVW5pdCksCiAgICAgICAgICAgICAgICAgICAgICAgUXVvdGEgPSBzdW0oT3JpZ19RdW90YSxuYS5ybSA9IFQpLAogICAgICAgICAgICAgICAgICAgICAgIERyYXduID0gc3VtKENoY3NfRHJhd24sbmEucm0gPSBUKSkKCkFwcHJvcHJpYXRlIGZpZWxkIGNsYXNzZXMgZm9yIG1vZGVsIHRyYWluaW5nCkNPRWxrRHJhdyRZZWFyIDwtIGFzLm51bWVyaWMoQ09FbGtEcmF3JFllYXIpCgpHcm91cCBIdW50ZXIgZGF0YSBieSBZZWFyIGFuZCBVbml0CkNPRWxrSHVudGVycyA8LSBzdW1tYXJpc2UoZ3JvdXBfYnkoQ09FbGtSaWZsZUFsbCxZZWFyLFVuaXQpLAogICAgICAgICAgICAgICAgICAgICAgICAgIEh1bnRlcnMgPSBzdW0oYyhIdW50ZXJzLkFudGxlcmVkLEh1bnRlcnMuQW50bGVybGVzcyxIdW50ZXJzLkVpdGhlciksbmEucm0gPSBUKSkKCkNPRWxrSHVudGVycyRZZWFyIDwtIGFzLm51bWVyaWMoQ09FbGtIdW50ZXJzJFllYXIpCgpKb2luIGluIEh1bnRlciBhbmQgRHJhdyBkYXRhIHRvZ2V0aGVyCkNPRWxrSHVudGVycyA8LSBsZWZ0X2pvaW4oQ09FbGtIdW50ZXJzLCBDT0Vsa0RyYXcsIGJ5ID0gYygiWWVhciIsIlVuaXQiKSkKClJlcGxhY2UgdGhlIGRyYXcgZGF0YSB0aGF0IGRvbid0IGhhdmUgZW50cmllcyB3aXRoIDAKQ09FbGtIdW50ZXJzJERyYXduW2lzLm5hKENPRWxrSHVudGVycyREcmF3bildIDwtIDAKQ09FbGtIdW50ZXJzJFF1b3RhW2lzLm5hKENPRWxrSHVudGVycyRRdW90YSldIDwtIDAKClNwbGl0IGludG8gdHJhaW4gYW5kIHRlc3Qgc2V0cy4gV2lsbCB1c2UgNzUlIG9mIHRoZSBkYXRhIHRvIHRyYWluIG9uLiBCZSBzdXJlIHRvIGluY2x1ZGUKZWFjaCB1bml0IGluIHRoZSBzcGxpdC4gLi4uIHNvIGRvIHRoZSBzcGxpdCBmb3IgZWFjaCB1bml0LCBmaXJzdCBtYWtlIHN1cmUgZWFjaCBVbml0IGhhcwphdCBsZWFzdCB0aHJlZSBlbnRyaWVzCgpDT0Vsa0h1bnRlcnMgPC0gbXV0YXRlKGdyb3VwX2J5KENPRWxrSHVudGVycyxVbml0KSwKICAgICAgICAgICAgICAgICAgICAgICBudW1lbnRyaWVzID0gbigpKQpDT0Vsa0h1bnRlcnMgPC0gZmlsdGVyKENPRWxrSHVudGVycywgbnVtZW50cmllcyA+PSAzKQpDT0Vsa0h1bnRlcnMkVW5pdFllYXIgPC0gcGFzdGUoQ09FbGtIdW50ZXJzJFVuaXQsIENPRWxrSHVudGVycyRZZWFyKQoKdHJhaW5kYXRhIDwtIENPRWxrSHVudGVycyAlPiUgZ3JvdXBfYnkoVW5pdCkgJT4lIHNhbXBsZV9mcmFjKHNpemUgPSAuNzUsIHJlcGxhY2UgPSBGKQp0ZXN0ZGF0YSA8LSBDT0Vsa0h1bnRlcnNbIUNPRWxrSHVudGVycyRVbml0WWVhciAlaW4lIHRyYWluZGF0YSRVbml0WWVhcixdCgpDT0Vsa0h1bnRlcnMgPC0gc2VsZWN0KENPRWxrSHVudGVycywgLVVuaXRZZWFyLCAtbnVtZW50cmllcykKCnRyYWluZGF0YSA8LSBzZWxlY3QodHJhaW5kYXRhLCAtVW5pdFllYXIsIC1udW1lbnRyaWVzKQp0ZXN0ZGF0YSA8LSBzZWxlY3QodGVzdGRhdGEsIC1Vbml0WWVhciwgLW51bWVudHJpZXMpCgpTYXZlIG9mZiBmb3IgaW1wb3J0aW5nIGludG8gQXp1cmVNTAp3cml0ZS5jc3YoQ09FbGtIdW50ZXJzLGZpbGUgPSAifi9fY29kZS9jb2xvcmFkby1kb3cvZGF0YXNldHMvQ09FbGtIdW50ZXJzLmNzdiIscm93Lm5hbWVzID0gRikKCm5vdGljZSB0aGF0IHRoZSBudW1iZXIgb2YgaHVudGVycyBkYXRhIGlzIHNrZXdlZC4KYGBge3J9CmdncGxvdChDT0Vsa0h1bnRlcnMsIGFlcyhIdW50ZXJzKSkgKyAKICBnZW9tX2RlbnNpdHkoKSArCiAgeGxhYigiSHVudGVycyBpbiBVbml0IikgKwogIHlsYWIoIk51bWJlciBvZiBVbml0cyIpICsKICB0aGVtZShheGlzLnRleHQueSA9IGVsZW1lbnRfYmxhbmsoKSkgKwogIGxhYnModGl0bGU9IkRpc3RyaWJ1dGlvbiBvZiBIdW50ZXJzIGluIGVhY2ggVW5pdCIsIHN1YnRpdGxlPSIyMDA2LTIwMTciLCBjYXB0aW9uPSJzb3VyY2U6IGNwdy5zdGF0ZS5jby51cyIpCgpgYGAKCgpBIGdlbmVyYWwgcnVsZSBvZiB0aHVtYiB0byBjb25zaWRlciBpcyB0aGF0IHNrZXdlZCBkYXRhIHdob3NlIHJhdGlvIG9mIHRoZSBoaWdoZXN0IHZhbHVlIHRvIHRoZSAKbG93ZXN0IHZhbHVlIGlzIGdyZWF0ZXIgdGhhbiAyMCBoYXZlIHNpZ25pZmljYW50IHNrZXduZXNzLiBBbHNvLCB0aGUgc2tld25lc3Mgc3RhdGlzdGljIGNhbiBiZSAKdXNlZCBhcyBhIGRpYWdub3N0aWMuIElmIHRoZSBwcmVkaWN0b3IgZGlzdHJpYnV0aW9uIGlzIHJvdWdobHkgc3ltbWV0cmljLCB0aGUgc2tld25lc3MgdmFsdWVzIAp3aWxsIGJlIGNsb3NlIHRvIHplcm8uIEFzIHRoZSBkaXN0cmlidXRpb24gYmVjb21lcyBtb3JlIHJpZ2h0IHNrZXdlZCwgdGhlIHNrZXduZXNzIHN0YXRpc3RpYyAKYmVjb21lcyBsYXJnZXIuIFNpbWlsYXJseSwgYXMgdGhlIGRpc3RyaWJ1dGlvbiBiZWNvbWVzIG1vcmUgbGVmdCBza2V3ZWQsIHRoZSB2YWx1ZSBiZWNvbWVzIG5lZ2F0aXZlLgpSZXBsYWNpbmcgdGhlIGRhdGEgd2l0aCB0aGUgbG9nLCBzcXVhcmUgcm9vdCwgb3IgaW52ZXJzZSBtYXkgaGVscCB0byByZW1vdmUgdGhlIHNrZXcuCgpFeGFtcGxlIG9mIGhvdyBCb3hDb3ggY2FuIHJlZGlzdHJpYnV0ZSB0aGUgZGF0YQpwcmVQcm9jVmFsdWVzMiA8LSBwcmVQcm9jZXNzKGFzLmRhdGEuZnJhbWUodHJhaW5kYXRhKSwgbWV0aG9kID0gIkJveENveCIpCnRyYWluQkMgPC0gcHJlZGljdChwcmVQcm9jVmFsdWVzMiwgYXMuZGF0YS5mcmFtZSh0cmFpbmRhdGEpKQoKZ2dwbG90KHRyYWluQkMsIGFlcyhIdW50ZXJzKSkgKyAKICBnZW9tX2RlbnNpdHkoKSArCiAgeGxhYigiQm94Q294IEh1bnRlcnMgaW4gVW5pdCIpICsKICB5bGFiKCJOdW1iZXIgb2YgVW5pdHMiKSArCiAgdGhlbWUoYXhpcy50ZXh0LnkgPSBlbGVtZW50X2JsYW5rKCkpICsKICBsYWJzKHRpdGxlPSJCb3hDb3ggRGlzdHJpYnV0aW9uIG9mIEh1bnRlcnMgaW4gZWFjaCBVbml0Iiwgc3VidGl0bGU9IjIwMDYtMjAxNyIsIGNhcHRpb249InNvdXJjZTogY3B3LnN0YXRlLmNvLnVzIikKCgoKCgpUcnkgZXhlY3V0aW5nIHRoaXMgY2h1bmsgYnkgY2xpY2tpbmcgdGhlICpSdW4qIGJ1dHRvbiB3aXRoaW4gdGhlIGNodW5rIG9yIGJ5IHBsYWNpbmcgeW91ciBjdXJzb3IgaW5zaWRlIGl0IGFuZCBwcmVzc2luZyAqQ21kK1NoaWZ0K0VudGVyKi4gCgpgYGB7cn0KcGxvdChjYXJzKQpgYGAKCkFkZCBhIG5ldyBjaHVuayBieSBjbGlja2luZyB0aGUgKkluc2VydCBDaHVuayogYnV0dG9uIG9uIHRoZSB0b29sYmFyIG9yIGJ5IHByZXNzaW5nICpDbWQrT3B0aW9uK0kqLgpgYGB7cn0KcXVpY2ttZXRob2RzIDwtIGMoImxtIiwnc3ZtTGluZWFyJywic3ZtUmFkaWFsIiwia25uIiwiY3ViaXN0Iiwia2tubiIsImdsbS5uYiIpCgpzdGVwMV9hbGwgPC0gTlVMTApmb3IgKGltZXRob2QgaW4gcXVpY2ttZXRob2RzKSB7CiAgc3RlcDEgPC0gTlVMTAogIHN0YXJ0IDwtIG5vdygpCiAgCiAgaWYgKGltZXRob2QgPT0gImxtIikgewogICAgY29udHJvbG1ldGhvZCA8LSAicmVwZWF0ZWRjdiIKICB9IGVsc2Uge2NvbnRyb2xtZXRob2QgPC0gImFkYXB0aXZlX2N2In0KICAKICBmaXRDb250cm9sIDwtIHRyYWluQ29udHJvbCgKICAgIG1ldGhvZCA9IGNvbnRyb2xtZXRob2QsCiAgICAjIHNlYXJjaCA9ICdyYW5kb20nLAogICAgbnVtYmVyID0gNCwKICAgIHJlcGVhdHMgPSA0LAogICAgYWxsb3dQYXJhbGxlbCA9IFRSVUUsCiAgICBzdW1tYXJ5RnVuY3Rpb24gPSBkZWZhdWx0U3VtbWFyeSkKICAKICByZWdpc3RlckRvU0VRKCkKICByZWdpc3RlckRvTUMoY29yZXMgPSA2KQogIAogIEh1bnRlcnNNb2RlbF8xID0gdHJhaW4oSHVudGVycyB+IC4sIGRhdGEgPSB0cmFpbmRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICBtZXRob2QgPSBpbWV0aG9kLAogICAgICAgICAgICAgICAgICAgICAgICAgcHJlUHJvYyA9IGMoImNlbnRlciIsInNjYWxlIiksIAogICAgICAgICAgICAgICAgICAgICAgICAgdHVuZUxlbmd0aCA9IDE1LAogICAgICAgICAgICAgICAgICAgICAgICAgdHJDb250cm9sID0gZml0Q29udHJvbCkKICAKICBIdW50ZXJzTW9kZWxfMQogIAogICMgbWVhc3VyZSBwZXJmb3JtYW5jZQogIHByZWRpY3RkYXRhIDwtIHByZWRpY3QoSHVudGVyc01vZGVsXzEsIHRlc3RkYXRhKQogIAogIHN0ZXAxJG1ldGhvZCA8LSBpbWV0aG9kCiAgc3RlcDEkUk1TRSA8LSBwb3N0UmVzYW1wbGUocHJlZCA9IHByZWRpY3RkYXRhLCBvYnMgPSB0ZXN0ZGF0YSRIdW50ZXJzKVsxXQogIHN0ZXAxJGR1cmF0aW9uIDwtIG5vdygpIC0gc3RhcnQKICBzdGVwMSA8LSBhcy5kYXRhLmZyYW1lKHN0ZXAxKQogIHN0ZXAxX2FsbCA8LSByYmluZChzdGVwMV9hbGwsc3RlcDEpCn0Kc3RlcDFfYWxsCmBgYAoKV2hlbiB5b3Ugc2F2ZSB0aGUgbm90ZWJvb2ssIGFuIEhUTUwgZmlsZSBjb250YWluaW5nIHRoZSBjb2RlIGFuZCBvdXRwdXQgd2lsbCBiZSBzYXZlZCBhbG9uZ3NpZGUgaXQgKGNsaWNrIHRoZSAqUHJldmlldyogYnV0dG9uIG9yIHByZXNzICpDbWQrU2hpZnQrSyogdG8gcHJldmlldyB0aGUgSFRNTCBmaWxlKS4gCgpUaGUgcHJldmlldyBzaG93cyB5b3UgYSByZW5kZXJlZCBIVE1MIGNvcHkgb2YgdGhlIGNvbnRlbnRzIG9mIHRoZSBlZGl0b3IuIENvbnNlcXVlbnRseSwgdW5saWtlICpLbml0KiwgKlByZXZpZXcqIGRvZXMgbm90IHJ1biBhbnkgUiBjb2RlIGNodW5rcy4gSW5zdGVhZCwgdGhlIG91dHB1dCBvZiB0aGUgY2h1bmsgd2hlbiBpdCB3YXMgbGFzdCBydW4gaW4gdGhlIGVkaXRvciBpcyBkaXNwbGF5ZWQuCgo=