we first need to get the working directory

getwd()
[1] "/cloud/project"
#next, we need to install packages 
#ggplot is used for highly custoizable simple to complex visualizations , maptools is used ti import, export and manipulate shapeflies. It hellps yo perform basic geospatial analysis. 
pkg <- c("ggplot2", "scales", "maptools",
              "sp", "maps", "grid", "car" )
new.pkg <- pkg[!(pkg %in% installed.packages())]
if (length(new.pkg)) {
  install.packages(new.pkg)  
}
Installing package into ‘/cloud/lib/x86_64-pc-linux-gnu-library/4.4’
(as ‘lib’ is unspecified)
Warning in install.packages :
  package ‘maptools’ is not available for this version of R

A version of this package for your version of R might be available elsewhere,
see the ideas at
https://cran.r-project.org/doc/manuals/r-patched/R-admin.html#Installing-packages
# read the CSV with headers
za <- read.csv("zeroaccess.csv", header=T,sep ="," )
#In this line of code, we can view the csv file that we saved as the variable za
View(za)
#we use the library function to load ggplot and create graphics
library(ggplot2)
# create a ggplot instance with zeroaccess data
gg <- ggplot(data=za, aes(x=long, y=lat)) 
# add the points, set transparency to 1/40th 
gg <- gg + geom_point(size=1, color="#000099", alpha=1/40) 
# add axes labels
gg <- gg + xlab("Longitude") + ylab("Latitude")
# simplify the theme for aesthetics
gg <- gg + theme_bw() 
# this may take a while, over 800,000 points plotted
print(gg)



<!-- rnb-text-end -->


<!-- rnb-chunk-begin -->


<!-- rnb-output-begin eyJkYXRhIjoiXG48IS0tIHJuYi1zb3VyY2UtYmVnaW4gZXlKa1lYUmhJam9pWUdCZ2NseHVJMHhsZENkeklHbHVkbVZ6ZEdsbllYUmxJSGRvWlhSb1pYSWdjRzl3ZFd4aGRHbHZiaUJvWVhNZ1lXNGdhVzF3WVdOMElHOXVJSFJvWlNCdWRXMWlaWElnYjJZZ2FXNW1aV04wYVc5dWN5QnBiaUIwYUdseklHUmhkR0Z6WlhRdUlFWnZjbTExYkdGMFpTQjBhR1VnYm5Wc2JDQmhibVFnWVd4MFpYSnVZWFJwZG1VZ2FIbHdiM1JvWlhObGN5QjBieUIwWlhOMElIUm9hWE1nY21Wc1lYUnBiMjV6YUdsd0xseHVjM1Z0YldGeWVTaHNiU2hKYm1abFkzUnBiMjV6SUg0Z2NHOXdMQ0JrWVhSaFBXTnZkVzUwZVM1a1lYUmhLU2xjYm1CZ1lDSjkgLS0+XG5cbmBgYHJcbiNMZXQncyBpbnZlc3RpZ2F0ZSB3aGV0aGVyIHBvcHVsYXRpb24gaGFzIGFuIGltcGFjdCBvbiB0aGUgbnVtYmVyIG9mIGluZmVjdGlvbnMgaW4gdGhpcyBkYXRhc2V0LiBGb3JtdWxhdGUgdGhlIG51bGwgYW5kIGFsdGVybmF0aXZlIGh5cG90aGVzZXMgdG8gdGVzdCB0aGlzIHJlbGF0aW9uc2hpcC5cbnN1bW1hcnkobG0oSW5mZWN0aW9ucyB+IHBvcCwgZGF0YT1jb3VudHkuZGF0YSkpXG5gYGBcblxuPCEtLSBybmItc291cmNlLWVuZCAtLT5cbiJ9 -->


<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuI0xldCdzIGludmVzdGlnYXRlIHdoZXRoZXIgcG9wdWxhdGlvbiBoYXMgYW4gaW1wYWN0IG9uIHRoZSBudW1iZXIgb2YgaW5mZWN0aW9ucyBpbiB0aGlzIGRhdGFzZXQuIEZvcm11bGF0ZSB0aGUgbnVsbCBhbmQgYWx0ZXJuYXRpdmUgaHlwb3RoZXNlcyB0byB0ZXN0IHRoaXMgcmVsYXRpb25zaGlwLlxuc3VtbWFyeShsbShJbmZlY3Rpb25zIH4gcG9wLCBkYXRhPWNvdW50eS5kYXRhKSlcbmBgYCJ9 -->

