• Goal
  • Material and methods
    • Table of strains
    • methods
  • Data and analysis
    • Pho4-GFP expression levels
    • PHO5pr-mCherry reporter levels
    • PHO5pr-mCherry induction levels normalized by Pho4 abundance
require(tidyverse)
require(cowplot)

Goal

After determining that I can take the cells directly from the media to the flow cytometer, by diluting them in the original media or just PBS, I decided to repeat the previous experiment, this time dropping the endogenous set (in retrospect should have kept them in) and added newly obtained plasmid-Pho4-GFP strains from my latest transformation.

Material and methods

See gDoc. This time I let all strains acclimate to the media for 2x o/n cycles. I also correctly grew up the pRS315 based strains in SD-leu to ensure that cells maintain their plasmids.

Table of strains

methods

See gDoc for details. Some strains didn’t grow to saturation after the first overnight culture and thus the o/n culture instead of the second growth, which was at mid log phase at the time of harvest, was used for flow cytometry.

Data and analysis

dat <- read_csv("20201221-Pho4-GFP-plasmid-leu2-test-stats.csv")

── Column specification ──────────────────────────────────────────────────────────────────────────────────────────────
cols(
  Sample = col_character(),
  Group = col_character(),
  Pho4 = col_character(),
  Pho4GFP = col_character(),
  PHO5RFP = col_logical(),
  PHO2 = col_character(),
  Parameter = col_character(),
  Count = col_double(),
  Median = col_double(),
  CV = col_double(),
  rCV = col_double()
)
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")))

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.

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.
  • For the plasmid-Pho4-GFP, the two ScPho4-GFP constructs appear to show higher expression in the yH295 background (P, Q) than in the yH296 background (M, N), for reasons I don’t fully understand. Could there be some level of feedback due to the lack of Pho2?

PHO5pr-mCherry reporter levels

rfp.bg <- mean(dat %>% filter(!PHO5RFP, Parameter == "PHO5pr-mCherry") %>% pull(Median))
rfp.basal <- dat %>% filter(PHO5RFP, Pho4 == "pho4-", Parameter == "PHO5pr-mCherry") %>% pull(Median) %>% mean() - rfp.bg

# removed a few outliers with MFI > 20k
p1 <- dat %>% filter(PHO5RFP) %>% 
  ggplot(aes(x = Sample, y = Median, fill =  Group, color = PHO2)) + 
  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(Pho4 ~ Parameter, scales = "free", space = "free_y") + ylab("MFI") +
  scale_fill_brewer(type = "div", drop = FALSE) + scale_color_manual(values = c("red", NA)) +
  coord_flip() + scale_y_continuous(expand = c(0.01,0.02)) +
  theme_bw()
p1

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).

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.

# calculate gfp background
gfp.bg <- dat %>% filter(Pho4GFP == "No-GFP", Parameter == "Pho4-GFP") %>% pull(Median) %>% mean()
# transform
dat1 <- dat %>% select(-Count, -CV, -rCV) %>% 
  pivot_wider(names_from = Parameter, values_from = Median) %>% 
  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))
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)) +
  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 = c(0.01,0.02)) + ylab("MFI (x1000, a.u.)") + 
  theme_bw()
  
p2 <- dat2 %>% 
  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")),
         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_hline(yintercept = 1, linetype = 2) +
  facet_grid(Pho4GFP ~ 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 = c(0.01,0.02)) + ylab("Fold Induction") + 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(
  p1 + theme(legend.position="none"),
  p2 + 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))

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 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, 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.

Discussions

  • In fact, after normalizing by Pho4 abundance, the plasmid approach yields relatively consistent induction ratios for the same construct, while the exogenously integrated Pho4 somehow showed more variability.
