Nathan Stewart 811847789

fitness1=c(1,1,0.9)
fitness2=c(1,1,0.5)
fitness3=c(1,1,0.1)
gen.time=1000
start.freq=0.5

results1 <- selection(time = gen.time, p0=start.freq, w=fitness1)
results2 <- selection(time = gen.time, p0=start.freq, w=fitness2, add=TRUE, color="red")
results3 <- selection(time = gen.time, p0=start.freq, w=fitness3, add=TRUE, color="blue")

This is problem 1. Black is weakest selection, blue is the strongest. It just impacts the speed at which A becomes fixed.Impacts the speed of evolution. always AA, Aa, aa

1. Initiate the Project

#This command loads required packages
#Note that you may need to install the learnPopGen package first!
library(learnPopGen)

Important tip: In this and the next exercise, we will focus entirely on running different evolutionary models. The plots for these models are generated automatically, and you do not need to use ggplot to produce the outputs.

2. Before You Get Started…

In the introduction video, I asked you to pause and predict what happens to the allele frequency of an allele A that provides a fitness advantage to its carriers. What is your prediction?

I would predict that an allele that provides a fitness advantage would eventually become completely dominant.

3. Modeling Allele Frequencies Across Generations: Introducing Key Parameters

Applying the HW principle is a powerful approach to test whether any evolutionary forces are impacting a population at any given locus. It does not tell us, however, what evolutionary force might be acting on that locus. In the following sections, we get to know different evolutionary forces and discover how they impact allele frequencies across generations.

First let’s consider how natural selection affects allele frequencies. Natural selection essentially manifests itself in different genotypes having a different fitness. Mathematically, we asign a fitness of 1 to one genotype (AA), and the fitness of other genotypes can than be defined relative to AA with a the parameter s (the strength of selection). For example, if the genotype aa has a 10% higher fitness than AA (s=0.1), its fitness would be 1+s = 1.1. If genotype Aa has a 15% lower fitness than AA (s=-0.15), its fitness would be 1+s = 0.85.

It takes just a few key parameters for us to model how selection affects allele frequency over time: (1) The strength of selection, s. (2) The mode of inheritance (dominant/recessive vs. additive). If an allele at a particular locus is dominant over another, s for the heterozygote is the same as for the dominant homozygote. Inheritance, however, may not be dominant/recessive, in which case you need two values of s to describe how selection might impact evolution.

4. Modeling the Effect of Selection on Allele Frequencies using the Selection Command

We can model the genotype frequencies in response to selection with the selection function. All we need to do is to tell the function the fitness (w) of the three genotypes (AA, Aa, aa). If the mode of inheritance is dominant/recessive, fitness is defined as:

fitness <- c(1, 1, 1+s)

If the mode of inheritance is not dominant/recessive, fitness is defined as:

fitness <- c(1, 1+s1, 1+s2)

Other parameters that are required is p0 (the starting allele frequency of p) and time (the number of generations you want to run the simulation for). We define these as:

start.freq <- number (between 0 and 1)

gen.time <- number (between 1 and infinity; be cautious with high numbers, as they use significant computation time)

Setting these parameters, we can model the effects of selection with the “selection” command as follows:

result <-selection(w=fitness, time=gen.time, p0=start.freq)

Let’s put this to the test. Let’s model the effect of selection on a gene with a dominant/recessive mode of inheritance, with the recessive allele being deleterious (i.e., its fitness is zero). Set the starting allele frequency at 0.5 and run the simulation for 50 generations.

#Define the fitness of each genotype
fitness <- c(1, 1, 0)

#Define the starting allele frequency p0
start.freq <- 0.5

#Define how many generations you want to simulate
gen.time <- 50

#Model the allele changes and store the results in an object called r
r <- selection(w=fitness, time=gen.time, p0=start.freq)

Note that running the selection command automatically plots the results of the model. You can also directly look at the numbers as a table using the following code.

#You can also look at the actual number if you want to
r.table <- data.frame(1:gen.time, r$p)
names(r.table) <- c("Generation", "p")

#Show last part of the table in the results
tail(r.table)

I hope what you can observe is that the frequency of A (p) increases over time. The speed of change slows as A gets more common, and it eventually flattens.

4.1. Varying the Strength of Selection

In the coming set of simulations, let’s explore how varying the strength of selection impacts how allele frequencies change across generations. We focus on a single gene with complete dominance of the A allele. In these first scenarios the dominant phenotype has a selective advantage over the recessive one, but the A allele is starting at a very low frequency in the population (p0=0.0001). In the first example, the strength of selection against the recessive homozygotes is s=-0.1. Run the simulation and record what happens to the allele frequencies of A and a over 1000 generations. What do you observe? Explain the pattern.

#Define the fitness of each genotype
fitness1 <- c(1, 1, (-0.1))

#Define the starting allele frequency p0
start.freq1 <- 0.0001 

#Define how many generations you want to simulate
gen.time1 <- 1000

#Model the allele changes and store the results in an object r1; note that the parameter t just signifies how many generations will be simulated
r1 <- selection(w=fitness1, time=gen.time1, p0=start.freq1)

i observed that the frequency of A appears to shoot up very quickly, and level out what appears to be within 300 generations. There is a sharp increase until about 100 generations. This means that the “a” allele is selected at a rate of -.1 and already started at a very low frequency, this menas that “A” allele is selected at a higher rate.

To truly understand how the strength of selection impacts allele frequencies, we need to run multiple models assuming different fitnesses for our genotypes. Using the same parameters as above, run multiple models with the selection coefficient varying between -1 and 0. Rather than running each model separately, you can actually run them in bulk, and the following code snippet teaches you how.

#Define the fitness of each genotype. Unlike above, you want to vary the strength of selection, so we will define multiple fitness sets (one for each model you want to run)
fitness1 <- c(1,1,1)
fitness2 <- c(1,1,0.7)
fitness3 <- c(1,1,0.5)
fitness4 <- c(1,1,0.3)
fitness5 <- c(1,1,0)

#Define the starting allele frequency p0. This parameter will will be the same for all models, so you only need to define it once.
start.freq1 <- 0.0001

#Define how many generations you want to simulate. This parameter will will be the same for all models, so you only need to define it once.
gen.time1 <- 1000

#Model the allele changes for the different strengths of selection. You need to run one model for each fitness distribution you defined above. Note that you can plot all results in a single graph by adding "add=TRUE" starting at the second model. 
r1 <- selection(w=fitness1, time=gen.time1, p0=start.freq1)
r2 <- selection(w=fitness2, time=gen.time1, p0=start.freq1, add=TRUE, color = 'red')
r3 <- selection(w=fitness3, time=gen.time1, p0=start.freq1, add=TRUE, color = 'blue')
r4 <- selection(w=fitness4, time=gen.time1, p0=start.freq1, add=TRUE, color = 'green')
r5 <- selection(w=fitness5, time=gen.time1, p0=start.freq1, add=TRUE, color = 'purple')

Looking at the results of your models, how does varying the strength of selection affect changes in allele frequencies across generations?

With decreasing strength of selection, the time it takes to arrive at 1. For example, when there is a decreased strength of selection, it takes less time to arrive at higher frequencies of AA.

4.2. Selection on Dominant vs. Recessive phenotypes

Let’s examine what happens when the phenotype with higher fitness is dominant vs. recessive. First, set the starting frequency of the A allele to p0=0.01, and give the dominant phenotype a fitness advantage over the recessive phenotype (s against the recessive homozygotes is -0.2). Run the simulation for 1000 generations.

#Define the fitness of each genotype
fitness1 <- c(1,1,0.8)

#Define the starting allele frequency p0
start.freq1 <-0.01

#Define how many generations you want to simulate
gen.time1 <- 1000

#Model the allele changes and store the results in an object r1; note that the parameter t just signifies how many generations will be simulated
r1 <- selection(w=fitness1, time=gen.time1, p0=start.freq1)


#In this case, it may be useful to look at the actual numbers for p at the end of your simulation
r1.table <- data.frame(1:gen.time1, r1$p)
names(r1.table) <- c("Generation", "p")
tail(r1.table)

Now let’s examine the opposite scenario. Set the starting allele frequency p0=0.99 but this time give the recessive phenotype the fitness advantage over the dominant phenotype (same s as above). Run the simulation for 1000 generations.

#Define the fitness of each genotype
fitness2 <-c(0.8,1,1)

#Define the starting allele frequency p0
start.freq2 <- 0.99

#Define how many generations you want to simulate
gen.time2 <- 1000

#Model the allele changes and store the results in an object r1; note that the parameter t just signifies how many generations will be simulated
r2 <- selection(w=fitness2, time=gen.time2, p0=start.freq2)


#In this case, it may be useful to look at the actual numbers for p at the end of your simulation
r2.table <- data.frame(1:gen.time2, r2$p)
names(r2.table) <- c("Generation", "p")
tail(r2.table)

