1 Motivation

This article was inspired by a recent meeting to discuss public health data science. It outlines a method for rapidly searching the Pubmed database and analysing retrieved abstracts. We are interested in rapidly assessing the literature on the extent of discussion or application of data science in public health research and practice.

2 Method

We used the RISmed package which provides an R interface to the Pubmed API to extract and analyse the most recent 12,000 abstract retrieved via a very non-specific search strategy. We used cluster analysis (topic modelling) to group and classify abstracts. We also searched the abstracts for the terms data science and big data and conclude there is currently a very small literature on data science in public/ population health and there is a potential large research agenda to help us understand how we can apply emerging data management and analytic techniques in modern public health practice.

2.1 Load libraries

Firstly we’ll load the relevant R libraries.

2.3 Create data frame

abstracts <- data.frame(title = fetch@ArticleTitle,
                        abstract = fetch@AbstractText, 
                        journal = fetch@Title,
                        DOI = fetch@PMID, 
                        year = fetch@YearPubmed)
## ensure abstracts are character fields (not factors)
abstracts <- abstracts %>% mutate(abstract = as.character(abstract))
abstracts %>%
  head()
abstracts %>%
  group_by(year) %>%
  count() %>%
  filter(year > 2013) %>%
  ggplot(aes(year, n)) +
  geom_point() +
  geom_line() +
  labs(title = "Pubmed articles with search terms `data science` & `population health` \n2015-2016", hjust = 0.5,
       y = "Articles")

The total number of abstracts was 11987

2.4 Word cloud

cloud <- abstracts %>%
  unnest_tokens(word, abstract) %>%
  anti_join(stop_words) %>%
  count(word, sort = TRUE) 
Joining, by = "word"
  
cloud %>%
with(wordcloud(word, n, min.freq = 10, max.words = 1000, colors = brewer.pal(8, "Dark2")), scale = c(8,.3), per.rot = 0.4)

2.5 Create bigrams

2.5.1 Bigram wordcloud

bigrams_united %>%
  with(wordcloud(bigram, n, max.words = 1000, random.order = FALSE, colors = brewer.pal(9, "Set1"), scale = c(8, 0.3)), per.rot = 0.4)

2.5.2 Journal wordlcoud

cloud3 <- abstracts %>%
  select(journal) %>%
  group_by(journal) %>%
  count(sort = TRUE)
cloud3 %>%
  with(wordcloud(journal, n, min.freq = 10, random.order = FALSE, max.words = 80, colors = brewer.pal(9, "Set1")), rot.per = .6)

2.5.3 Extract abstracts containing the phrase ‘data science’

 g <- abstracts[grepl("data science", abstracts$abstract),]
 g1 <- g$DOI %>% list
 abstracts <- abstracts %>% 
   mutate(DOI  = as.character(DOI)) 
 
 abstracts[abstracts$DOI %in% g1[[1]],] %>%
   select(title, journal, DOI) %>%
   knitr::kable()

title journal DOI
49 MO-FG-207B-01: Thorax/Lung. Medical physics 28048692
50 MO-FG-207B-02: Breast. Medical physics 28048031
52 MO-FG-207B-03: Brain. Medical physics 28047352
53 MO-FG-207B-04: Respond to Therapy. Medical physics 28046682
54 MO-FG-207B-00: State-of-the-Art in Radiomics in Radiology and Radiation Oncology. Medical physics 28046637
257 Applying Multiple Data Collection Tools to Quantify Human Papillomavirus Vaccine Communication on Twitter. Journal of medical Internet research 27919863
4237 Exploiting big data for critical care research. Current opinion in critical care 26348424
4985 Spatial and temporal epidemiological analysis in the Big Data era. Preventive veterinary medicine 26092722
5953 Strategic transformation of population studies: recommendations of the working group on epidemiology and population sciences from the National Heart, Lung, and Blood Advisory Council and Board of External Experts. American journal of epidemiology 25743324
6433 OpenHealth Platform for Interactive Contextualization of Population Health Open Data. AMIA ... Annual Symposium proceedings. AMIA Symposium 26958160

NA
NA

2.5.4 Extract abstracts containing the phrase ‘big data’

  
 g <- abstracts[grepl("big data", abstracts$abstract),]
 g1 <- g$DOI %>% list
 abstracts <- abstracts %>% 
   mutate(DOI  = as.character(DOI)) 
 
 abstracts[abstracts$DOI %in% g1[[1]],] %>%
   select(title, journal, DOI, year) %>%
   knitr::kable()
