Context

Connecticut has published a daily census of every inmate held in jail while awaiting trial.1

Get data

I download the data on 1-8-19 and save it as CT-jail_1-8-19.csv. It has 2.88 million rows.

Call the csv and clean up.

library(data.table); library(janitor)
CT<-fread('CT-jail_1-8-19.csv')
CT<-clean_names(CT)
CT$download_date<-as.Date(CT$download_date, '%m/%d/%Y')
CT$latest_admission_date<-as.Date(CT$latest_admission_date, '%m/%d/%Y')
CT$identifier<-as.character(CT$identifier)
#fix race names
CT$race[CT$race == 'AMER IND'] <- 'Native American'
CT$race[CT$race == 'ASIAN'] <- 'Asian'
CT$race[CT$race == 'BLACK'] <- 'Black'
CT$race[CT$race == 'WHITE'] <- 'White'
CT$race[CT$race == 'HISPANIC'] <- 'Hispanic'

Make graphs

Before making graphs, I call my custom theme, as per usual.

#Load more libraries
library(ggplot2);library(ggrepel); library(extrafont); library(ggthemes);library(reshape);library(grid);
library(scales);library(RColorBrewer);library(gridExtra)
#Define theme for my visuals
my_theme <- function() {
  # Define colors for the chart
  palette <- brewer.pal("Greys", n=9)
  color.background = palette[2]
  color.grid.major = palette[4]
  color.panel = palette[3]
  color.axis.text = palette[9]
  color.axis.title = palette[9]
  color.title = palette[9]
  # Create basic construction of chart
  theme_bw(base_size=9, base_family="Palatino") + 
  # Set the entire chart region to a light gray color
  theme(panel.background=element_rect(fill=color.panel, color=color.background)) +
  theme(plot.background=element_rect(fill=color.background, color=color.background)) +
  theme(panel.border=element_rect(color=color.background)) +
  # Format grid
  theme(panel.grid.major=element_line(color=color.grid.major,size=.25)) +
  theme(panel.grid.minor=element_blank()) +
  theme(axis.ticks=element_blank()) +
  # Format legend
  theme(legend.position="right") +
  theme(legend.background = element_rect(fill=color.background)) +
  theme(legend.text = element_text(size=7,color=color.axis.title)) + 
  theme(legend.title = element_text(size=0,face="bold", color=color.axis.title)) + 
  
  #Format facet labels
  theme(strip.text.x = element_text(size = 8, face="bold"))+
  # Format title and axes labels these and tick marks
  theme(plot.title=element_text(color=color.title, size=18, face="bold", hjust=0)) +
  theme(axis.text.x=element_text(size=8,color=color.axis.text)) +
  theme(axis.text.y=element_text(size=8,color=color.axis.text)) +
  theme(axis.title.x=element_text(size=10,color=color.axis.title, vjust=-1)) +
  theme(axis.title.y=element_text(size=10,color=color.axis.title, vjust=1.8)) +
  #Format title and facet_wrap title
  theme(strip.text = element_text(size=8), plot.title = element_text(size = 14, face = "bold", colour = "black", vjust = 1, hjust=0.5))+
    
  # Plot margins
  theme(plot.margin = unit(c(.2, .2, .2, .2), "cm"))
}

Visual 1

Show line chart of inmates over time.

library(dplyr)
CTdays<- CT %>% 
  group_by(download_date) %>% 
  summarise(n = n())
ggplot(data=CTdays, aes(x=download_date, y=n)) + 
  geom_line()+
  scale_y_continuous(limits=c(0,7000))+
  my_theme()+ theme(plot.title = element_text(hjust = 0))+
  labs(x="", y="Number of Pretrial Inmates")+
  ggtitle("Gender/Race of Connecticut Pretrial Inmates (7/1/16-1/8/19)", subtitle = "Data Available via Connecticut Open Data | Visualization via Alex Albright (thelittledataset.com)")

2017-8-24 is a crazy outlier, remove it.

