// File: simonrharris[P]SKA/src/sk_weed.cpp
// Function: weedKmers(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>>>> const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, float, float, int, int)
int weedKmers(const std::vector < std::string > & weedfiles, const std::string & kmerfile, const float minproportion, const float maxproportion, int minsamples, int maxsamples)
{

	const std::chrono::high_resolution_clock::time_point start = std::chrono::high_resolution_clock::now();
	// Create the kmer map
	std::set < std::string > kmerSet;
	
	std::ifstream fileStream;

	

	int kmersize=0;
	char base;
	
	

	if (kmerfile!=""){
		if (openFileStream(kmerfile, fileStream)){return 1;};
		std::vector < std::string > weednames;
		
		readKmerHeader(fileStream, kmersize, weednames);
		char kmerbuffer[kmersize*2/3];
		char asciibuffer[int(ceil(float(weednames.size())/6))];
		
		while (fileStream.read(asciibuffer, sizeof(asciibuffer))){
			std::string asciibits (asciibuffer, sizeof(asciibuffer));
			
			while (fileStream.peek()!='\n' && fileStream.get(base)){
				fileStream.read(kmerbuffer, sizeof(kmerbuffer));
				std::string kmer (kmerbuffer, sizeof(kmerbuffer));
				kmerSet.insert(kmer);
			}
			fileStream.ignore(256,'\n');//skip the end ofline character
	    }
		fileStream.close();
		
		std::cout << kmerSet.size() << " unique kmers in weed set" << std::endl;

		
	}


	std:: vector < std::string > sampleNames;
	if (collectSampleNames(weedfiles, sampleNames)!=0){return 1;}

	if (maxsamples==0){
		maxsamples=sampleNames.size();
	}
	else if (maxsamples>sampleNames.size()){
		std::cerr << "Warning: Maxsamples is greater than the number of samples in your files." << std::endl;
	}
	if (minsamples>sampleNames.size()){
		std::cerr << "Error: Minsamples is greater than the number of samples in your files." << std::endl;
		return 1;
	}

	int myminsamples=std::ceil(minproportion*sampleNames.size());
	int mymaxsamples;
	if (maxproportion==1.0){
		mymaxsamples=sampleNames.size();
	}
	else{
		mymaxsamples=std::floor(maxproportion*sampleNames.size());
	}

	if (myminsamples>minsamples){
		minsamples=myminsamples;
	}
	if (mymaxsamples<maxsamples){
		maxsamples=mymaxsamples;
	}

	if (minsamples>0 || maxsamples<sampleNames.size()){
		if (addKmersByFilters (kmerSet, weedfiles, minsamples, maxsamples, kmersize, sampleNames.size())){return 1;};
		std::cout << kmerSet.size() << " unique kmers in weed set" << std::endl;
	}
	
	int weeded=0;
	int totalweedkmers=0;
	
	for (std::vector < std::string >::const_iterator it = weedfiles.begin(); it != weedfiles.end(); ++it){

		if (openFileStream(*it, fileStream)){return 1;};

		int weedkmersize;
		std::vector < std::string > names;
		
		readKmerHeader(fileStream, weedkmersize, names);
		char kmerbuffer[weedkmersize*2/3];
		
		if (weedkmersize!=kmersize){
			std::cerr << "Files have different kmer sizes" << std::endl << std::endl;
			return 1;
		}
		std::string filename=std::string(*it);
		std::string outputfile=filename.substr(0, filename.find_last_of("."))+".weeded"+filename.substr(filename.find_last_of("."), filename.length());

		std::cout << "Writing weeded kmers to " << outputfile << std::endl;
	
		std::ofstream weededfile(outputfile);
		weededfile << "SKA v" << versionNumber << std::endl;
		weededfile << kmersize << std::endl;
		for ( std::vector < std::string >::iterator it=names.begin(); it!=names.end(); ++it){ //print each sample name to output file stream
			weededfile << *it << " "; 
		}
		weededfile << std::endl;

		bool firstkmer=true;

		char asciibuffer[int(ceil(float(names.size())/6))];
		while (fileStream.read(asciibuffer, sizeof(asciibuffer))){
			std::string asciibits (asciibuffer, sizeof(asciibuffer));
			
			while (fileStream.peek()!='\n' && fileStream.get(base)){
				fileStream.read(kmerbuffer, sizeof(kmerbuffer));
				std::string kmer (kmerbuffer, kmersize*2/3);
				
				std::set < std::string >::iterator it2 = kmerSet.find(kmer);//check if the kmer is in the hash
				if ( it2 == kmerSet.end() ){//if the kmer is not in the hash
					if (firstkmer){//if it's the first kmer, print the ascii bitstring
						weededfile << asciibits;
						firstkmer=false;
					}
					weededfile << base << kmer;//print the kmer
					weeded++;
				}
				totalweedkmers++;
			}
			if (firstkmer==false){
				weededfile << std::endl;
			}
			firstkmer=true;
			fileStream.ignore(256,'\n');//skip the end ofline character
    	}
		fileStream.close();
		weededfile.close();
	}
	std::cout << totalweedkmers << " kmers prior to weeding" << std::endl;
	std::cout << weeded << " kmers remaining after weeding" << std::endl;
	std::cout << totalweedkmers-weeded << " kmers weeded (Note this may be more than the number of kmers in the weed set due to mulitple variants of a kmer being in the file)" << std::endl;

	printDuration(start);
	
	return 0;
	
	
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x8c0, %rsp            # imm = 0x8C0
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movss %xmm0, -0x1c(%rbp)
movss %xmm1, -0x20(%rbp)
movl %edx, -0x24(%rbp)
movl %ecx, -0x28(%rbp)
callq 0x6080
movq %rax, -0x30(%rbp)
leaq -0x60(%rbp), %rdi
callq 0xf2f0
leaq -0x268(%rbp), %rdi
callq 0x65f0
jmp 0x490c3
movl $0x0, -0x278(%rbp)
movq -0x18(%rbp), %rdi
leaq 0x111da(%rip), %rsi     # 0x5a2b2
callq 0x2df20
movb %al, -0x6a1(%rbp)
jmp 0x490e5
movb -0x6a1(%rbp), %al
testb $0x1, %al
jne 0x490f4
jmp 0x4957d
movq -0x18(%rbp), %rdi
leaq -0x268(%rbp), %rsi
movl $0x1, %edx
callq 0xa4f0
movl %eax, -0x6a8(%rbp)
jmp 0x49111
movl -0x6a8(%rbp), %eax
cmpl $0x0, %eax
je 0x49160
movl $0x1, -0x4(%rbp)
movl $0x1, -0x280(%rbp)
jmp 0x4a3f2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x270(%rbp)
movl %eax, -0x274(%rbp)
jmp 0x4a41b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x270(%rbp)
movl %eax, -0x274(%rbp)
jmp 0x4a40f
leaq -0x298(%rbp), %rdi
movq %rdi, -0x6b0(%rbp)
callq 0x1ab40
movq -0x6b0(%rbp), %rdx
leaq -0x268(%rbp), %rdi
leaq -0x278(%rbp), %rsi
callq 0xcd40
jmp 0x4918f
movl -0x278(%rbp), %eax
addl %eax, %eax
cltq
imulq $0x55555556, %rax, %rax # imm = 0x55555556
movq %rax, %rcx
shrq $0x3f, %rcx
shrq $0x20, %rax
addl %ecx, %eax
movq %rax, -0x6c8(%rbp)
movq %rsp, %rcx
movq %rcx, -0x2a0(%rbp)
movq %rax, %rdx
addq $0xf, %rdx
andq $-0x10, %rdx
movq %rsp, %rcx
subq %rdx, %rcx
movq %rcx, -0x6c0(%rbp)
movq %rcx, %rsp
movq %rax, -0x2a8(%rbp)
leaq -0x298(%rbp), %rdi
callq 0xb670
movq %rax, %rdx
shrq %rdx
movl %eax, %ecx
andl $0x1, %ecx
orq %rdx, %rcx
cvtsi2ss %rcx, %xmm0
addss %xmm0, %xmm0
cvtsi2ss %rax, %xmm1
movss %xmm1, -0x6b8(%rbp)
testq %rax, %rax
movss %xmm0, -0x6b4(%rbp)
js 0x4922d
movss -0x6b8(%rbp), %xmm0
movss %xmm0, -0x6b4(%rbp)
movss -0x6b4(%rbp), %xmm0
movss 0x1043f(%rip), %xmm1    # 0x5967c
divss %xmm1, %xmm0
cvtss2sd %xmm0, %xmm0
callq 0x60b0
cvttsd2si %xmm0, %eax
movq %rax, -0x6d8(%rbp)
movq %rax, %rdx
addq $0xf, %rdx
andq $-0x10, %rdx
movq %rsp, %rcx
subq %rdx, %rcx
movq %rcx, -0x6d0(%rbp)
movq %rcx, %rsp
movq %rax, -0x2b0(%rbp)
movq -0x6d8(%rbp), %rdx
movq -0x6d0(%rbp), %rsi
leaq -0x268(%rbp), %rdi
callq 0x6680
movq %rax, -0x6e0(%rbp)
jmp 0x4929a
movq -0x6e0(%rbp), %rdi
movq (%rdi), %rax
movq -0x18(%rax), %rax
addq %rax, %rdi
callq 0x6670
movb %al, -0x6e1(%rbp)
jmp 0x492b8
movb -0x6e1(%rbp), %al
testb $0x1, %al
jne 0x492c7
jmp 0x494f4
leaq -0x2d1(%rbp), %rdi
movq %rdi, -0x6f0(%rbp)
callq 0x6910
movq -0x6d0(%rbp), %rsi
movq -0x6d8(%rbp), %rdx
movq -0x6f0(%rbp), %rcx
leaq -0x2d0(%rbp), %rdi
callq 0x65e0
jmp 0x492fd
leaq -0x2d1(%rbp), %rdi
callq 0x65a0
leaq -0x268(%rbp), %rdi
callq 0x61c0
movl %eax, -0x6f4(%rbp)
jmp 0x4931d
movl -0x6f4(%rbp), %ecx
xorl %eax, %eax
cmpl $0xa, %ecx
movb %al, -0x6f5(%rbp)
je 0x49378
leaq -0x268(%rbp), %rdi
leaq -0x279(%rbp), %rsi
callq 0x6720
movq %rax, -0x700(%rbp)
jmp 0x4934c
movq -0x700(%rbp), %rdi
movq (%rdi), %rax
movq -0x18(%rax), %rax
addq %rax, %rdi
callq 0x6670
movb %al, -0x701(%rbp)
jmp 0x4936a
movb -0x701(%rbp), %al
movb %al, -0x6f5(%rbp)
jmp 0x49378
movb -0x6f5(%rbp), %al
testb $0x1, %al
jne 0x49387
jmp 0x494bd
movq -0x6c8(%rbp), %rdx
movq -0x6c0(%rbp), %rsi
leaq -0x268(%rbp), %rdi
callq 0x6680
jmp 0x493a3
leaq -0x2f9(%rbp), %rdi
movq %rdi, -0x710(%rbp)
callq 0x6910
movq -0x6c0(%rbp), %rsi
movq -0x6c8(%rbp), %rdx
movq -0x710(%rbp), %rcx
leaq -0x2f8(%rbp), %rdi
callq 0x65e0
jmp 0x493d9
leaq -0x2f9(%rbp), %rdi
callq 0x65a0
leaq -0x60(%rbp), %rdi
leaq -0x2f8(%rbp), %rsi
callq 0xf310
movb %dl, -0x719(%rbp)
movq %rax, -0x718(%rbp)
jmp 0x49404
movb -0x719(%rbp), %al
movq -0x718(%rbp), %rcx
movq %rcx, -0x310(%rbp)
movb %al, -0x308(%rbp)
leaq -0x2f8(%rbp), %rdi
callq 0x6a08
jmp 0x49309
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x270(%rbp)
movl %eax, -0x274(%rbp)
jmp 0x4956c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x270(%rbp)
movl %eax, -0x274(%rbp)
leaq -0x2d1(%rbp), %rdi
callq 0x65a0
jmp 0x4956c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x270(%rbp)
movl %eax, -0x274(%rbp)
jmp 0x494e6
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x270(%rbp)
movl %eax, -0x274(%rbp)
leaq -0x2f9(%rbp), %rdi
callq 0x65a0
jmp 0x494e6
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x270(%rbp)
movl %eax, -0x274(%rbp)
leaq -0x2f8(%rbp), %rdi
callq 0x6a08
jmp 0x494e6
leaq -0x268(%rbp), %rdi
movl $0x100, %esi            # imm = 0x100
movl $0xa, %edx
callq 0x6340
jmp 0x494d5
leaq -0x2d0(%rbp), %rdi
callq 0x6a08
jmp 0x49277
leaq -0x2d0(%rbp), %rdi
callq 0x6a08
jmp 0x4956c
leaq -0x268(%rbp), %rdi
callq 0x60f0
jmp 0x49502
leaq -0x60(%rbp), %rdi
callq 0xf360
movq %rax, %rsi
movq 0x2fa93(%rip), %rdi     # 0x78fa8
callq 0x6120
movq %rax, -0x728(%rbp)
jmp 0x49523
movq -0x728(%rbp), %rdi
leaq 0x11233(%rip), %rsi     # 0x5a764
callq 0x6520
movq %rax, -0x730(%rbp)
jmp 0x4953f
movq -0x730(%rbp), %rdi
movq 0x2fa43(%rip), %rsi     # 0x78f90
callq 0x6570
jmp 0x49554
movq -0x2a0(%rbp), %rax
movq %rax, %rsp
leaq -0x298(%rbp), %rdi
callq 0xfe90
jmp 0x4957d
leaq -0x298(%rbp), %rdi
callq 0xfe90
jmp 0x4a40f
leaq -0x328(%rbp), %rdi
movq %rdi, -0x740(%rbp)
callq 0x1ab40
movq -0x740(%rbp), %rsi
movq -0x10(%rbp), %rdi
movl $0x1, %edx
callq 0xced0
movl %eax, -0x734(%rbp)
jmp 0x495ad
movl -0x734(%rbp), %eax
cmpl $0x0, %eax
je 0x495e5
movl $0x1, -0x4(%rbp)
movl $0x1, -0x280(%rbp)
jmp 0x4a3d6
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x270(%rbp)
movl %eax, -0x274(%rbp)
jmp 0x4a3e4
cmpl $0x0, -0x28(%rbp)
jne 0x495fc
leaq -0x328(%rbp), %rdi
callq 0xb670
movl %eax, -0x28(%rbp)
jmp 0x49657
movslq -0x28(%rbp), %rax
movq %rax, -0x748(%rbp)
leaq -0x328(%rbp), %rdi
callq 0xb670
movq %rax, %rcx
movq -0x748(%rbp), %rax
cmpq %rcx, %rax
jbe 0x49655
movq 0x2f9c7(%rip), %rdi     # 0x78ff0
leaq 0x1114e(%rip), %rsi     # 0x5a77e
callq 0x6520
movq %rax, -0x750(%rbp)
jmp 0x4963e
movq -0x750(%rbp), %rdi
movq 0x2f944(%rip), %rsi     # 0x78f90
callq 0x6570
jmp 0x49653
jmp 0x49655
jmp 0x49657
movslq -0x24(%rbp), %rax
movq %rax, -0x758(%rbp)
leaq -0x328(%rbp), %rdi
callq 0xb670
movq %rax, %rcx
movq -0x758(%rbp), %rax
cmpq %rcx, %rax
jbe 0x496c4
movq 0x2f96c(%rip), %rdi     # 0x78ff0
leaq 0x1113c(%rip), %rsi     # 0x5a7c7
callq 0x6520
movq %rax, -0x760(%rbp)
jmp 0x49699
movq -0x760(%rbp), %rdi
movq 0x2f8e9(%rip), %rsi     # 0x78f90
callq 0x6570
jmp 0x496ae
movl $0x1, -0x4(%rbp)
movl $0x1, -0x280(%rbp)
jmp 0x4a3d6
movss -0x1c(%rbp), %xmm0
movss %xmm0, -0x76c(%rbp)
leaq -0x328(%rbp), %rdi
callq 0xb670
movq %rax, %rdx
shrq %rdx
movl %eax, %ecx
andl $0x1, %ecx
orq %rdx, %rcx
cvtsi2ss %rcx, %xmm0
addss %xmm0, %xmm0
cvtsi2ss %rax, %xmm1
movss %xmm1, -0x768(%rbp)
testq %rax, %rax
movss %xmm0, -0x764(%rbp)
js 0x4971e
movss -0x768(%rbp), %xmm0
movss %xmm0, -0x764(%rbp)
movss -0x76c(%rbp), %xmm0
movss -0x764(%rbp), %xmm1
mulss %xmm1, %xmm0
callq 0x33ed0
movss %xmm0, -0x770(%rbp)
jmp 0x49741
movss -0x770(%rbp), %xmm0
cvttss2si %xmm0, %eax
movl %eax, -0x32c(%rbp)
movss -0x20(%rbp), %xmm0
cvtss2sd %xmm0, %xmm0
movsd 0xfb04(%rip), %xmm1     # 0x59268
ucomisd %xmm1, %xmm0
jne 0x49783
jp 0x49783
leaq -0x328(%rbp), %rdi
callq 0xb670
movl %eax, -0x330(%rbp)
jmp 0x49812
movss -0x20(%rbp), %xmm0
movss %xmm0, -0x77c(%rbp)
leaq -0x328(%rbp), %rdi
callq 0xb670
movq %rax, %rdx
shrq %rdx
movl %eax, %ecx
andl $0x1, %ecx
orq %rdx, %rcx
cvtsi2ss %rcx, %xmm0
addss %xmm0, %xmm0
cvtsi2ss %rax, %xmm1
movss %xmm1, -0x778(%rbp)
testq %rax, %rax
movss %xmm0, -0x774(%rbp)
js 0x497dd
movss -0x778(%rbp), %xmm0
movss %xmm0, -0x774(%rbp)
movss -0x77c(%rbp), %xmm0
movss -0x774(%rbp), %xmm1
mulss %xmm1, %xmm0
callq 0x4a670
movss %xmm0, -0x780(%rbp)
jmp 0x49800
movss -0x780(%rbp), %xmm0
cvttss2si %xmm0, %eax
movl %eax, -0x330(%rbp)
movl -0x32c(%rbp), %eax
cmpl -0x24(%rbp), %eax
jle 0x49826
movl -0x32c(%rbp), %eax
movl %eax, -0x24(%rbp)
movl -0x330(%rbp), %eax
cmpl -0x28(%rbp), %eax
jge 0x4983a
movl -0x330(%rbp), %eax
movl %eax, -0x28(%rbp)
cmpl $0x0, -0x24(%rbp)
jg 0x4986a
movslq -0x28(%rbp), %rax
movq %rax, -0x788(%rbp)
leaq -0x328(%rbp), %rdi
callq 0xb670
movq %rax, %rcx
movq -0x788(%rbp), %rax
cmpq %rcx, %rax
jae 0x49936
movq -0x10(%rbp), %rax
movq %rax, -0x7a0(%rbp)
movl -0x24(%rbp), %eax
movl %eax, -0x794(%rbp)
movl -0x28(%rbp), %eax
movl %eax, -0x790(%rbp)
leaq -0x328(%rbp), %rdi
callq 0xb670
movq -0x7a0(%rbp), %rsi
movl -0x794(%rbp), %edx
movl -0x790(%rbp), %ecx
movl %eax, %r9d
leaq -0x60(%rbp), %rdi
leaq -0x278(%rbp), %r8
callq 0x48700
movl %eax, -0x78c(%rbp)
jmp 0x498c1
movl -0x78c(%rbp), %eax
cmpl $0x0, %eax
je 0x498e2
movl $0x1, -0x4(%rbp)
movl $0x1, -0x280(%rbp)
jmp 0x4a3d6
leaq -0x60(%rbp), %rdi
callq 0xf360
movq %rax, %rsi
movq 0x2f6b3(%rip), %rdi     # 0x78fa8
callq 0x6120
movq %rax, -0x7a8(%rbp)
jmp 0x49903
movq -0x7a8(%rbp), %rdi
leaq 0x10e53(%rip), %rsi     # 0x5a764
callq 0x6520
movq %rax, -0x7b0(%rbp)
jmp 0x4991f
movq -0x7b0(%rbp), %rdi
movq 0x2f663(%rip), %rsi     # 0x78f90
callq 0x6570
jmp 0x49934
jmp 0x49936
movl $0x0, -0x334(%rbp)
movl $0x0, -0x338(%rbp)
movq -0x10(%rbp), %rdi
callq 0xefe0
movq %rax, -0x340(%rbp)
movq -0x10(%rbp), %rdi
callq 0xf050
movq %rax, -0x348(%rbp)
leaq -0x340(%rbp), %rdi
leaq -0x348(%rbp), %rsi
callq 0xf010
testb $0x1, %al
jne 0x49986
jmp 0x4a2c0
leaq -0x340(%rbp), %rdi
callq 0xf080
movq %rax, %rdi
leaq -0x268(%rbp), %rsi
movl $0x1, %edx
callq 0xa4f0
movl %eax, -0x7b4(%rbp)
jmp 0x499ae
movl -0x7b4(%rbp), %eax
cmpl $0x0, %eax
je 0x499cf
movl $0x1, -0x4(%rbp)
movl $0x1, -0x280(%rbp)
jmp 0x4a3d6
leaq -0x368(%rbp), %rdi
movq %rdi, -0x7c0(%rbp)
callq 0x1ab40
movq -0x7c0(%rbp), %rdx
leaq -0x268(%rbp), %rdi
leaq -0x34c(%rbp), %rsi
callq 0xcd40
jmp 0x499fe
movl -0x34c(%rbp), %eax
addl %eax, %eax
cltq
imulq $0x55555556, %rax, %rax # imm = 0x55555556
movq %rax, %rcx
shrq $0x3f, %rcx
shrq $0x20, %rax
addl %ecx, %eax
movq %rax, -0x7d0(%rbp)
movq %rsp, %rcx
movq %rcx, -0x370(%rbp)
movq %rax, %rdx
addq $0xf, %rdx
andq $-0x10, %rdx
movq %rsp, %rcx
subq %rdx, %rcx
movq %rcx, -0x7c8(%rbp)
movq %rcx, %rsp
movq %rax, -0x378(%rbp)
movl -0x34c(%rbp), %eax
cmpl -0x278(%rbp), %eax
je 0x49ad7
movq 0x2f58c(%rip), %rdi     # 0x78ff0
leaq 0x10cd9(%rip), %rsi     # 0x5a744
callq 0x6520
movq %rax, -0x7d8(%rbp)
jmp 0x49a79
movq -0x7d8(%rbp), %rdi
movq 0x2f509(%rip), %rsi     # 0x78f90
callq 0x6570
movq %rax, -0x7e0(%rbp)
jmp 0x49a95
movq -0x7e0(%rbp), %rdi
movq 0x2f4ed(%rip), %rsi     # 0x78f90
callq 0x6570
jmp 0x49aaa
movl $0x1, -0x4(%rbp)
movl $0x1, -0x280(%rbp)
jmp 0x4a252
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x270(%rbp)
movl %eax, -0x274(%rbp)
jmp 0x4a2af
leaq -0x340(%rbp), %rdi
callq 0xf080
movq %rax, %rsi
leaq -0x398(%rbp), %rdi
callq 0x6230
jmp 0x49af4
leaq 0x128c3(%rip), %rsi     # 0x5c3be
leaq -0x398(%rbp), %rdi
movq %rdi, -0x7e8(%rbp)
movq $-0x1, %rdx
callq 0x64f0
movq -0x7e8(%rbp), %rsi
movq %rax, %rcx
xorl %eax, %eax
movl %eax, %edx
leaq -0x3f8(%rbp), %rdi
callq 0x6550
jmp 0x49b31
leaq 0x10cd6(%rip), %rdx     # 0x5a80e
leaq -0x3d8(%rbp), %rdi
leaq -0x3f8(%rbp), %rsi
callq 0x24a10
jmp 0x49b4d
leaq 0x1286a(%rip), %rsi     # 0x5c3be
leaq -0x398(%rbp), %rdi
movq %rdi, -0x7f8(%rbp)
movq $-0x1, %rdx
callq 0x64f0
movq -0x7f8(%rbp), %rdi
movq %rax, -0x7f0(%rbp)
callq 0x67e0
movq -0x7f8(%rbp), %rsi
movq -0x7f0(%rbp), %rdx
movq %rax, %rcx
leaq -0x418(%rbp), %rdi
callq 0x6550
jmp 0x49ba0
leaq -0x3b8(%rbp), %rdi
leaq -0x3d8(%rbp), %rsi
leaq -0x418(%rbp), %rdx
callq 0x24a60
jmp 0x49bbc
leaq -0x418(%rbp), %rdi
callq 0x6a08
leaq -0x3d8(%rbp), %rdi
callq 0x6a08
leaq -0x3f8(%rbp), %rdi
callq 0x6a08
movq 0x2f3c1(%rip), %rdi     # 0x78fa8
leaq 0x10c28(%rip), %rsi     # 0x5a816
callq 0x6520
movq %rax, -0x800(%rbp)
jmp 0x49bfc
movq -0x800(%rbp), %rdi
leaq -0x3b8(%rbp), %rsi
callq 0x64d0
movq %rax, -0x808(%rbp)
jmp 0x49c18
movq -0x808(%rbp), %rdi
movq 0x2f36a(%rip), %rsi     # 0x78f90
callq 0x6570
jmp 0x49c2d
leaq -0x618(%rbp), %rdi
leaq -0x3b8(%rbp), %rsi
movl $0x10, %edx
callq 0x69b0
jmp 0x49c47
leaq 0x1012c(%rip), %rsi     # 0x59d7a
leaq -0x618(%rbp), %rdi
callq 0x6520
movq %rax, -0x810(%rbp)
jmp 0x49c63
movq -0x810(%rbp), %rdi
leaq 0x2f9ef(%rip), %rsi     # 0x79660
callq 0x64d0
movq %rax, -0x818(%rbp)
jmp 0x49c7f
movq -0x818(%rbp), %rdi
movq 0x2f303(%rip), %rsi     # 0x78f90
callq 0x6570
jmp 0x49c94
movl -0x278(%rbp), %esi
leaq -0x618(%rbp), %rdi
callq 0x68d0
movq %rax, -0x820(%rbp)
jmp 0x49caf
movq -0x820(%rbp), %rdi
movq 0x2f2d3(%rip), %rsi     # 0x78f90
callq 0x6570
jmp 0x49cc4
leaq -0x368(%rbp), %rdi
callq 0xb4c0
movq %rax, -0x620(%rbp)
leaq -0x368(%rbp), %rdi
callq 0xb340
movq %rax, -0x628(%rbp)
leaq -0x620(%rbp), %rdi
leaq -0x628(%rbp), %rsi
callq 0x4a690
testb $0x1, %al
jne 0x49d06
jmp 0x49df7
leaq -0x620(%rbp), %rdi
callq 0x30840
movq %rax, %rsi
leaq -0x618(%rbp), %rdi
callq 0x64d0
movq %rax, -0x828(%rbp)
jmp 0x49d2a
movq -0x828(%rbp), %rdi
leaq 0x10615(%rip), %rsi     # 0x5a34d
callq 0x6520
jmp 0x49d3f
jmp 0x49d41
leaq -0x620(%rbp), %rdi
callq 0x4a6d0
jmp 0x49cd7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x270(%rbp)
movl %eax, -0x274(%rbp)
jmp 0x4a2a3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x270(%rbp)
movl %eax, -0x274(%rbp)
jmp 0x49db8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x270(%rbp)
movl %eax, -0x274(%rbp)
jmp 0x49dac
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x270(%rbp)
movl %eax, -0x274(%rbp)
leaq -0x418(%rbp), %rdi
callq 0x6a08
leaq -0x3d8(%rbp), %rdi
callq 0x6a08
leaq -0x3f8(%rbp), %rdi
callq 0x6a08
jmp 0x4a2a3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x270(%rbp)
movl %eax, -0x274(%rbp)
jmp 0x4a297
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x270(%rbp)
movl %eax, -0x274(%rbp)
jmp 0x4a28b
movq 0x2f192(%rip), %rsi     # 0x78f90
leaq -0x618(%rbp), %rdi
callq 0x6570
jmp 0x49e0c
movb $0x1, -0x629(%rbp)
leaq -0x368(%rbp), %rdi
callq 0xb670
movq %rax, %rdx
shrq %rdx
movl %eax, %ecx
andl $0x1, %ecx
orq %rdx, %rcx
cvtsi2ss %rcx, %xmm0
addss %xmm0, %xmm0
cvtsi2ss %rax, %xmm1
movss %xmm1, -0x830(%rbp)
testq %rax, %rax
movss %xmm0, -0x82c(%rbp)
js 0x49e60
movss -0x830(%rbp), %xmm0
movss %xmm0, -0x82c(%rbp)
movss -0x82c(%rbp), %xmm0
movss 0xf80c(%rip), %xmm1     # 0x5967c
divss %xmm1, %xmm0
cvtss2sd %xmm0, %xmm0
callq 0x60b0
cvttsd2si %xmm0, %eax
movq %rax, -0x840(%rbp)
movq %rax, %rdx
addq $0xf, %rdx
andq $-0x10, %rdx
movq %rsp, %rcx
subq %rdx, %rcx
movq %rcx, -0x838(%rbp)
movq %rcx, %rsp
movq %rax, -0x638(%rbp)
movq -0x840(%rbp), %rdx
movq -0x838(%rbp), %rsi
leaq -0x268(%rbp), %rdi
callq 0x6680
movq %rax, -0x848(%rbp)
jmp 0x49ecd
movq -0x848(%rbp), %rdi
movq (%rdi), %rax
movq -0x18(%rax), %rax
addq %rax, %rdi
callq 0x6670
movb %al, -0x849(%rbp)
jmp 0x49eeb
movb -0x849(%rbp), %al
testb $0x1, %al
jne 0x49efa
jmp 0x4a208
leaq -0x659(%rbp), %rdi
movq %rdi, -0x858(%rbp)
callq 0x6910
movq -0x838(%rbp), %rsi
movq -0x840(%rbp), %rdx
movq -0x858(%rbp), %rcx
leaq -0x658(%rbp), %rdi
callq 0x65e0
jmp 0x49f30
leaq -0x659(%rbp), %rdi
callq 0x65a0
leaq -0x268(%rbp), %rdi
callq 0x61c0
movl %eax, -0x85c(%rbp)
jmp 0x49f50
movl -0x85c(%rbp), %ecx
xorl %eax, %eax
cmpl $0xa, %ecx
movb %al, -0x85d(%rbp)
je 0x49fab
leaq -0x268(%rbp), %rdi
leaq -0x279(%rbp), %rsi
callq 0x6720
movq %rax, -0x868(%rbp)
jmp 0x49f7f
movq -0x868(%rbp), %rdi
movq (%rdi), %rax
movq -0x18(%rax), %rax
addq %rax, %rdi
callq 0x6670
movb %al, -0x869(%rbp)
jmp 0x49f9d
movb -0x869(%rbp), %al
movb %al, -0x85d(%rbp)
jmp 0x49fab
movb -0x85d(%rbp), %al
testb $0x1, %al
jne 0x49fba
jmp 0x4a1a0
movq -0x7d0(%rbp), %rdx
movq -0x7c8(%rbp), %rsi
leaq -0x268(%rbp), %rdi
callq 0x6680
jmp 0x49fd6
movl -0x278(%rbp), %eax
addl %eax, %eax
cltq
imulq $0x55555556, %rax, %rax # imm = 0x55555556
movq %rax, %rcx
shrq $0x3f, %rcx
shrq $0x20, %rax
addl %ecx, %eax
cltq
movq %rax, -0x880(%rbp)
leaq -0x681(%rbp), %rdi
movq %rdi, -0x878(%rbp)
callq 0x6910
movq -0x7c8(%rbp), %rsi
movq -0x880(%rbp), %rdx
movq -0x878(%rbp), %rcx
leaq -0x680(%rbp), %rdi
callq 0x65e0
jmp 0x4a033
leaq -0x681(%rbp), %rdi
callq 0x65a0
leaq -0x60(%rbp), %rdi
leaq -0x680(%rbp), %rsi
callq 0xf400
movq %rax, -0x888(%rbp)
jmp 0x4a058
movq -0x888(%rbp), %rax
movq %rax, -0x690(%rbp)
leaq -0x60(%rbp), %rdi
callq 0xf470
movq %rax, -0x698(%rbp)
leaq -0x690(%rbp), %rdi
leaq -0x698(%rbp), %rsi
callq 0x4a6f0
testb $0x1, %al
jne 0x4a092
jmp 0x4a180
testb $0x1, -0x629(%rbp)
je 0x4a140
leaq -0x618(%rbp), %rdi
leaq -0x658(%rbp), %rsi
callq 0x64d0
jmp 0x4a0b4
movb $0x0, -0x629(%rbp)
jmp 0x4a140
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x270(%rbp)
movl %eax, -0x274(%rbp)
leaq -0x659(%rbp), %rdi
callq 0x65a0
jmp 0x4a28b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x270(%rbp)
movl %eax, -0x274(%rbp)
jmp 0x4a1f7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x270(%rbp)
movl %eax, -0x274(%rbp)
leaq -0x681(%rbp), %rdi
callq 0x65a0
jmp 0x4a1f7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x270(%rbp)
movl %eax, -0x274(%rbp)
leaq -0x680(%rbp), %rdi
callq 0x6a08
jmp 0x4a1f7
movsbl -0x279(%rbp), %esi
leaq -0x618(%rbp), %rdi
callq 0x6620
movq %rax, -0x890(%rbp)
jmp 0x4a15c
movq -0x890(%rbp), %rdi
leaq -0x680(%rbp), %rsi
callq 0x64d0
jmp 0x4a171
movl -0x334(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x334(%rbp)
movl -0x338(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x338(%rbp)
leaq -0x680(%rbp), %rdi
callq 0x6a08
jmp 0x49f3c
movb -0x629(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x4a1c7
movq 0x2edd9(%rip), %rsi     # 0x78f90
leaq -0x618(%rbp), %rdi
callq 0x6570
jmp 0x4a1c5
jmp 0x4a1c7
movb $0x1, -0x629(%rbp)
leaq -0x268(%rbp), %rdi
movl $0x100, %esi            # imm = 0x100
movl $0xa, %edx
callq 0x6340
jmp 0x4a1e6
leaq -0x658(%rbp), %rdi
callq 0x6a08
jmp 0x49eaa
leaq -0x658(%rbp), %rdi
callq 0x6a08
jmp 0x4a28b
leaq -0x268(%rbp), %rdi
callq 0x60f0
jmp 0x4a216
leaq -0x618(%rbp), %rdi
callq 0x6740
jmp 0x4a224
leaq -0x618(%rbp), %rdi
callq 0x67d0
leaq -0x3b8(%rbp), %rdi
callq 0x6a08
leaq -0x398(%rbp), %rdi
callq 0x6a08
movl $0x0, -0x280(%rbp)
movq -0x370(%rbp), %rax
movq %rax, %rsp
leaq -0x368(%rbp), %rdi
callq 0xfe90
movl -0x280(%rbp), %eax
testl %eax, %eax
jne 0x4a3d6
jmp 0x4a278
jmp 0x4a27a
leaq -0x340(%rbp), %rdi
callq 0xf0a0
jmp 0x4995a
leaq -0x618(%rbp), %rdi
callq 0x67d0
leaq -0x3b8(%rbp), %rdi
callq 0x6a08
leaq -0x398(%rbp), %rdi
callq 0x6a08
leaq -0x368(%rbp), %rdi
callq 0xfe90
jmp 0x4a3e4
movl -0x338(%rbp), %esi
movq 0x2ecdb(%rip), %rdi     # 0x78fa8
callq 0x68d0
movq %rax, -0x898(%rbp)
jmp 0x4a2db
movq -0x898(%rbp), %rdi
leaq 0x10546(%rip), %rsi     # 0x5a82f
callq 0x6520
movq %rax, -0x8a0(%rbp)
jmp 0x4a2f7
movq -0x8a0(%rbp), %rdi
movq 0x2ec8b(%rip), %rsi     # 0x78f90
callq 0x6570
jmp 0x4a30c
movl -0x334(%rbp), %esi
movq 0x2ec8f(%rip), %rdi     # 0x78fa8
callq 0x68d0
movq %rax, -0x8a8(%rbp)
jmp 0x4a327
movq -0x8a8(%rbp), %rdi
leaq 0x10512(%rip), %rsi     # 0x5a847
callq 0x6520
movq %rax, -0x8b0(%rbp)
jmp 0x4a343
movq -0x8b0(%rbp), %rdi
movq 0x2ec3f(%rip), %rsi     # 0x78f90
callq 0x6570
jmp 0x4a358
movl -0x338(%rbp), %esi
movl -0x334(%rbp), %eax
subl %eax, %esi
movq 0x2ec3b(%rip), %rdi     # 0x78fa8
callq 0x68d0
movq %rax, -0x8b8(%rbp)
jmp 0x4a37b
movq -0x8b8(%rbp), %rdi
leaq 0x104dd(%rip), %rsi     # 0x5a866
callq 0x6520
movq %rax, -0x8c0(%rbp)
jmp 0x4a397
movq -0x8c0(%rbp), %rdi
movq 0x2ebeb(%rip), %rsi     # 0x78f90
callq 0x6570
jmp 0x4a3ac
movq -0x30(%rbp), %rax
movq %rax, -0x6a0(%rbp)
movq -0x6a0(%rbp), %rdi
callq 0xa8f0
jmp 0x4a3c5
movl $0x0, -0x4(%rbp)
movl $0x1, -0x280(%rbp)
leaq -0x328(%rbp), %rdi
callq 0xfe90
jmp 0x4a3f2
leaq -0x328(%rbp), %rdi
callq 0xfe90
jmp 0x4a40f
leaq -0x268(%rbp), %rdi
callq 0x6140
leaq -0x60(%rbp), %rdi
callq 0xf740
movl -0x4(%rbp), %eax
movq %rbp, %rsp
popq %rbp
retq
leaq -0x268(%rbp), %rdi
callq 0x6140
leaq -0x60(%rbp), %rdi
callq 0xf740
movq -0x270(%rbp), %rdi
callq 0x6900