// File: Luthaf[P]zeopp/networkanalysis.cc
// Function: identifyCages(ATOM_NETWORK*, VORONOI_NETWORK*, DIJKSTRA_NETWORK*, double, bool, std::basic_fstream<char, std::char_traits<char>>&, std::vector<CAGE, std::allocator<CAGE>>&)
void identifyCages(ATOM_NETWORK *atmnet, VORONOI_NETWORK *vornet, DIJKSTRA_NETWORK *dnet, double probeRadius, bool visualize, fstream &output, vector<CAGE> &cages) {
  vector<bool> nodeProcessed = vector<bool>(dnet->nodes.size(), false);
  vector<double> bestRadii   = vector<double>(dnet->nodes.size(), -1);
  unsigned int nodeIndex = 0;

  double maxRadius = 0.0;
  DELTA_POS filter(1,1,1);

  // Iterate over all nodes
  while(nodeIndex < nodeProcessed.size()){
   
    // Place starting node on stack with (0,0,0) displacement
    DELTA_POS displacement(0,0,0);
    map<int, pair<DELTA_POS, double> > visitedNodes;
    
    HEAP<pair<int, pair<DELTA_POS, double> > > heap (betterPath);
    heap.insert(pair<int, pair<DELTA_POS, double> > (nodeIndex, pair<DELTA_POS, double> (displacement, dnet->nodes[nodeIndex].max_radius)));
  
    while(heap.size() != 0){
      // Remove best remaining path
      pair<int, pair<DELTA_POS, double> > pathInfo = heap.pop();
      map<int, pair<DELTA_POS, double> >::iterator nodeInfo = visitedNodes.find(pathInfo.first);
      
      // Ending on a preprocessed node
      if(pathInfo.first == -1){
	bestRadii[nodeIndex] = pathInfo.second.second;
	break;
      }

      if(nodeInfo != visitedNodes.end()){
	if(nodeInfo->second.first.equals(pathInfo.second.first)){
	  // Circling back to previous node so terminate path
	  continue;
	}
	else {
	  // Found the optimal path through the start node
	  bestRadii[nodeIndex] = min(pathInfo.second.second, nodeInfo->second.second);
	  maxRadius = max(maxRadius, bestRadii[nodeIndex]);
	  break;
	}
      }
      else{
	visitedNodes.insert(pathInfo);
	DIJKSTRA_NODE currentNode = dnet->nodes[pathInfo.first];
	vector<CONN>::iterator connIter = currentNode.connections.begin();
	// Follow all edges leading to adjoining nodes
      
	while(connIter != currentNode.connections.end()){
	  int to = connIter->to;
	  if(nodeProcessed[to]){
	    // Know the best radii for this path because the next node has already been processed
	    // Change the path's node id to -1 to denote this
	    heap.insert(pair<int, pair<DELTA_POS, double> > (-1, pair<DELTA_POS, double> (DELTA_POS(0,0,0), min(connIter->max_radius, min(pathInfo.second.second, bestRadii[to])))));
	  }
	  else{
	    DELTA_POS newDisplacement = pathInfo.second.first + (connIter->deltaPos*filter);
	    heap.insert(pair<int, pair<DELTA_POS, double> > (to, pair<DELTA_POS, double> (newDisplacement, 
											  min(dnet->nodes[to].max_radius, min(pathInfo.second.second, connIter->max_radius)))));
	  }
	  connIter++;
	}
      }
    }
    nodeProcessed[nodeIndex] = true;
    nodeIndex++;
  }

  double CUTOFF_RATIO = 0.8; 

  // Identify nodes that satisfy cage criteria
  set<int> cageElements;
  for(unsigned int i = 0; i < vornet->nodes.size(); i++){
    double ratio = bestRadii[i]/(dnet->nodes[i].max_radius);
    if(ratio < CUTOFF_RATIO && bestRadii[i] > probeRadius) {
      cageElements.insert(i);
    }
  }
  
  // Calculate node overlaps
  vector< vector<double> > overlapFractions = calculateNodeOverlap(atmnet, vornet);

  // Cluster nodes in cages
  vector< set<int> > clusters = clusterElements(cageElements, overlapFractions, 0.1);


  //vector<CAGE> cages;
  for(unsigned int i = 0; i < clusters.size(); i++){
    cages.push_back(CAGE(clusters[i], atmnet, vornet));
  }

  if(visualize){
    output << "set num_cages " << clusters.size() << "\n";
    for(unsigned int i = 0; i < cages.size(); i++){
      cages[i].writeToVMD(i, output);
    }
  }
  else{
    vector<double> cageRadii;
    for(unsigned int i = 0; i < cages.size(); i++){
      cageRadii.push_back(cages[i].getRadius());
    }

     sort(cageRadii.begin(), cageRadii.end());
    
    vector<int> counts;
    vector<double> radii;
    double prevRad = -1, tolerance = 0.001;
    int numCageTypes = 0;
    for(unsigned int i = 0; i < cageRadii.size(); i++){
      if(abs(cageRadii[i] - prevRad) < tolerance)
	counts[numCageTypes - 1]++;
      else{
	counts.push_back(1); radii.push_back(cageRadii[i]);
	prevRad = cageRadii[i];	numCageTypes++;
      }
    }

    double totalCageAV = 0;
    output << "Note: Probe radius is subtracted from cage radius" << "\n";
    for(unsigned int i = 0; i < counts.size(); i++){
      output << counts[i] << " cage(s) of radius " << radii[i] - probeRadius << "\n";
      totalCageAV += calcSphereVolume(radii[i] - probeRadius)*counts[i];
    }
    output << "Total Cage AV: " << totalCageAV << " A^3" << "\n";
    double volumeFraction = totalCageAV/calcDeterminant(atmnet->ucVectors);
    double rho_crystal    = calcDensity(atmnet);
    double cageAVPerMass  = volumeFraction/rho_crystal;
    output << "Total Cage AV/Mass: " << cageAVPerMass << " cm^3/g" <<  "\n";
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x750, %rsp            # imm = 0x750
movb %cl, %al
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movsd %xmm0, -0x20(%rbp)
andb $0x1, %al
movb %al, -0x21(%rbp)
movq %r8, -0x30(%rbp)
movq %r9, -0x38(%rbp)
movq -0x18(%rbp), %rdi
callq 0x10100
movq %rax, -0x548(%rbp)
movb $0x0, -0x61(%rbp)
leaq -0x62(%rbp), %rdi
movq %rdi, -0x540(%rbp)
callq 0x64b50
movq -0x548(%rbp), %rsi
movq -0x540(%rbp), %rcx
leaq -0x60(%rbp), %rdi
leaq -0x61(%rbp), %rdx
callq 0x64b70
jmp 0x620bc
leaq -0x62(%rbp), %rdi
callq 0x64bf0
movq -0x18(%rbp), %rdi
callq 0x10100
movq %rax, -0x558(%rbp)
movabsq $-0x4010000000000000, %rax # imm = 0xBFF0000000000000
movq %rax, -0x98(%rbp)
leaq -0x99(%rbp), %rdi
movq %rdi, -0x550(%rbp)
callq 0x10b20
movq -0x558(%rbp), %rsi
movq -0x550(%rbp), %rcx
leaq -0x90(%rbp), %rdi
leaq -0x98(%rbp), %rdx
callq 0x64ff0
jmp 0x6211c
leaq -0x99(%rbp), %rdi
callq 0x1ebe0
movl $0x0, -0xa0(%rbp)
movq $0x0, -0xa8(%rbp)
leaq -0xb4(%rbp), %rdi
movl $0x1, %ecx
movl %ecx, %esi
movl %ecx, %edx
callq 0x94010
jmp 0x62154
jmp 0x62156
movl -0xa0(%rbp), %eax
movq %rax, -0x560(%rbp)
leaq -0x60(%rbp), %rdi
callq 0x27d50
movq %rax, %rcx
movq -0x560(%rbp), %rax
cmpq %rcx, %rax
jae 0x628f4
leaq -0xc0(%rbp), %rdi
xorl %ecx, %ecx
movl %ecx, %esi
movl %ecx, %edx
callq 0x94010
jmp 0x62193
leaq -0xf0(%rbp), %rdi
callq 0x65070
leaq -0x2356(%rip), %rsi     # 0x5fe50
leaq -0x110(%rbp), %rdi
callq 0x65090
jmp 0x621b4
movq -0x18(%rbp), %rdi
movl -0xa0(%rbp), %eax
movl %eax, %esi
callq 0x2a4c0
movq %rax, %rdx
addq $0x38, %rdx
leaq -0x148(%rbp), %rdi
leaq -0xc0(%rbp), %rsi
callq 0x65150
jmp 0x621e1
leaq -0x130(%rbp), %rdi
leaq -0xa0(%rbp), %rsi
leaq -0x148(%rbp), %rdx
callq 0x65190
jmp 0x621fd
movups -0x130(%rbp), %xmm0
movups -0x120(%rbp), %xmm1
movq %rsp, %rax
movups %xmm1, 0x10(%rax)
movups %xmm0, (%rax)
leaq -0x110(%rbp), %rdi
callq 0x650f0
jmp 0x62223
jmp 0x62225
leaq -0x110(%rbp), %rdi
callq 0x651d0
movl %eax, -0x564(%rbp)
jmp 0x62239
movl -0x564(%rbp), %eax
cmpl $0x0, %eax
je 0x6285d
leaq -0x168(%rbp), %rdi
leaq -0x110(%rbp), %rsi
callq 0x651f0
jmp 0x6225d
leaq -0xf0(%rbp), %rdi
leaq -0x168(%rbp), %rsi
callq 0x65280
movq %rax, -0x570(%rbp)
jmp 0x62279
movq -0x570(%rbp), %rax
movq %rax, -0x170(%rbp)
cmpl $-0x1, -0x168(%rbp)
jne 0x62333
movsd -0x150(%rbp), %xmm0
movsd %xmm0, -0x578(%rbp)
movl -0xa0(%rbp), %eax
movl %eax, %esi
leaq -0x90(%rbp), %rdi
callq 0xedb0
movsd -0x578(%rbp), %xmm0
movsd %xmm0, (%rax)
jmp 0x6285d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0x62(%rbp), %rdi
callq 0x64bf0
jmp 0x632d4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0x99(%rbp), %rdi
callq 0x1ebe0
jmp 0x632cb
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0x632bf
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0x628e3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0x628d7
leaq -0xf0(%rbp), %rdi
callq 0x652e0
movq %rax, -0x178(%rbp)
leaq -0x170(%rbp), %rdi
leaq -0x178(%rbp), %rsi
callq 0x652b0
testb $0x1, %al
jne 0x62362
jmp 0x62488
leaq -0x170(%rbp), %rdi
callq 0x65310
movq %rax, %rdi
addq $0x8, %rdi
movl -0x158(%rbp), %eax
movl %eax, -0x180(%rbp)
movq -0x160(%rbp), %rax
movq %rax, -0x188(%rbp)
movl -0x180(%rbp), %eax
movl %eax, -0x190(%rbp)
movq -0x188(%rbp), %rax
movq %rax, -0x198(%rbp)
movq -0x198(%rbp), %rsi
movl -0x190(%rbp), %edx
callq 0x94040
movb %al, -0x579(%rbp)
jmp 0x623c3
movb -0x579(%rbp), %al
testb $0x1, %al
jne 0x623cf
jmp 0x623d4
jmp 0x62225
leaq -0x150(%rbp), %rax
movq %rax, -0x590(%rbp)
leaq -0x170(%rbp), %rdi
callq 0x65310
movq -0x590(%rbp), %rdi
movq %rax, %rsi
addq $0x18, %rsi
callq 0x64f50
movq %rax, -0x588(%rbp)
jmp 0x6240a
movq -0x588(%rbp), %rax
movsd (%rax), %xmm0
movsd %xmm0, -0x5a8(%rbp)
movl -0xa0(%rbp), %eax
movl %eax, %esi
leaq -0x90(%rbp), %rdi
movq %rdi, -0x5a0(%rbp)
callq 0xedb0
movsd -0x5a8(%rbp), %xmm0
movq -0x5a0(%rbp), %rdi
movsd %xmm0, (%rax)
movl -0xa0(%rbp), %eax
movl %eax, %esi
callq 0xedb0
movq %rax, %rsi
leaq -0xa8(%rbp), %rdi
callq 0x64c70
movq %rax, -0x598(%rbp)
jmp 0x62470
movq -0x598(%rbp), %rax
movsd (%rax), %xmm0
movsd %xmm0, -0xa8(%rbp)
jmp 0x6285d
leaq -0xf0(%rbp), %rdi
leaq -0x168(%rbp), %rsi
callq 0x65330
movb %dl, -0x5b1(%rbp)
movq %rax, -0x5b0(%rbp)
jmp 0x624aa
movb -0x5b1(%rbp), %al
movq -0x5b0(%rbp), %rcx
movq %rcx, -0x1a8(%rbp)
movb %al, -0x1a0(%rbp)
movq -0x18(%rbp), %rdi
movslq -0x168(%rbp), %rsi
callq 0x2a4c0
movq %rax, %rsi
leaq -0x1f0(%rbp), %rdi
callq 0x64400
jmp 0x624e5
leaq -0x1f0(%rbp), %rdi
addq $0x20, %rdi
callq 0x2a8e0
movq %rax, -0x1f8(%rbp)
leaq -0x1f0(%rbp), %rdi
addq $0x20, %rdi
callq 0x2a710
movq %rax, -0x200(%rbp)
leaq -0x1f8(%rbp), %rdi
leaq -0x200(%rbp), %rsi
callq 0x65370
testb $0x1, %al
jne 0x6252f
jmp 0x6284c
leaq -0x1f8(%rbp), %rdi
callq 0x653b0
movl 0x4(%rax), %eax
movl %eax, -0x204(%rbp)
movslq -0x204(%rbp), %rsi
leaq -0x60(%rbp), %rdi
callq 0x29990
movq %rdx, -0x5c8(%rbp)
movq %rax, -0x5c0(%rbp)
jmp 0x62564
movq -0x5c8(%rbp), %rax
movq -0x5c0(%rbp), %rcx
movq %rcx, -0x218(%rbp)
movq %rax, -0x210(%rbp)
leaq -0x218(%rbp), %rdi
callq 0x101a0
testb $0x1, %al
jne 0x62595
jmp 0x6269f
movl $0xffffffff, -0x23c(%rbp) # imm = 0xFFFFFFFF
leaq -0x264(%rbp), %rdi
xorl %ecx, %ecx
movl %ecx, %esi
movl %ecx, %edx
callq 0x94010
jmp 0x625b3
leaq -0x1f8(%rbp), %rdi
callq 0x653b0
addq $0x10, %rax
movq %rax, -0x5e0(%rbp)
leaq -0x150(%rbp), %rax
movq %rax, -0x5d8(%rbp)
movslq -0x204(%rbp), %rsi
leaq -0x90(%rbp), %rdi
callq 0xedb0
movq -0x5d8(%rbp), %rdi
movq %rax, %rsi
callq 0x64f50
movq %rax, -0x5d0(%rbp)
jmp 0x62603
movq -0x5d0(%rbp), %rsi
movq -0x5e0(%rbp), %rdi
callq 0x64f50
movq %rax, -0x5e8(%rbp)
jmp 0x6261f
movq -0x5e8(%rbp), %rdx
leaq -0x258(%rbp), %rdi
leaq -0x264(%rbp), %rsi
callq 0x653d0
jmp 0x6263b
leaq -0x238(%rbp), %rdi
leaq -0x23c(%rbp), %rsi
leaq -0x258(%rbp), %rdx
callq 0x65410
jmp 0x62657
movups -0x238(%rbp), %xmm0
movups -0x228(%rbp), %xmm1
movq %rsp, %rax
movups %xmm1, 0x10(%rax)
movups %xmm0, (%rax)
leaq -0x110(%rbp), %rdi
callq 0x650f0
jmp 0x6267d
jmp 0x62832
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0x1f0(%rbp), %rdi
callq 0x100e0
jmp 0x628d7
leaq -0x160(%rbp), %rax
movq %rax, -0x600(%rbp)
leaq -0x1f8(%rbp), %rdi
callq 0x653b0
movq %rax, %rdi
addq $0x18, %rdi
leaq -0xb4(%rbp), %rsi
callq 0x940f0
movl %edx, -0x5f4(%rbp)
movq %rax, -0x5f0(%rbp)
jmp 0x626db
movq -0x600(%rbp), %rdi
movl -0x5f4(%rbp), %eax
movq -0x5f0(%rbp), %rcx
movq %rcx, -0x290(%rbp)
movl %eax, -0x288(%rbp)
movl -0x288(%rbp), %eax
movl %eax, -0x278(%rbp)
movq -0x290(%rbp), %rax
movq %rax, -0x280(%rbp)
leaq -0x280(%rbp), %rsi
callq 0x94150
movl %edx, -0x60c(%rbp)
movq %rax, -0x608(%rbp)
jmp 0x62731
movl -0x60c(%rbp), %eax
movq -0x608(%rbp), %rcx
movq %rcx, -0x2a0(%rbp)
movl %eax, -0x298(%rbp)
movl -0x298(%rbp), %eax
movl %eax, -0x268(%rbp)
movq -0x2a0(%rbp), %rax
movq %rax, -0x270(%rbp)
movq -0x18(%rbp), %rdi
movslq -0x204(%rbp), %rsi
callq 0x2a4c0
addq $0x38, %rax
movq %rax, -0x628(%rbp)
leaq -0x150(%rbp), %rax
movq %rax, -0x620(%rbp)
leaq -0x1f8(%rbp), %rdi
callq 0x653b0
movq -0x620(%rbp), %rdi
movq %rax, %rsi
addq $0x10, %rsi
callq 0x64f50
movq %rax, -0x618(%rbp)
jmp 0x627b6
movq -0x618(%rbp), %rsi
movq -0x628(%rbp), %rdi
callq 0x64f50
movq %rax, -0x630(%rbp)
jmp 0x627d2
movq -0x630(%rbp), %rdx
leaq -0x2d8(%rbp), %rdi
leaq -0x270(%rbp), %rsi
callq 0x65450
jmp 0x627ee
leaq -0x2c0(%rbp), %rdi
leaq -0x204(%rbp), %rsi
leaq -0x2d8(%rbp), %rdx
callq 0x65490
jmp 0x6280a
movups -0x2c0(%rbp), %xmm0
movups -0x2b0(%rbp), %xmm1
movq %rsp, %rax
movups %xmm1, 0x10(%rax)
movups %xmm0, (%rax)
leaq -0x110(%rbp), %rdi
callq 0x650f0
jmp 0x62830
jmp 0x62832
leaq -0x1f8(%rbp), %rdi
xorl %esi, %esi
callq 0x654d0
movq %rax, -0x2e0(%rbp)
jmp 0x624fc
leaq -0x1f0(%rbp), %rdi
callq 0x100e0
jmp 0x62225
movl -0xa0(%rbp), %eax
movl %eax, %esi
leaq -0x60(%rbp), %rdi
callq 0x29990
movq %rdx, -0x640(%rbp)
movq %rax, -0x638(%rbp)
jmp 0x6287e
movq -0x640(%rbp), %rax
movq -0x638(%rbp), %rcx
movq %rcx, -0x2f0(%rbp)
movq %rax, -0x2e8(%rbp)
leaq -0x2f0(%rbp), %rdi
movl $0x1, %esi
callq 0x10040
movl -0xa0(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xa0(%rbp)
leaq -0x110(%rbp), %rdi
callq 0x65510
leaq -0xf0(%rbp), %rdi
callq 0x65530
jmp 0x62156
leaq -0x110(%rbp), %rdi
callq 0x65510
leaq -0xf0(%rbp), %rdi
callq 0x65530
jmp 0x632bf
movsd 0x193a54(%rip), %xmm0   # 0x1f6350
movsd %xmm0, -0x2f8(%rbp)
leaq -0x328(%rbp), %rdi
callq 0xf690
movl $0x0, -0x32c(%rbp)
movl -0x32c(%rbp), %eax
movq %rax, -0x648(%rbp)
movq -0x10(%rbp), %rdi
addq $0x48, %rdi
callq 0xf270
movq %rax, %rcx
movq -0x648(%rbp), %rax
cmpq %rcx, %rax
jae 0x62a33
movl -0x32c(%rbp), %eax
movl %eax, %esi
leaq -0x90(%rbp), %rdi
callq 0xedb0
movsd (%rax), %xmm0
movsd %xmm0, -0x650(%rbp)
movq -0x18(%rbp), %rdi
movl -0x32c(%rbp), %eax
movl %eax, %esi
callq 0x2a4c0
movsd -0x650(%rbp), %xmm0
divsd 0x38(%rax), %xmm0
movsd %xmm0, -0x338(%rbp)
movsd -0x338(%rbp), %xmm1
movsd -0x2f8(%rbp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x62a1d
movl -0x32c(%rbp), %eax
movl %eax, %esi
leaq -0x90(%rbp), %rdi
callq 0xedb0
movsd (%rax), %xmm0
ucomisd -0x20(%rbp), %xmm0
jbe 0x62a1d
movl -0x32c(%rbp), %eax
movl %eax, -0x33c(%rbp)
leaq -0x328(%rbp), %rdi
leaq -0x33c(%rbp), %rsi
callq 0x65910
movb %dl, -0x659(%rbp)
movq %rax, -0x658(%rbp)
jmp 0x629f0
movb -0x659(%rbp), %al
movq -0x658(%rbp), %rcx
movq %rcx, -0x350(%rbp)
movb %al, -0x348(%rbp)
jmp 0x62a1d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0x632b3
jmp 0x62a1f
movl -0x32c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x32c(%rbp)
jmp 0x6291a
movq -0x8(%rbp), %rsi
movq -0x10(%rbp), %rdx
leaq -0x368(%rbp), %rdi
callq 0x60790
jmp 0x62a49
leaq -0x3b0(%rbp), %rdi
leaq -0x328(%rbp), %rsi
callq 0x1c930
jmp 0x62a5e
leaq -0x3c8(%rbp), %rdi
leaq -0x368(%rbp), %rsi
callq 0x106a0
jmp 0x62a73
leaq -0x380(%rbp), %rdi
leaq -0x3b0(%rbp), %rsi
leaq -0x3c8(%rbp), %rdx
movsd 0x18f5d8(%rip), %xmm0   # 0x1f2068
callq 0x60af0
jmp 0x62a97
leaq -0x3c8(%rbp), %rdi
callq 0x10790
leaq -0x3b0(%rbp), %rdi
callq 0xf880
movl $0x0, -0x3cc(%rbp)
movl -0x3cc(%rbp), %eax
movq %rax, -0x668(%rbp)
leaq -0x380(%rbp), %rdi
callq 0x1c3e0
movq %rax, %rcx
movq -0x668(%rbp), %rax
cmpq %rcx, %rax
jae 0x62c03
movq -0x38(%rbp), %rax
movq %rax, -0x670(%rbp)
movl -0x3cc(%rbp), %eax
movl %eax, %esi
leaq -0x380(%rbp), %rdi
callq 0x65640
movq %rax, %rsi
leaq -0x480(%rbp), %rdi
callq 0x1c930
jmp 0x62b15
movq -0x8(%rbp), %rdx
movq -0x10(%rbp), %rcx
leaq -0x450(%rbp), %rdi
leaq -0x480(%rbp), %rsi
callq 0x61c80
jmp 0x62b32
movq -0x670(%rbp), %rdi
leaq -0x450(%rbp), %rsi
callq 0x65960
jmp 0x62b47
leaq -0x450(%rbp), %rdi
callq 0x65990
leaq -0x480(%rbp), %rdi
callq 0xf880
movl -0x3cc(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3cc(%rbp)
jmp 0x62ab9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0x632a7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0x62baa
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0x3c8(%rbp), %rdi
callq 0x10790
leaq -0x3b0(%rbp), %rdi
callq 0xf880
jmp 0x632a7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0x6329b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0x62bf2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0x450(%rbp), %rdi
callq 0x65990
leaq -0x480(%rbp), %rdi
callq 0xf880
jmp 0x6329b
testb $0x1, -0x21(%rbp)
je 0x62ccf
movq -0x30(%rbp), %rdi
addq $0x10, %rdi
leaq 0x1938e5(%rip), %rsi    # 0x1f6501
callq 0x5540
movq %rax, -0x678(%rbp)
jmp 0x62c2a
leaq -0x380(%rbp), %rdi
callq 0x1c3e0
movq -0x678(%rbp), %rdi
movq %rax, %rsi
callq 0x5160
movq %rax, -0x680(%rbp)
jmp 0x62c4e
movq -0x680(%rbp), %rdi
leaq 0x1969c9(%rip), %rsi    # 0x1f9625
callq 0x5540
jmp 0x62c63
movl $0x0, -0x484(%rbp)
movl -0x484(%rbp), %eax
movq %rax, -0x688(%rbp)
movq -0x38(%rbp), %rdi
callq 0x659d0
movq %rax, %rcx
movq -0x688(%rbp), %rax
cmpq %rcx, %rax
jae 0x62cca
movq -0x38(%rbp), %rdi
movl -0x484(%rbp), %eax
movl %eax, %esi
callq 0x659f0
movq %rax, %rdi
movl -0x484(%rbp), %esi
movq -0x30(%rbp), %rdx
callq 0x61ef0
jmp 0x62cb7
jmp 0x62cb9
movl -0x484(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x484(%rbp)
jmp 0x62c6d
jmp 0x63259
leaq -0x4a0(%rbp), %rdi
callq 0xf650
movl $0x0, -0x4a4(%rbp)
movl -0x4a4(%rbp), %eax
movq %rax, -0x690(%rbp)
movq -0x38(%rbp), %rdi
callq 0x659d0
movq %rax, %rcx
movq -0x690(%rbp), %rax
cmpq %rcx, %rax
jae 0x62d64
movq -0x38(%rbp), %rdi
movl -0x4a4(%rbp), %eax
movl %eax, %esi
callq 0x659f0
movq %rax, %rdi
callq 0x61e60
movsd %xmm0, -0x4b0(%rbp)
leaq -0x4a0(%rbp), %rdi
leaq -0x4b0(%rbp), %rsi
callq 0xf6d0
jmp 0x62d40
jmp 0x62d42
movl -0x4a4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x4a4(%rbp)
jmp 0x62ce5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
jmp 0x6324b
leaq -0x4a0(%rbp), %rdi
movq %rdi, -0x698(%rbp)
callq 0x26bb0
movq -0x698(%rbp), %rdi
movq %rax, -0x4b8(%rbp)
callq 0x269f0
movq %rax, -0x4c0(%rbp)
movq -0x4b8(%rbp), %rdi
movq -0x4c0(%rbp), %rsi
callq 0x65a10
jmp 0x62da6
leaq -0x4d8(%rbp), %rdi
callq 0xd0d0
leaq -0x4f0(%rbp), %rdi
callq 0xf650
movsd 0x18f9b2(%rip), %xmm0   # 0x1f2778
movsd %xmm0, -0x4f8(%rbp)
movsd 0x18f262(%rip), %xmm0   # 0x1f2038
movsd %xmm0, -0x500(%rbp)
movl $0x0, -0x504(%rbp)
movl $0x0, -0x508(%rbp)
movl -0x508(%rbp), %eax
movq %rax, -0x6a0(%rbp)
leaq -0x4a0(%rbp), %rdi
callq 0xf990
movq %rax, %rcx
movq -0x6a0(%rbp), %rax
cmpq %rcx, %rax
jae 0x62f3d
movl -0x508(%rbp), %eax
movl %eax, %esi
leaq -0x4a0(%rbp), %rdi
callq 0xedb0
movsd (%rax), %xmm0
movsd -0x4f8(%rbp), %xmm1
subsd %xmm1, %xmm0
callq 0x162b0
movsd %xmm0, -0x6a8(%rbp)
jmp 0x62e51
movsd -0x6a8(%rbp), %xmm1
movsd -0x500(%rbp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x62eb4
movl -0x504(%rbp), %eax
subl $0x1, %eax
movslq %eax, %rsi
leaq -0x4d8(%rbp), %rdi
callq 0xed60
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
jmp 0x62f27
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x70(%rbp)
movl %eax, -0x74(%rbp)
leaq -0x4f0(%rbp), %rdi
callq 0xf9d0
leaq -0x4d8(%rbp), %rdi
callq 0xec80
jmp 0x6324b
movl $0x1, -0x50c(%rbp)
leaq -0x4d8(%rbp), %rdi
leaq -0x50c(%rbp), %rsi
callq 0xffc0
jmp 0x62ed3
movl -0x508(%rbp), %eax
movl %eax, %esi
leaq -0x4a0(%rbp), %rdi
callq 0xedb0
movq %rax, %rsi
leaq -0x4f0(%rbp), %rdi
callq 0x105c0
jmp 0x62ef8
movl -0x508(%rbp), %eax
movl %eax, %esi
leaq -0x4a0(%rbp), %rdi
callq 0xedb0
movsd (%rax), %xmm0
movsd %xmm0, -0x4f8(%rbp)
movl -0x504(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x504(%rbp)
jmp 0x62f29
movl -0x508(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x508(%rbp)
jmp 0x62df2
movq $0x0, -0x518(%rbp)
movq -0x30(%rbp), %rdi
addq $0x10, %rdi
leaq 0x1935b9(%rip), %rsi    # 0x1f6510
callq 0x5540
movq %rax, -0x6b0(%rbp)
jmp 0x62f65
movq -0x6b0(%rbp), %rdi
leaq 0x1966b2(%rip), %rsi    # 0x1f9625
callq 0x5540
jmp 0x62f7a
movl $0x0, -0x51c(%rbp)
movl -0x51c(%rbp), %eax
movq %rax, -0x6b8(%rbp)
leaq -0x4d8(%rbp), %rdi
callq 0x10090
movq %rax, %rcx
movq -0x6b8(%rbp), %rax
cmpq %rcx, %rax
jae 0x630cd
movq -0x30(%rbp), %rax
addq $0x10, %rax
movq %rax, -0x6c8(%rbp)
movl -0x51c(%rbp), %eax
movl %eax, %esi
leaq -0x4d8(%rbp), %rdi
callq 0xed60
movq -0x6c8(%rbp), %rdi
movl (%rax), %esi
callq 0x58d0
movq %rax, -0x6c0(%rbp)
jmp 0x62fea
movq -0x6c0(%rbp), %rdi
leaq 0x19354a(%rip), %rsi    # 0x1f6542
callq 0x5540
movq %rax, -0x6d0(%rbp)
jmp 0x63006
movl -0x51c(%rbp), %eax
movl %eax, %esi
leaq -0x4f0(%rbp), %rdi
callq 0xedb0
movq -0x6d0(%rbp), %rdi
movsd (%rax), %xmm0
movsd -0x20(%rbp), %xmm1
subsd %xmm1, %xmm0
callq 0x5980
movq %rax, -0x6d8(%rbp)
jmp 0x6303c
movq -0x6d8(%rbp), %rdi
leaq 0x1965db(%rip), %rsi    # 0x1f9625
callq 0x5540
jmp 0x63051
movl -0x51c(%rbp), %eax
movl %eax, %esi
leaq -0x4f0(%rbp), %rdi
callq 0xedb0
movsd (%rax), %xmm0
movsd -0x20(%rbp), %xmm1
subsd %xmm1, %xmm0
callq 0xebac0
movsd %xmm0, -0x6e0(%rbp)
jmp 0x63081
movl -0x51c(%rbp), %eax
movl %eax, %esi
leaq -0x4d8(%rbp), %rdi
callq 0xed60
movsd -0x6e0(%rbp), %xmm0
cvtsi2sdl (%rax), %xmm2
movsd -0x518(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x518(%rbp)
movl -0x51c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x51c(%rbp)
jmp 0x62f84
movq -0x30(%rbp), %rdi
addq $0x10, %rdi
leaq 0x19347a(%rip), %rsi    # 0x1f6556
callq 0x5540
movq %rax, -0x6e8(%rbp)
jmp 0x630ea
movq -0x6e8(%rbp), %rdi
movsd -0x518(%rbp), %xmm0
callq 0x5980
movq %rax, -0x6f0(%rbp)
jmp 0x63107
movq -0x6f0(%rbp), %rdi
leaq 0x193451(%rip), %rsi    # 0x1f6566
callq 0x5540
movq %rax, -0x6f8(%rbp)
jmp 0x63123
movq -0x6f8(%rbp), %rdi
leaq 0x1964f4(%rip), %rsi    # 0x1f9625
callq 0x5540
jmp 0x63138
movsd -0x518(%rbp), %xmm0
movsd %xmm0, -0x708(%rbp)
movq -0x8(%rbp), %rdi
subq $-0x80, %rdi
callq 0xe9390
movsd %xmm0, -0x700(%rbp)
jmp 0x6315f
movsd -0x700(%rbp), %xmm1
movsd -0x708(%rbp), %xmm0
divsd %xmm1, %xmm0
movsd %xmm0, -0x528(%rbp)
movq -0x8(%rbp), %rdi
callq 0x74f60
movsd %xmm0, -0x710(%rbp)
jmp 0x6318e
movsd -0x710(%rbp), %xmm0
movsd %xmm0, -0x530(%rbp)
movsd -0x528(%rbp), %xmm0
movsd -0x530(%rbp), %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, -0x538(%rbp)
movq -0x30(%rbp), %rdi
addq $0x10, %rdi
leaq 0x1933a2(%rip), %rsi    # 0x1f656b
callq 0x5540
movq %rax, -0x718(%rbp)
jmp 0x631d7
movq -0x718(%rbp), %rdi
movsd -0x538(%rbp), %xmm0
callq 0x5980
movq %rax, -0x720(%rbp)
jmp 0x631f4
movq -0x720(%rbp), %rdi
leaq 0x19337e(%rip), %rsi    # 0x1f6580
callq 0x5540
movq %rax, -0x728(%rbp)
jmp 0x63210
movq -0x728(%rbp), %rdi
leaq 0x196407(%rip), %rsi    # 0x1f9625
callq 0x5540
jmp 0x63225
leaq -0x4f0(%rbp), %rdi
callq 0xf9d0
leaq -0x4d8(%rbp), %rdi
callq 0xec80
leaq -0x4a0(%rbp), %rdi
callq 0xf9d0
jmp 0x63259
leaq -0x4a0(%rbp), %rdi
callq 0xf9d0
jmp 0x6329b
leaq -0x380(%rbp), %rdi
callq 0x13b70
leaq -0x368(%rbp), %rdi
callq 0x10790
leaq -0x328(%rbp), %rdi
callq 0xf880
leaq -0x90(%rbp), %rdi
callq 0xf9d0
leaq -0x60(%rbp), %rdi
callq 0xf9b0
addq $0x750, %rsp            # imm = 0x750
popq %rbp
retq
leaq -0x380(%rbp), %rdi
callq 0x13b70
leaq -0x368(%rbp), %rdi
callq 0x10790
leaq -0x328(%rbp), %rdi
callq 0xf880
leaq -0x90(%rbp), %rdi
callq 0xf9d0
leaq -0x60(%rbp), %rdi
callq 0xf9b0
movq -0x70(%rbp), %rdi
callq 0x58f0
nopl (%rax)