This report illustrates the longitudinal and geographical fluctuation of different types of demands.
Service types are grouped by topics, which are based on assigning a few selected popular taxonomy term into broader categories. These topics cover around 80% of all the calls. Then I count number of calls for each topic, month and county.
Longitudinal Trends
To analyze longitudinal trends, I used the simple format iCarol dataset in combination of the archived taxonomy data for the years before 2016.
library(ggplot2)
library(cowplot)
library(lubridate)
library(stringr)
source('../src/transform/count_cat_geo.R')
mcalls2 <- mcalls %>%
filter(# date >= ymd('2016-05-01'),
#date < ymd('2016-06-01'),
#date < ymd('2017-02-01'),
!is.na(cat.code)) %>%
mutate(
yearmonth = str_c(year(date), str_pad(month(date), 2, 'left', '0'), sep='-')
)
dat1 <- mcalls2 %>%
count(yearmonth, topic) %>%
na.omit()
dat2 <- mcalls2 %>%
count(topic) %>%
rename(n_total = n)
dat <- dat1 %>%
left_join(dat2, by = 'topic') %>%
mutate(
topic = fct_reorder(topic, n_total),
n_scaled = n / n_total
)
Heatmap1(dat, yearmonth, topic, log(n))

But there was a period the calls are not recorded with taxonomy code, but rather free-text topics. Using some text matching techniques, I recovered some of them, but could not recover all (above graph clearly shows that between August 2014 and April 2016, some data are missing). Mass211 might or might not be able to provide us a more complete set of data. For now, we’ll focus on the new format data exportable from the new system.
library(ggplot2)
library(cowplot)
library(lubridate)
source('../src/transform/count_cat_geo.R')
mcalls1 <- mcalls.full %>%
filter(date >= ymd('2016-05-01'),
#date < ymd('2016-06-01'),
#date < ymd('2017-02-01'),
!is.na(cat.code)) %>%
mutate(
yearmonth = str_c(year(date), str_pad(month(date), 2, 'left', '0'), sep='-')
)
dat1 <- mcalls1 %>%
count(yearmonth, topic) %>%
na.omit()
dat2 <- mcalls1 %>%
count(topic) %>%
rename(n_total = n)
dat <- dat1 %>%
left_join(dat2, by = 'topic') %>%
mutate(
topic = fct_reorder(topic, n_total),
n_scaled = n / n_total
)
p1 <- Heatmap1(dat, yearmonth, topic, log(n))
p2 <- Heatmap1(dat, yearmonth, topic, n_scaled)
plot_grid(p1, p2)

Above graph shows how number of calls for each service category changes over time. Since number of calls varies a lot across categories, log(n) is used to make the graph more revealing. The graph on the right scales the numbers of each category by the total number of that category over the whole 14 month period.
It is immediately obvious that there is a sharp increase in mental health related calls beginning the end of 2016. This is because United Way’s Mental Health Line merged with Mass 2-1-1 around that time.
It can be verified by examing the taxonomy terms under the “mental health” topic:
mcalls.mental <- mcalls1 %>% filter(topic == 'mental')
dat1 <- mcalls.mental %>%
count(cat.name, yearmonth)
dat2 <- mcalls.mental %>%
count(cat.name, sort=TRUE) %>%
# total in all months
rename(n_total = n) %>%
head(10)
dat <- dat1 %>%
right_join(dat2, by = 'cat.name') %>%
mutate(n_scaled = n / n_total) %>%
mutate(
cat.name = str_trunc(cat.name, 30) %>% fct_reorder(n_total)
)
Heatmap1(dat, yearmonth, cat.name, n) +
labs(x = 'call date', y = 'taxonomy')

