Qualitative Color
Schemes
There are several color blind safe color schemes for qualitative
data. The following are short list of these suggested default schemes
for further modifications. Qualitative color schemes are probably the
most important and used in data visualization.
The bright qualitative color scheme is color-blind safe. The main
scheme for lines and their labels.
par(mfrow=c(2,4))
plot(1:5,type="n", axes = FALSE, xlab = "", ylab = "")
draw.circle(3,3,2,col="#4477AA")
text(3,3, "#4477AA")
##
plot(1:5,type="n", axes = FALSE, xlab = "", ylab = "")
draw.circle(3,3,2,col="#EE6677")
text(3,3, "#EE6677")
##
plot(1:5,type="n", axes = FALSE, xlab = "", ylab = "")
draw.circle(3,3,2,col="#228833")
text(3,3, "#228833")
##
plot(1:5,type="n",axes = FALSE, xlab = "", ylab = "")
draw.circle(3,3,2,col="#CCBB44")
text(3,3, "#CCBB44")
##
plot(1:5,type="n", axes = FALSE, xlab = "", ylab = "")
draw.circle(3,3,2,col="#66CCEE")
text(3,3, "#66CCEE")
##
plot(1:5,type="n", axes = FALSE, xlab = "", ylab = "")
draw.circle(3,3,2,col="#AA3377")
text(3,3, "#AA3377")
##
plot(1:5,type="n", axes = FALSE, xlab = "", ylab = "")
draw.circle(3,3,2,col="#BBBBBB")
text(3,3, "#BBBBBB")

High-contrast qualitative color scheme, an alternative to the bright
scheme that is color-blind safe, and optimized for contrast. The samples
below are shades of grey with the same luminescence. This scheme also
works well for people with monochrome vision and in a monochrome
printout.
par(mfrow=c(2,3))
plot(1:5,type="n", axes = FALSE, xlab = "", ylab = "", cex = 0.8)
draw.circle(3,3,2,col="#FFFFFF")
text(3,3, "#FFFFFF")
##
plot(1:5,type="n", axes = FALSE, xlab = "", ylab = "")
draw.circle(3,3,2,col="#004488")
text(3,3, "#004488")
##
plot(1:5,type="n", axes = FALSE, xlab = "", ylab = "")
draw.circle(3,3,2,col="#DDAA33")
text(3,3, "#DDAA33")
##
plot(1:5,type="n",axes = FALSE, xlab = "", ylab = "")
draw.circle(3,3,2,col="#BB5566")
text(3,3, "#BB5566")
##
plot(1:5,type="n", axes = FALSE, xlab = "", ylab = "")
draw.circle(3,3,2,col="#66CCEE")
text(3,3, "#66CCEE")
##
plot(1:5,type="n", axes = FALSE, xlab = "", ylab = "")
draw.circle(3,3,2,col="#000000")
text(3,3, "#000000", col = "#FFFFFF")

A vibrant qualitative color scheme, an alternative to the bright
scheme that is equally color-blind safe. It has been designed for a data
visualization framework.
par(mfrow=c(2,4))
plot(1:5,type="n", axes = FALSE, xlab = "", ylab = "")
draw.circle(3,3,2,col="#EE7733")
text(3,3, "#EE7733")
##
plot(1:5,type="n", axes = FALSE, xlab = "", ylab = "")
draw.circle(3,3,2,col="#0077BB")
text(3,3, "#0077BB")
##
plot(1:5,type="n", axes = FALSE, xlab = "", ylab = "")
draw.circle(3,3,2,col="#33BBEE")
text(3,3, "#33BBEE")
##
plot(1:5,type="n",axes = FALSE, xlab = "", ylab = "")
draw.circle(3,3,2,col="#EE3377")
text(3,3, "#EE3377")
##
plot(1:5,type="n", axes = FALSE, xlab = "", ylab = "")
draw.circle(3,3,2,col="#CC3311")
text(3,3, "#CC3311")
##
plot(1:5,type="n", axes = FALSE, xlab = "", ylab = "")
draw.circle(3,3,2,col="#009988")
text(3,3, "#009988")
##
plot(1:5,type="n", axes = FALSE, xlab = "", ylab = "")
draw.circle(3,3,2,col="#BBBBBB")
text(3,3, "#BBBBBB")

Muted qualitative color scheme, an alternative to the bright scheme
that is equally color-blind safe with more colors, but lacking a clear
red or medium blue.
par(mfrow=c(3,3))
plot(1:5,type="n", axes = FALSE, xlab = "", ylab = "")
draw.circle(3,3,1,col="#CC6677")
text(3,3, "#CC6677")
##
plot(1:5,type="n", axes = FALSE, xlab = "", ylab = "")
draw.circle(3,3,1,col="#332288")
text(3,3, "#332288")
##
plot(1:5,type="n", axes = FALSE, xlab = "", ylab = "")
draw.circle(3,3,1,col="#DDCC77")
text(3,3, "#DDCC77")
##
plot(1:5,type="n",axes = FALSE, xlab = "", ylab = "")
draw.circle(3,3,1,col="#117733")
text(3,3, "#117733")
##
plot(1:5,type="n", axes = FALSE, xlab = "", ylab = "")
draw.circle(3,3,1,col="#88CCEE")
text(3,3, "#88CCEE")
##
plot(1:5,type="n", axes = FALSE, xlab = "", ylab = "")
draw.circle(3,3,1,col="#882255")
text(3,3, "#882255")
##
plot(1:5,type="n",axes = FALSE, xlab = "", ylab = "")
draw.circle(3,3,1,col="#44AA99")
text(3,3, "#44AA99")
##
plot(1:5,type="n", axes = FALSE, xlab = "", ylab = "")
draw.circle(3,3,1,col="#999933")
text(3,3, "#999933")
##
plot(1:5,type="n", axes = FALSE, xlab = "", ylab = "")
draw.circle(3,3,1,col="#AA4499")
text(3,3, "#AA4499")

Medium-contrast qualitative color scheme, an alternative to the
high-contrast scheme that is color-blind safe with more colors. It is
also optimized for contrast to work in a monochrome printout, but the
differences are inevitably smaller. It is designed for situations
needing color pairs, shown by the three rectangles, with the lower half
in the grey-scale equivalent.
par(mfrow=c(1,5), oma=c(0,0,0,0), mar = c(1,0.5,1,0.5))
plot(NULL, type="n", xlim=c(-1,1), ylim=c(-1,1), axes = FALSE, xlab = "", ylab = "")
rect(xleft = -1, ybottom = -0.5, xright =1, ytop = 0.5, lty = 1, col = "#648FFF")
text(0,0, "#648FFF")
##
plot(NULL, type="n", xlim=c(-1,1), ylim=c(-1,1), axes = FALSE, xlab = "", ylab = "")
rect(xleft = -1, ybottom = -0.5, xright =1, ytop = 0.5, lty = 1, col = "#785EF0")
text(0,0, "#785EF0")
##
plot(NULL, type="n", xlim=c(-1,1), ylim=c(-1,1), axes = FALSE, xlab = "", ylab = "")
rect(xleft = -1, ybottom = -0.5, xright =1, ytop = 0.5, lty = 1, col = "#DC267F")
text(0,0, "#DC267F")
##
plot(NULL, type="n", xlim=c(-1,1), ylim=c(-1,1), axes = FALSE, xlab = "", ylab = "")
rect(xleft = -1, ybottom = -0.5, xright =1, ytop = 0.5, lty = 1, col = "#FE6100")
text(0,0, "#FE6100")
##
plot(NULL, type="n", xlim=c(-1,1), ylim=c(-1,1), axes = FALSE, xlab = "", ylab = "")
rect(xleft = -1, ybottom = -0.5, xright =1, ytop = 0.5, lty = 1, col = "#FFB000")
text(0,0, "#FFB000")

