// File: /workspace/github_cpp_makefile_star2_O3/dcarrey[P]hgt-detection/./fonctions.cpp
// Function: findBestHGTtab(InputTree, InputTree, Parameters, HGT*, int*, int*, int)
int findBestHGTtab(struct InputTree SpeciesTree,struct InputTree GeneTree,struct Parameters param,struct HGT *aHGT, int *nbHgtFound,int *initial,int bootstrap){

	struct InputTree tmpTree;
	struct InputTree tmpTree2;
	
	int i,j,k,l,first=1,ret=0,trouve;
	int size = SpeciesTree.size;
	int ktSpecies;
	struct CRITERIA aCrit,aCritRef,aCritRef2,aCrit_tmpTree2;
	struct DescTree *DTSpecies,*DTGene;
	int encore = 0;
  
	initInputTree(&tmpTree);
	initInputTree(&tmpTree2);
	
	(*nbHgtFound) = 0;

	printf("\n\n== NEW STEP OF DETECTION == [size of the trees (after reduction)=%d]",SpeciesTree.size);
  
	//== compute criteria
	InitCriteria(&aCrit,size);
	InitCriteria(&aCritRef,size);
	InitCriteria(&aCritRef2,size);
	InitCriteria(&aCrit_tmpTree2,size);
	computeCriteria(SpeciesTree.ADD,GeneTree.ADD,size,&aCrit,SpeciesTree.LONGUEUR,SpeciesTree.ARETE,GeneTree.LONGUEUR,GeneTree.ARETE);
	computeCriteria(SpeciesTree.ADD,GeneTree.ADD,size,&aCritRef,SpeciesTree.LONGUEUR,SpeciesTree.ARETE,GeneTree.LONGUEUR,GeneTree.ARETE);
	computeCriteria(SpeciesTree.ADD,GeneTree.ADD,size,&aCritRef2,SpeciesTree.LONGUEUR,SpeciesTree.ARETE,GeneTree.LONGUEUR,GeneTree.ARETE);
	loadCriteria(aCrit,&aHGT[0]);
  
	DTGene = (struct DescTree*)malloc((2*GeneTree.size-2-GeneTree.kt+1)*sizeof(struct DescTree));
	RechercherBipartition(GeneTree.ARETE,GeneTree.ADD,GeneTree.Root,GeneTree.Adjacence,DTGene,GeneTree.size,GeneTree.kt);	

	DTSpecies = (struct DescTree*)malloc((2*SpeciesTree.size-2-SpeciesTree.kt+1)*sizeof(struct DescTree));
	RechercherBipartition(SpeciesTree.ARETE,SpeciesTree.ADD,SpeciesTree.Root,SpeciesTree.Adjacence,DTSpecies,SpeciesTree.size,SpeciesTree.kt);

	int flag2 = 1;
	int flag3;   		//== pour tester les especes avec sur la branche au dessus
	int initial3=1;
	
	
	do{
		for(i=1;i<2*size-3-SpeciesTree.kt;i++)
			for(j=i+1;j<2*size-3-SpeciesTree.kt;j++){
				//== is it a valid hgt ?
				trouve=0;
				if(isAValidHGT(SpeciesTree,i,j)==1 && i!=j ){
					copyInputTree(&tmpTree,SpeciesTree,0,0);
				
					if(strcmp(param.subtree,"yes") == 0){
						if(TestSubTreeConstraint(SpeciesTree,i,j,DTSpecies,DTGene) == 0)  {
							continue;
							//FreeMemory_InputTree(&tmpTree);
							tmpTree.ADD = NULL;
							tmpTree.ARETE = NULL;
						}
						flag3=0;
						if(TestSubTreeLeafs(SpeciesTree,i,j,DTSpecies,DTGene) == 1){
							//printf("\nTestSubTreeLeafs => ok");
							flag3=1;
						}
					}
					
					applyHGT(GeneTree.ADD,&tmpTree,i,j);
					
					if(strcmp(param.criterion,"ls") == 0)
						AdjustBranchLength(&tmpTree,GeneTree,0,1);
					computeCriteria(tmpTree.ADD,GeneTree.ADD,size,&aCrit,tmpTree.LONGUEUR,tmpTree.ARETE,GeneTree.LONGUEUR,GeneTree.ARETE);
				
					first=1;
					loadCriteria(aCritRef,&aHGT[(*nbHgtFound)]);
					//printf("\ninitial = %d,initial3= %d",*initial,initial3);
					if(((aCritRef.RF-aCrit.RF) == 1) && (*initial==1) && (
					  (SpeciesTree.ARETE[2*i-1] == SpeciesTree.ARETE[2*j-1]) || 
					  (SpeciesTree.ARETE[2*i-1] == SpeciesTree.ARETE[2*j-2]) || 
					  (SpeciesTree.ARETE[2*i-2] == SpeciesTree.ARETE[2*j-2]) || 
					  (SpeciesTree.ARETE[2*i-2] == SpeciesTree.ARETE[2*j-2])
					  )) {
						UpdateCriterion(&first,param.criterion,aCrit,&aHGT[(*nbHgtFound)],i,j,0);
						//printf("\n===========> initial = %d",*initial);
						//printf("\tRF1=%d | RF2=%d | BD1=%2.1lf | BD2=%2.1lf",aHGT[(*nbHgtFound)].crit.RF,aCrit.RF,aHGT[(*nbHgtFound)].crit.BD,aCrit.BD);
						
						aHGT[(*nbHgtFound)].source_A = SpeciesTree.ARETE[2*i-1];
						aHGT[(*nbHgtFound)].source_B = SpeciesTree.ARETE[2*i-2];
						aHGT[(*nbHgtFound)].dest_A = SpeciesTree.ARETE[2*j-1];
						aHGT[(*nbHgtFound)].dest_B = SpeciesTree.ARETE[2*j-2];
						
						findListSpecies(&aHGT[(*nbHgtFound)],DTSpecies,SpeciesTree);
						trouve=1;
					}
					else  if((*initial==0) && ((flag3 == 1) || (initial3 == 0) )){
						if(TestCriterionAndUpdate(&first,param.criterion,aCrit,&aHGT[(*nbHgtFound)],i,j,0,0) == 1){		
							//printf("\n===========> flag3 = %d, initial3=%d",flag3,initial3);
							//printf("\tRF1=%d | RF2=%d | BD1=%2.1lf | BD2=%2.1lf",aHGT[(*nbHgtFound)].crit.RF,aCrit.RF,aHGT[(*nbHgtFound)].crit.BD,aCrit.BD);
							aHGT[(*nbHgtFound)].source_A = SpeciesTree.ARETE[2*i-1];
							aHGT[(*nbHgtFound)].source_B = SpeciesTree.ARETE[2*i-2];
							aHGT[(*nbHgtFound)].dest_A = SpeciesTree.ARETE[2*j-1];
							aHGT[(*nbHgtFound)].dest_B = SpeciesTree.ARETE[2*j-2];
							findListSpecies(&aHGT[(*nbHgtFound)],DTSpecies,SpeciesTree);
							trouve=1;
						}
					}
				}

				if(isAValidHGT(SpeciesTree,j,i)==1 && i!=j ){
					//initInputTree(&tmpTree2);
					copyInputTree(&tmpTree2,tmpTree,0,0);
					copyInputTree(&tmpTree,SpeciesTree,0,0);
					
					if(strcmp(param.subtree,"yes") == 0){
						if(TestSubTreeConstraint(SpeciesTree,j,i,DTSpecies,DTGene) == 0) {
							continue;
							//FreeMemory_InputTree(&tmpTree);
							tmpTree.ADD = NULL;
							tmpTree.ARETE = NULL;
						}
					
						if(TestSubTreeLeafs(SpeciesTree,j,i,DTSpecies,DTGene)==1){
							//printf("\nTestSubTreeLeafs (reverse) => ok");
							flag3=2;
						 }
					}
					
					//if(flag3 == 0){
						//initial3 = 0;
					//}
					
					applyHGT(GeneTree.ADD,&tmpTree,j,i);
					
					if(strcmp(param.criterion,"ls") == 0)
					  AdjustBranchLength(&tmpTree,GeneTree,0,1);
					computeCriteria(tmpTree.ADD,GeneTree.ADD,size,&aCrit,tmpTree.LONGUEUR,tmpTree.ARETE,GeneTree.LONGUEUR,GeneTree.ARETE);
					if(tmpTree2.ADD == NULL){
						printf("HOUSTON, we have a problem !");
						aCrit_tmpTree2.RF = (int) INFINI;
					}
					else{
						computeCriteria(tmpTree.ADD,tmpTree2.ADD,size,&aCrit_tmpTree2,tmpTree.LONGUEUR,tmpTree.ARETE,tmpTree2.LONGUEUR,tmpTree2.ARETE);
					}
					int flag=0;
					first=1;
					int flag_bootstrap = 0;
					if(trouve==0)
						loadCriteria(aCritRef,&aHGT[(*nbHgtFound)]);
					else{
						//printf("\n===========> rand_bootstrap : RF = %d",aCrit_tmpTree2.RF);
						if((bootstrap == 1) && (aCrit_tmpTree2.RF == 0) && /*(aCrit.BD == aHGT[(*nbHgtFound)].crit.BD) && */(aCrit.RF == aHGT[(*nbHgtFound)].crit.RF) ){
							flag_bootstrap = 1;
							//printf("\n==> rand_bootstrap1 : [%2d--%2d -> %2d--%2d]",aHGT[(*nbHgtFound)].source_A,aHGT[(*nbHgtFound)].source_B,aHGT[(*nbHgtFound)].dest_A,aHGT[(*nbHgtFound)].dest_B);
						}
						else{
							aHGT[(*nbHgtFound)].crit.diff_bd = fabs(aCrit.BD - aHGT[(*nbHgtFound)].crit.BD);
							if((flag2 == 1) && (fabs(aCrit.BD - aHGT[(*nbHgtFound)].crit.BD) <= 1)){
								if( (aHGT[(*nbHgtFound)].crit.RF - aCrit.RF) >= 1 ){
									trouve = 0;
									flag = 2;
								}      
								else{
									flag = 1;
									//printf("\n--> TEST FLAG : RF1=%d | RF2=%d | BD1=%2.1lf | BD2=%2.1lf",aHGT[(*nbHgtFound)].crit.RF,aCrit.RF,aHGT[(*nbHgtFound)].crit.BD,aCrit.BD);
								}
							}
							else{
								//printf("\n-->[%2d--%2d -> %2d--%2d]",aHGT[(*nbHgtFound)].source_A,aHGT[(*nbHgtFound)].source_B,aHGT[(*nbHgtFound)].dest_A,aHGT[(*nbHgtFound)].dest_B);
								//printf("\tRF1=%d | RF2=%d | BD1=%2.1lf | BD2=%2.1lf",aHGT[(*nbHgtFound)].crit.RF,aCrit.RF,aHGT[(*nbHgtFound)].crit.BD,aCrit.BD);
							}
						}
					}
					
					//flag_bootstrap = 0;
					if(flag != 1){
						if(((aCritRef.RF-aCrit.RF) == 1) && (*initial==1) && (
						  (SpeciesTree.ARETE[2*i-1] == SpeciesTree.ARETE[2*j-1]) || 
						  (SpeciesTree.ARETE[2*i-1] == SpeciesTree.ARETE[2*j-2]) || 
						  (SpeciesTree.ARETE[2*i-2] == SpeciesTree.ARETE[2*j-2]) || 
						  (SpeciesTree.ARETE[2*i-2] == SpeciesTree.ARETE[2*j-2])
						)) {
						
							if ((flag_bootstrap == 1) && (rand_bootstrap == 1)){
								
								//printf("\n===========>REVERSE : initial = %d",*initial);
								//printf("\tRF1=%d | RF2=%d | BD1=%2.1lf | BD2=%2.1lf",aHGT[(*nbHgtFound)].crit.RF,aCrit.RF,aHGT[(*nbHgtFound)].crit.BD,aCrit.BD);
								UpdateCriterion(&first,param.criterion,aCrit,&aHGT[(*nbHgtFound)],j,i,flag_bootstrap);
								aHGT[(*nbHgtFound)].source_A = SpeciesTree.ARETE[2*j-1];
								aHGT[(*nbHgtFound)].source_B = SpeciesTree.ARETE[2*j-2];
								aHGT[(*nbHgtFound)].dest_A = SpeciesTree.ARETE[2*i-1];
								aHGT[(*nbHgtFound)].dest_B = SpeciesTree.ARETE[2*i-2];
								findListSpecies(&aHGT[(*nbHgtFound)],DTSpecies,SpeciesTree);
								trouve=1;
								//printf("\n==> rand_bootstrap1.5 : [%2d--%2d -> %2d--%2d]",aHGT[(*nbHgtFound)].source_A,aHGT[(*nbHgtFound)].source_B,aHGT[(*nbHgtFound)].dest_A,aHGT[(*nbHgtFound)].dest_B);
							}
						}
						else if(((*initial==0) && ((flag3 == 2) || (initial3 == 0))) || (flag_bootstrap == 1)){
							if(TestCriterionAndUpdate(&first,param.criterion,aCrit,&aHGT[(*nbHgtFound)],j,i,flag,flag_bootstrap) == 1){	
								//printf("\n===========>REVERSE : flag3 = %d, initial3=%d",flag3,initial3);
								//printf("\tRF1=%d | RF2=%d | BD1=%2.1lf | BD2=%2.1lf",aHGT[(*nbHgtFound)].crit.RF,aCrit.RF,aHGT[(*nbHgtFound)].crit.BD,aCrit.BD);
								aHGT[(*nbHgtFound)].source_A = SpeciesTree.ARETE[2*j-1];
								aHGT[(*nbHgtFound)].source_B = SpeciesTree.ARETE[2*j-2];
								aHGT[(*nbHgtFound)].dest_A = SpeciesTree.ARETE[2*i-1];
								aHGT[(*nbHgtFound)].dest_B = SpeciesTree.ARETE[2*i-2];
								findListSpecies(&aHGT[(*nbHgtFound)],DTSpecies,SpeciesTree);
								trouve=1;
								//printf("\n==> rand_bootstrap2 : [%2d--%2d -> %2d--%2d]",aHGT[(*nbHgtFound)].source_A,aHGT[(*nbHgtFound)].source_B,aHGT[(*nbHgtFound)].dest_A,aHGT[(*nbHgtFound)].dest_B);
							}
						}
					}				
				}
				
				if (trouve == 1){
					(*nbHgtFound)++;
					//printf("\n===================> rand_bootstrap final : [%2d--%2d -> %2d--%2d]",aHGT[(*nbHgtFound)-1].source_A,aHGT[(*nbHgtFound)-1].source_B,aHGT[(*nbHgtFound)-1].dest_A,aHGT[(*nbHgtFound)-1].dest_B);			
				}

			}
			encore = 0;
		
		if((*nbHgtFound == 0) && (flag2==1)){
		  flag2 = 0;
		  encore = 1;
		}
		
		if((*nbHgtFound == 0) && (initial3==1) && (*initial==0) ){
		  initial3 = 0;
		  flag2=1;
		  encore = 1;
		}
		
		if((*nbHgtFound == 0) && (*initial==1)){
		  (*initial) = 0;
		  encore = 1;
		  flag2=1;
		}
		
		//initial3 = 0;

		
	 //   printf("On est rendu icit");
	}while(encore == 1);
	
	
	
	deleteBipartition(DTSpecies,SpeciesTree);
	deleteBipartition(DTGene,GeneTree);
	FreeCriteria(&aCrit,size);
	FreeCriteria(&aCritRef,size);
	FreeMemory_InputTree(&tmpTree,tmpTree.size);

	//printf("\n3)RF=%d",aHGT[0].crit.RF);	
	return (*nbHgtFound);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x4b8, %rsp            # imm = 0x4B8
movl %ecx, -0xb8(%rbp)
movq %rdx, -0x80(%rbp)
movq %rsi, -0x68(%rbp)
movq %rdi, -0x90(%rbp)
leaq 0x10(%rbp), %rdx
movl $0x1, %ecx
leaq -0x5c(%rbp), %rax
movl %ecx, (%rax)
movl (%rdx), %r13d
movq %r13, -0xa8(%rbp)
xorl %eax, %eax
leaq -0x1a0(%rbp), %rcx
movq %rax, 0x8(%rcx)
xorps %xmm0, %xmm0
movups %xmm0, 0x28(%rcx)
movq %rax, 0x38(%rcx)
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
movl %edx, 0x20(%rcx)
movl %edx, (%rcx)
movl %eax, 0x48(%rcx)
movups %xmm0, 0x10(%rcx)
leaq -0x2b8(%rbp), %rcx
movq %rax, 0x8(%rcx)
movups %xmm0, 0x28(%rcx)
movq %rax, 0x38(%rcx)
movl %edx, 0x20(%rcx)
movl %edx, (%rcx)
movl $0xffffffff, %r12d      # imm = 0xFFFFFFFF
movl %eax, 0x48(%rcx)
movups %xmm0, 0x10(%rcx)
movl %eax, (%rsi)
leaq 0x68(%rbp), %rbx
leaq 0x9368(%rip), %rdi      # 0x15993
movl %r13d, %esi
xorl %eax, %eax
callq 0x1030
leaq -0x148(%rbp), %r15
movq %r15, %rdi
movl %r13d, %esi
callq 0xb8ba
leaq -0x260(%rbp), %rdi
movl %r13d, %esi
callq 0xb8ba
leaq -0x318(%rbp), %rdi
movl %r13d, %esi
callq 0xb8ba
leaq -0x200(%rbp), %rdi
movl %r13d, %esi
callq 0xb8ba
movq 0x8(%rbx), %r14
movq 0x30(%rbx), %rax
movq %rax, -0x50(%rbp)
leaq 0x10(%rbp), %rax
movq 0x8(%rax), %rbx
movq 0x30(%rax), %rcx
movq %rcx, -0x78(%rbp)
movq %rbx, %rdi
movq %rbx, -0x30(%rbp)
movq %r14, %rsi
movl %r13d, %edx
movq %r15, %rcx
callq 0x8c46
movq %rbx, %rdi
movq %r14, %rsi
movl %r13d, %edx
leaq -0x260(%rbp), %rcx
callq 0x8c46
movq %rbx, %rdi
movq %r14, %rsi
movl %r13d, %edx
leaq -0x318(%rbp), %rcx
callq 0x8c46
movsd (%r15), %xmm0
movsd 0x10(%r15), %xmm1
movq 0x30(%r15), %rax
movq -0x90(%rbp), %rcx
movsd %xmm0, 0x20(%rcx)
movq %rax, 0x50(%rcx)
movsd %xmm1, 0x30(%rcx)
movl $0x1, %eax
movl %eax, (%rcx)
leaq 0x68(%rbp), %rax
movl (%rax), %ebx
movl 0x48(%rax), %r15d
movl %r15d, %eax
xorl %r12d, %eax
leal (%rax,%rbx,2), %eax
cltq
shlq $0x3, %rax
leaq (%rax,%rax,2), %rdi
callq 0x1140
leaq 0x68(%rbp), %rcx
movl 0x20(%rcx), %edx
movq 0x28(%rcx), %rcx
movl %r15d, (%rsp)
leaq 0x10(%rbp), %r15
movq -0x50(%rbp), %rdi
movq %r14, -0xd0(%rbp)
movq %r14, %rsi
movq %rax, -0xa0(%rbp)
movq %rax, %r8
movl %ebx, %r9d
callq 0x4e01
leal (,%r13,2), %r14d
movl 0x48(%r15), %ebx
xorl %ebx, %r12d
leal (%r12,%r13,2), %eax
cltq
shlq $0x3, %rax
leaq (%rax,%rax,2), %rdi
callq 0x1140
movq %rax, %r12
movl 0x20(%r15), %edx
movq 0x28(%r15), %rcx
movl %ebx, (%rsp)
movq -0x78(%rbp), %rdi
movq -0x30(%rbp), %rsi
movq %rax, %r8
movl %r13d, %r9d
callq 0x4e01
movq -0x68(%rbp), %r10
leal -0x4(,%r13,2), %eax
movl %eax, -0xac(%rbp)
movl %ebx, -0xb0(%rbp)
subl %ebx, %r14d
addl $-0x3, %r14d
movslq %r14d, %rdi
movq %r12, %r9
movq -0x90(%rbp), %r12
leaq -0x260(%rbp), %rdx
movsd (%rdx), %xmm0
movsd %xmm0, -0xc8(%rbp)
movsd 0x10(%rdx), %xmm0
movsd %xmm0, -0xc0(%rbp)
movl 0x30(%rdx), %eax
movl %eax, -0x6c(%rbp)
movl 0x34(%rdx), %eax
movl %eax, -0x84(%rbp)
movq -0x78(%rbp), %rax
addq $0x18, %rax
movq %rax, -0xe0(%rbp)
movl $0x1, -0x54(%rbp)
movl $0x1, -0x34(%rbp)
movq %r9, -0x40(%rbp)
movq %rdi, -0xd8(%rbp)
movl -0xac(%rbp), %eax
cmpl %eax, -0xb0(%rbp)
jge 0xd126
movl $0x1, %ecx
movl $0x2, %r13d
movq -0xe0(%rbp), %rbx
movq %rcx, %rdx
incq %rcx
cmpq %rdi, %rcx
movl %r13d, -0xb4(%rbp)
movq %rbx, -0xe8(%rbp)
jge 0xd101
leaq (%rdx,%rdx), %rax
movq %rax, -0x98(%rbp)
movq %rbx, -0x50(%rbp)
movq %rcx, -0x48(%rbp)
movq %rdx, -0x30(%rbp)
movl $0xb, %ecx
movq %rsp, %rdi
movq %r15, %rsi
rep  movsq (%rsi), %es:(%rdi)
movl %edx, %edi
movl %r13d, %esi
callq 0xa42b
xorl %r14d, %r14d
movb $0x1, %cl
movl %ecx, -0x88(%rbp)
testl %eax, %eax
je 0xcc0a
movl $0xb, %ecx
movq %rsp, %rdi
movq %r15, %rsi
rep  movsq (%rsi), %es:(%rdi)
leaq -0x1a0(%rbp), %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0xa587
leaq 0xc0(%rbp), %rax
cmpl $0x736579, 0xe9e(%rax)  # imm = 0x736579
je 0xc8cf
movq -0x30(%rbp), %rdx
jmp 0xc933
movl $0xb, %ecx
movq %rsp, %rdi
movq %r15, %rsi
rep  movsq (%rsi), %es:(%rdi)
movq -0x30(%rbp), %rbx
movl %ebx, %edi
movl %r13d, %esi
movq -0x40(%rbp), %rdx
movq -0xa0(%rbp), %r15
movq %r15, %rcx
callq 0x7eee
movq %rbx, %rdx
testl %eax, %eax
movq -0x68(%rbp), %r10
movq -0x48(%rbp), %rcx
je 0xd0e8
movl $0xb, %ecx
movq %rsp, %rdi
leaq 0x10(%rbp), %rsi
rep  movsq (%rsi), %es:(%rdi)
movl %edx, %edi
movl %r13d, %esi
movq -0x40(%rbp), %rdx
movq %r15, %rcx
callq 0x857b
movq -0x30(%rbp), %rdx
movl %eax, -0x58(%rbp)
leaq -0x1a0(%rbp), %rsi
movl %r13d, %ecx
callq 0x8d4e
leaq 0x4bc(%rbp), %rcx
movzwl (%rcx), %eax
xorl $0x736c, %eax           # imm = 0x736C
movzbl 0x2(%rcx), %ecx
orw %ax, %cx
movl -0x6c(%rbp), %r15d
jne 0xc980
movl $0xb, %ecx
movq %rsp, %rdi
leaq 0x68(%rbp), %rsi
rep  movsq (%rsi), %es:(%rdi)
leaq -0x1a0(%rbp), %rdi
xorl %esi, %esi
movl $0x1, %edx
callq 0xb793
movq -0x198(%rbp), %rdi
movq -0xd0(%rbp), %rsi
movq -0xa8(%rbp), %rdx
leaq -0x148(%rbp), %rcx
callq 0x8c46
movl $0x1, %edi
movl %edi, -0x5c(%rbp)
movq -0x68(%rbp), %r10
movslq (%r10), %rax
imulq $0xa8, %rax, %rax
movsd -0xc8(%rbp), %xmm0
movsd %xmm0, 0x20(%r12,%rax)
movl %r15d, 0x50(%r12,%rax)
movsd -0xc0(%rbp), %xmm0
movsd %xmm0, 0x30(%r12,%rax)
movl -0x84(%rbp), %ecx
movl %ecx, 0x54(%r12,%rax)
movl %edi, (%r12,%rax)
movl -0x118(%rbp), %ecx
movl %r15d, %edx
subl %ecx, %edx
xorl %edi, %edx
movq -0x80(%rbp), %rax
movl (%rax), %eax
movl %eax, %esi
xorl %edi, %esi
orl %edx, %esi
jne 0xca30
movq -0x78(%rbp), %r9
movq -0x98(%rbp), %rbx
movq -0x8(%r9,%rbx,8), %rsi
movq -0x50(%rbp), %rax
movq -0x8(%rax), %rdi
movq (%rax), %rdx
cmpq %rdx, %rsi
jne 0xcb08
movq %rdi, %rax
jmp 0xcb1e
cmpl $0x0, -0x34(%rbp)
sete %cl
cmpl $0x1, -0x58(%rbp)
sete %dl
testl %eax, %eax
movq -0x30(%rbp), %r8
movq -0x98(%rbp), %rbx
jne 0xcaff
orb %cl, %dl
je 0xcaff
movslq (%r10), %rax
imulq $0xa8, %rax, %rdx
addq %r12, %rdx
movl $0xc, %ecx
movq %rsp, %rdi
leaq -0x148(%rbp), %rsi
rep  movsq (%rsi), %es:(%rdi)
movl $0x0, 0x60(%rsp)
leaq -0x5c(%rbp), %rdi
leaq 0x4bc(%rbp), %rsi
movl %r8d, %ecx
movl %r13d, %r8d
xorl %r9d, %r9d
movq %r10, %r14
callq 0xa27b
testl %eax, %eax
je 0xcc03
movq -0x78(%rbp), %rdx
movl -0x8(%rdx,%rbx,8), %eax
movslq (%r14), %rcx
imulq $0xa8, %rcx, %rcx
movl %eax, 0x80(%r12,%rcx)
movl -0x10(%rdx,%rbx,8), %eax
movslq (%r14), %rcx
imulq $0xa8, %rcx, %rcx
movl %eax, 0x84(%r12,%rcx)
movq -0x50(%rbp), %rdx
movl (%rdx), %eax
movslq (%r14), %rcx
imulq $0xa8, %rcx, %rcx
movl %eax, 0x88(%r12,%rcx)
movq -0x8(%rdx), %rax
leaq -0x420(%rbp), %rdi
movq %r14, %r10
jmp 0xcba6
leaq 0x10(%rbp), %r15
jmp 0xcc0e
movq %rsi, %rax
cmpq %rdi, %rsi
je 0xcb1e
movq %rdi, %rax
cmpq %rdi, -0x10(%r9,%rbx,8)
jne 0xcc06
movsd -0x148(%rbp), %xmm0
movsd -0x138(%rbp), %xmm1
movl -0x114(%rbp), %edi
movslq (%r10), %r8
imulq $0xa8, %r8, %r8
movl %r13d, 0x8(%r12,%r8)
movq -0x30(%rbp), %r11
movl %r11d, 0x4(%r12,%r8)
movsd %xmm1, 0x30(%r12,%r8)
movsd %xmm0, 0x20(%r12,%r8)
movl %ecx, 0x50(%r12,%r8)
movl %edi, 0x54(%r12,%r8)
movslq (%r10), %rcx
imulq $0xa8, %rcx, %rcx
movl %esi, 0x80(%r12,%rcx)
movl -0x10(%r9,%rbx,8), %ecx
movslq (%r10), %rsi
imulq $0xa8, %rsi, %rsi
movl %ecx, 0x84(%r12,%rsi)
movslq (%r10), %rcx
imulq $0xa8, %rcx, %rcx
movl %edx, 0x88(%r12,%rcx)
leaq -0x478(%rbp), %rdi
movq -0x40(%rbp), %rdx
movslq (%r10), %rcx
imulq $0xa8, %rcx, %rcx
movl %eax, 0x8c(%r12,%rcx)
movslq (%r10), %rax
imulq $0xa8, %rax, %rax
addq %r12, %rax
movl $0xb, %ecx
leaq 0x10(%rbp), %r15
movq %r15, %rsi
rep  movsq (%rsi), %es:(%rdi)
movl $0xb, %ecx
movq %rsp, %rdi
movq %r15, %rsi
rep  movsq (%rsi), %es:(%rdi)
movq %rax, %rdi
movq %rdx, %rsi
callq 0xa143
movl $0x1, %r14d
movl $0x0, -0x88(%rbp)
jmp 0xcc0a
xorl %r14d, %r14d
leaq 0x10(%rbp), %r15
movq -0x30(%rbp), %r8
movl $0xb, %ecx
movq %rsp, %rdi
movq %r15, %rsi
rep  movsq (%rsi), %es:(%rdi)
movl %r13d, %edi
movl %r8d, %esi
callq 0xa42b
testl %eax, %eax
je 0xcc86
movl $0xb, %ecx
movq %rsp, %rdi
leaq -0x1a0(%rbp), %r14
movq %r14, %rsi
rep  movsq (%rsi), %es:(%rdi)
leaq -0x2b8(%rbp), %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0xa587
movl $0xb, %ecx
movq %rsp, %rdi
movq %r15, %rsi
rep  movsq (%rsi), %es:(%rdi)
movq %r14, %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0xa587
leaq 0xc0(%rbp), %rax
cmpl $0x736579, 0xe9e(%rax)  # imm = 0x736579
je 0xcc9a
movq -0x30(%rbp), %rcx
jmp 0xcd07
movq -0x68(%rbp), %r10
movq -0x48(%rbp), %rcx
movq -0x30(%rbp), %rdx
movl %r14d, %r15d
jmp 0xd0e0
movl $0xb, %ecx
movq %rsp, %rdi
movq %r15, %rsi
rep  movsq (%rsi), %es:(%rdi)
movl %r13d, %edi
movq -0x30(%rbp), %rbx
movl %ebx, %esi
movq -0x40(%rbp), %r14
movq %r14, %rdx
movq -0xa0(%rbp), %r12
movq %r12, %rcx
callq 0x7eee
testl %eax, %eax
je 0xd0c1
movl $0xb, %ecx
movq %rsp, %rdi
movq %r15, %rsi
rep  movsq (%rsi), %es:(%rdi)
movl %r13d, %edi
movl %ebx, %esi
movq %r14, %rdx
movq %r12, %rcx
callq 0x857b
testl %eax, %eax
movl $0x2, %eax
movl -0x58(%rbp), %ecx
cmovnel %eax, %ecx
movl %ecx, -0x58(%rbp)
movq -0x90(%rbp), %r12
movq %rbx, %rcx
leaq -0x1a0(%rbp), %rsi
movl %r13d, %edx
callq 0x8d4e
leaq 0x4bc(%rbp), %rcx
movzwl (%rcx), %eax
xorl $0x736c, %eax           # imm = 0x736C
movzbl 0x2(%rcx), %ecx
orw %ax, %cx
movq -0xa8(%rbp), %r14
jne 0xcd57
movl $0xb, %ecx
movq %rsp, %rdi
leaq 0x68(%rbp), %rsi
rep  movsq (%rsi), %es:(%rdi)
leaq -0x1a0(%rbp), %rdi
xorl %esi, %esi
movl $0x1, %edx
callq 0xb793
movq -0x198(%rbp), %r15
movq %r15, %rdi
movq -0xd0(%rbp), %rsi
movl %r14d, %edx
leaq -0x148(%rbp), %rcx
callq 0x8c46
movq -0x2b0(%rbp), %rsi
testq %rsi, %rsi
je 0xcd97
movq %r15, %rdi
movl %r14d, %edx
leaq -0x200(%rbp), %rcx
callq 0x8c46
jmp 0xcdaf
leaq 0x8c3c(%rip), %rdi      # 0x159da
xorl %eax, %eax
callq 0x1030
movl $0xf423f, -0x1d0(%rbp)  # imm = 0xF423F
movq -0x40(%rbp), %r14
movl -0x6c(%rbp), %esi
movq -0x98(%rbp), %rbx
movl $0x1, -0x5c(%rbp)
cmpb $0x0, -0x88(%rbp)
movq -0x68(%rbp), %r10
movq -0x78(%rbp), %r11
je 0xce2b
movslq (%r10), %rax
imulq $0xa8, %rax, %rax
movsd -0xc8(%rbp), %xmm0
movsd %xmm0, 0x20(%r12,%rax)
movl %esi, 0x50(%r12,%rax)
movsd -0xc0(%rbp), %xmm0
movsd %xmm0, 0x30(%r12,%rax)
movl -0x84(%rbp), %ecx
movl %ecx, 0x54(%r12,%rax)
movl $0x1, (%r12,%rax)
xorl %r8d, %r8d
movl -0x118(%rbp), %eax
xorl %ecx, %ecx
xorl %r9d, %r9d
xorl %r15d, %r15d
jmp 0xcece
movslq (%r10), %rcx
movl -0x118(%rbp), %eax
cmpl $0x1, -0xb8(%rbp)
jne 0xce67
cmpl $0x0, -0x1d0(%rbp)
jne 0xce67
imulq $0xa8, %rcx, %rdx
cmpl 0x50(%r12,%rdx), %eax
jne 0xce67
xorl %r9d, %r9d
movb $0x1, %cl
movl $0x1, %r8d
movl $0x1, %r15d
jmp 0xcece
imulq $0xa8, %rcx, %rcx
xorl %r8d, %r8d
movsd -0x138(%rbp), %xmm0
subsd 0x30(%r12,%rcx), %xmm0
andpd 0x81f8(%rip), %xmm0     # 0x15080
movlpd %xmm0, 0x48(%r12,%rcx)
movl $0x1, %r15d
cmpl $0x1, -0x54(%rbp)
jne 0xcec9
movsd 0x81c5(%rip), %xmm1     # 0x15068
ucomisd %xmm0, %xmm1
jb 0xcec9
addq %r12, %rcx
addq $0x20, %rcx
cmpl %eax, 0x30(%rcx)
jle 0xd0d8
movl $0x2, %r9d
xorl %r8d, %r8d
xorl %ecx, %ecx
jmp 0xce23
xorl %ecx, %ecx
xorl %r9d, %r9d
subl %eax, %esi
xorl $0x1, %esi
movq -0x80(%rbp), %rdx
movl (%rdx), %edx
movl %edx, %edi
xorl $0x1, %edi
orl %esi, %edi
jne 0xcfa3
movq -0x8(%r11,%rbx,8), %rdx
movq -0x50(%rbp), %rsi
movq (%rsi), %rsi
cmpq %rsi, %rdx
je 0xcf0f
movq -0x50(%rbp), %rdi
movq -0x8(%rdi), %rdi
cmpq %rdi, %rdx
je 0xcf0f
cmpq %rdi, -0x10(%r11,%rbx,8)
jne 0xcfa7
cmpl $0x1, 0xd23e(%rip)      # 0x1a154
sete %dil
andb %dil, %cl
cmpb $0x1, %cl
jne 0xd0d8
movsd -0x148(%rbp), %xmm0
movsd -0x138(%rbp), %xmm1
movl -0x114(%rbp), %ecx
movslq (%r10), %rdi
imulq $0xa8, %rdi, %rdi
movq -0x30(%rbp), %r8
movl %r8d, 0x8(%r12,%rdi)
movl %r13d, 0x4(%r12,%rdi)
movsd %xmm1, 0x30(%r12,%rdi)
movsd %xmm0, 0x20(%r12,%rdi)
movl %eax, 0x50(%r12,%rdi)
movl %ecx, 0x54(%r12,%rdi)
movslq (%r10), %rax
imulq $0xa8, %rax, %rax
movl %esi, 0x80(%r12,%rax)
movq -0x50(%rbp), %rax
movl -0x8(%rax), %eax
movslq (%r10), %rcx
imulq $0xa8, %rcx, %rcx
movl %eax, 0x84(%r12,%rcx)
leaq -0x3c8(%rbp), %rdi
jmp 0xd055
testl %edx, %edx
je 0xcfb0
testb %cl, %cl
jne 0xcfc8
jmp 0xd0d8
cmpl $0x0, -0x34(%rbp)
sete %al
cmpl $0x2, -0x58(%rbp)
sete %dl
orb %al, %dl
orb %cl, %dl
je 0xd0d8
movslq (%r10), %rax
imulq $0xa8, %rax, %rdx
addq %r12, %rdx
movl $0xc, %ecx
movq %rsp, %rdi
leaq -0x148(%rbp), %rsi
rep  movsq (%rsi), %es:(%rdi)
movl %r8d, 0x60(%rsp)
leaq -0x5c(%rbp), %rdi
leaq 0x4bc(%rbp), %rsi
movl %r13d, %ecx
movq -0x30(%rbp), %r8
movq %r10, %r14
callq 0xa27b
testl %eax, %eax
je 0xd0d5
movq -0x50(%rbp), %rdx
movl (%rdx), %eax
movslq (%r14), %rcx
imulq $0xa8, %rcx, %rcx
movl %eax, 0x80(%r12,%rcx)
movl -0x8(%rdx), %eax
movslq (%r14), %rcx
imulq $0xa8, %rcx, %rcx
movl %eax, 0x84(%r12,%rcx)
movq -0x78(%rbp), %rax
movq -0x8(%rax,%rbx,8), %rdx
leaq -0x370(%rbp), %rdi
movq %r14, %r10
movq %rax, %r11
movq -0x40(%rbp), %r14
movslq (%r10), %rax
imulq $0xa8, %rax, %rax
movl %edx, 0x88(%r12,%rax)
movl -0x10(%r11,%rbx,8), %eax
movslq (%r10), %rcx
imulq $0xa8, %rcx, %rcx
movl %eax, 0x8c(%r12,%rcx)
movslq (%r10), %rax
imulq $0xa8, %rax, %rax
addq %r12, %rax
movl $0xb, %ecx
leaq 0x10(%rbp), %rdx
movq %rdx, %rsi
rep  movsq (%rsi), %es:(%rdi)
movl $0xb, %ecx
movq %rsp, %rdi
movq %rdx, %rsi
rep  movsq (%rsi), %es:(%rdi)
movq %rax, %rdi
movq %r14, %rsi
callq 0xa143
movq -0x68(%rbp), %r10
movq -0x48(%rbp), %rcx
movq -0x30(%rbp), %rdx
jmp 0xd0e5
movq -0x68(%rbp), %r10
movq -0x90(%rbp), %r12
movq -0x48(%rbp), %rcx
movq %rbx, %rdx
jmp 0xd0e8
movq %r14, %r10
movq -0x48(%rbp), %rcx
movq -0x30(%rbp), %rdx
testl %r15d, %r15d
je 0xd0e8
incl (%r10)
addq $0x10, -0x50(%rbp)
incl %r13d
cmpl %r13d, -0xd8(%rbp)
leaq 0x10(%rbp), %r15
jg 0xc86d
movq -0xe8(%rbp), %rbx
addq $0x10, %rbx
movl -0xb4(%rbp), %r13d
incl %r13d
movq -0xd8(%rbp), %rdi
cmpq %rdi, %rcx
jl 0xc839
movl (%r10), %ecx
testl %ecx, %ecx
sete %dl
movl -0x54(%rbp), %r8d
cmpl $0x1, %r8d
sete %al
andb %dl, %al
movl $0x0, %esi
cmovnel %esi, %r8d
cmpl $0x1, -0x34(%rbp)
sete %sil
andb %dl, %sil
cmpb $0x1, %sil
jne 0xd171
movq -0x80(%rbp), %rcx
movl (%rcx), %edx
movl $0x1, %ecx
testl %edx, %edx
movq -0x40(%rbp), %r9
je 0xd17d
movl $0x1, -0x34(%rbp)
jmp 0xd18e
testl %ecx, %ecx
movq -0x40(%rbp), %r9
je 0xd188
xorl %eax, %eax
jmp 0xd1a9
movb $0x1, %al
movl $0x0, -0x34(%rbp)
jmp 0xd1ac
movq -0x80(%rbp), %rcx
movl (%rcx), %edx
cmpl $0x1, %edx
jne 0xd1a9
movq -0x80(%rbp), %rax
movl $0x0, (%rax)
movl $0x1, -0x54(%rbp)
jmp 0xc815
movl %r8d, %ecx
movl %ecx, -0x54(%rbp)
testb %al, %al
jne 0xc815
movl $0xb, %ecx
movq %rsp, %rdi
movq %r15, %rsi
rep  movsq (%rsi), %es:(%rdi)
movq %r9, %rdi
movq %r10, %rbx
callq 0x792f
movl $0xb, %ecx
movq %rsp, %rdi
leaq 0x68(%rbp), %rsi
rep  movsq (%rsi), %es:(%rdi)
movq -0xa0(%rbp), %rdi
callq 0x792f
leaq -0x148(%rbp), %rdi
movq -0xa8(%rbp), %r14
movl %r14d, %esi
callq 0xb982
leaq -0x260(%rbp), %rdi
movl %r14d, %esi
callq 0xb982
leaq -0x1a0(%rbp), %rdi
movl (%rdi), %esi
callq 0xb07d
movl (%rbx), %eax
addq $0x4b8, %rsp            # imm = 0x4B8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq