// File: isovic[P]cigargen/cigargen.cc
// Function: GenerateCigar(char*, unsigned int, char*, unsigned int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*, unsigned int*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>*)
int32_t GenerateCigar(char *query, uint32_t query_length, char *reference, uint32_t reference_length, std::string *ret_cigar, uint32_t *ret_alignment_length, std::string *ret_alignment) {
  if (query == NULL || reference == NULL || query_length == 0 || reference_length == 0)
    return -1;

  // Preallocate the memory for the DP matrix and traceback, and initialize all values to 0.
  std::vector<std::vector<int32_t> > dp_matrix((query_length + 1), std::vector<int32_t>((reference_length + 1), 0));
  std::vector<std::vector<uint8_t> > dp_traceback((query_length + 1), std::vector<uint8_t>((reference_length + 1), 0));
  // Temporary variables for storing the options for the current step. (Could have been done differently, but increases readability.)
  int32_t up=0, left=0, diagonal=0;

  // Initialize the first row and column according to Needleman-Wunsch.
  for (uint32_t i=0; i<=query_length; i++)
    dp_matrix[i][0] = i * PENALTY_INSERTION;
  for (uint32_t i=0; i<=reference_length; i++)
    dp_matrix[0][i] = i * PENALTY_DELETION;

  int32_t max_score_index = 0;

  for (uint32_t i=1; i<=query_length; i++) {
    for (uint32_t j=1; j<=reference_length; j++) {
      // Calculate the options for the current value of the DP matrix.
      up = dp_matrix[i-1][j] + PENALTY_INSERTION;
      left = dp_matrix[i][j-1] + PENALTY_DELETION;
      diagonal = dp_matrix[i-1][j-1] + ((query[i-1] == reference[j-1]) ? PENALTY_MATCH : PENALTY_MISMATCH);

      // Find the maximum of the three values.
      dp_matrix[i][j] = diagonal;
      dp_traceback[i][j] = ((query[i-1] == reference[j-1])?0:1);
      if (up > dp_matrix[i][j]) {
        dp_matrix[i][j] = up;
        dp_traceback[i][j] = 2;
      }
      if (left > dp_matrix[i][j]) {
        dp_matrix[i][j] = left;
        dp_traceback[i][j] = 3;
      }

      // If this is the last row of the matrix, we need to look up for the maximum score. This will be our starting point for the
      // CIGAR traceback calculation.
      if (i == query_length && dp_matrix[query_length][j] > dp_matrix[query_length][max_score_index])
        max_score_index = j;
    }
  }

  // Initialize the traceback column to the index of the highest score, and the traceback row to the last row of the matrix.
  int32_t current_traceback_row = query_length, current_traceback_column = max_score_index;

  std::stringstream cigar_stream;
  std::string cigar = "";
  std::string alignment = "";
  uint32_t edit_distance = 0;

  // Traceback: Find the CIGAR string.
  uint32_t iterations=0, num_insertions=0, type=0, last_type=0, num_same_types=0;
  while (current_traceback_column > 0 && current_traceback_row > 0) {
    type = dp_traceback[current_traceback_row][current_traceback_column];

    // Count the number of same transitions in the DP matrix (whether if it was to the left, right or up.)
    if (iterations == 0) {
      // If this is the first traceback step, initialize the last type for counting.
      last_type = type;
      num_same_types = 1;
    }
    else {
      if (type == last_type) {
        // If types of transition are the same, just count them.
        num_same_types += 1;
      }
      else {
        // If the type has changed, stream the CIGAR count, and reset the type to the current one.
        cigar_stream << TypeToSymbol(last_type) << num_same_types;
        last_type = type;
        num_same_types = 1;
      }
    }

    if (type != TYPE_MATCH)
      edit_distance += 1;

    // Accumulate the characters for the alignment, but only if this was asked for (that's why there is
    // the NULL testing). We insert a special character '+' in this implementation, which represents that
    // there was an insertion on the reference (one character was removed from the query).
    // Character '-' represents the deletion in the reference (or an insertion on the query).
    if (ret_alignment != NULL)
        alignment +=  ((type == TYPE_DELETION) ? '-' :
                      ((type == TYPE_MATCH) ? query[current_traceback_row - 1] :
                      ((type == TYPE_INSERTION) ? '+' :
                      'x')));

    if (type == TYPE_INSERTION)
      num_insertions += 1;

    // Row changes in all cases except when a deletion occurs (type == 3).
    current_traceback_row -= (type != TYPE_DELETION) ? 1 : 0;
    // Column changes in all cases except when an insertion occurs (type == 2).
    current_traceback_column -= (type != TYPE_INSERTION) ? 1 : 0;

    // Count the traceback length.
    iterations += 1;
  }

  // Stream the remaining count to the CIGAR stream.
  cigar_stream << TypeToSymbol(last_type) << num_same_types;
  cigar = cigar_stream.str();
  std::reverse(cigar.begin(), cigar.end());
  std::reverse(alignment.begin(), alignment.end());

  if (ret_cigar != NULL)
    *ret_cigar = cigar;
  else
    Verbose(stdout, query, query_length, reference, reference_length, cigar, dp_matrix, dp_traceback);

  // Return the final alignment length. We need to subtract the number of insertions on the reference because the final
  // alignment should be shorter than the traceback for this amount.
  if (ret_alignment_length != NULL)
    *ret_alignment_length = (iterations - num_insertions);

  // Return the final alignment if required. The alignment.size() value is larger than ret_alignment_length, because
  // query deletions have not been completely removed, but changed with a special character.
  if (ret_alignment != NULL)
    *ret_alignment = alignment;

  return edit_distance;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x3f0, %rsp            # imm = 0x3F0
movq 0x10(%rbp), %rax
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movq %rdx, -0x20(%rbp)
movl %ecx, -0x24(%rbp)
movq %r8, -0x30(%rbp)
movq %r9, -0x38(%rbp)
cmpq $0x0, -0x10(%rbp)
je 0x2a2f
cmpq $0x0, -0x20(%rbp)
je 0x2a2f
cmpl $0x0, -0x14(%rbp)
je 0x2a2f
cmpl $0x0, -0x24(%rbp)
jne 0x2a3b
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x35e6
movl -0x14(%rbp), %eax
incl %eax
movq %rax, -0x328(%rbp)
movl -0x24(%rbp), %eax
incl %eax
movq %rax, -0x320(%rbp)
movl $0x0, -0x6c(%rbp)
leaq -0x6d(%rbp), %rdi
movq %rdi, -0x318(%rbp)
callq 0x3940
movq -0x320(%rbp), %rsi
movq -0x318(%rbp), %rcx
leaq -0x68(%rbp), %rdi
leaq -0x6c(%rbp), %rdx
callq 0x3960
jmp 0x2a87
leaq -0x7d(%rbp), %rdi
movq %rdi, -0x330(%rbp)
callq 0x39e0
movq -0x328(%rbp), %rsi
movq -0x330(%rbp), %rcx
leaq -0x50(%rbp), %rdi
leaq -0x68(%rbp), %rdx
callq 0x3a00
jmp 0x2ab4
leaq -0x7d(%rbp), %rdi
callq 0x3a80
leaq -0x68(%rbp), %rdi
callq 0x3aa0
leaq -0x6d(%rbp), %rdi
callq 0x3b00
movl -0x14(%rbp), %eax
incl %eax
movq %rax, -0x348(%rbp)
movl -0x24(%rbp), %eax
incl %eax
movq %rax, -0x340(%rbp)
movb $0x0, -0xb1(%rbp)
leaq -0xb2(%rbp), %rdi
movq %rdi, -0x338(%rbp)
callq 0x3b20
movq -0x340(%rbp), %rsi
movq -0x338(%rbp), %rcx
leaq -0xb0(%rbp), %rdi
leaq -0xb1(%rbp), %rdx
callq 0x3b40
jmp 0x2b24
leaq -0xb3(%rbp), %rdi
movq %rdi, -0x350(%rbp)
callq 0x3bc0
movq -0x348(%rbp), %rsi
movq -0x350(%rbp), %rcx
leaq -0x98(%rbp), %rdi
leaq -0xb0(%rbp), %rdx
callq 0x3be0
jmp 0x2b5a
leaq -0xb3(%rbp), %rdi
callq 0x3c60
leaq -0xb0(%rbp), %rdi
callq 0x3c80
leaq -0xb2(%rbp), %rdi
callq 0x3ce0
movl $0x0, -0xb8(%rbp)
movl $0x0, -0xbc(%rbp)
movl $0x0, -0xc0(%rbp)
movl $0x0, -0xc4(%rbp)
movl -0xc4(%rbp), %eax
cmpl -0x14(%rbp), %eax
ja 0x2c75
imull $-0x6, -0xc4(%rbp), %eax
movl %eax, -0x354(%rbp)
movl -0xc4(%rbp), %eax
movl %eax, %esi
leaq -0x50(%rbp), %rdi
callq 0x3d00
movq %rax, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x3d20
movl -0x354(%rbp), %ecx
movl %ecx, (%rax)
movl -0xc4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xc4(%rbp)
jmp 0x2ba6
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
jmp 0x2c24
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
leaq -0x7d(%rbp), %rdi
callq 0x3a80
leaq -0x68(%rbp), %rdi
callq 0x3aa0
leaq -0x6d(%rbp), %rdi
callq 0x3b00
jmp 0x35f2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
jmp 0x2c64
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
leaq -0xb3(%rbp), %rdi
callq 0x3c60
leaq -0xb0(%rbp), %rdi
callq 0x3c80
leaq -0xb2(%rbp), %rdi
callq 0x3ce0
jmp 0x35db
movl $0x0, -0xc8(%rbp)
movl -0xc8(%rbp), %eax
cmpl -0x24(%rbp), %eax
ja 0x2ccd
imull $-0x6, -0xc8(%rbp), %eax
movl %eax, -0x358(%rbp)
leaq -0x50(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x3d00
movq %rax, %rdi
movl -0xc8(%rbp), %eax
movl %eax, %esi
callq 0x3d20
movl -0x358(%rbp), %ecx
movl %ecx, (%rax)
movl -0xc8(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xc8(%rbp)
jmp 0x2c7f
movl $0x0, -0xcc(%rbp)
movl $0x1, -0xd0(%rbp)
movl -0xd0(%rbp), %eax
cmpl -0x14(%rbp), %eax
ja 0x302d
movl $0x1, -0xd4(%rbp)
movl -0xd4(%rbp), %eax
cmpl -0x24(%rbp), %eax
ja 0x3017
movl -0xd0(%rbp), %eax
subl $0x1, %eax
movl %eax, %eax
movl %eax, %esi
leaq -0x50(%rbp), %rdi
callq 0x3d00
movq %rax, %rdi
movl -0xd4(%rbp), %eax
movl %eax, %esi
callq 0x3d20
movl (%rax), %eax
addl $-0x6, %eax
movl %eax, -0xb8(%rbp)
movl -0xd0(%rbp), %eax
movl %eax, %esi
leaq -0x50(%rbp), %rdi
callq 0x3d00
movq %rax, %rdi
movl -0xd4(%rbp), %eax
subl $0x1, %eax
movl %eax, %eax
movl %eax, %esi
callq 0x3d20
movl (%rax), %eax
addl $-0x6, %eax
movl %eax, -0xbc(%rbp)
movl -0xd0(%rbp), %eax
subl $0x1, %eax
movl %eax, %eax
movl %eax, %esi
leaq -0x50(%rbp), %rdi
callq 0x3d00
movq %rax, %rdi
movl -0xd4(%rbp), %eax
subl $0x1, %eax
movl %eax, %eax
movl %eax, %esi
callq 0x3d20
movl (%rax), %eax
movq -0x10(%rbp), %rcx
movl -0xd0(%rbp), %edx
subl $0x1, %edx
movl %edx, %edx
movsbl (%rcx,%rdx), %esi
movq -0x20(%rbp), %rcx
movl -0xd4(%rbp), %edx
subl $0x1, %edx
movl %edx, %edx
movsbl (%rcx,%rdx), %edi
movl $0xfffffffe, %ecx       # imm = 0xFFFFFFFE
movl $0x5, %edx
cmpl %edi, %esi
cmovel %edx, %ecx
addl %ecx, %eax
movl %eax, -0xc0(%rbp)
movl -0xc0(%rbp), %eax
movl %eax, -0x364(%rbp)
movl -0xd0(%rbp), %eax
movl %eax, %esi
leaq -0x50(%rbp), %rdi
callq 0x3d00
movq %rax, %rdi
movl -0xd4(%rbp), %eax
movl %eax, %esi
callq 0x3d20
movl -0x364(%rbp), %ecx
movl %ecx, (%rax)
movq -0x10(%rbp), %rax
movl -0xd0(%rbp), %ecx
subl $0x1, %ecx
movl %ecx, %ecx
movsbl (%rax,%rcx), %edx
movq -0x20(%rbp), %rax
movl -0xd4(%rbp), %ecx
subl $0x1, %ecx
movl %ecx, %ecx
movsbl (%rax,%rcx), %esi
movl $0x1, %eax
xorl %ecx, %ecx
cmpl %esi, %edx
cmovel %ecx, %eax
movb %al, -0x35d(%rbp)
movl -0xd0(%rbp), %eax
movl %eax, %esi
leaq -0x98(%rbp), %rdi
callq 0x3d40
movq %rax, %rdi
movl -0xd4(%rbp), %eax
movl %eax, %esi
callq 0x3d60
movb -0x35d(%rbp), %cl
movb %cl, (%rax)
movl -0xb8(%rbp), %eax
movl %eax, -0x35c(%rbp)
movl -0xd0(%rbp), %eax
movl %eax, %esi
leaq -0x50(%rbp), %rdi
callq 0x3d00
movq %rax, %rdi
movl -0xd4(%rbp), %eax
movl %eax, %esi
callq 0x3d20
movq %rax, %rcx
movl -0x35c(%rbp), %eax
cmpl (%rcx), %eax
jle 0x2f04
movl -0xb8(%rbp), %eax
movl %eax, -0x368(%rbp)
movl -0xd0(%rbp), %eax
movl %eax, %esi
leaq -0x50(%rbp), %rdi
callq 0x3d00
movq %rax, %rdi
movl -0xd4(%rbp), %eax
movl %eax, %esi
callq 0x3d20
movl -0x368(%rbp), %ecx
movl %ecx, (%rax)
movl -0xd0(%rbp), %eax
movl %eax, %esi
leaq -0x98(%rbp), %rdi
callq 0x3d40
movq %rax, %rdi
movl -0xd4(%rbp), %eax
movl %eax, %esi
callq 0x3d60
movb $0x2, (%rax)
movl -0xbc(%rbp), %eax
movl %eax, -0x36c(%rbp)
movl -0xd0(%rbp), %eax
movl %eax, %esi
leaq -0x50(%rbp), %rdi
callq 0x3d00
movq %rax, %rdi
movl -0xd4(%rbp), %eax
movl %eax, %esi
callq 0x3d20
movq %rax, %rcx
movl -0x36c(%rbp), %eax
cmpl (%rcx), %eax
jle 0x2f9a
movl -0xbc(%rbp), %eax
movl %eax, -0x370(%rbp)
movl -0xd0(%rbp), %eax
movl %eax, %esi
leaq -0x50(%rbp), %rdi
callq 0x3d00
movq %rax, %rdi
movl -0xd4(%rbp), %eax
movl %eax, %esi
callq 0x3d20
movl -0x370(%rbp), %ecx
movl %ecx, (%rax)
movl -0xd0(%rbp), %eax
movl %eax, %esi
leaq -0x98(%rbp), %rdi
callq 0x3d40
movq %rax, %rdi
movl -0xd4(%rbp), %eax
movl %eax, %esi
callq 0x3d60
movb $0x3, (%rax)
movl -0xd0(%rbp), %eax
cmpl -0x14(%rbp), %eax
jne 0x3001
movl -0x14(%rbp), %eax
movl %eax, %esi
leaq -0x50(%rbp), %rdi
callq 0x3d00
movq %rax, %rdi
movl -0xd4(%rbp), %eax
movl %eax, %esi
callq 0x3d20
movl (%rax), %eax
movl %eax, -0x374(%rbp)
movl -0x14(%rbp), %eax
movl %eax, %esi
leaq -0x50(%rbp), %rdi
callq 0x3d00
movq %rax, %rdi
movslq -0xcc(%rbp), %rsi
callq 0x3d20
movq %rax, %rcx
movl -0x374(%rbp), %eax
cmpl (%rcx), %eax
jle 0x3001
movl -0xd4(%rbp), %eax
movl %eax, -0xcc(%rbp)
jmp 0x3003
movl -0xd4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xd4(%rbp)
jmp 0x2cfa
jmp 0x3019
movl -0xd0(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xd0(%rbp)
jmp 0x2ce1
movl -0x14(%rbp), %eax
movl %eax, -0xd8(%rbp)
movl -0xcc(%rbp), %eax
movl %eax, -0xdc(%rbp)
leaq -0x268(%rbp), %rdi
callq 0x2120
jmp 0x3050
leaq -0x289(%rbp), %rdi
movq %rdi, -0x380(%rbp)
callq 0x22a0
movq -0x380(%rbp), %rdx
leaq 0x406c(%rip), %rsi      # 0x70dd
leaq -0x288(%rbp), %rdi
callq 0x26a0
jmp 0x307f
leaq -0x289(%rbp), %rdi
callq 0x21d0
leaq -0x2b1(%rbp), %rdi
movq %rdi, -0x388(%rbp)
callq 0x22a0
movq -0x388(%rbp), %rdx
leaq 0x4031(%rip), %rsi      # 0x70dd
leaq -0x2b0(%rbp), %rdi
callq 0x26a0
jmp 0x30ba
leaq -0x2b1(%rbp), %rdi
callq 0x21d0
movl $0x0, -0x2b8(%rbp)
movl $0x0, -0x2bc(%rbp)
movl $0x0, -0x2c0(%rbp)
movl $0x0, -0x2c4(%rbp)
movl $0x0, -0x2c8(%rbp)
movl $0x0, -0x2cc(%rbp)
xorl %eax, %eax
cmpl $0x0, -0xdc(%rbp)
movb %al, -0x389(%rbp)
jle 0x3123
cmpl $0x0, -0xd8(%rbp)
setg %al
movb %al, -0x389(%rbp)
movb -0x389(%rbp), %al
testb $0x1, %al
jne 0x3132
jmp 0x33b6
movslq -0xd8(%rbp), %rsi
leaq -0x98(%rbp), %rdi
callq 0x3d40
movq %rax, %rdi
movslq -0xdc(%rbp), %rsi
callq 0x3d60
movzbl (%rax), %eax
movl %eax, -0x2c4(%rbp)
cmpl $0x0, -0x2bc(%rbp)
jne 0x31cc
movl -0x2c4(%rbp), %eax
movl %eax, -0x2c8(%rbp)
movl $0x1, -0x2cc(%rbp)
jmp 0x3296
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
jmp 0x35cf
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
leaq -0x289(%rbp), %rdi
callq 0x21d0
jmp 0x35c3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
leaq -0x2b1(%rbp), %rdi
callq 0x21d0
jmp 0x35b7
movl -0x2c4(%rbp), %eax
cmpl -0x2c8(%rbp), %eax
jne 0x31ee
movl -0x2cc(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2cc(%rbp)
jmp 0x3294
leaq -0x268(%rbp), %rax
addq $0x10, %rax
movq %rax, -0x398(%rbp)
cmpl $0x4, -0x2c8(%rbp)
jae 0x3223
movl -0x2c8(%rbp), %eax
movl %eax, %ecx
leaq 0x3ef7(%rip), %rax      # 0x710f
movb (%rax,%rcx), %al
movb %al, -0x399(%rbp)
jmp 0x322d
movb $0x58, %al
movb %al, -0x399(%rbp)
jmp 0x322d
movq -0x398(%rbp), %rdi
movb -0x399(%rbp), %al
movsbl %al, %esi
callq 0x2200
movq %rax, -0x3a8(%rbp)
jmp 0x324b
movq -0x3a8(%rbp), %rdi
movl -0x2cc(%rbp), %esi
callq 0x2230
jmp 0x325f
movl -0x2c4(%rbp), %eax
movl %eax, -0x2c8(%rbp)
movl $0x1, -0x2cc(%rbp)
jmp 0x3294
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x78(%rbp)
movl %eax, -0x7c(%rbp)
leaq -0x2b0(%rbp), %rdi
callq 0x20e0
jmp 0x35b7
jmp 0x3296
cmpl $0x0, -0x2c4(%rbp)
je 0x32ae
movl -0x2b8(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2b8(%rbp)
cmpq $0x0, 0x10(%rbp)
je 0x3348
cmpl $0x3, -0x2c4(%rbp)
jne 0x32cc
movb $0x2d, %al
movb %al, -0x3a9(%rbp)
jmp 0x332f
cmpl $0x0, -0x2c4(%rbp)
jne 0x32f0
movq -0x10(%rbp), %rax
movl -0xd8(%rbp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
movb (%rax,%rcx), %al
movb %al, -0x3aa(%rbp)
jmp 0x3323
movl -0x2c4(%rbp), %ecx
movb $0x2b, %al
movb $0x78, %dl
movb %dl, -0x3ac(%rbp)
cmpl $0x2, %ecx
movb %al, -0x3ab(%rbp)
je 0x3317
movb -0x3ac(%rbp), %al
movb %al, -0x3ab(%rbp)
movb -0x3ab(%rbp), %al
movb %al, -0x3aa(%rbp)
movb -0x3aa(%rbp), %al
movb %al, -0x3a9(%rbp)
movb -0x3a9(%rbp), %al
movsbl %al, %esi
leaq -0x2b0(%rbp), %rdi
callq 0x20f0
jmp 0x3346
jmp 0x3348
cmpl $0x2, -0x2c4(%rbp)
jne 0x3360
movl -0x2c0(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c0(%rbp)
movl -0x2c4(%rbp), %edx
xorl %ecx, %ecx
movl $0x1, %eax
cmpl $0x3, %edx
cmovnel %eax, %ecx
movl -0xd8(%rbp), %eax
subl %ecx, %eax
movl %eax, -0xd8(%rbp)
movl -0x2c4(%rbp), %edx
xorl %ecx, %ecx
movl $0x1, %eax
cmpl $0x2, %edx
cmovnel %eax, %ecx
movl -0xdc(%rbp), %eax
subl %ecx, %eax
movl %eax, -0xdc(%rbp)
movl -0x2bc(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2bc(%rbp)
jmp 0x3102
leaq -0x268(%rbp), %rax
addq $0x10, %rax
movq %rax, -0x3b8(%rbp)
cmpl $0x4, -0x2c8(%rbp)
jae 0x33eb
movl -0x2c8(%rbp), %eax
movl %eax, %ecx
leaq 0x3d2f(%rip), %rax      # 0x710f
movb (%rax,%rcx), %al
movb %al, -0x3b9(%rbp)
jmp 0x33f5
movb $0x58, %al
movb %al, -0x3b9(%rbp)
jmp 0x33f5
movq -0x3b8(%rbp), %rdi
movb -0x3b9(%rbp), %al
movsbl %al, %esi
callq 0x2200
movq %rax, -0x3c8(%rbp)
jmp 0x3413
movq -0x3c8(%rbp), %rdi
movl -0x2cc(%rbp), %esi
callq 0x2230
jmp 0x3427
leaq -0x2f0(%rbp), %rdi
leaq -0x268(%rbp), %rsi
callq 0x2190
jmp 0x343c
leaq -0x288(%rbp), %rdi
movq %rdi, -0x3d0(%rbp)
leaq -0x2f0(%rbp), %rsi
movq %rsi, -0x3d8(%rbp)
callq 0x2210
movq -0x3d8(%rbp), %rdi
callq 0x20e0
movq -0x3d0(%rbp), %rdi
callq 0x2180
movq -0x3d0(%rbp), %rdi
movq %rax, -0x2f8(%rbp)
callq 0x20d0
movq %rax, -0x300(%rbp)
movq -0x2f8(%rbp), %rdi
movq -0x300(%rbp), %rsi
callq 0x3d80
jmp 0x34a4
leaq -0x2b0(%rbp), %rdi
movq %rdi, -0x3e0(%rbp)
callq 0x2180
movq -0x3e0(%rbp), %rdi
movq %rax, -0x308(%rbp)
callq 0x20d0
movq %rax, -0x310(%rbp)
movq -0x308(%rbp), %rdi
movq -0x310(%rbp), %rsi
callq 0x3d80
jmp 0x34e6
cmpq $0x0, -0x30(%rbp)
je 0x3501
movq -0x30(%rbp), %rdi
leaq -0x288(%rbp), %rsi
callq 0x2030
jmp 0x34ff
jmp 0x353f
movq 0x7ac8(%rip), %rax      # 0xafd0
movq (%rax), %rdi
movq -0x10(%rbp), %rsi
movl -0x14(%rbp), %edx
movq -0x20(%rbp), %rcx
movl -0x24(%rbp), %r8d
movq %rsp, %rax
leaq -0x98(%rbp), %r9
movq %r9, 0x8(%rax)
leaq -0x50(%rbp), %r9
movq %r9, (%rax)
leaq -0x288(%rbp), %r9
callq 0x3600
jmp 0x353d
jmp 0x353f
cmpq $0x0, -0x38(%rbp)
je 0x3558
movl -0x2bc(%rbp), %ecx
subl -0x2c0(%rbp), %ecx
movq -0x38(%rbp), %rax
movl %ecx, (%rax)
cmpq $0x0, 0x10(%rbp)
je 0x3573
movq 0x10(%rbp), %rdi
leaq -0x2b0(%rbp), %rsi
callq 0x2030
jmp 0x3571
jmp 0x3573
movl -0x2b8(%rbp), %eax
movl %eax, -0x4(%rbp)
leaq -0x2b0(%rbp), %rdi
callq 0x20e0
leaq -0x288(%rbp), %rdi
callq 0x20e0
leaq -0x268(%rbp), %rdi
callq 0x2140
leaq -0x98(%rbp), %rdi
callq 0x3dc0
leaq -0x50(%rbp), %rdi
callq 0x3e20
jmp 0x35e6
leaq -0x288(%rbp), %rdi
callq 0x20e0
leaq -0x268(%rbp), %rdi
callq 0x2140
leaq -0x98(%rbp), %rdi
callq 0x3dc0
leaq -0x50(%rbp), %rdi
callq 0x3e20
jmp 0x35f2
movl -0x4(%rbp), %eax
addq $0x3f0, %rsp            # imm = 0x3F0
popq %rbp
retq
movq -0x78(%rbp), %rdi
callq 0x2290
nopl (%rax,%rax)