Compare and contrast the results of the two simulations? What do you notice about the pace of change and the final allele frequencies? Why does the recessive allele persist in a population when selected against, but the dominant allele does not?

The results look similar at first, except towards opposite alleles, but if you look at smaller periods of time, the recessive allele is present for longer. This is likely due to the different starting frequencies.

4.3. Selection For Heterozygotes; Symmetrical Fitness between Homozygotes

So far we have only considered scenarios where fitness was distributed in a dominant/recessive way. Now we are going to investigate the consequences of selection for heterozygous individuals (they have a fitness advantage over homozygous individuals). Give the heterozygous genotypes a 1% fitness advantage over both of the homozygous genotypes. Run multiple simulations for 1000 generations and vary the starting allele frequency for values between 0 and 1.

#Define the parameters and set up the models
fitness1=c(1,1.01,1)
fitness2=c(1,1.01,1)
fitness3=c(1,1.01,1)
gen.time=1000
start.freq1=0.9
start.freq2=0.5
start.freq3=0.1
results1 <- selection(time = gen.time, p0=start.freq1, w=fitness1)
results2 <- selection(time = gen.time, p0=start.freq2, w=fitness2, add=TRUE, color="red")
results3 <- selection(time = gen.time, p0=start.freq3, w=fitness3, add=TRUE, color="blue")

What happens to the allele frequencies in the population? Can you explain why?

Since there is a fitness advantage for heterozygosity, the populations will trend towards whatever allele type has the higher fitness. In this case, it was the heterozygous individuals. The starting frequency determines the how dramatically the alleles will change. The graph shows that when the starting AA aleles are high, there will be a drop towards Aa, and when a higher frequency of aa (lower frequency of AA) there will be a rise in frequency of A until it reaches mostly Aa.

4.4. Selection For Heterozygotes; Asymmetrical Fitness between Homozygotes

What happens when heterozygous individuals have a fitness advantage, but selection is stronger against one of the homozygous genotypes? Set the starting allele frequency to p0=0.1, and give the aa genotype a fitness of 0.0. Run the simulation with various fitness coefficients for the AA genotype (between 0 and 1), while keeping the fitness of the heterozygotes at 1.

#Define the parameters and set up the models
fitness1=c(0.9,1,0.0)
fitness2=c(0.5,1,0.0)
fitness3=c(0.1,1,0.0)
gen.time=100
start.freq=0.1

results1 <- selection(time = gen.time, p0=start.freq, w=fitness1)
results2 <- selection(time = gen.time, p0=start.freq, w=fitness2, add=TRUE, color="red")
results3 <- selection(time = gen.time, p0=start.freq, w=fitness3, add=TRUE, color="blue")

How does changing the fitness of AA individuals influence the final allele frequencies in the population over time? Will the deleterious allele ever be lost from the population? What are the lowest and highest frequencies the a allele can reach? Why?

The fitness of AA individuals affects the end concentration of AA in the population. When there is a low fitness, the amount of AA individuals was much lower than a high fitness for AA individuals. The aa will not be removed from the population, because there will always be some surviving Aa individuals. The highest amount would be around 90% removed, while the lowest would be 50% removal due to the heterozygous individuals.

4.5. Selection Against Heterozygotes; Symmetrical Fitness between Homozygotes

Selection may also act against heterzygotes. How do allele frequencies change if the two homozygotes have equal fitness, but heterozgotes have a 50% reduced fitness? Simulate allele frequency changes with multiple values of p0 (between 0 and 1).

#Define the parameters and set up the models
fitness=c(1,0.5,1)
gen.time=100
start.freq1=0.9
start.freq2=0.5
start.freq3=0.1

results1 <- selection(time = gen.time, p0=start.freq1, w=fitness)
results2 <- selection(time = gen.time, p0=start.freq2, w=fitness, add=TRUE, color="red")
results3 <- selection(time = gen.time, p0=start.freq3, w=fitness, add=TRUE, color="blue")

What happens? Can you explain why?

It appears that selection depends almost entirely only the starting frequency of AA in the population. When there is a high starting frequency, it will end with a high, if there is a low AA frequency, the end will be mostly all aa. When there is a medium amount of AA it will stay at that medium amount of AA. I’m not entirely sure why this would occur, but I think it has to do with the equal fitnesses for AA and aa, so the population will be fine with either allele.

4.6. Selection Against Heterozygotes; Asymmetrical Fitness between Homozygotes

Now conduct the same simulation, but the homozygotes have a different fitness. Again, run the simulation multiple times with different p0. You can also play with different fitness distributions to observe additional patterns.

#Define the parameters and set up the models
fitness1=c(0.9,0.5,0.4)
fitness2=c(0.5,0.5,0.456)
fitness3=c(0.3,0.5,0.1)
gen.time=100
start.freq1=0.9
start.freq2=0.5
start.freq3=0.1
results1 <- selection(time = gen.time, p0=start.freq1, w=fitness1)
results2 <- selection(time = gen.time, p0=start.freq2, w=fitness2, add=TRUE, color="red")
results3 <- selection(time = gen.time, p0=start.freq3, w=fitness3, add=TRUE, color="blue")

What happens? Can you explain why?

It looks like whatever allele has the higher fitness will end up with a higher amount in the population. The highest starting amount of the allele in the population seems to determine how much of the allele will be in the population, with a lower amount to start results in a lower end population of AA individuals.

5. Reflection

If you think back to your initial prediction, what have you learned from running all of these models?

I would say that I was partially correct. The higher the fitness, the more likely the end result with will be mostly the allele with the stronger fitness, but the starting frequency also plays a role in the end amount of allele percentage in the population. The means that despite a really high fitness, the starting frequency limits just how high the end amount of the high fitness allele can be.

6. Resources

6.1. Data References

This exercise does not contain original data.

6.2. Resources You Consulted

Consulting additional resources to solve this assignment is absolutely allowed, but failure to disclose those resources is plagiarism. Please list any collaborators you worked with and resources you used below or state that you have not used any.

I received help from the discussion post for the assignment.