par(mfrow=c(1,8), oma=c(0,0,0,0), mar = c(1,0.5,1,0.5))
plot(NULL, type="n", xlim=c(-1,1), ylim=c(-1,1), axes = FALSE, xlab = "", ylab = "")
rect(xleft = -1, ybottom = -0.5, xright =1, ytop = 0.5, lty = 1, col = "#000000")
text(0,0, "#000000", col = "white")
##
plot(NULL, type="n", xlim=c(-1,1), ylim=c(-1,1), axes = FALSE, xlab = "", ylab = "")
rect(xleft = -1, ybottom = -0.5, xright =1, ytop = 0.5, lty = 1, col = "#E69F00")
text(0,0, "#E69F00")
##
plot(NULL, type="n", xlim=c(-1,1), ylim=c(-1,1), axes = FALSE, xlab = "", ylab = "")
rect(xleft = -1, ybottom = -0.5, xright =1, ytop = 0.5, lty = 1, col = "#56B4E9")
text(0,0, "#56B4E9")
##
plot(NULL, type="n", xlim=c(-1,1), ylim=c(-1,1), axes = FALSE, xlab = "", ylab = "")
rect(xleft = -1, ybottom = -0.5, xright =1, ytop = 0.5, lty = 1, col = "#009E73")
text(0,0, "#009E73")
##
plot(NULL, type="n", xlim=c(-1,1), ylim=c(-1,1), axes = FALSE, xlab = "", ylab = "")
rect(xleft = -1, ybottom = -0.5, xright =1, ytop = 0.5, lty = 1, col = "#F0E442")
text(0,0, "#F0E442")
##
plot(NULL, type="n", xlim=c(-1,1), ylim=c(-1,1), axes = FALSE, xlab = "", ylab = "")
rect(xleft = -1, ybottom = -0.5, xright =1, ytop = 0.5, lty = 1, col = "#0072B2")
text(0,0, "#0072B2")
##
plot(NULL, type="n", xlim=c(-1,1), ylim=c(-1,1), axes = FALSE, xlab = "", ylab = "")
rect(xleft = -1, ybottom = -0.5, xright =1, ytop = 0.5, lty = 1, col = "#D55E00")
text(0,0, "#D55E00")
##
plot(NULL, type="n", xlim=c(-1,1), ylim=c(-1,1), axes = FALSE, xlab = "", ylab = "")
rect(xleft = -1, ybottom = -0.5, xright =1, ytop = 0.5, lty = 1, col = "#CC79A7")
text(0,0, "#CC79A7")

par(mfrow=c(1,8), oma=c(0,0,0,0), mar = c(1,0.5,1,0.5))
plot(NULL, type="n", xlim=c(-1,1), ylim=c(-1,1), axes = FALSE, xlab = "", ylab = "")
rect(xleft = -1, ybottom = -0.5, xright =1, ytop = 0.5, lty = 1, col = "#332288")
text(0,0, "#332288", col = "white")
##
plot(NULL, type="n", xlim=c(-1,1), ylim=c(-1,1), axes = FALSE, xlab = "", ylab = "")
rect(xleft = -1, ybottom = -0.5, xright =1, ytop = 0.5, lty = 1, col = "#117733")
text(0,0, "#117733")
##
plot(NULL, type="n", xlim=c(-1,1), ylim=c(-1,1), axes = FALSE, xlab = "", ylab = "")
rect(xleft = -1, ybottom = -0.5, xright =1, ytop = 0.5, lty = 1, col = "#44AA99")
text(0,0, "#44AA99")
##
plot(NULL, type="n", xlim=c(-1,1), ylim=c(-1,1), axes = FALSE, xlab = "", ylab = "")
rect(xleft = -1, ybottom = -0.5, xright =1, ytop = 0.5, lty = 1, col = "#88CCEE")
text(0,0, "#88CCEE")
##
plot(NULL, type="n", xlim=c(-1,1), ylim=c(-1,1), axes = FALSE, xlab = "", ylab = "")
rect(xleft = -1, ybottom = -0.5, xright =1, ytop = 0.5, lty = 1, col = "#DDCC77")
text(0,0, "#DDCC77")
##
plot(NULL, type="n", xlim=c(-1,1), ylim=c(-1,1), axes = FALSE, xlab = "", ylab = "")
rect(xleft = -1, ybottom = -0.5, xright =1, ytop = 0.5, lty = 1, col = "#CC6677")
text(0,0, "#CC6677")
##
plot(NULL, type="n", xlim=c(-1,1), ylim=c(-1,1), axes = FALSE, xlab = "", ylab = "")
rect(xleft = -1, ybottom = -0.5, xright =1, ytop = 0.5, lty = 1, col = "#AA4499")
text(0,0, "#AA4499")
##
plot(NULL, type="n", xlim=c(-1,1), ylim=c(-1,1), axes = FALSE, xlab = "", ylab = "")
rect(xleft = -1, ybottom = -0.5, xright =1, ytop = 0.5, lty = 1, col = "#882255")
text(0,0, "#882255", col = "white")

iris0 = iris
Type = c(paste(iris$Species,".Sepal.Length", sep = ""),paste(iris$Species,".Sepal.Width", sep = ""))
Measure = c(iris$Sepal.Length ,iris$Sepal.Width)
irisNew = data.frame(Type = Type, Measure = Measure)
cols1 = c("#332288","#117733","#44AA99","#88CCEE","#DDCC77","#CC6677")
cols3 = c("#AA4499","#882255")
ggplot() +
geom_density(data = irisNew, aes(x = Measure, color = Type), lwd = 1.5)+
scale_color_manual(values = cols1)

