This document will show how to simulate polyploids in AlphaSimR and
demonstrate several behaviors that are unique to polyploids.
Simulating polyploids
This script shows how to create polyploids with runMacs
and how to set the probability of quadrivalent pairing.
library(AlphaSimR)
Loading required package: R6
# Changing ploidy argument in runMacs
founderPop = runMacs(nInd=100, nChr=10, segSites=1000,
ploidy=4)
founderPop
An object of class "MapPop"
Ploidy: 4
Individuals: 100
Chromosomes: 10
Loci: 10000
SP = SimParam$
new(founderPop)$
addTraitAD(1000, meanDD=0.2, varDD=0.1)$
setVarE(H2=1)
# Variable for probability of quadrivalent pairing
SP$quadProb
[1] 0
pop = newPop(founderPop)
head(
pullMarkerGeno(pop,
markers=c("1_1", "2_1", "3_1",
"4_1", "5_1", "6_1")),
n=8
)
1_1 2_1 3_1 4_1 5_1 6_1
1 2 2 3 0 1 4
2 1 0 3 1 0 4
3 2 2 4 1 1 4
4 3 2 3 1 1 4
5 4 1 3 1 1 4
6 0 1 1 1 0 4
7 2 0 4 1 0 2
8 3 0 2 0 1 4
head(
pullMarkerHaplo(pop,
markers=c("1_1", "2_1", "3_1",
"4_1", "5_1", "6_1")),
n=8
)
1_1 2_1 3_1 4_1 5_1 6_1
1_1 0 1 0 0 0 1
1_2 1 0 1 0 1 1
1_3 0 1 1 0 0 1
1_4 1 0 1 0 0 1
2_1 1 0 1 0 0 1
2_2 0 0 0 0 0 1
2_3 0 0 1 1 0 1
2_4 0 0 1 0 0 1
Double reductions
Double reductions result in two copies of a chromosome segment being
passed to a gamete. This behavior can only occur in multivalent paring.
This script will indirectly show the presence of double reductions by
tracking inbreeding depression.
# Create variable to track population means
muA = muB = numeric(31)
A = B = pop
# Bivalent pairing only
SP$quadProb = 0
muA[1] = meanG(A)
for(i in 2:31){
A = self(A)
muA[i] = meanG(A)
}
# Quadrivalent pairing only
SP$quadProb = 1
muB[1] = meanG(B)
for(i in 2:31){
B = self(B)
muB[i] = meanG(B)
}
plot(0:30, muA, type="l",
ylab="Mean", xlab="Selfing Generation")
lines(0:30, muB, col="red")