title journal DOI year
49 MO-FG-207B-01: Thorax/Lung. Medical physics 28048692 2017
50 MO-FG-207B-02: Breast. Medical physics 28048031 2017
52 MO-FG-207B-03: Brain. Medical physics 28047352 2017
53 MO-FG-207B-04: Respond to Therapy. Medical physics 28046682 2017
54 MO-FG-207B-00: State-of-the-Art in Radiomics in Radiology and Radiation Oncology. Medical physics 28046637 2017
253 Crowdsourcing Precision Cerebrovascular Health: Imaging and Cloud Seeding A Million Brains Initiative™. Frontiers in medicine 27921034 2016
658 Clinical chemistry in higher dimensions: Machine-learning and enhanced prediction from routine clinical chemistry data. Clinical biochemistry 27452181 2016
1555 Scaling up health knowledge at European level requires sharing integrated data: an approach for collection of database specification. ClinicoEconomics and outcomes research : CEOR 27358570 2016
1606 Social Media and Population Health Virtual Exchange for Senior Nursing Students: An International Collaboration. Studies in health technology and informatics 27332439 2016
1896 Translation in Data Mining to Advance Personalized Medicine for Health Equity. Intelligent information management 27195185 2016
1956 Community Vital Signs: Taking the Pulse of the Community While Caring for Patients. Journal of the American Board of Family Medicine : JABFM 27170802 2016
3383 Integration of molecular pathology, epidemiology and social science for global precision medicine. Expert review of molecular diagnostics 26636627 2015
3695 Routinely collected data as a strategic resource for research: priorities for methods and workforce. Public health research & practice 26536502 2015
3951 Latest developments in allergic rhinitis in Allergy for clinicians and researchers. Allergy 26443244 2015
4237 Exploiting big data for critical care research. Current opinion in critical care 26348424 2015
4754 NA Journal of the American Medical Informatics Association : JAMIA 26174867 2015
4834 Epidemiology research in rheumatology-progress and pitfalls. Nature reviews. Rheumatology 26150125 2015
5953 Strategic transformation of population studies: recommendations of the working group on epidemiology and population sciences from the National Heart, Lung, and Blood Advisory Council and Board of External Experts. American journal of epidemiology 25743324 2015
6212 Using networks to combine "big data" and traditional surveillance to improve influenza predictions. Scientific reports 25634021 2015
7407 Sensor, signal, and imaging informatics: big data and smart health technologies. Yearbook of medical informatics 25123735 2014
7408 Big Data Usage Patterns in the Health Care Domain: A Use Case Driven Approach Applied to the Assessment of Vaccination Benefits and Risks. Contribution of the IMIA Primary Healthcare Working Group. Yearbook of medical informatics 25123718 2014
7593 Big data for population-based cancer research: the integrated cancer information and surveillance system. North Carolina medical journal 25046092 2014
7684 Big data in health care: using analytics to identify and manage high-risk and high-cost patients. Health affairs (Project Hope) 25006137 2014
9021 Privacy-by-Design: Understanding Data Access Models for Secondary Data. AMIA Joint Summits on Translational Science proceedings. AMIA Joint Summits on Translational Science 24303251 2013
9159 Prevention and management of noncommunicable disease: the IOC Consensus Statement, Lausanne 2013. Clinical journal of sport medicine : official journal of the Canadian Academy of Sport Medicine 24169298 2013
9845 Transforming epidemiology for 21st century medicine and public health. Cancer epidemiology, biomarkers & prevention : a publication of the American Association for Cancer Research, cosponsored by the American Society of Preventive Oncology 23462917 2013
title journal DOI year
257 Applying Multiple Data Collection Tools to Quantify Human Papillomavirus Vaccine Communication on Twitter. Journal of medical Internet research 27919863 2016
566 Prospective functional classification of all possible missense variants in PPARG. Nature genetics 27749844 2016
658 Clinical chemistry in higher dimensions: Machine-learning and enhanced prediction from routine clinical chemistry data. Clinical biochemistry 27452181 2016
718 Extracting PICO Sentences from Clinical Trial Reports using Supervised Distant Supervision. Journal of machine learning research : JMLR 27746703 2016
804 Comparison of Approaches for Heart Failure Case Identification From Electronic Health Record Data. JAMA cardiology 27706470 2016
868 Assessing methods for generalizing experimental impact estimates to target populations. Journal of research on educational effectiveness 27668031 2016
1401 Predicting suicides after outpatient mental health visits in the Army Study to Assess Risk and Resilience in Servicemembers (Army STARRS). Molecular psychiatry 27431294 2016
1579 Cardiac image modelling: Breadth and depth in heart disease. Medical image analysis 27349830 2016
1732 Call for a Computer-Aided Cancer Detection and Classification Research Initiative in Oman. Asian Pacific journal of cancer prevention : APJCP 27268600 2016
1831 The Importance of Computer Science for Public Health Training: An Opportunity and Call to Action. JMIR public health and surveillance 27227145 2016
1913 Validating Machine Learning Algorithms for Twitter Data Against Established Measures of Suicidality. JMIR mental health 27185366 2016
2142 Objective Assessment of Physical Activity: Classifiers for Public Health. Medicine and science in sports and exercise 27089222 2016
2176 Do Staphylococcus epidermidis Genetic Clusters Predict Isolation Sources? Journal of clinical microbiology 27076664 2016
3039 Automated Outcome Classification of Computed Tomography Imaging Reports for Pediatric Traumatic Brain Injury. Academic emergency medicine : official journal of the Society for Academic Emergency Medicine 26766600 2016
3142 A land use regression model for ambient ultrafine particles in Montreal, Canada: A comparison of linear regression and a machine learning approach. Environmental research 26720396 2016
3168 Single-cell analysis of targeted transcriptome predicts drug sensitivity of single cells within human myeloma tumors. Leukemia 26710886 2015
3754 Combining Search, Social Media, and Traditional Data Sources to Improve Influenza Surveillance. PLoS computational biology 26513245 2015
4432 Implications of Cardiovascular Disease Risk Assessment Using the WHO/ISH Risk Prediction Charts in Rural India. PloS one 26287807 2015
4498 Thirty years of artificial intelligence in medicine (AIME) conferences: A review of research themes. Artificial intelligence in medicine 26265491 2015
4660 Lung necrosis and neutrophils reflect common pathways of susceptibility to Mycobacterium tuberculosis in genetically diverse, immune-competent mice. Disease models & mechanisms 26204894 2015
5022 RAIRS2 a new expert system for diagnosing tuberculosis with real-world tournament selection mechanism inside artificial immune recognition system. Medical & biological engineering & computing 26081904 2015
5170 Short-term Mortality Prediction for Elderly Patients Using Medicare Claims Data. International journal of machine learning and computing 28018571 2015
5249 Using EHRs for Heart Failure Therapy Recommendation Using Multidimensional Patient Similarity Analytics. Studies in health technology and informatics 25991168 2015
5411 Past and current use of walking measures for children with spina bifida: a systematic review. Archives of physical medicine and rehabilitation 25944500 2015
5511 Mapping chemical structure-activity information of HAART-drug cocktails over complex networks of AIDS epidemiology and socioeconomic data of U.S. counties. Bio Systems 25916548 2015
7058 The genetic interacting landscape of 63 candidate genes in Major Depressive Disorder: an explorative study. BioData mining 25279001 2014
7420 Visualization and unsupervised predictive clustering of high-dimensional multimodal neuroimaging data. Journal of neuroscience methods 25117552 2014
8662 NeuCube: a spiking neural network architecture for mapping, learning and understanding of spatio-temporal brain data. Neural networks : the official journal of the International Neural Network Society 24508754 2014
8865 High-throughput neuro-imaging informatics. Frontiers in neuroinformatics 24381556 2014
9273 A Machine Learning-Based Analysis of Game Data for Attention Deficit Hyperactivity Disorder Assessment. Games for health journal 26196929 2013
9430 e-Labs and the stock of health method for simulating health policies. Studies in health technology and informatics 23920562 2013

