// File: /workspace/github_cpp_makefile_star2_O3/Computer-Kids-Club[P]screenshare-pro-backend/server.cpp
// Function: main
int main(int argc, char *argv[]) {
    int opt = TRUE;
    int master_socket, addrlen, new_socket,
        max_clients = 30, activity, i, valread, sd;
    int max_sd;
    struct sockaddr_in address;

    bool doPrintSocketFrame = false;
    bool doPrintSocketFrameStats = false;

    // yes
    for (int i = 0; i < argc; i++) {
        if (argv[i][0] == '-') {
            if (strcmp(argv[i], "-pf") == 0) {
                doPrintSocketFrame = true;
            } else if (strcmp(argv[i], "-pfs") == 0) {
                doPrintSocketFrameStats = true;
            }
        }
    }

    unsigned long long totalFramesRecieved = 1;
    unsigned long long totalFramesSent = 1;
    unsigned long long lastFrameLength = 0;
    unsigned long long totalFrameLength = 0;

    std::unordered_map<std::string, int> urlToSocketDesc;
    std::unordered_map<int, std::vector<Client>> socketDescToClients;
    std::unordered_map<int, int> clientSocketDescToStreamerSocketDesc;
    std::unordered_map<int, Client> clients;

    char buffer[BUFFER_SIZE + 1];       //data buffer of 1K
    char send_buffer[BUFFER_SIZE + 1];  //data buffer of 1K

    //set of socket descriptors
    fd_set readfds;

    //create a master socket
    if ((master_socket = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
        perror("socket failed");
        exit(EXIT_FAILURE);
    }

    //set master socket to allow multiple connections ,
    //this is just a good habit, it will work without this
    if (setsockopt(master_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&opt,
                   sizeof(opt)) < 0) {
        perror("setsockopt");
        exit(EXIT_FAILURE);
    }

    //type of socket created
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons(PORT);

    //bind the socket to localhost port 4004
    if (0 > bind(master_socket, (struct sockaddr *)&address, sizeof(address))) {
        perror("bind failed");
        exit(EXIT_FAILURE);
    }
    printf(COLOR_RESET "Listener on port %d \n", PORT);

    //try to specify maximum of 3 pending connections for the master socket
    if (listen(master_socket, 3) < 0) {
        perror("listen");
        exit(EXIT_FAILURE);
    }

    //accept the incoming connection
    addrlen = sizeof(address);
    puts("Waiting for connections ...");

    while (TRUE) {
        //clear the socket set
        FD_ZERO(&readfds);

        //add master socket to set
        FD_SET(master_socket, &readfds);
        max_sd = master_socket;

        //add child sockets to set
        for (auto &clientFromClients : clients) {
            Client client = clientFromClients.second;
            //socket descriptor
            sd = client.socket_descriptor;

            //if valid socket descriptor then add to read list
            if (sd > 0)
                FD_SET(sd, &readfds);

            //highest file descriptor number, need it for the select function
            if (sd > max_sd)
                max_sd = sd;

            if (client.last_ping != -1) {
                if (client.last_ping != -1) {
                }
            }
        }

        //wait for an activity on one of the sockets , timeout is NULL ,
        //so wait indefinitely
        activity = select(max_sd + 1, &readfds, NULL, NULL, NULL);

        if ((activity < 0) && (errno != EINTR)) {
            printf("select error");
        }

        //If something happened on the master socket ,
        //then its an incoming connection
        if (FD_ISSET(master_socket, &readfds)) {
            if (0 > (new_socket = accept(master_socket, (struct sockaddr *)&address, (socklen_t *)&addrlen))) {
                perror("accept");
                exit(EXIT_FAILURE);
            }

            //inform user of socket number - used in send and receive commands
            printf(GREEN("New connection , socket fd is %d , ip is : %s , port : %d  \n"), new_socket, inet_ntoa(address.sin_addr), ntohs(address.sin_port));

            //puts("Welcome message sent successfully");

            clients[new_socket] = {new_socket, 0, "", -1};
            // clients.push_back({new_socket, 0});
            //printf("Adding to list of sockets as %d\n", i);
        }

        //else its some IO operation on some other socket
        // for (auto socketClientPair = clients.begin(); socketClientPair != clients.end(); ++socketClientPair) { //&socketClientPair : clients)
        auto it = clients.begin();
        while (it != clients.end()) {
            if (doPrintSocketFrameStats) {
                printf(COLOR_RESET "Total frames recieved: %llu\n", totalFramesRecieved);
                printf(COLOR_RESET "Total frames sent: %llu\n", totalFramesSent);
                printf(COLOR_RESET "Last frame length: %llu\n", lastFrameLength);
                printf(COLOR_RESET "Average frame length: %llu\n\n", totalFrameLength / totalFramesRecieved);
            }

            Client client = it->second;
            auto previous_it = it;
            ++it;
            //socket descriptor
            sd = client.socket_descriptor;
            if (FD_ISSET(sd, &readfds)) {
                //Check if it was for closing , and also read the
                //incoming message
                memset(buffer, 0, sizeof(buffer));

                int read_size = BUFFER_SIZE;

                if (client.startedWS == 1) {
                    read_size = 10;
                }
                if ((valread = read(sd, buffer, read_size)) == 0) {
                    //Somebody disconnected , get his details and print
                    getpeername(sd, (struct sockaddr *)&address, (socklen_t *)&addrlen);
                    printf(MAGENTA("Host disconnected , ip %s , port %d \n"), inet_ntoa(address.sin_addr), ntohs(address.sin_port));

                    //Close the socket and mark as 0 in list for reuse
                    close(sd);
                    //socketDescToClients[sd].erase(std::remove(socketDescToClients[sd].begin(), socketDescToClients[sd].end(), clients[sd]), socketDescToClients[sd].end());
                    it = clients.erase(previous_it);
                    continue;
                } else {
                    //set the string terminating NULL byte on the end
                    //of the data read
                    buffer[valread] = '\0';

                    if (client.startedWS == 1) {
                        unsigned int fin = (unsigned int)(buffer[0] & 0b10000000) == 0b10000000;
                        unsigned int opcode = (unsigned int)(buffer[0] & 0b00001111);
                        if (opcode > 2) {
                            //printf(BACK_YELLOW(RED("Something is very wrong: 1.") "\n=============================================================\n"));
                            //continue;
                        } else if (fin == 0 || opcode == 0) {
                            //printf(BACK_YELLOW(RED("Something is very wrong: 2.") "\n=============================================================\n"));
                            continue;
                        }
                        unsigned long payload_length = (unsigned int)(buffer[1] & 0b01111111);
                        unsigned int bit_offset = 2;
                        if (payload_length == 126) {
                            bit_offset += 2;
                            payload_length = (unsigned int)(buffer[2] & 0b11111111);
                            payload_length = payload_length << 8;
                            payload_length += (unsigned int)(buffer[3] & 0b11111111);
                        } else if (payload_length == 127) {
                            bit_offset += 8;
                            payload_length = (unsigned int)(buffer[2] & 0b11111111);
                            for (int shift_i = 0; shift_i < 7; shift_i++) {
                                payload_length = payload_length << 8;
                                payload_length += (unsigned int)(buffer[3 + shift_i] & 0b11111111);
                            }
                        }
                        if (doPrintSocketFrame) {
                            printf(BACK_YELLOW("================= Recieved websocket Frame ==================") ".");
                            printf("\n" BACK_YELLOW(" ") " Fin: %x ", fin);
                            printf(("Opcode: %x "), opcode);
                            printf(("Is masked: %d "), (unsigned int)((buffer[1] & 0b10000000) == 0b10000000));
                            printf(("Payload length: %lu"), payload_length);
                            printf(("\n" BACK_YELLOW(" ") " Mask: %x %x %x %x "),
                                   (unsigned int)(buffer[bit_offset + 0] & 0b11111111),
                                   (unsigned int)(buffer[bit_offset + 1] & 0b11111111),
                                   (unsigned int)(buffer[bit_offset + 2] & 0b11111111),
                                   (unsigned int)(buffer[bit_offset + 3] & 0b11111111));
                        }

                        bit_offset += 4;

                        totalFramesRecieved++;

                        int totalread = valread;
                        if (payload_length + bit_offset + 1 > BUFFER_SIZE) {
                            while (totalread < payload_length + bit_offset && (valread = read(sd, buffer, payload_length + bit_offset - totalread)) != 0) {
                                totalread += valread;
                            }
                            lastFrameLength = totalread;
                            totalFrameLength += totalread;
                            printf(BACK_YELLOW(RED("Dropped frame.")) " (Frame size is greater than %d bytes)\n", BUFFER_SIZE);
                            continue;
                        };
                        while (totalread < payload_length + bit_offset) {
                            valread = read(sd, buffer + totalread, payload_length + bit_offset - totalread);
                            totalread += valread;
                        }
                        lastFrameLength = totalread;
                        totalFrameLength += totalread;
                        buffer[totalread] = '\0';
                        if (doPrintSocketFrame) {
                            printf(("Total read length: %d\n"), totalread);
                            printf(BACK_YELLOW("=============================================================\n"));
                        }

                        //printf("Unmasked payload: \n>");
                        for (int payload_i = 0; payload_i < payload_length; payload_i++) {
                            buffer[bit_offset + payload_i] = buffer[bit_offset + payload_i] ^ buffer[bit_offset - 4 + payload_i % 4];
                            //printf("%c", buffer[bit_offset + payload_i]);
                        }

                        if (payload_length > 7 && buffer[bit_offset + 2] == 'h' && buffer[bit_offset + 3] == 'r' && buffer[bit_offset + 4] == 'e' && buffer[bit_offset + 5] == 'f') {
                            std::string url = std::string(buffer + bit_offset + 9, buffer + bit_offset - 2 + payload_length);
                            printf("%s\n", url.c_str());
                            if (url.compare(baseUrl) == 0) {
                                std::string stream_url = url + std::to_string(sd);
                                urlToSocketDesc[stream_url] = sd;
                                socketDescToClients[sd] = std::vector<Client>();

                                int send_len = generate_ws_frame(send_buffer, "{\"url\":\"" + stream_url + "\",\"streamer\":" + std::to_string(sd) + "}");

                                if (send(sd, send_buffer, send_len, 0) != send_len) {
                                    perror("send");
                                }

                                continue;
                            } else {
                                previous_it->second.url = url;
                                clientSocketDescToStreamerSocketDesc[sd] = urlToSocketDesc[url];
                                socketDescToClients[urlToSocketDesc[url]].push_back(previous_it->second);

                                int send_len = generate_ws_frame(send_buffer, "{\"watcher\":" + std::to_string(sd) + ",\"streamer\":" + std::to_string(urlToSocketDesc[url]) + "}");

                                if (send(sd, send_buffer, send_len, 0) != send_len) {
                                    perror("send");
                                }
                            }
                            continue;
                        }

                        if (opcode != 1 && opcode != 2) {
                            continue;
                        }

                        //printf("Bit offset: %d\n", bit_offset);

                        for (int payload_i = 0; payload_i < payload_length; payload_i++) {
                            buffer[bit_offset - 4 + payload_i] = buffer[bit_offset + payload_i];
                        }

                        buffer[0] = buffer[0] & 0b10001111;
                        buffer[1] = buffer[1] & 0b01111111;

                        opcode = (unsigned int)(buffer[0] & 0b00001111);

                        buffer[bit_offset - 4 + payload_length] = '\0';
                        buffer[bit_offset - 3 + payload_length] = '\0';
                        buffer[bit_offset - 2 + payload_length] = '\0';
                        buffer[bit_offset - 1 + payload_length] = '\0';

                        int target_sd_bit_offset = bit_offset - 4;
                        if (buffer[target_sd_bit_offset] == 't' && buffer[target_sd_bit_offset + 1] == 'o') {
                            int target_sd = 0;
                            target_sd_bit_offset += 2;
                            while (buffer[target_sd_bit_offset] != '{') {
                                target_sd = target_sd * 10 + buffer[target_sd_bit_offset++] - '0';
                            }
                            if (send(target_sd, buffer, bit_offset - 4 + payload_length, 0) != bit_offset - 4 + payload_length) {
                                perror("send");
                            } else {
                                totalFramesSent++;
                            }
                        } else if (clientSocketDescToStreamerSocketDesc[sd] && clientSocketDescToStreamerSocketDesc[sd] != sd) {
                            if (send(clientSocketDescToStreamerSocketDesc[sd], buffer, bit_offset - 4 + payload_length, 0) != bit_offset - 4 + payload_length) {
                                perror("send");
                            } else {
                                totalFramesSent++;
                            }
                        } else {
                            for (auto clientForSocket = socketDescToClients[sd].begin(); clientForSocket != socketDescToClients[sd].end();) {
                                if (send(clientForSocket->socket_descriptor, buffer, bit_offset - 4 + payload_length, 0) != bit_offset - 4 + payload_length) {
                                    perror("send");
                                    clientForSocket = socketDescToClients[sd].erase(clientForSocket);
                                } else {
                                    totalFramesSent++;
                                    clientForSocket++;
                                }
                            }
                        }

                        continue;
                    }

                    std::unordered_map<std::string, std::string> headerMap = parse_header(buffer, buffer + valread);

                    if (headerMap.count("Sec-WebSocket-Key") == 1) {
                        printf(GREEN("Recieved ws request\n"));
                        printf(CYAN("%s\n"), buffer);

                        char sha1_handshake[40];
                        size_t handshake_sz;

                        memset(sha1_handshake, 0, sizeof(sha1_handshake));
                        if (ws_compute_handshake(headerMap["Sec-WebSocket-Key"].c_str(), sha1_handshake, &handshake_sz) != 0) {
                            /* failed to compute handshake. */
                            printf("failed to compute handshake\n");
                            continue;
                        }

                        //printf("%s\n", sha1_handshake);

                        std::string strWSResponse = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: WebSocket\r\nConnection: Upgrade\r\n";
                        strWSResponse += "Sec-WebSocket-Accept: ";
                        strWSResponse += sha1_handshake;
                        strWSResponse += "\r\n";
                        const char *strWSResponseMsg = strWSResponse.c_str();

                        //send websocket response
                        if (send(sd, strWSResponseMsg, strlen(strWSResponseMsg), 0) != strlen(strWSResponseMsg)) {
                            perror("send");
                        }

                        previous_it->second.startedWS = 1;

                    } else {
                        printf(GREEN("Recieved http request\n"));
                        printf(RED("%s\n"), buffer);
                    }

                    /*for (auto x : headerMap)
                    {
                        //cout << x.first << " " << x.second << endl;
                        printf(">%s< -> >%s<\n", x.first.c_str(), x.second.c_str());
                    }*/
                    //send(sd, buffer, strlen(buffer), 0);
                }
            }
        }
    }

    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x20328, %rsp          # imm = 0x20328
movl $0x1, -0x144(%rbp)
testl %edi, %edi
jle 0x2613
movq %rsi, %rbx
movl %edi, %r13d
xorl %r15d, %r15d
leaq 0x4a62(%rip), %r14      # 0x7020
movl $0x0, -0x64(%rbp)
movl $0x0, -0x68(%rbp)
movq (%rbx,%r15,8), %r12
cmpb $0x2d, (%r12)
jne 0x2609
movq %r12, %rdi
movq %r14, %rsi
callq 0x22a0
testl %eax, %eax
je 0x2604
movq %r12, %rdi
leaq 0x4a34(%rip), %rsi      # 0x7024
callq 0x22a0
testl %eax, %eax
sete %al
movl -0x68(%rbp), %ecx
orb %al, %cl
movl %ecx, -0x68(%rbp)
jmp 0x2609
movb $0x1, %al
movl %eax, -0x64(%rbp)
incq %r15
cmpq %r15, %r13
jne 0x25cc
jmp 0x2621
movl $0x0, -0x68(%rbp)
movl $0x0, -0x64(%rbp)
leaq -0x2a0(%rbp), %rax
movq %rax, -0x30(%rax)
movl $0x1, %ecx
movq %rcx, -0x28(%rax)
xorps %xmm0, %xmm0
movups %xmm0, -0x20(%rax)
movl $0x3f800000, %edx       # imm = 0x3F800000
movl %edx, -0x10(%rax)
movups %xmm0, -0x8(%rax)
leaq -0x1f8(%rbp), %rax
movq %rax, -0x30(%rax)
movq %rcx, -0x28(%rax)
movups %xmm0, -0x20(%rax)
movl %edx, -0x10(%rax)
movups %xmm0, -0x8(%rax)
leaq -0x268(%rbp), %rax
movq %rax, -0x30(%rax)
movq %rcx, -0x28(%rax)
movups %xmm0, -0x20(%rax)
movl %edx, -0x10(%rax)
movups %xmm0, -0x8(%rax)
leaq -0x230(%rbp), %rax
movq %rax, -0x30(%rax)
movq %rcx, -0x28(%rax)
movups %xmm0, -0x20(%rax)
movl %edx, -0x10(%rax)
movups %xmm0, -0x8(%rax)
movl $0x2, %edi
movl $0x1, %esi
xorl %edx, %edx
callq 0x2080
testl %eax, %eax
je 0x3c99
movl %eax, %ebx
leaq -0x144(%rbp), %rcx
movl %eax, %edi
movl $0x1, %esi
movl $0x2, %edx
movl $0x4, %r8d
callq 0x2330
testl %eax, %eax
js 0x3ca2
movl $0xa40f0002, %eax       # imm = 0xA40F0002
leaq -0x188(%rbp), %rsi
movq %rax, (%rsi)
movl %ebx, %edi
movl $0x10, %edx
callq 0x2060
testl %eax, %eax
js 0x3cab
leaq 0x494d(%rip), %rdi      # 0x704e
movl $0xfa4, %esi            # imm = 0xFA4
xorl %eax, %eax
callq 0x2040
movl %ebx, %edi
movl $0x3, %esi
callq 0x2230
testl %eax, %eax
js 0x3cb4
leaq -0x118(%rbp), %rax
movl $0x10, (%rax)
leaq 0x493a(%rip), %rdi      # 0x706f
callq 0x22e0
leal 0x3f(%rbx), %eax
testl %ebx, %ebx
cmovnsl %ebx, %eax
movl %eax, %edx
andl $-0x40, %edx
movq %rbx, -0x1f0(%rbp)
movl %ebx, %ecx
subl %edx, %ecx
movl $0x1, %edx
movq %rdx, -0x120(%rbp)
shlq %cl, %rdx
movq %rdx, -0x1a8(%rbp)
sarl $0x6, %eax
cltq
movq %rax, -0x1a0(%rbp)
leaq -0x160(%rbp), %r12
movq $0x0, -0x198(%rbp)
movq $0x0, -0x110(%rbp)
movl $0x1, %eax
movq %rax, -0x190(%rbp)
xorps %xmm0, %xmm0
movaps %xmm0, -0x2e0(%rbp)
movaps %xmm0, -0x2f0(%rbp)
movaps %xmm0, -0x300(%rbp)
movaps %xmm0, -0x310(%rbp)
movaps %xmm0, -0x320(%rbp)
movaps %xmm0, -0x330(%rbp)
movaps %xmm0, -0x340(%rbp)
movaps %xmm0, -0x350(%rbp)
movq -0x1a8(%rbp), %rax
movq -0x1a0(%rbp), %rcx
orq %rax, -0x350(%rbp,%rcx,8)
movq -0x250(%rbp), %r14
movq -0x1f0(%rbp), %r15
movl %r15d, %ebx
testq %r14, %r14
je 0x2893
movq 0x10(%r14), %rax
movq %rax, -0xe8(%rbp)
leaq -0xd0(%rbp), %rax
movq %rax, -0xe0(%rbp)
movq 0x18(%r14), %rsi
movq 0x20(%r14), %rdx
addq %rsi, %rdx
leaq -0xe0(%rbp), %rdi
callq 0x4190
movl 0x38(%r14), %eax
movl %eax, -0xc0(%rbp)
movl -0xe8(%rbp), %ecx
movl %ecx, -0x2c(%rbp)
testl %ecx, %ecx
jle 0x2864
movl $0x1, %eax
shlq %cl, %rax
movl %ecx, %edx
shrl $0x6, %edx
orq %rax, -0x350(%rbp,%rdx,8)
cmpl %ebx, %ecx
cmovgl %ecx, %ebx
movq -0xe0(%rbp), %rdi
leaq -0xd0(%rbp), %rax
cmpq %rax, %rdi
je 0x288b
movq -0xd0(%rbp), %rsi
incq %rsi
callq 0x2200
movq (%r14), %r14
jmp 0x27ff
incl %ebx
movl %ebx, %edi
leaq -0x350(%rbp), %rsi
xorl %edx, %edx
xorl %ecx, %ecx
xorl %r8d, %r8d
callq 0x21e0
leaq -0x80(%rbp), %r14
testl %eax, %eax
jns 0x28ca
callq 0x2030
cmpl $0x4, (%rax)
je 0x28ca
leaq 0x47c8(%rip), %rdi      # 0x708b
xorl %eax, %eax
callq 0x2040
movq -0x1a8(%rbp), %rax
movq -0x1a0(%rbp), %rcx
testq %rax, -0x350(%rbp,%rcx,8)
je 0x29da
movl %r15d, %edi
leaq -0x188(%rbp), %rsi
leaq -0x118(%rbp), %rdx
callq 0x20d0
movl %eax, %ebx
movl %eax, -0x114(%rbp)
testl %eax, %eax
js 0x3c83
movl -0x184(%rbp), %edi
callq 0x2110
movzwl -0x186(%rbp), %ecx
rolw $0x8, %cx
movzwl %cx, %ecx
leaq 0x4773(%rip), %rdi      # 0x709f
movl %ebx, %esi
movq %rax, %rdx
xorl %eax, %eax
callq 0x2040
movl -0x114(%rbp), %eax
movl %eax, -0xe8(%rbp)
movl $0x0, -0xe4(%rbp)
leaq -0xd0(%rbp), %rax
movq %rax, -0xe0(%rbp)
leaq -0xe0(%rbp), %rdi
leaq 0x47f6(%rip), %rdx      # 0x7160
movq %rdx, %rsi
callq 0x495c
movl $0xffffffff, -0xc0(%rbp) # imm = 0xFFFFFFFF
leaq -0x260(%rbp), %rdi
leaq -0x114(%rbp), %rsi
callq 0x4646
movq %rax, %rbx
movq -0xe8(%rbp), %rax
movq %rax, (%rbx)
movq %rbx, %rdi
addq $0x8, %rdi
leaq -0xe0(%rbp), %rsi
callq 0x2280
movl -0xc0(%rbp), %eax
movl %eax, 0x28(%rbx)
movq -0xe0(%rbp), %rdi
leaq -0xd0(%rbp), %rax
cmpq %rax, %rdi
je 0x29da
movq -0xd0(%rbp), %rsi
incq %rsi
callq 0x2200
movq -0x250(%rbp), %r15
testq %r15, %r15
je 0x279d
jmp 0x33f3
leaq -0x298(%rbp), %rdi
leaq -0x2c(%rbp), %rsi
callq 0x51e0
leaq -0x80(%rbp), %r14
cmpl $0x0, (%rax)
je 0x2a1f
leaq -0x298(%rbp), %rdi
leaq -0x2c(%rbp), %rsi
callq 0x51e0
movl (%rax), %eax
cmpl -0x2c(%rbp), %eax
jne 0x2a9e
leaq -0x228(%rbp), %rdi
leaq -0x2c(%rbp), %rsi
callq 0x4ee8
movq (%rax), %r14
leaq -0x228(%rbp), %rdi
leaq -0x2c(%rbp), %rsi
callq 0x4ee8
cmpq 0x8(%rax), %r14
je 0x3c36
movl (%r14), %edi
leaq -0x10350(%rbp), %rsi
movq %rbx, %rdx
xorl %ecx, %ecx
callq 0x2130
cmpq %rbx, %rax
je 0x2a91
leaq 0x48d5(%rip), %rdi      # 0x7341
callq 0x21c0
leaq -0x228(%rbp), %rdi
leaq -0x2c(%rbp), %rsi
callq 0x4ee8
movq %rax, %rdi
movq %r14, %rsi
callq 0x56c8
movq %rax, %r14
jmp 0x2a32
incq -0x120(%rbp)
addq $0x30, %r14
jmp 0x2a32
leaq -0x298(%rbp), %rdi
leaq -0x2c(%rbp), %rsi
callq 0x51e0
movl (%rax), %edi
leaq -0x10350(%rbp), %rsi
movq %rbx, %rdx
xorl %ecx, %ecx
callq 0x2130
cmpq %rbx, %rax
jne 0x2b62
incq -0x120(%rbp)
jmp 0x3c3a
leaq 0x4864(%rip), %rdi      # 0x7341
callq 0x21c0
jmp 0x3af7
movl -0x2c(%rbp), %ebx
movl %ebx, %r14d
negl %r14d
cmovsl %ebx, %r14d
movl $0x1, %r15d
cmpl $0xa, %r14d
jb 0x2f51
movl $0x4, %r15d
movl %r14d, %eax
cmpl $0x63, %eax
jbe 0x2f48
cmpl $0x3e7, %eax            # imm = 0x3E7
jbe 0x2f4e
cmpl $0x2710, %eax           # imm = 0x2710
jb 0x2f51
movl %eax, %ecx
movl $0xd1b71759, %edx       # imm = 0xD1B71759
imulq %rdx, %rcx
shrq $0x2d, %rcx
addl $0x4, %r15d
cmpl $0x1869f, %eax          # imm = 0x1869F
movl %ecx, %eax
ja 0x2b0d
addl $-0x3, %r15d
jmp 0x2f51
leaq 0x47e9(%rip), %rdi      # 0x7341
callq 0x21c0
jmp 0x3c36
leaq 0x47d8(%rip), %rdi      # 0x7341
callq 0x21c0
jmp 0x3c3a
addl $-0x2, %r15d
jmp 0x2b7c
decl %r15d
shrl $0x1f, %ebx
leal (%r15,%rbx), %esi
leaq -0x130(%rbp), %rax
movq %rax, -0x140(%rbp)
leaq -0x140(%rbp), %r13
movq %r13, %rdi
movl $0x2d, %edx
callq 0x2250
addq -0x140(%rbp), %rbx
movq %rbx, %rdi
movl %r15d, %esi
movl %r14d, %edx
callq 0x423c
movl $0xb, %r8d
movq %r13, %rdi
xorl %esi, %esi
xorl %edx, %edx
leaq 0x4778(%rip), %rcx      # 0x7346
callq 0x2240
leaq -0xa0(%rbp), %r14
movq %r14, -0xb0(%rbp)
movq (%rax), %rdx
movq %rax, %rcx
addq $0x10, %rcx
cmpq %rcx, %rdx
leaq -0xd8(%rbp), %r13
je 0x2c0a
movq %rdx, -0xb0(%rbp)
movq (%rcx), %rdx
movq %rdx, -0xa0(%rbp)
jmp 0x2c11
movups (%rcx), %xmm0
movups %xmm0, (%r14)
movq 0x8(%rax), %rdx
movq %rdx, -0xa8(%rbp)
movq %rcx, (%rax)
movq $0x0, 0x8(%rax)
movb $0x0, 0x10(%rax)
leaq -0xb0(%rbp), %rdi
leaq 0x46f9(%rip), %rsi      # 0x7332
callq 0x2360
leaq -0x48(%rbp), %rsi
movq %rsi, -0x58(%rbp)
movq (%rax), %rdx
movq %rax, %rcx
addq $0x10, %rcx
cmpq %rcx, %rdx
je 0x2c62
movq %rdx, -0x58(%rbp)
movq (%rcx), %rdx
movq %rdx, -0x48(%rbp)
jmp 0x2c68
movups (%rcx), %xmm0
movups %xmm0, (%rsi)
leaq -0xe8(%rbp), %rsi
movq 0x8(%rax), %rdx
movq %rdx, -0x50(%rbp)
movq %rcx, (%rax)
movq $0x0, 0x8(%rax)
movb $0x0, 0x10(%rax)
leaq -0x2d0(%rbp), %rdi
callq 0x4ab6
movl (%rax), %ebx
movl %ebx, %r14d
negl %r14d
cmovsl %ebx, %r14d
movl $0x1, %r15d
cmpl $0xa, %r14d
jb 0x2cf1
movl $0x4, %r15d
movl %r14d, %eax
cmpl $0x63, %eax
jbe 0x2ce8
cmpl $0x3e7, %eax            # imm = 0x3E7
jbe 0x2cee
cmpl $0x2710, %eax           # imm = 0x2710
jb 0x2cf1
movl %eax, %ecx
movl $0xd1b71759, %edx       # imm = 0xD1B71759
imulq %rdx, %rcx
shrq $0x2d, %rcx
addl $0x4, %r15d
cmpl $0x1869f, %eax          # imm = 0x1869F
movl %ecx, %eax
ja 0x2cb3
addl $-0x3, %r15d
jmp 0x2cf1
addl $-0x2, %r15d
jmp 0x2cf1
decl %r15d
shrl $0x1f, %ebx
leal (%r15,%rbx), %esi
leaq -0xf8(%rbp), %rax
movq %rax, -0x108(%rbp)
leaq -0x108(%rbp), %rdi
movl $0x2d, %edx
callq 0x2250
addq -0x108(%rbp), %rbx
movq %rbx, %rdi
movl %r15d, %esi
movl %r14d, %edx
callq 0x423c
movq -0x58(%rbp), %rcx
movl $0xf, %edi
leaq -0x48(%rbp), %rax
cmpq %rax, %rcx
je 0x2d42
movq -0x48(%rbp), %rdi
movq -0x50(%rbp), %r8
movq -0x108(%rbp), %rsi
movq -0x100(%rbp), %rdx
leaq (%rdx,%r8), %rax
cmpq %rdi, %rax
leaq -0x80(%rbp), %r14
jbe 0x2d7e
movl $0xf, %edi
leaq -0xf8(%rbp), %r9
cmpq %r9, %rsi
je 0x2d79
movq -0xf8(%rbp), %rdi
cmpq %rdi, %rax
jbe 0x2d89
leaq -0x58(%rbp), %rdi
callq 0x20c0
jmp 0x2d99
leaq -0x108(%rbp), %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x2240
movq %r14, -0x90(%rbp)
movq (%rax), %rdx
leaq 0x10(%rax), %rcx
cmpq %rcx, %rdx
je 0x2dbc
movq %rdx, -0x90(%rbp)
movq (%rcx), %rdx
movq %rdx, -0x80(%rbp)
jmp 0x2dc3
movups (%rcx), %xmm0
movups %xmm0, (%r14)
movq %rax, %rdx
addq $0x8, %rdx
movq 0x8(%rax), %rsi
movq %rsi, -0x88(%rbp)
movq %rcx, (%rax)
movq $0x0, (%rdx)
movb $0x0, (%rcx)
leaq -0x90(%rbp), %rdi
leaq 0x454f(%rip), %rsi      # 0x733f
callq 0x2360
leaq -0x1b8(%rbp), %rsi
movq %rsi, -0x1c8(%rbp)
movq (%rax), %rdx
movq %rax, %rcx
addq $0x10, %rcx
cmpq %rcx, %rdx
je 0x2e25
movq %rdx, -0x1c8(%rbp)
movq (%rcx), %rdx
movq %rdx, -0x1b8(%rbp)
jmp 0x2e2b
movups (%rcx), %xmm0
movups %xmm0, (%rsi)
movq 0x8(%rax), %rdx
movq %rdx, -0x1c0(%rbp)
movq %rcx, (%rax)
movq $0x0, 0x8(%rax)
movb $0x0, 0x10(%rax)
leaq -0x20350(%rbp), %rdi
leaq -0x1c8(%rbp), %rsi
callq 0x6b1b
movl %eax, %ebx
movq -0x1c8(%rbp), %rdi
leaq -0x1b8(%rbp), %rax
cmpq %rax, %rdi
je 0x2e7c
movq -0x1b8(%rbp), %rsi
incq %rsi
callq 0x2200
movq -0x90(%rbp), %rdi
cmpq %r14, %rdi
je 0x2e94
movq -0x80(%rbp), %rsi
incq %rsi
callq 0x2200
movq -0x108(%rbp), %rdi
leaq -0xf8(%rbp), %rax
cmpq %rax, %rdi
je 0x2eb6
movq -0xf8(%rbp), %rsi
incq %rsi
callq 0x2200
movq -0x58(%rbp), %rdi
leaq -0x48(%rbp), %rax
cmpq %rax, %rdi
je 0x2ecf
movq -0x48(%rbp), %rsi
incq %rsi
callq 0x2200
movq -0xb0(%rbp), %rdi
leaq -0xa0(%rbp), %rax
cmpq %rax, %rdi
je 0x2ef1
movq -0xa0(%rbp), %rsi
incq %rsi
callq 0x2200
movq -0x140(%rbp), %rdi
leaq -0x130(%rbp), %rax
cmpq %rax, %rdi
je 0x2f13
movq -0x130(%rbp), %rsi
incq %rsi
callq 0x2200
movl -0x2c(%rbp), %edi
movslq %ebx, %rbx
leaq -0x20350(%rbp), %rsi
movq %rbx, %rdx
xorl %ecx, %ecx
callq 0x2130
cmpq %rbx, %rax
movq -0x38(%rbp), %rbx
je 0x33c1
leaq 0x4403(%rip), %rdi      # 0x7341
callq 0x21c0
jmp 0x33c1
addl $-0x2, %r15d
jmp 0x2f51
decl %r15d
shrl $0x1f, %ebx
leal (%r15,%rbx), %esi
leaq -0x48(%rbp), %rax
movq %rax, -0x58(%rbp)
leaq -0x58(%rbp), %r13
movq %r13, %rdi
movl $0x2d, %edx
callq 0x2250
addq -0x58(%rbp), %rbx
movq %rbx, %rdi
movl %r15d, %esi
movl %r14d, %edx
callq 0x423c
movq -0xe8(%rbp), %rcx
movq -0xe0(%rbp), %r8
movq %r13, %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x2240
leaq -0x80(%rbp), %r14
movq %r14, -0x90(%rbp)
movq (%rax), %rdx
movq %rax, %rcx
addq $0x10, %rcx
cmpq %rcx, %rdx
leaq -0x90(%rbp), %r15
leaq -0xd8(%rbp), %r13
je 0x2fd5
movq %rdx, -0x90(%rbp)
movq (%rcx), %rdx
movq %rdx, -0x80(%rbp)
jmp 0x2fdc
movups (%rcx), %xmm0
movups %xmm0, (%r14)
movq 0x8(%rax), %rdx
movq %rdx, -0x88(%rbp)
movq %rcx, (%rax)
movq $0x0, 0x8(%rax)
movb $0x0, 0x10(%rax)
movq -0x58(%rbp), %rdi
leaq -0x48(%rbp), %rax
cmpq %rax, %rdi
je 0x300f
movq -0x48(%rbp), %rsi
incq %rsi
callq 0x2200
movl -0x2c(%rbp), %ebx
leaq -0x2d0(%rbp), %rdi
movq %r15, %rsi
callq 0x4ab6
movl %ebx, (%rax)
xorps %xmm0, %xmm0
movaps %xmm0, -0xb0(%rbp)
movq $0x0, -0xa0(%rbp)
leaq -0x228(%rbp), %rdi
leaq -0x2c(%rbp), %rsi
callq 0x4ee8
movups (%rax), %xmm0
movq 0x10(%rax), %rcx
movq -0xb0(%rbp), %rdx
movq %rdx, (%rax)
movq -0xa8(%rbp), %rdx
movq %rdx, 0x8(%rax)
movq -0xa0(%rbp), %rdx
movq %rdx, 0x10(%rax)
movups %xmm0, -0x58(%rbp)
movq %rcx, -0x48(%rbp)
xorps %xmm0, %xmm0
movaps %xmm0, -0xb0(%rbp)
movq $0x0, -0xa0(%rbp)
leaq -0x58(%rbp), %rdi
callq 0x4024
leaq -0xb0(%rbp), %rdi
callq 0x4024
leaq -0x140(%rbp), %rbx
movq %rbx, %rdi
leaq 0x4276(%rip), %rsi      # 0x7328
movq %r15, %rdx
callq 0x4091
movq %rbx, %rdi
leaq 0x426d(%rip), %rsi      # 0x7331
callq 0x2360
leaq -0xa0(%rbp), %rsi
movq %rsi, -0xb0(%rbp)
movq (%rax), %rdx
movq %rax, %rcx
addq $0x10, %rcx
cmpq %rcx, %rdx
je 0x30f9
movq %rdx, -0xb0(%rbp)
movq (%rcx), %rdx
movq %rdx, -0xa0(%rbp)
jmp 0x30ff
movups (%rcx), %xmm0
movups %xmm0, (%rsi)
movq 0x8(%rax), %rdx
movq %rdx, -0xa8(%rbp)
movq %rcx, (%rax)
movq $0x0, 0x8(%rax)
movb $0x0, 0x10(%rax)
movl -0x2c(%rbp), %ebx
movl %ebx, %r14d
negl %r14d
cmovsl %ebx, %r14d
movl $0x1, %r15d
cmpl $0xa, %r14d
jb 0x3179
movl $0x4, %r15d
movl %r14d, %eax
cmpl $0x63, %eax
jbe 0x3170
cmpl $0x3e7, %eax            # imm = 0x3E7
jbe 0x3176
cmpl $0x2710, %eax           # imm = 0x2710
jb 0x3179
movl %eax, %ecx
movl $0xd1b71759, %edx       # imm = 0xD1B71759
imulq %rdx, %rcx
shrq $0x2d, %rcx
addl $0x4, %r15d
cmpl $0x1869f, %eax          # imm = 0x1869F
movl %ecx, %eax
ja 0x313b
addl $-0x3, %r15d
jmp 0x3179
addl $-0x2, %r15d
jmp 0x3179
decl %r15d
shrl $0x1f, %ebx
leal (%r15,%rbx), %esi
leaq -0xf8(%rbp), %rax
movq %rax, -0x108(%rbp)
leaq -0x108(%rbp), %rdi
movl $0x2d, %edx
callq 0x2250
addq -0x108(%rbp), %rbx
movq %rbx, %rdi
movl %r15d, %esi
movl %r14d, %edx
callq 0x423c
movq -0xb0(%rbp), %rcx
movl $0xf, %edi
leaq -0xa0(%rbp), %rax
cmpq %rax, %rcx
je 0x31d3
movq -0xa0(%rbp), %rdi
movq -0xa8(%rbp), %r8
movq -0x108(%rbp), %rsi
movq -0x100(%rbp), %rdx
leaq (%rdx,%r8), %rax
cmpq %rdi, %rax
leaq -0x80(%rbp), %r14
jbe 0x3212
movl $0xf, %edi
leaq -0xf8(%rbp), %r9
cmpq %r9, %rsi
je 0x320d
movq -0xf8(%rbp), %rdi
cmpq %rdi, %rax
jbe 0x3220
leaq -0xb0(%rbp), %rdi
callq 0x20c0
jmp 0x3230
leaq -0x108(%rbp), %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x2240
leaq -0x48(%rbp), %rsi
movq %rsi, -0x58(%rbp)
movq (%rax), %rdx
leaq 0x10(%rax), %rcx
cmpq %rcx, %rdx
je 0x3251
movq %rdx, -0x58(%rbp)
movq (%rcx), %rdx
movq %rdx, -0x48(%rbp)
jmp 0x3257
movups (%rcx), %xmm0
movups %xmm0, (%rsi)
movq %rax, %rdx
addq $0x8, %rdx
movq 0x8(%rax), %rsi
movq %rsi, -0x50(%rbp)
movq %rcx, (%rax)
movq $0x0, (%rdx)
movb $0x0, (%rcx)
leaq -0x58(%rbp), %rdi
leaq 0x40c1(%rip), %rsi      # 0x733f
callq 0x2360
leaq -0x1d8(%rbp), %rsi
movq %rsi, -0x1e8(%rbp)
movq (%rax), %rdx
movq %rax, %rcx
addq $0x10, %rcx
cmpq %rcx, %rdx
je 0x32b3
movq %rdx, -0x1e8(%rbp)
movq (%rcx), %rdx
movq %rdx, -0x1d8(%rbp)
jmp 0x32b9
movups (%rcx), %xmm0
movups %xmm0, (%rsi)
movq 0x8(%rax), %rdx
movq %rdx, -0x1e0(%rbp)
movq %rcx, (%rax)
movq $0x0, 0x8(%rax)
movb $0x0, 0x10(%rax)
leaq -0x20350(%rbp), %rdi
leaq -0x1e8(%rbp), %rsi
callq 0x6b1b
movl %eax, %ebx
movq -0x1e8(%rbp), %rdi
leaq -0x1d8(%rbp), %rax
cmpq %rax, %rdi
je 0x330a
movq -0x1d8(%rbp), %rsi
incq %rsi
callq 0x2200
movq -0x58(%rbp), %rdi
leaq -0x48(%rbp), %rax
cmpq %rax, %rdi
je 0x3323
movq -0x48(%rbp), %rsi
incq %rsi
callq 0x2200
movq -0x108(%rbp), %rdi
leaq -0xf8(%rbp), %rax
cmpq %rax, %rdi
je 0x3345
movq -0xf8(%rbp), %rsi
incq %rsi
callq 0x2200
movq -0xb0(%rbp), %rdi
leaq -0xa0(%rbp), %rax
cmpq %rax, %rdi
je 0x3367
movq -0xa0(%rbp), %rsi
incq %rsi
callq 0x2200
movq -0x140(%rbp), %rdi
leaq -0x130(%rbp), %rax
cmpq %rax, %rdi
je 0x3389
movq -0x130(%rbp), %rsi
incq %rsi
callq 0x2200
movl -0x2c(%rbp), %edi
movslq %ebx, %rbx
leaq -0x20350(%rbp), %rsi
movq %rbx, %rdx
xorl %ecx, %ecx
callq 0x2130
cmpq %rbx, %rax
jne 0x33e5
movq -0x90(%rbp), %rdi
cmpq %r14, %rdi
movq -0x38(%rbp), %rbx
je 0x33c1
movq -0x80(%rbp), %rsi
incq %rsi
callq 0x2200
movq -0xe8(%rbp), %rdi
cmpq %r13, %rdi
je 0x3c3e
movq -0xd8(%rbp), %rsi
incq %rsi
callq 0x2200
jmp 0x3c3e
leaq 0x3f55(%rip), %rdi      # 0x7341
callq 0x21c0
jmp 0x33a5
testb $0x1, -0x68(%rbp)
je 0x3458
leaq 0x3ce5(%rip), %rdi      # 0x70e5
movq -0x190(%rbp), %rbx
movq %rbx, %rsi
xorl %eax, %eax
callq 0x2040
leaq 0x3cee(%rip), %rdi      # 0x7106
movq -0x120(%rbp), %rsi
xorl %eax, %eax
callq 0x2040
leaq 0x3cf6(%rip), %rdi      # 0x7123
movq -0x110(%rbp), %rsi
xorl %eax, %eax
callq 0x2040
movq -0x198(%rbp), %rax
xorl %edx, %edx
divq %rbx
leaq 0x3cf2(%rip), %rdi      # 0x7140
movq %rax, %rsi
xorl %eax, %eax
callq 0x2040
movq 0x10(%r15), %rax
movq %rax, -0x178(%rbp)
movq %r12, -0x170(%rbp)
movq 0x18(%r15), %rsi
movq 0x20(%r15), %rdx
addq %rsi, %rdx
leaq -0x170(%rbp), %rdi
callq 0x4190
movl 0x38(%r15), %eax
movl %eax, -0x150(%rbp)
movq (%r15), %rax
movq %rax, -0x38(%rbp)
movl -0x178(%rbp), %ebx
movl %ebx, -0x2c(%rbp)
leal 0x3f(%rbx), %eax
testl %ebx, %ebx
cmovnsl %ebx, %eax
sarl $0x6, %eax
cltq
movq -0x350(%rbp,%rax,8), %rax
btq %rbx, %rax
jae 0x3547
movl $0x10000, %edx          # imm = 0x10000
movq %r12, %r13
leaq -0x10350(%rbp), %r12
movq %r12, %rdi
xorl %esi, %esi
callq 0x2160
cmpl $0x1, -0x174(%rbp)
movl $0xffff, %edx           # imm = 0xFFFF
movl $0xa, %eax
cmoveq %rax, %rdx
movl %ebx, %edi
movq %r12, %rsi
movq %r13, %r12
leaq -0x90(%rbp), %r13
callq 0x22b0
movq %rax, %rbx
testl %ebx, %ebx
je 0x3550
movslq %ebx, %rax
movb $0x0, -0x10350(%rbp,%rax)
cmpl $0x1, -0x174(%rbp)
jne 0x35af
movq %rax, -0x60(%rbp)
movzbl -0x10350(%rbp), %esi
movl %esi, %edx
andl $0xf, %edx
cmpl $0x2, %edx
ja 0x36d1
testb %sil, %sil
setns %al
testl %edx, %edx
sete %cl
orb %al, %cl
je 0x36d1
movq -0x38(%rbp), %rbx
jmp 0x3c57
movl -0x2c(%rbp), %edi
leaq -0x188(%rbp), %rsi
leaq -0x118(%rbp), %rdx
callq 0x2190
movl -0x184(%rbp), %edi
callq 0x2110
movzwl -0x186(%rbp), %ecx
rolw $0x8, %cx
movzwl %cx, %edx
leaq 0x3bdb(%rip), %rdi      # 0x7161
movq %rax, %rsi
xorl %eax, %eax
callq 0x2040
movl -0x2c(%rbp), %edi
callq 0x2370
leaq -0x260(%rbp), %rdi
movq %r15, %rsi
callq 0x49fa
movq %rax, %rbx
jmp 0x3c57
leaq (%rax,%rbp), %rdx
addq $-0x10350, %rdx         # imm = 0xFFFEFCB0
leaq -0xe8(%rbp), %rdi
leaq -0x10350(%rbp), %rsi
callq 0x5db4
movq %r14, -0x90(%rbp)
movq %r13, %rdi
leaq 0x3d74(%rip), %rsi      # 0x7352
leaq 0x3d7e(%rip), %rdx      # 0x7363
callq 0x495c
leaq -0xe8(%rbp), %rdi
movq %r13, %rsi
callq 0x5782
movq %rax, %rbx
movq -0x90(%rbp), %rdi
cmpq %r14, %rdi
je 0x3614
movq -0x80(%rbp), %rsi
incq %rsi
callq 0x2200
testq %rbx, %rbx
leaq -0x58(%rbp), %r13
je 0x3864
leaq 0x3d3c(%rip), %rdi      # 0x7364
xorl %eax, %eax
callq 0x2040
leaq 0x3d4c(%rip), %rdi      # 0x7382
leaq -0x10350(%rbp), %rsi
xorl %eax, %eax
callq 0x2040
xorps %xmm0, %xmm0
movaps %xmm0, -0x90(%rbp)
movaps %xmm0, -0x80(%rbp)
movq $0x0, -0x70(%rbp)
leaq -0x48(%rbp), %rax
movq %rax, -0x58(%rbp)
movq %r13, %rdi
leaq 0x3ce6(%rip), %rsi      # 0x7352
leaq 0x3cf0(%rip), %rdx      # 0x7363
callq 0x495c
leaq -0xe8(%rbp), %rdi
movq %r13, %rsi
callq 0x588e
movq (%rax), %rdi
leaq -0x90(%rbp), %rsi
leaq -0xb0(%rbp), %rdx
callq 0x69e8
movl %eax, %ebx
movq -0x58(%rbp), %rdi
leaq -0x48(%rbp), %rax
cmpq %rax, %rdi
je 0x36b8
movq -0x48(%rbp), %rsi
incq %rsi
callq 0x2200
testl %ebx, %ebx
je 0x3a78
leaq 0x3d9c(%rip), %rdi      # 0x7463
callq 0x22e0
jmp 0x3887
movzbl -0x1034f(%rbp), %r13d
andl $0x7f, %r13d
cmpq $0x7e, %r13
jne 0x36f9
movzwl -0x1034e(%rbp), %eax
rolw $0x8, %ax
movzwl %ax, %r13d
movl $0x4, %eax
jmp 0x372f
movl $0x2, %eax
cmpb $0x7f, %r13b
jne 0x372f
movzbl -0x1034e(%rbp), %r13d
xorl %eax, %eax
movq %r13, %rcx
shlq $0x8, %rcx
movzbl -0x1034d(%rbp,%rax), %r13d
orq %rcx, %r13
incq %rax
cmpq $0x7, %rax
jne 0x370e
movl $0xa, %eax
movl %edx, -0x110(%rbp)
movl %eax, %r14d
testb $0x1, -0x64(%rbp)
je 0x37d0
shrl $0x7, %esi
leaq 0x3a44(%rip), %rdi      # 0x7190
xorl %eax, %eax
movl %esi, %r12d
callq 0x2040
leaq 0x3a84(%rip), %rdi      # 0x71e1
movl %r12d, %esi
xorl %eax, %eax
callq 0x2040
leaq 0x3a91(%rip), %rdi      # 0x71ff
movl -0x110(%rbp), %esi
xorl %eax, %eax
callq 0x2040
movzbl -0x1034f(%rbp), %esi
shrl $0x7, %esi
leaq 0x3a7f(%rip), %rdi      # 0x720b
xorl %eax, %eax
callq 0x2040
leaq 0x3a80(%rip), %rdi      # 0x721a
movq %r13, %rsi
xorl %eax, %eax
callq 0x2040
leaq -0x10350(%rbp), %rax
movzbl (%r14,%rax), %esi
movzbl 0x1(%r14,%rax), %edx
movzbl 0x2(%r14,%rax), %ecx
movzbl 0x3(%r14,%rax), %r8d
leaq 0x3a65(%rip), %rdi      # 0x722e
xorl %eax, %eax
callq 0x2040
leaq (%r14,%r13), %r12
addq $0x4, %r12
leaq (%r14,%r13), %rax
addq $-0xfffb, %rax          # imm = 0xFFFF0005
cmpq $-0x10000, %rax         # imm = 0xFFFF0000
jae 0x383b
cmpq -0x60(%rbp), %r12
leaq -0x80(%rbp), %r14
jbe 0x381c
movl -0x2c(%rbp), %edi
movq %r12, %rdx
subq -0x60(%rbp), %rdx
leaq -0x10350(%rbp), %rsi
callq 0x22b0
testl %eax, %eax
je 0x381c
addl %eax, %ebx
movslq %ebx, %rax
movq %rax, -0x60(%rbp)
cmpq %rax, %r12
ja 0x37f4
leaq 0x3a33(%rip), %rdi      # 0x7256
movl $0xffff, %esi           # imm = 0xFFFF
xorl %eax, %eax
callq 0x2040
leaq -0x160(%rbp), %r12
jmp 0x3c3a
movq -0x60(%rbp), %rax
cmpq %rax, %r12
jbe 0x389c
movl -0x2c(%rbp), %edi
leaq (%rax,%rbp), %rsi
addq $-0x10350, %rsi         # imm = 0xFFFEFCB0
movq %r12, %rdx
subq %rax, %rdx
callq 0x22b0
addl %eax, %ebx
movslq %ebx, %rax
jmp 0x383f
leaq 0x3b87(%rip), %rdi      # 0x73f2
xorl %eax, %eax
callq 0x2040
leaq 0x3b99(%rip), %rdi      # 0x7412
leaq -0x10350(%rbp), %rsi
xorl %eax, %eax
callq 0x2040
movq -0x38(%rbp), %rbx
leaq -0xe8(%rbp), %rdi
callq 0x42ae
jmp 0x3c57
movb $0x0, -0x10350(%rbp,%rax)
testb $0x1, -0x64(%rbp)
movq %rax, -0x60(%rbp)
je 0x38d0
leaq 0x39f2(%rip), %rdi      # 0x72a7
movl %ebx, %esi
xorl %eax, %eax
callq 0x2040
leaq 0x39f9(%rip), %rdi      # 0x72be
xorl %eax, %eax
callq 0x2040
movq -0x60(%rbp), %rax
testq %r13, %r13
leaq -0x160(%rbp), %r12
je 0x3b5d
leaq 0x10(%r15), %rbx
addq $0x18, %r15
leaq 0x4(%r14), %rax
leaq -0x1034c(%rbp), %rcx
addq %r14, %rcx
xorl %edx, %edx
movl %edx, %esi
andl $0x3, %esi
addq %r14, %rsi
movb -0x10350(%rbp,%rsi), %sil
xorb %sil, (%rcx,%rdx)
incq %rdx
cmpq %rdx, %r13
jne 0x38f8
cmpq $0x7, %r13
jbe 0x3b29
leaq -0x10350(%rbp), %rcx
cmpb $0x68, 0x6(%r14,%rcx)
jne 0x3b29
cmpb $0x72, 0x7(%r14,%rcx)
jne 0x3b29
cmpb $0x65, 0x8(%r14,%rcx)
jne 0x3b29
cmpb $0x66, 0x9(%r14,%rcx)
jne 0x3b29
leaq (%rax,%rbp), %rcx
addq $-0x10350, %rcx         # imm = 0xFFFEFCB0
leaq -0x10347(%rbp,%rax), %rsi
leaq -0x2(%r13,%rcx), %rdx
leaq -0xd8(%rbp), %r13
movq %r13, -0xe8(%rbp)
leaq -0xe8(%rbp), %r14
movq %r14, %rdi
callq 0x4190
movq -0xe8(%rbp), %rdi
callq 0x22e0
movq %r14, %rdi
leaq 0x396f(%rip), %rsi      # 0x730f
callq 0x20b0
testl %eax, %eax
je 0x2ae7
movq %r15, %rdi
movq %r14, %rsi
callq 0x2150
leaq -0x2d0(%rbp), %rdi
leaq -0xe8(%rbp), %rsi
callq 0x4ab6
movl (%rax), %r14d
leaq -0x298(%rbp), %rdi
leaq -0x2c(%rbp), %rsi
callq 0x51e0
movl %r14d, (%rax)
leaq -0x2d0(%rbp), %rdi
leaq -0xe8(%rbp), %rsi
callq 0x4ab6
leaq -0x228(%rbp), %rdi
movq %rax, %rsi
callq 0x4ee8
movq %rax, %rdi
movq %rbx, %rsi
callq 0x4124
movl -0x2c(%rbp), %ebx
movl %ebx, %r14d
negl %r14d
cmovsl %ebx, %r14d
movl $0x1, %r15d
cmpl $0xa, %r14d
jb 0x2b7c
movl $0x4, %r15d
movl %r14d, %eax
cmpl $0x63, %eax
jbe 0x2b73
cmpl $0x3e7, %eax            # imm = 0x3E7
jbe 0x2b79
cmpl $0x2710, %eax           # imm = 0x2710
jb 0x2b7c
movl %eax, %ecx
movl $0xd1b71759, %edx       # imm = 0xD1B71759
imulq %rdx, %rcx
shrq $0x2d, %rcx
addl $0x4, %r15d
cmpl $0x1869f, %eax          # imm = 0x1869F
movl %ecx, %eax
ja 0x3a34
addl $-0x3, %r15d
jmp 0x2b7c
leaq -0x48(%rbp), %r14
movq %r14, -0x58(%rbp)
movq %r13, %rdi
leaq 0x3905(%rip), %rsi      # 0x738f
leaq 0x3949(%rip), %rdx      # 0x73da
callq 0x495c
movq %r13, %rdi
leaq 0x393b(%rip), %rsi      # 0x73db
callq 0x2360
movq %r13, %rdi
leaq -0x90(%rbp), %rsi
callq 0x2360
movq %r13, %rdi
leaq 0x391a(%rip), %rsi      # 0x73d8
callq 0x2360
movq -0x58(%rbp), %rbx
movl -0x2c(%rbp), %r14d
movq %rbx, %rdi
callq 0x2100
movl %r14d, %edi
movq %rbx, %rsi
movq %rax, %rdx
xorl %ecx, %ecx
callq 0x2130
movq %rax, %r14
movq %rbx, %rdi
callq 0x2100
cmpq %rax, %r14
jne 0x2ad6
movl $0x1, 0x14(%r15)
movq -0x58(%rbp), %rdi
leaq -0x48(%rbp), %rax
cmpq %rax, %rdi
leaq -0x80(%rbp), %r14
movq -0x38(%rbp), %rbx
je 0x388b
movq -0x48(%rbp), %rsi
incq %rsi
callq 0x2200
jmp 0x388b
movl -0x110(%rbp), %eax
addl $-0x3, %eax
cmpl $-0x2, %eax
jb 0x3c36
testq %r13, %r13
je 0x3b78
leaq -0x1034c(%rbp), %rax
addq %r14, %rax
xorl %ecx, %ecx
movb (%rax,%rcx), %dl
movb %dl, -0x4(%rax,%rcx)
incq %rcx
cmpq %rcx, %r13
jne 0x3b4c
jmp 0x3b78
movl -0x110(%rbp), %ecx
addl $-0x3, %ecx
cmpl $-0x2, %ecx
movq -0x38(%rbp), %rbx
jae 0x3b78
leaq -0x80(%rbp), %r14
jmp 0x3c42
andb $-0x71, -0x10350(%rbp)
andb $0x7f, -0x1034f(%rbp)
leaq (%r14,%r13), %rbx
xorl %ecx, %ecx
movb %cl, -0x10350(%rbp,%rbx)
leaq (%r14,%r13), %rax
incq %rax
movb %cl, -0x10350(%rbp,%rax)
leaq (%r14,%r13), %rax
addq $0x2, %rax
movb %cl, -0x10350(%rbp,%rax)
addq %r14, %r13
movb %cl, -0x1034d(%rbp,%r13)
cmpb $0x74, -0x10350(%rbp,%r14)
jne 0x29ef
movq %r14, %rax
orq $0x1, %rax
cmpb $0x6f, -0x10350(%rbp,%rax)
jne 0x29ef
movq %r14, %rax
addq $0x2, %rax
movb -0x10350(%rbp,%rax), %al
xorl %edi, %edi
cmpb $0x7b, %al
je 0x3c15
leaq -0x1034d(%rbp), %rcx
addq %rcx, %r14
xorl %edi, %edi
movsbl %al, %eax
leal (%rdi,%rdi,4), %ecx
leal (%rax,%rcx,2), %edi
addl $-0x30, %edi
movb (%r14), %al
incq %r14
cmpb $0x7b, %al
jne 0x3bff
leaq -0x10350(%rbp), %rsi
movq %rbx, %rdx
xorl %ecx, %ecx
callq 0x2130
cmpq %rbx, %rax
jne 0x2b51
incq -0x120(%rbp)
leaq -0x80(%rbp), %r14
movq -0x38(%rbp), %rbx
movq -0x60(%rbp), %rax
incq -0x190(%rbp)
addq %rax, -0x198(%rbp)
movq %rax, -0x110(%rbp)
movq -0x170(%rbp), %rdi
cmpq %r12, %rdi
je 0x3c72
movq -0x160(%rbp), %rsi
incq %rsi
callq 0x2200
movq %rbx, %r15
testq %rbx, %rbx
jne 0x33f3
jmp 0x279d
leaq 0x340e(%rip), %rdi      # 0x7098
callq 0x21c0
movl $0x1, %edi
callq 0x2270
leaq 0x3389(%rip), %rdi      # 0x7029
jmp 0x3c8a
leaq 0x338e(%rip), %rdi      # 0x7037
jmp 0x3c8a
leaq 0x3390(%rip), %rdi      # 0x7042
jmp 0x3c8a
leaq 0x33ad(%rip), %rdi      # 0x7068
jmp 0x3c8a
movq %rax, %rbx
movq -0x1e8(%rbp), %rdi
leaq -0x1d8(%rbp), %rax
cmpq %rax, %rdi
je 0x3ce7
movq -0x1d8(%rbp), %rsi
incq %rsi
callq 0x2200
jmp 0x3ce7
movq %rax, %rbx
movq -0x58(%rbp), %rdi
leaq -0x48(%rbp), %rax
cmpq %rax, %rdi
je 0x3d3f
movq -0x48(%rbp), %rsi
incq %rsi
callq 0x2200
jmp 0x3d3f
movq %rax, %rbx
jmp 0x3d9b
jmp 0x3dd1
movq %rax, %rbx
movq -0x58(%rbp), %rdi
leaq -0x48(%rbp), %rax
cmpq %rax, %rdi
je 0x3d30
movq -0x48(%rbp), %rsi
incq %rsi
callq 0x2200
jmp 0x3d30
movq %rax, %rbx
leaq -0x160(%rbp), %r12
jmp 0x3ef2
movq %rax, %rbx
movq -0x108(%rbp), %rdi
leaq -0xf8(%rbp), %rax
cmpq %rax, %rdi
je 0x3d79
movq -0xf8(%rbp), %rsi
incq %rsi
callq 0x2200
jmp 0x3d79
movq %rax, %rbx
leaq -0xb0(%rbp), %rdi
callq 0x4024
jmp 0x3dd4
jmp 0x3dd1
movq %rax, %rbx
movq -0xb0(%rbp), %rdi
leaq -0xa0(%rbp), %rax
cmpq %rax, %rdi
je 0x3d9b
movq -0xa0(%rbp), %rsi
incq %rsi
callq 0x2200
movq -0x140(%rbp), %rdi
leaq -0x130(%rbp), %rax
cmpq %rax, %rdi
je 0x3dbd
movq -0x130(%rbp), %rsi
incq %rsi
callq 0x2200
leaq -0x160(%rbp), %r12
leaq -0xd8(%rbp), %r13
leaq -0x80(%rbp), %r14
jmp 0x3dd4
movq %rax, %rbx
movq -0x90(%rbp), %rdi
cmpq %r14, %rdi
je 0x3ef9
movq -0x80(%rbp), %rsi
jmp 0x3ee5
movq %rax, %rbx
movq -0x1c8(%rbp), %rdi
leaq -0x1b8(%rbp), %rax
cmpq %rax, %rdi
je 0x3e2e
movq -0x1b8(%rbp), %rsi
incq %rsi
callq 0x2200
jmp 0x3e2e
movq %rax, %rbx
leaq -0xd8(%rbp), %r13
jmp 0x3ecb
movq %rax, %rbx
jmp 0x3ef9
movq %rax, %rbx
movq -0x90(%rbp), %rdi
leaq -0x80(%rbp), %rax
cmpq %rax, %rdi
je 0x3e4f
movq -0x80(%rbp), %rsi
incq %rsi
callq 0x2200
jmp 0x3e4f
movq %rax, %rbx
movq -0x108(%rbp), %rdi
leaq -0xf8(%rbp), %rax
cmpq %rax, %rdi
je 0x3e71
movq -0xf8(%rbp), %rsi
incq %rsi
callq 0x2200
leaq -0x160(%rbp), %r12
leaq -0xd8(%rbp), %r13
jmp 0x3e90
movq %rax, %rbx
jmp 0x3eb0
jmp 0x3eef
jmp 0x3fb8
movq %rax, %rbx
movq -0x58(%rbp), %rdi
leaq -0x48(%rbp), %rax
cmpq %rax, %rdi
leaq -0xa0(%rbp), %r14
je 0x3eb0
movq -0x48(%rbp), %rsi
incq %rsi
callq 0x2200
movq -0xb0(%rbp), %rdi
cmpq %r14, %rdi
je 0x3ecb
movq -0xa0(%rbp), %rsi
incq %rsi
callq 0x2200
movq -0x140(%rbp), %rdi
leaq -0x130(%rbp), %rax
cmpq %rax, %rdi
je 0x3ef9
movq -0x130(%rbp), %rsi
incq %rsi
callq 0x2200
jmp 0x3ef9
movq %rax, %rbx
leaq -0xd8(%rbp), %r13
movq -0xe8(%rbp), %rdi
cmpq %r13, %rdi
je 0x3fc9
movq -0xd8(%rbp), %rsi
incq %rsi
callq 0x2200
jmp 0x3fc9
jmp 0x3fb8
jmp 0x3fb8
movq %rax, %rbx
leaq -0x48(%rbp), %r14
jmp 0x3f3c
jmp 0x3f47
jmp 0x3fb8
jmp 0x3f47
movq %rax, %rbx
movq -0x58(%rbp), %rdi
cmpq %r14, %rdi
jne 0x3f75
jmp 0x3f81
movq %rax, %rbx
jmp 0x3f81
movq %rax, %rbx
movq -0x90(%rbp), %rdi
cmpq %r14, %rdi
je 0x3f81
movq -0x80(%rbp), %rsi
jmp 0x3f79
jmp 0x3fb8
jmp 0x3fb8
movq %rax, %rbx
movq -0x58(%rbp), %rdi
leaq -0x48(%rbp), %rax
cmpq %rax, %rdi
je 0x3f81
movq -0x48(%rbp), %rsi
incq %rsi
callq 0x2200
leaq -0xe8(%rbp), %rdi
callq 0x42ae
jmp 0x3fc9
jmp 0x3fb8
jmp 0x3fb8
jmp 0x3fbf
movq %rax, %rbx
movq -0xe0(%rbp), %rdi
leaq -0xd0(%rbp), %rax
cmpq %rax, %rdi
je 0x3feb
movq -0xd0(%rbp), %rsi
jmp 0x3fdc
jmp 0x3fe8
jmp 0x3fb8
movq %rax, %rbx
jmp 0x3fc9
jmp 0x3fe8
movq %rax, %rbx
leaq -0x160(%rbp), %r12
movq -0x170(%rbp), %rdi
cmpq %r12, %rdi
je 0x3feb
movq -0x160(%rbp), %rsi
incq %rsi
callq 0x2200
jmp 0x3feb
jmp 0x3fe8
movq %rax, %rbx
leaq -0x260(%rbp), %rdi
callq 0x43aa
leaq -0x298(%rbp), %rdi
callq 0x4460
leaq -0x228(%rbp), %rdi
callq 0x44e8
leaq -0x2d0(%rbp), %rdi
callq 0x4590
movq %rbx, %rdi
callq 0x2320
nop