Install library using install.packages("ggplot2")
Import ggplot2 and dplyr library:
> library("ggplot2")
> library("dplyr")
Loading the data set and do some changes to make it usable -
> college <- read.csv('Data/college.csv')
> college <- college %>%
+ mutate(state=as.factor(state), region=as.factor(region),
+ highest_degree=as.factor(highest_degree),
+ control=as.factor(control), gender=as.factor(gender),
+ loan_default_rate=as.numeric(loan_default_rate))
Calling ggplot() alone just creates a blank plot -
> ggplot()

Tell ggplot what data to use -
> ggplot(data=college) +
+ geom_point(mapping = aes(x=tuition, y=sat_avg))

The same scatter plot can also be made using qplot which stands for quick plot -
> qplot(data= college, x=tuition, y=sat_avg)

Shape
Let’s try representing a different dimension. What if we want to differentiate public vs. private schools? We can do this using the shape attribute -
> ggplot(data=college) +
+ geom_point(mapping=aes(x=tuition, y=sat_avg,
+ shape=control))

Using qplot -
> qplot(data = college, x = tuition, y = sat_avg,
+ shape = control)

Color
What if we try color instead of shape to view different categories?
> ggplot(data = college) +
+ geom_point(mapping = aes(x = tuition, y = sat_avg,
+ color = control))

Using qplot -
> qplot(data = college, x = tuition, y = sat_avg,
+ color = control)

Using RStudio Addin for coloring
View this link for details on how to install and use this.
> CPCOLS <- c("#8B0A50", "#9A32CD")
>
> ggplot(data = college) +
+ geom_point(mapping = aes(x = tuition, y = sat_avg,
+ color = control))+
+ scale_color_manual(values=CPCOLS)

Point size
Let’s alter the size of pointers in accordance to the number of undergraduates in each points -
> ggplot(data = college) +
+ geom_point(mapping = aes(x = tuition, y = sat_avg,
+ color = control, size = undergrads))

Using qplot -
> qplot(data = college, x = tuition, y = sat_avg,
+ color = control, size = undergrads)

Alpha - transparency
To add some transparency so we can see through those points -
> ggplot(data = college) +
+ geom_point(mapping = aes(x = tuition, y = sat_avg,
+ color = control, size = undergrads),
+ alpha = 0.35)

Using qplot -
> qplot(data = college, x = tuition, y = sat_avg,
+ color = control, size = undergrads,alpha=I(0.35)) # manually setting alpha = I(n) -- 0<n<1

Title and Subtitle
Add title and subtitle using the ggtitle -
> ggplot(data = college) +
+ geom_point(mapping = aes(x = tuition, y = sat_avg,
+ color = control, size = undergrads),
+ alpha = 0.35) +
+ ggtitle("SAT Average score VS Tuition Fee",
+ subtitle = "A comparison study")

Alternatively -
> ggplot(data = college) +
+ geom_point(mapping = aes(x = tuition, y = sat_avg,
+ color = control, size = undergrads),
+ alpha = 0.35) +
+ labs(title = "SAT Average score VS Tuition Fee",
+ subtitle = "A comparison study")

Axis labels
> ggplot(data = college) +
+ geom_point(mapping = aes(x = tuition, y = sat_avg,
+ color = control, size = undergrads),
+ alpha = 0.35) +
+ xlab("Tuition Fees")+
+ ylab("SAT Average Score")

Alternatively using labs -
> ggplot(data = college) +
+ geom_point(mapping = aes(x = tuition, y = sat_avg,
+ color = control, size = undergrads),
+ alpha = 0.35) +
+ labs(x = "Tuition Fees", y = "SAT Average Score",
+ title = "SAT Average score VS Tuition Fee",
+ subtitle = "A comparison study")

To plot the title in middle -
> ggplot(data = college) +
+ geom_point(mapping = aes(x = tuition, y = sat_avg,
+ color = control, size = undergrads),
+ alpha = 0.35) +
+ labs(x = "Tuition Fees", y = "SAT Average Score",
+ title = "SAT Average score VS Tuition Fee",
+ subtitle = "A comparison study") +
+ theme(plot.title = element_text(hjust = 0.5))

Axis limit
Using xlim and ylim -
> ggplot(data = college) +
+ geom_point(mapping = aes(x = tuition, y = sat_avg,
+ color = control, size = undergrads),
+ alpha = 0.35) +
+ labs(x = "Tuition Fees", y = "SAT Average Score",
+ title = "SAT Average score VS Tuition Fee",
+ subtitle = "A comparison study")+
+ xlim(0,55000)+ylim(500,1800)

expand_limits doesn’t cut values from the plot -
> ggplot(data = college) +
+ geom_point(mapping = aes(x = tuition, y = sat_avg,
+ color = control, size = undergrads),
+ alpha = 0.35) +
+ labs(x = "Tuition Fees", y = "SAT Average Score",
+ title = "SAT Average score VS Tuition Fee",
+ subtitle = "A comparison study")+
+ expand_limits(x=c(0,55000),y=c(1500,2000))

Caption
The caption appears in the bottom-right, and is often used for sources, notes or copyright -
> ggplot(data = college) +
+ geom_point(mapping = aes(x = tuition, y = sat_avg,
+ color = control, size = undergrads),
+ alpha = 0.35) +
+ labs(x = "Tuition Fees", y = "SAT Average Score",
+ title = "SAT Average score VS Tuition Fee",
+ caption = "Source: U.S. Department of Education")

Tag
The plot tag appears at the top-left, and is typically used for labelling a subplot with a letter -
> ggplot(data = college) +
+ geom_point(mapping = aes(x = tuition, y = sat_avg,
+ color = control, size = undergrads),
+ alpha = 0.35) +
+ labs(x = "Tuition Fees", y = "SAT Average Score",
+ title = "SAT Average score VS Tuition Fee",
+ subtitle = "A comparison study",
+ caption = "Source: U.S. Department of Education",
+ tag = "A")

Changing background color
plot.background changes the color of background of plot and panel.backgrund changes the color of background of panel-
> ggplot(data = college) +
+ geom_point(mapping = aes(x = tuition, y = sat_avg,
+ color = control, size = undergrads),
+ alpha = 0.35) +
+ labs(x = "Tuition Fees", y = "SAT Average Score",
+ title = "SAT Average score VS Tuition Fee",
+ subtitle = "A comparison study",
+ caption = "Source: U.S. Department of Education",
+ tag = "A")+
+ theme(plot.background = element_rect(fill='darkseagreen'))

> ggplot(data = college) +
+ geom_point(mapping = aes(x = tuition, y = sat_avg,
+ color = control, size = undergrads),
+ alpha = 0.35) +
+ labs(x = "Tuition Fees", y = "SAT Average Score",
+ title = "SAT Average score VS Tuition Fee",
+ subtitle = "A comparison study",
+ caption = "Source: U.S. Department of Education",
+ tag = "A")+
+ theme(panel.background = element_rect(fill='azure1'))

> ggplot(data = college) +
+ geom_point(mapping = aes(x = tuition, y = sat_avg,
+ color = control, size = undergrads),
+ alpha = 0.35) +
+ labs(x = "Tuition Fees", y = "SAT Average Score",
+ title = "SAT Average score VS Tuition Fee",
+ subtitle = "A comparison study",
+ caption = "Source: U.S. Department of Education",
+ tag = "A")+
+ theme(panel.background = element_rect(fill='azure1'),
+ plot.background = element_rect(fill='azure1'))

