// File: /workspace/github_cpp_makefile_star2_O2/ChnMasterOG[P]KmerGO2/kmergo/kmer_union.cpp
// Function: get_Son_Matrix(unsigned short, KmerGO_parameters, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>>, std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>>, std::vector<float, std::allocator<float>>)
void get_Son_Matrix(uint16_t Nprocess, KmerGO_parameters p, std::vector<std::string> kmerdb_list, 
	std::vector<std::string> beacon_kmer, std::vector<float> ALLfcounter)
{
	uint32 i;
	uint32 files_number = kmerdb_list.size();
	uint32 _kmer_length;

	CKMCFile* kmer_data_base = new CKMCFile[files_number];
	FILE* out_file;
	std::string out_file_name = joinPath(p.matrixes_path, "son_matrix_" + std::to_string(Nprocess) + ".txt");

	/* open k-mer data base */
	for (i = 0; i < files_number; i++)
	{
		if (!kmer_data_base[i].OpenForListing(joinPath(p.kmercountings_path, kmerdb_list[i])))
		{
			mtx.lock();
			union_err_number = -11;
			mtx.unlock();
			std::cout << "Thread-" << std::to_string(Nprocess) << "[Error]: Can not open some k-mer database in at least one thread." << std::endl;
			return;
		}
	}

	/* open the output file */
	if ((out_file = fopen(out_file_name.c_str(), "wb")) == NULL)
	{
		mtx.lock();
		union_err_number = -12;
		mtx.unlock();
		std::cout << "Thread-" << std::to_string(Nprocess) << "[Error]: Can not open output files in at least one thread." << std::endl;
		return;
	}
	setvbuf(out_file, NULL, _IOFBF, 1 << 24);

	/* get information from the k-mer database */
	_kmer_length = kmer_data_base[0].KmerLength();
	CKmerAPI kmer_object(_kmer_length);
	CKmerAPI beacon_start_kmer_object(_kmer_length);
	CKmerAPI beacon_end_kmer_object(_kmer_length);
	CKmerAPI minimum_kmer_object(_kmer_length);
	CKmerAPI maximum_kmer_object(_kmer_length);
	uint64 counter;

	/* create beacon k-mer object: start-kmer index is 0; end-kmer index is 1 */
	beacon_start_kmer_object.from_string(beacon_kmer[0]);
	beacon_end_kmer_object.from_string(beacon_kmer[1]);

	/* create minimum/maximum k-mer object */
	std::string temp_str = "";
	for (i = 0; i < _kmer_length - 1; i++) temp_str += "A";
	minimum_kmer_object.from_string(temp_str);	// is less than "A"*_kmer_length (modified kmer_api "operator<" function)
	temp_str = "";
	for (i = 0; i < _kmer_length; i++) temp_str += "T";
	maximum_kmer_object.from_string(temp_str);

	/* write head text */
	fwrite("k-mer", 1, 5, out_file);
	for (i = 0; i < files_number; i++)
	{
		fwrite("\t", 1, 1, out_file);
		fwrite(kmerdb_list[i].c_str(), 1, kmerdb_list[i].length(), out_file);
	}
	fwrite("\n", 1, 1, out_file);
	
	/* jump to corresponding k-mer and build k-mer loser tree */
	KmerLoserTree kmer_losertree(files_number, _kmer_length);
	uint32 end_number = 0;
	bool start_flag;
	for (i = 0; i < files_number; i++)
	{
		start_flag = false;
		while (kmer_data_base[i].ReadNextKmer(kmer_object, counter))
		{
			if (!kmer_object.operator<(beacon_start_kmer_object))
			{
				kmer_losertree.kmer_list[i].operator=(kmer_object);
				kmer_losertree.counter_list[i] = counter;
				start_flag = true;
				break;
			}
		}
		if (!start_flag || !kmer_object.operator<(beacon_end_kmer_object))	// no next k-mer
		{
			end_number++;
			kmer_losertree.kmer_list[i].operator=(maximum_kmer_object);
			kmer_losertree.counter_list[i] = 0;
		}
		else
		{
			mtx.lock();
			progress++;
			mtx.unlock();
		}
	}
	if (end_number == files_number)	// end of running
	{
		for (i = 0; i < files_number; i++) kmer_data_base[i].Close();
		fclose(out_file);
		delete[] kmer_data_base;
		return;
	}
	kmer_losertree.kmer_list[files_number].operator=(minimum_kmer_object);
	kmer_losertree.build();

	/* prepare variables for main loop */
	uint32 min_index;
	uint32 no_zero_counter[2] = { 0, 0 };
	uint32 no_zero_counter_thr[2] = { 1, 1 };
	std::vector<std::string> zero_matrix;
	std::vector<std::string> write_matrix;
	CKmerAPI min_kmer(_kmer_length);
	char temp_cstr[1024];

	if (p.single_step == false)
	{
		no_zero_counter_thr[0] = p.groupA_number * 0.2;
		if (!p.groupA_name.compare("")) no_zero_counter_thr[1] = 1;
		else no_zero_counter_thr[1] = (files_number - p.groupA_number) * 0.2;
	}

	for (i = 0; i < files_number; i++)
	{
		zero_matrix.push_back("\t0");
		write_matrix.push_back("\t0");
	}

	/* main loop */
	while (true)
	{
		min_index = kmer_losertree.getMIN();
		sprintf(temp_cstr, "\t%.4f", (double)kmer_losertree.counter_list[min_index] / ALLfcounter[min_index]);	// normalization
		if (min_kmer.operator==(kmer_losertree.kmer_list[min_index]))	// new k-mer is equal to last k-mer
		{
			write_matrix[min_index] = temp_cstr;
		}
		else
		{
			if (no_zero_counter[0] >= no_zero_counter_thr[0] || no_zero_counter[1] >= no_zero_counter_thr[1])	// write last line
			{
				min_kmer.to_string(temp_str);
				fwrite(temp_str.c_str(), 1, _kmer_length, out_file);
				for (i = 0; i < files_number; i++) fwrite(write_matrix[i].c_str(), 1, write_matrix[i].length(), out_file);
				fwrite("\n", 1, 1, out_file);
			}
			no_zero_counter[0] = no_zero_counter[1] = 0;
			write_matrix = zero_matrix;
			write_matrix[min_index] = temp_cstr;
		}
		if (p.single_step == false)	// count no zero numbers
		{
			if (!p.groupA_name.compare("")) no_zero_counter[0]++;
			else if(!p.trait_information_map[kmerdb_list[min_index]].compare(p.groupA_name)) no_zero_counter[0]++;
			else no_zero_counter[1]++;
		}
		else no_zero_counter[0]++;
		min_kmer.operator=(kmer_losertree.kmer_list[min_index]);
		if (!kmer_data_base[min_index].ReadNextKmer(kmer_object, counter) || !kmer_object.operator<(beacon_end_kmer_object))	// no next k-mer
		{
			end_number++;
			kmer_object = maximum_kmer_object;
			counter = 0;
		}
		else
		{
			mtx.lock();
			progress++;	// update progress
			mtx.unlock();
		}
		if (end_number == files_number)	// end of running
		{
			if (no_zero_counter[0] >= no_zero_counter_thr[0] || no_zero_counter[1] >= no_zero_counter_thr[1])	// write last line
			{
				min_kmer.to_string(temp_str);
				fwrite(temp_str.c_str(), 1, _kmer_length, out_file);
				for (i = 0; i < files_number; i++) fwrite(write_matrix[i].c_str(), 1, write_matrix[i].length(), out_file);
				fwrite("\n", 1, 1, out_file);
			}
			break;
		}
		kmer_losertree.kmer_list[min_index].operator=(kmer_object);
		kmer_losertree.counter_list[min_index] = counter;
		kmer_losertree.adjust(min_index);
	}

	/* close files */
	for (i = 0; i < files_number; i++) kmer_data_base[i].Close();
	fclose(out_file);

	delete[] kmer_data_base;

	return;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x698, %rsp            # imm = 0x698
movq %r8, 0x100(%rsp)
movq %rcx, 0x58(%rsp)
movq %rsi, 0x48(%rsp)
movl %edi, %ebx
movq 0x8(%rdx), %rax
movq %rdx, 0x70(%rsp)
subq (%rdx), %rax
sarq $0x5, %rax
movq %rax, 0x30(%rsp)
movl %eax, %ebp
imulq $0xc0, %rbp, %r14
orq $0x8, %r14
movq %r14, %rdi
callq 0x414e30
movq %rax, 0x38(%rsp)
movq %rbp, (%rax)
addq $0x8, %rax
movq %rax, 0x18(%rsp)
testq %rbp, %rbp
je 0x40668f
imulq $-0xc0, %rbp, %r13
xorl %r12d, %r12d
movq 0x18(%rsp), %r15
movq %r15, %rdi
callq 0x4105b4
addq $-0xc0, %r12
addq $0xc0, %r15
cmpq %r12, %r13
jne 0x406674
movq 0x48(%rsp), %rax
leaq 0x60(%rax), %rsi
leaq 0x230(%rsp), %r14
movq %r14, %rdi
callq 0x486820
movzwl %bx, %ebx
leaq 0x108(%rsp), %rdi
movl %ebx, %esi
callq 0x4060ae
leaq 0x195bdf(%rip), %rsi    # 0x59c2a0
leaq 0x290(%rsp), %rdi
leaq 0x108(%rsp), %rdx
callq 0x406146
leaq 0x195bcf(%rip), %rdx    # 0x59c2ac
leaq 0x1f0(%rsp), %rdi
leaq 0x290(%rsp), %rsi
callq 0x405f45
movl %ebx, 0xc(%rsp)
movq %rbp, 0x40(%rsp)
leaq 0x188(%rsp), %rdi
leaq 0x230(%rsp), %rsi
leaq 0x1f0(%rsp), %rdx
callq 0x405fcb
leaq 0x1f0(%rsp), %rdi
callq 0x484210
leaq 0x290(%rsp), %rdi
callq 0x484210
leaq 0x108(%rsp), %rdi
callq 0x484210
leaq 0x230(%rsp), %rdi
callq 0x484210
movq 0x48(%rsp), %rax
addq $0x40, %rax
movq %rax, 0x10(%rsp)
movl 0x30(%rsp), %eax
movq %rax, 0x60(%rsp)
shlq $0x5, %rax
movq %rax, 0x78(%rsp)
addq $0x20, %rax
movq %rax, 0x20(%rsp)
xorl %ebp, %ebp
leaq 0x270(%rsp), %r13
leaq 0x250(%rsp), %rbx
movq 0x18(%rsp), %r15
leaq 0x20(%rbp), %r14
cmpq %r14, 0x20(%rsp)
je 0x40687a
movq %r13, %rdi
movq 0x10(%rsp), %rsi
callq 0x486820
movq 0x70(%rsp), %rax
addq (%rax), %rbp
movq %rbx, %rdi
movq %rbp, %rsi
callq 0x486820
leaq 0x290(%rsp), %rbp
movq %rbp, %rdi
movq %r13, %rsi
movq %rbx, %rdx
callq 0x405fcb
movq %r15, %rdi
movq %rbp, %rsi
callq 0x410460
movl %eax, %r12d
addq $0xc0, %r15
movq %rbp, %rdi
callq 0x484210
movq %rbx, %rdi
callq 0x484210
movq %r13, %rdi
callq 0x484210
movq %r14, %rbp
testb %r12b, %r12b
jne 0x40678c
leaq 0x20fedb(%rip), %rdi    # 0x6166e8
callq 0x407f5e
movw $0xfff5, 0x20febf(%rip) # imm = 0xFFF5
leaq 0x20fec6(%rip), %rdi    # 0x6166e8
callq 0x4f57b0
movq $0x1b6c960, %rdi        # imm = 0x1B6C960
leaq 0x195a7c(%rip), %rsi    # 0x59c2b1
callq 0x47de40
movq %rax, %rbx
leaq 0x290(%rsp), %rdi
movl 0xc(%rsp), %esi
callq 0x4060ae
leaq 0x290(%rsp), %rsi
movq %rbx, %rdi
callq 0x486ac0
leaq 0x195a54(%rip), %rsi    # 0x59c2b9
movq %rax, %rdi
callq 0x47de40
movq %rax, %rdi
callq 0x47d720
jmp 0x406bd4
movq 0x188(%rsp), %rdi
leaq 0x195a72(%rip), %rsi    # 0x59c2fb
callq 0x4e6bf0
testq %rax, %rax
je 0x406b65
movq %rax, %r14
movl $0x1000000, %ecx        # imm = 0x1000000
movq %rax, %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x4e7ac0
movq 0x18(%rsp), %rdi
callq 0x410ff2
movl %eax, %ebx
leaq 0x1d8(%rsp), %rdi
movl %eax, %esi
callq 0x407f72
leaq 0x1c0(%rsp), %rdi
movl %ebx, %esi
callq 0x407f72
leaq 0x170(%rsp), %rdi
movl %ebx, %esi
callq 0x407f72
leaq 0x1a8(%rsp), %rdi
movl %ebx, %esi
callq 0x407f72
leaq 0x158(%rsp), %rdi
movl %ebx, 0x10(%rsp)
movl %ebx, %esi
callq 0x407f72
movq 0x58(%rsp), %rbx
movq (%rbx), %rsi
leaq 0x1c0(%rsp), %rdi
callq 0x407fe8
movq (%rbx), %rsi
addq $0x20, %rsi
leaq 0x170(%rsp), %rdi
callq 0x407fe8
leaq 0x1ba574(%rip), %rsi    # 0x5c0eaa
leaq 0xa8(%rsp), %rdi
leaq 0x290(%rsp), %rdx
callq 0x405d40
pushq $0x1
popq %rbp
leaq 0x1ac4d8(%rip), %rbx    # 0x5b2e2d
leaq 0xa8(%rsp), %r15
cmpl %ebp, 0x10(%rsp)
je 0x406972
movq %r15, %rdi
movq %rbx, %rsi
callq 0x4859c0
incl %ebp
jmp 0x40695d
leaq 0x1a8(%rsp), %rdi
leaq 0xa8(%rsp), %rsi
callq 0x407fe8
leaq 0x1ba51c(%rip), %rsi    # 0x5c0eaa
leaq 0xa8(%rsp), %rdi
callq 0x4851c0
leaq 0x1ac493(%rip), %rbx    # 0x5b2e35
leaq 0xa8(%rsp), %r15
movl 0x10(%rsp), %ebp
subl $0x1, %ebp
jb 0x4069c0
movq %r15, %rdi
movq %rbx, %rsi
callq 0x4859c0
jmp 0x4069ae
leaq 0x158(%rsp), %rdi
leaq 0xa8(%rsp), %rsi
callq 0x407fe8
leaq 0x19595d(%rip), %rdi    # 0x59c339
pushq $0x1
popq %rbx
pushq $0x5
popq %rdx
movq %rbx, %rsi
movq %r14, %rcx
callq 0x4e7070
xorl %r15d, %r15d
pushq $0x9
popq %rbp
cmpq %r15, 0x78(%rsp)
je 0x406a26
movl %ebp, %edi
movq %r14, %rsi
callq 0x4eb5d0
movq 0x70(%rsp), %rax
movq (%rax), %rax
movq (%rax,%r15), %rdi
movq 0x8(%rax,%r15), %rdx
movq %rbx, %rsi
movq %r14, %rcx
callq 0x4e7070
addq $0x20, %r15
jmp 0x4069f3
pushq $0xa
popq %rdi
movq %r14, %rsi
callq 0x4eb5d0
leaq 0x108(%rsp), %rdi
movq 0x30(%rsp), %rsi
movl 0x10(%rsp), %edx
callq 0x40e474
xorl %r13d, %r13d
leaq 0x1d8(%rsp), %rbx
leaq 0x68(%rsp), %rbp
leaq 0x1c0(%rsp), %r12
movl $0x0, 0x20(%rsp)
movq 0x60(%rsp), %r15
cmpq %r15, %r13
je 0x406b2d
imulq $0xc0, %r13, %r15
addq 0x18(%rsp), %r15
movq %r15, %rdi
movq %rbx, %rsi
movq %rbp, %rdx
callq 0x410c90
testb %al, %al
je 0x406afb
movq %rbx, %rdi
movq %r12, %rsi
callq 0x408018
testb %al, %al
jne 0x406a81
imulq $0x18, %r13, %rdi
addq 0x128(%rsp), %rdi
movq %rbx, %rsi
callq 0x40805e
movl 0x68(%rsp), %eax
movq 0x140(%rsp), %rcx
movl %eax, (%rcx,%r13,4)
movq %rbx, %rdi
leaq 0x170(%rsp), %rsi
callq 0x408018
testb %al, %al
je 0x406afb
leaq 0x20fc07(%rip), %rdi    # 0x6166e8
callq 0x407f5e
incq 0x20fbf3(%rip)          # 0x6166e0
leaq 0x20fbf4(%rip), %rdi    # 0x6166e8
callq 0x4f57b0
jmp 0x406b25
imulq $0x18, %r13, %rdi
addq 0x128(%rsp), %rdi
leaq 0x158(%rsp), %rsi
callq 0x40805e
incl 0x20(%rsp)
movq 0x140(%rsp), %rax
andl $0x0, (%rax,%r13,4)
incq %r13
jmp 0x406a67
movl 0x20(%rsp), %eax
cmpl 0x30(%rsp), %eax
jne 0x406be6
movq 0x38(%rsp), %r12
subq $0x1, %r15
jb 0x406c68
movq 0x18(%rsp), %rbx
movq %rbx, %rdi
callq 0x410e72
addq $0xc0, %rbx
movq %rbx, 0x18(%rsp)
jmp 0x406b40
leaq 0x20fb7c(%rip), %rdi    # 0x6166e8
callq 0x407f5e
movw $0xfff4, 0x20fb60(%rip) # imm = 0xFFF4
leaq 0x20fb67(%rip), %rdi    # 0x6166e8
callq 0x4f57b0
movq $0x1b6c960, %rdi        # imm = 0x1B6C960
leaq 0x19571d(%rip), %rsi    # 0x59c2b1
callq 0x47de40
movq %rax, %rbx
leaq 0x290(%rsp), %rdi
movl 0xc(%rsp), %esi
callq 0x4060ae
leaq 0x290(%rsp), %rsi
movq %rbx, %rdi
callq 0x486ac0
leaq 0x19573a(%rip), %rsi    # 0x59c2fe
movq %rax, %rdi
callq 0x47de40
movq %rax, %rdi
callq 0x47d720
leaq 0x290(%rsp), %rdi
callq 0x484210
jmp 0x4071c6
imulq $0x18, 0x40(%rsp), %rdi
addq 0x128(%rsp), %rdi
leaq 0x1a8(%rsp), %rsi
callq 0x40805e
leaq 0x108(%rsp), %rdi
callq 0x40e5e6
xorpd %xmm0, %xmm0
movapd %xmm0, 0xe0(%rsp)
andq $0x0, 0xf0(%rsp)
movapd %xmm0, 0x80(%rsp)
andq $0x0, 0x90(%rsp)
leaq 0xc8(%rsp), %rdi
movl 0x10(%rsp), %esi
callq 0x407f72
pushq $0x1
popq %r15
movq 0x48(%rsp), %rbx
cmpb $0x0, 0x100(%rbx)
je 0x406cb0
movq %r15, 0x50(%rsp)
movq %r15, 0x40(%rsp)
jmp 0x406d0d
movq %r14, %rdi
callq 0x4e64c0
movq (%r12), %rax
imulq $0xc0, %rax, %r14
leaq 0x8(%r14), %rbx
testq %rax, %rax
je 0x406ca0
movq %r12, %r15
addq $-0xb8, %r15
leaq (%r15,%r14), %rdi
callq 0x4105d6
addq $-0xc0, %r14
jne 0x406c8e
movq %r12, %rdi
movq %rbx, %rsi
callq 0x413f50
jmp 0x40716b
movl 0x128(%rbx), %eax
cvtsi2sd %rax, %xmm0
mulsd 0x19558d(%rip), %xmm0   # 0x59c250
cvttsd2si %xmm0, %rax
movq %rax, 0x40(%rsp)
leaq 0x108(%rbx), %rdi
leaq 0x1ba1cf(%rip), %rsi    # 0x5c0eaa
callq 0x486420
testl %eax, %eax
je 0x406d08
movq 0x30(%rsp), %rax
subl 0x128(%rbx), %eax
cvtsi2sd %rax, %xmm0
mulsd 0x195554(%rip), %xmm0   # 0x59c250
cvttsd2si %xmm0, %rax
movq %rax, 0x50(%rsp)
jmp 0x406d0d
movq %r15, 0x50(%rsp)
leaq 0x19562b(%rip), %rbx    # 0x59c33f
leaq 0x210(%rsp), %r15
leaq 0x2f(%rsp), %r12
leaq 0x80(%rsp), %rbp
movq 0x30(%rsp), %rax
movl %eax, %r13d
subl $0x1, %r13d
jb 0x406d80
movq %r15, %rdi
movq %rbx, %rsi
movq %r12, %rdx
callq 0x405d40
leaq 0xe0(%rsp), %rdi
movq %r15, %rsi
callq 0x4061f4
movq %r15, %rdi
callq 0x484210
movq %r15, %rdi
movq %rbx, %rsi
movq %r12, %rdx
callq 0x405d40
movq %rbp, %rdi
movq %r15, %rsi
callq 0x4061f4
movq %r15, %rdi
callq 0x484210
jmp 0x406d31
movl 0x10(%rsp), %eax
movq %rax, 0xa0(%rsp)
movq 0x48(%rsp), %rax
leaq 0x108(%rax), %rcx
movq %rcx, 0x58(%rsp)
addq $0x158, %rax            # imm = 0x158
movq %rax, 0xf8(%rsp)
xorl %r13d, %r13d
leaq 0x1d8(%rsp), %r12
movl $0x0, 0xc(%rsp)
leaq 0x108(%rsp), %rdi
callq 0x40e62a
movl %eax, 0x10(%rsp)
movq %r14, %rbx
movq %r13, %r14
movq %r12, %r13
movl 0x10(%rsp), %r15d
movq 0x140(%rsp), %rax
movl (%rax,%r15,4), %eax
cvtsi2sd %rax, %xmm0
movq 0x100(%rsp), %rax
movq (%rax), %rax
cvtss2sd (%rax,%r15,4), %xmm1
divsd %xmm1, %xmm0
leaq 0x290(%rsp), %r12
movq %r12, %rdi
leaq 0x19552d(%rip), %rsi    # 0x59c342
movb $0x1, %al
callq 0x4dff70
imulq $0x18, %r15, %rbp
movq 0x128(%rsp), %rsi
addq %rbp, %rsi
leaq 0xc8(%rsp), %rdi
callq 0x4080d4
testb %al, %al
je 0x406e61
movq %r15, %rdi
shlq $0x5, %rdi
addq 0x80(%rsp), %rdi
movq %r12, %rsi
callq 0x4851c0
movq %r13, %r12
movq %r14, %r13
movq %rbx, %r14
jmp 0x406f1b
cmpl 0x40(%rsp), %r14d
movq %r13, %r12
movq %rbx, %r14
jae 0x406e78
movl 0xc(%rsp), %eax
cmpl 0x50(%rsp), %eax
jb 0x406edf
leaq 0xc8(%rsp), %rdi
leaq 0xa8(%rsp), %rsi
callq 0x408104
movq 0xa8(%rsp), %rdi
pushq $0x1
popq %rsi
movq 0xa0(%rsp), %rdx
movq %r14, %rcx
callq 0x4e7070
xorl %r13d, %r13d
cmpq %r13, 0x78(%rsp)
je 0x406ed4
movq 0x80(%rsp), %rax
movq (%rax,%r13), %rdi
movq 0x8(%rax,%r13), %rdx
pushq $0x1
popq %rsi
movq %r14, %rcx
callq 0x4e7070
addq $0x20, %r13
jmp 0x406eab
pushq $0xa
popq %rdi
movq %r14, %rsi
callq 0x4eb5d0
leaq 0x80(%rsp), %rdi
leaq 0xe0(%rsp), %rsi
callq 0x40812c
movq %r15, %rdi
shlq $0x5, %rdi
addq 0x80(%rsp), %rdi
xorl %r13d, %r13d
leaq 0x290(%rsp), %rsi
callq 0x4851c0
movl $0x0, 0xc(%rsp)
movq 0x48(%rsp), %rax
cmpb $0x0, 0x100(%rax)
je 0x407001
incl %r13d
movq 0x128(%rsp), %rsi
addq %rbp, %rsi
leaq 0xc8(%rsp), %rdi
callq 0x40805e
imulq $0xc0, %r15, %rdi
addq 0x18(%rsp), %rdi
movq %r12, %rsi
leaq 0x68(%rsp), %rdx
callq 0x410c90
testb %al, %al
je 0x406f9e
movq %r12, %rdi
leaq 0x170(%rsp), %rsi
callq 0x408018
testb %al, %al
je 0x406f9e
leaq 0x20f768(%rip), %rdi    # 0x6166e8
callq 0x407f5e
incq 0x20f754(%rip)          # 0x6166e0
leaq 0x20f755(%rip), %rdi    # 0x6166e8
callq 0x4f57b0
movl 0x20(%rsp), %eax
jmp 0x406fba
movq %r12, %rdi
leaq 0x158(%rsp), %rsi
callq 0x40805e
movl 0x20(%rsp), %eax
incl %eax
andq $0x0, 0x68(%rsp)
movl %eax, 0x20(%rsp)
cmpl 0x30(%rsp), %eax
je 0x407054
addq 0x128(%rsp), %rbp
movq %rbp, %rdi
movq %r12, %rsi
callq 0x40805e
movl 0x68(%rsp), %eax
movq 0x140(%rsp), %rcx
movl %eax, (%rcx,%r15,4)
leaq 0x108(%rsp), %rdi
movl 0x10(%rsp), %esi
callq 0x40e568
jmp 0x406dbe
movq 0x58(%rsp), %rdi
leaq 0x1b9e9d(%rip), %rsi    # 0x5c0eaa
callq 0x486420
testl %eax, %eax
je 0x406f2d
movq %r15, %rsi
shlq $0x5, %rsi
movq 0x70(%rsp), %rax
addq (%rax), %rsi
movq 0xf8(%rsp), %rdi
callq 0x4081f6
movq %rax, %rdi
movq 0x58(%rsp), %rsi
callq 0x486270
testl %eax, %eax
je 0x406f2d
incl 0xc(%rsp)
jmp 0x406f30
cmpl 0x40(%rsp), %r13d
jae 0x40706c
movl 0xc(%rsp), %eax
cmpl 0x50(%rsp), %eax
jae 0x40706c
movq 0x38(%rsp), %r12
jmp 0x4070db
leaq 0xc8(%rsp), %rdi
leaq 0xa8(%rsp), %rsi
callq 0x408104
movq 0x38(%rsp), %r12
movq 0xa8(%rsp), %rdi
pushq $0x1
popq %rbx
movq %rbx, %rsi
movq 0xa0(%rsp), %rdx
movq %r14, %rcx
callq 0x4e7070
xorl %r15d, %r15d
cmpq %r15, 0x78(%rsp)
je 0x4070d0
movq 0x80(%rsp), %rax
movq (%rax,%r15), %rdi
movq 0x8(%rax,%r15), %rdx
movq %rbx, %rsi
movq %r14, %rcx
callq 0x4e7070
addq $0x20, %r15
jmp 0x4070a7
pushq $0xa
popq %rdi
movq %r14, %rsi
callq 0x4eb5d0
movq 0x60(%rsp), %r15
subq $0x1, %r15
jb 0x407101
movq 0x18(%rsp), %rbx
movq %rbx, %rdi
callq 0x410e72
addq $0xc0, %rbx
movq %rbx, 0x18(%rsp)
jmp 0x4070e0
movq %r14, %rdi
callq 0x4e64c0
movq (%r12), %rax
imulq $0xc0, %rax, %r14
leaq 0x8(%r14), %rbx
testq %rax, %rax
je 0x407139
movq %r12, %r15
addq $-0xb8, %r15
leaq (%r15,%r14), %rdi
callq 0x4105d6
addq $-0xc0, %r14
jne 0x407127
movq %r12, %rdi
movq %rbx, %rsi
callq 0x413f50
leaq 0xc8(%rsp), %rdi
callq 0x40825c
leaq 0x80(%rsp), %rdi
callq 0x40616a
leaq 0xe0(%rsp), %rdi
callq 0x40616a
leaq 0x108(%rsp), %rdi
callq 0x40e53e
leaq 0xa8(%rsp), %rdi
callq 0x484210
leaq 0x158(%rsp), %rdi
callq 0x40825c
leaq 0x1a8(%rsp), %rdi
callq 0x40825c
leaq 0x170(%rsp), %rdi
callq 0x40825c
leaq 0x1c0(%rsp), %rdi
callq 0x40825c
leaq 0x1d8(%rsp), %rdi
callq 0x40825c
leaq 0x188(%rsp), %rdi
callq 0x484210
addq $0x698, %rsp            # imm = 0x698
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x40733f
movq %rax, %rbx
jmp 0x40734f
jmp 0x4072da
jmp 0x40736b
jmp 0x4072b6
jmp 0x40722f
movq %rax, %rbx
jmp 0x407395
movq %rax, %rbx
jmp 0x4073a2
movq %rax, %rbx
jmp 0x4073af
movq %rax, %rbx
jmp 0x4073bc
jmp 0x4072da
jmp 0x4072da
jmp 0x40727a
movq %rax, %rbx
jmp 0x407388
jmp 0x4072b6
movq %rax, %rbx
leaq 0x1f0(%rsp), %rdi
callq 0x484210
jmp 0x40724e
movq %rax, %rbx
leaq 0x290(%rsp), %rdi
callq 0x484210
jmp 0x407260
movq %rax, %rbx
leaq 0x108(%rsp), %rdi
callq 0x484210
jmp 0x407272
movq %rax, %rbx
movq %r14, %rdi
jmp 0x4073d1
movq %rax, %rbx
leaq 0x290(%rsp), %rdi
jmp 0x4072fa
jmp 0x4072da
jmp 0x40733f
jmp 0x40733f
jmp 0x40729a
jmp 0x40733f
movq %rax, %rbx
leaq 0x210(%rsp), %rdi
callq 0x484210
jmp 0x407342
jmp 0x40736b
jmp 0x4072b6
movq %rax, %rbx
jmp 0x40737b
jmp 0x40736b
movq %rax, %rbx
jmp 0x4072f2
movq %rax, %rbx
leaq 0x290(%rsp), %rdi
callq 0x484210
jmp 0x4072e5
movq %rax, %rbx
jmp 0x4073c9
movq %rax, %rbx
leaq 0x250(%rsp), %rdi
callq 0x484210
leaq 0x270(%rsp), %rdi
callq 0x484210
jmp 0x4073c9
movq %rax, %rbx
testq %r12, %r12
je 0x40732d
negq %r12
movq 0x38(%rsp), %r15
addq $-0xb8, %r15
leaq (%r15,%r12), %rdi
callq 0x4105d6
addq $-0xc0, %r12
jne 0x40731b
movq 0x38(%rsp), %rdi
movq %r14, %rsi
callq 0x413f50
jmp 0x4073d6
movq %rax, %rbx
leaq 0xc8(%rsp), %rdi
callq 0x40825c
leaq 0x80(%rsp), %rdi
callq 0x40616a
leaq 0xe0(%rsp), %rdi
callq 0x40616a
jmp 0x40736e
movq %rax, %rbx
leaq 0x108(%rsp), %rdi
callq 0x40e53e
leaq 0xa8(%rsp), %rdi
callq 0x484210
leaq 0x158(%rsp), %rdi
callq 0x40825c
leaq 0x1a8(%rsp), %rdi
callq 0x40825c
leaq 0x170(%rsp), %rdi
callq 0x40825c
leaq 0x1c0(%rsp), %rdi
callq 0x40825c
leaq 0x1d8(%rsp), %rdi
callq 0x40825c
leaq 0x188(%rsp), %rdi
callq 0x484210
movq %rbx, %rdi
callq 0x4b8e10