CTdays<- subset(CTdays, n<6000)

Visual 2

Graph by day now with 2017-8-24 removed (as I assume it must be an error).

ggplot(data=CTdays, aes(x=download_date, y=n)) + 
  geom_line()+
  my_theme()+ theme(plot.title = element_text(hjust = 0))+
  labs(x="Date", y="Number of Pretrial Inmates", caption="\nData plotted by day. Red lines mark the beginning/end of years.")+
  geom_vline(xintercept = as.numeric(as.Date(
    c("2017-01-01","2018-01-01", "2019-01-01")
    )), linetype=4, color="red")+
  scale_x_date(date_breaks = "1 month", date_labels = "%m-%y")+
  scale_y_continuous(limits=c(0,3700))+
  theme(axis.text.x = element_text(angle = 90, hjust = 1))+
  ggtitle("Connecticut Pretrial Inmate Population 7/1/16-1/8/19", subtitle = "Data Available via Connecticut Open Data | Visualization via Alex Albright (thelittledataset.com)")
  
ggsave("time-pop0.png", width=7, height=4.5, dpi=900)

Visual 3

Zoom in to see variation.

ggplot(data=CTdays, aes(x=download_date, y=n)) + 
  geom_line()+
  my_theme()+ theme(plot.title = element_text(hjust = 0))+
  labs(x="Date", y="Number of Pretrial Inmates", caption="\nData plotted by day. Red lines mark the beginning/end of years.")+
  geom_vline(xintercept = as.numeric(as.Date(
    c("2017-01-01","2018-01-01", "2019-01-01")
    )), linetype=4, color="red")+
  scale_x_date(date_breaks = "1 month", date_labels = "%m-%y")+
  theme(axis.text.x = element_text(angle = 90, hjust = 1))+
  ggtitle("Connecticut Pretrial Inmate Population 7/1/16-1/8/19", subtitle = "Data Available via Connecticut Open Data | Visualization via Alex Albright (thelittledataset.com)")
  
ggsave("time-pop.png", width=7, height=4.5, dpi=900)

Visual 4

Color december portions.

CTdays$month<-month(CTdays$download_date)
CTdays$dec<-0
CTdays$dec[CTdays$month==12]<-1
CTdays$dec<-as.numeric(CTdays$dec)
ggplot(data=CTdays, aes(x=download_date, y=n, color=dec)) + 
  geom_line()+ #scale_color_manual(values = c("black", "red"))+
  my_theme()+ theme(plot.title = element_text(hjust = 0))+
  labs(x="Date", y="Number of Pretrial Inmates", caption="\nData plotted by day. Light blue denotes days during December.")+
  scale_x_date(date_breaks = "1 month", date_labels = "%m-%y")+
  theme(axis.text.x = element_text(angle = 90, hjust = 1), legend.position="none")+
  ggtitle("Connecticut Pretrial Inmate Population 7/1/16-1/8/19", subtitle = "Data Available via Connecticut Open Data | Visualization via Alex Albright (thelittledataset.com)")
  
ggsave("time-pop-dec.png", width=7, height=4.5, dpi=900)

Visual 5

Zoom in on December for the three years… Subset down to december days and facet by year.

CTdaysdec<-subset(CTdays, CTdays$dec==1)
CTdaysdec$day<-as.numeric(format(CTdaysdec$download_date, "%d"))
CTdaysdec$year<-year(CTdaysdec$download_date)
ggplot(data=CTdaysdec, aes(x=day, y=n)) + 
  geom_line()+
  geom_point(data=subset(CTdaysdec, day==24), color="#009E73")+
  geom_point(data=subset(CTdaysdec, day==25), color="#D55E00")+
  my_theme()+ theme(plot.title = element_text(hjust = 0))+
  labs(x="Date in December", y="Number of Pretrial Inmates", caption="\nData plotted by day for December 2016, 2017, and 2018.\nGreen dots mark Xmas eve and red dots mark Xmas.")+
  scale_x_continuous(breaks=seq(1,31,3), labels=seq(1,31,3))+
  facet_wrap(~year)+
  ggtitle("Spotting Seasonality", subtitle = "Data Available via Connecticut Open Data | Visualization via Alex Albright (thelittledataset.com)")
  