2.6 Create document term matrix

abstracts %>%
  unnest_tokens(word, abstract) %>%
  anti_join(stop_words) %>%
  count(DOI, word, sort = TRUE) %>%
  cast_dtm(DOI, word, n) ->
  abstracts1
Joining, by = "word"

3 Topic modelling (cluster analysis of abstracts)

library(topicmodels)
abs_lda <- LDA(abstracts1, k = 10, control = list(seed = 1234))
abs_lda_td <- tidytext:::tidy.LDA(abs_lda)

3.1 Plot terms by topic

3.2 Classify documents

abs_lda_gamma <- tidytext:::tidy.LDA(abs_lda, matrix = "gamma")
abs_class <- abs_lda_gamma %>%
  group_by(document) %>%
  top_n(1, gamma) %>%
  ungroup() %>%
  arrange(gamma)
abs_class %>%
  sample_n(6)
abstracts %>%
  group_by(journal) %>%
  count(sort = TRUE) %>%
  filter(n >=40) ->top40
abstracts %>%
  left_join(top40) %>%
  filter(!is.na(n)) %>%
  rename(document = DOI) %>%
  left_join(abs_class) %>%
  filter(!is.na(topic)) %>%
  ggplot(aes(document, factor(topic))) +
  geom_jitter(aes(colour = factor(topic)), size = 1, width = 0.1) +
  facet_wrap(~journal) +
  theme(strip.text.x = element_text(size = 8), axis.text.x = element_blank(), axis.ticks.x = element_blank(), axis.text = element_text(size  =10)) +
  scale_color_viridis(discrete = TRUE, option = "C") +
  theme(panel.background = element_rect(fill = "aliceblue")) +
  labs(title = "Top 15 journals",
       subtitle = "Documents by topic",
       x = "Time")

