Merge branch 'master' of ssh://gsa1.broadinstitute.org/humgen/gsa-scr1/gsa-engineering/git/unstable
This commit is contained in:
commit
ed34b4f088
|
|
@ -186,17 +186,21 @@ public class ReadUtils {
|
||||||
* @return the reference coordinate for the adaptor boundary (effectively the first base IN the adaptor, closest to the read. NULL if the read is unmapped or the mate is mapped to another contig.
|
* @return the reference coordinate for the adaptor boundary (effectively the first base IN the adaptor, closest to the read. NULL if the read is unmapped or the mate is mapped to another contig.
|
||||||
*/
|
*/
|
||||||
public static Integer getAdaptorBoundary(final SAMRecord read) {
|
public static Integer getAdaptorBoundary(final SAMRecord read) {
|
||||||
|
final int MAXIMUM_ADAPTOR_LENGTH = 8;
|
||||||
final int insertSize = Math.abs(read.getInferredInsertSize()); // the inferred insert size can be negative if the mate is mapped before the read (so we take the absolute value)
|
final int insertSize = Math.abs(read.getInferredInsertSize()); // the inferred insert size can be negative if the mate is mapped before the read (so we take the absolute value)
|
||||||
|
|
||||||
if (insertSize == 0 || read.getReadUnmappedFlag()) // no adaptors in reads with mates in another
|
if (insertSize == 0 || read.getReadUnmappedFlag()) // no adaptors in reads with mates in another chromosome or unmapped pairs
|
||||||
return null; // chromosome or unmapped pairs
|
return null;
|
||||||
|
|
||||||
int adaptorBoundary; // the reference coordinate for the adaptor boundary (effectively the first base IN the adaptor, closest to the read)
|
Integer adaptorBoundary; // the reference coordinate for the adaptor boundary (effectively the first base IN the adaptor, closest to the read)
|
||||||
if (read.getReadNegativeStrandFlag())
|
if (read.getReadNegativeStrandFlag())
|
||||||
adaptorBoundary = read.getMateAlignmentStart() - 1; // case 1 (see header)
|
adaptorBoundary = read.getMateAlignmentStart() - 1; // case 1 (see header)
|
||||||
else
|
else
|
||||||
adaptorBoundary = read.getAlignmentStart() + insertSize + 1; // case 2 (see header)
|
adaptorBoundary = read.getAlignmentStart() + insertSize + 1; // case 2 (see header)
|
||||||
|
|
||||||
|
if ( (adaptorBoundary < read.getAlignmentStart() - MAXIMUM_ADAPTOR_LENGTH) || (adaptorBoundary > read.getAlignmentEnd() + MAXIMUM_ADAPTOR_LENGTH) )
|
||||||
|
adaptorBoundary = null; // we are being conservative by not allowing the adaptor boundary to go beyond what we belive is the maximum size of an adaptor
|
||||||
|
|
||||||
return adaptorBoundary;
|
return adaptorBoundary;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ public class VariantAnnotatorIntegrationTest extends WalkerTest {
|
||||||
public void testHasAnnotsAsking1() {
|
public void testHasAnnotsAsking1() {
|
||||||
WalkerTestSpec spec = new WalkerTestSpec(
|
WalkerTestSpec spec = new WalkerTestSpec(
|
||||||
baseTestString() + " -G Standard --variant:VCF3 " + validationDataLocation + "vcfexample2.vcf -I " + validationDataLocation + "low_coverage_CEU.chr1.10k-11k.bam -L 1:10,020,000-10,021,000", 1,
|
baseTestString() + " -G Standard --variant:VCF3 " + validationDataLocation + "vcfexample2.vcf -I " + validationDataLocation + "low_coverage_CEU.chr1.10k-11k.bam -L 1:10,020,000-10,021,000", 1,
|
||||||
Arrays.asList("e70eb5f80c93e366dcbe3cf684c154e4"));
|
Arrays.asList("604328867fc9aaf3e71fa0f9ca2ba5c9"));
|
||||||
executeTest("test file has annotations, asking for annotations, #1", spec);
|
executeTest("test file has annotations, asking for annotations, #1", spec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -66,7 +66,7 @@ public class VariantAnnotatorIntegrationTest extends WalkerTest {
|
||||||
public void testNoAnnotsAsking1() {
|
public void testNoAnnotsAsking1() {
|
||||||
WalkerTestSpec spec = new WalkerTestSpec(
|
WalkerTestSpec spec = new WalkerTestSpec(
|
||||||
baseTestString() + " -G Standard --variant:VCF3 " + validationDataLocation + "vcfexample2empty.vcf -I " + validationDataLocation + "low_coverage_CEU.chr1.10k-11k.bam -L 1:10,020,000-10,021,000", 1,
|
baseTestString() + " -G Standard --variant:VCF3 " + validationDataLocation + "vcfexample2empty.vcf -I " + validationDataLocation + "low_coverage_CEU.chr1.10k-11k.bam -L 1:10,020,000-10,021,000", 1,
|
||||||
Arrays.asList("1e52761fdff73a5361b5eb0a6e5d9dad"));
|
Arrays.asList("bbde8c92d27ad2a7ec1ff2d095d459eb"));
|
||||||
executeTest("test file doesn't have annotations, asking for annotations, #1", spec);
|
executeTest("test file doesn't have annotations, asking for annotations, #1", spec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -82,7 +82,7 @@ public class VariantAnnotatorIntegrationTest extends WalkerTest {
|
||||||
public void testExcludeAnnotations() {
|
public void testExcludeAnnotations() {
|
||||||
WalkerTestSpec spec = new WalkerTestSpec(
|
WalkerTestSpec spec = new WalkerTestSpec(
|
||||||
baseTestString() + " -G Standard -XA FisherStrand -XA ReadPosRankSumTest --variant:VCF3 " + validationDataLocation + "vcfexample2empty.vcf -I " + validationDataLocation + "low_coverage_CEU.chr1.10k-11k.bam -L 1:10,020,000-10,021,000", 1,
|
baseTestString() + " -G Standard -XA FisherStrand -XA ReadPosRankSumTest --variant:VCF3 " + validationDataLocation + "vcfexample2empty.vcf -I " + validationDataLocation + "low_coverage_CEU.chr1.10k-11k.bam -L 1:10,020,000-10,021,000", 1,
|
||||||
Arrays.asList("bb4eebfaffc230cb8a31e62e7b53a300"));
|
Arrays.asList("8ec9f79cab84f26d8250f00d99d18aac"));
|
||||||
executeTest("test exclude annotations", spec);
|
executeTest("test exclude annotations", spec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ public class CallableLociWalkerIntegrationTest extends WalkerTest {
|
||||||
public void testCallableLociWalker3() {
|
public void testCallableLociWalker3() {
|
||||||
String gatk_args = commonArgs + " -format BED -L 1:10,000,000-11,000,000 -minDepth 10 -maxDepth 100 --minBaseQuality 10 --minMappingQuality 20 -summary %s";
|
String gatk_args = commonArgs + " -format BED -L 1:10,000,000-11,000,000 -minDepth 10 -maxDepth 100 --minBaseQuality 10 --minMappingQuality 20 -summary %s";
|
||||||
WalkerTestSpec spec = new WalkerTestSpec(gatk_args, 2,
|
WalkerTestSpec spec = new WalkerTestSpec(gatk_args, 2,
|
||||||
Arrays.asList("4496551d4493857e5153d8172965e527", "b0667e31af9aec02eaf73ca73ec16937"));
|
Arrays.asList("b7d26a470ef906590249f2fa45fd6bdd", "da431d393f7c2b2b3e27556b86c1dbc7"));
|
||||||
executeTest("formatBed lots of arguments", spec);
|
executeTest("formatBed lots of arguments", spec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -55,25 +55,25 @@ public class DepthOfCoverageIntegrationTest extends WalkerTest {
|
||||||
spec.setOutputFileLocation(baseOutputFile);
|
spec.setOutputFileLocation(baseOutputFile);
|
||||||
|
|
||||||
// now add the expected files that get generated
|
// now add the expected files that get generated
|
||||||
spec.addAuxFile("2f072fd8b41b5ac1108797f89376c797", baseOutputFile);
|
spec.addAuxFile("0f9603eb1ca4a26828e82d8c8f4991f6", baseOutputFile);
|
||||||
spec.addAuxFile("d17ac7cc0b58ba801d2b0727a363d615", createTempFileFromBase(baseOutputFile.getAbsolutePath()+".library_cumulative_coverage_counts"));
|
spec.addAuxFile("51e6c09a307654f43811af35238fb179", createTempFileFromBase(baseOutputFile.getAbsolutePath()+".library_cumulative_coverage_counts"));
|
||||||
spec.addAuxFile("c05190c9e6239cdb1cd486edcbc23505", createTempFileFromBase(baseOutputFile.getAbsolutePath()+".library_cumulative_coverage_proportions"));
|
spec.addAuxFile("229b9b5bc2141c86dbc69c8acc9eba6a", createTempFileFromBase(baseOutputFile.getAbsolutePath()+".library_cumulative_coverage_proportions"));
|
||||||
spec.addAuxFile("9cd395f47b329b9dd00ad024fcac9929", createTempFileFromBase(baseOutputFile.getAbsolutePath()+".library_interval_statistics"));
|
spec.addAuxFile("9cd395f47b329b9dd00ad024fcac9929", createTempFileFromBase(baseOutputFile.getAbsolutePath()+".library_interval_statistics"));
|
||||||
spec.addAuxFile("c94a52b4e73a7995319e0b570c80d2f7", createTempFileFromBase(baseOutputFile.getAbsolutePath()+".library_interval_summary"));
|
spec.addAuxFile("e69ee59f447816c025c09a56e321cef8", createTempFileFromBase(baseOutputFile.getAbsolutePath()+".library_interval_summary"));
|
||||||
spec.addAuxFile("1970a44efb7ace4e51a37f0bd2dc84d1", createTempFileFromBase(baseOutputFile.getAbsolutePath()+".library_statistics"));
|
spec.addAuxFile("fa054b665d1ae537ada719da7713e11b", createTempFileFromBase(baseOutputFile.getAbsolutePath()+".library_statistics"));
|
||||||
spec.addAuxFile("c321c542be25359d2e26d45cbeb6d7ab", createTempFileFromBase(baseOutputFile.getAbsolutePath()+".library_summary"));
|
spec.addAuxFile("28dec9383b3a323a5ce7d96d62712917", createTempFileFromBase(baseOutputFile.getAbsolutePath()+".library_summary"));
|
||||||
spec.addAuxFile("9023cc8939777d515cd2895919a99688", createTempFileFromBase(baseOutputFile.getAbsolutePath()+".read_group_cumulative_coverage_counts"));
|
spec.addAuxFile("a836b92ac17b8ff9788e2aaa9116b5d4", createTempFileFromBase(baseOutputFile.getAbsolutePath()+".read_group_cumulative_coverage_counts"));
|
||||||
spec.addAuxFile("3597b69e90742c5dd7c83fbc74d079f3", createTempFileFromBase(baseOutputFile.getAbsolutePath()+".read_group_cumulative_coverage_proportions"));
|
spec.addAuxFile("d32a8c425fadcc4c048bd8b48d0f61e5", createTempFileFromBase(baseOutputFile.getAbsolutePath()+".read_group_cumulative_coverage_proportions"));
|
||||||
spec.addAuxFile("7b9d0e93bf5b5313995be7010ef1f528", createTempFileFromBase(baseOutputFile.getAbsolutePath()+".read_group_interval_statistics"));
|
spec.addAuxFile("7b9d0e93bf5b5313995be7010ef1f528", createTempFileFromBase(baseOutputFile.getAbsolutePath()+".read_group_interval_statistics"));
|
||||||
spec.addAuxFile("1a6ea3aa759fb154ccc4e171ebca9d02", createTempFileFromBase(baseOutputFile.getAbsolutePath()+".read_group_interval_summary"));
|
spec.addAuxFile("4656c8797696cf5ef0cdc5971271236a", createTempFileFromBase(baseOutputFile.getAbsolutePath()+".read_group_interval_summary"));
|
||||||
spec.addAuxFile("b492644ff06b4ffb044d5075cd168abf", createTempFileFromBase(baseOutputFile.getAbsolutePath()+".read_group_statistics"));
|
spec.addAuxFile("6f1d7f2120a4ac524c6026498f45295a", createTempFileFromBase(baseOutputFile.getAbsolutePath()+".read_group_statistics"));
|
||||||
spec.addAuxFile("77cef87dc4083a7b60b7a7b38b4c0bd8", createTempFileFromBase(baseOutputFile.getAbsolutePath()+".read_group_summary"));
|
spec.addAuxFile("69c424bca013159942337b67fdf31ff8", createTempFileFromBase(baseOutputFile.getAbsolutePath()+".read_group_summary"));
|
||||||
spec.addAuxFile("8e1adbe37b98bb2271ba13932d5c947f", createTempFileFromBase(baseOutputFile.getAbsolutePath()+".sample_cumulative_coverage_counts"));
|
spec.addAuxFile("6909d50a7da337cd294828b32b945eb8", createTempFileFromBase(baseOutputFile.getAbsolutePath()+".sample_cumulative_coverage_counts"));
|
||||||
spec.addAuxFile("761d2f9daf2ebaf43abf65c8fd2fcd05", createTempFileFromBase(baseOutputFile.getAbsolutePath()+".sample_cumulative_coverage_proportions"));
|
spec.addAuxFile("a395dafde101971d2b9e5ddb6cd4b7d0", createTempFileFromBase(baseOutputFile.getAbsolutePath()+".sample_cumulative_coverage_proportions"));
|
||||||
spec.addAuxFile("df0ba76e0e6082c0d29fcfd68efc6b77", createTempFileFromBase(baseOutputFile.getAbsolutePath()+".sample_interval_statistics"));
|
spec.addAuxFile("df0ba76e0e6082c0d29fcfd68efc6b77", createTempFileFromBase(baseOutputFile.getAbsolutePath()+".sample_interval_statistics"));
|
||||||
spec.addAuxFile("0582b4681dbc02ece2dfe2752dcfd228", createTempFileFromBase(baseOutputFile.getAbsolutePath()+".sample_interval_summary"));
|
spec.addAuxFile("185b910e499c08a8b88dd3ed1ac9e8ec", createTempFileFromBase(baseOutputFile.getAbsolutePath()+".sample_interval_summary"));
|
||||||
spec.addAuxFile("0685214965bf1863f7ce8de2e38af060", createTempFileFromBase(baseOutputFile.getAbsolutePath()+".sample_statistics"));
|
spec.addAuxFile("d5d11b686689467b5a8836f0a07f447d", createTempFileFromBase(baseOutputFile.getAbsolutePath()+".sample_statistics"));
|
||||||
spec.addAuxFile("7a0cd8a5ebaaa82621fd3b5aed9c32fe", createTempFileFromBase(baseOutputFile.getAbsolutePath()+".sample_summary"));
|
spec.addAuxFile("ad1a2775a31b1634daf64e691676bb96", createTempFileFromBase(baseOutputFile.getAbsolutePath()+".sample_summary"));
|
||||||
|
|
||||||
execute("testBaseOutputNoFiltering",spec);
|
execute("testBaseOutputNoFiltering",spec);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -189,7 +189,7 @@ public class UnifiedGenotyperIntegrationTest extends WalkerTest {
|
||||||
" -o %s" +
|
" -o %s" +
|
||||||
" -L 1:10,000,000-10,100,000",
|
" -L 1:10,000,000-10,100,000",
|
||||||
1,
|
1,
|
||||||
Arrays.asList("2b2729414ae855d390e7940956745bce"));
|
Arrays.asList("f0fbe472f155baf594b1eeb58166edef"));
|
||||||
|
|
||||||
executeTest(String.format("test multiple technologies"), spec);
|
executeTest(String.format("test multiple technologies"), spec);
|
||||||
}
|
}
|
||||||
|
|
@ -208,7 +208,7 @@ public class UnifiedGenotyperIntegrationTest extends WalkerTest {
|
||||||
" -L 1:10,000,000-10,100,000" +
|
" -L 1:10,000,000-10,100,000" +
|
||||||
" -baq CALCULATE_AS_NECESSARY",
|
" -baq CALCULATE_AS_NECESSARY",
|
||||||
1,
|
1,
|
||||||
Arrays.asList("95c6120efb92e5a325a5cec7d77c2dab"));
|
Arrays.asList("8c87c749a7bb5a76ed8504d4ec254272"));
|
||||||
|
|
||||||
executeTest(String.format("test calling with BAQ"), spec);
|
executeTest(String.format("test calling with BAQ"), spec);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,8 +34,8 @@ public class RecalibrationWalkersIntegrationTest extends WalkerTest {
|
||||||
|
|
||||||
new CCTest( validationDataLocation + "NA12892.SLX.SRP000031.2009_06.selected.bam", "ab4940a16ab990181bd8368c76b23853" );
|
new CCTest( validationDataLocation + "NA12892.SLX.SRP000031.2009_06.selected.bam", "ab4940a16ab990181bd8368c76b23853" );
|
||||||
new CCTest( validationDataLocation + "NA19240.chr1.BFAST.SOLID.bam", "17d4b8001c982a70185e344929cf3941");
|
new CCTest( validationDataLocation + "NA19240.chr1.BFAST.SOLID.bam", "17d4b8001c982a70185e344929cf3941");
|
||||||
new CCTest( validationDataLocation + "NA12873.454.SRP000031.2009_06.chr1.10_20mb.bam", "36c0c467b6245c2c6c4e9c956443a154" );
|
new CCTest( validationDataLocation + "NA12873.454.SRP000031.2009_06.chr1.10_20mb.bam", "714e65d6cb51ae32221a77ce84cbbcdc" );
|
||||||
new CCTest( validationDataLocation + "NA12878.1kg.p2.chr1_10mb_11_mb.allTechs.bam", "955a8fa2ddb2b04c406766ccd9ac45cc" );
|
new CCTest( validationDataLocation + "NA12878.1kg.p2.chr1_10mb_11_mb.allTechs.bam", "932f0063abb2a23c22ec992ef8d36aa5" );
|
||||||
return CCTest.getTests(CCTest.class);
|
return CCTest.getTests(CCTest.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -91,8 +91,8 @@ public class RecalibrationWalkersIntegrationTest extends WalkerTest {
|
||||||
public Object[][] createTRTestData() {
|
public Object[][] createTRTestData() {
|
||||||
new TRTest( validationDataLocation + "NA12892.SLX.SRP000031.2009_06.selected.bam", "0b7123ae9f4155484b68e4a4f96c5504" );
|
new TRTest( validationDataLocation + "NA12892.SLX.SRP000031.2009_06.selected.bam", "0b7123ae9f4155484b68e4a4f96c5504" );
|
||||||
new TRTest( validationDataLocation + "NA19240.chr1.BFAST.SOLID.bam", "d04cf1f6df486e45226ebfbf93a188a5");
|
new TRTest( validationDataLocation + "NA19240.chr1.BFAST.SOLID.bam", "d04cf1f6df486e45226ebfbf93a188a5");
|
||||||
new TRTest( validationDataLocation + "NA12873.454.SRP000031.2009_06.chr1.10_20mb.bam", "b2f4757bc47cf23bd9a09f756c250787" );
|
new TRTest( validationDataLocation + "NA12873.454.SRP000031.2009_06.chr1.10_20mb.bam", "74314e5562c1a65547bb0edaacffe602" );
|
||||||
new TRTest( validationDataLocation + "NA12878.1kg.p2.chr1_10mb_11_mb.allTechs.bam", "502c7df4d4923c4d078b014bf78bed34" );
|
new TRTest( validationDataLocation + "NA12878.1kg.p2.chr1_10mb_11_mb.allTechs.bam", "41c2f82f7789421f3690ed3c35b8f2e4" );
|
||||||
|
|
||||||
return TRTest.getTests(TRTest.class);
|
return TRTest.getTests(TRTest.class);
|
||||||
}
|
}
|
||||||
|
|
@ -291,7 +291,7 @@ public class RecalibrationWalkersIntegrationTest extends WalkerTest {
|
||||||
@Test
|
@Test
|
||||||
public void testCountCovariatesNoIndex() {
|
public void testCountCovariatesNoIndex() {
|
||||||
HashMap<String, String> e = new HashMap<String, String>();
|
HashMap<String, String> e = new HashMap<String, String>();
|
||||||
e.put( validationDataLocation + "NA12878.1kg.p2.chr1_10mb_11_mb.allTechs.noindex.bam", "828d247c6e8ef5ebdf3603dc0ce79f61" );
|
e.put( validationDataLocation + "NA12878.1kg.p2.chr1_10mb_11_mb.allTechs.noindex.bam", "aac7df368ca589dc0a66d5bd9ad007e3" );
|
||||||
|
|
||||||
for ( Map.Entry<String, String> entry : e.entrySet() ) {
|
for ( Map.Entry<String, String> entry : e.entrySet() ) {
|
||||||
String bam = entry.getKey();
|
String bam = entry.getKey();
|
||||||
|
|
@ -317,7 +317,7 @@ public class RecalibrationWalkersIntegrationTest extends WalkerTest {
|
||||||
@Test(dependsOnMethods = "testCountCovariatesNoIndex")
|
@Test(dependsOnMethods = "testCountCovariatesNoIndex")
|
||||||
public void testTableRecalibratorNoIndex() {
|
public void testTableRecalibratorNoIndex() {
|
||||||
HashMap<String, String> e = new HashMap<String, String>();
|
HashMap<String, String> e = new HashMap<String, String>();
|
||||||
e.put( validationDataLocation + "NA12878.1kg.p2.chr1_10mb_11_mb.allTechs.noindex.bam", "991f093a0e610df235d28ada418ebf33" );
|
e.put( validationDataLocation + "NA12878.1kg.p2.chr1_10mb_11_mb.allTechs.noindex.bam", "02249d9933481052df75c58a2a1a8e63" );
|
||||||
|
|
||||||
for ( Map.Entry<String, String> entry : e.entrySet() ) {
|
for ( Map.Entry<String, String> entry : e.entrySet() ) {
|
||||||
String bam = entry.getKey();
|
String bam = entry.getKey();
|
||||||
|
|
|
||||||
|
|
@ -103,10 +103,31 @@ public class ReadUtilsUnitTest extends BaseTest {
|
||||||
read.setReadNegativeStrandFlag(false);
|
read.setReadNegativeStrandFlag(false);
|
||||||
boundary = ReadUtils.getAdaptorBoundary(read);
|
boundary = ReadUtils.getAdaptorBoundary(read);
|
||||||
Assert.assertNull(boundary);
|
Assert.assertNull(boundary);
|
||||||
|
read.setInferredInsertSize(10);
|
||||||
|
|
||||||
// Test case 6: read is unmapped
|
// Test case 6: read is unmapped
|
||||||
read.setReadUnmappedFlag(true);
|
read.setReadUnmappedFlag(true);
|
||||||
boundary = ReadUtils.getAdaptorBoundary(read);
|
boundary = ReadUtils.getAdaptorBoundary(read);
|
||||||
Assert.assertNull(boundary);
|
Assert.assertNull(boundary);
|
||||||
|
read.setReadUnmappedFlag(false);
|
||||||
|
|
||||||
|
// Test case 7: reads don't overlap and look like this:
|
||||||
|
// <--------|
|
||||||
|
// |------>
|
||||||
|
// first read:
|
||||||
|
myStart = 980;
|
||||||
|
read.setAlignmentStart(myStart);
|
||||||
|
read.setInferredInsertSize(20);
|
||||||
|
read.setReadNegativeStrandFlag(true);
|
||||||
|
boundary = ReadUtils.getAdaptorBoundary(read);
|
||||||
|
Assert.assertNull(boundary);
|
||||||
|
|
||||||
|
// second read:
|
||||||
|
myStart = 1000;
|
||||||
|
read.setAlignmentStart(myStart);
|
||||||
|
read.setMateAlignmentStart(980);
|
||||||
|
read.setReadNegativeStrandFlag(false);
|
||||||
|
boundary = ReadUtils.getAdaptorBoundary(read);
|
||||||
|
Assert.assertNull(boundary);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue