Introduction
One of the effects of global warming has been the melting of the polar ice at such a rate that it is contributing to the elevation of sealevels.
In this study, we will take historical data of sealevels from 4 locations and determine the annual rise of sealevels in recent years. The data from 4 locations were chosen (i.e., Chittagong, Halifax, Singapore, and Yap.) and are marked on the map given below.
Loading required package: maps

Methodology
The following datasets were chosen and downloaded from the University of Hawaii Sea Level Center archive.
Datasets included in this study
h124a |
Chittagong, Bangladesh |
Flood prone area |
22.24700, 91.82500 |
2007-07-01 to 2018-12-06 |
h275a |
Halifax, Canada |
Large tidal swells |
44.667100, -63.58300 |
1895-10-16 to 2014-08-12 |
h327a |
Keppel Harbour, Singapore |
Busy shallow harbor |
1.26300, 103.82200 |
1981-08-14 to 1990-01-30 |
h008b |
Yap, Micronesia |
Shallow open ocean |
9.51700, 138.13300 |
1969-05-11 to 2018-12-31 |
The data was cleaned, tidied and transformed using the various libraries associated with Tidyverse. The ggplot package was used to visual the results of analysis of the datasets. The data was prepared and analyzed using the following workflow:
── Attaching packages ──────────────────────────────────────── tidyverse 1.3.1 ──
✓ ggplot2 3.3.5 ✓ purrr 0.3.4
✓ tibble 3.1.3 ✓ dplyr 1.0.7
✓ tidyr 1.1.3 ✓ stringr 1.4.0
✓ readr 2.0.0 ✓ forcats 0.5.1
── Conflicts ─────────────────────────────────────────── tidyverse_conflicts() ──
x dplyr::filter() masks stats::filter()
x dplyr::lag() masks stats::lag()
x purrr::map() masks maps::map()
- The CSV versions of the hourly datasets were downloaded for the target locations. The each dataset was loaded into R and trimmed for analysis. The missing data points and unused columns were removed from each of datasets.
loaddata <- function(cnt) {
fnames = c("h124a","h275a","h327a","h008b")
dat = read_csv(paste("datasets/",fnames[cnt],".csv",sep=""),
col_names = c("yr","mon","day","hr","level"),
col_types = c("i","i","i","i","i"))
dat = dat %>%
filter(level > -1) %>%
mutate(tm5 = (as.integer(yr / 5) * 5)) %>%
select(c(yr,tm5,level))
}
- Annual and decade averages were calculated for the data sets. An overall plot of the variation was made. Regression analysis were used to determine the annual rate of change. The annual rate and its standard error were extracted from the regression summary.
extractregression <- function(lm) {
llm = summary(lm)
lllm = round(llm$coefficients[2,1:2],4)
}
- The datasets were reloaded and subjected to linear regression to determine the annual rate of increment.
city = c("Chittagong","Halifax","Singapore","Yap")
sumdat = c("City","StartYr","EndYr","Missing","Existing",
"Annual Rise","err", "Rise5","err5")
colors = rainbow(4)
plot(-1,-1,xlim=c(0,7500),ylim=c(0,0.001),xlab="Sea levels",ylab="Frequency",
main="Range of sealevels observed")
for (cnt in c(1:4)) {
dat = loaddata(cnt)
l = length(dat$yr)
d = density(dat$level,bw=20)
lm = lm(dat$level ~ dat$yr)
lm5 = lm(dat$level ~ dat$tm5)
rate = extractregression(lm)
rate5 = extractregression(lm5)
lines(d$x,d$y,lwd=2,col=colors[cnt])
sumdat = rbind(sumdat,c(city[cnt],
min(dat$yr),max(dat$yr),
365*24 * (1+max(dat$yr)-min(dat$yr)) - l,l,
rate[1], rate[2], rate5[1], rate5[2]))
}
legend(5000,0.0008, city,fill=colors)

