// File: zeeev[P]DASVC/bamtools/src/api/internal/bam/BamWriter_p.cpp
// Function: BamTools::Internal::BamWriterPrivate::WriteAlignment(BamTools::BamAlignment const&)
void BamWriterPrivate::WriteAlignment(const BamAlignment& al) {

    // calculate char lengths
    const unsigned int nameLength         = al.Name.size() + 1;
    const unsigned int numCigarOperations = al.CigarData.size();
    const unsigned int queryLength        = ( (al.QueryBases == "*") ? 0 : al.QueryBases.size() );
    const unsigned int tagDataLength      = al.TagData.size();

    // no way to tell if alignment's bin is already defined (there is no default, invalid value)
    // so we'll go ahead calculate its bin ID before storing
    const uint32_t alignmentBin = CalculateMinimumBin(al.Position, al.GetEndPosition());

    // create our packed cigar string
    string packedCigar;
    CreatePackedCigar(al.CigarData, packedCigar);
    const unsigned int packedCigarLength = packedCigar.size();

    // encode the query
    unsigned int encodedQueryLength = 0;
    string encodedQuery;
    if ( queryLength > 0 ) {
        EncodeQuerySequence(al.QueryBases, encodedQuery);
        encodedQueryLength = encodedQuery.size();
    }

    // write the block size
    const unsigned int dataBlockSize = nameLength +
                                       packedCigarLength +
                                       encodedQueryLength +
                                       queryLength +         // here referring to quality length
                                       tagDataLength;
    unsigned int blockSize = Constants::BAM_CORE_SIZE + dataBlockSize;
    if ( m_isBigEndian ) BamTools::SwapEndian_32(blockSize);
    m_stream.Write((char*)&blockSize, Constants::BAM_SIZEOF_INT);

    // assign the BAM core data
    uint32_t buffer[Constants::BAM_CORE_BUFFER_SIZE];
    buffer[0] = al.RefID;
    buffer[1] = al.Position;
    buffer[2] = (alignmentBin << 16) | (al.MapQuality << 8) | nameLength;
    buffer[3] = (al.AlignmentFlag << 16) | numCigarOperations;
    buffer[4] = queryLength;
    buffer[5] = al.MateRefID;
    buffer[6] = al.MatePosition;
    buffer[7] = al.InsertSize;

    // swap BAM core endian-ness, if necessary
    if ( m_isBigEndian ) {
        for ( int i = 0; i < 8; ++i )
            BamTools::SwapEndian_32(buffer[i]);
    }

    // write the BAM core
    m_stream.Write((char*)&buffer, Constants::BAM_CORE_SIZE);

    // write the query name
    m_stream.Write(al.Name.c_str(), nameLength);

    // write the packed cigar
    if ( m_isBigEndian ) {
        char* cigarData = new char[packedCigarLength]();
        memcpy(cigarData, packedCigar.data(), packedCigarLength);
        if ( m_isBigEndian ) {
            for ( size_t i = 0; i < packedCigarLength; ++i )
                BamTools::SwapEndian_32p(&cigarData[i]);
        }
        m_stream.Write(cigarData, packedCigarLength);
        delete[] cigarData; // TODO: cleanup on Write exception thrown?
    }
    else
        m_stream.Write(packedCigar.data(), packedCigarLength);

    if ( queryLength > 0 ) {

        // write the encoded query sequence
        m_stream.Write(encodedQuery.data(), encodedQueryLength);

        // write the base qualities
        char* pBaseQualities = new char[queryLength]();
        if ( al.Qualities.empty() || ( al.Qualities.size() == 1 && al.Qualities[0] == '*' ) || al.Qualities[0] == (char)0xFF )
            memset(pBaseQualities, 0xFF, queryLength); // if missing or '*', fill with invalid qual
        else {
            for ( size_t i = 0; i < queryLength; ++i )
                pBaseQualities[i] = al.Qualities.at(i) - 33; // FASTQ ASCII -> phred score conversion
        }
        m_stream.Write(pBaseQualities, queryLength);
        delete[] pBaseQualities;
    }

    // write the tag data
    if ( m_isBigEndian ) {

        char* tagData = new char[tagDataLength]();
        memcpy(tagData, al.TagData.data(), tagDataLength);

        size_t i = 0;
        while ( i < tagDataLength ) {

            i += Constants::BAM_TAG_TAGSIZE;  // skip tag chars (e.g. "RG", "NM", etc.)
            const char type = tagData[i];     // get tag type at position i
            ++i;

            switch ( type ) {

                case(Constants::BAM_TAG_TYPE_ASCII) :
                case(Constants::BAM_TAG_TYPE_INT8)  :
                case(Constants::BAM_TAG_TYPE_UINT8) :
                    ++i;
                    break;

                case(Constants::BAM_TAG_TYPE_INT16)  :
                case(Constants::BAM_TAG_TYPE_UINT16) :
                    BamTools::SwapEndian_16p(&tagData[i]);
                    i += sizeof(uint16_t);
                    break;

                case(Constants::BAM_TAG_TYPE_FLOAT)  :
                case(Constants::BAM_TAG_TYPE_INT32)  :
                case(Constants::BAM_TAG_TYPE_UINT32) :
                    BamTools::SwapEndian_32p(&tagData[i]);
                    i += sizeof(uint32_t);
                    break;

                case(Constants::BAM_TAG_TYPE_HEX) :
                case(Constants::BAM_TAG_TYPE_STRING) :
                    // no endian swapping necessary for hex-string/string data
                    while ( tagData[i] )
                        ++i;
                    // increment one more for null terminator
                    ++i;
                    break;

                case(Constants::BAM_TAG_TYPE_ARRAY) :

                {
                    // read array type
                    const char arrayType = tagData[i];
                    ++i;

                    // swap endian-ness of number of elements in place, then retrieve for loop
                    BamTools::SwapEndian_32p(&tagData[i]);
                    int32_t numElements;
                    memcpy(&numElements, &tagData[i], sizeof(uint32_t));
                    i += sizeof(uint32_t);

                    // swap endian-ness of array elements
                    for ( int j = 0; j < numElements; ++j ) {
                        switch (arrayType) {
                            case (Constants::BAM_TAG_TYPE_INT8)  :
                            case (Constants::BAM_TAG_TYPE_UINT8) :
                                // no endian-swapping necessary
                                ++i;
                                break;
                            case (Constants::BAM_TAG_TYPE_INT16)  :
                            case (Constants::BAM_TAG_TYPE_UINT16) :
                                BamTools::SwapEndian_16p(&tagData[i]);
                                i += sizeof(uint16_t);
                                break;
                            case (Constants::BAM_TAG_TYPE_FLOAT)  :
                            case (Constants::BAM_TAG_TYPE_INT32)  :
                            case (Constants::BAM_TAG_TYPE_UINT32) :
                                BamTools::SwapEndian_32p(&tagData[i]);
                                i += sizeof(uint32_t);
                                break;
                            default:
                                delete[] tagData;
                                const string message = string("invalid binary array type: ") + arrayType;
                                throw BamException("BamWriter::SaveAlignment", message);
                        }
                    }

                    break;
                }

                default :
                    delete[] tagData;
                    const string message = string("invalid tag type: ") + type;
                    throw BamException("BamWriter::SaveAlignment", message);
            }
        }

        m_stream.Write(tagData, tagDataLength);
        delete[] tagData; // TODO: cleanup on Write exception thrown?
    }
    else
        m_stream.Write(al.TagData.data(), tagDataLength);
}