Use element_blank() to remove all grids and colors from background -
> ggplot(data = college) +
+ geom_point(mapping = aes(x = tuition, y = sat_avg,
+ color = control, size = undergrads),
+ alpha = 0.35) +
+ labs(x = "Tuition Fees", y = "SAT Average Score",
+ title = "SAT Average score VS Tuition Fee")+
+ theme(panel.background = element_blank())

Using Predefined Themes
List of themes: * theme_bw() * theme_minimal() * theme_linedraw() * theme_light() * theme_dark() * theme_classic() * theme_void() * theme_test()
Using classic theme -
> ggplot(data = college) +
+ geom_point(mapping = aes(x = tuition, y = sat_avg,
+ color = control, size = undergrads),
+ alpha = 0.35) +
+ labs(x = "Tuition Fees", y = "SAT Average Score",
+ title = "SAT Average score VS Tuition Fee") +
+ theme_classic()

Using minimal theme -
> ggplot(data = college) +
+ geom_point(mapping = aes(x = tuition, y = sat_avg,
+ color = control, size = undergrads),
+ alpha = 0.35) +
+ labs(x = "Tuition Fees", y = "SAT Average Score",
+ title = "SAT Average score VS Tuition Fee") +
+ theme_minimal()

Using dark theme -
> ggplot(data = college) +
+ geom_point(mapping = aes(x = tuition, y = sat_avg,
+ color = control, size = undergrads),
+ alpha = 0.35) +
+ labs(x = "Tuition Fees", y = "SAT Average Score",
+ title = "SAT Average score VS Tuition Fee") +
+ theme_dark()

More themes can be found from the package ggthemes. Load the package -
> library(ggthemes)
Details on the themes can be found here.
Using the theme solarized -
> ggplot(data = college) +
+ geom_point(mapping = aes(x = tuition, y = sat_avg,
+ color = control, size = undergrads),
+ alpha = 0.35) +
+ labs(x = "Tuition Fees", y = "SAT Average Score",
+ title = "SAT Average score VS Tuition Fee") +
+ theme_solarized()

Axis grids
Showing both grids in a single color using panel.grid.major -
> ggplot(data = college) +
+ geom_point(mapping = aes(x = tuition, y = sat_avg,
+ color = control, size = undergrads),
+ alpha = 0.35) +
+ labs(x = "Tuition Fees", y = "SAT Average Score",
+ title = "SAT Average score VS Tuition Fee")+
+ theme(panel.background = element_blank(),
+ panel.grid.major = element_line("grey"))

Showing only X axis grid using panel.grid.major.x-
> ggplot(data = college) +
+ geom_point(mapping = aes(x = tuition, y = sat_avg,
+ color = control, size = undergrads),
+ alpha = 0.35) +
+ labs(x = "Tuition Fees", y = "SAT Average Score",
+ title = "SAT Average score VS Tuition Fee")+
+ theme(panel.background = element_blank(),
+ panel.grid.major.x = element_line("grey"))

Similarly Y axis grid -
> ggplot(data = college) +
+ geom_point(mapping = aes(x = tuition, y = sat_avg,
+ color = control, size = undergrads),
+ alpha = 0.35) +
+ labs(x = "Tuition Fees", y = "SAT Average Score",
+ title = "SAT Average score VS Tuition Fee")+
+ theme(panel.background = element_blank(),
+ panel.grid.major.y = element_line("grey"))

To hide grids use element_blank() -
> ggplot(data = college) +
+ geom_point(mapping = aes(x = tuition, y = sat_avg,
+ color = control, size = undergrads),
+ alpha = 0.35) +
+ labs(x = "Tuition Fees", y = "SAT Average Score",
+ title = "SAT Average score VS Tuition Fee")+
+ theme(panel.background = element_blank(),
+ panel.grid.major = element_blank())

Legend Customization
Changing Legend Titles
> ggplot(data = college) +
+ geom_point(mapping = aes(x = tuition, y = sat_avg,
+ color = control, size = undergrads),
+ alpha = 0.35) +
+ labs(x = "Tuition Fees",
+ y = "SAT Average Score",
+ title = "SAT Average score VS Tuition Fee",
+ size="No. of students",
+ color="Institution Type")

Legend position
Can take values - right, left, bottom, top, none.
Example -
> ggplot(data = college) +
+ geom_point(mapping = aes(x = tuition, y = sat_avg,
+ color = control, size = undergrads),
+ alpha = 0.35) +
+ labs(x = "Tuition Fees",
+ y = "SAT Average Score",
+ title = "SAT Average score VS Tuition Fee")+
+ theme(legend.position = "left")

legend.position = "none" to hide the legend-
> ggplot(data = college) +
+ geom_point(mapping = aes(x = tuition, y = sat_avg,
+ color = control, size = undergrads),
+ alpha = 0.35) +
+ labs(x = "Tuition Fees",
+ y = "SAT Average Score",
+ title = "SAT Average score VS Tuition Fee")+
+ theme(legend.position = "none")

Legend title
To hide the legend title -
> ggplot(data = college) +
+ geom_point(mapping = aes(x = tuition, y = sat_avg,
+ color = control, size = undergrads),
+ alpha = 0.35) +
+ labs(x = "Tuition Fees",
+ y = "SAT Average Score",
+ title = "SAT Average score VS Tuition Fee")+
+ theme(legend.title = element_blank())

Legend Direction
Layout of items in legends (“horizontal” or “vertical”)
> ggplot(data = college) +
+ geom_point(mapping = aes(x = tuition, y = sat_avg,
+ color = control, size = undergrads),
+ alpha = 0.35) +
+ labs(x = "Tuition Fees",
+ y = "SAT Average Score",
+ title = "SAT Average score VS Tuition Fee")+
+ theme(legend.direction = "vertical",
+ legend.position = "top")

Legend Box Positioning
Using legend.box -
> ggplot(data = college) +
+ geom_point(mapping = aes(x = tuition, y = sat_avg,
+ color = control, size = undergrads),
+ alpha = 0.35) +
+ labs(x = "Tuition Fees",
+ y = "SAT Average Score",
+ title = "SAT Average score VS Tuition Fee")+
+ theme(legend.position = "top",
+ legend.box = "vertical")

To alight the legend box to left, right or center use legend.box.just -
> ggplot(data = college) +
+ geom_point(mapping = aes(x = tuition, y = sat_avg,
+ color = control, size = undergrads),
+ alpha = 0.35) +
+ labs(x = "Tuition Fees",
+ y = "SAT Average Score",
+ title = "SAT Average score VS Tuition Fee")+
+ theme(legend.position = "top",
+ legend.box = "vertical",
+ legend.box.just = "right")

