// File: /workspace/github_cpp_makefile_star2_O2/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 $0x4d8, %rsp            # imm = 0x4D8
callq 0x56e1
testb %al, %al
je 0x4baa
movq %rsp, -0xf8(%rbp)
movl 0x86c2(%rip), %eax      # 0xd1d8
movl 0x86b4(%rip), %ecx      # 0xd1d0
decl %ecx
imull 0x86af(%rip), %ecx      # 0xd1d4
movl %eax, %r15d
subl %ecx, %r15d
movq %rsp, %rcx
leaq 0xf(,%rax,8), %rax
andq $-0x10, %rax
subq %rax, %rcx
movq %rcx, -0x60(%rbp)
movq %rcx, %rsp
movl 0x868e(%rip), %eax      # 0xd1d8
movq %rsp, %rcx
movq %rax, -0x50(%rbp)
leaq 0xf(,%rax,8), %rax
andq $-0x10, %rax
subq %rax, %rcx
movq %rcx, -0x68(%rbp)
movq %rcx, %rsp
leaq 0xf(,%r15,8), %rax
andq $-0x10, %rax
movq %rsp, %r12
subq %rax, %r12
movq %r12, %rsp
xorl %r13d, %r13d
testl %r15d, %r15d
movl $0x0, %ebx
cmovgl %r15d, %ebx
leaq 0x3c46(%rip), %r14      # 0x87d8
cmpq %r13, %rbx
je 0x4bb2
movq %r14, %rdi
callq 0x3060
movsd %xmm0, (%r12,%r13,8)
incq %r13
jmp 0x4b92
pushq $-0x1
popq %rbx
jmp 0x568d
movl 0x8670(%rip), %ecx      # 0xd228
movq %rsp, %rdx
movq %rcx, %rax
shlq $0x5, %rax
subq %rax, %rdx
movq %rdx, -0xe0(%rbp)
movq %rdx, %rsp
movq %rsp, %rbx
movq %rcx, %r14
shlq $0x6, %r14
subq %r14, %rbx
movq %rbx, %rsp
movq %rcx, -0x70(%rbp)
testq %rcx, %rcx
je 0x4bf5
movq %rbx, %rdi
xorl %esi, %esi
movq %r14, %rdx
callq 0x3120
movq %rbx, -0x30(%rbp)
movl 0x85d0(%rip), %r9d      # 0xd1d0
movl %r9d, -0xd0(%rbp)
movl 0x85c6(%rip), %r10d     # 0xd1d4
movl %r10d, -0xcc(%rbp)
movl 0x85d1(%rip), %eax      # 0xd1ec
movl %eax, -0xb8(%rbp)
movl 0x85c9(%rip), %eax      # 0xd1f0
movl %eax, -0xb4(%rbp)
movq -0x50(%rbp), %r8
movl %r8d, -0xc8(%rbp)
movl 0x85a6(%rip), %eax      # 0xd1e4
movl %eax, -0xc4(%rbp)
movsd 0x85ac(%rip), %xmm0     # 0xd1f8
movsd %xmm0, -0xb0(%rbp)
movl 0x858e(%rip), %eax      # 0xd1e8
movl %eax, -0xc0(%rbp)
movsd 0x8598(%rip), %xmm0     # 0xd200
movsd %xmm0, -0xa8(%rbp)
movl %r15d, -0xbc(%rbp)
movq %r12, -0x80(%rbp)
movb 0x85cf(%rip), %al       # 0xd250
movb %al, -0x98(%rbp)
cmpb $0x1, 0x85ba(%rip)      # 0xd248
movq -0x68(%rbp), %r13
jne 0x4cbe
movq 0x85a5(%rip), %rsi      # 0xd240
movq 0x858e(%rip), %rdx      # 0xd230
movl 0x8534(%rip), %ecx      # 0xd1dc
subq $0x8, %rsp
leaq 0x3887(%rip), %rdi      # 0x853a
xorl %eax, %eax
pushq %r10
callq 0x3040
popq %rcx
popq %rdx
movq 0x857b(%rip), %rdi      # 0xd240
leaq 0x38f8(%rip), %rsi      # 0x85c4
callq 0x3230
testq %rax, %rax
movq -0x60(%rbp), %r12
je 0x562d
movq %rax, %r15
movq 0x8548(%rip), %rdi      # 0xd230
leaq 0x38ee(%rip), %rsi      # 0x85dd
callq 0x3230
testq %rax, %rax
je 0x5640
movq %rax, %rbx
movq 0x8531(%rip), %rdi      # 0xd238
leaq 0x38cf(%rip), %rsi      # 0x85dd
callq 0x3230
movq %rax, -0x50(%rbp)
cmpb $0x1, 0x852a(%rip)      # 0xd248
jne 0x4d35
movq 0x8519(%rip), %rsi      # 0xd240
leaq 0x38b1(%rip), %rdi      # 0x85df
xorl %eax, %eax
callq 0x3040
movq -0x30(%rbp), %rax
addq $0x10, %rax
movq %rax, -0xf0(%rbp)
addq $0x8, -0xe0(%rbp)
movl $0x0, -0x54(%rbp)
movq $0x0, -0xe8(%rbp)
xorl %eax, %eax
movq %rbx, -0x48(%rbp)
movq %r15, -0x100(%rbp)
cmpl 0x846b(%rip), %eax      # 0xd1dc
jge 0x558e
movl %eax, -0x74(%rbp)
movb 0x84c8(%rip), %al       # 0xd248
cmpb $0x1, %al
jne 0x4d9b
leaq 0x3866(%rip), %rdi      # 0x85f1
movl -0x74(%rbp), %esi
xorl %eax, %eax
callq 0x3040
movb 0x84ad(%rip), %al       # 0xd248
testb $0x1, %al
je 0x4dad
leaq 0x3852(%rip), %rdi      # 0x85f8
xorl %eax, %eax
callq 0x3040
xorl %ebx, %ebx
movslq 0x8422(%rip), %rax      # 0xd1d8
cmpq %rax, %rbx
jge 0x4e5e
leaq -0x500(%rbp), %rdi
movl $0x400, %esi            # imm = 0x400
movq %r15, %rdx
callq 0x32e0
movq %rax, %rdi
leaq 0x3864(%rip), %rsi      # 0x8641
callq 0x32d0
testq %rax, %rax
je 0x4e1c
movq %rax, %rdi
callq 0x3240
movsd %xmm0, (%r12,%rbx,8)
xorl %edi, %edi
leaq 0x43af(%rip), %rsi      # 0x91ad
callq 0x32d0
testq %rax, %rax
je 0x4e3d
movq %rax, %rdi
callq 0x3240
movsd %xmm0, (%r13,%rbx,8)
incq %rbx
jmp 0x4daf
movq 0x81a5(%rip), %rax      # 0xcfc8
movq (%rax), %rdi
movq 0x8413(%rip), %rdx      # 0xd240
leaq 0x37d2(%rip), %rsi      # 0x8606
xorl %eax, %eax
callq 0x3290
jmp 0x4df5
movq 0x8184(%rip), %rax      # 0xcfc8
movq (%rax), %rdi
movq 0x83f2(%rip), %rdx      # 0xd240
leaq 0x37b1(%rip), %rsi      # 0x8606
xorl %eax, %eax
callq 0x3290
jmp 0x4e17
cmpb $0x1, 0x83e3(%rip)      # 0xd248
jne 0x4e75
leaq 0x37be(%rip), %rdi      # 0x862c
xorl %eax, %eax
callq 0x3040
movl 0x83ad(%rip), %eax      # 0xd228
testl %eax, %eax
movq -0x48(%rbp), %rbx
je 0x4f22
cmpl %eax, -0x54(%rbp)
jge 0x4fb2
movq %r12, -0x90(%rbp)
movq %r13, -0x88(%rbp)
leaq -0x40(%rbp), %rdi
pushq $0x1
popq %rsi
leaq 0xe8c(%rip), %rdx       # 0x5d38
leaq -0xd0(%rbp), %rcx
callq 0x6293
movslq -0x54(%rbp), %rbx
shlq $0x6, %rbx
addq -0x30(%rbp), %rbx
movq %rbx, %rdi
leaq -0x40(%rbp), %rsi
callq 0x63a8
leaq -0x38(%rbp), %rdi
callq 0x644a
movq %r13, -0x90(%rbp)
movq %r12, -0x88(%rbp)
leaq -0x40(%rbp), %rdi
pushq $0x1
popq %rsi
leaq 0xe43(%rip), %rdx       # 0x5d38
leaq -0xd0(%rbp), %rcx
callq 0x6293
addq $0x10, %rbx
movq %rbx, %rdi
leaq -0x40(%rbp), %rsi
callq 0x63a8
leaq -0x38(%rbp), %rdi
callq 0x644a
incl -0x54(%rbp)
jmp 0x54f6
movb 0x8325(%rip), %al       # 0xd24d
movq %r12, -0x90(%rbp)
movq %r13, -0x88(%rbp)
cmpb $0x1, %al
jne 0x5067
movb $0x1, 0x8309(%rip)      # 0xd24e
subq $0x60, %rsp
pushq $0xb
popq %rcx
movq %rsp, %rdi
leaq -0xd0(%rbp), %rsi
rep  movsq (%rsi), %es:(%rdi)
callq 0x5d38
addq $0x60, %rsp
movq %rbx, %rdi
leaq 0x36d0(%rip), %rsi      # 0x863c
movb $0x1, %al
callq 0x3290
cmpb $0x1, 0x82d0(%rip)      # 0xd24a
jne 0x50d4
xorl %ebx, %ebx
movslq -0xbc(%rbp), %rax
cmpq %rax, %rbx
jge 0x50d4
movq -0x80(%rbp), %rax
movsd (%rax,%rbx,8), %xmm0
movq -0x50(%rbp), %rdi
leaq 0x3165(%rip), %rsi      # 0x810b
movb $0x1, %al
callq 0x3290
incq %rbx
jmp 0x4f82
cmpb $0x0, 0x8290(%rip)      # 0xd249
je 0x52ce
movq -0xe8(%rbp), %rax
movq %rax, -0xe8(%rbp)
cltq
shlq $0x6, %rax
movq -0x30(%rbp), %rcx
leaq (%rcx,%rax), %r12
addq %rcx, %rax
addq $0x10, %rax
movq %rax, -0xd8(%rbp)
cmpq $0x0, (%r12)
movq 0x10(%r12), %rax
je 0x5041
testq %rax, %rax
je 0x504a
movq %r15, %rbx
movslq 0x81dc(%rip), %rax      # 0xd1e0
movq %rax, -0x40(%rbp)
movq %r12, %rdi
leaq -0x40(%rbp), %r15
movq %r15, %rsi
callq 0x63e2
movl %eax, %r13d
movslq 0x81bf(%rip), %rax      # 0xd1e0
movq %rax, -0x40(%rbp)
movq -0xd8(%rbp), %rdi
movq %r15, %rsi
callq 0x63e2
orl %r13d, %eax
movq %rbx, %r15
jne 0x4fe9
jmp 0x5428
testq %rax, %rax
je 0x5515
movq -0xe8(%rbp), %rax
cmpl 0x81d1(%rip), %eax      # 0xd228
leal 0x1(%rax), %eax
movl $0x0, %ecx
cmovgel %ecx, %eax
jmp 0x4fc6
subq $0x60, %rsp
pushq $0xb
popq %rcx
movq %rsp, %rdi
leaq -0xd0(%rbp), %rsi
rep  movsq (%rsi), %es:(%rdi)
callq 0x5d38
addq $0x60, %rsp
movq %rbx, %rdi
leaq 0x35ae(%rip), %rsi      # 0x863c
movb $0x1, %al
callq 0x3290
cmpb $0x1, 0x81ae(%rip)      # 0xd24a
jne 0x5150
xorl %ebx, %ebx
movslq -0xbc(%rbp), %rax
cmpq %rax, %rbx
jge 0x5150
movq -0x80(%rbp), %rax
movsd (%rax,%rbx,8), %xmm0
movq -0x50(%rbp), %rdi
leaq 0x3043(%rip), %rsi      # 0x810b
movb $0x1, %al
callq 0x3290
incq %rbx
jmp 0x50a4
movb $0x0, 0x8173(%rip)      # 0xd24e
movb $0x1, 0x816d(%rip)      # 0xd24f
subq $0x60, %rsp
pushq $0xb
popq %rcx
movq %rsp, %rdi
leaq -0xd0(%rbp), %rsi
rep  movsq (%rsi), %es:(%rdi)
callq 0x5d38
addq $0x60, %rsp
movq -0x48(%rbp), %rdi
leaq 0x3532(%rip), %rsi      # 0x863c
movb $0x1, %al
callq 0x3290
cmpb $0x1, 0x8132(%rip)      # 0xd24a
jne 0x51cc
xorl %ebx, %ebx
movslq -0xbc(%rbp), %rax
cmpq %rax, %rbx
jge 0x51cc
movq -0x80(%rbp), %rax
movsd (%rax,%rbx,8), %xmm0
movq -0x50(%rbp), %rdi
leaq 0x2fc7(%rip), %rsi      # 0x810b
movb $0x1, %al
callq 0x3290
incq %rbx
jmp 0x5120
movq %r13, -0x90(%rbp)
movq %r12, -0x88(%rbp)
subq $0x60, %rsp
pushq $0xb
popq %rcx
movq %rsp, %rdi
leaq -0xd0(%rbp), %rsi
rep  movsq (%rsi), %es:(%rdi)
callq 0x5d38
addq $0x60, %rsp
movq -0x48(%rbp), %rdi
leaq 0x2f85(%rip), %rsi      # 0x810b
movb $0x1, %al
callq 0x3290
cmpb $0x1, 0x80b6(%rip)      # 0xd24a
jne 0x54f6
xorl %ebx, %ebx
movslq -0xbc(%rbp), %rax
cmpq %rax, %rbx
jge 0x54f6
movq -0x80(%rbp), %rax
movsd (%rax,%rbx,8), %xmm0
movq -0x50(%rbp), %rdi
leaq 0x2f4b(%rip), %rsi      # 0x810b
movb $0x1, %al
callq 0x3290
incq %rbx
jmp 0x519c
movb $0x0, 0x807c(%rip)      # 0xd24f
movb $0x1, 0x8074(%rip)      # 0xd24e
movq %r13, -0x90(%rbp)
movq %r12, -0x88(%rbp)
subq $0x60, %rsp
pushq $0xb
popq %rcx
movq %rsp, %rdi
leaq -0xd0(%rbp), %rsi
rep  movsq (%rsi), %es:(%rdi)
callq 0x5d38
addq $0x60, %rsp
movq -0x48(%rbp), %rdi
leaq 0x342c(%rip), %rsi      # 0x863c
movb $0x1, %al
callq 0x3290
cmpb $0x1, 0x802c(%rip)      # 0xd24a
jne 0x524e
xorl %ebx, %ebx
movslq -0xbc(%rbp), %rax
cmpq %rax, %rbx
jge 0x524e
movq -0x80(%rbp), %rax
movsd (%rax,%rbx,8), %xmm0
movq -0x50(%rbp), %rdi
leaq 0x2ec9(%rip), %rsi      # 0x810b
movb $0x1, %al
callq 0x3290
incq %rbx
jmp 0x5222
movb $0x0, 0x7ff9(%rip)      # 0xd24e
movb $0x1, 0x7ff3(%rip)      # 0xd24f
subq $0x60, %rsp
pushq $0xb
popq %rcx
movq %rsp, %rdi
leaq -0xd0(%rbp), %rsi
rep  movsq (%rsi), %es:(%rdi)
callq 0x5d38
addq $0x60, %rsp
movq -0x48(%rbp), %rdi
leaq 0x2e87(%rip), %rsi      # 0x810b
movb $0x1, %al
callq 0x3290
cmpb $0x1, 0x7fb8(%rip)      # 0xd24a
jne 0x52c2
xorl %ebx, %ebx
movslq -0xbc(%rbp), %rax
cmpq %rax, %rbx
jge 0x52c2
movq -0x80(%rbp), %rax
movsd (%rax,%rbx,8), %xmm0
movq -0x50(%rbp), %rdi
leaq 0x2e55(%rip), %rsi      # 0x810b
movb $0x1, %al
callq 0x3290
incq %rbx
jmp 0x5296
movb $0x0, 0x7f86(%rip)      # 0xd24f
jmp 0x54f6
movq -0xf0(%rbp), %rbx
movq -0xe0(%rbp), %r12
xorl %r13d, %r13d
movslq %eax, %rcx
cmpq %rcx, %r13
jge 0x5325
cmpq $0x0, -0x10(%rbx)
je 0x5318
cmpq $0x0, (%rbx)
je 0x5318
leaq -0x10(%rbx), %rdi
callq 0x6404
movsd %xmm0, -0x8(%r12)
movq %rbx, %rdi
callq 0x6404
movsd %xmm0, (%r12)
movl 0x7f10(%rip), %eax      # 0xd228
incq %r13
addq $0x20, %r12
addq $0x40, %rbx
jmp 0x52df
movq -0x60(%rbp), %rax
movq %rax, -0x90(%rbp)
movq -0x68(%rbp), %r13
movq %r13, -0x88(%rbp)
leaq -0x40(%rbp), %rdi
pushq $0x1
popq %rsi
leaq 0x9ef(%rip), %rbx       # 0x5d38
movq %rbx, %rdx
leaq -0xd0(%rbp), %r12
movq %r12, %rcx
callq 0x6293
movq -0x30(%rbp), %rdi
leaq -0x40(%rbp), %r15
movq %r15, %rsi
callq 0x63a8
leaq -0x38(%rbp), %rdi
callq 0x644a
movq %r13, -0x90(%rbp)
movq -0x60(%rbp), %rax
movq %rax, -0x88(%rbp)
movq %r15, %rdi
pushq $0x1
popq %rsi
movq %rbx, %rdx
movq %r12, %rcx
callq 0x6293
movq -0xf0(%rbp), %rdi
movq %r15, %rsi
callq 0x63a8
leaq -0x38(%rbp), %rdi
callq 0x644a
movq -0xe0(%rbp), %rbx
xorl %r12d, %r12d
movslq 0x7e68(%rip), %rax      # 0xd228
cmpq %rax, %r12
jge 0x5412
movsd -0x8(%rbx), %xmm0
movq -0x48(%rbp), %r15
movq %r15, %rdi
leaq 0x3264(%rip), %rsi      # 0x863c
movb $0x1, %al
callq 0x3290
movsd (%rbx), %xmm0
movq %r15, %rdi
leaq 0x2d1e(%rip), %rsi      # 0x810b
movb $0x1, %al
callq 0x3290
leaq 0x33dd(%rip), %rdi      # 0x87d8
callq 0x3060
movsd %xmm0, -0x8(%rbx)
movsd %xmm0, (%rbx)
incq %r12
addq $0x20, %rbx
jmp 0x53b9
pushq $0x1
popq %rax
movl %eax, -0x54(%rbp)
movq -0x60(%rbp), %r12
movq -0x100(%rbp), %r15
jmp 0x54f6
movq %r12, %rdi
callq 0x6404
movq -0x48(%rbp), %r13
movq %r13, %rdi
leaq 0x31fe(%rip), %rsi      # 0x863c
movb $0x1, %al
callq 0x3290
movq -0xd8(%rbp), %rdi
callq 0x6404
movq %r13, %rdi
leaq 0x2cb0(%rip), %rsi      # 0x810b
movb $0x1, %al
callq 0x3290
movq -0x60(%rbp), %rax
movq %rax, -0x90(%rbp)
movq -0x68(%rbp), %r13
movq %r13, -0x88(%rbp)
leaq -0x40(%rbp), %rdi
pushq $0x1
popq %rbx
movl %ebx, %esi
leaq 0x8b0(%rip), %rdx       # 0x5d38
leaq -0xd0(%rbp), %rcx
callq 0x6293
movq %r12, %rdi
leaq -0x40(%rbp), %r12
movq %r12, %rsi
callq 0x63a8
leaq -0x38(%rbp), %rdi
callq 0x644a
movq %r13, -0x90(%rbp)
movq -0x60(%rbp), %r13
movq %r13, -0x88(%rbp)
movq %r12, %rdi
movl %ebx, %esi
leaq 0x86e(%rip), %rdx       # 0x5d38
leaq -0xd0(%rbp), %rcx
callq 0x6293
movq %r13, %r12
movq -0xd8(%rbp), %rdi
leaq -0x40(%rbp), %rsi
callq 0x63a8
leaq -0x38(%rbp), %rdi
callq 0x644a
movq -0x68(%rbp), %r13
cmpb $0x1, 0x7d4b(%rip)      # 0xd248
jne 0x550b
leaq 0x34d8(%rip), %rdi      # 0x89de
callq 0x32b0
movl -0x74(%rbp), %eax
incl %eax
jmp 0x4d6b
movq -0x60(%rbp), %rax
movq %rax, -0x90(%rbp)
movq -0x68(%rbp), %r13
movq %r13, -0x88(%rbp)
leaq -0x40(%rbp), %rdi
pushq $0x1
popq %rbx
movl %ebx, %esi
leaq 0x7fd(%rip), %rdx       # 0x5d38
leaq -0xd0(%rbp), %rcx
callq 0x6293
movq %r12, %rdi
leaq -0x40(%rbp), %r12
movq %r12, %rsi
callq 0x63a8
leaq -0x38(%rbp), %rdi
callq 0x644a
movq %r13, -0x90(%rbp)
movq -0x60(%rbp), %r13
movq %r13, -0x88(%rbp)
movq %r12, %rdi
movl %ebx, %esi
leaq 0x7bb(%rip), %rdx       # 0x5d38
leaq -0xd0(%rbp), %rcx
callq 0x6293
jmp 0x54d6
movl 0x7c94(%rip), %eax      # 0xd228
movq -0x30(%rbp), %rcx
leaq 0x10(%rcx), %rbx
xorl %r12d, %r12d
movq -0x48(%rbp), %r13
movslq %eax, %rcx
cmpq %rcx, %r12
jge 0x55fa
cmpq $0x0, -0x10(%rbx)
je 0x55f1
cmpq $0x0, (%rbx)
je 0x55f1
leaq -0x10(%rbx), %rdi
callq 0x6404
movq %r13, %rdi
leaq 0x3071(%rip), %rsi      # 0x863c
movb $0x1, %al
callq 0x3290
movq %rbx, %rdi
callq 0x6404
movq %r13, %rdi
leaq 0x2b27(%rip), %rsi      # 0x810b
movb $0x1, %al
callq 0x3290
movl 0x7c37(%rip), %eax      # 0xd228
incq %r12
addq $0x40, %rbx
jmp 0x55a3
movq %r15, %rdi
callq 0x31f0
movq -0x48(%rbp), %rdi
callq 0x31f0
movq -0x50(%rbp), %rdi
callq 0x31f0
xorl %ebx, %ebx
cmpb $0x0, 0x7c2b(%rip)      # 0xd248
je 0x5662
leaq 0x33ad(%rip), %rdi      # 0x89d3
callq 0x32b0
jmp 0x5662
movq 0x7994(%rip), %rax      # 0xcfc8
movq (%rax), %rdi
movq 0x7c02(%rip), %rdx      # 0xd240
jmp 0x5651
movq 0x7981(%rip), %rax      # 0xcfc8
movq (%rax), %rdi
movq 0x7bdf(%rip), %rdx      # 0xd230
leaq 0x2f6e(%rip), %rsi      # 0x85c6
xorl %eax, %eax
callq 0x3290
pushq $-0x1
popq %rbx
movq -0x30(%rbp), %r14
movq -0x70(%rbp), %r15
testq %r15, %r15
je 0x5686
addq $-0x8, %r14
shlq $0x6, %r15
leaq (%r14,%r15), %rdi
callq 0x644a
addq $-0x10, %r15
jne 0x5677
movq -0xf8(%rbp), %rsp
movl %ebx, %eax
leaq -0x28(%rbp), %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x56b8
jmp 0x56b8
jmp 0x56b8
jmp 0x56b8
jmp 0x56b8
jmp 0x56b8
jmp 0x56b8
jmp 0x56b8
jmp 0x56b8
jmp 0x56b8
jmp 0x56b8
jmp 0x56b8
jmp 0x56b8
movq %rax, %rbx
movq -0x30(%rbp), %r15
cmpq $0x0, -0x70(%rbp)
je 0x56d9
addq $-0x8, %r15
leaq (%r15,%r14), %rdi
callq 0x644a
addq $-0x10, %r14
jne 0x56ca
movq %rbx, %rdi
callq 0x3330