LS0tDQp0aXRsZTogIlNpbXVsYXRpbmcgdGhlIEVmZmVjdHMgb2YgU2VsZWN0aW9uIGFuZCBEcmlmdCINCm91dHB1dDoNCiAgaHRtbF9ub3RlYm9vazoNCiAgICBmaWdfY2FwdGlvbjogeWVzDQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZGVwdGg6IDMNCiAgICB0b2NfZmxvYXQ6IHllcw0KLS0tDQoNCiMjIE5hdGhhbiBTdGV3YXJ0IDgxMTg0Nzc4OQ0KDQoNCmBgYHtyfQ0KZml0bmVzczE9YygxLDEsMC45KQ0KZml0bmVzczI9YygxLDEsMC41KQ0KZml0bmVzczM9YygxLDEsMC4xKQ0KZ2VuLnRpbWU9MTAwMA0Kc3RhcnQuZnJlcT0wLjUNCg0KcmVzdWx0czEgPC0gc2VsZWN0aW9uKHRpbWUgPSBnZW4udGltZSwgcDA9c3RhcnQuZnJlcSwgdz1maXRuZXNzMSkNCnJlc3VsdHMyIDwtIHNlbGVjdGlvbih0aW1lID0gZ2VuLnRpbWUsIHAwPXN0YXJ0LmZyZXEsIHc9Zml0bmVzczIsIGFkZD1UUlVFLCBjb2xvcj0icmVkIikNCnJlc3VsdHMzIDwtIHNlbGVjdGlvbih0aW1lID0gZ2VuLnRpbWUsIHAwPXN0YXJ0LmZyZXEsIHc9Zml0bmVzczMsIGFkZD1UUlVFLCBjb2xvcj0iYmx1ZSIpDQpgYGANCipUaGlzIGlzIHByb2JsZW0gMS4gQmxhY2sgaXMgd2Vha2VzdCBzZWxlY3Rpb24sIGJsdWUgaXMgdGhlIHN0cm9uZ2VzdC4gSXQganVzdCBpbXBhY3RzIHRoZSBzcGVlZCBhdCB3aGljaCBBIGJlY29tZXMgZml4ZWQuSW1wYWN0cyB0aGUgc3BlZWQgb2YgZXZvbHV0aW9uLiBhbHdheXMgQUEsIEFhLCBhYSoNCg0KDQojIDEuIEluaXRpYXRlIHRoZSBQcm9qZWN0DQpgYGB7ciBtZXNzYWdlPUZBTFNFfQ0KI1RoaXMgY29tbWFuZCBsb2FkcyByZXF1aXJlZCBwYWNrYWdlcw0KI05vdGUgdGhhdCB5b3UgbWF5IG5lZWQgdG8gaW5zdGFsbCB0aGUgbGVhcm5Qb3BHZW4gcGFja2FnZSBmaXJzdCENCmxpYnJhcnkobGVhcm5Qb3BHZW4pDQpgYGANCg0KSW1wb3J0YW50IHRpcDogSW4gdGhpcyBhbmQgdGhlIG5leHQgZXhlcmNpc2UsIHdlIHdpbGwgZm9jdXMgZW50aXJlbHkgb24gcnVubmluZyBkaWZmZXJlbnQgZXZvbHV0aW9uYXJ5IG1vZGVscy4gVGhlIHBsb3RzIGZvciB0aGVzZSBtb2RlbHMgYXJlIGdlbmVyYXRlZCBhdXRvbWF0aWNhbGx5LCBhbmQgeW91IGRvIG5vdCBuZWVkIHRvIHVzZSBnZ3Bsb3QgdG8gcHJvZHVjZSB0aGUgb3V0cHV0cy4gDQoNCiMgMi4gQmVmb3JlIFlvdSBHZXQgU3RhcnRlZC4uLg0KSW4gdGhlIGludHJvZHVjdGlvbiB2aWRlbywgSSBhc2tlZCB5b3UgdG8gcGF1c2UgYW5kIHByZWRpY3Qgd2hhdCBoYXBwZW5zIHRvIHRoZSBhbGxlbGUgZnJlcXVlbmN5IG9mIGFuIGFsbGVsZSBBIHRoYXQgcHJvdmlkZXMgYSBmaXRuZXNzIGFkdmFudGFnZSB0byBpdHMgY2FycmllcnMuIFdoYXQgaXMgeW91ciBwcmVkaWN0aW9uPw0KDQoqSSB3b3VsZCBwcmVkaWN0IHRoYXQgYW4gYWxsZWxlIHRoYXQgcHJvdmlkZXMgYSBmaXRuZXNzIGFkdmFudGFnZSB3b3VsZCBldmVudHVhbGx5IGJlY29tZSBjb21wbGV0ZWx5IGRvbWluYW50LioNCg0KIyAzLiBNb2RlbGluZyBBbGxlbGUgRnJlcXVlbmNpZXMgQWNyb3NzIEdlbmVyYXRpb25zOiBJbnRyb2R1Y2luZyBLZXkgUGFyYW1ldGVycw0KQXBwbHlpbmcgdGhlIEhXIHByaW5jaXBsZSBpcyBhIHBvd2VyZnVsIGFwcHJvYWNoIHRvIHRlc3Qgd2hldGhlciBhbnkgZXZvbHV0aW9uYXJ5IGZvcmNlcyBhcmUgaW1wYWN0aW5nIGEgcG9wdWxhdGlvbiBhdCBhbnkgZ2l2ZW4gbG9jdXMuIEl0IGRvZXMgbm90IHRlbGwgdXMsIGhvd2V2ZXIsIHdoYXQgZXZvbHV0aW9uYXJ5IGZvcmNlIG1pZ2h0IGJlIGFjdGluZyBvbiB0aGF0IGxvY3VzLiBJbiB0aGUgZm9sbG93aW5nIHNlY3Rpb25zLCB3ZSBnZXQgdG8ga25vdyBkaWZmZXJlbnQgZXZvbHV0aW9uYXJ5IGZvcmNlcyBhbmQgZGlzY292ZXIgaG93IHRoZXkgaW1wYWN0IGFsbGVsZSBmcmVxdWVuY2llcyBhY3Jvc3MgZ2VuZXJhdGlvbnMuDQoNCkZpcnN0IGxldCdzIGNvbnNpZGVyIGhvdyBuYXR1cmFsIHNlbGVjdGlvbiBhZmZlY3RzIGFsbGVsZSBmcmVxdWVuY2llcy4gTmF0dXJhbCBzZWxlY3Rpb24gZXNzZW50aWFsbHkgbWFuaWZlc3RzIGl0c2VsZiBpbiBkaWZmZXJlbnQgZ2Vub3R5cGVzIGhhdmluZyBhIGRpZmZlcmVudCBmaXRuZXNzLiBNYXRoZW1hdGljYWxseSwgd2UgYXNpZ24gYSBmaXRuZXNzIG9mIDEgdG8gb25lIGdlbm90eXBlIChBQSksIGFuZCB0aGUgZml0bmVzcyBvZiBvdGhlciBnZW5vdHlwZXMgY2FuIHRoYW4gYmUgZGVmaW5lZCByZWxhdGl2ZSB0byBBQSB3aXRoIGEgdGhlIHBhcmFtZXRlciBzICh0aGUgc3RyZW5ndGggb2Ygc2VsZWN0aW9uKS4gRm9yIGV4YW1wbGUsIGlmIHRoZSBnZW5vdHlwZSBhYSBoYXMgYSAxMCUgaGlnaGVyIGZpdG5lc3MgdGhhbiBBQSAocz0wLjEpLCBpdHMgZml0bmVzcyB3b3VsZCBiZSAxK3MgPSAxLjEuIElmIGdlbm90eXBlIEFhIGhhcyBhIDE1JSBsb3dlciBmaXRuZXNzIHRoYW4gQUEgKHM9LTAuMTUpLCBpdHMgZml0bmVzcyB3b3VsZCBiZSAxK3MgPSAwLjg1Lg0KDQpJdCB0YWtlcyBqdXN0IGEgZmV3IGtleSBwYXJhbWV0ZXJzIGZvciB1cyB0byBtb2RlbCBob3cgc2VsZWN0aW9uIGFmZmVjdHMgYWxsZWxlIGZyZXF1ZW5jeSBvdmVyIHRpbWU6ICgxKSBUaGUgc3RyZW5ndGggb2Ygc2VsZWN0aW9uLCBzLiAoMikgVGhlIG1vZGUgb2YgaW5oZXJpdGFuY2UgKGRvbWluYW50L3JlY2Vzc2l2ZSB2cy4gYWRkaXRpdmUpLiBJZiBhbiBhbGxlbGUgYXQgYSBwYXJ0aWN1bGFyIGxvY3VzIGlzIGRvbWluYW50IG92ZXIgYW5vdGhlciwgcyBmb3IgdGhlIGhldGVyb3p5Z290ZSBpcyB0aGUgc2FtZSBhcyBmb3IgdGhlIGRvbWluYW50IGhvbW96eWdvdGUuIEluaGVyaXRhbmNlLCBob3dldmVyLCBtYXkgbm90IGJlIGRvbWluYW50L3JlY2Vzc2l2ZSwgaW4gd2hpY2ggY2FzZSB5b3UgbmVlZCB0d28gdmFsdWVzIG9mIHMgdG8gZGVzY3JpYmUgaG93IHNlbGVjdGlvbiBtaWdodCBpbXBhY3QgZXZvbHV0aW9uLiANCg0KIVtdKGRvbWluYW50X2FkZGl0aXZlLnBuZykNCg0KIyA0LiBNb2RlbGluZyB0aGUgRWZmZWN0IG9mIFNlbGVjdGlvbiBvbiBBbGxlbGUgRnJlcXVlbmNpZXMgdXNpbmcgdGhlIFNlbGVjdGlvbiBDb21tYW5kDQpXZSBjYW4gbW9kZWwgdGhlIGdlbm90eXBlIGZyZXF1ZW5jaWVzIGluICByZXNwb25zZSB0byBzZWxlY3Rpb24gd2l0aCB0aGUgc2VsZWN0aW9uIGZ1bmN0aW9uLiBBbGwgd2UgbmVlZCB0byBkbyBpcyB0byB0ZWxsIHRoZSBmdW5jdGlvbiB0aGUgKipmaXRuZXNzICh3KSBvZiB0aGUgdGhyZWUgZ2Vub3R5cGVzIChBQSwgQWEsIGFhKSoqLiBJZiB0aGUgbW9kZSBvZiBpbmhlcml0YW5jZSBpcyBkb21pbmFudC9yZWNlc3NpdmUsIGZpdG5lc3MgaXMgZGVmaW5lZCBhczoNCg0KZml0bmVzcyA8LSBjKDEsIDEsIDErcykNCg0KSWYgdGhlIG1vZGUgb2YgaW5oZXJpdGFuY2UgaXMgbm90IGRvbWluYW50L3JlY2Vzc2l2ZSwgZml0bmVzcyBpcyBkZWZpbmVkIGFzOg0KDQpmaXRuZXNzIDwtIGMoMSwgMStzMSwgMStzMikNCg0KT3RoZXIgcGFyYW1ldGVycyB0aGF0IGFyZSByZXF1aXJlZCBpcyAqKnAwICh0aGUgc3RhcnRpbmcgYWxsZWxlIGZyZXF1ZW5jeSBvZiBwKSoqIGFuZCAqKnRpbWUgKHRoZSBudW1iZXIgb2YgZ2VuZXJhdGlvbnMgeW91IHdhbnQgdG8gcnVuIHRoZSBzaW11bGF0aW9uIGZvcikqKi4gV2UgZGVmaW5lIHRoZXNlIGFzOg0KDQpzdGFydC5mcmVxIDwtIG51bWJlciAoYmV0d2VlbiAwIGFuZCAxKQ0KDQpnZW4udGltZSA8LSBudW1iZXIgKGJldHdlZW4gMSBhbmQgaW5maW5pdHk7IGJlIGNhdXRpb3VzIHdpdGggaGlnaCBudW1iZXJzLCBhcyB0aGV5IHVzZSBzaWduaWZpY2FudCBjb21wdXRhdGlvbiB0aW1lKQ0KDQpTZXR0aW5nIHRoZXNlIHBhcmFtZXRlcnMsIHdlIGNhbiBtb2RlbCB0aGUgZWZmZWN0cyBvZiBzZWxlY3Rpb24gd2l0aCB0aGUgInNlbGVjdGlvbiIgY29tbWFuZCBhcyBmb2xsb3dzOg0KDQpyZXN1bHQgPC1zZWxlY3Rpb24odz1maXRuZXNzLCB0aW1lPWdlbi50aW1lLCBwMD1zdGFydC5mcmVxKQ0KDQpMZXQncyBwdXQgdGhpcyB0byB0aGUgdGVzdC4gTGV0J3MgbW9kZWwgdGhlIGVmZmVjdCBvZiBzZWxlY3Rpb24gb24gYSBnZW5lIHdpdGggYSBkb21pbmFudC9yZWNlc3NpdmUgbW9kZSBvZiBpbmhlcml0YW5jZSwgd2l0aCB0aGUgcmVjZXNzaXZlIGFsbGVsZSBiZWluZyBkZWxldGVyaW91cyAoaS5lLiwgaXRzIGZpdG5lc3MgaXMgemVybykuIFNldCB0aGUgc3RhcnRpbmcgYWxsZWxlIGZyZXF1ZW5jeSBhdCAwLjUgYW5kIHJ1biB0aGUgc2ltdWxhdGlvbiBmb3IgNTAgZ2VuZXJhdGlvbnMuDQoNCmBgYHtyfQ0KI0RlZmluZSB0aGUgZml0bmVzcyBvZiBlYWNoIGdlbm90eXBlDQpmaXRuZXNzIDwtIGMoMSwgMSwgMCkNCg0KI0RlZmluZSB0aGUgc3RhcnRpbmcgYWxsZWxlIGZyZXF1ZW5jeSBwMA0Kc3RhcnQuZnJlcSA8LSAwLjUNCg0KI0RlZmluZSBob3cgbWFueSBnZW5lcmF0aW9ucyB5b3Ugd2FudCB0byBzaW11bGF0ZQ0KZ2VuLnRpbWUgPC0gNTANCg0KI01vZGVsIHRoZSBhbGxlbGUgY2hhbmdlcyBhbmQgc3RvcmUgdGhlIHJlc3VsdHMgaW4gYW4gb2JqZWN0IGNhbGxlZCByDQpyIDwtIHNlbGVjdGlvbih3PWZpdG5lc3MsIHRpbWU9Z2VuLnRpbWUsIHAwPXN0YXJ0LmZyZXEpDQpgYGANCg0KTm90ZSB0aGF0IHJ1bm5pbmcgdGhlIHNlbGVjdGlvbiBjb21tYW5kIGF1dG9tYXRpY2FsbHkgcGxvdHMgdGhlIHJlc3VsdHMgb2YgdGhlIG1vZGVsLiBZb3UgY2FuIGFsc28gZGlyZWN0bHkgbG9vayBhdCB0aGUgbnVtYmVycyBhcyBhIHRhYmxlIHVzaW5nIHRoZSBmb2xsb3dpbmcgY29kZS4NCg0KYGBge3J9DQojWW91IGNhbiBhbHNvIGxvb2sgYXQgdGhlIGFjdHVhbCBudW1iZXIgaWYgeW91IHdhbnQgdG8NCnIudGFibGUgPC0gZGF0YS5mcmFtZSgxOmdlbi50aW1lLCByJHApDQpuYW1lcyhyLnRhYmxlKSA8LSBjKCJHZW5lcmF0aW9uIiwgInAiKQ0KDQojU2hvdyBsYXN0IHBhcnQgb2YgdGhlIHRhYmxlIGluIHRoZSByZXN1bHRzDQp0YWlsKHIudGFibGUpDQpgYGANCg0KSSBob3BlIHdoYXQgeW91IGNhbiBvYnNlcnZlIGlzIHRoYXQgdGhlIGZyZXF1ZW5jeSBvZiBBIChwKSBpbmNyZWFzZXMgb3ZlciB0aW1lLiBUaGUgc3BlZWQgb2YgY2hhbmdlIHNsb3dzIGFzIEEgZ2V0cyBtb3JlIGNvbW1vbiwgYW5kIGl0IGV2ZW50dWFsbHkgZmxhdHRlbnMuDQoNCiMjIDQuMS4gVmFyeWluZyB0aGUgU3RyZW5ndGggb2YgU2VsZWN0aW9uDQpJbiB0aGUgY29taW5nIHNldCBvZiBzaW11bGF0aW9ucywgbGV0J3MgZXhwbG9yZSBob3cgdmFyeWluZyB0aGUgc3RyZW5ndGggb2Ygc2VsZWN0aW9uIGltcGFjdHMgaG93IGFsbGVsZSBmcmVxdWVuY2llcyBjaGFuZ2UgYWNyb3NzIGdlbmVyYXRpb25zLiBXZSBmb2N1cyBvbiBhIHNpbmdsZSBnZW5lIHdpdGggY29tcGxldGUgZG9taW5hbmNlIG9mIHRoZSBBIGFsbGVsZS4gSW4gdGhlc2UgZmlyc3Qgc2NlbmFyaW9zIHRoZSBkb21pbmFudCBwaGVub3R5cGUgaGFzIGEgc2VsZWN0aXZlIGFkdmFudGFnZSBvdmVyIHRoZSByZWNlc3NpdmUgb25lLCBidXQgdGhlIEEgYWxsZWxlIGlzIHN0YXJ0aW5nIGF0IGEgdmVyeSBsb3cgZnJlcXVlbmN5IGluIHRoZSBwb3B1bGF0aW9uIChwMD0wLjAwMDEpLiBJbiB0aGUgZmlyc3QgZXhhbXBsZSwgdGhlIHN0cmVuZ3RoIG9mIHNlbGVjdGlvbiBhZ2FpbnN0IHRoZSByZWNlc3NpdmUgaG9tb3p5Z290ZXMgaXMgcz0tMC4xLiBSdW4gdGhlIHNpbXVsYXRpb24gYW5kIHJlY29yZCB3aGF0IGhhcHBlbnMgdG8gdGhlIGFsbGVsZSBmcmVxdWVuY2llcyBvZiBBIGFuZCBhIG92ZXIgMTAwMCBnZW5lcmF0aW9ucy4gV2hhdCBkbyB5b3Ugb2JzZXJ2ZT8gRXhwbGFpbiB0aGUgcGF0dGVybi4gDQpgYGB7cn0NCiNEZWZpbmUgdGhlIGZpdG5lc3Mgb2YgZWFjaCBnZW5vdHlwZQ0KZml0bmVzczEgPC0gYygxLCAxLCAoLTAuMSkpDQoNCiNEZWZpbmUgdGhlIHN0YXJ0aW5nIGFsbGVsZSBmcmVxdWVuY3kgcDANCnN0YXJ0LmZyZXExIDwtIDAuMDAwMSANCg0KI0RlZmluZSBob3cgbWFueSBnZW5lcmF0aW9ucyB5b3Ugd2FudCB0byBzaW11bGF0ZQ0KZ2VuLnRpbWUxIDwtIDEwMDANCg0KI01vZGVsIHRoZSBhbGxlbGUgY2hhbmdlcyBhbmQgc3RvcmUgdGhlIHJlc3VsdHMgaW4gYW4gb2JqZWN0IHIxOyBub3RlIHRoYXQgdGhlIHBhcmFtZXRlciB0IGp1c3Qgc2lnbmlmaWVzIGhvdyBtYW55IGdlbmVyYXRpb25zIHdpbGwgYmUgc2ltdWxhdGVkDQpyMSA8LSBzZWxlY3Rpb24odz1maXRuZXNzMSwgdGltZT1nZW4udGltZTEsIHAwPXN0YXJ0LmZyZXExKQ0KYGBgDQoqaSBvYnNlcnZlZCB0aGF0IHRoZSBmcmVxdWVuY3kgb2YgQSBhcHBlYXJzIHRvIHNob290IHVwIHZlcnkgcXVpY2tseSwgYW5kIGxldmVsIG91dCB3aGF0IGFwcGVhcnMgdG8gYmUgd2l0aGluIDMwMCBnZW5lcmF0aW9ucy4gVGhlcmUgaXMgYSBzaGFycCBpbmNyZWFzZSB1bnRpbCBhYm91dCAxMDAgZ2VuZXJhdGlvbnMuIFRoaXMgbWVhbnMgdGhhdCB0aGUgImEiIGFsbGVsZSBpcyBzZWxlY3RlZCBhdCBhIHJhdGUgb2YgLS4xIGFuZCBhbHJlYWR5IHN0YXJ0ZWQgYXQgYSB2ZXJ5IGxvdyBmcmVxdWVuY3ksIHRoaXMgbWVuYXMgdGhhdCAiQSIgYWxsZWxlIGlzIHNlbGVjdGVkIGF0IGEgaGlnaGVyIHJhdGUuKg0KDQpUbyB0cnVseSB1bmRlcnN0YW5kIGhvdyB0aGUgc3RyZW5ndGggb2Ygc2VsZWN0aW9uIGltcGFjdHMgYWxsZWxlIGZyZXF1ZW5jaWVzLCB3ZSBuZWVkIHRvIHJ1biBtdWx0aXBsZSBtb2RlbHMgYXNzdW1pbmcgZGlmZmVyZW50IGZpdG5lc3NlcyBmb3Igb3VyIGdlbm90eXBlcy4gVXNpbmcgdGhlIHNhbWUgcGFyYW1ldGVycyBhcyBhYm92ZSwgcnVuIG11bHRpcGxlIG1vZGVscyB3aXRoIHRoZSBzZWxlY3Rpb24gY29lZmZpY2llbnQgdmFyeWluZyBiZXR3ZWVuIC0xIGFuZCAwLiBSYXRoZXIgdGhhbiBydW5uaW5nIGVhY2ggbW9kZWwgc2VwYXJhdGVseSwgeW91IGNhbiBhY3R1YWxseSBydW4gdGhlbSBpbiBidWxrLCBhbmQgdGhlIGZvbGxvd2luZyBjb2RlIHNuaXBwZXQgdGVhY2hlcyB5b3UgaG93Lg0KDQpgYGB7cn0NCiNEZWZpbmUgdGhlIGZpdG5lc3Mgb2YgZWFjaCBnZW5vdHlwZS4gVW5saWtlIGFib3ZlLCB5b3Ugd2FudCB0byB2YXJ5IHRoZSBzdHJlbmd0aCBvZiBzZWxlY3Rpb24sIHNvIHdlIHdpbGwgZGVmaW5lIG11bHRpcGxlIGZpdG5lc3Mgc2V0cyAob25lIGZvciBlYWNoIG1vZGVsIHlvdSB3YW50IHRvIHJ1bikNCmZpdG5lc3MxIDwtIGMoMSwxLDEpDQpmaXRuZXNzMiA8LSBjKDEsMSwwLjcpDQpmaXRuZXNzMyA8LSBjKDEsMSwwLjUpDQpmaXRuZXNzNCA8LSBjKDEsMSwwLjMpDQpmaXRuZXNzNSA8LSBjKDEsMSwwKQ0KDQojRGVmaW5lIHRoZSBzdGFydGluZyBhbGxlbGUgZnJlcXVlbmN5IHAwLiBUaGlzIHBhcmFtZXRlciB3aWxsIHdpbGwgYmUgdGhlIHNhbWUgZm9yIGFsbCBtb2RlbHMsIHNvIHlvdSBvbmx5IG5lZWQgdG8gZGVmaW5lIGl0IG9uY2UuDQpzdGFydC5mcmVxMSA8LSAwLjAwMDENCg0KI0RlZmluZSBob3cgbWFueSBnZW5lcmF0aW9ucyB5b3Ugd2FudCB0byBzaW11bGF0ZS4gVGhpcyBwYXJhbWV0ZXIgd2lsbCB3aWxsIGJlIHRoZSBzYW1lIGZvciBhbGwgbW9kZWxzLCBzbyB5b3Ugb25seSBuZWVkIHRvIGRlZmluZSBpdCBvbmNlLg0KZ2VuLnRpbWUxIDwtIDEwMDANCg0KI01vZGVsIHRoZSBhbGxlbGUgY2hhbmdlcyBmb3IgdGhlIGRpZmZlcmVudCBzdHJlbmd0aHMgb2Ygc2VsZWN0aW9uLiBZb3UgbmVlZCB0byBydW4gb25lIG1vZGVsIGZvciBlYWNoIGZpdG5lc3MgZGlzdHJpYnV0aW9uIHlvdSBkZWZpbmVkIGFib3ZlLiBOb3RlIHRoYXQgeW91IGNhbiBwbG90IGFsbCByZXN1bHRzIGluIGEgc2luZ2xlIGdyYXBoIGJ5IGFkZGluZyAiYWRkPVRSVUUiIHN0YXJ0aW5nIGF0IHRoZSBzZWNvbmQgbW9kZWwuIA0KcjEgPC0gc2VsZWN0aW9uKHc9Zml0bmVzczEsIHRpbWU9Z2VuLnRpbWUxLCBwMD1zdGFydC5mcmVxMSkNCnIyIDwtIHNlbGVjdGlvbih3PWZpdG5lc3MyLCB0aW1lPWdlbi50aW1lMSwgcDA9c3RhcnQuZnJlcTEsIGFkZD1UUlVFLCBjb2xvciA9ICdyZWQnKQ0KcjMgPC0gc2VsZWN0aW9uKHc9Zml0bmVzczMsIHRpbWU9Z2VuLnRpbWUxLCBwMD1zdGFydC5mcmVxMSwgYWRkPVRSVUUsIGNvbG9yID0gJ2JsdWUnKQ0KcjQgPC0gc2VsZWN0aW9uKHc9Zml0bmVzczQsIHRpbWU9Z2VuLnRpbWUxLCBwMD1zdGFydC5mcmVxMSwgYWRkPVRSVUUsIGNvbG9yID0gJ2dyZWVuJykNCnI1IDwtIHNlbGVjdGlvbih3PWZpdG5lc3M1LCB0aW1lPWdlbi50aW1lMSwgcDA9c3RhcnQuZnJlcTEsIGFkZD1UUlVFLCBjb2xvciA9ICdwdXJwbGUnKQ0KYGBgDQoNCkxvb2tpbmcgYXQgdGhlIHJlc3VsdHMgb2YgeW91ciBtb2RlbHMsIGhvdyBkb2VzIHZhcnlpbmcgdGhlIHN0cmVuZ3RoIG9mIHNlbGVjdGlvbiBhZmZlY3QgY2hhbmdlcyBpbiBhbGxlbGUgZnJlcXVlbmNpZXMgYWNyb3NzIGdlbmVyYXRpb25zPw0KDQoqV2l0aCBkZWNyZWFzaW5nIHN0cmVuZ3RoIG9mIHNlbGVjdGlvbiwgdGhlIHRpbWUgaXQgdGFrZXMgdG8gYXJyaXZlIGF0IDEuIEZvciBleGFtcGxlLCB3aGVuIHRoZXJlIGlzIGEgZGVjcmVhc2VkIHN0cmVuZ3RoIG9mIHNlbGVjdGlvbiwgaXQgdGFrZXMgbGVzcyB0aW1lIHRvIGFycml2ZSBhdCBoaWdoZXIgZnJlcXVlbmNpZXMgb2YgQUEuICoNCg0KIyMgNC4yLiBTZWxlY3Rpb24gb24gRG9taW5hbnQgdnMuIFJlY2Vzc2l2ZSBwaGVub3R5cGVzDQpMZXTigJlzIGV4YW1pbmUgd2hhdCBoYXBwZW5zIHdoZW4gdGhlIHBoZW5vdHlwZSB3aXRoIGhpZ2hlciBmaXRuZXNzIGlzIGRvbWluYW50IHZzLiByZWNlc3NpdmUuIEZpcnN0LCBzZXQgdGhlIHN0YXJ0aW5nIGZyZXF1ZW5jeSBvZiB0aGUgQSBhbGxlbGUgdG8gcDA9MC4wMSwgYW5kIGdpdmUgdGhlIGRvbWluYW50IHBoZW5vdHlwZSBhIGZpdG5lc3MgYWR2YW50YWdlIG92ZXIgdGhlIHJlY2Vzc2l2ZSBwaGVub3R5cGUgKHMgYWdhaW5zdCB0aGUgcmVjZXNzaXZlIGhvbW96eWdvdGVzIGlzIC0wLjIpLiBSdW4gdGhlIHNpbXVsYXRpb24gZm9yIDEwMDAgZ2VuZXJhdGlvbnMuIA0KDQpgYGB7cn0NCiNEZWZpbmUgdGhlIGZpdG5lc3Mgb2YgZWFjaCBnZW5vdHlwZQ0KZml0bmVzczEgPC0gYygxLDEsMC44KQ0KDQojRGVmaW5lIHRoZSBzdGFydGluZyBhbGxlbGUgZnJlcXVlbmN5IHAwDQpzdGFydC5mcmVxMSA8LTAuMDENCg0KI0RlZmluZSBob3cgbWFueSBnZW5lcmF0aW9ucyB5b3Ugd2FudCB0byBzaW11bGF0ZQ0KZ2VuLnRpbWUxIDwtIDEwMDANCg0KI01vZGVsIHRoZSBhbGxlbGUgY2hhbmdlcyBhbmQgc3RvcmUgdGhlIHJlc3VsdHMgaW4gYW4gb2JqZWN0IHIxOyBub3RlIHRoYXQgdGhlIHBhcmFtZXRlciB0IGp1c3Qgc2lnbmlmaWVzIGhvdyBtYW55IGdlbmVyYXRpb25zIHdpbGwgYmUgc2ltdWxhdGVkDQpyMSA8LSBzZWxlY3Rpb24odz1maXRuZXNzMSwgdGltZT1nZW4udGltZTEsIHAwPXN0YXJ0LmZyZXExKQ0KDQojSW4gdGhpcyBjYXNlLCBpdCBtYXkgYmUgdXNlZnVsIHRvIGxvb2sgYXQgdGhlIGFjdHVhbCBudW1iZXJzIGZvciBwIGF0IHRoZSBlbmQgb2YgeW91ciBzaW11bGF0aW9uDQpyMS50YWJsZSA8LSBkYXRhLmZyYW1lKDE6Z2VuLnRpbWUxLCByMSRwKQ0KbmFtZXMocjEudGFibGUpIDwtIGMoIkdlbmVyYXRpb24iLCAicCIpDQp0YWlsKHIxLnRhYmxlKQ0KYGBgDQoNCk5vdyBsZXQncyBleGFtaW5lIHRoZSBvcHBvc2l0ZSBzY2VuYXJpby4gU2V0IHRoZSBzdGFydGluZyBhbGxlbGUgZnJlcXVlbmN5IHAwPTAuOTkgYnV0IHRoaXMgdGltZSBnaXZlIHRoZSByZWNlc3NpdmUgcGhlbm90eXBlIHRoZSBmaXRuZXNzIGFkdmFudGFnZSBvdmVyIHRoZSBkb21pbmFudCBwaGVub3R5cGUgKHNhbWUgcyBhcyBhYm92ZSkuIFJ1biB0aGUgc2ltdWxhdGlvbiBmb3IgMTAwMCBnZW5lcmF0aW9ucy4NCg0KYGBge3J9DQojRGVmaW5lIHRoZSBmaXRuZXNzIG9mIGVhY2ggZ2Vub3R5cGUNCmZpdG5lc3MyIDwtYygwLjgsMSwxKQ0KDQojRGVmaW5lIHRoZSBzdGFydGluZyBhbGxlbGUgZnJlcXVlbmN5IHAwDQpzdGFydC5mcmVxMiA8LSAwLjk5DQoNCiNEZWZpbmUgaG93IG1hbnkgZ2VuZXJhdGlvbnMgeW91IHdhbnQgdG8gc2ltdWxhdGUNCmdlbi50aW1lMiA8LSAxMDAwDQoNCiNNb2RlbCB0aGUgYWxsZWxlIGNoYW5nZXMgYW5kIHN0b3JlIHRoZSByZXN1bHRzIGluIGFuIG9iamVjdCByMTsgbm90ZSB0aGF0IHRoZSBwYXJhbWV0ZXIgdCBqdXN0IHNpZ25pZmllcyBob3cgbWFueSBnZW5lcmF0aW9ucyB3aWxsIGJlIHNpbXVsYXRlZA0KcjIgPC0gc2VsZWN0aW9uKHc9Zml0bmVzczIsIHRpbWU9Z2VuLnRpbWUyLCBwMD1zdGFydC5mcmVxMikNCg0KI0luIHRoaXMgY2FzZSwgaXQgbWF5IGJlIHVzZWZ1bCB0byBsb29rIGF0IHRoZSBhY3R1YWwgbnVtYmVycyBmb3IgcCBhdCB0aGUgZW5kIG9mIHlvdXIgc2ltdWxhdGlvbg0KcjIudGFibGUgPC0gZGF0YS5mcmFtZSgxOmdlbi50aW1lMiwgcjIkcCkNCm5hbWVzKHIyLnRhYmxlKSA8LSBjKCJHZW5lcmF0aW9uIiwgInAiKQ0KdGFpbChyMi50YWJsZSkNCmBgYA0KDQpDb21wYXJlIGFuZCBjb250cmFzdCB0aGUgcmVzdWx0cyBvZiB0aGUgdHdvIHNpbXVsYXRpb25zPyBXaGF0IGRvIHlvdSBub3RpY2UgYWJvdXQgdGhlIHBhY2Ugb2YgY2hhbmdlIGFuZCB0aGUgZmluYWwgYWxsZWxlIGZyZXF1ZW5jaWVzPyBXaHkgZG9lcyB0aGUgcmVjZXNzaXZlIGFsbGVsZSBwZXJzaXN0IGluIGEgcG9wdWxhdGlvbiB3aGVuIHNlbGVjdGVkIGFnYWluc3QsIGJ1dCB0aGUgZG9taW5hbnQgYWxsZWxlIGRvZXMgbm90Pw0KDQoqVGhlIHJlc3VsdHMgbG9vayBzaW1pbGFyIGF0IGZpcnN0LCBleGNlcHQgdG93YXJkcyBvcHBvc2l0ZSBhbGxlbGVzLCBidXQgaWYgeW91IGxvb2sgYXQgc21hbGxlciBwZXJpb2RzIG9mIHRpbWUsIHRoZSByZWNlc3NpdmUgYWxsZWxlIGlzIHByZXNlbnQgZm9yIGxvbmdlci4gVGhpcyBpcyBsaWtlbHkgZHVlIHRvIHRoZSBkaWZmZXJlbnQgc3RhcnRpbmcgZnJlcXVlbmNpZXMuKg0KDQojIyA0LjMuIFNlbGVjdGlvbiBGb3IgSGV0ZXJvenlnb3RlczsgU3ltbWV0cmljYWwgRml0bmVzcyBiZXR3ZWVuIEhvbW96eWdvdGVzDQpTbyBmYXIgd2UgaGF2ZSBvbmx5IGNvbnNpZGVyZWQgc2NlbmFyaW9zIHdoZXJlIGZpdG5lc3Mgd2FzIGRpc3RyaWJ1dGVkIGluIGEgZG9taW5hbnQvcmVjZXNzaXZlIHdheS4gTm93IHdlIGFyZSBnb2luZyB0byBpbnZlc3RpZ2F0ZSB0aGUgY29uc2VxdWVuY2VzIG9mIHNlbGVjdGlvbiBmb3IgaGV0ZXJvenlnb3VzIGluZGl2aWR1YWxzICh0aGV5IGhhdmUgYSBmaXRuZXNzIGFkdmFudGFnZSBvdmVyIGhvbW96eWdvdXMgaW5kaXZpZHVhbHMpLiBHaXZlIHRoZSBoZXRlcm96eWdvdXMgZ2Vub3R5cGVzIGEgMSUgZml0bmVzcyBhZHZhbnRhZ2Ugb3ZlciBib3RoIG9mIHRoZSBob21venlnb3VzIGdlbm90eXBlcy4gUnVuIG11bHRpcGxlIHNpbXVsYXRpb25zIGZvciAxMDAwIGdlbmVyYXRpb25zIGFuZCB2YXJ5IHRoZSBzdGFydGluZyBhbGxlbGUgZnJlcXVlbmN5IGZvciB2YWx1ZXMgYmV0d2VlbiAwIGFuZCAxLg0KYGBge3J9DQojRGVmaW5lIHRoZSBwYXJhbWV0ZXJzIGFuZCBzZXQgdXAgdGhlIG1vZGVscw0KZml0bmVzczE9YygxLDEuMDEsMSkNCmZpdG5lc3MyPWMoMSwxLjAxLDEpDQpmaXRuZXNzMz1jKDEsMS4wMSwxKQ0KZ2VuLnRpbWU9MTAwMA0Kc3RhcnQuZnJlcTE9MC45DQpzdGFydC5mcmVxMj0wLjUNCnN0YXJ0LmZyZXEzPTAuMQ0KcmVzdWx0czEgPC0gc2VsZWN0aW9uKHRpbWUgPSBnZW4udGltZSwgcDA9c3RhcnQuZnJlcTEsIHc9Zml0bmVzczEpDQpyZXN1bHRzMiA8LSBzZWxlY3Rpb24odGltZSA9IGdlbi50aW1lLCBwMD1zdGFydC5mcmVxMiwgdz1maXRuZXNzMiwgYWRkPVRSVUUsIGNvbG9yPSJyZWQiKQ0KcmVzdWx0czMgPC0gc2VsZWN0aW9uKHRpbWUgPSBnZW4udGltZSwgcDA9c3RhcnQuZnJlcTMsIHc9Zml0bmVzczMsIGFkZD1UUlVFLCBjb2xvcj0iYmx1ZSIpDQpgYGANCg0KV2hhdCBoYXBwZW5zIHRvIHRoZSBhbGxlbGUgZnJlcXVlbmNpZXMgaW4gdGhlIHBvcHVsYXRpb24/IENhbiB5b3UgZXhwbGFpbiB3aHk/DQoNCipTaW5jZSB0aGVyZSBpcyBhIGZpdG5lc3MgYWR2YW50YWdlIGZvciBoZXRlcm96eWdvc2l0eSwgdGhlIHBvcHVsYXRpb25zIHdpbGwgdHJlbmQgdG93YXJkcyB3aGF0ZXZlciBhbGxlbGUgdHlwZSBoYXMgdGhlIGhpZ2hlciBmaXRuZXNzLiBJbiB0aGlzIGNhc2UsIGl0IHdhcyB0aGUgaGV0ZXJvenlnb3VzIGluZGl2aWR1YWxzLiBUaGUgc3RhcnRpbmcgZnJlcXVlbmN5IGRldGVybWluZXMgdGhlIGhvdyBkcmFtYXRpY2FsbHkgdGhlIGFsbGVsZXMgd2lsbCBjaGFuZ2UuIFRoZSBncmFwaCBzaG93cyB0aGF0IHdoZW4gdGhlIHN0YXJ0aW5nIEFBIGFsZWxlcyBhcmUgaGlnaCwgdGhlcmUgd2lsbCBiZSBhIGRyb3AgdG93YXJkcyBBYSwgYW5kIHdoZW4gYSBoaWdoZXIgZnJlcXVlbmN5IG9mIGFhIChsb3dlciBmcmVxdWVuY3kgb2YgQUEpIHRoZXJlIHdpbGwgYmUgYSByaXNlIGluIGZyZXF1ZW5jeSBvZiBBIHVudGlsIGl0IHJlYWNoZXMgbW9zdGx5IEFhLiAqDQoNCiMjIDQuNC4gU2VsZWN0aW9uIEZvciBIZXRlcm96eWdvdGVzOyBBc3ltbWV0cmljYWwgRml0bmVzcyBiZXR3ZWVuIEhvbW96eWdvdGVzDQpXaGF0IGhhcHBlbnMgd2hlbiBoZXRlcm96eWdvdXMgaW5kaXZpZHVhbHMgaGF2ZSBhIGZpdG5lc3MgYWR2YW50YWdlLCBidXQgc2VsZWN0aW9uIGlzIHN0cm9uZ2VyIGFnYWluc3Qgb25lIG9mIHRoZSBob21venlnb3VzIGdlbm90eXBlcz8gU2V0IHRoZSBzdGFydGluZyBhbGxlbGUgZnJlcXVlbmN5IHRvIHAwPTAuMSwgYW5kIGdpdmUgdGhlIGFhIGdlbm90eXBlIGEgZml0bmVzcyBvZiAwLjAuIFJ1biB0aGUgc2ltdWxhdGlvbiB3aXRoIHZhcmlvdXMgZml0bmVzcyBjb2VmZmljaWVudHMgZm9yIHRoZSBBQSBnZW5vdHlwZSAoYmV0d2VlbiAwIGFuZCAxKSwgd2hpbGUga2VlcGluZyB0aGUgZml0bmVzcyBvZiB0aGUgaGV0ZXJvenlnb3RlcyBhdCAxLiANCg0KYGBge3J9DQojRGVmaW5lIHRoZSBwYXJhbWV0ZXJzIGFuZCBzZXQgdXAgdGhlIG1vZGVscw0KZml0bmVzczE9YygwLjksMSwwLjApDQpmaXRuZXNzMj1jKDAuNSwxLDAuMCkNCmZpdG5lc3MzPWMoMC4xLDEsMC4wKQ0KZ2VuLnRpbWU9MTAwDQpzdGFydC5mcmVxPTAuMQ0KDQpyZXN1bHRzMSA8LSBzZWxlY3Rpb24odGltZSA9IGdlbi50aW1lLCBwMD1zdGFydC5mcmVxLCB3PWZpdG5lc3MxKQ0KcmVzdWx0czIgPC0gc2VsZWN0aW9uKHRpbWUgPSBnZW4udGltZSwgcDA9c3RhcnQuZnJlcSwgdz1maXRuZXNzMiwgYWRkPVRSVUUsIGNvbG9yPSJyZWQiKQ0KcmVzdWx0czMgPC0gc2VsZWN0aW9uKHRpbWUgPSBnZW4udGltZSwgcDA9c3RhcnQuZnJlcSwgdz1maXRuZXNzMywgYWRkPVRSVUUsIGNvbG9yPSJibHVlIikNCmBgYA0KDQpIb3cgZG9lcyBjaGFuZ2luZyB0aGUgZml0bmVzcyBvZiBBQSBpbmRpdmlkdWFscyBpbmZsdWVuY2UgdGhlIGZpbmFsIGFsbGVsZSBmcmVxdWVuY2llcyBpbiB0aGUgcG9wdWxhdGlvbiBvdmVyIHRpbWU/IFdpbGwgdGhlIGRlbGV0ZXJpb3VzIGFsbGVsZSBldmVyIGJlIGxvc3QgZnJvbSB0aGUgcG9wdWxhdGlvbj8gV2hhdCBhcmUgdGhlIGxvd2VzdCBhbmQgaGlnaGVzdCBmcmVxdWVuY2llcyB0aGUgYSBhbGxlbGUgY2FuIHJlYWNoPyBXaHk/DQoNCipUaGUgZml0bmVzcyBvZiBBQSBpbmRpdmlkdWFscyBhZmZlY3RzIHRoZSBlbmQgY29uY2VudHJhdGlvbiBvZiBBQSBpbiB0aGUgcG9wdWxhdGlvbi4gV2hlbiB0aGVyZSBpcyBhIGxvdyBmaXRuZXNzLCB0aGUgYW1vdW50IG9mIEFBIGluZGl2aWR1YWxzIHdhcyBtdWNoIGxvd2VyIHRoYW4gYSBoaWdoIGZpdG5lc3MgZm9yIEFBIGluZGl2aWR1YWxzLiBUaGUgYWEgd2lsbCBub3QgYmUgcmVtb3ZlZCBmcm9tIHRoZSBwb3B1bGF0aW9uLCBiZWNhdXNlIHRoZXJlIHdpbGwgYWx3YXlzIGJlIHNvbWUgc3Vydml2aW5nIEFhIGluZGl2aWR1YWxzLiBUaGUgaGlnaGVzdCBhbW91bnQgd291bGQgYmUgYXJvdW5kIDkwJSByZW1vdmVkLCB3aGlsZSB0aGUgbG93ZXN0IHdvdWxkIGJlIDUwJSByZW1vdmFsIGR1ZSB0byB0aGUgaGV0ZXJvenlnb3VzIGluZGl2aWR1YWxzLioNCg0KIyMgNC41LiBTZWxlY3Rpb24gQWdhaW5zdCBIZXRlcm96eWdvdGVzOyBTeW1tZXRyaWNhbCBGaXRuZXNzIGJldHdlZW4gSG9tb3p5Z290ZXMNClNlbGVjdGlvbiBtYXkgYWxzbyBhY3QgYWdhaW5zdCBoZXRlcnp5Z290ZXMuIEhvdyBkbyBhbGxlbGUgZnJlcXVlbmNpZXMgY2hhbmdlIGlmIHRoZSB0d28gaG9tb3p5Z290ZXMgaGF2ZSBlcXVhbCBmaXRuZXNzLCBidXQgaGV0ZXJvemdvdGVzIGhhdmUgYSA1MCUgcmVkdWNlZCBmaXRuZXNzPyBTaW11bGF0ZSBhbGxlbGUgZnJlcXVlbmN5IGNoYW5nZXMgd2l0aCBtdWx0aXBsZSB2YWx1ZXMgb2YgcDAgKGJldHdlZW4gMCBhbmQgMSkuDQoNCmBgYHtyfQ0KI0RlZmluZSB0aGUgcGFyYW1ldGVycyBhbmQgc2V0IHVwIHRoZSBtb2RlbHMNCmZpdG5lc3M9YygxLDAuNSwxKQ0KZ2VuLnRpbWU9MTAwDQpzdGFydC5mcmVxMT0wLjkNCnN0YXJ0LmZyZXEyPTAuNQ0Kc3RhcnQuZnJlcTM9MC4xDQoNCnJlc3VsdHMxIDwtIHNlbGVjdGlvbih0aW1lID0gZ2VuLnRpbWUsIHAwPXN0YXJ0LmZyZXExLCB3PWZpdG5lc3MpDQpyZXN1bHRzMiA8LSBzZWxlY3Rpb24odGltZSA9IGdlbi50aW1lLCBwMD1zdGFydC5mcmVxMiwgdz1maXRuZXNzLCBhZGQ9VFJVRSwgY29sb3I9InJlZCIpDQpyZXN1bHRzMyA8LSBzZWxlY3Rpb24odGltZSA9IGdlbi50aW1lLCBwMD1zdGFydC5mcmVxMywgdz1maXRuZXNzLCBhZGQ9VFJVRSwgY29sb3I9ImJsdWUiKQ0KYGBgDQoNCldoYXQgaGFwcGVucz8gQ2FuIHlvdSBleHBsYWluIHdoeT8NCg0KKkl0IGFwcGVhcnMgdGhhdCBzZWxlY3Rpb24gZGVwZW5kcyBhbG1vc3QgZW50aXJlbHkgb25seSB0aGUgc3RhcnRpbmcgZnJlcXVlbmN5IG9mIEFBIGluIHRoZSBwb3B1bGF0aW9uLiBXaGVuIHRoZXJlIGlzIGEgaGlnaCBzdGFydGluZyBmcmVxdWVuY3ksIGl0IHdpbGwgZW5kIHdpdGggYSBoaWdoLCBpZiB0aGVyZSBpcyBhIGxvdyBBQSBmcmVxdWVuY3ksIHRoZSBlbmQgd2lsbCBiZSBtb3N0bHkgYWxsIGFhLiBXaGVuIHRoZXJlIGlzIGEgbWVkaXVtIGFtb3VudCBvZiBBQSBpdCB3aWxsIHN0YXkgYXQgdGhhdCBtZWRpdW0gYW1vdW50IG9mIEFBLiBJJ20gbm90IGVudGlyZWx5IHN1cmUgd2h5IHRoaXMgd291bGQgb2NjdXIsIGJ1dCBJIHRoaW5rIGl0IGhhcyB0byBkbyB3aXRoIHRoZSBlcXVhbCBmaXRuZXNzZXMgZm9yIEFBIGFuZCBhYSwgc28gdGhlIHBvcHVsYXRpb24gd2lsbCBiZSBmaW5lIHdpdGggZWl0aGVyIGFsbGVsZS4qDQoNCiMjIDQuNi4gU2VsZWN0aW9uIEFnYWluc3QgSGV0ZXJvenlnb3RlczsgQXN5bW1ldHJpY2FsIEZpdG5lc3MgYmV0d2VlbiBIb21venlnb3Rlcw0KTm93IGNvbmR1Y3QgdGhlIHNhbWUgc2ltdWxhdGlvbiwgYnV0IHRoZSBob21venlnb3RlcyBoYXZlIGEgZGlmZmVyZW50IGZpdG5lc3MuIEFnYWluLCBydW4gdGhlIHNpbXVsYXRpb24gbXVsdGlwbGUgdGltZXMgd2l0aCBkaWZmZXJlbnQgcDAuIFlvdSBjYW4gYWxzbyBwbGF5IHdpdGggZGlmZmVyZW50IGZpdG5lc3MgZGlzdHJpYnV0aW9ucyB0byBvYnNlcnZlIGFkZGl0aW9uYWwgcGF0dGVybnMuIA0KDQpgYGB7cn0NCiNEZWZpbmUgdGhlIHBhcmFtZXRlcnMgYW5kIHNldCB1cCB0aGUgbW9kZWxzDQpmaXRuZXNzMT1jKDAuOSwwLjUsMC40KQ0KZml0bmVzczI9YygwLjUsMC41LDAuNDU2KQ0KZml0bmVzczM9YygwLjMsMC41LDAuMSkNCmdlbi50aW1lPTEwMA0Kc3RhcnQuZnJlcTE9MC45DQpzdGFydC5mcmVxMj0wLjUNCnN0YXJ0LmZyZXEzPTAuMQ0KcmVzdWx0czEgPC0gc2VsZWN0aW9uKHRpbWUgPSBnZW4udGltZSwgcDA9c3RhcnQuZnJlcTEsIHc9Zml0bmVzczEpDQpyZXN1bHRzMiA8LSBzZWxlY3Rpb24odGltZSA9IGdlbi50aW1lLCBwMD1zdGFydC5mcmVxMiwgdz1maXRuZXNzMiwgYWRkPVRSVUUsIGNvbG9yPSJyZWQiKQ0KcmVzdWx0czMgPC0gc2VsZWN0aW9uKHRpbWUgPSBnZW4udGltZSwgcDA9c3RhcnQuZnJlcTMsIHc9Zml0bmVzczMsIGFkZD1UUlVFLCBjb2xvcj0iYmx1ZSIpDQpgYGANCg0KV2hhdCBoYXBwZW5zPyBDYW4geW91IGV4cGxhaW4gd2h5Pw0KDQoqSXQgbG9va3MgbGlrZSB3aGF0ZXZlciBhbGxlbGUgaGFzIHRoZSBoaWdoZXIgZml0bmVzcyB3aWxsIGVuZCB1cCB3aXRoIGEgaGlnaGVyIGFtb3VudCBpbiB0aGUgcG9wdWxhdGlvbi4gVGhlIGhpZ2hlc3Qgc3RhcnRpbmcgYW1vdW50IG9mIHRoZSBhbGxlbGUgaW4gdGhlIHBvcHVsYXRpb24gc2VlbXMgdG8gZGV0ZXJtaW5lIGhvdyBtdWNoIG9mIHRoZSBhbGxlbGUgd2lsbCBiZSBpbiB0aGUgcG9wdWxhdGlvbiwgd2l0aCBhIGxvd2VyIGFtb3VudCB0byBzdGFydCByZXN1bHRzIGluIGEgbG93ZXIgZW5kIHBvcHVsYXRpb24gb2YgQUEgaW5kaXZpZHVhbHMuKg0KDQojIDUuIFJlZmxlY3Rpb24NCklmIHlvdSB0aGluayBiYWNrIHRvIHlvdXIgaW5pdGlhbCBwcmVkaWN0aW9uLCB3aGF0IGhhdmUgeW91IGxlYXJuZWQgZnJvbSBydW5uaW5nIGFsbCBvZiB0aGVzZSBtb2RlbHM/DQoNCipJIHdvdWxkIHNheSB0aGF0IEkgd2FzIHBhcnRpYWxseSBjb3JyZWN0LiBUaGUgaGlnaGVyIHRoZSBmaXRuZXNzLCB0aGUgbW9yZSBsaWtlbHkgdGhlIGVuZCByZXN1bHQgd2l0aCB3aWxsIGJlIG1vc3RseSB0aGUgYWxsZWxlIHdpdGggdGhlIHN0cm9uZ2VyIGZpdG5lc3MsIGJ1dCB0aGUgc3RhcnRpbmcgZnJlcXVlbmN5IGFsc28gcGxheXMgYSByb2xlIGluIHRoZSBlbmQgYW1vdW50IG9mIGFsbGVsZSBwZXJjZW50YWdlIGluIHRoZSBwb3B1bGF0aW9uLiBUaGUgbWVhbnMgdGhhdCBkZXNwaXRlIGEgcmVhbGx5IGhpZ2ggZml0bmVzcywgdGhlIHN0YXJ0aW5nIGZyZXF1ZW5jeSBsaW1pdHMganVzdCBob3cgaGlnaCB0aGUgZW5kIGFtb3VudCBvZiB0aGUgaGlnaCBmaXRuZXNzIGFsbGVsZSBjYW4gYmUuICoNCg0KIyA2LiBSZXNvdXJjZXMNCiMjIDYuMS4gRGF0YSBSZWZlcmVuY2VzDQpUaGlzIGV4ZXJjaXNlIGRvZXMgbm90IGNvbnRhaW4gb3JpZ2luYWwgZGF0YS4NCg0KIyMgNi4yLiBSZXNvdXJjZXMgWW91IENvbnN1bHRlZA0KQ29uc3VsdGluZyBhZGRpdGlvbmFsIHJlc291cmNlcyB0byBzb2x2ZSB0aGlzIGFzc2lnbm1lbnQgaXMgYWJzb2x1dGVseSBhbGxvd2VkLCBidXQgZmFpbHVyZSB0byBkaXNjbG9zZSB0aG9zZSByZXNvdXJjZXMgaXMgcGxhZ2lhcmlzbS4gUGxlYXNlIGxpc3QgYW55IGNvbGxhYm9yYXRvcnMgeW91IHdvcmtlZCB3aXRoIGFuZCByZXNvdXJjZXMgeW91IHVzZWQgYmVsb3cgb3Igc3RhdGUgdGhhdCB5b3UgaGF2ZSBub3QgdXNlZCBhbnkuDQoNCipJIHJlY2VpdmVkIGhlbHAgZnJvbSB0aGUgZGlzY3Vzc2lvbiBwb3N0IGZvciB0aGUgYXNzaWdubWVudC4qDQo=