// File: /workspace/github_cpp_makefile_star2_O1/jmmccracken[P]PAI/ccmth.cpp
// Function: main
int main(int argc, char **argv){

    bool bCmdLineOK = ReadCmdLineArgs(argc,argv);
    if( !bCmdLineOK ){
        return(-1);
    }

    char cBuffer[1024]; //read in buffer
    char *cColValue, //used for read in
         *cRowValues; //used for read in
    int iter = 0;

    int iEstimatedY_Length = iLibraryLength-((iEmbeddingDimension-1)*iLagTimeStep);
    double dX[iLibraryLength],
           dY[iLibraryLength],
           dEstimatedY[iEstimatedY_Length];

    //Populate estimate time series, just in case
    for(int iPre = 0;iPre < iEstimatedY_Length;iPre++ ){
        dEstimatedY[iPre] = nan("");
    }

    //Declare things needed for threading
    double dCCMcorrs[iNumThreads][4];
    future<double> WorkerThreads[iNumThreads][4];
    future_status WorkerStatus[4];
    CCM_asyncData sThreadData;
    sThreadData.iEmbeddingDimension = iEmbeddingDimension;
    sThreadData.iLagTimeStep = iLagTimeStep;
    sThreadData.iYEmbeddingDimension = iYEmbeddingDimension;
    sThreadData.iYLagTimeStep = iYLagTimeStep;
    sThreadData.iLibraryLength = iLibraryLength;
    sThreadData.iMaxAutoCorrToCheck = iMaxAutoCorrToCheck;
    sThreadData.dCompareTolerance = dCompareTolerance;
    sThreadData.iNumberOfTimeStep2Check = iNumberOfTimeStep2Check;
    sThreadData.dWeightToleranceLevel = dWeightToleranceLevel;
    sThreadData.iEstimatedYLength = iEstimatedY_Length;
    sThreadData.dEstimatedY = dEstimatedY;
    sThreadData.bL2 = bL2;

    if( bVerboseFlag ){
            printf("Input data file: %s\nOutput file: %s\nNumber of time series in input file: %i\nLibrary length: %i\nEmbedding dimension: %i\nLag time step: %i\n",cFilename,cOutputname,iNumOfTimeSeries,iLibraryLength,iEmbeddingDimension,iLagTimeStep);
    }

    //open data input file
    FILE *ifstream = fopen(cFilename,"r");
    if(ifstream == NULL){
        fprintf(stderr, "Error: Cannot open %s\n",cFilename);
            return(-1);
    }

    //open [-o] output file
    FILE *ofstream = fopen(cOutputname,"w");
    if(ofstream == NULL){
        fprintf(stderr, "Error: Cannot open %s\n",cOutputname);
        return(-1);
    }

    //open [-eY] output file
    FILE *ofstreamTS = fopen(cTSOutputname,"w");
    if(ofstream == NULL){
        fprintf(stderr, "Error: Cannot open %s\n",cTSOutputname);
        return(-1);
    }

    if( bVerboseFlag ){ printf("Processing %s...\n",cFilename); }
    int iCurrentThreadsUsed = 0,
        iCheckThread = 0;
    bool bFoundOpenThread;
    for(int iTSiter = 0;iTSiter < iNumOfTimeSeries;iTSiter++ ){

        if( bVerboseFlag ){ printf("TS %i:",iTSiter); }
        if( bVerboseFlag ){ printf("Reading TS..."); }
        bFoundOpenThread = false;

        //read in dX and dY
        for( iter=0;iter < iLibraryLength;iter++ ){
                cRowValues = fgets(cBuffer,sizeof(cBuffer),ifstream);
                cColValue = strtok(cRowValues,",");
                if( cColValue != NULL ){
                   dX[iter] = atof(cColValue);
                }else{
                   fprintf(stderr, "Error: %s is not formatted correctly\n",cFilename);
                }

                cColValue = strtok(NULL,";");
                if( cColValue != NULL ){
                   dY[iter] = atof(cColValue);
                }else{
                   fprintf(stderr, "Error: %s is not formatted correctly\n",cFilename);
                }
        }

        if( bVerboseFlag ){ printf("Writing CCMs..."); }

        if( iNumThreads == 0 ){

              if( bPAI ){

                  sThreadData.dX = dX;
                  sThreadData.dY = dY;
                  bPAICalcPart1 = true;
                  fprintf(ofstream,"%.20f,",CCMcorr_async(sThreadData));
                  //printf("%.20f,",CCMcorr_async(sThreadData));
                  if( bSaveEstimatedTS ){
                      for(int iPrintStep = 0;iPrintStep < sThreadData.iEstimatedYLength;iPrintStep++ ){
			fprintf(ofstreamTS,"%.20f\n",sThreadData.dEstimatedY[iPrintStep]);
                      }
                  }
                  bPAICalcPart1 = false;
                  bPAICalcPart2 = true;
                  fprintf(ofstream,"%.20f,",CCMcorr_async(sThreadData));
                  //printf("%.20f,",CCMcorr_async(sThreadData));
                  if( bSaveEstimatedTS ){
                      for(int iPrintStep = 0;iPrintStep < sThreadData.iEstimatedYLength;iPrintStep++ ){
			fprintf(ofstreamTS,"%.20f\n",sThreadData.dEstimatedY[iPrintStep]);
                      }
                  }
                  bPAICalcPart2 = false;

                  bPAICalcPart1 = true;
                  sThreadData.dX = dY;
                  sThreadData.dY = dX;
                  fprintf(ofstream,"%.20f,",CCMcorr_async(sThreadData));
                  //printf("%.20f\n",CCMcorr_async(sThreadData));
                  if( bSaveEstimatedTS ){
                      for(int iPrintStep = 0;iPrintStep < sThreadData.iEstimatedYLength;iPrintStep++ ){
			fprintf(ofstreamTS,"%.20f\n",sThreadData.dEstimatedY[iPrintStep]);
                      }
                  }
                  bPAICalcPart1 = false;
                  bPAICalcPart2 = true;
                  fprintf(ofstream,"%.20f\n",CCMcorr_async(sThreadData));
                  //printf("%.20f\n",CCMcorr_async(sThreadData));
                  if( bSaveEstimatedTS ){
                      for(int iPrintStep = 0;iPrintStep < sThreadData.iEstimatedYLength;iPrintStep++ ){
			fprintf(ofstreamTS,"%.20f\n",sThreadData.dEstimatedY[iPrintStep]);
                      }
                  }
                  bPAICalcPart2 = false;

              }else{

                  sThreadData.dX = dX;
                  sThreadData.dY = dY;
                  fprintf(ofstream,"%.20f,",CCMcorr_async(sThreadData));
                  //printf("%.20f,",CCMcorr_async(sThreadData));
                  if( bSaveEstimatedTS ){
                      for(int iPrintStep = 0;iPrintStep < sThreadData.iEstimatedYLength;iPrintStep++ ){
			fprintf(ofstreamTS,"%.20f\n",sThreadData.dEstimatedY[iPrintStep]);
                      }
                  }

                  sThreadData.dX = dY;
                  sThreadData.dY = dX;
                  fprintf(ofstream,"%.20f\n",CCMcorr_async(sThreadData));
                  //printf("%.20f\n",CCMcorr_async(sThreadData));
                  if( bSaveEstimatedTS ){
                      for(int iPrintStep = 0;iPrintStep < sThreadData.iEstimatedYLength;iPrintStep++ ){
			fprintf(ofstreamTS,"%.20f\n",sThreadData.dEstimatedY[iPrintStep]);
                      }
                  }

              }

        }else{
            if( iCurrentThreadsUsed < iNumThreads ){

                sThreadData.dX = dX;
                sThreadData.dY = dY;
                WorkerThreads[iCurrentThreadsUsed][0] = async(launch::async,CCMcorr_async,sThreadData);

                sThreadData.dX = dY;
                sThreadData.dY = dX;
                WorkerThreads[iCurrentThreadsUsed][1] = async(launch::async,CCMcorr_async,sThreadData);

                iCurrentThreadsUsed++;

            }else{

                if( bOptThreading ){

                    while( !bFoundOpenThread ){
                        if( WorkerThreads[iCheckThread][0].valid() && WorkerThreads[iCheckThread][1].valid() ){

                            WorkerStatus[0] = WorkerThreads[iCheckThread][0].wait_for(chrono::seconds(iThreadWaitSec));
                            WorkerStatus[1] = WorkerThreads[iCheckThread][1].wait_for(chrono::seconds(iThreadWaitSec));

                            if( (WorkerStatus[0] == future_status::ready) && (WorkerStatus[1] == future_status::ready) ){
				
				fprintf(ofstream,"%.20f,",WorkerThreads[iCheckThread][0].get());
				fprintf(ofstream,"%.20f\n",WorkerThreads[iCheckThread][1].get());
				//printf("%.20f,",WorkerThreads[iCheckThread][0].get());
				//printf("%.20f\n",WorkerThreads[iCheckThread][1].get());

                                sThreadData.dX = dX;
                                sThreadData.dY = dY;
                                WorkerThreads[iCheckThread][0] = async(launch::async,CCMcorr_async,sThreadData);

                                sThreadData.dX = dY;
                                sThreadData.dY = dX;
                                WorkerThreads[iCheckThread][1] = async(launch::async,CCMcorr_async,sThreadData);

                                bFoundOpenThread = true;

                            }

                        }else if(!WorkerThreads[iCheckThread][0].valid()&&!WorkerThreads[iCheckThread][1].valid() ){

                            sThreadData.dX = dX;
                            sThreadData.dY = dY;
                            WorkerThreads[iCheckThread][0] = async(launch::async,CCMcorr_async,sThreadData);

                            sThreadData.dX = dY;
                            sThreadData.dY = dX;
                            WorkerThreads[iCheckThread][1] = async(launch::async,CCMcorr_async,sThreadData);

                            bFoundOpenThread = true;

                        }else{

                            iCheckThread++;
                            if( iCheckThread > iNumThreads ){
                                iCheckThread = 0;
                            }

                        }

                    }

                }else{

                    for(int iThreadIter = 0;iThreadIter < iNumThreads;iThreadIter++ ){

                        if( WorkerThreads[iThreadIter][0].valid() && WorkerThreads[iThreadIter][1].valid() ){
                            dCCMcorrs[iThreadIter][0] = WorkerThreads[iThreadIter][0].get();
                            dCCMcorrs[iThreadIter][1] = WorkerThreads[iThreadIter][1].get();
                        }

                    }

                    iCurrentThreadsUsed = 0;

                    sThreadData.dX = dX;
                    sThreadData.dY = dY;
                    WorkerThreads[iCurrentThreadsUsed][0] = async(launch::async,CCMcorr_async,sThreadData);

                    sThreadData.dX = dY;
                    sThreadData.dY = dX;
                    WorkerThreads[iCurrentThreadsUsed][1] = async(launch::async,CCMcorr_async,sThreadData);

                    for(int iThreadIter = 0;iThreadIter < iNumThreads;iThreadIter++ ){
                        fprintf(ofstream,"%.20f,",dCCMcorrs[iThreadIter][0]);
                        fprintf(ofstream,"%.20f\n",dCCMcorrs[iThreadIter][1]);
                        //printf("%.20f,",dCCMcorrs[iThreadIter][0]);
                        //printf("%.20f\n",dCCMcorrs[iThreadIter][1]);
                        dCCMcorrs[iThreadIter][0] = nan("");
                        dCCMcorrs[iThreadIter][1] = nan("");
                    }

                    iCurrentThreadsUsed++;
                }
            }
        }

        if( bVerboseFlag ){ printf(" done.\n"); }

    }

    for(int iThreadIter = 0;iThreadIter < iNumThreads;iThreadIter++ ){

        if( WorkerThreads[iThreadIter][0].valid() && WorkerThreads[iThreadIter][1].valid() ){
            fprintf(ofstream,"%.20f,",WorkerThreads[iThreadIter][0].get());
            fprintf(ofstream,"%.20f\n",WorkerThreads[iThreadIter][1].get());

        }

    }

    fclose(ifstream);
    fclose(ofstream);
    fclose(ofstreamTS);

    if( bVerboseFlag ){ printf(" Finished.\n"); }

    return(0);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x4e8, %rsp            # imm = 0x4E8
callq 0x5e9b
movl $0xffffffff, %r14d      # imm = 0xFFFFFFFF
testb %al, %al
je 0x5e23
movq %rsp, -0x108(%rbp)
movl 0x8028(%rip), %eax      # 0xd1c0
movl 0x801a(%rip), %ecx      # 0xd1b8
decl %ecx
imull 0x8015(%rip), %ecx      # 0xd1bc
movl %eax, %r13d
subl %ecx, %r13d
movq %rsp, %rcx
leaq 0xf(,%rax,8), %rax
andq $-0x10, %rax
subq %rax, %rcx
movq %rcx, -0x78(%rbp)
movq %rcx, %rsp
movl 0x7ff4(%rip), %eax      # 0xd1c0
movq %rsp, %rcx
movq %rax, -0xd8(%rbp)
leaq 0xf(,%rax,8), %rax
andq $-0x10, %rax
subq %rax, %rcx
movq %rcx, -0x48(%rbp)
movq %rcx, %rsp
leaq 0xf(,%r13,8), %rax
andq $-0x10, %rax
movq %rsp, %r15
subq %rax, %r15
movq %r15, %rsp
testl %r13d, %r13d
jle 0x5229
movl %r13d, %r14d
xorl %r12d, %r12d
leaq 0x3609(%rip), %rbx      # 0x881c
movq %rbx, %rdi
callq 0x3060
movsd %xmm0, (%r15,%r12,8)
incq %r12
cmpq %r12, %r14
jne 0x5213
movl 0x7fe0(%rip), %r12d     # 0xd210
movq %rsp, %rcx
movq %r12, %rax
shlq $0x5, %rax
subq %rax, %rcx
movq %rcx, -0xe8(%rbp)
movq %rcx, %rsp
movq %rsp, %rbx
movq %r12, %r14
shlq $0x6, %r14
subq %r14, %rbx
movq %rbx, %rsp
testq %r12, %r12
je 0x5269
movq %rbx, %rdi
xorl %esi, %esi
movq %r14, %rdx
callq 0x30f0
movq %r14, -0x100(%rbp)
movq %rbx, -0x50(%rbp)
movl 0x7f3d(%rip), %r9d      # 0xd1b8
movl %r9d, -0xd0(%rbp)
movl 0x7f33(%rip), %r10d     # 0xd1bc
movl %r10d, -0xcc(%rbp)
movl 0x7f3e(%rip), %eax      # 0xd1d4
movl %eax, -0xb8(%rbp)
movl 0x7f36(%rip), %eax      # 0xd1d8
movl %eax, -0xb4(%rbp)
movq -0xd8(%rbp), %r8
movl %r8d, -0xc8(%rbp)
movl 0x7f10(%rip), %eax      # 0xd1cc
movl %eax, -0xc4(%rbp)
movsd 0x7f16(%rip), %xmm0     # 0xd1e0
movsd %xmm0, -0xb0(%rbp)
movl 0x7ef8(%rip), %eax      # 0xd1d0
movl %eax, -0xc0(%rbp)
movsd 0x7f02(%rip), %xmm0     # 0xd1e8
movsd %xmm0, -0xa8(%rbp)
movl %r13d, -0xbc(%rbp)
movq %r15, -0x80(%rbp)
movb 0x7f39(%rip), %al       # 0xd238
movb %al, -0x98(%rbp)
cmpb $0x1, 0x7f24(%rip)      # 0xd230
jne 0x533a
movq 0x7f13(%rip), %rsi      # 0xd228
movq 0x7efc(%rip), %rdx      # 0xd218
movl 0x7ea2(%rip), %ecx      # 0xd1c4
subq $0x8, %rsp
leaq 0x3233(%rip), %rdi      # 0x8560
xorl %eax, %eax
pushq %r10
callq 0x3040
addq $0x10, %rsp
movq 0x7ee7(%rip), %rdi      # 0xd228
leaq 0x32a2(%rip), %rsi      # 0x85ea
callq 0x3210
movq %rax, -0xf8(%rbp)
testq %rax, %rax
movq -0x50(%rbp), %r13
movq -0x78(%rbp), %r15
je 0x5e35
movq 0x7eac(%rip), %rdi      # 0xd218
leaq 0x3290(%rip), %rsi      # 0x8603
callq 0x3210
movq %rax, -0x58(%rbp)
testq %rax, %rax
je 0x5e3c
movq 0x7e94(%rip), %rdi      # 0xd220
leaq 0x3270(%rip), %rsi      # 0x8603
callq 0x3210
movq %rax, %rbx
cmpb $0x1, 0x7e8e(%rip)      # 0xd230
jne 0x53b9
movq 0x7e7d(%rip), %rsi      # 0xd228
leaq 0x3253(%rip), %rdi      # 0x8605
xorl %eax, %eax
callq 0x3040
movq %rbx, -0x68(%rbp)
movq %r12, -0xe0(%rbp)
cmpl $0x0, 0x7df9(%rip)      # 0xd1c4
jle 0x5d56
addq $0x8, -0xe8(%rbp)
leaq 0x10(%r13), %rax
movq %rax, -0x110(%rbp)
leaq 0x3431(%rip), %r14      # 0x881c
movl $0x0, -0x6c(%rbp)
movq $0x0, -0xd8(%rbp)
movl $0x0, -0x5c(%rbp)
cmpb $0x1, 0x7e25(%rip)      # 0xd230
jne 0x541e
leaq 0x3203(%rip), %rdi      # 0x8617
movl -0x6c(%rbp), %esi
xorl %eax, %eax
callq 0x3040
cmpb $0x1, 0x7e0b(%rip)      # 0xd230
movq -0xf8(%rbp), %r12
jne 0x543c
leaq 0x31e9(%rip), %rdi      # 0x861e
xorl %eax, %eax
callq 0x3040
cmpl $0x0, 0x7d7d(%rip)      # 0xd1c0
jle 0x54c0
xorl %ebx, %ebx
leaq -0x510(%rbp), %rdi
movl $0x400, %esi            # imm = 0x400
movq %r12, %rdx
callq 0x32b0
movq %rax, %rdi
leaq 0x3202(%rip), %rsi      # 0x8667
callq 0x32a0
testq %rax, %rax
je 0x54b2
movq %rax, %rdi
callq 0x3220
movsd %xmm0, (%r15,%rbx,8)
xorl %edi, %edi
leaq 0x3dc8(%rip), %rsi      # 0x924e
callq 0x32a0
testq %rax, %rax
je 0x54b9
movq %rax, %rdi
callq 0x3220
movq -0x48(%rbp), %rax
movsd %xmm0, (%rax,%rbx,8)
incq %rbx
movslq 0x7d15(%rip), %rax      # 0xd1c0
cmpq %rax, %rbx
jl 0x5447
jmp 0x54c0
callq 0x39b6
jmp 0x547d
callq 0x39db
jmp 0x54a1
cmpb $0x1, 0x7d69(%rip)      # 0xd230
jne 0x54d7
leaq 0x3182(%rip), %rdi      # 0x8652
xorl %eax, %eax
callq 0x3040
movl 0x7d33(%rip), %eax      # 0xd210
testl %eax, %eax
je 0x55b6
cmpl %eax, -0x5c(%rbp)
jge 0x57f4
movq %r15, -0x90(%rbp)
movq -0x48(%rbp), %rax
movq %rax, -0x88(%rbp)
leaq -0x40(%rbp), %rdi
movl $0x1, %esi
leaq 0xece(%rip), %rdx       # 0x63de
leaq -0xd0(%rbp), %rcx
callq 0x693c
movslq -0x5c(%rbp), %rbx
shlq $0x6, %rbx
movaps -0x40(%rbp), %xmm0
xorps %xmm1, %xmm1
movaps %xmm1, -0x40(%rbp)
movq 0x8(%r13,%rbx), %rdi
movaps %xmm0, (%r13,%rbx)
testq %rdi, %rdi
je 0x5544
callq 0x6b08
movq -0x38(%rbp), %rdi
testq %rdi, %rdi
je 0x5552
callq 0x6b08
movq -0x48(%rbp), %rax
movq %rax, -0x90(%rbp)
movq %r15, -0x88(%rbp)
leaq -0x40(%rbp), %rdi
movl $0x1, %esi
leaq 0xe6a(%rip), %rdx       # 0x63de
leaq -0xd0(%rbp), %rcx
callq 0x693c
addq %r13, %rbx
movaps -0x40(%rbp), %xmm0
xorps %xmm1, %xmm1
movaps %xmm1, -0x40(%rbp)
movq 0x18(%rbx), %rdi
movaps %xmm0, 0x10(%rbx)
testq %rdi, %rdi
je 0x55a0
callq 0x6b08
movq -0x38(%rbp), %rdi
testq %rdi, %rdi
je 0x55ae
callq 0x6b08
incl -0x5c(%rbp)
jmp 0x5d2d
cmpb $0x1, 0x7c78(%rip)      # 0xd235
jne 0x5a87
movq %r15, -0x90(%rbp)
movq -0x48(%rbp), %rax
movq %rax, -0x88(%rbp)
movb $0x1, 0x7c5a(%rip)      # 0xd236
subq $0x60, %rsp
movl $0xb, %ecx
movq %rsp, %rdi
leaq -0xd0(%rbp), %rsi
rep  movsq (%rsi), %es:(%rdi)
callq 0x63de
addq $0x60, %rsp
movq -0x58(%rbp), %rdi
leaq 0x305c(%rip), %rsi      # 0x8662
movb $0x1, %al
callq 0x3260
cmpb $0x1, 0x7c1e(%rip)      # 0xd232
movq -0x68(%rbp), %r12
leaq 0x2af4(%rip), %r13      # 0x8113
jne 0x5651
cmpl $0x0, -0xbc(%rbp)
jle 0x5651
xorl %ebx, %ebx
movq -0x80(%rbp), %rax
movsd (%rax,%rbx,8), %xmm0
movq %r12, %rdi
movq %r13, %rsi
movb $0x1, %al
callq 0x3260
incq %rbx
movslq -0xbc(%rbp), %rax
cmpq %rax, %rbx
jl 0x562c
movb $0x0, 0x7bde(%rip)      # 0xd236
movb $0x1, 0x7bd8(%rip)      # 0xd237
subq $0x60, %rsp
movl $0xb, %ecx
movq %rsp, %rdi
leaq -0xd0(%rbp), %rsi
rep  movsq (%rsi), %es:(%rdi)
callq 0x63de
addq $0x60, %rsp
movq -0x58(%rbp), %rdi
leaq 0x2fd9(%rip), %rsi      # 0x8662
movb $0x1, %al
callq 0x3260
cmpb $0x1, 0x7b9b(%rip)      # 0xd232
movq -0x68(%rbp), %r12
leaq 0x2a71(%rip), %r13      # 0x8113
jne 0x56d4
cmpl $0x0, -0xbc(%rbp)
jle 0x56d4
xorl %ebx, %ebx
movq -0x80(%rbp), %rax
movsd (%rax,%rbx,8), %xmm0
movq %r12, %rdi
movq %r13, %rsi
movb $0x1, %al
callq 0x3260
incq %rbx
movslq -0xbc(%rbp), %rax
cmpq %rax, %rbx
jl 0x56af
movb $0x0, 0x7b5c(%rip)      # 0xd237
movb $0x1, 0x7b54(%rip)      # 0xd236
movq -0x48(%rbp), %rax
movq %rax, -0x90(%rbp)
movq %r15, -0x88(%rbp)
subq $0x60, %rsp
movl $0xb, %ecx
movq %rsp, %rdi
leaq -0xd0(%rbp), %rsi
rep  movsq (%rsi), %es:(%rdi)
callq 0x63de
addq $0x60, %rsp
movq -0x58(%rbp), %rdi
leaq 0x2f44(%rip), %rsi      # 0x8662
movb $0x1, %al
callq 0x3260
cmpb $0x1, 0x7b06(%rip)      # 0xd232
movq -0x68(%rbp), %r12
leaq 0x29dc(%rip), %r13      # 0x8113
jne 0x5769
cmpl $0x0, -0xbc(%rbp)
jle 0x5769
xorl %ebx, %ebx
movq -0x80(%rbp), %rax
movsd (%rax,%rbx,8), %xmm0
movq %r12, %rdi
movq %r13, %rsi
movb $0x1, %al
callq 0x3260
incq %rbx
movslq -0xbc(%rbp), %rax
cmpq %rax, %rbx
jl 0x5744
movb $0x0, 0x7ac6(%rip)      # 0xd236
movb $0x1, 0x7ac0(%rip)      # 0xd237
subq $0x60, %rsp
movl $0xb, %ecx
movq %rsp, %rdi
leaq -0xd0(%rbp), %rsi
rep  movsq (%rsi), %es:(%rdi)
callq 0x63de
addq $0x60, %rsp
movq -0x58(%rbp), %rdi
leaq 0x2972(%rip), %r13      # 0x8113
movq %r13, %rsi
movb $0x1, %al
callq 0x3260
cmpb $0x1, 0x7a80(%rip)      # 0xd232
movq -0x68(%rbp), %r12
jne 0x57e8
cmpl $0x0, -0xbc(%rbp)
jle 0x57e8
xorl %ebx, %ebx
movq -0x80(%rbp), %rax
movsd (%rax,%rbx,8), %xmm0
movq %r12, %rdi
movq %r13, %rsi
movb $0x1, %al
callq 0x3260
incq %rbx
movslq -0xbc(%rbp), %rax
cmpq %rax, %rbx
jl 0x57c3
movb $0x0, 0x7a48(%rip)      # 0xd237
jmp 0x5d29
cmpb $0x1, 0x7a36(%rip)      # 0xd231
jne 0x5ba2
xorl %r12d, %r12d
movslq -0xd8(%rbp), %rax
shlq $0x6, %rax
leaq (%rax,%r13), %rbx
movq (%r13,%rax), %rax
testq %rax, %rax
je 0x587f
cmpq $0x0, 0x10(%rbx)
je 0x587a
movq %r14, %r15
movslq 0x799a(%rip), %rax      # 0xd1c8
movq %rax, -0x40(%rbp)
movq %rbx, %rdi
leaq -0x40(%rbp), %r14
movq %r14, %rsi
callq 0x6a8c
movl %eax, %r13d
movq %rbx, -0xf0(%rbp)
addq $0x10, %rbx
movslq 0x7972(%rip), %rax      # 0xd1c8
movq %rax, -0x40(%rbp)
movq %rbx, %rdi
movq %r14, %rsi
callq 0x6a8c
orl %r13d, %eax
movq %r15, %r14
je 0x596e
movq -0x50(%rbp), %r13
jmp 0x5a74
testq %rax, %rax
jne 0x5886
cmpq $0x0, 0x10(%rbx)
je 0x58aa
movq -0xd8(%rbp), %rax
cmpl 0x797d(%rip), %eax      # 0xd210
leal 0x1(%rax), %eax
movl $0x0, %ecx
cmovgel %ecx, %eax
movq %rax, -0xd8(%rbp)
jmp 0x5a74
movq %rbx, %r12
movq -0x78(%rbp), %rbx
movq %rbx, -0x90(%rbp)
movq -0x48(%rbp), %rax
movq %rax, -0x88(%rbp)
leaq -0x40(%rbp), %r15
movq %r15, %rdi
movl $0x1, %esi
leaq 0xb08(%rip), %rdx       # 0x63de
leaq -0xd0(%rbp), %rcx
callq 0x693c
movaps -0x40(%rbp), %xmm0
xorps %xmm1, %xmm1
movaps %xmm1, -0x40(%rbp)
movq 0x8(%r12), %rdi
movaps %xmm0, (%r12)
testq %rdi, %rdi
je 0x5901
callq 0x6b08
movq -0x38(%rbp), %rdi
testq %rdi, %rdi
je 0x590f
callq 0x6b08
movq -0x48(%rbp), %rax
movq %rax, -0x90(%rbp)
movq %rbx, -0x88(%rbp)
movq %r15, %rdi
movl $0x1, %esi
leaq 0xaae(%rip), %rdx       # 0x63de
leaq -0xd0(%rbp), %rcx
callq 0x693c
movaps -0x40(%rbp), %xmm0
xorps %xmm1, %xmm1
movaps %xmm1, -0x40(%rbp)
movq 0x18(%r12), %rdi
movaps %xmm0, 0x10(%r12)
testq %rdi, %rdi
je 0x595c
callq 0x6b08
movq -0x38(%rbp), %rdi
testq %rdi, %rdi
je 0x5a71
jmp 0x5a6c
movq -0xf0(%rbp), %rdi
movq -0x50(%rbp), %r13
callq 0x6aa6
movq -0x58(%rbp), %r15
movq %r15, %rdi
leaq 0x2cd6(%rip), %rsi      # 0x8662
movb $0x1, %al
callq 0x3260
movq %rbx, %rdi
callq 0x6aa6
movq %r15, %rdi
leaq 0x276e(%rip), %rsi      # 0x8113
movb $0x1, %al
callq 0x3260
movq -0x78(%rbp), %rbx
movq %rbx, -0x90(%rbp)
movq -0x48(%rbp), %rax
movq %rax, -0x88(%rbp)
leaq -0x40(%rbp), %r15
movq %r15, %rdi
movl $0x1, %esi
leaq 0xa09(%rip), %rdx       # 0x63de
leaq -0xd0(%rbp), %rcx
callq 0x693c
movaps -0x40(%rbp), %xmm0
xorps %xmm1, %xmm1
movaps %xmm1, -0x40(%rbp)
movq -0xf0(%rbp), %rax
movq 0x8(%rax), %rdi
movaps %xmm0, (%rax)
testq %rdi, %rdi
je 0x5a04
callq 0x6b08
movq -0x38(%rbp), %rdi
testq %rdi, %rdi
je 0x5a12
callq 0x6b08
movq -0x48(%rbp), %rax
movq %rax, -0x90(%rbp)
movq %rbx, -0x88(%rbp)
movq %r15, %rdi
movl $0x1, %esi
leaq 0x9ab(%rip), %rdx       # 0x63de
leaq -0xd0(%rbp), %rcx
callq 0x693c
movaps -0x40(%rbp), %xmm0
xorps %xmm1, %xmm1
movaps %xmm1, -0x40(%rbp)
movq -0xf0(%rbp), %rax
movq 0x18(%rax), %rdi
movaps %xmm0, 0x10(%rax)
testq %rdi, %rdi
je 0x5a63
callq 0x6b08
movq -0x38(%rbp), %rdi
testq %rdi, %rdi
je 0x5a71
callq 0x6b08
movb $0x1, %r12b
testb $0x1, %r12b
je 0x5804
movq -0x78(%rbp), %r15
jmp 0x5d2d
movq %r15, -0x90(%rbp)
movq -0x48(%rbp), %rax
movq %rax, -0x88(%rbp)
subq $0x60, %rsp
movl $0xb, %ecx
movq %rsp, %rdi
leaq -0xd0(%rbp), %rsi
rep  movsq (%rsi), %es:(%rdi)
callq 0x63de
addq $0x60, %rsp
movq -0x58(%rbp), %rdi
leaq 0x2b9f(%rip), %rsi      # 0x8662
movb $0x1, %al
callq 0x3260
cmpb $0x1, 0x7761(%rip)      # 0xd232
movq -0x68(%rbp), %r12
leaq 0x2637(%rip), %r13      # 0x8113
jne 0x5b0e
cmpl $0x0, -0xbc(%rbp)
jle 0x5b0e
xorl %ebx, %ebx
movq -0x80(%rbp), %rax
movsd (%rax,%rbx,8), %xmm0
movq %r12, %rdi
movq %r13, %rsi
movb $0x1, %al
callq 0x3260
incq %rbx
movslq -0xbc(%rbp), %rax
cmpq %rax, %rbx
jl 0x5ae9
movq -0x48(%rbp), %rax
movq %rax, -0x90(%rbp)
movq %r15, -0x88(%rbp)
subq $0x60, %rsp
movl $0xb, %ecx
movq %rsp, %rdi
leaq -0xd0(%rbp), %rsi
rep  movsq (%rsi), %es:(%rdi)
callq 0x63de
addq $0x60, %rsp
movq -0x58(%rbp), %rdi
leaq 0x25c9(%rip), %rsi      # 0x8113
movb $0x1, %al
callq 0x3260
cmpb $0x1, 0x76da(%rip)      # 0xd232
jne 0x5d29
cmpl $0x0, -0xbc(%rbp)
jle 0x5d29
xorl %ebx, %ebx
movq -0x68(%rbp), %r12
leaq 0x259b(%rip), %r13      # 0x8113
movq -0x80(%rbp), %rax
movsd (%rax,%rbx,8), %xmm0
movq %r12, %rdi
movq %r13, %rsi
movb $0x1, %al
callq 0x3260
incq %rbx
movslq -0xbc(%rbp), %rax
cmpq %rax, %rbx
jl 0x5b78
jmp 0x5d29
cmpl $0x0, 0x7667(%rip)      # 0xd210
jle 0x5bfd
movq -0x110(%rbp), %r12
movq -0xe8(%rbp), %rbx
xorl %r15d, %r15d
cmpq $0x0, -0x10(%r12)
je 0x5be6
cmpq $0x0, (%r12)
je 0x5be6
leaq -0x10(%r12), %rdi
callq 0x6aa6
movsd %xmm0, -0x8(%rbx)
movq %r12, %rdi
callq 0x6aa6
movsd %xmm0, (%rbx)
incq %r15
movslq 0x7620(%rip), %rax      # 0xd210
addq $0x20, %rbx
addq $0x40, %r12
cmpq %rax, %r15
jl 0x5bbc
movq -0x78(%rbp), %r15
movq %r15, -0x90(%rbp)
movq -0x48(%rbp), %rax
movq %rax, -0x88(%rbp)
leaq -0x40(%rbp), %rdi
movl $0x1, %esi
leaq 0x7bb(%rip), %rdx       # 0x63de
leaq -0xd0(%rbp), %rcx
callq 0x693c
movaps -0x40(%rbp), %xmm0
xorps %xmm1, %xmm1
movaps %xmm1, -0x40(%rbp)
movq 0x8(%r13), %rdi
movaps %xmm0, (%r13)
testq %rdi, %rdi
je 0x5c4d
callq 0x6b08
movq -0x38(%rbp), %rdi
testq %rdi, %rdi
je 0x5c5b
callq 0x6b08
movq -0x48(%rbp), %rax
movq %rax, -0x90(%rbp)
movq %r15, -0x88(%rbp)
leaq -0x40(%rbp), %rdi
movl $0x1, %esi
leaq 0x761(%rip), %rdx       # 0x63de
leaq -0xd0(%rbp), %rcx
callq 0x693c
movaps -0x40(%rbp), %xmm0
xorps %xmm1, %xmm1
movaps %xmm1, -0x40(%rbp)
movq 0x18(%r13), %rdi
movaps %xmm0, 0x10(%r13)
testq %rdi, %rdi
je 0x5ca7
callq 0x6b08
movq -0x38(%rbp), %rdi
testq %rdi, %rdi
je 0x5cb5
callq 0x6b08
movl $0x1, -0x5c(%rbp)
cmpl $0x0, 0x754d(%rip)      # 0xd210
jle 0x5d2d
movq -0xe8(%rbp), %rbx
xorl %r15d, %r15d
movq -0x58(%rbp), %r12
leaq 0x2439(%rip), %r13      # 0x8113
movsd -0x8(%rbx), %xmm0
movq %r12, %rdi
leaq 0x2979(%rip), %rsi      # 0x8662
movb $0x1, %al
callq 0x3260
movsd (%rbx), %xmm0
movq %r12, %rdi
movq %r13, %rsi
movb $0x1, %al
callq 0x3260
movq %r14, %rdi
callq 0x3060
movsd %xmm0, -0x8(%rbx)
movsd %xmm0, (%rbx)
incq %r15
movslq 0x74f4(%rip), %rax      # 0xd210
addq $0x20, %rbx
cmpq %rax, %r15
jl 0x5cda
movq -0x78(%rbp), %r15
movq -0x50(%rbp), %r13
cmpb $0x1, 0x74fc(%rip)      # 0xd230
jne 0x5d42
leaq 0x2d42(%rip), %rdi      # 0x8a7f
callq 0x3280
movl -0x6c(%rbp), %eax
incl %eax
movl %eax, -0x6c(%rbp)
cmpl 0x7474(%rip), %eax      # 0xd1c4
jl 0x5404
cmpl $0x0, 0x74b3(%rip)      # 0xd210
movq -0x58(%rbp), %r15
jle 0x5dc2
leaq 0x10(%r13), %r12
xorl %ebx, %ebx
leaq 0x28f2(%rip), %r14      # 0x8662
cmpq $0x0, -0x10(%r12)
je 0x5daf
cmpq $0x0, (%r12)
je 0x5daf
leaq -0x10(%r12), %rdi
callq 0x6aa6
movq %r15, %rdi
movq %r14, %rsi
movb $0x1, %al
callq 0x3260
movq %r12, %rdi
callq 0x6aa6
movq %r15, %rdi
leaq 0x236b(%rip), %rsi      # 0x8113
movb $0x1, %al
callq 0x3260
incq %rbx
movslq 0x7457(%rip), %rax      # 0xd210
addq $0x40, %r12
cmpq %rax, %rbx
jl 0x5d70
movq -0xf8(%rbp), %rdi
callq 0x31c0
movq %r15, %rdi
callq 0x31c0
movq -0x68(%rbp), %rdi
callq 0x31c0
xorl %r14d, %r14d
cmpb $0x0, 0x7447(%rip)      # 0xd230
je 0x5df7
leaq 0x2c82(%rip), %rdi      # 0x8a74
callq 0x3280
movq -0xe0(%rbp), %r12
testq %r12, %r12
je 0x5e1c
shlq $0x6, %r12
movq -0x8(%r13,%r12), %rdi
testq %rdi, %rdi
je 0x5e16
callq 0x6b08
addq $-0x10, %r12
jne 0x5e07
movq -0x108(%rbp), %rsp
movl %r14d, %eax
leaq -0x28(%rbp), %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
callq 0x3a25
jmp 0x5e41
callq 0x3a00
movl $0xffffffff, %r14d      # imm = 0xFFFFFFFF
jmp 0x5dfe
jmp 0x5e6a
jmp 0x5e6a
jmp 0x5e6a
jmp 0x5e6a
jmp 0x5e6a
jmp 0x5e6a
jmp 0x5e6a
jmp 0x5e6a
jmp 0x5e6a
jmp 0x5e61
jmp 0x5e6a
jmp 0x5e61
movq %rax, %r15
movq -0x50(%rbp), %r13
jmp 0x5e6d
movq %rax, %r15
cmpq $0x0, -0xe0(%rbp)
movq -0x100(%rbp), %rbx
je 0x5e93
movq -0x8(%r13,%rbx), %rdi
testq %rdi, %rdi
je 0x5e8d
callq 0x6b08
addq $-0x10, %rbx
jne 0x5e7e
movq %r15, %rdi
callq 0x3300