Density plots
The range of sealevels experience within a single year or a 5 yr period were calculated this way.
draw_density <- function(cnt,type) {
fnames = c("h124a","h275a","h327a","h008b")
city = c("Chittagong","Halifax","Singapore","Yap")
dat = read_csv(paste("datasets/",fnames[cnt],".csv",sep=""),
col_names = c("yr","mon","day","hr","level"),
col_types = c("i","i","i","i","i"))
dat2 = dat %>%
filter(level > -1) %>%
mutate(tm5 = (as.integer(yr / 5) * 5)) %>%
select(c(yr,tm5,level))
if (type=="Y") {
lb = ": comparison of yr to yr"
dat2 %>%
ggplot(aes(x=level))+
geom_density(mapping=aes(x=level,color=yr,group=yr))+
scale_color_gradient(low="#99000066",high="#FFFF0066")+
labs(title=paste(city[cnt],lb))
} else {
lb = ": comparison of 5yr data units"
dat2 %>%
ggplot(aes(x=level))+
geom_density(mapping=aes(x=level,color=tm5,group=tm5),lwd=2)+
scale_color_gradient(low="#99000066",high="#FFFF0066")+
labs(title=paste(city[cnt],lb))
}
}
Boxplots
Boxplots were also drawn to illustrate the progression of the mean sealevel.
draw_boxplot <- function(cnt,type) {
fnames = c("h124a","h275a","h327a","h008b")
city = c("Chittagong","Halifax","Singapore","Yap")
dat = read_csv(paste("datasets/",fnames[cnt],".csv",sep=""),
col_names = c("yr","mon","day","hr","level"),
col_types = c("i","i","i","i","i"))
dat2 = dat %>%
filter(level > -1) %>%
mutate(tm5 = (as.integer(yr / 5) * 5)) %>%
select(c(yr,tm5,level))
if (type=="Y") {
lb = ": comparison of yr to yr"
dat2 %>%
ggplot(aes(x=yr,y=level,group=yr))+
geom_boxplot(mapping=aes(x=yr,y=level))+
labs(title=paste(city[cnt],lb))
} else {
lb = ": comparison of 5yr data units"
dat2 %>%
ggplot(aes(x=tm5,y=level,group=tm5))+
geom_boxplot(mapping=aes(x=tm5,y=level))+
labs(title=paste(city[cnt],lb))
}
}
Summary of the datasets
knitr::kable(sumdat[,c(1:5)])
sumdat |
City |
StartYr |
EndYr |
Missing |
Existing |
|
Chittagong |
2007 |
2018 |
8402 |
96718 |
|
Halifax |
1895 |
2014 |
233879 |
817321 |
|
Singapore |
1981 |
1990 |
14309 |
73291 |
|
Yap |
1969 |
2018 |
42280 |
395720 |
Results
Each country has a different story to tell. The analysis of the datasets are displayed in the following table. Summary plots for the range of sealevels experienced over 5 year periods are given for each country in the following sections.
sumdat[1,c(6:9)] = c("Freq:","Yr by yr","Freq:","5yr")
knitr::kable(sumdat[,c(1,6:9)])
sumdat |
City |
Freq: |
Yr by yr |
Freq: |
5yr |
|
Chittagong |
-4.4997 |
1.3383 |
-2.4598 |
1.1955 |
|
Halifax |
2.7503 |
0.0186 |
2.7555 |
0.0186 |
|
Singapore |
12.0778 |
1.0691 |
10.1245 |
1.0331 |
|
Yap |
2.6788 |
0.0426 |
2.5486 |
0.0425 |
LS0tCnRpdGxlOiAiVGhlIHJpc2Ugb2Ygc2VhIGxldmVscyBpbiByZWNlbnQgeWVhcnMiCmF1dGhvcjogIkRyIFJvYmVydCBCYXR6aW5nZXIsIFBheWFwIFVuaXZlcnNpdHkgRGVwdC4gb2YgQ29tcHV0ZXIgU2NpZW5jZSIKZGF0ZTogIjIwIEp1bHkgMjAyMSIKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6CiAgICB0b2M6IHRydWUKICAgIHRvY19kZXB0aDogMwogICAgbnVtYmVyX3NlY3Rpb246IHRydWUKICAgIGhpZ2hsaWdodDogdGFuZ28KICAgIHRoZW1lOiB1bml0ZWQKICBwZGZfZG9jdW1lbnQ6IGRlZmF1bHQKYWJzdHJhY3Q6ICJUaGlzIGV4ZXJjaXNlIGlzIHVzZXMgZGF0YSBmcm9tIHRoZSBhcmNoaXZlIG9mIHRoZSBVbml2ZXJzaXR5IG9mIEhhd2FpaSBTZWEgTGV2ZWwgQ2VudGVyIHRvIGRldGVybWluZSB0aGUgcmF0ZSBvZiBjaGFuZ2UgaW4gdGhlIHNlYSBsZXZlbCBpbiByZWNlbnQgeWVhcnMuXG5cbiIKLS0tCgojIEludHJvZHVjdGlvbgoKT25lIG9mIHRoZSBlZmZlY3RzIG9mIGdsb2JhbCB3YXJtaW5nIGhhcyBiZWVuIHRoZSBtZWx0aW5nIG9mIHRoZSBwb2xhciBpY2UgYXQgc3VjaCBhIHJhdGUgdGhhdCBpdCBpcyBjb250cmlidXRpbmcgdG8gdGhlIGVsZXZhdGlvbiBvZiBzZWFsZXZlbHMuW15HdWdnZW5oZWltXQoKW15HdWdnZW5oZWltXTogRGF2aWQgR3VnZ2VuaGllbSwgMjAwNi4gQW4gSW5jb252ZW5pZW50IFRydXRoLiBBIGRvY3VtZW50YXJ5IGZpbG0gYmFzZWQgb24gQWwgR29yZSdzIHNsaWRlIHByZXNlbnRhdGlvbi4gUmVsZWFzZWQgYnkgUGFyYW1vdW50IEZpbG1zIAoKSW4gdGhpcyBzdHVkeSwgd2Ugd2lsbCB0YWtlIGhpc3RvcmljYWwgZGF0YSBvZiBzZWFsZXZlbHMgZnJvbSA0IGxvY2F0aW9ucyBhbmQgZGV0ZXJtaW5lIHRoZSBhbm51YWwgcmlzZSBvZiBzZWFsZXZlbHMgaW4gcmVjZW50IHllYXJzLiBUaGUgZGF0YSBmcm9tIDQgbG9jYXRpb25zIHdlcmUgY2hvc2VuIChpLmUuLCBDaGl0dGFnb25nLFteaDEyNGFdIEhhbGlmYXgsW15oMjc1YV0gU2luZ2Fwb3JlLFteaDMyN2FdIGFuZCBZYXAuW15oMDA4Yl0pIGFuZCBhcmUgbWFya2VkIG9uIHRoZSBtYXAgZ2l2ZW4gYmVsb3cuCgpbXmgxMjRhXTogVW5pdmVyc2l0eSBvZiBIYXdhaWkgU2VhIExldmVsIENlbnRlciwgMjAxNi4gTGVnYWN5IERhdGEgQXJjaGl2ZXM6IFJlYWRpbmdzIGZyb20gQ2hpdHRhZ29uZywgQmFuZ2xhZGVzaDogaHR0cDovL3Voc2xjLnNvZXN0Lmhhd2FpaS5lZHUvZGF0YS9jc3YvcnFkcy9pbmRpYW4vaG91cmx5L2gxMjRhLmNzdgoKW15oMjc1YV06IFVuaXZlcnNpdHkgb2YgSGF3YWlpIFNlYSBMZXZlbCBDZW50ZXIsIDIwMTYuIExlZ2FjeSBEYXRhIEFyY2hpdmVzOiBSZWFkaW5ncyBmcm9tIEhhbGlmYXgsIENhbmFkYTogRG93bmxvYWRlZCBmcm9tIGh0dHA6Ly91aHNsYy5zb2VzdC5oYXdhaWkuZWR1L2RhdGEvY3N2L3JxZHMvYXRsYW50aWMvaG91cmx5L2gyNzVhLmNzdiAKClteaDMyN2FdOiBVbml2ZXJzaXR5IG9mIEhhd2FpaSBTZWEgTGV2ZWwgQ2VudGVyLCAyMDE2LiBMZWdhY3kgRGF0YSBBcmNoaXZlczogUmVhZGluZ3MgZnJvbSBLZXBwZWwgSGFyYm9yLCBTaW5nYXBvcmUuIERvd25sb2FkZWQgZnJvbSAgaHR0cDovL3Voc2xjLnNvZXN0Lmhhd2FpaS5lZHUvZGF0YS9jc3YvcnFkcy9wYWNpZmljL2hvdXJseS9oMzI3YS5jc3YKClteaDAwOGJdOiBVbml2ZXJzaXR5IG9mIEhhd2FpaSBTZWEgTGV2ZWwgQ2VudGVyLCAyMDE2LiBMZWdhY3kgRGF0YSBBcmNoaXZlczogUmVhZGluZ3MgZnJvbSBZYXAsIE1pY3JvbmVzaWEuIERvd25sb2FkZWQgZnJvbSBodHRwOi8vdWhzbGMuc29lc3QuaGF3YWlpLmVkdS9kYXRhL2Nzdi9ycWRzL3BhY2lmaWMvaG91cmx5L2gwMDhiLmNzdgoKCgpgYGB7cixlY2hvPUZBTFNFfQpsaWJyYXJ5KG1hcGRhdGEpCm1hcCgnd29ybGRIaXJlcycseGxpbT1jKC05MCwxNTUpLHlsaW09YygtNTUsODYpKQp0aXRsZSgiTWFwIG9mIExvY2F0aW9ucyBTdHVkaWVkIikKcG9seWdvbihjKC0xMDAsLTEwMCwxNjAsMTYwKSxjKC02MCw5MCw5MCwtNjApLGNvbD0iIzY2OTljYzY2IikKcG9pbnRzKGMoOTEuODI1MDAsICAtNjMuNTgzMDAsICAxMDMuODIyMCwxMzguMTMzMDApLAogICAgICAgYygyMi4yNDcwMCw0NC42NjcwMCwxLjI2MzAwLDkuNTE3MDApLGNvbD0icmVkIixwY2g9MTkpCnRleHQoICBjKDkxLjgyNTAwLCAgLTYzLjU4MzAwLCAgMTAzLjgyMjArNSwxMzguMTMzMDArMiksCiAgICAgICBjKDIyLjI0NzAwLTEsNDQuNjY3MDAtNCwxLjI2MzAwLTUsOS41MTcwMCksCiAgICAgICBjKCJDaGl0dGFnb25nIiwgIkhhbGlmYXgiLCAiU2luZ2Fwb3JlIiwgIllhcCIpLAogICAgICAgcG9zPWMoMyw0LDIsMyksY2V4PTEuMixjb2w9InJlZCIpCmBgYCAgICAgICAgICAKCiMgUmVzZWFyY2ggUXVlc3Rpb24KCgojIE1ldGhvZG9sb2d5CgpUaGUgZm9sbG93aW5nIGRhdGFzZXRzIHdlcmUgY2hvc2VuIGFuZCBkb3dubG9hZGVkIGZyb20gdGhlIFVuaXZlcnNpdHkgb2YgSGF3YWlpIFNlYSBMZXZlbCBDZW50ZXIgYXJjaGl2ZS4KClRhYmxlOiBEYXRhc2V0cyBpbmNsdWRlZCBpbiB0aGlzIHN0dWR5CgorLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tKwp8IEZpbGUgSUQgfCBDSVRZLCBDT1VOVFJZICB8IERlc2NyaXB0aW9uICAgICAgICB8IExBVElUVURFLCBMT05HSVRVREUgfCBEYXRlcyBvZiByZWNvcmQgfAorPT09PT09PT09Kz09PT09PT09PT09PT09PT0rPT09PT09PT09PT09PT09PT09PT0rPT09PT09PT09PT09PT09PT09PT09Kz09PT09PT09PT09PT09PT09Kwp8IGgxMjRhICAgfCBDaGl0dGFnb25nLCAgICB8IEZsb29kIHByb25lIGFyZWEgICB8IDIyLjI0NzAwLCA5MS44MjUwMCAgfCAyMDA3LTA3LTAxIHRvICAgfAp8ICAgICAgICAgfCBCYW5nbGFkZXNoICAgICB8ICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAyMDE4LTEyLTA2ICAgICAgfAorLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tKwp8IGgyNzVhICAgfCBIYWxpZmF4LCAgICAgICB8IExhcmdlIHRpZGFsIHN3ZWxscyB8IDQ0LjY2NzEwMCwgLTYzLjU4MzAwfCAxODk1LTEwLTE2IHRvICAgfAp8ICAgICAgICAgfCBDYW5hZGEgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAyMDE0LTA4LTEyICAgICAgfAorLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tKwp8IGgzMjdhICAgfCBLZXBwZWwgSGFyYm91cix8IEJ1c3kgc2hhbGxvdyBoYXJib3J8IDEuMjYzMDAsIDEwMy44MjIwMCAgfCAxOTgxLTA4LTE0IHRvICAgfAp8ICAgICAgICAgfCBTaW5nYXBvcmUgICAgICB8ICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAxOTkwLTAxLTMwICAgICAgfAorLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tKwp8IGgwMDhiICAgfCBZYXAsICAgICAgICAgICB8IFNoYWxsb3cgb3BlbiBvY2VhbiB8ICA5LjUxNzAwLCAxMzguMTMzMDAgfCAxOTY5LTA1LTExIHRvICAgfAp8ICAgICAgICAgfCBNaWNyb25lc2lhICAgICB8ICAgICAgICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgfCAyMDE4LTEyLTMxICAgICAgfAorLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLS0tKwoKCgpUaGUgZGF0YSB3YXMgY2xlYW5lZCwgdGlkaWVkIGFuZCB0cmFuc2Zvcm1lZCB1c2luZyB0aGUgdmFyaW91cyBsaWJyYXJpZXMgYXNzb2NpYXRlZCB3aXRoIFRpZHl2ZXJzZVtedGlkeXZlcnNlXS4gVGhlIGdncGxvdFteZ2dwbG90XSBwYWNrYWdlIHdhcyB1c2VkIHRvIHZpc3VhbCB0aGUgcmVzdWx0cyBvZiBhbmFseXNpcyBvZiB0aGUgZGF0YXNldHMuIFRoZSBkYXRhIHdhcyBwcmVwYXJlZCBhbmQgYW5hbHl6ZWQgdXNpbmcgdGhlIGZvbGxvd2luZyB3b3JrZmxvdzoKCltedGlkeXZlcnNlXTogSGFkbHkgV2lja2hhbSBldCBhbC4sICgyMDE5KS4gV2VsY29tZSB0byB0aGUgdGlkeXZlcnNlLiBKb3VybmFsIG9mIE9wZW4gU291cmNlIFNvZnR3YXJlLCA0KDQzKSwgMTY4NgoKW15nZ3Bsb3RdOiAgSGFkbHkgV2lja2hhbSwgMjAxNi4gZ2dwbG90MjogRWxlZ2FudCBHcmFwaGljcyBmb3IgRGF0YSBBbmFseXNpcy4gU3ByaW5nZXItVmVybGFnLCBOZXcgWW9yay4KCmBgYHtyfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKYGBgCgoqIFRoZSBDU1YgdmVyc2lvbnMgb2YgdGhlIGhvdXJseSBkYXRhc2V0cyB3ZXJlIGRvd25sb2FkZWQgZm9yIHRoZSB0YXJnZXQgbG9jYXRpb25zLiBUaGUgZWFjaCBkYXRhc2V0IHdhcyBsb2FkZWQgaW50byBSIGFuZCB0cmltbWVkIGZvciBhbmFseXNpcy4gVGhlIG1pc3NpbmcgZGF0YSBwb2ludHMgYW5kIHVudXNlZCBjb2x1bW5zIHdlcmUgcmVtb3ZlZCBmcm9tIGVhY2ggb2YgZGF0YXNldHMuCgoKYGBge3J9CmxvYWRkYXRhIDwtIGZ1bmN0aW9uKGNudCkgewogICBmbmFtZXMgPSAgYygiaDEyNGEiLCJoMjc1YSIsImgzMjdhIiwiaDAwOGIiKQogICBkYXQgPSByZWFkX2NzdihwYXN0ZSgiZGF0YXNldHMvIixmbmFtZXNbY250XSwiLmNzdiIsc2VwPSIiKSwKICAgICAgICAgICAgICAgICAgY29sX25hbWVzID0gYygieXIiLCJtb24iLCJkYXkiLCJociIsImxldmVsIiksCiAgICAgICAgICAgICAgICAgIGNvbF90eXBlcyA9IGMoImkiLCJpIiwiaSIsImkiLCJpIikpCiAgIGRhdCA9IGRhdCAlPiUgCiAgICAgICBmaWx0ZXIobGV2ZWwgPiAtMSkgJT4lCiAgICAgICBtdXRhdGUodG01ID0gKGFzLmludGVnZXIoeXIgLyA1KSAqIDUpKSAlPiUKICAgICAgIHNlbGVjdChjKHlyLHRtNSxsZXZlbCkpCn0KYGBgCgoqIEFubnVhbCBhbmQgZGVjYWRlIGF2ZXJhZ2VzIHdlcmUgY2FsY3VsYXRlZCBmb3IgdGhlIGRhdGEgc2V0cy4gQW4gb3ZlcmFsbCBwbG90IG9mIHRoZSB2YXJpYXRpb24gd2FzIG1hZGUuIFJlZ3Jlc3Npb24gYW5hbHlzaXMgd2VyZSB1c2VkIHRvIGRldGVybWluZSB0aGUgYW5udWFsIHJhdGUgb2YgY2hhbmdlLiBUaGUgYW5udWFsIHJhdGUgYW5kIGl0cyBzdGFuZGFyZCBlcnJvciB3ZXJlIGV4dHJhY3RlZCBmcm9tIHRoZSByZWdyZXNzaW9uIHN1bW1hcnkuCgpgYGB7cn0KZXh0cmFjdHJlZ3Jlc3Npb24gPC0gZnVuY3Rpb24obG0pIHsKICAgbGxtID0gc3VtbWFyeShsbSkKICAgbGxsbSA9IHJvdW5kKGxsbSRjb2VmZmljaWVudHNbMiwxOjJdLDQpCn0gCmBgYAoKKiBUaGUgZGF0YXNldHMgd2VyZSByZWxvYWRlZCBhbmQgc3ViamVjdGVkIHRvIGxpbmVhciByZWdyZXNzaW9uIHRvIGRldGVybWluZSB0aGUgYW5udWFsIHJhdGUgb2YgaW5jcmVtZW50LgoKYGBge3J9CmNpdHkgPSBjKCJDaGl0dGFnb25nIiwiSGFsaWZheCIsIlNpbmdhcG9yZSIsIllhcCIpCnN1bWRhdCA9IGMoIkNpdHkiLCJTdGFydFlyIiwiRW5kWXIiLCJNaXNzaW5nIiwiRXhpc3RpbmciLAogICAgICAgICAgICJBbm51YWwgUmlzZSIsImVyciIsICJSaXNlNSIsImVycjUiKQpjb2xvcnMgPSByYWluYm93KDQpCnBsb3QoLTEsLTEseGxpbT1jKDAsNzUwMCkseWxpbT1jKDAsMC4wMDEpLHhsYWI9IlNlYSBsZXZlbHMiLHlsYWI9IkZyZXF1ZW5jeSIsCiAgICAgbWFpbj0iUmFuZ2Ugb2Ygc2VhbGV2ZWxzIG9ic2VydmVkIikKCmZvciAoY250IGluIGMoMTo0KSkgewogICBkYXQgPSBsb2FkZGF0YShjbnQpCiAgIGwgPSBsZW5ndGgoZGF0JHlyKQogICBkID0gZGVuc2l0eShkYXQkbGV2ZWwsYnc9MjApCiAgIGxtID0gbG0oZGF0JGxldmVsIH4gZGF0JHlyKQogICBsbTUgPSBsbShkYXQkbGV2ZWwgfiBkYXQkdG01KSAKICAgcmF0ZSA9IGV4dHJhY3RyZWdyZXNzaW9uKGxtKQogICByYXRlNSA9IGV4dHJhY3RyZWdyZXNzaW9uKGxtNSkKICAgbGluZXMoZCR4LGQkeSxsd2Q9Mixjb2w9Y29sb3JzW2NudF0pCiAgIHN1bWRhdCA9IHJiaW5kKHN1bWRhdCxjKGNpdHlbY250XSwKICAgICAgICAgbWluKGRhdCR5ciksbWF4KGRhdCR5ciksCiAgICAgICAgIDM2NSoyNCAqICgxK21heChkYXQkeXIpLW1pbihkYXQkeXIpKSAtIGwsbCwKICAgICAgICAgcmF0ZVsxXSwgcmF0ZVsyXSwgcmF0ZTVbMV0sIHJhdGU1WzJdKSkKfQpsZWdlbmQoNTAwMCwwLjAwMDgsIGNpdHksZmlsbD1jb2xvcnMpCmBgYAoKIyMgRGVuc2l0eSBwbG90cwoKVGhlIHJhbmdlIG9mIHNlYWxldmVscyBleHBlcmllbmNlIHdpdGhpbiBhIHNpbmdsZSB5ZWFyIG9yIGEgNSB5ciBwZXJpb2Qgd2VyZSBjYWxjdWxhdGVkIHRoaXMgd2F5LgoKYGBge3J9CmRyYXdfZGVuc2l0eSA8LSBmdW5jdGlvbihjbnQsdHlwZSkgewpmbmFtZXMgPSAgYygiaDEyNGEiLCJoMjc1YSIsImgzMjdhIiwiaDAwOGIiKQpjaXR5ID0gYygiQ2hpdHRhZ29uZyIsIkhhbGlmYXgiLCJTaW5nYXBvcmUiLCJZYXAiKQogICBkYXQgPSByZWFkX2NzdihwYXN0ZSgiZGF0YXNldHMvIixmbmFtZXNbY250XSwiLmNzdiIsc2VwPSIiKSwKICAgICAgICAgICAgICAgICAgY29sX25hbWVzID0gYygieXIiLCJtb24iLCJkYXkiLCJociIsImxldmVsIiksCiAgICAgICAgICAgICAgICAgIGNvbF90eXBlcyA9IGMoImkiLCJpIiwiaSIsImkiLCJpIikpCiAgIGRhdDIgPSBkYXQgJT4lIAogICAgICAgZmlsdGVyKGxldmVsID4gLTEpICU+JQogICAgICAgbXV0YXRlKHRtNSA9IChhcy5pbnRlZ2VyKHlyIC8gNSkgKiA1KSkgJT4lCiAgICAgICBzZWxlY3QoYyh5cix0bTUsbGV2ZWwpKQogICBpZiAodHlwZT09IlkiKSB7CiAgICAgIGxiID0gIjogY29tcGFyaXNvbiBvZiB5ciB0byB5ciIKICAgZGF0MiAlPiUKICAgICAgIGdncGxvdChhZXMoeD1sZXZlbCkpKwogICAgICAgZ2VvbV9kZW5zaXR5KG1hcHBpbmc9YWVzKHg9bGV2ZWwsY29sb3I9eXIsZ3JvdXA9eXIpKSsKICAgICAgIHNjYWxlX2NvbG9yX2dyYWRpZW50KGxvdz0iIzk5MDAwMDY2IixoaWdoPSIjRkZGRjAwNjYiKSsKICAgICAgIGxhYnModGl0bGU9cGFzdGUoY2l0eVtjbnRdLGxiKSkKICAgfSBlbHNlIHsKICAgICAgbGIgPSAiOiBjb21wYXJpc29uIG9mIDV5ciBkYXRhIHVuaXRzIgogICBkYXQyICU+JQogICAgICAgZ2dwbG90KGFlcyh4PWxldmVsKSkrCiAgICAgICBnZW9tX2RlbnNpdHkobWFwcGluZz1hZXMoeD1sZXZlbCxjb2xvcj10bTUsZ3JvdXA9dG01KSxsd2Q9MikrCiAgICAgICBzY2FsZV9jb2xvcl9ncmFkaWVudChsb3c9IiM5OTAwMDA2NiIsaGlnaD0iI0ZGRkYwMDY2IikrCiAgICAgICBsYWJzKHRpdGxlPXBhc3RlKGNpdHlbY250XSxsYikpCn0KfQpgYGAKCiMjIEJveHBsb3RzCgpCb3hwbG90cyB3ZXJlIGFsc28gZHJhd24gdG8gaWxsdXN0cmF0ZSB0aGUgcHJvZ3Jlc3Npb24gb2YgdGhlIG1lYW4gc2VhbGV2ZWwuCgpgYGB7cn0KZHJhd19ib3hwbG90IDwtIGZ1bmN0aW9uKGNudCx0eXBlKSB7CmZuYW1lcyA9ICBjKCJoMTI0YSIsImgyNzVhIiwiaDMyN2EiLCJoMDA4YiIpCmNpdHkgPSBjKCJDaGl0dGFnb25nIiwiSGFsaWZheCIsIlNpbmdhcG9yZSIsIllhcCIpCiAgIGRhdCA9IHJlYWRfY3N2KHBhc3RlKCJkYXRhc2V0cy8iLGZuYW1lc1tjbnRdLCIuY3N2IixzZXA9IiIpLAogICAgICAgICAgICAgICAgICBjb2xfbmFtZXMgPSBjKCJ5ciIsIm1vbiIsImRheSIsImhyIiwibGV2ZWwiKSwKICAgICAgICAgICAgICAgICAgY29sX3R5cGVzID0gYygiaSIsImkiLCJpIiwiaSIsImkiKSkKICAgZGF0MiA9IGRhdCAlPiUgCiAgICAgICBmaWx0ZXIobGV2ZWwgPiAtMSkgJT4lCiAgICAgICBtdXRhdGUodG01ID0gKGFzLmludGVnZXIoeXIgLyA1KSAqIDUpKSAlPiUKICAgICAgIHNlbGVjdChjKHlyLHRtNSxsZXZlbCkpCiAgIGlmICh0eXBlPT0iWSIpIHsKICAgICAgbGIgPSAiOiBjb21wYXJpc29uIG9mIHlyIHRvIHlyIgogICBkYXQyICU+JQogICAgICAgZ2dwbG90KGFlcyh4PXlyLHk9bGV2ZWwsZ3JvdXA9eXIpKSsKICAgICAgIGdlb21fYm94cGxvdChtYXBwaW5nPWFlcyh4PXlyLHk9bGV2ZWwpKSsKICAgICAgIGxhYnModGl0bGU9cGFzdGUoY2l0eVtjbnRdLGxiKSkKICAgfSBlbHNlIHsKICAgICAgbGIgPSAiOiBjb21wYXJpc29uIG9mIDV5ciBkYXRhIHVuaXRzIgogICBkYXQyICU+JQogICAgICAgZ2dwbG90KGFlcyh4PXRtNSx5PWxldmVsLGdyb3VwPXRtNSkpKwogICAgICAgZ2VvbV9ib3hwbG90KG1hcHBpbmc9YWVzKHg9dG01LHk9bGV2ZWwpKSsKICAgICAgIGxhYnModGl0bGU9cGFzdGUoY2l0eVtjbnRdLGxiKSkKfQp9CmBgYAoKIyMgU3VtbWFyeSBvZiB0aGUgZGF0YXNldHMKCmBgYHtyfQprbml0cjo6a2FibGUoc3VtZGF0WyxjKDE6NSldKQpgYGAKCiMgUmVzdWx0cwoKRWFjaCBjb3VudHJ5IGhhcyBhIGRpZmZlcmVudCBzdG9yeSB0byB0ZWxsLiBUaGUgYW5hbHlzaXMgb2YgdGhlIGRhdGFzZXRzIGFyZSBkaXNwbGF5ZWQgaW4gdGhlIGZvbGxvd2luZyB0YWJsZS4gU3VtbWFyeSBwbG90cyBmb3IgdGhlIHJhbmdlIG9mIHNlYWxldmVscyBleHBlcmllbmNlZCBvdmVyIDUgeWVhciBwZXJpb2RzIGFyZSBnaXZlbiBmb3IgZWFjaCBjb3VudHJ5IGluIHRoZSBmb2xsb3dpbmcgc2VjdGlvbnMuCgoKYGBge3J9CnN1bWRhdFsxLGMoNjo5KV0gPSBjKCJGcmVxOiIsIllyIGJ5IHlyIiwiRnJlcToiLCI1eXIiKQprbml0cjo6a2FibGUoc3VtZGF0WyxjKDEsNjo5KV0pCmBgYAoKIyMgWWVhciB0byB5ZWFyIGNvbXBhcmlzb25zIAoKKiAqKkNoaXR0YWdvbmcsIEJhbmdsYWRlc2gqKgoKYGBge3Isb3V0LndpZHRoPSI5MCUiLGZpZy53aWR0aD03LGZpZy5oZWlnaHQ9NH0gICAgICAKZHJhd19kZW5zaXR5KDEsIlkiKQpgYGAKCgoKKiAqKkhhbGlmYXgsIENhbmFkYSoqCgpgYGB7cn0KZHJhd19kZW5zaXR5KDIsIlkiKQpgYGAKCiogKipTaW5nYXBvcmUqKgoKYGBge3J9CmRyYXdfZGVuc2l0eSgzLCJZIikKYGBgCgoqICoqWWFwLCBNaWNyb25lc2lhKioKCmBgYHtyfQpkcmF3X2RlbnNpdHkoNCwiWSIpCmBgYAoKCiMgU3VtbWFyeQoKIyMgQ2hpdHRhZ29uZwoKYGBge3Isb3V0LndpZHRoPSI1MCUiLGVjaG89RkFMU0V9CmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCJzbGlkZXMvQ2hpdHRhZ29uZy5qcGciKQpgYGAKCmBgYHtyLG91dC53aWR0aD0iOTAlIixmaWcud2lkdGg9NyxmaWcuaGVpZ2h0PTR9ICAgICAgCmRyYXdfZGVuc2l0eSgxLCJUIikKYGBgCgpgYGB7cn0KZHJhd19ib3hwbG90KDEsIlkiKQpgYGAKCiogVGhlIHNlbnNvcnMgYXJlIG9uIGEgYnVveSBpbiB0aGUgZXN0dWFyeSBmcm9tIGEgbWFqb3Igcml2ZXIgZmxvd2luZyBmcm9tIE15YW5tYXIuCiogTmVhciA2MCUgb2YgQmFuZ2xhZGVzaCdzIGxhbmQgbWFzcyB3YXMgZmxvb2RlZCAoPjJtKSBhbm51YWxseSBkdXJpbmcgcmFpbnkgc2Vhc29uLiAKKiBUaGUgcml2ZXIgZmxvb2Rpbmcgd2FzIHNldmVyZSAoPjQgbSkgYmVmb3JlIHRoZSByaXZlciB3YXMgZHJlZGdlZC4KKiBEcmVkZ2luZyBjaGFuZ2VkIHRoZSBsb3d0aWRlIHJlYWRpbmdzIGJ1dCB0aGUgaGlnaCB0aWRlIHJlYWRpbmdzIGNvbnRpbnVlZCB0byBpbmNyZWFzZSB3aXRoIHRpbWUuCiogVGhlIHByb2dyZXNzIGJlaW5nIG1hZGUgaW4gZHJlZGdpbmcgYW5kIGZsb29kIHByZXZlbnRpb24gKDEwY20gcGVyIHlyKSBtYXNrcyB3aGF0ZXZlciBlZmZlY3RzIGluY3JlYXNpbmcgc2VhbGV2ZWwgbWlnaHQgYmUgKDJtbSBwZXIgeXIpCgojIyBIYWxpZmF4CgpgYGB7cixvdXQud2lkdGg9IjUwJSIsZWNobz1GQUxTRX0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoInNsaWRlcy9IYWxpZmF4LmpwZyIpCmBgYAoKYGBge3Isb3V0LndpZHRoPSI5MCUiLGZpZy53aWR0aD03LGZpZy5oZWlnaHQ9NH0KZHJhd19kZW5zaXR5KDIsIlQiKQpgYGAKYGBge3J9CmRyYXdfYm94cGxvdCgyLCJZIikKYGBgCiogU2Vuc29ycyBvbiBhIGJ1b3kgYXQgdGhlIG1vdXRoIG9mIHRoZSBoYXJib3IuCiogVGhlIHRpZGFsIGJheSBjaGFuZ2VzIHRoZSBzaGFwZSBvZiB0aGUgdGlkYWwgY3VydmUgYnV0IGhlbHBzIHRvIGdpdmVuIGNvbnN0YW50IHJlYWRpbmdzLgoqIEluaXRpYWxseSB0aGUgc2VhbGV2ZWxzIHdlcmUgY29uc3RhbnQgYnV0IHRoZSByaXNlIGluIHNlYWxldmVsIGhhcyBiZWVuIG9uZ29pbmcgZm9yIDEwMCB5ZWFycy4KCgojIyBTaW5nYXBvcmUKCmBgYHtyLG91dC53aWR0aD0iNTAlIixlY2hvPUZBTFNFfQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygic2xpZGVzL1NpbmdhcG9yZS5qcGciKQpgYGAKCmBgYHtyLG91dC53aWR0aD0iOTAlIixmaWcud2lkdGg9NyxmaWcuaGVpZ2h0PTR9CmRyYXdfZGVuc2l0eSgzLCJUIikKYGBgCmBgYHtyfQpkcmF3X2JveHBsb3QoMywiWSIpCmBgYAoKKiBEcmVkZ2luZyBhbmQgd2lkZW5pbmcgb2YgdGhlIGNoYW5uZWwgY29udHJpYnV0ZWQgdG8gaGVpZ2h0IG9mIHRoZSB0aWRlcy4KKiBDaGFuZ2VzIGluIHJhaW4gcGF0dGVybnMgYW5kIGZsYXNoIGZsb29kaW5nIG9mIDE5ODAgY29udHJpYnV0ZWQgdG8gYSByaXNlIHRoZSBzZWFsZXZlbCByZWFkaW5ncy4KKiBBZnRlciAxOTgwLCB0aGUgc2VhIGxldmVscyBoYXZlIGEgY29uc2lzdGVudCByaXNlLgoKCiMjIFlhcAoKYGBge3Isb3V0LndpZHRoPSI1MCUiLGVjaG89RkFMU0V9CmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCJzbGlkZXMvWWFwLmpwZyIpCmBgYAoKYGBge3Isb3V0LndpZHRoPSI5MCUiLGZpZy53aWR0aD03LGZpZy5oZWlnaHQ9NH0KZHJhd19kZW5zaXR5KDQsIlQiKQpgYGAKCmBgYHtyfQpkcmF3X2JveHBsb3QoNCwiWSIpCmBgYAoKKiBTZW5zb3JzIHdlcmUgbG9jYXRlZCBvbiBhbiBvZmZzaG9yZSBidW95IHdoZXJlIHRoZXkgd2VyZSBub3QgYm90aGVyZWQgYnkgdGlkYWwgcmVzaXN0YW5jZSBvZiB0aGUgc2hvcmVsaW5lLgoqIFRoZSB0aWRhbCBsZXZlbHMgd2VyZSBmYXIgbW9yZSByZWd1bGFyIHRoYW4gb3RoZXIgaGFyYm9yIHJlYWRpbmdzLgoqIFRoZXJlIHNlZW1zIHRvIGEgc3RlYWR5IGluY3JlbWVudCBzaW5jZSAxOTkwLCB0aGUgaW5jcmVhc2UgaW4gdGhlIHNpemUgYW5kIG51bWJlciBvZiB0eXBob29ucyBoYXZlIGhhZCBhbiBlZmZlY3Qgb2YgdGhlIHNlYSBsZXZlbCBtZWFzdXJlZCBpbiByZWNlbnQgeWVhcnMuLgoKCkluIHNob3J0LCB0aGUgdGlkZXMgaGF2ZSBiZWVuIHJpc2luZyBhcHByb3hpbWF0ZWx5IDJtbSBwZXIgeWVhciBhcm91bmQgdGhlIGdsb2JlLiBIb3dldmVyLCBzdG9ybXMsIGZsb29kaW5nLCBlYXJ0aHF1YWtlIGRyaXZlbiB0c3VuYW1pcywgYW5kIGV2ZW4gdGhlIGRhaWx5IHRpZGVzIGNyZWF0ZSBzaG9ydCB0ZXJtIGxvY2FsIHZhcmlhdGlvbnMgdGhhdCBjYW4gbWFzayB0aGUgZWZmZWN0cyBvZiBnbG9iYWwgc2VhIGNoYW5nZXMuIEhvd2V2ZXIsIGxvbmcgdGVybSBzdHVkaWVzIHBhcnRpY3VsYXJseSBvZiBvZmZzaG9yZSBidW95cyBjbGVhcmx5IGlsbHVzdHJhdGUgdGhlIHRyZW5kIHRvd2FyZHMgaGlnaGVyIHRpZGVzIG92ZXIgdGltZS4gSG93ZXZlciwgZGF0YSBmcm9tIG9mZnNob3JlIGJ1b3lzIHdlcmUgb2Z0ZW4gbG9zdCBwYXJ0aWN1bGFybHkgaW4gdGhlIHllYXJseSB5ZWFycyBvZiBvcGVyYXRpb24uIAoKIyBSZWZlcmVuY2UK