```r
#Let's investigate whether population has an impact on the number of infections in this dataset. Formulate the null and alternative hypotheses to test this relationship.
summary(lm(Infections ~ pop, data=county.data))

Call:
lm(formula = Infections ~ pop, data = county.data)

Residuals:
    Min      1Q  Median      3Q     Max 
-365.26  -70.35   -5.70   59.59 2724.00 

Coefficients:
             Estimate Std. Error t value Pr(>|t|)    
(Intercept) 1.250e+02  2.416e+00  51.755  < 2e-16 ***
pop         4.228e-05  7.147e-06   5.916 3.67e-09 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 127.8 on 3070 degrees of freedom
Multiple R-squared:  0.01127,   Adjusted R-squared:  0.01095 
F-statistic:    35 on 1 and 3070 DF,  p-value: 3.668e-09
# requires package : ggplot2
# requires object: za (5-1)
# the "maps" and "mapproj" packages are used by ggplot
# load map data of the world
world <- map_data("world")
#Remove Antarctica
world <- subset(world, world$region!="Antarctica")
# load world data into ggplot object
gg <- ggplot(data=world, aes(x=long, y=lat))
# trace along the lat/long coords by group (countries)
gg <- gg + geom_path(aes(group=group), colour="gray70")
# now project using the mercator projection
# try different projections with ?mapproject
gg <- gg + coord_map("mercator", xlim=c(-200, 200))
# load up the ZeroAccess points, overiding the default data set
gg <- gg + geom_point(data=za, aes(long, lat), 
                      colour="#000099", alpha=1/40, size=1)
# remove text, axes ticks, grid lines and do gray border on white
gg <- gg + theme(text=element_blank(), 
                 axis.ticks=element_blank(),
                 panel.grid=element_blank(),
                 panel.background=element_rect(color="gray50",
                                               fill="white"))
print(gg)

Interpret the output

#The function map_data(“world”) loads a pre-built dataset of world map data, which contains coordinates for #the countries of the world. This data includes latitude, longitude, and country names. #world <- subset(world, world$region!=“Antarctica”)This line removes Antarctica from the world map data by #filtering out any rows where the region column equals “Antarctica.” #The ggplot() function initializes a ggplot object with the world map data. Here, it maps the longitude #(long) and latitude (lat) from the world dataset to the x and y axes of the plot #The geom_path() function is used to draw the borders of countries by connecting the latitude and longitude #coordinates in each country (defined by group). The color of the lines is set to gray70 (a light gray #color).coord_map(“mercator”) applies the Mercator projection to the world map. The xlim=c(-200, 200) #argument sets the longitude limits for the x-axis, essentially focusing the map on the typical world view. #geom_point() adds points to the map based on the data in the za dataset (likely a dataset with latitudes and #longitudes for certain locations, such as ZeroAccess points). ##size (size=1). theme() is used to customize the appearance of the map: ##axis.ticks=element_blank() removes axis ticks. ###border around the plot. #print(gg) outputs the final map to the R console or plotting window.

pop.lm <- lm(Infections ~ pop, data=county.data)
predict(pop.lm, data.frame(pop=6000000), interval="confidence")
       fit      lwr      upr
1 378.7109 295.9209 461.5009
View(county.data)
set.seed(1)
# generate 200 random numbers around 10
input <- rnorm(200, mean=10)
summary(input)

#interpret the syntax above 
#set.seed(1) sets the random number generator's seed to 1. This ensures that any random processes, like #generating random numbers, will produce the same result every time the code is run. It's useful for #reproducibility, so you or others can get the exact same output when running the code.
#rnorm(200, mean=10) generates 200 random numbers from a normal distribution (a bell curve) with:
#A mean of 10, meaning the numbers will be centered around 10.
#A standard deviation of 1 (the default value). This means most of the numbers will fall between 8 and 12, #but there will also be some that are outside of that range.
#The resulting 200 numbers are stored in the variable input.
#summary(input) provides a summary statistics of the generated data in input, including:
#Min: The minimum value in the dataset.
#1st Qu. (Quartile): The first quartile (25th percentile) value.
#Median: The median (50th percentile) value, which represents the middle of the data.
#Mean: The average of the dataset.
#3rd Qu. (Quartile): The third quartile (75th percentile) value.
#Max: The maximum value in the dataset.
# requires objects: input (5-16)
# generate output around a mean of 2 x input
output <- rnorm(200, mean=input*2)
# put into data frame to plot it
our.data <- data.frame(input, output)
gg <- ggplot(our.data, aes(input, output))
gg <- gg + geom_point()
gg <- gg + geom_smooth(method = "lm", se=F, color="red")
gg <- gg + theme_bw()
print(gg)
#In this case, since output is generated to be around 2 * input, the scatter plot would likely show a #positive linear relationship between input and output. The red line would be a straight line with a #positive slope, reflecting the output being approximately twice the input.
# Set seed and generate random data
set.seed(1)
input <- rnorm(200, mean=10)
output <- rnorm(200, mean=input*2)

# Put data into a data frame
our.data <- data.frame(input, output)

# Create the ggplot object
gg <- ggplot(our.data, aes(input, output))

# Add scatter plot points with customized appearance (larger and semi-transparent)
gg <- gg + geom_point(color="blue", alpha=0.6, size=2)

# Add a linear regression line in red
gg <- gg + geom_smooth(method="lm", se=F, color="red")

# Customize labels and title
gg <- gg + labs(
  title="Scatter Plot with Linear Regression Line",
  x="Input Values",
  y="Output Values (2 * Input)"
)

# Add a subtitle and caption for additional context
gg <- gg + labs(subtitle="A simple linear relationship: Output ~ 2 * Input", 
                 caption="Data generated from a normal distribution")

# Apply a black-and-white theme with minor adjustments to gridlines
gg <- gg + theme_bw() +
  theme(
    panel.grid.major = element_line(color="gray90", size=0.5),   # Light gray gridlines
    panel.grid.minor = element_line(color="gray95", size=0.25),  # Fainter gridlines
    text = element_text(size=12)   # Increase text size for readability
  )

# Display the plot
print(gg)
model <- lm(output ~ input)
summary(model)
#confint(model) calculates and returns the confidence intervals for each of the coefficients (parameters) of #the model.A confidence interval (CI) provides a range of values that, with a certain level of confidence #(usually 95%), is believed to contain the true value of the model parameter.
#For example, a 95% confidence interval means we are 95% confident that the true coefficient of a parameter #lies within the specified interval.
confint(model)
#Using the county.data dataset, let us run a model of Infections vs ufo2010(Aliens Visits according to the #UFO).

summary(lm(county.data$Infections ~ county.data$ufo2010, data= county.data))

Given the output printed above, is ufo2010 significant at a 5% significance level?1%?


Let us now run a model of Infections vs every single quantitative variable that is included in the dataset.
View(county.data)
summary(lm(Infections ~ pop + income + ipaddr + ufo2010, 
           data=county.data))
install.packages("carData")
library(car) # for the vif() function
#Let's examine the variance inflation factor (VIF) of the model to assess whether there is a risk of high #correlation between the predictors. Keep in mind that strong correlation between any two predictors could #lead to heteroskedasticity, which would compromise the accuracy of our model.

model <- lm(Infections ~ pop + income + ipaddr + ufo2010, 
            data=county.data)
sqrt(vif(model))

<!-- rnb-text-end -->


<!-- rnb-chunk-begin -->


<!-- rnb-output-begin eyJkYXRhIjoiXG48IS0tIHJuYi1zb3VyY2UtYmVnaW4gZXlKa1lYUmhJam9pWUdCZ2NseHVJMHhsZENkeklHbHVkbVZ6ZEdsbllYUmxJSGRvWlhSb1pYSWdjRzl3ZFd4aGRHbHZiaUJvWVhNZ1lXNGdhVzF3WVdOMElHOXVJSFJvWlNCdWRXMWlaWElnYjJZZ2FXNW1aV04wYVc5dWN5QnBiaUIwYUdseklHUmhkR0Z6WlhRdUlFWnZjbTExYkdGMFpTQjBhR1VnYm5Wc2JDQmhibVFnWVd4MFpYSnVZWFJwZG1VZ2FIbHdiM1JvWlhObGN5QjBieUIwWlhOMElIUm9hWE1nY21Wc1lYUnBiMjV6YUdsd0xseHVjM1Z0YldGeWVTaHNiU2hKYm1abFkzUnBiMjV6SUg0Z2NHOXdMQ0JrWVhSaFBXTnZkVzUwZVM1a1lYUmhLU2xjYm1CZ1lDSjkgLS0+XG5cbmBgYHJcbiNMZXQncyBpbnZlc3RpZ2F0ZSB3aGV0aGVyIHBvcHVsYXRpb24gaGFzIGFuIGltcGFjdCBvbiB0aGUgbnVtYmVyIG9mIGluZmVjdGlvbnMgaW4gdGhpcyBkYXRhc2V0LiBGb3JtdWxhdGUgdGhlIG51bGwgYW5kIGFsdGVybmF0aXZlIGh5cG90aGVzZXMgdG8gdGVzdCB0aGlzIHJlbGF0aW9uc2hpcC5cbnN1bW1hcnkobG0oSW5mZWN0aW9ucyB+IHBvcCwgZGF0YT1jb3VudHkuZGF0YSkpXG5gYGBcblxuPCEtLSBybmItc291cmNlLWVuZCAtLT5cbiJ9 -->


<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuI0xldCdzIGludmVzdGlnYXRlIHdoZXRoZXIgcG9wdWxhdGlvbiBoYXMgYW4gaW1wYWN0IG9uIHRoZSBudW1iZXIgb2YgaW5mZWN0aW9ucyBpbiB0aGlzIGRhdGFzZXQuIEZvcm11bGF0ZSB0aGUgbnVsbCBhbmQgYWx0ZXJuYXRpdmUgaHlwb3RoZXNlcyB0byB0ZXN0IHRoaXMgcmVsYXRpb25zaGlwLlxuc3VtbWFyeShsbShJbmZlY3Rpb25zIH4gcG9wLCBkYXRhPWNvdW50eS5kYXRhKSlcbmBgYCJ9 -->

```r
#Let's investigate whether population has an impact on the number of infections in this dataset. Formulate the null and alternative hypotheses to test this relationship.
summary(lm(Infections ~ pop, data=county.data))
#intepret above
#Population is statistically significant in predicting Infections, but the relationship is weak. The R-squared value is very low, meaning that population alone explains only a small portion of the variability in infections.
# model suggests a positive but very small effect of population on infections, with each unit increase in population leading to a very tiny increase in infections.
#Despite the statistical significance of the model, the low R-squared suggests that other factors not included in the model might be influencing the number of infections, and population alone may not be a strong enough predictor.
#Conclusion:
#While population appears to have a statistically significant relationship with the number of infections, the weak explanatory power (low R-squared) suggests that population is not the main factor driving infections in this dataset. Further investigation with additional variables may provide a better model.
pop.lm <- lm(Infections ~ pop, data=county.data)
predict(pop.lm, data.frame(pop=6000000), interval="confidence")
#The model predicts a number of infections between 295.92 and 461.50 with a certain level of confidence, which helps assess the uncertainty around the predicted value. The actual number of infections could fall anywhere within this range. Predicted Infections:
#For a population of 1,000,000, the predicted number of infections is 167.28.
#For a population of 2,000,000, the predicted number of infections is 209.56.
#Summary of Predictions:
#Based on Population:

