// File: medvedevgroup[P]varmatch/src/wholegenome.cpp
// Function: WholeGenome::MatchVariantListInThread(int, int, int, std::vector<DiploidVariant, std::allocator<DiploidVariant>>&, int)
bool WholeGenome::MatchVariantListInThread(int thread_index, 
    int threshold_index,
    int chr_id,
    vector<DiploidVariant> & variant_list,
    int cluster_id){
    //===================================================
    sort(variant_list.begin(), variant_list.end());
    // decide reference sequence
    vector<DiploidVariant> separate_var_list[2];
    vector<Interval> intervals;
    // separate into ref and que
    int total_mil = 0;
    int total_mdl = 0;
    int min_pos = genome_sequences[chr_id].length() + 1;
    int max_pos = -1;
    for (int i = 0; i < variant_list.size(); i++) {
        int flag = 0;
        if (variant_list[i].flag) flag = 1; // flag indicate if the variant is from ref set(0) or query set(1)
        int pos = variant_list[i].pos;
        separate_var_list[flag].push_back(variant_list[i]);
        total_mil += variant_list[i].mil;
        total_mdl += variant_list[i].mdl;
        auto ref_sequence = variant_list[i].ref;
        auto alt_sequences = variant_list[i].alts;
        min_pos = min(pos, min_pos);
        max_pos = max((int)(pos + ref_sequence.length()), max_pos);

        int end_pos = pos + ref_sequence.length() - 1; // included end position!!
        intervals.push_back(Interval(pos, end_pos));
    }
    min_pos = max(min_pos - 1, 0);
    max_pos = min(max_pos + 1, (int)genome_sequences[chr_id].length()); //exclusive

    if (separate_var_list[0].size() == 0 || separate_var_list[1].size() == 0) {
        //dout << separate_var_list[0].size() << ", " << separate_var_list[1].size() << endl;
        return false;
    }
    if (separate_var_list[0].size() == 1 && separate_var_list[1].size() == 1){
        // try direct match to save time
        if(separate_var_list[0][0] == separate_var_list[1][0]){

            DiploidVariant tv = separate_var_list[0][0];
            string match_record = chrname_by_chrid[chr_id] + "\t" + to_string(tv.pos+1) + "\t" + tv.ref + "\t" + tv.alts[0];
            if(tv.multi_alts) match_record += "/" + tv.alts[1];
            match_record += "\t.\t.\t.\t.\t.\n";
            // here we need to push back for all mode_index
            //complex_match_records[thread_index]->push_back(match_record);

            int edit_distance = CalculateEditDistance(tv, 0, 0);
            for(int mi = 0; mi < mode_index_list.size(); mi ++){
                int mode_i = mode_index_list[mi];
                //if(mi == 0){
                

                // this line should be recovered
                match_records_by_mode_by_thread[thread_index][mode_i]->push_back(match_record);
                
                //}else{
                //    match_records_by_mode_by_thread[thread_index][mode_i]->push_back("$"+to_string(match_records_by_mode_by_thread[thread_index][0]->size()));
                    // use dollor to represent that it is the same
                //}
                baseline_total_match_num[thread_index][threshold_index]->at(mode_i)++;
                query_total_match_num[thread_index][threshold_index]->at(mode_i)++;

                baseline_total_edit_distance[thread_index][threshold_index]->at(mode_i) +=  edit_distance;
                query_total_edit_distance[thread_index][threshold_index]->at(mode_i) += edit_distance;
                //calculate the edit distance
            }
            // output match result
            return true;
        }
        // if not match, still can match by changing genome
    }else if(separate_var_list[0].size() == 1 || separate_var_list[1].size() == 1){
        int flag = 0;
        if(separate_var_list[1].size() == 1) flag = 1;
        int r_flag = 1-flag;
        if(separate_var_list[r_flag].size() > 4){
            int total_r_mdl = 0;
            int total_r_mil = 0;

            for(int k = 0; k < separate_var_list[r_flag].size(); k++){
                DiploidVariant var = separate_var_list[r_flag][k];
                int var_mdl = var.mdl;
                int var_mil = var.mil;
                int ref_length = var.ref.length();
                total_r_mdl += var_mdl;
                total_r_mil += var_mil;
            }

            if(max(separate_var_list[flag][0].mdl, separate_var_list[flag][0].mil) > max(total_r_mdl, total_r_mil)) return false;
        }
    }

    separate_var_list[0].clear();
    separate_var_list[1].clear();
    // remove singular variant
    // [todo] try removing this filter to see running time changes
    vector<bool> appliable_flag;
    int total_change = total_mil+total_mdl;

    if(variant_list.size() > EASY_MATCH_VAR_NUM){
        for(int k = 0; k < variant_list.size(); k++){
            DiploidVariant cur_var = variant_list[k];
            int max_change = max(cur_var.mil, cur_var.mdl);
            if(max_change > total_change-max_change){
                appliable_flag.push_back(false);
                //dout << "this variant is removed" << endl;
            }else{
                appliable_flag.push_back(true);
            }
        }
    }else{
        for(int k = 0; k < variant_list.size(); k++){
            appliable_flag.push_back(true);
        }
    }

    string subsequence = genome_sequences[chr_id].substr(min_pos, max_pos - min_pos);

    ToUpper(subsequence); // subsequence only contains upper char
    int offset = min_pos;
    int subsequence_length = max_pos - min_pos;

    // have subsequence in hand
    //generate decision point
    multimap<int, int> * choices_by_pos[2];
    // choice by pos is to also equal to var by pos
    for(int i = 0; i < 2; i++){
        choices_by_pos[i] = new multimap<int, int>();
    }

    for(int index = 0; index < variant_list.size(); index++){
        if(!appliable_flag[index]) continue;
        // remove decision point if not applicable
        int pos = variant_list[index].pos - offset;
        int flag = 0;
        if(variant_list[index].flag) flag = 1;
        choices_by_pos[flag]->insert(pair<int, int>(pos, index));
        //dout << pos << index << endl;
    }

    vector<Interval> mergered_intervals = merge(intervals);
//    unordered_map<int, bool> sync_points;
//    for(int i = 0; i < mergered_intervals.size(); i++){
//        sync_points[mergered_intervals[i].end-offset] = true;
//    }
    vector<int> sync_points;
    for(int i = 0; i < mergered_intervals.size(); i++){
        sync_points.push_back(mergered_intervals[i].end-offset);
    }

    if(sync_points.back() < subsequence.size() - 1){
        sync_points.push_back(subsequence.size()-1);
    }

    int score_unit;
    int match_mode;
    int score_scheme;

    for(int i = 0; i < score_unit_list.size(); i++){
        score_unit = score_unit_list[i];
        for(int j = 0; j < match_mode_list.size(); j++){
            match_mode = match_mode_list[j];
            for(int k = 0; k < score_scheme_list.size(); k++){
                score_scheme = score_scheme_list[k];

                bool method2 = MatchingSingleClusterBaseExtending(
                                            cluster_id,
                                            thread_index,
                                            variant_list,
                                            subsequence,
                                            offset,
                                            choices_by_pos,
                                            sync_points,
                                            chr_id,
                                            score_unit,
                                            match_mode,
                                            score_scheme,
                                            threshold_index);
            }
        }
    }

    for(int i = 0; i < 2; i++){
        delete choices_by_pos[i];
    }
    //delete choices_by_pos;

    return true;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r14
pushq %rbx
subq $0x640, %rsp            # imm = 0x640
movq %rdi, -0x20(%rbp)
movl %esi, -0x24(%rbp)
movl %edx, -0x28(%rbp)
movl %ecx, -0x2c(%rbp)
movq %r8, -0x38(%rbp)
movl %r9d, -0x3c(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0x478(%rbp)
movq -0x38(%rbp), %rdi
callq 0x33d60
movq %rax, -0x48(%rbp)
movq -0x38(%rbp), %rdi
callq 0x33d90
movq %rax, -0x50(%rbp)
movq -0x48(%rbp), %rdi
movq -0x50(%rbp), %rsi
callq 0x33d20
leaq -0x80(%rbp), %rax
movq %rax, %rcx
addq $0x30, %rcx
movq %rcx, -0x470(%rbp)
movq %rax, -0x468(%rbp)
movq -0x468(%rbp), %rdi
movq %rdi, -0x480(%rbp)
callq 0x322d0
movq -0x480(%rbp), %rax
movq -0x470(%rbp), %rcx
addq $0x18, %rax
cmpq %rcx, %rax
movq %rax, -0x468(%rbp)
jne 0x1f64e
leaq -0x98(%rbp), %rdi
callq 0x33dc0
movq -0x478(%rbp), %rdi
movl $0x0, -0x9c(%rbp)
movl $0x0, -0xa0(%rbp)
addq $0x118, %rdi            # imm = 0x118
leaq -0x2c(%rbp), %rsi
callq 0x32770
movq %rax, -0x488(%rbp)
jmp 0x1f6bf
movq -0x488(%rbp), %rdi
callq 0x6630
addq $0x1, %rax
movl %eax, -0xa4(%rbp)
movl $0xffffffff, -0xb8(%rbp) # imm = 0xFFFFFFFF
movl $0x0, -0xbc(%rbp)
movslq -0xbc(%rbp), %rax
movq %rax, -0x490(%rbp)
movq -0x38(%rbp), %rdi
callq 0x335b0
movq %rax, %rcx
movq -0x490(%rbp), %rax
cmpq %rcx, %rax
jae 0x1f97d
movl $0x0, -0xc0(%rbp)
movq -0x38(%rbp), %rdi
movslq -0xbc(%rbp), %rsi
callq 0x33de0
testb $0x1, 0x4c(%rax)
je 0x1f756
movl $0x1, -0xc0(%rbp)
jmp 0x1f756
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xb0(%rbp)
movl %eax, -0xb4(%rbp)
jmp 0x20a0e
movq -0x38(%rbp), %rdi
movslq -0xbc(%rbp), %rsi
callq 0x33de0
movl (%rax), %eax
movl %eax, -0xc4(%rbp)
movslq -0xc0(%rbp), %rax
leaq (%rax,%rax,2), %rax
leaq -0x80(%rbp,%rax,8), %rax
movq %rax, -0x498(%rbp)
movq -0x38(%rbp), %rdi
movslq -0xbc(%rbp), %rsi
callq 0x33de0
movq -0x498(%rbp), %rdi
movq %rax, %rsi
callq 0x32bf0
jmp 0x1f7a6
movq -0x38(%rbp), %rdi
movslq -0xbc(%rbp), %rsi
callq 0x33de0
movl 0x48(%rax), %ecx
movl -0x9c(%rbp), %eax
addl %ecx, %eax
movl %eax, -0x9c(%rbp)
movq -0x38(%rbp), %rdi
movslq -0xbc(%rbp), %rsi
callq 0x33de0
movl 0x44(%rax), %ecx
movl -0xa0(%rbp), %eax
addl %ecx, %eax
movl %eax, -0xa0(%rbp)
movq -0x38(%rbp), %rdi
movslq -0xbc(%rbp), %rsi
callq 0x33de0
movq %rax, %rsi
addq $0x8, %rsi
leaq -0xe8(%rbp), %rdi
callq 0x61b0
jmp 0x1f80d
movq -0x38(%rbp), %rdi
movslq -0xbc(%rbp), %rsi
callq 0x33de0
movq %rax, %rsi
addq $0x28, %rsi
leaq -0x100(%rbp), %rdi
callq 0x32950
jmp 0x1f832
leaq -0xc4(%rbp), %rdi
leaq -0xa4(%rbp), %rsi
callq 0x10420
movq %rax, -0x4a0(%rbp)
jmp 0x1f84e
movq -0x4a0(%rbp), %rax
movl (%rax), %eax
movl %eax, -0xa4(%rbp)
movl -0xc4(%rbp), %eax
movl %eax, -0x4ac(%rbp)
leaq -0xe8(%rbp), %rdi
callq 0x6630
movq %rax, %rcx
movl -0x4ac(%rbp), %eax
addl %ecx, %eax
movl %eax, -0x104(%rbp)
leaq -0x104(%rbp), %rdi
leaq -0xb8(%rbp), %rsi
callq 0x32a80
movq %rax, -0x4a8(%rbp)
jmp 0x1f8a2
movq -0x4a8(%rbp), %rax
movl (%rax), %eax
movl %eax, -0xb8(%rbp)
movl -0xc4(%rbp), %eax
movl %eax, -0x4b0(%rbp)
leaq -0xe8(%rbp), %rdi
callq 0x6630
movl -0x4b0(%rbp), %ecx
movl %eax, %edx
movl %ecx, %eax
movl %edx, %ecx
leal -0x1(%rax,%rcx), %eax
movl %eax, -0x108(%rbp)
movl -0xc4(%rbp), %esi
movl -0x108(%rbp), %edx
leaq -0x110(%rbp), %rdi
callq 0x33e30
jmp 0x1f8f9
leaq -0x98(%rbp), %rdi
leaq -0x110(%rbp), %rsi
callq 0x33e00
jmp 0x1f90e
leaq -0x100(%rbp), %rdi
callq 0x13370
leaq -0xe8(%rbp), %rdi
callq 0x6828
movl -0xbc(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xbc(%rbp)
jmp 0x1f6e9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xb0(%rbp)
movl %eax, -0xb4(%rbp)
jmp 0x1f96c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xb0(%rbp)
movl %eax, -0xb4(%rbp)
leaq -0x100(%rbp), %rdi
callq 0x13370
leaq -0xe8(%rbp), %rdi
callq 0x6828
jmp 0x20a0e
movl -0xa4(%rbp), %eax
decl %eax
movl %eax, -0x114(%rbp)
movl $0x0, -0x118(%rbp)
leaq -0x114(%rbp), %rdi
leaq -0x118(%rbp), %rsi
callq 0x32a80
movq %rax, -0x4b8(%rbp)
jmp 0x1f9b1
movq -0x478(%rbp), %rdi
movq -0x4b8(%rbp), %rax
movl (%rax), %eax
movl %eax, -0xa4(%rbp)
movl -0xb8(%rbp), %eax
incl %eax
movl %eax, -0x11c(%rbp)
addq $0x118, %rdi            # imm = 0x118
leaq -0x2c(%rbp), %rsi
callq 0x32770
movq %rax, -0x4c0(%rbp)
jmp 0x1f9ee
movq -0x4c0(%rbp), %rdi
callq 0x6630
movl %eax, -0x120(%rbp)
leaq -0x11c(%rbp), %rdi
leaq -0x120(%rbp), %rsi
callq 0x10420
movq %rax, -0x4c8(%rbp)
jmp 0x1fa1c
movq -0x4c8(%rbp), %rax
movl (%rax), %eax
movl %eax, -0xb8(%rbp)
leaq -0x80(%rbp), %rdi
callq 0x335b0
cmpq $0x0, %rax
je 0x1fa4d
leaq -0x80(%rbp), %rdi
addq $0x18, %rdi
callq 0x335b0
cmpq $0x0, %rax
jne 0x1fa60
movb $0x0, -0x11(%rbp)
movl $0x1, -0x124(%rbp)
jmp 0x209ea
leaq -0x80(%rbp), %rdi
callq 0x335b0
cmpq $0x1, %rax
jne 0x1fff3
leaq -0x80(%rbp), %rdi
addq $0x18, %rdi
callq 0x335b0
cmpq $0x1, %rax
jne 0x1fff3
xorl %eax, %eax
movl %eax, %esi
movq %rsi, -0x4e0(%rbp)
leaq -0x80(%rbp), %rdi
callq 0x33de0
movq -0x4e0(%rbp), %rsi
movq %rax, -0x4d8(%rbp)
leaq -0x68(%rbp), %rdi
callq 0x33de0
movq -0x4d8(%rbp), %rdi
movq %rax, %rsi
callq 0x33e50
movb %al, -0x4c9(%rbp)
jmp 0x1facc
movb -0x4c9(%rbp), %al
testb $0x1, %al
jne 0x1fadb
jmp 0x1ffee
xorl %eax, %eax
movl %eax, %esi
leaq -0x80(%rbp), %rdi
callq 0x33de0
movq %rax, %rsi
leaq -0x180(%rbp), %rdi
callq 0x340a0
jmp 0x1faf9
movq -0x478(%rbp), %rdi
addq $0xb8, %rdi
leaq -0x2c(%rbp), %rsi
callq 0x32770
movq %rax, -0x4e8(%rbp)
jmp 0x1fb19
movq -0x4e8(%rbp), %rsi
leaq 0x35a76(%rip), %rdx     # 0x5559d
leaq -0x240(%rbp), %rdi
callq 0xe200
jmp 0x1fb35
movl -0x180(%rbp), %esi
incl %esi
leaq -0x260(%rbp), %rdi
callq 0xb190
jmp 0x1fb4b
leaq -0x220(%rbp), %rdi
leaq -0x240(%rbp), %rsi
leaq -0x260(%rbp), %rdx
callq 0xde60
jmp 0x1fb67
leaq 0x35a2f(%rip), %rdx     # 0x5559d
leaq -0x200(%rbp), %rdi
leaq -0x220(%rbp), %rsi
callq 0xb0f0
jmp 0x1fb83
leaq -0x178(%rbp), %rdx
leaq -0x1e0(%rbp), %rdi
leaq -0x200(%rbp), %rsi
callq 0xe1b0
jmp 0x1fb9f
leaq 0x359f7(%rip), %rdx     # 0x5559d
leaq -0x1c0(%rbp), %rdi
leaq -0x1e0(%rbp), %rsi
callq 0xb0f0
jmp 0x1fbbb
leaq -0x158(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x9080
movq %rax, %rdx
leaq -0x1a0(%rbp), %rdi
leaq -0x1c0(%rbp), %rsi
callq 0xe1b0
jmp 0x1fbe3
leaq -0x1c0(%rbp), %rdi
callq 0x6828
leaq -0x1e0(%rbp), %rdi
callq 0x6828
leaq -0x200(%rbp), %rdi
callq 0x6828
leaq -0x220(%rbp), %rdi
callq 0x6828
leaq -0x260(%rbp), %rdi
callq 0x6828
leaq -0x240(%rbp), %rdi
callq 0x6828
testb $0x1, -0x13f(%rbp)
je 0x1fd9e
leaq -0x158(%rbp), %rdi
movl $0x1, %esi
callq 0x9080
movq %rax, %rdx
leaq 0x3594c(%rip), %rsi     # 0x5559f
leaq -0x280(%rbp), %rdi
callq 0x10610
jmp 0x1fc61
leaq -0x1a0(%rbp), %rdi
leaq -0x280(%rbp), %rsi
callq 0x6560
jmp 0x1fc76
leaq -0x280(%rbp), %rdi
callq 0x6828
jmp 0x1fd9e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xb0(%rbp)
movl %eax, -0xb4(%rbp)
jmp 0x1ffdd
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xb0(%rbp)
movl %eax, -0xb4(%rbp)
jmp 0x1fd53
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xb0(%rbp)
movl %eax, -0xb4(%rbp)
jmp 0x1fd47
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xb0(%rbp)
movl %eax, -0xb4(%rbp)
jmp 0x1fd3b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xb0(%rbp)
movl %eax, -0xb4(%rbp)
jmp 0x1fd2f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xb0(%rbp)
movl %eax, -0xb4(%rbp)
jmp 0x1fd23
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xb0(%rbp)
movl %eax, -0xb4(%rbp)
leaq -0x1c0(%rbp), %rdi
callq 0x6828
leaq -0x1e0(%rbp), %rdi
callq 0x6828
leaq -0x200(%rbp), %rdi
callq 0x6828
leaq -0x220(%rbp), %rdi
callq 0x6828
leaq -0x260(%rbp), %rdi
callq 0x6828
leaq -0x240(%rbp), %rdi
callq 0x6828
jmp 0x1ffdd
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xb0(%rbp)
movl %eax, -0xb4(%rbp)
jmp 0x1ffd1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xb0(%rbp)
movl %eax, -0xb4(%rbp)
leaq -0x280(%rbp), %rdi
callq 0x6828
jmp 0x1ffd1
leaq 0x357fc(%rip), %rsi     # 0x555a1
leaq -0x1a0(%rbp), %rdi
callq 0x6410
jmp 0x1fdb3
movq -0x478(%rbp), %rdi
leaq -0x180(%rbp), %rsi
xorl %ecx, %ecx
movl %ecx, %edx
callq 0x20ac0
movl %eax, -0x4ec(%rbp)
jmp 0x1fdd2
movl -0x4ec(%rbp), %eax
movl %eax, -0x284(%rbp)
movl $0x0, -0x288(%rbp)
movq -0x478(%rbp), %rdi
movslq -0x288(%rbp), %rax
movq %rax, -0x4f8(%rbp)
addq $0x238, %rdi            # imm = 0x238
callq 0x19a40
movq %rax, %rcx
movq -0x4f8(%rbp), %rax
cmpq %rcx, %rax
jae 0x1ffa6
movq -0x478(%rbp), %rdi
addq $0x238, %rdi            # imm = 0x238
movslq -0x288(%rbp), %rsi
callq 0x19a60
movq %rax, %rcx
movq -0x478(%rbp), %rax
movl (%rcx), %ecx
movl %ecx, -0x28c(%rbp)
movq 0x178(%rax), %rax
movslq -0x24(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x28c(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
leaq -0x1a0(%rbp), %rsi
callq 0x17750
jmp 0x1fe70
movq -0x478(%rbp), %rax
movq 0x180(%rax), %rax
movslq -0x24(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x28(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
movslq -0x28c(%rbp), %rsi
callq 0x34130
movq %rax, -0x500(%rbp)
jmp 0x1fea3
movq -0x478(%rbp), %rax
movq -0x500(%rbp), %rcx
movl (%rcx), %edx
incl %edx
movl %edx, (%rcx)
movq 0x188(%rax), %rax
movslq -0x24(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x28(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
movslq -0x28c(%rbp), %rsi
callq 0x34130
movq %rax, -0x508(%rbp)
jmp 0x1fee3
movq -0x478(%rbp), %rax
movq -0x508(%rbp), %rcx
movl (%rcx), %edx
incl %edx
movl %edx, (%rcx)
movl -0x284(%rbp), %ecx
movl %ecx, -0x514(%rbp)
movq 0x190(%rax), %rax
movslq -0x24(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x28(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
movslq -0x28c(%rbp), %rsi
callq 0x34130
movq %rax, -0x510(%rbp)
jmp 0x1ff2f
movq -0x478(%rbp), %rax
movq -0x510(%rbp), %rcx
movl -0x514(%rbp), %esi
movl (%rcx), %edx
addl %esi, %edx
movl %edx, (%rcx)
movl -0x284(%rbp), %ecx
movl %ecx, -0x524(%rbp)
movq 0x198(%rax), %rax
movslq -0x24(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq -0x28(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
movslq -0x28c(%rbp), %rsi
callq 0x34130
movq %rax, -0x520(%rbp)
jmp 0x1ff81
movq -0x520(%rbp), %rax
movl -0x524(%rbp), %ecx
addl (%rax), %ecx
movl %ecx, (%rax)
movl -0x288(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x288(%rbp)
jmp 0x1fde8
movb $0x1, -0x11(%rbp)
movl $0x1, -0x124(%rbp)
leaq -0x1a0(%rbp), %rdi
callq 0x6828
leaq -0x180(%rbp), %rdi
callq 0x32c60
jmp 0x209ea
leaq -0x1a0(%rbp), %rdi
callq 0x6828
leaq -0x180(%rbp), %rdi
callq 0x32c60
jmp 0x20a0e
jmp 0x2021f
leaq -0x80(%rbp), %rdi
callq 0x335b0
cmpq $0x1, %rax
je 0x20019
leaq -0x80(%rbp), %rdi
addq $0x18, %rdi
callq 0x335b0
cmpq $0x1, %rax
jne 0x2021d
movl $0x0, -0x290(%rbp)
leaq -0x80(%rbp), %rdi
addq $0x18, %rdi
callq 0x335b0
cmpq $0x1, %rax
jne 0x20040
movl $0x1, -0x290(%rbp)
movl $0x1, %eax
subl -0x290(%rbp), %eax
movl %eax, -0x294(%rbp)
movslq -0x294(%rbp), %rax
leaq -0x80(%rbp), %rdi
imulq $0x18, %rax, %rax
addq %rax, %rdi
callq 0x335b0
cmpq $0x4, %rax
jbe 0x2021b
movl $0x0, -0x298(%rbp)
movl $0x0, -0x29c(%rbp)
movl $0x0, -0x2a0(%rbp)
movslq -0x2a0(%rbp), %rax
movq %rax, -0x530(%rbp)
movslq -0x294(%rbp), %rax
leaq -0x80(%rbp), %rdi
imulq $0x18, %rax, %rax
addq %rax, %rdi
callq 0x335b0
movq %rax, %rcx
movq -0x530(%rbp), %rax
cmpq %rcx, %rax
jae 0x20167
movslq -0x294(%rbp), %rax
leaq (%rax,%rax,2), %rax
leaq -0x80(%rbp,%rax,8), %rdi
movslq -0x2a0(%rbp), %rsi
callq 0x33de0
movq %rax, %rsi
leaq -0x2f8(%rbp), %rdi
callq 0x340a0
jmp 0x200f5
movl -0x2b4(%rbp), %eax
movl %eax, -0x2fc(%rbp)
movl -0x2b0(%rbp), %eax
movl %eax, -0x300(%rbp)
leaq -0x2f8(%rbp), %rdi
addq $0x8, %rdi
callq 0x6630
movl %eax, -0x304(%rbp)
movl -0x2fc(%rbp), %eax
addl -0x298(%rbp), %eax
movl %eax, -0x298(%rbp)
movl -0x300(%rbp), %eax
addl -0x29c(%rbp), %eax
movl %eax, -0x29c(%rbp)
leaq -0x2f8(%rbp), %rdi
callq 0x32c60
movl -0x2a0(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2a0(%rbp)
jmp 0x20090
movslq -0x290(%rbp), %rax
leaq (%rax,%rax,2), %rax
leaq -0x80(%rbp,%rax,8), %rdi
xorl %eax, %eax
movl %eax, %esi
movq %rsi, -0x548(%rbp)
callq 0x33de0
movq -0x548(%rbp), %rsi
addq $0x44, %rax
movq %rax, -0x540(%rbp)
movslq -0x290(%rbp), %rax
leaq (%rax,%rax,2), %rax
leaq -0x80(%rbp,%rax,8), %rdi
callq 0x33de0
movq -0x540(%rbp), %rdi
movq %rax, %rsi
addq $0x48, %rsi
callq 0x32a80
movq %rax, -0x538(%rbp)
jmp 0x201ca
movq -0x538(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x554(%rbp)
leaq -0x298(%rbp), %rdi
leaq -0x29c(%rbp), %rsi
callq 0x32a80
movq %rax, -0x550(%rbp)
jmp 0x201f5
movl -0x554(%rbp), %eax
movq -0x550(%rbp), %rcx
cmpl (%rcx), %eax
jle 0x20219
movb $0x0, -0x11(%rbp)
movl $0x1, -0x124(%rbp)
jmp 0x209ea
jmp 0x2021b
jmp 0x2021d
jmp 0x2021f
leaq -0x80(%rbp), %rdi
callq 0x32660
leaq -0x80(%rbp), %rdi
addq $0x18, %rdi
callq 0x32660
leaq -0x330(%rbp), %rdi
callq 0x34170
movl -0x9c(%rbp), %eax
addl -0xa0(%rbp), %eax
movl %eax, -0x334(%rbp)
movq -0x38(%rbp), %rdi
callq 0x335b0
cmpq $0x5, %rax
jbe 0x2037f
movl $0x0, -0x338(%rbp)
movslq -0x338(%rbp), %rax
movq %rax, -0x560(%rbp)
movq -0x38(%rbp), %rdi
callq 0x335b0
movq %rax, %rcx
movq -0x560(%rbp), %rax
cmpq %rcx, %rax
jae 0x2037d
movq -0x38(%rbp), %rdi
movslq -0x338(%rbp), %rsi
callq 0x33de0
movq %rax, %rsi
leaq -0x390(%rbp), %rdi
callq 0x340a0
jmp 0x202bb
leaq -0x348(%rbp), %rdi
leaq -0x34c(%rbp), %rsi
callq 0x32a80
movq %rax, -0x568(%rbp)
jmp 0x202d7
movq -0x568(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x394(%rbp)
movl -0x394(%rbp), %eax
movl -0x334(%rbp), %ecx
subl -0x394(%rbp), %ecx
cmpl %ecx, %eax
jle 0x20348
leaq -0x330(%rbp), %rdi
xorl %esi, %esi
callq 0x34190
jmp 0x2030c
jmp 0x2035d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xb0(%rbp)
movl %eax, -0xb4(%rbp)
jmp 0x209dc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xb0(%rbp)
movl %eax, -0xb4(%rbp)
leaq -0x390(%rbp), %rdi
callq 0x32c60
jmp 0x209dc
leaq -0x330(%rbp), %rdi
movl $0x1, %esi
callq 0x34190
jmp 0x2035b
jmp 0x2035d
leaq -0x390(%rbp), %rdi
callq 0x32c60
movl -0x338(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x338(%rbp)
jmp 0x20270
jmp 0x203d7
movl $0x0, -0x398(%rbp)
movslq -0x398(%rbp), %rax
movq %rax, -0x570(%rbp)
movq -0x38(%rbp), %rdi
callq 0x335b0
movq %rax, %rcx
movq -0x570(%rbp), %rax
cmpq %rcx, %rax
jae 0x203d5
leaq -0x330(%rbp), %rdi
movl $0x1, %esi
callq 0x34190
jmp 0x203c2
jmp 0x203c4
movl -0x398(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x398(%rbp)
jmp 0x20389
jmp 0x203d7
movq -0x478(%rbp), %rdi
addq $0x118, %rdi            # imm = 0x118
leaq -0x2c(%rbp), %rsi
callq 0x32770
movq %rax, -0x578(%rbp)
jmp 0x203f7
movq -0x578(%rbp), %rsi
movslq -0xa4(%rbp), %rdx
movl %edx, %ecx
movl -0xb8(%rbp), %eax
subl %ecx, %eax
movslq %eax, %rcx
leaq -0x3b8(%rbp), %rdi
callq 0x6460
jmp 0x20420
movq -0x478(%rbp), %rdi
leaq -0x3b8(%rbp), %rsi
callq 0x328c0
jmp 0x20435
movl -0xa4(%rbp), %eax
movl %eax, -0x3bc(%rbp)
movl -0xb8(%rbp), %eax
subl -0xa4(%rbp), %eax
movl %eax, -0x3c0(%rbp)
movl $0x0, -0x3d4(%rbp)
cmpl $0x2, -0x3d4(%rbp)
jge 0x204d6
movl $0x30, %edi
callq 0x6430
movq %rax, -0x580(%rbp)
jmp 0x20479
movq -0x580(%rbp), %rdi
xorl %esi, %esi
movl $0x30, %edx
callq 0x6240
movq -0x580(%rbp), %rdi
callq 0x34260
movq -0x580(%rbp), %rcx
movslq -0x3d4(%rbp), %rax
movq %rcx, -0x3d0(%rbp,%rax,8)
movl -0x3d4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3d4(%rbp)
jmp 0x2045d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xb0(%rbp)
movl %eax, -0xb4(%rbp)
jmp 0x209d0
movl $0x0, -0x3d8(%rbp)
movslq -0x3d8(%rbp), %rax
movq %rax, -0x588(%rbp)
movq -0x38(%rbp), %rdi
callq 0x335b0
movq %rax, %rcx
movq -0x588(%rbp), %rax
cmpq %rcx, %rax
jae 0x2061a
movslq -0x3d8(%rbp), %rsi
leaq -0x330(%rbp), %rdi
callq 0x34280
movq %rdx, -0x598(%rbp)
movq %rax, -0x590(%rbp)
jmp 0x2052d
movq -0x598(%rbp), %rax
movq -0x590(%rbp), %rcx
movq %rcx, -0x3e8(%rbp)
movq %rax, -0x3e0(%rbp)
leaq -0x3e8(%rbp), %rdi
callq 0x342e0
xorb $-0x1, %al
testb $0x1, %al
jne 0x2055d
jmp 0x20562
jmp 0x20606
movq -0x38(%rbp), %rdi
movslq -0x3d8(%rbp), %rsi
callq 0x33de0
movl (%rax), %eax
subl -0x3bc(%rbp), %eax
movl %eax, -0x3ec(%rbp)
movl $0x0, -0x3f0(%rbp)
movq -0x38(%rbp), %rdi
movslq -0x3d8(%rbp), %rsi
callq 0x33de0
testb $0x1, 0x4c(%rax)
je 0x205aa
movl $0x1, -0x3f0(%rbp)
movslq -0x3f0(%rbp), %rax
movq -0x3d0(%rbp,%rax,8), %rax
movq %rax, -0x5a0(%rbp)
leaq -0x3f8(%rbp), %rdi
leaq -0x3ec(%rbp), %rsi
leaq -0x3d8(%rbp), %rdx
callq 0x34340
jmp 0x205dc
movq -0x5a0(%rbp), %rdi
leaq -0x3f8(%rbp), %rsi
callq 0x34310
movq %rax, -0x5a8(%rbp)
jmp 0x205f8
movq -0x5a8(%rbp), %rax
movq %rax, -0x400(%rbp)
movl -0x3d8(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3d8(%rbp)
jmp 0x204e0
movq -0x478(%rbp), %rsi
leaq -0x418(%rbp), %rdi
leaq -0x98(%rbp), %rdx
callq 0x34370
jmp 0x20636
leaq -0x430(%rbp), %rdi
callq 0x32270
movl $0x0, -0x434(%rbp)
movslq -0x434(%rbp), %rax
movq %rax, -0x5b0(%rbp)
leaq -0x418(%rbp), %rdi
callq 0x344d0
movq %rax, %rcx
movq -0x5b0(%rbp), %rax
cmpq %rcx, %rax
jae 0x206f0
movslq -0x434(%rbp), %rsi
leaq -0x418(%rbp), %rdi
callq 0x34520
movl 0x4(%rax), %eax
movl -0x3bc(%rbp), %ecx
subl %ecx, %eax
movl %eax, -0x438(%rbp)
leaq -0x430(%rbp), %rdi
leaq -0x438(%rbp), %rsi
callq 0x344f0
jmp 0x206ae
jmp 0x206b0
movl -0x434(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x434(%rbp)
jmp 0x2064c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0xb0(%rbp)
movl %eax, -0xb4(%rbp)
leaq -0x430(%rbp), %rdi
callq 0xbca0
leaq -0x418(%rbp), %rdi
callq 0x345a0
jmp 0x209d0
leaq -0x430(%rbp), %rdi
callq 0x34540
movslq (%rax), %rax
movq %rax, -0x5b8(%rbp)
leaq -0x3b8(%rbp), %rdi
callq 0x6320
movq %rax, %rcx
movq -0x5b8(%rbp), %rax
subq $0x1, %rcx
cmpq %rcx, %rax
jae 0x20750
leaq -0x3b8(%rbp), %rdi
callq 0x6320
decl %eax
movl %eax, -0x43c(%rbp)
leaq -0x430(%rbp), %rdi
leaq -0x43c(%rbp), %rsi
callq 0x344f0
jmp 0x2074e
jmp 0x20750
movl $0x0, -0x44c(%rbp)
movq -0x478(%rbp), %rdi
movslq -0x44c(%rbp), %rax
movq %rax, -0x5c0(%rbp)
addq $0x1f0, %rdi            # imm = 0x1F0
callq 0x19a40
movq %rax, %rcx
movq -0x5c0(%rbp), %rax
cmpq %rcx, %rax
jae 0x20931
movq -0x478(%rbp), %rdi
addq $0x1f0, %rdi            # imm = 0x1F0
movslq -0x44c(%rbp), %rsi
callq 0x19a60
movl (%rax), %eax
movl %eax, -0x440(%rbp)
movl $0x0, -0x450(%rbp)
movq -0x478(%rbp), %rdi
movslq -0x450(%rbp), %rax
movq %rax, -0x5c8(%rbp)
addq $0x208, %rdi            # imm = 0x208
callq 0x19a40
movq %rax, %rcx
movq -0x5c8(%rbp), %rax
cmpq %rcx, %rax
jae 0x2091b
movq -0x478(%rbp), %rdi
addq $0x208, %rdi            # imm = 0x208
movslq -0x450(%rbp), %rsi
callq 0x19a60
movl (%rax), %eax
movl %eax, -0x444(%rbp)
movl $0x0, -0x454(%rbp)
movq -0x478(%rbp), %rdi
movslq -0x454(%rbp), %rax
movq %rax, -0x5d0(%rbp)
addq $0x220, %rdi            # imm = 0x220
callq 0x19a40
movq %rax, %rcx
movq -0x5d0(%rbp), %rax
cmpq %rcx, %rax
jae 0x20905
movq -0x478(%rbp), %rdi
addq $0x220, %rdi            # imm = 0x220
movslq -0x454(%rbp), %rsi
callq 0x19a60
movq -0x478(%rbp), %rdi
movl (%rax), %eax
movl %eax, -0x448(%rbp)
movl -0x3c(%rbp), %esi
movl -0x24(%rbp), %edx
movq -0x38(%rbp), %rcx
movl -0x3bc(%rbp), %r9d
movl -0x2c(%rbp), %r8d
movl -0x440(%rbp), %r10d
movl -0x444(%rbp), %r11d
movl -0x448(%rbp), %ebx
movl -0x28(%rbp), %r14d
movq %rsp, %rax
movl %r14d, 0x30(%rax)
movl %ebx, 0x28(%rax)
movl %r11d, 0x20(%rax)
movl %r10d, 0x18(%rax)
movl %r8d, 0x10(%rax)
leaq -0x430(%rbp), %r8
movq %r8, 0x8(%rax)
leaq -0x3d0(%rbp), %r8
movq %r8, (%rax)
leaq -0x3b8(%rbp), %r8
callq 0x20bf0
movb %al, -0x5d1(%rbp)
jmp 0x208e3
movb -0x5d1(%rbp), %al
andb $0x1, %al
movb %al, -0x455(%rbp)
movl -0x454(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x454(%rbp)
jmp 0x2081a
jmp 0x20907
movl -0x450(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x450(%rbp)
jmp 0x207ba
jmp 0x2091d
movl -0x44c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x44c(%rbp)
jmp 0x2075a
movl $0x0, -0x45c(%rbp)
cmpl $0x2, -0x45c(%rbp)
jge 0x20990
movslq -0x45c(%rbp), %rax
movq -0x3d0(%rbp,%rax,8), %rax
movq %rax, -0x5e0(%rbp)
cmpq $0x0, %rax
je 0x2097d
movq -0x5e0(%rbp), %rdi
callq 0x34580
movq -0x5e0(%rbp), %rdi
movl $0x30, %esi
callq 0x6440
jmp 0x2097f
movl -0x45c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x45c(%rbp)
jmp 0x2093b
movb $0x1, -0x11(%rbp)
movl $0x1, -0x124(%rbp)
leaq -0x430(%rbp), %rdi
callq 0xbca0
leaq -0x418(%rbp), %rdi
callq 0x345a0
leaq -0x3b8(%rbp), %rdi
callq 0x6828
leaq -0x330(%rbp), %rdi
callq 0x34600
jmp 0x209ea
leaq -0x3b8(%rbp), %rdi
callq 0x6828
leaq -0x330(%rbp), %rdi
callq 0x34600
jmp 0x20a0e
leaq -0x98(%rbp), %rdi
callq 0x345a0
leaq -0x80(%rbp), %rax
movq %rax, -0x5f0(%rbp)
addq $0x30, %rax
movq %rax, -0x5e8(%rbp)
jmp 0x20a32
leaq -0x98(%rbp), %rdi
callq 0x345a0
leaq -0x80(%rbp), %rax
movq %rax, -0x600(%rbp)
addq $0x30, %rax
movq %rax, -0x5f8(%rbp)
jmp 0x20a74
movq -0x5e8(%rbp), %rdi
addq $-0x18, %rdi
movq %rdi, -0x608(%rbp)
callq 0x32680
movq -0x5f0(%rbp), %rcx
movq -0x608(%rbp), %rax
cmpq %rcx, %rax
movq %rax, -0x5e8(%rbp)
jne 0x20a32
movb -0x11(%rbp), %al
andb $0x1, %al
addq $0x640, %rsp            # imm = 0x640
popq %rbx
popq %r14
popq %rbp
retq
movq -0x5f8(%rbp), %rdi
addq $-0x18, %rdi
movq %rdi, -0x610(%rbp)
callq 0x32680
movq -0x600(%rbp), %rcx
movq -0x610(%rbp), %rax
cmpq %rcx, %rax
movq %rax, -0x5f8(%rbp)
jne 0x20a74
jmp 0x20aa7
movq -0xb0(%rbp), %rdi
callq 0x6750
nopw %cs:(%rax,%rax)