A comprehensive KASP primer design tool for SNP analysis and primer design
Project description
KASPioneer
A comprehensive KASP (Kompetitive Allele Specific PCR) primer design tool for SNP analysis and primer design with multiple analysis modes.
Table of Contents
- Overview
- Prerequisites
- Installation
- Quick Start
- Genome Index Setup
- Functions
- Parameters
- Output Files
- Examples
- Performance Optimization
- Troubleshooting
Overview
KASPioneer is a modular KASP primer design tool that provides four distinct analysis modes for different research scenarios:
- Genome-wide Analysis (
genome): Density-based sampling across entire genome - Region-based Analysis (
region): SNP analysis within specific genomic regions - Target SNP Analysis (
target): Focused analysis on specific SNPs with flanking analysis - Custom Sequence Analysis (
custom): Primer design from custom SNP sequences
Prerequisites
- Python 3.7+
- Required Python packages:
tqdm(progress bars)primer3-py(primer design calculations)pysam(VCF parsing)
Installation
Method 1: Direct Installation (Recommended)
# Clone the repository
git clone <repository-url>
cd KASPioneer_v3
# Install dependencies
pip install tqdm primer3-py pysam numpy pandas
# Make the script executable
chmod +x kasp_designer.py
Method 2: Using the Packaging Script
# Clone the repository
git clone <repository-url>
cd KASPioneer_v3
# Run the packaging script to create installable package
./run.sh
# Follow the instructions provided by the script for:
# - PyPI + pip installation
# - Conda package installation
# - Standalone executable creation
Method 3: Development Installation
# Clone the repository
git clone <repository-url>
cd KASPioneer_v3
# Install in development mode
pip install -e .
# Or install with all dependencies
pip install -r requirements.txt
System Requirements
- Python: 3.7 or higher
- Memory: At least 4GB RAM (8GB+ recommended for large genomes)
- Storage: At least 2GB free space for genome indices
- External Tools: bowtie2 (for primer specificity validation)
Installing bowtie2
# Ubuntu/Debian
sudo apt-get install bowtie2
# CentOS/RHEL
sudo yum install bowtie2
# macOS
brew install bowtie2
# Or download from: http://bowtie-bio.sourceforge.net/bowtie2/index.shtml
Quick Start
Test Data
The repository includes test data in the test_data/ directory:
BSA-test.vcf.gz: BSA (Bulked Segregant Analysis) test VCF file with sample data3k-test.vcf.gz: 3K rice genome test VCF filemsu7_chr1_12.fa: Rice genome reference (chromosomes 1-12)test_snp_sequences.txt: Example custom SNP sequences filefiltered.sh: Example filtering script
1. Build Genome Index (Required First Step)
⚠️ IMPORTANT: You must build the genome index before running any primer design functions for specificity validation.
# Using test data
python kasp_designer.py build_index --ref test_data/msu7_chr1_12.fa --bowtie_index genome_index/msu7_chr1_12
# Using your own data
python kasp_designer.py build_index --ref genome.fa --bowtie_index genome_index/genome
2. Run Primer Design
Using Test Data (Quick Test)
# Genome-wide analysis with test data
python kasp_designer.py genome --vcf test_data/BSA-test.vcf.gz --ref test_data/msu7_chr1_12.fa --mother PR25 --father RIBENQING --output_prefix test_genome --bowtie_index genome_index/msu7_chr1_12 --threads 4
# Region-based analysis with test data
python kasp_designer.py region --vcf test_data/BSA-test.vcf.gz --ref test_data/msu7_chr1_12.fa --chrom 1 --start 1000000 --end 2000000 --mother PR25 --father RIBENQING --output_prefix test_region --bowtie_index genome_index/msu7_chr1_12 --threads 4
# Target SNP analysis with test data
python kasp_designer.py target --vcf test_data/BSA-test.vcf.gz --ref test_data/msu7_chr1_12.fa --chrom 1 --position 1500000 --mother PR25 --father RIBENQING --output_prefix test_target --bowtie_index genome_index/msu7_chr1_12 --threads 4
# Custom sequence analysis with test data
python kasp_designer.py custom --snp_sequences test_data/test_snp_sequences.txt --ref test_data/msu7_chr1_12.fa --output_prefix test_custom --bowtie_index genome_index/msu7_chr1_12 --threads 4
Using Your Own Data
# Genome-wide analysis
python kasp_designer.py genome --vcf variants.vcf.gz --ref genome.fa --mother PR25 --father RIBENQING --output_prefix results_genome --bowtie_index genome_index/genome --threads 12
# Region-based analysis
python kasp_designer.py region --vcf variants.vcf.gz --ref genome.fa --chrom chr1 --start 123456 --end 173456 --mother PR25 --father RIBENQING --output_prefix results_region --bowtie_index genome_index/genome --threads 12
# Target SNP analysis
python kasp_designer.py target --vcf variants.vcf.gz --ref genome.fa --chrom chr1 --position 123456 --mother PR25 --father RIBENQING --output_prefix results_target --bowtie_index genome_index/genome --threads 12
# Custom sequence analysis
python kasp_designer.py custom --snp_sequences snp_list.txt --ref genome.fa --output_prefix results_custom --bowtie_index genome_index/genome --threads 12
Genome Index Setup
Building the Index
The genome index is essential for primer specificity validation. Build it once and reuse for all analyses:
python kasp_designer.py build_index --ref genome.fa --bowtie_index genome_index/genome
Parameters:
--ref: Reference genome FASTA file--bowtie_index: Output path for bowtie index (without extension)
Output:
- Creates bowtie index files:
genome_index/genome.1.bt2,genome_index/genome.2.bt2, etc.
Functions
Genome-wide Analysis
Function: genome
Purpose: Performs density-based sampling across the entire genome, dividing each chromosome into bins and selecting representative SNPs for primer design. This function is ideal for genome-wide association studies (GWAS) and large-scale marker development.
How it works:
- Chromosome Division: Each chromosome is divided into equal-sized bins (default: 20 bins per chromosome)
- SNP Selection: Within each bin, SNPs are selected using uniform bin sampling to ensure even distribution
- Flanking Analysis: For each selected SNP, flanking SNPs are analyzed to ensure proper spacing
- Parallel Processing: Uses chromosome-based multiprocessing for optimal performance
- Quality Assessment: Each primer set is evaluated for quality and specificity
Command:
python kasp_designer.py genome --vcf variants.vcf.gz --ref genome.fa --mother PR25 --father RIBENQING --output_prefix results_genome --bowtie_index genome_index/genome --threads 12
Required Parameters:
--vcf: Input VCF file (can be .gz compressed) - Contains SNP variants--ref: Reference genome FASTA file - Used for primer design and specificity validation--mother: Mother sample name in VCF - Must be homozygous for different alleles--father: Father sample name in VCF - Must be homozygous for different alleles--output_prefix: Output file prefix - Results will be saved as{prefix}_genome.tsv
Optional Parameters:
--bins_per_chr: Number of bins per chromosome (default: 20) - Higher values = more SNPs selected--flank_snps: Number of flanking SNPs on each side of median SNP (default: 10) - Ensures proper spacing--threads: Number of parallel threads (default: CPU cores - 1) - Optimize based on your system
Output File: {output_prefix}_genome.tsv
Use Cases:
- Genome-wide marker development
- Large-scale genetic mapping
- Population genetics studies
- Breeding program marker selection
Region-based Analysis
Function: region
Purpose: Analyzes SNPs within a specific genomic region and designs primers for all qualifying SNPs. This function is perfect for fine-mapping studies, QTL analysis, and candidate gene regions.
How it works:
- Region Definition: Defines a specific genomic region by chromosome and coordinates
- SNP Extraction: Extracts all SNPs within the specified region from the VCF file
- Quality Filtering: Applies quality filters and parent genotype requirements
- Batch Processing: Uses SNP batch-based multiprocessing for efficient analysis
- Comprehensive Analysis: Designs primers for all qualifying SNPs in the region
Command:
python kasp_designer.py region --vcf variants.vcf.gz --ref genome.fa --chrom chr1 --start 123456 --end 173456 --mother PR25 --father RIBENQING --output_prefix results_region --bowtie_index genome_index/genome --threads 12
Required Parameters:
--vcf: Input VCF file (can be .gz compressed) - Contains SNP variants--ref: Reference genome FASTA file - Used for primer design and specificity validation--chrom: Chromosome name - Target chromosome (e.g., "chr1", "1", "Chr1")--start: Start position of the region - Beginning coordinate (1-based)--end: End position of the region - Ending coordinate (1-based)--mother: Mother sample name in VCF - Must be homozygous for different alleles--father: Father sample name in VCF - Must be homozygous for different alleles--output_prefix: Output file prefix - Results will be saved as{prefix}_region.tsv
Output File: {output_prefix}_region.tsv
Use Cases:
- Fine-mapping studies
- QTL (Quantitative Trait Loci) analysis
- Candidate gene regions
- Linkage analysis
- Regional association studies
Target SNP Analysis
Function: target
Purpose: Focuses on a specific target SNP and optionally includes flanking SNPs for comprehensive analysis. This function is ideal for validating specific markers, designing primers for known functional SNPs, or analyzing SNPs of particular interest.
How it works:
- Target Identification: Locates the specific SNP at the given chromosome position
- Flanking Analysis: Optionally includes flanking SNPs for comprehensive coverage
- Quality Assessment: Evaluates each SNP for primer design feasibility
- Batch Processing: Uses SNP batch-based multiprocessing for efficient analysis
- Detailed Results: Provides comprehensive primer information for each SNP
Command:
python kasp_designer.py target --vcf variants.vcf.gz --ref genome.fa --chrom chr1 --position 123456 --mother PR25 --father RIBENQING --output_prefix results_target --bowtie_index genome_index/genome --threads 12
Required Parameters:
--vcf: Input VCF file (can be .gz compressed) - Contains SNP variants--ref: Reference genome FASTA file - Used for primer design and specificity validation--chrom: Chromosome name - Target chromosome (e.g., "chr1", "1", "Chr1")--position: Target SNP position - Exact coordinate of the target SNP (1-based)--mother: Mother sample name in VCF - Must be homozygous for different alleles--father: Father sample name in VCF - Must be homozygous for different alleles--output_prefix: Output file prefix - Results will be saved as{prefix}_target.tsv
Optional Parameters:
--flank_snps: Number of flanking SNPs on each side of target SNP (default: 10) - Set to 0 for target SNP only
Output File: {output_prefix}_target.tsv
Use Cases:
- Validating specific markers
- Designing primers for known functional SNPs
- Analyzing SNPs of particular interest
- Marker-assisted selection (MAS)
- Genotyping specific loci
Custom Sequence Analysis
Function: custom
Purpose: Designs primers from custom SNP sequences provided in a text file. This function is perfect for designing primers from known sequences, validating specific sequences, or working with sequences from external sources.
How it works:
- Sequence Parsing: Reads custom SNP sequences from input file
- SNP Detection: Automatically detects SNP positions and alleles from sequence format
- Primer Design: Designs KASP primers for each custom sequence
- Batch Processing: Uses SNP batch-based multiprocessing for efficient analysis
- Quality Assessment: Evaluates primer quality and specificity for each sequence
Command:
python kasp_designer.py custom --snp_sequences snp_list.txt --ref genome.fa --output_prefix results_custom --bowtie_index genome_index/genome --threads 12
Required Parameters:
--snp_sequences: Input file with SNP sequences - Text file containing custom sequences--ref: Reference genome FASTA file - Used for primer design and specificity validation--output_prefix: Output file prefix - Results will be saved as{prefix}_custom.tsv
Input File Format:
SNP_ID1,ATCGATCGATCG[A/T]GATCGATCGATCG
SNP_ID2,GCTAGCTAGCTA[G/C]TAGCTAGCTAGCT
SNP_ID3,TTTTTTTTTTTTTTTTTTTT[C/G]TTTTTTTTTTTTTTTTTTTT
Format Rules:
- One SNP per line
- Format:
SNP_ID,SEQUENCE_WITH_SNP - SNP format:
[REF/ALT]where REF and ALT are the two alleles - Sequence should be at least 50bp long for optimal primer design
- SNP should be positioned away from sequence ends (at least 25bp from each end)
Output File: {output_prefix}_custom.tsv
Use Cases:
- Designing primers from known sequences
- Validating specific sequences
- Working with sequences from external sources
- Converting existing markers to KASP format
- Designing primers for specific gene regions
Parameters
Common Parameters
All functions share these common parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
--min_qual |
float | 30.0 | Minimum SNP quality score |
--verbose |
flag | False | Enable verbose logging |
--min_left_dist |
int | 26 | Filter left SNP closer than this distance (bp) |
--min_right_dist |
int | 80 | Filter right SNP closer than this distance (bp) |
--upstream_len |
int | 30 | Upstream sequence length |
--downstream_len |
int | 100 | Downstream sequence length |
--min_primer_len |
int | 20 | Minimum primer length |
--max_primer_len |
int | 26 | Maximum primer length |
--min_gc |
float | 30.0 | Minimum GC content (%) |
--max_gc |
float | 60.0 | Maximum GC content (%) |
--min_tm |
float | 55.0 | Minimum melting temperature (°C) |
--max_tm |
float | 61.0 | Maximum melting temperature (°C) |
--max_tm_diff |
float | 3.0 | Maximum Tm difference between primers (°C) |
--max_product_len |
int | 100 | Maximum PCR product length (bp) |
--fam_tail |
string | GAAGGTGACCAAGTTCATGCT | FAM tail sequence |
--hex_tail |
string | GAAGGTCGGAGTCAACGGATT | HEX tail sequence |
--threads |
int | CPU cores - 1 | Number of parallel threads |
Output Files
Output File Structure
All functions generate TSV (Tab-Separated Values) files with the following columns:
Common Columns
| Column | Description |
|---|---|
chrom |
Chromosome name |
pos |
SNP position |
ref |
Reference allele |
alt |
Alternative allele |
forwardA |
Forward primer for allele A |
forwardB |
Forward primer for allele B |
reverse |
Reverse primer |
forwardA_withtail |
Forward primer A with FAM tail |
forwardB_withtail |
Forward primer B with HEX tail |
fA_tm |
Melting temperature of forward primer A (°C) |
fB_tm |
Melting temperature of forward primer B (°C) |
r_tm |
Melting temperature of reverse primer (°C) |
fA_gc |
GC content of forward primer A (%) |
fB_gc |
GC content of forward primer B (%) |
r_gc |
GC content of reverse primer (%) |
product_len |
PCR product length (bp) |
primer_quality_score |
Overall primer quality score (0-100) |
structure_quality |
Structure quality score (0-1) |
recommended_annealing_temp |
Recommended annealing temperature (°C) |
specificity |
Specificity validation result |
Function-Specific Columns
Genome Analysis (genome):
| Column | Description |
|---|---|
bin_name |
Bin name (e.g., "1_Bin_1") |
Region Analysis (region):
- No additional columns
Target Analysis (target):
| Column | Description |
|---|---|
flank_direction |
SNP type: "TARGET", "FLANKING_LEFT", or "FLANKING_RIGHT" |
Custom Analysis (custom):
| Column | Description |
|---|---|
snp_id |
Custom SNP identifier |
sequence |
Original input sequence |
ref_allele |
Reference allele |
alt_allele |
Alternative allele |
Quality Metrics
Primer Quality Score (0-100)
The primer quality score is a comprehensive assessment of primer set quality, calculated using multiple factors:
Score Ranges:
- 90-100: Excellent quality - Ideal for high-throughput genotyping
- 80-89: Very good quality - Suitable for most applications
- 70-79: Good quality - Acceptable for most studies
- 60-69: Fair quality - May require optimization
- 50-59: Poor quality - Not recommended for production use
- 0-49: Very poor quality - Significant issues detected
Scoring Factors (with penalties):
-
Tm Difference Penalty (0-25 points deducted)
- Ideal: < 2°C difference between primers
- Penalty: 5 points per 1°C over 3°C difference
- Formula:
max(abs(fA_tm - r_tm), abs(fB_tm - r_tm))
-
GC Content Penalty (0-15 points deducted)
- Ideal range: 40-60% for all primers
- Penalty: 5 points per primer outside ideal range
- Affects primer stability and specificity
-
Product Length Penalty (0-10 points deducted)
- Ideal range: 60-120bp
- Penalty: 10 points if outside range
- Affects PCR efficiency and resolution
-
Structure Quality Multiplier (0-1 multiplier)
- Multiplies total score by structure quality
- Accounts for secondary structure issues
-
Primer Length Penalty (0-9 points deducted)
- Ideal range: 18-25bp for all primers
- Penalty: 3 points per primer outside range
- Affects primer specificity and efficiency
Final Score Calculation:
Score = (100 - Tm_penalty - GC_penalty - Product_penalty - Length_penalty) × Structure_quality
Structure Quality Score (0-1)
The structure quality score evaluates secondary structure formation in primers:
Score Ranges:
- 1.0: No secondary structures detected
- 0.7-0.9: Minor secondary structures (acceptable)
- 0.4-0.6: Moderate secondary structures (may affect performance)
- 0.0-0.3: Significant secondary structures (not recommended)
Structure Types Evaluated:
-
Hairpin Structures (0.3 penalty)
- Self-complementary regions within primers
- Can cause primer-dimer formation
- Detected using primer3 hairpin calculation
-
Homodimer Structures (0.2 penalty)
- Self-dimerization of primers
- Can reduce primer availability
- Detected using primer3 homodimer calculation
-
Heterodimer Structures (0.2-0.3 penalty)
- Cross-dimerization between primers
- ForwardA-Reverse: 0.2 penalty
- ForwardB-Reverse: 0.2 penalty
- ForwardA-ForwardB: 0.3 penalty
Calculation:
Structure_quality = max(0, 1.0 - hairpin_penalty - homodimer_penalty - heterodimer_penalty)
Recommended Annealing Temperature
The recommended annealing temperature is calculated to optimize PCR performance:
Formula:
Recommended_Tm = min(fA_tm, fB_tm, r_tm) - 3°C
Rationale:
- Uses the lowest Tm among all primers as baseline
- Subtracts 3°C to ensure all primers can anneal efficiently
- Provides optimal balance between specificity and efficiency
- Accounts for primer competition in multiplex reactions
Temperature Ranges:
- 55-65°C: Optimal range for most KASP reactions
- 50-55°C: May require optimization for specificity
- 65-70°C: May reduce efficiency for some primers
- <50°C or >70°C: Not recommended for KASP reactions
Examples
Example 1: Quick Test with Test Data
# Build index using test data
python kasp_designer.py build_index --ref test_data/msu7_chr1_12.fa --bowtie_index genome_index/msu7_chr1_12
# Test genome-wide analysis
python kasp_designer.py genome \
--vcf test_data/BSA-test.vcf.gz \
--ref test_data/msu7_chr1_12.fa \
--mother PR25 \
--father RIBENQING \
--output_prefix test_genome \
--bowtie_index genome_index/msu7_chr1_12 \
--bins_per_chr 5 \
--flank_snps 3 \
--threads 4
Example 2: Region-based Analysis with Test Data
# Test region-based analysis
python kasp_designer.py region \
--vcf test_data/BSA-test.vcf.gz \
--ref test_data/msu7_chr1_12.fa \
--chrom 1 \
--start 1000000 \
--end 2000000 \
--mother PR25 \
--father RIBENQING \
--output_prefix test_region \
--bowtie_index genome_index/msu7_chr1_12 \
--threads 4
Example 3: Target SNP Analysis with Test Data
# Test target SNP analysis
python kasp_designer.py target \
--vcf test_data/BSA-test.vcf.gz \
--ref test_data/msu7_chr1_12.fa \
--chrom 1 \
--position 1500000 \
--mother PR25 \
--father RIBENQING \
--output_prefix test_target \
--bowtie_index genome_index/msu7_chr1_12 \
--flank_snps 2 \
--threads 4
Example 4: Custom Sequence Analysis with Test Data
Test input file (test_data/test_snp_sequences.txt):
SNP_001,ATCGATCGATCGATCGATCG[A/T]GATCGATCGATCGATCGATCG
SNP_002,GCTAGCTAGCTAGCTAGCTA[G/C]TAGCTAGCTAGCTAGCTAGCT
SNP_003,TTTTTTTTTTTTTTTTTTTT[C/G]TTTTTTTTTTTTTTTTTTTT
Command:
python kasp_designer.py custom \
--snp_sequences test_data/test_snp_sequences.txt \
--ref test_data/msu7_chr1_12.fa \
--output_prefix test_custom \
--bowtie_index genome_index/msu7_chr1_12 \
--threads 4
Example 5: Production Analysis with Your Data
# Build index for your genome
python kasp_designer.py build_index --ref your_genome.fa --bowtie_index genome_index/your_genome
# Run genome-wide analysis
python kasp_designer.py genome \
--vcf your_variants.vcf.gz \
--ref your_genome.fa \
--mother YOUR_MOTHER_SAMPLE \
--father YOUR_FATHER_SAMPLE \
--output_prefix production_genome_analysis \
--bowtie_index genome_index/your_genome \
--bins_per_chr 20 \
--flank_snps 10 \
--threads 16
Performance Optimization
Threading Strategy
- Genome Analysis: Uses chromosome-based parallel processing
- Other Analyses: Uses batch-based parallel processing
- Recommended: Use
--threadsequal to your CPU cores minus 1
Memory Usage
- Large Genomes: Consider using compressed VCF files (.vcf.gz)
- Memory Optimization: The tool processes chromosomes sequentially to minimize memory usage
Speed Tips
- Use compressed VCF files (.vcf.gz) for faster I/O
- Pre-build genome index and reuse for multiple analyses
- Adjust batch sizes based on your system's memory
- Use SSD storage for faster file I/O operations
Troubleshooting
Common Issues
1. "Genome index not found" Error
# Solution: Build the genome index first
python kasp_designer.py build_index --ref genome.fa --bowtie_index genome_index/genome
2. "Sample not found in VCF" Error
# Check sample names in VCF file
bcftools query -l variants.vcf.gz
# Use exact sample names (case-sensitive)
python kasp_designer.py genome --mother PR25 --father RIBENQING ...
3. "No SNPs found" Warning
- Check VCF file quality filters (
--min_qual) - Verify chromosome names match between VCF and reference
- Check parent genotype filters (must be homozygous and different)
4. Memory Issues
- Use compressed VCF files
- Reduce
--threadsparameter - Process smaller regions at a time
5. Slow Performance
- Ensure genome index is built
- Use SSD storage
- Increase
--threads(but not more than CPU cores) - Check disk space availability
Debug Mode
Enable verbose logging for detailed information:
python kasp_designer.py genome --verbose --vcf variants.vcf.gz ...
Log Files
The tool provides detailed logging information including:
- Processing progress
- SNP filtering statistics
- Primer design success rates
- Specificity validation results
Citation
If you use KASPioneer in your research, please cite:
KASPioneer: A Comprehensive KASP Primer Design Tool
[Your citation information here]
License
[Your license information here]
Support
For questions, issues, or feature requests, please:
- Check this README for common solutions
- Search existing issues on GitHub
- Create a new issue with detailed information
Changelog
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file kaspioneer-1.0.0.tar.gz.
File metadata
- Download URL: kaspioneer-1.0.0.tar.gz
- Upload date:
- Size: 555.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ed4b7795b80f4a6d46bd2c6db5802b43b3b53ba8f4572c9fa2387579ce6d2d8c
|
|
| MD5 |
20872d3d60638aff9e264f173859073b
|
|
| BLAKE2b-256 |
36cd5dce3f5bcc0fc54878817317c30be40aa5dcfeb5d12c36eaaef35e97e74e
|
File details
Details for the file kaspioneer-1.0.0-py3-none-any.whl.
File metadata
- Download URL: kaspioneer-1.0.0-py3-none-any.whl
- Upload date:
- Size: 554.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a3998a8ed5dc2016b0158ff1bb54d0e760da025e2eeea6305a9d2f7cefdaf840
|
|
| MD5 |
0a581e423472421cfeb4e0ec21d987ce
|
|
| BLAKE2b-256 |
388a9e35d4eb8335afbd8cbb975c972b5e5cc0701ad0b39621638a7223c8de3b
|