// File: /workspace/github_c_makefile_star2_O1/qpfiffer[P]38-Moths/src/grengine.c
// Function: m38_generate_response
m38_handled_request *m38_generate_response(const int accept_fd, const m38_app *app) {
	unsigned char *to_read = calloc(1, MAX_READ_LEN);
	char *actual_response = NULL;
	m38_http_response response = {
		.mimetype = {0},
		0
	};
	response.extra_headers = vector_new(sizeof(m38_header_pair *), 4);

	m38_handled_request *hreq = NULL;
	const m38_route *matching_route = NULL;
	size_t num_read = 0;
	int rc = 0;

	rc = read_max_bytes_from_socket(accept_fd, &to_read, &num_read);
	if (rc != 0)
		goto error;

	m38_http_request request = {
		.verb = {0},
		.resource = {0},
		.matches = {{0}},
		.header_len = 0,
		.full_header = NULL,
		.body_len = 0,
		.full_body = NULL
	};

	rc = m38_parse_request(to_read, num_read, &request);
	if (rc != 0) {
		m38_log_msg(LOG_ERR, "Could not parse request.");
		goto error;
	}

	char *clength = m38_get_header_value_raw(request.full_header, request.header_len, "Content-Length");
	size_t clength_num = 0;
	if (clength == NULL) {
		m38_log_msg(LOG_WARN, "Could not parse content length.");
	} else {
		clength_num = atoi(clength);
		free(clength);
	}

	/* Do we have a POST body or something? */
	const size_t post_body_len = num_read - request.header_len;
	if (post_body_len <= 0 && clength_num > 0) {
		/* re-read will just copy into the m38_http_request. */
		rc = attempt_reread_from_socket(accept_fd, clength_num, post_body_len, &request);
		if (rc != 0) {
			m38_log_msg(LOG_ERR, "Could not reread from socket and parse body.");
			goto error;
		}
	} else {
		rc = m38_parse_body(post_body_len, clength_num, to_read, &request);
		if (rc != 0) {
			m38_log_msg(LOG_ERR, "Could not parse body.");
			goto error;
		}
	}

	/* Parses form encoding, if applicable: */
	const char form_encoding[] = "application/x-www-form-urlencoded";
	const size_t form_encoding_siz = strlen(form_encoding);
	char *content_type = m38_get_header_value_request(&request, "Content-Type");

	if (content_type &&
			strlen(content_type) >= form_encoding_siz &&
			strncmp(form_encoding, content_type, form_encoding_siz) == 0) {
		rc = m38_parse_form_encoded_body(&request);
		if (rc != 0) {
			/* application/x-www-form-urlencoded */
			m38_log_msg(LOG_ERR, "Could not parse form-urlencoded body.");
			goto error;
		}
	
	}

	/* Find our matching route: */
	int64_t i;
	for (i = 0; i < app->num_routes; i++) {
		const m38_route *cur_route = &app->routes[i];
		if (strcmp(cur_route->verb, request.verb) != 0)
			continue;

		assert(cur_route->expected_matches < MAX_MATCHES);
		regex_t regex;
		int reti = regcomp(&regex, cur_route->route_match, REG_EXTENDED);
		if (reti != 0) {
			char errbuf[128];
			regerror(reti, &regex, errbuf, sizeof(errbuf));
			m38_log_msg(LOG_ERR, "%s", errbuf);
			assert(reti == 0);
		}

		if (cur_route->expected_matches > 0)
			reti = regexec(&regex, request.resource, cur_route->expected_matches + 1, request.matches, 0);
		else
			reti = regexec(&regex, request.resource, 0, NULL, 0);
		regfree(&regex);
		if (reti == 0) {
			matching_route = &app->routes[i];
			break;
		}
	}

	/* If we didn't find one just use the 404 route: */
	int64_t response_code = 0;
	if (matching_route == NULL) {
		matching_route = &r_404_route;
		response_code = 404;
		if (app->r_404_route) {
			m38_log_msg(LOG_INFO, "Setting custom 404 handler for %s.", matching_route->name);
			matching_route = app->r_404_route;
		} else {
			m38_log_msg(LOG_INFO, "Using internal 404 handler for %s.", matching_route->name);
		}
	} else {
		/* Run the handler through with the data we have: */
		m38_log_msg(LOG_INFO, "Calling handler for %s.", matching_route->name);
		response_code = matching_route->handler(&request, &response);
	}

	/* It doesn't seem like you actually need the response.outsize and .out checks here,
	 * but this makes it so that a view function can return a 404 and the 404 handler will
	 * be called. Very nifty.
	 */
	if (response_code == 404 && (response.outsize == 0 || response.out == NULL)) {
		m38_log_msg(LOG_INFO, "No response gen: Calling 404 handler for %s.", matching_route->name);
		matching_route = &r_404_route;

		if (app->r_404_route) {
			m38_log_msg(LOG_INFO, "Setting custom 404 handler for %s.", matching_route->name);
			matching_route = app->r_404_route;
		} else {
			m38_log_msg(LOG_INFO, "Using internal 404 handler for %s.", matching_route->name);
		}

		if (matching_route->handler) {
			response_code = matching_route->handler(&request, &response);
		} else {
			m38_log_msg(LOG_ERR, "No handler for route %s.", matching_route->name);
		}
	}

	/* Embed the handler's text into the header: */
	size_t header_size = 0;
	size_t actual_response_siz = 0;

	/* Figure out if this thing needs to be partial */
	char *range_header_value = m38_get_header_value_raw(request.full_header, request.header_len, "Range");
	if (range_header_value && RESPONSE_OK(response_code)) {
		response_code = 206;
	}

	/* Figure out what header we need to use: */
	const code_to_message *matched_response = NULL;
	const code_to_message *response_headers = get_response_headers();
	const int64_t num_elements = get_response_headers_num_elements();
	for (i = 0; i < num_elements; i++) {
		code_to_message current_response = response_headers[i];
		if (current_response.code == response_code) {
			matched_response = &response_headers[i];
			break;
		}
	}
	/* Blow up if we don't have that code. We should have them all at
	 * compile time. */
	assert(matched_response != NULL);

	if (response_code == 200 || response_code == 404 || response_code == 301 ||
			response_code == 302 ||response_code == 400 || response_code == 403 ||
			response_code == 500) {
		const size_t integer_length = UINT_LEN(response.outsize);
		if (response.mimetype[0] == '\0')
			memcpy(response.mimetype, "text/html", strlen("text/html"));

		header_size = strlen(response.mimetype) + strlen(matched_response->message)
			+ integer_length - strlen("%s") - strlen("%zu") + strlen(r_final);

		size_t i = 0;
		for (i = 0; i < response.extra_headers->count; i++) {
			m38_header_pair **pair = (m38_header_pair **)vector_get(response.extra_headers, i);
			header_size += (*pair)->header_len + strlen(": ") + (*pair)->value_len
								    + strlen("\r\n");
		}
		actual_response_siz = response.outsize + header_size;
		actual_response = malloc(actual_response_siz + 1);
		memset(actual_response, '\0', actual_response_siz);
		actual_response[actual_response_siz] = '\0';

		/* snprintf the header because it's just a string: */
		snprintf(actual_response, actual_response_siz, matched_response->message, response.mimetype, response.outsize);
		for (i = 0; i < response.extra_headers->count; i++) {
			m38_header_pair **pair = (m38_header_pair **)vector_get(response.extra_headers, i);
			const size_t siz = (*pair)->header_len + strlen(": ") + (*pair)->value_len
								    + strlen("\r\n") + 1;
			char buf[siz];
			buf[siz] = '\0';
			snprintf(buf, actual_response_siz, "%s: %s\r\n", (*pair)->header, (*pair)->value);
			strncat(actual_response, buf, siz);
		}
		strcat(actual_response, r_final);

		/* memcpy the rest because it could be anything: */
		memcpy(actual_response + header_size, response.out, response.outsize);
	} else if (response_code == 206) {
		/* Byte range queries have some extra shit. */
		m38_range_header byte_range = m38_parse_range_header(range_header_value);
		/* TODO: Add the custom header stuff here (for 206), too. */

		m38_log_msg(LOG_INFO, "Range header parsed: Raw: %s Limit: %zu Offset: %zu", range_header_value, byte_range.limit, byte_range.offset);
		free(range_header_value);

		size_t end_byte = 0;
		if (byte_range.limit == 0) {
			end_byte = response.outsize - 1;
		} else {
			end_byte = (response.outsize - byte_range.limit) - 1;
		}

		if (end_byte >= response.outsize)
			end_byte = response.outsize - 1;
		const size_t start_byte = byte_range.offset < response.outsize ? byte_range.offset : 0;
		const size_t max_size = response.outsize; /* Should be the same as file size. */
		const size_t integer_length = UINT_LEN(max_size);

		const size_t minb_len = start_byte == 0 ? 1 : UINT_LEN(start_byte);
		const size_t maxb_len = end_byte == 0 ? 1 : UINT_LEN(end_byte);
		/* Compute the size of the header */
		header_size = strlen(response.mimetype) + strlen(matched_response->message) + strlen(r_final)
			+ integer_length + minb_len + maxb_len + integer_length
			- strlen("%s") - (strlen("%zu") * 4);
		actual_response_siz = max_size + header_size;
		/* malloc the full response */
		actual_response = malloc(actual_response_siz + 1);
		actual_response[actual_response_siz] = '\0';

		/* snprintf the header because it's just a string: */
		snprintf(actual_response, actual_response_siz, matched_response->message,
			response.mimetype, max_size,
			start_byte, end_byte, max_size);
		m38_log_msg(LOG_INFO, "Sending back: Content-Range: %zu-%zu/%zu", start_byte, end_byte, max_size);

		strcat(actual_response, r_final);

		/* memcpy the rest because it could be anything: */
		memcpy(actual_response + header_size, response.out + start_byte, end_byte - start_byte);
	}

	log_request(&request, &response, response_code);

	hreq = malloc(sizeof(m38_handled_request));
	hreq->response_bytes = actual_response;
	hreq->response_len = actual_response_siz;
	hreq->response_code = response_code;
	hreq->accept_fd = accept_fd;
	hreq->sent = 0;
	hreq->matching_route = matching_route;
	memcpy(&hreq->response, &response, sizeof(response));

	free(to_read);
	free(request.full_header);
	free(request.full_body);
	free(request.form_elements);
	return hreq;

error:
	if (matching_route != NULL && matching_route->cleanup != NULL)
		matching_route->cleanup(500, &response);
	free(actual_response);
	free(to_read);
	free(request.full_header);
	free(request.full_body);
	free(request.form_elements);
	return NULL;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x3a8, %rsp            # imm = 0x3A8
movq %rsi, %r15
movl %edi, %r13d
movl $0x1, %edi
movl $0x400, %esi            # imm = 0x400
callq 0x32e0
leaq -0x58(%rbp), %rbx
movq %rax, (%rbx)
xorpd %xmm0, %xmm0
movapd %xmm0, -0x70(%rbp)
movapd %xmm0, -0x80(%rbp)
movapd %xmm0, -0x90(%rbp)
movapd %xmm0, -0xa0(%rbp)
movl $0x8, %edi
movl $0x4, %esi
callq 0x3410
movq %rax, -0x68(%rbp)
leaq -0xb8(%rbp), %rdx
movq $0x0, (%rdx)
movl %r13d, %edi
movq %rbx, %rsi
callq 0x59fa
testl %eax, %eax
jne 0x4f50
leaq -0x350(%rbp), %rbx
movl $0x258, %edx            # imm = 0x258
movq %rbx, %rdi
xorl %esi, %esi
callq 0x3220
movq -0x58(%rbp), %r14
movq -0xb8(%rbp), %r12
movq %r14, %rdi
movq %r12, %rsi
movq %rbx, %rdx
callq 0x3250
testl %eax, %eax
je 0x4f91
leaq 0x52f2(%rip), %rsi      # 0xa236
movl $0x3, %edi
xorl %eax, %eax
callq 0x3540
movq -0x58(%rbp), %rdi
callq 0x3050
xorl %ebx, %ebx
movq -0x120(%rbp), %rdi
callq 0x3050
movq -0x110(%rbp), %rdi
callq 0x3050
movq -0x100(%rbp), %rdi
callq 0x3050
movq %rbx, %rax
leaq -0x28(%rbp), %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl %r13d, -0x3c(%rbp)
movq -0x120(%rbp), %rdi
movq -0x118(%rbp), %rsi
leaq 0x52a5(%rip), %rdx      # 0xa24f
callq 0x3210
testq %rax, %rax
je 0x4fcc
movq %rax, %rbx
movq %rax, %rdi
callq 0x3530
movslq %eax, %r13
movq %rbx, %rdi
callq 0x3050
jmp 0x4fe2
leaq 0x528b(%rip), %rsi      # 0xa25e
xorl %r13d, %r13d
movl $0x2, %edi
xorl %eax, %eax
callq 0x3540
subq -0x118(%rbp), %r12
jne 0x5067
testq %r13, %r13
je 0x5067
xorl %eax, %eax
leaq -0x3d0(%rbp), %rbx
movq %rax, (%rbx)
leaq -0xf8(%rbp), %r14
movq %rax, (%r14)
movl $0x1, %edi
movl $0x400, %esi            # imm = 0x400
callq 0x32e0
movq %rax, (%rbx)
leaq 0x5594(%rip), %rsi      # 0xa5b3
movl $0x2, %edi
movq %r13, %rdx
xorl %ecx, %ecx
xorl %eax, %eax
callq 0x3540
leaq 0x55b3(%rip), %rsi      # 0xa5ea
movl $0x2, %edi
movq %r13, %rdx
xorl %ecx, %ecx
xorl %eax, %eax
callq 0x3540
movl -0x3c(%rbp), %edi
movq %rbx, %rsi
movq %r14, %rdx
callq 0x59fa
movl %eax, %r14d
movq (%rbx), %rdi
testl %eax, %eax
je 0x508c
callq 0x3050
jmp 0x50a1
leaq -0x350(%rbp), %rcx
movq %r12, %rdi
movq %r13, %rsi
movq %r14, %rdx
callq 0x3420
testl %eax, %eax
je 0x50b2
leaq 0x5224(%rip), %rsi      # 0xa2ab
jmp 0x4f44
movq %rdi, -0x110(%rbp)
movq -0xf8(%rbp), %rax
movq %rax, -0x108(%rbp)
testl %r14d, %r14d
je 0x50b2
leaq 0x51d1(%rip), %rsi      # 0xa27e
jmp 0x4f44
leaq 0x5208(%rip), %rsi      # 0xa2c1
leaq -0x350(%rbp), %rdi
callq 0x3040
testq %rax, %rax
je 0x50f7
movq %rax, %rbx
movq %rax, %rdi
callq 0x3150
cmpq $0x21, %rax
jb 0x50f7
leaq 0x556e(%rip), %rdi      # 0xa650
movl $0x21, %edx
movq %rbx, %rsi
callq 0x30b0
testl %eax, %eax
je 0x52bf
cmpl $0x0, 0x18(%r15)
jle 0x51d4
xorl %r12d, %r12d
leaq -0xf8(%rbp), %r14
movq $0x0, -0x30(%rbp)
xorl %r13d, %r13d
movq 0x10(%r15), %rbx
leaq (%rbx,%r12), %rdi
leaq -0x350(%rbp), %rsi
callq 0x32f0
testl %eax, %eax
je 0x5136
xorl %eax, %eax
jmp 0x51b7
cmpq $0x4, 0x150(%rbx,%r12)
jae 0x596a
leaq (%rbx,%r12), %rsi
addq $0x50, %rsi
movq %r14, %rdi
movl $0x1, %edx
callq 0x32c0
testl %eax, %eax
jne 0x5989
movq 0x150(%rbx,%r12), %rdx
testq %rdx, %rdx
je 0x5185
incq %rdx
movq %r14, %rdi
leaq -0x340(%rbp), %rsi
leaq -0x140(%rbp), %rcx
jmp 0x5193
movq %r14, %rdi
leaq -0x340(%rbp), %rsi
xorl %edx, %edx
xorl %ecx, %ecx
xorl %r8d, %r8d
callq 0x3400
movl %eax, %ebx
movq %r14, %rdi
callq 0x3140
testl %ebx, %ebx
sete %al
jne 0x51b7
movq 0x10(%r15), %rcx
addq %r12, %rcx
movq %rcx, -0x30(%rbp)
testb %al, %al
jne 0x51dc
incq %r13
movslq 0x18(%r15), %rax
addq $0x168, %r12            # imm = 0x168
cmpq %rax, %r13
jl 0x5117
jmp 0x51dc
movq $0x0, -0x30(%rbp)
movq -0x30(%rbp), %r13
testq %r13, %r13
je 0x5213
leaq 0x10(%r13), %rdx
leaq 0x51d4(%rip), %rsi      # 0xa3c4
xorl %edi, %edi
xorl %eax, %eax
callq 0x3540
leaq -0x350(%rbp), %rdi
leaq -0xa0(%rbp), %rsi
callq *0x158(%r13)
movslq %eax, %rbx
jmp 0x525a
cmpq $0x0, 0x20(%r15)
je 0x5237
leaq 0x515d(%rip), %rsi      # 0xa37e
leaq 0x9a68(%rip), %rdx      # 0xec90
xorl %edi, %edi
xorl %eax, %eax
callq 0x3540
movq 0x20(%r15), %r13
jmp 0x5255
leaq 0x5163(%rip), %rsi      # 0xa3a1
leaq 0x9a4b(%rip), %rdx      # 0xec90
xorl %edi, %edi
xorl %eax, %eax
callq 0x3540
leaq 0x9a2b(%rip), %r13      # 0xec80
movl $0x194, %ebx            # imm = 0x194
cmpq $0x194, %rbx            # imm = 0x194
jne 0x5335
cmpq $0x0, -0x98(%rbp)
movl $0x194, %ebx            # imm = 0x194
je 0x5284
cmpq $0x0, -0xa0(%rbp)
jne 0x5335
addq $0x10, %r13
leaq 0x514d(%rip), %rsi      # 0xa3dc
xorl %edi, %edi
movq %r13, %rdx
xorl %eax, %eax
callq 0x3540
cmpq $0x0, 0x20(%r15)
je 0x52df
leaq 0x50d5(%rip), %rsi      # 0xa37e
leaq 0x99e0(%rip), %rdx      # 0xec90
xorl %edi, %edi
xorl %eax, %eax
callq 0x3540
movq 0x20(%r15), %r13
jmp 0x52fd
leaq -0x350(%rbp), %rdi
callq 0x3190
testl %eax, %eax
je 0x50f7
leaq 0x4ff4(%rip), %rsi      # 0xa2ce
jmp 0x4f44
leaq 0x50bb(%rip), %rsi      # 0xa3a1
leaq 0x99a3(%rip), %rdx      # 0xec90
xorl %edi, %edi
xorl %eax, %eax
callq 0x3540
leaq 0x9983(%rip), %r13      # 0xec80
movq 0x158(%r13), %rax
testq %rax, %rax
je 0x531e
leaq -0x350(%rbp), %rdi
leaq -0xa0(%rbp), %rsi
callq *%rax
movslq %eax, %rbx
jmp 0x5335
leaq 0x10(%r13), %rdx
leaq 0x50e0(%rip), %rsi      # 0xa409
movl $0x3, %edi
xorl %eax, %eax
callq 0x3540
movq -0x120(%rbp), %rdi
movq -0x118(%rbp), %rsi
leaq 0x50d8(%rip), %rdx      # 0xa422
callq 0x3210
leaq -0xc8(%rbx), %rcx
cmpq $0xc8, %rcx
movl $0xce, %r8d
cmovaeq %rbx, %r8
movq %rax, %r14
testq %rax, %rax
cmoveq %rbx, %r8
xorl %eax, %eax
leaq 0x9886(%rip), %rcx      # 0xec00
xorl %r15d, %r15d
movq %r15, %rdx
leaq (%rcx,%rax), %r15
movslq (%rax,%rcx), %rsi
cmpq %rsi, %r8
cmovneq %rdx, %r15
je 0x539e
leaq 0x10(%rax), %rdx
cmpq $0x70, %rax
movq %rdx, %rax
jne 0x537d
testq %r15, %r15
je 0x59db
xorl %ebx, %ebx
movq $0x0, -0x38(%rbp)
cmpq $0x18f, %r8             # imm = 0x18F
jg 0x5648
leaq -0x12d(%r8), %rax
cmpq $0x2, %rax
jb 0x566d
cmpq $0xc8, %r8
je 0x566d
cmpq $0xce, %r8
jne 0x585f
movq %r8, -0x50(%rbp)
movq %r13, -0x30(%rbp)
movq %r14, %rdi
callq 0x3580
movq %rax, %r12
movq %rdx, %rbx
leaq 0x5044(%rip), %rsi      # 0xa44a
xorl %r13d, %r13d
xorl %edi, %edi
movq %r14, %rdx
movq %rax, %rcx
movq %rbx, %r8
xorl %eax, %eax
callq 0x3540
movq %r14, %rdi
movq %r12, %r14
callq 0x3050
movq -0x98(%rbp), %r12
notq %r14
leaq -0x1(%r12), %rax
addq %r12, %r14
cmovaeq %rax, %r14
cmpq %r12, %rbx
cmovbq %rbx, %r13
movl $0x8, %eax
cmpq $0x1, %r12
jb 0x54a8
movq %r12, %xmm1
punpckldq 0x4c65(%rip), %xmm1 # xmm1 = xmm1[0],mem[0],xmm1[1],mem[1]
subpd 0x4c6d(%rip), %xmm1     # 0xa0d0
movapd %xmm1, %xmm0
unpckhpd %xmm1, %xmm0            # xmm0 = xmm0[1],xmm1[1]
addsd %xmm1, %xmm0
callq 0x3310
callq 0x3520
addsd 0x4c5f(%rip), %xmm0     # 0xa0e0
cvttsd2si %xmm0, %rax
movq %rax, %rcx
subsd 0x4c57(%rip), %xmm0     # 0xa0e8
cvttsd2si %xmm0, %rdx
sarq $0x3f, %rcx
andq %rcx, %rdx
orq %rax, %rdx
leaq 0x6(,%rdx,2), %rax
movq %rax, -0x38(%rbp)
movq %r12, -0xb0(%rbp)
movl $0x1, %r12d
movl $0x1, %ebx
testq %r13, %r13
je 0x5515
movq %r13, %xmm1
punpckldq 0x4bf0(%rip), %xmm1 # xmm1 = xmm1[0],mem[0],xmm1[1],mem[1]
subpd 0x4bf8(%rip), %xmm1     # 0xa0d0
movapd %xmm1, %xmm0
unpckhpd %xmm1, %xmm0            # xmm0 = xmm0[1],xmm1[1]
addsd %xmm1, %xmm0
callq 0x3310
callq 0x3520
addsd 0x4bea(%rip), %xmm0     # 0xa0e0
cvttsd2si %xmm0, %rax
movq %rax, %rcx
sarq $0x3f, %rcx
subsd 0x4bde(%rip), %xmm0     # 0xa0e8
cvttsd2si %xmm0, %rbx
andq %rcx, %rbx
orq %rax, %rbx
movq %r13, -0x48(%rbp)
testq %r14, %r14
je 0x5570
movq %r14, %xmm1
punpckldq 0x4b95(%rip), %xmm1 # xmm1 = xmm1[0],mem[0],xmm1[1],mem[1]
subpd 0x4b9d(%rip), %xmm1     # 0xa0d0
movapd %xmm1, %xmm0
unpckhpd %xmm1, %xmm0            # xmm0 = xmm0[1],xmm1[1]
addsd %xmm1, %xmm0
callq 0x3310
callq 0x3520
addsd 0x4b8f(%rip), %xmm0     # 0xa0e0
cvttsd2si %xmm0, %rax
movq %rax, %rcx
sarq $0x3f, %rcx
subsd 0x4b83(%rip), %xmm0     # 0xa0e8
cvttsd2si %xmm0, %r12
andq %rcx, %r12
orq %rax, %r12
leaq -0x90(%rbp), %rdi
callq 0x3150
movq %rax, -0xa8(%rbp)
movq 0x8(%r15), %rdi
callq 0x3150
movq -0x38(%rbp), %r13
addq %rbx, %r13
addq %r12, %r13
addq -0xa8(%rbp), %r13
addq %rax, %r13
movq -0xb0(%rbp), %r12
leaq (%r12,%r13), %rbx
leaq (%r12,%r13), %rdi
incq %rdi
callq 0x33a0
movb $0x0, (%rax,%rbx)
movq 0x8(%r15), %rdx
movq %rax, %rdi
movq %rbx, -0x38(%rbp)
movq %rbx, %rsi
movq %rax, %rbx
leaq -0x90(%rbp), %rcx
movq %r12, %r8
movq -0x48(%rbp), %r15
movq %r15, %r9
xorl %eax, %eax
pushq %r12
pushq %r14
callq 0x31e0
addq $0x10, %rsp
leaq 0x4e8b(%rip), %rsi      # 0xa47e
xorl %edi, %edi
movq %r15, %rdx
movq %r14, %rcx
movq %r12, %r8
xorl %eax, %eax
callq 0x3540
movq %rbx, %rdi
callq 0x3150
movabsq $0xa0d0a0d736874, %rcx  # imm = 0xA0D0A0D736874
movq %rcx, 0xd(%rbx,%rax)
movapd 0x505c(%rip), %xmm0     # 0xa680
movupd %xmm0, (%rbx,%rax)
addq %rbx, %r13
subq %r15, %r14
leaq -0x90(%rbp), %rax
addq -0x10(%rax), %r15
movq %r13, %rdi
movq %r15, %rsi
movq %r14, %rdx
jmp 0x5852
leaq -0x190(%r8), %rax
cmpq $0x4, %rax
ja 0x5660
movl $0x19, %ecx
btq %rax, %rcx
jb 0x566d
cmpq $0x1f4, %r8             # imm = 0x1F4
jne 0x585f
movq %r8, -0x50(%rbp)
movq %r13, -0x30(%rbp)
movq -0x98(%rbp), %rax
testq %rax, %rax
je 0x56d9
movq %rax, %xmm1
punpckldq 0x4a32(%rip), %xmm1 # xmm1 = xmm1[0],mem[0],xmm1[1],mem[1]
subpd 0x4a3a(%rip), %xmm1     # 0xa0d0
movapd %xmm1, %xmm0
unpckhpd %xmm1, %xmm0            # xmm0 = xmm0[1],xmm1[1]
addsd %xmm1, %xmm0
callq 0x3310
callq 0x3520
addsd 0x4a2c(%rip), %xmm0     # 0xa0e0
cvttsd2si %xmm0, %rax
movq %rax, %rcx
subsd 0x4a24(%rip), %xmm0     # 0xa0e8
cvttsd2si %xmm0, %r13
sarq $0x3f, %rcx
andq %rcx, %r13
orq %rax, %r13
addq $0xf, %r13
jmp 0x56df
movl $0x10, %r13d
leaq -0x90(%rbp), %rdi
cmpb $0x0, (%rdi)
jne 0x56fc
movabsq $0x6d74682f74786574, %rax # imm = 0x6D74682F74786574
movq %rax, (%rdi)
movb $0x6c, 0x8(%rdi)
callq 0x3150
movq %rax, %rbx
movq 0x8(%r15), %rdi
callq 0x3150
addq %rbx, %r13
addq %rax, %r13
movq -0x68(%rbp), %rdi
cmpq $0x0, 0x10(%rdi)
je 0x5746
xorl %ebx, %ebx
movl %ebx, %esi
callq 0x3170
movq (%rax), %rax
movq 0x18(%rax), %rcx
addq 0x8(%rax), %r13
addq %rcx, %r13
addq $0x4, %r13
incq %rbx
movq -0x68(%rbp), %rdi
cmpq 0x10(%rdi), %rbx
jb 0x5720
movq -0x98(%rbp), %rbx
leaq (%rbx,%r13), %r14
leaq (%rbx,%r13), %rdi
incq %rdi
callq 0x33a0
movq %rax, %r12
movq %rax, %rdi
xorl %esi, %esi
movq %r14, %rdx
callq 0x3220
movb $0x0, (%r12,%r14)
movq 0x8(%r15), %rdx
movq %r12, -0x48(%rbp)
movq %r12, %rdi
movq %r14, -0x38(%rbp)
movq %r14, %rsi
leaq -0x90(%rbp), %rcx
movq %rbx, %r8
xorl %eax, %eax
callq 0x31e0
movq -0x68(%rbp), %rdi
cmpq $0x0, 0x10(%rdi)
je 0x5816
xorl %ebx, %ebx
movl %ebx, %esi
callq 0x3170
movq %rsp, %r14
movq (%rax), %rcx
movq 0x8(%rcx), %rdx
movq 0x18(%rcx), %rcx
leaq (%rdx,%rcx), %r15
addq $0x5, %r15
addq %rdx, %rcx
addq $0x14, %rcx
andq $-0x10, %rcx
movq %rsp, %r12
subq %rcx, %r12
movq %r12, %rsp
movb $0x0, (%r12,%r15)
movq (%rax), %rax
movq (%rax), %rcx
movq 0x10(%rax), %r8
movq %r12, %rdi
movq -0x38(%rbp), %rsi
leaq 0x4c51(%rip), %rdx      # 0xa441
xorl %eax, %eax
callq 0x31e0
movq -0x48(%rbp), %rdi
movq %r12, %rsi
movq %r15, %rdx
callq 0x3270
movq %r14, %rsp
incq %rbx
movq -0x68(%rbp), %rdi
cmpq 0x10(%rdi), %rbx
jb 0x57a2
movq -0x48(%rbp), %rbx
movq %rbx, %rdi
callq 0x3150
movabsq $0xa0d0a0d736874, %rcx  # imm = 0xA0D0A0D736874
movq %rcx, 0xd(%rbx,%rax)
movapd 0x4e47(%rip), %xmm0     # 0xa680
movupd %xmm0, (%rbx,%rax)
movq %rbx, %rdi
addq %r13, %rdi
movq -0xa0(%rbp), %rsi
movq -0x98(%rbp), %rdx
callq 0x3350
movq -0x30(%rbp), %r13
movq -0x50(%rbp), %r8
leaq -0x340(%rbp), %r12
movq 0x220(%r12), %rdi
movq 0x228(%r12), %rsi
leaq 0x4d90(%rip), %rdx      # 0xa60d
movq %r8, %r15
callq 0x3210
movq %rax, %r14
movq 0x220(%r12), %rdi
movq 0x228(%r12), %rsi
leaq 0x4d78(%rip), %rdx      # 0xa617
callq 0x3210
movq %rbx, %r12
movq %rax, %rbx
testq %r14, %r14
leaq 0x4d84(%rip), %rdx      # 0xa638
cmovneq %r14, %rdx
testq %rax, %rax
leaq 0x4d7b(%rip), %r10      # 0xa63d
cmovneq %rax, %r10
leaq 0x4d55(%rip), %rsi      # 0xa622
leaq -0x350(%rbp), %rcx
movl $0x4, %edi
leaq -0x340(%rbp), %r8
movl %r15d, %r9d
xorl %eax, %eax
pushq %r10
pushq -0x98(%rbp)
callq 0x3540
addq $0x10, %rsp
movq %r14, %rdi
callq 0x3050
movq %rbx, %rdi
callq 0x3050
movl $0x68, %edi
callq 0x33a0
movq %rax, %rbx
movq %r12, (%rax)
movq -0x38(%rbp), %rax
movq %rax, 0x8(%rbx)
movl %r15d, 0x14(%rbx)
movl -0x3c(%rbp), %eax
movl %eax, 0x10(%rbx)
movq $0x0, 0x18(%rbx)
movq %r13, 0x20(%rbx)
movapd -0xa0(%rbp), %xmm0
movaps -0x90(%rbp), %xmm1
movaps -0x80(%rbp), %xmm2
movaps -0x70(%rbp), %xmm3
movupd %xmm0, 0x28(%rbx)
movups %xmm1, 0x38(%rbx)
movups %xmm2, 0x48(%rbx)
movups %xmm3, 0x58(%rbx)
movq -0x58(%rbp), %rdi
callq 0x3050
jmp 0x4f5b
leaq 0x4983(%rip), %rdi      # 0xa2f4
leaq 0x49a6(%rip), %rsi      # 0xa31e
leaq 0x49ae(%rip), %rcx      # 0xa32d
movl $0x1cb, %edx            # imm = 0x1CB
callq 0x3200
leaq -0xf8(%rbp), %rsi
leaq -0x3d0(%rbp), %rbx
movl $0x80, %ecx
movl %eax, %edi
movq %rbx, %rdx
callq 0x3360
leaq 0x4bc7(%rip), %rsi      # 0xa574
movl $0x3, %edi
movq %rbx, %rdx
xorl %eax, %eax
callq 0x3540
leaq 0x49b1(%rip), %rdi      # 0xa374
leaq 0x4954(%rip), %rsi      # 0xa31e
leaq 0x495c(%rip), %rcx      # 0xa32d
movl $0x1d2, %edx            # imm = 0x1D2
callq 0x3200
leaq 0x4a46(%rip), %rdi      # 0xa428
leaq 0x4935(%rip), %rsi      # 0xa31e
leaq 0x493d(%rip), %rcx      # 0xa32d
movl $0x21e, %edx            # imm = 0x21E
callq 0x3200