Data and analysis
Import data
#dat <- read_csv("20201223-Pho4-GFP-stats.csv")
#dat <- dat %>% mutate(Pho4GFP = factor(Pho4GFP, levels = c("No-GFP","ScPho4-mNeon","ScPho4-EGFP", "CgPho4-mNeon")), Group = factor(Group, levels = c("control", "endogenous", "exogenous", "plasmid")), Pho4 = factor(Pho4, levels = c("pho4-","ScPho4", "CgPho4"))) %>% filter(Sample != "G2") # remove G2 as it most likely had multiple PHO5pr-mCherry integrated and causes the rest of the RFP data to be compressed
dat <- read_tsv("./20201223-gated-median-out.txt", col_types = cols()) %>%
rename(Sample = name) %>%
relocate(Sample) %>%
# remove G2 as it most likely had multiple PHO5pr-mCherry integrated and
# causes the rest of the RFP data to be compressed
filter(Sample != "G2")
dat <- mutate(
dat,
Pho4GFP = factor(Pho4GFP,
levels = c("No-GFP","ScPho4-mNeon","ScPho4-EGFP", "CgPho4-mNeon")),
Group = factor(Group,
levels = c("control", "endogenous", "exogenous", "plasmid"),
labels = c("no GFP", "pho4::Pho4-GFP", "leu2::Pho4-GFP", "plasmid"))
)
issues <- c("G3","B3","C1","C2","D1","E3") # see below for reasons
Looking at the detailed plots, I identified a few samples that are
problematic.
| lack PHO5pr-mCherry |
two populations |
too few cells collected |
|
 |
 |
 |
|
| two populations |
two populations |
two populations |
|
 |
 |
 |
|
In the FlowCore analysis, I now fixed some of them using a cluster
gate. C1, D1 and E3 should now represent a homogenous population.
Pho4-GFP expression levels
First look at the level of Pho4-GFP compared with the negative
controls.

Figure 1 Pho4-GFP intensity by strain. Pho4-GFP
intensities were quantified on an Attune NxT flow cytometer using 400 mV
on the BL1 channel. Acquisition rate is 200 ul/min. At least 10,000
events were collected and the median fluorescent intensity (MFI,
arbitrary units) were presented on the x-axis, while strain IDs are
listed on the vertical axis. An asterisk next to a bar indicates issues
found with the sample (see methods section for details).
Discussion
- Somewhat surprising to me, the exogenously integrated Pho4-GFP,
except for the ScPho4-mNeon, seem to have rather low fluorescent
intensity. For example, F1, E2 and E3 all have very low GFP
signals.
- Last time (see 2020-12-21
report) I observed higher ScPho4-mNeon and ScPho4-EGFP expression in
the yH295 background (P, Q) than in the yH296 background (M, N). I
suspected there may be some feedback due to the lack of Pho2. This time
however, their expression levels appear to be the same. The main
difference in the experimental protocol compared to the last time is
that I did one o/n growth before the final growth instead of two.
PHO5pr-mCherry reporter levels
#rfp.bg <- mean(dat %>% filter(!PHO5RFP) %>% pull(YL2.H))
# didn't include a negative control for no RFP. from preivous runs, we know'
# the background for RFP is extremely low (~100), and thus can be safely ignored
rfp.basal <- dat %>% filter(Sample %in% c("yH295", "yH296")) %>% pull(YL2.H) %>% mean()
# removed a few outliers with MFI > 20k
p2 <- dat %>% #filter(PHO5RFP) %>%
select(Sample, Group, Pho4GFP, PHO2, BL1.H, YL2.H) %>%
pivot_longer(cols = c(BL1.H, YL2.H),
names_to = "Parameter", values_to = "Median") %>%
mutate(Parameter = factor(Parameter, levels = c("BL1.H", "YL2.H"),
labels = c("Pho4-GFP", "PHO5-RFP")),
Sample = ifelse(PHO2 == "pho2-", paste("*", Sample), Sample)) %>%
ggplot(aes(x = Sample, y = Median, fill = Group)) +
geom_bar(stat = "identity", position = position_dodge2(width = 0.9)) +
geom_hline(aes(yintercept = ifelse(Parameter == "Pho4-GFP", gfp.bg, rfp.basal)), linetype = 2, alpha = 0.6) +
facet_grid(Pho4GFP ~ Parameter, scales = "free", space = "free_y") +
xlab("Sample (* = pho2-)") + ylab("Median Fluorescent Intensity (a.u.)") +
scale_fill_brewer("Pho4-GFP source", type = "div", drop = FALSE) + #scale_color_manual(values = c("red", NA)) +
coord_flip() + scale_y_continuous(expand = c(0.01,0.02)) +
theme_bw()
p2

ggsave("img/20201223-Pho4-GFP-PHO5RFP-levels.png", width = 6, height = 6)
Figure 2 Corresponding Pho4-GFP and PHO5pr-mCherry reporter
fluorescence intensity per strain. Pho4-GFP and PHO5p-mCherry
intensities were quantified on an Attune NxT flow cytometer using 400 mV
on the BL1 and 430 mV on the YL2 channels respectively. Acquisition rate
is 200 ul/min. At least 10,000 events were collected. Strain IDs are
listed on the vertical axis and the Median Fluorescent Intensity (MFI,
arbitury units) for each channel on the horizontal axis. An asterisk
next to a bar indicates an overnight growth instead of a mid-log phase
growth was used for quantification. The dashed vertical line for
Pho4-GFP indicates the autofluorescence as calculated by the mean of the
intensities in the strains without GFP; the dashed vertical line for the
RFP plot indicates the basal level expression from the reporter without
Pho4, calculated by the average of yH295 and yH296, both of which lack
Pho4 but has the reporter). An asterisk next to a bar indicates issues
found with the sample (see methods section for details).
Discussion
- This experiment showed a lot of variability among the biological
replicates, especially for exogenously integrated CgPho4 (C and F). This
wasn’t the case in my previous experiment. It will be useful to repeat
this again.
- yH267 doesn’t conform to my expectation – it has ScPho4 and ScPho2
as well as the PHO5pr-mCherry reporter, and thus should give
normal levels of RFP, but didn’t.
PHO5pr-mCherry induction levels normalized by Pho4
abundance
We will first transform the raw GFP and RFP intensities to make them
more interpretable. For the GFP intensity, as there is a substantial
background, we will subtract the background from all the GFP-containing
strains to obtain the meaningful measure for Pho4 protein levels. For
RFP, there is minimal background (see below). However, there is a
“basal” expression of the reporter in the absence of Pho4 – what we are
interested in is not the absolute level of reporter expression but the
fold induction compared with the pho4∆ strains.
# transform
dat1 <- dat %>%
# remove the control groups as we need to calculate R/G
filter(Group != "no GFP") %>%
mutate(#GFP.noBG = ifelse(Pho4GFP == "No-GFP", NA, `Pho4-GFP` - gfp.bg),
#RFP.noBG = ifelse(PHO5RFP, `PHO5pr-mCherry` - rfp.bg, 0),
#RFP.FC = ifelse(PHO5RFP, RFP.noBG / rfp.basal, NA),
#nRFP.FC = RFP.FC / GFP.noBG * median(GFP.noBG, na.rm = T))
GFP.noBG = BL1.H - gfp.bg,
GFP.noBG = ifelse(GFP.noBG > 0, GFP.noBG, NA),
RFP.noBG = YL2.H, # - rfp.bg,
RFP.FC = RFP.noBG / rfp.basal,
RvG = RFP.noBG / GFP.noBG
)
p3 <- dat1 %>%
mutate(GFP.noBG = GFP.noBG / 1000, RFP.noBG = RFP.noBG / 1000) %>%
pivot_longer(cols = c(GFP.noBG, RFP.noBG), names_to = "Parameter", values_to = "Value") %>%
mutate(Parameter = factor(Parameter, levels = c("GFP.noBG", "RFP.noBG"),
labels = c("Pho4-GFP noBG", "PHO5pr-RFP noBG")),
Sample = ifelse(PHO2 == "pho2-", paste("*", Sample), Sample)) %>%
ggplot(aes(x = Sample, y = Value, fill = Group)) +
geom_bar(stat = "identity", position = position_dodge2(width = 0.9)) +
geom_text(aes(label = ifelse(Sample %in% issues, "*", ""), hjust = -0.2, vjust = 0.8), color = "black", size = 5) +
facet_grid(Pho4GFP ~ Parameter, scales = "free", space = "free_y") +
scale_fill_brewer("Pho4-GFP source", type = "div", drop = FALSE) +
scale_color_manual(values = c("red", NA)) +
coord_flip() + scale_y_continuous(expand = c(0.01,0.02)) +
xlab("Sample (* = pho2-)") +
ylab("Median Fluorescent Intensity (-backgroundd)") +
theme_bw()
p4 <- dat1 %>%
pivot_longer(cols = c(RFP.FC, RvG), names_to = "Parameter", values_to = "Value") %>%
mutate(Parameter = factor(Parameter, levels = c("RFP.FC", "RvG"),
labels = c("PHO5 fold induction", "PHO5-RFP / Pho4-GFP")),
Sample = ifelse(PHO2 == "pho2-", paste("*", Sample), Sample)) %>%
ggplot(aes(x = Sample, y = Value, fill = Group)) +
geom_bar(stat = "identity", position = position_dodge2(width = 0.9)) +
geom_hline(yintercept = 1, linetype = 2) +
geom_text(aes(label = ifelse(Sample %in% issues, "*", ""), hjust = -0.2, vjust = 0.8), color = "black", size = 5) +
facet_grid(Pho4GFP ~ Parameter, scales = "free", space = "free_y") +
scale_fill_brewer("Pho4-GFP source", type = "div", drop = F) + #scale_color_manual(values = c("red", NA)) +
coord_flip() + scale_y_continuous(expand = c(0.01,0.02)) +
ylab(NULL) + xlab("") +
theme_bw()
## place shared legend at the bottom
## reference: https://wilkelab.org/cowplot/articles/shared_legends.html
legend <- get_legend(
p1 +
guides(color = guide_legend(nrow = 1), fill = guide_legend(nrow = 1)) +
theme(legend.position = "bottom")
)
prow <- plot_grid(
p3 + theme(legend.position="none"),
p4 + theme(legend.position="none"),
align = 'vh',
labels = c("A", "B", "C"),
hjust = -1,
nrow = 1
)
plot_grid(prow, legend, ncol = 1, rel_heights = c(1, .1))