#For population = 1,000,000, the predicted number of infections is 167.28.
##Based on Income:

####infections, though further analysis may be needed to refine the model and incorporate other important variables.
LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKIyB3ZSBmaXJzdCBuZWVkIHRvIGdldCB0aGUgd29ya2luZyBkaXJlY3RvcnkgCmBgYHtyfQpnZXR3ZCgpCmBgYAoKCmBgYHtyfQojbmV4dCwgd2UgbmVlZCB0byBpbnN0YWxsIHBhY2thZ2VzIAojZ2dwbG90IGlzIHVzZWQgZm9yIGhpZ2hseSBjdXN0b2l6YWJsZSBzaW1wbGUgdG8gY29tcGxleCB2aXN1YWxpemF0aW9ucyAsIG1hcHRvb2xzIGlzIHVzZWQgdGkgaW1wb3J0LCBleHBvcnQgYW5kIG1hbmlwdWxhdGUgc2hhcGVmbGllcy4gSXQgaGVsbHBzIHlvIHBlcmZvcm0gYmFzaWMgZ2Vvc3BhdGlhbCBhbmFseXNpcy4gCiNwa2cgPC0gYygiZ2dwbG90MiIsICJzY2FsZXMiLCAibWFwdG9vbHMiLAogICAgICAgICAgICAgICJzcCIsICJtYXBzIiwgImdyaWQiLCAiY2FyIiApCiMjaWYgKGxlbmd0aChuZXcucGtnKSkgewogIyBpbnN0YWxsLnBhY2thZ2VzKG5ldy5wa2cpICAKfQpgYGAKYGBge3J9CiMgcmVhZCB0aGUgQ1NWIHdpdGggaGVhZGVycwp6YSA8LSByZWFkLmNzdigiemVyb2FjY2Vzcy5jc3YiLCBoZWFkZXI9VCxzZXAgPSIsIiApCmBgYApgYGB7cn0KI0luIHRoaXMgbGluZSBvZiBjb2RlLCB3ZSBjYW4gdmlldyB0aGUgY3N2IGZpbGUgdGhhdCB3ZSBzYXZlZCBhcyB0aGUgdmFyaWFibGUgemEKVmlldyh6YSkKYGBgCmBgYHtyfQojd2UgdXNlIHRoZSBsaWJyYXJ5IGZ1bmN0aW9uIHRvIGxvYWQgZ2dwbG90IGFuZCBjcmVhdGUgZ3JhcGhpY3MKbGlicmFyeShnZ3Bsb3QyKQpgYGAKYGBge3J9CiMgY3JlYXRlIGEgZ2dwbG90IGluc3RhbmNlIHdpdGggemVyb2FjY2VzcyBkYXRhCmdnIDwtIGdncGxvdChkYXRhPXphLCBhZXMoeD1sb25nLCB5PWxhdCkpIAojIGFkZCB0aGUgcG9pbnRzLCBzZXQgdHJhbnNwYXJlbmN5IHRvIDEvNDB0aCAKZ2cgPC0gZ2cgKyBnZW9tX3BvaW50KHNpemU9MSwgY29sb3I9IiMwMDAwOTkiLCBhbHBoYT0xLzQwKSAKIyBhZGQgYXhlcyBsYWJlbHMKZ2cgPC0gZ2cgKyB4bGFiKCJMb25naXR1ZGUiKSArIHlsYWIoIkxhdGl0dWRlIikKIyBzaW1wbGlmeSB0aGUgdGhlbWUgZm9yIGFlc3RoZXRpY3MKZ2cgPC0gZ2cgKyB0aGVtZV9idygpIAojIHRoaXMgbWF5IHRha2UgYSB3aGlsZSwgb3ZlciA4MDAsMDAwIHBvaW50cyBwbG90dGVkCnByaW50KGdnKQpgYGAKYGBgCgpgYGB7cn0KI21hcHByb2ogaXMgYSBwYWNrYWdlIHRoYXQgaXMgZGVzaWduZWQgdG8gaGFuZGxlIG1hcCBwcm9qZWN0aW9ucyBhbmQgZ2VvZ3JhcGhpY2FsIGNvb3JkaW5hdGUgdHJhbnNmb3JtYXRpb25zLgojdGhlIHBhY2thZ2UgcHJvdmlkZXMgc2VydmVyYWwgdG9vbHMgdG8gd29yayB3aXRoIHZhcmlvdXMgdHlwZXMgb2YgbWFwcyBwcm9qZWN0aW9ucyB3aGljaCBhcmUgbWV0aG9kcyB1c2VkCiMgdG8gcmVwcmVzZW50IHRoZSBjdXJ2ZWQgc3VyZmFjZSBvZiBFYXJ0aCBvbiBhIGZsYXQgcGxhbmUgCmluc3RhbGwucGFja2FnZXMoIm1hcHByb2oiKQpgYGAKCmBgYHtyfQojIHJlcXVpcmVzIHBhY2thZ2UgOiBnZ3Bsb3QyCiMgcmVxdWlyZXMgb2JqZWN0OiB6YSAoNS0xKQojIHRoZSAibWFwcyIgYW5kICJtYXBwcm9qIiBwYWNrYWdlcyBhcmUgdXNlZCBieSBnZ3Bsb3QKIyBsb2FkIG1hcCBkYXRhIG9mIHRoZSB3b3JsZAp3b3JsZCA8LSBtYXBfZGF0YSgid29ybGQiKQojUmVtb3ZlIEFudGFyY3RpY2EKd29ybGQgPC0gc3Vic2V0KHdvcmxkLCB3b3JsZCRyZWdpb24hPSJBbnRhcmN0aWNhIikKIyBsb2FkIHdvcmxkIGRhdGEgaW50byBnZ3Bsb3Qgb2JqZWN0CmdnIDwtIGdncGxvdChkYXRhPXdvcmxkLCBhZXMoeD1sb25nLCB5PWxhdCkpCiMgdHJhY2UgYWxvbmcgdGhlIGxhdC9sb25nIGNvb3JkcyBieSBncm91cCAoY291bnRyaWVzKQpnZyA8LSBnZyArIGdlb21fcGF0aChhZXMoZ3JvdXA9Z3JvdXApLCBjb2xvdXI9ImdyYXk3MCIpCiMgbm93IHByb2plY3QgdXNpbmcgdGhlIG1lcmNhdG9yIHByb2plY3Rpb24KIyB0cnkgZGlmZmVyZW50IHByb2plY3Rpb25zIHdpdGggP21hcHByb2plY3QKZ2cgPC0gZ2cgKyBjb29yZF9tYXAoIm1lcmNhdG9yIiwgeGxpbT1jKC0yMDAsIDIwMCkpCiMgbG9hZCB1cCB0aGUgWmVyb0FjY2VzcyBwb2ludHMsIG92ZXJpZGluZyB0aGUgZGVmYXVsdCBkYXRhIHNldApnZyA8LSBnZyArIGdlb21fcG9pbnQoZGF0YT16YSwgYWVzKGxvbmcsIGxhdCksIAogICAgICAgICAgICAgICAgICAgICAgY29sb3VyPSIjMDAwMDk5IiwgYWxwaGE9MS80MCwgc2l6ZT0xKQojIHJlbW92ZSB0ZXh0LCBheGVzIHRpY2tzLCBncmlkIGxpbmVzIGFuZCBkbyBncmF5IGJvcmRlciBvbiB3aGl0ZQpnZyA8LSBnZyArIHRoZW1lKHRleHQ9ZWxlbWVudF9ibGFuaygpLCAKICAgICAgICAgICAgICAgICBheGlzLnRpY2tzPWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICAgICAgICAgICBwYW5lbC5ncmlkPWVsZW1lbnRfYmxhbmsoKSwKICAgICAgICAgICAgICAgICBwYW5lbC5iYWNrZ3JvdW5kPWVsZW1lbnRfcmVjdChjb2xvcj0iZ3JheTUwIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxsPSJ3aGl0ZSIpKQpwcmludChnZykKCmBgYAoKIyBJbnRlcnByZXQgdGhlIG91dHB1dAojVGhlIGZ1bmN0aW9uIG1hcF9kYXRhKCJ3b3JsZCIpIGxvYWRzIGEgcHJlLWJ1aWx0IGRhdGFzZXQgb2Ygd29ybGQgbWFwIGRhdGEsIHdoaWNoIGNvbnRhaW5zIGNvb3JkaW5hdGVzIGZvciAjdGhlIGNvdW50cmllcyBvZiB0aGUgd29ybGQuIFRoaXMgZGF0YSBpbmNsdWRlcyBsYXRpdHVkZSwgbG9uZ2l0dWRlLCBhbmQgY291bnRyeSBuYW1lcy4KI3dvcmxkIDwtIHN1YnNldCh3b3JsZCwgd29ybGQkcmVnaW9uIT0iQW50YXJjdGljYSIpVGhpcyBsaW5lIHJlbW92ZXMgQW50YXJjdGljYSBmcm9tIHRoZSB3b3JsZCBtYXAgZGF0YSBieSAjZmlsdGVyaW5nIG91dCBhbnkgcm93cyB3aGVyZSB0aGUgcmVnaW9uIGNvbHVtbiBlcXVhbHMgIkFudGFyY3RpY2EuIgojVGhlIGdncGxvdCgpIGZ1bmN0aW9uIGluaXRpYWxpemVzIGEgZ2dwbG90IG9iamVjdCB3aXRoIHRoZSB3b3JsZCBtYXAgZGF0YS4gSGVyZSwgaXQgbWFwcyB0aGUgbG9uZ2l0dWRlICMobG9uZykgYW5kIGxhdGl0dWRlIChsYXQpIGZyb20gdGhlIHdvcmxkIGRhdGFzZXQgdG8gdGhlIHggYW5kIHkgYXhlcyBvZiB0aGUgcGxvdAojVGhlIGdlb21fcGF0aCgpIGZ1bmN0aW9uIGlzIHVzZWQgdG8gZHJhdyB0aGUgYm9yZGVycyBvZiBjb3VudHJpZXMgYnkgY29ubmVjdGluZyB0aGUgbGF0aXR1ZGUgYW5kIGxvbmdpdHVkZSAjY29vcmRpbmF0ZXMgaW4gZWFjaCBjb3VudHJ5IChkZWZpbmVkIGJ5IGdyb3VwKS4gVGhlIGNvbG9yIG9mIHRoZSBsaW5lcyBpcyBzZXQgdG8gZ3JheTcwIChhIGxpZ2h0IGdyYXkgI2NvbG9yKS5jb29yZF9tYXAoIm1lcmNhdG9yIikgYXBwbGllcyB0aGUgTWVyY2F0b3IgcHJvamVjdGlvbiB0byB0aGUgd29ybGQgbWFwLiBUaGUgeGxpbT1jKC0yMDAsIDIwMCkgI2FyZ3VtZW50IHNldHMgdGhlIGxvbmdpdHVkZSBsaW1pdHMgZm9yIHRoZSB4LWF4aXMsIGVzc2VudGlhbGx5IGZvY3VzaW5nIHRoZSBtYXAgb24gdGhlIHR5cGljYWwgd29ybGQgdmlldy4KI2dlb21fcG9pbnQoKSBhZGRzIHBvaW50cyB0byB0aGUgbWFwIGJhc2VkIG9uIHRoZSBkYXRhIGluIHRoZSB6YSBkYXRhc2V0IChsaWtlbHkgYSBkYXRhc2V0IHdpdGggbGF0aXR1ZGVzIGFuZCAjbG9uZ2l0dWRlcyBmb3IgY2VydGFpbiBsb2NhdGlvbnMsIHN1Y2ggYXMgWmVyb0FjY2VzcyBwb2ludHMpLgojI3NpemUgKHNpemU9MSkuIHRoZW1lKCkgaXMgdXNlZCB0byBjdXN0b21pemUgdGhlIGFwcGVhcmFuY2Ugb2YgdGhlIG1hcDoKIyNheGlzLnRpY2tzPWVsZW1lbnRfYmxhbmsoKSByZW1vdmVzIGF4aXMgdGlja3MuCiMjI2JvcmRlciBhcm91bmQgdGhlIHBsb3QuCiNwcmludChnZykgb3V0cHV0cyB0aGUgZmluYWwgbWFwIHRvIHRoZSBSIGNvbnNvbGUgb3IgcGxvdHRpbmcgd2luZG93LgoKYGBge3J9CiMgcmVhZCB1cCBjZW5zdXMgZGF0YSBwZXIgY291bnR5CmNvdW50eS5kYXRhIDwtIHJlYWQuY3N2KCJjb3VudHlkYXRhc2V0LmNzdiIsIGhlYWRlcj1ULHNlcCA9ICIsIikKCmBgYAoKYGBge3J9ClZpZXcoY291bnR5LmRhdGEpCmBgYApgYGB7cn0Kc2V0LnNlZWQoMSkKIyBnZW5lcmF0ZSAyMDAgcmFuZG9tIG51bWJlcnMgYXJvdW5kIDEwCmlucHV0IDwtIHJub3JtKDIwMCwgbWVhbj0xMCkKc3VtbWFyeShpbnB1dCkKYGBgCmBgYHtyfQoKI2ludGVycHJldCB0aGUgc3ludGF4IGFib3ZlIAojc2V0LnNlZWQoMSkgc2V0cyB0aGUgcmFuZG9tIG51bWJlciBnZW5lcmF0b3IncyBzZWVkIHRvIDEuIFRoaXMgZW5zdXJlcyB0aGF0IGFueSByYW5kb20gcHJvY2Vzc2VzLCBsaWtlICNnZW5lcmF0aW5nIHJhbmRvbSBudW1iZXJzLCB3aWxsIHByb2R1Y2UgdGhlIHNhbWUgcmVzdWx0IGV2ZXJ5IHRpbWUgdGhlIGNvZGUgaXMgcnVuLiBJdCdzIHVzZWZ1bCBmb3IgI3JlcHJvZHVjaWJpbGl0eSwgc28geW91IG9yIG90aGVycyBjYW4gZ2V0IHRoZSBleGFjdCBzYW1lIG91dHB1dCB3aGVuIHJ1bm5pbmcgdGhlIGNvZGUuCiNybm9ybSgyMDAsIG1lYW49MTApIGdlbmVyYXRlcyAyMDAgcmFuZG9tIG51bWJlcnMgZnJvbSBhIG5vcm1hbCBkaXN0cmlidXRpb24gKGEgYmVsbCBjdXJ2ZSkgd2l0aDoKI0EgbWVhbiBvZiAxMCwgbWVhbmluZyB0aGUgbnVtYmVycyB3aWxsIGJlIGNlbnRlcmVkIGFyb3VuZCAxMC4KI0Egc3RhbmRhcmQgZGV2aWF0aW9uIG9mIDEgKHRoZSBkZWZhdWx0IHZhbHVlKS4gVGhpcyBtZWFucyBtb3N0IG9mIHRoZSBudW1iZXJzIHdpbGwgZmFsbCBiZXR3ZWVuIDggYW5kIDEyLCAjYnV0IHRoZXJlIHdpbGwgYWxzbyBiZSBzb21lIHRoYXQgYXJlIG91dHNpZGUgb2YgdGhhdCByYW5nZS4KI1RoZSByZXN1bHRpbmcgMjAwIG51bWJlcnMgYXJlIHN0b3JlZCBpbiB0aGUgdmFyaWFibGUgaW5wdXQuCiNzdW1tYXJ5KGlucHV0KSBwcm92aWRlcyBhIHN1bW1hcnkgc3RhdGlzdGljcyBvZiB0aGUgZ2VuZXJhdGVkIGRhdGEgaW4gaW5wdXQsIGluY2x1ZGluZzoKI01pbjogVGhlIG1pbmltdW0gdmFsdWUgaW4gdGhlIGRhdGFzZXQuCiMxc3QgUXUuIChRdWFydGlsZSk6IFRoZSBmaXJzdCBxdWFydGlsZSAoMjV0aCBwZXJjZW50aWxlKSB2YWx1ZS4KI01lZGlhbjogVGhlIG1lZGlhbiAoNTB0aCBwZXJjZW50aWxlKSB2YWx1ZSwgd2hpY2ggcmVwcmVzZW50cyB0aGUgbWlkZGxlIG9mIHRoZSBkYXRhLgojTWVhbjogVGhlIGF2ZXJhZ2Ugb2YgdGhlIGRhdGFzZXQuCiMzcmQgUXUuIChRdWFydGlsZSk6IFRoZSB0aGlyZCBxdWFydGlsZSAoNzV0aCBwZXJjZW50aWxlKSB2YWx1ZS4KI01heDogVGhlIG1heGltdW0gdmFsdWUgaW4gdGhlIGRhdGFzZXQuCgoKCmBgYAoKYGBge3J9CiMgcmVxdWlyZXMgb2JqZWN0czogaW5wdXQgKDUtMTYpCiMgZ2VuZXJhdGUgb3V0cHV0IGFyb3VuZCBhIG1lYW4gb2YgMiB4IGlucHV0Cm91dHB1dCA8LSBybm9ybSgyMDAsIG1lYW49aW5wdXQqMikKIyBwdXQgaW50byBkYXRhIGZyYW1lIHRvIHBsb3QgaXQKb3VyLmRhdGEgPC0gZGF0YS5mcmFtZShpbnB1dCwgb3V0cHV0KQpnZyA8LSBnZ3Bsb3Qob3VyLmRhdGEsIGFlcyhpbnB1dCwgb3V0cHV0KSkKZ2cgPC0gZ2cgKyBnZW9tX3BvaW50KCkKZ2cgPC0gZ2cgKyBnZW9tX3Ntb290aChtZXRob2QgPSAibG0iLCBzZT1GLCBjb2xvcj0icmVkIikKZ2cgPC0gZ2cgKyB0aGVtZV9idygpCnByaW50KGdnKQpgYGAKYGBge3J9CiNJbiB0aGlzIGNhc2UsIHNpbmNlIG91dHB1dCBpcyBnZW5lcmF0ZWQgdG8gYmUgYXJvdW5kIDIgKiBpbnB1dCwgdGhlIHNjYXR0ZXIgcGxvdCB3b3VsZCBsaWtlbHkgc2hvdyBhICNwb3NpdGl2ZSBsaW5lYXIgcmVsYXRpb25zaGlwIGJldHdlZW4gaW5wdXQgYW5kIG91dHB1dC4gVGhlIHJlZCBsaW5lIHdvdWxkIGJlIGEgc3RyYWlnaHQgbGluZSB3aXRoIGEgI3Bvc2l0aXZlIHNsb3BlLCByZWZsZWN0aW5nIHRoZSBvdXRwdXQgYmVpbmcgYXBwcm94aW1hdGVseSB0d2ljZSB0aGUgaW5wdXQuCgpgYGAKCgoKCmBgYHtyfQojIFNldCBzZWVkIGFuZCBnZW5lcmF0ZSByYW5kb20gZGF0YQpzZXQuc2VlZCgxKQppbnB1dCA8LSBybm9ybSgyMDAsIG1lYW49MTApCm91dHB1dCA8LSBybm9ybSgyMDAsIG1lYW49aW5wdXQqMikKCiMgUHV0IGRhdGEgaW50byBhIGRhdGEgZnJhbWUKb3VyLmRhdGEgPC0gZGF0YS5mcmFtZShpbnB1dCwgb3V0cHV0KQoKIyBDcmVhdGUgdGhlIGdncGxvdCBvYmplY3QKZ2cgPC0gZ2dwbG90KG91ci5kYXRhLCBhZXMoaW5wdXQsIG91dHB1dCkpCgojIEFkZCBzY2F0dGVyIHBsb3QgcG9pbnRzIHdpdGggY3VzdG9taXplZCBhcHBlYXJhbmNlIChsYXJnZXIgYW5kIHNlbWktdHJhbnNwYXJlbnQpCmdnIDwtIGdnICsgZ2VvbV9wb2ludChjb2xvcj0iYmx1ZSIsIGFscGhhPTAuNiwgc2l6ZT0yKQoKIyBBZGQgYSBsaW5lYXIgcmVncmVzc2lvbiBsaW5lIGluIHJlZApnZyA8LSBnZyArIGdlb21fc21vb3RoKG1ldGhvZD0ibG0iLCBzZT1GLCBjb2xvcj0icmVkIikKCiMgQ3VzdG9taXplIGxhYmVscyBhbmQgdGl0bGUKZ2cgPC0gZ2cgKyBsYWJzKAogIHRpdGxlPSJTY2F0dGVyIFBsb3Qgd2l0aCBMaW5lYXIgUmVncmVzc2lvbiBMaW5lIiwKICB4PSJJbnB1dCBWYWx1ZXMiLAogIHk9Ik91dHB1dCBWYWx1ZXMgKDIgKiBJbnB1dCkiCikKCiMgQWRkIGEgc3VidGl0bGUgYW5kIGNhcHRpb24gZm9yIGFkZGl0aW9uYWwgY29udGV4dApnZyA8LSBnZyArIGxhYnMoc3VidGl0bGU9IkEgc2ltcGxlIGxpbmVhciByZWxhdGlvbnNoaXA6IE91dHB1dCB+IDIgKiBJbnB1dCIsIAogICAgICAgICAgICAgICAgIGNhcHRpb249IkRhdGEgZ2VuZXJhdGVkIGZyb20gYSBub3JtYWwgZGlzdHJpYnV0aW9uIikKCiMgQXBwbHkgYSBibGFjay1hbmQtd2hpdGUgdGhlbWUgd2l0aCBtaW5vciBhZGp1c3RtZW50cyB0byBncmlkbGluZXMKZ2cgPC0gZ2cgKyB0aGVtZV9idygpICsKICB0aGVtZSgKICAgIHBhbmVsLmdyaWQubWFqb3IgPSBlbGVtZW50X2xpbmUoY29sb3I9ImdyYXk5MCIsIHNpemU9MC41KSwgICAjIExpZ2h0IGdyYXkgZ3JpZGxpbmVzCiAgICBwYW5lbC5ncmlkLm1pbm9yID0gZWxlbWVudF9saW5lKGNvbG9yPSJncmF5OTUiLCBzaXplPTAuMjUpLCAgIyBGYWludGVyIGdyaWRsaW5lcwogICAgdGV4dCA9IGVsZW1lbnRfdGV4dChzaXplPTEyKSAgICMgSW5jcmVhc2UgdGV4dCBzaXplIGZvciByZWFkYWJpbGl0eQogICkKCiMgRGlzcGxheSB0aGUgcGxvdApwcmludChnZykKCgpgYGAKCmBgYHtyfQptb2RlbCA8LSBsbShvdXRwdXQgfiBpbnB1dCkKc3VtbWFyeShtb2RlbCkKCmBgYApgYGB7cn0KI2NvbmZpbnQobW9kZWwpIGNhbGN1bGF0ZXMgYW5kIHJldHVybnMgdGhlIGNvbmZpZGVuY2UgaW50ZXJ2YWxzIGZvciBlYWNoIG9mIHRoZSBjb2VmZmljaWVudHMgKHBhcmFtZXRlcnMpIG9mICN0aGUgbW9kZWwuQSBjb25maWRlbmNlIGludGVydmFsIChDSSkgcHJvdmlkZXMgYSByYW5nZSBvZiB2YWx1ZXMgdGhhdCwgd2l0aCBhIGNlcnRhaW4gbGV2ZWwgb2YgY29uZmlkZW5jZSAjKHVzdWFsbHkgOTUlKSwgaXMgYmVsaWV2ZWQgdG8gY29udGFpbiB0aGUgdHJ1ZSB2YWx1ZSBvZiB0aGUgbW9kZWwgcGFyYW1ldGVyLgojRm9yIGV4YW1wbGUsIGEgOTUlIGNvbmZpZGVuY2UgaW50ZXJ2YWwgbWVhbnMgd2UgYXJlIDk1JSBjb25maWRlbnQgdGhhdCB0aGUgdHJ1ZSBjb2VmZmljaWVudCBvZiBhIHBhcmFtZXRlciAjbGllcyB3aXRoaW4gdGhlIHNwZWNpZmllZCBpbnRlcnZhbC4KY29uZmludChtb2RlbCkKYGBgCgoKCgpgYGB7cn0KI1VzaW5nIHRoZSBjb3VudHkuZGF0YSBkYXRhc2V0LCBsZXQgdXMgcnVuIGEgbW9kZWwgb2YgSW5mZWN0aW9ucyB2cyB1Zm8yMDEwKEFsaWVucyBWaXNpdHMgYWNjb3JkaW5nIHRvIHRoZSAjVUZPKS4KCnN1bW1hcnkobG0oY291bnR5LmRhdGEkSW5mZWN0aW9ucyB+IGNvdW50eS5kYXRhJHVmbzIwMTAsIGRhdGE9IGNvdW50eS5kYXRhKSkKCmBgYApgYGB7cn0KCkdpdmVuIHRoZSBvdXRwdXQgcHJpbnRlZCBhYm92ZSwgaXMgdWZvMjAxMCBzaWduaWZpY2FudCBhdCBhIDUlIHNpZ25pZmljYW5jZSBsZXZlbD8xJT8KCgpMZXQgdXMgbm93IHJ1biBhIG1vZGVsIG9mIEluZmVjdGlvbnMgdnMgZXZlcnkgc2luZ2xlIHF1YW50aXRhdGl2ZSB2YXJpYWJsZSB0aGF0IGlzIGluY2x1ZGVkIGluIHRoZSBkYXRhc2V0LgpgYGAKCmBgYHtyfQpWaWV3KGNvdW50eS5kYXRhKQoKYGBgCgoKYGBge3J9CnN1bW1hcnkobG0oSW5mZWN0aW9ucyB+IHBvcCArIGluY29tZSArIGlwYWRkciArIHVmbzIwMTAsIAogICAgICAgICAgIGRhdGE9Y291bnR5LmRhdGEpKQpgYGAKYGBge3J9Cmluc3RhbGwucGFja2FnZXMoImNhckRhdGEiKQpgYGAKCmBgYHtyfQpsaWJyYXJ5KGNhcikgIyBmb3IgdGhlIHZpZigpIGZ1bmN0aW9uCgpgYGAKCmBgYHtyfQojTGV0J3MgZXhhbWluZSB0aGUgdmFyaWFuY2UgaW5mbGF0aW9uIGZhY3RvciAoVklGKSBvZiB0aGUgbW9kZWwgdG8gYXNzZXNzIHdoZXRoZXIgdGhlcmUgaXMgYSByaXNrIG9mIGhpZ2ggI2NvcnJlbGF0aW9uIGJldHdlZW4gdGhlIHByZWRpY3RvcnMuIEtlZXAgaW4gbWluZCB0aGF0IHN0cm9uZyBjb3JyZWxhdGlvbiBiZXR3ZWVuIGFueSB0d28gcHJlZGljdG9ycyBjb3VsZCAjbGVhZCB0byBoZXRlcm9za2VkYXN0aWNpdHksIHdoaWNoIHdvdWxkIGNvbXByb21pc2UgdGhlIGFjY3VyYWN5IG9mIG91ciBtb2RlbC4KCm1vZGVsIDwtIGxtKEluZmVjdGlvbnMgfiBwb3AgKyBpbmNvbWUgKyBpcGFkZHIgKyB1Zm8yMDEwLCAKICAgICAgICAgICAgZGF0YT1jb3VudHkuZGF0YSkKc3FydCh2aWYobW9kZWwpKQpgYGAKYGBgCmBgYHtyfQojTGV0J3MgaW52ZXN0aWdhdGUgd2hldGhlciBwb3B1bGF0aW9uIGhhcyBhbiBpbXBhY3Qgb24gdGhlIG51bWJlciBvZiBpbmZlY3Rpb25zIGluIHRoaXMgZGF0YXNldC4gRm9ybXVsYXRlIHRoZSBudWxsIGFuZCBhbHRlcm5hdGl2ZSBoeXBvdGhlc2VzIHRvIHRlc3QgdGhpcyByZWxhdGlvbnNoaXAuCnN1bW1hcnkobG0oSW5mZWN0aW9ucyB+IHBvcCwgZGF0YT1jb3VudHkuZGF0YSkpCmBgYApgYGB7cn0KI2ludGVwcmV0IGFib3ZlCiNQb3B1bGF0aW9uIGlzIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQgaW4gcHJlZGljdGluZyBJbmZlY3Rpb25zLCBidXQgdGhlIHJlbGF0aW9uc2hpcCBpcyB3ZWFrLiBUaGUgUi1zcXVhcmVkIHZhbHVlIGlzIHZlcnkgbG93LCBtZWFuaW5nIHRoYXQgcG9wdWxhdGlvbiBhbG9uZSBleHBsYWlucyBvbmx5IGEgc21hbGwgcG9ydGlvbiBvZiB0aGUgdmFyaWFiaWxpdHkgaW4gaW5mZWN0aW9ucy4KIyBtb2RlbCBzdWdnZXN0cyBhIHBvc2l0aXZlIGJ1dCB2ZXJ5IHNtYWxsIGVmZmVjdCBvZiBwb3B1bGF0aW9uIG9uIGluZmVjdGlvbnMsIHdpdGggZWFjaCB1bml0IGluY3JlYXNlIGluIHBvcHVsYXRpb24gbGVhZGluZyB0byBhIHZlcnkgdGlueSBpbmNyZWFzZSBpbiBpbmZlY3Rpb25zLgojRGVzcGl0ZSB0aGUgc3RhdGlzdGljYWwgc2lnbmlmaWNhbmNlIG9mIHRoZSBtb2RlbCwgdGhlIGxvdyBSLXNxdWFyZWQgc3VnZ2VzdHMgdGhhdCBvdGhlciBmYWN0b3JzIG5vdCBpbmNsdWRlZCBpbiB0aGUgbW9kZWwgbWlnaHQgYmUgaW5mbHVlbmNpbmcgdGhlIG51bWJlciBvZiBpbmZlY3Rpb25zLCBhbmQgcG9wdWxhdGlvbiBhbG9uZSBtYXkgbm90IGJlIGEgc3Ryb25nIGVub3VnaCBwcmVkaWN0b3IuCiNDb25jbHVzaW9uOgojV2hpbGUgcG9wdWxhdGlvbiBhcHBlYXJzIHRvIGhhdmUgYSBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50IHJlbGF0aW9uc2hpcCB3aXRoIHRoZSBudW1iZXIgb2YgaW5mZWN0aW9ucywgdGhlIHdlYWsgZXhwbGFuYXRvcnkgcG93ZXIgKGxvdyBSLXNxdWFyZWQpIHN1Z2dlc3RzIHRoYXQgcG9wdWxhdGlvbiBpcyBub3QgdGhlIG1haW4gZmFjdG9yIGRyaXZpbmcgaW5mZWN0aW9ucyBpbiB0aGlzIGRhdGFzZXQuIEZ1cnRoZXIgaW52ZXN0aWdhdGlvbiB3aXRoIGFkZGl0aW9uYWwgdmFyaWFibGVzIG1heSBwcm92aWRlIGEgYmV0dGVyIG1vZGVsLgoKCgoKYGBgCmBgYHtyfQpwb3AubG0gPC0gbG0oSW5mZWN0aW9ucyB+IHBvcCwgZGF0YT1jb3VudHkuZGF0YSkKcHJlZGljdChwb3AubG0sIGRhdGEuZnJhbWUocG9wPTYwMDAwMDApLCBpbnRlcnZhbD0iY29uZmlkZW5jZSIpCmBgYAoKYGBge3J9CiNUaGUgbW9kZWwgcHJlZGljdHMgYSBudW1iZXIgb2YgaW5mZWN0aW9ucyBiZXR3ZWVuIDI5NS45MiBhbmQgNDYxLjUwIHdpdGggYSBjZXJ0YWluIGxldmVsIG9mIGNvbmZpZGVuY2UsIHdoaWNoIGhlbHBzIGFzc2VzcyB0aGUgdW5jZXJ0YWludHkgYXJvdW5kIHRoZSBwcmVkaWN0ZWQgdmFsdWUuIFRoZSBhY3R1YWwgbnVtYmVyIG9mIGluZmVjdGlvbnMgY291bGQgZmFsbCBhbnl3aGVyZSB3aXRoaW4gdGhpcyByYW5nZS4gUHJlZGljdGVkIEluZmVjdGlvbnM6CiNGb3IgYSBwb3B1bGF0aW9uIG9mIDEsMDAwLDAwMCwgdGhlIHByZWRpY3RlZCBudW1iZXIgb2YgaW5mZWN0aW9ucyBpcyAxNjcuMjguCiNGb3IgYSBwb3B1bGF0aW9uIG9mIDIsMDAwLDAwMCwgdGhlIHByZWRpY3RlZCBudW1iZXIgb2YgaW5mZWN0aW9ucyBpcyAyMDkuNTYuCiNTdW1tYXJ5IG9mIFByZWRpY3Rpb25zOgojQmFzZWQgb24gUG9wdWxhdGlvbjoKCiNGb3IgcG9wdWxhdGlvbiA9IDEsMDAwLDAwMCwgdGhlIHByZWRpY3RlZCBudW1iZXIgb2YgaW5mZWN0aW9ucyBpcyAxNjcuMjguCiMjQmFzZWQgb24gSW5jb21lOgoKIyMjI2luZmVjdGlvbnMsIHRob3VnaCBmdXJ0aGVyIGFuYWx5c2lzIG1heSBiZSBuZWVkZWQgdG8gcmVmaW5lIHRoZSBtb2RlbCBhbmQgaW5jb3Jwb3JhdGUgb3RoZXIgaW1wb3J0YW50IHZhcmlhYmxlcy4KYGBgCgo=