While there are calls to the “Mental Health Hotline” (or, “Call2Talk”" as branded by United Way) before the merge, and these calls are recorded in the same system, it is only after the merge that we see a huge increase in the usage of this service. This might be related to the increased awareness 2-1-1 during the merge, or simply because 2-1-1 is an easier-to-remember number.
It is fair to say the broad usage of Call2Talk may have overshadowed some more serious mental health issues. If we remove Call2Talk calls:
dat %<>% filter(cat.name != 'Mental Health Hotlines')
Heatmap1(dat, yearmonth, cat.name, n) + labs(x = 'call date', y = 'taxonomy')

Talklines/Warmliness has a spike in Dec, 2016, which might just be because of wrong categorization by 2-1-1 staffs during the transition period. Considering its similarity with Mental Health Hotlines, we might want to remove these calls as well for future analysis.
Geographic Distribution
Following graph shows the geographic distribution of the calls for popular service types.
source('../src/transform/count_cat_geo.R')
dat <- CountCatGeo(mcalls1)
p1 <- Heatmap1(dat, county, topic, log(n))
p2 <- Heatmap1(dat, county, topic, n_scaled)
plot_grid(p1, p2)

It is no surprise that Suffolk and Middlesex County contributed most calls, as they are the most populated counties. What matters more is the per capita data. Following graph is rendered with number of calls per 100,000 people:
p1 <- Heatmap1(dat, county, topic, log(p))
p2 <- Heatmap1(dat, county, topic, p_scaled)
plot_grid(p1, p2)

By the first look, Franklin County seems to have serious mental health issues. It is worth verifying where do exactly these calls come from. While it is not possible to identify the callers of all the calls, in the complete 2-1-1 dataset, there does exists some information to infer caller identity. For example, using phone numbers and notes by 2-1-1 staff, we can attribute about 80% of Call2Talk calls in Franklin county to one or two callers.
WHen removing two most seen phone numbers from the dataset, the graph becomes this:
source('../src/transform/count_cat_geo.R')
dat <- mcalls.complex %>%
filter(!(phone %in% c('4137687270','5084004343')) | is.na(phone), state == 'MA') %>%
CountCatGeo()
p1 <- Heatmap1(dat, county, topic, log(p))
p2 <- Heatmap1(dat, county, topic, p_scaled)
plot_grid(p1, p2)

Conclusion
We have only one year of reliable longitudinal data, it is hard to detect any signals caused by demographic or economic changes over such a short period.
Since Call2Talk is the category most likely to get repetitive callers, it might be best if we could just exclude all Call2Talk calls once and for all.
LS0tCnRpdGxlOiAiSGVhbHRoIGFuZCBIdW1hbiBTZXJ2aWNlIERlbWFuZHMgQWNyb3NzIFNwYWNlIGFuZCBUaW1lIgpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazoKICAgIGNvZGVfZm9sZGluZzogaGlkZQogICAgdGhlbWU6IHJlYWRhYmxlCiAgcGRmX2RvY3VtZW50OiBkZWZhdWx0Ci0tLQoKPHN0eWxlPgppbWcgewogICAgaW1hZ2UtcmVuZGVyaW5nOiAtd2Via2l0LW9wdGltaXplLWNvbnRyYXN0Owp9Cjwvc3R5bGU+CgpUaGlzIHJlcG9ydCBpbGx1c3RyYXRlcyB0aGUgbG9uZ2l0dWRpbmFsIGFuZCBnZW9ncmFwaGljYWwgZmx1Y3R1YXRpb24gb2YgZGlmZmVyZW50IHR5cGVzIG9mIGRlbWFuZHMuCgpTZXJ2aWNlIHR5cGVzIGFyZSBncm91cGVkIGJ5IF90b3BpY3NfLCB3aGljaCBhcmUgYmFzZWQgb24gYXNzaWduaW5nIGEgZmV3IHNlbGVjdGVkIHBvcHVsYXIgdGF4b25vbXkgdGVybSBpbnRvIGJyb2FkZXIgY2F0ZWdvcmllcy4gVGhlc2UgdG9waWNzIGNvdmVyIGFyb3VuZCA4MCUgb2YgYWxsIHRoZSBjYWxscy4gVGhlbiBJIGNvdW50IG51bWJlciBvZiBjYWxscyBmb3IgZWFjaCB0b3BpYywgbW9udGggYW5kIGNvdW50eS4KCiMjIExvbmdpdHVkaW5hbCBUcmVuZHMKClRvIGFuYWx5emUgbG9uZ2l0dWRpbmFsIHRyZW5kcywgSSB1c2VkIHRoZSBzaW1wbGUgZm9ybWF0IGlDYXJvbCBkYXRhc2V0IGluIGNvbWJpbmF0aW9uIG9mIHRoZSBhcmNoaXZlZCB0YXhvbm9teSBkYXRhIGZvciB0aGUgeWVhcnMgYmVmb3JlIDIwMTYuCgpgYGB7ciwgZmlnLndpZHRoPTcsIGZpZy5oZWlnaHQ9MiwgZmlnLnJldGluYT0yLCBtZXNzYWdlPUZBTFNFfQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoY293cGxvdCkKbGlicmFyeShsdWJyaWRhdGUpCmxpYnJhcnkoc3RyaW5ncikKCnNvdXJjZSgnLi4vc3JjL3RyYW5zZm9ybS9jb3VudF9jYXRfZ2VvLlInKQoKbWNhbGxzMiA8LSBtY2FsbHMgJT4lCiAgZmlsdGVyKCMgZGF0ZSA+PSB5bWQoJzIwMTYtMDUtMDEnKSwKICAgICAgICAgI2RhdGUgPCB5bWQoJzIwMTYtMDYtMDEnKSwKICAgICAgICAgI2RhdGUgPCB5bWQoJzIwMTctMDItMDEnKSwKICAgICAgICAgIWlzLm5hKGNhdC5jb2RlKSkgJT4lCiAgbXV0YXRlKAogICAgeWVhcm1vbnRoID0gc3RyX2MoeWVhcihkYXRlKSwgc3RyX3BhZChtb250aChkYXRlKSwgMiwgJ2xlZnQnLCAnMCcpLCBzZXA9Jy0nKQogICkKCmRhdDEgPC0gbWNhbGxzMiAlPiUKICBjb3VudCh5ZWFybW9udGgsIHRvcGljKSAlPiUKICBuYS5vbWl0KCkKCmRhdDIgPC0gbWNhbGxzMiAlPiUKICBjb3VudCh0b3BpYykgJT4lCiAgcmVuYW1lKG5fdG90YWwgPSBuKQoKZGF0IDwtIGRhdDEgJT4lCiAgbGVmdF9qb2luKGRhdDIsIGJ5ID0gJ3RvcGljJykgJT4lCiAgbXV0YXRlKAogICAgdG9waWMgPSBmY3RfcmVvcmRlcih0b3BpYywgbl90b3RhbCksCiAgICBuX3NjYWxlZCA9IG4gLyBuX3RvdGFsCiAgKQogIApIZWF0bWFwMShkYXQsIHllYXJtb250aCwgdG9waWMsIGxvZyhuKSkKYGBgCgpCdXQgdGhlcmUgd2FzIGEgcGVyaW9kIHRoZSBjYWxscyBhcmUgbm90IHJlY29yZGVkIHdpdGggdGF4b25vbXkgY29kZSwgYnV0IHJhdGhlciBmcmVlLXRleHQgdG9waWNzLiBVc2luZyBzb21lIHRleHQgbWF0Y2hpbmcgdGVjaG5pcXVlcywgSSByZWNvdmVyZWQgc29tZSBvZiB0aGVtLCBidXQgY291bGQgbm90IHJlY292ZXIgYWxsIChhYm92ZSBncmFwaCBjbGVhcmx5IHNob3dzIHRoYXQgYmV0d2VlbiBBdWd1c3QgMjAxNCBhbmQgQXByaWwgMjAxNiwgc29tZSBkYXRhIGFyZSBtaXNzaW5nKS4gTWFzczIxMSBtaWdodCBvciBtaWdodCBub3QgYmUgYWJsZSB0byBwcm92aWRlIHVzIGEgbW9yZSBjb21wbGV0ZSBzZXQgb2YgZGF0YS4gRm9yIG5vdywgd2UnbGwgZm9jdXMgb24gdGhlIG5ldyBmb3JtYXQgZGF0YSBleHBvcnRhYmxlIGZyb20gdGhlIG5ldyBzeXN0ZW0uCgpgYGB7ciwgZmlnLndpZHRoPTcsIGZpZy5oZWlnaHQ9MiwgZmlnLnJldGluYT0yLCBtZXNzYWdlPUZBTFNFfQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoY293cGxvdCkKbGlicmFyeShsdWJyaWRhdGUpCmxpYnJhcnkoc3RyaW5ncikKCnNvdXJjZSgnLi4vc3JjL3RyYW5zZm9ybS9jb3VudF9jYXRfZ2VvLlInKQoKbWNhbGxzMSA8LSBtY2FsbHMuZnVsbCAlPiUKICBmaWx0ZXIoZGF0ZSA+PSB5bWQoJzIwMTYtMDUtMDEnKSwKICAgICAgICAgI2RhdGUgPCB5bWQoJzIwMTYtMDYtMDEnKSwKICAgICAgICAgI2RhdGUgPCB5bWQoJzIwMTctMDItMDEnKSwKICAgICAgICAgIWlzLm5hKGNhdC5jb2RlKSkgJT4lCiAgbXV0YXRlKAogICAgeWVhcm1vbnRoID0gc3RyX2MoeWVhcihkYXRlKSwgc3RyX3BhZChtb250aChkYXRlKSwgMiwgJ2xlZnQnLCAnMCcpLCBzZXA9Jy0nKQogICkKCmRhdDEgPC0gbWNhbGxzMSAlPiUKICBjb3VudCh5ZWFybW9udGgsIHRvcGljKSAlPiUKICBuYS5vbWl0KCkKCmRhdDIgPC0gbWNhbGxzMSAlPiUKICBjb3VudCh0b3BpYykgJT4lCiAgcmVuYW1lKG5fdG90YWwgPSBuKQoKZGF0IDwtIGRhdDEgJT4lCiAgbGVmdF9qb2luKGRhdDIsIGJ5ID0gJ3RvcGljJykgJT4lCiAgbXV0YXRlKAogICAgdG9waWMgPSBmY3RfcmVvcmRlcih0b3BpYywgbl90b3RhbCksCiAgICBuX3NjYWxlZCA9IG4gLyBuX3RvdGFsCiAgKQogIApwMSA8LSBIZWF0bWFwMShkYXQsIHllYXJtb250aCwgdG9waWMsIGxvZyhuKSkKcDIgPC0gSGVhdG1hcDEoZGF0LCB5ZWFybW9udGgsIHRvcGljLCBuX3NjYWxlZCkKCnBsb3RfZ3JpZChwMSwgcDIpCmBgYAoKQWJvdmUgZ3JhcGggc2hvd3MgaG93IG51bWJlciBvZiBjYWxscyBmb3IgZWFjaCBzZXJ2aWNlIGNhdGVnb3J5IGNoYW5nZXMgb3ZlciB0aW1lLiBTaW5jZSBudW1iZXIgb2YgY2FsbHMgdmFyaWVzIGEgbG90IGFjcm9zcyBjYXRlZ29yaWVzLCBgbG9nKG4pYCBpcyB1c2VkIHRvIG1ha2UgdGhlIGdyYXBoIG1vcmUgcmV2ZWFsaW5nLiBUaGUgZ3JhcGggb24gdGhlIHJpZ2h0IHNjYWxlcyB0aGUgbnVtYmVycyBvZiBlYWNoIGNhdGVnb3J5IGJ5IHRoZSB0b3RhbCBudW1iZXIgb2YgdGhhdCBjYXRlZ29yeSBvdmVyIHRoZSB3aG9sZSAxNCBtb250aCBwZXJpb2QuCgpJdCBpcyBpbW1lZGlhdGVseSBvYnZpb3VzIHRoYXQgdGhlcmUgaXMgYSBzaGFycCBpbmNyZWFzZSBpbiBtZW50YWwgaGVhbHRoIHJlbGF0ZWQgY2FsbHMgYmVnaW5uaW5nIHRoZSBlbmQgb2YgMjAxNi4gVGhpcyBpcyBiZWNhdXNlIFVuaXRlZCBXYXkncyBNZW50YWwgSGVhbHRoIExpbmUgbWVyZ2VkIHdpdGggTWFzcyAyLTEtMSBhcm91bmQgdGhhdCB0aW1lLgoKSXQgY2FuIGJlIHZlcmlmaWVkIGJ5IGV4YW1pbmcgdGhlIHRheG9ub215IHRlcm1zIHVuZGVyIHRoZSAibWVudGFsIGhlYWx0aCIgdG9waWM6CgpgYGB7ciwgZmlnLndpZHRoPTYsIGZpZy5oZWlnaHQ9Mi41LCBmaWcucmV0aW5hPTJ9Cm1jYWxscy5tZW50YWwgPC0gbWNhbGxzMSAlPiUgZmlsdGVyKHRvcGljID09ICdtZW50YWwnKQpkYXQxIDwtIG1jYWxscy5tZW50YWwgJT4lCiAgY291bnQoY2F0Lm5hbWUsIHllYXJtb250aCkKZGF0MiA8LSBtY2FsbHMubWVudGFsICU+JQogIGNvdW50KGNhdC5uYW1lLCBzb3J0PVRSVUUpICU+JQogICMgdG90YWwgaW4gYWxsIG1vbnRocwogIHJlbmFtZShuX3RvdGFsID0gbikgJT4lCiAgaGVhZCgxMCkKCmRhdCA8LSBkYXQxICU+JQogIHJpZ2h0X2pvaW4oZGF0MiwgYnkgPSAnY2F0Lm5hbWUnKSAlPiUKICBtdXRhdGUobl9zY2FsZWQgPSBuIC8gbl90b3RhbCkgJT4lCiAgbXV0YXRlKAogICAgY2F0Lm5hbWUgPSBzdHJfdHJ1bmMoY2F0Lm5hbWUsIDMwKSAlPiUgZmN0X3Jlb3JkZXIobl90b3RhbCkKICApCgpIZWF0bWFwMShkYXQsIHllYXJtb250aCwgY2F0Lm5hbWUsIG4pICsKICBsYWJzKHggPSAnY2FsbCBkYXRlJywgeSA9ICd0YXhvbm9teScpCmBgYAoKV2hpbGUgdGhlcmUgYXJlIGNhbGxzIHRvIHRoZSAiTWVudGFsIEhlYWx0aCBIb3RsaW5lIiAob3IsICJDYWxsMlRhbGsiIiBhcyBicmFuZGVkIGJ5IFVuaXRlZCBXYXkpIGJlZm9yZSB0aGUgbWVyZ2UsIGFuZCB0aGVzZSBjYWxscyBhcmUgcmVjb3JkZWQgaW4gdGhlIHNhbWUgc3lzdGVtLCBpdCBpcyBvbmx5IGFmdGVyIHRoZSBtZXJnZSB0aGF0IHdlIHNlZSBhIGh1Z2UgaW5jcmVhc2UgaW4gdGhlIHVzYWdlIG9mIHRoaXMgc2VydmljZS4gVGhpcyBtaWdodCBiZSByZWxhdGVkIHRvIHRoZSBpbmNyZWFzZWQgYXdhcmVuZXNzIDItMS0xIGR1cmluZyB0aGUgbWVyZ2UsIG9yIHNpbXBseSBiZWNhdXNlIDItMS0xIGlzIGFuIGVhc2llci10by1yZW1lbWJlciBudW1iZXIuCgpJdCBpcyBmYWlyIHRvIHNheSB0aGUgYnJvYWQgdXNhZ2Ugb2YgQ2FsbDJUYWxrIG1heSBoYXZlIG92ZXJzaGFkb3dlZCBzb21lIG1vcmUgc2VyaW91cyBtZW50YWwgaGVhbHRoIGlzc3Vlcy4gSWYgd2UgcmVtb3ZlIENhbGwyVGFsayBjYWxsczoKCmBgYHtyLCBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD0yLjUsIG91dC53aWR0aD0nNTAlJywgZmlnLnJldGluYT0yfQpkYXQgJTw+JSBmaWx0ZXIoY2F0Lm5hbWUgIT0gJ01lbnRhbCBIZWFsdGggSG90bGluZXMnKQpIZWF0bWFwMShkYXQsIHllYXJtb250aCwgY2F0Lm5hbWUsIG4pICsgbGFicyh4ID0gJ2NhbGwgZGF0ZScsIHkgPSAndGF4b25vbXknKQpgYGAKCmBUYWxrbGluZXMvV2FybWxpbmVzc2AgaGFzIGEgc3Bpa2UgaW4gRGVjLCAyMDE2LCB3aGljaCBtaWdodCBqdXN0IGJlIGJlY2F1c2Ugb2Ygd3JvbmcgY2F0ZWdvcml6YXRpb24gYnkgMi0xLTEgc3RhZmZzIGR1cmluZyB0aGUgdHJhbnNpdGlvbiBwZXJpb2QuIENvbnNpZGVyaW5nIGl0cyBzaW1pbGFyaXR5IHdpdGggYE1lbnRhbCBIZWFsdGggSG90bGluZXNgLCB3ZSBtaWdodCB3YW50IHRvIHJlbW92ZSB0aGVzZSBjYWxscyBhcyB3ZWxsIGZvciBmdXR1cmUgYW5hbHlzaXMuCgoKIyMgR2VvZ3JhcGhpYyBEaXN0cmlidXRpb24KCkZvbGxvd2luZyBncmFwaCBzaG93cyB0aGUgZ2VvZ3JhcGhpYyBkaXN0cmlidXRpb24gb2YgdGhlIGNhbGxzIGZvciBwb3B1bGFyIHNlcnZpY2UgdHlwZXMuCgpgYGB7ciwgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9Mi41LCBmaWcucmV0aW5hPTJ9CnNvdXJjZSgnLi4vc3JjL3RyYW5zZm9ybS9jb3VudF9jYXRfZ2VvLlInKQoKZGF0IDwtIENvdW50Q2F0R2VvKG1jYWxsczEpCnAxIDwtIEhlYXRtYXAxKGRhdCwgY291bnR5LCB0b3BpYywgbG9nKG4pKQpwMiA8LSBIZWF0bWFwMShkYXQsIGNvdW50eSwgdG9waWMsIG5fc2NhbGVkKQoKcGxvdF9ncmlkKHAxLCBwMikKYGBgCgpJdCBpcyBubyBzdXJwcmlzZSB0aGF0IFN1ZmZvbGsgYW5kIE1pZGRsZXNleCBDb3VudHkgY29udHJpYnV0ZWQgbW9zdCBjYWxscywgYXMgdGhleSBhcmUgdGhlIG1vc3QgcG9wdWxhdGVkIGNvdW50aWVzLiBXaGF0IG1hdHRlcnMgbW9yZSBpcyB0aGUgcGVyIGNhcGl0YSBkYXRhLiBGb2xsb3dpbmcgZ3JhcGggaXMgcmVuZGVyZWQgd2l0aCBudW1iZXIgb2YgY2FsbHMgcGVyIDEwMCwwMDAgcGVvcGxlOgoKYGBge3IsIGZpZy53aWR0aD04LCBmaWcuaGVpZ2h0PTIuNSwgZmlnLnJldGluYT1UUlVFfQpwMSA8LSBIZWF0bWFwMShkYXQsIGNvdW50eSwgdG9waWMsIGxvZyhwKSkKcDIgPC0gSGVhdG1hcDEoZGF0LCBjb3VudHksIHRvcGljLCBwX3NjYWxlZCkKcGxvdF9ncmlkKHAxLCBwMikKYGBgCgpCeSB0aGUgZmlyc3QgbG9vaywgRnJhbmtsaW4gQ291bnR5IHNlZW1zIHRvIGhhdmUgc2VyaW91cyBtZW50YWwgaGVhbHRoIGlzc3Vlcy4gSXQgaXMgd29ydGggdmVyaWZ5aW5nIHdoZXJlIGRvIGV4YWN0bHkgdGhlc2UgY2FsbHMgY29tZSBmcm9tLiBXaGlsZSBpdCBpcyBub3QgcG9zc2libGUgdG8gaWRlbnRpZnkgdGhlIGNhbGxlcnMgb2YgYWxsIHRoZSBjYWxscywgaW4gdGhlIGNvbXBsZXRlIDItMS0xIGRhdGFzZXQsIHRoZXJlIGRvZXMgZXhpc3RzIHNvbWUgaW5mb3JtYXRpb24gdG8gaW5mZXIgY2FsbGVyIGlkZW50aXR5LiBGb3IgZXhhbXBsZSwgdXNpbmcgcGhvbmUgbnVtYmVycyBhbmQgbm90ZXMgYnkgMi0xLTEgc3RhZmYsIHdlIGNhbiBhdHRyaWJ1dGUgYWJvdXQgODAlIG9mIENhbGwyVGFsayBjYWxscyBpbiBGcmFua2xpbiBjb3VudHkgdG8gb25lIG9yIHR3byBjYWxsZXJzLgoKV0hlbiByZW1vdmluZyB0d28gbW9zdCBzZWVuIHBob25lIG51bWJlcnMgZnJvbSB0aGUgZGF0YXNldCwgdGhlIGdyYXBoIGJlY29tZXMgdGhpczoKCmBgYHtyLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD0yLjUsIGZpZy5yZXRpbmE9VFJVRX0Kc291cmNlKCcuLi9zcmMvdHJhbnNmb3JtL2NvdW50X2NhdF9nZW8uUicpCgpkYXQgPC0gbWNhbGxzLmNvbXBsZXggJT4lCiAgZmlsdGVyKCEocGhvbmUgJWluJSBjKCc0MTM3Njg3MjcwJywnNTA4NDAwNDM0MycpKSB8IGlzLm5hKHBob25lKSwgc3RhdGUgPT0gJ01BJykgJT4lCiAgQ291bnRDYXRHZW8oKQpwMSA8LSBIZWF0bWFwMShkYXQsIGNvdW50eSwgdG9waWMsIGxvZyhwKSkKcDIgPC0gSGVhdG1hcDEoZGF0LCBjb3VudHksIHRvcGljLCBwX3NjYWxlZCkKcGxvdF9ncmlkKHAxLCBwMikKYGBgCgojIyBDb25jbHVzaW9uCgpXZSBoYXZlIG9ubHkgb25lIHllYXIgb2YgcmVsaWFibGUgbG9uZ2l0dWRpbmFsIGRhdGEsIGl0IGlzIGhhcmQgdG8gZGV0ZWN0IGFueSBzaWduYWxzIGNhdXNlZCBieSBkZW1vZ3JhcGhpYyBvciBlY29ub21pYyBjaGFuZ2VzIG92ZXIgc3VjaCBhIHNob3J0IHBlcmlvZC4gCgpTaW5jZSBDYWxsMlRhbGsgaXMgdGhlIGNhdGVnb3J5IG1vc3QgbGlrZWx5IHRvIGdldCByZXBldGl0aXZlIGNhbGxlcnMsIGl0IG1pZ2h0IGJlIGJlc3QgaWYgd2UgY291bGQganVzdCBleGNsdWRlIGFsbCBDYWxsMlRhbGsgY2FsbHMgb25jZSBhbmQgZm9yIGFsbC4=