Special thanks to Mike Chappel for his course in Lynda on ggplot2.
Check out https://www.homeworkhelponline.net for R Studio Programming assignment help.
LS0tDQp0aXRsZTogImdncGxvdDIgLSBzY2F0dGVyIHBsb3QiDQphdXRob3I6ICdNRCBBSFNBTlVMIElTTEFNJw0Kb3V0cHV0OiANCiAgaHRtbF9kb2N1bWVudDoNCiAgICB0b2M6IHRydWUNCiAgICB0b2NfZmxvYXQ6IHRydWUNCiAgICB0b2NfZGVwdGg6IDQNCiAgICB0aGVtZTogY2VydWxlYW4NCiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlDQp0b2MtdGl0bGU6ICJUYWJsZSBvZiBjb250ZW50Ig0KLS0tDQoNCmBgYHtyLCBpbmNsdWRlPUZBTFNFfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KA0KICBjb21tZW50ID0gIiIsIHByb21wdCA9IFRSVUUsIG1lc3NhZ2U9Riwgd2FybmluZyA9IEYNCikNCmBgYA0KLS0tDQoNCkluc3RhbGwgbGlicmFyeSB1c2luZyBgaW5zdGFsbC5wYWNrYWdlcygiZ2dwbG90MiIpYCAgIA0KSW1wb3J0IGdncGxvdDIgYW5kIGRwbHlyIGxpYnJhcnk6DQpgYGB7ciB3YXJuaW5nPUZ9DQpsaWJyYXJ5KCJnZ3Bsb3QyIikNCmxpYnJhcnkoImRwbHlyIikNCmBgYA0KDQpMb2FkaW5nIHRoZSBkYXRhIHNldCBhbmQgZG8gc29tZSBjaGFuZ2VzIHRvIG1ha2UgaXQgdXNhYmxlIC0gDQpgYGB7cn0NCmNvbGxlZ2UgPC0gcmVhZC5jc3YoJ0RhdGEvY29sbGVnZS5jc3YnKQ0KY29sbGVnZSA8LSBjb2xsZWdlICU+JQ0KICBtdXRhdGUoc3RhdGU9YXMuZmFjdG9yKHN0YXRlKSwgcmVnaW9uPWFzLmZhY3RvcihyZWdpb24pLA0KICAgICAgICAgaGlnaGVzdF9kZWdyZWU9YXMuZmFjdG9yKGhpZ2hlc3RfZGVncmVlKSwNCiAgICAgICAgIGNvbnRyb2w9YXMuZmFjdG9yKGNvbnRyb2wpLCBnZW5kZXI9YXMuZmFjdG9yKGdlbmRlciksDQogICAgICAgICBsb2FuX2RlZmF1bHRfcmF0ZT1hcy5udW1lcmljKGxvYW5fZGVmYXVsdF9yYXRlKSkNCmBgYA0KDQotLS0NCg0KQ2FsbGluZyBnZ3Bsb3QoKSBhbG9uZSBqdXN0IGNyZWF0ZXMgYSBibGFuayBwbG90IC0NCmBgYHtyfQ0KZ2dwbG90KCkNCmBgYA0KDQpUZWxsIGdncGxvdCB3aGF0IGRhdGEgdG8gdXNlIC0NCmBgYHtyfQ0KZ2dwbG90KGRhdGE9Y29sbGVnZSkgKw0KICBnZW9tX3BvaW50KG1hcHBpbmcgPSBhZXMoeD10dWl0aW9uLCB5PXNhdF9hdmcpKQ0KYGBgDQoNClRoZSBzYW1lIHNjYXR0ZXIgcGxvdCBjYW4gYWxzbyBiZSBtYWRlIHVzaW5nIGBxcGxvdGAgd2hpY2ggc3RhbmRzIGZvciBxdWljayBwbG90IC0gDQpgYGB7cn0NCnFwbG90KGRhdGE9IGNvbGxlZ2UsIHg9dHVpdGlvbiwgeT1zYXRfYXZnKQ0KYGBgDQoNCi0tLQ0KDQojIyMgU2hhcGUgICANCg0KTGV0J3MgdHJ5IHJlcHJlc2VudGluZyBhIGRpZmZlcmVudCBkaW1lbnNpb24uIFdoYXQgaWYgd2Ugd2FudCB0byBkaWZmZXJlbnRpYXRlIHB1YmxpYyB2cy4gcHJpdmF0ZSBzY2hvb2xzPw0KV2UgY2FuIGRvIHRoaXMgdXNpbmcgdGhlIHNoYXBlIGF0dHJpYnV0ZSAtIA0KYGBge3J9DQpnZ3Bsb3QoZGF0YT1jb2xsZWdlKSArDQogIGdlb21fcG9pbnQobWFwcGluZz1hZXMoeD10dWl0aW9uLCB5PXNhdF9hdmcsIA0KICAgICAgICAgICAgICAgICAgICAgICAgIHNoYXBlPWNvbnRyb2wpKQ0KYGBgDQoNClVzaW5nIGBxcGxvdGAgLSANCmBgYHtyfQ0KcXBsb3QoZGF0YSA9IGNvbGxlZ2UsIHggPSB0dWl0aW9uLCB5ID0gc2F0X2F2ZywgDQogICAgICBzaGFwZSA9IGNvbnRyb2wpDQpgYGANCg0KLS0tDQoNCiMjIyBDb2xvciAgIA0KDQpXaGF0IGlmIHdlIHRyeSBjb2xvciBpbnN0ZWFkIG9mIHNoYXBlIHRvIHZpZXcgZGlmZmVyZW50IGNhdGVnb3JpZXM/DQpgYGB7cn0NCmdncGxvdChkYXRhID0gY29sbGVnZSkgKw0KICBnZW9tX3BvaW50KG1hcHBpbmcgPSBhZXMoeCA9IHR1aXRpb24sIHkgPSBzYXRfYXZnLCANCiAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9IGNvbnRyb2wpKQ0KYGBgDQoNClVzaW5nIGBxcGxvdGAgLSANCmBgYHtyfQ0KcXBsb3QoZGF0YSA9IGNvbGxlZ2UsIHggPSB0dWl0aW9uLCB5ID0gc2F0X2F2ZywgDQogICAgICBjb2xvciA9IGNvbnRyb2wpDQpgYGANCg0KIyMjIyBVc2luZyBSU3R1ZGlvIEFkZGluIGZvciBjb2xvcmluZw0KDQpWaWV3IHRoaXMgW2xpbmtdKGh0dHBzOi8vZ2l0aHViLmNvbS9kYWF0dGFsaS9jb2xvdXJwaWNrZXIpIGZvciBkZXRhaWxzIG9uIGhvdyB0byBpbnN0YWxsIGFuZCB1c2UgdGhpcy4NCg0KYGBge3J9DQpDUENPTFMgPC0gYygiIzhCMEE1MCIsICIjOUEzMkNEIikNCg0KZ2dwbG90KGRhdGEgPSBjb2xsZWdlKSArDQogIGdlb21fcG9pbnQobWFwcGluZyA9IGFlcyh4ID0gdHVpdGlvbiwgeSA9IHNhdF9hdmcsIA0KICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yID0gY29udHJvbCkpKw0Kc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcz1DUENPTFMpDQpgYGANCg0KLS0tDQoNCiMjIyBQb2ludCBzaXplIA0KDQpMZXQncyBhbHRlciB0aGUgc2l6ZSBvZiBwb2ludGVycyBpbiBhY2NvcmRhbmNlIHRvIHRoZSBudW1iZXIgb2YgdW5kZXJncmFkdWF0ZXMgaW4gZWFjaCBwb2ludHMgLSANCmBgYHtyfQ0KZ2dwbG90KGRhdGEgPSBjb2xsZWdlKSArDQogIGdlb21fcG9pbnQobWFwcGluZyA9IGFlcyh4ID0gdHVpdGlvbiwgeSA9IHNhdF9hdmcsIA0KICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yID0gY29udHJvbCwgc2l6ZSA9IHVuZGVyZ3JhZHMpKQ0KYGBgDQoNClVzaW5nIGBxcGxvdGAgLSANCmBgYHtyfQ0KcXBsb3QoZGF0YSA9IGNvbGxlZ2UsIHggPSB0dWl0aW9uLCB5ID0gc2F0X2F2ZywgDQogICAgICBjb2xvciA9IGNvbnRyb2wsIHNpemUgPSB1bmRlcmdyYWRzKQ0KYGBgDQoNCi0tLQ0KDQojIyMgQWxwaGEgLSB0cmFuc3BhcmVuY3kgDQpUbyBhZGQgc29tZSB0cmFuc3BhcmVuY3kgc28gd2UgY2FuIHNlZSB0aHJvdWdoIHRob3NlIHBvaW50cyAtIA0KYGBge3J9DQpnZ3Bsb3QoZGF0YSA9IGNvbGxlZ2UpICsNCiAgZ2VvbV9wb2ludChtYXBwaW5nID0gYWVzKHggPSB0dWl0aW9uLCB5ID0gc2F0X2F2ZywgDQogICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSBjb250cm9sLCBzaXplID0gdW5kZXJncmFkcyksIA0KICAgICAgICAgICAgIGFscGhhID0gMC4zNSkNCmBgYA0KDQpVc2luZyBgcXBsb3RgIC0gDQpgYGB7cn0NCnFwbG90KGRhdGEgPSBjb2xsZWdlLCB4ID0gdHVpdGlvbiwgeSA9IHNhdF9hdmcsIA0KICAgICAgY29sb3IgPSBjb250cm9sLCBzaXplID0gdW5kZXJncmFkcyxhbHBoYT1JKDAuMzUpKSAjIG1hbnVhbGx5IHNldHRpbmcgYWxwaGEgPSBJKG4pIC0tIDA8bjwxDQpgYGANCg0KLS0tDQoNCiMjIyBUaXRsZSBhbmQgU3VidGl0bGUNCg0KQWRkIHRpdGxlIGFuZCBzdWJ0aXRsZSB1c2luZyB0aGUgZ2d0aXRsZSAtDQpgYGB7cn0NCmdncGxvdChkYXRhID0gY29sbGVnZSkgKw0KICBnZW9tX3BvaW50KG1hcHBpbmcgPSBhZXMoeCA9IHR1aXRpb24sIHkgPSBzYXRfYXZnLCANCiAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9IGNvbnRyb2wsIHNpemUgPSB1bmRlcmdyYWRzKSwgDQogICAgICAgICAgICAgYWxwaGEgPSAwLjM1KSArDQogIGdndGl0bGUoIlNBVCBBdmVyYWdlIHNjb3JlIFZTIFR1aXRpb24gRmVlIiwNCiAgICAgICAgICBzdWJ0aXRsZSA9ICJBIGNvbXBhcmlzb24gc3R1ZHkiKQ0KYGBgDQoNCkFsdGVybmF0aXZlbHkgLSANCmBgYHtyfQ0KZ2dwbG90KGRhdGEgPSBjb2xsZWdlKSArDQogIGdlb21fcG9pbnQobWFwcGluZyA9IGFlcyh4ID0gdHVpdGlvbiwgeSA9IHNhdF9hdmcsIA0KICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yID0gY29udHJvbCwgc2l6ZSA9IHVuZGVyZ3JhZHMpLCANCiAgICAgICAgICAgICBhbHBoYSA9IDAuMzUpICsNCiAgbGFicyh0aXRsZSA9ICJTQVQgQXZlcmFnZSBzY29yZSBWUyBUdWl0aW9uIEZlZSIsDQogICAgICAgICAgc3VidGl0bGUgPSAiQSBjb21wYXJpc29uIHN0dWR5IikNCmBgYA0KDQotLS0NCg0KIyMjIEF4aXMgbGFiZWxzDQoNCmBgYHtyfQ0KZ2dwbG90KGRhdGEgPSBjb2xsZWdlKSArDQogIGdlb21fcG9pbnQobWFwcGluZyA9IGFlcyh4ID0gdHVpdGlvbiwgeSA9IHNhdF9hdmcsIA0KICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yID0gY29udHJvbCwgc2l6ZSA9IHVuZGVyZ3JhZHMpLCANCiAgICAgICAgICAgICBhbHBoYSA9IDAuMzUpICsNCiAgeGxhYigiVHVpdGlvbiBGZWVzIikrDQogIHlsYWIoIlNBVCBBdmVyYWdlIFNjb3JlIikNCmBgYA0KDQpBbHRlcm5hdGl2ZWx5IHVzaW5nIGBsYWJzYCAtIA0KYGBge3J9DQpnZ3Bsb3QoZGF0YSA9IGNvbGxlZ2UpICsNCiAgZ2VvbV9wb2ludChtYXBwaW5nID0gYWVzKHggPSB0dWl0aW9uLCB5ID0gc2F0X2F2ZywgDQogICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSBjb250cm9sLCBzaXplID0gdW5kZXJncmFkcyksIA0KICAgICAgICAgICAgIGFscGhhID0gMC4zNSkgKw0KICBsYWJzKHggPSAiVHVpdGlvbiBGZWVzIiwgeSA9ICJTQVQgQXZlcmFnZSBTY29yZSIsDQogICAgICAgdGl0bGUgPSAiU0FUIEF2ZXJhZ2Ugc2NvcmUgVlMgVHVpdGlvbiBGZWUiLA0KICAgICAgIHN1YnRpdGxlID0gIkEgY29tcGFyaXNvbiBzdHVkeSIpDQpgYGANCg0KVG8gcGxvdCB0aGUgdGl0bGUgaW4gbWlkZGxlIC0gDQpgYGB7cn0NCmdncGxvdChkYXRhID0gY29sbGVnZSkgKw0KICBnZW9tX3BvaW50KG1hcHBpbmcgPSBhZXMoeCA9IHR1aXRpb24sIHkgPSBzYXRfYXZnLCANCiAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9IGNvbnRyb2wsIHNpemUgPSB1bmRlcmdyYWRzKSwgDQogICAgICAgICAgICAgYWxwaGEgPSAwLjM1KSArDQogIGxhYnMoeCA9ICJUdWl0aW9uIEZlZXMiLCB5ID0gIlNBVCBBdmVyYWdlIFNjb3JlIiwNCiAgICAgICB0aXRsZSA9ICJTQVQgQXZlcmFnZSBzY29yZSBWUyBUdWl0aW9uIEZlZSIsDQogICAgICAgc3VidGl0bGUgPSAiQSBjb21wYXJpc29uIHN0dWR5IikgKw0KICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkNCmBgYA0KDQotLS0NCg0KIyMjIEF4aXMgbGltaXQNCg0KVXNpbmcgYHhsaW1gIGFuZCBgeWxpbWAgLSANCmBgYHtyfQ0KZ2dwbG90KGRhdGEgPSBjb2xsZWdlKSArDQogIGdlb21fcG9pbnQobWFwcGluZyA9IGFlcyh4ID0gdHVpdGlvbiwgeSA9IHNhdF9hdmcsIA0KICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yID0gY29udHJvbCwgc2l6ZSA9IHVuZGVyZ3JhZHMpLCANCiAgICAgICAgICAgICBhbHBoYSA9IDAuMzUpICsNCiAgbGFicyh4ID0gIlR1aXRpb24gRmVlcyIsIHkgPSAiU0FUIEF2ZXJhZ2UgU2NvcmUiLA0KICAgICAgIHRpdGxlID0gIlNBVCBBdmVyYWdlIHNjb3JlIFZTIFR1aXRpb24gRmVlIiwNCiAgICAgICBzdWJ0aXRsZSA9ICJBIGNvbXBhcmlzb24gc3R1ZHkiKSsNCiAgeGxpbSgwLDU1MDAwKSt5bGltKDUwMCwxODAwKQ0KYGBgDQoNCmBleHBhbmRfbGltaXRzYCBkb2Vzbid0IGN1dCB2YWx1ZXMgZnJvbSB0aGUgcGxvdCAtDQpgYGB7cn0NCmdncGxvdChkYXRhID0gY29sbGVnZSkgKw0KICBnZW9tX3BvaW50KG1hcHBpbmcgPSBhZXMoeCA9IHR1aXRpb24sIHkgPSBzYXRfYXZnLCANCiAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9IGNvbnRyb2wsIHNpemUgPSB1bmRlcmdyYWRzKSwgDQogICAgICAgICAgICAgYWxwaGEgPSAwLjM1KSArDQogIGxhYnMoeCA9ICJUdWl0aW9uIEZlZXMiLCB5ID0gIlNBVCBBdmVyYWdlIFNjb3JlIiwNCiAgICAgICB0aXRsZSA9ICJTQVQgQXZlcmFnZSBzY29yZSBWUyBUdWl0aW9uIEZlZSIsDQogICAgICAgc3VidGl0bGUgPSAiQSBjb21wYXJpc29uIHN0dWR5IikrDQogIGV4cGFuZF9saW1pdHMoeD1jKDAsNTUwMDApLHk9YygxNTAwLDIwMDApKQ0KYGBgDQoNCi0tLQ0KDQojIyMgQ2FwdGlvbiANClRoZSBjYXB0aW9uIGFwcGVhcnMgaW4gdGhlIGJvdHRvbS1yaWdodCwgYW5kIGlzIG9mdGVuIHVzZWQgZm9yIHNvdXJjZXMsIG5vdGVzIG9yIGNvcHlyaWdodCAtIA0KYGBge3J9DQpnZ3Bsb3QoZGF0YSA9IGNvbGxlZ2UpICsNCiAgZ2VvbV9wb2ludChtYXBwaW5nID0gYWVzKHggPSB0dWl0aW9uLCB5ID0gc2F0X2F2ZywgDQogICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSBjb250cm9sLCBzaXplID0gdW5kZXJncmFkcyksIA0KICAgICAgICAgICAgIGFscGhhID0gMC4zNSkgKw0KICBsYWJzKHggPSAiVHVpdGlvbiBGZWVzIiwgeSA9ICJTQVQgQXZlcmFnZSBTY29yZSIsDQogICAgICAgdGl0bGUgPSAiU0FUIEF2ZXJhZ2Ugc2NvcmUgVlMgVHVpdGlvbiBGZWUiLA0KICAgICAgIGNhcHRpb24gPSAiU291cmNlOiBVLlMuIERlcGFydG1lbnQgb2YgRWR1Y2F0aW9uIikNCmBgYA0KDQotLS0NCg0KIyMjIFRhZw0KDQpUaGUgcGxvdCB0YWcgYXBwZWFycyBhdCB0aGUgdG9wLWxlZnQsIGFuZCBpcyB0eXBpY2FsbHkgdXNlZCBmb3IgbGFiZWxsaW5nIGEgc3VicGxvdCB3aXRoIGEgbGV0dGVyIC0gDQpgYGB7cn0NCmdncGxvdChkYXRhID0gY29sbGVnZSkgKw0KICBnZW9tX3BvaW50KG1hcHBpbmcgPSBhZXMoeCA9IHR1aXRpb24sIHkgPSBzYXRfYXZnLCANCiAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9IGNvbnRyb2wsIHNpemUgPSB1bmRlcmdyYWRzKSwgDQogICAgICAgICAgICAgYWxwaGEgPSAwLjM1KSArDQogIGxhYnMoeCA9ICJUdWl0aW9uIEZlZXMiLCB5ID0gIlNBVCBBdmVyYWdlIFNjb3JlIiwNCiAgICAgICB0aXRsZSA9ICJTQVQgQXZlcmFnZSBzY29yZSBWUyBUdWl0aW9uIEZlZSIsDQogICAgICAgc3VidGl0bGUgPSAiQSBjb21wYXJpc29uIHN0dWR5IiwNCiAgICAgICBjYXB0aW9uID0gIlNvdXJjZTogVS5TLiBEZXBhcnRtZW50IG9mIEVkdWNhdGlvbiIsDQogICAgICAgdGFnID0gIkEiKQ0KYGBgDQoNCi0tLQ0KDQojIyMgQ2hhbmdpbmcgYmFja2dyb3VuZCBjb2xvciAgDQoNCmBwbG90LmJhY2tncm91bmRgIGNoYW5nZXMgdGhlIGNvbG9yIG9mIGJhY2tncm91bmQgb2YgcGxvdCBhbmQgYHBhbmVsLmJhY2tncnVuZGAgY2hhbmdlcyB0aGUgY29sb3Igb2YgYmFja2dyb3VuZCBvZiBwYW5lbC0NCmBgYHtyfQ0KZ2dwbG90KGRhdGEgPSBjb2xsZWdlKSArDQogIGdlb21fcG9pbnQobWFwcGluZyA9IGFlcyh4ID0gdHVpdGlvbiwgeSA9IHNhdF9hdmcsIA0KICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yID0gY29udHJvbCwgc2l6ZSA9IHVuZGVyZ3JhZHMpLCANCiAgICAgICAgICAgICBhbHBoYSA9IDAuMzUpICsNCiAgbGFicyh4ID0gIlR1aXRpb24gRmVlcyIsIHkgPSAiU0FUIEF2ZXJhZ2UgU2NvcmUiLA0KICAgICAgIHRpdGxlID0gIlNBVCBBdmVyYWdlIHNjb3JlIFZTIFR1aXRpb24gRmVlIiwNCiAgICAgICBzdWJ0aXRsZSA9ICJBIGNvbXBhcmlzb24gc3R1ZHkiLA0KICAgICAgIGNhcHRpb24gPSAiU291cmNlOiBVLlMuIERlcGFydG1lbnQgb2YgRWR1Y2F0aW9uIiwNCiAgICAgICB0YWcgPSAiQSIpKw0KICB0aGVtZShwbG90LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbD0nZGFya3NlYWdyZWVuJykpDQpgYGANCg0KYGBge3J9DQpnZ3Bsb3QoZGF0YSA9IGNvbGxlZ2UpICsNCiAgZ2VvbV9wb2ludChtYXBwaW5nID0gYWVzKHggPSB0dWl0aW9uLCB5ID0gc2F0X2F2ZywgDQogICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSBjb250cm9sLCBzaXplID0gdW5kZXJncmFkcyksIA0KICAgICAgICAgICAgIGFscGhhID0gMC4zNSkgKw0KICBsYWJzKHggPSAiVHVpdGlvbiBGZWVzIiwgeSA9ICJTQVQgQXZlcmFnZSBTY29yZSIsDQogICAgICAgdGl0bGUgPSAiU0FUIEF2ZXJhZ2Ugc2NvcmUgVlMgVHVpdGlvbiBGZWUiLA0KICAgICAgIHN1YnRpdGxlID0gIkEgY29tcGFyaXNvbiBzdHVkeSIsDQogICAgICAgY2FwdGlvbiA9ICJTb3VyY2U6IFUuUy4gRGVwYXJ0bWVudCBvZiBFZHVjYXRpb24iLA0KICAgICAgIHRhZyA9ICJBIikrDQogIHRoZW1lKHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbD0nYXp1cmUxJykpDQpgYGANCg0KYGBge3J9DQpnZ3Bsb3QoZGF0YSA9IGNvbGxlZ2UpICsNCiAgZ2VvbV9wb2ludChtYXBwaW5nID0gYWVzKHggPSB0dWl0aW9uLCB5ID0gc2F0X2F2ZywgDQogICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSBjb250cm9sLCBzaXplID0gdW5kZXJncmFkcyksIA0KICAgICAgICAgICAgIGFscGhhID0gMC4zNSkgKw0KICBsYWJzKHggPSAiVHVpdGlvbiBGZWVzIiwgeSA9ICJTQVQgQXZlcmFnZSBTY29yZSIsDQogICAgICAgdGl0bGUgPSAiU0FUIEF2ZXJhZ2Ugc2NvcmUgVlMgVHVpdGlvbiBGZWUiLA0KICAgICAgIHN1YnRpdGxlID0gIkEgY29tcGFyaXNvbiBzdHVkeSIsDQogICAgICAgY2FwdGlvbiA9ICJTb3VyY2U6IFUuUy4gRGVwYXJ0bWVudCBvZiBFZHVjYXRpb24iLA0KICAgICAgIHRhZyA9ICJBIikrDQogIHRoZW1lKHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbD0nYXp1cmUxJyksDQogICAgICAgIHBsb3QuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsPSdhenVyZTEnKSkNCmBgYA0KDQpVc2UgYGVsZW1lbnRfYmxhbmsoKWAgdG8gcmVtb3ZlIGFsbCBncmlkcyBhbmQgY29sb3JzIGZyb20gYmFja2dyb3VuZCAtDQpgYGB7cn0NCmdncGxvdChkYXRhID0gY29sbGVnZSkgKw0KICBnZW9tX3BvaW50KG1hcHBpbmcgPSBhZXMoeCA9IHR1aXRpb24sIHkgPSBzYXRfYXZnLCANCiAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9IGNvbnRyb2wsIHNpemUgPSB1bmRlcmdyYWRzKSwgDQogICAgICAgICAgICAgYWxwaGEgPSAwLjM1KSArDQogIGxhYnMoeCA9ICJUdWl0aW9uIEZlZXMiLCB5ID0gIlNBVCBBdmVyYWdlIFNjb3JlIiwNCiAgICAgICB0aXRsZSA9ICJTQVQgQXZlcmFnZSBzY29yZSBWUyBUdWl0aW9uIEZlZSIpKw0KICB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpKQ0KYGBgDQoNCi0tLQ0KDQojIyMgVXNpbmcgUHJlZGVmaW5lZCBUaGVtZXMNCkxpc3Qgb2YgdGhlbWVzOg0KKiB0aGVtZV9idygpDQoqIHRoZW1lX21pbmltYWwoKQ0KKiB0aGVtZV9saW5lZHJhdygpIA0KKiB0aGVtZV9saWdodCgpIA0KKiB0aGVtZV9kYXJrKCkgDQoqIHRoZW1lX2NsYXNzaWMoKSANCiogdGhlbWVfdm9pZCgpIA0KKiB0aGVtZV90ZXN0KCkNCg0KVXNpbmcgY2xhc3NpYyB0aGVtZSAtIA0KYGBge3J9DQpnZ3Bsb3QoZGF0YSA9IGNvbGxlZ2UpICsNCiAgZ2VvbV9wb2ludChtYXBwaW5nID0gYWVzKHggPSB0dWl0aW9uLCB5ID0gc2F0X2F2ZywgDQogICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSBjb250cm9sLCBzaXplID0gdW5kZXJncmFkcyksIA0KICAgICAgICAgICAgIGFscGhhID0gMC4zNSkgKw0KICBsYWJzKHggPSAiVHVpdGlvbiBGZWVzIiwgeSA9ICJTQVQgQXZlcmFnZSBTY29yZSIsDQogICAgICAgdGl0bGUgPSAiU0FUIEF2ZXJhZ2Ugc2NvcmUgVlMgVHVpdGlvbiBGZWUiKSArDQogIHRoZW1lX2NsYXNzaWMoKQ0KYGBgDQoNClVzaW5nIG1pbmltYWwgdGhlbWUgLSANCmBgYHtyfQ0KZ2dwbG90KGRhdGEgPSBjb2xsZWdlKSArDQogIGdlb21fcG9pbnQobWFwcGluZyA9IGFlcyh4ID0gdHVpdGlvbiwgeSA9IHNhdF9hdmcsIA0KICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yID0gY29udHJvbCwgc2l6ZSA9IHVuZGVyZ3JhZHMpLCANCiAgICAgICAgICAgICBhbHBoYSA9IDAuMzUpICsNCiAgbGFicyh4ID0gIlR1aXRpb24gRmVlcyIsIHkgPSAiU0FUIEF2ZXJhZ2UgU2NvcmUiLA0KICAgICAgIHRpdGxlID0gIlNBVCBBdmVyYWdlIHNjb3JlIFZTIFR1aXRpb24gRmVlIikgKw0KICB0aGVtZV9taW5pbWFsKCkNCmBgYA0KDQpVc2luZyBkYXJrIHRoZW1lIC0gDQpgYGB7cn0NCmdncGxvdChkYXRhID0gY29sbGVnZSkgKw0KICBnZW9tX3BvaW50KG1hcHBpbmcgPSBhZXMoeCA9IHR1aXRpb24sIHkgPSBzYXRfYXZnLCANCiAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9IGNvbnRyb2wsIHNpemUgPSB1bmRlcmdyYWRzKSwgDQogICAgICAgICAgICAgYWxwaGEgPSAwLjM1KSArDQogIGxhYnMoeCA9ICJUdWl0aW9uIEZlZXMiLCB5ID0gIlNBVCBBdmVyYWdlIFNjb3JlIiwNCiAgICAgICB0aXRsZSA9ICJTQVQgQXZlcmFnZSBzY29yZSBWUyBUdWl0aW9uIEZlZSIpICsNCiAgdGhlbWVfZGFyaygpDQpgYGANCg0KTW9yZSB0aGVtZXMgY2FuIGJlIGZvdW5kIGZyb20gdGhlIHBhY2thZ2UgYGdndGhlbWVzYC4gTG9hZCB0aGUgcGFja2FnZSAtIA0KYGBge3J9DQpsaWJyYXJ5KGdndGhlbWVzKQ0KYGBgDQoNCkRldGFpbHMgb24gdGhlIHRoZW1lcyBjYW4gYmUgZm91bmQgW2hlcmVdKGh0dHBzOi8veXV0YW5uaWhpbGF0aW9uLmdpdGh1Yi5pby9hbGxZb3VyRmlndXJlQXJlQmVsb25nVG9Vcy9nZ3RoZW1lcy8pLiAgIA0KDQpVc2luZyB0aGUgdGhlbWUgc29sYXJpemVkIC0gDQpgYGB7cn0NCmdncGxvdChkYXRhID0gY29sbGVnZSkgKw0KICBnZW9tX3BvaW50KG1hcHBpbmcgPSBhZXMoeCA9IHR1aXRpb24sIHkgPSBzYXRfYXZnLCANCiAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9IGNvbnRyb2wsIHNpemUgPSB1bmRlcmdyYWRzKSwgDQogICAgICAgICAgICAgYWxwaGEgPSAwLjM1KSArDQogIGxhYnMoeCA9ICJUdWl0aW9uIEZlZXMiLCB5ID0gIlNBVCBBdmVyYWdlIFNjb3JlIiwNCiAgICAgICB0aXRsZSA9ICJTQVQgQXZlcmFnZSBzY29yZSBWUyBUdWl0aW9uIEZlZSIpICsNCiAgdGhlbWVfc29sYXJpemVkKCkNCmBgYA0KDQotLS0NCg0KIyMjIEF4aXMgZ3JpZHMNCg0KU2hvd2luZyBib3RoIGdyaWRzIGluIGEgc2luZ2xlIGNvbG9yIHVzaW5nIGBwYW5lbC5ncmlkLm1ham9yYCAtIA0KYGBge3J9DQpnZ3Bsb3QoZGF0YSA9IGNvbGxlZ2UpICsNCiAgZ2VvbV9wb2ludChtYXBwaW5nID0gYWVzKHggPSB0dWl0aW9uLCB5ID0gc2F0X2F2ZywgDQogICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSBjb250cm9sLCBzaXplID0gdW5kZXJncmFkcyksIA0KICAgICAgICAgICAgIGFscGhhID0gMC4zNSkgKw0KICBsYWJzKHggPSAiVHVpdGlvbiBGZWVzIiwgeSA9ICJTQVQgQXZlcmFnZSBTY29yZSIsDQogICAgICAgdGl0bGUgPSAiU0FUIEF2ZXJhZ2Ugc2NvcmUgVlMgVHVpdGlvbiBGZWUiKSsNCiAgdGhlbWUocGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgcGFuZWwuZ3JpZC5tYWpvciA9IGVsZW1lbnRfbGluZSgiZ3JleSIpKQ0KYGBgDQoNClNob3dpbmcgb25seSBYIGF4aXMgZ3JpZCB1c2luZyBgcGFuZWwuZ3JpZC5tYWpvci54YC0NCmBgYHtyfQ0KZ2dwbG90KGRhdGEgPSBjb2xsZWdlKSArDQogIGdlb21fcG9pbnQobWFwcGluZyA9IGFlcyh4ID0gdHVpdGlvbiwgeSA9IHNhdF9hdmcsIA0KICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yID0gY29udHJvbCwgc2l6ZSA9IHVuZGVyZ3JhZHMpLCANCiAgICAgICAgICAgICBhbHBoYSA9IDAuMzUpICsNCiAgbGFicyh4ID0gIlR1aXRpb24gRmVlcyIsIHkgPSAiU0FUIEF2ZXJhZ2UgU2NvcmUiLA0KICAgICAgIHRpdGxlID0gIlNBVCBBdmVyYWdlIHNjb3JlIFZTIFR1aXRpb24gRmVlIikrDQogIHRoZW1lKHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X2JsYW5rKCksDQogICAgICAgIHBhbmVsLmdyaWQubWFqb3IueCA9IGVsZW1lbnRfbGluZSgiZ3JleSIpKQ0KYGBgDQoNClNpbWlsYXJseSBZIGF4aXMgZ3JpZCAtIA0KYGBge3J9DQpnZ3Bsb3QoZGF0YSA9IGNvbGxlZ2UpICsNCiAgZ2VvbV9wb2ludChtYXBwaW5nID0gYWVzKHggPSB0dWl0aW9uLCB5ID0gc2F0X2F2ZywgDQogICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSBjb250cm9sLCBzaXplID0gdW5kZXJncmFkcyksIA0KICAgICAgICAgICAgIGFscGhhID0gMC4zNSkgKw0KICBsYWJzKHggPSAiVHVpdGlvbiBGZWVzIiwgeSA9ICJTQVQgQXZlcmFnZSBTY29yZSIsDQogICAgICAgdGl0bGUgPSAiU0FUIEF2ZXJhZ2Ugc2NvcmUgVlMgVHVpdGlvbiBGZWUiKSsNCiAgdGhlbWUocGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSwNCiAgICAgICAgcGFuZWwuZ3JpZC5tYWpvci55ID0gZWxlbWVudF9saW5lKCJncmV5IikpDQpgYGANCg0KVG8gaGlkZSBncmlkcyB1c2UgZWxlbWVudF9ibGFuaygpIC0gDQpgYGB7cn0NCmdncGxvdChkYXRhID0gY29sbGVnZSkgKw0KICBnZW9tX3BvaW50KG1hcHBpbmcgPSBhZXMoeCA9IHR1aXRpb24sIHkgPSBzYXRfYXZnLCANCiAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9IGNvbnRyb2wsIHNpemUgPSB1bmRlcmdyYWRzKSwgDQogICAgICAgICAgICAgYWxwaGEgPSAwLjM1KSArDQogIGxhYnMoeCA9ICJUdWl0aW9uIEZlZXMiLCB5ID0gIlNBVCBBdmVyYWdlIFNjb3JlIiwNCiAgICAgICB0aXRsZSA9ICJTQVQgQXZlcmFnZSBzY29yZSBWUyBUdWl0aW9uIEZlZSIpKw0KICB0aGVtZShwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpLA0KICAgICAgICBwYW5lbC5ncmlkLm1ham9yID0gZWxlbWVudF9ibGFuaygpKQ0KYGBgDQoNCi0tLQ0KDQojIyMgTGVnZW5kIEN1c3RvbWl6YXRpb24NCiMjIyMgQ2hhbmdpbmcgTGVnZW5kIFRpdGxlcw0KYGBge3J9DQpnZ3Bsb3QoZGF0YSA9IGNvbGxlZ2UpICsNCiAgZ2VvbV9wb2ludChtYXBwaW5nID0gYWVzKHggPSB0dWl0aW9uLCB5ID0gc2F0X2F2ZywgDQogICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSBjb250cm9sLCBzaXplID0gdW5kZXJncmFkcyksIA0KICAgICAgICAgICAgIGFscGhhID0gMC4zNSkgKw0KICBsYWJzKHggPSAiVHVpdGlvbiBGZWVzIiwgDQogICAgICAgeSA9ICJTQVQgQXZlcmFnZSBTY29yZSIsDQogICAgICAgdGl0bGUgPSAiU0FUIEF2ZXJhZ2Ugc2NvcmUgVlMgVHVpdGlvbiBGZWUiLA0KICAgICAgIHNpemU9Ik5vLiBvZiBzdHVkZW50cyIsDQogICAgICAgY29sb3I9Ikluc3RpdHV0aW9uIFR5cGUiKQ0KYGBgDQoNCiMjIyMgTGVnZW5kIHBvc2l0aW9uDQpDYW4gdGFrZSB2YWx1ZXMgLSByaWdodCwgbGVmdCwgYm90dG9tLCB0b3AsIG5vbmUuICAgDQpFeGFtcGxlIC0gDQpgYGB7cn0NCmdncGxvdChkYXRhID0gY29sbGVnZSkgKw0KICBnZW9tX3BvaW50KG1hcHBpbmcgPSBhZXMoeCA9IHR1aXRpb24sIHkgPSBzYXRfYXZnLCANCiAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9IGNvbnRyb2wsIHNpemUgPSB1bmRlcmdyYWRzKSwgDQogICAgICAgICAgICAgYWxwaGEgPSAwLjM1KSArDQogIGxhYnMoeCA9ICJUdWl0aW9uIEZlZXMiLCANCiAgICAgICB5ID0gIlNBVCBBdmVyYWdlIFNjb3JlIiwNCiAgICAgICB0aXRsZSA9ICJTQVQgQXZlcmFnZSBzY29yZSBWUyBUdWl0aW9uIEZlZSIpKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibGVmdCIpDQpgYGANCiAgICANCmBsZWdlbmQucG9zaXRpb24gPSAibm9uZSJgIHRvIGhpZGUgdGhlIGxlZ2VuZC0gDQpgYGB7cn0NCmdncGxvdChkYXRhID0gY29sbGVnZSkgKw0KICBnZW9tX3BvaW50KG1hcHBpbmcgPSBhZXMoeCA9IHR1aXRpb24sIHkgPSBzYXRfYXZnLCANCiAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9IGNvbnRyb2wsIHNpemUgPSB1bmRlcmdyYWRzKSwgDQogICAgICAgICAgICAgYWxwaGEgPSAwLjM1KSArDQogIGxhYnMoeCA9ICJUdWl0aW9uIEZlZXMiLCANCiAgICAgICB5ID0gIlNBVCBBdmVyYWdlIFNjb3JlIiwNCiAgICAgICB0aXRsZSA9ICJTQVQgQXZlcmFnZSBzY29yZSBWUyBUdWl0aW9uIEZlZSIpKw0KICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpDQpgYGANCg0KIyMjIyBMZWdlbmQgdGl0bGUgICAgDQoNClRvIGhpZGUgdGhlIGxlZ2VuZCB0aXRsZSAtIA0KYGBge3J9DQpnZ3Bsb3QoZGF0YSA9IGNvbGxlZ2UpICsNCiAgZ2VvbV9wb2ludChtYXBwaW5nID0gYWVzKHggPSB0dWl0aW9uLCB5ID0gc2F0X2F2ZywgDQogICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSBjb250cm9sLCBzaXplID0gdW5kZXJncmFkcyksIA0KICAgICAgICAgICAgIGFscGhhID0gMC4zNSkgKw0KICBsYWJzKHggPSAiVHVpdGlvbiBGZWVzIiwgDQogICAgICAgeSA9ICJTQVQgQXZlcmFnZSBTY29yZSIsDQogICAgICAgdGl0bGUgPSAiU0FUIEF2ZXJhZ2Ugc2NvcmUgVlMgVHVpdGlvbiBGZWUiKSsNCiAgdGhlbWUobGVnZW5kLnRpdGxlID0gZWxlbWVudF9ibGFuaygpKQ0KYGBgDQoNCg0KDQojIyMjIExlZ2VuZCBEaXJlY3Rpb24NCkxheW91dCBvZiBpdGVtcyBpbiBsZWdlbmRzICgiaG9yaXpvbnRhbCIgb3IgInZlcnRpY2FsIikgDQpgYGB7cn0NCmdncGxvdChkYXRhID0gY29sbGVnZSkgKw0KICBnZW9tX3BvaW50KG1hcHBpbmcgPSBhZXMoeCA9IHR1aXRpb24sIHkgPSBzYXRfYXZnLCANCiAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvciA9IGNvbnRyb2wsIHNpemUgPSB1bmRlcmdyYWRzKSwgDQogICAgICAgICAgICAgYWxwaGEgPSAwLjM1KSArDQogIGxhYnMoeCA9ICJUdWl0aW9uIEZlZXMiLCANCiAgICAgICB5ID0gIlNBVCBBdmVyYWdlIFNjb3JlIiwNCiAgICAgICB0aXRsZSA9ICJTQVQgQXZlcmFnZSBzY29yZSBWUyBUdWl0aW9uIEZlZSIpKw0KICB0aGVtZShsZWdlbmQuZGlyZWN0aW9uID0gInZlcnRpY2FsIiwNCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uID0gInRvcCIpDQpgYGANCg0KIyMjIyBMZWdlbmQgQm94IFBvc2l0aW9uaW5nDQpVc2luZyBgbGVnZW5kLmJveGAgLQ0KYGBge3J9DQpnZ3Bsb3QoZGF0YSA9IGNvbGxlZ2UpICsNCiAgZ2VvbV9wb2ludChtYXBwaW5nID0gYWVzKHggPSB0dWl0aW9uLCB5ID0gc2F0X2F2ZywgDQogICAgICAgICAgICAgICAgICAgICAgICAgY29sb3IgPSBjb250cm9sLCBzaXplID0gdW5kZXJncmFkcyksIA0KICAgICAgICAgICAgIGFscGhhID0gMC4zNSkgKw0KICBsYWJzKHggPSAiVHVpdGlvbiBGZWVzIiwgDQogICAgICAgeSA9ICJTQVQgQXZlcmFnZSBTY29yZSIsDQogICAgICAgdGl0bGUgPSAiU0FUIEF2ZXJhZ2Ugc2NvcmUgVlMgVHVpdGlvbiBGZWUiKSsNCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gInRvcCIsDQogICAgICAgICAgbGVnZW5kLmJveCA9ICJ2ZXJ0aWNhbCIpDQpgYGANCg0KVG8gYWxpZ2h0IHRoZSBsZWdlbmQgYm94IHRvIGxlZnQsIHJpZ2h0IG9yIGNlbnRlciB1c2UgYGxlZ2VuZC5ib3guanVzdGAgLSANCmBgYHtyfQ0KZ2dwbG90KGRhdGEgPSBjb2xsZWdlKSArDQogIGdlb21fcG9pbnQobWFwcGluZyA9IGFlcyh4ID0gdHVpdGlvbiwgeSA9IHNhdF9hdmcsIA0KICAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yID0gY29udHJvbCwgc2l6ZSA9IHVuZGVyZ3JhZHMpLCANCiAgICAgICAgICAgICBhbHBoYSA9IDAuMzUpICsNCiAgbGFicyh4ID0gIlR1aXRpb24gRmVlcyIsIA0KICAgICAgIHkgPSAiU0FUIEF2ZXJhZ2UgU2NvcmUiLA0KICAgICAgIHRpdGxlID0gIlNBVCBBdmVyYWdlIHNjb3JlIFZTIFR1aXRpb24gRmVlIikrDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJ0b3AiLA0KICAgICAgICBsZWdlbmQuYm94ID0gInZlcnRpY2FsIiwNCiAgICAgICAgbGVnZW5kLmJveC5qdXN0ID0gInJpZ2h0IikNCmBgYA0KDQotLS0NCg0KU3BlY2lhbCB0aGFua3MgdG8gW01pa2UgQ2hhcHBlbF0oaHR0cHM6Ly93d3cubHluZGEuY29tL01pa2UtQ2hhcHBsZS8yNDA1MDYxLTEuaHRtbCkgZm9yIGhpcyBjb3Vyc2UgaW4gTHluZGEgb24gZ2dwbG90Mi4gDQoNCkNoZWNrIG91dCBbaHR0cHM6Ly93d3cuaG9tZXdvcmtoZWxwb25saW5lLm5ldF0oaHR0cHM6Ly93d3cuaG9tZXdvcmtoZWxwb25saW5lLm5ldC9wcm9ncmFtbWluZy9yLXByb2dyYW1taW5nICJSIGhlbHAiKSBmb3IgUiBTdHVkaW8gUHJvZ3JhbW1pbmcgYXNzaWdubWVudCBoZWxwLg==