// File: ruankotovich[P]B-Tree/src/secondarybtree.cpp
// Function: SecondaryBTree::insertRecursive(SecondaryBTreeDataMap&, SecondaryBTreeNodeReinterpret*, int, _IO_FILE*)
SecondaryBTreeRecursionResponse SecondaryBTree::insertRecursive(SecondaryBTreeDataMap& key, SecondaryBTreeNodeReinterpret* nodeReinterpretation, int offset, FILE* indexFile)
{
    for (unsigned short i = 0; i < nodeReinterpretation->node.count; ++i) {
        if (nodeReinterpretation->node.keys[i] == key) return SUCCESSFUL_TREE_INSERTION;
    }

    if (nodeReinterpretation->node.isLeaf()) {

        if (nodeReinterpretation->node.hasRoom()) {
            nodeReinterpretation->node.insert(key);
            writeBackNode(&nodeReinterpretation->node, offset, indexFile);
            return SUCCESSFUL_TREE_INSERTION;
        }

        SecondaryBTreeNode* splitLeaf = new SecondaryBTreeNode(SECONDARY_MAX_KEYS);
        SecondaryBTreeDataMap promoted;

        // elege o promoted e manipula os vetores resultantes da operação do splitLeaf.
        SecondaryBTreeDataMap leftMiddleKey = nodeReinterpretation->node.keys[SECONDARY_LEFT_MIDDLE_KEY];
        SecondaryBTreeDataMap rightMiddleKey = nodeReinterpretation->node.keys[SECONDARY_RIGHT_MIDDLE_KEY];

        splitLeaf->count = nodeReinterpretation->node.count = SECONDARY_HALF_MAX_KEYS;

        switch (relativeKeyPosition(key, leftMiddleKey, rightMiddleKey)) {
        case RELATIVE_LEFT: {
            promoted = leftMiddleKey;
            --nodeReinterpretation->node.count;

            nodeReinterpretation->node.insert(key);

            for (int i = SECONDARY_HALF_MAX_KEYS, j = 0; i < SECONDARY_MAX_KEYS; ++i, ++j) {
                splitLeaf->keys[j] = nodeReinterpretation->node.keys[i];
            }
        } // não esquecer de manipular os blockPointes para nós não-folha
        break;

        case RELATIVE_RIGHT: {
            promoted = rightMiddleKey;
            --splitLeaf->count;

            for (int i = SECONDARY_RIGHT_MIDDLE_KEY + 1, j = 0; i < SECONDARY_MAX_KEYS; ++i, ++j) {
                splitLeaf->keys[j] = nodeReinterpretation->node.keys[i];
            } // não esquecer de manipular os blockPointes para nós não-folha

            splitLeaf->insert(key);
        } break;

        case RELATIVE_MIDDLE: {
            promoted = key;

            for (int i = SECONDARY_HALF_MAX_KEYS, j = 0; i < SECONDARY_MAX_KEYS; ++i, ++j) {
                splitLeaf->keys[j] = nodeReinterpretation->node.keys[i];
            }
        } // não esquecer de manipular os blockPointes para nós não-folha

        break;
        }

        writeBackNode(&nodeReinterpretation->node, offset, indexFile);
        int offset = writeNewNode(splitLeaf, indexFile);

        delete splitLeaf; // deleta da memória principal pois já foi salvo no disco

        // return { true, { promoted, offset } };
        return SecondaryBTreeRecursionResponse(true, promoted, offset);
    }
    //key.key[299] = '\0';
    int result = upperBound(nodeReinterpretation->node.keys, nodeReinterpretation->node.count, key); // [TROCAR]

    //auto resultPair = u(nodeReinterpretation->node.keys, nodeReinterpretation->node.count, key);
    int childNodeOffset;

    if (result >= nodeReinterpretation->node.count) {
        childNodeOffset = result;
        result = nodeReinterpretation->node.count - 1;
    }

    childNodeOffset = ((key < nodeReinterpretation->node.keys[result]) ? nodeReinterpretation->node.blockPointers[result] : nodeReinterpretation->node.blockPointers[result + 1]);

    SecondaryBTreeNodeReinterpret* retrieveNode = new SecondaryBTreeNodeReinterpret();
    fseek(indexFile, sizeof(AbstractBlock_t) * childNodeOffset, SEEK_SET);
    fread(&retrieveNode->block, sizeof(AbstractBlock_t), 1, indexFile);

    auto resultRecursion = insertRecursive(key, retrieveNode, childNodeOffset, indexFile);
    delete retrieveNode;

    if (resultRecursion.hasBeenSplit) { // caso em que veio um valor promovido e um blockPointer
        //caso 1 - tem espaço para inserir o promovido
        if (nodeReinterpretation->node.hasRoom()) {
            //o + 1 é para não realizar essa soma em toda iteração do for logo abaixo
            int rightIndexInserted = nodeReinterpretation->node.insert(resultRecursion.promotedKey) + 1;

            for (unsigned short i = nodeReinterpretation->node.countPointers; i > rightIndexInserted; --i) {
                nodeReinterpretation->node.blockPointers[i] = nodeReinterpretation->node.blockPointers[i - 1];
            }

            nodeReinterpretation->node.blockPointers[rightIndexInserted] = resultRecursion.newBlockOffset;
            ++nodeReinterpretation->node.countPointers;

            writeBackNode(&nodeReinterpretation->node, offset, indexFile);
        } else { // caso 2 - não tem espaço para inserir o promovido -> fazer o split com remanejamento de chaves
            SecondaryBTreeNodeReinterpret* split = new SecondaryBTreeNodeReinterpret();
            SecondaryBTreeDataMap promoted;

            // elege o promoted e manipula os vetores resultantes da operação do split.
            SecondaryBTreeDataMap leftMiddleKey = nodeReinterpretation->node.keys[SECONDARY_LEFT_MIDDLE_KEY];
            SecondaryBTreeDataMap rightMiddleKey = nodeReinterpretation->node.keys[SECONDARY_RIGHT_MIDDLE_KEY];

            split->node.count = nodeReinterpretation->node.count = SECONDARY_HALF_MAX_KEYS; // remoção lógica exatamente na metade

            //como está cheio, vai metade dos elementos para cada bloco, contnado com o split.
            // se vai metade, haverá metade + 1 ponteiros para bloco preenchidos.
            split->node.countPointers = nodeReinterpretation->node.countPointers = SECONDARY_HALF_MAX_KEYS + 1;

            switch (relativeKeyPosition(resultRecursion.promotedKey, leftMiddleKey, rightMiddleKey)) {
            case RELATIVE_LEFT: {
                promoted = leftMiddleKey;

                --nodeReinterpretation->node.count;

                // índice do ponteiro mais à direita do vetor blockPointers
                int greaterNodeBlockPointer = nodeReinterpretation->node.blockPointers[nodeReinterpretation->node.countPointers - 1]; // a subtração tem a ver com índice

                //índice em que foi inserido o promovido no nó já existente
                int rightIndexInserted = nodeReinterpretation->node.insert(resultRecursion.promotedKey) + 1;

                //remanejar os blockPoints
                for (int i = nodeReinterpretation->node.countPointers - 1; i > rightIndexInserted; --i) {
                    nodeReinterpretation->node.blockPointers[i] = nodeReinterpretation->node.blockPointers[i - 1];
                }

                nodeReinterpretation->node.blockPointers[rightIndexInserted] = resultRecursion.newBlockOffset;

                for (int i = SECONDARY_HALF_MAX_KEYS, j = 0; i < SECONDARY_MAX_KEYS; ++i, ++j) {
                    split->node.keys[j] = nodeReinterpretation->node.keys[i];
                    split->node.blockPointers[j + 1] = nodeReinterpretation->node.blockPointers[i + 1];
                } // não esquecer de manipular os blockPointes para nós não-folha

                split->node.blockPointers[0] = greaterNodeBlockPointer;
            } break;

            case RELATIVE_RIGHT: {
                promoted = rightMiddleKey;
                --split->node.count;
                // não é preciso modificar o countPointers nem o count do node aqui porque eles já foram atribuidos ali em cima,
                // então a remoção lógica já foi feita

                for (int i = SECONDARY_RIGHT_MIDDLE_KEY + 1, j = 0; i < SECONDARY_MAX_KEYS; ++i, ++j) {
                    split->node.keys[j] = nodeReinterpretation->node.keys[i];
                    split->node.blockPointers[j] = nodeReinterpretation->node.blockPointers[i];
                } // não esquecer de manipular os blockPointes para nós não-folha/

                split->node.blockPointers[SECONDARY_HALF_MAX_KEYS - 1] = nodeReinterpretation->node.blockPointers[SECONDARY_MAX_KEYS];
                int rightIndexInserted = split->node.insert(resultRecursion.promotedKey) + 1;

                //remanejar os blockPoints
                for (unsigned short i = split->node.countPointers - 1; i > rightIndexInserted; --i) {
                    split->node.blockPointers[i] = split->node.blockPointers[i - 1];
                }

                split->node.blockPointers[rightIndexInserted] = resultRecursion.newBlockOffset;
            } break;

            case RELATIVE_MIDDLE: {
                promoted = resultRecursion.promotedKey;

                for (int i = SECONDARY_HALF_MAX_KEYS, j = 0; i < SECONDARY_MAX_KEYS; ++i, ++j) {
                    split->node.keys[j] = nodeReinterpretation->node.keys[i];
                    split->node.blockPointers[j + 1] = nodeReinterpretation->node.blockPointers[i + 1];
                } // não esquecer de manipular os blockPointes para nós não-folha
                split->node.blockPointers[0] = resultRecursion.newBlockOffset;
            } break;
            }

            writeBackNode(&nodeReinterpretation->node, offset, indexFile);
            int offset = writeNewNode(&split->node, indexFile);
            delete split; // deleta da memória principal pois já foi salvo no disco
            return SecondaryBTreeRecursionResponse(true, promoted, offset);
        }
    }

    return SUCCESSFUL_TREE_INSERTION;
    // return SecondaryBTreeRecursionResponse(false, 0, 0);
    // return { false, { 0, 0 } };*/
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xc10, %rsp            # imm = 0xC10
movq %rdi, -0xa58(%rbp)
movq %rdi, -0xa50(%rbp)
movq %rsi, -0x8(%rbp)
movq %rdx, -0x10(%rbp)
movq %rcx, -0x18(%rbp)
movl %r8d, -0x1c(%rbp)
movq %r9, -0x28(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0xa48(%rbp)
movw $0x0, -0x2a(%rbp)
movzwl -0x2a(%rbp), %eax
movq -0x18(%rbp), %rcx
movzwl (%rcx), %ecx
cmpl %ecx, %eax
jge 0x1ecf
movq -0x18(%rbp), %rdi
addq $0x4, %rdi
movzwl -0x2a(%rbp), %eax
imulq $0x130, %rax, %rax      # imm = 0x130
addq %rax, %rdi
movq -0x10(%rbp), %rsi
callq 0x1ae0
testb $0x1, %al
jne 0x1ea2
jmp 0x1ebf
movq -0xa48(%rbp), %rsi
movq -0xa58(%rbp), %rdi
movl $0x138, %edx            # imm = 0x138
callq 0x1070
jmp 0x2a88
jmp 0x1ec1
movw -0x2a(%rbp), %ax
addw $0x1, %ax
movw %ax, -0x2a(%rbp)
jmp 0x1e6e
movq -0x18(%rbp), %rdi
callq 0x1b70
testb $0x1, %al
jne 0x1ee1
jmp 0x2262
movq -0x18(%rbp), %rdi
callq 0x1b90
testb $0x1, %al
jne 0x1ef0
jmp 0x1f2a
movq -0x18(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x1bb0
movq -0x18(%rbp), %rdi
movl -0x1c(%rbp), %esi
movq -0x28(%rbp), %rdx
callq 0x30d0
movq -0xa58(%rbp), %rdi
movq -0xa48(%rbp), %rsi
movl $0x138, %edx            # imm = 0x138
callq 0x1070
jmp 0x2a88
movl $0xe78, %edi            # imm = 0xE78
callq 0x10b0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0xa60(%rbp)
movl $0xc, %esi
callq 0x1ac0
jmp 0x1f4d
movq -0xa60(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x18(%rbp), %rsi
addq $0x5f4, %rsi            # imm = 0x5F4
leaq -0x2a4(%rbp), %rdi
movq %rdi, -0xa78(%rbp)
movl $0x130, %edx            # imm = 0x130
movq %rdx, -0xa80(%rbp)
callq 0x1070
movq -0xa80(%rbp), %rdx
movq -0x18(%rbp), %rsi
addq $0x724, %rsi            # imm = 0x724
leaq -0x3d4(%rbp), %rdi
movq %rdi, -0xa70(%rbp)
callq 0x1070
movq -0xa78(%rbp), %rsi
movq -0xa70(%rbp), %rdx
movq -0x18(%rbp), %rax
movw $0x6, (%rax)
movq -0x38(%rbp), %rax
movw $0x6, (%rax)
movq -0x10(%rbp), %rdi
callq 0x3120
movsbl %al, %eax
movl %eax, -0xa64(%rbp)
subl $-0x1, %eax
je 0x2026
jmp 0x1fe0
movl -0xa64(%rbp), %eax
testl %eax, %eax
je 0x2174
jmp 0x1ff0
movl -0xa64(%rbp), %eax
subl $0x1, %eax
je 0x20cd
jmp 0x21fa
movq -0xa60(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
movl $0xe78, %esi            # imm = 0xE78
callq 0x10c0
jmp 0x2a98
leaq -0x174(%rbp), %rdi
leaq -0x2a4(%rbp), %rsi
callq 0x1a60
movq -0x18(%rbp), %rax
movw (%rax), %cx
addw $-0x1, %cx
movw %cx, (%rax)
movq -0x18(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x1bb0
movl $0x6, -0x3d8(%rbp)
movl $0x0, -0x3dc(%rbp)
cmpl $0xc, -0x3d8(%rbp)
jge 0x20c8
movq -0x18(%rbp), %rsi
addq $0x4, %rsi
movslq -0x3d8(%rbp), %rax
imulq $0x130, %rax, %rax      # imm = 0x130
addq %rax, %rsi
movq -0x38(%rbp), %rdi
addq $0x4, %rdi
movslq -0x3dc(%rbp), %rax
imulq $0x130, %rax, %rax      # imm = 0x130
addq %rax, %rdi
callq 0x1a60
movl -0x3d8(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3d8(%rbp)
movl -0x3dc(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3dc(%rbp)
jmp 0x2068
jmp 0x21fa
leaq -0x174(%rbp), %rdi
leaq -0x3d4(%rbp), %rsi
callq 0x1a60
movq -0x38(%rbp), %rax
movw (%rax), %cx
addw $-0x1, %cx
movw %cx, (%rax)
movl $0x7, -0x3e0(%rbp)
movl $0x0, -0x3e4(%rbp)
cmpl $0xc, -0x3e0(%rbp)
jge 0x2162
movq -0x18(%rbp), %rsi
addq $0x4, %rsi
movslq -0x3e0(%rbp), %rax
imulq $0x130, %rax, %rax      # imm = 0x130
addq %rax, %rsi
movq -0x38(%rbp), %rdi
addq $0x4, %rdi
movslq -0x3e4(%rbp), %rax
imulq $0x130, %rax, %rax      # imm = 0x130
addq %rax, %rdi
callq 0x1a60
movl -0x3e0(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3e0(%rbp)
movl -0x3e4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3e4(%rbp)
jmp 0x2102
movq -0x38(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x1bb0
jmp 0x21fa
movq -0x10(%rbp), %rsi
leaq -0x174(%rbp), %rdi
callq 0x1a60
movl $0x6, -0x3e8(%rbp)
movl $0x0, -0x3ec(%rbp)
cmpl $0xc, -0x3e8(%rbp)
jge 0x21f8
movq -0x18(%rbp), %rsi
addq $0x4, %rsi
movslq -0x3e8(%rbp), %rax
imulq $0x130, %rax, %rax      # imm = 0x130
addq %rax, %rsi
movq -0x38(%rbp), %rdi
addq $0x4, %rdi
movslq -0x3ec(%rbp), %rax
imulq $0x130, %rax, %rax      # imm = 0x130
addq %rax, %rdi
callq 0x1a60
movl -0x3e8(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3e8(%rbp)
movl -0x3ec(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3ec(%rbp)
jmp 0x2198
jmp 0x21fa
movq -0x18(%rbp), %rdi
movl -0x1c(%rbp), %esi
movq -0x28(%rbp), %rdx
callq 0x30d0
movq -0x38(%rbp), %rdi
movq -0x28(%rbp), %rsi
callq 0x3180
movl %eax, -0x3f0(%rbp)
movq -0x38(%rbp), %rax
movq %rax, -0xa88(%rbp)
cmpq $0x0, %rax
je 0x223f
movq -0xa88(%rbp), %rdi
movl $0xe78, %esi            # imm = 0xE78
callq 0x10c0
movq -0xa58(%rbp), %rdi
movl -0x3f0(%rbp), %ecx
movl $0x1, %esi
leaq -0x174(%rbp), %rdx
callq 0x1a10
jmp 0x2a88
movq -0x18(%rbp), %rax
addq $0x4, %rax
movq %rax, -0xa90(%rbp)
movq -0x18(%rbp), %rax
movzwl (%rax), %eax
movl %eax, -0xa94(%rbp)
movq -0x10(%rbp), %rsi
leaq -0x528(%rbp), %rdi
movl $0x130, %edx            # imm = 0x130
callq 0x1070
movq %rsp, %rdi
movl $0x26, %ecx
leaq -0x528(%rbp), %rsi
rep  movsq (%rsi), %es:(%rdi)
movl -0xa94(%rbp), %esi
movq -0xa90(%rbp), %rdi
callq 0x2ab0
movl %eax, -0x3f4(%rbp)
movl -0x3f4(%rbp), %eax
movq -0x18(%rbp), %rcx
movzwl (%rcx), %ecx
cmpl %ecx, %eax
jl 0x22ea
movl -0x3f4(%rbp), %eax
movl %eax, -0x52c(%rbp)
movq -0x18(%rbp), %rax
movzwl (%rax), %eax
subl $0x1, %eax
movl %eax, -0x3f4(%rbp)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
addq $0x4, %rsi
movslq -0x3f4(%rbp), %rax
imulq $0x130, %rax, %rax      # imm = 0x130
addq %rax, %rsi
callq 0x1b10
testb $0x1, %al
jne 0x2312
jmp 0x232c
movq -0x18(%rbp), %rax
movslq -0x3f4(%rbp), %rcx
movl 0xe44(%rax,%rcx,4), %eax
movl %eax, -0xa98(%rbp)
jmp 0x2349
movq -0x18(%rbp), %rax
movl -0x3f4(%rbp), %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
movl 0xe44(%rax,%rcx,4), %eax
movl %eax, -0xa98(%rbp)
movl -0xa98(%rbp), %eax
movl %eax, -0x52c(%rbp)
movl $0x1000, %edi           # imm = 0x1000
callq 0x10b0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0xaa0(%rbp)
callq 0x30b0
jmp 0x2373
movq -0xaa0(%rbp), %rax
movq %rax, -0x538(%rbp)
movq -0x28(%rbp), %rdi
movslq -0x52c(%rbp), %rsi
shlq $0xc, %rsi
xorl %edx, %edx
callq 0x10d0
movq -0x538(%rbp), %rdi
movq -0x28(%rbp), %rcx
movl $0x1000, %esi           # imm = 0x1000
movl $0x1, %edx
callq 0x1100
movq -0xa48(%rbp), %rsi
movq -0x10(%rbp), %rdx
movq -0x538(%rbp), %rcx
movl -0x52c(%rbp), %r8d
movq -0x28(%rbp), %r9
leaq -0x670(%rbp), %rdi
callq 0x1e30
movq -0x538(%rbp), %rax
movq %rax, -0xaa8(%rbp)
cmpq $0x0, %rax
je 0x23ff
movq -0xaa8(%rbp), %rdi
movl $0x1000, %esi           # imm = 0x1000
callq 0x10c0
testb $0x1, -0x670(%rbp)
je 0x2a70
movq -0x18(%rbp), %rdi
callq 0x1b90
testb $0x1, %al
jne 0x241e
jmp 0x24f6
movq -0x18(%rbp), %rdi
leaq -0x670(%rbp), %rsi
addq $0x4, %rsi
callq 0x1bb0
addl $0x1, %eax
movl %eax, -0x674(%rbp)
movq -0x18(%rbp), %rax
movw 0x2(%rax), %ax
movw %ax, -0x676(%rbp)
movzwl -0x676(%rbp), %eax
cmpl -0x674(%rbp), %eax
jle 0x24b9
movq -0x18(%rbp), %rax
movzwl -0x676(%rbp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
movl 0xe44(%rax,%rcx,4), %edx
movq -0x18(%rbp), %rax
movzwl -0x676(%rbp), %ecx
movl %edx, 0xe44(%rax,%rcx,4)
movw -0x676(%rbp), %ax
addw $-0x1, %ax
movw %ax, -0x676(%rbp)
jmp 0x244a
movq -0xaa0(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
movl $0x1000, %esi           # imm = 0x1000
callq 0x10c0
jmp 0x2a98
movl -0x53c(%rbp), %edx
movq -0x18(%rbp), %rax
movslq -0x674(%rbp), %rcx
movl %edx, 0xe44(%rax,%rcx,4)
movq -0x18(%rbp), %rax
movw 0x2(%rax), %cx
addw $0x1, %cx
movw %cx, 0x2(%rax)
movq -0x18(%rbp), %rdi
movl -0x1c(%rbp), %esi
movq -0x28(%rbp), %rdx
callq 0x30d0
jmp 0x2a6e
movl $0x1000, %edi           # imm = 0x1000
callq 0x10b0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0xab0(%rbp)
callq 0x30b0
jmp 0x2514
movq -0xab0(%rbp), %rax
movq %rax, -0x680(%rbp)
movq -0x18(%rbp), %rsi
addq $0x5f4, %rsi            # imm = 0x5F4
leaq -0x8e0(%rbp), %rdi
movq %rdi, -0xac8(%rbp)
movl $0x130, %edx            # imm = 0x130
movq %rdx, -0xad0(%rbp)
callq 0x1070
movq -0xad0(%rbp), %rdx
movq -0x18(%rbp), %rsi
addq $0x724, %rsi            # imm = 0x724
leaq -0xa10(%rbp), %rdi
movq %rdi, -0xac0(%rbp)
callq 0x1070
movq -0xac8(%rbp), %rsi
movq -0xac0(%rbp), %rdx
movq -0x18(%rbp), %rax
movw $0x6, (%rax)
movq -0x680(%rbp), %rax
movw $0x6, (%rax)
movq -0x18(%rbp), %rax
movw $0x7, 0x2(%rax)
movq -0x680(%rbp), %rax
movw $0x7, 0x2(%rax)
leaq -0x66c(%rbp), %rdi
callq 0x3120
movsbl %al, %eax
movl %eax, -0xab4(%rbp)
subl $-0x1, %eax
je 0x260d
jmp 0x25c7
movl -0xab4(%rbp), %eax
testl %eax, %eax
je 0x292a
jmp 0x25d7
movl -0xab4(%rbp), %eax
subl $0x1, %eax
je 0x27a2
jmp 0x2a03
movq -0xab0(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
movl $0x1000, %esi           # imm = 0x1000
callq 0x10c0
jmp 0x2a98
leaq -0x7b0(%rbp), %rdi
leaq -0x8e0(%rbp), %rsi
callq 0x1a60
movq -0x18(%rbp), %rax
movw (%rax), %cx
addw $-0x1, %cx
movw %cx, (%rax)
movq -0x18(%rbp), %rax
movq -0x18(%rbp), %rcx
movzwl 0x2(%rcx), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
movl 0xe44(%rax,%rcx,4), %eax
movl %eax, -0xa14(%rbp)
movq -0x18(%rbp), %rdi
leaq -0x670(%rbp), %rsi
addq $0x4, %rsi
callq 0x1bb0
addl $0x1, %eax
movl %eax, -0xa18(%rbp)
movq -0x18(%rbp), %rax
movzwl 0x2(%rax), %eax
subl $0x1, %eax
movl %eax, -0xa1c(%rbp)
movl -0xa1c(%rbp), %eax
cmpl -0xa18(%rbp), %eax
jle 0x26c3
movq -0x18(%rbp), %rax
movl -0xa1c(%rbp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
movl 0xe44(%rax,%rcx,4), %edx
movq -0x18(%rbp), %rax
movslq -0xa1c(%rbp), %rcx
movl %edx, 0xe44(%rax,%rcx,4)
movl -0xa1c(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0xa1c(%rbp)
jmp 0x267b
movl -0x53c(%rbp), %edx
movq -0x18(%rbp), %rax
movslq -0xa18(%rbp), %rcx
movl %edx, 0xe44(%rax,%rcx,4)
movl $0x6, -0xa20(%rbp)
movl $0x0, -0xa24(%rbp)
cmpl $0xc, -0xa20(%rbp)
jge 0x278a
movq -0x18(%rbp), %rsi
addq $0x4, %rsi
movslq -0xa20(%rbp), %rax
imulq $0x130, %rax, %rax      # imm = 0x130
addq %rax, %rsi
movq -0x680(%rbp), %rdi
addq $0x4, %rdi
movslq -0xa24(%rbp), %rax
imulq $0x130, %rax, %rax      # imm = 0x130
addq %rax, %rdi
callq 0x1a60
movq -0x18(%rbp), %rax
movl -0xa20(%rbp), %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
movl 0xe44(%rax,%rcx,4), %edx
movq -0x680(%rbp), %rax
movl -0xa24(%rbp), %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
movl %edx, 0xe44(%rax,%rcx,4)
movl -0xa20(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xa20(%rbp)
movl -0xa24(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xa24(%rbp)
jmp 0x26ef
movl -0xa14(%rbp), %ecx
movq -0x680(%rbp), %rax
movl %ecx, 0xe44(%rax)
jmp 0x2a03
leaq -0x7b0(%rbp), %rdi
leaq -0xa10(%rbp), %rsi
callq 0x1a60
movq -0x680(%rbp), %rax
movw (%rax), %cx
addw $-0x1, %cx
movw %cx, (%rax)
movl $0x7, -0xa28(%rbp)
movl $0x0, -0xa2c(%rbp)
cmpl $0xc, -0xa28(%rbp)
jge 0x286b
movq -0x18(%rbp), %rsi
addq $0x4, %rsi
movslq -0xa28(%rbp), %rax
imulq $0x130, %rax, %rax      # imm = 0x130
addq %rax, %rsi
movq -0x680(%rbp), %rdi
addq $0x4, %rdi
movslq -0xa2c(%rbp), %rax
imulq $0x130, %rax, %rax      # imm = 0x130
addq %rax, %rdi
callq 0x1a60
movq -0x18(%rbp), %rax
movslq -0xa28(%rbp), %rcx
movl 0xe44(%rax,%rcx,4), %edx
movq -0x680(%rbp), %rax
movslq -0xa2c(%rbp), %rcx
movl %edx, 0xe44(%rax,%rcx,4)
movl -0xa28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xa28(%rbp)
movl -0xa2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xa2c(%rbp)
jmp 0x27da
movq -0x18(%rbp), %rax
movl 0xe74(%rax), %ecx
movq -0x680(%rbp), %rax
movl %ecx, 0xe58(%rax)
movq -0x680(%rbp), %rdi
leaq -0x670(%rbp), %rsi
addq $0x4, %rsi
callq 0x1bb0
addl $0x1, %eax
movl %eax, -0xa30(%rbp)
movq -0x680(%rbp), %rax
movzwl 0x2(%rax), %eax
subl $0x1, %eax
movw %ax, -0xa32(%rbp)
movzwl -0xa32(%rbp), %eax
cmpl -0xa30(%rbp), %eax
jle 0x290a
movq -0x680(%rbp), %rax
movzwl -0xa32(%rbp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
movl 0xe44(%rax,%rcx,4), %edx
movq -0x680(%rbp), %rax
movzwl -0xa32(%rbp), %ecx
movl %edx, 0xe44(%rax,%rcx,4)
movw -0xa32(%rbp), %ax
addw $-0x1, %ax
movw %ax, -0xa32(%rbp)
jmp 0x28b7
movl -0x53c(%rbp), %edx
movq -0x680(%rbp), %rax
movslq -0xa30(%rbp), %rcx
movl %edx, 0xe44(%rax,%rcx,4)
jmp 0x2a03
leaq -0x670(%rbp), %rsi
addq $0x4, %rsi
leaq -0x7b0(%rbp), %rdi
callq 0x1a60
movl $0x6, -0xa38(%rbp)
movl $0x0, -0xa3c(%rbp)
cmpl $0xc, -0xa38(%rbp)
jge 0x29f0
movq -0x18(%rbp), %rsi
addq $0x4, %rsi
movslq -0xa38(%rbp), %rax
imulq $0x130, %rax, %rax      # imm = 0x130
addq %rax, %rsi
movq -0x680(%rbp), %rdi
addq $0x4, %rdi
movslq -0xa3c(%rbp), %rax
imulq $0x130, %rax, %rax      # imm = 0x130
addq %rax, %rdi
callq 0x1a60
movq -0x18(%rbp), %rax
movl -0xa38(%rbp), %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
movl 0xe44(%rax,%rcx,4), %edx
movq -0x680(%rbp), %rax
movl -0xa3c(%rbp), %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
movl %edx, 0xe44(%rax,%rcx,4)
movl -0xa38(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xa38(%rbp)
movl -0xa3c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xa3c(%rbp)
jmp 0x2955
movl -0x53c(%rbp), %ecx
movq -0x680(%rbp), %rax
movl %ecx, 0xe44(%rax)
movq -0x18(%rbp), %rdi
movl -0x1c(%rbp), %esi
movq -0x28(%rbp), %rdx
callq 0x30d0
movq -0x680(%rbp), %rdi
movq -0x28(%rbp), %rsi
callq 0x3180
movl %eax, -0xa40(%rbp)
movq -0x680(%rbp), %rax
movq %rax, -0xad8(%rbp)
cmpq $0x0, %rax
je 0x2a4e
movq -0xad8(%rbp), %rdi
movl $0x1000, %esi           # imm = 0x1000
callq 0x10c0
movq -0xa58(%rbp), %rdi
movl -0xa40(%rbp), %ecx
movl $0x1, %esi
leaq -0x7b0(%rbp), %rdx
callq 0x1a10
jmp 0x2a88
jmp 0x2a70
movq -0xa48(%rbp), %rsi
movq -0xa58(%rbp), %rdi
movl $0x138, %edx            # imm = 0x138
callq 0x1070
movq -0xa50(%rbp), %rax
addq $0xc10, %rsp            # imm = 0xC10
popq %rbp
retq
movq -0x40(%rbp), %rdi
callq 0x1140
nopw %cs:(%rax,%rax)