ggsave("time-pop-xmas.png", width=7, height=4.5, dpi=900)

I add red/green ornaments on Christmas eve and Christmas. There are drops around holidays (xmas).


  1. H/t to Data is Plural for blasting this out way back when.

LS0tCnRpdGxlOiAiU3BvdHRpbmcgKEhvbGlkYXkpIFNlYXNvbmFsaXR5IgphdXRob3I6IEFsZXggQWxicmlnaHQKZGF0ZTogIjMtMzEtMjAxOSIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKIyBDb250ZXh0IAoKQ29ubmVjdGljdXQgW2hhcyBwdWJsaXNoZWQgYSBkYWlseSBjZW5zdXNdKGh0dHBzOi8vZGF0YS5jdC5nb3YvUHVibGljLVNhZmV0eS9BY2N1c2VkLVByZS1UcmlhbC1Jbm1hdGVzLWluLUNvcnJlY3Rpb25hbC1GYWNpbHRpZS9iNjc0LWp5NncpIG9mIGV2ZXJ5IGlubWF0ZSBoZWxkIGluIGphaWwgd2hpbGUgYXdhaXRpbmcgdHJpYWwuXltIL3QgdG8gKkRhdGEgaXMgUGx1cmFsKiBmb3IgYmxhc3RpbmcgdGhpcyBvdXQgd2F5IGJhY2sgd2hlbi5dIAoKIyBHZXQgZGF0YQoKSSBkb3dubG9hZCB0aGUgZGF0YSBvbiAxLTgtMTkgYW5kIHNhdmUgaXQgYXMgYENULWphaWxfMS04LTE5LmNzdmAuIEl0IGhhcyAyLjg4IG1pbGxpb24gcm93cy4KCkNhbGwgdGhlIGBjc3ZgIGFuZCBjbGVhbiB1cC4KCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpsaWJyYXJ5KGRhdGEudGFibGUpOyBsaWJyYXJ5KGphbml0b3IpCkNUPC1mcmVhZCgnQ1QtamFpbF8xLTgtMTkuY3N2JykKQ1Q8LWNsZWFuX25hbWVzKENUKQpDVCRkb3dubG9hZF9kYXRlPC1hcy5EYXRlKENUJGRvd25sb2FkX2RhdGUsICclbS8lZC8lWScpCkNUJGxhdGVzdF9hZG1pc3Npb25fZGF0ZTwtYXMuRGF0ZShDVCRsYXRlc3RfYWRtaXNzaW9uX2RhdGUsICclbS8lZC8lWScpCkNUJGlkZW50aWZpZXI8LWFzLmNoYXJhY3RlcihDVCRpZGVudGlmaWVyKQpgYGAKCiMgTWFrZSBncmFwaHMKCkJlZm9yZSBtYWtpbmcgZ3JhcGhzLCBJIGNhbGwgbXkgY3VzdG9tIHRoZW1lLCBhcyBwZXIgdXN1YWwuCgpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KI0xvYWQgbW9yZSBsaWJyYXJpZXMKbGlicmFyeShnZ3Bsb3QyKTtsaWJyYXJ5KGdncmVwZWwpOyBsaWJyYXJ5KGV4dHJhZm9udCk7IGxpYnJhcnkoZ2d0aGVtZXMpO2xpYnJhcnkocmVzaGFwZSk7bGlicmFyeShncmlkKTsKbGlicmFyeShzY2FsZXMpO2xpYnJhcnkoUkNvbG9yQnJld2VyKTtsaWJyYXJ5KGdyaWRFeHRyYSkKCiNEZWZpbmUgdGhlbWUgZm9yIG15IHZpc3VhbHMKbXlfdGhlbWUgPC0gZnVuY3Rpb24oKSB7CgogICMgRGVmaW5lIGNvbG9ycyBmb3IgdGhlIGNoYXJ0CiAgcGFsZXR0ZSA8LSBicmV3ZXIucGFsKCJHcmV5cyIsIG49OSkKICBjb2xvci5iYWNrZ3JvdW5kID0gcGFsZXR0ZVsyXQogIGNvbG9yLmdyaWQubWFqb3IgPSBwYWxldHRlWzRdCiAgY29sb3IucGFuZWwgPSBwYWxldHRlWzNdCiAgY29sb3IuYXhpcy50ZXh0ID0gcGFsZXR0ZVs5XQogIGNvbG9yLmF4aXMudGl0bGUgPSBwYWxldHRlWzldCiAgY29sb3IudGl0bGUgPSBwYWxldHRlWzldCgogICMgQ3JlYXRlIGJhc2ljIGNvbnN0cnVjdGlvbiBvZiBjaGFydAogIHRoZW1lX2J3KGJhc2Vfc2l6ZT05LCBiYXNlX2ZhbWlseT0iUGFsYXRpbm8iKSArIAoKICAjIFNldCB0aGUgZW50aXJlIGNoYXJ0IHJlZ2lvbiB0byBhIGxpZ2h0IGdyYXkgY29sb3IKICB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kPWVsZW1lbnRfcmVjdChmaWxsPWNvbG9yLnBhbmVsLCBjb2xvcj1jb2xvci5iYWNrZ3JvdW5kKSkgKwogIHRoZW1lKHBsb3QuYmFja2dyb3VuZD1lbGVtZW50X3JlY3QoZmlsbD1jb2xvci5iYWNrZ3JvdW5kLCBjb2xvcj1jb2xvci5iYWNrZ3JvdW5kKSkgKwogIHRoZW1lKHBhbmVsLmJvcmRlcj1lbGVtZW50X3JlY3QoY29sb3I9Y29sb3IuYmFja2dyb3VuZCkpICsKCiAgIyBGb3JtYXQgZ3JpZAogIHRoZW1lKHBhbmVsLmdyaWQubWFqb3I9ZWxlbWVudF9saW5lKGNvbG9yPWNvbG9yLmdyaWQubWFqb3Isc2l6ZT0uMjUpKSArCiAgdGhlbWUocGFuZWwuZ3JpZC5taW5vcj1lbGVtZW50X2JsYW5rKCkpICsKICB0aGVtZShheGlzLnRpY2tzPWVsZW1lbnRfYmxhbmsoKSkgKwoKICAjIEZvcm1hdCBsZWdlbmQKICB0aGVtZShsZWdlbmQucG9zaXRpb249InJpZ2h0IikgKwogIHRoZW1lKGxlZ2VuZC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGw9Y29sb3IuYmFja2dyb3VuZCkpICsKICB0aGVtZShsZWdlbmQudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTcsY29sb3I9Y29sb3IuYXhpcy50aXRsZSkpICsgCiAgdGhlbWUobGVnZW5kLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemU9MCxmYWNlPSJib2xkIiwgY29sb3I9Y29sb3IuYXhpcy50aXRsZSkpICsgCiAgCiAgI0Zvcm1hdCBmYWNldCBsYWJlbHMKICB0aGVtZShzdHJpcC50ZXh0LnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IDgsIGZhY2U9ImJvbGQiKSkrCgogICMgRm9ybWF0IHRpdGxlIGFuZCBheGVzIGxhYmVscyB0aGVzZSBhbmQgdGljayBtYXJrcwogIHRoZW1lKHBsb3QudGl0bGU9ZWxlbWVudF90ZXh0KGNvbG9yPWNvbG9yLnRpdGxlLCBzaXplPTE4LCBmYWNlPSJib2xkIiwgaGp1c3Q9MCkpICsKICB0aGVtZShheGlzLnRleHQueD1lbGVtZW50X3RleHQoc2l6ZT04LGNvbG9yPWNvbG9yLmF4aXMudGV4dCkpICsKICB0aGVtZShheGlzLnRleHQueT1lbGVtZW50X3RleHQoc2l6ZT04LGNvbG9yPWNvbG9yLmF4aXMudGV4dCkpICsKICB0aGVtZShheGlzLnRpdGxlLng9ZWxlbWVudF90ZXh0KHNpemU9MTAsY29sb3I9Y29sb3IuYXhpcy50aXRsZSwgdmp1c3Q9LTEpKSArCiAgdGhlbWUoYXhpcy50aXRsZS55PWVsZW1lbnRfdGV4dChzaXplPTEwLGNvbG9yPWNvbG9yLmF4aXMudGl0bGUsIHZqdXN0PTEuOCkpICsKCiAgI0Zvcm1hdCB0aXRsZSBhbmQgZmFjZXRfd3JhcCB0aXRsZQogIHRoZW1lKHN0cmlwLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT04KSwgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gMTQsIGZhY2UgPSAiYm9sZCIsIGNvbG91ciA9ICJibGFjayIsIHZqdXN0ID0gMSwgaGp1c3Q9MC41KSkrCiAgICAKICAjIFBsb3QgbWFyZ2lucwogIHRoZW1lKHBsb3QubWFyZ2luID0gdW5pdChjKC4yLCAuMiwgLjIsIC4yKSwgImNtIikpCn0KYGBgCgojIyBWaXN1YWwgMQoKU2hvdyBsaW5lIGNoYXJ0IG9mIGlubWF0ZXMgb3ZlciB0aW1lLgoKYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmxpYnJhcnkoZHBseXIpCkNUZGF5czwtIENUICU+JSAKICBncm91cF9ieShkb3dubG9hZF9kYXRlKSAlPiUgCiAgc3VtbWFyaXNlKG4gPSBuKCkpCgpnZ3Bsb3QoZGF0YT1DVGRheXMsIGFlcyh4PWRvd25sb2FkX2RhdGUsIHk9bikpICsgCiAgZ2VvbV9saW5lKCkrCiAgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cz1jKDAsNzAwMCkpKwogIG15X3RoZW1lKCkrIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwKSkrCiAgbGFicyh4PSIiLCB5PSJOdW1iZXIgb2YgUHJldHJpYWwgSW5tYXRlcyIpKwogIGdndGl0bGUoIkdlbmRlci9SYWNlIG9mIENvbm5lY3RpY3V0IFByZXRyaWFsIElubWF0ZXMgKDcvMS8xNi0xLzgvMTkpIiwgc3VidGl0bGUgPSAiRGF0YSBBdmFpbGFibGUgdmlhIENvbm5lY3RpY3V0IE9wZW4gRGF0YSB8IFZpc3VhbGl6YXRpb24gdmlhIEFsZXggQWxicmlnaHQgKHRoZWxpdHRsZWRhdGFzZXQuY29tKSIpCmBgYAoyMDE3LTgtMjQgaXMgYSBjcmF6eSBvdXRsaWVyLCByZW1vdmUgaXQuIApgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KQ1RkYXlzPC0gc3Vic2V0KENUZGF5cywgbjw2MDAwKQpgYGAKCiMjIFZpc3VhbCAyCgpHcmFwaCBieSBkYXkgbm93IHdpdGggMjAxNy04LTI0IHJlbW92ZWQgKGFzIEkgYXNzdW1lIGl0IG11c3QgYmUgYW4gZXJyb3IpLgoKYGBge3IsIG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CmdncGxvdChkYXRhPUNUZGF5cywgYWVzKHg9ZG93bmxvYWRfZGF0ZSwgeT1uKSkgKyAKICBnZW9tX2xpbmUoKSsKICBteV90aGVtZSgpKyB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMCkpKwogIGxhYnMoeD0iRGF0ZSIsIHk9Ik51bWJlciBvZiBQcmV0cmlhbCBJbm1hdGVzIiwgY2FwdGlvbj0iXG5EYXRhIHBsb3R0ZWQgYnkgZGF5LiBSZWQgbGluZXMgbWFyayB0aGUgYmVnaW5uaW5nL2VuZCBvZiB5ZWFycy4iKSsKICBnZW9tX3ZsaW5lKHhpbnRlcmNlcHQgPSBhcy5udW1lcmljKGFzLkRhdGUoCiAgICBjKCIyMDE3LTAxLTAxIiwiMjAxOC0wMS0wMSIsICIyMDE5LTAxLTAxIikKICAgICkpLCBsaW5ldHlwZT00LCBjb2xvcj0icmVkIikrCiAgc2NhbGVfeF9kYXRlKGRhdGVfYnJlYWtzID0gIjEgbW9udGgiLCBkYXRlX2xhYmVscyA9ICIlbS0leSIpKwogIHNjYWxlX3lfY29udGludW91cyhsaW1pdHM9YygwLDM3MDApKSsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCBoanVzdCA9IDEpKSsKICBnZ3RpdGxlKCJDb25uZWN0aWN1dCBQcmV0cmlhbCBJbm1hdGUgUG9wdWxhdGlvbiA3LzEvMTYtMS84LzE5Iiwgc3VidGl0bGUgPSAiRGF0YSBBdmFpbGFibGUgdmlhIENvbm5lY3RpY3V0IE9wZW4gRGF0YSB8IFZpc3VhbGl6YXRpb24gdmlhIEFsZXggQWxicmlnaHQgKHRoZWxpdHRsZWRhdGFzZXQuY29tKSIpCiAgCmdnc2F2ZSgidGltZS1wb3AwLnBuZyIsIHdpZHRoPTcsIGhlaWdodD00LjUsIGRwaT05MDApCmBgYAoKIyMgVmlzdWFsIDMKClpvb20gaW4gdG8gc2VlIHZhcmlhdGlvbi4KCmBgYHtyLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQpnZ3Bsb3QoZGF0YT1DVGRheXMsIGFlcyh4PWRvd25sb2FkX2RhdGUsIHk9bikpICsgCiAgZ2VvbV9saW5lKCkrCiAgbXlfdGhlbWUoKSsgdGhlbWUocGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChoanVzdCA9IDApKSsKICBsYWJzKHg9IkRhdGUiLCB5PSJOdW1iZXIgb2YgUHJldHJpYWwgSW5tYXRlcyIsIGNhcHRpb249IlxuRGF0YSBwbG90dGVkIGJ5IGRheS4gUmVkIGxpbmVzIG1hcmsgdGhlIGJlZ2lubmluZy9lbmQgb2YgeWVhcnMuIikrCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gYXMubnVtZXJpYyhhcy5EYXRlKAogICAgYygiMjAxNy0wMS0wMSIsIjIwMTgtMDEtMDEiLCAiMjAxOS0wMS0wMSIpCiAgICApKSwgbGluZXR5cGU9NCwgY29sb3I9InJlZCIpKwogIHNjYWxlX3hfZGF0ZShkYXRlX2JyZWFrcyA9ICIxIG1vbnRoIiwgZGF0ZV9sYWJlbHMgPSAiJW0tJXkiKSsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwLCBoanVzdCA9IDEpKSsKICBnZ3RpdGxlKCJDb25uZWN0aWN1dCBQcmV0cmlhbCBJbm1hdGUgUG9wdWxhdGlvbiA3LzEvMTYtMS84LzE5Iiwgc3VidGl0bGUgPSAiRGF0YSBBdmFpbGFibGUgdmlhIENvbm5lY3RpY3V0IE9wZW4gRGF0YSB8IFZpc3VhbGl6YXRpb24gdmlhIEFsZXggQWxicmlnaHQgKHRoZWxpdHRsZWRhdGFzZXQuY29tKSIpCiAgCmdnc2F2ZSgidGltZS1wb3AucG5nIiwgd2lkdGg9NywgaGVpZ2h0PTQuNSwgZHBpPTkwMCkKYGBgCgojIyBWaXN1YWwgNAoKQ29sb3IgZGVjZW1iZXIgcG9ydGlvbnMuCgpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KQ1RkYXlzJG1vbnRoPC1tb250aChDVGRheXMkZG93bmxvYWRfZGF0ZSkKQ1RkYXlzJGRlYzwtMApDVGRheXMkZGVjW0NUZGF5cyRtb250aD09MTJdPC0xCkNUZGF5cyRkZWM8LWFzLm51bWVyaWMoQ1RkYXlzJGRlYykKCmdncGxvdChkYXRhPUNUZGF5cywgYWVzKHg9ZG93bmxvYWRfZGF0ZSwgeT1uLCBjb2xvcj1kZWMpKSArIAogIGdlb21fbGluZSgpKyAjc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoImJsYWNrIiwgInJlZCIpKSsKICBteV90aGVtZSgpKyB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMCkpKwogIGxhYnMoeD0iRGF0ZSIsIHk9Ik51bWJlciBvZiBQcmV0cmlhbCBJbm1hdGVzIiwgY2FwdGlvbj0iXG5EYXRhIHBsb3R0ZWQgYnkgZGF5LiBMaWdodCBibHVlIGRlbm90ZXMgZGF5cyBkdXJpbmcgRGVjZW1iZXIuIikrCiAgc2NhbGVfeF9kYXRlKGRhdGVfYnJlYWtzID0gIjEgbW9udGgiLCBkYXRlX2xhYmVscyA9ICIlbS0leSIpKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTAsIGhqdXN0ID0gMSksIGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpKwogIGdndGl0bGUoIkNvbm5lY3RpY3V0IFByZXRyaWFsIElubWF0ZSBQb3B1bGF0aW9uIDcvMS8xNi0xLzgvMTkiLCBzdWJ0aXRsZSA9ICJEYXRhIEF2YWlsYWJsZSB2aWEgQ29ubmVjdGljdXQgT3BlbiBEYXRhIHwgVmlzdWFsaXphdGlvbiB2aWEgQWxleCBBbGJyaWdodCAodGhlbGl0dGxlZGF0YXNldC5jb20pIikKICAKZ2dzYXZlKCJ0aW1lLXBvcC1kZWMucG5nIiwgd2lkdGg9NywgaGVpZ2h0PTQuNSwgZHBpPTkwMCkKYGBgCgojIyBWaXN1YWwgNQoKWm9vbSBpbiBvbiBEZWNlbWJlciBmb3IgdGhlIHRocmVlIHllYXJzLi4uIFN1YnNldCBkb3duIHRvIGRlY2VtYmVyIGRheXMgYW5kIGZhY2V0IGJ5IHllYXIuCgpgYGB7ciwgbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KQ1RkYXlzZGVjPC1zdWJzZXQoQ1RkYXlzLCBDVGRheXMkZGVjPT0xKQpDVGRheXNkZWMkZGF5PC1hcy5udW1lcmljKGZvcm1hdChDVGRheXNkZWMkZG93bmxvYWRfZGF0ZSwgIiVkIikpCkNUZGF5c2RlYyR5ZWFyPC15ZWFyKENUZGF5c2RlYyRkb3dubG9hZF9kYXRlKQoKZ2dwbG90KGRhdGE9Q1RkYXlzZGVjLCBhZXMoeD1kYXksIHk9bikpICsgCiAgZ2VvbV9saW5lKCkrCiAgZ2VvbV9wb2ludChkYXRhPXN1YnNldChDVGRheXNkZWMsIGRheT09MjQpLCBjb2xvcj0iIzAwOUU3MyIpKwogIGdlb21fcG9pbnQoZGF0YT1zdWJzZXQoQ1RkYXlzZGVjLCBkYXk9PTI1KSwgY29sb3I9IiNENTVFMDAiKSsKICBteV90aGVtZSgpKyB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMCkpKwogIGxhYnMoeD0iRGF0ZSBpbiBEZWNlbWJlciIsIHk9Ik51bWJlciBvZiBQcmV0cmlhbCBJbm1hdGVzIiwgY2FwdGlvbj0iXG5EYXRhIHBsb3R0ZWQgYnkgZGF5IGZvciBEZWNlbWJlciAyMDE2LCAyMDE3LCBhbmQgMjAxOC5cbkdyZWVuIGRvdHMgbWFyayBYbWFzIGV2ZSBhbmQgcmVkIGRvdHMgbWFyayBYbWFzLiIpKwogIHNjYWxlX3hfY29udGludW91cyhicmVha3M9c2VxKDEsMzEsMyksIGxhYmVscz1zZXEoMSwzMSwzKSkrCiAgZmFjZXRfd3JhcCh+eWVhcikrCiAgZ2d0aXRsZSgiU3BvdHRpbmcgU2Vhc29uYWxpdHkiLCBzdWJ0aXRsZSA9ICJEYXRhIEF2YWlsYWJsZSB2aWEgQ29ubmVjdGljdXQgT3BlbiBEYXRhIHwgVmlzdWFsaXphdGlvbiB2aWEgQWxleCBBbGJyaWdodCAodGhlbGl0dGxlZGF0YXNldC5jb20pIikKICAKZ2dzYXZlKCJ0aW1lLXBvcC14bWFzLnBuZyIsIHdpZHRoPTcsIGhlaWdodD00LjUsIGRwaT05MDApCmBgYAoKSSBhZGQgcmVkL2dyZWVuIG9ybmFtZW50cyBvbiBDaHJpc3RtYXMgZXZlIGFuZCBDaHJpc3RtYXMuIFRoZXJlIGFyZSBkcm9wcyBhcm91bmQgaG9saWRheXMgKHhtYXMpLgoKLSBUaGVyZSBpcyBhIERhbGxhcyBhcnRpY2xlIHRoYXQgbWVudGlvbnMgQ29tbWlzc2lvbmVyIE1pa2UgQ2FudHJlbGwgd2hvIHNheXMsIFsiV2UgZ28gZG93biBldmVyeSBDaHJpc3RtYXMgLi4uIFBlb3BsZSBhcmUgZ2V0dGluZyB0aGVpciBsb3ZlZCBvbmVzIG91dCBvZiBqYWlsLCBvciBwZW9wbGUgYXJlIG5vdCB3YW50aW5nIHRvIGdldCBpbiBqYWlsLCBzbyB0aGV5IHN0YXkgb3V0LiIiXShodHRwczovL3d3dy5kYWxsYXNuZXdzLmNvbS9uZXdzL2RhbGxhcy1jb3VudHkvMjAxNy8xMi8yMy9kYWxsYXMtY291bnR5LWphaWwtcG9wdWxhdGlvbi1kaXBzLWhpc3RvcmljLWxvd2FuZC1vZmZpY2lhbHMtZGlzYWdyZWUpCi0gVGhlIEJKUyBtZW50aW9ucyB0aGlzIHRvbyBidXQgZG9lc24ndCBhdHRyaWJ1dGUgaXQgdG8gdGhlIGhvbGlkYXlzOiBbIkNvbXBhcmlzb25zIG9mIHllYXItZW5kIGRhdGEgd2l0aCBwcmV2aW91cyBtaWR5ZWFyIGRhdGEgbmVlZCB0byBjb25zaWRlciBzZWFzb25hbCB2YXJpYXRpb25zLCBhcyBqYWlscyB0eXBpY2FsbHkgaG9sZCBmZXdlciBpbm1hdGVzIGF0IHllYXItZW5kIHRoYW4gYXQgbWlkeWVhci4iXShodHRwczovL3d3dy5ianMuZ292L2NvbnRlbnQvcHViL3BkZi9qaTE2LnBkZik=