// File: /workspace/github_cpp_makefile_star2_O2/millanek[P]evo/process_vcf_filter.cpp
// Function: filterMain(int, char**)
int filterMain(int argc, char** argv) {
    parseFilterOptions(argc, argv);
    //std::ios_base::openmode mode = std::ios_base::in;
    string fileName = opt::vcfFile;
    string fileRoot = stripExtension(fileName);
    std::vector<int> depthsHetFailed;
    std::vector<int> depthsHetPassed;
    std::vector<int> numVariantsPerHetCount;
    std::vector<std::vector<int> > num_indiv_het_vs_depth;
    
    std::ofstream* statsFFile;
    std::ofstream* statsVarDepthFile;
    std::ofstream* statsStrandBiasFile;
    std::ofstream* statsVariantQualityFile;
    std::ofstream* statsSegregationMetricFile;
    
    // Collect some numbers about why variants were filtered out:
    int numTotalFilteredOut = 0;
    int numMultiallelic = 0; int numInvariant = 0;
    // SB - strand bias; OD - overall depth; OQ - overall quality; F - inbreeding coefficient;
    int numSB = 0; int numOD = 0; int numOQ = 0; int numF = 0; int numOQ_OD = 0; int numOQ_SB = 0; int numOQ_F = 0; int numSB_F = 0; int numSB_OD = 0; int numF_OD = 0;
    int numOQ_OD_F = 0; int numOQ_OD_SB = 0; int numOQ_SB_F = 0; int numSB_F_OD = 0; int numOQ_OD_F_SB = 0;
    
    
    
    if (opt::bStats) {
        statsFFile = new std::ofstream(fileRoot + ".inbreeding");
        statsVarDepthFile = new std::ofstream(fileRoot + ".varDepth");
        statsStrandBiasFile = new std::ofstream(fileRoot + ".strandBias");
        statsVariantQualityFile = new std::ofstream(fileRoot + ".varQual");
        statsSegregationMetricFile = new std::ofstream(fileRoot + ".SGB");
        std::cerr << "Getting statistics for variants from: " << fileName << " to help with setting filtering criteria" << std::endl;
    } else {
        std::cerr << "Filtering variants from: " << fileName << std::endl;
        std::cerr << "Minimum variant quality score (overall) set to: " << opt::min_overall_quality << std::endl;
        std::cerr << "Maximum read depth (overall) set to: " << opt::max_overall_depth << std::endl;
        std::cerr << "Minimum read depth (overall) set to: " << opt::min_overall_depth << std::endl;
        std::cerr << "Minimum copies for a variant (e.g. 1 for allowing singletons): " << opt::min_copies << std::endl;
        std::cerr << "Minimum read depth at the variant position: " << opt::min_depth_in_any_individual << std::endl;
        if (opt::bAllowMissingGenotpyes)
            std::cerr << "Genotypes for individuals with lower read depth at the variant position will be set to missing (./.)" << std::endl;
        if (opt::max_het_indiv < std::numeric_limits<int>::max())
            std::cerr << "Filter out sites where more than " << opt::max_het_indiv << " individuals are heterozygous"  << std::endl;
    }
    // Open connection to read from the vcf file
    // std::ifstream* inFile = new std::ifstream(fileName.c_str(), mode);
    std::istream* inFile = createReader(fileName.c_str());
    
    
    bool gotChromosomeNumber = false;
    int numChromosomes;
    string line;
    int totalVariantNumber = 0;
    while (getline(*inFile, line)) {
        if (line[0] == '#') {
            if (!opt::bStats) std::cout << line << std::endl;
        } else {
            double r = ((double) rand() / (RAND_MAX));
            if (r > opt::subsample) {
                continue;
            }
            totalVariantNumber++;
            if (totalVariantNumber % 100000 == 0) std::cerr << "Filtered " << totalVariantNumber << " variants" << std::endl;
            FilterResult result;
            std::vector<std::string> fields = split(line, '\t');
            if (!gotChromosomeNumber) {
                const std::vector<std::string>::size_type numSamples = fields.size() - NUM_NON_GENOTYPE_COLUMNS;
                numChromosomes = (int)numSamples * 2;
                std::cerr << "Number of chromosomes: " << numChromosomes << std::endl;
                numVariantsPerHetCount.assign(numSamples + 1, 0);
                gotChromosomeNumber = true;
            }
            result.overallQuality = stringToDouble(fields[5]);
            
            result.counts = getThisVariantCounts(fields);
            
            if (opt::bStats) {
                
                *statsFFile << result.counts.inbreedingCoefficient << std::endl;
                *statsVarDepthFile << result.counts.overallDepth << std::endl;
                if (!result.counts.FSpval.empty()) {
                    *statsStrandBiasFile << result.counts.FSpval << std::endl;
                } else if (!result.counts.MQSBpval.empty()) {
                    *statsStrandBiasFile << result.counts.MQSBpval << std::endl;
                }
                if (result.counts.SGB < std::numeric_limits<double>::max()) {
                    *statsSegregationMetricFile << result.counts.SGB << std::endl;
                }
                *statsVariantQualityFile << result.overallQuality << std::endl;
                if (totalVariantNumber >= 1000000)
                    exit(EXIT_SUCCESS);
                else
                    continue;
            }
            
            
            // Start filtering
            // 1) Throw away stuff that is not bi-allelic
            if (opt::bBiallelicFilter) {
                result.biallelicPassed = testBiallelic(fields[4]);
                if (!result.biallelicPassed) { result.biallelicPassed = false; numTotalFilteredOut++; numMultiallelic++; continue; }
            } else
                result.biallelicPassed = true;
            
            // 2) Filtering on overall quality
            if (result.overallQuality < opt::min_overall_quality)
                result.overallQualityPassed = false;
            
            // 3) Filtering on overall depth
            if (result.counts.overallDepth >= opt::min_overall_depth && result.counts.overallDepth <= opt::max_overall_depth) {
                result.overallDepthPassed = true;
            } else
                result.overallDepthPassed = false;
            
            // 4) Filtering on strand bias
            if (!result.counts.FSpval.empty()) {
                if (stringToDouble(result.counts.FSpval) > opt::max_FS)
                    result.strandBiasPassed = false;
            }
            
            if (!result.counts.MQSBpval.empty()) {
                if (stringToDouble(result.counts.MQSBpval) < opt::min_MQSB)
                    result.strandBiasPassed = false;
            }
            
            // 5) Filter on inbreeding coefficinet
            if (result.counts.inbreedingCoefficient < opt::min_F) {
                result.inbreedingCoeffPassed = false;
            }
            
            // 6) Filtering on the number of copies/allele frequency
            if (result.counts.overall <= (numChromosomes - opt::min_copies) && result.counts.overall >= opt::min_copies) {
                
            } else {
                numInvariant++; continue;
            }
            
            if (result.inbreedingCoeffPassed && result.overallDepthPassed && result.overallQualityPassed && result.strandBiasPassed) {
                std::cout << line << std::endl;
            } else {
                numTotalFilteredOut++;
                if (!result.inbreedingCoeffPassed && result.overallDepthPassed && result.overallQualityPassed && result.strandBiasPassed) {
                    numF++;
                } else if (result.inbreedingCoeffPassed && !result.overallDepthPassed && result.overallQualityPassed && result.strandBiasPassed) {
                    numOD++;
                } else if (result.inbreedingCoeffPassed && result.overallDepthPassed && !result.overallQualityPassed && result.strandBiasPassed) {
                    numOQ++;
                } else if (result.inbreedingCoeffPassed && result.overallDepthPassed && result.overallQualityPassed && !result.strandBiasPassed) {
                    numSB++;
                } else if (!result.inbreedingCoeffPassed && result.overallDepthPassed && !result.overallQualityPassed && result.strandBiasPassed) {
                    numOQ_F++;
                } else if (result.inbreedingCoeffPassed && !result.overallDepthPassed && !result.overallQualityPassed && result.strandBiasPassed) {
                    numOQ_OD++;
                } else if (result.inbreedingCoeffPassed && result.overallDepthPassed && !result.overallQualityPassed && !result.strandBiasPassed) {
                    numOQ_SB++;
                } else if (!result.inbreedingCoeffPassed && result.overallDepthPassed && result.overallQualityPassed && !result.strandBiasPassed) {
                    numSB_F++;
                } else if (result.inbreedingCoeffPassed && !result.overallDepthPassed && result.overallQualityPassed && !result.strandBiasPassed) {
                    numSB_OD++;
                } else if (!result.inbreedingCoeffPassed && !result.overallDepthPassed && result.overallQualityPassed && result.strandBiasPassed) {
                    numF_OD++;
                } else if (!result.inbreedingCoeffPassed && !result.overallDepthPassed && !result.overallQualityPassed && result.strandBiasPassed) {
                    numOQ_OD_F++;
                } else if (result.inbreedingCoeffPassed && !result.overallDepthPassed && !result.overallQualityPassed && !result.strandBiasPassed) {
                    numOQ_OD_SB++;
                } else if (!result.inbreedingCoeffPassed && result.overallDepthPassed && !result.overallQualityPassed && !result.strandBiasPassed) {
                    numOQ_SB_F++;
                } else if (!result.inbreedingCoeffPassed && !result.overallDepthPassed && result.overallQualityPassed && !result.strandBiasPassed) {
                    numSB_F_OD++;
                } else if (!result.inbreedingCoeffPassed && !result.overallDepthPassed && !result.overallQualityPassed && !result.strandBiasPassed) {
                    numOQ_OD_F_SB++;
                }
            }
            
            // 7) Filtering on per-individual criteria
            
            /*if (result.counts.minimumDepthInAnIndividual >= opt::min_depth_in_any_individual) {
                
            } else if (opt::bAllowMissingGenotpyes) {
                // Set genotypes to missing for individuals with too low coverage
                for (int i = NUM_NON_GENOTYPE_COLUMNS; i != fields.size(); i++) {
                    if (result.counts.depthPerIndividual[i-NUM_NON_GENOTYPE_COLUMNS] < opt::min_depth_in_any_individual) {
                        fields[i][0] = '.'; fields[i][2] = '.';
                    }
                }
                print_vector_stream(fields, std::cout,'\t');
            }
            */
            
        }
    }
    std::cerr << "Total variants filtered out: " << numTotalFilteredOut << std::endl;
    std::cerr << "Reasons for filtering:" << std::endl;
    std::cerr << "Not biallelic: " << numMultiallelic << std::endl;
    std::cerr << "Invariant (not polymorphic in called samples): " << numInvariant << std::endl;
    std::cerr << "Other reasons:" << std::endl;
    std::cerr << "SB - strand bias; OD - overall depth; OQ - overall quality; F - inbreeding coefficient" << std::endl;
    std::cerr << "OQ+OD+F+SB:\t" << numOQ_OD_F_SB << " (" << ((double)numOQ_OD_F_SB/numTotalFilteredOut)*100 << "%)" << std::endl;
    std::cerr << "OQ+OD+F: \t" << numOQ_OD_F << " (" << ((double)numOQ_OD_F/numTotalFilteredOut)*100 << "%)" << std::endl;
    std::cerr << "OQ+OD+SB: \t" << numOQ_OD_SB << " (" << ((double)numOQ_OD_SB/numTotalFilteredOut)*100 << "%)" << std::endl;
    std::cerr << "OQ+SB+F: \t" << numOQ_SB_F << " (" << ((double)numOQ_SB_F/numTotalFilteredOut)*100 << "%)" << std::endl;
    std::cerr << "SB+F+OD: \t" << numSB_F_OD << " (" << ((double)numSB_F_OD/numTotalFilteredOut)*100 << "%)" << std::endl;
    std::cerr << "OQ+OD: \t" << numOQ_OD << " (" << ((double)numOQ_OD/numTotalFilteredOut)*100 << "%)" << std::endl;
    std::cerr << "OQ+F: \t" << numOQ_F << " (" << ((double)numOQ_F/numTotalFilteredOut)*100 << "%)" << std::endl;
    std::cerr << "OQ+SB: \t" << numOQ_SB << " (" << ((double)numOQ_SB/numTotalFilteredOut)*100 << "%)" << std::endl;
    std::cerr << "SB+F: \t" << numSB_F << " (" << ((double)numSB_F/numTotalFilteredOut)*100 << "%)" << std::endl;
    std::cerr << "SB+OD: \t" << numSB_OD << " (" << ((double)numSB_OD/numTotalFilteredOut)*100 << "%)" << std::endl;
    std::cerr << "F+OD: \t" << numF_OD << " (" << ((double)numF_OD/numTotalFilteredOut)*100 << "%)" << std::endl;
    std::cerr << "OQ: \t" << numOQ << " (" << ((double)numOQ/numTotalFilteredOut)*100 << "%)" << std::endl;
    std::cerr << "SB: \t" << numSB << " (" << ((double)numSB/numTotalFilteredOut)*100 << "%)" << std::endl;
    std::cerr << "OD: \t" << numOD << " (" << ((double)numOD/numTotalFilteredOut)*100 << "%)" << std::endl;
    std::cerr << "F: \t" << numF << " (" << ((double)numF/numTotalFilteredOut)*100 << "%)" << std::endl;
    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x3e8, %rsp            # imm = 0x3E8
callq 0x4e35f
leaq 0x912cf(%rip), %rsi     # 0xde2c8
leaq 0x1f0(%rsp), %rbx
movq %rbx, %rdi
callq 0x8600
leaq 0x1b0(%rsp), %rdi
movq %rbx, %rsi
callq 0x404d7
andq $0x0, 0x260(%rsp)
xorpd %xmm0, %xmm0
andq $0x0, 0x240(%rsp)
movapd %xmm0, 0x250(%rsp)
andq $0x0, 0x1e0(%rsp)
movapd %xmm0, 0x230(%rsp)
andq $0x0, 0x220(%rsp)
movapd %xmm0, 0x1d0(%rsp)
movapd %xmm0, 0x210(%rsp)
cmpb $0x1, 0x9127c(%rip)     # 0xde2e8
jne 0x4d238
movl $0x200, %edi            # imm = 0x200
callq 0x8490
movq %rax, 0x80(%rsp)
leaq 0x5449d(%rip), %rdx     # 0xa1528
leaq 0xa0(%rsp), %rdi
leaq 0x1b0(%rsp), %rsi
callq 0x28806
leaq 0xa0(%rsp), %rsi
pushq $0x10
popq %rdx
movq 0x80(%rsp), %rdi
callq 0x8900
leaq 0xa0(%rsp), %rdi
callq 0x8978
movl $0x200, %edi            # imm = 0x200
callq 0x8490
movq %rax, 0x78(%rsp)
leaq 0x54459(%rip), %rdx     # 0xa1534
leaq 0xa0(%rsp), %rdi
leaq 0x1b0(%rsp), %rsi
callq 0x28806
leaq 0xa0(%rsp), %rsi
pushq $0x10
popq %rdx
movq 0x78(%rsp), %rdi
callq 0x8900
leaq 0xa0(%rsp), %rdi
callq 0x8978
movl $0x200, %edi            # imm = 0x200
callq 0x8490
movq %rax, 0x68(%rsp)
leaq 0x54416(%rip), %rdx     # 0xa153e
leaq 0xa0(%rsp), %rdi
leaq 0x1b0(%rsp), %rsi
callq 0x28806
leaq 0xa0(%rsp), %rsi
pushq $0x10
popq %rdx
movq 0x68(%rsp), %rdi
callq 0x8900
leaq 0xa0(%rsp), %rdi
callq 0x8978
movl $0x200, %edi            # imm = 0x200
callq 0x8490
movq %rax, 0x70(%rsp)
leaq 0x543d5(%rip), %rdx     # 0xa154a
leaq 0xa0(%rsp), %rdi
leaq 0x1b0(%rsp), %rsi
callq 0x28806
leaq 0xa0(%rsp), %rsi
pushq $0x10
popq %rdx
movq 0x70(%rsp), %rdi
callq 0x8900
leaq 0xa0(%rsp), %rdi
callq 0x8978
movl $0x200, %edi            # imm = 0x200
callq 0x8490
movq %rax, 0x50(%rsp)
leaq 0x54391(%rip), %rdx     # 0xa1553
leaq 0xa0(%rsp), %rdi
leaq 0x1b0(%rsp), %rsi
callq 0x28806
leaq 0xa0(%rsp), %rsi
pushq $0x10
popq %rdx
movq 0x50(%rsp), %rdi
callq 0x8900
leaq 0xa0(%rsp), %rdi
callq 0x8978
movq 0x8fde8(%rip), %rdi     # 0xdcfe8
leaq 0x54351(%rip), %rsi     # 0xa1558
callq 0x8480
leaq 0x1f0(%rsp), %rsi
movq %rax, %rdi
callq 0x8430
leaq 0x5435c(%rip), %rsi     # 0xa157f
movq %rax, %rdi
callq 0x8480
movq %rax, %rdi
callq 0x8230
jmp 0x4d398
movq 0x8fda9(%rip), %rdi     # 0xdcfe8
leaq 0x54362(%rip), %rsi     # 0xa15a8
callq 0x8480
leaq 0x1f0(%rsp), %rsi
movq %rax, %rdi
callq 0x8430
movq %rax, %rdi
callq 0x8230
movq 0x8fd7e(%rip), %rdi     # 0xdcfe8
leaq 0x54351(%rip), %rsi     # 0xa15c2
callq 0x8480
movl 0x902d4(%rip), %esi     # 0xdd550
movq %rax, %rdi
callq 0x8840
movq %rax, %rdi
callq 0x8230
movq 0x8fd55(%rip), %rdi     # 0xdcfe8
leaq 0x54359(%rip), %rsi     # 0xa15f3
callq 0x8480
movl 0x902af(%rip), %esi     # 0xdd554
movq %rax, %rdi
callq 0x8840
movq %rax, %rdi
callq 0x8230
movq 0x8fd2c(%rip), %rdi     # 0xdcfe8
leaq 0x54356(%rip), %rsi     # 0xa1619
callq 0x8480
movl 0x9101e(%rip), %esi     # 0xde2ec
movq %rax, %rdi
callq 0x8840
movq %rax, %rdi
callq 0x8230
movq 0x8fd03(%rip), %rdi     # 0xdcfe8
leaq 0x54353(%rip), %rsi     # 0xa163f
callq 0x8480
movl 0x90261(%rip), %esi     # 0xdd558
movq %rax, %rdi
callq 0x8840
movq %rax, %rdi
callq 0x8230
movq 0x8fcda(%rip), %rdi     # 0xdcfe8
leaq 0x5436a(%rip), %rsi     # 0xa167f
callq 0x8480
movl 0x90fd0(%rip), %esi     # 0xde2f0
movq %rax, %rdi
callq 0x8840
movq %rax, %rdi
callq 0x8230
cmpb $0x1, 0x90fbd(%rip)     # 0xde2f4
jne 0x4d354
movq 0x8fca8(%rip), %rdi     # 0xdcfe8
leaq 0x54365(%rip), %rsi     # 0xa16ac
callq 0x8480
movq %rax, %rdi
callq 0x8230
cmpl $0x7fffffff, 0x901fe(%rip) # imm = 0x7FFFFFFF
je 0x4d398
movq 0x8fc81(%rip), %rdi     # 0xdcfe8
leaq 0x543a3(%rip), %rsi     # 0xa1711
callq 0x8480
movl 0x901e3(%rip), %esi     # 0xdd55c
movq %rax, %rdi
callq 0x8840
leaq 0x543ab(%rip), %rsi     # 0xa1733
movq %rax, %rdi
callq 0x8480
movq %rax, %rdi
callq 0x8230
movq 0x1f0(%rsp), %rsi
leaq 0xa0(%rsp), %rdi
leaq 0x2e8(%rsp), %rdx
callq 0x21904
leaq 0xa0(%rsp), %rdi
pushq $0x8
popq %rsi
callq 0x42587
movq %rax, %rbx
leaq 0xa0(%rsp), %rdi
callq 0x8978
leaq 0x278(%rsp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
movb $0x0, (%rax)
movl $0x0, (%rsp)
leaq 0x268(%rsp), %rbp
movl $0x0, 0x48(%rsp)
movl $0x0, 0x4c(%rsp)
movl $0x0, 0x34(%rsp)
movl $0x0, 0x40(%rsp)
movl $0x0, 0x38(%rsp)
movl $0x0, 0x44(%rsp)
movl $0x0, 0x1c(%rsp)
movl $0x0, 0x24(%rsp)
movl $0x0, 0x18(%rsp)
movl $0x0, 0x10(%rsp)
movl $0x0, 0xc(%rsp)
movl $0x0, 0x3c(%rsp)
movl $0x0, 0x20(%rsp)
movl $0x0, 0x2c(%rsp)
movl $0x0, 0x28(%rsp)
movl $0x0, 0x14(%rsp)
movl $0x0, 0x30(%rsp)
xorl %r14d, %r14d
xorl %r12d, %r12d
movl %r12d, %r13d
movq %rbx, %rdi
movq %rbp, %rsi
callq 0x80a0
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
testb $0x5, 0x20(%rax,%rcx)
jne 0x4dae1
movq 0x268(%rsp), %rax
cmpb $0x23, (%rax)
jne 0x4d4db
cmpb $0x0, 0x90e2e(%rip)     # 0xde2e8
movl %r13d, %r12d
jne 0x4d486
movq 0x8faf2(%rip), %rdi     # 0xdcfb8
movq %rbp, %rsi
callq 0x8430
movq %rax, %rdi
callq 0x8230
movl %r13d, %r12d
jmp 0x4d486
callq 0x8160
cvtsi2sd %eax, %xmm0
divsd 0x44c34(%rip), %xmm0    # 0x92120
ucomisd 0x9006c(%rip), %xmm0    # 0xdd560
movl %r13d, %r12d
ja 0x4d486
leal 0x1(%r13), %r12d
movl %r12d, %eax
cltd
movl $0x186a0, %ecx          # imm = 0x186A0
idivl %ecx
testl %edx, %edx
jne 0x4d541
movq 0x8fad5(%rip), %rdi     # 0xdcfe8
leaq 0x54237(%rip), %rsi     # 0xa1751
callq 0x8480
movq %rax, %rdi
movl %r12d, %esi
callq 0x8840
movq %rax, %rdi
leaq 0x59f9b(%rip), %rsi     # 0xa74cf
callq 0x8480
movq %rax, %rdi
callq 0x8230
leaq 0xa0(%rsp), %rdi
callq 0x4a6c6
leaq 0x88(%rsp), %rdi
movq %rbp, %rsi
pushq $0x9
popq %rdx
callq 0x40349
testb $0x1, %r14b
jne 0x4d5cd
movq 0x90(%rsp), %r14
subq 0x88(%rsp), %r14
movq 0x8fa6a(%rip), %rdi     # 0xdcfe8
leaq 0x5309e(%rip), %rsi     # 0xa0623
callq 0x8480
sarq $0x5, %r14
leal -0x12(,%r14,2), %r15d
movq %rax, %rdi
movl %r15d, %esi
callq 0x8840
movq %rax, %rdi
callq 0x8230
addq $-0x8, %r14
andl $0x0, 0x2e8(%rsp)
leaq 0x1d0(%rsp), %rdi
movq %r14, %rsi
leaq 0x2e8(%rsp), %rdx
callq 0x44dfe
movq 0x88(%rsp), %rsi
movl $0xa0, %eax
addq %rax, %rsi
leaq 0x2c8(%rsp), %r14
movq %r14, %rdi
callq 0x8600
movq %r14, %rdi
callq 0x402aa
cvttsd2si %xmm0, %eax
movl %eax, 0xa0(%rsp)
movq %r14, %rdi
callq 0x8978
leaq 0x2e8(%rsp), %r14
movq %r14, %rdi
leaq 0x88(%rsp), %rsi
callq 0x40d83
leaq 0xa8(%rsp), %rdi
movq %r14, %rsi
callq 0x4e5f6
movq %r14, %rdi
callq 0x289b4
cmpb $0x1, 0x90ca9(%rip)     # 0xde2e8
jne 0x4d708
movsd 0x100(%rsp), %xmm0
movq 0x80(%rsp), %rdi
callq 0x8750
movq %rax, %rdi
callq 0x8230
movl 0xb0(%rsp), %esi
movq 0x78(%rsp), %rdi
callq 0x8840
movq %rax, %rdi
callq 0x8230
cmpq $0x0, 0xc0(%rsp)
leaq 0xb8(%rsp), %rsi
jne 0x4d6a2
cmpq $0x0, 0xe0(%rsp)
leaq 0xd8(%rsp), %rsi
je 0x4d6b4
movq 0x68(%rsp), %rdi
callq 0x8430
movq %rax, %rdi
callq 0x8230
movsd 0xf8(%rsp), %xmm0
movsd 0x48adb(%rip), %xmm1    # 0x961a0
ucomisd %xmm0, %xmm1
jbe 0x4d6dd
movq 0x50(%rsp), %rdi
callq 0x8750
movq %rax, %rdi
callq 0x8230
movl 0xa0(%rsp), %esi
movq 0x70(%rsp), %rdi
callq 0x8840
movq %rax, %rdi
callq 0x8230
cmpl $0xf423f, %r13d         # imm = 0xF423F
jl 0x4d8cf
jmp 0x4e1c7
cmpb $0x0, 0x90be6(%rip)     # 0xde2f5
je 0x4d71b
movb $0x1, 0x1a8(%rsp)
jmp 0x4d73b
movq 0x88(%rsp), %rdi
subq $-0x80, %rdi
callq 0x41f35
movb %al, 0x1a8(%rsp)
testb %al, %al
je 0x4d8c0
movl 0xa0(%rsp), %eax
cmpl 0x8fe08(%rip), %eax     # 0xdd550
jge 0x4d752
movb $0x0, 0xa4(%rsp)
movl 0xb0(%rsp), %eax
cmpl 0x90b8d(%rip), %eax     # 0xde2ec
setge %cl
cmpl 0x8fdec(%rip), %eax     # 0xdd554
setle %al
andb %cl, %al
movb %al, 0xa5(%rsp)
cmpq $0x0, 0xc0(%rsp)
je 0x4d7d6
leaq 0x2a8(%rsp), %rdi
leaq 0xb8(%rsp), %rsi
callq 0x8600
leaq 0x2a8(%rsp), %r14
movq %r14, %rdi
callq 0x402aa
movsd %xmm0, 0x60(%rsp)
movsd 0x8fdb6(%rip), %xmm0    # 0xdd568
movsd %xmm0, 0x58(%rsp)
movq %r14, %rdi
callq 0x8978
movsd 0x60(%rsp), %xmm0
ucomisd 0x58(%rsp), %xmm0
jbe 0x4d7d6
movb $0x0, 0xa6(%rsp)
cmpq $0x0, 0xe0(%rsp)
je 0x4d838
leaq 0x288(%rsp), %rdi
leaq 0xd8(%rsp), %rsi
callq 0x8600
leaq 0x288(%rsp), %r14
movq %r14, %rdi
callq 0x402aa
movsd %xmm0, 0x60(%rsp)
movsd 0x90ae4(%rip), %xmm0    # 0xde2f8
movsd %xmm0, 0x58(%rsp)
movq %r14, %rdi
callq 0x8978
movsd 0x58(%rsp), %xmm0
ucomisd 0x60(%rsp), %xmm0
jbe 0x4d838
movb $0x0, 0xa6(%rsp)
movsd 0x8fd30(%rip), %xmm0    # 0xdd570
ucomisd 0x100(%rsp), %xmm0
jbe 0x4d853
movb $0x0, 0xa7(%rsp)
movl 0xa8(%rsp), %eax
movl 0x8fcf8(%rip), %ecx     # 0xdd558
cmpl %ecx, %eax
jl 0x4d8ba
movl %r15d, %edx
subl %ecx, %edx
cmpl %edx, %eax
jg 0x4d8ba
cmpb $0x1, 0xa7(%rsp)
jne 0x4d8f1
cmpb $0x1, 0xa5(%rsp)
jne 0x4d919
cmpb $0x1, 0xa4(%rsp)
jne 0x4d94a
cmpb $0x1, 0xa6(%rsp)
jne 0x4d94a
movq 0x8f710(%rip), %rdi     # 0xdcfb8
movq %rbp, %rsi
callq 0x8430
movq %rax, %rdi
callq 0x8230
jmp 0x4d8cf
incl 0x4c(%rsp)
jmp 0x4d8cf
movb $0x0, 0x1a8(%rsp)
incl (%rsp)
incl 0x48(%rsp)
leaq 0x88(%rsp), %rdi
callq 0x28a08
leaq 0xa8(%rsp), %rdi
callq 0x289b4
movb $0x1, %r14b
jmp 0x4d486
incl (%rsp)
movb 0xa4(%rsp), %al
cmpb $0x1, 0xa5(%rsp)
jne 0x4d936
testb %al, %al
je 0x4d96e
cmpb $0x1, 0xa6(%rsp)
jne 0x4d96e
incl 0x44(%rsp)
jmp 0x4d8cf
incl (%rsp)
cmpb $0x1, 0xa4(%rsp)
jne 0x4d993
cmpb $0x1, 0xa6(%rsp)
jne 0x4d993
incl 0x40(%rsp)
jmp 0x4d8cf
testb %al, %al
je 0x4d9b8
cmpb $0x1, 0xa6(%rsp)
jne 0x4d9b8
incl 0x3c(%rsp)
jmp 0x4d8cf
incl (%rsp)
cmpb $0x0, 0xa4(%rsp)
jne 0x4d9dd
cmpb $0x1, 0xa6(%rsp)
jne 0x4d9dd
incl 0x38(%rsp)
jmp 0x4d8cf
cmpb $0x0, 0xa4(%rsp)
jne 0x4da17
cmpb $0x1, 0xa6(%rsp)
jne 0x4da17
incl 0x18(%rsp)
jmp 0x4d8cf
cmpb $0x0, 0xa4(%rsp)
jne 0x4da51
cmpb $0x1, 0xa6(%rsp)
jne 0x4da51
incl 0x1c(%rsp)
jmp 0x4d8cf
cmpb $0x0, 0xa4(%rsp)
jne 0x4da87
cmpb $0x1, 0xa6(%rsp)
jne 0x4da87
incl 0x20(%rsp)
jmp 0x4d8cf
cmpb $0x1, 0xa4(%rsp)
jne 0x4d9f5
cmpb $0x0, 0xa6(%rsp)
je 0x4dabd
cmpb $0x0, 0xa4(%rsp)
jne 0x4d8cf
movzbl 0xa6(%rsp), %eax
xorl $0x1, %eax
addl %eax, 0x24(%rsp)
jmp 0x4d8cf
cmpb $0x1, 0xa4(%rsp)
jne 0x4da2f
cmpb $0x0, 0xa6(%rsp)
je 0x4dac6
cmpb $0x0, 0xa4(%rsp)
jne 0x4d8cf
movzbl 0xa6(%rsp), %eax
xorl $0x1, %eax
addl %eax, 0x28(%rsp)
jmp 0x4d8cf
cmpb $0x1, 0xa4(%rsp)
jne 0x4da65
cmpb $0x0, 0xa6(%rsp)
je 0x4dacf
cmpb $0x0, 0xa4(%rsp)
jne 0x4d8cf
movzbl 0xa6(%rsp), %eax
xorl $0x1, %eax
addl %eax, 0x2c(%rsp)
jmp 0x4d8cf
cmpb $0x1, 0xa4(%rsp)
jne 0x4da9b
cmpb $0x0, 0xa6(%rsp)
je 0x4dad8
cmpb $0x0, 0xa4(%rsp)
jne 0x4d8cf
movzbl 0xa6(%rsp), %eax
xorl $0x1, %eax
addl %eax, 0x30(%rsp)
jmp 0x4d8cf
incl 0x34(%rsp)
jmp 0x4d8cf
incl 0x10(%rsp)
jmp 0x4d8cf
incl 0xc(%rsp)
jmp 0x4d8cf
incl 0x14(%rsp)
jmp 0x4d8cf
movq 0x8f500(%rip), %rdi     # 0xdcfe8
leaq 0x53c6c(%rip), %rsi     # 0xa175b
callq 0x8480
movl 0x44(%rsp), %ebx
movl 0x40(%rsp), %ebp
movl 0x34(%rsp), %r14d
movl 0x38(%rsp), %r15d
movl 0x3c(%rsp), %r12d
movq %rax, %rdi
movl (%rsp), %esi
callq 0x8840
movq %rax, %rdi
callq 0x8230
movq 0x8f4c3(%rip), %rdi     # 0xdcfe8
leaq 0x53c4d(%rip), %rsi     # 0xa1779
callq 0x8480
movq %rax, %rdi
callq 0x8230
movq 0x8f4a8(%rip), %rdi     # 0xdcfe8
leaq 0x53c49(%rip), %rsi     # 0xa1790
callq 0x8480
movq %rax, %rdi
movl 0x48(%rsp), %esi
callq 0x8840
movq %rax, %rdi
callq 0x8230
movq 0x8f481(%rip), %rdi     # 0xdcfe8
leaq 0x53c32(%rip), %rsi     # 0xa17a0
callq 0x8480
movq %rax, %rdi
movl 0x4c(%rsp), %esi
callq 0x8840
movq %rax, %rdi
callq 0x8230
movq 0x8f45a(%rip), %rdi     # 0xdcfe8
leaq 0x53c3b(%rip), %rsi     # 0xa17d0
callq 0x8480
movq %rax, %rdi
callq 0x8230
movq 0x8f43f(%rip), %rdi     # 0xdcfe8
leaq 0x53c2f(%rip), %rsi     # 0xa17df
callq 0x8480
movq %rax, %rdi
callq 0x8230
movq 0x8f424(%rip), %rdi     # 0xdcfe8
leaq 0x53c6b(%rip), %rsi     # 0xa1836
callq 0x8480
movq %rax, %rdi
movl 0x30(%rsp), %esi
callq 0x8840
leaq 0x53c60(%rip), %rsi     # 0xa1843
movq %rax, %rdi
callq 0x8480
cvtsi2sdl 0x30(%rsp), %xmm0
cvtsi2sdl (%rsp), %xmm1
movsd %xmm1, (%rsp)
divsd %xmm1, %xmm0
mulsd 0x50eb1(%rip), %xmm0    # 0x9eab8
movq %rax, %rdi
callq 0x8750
leaq 0x59e06(%rip), %rsi     # 0xa7a1c
movq %rax, %rdi
callq 0x8480
movq %rax, %rdi
callq 0x8230
movq 0x8f3bb(%rip), %rdi     # 0xdcfe8
leaq 0x53c12(%rip), %rsi     # 0xa1846
callq 0x8480
movq %rax, %rdi
movl 0x20(%rsp), %esi
callq 0x8840
leaq 0x53bf7(%rip), %rsi     # 0xa1843
movq %rax, %rdi
callq 0x8480
cvtsi2sdl 0x20(%rsp), %xmm0
divsd (%rsp), %xmm0
mulsd 0x50e51(%rip), %xmm0    # 0x9eab8
movq %rax, %rdi
callq 0x8750
leaq 0x59da6(%rip), %rsi     # 0xa7a1c
movq %rax, %rdi
callq 0x8480
movq %rax, %rdi
callq 0x8230
movq 0x8f35b(%rip), %rdi     # 0xdcfe8
leaq 0x53bbd(%rip), %rsi     # 0xa1851
callq 0x8480
movq %rax, %rdi
movl 0x2c(%rsp), %esi
callq 0x8840
leaq 0x53b97(%rip), %rsi     # 0xa1843
movq %rax, %rdi
callq 0x8480
cvtsi2sdl 0x2c(%rsp), %xmm0
divsd (%rsp), %xmm0
mulsd 0x50df1(%rip), %xmm0    # 0x9eab8
movq %rax, %rdi
callq 0x8750
leaq 0x59d46(%rip), %rsi     # 0xa7a1c
movq %rax, %rdi
callq 0x8480
movq %rax, %rdi
callq 0x8230
movq 0x8f2fb(%rip), %rdi     # 0xdcfe8
leaq 0x53b69(%rip), %rsi     # 0xa185d
callq 0x8480
movq %rax, %rdi
movl 0x28(%rsp), %esi
callq 0x8840
leaq 0x53b37(%rip), %rsi     # 0xa1843
movq %rax, %rdi
callq 0x8480
cvtsi2sdl 0x28(%rsp), %xmm0
divsd (%rsp), %xmm0
mulsd 0x50d91(%rip), %xmm0    # 0x9eab8
movq %rax, %rdi
callq 0x8750
leaq 0x59ce6(%rip), %rsi     # 0xa7a1c
movq %rax, %rdi
callq 0x8480
movq %rax, %rdi
callq 0x8230
movq 0x8f29b(%rip), %rdi     # 0xdcfe8
leaq 0x53b14(%rip), %rsi     # 0xa1868
callq 0x8480
movq %rax, %rdi
movl 0x14(%rsp), %esi
callq 0x8840
leaq 0x53ad7(%rip), %rsi     # 0xa1843
movq %rax, %rdi
callq 0x8480
cvtsi2sdl 0x14(%rsp), %xmm0
divsd (%rsp), %xmm0
mulsd 0x50d31(%rip), %xmm0    # 0x9eab8
movq %rax, %rdi
callq 0x8750
leaq 0x59c86(%rip), %rsi     # 0xa7a1c
movq %rax, %rdi
callq 0x8480
movq %rax, %rdi
callq 0x8230
movq 0x8f23b(%rip), %rdi     # 0xdcfe8
leaq 0x53abf(%rip), %rsi     # 0xa1873
callq 0x8480
movq %rax, %rdi
movl 0x1c(%rsp), %esi
callq 0x8840
leaq 0x53a77(%rip), %rsi     # 0xa1843
movq %rax, %rdi
callq 0x8480
cvtsi2sdl 0x1c(%rsp), %xmm0
divsd (%rsp), %xmm0
mulsd 0x50cd1(%rip), %xmm0    # 0x9eab8
movq %rax, %rdi
callq 0x8750
leaq 0x59c26(%rip), %rsi     # 0xa7a1c
movq %rax, %rdi
callq 0x8480
movq %rax, %rdi
callq 0x8230
movq 0x8f1db(%rip), %rdi     # 0xdcfe8
leaq 0x53a68(%rip), %rsi     # 0xa187c
callq 0x8480
movq %rax, %rdi
movl 0x18(%rsp), %esi
callq 0x8840
leaq 0x53a17(%rip), %rsi     # 0xa1843
movq %rax, %rdi
callq 0x8480
cvtsi2sdl 0x18(%rsp), %xmm0
divsd (%rsp), %xmm0
mulsd 0x50c71(%rip), %xmm0    # 0x9eab8
movq %rax, %rdi
callq 0x8750
leaq 0x59bc6(%rip), %rsi     # 0xa7a1c
movq %rax, %rdi
callq 0x8480
movq %rax, %rdi
callq 0x8230
movq 0x8f17b(%rip), %rdi     # 0xdcfe8
leaq 0x53a10(%rip), %rsi     # 0xa1884
callq 0x8480
movq %rax, %rdi
movl 0x24(%rsp), %esi
callq 0x8840
leaq 0x539b7(%rip), %rsi     # 0xa1843
movq %rax, %rdi
callq 0x8480
cvtsi2sdl 0x24(%rsp), %xmm0
divsd (%rsp), %xmm0
mulsd 0x50c11(%rip), %xmm0    # 0x9eab8
movq %rax, %rdi
callq 0x8750
leaq 0x59b66(%rip), %rsi     # 0xa7a1c
movq %rax, %rdi
callq 0x8480
movq %rax, %rdi
callq 0x8230
movq 0x8f11b(%rip), %rdi     # 0xdcfe8
leaq 0x5398c(%rip), %rsi     # 0xa1860
callq 0x8480
movq %rax, %rdi
movl 0x10(%rsp), %esi
callq 0x8840
leaq 0x53957(%rip), %rsi     # 0xa1843
movq %rax, %rdi
callq 0x8480
cvtsi2sdl 0x10(%rsp), %xmm0
divsd (%rsp), %xmm0
mulsd 0x50bb1(%rip), %xmm0    # 0x9eab8
movq %rax, %rdi
callq 0x8750
leaq 0x59b06(%rip), %rsi     # 0xa7a1c
movq %rax, %rdi
callq 0x8480
movq %rax, %rdi
callq 0x8230
movq 0x8f0bb(%rip), %rdi     # 0xdcfe8
leaq 0x53959(%rip), %rsi     # 0xa188d
callq 0x8480
movq %rax, %rdi
movl 0xc(%rsp), %esi
callq 0x8840
leaq 0x538f7(%rip), %rsi     # 0xa1843
movq %rax, %rdi
callq 0x8480
cvtsi2sdl 0xc(%rsp), %xmm0
divsd (%rsp), %xmm0
mulsd 0x50b51(%rip), %xmm0    # 0x9eab8
movq %rax, %rdi
callq 0x8750
leaq 0x59aa6(%rip), %rsi     # 0xa7a1c
movq %rax, %rdi
callq 0x8480
movq %rax, %rdi
callq 0x8230
movq 0x8f05b(%rip), %rdi     # 0xdcfe8
leaq 0x538d7(%rip), %rsi     # 0xa186b
callq 0x8480
movq %rax, %rdi
movl %r12d, %esi
callq 0x8840
leaq 0x53898(%rip), %rsi     # 0xa1843
movq %rax, %rdi
callq 0x8480
cvtsi2sd %r12d, %xmm0
divsd (%rsp), %xmm0
mulsd 0x50af3(%rip), %xmm0    # 0x9eab8
movq %rax, %rdi
callq 0x8750
leaq 0x59a48(%rip), %rsi     # 0xa7a1c
movq %rax, %rdi
callq 0x8480
movq %rax, %rdi
callq 0x8230
movq 0x8effd(%rip), %rdi     # 0xdcfe8
leaq 0x538a4(%rip), %rsi     # 0xa1896
callq 0x8480
movq %rax, %rdi
movl %r15d, %esi
callq 0x8840
leaq 0x5383a(%rip), %rsi     # 0xa1843
movq %rax, %rdi
callq 0x8480
cvtsi2sd %r15d, %xmm0
divsd (%rsp), %xmm0
mulsd 0x50a95(%rip), %xmm0    # 0x9eab8
movq %rax, %rdi
callq 0x8750
leaq 0x599ea(%rip), %rsi     # 0xa7a1c
movq %rax, %rdi
callq 0x8480
movq %rax, %rdi
callq 0x8230
movq 0x8ef9f(%rip), %rdi     # 0xdcfe8
leaq 0x53807(%rip), %rsi     # 0xa1857
callq 0x8480
movq %rax, %rdi
movl %r14d, %esi
callq 0x8840
leaq 0x537dc(%rip), %rsi     # 0xa1843
movq %rax, %rdi
callq 0x8480
cvtsi2sd %r14d, %xmm0
divsd (%rsp), %xmm0
mulsd 0x50a37(%rip), %xmm0    # 0x9eab8
movq %rax, %rdi
callq 0x8750
leaq 0x5998c(%rip), %rsi     # 0xa7a1c
movq %rax, %rdi
callq 0x8480
movq %rax, %rdi
callq 0x8230
movq 0x8ef41(%rip), %rdi     # 0xdcfe8
leaq 0x537e2(%rip), %rsi     # 0xa1890
callq 0x8480
movq %rax, %rdi
movl %ebp, %esi
callq 0x8840
leaq 0x5377f(%rip), %rsi     # 0xa1843
movq %rax, %rdi
callq 0x8480
cvtsi2sd %ebp, %xmm0
divsd (%rsp), %xmm0
mulsd 0x509db(%rip), %xmm0    # 0x9eab8
movq %rax, %rdi
callq 0x8750
leaq 0x59930(%rip), %rsi     # 0xa7a1c
movq %rax, %rdi
callq 0x8480
movq %rax, %rdi
callq 0x8230
movq 0x8eee5(%rip), %rdi     # 0xdcfe8
leaq 0x53759(%rip), %rsi     # 0xa1863
callq 0x8480
movq %rax, %rdi
movl %ebx, %esi
callq 0x8840
leaq 0x53723(%rip), %rsi     # 0xa1843
movq %rax, %rdi
callq 0x8480
cvtsi2sd %ebx, %xmm0
divsd (%rsp), %xmm0
mulsd 0x5097f(%rip), %xmm0    # 0x9eab8
movq %rax, %rdi
callq 0x8750
leaq 0x598d4(%rip), %rsi     # 0xa7a1c
movq %rax, %rdi
callq 0x8480
movq %rax, %rdi
callq 0x8230
leaq 0x268(%rsp), %rdi
callq 0x8978
leaq 0x210(%rsp), %rdi
callq 0x3b73c
leaq 0x1d0(%rsp), %rdi
callq 0x2aef2
leaq 0x230(%rsp), %rdi
callq 0x2aef2
leaq 0x250(%rsp), %rdi
callq 0x2aef2
leaq 0x1b0(%rsp), %rdi
callq 0x8978
leaq 0x1f0(%rsp), %rdi
callq 0x8978
xorl %eax, %eax
addq $0x3e8, %rsp            # imm = 0x3E8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
xorl %edi, %edi
callq 0x8540
movq %rax, %rbx
leaq 0xa0(%rsp), %rdi
callq 0x8978
jmp 0x4e1e3
movq %rax, %rbx
movl $0x200, %esi            # imm = 0x200
movq 0x50(%rsp), %rdi
jmp 0x4e277
movq %rax, %rbx
leaq 0xa0(%rsp), %rdi
callq 0x8978
jmp 0x4e207
movq %rax, %rbx
movl $0x200, %esi            # imm = 0x200
movq 0x70(%rsp), %rdi
jmp 0x4e277
movq %rax, %rbx
leaq 0xa0(%rsp), %rdi
callq 0x8978
jmp 0x4e228
movq %rax, %rbx
movl $0x200, %esi            # imm = 0x200
movq 0x68(%rsp), %rdi
jmp 0x4e277
movq %rax, %rbx
leaq 0xa0(%rsp), %rdi
callq 0x8978
jmp 0x4e249
movq %rax, %rbx
movl $0x200, %esi            # imm = 0x200
movq 0x78(%rsp), %rdi
jmp 0x4e277
movq %rax, %rbx
leaq 0xa0(%rsp), %rdi
callq 0x8978
jmp 0x4e26a
movq %rax, %rbx
movl $0x200, %esi            # imm = 0x200
movq 0x80(%rsp), %rdi
callq 0x84a0
jmp 0x4e309
movq %rax, %rbx
leaq 0xa0(%rsp), %rdi
jmp 0x4e304
jmp 0x4e2d3
movq %rax, %rbx
jmp 0x4e34a
movq %rax, %rbx
leaq 0x2a8(%rsp), %rdi
jmp 0x4e2c6
movq %rax, %rbx
leaq 0x288(%rsp), %rdi
jmp 0x4e2c6
jmp 0x4e2d8
movq %rax, %rbx
jmp 0x4e2e8
jmp 0x4e2f9
movq %rax, %rbx
leaq 0x2c8(%rsp), %rdi
callq 0x8978
jmp 0x4e2db
jmp 0x4e2d8
jmp 0x4e2f9
jmp 0x4e2d8
movq %rax, %rbx
jmp 0x4e309
movq %rax, %rbx
leaq 0x88(%rsp), %rdi
callq 0x28a08
leaq 0xa8(%rsp), %rdi
callq 0x289b4
jmp 0x4e2fc
jmp 0x4e2f9
movq %rax, %rbx
leaq 0x268(%rsp), %rdi
callq 0x8978
leaq 0x210(%rsp), %rdi
callq 0x3b73c
leaq 0x1d0(%rsp), %rdi
callq 0x2aef2
leaq 0x230(%rsp), %rdi
callq 0x2aef2
leaq 0x250(%rsp), %rdi
callq 0x2aef2
leaq 0x1b0(%rsp), %rdi
callq 0x8978
leaq 0x1f0(%rsp), %rdi
callq 0x8978
movq %rbx, %rdi
callq 0x8870