// File: m1c0l[P]TCP/server.cpp
// Function: main
int main(int argc, char **argv) {
	if (argc != 3) {
		cerr << "usage: " << argv[0] << " PORT-NUMBER FILENAME" << '\n';
		return 1;
	}

	string port = argv[1];
	string filename = argv[2];

	srand (time(NULL)); //Used to generate random ISN

	//Create UDP socket
	int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
	if (sockfd == -1) {
		perror("socket");
		return 1;
	}

	//Timeout flags and stuff could be set here
	int yes = 1;
	if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
		perror("setsockopt");
		return 1;
	}


	sockaddr_in addr, other;
	addr.sin_family = AF_INET;
	addr.sin_port = htons(stoi(port));
	addr.sin_addr.s_addr = htonl(INADDR_ANY);//inet_addr("127.0.0.1");

	memset(addr.sin_zero, '\0', sizeof(addr.sin_zero));

	if (bind(sockfd, (sockaddr*) &addr, sizeof(addr)) == -1) {
		perror("bind");
		return 2;
	}

	socklen_t other_length = sizeof(other);
	TcpMessage received;
	TcpMessage toSend;
	bool hasReceivedSyn = false;
	bool sendFile = false;
	uint16_t seqToSend = rand() % MAX_SEQ_NUM; //The first sync
	uint16_t ackToSend;
	uint16_t ssThresh = MAX_SEQ_NUM;
	ifstream wantedFile;
	string flagsToSend = "";
	for (int packetsSent = 0; true; packetsSent++) {
	    // cerr << "Waiting for something" << endl;
		int r = received.recvfrom(sockfd, &other, other_length);
		if (r == RECV_TIMEOUT) {
			if (hasReceivedSyn) { // client ACK not received; resend SYN-ACK
				printSend("SYN", toSend.seqNum, DATA_SIZE, DATA_SIZE, true);
				toSend.sendto(sockfd, &other, other_length);
				// cerr << "Sending SYN-ACK (retransmit):" << endl;
				toSend.dump();
			}
			continue;
		}

		// cerr << "Packet arrived from" << inet_ntoa(addr.sin_addr)<< ": " << ntohs(other.sin_port) << endl;
		// cerr << "Received:" << endl;
		received.dump();

		clientRecvWindow = received.recvWindow;

		if (!packetsSent) {
			// Set receive timeout of 0.5s
			// Only want to run this code once
			timeval recvTimeval;
			recvTimeval.tv_sec = 0;
			recvTimeval.tv_usec = TIMEOUT * 1000;
			setSocketTimeout(sockfd, recvTimeval);
		}


		//Send SYN-ACK if client is trying to set up connection

		switch (received.flags) {
		case SYN_FLAG:
			printRecv(received.ackNum);
		    if (hasReceivedSyn) {
				// cerr << "Got another SYN, sending SYN-ACK\n";
			}
		    flagsToSend ="SA";
			printSend("SYN", seqToSend, DATA_SIZE, DATA_SIZE, hasReceivedSyn);
		    hasReceivedSyn = true;

		    break;

		case SYN_FLAG | ACK_FLAG:
		    // cerr << "Both SYN and ACK were set by client\n";
		    //exit(1);
		    break;

		case ACK_FLAG:
			printRecv(received.ackNum);
		    if (!hasReceivedSyn) {
				// cerr << "ACK before handshake\n";
				break;
			}
		    flagsToSend = "A";
		    //Time to start sending the file back
		    sendFile = true;

		    break;

		default:
		    // cerr << "Incorrect flags set\n";
		    break;
		}

		// if we're done handshake and are ready to send the file now
		if (sendFile) {
			break;
		}

		ackToSend = incSeqNum(received.seqNum, 1);
		toSend = TcpMessage(seqToSend, ackToSend, clientRecvWindow, flagsToSend);
		toSend.sendto(sockfd, &other, other_length);
		// cerr << "Handshake: sending packet\n";
		toSend.dump();
	}

	char filebuf[DATA_SIZE];
	wantedFile.open(filename);
	if (!wantedFile) {
		perror("fstream open");
		exit(1);
	}

	// if the client sent data, increment ack by that number
	size_t recvLength = received.data.length();
	ackToSend = incSeqNum(received.seqNum, recvLength);
	// increment our sequence number by 1
	seqToSend = incSeqNum(seqToSend, 1);

	double cwnd = DATA_SIZE;
	uint16_t cwndBot = seqToSend;
	uint16_t cwndTop = seqToSend + cwnd;
	bool useSlowStart = true;
	int filepkts = 0;

	uint16_t lastAckExpected = BAD_SEQ_NUM;
	lastAckRecvd = seqToSend;



	/* data */

	while(true) {

		// update receiver/congestion windows
		rwndBot = lastAckRecvd;
		rwndTop = incSeqNum(rwndBot, clientRecvWindow);
		cwndBot = lastAckRecvd;
		cwndTop = incSeqNum(cwndBot, cwnd);

		// remove old packets that are outside receiver window
		auto it = packetsInWindow.begin(); // iterator
		while (it != packetsInWindow.end()) {
			auto curr = it;
			it++;
			uint16_t currSeq = curr->second.seqNum;
			if (!inWindow(currSeq, rwndBot, rwndTop)) {
				packetsInWindow.erase(curr);
			}
		}

		// create new packets
		uint16_t seqToSendEnd = incSeqNum(seqToSend, DATA_SIZE);
		// stop if next packet will be outside rwnd or cwnd
		while (inWindow(seqToSendEnd, cwndBot, cwndTop) &&
			   lastAckExpected == BAD_SEQ_NUM) {

			memset(filebuf, 0, DATA_SIZE);
			wantedFile.read(filebuf, DATA_SIZE);
			streamsize dataSize = wantedFile.gcount();
			toSend = TcpMessage(seqToSend, ackToSend, clientRecvWindow, "A");
			toSend.data = string(filebuf, dataSize);

			// if already in map, we're retransmitting
			bool isRetransmit = packetsInWindow.count(toSend.seqNum);
			// store packet in case retransmission needed
			packetsInWindow[toSend.seqNum] = toSend;
			timestamps[toSend.seqNum] = now();

			seqToSend = incSeqNum(seqToSend, dataSize);
			seqToSendEnd = incSeqNum(seqToSend, DATA_SIZE);

			// send packet
			if (dataSize > 0) {
				printSend("data", toSend.seqNum, cwnd, ssThresh, isRetransmit);
				// cerr << "sending packet " << filepkts << " of file: " << endl;
				toSend.dump();
				toSend.sendto(sockfd, &other, other_length);
				filepkts++;
			}
			// no more data; this packet's seq should be the last ACK
			else {
				lastAckExpected = seqToSend;
				break;
			}

		}

	    int r = getAcks(sockfd, &other, other_length);

		// a old packet timed out; resend it
		if (r == RECV_TIMED_OUT_ALREADY) {
			// no packets in window
			if (timedOutSeq == BAD_SEQ_NUM) {
				// cerr << "!!!!!!!!!!!! no packets in window" << endl;
			}

			// cerr << "retransmit (timed out already)" << endl;
			packetsInWindow[timedOutSeq].dump();
			packetsInWindow[timedOutSeq].sendto(sockfd, &other, other_length);
			timestamps[timedOutSeq] = now();
		}

		// no ACK received
		else if (r == RECV_TIMEOUT) {
			// retransmit last ACKed packet
			if (packetsInWindow.count(lastAckRecvd) == 0) {
				// cerr << "!!!!! packet not in window: " << lastAckRecvd << endl;
				// cerr << "!!!!! should never reach this" << endl;
				for (auto i : packetsInWindow) {
					// cerr << i.first << " ";
				}
				// cerr << endl;
				if (packetsInWindow.size() == 0) {
					// cerr << "packetsInWindow is empty!" << endl;
				}
				continue;
			}
			// cerr << "retransmitting (timeout)" << endl;
			printSend("data", packetsInWindow[lastAckRecvd].seqNum, cwnd, ssThresh, true);
			packetsInWindow[lastAckRecvd].dump();
			packetsInWindow[lastAckRecvd].sendto(sockfd, &other, other_length);
			timestamps[lastAckRecvd] = now();

			// update congestion control
			ssThresh = cwnd / 2;
			if (ssThresh < DATA_SIZE) {
				ssThresh = DATA_SIZE;
			}
			cwnd = DATA_SIZE;
			useSlowStart = true;
		}
		// got an ACK
		else {
			// check if we are done
			// this can only be true after the last packet is sent; otherwise,
			// lastAckExpected has a impossible value
			if (lastAckRecvd == lastAckExpected) {
				break;
			}

			// fast retransmit
			if (lastAckRecvd == previousAck) {
				acksInARow++; 
				if (acksInARow == 4) {
					// cerr << "retransmitting (fast retransmit)" << lastAckRecvd << endl;
					if (packetsInWindow.count(lastAckRecvd) == 0) {
						// cerr << "!!!!! packet not in window: " << lastAckRecvd << endl;
						// cerr << "!!!!! should never reach this" << endl;
						for (auto i : packetsInWindow) {
							// cerr << i.first << " ";
						}
						// cerr << endl;
						if (packetsInWindow.size() == 0) {
							// cerr << "packetsInWindow is empty!" << endl;
						}
						continue;
					}
					printSend("data", packetsInWindow[lastAckRecvd].seqNum, cwnd, ssThresh, true);
					packetsInWindow[lastAckRecvd].dump();
					packetsInWindow[lastAckRecvd].sendto(sockfd, &other, other_length);
					timestamps[lastAckRecvd] = now();
					acksInARow = 0;
					//fast recovery
					//should actually be same logic as timeout retransmit, just without setting useSlowStart
					ssThresh = (cwnd/2 < DATA_SIZE) ? DATA_SIZE : cwnd/2;
					cwnd = ssThresh > clientRecvWindow ? clientRecvWindow : ssThresh;
					useSlowStart = false;
					previousAck = lastAckRecvd;
					continue;
					
				}
			}
			previousAck = lastAckRecvd;
			
			// check if all packets in window were cumulatively ACKed
			if (lastAckRecvd == seqToSend) {
				// cerr << "!!!!!!!!! all packets ACKed" << endl;
			}

			// update congestion control
			if (useSlowStart) {
				cwnd = cwnd + DATA_SIZE;
			}
			else {
				cwnd = cwnd + DATA_SIZE * DATA_SIZE /cwnd;
			}
			if (cwnd > clientRecvWindow) {
				cwnd = clientRecvWindow;
			}
			if (cwnd >= ssThresh) {
				useSlowStart = false;
			}
		}
	}


	// cerr << "out of loop\n";


	/* FIN */

	// reset to 0.5s timeout
	timeval recvTimeval;
	recvTimeval.tv_sec = 0;
	recvTimeval.tv_usec = TIMEOUT * 1000;
	setSocketTimeout(sockfd, recvTimeval);

	bool hasReceivedFin = false;
	bool hasReceivedFinAck = false;
	bool hasSentFin = false;
	bool hasSentAckFin = false;
	int timedWaitTimer = 2 * MAX_SEG_LIFETIME; // milliseconds to wait before closing

	while (timedWaitTimer > 0) {

		/* send FIN if no FIN-ACK received yet */
		if (!hasReceivedFinAck) {
			flagsToSend = "F";
			// Sequence number shouldn't change since we already increased by total data size
			ackToSend = 0; // ACK is invalid this packet
			toSend = TcpMessage(seqToSend, ackToSend, clientRecvWindow, flagsToSend);
			toSend.sendto(sockfd, &other, other_length);
			printSend("FIN", seqToSend, DATA_SIZE, ssThresh, hasSentFin);
			// cerr << "Sending FIN\n";
			toSend.dump();
			hasSentFin = true;
		}

		/* timed wait timer counts down after FIN received */
		if (hasReceivedFin) {
			timedWaitTimer -= TIMEOUT; // wait TIMEOUT msec each loop
		}

		int r = received.recvfrom(sockfd, &other, other_length);
		if (r == RECV_TIMEOUT) {
			// cerr << "Timeout while waiting for FIN-ACK/FIN\n";
			continue;
		}
		clientRecvWindow = received.recvWindow;

		switch(received.flags) {
			// FIN-ACK
			case FIN_FLAG | ACK_FLAG:
				printRecv(received.ackNum);
				// cerr << "Received FIN-ACK\n";
				hasReceivedFinAck = true;
				break;

			// FIN
			case FIN_FLAG:
				printRecv(received.ackNum);
				// cerr << "Received FIN\n";

				flagsToSend = "A";// this is "FIN-ACK" but without FIN flag
				seqToSend = incSeqNum(seqToSend, 1);// increase sequence number by 1
				ackToSend = incSeqNum(received.seqNum, 1); // increase ack by 1
				toSend = TcpMessage(seqToSend, ackToSend, clientRecvWindow, flagsToSend);
				toSend.sendto(sockfd, &other, other_length);
				printSend("data", seqToSend, DATA_SIZE, ssThresh, hasSentAckFin);
				// cerr << "Sending ACK of FIN\n";
				toSend.dump();
				// cerr << "Server received FIN; starting timed wait..." << endl;
				hasReceivedFinAck = true; // assume that client got a FIN
				hasReceivedFin = true;
				hasSentAckFin = true;
				break;

			default:
				// cerr << "Received packet wasn't FIN-ACK or FIN!\n";
				//exit(1);
				break;
		}
		received.dump();
	}

	// cerr << "Shouldn't receive anything else from client now\n";

	close(sockfd);
	return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xd40, %rsp            # imm = 0xD40
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
cmpl $0x3, -0x8(%rbp)
je 0x37a9
movq 0xa88a(%rip), %rdi      # 0xdff0
leaq 0x593e(%rip), %rsi      # 0x90ab
callq 0x2260
movq %rax, %rdi
movq -0x10(%rbp), %rax
movq (%rax), %rsi
callq 0x2260
movq %rax, %rdi
leaq 0x5928(%rip), %rsi      # 0x90b3
callq 0x2260
movq %rax, %rdi
movl $0xa, %esi
callq 0x22f0
movl $0x1, -0x4(%rbp)
jmp 0x53ab
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0xb38(%rbp)
leaq -0x31(%rbp), %rdi
movq %rdi, -0xb30(%rbp)
callq 0x2400
movq -0xb38(%rbp), %rsi
movq -0xb30(%rbp), %rdx
leaq -0x30(%rbp), %rdi
callq 0x2c70
jmp 0x37e1
leaq -0x31(%rbp), %rdi
callq 0x22a0
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0xb48(%rbp)
leaq -0x69(%rbp), %rdi
movq %rdi, -0xb40(%rbp)
callq 0x2400
movq -0xb48(%rbp), %rsi
movq -0xb40(%rbp), %rdx
leaq -0x68(%rbp), %rdi
callq 0x2c70
jmp 0x3822
leaq -0x69(%rbp), %rdi
callq 0x22a0
xorl %eax, %eax
movl %eax, %edi
callq 0x2240
movl %eax, %edi
callq 0x2250
movl $0x2, %esi
xorl %edx, %edx
movl %esi, %edi
callq 0x20a0
movl %eax, -0x70(%rbp)
cmpl $-0x1, -0x70(%rbp)
jne 0x38b8
leaq 0x5870(%rip), %rdi      # 0x90c9
callq 0x21f0
jmp 0x3860
movl $0x1, -0x4(%rbp)
movl $0x1, -0x74(%rbp)
jmp 0x5383
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x31(%rbp), %rdi
callq 0x22a0
jmp 0x53b7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x69(%rbp), %rdi
callq 0x22a0
jmp 0x53a0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x5397
movl $0x1, -0x78(%rbp)
movl -0x70(%rbp), %edi
movl $0x1, %esi
movl $0x2, %edx
leaq -0x78(%rbp), %rcx
movl $0x4, %r8d
callq 0x2410
cmpl $-0x1, %eax
jne 0x3901
leaq 0x5757(%rip), %rdi      # 0x903e
callq 0x21f0
jmp 0x38ee
movl $0x1, -0x4(%rbp)
movl $0x1, -0x74(%rbp)
jmp 0x5383
movw $0x2, -0x88(%rbp)
xorl %eax, %eax
movl %eax, %esi
leaq -0x30(%rbp), %rdi
movl $0xa, %edx
callq 0x5610
movl %eax, -0xb4c(%rbp)
jmp 0x3924
movl -0xb4c(%rbp), %eax
movzwl %ax, %edi
callq 0x2050
movw %ax, -0x86(%rbp)
xorl %edi, %edi
callq 0x21b0
movl %eax, -0x84(%rbp)
leaq -0x88(%rbp), %rdi
addq $0x8, %rdi
xorl %esi, %esi
movl $0x8, %edx
callq 0x2150
movl -0x70(%rbp), %edi
leaq -0x88(%rbp), %rsi
movl $0x10, %edx
callq 0x2080
cmpl $-0x1, %eax
jne 0x3997
leaq 0x5753(%rip), %rdi      # 0x90d0
callq 0x21f0
jmp 0x3984
movl $0x2, -0x4(%rbp)
movl $0x1, -0x74(%rbp)
jmp 0x5383
movl $0x10, -0x9c(%rbp)
leaq -0xc8(%rbp), %rdi
callq 0x2860
jmp 0x39af
leaq -0xf0(%rbp), %rdi
callq 0x2860
jmp 0x39bd
movb $0x0, -0xf1(%rbp)
movb $0x0, -0xf2(%rbp)
callq 0x20c0
movslq %eax, %rcx
imulq $-0x77777777, %rcx, %rcx # imm = 0x88888889
shrq $0x20, %rcx
addl %eax, %ecx
movl %ecx, %edx
shrl $0x1f, %edx
shrl $0xe, %ecx
addl %edx, %ecx
imull $0x7800, %ecx, %ecx     # imm = 0x7800
subl %ecx, %eax
movw %ax, -0xf4(%rbp)
movw $0x7800, -0xf8(%rbp)    # imm = 0x7800
leaq -0x300(%rbp), %rdi
callq 0x22e0
jmp 0x3a10
leaq -0x321(%rbp), %rdi
movq %rdi, -0xb58(%rbp)
callq 0x2400
movq -0xb58(%rbp), %rdx
leaq 0x5681(%rip), %rsi      # 0x90b2
leaq -0x320(%rbp), %rdi
callq 0x2c70
jmp 0x3a3f
leaq -0x321(%rbp), %rdi
callq 0x22a0
movl $0x0, -0x328(%rbp)
movb $0x1, %al
testb $0x1, %al
jne 0x3a60
jmp 0x3ec4
movl -0x70(%rbp), %esi
movl -0x9c(%rbp), %ecx
leaq -0xc8(%rbp), %rdi
leaq -0x98(%rbp), %rdx
callq 0x2bb0
movl %eax, -0xb5c(%rbp)
jmp 0x3a84
movl -0xb5c(%rbp), %eax
movl %eax, -0x32c(%rbp)
cmpl $0x2, -0x32c(%rbp)
jne 0x3bd0
testb $0x1, -0xf1(%rbp)
je 0x3bcb
leaq -0x351(%rbp), %rdi
movq %rdi, -0xb68(%rbp)
callq 0x2400
movq -0xb68(%rbp), %rdx
leaq 0x560a(%rip), %rsi      # 0x90d5
leaq -0x350(%rbp), %rdi
callq 0x2c70
jmp 0x3ad9
movzwl -0xf0(%rbp), %esi
leaq -0x350(%rbp), %rdi
movl $0x400, %ecx            # imm = 0x400
movl $0x1, %r8d
movl %ecx, %edx
callq 0x3350
jmp 0x3afb
leaq -0x350(%rbp), %rdi
callq 0x2170
leaq -0x351(%rbp), %rdi
callq 0x22a0
movl -0x70(%rbp), %esi
movl -0x9c(%rbp), %ecx
leaq -0xf0(%rbp), %rdi
leaq -0x98(%rbp), %rdx
callq 0x2b30
jmp 0x3b31
leaq -0xf0(%rbp), %rdi
callq 0x2c60
jmp 0x3b3f
jmp 0x3bcb
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x5375
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x5369
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x321(%rbp), %rdi
callq 0x22a0
jmp 0x535d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x5351
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x3bba
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x350(%rbp), %rdi
callq 0x2170
leaq -0x351(%rbp), %rdi
callq 0x22a0
jmp 0x5351
jmp 0x3e93
leaq -0xc8(%rbp), %rdi
callq 0x2c60
jmp 0x3bde
movw -0xc4(%rbp), %ax
movw %ax, 0xa678(%rip)       # 0xe264
cmpl $0x0, -0x328(%rbp)
jne 0x3c33
movq $0x0, -0x368(%rbp)
movq $0x7a120, -0x360(%rbp) # imm = 0x7A120
movl -0x70(%rbp), %edi
movups -0x368(%rbp), %xmm0
movaps %xmm0, -0x380(%rbp)
movq -0x380(%rbp), %rsi
movq -0x378(%rbp), %rdx
callq 0x3180
jmp 0x3c31
jmp 0x3c33
movzwl -0xc2(%rbp), %eax
movl %eax, -0xb6c(%rbp)
subl $0x2, %eax
je 0x3c6c
jmp 0x3c47
movl -0xb6c(%rbp), %eax
subl $0x4, %eax
je 0x3d4b
jmp 0x3c58
movl -0xb6c(%rbp), %eax
subl $0x6, %eax
je 0x3d49
jmp 0x3d82
movzwl -0xc6(%rbp), %edi
callq 0x3300
jmp 0x3c7a
testb $0x1, -0xf1(%rbp)
je 0x3c85
jmp 0x3c85
leaq 0x544d(%rip), %rsi      # 0x90d9
leaq -0x320(%rbp), %rdi
callq 0x2360
jmp 0x3c9a
leaq -0x3a1(%rbp), %rdi
movq %rdi, -0xb78(%rbp)
callq 0x2400
movq -0xb78(%rbp), %rdx
leaq 0x541a(%rip), %rsi      # 0x90d5
leaq -0x3a0(%rbp), %rdi
callq 0x2c70
jmp 0x3cc9
movzwl -0xf4(%rbp), %esi
movzbl -0xf1(%rbp), %r8d
andl $0x1, %r8d
leaq -0x3a0(%rbp), %rdi
movl $0x400, %ecx            # imm = 0x400
movl %ecx, %edx
callq 0x3350
jmp 0x3cf1
leaq -0x3a0(%rbp), %rdi
callq 0x2170
leaq -0x3a1(%rbp), %rdi
callq 0x22a0
movb $0x1, -0xf1(%rbp)
jmp 0x3d84
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x3d38
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x3a0(%rbp), %rdi
callq 0x2170
leaq -0x3a1(%rbp), %rdi
callq 0x22a0
jmp 0x5351
jmp 0x3d84
movzwl -0xc6(%rbp), %edi
callq 0x3300
jmp 0x3d59
testb $0x1, -0xf1(%rbp)
jne 0x3d64
jmp 0x3d84
leaq 0x536f(%rip), %rsi      # 0x90da
leaq -0x320(%rbp), %rdi
callq 0x2360
jmp 0x3d79
movb $0x1, -0xf2(%rbp)
jmp 0x3d84
jmp 0x3d84
testb $0x1, -0xf2(%rbp)
je 0x3d92
jmp 0x3ec4
movzwl -0xc8(%rbp), %edi
movl $0x1, %esi
callq 0x2fc0
movw %ax, -0xb7a(%rbp)
jmp 0x3dac
movw -0xb7a(%rbp), %ax
movw %ax, -0xf6(%rbp)
movw -0xf4(%rbp), %ax
movw %ax, -0xb80(%rbp)
movw -0xf6(%rbp), %ax
movw %ax, -0xb7e(%rbp)
movw 0xa487(%rip), %ax       # 0xe264
movw %ax, -0xb7c(%rbp)
leaq -0x3f0(%rbp), %rdi
leaq -0x320(%rbp), %rsi
callq 0x2120
jmp 0x3df9
movw -0xb7c(%rbp), %ax
movw -0xb7e(%rbp), %cx
movw -0xb80(%rbp), %dx
movzwl %dx, %esi
movzwl %cx, %edx
movzwl %ax, %ecx
leaq -0x3d0(%rbp), %rdi
leaq -0x3f0(%rbp), %r8
callq 0x2660
jmp 0x3e2c
leaq -0xf0(%rbp), %rdi
movq %rdi, -0xb88(%rbp)
leaq -0x3d0(%rbp), %rsi
movq %rsi, -0xb90(%rbp)
callq 0x5650
movq -0xb90(%rbp), %rdi
callq 0x55f0
leaq -0x3f0(%rbp), %rdi
callq 0x2170
movq -0xb88(%rbp), %rdi
movl -0x70(%rbp), %esi
movl -0x9c(%rbp), %ecx
leaq -0x98(%rbp), %rdx
callq 0x2b30
jmp 0x3e83
leaq -0xf0(%rbp), %rdi
callq 0x2c60
jmp 0x3e91
jmp 0x3e93
movl -0x328(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x328(%rbp)
jmp 0x3a55
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x3f0(%rbp), %rdi
callq 0x2170
jmp 0x5351
leaq -0x300(%rbp), %rdi
leaq -0x68(%rbp), %rsi
movl $0x8, %edx
callq 0x2210
jmp 0x3edb
movq -0x300(%rbp), %rax
movq -0x18(%rax), %rax
leaq -0x300(%rbp,%rax), %rdi
callq 0x2140
movb %al, -0xb91(%rbp)
jmp 0x3efb
movb -0xb91(%rbp), %al
testb $0x1, %al
jne 0x3f07
jmp 0x3f1f
leaq 0x51ce(%rip), %rdi      # 0x90dc
callq 0x21f0
jmp 0x3f15
movl $0x1, %edi
callq 0x2300
leaq -0xc0(%rbp), %rdi
callq 0x2390
movq %rax, -0x7f8(%rbp)
movzwl -0xc8(%rbp), %edi
movzwl -0x7f8(%rbp), %esi
callq 0x2fc0
movw %ax, -0xb94(%rbp)
jmp 0x3f4e
movw -0xb94(%rbp), %ax
movw %ax, -0xf6(%rbp)
movzwl -0xf4(%rbp), %edi
movl $0x1, %esi
callq 0x2fc0
movw %ax, -0xb96(%rbp)
jmp 0x3f76
movw -0xb96(%rbp), %ax
movw %ax, -0xf4(%rbp)
movabsq $0x4090000000000000, %rax # imm = 0x4090000000000000
movq %rax, -0x800(%rbp)
movw -0xf4(%rbp), %ax
movw %ax, -0x802(%rbp)
movzwl -0xf4(%rbp), %eax
cvtsi2sd %eax, %xmm0
movsd -0x800(%rbp), %xmm1
addsd %xmm1, %xmm0
cvttsd2si %xmm0, %eax
movw %ax, -0x804(%rbp)
movb $0x1, -0x805(%rbp)
movl $0x0, -0x80c(%rbp)
movw $0xd903, -0x80e(%rbp)   # imm = 0xD903
movw -0xf4(%rbp), %ax
movw %ax, 0xa275(%rip)       # 0xe262
jmp 0x3fef
movw 0xa26c(%rip), %ax       # 0xe262
movw %ax, 0xa269(%rip)       # 0xe266
movzwl 0xa262(%rip), %edi      # 0xe266
movzwl 0xa259(%rip), %esi      # 0xe264
callq 0x2fc0
movw %ax, -0xb98(%rbp)
jmp 0x4019
movw -0xb98(%rbp), %ax
movw %ax, 0xa241(%rip)       # 0xe268
movw 0xa234(%rip), %ax       # 0xe262
movw %ax, -0x802(%rbp)
movzwl -0x802(%rbp), %edi
cvttsd2si -0x800(%rbp), %eax
movzwl %ax, %esi
callq 0x2fc0
movw %ax, -0xb9a(%rbp)
jmp 0x4055
movw -0xb9a(%rbp), %ax
movw %ax, -0x804(%rbp)
leaq 0xa206(%rip), %rdi      # 0xe270
callq 0x5470
movq %rax, -0x818(%rbp)
leaq 0xa1f3(%rip), %rdi      # 0xe270
callq 0x54a0
movq %rax, -0x820(%rbp)
leaq -0x818(%rbp), %rdi
leaq -0x820(%rbp), %rsi
callq 0x54d0
testb $0x1, %al
jne 0x40a5
jmp 0x414a
movq -0x818(%rbp), %rax
movq %rax, -0x828(%rbp)
leaq -0x818(%rbp), %rdi
xorl %esi, %esi
callq 0x5690
movq %rax, -0x830(%rbp)
leaq -0x828(%rbp), %rdi
callq 0x56c0
movw 0x8(%rax), %ax
movw %ax, -0x832(%rbp)
movzwl -0x832(%rbp), %edi
movzwl 0xa179(%rip), %esi      # 0xe266
movzwl 0xa174(%rip), %edx      # 0xe268
callq 0x2ff0
movb %al, -0xb9b(%rbp)
jmp 0x4101
movb -0xb9b(%rbp), %al
testb $0x1, %al
jne 0x4145
jmp 0x410d
movq -0x828(%rbp), %rax
movq %rax, -0x840(%rbp)
movq -0x840(%rbp), %rsi
leaq 0xa147(%rip), %rdi      # 0xe270
callq 0x56f0
movq %rax, -0xba8(%rbp)
jmp 0x4137
movq -0xba8(%rbp), %rax
movq %rax, -0x848(%rbp)
jmp 0x4076
movzwl -0xf4(%rbp), %edi
movl $0x400, %esi            # imm = 0x400
callq 0x2fc0
movw %ax, -0xbaa(%rbp)
jmp 0x4164
movw -0xbaa(%rbp), %ax
movw %ax, -0x84a(%rbp)
movzwl -0x84a(%rbp), %edi
movzwl -0x802(%rbp), %esi
movzwl -0x804(%rbp), %edx
callq 0x2ff0
movb %al, -0xbab(%rbp)
jmp 0x4194
movb -0xbab(%rbp), %cl
xorl %eax, %eax
testb $0x1, %cl
movb %al, -0xbac(%rbp)
jne 0x41a9
jmp 0x41be
movzwl -0x80e(%rbp), %eax
cmpl $0xd903, %eax           # imm = 0xD903
sete %al
movb %al, -0xbac(%rbp)
movb -0xbac(%rbp), %al
testb $0x1, %al
jne 0x41cd
jmp 0x45e0
leaq -0x7f0(%rbp), %rdi
movq %rdi, -0xbc0(%rbp)
xorl %esi, %esi
movl $0x400, %edx            # imm = 0x400
movq %rdx, -0xbb8(%rbp)
callq 0x2150
movq -0xbc0(%rbp), %rsi
movq -0xbb8(%rbp), %rdx
leaq -0x300(%rbp), %rdi
callq 0x2330
jmp 0x420a
leaq -0x300(%rbp), %rdi
callq 0x2460
movq %rax, -0xbc8(%rbp)
jmp 0x421f
movq -0xbc8(%rbp), %rax
movq %rax, -0x858(%rbp)
movw -0xf4(%rbp), %ax
movw %ax, -0xbd6(%rbp)
movw -0xf6(%rbp), %ax
movw %ax, -0xbd4(%rbp)
movw 0xa014(%rip), %ax       # 0xe264
movw %ax, -0xbd2(%rbp)
leaq -0x8a1(%rbp), %rdi
movq %rdi, -0xbd0(%rbp)
callq 0x2400
movq -0xbd0(%rbp), %rdx
leaq 0x4e62(%rip), %rsi      # 0x90da
leaq -0x8a0(%rbp), %rdi
callq 0x2c70
jmp 0x4286
movw -0xbd2(%rbp), %ax
movw -0xbd4(%rbp), %cx
movw -0xbd6(%rbp), %dx
movzwl %dx, %esi
movzwl %cx, %edx
movzwl %ax, %ecx
leaq -0x880(%rbp), %rdi
leaq -0x8a0(%rbp), %r8
callq 0x2660
jmp 0x42b9
leaq -0xf0(%rbp), %rdi
leaq -0x880(%rbp), %rsi
movq %rsi, -0xbf0(%rbp)
callq 0x5650
movq -0xbf0(%rbp), %rdi
callq 0x55f0
leaq -0x8a0(%rbp), %rdi
callq 0x2170
leaq -0x8a1(%rbp), %rdi
callq 0x22a0
movq -0x858(%rbp), %rax
movq %rax, -0xbe8(%rbp)
leaq -0x8c9(%rbp), %rdi
movq %rdi, -0xbe0(%rbp)
callq 0x2400
movq -0xbe8(%rbp), %rdx
movq -0xbe0(%rbp), %rcx
leaq -0x8c8(%rbp), %rdi
leaq -0x7f0(%rbp), %rsi
callq 0x22d0
jmp 0x433b
leaq -0xe8(%rbp), %rdi
leaq -0x8c8(%rbp), %rsi
movq %rsi, -0xc00(%rbp)
callq 0x2310
movq -0xc00(%rbp), %rdi
callq 0x2170
leaq -0x8c9(%rbp), %rdi
callq 0x22a0
leaq 0x9efc(%rip), %rdi      # 0xe270
leaq -0xf0(%rbp), %rsi
callq 0x5730
movq %rax, -0xbf8(%rbp)
jmp 0x4389
movq -0xbf8(%rbp), %rax
testq %rax, %rax
setne -0x8ca(%rbp)
leaq 0x9ecf(%rip), %rdi      # 0xe270
leaq -0xf0(%rbp), %rsi
callq 0x5760
movq %rax, -0xc08(%rbp)
jmp 0x43b6
movq -0xc08(%rbp), %rdi
leaq -0xf0(%rbp), %rsi
callq 0x5790
jmp 0x43cb
callq 0x31e0
movq %rdx, -0xc18(%rbp)
movq %rax, -0xc10(%rbp)
jmp 0x43e0
movq -0xc18(%rbp), %rax
movq -0xc10(%rbp), %rcx
movq %rcx, -0x8e0(%rbp)
movq %rax, -0x8d8(%rbp)
leaq 0x9ea5(%rip), %rdi      # 0xe2a8
leaq -0xf0(%rbp), %rsi
callq 0x5570
movq %rax, -0xc20(%rbp)
jmp 0x4418
movq -0xc20(%rbp), %rax
movups -0x8e0(%rbp), %xmm0
movups %xmm0, (%rax)
movzwl -0xf4(%rbp), %edi
movzwl -0x858(%rbp), %esi
callq 0x2fc0
movw %ax, -0xc22(%rbp)
jmp 0x4445
movw -0xc22(%rbp), %ax
movw %ax, -0xf4(%rbp)
movzwl -0xf4(%rbp), %edi
movl $0x400, %esi            # imm = 0x400
callq 0x2fc0
movw %ax, -0xc24(%rbp)
jmp 0x446d
movw -0xc24(%rbp), %ax
movw %ax, -0x84a(%rbp)
cmpq $0x0, -0x858(%rbp)
jle 0x45cb
leaq -0x901(%rbp), %rdi
movq %rdi, -0xc30(%rbp)
callq 0x2400
movq -0xc30(%rbp), %rdx
leaq 0x4bfc(%rip), %rsi      # 0x90a6
leaq -0x900(%rbp), %rdi
callq 0x2c70
jmp 0x44b8
movzwl -0xf0(%rbp), %esi
cvttsd2si -0x800(%rbp), %edx
movzwl -0xf8(%rbp), %ecx
movzbl -0x8ca(%rbp), %r8d
andl $0x1, %r8d
leaq -0x900(%rbp), %rdi
callq 0x3350
jmp 0x44e8
leaq -0x900(%rbp), %rdi
callq 0x2170
leaq -0x901(%rbp), %rdi
callq 0x22a0
leaq -0xf0(%rbp), %rdi
callq 0x2c60
jmp 0x450e
movl -0x70(%rbp), %esi
movl -0x9c(%rbp), %ecx
leaq -0xf0(%rbp), %rdi
leaq -0x98(%rbp), %rdx
callq 0x2b30
jmp 0x452c
movl -0x80c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x80c(%rbp)
jmp 0x45db
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x4566
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x8a0(%rbp), %rdi
callq 0x2170
leaq -0x8a1(%rbp), %rdi
callq 0x22a0
jmp 0x5351
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x8c9(%rbp), %rdi
callq 0x22a0
jmp 0x5351
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x45ba
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x900(%rbp), %rdi
callq 0x2170
leaq -0x901(%rbp), %rdi
callq 0x22a0
jmp 0x5351
movw -0xf4(%rbp), %ax
movw %ax, -0x80e(%rbp)
jmp 0x45e0
jmp 0x4172
movl -0x70(%rbp), %edi
movl -0x9c(%rbp), %edx
leaq -0x98(%rbp), %rsi
callq 0x3430
movl %eax, -0xc34(%rbp)
jmp 0x45fd
movl -0xc34(%rbp), %eax
movl %eax, -0x908(%rbp)
cmpl $0x3, -0x908(%rbp)
jne 0x46f8
movzwl 0x9cc3(%rip), %eax      # 0xe2e0
cmpl $0xd903, %eax           # imm = 0xD903
jne 0x4626
jmp 0x4626
leaq 0x9c43(%rip), %rdi      # 0xe270
leaq 0x9cac(%rip), %rsi      # 0xe2e0
callq 0x5760
movq %rax, -0xc40(%rbp)
jmp 0x4642
movq -0xc40(%rbp), %rdi
callq 0x2c60
jmp 0x4650
leaq 0x9c19(%rip), %rdi      # 0xe270
leaq 0x9c82(%rip), %rsi      # 0xe2e0
callq 0x5760
movq %rax, -0xc48(%rbp)
jmp 0x466c
movq -0xc48(%rbp), %rdi
movl -0x70(%rbp), %esi
movl -0x9c(%rbp), %ecx
leaq -0x98(%rbp), %rdx
callq 0x2b30
jmp 0x468a
callq 0x31e0
movq %rdx, -0xc58(%rbp)
movq %rax, -0xc50(%rbp)
jmp 0x469f
movq -0xc58(%rbp), %rax
movq -0xc50(%rbp), %rcx
movq %rcx, -0x918(%rbp)
movq %rax, -0x910(%rbp)
leaq 0x9be6(%rip), %rdi      # 0xe2a8
leaq 0x9c17(%rip), %rsi      # 0xe2e0
callq 0x5570
movq %rax, -0xc60(%rbp)
jmp 0x46d7
movq -0xc60(%rbp), %rax
movq -0x918(%rbp), %rcx
movq %rcx, (%rax)
movq -0x910(%rbp), %rcx
movq %rcx, 0x8(%rax)
jmp 0x4de0
cmpl $0x2, -0x908(%rbp)
jne 0x49ac
leaq 0x9b64(%rip), %rdi      # 0xe270
leaq 0x9b4f(%rip), %rsi      # 0xe262
callq 0x5730
movq %rax, -0xc68(%rbp)
jmp 0x4721
movq -0xc68(%rbp), %rax
cmpq $0x0, %rax
jne 0x47cf
leaq 0x9b37(%rip), %rax      # 0xe270
movq %rax, -0x920(%rbp)
leaq 0x9b29(%rip), %rdi      # 0xe270
callq 0x5470
movq %rax, -0x928(%rbp)
leaq 0x9b16(%rip), %rdi      # 0xe270
callq 0x54a0
movq %rax, -0x930(%rbp)
leaq -0x928(%rbp), %rdi
leaq -0x930(%rbp), %rsi
callq 0x54d0
testb $0x1, %al
jne 0x477f
jmp 0x47b6
leaq -0x928(%rbp), %rdi
callq 0x5500
movq %rax, %rsi
leaq -0x960(%rbp), %rdi
callq 0x5530
jmp 0x479c
leaq -0x960(%rbp), %rdi
callq 0x55a0
leaq -0x928(%rbp), %rdi
callq 0x55c0
jmp 0x4766
leaq 0x9ab3(%rip), %rdi      # 0xe270
callq 0x57d0
cmpq $0x0, %rax
jne 0x47ca
jmp 0x47ca
jmp 0x3fed
leaq -0x981(%rbp), %rdi
movq %rdi, -0xc70(%rbp)
callq 0x2400
movq -0xc70(%rbp), %rdx
leaq 0x48b6(%rip), %rsi      # 0x90a6
leaq -0x980(%rbp), %rdi
callq 0x2c70
jmp 0x47fe
leaq 0x9a6b(%rip), %rdi      # 0xe270
leaq 0x9a56(%rip), %rsi      # 0xe262
callq 0x5760
movq %rax, -0xc78(%rbp)
jmp 0x481a
movq -0xc78(%rbp), %rax
movzwl (%rax), %esi
cvttsd2si -0x800(%rbp), %edx
movzwl -0xf8(%rbp), %ecx
leaq -0x980(%rbp), %rdi
movl $0x1, %r8d
callq 0x3350
jmp 0x4847
leaq -0x980(%rbp), %rdi
callq 0x2170
leaq -0x981(%rbp), %rdi
callq 0x22a0
leaq 0x9a0a(%rip), %rdi      # 0xe270
leaq 0x99f5(%rip), %rsi      # 0xe262
callq 0x5760
movq %rax, -0xc80(%rbp)
jmp 0x487b
movq -0xc80(%rbp), %rdi
callq 0x2c60
jmp 0x4889
leaq 0x99e0(%rip), %rdi      # 0xe270
leaq 0x99cb(%rip), %rsi      # 0xe262
callq 0x5760
movq %rax, -0xc88(%rbp)
jmp 0x48a5
movq -0xc88(%rbp), %rdi
movl -0x70(%rbp), %esi
movl -0x9c(%rbp), %ecx
leaq -0x98(%rbp), %rdx
callq 0x2b30
jmp 0x48c3
callq 0x31e0
movq %rdx, -0xc98(%rbp)
movq %rax, -0xc90(%rbp)
jmp 0x48d8
movq -0xc98(%rbp), %rax
movq -0xc90(%rbp), %rcx
movq %rcx, -0x998(%rbp)
movq %rax, -0x990(%rbp)
leaq 0x99ad(%rip), %rdi      # 0xe2a8
leaq 0x9960(%rip), %rsi      # 0xe262
callq 0x5570
movq %rax, -0xca0(%rbp)
jmp 0x4910
movq -0xca0(%rbp), %rax
movups -0x998(%rbp), %xmm0
movups %xmm0, (%rax)
movsd -0x800(%rbp), %xmm0
movsd 0x4737(%rip), %xmm1     # 0x9068
mulsd %xmm1, %xmm0
cvttsd2si %xmm0, %eax
movw %ax, -0xf8(%rbp)
movzwl -0xf8(%rbp), %eax
cmpl $0x400, %eax            # imm = 0x400
jge 0x4990
movw $0x400, -0xf8(%rbp)     # imm = 0x400
jmp 0x4990
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x497f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0x980(%rbp), %rdi
callq 0x2170
leaq -0x981(%rbp), %rdi
callq 0x22a0
jmp 0x5351
movsd 0x46c0(%rip), %xmm0     # 0x9058
movsd %xmm0, -0x800(%rbp)
movb $0x1, -0x805(%rbp)
jmp 0x4dde
movzwl 0x98af(%rip), %eax      # 0xe262
movzwl -0x80e(%rbp), %ecx
cmpl %ecx, %eax
jne 0x49c3
jmp 0x4de5
movzwl 0x9898(%rip), %eax      # 0xe262
movzwl 0x9881(%rip), %ecx      # 0xe252
cmpl %ecx, %eax
jne 0x4d27
movw 0x9902(%rip), %ax       # 0xe2e2
addw $0x1, %ax
movw %ax, 0x98f7(%rip)       # 0xe2e2
movzwl 0x98f0(%rip), %eax      # 0xe2e2
cmpl $0x4, %eax
jne 0x4d25
leaq 0x986e(%rip), %rdi      # 0xe270
leaq 0x9859(%rip), %rsi      # 0xe262
callq 0x5730
movq %rax, -0xca8(%rbp)
jmp 0x4a17
movq -0xca8(%rbp), %rax
cmpq $0x0, %rax
jne 0x4ac5
leaq 0x9841(%rip), %rax      # 0xe270
movq %rax, -0x9a0(%rbp)
leaq 0x9833(%rip), %rdi      # 0xe270
callq 0x5470
movq %rax, -0x9a8(%rbp)
leaq 0x9820(%rip), %rdi      # 0xe270
callq 0x54a0
movq %rax, -0x9b0(%rbp)
leaq -0x9a8(%rbp), %rdi
leaq -0x9b0(%rbp), %rsi
callq 0x54d0
testb $0x1, %al
jne 0x4a75
jmp 0x4aac
leaq -0x9a8(%rbp), %rdi
callq 0x5500
movq %rax, %rsi
leaq -0x9e0(%rbp), %rdi
callq 0x5530
jmp 0x4a92
leaq -0x9e0(%rbp), %rdi
callq 0x55a0
leaq -0x9a8(%rbp), %rdi
callq 0x55c0
jmp 0x4a5c
leaq 0x97bd(%rip), %rdi      # 0xe270
callq 0x57d0
cmpq $0x0, %rax
jne 0x4ac0
jmp 0x4ac0
jmp 0x3fed
leaq -0xa01(%rbp), %rdi
movq %rdi, -0xcb0(%rbp)
callq 0x2400
movq -0xcb0(%rbp), %rdx
leaq 0x45c0(%rip), %rsi      # 0x90a6
leaq -0xa00(%rbp), %rdi
callq 0x2c70
jmp 0x4af4
leaq 0x9775(%rip), %rdi      # 0xe270
leaq 0x9760(%rip), %rsi      # 0xe262
callq 0x5760
movq %rax, -0xcb8(%rbp)
jmp 0x4b10
movq -0xcb8(%rbp), %rax
movzwl (%rax), %esi
cvttsd2si -0x800(%rbp), %edx
movzwl -0xf8(%rbp), %ecx
leaq -0xa00(%rbp), %rdi
movl $0x1, %r8d
callq 0x3350
jmp 0x4b3d
leaq -0xa00(%rbp), %rdi
callq 0x2170
leaq -0xa01(%rbp), %rdi
callq 0x22a0
leaq 0x9714(%rip), %rdi      # 0xe270
leaq 0x96ff(%rip), %rsi      # 0xe262
callq 0x5760
movq %rax, -0xcc0(%rbp)
jmp 0x4b71
movq -0xcc0(%rbp), %rdi
callq 0x2c60
jmp 0x4b7f
leaq 0x96ea(%rip), %rdi      # 0xe270
leaq 0x96d5(%rip), %rsi      # 0xe262
callq 0x5760
movq %rax, -0xcc8(%rbp)
jmp 0x4b9b
movq -0xcc8(%rbp), %rdi
movl -0x70(%rbp), %esi
movl -0x9c(%rbp), %ecx
leaq -0x98(%rbp), %rdx
callq 0x2b30
jmp 0x4bb9
callq 0x31e0
movq %rdx, -0xcd8(%rbp)
movq %rax, -0xcd0(%rbp)
jmp 0x4bce
movq -0xcd8(%rbp), %rax
movq -0xcd0(%rbp), %rcx
movq %rcx, -0xa18(%rbp)
movq %rax, -0xa10(%rbp)
leaq 0x96b7(%rip), %rdi      # 0xe2a8
leaq 0x966a(%rip), %rsi      # 0xe262
callq 0x5570
movq %rax, -0xce0(%rbp)
jmp 0x4c06
movq -0xce0(%rbp), %rax
movq -0xa18(%rbp), %rcx
movq %rcx, (%rax)
movq -0xa10(%rbp), %rcx
movq %rcx, 0x8(%rax)
movw $0x0, 0x96b7(%rip)      # 0xe2e2
movsd -0x800(%rbp), %xmm1
movsd 0x4425(%rip), %xmm0     # 0x9060
divsd %xmm0, %xmm1
movsd 0x4411(%rip), %xmm0     # 0x9058
ucomisd %xmm1, %xmm0
jbe 0x4c5f
movsd 0x4403(%rip), %xmm0     # 0x9058
movsd %xmm0, -0xce8(%rbp)
jmp 0x4c7b
movsd -0x800(%rbp), %xmm0
movsd 0x43f1(%rip), %xmm1     # 0x9060
divsd %xmm1, %xmm0
movsd %xmm0, -0xce8(%rbp)
movsd -0xce8(%rbp), %xmm0
cvttsd2si %xmm0, %eax
movw %ax, -0xf8(%rbp)
movzwl -0xf8(%rbp), %eax
movzwl 0x95c8(%rip), %ecx      # 0xe264
cmpl %ecx, %eax
jle 0x4cb0
movw 0x95bd(%rip), %ax       # 0xe264
movw %ax, -0xcea(%rbp)
jmp 0x4cbe
movw -0xf8(%rbp), %ax
movw %ax, -0xcea(%rbp)
movw -0xcea(%rbp), %ax
movzwl %ax, %eax
cvtsi2sd %eax, %xmm0
movsd %xmm0, -0x800(%rbp)
movb $0x0, -0x805(%rbp)
movw 0x9580(%rip), %ax       # 0xe262
movw %ax, 0x9569(%rip)       # 0xe252
jmp 0x3fed
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x4d14
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0xa00(%rbp), %rdi
callq 0x2170
leaq -0xa01(%rbp), %rdi
callq 0x22a0
jmp 0x5351
jmp 0x4d27
movw 0x9534(%rip), %ax       # 0xe262
movw %ax, 0x951d(%rip)       # 0xe252
movzwl 0x9526(%rip), %eax      # 0xe262
movzwl -0xf4(%rbp), %ecx
cmpl %ecx, %eax
jne 0x4d49
jmp 0x4d49
testb $0x1, -0x805(%rbp)
je 0x4d6c
movsd 0x42fe(%rip), %xmm0     # 0x9058
addsd -0x800(%rbp), %xmm0
movsd %xmm0, -0x800(%rbp)
jmp 0x4d90
movsd -0x800(%rbp), %xmm0
movsd 0x42d4(%rip), %xmm1     # 0x9050
divsd -0x800(%rbp), %xmm1
addsd %xmm1, %xmm0
movsd %xmm0, -0x800(%rbp)
movsd -0x800(%rbp), %xmm0
movzwl 0x94c5(%rip), %eax      # 0xe264
cvtsi2sd %eax, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x4dbc
movzwl 0x94b4(%rip), %eax      # 0xe264
cvtsi2sd %eax, %xmm0
movsd %xmm0, -0x800(%rbp)
movsd -0x800(%rbp), %xmm0
movzwl -0xf8(%rbp), %eax
cvtsi2sd %eax, %xmm1
ucomisd %xmm1, %xmm0
jb 0x4ddc
movb $0x0, -0x805(%rbp)
jmp 0x4dde
jmp 0x4de0
jmp 0x3fed
movq $0x0, -0xa28(%rbp)
movq $0x7a120, -0xa20(%rbp) # imm = 0x7A120
movl -0x70(%rbp), %edi
movups -0xa28(%rbp), %xmm0
movaps %xmm0, -0xa40(%rbp)
movq -0xa40(%rbp), %rsi
movq -0xa38(%rbp), %rdx
callq 0x3180
jmp 0x4e21
movb $0x0, -0xa41(%rbp)
movb $0x0, -0xa42(%rbp)
movb $0x0, -0xa43(%rbp)
movb $0x0, -0xa44(%rbp)
movl $0x1d4c0, -0xa48(%rbp)  # imm = 0x1D4C0
cmpl $0x0, -0xa48(%rbp)
jle 0x5307
testb $0x1, -0xa42(%rbp)
jne 0x5027
leaq 0x4281(%rip), %rsi      # 0x90e9
leaq -0x320(%rbp), %rdi
callq 0x2360
jmp 0x4e76
movw $0x0, -0xf6(%rbp)
movw -0xf4(%rbp), %ax
movw %ax, -0xcf0(%rbp)
movw -0xf6(%rbp), %ax
movw %ax, -0xcee(%rbp)
movw 0x93c2(%rip), %ax       # 0xe264
movw %ax, -0xcec(%rbp)
leaq -0xa90(%rbp), %rdi
leaq -0x320(%rbp), %rsi
callq 0x2120
jmp 0x4ebe
movw -0xcec(%rbp), %ax
movw -0xcee(%rbp), %cx
movw -0xcf0(%rbp), %dx
movzwl %dx, %esi
movzwl %cx, %edx
movzwl %ax, %ecx
leaq -0xa70(%rbp), %rdi
leaq -0xa90(%rbp), %r8
callq 0x2660
jmp 0x4ef1
leaq -0xf0(%rbp), %rdi
movq %rdi, -0xcf8(%rbp)
leaq -0xa70(%rbp), %rsi
movq %rsi, -0xd00(%rbp)
callq 0x5650
movq -0xd00(%rbp), %rdi
callq 0x55f0
leaq -0xa90(%rbp), %rdi
callq 0x2170
movq -0xcf8(%rbp), %rdi
movl -0x70(%rbp), %esi
movl -0x9c(%rbp), %ecx
leaq -0x98(%rbp), %rdx
callq 0x2b30
jmp 0x4f48
leaq -0xab1(%rbp), %rdi
movq %rdi, -0xd08(%rbp)
callq 0x2400
movq -0xd08(%rbp), %rdx
leaq 0x4182(%rip), %rsi      # 0x90eb
leaq -0xab0(%rbp), %rdi
callq 0x2c70
jmp 0x4f77
movzwl -0xf4(%rbp), %esi
movzwl -0xf8(%rbp), %ecx
movzbl -0xa43(%rbp), %r8d
andl $0x1, %r8d
leaq -0xab0(%rbp), %rdi
movl $0x400, %edx            # imm = 0x400
callq 0x3350
jmp 0x4fa4
leaq -0xab0(%rbp), %rdi
callq 0x2170
leaq -0xab1(%rbp), %rdi
callq 0x22a0
leaq -0xf0(%rbp), %rdi
callq 0x2c60
jmp 0x4fca
movb $0x1, -0xa43(%rbp)
jmp 0x5027
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0xa90(%rbp), %rdi
callq 0x2170
jmp 0x5351
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x5016
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0xab0(%rbp), %rdi
callq 0x2170
leaq -0xab1(%rbp), %rdi
callq 0x22a0
jmp 0x5351
testb $0x1, -0xa41(%rbp)
je 0x5041
movl -0xa48(%rbp), %eax
subl $0x1f4, %eax            # imm = 0x1F4
movl %eax, -0xa48(%rbp)
movl -0x70(%rbp), %esi
movl -0x9c(%rbp), %ecx
leaq -0xc8(%rbp), %rdi
leaq -0x98(%rbp), %rdx
callq 0x2bb0
movl %eax, -0xd0c(%rbp)
jmp 0x5065
movl -0xd0c(%rbp), %eax
movl %eax, -0xab8(%rbp)
cmpl $0x2, -0xab8(%rbp)
jne 0x507f
jmp 0x4e47
movw -0xc4(%rbp), %ax
movw %ax, 0x91d7(%rip)       # 0xe264
movzwl -0xc2(%rbp), %eax
movl %eax, -0xd10(%rbp)
subl $0x1, %eax
je 0x50cc
jmp 0x50a1
movl -0xd10(%rbp), %eax
subl $0x5, %eax
jne 0x52f2
jmp 0x50b2
movzwl -0xc6(%rbp), %edi
callq 0x3300
jmp 0x50c0
movb $0x1, -0xa42(%rbp)
jmp 0x52f4
movzwl -0xc6(%rbp), %edi
callq 0x3300
jmp 0x50da
leaq 0x3ff9(%rip), %rsi      # 0x90da
leaq -0x320(%rbp), %rdi
callq 0x2360
jmp 0x50ef
movzwl -0xf4(%rbp), %edi
movl $0x1, %esi
callq 0x2fc0
movw %ax, -0xd12(%rbp)
jmp 0x5109
movw -0xd12(%rbp), %ax
movw %ax, -0xf4(%rbp)
movzwl -0xc8(%rbp), %edi
movl $0x1, %esi
callq 0x2fc0
movw %ax, -0xd14(%rbp)
jmp 0x5131
movw -0xd14(%rbp), %ax
movw %ax, -0xf6(%rbp)
movw -0xf4(%rbp), %ax
movw %ax, -0xd1a(%rbp)
movw -0xf6(%rbp), %ax
movw %ax, -0xd18(%rbp)
movw 0x9102(%rip), %ax       # 0xe264
movw %ax, -0xd16(%rbp)
leaq -0xb00(%rbp), %rdi
leaq -0x320(%rbp), %rsi
callq 0x2120
jmp 0x517e
movw -0xd16(%rbp), %ax
movw -0xd18(%rbp), %cx
movw -0xd1a(%rbp), %dx
movzwl %dx, %esi
movzwl %cx, %edx
movzwl %ax, %ecx
leaq -0xae0(%rbp), %rdi
leaq -0xb00(%rbp), %r8
callq 0x2660
jmp 0x51b1
leaq -0xf0(%rbp), %rdi
movq %rdi, -0xd28(%rbp)
leaq -0xae0(%rbp), %rsi
movq %rsi, -0xd30(%rbp)
callq 0x5650
movq -0xd30(%rbp), %rdi
callq 0x55f0
leaq -0xb00(%rbp), %rdi
callq 0x2170
movq -0xd28(%rbp), %rdi
movl -0x70(%rbp), %esi
movl -0x9c(%rbp), %ecx
leaq -0x98(%rbp), %rdx
callq 0x2b30
jmp 0x5208
leaq -0xb21(%rbp), %rdi
movq %rdi, -0xd38(%rbp)
callq 0x2400
movq -0xd38(%rbp), %rdx
leaq 0x3e7d(%rip), %rsi      # 0x90a6
leaq -0xb20(%rbp), %rdi
callq 0x2c70
jmp 0x5237
movzwl -0xf4(%rbp), %esi
movzwl -0xf8(%rbp), %ecx
movzbl -0xa44(%rbp), %r8d
andl $0x1, %r8d
leaq -0xb20(%rbp), %rdi
movl $0x400, %edx            # imm = 0x400
callq 0x3350
jmp 0x5264
leaq -0xb20(%rbp), %rdi
callq 0x2170
leaq -0xb21(%rbp), %rdi
callq 0x22a0
leaq -0xf0(%rbp), %rdi
callq 0x2c60
jmp 0x528a
movb $0x1, -0xa42(%rbp)
movb $0x1, -0xa41(%rbp)
movb $0x1, -0xa44(%rbp)
jmp 0x52f4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0xb00(%rbp), %rdi
callq 0x2170
jmp 0x5351
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
jmp 0x52e4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x40(%rbp)
movl %eax, -0x44(%rbp)
leaq -0xb20(%rbp), %rdi
callq 0x2170
leaq -0xb21(%rbp), %rdi
callq 0x22a0
jmp 0x5351
jmp 0x52f4
leaq -0xc8(%rbp), %rdi
callq 0x2c60
jmp 0x5302
jmp 0x4e47
movl -0x70(%rbp), %edi
callq 0x2430
jmp 0x5311
movl $0x0, -0x4(%rbp)
movl $0x1, -0x74(%rbp)
leaq -0x320(%rbp), %rdi
callq 0x2170
leaq -0x300(%rbp), %rdi
callq 0x20b0
leaq -0xf0(%rbp), %rdi
callq 0x55f0
leaq -0xc8(%rbp), %rdi
callq 0x55f0
jmp 0x5383
leaq -0x320(%rbp), %rdi
callq 0x2170
leaq -0x300(%rbp), %rdi
callq 0x20b0
leaq -0xf0(%rbp), %rdi
callq 0x55f0
leaq -0xc8(%rbp), %rdi
callq 0x55f0
jmp 0x5397
leaq -0x68(%rbp), %rdi
callq 0x2170
leaq -0x30(%rbp), %rdi
callq 0x2170
jmp 0x53ab
leaq -0x68(%rbp), %rdi
callq 0x2170
leaq -0x30(%rbp), %rdi
callq 0x2170
jmp 0x53b7
movl -0x4(%rbp), %eax
addq $0xd40, %rsp            # imm = 0xD40
popq %rbp
retq
movq -0x40(%rbp), %rdi
callq 0x23f0