// Assembly:
subq $0x328, %rsp            # imm = 0x328
movq %rdi, 0x320(%rsp)
movq %rsi, 0x318(%rsp)
movq 0x320(%rsp), %rax
movq %rax, 0x150(%rsp)
movq 0x318(%rsp), %rdi
callq 0x74cd0
addq $0x1, %rax
movl %eax, 0x314(%rsp)
movq 0x318(%rsp), %rdi
addq $0xb8, %rdi
callq 0x73970
movl %eax, 0x310(%rsp)
movq 0x318(%rsp), %rdi
addq $0x28, %rdi
leaq 0x3b0dc(%rip), %rsi     # 0xea219
callq 0x7cc20
testb $0x1, %al
jne 0xaf148
jmp 0xaf154
xorl %eax, %eax
movq %rax, 0x148(%rsp)
jmp 0xaf16d
movq 0x318(%rsp), %rdi
addq $0x28, %rdi
callq 0x74cd0
movq %rax, 0x148(%rsp)
movq 0x148(%rsp), %rax
movl %eax, 0x30c(%rsp)
movq 0x318(%rsp), %rdi
addq $0x88, %rdi
callq 0x74cd0
movl %eax, 0x308(%rsp)
movq 0x318(%rsp), %rdi
movl 0xac(%rdi), %eax
movl %eax, 0x13c(%rsp)
xorl %edx, %edx
movl %edx, %esi
callq 0x76240
movl 0x13c(%rsp), %esi
movq 0x150(%rsp), %rdi
movl %eax, %edx
callq 0x73660
movl %eax, 0x304(%rsp)
leaq 0x2e0(%rsp), %rdi
movq %rdi, 0x140(%rsp)
callq 0x79100
movq 0x150(%rsp), %rdi
movq 0x140(%rsp), %rdx
movq 0x318(%rsp), %rsi
addq $0xb8, %rsi
callq 0x73b80
jmp 0xaf20d
leaq 0x2e0(%rsp), %rdi
callq 0x74cd0
movq %rax, 0x130(%rsp)
jmp 0xaf224
movq 0x130(%rsp), %rax
movl %eax, 0x2d0(%rsp)
movl $0x0, 0x2cc(%rsp)
leaq 0x2a8(%rsp), %rdi
callq 0x79100
jmp 0xaf24d
cmpl $0x0, 0x30c(%rsp)
jbe 0xaf2d4
movq 0x150(%rsp), %rdi
movq 0x318(%rsp), %rsi
addq $0x28, %rsi
leaq 0x2a8(%rsp), %rdx
callq 0x782c0
jmp 0xaf27a
leaq 0x2a8(%rsp), %rdi
callq 0x74cd0
movq %rax, 0x128(%rsp)
jmp 0xaf291
movq 0x128(%rsp), %rax
movl %eax, 0x2cc(%rsp)
jmp 0xaf2d4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2d8(%rsp)
movl %eax, 0x2d4(%rsp)
jmp 0xb0048
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2d8(%rsp)
movl %eax, 0x2d4(%rsp)
jmp 0xb0037
movq 0x150(%rsp), %rax
movl 0x314(%rsp), %ecx
addl 0x2d0(%rsp), %ecx
addl 0x2cc(%rsp), %ecx
addl 0x30c(%rsp), %ecx
addl 0x308(%rsp), %ecx
movl %ecx, 0x2a4(%rsp)
movl 0x2a4(%rsp), %ecx
addl $0x20, %ecx
movl %ecx, 0x2a0(%rsp)
testb $0x1, 0x40(%rax)
je 0xaf32e
leaq 0x2a0(%rsp), %rdi
callq 0x77400
jmp 0xaf32c
jmp 0xaf32e
movq 0x150(%rsp), %rdi
leaq 0x2a0(%rsp), %rsi
movl $0x4, %edx
callq 0x7b740
jmp 0xaf34a
movq 0x150(%rsp), %rax
movq 0x318(%rsp), %rcx
movl 0xa8(%rcx), %ecx
movl %ecx, 0x280(%rsp)
movq 0x318(%rsp), %rcx
movl 0xac(%rcx), %ecx
movl %ecx, 0x284(%rsp)
movl 0x304(%rsp), %ecx
shll $0x10, %ecx
movq 0x318(%rsp), %rdx
movzwl 0xb2(%rdx), %edx
shll $0x8, %edx
orl %edx, %ecx
orl 0x314(%rsp), %ecx
movl %ecx, 0x288(%rsp)
movq 0x318(%rsp), %rcx
movl 0xb4(%rcx), %ecx
shll $0x10, %ecx
orl 0x310(%rsp), %ecx
movl %ecx, 0x28c(%rsp)
movl 0x30c(%rsp), %ecx
movl %ecx, 0x290(%rsp)
movq 0x318(%rsp), %rcx
movl 0xd0(%rcx), %ecx
movl %ecx, 0x294(%rsp)
movq 0x318(%rsp), %rcx
movl 0xd4(%rcx), %ecx
movl %ecx, 0x298(%rsp)
movq 0x318(%rsp), %rcx
movl 0xd8(%rcx), %ecx
movl %ecx, 0x29c(%rsp)
testb $0x1, 0x40(%rax)
je 0xaf45d
movl $0x0, 0x27c(%rsp)
cmpl $0x8, 0x27c(%rsp)
jge 0xaf45b
movslq 0x27c(%rsp), %rax
leaq 0x280(%rsp,%rax,4), %rdi
callq 0x77400
jmp 0xaf446
jmp 0xaf448
movl 0x27c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x27c(%rsp)
jmp 0xaf425
jmp 0xaf45d
movq 0x150(%rsp), %rdi
leaq 0x280(%rsp), %rsi
movl $0x20, %edx
callq 0x7b740
jmp 0xaf479
movq 0x150(%rsp), %rax
movq %rax, 0x118(%rsp)
movq 0x318(%rsp), %rdi
callq 0x73020
movq %rax, 0x120(%rsp)
jmp 0xaf4a0
movq 0x120(%rsp), %rsi
movq 0x118(%rsp), %rdi
movl 0x314(%rsp), %eax
movl %eax, %edx
callq 0x7b740
jmp 0xaf4c0
movq 0x150(%rsp), %rax
testb $0x1, 0x40(%rax)
je 0xaf605
movl 0x2d0(%rsp), %eax
movl %eax, %edi
movq %rdi, 0x108(%rsp)
callq 0x710e0
movq %rax, 0x110(%rsp)
jmp 0xaf4f2
movq 0x110(%rsp), %rdi
movq 0x108(%rsp), %rdx
xorl %esi, %esi
callq 0x73d00
movq 0x110(%rsp), %rax
movq %rax, 0x270(%rsp)
movq 0x270(%rsp), %rax
movq %rax, 0xf8(%rsp)
leaq 0x2e0(%rsp), %rdi
callq 0x785e0
movq %rax, 0x100(%rsp)
jmp 0xaf540
movq 0x100(%rsp), %rsi
movq 0xf8(%rsp), %rdi
movl 0x2d0(%rsp), %eax
movl %eax, %edx
callq 0x757c0
movq 0x150(%rsp), %rax
testb $0x1, 0x40(%rax)
je 0xaf5c0
movq $0x0, 0x268(%rsp)
movq 0x268(%rsp), %rax
movl 0x2d0(%rsp), %ecx
cmpq %rcx, %rax
jae 0xaf5be
movq 0x270(%rsp), %rdi
movq 0x268(%rsp), %rax
addq %rax, %rdi
callq 0x7a7d0
jmp 0xaf5a6
jmp 0xaf5a8
movq 0x268(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x268(%rsp)
jmp 0xaf578
jmp 0xaf5c0
movq 0x150(%rsp), %rdi
movq 0x270(%rsp), %rsi
movl 0x2d0(%rsp), %eax
movl %eax, %edx
callq 0x7b740
jmp 0xaf5e0
movq 0x270(%rsp), %rax
movq %rax, 0xf0(%rsp)
cmpq $0x0, %rax
je 0xaf603
movq 0xf0(%rsp), %rdi
callq 0x785d0
jmp 0xaf64e
movq 0x150(%rsp), %rax
movq %rax, 0xe0(%rsp)
leaq 0x2e0(%rsp), %rdi
callq 0x785e0
movq %rax, 0xe8(%rsp)
jmp 0xaf62c
movq 0xe8(%rsp), %rsi
movq 0xe0(%rsp), %rdi
movl 0x2d0(%rsp), %eax
movl %eax, %edx
callq 0x7b740
jmp 0xaf64c
jmp 0xaf64e
cmpl $0x0, 0x30c(%rsp)
jbe 0xaf87c
movq 0x150(%rsp), %rax
movq %rax, 0xd0(%rsp)
leaq 0x2a8(%rsp), %rdi
callq 0x785e0
movq %rax, 0xd8(%rsp)
jmp 0xaf683
movq 0xd8(%rsp), %rsi
movq 0xd0(%rsp), %rdi
movl 0x2cc(%rsp), %eax
movl %eax, %edx
callq 0x7b740
jmp 0xaf6a3
movl 0x30c(%rsp), %eax
movl %eax, %edi
movq %rdi, 0xc0(%rsp)
callq 0x710e0
movq %rax, 0xc8(%rsp)
jmp 0xaf6c3
movq 0xc8(%rsp), %rdi
movq 0xc0(%rsp), %rdx
xorl %esi, %esi
callq 0x73d00
movq 0xc8(%rsp), %rax
movq %rax, 0x260(%rsp)
movq 0x318(%rsp), %rdi
addq $0x68, %rdi
callq 0x7aba0
movb %al, 0xbf(%rsp)
jmp 0xaf704
movb 0xbf(%rsp), %al
testb $0x1, %al
jne 0xaf79c
jmp 0xaf715
movq 0x318(%rsp), %rdi
addq $0x68, %rdi
callq 0x74cd0
movq %rax, 0xb0(%rsp)
jmp 0xaf730
movq 0xb0(%rsp), %rax
cmpq $0x1, %rax
jne 0xaf76d
movq 0x318(%rsp), %rdi
addq $0x68, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x771c0
movq %rax, 0xa8(%rsp)
jmp 0xaf75d
movq 0xa8(%rsp), %rax
movsbl (%rax), %eax
cmpl $0x2a, %eax
je 0xaf79c
movq 0x318(%rsp), %rdi
addq $0x68, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x771c0
movq %rax, 0xa0(%rsp)
jmp 0xaf78c
movq 0xa0(%rsp), %rax
movsbl (%rax), %eax
cmpl $-0x1, %eax
jne 0xaf7b9
movq 0x260(%rsp), %rdi
movl 0x30c(%rsp), %eax
movl %eax, %edx
movl $0xff, %esi
callq 0x73d00
jmp 0xaf837
movq $0x0, 0x258(%rsp)
movq 0x258(%rsp), %rax
movl 0x30c(%rsp), %ecx
cmpq %rcx, %rax
jae 0xaf835
movq 0x318(%rsp), %rdi
addq $0x68, %rdi
movq 0x258(%rsp), %rsi
callq 0x77cf0
movq %rax, 0x98(%rsp)
jmp 0xaf7fc
movq 0x98(%rsp), %rax
movsbl (%rax), %eax
subl $0x21, %eax
movb %al, %dl
movq 0x260(%rsp), %rax
movq 0x258(%rsp), %rcx
movb %dl, (%rax,%rcx)
movq 0x258(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x258(%rsp)
jmp 0xaf7c5
jmp 0xaf837
movq 0x150(%rsp), %rdi
movq 0x260(%rsp), %rsi
movl 0x30c(%rsp), %eax
movl %eax, %edx
callq 0x7b740
jmp 0xaf857
movq 0x260(%rsp), %rax
movq %rax, 0x90(%rsp)
cmpq $0x0, %rax
je 0xaf87a
movq 0x90(%rsp), %rdi
callq 0x785d0
jmp 0xaf87c
movq 0x150(%rsp), %rax
testb $0x1, 0x40(%rax)
je 0xaffcf
movl 0x308(%rsp), %eax
movl %eax, %edi
movq %rdi, 0x80(%rsp)
callq 0x710e0
movq %rax, 0x88(%rsp)
jmp 0xaf8ae
movq 0x88(%rsp), %rdi
movq 0x80(%rsp), %rdx
xorl %esi, %esi
callq 0x73d00
movq 0x88(%rsp), %rax
movq %rax, 0x250(%rsp)
movq 0x250(%rsp), %rax
movq %rax, 0x70(%rsp)
movq 0x318(%rsp), %rdi
addq $0x88, %rdi
callq 0x785e0
movq %rax, 0x78(%rsp)
jmp 0xaf8fd
movq 0x78(%rsp), %rsi
movq 0x70(%rsp), %rdi
movl 0x308(%rsp), %eax
movl %eax, %edx
callq 0x757c0
movq $0x0, 0x248(%rsp)
movq 0x248(%rsp), %rax
movl 0x308(%rsp), %ecx
cmpq %rcx, %rax
jae 0xaff90
movq 0x248(%rsp), %rax
addq $0x2, %rax
movq %rax, 0x248(%rsp)
movq 0x250(%rsp), %rax
movq 0x248(%rsp), %rcx
movb (%rax,%rcx), %al
movb %al, 0x247(%rsp)
movq 0x248(%rsp), %rax
incq %rax
movq %rax, 0x248(%rsp)
movsbl 0x247(%rsp), %eax
addl $-0x41, %eax
movl %eax, %ecx
movq %rcx, 0x68(%rsp)
subl $0x32, %eax
ja 0xafdc2
movq 0x68(%rsp), %rax
leaq 0x3b5a7(%rip), %rcx     # 0xeaf48
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq 0x248(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x248(%rsp)
jmp 0xafecc
movq 0x250(%rsp), %rdi
movq 0x248(%rsp), %rax
addq %rax, %rdi
callq 0x726d0
jmp 0xaf9dd
movq 0x248(%rsp), %rax
addq $0x2, %rax
movq %rax, 0x248(%rsp)
jmp 0xafecc
movq 0x250(%rsp), %rdi
movq 0x248(%rsp), %rax
addq %rax, %rdi
callq 0x7a7d0
jmp 0xafa10
movq 0x248(%rsp), %rax
addq $0x4, %rax
movq %rax, 0x248(%rsp)
jmp 0xafecc
jmp 0xafa2b
movq 0x250(%rsp), %rax
movq 0x248(%rsp), %rcx
cmpb $0x0, (%rax,%rcx)
je 0xafa57
movq 0x248(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x248(%rsp)
jmp 0xafa2b
movq 0x248(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x248(%rsp)
jmp 0xafecc
movq 0x250(%rsp), %rax
movq 0x248(%rsp), %rcx
movb (%rax,%rcx), %al
movb %al, 0x246(%rsp)
movq 0x248(%rsp), %rax
incq %rax
movq %rax, 0x248(%rsp)
movq 0x250(%rsp), %rdi
movq 0x248(%rsp), %rax
addq %rax, %rdi
callq 0x7a7d0
jmp 0xafab7
movq 0x250(%rsp), %rax
movq 0x248(%rsp), %rcx
movl (%rax,%rcx), %eax
movl %eax, 0x240(%rsp)
movq 0x248(%rsp), %rax
addq $0x4, %rax
movq %rax, 0x248(%rsp)
movl $0x0, 0x23c(%rsp)
movl 0x23c(%rsp), %eax
cmpl 0x240(%rsp), %eax
jge 0xafdbd
movsbl 0x246(%rsp), %eax
movl %eax, 0x64(%rsp)
subl $0x43, %eax
je 0xafb5d
jmp 0xafb17
movl 0x64(%rsp), %eax
subl $0x49, %eax
je 0xafba9
jmp 0xafb26
movl 0x64(%rsp), %eax
subl $0x53, %eax
je 0xafb76
jmp 0xafb31
movl 0x64(%rsp), %eax
subl $0x63, %eax
je 0xafb5d
jmp 0xafb3c
movl 0x64(%rsp), %eax
subl $0x66, %eax
je 0xafba9
jmp 0xafb47
movl 0x64(%rsp), %eax
subl $0x69, %eax
je 0xafba9
jmp 0xafb52
movl 0x64(%rsp), %eax
subl $0x73, %eax
je 0xafb76
jmp 0xafbdc
movq 0x248(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x248(%rsp)
jmp 0xafce6
movq 0x250(%rsp), %rdi
movq 0x248(%rsp), %rax
addq %rax, %rdi
callq 0x726d0
jmp 0xafb90
movq 0x248(%rsp), %rax
addq $0x2, %rax
movq %rax, 0x248(%rsp)
jmp 0xafce6
movq 0x250(%rsp), %rdi
movq 0x248(%rsp), %rax
addq %rax, %rdi
callq 0x7a7d0
jmp 0xafbc3
movq 0x248(%rsp), %rax
addq $0x4, %rax
movq %rax, 0x248(%rsp)
jmp 0xafce6
movq 0x250(%rsp), %rax
movq %rax, 0x58(%rsp)
cmpq $0x0, %rax
je 0xafbf9
movq 0x58(%rsp), %rdi
callq 0x785d0
leaq 0x1f7(%rsp), %rdi
movq %rdi, 0x50(%rsp)
callq 0x7b5f0
movq 0x50(%rsp), %rdx
leaq 0x3a63f(%rip), %rsi     # 0xea256
leaq 0x1f8(%rsp), %rdi
callq 0x78e70
jmp 0xafc26
movsbl 0x246(%rsp), %edx
leaq 0x218(%rsp), %rdi
leaq 0x1f8(%rsp), %rsi
callq 0x74830
jmp 0xafc45
leaq 0x1f8(%rsp), %rdi
callq 0x7cce8
jmp 0xafc54
leaq 0x1f7(%rsp), %rdi
callq 0x76f80
movb $0x1, 0x1ce(%rsp)
movl $0x28, %edi
callq 0x737c0
movq %rax, 0x40(%rsp)
leaq 0x1cf(%rsp), %rdi
movq %rdi, 0x48(%rsp)
callq 0x7b5f0
movq 0x48(%rsp), %rdx
leaq 0x3b3e6(%rip), %rsi     # 0xeb07c
leaq 0x1d0(%rsp), %rdi
callq 0x78e70
jmp 0xafca5
movq 0x40(%rsp), %rdi
leaq 0x1d0(%rsp), %rsi
leaq 0x218(%rsp), %rdx
callq 0x79cd0
jmp 0xafcc1
movq 0x40(%rsp), %rdi
movb $0x0, 0x1ce(%rsp)
movq 0x6223b(%rip), %rsi     # 0x111f10
movq 0x62284(%rip), %rdx     # 0x111f60
callq 0x7b010
jmp 0xb006e
jmp 0xafce8
movl 0x23c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x23c(%rsp)
jmp 0xafaf0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2d8(%rsp)
movl %eax, 0x2d4(%rsp)
jmp 0xafd39
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2d8(%rsp)
movl %eax, 0x2d4(%rsp)
leaq 0x1f8(%rsp), %rdi
callq 0x7cce8
jmp 0xafd37
jmp 0xafd39
leaq 0x1f7(%rsp), %rdi
callq 0x76f80
jmp 0xb0037
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2d8(%rsp)
movl %eax, 0x2d4(%rsp)
jmp 0xafd86
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2d8(%rsp)
movl %eax, 0x2d4(%rsp)
leaq 0x1d0(%rsp), %rdi
callq 0x7cce8
jmp 0xafd84
jmp 0xafd86
leaq 0x1cf(%rsp), %rdi
callq 0x76f80
testb $0x1, 0x1ce(%rsp)
jne 0xafd9f
jmp 0xafda9
movq 0x40(%rsp), %rdi
callq 0x74e00
leaq 0x218(%rsp), %rdi
callq 0x7cce8
jmp 0xafdb8
jmp 0xb0037
jmp 0xafecc
movq 0x250(%rsp), %rax
movq %rax, 0x38(%rsp)
cmpq $0x0, %rax
je 0xafddf
movq 0x38(%rsp), %rdi
callq 0x785d0
leaq 0x187(%rsp), %rdi
movq %rdi, 0x30(%rsp)
callq 0x7b5f0
movq 0x30(%rsp), %rdx
leaq 0x3a475(%rip), %rsi     # 0xea272
leaq 0x188(%rsp), %rdi
callq 0x78e70
jmp 0xafe0c
movsbl 0x247(%rsp), %edx
leaq 0x1a8(%rsp), %rdi
leaq 0x188(%rsp), %rsi
callq 0x74830
jmp 0xafe2b
leaq 0x188(%rsp), %rdi
callq 0x7cce8
jmp 0xafe3a
leaq 0x187(%rsp), %rdi
callq 0x76f80
movb $0x1, 0x15e(%rsp)
movl $0x28, %edi
callq 0x737c0
movq %rax, 0x20(%rsp)
leaq 0x15f(%rsp), %rdi
movq %rdi, 0x28(%rsp)
callq 0x7b5f0
movq 0x28(%rsp), %rdx
leaq 0x3b200(%rip), %rsi     # 0xeb07c
leaq 0x160(%rsp), %rdi
callq 0x78e70
jmp 0xafe8b
movq 0x20(%rsp), %rdi
leaq 0x160(%rsp), %rsi
leaq 0x1a8(%rsp), %rdx
callq 0x79cd0
jmp 0xafea7
movq 0x20(%rsp), %rdi
movb $0x0, 0x15e(%rsp)
movq 0x62055(%rip), %rsi     # 0x111f10
movq 0x6209e(%rip), %rdx     # 0x111f60
callq 0x7b010
jmp 0xb006e
jmp 0xaf921
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2d8(%rsp)
movl %eax, 0x2d4(%rsp)
jmp 0xaff0c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2d8(%rsp)
movl %eax, 0x2d4(%rsp)
leaq 0x188(%rsp), %rdi
callq 0x7cce8
jmp 0xaff0a
jmp 0xaff0c
leaq 0x187(%rsp), %rdi
callq 0x76f80
jmp 0xb0037
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2d8(%rsp)
movl %eax, 0x2d4(%rsp)
jmp 0xaff59
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x2d8(%rsp)
movl %eax, 0x2d4(%rsp)
leaq 0x160(%rsp), %rdi
callq 0x7cce8
jmp 0xaff57
jmp 0xaff59
leaq 0x15f(%rsp), %rdi
callq 0x76f80
testb $0x1, 0x15e(%rsp)
jne 0xaff72
jmp 0xaff7c
movq 0x20(%rsp), %rdi
callq 0x74e00
leaq 0x1a8(%rsp), %rdi
callq 0x7cce8
jmp 0xaff8b
jmp 0xb0037
movq 0x150(%rsp), %rdi
movq 0x250(%rsp), %rsi
movl 0x308(%rsp), %eax
movl %eax, %edx
callq 0x7b740
jmp 0xaffb0
movq 0x250(%rsp), %rax
movq %rax, 0x18(%rsp)
cmpq $0x0, %rax
je 0xaffcd
movq 0x18(%rsp), %rdi
callq 0x785d0
jmp 0xb0013
movq 0x150(%rsp), %rax
movq %rax, 0x8(%rsp)
movq 0x318(%rsp), %rdi
addq $0x88, %rdi
callq 0x785e0
movq %rax, 0x10(%rsp)
jmp 0xafff7
movq 0x10(%rsp), %rsi
movq 0x8(%rsp), %rdi
movl 0x308(%rsp), %eax
movl %eax, %edx
callq 0x7b740
jmp 0xb0011
jmp 0xb0013
leaq 0x2a8(%rsp), %rdi
callq 0x7cce8
jmp 0xb0022
leaq 0x2e0(%rsp), %rdi
callq 0x7cce8
addq $0x328, %rsp            # imm = 0x328
retq
leaq 0x2a8(%rsp), %rdi
callq 0x7cce8
jmp 0xb0046
jmp 0xb0048
leaq 0x2e0(%rsp), %rdi
callq 0x7cce8
jmp 0xb0057
jmp 0xb0059
movq 0x2d8(%rsp), %rdi
callq 0x7b550
movq %rax, %rdi
callq 0x88ef0
nop