Data import
dat0 <- read_csv("20210319-Bin-reanalyzed-chimera-test-1-results.csv")
── Column specification ─────────────────────────────────────────────────────────────────────
cols(
Group = col_character(),
Sample = col_character(),
Rep = col_double(),
Pho4 = col_character(),
Pho2 = col_character(),
Pho5RFP = col_character(),
FP = col_logical(),
Parameter = col_character(),
Count = col_double(),
Concentration = col_double(),
Perc_total = col_double(),
Median = col_double(),
CV = col_double(),
rCV = col_double()
)
Quality control
yLS_K and yJZ_B3, B4 each have one or more biological replicates that showed abnormal patterns on the FCS-H vs SSC-H – very few cells and a large number of small particles with high SSC-H and low FSC-H. See the last section of the knitted document.
ggplot(dat0, aes(x = Count, y = Concentration, shape = Pho2, color = Pho4)) +
geom_point(size = 2, alpha = 0.8) +
xlab("Total # of events recorded") + ylab("Concentration (events/s)") +
theme_cowplot() + background_grid() + panel_border()

Figure 1. Acquisition stats show a few samples undersampled and problematic. Concentration is measured by recorded events / second (y-axis) while total number of recorded events in the “singlet” gate is plotted on the x-axis. Samples are colored by the Pho4 genotype, and the shape reflects the status of Pho2 in the host strain. Lindsey and Jia’s samples are mixed.
Discussion
- First of all, it appears that Lindsey and Jia didn’t correctly set the acquisition stop criteria. I suspect that they let the acquisition to stop when the number of events reach 10,000, but didn’t set the population to the “singlet” gate. By default, the criteria will apply to ALL events.
- pH179 when transformed into the pho2∆ background appears to have trouble growing. We should consider changing the composition of the media to include additional adenine, since pho2∆ is sensitive to adenine deprivation. Also, it would be helpful to test and identify a media/growth condition in which the two host strains, with or without Pho2, grow roughly at the same rate.
- A separate issue is that the voltage for the FSC channel is probably too large (350 mV, vs 285 in my experiments). As can be seen in the plot below, many events were cutoff of the right boundary on the FSC-H axis. While those events may not be what we want to include (seems like they have much higher SSC, but not sure if the result will look the same after lowering the voltage), we should still try adjust the FSC voltage to “bring them inside the plot”.
Figure 2. Example plots demonstrating potentially too high voltage for FSC
Filter data
issues <- c("K-1","K-2","K-3","B3-1","B3-2","B3-3","B4-1") # see below for reasons
dat <- dat0 %>%
mutate(id = paste(Sample, Rep, sep = "-")) %>%
filter(!id %in% issues) %>%
select(-id)
Analysis
Pho4-GFP expression levels
First look at the background fluorescence level in the GFP channel
gfp.bg <- dat %>% filter(!FP, Parameter == "chimera-GFP-H") %>% pull(Median) %>% mean()
p0 <- dat %>%
filter(!FP, Parameter == "chimera-GFP-H") %>%
ggplot(aes(x = Sample, y = Median)) + geom_col(position = position_dodge()) +
geom_hline(yintercept = gfp.bg, linetype = "dashed", alpha = 0.6) +
labs(title = "Background GFP level") + ylab("MFI") + ylim(c(0, 6000)) +
theme_cowplot() + theme(axis.text.x = element_text(angle = 90),
plot.title = element_text(hjust = 0.5))
p0

Figure 3. Background GFP in strains with no mNeon. MFI: Median fluorescent intensity. Dotted line shows the average of all negative samples and will be used for background subtraction in later analyses.
It’s good to see that all the negative strains have the same level of background in the BL1 (GFP) channel. Unfortunately we didn’t include any strain that have strong RFP but no GFP so as to evaluate the spillover of the RFP signal into the GFP channel.
Next, we can examine the Pho4-GFP levels for the different contructs, in PHO2 or pho2∆ backgrounds, and transformed into two genetic backgrounds.
p1 <- dat %>% filter(FP, Parameter == "chimera-GFP-H") %>%
ggplot(aes(x = Pho4, y = Median, alpha = Group)) +
scale_alpha_discrete("User", range = c(0.5, 1)) +
geom_bar(aes(fill = Pho4), stat = "identity", position = position_dodge2()) +
stat_summary(fun = "mean", geom = "crossbar", colour = "red", size = 0.2,
position = position_dodge2(), show.legend = F) +
geom_hline(yintercept = gfp.bg, linetype = "dashed", alpha = 0.6) +
facet_wrap(~Pho2, nrow = 1, scales = "free_x") +
ylab("MFI") + scale_y_continuous(expand = expansion(mult = c(0.01,0.1))) +
labs(title = "GFP fluorescent intensity (arbitrary units)") +
theme_cowplot() + theme(axis.text.x = element_text(angle = 40, vjust = 1, hjust = 1))
Using alpha for a discrete variable is not advised.
p1

#left_col <- plot_grid(p0, NULL, nrow = 2, rel_heights = c(2,1))
#plot_grid(left_col, p1, ncol = 2, rel_widths = c(1,4))
Figure 4. Pho4-chimera abundance measured by mNeon fluorescent intensity. Dotted line indicates the background level of GFP. Each bar represents one biological replicate. Jia and Lindsey’s samples were grouped by the plasmid they contain and arranged side-by-side to show their similarity or difference. The red lines indicate the mean for each group.
Discussion
There is great variability among Pho4 chimeric constructs, where pH177 showed the highest expression level by fluorescent protein abundance
There appear to be more chimera protein in the pho2∆ background than in the PHO2 wild type background.
I’ve seen a similar picture in one of my previous experiments, but a repeat of that experiment didn’t reproduce the phenomenon.
While I initially suspected some sort of transcriptional feedback – somehow lack of Pho2 induces Pho4 to be more highly expressed – the lack of reproducibility in the second try made me think it could have to do with how PHO2 and pho2∆ strains grow. We know that Pho2 is also responsible for regulating de novo purine synthesis and as such, pho2∆ strains are extremely sensitive to purine deprivation.
What if we add additional adenine to our media for growing the strains (following the low autofluorescence media recipe perhaps)? One idea is to test a range of media with different concentrations of adenine and phosphate, and record growth curves for the PHO2 and pho2∆ strains, to determine if there is any difference in growth rate and hopefully identify a condition that shows no difference between the two.
PHO5p-RFP reporter expression
rfp.bg <- dat %>% filter(!FP, Parameter == "PHO5pr-mCherry-H") %>% pull(Median) %>% mean()
rfp.basal <- dat %>% filter(FP, Parameter == "PHO5pr-mCherry-H", Pho4 == "pho4del") %>% pull(Median) %>% mean()
dat %>%
filter(Parameter == "PHO5pr-mCherry-H", xor(!FP, Pho4 == "pho4del")) %>%
ggplot(aes(x = Sample, y = Median)) + geom_col(position = position_dodge()) +
ylim(c(0, 6000)) + ylab("Median Fluorescent Intensity") +
labs(title = "RFP background fluorescence (yH156) and\nbasal expression w/o Pho4 (yH295-373)") +
theme_cowplot()

Figure 5. Background RFP level and basal PHO5pr-mCherry expression.
p1 <- dat %>%
filter(FP, Pho4 != "pho4del") %>%
mutate(MFI = Median / 1000) %>%
ggplot(aes(x = Pho4, y = MFI, fill = Pho4, alpha = Group)) + scale_alpha_discrete("User", range = c(0.5, 1)) +
geom_col(position = position_dodge2(width = 0.9)) +
#stat_summary(fun = "mean", geom = "crossbar", color = "red", size = 0.3, width = 0.3) +
geom_hline(aes(yintercept = ifelse(Parameter == "chimera-GFP-H", gfp.bg/1000, rfp.basal/1000)), linetype = 2, alpha = 0.6) +
facet_grid(Pho2 ~ Parameter, scales = "free", space = "free_y") + ylab("Median Fluorescent Intensity (x1000)") +
#scale_color_brewer(type = "qual") + scale_color_manual(values = c("red", NA)) +
coord_flip() + scale_y_continuous(expand = expansion(mult = c(0.01,0.1))) +
theme_cowplot() + background_grid(major = "x", minor = "x") + panel_border()
Using alpha for a discrete variable is not advised.
p1

