// File: Luthaf[P]zeopp/area_and_volume.cc
// Function: blockPockets(ATOM_NETWORK*, std::ostream&, std::vector<Point, std::allocator<Point>>, std::vector<int, std::allocator<int>>, std::vector<Point, std::allocator<Point>>, std::vector<int, std::allocator<int>>, double)
void blockPockets(ATOM_NETWORK *atmnet, ostream &output, vector<Point> axsPoints, vector<int> axsPChIDs, vector<Point> inaxsPoints, vector<int> inaxsPPIDs, double probeRad){
/*
  for(unsigned int i = 0; i < axsPoints.size(); i++){
    Point coords = axsPoints.at(i);
    output << coords[0] << " " << coords[1] << " " << coords[2] << " 1 a " << axsPChIDs[i] << "\n";
   }
*/
/*
  for(unsigned int i = 0; i < inaxsPoints.size(); i++){
    Point coords = inaxsPoints.at(i);
    // print coordinates and pocket ID
    output <<  coords[0] << " " << coords[1] << " " << coords[2] << " 0 block " << inaxsPPIDs[i] << "\n";
  }
*/

  //DESCRIPTION: iterate over each pore ID that corresponds to a pocket, and block all points in that pocket with spheres without blocking any non-pocket points - the spheres are created iteratively, and many spheres may be needed per pocket
  bool debug = false; //prints extra info to terminal, including .xyz format Cartesian pocket info for visualisation
  vector<SPHERE> spheres_vector; //stores blocking spheres we have created below;
  double sphere_radius_overshoot = 0.1; //optional - the amount in A by which a sphere can extend beyond the furthest point to be blocked (so that the sphere does not perfectly intersect the furthest MC point, potentially leaving volume nearby that should have been blocked)

  //1) identify how many pores we have, and which ones are pockets
  int max_pore_ID = 0;
  int num_axsPoints = axsPoints.size();
  int num_inaxsPoints = inaxsPoints.size();
  for(int i=0; i<num_axsPoints; i++) if(axsPChIDs.at(i)>max_pore_ID) max_pore_ID = axsPChIDs.at(i);
  for(int i=0; i<num_inaxsPoints; i++) if(inaxsPPIDs.at(i)>max_pore_ID) max_pore_ID = inaxsPPIDs.at(i);
  int num_pores = max_pore_ID+1;
  vector<bool> is_pocket;
  for(int i=0; i<num_pores; i++) is_pocket.push_back(false);
  for(int i=0; i<num_inaxsPoints; i++) if(!is_pocket.at(inaxsPPIDs.at(i))) is_pocket.at(inaxsPPIDs.at(i)) = true;
  if(debug) {
    printf("DEBUG: there are %d pores and they are assigned to channels and pockets as follows:\n", num_pores);
    for(int i=0; i<num_pores; i++) {
      printf("ID %d: ", i);
      if(is_pocket.at(i)) printf("pocket\n"); else printf("channel\n");
    }
  }

  //2) for each pocket, determine which points are members of this pocket and not already blocked by an earlier sphere (hence the resulting points may not all be connected), and store them all in selected_points
  for(int i=0; i<num_pores; i++) {
    vector<Point> selected_points; //stores to-be-blocked points in this pore
    if(is_pocket.at(i)) { //this pore is a pocket - we are going to block it with spheres
      for(int j=0; j<num_inaxsPoints; j++) {
        if(inaxsPPIDs.at(j)==i) { //inaxs point j is in pore i, so needs to be blocked - if it is not already blocked, push to selected_points vector
          Point p = inaxsPoints.at(j);
          bool already_blocked = false;
          int num_spheres = spheres_vector.size();
					for(int s=0; s<num_spheres && !already_blocked; s++) {
            SPHERE this_sphere = spheres_vector.at(s);
            double dist = atmnet->calcDistanceABC(p[0], p[1], p[2], this_sphere.x, this_sphere.y, this_sphere.z);
						if(dist<this_sphere.r) already_blocked = true;
					}
          if(!already_blocked) selected_points.push_back(p);
        }
      }

      //3) begin a loop - while there are points in selected_points, we need to do more blocking
      int num_selected_points = selected_points.size();
      while(num_selected_points>0) {
        if(debug) printf("DEBUG: there are %d points left to be blocked in pore with ID %d\n", num_selected_points, i);
        int most_dense_index = get_most_dense_index(atmnet, &selected_points);
        Point most_dense = selected_points.at(most_dense_index); //find most dense point in the remaining point cloud
        double closest_channel = -1; //distance to nearest MC point that is in a channel
        for(int j=0; j<num_axsPoints; j++) { //loop over points to be preserved, and find closest
          Point p = axsPoints.at(j);
          double dist = atmnet->calcDistanceABC(p[0], p[1], p[2], most_dense[0], most_dense[1], most_dense[2]);
          if(dist<closest_channel || closest_channel<0) closest_channel=dist;
        }
        double furthest_same_pocket = 0; //distance to furthest MC point that is part of this pore
        vector<double> vector_of_distances_to_sphere_centroid; //keep track of the distance of each to-be-blocked point to the most dense point - it will save us calculating this again later when we check which points were blocked
        for(int j=0; j<num_selected_points; j++) { //loop over points to be blocked, and find furthest
          Point p = selected_points.at(j);
          double dist = atmnet->calcDistanceABC(p[0], p[1], p[2], most_dense[0], most_dense[1], most_dense[2]);
          if(dist>furthest_same_pocket || furthest_same_pocket<0) furthest_same_pocket=dist;
          vector_of_distances_to_sphere_centroid.push_back(dist);
        }

        //4) calculate the largest acceptable sphere at this most dense position
        double radius = 0;
        if(closest_channel<0) radius = furthest_same_pocket + probeRad + sphere_radius_overshoot; //no channels - we can safely have a single sphere, inflated by probeRad to cover the void space here
        else if(furthest_same_pocket<closest_channel) radius = min(furthest_same_pocket + probeRad + sphere_radius_overshoot, closest_channel - (probeRad + sphere_radius_overshoot)); //there are channels, but none are closer than the furthest point in this pocket, so we can extend the sphere to cover everything; try and inflate the sphere by probeRad to ensure the void space is blocked, but not if this would cause anything within probeRad of an accessible MC point to be blocked
        else radius = max(sphere_radius_overshoot, closest_channel - (probeRad + sphere_radius_overshoot)); //else there are channels closer than the furthest pocket MC point, and we have to accommodate them

        //5) create the sphere and remove to-be-blocked points that were blocked by it
        SPHERE new_sphere;
        new_sphere.x = most_dense[0];
        new_sphere.y = most_dense[1];
        new_sphere.z = most_dense[2];
        new_sphere.r = radius;
        spheres_vector.push_back(new_sphere);
        for(int j=num_selected_points-1; j>=0; j--) { //loop over points to be blocked and eliminate blocked ones - we iterate backwards so that the vector of distances is still relevant
          if(vector_of_distances_to_sphere_centroid.at(j)<radius) { //blocked
				    Point swap = selected_points.at(j);
				    selected_points.at(j) = selected_points.at(num_selected_points-1);
				    selected_points.at(num_selected_points-1) = swap;
				    selected_points.pop_back();
				    num_selected_points--; //update counter iteratively
          }
        }
      } //6) end while loop - we have totally blocked this pocket - safe to move on to next pore
    } //7) end if is_pocket - we either ran the blocking part or bypassed this pore
  } //8) end for loop - we have analysed all pores and blocked where necessary
  int num_spheres = spheres_vector.size();
  //9) write to output (directed to .block file)
  if(debug) printf("DEBUG: %d blocking spheres were created, Cartesian positions in xyz format follow, if any\n%d\nXYZ FORMAT CARTESIAN POCKETS FOR VISUALIZATION\n", num_spheres, num_spheres);
  output << num_spheres << "\n";
  for(int i=0; i<num_spheres; i++) {
    SPHERE s = spheres_vector.at(i);
    if(debug) {
      Point f; f[0] = s.x; f[1] = s.y; f[2] = s.z;
      Point c = atmnet->abc_to_xyz(f);
      printf("X %.3f %.3f %.3f %.3f\n", c[0], c[1], c[2], s.r);
    }
    output << s.x << " " << s.y << " " << s.z << " " << s.r << "\n";
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x5d0, %rsp            # imm = 0x5D0
movq %rdx, -0x300(%rbp)
movq %rcx, -0x310(%rbp)
movq %r8, -0x2f8(%rbp)
movq %r9, -0x308(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
movq %r9, -0x30(%rbp)
movsd %xmm0, -0x38(%rbp)
movb $0x0, -0x39(%rbp)
leaq -0x58(%rbp), %rdi
callq 0x852e0
movq -0x300(%rbp), %rdi
movsd 0x178e18(%rip), %xmm0   # 0x1f2068
movsd %xmm0, -0x60(%rbp)
movl $0x0, -0x64(%rbp)
callq 0x17c60
movq -0x2f8(%rbp), %rdi
movl %eax, -0x68(%rbp)
callq 0x17c60
movl %eax, -0x6c(%rbp)
movl $0x0, -0x70(%rbp)
movl -0x70(%rbp), %eax
cmpl -0x68(%rbp), %eax
jge 0x792ee
movq -0x310(%rbp), %rdi
movslq -0x70(%rbp), %rsi
callq 0x101d0
movq %rax, -0x318(%rbp)
jmp 0x7929b
movq -0x318(%rbp), %rax
movl (%rax), %eax
cmpl -0x64(%rbp), %eax
jle 0x792e1
movq -0x310(%rbp), %rdi
movslq -0x70(%rbp), %rsi
callq 0x101d0
movq %rax, -0x320(%rbp)
jmp 0x792c2
movq -0x320(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x64(%rbp)
jmp 0x792e1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
jmp 0x7a46e
jmp 0x792e3
movl -0x70(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x70(%rbp)
jmp 0x7927a
movl $0x0, -0x80(%rbp)
movl -0x80(%rbp), %eax
cmpl -0x6c(%rbp), %eax
jge 0x79356
movq -0x308(%rbp), %rdi
movslq -0x80(%rbp), %rsi
callq 0x101d0
movq %rax, -0x328(%rbp)
jmp 0x79316
movq -0x328(%rbp), %rax
movl (%rax), %eax
cmpl -0x64(%rbp), %eax
jle 0x79349
movq -0x308(%rbp), %rdi
movslq -0x80(%rbp), %rsi
callq 0x101d0
movq %rax, -0x330(%rbp)
jmp 0x7933d
movq -0x330(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x64(%rbp)
jmp 0x7934b
movl -0x80(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x80(%rbp)
jmp 0x792f5
movl -0x64(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x84(%rbp)
leaq -0xb0(%rbp), %rdi
callq 0xf670
movl $0x0, -0xb4(%rbp)
movl -0xb4(%rbp), %eax
cmpl -0x84(%rbp), %eax
jge 0x793ba
leaq -0xb0(%rbp), %rdi
xorl %esi, %esi
callq 0xf700
jmp 0x79396
jmp 0x79398
movl -0xb4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xb4(%rbp)
jmp 0x79378
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
jmp 0x7a462
movl $0x0, -0xb8(%rbp)
movl -0xb8(%rbp), %eax
cmpl -0x6c(%rbp), %eax
jge 0x794ca
movq -0x308(%rbp), %rdi
movslq -0xb8(%rbp), %rsi
callq 0x101d0
movq %rax, -0x338(%rbp)
jmp 0x793ef
movq -0x338(%rbp), %rax
movslq (%rax), %rsi
leaq -0xb0(%rbp), %rdi
callq 0xfff0
movq %rdx, -0x348(%rbp)
movq %rax, -0x340(%rbp)
jmp 0x79415
movq -0x348(%rbp), %rax
movq -0x340(%rbp), %rcx
movq %rcx, -0xc8(%rbp)
movq %rax, -0xc0(%rbp)
leaq -0xc8(%rbp), %rdi
callq 0x101a0
xorb $-0x1, %al
testb $0x1, %al
jne 0x79445
jmp 0x794b4
movq -0x308(%rbp), %rdi
movslq -0xb8(%rbp), %rsi
callq 0x101d0
movq %rax, -0x350(%rbp)
jmp 0x79461
movq -0x350(%rbp), %rax
movslq (%rax), %rsi
leaq -0xb0(%rbp), %rdi
callq 0xfff0
movq %rdx, -0x360(%rbp)
movq %rax, -0x358(%rbp)
jmp 0x79487
movq -0x360(%rbp), %rax
movq -0x358(%rbp), %rcx
movq %rcx, -0xd8(%rbp)
movq %rax, -0xd0(%rbp)
leaq -0xd8(%rbp), %rdi
movl $0x1, %esi
callq 0x10040
jmp 0x794b6
movl -0xb8(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xb8(%rbp)
jmp 0x793c4
testb $0x1, -0x39(%rbp)
je 0x795a9
movl -0x84(%rbp), %esi
leaq 0x17dbba(%rip), %rdi    # 0x1f709b
xorl %eax, %eax
callq 0x5070
jmp 0x794ea
movl $0x0, -0xdc(%rbp)
movl -0xdc(%rbp), %eax
cmpl -0x84(%rbp), %eax
jge 0x795a7
movl -0xdc(%rbp), %esi
leaq 0x17dbdd(%rip), %rdi    # 0x1f70f0
xorl %eax, %eax
callq 0x5070
jmp 0x7951c
movslq -0xdc(%rbp), %rsi
leaq -0xb0(%rbp), %rdi
callq 0xfff0
movq %rdx, -0x370(%rbp)
movq %rax, -0x368(%rbp)
jmp 0x7953f
movq -0x370(%rbp), %rax
movq -0x368(%rbp), %rcx
movq %rcx, -0xf0(%rbp)
movq %rax, -0xe8(%rbp)
leaq -0xf0(%rbp), %rdi
callq 0x101a0
testb $0x1, %al
jne 0x7956d
jmp 0x7957f
leaq 0x17db84(%rip), %rdi    # 0x1f70f8
xorl %eax, %eax
callq 0x5070
jmp 0x7957d
jmp 0x79591
leaq 0x17db7a(%rip), %rdi    # 0x1f7100
xorl %eax, %eax
callq 0x5070
jmp 0x7958f
jmp 0x79591
jmp 0x79593
movl -0xdc(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xdc(%rbp)
jmp 0x794f4
jmp 0x795a9
movl $0x0, -0xf4(%rbp)
movl -0xf4(%rbp), %eax
cmpl -0x84(%rbp), %eax
jge 0x7a0d0
leaq -0x110(%rbp), %rdi
callq 0xed40
movslq -0xf4(%rbp), %rsi
leaq -0xb0(%rbp), %rdi
callq 0xfff0
movq %rdx, -0x380(%rbp)
movq %rax, -0x378(%rbp)
jmp 0x795f4
movq -0x380(%rbp), %rax
movq -0x378(%rbp), %rcx
movq %rcx, -0x120(%rbp)
movq %rax, -0x118(%rbp)
leaq -0x120(%rbp), %rdi
callq 0x101a0
testb $0x1, %al
jne 0x79625
jmp 0x7a09f
movl $0x0, -0x124(%rbp)
movl -0x124(%rbp), %eax
cmpl -0x6c(%rbp), %eax
jge 0x7988d
movq -0x308(%rbp), %rdi
movslq -0x124(%rbp), %rsi
callq 0x101d0
movq %rax, -0x388(%rbp)
jmp 0x7965a
movq -0x388(%rbp), %rax
movl (%rax), %eax
cmpl -0xf4(%rbp), %eax
jne 0x79877
movq -0x2f8(%rbp), %rdi
movslq -0x124(%rbp), %rsi
callq 0x59c60
movq %rax, -0x390(%rbp)
jmp 0x7968b
movq -0x390(%rbp), %rax
movq (%rax), %rcx
movq %rcx, -0x140(%rbp)
movq 0x8(%rax), %rcx
movq %rcx, -0x138(%rbp)
movq 0x10(%rax), %rax
movq %rax, -0x130(%rbp)
movb $0x0, -0x141(%rbp)
leaq -0x58(%rbp), %rdi
callq 0x85300
movl %eax, -0x148(%rbp)
movl $0x0, -0x14c(%rbp)
movl -0x14c(%rbp), %ecx
xorl %eax, %eax
cmpl -0x148(%rbp), %ecx
movb %al, -0x391(%rbp)
jge 0x796f6
movb -0x141(%rbp), %al
xorb $-0x1, %al
movb %al, -0x391(%rbp)
movb -0x391(%rbp), %al
testb $0x1, %al
jne 0x79705
jmp 0x79855
movslq -0x14c(%rbp), %rsi
leaq -0x58(%rbp), %rdi
callq 0x85320
movq %rax, -0x3a0(%rbp)
jmp 0x7971e
movq -0x3a0(%rbp), %rax
movups (%rax), %xmm0
movups 0x10(%rax), %xmm1
movaps %xmm1, -0x160(%rbp)
movaps %xmm0, -0x170(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x3b0(%rbp)
leaq -0x140(%rbp), %rdi
xorl %esi, %esi
callq 0xe9d70
movq %rax, -0x3a8(%rbp)
jmp 0x7975c
movq -0x3a8(%rbp), %rax
movsd (%rax), %xmm0
movsd %xmm0, -0x3c0(%rbp)
leaq -0x140(%rbp), %rdi
movl $0x1, %esi
callq 0xe9d70
movq %rax, -0x3b8(%rbp)
jmp 0x79789
movq -0x3b8(%rbp), %rax
movsd (%rax), %xmm0
movsd %xmm0, -0x3d0(%rbp)
leaq -0x140(%rbp), %rdi
movl $0x2, %esi
callq 0xe9d70
movq %rax, -0x3c8(%rbp)
jmp 0x797b6
movsd -0x3d0(%rbp), %xmm1
movsd -0x3c0(%rbp), %xmm0
movq -0x3b0(%rbp), %rdi
movq -0x3c8(%rbp), %rax
movsd (%rax), %xmm2
movsd -0x170(%rbp), %xmm3
movsd -0x168(%rbp), %xmm4
movsd -0x160(%rbp), %xmm5
callq 0x97720
movsd %xmm0, -0x3d8(%rbp)
jmp 0x797ff
movsd -0x3d8(%rbp), %xmm0
movsd %xmm0, -0x178(%rbp)
movsd -0x178(%rbp), %xmm1
movsd -0x158(%rbp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x7983f
movb $0x1, -0x141(%rbp)
jmp 0x7983f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
jmp 0x7a0bf
jmp 0x79841
movl -0x14c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x14c(%rbp)
jmp 0x796d2
testb $0x1, -0x141(%rbp)
jne 0x79875
leaq -0x110(%rbp), %rdi
leaq -0x140(%rbp), %rsi
callq 0x59bf0
jmp 0x79873
jmp 0x79875
jmp 0x79877
jmp 0x79879
movl -0x124(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x124(%rbp)
jmp 0x7962f
leaq -0x110(%rbp), %rdi
callq 0x17c60
movl %eax, -0x17c(%rbp)
cmpl $0x0, -0x17c(%rbp)
jle 0x7a09d
testb $0x1, -0x39(%rbp)
je 0x798d0
movl -0x17c(%rbp), %esi
movl -0xf4(%rbp), %edx
leaq 0x17d844(%rip), %rdi    # 0x1f7109
xorl %eax, %eax
callq 0x5070
jmp 0x798ce
jmp 0x798d0
movq -0x8(%rbp), %rdi
leaq -0x110(%rbp), %rsi
callq 0x83f60
movl %eax, -0x3dc(%rbp)
jmp 0x798e8
movl -0x3dc(%rbp), %eax
movl %eax, -0x180(%rbp)
movslq -0x180(%rbp), %rsi
leaq -0x110(%rbp), %rdi
callq 0x59c60
movq %rax, -0x3e8(%rbp)
jmp 0x79910
movq -0x3e8(%rbp), %rax
movq (%rax), %rcx
movq %rcx, -0x198(%rbp)
movq 0x8(%rax), %rcx
movq %rcx, -0x190(%rbp)
movq 0x10(%rax), %rax
movq %rax, -0x188(%rbp)
movsd 0x178e39(%rip), %xmm0   # 0x1f2778
movsd %xmm0, -0x1a0(%rbp)
movl $0x0, -0x1a4(%rbp)
movl -0x1a4(%rbp), %eax
cmpl -0x68(%rbp), %eax
jge 0x79b3a
movq -0x300(%rbp), %rdi
movslq -0x1a4(%rbp), %rsi
callq 0x59c60
movq %rax, -0x3f0(%rbp)
jmp 0x7997c
movq -0x3f0(%rbp), %rax
movq 0x10(%rax), %rcx
movq %rcx, -0x1b0(%rbp)
movups (%rax), %xmm0
movaps %xmm0, -0x1c0(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x400(%rbp)
leaq -0x1c0(%rbp), %rdi
xorl %esi, %esi
callq 0xe9d70
movq %rax, -0x3f8(%rbp)
jmp 0x799ba
movq -0x3f8(%rbp), %rax
movsd (%rax), %xmm0
movsd %xmm0, -0x410(%rbp)
leaq -0x1c0(%rbp), %rdi
movl $0x1, %esi
callq 0xe9d70
movq %rax, -0x408(%rbp)
jmp 0x799e7
movq -0x408(%rbp), %rax
movsd (%rax), %xmm0
movsd %xmm0, -0x420(%rbp)
leaq -0x1c0(%rbp), %rdi
movl $0x2, %esi
callq 0xe9d70
movq %rax, -0x418(%rbp)
jmp 0x79a14
movq -0x418(%rbp), %rax
movsd (%rax), %xmm0
movsd %xmm0, -0x430(%rbp)
leaq -0x198(%rbp), %rdi
xorl %esi, %esi
callq 0xe9d70
movq %rax, -0x428(%rbp)
jmp 0x79a3e
movq -0x428(%rbp), %rax
movsd (%rax), %xmm0
movsd %xmm0, -0x440(%rbp)
leaq -0x198(%rbp), %rdi
movl $0x1, %esi
callq 0xe9d70
movq %rax, -0x438(%rbp)
jmp 0x79a6b
movq -0x438(%rbp), %rax
movsd (%rax), %xmm0
movsd %xmm0, -0x450(%rbp)
leaq -0x198(%rbp), %rdi
movl $0x2, %esi
callq 0xe9d70
movq %rax, -0x448(%rbp)
jmp 0x79a98
movsd -0x450(%rbp), %xmm4
movsd -0x440(%rbp), %xmm3
movsd -0x430(%rbp), %xmm2
movsd -0x420(%rbp), %xmm1
movsd -0x410(%rbp), %xmm0
movq -0x400(%rbp), %rdi
movq -0x448(%rbp), %rax
movsd (%rax), %xmm5
callq 0x97720
movsd %xmm0, -0x458(%rbp)
jmp 0x79ae1
movsd -0x458(%rbp), %xmm0
movsd %xmm0, -0x1c8(%rbp)
movsd -0x1c8(%rbp), %xmm1
movsd -0x1a0(%rbp), %xmm0
ucomisd %xmm1, %xmm0
ja 0x79b14
xorps %xmm0, %xmm0
ucomisd -0x1a0(%rbp), %xmm0
jbe 0x79b24
movsd -0x1c8(%rbp), %xmm0
movsd %xmm0, -0x1a0(%rbp)
jmp 0x79b26
movl -0x1a4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1a4(%rbp)
jmp 0x79951
xorps %xmm0, %xmm0
movsd %xmm0, -0x1d0(%rbp)
leaq -0x1e8(%rbp), %rdi
callq 0xf650
movl $0x0, -0x1ec(%rbp)
movl -0x1ec(%rbp), %eax
cmpl -0x17c(%rbp), %eax
jge 0x79d77
movslq -0x1ec(%rbp), %rsi
leaq -0x110(%rbp), %rdi
callq 0x59c60
movq %rax, -0x460(%rbp)
jmp 0x79b89
movq -0x460(%rbp), %rax
movq 0x10(%rax), %rcx
movq %rcx, -0x200(%rbp)
movups (%rax), %xmm0
movaps %xmm0, -0x210(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x470(%rbp)
leaq -0x210(%rbp), %rdi
xorl %esi, %esi
callq 0xe9d70
movq %rax, -0x468(%rbp)
jmp 0x79bc7
movq -0x468(%rbp), %rax
movsd (%rax), %xmm0
movsd %xmm0, -0x480(%rbp)
leaq -0x210(%rbp), %rdi
movl $0x1, %esi
callq 0xe9d70
movq %rax, -0x478(%rbp)
jmp 0x79bf4
movq -0x478(%rbp), %rax
movsd (%rax), %xmm0
movsd %xmm0, -0x490(%rbp)
leaq -0x210(%rbp), %rdi
movl $0x2, %esi
callq 0xe9d70
movq %rax, -0x488(%rbp)
jmp 0x79c21
movq -0x488(%rbp), %rax
movsd (%rax), %xmm0
movsd %xmm0, -0x4a0(%rbp)
leaq -0x198(%rbp), %rdi
xorl %esi, %esi
callq 0xe9d70
movq %rax, -0x498(%rbp)
jmp 0x79c4b
movq -0x498(%rbp), %rax
movsd (%rax), %xmm0
movsd %xmm0, -0x4b0(%rbp)
leaq -0x198(%rbp), %rdi
movl $0x1, %esi
callq 0xe9d70
movq %rax, -0x4a8(%rbp)
jmp 0x79c78
movq -0x4a8(%rbp), %rax
movsd (%rax), %xmm0
movsd %xmm0, -0x4c0(%rbp)
leaq -0x198(%rbp), %rdi
movl $0x2, %esi
callq 0xe9d70
movq %rax, -0x4b8(%rbp)
jmp 0x79ca5
movsd -0x4c0(%rbp), %xmm4
movsd -0x4b0(%rbp), %xmm3
movsd -0x4a0(%rbp), %xmm2
movsd -0x490(%rbp), %xmm1
movsd -0x480(%rbp), %xmm0
movq -0x470(%rbp), %rdi
movq -0x4b8(%rbp), %rax
movsd (%rax), %xmm5
callq 0x97720
movsd %xmm0, -0x4c8(%rbp)
jmp 0x79cee
movsd -0x4c8(%rbp), %xmm0
movsd %xmm0, -0x218(%rbp)
movsd -0x218(%rbp), %xmm0
ucomisd -0x1d0(%rbp), %xmm0
ja 0x79d1d
xorps %xmm0, %xmm0
ucomisd -0x1d0(%rbp), %xmm0
jbe 0x79d4c
movsd -0x218(%rbp), %xmm0
movsd %xmm0, -0x1d0(%rbp)
jmp 0x79d4c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
leaq -0x1e8(%rbp), %rdi
callq 0xf9d0
jmp 0x7a0bf
leaq -0x1e8(%rbp), %rdi
leaq -0x218(%rbp), %rsi
callq 0x105c0
jmp 0x79d61
jmp 0x79d63
movl -0x1ec(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1ec(%rbp)
jmp 0x79b5b
xorps %xmm0, %xmm0
movsd %xmm0, -0x220(%rbp)
xorps %xmm0, %xmm0
ucomisd -0x1a0(%rbp), %xmm0
jbe 0x79dae
movsd -0x1d0(%rbp), %xmm0
addsd -0x38(%rbp), %xmm0
addsd -0x60(%rbp), %xmm0
movsd %xmm0, -0x220(%rbp)
jmp 0x79e89
movsd -0x1d0(%rbp), %xmm1
movsd -0x1a0(%rbp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x79e39
movsd -0x1d0(%rbp), %xmm0
movsd -0x38(%rbp), %xmm1
addsd %xmm1, %xmm0
movsd -0x60(%rbp), %xmm1
addsd %xmm1, %xmm0
movsd %xmm0, -0x228(%rbp)
movsd -0x1a0(%rbp), %xmm0
movsd -0x38(%rbp), %xmm1
movsd -0x60(%rbp), %xmm2
addsd %xmm2, %xmm1
subsd %xmm1, %xmm0
movsd %xmm0, -0x230(%rbp)
leaq -0x228(%rbp), %rdi
leaq -0x230(%rbp), %rsi
callq 0x64f50
movq %rax, -0x4d0(%rbp)
jmp 0x79e24
movq -0x4d0(%rbp), %rax
movsd (%rax), %xmm0
movsd %xmm0, -0x220(%rbp)
jmp 0x79e87
movsd -0x1a0(%rbp), %xmm0
movsd -0x38(%rbp), %xmm1
movsd -0x60(%rbp), %xmm2
addsd %xmm2, %xmm1
subsd %xmm1, %xmm0
movsd %xmm0, -0x238(%rbp)
leaq -0x60(%rbp), %rdi
leaq -0x238(%rbp), %rsi
callq 0x64c70
movq %rax, -0x4d8(%rbp)
jmp 0x79e74
movq -0x4d8(%rbp), %rax
movsd (%rax), %xmm0
movsd %xmm0, -0x220(%rbp)
jmp 0x79e89
leaq -0x198(%rbp), %rdi
xorl %esi, %esi
callq 0xe9d70
movq %rax, -0x4e0(%rbp)
jmp 0x79ea0
movq -0x4e0(%rbp), %rax
movsd (%rax), %xmm0
movsd %xmm0, -0x258(%rbp)
leaq -0x198(%rbp), %rdi
movl $0x1, %esi
callq 0xe9d70
movq %rax, -0x4e8(%rbp)
jmp 0x79ecd
movq -0x4e8(%rbp), %rax
movsd (%rax), %xmm0
movsd %xmm0, -0x250(%rbp)
leaq -0x198(%rbp), %rdi
movl $0x2, %esi
callq 0xe9d70
movq %rax, -0x4f0(%rbp)
jmp 0x79efa
movq -0x4f0(%rbp), %rax
movsd (%rax), %xmm0
movsd %xmm0, -0x248(%rbp)
movsd -0x220(%rbp), %xmm0
movsd %xmm0, -0x240(%rbp)
leaq -0x58(%rbp), %rdi
leaq -0x258(%rbp), %rsi
callq 0x85360
jmp 0x79f2f
movl -0x17c(%rbp), %eax
subl $0x1, %eax
movl %eax, -0x25c(%rbp)
cmpl $0x0, -0x25c(%rbp)
jl 0x7a08c
movslq -0x25c(%rbp), %rsi
leaq -0x1e8(%rbp), %rdi
callq 0xfc80
movq %rax, -0x4f8(%rbp)
jmp 0x79f67
movq -0x4f8(%rbp), %rax
movsd (%rax), %xmm1
movsd -0x220(%rbp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x7a076
movslq -0x25c(%rbp), %rsi
leaq -0x110(%rbp), %rdi
callq 0x59c60
movq %rax, -0x500(%rbp)
jmp 0x79fa0
movq -0x500(%rbp), %rax
movq 0x10(%rax), %rcx
movq %rcx, -0x270(%rbp)
movups (%rax), %xmm0
movaps %xmm0, -0x280(%rbp)
movl -0x17c(%rbp), %eax
decl %eax
movslq %eax, %rsi
leaq -0x110(%rbp), %rdi
callq 0x59c60
movq %rax, -0x508(%rbp)
jmp 0x79fdc
movslq -0x25c(%rbp), %rsi
leaq -0x110(%rbp), %rdi
callq 0x59c60
movq %rax, -0x510(%rbp)
jmp 0x79ff8
movq -0x510(%rbp), %rax
movq -0x508(%rbp), %rcx
movq 0x10(%rcx), %rdx
movq %rdx, 0x10(%rax)
movups (%rcx), %xmm0
movups %xmm0, (%rax)
movl -0x17c(%rbp), %eax
decl %eax
movslq %eax, %rsi
leaq -0x110(%rbp), %rdi
callq 0x59c60
movq %rax, -0x518(%rbp)
jmp 0x7a034
movq -0x518(%rbp), %rax
movq -0x280(%rbp), %rcx
movq %rcx, (%rax)
movq -0x278(%rbp), %rcx
movq %rcx, 0x8(%rax)
movq -0x270(%rbp), %rcx
movq %rcx, 0x10(%rax)
leaq -0x110(%rbp), %rdi
callq 0x853d0
movl -0x17c(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x17c(%rbp)
jmp 0x7a078
movl -0x25c(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x25c(%rbp)
jmp 0x79f3e
leaq -0x1e8(%rbp), %rdi
callq 0xf9d0
jmp 0x7989f
jmp 0x7a09f
leaq -0x110(%rbp), %rdi
callq 0xefe0
movl -0xf4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xf4(%rbp)
jmp 0x795b3
leaq -0x110(%rbp), %rdi
callq 0xefe0
jmp 0x7a462
leaq -0x58(%rbp), %rdi
callq 0x85300
movl %eax, -0x284(%rbp)
testb $0x1, -0x39(%rbp)
je 0x7a0ff
movl -0x284(%rbp), %edx
leaq 0x17d059(%rip), %rdi    # 0x1f714b
xorl %eax, %eax
movl %edx, %esi
callq 0x5070
jmp 0x7a0fd
jmp 0x7a0ff
movq -0x10(%rbp), %rdi
movl -0x284(%rbp), %esi
callq 0x58d0
movq %rax, -0x520(%rbp)
jmp 0x7a117
movq -0x520(%rbp), %rdi
leaq 0x17f500(%rip), %rsi    # 0x1f9625
callq 0x5540
jmp 0x7a12c
movl $0x0, -0x288(%rbp)
movl -0x288(%rbp), %eax
cmpl -0x284(%rbp), %eax
jge 0x7a444
movslq -0x288(%rbp), %rsi
leaq -0x58(%rbp), %rdi
callq 0x85320
movq %rax, -0x528(%rbp)
jmp 0x7a161
movq -0x528(%rbp), %rax
movq (%rax), %rcx
movq %rcx, -0x2a8(%rbp)
movq 0x8(%rax), %rcx
movq %rcx, -0x2a0(%rbp)
movq 0x10(%rax), %rcx
movq %rcx, -0x298(%rbp)
movq 0x18(%rax), %rax
movq %rax, -0x290(%rbp)
testb $0x1, -0x39(%rbp)
je 0x7a354
leaq -0x2c0(%rbp), %rdi
xorps %xmm2, %xmm2
movaps %xmm2, %xmm0
movaps %xmm2, %xmm1
callq 0xe9c70
jmp 0x7a1b4
movsd -0x2a8(%rbp), %xmm0
movsd %xmm0, -0x538(%rbp)
leaq -0x2c0(%rbp), %rdi
xorl %esi, %esi
callq 0xe9d70
movq %rax, -0x530(%rbp)
jmp 0x7a1db
movq -0x530(%rbp), %rax
movsd -0x538(%rbp), %xmm0
movsd %xmm0, (%rax)
movsd -0x2a0(%rbp), %xmm0
movsd %xmm0, -0x548(%rbp)
leaq -0x2c0(%rbp), %rdi
movl $0x1, %esi
callq 0xe9d70
movq %rax, -0x540(%rbp)
jmp 0x7a218
movq -0x540(%rbp), %rax
movsd -0x548(%rbp), %xmm0
movsd %xmm0, (%rax)
movsd -0x298(%rbp), %xmm0
movsd %xmm0, -0x558(%rbp)
leaq -0x2c0(%rbp), %rdi
movl $0x2, %esi
callq 0xe9d70
movq %rax, -0x550(%rbp)
jmp 0x7a255
movq -0x550(%rbp), %rax
movsd -0x558(%rbp), %xmm0
movsd %xmm0, (%rax)
movq -0x8(%rbp), %rsi
movq -0x2b0(%rbp), %rax
movq %rax, -0x2e0(%rbp)
movups -0x2c0(%rbp), %xmm0
movaps %xmm0, -0x2f0(%rbp)
movq -0x2e0(%rbp), %rcx
movq %rsp, %rax
movq %rcx, 0x10(%rax)
movaps -0x2f0(%rbp), %xmm0
movups %xmm0, (%rax)
leaq -0x2d8(%rbp), %rdi
callq 0x961d0
jmp 0x7a2ae
leaq -0x2d8(%rbp), %rdi
xorl %esi, %esi
callq 0xe9d70
movq %rax, -0x560(%rbp)
jmp 0x7a2c5
movq -0x560(%rbp), %rax
movsd (%rax), %xmm0
movsd %xmm0, -0x570(%rbp)
leaq -0x2d8(%rbp), %rdi
movl $0x1, %esi
callq 0xe9d70
movq %rax, -0x568(%rbp)
jmp 0x7a2f2
movq -0x568(%rbp), %rax
movsd (%rax), %xmm0
movsd %xmm0, -0x580(%rbp)
leaq -0x2d8(%rbp), %rdi
movl $0x2, %esi
callq 0xe9d70
movq %rax, -0x578(%rbp)
jmp 0x7a31f
movsd -0x580(%rbp), %xmm1
movsd -0x570(%rbp), %xmm0
movq -0x578(%rbp), %rax
movsd (%rax), %xmm2
movsd -0x290(%rbp), %xmm3
leaq 0x17ce8f(%rip), %rdi    # 0x1f71d8
movb $0x4, %al
callq 0x5070
jmp 0x7a352
jmp 0x7a354
movq -0x10(%rbp), %rdi
movsd -0x2a8(%rbp), %xmm0
callq 0x5980
movq %rax, -0x588(%rbp)
jmp 0x7a36e
movq -0x588(%rbp), %rdi
leaq 0x181f32(%rip), %rsi    # 0x1fc2ae
callq 0x5540
movq %rax, -0x590(%rbp)
jmp 0x7a38a
movq -0x590(%rbp), %rdi
movsd -0x2a0(%rbp), %xmm0
callq 0x5980
movq %rax, -0x598(%rbp)
jmp 0x7a3a7
movq -0x598(%rbp), %rdi
leaq 0x181ef9(%rip), %rsi    # 0x1fc2ae
callq 0x5540
movq %rax, -0x5a0(%rbp)
jmp 0x7a3c3
movq -0x5a0(%rbp), %rdi
movsd -0x298(%rbp), %xmm0
callq 0x5980
movq %rax, -0x5a8(%rbp)
jmp 0x7a3e0
movq -0x5a8(%rbp), %rdi
leaq 0x181ec0(%rip), %rsi    # 0x1fc2ae
callq 0x5540
movq %rax, -0x5b0(%rbp)
jmp 0x7a3fc
movq -0x5b0(%rbp), %rdi
movsd -0x290(%rbp), %xmm0
callq 0x5980
movq %rax, -0x5b8(%rbp)
jmp 0x7a419
movq -0x5b8(%rbp), %rdi
leaq 0x17f1fe(%rip), %rsi    # 0x1f9625
callq 0x5540
jmp 0x7a42e
jmp 0x7a430
movl -0x288(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x288(%rbp)
jmp 0x7a136
leaq -0xb0(%rbp), %rdi
callq 0xf9b0
leaq -0x58(%rbp), %rdi
callq 0x85400
addq $0x5d0, %rsp            # imm = 0x5D0
popq %rbp
retq
leaq -0xb0(%rbp), %rdi
callq 0xf9b0
leaq -0x58(%rbp), %rdi
callq 0x85400
movq -0x78(%rbp), %rdi
callq 0x58f0