// File: Luthaf[P]zeopp/channel.cc
// Function: PORE::getRestrictingDiameters(int, std::vector<int, std::allocator<int>>, std::vector<std::vector<double, std::allocator<double>>, std::allocator<std::vector<double, std::allocator<double>>>>*, std::vector<std::vector<std::pair<int, int>, std::allocator<std::pair<int, int>>>, std::allocator<std::vector<std::pair<int, int>, std::allocator<std::pair<int, int>>>>>*, std::vector<double, std::allocator<double>>*, std::vector<int, std::allocator<int>>*, std::vector<double, std::allocator<double>>*, std::vector<int, std::allocator<int>>*)
void PORE::getRestrictingDiameters(int nSegments, vector<int> vorNetID, vector< vector<double> > *PLDtable, vector< vector< pair<int,int> > > *PLDEdgeTable, 
                                  vector<double> *segmentDi, vector<int> *segmentDiNodeID, vector <double> *segmentDiFinal, vector<int> *segmentDiFinalNodeID){
    //Define three access types
    const int ACCESSED   =  1;
    const int UNKNOWN      = -1;

    // flag that is used to terminate the search
    
    bool node2FoundFlag = false;

    // Make a local copy of nodes vector as it will be modified
    vector<DIJKSTRA_NODE> lnodes = nodes;
    
    // Initialize the unit cell position of each node
    vector<DELTA_POS> directions = vector<DELTA_POS> (lnodes.size(), DELTA_POS(0,0,0));
    
    // Initialize the status of each node as UNKNOWN
    vector<int> accessStatuses = vector<int> (lnodes.size(), UNKNOWN);
    unsigned int nodeIndex = 0;
    
    double di,df;

    if(nSegments < 1){
      cerr << "Number of semgents lower than 1. This function should not be called.\n" << "\n";
      abort();
      };

//debug
//for(unsigned int i=0; i<vorNetID.size();i++) cout << vorNetID[i] << "  ";


    // Need to translate IDs from the original Voronoi network to PORE ids 

    vector <int> PoreNodesSegmentIDs; // will store segment ID for each node in the current PORE

    PoreNodesSegmentIDs.resize(nodes.size(), -1);

    int nSegPresent = 0;
    for(unsigned int i=0; i<nodes.size(); i++)
       {
       int VnodeID = reverseIDMappings.find(i)->second;
       if(vorNetID[VnodeID] >= 0)
         {
         PoreNodesSegmentIDs[i] = vorNetID[VnodeID]; 
         nSegPresent++;
         };

       };

    cout << "Current PORE contains " << nSegPresent << " nodes in predefined segments. Proceeding with Restricting Diameter Calcs\n";

    // Start analysis by accepting all nodes already assigned to segments (segment seed nodes)
    // Store information about largest node pre-assigned to each segment

    for(unsigned int i=0; i<nodes.size(); i++)
       {
       if(PoreNodesSegmentIDs[i] > -1) 
          {
          accessStatuses[i] = ACCESSED;   
          directions[i] = DELTA_POS(0,0,0); // not sure about this line
          
          if(segmentDi->at(PoreNodesSegmentIDs[i]) < nodes.at(i).max_radius*2) 
             {
             segmentDi->at(PoreNodesSegmentIDs[i]) = nodes.at(i).max_radius*2;
             segmentDiNodeID->at(PoreNodesSegmentIDs[i]) = reverseIDMappings.find(i)->second;
             segmentDiFinal->at(PoreNodesSegmentIDs[i]) = segmentDi->at(PoreNodesSegmentIDs[i]);
             };
          };
       };


/* BUG BUG line (1ln) below, it probably clears segmentDiFinal too many times, moving to the above loop */
//    for(int i=0; i<nSegments; i++) segmentDiFinal->at(i) = segmentDi->at(i); // copying current segments into Final
    
/* old stuff to be removed
    // Start analysis for node of id = nodeid
    
    nodeIndex = node1; // node1 is w.r.t pore node index (use PORE reverseMapping to retrieve original node
    
    // accept the initial node
    di=lnodes.at(nodeIndex).max_radius;
    df=lnodes.at(nodeIndex).max_radius;
    
    accessStatuses[nodeIndex] = ACCESSED;
    
    directions[nodeIndex] = DELTA_POS(0,0,0);

 ends old stuff */
    
    compareConnections_ptr = &lnodes;
    HEAP< pair<int,int> > stack(compareConnections);
    
    // loop over all connections and add them to stack
    for(unsigned int n=0;  n<nodes.size(); n++)
      {
      if(accessStatuses[n] == ACCESSED)
        {
        for(unsigned int i=0; i<lnodes[n].connections.size(); i++)
          {
          if(lnodes[n].connections.at(i).max_radius > lnodes.at(lnodes[n].connections.at(i).to).max_radius)
              lnodes[n].connections.at(i).max_radius = lnodes.at(lnodes[n].connections.at(i).to).max_radius;
        
          stack.insert(pair<int,int>(n,i));
          };
        };
      };
    
    stack.reHeapify();

//
// Note: in the following blocks, we probably dont need directions[]
// to be cleaned in the future

    
    while(stack.size() != 0){
        //loop with Dijkstra-like propagation
        
        // select the path with largest opening
        pair<int,int> best = stack.pop();
        
        int best_node = lnodes[best.first].connections[best.second].to;
        
        if(accessStatuses[best_node]==UNKNOWN)
        {
            // if the node (best_node) is not assigned to segment, assign it to the current segment (determined by node best.first)
            // check new connections, add to heap or terminane
            
            accessStatuses[best_node] = ACCESSED; 
            directions[best_node] = directions[best.first];
            directions[best_node] = directions[best_node] + (lnodes[best.first].connections.at(best.second).deltaPos);
            PoreNodesSegmentIDs[best_node] = PoreNodesSegmentIDs[best.first];
           
            if(nodes.at(best_node).max_radius * 2 > segmentDiFinal->at(PoreNodesSegmentIDs[best.first])) 
               {   
               segmentDiFinal->at(PoreNodesSegmentIDs[best.first]) = nodes.at(best_node).max_radius * 2; 
               segmentDiFinalNodeID->at(PoreNodesSegmentIDs[best.first]) = reverseIDMappings.find(best_node)->second;
               };

            // going to add new connections to the heap
            for(unsigned int i=0; i<lnodes[best_node].connections.size(); i++)
            {
                if(lnodes[best_node].connections.at(i).max_radius > lnodes.at(lnodes[best_node].connections.at(i).to).max_radius)
                    lnodes[best_node].connections.at(i).max_radius = lnodes.at(lnodes[best_node].connections.at(i).to).max_radius;
                
                if(lnodes[best_node].connections[i].to!=best.first)
                    stack.insert(pair<int,int>(best_node,i));
            };	
//            stack.reHeapify(); 
//            I think reHeapify is not needed as heap.insert ensures proper sorting
        }
        
        else if(accessStatuses[best_node]==ACCESSED){
            //selected connection leads to a node that is already assigned to a segment

            // if it is of different segment, note the destricting diameter
            if(PoreNodesSegmentIDs[best_node] != PoreNodesSegmentIDs[best.first])
              {
              // record the largest resticting diameter between two segments of the same PORE
              double r = lnodes[best.first].connections.at(best.second).max_radius;

//begin debug
//cout << "PLD table size: " << PLDtable->size() << "   " << PLDtable->at(PoreNodesSegmentIDs[best_node]).size() << "\n";
//cout << "PoreNodesSegmentIDs[best_node]= " << PoreNodesSegmentIDs[best_node] << "   PoreNodesSegmentIDs[best.first]= " << PoreNodesSegmentIDs[best.first] << "\n"; 
//              if(PLDtable->size() > PoreNodesSegmentIDs[best_node] + 1 || PLDtable->at(PoreNodesSegmentIDs[best_node]).size() > PoreNodesSegmentIDs[best.first] + 1)
//    {cout << "alarm...\n";
//};
//end debug
              double stored_d = PLDtable->at(PoreNodesSegmentIDs[best_node]).at(PoreNodesSegmentIDs[best.first]);
              if(2*r> stored_d)
                {
                PLDtable->at(PoreNodesSegmentIDs[best_node]).at(PoreNodesSegmentIDs[best.first]) = 2*r;
                PLDtable->at(PoreNodesSegmentIDs[best.first]).at(PoreNodesSegmentIDs[best_node]) = 2*r;
                pair<int,int> p(reverseIDMappings.find(best_node)->second, reverseIDMappings.find(best.first)->second); 
                PLDEdgeTable->at(PoreNodesSegmentIDs[best_node]).at(PoreNodesSegmentIDs[best.first]) = p;
                PLDEdgeTable->at(PoreNodesSegmentIDs[best.first]).at(PoreNodesSegmentIDs[best_node]) = p;
                }else{
                //cerr << "Trying to store smaller diameter than already stored. This shouldnt happen. Check the code\n";
                };              
              } else
              {
              // both nodes are of the same segment, do nothing

              };
            
           /* old stuff, probably to be removed  
            if(!(directions[best_node]).equals(directions[best.first] + lnodes[best.first].connections.at(best.second).deltaPos))
            {
                // if nodes are in different unit cells (a loop is found); just update df and continue 
                if(df>nodes[best.first].connections.at(best.second).max_radius) df=nodes[best.first].connections.at(best.second).max_radius;
            };
           */
        }
        
        else{
            //
            // need this section ?
            //
        };
        
    };
   
   for(int i=0; i<nSegments; i++)
     {
     if(segmentDi->at(i)!=segmentDiFinal->at(i)) cerr << "Segment Di(" << segmentDi->at(i) << ") is different than Segment Di Final (" << segmentDiFinal->at(i) << ") for segment " << i << ".\n";
     };  

}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x510, %rsp            # imm = 0x510
movq %rdx, -0x1d8(%rbp)
movq 0x20(%rbp), %rax
movq 0x18(%rbp), %rax
movq 0x10(%rbp), %rax
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
movq %r9, -0x30(%rbp)
movq -0x8(%rbp), %rsi
movq %rsi, -0x1d0(%rbp)
movl $0x1, -0x34(%rbp)
movl $0xffffffff, -0x38(%rbp) # imm = 0xFFFFFFFF
movb $0x0, -0x39(%rbp)
addq $0x60, %rsi
leaq -0x58(%rbp), %rdi
movq %rdi, -0x1c8(%rbp)
callq 0x67230
movq -0x1c8(%rbp), %rdi
callq 0x10100
movq %rax, -0x1c0(%rbp)
leaq -0x7c(%rbp), %rdi
xorl %ecx, %ecx
movl %ecx, %esi
movl %ecx, %edx
callq 0x94010
jmp 0xcbd1a
leaq -0x8d(%rbp), %rdi
movq %rdi, -0x1e0(%rbp)
callq 0x65af0
movq -0x1c0(%rbp), %rsi
movq -0x1e0(%rbp), %rcx
leaq -0x70(%rbp), %rdi
leaq -0x7c(%rbp), %rdx
callq 0xce390
jmp 0xcbd4a
leaq -0x8d(%rbp), %rdi
callq 0x14e70
leaq -0x58(%rbp), %rdi
callq 0x10100
movq %rax, -0x1f0(%rbp)
leaq -0xa9(%rbp), %rdi
movq %rdi, -0x1e8(%rbp)
callq 0x10960
movq -0x1f0(%rbp), %rsi
movq -0x1e8(%rbp), %rcx
leaq -0xa8(%rbp), %rdi
leaq -0x38(%rbp), %rdx
callq 0x65a70
jmp 0xcbd99
leaq -0xa9(%rbp), %rdi
callq 0x13030
movl $0x0, -0xb0(%rbp)
cmpl $0x1, -0xc(%rbp)
jge 0xcbe63
movq 0x1a7230(%rip), %rdi    # 0x272ff0
leaq 0x12f9f0(%rip), %rsi    # 0x1fb7b7
callq 0x5540
movq %rax, -0x1f8(%rbp)
jmp 0xcbdd5
movq -0x1f8(%rbp), %rdi
leaq 0x12d842(%rip), %rsi    # 0x1f9625
callq 0x5540
jmp 0xcbdea
callq 0x52b0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
jmp 0xcd0ed
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
leaq -0x8d(%rbp), %rdi
callq 0x14e70
jmp 0xcd0ed
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
leaq -0xa9(%rbp), %rdi
callq 0x13030
jmp 0xcd0e4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
jmp 0xcd0d8
leaq -0xd8(%rbp), %rdi
movq %rdi, -0x200(%rbp)
callq 0xd0d0
movq -0x1d0(%rbp), %rdi
addq $0x60, %rdi
callq 0x10100
movq -0x200(%rbp), %rdi
movq %rax, %rsi
movl $0xffffffff, -0xdc(%rbp) # imm = 0xFFFFFFFF
leaq -0xdc(%rbp), %rdx
callq 0x84b00
jmp 0xcbea8
movl $0x0, -0xe0(%rbp)
movl $0x0, -0xe4(%rbp)
movq -0x1d0(%rbp), %rdi
movl -0xe4(%rbp), %eax
movq %rax, -0x208(%rbp)
addq $0x60, %rdi
callq 0x10100
movq %rax, %rcx
movq -0x208(%rbp), %rax
cmpq %rcx, %rax
jae 0xcbfc8
movq -0x1d0(%rbp), %rdi
addq $0x30, %rdi
movl -0xe4(%rbp), %eax
movl %eax, -0xf4(%rbp)
leaq -0xf4(%rbp), %rsi
callq 0x102e0
movq %rax, -0x210(%rbp)
jmp 0xcbf18
movq -0x210(%rbp), %rax
movq %rax, -0xf0(%rbp)
leaq -0xf0(%rbp), %rdi
callq 0x10350
movq -0x1d8(%rbp), %rdi
movl 0x4(%rax), %eax
movl %eax, -0xe8(%rbp)
movslq -0xe8(%rbp), %rsi
callq 0xed60
cmpl $0x0, (%rax)
jl 0xcbfb2
movq -0x1d8(%rbp), %rdi
movslq -0xe8(%rbp), %rsi
callq 0xed60
movl (%rax), %eax
movl %eax, -0x214(%rbp)
movl -0xe4(%rbp), %eax
movl %eax, %esi
leaq -0xd8(%rbp), %rdi
callq 0xed60
movl -0x214(%rbp), %ecx
movl %ecx, (%rax)
movl -0xe0(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xe0(%rbp)
jmp 0xcbfb2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
jmp 0xcd0cc
jmp 0xcbfb4
movl -0xe4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xe4(%rbp)
jmp 0xcbebc
movq 0x1a6ff1(%rip), %rdi    # 0x272fc0
leaq 0x12f827(%rip), %rsi    # 0x1fb7fd
callq 0x5540
movq %rax, -0x220(%rbp)
jmp 0xcbfe4
movq -0x220(%rbp), %rdi
movl -0xe0(%rbp), %esi
callq 0x58d0
movq %rax, -0x228(%rbp)
jmp 0xcbfff
movq -0x228(%rbp), %rdi
leaq 0x12f807(%rip), %rsi    # 0x1fb814
callq 0x5540
jmp 0xcc014
movl $0x0, -0xf8(%rbp)
movq -0x1d0(%rbp), %rdi
movl -0xf8(%rbp), %eax
movq %rax, -0x230(%rbp)
addq $0x60, %rdi
callq 0x10100
movq %rax, %rcx
movq -0x230(%rbp), %rax
cmpq %rcx, %rax
jae 0xcc312
movl -0xf8(%rbp), %eax
movl %eax, %esi
leaq -0xd8(%rbp), %rdi
callq 0xed60
cmpl $-0x1, (%rax)
jle 0xcc2fc
movl -0xf8(%rbp), %eax
movl %eax, %esi
leaq -0xa8(%rbp), %rdi
callq 0xed60
movl $0x1, (%rax)
leaq -0x104(%rbp), %rdi
xorl %ecx, %ecx
movl %ecx, %esi
movl %ecx, %edx
callq 0x94010
jmp 0xcc099
movl -0xf8(%rbp), %eax
movl %eax, %esi
leaq -0x70(%rbp), %rdi
callq 0x658f0
movl -0xfc(%rbp), %ecx
movl %ecx, 0x8(%rax)
movq -0x104(%rbp), %rcx
movq %rcx, (%rax)
movq -0x30(%rbp), %rax
movq %rax, -0x240(%rbp)
movl -0xf8(%rbp), %eax
movl %eax, %esi
leaq -0xd8(%rbp), %rdi
callq 0xed60
movq -0x240(%rbp), %rdi
movslq (%rax), %rsi
callq 0xfc80
movq %rax, -0x238(%rbp)
jmp 0xcc0f4
movq -0x1d0(%rbp), %rdi
movq -0x238(%rbp), %rax
movsd (%rax), %xmm0
movsd %xmm0, -0x250(%rbp)
addq $0x60, %rdi
movl -0xf8(%rbp), %eax
movl %eax, %esi
callq 0x10130
movq %rax, -0x248(%rbp)
jmp 0xcc128
movsd -0x250(%rbp), %xmm1
movq -0x248(%rbp), %rax
movsd 0x125f09(%rip), %xmm0   # 0x1f2048
mulsd 0x38(%rax), %xmm0
ucomisd %xmm1, %xmm0
jbe 0xcc2fa
movq -0x1d0(%rbp), %rdi
addq $0x60, %rdi
movl -0xf8(%rbp), %eax
movl %eax, %esi
callq 0x10130
movq %rax, -0x258(%rbp)
jmp 0xcc16f
movq -0x258(%rbp), %rax
movsd 0x38(%rax), %xmm0
addsd %xmm0, %xmm0
movsd %xmm0, -0x270(%rbp)
movq -0x30(%rbp), %rax
movq %rax, -0x268(%rbp)
movl -0xf8(%rbp), %eax
movl %eax, %esi
leaq -0xd8(%rbp), %rdi
callq 0xed60
movq -0x268(%rbp), %rdi
movslq (%rax), %rsi
callq 0xfc80
movq %rax, -0x260(%rbp)
jmp 0xcc1be
movq -0x1d0(%rbp), %rdi
movq -0x260(%rbp), %rax
movsd -0x270(%rbp), %xmm0
movsd %xmm0, (%rax)
addq $0x30, %rdi
movl -0xf8(%rbp), %eax
movl %eax, -0x114(%rbp)
leaq -0x114(%rbp), %rsi
callq 0x102e0
movq %rax, -0x278(%rbp)
jmp 0xcc1fd
movq -0x278(%rbp), %rax
movq %rax, -0x110(%rbp)
leaq -0x110(%rbp), %rdi
callq 0x10350
movl 0x4(%rax), %eax
movl %eax, -0x28c(%rbp)
movq 0x10(%rbp), %rax
movq %rax, -0x288(%rbp)
movl -0xf8(%rbp), %eax
movl %eax, %esi
leaq -0xd8(%rbp), %rdi
callq 0xed60
movq -0x288(%rbp), %rdi
movslq (%rax), %rsi
callq 0x101d0
movq %rax, -0x280(%rbp)
jmp 0xcc257
movq -0x280(%rbp), %rax
movl -0x28c(%rbp), %ecx
movl %ecx, (%rax)
movq -0x30(%rbp), %rax
movq %rax, -0x2a0(%rbp)
movl -0xf8(%rbp), %eax
movl %eax, %esi
leaq -0xd8(%rbp), %rdi
callq 0xed60
movq -0x2a0(%rbp), %rdi
movslq (%rax), %rsi
callq 0xfc80
movq %rax, -0x298(%rbp)
jmp 0xcc29d
movq -0x298(%rbp), %rax
movsd (%rax), %xmm0
movsd %xmm0, -0x2b8(%rbp)
movq 0x18(%rbp), %rax
movq %rax, -0x2b0(%rbp)
movl -0xf8(%rbp), %eax
movl %eax, %esi
leaq -0xd8(%rbp), %rdi
callq 0xed60
movq -0x2b0(%rbp), %rdi
movslq (%rax), %rsi
callq 0xfc80
movq %rax, -0x2a8(%rbp)
jmp 0xcc2e7
movq -0x2a8(%rbp), %rax
movsd -0x2b8(%rbp), %xmm0
movsd %xmm0, (%rax)
jmp 0xcc2fc
jmp 0xcc2fe
movl -0xf8(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xf8(%rbp)
jmp 0xcc01e
leaq -0x58(%rbp), %rax
movq %rax, 0x1a7523(%rip)    # 0x273840
leaq -0x1474(%rip), %rsi     # 0xcaeb0
leaq -0x138(%rbp), %rdi
callq 0xce410
jmp 0xcc332
movl $0x0, -0x13c(%rbp)
movq -0x1d0(%rbp), %rdi
movl -0x13c(%rbp), %eax
movq %rax, -0x2c0(%rbp)
addq $0x60, %rdi
callq 0x10100
movq %rax, %rcx
movq -0x2c0(%rbp), %rax
cmpq %rcx, %rax
jae 0xcc59c
movl -0x13c(%rbp), %eax
movl %eax, %esi
leaq -0xa8(%rbp), %rdi
callq 0xed60
cmpl $0x1, (%rax)
jne 0xcc586
movl $0x0, -0x140(%rbp)
movl -0x140(%rbp), %eax
movq %rax, -0x2c8(%rbp)
movl -0x13c(%rbp), %eax
movl %eax, %esi
leaq -0x58(%rbp), %rdi
callq 0x2a4c0
movq %rax, %rdi
addq $0x20, %rdi
callq 0x2a9e0
movq %rax, %rcx
movq -0x2c8(%rbp), %rax
cmpq %rcx, %rax
jae 0xcc584
movl -0x13c(%rbp), %eax
movl %eax, %esi
leaq -0x58(%rbp), %rdi
callq 0x2a4c0
movq %rax, %rdi
addq $0x20, %rdi
movl -0x140(%rbp), %eax
movl %eax, %esi
callq 0x64470
movq %rax, -0x2d0(%rbp)
jmp 0xcc3fe
movq -0x2d0(%rbp), %rax
movsd 0x10(%rax), %xmm0
movsd %xmm0, -0x2e0(%rbp)
movl -0x13c(%rbp), %eax
movl %eax, %esi
leaq -0x58(%rbp), %rdi
callq 0x2a4c0
movq %rax, %rdi
addq $0x20, %rdi
movl -0x140(%rbp), %eax
movl %eax, %esi
callq 0x64470
movq %rax, -0x2d8(%rbp)
jmp 0xcc440
movq -0x2d8(%rbp), %rax
movslq 0x4(%rax), %rsi
leaq -0x58(%rbp), %rdi
callq 0x10130
movq %rax, -0x2e8(%rbp)
jmp 0xcc45d
movsd -0x2e0(%rbp), %xmm0
movq -0x2e8(%rbp), %rax
ucomisd 0x38(%rax), %xmm0
jbe 0xcc53d
movl -0x13c(%rbp), %eax
movl %eax, %esi
leaq -0x58(%rbp), %rdi
callq 0x2a4c0
movq %rax, %rdi
addq $0x20, %rdi
movl -0x140(%rbp), %eax
movl %eax, %esi
callq 0x64470
movq %rax, -0x2f0(%rbp)
jmp 0xcc4a5
movq -0x2f0(%rbp), %rax
movslq 0x4(%rax), %rsi
leaq -0x58(%rbp), %rdi
callq 0x10130
movq %rax, -0x2f8(%rbp)
jmp 0xcc4c2
movq -0x2f8(%rbp), %rax
movsd 0x38(%rax), %xmm0
movsd %xmm0, -0x308(%rbp)
movl -0x13c(%rbp), %eax
movl %eax, %esi
leaq -0x58(%rbp), %rdi
callq 0x2a4c0
movq %rax, %rdi
addq $0x20, %rdi
movl -0x140(%rbp), %eax
movl %eax, %esi
callq 0x64470
movq %rax, -0x300(%rbp)
jmp 0xcc504
movq -0x300(%rbp), %rax
movsd -0x308(%rbp), %xmm0
movsd %xmm0, 0x10(%rax)
jmp 0xcc53d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
leaq -0x138(%rbp), %rdi
callq 0xce5b0
jmp 0xcd0cc
leaq -0x148(%rbp), %rdi
leaq -0x13c(%rbp), %rsi
leaq -0x140(%rbp), %rdx
callq 0x103a0
jmp 0xcc559
movq -0x148(%rbp), %rsi
leaq -0x138(%rbp), %rdi
callq 0xce470
jmp 0xcc56e
jmp 0xcc570
movl -0x140(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x140(%rbp)
jmp 0xcc393
jmp 0xcc586
jmp 0xcc588
movl -0x13c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x13c(%rbp)
jmp 0xcc33c
leaq -0x138(%rbp), %rdi
callq 0xce4d0
jmp 0xcc5aa
jmp 0xcc5ac
leaq -0x138(%rbp), %rdi
callq 0xce520
movl %eax, -0x30c(%rbp)
jmp 0xcc5c0
movl -0x30c(%rbp), %eax
cmpl $0x0, %eax
je 0xccf05
leaq -0x138(%rbp), %rdi
callq 0xce540
movq %rax, -0x318(%rbp)
jmp 0xcc5e4
movq -0x318(%rbp), %rax
movq %rax, -0x150(%rbp)
movslq -0x150(%rbp), %rsi
leaq -0x58(%rbp), %rdi
callq 0x2a4c0
movq %rax, %rdi
addq $0x20, %rdi
movslq -0x14c(%rbp), %rsi
callq 0x69220
movl 0x4(%rax), %eax
movl %eax, -0x154(%rbp)
movslq -0x154(%rbp), %rsi
leaq -0xa8(%rbp), %rdi
callq 0xed60
cmpl $-0x1, (%rax)
jne 0xccb2e
movslq -0x154(%rbp), %rsi
leaq -0xa8(%rbp), %rdi
callq 0xed60
movl $0x1, (%rax)
movslq -0x150(%rbp), %rsi
leaq -0x70(%rbp), %rdi
movq %rdi, -0x330(%rbp)
callq 0x658f0
movq -0x330(%rbp), %rdi
movq %rax, -0x338(%rbp)
movslq -0x154(%rbp), %rsi
callq 0x658f0
movq -0x338(%rbp), %rcx
movq -0x330(%rbp), %rdi
movl 0x8(%rcx), %edx
movl %edx, 0x8(%rax)
movq (%rcx), %rcx
movq %rcx, (%rax)
movslq -0x154(%rbp), %rsi
callq 0x658f0
movq %rax, -0x328(%rbp)
movslq -0x150(%rbp), %rsi
leaq -0x58(%rbp), %rdi
callq 0x2a4c0
movq %rax, %rdi
addq $0x20, %rdi
movslq -0x14c(%rbp), %rsi
callq 0x64470
movq %rax, -0x320(%rbp)
jmp 0xcc6dd
movq -0x328(%rbp), %rdi
movq -0x320(%rbp), %rsi
addq $0x18, %rsi
callq 0x94150
movl %edx, -0x344(%rbp)
movq %rax, -0x340(%rbp)
jmp 0xcc703
movl -0x344(%rbp), %eax
movq -0x340(%rbp), %rcx
movq %rcx, -0x170(%rbp)
movl %eax, -0x168(%rbp)
movl -0x168(%rbp), %eax
movl %eax, -0x158(%rbp)
movq -0x170(%rbp), %rax
movq %rax, -0x160(%rbp)
movslq -0x154(%rbp), %rsi
leaq -0x70(%rbp), %rdi
callq 0x658f0
movl -0x158(%rbp), %ecx
movl %ecx, 0x8(%rax)
movq -0x160(%rbp), %rcx
movq %rcx, (%rax)
movslq -0x150(%rbp), %rsi
leaq -0xd8(%rbp), %rdi
movq %rdi, -0x360(%rbp)
callq 0xed60
movq -0x360(%rbp), %rdi
movl (%rax), %eax
movl %eax, -0x354(%rbp)
movslq -0x154(%rbp), %rsi
callq 0xed60
movl -0x354(%rbp), %ecx
movq -0x1d0(%rbp), %rdi
movl %ecx, (%rax)
addq $0x60, %rdi
movslq -0x154(%rbp), %rsi
callq 0x10130
movq %rax, -0x350(%rbp)
jmp 0xcc7b7
movq -0x350(%rbp), %rax
movsd 0x38(%rax), %xmm0
addsd %xmm0, %xmm0
movsd %xmm0, -0x378(%rbp)
movq 0x18(%rbp), %rax
movq %rax, -0x370(%rbp)
movslq -0x150(%rbp), %rsi
leaq -0xd8(%rbp), %rdi
callq 0xed60
movq -0x370(%rbp), %rdi
movslq (%rax), %rsi
callq 0xfc80
movq %rax, -0x368(%rbp)
jmp 0xcc805
movsd -0x378(%rbp), %xmm0
movq -0x368(%rbp), %rax
ucomisd (%rax), %xmm0
jbe 0xcc927
movq -0x1d0(%rbp), %rdi
addq $0x60, %rdi
movslq -0x154(%rbp), %rsi
callq 0x10130
movq %rax, -0x380(%rbp)
jmp 0xcc83e
movq -0x380(%rbp), %rax
movsd 0x38(%rax), %xmm0
addsd %xmm0, %xmm0
movsd %xmm0, -0x398(%rbp)
movq 0x18(%rbp), %rax
movq %rax, -0x390(%rbp)
movslq -0x150(%rbp), %rsi
leaq -0xd8(%rbp), %rdi
callq 0xed60
movq -0x390(%rbp), %rdi
movslq (%rax), %rsi
callq 0xfc80
movq %rax, -0x388(%rbp)
jmp 0xcc88c
movq -0x1d0(%rbp), %rdi
movq -0x388(%rbp), %rax
movsd -0x398(%rbp), %xmm0
movsd %xmm0, (%rax)
addq $0x30, %rdi
leaq -0x154(%rbp), %rsi
callq 0x102e0
movq %rax, -0x3a0(%rbp)
jmp 0xcc8bf
movq -0x3a0(%rbp), %rax
movq %rax, -0x178(%rbp)
leaq -0x178(%rbp), %rdi
callq 0x10350
movl 0x4(%rax), %eax
movl %eax, -0x3b4(%rbp)
movq 0x20(%rbp), %rax
movq %rax, -0x3b0(%rbp)
movslq -0x150(%rbp), %rsi
leaq -0xd8(%rbp), %rdi
callq 0xed60
movq -0x3b0(%rbp), %rdi
movslq (%rax), %rsi
callq 0x101d0
movq %rax, -0x3a8(%rbp)
jmp 0xcc918
movq -0x3a8(%rbp), %rax
movl -0x3b4(%rbp), %ecx
movl %ecx, (%rax)
movl $0x0, -0x17c(%rbp)
movl -0x17c(%rbp), %eax
movq %rax, -0x3c0(%rbp)
movslq -0x154(%rbp), %rsi
leaq -0x58(%rbp), %rdi
callq 0x2a4c0
movq %rax, %rdi
addq $0x20, %rdi
callq 0x2a9e0
movq %rax, %rcx
movq -0x3c0(%rbp), %rax
cmpq %rcx, %rax
jae 0xccb29
movslq -0x154(%rbp), %rsi
leaq -0x58(%rbp), %rdi
callq 0x2a4c0
movq %rax, %rdi
addq $0x20, %rdi
movl -0x17c(%rbp), %eax
movl %eax, %esi
callq 0x64470
movq %rax, -0x3c8(%rbp)
jmp 0xcc99a
movq -0x3c8(%rbp), %rax
movsd 0x10(%rax), %xmm0
movsd %xmm0, -0x3d8(%rbp)
movslq -0x154(%rbp), %rsi
leaq -0x58(%rbp), %rdi
callq 0x2a4c0
movq %rax, %rdi
addq $0x20, %rdi
movl -0x17c(%rbp), %eax
movl %eax, %esi
callq 0x64470
movq %rax, -0x3d0(%rbp)
jmp 0xcc9db
movq -0x3d0(%rbp), %rax
movslq 0x4(%rax), %rsi
leaq -0x58(%rbp), %rdi
callq 0x10130
movq %rax, -0x3e0(%rbp)
jmp 0xcc9f8
movsd -0x3d8(%rbp), %xmm0
movq -0x3e0(%rbp), %rax
ucomisd 0x38(%rax), %xmm0
jbe 0xccab1
movslq -0x154(%rbp), %rsi
leaq -0x58(%rbp), %rdi
callq 0x2a4c0
movq %rax, %rdi
addq $0x20, %rdi
movl -0x17c(%rbp), %eax
movl %eax, %esi
callq 0x64470
movq %rax, -0x3e8(%rbp)
jmp 0xcca3f
movq -0x3e8(%rbp), %rax
movslq 0x4(%rax), %rsi
leaq -0x58(%rbp), %rdi
callq 0x10130
movq %rax, -0x3f0(%rbp)
jmp 0xcca5c
movq -0x3f0(%rbp), %rax
movsd 0x38(%rax), %xmm0
movsd %xmm0, -0x400(%rbp)
movslq -0x154(%rbp), %rsi
leaq -0x58(%rbp), %rdi
callq 0x2a4c0
movq %rax, %rdi
addq $0x20, %rdi
movl -0x17c(%rbp), %eax
movl %eax, %esi
callq 0x64470
movq %rax, -0x3f8(%rbp)
jmp 0xcca9d
movq -0x3f8(%rbp), %rax
movsd -0x400(%rbp), %xmm0
movsd %xmm0, 0x10(%rax)
movslq -0x154(%rbp), %rsi
leaq -0x58(%rbp), %rdi
callq 0x2a4c0
movq %rax, %rdi
addq $0x20, %rdi
movl -0x17c(%rbp), %eax
movl %eax, %esi
callq 0x69220
movl 0x4(%rax), %eax
cmpl -0x150(%rbp), %eax
je 0xccb13
leaq -0x184(%rbp), %rdi
leaq -0x154(%rbp), %rsi
leaq -0x17c(%rbp), %rdx
callq 0xcd170
jmp 0xccafc
movq -0x184(%rbp), %rsi
leaq -0x138(%rbp), %rdi
callq 0xce470
jmp 0xccb11
jmp 0xccb13
jmp 0xccb15
movl -0x17c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x17c(%rbp)
jmp 0xcc931
jmp 0xccf00
movslq -0x154(%rbp), %rsi
leaq -0xa8(%rbp), %rdi
callq 0xed60
cmpl $0x1, (%rax)
jne 0xccefc
movslq -0x154(%rbp), %rsi
leaq -0xd8(%rbp), %rdi
callq 0xed60
movl (%rax), %eax
movl %eax, -0x404(%rbp)
movslq -0x150(%rbp), %rsi
leaq -0xd8(%rbp), %rdi
callq 0xed60
movq %rax, %rcx
movl -0x404(%rbp), %eax
cmpl (%rcx), %eax
je 0xccef8
movslq -0x150(%rbp), %rsi
leaq -0x58(%rbp), %rdi
callq 0x2a4c0
movq %rax, %rdi
addq $0x20, %rdi
movslq -0x14c(%rbp), %rsi
callq 0x64470
movq %rax, -0x410(%rbp)
jmp 0xccbb5
movq -0x410(%rbp), %rax
movsd 0x10(%rax), %xmm0
movsd %xmm0, -0x190(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0x420(%rbp)
movslq -0x154(%rbp), %rsi
leaq -0xd8(%rbp), %rdi
callq 0xed60
movq -0x420(%rbp), %rdi
movslq (%rax), %rsi
callq 0xce5f0
movq %rax, -0x418(%rbp)
jmp 0xccbff
movslq -0x150(%rbp), %rsi
leaq -0xd8(%rbp), %rdi
callq 0xed60
movq -0x418(%rbp), %rdi
movslq (%rax), %rsi
callq 0xfc80
movq %rax, -0x428(%rbp)
jmp 0xccc2a
movq -0x428(%rbp), %rax
movsd (%rax), %xmm0
movsd %xmm0, -0x198(%rbp)
movsd 0x125403(%rip), %xmm0   # 0x1f2048
mulsd -0x190(%rbp), %xmm0
ucomisd -0x198(%rbp), %xmm0
jbe 0xccef4
movsd -0x190(%rbp), %xmm0
addsd %xmm0, %xmm0
movsd %xmm0, -0x440(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0x438(%rbp)
movslq -0x154(%rbp), %rsi
leaq -0xd8(%rbp), %rdi
callq 0xed60
movq -0x438(%rbp), %rdi
movslq (%rax), %rsi
callq 0xce5f0
movq %rax, -0x430(%rbp)
jmp 0xccca5
movslq -0x150(%rbp), %rsi
leaq -0xd8(%rbp), %rdi
callq 0xed60
movq -0x430(%rbp), %rdi
movslq (%rax), %rsi
callq 0xfc80
movq %rax, -0x448(%rbp)
jmp 0xcccd0
movq -0x448(%rbp), %rax
movsd -0x440(%rbp), %xmm0
movsd %xmm0, (%rax)
movsd -0x190(%rbp), %xmm0
addsd %xmm0, %xmm0
movsd %xmm0, -0x460(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0x458(%rbp)
movslq -0x150(%rbp), %rsi
leaq -0xd8(%rbp), %rdi
callq 0xed60
movq -0x458(%rbp), %rdi
movslq (%rax), %rsi
callq 0xce5f0
movq %rax, -0x450(%rbp)
jmp 0xccd2d
movslq -0x154(%rbp), %rsi
leaq -0xd8(%rbp), %rdi
callq 0xed60
movq -0x450(%rbp), %rdi
movslq (%rax), %rsi
callq 0xfc80
movq %rax, -0x468(%rbp)
jmp 0xccd58
movq -0x1d0(%rbp), %rdi
movq -0x468(%rbp), %rax
movsd -0x460(%rbp), %xmm0
movsd %xmm0, (%rax)
addq $0x30, %rdi
leaq -0x154(%rbp), %rsi
callq 0x102e0
movq %rax, -0x470(%rbp)
jmp 0xccd8b
movq -0x470(%rbp), %rax
movq %rax, -0x1a8(%rbp)
leaq -0x1a8(%rbp), %rdi
callq 0x10350
movq -0x1d0(%rbp), %rdi
addq $0x4, %rax
movq %rax, -0x480(%rbp)
addq $0x30, %rdi
leaq -0x150(%rbp), %rsi
callq 0x102e0
movq %rax, -0x478(%rbp)
jmp 0xccdd0
movq -0x478(%rbp), %rax
movq %rax, -0x1b0(%rbp)
leaq -0x1b0(%rbp), %rdi
callq 0x10350
movq -0x480(%rbp), %rsi
movq %rax, %rdx
addq $0x4, %rdx
leaq -0x1a0(%rbp), %rdi
callq 0xf590
jmp 0xcce06
movq -0x28(%rbp), %rax
movq %rax, -0x490(%rbp)
movslq -0x154(%rbp), %rsi
leaq -0xd8(%rbp), %rdi
callq 0xed60
movq -0x490(%rbp), %rdi
movslq (%rax), %rsi
callq 0xce630
movq %rax, -0x488(%rbp)
jmp 0xcce3c
movslq -0x150(%rbp), %rsi
leaq -0xd8(%rbp), %rdi
callq 0xed60
movq -0x488(%rbp), %rdi
movslq (%rax), %rsi
callq 0xce670
movq %rax, -0x498(%rbp)
jmp 0xcce67
movq -0x498(%rbp), %rdi
leaq -0x1a0(%rbp), %rsi
callq 0xce6b0
jmp 0xcce7c
movq -0x28(%rbp), %rax
movq %rax, -0x4a8(%rbp)
movslq -0x150(%rbp), %rsi
leaq -0xd8(%rbp), %rdi
callq 0xed60
movq -0x4a8(%rbp), %rdi
movslq (%rax), %rsi
callq 0xce630
movq %rax, -0x4a0(%rbp)
jmp 0xcceb2
movslq -0x154(%rbp), %rsi
leaq -0xd8(%rbp), %rdi
callq 0xed60
movq -0x4a0(%rbp), %rdi
movslq (%rax), %rsi
callq 0xce670
movq %rax, -0x4b0(%rbp)
jmp 0xccedd
movq -0x4b0(%rbp), %rdi
leaq -0x1a0(%rbp), %rsi
callq 0xce6b0
jmp 0xccef2
jmp 0xccef6
jmp 0xccef6
jmp 0xccefa
jmp 0xccefa
jmp 0xccefe
jmp 0xccefe
jmp 0xccf00
jmp 0xcc5ac
movl $0x0, -0x1b4(%rbp)
movl -0x1b4(%rbp), %eax
cmpl -0xc(%rbp), %eax
jge 0xcd08d
movq -0x30(%rbp), %rdi
movslq -0x1b4(%rbp), %rsi
callq 0xfc80
movq %rax, -0x4b8(%rbp)
jmp 0xccf37
movq -0x4b8(%rbp), %rax
movsd (%rax), %xmm0
movsd %xmm0, -0x4c8(%rbp)
movq 0x18(%rbp), %rdi
movslq -0x1b4(%rbp), %rsi
callq 0xfc80
movq %rax, -0x4c0(%rbp)
jmp 0xccf63
movsd -0x4c8(%rbp), %xmm0
movq -0x4c0(%rbp), %rax
ucomisd (%rax), %xmm0
jne 0xccf7f
jp 0xccf7f
jmp 0xcd077
movq 0x1a606a(%rip), %rdi    # 0x272ff0
leaq 0x12e8d2(%rip), %rsi    # 0x1fb85f
callq 0x5540
movq %rax, -0x4d0(%rbp)
jmp 0xccf9b
movq -0x30(%rbp), %rdi
movslq -0x1b4(%rbp), %rsi
callq 0xfc80
movq %rax, -0x4d8(%rbp)
jmp 0xccfb4
movq -0x4d0(%rbp), %rdi
movq -0x4d8(%rbp), %rax
movsd (%rax), %xmm0
callq 0x5980
movq %rax, -0x4e0(%rbp)
jmp 0xccfd4
movq -0x4e0(%rbp), %rdi
leaq 0x12e889(%rip), %rsi    # 0x1fb86b
callq 0x5540
movq %rax, -0x4e8(%rbp)
jmp 0xccff0
movq 0x18(%rbp), %rdi
movslq -0x1b4(%rbp), %rsi
callq 0xfc80
movq %rax, -0x4f0(%rbp)
jmp 0xcd009
movq -0x4e8(%rbp), %rdi
movq -0x4f0(%rbp), %rax
movsd (%rax), %xmm0
callq 0x5980
movq %rax, -0x4f8(%rbp)
jmp 0xcd029
movq -0x4f8(%rbp), %rdi
leaq 0x12e85b(%rip), %rsi    # 0x1fb892
callq 0x5540
movq %rax, -0x500(%rbp)
jmp 0xcd045
movq -0x500(%rbp), %rdi
movl -0x1b4(%rbp), %esi
callq 0x58d0
movq %rax, -0x508(%rbp)
jmp 0xcd060
movq -0x508(%rbp), %rdi
leaq 0x13cce3(%rip), %rsi    # 0x209d51
callq 0x5540
jmp 0xcd075
jmp 0xcd077
jmp 0xcd079
movl -0x1b4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1b4(%rbp)
jmp 0xccf0f
leaq -0x138(%rbp), %rdi
callq 0xce5b0
leaq -0xd8(%rbp), %rdi
callq 0xec80
leaq -0xa8(%rbp), %rdi
callq 0xec80
leaq -0x70(%rbp), %rdi
callq 0x14c80
leaq -0x58(%rbp), %rdi
callq 0x10e40
addq $0x510, %rsp            # imm = 0x510
popq %rbp
retq
leaq -0xd8(%rbp), %rdi
callq 0xec80
leaq -0xa8(%rbp), %rdi
callq 0xec80
leaq -0x70(%rbp), %rdi
callq 0x14c80
leaq -0x58(%rbp), %rdi
callq 0x10e40
movq -0x88(%rbp), %rdi
callq 0x58f0
nopw %cs:(%rax,%rax)
nopl (%rax)