NA
NA
Contribution of digenic dominance to response to selection
The digenic dominance in polyploids behaves similarly to
additive-by-additive genetic variance with respect to response to
selection. This will be demonstrated in the below script.
founderPop = quickHaplo(nInd=1000, nChr=10,
segSites=1000, ploidy=4)
SP = SimParam$
new(founderPop)$
addTraitAD(1000, varDD=2)$
setVarE(H2=1)
pop = newPop(founderPop)
varA(pop)
Trait1
Trait1 1
varD(pop)
Trait1
Trait1 0.7382906
pop2 = selectCross(pop, nInd=100, nCrosses=1000)
# Observed response to selection
meanG(pop2) - meanG(pop)
Trait1
1.612925
# Expected response without digenic dominance
selInt(p=0.1) * varA(pop) / sqrt(varP(pop))
Trait1
Trait1 1.335775
# Expected response with digenic dominance in an unselected population
selInt(p=0.1) * (varA(pop) + (1/3)*varD(pop)) / sqrt(varP(pop))
Trait1
Trait1 1.664505
# Repeat measurement after multiple rounds of selecton
for(i in 1:10){
pop = selectCross(pop, nInd=100, nCrosses=1000)
}
pop2 = selectCross(pop, nInd=100, nCrosses=1000)
# Observed response to selection
meanG(pop2) - meanG(pop)
Trait1
1.220221
# Expected response without digenic dominance
selInt(p=0.1) * varA(pop) / sqrt(varP(pop))
Trait1
Trait1 1.305264
# Expected response with digenic dominance in an unselected population
selInt(p=0.1) * (varA(pop) + (1/3)*varD(pop)) / sqrt(varP(pop))
Trait1
Trait1 1.668836
Progressive heterosis
The below script will demonstrate the occurrence of progressive
heterosis in tetraploids and its absence in diploids. This script comes
from the AlphaSimR_Examples GitHub repository. It uses 100 replications,
because progressive heterosis is not as reliably present as many of the
other properties that have been presented.
het2sc = het4sc = het2dc = het4dc = numeric(100)
for(REP in 1:100){
founderPop = quickHaplo(nInd=400, nChr=4, segSites=100, ploidy=4)
SP = SimParam$
new(founderPop)$
addTraitAD(100, meanDD=0.6, varDD=0.2)$
setVarE(h2=0.3)
# Create 4 tetraploid populations
tetraploid = vector("list", 4)
tetraploid[[1]] = newPop(founderPop[1:100])
tetraploid[[2]] = newPop(founderPop[101:200])
tetraploid[[3]] = newPop(founderPop[201:300])
tetraploid[[4]] = newPop(founderPop[301:400])
# Create diploid populations from tetraploid populations
diploid = vector("list", 4)
for(i in 1:4){
diploid[[i]] = reduceGenome(tetraploid[[i]])
}
# Perform 5 generations of recurrent selection
for(gen in 1:5){
for(i in 1:4){
tetraploid[[i]] = selectCross(tetraploid[[i]], nInd=10, nCrosses=100)
diploid[[i]] = selectCross(diploid[[i]], nInd=10, nCrosses=100)
}
}
# Create single cross populations (1/2 and 3/4)
tetraSC = list(randCross2(tetraploid[[1]], tetraploid[[2]], nCrosses=100),
randCross2(tetraploid[[3]], tetraploid[[4]], nCrosses=100))
diploidSC = list(randCross2(diploid[[1]], diploid[[2]], nCrosses=100),
randCross2(diploid[[3]], diploid[[4]], nCrosses=100))
# Create double cross populations
tetraDouble = randCross2(tetraSC[[1]], tetraSC[[2]], nCrosses=1000)
diploidDouble = randCross2(diploidSC[[1]], diploidSC[[2]], nCrosses=1000)
# Calculate mean of all base populations
meanTetra = mean(unlist(lapply(tetraploid,meanG)))
meanDiploid = mean(unlist(lapply(diploid,meanG)))
# Calculate mean of single cross populations
meanTetraSC = mean(unlist(lapply(tetraSC,meanG)))
meanDiploidSC = mean(unlist(lapply(diploidSC,meanG)))
# Measure single cross heterosis
het4sc[REP] = meanTetraSC - meanTetra
het2sc[REP] = meanDiploidSC - meanDiploid
# Measure double cross heterois
het4dc[REP] = meanG(tetraDouble) - meanTetra
het2dc[REP] = meanG(diploidDouble) - meanDiploid
}
Registered S3 methods overwritten by 'htmltools':
method from
print.html tools:rstudio
print.shiny.tag tools:rstudio
print.shiny.tag.list tools:rstudio
boxplot(het2dc,het2sc,het4dc,het4sc,
names=c("Diploid D", "Diploid S",
"Tetraploid D", "Tetraploid S"),
las=2,
main="Single (S) vs Double (D) Cross Means")

boxplot(het2dc-het2sc,het4dc-het4sc,
names=c("Diploid", "Tetraploid"),
las=2,
main="Progressive Heterosis")