NA
LS0tCnRpdGxlOiAnUHVibWVkMjogc2VhcmNoaW5nIFB1Ym1lZCBmb3IgYXJ0aWNsZXMgb24gcHVibGljIGhlYWx0aCBhbmQgZGF0YSBzY2llbmNlJwpvdXRwdXQ6CiAgaHRtbF9ub3RlYm9vazoKICAgIG51bWJlcl9zZWN0aW9uczogeWVzCiAgICB0b2M6IHllcwogICAgdG9jX2Zsb2F0OiB5ZXMKICBodG1sX2RvY3VtZW50OgogICAgdG9jOiB5ZXMKICB3b3JkX2RvY3VtZW50OgogICAgdG9jOiB5ZXMKLS0tCiMgTW90aXZhdGlvbgoKVGhpcyBhcnRpY2xlIHdhcyBpbnNwaXJlZCBieSBhIHJlY2VudCBtZWV0aW5nIHRvIGRpc2N1c3MgcHVibGljIGhlYWx0aCBkYXRhIHNjaWVuY2UuIEl0IG91dGxpbmVzIGEgbWV0aG9kIGZvciByYXBpZGx5IHNlYXJjaGluZyB0aGUgUHVibWVkIGRhdGFiYXNlIGFuZCBhbmFseXNpbmcgcmV0cmlldmVkIGFic3RyYWN0cy4gV2UgYXJlIGludGVyZXN0ZWQgaW4gcmFwaWRseSBhc3Nlc3NpbmcgdGhlIGxpdGVyYXR1cmUgb24gdGhlIGV4dGVudCBvZiBkaXNjdXNzaW9uIG9yIGFwcGxpY2F0aW9uIG9mIGRhdGEgc2NpZW5jZSBpbiBwdWJsaWMgaGVhbHRoIHJlc2VhcmNoIGFuZCBwcmFjdGljZS4KCgoKIyBNZXRob2QKCldlIHVzZWQgdGhlIGBSSVNtZWRgIHBhY2thZ2Ugd2hpY2ggcHJvdmlkZXMgYW4gYFJgIGludGVyZmFjZSB0byB0aGUgUHVibWVkIEFQSSB0byBleHRyYWN0IGFuZCBhbmFseXNlIHRoZSBtb3N0IHJlY2VudCAxMiwwMDAgYWJzdHJhY3QgcmV0cmlldmVkIHZpYSBhIHZlcnkgbm9uLXNwZWNpZmljIHNlYXJjaCBzdHJhdGVneS4gV2UgdXNlZCBjbHVzdGVyIGFuYWx5c2lzICh0b3BpYyBtb2RlbGxpbmcpIHRvIGdyb3VwIGFuZCBjbGFzc2lmeSBhYnN0cmFjdHMuIFdlIGFsc28gc2VhcmNoZWQgdGhlIGFic3RyYWN0cyBmb3IgdGhlIHRlcm1zICpkYXRhIHNjaWVuY2UqIGFuZCAqYmlnIGRhdGEqIGFuZCBjb25jbHVkZSB0aGVyZSBpcyBjdXJyZW50bHkgYSB2ZXJ5IHNtYWxsIGxpdGVyYXR1cmUgb24gZGF0YSBzY2llbmNlIGluIHB1YmxpYy8gcG9wdWxhdGlvbiBoZWFsdGggYW5kIHRoZXJlIGlzIGEgcG90ZW50aWFsIGxhcmdlIHJlc2VhcmNoIGFnZW5kYSB0byBoZWxwIHVzIHVuZGVyc3RhbmQgaG93IHdlIGNhbiBhcHBseSBlbWVyZ2luZyBkYXRhIG1hbmFnZW1lbnQgYW5kIGFuYWx5dGljIHRlY2huaXF1ZXMgaW4gbW9kZXJuIHB1YmxpYyBoZWFsdGggcHJhY3RpY2UuCgojIyBMb2FkIGxpYnJhcmllcwoKRmlyc3RseSB3ZSdsbCBsb2FkIHRoZSByZWxldmFudCBgUmAgbGlicmFyaWVzLgoKYGBge3IgbG9hZCBsaWJyYXJpZXMsIGluY2x1ZGU9RkFMU0V9CmxpYnJhcnkoZHBseXIpCmxpYnJhcnkoUklTbWVkKQppZighcmVxdWlyZSh3b3JkY2xvdWQpKWluc3RhbGwucGFja2FnZXMoIndvcmRjbG91ZCIpCmxpYnJhcnkod29yZGNsb3VkKQpsaWJyYXJ5KHRpZHl0ZXh0KQpsaWJyYXJ5KHRpZHlyKQpsaWJyYXJ5KGdncGxvdDIpCmlmKCFyZXF1aXJlKHRtKSlpbnN0YWxsLnBhY2thZ2VzKCJ0bSIpCmxpYnJhcnkodG0pCmlmKCFyZXF1aXJlKHRvcGljbW9kZWxzKSlpbnN0YWxsLnBhY2thZ2VzKCJ0b3BpY21vZGVscyIpCmxpYnJhcnkodG9waWNtb2RlbHMpCmlmKCFyZXF1aXJlKHZpcmlkaXMpKWluc3RhbGwucGFja2FnZXMoInZpcmlkaXMiKQpzdXBwcmVzc1BhY2thZ2VTdGFydHVwTWVzc2FnZXMobGlicmFyeSh2aXJpZGlzKSkKCmBgYAoKIyMgU2VuZCBzZWFyY2gKTmV4dCwgd2UnbGwgcXVlcnkgdGhlIFB1Ym1lZCBBUEkgdmlhIHRoZSBSSVNtZWQgcGFja2FnZS4gV2UnbGwgdXNlIGEgYnJvYWQgc2VhcmNoIHN0cmF0ZWd5LgoKYGBge3IgcnVuIHNlYXJjaH0KcmVzMSA8LSBFVXRpbHNTdW1tYXJ5KCJkYXRhICsgc2NpZW5jZSwgcG9wdWxhdGlvbiArIGhlYWx0aCIsIAogICAgICAgICAgICAgICAgICAgICAgdHlwZSA9ICJlc2VhcmNoIiwgCiAgICAgICAgICAgICAgICAgICAgICBkYiA9ICJwdWJtZWQiLAogICAgICAgICAgICAgICAgICAgICAgZGF0ZXR5cGUgPSAicGRhdCIsCiAgICAgICAgICAgICAgICAgICAgICByZXRtYXggPSAxMjAwMCwKICAgICAgICAgICAgICAgICAgICAgIG1pbmRhdGUgPSAyMDA1LCAKICAgICAgICAgICAgICAgICAgICAgIG1heGRhdGUgPSAyMDE2KQoKYGBgCgpUaGUgcXVlcnkgc2VudCB0byBQdWJtZWQgaXMgYHIgcmVzMUBxdWVyeXRyYW5zbGF0aW9uYCB3aGljaCByZXRyaWV2ZXMgYHIgcmVzMUBjb3VudGAgUHVibWVkIGVudHJpZXMuIFRoZSBxdWVyeSBzdHJpbmcgc2hvd3MgdGhhdCBkYXRhIHNjaWVuY2UgaXMgbm90IGEgY3VycmVudCBNRVNIIGhlYWRpbmcuCkkgaGF2ZSByZXN0cmljdGVkIHRoZSBkb3dubG9hZCB0byAxMiwwMDAgZW50cmllcyBpbiB0aGUgaW50ZXJlc3RzIG9mIHRpbWUgYW5kIGxpbWl0YXRpb25zIG9uIHRoZSBQdWJtZWQgQVBJLgoKCmBgYHtyIHJldHJpZXZlIHB1Ym1lZCBlbnRyaWVzLCBjYWNoZT0gVFJVRX0KZmV0Y2ggPC0gRVV0aWxzR2V0KHJlczEsIHR5cGUgPSAiZWZldGNoIiwgZGIgPSAicHVibWVkIikKYGBgCgoKIyMgQ3JlYXRlIGRhdGEgZnJhbWUKYGBge3IgZXh0cmFjdCBmaWVsZHMgYW5kIGNvbnZlcnQgdG8gZGF0YSBmcmFtZX0KYWJzdHJhY3RzIDwtIGRhdGEuZnJhbWUodGl0bGUgPSBmZXRjaEBBcnRpY2xlVGl0bGUsCiAgICAgICAgICAgICAgICAgICAgICAgIGFic3RyYWN0ID0gZmV0Y2hAQWJzdHJhY3RUZXh0LCAKICAgICAgICAgICAgICAgICAgICAgICAgam91cm5hbCA9IGZldGNoQFRpdGxlLAogICAgICAgICAgICAgICAgICAgICAgICBET0kgPSBmZXRjaEBQTUlELCAKICAgICAgICAgICAgICAgICAgICAgICAgeWVhciA9IGZldGNoQFllYXJQdWJtZWQpCgojIyBlbnN1cmUgYWJzdHJhY3RzIGFyZSBjaGFyYWN0ZXIgZmllbGRzIChub3QgZmFjdG9ycykKYWJzdHJhY3RzIDwtIGFic3RyYWN0cyAlPiUgbXV0YXRlKGFic3RyYWN0ID0gYXMuY2hhcmFjdGVyKGFic3RyYWN0KSkKCgphYnN0cmFjdHMgJT4lCiAgaGVhZCgpCmBgYApgYGB7ciBwbG90IGFydGljbGUgY291bnQgcGVyIHllYXJ9CmFic3RyYWN0cyAlPiUKICBncm91cF9ieSh5ZWFyKSAlPiUKICBjb3VudCgpICU+JQogIGZpbHRlcih5ZWFyID4gMjAxMykgJT4lCiAgZ2dwbG90KGFlcyh5ZWFyLCBuKSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2VvbV9saW5lKCkgKwogIGxhYnModGl0bGUgPSAiUHVibWVkIGFydGljbGVzIHdpdGggc2VhcmNoIHRlcm1zIGBkYXRhIHNjaWVuY2VgICYgYHBvcHVsYXRpb24gaGVhbHRoYCBcbjIwMTQtMjAxNyIsIGhqdXN0ID0gMC41LAogICAgICAgeSA9ICJBcnRpY2xlcyIpCgpgYGAKClRoZSB0b3RhbCBudW1iZXIgb2YgYWJzdHJhY3RzIHdhcyBgciBhYnN0cmFjdHMgJT4lIGNvdW50KCkgJT4lIGxpc3QoKWAKCiMjIFdvcmQgY2xvdWQKCmBgYHtyIHdvcmQgY2xvdWQgIHRvcCAxMDAwIHRlcm1zIGFic3RyYWN0cywgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9Nn0KY2xvdWQgPC0gYWJzdHJhY3RzICU+JQogIHVubmVzdF90b2tlbnMod29yZCwgYWJzdHJhY3QpICU+JQogIGFudGlfam9pbihzdG9wX3dvcmRzKSAlPiUKICBjb3VudCh3b3JkLCBzb3J0ID0gVFJVRSkgCiAgCmNsb3VkICU+JQp3aXRoKHdvcmRjbG91ZCh3b3JkLCBuLCBtaW4uZnJlcSA9IDEwLCBtYXgud29yZHMgPSAxMDAwLCBjb2xvcnMgPSBicmV3ZXIucGFsKDgsICJEYXJrMiIpKSwgc2NhbGUgPSBjKDgsLjMpLCBwZXIucm90ID0gMC40KQoKYGBgCgojIyBDcmVhdGUgYmlncmFtcwoKYGBge3IgZXh0cmFjdCBhbmQgcGxvdCBiaWdyYW1zLCBmaWcuaGVpZ2h0PTgsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmRzX2JpZ3JhbXMgPC0gYWJzdHJhY3RzICU+JQogIHVubmVzdF90b2tlbnMobmdyYW0sIGFic3RyYWN0LCB0b2tlbiA9ICJuZ3JhbXMiLCBuPTIpICU+JQogIGNvdW50KG5ncmFtLCBzb3J0ID0gVFJVRSkKCgoKYmlncmFtc19zZXBhcmF0ZWQgPC0gZHNfYmlncmFtcyAlPiUKICBzZXBhcmF0ZShuZ3JhbSwgYygid29yZDEiLCAid29yZDIiKSwgc2VwID0gIiAiKQoKYmlncmFtc19maWx0ZXJlZCA8LSBiaWdyYW1zX3NlcGFyYXRlZCAlPiUKICBmaWx0ZXIoIXdvcmQxICVpbiUgc3RvcF93b3JkcyR3b3JkKSAlPiUKICBmaWx0ZXIoIXdvcmQyICVpbiUgc3RvcF93b3JkcyR3b3JkKSAKCmJpZ3JhbXNfZmlsdGVyZWQKCmJpZ3JhbXNfZmlsdGVyZWQgJT4lIAogIGZpbHRlcih3b3JkMSAhPSAiMCIpICAlPiUKICBjb3VudCh3b3JkMSwgd29yZDIpICU+JQogIGFycmFuZ2UoLW5uKQoKYmlncmFtc191bml0ZWQgPC0gYmlncmFtc19maWx0ZXJlZCAlPiUKICB1bml0ZShiaWdyYW0sIHdvcmQxLCB3b3JkMiwgc2VwID0gIiAiKSAKCmJpZ3JhbXNfdW5pdGVkICU+JQogIGZpbHRlcihuID4gMjUwKSAlPiUKICBhcnJhbmdlKC1uKSAlPiUKICBnZ3Bsb3QoYWVzKHJlb3JkZXIoYmlncmFtLCBuKSwgbikpICsKICBnZW9tX3BvaW50KCkgKwogIGNvb3JkX2ZsaXAoKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSAgPSAxMCkpICsKICBsYWJzKHRpdGxlID0gIkJpZ3JhbXMgd2l0aCBmcmVxdWVuY3kgY291bnQgPiAyNTAiLCB4ID0gIiIpCmBgYAoKCiMjIyBCaWdyYW0gd29yZGNsb3VkCgpgYGB7ciBiaWdyYW0gd29yZGNsb3VkLCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD02fQpiaWdyYW1zX3VuaXRlZCAlPiUKICB3aXRoKHdvcmRjbG91ZChiaWdyYW0sIG4sIG1heC53b3JkcyA9IDEwMDAsIHJhbmRvbS5vcmRlciA9IEZBTFNFLCBjb2xvcnMgPSBicmV3ZXIucGFsKDksICJTZXQxIiksIHNjYWxlID0gYyg4LCAwLjMpKSwgcGVyLnJvdCA9IDAuNCkKCmBgYAoKCgojIyMgSm91cm5hbCB3b3JkbGNvdWQKCmBgYHtyLCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD02fQpjbG91ZDMgPC0gYWJzdHJhY3RzICU+JQogIHNlbGVjdChqb3VybmFsKSAlPiUKICBncm91cF9ieShqb3VybmFsKSAlPiUKICBjb3VudChzb3J0ID0gVFJVRSkKCmNsb3VkMyAlPiUKICB3aXRoKHdvcmRjbG91ZChqb3VybmFsLCBuLCBtaW4uZnJlcSA9IDEwLCByYW5kb20ub3JkZXIgPSBGQUxTRSwgbWF4LndvcmRzID0gODAsIGNvbG9ycyA9IGJyZXdlci5wYWwoOSwgIlNldDEiKSksIHJvdC5wZXIgPSAuNikKYGBgCgojIyMgRXh0cmFjdCBhYnN0cmFjdHMgY29udGFpbmluZyB0aGUgcGhyYXNlICdkYXRhIHNjaWVuY2UnCgpgYGB7ciBhYnN0cmFjdCB3aGljaCBtZW50aW9uIGRhdGEgc2NpZW5jZX0KIGcgPC0gYWJzdHJhY3RzW2dyZXBsKCJkYXRhIHNjaWVuY2UiLCBhYnN0cmFjdHMkYWJzdHJhY3QpLF0KCiBnMSA8LSBnJERPSSAlPiUgbGlzdAogYWJzdHJhY3RzIDwtIGFic3RyYWN0cyAlPiUgCiAgIG11dGF0ZShET0kgID0gYXMuY2hhcmFjdGVyKERPSSkpIAogCiBhYnN0cmFjdHNbYWJzdHJhY3RzJERPSSAlaW4lIGcxW1sxXV0sXSAlPiUKICAgc2VsZWN0KHRpdGxlLCBqb3VybmFsLCBET0kpICU+JQogICBrbml0cjo6a2FibGUoKQogCiAKYGBgCgojIyMgRXh0cmFjdCBhYnN0cmFjdHMgY29udGFpbmluZyB0aGUgcGhyYXNlICdiaWcgZGF0YScKCgpgYGB7ciBhYnN0cmFjdHMgd2hpY2ggbWVudGlvbiBiaWcgZGF0YX0KICAKIGcgPC0gYWJzdHJhY3RzW2dyZXBsKCJiaWcgZGF0YSIsIGFic3RyYWN0cyRhYnN0cmFjdCksXQoKIGcxIDwtIGckRE9JICU+JSBsaXN0CiBhYnN0cmFjdHMgPC0gYWJzdHJhY3RzICU+JSAKICAgbXV0YXRlKERPSSAgPSBhcy5jaGFyYWN0ZXIoRE9JKSkgCiAKIGFic3RyYWN0c1thYnN0cmFjdHMkRE9JICVpbiUgZzFbWzFdXSxdICU+JQogICBzZWxlY3QodGl0bGUsIGpvdXJuYWwsIERPSSwgeWVhcikgJT4lCiAgIGtuaXRyOjprYWJsZSgpCmBgYAoKYGBge3J9CmcgPC0gYWJzdHJhY3RzW2dyZXBsKCJtYWNoaW5lIGxlYXJuaW5nIiwgYWJzdHJhY3RzJGFic3RyYWN0KSxdCgogZzEgPC0gZyRET0kgJT4lIGxpc3QKIGFic3RyYWN0cyA8LSBhYnN0cmFjdHMgJT4lIAogICBtdXRhdGUoRE9JICA9IGFzLmNoYXJhY3RlcihET0kpKSAKIAogYWJzdHJhY3RzW2Fic3RyYWN0cyRET0kgJWluJSBnMVtbMV1dLF0gJT4lCiAgIHNlbGVjdCh0aXRsZSwgam91cm5hbCwgRE9JLCB5ZWFyKSAlPiUKICAga25pdHI6OmthYmxlKGZvcm1hdCA9ICJwYW5kb2MiKQoKYGBgCgojIyBDcmVhdGUgZG9jdW1lbnQgdGVybSBtYXRyaXgKCmBgYHtyIERUTX0KCgoKYWJzdHJhY3RzICU+JQogIHVubmVzdF90b2tlbnMod29yZCwgYWJzdHJhY3QpICU+JQogIGFudGlfam9pbihzdG9wX3dvcmRzKSAlPiUKICBjb3VudChET0ksIHdvcmQsIHNvcnQgPSBUUlVFKSAlPiUKICBjYXN0X2R0bShET0ksIHdvcmQsIG4pIC0+CiAgYWJzdHJhY3RzMQoKCgpgYGAKIyBUb3BpYyBtb2RlbGxpbmcgKGNsdXN0ZXIgYW5hbHlzaXMgb2YgYWJzdHJhY3RzKQoKYGBge3IgdG9waWMgbW9kZWxsaW5nLCBjYWNoZT0gVFJVRX0KbGlicmFyeSh0b3BpY21vZGVscykKCmFic19sZGEgPC0gTERBKGFic3RyYWN0czEsIGsgPSAxMCwgY29udHJvbCA9IGxpc3Qoc2VlZCA9IDEyMzQpKQoKCgphYnNfbGRhX3RkIDwtIHRpZHl0ZXh0Ojo6dGlkeS5MREEoYWJzX2xkYSkKCgoKYGBgCgojIyBQbG90IHRlcm1zIGJ5IHRvcGljCgpgYGB7ciB0b3AgdGVybXMgYnkgdG9waWMsIGZpZy5oZWlnaHQ9OCwgZmlnLndpZHRoPTh9CmxpYnJhcnkoZ2dpcmFwaCkKbGlicmFyeShwbG90bHkpCgoKdG9wX3Rlcm1zIDwtIGFic19sZGFfdGQgJT4lCiAgZ3JvdXBfYnkodG9waWMpICU+JQogIHRvcF9uKDEwLCBiZXRhKSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgYXJyYW5nZSh0b3BpYywgLWJldGEpIAoKdCA8LSB0b3BfdGVybXMgJT4lCiAgZmlsdGVyKHRlcm0gIT0gInF1b3QiICYgdGVybSAhPSAiZGUiICYgdGVybSAhPSAiOTUiICYgdGVybSAhPSAiY2kiKSAKCgpnZ3Bsb3QodCwgYWVzKHJlb3JkZXIodGVybSwgYmV0YSksc3FydChiZXRhKSwgY29sb3VyID0gZmFjdG9yKHRvcGljKSkpICsKICBnZW9tX3BvaW50KHNpemUgID0gLjYpKwogIGdlb21fbGluZShhZXMoZ3JvdXAgPSBmYWN0b3IodG9waWMpKSwgbHR5ID0gImRhc2hlZCIpKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KHNpemUgPSA4LCBhbmdsZSA9IDQ1LCBoanVzdCA9IDEpKSsKICBsYWJzKHggPSAiIikgKwogIHNjYWxlX2ZpbGxfZ3JhZGllbnQyKCkgKwogIHRoZW1lKHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJhbGljZWJsdWUiKSkgKwogIGZhY2V0X3dyYXAofnRvcGljLCBuY29sID0gMikgKwogIGdlb21fdGV4dChhZXMobGFiZWwgPSB0ZXJtLCBhbmdsZSA9IDkwKSkKCgoKICAKYGBgCgojIyBDbGFzc2lmeSBkb2N1bWVudHMgCgpgYGB7ciBkb2N1bWVudCBjbGFzc2lmaWNhdGlvbn0KYWJzX2xkYV9nYW1tYSA8LSB0aWR5dGV4dDo6OnRpZHkuTERBKGFic19sZGEsIG1hdHJpeCA9ICJnYW1tYSIpCgoKYWJzX2NsYXNzIDwtIGFic19sZGFfZ2FtbWEgJT4lCiAgZ3JvdXBfYnkoZG9jdW1lbnQpICU+JQogIHRvcF9uKDEsIGdhbW1hKSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgYXJyYW5nZShnYW1tYSkKCgoKYGBgCgpgYGB7ciwgZmlnLmhlaWdodD04LCBmaWcud2lkdGg9OCwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KYWJzdHJhY3RzICU+JQogIGdyb3VwX2J5KGpvdXJuYWwpICU+JQogIGNvdW50KHNvcnQgPSBUUlVFKSAlPiUKICBmaWx0ZXIobiA+PTQwKSAtPnRvcDQwCgphYnN0cmFjdHMgJT4lCiAgbGVmdF9qb2luKHRvcDQwKSAlPiUKICBmaWx0ZXIoIWlzLm5hKG4pKSAlPiUKICByZW5hbWUoZG9jdW1lbnQgPSBET0kpICU+JQogIGxlZnRfam9pbihhYnNfY2xhc3MpICU+JQogIGZpbHRlcighaXMubmEodG9waWMpKSAlPiUKICBnZ3Bsb3QoYWVzKGRvY3VtZW50LCBmYWN0b3IodG9waWMpKSkgKwogIGdlb21faml0dGVyKGFlcyhjb2xvdXIgPSBmYWN0b3IodG9waWMpKSwgc2l6ZSA9IDEsIHdpZHRoID0gMC4xKSArCiAgZmFjZXRfd3JhcCh+am91cm5hbCkgKwogIHRoZW1lKHN0cmlwLnRleHQueCA9IGVsZW1lbnRfdGV4dChzaXplID0gOCksIGF4aXMudGV4dC54ID0gZWxlbWVudF9ibGFuaygpLCBheGlzLnRpY2tzLnggPSBlbGVtZW50X2JsYW5rKCksIGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplICA9MTApKSArCiAgc2NhbGVfY29sb3JfdmlyaWRpcyhkaXNjcmV0ZSA9IFRSVUUsIG9wdGlvbiA9ICJDIikgKwogIHRoZW1lKHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJhbGljZWJsdWUiKSkgKwogIGxhYnModGl0bGUgPSAiVG9wIDE1IGpvdXJuYWxzIiwKICAgICAgIHN1YnRpdGxlID0gIkRvY3VtZW50cyBieSB0b3BpYyIsCiAgICAgICB4ID0gIlRpbWUiKQogIApgYGAKCg==