dat2 <- dat1 %>% filter(Pho4GFP != "No-GFP", PHO5RFP)
p1 <- dat2 %>%
mutate(GFP.noBG = GFP.noBG / 1000, RFP.noBG = RFP.noBG / 1000) %>%
pivot_longer(cols = c(GFP.noBG, RFP.noBG), names_to = "Parameter", values_to = "Value") %>%
mutate(Parameter = factor(Parameter, levels = c("GFP.noBG", "RFP.noBG"),
labels = c("Pho4-GFP abundance", "PHO5pr-mCherry level")),
Group = factor(Group, levels = c("control", "endogenous", "exogenous", "plasmid"))) %>%
ggplot(aes(x = Sample, y = Value, fill = Group, color = PHO2)) +
geom_bar(stat = "identity", position = position_dodge2(width = 0.9)) +
geom_text(aes(label = ifelse(Sample %in% issues, "*", ""), hjust = -0.2, vjust = 0.8), color = "black", size = 5) +
facet_grid(Pho4GFP ~ Parameter, scales = "free", space = "free_y") +
scale_fill_brewer(type = "div", drop = FALSE) + scale_color_manual(values = c("red", NA)) +
coord_flip() + scale_y_continuous(expand = expansion(mult=c(0.01,0.1))) + ylab("MFI (x1000, a.u.)") +
theme_bw()
Figure 3 Composite plot including Pho4 abundance,
PHO5 reporter strength and fold induction values.
Pho4-GFP and PHO5p-mCherry intensities were quantified as defined above.
Strain IDs are listed on the vertical axis. In (A), the
x-axis values represent the Median Fluorescent Intensity (MFI, arbitury
units) for either Pho4-GFP or PHO5pr-mCherry. For Pho4-GFP, the
background level based on strains without Pho4-GFP was subtracted. No
background subtraction was done for mCherry, but past results suggest
that the background fluorescence is neglegible relative to the positive
strains. In (B), the fold change for PHO5
reporter is calculated as the background-subtracted RFP level divided by
the basal expression level, as measured by the mean of the two strains
containing the reporter but have pho4∆. The normalized
induction ratio on the right column is calculated by dividing the
induction fold change from the left column by the corresponding Pho4-GFP
(background subtracted) levels and multiplied by the median Pho4-GFP
levels of all strains. The dashed lines in both columns indicate the
induction fold change of 1, i.e. no change compared to the
pho4∆ strains. In both panels, the x-axes are square-root
transformed so as to bring outliers into the plot without compressing
the rest of the data range. An asterisk next to a bar indicates an
overnight growth instead of a mid-log phase growth was used for
quantification. An asterisk next to a bar indicates issues found with
the sample (see methods section for details).
Discussion
- Plasmid-born Pho4-GFP strains show more variability in Pho4
abundance, but yields quite consistent fold induction values after
normalizing by the GFP intensity. Some issues do exist, e.g. Q1, Q2. B2
and B4’s abnormally high induction after normalization is due to the
very low GFP intensity.
- The exogenously integrated strains show more variability, likely due
to two reasons: multiple-integration at the time of transformation and
spontaneous loop-out leading to loss of the extra copies during the
outgrowth (or even on the plates)
- Based on limited data, the endogenously integrated Pho4-GFP has the
lowest clone-to-clone variability. If we could make the reporter
construct also endogenous, we would expect highly reproducible
data.
Plot variations
Present the above plot in a different way.
pd <- position_dodge(0.9)
tmp <- bind_rows(
"Pho4-GFP (MFI)" = select(dat, Sample, Group, Pho4GFP, PHO2, Value = BL1.H),
"PHO5-RFP / Pho4-GFP" = select(dat1, Sample, Group, Pho4GFP, PHO2, Value = RvG),
.id = "Parameter"
)
p5 <- tmp %>%
ggplot(aes(x = PHO2, y = Value, group = Group)) +
stat_summary(aes(fill = Group), geom = "crossbar",
fun.data = "mean_sdl", fun.args = list(mult = 1),
position = pd, linewidth = 0.2, width = 0.5) +
geom_point(shape = 21, size = 1, position = pd, color = "gray20", fill = "white") +
#geom_hline(yintercept = gfp.bg, linetype = "dashed", alpha = 0.6) +
facet_grid(Pho4GFP ~ Parameter, scales = "free", space = "free_y") +
scale_fill_brewer("Pho4-GFP source", type = "div", drop = FALSE,
breaks = c("no GFP", "leu2::Pho4-GFP", "plasmid")) +
#scale_y_continuous(limits = c(0,NA), expand = c(0.01,0)) +
coord_flip() + theme_bw() +
theme(axis.title = element_blank(), legend.position = "top")
p5

