// File: Ahhgust[P]STRaitRazor/trie.cpp
// Function: Trie::makeTrieFromConfig(std::vector<Config, std::allocator<Config>>*, unsigned int, unsigned char, unsigned char)
void
Trie::makeTrieFromConfig(vector<Config> *c, unsigned numStrs, unsigned char distance, unsigned char motifDistance) {
  unsigned i, nf, nr, memNeeded=0;

  if (distance >2) {
    cerr << "Sorry, the max anchor distance supported with trie-search is 2; " << distance   << " is too big!" << endl;
    exit(EXIT_FAILURE);
  } else if (motifDistance > 1) {
    cerr << "Sorry, the max motif distance supported with trie-search is 1; " << motifDistance   << " is too big!" << endl;
    exit(EXIT_FAILURE);
  }

  // make a table of IUPAC codes
  char IUPAC[255][2];
  memset(IUPAC, 0, 255+255);
  IUPAC[ (int)'R'][0] = 'A';
  IUPAC[ (int)'R'][1] = 'G';

  IUPAC[ (int)'Y'][0] = 'C';
  IUPAC[ (int)'Y'][1] = 'T';

  IUPAC[ (int)'S'][0] = 'G';
  IUPAC[ (int)'S'][1] = 'C';

  IUPAC[ (int)'W'][0] = 'A';
  IUPAC[ (int)'W'][1] = 'T';

  IUPAC[ (int)'K'][0] = 'G';
  IUPAC[ (int)'K'][1] = 'T';

  IUPAC[ (int)'M'][0] = 'A';
  IUPAC[ (int)'M'][1] = 'C';

  // compute an (upper-bound) on the number of nodes in the trie
  for (i=0; i < numStrs; ++i) {
    // math for the memory needed for a hamming distance of 1:
    // N = length of string + 1 (ie, including \0)
    // entering that string requires at most N nodes.
    // entering all the 1-base substitutions on that string requires
    // 3*N for all the substitutions on the 0th positoin
    // 3*(N-1) for all of the substutitions on the 1st position (previous position 0 is already in the trie)
    // 3*(N-2) for all of the subs on the second position (previous 2 positions are in the trie) 
    // ...
    // 3 
    // which is equal to:
    // N + 3N + (3(N)(N-1))/2
    //memNeeded += (2*c[i].forwardLength + 2) + (3* (c[i].reverseLength+2)* (c[i].reverseLength+3))/2;
    //memNeeded += (2*c[i].reverseLength + 2) + (3* (c[i].forwardLength+2)* (c[i].forwardLength+3))/2;

    // we have the forwardFlank twice (8N) (+ and - strand)
    // and again for the reverse flank
    nf = (8*((*c)[i].forwardLength+1)) + 3* ((*c)[i].forwardLength)*((*c)[i].forwardLength-1);
    nr = (8*((*c)[i].reverseLength+1)) + 3* ((*c)[i].reverseLength)*((*c)[i].reverseLength-1);


    const char *s = (*c)[i].forwardFlank.c_str();
    unsigned nfAmbig=0;
    for (unsigned j = 0; j < (*c)[i].forwardLength; ++j, ++s) { // adjust the memory for IUPAC codes (double the memory for each IUPAC code)
      if ( IUPAC[(int)*s][0] != 0) {
        nf = nf + nf;
        ++nfAmbig;
      }
    }

    if (nfAmbig > 1) {
      cerr << endl << "At most 1 ambiguity code is supported per anchor." << endl 
           << "Problem with locus: " << (*c)[i].locusName << " Anchor " << (*c)[i].forwardFlank << endl << endl;
      exit(EXIT_FAILURE);
    }

    s = (*c)[i].reverseFlank.c_str();
    unsigned nrAmbig=0;
    for (unsigned j = 0; j < (*c)[i].reverseLength; ++j, ++s) { // adjust the memory for IUPAC codes (double the memory for each IUPAC code)
      if ( IUPAC[(int)*s][0] != 0) {
        nr = nr + nr;
        ++nrAmbig;
      }
    }



    if (nrAmbig > 1) {
      cerr << endl << "At most 1 ambiguity code is supported per anchor." << endl <<
        "Problem with locus: " << (*c)[i].locusName << " Anchor " << (*c)[i].reverseFlank << endl << endl;
      exit(EXIT_FAILURE);
    }
    
    if (distance == 0) {
      memNeeded += ((*c)[i].forwardLength+1)*(2*(nfAmbig+1)) + ((*c)[i].reverseLength+1)*(2*(nrAmbig+1));
    } else if (distance == 1) {
      memNeeded += nf + nr;
    } else if (distance == 2) {
      // got lazy with this one; wolfram alpha was used to simplify the sum:
      // sum i=1 to N (i)(i-1)
      // which is the (worst-case) memory needed to add a word of length N and all 2-permutations of it
      memNeeded += (nfAmbig*nfAmbig+1)*6*((*c)[i].forwardLength)*((*c)[i].forwardLength+1)*((*c)[i].forwardLength+2);
      memNeeded += (nrAmbig*nrAmbig+1)*6*((*c)[i].reverseLength)*((*c)[i].reverseLength+1)*((*c)[i].reverseLength-1);
    }

    memNeeded += ((*c)[i].motifLength+1) *2; // the motifs are also added
    if (motifDistance == 1) {
      memNeeded += (8*((*c)[i].motifLength+1)) + 3* ((*c)[i].motifLength)*((*c)[i].motifLength-1);
    }
  }

  initMem(memNeeded);

  for (i=0; i < numStrs; ++i) {

    int numAmbig=0;
    string s =  (*c)[i].forwardFlank;
    for (unsigned j= 0; j < (*c)[i].forwardLength; ++j) {
      if ( IUPAC[(int)s.at(j)][0] != 0) {

        int iupac = (int)s.at(j);

        s[j] = IUPAC[ iupac ][0]; // overwrite the ambiguity code with the first form, then add to trie
        addPermutations(s, (*c)[i].forwardLength, i, (unsigned char) FORWARDFLANK,
                        (unsigned char) FORWARDFLANK_RC, distance);
        
        
        s[j] = IUPAC[ iupac ][1]; // overwrite the ambiguity code with the second form, then add to trie
        addPermutations(s, (*c)[i].forwardLength, i, (unsigned char) FORWARDFLANK,
                        (unsigned char) FORWARDFLANK_RC, distance);
        
        ++numAmbig;
        break;
      }
    }
    
    if (numAmbig==0) {

      addPermutations((*c)[i].forwardFlank, (*c)[i].forwardLength, i, (unsigned char) FORWARDFLANK,
                      (unsigned char) FORWARDFLANK_RC, distance);
    }
    numAmbig=0;
    s =  (*c)[i].reverseFlank;
    for (unsigned j= 0; j < (*c)[i].reverseLength; ++j) {
      if ( IUPAC[(int)s.at(j)][0] != 0) {

        int iupac = (int)s.at(j);

        s[j] = IUPAC[ iupac ][0]; // overwrite the ambiguity code with the first form, then add to trie
        addPermutations(s, (*c)[i].reverseLength, i, (unsigned char) REVERSEFLANK, 
                        (unsigned char) REVERSEFLANK_RC, distance);
        
        s[j] = IUPAC[ iupac ][1]; // overwrite the ambiguity code with the second form, then add to trie
        addPermutations(s, (*c)[i].reverseLength, i, (unsigned char) REVERSEFLANK, 
                        (unsigned char) REVERSEFLANK_RC, distance);
        
        ++numAmbig;
        break;
      }
    }


    // and the reverse flank (and its RC)
    if (numAmbig==0)
      addPermutations((*c)[i].reverseFlank, (*c)[i].reverseLength, i, (unsigned char) REVERSEFLANK, 
                      (unsigned char) REVERSEFLANK_RC, distance);
    
    if (motifDistance==0) {
    // add the motif (no degeneracy in this)
      addWord((*c)[i].strMotif.c_str(), (*c)[i].motifLength, i, MOTIF);
      addWordRC((*c)[i].strMotif.c_str(), (*c)[i].motifLength, i, MOTIF_RC);
    } else {
      addPermutations((*c)[i].strMotif, (*c)[i].motifLength, i, (unsigned char) MOTIF, (unsigned char) MOTIF_RC, motifDistance);
    }
  } 
  
  //  cerr << memNeeded << " bytes asked for ; Mem unused: " << memNeeded - (mem-root) << endl;

  if (mem-root > (int) memNeeded) {
    cerr << "Error with the maths. Email the author (August) to fix this!" << endl;
    exit(1);
  }
  
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x460, %rsp            # imm = 0x460
movb %r8b, %al
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl %edx, -0x14(%rbp)
movb %cl, -0x15(%rbp)
movb %al, -0x16(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x378(%rbp)
movl $0x0, -0x28(%rbp)
movzbl -0x15(%rbp), %eax
cmpl $0x2, %eax
jle 0x12231
movq 0x9dff(%rip), %rdi      # 0x1bff0
leaq 0x2c2e(%rip), %rsi      # 0x14e26
callq 0x3290
movq %rax, %rdi
movzbl -0x15(%rbp), %esi
callq 0x33f0
movq %rax, %rdi
leaq 0x2c54(%rip), %rsi      # 0x14e67
callq 0x3290
movq %rax, %rdi
movq 0x9d96(%rip), %rsi      # 0x1bfb8
callq 0x32e0
movl $0x1, %edi
callq 0x3330
movzbl -0x16(%rbp), %eax
cmpl $0x1, %eax
jle 0x12281
movq 0x9daf(%rip), %rdi      # 0x1bff0
leaq 0x2c2c(%rip), %rsi      # 0x14e74
callq 0x3290
movq %rax, %rdi
movzbl -0x16(%rbp), %esi
callq 0x33f0
movq %rax, %rdi
leaq 0x2c04(%rip), %rsi      # 0x14e67
callq 0x3290
movq %rax, %rdi
movq 0x9d46(%rip), %rsi      # 0x1bfb8
callq 0x32e0
movl $0x1, %edi
callq 0x3330
jmp 0x12283
leaq -0x230(%rbp), %rdi
xorl %esi, %esi
movl $0x1fe, %edx            # imm = 0x1FE
callq 0x3160
movb $0x41, -0x18c(%rbp)
movb $0x47, -0x18b(%rbp)
movb $0x43, -0x17e(%rbp)
movb $0x54, -0x17d(%rbp)
movb $0x47, -0x18a(%rbp)
movb $0x43, -0x189(%rbp)
movb $0x41, -0x182(%rbp)
movb $0x54, -0x181(%rbp)
movb $0x47, -0x19a(%rbp)
movb $0x54, -0x199(%rbp)
movb $0x41, -0x196(%rbp)
movb $0x43, -0x195(%rbp)
movl $0x0, -0x1c(%rbp)
movl -0x1c(%rbp), %eax
cmpl -0x14(%rbp), %eax
jae 0x1293d
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %eax
movl %eax, %esi
callq 0x8890
movl 0xa0(%rax), %eax
addl $0x1, %eax
shll $0x3, %eax
movl %eax, -0x384(%rbp)
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %eax
movl %eax, %esi
callq 0x8890
imull $0x3, 0xa0(%rax), %eax
movl %eax, -0x388(%rbp)
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %eax
movl %eax, %esi
callq 0x8890
movl -0x388(%rbp), %ecx
movq %rax, %rdx
movl -0x384(%rbp), %eax
movl 0xa0(%rdx), %edx
subl $0x1, %edx
imull %edx, %ecx
addl %ecx, %eax
movl %eax, -0x20(%rbp)
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %eax
movl %eax, %esi
callq 0x8890
movl 0xa4(%rax), %eax
addl $0x1, %eax
shll $0x3, %eax
movl %eax, -0x37c(%rbp)
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %eax
movl %eax, %esi
callq 0x8890
imull $0x3, 0xa4(%rax), %eax
movl %eax, -0x380(%rbp)
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %eax
movl %eax, %esi
callq 0x8890
movl -0x380(%rbp), %ecx
movq %rax, %rdx
movl -0x37c(%rbp), %eax
movl 0xa4(%rdx), %edx
subl $0x1, %edx
imull %edx, %ecx
addl %ecx, %eax
movl %eax, -0x24(%rbp)
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %eax
movl %eax, %esi
callq 0x8890
movq %rax, %rdi
addq $0x40, %rdi
callq 0x3100
movq %rax, -0x238(%rbp)
movl $0x0, -0x23c(%rbp)
movl $0x0, -0x240(%rbp)
movl -0x240(%rbp), %eax
movl %eax, -0x38c(%rbp)
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %eax
movl %eax, %esi
callq 0x8890
movq %rax, %rcx
movl -0x38c(%rbp), %eax
cmpl 0xa0(%rcx), %eax
jae 0x12488
movq -0x238(%rbp), %rax
movsbl (%rax), %eax
cltq
movsbl -0x230(%rbp,%rax,2), %eax
cmpl $0x0, %eax
je 0x12460
movl -0x20(%rbp), %eax
addl -0x20(%rbp), %eax
movl %eax, -0x20(%rbp)
movl -0x23c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x23c(%rbp)
jmp 0x12462
movl -0x240(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x240(%rbp)
movq -0x238(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x238(%rbp)
jmp 0x12404
cmpl $0x1, -0x23c(%rbp)
jbe 0x12558
movq 0x9b54(%rip), %rdi      # 0x1bff0
movq 0x9b15(%rip), %rsi      # 0x1bfb8
callq 0x32e0
movq %rax, %rdi
leaq 0x2a02(%rip), %rsi      # 0x14eb4
callq 0x3290
movq %rax, %rdi
movq 0x9af7(%rip), %rsi      # 0x1bfb8
callq 0x32e0
movq %rax, %rdi
leaq 0x2a16(%rip), %rsi      # 0x14ee6
callq 0x3290
movq %rax, -0x3a0(%rbp)
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %eax
movl %eax, %esi
callq 0x8890
movq -0x3a0(%rbp), %rdi
movq %rax, %rsi
callq 0x3270
movq %rax, %rdi
leaq 0x29f8(%rip), %rsi      # 0x14efb
callq 0x3290
movq %rax, -0x398(%rbp)
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %eax
movl %eax, %esi
callq 0x8890
movq -0x398(%rbp), %rdi
movq %rax, %rsi
addq $0x40, %rsi
callq 0x3270
movq %rax, %rdi
movq 0x9a7e(%rip), %rsi      # 0x1bfb8
callq 0x32e0
movq %rax, %rdi
movq 0x9a6f(%rip), %rsi      # 0x1bfb8
callq 0x32e0
movl $0x1, %edi
callq 0x3330
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %eax
movl %eax, %esi
callq 0x8890
movq %rax, %rdi
addq $0x60, %rdi
callq 0x3100
movq %rax, -0x238(%rbp)
movl $0x0, -0x244(%rbp)
movl $0x0, -0x248(%rbp)
movl -0x248(%rbp), %eax
movl %eax, -0x3a4(%rbp)
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %eax
movl %eax, %esi
callq 0x8890
movq %rax, %rcx
movl -0x3a4(%rbp), %eax
cmpl 0xa4(%rcx), %eax
jae 0x12611
movq -0x238(%rbp), %rax
movsbl (%rax), %eax
cltq
movsbl -0x230(%rbp,%rax,2), %eax
cmpl $0x0, %eax
je 0x125e9
movl -0x24(%rbp), %eax
addl -0x24(%rbp), %eax
movl %eax, -0x24(%rbp)
movl -0x244(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x244(%rbp)
jmp 0x125eb
movl -0x248(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x248(%rbp)
movq -0x238(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x238(%rbp)
jmp 0x1258d
cmpl $0x1, -0x244(%rbp)
jbe 0x126e1
movq 0x99cb(%rip), %rdi      # 0x1bff0
movq 0x998c(%rip), %rsi      # 0x1bfb8
callq 0x32e0
movq %rax, %rdi
leaq 0x2879(%rip), %rsi      # 0x14eb4
callq 0x3290
movq %rax, %rdi
movq 0x996e(%rip), %rsi      # 0x1bfb8
callq 0x32e0
movq %rax, %rdi
leaq 0x288d(%rip), %rsi      # 0x14ee6
callq 0x3290
movq %rax, -0x3b8(%rbp)
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %eax
movl %eax, %esi
callq 0x8890
movq -0x3b8(%rbp), %rdi
movq %rax, %rsi
callq 0x3270
movq %rax, %rdi
leaq 0x286f(%rip), %rsi      # 0x14efb
callq 0x3290
movq %rax, -0x3b0(%rbp)
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %eax
movl %eax, %esi
callq 0x8890
movq -0x3b0(%rbp), %rdi
movq %rax, %rsi
addq $0x60, %rsi
callq 0x3270
movq %rax, %rdi
movq 0x98f5(%rip), %rsi      # 0x1bfb8
callq 0x32e0
movq %rax, %rdi
movq 0x98e6(%rip), %rsi      # 0x1bfb8
callq 0x32e0
movl $0x1, %edi
callq 0x3330
movzbl -0x15(%rbp), %eax
cmpl $0x0, %eax
jne 0x12750
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %eax
movl %eax, %esi
callq 0x8890
movl 0xa0(%rax), %eax
addl $0x1, %eax
movl -0x23c(%rbp), %ecx
addl $0x1, %ecx
shll %ecx
imull %ecx, %eax
movl %eax, -0x3bc(%rbp)
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %eax
movl %eax, %esi
callq 0x8890
movq %rax, %rcx
movl -0x3bc(%rbp), %eax
movl 0xa4(%rcx), %ecx
addl $0x1, %ecx
movl -0x244(%rbp), %edx
addl $0x1, %edx
shll %edx
imull %edx, %ecx
addl %ecx, %eax
addl -0x28(%rbp), %eax
movl %eax, -0x28(%rbp)
jmp 0x12899
movzbl -0x15(%rbp), %eax
cmpl $0x1, %eax
jne 0x1276a
movl -0x20(%rbp), %eax
addl -0x24(%rbp), %eax
addl -0x28(%rbp), %eax
movl %eax, -0x28(%rbp)
jmp 0x12897
movzbl -0x15(%rbp), %eax
cmpl $0x2, %eax
jne 0x12895
movl -0x23c(%rbp), %eax
imull -0x23c(%rbp), %eax
addl $0x1, %eax
imull $0x6, %eax, %eax
movl %eax, -0x3d4(%rbp)
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %eax
movl %eax, %esi
callq 0x8890
movq %rax, %rcx
movl -0x3d4(%rbp), %eax
imull 0xa0(%rcx), %eax
movl %eax, -0x3d0(%rbp)
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %eax
movl %eax, %esi
callq 0x8890
movq %rax, %rcx
movl -0x3d0(%rbp), %eax
movl 0xa0(%rcx), %ecx
addl $0x1, %ecx
imull %ecx, %eax
movl %eax, -0x3cc(%rbp)
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %eax
movl %eax, %esi
callq 0x8890
movq %rax, %rcx
movl -0x3cc(%rbp), %eax
movl 0xa0(%rcx), %ecx
addl $0x2, %ecx
imull %ecx, %eax
addl -0x28(%rbp), %eax
movl %eax, -0x28(%rbp)
movl -0x244(%rbp), %eax
imull -0x244(%rbp), %eax
addl $0x1, %eax
imull $0x6, %eax, %eax
movl %eax, -0x3c8(%rbp)
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %eax
movl %eax, %esi
callq 0x8890
movq %rax, %rcx
movl -0x3c8(%rbp), %eax
imull 0xa4(%rcx), %eax
movl %eax, -0x3c4(%rbp)
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %eax
movl %eax, %esi
callq 0x8890
movq %rax, %rcx
movl -0x3c4(%rbp), %eax
movl 0xa4(%rcx), %ecx
addl $0x1, %ecx
imull %ecx, %eax
movl %eax, -0x3c0(%rbp)
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %eax
movl %eax, %esi
callq 0x8890
movq %rax, %rcx
movl -0x3c0(%rbp), %eax
movl 0xa4(%rcx), %ecx
subl $0x1, %ecx
imull %ecx, %eax
addl -0x28(%rbp), %eax
movl %eax, -0x28(%rbp)
jmp 0x12897
jmp 0x12899
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %eax
movl %eax, %esi
callq 0x8890
movl 0xa8(%rax), %eax
addl $0x1, %eax
shll %eax
addl -0x28(%rbp), %eax
movl %eax, -0x28(%rbp)
movzbl -0x16(%rbp), %eax
cmpl $0x1, %eax
jne 0x1292d
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %eax
movl %eax, %esi
callq 0x8890
movl 0xa8(%rax), %eax
addl $0x1, %eax
shll $0x3, %eax
movl %eax, -0x3d8(%rbp)
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %eax
movl %eax, %esi
callq 0x8890
imull $0x3, 0xa8(%rax), %eax
movl %eax, -0x3dc(%rbp)
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %eax
movl %eax, %esi
callq 0x8890
movl -0x3dc(%rbp), %ecx
movq %rax, %rdx
movl -0x3d8(%rbp), %eax
movl 0xa8(%rdx), %edx
subl $0x1, %edx
imull %edx, %ecx
addl %ecx, %eax
addl -0x28(%rbp), %eax
movl %eax, -0x28(%rbp)
jmp 0x1292f
movl -0x1c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1c(%rbp)
jmp 0x122f1
movq -0x378(%rbp), %rdi
movl -0x28(%rbp), %esi
callq 0x11710
movl $0x0, -0x1c(%rbp)
movl -0x1c(%rbp), %eax
cmpl -0x14(%rbp), %eax
jae 0x1311d
movl $0x0, -0x24c(%rbp)
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %eax
movl %eax, %esi
callq 0x8890
movq %rax, %rsi
addq $0x40, %rsi
leaq -0x270(%rbp), %rdi
callq 0x3120
movl $0x0, -0x274(%rbp)
movl -0x274(%rbp), %eax
movl %eax, -0x3e0(%rbp)
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %eax
movl %eax, %esi
callq 0x8890
movq %rax, %rcx
movl -0x3e0(%rbp), %eax
cmpl 0xa0(%rcx), %eax
jae 0x12bec
movl -0x274(%rbp), %eax
movl %eax, %esi
leaq -0x270(%rbp), %rdi
callq 0x3510
movq %rax, -0x3e8(%rbp)
jmp 0x129e0
movq -0x3e8(%rbp), %rax
movsbl (%rax), %eax
cltq
movsbl -0x230(%rbp,%rax,2), %eax
cmpl $0x0, %eax
je 0x12bd6
movl -0x274(%rbp), %eax
movl %eax, %esi
leaq -0x270(%rbp), %rdi
callq 0x3510
movq %rax, -0x3f0(%rbp)
jmp 0x12a1a
movq -0x3f0(%rbp), %rax
movsbl (%rax), %eax
movl %eax, -0x288(%rbp)
movslq -0x288(%rbp), %rax
movb -0x230(%rbp,%rax,2), %al
movb %al, -0x3f9(%rbp)
movl -0x274(%rbp), %eax
movl %eax, %esi
leaq -0x270(%rbp), %rdi
callq 0x3520
movq %rax, -0x3f8(%rbp)
jmp 0x12a5b
movq -0x3f8(%rbp), %rax
movb -0x3f9(%rbp), %cl
movb %cl, (%rax)
leaq -0x2a8(%rbp), %rdi
leaq -0x270(%rbp), %rsi
callq 0x3120
jmp 0x12a7f
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %eax
movl %eax, %esi
callq 0x8890
movq -0x378(%rbp), %rdi
movl 0xa0(%rax), %edx
movl -0x1c(%rbp), %ecx
movzbl -0x15(%rbp), %esi
movq %rsp, %rax
movl %esi, (%rax)
leaq -0x2a8(%rbp), %rsi
xorl %r8d, %r8d
movl $0x1, %r9d
callq 0x11d80
jmp 0x12abd
leaq -0x2a8(%rbp), %rdi
callq 0x31b0
movslq -0x288(%rbp), %rax
movb -0x22f(%rbp,%rax,2), %al
movb %al, -0x409(%rbp)
movl -0x274(%rbp), %eax
movl %eax, %esi
leaq -0x270(%rbp), %rdi
callq 0x3520
movq %rax, -0x408(%rbp)
jmp 0x12afa
movq -0x408(%rbp), %rax
movb -0x409(%rbp), %cl
movb %cl, (%rax)
leaq -0x2c8(%rbp), %rdi
leaq -0x270(%rbp), %rsi
callq 0x3120
jmp 0x12b1e
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %eax
movl %eax, %esi
callq 0x8890
movq -0x378(%rbp), %rdi
movl 0xa0(%rax), %edx
movl -0x1c(%rbp), %ecx
movzbl -0x15(%rbp), %esi
movq %rsp, %rax
movl %esi, (%rax)
leaq -0x2c8(%rbp), %rsi
xorl %r8d, %r8d
movl $0x1, %r9d
callq 0x11d80
jmp 0x12b5c
leaq -0x2c8(%rbp), %rdi
callq 0x31b0
movl -0x24c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x24c(%rbp)
jmp 0x12bec
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x280(%rbp)
movl %eax, -0x284(%rbp)
jmp 0x1310f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x280(%rbp)
movl %eax, -0x284(%rbp)
leaq -0x2a8(%rbp), %rdi
callq 0x31b0
jmp 0x1310f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x280(%rbp)
movl %eax, -0x284(%rbp)
leaq -0x2c8(%rbp), %rdi
callq 0x31b0
jmp 0x1310f
jmp 0x12bd8
movl -0x274(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x274(%rbp)
jmp 0x12994
cmpl $0x0, -0x24c(%rbp)
jne 0x12c8b
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %eax
movl %eax, %esi
callq 0x8890
movq %rax, %rsi
addq $0x40, %rsi
leaq -0x2e8(%rbp), %rdi
callq 0x3120
jmp 0x12c1c
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %eax
movl %eax, %esi
callq 0x8890
movq -0x378(%rbp), %rdi
movl 0xa0(%rax), %edx
movl -0x1c(%rbp), %ecx
movzbl -0x15(%rbp), %esi
movq %rsp, %rax
movl %esi, (%rax)
leaq -0x2e8(%rbp), %rsi
xorl %r8d, %r8d
movl $0x1, %r9d
callq 0x11d80
jmp 0x12c5a
leaq -0x2e8(%rbp), %rdi
callq 0x31b0
jmp 0x12c8b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x280(%rbp)
movl %eax, -0x284(%rbp)
leaq -0x2e8(%rbp), %rdi
callq 0x31b0
jmp 0x1310f
movl $0x0, -0x24c(%rbp)
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %eax
movl %eax, %esi
callq 0x8890
movq %rax, %rsi
addq $0x60, %rsi
leaq -0x270(%rbp), %rdi
callq 0x3040
jmp 0x12cb8
movl $0x0, -0x2ec(%rbp)
movl -0x2ec(%rbp), %eax
movl %eax, -0x410(%rbp)
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %eax
movl %eax, %esi
callq 0x8890
movq %rax, %rcx
movl -0x410(%rbp), %eax
cmpl 0xa4(%rcx), %eax
jae 0x12f09
movl -0x2ec(%rbp), %eax
movl %eax, %esi
leaq -0x270(%rbp), %rdi
callq 0x3510
movq %rax, -0x418(%rbp)
jmp 0x12d0e
movq -0x418(%rbp), %rax
movsbl (%rax), %eax
cltq
movsbl -0x230(%rbp,%rax,2), %eax
cmpl $0x0, %eax
je 0x12ef3
movl -0x2ec(%rbp), %eax
movl %eax, %esi
leaq -0x270(%rbp), %rdi
callq 0x3510
movq %rax, -0x420(%rbp)
jmp 0x12d48
movq -0x420(%rbp), %rax
movsbl (%rax), %eax
movl %eax, -0x2f0(%rbp)
movslq -0x2f0(%rbp), %rax
movb -0x230(%rbp,%rax,2), %al
movb %al, -0x429(%rbp)
movl -0x2ec(%rbp), %eax
movl %eax, %esi
leaq -0x270(%rbp), %rdi
callq 0x3520
movq %rax, -0x428(%rbp)
jmp 0x12d89
movq -0x428(%rbp), %rax
movb -0x429(%rbp), %cl
movb %cl, (%rax)
leaq -0x310(%rbp), %rdi
leaq -0x270(%rbp), %rsi
callq 0x3120
jmp 0x12dad
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %eax
movl %eax, %esi
callq 0x8890
movq -0x378(%rbp), %rdi
movl 0xa4(%rax), %edx
movl -0x1c(%rbp), %ecx
movzbl -0x15(%rbp), %esi
movq %rsp, %rax
movl %esi, (%rax)
leaq -0x310(%rbp), %rsi
movl $0x3, %r8d
movl $0x2, %r9d
callq 0x11d80
jmp 0x12dee
leaq -0x310(%rbp), %rdi
callq 0x31b0
movslq -0x2f0(%rbp), %rax
movb -0x22f(%rbp,%rax,2), %al
movb %al, -0x439(%rbp)
movl -0x2ec(%rbp), %eax
movl %eax, %esi
leaq -0x270(%rbp), %rdi
callq 0x3520
movq %rax, -0x438(%rbp)
jmp 0x12e2b
movq -0x438(%rbp), %rax
movb -0x439(%rbp), %cl
movb %cl, (%rax)
leaq -0x330(%rbp), %rdi
leaq -0x270(%rbp), %rsi
callq 0x3120
jmp 0x12e4f
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %eax
movl %eax, %esi
callq 0x8890
movq -0x378(%rbp), %rdi
movl 0xa4(%rax), %edx
movl -0x1c(%rbp), %ecx
movzbl -0x15(%rbp), %esi
movq %rsp, %rax
movl %esi, (%rax)
leaq -0x330(%rbp), %rsi
movl $0x3, %r8d
movl $0x2, %r9d
callq 0x11d80
jmp 0x12e90
leaq -0x330(%rbp), %rdi
callq 0x31b0
movl -0x24c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x24c(%rbp)
jmp 0x12f09
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x280(%rbp)
movl %eax, -0x284(%rbp)
leaq -0x310(%rbp), %rdi
callq 0x31b0
jmp 0x1310f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x280(%rbp)
movl %eax, -0x284(%rbp)
leaq -0x330(%rbp), %rdi
callq 0x31b0
jmp 0x1310f
jmp 0x12ef5
movl -0x2ec(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2ec(%rbp)
jmp 0x12cc2
cmpl $0x0, -0x24c(%rbp)
jne 0x12fab
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %eax
movl %eax, %esi
callq 0x8890
movq %rax, %rsi
addq $0x60, %rsi
leaq -0x350(%rbp), %rdi
callq 0x3120
jmp 0x12f39
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %eax
movl %eax, %esi
callq 0x8890
movq -0x378(%rbp), %rdi
movl 0xa4(%rax), %edx
movl -0x1c(%rbp), %ecx
movzbl -0x15(%rbp), %esi
movq %rsp, %rax
movl %esi, (%rax)
leaq -0x350(%rbp), %rsi
movl $0x3, %r8d
movl $0x2, %r9d
callq 0x11d80
jmp 0x12f7a
leaq -0x350(%rbp), %rdi
callq 0x31b0
jmp 0x12fab
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x280(%rbp)
movl %eax, -0x284(%rbp)
leaq -0x350(%rbp), %rdi
callq 0x31b0
jmp 0x1310f
movzbl -0x16(%rbp), %eax
cmpl $0x0, %eax
jne 0x13063
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %eax
movl %eax, %esi
callq 0x8890
movq %rax, %rdi
subq $-0x80, %rdi
callq 0x3100
movq %rax, -0x448(%rbp)
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %eax
movl %eax, %esi
callq 0x8890
movq -0x378(%rbp), %rdi
movq -0x448(%rbp), %rsi
movl 0xa8(%rax), %edx
movl -0x1c(%rbp), %ecx
movl $0x4, %r8d
callq 0x117f0
jmp 0x1300b
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %eax
movl %eax, %esi
callq 0x8890
movq %rax, %rdi
subq $-0x80, %rdi
callq 0x3100
movq %rax, -0x450(%rbp)
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %eax
movl %eax, %esi
callq 0x8890
movq -0x378(%rbp), %rdi
movq -0x450(%rbp), %rsi
movl 0xa8(%rax), %edx
movl -0x1c(%rbp), %ecx
movl $0x5, %r8d
callq 0x11a60
jmp 0x1305e
jmp 0x130f5
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %eax
movl %eax, %esi
callq 0x8890
movq %rax, %rsi
subq $-0x80, %rsi
leaq -0x370(%rbp), %rdi
callq 0x3120
jmp 0x13086
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %eax
movl %eax, %esi
callq 0x8890
movq -0x378(%rbp), %rdi
movl 0xa8(%rax), %edx
movl -0x1c(%rbp), %ecx
movzbl -0x16(%rbp), %esi
movq %rsp, %rax
movl %esi, (%rax)
leaq -0x370(%rbp), %rsi
movl $0x4, %r8d
movl $0x5, %r9d
callq 0x11d80
jmp 0x130c7
leaq -0x370(%rbp), %rdi
callq 0x31b0
jmp 0x130f5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x280(%rbp)
movl %eax, -0x284(%rbp)
leaq -0x370(%rbp), %rdi
callq 0x31b0
jmp 0x1310f
leaq -0x270(%rbp), %rdi
callq 0x31b0
movl -0x1c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1c(%rbp)
jmp 0x12953
leaq -0x270(%rbp), %rdi
callq 0x31b0
jmp 0x13176
movq -0x378(%rbp), %rcx
movq 0x8(%rcx), %rax
movq (%rcx), %rcx
subq %rcx, %rax
movl $0x30, %ecx
cqto
idivq %rcx
movslq -0x28(%rbp), %rcx
cmpq %rcx, %rax
jle 0x1316d
movq 0x8ea8(%rip), %rdi      # 0x1bff0
leaq 0x1db5(%rip), %rsi      # 0x14f04
callq 0x3290
movq %rax, %rdi
movq 0x8e5a(%rip), %rsi      # 0x1bfb8
callq 0x32e0
movl $0x1, %edi
callq 0x3330
addq $0x460, %rsp            # imm = 0x460
popq %rbp
retq
movq -0x280(%rbp), %rdi
callq 0x34a0
nopw %cs:(%rax,%rax)
nopl (%rax)