Figure 6. Pho4-GFP and PHO5pr-RFP intensities plotted side-by-side. The raw fluorescent intensities in arbitrary units are plotted on the x-axis. Color of the bars are meant to highlight the different Pho4 chimera (or endogenous Pho4) constructs. To distinguish and compare the results from Jia and Lindsey’s experiments, the two sets of results were combined and grouped by the Pho4 chimera, and plotted side-by-side with Jia’s results shown in a lighter (semi-transparent) color. The dashed lines in the GFP panel indicates background fluorescence, while the dashed line in the RFP channel indicates basal mCherry levels (in strains with the PHO5pr-mCherry reporter but lacking Pho4).
Discussion
- For the majority of the Pho4 chimera, their expression levels as judged by the GFP intensity are similar between Jia and Lindsey’s strains, which is expected. However, a few constructs did show differences, e.g. pH193, pH180 and pH177. Interestingly, the differences are only seen in the pho2∆ background.
- For CgPho4 (pH188), the PHO5pr-mCherry reporter levels are comparable in pho2∆ vs PHO2 wild type backgrounds, while for ScPho4 (pH194), the reporter level without Pho2 is clearly the lowest compared with all the chimera and CgPho4.
- In PHO2 wild type background, Lindsey’s strains show more variability among the Pho4 chimera, e.g. pH177 and pH180 induce higher levels of reporter expression than either pure ScPho4 or pure CgPho4 (although, pH177 seems to be at ~2 fold more abundant than the others).
Normalized Pho4 chimera activity with and without Pho2
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, we will similarly subtract the background, which is minimal (~100 a.u. w/o mCherry reporter). Since what we are interested in is not the absolute level of reporter expression but the fold induction compared with the pho4∆ strains, we will divide the background subtracted RFP levels in the experimental strain by the basal expression level. Then, the induction fold change, call it M, is a function of both Pho4 chimera’s activity (A) in each strain and also the protein level of the chimera (C) (other factors matter, too, but we assume they are the same among all strains for simplicity). We will further assume that M is proportional to both S and C (may not be correct), which leads to \(M = kSA\). Rearranging this equation, we get the quantity we are interested in, i.e. activity, as \(A/k = M/S\). Since \(k\) is a constant and we are only interested in the relative values of activity among the chimera, we can let \(A' = A/k\), and for simplicity, we will equate \(A'\) with \(A\) below.
dat1 <- dat %>%
# remove all the control strains, including the parents, and only retain the experimental ones
filter(FP, Pho4 != "pho4del") %>%
select(Group, Sample, Rep, Pho4, Pho2, Pho5RFP, Parameter, Median) %>%
pivot_wider(names_from = Parameter, values_from = Median) %>%
mutate(GFP.noBG = `chimera-GFP-H` - gfp.bg,
RFP.noBG = `PHO5pr-mCherry-H` - rfp.bg,
RFP.FC = RFP.noBG / rfp.basal,
nRFP.FC = RFP.FC / GFP.noBG * median(GFP.noBG, na.rm = T))
p2 <- dat1 %>%
pivot_longer(cols = c(RFP.FC, nRFP.FC), names_to = "Parameter", values_to = "Value") %>%
mutate(Parameter = factor(Parameter, levels = c("RFP.FC", "nRFP.FC"),
labels = c("PHO5 fold induction", "PHO5 induction / Pho4-GFP"))) %>%
ggplot(aes(x = Pho4, y = Value, fill = Pho4, alpha = Group)) + scale_alpha_discrete("User", range = c(0.5, 1)) +
geom_col(position = position_dodge2(width = 0.9, preserve = "total")) +
stat_summary(fun = "mean", geom = "crossbar", position = position_dodge2(width = 0.9),
color = "red", size = 0.3, show.legend = F) +
#geom_text(aes(label = ifelse(Sample %in% issues, "*", ""), hjust = -0.2, vjust = 0.8), color = "black", size = 5) +
geom_hline(yintercept = 1, linetype = 2) +
facet_grid(Pho2 ~ Parameter, scales = "free", space = "free_y") +
#scale_fill_brewer(type = "div", drop = F) + scale_color_manual(values = c("red", NA)) +
coord_flip() + scale_y_continuous(expand = expansion(mult=c(0.01,0.1))) + ylab("Fold Induction") + xlab("") +
theme_bw()
Using alpha for a discrete variable is not advised.
p2

