require(tidyverse)
require(cowplot)

Goal

This is to repeat the 2020-12-21 experiment.

Material and methods

See gDoc. This time I reverted to one o/n growth. The second growth was done in the 96-well clear plate (not deep well). Cells were directly diluted into PBS and run on the flow cytometer.

Table of strains

Data and analysis

Import data

dat <- read_csv("20201223-Pho4-GFP-stats.csv")

── Column specification ─────────────────────────────────────────────────────────────────────
cols(
  Sample = col_character(),
  Tube = 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"))) %>% 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
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

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.basal <- dat %>% filter(PHO5RFP, Pho4 == "pho4-", Parameter == "PHO5pr-mCherry") %>% pull(Median) %>% mean()

# 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_text(aes(label = ifelse(Sample %in% issues, "*", ""), hjust = -0.2, vjust = 0.8), color = "black", size = 5) +
  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 = expansion(mult = c(0.01,0.1))) +
  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). 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.

# 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 = `PHO5pr-mCherry`, # I didn't include a RFP- strain in this experiment
         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)) +
  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()
  
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_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(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 = expansion(mult=c(0.01,0.1))) + 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. 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.

Conclusion

  • If CRISPR can boost the gene editing efficiency, prefers the endogenous method.
  • Plasmid is a viable approach for 1) quickly assessing the phenotypes of the constructs and 2) a backup should the endogenous approach encounter technical difficulties.
