// File: /workspace/github_cpp_makefile_star2_O2/schneebergerlab[P]DrLink/detect_recombsite.cpp
// Function: check_co_read_density(unsigned long, unsigned long, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, int*, bool*, int*, int*, int*, int*, int*)
bool check_co_read_density(unsigned long       co_start,
                           unsigned long       co_end,
                           string              read_align_info,
                           string              read_order_info,
                           string              read_id_info,
                           int*                bp_per_read_in_co,
                           bool*               bp_boundary_same_fragment,
                           int*                min_RR_dist,
                           int*                max_RR_dist,
                           int*                n_readLeft,
                           int*                n_readRight,
                           int*                max_CORR_dist)
{
    /* this function checks read density in a potential CO interval
       how many bp per read within this interval
       -The larger/"smaller" the value, the higher chance that 
        this molecule is falsely merged from different molecules.
       
       Example molecule with info:
       
	1#ACGCGTGGTCCAGTAT  8229787 8277108 47422   0.08    30  R   8277208
 
 	# span of reads: read_align_info
	8229787,8229914;8229933,8230022;8234823,8234973;8235084,8235141;
	8235256,8235406;8235546,8235673;8237785,8237913;8238134,8238284;
	8245266,8245416;8245555,8245682;8250091,8250218;8250471,8250611;
	8252479,8252629;8252479,8252629;8252711,8252807;8252714,8252807;
	8256708,8256858;8257166,8257293;8262644,8262803;8262929,8263056;
	8264841,8264991;8265091,8265218;8266796,8266946;8266809,8266864;
	8267521,8267644;8267724,8267873;8272690,8272817;8273056,8273206;
	8276756,8276883;8277108,8277208 

	# order in read pairs: read_order_info
	1,2,2,1,2,1,1,2,2,1,1,2,2,2,1,1,2,1,2,1,2,1,2,1,1,2,1,2,1,2 

	# id of reads: read_id_info
	J00137:105:HNFWJBBXX:3:1213:4685:18616,J00137:105:HNFWJBBXX:3:1213:4685:18616,
	J00137:102:HMYVWBBXX:7:2102:6482:8400,J00137:102:HMYVWBBXX:7:2102:6482:8400,
	J00137:105:HNFWJBBXX:3:2225:2950:3266,J00137:105:HNFWJBBXX:3:2225:2950:3266,
	J00137:108:HNGC7BBXX:3:1211:16072:22133,J00137:108:HNGC7BBXX:3:1211:16072:22133,
	J00137:105:HNFWJBBXX:3:1109:7314:28973,J00137:105:HNFWJBBXX:3:1109:7314:28973,
	J00137:108:HNGC7BBXX:3:2103:14874:10247,J00137:108:HNGC7BBXX:3:2103:14874:10247,
	J00137:102:HMYVWBBXX:7:2127:1692:16559,J00137:102:HMYVWBBXX:7:2127:1895:16665,
	J00137:102:HMYVWBBXX:7:2127:1692:16559,J00137:102:HMYVWBBXX:7:2127:1895:16665,
	J00137:105:HNFWJBBXX:3:1114:28107:1525,J00137:105:HNFWJBBXX:3:1114:28107:1525,
	J00137:102:HMYVWBBXX:8:2124:19471:30274,J00137:102:HMYVWBBXX:8:2124:19471:30274,
	J00137:108:HNGC7BBXX:3:1210:19705:2897,J00137:108:HNGC7BBXX:3:1210:19705:2897,
	J00137:102:HMYVWBBXX:7:2106:30655:43251,J00137:102:HMYVWBBXX:7:2106:30655:43251,
	J00137:108:HNGC7BBXX:3:1212:11363:38029,J00137:108:HNGC7BBXX:3:1212:11363:38029,
	J00137:105:HNFWJBBXX:3:2204:5284:22854,J00137:105:HNFWJBBXX:3:2204:5284:22854,
	J00137:105:HNFWJBBXX:3:1104:14143:15451,J00137:105:HNFWJBBXX:3:1104:14143:15451
	
	bp predicted as: 8252716 -> 8262697, where CO start/end in reads at 8252714, 8262644
    */
    //
    if(co_end < co_start)
    {
        return false;
    }
    // return values
    *bp_per_read_in_co         = -1;     // read density within CO interval
    *bp_boundary_same_fragment = false;  // whether the read covering co start/end from the same fragment
    *min_RR_dist               = 999999; // minimum R1-R1 or R2-R2 distance within the molecule
    *max_RR_dist               = 0;      // maximum ...
    // task 1. check read density within the potential CO interval
    vector<string> respan  = split_string(read_align_info, ';'); // ; with ,    
    vector<string> reorder = split_string(read_order_info, ','); // ,
    vector<string> reid    = split_string(read_id_info,    ','); // ,
    assert( respan.size() == reorder.size() );
    assert( respan.size() == reid.size() ); 
    vector<string>::iterator ritr;
    vector<string>::iterator ritr_end;
    ritr     = respan.begin();
    ritr_end = respan.end();
    int n_read = 0;                    // number of reads in interval
    int i_read = -1;                   // to satisfy index start from 0 in vector
    unsigned long sta_aligned_pos = 0; // last  read covering start of interval
    unsigned long end_aligned_pos = 0; // first read covering end   of interval
    string        sta_read_name("");
    string        end_read_name("");
    string        sta_read_order("");
    string        end_read_order("");
    //
    map<string, int> readLeft;
    map<string, int> readRight;
    //
    unsigned long lastReadStaInCO     = 0; // <read_align_sta, read_align_end>
    unsigned long maxIntervalSizeInCo = 0;
    //
    while(ritr != ritr_end)
    {
        vector<string> ralign = split_string(*ritr, ',');
        
        unsigned long rsta = strtoul(ralign[0].c_str(), NULL, 0);
        unsigned long rend = strtoul(ralign[1].c_str(), NULL, 0);
        
        i_read ++; // first valid: i_read = 0
        
        // skip checking reads in front of the interval
        if(rend < co_start)
        {
            if(readLeft.find(reid[i_read]) == readLeft.end())
            {
                readLeft.insert(std::pair<string, int>(reid[i_read], 1));
            }
            ritr ++;
            continue;
        }
        //
        if(rsta<=co_start && co_start<=rend)
        {
            sta_aligned_pos = rsta; // take the last  read statisfying this
            sta_read_order  = reorder[i_read];            
            sta_read_name   = reid[i_read];
        }
        //
        if(end_aligned_pos==0 && rsta<=co_end && co_end<=rend)
        {
            end_aligned_pos = rsta; // take the first read satsifying this
            end_read_order  = reorder[i_read];            
            end_read_name   = reid[i_read];        
        }
        // number of reads within interval
        if(co_start<rsta && rend<co_end)
        {
            n_read ++;
        }
        // reads on/in CO interval
        if( (co_start<=rsta && rsta<=co_end) || (co_start<=rend && rend<=co_end) )
        {
            if(lastReadStaInCO != 0)
            {
                assert(rsta>=lastReadStaInCO);
                unsigned long this_dist = rsta - lastReadStaInCO;
                if(this_dist > maxIntervalSizeInCo) 
                {
                    maxIntervalSizeInCo = this_dist;
                }
            }
            lastReadStaInCO     = rsta;
        }        
        // reads after the interval
        if(rsta > co_end)
        {
            if(readRight.find(reid[i_read]) == readRight.end())
            {
                readRight.insert(std::pair<string, int>(reid[i_read], 1));
            }
        }
        ritr ++;
    }
    //
    *max_CORR_dist = maxIntervalSizeInCo;
    // exclude read ids at start and end of CO
    if(readLeft.find(sta_read_name) != readLeft.end())
    {
        readLeft.erase(sta_read_name);
    }
    *n_readLeft = readLeft.size();
    if(readRight.find(end_read_name) != readRight.end())
    {
        readRight.erase(end_read_name);
    }
    *n_readRight = readRight.size();
    // e.g., one read r2 within interval: co_sta_in_r1----r2------co_end_in_r3, that is, n_read = 1,
    //      => density = (co_end - co_sta) / (n_read+1)
    n_read += 1; 
    *bp_per_read_in_co = (co_end - co_start)/n_read; // check::TODO: use end_last_read - sta_first_read :: full span
    //
    string frag(" different ");
    if(end_read_name.compare(sta_read_name) == 0)
    {
        *bp_boundary_same_fragment = true;
        frag                       = (string)" same ";
    }
    //
    if(sta_read_name.size() != 0 && end_read_name.size() != 0)
    {
        cout << "         CO starts/ends in reads at " 
             << sta_aligned_pos   << ", " << end_aligned_pos << "\n"
             << "          with " << frag << " read ids: " 
             << sta_read_name     << ", " << end_read_name
             << endl;
    }
    else // reads in molecule missing compared to vcf, possibly due to secondary alignment etc.
    if(sta_read_name.size() != 0 && end_read_name.size() == 0)
    {
        cout << "         CO starts in read at " 
             << sta_aligned_pos   << ", CO-end read discarded during bam conversion. " << "\n"
             << "          with " << frag << " read id: " 
             << sta_read_name     << ","
             << endl;    
    }
    else
    if(sta_read_name.size() == 0 && end_read_name.size() != 0)
    {
        cout << "         CO ends in read at " 
             << "CO-start read discarded during bam conversion" << ", " << end_aligned_pos << "\n"
             << "          with " << frag << " read id: " 
             << ", "              << end_read_name
             << endl;    
    }
    else
    {
        cout << "         CO starts/ends in reads -- both discarded during bam conversion. " 
             << endl;
    }

    // task 2. check read density within the potential-CO related molecule
    unsigned long RR_dist_total  = 0;
    int           RR_dist_num    = 0;
    unsigned long lastR1AlignSta = 0; // for calculating R1 distance
    unsigned long lastR1AlignEnd = 0; // ..
    unsigned long lastR2AlignSta = 0; // for calculating R2 distance
    unsigned long lastR2AlignEnd = 0; // ..  
    ritr        = respan.begin();
    ritr_end    = respan.end();
    i_read      = -1;
    while(ritr != ritr_end)
    {
        vector<string> ralign = split_string(*ritr, ',');
        unsigned long rsta = strtoul(ralign[0].c_str(), NULL, 0);
        unsigned long rend = strtoul(ralign[1].c_str(), NULL, 0);
        // the i_read-th read: 0,1,...,n-1
        i_read ++;
        string iorder = reorder[i_read];
        
        if(i_read == 0)
        {
            if(iorder.compare("1") == 0)
            {
                lastR1AlignSta = rsta;
                lastR1AlignEnd = rend;
            }
            else
            {
                lastR2AlignSta = rsta;
                lastR2AlignEnd = rend;                
            }
        }
        else
        {
            if(iorder.compare("1") == 0) // current is R1
            {
                if(lastR1AlignSta > 0)   // there is last R1
                {
                    // the dist where a read takes within a molecule: always >= 0
                    int i_dist   = (rsta>lastR1AlignSta)?(rsta-lastR1AlignSta):((lastR1AlignSta-rsta)*(-1));
                    *min_RR_dist = (*min_RR_dist>i_dist)?i_dist:*min_RR_dist;
                    *max_RR_dist = (*max_RR_dist<i_dist)?i_dist:*max_RR_dist;
                    RR_dist_total+= i_dist>0?i_dist:(-1)*i_dist; // absolute dist total
                    RR_dist_num ++;
                }
                lastR1AlignSta  = rsta;
                lastR1AlignEnd  = rend;
            }
            else                         // current is R2
            {
                if(lastR2AlignSta > 0)   // there is last R2
                {
                    // minus exists: meaning overlapped RR reads
                    int i_dist  = (rsta>lastR2AlignSta)?(rsta-lastR2AlignSta):((lastR2AlignSta-rsta)*(-1));
                    *min_RR_dist = (*min_RR_dist>i_dist)?i_dist:*min_RR_dist;
                    *max_RR_dist = (*max_RR_dist<i_dist)?i_dist:*max_RR_dist;
                    RR_dist_total+= i_dist>0?i_dist:(-1)*i_dist; // absolute dist total
                    RR_dist_num ++;              
                }                
                lastR2AlignSta  = rsta;
                lastR2AlignEnd  = rend;                
            }          
        }
        
        ritr ++;
    }

    return true;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x1d8, %rsp            # imm = 0x1D8
movq %rsi, 0x18(%rsp)
movq %rsi, %r13
subq %rdi, %r13
jb 0x146ea
movq %r9, %r14
movq %r8, %rbx
movq %rcx, %r15
movq %rdi, 0x38(%rsp)
movq 0x220(%rsp), %rax
movq 0x218(%rsp), %rcx
movq 0x210(%rsp), %rsi
orl $-0x1, (%r9)
movb $0x0, (%rsi)
movl $0xf423f, (%rcx)        # imm = 0xF423F
andl $0x0, (%rax)
leaq 0x58(%rsp), %r12
movb $0x3b, (%r12)
leaq 0xe8(%rsp), %rdi
movq %rdx, %rsi
movq %r12, %rdx
callq 0x26120
movb $0x2c, (%r12)
leaq 0x88(%rsp), %rdi
leaq 0x58(%rsp), %rdx
movq %r15, %rsi
callq 0x26120
leaq 0x58(%rsp), %rdx
movb $0x2c, (%rdx)
leaq 0x40(%rsp), %rdi
movq %rbx, %rsi
callq 0x26120
movq 0xe8(%rsp), %rcx
movq 0xf0(%rsp), %rax
movq %rax, 0x30(%rsp)
movq %rcx, 0x8(%rsp)
subq %rcx, %rax
movq 0x90(%rsp), %rcx
subq 0x88(%rsp), %rcx
cmpq %rcx, %rax
jne 0x14723
movq 0x48(%rsp), %rcx
subq 0x40(%rsp), %rcx
cmpq %rcx, %rax
jne 0x14742
leaq 0x19c20(%rip), %rsi     # 0x2db1a
leaq 0xc8(%rsp), %rdi
leaq 0x58(%rsp), %rdx
callq 0x4d3e
leaq 0x19c07(%rip), %rsi     # 0x2db1a
leaq 0x120(%rsp), %rdi
leaq 0x58(%rsp), %rdx
callq 0x4d3e
leaq 0x19bee(%rip), %rsi     # 0x2db1a
leaq 0x1b8(%rsp), %rdi
leaq 0x58(%rsp), %rdx
callq 0x4d3e
movq %r13, 0x140(%rsp)
movq %r14, 0x148(%rsp)
leaq 0x19bc5(%rip), %rsi     # 0x2db1a
leaq 0x198(%rsp), %rdi
leaq 0x58(%rsp), %rdx
callq 0x4d3e
leaq 0x60(%rsp), %rax
andl $0x0, (%rax)
andq $0x0, 0x8(%rax)
movq %rax, 0x10(%rax)
movq %rax, 0x18(%rax)
andq $0x0, 0x20(%rax)
leaq 0x170(%rsp), %rax
andl $0x0, (%rax)
andq $0x0, 0x8(%rax)
movq %rax, 0x10(%rax)
movq %rax, 0x18(%rax)
andq $0x0, 0x20(%rax)
xorl %r14d, %r14d
leaq 0x100(%rsp), %r15
leaq 0xa0(%rsp), %rbx
movq $0x0, 0x28(%rsp)
xorl %r12d, %r12d
movq $0x0, (%rsp)
movq $0x0, 0x20(%rsp)
movl $0x0, 0x14(%rsp)
movq 0x8(%rsp), %rax
leaq (%rax,%r14), %rsi
cmpq 0x30(%rsp), %rsi
je 0x141e9
movb $0x2c, 0xa0(%rsp)
movq %r15, %rdi
movq %rbx, %r13
movq %rbx, %rdx
callq 0x26120
movq 0x100(%rsp), %rax
movq (%rax), %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x4130
movq %rax, %rbp
movq 0x100(%rsp), %rax
movq 0x20(%rax), %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x4130
movq %rax, %rbx
movq 0x38(%rsp), %rax
cmpq %rax, %rbx
jae 0x14089
movq 0x40(%rsp), %rsi
addq %r14, %rsi
leaq 0x58(%rsp), %rdi
callq 0xa992
leaq 0x60(%rsp), %rcx
cmpq %rcx, %rax
movq %r13, %rbx
jne 0x141d8
movq 0x40(%rsp), %rsi
addq %r14, %rsi
movq %rbx, %rdi
callq 0x4400
movl $0x1, 0xc0(%rsp)
leaq 0x58(%rsp), %rdi
movq %rbx, %rsi
callq 0xaa08
jmp 0x141cb
cmpq %rax, %rbp
ja 0x140c3
movq 0x88(%rsp), %rsi
addq %r14, %rsi
leaq 0x1b8(%rsp), %rdi
callq 0x41e0
movq 0x40(%rsp), %rsi
addq %r14, %rsi
leaq 0xc8(%rsp), %rdi
callq 0x41e0
movq %rbp, %rax
movq %rbp, 0x20(%rsp)
cmpq $0x0, (%rsp)
jne 0x1411d
movq 0x18(%rsp), %rcx
cmpq %rcx, %rbp
seta %al
cmpq %rcx, %rbx
setb %cl
orb %al, %cl
je 0x140e9
movq $0x0, (%rsp)
jmp 0x1411d
movq 0x88(%rsp), %rsi
addq %r14, %rsi
leaq 0x198(%rsp), %rdi
callq 0x41e0
movq 0x40(%rsp), %rsi
addq %r14, %rsi
leaq 0x120(%rsp), %rdi
callq 0x41e0
movq %rbp, %rax
movq %rbp, (%rsp)
movq 0x18(%rsp), %rdi
cmpq %rdi, %rbx
setb %al
seta %dl
cmpq 0x38(%rsp), %rbp
seta %cl
setb %sil
cmpq %rdi, %rbp
seta %dil
orb %sil, %dil
testb %dl, %dil
jne 0x1416b
testq %r12, %r12
je 0x14168
movq %rbp, %rdx
subq %r12, %rdx
jb 0x14704
movq 0x28(%rsp), %rsi
cmpq %rsi, %rdx
cmovaq %rdx, %rsi
movq %rsi, 0x28(%rsp)
movq %rbp, %r12
andb %al, %cl
movzbl %cl, %eax
addl %eax, 0x14(%rsp)
cmpq 0x18(%rsp), %rbp
jbe 0x141d5
movq 0x40(%rsp), %rsi
addq %r14, %rsi
leaq 0x168(%rsp), %rdi
callq 0xa992
movq %r13, %rbx
leaq 0x170(%rsp), %rcx
cmpq %rcx, %rax
jne 0x141d8
movq 0x40(%rsp), %rsi
addq %r14, %rsi
movq %rbx, %rdi
callq 0x4400
movl $0x1, 0xc0(%rsp)
leaq 0x168(%rsp), %rdi
movq %rbx, %rsi
callq 0xaa08
movq %rbx, %rdi
callq 0x4638
jmp 0x141d8
movq %r13, %rbx
movq %r15, %rdi
callq 0x5d02
addq $0x20, %r14
jmp 0x13fd6
movq 0x238(%rsp), %rax
movq 0x28(%rsp), %rcx
movl %ecx, (%rax)
leaq 0x58(%rsp), %rdi
leaq 0xc8(%rsp), %rsi
callq 0xa992
leaq 0x60(%rsp), %rcx
cmpq %rcx, %rax
je 0x14226
leaq 0x58(%rsp), %rdi
leaq 0xc8(%rsp), %rsi
callq 0x176d8
movl 0x80(%rsp), %eax
movq 0x228(%rsp), %rcx
movl %eax, (%rcx)
leaq 0x168(%rsp), %rdi
leaq 0x120(%rsp), %rsi
callq 0xa992
leaq 0x170(%rsp), %rcx
cmpq %rcx, %rax
je 0x1426e
leaq 0x168(%rsp), %rdi
leaq 0x120(%rsp), %rsi
callq 0x176d8
movl 0x190(%rsp), %eax
movq 0x230(%rsp), %rcx
movl %eax, (%rcx)
movl 0x14(%rsp), %eax
incl %eax
movslq %eax, %rcx
movq 0x140(%rsp), %rax
xorl %edx, %edx
divq %rcx
movq 0x148(%rsp), %rcx
movl %eax, (%rcx)
leaq 0x173da(%rip), %rsi     # 0x2b680
leaq 0xa0(%rsp), %rdi
leaq 0x100(%rsp), %rdx
callq 0x4d3e
leaq 0x120(%rsp), %rdi
leaq 0xc8(%rsp), %rsi
callq 0x4030
testl %eax, %eax
jne 0x1431b
movq 0x210(%rsp), %rax
movb $0x1, (%rax)
leaq 0x173a6(%rip), %rsi     # 0x2b68c
leaq 0x100(%rsp), %rdi
leaq 0x150(%rsp), %rdx
callq 0x4d3e
leaq 0xa0(%rsp), %rdi
leaq 0x100(%rsp), %rbx
movq %rbx, %rsi
callq 0x43c0
movq %rbx, %rdi
callq 0x4638
cmpq $0x0, 0xd0(%rsp)
movq 0x128(%rsp), %rax
je 0x143c8
testq %rax, %rax
je 0x1446f
movq 0x28c86(%rip), %rdi     # 0x3cfc8
leaq 0x1734a(%rip), %rsi     # 0x2b693
callq 0x4330
movq %rax, %rdi
movq 0x20(%rsp), %rsi
callq 0x4230
leaq 0x192f4(%rip), %rsi     # 0x2d656
movq %rax, %rdi
callq 0x4330
movq %rax, %rdi
movq (%rsp), %rsi
callq 0x4230
leaq 0x18b16(%rip), %rsi     # 0x2ce93
movq %rax, %rdi
callq 0x4330
leaq 0x1732c(%rip), %rsi     # 0x2b6b8
movq %rax, %rdi
callq 0x4330
leaq 0xa0(%rsp), %rsi
movq %rax, %rdi
callq 0x42e0
leaq 0x1731d(%rip), %rsi     # 0x2b6c8
movq %rax, %rdi
callq 0x4330
leaq 0xc8(%rsp), %rsi
movq %rax, %rdi
callq 0x42e0
jmp 0x1444b
testq %rax, %rax
je 0x144f7
movq 0x28bf0(%rip), %rdi     # 0x3cfc8
leaq 0x1734f(%rip), %rsi     # 0x2b72e
callq 0x4330
leaq 0x17360(%rip), %rsi     # 0x2b74b
movq %rax, %rdi
callq 0x4330
leaq 0x1925c(%rip), %rsi     # 0x2d656
movq %rax, %rdi
callq 0x4330
movq %rax, %rdi
movq (%rsp), %rsi
callq 0x4230
leaq 0x18a7e(%rip), %rsi     # 0x2ce93
movq %rax, %rdi
callq 0x4330
leaq 0x17294(%rip), %rsi     # 0x2b6b8
movq %rax, %rdi
callq 0x4330
leaq 0xa0(%rsp), %rsi
movq %rax, %rdi
callq 0x42e0
leaq 0x172e0(%rip), %rsi     # 0x2b723
movq %rax, %rdi
callq 0x4330
leaq 0x19204(%rip), %rsi     # 0x2d656
movq %rax, %rdi
callq 0x4330
leaq 0x120(%rsp), %rsi
movq %rax, %rdi
callq 0x42e0
jmp 0x1450a
movq 0x28b52(%rip), %rdi     # 0x3cfc8
leaq 0x17257(%rip), %rsi     # 0x2b6d4
callq 0x4330
movq %rax, %rdi
movq 0x20(%rsp), %rsi
callq 0x4230
leaq 0x1725d(%rip), %rsi     # 0x2b6f3
movq %rax, %rdi
callq 0x4330
leaq 0x189ee(%rip), %rsi     # 0x2ce93
movq %rax, %rdi
callq 0x4330
leaq 0x17204(%rip), %rsi     # 0x2b6b8
movq %rax, %rdi
callq 0x4330
leaq 0xa0(%rsp), %rsi
movq %rax, %rdi
callq 0x42e0
leaq 0x17250(%rip), %rsi     # 0x2b723
movq %rax, %rdi
callq 0x4330
leaq 0xc8(%rsp), %rsi
movq %rax, %rdi
callq 0x42e0
movq %rax, %rdi
leaq 0x159ab(%rip), %rsi     # 0x29ea0
jmp 0x14505
leaq 0x1727b(%rip), %rsi     # 0x2b779
movq 0x28ac3(%rip), %rdi     # 0x3cfc8
callq 0x4330
movq %rax, %rdi
callq 0x41c0
movq 0xe8(%rsp), %rax
movq %rax, 0x30(%rsp)
movq 0xf0(%rsp), %rax
movq %rax, (%rsp)
xorl %r13d, %r13d
leaq 0x150(%rsp), %rbp
leaq 0x100(%rsp), %r12
xorl %r15d, %r15d
movq $0x0, 0x8(%rsp)
xorl %r14d, %r14d
movq 0x30(%rsp), %rax
leaq (%rax,%r13), %rsi
cmpq (%rsp), %rsi
je 0x14669
movb $0x2c, 0x100(%rsp)
movq %rbp, %rbx
movq %rbp, %rdi
movq %r12, %rdx
callq 0x26120
movq 0x150(%rsp), %rax
movq (%rax), %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x4130
movq %rax, %rbp
movq 0x150(%rsp), %rax
movq 0x20(%rax), %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x4130
movq 0x88(%rsp), %rsi
addq %r13, %rsi
movq %r12, %rdi
callq 0x4400
movq %r12, %rdi
leaq 0x15082(%rip), %rsi     # 0x29641
callq 0x4110
subq $0x1, %r15
jae 0x145e0
testl %eax, %eax
movq 0x8(%rsp), %rax
cmoveq %rbp, %rax
movq %rax, 0x8(%rsp)
cmovneq %rbp, %r14
jmp 0x1464d
testl %eax, %eax
je 0x14615
testq %r14, %r14
je 0x14610
movl %ebp, %eax
subl %r14d, %eax
movq 0x218(%rsp), %rdx
movl (%rdx), %ecx
cmpl %eax, %ecx
cmovgel %eax, %ecx
movl %ecx, (%rdx)
movq 0x220(%rsp), %rdx
movl (%rdx), %ecx
cmpl %eax, %ecx
cmovgl %ecx, %eax
movl %eax, (%rdx)
movq %rbp, %r14
jmp 0x1464d
movq 0x8(%rsp), %rax
testq %rax, %rax
je 0x14648
movq %rax, %rcx
movl %ebp, %eax
subl %ecx, %eax
movq 0x218(%rsp), %rdx
movl (%rdx), %ecx
cmpl %eax, %ecx
cmovgel %eax, %ecx
movl %ecx, (%rdx)
movq 0x220(%rsp), %rdx
movl (%rdx), %ecx
cmpl %eax, %ecx
cmovgl %ecx, %eax
movl %eax, (%rdx)
movq %rbp, 0x8(%rsp)
movq %r12, %rdi
callq 0x4638
movq %rbx, %rbp
movq %rbx, %rdi
callq 0x5d02
addq $0x20, %r13
jmp 0x1454d
leaq 0xa0(%rsp), %rdi
callq 0x4638
leaq 0x168(%rsp), %rdi
callq 0xa004
leaq 0x58(%rsp), %rdi
callq 0xa004
leaq 0x198(%rsp), %rdi
callq 0x4638
leaq 0x1b8(%rsp), %rdi
callq 0x4638
leaq 0x120(%rsp), %rdi
callq 0x4638
leaq 0xc8(%rsp), %rdi
callq 0x4638
leaq 0x40(%rsp), %rdi
callq 0x5d02
leaq 0x88(%rsp), %rdi
callq 0x5d02
leaq 0xe8(%rsp), %rdi
callq 0x5d02
movq 0x38(%rsp), %rdi
cmpq %rdi, 0x18(%rsp)
setae %al
addq $0x1d8, %rsp            # imm = 0x1D8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x16f5f(%rip), %rdi     # 0x2b66a
leaq 0x167ef(%rip), %rsi     # 0x2af01
leaq 0x16eb1(%rip), %rcx     # 0x2b5ca
movl $0x50b, %edx            # imm = 0x50B
callq 0x4210
leaq 0x16e80(%rip), %rdi     # 0x2b5aa
leaq 0x167d0(%rip), %rsi     # 0x2af01
leaq 0x16e92(%rip), %rcx     # 0x2b5ca
movl $0x4cb, %edx            # imm = 0x4CB
callq 0x4210
leaq 0x16f04(%rip), %rdi     # 0x2b64d
leaq 0x167b1(%rip), %rsi     # 0x2af01
leaq 0x16e73(%rip), %rcx     # 0x2b5ca
movl $0x4cc, %edx            # imm = 0x4CC
callq 0x4210
jmp 0x147d4
jmp 0x147f8
jmp 0x147f8
jmp 0x147f8
movq %rax, %rbx
jmp 0x1481f
movq %rax, %rbx
jmp 0x1482c
movq %rax, %rbx
jmp 0x14839
movq %rax, %rbx
jmp 0x14846
movq %rax, %rbx
jmp 0x14850
movq %rax, %rbx
jmp 0x1485d
jmp 0x147f8
jmp 0x147a8
jmp 0x147c2
movq %rax, %rbx
leaq 0xa0(%rsp), %rdi
callq 0x4638
jmp 0x147c5
jmp 0x147c2
jmp 0x147c2
jmp 0x147d4
jmp 0x147c2
movq %rax, %rbx
leaq 0x100(%rsp), %rdi
callq 0x5d02
jmp 0x147fb
movq %rax, %rbx
jmp 0x147e9
movq %rax, %rbx
leaq 0x150(%rsp), %rdi
callq 0x5d02
leaq 0xa0(%rsp), %rdi
callq 0x4638
jmp 0x147fb
movq %rax, %rbx
leaq 0x168(%rsp), %rdi
callq 0xa004
leaq 0x58(%rsp), %rdi
callq 0xa004
leaq 0x198(%rsp), %rdi
callq 0x4638
leaq 0x1b8(%rsp), %rdi
callq 0x4638
leaq 0x120(%rsp), %rdi
callq 0x4638
leaq 0xc8(%rsp), %rdi
callq 0x4638
leaq 0x40(%rsp), %rdi
callq 0x5d02
leaq 0x88(%rsp), %rdi
callq 0x5d02
leaq 0xe8(%rsp), %rdi
callq 0x5d02
movq %rbx, %rdi
callq 0x45a0