// File: /workspace/github_cpp_makefile_star2_O3/tomfunkhouser[P]gaps/pkgs/R3Shapes/R3Mesh.cpp
// Function: gaps::R3Mesh::GeodesicDistances(gaps::R3MeshVertex const*, double) const
RNLength *R3Mesh::
GeodesicDistances(const R3MeshVertex *source_vertex, RNLength max_distance) const
{
  // Create arrays of upper bounds on distances
  RNLength *vertex_distances = new RNLength [ NVertices() ];
  RNLength *edge_distances = new RNLength [ NEdges() ];
  RNLength *face_distances = new RNLength [ NFaces() ];
  assert(vertex_distances && edge_distances && face_distances);
  for (int i = 0; i < NVertices(); i++) vertex_distances[i] = FLT_MAX;
  for (int i = 0; i < NEdges(); i++) edge_distances[i] = FLT_MAX;
  for (int i = 0; i < NFaces(); i++) face_distances[i] = FLT_MAX;
  vertex_distances [VertexID(source_vertex)] = 0;

  // Initialize heap of beams originating at source vertex
  R3MeshGeodesicBeam tmp;
  RNHeap<R3MeshGeodesicBeam *> heap(&tmp, &(tmp.distance));
  RNArray<R3MeshGeodesicBeam *> beams;
  R3MeshCreateGeodesicBeamsForVertex(this, source_vertex, max_distance, 0, NULL, 
    vertex_distances, edge_distances, face_distances, heap, beams);
  for (int i = 0; i < VertexValence(source_vertex); i++) {
    R3MeshEdge *e = EdgeOnVertex(source_vertex, i);
    R3MeshVertex *vertex = VertexAcrossEdge(e, source_vertex);
    edge_distances [EdgeID(e)] = EdgeLength(e);
    vertex_distances [VertexID(vertex)] = EdgeLength(e);
    if (R3MeshVertexIsSaddleOrBoundary(this, vertex)) {
      R3MeshCreateGeodesicBeamsForVertex(this, vertex, max_distance, EdgeLength(e), NULL, 
        vertex_distances, edge_distances, face_distances, heap, beams);
    }
  }

  // Pop beams off heap
  while (!heap.IsEmpty()) {
    // Get beam
    R3MeshGeodesicBeam *beam = heap.Pop();
    assert(beam);

    // Get face across edge
    R3MeshFace *face = FaceAcrossEdge(beam->edge, beam->face);
    assert(face);

    // Check beam distances versus upper bounds on distances found already
    if (beam->distance > beam->distance - beam->distance_to_source + vertex_distances[VertexID(beam->source)]) continue;
    if (beam->distance >= edge_distances[EdgeID(beam->edge)]) continue;
    if (beam->distance >= face_distances[FaceID(face)]) continue;

    // Construct beam extent
    R3Point left_span_position = beam->span.Start();
    R3Vector left_vector =  left_span_position.Vector();
    R3Vector left_normal = left_vector % R3posz_vector; left_normal.Normalize();
    R3Plane left_plane(left_span_position, left_normal);
    R3Point right_span_position = beam->span.End();
    R3Vector right_vector =  right_span_position.Vector();
    R3Vector right_normal = R3posz_vector % right_vector; right_normal.Normalize();
    R3Plane right_plane(right_span_position, right_normal);

    // Find affine that takes points on face into beam coordinate system
    R3Vector face_normal = FaceNormal(face);
    face_normal.Transform(beam->affine);
    R3Affine affine = R3identity_affine;
    affine.Translate(beam->span.Midpoint().Vector());
    affine.Rotate(face_normal, R3posz_vector);
    affine.Translate(-(beam->span.Midpoint().Vector()));
    affine.Transform(beam->affine);

    // Spawn beams across edges
    for (int i = 0; i < 2; i++) {
      R3MeshEdge *edge = EdgeOnFace(face, beam->edge, i);
      R3MeshFace *neighbor_face = FaceAcrossEdge(edge, face);
      if (!neighbor_face) continue;

      // Check versus upper-bound distances
      if (beam->distance >= edge_distances[EdgeID(edge)]) continue;
      if (beam->distance >= face_distances[FaceID(neighbor_face)]) continue;

      // Get edge span in unfolded beam coordinate system
      R3MeshVertex *v_ccw = VertexOnFace(face, edge, RN_CCW);
      R3MeshVertex *v_cw = VertexOnFace(face, edge, RN_CW);
      R3Point p_ccw = VertexPosition(v_ccw);
      R3Point p_cw = VertexPosition(v_cw);
      p_ccw.Transform(affine);
      p_cw.Transform(affine);
      R3Span edge_span(p_ccw, p_cw);
      // assert(RNIsZero(p_ccw[2]));
      // assert(RNIsZero(p_cw[2]));

      // Check if source is on correct side of edge span
      R3Vector span_vector = edge_span.Vector();
      if (RNIsZero(span_vector.Length())) continue;
      R3Vector span_normal = R3posz_vector % span_vector; span_normal.Normalize();
      R3Plane span_plane(edge_span.Midpoint(), span_normal);
      if (RNIsPositive(R3SignedDistance(span_plane, R3zero_point))) continue;
      
      // Check for edge-beam intersection
      // RNScalar left_dcw = R3SignedDistance(left_plane, edge_span.End());
      // if (RNIsNegative(left_dcw)) continue;
      // RNScalar right_dccw = R3SignedDistance(right_plane, edge_span.Start());
      // if (RNIsNegative(right_dccw)) continue;
        
      // Clip edge span to beam
      if (!edge_span.Clip(left_plane)) continue;
      if (!edge_span.Clip(right_plane)) continue;

      // Get lower bound on distance to edge span
      RNLength beam_distance = beam->distance_to_source + R3Distance(R3zero_point, edge_span);
      if ((max_distance > 0) && (beam_distance > max_distance)) continue;

      // Check versus upper-bound distances
      if (beam_distance >= edge_distances[EdgeID(edge)]) continue;
      if (beam_distance >= face_distances[FaceID(neighbor_face)]) continue;

      // Create beam
      R3MeshGeodesicBeam *child_beam = new R3MeshGeodesicBeam();
      child_beam->source = beam->source;
      child_beam->face = face;
      child_beam->edge = edge;
      child_beam->affine = affine;
      child_beam->span = edge_span;
      child_beam->distance = beam_distance;
      child_beam->distance_to_source = beam->distance_to_source;
      child_beam->parent = beam;

      // Add beam to heap
      heap.Push(child_beam);
      beams.Insert(child_beam);
    }

    // Update upper bound distances and spawn beams from vertices
    for (int i = 0; i < 3; i++) {
      R3MeshVertex *vertex = VertexOnFace(face, i);
      R3Point vertex_position = VertexPosition(vertex);
      vertex_position.Transform(affine);

      // Compute distance to vertex along this path
      RNLength vertex_distance = 0;
      RNBoolean vertex_visible = FALSE;
      if (R3SignedDistance(left_plane, vertex_position) < 0) {
        // Vertex is to the left of the beam
        RNLength left_distance1 = R3Distance(R3zero_point, left_span_position);
        RNLength left_distance2 = R3Distance(left_span_position, vertex_position);
        vertex_distance = beam->distance_to_source + left_distance1 + left_distance2;
      }
      else if (R3SignedDistance(right_plane, vertex_position) < 0) {
        // Vertex is to the right of the beam
        RNLength right_distance1 = R3Distance(R3zero_point, right_span_position);
        RNLength right_distance2 = R3Distance(right_span_position, vertex_position);
        vertex_distance = beam->distance_to_source + right_distance1 + right_distance2;
      }
      else {
        // Vertex is inside the beam
        vertex_distance = beam->distance_to_source + R3Distance(R3zero_point, vertex_position);
        vertex_visible = TRUE;
      }

      // Update upper bound distances
      if (vertex_distance < vertex_distances[VertexID(vertex)]) {
        // Remember vertex distance
        RNLength old_vertex_distance = vertex_distances[VertexID(vertex)];
        vertex_distances[VertexID(vertex)] = vertex_distance;

        // Update edge distances
        for (int j = 0; j < 2; j++) {
          R3MeshEdge *edge = EdgeOnFace(face, beam->edge, j);
          if (vertex_distance < edge_distances[EdgeID(edge)]) {
            R3MeshVertex *v = VertexAcrossEdge(edge, vertex);
            if (vertex_distance > vertex_distances[VertexID(v)]) {
              edge_distances[EdgeID(edge)] = vertex_distance;
            }
          }
        }

        // Update face distance
        if (vertex_distance < face_distances[FaceID(face)]) {
          R3MeshVertex *v0 = VertexOnFace(face, vertex, RN_CCW);
          R3MeshVertex *v1 = VertexOnFace(face, vertex, RN_CW);
          if ((vertex_distance > vertex_distances[VertexID(v0)]) && (vertex_distance > vertex_distances[VertexID(v1)])) {
            face_distances[FaceID(face)] = vertex_distance;
          }
        }

        // Spawn beam from "across" vertex if it is a visible saddle or boundary
        if (vertex_visible && (vertex == VertexAcrossFace(face, beam->edge))) { 
          if (RNIsLess(vertex_distance, old_vertex_distance)) {
            if (R3MeshVertexIsSaddleOrBoundary(this, vertex)) {
              R3MeshCreateGeodesicBeamsForVertex(this, vertex, max_distance, vertex_distance, beam, 
                vertex_distances, edge_distances, face_distances, heap, beams);
            }
          }
        }
      }
    }
  }

  // Delete all beams
  for (int i = 0; i < beams.NEntries(); i++) {
    delete beams[i];
  }

  // Delete edge and face distances
  delete [] edge_distances;
  delete [] face_distances;

  // Return vertex distances
  return vertex_distances;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x528, %rsp            # imm = 0x528
movq %xmm0, 0x40(%rsp)
movq %rsi, %rbx
movq %rdi, %r14
movslq 0x14(%rdi), %r13
leaq (,%r13,8), %rdi
testq %r13, %r13
movq $-0x1, %rbp
cmovsq %rbp, %rdi
callq 0xe030
movq %rax, 0x28(%rsp)
movslq 0x24(%r14), %r12
leaq (,%r12,8), %rdi
testq %r12, %r12
cmovsq %rbp, %rdi
callq 0xe030
movq %rax, %r15
movq %r14, 0x30(%rsp)
movslq 0x34(%r14), %r14
leaq (,%r14,8), %rdi
testq %r14, %r14
cmovsq %rbp, %rdi
callq 0xe030
movq %rax, 0x20(%rsp)
movabsq $0x47efffffe0000000, %rax # imm = 0x47EFFFFFE0000000
testq %r13, %r13
jle 0x1ada3
leal 0x1(%r13), %ecx
decq %r13
movq %r13, %xmm0
pshufd $0x44, %xmm0, %xmm0     # xmm0 = xmm0[0,1,0,1]
shrl %ecx
shlq $0x4, %rcx
movdqa 0x87558(%rip), %xmm1    # 0xa2280
xorl %edx, %edx
movdqa 0x8755e(%rip), %xmm2    # 0xa2290
pxor %xmm2, %xmm0
pcmpeqd %xmm3, %xmm3
movdqa 0x8755e(%rip), %xmm4    # 0xa22a0
movdqa %xmm1, %xmm5
pxor %xmm2, %xmm5
movdqa %xmm5, %xmm6
pcmpgtd %xmm0, %xmm6
pcmpeqd %xmm0, %xmm5
pshufd $0xf5, %xmm5, %xmm7     # xmm7 = xmm5[1,1,3,3]
pand %xmm6, %xmm7
pshufd $0xf5, %xmm6, %xmm5     # xmm5 = xmm6[1,1,3,3]
por %xmm7, %xmm5
movd %xmm5, %esi
notl %esi
testb $0x1, %sil
je 0x1ad7d
movq 0x28(%rsp), %rsi
movq %rax, (%rsi,%rdx)
pxor %xmm3, %xmm5
pextrw $0x4, %xmm5, %esi
testb $0x1, %sil
je 0x1ad96
movq 0x28(%rsp), %rsi
movq %rax, 0x8(%rsi,%rdx)
paddq %xmm4, %xmm1
addq $0x10, %rdx
cmpq %rdx, %rcx
jne 0x1ad42
testl %r12d, %r12d
jle 0x1ae3d
leal 0x1(%r12), %ecx
decq %r12
movq %r12, %xmm0
pshufd $0x44, %xmm0, %xmm0     # xmm0 = xmm0[0,1,0,1]
shrl %ecx
shlq $0x4, %rcx
movdqa 0x874b4(%rip), %xmm1    # 0xa2280
xorl %edx, %edx
movdqa 0x874ba(%rip), %xmm2    # 0xa2290
pxor %xmm2, %xmm0
pcmpeqd %xmm3, %xmm3
movdqa 0x874ba(%rip), %xmm4    # 0xa22a0
movdqa %xmm1, %xmm5
pxor %xmm2, %xmm5
movdqa %xmm5, %xmm6
pcmpgtd %xmm0, %xmm6
pcmpeqd %xmm0, %xmm5
pshufd $0xf5, %xmm5, %xmm7     # xmm7 = xmm5[1,1,3,3]
pand %xmm6, %xmm7
pshufd $0xf5, %xmm6, %xmm5     # xmm5 = xmm6[1,1,3,3]
por %xmm7, %xmm5
movd %xmm5, %esi
notl %esi
testb $0x1, %sil
je 0x1ae1c
movq %rax, (%r15,%rdx)
pxor %xmm3, %xmm5
pextrw $0x4, %xmm5, %esi
testb $0x1, %sil
je 0x1ae30
movq %rax, 0x8(%r15,%rdx)
paddq %xmm4, %xmm1
addq $0x10, %rdx
cmpq %rdx, %rcx
jne 0x1ade6
testl %r14d, %r14d
jle 0x1aee0
leal 0x1(%r14), %ecx
decq %r14
movq %r14, %xmm0
pshufd $0x44, %xmm0, %xmm0     # xmm0 = xmm0[0,1,0,1]
shrl %ecx
shlq $0x4, %rcx
movdqa 0x8741b(%rip), %xmm1    # 0xa2280
xorl %edx, %edx
movdqa 0x87421(%rip), %xmm2    # 0xa2290
pxor %xmm2, %xmm0
pcmpeqd %xmm3, %xmm3
movdqa 0x87421(%rip), %xmm4    # 0xa22a0
movdqa %xmm1, %xmm5
pxor %xmm2, %xmm5
movdqa %xmm5, %xmm6
pcmpgtd %xmm0, %xmm6
pcmpeqd %xmm0, %xmm5
pshufd $0xf5, %xmm5, %xmm7     # xmm7 = xmm5[1,1,3,3]
pand %xmm6, %xmm7
pshufd $0xf5, %xmm6, %xmm5     # xmm5 = xmm6[1,1,3,3]
por %xmm7, %xmm5
movd %xmm5, %esi
notl %esi
testb $0x1, %sil
je 0x1aeba
movq 0x20(%rsp), %rsi
movq %rax, (%rsi,%rdx)
pxor %xmm3, %xmm5
pextrw $0x4, %xmm5, %esi
testb $0x1, %sil
je 0x1aed3
movq 0x20(%rsp), %rsi
movq %rax, 0x8(%rsi,%rdx)
paddq %xmm4, %xmm1
addq $0x10, %rdx
cmpq %rdx, %rcx
jne 0x1ae7f
movslq 0x70(%rbx), %rax
movq 0x28(%rsp), %rcx
movq $0x0, (%rcx,%rax,8)
leaq 0x3b0(%rsp), %rdi
callq 0x29f8c
leaq 0x4c0(%rsp), %rdi
callq 0x3b8e0
pxor %xmm0, %xmm0
movdqa %xmm0, 0x70(%rsp)
movdqu %xmm0, 0x88(%rsp)
movq $0x0, 0x98(%rsp)
movl $0x1, 0xa0(%rsp)
movabsq $-0xfffffe88, %rax      # imm = 0xFFFFFFFF00000178
movq %rax, 0x80(%rsp)
leaq 0x48(%rsp), %r14
movq %r14, %rdi
callq 0x6f80c
movq %r14, (%rsp)
leaq 0x70(%rsp), %r9
pxor %xmm1, %xmm1
movq 0x30(%rsp), %rdi
movq %rbx, %rsi
movsd 0x40(%rsp), %xmm0
xorl %edx, %edx
movq %r15, %rcx
movq 0x20(%rsp), %r8
callq 0x1bcdc
cmpl $0x0, 0x14(%rbx)
jle 0x1b05f
xorl %r14d, %r14d
leaq 0x70(%rsp), %r12
movq 0x8(%rbx), %rax
movq (%rax,%r14,8), %rbp
movq 0x8(%rbp), %r13
cmpq %rbx, %r13
jne 0x1afa5
movq 0x10(%rbp), %r13
movq 0x38(%rbp), %rax
testb $0x2, %al
jne 0x1afc2
movq 0x30(%rsp), %rdi
movq (%rdi), %rax
movq %rbp, %rsi
callq *0x2b8(%rax)
movq 0x38(%rbp), %rax
movsd 0x28(%rbp), %xmm0
movslq 0x30(%rbp), %rcx
movsd %xmm0, (%r15,%rcx,8)
testb $0x2, %al
jne 0x1afeb
movq 0x30(%rsp), %rdi
movq (%rdi), %rax
movq %rbp, %rsi
callq *0x2b8(%rax)
movsd 0x28(%rbp), %xmm0
movslq 0x70(%r13), %rax
movq 0x28(%rsp), %rcx
movsd %xmm0, (%rcx,%rax,8)
movq 0x30(%rsp), %rdi
movq %r13, %rsi
callq 0x1c0c5
testl %eax, %eax
je 0x1b04f
testb $0x2, 0x38(%rbp)
jne 0x1b021
movq 0x30(%rsp), %rdi
movq (%rdi), %rax
movq %rbp, %rsi
callq *0x2b8(%rax)
movq 0x28(%rbp), %xmm1
leaq 0x48(%rsp), %rax
movq %rax, (%rsp)
movq 0x30(%rsp), %rdi
movq %r13, %rsi
movsd 0x40(%rsp), %xmm0
xorl %edx, %edx
movq %r15, %rcx
movq 0x20(%rsp), %r8
movq %r12, %r9
callq 0x1bcdc
incq %r14
movslq 0x14(%rbx), %rax
cmpq %rax, %r14
jl 0x1af90
cmpl $0x0, 0x78(%rsp)
je 0x1bb95
leaq 0x70(%rsp), %r14
leaq 0xe8(%rsp), %r12
leaq 0x240(%rsp), %rbx
leaq 0x228(%rsp), %rbp
leaq 0xc705a(%rip), %rax     # 0xe20e8
addq $0x10, %rax
movq %rax, 0xc8(%rsp)
movl $0x88, %eax
addq 0xc9f3a(%rip), %rax     # 0xe4fe0
movq %rax, 0xb8(%rsp)
leaq 0xcaf4b(%rip), %rax     # 0xe6000
addq $0x8, %rax
movq %rax, 0xc0(%rsp)
movq %r14, %rdi
callq 0x2422a
movq 0x10(%rax), %rsi
movq 0x18(%rsi), %rcx
movq %rcx, 0x10(%rsp)
cmpq 0x8(%rax), %rcx
jne 0x1b0e5
movq 0x20(%rsi), %rcx
movq %rcx, 0x10(%rsp)
movsd 0x178(%rax), %xmm0
movapd %xmm0, %xmm1
subsd 0x180(%rax), %xmm1
movq %rax, 0x18(%rsp)
movq (%rax), %rcx
movslq 0x70(%rcx), %rcx
movq 0x28(%rsp), %rdx
addsd (%rdx,%rcx,8), %xmm1
ucomisd %xmm1, %xmm0
ja 0x1bb8a
movslq 0x30(%rsi), %rax
ucomisd (%r15,%rax,8), %xmm0
jae 0x1bb8a
movq 0x10(%rsp), %rax
movslq 0xa4(%rax), %rax
movq 0x20(%rsp), %rcx
ucomisd (%rcx,%rax,8), %xmm0
jae 0x1bb8a
movq 0x18(%rsp), %rax
leaq 0x128(%rax), %rsi
movq %r12, %r14
movq %r12, %rdi
movq %rsi, %r13
callq 0x3c542
movsd 0xe8(%rsp), %xmm0
movq 0xf0(%rsp), %xmm1
movq 0xf8(%rsp), %xmm2
movq %rbx, %rdi
callq 0x3cfc6
movq %rbp, %rdi
movq %rbx, %rsi
leaq 0x8d5b1(%rip), %rdx     # 0xa8740
callq 0x3d8fa
leaq 0x260(%rsp), %rbx
movq %rbp, %rdi
callq 0x3d2dc
leaq 0x1c0(%rsp), %rdi
movq %r14, %rsi
movq %rbp, %rdx
callq 0x3b0b2
movq 0x18(%rsp), %rax
leaq 0x158(%rax), %rsi
leaq 0xd0(%rsp), %rdi
callq 0x3c542
movsd 0xd0(%rsp), %xmm0
movq 0xd8(%rsp), %xmm1
movq 0xe0(%rsp), %xmm2
leaq 0x380(%rsp), %r14
movq %r14, %rdi
callq 0x3cfc6
leaq 0x368(%rsp), %r12
movq %r12, %rdi
leaq 0x8d533(%rip), %rsi     # 0xa8740
movq %r14, %rdx
callq 0x3d8fa
movq %r12, %rdi
callq 0x3d2dc
leaq 0x1a0(%rsp), %rdi
leaq 0xd0(%rsp), %rsi
movq %r12, %rdx
callq 0x3b0b2
movq 0x10(%rsp), %rax
testb $0x4, 0xa8(%rax)
jne 0x1b256
movq 0x30(%rsp), %rdi
movq (%rdi), %rax
movq 0x10(%rsp), %rsi
callq *0x2c8(%rax)
movq 0x10(%rsp), %rax
leaq 0x38(%rax), %rsi
leaq 0x188(%rsp), %rdi
callq 0x3cfd6
movq 0x18(%rsp), %r12
addq $0x18, %r12
leaq 0x188(%rsp), %rdi
movq %r12, %rsi
callq 0x3db46
movq 0xc8(%rsp), %rax
movq %rax, 0x258(%rsp)
movq %rbx, %rdi
movq 0xc0(%rsp), %rsi
callq 0x2c2be
leaq 0x2e0(%rsp), %rdi
movq 0xb8(%rsp), %rsi
callq 0x2c2be
leaq 0xcad3f(%rip), %rax     # 0xe6000
movq 0x108(%rax), %rax
movq %rax, 0x360(%rsp)
leaq 0x150(%rsp), %rdi
movq %r13, %rsi
callq 0x3bb82
movsd 0x150(%rsp), %xmm0
movq 0x158(%rsp), %xmm1
movq 0x160(%rsp), %xmm2
leaq 0x100(%rsp), %rdi
callq 0x3cfc6
movq %rbx, %rdi
leaq 0x100(%rsp), %rsi
callq 0x2d3f8
andb $-0x3, 0x360(%rsp)
movq %rbx, %rdi
leaq 0x188(%rsp), %rsi
leaq 0x8d40e(%rip), %rdx     # 0xa8740
callq 0x2dbe4
andb $-0x3, 0x360(%rsp)
leaq 0x58(%rsp), %rdi
movq %r13, %rsi
callq 0x3bb82
movsd 0x58(%rsp), %xmm0
movq 0x60(%rsp), %xmm1
movq 0x68(%rsp), %xmm2
leaq 0x150(%rsp), %rdi
callq 0x3cfc6
leaq 0x100(%rsp), %rdi
leaq 0x150(%rsp), %rsi
callq 0x3dc00
movq %rbx, %rdi
leaq 0x100(%rsp), %rsi
callq 0x2d3f8
andb $-0x3, 0x360(%rsp)
leaq 0x258(%rsp), %rdi
movq %r12, %rsi
callq 0x2a196
movq 0x10(%rsp), %rax
leaq 0x28(%rax), %rbp
leaq 0x30(%rax), %rbx
movb $0x1, %r13b
movq 0x18(%rsp), %rax
movq 0x10(%rax), %rax
movq 0x10(%rsp), %rcx
movq 0x20(%rcx), %r14
cmpq %rax, %r14
je 0x1b3f1
movq (%rbp), %rcx
cmpq %rax, %rcx
je 0x1b3fe
testb $0x1, %r13b
cmovneq %r14, %rcx
cmpq %rax, (%rbx)
movl $0x0, %eax
cmovneq %rax, %rcx
movq %rcx, %r14
jmp 0x1b40a
testb $0x1, %r13b
movq %rbx, %rax
cmovneq %rbp, %rax
jmp 0x1b407
movq %rbx, %rax
testb $0x1, %r13b
je 0x1b40a
movq (%rax), %r14
movq 0x18(%r14), %rax
movq %rax, %rcx
cmpq 0x10(%rsp), %rax
jne 0x1b41c
movq 0x20(%r14), %rcx
movq %rcx, 0x8(%rsp)
testq %rcx, %rcx
je 0x1b79d
movq 0x18(%rsp), %rcx
movsd 0x178(%rcx), %xmm0
movslq 0x30(%r14), %rcx
ucomisd (%r15,%rcx,8), %xmm0
jae 0x1b79d
movq 0x8(%rsp), %rcx
movslq 0xa4(%rcx), %rcx
movq 0x20(%rsp), %rdx
ucomisd (%rdx,%rcx,8), %xmm0
jae 0x1b79d
xorl %ecx, %ecx
xorl %edx, %edx
cmpq 0x10(%rsp), %rax
setne %cl
sete %dl
movq 0x8(%r14,%rdx,8), %rsi
movq 0x8(%r14,%rcx,8), %r12
addq $0x18, %rsi
leaq 0x58(%rsp), %rdi
callq 0x3c542
addq $0x18, %r12
leaq 0x170(%rsp), %rdi
movq %r12, %rsi
callq 0x3c542
leaq 0x58(%rsp), %rdi
leaq 0x258(%rsp), %rsi
callq 0x3ce48
leaq 0x170(%rsp), %rdi
leaq 0x258(%rsp), %rsi
callq 0x3ce48
leaq 0x100(%rsp), %rdi
leaq 0x58(%rsp), %rsi
leaq 0x170(%rsp), %rdx
callq 0x3b9b6
leaq 0x210(%rsp), %r12
movq %r12, %rdi
leaq 0x118(%rsp), %rsi
callq 0x3cfd6
movq %r12, %rdi
callq 0x3d0cc
leaq 0xca692(%rip), %rax     # 0xe5b98
movsd (%rax), %xmm1
movapd %xmm1, %xmm2
xorpd 0x86b0a(%rip), %xmm2    # 0xa2020
ucomisd %xmm2, %xmm0
jb 0x1b526
ucomisd %xmm0, %xmm1
jae 0x1b79d
leaq 0x1f8(%rsp), %r12
movq %r12, %rdi
leaq 0x8d208(%rip), %rsi     # 0xa8740
leaq 0x210(%rsp), %rdx
callq 0x3d8fa
movq %r12, %rdi
callq 0x3d2dc
leaq 0x1e0(%rsp), %rdi
leaq 0x100(%rsp), %rsi
callq 0x3bb82
leaq 0x150(%rsp), %r12
movq %r12, %rdi
leaq 0x1e0(%rsp), %rsi
leaq 0x1f8(%rsp), %rdx
callq 0x3b0b2
movq %r12, %rdi
leaq 0x4cb4d4(%rip), %rsi    # 0x4e6a60
callq 0x49617
leaq 0xca600(%rip), %rax     # 0xe5b98
ucomisd (%rax), %xmm0
ja 0x1b79d
leaq 0x100(%rsp), %rdi
leaq 0x1c0(%rsp), %rsi
callq 0x3bef4
testl %eax, %eax
je 0x1b79d
leaq 0x100(%rsp), %rdi
leaq 0x1a0(%rsp), %rsi
callq 0x3bef4
testl %eax, %eax
je 0x1b79d
movq 0x18(%rsp), %rax
movsd 0x180(%rax), %xmm0
movsd %xmm0, 0x38(%rsp)
leaq 0x4cb46a(%rip), %rdi    # 0x4e6a60
leaq 0x100(%rsp), %rsi
callq 0x494e6
movsd 0x40(%rsp), %xmm1
ucomisd 0x86bd7(%rip), %xmm1    # 0xa21e8
movsd 0x38(%rsp), %xmm1
addsd %xmm0, %xmm1
movsd %xmm1, 0x38(%rsp)
jbe 0x1b635
movsd 0x38(%rsp), %xmm0
ucomisd 0x40(%rsp), %xmm0
ja 0x1b79d
movslq 0x30(%r14), %rax
movsd 0x38(%rsp), %xmm0
ucomisd (%r15,%rax,8), %xmm0
jae 0x1b79d
movq 0x8(%rsp), %rax
movslq 0xa4(%rax), %rax
movq 0x20(%rsp), %rcx
movsd 0x38(%rsp), %xmm0
ucomisd (%rcx,%rax,8), %xmm0
jae 0x1b79d
movl $0x190, %edi            # imm = 0x190
callq 0xe440
movq %rax, %r12
movl $0x190, %edx            # imm = 0x190
movq %rax, %rdi
xorl %esi, %esi
callq 0xe260
leaq 0x18(%r12), %rdi
movq %rdi, 0xb0(%rsp)
callq 0x29f8c
leaq 0x128(%r12), %rdi
movq %rdi, 0x8(%rsp)
callq 0x3b8e0
movq 0x18(%rsp), %rax
movq (%rax), %rax
movq %rax, (%r12)
movq 0x10(%rsp), %rax
movq %rax, 0x8(%r12)
movq %r14, 0x10(%r12)
leaq 0x20(%r12), %rdi
leaq 0x260(%rsp), %rsi
callq 0x2dea2
leaq 0xa0(%r12), %rdi
leaq 0x2e0(%rsp), %rsi
callq 0x2dea2
movq 0x360(%rsp), %rax
movq %rax, 0x120(%r12)
movq 0x8(%rsp), %rdi
leaq 0x100(%rsp), %rsi
callq 0x3c89a
leaq 0x140(%r12), %rdi
leaq 0x118(%rsp), %rsi
callq 0x3d752
movq %r12, %rdi
addq $0x158, %rdi            # imm = 0x158
leaq 0x130(%rsp), %rsi
callq 0x3c89a
movsd 0x148(%rsp), %xmm0
movsd %xmm0, 0x170(%r12)
movsd 0x38(%rsp), %xmm0
movsd %xmm0, 0x178(%r12)
movq 0x18(%rsp), %rax
movsd 0x180(%rax), %xmm0
movsd %xmm0, 0x180(%r12)
movq %rax, 0x188(%r12)
leaq 0x70(%rsp), %rdi
movq %r12, %rsi
callq 0x242d0
movl 0x54(%rsp), %edx
leaq 0x48(%rsp), %rdi
movq %r12, %rsi
callq 0x6f8a2
testb $0x1, %r13b
movl $0x0, %r13d
jne 0x1b3b8
xorl %r13d, %r13d
movq 0x10(%rsp), %rax
movq 0x8(%rax,%r13,8), %r12
leaq 0x18(%r12), %rsi
leaq 0x100(%rsp), %r14
movq %r14, %rdi
callq 0x3c542
movq %r14, %rdi
leaq 0x258(%rsp), %rsi
callq 0x3ce48
leaq 0x1c0(%rsp), %rdi
movq %r14, %rsi
callq 0x49617
pxor %xmm1, %xmm1
ucomisd %xmm0, %xmm1
jbe 0x1b828
leaq 0x4cb260(%rip), %rdi    # 0x4e6a60
leaq 0xe8(%rsp), %r14
movq %r14, %rsi
callq 0x49404
movsd %xmm0, 0x8(%rsp)
movq %r14, %rdi
leaq 0x100(%rsp), %rsi
callq 0x49404
jmp 0x1b874
leaq 0x1a0(%rsp), %rdi
leaq 0x100(%rsp), %rsi
callq 0x49617
xorpd %xmm1, %xmm1
ucomisd %xmm0, %xmm1
jbe 0x1b893
leaq 0x4cb212(%rip), %rdi    # 0x4e6a60
leaq 0xd0(%rsp), %r14
movq %r14, %rsi
callq 0x49404
movsd %xmm0, 0x8(%rsp)
movq %r14, %rdi
leaq 0x100(%rsp), %rsi
callq 0x49404
movq 0x18(%rsp), %rax
movsd 0x8(%rsp), %xmm1
addsd 0x180(%rax), %xmm1
addsd %xmm1, %xmm0
movb $0x1, %cl
movapd %xmm0, %xmm1
jmp 0x1b8c6
movq 0x18(%rsp), %rax
movsd 0x180(%rax), %xmm0
movsd %xmm0, 0x8(%rsp)
leaq 0x4cb1b3(%rip), %rdi    # 0x4e6a60
leaq 0x100(%rsp), %rsi
callq 0x49404
movsd 0x8(%rsp), %xmm1
addsd %xmm0, %xmm1
xorl %ecx, %ecx
movslq 0x70(%r12), %rax
movq 0x28(%rsp), %rdx
movsd (%rdx,%rax,8), %xmm0
movsd %xmm1, 0x8(%rsp)
ucomisd %xmm1, %xmm0
jbe 0x1bb53
movq 0x28(%rsp), %rdx
movsd 0x8(%rsp), %xmm1
movsd %xmm1, (%rdx,%rax,8)
movq 0x18(%rsp), %rax
movq 0x10(%rax), %rax
movq 0x10(%rsp), %rdx
movq 0x20(%rdx), %rsi
movb $0x1, %dl
cmpq %rax, %rsi
je 0x1b92d
movq (%rbp), %rdi
cmpq %rax, %rdi
je 0x1b939
testb $0x1, %dl
cmovneq %rsi, %rdi
cmpq %rax, (%rbx)
movl $0x0, %r8d
cmovneq %r8, %rdi
jmp 0x1b947
testb $0x1, %dl
movq %rbx, %r8
cmovneq %rbp, %r8
jmp 0x1b944
movq %rbx, %r8
movq %rsi, %rdi
testb $0x1, %dl
je 0x1b947
movq (%r8), %rdi
movslq 0x30(%rdi), %r8
movsd (%r15,%r8,8), %xmm1
ucomisd 0x8(%rsp), %xmm1
jbe 0x1b989
movq 0x8(%rdi), %r9
cmpq %r12, %r9
jne 0x1b966
movq 0x10(%rdi), %r9
movslq 0x70(%r9), %rdi
movq 0x28(%rsp), %r9
movsd 0x8(%rsp), %xmm1
ucomisd (%r9,%rdi,8), %xmm1
jbe 0x1b989
movsd 0x8(%rsp), %xmm1
movsd %xmm1, (%r15,%r8,8)
testb $0x1, %dl
movl $0x0, %edx
jne 0x1b909
movq 0x10(%rsp), %rdx
movslq 0xa4(%rdx), %rdx
movq 0x20(%rsp), %rdi
movsd (%rdi,%rdx,8), %xmm1
ucomisd 0x8(%rsp), %xmm1
jbe 0x1ba84
movq 0x10(%rsp), %r9
cmpq %r12, 0x8(%r9)
je 0x1b9e8
cmpq %r12, 0x10(%r9)
je 0x1b9ef
cmpq %r12, 0x18(%r9)
je 0x1ba0e
xorl %esi, %esi
cmpq %r9, 0x18
sete %sil
leaq 0x8(,%rsi,8), %rsi
jmp 0x1ba24
movl $0x30, %edi
jmp 0x1b9f8
movq 0x28(%r9), %rsi
movl $0x20, %edi
xorl %r8d, %r8d
cmpq %r9, 0x18(%rsi)
sete %r8b
movq 0x8(%rsi,%r8,8), %rsi
movq (%r9,%rdi), %rdi
jmp 0x1ba33
movq 0x30(%r9), %rsi
xorl %edi, %edi
cmpq %r9, 0x18(%rsi)
sete %dil
leaq (%rsi,%rdi,8), %rsi
addq $0x8, %rsi
movq (%rsi), %rsi
cmpq %r12, 0x18(%r9)
je 0x1bad5
xorl %edi, %edi
movslq 0x70(%rsi), %rsi
movq 0x28(%rsp), %r8
movsd 0x8(%rsp), %xmm1
ucomisd (%r8,%rsi,8), %xmm1
jbe 0x1ba84
xorl %esi, %esi
movq 0x10(%rsp), %r8
cmpq %r8, 0x18(%rdi)
setne %sil
movq 0x8(%rdi,%rsi,8), %rsi
movslq 0x70(%rsi), %rsi
movq 0x28(%rsp), %rdi
movsd 0x8(%rsp), %xmm1
ucomisd (%rdi,%rsi,8), %xmm1
jbe 0x1ba84
movq 0x20(%rsp), %rsi
movsd 0x8(%rsp), %xmm1
movsd %xmm1, (%rsi,%rdx,8)
testb %cl, %cl
jne 0x1bb53
movq 0x10(%rsp), %rcx
movq 0x8(%rcx), %rcx
movq 0x8(%rax), %rdx
cmpq %rcx, %rdx
je 0x1baa4
cmpq %rcx, 0x10(%rax)
jne 0x1bae6
movq 0x10(%rsp), %rcx
movq 0x10(%rcx), %rcx
cmpq %rcx, %rdx
je 0x1bab8
cmpq %rcx, 0x10(%rax)
jne 0x1bae6
movq 0x10(%rsp), %rcx
movq 0x18(%rcx), %rsi
cmpq %rsi, %rdx
je 0x1bae4
cmpq %rsi, 0x10(%rax)
movl $0x0, %ecx
cmovneq %rsi, %rcx
jmp 0x1bae6
movl $0x28, %edi
movq 0x10(%rsp), %r9
jmp 0x1ba08
xorl %ecx, %ecx
cmpq %rcx, %r12
jne 0x1bb53
movsd 0x8(%rsp), %xmm1
subsd %xmm0, %xmm1
leaq 0xca09c(%rip), %rax     # 0xe5b98
movsd (%rax), %xmm0
xorpd 0x86518(%rip), %xmm0    # 0xa2020
ucomisd %xmm1, %xmm0
jbe 0x1bb53
movq 0x30(%rsp), %rdi
movq %r12, %rsi
callq 0x1c0c5
testl %eax, %eax
je 0x1bb53
leaq 0x48(%rsp), %rax
movq %rax, (%rsp)
movq 0x30(%rsp), %rdi
movq %r12, %rsi
movsd 0x40(%rsp), %xmm0
movsd 0x8(%rsp), %xmm1
movq 0x18(%rsp), %rdx
movq %r15, %rcx
movq 0x20(%rsp), %r8
leaq 0x70(%rsp), %r9
callq 0x1bcdc
incq %r13
cmpq $0x3, %r13
jne 0x1b7b0
leaq 0x258(%rsp), %rdi
callq 0x2a028
leaq 0x70(%rsp), %r14
leaq 0xe8(%rsp), %r12
leaq 0x240(%rsp), %rbx
leaq 0x228(%rsp), %rbp
cmpl $0x0, 0x78(%rsp)
jne 0x1b0c1
cmpl $0x0, 0x54(%rsp)
jle 0x1bbd0
xorl %r14d, %r14d
movq 0x48(%rsp), %rax
movq (%rax,%r14,8), %rbx
testq %rbx, %rbx
je 0x1bbb6
leaq 0x18(%rbx), %rdi
callq 0x2a028
movl $0x190, %esi            # imm = 0x190
movq %rbx, %rdi
callq 0xe450
incq %r14
movslq 0x54(%rsp), %rax
cmpq %rax, %r14
jl 0x1bb9f
movq %r15, %rdi
callq 0xe5b0
movq 0x20(%rsp), %rdi
callq 0xe5b0
leaq 0x48(%rsp), %rdi
callq 0x6f876
movq 0x70(%rsp), %rdi
testq %rdi, %rdi
je 0x1bbfb
callq 0xe5b0
leaq 0x3b0(%rsp), %rdi
callq 0x2a028
movq 0x28(%rsp), %rax
addq $0x528, %rsp            # imm = 0x528
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
movq 0xb0(%rsp), %rdi
callq 0x2a028
jmp 0x1bc34
movq %rax, %rbx
movl $0x190, %esi            # imm = 0x190
movq %r12, %rdi
callq 0xe450
jmp 0x1bca1
jmp 0x1bc97
movq %rax, %rbx
jmp 0x1bcb8
movq %rax, %rbx
jmp 0x1bcc7
jmp 0x1bc9e
jmp 0x1bc9e
jmp 0x1bc97
jmp 0x1bc97
jmp 0x1bc97
jmp 0x1bc97
jmp 0x1bc97
jmp 0x1bc97
jmp 0x1bc97
movq %rax, %rbx
leaq 0x258(%rsp), %rdi
callq 0x2a6bc
jmp 0x1bcae
jmp 0x1bc97
jmp 0x1bc9e
jmp 0x1bc9e
jmp 0x1bc97
jmp 0x1bc9e
jmp 0x1bc9e
jmp 0x1bc9e
jmp 0x1bc9e
jmp 0x1bc9e
jmp 0x1bc9e
jmp 0x1bc9e
jmp 0x1bc9e
jmp 0x1bc9e
jmp 0x1bc97
jmp 0x1bc9e
jmp 0x1bc9e
jmp 0x1bc9e
jmp 0x1bc9e
movq %rax, %rbx
jmp 0x1bcae
jmp 0x1bc9e
movq %rax, %rbx
leaq 0x258(%rsp), %rdi
callq 0x2a028
leaq 0x48(%rsp), %rdi
callq 0x6f876
movq 0x70(%rsp), %rdi
testq %rdi, %rdi
je 0x1bcc7
callq 0xe5b0
leaq 0x3b0(%rsp), %rdi
callq 0x2a028
movq %rbx, %rdi
callq 0xe7e0