LS0tCnRpdGxlOiBhbmFseXplIGZsb3cgY3l0b21ldHJ5IGRhdGEgZnJvbSAyMDIwLTEyLTIzCmF1dGhvcjogQmluIEhlCmRhdGU6IDIwMjAtMTItMjMKb3V0cHV0OiAKICBodG1sX25vdGVib29rOgogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6IHRydWUKICAgIGRmX3ByaW50OiBkZWZhdWx0CiAgICBjb2RlX2ZvbGRpbmc6IGhpZGUKLS0tCgpgYGB7ciBzZXR1cH0KcmVxdWlyZSh0aWR5dmVyc2UpCnJlcXVpcmUoY293cGxvdCkKYGBgCgojIyBHb2FsCgpUaGlzIGlzIHRvIHJlcGVhdCB0aGUgMjAyMC0xMi0yMSBleHBlcmltZW50LgoKIyMgTWF0ZXJpYWwgYW5kIG1ldGhvZHMKClNlZSBnRG9jLiBUaGlzIHRpbWUgSSByZXZlcnRlZCB0byBvbmUgby9uIGdyb3d0aC4gVGhlIHNlY29uZCBncm93dGggd2FzIGRvbmUgaW4gdGhlIDk2LXdlbGwgY2xlYXIgcGxhdGUgKG5vdCBkZWVwIHdlbGwpLiBDZWxscyB3ZXJlIGRpcmVjdGx5IGRpbHV0ZWQgaW50byBQQlMgYW5kIHJ1biBvbiB0aGUgZmxvdyBjeXRvbWV0ZXIuCgojIyMgVGFibGUgb2Ygc3RyYWlucwohW10oLi4vMjAyMDEyMjEtUGhvNC1HRlAtcGxhc21pZC1sZXUyLXRlc3QvaW1nL3N0cmFpbnMtZ2Vub3R5cGUucG5nKQoKIyMgRGF0YSBhbmQgYW5hbHlzaXMKIyMjIEltcG9ydCBkYXRhCmBgYHtyfQpkYXQgPC0gcmVhZF9jc3YoIjIwMjAxMjIzLVBobzQtR0ZQLXN0YXRzLmNzdiIpCmRhdCA8LSBkYXQgJT4lIG11dGF0ZShQaG80R0ZQID0gZmFjdG9yKFBobzRHRlAsIGxldmVscyA9IGMoIk5vLUdGUCIsIlNjUGhvNC1tTmVvbiIsIlNjUGhvNC1FR0ZQIiwgIkNnUGhvNC1tTmVvbiIpKSwgR3JvdXAgPSBmYWN0b3IoR3JvdXAsIGxldmVscyA9IGMoImNvbnRyb2wiLCAiZW5kb2dlbm91cyIsICJleG9nZW5vdXMiLCAicGxhc21pZCIpKSwgUGhvNCA9IGZhY3RvcihQaG80LCBsZXZlbHMgPSBjKCJwaG80LSIsIlNjUGhvNCIsICJDZ1BobzQiKSkpICU+JSBmaWx0ZXIoU2FtcGxlICE9ICJHMiIpICMgcmVtb3ZlIEcyIGFzIGl0IG1vc3QgbGlrZWx5IGhhZCBtdWx0aXBsZSBQSE81cHItbUNoZXJyeSBpbnRlZ3JhdGVkIGFuZCBjYXVzZXMgdGhlIHJlc3Qgb2YgdGhlIFJGUCBkYXRhIHRvIGJlIGNvbXByZXNzZWQKaXNzdWVzIDwtIGMoIkczIiwiQjMiLCJDMSIsIkMyIiwiRDEiLCJFMyIpICMgc2VlIGJlbG93IGZvciByZWFzb25zCmBgYApMb29raW5nIGF0IHRoZSBkZXRhaWxlZCBwbG90cywgSSBpZGVudGlmaWVkIGEgZmV3IHNhbXBsZXMgdGhhdCBhcmUgcHJvYmxlbWF0aWMuCgp8IHwgfCB8IHwKfDotLTp8Oi0tOnw6LS06fDotLTp8CnwgbGFjayBfUEhPNXByLW1DaGVycnlfIHwgdHdvIHBvcHVsYXRpb25zIHwgdG9vIGZldyBjZWxscyBjb2xsZWN0ZWQgfAp8ICFbXSguL2ltZy9CMy5wbmcpIHwgIVtdKC4vaW1nL0MxLnBuZykgfCAhW10oLi9pbWcvQzIucG5nKSB8CnwgdHdvIHBvcHVsYXRpb25zIHwgdHdvIHBvcHVsYXRpb25zIHwgdHdvIHBvcHVsYXRpb25zIHwKfCAhW10oLi9pbWcvRDEucG5nKSB8ICFbXSguL2ltZy9FMy5wbmcpIHwgIVtdKC4vaW1nL0czLnBuZykgfAogCgojIyMgUGhvNC1HRlAgZXhwcmVzc2lvbiBsZXZlbHMKRmlyc3QgbG9vayBhdCB0aGUgbGV2ZWwgb2YgUGhvNC1HRlAgY29tcGFyZWQgd2l0aCB0aGUgbmVnYXRpdmUgY29udHJvbHMuCmBgYHtyLCBlY2hvID0gRiwgZmlnLmhlaWdodCA9IDYsIGZpZy53aWR0aCA9IDZ9CmdmcC5iZyA8LSBkYXQgJT4lIGZpbHRlcihQaG80R0ZQID09ICJOby1HRlAiLCBQYXJhbWV0ZXIgPT0gIlBobzQtR0ZQIikgJT4lIHB1bGwoTWVkaWFuKSAlPiUgbWVhbigpCnAxIDwtIGRhdCAlPiUgZmlsdGVyKFBhcmFtZXRlciA9PSAiUGhvNC1HRlAiKSAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gU2FtcGxlLCB5ID0gTWVkaWFuLCBmaWxsID0gIEdyb3VwKSkgKyAKICBnZW9tX3RleHQoYWVzKGxhYmVsID0gaWZlbHNlKFNhbXBsZSAlaW4lIGlzc3VlcywgIioiLCAiIiksIGhqdXN0ID0gLTAuMiwgdmp1c3QgPSAwLjgpLCBjb2xvciA9ICJibGFjayIsIHNpemUgPSA1KSArCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIsIHBvc2l0aW9uID0gcG9zaXRpb25fZG9kZ2UyKHdpZHRoID0gMC45KSkgKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IGdmcC5iZywgbGluZXR5cGUgPSAiZGFzaGVkIiwgYWxwaGEgPSAwLjYpICsKICBmYWNldF9ncmlkKFBobzRHRlB+Liwgc2NhbGVzID0gImZyZWVfeSIsIHNwYWNlID0gImZyZWVfeSIpICsKICBzY2FsZV9maWxsX2JyZXdlcih0eXBlID0gImRpdiIsIGRyb3AgPSBGQUxTRSkgKyB5bGFiKCJNRkkiKSArCiAgY29vcmRfZmxpcCgpICsgc2NhbGVfeV9jb250aW51b3VzKGV4cGFuZCA9IGV4cGFuc2lvbihtdWx0ID0gYygwLjAxLDAuMSkpKSArCiAgdGhlbWVfYncoKSArIGxhYnModGl0bGUgPSAiR0ZQIGZsdW9yZXNjZW50IGludGVuc2l0eSAoYXJiaXRyYXJ5IHVuaXRzKSIsIHN1YnRpdGxlID0gImRhc2hlZCBsaW5lIGluZGljYXRlcyBiYWNrZ3JvdW5kIGZsdW9yZXNjZW5jZSIpCgpwMQpgYGAKKipGaWd1cmUgMSBQaG80LUdGUCBpbnRlbnNpdHkgYnkgc3RyYWluLioqIFBobzQtR0ZQIGludGVuc2l0aWVzIHdlcmUgcXVhbnRpZmllZCBvbiBhbiBBdHR1bmUgTnhUIGZsb3cgY3l0b21ldGVyIHVzaW5nIDQwMCBtViBvbiB0aGUgQkwxIGNoYW5uZWwuIEFjcXVpc2l0aW9uIHJhdGUgaXMgMjAwIHVsL21pbi4gQXQgbGVhc3QgMTAsMDAwIGV2ZW50cyB3ZXJlIGNvbGxlY3RlZCBhbmQgdGhlIG1lZGlhbiBmbHVvcmVzY2VudCBpbnRlbnNpdHkgKE1GSSwgYXJiaXRyYXJ5IHVuaXRzKSB3ZXJlIHByZXNlbnRlZCBvbiB0aGUgeC1heGlzLCB3aGlsZSBzdHJhaW4gSURzIGFyZSBsaXN0ZWQgb24gdGhlIHZlcnRpY2FsIGF4aXMuIEFuIGFzdGVyaXNrIG5leHQgdG8gYSBiYXIgaW5kaWNhdGVzIGlzc3VlcyBmb3VuZCB3aXRoIHRoZSBzYW1wbGUgKHNlZSBtZXRob2RzIHNlY3Rpb24gZm9yIGRldGFpbHMpLgoKX0Rpc2N1c3Npb25fCgotIFNvbWV3aGF0IHN1cnByaXNpbmcgdG8gbWUsIHRoZSBleG9nZW5vdXNseSBpbnRlZ3JhdGVkIFBobzQtR0ZQLCBleGNlcHQgZm9yIHRoZSBTY1BobzQtbU5lb24sIHNlZW0gdG8gaGF2ZSByYXRoZXIgbG93IGZsdW9yZXNjZW50IGludGVuc2l0eS4gRm9yIGV4YW1wbGUsIEYxLCBFMiBhbmQgRTMgYWxsIGhhdmUgdmVyeSBsb3cgR0ZQIHNpZ25hbHMuCi0gTGFzdCB0aW1lIChzZWUgWzIwMjAtMTItMjEgcmVwb3J0XShodHRwczovL3JwdWJzLmNvbS9lbXB0eWhiL1BobzQtR0ZQLXRlc3QtMjAyMDEyMjEpKSBJIG9ic2VydmVkIGhpZ2hlciBTY1BobzQtbU5lb24gYW5kIFNjUGhvNC1FR0ZQIGV4cHJlc3Npb24gaW4gdGhlIHlIMjk1IGJhY2tncm91bmQgKFAsIFEpIHRoYW4gaW4gdGhlIHlIMjk2IGJhY2tncm91bmQgKE0sIE4pLiBJIHN1c3BlY3RlZCB0aGVyZSBtYXkgYmUgc29tZSBmZWVkYmFjayBkdWUgdG8gdGhlIGxhY2sgb2YgUGhvMi4gVGhpcyB0aW1lIGhvd2V2ZXIsIHRoZWlyIGV4cHJlc3Npb24gbGV2ZWxzIGFwcGVhciB0byBiZSB0aGUgc2FtZS4gVGhlIG1haW4gZGlmZmVyZW5jZSBpbiB0aGUgZXhwZXJpbWVudGFsIHByb3RvY29sIGNvbXBhcmVkIHRvIHRoZSBsYXN0IHRpbWUgaXMgdGhhdCBJIGRpZCBvbmUgby9uIGdyb3d0aCBiZWZvcmUgdGhlIGZpbmFsIGdyb3d0aCBpbnN0ZWFkIG9mIHR3by4KCiMjIyBQSE81cHItbUNoZXJyeSByZXBvcnRlciBsZXZlbHMKYGBge3IsIGZpZy5oZWlnaHQgPSA3LCBmaWcud2lkdGggPSA3fQpyZnAuYmFzYWwgPC0gZGF0ICU+JSBmaWx0ZXIoUEhPNVJGUCwgUGhvNCA9PSAicGhvNC0iLCBQYXJhbWV0ZXIgPT0gIlBITzVwci1tQ2hlcnJ5IikgJT4lIHB1bGwoTWVkaWFuKSAlPiUgbWVhbigpCgojIHJlbW92ZWQgYSBmZXcgb3V0bGllcnMgd2l0aCBNRkkgPiAyMGsKcDEgPC0gZGF0ICU+JSBmaWx0ZXIoUEhPNVJGUCkgJT4lIAogIGdncGxvdChhZXMoeCA9IFNhbXBsZSwgeSA9IE1lZGlhbiwgZmlsbCA9ICBHcm91cCwgY29sb3IgPSBQSE8yKSkgKyAKICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZTIod2lkdGggPSAwLjkpKSArCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IGlmZWxzZShTYW1wbGUgJWluJSBpc3N1ZXMsICIqIiwgIiIpLCBoanVzdCA9IC0wLjIsIHZqdXN0ID0gMC44KSwgY29sb3IgPSAiYmxhY2siLCBzaXplID0gNSkgKwogIGdlb21faGxpbmUoYWVzKHlpbnRlcmNlcHQgPSBpZmVsc2UoUGFyYW1ldGVyID09ICJQaG80LUdGUCIsIGdmcC5iZywgcmZwLmJhc2FsKSksIGxpbmV0eXBlID0gMiwgYWxwaGEgPSAwLjYpICsKICBmYWNldF9ncmlkKFBobzQgfiBQYXJhbWV0ZXIsIHNjYWxlcyA9ICJmcmVlIiwgc3BhY2UgPSAiZnJlZV95IikgKyB5bGFiKCJNRkkiKSArCiAgc2NhbGVfZmlsbF9icmV3ZXIodHlwZSA9ICJkaXYiLCBkcm9wID0gRkFMU0UpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoInJlZCIsIE5BKSkgKwogIGNvb3JkX2ZsaXAoKSArIHNjYWxlX3lfY29udGludW91cyhleHBhbmQgPSBleHBhbnNpb24obXVsdCA9IGMoMC4wMSwwLjEpKSkgKwogIHRoZW1lX2J3KCkKcDEKYGBgCioqRmlndXJlIDIgQ29ycmVzcG9uZGluZyBQaG80LUdGUCBhbmQgUEhPNXByLW1DaGVycnkgcmVwb3J0ZXIgZmx1b3Jlc2NlbmNlIGludGVuc2l0eSBwZXIgc3RyYWluLioqIFBobzQtR0ZQIGFuZCBQSE81cC1tQ2hlcnJ5IGludGVuc2l0aWVzIHdlcmUgcXVhbnRpZmllZCBvbiBhbiBBdHR1bmUgTnhUIGZsb3cgY3l0b21ldGVyIHVzaW5nIDQwMCBtViBvbiB0aGUgQkwxIGFuZCA0MzAgbVYgb24gdGhlIFlMMiBjaGFubmVscyByZXNwZWN0aXZlbHkuIEFjcXVpc2l0aW9uIHJhdGUgaXMgMjAwIHVsL21pbi4gQXQgbGVhc3QgMTAsMDAwIGV2ZW50cyB3ZXJlIGNvbGxlY3RlZC4gU3RyYWluIElEcyBhcmUgbGlzdGVkIG9uIHRoZSB2ZXJ0aWNhbCBheGlzIGFuZCB0aGUgTWVkaWFuIEZsdW9yZXNjZW50IEludGVuc2l0eSAoTUZJLCBhcmJpdHVyeSB1bml0cykgZm9yIGVhY2ggY2hhbm5lbCBvbiB0aGUgaG9yaXpvbnRhbCBheGlzLiBBbiBhc3RlcmlzayBuZXh0IHRvIGEgYmFyIGluZGljYXRlcyBhbiBvdmVybmlnaHQgZ3Jvd3RoIGluc3RlYWQgb2YgYSBtaWQtbG9nIHBoYXNlIGdyb3d0aCB3YXMgdXNlZCBmb3IgcXVhbnRpZmljYXRpb24uIFRoZSBkYXNoZWQgdmVydGljYWwgbGluZSBmb3IgUGhvNC1HRlAgaW5kaWNhdGVzIHRoZSBhdXRvZmx1b3Jlc2NlbmNlIGFzIGNhbGN1bGF0ZWQgYnkgdGhlIG1lYW4gb2YgdGhlIGludGVuc2l0aWVzIGluIHRoZSBzdHJhaW5zIHdpdGhvdXQgR0ZQOyB0aGUgZGFzaGVkIHZlcnRpY2FsIGxpbmUgZm9yIHRoZSBSRlAgcGxvdCBpbmRpY2F0ZXMgdGhlIGJhc2FsIGxldmVsIGV4cHJlc3Npb24gZnJvbSB0aGUgcmVwb3J0ZXIgd2l0aG91dCBQaG80LCBjYWxjdWxhdGVkIGJ5IHRoZSBhdmVyYWdlIG9mIHlIMjk1IGFuZCB5SDI5NiwgYm90aCBvZiB3aGljaCBsYWNrIFBobzQgYnV0IGhhcyB0aGUgcmVwb3J0ZXIpLiBBbiBhc3RlcmlzayBuZXh0IHRvIGEgYmFyIGluZGljYXRlcyBpc3N1ZXMgZm91bmQgd2l0aCB0aGUgc2FtcGxlIChzZWUgbWV0aG9kcyBzZWN0aW9uIGZvciBkZXRhaWxzKS4KCl9EaXNjdXNzaW9uXwoKLSBUaGlzIGV4cGVyaW1lbnQgc2hvd2VkIGEgbG90IG9mIHZhcmlhYmlsaXR5IGFtb25nIHRoZSBiaW9sb2dpY2FsIHJlcGxpY2F0ZXMsIGVzcGVjaWFsbHkgZm9yIGV4b2dlbm91c2x5IGludGVncmF0ZWQgQ2dQaG80IChDIGFuZCBGKS4gVGhpcyB3YXNuJ3QgdGhlIGNhc2UgaW4gbXkgcHJldmlvdXMgZXhwZXJpbWVudC4gSXQgd2lsbCBiZSB1c2VmdWwgdG8gcmVwZWF0IHRoaXMgYWdhaW4uCi0geUgyNjcgZG9lc24ndCBjb25mb3JtIHRvIG15IGV4cGVjdGF0aW9uIC0tIGl0IGhhcyBTY1BobzQgYW5kIFNjUGhvMiBhcyB3ZWxsIGFzIHRoZSBfUEhPNXByLW1DaGVycnlfIHJlcG9ydGVyLCBhbmQgdGh1cyBzaG91bGQgZ2l2ZSBub3JtYWwgbGV2ZWxzIG9mIFJGUCwgYnV0IGRpZG4ndC4KCiMjIyBfUEhPNXByLW1DaGVycnlfIGluZHVjdGlvbiBsZXZlbHMgbm9ybWFsaXplZCBieSBQaG80IGFidW5kYW5jZQpXZSB3aWxsIGZpcnN0IHRyYW5zZm9ybSB0aGUgcmF3IEdGUCBhbmQgUkZQIGludGVuc2l0aWVzIHRvIG1ha2UgdGhlbSBtb3JlIGludGVycHJldGFibGUuIEZvciB0aGUgR0ZQIGludGVuc2l0eSwgYXMgdGhlcmUgaXMgYSBzdWJzdGFudGlhbCBiYWNrZ3JvdW5kLCB3ZSB3aWxsIHN1YnRyYWN0IHRoZSBiYWNrZ3JvdW5kIGZyb20gYWxsIHRoZSBHRlAtY29udGFpbmluZyBzdHJhaW5zIHRvIG9idGFpbiB0aGUgbWVhbmluZ2Z1bCBtZWFzdXJlIGZvciBQaG80IHByb3RlaW4gbGV2ZWxzLiBGb3IgUkZQLCB0aGVyZSBpcyBtaW5pbWFsIGJhY2tncm91bmQgKHNlZSBiZWxvdykuIEhvd2V2ZXIsIHRoZXJlIGlzIGEgImJhc2FsIiBleHByZXNzaW9uIG9mIHRoZSByZXBvcnRlciBpbiB0aGUgYWJzZW5jZSBvZiBQaG80IC0tIHdoYXQgd2UgYXJlIGludGVyZXN0ZWQgaW4gaXMgbm90IHRoZSBhYnNvbHV0ZSBsZXZlbCBvZiByZXBvcnRlciBleHByZXNzaW9uIGJ1dCB0aGUgZm9sZCBpbmR1Y3Rpb24gY29tcGFyZWQgd2l0aCB0aGUgX3BobzTiiIZfIHN0cmFpbnMuCmBgYHtyIHRyYW5zZm9ybX0KIyBjYWxjdWxhdGUgZ2ZwIGJhY2tncm91bmQKZ2ZwLmJnIDwtIGRhdCAlPiUgZmlsdGVyKFBobzRHRlAgPT0gIk5vLUdGUCIsIFBhcmFtZXRlciA9PSAiUGhvNC1HRlAiKSAlPiUgcHVsbChNZWRpYW4pICU+JSBtZWFuKCkKIyB0cmFuc2Zvcm0KZGF0MSA8LSBkYXQgJT4lIHNlbGVjdCgtQ291bnQsIC1DViwgLXJDVikgJT4lIAogIHBpdm90X3dpZGVyKG5hbWVzX2Zyb20gPSBQYXJhbWV0ZXIsIHZhbHVlc19mcm9tID0gTWVkaWFuKSAlPiUgCiAgbXV0YXRlKEdGUC5ub0JHID0gaWZlbHNlKFBobzRHRlAgPT0gIk5vLUdGUCIsIE5BLCBgUGhvNC1HRlBgIC0gZ2ZwLmJnKSwKICAgICAgICAgUkZQLm5vQkcgPSBgUEhPNXByLW1DaGVycnlgLCAjIEkgZGlkbid0IGluY2x1ZGUgYSBSRlAtIHN0cmFpbiBpbiB0aGlzIGV4cGVyaW1lbnQKICAgICAgICAgUkZQLkZDID0gaWZlbHNlKFBITzVSRlAsIFJGUC5ub0JHIC8gcmZwLmJhc2FsLCBOQSksCiAgICAgICAgIG5SRlAuRkMgPSBSRlAuRkMgLyBHRlAubm9CRyAqIG1lZGlhbihHRlAubm9CRywgbmEucm0gPSBUKSkKYGBgCgpgYGB7ciBwbG90X25vcm1hbGl6ZWRfaW5kdWN0aW9uLCBmaWcuaGVpZ2h0ID0gNywgZmlnLndpZHRoPTEwLCB3YXJuaW5nPUZBTFNFfQpkYXQyIDwtIGRhdDEgJT4lIGZpbHRlcihQaG80R0ZQICE9ICJOby1HRlAiLCBQSE81UkZQKQpwMSA8LSBkYXQyICU+JSAKICBtdXRhdGUoR0ZQLm5vQkcgPSBHRlAubm9CRyAvIDEwMDAsIFJGUC5ub0JHID0gUkZQLm5vQkcgLyAxMDAwKSAlPiUgCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKEdGUC5ub0JHLCBSRlAubm9CRyksIG5hbWVzX3RvID0gIlBhcmFtZXRlciIsIHZhbHVlc190byA9ICJWYWx1ZSIpICU+JQogIG11dGF0ZShQYXJhbWV0ZXIgPSBmYWN0b3IoUGFyYW1ldGVyLCBsZXZlbHMgPSBjKCJHRlAubm9CRyIsICJSRlAubm9CRyIpLCAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbHMgPSBjKCJQaG80LUdGUCBhYnVuZGFuY2UiLCAiUEhPNXByLW1DaGVycnkgbGV2ZWwiKSksCiAgICAgICAgIEdyb3VwID0gZmFjdG9yKEdyb3VwLCBsZXZlbHMgPSBjKCJjb250cm9sIiwgImVuZG9nZW5vdXMiLCAiZXhvZ2Vub3VzIiwgInBsYXNtaWQiKSkpICU+JSAKICBnZ3Bsb3QoYWVzKHggPSBTYW1wbGUsIHkgPSBWYWx1ZSwgZmlsbCA9ICBHcm91cCwgY29sb3IgPSBQSE8yKSkgKyAKICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IiwgcG9zaXRpb24gPSBwb3NpdGlvbl9kb2RnZTIod2lkdGggPSAwLjkpKSArCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbCA9IGlmZWxzZShTYW1wbGUgJWluJSBpc3N1ZXMsICIqIiwgIiIpLCBoanVzdCA9IC0wLjIsIHZqdXN0ID0gMC44KSwgY29sb3IgPSAiYmxhY2siLCBzaXplID0gNSkgKwogIGZhY2V0X2dyaWQoUGhvNEdGUCB+IFBhcmFtZXRlciwgc2NhbGVzID0gImZyZWUiLCBzcGFjZSA9ICJmcmVlX3kiKSArCiAgc2NhbGVfZmlsbF9icmV3ZXIodHlwZSA9ICJkaXYiLCBkcm9wID0gRkFMU0UpICsgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGMoInJlZCIsIE5BKSkgKwogIGNvb3JkX2ZsaXAoKSArIHNjYWxlX3lfY29udGludW91cyhleHBhbmQgPSBleHBhbnNpb24obXVsdD1jKDAuMDEsMC4xKSkpICsgeWxhYigiTUZJICh4MTAwMCwgYS51LikiKSArIAogIHRoZW1lX2J3KCkKICAKcDIgPC0gZGF0MiAlPiUgCiAgcGl2b3RfbG9uZ2VyKGNvbHMgPSBjKFJGUC5GQywgblJGUC5GQyksIG5hbWVzX3RvID0gIlBhcmFtZXRlciIsIHZhbHVlc190byA9ICJWYWx1ZSIpICU+JQogIG11dGF0ZShQYXJhbWV0ZXIgPSBmYWN0b3IoUGFyYW1ldGVyLCBsZXZlbHMgPSBjKCJSRlAuRkMiLCAiblJGUC5GQyIpLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxhYmVscyA9IGMoIlBITzUgZm9sZCBpbmR1Y3Rpb24iLCAiUEhPNSBpbmR1Y3Rpb24gLyBQaG80LUdGUCIpKSwKICAgICAgICAgR3JvdXAgPSBmYWN0b3IoR3JvdXAsIGxldmVscyA9IGMoImNvbnRyb2wiLCAiZW5kb2dlbm91cyIsICJleG9nZW5vdXMiLCAicGxhc21pZCIpKSkgJT4lIAogIGdncGxvdChhZXMoeCA9IFNhbXBsZSwgeSA9IFZhbHVlLCBmaWxsID0gIEdyb3VwLCBjb2xvciA9IFBITzIpKSArIAogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiLCBwb3NpdGlvbiA9IHBvc2l0aW9uX2RvZGdlMih3aWR0aCA9IDAuOSkpICsKICBnZW9tX3RleHQoYWVzKGxhYmVsID0gaWZlbHNlKFNhbXBsZSAlaW4lIGlzc3VlcywgIioiLCAiIiksIGhqdXN0ID0gLTAuMiwgdmp1c3QgPSAwLjgpLCBjb2xvciA9ICJibGFjayIsIHNpemUgPSA1KSArCiAgZ2VvbV9obGluZSh5aW50ZXJjZXB0ID0gMSwgbGluZXR5cGUgPSAyKSArCiAgZmFjZXRfZ3JpZChQaG80R0ZQIH4gUGFyYW1ldGVyLCBzY2FsZXMgPSAiZnJlZSIsIHNwYWNlID0gImZyZWVfeSIpICsKICBzY2FsZV9maWxsX2JyZXdlcih0eXBlID0gImRpdiIsIGRyb3AgPSBGKSArIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCJyZWQiLCBOQSkpICsKICBjb29yZF9mbGlwKCkgKyBzY2FsZV95X2NvbnRpbnVvdXMoZXhwYW5kID0gZXhwYW5zaW9uKG11bHQ9YygwLjAxLDAuMSkpKSArIHlsYWIoIkZvbGQgSW5kdWN0aW9uIikgKyB4bGFiKCIiKSArCiAgdGhlbWVfYncoKQoKIyMgcGxhY2Ugc2hhcmVkIGxlZ2VuZCBhdCB0aGUgYm90dG9tCiMjIHJlZmVyZW5jZTogaHR0cHM6Ly93aWxrZWxhYi5vcmcvY293cGxvdC9hcnRpY2xlcy9zaGFyZWRfbGVnZW5kcy5odG1sCmxlZ2VuZCA8LSBnZXRfbGVnZW5kKAogIHAxICsgCiAgZ3VpZGVzKGNvbG9yID0gZ3VpZGVfbGVnZW5kKG5yb3cgPSAxKSwgZmlsbCA9IGd1aWRlX2xlZ2VuZChucm93ID0gMSkpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAiYm90dG9tIikKKQpwcm93IDwtIHBsb3RfZ3JpZCgKICBwMSArIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpLAogIHAyICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIiksCiAgYWxpZ24gPSAndmgnLAogIGxhYmVscyA9IGMoIkEiLCAiQiIsICJDIiksCiAgaGp1c3QgPSAtMSwKICBucm93ID0gMQopCnBsb3RfZ3JpZChwcm93LCBsZWdlbmQsIG5jb2wgPSAxLCByZWxfaGVpZ2h0cyA9IGMoMSwgLjEpKQpgYGAKKipGaWd1cmUgMyBDb21wb3NpdGUgcGxvdCBpbmNsdWRpbmcgUGhvNCBhYnVuZGFuY2UsIF9QSE81XyByZXBvcnRlciBzdHJlbmd0aCBhbmQgZm9sZCBpbmR1Y3Rpb24gdmFsdWVzLioqIFBobzQtR0ZQIGFuZCBQSE81cC1tQ2hlcnJ5IGludGVuc2l0aWVzIHdlcmUgcXVhbnRpZmllZCBhcyBkZWZpbmVkIGFib3ZlLiBTdHJhaW4gSURzIGFyZSBsaXN0ZWQgb24gdGhlIHZlcnRpY2FsIGF4aXMuIEluICoqKEEpKiosIHRoZSB4LWF4aXMgdmFsdWVzIHJlcHJlc2VudCB0aGUgTWVkaWFuIEZsdW9yZXNjZW50IEludGVuc2l0eSAoTUZJLCBhcmJpdHVyeSB1bml0cykgZm9yIGVpdGhlciBQaG80LUdGUCBvciBQSE81cHItbUNoZXJyeS4gRm9yIFBobzQtR0ZQLCB0aGUgYmFja2dyb3VuZCBsZXZlbCBiYXNlZCBvbiBzdHJhaW5zIHdpdGhvdXQgUGhvNC1HRlAgd2FzIHN1YnRyYWN0ZWQuIE5vIGJhY2tncm91bmQgc3VidHJhY3Rpb24gd2FzIGRvbmUgZm9yIG1DaGVycnksIGJ1dCBwYXN0IHJlc3VsdHMgc3VnZ2VzdCB0aGF0IHRoZSBiYWNrZ3JvdW5kIGZsdW9yZXNjZW5jZSBpcyBuZWdsZWdpYmxlIHJlbGF0aXZlIHRvIHRoZSBwb3NpdGl2ZSBzdHJhaW5zLiBJbiAqKihCKSoqLCB0aGUgZm9sZCBjaGFuZ2UgZm9yIF9QSE81XyByZXBvcnRlciBpcyBjYWxjdWxhdGVkIGFzIHRoZSBiYWNrZ3JvdW5kLXN1YnRyYWN0ZWQgUkZQIGxldmVsIGRpdmlkZWQgYnkgdGhlIGJhc2FsIGV4cHJlc3Npb24gbGV2ZWwsIGFzIG1lYXN1cmVkIGJ5IHRoZSBtZWFuIG9mIHRoZSB0d28gc3RyYWlucyBjb250YWluaW5nIHRoZSByZXBvcnRlciBidXQgaGF2ZSBfcGhvNOKIhl8uIFRoZSBub3JtYWxpemVkIGluZHVjdGlvbiByYXRpbyBvbiB0aGUgcmlnaHQgY29sdW1uIGlzIGNhbGN1bGF0ZWQgYnkgZGl2aWRpbmcgdGhlIGluZHVjdGlvbiBmb2xkIGNoYW5nZSBmcm9tIHRoZSBsZWZ0IGNvbHVtbiBieSB0aGUgY29ycmVzcG9uZGluZyBQaG80LUdGUCAoYmFja2dyb3VuZCBzdWJ0cmFjdGVkKSBsZXZlbHMgYW5kIG11bHRpcGxpZWQgYnkgdGhlIG1lZGlhbiBQaG80LUdGUCBsZXZlbHMgb2YgYWxsIHN0cmFpbnMuIFRoZSBkYXNoZWQgbGluZXMgaW4gYm90aCBjb2x1bW5zIGluZGljYXRlIHRoZSBpbmR1Y3Rpb24gZm9sZCBjaGFuZ2Ugb2YgMSwgaS5lLiBubyBjaGFuZ2UgY29tcGFyZWQgdG8gdGhlIF9waG804oiGXyBzdHJhaW5zLiBJbiBib3RoIHBhbmVscywgdGhlIHgtYXhlcyBhcmUgc3F1YXJlLXJvb3QgdHJhbnNmb3JtZWQgc28gYXMgdG8gYnJpbmcgb3V0bGllcnMgaW50byB0aGUgcGxvdCB3aXRob3V0IGNvbXByZXNzaW5nIHRoZSByZXN0IG9mIHRoZSBkYXRhIHJhbmdlLiBBbiBhc3RlcmlzayBuZXh0IHRvIGEgYmFyIGluZGljYXRlcyBhbiBvdmVybmlnaHQgZ3Jvd3RoIGluc3RlYWQgb2YgYSBtaWQtbG9nIHBoYXNlIGdyb3d0aCB3YXMgdXNlZCBmb3IgcXVhbnRpZmljYXRpb24uIEFuIGFzdGVyaXNrIG5leHQgdG8gYSBiYXIgaW5kaWNhdGVzIGlzc3VlcyBmb3VuZCB3aXRoIHRoZSBzYW1wbGUgKHNlZSBtZXRob2RzIHNlY3Rpb24gZm9yIGRldGFpbHMpLgoKX0Rpc2N1c3Npb25fCgotIFBsYXNtaWQtYm9ybiBQaG80LUdGUCBzdHJhaW5zIHNob3cgbW9yZSB2YXJpYWJpbGl0eSBpbiBQaG80IGFidW5kYW5jZSwgYnV0IHlpZWxkcyBxdWl0ZSBjb25zaXN0ZW50IGZvbGQgaW5kdWN0aW9uIHZhbHVlcyBhZnRlciBub3JtYWxpemluZyBieSB0aGUgR0ZQIGludGVuc2l0eS4gU29tZSBpc3N1ZXMgZG8gZXhpc3QsIGUuZy4gUTEsIFEyLiBCMiBhbmQgQjQncyBhYm5vcm1hbGx5IGhpZ2ggaW5kdWN0aW9uIGFmdGVyIG5vcm1hbGl6YXRpb24gaXMgZHVlIHRvIHRoZSB2ZXJ5IGxvdyBHRlAgaW50ZW5zaXR5LgotIFRoZSBleG9nZW5vdXNseSBpbnRlZ3JhdGVkIHN0cmFpbnMgc2hvdyBtb3JlIHZhcmlhYmlsaXR5LCBsaWtlbHkgZHVlIHRvIHR3byByZWFzb25zOiBtdWx0aXBsZS1pbnRlZ3JhdGlvbiBhdCB0aGUgdGltZSBvZiB0cmFuc2Zvcm1hdGlvbiBhbmQgc3BvbnRhbmVvdXMgbG9vcC1vdXQgbGVhZGluZyB0byBsb3NzIG9mIHRoZSBleHRyYSBjb3BpZXMgZHVyaW5nIHRoZSBvdXRncm93dGggKG9yIGV2ZW4gb24gdGhlIHBsYXRlcykKLSBCYXNlZCBvbiBsaW1pdGVkIGRhdGEsIHRoZSBlbmRvZ2Vub3VzbHkgaW50ZWdyYXRlZCBQaG80LUdGUCBoYXMgdGhlIGxvd2VzdCBjbG9uZS10by1jbG9uZSB2YXJpYWJpbGl0eS4gSWYgd2UgY291bGQgbWFrZSB0aGUgcmVwb3J0ZXIgY29uc3RydWN0IGFsc28gZW5kb2dlbm91cywgd2Ugd291bGQgZXhwZWN0IGhpZ2hseSByZXByb2R1Y2libGUgZGF0YS4KCiMjIENvbmNsdXNpb24KLSBJZiBDUklTUFIgY2FuIGJvb3N0IHRoZSBnZW5lIGVkaXRpbmcgZWZmaWNpZW5jeSwgcHJlZmVycyB0aGUgZW5kb2dlbm91cyBtZXRob2QuCi0gUGxhc21pZCBpcyBhIHZpYWJsZSBhcHByb2FjaCBmb3IgMSkgcXVpY2tseSBhc3Nlc3NpbmcgdGhlIHBoZW5vdHlwZXMgb2YgdGhlIGNvbnN0cnVjdHMgYW5kIDIpIGEgYmFja3VwIHNob3VsZCB0aGUgZW5kb2dlbm91cyBhcHByb2FjaCBlbmNvdW50ZXIgdGVjaG5pY2FsIGRpZmZpY3VsdGllcy4=