This is an R Markdown Notebook. When you execute code within the notebook, the results appear beneath the code.


Description

Use historical draw results, and number of hunters to train a model we can use to predict the number of hunters in future years.

TODO - Include other potential inputs that could impact how many hunters get a license and show up. Those could include economic indicators, and costs associated with hunting (transportation, lodging). #’ NOTICE that I am only looking at the general rifle hunting seasons on public land. There are also hunters for Archery, Muzzleloader, Private Land, Ranching for Wildlife, etc.


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=