Figure 7. Composite plot including Pho4 abundance, PHO5 reporter strength and fold induction values. Pho4-GFP and PHO5p-mCherry intensities were quantified using flow cytometry. Pho4 chimera were labeled by the plasmid ID (see table at the top for details) and are listed on the vertical axis. Each bar is one biological replicate, with Jia and Lindsey’s strains grouped by the plasmid transformed and arranged side-by-side (Jia’s data are lighter in color). The red vertical bar indicate the mean value across biological replicates for either Jia or Lindsey’s strains. In (A), the x-axis values represent the Median Fluorescent Intensity (MFI, arbitury units) for either Pho4-GFP or PHO5pr-mCherry after subtracting the background (based on strains without the corresponding fluorescent protein). In (B), the fold change for PHO5 reporter is calculated as the background-subtracted RFP level divided by the basal expression level. The normalized induction 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.
Discussion
- Other than CgPho4 (pH188), the rest seem not different from ScPho4 in that they have little activity without Pho2.
- We need to first figure out the Pho4 chimera level in pho2∆ background, as the unnormalized ratio (in B left column) for a few of the chimera do seem to be above ScPho4, but after the normalization all went down, because the corresponding chimera appear to be expressed at a higher level. What’s curious is that the higher expression is only in the pho2∆ background.
- We also need to repeat this experiment to examine the variability.
LS0tCnRpdGxlOiBhbmFseXplIGZsb3cgY3l0b21ldHJ5IGRhdGEgZnJvbSAyMDIxLTAzLTEwCmF1dGhvcjogQmluIEhlCm91dHB1dDogCiAgaHRtbF9ub3RlYm9vazoKICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OiB0cnVlCiAgICBkZl9wcmludDogZGVmYXVsdAogICAgY29kZV9mb2xkaW5nOiBoaWRlCi0tLQoKYGBge3Igc2V0dXB9CnJlcXVpcmUodGlkeXZlcnNlKQpyZXF1aXJlKGNvd3Bsb3QpCmBgYAoKIyMgRXhlY3V0aXZlIHN1bW1hcnkKPi0gW0EgZmV3XSgjcWMpIFt0ZWNobmljYWwgdGhpbmdzXSgjc3VwZmlnKSB0byBjb3JyZWN0IGluIHRoZSBjb2xsZWN0aW9uIG9mIGZsb3cgY3l0b21ldHJ5IGRhdGEsIGluY2x1ZGluZyBzZXR0aW5nIHRoZSBhY3F1aXNpdGlvbiB0aHJlc2hvbGQsIHByb3Blcmx5IGRyYXdpbmcgdGhlIGdhdGUgYW5kIGlkZW50aWZ5aW5nIGFuZCByZW1vdmluZyBwcm9ibGVtYXRpYyBzYW1wbGVzLgo+LSBUaGVyZSBpcyBzdWJzdGFudGlhbCB2YXJpYWJpbGl0eSBpbiBQaG80LWNoaW1lcmEgYWJ1bmRhbmNlIGFzIG1lYXN1cmVkIGJ5IG1OZW9uIGludGVuc2l0eSBhbW9uZyB0aGUgY2hpbWVyaWMgLyBlbmRvZ2Vub3VzIGNvbnN0cnVjdHMsIGJ1dCBvbmx5IGluIHRoZSBfcGhvMuKIhl8gYmFja2dyb3VuZCwgd2hpbGUgdGhlIHNhbWUgcGxhc21pZHMgYXBwZWFyIHRvIGJlIGV4cHJlc3NlZCB0byBhIHNpbWlsYXIgbGV2ZWwgd2l0aCBfUEhPMl8uCj4gIC0gaHlwb3RoZXNlcz8KPiAgLSBub3QgbmVjZXNzYXJpbHkgcmVhbCwgc2VlIG15IFsyMDIwLTEyLTIxXShodHRwczovL3JwdWJzLmNvbS9lbXB0eWhiL1BobzQtR0ZQLXRlc3QtMjAyMDEyMjEpIHZzIFsyMDIwLTEyLTIzXShodHRwczovL3JwdWJzLmNvbS9lbXB0eWhiL3Rlc3QtcGhvNC1nZnAtMjAyMDEyMjMpIGFuYWx5c2VzLgo+LSBDaGltZXJhIGFjdGl2aXR5IGFzIG1lYXN1cmVkIGJ5IFJGUC9HRlAgY29uZmlybXMgdGhhdCBDZ1BobzQgaXMgUGhvMi1pbmRlcGVuZGVudCB3aGlsZSBTY1BobzQgaXMgZGVwZW5kZW50LiBCdXQgYWxsIGNoaW1lcmEgdGVzdGVkIGFwcGVhciB0byBiZSBQaG8yLWRlcGVuZGVudCwgaW4gY29udHJhc3QgdG8gcHJldmlvdXMgcGhvc3BoYXRhc2UgYXNzYXkgcmVzdWx0cy4gTm90YWJseSwgcGFydCBvZiB0aGlzIGlzIGR1ZSB0byB0aGUgYXBwYXJlbnRseSBoaWdoZXIgZXhwcmVzc2lvbiBsZXZlbCBvZiB0aGUgY2hpbWVyYS4KPgo+KipfVE9ET18qKgo+Cj4xLiBJbnZlc3RpZ2F0ZSB0aGUgZWZmZWN0IG9mIGdyb3d0aCBtZWRpYSAoYWRlbmluZSBhbmQgcGhvc3BoYXRlIGxldmVscykgb24gUGhvNCBjaGltZXJhIGV4cHJlc3Npb24gaW4gX3BobzLiiIZfIHN0cmFpbnMuCj4xLiBVc2UgV2VzdGVybiB0byBjb25maXJtIHdoZXRoZXIgdGhlIGhpZ2hlciBQaG80IGFidW5kYW5jZSBmb3Igc29tZSBjaGltZXJhIGluIF9waG8y4oiGXyBpcyByZWFsLCBlLmcuIHBIMTc3Cj4xLiBSZXBlYXQgdGhpcyBleHBlcmltZW50IHRvIGRldGVybWluZSBpZiB0aGUgb2JzZXJ2YXRpb25zIGFyZSByZXByb2R1Y2libGUuCj4xLiBWYWxpZGF0ZSB0aGUgZmxvdyBjeXRvbWV0cnkgcmVzdWx0cyB3aXRoIHBob3NwaGF0YXNlIGFzc2F5IChvbmx5IHdvcmtzIGZvciB5SDI5NSw2IHBhcmVudHMpCgojIyBHb2FsCgpWYWxpZGF0ZSB0aGUgcGhvc3BoYXRhc2UgYXNzYXkgcmVzdWx0cyBmb3IgWHUncyBQaG80IGNoaW1lcmEgdXNpbmcgdGhlIG5ldyBkdWFsLWZsdW9yZXNjZW5jZSByZXBvcnRlciBhcHByb2FjaC4KCiMjIE1hdGVyaWFsIGFuZCBtZXRob2RzCgpKaWEgc3ViY2xvbmVkIGEgc2V0IG9mIFh1J3MgY2hpbWVyaWMgUGhvNCBwbGFzbWlkcyBpbnRvIGhlciBtTmVvbiB0YWdnZWQgYmFja2JvbmUgKHBIMTczKSB1c2luZyB0aGUgbmV3IEdvbGRlbiBHYXRlIGFwcHJvYWNoLiBUaGUgY29tcGxldGUgbGlzdCBvZiBwbGFzbWlkcyBjYW4gYmUgZm91bmQgW2hlcmVdKGh0dHBzOi8vZG9jcy5nb29nbGUuY29tL3NwcmVhZHNoZWV0cy9kLzF5Zjc3ZWtkb1o5U1QwdGNLZE1xRERqQWlyMlRtdFNlQ1hmZHpweHhzZ1dzL2VkaXQ/dXNwPXNoYXJpbmcpLgoKQWxsIHN0cmFpbnMgaW4gdGhlIHRhYmxlIGJlbG93IGhhdmUgKnBobzgwOjpUcnAxKgoKYGBge3J9CnNhbXBsZXMgPC0gcmVhZF9jc3YoIjIwMjEwMzEwLVRlc3QtWHUtQ2hpbWVyYXMtc2FtcGxlLWxpc3QuY3N2IiwgY29sX3R5cGVzID0gImNjY2NjbGMiKQpzYW1wbGVzCmBgYAoKQ2VsbHMgYXJlIGZpcnN0IGdyb3duIHRvIHNhdHVyYXRpb24gby9uIGluIFNELWxldSwgZGlsdXRlZCBpbiB0aGUgbW9ybmluZyB0byBPRH4wLjIgaW4gU0QtbGV1IGFuZCByZWdyb3duIGZvciB+MiBkb3VibGluZ3MuIEFmdGVyIHRoZSBjdWx0dXJlIHJlYWNoZWQgZGVzaXJlZCBPRCAobWlkIGxvZyBwaGFzZSksIGNlbGxzIHdlcmUgc3B1biBkb3duIGFuZCByZXN1c3BlbmRlZCBpbiBQQlMgYW5kIHVzZWQgZm9yIGZsb3cgY3l0b21ldHJ5LiBWb2x0YWdlcyB1c2VkIGFyZToKCnwgRGV0ZWN0b3IgfCBWb2x0YWdlIHwgQ29tbWVudHMgfAp8LS0tLS0tLS0tLXwtLS0tLS0tLS18LS0tLS0tLS0tLXwKfCBGU0MgICAgICB8IDM1MCBtViAgfCBJIG5vcm1hbGx5IHVzZSAyODUgbVYgfAp8IFNTQyAgICAgIHwgMzUwIG1WICB8IE5BIHwKfCBCTDEgICAgICB8IDQwMCBtViAgfCBOQSB8CnwgWUwyICAgICAgfCA0NTAgbVYgIHwgaGlnaGVyIHRoYW4gbWluZSB8CgojIyBEYXRhIGltcG9ydApgYGB7ciBpbXBvcnRfZGF0YX0KZGF0MCA8LSByZWFkX2NzdigiMjAyMTAzMTktQmluLXJlYW5hbHl6ZWQtY2hpbWVyYS10ZXN0LTEtcmVzdWx0cy5jc3YiKQpgYGAKCiMjIFF1YWxpdHkgY29udHJvbHsjcWN9CnlMU19LIGFuZCB5SlpfQjMsIEI0IGVhY2ggaGF2ZSBvbmUgb3IgbW9yZSBiaW9sb2dpY2FsIHJlcGxpY2F0ZXMgdGhhdCBzaG93ZWQgYWJub3JtYWwgcGF0dGVybnMgb24gdGhlIEZDUy1IIHZzIFNTQy1IIC0tIHZlcnkgZmV3IGNlbGxzIGFuZCBhIGxhcmdlIG51bWJlciBvZiBzbWFsbCBwYXJ0aWNsZXMgd2l0aCBoaWdoIFNTQy1IIGFuZCBsb3cgRlNDLUguIFNlZSB0aGUgW2xhc3Qgc2VjdGlvbl0oI3N1cGZpZykgb2YgdGhlIGtuaXR0ZWQgZG9jdW1lbnQuCgpgYGB7ciBRQywgZmlnLndpZHRoPTYsIGZpZy5oZWlnaHQ9NH0KZ2dwbG90KGRhdDAsIGFlcyh4ID0gQ291bnQsIHkgPSBDb25jZW50cmF0aW9uLCBzaGFwZSA9IFBobzIsIGNvbG9yID0gUGhvNCkpICsgCiAgZ2VvbV9wb2ludChzaXplID0gMiwgYWxwaGEgPSAwLjgpICsgCiAgeGxhYigiVG90YWwgIyBvZiBldmVudHMgcmVjb3JkZWQiKSArIHlsYWIoIkNvbmNlbnRyYXRpb24gKGV2ZW50cy9zKSIpICsgCiAgdGhlbWVfY293cGxvdCgpICsgYmFja2dyb3VuZF9ncmlkKCkgKyBwYW5lbF9ib3JkZXIoKQpgYGAKKipGaWd1cmUgMS4gQWNxdWlzaXRpb24gc3RhdHMgc2hvdyBhIGZldyBzYW1wbGVzIHVuZGVyc2FtcGxlZCBhbmQgcHJvYmxlbWF0aWMuKiogQ29uY2VudHJhdGlvbiBpcyBtZWFzdXJlZCBieSByZWNvcmRlZCBldmVudHMgLyBzZWNvbmQgKHktYXhpcykgd2hpbGUgdG90YWwgbnVtYmVyIG9mIHJlY29yZGVkIGV2ZW50cyBpbiB0aGUgInNpbmdsZXQiIGdhdGUgaXMgcGxvdHRlZCBvbiB0aGUgeC1heGlzLiBTYW1wbGVzIGFyZSBjb2xvcmVkIGJ5IHRoZSBQaG80IGdlbm90eXBlLCBhbmQgdGhlIHNoYXBlIHJlZmxlY3RzIHRoZSBzdGF0dXMgb2YgUGhvMiBpbiB0aGUgaG9zdCBzdHJhaW4uIExpbmRzZXkgYW5kIEppYSdzIHNhbXBsZXMgYXJlIG1peGVkLgoKKipfRGlzY3Vzc2lvbl8qKgoKLSBGaXJzdCBvZiBhbGwsIGl0IGFwcGVhcnMgdGhhdCBMaW5kc2V5IGFuZCBKaWEgZGlkbid0IGNvcnJlY3RseSBzZXQgdGhlIGFjcXVpc2l0aW9uIHN0b3AgY3JpdGVyaWEuIEkgc3VzcGVjdCB0aGF0IHRoZXkgbGV0IHRoZSBhY3F1aXNpdGlvbiB0byBzdG9wIHdoZW4gdGhlIG51bWJlciBvZiBldmVudHMgcmVhY2ggMTAsMDAwLCBidXQgZGlkbid0IHNldCB0aGUgcG9wdWxhdGlvbiB0byB0aGUgInNpbmdsZXQiIGdhdGUuIEJ5IGRlZmF1bHQsIHRoZSBjcml0ZXJpYSB3aWxsIGFwcGx5IHRvIEFMTCBldmVudHMuCi0gcEgxNzkgd2hlbiB0cmFuc2Zvcm1lZCBpbnRvIHRoZSBfcGhvMuKIhl8gYmFja2dyb3VuZCBhcHBlYXJzIHRvIGhhdmUgdHJvdWJsZSBncm93aW5nLiBXZSBzaG91bGQgY29uc2lkZXIgY2hhbmdpbmcgdGhlIGNvbXBvc2l0aW9uIG9mIHRoZSBtZWRpYSB0byBpbmNsdWRlIGFkZGl0aW9uYWwgYWRlbmluZSwgc2luY2UgX3BobzLiiIZfIGlzIHNlbnNpdGl2ZSB0byBhZGVuaW5lIGRlcHJpdmF0aW9uLiBBbHNvLCBpdCB3b3VsZCBiZSBoZWxwZnVsIHRvIHRlc3QgYW5kIGlkZW50aWZ5IGEgbWVkaWEvZ3Jvd3RoIGNvbmRpdGlvbiBpbiB3aGljaCB0aGUgdHdvIGhvc3Qgc3RyYWlucywgd2l0aCBvciB3aXRob3V0IFBobzIsIGdyb3cgcm91Z2hseSBhdCB0aGUgc2FtZSByYXRlLgotIEEgc2VwYXJhdGUgaXNzdWUgaXMgdGhhdCB0aGUgdm9sdGFnZSBmb3IgdGhlIEZTQyBjaGFubmVsIGlzIHByb2JhYmx5IHRvbyBsYXJnZSAoMzUwIG1WLCB2cyAyODUgaW4gbXkgZXhwZXJpbWVudHMpLiBBcyBjYW4gYmUgc2VlbiBpbiB0aGUgcGxvdCBiZWxvdywgbWFueSBldmVudHMgd2VyZSBjdXRvZmYgb2YgdGhlIHJpZ2h0IGJvdW5kYXJ5IG9uIHRoZSBGU0MtSCBheGlzLiBXaGlsZSB0aG9zZSBldmVudHMgbWF5IG5vdCBiZSB3aGF0IHdlIHdhbnQgdG8gaW5jbHVkZSAoc2VlbXMgbGlrZSB0aGV5IGhhdmUgbXVjaCBoaWdoZXIgU1NDLCBidXQgbm90IHN1cmUgaWYgdGhlIHJlc3VsdCB3aWxsIGxvb2sgdGhlIHNhbWUgYWZ0ZXIgbG93ZXJpbmcgdGhlIHZvbHRhZ2UpLCB3ZSBzaG91bGQgc3RpbGwgdHJ5IGFkanVzdCB0aGUgRlNDIHZvbHRhZ2UgdG8gImJyaW5nIHRoZW0gaW5zaWRlIHRoZSBwbG90Ii4KICAgICFbeUgxNTYgZXhhbXBsZV0oLi9pbWcveUgxNTYtcGxvdC5wbmcpCioqRmlndXJlIDIuIEV4YW1wbGUgcGxvdHMgZGVtb25zdHJhdGluZyBwb3RlbnRpYWxseSB0b28gaGlnaCB2b2x0YWdlIGZvciBGU0MqKgoKKipGaWx0ZXIgZGF0YSoqCmBgYHtyfQppc3N1ZXMgPC0gYygiSy0xIiwiSy0yIiwiSy0zIiwiQjMtMSIsIkIzLTIiLCJCMy0zIiwiQjQtMSIpICMgc2VlIGJlbG93IGZvciByZWFzb25zCmRhdCA8LSBkYXQwICU+JSAKICBtdXRhdGUoaWQgPSBwYXN0ZShTYW1wbGUsIFJlcCwgc2VwID0gIi0iKSkgJT4lIAogIGZpbHRlcighaWQgJWluJSBpc3N1ZXMpICU+JSAKICBzZWxlY3QoLWlkKQpgYGAKCiMjIEFuYWx5c2lzCiMjIyBQaG80LUdGUCBleHByZXNzaW9uIGxldmVscwpGaXJzdCBsb29rIGF0IHRoZSBiYWNrZ3JvdW5kIGZsdW9yZXNjZW5jZSBsZXZlbCBpbiB0aGUgR0ZQIGNoYW5uZWwKYGBge3IgZmlnLndpZHRoID0gNCwgZmlnLmhlaWdodD00fQpnZnAuYmcgPC0gZGF0ICU+JSBmaWx0ZXIoIUZQLCBQYXJhbWV0ZXIgPT0gImNoaW1lcmEtR0ZQLUgiKSAlPiUgcHVsbChNZWRpYW4pICU+JSBtZWFuKCkKcDAgPC0gZGF0ICU+JSAKICBmaWx0ZXIoIUZQLCBQYXJhbWV0ZXIgPT0gImNoaW1lcmEtR0ZQLUgiKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gU2FtcGxlLCB5ID0gTWVkaWFuKSkgKyBnZW9tX2NvbChwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKCkpICsgCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gZ2ZwLmJnLCBsaW5ldHlwZSA9ICJkYXNoZWQiLCBhbHBoYSA9IDAuNikgKwogIGxhYnModGl0bGUgPSAiQmFja2dyb3VuZCBHRlAgbGV2ZWwiKSArIHlsYWIoIk1GSSIpICsgeWxpbShjKDAsIDYwMDApKSArIAogIHRoZW1lX2Nvd3Bsb3QoKSArIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApLCAKICAgICAgICAgICAgICAgICAgICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0ID0gMC41KSkKcDAKYGBgCioqRmlndXJlIDMuIEJhY2tncm91bmQgR0ZQIGluIHN0cmFpbnMgd2l0aCBubyBtTmVvbi4qKiBNRkk6IE1lZGlhbiBmbHVvcmVzY2VudCBpbnRlbnNpdHkuIERvdHRlZCBsaW5lIHNob3dzIHRoZSBhdmVyYWdlIG9mIGFsbCBuZWdhdGl2ZSBzYW1wbGVzIGFuZCB3aWxsIGJlIHVzZWQgZm9yIGJhY2tncm91bmQgc3VidHJhY3Rpb24gaW4gbGF0ZXIgYW5hbHlzZXMuCgpJdCdzIGdvb2QgdG8gc2VlIHRoYXQgYWxsIHRoZSBuZWdhdGl2ZSBzdHJhaW5zIGhhdmUgdGhlIHNhbWUgbGV2ZWwgb2YgYmFja2dyb3VuZCBpbiB0aGUgQkwxIChHRlApIGNoYW5uZWwuIFVuZm9ydHVuYXRlbHkgd2UgZGlkbid0IGluY2x1ZGUgYW55IHN0cmFpbiB0aGF0IGhhdmUgc3Ryb25nIFJGUCBidXQgbm8gR0ZQIHNvIGFzIHRvIGV2YWx1YXRlIHRoZSBzcGlsbG92ZXIgb2YgdGhlIFJGUCBzaWduYWwgaW50byB0aGUgR0ZQIGNoYW5uZWwuCgpOZXh0LCB3ZSBjYW4gZXhhbWluZSB0aGUgUGhvNC1HRlAgbGV2ZWxzIGZvciB0aGUgZGlmZmVyZW50IGNvbnRydWN0cywgaW4gX1BITzJfIG9yIF9waG8y4oiGXyBiYWNrZ3JvdW5kcywgYW5kIHRyYW5zZm9ybWVkIGludG8gdHdvIGdlbmV0aWMgYmFja2dyb3VuZHMuCmBgYHtyLCBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD00fQpwMSA8LSBkYXQgJT4lIGZpbHRlcihGUCwgUGFyYW1ldGVyID09ICJjaGltZXJhLUdGUC1IIikgJT4lIAogIGdncGxvdChhZXMoeCA9IFBobzQsIHkgPSBNZWRpYW4sIGFscGhhID0gR3JvdXApKSArIAogIHNjYWxlX2FscGhhX2Rpc2NyZXRlKCJVc2VyIiwgcmFuZ2UgPSBjKDAuNSwgMSkpICsKICBnZW9tX2JhcihhZXMoZmlsbCA9IFBobzQpLCBzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZTIoKSkgKyAKICBzdGF0X3N1bW1hcnkoZnVuID0gIm1lYW4iLCBnZW9tID0gImNyb3NzYmFyIiwgY29sb3VyID0gInJlZCIsIHNpemUgPSAwLjIsIAogICAgICAgICAgICAgICBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlMigpLCBzaG93LmxlZ2VuZCA9IEYpICsKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSBnZnAuYmcsIGxpbmV0eXBlID0gImRhc2hlZCIsIGFscGhhID0gMC42KSArCiAgZmFjZXRfd3JhcCh+UGhvMiwgbnJvdyA9IDEsIHNjYWxlcyA9ICJmcmVlX3giKSArCiAgeWxhYigiTUZJIikgKyBzY2FsZV95X2NvbnRpbnVvdXMoZXhwYW5kID0gZXhwYW5zaW9uKG11bHQgPSBjKDAuMDEsMC4xKSkpICsKICBsYWJzKHRpdGxlID0gIkdGUCBmbHVvcmVzY2VudCBpbnRlbnNpdHkgKGFyYml0cmFyeSB1bml0cykiKSArCiAgdGhlbWVfY293cGxvdCgpICsgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA0MCwgdmp1c3QgPSAxLCBoanVzdCA9IDEpKQoKcDEKI2xlZnRfY29sIDwtIHBsb3RfZ3JpZChwMCwgTlVMTCwgbnJvdyA9IDIsIHJlbF9oZWlnaHRzID0gYygyLDEpKQojcGxvdF9ncmlkKGxlZnRfY29sLCBwMSwgbmNvbCA9IDIsIHJlbF93aWR0aHMgPSBjKDEsNCkpCmBgYAoqKkZpZ3VyZSA0LiBQaG80LWNoaW1lcmEgYWJ1bmRhbmNlIG1lYXN1cmVkIGJ5IG1OZW9uIGZsdW9yZXNjZW50IGludGVuc2l0eS4qKiBEb3R0ZWQgbGluZSBpbmRpY2F0ZXMgdGhlIGJhY2tncm91bmQgbGV2ZWwgb2YgR0ZQLiBFYWNoIGJhciByZXByZXNlbnRzIG9uZSBiaW9sb2dpY2FsIHJlcGxpY2F0ZS4gSmlhIGFuZCBMaW5kc2V5J3Mgc2FtcGxlcyB3ZXJlIGdyb3VwZWQgYnkgdGhlIHBsYXNtaWQgdGhleSBjb250YWluIGFuZCBhcnJhbmdlZCBzaWRlLWJ5LXNpZGUgdG8gc2hvdyB0aGVpciBzaW1pbGFyaXR5IG9yIGRpZmZlcmVuY2UuIFRoZSByZWQgbGluZXMgaW5kaWNhdGUgdGhlIG1lYW4gZm9yIGVhY2ggZ3JvdXAuCgoqKl9EaXNjdXNzaW9uXyoqCgotIFRoZXJlIGlzIGdyZWF0IHZhcmlhYmlsaXR5IGFtb25nIFBobzQgY2hpbWVyaWMgY29uc3RydWN0cywgd2hlcmUgcEgxNzcgc2hvd2VkIHRoZSBoaWdoZXN0IGV4cHJlc3Npb24gbGV2ZWwgYnkgZmx1b3Jlc2NlbnQgcHJvdGVpbiBhYnVuZGFuY2UKLSBUaGVyZSBhcHBlYXIgdG8gYmUgbW9yZSBjaGltZXJhIHByb3RlaW4gaW4gdGhlIF9waG8y4oiGXyBiYWNrZ3JvdW5kIHRoYW4gaW4gdGhlIF9QSE8yXyB3aWxkIHR5cGUgYmFja2dyb3VuZC4gCgogICAgSSd2ZSBzZWVuIGEgc2ltaWxhciBwaWN0dXJlIGluIFtvbmUgb2YgbXkgcHJldmlvdXMgZXhwZXJpbWVudHNdKGh0dHBzOi8vcnB1YnMuY29tL2VtcHR5aGIvUGhvNC1HRlAtdGVzdC0yMDIwMTIyMSksIGJ1dCBhIFtyZXBlYXQgb2YgdGhhdCBleHBlcmltZW50XShodHRwczovL3JwdWJzLmNvbS9lbXB0eWhiL3Rlc3QtcGhvNC1nZnAtMjAyMDEyMjMpIGRpZG4ndCByZXByb2R1Y2UgdGhlIHBoZW5vbWVub24uIAogICAgCiAgICBXaGlsZSBJIGluaXRpYWxseSBzdXNwZWN0ZWQgc29tZSBzb3J0IG9mIHRyYW5zY3JpcHRpb25hbCBmZWVkYmFjayAtLSBzb21laG93IGxhY2sgb2YgUGhvMiBpbmR1Y2VzIFBobzQgdG8gYmUgbW9yZSBoaWdobHkgZXhwcmVzc2VkIC0tIHRoZSBsYWNrIG9mIHJlcHJvZHVjaWJpbGl0eSBpbiB0aGUgc2Vjb25kIHRyeSBtYWRlIG1lIHRoaW5rIGl0IGNvdWxkIGhhdmUgdG8gZG8gd2l0aCBob3cgX1BITzJfIGFuZCBfcGhvMuKIhl8gc3RyYWlucyBncm93LiBXZSBrbm93IHRoYXQgUGhvMiBpcyBhbHNvIHJlc3BvbnNpYmxlIGZvciByZWd1bGF0aW5nIGRlIG5vdm8gcHVyaW5lIHN5bnRoZXNpcyBhbmQgYXMgc3VjaCwgX3BobzLiiIZfIHN0cmFpbnMgYXJlIGV4dHJlbWVseSBzZW5zaXRpdmUgdG8gcHVyaW5lIGRlcHJpdmF0aW9uLiAKICAgIAogICAgV2hhdCBpZiB3ZSBhZGQgYWRkaXRpb25hbCBhZGVuaW5lIHRvIG91ciBtZWRpYSBmb3IgZ3Jvd2luZyB0aGUgc3RyYWlucyAoZm9sbG93aW5nIHRoZSBsb3cgYXV0b2ZsdW9yZXNjZW5jZSBtZWRpYSByZWNpcGUgcGVyaGFwcyk/IE9uZSBpZGVhIGlzIHRvIHRlc3QgYSByYW5nZSBvZiBtZWRpYSB3aXRoIGRpZmZlcmVudCBjb25jZW50cmF0aW9ucyBvZiBhZGVuaW5lIGFuZCBwaG9zcGhhdGUsIGFuZCByZWNvcmQgZ3Jvd3RoIGN1cnZlcyBmb3IgdGhlIF9QSE8yXyBhbmQgX3BobzLiiIZfIHN0cmFpbnMsIHRvIGRldGVybWluZSBpZiB0aGVyZSBpcyBhbnkgZGlmZmVyZW5jZSBpbiBncm93dGggcmF0ZSBhbmQgaG9wZWZ1bGx5IGlkZW50aWZ5IGEgY29uZGl0aW9uIHRoYXQgc2hvd3Mgbm8gZGlmZmVyZW5jZSBiZXR3ZWVuIHRoZSB0d28uCgojIyMgUEhPNXAtUkZQIHJlcG9ydGVyIGV4cHJlc3Npb24KYGBge3IsIGZpZy53aWR0aD02LCBmaWcuaGVpZ2h0PTR9CnJmcC5iZyA8LSBkYXQgJT4lIGZpbHRlcighRlAsIFBhcmFtZXRlciA9PSAiUEhPNXByLW1DaGVycnktSCIpICU+JSBwdWxsKE1lZGlhbikgJT4lIG1lYW4oKQpyZnAuYmFzYWwgPC0gZGF0ICU+JSBmaWx0ZXIoRlAsIFBhcmFtZXRlciA9PSAiUEhPNXByLW1DaGVycnktSCIsIFBobzQgPT0gInBobzRkZWwiKSAlPiUgcHVsbChNZWRpYW4pICU+JSBtZWFuKCkKZGF0ICU+JSAKICBmaWx0ZXIoUGFyYW1ldGVyID09ICJQSE81cHItbUNoZXJyeS1IIiwgeG9yKCFGUCwgUGhvNCA9PSAicGhvNGRlbCIpKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gU2FtcGxlLCB5ID0gTWVkaWFuKSkgKyBnZW9tX2NvbChwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlKCkpICsgCiAgeWxpbShjKDAsIDYwMDApKSArIHlsYWIoIk1lZGlhbiBGbHVvcmVzY2VudCBJbnRlbnNpdHkiKSArCiAgbGFicyh0aXRsZSA9ICJSRlAgYmFja2dyb3VuZCBmbHVvcmVzY2VuY2UgKHlIMTU2KSBhbmRcbmJhc2FsIGV4cHJlc3Npb24gdy9vIFBobzQgKHlIMjk1LTM3MykiKSArIAogIHRoZW1lX2Nvd3Bsb3QoKQpgYGAKKipGaWd1cmUgNS4gQmFja2dyb3VuZCBSRlAgbGV2ZWwgYW5kIGJhc2FsIFBITzVwci1tQ2hlcnJ5IGV4cHJlc3Npb24uKioKCmBgYHtyLCBmaWcuaGVpZ2h0PTYsIGZpZy53aWR0aD04fQpwMSA8LSBkYXQgJT4lIAogIGZpbHRlcihGUCwgUGhvNCAhPSAicGhvNGRlbCIpICU+JSAKICBtdXRhdGUoTUZJID0gTWVkaWFuIC8gMTAwMCkgJT4lIAogIGdncGxvdChhZXMoeCA9IFBobzQsIHkgPSBNRkksIGZpbGwgPSBQaG80LCBhbHBoYSA9IEdyb3VwKSkgKyBzY2FsZV9hbHBoYV9kaXNjcmV0ZSgiVXNlciIsIHJhbmdlID0gYygwLjUsIDEpKSArCiAgZ2VvbV9jb2wocG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZTIod2lkdGggPSAwLjkpKSArCiAgI3N0YXRfc3VtbWFyeShmdW4gPSAibWVhbiIsIGdlb20gPSAiY3Jvc3NiYXIiLCBjb2xvciA9ICJyZWQiLCBzaXplID0gMC4zLCB3aWR0aCA9IDAuMykgKwogIGdlb21faGxpbmUoYWVzKHlpbnRlcmNlcHQgPSBpZmVsc2UoUGFyYW1ldGVyID09ICJjaGltZXJhLUdGUC1IIiwgZ2ZwLmJnLzEwMDAsIHJmcC5iYXNhbC8xMDAwKSksIGxpbmV0eXBlID0gMiwgYWxwaGEgPSAwLjYpICsKICBmYWNldF9ncmlkKFBobzIgfiBQYXJhbWV0ZXIsIHNjYWxlcyA9ICJmcmVlIiwgc3BhY2UgPSAiZnJlZV95IikgKyB5bGFiKCJNZWRpYW4gRmx1b3Jlc2NlbnQgSW50ZW5zaXR5ICh4MTAwMCkiKSArCiAgI3NjYWxlX2NvbG9yX2JyZXdlcih0eXBlID0gInF1YWwiKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCJyZWQiLCBOQSkpICsKICBjb29yZF9mbGlwKCkgKyBzY2FsZV95X2NvbnRpbnVvdXMoZXhwYW5kID0gZXhwYW5zaW9uKG11bHQgPSBjKDAuMDEsMC4xKSkpICsKICB0aGVtZV9jb3dwbG90KCkgKyBiYWNrZ3JvdW5kX2dyaWQobWFqb3IgPSAieCIsIG1pbm9yID0gIngiKSArIHBhbmVsX2JvcmRlcigpCnAxCmBgYAoqKkZpZ3VyZSA2LiBQaG80LUdGUCBhbmQgUEhPNXByLVJGUCBpbnRlbnNpdGllcyBwbG90dGVkIHNpZGUtYnktc2lkZS4qKiBUaGUgcmF3IGZsdW9yZXNjZW50IGludGVuc2l0aWVzIGluIGFyYml0cmFyeSB1bml0cyBhcmUgcGxvdHRlZCBvbiB0aGUgeC1heGlzLiBDb2xvciBvZiB0aGUgYmFycyBhcmUgbWVhbnQgdG8gaGlnaGxpZ2h0IHRoZSBkaWZmZXJlbnQgUGhvNCBjaGltZXJhIChvciBlbmRvZ2Vub3VzIFBobzQpIGNvbnN0cnVjdHMuIFRvIGRpc3Rpbmd1aXNoIGFuZCBjb21wYXJlIHRoZSByZXN1bHRzIGZyb20gSmlhIGFuZCBMaW5kc2V5J3MgZXhwZXJpbWVudHMsIHRoZSB0d28gc2V0cyBvZiByZXN1bHRzIHdlcmUgY29tYmluZWQgYW5kIGdyb3VwZWQgYnkgdGhlIFBobzQgY2hpbWVyYSwgYW5kIHBsb3R0ZWQgc2lkZS1ieS1zaWRlIHdpdGggSmlhJ3MgcmVzdWx0cyBzaG93biBpbiBhIGxpZ2h0ZXIgKHNlbWktdHJhbnNwYXJlbnQpIGNvbG9yLiBUaGUgZGFzaGVkIGxpbmVzIGluIHRoZSBHRlAgcGFuZWwgaW5kaWNhdGVzIGJhY2tncm91bmQgZmx1b3Jlc2NlbmNlLCB3aGlsZSB0aGUgZGFzaGVkIGxpbmUgaW4gdGhlIFJGUCBjaGFubmVsIGluZGljYXRlcyBiYXNhbCBtQ2hlcnJ5IGxldmVscyAoaW4gc3RyYWlucyB3aXRoIHRoZSBQSE81cHItbUNoZXJyeSByZXBvcnRlciBidXQgbGFja2luZyBQaG80KS4KCioqX0Rpc2N1c3Npb25fKioKCi0gRm9yIHRoZSBtYWpvcml0eSBvZiB0aGUgUGhvNCBjaGltZXJhLCB0aGVpciBleHByZXNzaW9uIGxldmVscyBhcyBqdWRnZWQgYnkgdGhlIEdGUCBpbnRlbnNpdHkgYXJlIHNpbWlsYXIgYmV0d2VlbiBKaWEgYW5kIExpbmRzZXkncyBzdHJhaW5zLCB3aGljaCBpcyBleHBlY3RlZC4gSG93ZXZlciwgYSBmZXcgY29uc3RydWN0cyBkaWQgc2hvdyBkaWZmZXJlbmNlcywgZS5nLiBwSDE5MywgcEgxODAgYW5kIHBIMTc3LiBJbnRlcmVzdGluZ2x5LCB0aGUgZGlmZmVyZW5jZXMgYXJlIG9ubHkgc2VlbiBpbiB0aGUgX3BobzLiiIZfIGJhY2tncm91bmQuCi0gRm9yIENnUGhvNCAocEgxODgpLCB0aGUgUEhPNXByLW1DaGVycnkgcmVwb3J0ZXIgbGV2ZWxzIGFyZSBjb21wYXJhYmxlIGluIF9waG8y4oiGXyB2cyBfUEhPMl8gd2lsZCB0eXBlIGJhY2tncm91bmRzLCB3aGlsZSBmb3IgU2NQaG80IChwSDE5NCksIHRoZSByZXBvcnRlciBsZXZlbCB3aXRob3V0IFBobzIgaXMgY2xlYXJseSB0aGUgbG93ZXN0IGNvbXBhcmVkIHdpdGggYWxsIHRoZSBjaGltZXJhIGFuZCBDZ1BobzQuCi0gSW4gX1BITzJfIHdpbGQgdHlwZSBiYWNrZ3JvdW5kLCBMaW5kc2V5J3Mgc3RyYWlucyBzaG93IG1vcmUgdmFyaWFiaWxpdHkgYW1vbmcgdGhlIFBobzQgY2hpbWVyYSwgZS5nLiBwSDE3NyBhbmQgcEgxODAgaW5kdWNlIGhpZ2hlciBsZXZlbHMgb2YgcmVwb3J0ZXIgZXhwcmVzc2lvbiB0aGFuIGVpdGhlciBwdXJlIFNjUGhvNCBvciBwdXJlIENnUGhvNCAoYWx0aG91Z2gsIHBIMTc3IHNlZW1zIHRvIGJlIGF0IH4yIGZvbGQgbW9yZSBhYnVuZGFudCB0aGFuIHRoZSBvdGhlcnMpLgoKCiMjIyBOb3JtYWxpemVkIFBobzQgY2hpbWVyYSBhY3Rpdml0eSB3aXRoIGFuZCB3aXRob3V0IFBobzIKV2Ugd2lsbCBmaXJzdCB0cmFuc2Zvcm0gdGhlIHJhdyBHRlAgYW5kIFJGUCBpbnRlbnNpdGllcyB0byBtYWtlIHRoZW0gbW9yZSBpbnRlcnByZXRhYmxlLiBGb3IgdGhlIEdGUCBpbnRlbnNpdHksIGFzIHRoZXJlIGlzIGEgc3Vic3RhbnRpYWwgYmFja2dyb3VuZCwgd2Ugd2lsbCBzdWJ0cmFjdCB0aGUgYmFja2dyb3VuZCBmcm9tIGFsbCB0aGUgR0ZQLWNvbnRhaW5pbmcgc3RyYWlucyB0byBvYnRhaW4gdGhlIG1lYW5pbmdmdWwgbWVhc3VyZSBmb3IgUGhvNCBwcm90ZWluIGxldmVscy4gRm9yIFJGUCwgd2Ugd2lsbCBzaW1pbGFybHkgc3VidHJhY3QgdGhlIGJhY2tncm91bmQsIHdoaWNoIGlzIG1pbmltYWwgKH4xMDAgYS51LiB3L28gbUNoZXJyeSByZXBvcnRlcikuIFNpbmNlIHdoYXQgd2UgYXJlIGludGVyZXN0ZWQgaW4gaXMgbm90IHRoZSBhYnNvbHV0ZSBsZXZlbCBvZiByZXBvcnRlciBleHByZXNzaW9uIGJ1dCB0aGUgZm9sZCBpbmR1Y3Rpb24gY29tcGFyZWQgd2l0aCB0aGUgX3BobzTiiIZfIHN0cmFpbnMsIHdlIHdpbGwgZGl2aWRlIHRoZSBiYWNrZ3JvdW5kIHN1YnRyYWN0ZWQgUkZQIGxldmVscyBpbiB0aGUgZXhwZXJpbWVudGFsIHN0cmFpbiBieSB0aGUgYmFzYWwgZXhwcmVzc2lvbiBsZXZlbC4gVGhlbiwgdGhlIGluZHVjdGlvbiBmb2xkIGNoYW5nZSwgY2FsbCBpdCBNLCBpcyBhIGZ1bmN0aW9uIG9mIGJvdGggUGhvNCBjaGltZXJhJ3MgYWN0aXZpdHkgKEEpIGluIGVhY2ggc3RyYWluIGFuZCBhbHNvIHRoZSBwcm90ZWluIGxldmVsIG9mIHRoZSBjaGltZXJhIChDKSAob3RoZXIgZmFjdG9ycyBtYXR0ZXIsIHRvbywgYnV0IHdlIGFzc3VtZSB0aGV5IGFyZSB0aGUgc2FtZSBhbW9uZyBhbGwgc3RyYWlucyBmb3Igc2ltcGxpY2l0eSkuIFdlIHdpbGwgZnVydGhlciBhc3N1bWUgdGhhdCBNIGlzIHByb3BvcnRpb25hbCB0byBib3RoIFMgYW5kIEMgKG1heSBub3QgYmUgY29ycmVjdCksIHdoaWNoIGxlYWRzIHRvICRNID0ga1NBJC4gUmVhcnJhbmdpbmcgdGhpcyBlcXVhdGlvbiwgd2UgZ2V0IHRoZSBxdWFudGl0eSB3ZSBhcmUgaW50ZXJlc3RlZCBpbiwgaS5lLiBhY3Rpdml0eSwgYXMgJEEvayA9IE0vUyQuIFNpbmNlICRrJCBpcyBhIGNvbnN0YW50IGFuZCB3ZSBhcmUgb25seSBpbnRlcmVzdGVkIGluIHRoZSByZWxhdGl2ZSB2YWx1ZXMgb2YgYWN0aXZpdHkgYW1vbmcgdGhlIGNoaW1lcmEsIHdlIGNhbiBsZXQgJEEnID0gQS9rJCwgYW5kIGZvciBzaW1wbGljaXR5LCB3ZSB3aWxsIGVxdWF0ZSAkQSckIHdpdGggJEEkIGJlbG93LiAKYGBge3IgdHJhbnNmb3JtfQpkYXQxIDwtIGRhdCAlPiUgCiAgIyByZW1vdmUgYWxsIHRoZSBjb250cm9sIHN0cmFpbnMsIGluY2x1ZGluZyB0aGUgcGFyZW50cywgYW5kIG9ubHkgcmV0YWluIHRoZSBleHBlcmltZW50YWwgb25lcwogIGZpbHRlcihGUCwgUGhvNCAhPSAicGhvNGRlbCIpICU+JSAKICBzZWxlY3QoR3JvdXAsIFNhbXBsZSwgUmVwLCBQaG80LCBQaG8yLCBQaG81UkZQLCBQYXJhbWV0ZXIsIE1lZGlhbikgJT4lIAogIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBQYXJhbWV0ZXIsIHZhbHVlc19mcm9tID0gTWVkaWFuKSAlPiUgCiAgbXV0YXRlKEdGUC5ub0JHID0gYGNoaW1lcmEtR0ZQLUhgIC0gZ2ZwLmJnLAogICAgICAgICBSRlAubm9CRyA9IGBQSE81cHItbUNoZXJyeS1IYCAtIHJmcC5iZywKICAgICAgICAgUkZQLkZDID0gUkZQLm5vQkcgLyByZnAuYmFzYWwsCiAgICAgICAgIG5SRlAuRkMgPSBSRlAuRkMgLyBHRlAubm9CRyAqIG1lZGlhbihHRlAubm9CRywgbmEucm0gPSBUKSkKYGBgCgpgYGB7ciwgZmlnLmhlaWdodD02LCBmaWcud2lkdGg9OH0KcDIgPC0gZGF0MSAlPiUgCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKFJGUC5GQywgblJGUC5GQyksIG5hbWVzX3RvID0gIlBhcmFtZXRlciIsIHZhbHVlc190byA9ICJWYWx1ZSIpICU+JQogIG11dGF0ZShQYXJhbWV0ZXIgPSBmYWN0b3IoUGFyYW1ldGVyLCBsZXZlbHMgPSBjKCJSRlAuRkMiLCAiblJGUC5GQyIpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIlBITzUgZm9sZCBpbmR1Y3Rpb24iLCAiUEhPNSBpbmR1Y3Rpb24gLyBQaG80LUdGUCIpKSkgJT4lIAogIGdncGxvdChhZXMoeCA9IFBobzQsIHkgPSBWYWx1ZSwgZmlsbCA9ICBQaG80LCBhbHBoYSA9IEdyb3VwKSkgKyBzY2FsZV9hbHBoYV9kaXNjcmV0ZSgiVXNlciIsIHJhbmdlID0gYygwLjUsIDEpKSArCiAgZ2VvbV9jb2wocG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZTIod2lkdGggPSAwLjksIHByZXNlcnZlID0gInRvdGFsIikpICsKICBzdGF0X3N1bW1hcnkoZnVuID0gIm1lYW4iLCBnZW9tID0gImNyb3NzYmFyIiwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZTIod2lkdGggPSAwLjkpLCAKICAgICAgICAgICAgICAgY29sb3IgPSAicmVkIiwgc2l6ZSA9IDAuMywgc2hvdy5sZWdlbmQgPSBGKSArCiAgI2dlb21fdGV4dChhZXMobGFiZWwgPSBpZmVsc2UoU2FtcGxlICVpbiUgaXNzdWVzLCAiKiIsICIiKSwgaGp1c3QgPSAtMC4yLCB2anVzdCA9IDAuOCksIGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDUpICsKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAxLCBsaW5ldHlwZSA9IDIpICsKICBmYWNldF9ncmlkKFBobzIgfiBQYXJhbWV0ZXIsIHNjYWxlcyA9ICJmcmVlIiwgc3BhY2UgPSAiZnJlZV95IikgKwogICNzY2FsZV9maWxsX2JyZXdlcih0eXBlID0gImRpdiIsIGRyb3AgPSBGKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCJyZWQiLCBOQSkpICsKICBjb29yZF9mbGlwKCkgKyBzY2FsZV95X2NvbnRpbnVvdXMoZXhwYW5kID0gZXhwYW5zaW9uKG11bHQ9YygwLjAxLDAuMSkpKSArIHlsYWIoIkZvbGQgSW5kdWN0aW9uIikgKyB4bGFiKCIiKSArCiAgdGhlbWVfYncoKQoKcDIKYGBgCioqRmlndXJlIDcuIENvbXBvc2l0ZSBwbG90IGluY2x1ZGluZyBQaG80IGFidW5kYW5jZSwgX1BITzVfIHJlcG9ydGVyIHN0cmVuZ3RoIGFuZCBmb2xkIGluZHVjdGlvbiB2YWx1ZXMuKiogUGhvNC1HRlAgYW5kIFBITzVwLW1DaGVycnkgaW50ZW5zaXRpZXMgd2VyZSBxdWFudGlmaWVkIHVzaW5nIGZsb3cgY3l0b21ldHJ5LiBQaG80IGNoaW1lcmEgd2VyZSBsYWJlbGVkIGJ5IHRoZSBwbGFzbWlkIElEIChzZWUgdGFibGUgYXQgdGhlIHRvcCBmb3IgZGV0YWlscykgYW5kIGFyZSBsaXN0ZWQgb24gdGhlIHZlcnRpY2FsIGF4aXMuIEVhY2ggYmFyIGlzIG9uZSBiaW9sb2dpY2FsIHJlcGxpY2F0ZSwgd2l0aCBKaWEgYW5kIExpbmRzZXkncyBzdHJhaW5zIGdyb3VwZWQgYnkgdGhlIHBsYXNtaWQgdHJhbnNmb3JtZWQgYW5kIGFycmFuZ2VkIHNpZGUtYnktc2lkZSAoSmlhJ3MgZGF0YSBhcmUgbGlnaHRlciBpbiBjb2xvcikuIFRoZSByZWQgdmVydGljYWwgYmFyIGluZGljYXRlIHRoZSBtZWFuIHZhbHVlIGFjcm9zcyBiaW9sb2dpY2FsIHJlcGxpY2F0ZXMgZm9yIGVpdGhlciBKaWEgb3IgTGluZHNleSdzIHN0cmFpbnMuIEluICoqKEEpKiosIHRoZSB4LWF4aXMgdmFsdWVzIHJlcHJlc2VudCB0aGUgTWVkaWFuIEZsdW9yZXNjZW50IEludGVuc2l0eSAoTUZJLCBhcmJpdHVyeSB1bml0cykgZm9yIGVpdGhlciBQaG80LUdGUCBvciBQSE81cHItbUNoZXJyeSBhZnRlciBzdWJ0cmFjdGluZyB0aGUgYmFja2dyb3VuZCAoYmFzZWQgb24gc3RyYWlucyB3aXRob3V0IHRoZSBjb3JyZXNwb25kaW5nIGZsdW9yZXNjZW50IHByb3RlaW4pLiBJbiAqKihCKSoqLCB0aGUgZm9sZCBjaGFuZ2UgZm9yIF9QSE81XyByZXBvcnRlciBpcyBjYWxjdWxhdGVkIGFzIHRoZSBiYWNrZ3JvdW5kLXN1YnRyYWN0ZWQgUkZQIGxldmVsIGRpdmlkZWQgYnkgdGhlIGJhc2FsIGV4cHJlc3Npb24gbGV2ZWwuIFRoZSBub3JtYWxpemVkIGluZHVjdGlvbiBvbiB0aGUgcmlnaHQgY29sdW1uIGlzIGNhbGN1bGF0ZWQgYnkgZGl2aWRpbmcgdGhlIGluZHVjdGlvbiBmb2xkIGNoYW5nZSBmcm9tIHRoZSBsZWZ0IGNvbHVtbiBieSB0aGUgY29ycmVzcG9uZGluZyBQaG80LUdGUCAoYmFja2dyb3VuZCBzdWJ0cmFjdGVkKSBsZXZlbHMgYW5kIG11bHRpcGxpZWQgYnkgdGhlIG1lZGlhbiBQaG80LUdGUCBsZXZlbHMgb2YgYWxsIHN0cmFpbnMuIFRoZSBkYXNoZWQgbGluZXMgaW4gYm90aCBjb2x1bW5zIGluZGljYXRlIHRoZSBpbmR1Y3Rpb24gZm9sZCBjaGFuZ2Ugb2YgMSwgaS5lLiBubyBjaGFuZ2UgY29tcGFyZWQgdG8gdGhlIF9waG804oiGXyBzdHJhaW5zLiAKCioqX0Rpc2N1c3Npb25fKioKCi0gT3RoZXIgdGhhbiBDZ1BobzQgKHBIMTg4KSwgdGhlIHJlc3Qgc2VlbSBub3QgZGlmZmVyZW50IGZyb20gU2NQaG80IGluIHRoYXQgdGhleSBoYXZlIGxpdHRsZSBhY3Rpdml0eSB3aXRob3V0IFBobzIuCi0gV2UgbmVlZCB0byBmaXJzdCBmaWd1cmUgb3V0IHRoZSBQaG80IGNoaW1lcmEgbGV2ZWwgaW4gX3BobzLiiIZfIGJhY2tncm91bmQsIGFzIHRoZSB1bm5vcm1hbGl6ZWQgcmF0aW8gKGluICoqQioqIGxlZnQgY29sdW1uKSBmb3IgYSBmZXcgb2YgdGhlIGNoaW1lcmEgZG8gc2VlbSB0byBiZSBhYm92ZSBTY1BobzQsIGJ1dCBhZnRlciB0aGUgbm9ybWFsaXphdGlvbiBhbGwgd2VudCBkb3duLCBiZWNhdXNlIHRoZSBjb3JyZXNwb25kaW5nIGNoaW1lcmEgYXBwZWFyIHRvIGJlIGV4cHJlc3NlZCBhdCBhIGhpZ2hlciBsZXZlbC4gV2hhdCdzIGN1cmlvdXMgaXMgdGhhdCB0aGUgaGlnaGVyIGV4cHJlc3Npb24gaXMgb25seSBpbiB0aGUgX3BobzLiiIZfIGJhY2tncm91bmQuCi0gV2UgYWxzbyBuZWVkIHRvIHJlcGVhdCB0aGlzIGV4cGVyaW1lbnQgdG8gZXhhbWluZSB0aGUgdmFyaWFiaWxpdHkuCgojIyBTdXBwbGVtZW50YXJ5IGZpZ3VyZXN7I3N1cGZpZ30KSGVyZSBhcmUgcGxvdHMgdGhhdCBkZW1vbnN0cmF0ZSB0aGUgaXNzdWVzIHdpdGggc29tZSBvZiB0aGUgc2FtcGxlczoKIVtMaW5kc2V5IHNhbXBsZSBLMV0oLi9pbWcvSzEtaXNzdWUtcGxvdC5wbmcpCiFbTGluZHNleSBzYW1wbGUgSzJdKC4vaW1nL0syLWlzc3VlLXBsb3QucG5nKQohW0xpbmRzZXkgc2FtcGxlIEszXSguL2ltZy9LMy1pc3N1ZS1wbG90LnBuZykKIVtKaWEgc2FtcGxlIEIzLTFdKC4vaW1nL0IzLTEtaXNzdWUtcGxvdC5wbmcpCiFbSmlhIHNhbXBsZSBCMy0yXSguL2ltZy9CMy0yLWlzc3VlLXBsb3QucG5nKQohW0ppYSBzYW1wbGUgQjMtM10oLi9pbWcvQjMtMy1pc3N1ZS1wbG90LnBuZykKIVtKaWEgc2FtcGxlIEI0LTFdKC4vaW1nL0I0LTEtaXNzdWUtcGxvdC5wbmcp