// File: /workspace/github_cpp_makefile_star2_O2/Luthaf[P]zeopp/area_and_volume.cc
// Function: getLocalSubstructures(char*, double, double, TRIPLET, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, VORONOI_NETWORK*, ATOM_NETWORK*, bool, bool)
void getLocalSubstructures(char* name, double probeRad, double local_substructure_radius, TRIPLET supercell_steps_local_substructure, string element, VORONOI_NETWORK* vornet, ATOM_NETWORK* atmnet, bool radial, bool usingElementOnly) {
  vector<bool> accessInfo;
  vector<CHANNEL> channels;
  CHANNEL::findChannels(vornet, probeRad, &accessInfo, &channels);
  ATOM_NETWORK simplified_atmnet;
  atmnet->copy(&simplified_atmnet);
  VORONOI_NETWORK simplified_vornet;
  vornet->copy(&simplified_vornet);
  vector<bool> isAccessible;
  int num_accessible = 0;
  //if not simplifying, avoid the calculation and just copy the data
  if(!usingElementOnly) {
    isAccessible = accessInfo;
  } else {
    //create the simplified atmnet, ready to calculate simplified vornet etc.
    simplified_vornet.edges.clear();
    simplified_vornet.nodes.clear();
    simplified_atmnet.atoms.clear();
    simplified_atmnet.numAtoms = 0;
    for(int i=0; i<atmnet->numAtoms; i++){
      if(atmnet->atoms.at(i).type.compare(element)==0) {
        ATOM newAtom;
        newAtom.type = atmnet->atoms.at(i).type;
        newAtom.a_coord = atmnet->atoms.at(i).a_coord;
        newAtom.b_coord = atmnet->atoms.at(i).b_coord;
        newAtom.c_coord = atmnet->atoms.at(i).c_coord;
        newAtom.x = atmnet->atoms.at(i).x;
        newAtom.y = atmnet->atoms.at(i).y;
        newAtom.z = atmnet->atoms.at(i).z;
        newAtom.radius = lookupRadius(newAtom.type, radial);
        simplified_atmnet.atoms.push_back(newAtom);
        simplified_atmnet.numAtoms++;
      }
    }
    cout << "Starting simplified Voronoi decomposition" << "\n";
    vector< VOR_CELL> simplified_cells;
    vector< BASIC_VCELL> simplified_bvcells;
    if(radial) {
      container_periodic_poly *rad_con = (container_periodic_poly *)performVoronoiDecomp(true, &simplified_atmnet, &simplified_vornet, simplified_cells, false, simplified_bvcells);
      delete rad_con;
    } else {
      container_periodic *no_rad_con = (container_periodic *)performVoronoiDecomp (false, &simplified_atmnet, &simplified_vornet, simplified_cells, false, simplified_bvcells); 
      delete no_rad_con;
    }
    cout << "Finished simplified Voronoi decomposition" << "\n";
    printf("*** Original voronoi network on %d atoms contains %d nodes and %d edges ***\n", atmnet->numAtoms, (int)(vornet->nodes.size()), (int)(vornet->edges.size()));
    printf("*** Simplified voronoi network on %d atoms contains %d nodes and %d edges ***\n", simplified_atmnet.numAtoms, (int)(simplified_vornet.nodes.size()), (int)(simplified_vornet.edges.size()));
    //now check which of these nodes of the simplified network lie in accessible space w.r.t. atmnet
    float chan_radius = probeRad;
    determineAccessibility(atmnet, chan_radius, probeRad, true, &isAccessible, &simplified_vornet); //where probeRad is the smaller, used to probe the channels accessible to chan_radius, the larger
  }
  for(int i=0; i<(int)(simplified_vornet.nodes.size()); i++) {
    if(simplified_vornet.nodes.at(i).rad_stat_sphere<=0) isAccessible.at(i)=false;
    if(isAccessible.at(i)==true) num_accessible++;
  }
  printf("*** %d of these %d nodes lie in accessible space ***\n", num_accessible, (int)(simplified_vornet.nodes.size()));
  //now try and remove redundant nodes
  int malloc_num_accessible = num_accessible;
  double **distance_between_nodes_array = new double*[malloc_num_accessible];
  for(int i=0; i<malloc_num_accessible; i++) distance_between_nodes_array[i] = new double[malloc_num_accessible];
  int *node_reference = new int[malloc_num_accessible];
  double *node_density = new double[malloc_num_accessible];
  int iter = 0;
  for(int i=0; i<(int)(simplified_vornet.nodes.size()); i++) {
    if(isAccessible.at(i)==true) {
      node_reference[iter] = i; //now we can iterate over this array for simplicity
      iter++;
    }
  }
  double minimum_node_distance = 1.0; //two nodes closer than this probably don't tell us anything different about the structure
  char some_distance_too_low_exists = 0;
  for(int i=0; i<malloc_num_accessible; i++) {
    node_density[i] = 0.0;
  }
  for(int i=0; i<malloc_num_accessible; i++) {
    distance_between_nodes_array[i][i] = 0.0;
    for(int j=i+1; j<malloc_num_accessible; j++) {
      int node_i = node_reference[i];
      int node_j = node_reference[j];
      Point abcCoord_i = atmnet->xyz_to_abc(simplified_vornet.nodes.at(node_i).x, simplified_vornet.nodes.at(node_i).y, simplified_vornet.nodes.at(node_i).z);
      Point abcCoord_j = atmnet->xyz_to_abc(simplified_vornet.nodes.at(node_j).x, simplified_vornet.nodes.at(node_j).y, simplified_vornet.nodes.at(node_j).z);
      double distance = atmnet->getDistCalc().minimum_periodic_distance(abcCoord_i.vals[0], abcCoord_i.vals[1], abcCoord_i.vals[2], abcCoord_j.vals[0], abcCoord_j.vals[1], abcCoord_j.vals[2]);
      if(distance<minimum_node_distance) some_distance_too_low_exists = 1;
      distance_between_nodes_array[i][j] = distance;
      distance_between_nodes_array[j][i] = distance;
      node_density[i] += exp(-1*distance*distance);
      node_density[j] += exp(-1*distance*distance);
    }
  }
  if(some_distance_too_low_exists>0) {
    //now we have the distance array, iterate over the nodes, removing the most dense, while there are some accessible ones closer than some distance
    while(some_distance_too_low_exists==1) {
      int accessibility_index_of_max_density_node = -1;
      double max_density = -1;
      for(int i=0; i<malloc_num_accessible; i++) {
        if(isAccessible.at(node_reference[i])==true) {
          if(node_density[i]>max_density) {
            max_density = node_density[i];
            accessibility_index_of_max_density_node = i;
          }
        }
      }
      if(max_density<0 || accessibility_index_of_max_density_node<0) {
        printf("ERROR: no node found in max density search\n");
        exit(EXIT_FAILURE);
      }
      //remove this most dense node
      isAccessible.at(node_reference[accessibility_index_of_max_density_node])=false;
      num_accessible--;
      //we need to recalculate densities and check if any remaining accessible node triggers the too-close test!
      some_distance_too_low_exists = 0;
      for(int i=0; i<malloc_num_accessible; i++) {
        node_density[i] = 0.0;
      }
      for(int i=0; i<malloc_num_accessible; i++) {
        int node_i = node_reference[i];
        if(isAccessible.at(node_i)==true) {
          for(int j=i+1; j<malloc_num_accessible; j++) {
            int node_j = node_reference[j];
            if(isAccessible.at(node_j)==true) {
              double distance = distance_between_nodes_array[i][j];
              if(distance<minimum_node_distance) some_distance_too_low_exists = 1;
              node_density[i] += exp(-1*distance*distance);
              node_density[j] += exp(-1*distance*distance);
            }
          }
        }
      }
    }
    printf("STATUS: %d nodes were removed, leaving %d, none of which are within %.3fA of any other\n", malloc_num_accessible-num_accessible, num_accessible, minimum_node_distance);
  }
  //free memory
  for(int i=0; i<malloc_num_accessible; i++) delete[] distance_between_nodes_array[i];
  delete[] distance_between_nodes_array;
  delete[] node_reference;
  delete[] node_density;

  //construct the supercell_atmnet for extracting spheres
  ATOM_NETWORK supercell_atmnet;
  atmnet->copy(&supercell_atmnet);
  for(int a_step=-1*supercell_steps_local_substructure[0]; a_step<=supercell_steps_local_substructure[0]; a_step++) {
    for(int b_step=-1*supercell_steps_local_substructure[1]; b_step<=supercell_steps_local_substructure[1]; b_step++) {
      for(int c_step=-1*supercell_steps_local_substructure[2]; c_step<=supercell_steps_local_substructure[2]; c_step++) {
        if(a_step!=0 || b_step!=0 || c_step!=0) { //don't make copies within the unit cell!
          for(int i=0; i<atmnet->numAtoms; i++){
            ATOM newAtom;
            newAtom.type = atmnet->atoms.at(i).type;
            newAtom.a_coord = atmnet->atoms.at(i).a_coord+a_step;
            newAtom.b_coord = atmnet->atoms.at(i).b_coord+b_step;
            newAtom.c_coord = atmnet->atoms.at(i).c_coord+c_step;
            Point xyz = atmnet->abc_to_xyz(newAtom.a_coord, newAtom.b_coord, newAtom.c_coord);
            newAtom.x = xyz.vals[0];
            newAtom.y = xyz.vals[1];
            newAtom.z = xyz.vals[2];
            newAtom.radius = lookupRadius(newAtom.type, radial);
            supercell_atmnet.atoms.push_back(newAtom);
            supercell_atmnet.numAtoms++;
          }
        }
      }
    }
  }
  printf("*** Unit cell contains %d atoms; supercell contains %d atoms ***\n", atmnet->numAtoms, supercell_atmnet.numAtoms);
  int node_index = 0;
  for(int i=0; i<(int)(simplified_vornet.nodes.size()); i++) {
    vector<ATOM> vector_of_local_atoms; //all those visible atoms within some distance, i.e. those which comprise the local surface
    if(isAccessible.at(i)==true) {
      for(int j=0; j<supercell_atmnet.numAtoms; j++) {
        float distance = calcEuclideanDistance(simplified_vornet.nodes.at(i).x, simplified_vornet.nodes.at(i).y, simplified_vornet.nodes.at(i).z, supercell_atmnet.atoms.at(j).x, supercell_atmnet.atoms.at(j).y, supercell_atmnet.atoms.at(j).z);
        if(distance<=local_substructure_radius) vector_of_local_atoms.push_back(supercell_atmnet.atoms.at(j));
      }
      //now finished putting local atoms in the vector, write them to file for now
      string number = intAsString(node_index);
      string filename_xyz = string(name).append("_local_substructure_");
      filename_xyz.append(number);
      filename_xyz.append(".xyz");
      FILE *local_xyz; local_xyz = fopen(filename_xyz.c_str(), "w");
      fprintf(local_xyz, "%d\nxyz header\n", (int)vector_of_local_atoms.size()+1);
      for(int j=0; j<(int)vector_of_local_atoms.size(); j++) {
        fprintf(local_xyz, "%s %.3f %.3f %.3f\n", vector_of_local_atoms.at(j).type.c_str(), vector_of_local_atoms.at(j).x, vector_of_local_atoms.at(j).y, vector_of_local_atoms.at(j).z);
      }
      fprintf(local_xyz, "X %.3f %.3f %.3f\n", simplified_vornet.nodes.at(i).x, simplified_vornet.nodes.at(i).y, simplified_vornet.nodes.at(i).z);
      fclose(local_xyz);
      node_index++;
    }
  }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xb78, %rsp            # imm = 0xB78
movl %r9d, %ebx
movl %r8d, 0x10(%rsp)
leaq 0x228(%rsp), %rax
andq $0x0, (%rax)
movq %rcx, 0x8(%rsp)
andl $0x0, 0x8(%rax)
movq %rdx, %r15
andq $0x0, 0x10(%rax)
movq %rsi, %r12
andl $0x0, 0x18(%rax)
movsd %xmm1, 0xf0(%rsp)
andq $0x0, 0x20(%rax)
movq %rdi, 0xe8(%rsp)
xorps %xmm1, %xmm1
leaq 0x210(%rsp), %rdx
movaps %xmm1, (%rdx)
andq $0x0, 0x10(%rdx)
movq %r15, %rdi
movsd %xmm0, 0x20(%rsp)
movq %rax, %rsi
callq 0x55b76
leaq 0x718(%rsp), %rdi
callq 0x3db30
leaq 0x718(%rsp), %r14
movq 0x8(%rsp), %rdi
movq %r14, %rsi
callq 0x3eada
leaq 0xf8(%rsp), %rdi
callq 0x4090e
leaq 0xf8(%rsp), %rsi
movq %r15, %rdi
callq 0x40a3a
andq $0x0, 0xc0(%rsp)
andl $0x0, 0xc8(%rsp)
andq $0x0, 0xd0(%rsp)
andl $0x0, 0xd8(%rsp)
andq $0x0, 0xe0(%rsp)
movzbl 0x10(%rsp), %eax
movl %eax, 0x78(%rsp)
testb %bl, %bl
je 0x33911
movq %r15, 0x30(%rsp)
movq 0x158(%rsp), %rax
cmpq %rax, 0x160(%rsp)
je 0x33791
movq %rax, 0x160(%rsp)
leaq 0x140(%rsp), %rdi
callq 0xa840
movl $0x2f0, %r13d           # imm = 0x2F0
addq %r13, %r14
movq %r14, %rdi
callq 0xa732
andl $0x0, 0x828(%rsp)
addq 0x8(%rsp), %r13
xorl %r15d, %r15d
leaq 0x2b0(%rsp), %rbx
leaq 0x290(%rsp), %rbp
movq 0x8(%rsp), %rax
movslq 0x110(%rax), %rax
cmpq %rax, %r15
jge 0x3392b
movq %r13, %rdi
movq %r15, %rsi
callq 0xa73a
addq $0x40, %rax
movq %rax, %rdi
movq %r12, %rsi
callq 0x4040
testl %eax, %eax
jne 0x33909
movq %rbx, %rdi
callq 0x3dc5a
movq %r13, %rdi
movq %r15, %rsi
callq 0xa73a
addq $0x40, %rax
leaq 0x2f0(%rsp), %rdi
movq %rax, %rsi
callq 0x4270
movq %r13, %rdi
movq %r15, %rsi
callq 0xa73a
movsd 0x18(%rax), %xmm0
movsd %xmm0, 0x2c8(%rsp)
movq %r13, %rdi
movq %r15, %rsi
callq 0xa73a
movsd 0x20(%rax), %xmm0
movsd %xmm0, 0x2d0(%rsp)
movq %r13, %rdi
movq %r15, %rsi
callq 0xa73a
movsd 0x28(%rax), %xmm0
movsd %xmm0, 0x2d8(%rsp)
movq %r13, %rdi
movq %r15, %rsi
callq 0xa73a
movsd (%rax), %xmm0
movsd %xmm0, 0x2b0(%rsp)
movq %r13, %rdi
movq %r15, %rsi
callq 0xa73a
movsd 0x8(%rax), %xmm0
movsd %xmm0, 0x2b8(%rsp)
movq %r13, %rdi
movq %r15, %rsi
callq 0xa73a
movsd 0x10(%rax), %xmm0
movsd %xmm0, 0x2c0(%rsp)
movq %rbp, %rdi
leaq 0x2f0(%rsp), %rsi
callq 0x45d0
movq %rbp, %rdi
movl 0x78(%rsp), %esi
callq 0x1b1bb
movsd %xmm0, 0x2e0(%rsp)
movq %rbp, %rdi
callq 0x4210
movq %r14, %rdi
movq %rbx, %rsi
callq 0xa7d8
incl 0x828(%rsp)
movq %rbx, %rdi
callq 0xa808
incq %r15
jmp 0x337cf
leaq 0xc0(%rsp), %rdi
leaq 0x228(%rsp), %rsi
callq 0x37084
jmp 0x33adc
movq 0x11c68e(%rip), %rdi    # 0x14ffc0
leaq 0xcd41b(%rip), %rsi     # 0x100d54
callq 0x4480
leaq 0xcec39(%rip), %rsi     # 0x10257e
movq %rax, %rdi
callq 0x4480
xorps %xmm0, %xmm0
movaps %xmm0, 0x2b0(%rsp)
andq $0x0, 0x2c0(%rsp)
movaps %xmm0, 0x170(%rsp)
andq $0x0, 0x180(%rsp)
cmpb $0x0, 0x10(%rsp)
je 0x339bb
pushq $0x1
popq %rdi
leaq 0x718(%rsp), %rsi
leaq 0xf8(%rsp), %rdx
leaq 0x2b0(%rsp), %rcx
leaq 0x170(%rsp), %r9
xorl %r8d, %r8d
callq 0x52ae
movq %rax, %rbx
testq %rax, %rax
je 0x339b4
movq %rbx, %rdi
callq 0xa63a
movl $0x298, %esi            # imm = 0x298
jmp 0x339fa
leaq 0x718(%rsp), %rsi
leaq 0xf8(%rsp), %rdx
leaq 0x2b0(%rsp), %rcx
leaq 0x170(%rsp), %r9
xorl %edi, %edi
xorl %r8d, %r8d
callq 0x52ae
movq %rax, %rbx
testq %rax, %rax
je 0x339f5
movq %rbx, %rdi
callq 0xa654
movl $0x270, %esi            # imm = 0x270
movq %rbx, %rdi
callq 0x44b0
movq 0x11c5b7(%rip), %rdi    # 0x14ffc0
leaq 0xcd36e(%rip), %rsi     # 0x100d7e
callq 0x4480
leaq 0xceb62(%rip), %rsi     # 0x10257e
movq %rax, %rdi
callq 0x4480
movq 0x8(%rsp), %r15
movl 0x110(%r15), %esi
movq 0x30(%rsp), %rdx
movq 0x50(%rdx), %rcx
movq 0x68(%rdx), %rax
subq 0x48(%rdx), %rcx
shrq $0x6, %rcx
subq 0x60(%rdx), %rax
pushq $0x28
popq %r14
cqto
idivq %r14
leaq 0xcd34f(%rip), %rdi     # 0x100da8
movl %ecx, %edx
movl %eax, %ecx
xorl %eax, %eax
callq 0x4050
movl 0x828(%rsp), %esi
leaq 0xf8(%rsp), %rbx
movq 0x50(%rbx), %rcx
subq 0x48(%rbx), %rcx
movq 0x68(%rbx), %rax
shrq $0x6, %rcx
subq 0x60(%rbx), %rax
cqto
idivq %r14
leaq 0xcd362(%rip), %rdi     # 0x100df5
movl %ecx, %edx
movl %eax, %ecx
xorl %eax, %eax
callq 0x4050
movsd 0x20(%rsp), %xmm1
cvtsd2ss %xmm1, %xmm0
cvtss2sd %xmm0, %xmm0
pushq $0x1
popq %rsi
leaq 0xc0(%rsp), %rdx
movq %r15, %rdi
movq %rbx, %rcx
callq 0x31734
leaq 0x170(%rsp), %rdi
callq 0xaa94
leaq 0x2b0(%rsp), %rdi
callq 0xaa72
xorl %ebx, %ebx
leaq 0x140(%rsp), %r15
leaq 0xc0(%rsp), %r14
xorl %ebp, %ebp
movq 0x148(%rsp), %rdx
subq 0x140(%rsp), %rdx
shrq $0x6, %rdx
movslq %edx, %rax
cmpq %rax, %rbx
jge 0x33b4c
movq %r15, %rdi
movq %rbx, %rsi
callq 0xa848
xorps %xmm0, %xmm0
ucomisd 0x18(%rax), %xmm0
jb 0x33b32
movq %r14, %rdi
movq %rbx, %rsi
callq 0xaba4
notq %rdx
andq %rdx, (%rax)
movq %r14, %rdi
movq %rbx, %rsi
callq 0xaba4
andq (%rax), %rdx
cmpq $0x1, %rdx
sbbl $-0x1, %ebp
incq %rbx
jmp 0x33af0
leaq 0xcd2f1(%rip), %rdi     # 0x100e44
movl %ebp, %esi
xorl %eax, %eax
callq 0x4050
movl %ebp, %ebx
leaq (,%rbx,8), %r14
movq %r14, %rdi
callq 0x4030
movq %rax, 0x18(%rsp)
xorl %r15d, %r15d
cmpq %r15, %rbx
je 0x33b91
movq %r14, %rdi
callq 0x4030
movq 0x18(%rsp), %rcx
movq %rax, (%rcx,%r15,8)
incq %r15
jmp 0x33b76
movl %ebp, 0x6c(%rsp)
leaq (,%rbx,4), %rdi
callq 0x4030
movq %rax, %r13
movq %r14, %rdi
callq 0x4030
movq %rax, 0x10(%rsp)
xorl %r14d, %r14d
leaq 0xc0(%rsp), %r12
xorl %r15d, %r15d
movq 0x148(%rsp), %rax
subq 0x140(%rsp), %rax
shrq $0x6, %rax
cltq
cmpq %rax, %r14
jge 0x33bfb
movq %r12, %rdi
movq %r14, %rsi
callq 0xaba4
testq %rdx, (%rax)
je 0x33bf6
movslq %r15d, %r15
movl %r14d, (%r13,%r15,4)
incl %r15d
incq %r14
jmp 0x33bc0
xorl %eax, %eax
movq 0x10(%rsp), %rcx
cmpq %rax, %rbx
je 0x33c11
andq $0x0, (%rcx,%rax,8)
incq %rax
jmp 0x33c02
pushq $0x1
popq %rbp
xorl %ecx, %ecx
xorl %r12d, %r12d
movq %rbx, 0x70(%rsp)
cmpq %rbx, %rcx
je 0x33e25
movq 0x18(%rsp), %rax
movq (%rax,%rcx,8), %rax
andq $0x0, (%rax,%rcx,8)
movq %rcx, 0x20(%rsp)
leaq 0x1(%rcx), %rax
movq %rax, 0x48(%rsp)
movq %rbp, 0x60(%rsp)
cmpq %rbx, %rbp
jae 0x33e13
movl %r12d, %ebx
movq 0x20(%rsp), %rax
movslq (%r13,%rax,4), %r12
movslq (%r13,%rbp,4), %r14
leaq 0x140(%rsp), %r15
movq %r15, %rdi
movq %r12, %rsi
callq 0xa848
movsd (%rax), %xmm0
movsd %xmm0, 0x30(%rsp)
movq %r15, %rdi
movq %r12, %rsi
callq 0xa848
movsd 0x8(%rax), %xmm0
movsd %xmm0, 0x50(%rsp)
movq %r15, %rdi
movq %r12, %rsi
callq 0xa848
movsd 0x10(%rax), %xmm2
leaq 0x170(%rsp), %rdi
movq 0x8(%rsp), %rsi
movsd 0x30(%rsp), %xmm0
movsd 0x50(%rsp), %xmm1
callq 0x3f1ce
movq %r15, %rdi
movq %r14, %rsi
callq 0xa848
movsd (%rax), %xmm0
movsd %xmm0, 0x30(%rsp)
leaq 0x140(%rsp), %rdi
movq %r14, %rsi
callq 0xa848
movsd 0x8(%rax), %xmm0
movsd %xmm0, 0x50(%rsp)
leaq 0x140(%rsp), %rdi
movq %r14, %rsi
callq 0xa848
movsd 0x10(%rax), %xmm2
leaq 0x80(%rsp), %rdi
movq 0x8(%rsp), %rsi
movsd 0x30(%rsp), %xmm0
movsd 0x50(%rsp), %xmm1
callq 0x3f1ce
leaq 0x2b0(%rsp), %r14
movq %r14, %rdi
movq 0x8(%rsp), %rsi
callq 0x3ec9e
movsd 0x170(%rsp), %xmm0
movsd 0x178(%rsp), %xmm1
movsd 0x180(%rsp), %xmm2
movsd 0x80(%rsp), %xmm3
movsd 0x88(%rsp), %xmm4
movsd 0x90(%rsp), %xmm5
movq %r14, %rdi
callq 0x59cea
movq %r14, %rdi
movaps %xmm0, 0x30(%rsp)
callq 0xb0f0
movsd 0xc82c9(%rip), %xmm0    # 0xfc058
movapd 0x30(%rsp), %xmm1
ucomisd %xmm1, %xmm0
movl %ebx, %r12d
movzbl %r12b, %r12d
pushq $0x1
popq %rax
cmoval %eax, %r12d
movq 0x18(%rsp), %rcx
movq 0x20(%rsp), %rbx
movq (%rcx,%rbx,8), %rax
movsd %xmm1, (%rax,%rbp,8)
movq (%rcx,%rbp,8), %rax
movsd %xmm1, (%rax,%rbx,8)
movapd %xmm1, %xmm0
xorpd 0xcc801(%rip), %xmm0    # 0x1005d0
mulsd %xmm1, %xmm0
movapd %xmm0, 0x30(%rsp)
callq 0x47b0
movq 0x10(%rsp), %r14
addsd (%r14,%rbx,8), %xmm0
movsd %xmm0, (%r14,%rbx,8)
movapd 0x30(%rsp), %xmm0
callq 0x47b0
addsd (%r14,%rbp,8), %xmm0
movsd %xmm0, (%r14,%rbp,8)
incq %rbp
movq 0x70(%rsp), %rbx
jmp 0x33c48
movq 0x60(%rsp), %rbp
incq %rbp
movq 0x48(%rsp), %rcx
jmp 0x33c1e
testb %r12b, %r12b
je 0x33fc8
leaq 0xc0(%rsp), %r14
movl 0x6c(%rsp), %eax
movl %eax, 0x30(%rsp)
cmpb $0x1, %r12b
jne 0x33fa8
xorl %r15d, %r15d
pushq $-0x1
popq %rbp
movsd 0xcc492(%rip), %xmm0    # 0x1002e8
movsd %xmm0, 0x20(%rsp)
cmpq %r15, %rbx
je 0x33e94
movslq (%r13,%r15,4), %rsi
movq %r14, %rdi
callq 0xaba4
testq %rdx, (%rax)
je 0x33e8f
movq 0x10(%rsp), %rax
movsd (%rax,%r15,8), %xmm0
ucomisd 0x20(%rsp), %xmm0
jbe 0x33e8f
movl %r15d, %ebp
movsd %xmm0, 0x20(%rsp)
incq %r15
jmp 0x33e5c
xorpd %xmm0, %xmm0
ucomisd 0x20(%rsp), %xmm0
ja 0x3464b
testl %ebp, %ebp
js 0x3464b
movl %ebp, %eax
movslq (%r13,%rax,4), %rsi
movq %r14, %rdi
callq 0xaba4
notq %rdx
andq %rdx, (%rax)
xorl %eax, %eax
cmpq %rax, %rbx
je 0x33ed7
movq 0x10(%rsp), %rcx
andq $0x0, (%rcx,%rax,8)
incq %rax
jmp 0x33ec3
decl 0x30(%rsp)
xorl %r15d, %r15d
xorl %r12d, %r12d
cmpq %rbx, %r15
je 0x33e3e
movslq (%r13,%r15,4), %rsi
movq %r14, %rdi
callq 0xaba4
testq %rdx, (%rax)
je 0x33fa0
movq %r15, %rbp
movq %rbp, %rcx
leaq 0x1(%rcx), %rbp
cmpq %rbx, %rbp
jae 0x33fa0
movslq 0x4(%r13,%rcx,4), %rsi
movq %r14, %rdi
callq 0xaba4
movq %rbp, %rcx
testq %rdx, (%rax)
je 0x33f06
movq 0x18(%rsp), %rax
movq (%rax,%r15,8), %rax
movsd (%rax,%rbp,8), %xmm2
movsd 0xc811a(%rip), %xmm1    # 0xfc058
ucomisd %xmm2, %xmm1
movzbl %r12b, %r12d
pushq $0x1
popq %rax
cmoval %eax, %r12d
movapd %xmm2, %xmm0
xorpd 0xcc677(%rip), %xmm0    # 0x1005d0
mulsd %xmm2, %xmm0
movapd %xmm0, 0x20(%rsp)
callq 0x47b0
movl %r12d, %ebx
movq 0x10(%rsp), %r12
addsd (%r12,%r15,8), %xmm0
movsd %xmm0, (%r12,%r15,8)
movapd 0x20(%rsp), %xmm0
callq 0x47b0
addsd (%r12,%rbp,8), %xmm0
movsd %xmm0, (%r12,%rbp,8)
movl %ebx, %r12d
movq 0x70(%rsp), %rbx
jmp 0x33f03
incq %r15
jmp 0x33ee1
movl 0x6c(%rsp), %esi
movl 0x30(%rsp), %edx
subl %edx, %esi
leaq 0xccec1(%rip), %rdi     # 0x100e7a
movsd 0xc8097(%rip), %xmm0    # 0xfc058
movb $0x1, %al
callq 0x4050
xorl %r14d, %r14d
cmpq %r14, %rbx
je 0x33fe8
movq 0x18(%rsp), %rax
movq (%rax,%r14,8), %rdi
testq %rdi, %rdi
je 0x33fe3
callq 0x4590
incq %r14
jmp 0x33fcb
movq 0x18(%rsp), %rdi
callq 0x4590
movq %r13, %rdi
callq 0x4590
movq 0x10(%rsp), %rdi
callq 0x4590
leaq 0x2b0(%rsp), %rdi
callq 0x3db30
leaq 0x2b0(%rsp), %rsi
movq 0x8(%rsp), %rdi
movq %rsi, 0x20(%rsp)
callq 0x3eada
xorl %ebx, %ebx
leaq 0xbb0(%rsp), %rdi
xorl %esi, %esi
callq 0x63fb2
subl (%rax), %ebx
movq %rbx, 0x48(%rsp)
movl $0x2f0, %eax            # imm = 0x2F0
movq 0x8(%rsp), %rcx
leaq (%rcx,%rax), %rbx
leaq 0x1b0(%rsp), %r15
addq %rax, 0x20(%rsp)
leaq 0x170(%rsp), %r12
leaq 0x80(%rsp), %rbp
leaq 0x270(%rsp), %r14
leaq 0xbb0(%rsp), %rdi
xorl %esi, %esi
callq 0x63fb2
movq 0x48(%rsp), %rcx
cmpl (%rax), %ecx
jg 0x34281
leaq 0xbb0(%rsp), %rdi
pushq $0x1
popq %rsi
callq 0x63fb2
xorl %ecx, %ecx
subl (%rax), %ecx
movl %ecx, 0x60(%rsp)
cvtsi2sdl 0x48(%rsp), %xmm0
movsd %xmm0, 0x50(%rsp)
leaq 0xbb0(%rsp), %rdi
pushq $0x1
popq %rsi
callq 0x63fb2
movl 0x60(%rsp), %ecx
cmpl (%rax), %ecx
jg 0x34270
leaq 0xbb0(%rsp), %rdi
pushq $0x2
popq %rsi
callq 0x63fb2
xorl %ecx, %ecx
subl (%rax), %ecx
movl %ecx, 0x18(%rsp)
movq 0x48(%rsp), %rax
movl 0x60(%rsp), %ecx
orl %ecx, %eax
setne 0x70(%rsp)
cvtsi2sd %ecx, %xmm0
movsd %xmm0, 0x30(%rsp)
leaq 0xbb0(%rsp), %rdi
pushq $0x2
popq %rsi
callq 0x63fb2
movl 0x18(%rsp), %ecx
cmpl (%rax), %ecx
jg 0x34267
testl %ecx, %ecx
setne %al
orb 0x70(%rsp), %al
cmpb $0x1, %al
jne 0x3425e
cvtsi2sdl 0x18(%rsp), %xmm0
movsd %xmm0, 0x10(%rsp)
xorl %r13d, %r13d
movq 0x8(%rsp), %rax
movslq 0x110(%rax), %rax
cmpq %rax, %r13
jge 0x3425e
movq %r12, %rdi
callq 0x3dc5a
movq %rbx, %rdi
movq %r13, %rsi
callq 0xa73a
addq $0x40, %rax
movq %r15, %rdi
movq %rax, %rsi
callq 0x4270
movq %rbx, %rdi
movq %r13, %rsi
callq 0xa73a
movsd 0x18(%rax), %xmm0
addsd 0x50(%rsp), %xmm0
movsd %xmm0, 0x188(%rsp)
movq %rbx, %rdi
movq %r13, %rsi
callq 0xa73a
movsd 0x20(%rax), %xmm0
addsd 0x30(%rsp), %xmm0
movsd %xmm0, 0x190(%rsp)
movq %rbx, %rdi
movq %r13, %rsi
callq 0xa73a
movsd 0x28(%rax), %xmm2
addsd 0x10(%rsp), %xmm2
movsd %xmm2, 0x198(%rsp)
movsd 0x188(%rsp), %xmm0
movsd 0x190(%rsp), %xmm1
movq %rbp, %rdi
movq 0x8(%rsp), %rsi
callq 0x3f0e6
movaps 0x80(%rsp), %xmm0
movaps %xmm0, 0x170(%rsp)
movsd 0x90(%rsp), %xmm0
movsd %xmm0, 0x180(%rsp)
movq %r14, %rdi
movq %r15, %rsi
callq 0x45d0
movq %r14, %rdi
movl 0x78(%rsp), %esi
callq 0x1b1bb
movsd %xmm0, 0x1a0(%rsp)
movq %r14, %rdi
callq 0x4210
movq 0x20(%rsp), %rdi
movq %r12, %rsi
callq 0xa7d8
incl 0x3c0(%rsp)
movq %r12, %rdi
callq 0xa808
incq %r13
jmp 0x3413d
incl 0x18(%rsp)
jmp 0x34101
incl 0x60(%rsp)
jmp 0x340b3
movq 0x48(%rsp), %rax
incl %eax
movq %rax, 0x48(%rsp)
jmp 0x34073
movq 0x8(%rsp), %rax
movl 0x110(%rax), %esi
movl 0x3c0(%rsp), %edx
leaq 0xccc38(%rip), %rdi     # 0x100ed2
xorl %eax, %eax
callq 0x4050
leaq 0xa0(%rsp), %r14
leaq 0x170(%rsp), %r12
leaq 0x250(%rsp), %rbp
movl $0x98, %ebx
xorl %r15d, %r15d
movl $0x0, 0x18(%rsp)
movq 0x148(%rsp), %rax
subq 0x140(%rsp), %rax
shrq $0x6, %rax
cltq
cmpq %rax, %r15
jge 0x345eb
xorps %xmm0, %xmm0
movaps %xmm0, 0xa0(%rsp)
andq $0x0, 0xb0(%rsp)
leaq 0xc0(%rsp), %rdi
movq %r15, %rsi
callq 0xaba4
testq %rdx, (%rax)
je 0x345db
xorl %r13d, %r13d
movslq 0x3c0(%rsp), %rax
cmpq %rax, %r13
jge 0x34414
leaq 0x140(%rsp), %rdi
movq %r15, %rsi
callq 0xa848
movsd (%rax), %xmm0
movsd %xmm0, 0x8(%rsp)
leaq 0x140(%rsp), %rdi
movq %r15, %rsi
callq 0xa848
movsd 0x8(%rax), %xmm0
movsd %xmm0, 0x10(%rsp)
leaq 0x140(%rsp), %rdi
movq %r15, %rsi
callq 0xa848
movsd 0x10(%rax), %xmm0
movsd %xmm0, 0x30(%rsp)
movq 0x20(%rsp), %rdi
movq %r13, %rsi
callq 0xa73a
movsd (%rax), %xmm0
movsd %xmm0, 0x78(%rsp)
movq 0x20(%rsp), %rdi
movq %r13, %rsi
callq 0xa73a
movsd 0x8(%rax), %xmm0
movsd %xmm0, 0x50(%rsp)
movq 0x20(%rsp), %rdi
movq %r13, %rsi
callq 0xa73a
movsd 0x10(%rax), %xmm5
movsd 0x8(%rsp), %xmm0
movsd 0x10(%rsp), %xmm1
movsd 0x30(%rsp), %xmm2
movsd 0x78(%rsp), %xmm3
movsd 0x50(%rsp), %xmm4
callq 0x64934
cvtsd2ss %xmm0, %xmm0
cvtss2sd %xmm0, %xmm0
movsd 0xf0(%rsp), %xmm1
ucomisd %xmm0, %xmm1
jb 0x3440c
movq 0x20(%rsp), %rdi
movq %r13, %rsi
callq 0xa73a
movq %r14, %rdi
movq %rax, %rsi
callq 0xa7d8
incq %r13
jmp 0x34318
movq %r12, %rdi
movl 0x18(%rsp), %esi
callq 0x38621
movq %rbp, %rdi
movq 0xe8(%rsp), %rsi
leaq 0x5f(%rsp), %rdx
callq 0x1b80e
movq %rbp, %rdi
leaq 0xccad5(%rip), %rsi     # 0x100f14
callq 0x4800
leaq 0x80(%rsp), %r13
movq %r13, %rdi
movq %rax, %rsi
callq 0x45d0
movq %rbp, %rdi
callq 0x4210
movq %r13, %rdi
movq %r12, %rsi
callq 0x4850
movq %r13, %rdi
leaq 0xccd68(%rip), %rsi     # 0x1011dc
callq 0x4800
movq 0x80(%rsp), %rdi
leaq 0xcc72c(%rip), %rsi     # 0x100bb4
callq 0x4530
movq %rax, %rbp
movq 0xa8(%rsp), %rax
subq 0xa0(%rsp), %rax
cqto
idivq %rbx
leal 0x1(%rax), %edx
movq %rbp, %rdi
leaq 0xcca77(%rip), %rsi     # 0x100f29
xorl %eax, %eax
callq 0x4610
xorl %r13d, %r13d
movq 0xa8(%rsp), %rax
subq 0xa0(%rsp), %rax
cqto
idivq %rbx
cltq
cmpq %rax, %r13
jge 0x3454a
movq %r14, %rdi
movq %r13, %rsi
callq 0xa73a
movq 0x40(%rax), %r12
movq %r14, %rdi
movq %r13, %rsi
callq 0xa73a
movsd (%rax), %xmm0
movsd %xmm0, 0x8(%rsp)
movq %r14, %rdi
movq %r13, %rsi
callq 0xa73a
movsd 0x8(%rax), %xmm0
movsd %xmm0, 0x10(%rsp)
movq %r14, %rdi
movq %r13, %rsi
callq 0xa73a
movsd 0x10(%rax), %xmm2
movq %rbp, %rdi
leaq 0xcca0c(%rip), %rsi     # 0x100f38
movq %r12, %rdx
movsd 0x8(%rsp), %xmm0
movsd 0x10(%rsp), %xmm1
movb $0x3, %al
callq 0x4610
incq %r13
jmp 0x344bc
leaq 0x140(%rsp), %r12
movq %r12, %rdi
movq %r15, %rsi
callq 0xa848
movsd (%rax), %xmm0
movsd %xmm0, 0x8(%rsp)
movq %r12, %rdi
movq %r15, %rsi
callq 0xa848
movsd 0x8(%rax), %xmm0
movsd %xmm0, 0x10(%rsp)
movq %r12, %rdi
movq %r15, %rsi
callq 0xa848
movsd 0x10(%rax), %xmm2
movq %rbp, %rdi
leaq 0xcc9b4(%rip), %rsi     # 0x100f4b
movsd 0x8(%rsp), %xmm0
movsd 0x10(%rsp), %xmm1
movb $0x3, %al
callq 0x4610
movq %rbp, %rdi
callq 0x4490
incl 0x18(%rsp)
leaq 0x80(%rsp), %rdi
callq 0x4210
leaq 0x170(%rsp), %r12
movq %r12, %rdi
callq 0x4210
leaq 0x250(%rsp), %rbp
movq %r14, %rdi
callq 0xb110
incq %r15
jmp 0x342c9
leaq 0x2b0(%rsp), %rdi
callq 0xaab6
leaq 0xc0(%rsp), %rdi
callq 0xa976
leaq 0xf8(%rsp), %rdi
callq 0xa95c
leaq 0x718(%rsp), %rdi
callq 0xaab6
leaq 0x210(%rsp), %rdi
callq 0x37062
leaq 0x228(%rsp), %rdi
callq 0xa976
addq $0xb78, %rsp            # imm = 0xB78
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0xccabc(%rip), %rdi     # 0x10110e
callq 0x4670
pushq $0x1
popq %rdi
callq 0x524c
jmp 0x3467e
jmp 0x3467e
jmp 0x3467e
jmp 0x3477f
jmp 0x3477f
jmp 0x3477a
jmp 0x3477a
jmp 0x3477a
movq %rax, %rbx
leaq 0x170(%rsp), %rdi
callq 0xaa94
leaq 0x2b0(%rsp), %rdi
callq 0xaa72
jmp 0x347b5
jmp 0x3477a
movq %rax, %rbx
jmp 0x347c2
jmp 0x346af
movq %rax, %rbx
jmp 0x347cf
jmp 0x346b9
movq %rax, %rbx
jmp 0x347dc
jmp 0x3477a
movq %rax, %rbx
jmp 0x3473b
jmp 0x34762
movq %rax, %rbx
leaq 0x290(%rsp), %rdi
callq 0x4210
jmp 0x34715
jmp 0x3477a
jmp 0x34762
jmp 0x3477f
jmp 0x3477f
jmp 0x3472b
movq %rax, %rbx
leaq 0x250(%rsp), %rdi
jmp 0x34736
jmp 0x3472b
jmp 0x3477a
jmp 0x3477a
jmp 0x3477a
jmp 0x3477a
jmp 0x3477a
jmp 0x3477a
jmp 0x3477a
movq %rax, %rbx
leaq 0x2b0(%rsp), %rdi
callq 0xa808
jmp 0x347b5
jmp 0x3477f
jmp 0x3477f
movq %rax, %rbx
leaq 0x80(%rsp), %rdi
callq 0x4210
leaq 0x170(%rsp), %rdi
callq 0x4210
jmp 0x34765
jmp 0x3477a
jmp 0x3477a
jmp 0x3477a
movq %rax, %rbx
leaq 0x2b0(%rsp), %rdi
callq 0xb0f0
jmp 0x347b5
movq %rax, %rbx
leaq 0xa0(%rsp), %rdi
callq 0xb110
jmp 0x347a8
jmp 0x3477a
jmp 0x3477a
jmp 0x3477f
movq %rax, %rbx
jmp 0x347b5
movq %rax, %rbx
jmp 0x347a8
movq %rax, %rbx
leaq 0x270(%rsp), %rdi
callq 0x4210
jmp 0x3479b
jmp 0x34798
movq %rax, %rbx
leaq 0x170(%rsp), %rdi
callq 0xa808
leaq 0x2b0(%rsp), %rdi
callq 0xaab6
leaq 0xc0(%rsp), %rdi
callq 0xa976
leaq 0xf8(%rsp), %rdi
callq 0xa95c
leaq 0x718(%rsp), %rdi
callq 0xaab6
leaq 0x210(%rsp), %rdi
callq 0x37062
leaq 0x228(%rsp), %rdi
callq 0xa976
movq %rbx, %rdi
callq 0x4780