ggsave("img/20201223-Pho4-GFP-RvG-crossbar.png", width = 5, height = 6)
Figure 4 Variability in Pho4-GFP intensity and normalized
PHO5RFP levels between plasmids and integrated Pho4 The same
definitions for the two values as above. Here, the different biological
replicates are plotted as dots. The crossbar shows the mean (middle
line) and standard deviation (box).
Discussions
- It’s clear that plasmid-born Pho4 has smaller biological variation
than exogenously integrated ones.
LS0tCnRpdGxlOiBhbmFseXplIGZsb3cgY3l0b21ldHJ5IGRhdGEgZnJvbSAyMDIwLTEyLTIzCmF1dGhvcjogQmluIEhlCmRhdGU6IDIwMjAtMTItMjMsIHVwZGF0ZWQgYHIgU3lzLkRhdGUoKWAKb3V0cHV0OiAKICBodG1sX25vdGVib29rOgogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6IHRydWUKICAgIGRmX3ByaW50OiBkZWZhdWx0CiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUKLS0tCgpgYGB7ciBzZXR1cCwgbWVzc2FnZT1GQUxTRX0KcmVxdWlyZSh0aWR5dmVyc2UpCnJlcXVpcmUoY293cGxvdCkKYGBgCgojIyBHb2FsCgpUaGlzIGlzIHRvIHJlcGVhdCB0aGUgMjAyMC0xMi0yMSBleHBlcmltZW50LgoKIyMgTWF0ZXJpYWwgYW5kIG1ldGhvZHMKClNlZSBnRG9jLiBUaGlzIHRpbWUgSSByZXZlcnRlZCB0byBvbmUgby9uIGdyb3d0aC4gVGhlIHNlY29uZCBncm93dGggd2FzIGRvbmUgaW4gdGhlIDk2LXdlbGwgY2xlYXIgcGxhdGUgKG5vdCBkZWVwIHdlbGwpLiBDZWxscyB3ZXJlIGRpcmVjdGx5IGRpbHV0ZWQgaW50byBQQlMgYW5kIHJ1biBvbiB0aGUgZmxvdyBjeXRvbWV0ZXIuCgojIyMgVGFibGUgb2Ygc3RyYWlucwohW10oLi4vMjAyMDEyMjEtUGhvNC1HRlAtcGxhc21pZC1sZXUyLXRlc3QvaW1nL3N0cmFpbnMtZ2Vub3R5cGUucG5nKQoKIyMgRGF0YSBhbmQgYW5hbHlzaXMKIyMjIEltcG9ydCBkYXRhCmBgYHtyfQojZGF0IDwtIHJlYWRfY3N2KCIyMDIwMTIyMy1QaG80LUdGUC1zdGF0cy5jc3YiKQojZGF0IDwtIGRhdCAlPiUgbXV0YXRlKFBobzRHRlAgPSBmYWN0b3IoUGhvNEdGUCwgbGV2ZWxzID0gYygiTm8tR0ZQIiwiU2NQaG80LW1OZW9uIiwiU2NQaG80LUVHRlAiLCAiQ2dQaG80LW1OZW9uIikpLCBHcm91cCA9IGZhY3RvcihHcm91cCwgbGV2ZWxzID0gYygiY29udHJvbCIsICJlbmRvZ2Vub3VzIiwgImV4b2dlbm91cyIsICJwbGFzbWlkIikpLCBQaG80ID0gZmFjdG9yKFBobzQsIGxldmVscyA9IGMoInBobzQtIiwiU2NQaG80IiwgIkNnUGhvNCIpKSkgJT4lIGZpbHRlcihTYW1wbGUgIT0gIkcyIikgIyByZW1vdmUgRzIgYXMgaXQgbW9zdCBsaWtlbHkgaGFkIG11bHRpcGxlIFBITzVwci1tQ2hlcnJ5IGludGVncmF0ZWQgYW5kIGNhdXNlcyB0aGUgcmVzdCBvZiB0aGUgUkZQIGRhdGEgdG8gYmUgY29tcHJlc3NlZAoKZGF0IDwtIHJlYWRfdHN2KCIuLzIwMjAxMjIzLWdhdGVkLW1lZGlhbi1vdXQudHh0IiwgY29sX3R5cGVzID0gY29scygpKSAlPiUgCiAgcmVuYW1lKFNhbXBsZSA9IG5hbWUpICU+JQogIHJlbG9jYXRlKFNhbXBsZSkgJT4lIAogICMgcmVtb3ZlIEcyIGFzIGl0IG1vc3QgbGlrZWx5IGhhZCBtdWx0aXBsZSBQSE81cHItbUNoZXJyeSBpbnRlZ3JhdGVkIGFuZCAKICAjIGNhdXNlcyB0aGUgcmVzdCBvZiB0aGUgUkZQIGRhdGEgdG8gYmUgY29tcHJlc3NlZAogIGZpbHRlcihTYW1wbGUgIT0gIkcyIikKZGF0IDwtIG11dGF0ZSgKICBkYXQsCiAgUGhvNEdGUCA9IGZhY3RvcihQaG80R0ZQLCAKICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoIk5vLUdGUCIsIlNjUGhvNC1tTmVvbiIsIlNjUGhvNC1FR0ZQIiwgIkNnUGhvNC1tTmVvbiIpKSwgCiAgR3JvdXAgPSBmYWN0b3IoR3JvdXAsIAogICAgICAgICAgICAgICAgIGxldmVscyA9IGMoImNvbnRyb2wiLCAiZW5kb2dlbm91cyIsICJleG9nZW5vdXMiLCAicGxhc21pZCIpLAogICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIm5vIEdGUCIsICJwaG80OjpQaG80LUdGUCIsICJsZXUyOjpQaG80LUdGUCIsICJwbGFzbWlkIikpCikKaXNzdWVzIDwtIGMoIkczIiwiQjMiLCJDMSIsIkMyIiwiRDEiLCJFMyIpICMgc2VlIGJlbG93IGZvciByZWFzb25zCmBgYAoKTG9va2luZyBhdCB0aGUgZGV0YWlsZWQgcGxvdHMsIEkgaWRlbnRpZmllZCBhIGZldyBzYW1wbGVzIHRoYXQgYXJlIHByb2JsZW1hdGljLgoKfCB8IHwgfCB8Cnw6LS06fDotLTp8Oi0tOnw6LS06fAp8IGxhY2sgX1BITzVwci1tQ2hlcnJ5XyB8IHR3byBwb3B1bGF0aW9ucyB8IHRvbyBmZXcgY2VsbHMgY29sbGVjdGVkIHwKfCAhW10oLi9pbWcvQjMucG5nKSB8ICFbXSguL2ltZy9DMS5wbmcpIHwgIVtdKC4vaW1nL0MyLnBuZykgfAp8IHR3byBwb3B1bGF0aW9ucyB8IHR3byBwb3B1bGF0aW9ucyB8IHR3byBwb3B1bGF0aW9ucyB8CnwgIVtdKC4vaW1nL0QxLnBuZykgfCAhW10oLi9pbWcvRTMucG5nKSB8ICFbXSguL2ltZy9HMy5wbmcpIHwKIAo+IEluIHRoZSBGbG93Q29yZSBhbmFseXNpcywgSSBub3cgZml4ZWQgc29tZSBvZiB0aGVtIHVzaW5nIGEgY2x1c3RlciBnYXRlLgo+IEMxLCBEMSBhbmQgRTMgc2hvdWxkIG5vdyByZXByZXNlbnQgYSBob21vZ2Vub3VzIHBvcHVsYXRpb24uCgojIyMgUGhvNC1HRlAgZXhwcmVzc2lvbiBsZXZlbHMKRmlyc3QgbG9vayBhdCB0aGUgbGV2ZWwgb2YgUGhvNC1HRlAgY29tcGFyZWQgd2l0aCB0aGUgbmVnYXRpdmUgY29udHJvbHMuCmBgYHtyLCBlY2hvID0gRiwgZmlnLmhlaWdodCA9IDYsIGZpZy53aWR0aCA9IDZ9CmdmcC5iZyA8LSBkYXQgJT4lIGZpbHRlcihQaG80R0ZQID09ICJOby1HRlAiKSAlPiUgcHVsbChCTDEuSCkgJT4lIG1lYW4oKQpwMSA8LSBkYXQgJT4lIAogIG11dGF0ZShTYW1wbGUgPSBpZmVsc2UoUEhPMiA9PSAicGhvMi0iLCBwYXN0ZSgiKiIsIFNhbXBsZSksIFNhbXBsZSkpICU+JQogIGdncGxvdChhZXMoeCA9IFNhbXBsZSwgeSA9IEJMMS5ILCBmaWxsID0gIEdyb3VwKSkgKyAKICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZTIod2lkdGggPSAwLjkpKSArCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gZ2ZwLmJnLCBsaW5ldHlwZSA9ICJkYXNoZWQiLCBhbHBoYSA9IDAuNikgKwogIGZhY2V0X2dyaWQoUGhvNEdGUH4uLCBzY2FsZXMgPSAiZnJlZV95Iiwgc3BhY2UgPSAiZnJlZV95IikgKwogIHNjYWxlX2ZpbGxfYnJld2VyKCJQaG80LUdGUCBzb3VyY2UiLCB0eXBlID0gImRpdiIsIGRyb3AgPSBGQUxTRSkgKyAKICBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygwLE5BKSwgZXhwYW5kID0gYygwLjAxLDApKSArCiAgY29vcmRfZmxpcCgpICsgCiAgdGhlbWVfYncoKSArCiAgbGFicyh0aXRsZSA9ICJHRlAgZmx1b3Jlc2NlbnQgaW50ZW5zaXR5IChhcmJpdHJhcnkgdW5pdHMpIiwgCiAgICAgICBzdWJ0aXRsZSA9ICJkYXNoZWQgbGluZSBpbmRpY2F0ZXMgYmFja2dyb3VuZCBmbHVvcmVzY2VuY2UiLCAKICAgICAgIHggPSAiU2FtcGxlICgqID0gcGhvMi0pIiwKICAgICAgIHkgPSAiR0ZQIEludGVuc2l0eSAoYS51LikiKQoKcDEKZ2dzYXZlKCJpbWcvMjAyMDEyMjMtUGhvNC1HRlAtbGV2ZWxzLnBuZyIsIHdpZHRoID0gNSwgaGVpZ2h0ID0gNikKYGBgCioqRmlndXJlIDEgUGhvNC1HRlAgaW50ZW5zaXR5IGJ5IHN0cmFpbi4qKiBQaG80LUdGUCBpbnRlbnNpdGllcyB3ZXJlIHF1YW50aWZpZWQgb24gYW4gQXR0dW5lIE54VCBmbG93IGN5dG9tZXRlciB1c2luZyA0MDAgbVYgb24gdGhlIEJMMSBjaGFubmVsLiBBY3F1aXNpdGlvbiByYXRlIGlzIDIwMCB1bC9taW4uIEF0IGxlYXN0IDEwLDAwMCBldmVudHMgd2VyZSBjb2xsZWN0ZWQgYW5kIHRoZSBtZWRpYW4gZmx1b3Jlc2NlbnQgaW50ZW5zaXR5IChNRkksIGFyYml0cmFyeSB1bml0cykgd2VyZSBwcmVzZW50ZWQgb24gdGhlIHgtYXhpcywgd2hpbGUgc3RyYWluIElEcyBhcmUgbGlzdGVkIG9uIHRoZSB2ZXJ0aWNhbCBheGlzLiBBbiBhc3RlcmlzayBuZXh0IHRvIGEgYmFyIGluZGljYXRlcyBpc3N1ZXMgZm91bmQgd2l0aCB0aGUgc2FtcGxlIChzZWUgbWV0aG9kcyBzZWN0aW9uIGZvciBkZXRhaWxzKS4KCl9EaXNjdXNzaW9uXwoKLSBTb21ld2hhdCBzdXJwcmlzaW5nIHRvIG1lLCB0aGUgZXhvZ2Vub3VzbHkgaW50ZWdyYXRlZCBQaG80LUdGUCwgZXhjZXB0IGZvciB0aGUgU2NQaG80LW1OZW9uLCBzZWVtIHRvIGhhdmUgcmF0aGVyIGxvdyBmbHVvcmVzY2VudCBpbnRlbnNpdHkuIEZvciBleGFtcGxlLCBGMSwgRTIgYW5kIEUzIGFsbCBoYXZlIHZlcnkgbG93IEdGUCBzaWduYWxzLgotIExhc3QgdGltZSAoc2VlIFsyMDIwLTEyLTIxIHJlcG9ydF0oaHR0cHM6Ly9ycHVicy5jb20vZW1wdHloYi9QaG80LUdGUC10ZXN0LTIwMjAxMjIxKSkgSSBvYnNlcnZlZCBoaWdoZXIgU2NQaG80LW1OZW9uIGFuZCBTY1BobzQtRUdGUCBleHByZXNzaW9uIGluIHRoZSB5SDI5NSBiYWNrZ3JvdW5kIChQLCBRKSB0aGFuIGluIHRoZSB5SDI5NiBiYWNrZ3JvdW5kIChNLCBOKS4gSSBzdXNwZWN0ZWQgdGhlcmUgbWF5IGJlIHNvbWUgZmVlZGJhY2sgZHVlIHRvIHRoZSBsYWNrIG9mIFBobzIuIFRoaXMgdGltZSBob3dldmVyLCB0aGVpciBleHByZXNzaW9uIGxldmVscyBhcHBlYXIgdG8gYmUgdGhlIHNhbWUuIFRoZSBtYWluIGRpZmZlcmVuY2UgaW4gdGhlIGV4cGVyaW1lbnRhbCBwcm90b2NvbCBjb21wYXJlZCB0byB0aGUgbGFzdCB0aW1lIGlzIHRoYXQgSSBkaWQgb25lIG8vbiBncm93dGggYmVmb3JlIHRoZSBmaW5hbCBncm93dGggaW5zdGVhZCBvZiB0d28uCgojIyMgUEhPNXByLW1DaGVycnkgcmVwb3J0ZXIgbGV2ZWxzCmBgYHtyLCBmaWcuaGVpZ2h0ID0gNywgZmlnLndpZHRoID0gN30KI3JmcC5iZyA8LSBtZWFuKGRhdCAlPiUgZmlsdGVyKCFQSE81UkZQKSAlPiUgcHVsbChZTDIuSCkpCiMgZGlkbid0IGluY2x1ZGUgYSBuZWdhdGl2ZSBjb250cm9sIGZvciBubyBSRlAuIGZyb20gcHJlaXZvdXMgcnVucywgd2Uga25vdycKIyB0aGUgYmFja2dyb3VuZCBmb3IgUkZQIGlzIGV4dHJlbWVseSBsb3cgKH4xMDApLCBhbmQgdGh1cyBjYW4gYmUgc2FmZWx5IGlnbm9yZWQKcmZwLmJhc2FsIDwtIGRhdCAlPiUgZmlsdGVyKFNhbXBsZSAlaW4lIGMoInlIMjk1IiwgInlIMjk2IikpICU+JSBwdWxsKFlMMi5IKSAlPiUgbWVhbigpCgojIHJlbW92ZWQgYSBmZXcgb3V0bGllcnMgd2l0aCBNRkkgPiAyMGsKcDIgPC0gZGF0ICU+JSAjZmlsdGVyKFBITzVSRlApICU+JSAKICBzZWxlY3QoU2FtcGxlLCBHcm91cCwgUGhvNEdGUCwgUEhPMiwgQkwxLkgsIFlMMi5IKSAlPiUgCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKEJMMS5ILCBZTDIuSCksCiAgICAgICAgICAgICAgIG5hbWVzX3RvID0gIlBhcmFtZXRlciIsIHZhbHVlc190byA9ICJNZWRpYW4iKSAlPiUgCiAgbXV0YXRlKFBhcmFtZXRlciA9IGZhY3RvcihQYXJhbWV0ZXIsIGxldmVscyA9IGMoIkJMMS5IIiwgIllMMi5IIiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiUGhvNC1HRlAiLCAiUEhPNS1SRlAiKSksCiAgICAgICAgIFNhbXBsZSA9IGlmZWxzZShQSE8yID09ICJwaG8yLSIsIHBhc3RlKCIqIiwgU2FtcGxlKSwgU2FtcGxlKSkgJT4lCiAgZ2dwbG90KGFlcyh4ID0gU2FtcGxlLCB5ID0gTWVkaWFuLCBmaWxsID0gIEdyb3VwKSkgKyAKICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZTIod2lkdGggPSAwLjkpKSArCiAgZ2VvbV9obGluZShhZXMoeWludGVyY2VwdCA9IGlmZWxzZShQYXJhbWV0ZXIgPT0gIlBobzQtR0ZQIiwgZ2ZwLmJnLCByZnAuYmFzYWwpKSwgbGluZXR5cGUgPSAyLCBhbHBoYSA9IDAuNikgKwogIGZhY2V0X2dyaWQoUGhvNEdGUCB+IFBhcmFtZXRlciwgc2NhbGVzID0gImZyZWUiLCBzcGFjZSA9ICJmcmVlX3kiKSArIAogIHhsYWIoIlNhbXBsZSAoKiA9IHBobzItKSIpICsgeWxhYigiTWVkaWFuIEZsdW9yZXNjZW50IEludGVuc2l0eSAoYS51LikiKSArCiAgc2NhbGVfZmlsbF9icmV3ZXIoIlBobzQtR0ZQIHNvdXJjZSIsIHR5cGUgPSAiZGl2IiwgZHJvcCA9IEZBTFNFKSArICNzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygicmVkIiwgTkEpKSArCiAgY29vcmRfZmxpcCgpICsgc2NhbGVfeV9jb250aW51b3VzKGV4cGFuZCA9IGMoMC4wMSwwLjAyKSkgKwogIHRoZW1lX2J3KCkKcDIKZ2dzYXZlKCJpbWcvMjAyMDEyMjMtUGhvNC1HRlAtUEhPNVJGUC1sZXZlbHMucG5nIiwgd2lkdGggPSA2LCBoZWlnaHQgPSA2KQpgYGAKKipGaWd1cmUgMiBDb3JyZXNwb25kaW5nIFBobzQtR0ZQIGFuZCBQSE81cHItbUNoZXJyeSByZXBvcnRlciBmbHVvcmVzY2VuY2UgaW50ZW5zaXR5IHBlciBzdHJhaW4uKiogUGhvNC1HRlAgYW5kIFBITzVwLW1DaGVycnkgaW50ZW5zaXRpZXMgd2VyZSBxdWFudGlmaWVkIG9uIGFuIEF0dHVuZSBOeFQgZmxvdyBjeXRvbWV0ZXIgdXNpbmcgNDAwIG1WIG9uIHRoZSBCTDEgYW5kIDQzMCBtViBvbiB0aGUgWUwyIGNoYW5uZWxzIHJlc3BlY3RpdmVseS4gQWNxdWlzaXRpb24gcmF0ZSBpcyAyMDAgdWwvbWluLiBBdCBsZWFzdCAxMCwwMDAgZXZlbnRzIHdlcmUgY29sbGVjdGVkLiBTdHJhaW4gSURzIGFyZSBsaXN0ZWQgb24gdGhlIHZlcnRpY2FsIGF4aXMgYW5kIHRoZSBNZWRpYW4gRmx1b3Jlc2NlbnQgSW50ZW5zaXR5IChNRkksIGFyYml0dXJ5IHVuaXRzKSBmb3IgZWFjaCBjaGFubmVsIG9uIHRoZSBob3Jpem9udGFsIGF4aXMuIEFuIGFzdGVyaXNrIG5leHQgdG8gYSBiYXIgaW5kaWNhdGVzIGFuIG92ZXJuaWdodCBncm93dGggaW5zdGVhZCBvZiBhIG1pZC1sb2cgcGhhc2UgZ3Jvd3RoIHdhcyB1c2VkIGZvciBxdWFudGlmaWNhdGlvbi4gVGhlIGRhc2hlZCB2ZXJ0aWNhbCBsaW5lIGZvciBQaG80LUdGUCBpbmRpY2F0ZXMgdGhlIGF1dG9mbHVvcmVzY2VuY2UgYXMgY2FsY3VsYXRlZCBieSB0aGUgbWVhbiBvZiB0aGUgaW50ZW5zaXRpZXMgaW4gdGhlIHN0cmFpbnMgd2l0aG91dCBHRlA7IHRoZSBkYXNoZWQgdmVydGljYWwgbGluZSBmb3IgdGhlIFJGUCBwbG90IGluZGljYXRlcyB0aGUgYmFzYWwgbGV2ZWwgZXhwcmVzc2lvbiBmcm9tIHRoZSByZXBvcnRlciB3aXRob3V0IFBobzQsIGNhbGN1bGF0ZWQgYnkgdGhlIGF2ZXJhZ2Ugb2YgeUgyOTUgYW5kIHlIMjk2LCBib3RoIG9mIHdoaWNoIGxhY2sgUGhvNCBidXQgaGFzIHRoZSByZXBvcnRlcikuIEFuIGFzdGVyaXNrIG5leHQgdG8gYSBiYXIgaW5kaWNhdGVzIGlzc3VlcyBmb3VuZCB3aXRoIHRoZSBzYW1wbGUgKHNlZSBtZXRob2RzIHNlY3Rpb24gZm9yIGRldGFpbHMpLgoKX0Rpc2N1c3Npb25fCgotIFRoaXMgZXhwZXJpbWVudCBzaG93ZWQgYSBsb3Qgb2YgdmFyaWFiaWxpdHkgYW1vbmcgdGhlIGJpb2xvZ2ljYWwgcmVwbGljYXRlcywgZXNwZWNpYWxseSBmb3IgZXhvZ2Vub3VzbHkgaW50ZWdyYXRlZCBDZ1BobzQgKEMgYW5kIEYpLiBUaGlzIHdhc24ndCB0aGUgY2FzZSBpbiBteSBwcmV2aW91cyBleHBlcmltZW50LiBJdCB3aWxsIGJlIHVzZWZ1bCB0byByZXBlYXQgdGhpcyBhZ2Fpbi4KLSB5SDI2NyBkb2Vzbid0IGNvbmZvcm0gdG8gbXkgZXhwZWN0YXRpb24gLS0gaXQgaGFzIFNjUGhvNCBhbmQgU2NQaG8yIGFzIHdlbGwgYXMgdGhlIF9QSE81cHItbUNoZXJyeV8gcmVwb3J0ZXIsIGFuZCB0aHVzIHNob3VsZCBnaXZlIG5vcm1hbCBsZXZlbHMgb2YgUkZQLCBidXQgZGlkbid0LgoKIyMjIF9QSE81cHItbUNoZXJyeV8gaW5kdWN0aW9uIGxldmVscyBub3JtYWxpemVkIGJ5IFBobzQgYWJ1bmRhbmNlCldlIHdpbGwgZmlyc3QgdHJhbnNmb3JtIHRoZSByYXcgR0ZQIGFuZCBSRlAgaW50ZW5zaXRpZXMgdG8gbWFrZSB0aGVtIG1vcmUgaW50ZXJwcmV0YWJsZS4gRm9yIHRoZSBHRlAgaW50ZW5zaXR5LCBhcyB0aGVyZSBpcyBhIHN1YnN0YW50aWFsIGJhY2tncm91bmQsIHdlIHdpbGwgc3VidHJhY3QgdGhlIGJhY2tncm91bmQgZnJvbSBhbGwgdGhlIEdGUC1jb250YWluaW5nIHN0cmFpbnMgdG8gb2J0YWluIHRoZSBtZWFuaW5nZnVsIG1lYXN1cmUgZm9yIFBobzQgcHJvdGVpbiBsZXZlbHMuIEZvciBSRlAsIHRoZXJlIGlzIG1pbmltYWwgYmFja2dyb3VuZCAoc2VlIGJlbG93KS4gSG93ZXZlciwgdGhlcmUgaXMgYSAiYmFzYWwiIGV4cHJlc3Npb24gb2YgdGhlIHJlcG9ydGVyIGluIHRoZSBhYnNlbmNlIG9mIFBobzQgLS0gd2hhdCB3ZSBhcmUgaW50ZXJlc3RlZCBpbiBpcyBub3QgdGhlIGFic29sdXRlIGxldmVsIG9mIHJlcG9ydGVyIGV4cHJlc3Npb24gYnV0IHRoZSBmb2xkIGluZHVjdGlvbiBjb21wYXJlZCB3aXRoIHRoZSBfcGhvNOKIhl8gc3RyYWlucy4KYGBge3IgdHJhbnNmb3JtfQojIHRyYW5zZm9ybQpkYXQxIDwtIGRhdCAlPiUKICAjIHJlbW92ZSB0aGUgY29udHJvbCBncm91cHMgYXMgd2UgbmVlZCB0byBjYWxjdWxhdGUgUi9HCiAgZmlsdGVyKEdyb3VwICE9ICJubyBHRlAiKSAlPiUgCiAgbXV0YXRlKCNHRlAubm9CRyA9IGlmZWxzZShQaG80R0ZQID09ICJOby1HRlAiLCBOQSwgYFBobzQtR0ZQYCAtIGdmcC5iZyksCiAgICAjUkZQLm5vQkcgPSBpZmVsc2UoUEhPNVJGUCwgYFBITzVwci1tQ2hlcnJ5YCAtIHJmcC5iZywgMCksCiAgICAjUkZQLkZDID0gaWZlbHNlKFBITzVSRlAsIFJGUC5ub0JHIC8gcmZwLmJhc2FsLCBOQSksCiAgICAjblJGUC5GQyA9IFJGUC5GQyAvIEdGUC5ub0JHICogbWVkaWFuKEdGUC5ub0JHLCBuYS5ybSA9IFQpKQogICAgR0ZQLm5vQkcgPSBCTDEuSCAtIGdmcC5iZywKICAgIEdGUC5ub0JHID0gaWZlbHNlKEdGUC5ub0JHID4gMCwgR0ZQLm5vQkcsIE5BKSwKICAgIFJGUC5ub0JHID0gWUwyLkgsICMgLSByZnAuYmcsCiAgICBSRlAuRkMgPSBSRlAubm9CRyAvIHJmcC5iYXNhbCwKICAgIFJ2RyA9IFJGUC5ub0JHIC8gR0ZQLm5vQkcKICApCmBgYAoKYGBge3IgcGxvdF9ub3JtYWxpemVkX2luZHVjdGlvbiwgZmlnLmhlaWdodCA9IDcsIGZpZy53aWR0aD0xMCwgd2FybmluZz1GQUxTRX0KcDMgPC0gZGF0MSAlPiUgCiAgbXV0YXRlKEdGUC5ub0JHID0gR0ZQLm5vQkcgLyAxMDAwLCBSRlAubm9CRyA9IFJGUC5ub0JHIC8gMTAwMCkgJT4lIAogIHBpdm90X2xvbmdlcihjb2xzID0gYyhHRlAubm9CRywgUkZQLm5vQkcpLCBuYW1lc190byA9ICJQYXJhbWV0ZXIiLCB2YWx1ZXNfdG8gPSAiVmFsdWUiKSAlPiUKICBtdXRhdGUoUGFyYW1ldGVyID0gZmFjdG9yKFBhcmFtZXRlciwgbGV2ZWxzID0gYygiR0ZQLm5vQkciLCAiUkZQLm5vQkciKSwgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiUGhvNC1HRlAgbm9CRyIsICJQSE81cHItUkZQIG5vQkciKSksCiAgICAgICAgIFNhbXBsZSA9IGlmZWxzZShQSE8yID09ICJwaG8yLSIsIHBhc3RlKCIqIiwgU2FtcGxlKSwgU2FtcGxlKSkgJT4lIAogIGdncGxvdChhZXMoeCA9IFNhbXBsZSwgeSA9IFZhbHVlLCBmaWxsID0gIEdyb3VwKSkgKyAKICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZTIod2lkdGggPSAwLjkpKSArCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IGlmZWxzZShTYW1wbGUgJWluJSBpc3N1ZXMsICIqIiwgIiIpLCBoanVzdCA9IC0wLjIsIHZqdXN0ID0gMC44KSwgY29sb3IgPSAiYmxhY2siLCBzaXplID0gNSkgKwogIGZhY2V0X2dyaWQoUGhvNEdGUCB+IFBhcmFtZXRlciwgc2NhbGVzID0gImZyZWUiLCBzcGFjZSA9ICJmcmVlX3kiKSArCiAgc2NhbGVfZmlsbF9icmV3ZXIoIlBobzQtR0ZQIHNvdXJjZSIsIHR5cGUgPSAiZGl2IiwgZHJvcCA9IEZBTFNFKSArIAogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCJyZWQiLCBOQSkpICsKICBjb29yZF9mbGlwKCkgKyBzY2FsZV95X2NvbnRpbnVvdXMoZXhwYW5kID0gYygwLjAxLDAuMDIpKSArIAogIHhsYWIoIlNhbXBsZSAoKiA9IHBobzItKSIpICsgCiAgeWxhYigiTWVkaWFuIEZsdW9yZXNjZW50IEludGVuc2l0eSAoLWJhY2tncm91bmRkKSIpICsKICB0aGVtZV9idygpCiAgCnA0IDwtIGRhdDEgJT4lIAogIHBpdm90X2xvbmdlcihjb2xzID0gYyhSRlAuRkMsIFJ2RyksIG5hbWVzX3RvID0gIlBhcmFtZXRlciIsIHZhbHVlc190byA9ICJWYWx1ZSIpICU+JQogIG11dGF0ZShQYXJhbWV0ZXIgPSBmYWN0b3IoUGFyYW1ldGVyLCBsZXZlbHMgPSBjKCJSRlAuRkMiLCAiUnZHIiksIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiUEhPNSBmb2xkIGluZHVjdGlvbiIsICJQSE81LVJGUCAvIFBobzQtR0ZQIikpLAogICAgICAgICBTYW1wbGUgPSBpZmVsc2UoUEhPMiA9PSAicGhvMi0iLCBwYXN0ZSgiKiIsIFNhbXBsZSksIFNhbXBsZSkpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBTYW1wbGUsIHkgPSBWYWx1ZSwgZmlsbCA9ICBHcm91cCkpICsgCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UyKHdpZHRoID0gMC45KSkgKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDEsIGxpbmV0eXBlID0gMikgKwogIGdlb21fdGV4dChhZXMobGFiZWwgPSBpZmVsc2UoU2FtcGxlICVpbiUgaXNzdWVzLCAiKiIsICIiKSwgaGp1c3QgPSAtMC4yLCB2anVzdCA9IDAuOCksIGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDUpICsKICBmYWNldF9ncmlkKFBobzRHRlAgfiBQYXJhbWV0ZXIsIHNjYWxlcyA9ICJmcmVlIiwgc3BhY2UgPSAiZnJlZV95IikgKwogIHNjYWxlX2ZpbGxfYnJld2VyKCJQaG80LUdGUCBzb3VyY2UiLCB0eXBlID0gImRpdiIsIGRyb3AgPSBGKSArICNzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gYygicmVkIiwgTkEpKSArCiAgY29vcmRfZmxpcCgpICsgc2NhbGVfeV9jb250aW51b3VzKGV4cGFuZCA9IGMoMC4wMSwwLjAyKSkgKyAKICB5bGFiKE5VTEwpICsgeGxhYigiIikgKwogIHRoZW1lX2J3KCkKCiMjIHBsYWNlIHNoYXJlZCBsZWdlbmQgYXQgdGhlIGJvdHRvbQojIyByZWZlcmVuY2U6IGh0dHBzOi8vd2lsa2VsYWIub3JnL2Nvd3Bsb3QvYXJ0aWNsZXMvc2hhcmVkX2xlZ2VuZHMuaHRtbApsZWdlbmQgPC0gZ2V0X2xlZ2VuZCgKICBwMSArIAogIGd1aWRlcyhjb2xvciA9IGd1aWRlX2xlZ2VuZChucm93ID0gMSksIGZpbGwgPSBndWlkZV9sZWdlbmQobnJvdyA9IDEpKSArCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gImJvdHRvbSIpCikKcHJvdyA8LSBwbG90X2dyaWQoCiAgcDMgKyB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSwKICBwNCArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpLAogIGFsaWduID0gJ3ZoJywKICBsYWJlbHMgPSBjKCJBIiwgIkIiLCAiQyIpLAogIGhqdXN0ID0gLTEsCiAgbnJvdyA9IDEKKQpwbG90X2dyaWQocHJvdywgbGVnZW5kLCBuY29sID0gMSwgcmVsX2hlaWdodHMgPSBjKDEsIC4xKSkKYGBgCioqRmlndXJlIDMgQ29tcG9zaXRlIHBsb3QgaW5jbHVkaW5nIFBobzQgYWJ1bmRhbmNlLCBfUEhPNV8gcmVwb3J0ZXIgc3RyZW5ndGggYW5kIGZvbGQgaW5kdWN0aW9uIHZhbHVlcy4qKiBQaG80LUdGUCBhbmQgUEhPNXAtbUNoZXJyeSBpbnRlbnNpdGllcyB3ZXJlIHF1YW50aWZpZWQgYXMgZGVmaW5lZCBhYm92ZS4gU3RyYWluIElEcyBhcmUgbGlzdGVkIG9uIHRoZSB2ZXJ0aWNhbCBheGlzLiBJbiAqKihBKSoqLCB0aGUgeC1heGlzIHZhbHVlcyByZXByZXNlbnQgdGhlIE1lZGlhbiBGbHVvcmVzY2VudCBJbnRlbnNpdHkgKE1GSSwgYXJiaXR1cnkgdW5pdHMpIGZvciBlaXRoZXIgUGhvNC1HRlAgb3IgUEhPNXByLW1DaGVycnkuIEZvciBQaG80LUdGUCwgdGhlIGJhY2tncm91bmQgbGV2ZWwgYmFzZWQgb24gc3RyYWlucyB3aXRob3V0IFBobzQtR0ZQIHdhcyBzdWJ0cmFjdGVkLiBObyBiYWNrZ3JvdW5kIHN1YnRyYWN0aW9uIHdhcyBkb25lIGZvciBtQ2hlcnJ5LCBidXQgcGFzdCByZXN1bHRzIHN1Z2dlc3QgdGhhdCB0aGUgYmFja2dyb3VuZCBmbHVvcmVzY2VuY2UgaXMgbmVnbGVnaWJsZSByZWxhdGl2ZSB0byB0aGUgcG9zaXRpdmUgc3RyYWlucy4gSW4gKiooQikqKiwgdGhlIGZvbGQgY2hhbmdlIGZvciBfUEhPNV8gcmVwb3J0ZXIgaXMgY2FsY3VsYXRlZCBhcyB0aGUgYmFja2dyb3VuZC1zdWJ0cmFjdGVkIFJGUCBsZXZlbCBkaXZpZGVkIGJ5IHRoZSBiYXNhbCBleHByZXNzaW9uIGxldmVsLCBhcyBtZWFzdXJlZCBieSB0aGUgbWVhbiBvZiB0aGUgdHdvIHN0cmFpbnMgY29udGFpbmluZyB0aGUgcmVwb3J0ZXIgYnV0IGhhdmUgX3BobzTiiIZfLiBUaGUgbm9ybWFsaXplZCBpbmR1Y3Rpb24gcmF0aW8gb24gdGhlIHJpZ2h0IGNvbHVtbiBpcyBjYWxjdWxhdGVkIGJ5IGRpdmlkaW5nIHRoZSBpbmR1Y3Rpb24gZm9sZCBjaGFuZ2UgZnJvbSB0aGUgbGVmdCBjb2x1bW4gYnkgdGhlIGNvcnJlc3BvbmRpbmcgUGhvNC1HRlAgKGJhY2tncm91bmQgc3VidHJhY3RlZCkgbGV2ZWxzIGFuZCBtdWx0aXBsaWVkIGJ5IHRoZSBtZWRpYW4gUGhvNC1HRlAgbGV2ZWxzIG9mIGFsbCBzdHJhaW5zLiBUaGUgZGFzaGVkIGxpbmVzIGluIGJvdGggY29sdW1ucyBpbmRpY2F0ZSB0aGUgaW5kdWN0aW9uIGZvbGQgY2hhbmdlIG9mIDEsIGkuZS4gbm8gY2hhbmdlIGNvbXBhcmVkIHRvIHRoZSBfcGhvNOKIhl8gc3RyYWlucy4gSW4gYm90aCBwYW5lbHMsIHRoZSB4LWF4ZXMgYXJlIHNxdWFyZS1yb290IHRyYW5zZm9ybWVkIHNvIGFzIHRvIGJyaW5nIG91dGxpZXJzIGludG8gdGhlIHBsb3Qgd2l0aG91dCBjb21wcmVzc2luZyB0aGUgcmVzdCBvZiB0aGUgZGF0YSByYW5nZS4gQW4gYXN0ZXJpc2sgbmV4dCB0byBhIGJhciBpbmRpY2F0ZXMgYW4gb3Zlcm5pZ2h0IGdyb3d0aCBpbnN0ZWFkIG9mIGEgbWlkLWxvZyBwaGFzZSBncm93dGggd2FzIHVzZWQgZm9yIHF1YW50aWZpY2F0aW9uLiBBbiBhc3RlcmlzayBuZXh0IHRvIGEgYmFyIGluZGljYXRlcyBpc3N1ZXMgZm91bmQgd2l0aCB0aGUgc2FtcGxlIChzZWUgbWV0aG9kcyBzZWN0aW9uIGZvciBkZXRhaWxzKS4KCl9EaXNjdXNzaW9uXwoKLSBQbGFzbWlkLWJvcm4gUGhvNC1HRlAgc3RyYWlucyBzaG93IG1vcmUgdmFyaWFiaWxpdHkgaW4gUGhvNCBhYnVuZGFuY2UsIGJ1dCB5aWVsZHMgcXVpdGUgY29uc2lzdGVudCBmb2xkIGluZHVjdGlvbiB2YWx1ZXMgYWZ0ZXIgbm9ybWFsaXppbmcgYnkgdGhlIEdGUCBpbnRlbnNpdHkuIFNvbWUgaXNzdWVzIGRvIGV4aXN0LCBlLmcuIFExLCBRMi4gQjIgYW5kIEI0J3MgYWJub3JtYWxseSBoaWdoIGluZHVjdGlvbiBhZnRlciBub3JtYWxpemF0aW9uIGlzIGR1ZSB0byB0aGUgdmVyeSBsb3cgR0ZQIGludGVuc2l0eS4KLSBUaGUgZXhvZ2Vub3VzbHkgaW50ZWdyYXRlZCBzdHJhaW5zIHNob3cgbW9yZSB2YXJpYWJpbGl0eSwgbGlrZWx5IGR1ZSB0byB0d28gcmVhc29uczogbXVsdGlwbGUtaW50ZWdyYXRpb24gYXQgdGhlIHRpbWUgb2YgdHJhbnNmb3JtYXRpb24gYW5kIHNwb250YW5lb3VzIGxvb3Atb3V0IGxlYWRpbmcgdG8gbG9zcyBvZiB0aGUgZXh0cmEgY29waWVzIGR1cmluZyB0aGUgb3V0Z3Jvd3RoIChvciBldmVuIG9uIHRoZSBwbGF0ZXMpCi0gQmFzZWQgb24gbGltaXRlZCBkYXRhLCB0aGUgZW5kb2dlbm91c2x5IGludGVncmF0ZWQgUGhvNC1HRlAgaGFzIHRoZSBsb3dlc3QgY2xvbmUtdG8tY2xvbmUgdmFyaWFiaWxpdHkuIElmIHdlIGNvdWxkIG1ha2UgdGhlIHJlcG9ydGVyIGNvbnN0cnVjdCBhbHNvIGVuZG9nZW5vdXMsIHdlIHdvdWxkIGV4cGVjdCBoaWdobHkgcmVwcm9kdWNpYmxlIGRhdGEuCgojIyMgUGxvdCB2YXJpYXRpb25zClByZXNlbnQgdGhlIGFib3ZlIHBsb3QgaW4gYSBkaWZmZXJlbnQgd2F5LgpgYGB7ciBwbG90X3ZhcmlhdGlvbiwgZmlnLmhlaWdodCA9IDUsIGZpZy53aWR0aD02fQpwZCA8LSBwb3NpdGlvbl9kb2RnZSgwLjkpCnRtcCA8LSBiaW5kX3Jvd3MoCiAgIlBobzQtR0ZQIChNRkkpIiA9IHNlbGVjdChkYXQsIFNhbXBsZSwgR3JvdXAsIFBobzRHRlAsIFBITzIsIFZhbHVlID0gQkwxLkgpLAogICJQSE81LVJGUCAvIFBobzQtR0ZQIiA9IHNlbGVjdChkYXQxLCBTYW1wbGUsIEdyb3VwLCBQaG80R0ZQLCBQSE8yLCBWYWx1ZSA9IFJ2RyksCiAgLmlkID0gIlBhcmFtZXRlciIKKQpwNSA8LSB0bXAgJT4lIAogIGdncGxvdChhZXMoeCA9IFBITzIsIHkgPSBWYWx1ZSwgZ3JvdXAgPSBHcm91cCkpICsgCiAgc3RhdF9zdW1tYXJ5KGFlcyhmaWxsID0gR3JvdXApLCBnZW9tID0gImNyb3NzYmFyIiwgCiAgICAgICAgICAgICAgIGZ1bi5kYXRhID0gIm1lYW5fc2RsIiwgZnVuLmFyZ3MgPSBsaXN0KG11bHQgPSAxKSwgCiAgICAgICAgICAgICAgIHBvc2l0aW9uID0gcGQsIGxpbmV3aWR0aCA9IDAuMiwgd2lkdGggPSAwLjUpICsKICBnZW9tX3BvaW50KHNoYXBlID0gMjEsIHNpemUgPSAxLCBwb3NpdGlvbiA9IHBkLCBjb2xvciA9ICJncmF5MjAiLCBmaWxsID0gIndoaXRlIikgKwogICNnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSBnZnAuYmcsIGxpbmV0eXBlID0gImRhc2hlZCIsIGFscGhhID0gMC42KSArCiAgZmFjZXRfZ3JpZChQaG80R0ZQIH4gUGFyYW1ldGVyLCBzY2FsZXMgPSAiZnJlZSIsIHNwYWNlID0gImZyZWVfeSIpICsKICBzY2FsZV9maWxsX2JyZXdlcigiUGhvNC1HRlAgc291cmNlIiwgdHlwZSA9ICJkaXYiLCBkcm9wID0gRkFMU0UsCiAgICAgICAgICAgICAgICAgICAgYnJlYWtzID0gYygibm8gR0ZQIiwgImxldTI6OlBobzQtR0ZQIiwgInBsYXNtaWQiKSkgKyAKICAjc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoMCxOQSksIGV4cGFuZCA9IGMoMC4wMSwwKSkgKwogIGNvb3JkX2ZsaXAoKSArICB0aGVtZV9idygpICsKICB0aGVtZShheGlzLnRpdGxlID0gZWxlbWVudF9ibGFuaygpLCBsZWdlbmQucG9zaXRpb24gPSAidG9wIikKcDUKZ2dzYXZlKCJpbWcvMjAyMDEyMjMtUGhvNC1HRlAtUnZHLWNyb3NzYmFyLnBuZyIsIHdpZHRoID0gNSwgaGVpZ2h0ID0gNikKYGBgCioqRmlndXJlIDQgVmFyaWFiaWxpdHkgaW4gUGhvNC1HRlAgaW50ZW5zaXR5IGFuZCBub3JtYWxpemVkIFBITzVSRlAgbGV2ZWxzIGJldHdlZW4gcGxhc21pZHMgYW5kIGludGVncmF0ZWQgUGhvNCoqIFRoZSBzYW1lIGRlZmluaXRpb25zIGZvciB0aGUgdHdvIHZhbHVlcyBhcyBhYm92ZS4gSGVyZSwgdGhlIGRpZmZlcmVudCBiaW9sb2dpY2FsIHJlcGxpY2F0ZXMgYXJlIHBsb3R0ZWQgYXMgZG90cy4gVGhlIGNyb3NzYmFyIHNob3dzIHRoZSBtZWFuIChtaWRkbGUgbGluZSkgYW5kIHN0YW5kYXJkIGRldmlhdGlvbiAoYm94KS4KCl9EaXNjdXNzaW9uc18KCi0gSXQncyBjbGVhciB0aGF0IHBsYXNtaWQtYm9ybiBQaG80IGhhcyBzbWFsbGVyIGJpb2xvZ2ljYWwgdmFyaWF0aW9uIHRoYW4gZXhvZ2Vub3VzbHkgaW50ZWdyYXRlZCBvbmVzLgoKIyMgQ29uY2x1c2lvbgotIElmIENSSVNQUiBjYW4gYm9vc3QgdGhlIGdlbmUgZWRpdGluZyBlZmZpY2llbmN5LCBwcmVmZXJzIHRoZSBlbmRvZ2Vub3VzIG1ldGhvZC4KLSBQbGFzbWlkIGlzIGEgdmlhYmxlIGFwcHJvYWNoIGZvciAxKSBxdWlja2x5IGFzc2Vzc2luZyB0aGUgcGhlbm90eXBlcyBvZiB0aGUgY29uc3RydWN0cyBhbmQgMikgYSBiYWNrdXAgc2hvdWxkIHRoZSBlbmRvZ2Vub3VzIGFwcHJvYWNoIGVuY291bnRlciB0ZWNobmljYWwgZGlmZmljdWx0aWVzLg==