// File: /workspace/github_cpp_makefile_star2_O1/brc7[P]DiversitySampling/targets/samplerace.cpp
// Function: main
int main(int argc, char **argv){

    if (argc < 4){
        std::clog<<"Usage: "<<std::endl; 
        std::clog<<"samplerace <tau> <format> <input> <output>"; 
        std::clog<<" [--range race_range] [--reps race_reps] [--hashes n_minhashes] [-k kmer_size]"<<std::endl; 
        std::clog<<"Positional arguments: "<<std::endl; 
        std::clog<<"tau: floating point RACE sampling threshold. Roughly determines how many samples you will store. You may specify this in scientific notation (i.e. 10e-6)"<<std::endl; 
        std::clog<<"format: Either PE, SE, or I for paired-end, single-end, and interleaved paired reads"<<std::endl; 
        std::clog<<"input: path to input data file (.fastq or .fasta extension). For PE format, specify two files."<<std::endl; 
        std::clog<<"output: path to output sample file (same extension as input). For PE format, specify two files."<<std::endl; 
        
        std::clog<<"Optional arguments: "<<std::endl; 
        std::clog<<"[--range race_range]: (Optional, default 10000) Hash range for each ACE (B)"<<std::endl;
        std::clog<<"[--reps race_reps]: (Optional, default 10) Number of ACE repetitions (R)"<<std::endl;
        std::clog<<"[--hashes n_minhashes]: (Optional, default 1) Number of MinHashes for each ACE (n)"<<std::endl;
        std::clog<<"[--k kmer_size]: (Optional, default 16) Size of each MinHash k-mer (k)"<<std::endl;

        std::clog<<std::endl<<"Example usage:"<<std::endl; 
        std::clog<<"samplerace 15.0 PE data/input-1.fastq data/input-2.fastq data/output-1.fastq data/output-2.fastq --range 100 --reps 50 --hashes 3 --k 5"<<std::endl; 
        std::clog<<"samplerace 10e-6 SE data/input.fastq data/output.fastq --range 100 --reps 5 --hashes 1 --k 33"<<std::endl; 
        std::clog<<"samplerace 0.1 SE data/input.fasta data/output.fasta --range 100000 --k 20"<<std::endl; 
        return -1; 
    }


    // POSITIONAL ARGUMENTS
    double tau = std::stod(argv[1]);
    int format; // ENUM: 1 = unpaired, 2 = interleaved, 3 = paired
    if (std::strcmp("SE",argv[2]) == 0){
        format = 1;
    } else if (std::strcmp("I",argv[2]) == 0){
        format = 2; 
    } else if (std::strcmp("PE",argv[2]) == 0){
        format = 3; 
        if (argc < 7){
            std::cerr<<"For paired-end reads, please specify the input and output files as:"<<std::endl; 
            std::cerr<<"input1.fastq input2.fastq output1.fastq output2.fastq"<<std::endl; 
            return -1; 
        }
    } else {
        std::cerr<<"Invalid format, please specify either SE, PE, or I"<<std::endl; 
        return -1;
    }

    // open the correct file streams given the format
    std::ifstream datastream1;
    std::ofstream samplestream1;
    std::ifstream datastream2;
    std::ofstream samplestream2;

    if (format != 3){
        datastream1.open(argv[3]);
        samplestream1.open(argv[4]);
    } else {
        datastream1.open(argv[3]);
        datastream2.open(argv[4]);
        samplestream1.open(argv[5]);
        samplestream2.open(argv[6]);
    }

    // determine file extension
    std::string filename(argv[3]); 
    std::string file_extension = "";
    size_t idx = filename.rfind('.',filename.length()); 
    if (file_extension == "fq"){
        file_extension = "fastq"; 
    }
    if (idx != std::string::npos){
        file_extension = filename.substr(idx+1, filename.length() - idx); 
    } else {
        std::cerr<<"Input file does not appear to have any file extension."<<std::endl; 
        return -1; 
    }
    if (file_extension != "fasta" && file_extension != "fastq"){
        std::cerr<<"Unknown file extension: "<<file_extension<<std::endl; 
        std::cerr<<"Please specify either a file with the .fasta or .fastq extension."<<std::endl; 
        return -1; 
    }

    // OPTIONAL ARGUMENTS
    int race_range = 10000;
    int race_repetitions = 10;
    int hash_power = 1;
    int kmer_k = 16;

    for (int i = 0; i < argc; ++i){
        if (std::strcmp("--range",argv[i]) == 0){
            if ((i+1) < argc){
                race_range = std::stoi(argv[i+1]);
            } else {
                std::cerr<<"Invalid argument for optional parameter --range"<<std::endl; 
                return -1;
            }
        }
        if (std::strcmp("--reps",argv[i]) == 0){
            if ((i+1) < argc){
                race_repetitions = std::stoi(argv[i+1]);
            } else {
                std::cerr<<"Invalid argument for optional parameter --reps"<<std::endl; 
                return -1;
            }
        }
        if (std::strcmp("--hashes",argv[i]) == 0){
            if ((i+1) < argc){
                hash_power = std::stoi(argv[i+1]);
            } else {
                std::cerr<<"Invalid argument for optional parameter --hashes"<<std::endl; 
                return -1;
            }
        }
        if (std::strcmp("--k",argv[i]) == 0){
            if ((i+1) < argc){
                kmer_k = std::stoi(argv[i+1]);
            } else {
                std::cerr<<"Invalid argument for optional parameter --k"<<std::endl; 
                return -1;
            }
        }
    }

    // Check if arguments are valid
    if (tau <= 0){ std::cerr<<"Invalid value for parameter <tau>"<<std::endl; return -1; }
    if (race_range <= 0){ std::cerr<<"Invalid value for optional parameter --range"<<std::endl; return -1; }
    if (race_repetitions <= 0){ std::cerr<<"Invalid value for optional parameter --reps"<<std::endl; return -1; }
    if (hash_power <= 0){ std::cerr<<"Invalid value for optional parameter --hashes"<<std::endl; return -1; }
    if (kmer_k <= 0){ std::cerr<<"Invalid value for optional parameter --k"<<std::endl; return -1; }

    // done parsing information. Begin RACE algorithm: 

    // buffer for sequences and fasta/fastq chunks
    std::string sequence;
    std::string chunk1;
    std::string chunk2;

    // set up the hash function that will be used to hash input sequences
    SequenceMinHash hash = SequenceMinHash(race_repetitions*hash_power);
    int* raw_hashes = new int[race_repetitions*hash_power]; 
    int* rehashes = new int[race_repetitions];

    RACE sketch = RACE(race_repetitions,race_range); 

    do{
        bool success = false; 
        int c = datastream1.peek(); 
        if (c == EOF) {
            if (datastream1.eof()){
                continue; 
            }
        }

        switch(format){
            case 1: // 1 = unpaired
            success = SequenceFeaturesSE(datastream1, sequence, chunk1, file_extension);
            break; 
            case 2: // 2 = interleaved
            success = SequenceFeaturesI(datastream1, sequence, chunk1, file_extension); 
            break; 
            case 3: // 3 = paired
            success = SequenceFeaturesPE(datastream1, datastream2, sequence, chunk1, chunk2, file_extension);
            break; 
        }
        if (!success) continue;

        hash.getHash(kmer_k, sequence, raw_hashes); 
        // now that we have the sequence and label
        // feed the sequence into the RACE structure
        // first rehash so that the arrays can fit into RACE
        rehash(raw_hashes, rehashes, race_repetitions, hash_power);
        // then simultaneously query and add 
        double KDE = sketch.query_and_add(rehashes); 
        // note: KDE is on a scale from [0,N] not the normalized interval [0,1]
        if (KDE < tau){
            // then keep this sample
            
            switch(format){
                case 1: // 1 = unpaired
                samplestream1 << chunk1; 
                break; 
                case 2: // 2 = interleaved
                samplestream1 << chunk1; 
                break; 
                case 3: // 3 = paired
                samplestream1 << chunk1; 
                samplestream2 << chunk2; 
                break; 
            }
        }
    }
    while(datastream1);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x978, %rsp            # imm = 0x978
cmpl $0x3, %edi
jg 0x39e1
movq 0x49cf(%rip), %rbx      # 0x7fb8
leaq 0x1bf0(%rip), %rsi      # 0x51e0
movl $0x7, %edx
movq %rbx, %rdi
callq 0x21c0
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2180
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
leaq 0x1bbd(%rip), %rsi      # 0x51e8
movl $0x2a, %edx
movq %rbx, %rdi
callq 0x21c0
leaq 0x1bd4(%rip), %rsi      # 0x5213
movl $0x4e, %edx
movq %rbx, %rdi
callq 0x21c0
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2180
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
leaq 0x1be8(%rip), %rsi      # 0x5262
movl $0x16, %edx
movq %rbx, %rdi
callq 0x21c0
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2180
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
leaq 0x1bc4(%rip), %rsi      # 0x5279
movl $0x99, %edx
movq %rbx, %rdi
callq 0x21c0
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2180
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
leaq 0x1c23(%rip), %rsi      # 0x5313
movl $0x54, %edx
movq %rbx, %rdi
callq 0x21c0
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2180
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
leaq 0x1c3d(%rip), %rsi      # 0x5368
movl $0x5e, %edx
movq %rbx, %rdi
callq 0x21c0
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2180
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
leaq 0x1c61(%rip), %rsi      # 0x53c7
movl $0x5f, %edx
movq %rbx, %rdi
callq 0x21c0
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2180
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
leaq 0x1c86(%rip), %rsi      # 0x5427
movl $0x14, %edx
movq %rbx, %rdi
callq 0x21c0
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2180
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
leaq 0x1c60(%rip), %rsi      # 0x543c
movl $0x4b, %edx
movq %rbx, %rdi
callq 0x21c0
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2180
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
leaq 0x1c71(%rip), %rsi      # 0x5488
movl $0x48, %edx
movq %rbx, %rdi
callq 0x21c0
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2180
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
leaq 0x1c7f(%rip), %rsi      # 0x54d1
movl $0x52, %edx
movq %rbx, %rdi
callq 0x21c0
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2180
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
leaq 0x1c97(%rip), %rsi      # 0x5524
movl $0x46, %edx
movq %rbx, %rdi
callq 0x21c0
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2180
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2180
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
movq %rax, %r14
leaq 0x1c79(%rip), %rsi      # 0x556b
movl $0xe, %edx
movq %rax, %rdi
callq 0x21c0
movq (%r14), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x2180
movsbl %al, %esi
movq %r14, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
leaq 0x1c4d(%rip), %rsi      # 0x557a
movl $0x87, %edx
movq %rbx, %rdi
callq 0x21c0
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2180
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
leaq 0x1c9a(%rip), %rsi      # 0x5602
movl $0x5d, %edx
movq %rbx, %rdi
callq 0x21c0
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2180
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
leaq 0x1cbd(%rip), %rsi      # 0x5660
movl $0x4a, %edx
movq %rbx, %rdi
callq 0x21c0
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2180
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
jmp 0x4719
movq %rsi, %rbx
movq %rdi, %r13
movq 0x8(%rsi), %rsi
leaq 0x168(%rsp), %rdi
leaq 0x370(%rsp), %rdx
callq 0x499a
movq 0x168(%rsp), %r15
callq 0x2050
movq %rax, %rbp
movl (%rax), %r14d
movl $0x0, (%rax)
leaq 0x770(%rsp), %r12
movq %r15, %rdi
movq %r12, %rsi
callq 0x2140
movsd %xmm0, 0xb8(%rsp)
cmpq %r15, (%r12)
je 0x478d
movl (%rbp), %eax
testl %eax, %eax
je 0x3a57
cmpl $0x22, %eax
jne 0x3a5b
leaq 0x1f2f(%rip), %rdi      # 0x5981
callq 0x2240
movl %r14d, (%rbp)
leaq 0x178(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x3a7c
movq 0x178(%rsp), %rsi
incq %rsi
callq 0x2190
movq 0x10(%rbx), %r15
leaq 0x1c24(%rip), %rdi      # 0x56ab
movq %r15, %rsi
callq 0x2220
testl %eax, %eax
je 0x3ad5
leaq 0x1cc2(%rip), %rdi      # 0x575c
movq %r15, %rsi
callq 0x2220
testl %eax, %eax
je 0x3add
leaq 0x1c01(%rip), %rdi      # 0x56ae
movq %r15, %rsi
callq 0x2220
testl %eax, %eax
je 0x4092
movq 0x452c(%rip), %rbx      # 0x7ff0
leaq 0x1c60(%rip), %rsi      # 0x572b
movl $0x32, %edx
jmp 0x39a8
movl $0x1, %r12d
jmp 0x3ae3
movl $0x2, %r12d
xorl %r14d, %r14d
leaq 0x168(%rsp), %rdi
callq 0x21b0
leaq 0x370(%rsp), %r15
movq %r15, %rdi
callq 0x2280
leaq 0x770(%rsp), %rdi
callq 0x21b0
leaq 0x570(%rsp), %rdi
callq 0x2280
movq 0x18(%rbx), %rsi
testb %r14b, %r14b
je 0x3b74
leaq 0x168(%rsp), %rdi
movl $0x8, %edx
callq 0x2100
movq 0x20(%rbx), %rsi
leaq 0x770(%rsp), %rdi
movl $0x8, %edx
callq 0x2100
movq 0x28(%rbx), %rsi
leaq 0x370(%rsp), %rdi
movl $0x10, %edx
callq 0x2060
leaq 0x570(%rsp), %r15
movl $0x30, %r14d
jmp 0x3b8c
movl $0x20, %r14d
leaq 0x168(%rsp), %rdi
movl $0x8, %edx
callq 0x2100
movq (%rbx,%r14), %rsi
movq %r15, %rdi
movl $0x10, %edx
callq 0x2060
movq 0x18(%rbx), %rsi
leaq 0x128(%rsp), %rdi
leaq 0x20(%rsp), %rdx
callq 0x499a
leaq 0x30(%rsp), %rax
movq %rax, -0x10(%rax)
leaq 0x14f4(%rip), %rdx      # 0x50b7
leaq 0x20(%rsp), %rdi
movq %rdx, %rsi
callq 0x49d8
leaq 0x128(%rsp), %rdi
movq 0x8(%rdi), %rdx
movl $0x2e, %esi
callq 0x22e0
movq %rax, %r15
leaq 0x1b6e(%rip), %rsi      # 0x575e
leaq 0x20(%rsp), %rdi
callq 0x2080
testl %eax, %eax
jne 0x3c1b
leaq 0x20(%rsp), %rdi
movq 0x8(%rdi), %rdx
leaq 0x1b17(%rip), %rcx      # 0x5725
movl $0x5, %r8d
xorl %esi, %esi
callq 0x2270
cmpq $-0x1, %r15
je 0x4042
leaq 0x128(%rsp), %rsi
movq 0x8(%rsi), %rcx
subq %r15, %rcx
incq %r15
movq %rsp, %rdi
movq %r15, %rdx
callq 0x21a0
leaq 0x20(%rsp), %rdi
movq %rsp, %r15
movq %r15, %rsi
callq 0x21e0
movq (%r15), %rdi
leaq 0x10(%rsp), %rax
cmpq %rax, %rdi
je 0x3c6c
movq 0x10(%rsp), %rsi
incq %rsi
callq 0x2190
leaq 0x1391(%rip), %rsi      # 0x5004
leaq 0x20(%rsp), %rdi
callq 0x2080
testl %eax, %eax
je 0x3cff
leaq 0x1a9d(%rip), %rsi      # 0x5725
leaq 0x20(%rsp), %rdi
callq 0x2080
testl %eax, %eax
je 0x3cff
movq 0x4353(%rip), %rdi      # 0x7ff0
leaq 0x1af4(%rip), %rsi      # 0x5798
movl $0x18, %edx
callq 0x21c0
movq 0x20(%rsp), %rsi
movq 0x28(%rsp), %rdx
movq 0x4331(%rip), %rdi      # 0x7ff0
callq 0x21c0
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2180
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
movl $0x41, %edx
leaq 0x1ab7(%rip), %rsi      # 0x57b1
jmp 0x404e
movq %r12, 0xb0(%rsp)
movq %r13, %rdx
movl %edx, %r13d
cmpl $0x2, %edx
movl $0x1, %ecx
movl $0x1, %eax
movq %rax, 0x70(%rsp)
cmovll %ecx, %edx
negq %rdx
movq %rdx, 0x80(%rsp)
movl $0x2710, %eax           # imm = 0x2710
movq %rax, 0x68(%rsp)
movl $0xa, %eax
movq %rax, 0x78(%rsp)
movl $0x10, %eax
movq %rax, 0xc0(%rsp)
movb $0x1, 0x60(%rsp)
movl $0x1, %r14d
movq -0x8(%rbx,%r14,8), %rsi
leaq 0x1b91(%rip), %rdi      # 0x58f6
callq 0x2220
testl %eax, %eax
jne 0x3e08
cmpq %r13, %r14
jae 0x40f9
movq (%rbx,%r14,8), %rsi
movq %rsp, %rdi
leaq 0x90(%rsp), %rdx
callq 0x499a
movq (%rsp), %r12
movl (%rbp), %r15d
movl $0x0, (%rbp)
movq %r12, %rdi
leaq 0x40(%rsp), %rsi
movl $0xa, %edx
callq 0x2230
cmpq %r12, 0x40(%rsp)
je 0x472d
movq %rax, 0x68(%rsp)
addq $-0x80000000, %rax      # imm = 0x80000000
movabsq $-0x100000000, %rcx     # imm = 0xFFFFFFFF00000000
cmpq %rcx, %rax
jb 0x4739
movl (%rbp), %eax
cmpl $0x22, %eax
je 0x4739
testl %eax, %eax
jne 0x3ded
movl %r15d, (%rbp)
movq (%rsp), %rdi
leaq 0x10(%rsp), %rax
cmpq %rax, %rdi
je 0x3e08
movq 0x10(%rsp), %rsi
incq %rsi
callq 0x2190
movq -0x8(%rbx,%r14,8), %rsi
leaq 0x1b0f(%rip), %rdi      # 0x5923
callq 0x2220
testl %eax, %eax
jne 0x3eb7
cmpq %r13, %r14
jae 0x4149
movq (%rbx,%r14,8), %rsi
movq %rsp, %rdi
leaq 0x90(%rsp), %rdx
callq 0x499a
movq (%rsp), %r12
movl (%rbp), %r15d
movl $0x0, (%rbp)
movq %r12, %rdi
leaq 0x40(%rsp), %rsi
movl $0xa, %edx
callq 0x2230
cmpq %r12, 0x40(%rsp)
je 0x4751
movq %rax, 0x78(%rsp)
addq $-0x80000000, %rax      # imm = 0x80000000
movabsq $-0x100000000, %rcx     # imm = 0xFFFFFFFF00000000
cmpq %rcx, %rax
jb 0x4745
movl (%rbp), %eax
cmpl $0x22, %eax
je 0x4745
testl %eax, %eax
jne 0x3e9c
movl %r15d, (%rbp)
movq (%rsp), %rdi
leaq 0x10(%rsp), %rax
cmpq %rax, %rdi
je 0x3eb7
movq 0x10(%rsp), %rsi
incq %rsi
callq 0x2190
movq -0x8(%rbx,%r14,8), %rsi
leaq 0x1a8c(%rip), %rdi      # 0x594f
callq 0x2220
testl %eax, %eax
jne 0x3f66
cmpq %r13, %r14
jae 0x4199
movq (%rbx,%r14,8), %rsi
movq %rsp, %rdi
leaq 0x90(%rsp), %rdx
callq 0x499a
movq (%rsp), %r12
movl (%rbp), %r15d
movl $0x0, (%rbp)
movq %r12, %rdi
leaq 0x40(%rsp), %rsi
movl $0xa, %edx
callq 0x2230
cmpq %r12, 0x40(%rsp)
je 0x4769
movq %rax, 0x70(%rsp)
addq $-0x80000000, %rax      # imm = 0x80000000
movabsq $-0x100000000, %rcx     # imm = 0xFFFFFFFF00000000
cmpq %rcx, %rax
jb 0x475d
movl (%rbp), %eax
cmpl $0x22, %eax
je 0x475d
testl %eax, %eax
jne 0x3f4b
movl %r15d, (%rbp)
movq (%rsp), %rdi
leaq 0x10(%rsp), %rax
cmpq %rax, %rdi
je 0x3f66
movq 0x10(%rsp), %rsi
incq %rsi
callq 0x2190
movq -0x8(%rbx,%r14,8), %rsi
leaq 0x1a0b(%rip), %rdi      # 0x597d
callq 0x2220
testl %eax, %eax
jne 0x4018
cmpq %r13, %r14
jae 0x41e6
movq (%rbx,%r14,8), %rsi
movq %rsp, %rdi
leaq 0x90(%rsp), %rdx
callq 0x499a
movq (%rsp), %r12
movl (%rbp), %r15d
movl $0x0, (%rbp)
movq %r12, %rdi
leaq 0x40(%rsp), %rsi
movl $0xa, %edx
callq 0x2230
cmpq %r12, 0x40(%rsp)
je 0x4775
movq %rax, 0xc0(%rsp)
addq $-0x80000000, %rax      # imm = 0x80000000
movabsq $-0x100000000, %rcx     # imm = 0xFFFFFFFF00000000
cmpq %rcx, %rax
jb 0x4781
movl (%rbp), %eax
cmpl $0x22, %eax
je 0x4781
testl %eax, %eax
jne 0x3ffd
movl %r15d, (%rbp)
movq (%rsp), %rdi
leaq 0x10(%rsp), %rax
cmpq %rax, %rdi
je 0x4018
movq 0x10(%rsp), %rsi
incq %rsi
callq 0x2190
cmpq %r13, %r14
setb 0x60(%rsp)
movq 0x80(%rsp), %rax
addq %r14, %rax
incq %rax
incq %r14
cmpq $0x1, %rax
jne 0x3d59
xorl %ebx, %ebx
jmp 0x4231
movl $0x36, %edx
leaq 0x1713(%rip), %rsi      # 0x5761
movq 0x3f9b(%rip), %rbx      # 0x7ff0
movq %rbx, %rdi
callq 0x21c0
movq (%rbx), %rax
addq -0x18(%rax), %rbx
movq %rbx, %rdi
movl $0xa, %esi
callq 0x2180
movsbl %al, %esi
movq 0x3f75(%rip), %rdi      # 0x7ff0
callq 0x2040
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
movq %rax, %rdi
callq 0x2120
jmp 0x4654
cmpl $0x6, %r13d
jg 0x40eb
movq 0x3f51(%rip), %rbx      # 0x7ff0
leaq 0x160b(%rip), %rsi      # 0x56b1
movl $0x43, %edx
movq %rbx, %rdi
callq 0x21c0
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2180
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
leaq 0x1614(%rip), %rsi      # 0x56f5
movl $0x35, %edx
jmp 0x39a8
movl $0x3, %r12d
movb $0x1, %r14b
jmp 0x3ae6
movq 0x3ef0(%rip), %rbx      # 0x7ff0
leaq 0x16ec(%rip), %rsi      # 0x57f3
movl $0x2f, %edx
movq %rbx, %rdi
callq 0x21c0
movq (%rbx), %rax
addq -0x18(%rax), %rbx
movq %rbx, %rdi
movl $0xa, %esi
callq 0x2180
movsbl %al, %esi
movq 0x3ebe(%rip), %rdi      # 0x7ff0
callq 0x2040
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
movq %rax, %rdi
callq 0x2120
jmp 0x4231
movq 0x3ea0(%rip), %rbx      # 0x7ff0
leaq 0x16cc(%rip), %rsi      # 0x5823
movl $0x2e, %edx
movq %rbx, %rdi
callq 0x21c0
movq (%rbx), %rax
addq -0x18(%rax), %rbx
movq %rbx, %rdi
movl $0xa, %esi
callq 0x2180
movsbl %al, %esi
movq 0x3e6e(%rip), %rdi      # 0x7ff0
callq 0x2040
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
movq %rax, %rdi
callq 0x2120
jmp 0x4231
movq 0x3e50(%rip), %rbx      # 0x7ff0
leaq 0x16ab(%rip), %rsi      # 0x5852
movl $0x30, %edx
movq %rbx, %rdi
callq 0x21c0
movq (%rbx), %rax
addq -0x18(%rax), %rbx
movq %rbx, %rdi
movl $0xa, %esi
callq 0x2180
movsbl %al, %esi
movq 0x3e1e(%rip), %rdi      # 0x7ff0
callq 0x2040
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
movq %rax, %rdi
callq 0x2120
jmp 0x4231
movq 0x3e03(%rip), %rbx      # 0x7ff0
leaq 0x168f(%rip), %rsi      # 0x5883
movl $0x2b, %edx
movq %rbx, %rdi
callq 0x21c0
movq (%rbx), %rax
addq -0x18(%rax), %rbx
movq %rbx, %rdi
movl $0xa, %esi
callq 0x2180
movsbl %al, %esi
movq 0x3dd1(%rip), %rdi      # 0x7ff0
callq 0x2040
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
movq %rax, %rdi
callq 0x2120
testb $0x1, 0x60(%rsp)
movq 0x70(%rsp), %rcx
movq 0x78(%rsp), %r15
movq 0xc0(%rsp), %r13
movq 0x68(%rsp), %rax
jne 0x4654
xorpd %xmm0, %xmm0
ucomisd 0xb8(%rsp), %xmm0
jae 0x45b4
testl %eax, %eax
jle 0x4601
testl %r15d, %r15d
jle 0x460f
testl %ecx, %ecx
jle 0x461d
testl %r13d, %r13d
jle 0x462b
leaq 0x10(%rsp), %rax
movq %rax, (%rsp)
xorl %eax, %eax
movq %rax, 0x8(%rsp)
movb %al, 0x10(%rsp)
leaq 0x50(%rsp), %rdx
movq %rdx, -0x10(%rdx)
movq %rax, -0x8(%rdx)
movb %al, (%rdx)
leaq 0xa0(%rsp), %rdx
movq %rdx, -0x10(%rdx)
movq %rax, -0x8(%rdx)
movb %al, (%rdx)
movl %ecx, %ebp
imull %r15d, %ebp
leaq 0x8c(%rsp), %rdi
movl %ebp, %esi
callq 0x24bc
movl %ebp, %edi
shlq $0x2, %rdi
callq 0x2030
movq %rax, %r14
movl %r15d, %ebp
leaq (,%rbp,4), %rdi
callq 0x2030
movq %rax, %r12
movl 0x68(%rsp), %edx
leaq 0x148(%rsp), %rdi
movq %rbp, %rsi
callq 0x2fa0
movl %r13d, %eax
movq %rax, 0x60(%rsp)
leaq 0x168(%rsp), %r13
movq %rsp, %rbp
movq 0xb0(%rsp), %rax
decl %eax
movl %eax, 0x80(%rsp)
movq %r13, %rdi
callq 0x20b0
cmpl $-0x1, %eax
jne 0x4352
movq 0x168(%rsp), %rax
movq -0x18(%rax), %rax
testb $0x2, 0x188(%rsp,%rax)
jne 0x4528
movq 0xb0(%rsp), %rax
cmpl $0x3, %eax
je 0x43c2
cmpl $0x2, %eax
jne 0x4429
leaq 0xf8(%rsp), %rax
movq %rax, 0xe8(%rsp)
movq 0x20(%rsp), %rsi
movq 0x28(%rsp), %rdx
addq %rsi, %rdx
leaq 0xe8(%rsp), %rdi
callq 0x2e3e
movq %r13, %rdi
movq %rbp, %rsi
leaq 0x40(%rsp), %rdx
leaq 0xe8(%rsp), %rcx
callq 0x2cca
movl %eax, %r15d
movq 0xe8(%rsp), %rdi
leaq 0xf8(%rsp), %rcx
jmp 0x447e
leaq 0xd8(%rsp), %rax
movq %rax, 0xc8(%rsp)
movq 0x20(%rsp), %rsi
movq 0x28(%rsp), %rdx
addq %rsi, %rdx
leaq 0xc8(%rsp), %rdi
callq 0x2e3e
movq %r13, %rdi
leaq 0x770(%rsp), %rsi
movq %rbp, %rdx
leaq 0x40(%rsp), %rcx
leaq 0x90(%rsp), %r8
leaq 0xc8(%rsp), %r9
callq 0x2b41
movl %eax, %r15d
movq 0xc8(%rsp), %rdi
leaq 0xd8(%rsp), %rcx
jmp 0x447e
leaq 0x118(%rsp), %rax
movq %rax, 0x108(%rsp)
movq 0x20(%rsp), %rsi
movq 0x28(%rsp), %rdx
addq %rsi, %rdx
leaq 0x108(%rsp), %rdi
callq 0x2e3e
movq %r13, %rdi
movq %rbp, %rsi
leaq 0x40(%rsp), %rdx
leaq 0x108(%rsp), %rcx
callq 0x2ab3
movl %eax, %r15d
movq 0x108(%rsp), %rdi
leaq 0x118(%rsp), %rcx
movq %rcx, %rax
cmpq %rcx, %rdi
je 0x4491
movq (%rax), %rsi
incq %rsi
callq 0x2190
testb %r15b, %r15b
je 0x4528
leaq 0x8c(%rsp), %rdi
movq 0x60(%rsp), %rsi
movq %rbp, %rdx
movq %r14, %rcx
callq 0x24c0
movq %r14, %rdi
movq %r12, %rsi
movq 0x78(%rsp), %rdx
movq 0x70(%rsp), %rcx
callq 0x2f48
leaq 0x148(%rsp), %rdi
movq %r12, %rsi
callq 0x3036
movsd 0xb8(%rsp), %xmm1
ucomisd %xmm0, %xmm1
jbe 0x4528
leaq 0x370(%rsp), %rdi
leaq 0x40(%rsp), %rax
cmpl $0x2, 0x80(%rsp)
jb 0x451c
movq 0x40(%rsp), %rsi
movq 0x48(%rsp), %rdx
callq 0x21c0
leaq 0x570(%rsp), %rdi
leaq 0x90(%rsp), %rax
movq (%rax), %rsi
movq 0x8(%rax), %rdx
callq 0x21c0
movq 0x168(%rsp), %rax
movq -0x18(%rax), %rax
testb $0x5, 0x188(%rsp,%rax)
je 0x432b
leaq 0x148(%rsp), %rdi
callq 0x2ff4
movq 0x90(%rsp), %rdi
leaq 0xa0(%rsp), %rax
cmpq %rax, %rdi
je 0x4574
movq 0xa0(%rsp), %rsi
incq %rsi
callq 0x2190
movq 0x40(%rsp), %rdi
leaq 0x50(%rsp), %rax
cmpq %rax, %rdi
je 0x4590
movq 0x50(%rsp), %rsi
incq %rsi
callq 0x2190
movq (%rsp), %rdi
leaq 0x10(%rsp), %rax
cmpq %rax, %rdi
je 0x4654
movq 0x10(%rsp), %rsi
incq %rsi
callq 0x2190
jmp 0x4654
movq 0x3a35(%rip), %rbx      # 0x7ff0
leaq 0x12ed(%rip), %rsi      # 0x58af
movl $0x21, %edx
movq %rbx, %rdi
callq 0x21c0
movq (%rbx), %rax
addq -0x18(%rax), %rbx
movq %rbx, %rdi
movl $0xa, %esi
callq 0x2180
movsbl %al, %esi
movq 0x3a03(%rip), %rdi      # 0x7ff0
callq 0x2040
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
movq %rax, %rdi
callq 0x2120
jmp 0x4654
movl $0x2c, %edx
leaq 0x12c4(%rip), %rsi      # 0x58d1
jmp 0x4637
movl $0x2b, %edx
leaq 0x12e3(%rip), %rsi      # 0x58fe
jmp 0x4637
movl $0x2d, %edx
leaq 0x1301(%rip), %rsi      # 0x592a
jmp 0x4637
movl $0x28, %edx
leaq 0x1321(%rip), %rsi      # 0x5958
movq 0x39b2(%rip), %rdi      # 0x7ff0
callq 0x21c0
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
movq 0x39a1(%rip), %rdi      # 0x7ff0
callq 0x20d0
movq 0x20(%rsp), %rdi
leaq 0x30(%rsp), %rax
cmpq %rax, %rdi
je 0x4670
movq 0x30(%rsp), %rsi
incq %rsi
callq 0x2190
leaq 0x138(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x4691
movq 0x138(%rsp), %rsi
incq %rsi
callq 0x2190
movq 0x3938(%rip), %rax      # 0x7fd0
movq (%rax), %r14
movq 0x18(%rax), %r15
leaq 0x578(%rsp), %rdi
movq %r14, -0x8(%rdi)
movq -0x18(%r14), %rax
movq %r15, 0x570(%rsp,%rax)
callq 0x2160
movl $0xf8, %r12d
leaq 0x570(%rsp), %rdi
addq %r12, %rdi
callq 0x20a0
leaq 0x770(%rsp), %rdi
callq 0x2070
leaq 0x378(%rsp), %rdi
movq %r14, -0x8(%rdi)
movq -0x18(%r14), %rax
movq %r15, 0x370(%rsp,%rax)
callq 0x2160
leaq 0x370(%rsp), %rdi
addq %r12, %rdi
callq 0x20a0
leaq 0x168(%rsp), %rdi
callq 0x2070
movl %ebx, %eax
addq $0x978, %rsp            # imm = 0x978
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x1252(%rip), %rdi      # 0x5986
callq 0x20f0
leaq 0x1246(%rip), %rdi      # 0x5986
callq 0x2240
leaq 0x123a(%rip), %rdi      # 0x5986
callq 0x2240
leaq 0x122e(%rip), %rdi      # 0x5986
callq 0x20f0
leaq 0x1222(%rip), %rdi      # 0x5986
callq 0x2240
leaq 0x1216(%rip), %rdi      # 0x5986
callq 0x20f0
leaq 0x120a(%rip), %rdi      # 0x5986
callq 0x20f0
leaq 0x11fe(%rip), %rdi      # 0x5986
callq 0x2240
leaq 0x11ed(%rip), %rdi      # 0x5981
callq 0x20f0
jmp 0x479f
jmp 0x479f
jmp 0x479f
movq %rax, %rbx
jmp 0x485f
movq %rax, %rbx
movq 0xc8(%rsp), %rdi
leaq 0xd8(%rsp), %rax
cmpq %rax, %rdi
je 0x4852
movq 0xd8(%rsp), %rsi
jmp 0x480f
movq %rax, %rbx
movq 0xe8(%rsp), %rdi
leaq 0xf8(%rsp), %rax
cmpq %rax, %rdi
je 0x4852
movq 0xf8(%rsp), %rsi
jmp 0x480f
movq %rax, %rbx
movq 0x108(%rsp), %rdi
leaq 0x118(%rsp), %rax
cmpq %rax, %rdi
je 0x4852
movq 0x118(%rsp), %rsi
incq %rsi
callq 0x2190
jmp 0x4852
jmp 0x484f
jmp 0x491e
jmp 0x491e
jmp 0x491e
movq %rax, %rbx
jmp 0x493d
jmp 0x48e9
movq %rax, %rbx
jmp 0x496b
movq %rax, %rbx
jmp 0x4978
movq %rax, %rbx
jmp 0x4985
movq %rax, %rbx
leaq 0x148(%rsp), %rdi
callq 0x2ff4
movq 0x90(%rsp), %rdi
leaq 0xa0(%rsp), %rax
cmpq %rax, %rdi
je 0x4884
movq 0xa0(%rsp), %rsi
incq %rsi
callq 0x2190
movq 0x40(%rsp), %rdi
leaq 0x50(%rsp), %rax
cmpq %rax, %rdi
je 0x4901
movq 0x50(%rsp), %rsi
incq %rsi
callq 0x2190
jmp 0x4901
movq %rax, %rbx
jmp 0x4992
jmp 0x491e
jmp 0x491e
jmp 0x491e
jmp 0x491e
movq %rax, %rbx
cmpl $0x0, (%rbp)
jne 0x48bf
movl %r14d, (%rbp)
leaq 0x178(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x4992
movq 0x178(%rsp), %rsi
incq %rsi
callq 0x2190
jmp 0x4992
movq %rax, %rbx
jmp 0x495e
jmp 0x48f4
jmp 0x48f4
jmp 0x48f4
movq %rax, %rbx
cmpl $0x0, (%rbp)
jne 0x4901
movl %r15d, (%rbp)
movq (%rsp), %rdi
leaq 0x10(%rsp), %rax
cmpq %rax, %rdi
je 0x4921
movq 0x10(%rsp), %rsi
incq %rsi
callq 0x2190
jmp 0x4921
movq %rax, %rbx
movq 0x20(%rsp), %rdi
leaq 0x30(%rsp), %rax
cmpq %rax, %rdi
je 0x493d
movq 0x30(%rsp), %rsi
incq %rsi
callq 0x2190
leaq 0x138(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x495e
movq 0x138(%rsp), %rsi
incq %rsi
callq 0x2190
leaq 0x570(%rsp), %rdi
callq 0x2250
leaq 0x770(%rsp), %rdi
callq 0x2070
leaq 0x370(%rsp), %rdi
callq 0x2250
leaq 0x168(%rsp), %rdi
callq 0x2070
movq %rbx, %rdi
callq 0x22a0