Other polyploid behaviors
founderPop = quickHaplo(nInd=100, nChr=10,
segSites=1000)
SP = SimParam$
new(founderPop)$
addTraitAD(1000, meanDD=0.6)
diploid = newPop(founderPop)
# Create tetraploids from diploids
tetraploid = doubleGenome(diploid)
tetraploid2 = randCross(tetraploid, 1000)
# Polyploids produced by doubling are partially inbred (not HWE)
meanG(tetraploid2) - meanG(tetraploid)
Trait1
13.19257
# You can cross different ploidy levels
triploid = randCross2(diploid, tetraploid, 1000)
# Odd ploidy levels are dead ends
LS0tDQp0aXRsZTogIlF1YW50aXRhdGl2ZSBHZW5ldGljczogUG9seXBsb2lkcyINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KLS0tDQoNClRoaXMgZG9jdW1lbnQgd2lsbCBzaG93IGhvdyB0byBzaW11bGF0ZSBwb2x5cGxvaWRzIGluIEFscGhhU2ltUiBhbmQgZGVtb25zdHJhdGUgc2V2ZXJhbCBiZWhhdmlvcnMgdGhhdCBhcmUgdW5pcXVlIHRvIHBvbHlwbG9pZHMuDQoNCiMjIFNpbXVsYXRpbmcgcG9seXBsb2lkcw0KDQpUaGlzIHNjcmlwdCBzaG93cyBob3cgdG8gY3JlYXRlIHBvbHlwbG9pZHMgd2l0aCBgcnVuTWFjc2AgYW5kIGhvdyB0byBzZXQgdGhlIHByb2JhYmlsaXR5IG9mIHF1YWRyaXZhbGVudCBwYWlyaW5nLg0KDQpgYGB7cn0NCmxpYnJhcnkoQWxwaGFTaW1SKQ0KDQojIENoYW5naW5nIHBsb2lkeSBhcmd1bWVudCBpbiBydW5NYWNzDQpmb3VuZGVyUG9wID0gcnVuTWFjcyhuSW5kPTEwMCwgbkNocj0xMCwgc2VnU2l0ZXM9MTAwMCwgDQogICAgICAgICAgICAgICAgICAgICBwbG9pZHk9NCkNCg0KZm91bmRlclBvcA0KDQpTUCA9IFNpbVBhcmFtJA0KICBuZXcoZm91bmRlclBvcCkkDQogIGFkZFRyYWl0QUQoMTAwMCwgbWVhbkREPTAuMiwgdmFyREQ9MC4xKSQNCiAgc2V0VmFyRShIMj0xKQ0KDQojIFZhcmlhYmxlIGZvciBwcm9iYWJpbGl0eSBvZiBxdWFkcml2YWxlbnQgcGFpcmluZw0KU1AkcXVhZFByb2INCg0KcG9wID0gbmV3UG9wKGZvdW5kZXJQb3ApDQoNCmhlYWQoDQogIHB1bGxNYXJrZXJHZW5vKHBvcCwgDQogICAgICAgICAgICAgICAgIG1hcmtlcnM9YygiMV8xIiwgIjJfMSIsICIzXzEiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICI0XzEiLCAiNV8xIiwgIjZfMSIpKSwNCiAgbj04DQogICkNCg0KaGVhZCgNCiAgcHVsbE1hcmtlckhhcGxvKHBvcCwgDQogICAgICAgICAgICAgICAgICBtYXJrZXJzPWMoIjFfMSIsICIyXzEiLCAiM18xIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIjRfMSIsICI1XzEiLCAiNl8xIikpLA0KICBuPTgNCikNCmBgYA0KDQoNCiMjIERvdWJsZSByZWR1Y3Rpb25zDQoNCkRvdWJsZSByZWR1Y3Rpb25zIHJlc3VsdCBpbiB0d28gY29waWVzIG9mIGEgY2hyb21vc29tZSBzZWdtZW50IGJlaW5nIHBhc3NlZCB0byBhIGdhbWV0ZS4gVGhpcyBiZWhhdmlvciBjYW4gb25seSBvY2N1ciBpbiBtdWx0aXZhbGVudCBwYXJpbmcuIFRoaXMgc2NyaXB0IHdpbGwgaW5kaXJlY3RseSBzaG93IHRoZSBwcmVzZW5jZSBvZiBkb3VibGUgcmVkdWN0aW9ucyBieSB0cmFja2luZyBpbmJyZWVkaW5nIGRlcHJlc3Npb24uDQoNCmBgYHtyfQ0KIyBDcmVhdGUgdmFyaWFibGUgdG8gdHJhY2sgcG9wdWxhdGlvbiBtZWFucw0KbXVBID0gbXVCID0gbnVtZXJpYygzMSkNCkEgPSBCID0gcG9wDQoNCiMgQml2YWxlbnQgcGFpcmluZyBvbmx5DQpTUCRxdWFkUHJvYiA9IDANCg0KbXVBWzFdID0gbWVhbkcoQSkNCg0KZm9yKGkgaW4gMjozMSl7DQogIEEgPSBzZWxmKEEpDQogIG11QVtpXSA9IG1lYW5HKEEpDQp9DQoNCiMgUXVhZHJpdmFsZW50IHBhaXJpbmcgb25seQ0KU1AkcXVhZFByb2IgPSAxDQoNCm11QlsxXSA9IG1lYW5HKEIpDQoNCmZvcihpIGluIDI6MzEpew0KICBCID0gc2VsZihCKQ0KICBtdUJbaV0gPSBtZWFuRyhCKQ0KfQ0KDQpwbG90KDA6MzAsIG11QSwgdHlwZT0ibCIsIA0KICAgICB5bGFiPSJNZWFuIiwgeGxhYj0iU2VsZmluZyBHZW5lcmF0aW9uIikNCmxpbmVzKDA6MzAsIG11QiwgY29sPSJyZWQiKQ0KDQoNCmBgYA0KDQojIyBDb250cmlidXRpb24gb2YgZGlnZW5pYyBkb21pbmFuY2UgdG8gcmVzcG9uc2UgdG8gc2VsZWN0aW9uDQoNClRoZSBkaWdlbmljIGRvbWluYW5jZSBpbiBwb2x5cGxvaWRzIGJlaGF2ZXMgc2ltaWxhcmx5IHRvIGFkZGl0aXZlLWJ5LWFkZGl0aXZlIGdlbmV0aWMgdmFyaWFuY2Ugd2l0aCByZXNwZWN0IHRvIHJlc3BvbnNlIHRvIHNlbGVjdGlvbi4gVGhpcyB3aWxsIGJlIGRlbW9uc3RyYXRlZCBpbiB0aGUgYmVsb3cgc2NyaXB0Lg0KDQpgYGB7cn0NCmZvdW5kZXJQb3AgPSBxdWlja0hhcGxvKG5JbmQ9MTAwMCwgbkNocj0xMCwgDQogICAgICAgICAgICAgICAgICAgICAgICBzZWdTaXRlcz0xMDAwLCBwbG9pZHk9NCkNCg0KU1AgPSBTaW1QYXJhbSQNCiAgbmV3KGZvdW5kZXJQb3ApJA0KICBhZGRUcmFpdEFEKDEwMDAsIHZhckREPTIpJA0KICBzZXRWYXJFKEgyPTEpDQoNCnBvcCA9IG5ld1BvcChmb3VuZGVyUG9wKQ0KDQp2YXJBKHBvcCkNCnZhckQocG9wKQ0KDQpwb3AyID0gc2VsZWN0Q3Jvc3MocG9wLCBuSW5kPTEwMCwgbkNyb3NzZXM9MTAwMCkNCg0KIyBPYnNlcnZlZCByZXNwb25zZSB0byBzZWxlY3Rpb24NCm1lYW5HKHBvcDIpIC0gbWVhbkcocG9wKQ0KDQojIEV4cGVjdGVkIHJlc3BvbnNlIHdpdGhvdXQgZGlnZW5pYyBkb21pbmFuY2UNCnNlbEludChwPTAuMSkgKiB2YXJBKHBvcCkgLyBzcXJ0KHZhclAocG9wKSkNCg0KIyBFeHBlY3RlZCByZXNwb25zZSB3aXRoIGRpZ2VuaWMgZG9taW5hbmNlIGluIGFuIHVuc2VsZWN0ZWQgcG9wdWxhdGlvbg0Kc2VsSW50KHA9MC4xKSAqICh2YXJBKHBvcCkgKyAoMS8zKSp2YXJEKHBvcCkpIC8gc3FydCh2YXJQKHBvcCkpDQoNCiMgUmVwZWF0IG1lYXN1cmVtZW50IGFmdGVyIG11bHRpcGxlIHJvdW5kcyBvZiBzZWxlY3Rvbg0KZm9yKGkgaW4gMToxMCl7DQogIHBvcCA9IHNlbGVjdENyb3NzKHBvcCwgbkluZD0xMDAsIG5Dcm9zc2VzPTEwMDApDQp9DQoNCnBvcDIgPSBzZWxlY3RDcm9zcyhwb3AsIG5JbmQ9MTAwLCBuQ3Jvc3Nlcz0xMDAwKQ0KDQojIE9ic2VydmVkIHJlc3BvbnNlIHRvIHNlbGVjdGlvbg0KbWVhbkcocG9wMikgLSBtZWFuRyhwb3ApDQoNCiMgRXhwZWN0ZWQgcmVzcG9uc2Ugd2l0aG91dCBkaWdlbmljIGRvbWluYW5jZQ0Kc2VsSW50KHA9MC4xKSAqIHZhckEocG9wKSAvIHNxcnQodmFyUChwb3ApKQ0KDQojIEV4cGVjdGVkIHJlc3BvbnNlIHdpdGggZGlnZW5pYyBkb21pbmFuY2UgaW4gYW4gdW5zZWxlY3RlZCBwb3B1bGF0aW9uDQpzZWxJbnQocD0wLjEpICogKHZhckEocG9wKSArICgxLzMpKnZhckQocG9wKSkgLyBzcXJ0KHZhclAocG9wKSkNCg0KYGBgDQoNCiMjIFByb2dyZXNzaXZlIGhldGVyb3Npcw0KDQpUaGUgYmVsb3cgc2NyaXB0IHdpbGwgZGVtb25zdHJhdGUgdGhlIG9jY3VycmVuY2Ugb2YgcHJvZ3Jlc3NpdmUgaGV0ZXJvc2lzIGluIHRldHJhcGxvaWRzIGFuZCBpdHMgYWJzZW5jZSBpbiBkaXBsb2lkcy4gVGhpcyBzY3JpcHQgY29tZXMgZnJvbSB0aGUgQWxwaGFTaW1SX0V4YW1wbGVzIEdpdEh1YiByZXBvc2l0b3J5LiBJdCB1c2VzIDEwMCByZXBsaWNhdGlvbnMsIGJlY2F1c2UgcHJvZ3Jlc3NpdmUgaGV0ZXJvc2lzIGlzIG5vdCBhcyByZWxpYWJseSBwcmVzZW50IGFzIG1hbnkgb2YgdGhlIG90aGVyIHByb3BlcnRpZXMgdGhhdCBoYXZlIGJlZW4gcHJlc2VudGVkLg0KDQpgYGB7cn0NCmhldDJzYyA9IGhldDRzYyA9IGhldDJkYyA9IGhldDRkYyA9IG51bWVyaWMoMTAwKQ0KZm9yKFJFUCBpbiAxOjEwMCl7DQogIGZvdW5kZXJQb3AgPSBxdWlja0hhcGxvKG5JbmQ9NDAwLCBuQ2hyPTQsIHNlZ1NpdGVzPTEwMCwgcGxvaWR5PTQpDQogIA0KICBTUCA9IFNpbVBhcmFtJA0KICAgIG5ldyhmb3VuZGVyUG9wKSQNCiAgICBhZGRUcmFpdEFEKDEwMCwgbWVhbkREPTAuNiwgdmFyREQ9MC4yKSQNCiAgICBzZXRWYXJFKGgyPTAuMykNCiAgDQogICMgQ3JlYXRlIDQgdGV0cmFwbG9pZCBwb3B1bGF0aW9ucw0KICB0ZXRyYXBsb2lkID0gdmVjdG9yKCJsaXN0IiwgNCkNCiAgdGV0cmFwbG9pZFtbMV1dID0gbmV3UG9wKGZvdW5kZXJQb3BbMToxMDBdKQ0KICB0ZXRyYXBsb2lkW1syXV0gPSBuZXdQb3AoZm91bmRlclBvcFsxMDE6MjAwXSkNCiAgdGV0cmFwbG9pZFtbM11dID0gbmV3UG9wKGZvdW5kZXJQb3BbMjAxOjMwMF0pDQogIHRldHJhcGxvaWRbWzRdXSA9IG5ld1BvcChmb3VuZGVyUG9wWzMwMTo0MDBdKQ0KICANCiAgIyBDcmVhdGUgZGlwbG9pZCBwb3B1bGF0aW9ucyBmcm9tIHRldHJhcGxvaWQgcG9wdWxhdGlvbnMNCiAgZGlwbG9pZCA9IHZlY3RvcigibGlzdCIsIDQpDQogIGZvcihpIGluIDE6NCl7DQogICAgZGlwbG9pZFtbaV1dID0gcmVkdWNlR2Vub21lKHRldHJhcGxvaWRbW2ldXSkNCiAgfQ0KICANCiAgIyBQZXJmb3JtIDUgZ2VuZXJhdGlvbnMgb2YgcmVjdXJyZW50IHNlbGVjdGlvbg0KICBmb3IoZ2VuIGluIDE6NSl7IA0KICAgIGZvcihpIGluIDE6NCl7DQogICAgICB0ZXRyYXBsb2lkW1tpXV0gPSBzZWxlY3RDcm9zcyh0ZXRyYXBsb2lkW1tpXV0sIG5JbmQ9MTAsIG5Dcm9zc2VzPTEwMCkNCiAgICAgIGRpcGxvaWRbW2ldXSA9IHNlbGVjdENyb3NzKGRpcGxvaWRbW2ldXSwgbkluZD0xMCwgbkNyb3NzZXM9MTAwKQ0KICAgIH0NCiAgfQ0KICANCiAgIyBDcmVhdGUgc2luZ2xlIGNyb3NzIHBvcHVsYXRpb25zICgxLzIgYW5kIDMvNCkNCiAgdGV0cmFTQyA9IGxpc3QocmFuZENyb3NzMih0ZXRyYXBsb2lkW1sxXV0sIHRldHJhcGxvaWRbWzJdXSwgbkNyb3NzZXM9MTAwKSwNCiAgICAgICAgICAgICAgICAgcmFuZENyb3NzMih0ZXRyYXBsb2lkW1szXV0sIHRldHJhcGxvaWRbWzRdXSwgbkNyb3NzZXM9MTAwKSkNCiAgZGlwbG9pZFNDID0gbGlzdChyYW5kQ3Jvc3MyKGRpcGxvaWRbWzFdXSwgZGlwbG9pZFtbMl1dLCBuQ3Jvc3Nlcz0xMDApLA0KICAgICAgICAgICAgICAgICAgIHJhbmRDcm9zczIoZGlwbG9pZFtbM11dLCBkaXBsb2lkW1s0XV0sIG5Dcm9zc2VzPTEwMCkpDQogIA0KICAjIENyZWF0ZSBkb3VibGUgY3Jvc3MgcG9wdWxhdGlvbnMNCiAgdGV0cmFEb3VibGUgPSByYW5kQ3Jvc3MyKHRldHJhU0NbWzFdXSwgdGV0cmFTQ1tbMl1dLCBuQ3Jvc3Nlcz0xMDAwKQ0KICBkaXBsb2lkRG91YmxlID0gcmFuZENyb3NzMihkaXBsb2lkU0NbWzFdXSwgZGlwbG9pZFNDW1syXV0sIG5Dcm9zc2VzPTEwMDApDQogIA0KICAjIENhbGN1bGF0ZSBtZWFuIG9mIGFsbCBiYXNlIHBvcHVsYXRpb25zDQogIG1lYW5UZXRyYSA9IG1lYW4odW5saXN0KGxhcHBseSh0ZXRyYXBsb2lkLG1lYW5HKSkpDQogIG1lYW5EaXBsb2lkID0gbWVhbih1bmxpc3QobGFwcGx5KGRpcGxvaWQsbWVhbkcpKSkNCiAgDQogICMgQ2FsY3VsYXRlIG1lYW4gb2Ygc2luZ2xlIGNyb3NzIHBvcHVsYXRpb25zDQogIG1lYW5UZXRyYVNDID0gbWVhbih1bmxpc3QobGFwcGx5KHRldHJhU0MsbWVhbkcpKSkNCiAgbWVhbkRpcGxvaWRTQyA9IG1lYW4odW5saXN0KGxhcHBseShkaXBsb2lkU0MsbWVhbkcpKSkNCiAgDQogICMgTWVhc3VyZSBzaW5nbGUgY3Jvc3MgaGV0ZXJvc2lzDQogIGhldDRzY1tSRVBdID0gbWVhblRldHJhU0MgLSBtZWFuVGV0cmENCiAgaGV0MnNjW1JFUF0gPSBtZWFuRGlwbG9pZFNDIC0gbWVhbkRpcGxvaWQNCiAgDQogICMgTWVhc3VyZSBkb3VibGUgY3Jvc3MgaGV0ZXJvaXMNCiAgaGV0NGRjW1JFUF0gPSBtZWFuRyh0ZXRyYURvdWJsZSkgLSBtZWFuVGV0cmEgDQogIGhldDJkY1tSRVBdID0gbWVhbkcoZGlwbG9pZERvdWJsZSkgLSBtZWFuRGlwbG9pZCANCn0NCmJveHBsb3QoaGV0MmRjLGhldDJzYyxoZXQ0ZGMsaGV0NHNjLCANCiAgICAgICAgbmFtZXM9YygiRGlwbG9pZCBEIiwgIkRpcGxvaWQgUyIsDQogICAgICAgICAgICAgICAgIlRldHJhcGxvaWQgRCIsICJUZXRyYXBsb2lkIFMiKSwNCiAgICAgICAgbGFzPTIsDQogICAgICAgIG1haW49IlNpbmdsZSAoUykgdnMgRG91YmxlIChEKSBDcm9zcyBNZWFucyIpDQpib3hwbG90KGhldDJkYy1oZXQyc2MsaGV0NGRjLWhldDRzYywgDQogICAgICAgIG5hbWVzPWMoIkRpcGxvaWQiLCAiVGV0cmFwbG9pZCIpLA0KICAgICAgICBsYXM9MiwNCiAgICAgICAgbWFpbj0iUHJvZ3Jlc3NpdmUgSGV0ZXJvc2lzIikNCg0KYGBgDQoNCiMjIE90aGVyIHBvbHlwbG9pZCBiZWhhdmlvcnMNCg0KYGBge3J9DQpmb3VuZGVyUG9wID0gcXVpY2tIYXBsbyhuSW5kPTEwMCwgbkNocj0xMCwgDQogICAgICAgICAgICAgICAgICAgICAgICBzZWdTaXRlcz0xMDAwKQ0KDQpTUCA9IFNpbVBhcmFtJA0KICBuZXcoZm91bmRlclBvcCkkDQogIGFkZFRyYWl0QUQoMTAwMCwgbWVhbkREPTAuNikNCg0KZGlwbG9pZCA9IG5ld1BvcChmb3VuZGVyUG9wKQ0KDQojIENyZWF0ZSB0ZXRyYXBsb2lkcyBmcm9tIGRpcGxvaWRzDQp0ZXRyYXBsb2lkID0gZG91YmxlR2Vub21lKGRpcGxvaWQpDQp0ZXRyYXBsb2lkMiA9IHJhbmRDcm9zcyh0ZXRyYXBsb2lkLCAxMDAwKQ0KDQojIFBvbHlwbG9pZHMgcHJvZHVjZWQgYnkgZG91YmxpbmcgYXJlIHBhcnRpYWxseSBpbmJyZWQgKG5vdCBIV0UpDQptZWFuRyh0ZXRyYXBsb2lkMikgLSBtZWFuRyh0ZXRyYXBsb2lkKQ0KDQojIFlvdSBjYW4gY3Jvc3MgZGlmZmVyZW50IHBsb2lkeSBsZXZlbHMNCnRyaXBsb2lkID0gcmFuZENyb3NzMihkaXBsb2lkLCB0ZXRyYXBsb2lkLCAxMDAwKQ0KDQojIE9kZCBwbG9pZHkgbGV2ZWxzIGFyZSBkZWFkIGVuZHMNCmBgYA0KDQo=