LS0tCnRpdGxlOiBhbmFseXplIGZsb3cgY3l0b21ldHJ5IGRhdGEgZnJvbSAyMDIwLTEyLTIxCmF1dGhvcjogQmluIEhlCmRhdGU6IDIwMjAtMTItMjEKb3V0cHV0OiAKICBodG1sX25vdGVib29rOgogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6IHRydWUKICAgIGRmX3ByaW50OiBkZWZhdWx0CiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUKLS0tCgpgYGB7ciBzZXR1cH0KcmVxdWlyZSh0aWR5dmVyc2UpCnJlcXVpcmUoY293cGxvdCkKYGBgCgojIyBHb2FsCgpBZnRlciBkZXRlcm1pbmluZyB0aGF0IEkgY2FuIHRha2UgdGhlIGNlbGxzIGRpcmVjdGx5IGZyb20gdGhlIG1lZGlhIHRvIHRoZSBmbG93IGN5dG9tZXRlciwgYnkgZGlsdXRpbmcgdGhlbSBpbiB0aGUgb3JpZ2luYWwgbWVkaWEgb3IganVzdCBQQlMsIEkgZGVjaWRlZCB0byByZXBlYXQgdGhlIHByZXZpb3VzIGV4cGVyaW1lbnQsIHRoaXMgdGltZSBkcm9wcGluZyB0aGUgZW5kb2dlbm91cyBzZXQgKGluIHJldHJvc3BlY3Qgc2hvdWxkIGhhdmUga2VwdCB0aGVtIGluKSBhbmQgYWRkZWQgbmV3bHkgb2J0YWluZWQgcGxhc21pZC1QaG80LUdGUCBzdHJhaW5zIGZyb20gbXkgbGF0ZXN0IHRyYW5zZm9ybWF0aW9uLgoKIyMgTWF0ZXJpYWwgYW5kIG1ldGhvZHMKU2VlIGdEb2MuIFRoaXMgdGltZSBJIGxldCBhbGwgc3RyYWlucyBhY2NsaW1hdGUgdG8gdGhlIG1lZGlhIGZvciAyeCBvL24gY3ljbGVzLiBJIGFsc28gY29ycmVjdGx5IGdyZXcgdXAgdGhlIHBSUzMxNSBiYXNlZCBzdHJhaW5zIGluIFNELWxldSB0byBlbnN1cmUgdGhhdCBjZWxscyBtYWludGFpbiB0aGVpciBwbGFzbWlkcy4KCiMjIyBUYWJsZSBvZiBzdHJhaW5zCiFbXSguL2ltZy9zdHJhaW5zLWdlbm90eXBlLnBuZykKCiMjIyBtZXRob2RzClNlZSBnRG9jIGZvciBkZXRhaWxzLiBTb21lIHN0cmFpbnMgZGlkbid0IGdyb3cgdG8gc2F0dXJhdGlvbiBhZnRlciB0aGUgZmlyc3Qgb3Zlcm5pZ2h0IGN1bHR1cmUgYW5kIHRodXMgdGhlIG8vbiBjdWx0dXJlIGluc3RlYWQgb2YgdGhlIHNlY29uZCBncm93dGgsIHdoaWNoIHdhcyBhdCBtaWQgbG9nIHBoYXNlIGF0IHRoZSB0aW1lIG9mIGhhcnZlc3QsIHdhcyB1c2VkIGZvciBmbG93IGN5dG9tZXRyeS4KCiMjIERhdGEgYW5kIGFuYWx5c2lzCmBgYHtyfQpkYXQgPC0gcmVhZF9jc3YoIjIwMjAxMjIxLVBobzQtR0ZQLXBsYXNtaWQtbGV1Mi10ZXN0LXN0YXRzLmNzdiIpCmRhdCA8LSBkYXQgJT4lIG11dGF0ZShQaG80R0ZQID0gZmFjdG9yKFBobzRHRlAsIGxldmVscyA9IGMoIk5vLUdGUCIsIlNjUGhvNC1tTmVvbiIsIlNjUGhvNC1FR0ZQIiwgIkNnUGhvNC1tTmVvbiIpKSwgR3JvdXAgPSBmYWN0b3IoR3JvdXAsIGxldmVscyA9IGMoImNvbnRyb2wiLCAiZW5kb2dlbm91cyIsICJleG9nZW5vdXMiLCAicGxhc21pZCIpKSwgUGhvNCA9IGZhY3RvcihQaG80LCBsZXZlbHMgPSBjKCJwaG80LSIsIlNjUGhvNCIsICJDZ1BobzQiKSkpCmBgYAoKIyMjIFBobzQtR0ZQIGV4cHJlc3Npb24gbGV2ZWxzCkZpcnN0IGxvb2sgYXQgdGhlIGxldmVsIG9mIFBobzQtR0ZQIGNvbXBhcmVkIHdpdGggdGhlIG5lZ2F0aXZlIGNvbnRyb2xzLgpgYGB7ciwgZWNobyA9IEYsIGZpZy5oZWlnaHQgPSA2LCBmaWcud2lkdGggPSA2fQpnZnAuYmcgPC0gZGF0ICU+JSBmaWx0ZXIoUGhvNEdGUCA9PSAiTm8tR0ZQIiwgUGFyYW1ldGVyID09ICJQaG80LUdGUCIpICU+JSBwdWxsKE1lZGlhbikgJT4lIG1lYW4oKQpwMSA8LSBkYXQgJT4lIGZpbHRlcihQYXJhbWV0ZXIgPT0gIlBobzQtR0ZQIiwgTWVkaWFuIDwgMzAwMCkgJT4lIAogIGdncGxvdChhZXMoeCA9IFNhbXBsZSwgeSA9IE1lZGlhbiwgZmlsbCA9ICBHcm91cCkpICsgCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UyKHdpZHRoID0gMC45KSkgKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IGdmcC5iZywgbGluZXR5cGUgPSAiZGFzaGVkIiwgYWxwaGEgPSAwLjYpICsKICBmYWNldF9ncmlkKFBobzRHRlB+Liwgc2NhbGVzID0gImZyZWVfeSIsIHNwYWNlID0gImZyZWVfeSIpICsKICBzY2FsZV9maWxsX2JyZXdlcih0eXBlID0gImRpdiIsIGRyb3AgPSBGQUxTRSkgKyB5bGFiKCJNRkkiKSArCiAgY29vcmRfZmxpcCgpICsgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoMCwzMDAwKSwgZXhwYW5kID0gYygwLjAxLDApKSArCiAgdGhlbWVfYncoKSArIGxhYnModGl0bGUgPSAiR0ZQIGZsdW9yZXNjZW50IGludGVuc2l0eSAoYXJiaXRyYXJ5IHVuaXRzKSIsIHN1YnRpdGxlID0gImRhc2hlZCBsaW5lIGluZGljYXRlcyBiYWNrZ3JvdW5kIGZsdW9yZXNjZW5jZSIpCgpwMQpgYGAKKipGaWd1cmUgMSBQaG80LUdGUCBpbnRlbnNpdHkgYnkgc3RyYWluLioqIFBobzQtR0ZQIGludGVuc2l0aWVzIHdlcmUgcXVhbnRpZmllZCBvbiBhbiBBdHR1bmUgTnhUIGZsb3cgY3l0b21ldGVyIHVzaW5nIDQwMCBtViBvbiB0aGUgQkwxIGNoYW5uZWwuIEFjcXVpc2l0aW9uIHJhdGUgaXMgMjAwIHVsL21pbi4gQXQgbGVhc3QgMTAsMDAwIGV2ZW50cyB3ZXJlIGNvbGxlY3RlZCBhbmQgdGhlIG1lZGlhbiBmbHVvcmVzY2VudCBpbnRlbnNpdHkgKE1GSSwgYXJiaXRyYXJ5IHVuaXRzKSB3ZXJlIHByZXNlbnRlZCBvbiB0aGUgeC1heGlzLCB3aGlsZSBzdHJhaW4gSURzIGFyZSBsaXN0ZWQgb24gdGhlIHZlcnRpY2FsIGF4aXMuCgpfRGlzY3Vzc2lvbl8KCi0gU29tZXdoYXQgc3VycHJpc2luZyB0byBtZSwgdGhlIGV4b2dlbm91c2x5IGludGVncmF0ZWQgUGhvNC1HRlAsIGV4Y2VwdCBmb3IgdGhlIFNjUGhvNC1tTmVvbiwgc2VlbSB0byBoYXZlIHJhdGhlciBsb3cgZmx1b3Jlc2NlbnQgaW50ZW5zaXR5LiBGb3IgZXhhbXBsZSwgRjEsIEUyIGFuZCBFMyBhbGwgaGF2ZSB2ZXJ5IGxvdyBHRlAgc2lnbmFscy4KLSBGb3IgdGhlIHBsYXNtaWQtUGhvNC1HRlAsIHRoZSB0d28gU2NQaG80LUdGUCBjb25zdHJ1Y3RzIGFwcGVhciB0byBzaG93IGhpZ2hlciBleHByZXNzaW9uIGluIHRoZSB5SDI5NSBiYWNrZ3JvdW5kIChQLCBRKSB0aGFuIGluIHRoZSB5SDI5NiBiYWNrZ3JvdW5kIChNLCBOKSwgZm9yIHJlYXNvbnMgSSBkb24ndCBmdWxseSB1bmRlcnN0YW5kLiBDb3VsZCB0aGVyZSBiZSBzb21lIGxldmVsIG9mIGZlZWRiYWNrIGR1ZSB0byB0aGUgbGFjayBvZiBQaG8yPwoKIyMjIFBITzVwci1tQ2hlcnJ5IHJlcG9ydGVyIGxldmVscwpgYGB7ciwgZmlnLmhlaWdodCA9IDYsIGZpZy53aWR0aCA9IDd9CnJmcC5iZyA8LSBtZWFuKGRhdCAlPiUgZmlsdGVyKCFQSE81UkZQLCBQYXJhbWV0ZXIgPT0gIlBITzVwci1tQ2hlcnJ5IikgJT4lIHB1bGwoTWVkaWFuKSkKcmZwLmJhc2FsIDwtIGRhdCAlPiUgZmlsdGVyKFBITzVSRlAsIFBobzQgPT0gInBobzQtIiwgUGFyYW1ldGVyID09ICJQSE81cHItbUNoZXJyeSIpICU+JSBwdWxsKE1lZGlhbikgJT4lIG1lYW4oKSAtIHJmcC5iZwoKIyByZW1vdmVkIGEgZmV3IG91dGxpZXJzIHdpdGggTUZJID4gMjBrCnAxIDwtIGRhdCAlPiUgZmlsdGVyKFBITzVSRlApICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBTYW1wbGUsIHkgPSBNZWRpYW4sIGZpbGwgPSAgR3JvdXAsIGNvbG9yID0gUEhPMikpICsgCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UyKHdpZHRoID0gMC45KSkgKwogIGdlb21faGxpbmUoYWVzKHlpbnRlcmNlcHQgPSBpZmVsc2UoUGFyYW1ldGVyID09ICJQaG80LUdGUCIsIGdmcC5iZywgcmZwLmJhc2FsKSksIGxpbmV0eXBlID0gMiwgYWxwaGEgPSAwLjYpICsKICBmYWNldF9ncmlkKFBobzQgfiBQYXJhbWV0ZXIsIHNjYWxlcyA9ICJmcmVlIiwgc3BhY2UgPSAiZnJlZV95IikgKyB5bGFiKCJNRkkiKSArCiAgc2NhbGVfZmlsbF9icmV3ZXIodHlwZSA9ICJkaXYiLCBkcm9wID0gRkFMU0UpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoInJlZCIsIE5BKSkgKwogIGNvb3JkX2ZsaXAoKSArIHNjYWxlX3lfY29udGludW91cyhleHBhbmQgPSBjKDAuMDEsMC4wMikpICsKICB0aGVtZV9idygpCnAxCmBgYAoqKkZpZ3VyZSAyIENvcnJlc3BvbmRpbmcgUGhvNC1HRlAgYW5kIFBITzVwci1tQ2hlcnJ5IHJlcG9ydGVyIGZsdW9yZXNjZW5jZSBpbnRlbnNpdHkgcGVyIHN0cmFpbi4qKiBQaG80LUdGUCBhbmQgUEhPNXAtbUNoZXJyeSBpbnRlbnNpdGllcyB3ZXJlIHF1YW50aWZpZWQgb24gYW4gQXR0dW5lIE54VCBmbG93IGN5dG9tZXRlciB1c2luZyA0MDAgbVYgb24gdGhlIEJMMSBhbmQgNDMwIG1WIG9uIHRoZSBZTDIgY2hhbm5lbHMgcmVzcGVjdGl2ZWx5LiBBY3F1aXNpdGlvbiByYXRlIGlzIDIwMCB1bC9taW4uIEF0IGxlYXN0IDEwLDAwMCBldmVudHMgd2VyZSBjb2xsZWN0ZWQuIFN0cmFpbiBJRHMgYXJlIGxpc3RlZCBvbiB0aGUgdmVydGljYWwgYXhpcyBhbmQgdGhlIE1lZGlhbiBGbHVvcmVzY2VudCBJbnRlbnNpdHkgKE1GSSwgYXJiaXR1cnkgdW5pdHMpIGZvciBlYWNoIGNoYW5uZWwgb24gdGhlIGhvcml6b250YWwgYXhpcy4gQW4gYXN0ZXJpc2sgbmV4dCB0byBhIGJhciBpbmRpY2F0ZXMgYW4gb3Zlcm5pZ2h0IGdyb3d0aCBpbnN0ZWFkIG9mIGEgbWlkLWxvZyBwaGFzZSBncm93dGggd2FzIHVzZWQgZm9yIHF1YW50aWZpY2F0aW9uLiBUaGUgZGFzaGVkIHZlcnRpY2FsIGxpbmUgZm9yIFBobzQtR0ZQIGluZGljYXRlcyB0aGUgYXV0b2ZsdW9yZXNjZW5jZSBhcyBjYWxjdWxhdGVkIGJ5IHRoZSBtZWFuIG9mIHRoZSBpbnRlbnNpdGllcyBpbiB0aGUgc3RyYWlucyB3aXRob3V0IEdGUDsgdGhlIGRhc2hlZCB2ZXJ0aWNhbCBsaW5lIGZvciB0aGUgUkZQIHBsb3QgaW5kaWNhdGVzIHRoZSBiYXNhbCBsZXZlbCBleHByZXNzaW9uIGZyb20gdGhlIHJlcG9ydGVyIHdpdGhvdXQgUGhvNCwgY2FsY3VsYXRlZCBieSB0aGUgYXZlcmFnZSBvZiB5SDI5NSBhbmQgeUgyOTYsIGJvdGggb2Ygd2hpY2ggbGFjayBQaG80IGJ1dCBoYXMgdGhlIHJlcG9ydGVyKS4KCl9EaXNjdXNzaW9uXwoKLSBUaGlzIGV4cGVyaW1lbnQgc2hvd2VkIGEgbG90IG9mIHZhcmlhYmlsaXR5IGFtb25nIHRoZSBiaW9sb2dpY2FsIHJlcGxpY2F0ZXMsIGVzcGVjaWFsbHkgZm9yIGV4b2dlbm91c2x5IGludGVncmF0ZWQgQ2dQaG80IChDIGFuZCBGKS4gVGhpcyB3YXNuJ3QgdGhlIGNhc2UgaW4gbXkgcHJldmlvdXMgZXhwZXJpbWVudC4gSXQgd2lsbCBiZSB1c2VmdWwgdG8gcmVwZWF0IHRoaXMgYWdhaW4uCi0geUgyNjcgZG9lc24ndCBjb25mb3JtIHRvIG15IGV4cGVjdGF0aW9uIC0tIGl0IGhhcyBTY1BobzQgYW5kIFNjUGhvMiBhcyB3ZWxsIGFzIHRoZSBfUEhPNXByLW1DaGVycnlfIHJlcG9ydGVyLCBhbmQgdGh1cyBzaG91bGQgZ2l2ZSBub3JtYWwgbGV2ZWxzIG9mIFJGUCwgYnV0IGRpZG4ndC4KCiMjIyBfUEhPNXByLW1DaGVycnlfIGluZHVjdGlvbiBsZXZlbHMgbm9ybWFsaXplZCBieSBQaG80IGFidW5kYW5jZQpXZSB3aWxsIGZpcnN0IHRyYW5zZm9ybSB0aGUgcmF3IEdGUCBhbmQgUkZQIGludGVuc2l0aWVzIHRvIG1ha2UgdGhlbSBtb3JlIGludGVycHJldGFibGUuIEZvciB0aGUgR0ZQIGludGVuc2l0eSwgYXMgdGhlcmUgaXMgYSBzdWJzdGFudGlhbCBiYWNrZ3JvdW5kLCB3ZSB3aWxsIHN1YnRyYWN0IHRoZSBiYWNrZ3JvdW5kIGZyb20gYWxsIHRoZSBHRlAtY29udGFpbmluZyBzdHJhaW5zIHRvIG9idGFpbiB0aGUgbWVhbmluZ2Z1bCBtZWFzdXJlIGZvciBQaG80IHByb3RlaW4gbGV2ZWxzLiBGb3IgUkZQLCB0aGVyZSBpcyBtaW5pbWFsIGJhY2tncm91bmQgKHNlZSBiZWxvdykuIEhvd2V2ZXIsIHRoZXJlIGlzIGEgImJhc2FsIiBleHByZXNzaW9uIG9mIHRoZSByZXBvcnRlciBpbiB0aGUgYWJzZW5jZSBvZiBQaG80IC0tIHdoYXQgd2UgYXJlIGludGVyZXN0ZWQgaW4gaXMgbm90IHRoZSBhYnNvbHV0ZSBsZXZlbCBvZiByZXBvcnRlciBleHByZXNzaW9uIGJ1dCB0aGUgZm9sZCBpbmR1Y3Rpb24gY29tcGFyZWQgd2l0aCB0aGUgX3BobzTiiIZfIHN0cmFpbnMuCmBgYHtyIHRyYW5zZm9ybX0KIyBjYWxjdWxhdGUgZ2ZwIGJhY2tncm91bmQKZ2ZwLmJnIDwtIGRhdCAlPiUgZmlsdGVyKFBobzRHRlAgPT0gIk5vLUdGUCIsIFBhcmFtZXRlciA9PSAiUGhvNC1HRlAiKSAlPiUgcHVsbChNZWRpYW4pICU+JSBtZWFuKCkKIyB0cmFuc2Zvcm0KZGF0MSA8LSBkYXQgJT4lIHNlbGVjdCgtQ291bnQsIC1DViwgLXJDVikgJT4lIAogIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBQYXJhbWV0ZXIsIHZhbHVlc19mcm9tID0gTWVkaWFuKSAlPiUgCiAgbXV0YXRlKEdGUC5ub0JHID0gaWZlbHNlKFBobzRHRlAgPT0gIk5vLUdGUCIsIE5BLCBgUGhvNC1HRlBgIC0gZ2ZwLmJnKSwKICAgICAgICAgUkZQLm5vQkcgPSBpZmVsc2UoUEhPNVJGUCwgYFBITzVwci1tQ2hlcnJ5YCAtIHJmcC5iZywgMCksCiAgICAgICAgIFJGUC5GQyA9IGlmZWxzZShQSE81UkZQLCBSRlAubm9CRyAvIHJmcC5iYXNhbCwgTkEpLAogICAgICAgICBuUkZQLkZDID0gUkZQLkZDIC8gR0ZQLm5vQkcgKiBtZWRpYW4oR0ZQLm5vQkcsIG5hLnJtID0gVCkpCmBgYAoKYGBge3IgcGxvdF9ub3JtYWxpemVkX2luZHVjdGlvbiwgZmlnLmhlaWdodCA9IDcsIGZpZy53aWR0aD0xMCwgd2FybmluZz1GQUxTRX0KZGF0MiA8LSBkYXQxICU+JSBmaWx0ZXIoUGhvNEdGUCAhPSAiTm8tR0ZQIiwgUEhPNVJGUCkKcDEgPC0gZGF0MiAlPiUgCiAgbXV0YXRlKEdGUC5ub0JHID0gR0ZQLm5vQkcgLyAxMDAwLCBSRlAubm9CRyA9IFJGUC5ub0JHIC8gMTAwMCkgJT4lIAogIHBpdm90X2xvbmdlcihjb2xzID0gYyhHRlAubm9CRywgUkZQLm5vQkcpLCBuYW1lc190byA9ICJQYXJhbWV0ZXIiLCB2YWx1ZXNfdG8gPSAiVmFsdWUiKSAlPiUKICBtdXRhdGUoUGFyYW1ldGVyID0gZmFjdG9yKFBhcmFtZXRlciwgbGV2ZWxzID0gYygiR0ZQLm5vQkciLCAiUkZQLm5vQkciKSwgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzID0gYygiUGhvNC1HRlAgYWJ1bmRhbmNlIiwgIlBITzVwci1tQ2hlcnJ5IGxldmVsIikpLAogICAgICAgICBHcm91cCA9IGZhY3RvcihHcm91cCwgbGV2ZWxzID0gYygiY29udHJvbCIsICJlbmRvZ2Vub3VzIiwgImV4b2dlbm91cyIsICJwbGFzbWlkIikpKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gU2FtcGxlLCB5ID0gVmFsdWUsIGZpbGwgPSAgR3JvdXAsIGNvbG9yID0gUEhPMikpICsgCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UyKHdpZHRoID0gMC45KSkgKwogIGZhY2V0X2dyaWQoUGhvNEdGUCB+IFBhcmFtZXRlciwgc2NhbGVzID0gImZyZWUiLCBzcGFjZSA9ICJmcmVlX3kiKSArCiAgc2NhbGVfZmlsbF9icmV3ZXIodHlwZSA9ICJkaXYiLCBkcm9wID0gRkFMU0UpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoInJlZCIsIE5BKSkgKwogIGNvb3JkX2ZsaXAoKSArIHNjYWxlX3lfY29udGludW91cyhleHBhbmQgPSBjKDAuMDEsMC4wMikpICsgeWxhYigiTUZJICh4MTAwMCwgYS51LikiKSArIAogIHRoZW1lX2J3KCkKICAKcDIgPC0gZGF0MiAlPiUgCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKFJGUC5GQywgblJGUC5GQyksIG5hbWVzX3RvID0gIlBhcmFtZXRlciIsIHZhbHVlc190byA9ICJWYWx1ZSIpICU+JQogIG11dGF0ZShQYXJhbWV0ZXIgPSBmYWN0b3IoUGFyYW1ldGVyLCBsZXZlbHMgPSBjKCJSRlAuRkMiLCAiblJGUC5GQyIpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIlBITzUgZm9sZCBpbmR1Y3Rpb24iLCAiUEhPNSBpbmR1Y3Rpb24gLyBQaG80LUdGUCIpKSwKICAgICAgICAgR3JvdXAgPSBmYWN0b3IoR3JvdXAsIGxldmVscyA9IGMoImNvbnRyb2wiLCAiZW5kb2dlbm91cyIsICJleG9nZW5vdXMiLCAicGxhc21pZCIpKSkgJT4lIAogIGdncGxvdChhZXMoeCA9IFNhbXBsZSwgeSA9IFZhbHVlLCBmaWxsID0gIEdyb3VwLCBjb2xvciA9IFBITzIpKSArIAogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlMih3aWR0aCA9IDAuOSkpICsKICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAxLCBsaW5ldHlwZSA9IDIpICsKICBmYWNldF9ncmlkKFBobzRHRlAgfiBQYXJhbWV0ZXIsIHNjYWxlcyA9ICJmcmVlIiwgc3BhY2UgPSAiZnJlZV95IikgKwogIHNjYWxlX2ZpbGxfYnJld2VyKHR5cGUgPSAiZGl2IiwgZHJvcCA9IEYpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoInJlZCIsIE5BKSkgKwogIGNvb3JkX2ZsaXAoKSArIHNjYWxlX3lfY29udGludW91cyhleHBhbmQgPSBjKDAuMDEsMC4wMikpICsgeWxhYigiRm9sZCBJbmR1Y3Rpb24iKSArIHhsYWIoIiIpICsKICB0aGVtZV9idygpCgojIyBwbGFjZSBzaGFyZWQgbGVnZW5kIGF0IHRoZSBib3R0b20KIyMgcmVmZXJlbmNlOiBodHRwczovL3dpbGtlbGFiLm9yZy9jb3dwbG90L2FydGljbGVzL3NoYXJlZF9sZWdlbmRzLmh0bWwKbGVnZW5kIDwtIGdldF9sZWdlbmQoCiAgcDEgKyAKICBndWlkZXMoY29sb3IgPSBndWlkZV9sZWdlbmQobnJvdyA9IDEpLCBmaWxsID0gZ3VpZGVfbGVnZW5kKG5yb3cgPSAxKSkgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJib3R0b20iKQopCnByb3cgPC0gcGxvdF9ncmlkKAogIHAxICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIiksCiAgcDIgKyB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSwKICBhbGlnbiA9ICd2aCcsCiAgbGFiZWxzID0gYygiQSIsICJCIiwgIkMiKSwKICBoanVzdCA9IC0xLAogIG5yb3cgPSAxCikKcGxvdF9ncmlkKHByb3csIGxlZ2VuZCwgbmNvbCA9IDEsIHJlbF9oZWlnaHRzID0gYygxLCAuMSkpCmBgYAoqKkZpZ3VyZSAzIENvbXBvc2l0ZSBwbG90IGluY2x1ZGluZyBQaG80IGFidW5kYW5jZSwgX1BITzVfIHJlcG9ydGVyIHN0cmVuZ3RoIGFuZCBmb2xkIGluZHVjdGlvbiB2YWx1ZXMuKiogUGhvNC1HRlAgYW5kIFBITzVwLW1DaGVycnkgaW50ZW5zaXRpZXMgd2VyZSBxdWFudGlmaWVkIGFzIGRlZmluZWQgYWJvdmUuIFN0cmFpbiBJRHMgYXJlIGxpc3RlZCBvbiB0aGUgdmVydGljYWwgYXhpcy4gSW4gKiooQSkqKiwgdGhlIHgtYXhpcyB2YWx1ZXMgcmVwcmVzZW50IHRoZSBNZWRpYW4gRmx1b3Jlc2NlbnQgSW50ZW5zaXR5IChNRkksIGFyYml0dXJ5IHVuaXRzKSBmb3IgZWl0aGVyIFBobzQtR0ZQIG9yIFBITzVwci1tQ2hlcnJ5IGFmdGVyIHN1YnRyYWN0aW5nIHRoZSBiYWNrZ3JvdW5kIChiYXNlZCBvbiBzdHJhaW5zIHdpdGhvdXQgdGhlIGNvcnJlc3BvbmRpbmcgZmx1b3Jlc2NlbnQgcHJvdGVpbikuIEluICoqKEIpKiosIHRoZSBmb2xkIGNoYW5nZSBmb3IgX1BITzVfIHJlcG9ydGVyIGlzIGNhbGN1bGF0ZWQgYXMgdGhlIGJhY2tncm91bmQtc3VidHJhY3RlZCBSRlAgbGV2ZWwgZGl2aWRlZCBieSB0aGUgYmFzYWwgZXhwcmVzc2lvbiBsZXZlbCwgYXMgbWVhc3VyZWQgYnkgdGhlIG1lYW4gb2YgdGhlIHR3byBzdHJhaW5zIGNvbnRhaW5pbmcgdGhlIHJlcG9ydGVyIGJ1dCBoYXZlIF9waG804oiGXy4gVGhlIG5vcm1hbGl6ZWQgaW5kdWN0aW9uIHJhdGlvIG9uIHRoZSByaWdodCBjb2x1bW4gaXMgY2FsY3VsYXRlZCBieSBkaXZpZGluZyB0aGUgaW5kdWN0aW9uIGZvbGQgY2hhbmdlIGZyb20gdGhlIGxlZnQgY29sdW1uIGJ5IHRoZSBjb3JyZXNwb25kaW5nIFBobzQtR0ZQIChiYWNrZ3JvdW5kIHN1YnRyYWN0ZWQpIGxldmVscyBhbmQgbXVsdGlwbGllZCBieSB0aGUgbWVkaWFuIFBobzQtR0ZQIGxldmVscyBvZiBhbGwgc3RyYWlucy4gVGhlIGRhc2hlZCBsaW5lcyBpbiBib3RoIGNvbHVtbnMgaW5kaWNhdGUgdGhlIGluZHVjdGlvbiBmb2xkIGNoYW5nZSBvZiAxLCBpLmUuIG5vIGNoYW5nZSBjb21wYXJlZCB0byB0aGUgX3BobzTiiIZfIHN0cmFpbnMuIEluIGJvdGggcGFuZWxzLCB0aGUgeC1heGVzIGFyZSBzcXVhcmUtcm9vdCB0cmFuc2Zvcm1lZCBzbyBhcyB0byBicmluZyBvdXRsaWVycyBpbnRvIHRoZSBwbG90IHdpdGhvdXQgY29tcHJlc3NpbmcgdGhlIHJlc3Qgb2YgdGhlIGRhdGEgcmFuZ2UuIEFuIGFzdGVyaXNrIG5leHQgdG8gYSBiYXIgaW5kaWNhdGVzIGFuIG92ZXJuaWdodCBncm93dGggaW5zdGVhZCBvZiBhIG1pZC1sb2cgcGhhc2UgZ3Jvd3RoIHdhcyB1c2VkIGZvciBxdWFudGlmaWNhdGlvbi4KCl9EaXNjdXNzaW9uc18KCi0gSW4gZmFjdCwgYWZ0ZXIgbm9ybWFsaXppbmcgYnkgUGhvNCBhYnVuZGFuY2UsIHRoZSBwbGFzbWlkIGFwcHJvYWNoIHlpZWxkcyByZWxhdGl2ZWx5IGNvbnNpc3RlbnQgaW5kdWN0aW9uIHJhdGlvcyBmb3IgdGhlIHNhbWUgY29uc3RydWN0LCB3aGlsZSB0aGUgZXhvZ2Vub3VzbHkgaW50ZWdyYXRlZCBQaG80IHNvbWVob3cgc2hvd2VkIG1vcmUgdmFyaWFiaWxpdHku