```{r, eval=FALSE}
iris0 = iris
Type = c(paste(iris$Species,".Sepal.Length", sep = ""),paste(iris$Species,".Sepal.Width", sep = ""))
Measure = c(iris$Sepal.Length ,iris$Sepal.Width)
irisNew = data.frame(Type = Type, Measure = Measure)
cols1 = c("#332288","#117733","#44AA99","#88CCEE","#DDCC77","#CC6677")
cols3 = c("#AA4499","#882255")
ggplot() +
geom_density(data = irisNew, aes(x = Measure, color = Type), lwd = 1.5)+
scale_color_manual(values = cols1)
```
LS0tDQp0aXRsZTogIlVzaW5nIENvbnRyYXN0IENvbG9ycyBmb3IgRGF0YSBWaXN1YWxpemF0aW9uIg0KYXV0aG9yOiAiQ2hlbmcgUGVuZyINCmRhdGU6ICJXZXN0IENoZXN0ZXIgVW5pdmVyc2l0eSAiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6IA0KICAgIHRvYzogeWVzDQogICAgdG9jX2RlcHRoOiA0DQogICAgdG9jX2Zsb2F0OiB5ZXMNCiAgICBmaWdfd2lkdGg6IDYNCiAgICBudW1iZXJfc2VjdGlvbnM6IHllcw0KICAgIHRvY19jb2xsYXBzZWQ6IHllcw0KICAgIGNvZGVfZm9sZGluZzogaGlkZQ0KICAgIGNvZGVfZG93bmxvYWQ6IHllcw0KICAgIHNtb290aF9zY3JvbGw6IHRydWUNCiAgICB0aGVtZTogcmVhZGFibGUNCiAgICBmaWdfaGVpZ2h0OiA0DQotLS0NCg0KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4NCg0KZGl2I1RPQyBsaSB7DQogICAgbGlzdC1zdHlsZTpub25lOw0KICAgIGJhY2tncm91bmQtY29sb3I6bGlnaHRncmF5Ow0KICAgIGJhY2tncm91bmQtaW1hZ2U6bm9uZTsNCiAgICBiYWNrZ3JvdW5kLXJlcGVhdDpub25lOw0KICAgIGJhY2tncm91bmQtcG9zaXRpb246MDsNCiAgICBmb250LWZhbWlseTogQXJpYWwsIEhlbHZldGljYSwgc2Fucy1zZXJpZjsNCiAgICBjb2xvcjogIzc4MGMwYzsNCn0NCg0KLyogbW91c2Ugb3ZlciBsaW5rICovDQpkaXYjVE9DIGE6aG92ZXIgew0KICBjb2xvcjogcmVkOw0KfQ0KDQovKiB1bnZpc2l0ZWQgbGluayAqLw0KZGl2I1RPQyBhOmxpbmsgew0KICBjb2xvcjogYmx1ZTsNCn0NCg0KDQoNCmgxLnRpdGxlIHsNCiAgZm9udC1zaXplOiAyNHB4Ow0KICBjb2xvcjogRGFya2JsdWU7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCiAgZm9udC1mYW1pbHk6IEFyaWFsLCBIZWx2ZXRpY2EsIHNhbnMtc2VyaWY7DQogIGZvbnQtdmFyaWFudC1jYXBzOiBub3JtYWw7DQp9DQpoNC5hdXRob3IgeyANCiAgICBmb250LXNpemU6IDE4cHg7DQogIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICBjb2xvcjogRGFya1JlZDsNCiAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KaDQuZGF0ZSB7IA0KICBmb250LXNpemU6IDE4cHg7DQogIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICBjb2xvcjogRGFya0JsdWU7DQogIHRleHQtYWxpZ246IGNlbnRlcjsNCn0NCmgxIHsNCiAgICBmb250LXNpemU6IDI0cHg7DQogICAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogICAgY29sb3I6IGRhcmtyZWQ7DQogICAgdGV4dC1hbGlnbjogY2VudGVyOw0KfQ0KaDIgew0KICAgIGZvbnQtc2l6ZTogMThweDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogbmF2eTsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQpoMyB7IA0KICAgIGZvbnQtc2l6ZTogMTVweDsNCiAgICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgICBjb2xvcjogbmF2eTsNCiAgICB0ZXh0LWFsaWduOiBsZWZ0Ow0KfQ0KDQpoNCB7IC8qIEhlYWRlciA0IC0gYW5kIHRoZSBhdXRob3IgYW5kIGRhdGEgaGVhZGVycyB1c2UgdGhpcyB0b28gICovDQogICAgZm9udC1zaXplOiAxOHB4Ow0KICAgIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICAgIGNvbG9yOiBkYXJrcmVkOw0KICAgIHRleHQtYWxpZ246IGxlZnQ7DQp9DQoNCi8qIHVudmlzaXRlZCBsaW5rICovDQphOmxpbmsgew0KICBjb2xvcjogZ3JlZW47DQp9DQoNCi8qIHZpc2l0ZWQgbGluayAqLw0KYTp2aXNpdGVkIHsNCiAgY29sb3I6IGdyZWVuOw0KfQ0KDQovKiBtb3VzZSBvdmVyIGxpbmsgKi8NCmE6aG92ZXIgew0KICBjb2xvcjogcmVkOw0KfQ0KDQovKiBzZWxlY3RlZCBsaW5rICovDQphOmFjdGl2ZSB7DQogIGNvbG9yOiB5ZWxsb3c7DQp9DQoNCnRhYmxlLCB0aCwgdGQgew0KICBib3JkZXI6IDFweCBzb2xpZCBibGFjazsNCiAgYm9yZGVyLWNvbGxhcHNlOiBjb2xsYXBzZTsNCn0NCnRoLCB0ZCB7DQogIHBhZGRpbmctdG9wOiAzcHg7DQogIHBhZGRpbmctYm90dG9tOiAzcHg7DQogIHBhZGRpbmctbGVmdDogMTBweDsNCiAgcGFkZGluZy1yaWdodDogMTBweDsNCn0NCg0KDQo8L3N0eWxlPg0KDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0KIyBjb2RlIGNodW5rIHNwZWNpZmllcyB3aGV0aGVyIHRoZSBSIGNvZGUsIHdhcm5pbmdzLCBhbmQgb3V0cHV0IA0KIyB3aWxsIGJlIGluY2x1ZGVkIGluIHRoZSBvdXRwdXQgZmlsZXMuDQpvcHRpb25zKHJlcG9zID0gbGlzdChDUkFOPSJodHRwOi8vY3Jhbi5yc3R1ZGlvLmNvbS8iKSkNCmlmICghcmVxdWlyZSgidGlkeXZlcnNlIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoInRpZHl2ZXJzZSIpDQogICBsaWJyYXJ5KHRpZHl2ZXJzZSkNCn0NCmlmICghcmVxdWlyZSgia25pdHIiKSkgew0KICAgaW5zdGFsbC5wYWNrYWdlcygia25pdHIiKQ0KICAgbGlicmFyeShrbml0cikNCn0NCmlmICghcmVxdWlyZSgiY293cGxvdCIpKSB7DQogICBpbnN0YWxsLnBhY2thZ2VzKCJjb3dwbG90IikNCiAgIGxpYnJhcnkoY293cGxvdCkNCn0NCmlmICghcmVxdWlyZSgibGF0ZXgyZXhwIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoImxhdGV4MmV4cCIpDQogICBsaWJyYXJ5KGxhdGV4MmV4cCkNCn0NCmlmICghcmVxdWlyZSgicGxvdGx5IikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoInBsb3RseSIpDQogICBsaWJyYXJ5KHBsb3RseSkNCn0NCmlmICghcmVxdWlyZSgiZ2FwbWluZGVyIikpIHsNCiAgIGluc3RhbGwucGFja2FnZXMoImdhcG1pbmRlciIpDQogICBsaWJyYXJ5KGdhcG1pbmRlcikNCn0NCmlmICghcmVxdWlyZSgicG5nIikpIHsNCiAgICBpbnN0YWxsLnBhY2thZ2VzKCJwbmciKSAgICAgICAgICAgICAjIEluc3RhbGwgcG5nIHBhY2thZ2UNCiAgICBsaWJyYXJ5KCJwbmciKQ0KfQ0KaWYgKCFyZXF1aXJlKCJSQ3VybCIpKSB7DQogICAgaW5zdGFsbC5wYWNrYWdlcygiUkN1cmwiKSAgICAgICAgICAgIyBJbnN0YWxsIFJDdXJsIHBhY2thZ2UNCiAgICBsaWJyYXJ5KCJSQ3VybCIpDQp9DQppZiAoIXJlcXVpcmUoImNvbG91cnBpY2tlciIpKSB7DQogICAgaW5zdGFsbC5wYWNrYWdlcygiY29sb3VycGlja2VyIikgICAgICAgICAgICAgIA0KICAgIGxpYnJhcnkoImNvbG91cnBpY2tlciIpDQp9DQppZiAoIXJlcXVpcmUoImdpZnNraSIpKSB7DQogICAgaW5zdGFsbC5wYWNrYWdlcygiZ2lmc2tpIikgICAgICAgICAgICAgIA0KICAgIGxpYnJhcnkoImdpZnNraSIpDQp9DQppZiAoIXJlcXVpcmUoIm1hZ2ljayIpKSB7DQogICAgaW5zdGFsbC5wYWNrYWdlcygibWFnaWNrIikgICAgICAgICAgICAgIA0KICAgIGxpYnJhcnkoIm1hZ2ljayIpDQp9DQppZiAoIXJlcXVpcmUoImdyRGV2aWNlcyIpKSB7DQogICAgaW5zdGFsbC5wYWNrYWdlcygiZ3JEZXZpY2VzIikgICAgICAgICAgICAgIA0KICAgIGxpYnJhcnkoImdyRGV2aWNlcyIpDQp9DQojIyMgZ2dwbG90IGFuZCBleHRlbnNpb25zDQppZiAoIXJlcXVpcmUoImdncGxvdDIiKSkgew0KICAgIGluc3RhbGwucGFja2FnZXMoImdncGxvdDIiKSAgICAgICAgICAgICAgDQogICAgbGlicmFyeSgiZ2dwbG90MiIpDQp9DQppZiAoIXJlcXVpcmUoImdnYW5pbWF0ZSIpKSB7DQogICAgaW5zdGFsbC5wYWNrYWdlcygiZ2dhbmltYXRlIikgICAgICAgICAgICAgIA0KICAgIGxpYnJhcnkoImdnYW5pbWF0ZSIpDQp9DQppZiAoIXJlcXVpcmUoImdncmlkZ2VzIikpIHsNCiAgICBpbnN0YWxsLnBhY2thZ2VzKCJnZ3JpZGdlcyIpICAgICAgICAgICAgICANCiAgICBsaWJyYXJ5KCJnZ3JpZGdlcyIpDQp9DQppZiAoIXJlcXVpcmUoInBsb3RyaXgiKSkgew0KICAgIGluc3RhbGwucGFja2FnZXMoInBsb3RyaXgiKSAgICAgICAgICAgICAgDQogICAgbGlicmFyeSgicGxvdHJpeCIpDQp9DQoNCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gVFJVRSwgICAgICAgDQogICAgICAgICAgICAgICAgICAgICAgd2FybmluZyA9IEZBTFNFLCAgIA0KICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IFRSVUUsICAgDQogICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IEZBTFNFKQ0KYGBgDQoNCg0KXA0KDQoNCiMgSW50cm9kdWN0aW9uDQoNCkRhdGEgdmlzdWFsaXphdGlvbiBiZWNvbWVzIG1vcmUgZWZmZWN0aXZlIHdoZW4gdGhlIGNvbG9ycyBhcmUgY2hvc2VuIGNhcmVmdWxseS4gSXQgaXMgY29udmVuaWVudCB0byBoYXZlIGNvbnZlbmllbnQgY29sb3Igc2NoZW1lcyByZWFkeSBmb3IgZGlmZmVyZW50IHR5cGVzIG9mIGRhdGEgdGhhdCBhcmUNCg0KKiBkaXN0aW5jdCBmb3IgYWxsIHBlb3BsZSwgaW5jbHVkaW5nIGNvbG9yLWJsaW5kIHJlYWRlcnM7DQoqIGRpc3RpbmN0IGZyb20gYmxhY2sgYW5kIHdoaXRlOw0KKiBkaXN0aW5jdCBvbiBzY3JlZW4gYW5kIHBhcGVyOw0KKiBtYXRjaGluZyB3ZWxsIHRvZ2V0aGVyLg0KDQpUaGlzIG5vdGUgZGlzY3Vzc2VzIGJyaWVmbHkgc3VjaCBjb2xvciBzY2hlbWVzLiBBIGNvbG9yIHNjaGVtZSBzaG91bGQgcmVmbGVjdCBlYWNoIG9mIHRoZSB0aHJlZSB0eXBlcyBvZiBkYXRhOg0KDQoqKlF1YWxpdGF0aXZlIGRhdGEqKiAtIG5vbWluYWwgb3IgY2F0ZWdvcmljYWwgZGF0YSwgd2hlcmUgbWFnbml0dWRlIGRpZmZlcmVuY2VzIGFyZSBub3QgcmVsZXZhbnQuIFRoaXMgaW5jbHVkZXMgbGluZXMgaW4gcGxvdHMgYW5kIHRleHQgaW4gcHJlc2VudGF0aW9ucy4NCg0KKipEaXZlcmdpbmcgZGF0YSoqIC0gZGF0YSBvcmRlcmVkIGJldHdlZW4gdHdvIGV4dHJlbWVzIHdoZXJlIHRoZSBtaWRwb2ludCBpcyBpbXBvcnRhbnQsIGUuZy4gcG9zaXRpdmUgYW5kIG5lZ2F0aXZlIGRldmlhdGlvbnMgZnJvbSB6ZXJvIG9yIGEgbWVhbi4NCg0KKipTZXF1ZW50aWFsIGRhdGEqKiAtIGRhdGEgb3JkZXJlZCBmcm9tIGxvdyB0byBoaWdoLg0KDQoNCg0KIyBRdWFsaXRhdGl2ZSBDb2xvciBTY2hlbWVzDQoNClRoZXJlIGFyZSBzZXZlcmFsIGNvbG9yIGJsaW5kIHNhZmUgY29sb3Igc2NoZW1lcyBmb3IgcXVhbGl0YXRpdmUgZGF0YS4gVGhlIGZvbGxvd2luZyBhcmUgc2hvcnQgbGlzdCBvZiB0aGVzZSBzdWdnZXN0ZWQgZGVmYXVsdCBzY2hlbWVzIGZvciBmdXJ0aGVyIG1vZGlmaWNhdGlvbnMuIFF1YWxpdGF0aXZlIGNvbG9yIHNjaGVtZXMgYXJlIHByb2JhYmx5IHRoZSBtb3N0IGltcG9ydGFudCBhbmQgdXNlZCBpbiBkYXRhIHZpc3VhbGl6YXRpb24uDQoNCiogKipCcmlnaHQgU2NoZW1lKioNCg0KVGhlIGJyaWdodCBxdWFsaXRhdGl2ZSBjb2xvciBzY2hlbWUgaXMgY29sb3ItYmxpbmQgc2FmZS4gVGhlIG1haW4gc2NoZW1lIGZvciBsaW5lcyBhbmQgdGhlaXIgbGFiZWxzLg0KDQoNCmBgYHtyIGZpZy5hbGlnbj0nY2VudGVyJ30NCnBhcihtZnJvdz1jKDIsNCkpDQpwbG90KDE6NSx0eXBlPSJuIiwgYXhlcyA9IEZBTFNFLCB4bGFiID0gIiIsIHlsYWIgPSAiIikNCmRyYXcuY2lyY2xlKDMsMywyLGNvbD0iIzQ0NzdBQSIpDQp0ZXh0KDMsMywgIiM0NDc3QUEiKQ0KIyMNCnBsb3QoMTo1LHR5cGU9Im4iLCBheGVzID0gRkFMU0UsIHhsYWIgPSAiIiwgeWxhYiA9ICIiKQ0KZHJhdy5jaXJjbGUoMywzLDIsY29sPSIjRUU2Njc3IikNCnRleHQoMywzLCAiI0VFNjY3NyIpDQojIw0KcGxvdCgxOjUsdHlwZT0ibiIsIGF4ZXMgPSBGQUxTRSwgeGxhYiA9ICIiLCB5bGFiID0gIiIpDQpkcmF3LmNpcmNsZSgzLDMsMixjb2w9IiMyMjg4MzMiKQ0KdGV4dCgzLDMsICIjMjI4ODMzIikNCiMjDQpwbG90KDE6NSx0eXBlPSJuIixheGVzID0gRkFMU0UsIHhsYWIgPSAiIiwgeWxhYiA9ICIiKQ0KZHJhdy5jaXJjbGUoMywzLDIsY29sPSIjQ0NCQjQ0IikNCnRleHQoMywzLCAiI0NDQkI0NCIpDQojIw0KcGxvdCgxOjUsdHlwZT0ibiIsIGF4ZXMgPSBGQUxTRSwgeGxhYiA9ICIiLCB5bGFiID0gIiIpDQpkcmF3LmNpcmNsZSgzLDMsMixjb2w9IiM2NkNDRUUiKQ0KdGV4dCgzLDMsICIjNjZDQ0VFIikNCiMjDQpwbG90KDE6NSx0eXBlPSJuIiwgYXhlcyA9IEZBTFNFLCB4bGFiID0gIiIsIHlsYWIgPSAiIikNCmRyYXcuY2lyY2xlKDMsMywyLGNvbD0iI0FBMzM3NyIpDQp0ZXh0KDMsMywgIiNBQTMzNzciKQ0KIyMNCnBsb3QoMTo1LHR5cGU9Im4iLCBheGVzID0gRkFMU0UsIHhsYWIgPSAiIiwgeWxhYiA9ICIiKQ0KZHJhdy5jaXJjbGUoMywzLDIsY29sPSIjQkJCQkJCIikNCnRleHQoMywzLCAiI0JCQkJCQiIpDQpgYGANCg0KDQoqICoqSGlnaC1jb250cmFzdCBTY2hlbWUqKg0KDQpIaWdoLWNvbnRyYXN0IHF1YWxpdGF0aXZlIGNvbG9yIHNjaGVtZSwgYW4gYWx0ZXJuYXRpdmUgdG8gdGhlIGJyaWdodCBzY2hlbWUgdGhhdCBpcyBjb2xvci1ibGluZCBzYWZlLCBhbmQgb3B0aW1pemVkIGZvciBjb250cmFzdC4gVGhlIHNhbXBsZXMgYmVsb3cgYXJlIHNoYWRlcyBvZiBncmV5IHdpdGggdGhlIHNhbWUgbHVtaW5lc2NlbmNlLiBUaGlzIHNjaGVtZSBhbHNvIHdvcmtzIHdlbGwgZm9yIHBlb3BsZSB3aXRoIG1vbm9jaHJvbWUgdmlzaW9uIGFuZCBpbiBhIG1vbm9jaHJvbWUgcHJpbnRvdXQuDQoNCmBgYHtyIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTV9DQpwYXIobWZyb3c9YygyLDMpKQ0KcGxvdCgxOjUsdHlwZT0ibiIsIGF4ZXMgPSBGQUxTRSwgeGxhYiA9ICIiLCB5bGFiID0gIiIsIGNleCA9IDAuOCkNCmRyYXcuY2lyY2xlKDMsMywyLGNvbD0iI0ZGRkZGRiIpDQp0ZXh0KDMsMywgIiNGRkZGRkYiKQ0KIyMNCnBsb3QoMTo1LHR5cGU9Im4iLCBheGVzID0gRkFMU0UsIHhsYWIgPSAiIiwgeWxhYiA9ICIiKQ0KZHJhdy5jaXJjbGUoMywzLDIsY29sPSIjMDA0NDg4IikNCnRleHQoMywzLCAiIzAwNDQ4OCIpDQojIw0KcGxvdCgxOjUsdHlwZT0ibiIsIGF4ZXMgPSBGQUxTRSwgeGxhYiA9ICIiLCB5bGFiID0gIiIpDQpkcmF3LmNpcmNsZSgzLDMsMixjb2w9IiNEREFBMzMiKQ0KdGV4dCgzLDMsICIjRERBQTMzIikNCiMjDQpwbG90KDE6NSx0eXBlPSJuIixheGVzID0gRkFMU0UsIHhsYWIgPSAiIiwgeWxhYiA9ICIiKQ0KZHJhdy5jaXJjbGUoMywzLDIsY29sPSIjQkI1NTY2IikNCnRleHQoMywzLCAiI0JCNTU2NiIpDQojIw0KcGxvdCgxOjUsdHlwZT0ibiIsIGF4ZXMgPSBGQUxTRSwgeGxhYiA9ICIiLCB5bGFiID0gIiIpDQpkcmF3LmNpcmNsZSgzLDMsMixjb2w9IiM2NkNDRUUiKQ0KdGV4dCgzLDMsICIjNjZDQ0VFIikNCiMjDQpwbG90KDE6NSx0eXBlPSJuIiwgYXhlcyA9IEZBTFNFLCB4bGFiID0gIiIsIHlsYWIgPSAiIikNCmRyYXcuY2lyY2xlKDMsMywyLGNvbD0iIzAwMDAwMCIpDQp0ZXh0KDMsMywgIiMwMDAwMDAiLCBjb2wgPSAiI0ZGRkZGRiIpDQpgYGANCg0KDQoqICoqVmlicmFudCBTY2hlbWUqKg0KDQoNCkEgdmlicmFudCBxdWFsaXRhdGl2ZSBjb2xvciBzY2hlbWUsIGFuIGFsdGVybmF0aXZlIHRvIHRoZSBicmlnaHQgc2NoZW1lIHRoYXQgaXMgZXF1YWxseSBjb2xvci1ibGluZCBzYWZlLiBJdCBoYXMgYmVlbiBkZXNpZ25lZCBmb3IgYSBkYXRhIHZpc3VhbGl6YXRpb24gZnJhbWV3b3JrLiANCg0KDQpgYGB7ciBmaWcuYWxpZ249J2NlbnRlcid9DQpwYXIobWZyb3c9YygyLDQpKQ0KcGxvdCgxOjUsdHlwZT0ibiIsIGF4ZXMgPSBGQUxTRSwgeGxhYiA9ICIiLCB5bGFiID0gIiIpDQpkcmF3LmNpcmNsZSgzLDMsMixjb2w9IiNFRTc3MzMiKQ0KdGV4dCgzLDMsICIjRUU3NzMzIikNCiMjDQpwbG90KDE6NSx0eXBlPSJuIiwgYXhlcyA9IEZBTFNFLCB4bGFiID0gIiIsIHlsYWIgPSAiIikNCmRyYXcuY2lyY2xlKDMsMywyLGNvbD0iIzAwNzdCQiIpDQp0ZXh0KDMsMywgIiMwMDc3QkIiKQ0KIyMNCnBsb3QoMTo1LHR5cGU9Im4iLCBheGVzID0gRkFMU0UsIHhsYWIgPSAiIiwgeWxhYiA9ICIiKQ0KZHJhdy5jaXJjbGUoMywzLDIsY29sPSIjMzNCQkVFIikNCnRleHQoMywzLCAiIzMzQkJFRSIpDQojIw0KcGxvdCgxOjUsdHlwZT0ibiIsYXhlcyA9IEZBTFNFLCB4bGFiID0gIiIsIHlsYWIgPSAiIikNCmRyYXcuY2lyY2xlKDMsMywyLGNvbD0iI0VFMzM3NyIpDQp0ZXh0KDMsMywgIiNFRTMzNzciKQ0KIyMNCnBsb3QoMTo1LHR5cGU9Im4iLCBheGVzID0gRkFMU0UsIHhsYWIgPSAiIiwgeWxhYiA9ICIiKQ0KZHJhdy5jaXJjbGUoMywzLDIsY29sPSIjQ0MzMzExIikNCnRleHQoMywzLCAiI0NDMzMxMSIpDQojIw0KcGxvdCgxOjUsdHlwZT0ibiIsIGF4ZXMgPSBGQUxTRSwgeGxhYiA9ICIiLCB5bGFiID0gIiIpDQpkcmF3LmNpcmNsZSgzLDMsMixjb2w9IiMwMDk5ODgiKQ0KdGV4dCgzLDMsICIjMDA5OTg4IikNCiMjDQpwbG90KDE6NSx0eXBlPSJuIiwgYXhlcyA9IEZBTFNFLCB4bGFiID0gIiIsIHlsYWIgPSAiIikNCmRyYXcuY2lyY2xlKDMsMywyLGNvbD0iI0JCQkJCQiIpDQp0ZXh0KDMsMywgIiNCQkJCQkIiKQ0KYGBgDQoNCg0KDQoqICoqTXV0ZWQgU2NoZW1lKioNCg0KTXV0ZWQgcXVhbGl0YXRpdmUgY29sb3Igc2NoZW1lLCBhbiBhbHRlcm5hdGl2ZSB0byB0aGUgYnJpZ2h0IHNjaGVtZSB0aGF0IGlzIGVxdWFsbHkgY29sb3ItYmxpbmQgc2FmZSB3aXRoIG1vcmUgY29sb3JzLCBidXQgbGFja2luZyBhIGNsZWFyIHJlZCBvciBtZWRpdW0gYmx1ZS4NCg0KDQpgYGB7ciBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD03LCBmaWcuaGVpZ2h0PTd9DQpwYXIobWZyb3c9YygzLDMpKQ0KDQpwbG90KDE6NSx0eXBlPSJuIiwgYXhlcyA9IEZBTFNFLCB4bGFiID0gIiIsIHlsYWIgPSAiIikNCmRyYXcuY2lyY2xlKDMsMywxLGNvbD0iI0NDNjY3NyIpDQp0ZXh0KDMsMywgIiNDQzY2NzciKQ0KIyMNCnBsb3QoMTo1LHR5cGU9Im4iLCBheGVzID0gRkFMU0UsIHhsYWIgPSAiIiwgeWxhYiA9ICIiKQ0KZHJhdy5jaXJjbGUoMywzLDEsY29sPSIjMzMyMjg4IikNCnRleHQoMywzLCAiIzMzMjI4OCIpDQojIw0KcGxvdCgxOjUsdHlwZT0ibiIsIGF4ZXMgPSBGQUxTRSwgeGxhYiA9ICIiLCB5bGFiID0gIiIpDQpkcmF3LmNpcmNsZSgzLDMsMSxjb2w9IiNERENDNzciKQ0KdGV4dCgzLDMsICIjRERDQzc3IikNCiMjDQpwbG90KDE6NSx0eXBlPSJuIixheGVzID0gRkFMU0UsIHhsYWIgPSAiIiwgeWxhYiA9ICIiKQ0KZHJhdy5jaXJjbGUoMywzLDEsY29sPSIjMTE3NzMzIikNCnRleHQoMywzLCAiIzExNzczMyIpDQojIw0KcGxvdCgxOjUsdHlwZT0ibiIsIGF4ZXMgPSBGQUxTRSwgeGxhYiA9ICIiLCB5bGFiID0gIiIpDQpkcmF3LmNpcmNsZSgzLDMsMSxjb2w9IiM4OENDRUUiKQ0KdGV4dCgzLDMsICIjODhDQ0VFIikNCiMjDQpwbG90KDE6NSx0eXBlPSJuIiwgYXhlcyA9IEZBTFNFLCB4bGFiID0gIiIsIHlsYWIgPSAiIikNCmRyYXcuY2lyY2xlKDMsMywxLGNvbD0iIzg4MjI1NSIpDQp0ZXh0KDMsMywgIiM4ODIyNTUiKQ0KIyMNCnBsb3QoMTo1LHR5cGU9Im4iLGF4ZXMgPSBGQUxTRSwgeGxhYiA9ICIiLCB5bGFiID0gIiIpDQpkcmF3LmNpcmNsZSgzLDMsMSxjb2w9IiM0NEFBOTkiKQ0KdGV4dCgzLDMsICIjNDRBQTk5IikNCiMjDQpwbG90KDE6NSx0eXBlPSJuIiwgYXhlcyA9IEZBTFNFLCB4bGFiID0gIiIsIHlsYWIgPSAiIikNCmRyYXcuY2lyY2xlKDMsMywxLGNvbD0iIzk5OTkzMyIpDQp0ZXh0KDMsMywgIiM5OTk5MzMiKQ0KIyMNCnBsb3QoMTo1LHR5cGU9Im4iLCBheGVzID0gRkFMU0UsIHhsYWIgPSAiIiwgeWxhYiA9ICIiKQ0KZHJhdy5jaXJjbGUoMywzLDEsY29sPSIjQUE0NDk5IikNCnRleHQoMywzLCAiI0FBNDQ5OSIpDQpgYGANCg0KDQoqICoqTWVkaXVtLWNvbnRyYXN0IFNjaGVtZSoqDQoNCk1lZGl1bS1jb250cmFzdCBxdWFsaXRhdGl2ZSBjb2xvciBzY2hlbWUsIGFuIGFsdGVybmF0aXZlIHRvIHRoZSBoaWdoLWNvbnRyYXN0IHNjaGVtZSB0aGF0IGlzIGNvbG9yLWJsaW5kIHNhZmUgd2l0aCBtb3JlIGNvbG9ycy4gSXQgaXMgYWxzbyBvcHRpbWl6ZWQgZm9yIGNvbnRyYXN0IHRvIHdvcmsgaW4gYSBtb25vY2hyb21lIHByaW50b3V0LCBidXQgdGhlIGRpZmZlcmVuY2VzIGFyZSBpbmV2aXRhYmx5IHNtYWxsZXIuIEl0IGlzIGRlc2lnbmVkIGZvciBzaXR1YXRpb25zIG5lZWRpbmcgY29sb3IgcGFpcnMsIHNob3duIGJ5IHRoZSB0aHJlZSByZWN0YW5nbGVzLCB3aXRoIHRoZSBsb3dlciBoYWxmIGluIHRoZSBncmV5LXNjYWxlIGVxdWl2YWxlbnQuDQoNCg0KYGBge3IgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9NywgZmlnLmhlaWdodD0xfQ0KcGFyKG1mcm93PWMoMSw1KSwgb21hPWMoMCwwLDAsMCksIG1hciA9IGMoMSwwLjUsMSwwLjUpKQ0KcGxvdChOVUxMLCB0eXBlPSJuIiwgeGxpbT1jKC0xLDEpLCB5bGltPWMoLTEsMSksIGF4ZXMgPSBGQUxTRSwgeGxhYiA9ICIiLCB5bGFiID0gIiIpDQpyZWN0KHhsZWZ0ID0gLTEsIHlib3R0b20gPSAtMC41LCB4cmlnaHQgPTEsIHl0b3AgPSAwLjUsIGx0eSA9IDEsIGNvbCA9ICIjNjQ4RkZGIikNCnRleHQoMCwwLCAiIzY0OEZGRiIpDQojIw0KcGxvdChOVUxMLCB0eXBlPSJuIiwgeGxpbT1jKC0xLDEpLCB5bGltPWMoLTEsMSksIGF4ZXMgPSBGQUxTRSwgeGxhYiA9ICIiLCB5bGFiID0gIiIpDQpyZWN0KHhsZWZ0ID0gLTEsIHlib3R0b20gPSAtMC41LCB4cmlnaHQgPTEsIHl0b3AgPSAwLjUsIGx0eSA9IDEsIGNvbCA9ICIjNzg1RUYwIikNCnRleHQoMCwwLCAiIzc4NUVGMCIpDQojIw0KcGxvdChOVUxMLCB0eXBlPSJuIiwgeGxpbT1jKC0xLDEpLCB5bGltPWMoLTEsMSksIGF4ZXMgPSBGQUxTRSwgeGxhYiA9ICIiLCB5bGFiID0gIiIpDQpyZWN0KHhsZWZ0ID0gLTEsIHlib3R0b20gPSAtMC41LCB4cmlnaHQgPTEsIHl0b3AgPSAwLjUsIGx0eSA9IDEsIGNvbCA9ICIjREMyNjdGIikNCnRleHQoMCwwLCAiI0RDMjY3RiIpDQojIw0KcGxvdChOVUxMLCB0eXBlPSJuIiwgeGxpbT1jKC0xLDEpLCB5bGltPWMoLTEsMSksIGF4ZXMgPSBGQUxTRSwgeGxhYiA9ICIiLCB5bGFiID0gIiIpDQpyZWN0KHhsZWZ0ID0gLTEsIHlib3R0b20gPSAtMC41LCB4cmlnaHQgPTEsIHl0b3AgPSAwLjUsIGx0eSA9IDEsIGNvbCA9ICIjRkU2MTAwIikNCnRleHQoMCwwLCAiI0ZFNjEwMCIpDQojIw0KcGxvdChOVUxMLCB0eXBlPSJuIiwgeGxpbT1jKC0xLDEpLCB5bGltPWMoLTEsMSksIGF4ZXMgPSBGQUxTRSwgeGxhYiA9ICIiLCB5bGFiID0gIiIpDQpyZWN0KHhsZWZ0ID0gLTEsIHlib3R0b20gPSAtMC41LCB4cmlnaHQgPTEsIHl0b3AgPSAwLjUsIGx0eSA9IDEsIGNvbCA9ICIjRkZCMDAwIikNCnRleHQoMCwwLCAiI0ZGQjAwMCIpDQpgYGANCg0KDQoNCmBgYHtyIGZpZy5hbGlnbj0nY2VudGVyJywgZmlnLndpZHRoPTcsIGZpZy5oZWlnaHQ9MX0NCnBhcihtZnJvdz1jKDEsOCksIG9tYT1jKDAsMCwwLDApLCBtYXIgPSBjKDEsMC41LDEsMC41KSkNCnBsb3QoTlVMTCwgdHlwZT0ibiIsIHhsaW09YygtMSwxKSwgeWxpbT1jKC0xLDEpLCBheGVzID0gRkFMU0UsIHhsYWIgPSAiIiwgeWxhYiA9ICIiKQ0KcmVjdCh4bGVmdCA9IC0xLCB5Ym90dG9tID0gLTAuNSwgeHJpZ2h0ID0xLCB5dG9wID0gMC41LCBsdHkgPSAxLCBjb2wgPSAiIzAwMDAwMCIpDQp0ZXh0KDAsMCwgIiMwMDAwMDAiLCBjb2wgPSAid2hpdGUiKQ0KIyMNCnBsb3QoTlVMTCwgdHlwZT0ibiIsIHhsaW09YygtMSwxKSwgeWxpbT1jKC0xLDEpLCBheGVzID0gRkFMU0UsIHhsYWIgPSAiIiwgeWxhYiA9ICIiKQ0KcmVjdCh4bGVmdCA9IC0xLCB5Ym90dG9tID0gLTAuNSwgeHJpZ2h0ID0xLCB5dG9wID0gMC41LCBsdHkgPSAxLCBjb2wgPSAiI0U2OUYwMCIpDQp0ZXh0KDAsMCwgIiNFNjlGMDAiKQ0KIyMNCnBsb3QoTlVMTCwgdHlwZT0ibiIsIHhsaW09YygtMSwxKSwgeWxpbT1jKC0xLDEpLCBheGVzID0gRkFMU0UsIHhsYWIgPSAiIiwgeWxhYiA9ICIiKQ0KcmVjdCh4bGVmdCA9IC0xLCB5Ym90dG9tID0gLTAuNSwgeHJpZ2h0ID0xLCB5dG9wID0gMC41LCBsdHkgPSAxLCBjb2wgPSAiIzU2QjRFOSIpDQp0ZXh0KDAsMCwgIiM1NkI0RTkiKQ0KIyMNCnBsb3QoTlVMTCwgdHlwZT0ibiIsIHhsaW09YygtMSwxKSwgeWxpbT1jKC0xLDEpLCBheGVzID0gRkFMU0UsIHhsYWIgPSAiIiwgeWxhYiA9ICIiKQ0KcmVjdCh4bGVmdCA9IC0xLCB5Ym90dG9tID0gLTAuNSwgeHJpZ2h0ID0xLCB5dG9wID0gMC41LCBsdHkgPSAxLCBjb2wgPSAiIzAwOUU3MyIpDQp0ZXh0KDAsMCwgIiMwMDlFNzMiKQ0KIyMNCnBsb3QoTlVMTCwgdHlwZT0ibiIsIHhsaW09YygtMSwxKSwgeWxpbT1jKC0xLDEpLCBheGVzID0gRkFMU0UsIHhsYWIgPSAiIiwgeWxhYiA9ICIiKQ0KcmVjdCh4bGVmdCA9IC0xLCB5Ym90dG9tID0gLTAuNSwgeHJpZ2h0ID0xLCB5dG9wID0gMC41LCBsdHkgPSAxLCBjb2wgPSAiI0YwRTQ0MiIpDQp0ZXh0KDAsMCwgIiNGMEU0NDIiKQ0KIyMNCnBsb3QoTlVMTCwgdHlwZT0ibiIsIHhsaW09YygtMSwxKSwgeWxpbT1jKC0xLDEpLCBheGVzID0gRkFMU0UsIHhsYWIgPSAiIiwgeWxhYiA9ICIiKQ0KcmVjdCh4bGVmdCA9IC0xLCB5Ym90dG9tID0gLTAuNSwgeHJpZ2h0ID0xLCB5dG9wID0gMC41LCBsdHkgPSAxLCBjb2wgPSAiIzAwNzJCMiIpDQp0ZXh0KDAsMCwgIiMwMDcyQjIiKQ0KIyMNCnBsb3QoTlVMTCwgdHlwZT0ibiIsIHhsaW09YygtMSwxKSwgeWxpbT1jKC0xLDEpLCBheGVzID0gRkFMU0UsIHhsYWIgPSAiIiwgeWxhYiA9ICIiKQ0KcmVjdCh4bGVmdCA9IC0xLCB5Ym90dG9tID0gLTAuNSwgeHJpZ2h0ID0xLCB5dG9wID0gMC41LCBsdHkgPSAxLCBjb2wgPSAiI0Q1NUUwMCIpDQp0ZXh0KDAsMCwgIiNENTVFMDAiKQ0KIyMNCnBsb3QoTlVMTCwgdHlwZT0ibiIsIHhsaW09YygtMSwxKSwgeWxpbT1jKC0xLDEpLCBheGVzID0gRkFMU0UsIHhsYWIgPSAiIiwgeWxhYiA9ICIiKQ0KcmVjdCh4bGVmdCA9IC0xLCB5Ym90dG9tID0gLTAuNSwgeHJpZ2h0ID0xLCB5dG9wID0gMC41LCBsdHkgPSAxLCBjb2wgPSAiI0NDNzlBNyIpDQp0ZXh0KDAsMCwgIiNDQzc5QTciKQ0KYGBgDQoNCg0KDQpgYGB7ciBmaWcuYWxpZ249J2NlbnRlcicsIGZpZy53aWR0aD03LCBmaWcuaGVpZ2h0PTF9DQpwYXIobWZyb3c9YygxLDgpLCBvbWE9YygwLDAsMCwwKSwgbWFyID0gYygxLDAuNSwxLDAuNSkpDQoNCnBsb3QoTlVMTCwgdHlwZT0ibiIsIHhsaW09YygtMSwxKSwgeWxpbT1jKC0xLDEpLCBheGVzID0gRkFMU0UsIHhsYWIgPSAiIiwgeWxhYiA9ICIiKQ0KcmVjdCh4bGVmdCA9IC0xLCB5Ym90dG9tID0gLTAuNSwgeHJpZ2h0ID0xLCB5dG9wID0gMC41LCBsdHkgPSAxLCBjb2wgPSAiIzMzMjI4OCIpDQp0ZXh0KDAsMCwgIiMzMzIyODgiLCBjb2wgPSAid2hpdGUiKQ0KIyMNCnBsb3QoTlVMTCwgdHlwZT0ibiIsIHhsaW09YygtMSwxKSwgeWxpbT1jKC0xLDEpLCBheGVzID0gRkFMU0UsIHhsYWIgPSAiIiwgeWxhYiA9ICIiKQ0KcmVjdCh4bGVmdCA9IC0xLCB5Ym90dG9tID0gLTAuNSwgeHJpZ2h0ID0xLCB5dG9wID0gMC41LCBsdHkgPSAxLCBjb2wgPSAiIzExNzczMyIpDQp0ZXh0KDAsMCwgIiMxMTc3MzMiKQ0KIyMNCnBsb3QoTlVMTCwgdHlwZT0ibiIsIHhsaW09YygtMSwxKSwgeWxpbT1jKC0xLDEpLCBheGVzID0gRkFMU0UsIHhsYWIgPSAiIiwgeWxhYiA9ICIiKQ0KcmVjdCh4bGVmdCA9IC0xLCB5Ym90dG9tID0gLTAuNSwgeHJpZ2h0ID0xLCB5dG9wID0gMC41LCBsdHkgPSAxLCBjb2wgPSAiIzQ0QUE5OSIpDQp0ZXh0KDAsMCwgIiM0NEFBOTkiKQ0KIyMNCnBsb3QoTlVMTCwgdHlwZT0ibiIsIHhsaW09YygtMSwxKSwgeWxpbT1jKC0xLDEpLCBheGVzID0gRkFMU0UsIHhsYWIgPSAiIiwgeWxhYiA9ICIiKQ0KcmVjdCh4bGVmdCA9IC0xLCB5Ym90dG9tID0gLTAuNSwgeHJpZ2h0ID0xLCB5dG9wID0gMC41LCBsdHkgPSAxLCBjb2wgPSAiIzg4Q0NFRSIpDQp0ZXh0KDAsMCwgIiM4OENDRUUiKQ0KIyMNCnBsb3QoTlVMTCwgdHlwZT0ibiIsIHhsaW09YygtMSwxKSwgeWxpbT1jKC0xLDEpLCBheGVzID0gRkFMU0UsIHhsYWIgPSAiIiwgeWxhYiA9ICIiKQ0KcmVjdCh4bGVmdCA9IC0xLCB5Ym90dG9tID0gLTAuNSwgeHJpZ2h0ID0xLCB5dG9wID0gMC41LCBsdHkgPSAxLCBjb2wgPSAiI0REQ0M3NyIpDQp0ZXh0KDAsMCwgIiNERENDNzciKQ0KIyMNCnBsb3QoTlVMTCwgdHlwZT0ibiIsIHhsaW09YygtMSwxKSwgeWxpbT1jKC0xLDEpLCBheGVzID0gRkFMU0UsIHhsYWIgPSAiIiwgeWxhYiA9ICIiKQ0KcmVjdCh4bGVmdCA9IC0xLCB5Ym90dG9tID0gLTAuNSwgeHJpZ2h0ID0xLCB5dG9wID0gMC41LCBsdHkgPSAxLCBjb2wgPSAiI0NDNjY3NyIpDQp0ZXh0KDAsMCwgIiNDQzY2NzciKQ0KIyMNCnBsb3QoTlVMTCwgdHlwZT0ibiIsIHhsaW09YygtMSwxKSwgeWxpbT1jKC0xLDEpLCBheGVzID0gRkFMU0UsIHhsYWIgPSAiIiwgeWxhYiA9ICIiKQ0KcmVjdCh4bGVmdCA9IC0xLCB5Ym90dG9tID0gLTAuNSwgeHJpZ2h0ID0xLCB5dG9wID0gMC41LCBsdHkgPSAxLCBjb2wgPSAiI0FBNDQ5OSIpDQp0ZXh0KDAsMCwgIiNBQTQ0OTkiKQ0KIyMNCnBsb3QoTlVMTCwgdHlwZT0ibiIsIHhsaW09YygtMSwxKSwgeWxpbT1jKC0xLDEpLCBheGVzID0gRkFMU0UsIHhsYWIgPSAiIiwgeWxhYiA9ICIiKQ0KcmVjdCh4bGVmdCA9IC0xLCB5Ym90dG9tID0gLTAuNSwgeHJpZ2h0ID0xLCB5dG9wID0gMC41LCBsdHkgPSAxLCBjb2wgPSAiIzg4MjI1NSIpDQp0ZXh0KDAsMCwgIiM4ODIyNTUiLCBjb2wgPSAid2hpdGUiKQ0KYGBgDQoNCg0KYGBge3IgZmlnLmFsaWduPSdjZW50ZXInLCBmaWcud2lkdGg9NiwgZmlnLmhlaWdodD00fQ0KaXJpczAgPSBpcmlzDQpUeXBlID0gYyhwYXN0ZShpcmlzJFNwZWNpZXMsIi5TZXBhbC5MZW5ndGgiLCBzZXAgPSAiIikscGFzdGUoaXJpcyRTcGVjaWVzLCIuU2VwYWwuV2lkdGgiLCBzZXAgPSAiIikpDQpNZWFzdXJlID0gYyhpcmlzJFNlcGFsLkxlbmd0aCAsaXJpcyRTZXBhbC5XaWR0aCkNCmlyaXNOZXcgPSBkYXRhLmZyYW1lKFR5cGUgPSBUeXBlLCBNZWFzdXJlID0gTWVhc3VyZSkNCmNvbHMxID0gYygiIzMzMjI4OCIsIiMxMTc3MzMiLCIjNDRBQTk5IiwiIzg4Q0NFRSIsIiNERENDNzciLCIjQ0M2Njc3IikNCmNvbHMzID0gYygiI0FBNDQ5OSIsIiM4ODIyNTUiKQ0KZ2dwbG90KCkgKyANCiAgICAgIGdlb21fZGVuc2l0eShkYXRhID0gaXJpc05ldywgYWVzKHggPSBNZWFzdXJlLCBjb2xvciA9IFR5cGUpLCBsd2QgPSAxLjUpKyANCiAgICAgIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjb2xzMSkgDQpgYGANCg0KDQoNCg0KYGBgYHt2ZXJiYXRpbX0NCmBgYHtyLCBldmFsPUZBTFNFfQ0KaXJpczAgPSBpcmlzDQpUeXBlID0gYyhwYXN0ZShpcmlzJFNwZWNpZXMsIi5TZXBhbC5MZW5ndGgiLCBzZXAgPSAiIikscGFzdGUoaXJpcyRTcGVjaWVzLCIuU2VwYWwuV2lkdGgiLCBzZXAgPSAiIikpDQpNZWFzdXJlID0gYyhpcmlzJFNlcGFsLkxlbmd0aCAsaXJpcyRTZXBhbC5XaWR0aCkNCmlyaXNOZXcgPSBkYXRhLmZyYW1lKFR5cGUgPSBUeXBlLCBNZWFzdXJlID0gTWVhc3VyZSkNCmNvbHMxID0gYygiIzMzMjI4OCIsIiMxMTc3MzMiLCIjNDRBQTk5IiwiIzg4Q0NFRSIsIiNERENDNzciLCIjQ0M2Njc3IikNCmNvbHMzID0gYygiI0FBNDQ5OSIsIiM4ODIyNTUiKQ0KZ2dwbG90KCkgKyANCiAgICAgIGdlb21fZGVuc2l0eShkYXRhID0gaXJpc05ldywgYWVzKHggPSBNZWFzdXJlLCBjb2xvciA9IFR5cGUpLCBsd2QgPSAxLjUpKyANCiAgICAgIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjb2xzMSkgDQpgYGANCmBgYGANCg0KDQoNCg0KDQoNCg0KDQoNCg0K