// File: gersteinlab[P]MUSIC/src/ms_min_max_utils.cpp
// Function: get_extrema_per_plateaus(double*, int, std::vector<t_extrema_node*, std::allocator<t_extrema_node*>>*, std::vector<t_extrema_node*, std::allocator<t_extrema_node*>>*, int*, int, double)
void get_extrema_per_plateaus(double* data, int l_signal,
	vector<t_extrema_node*>* maxes, 
	vector<t_extrema_node*>* mins,
	int* derivative_sign_map,
	int i_scale,
	double zero_deriv)
{
	vector<t_extrema_node*>* extrema_nodes = new vector<t_extrema_node*>();

	double* deriv = new double[l_signal + 2];
	//vector<int>* plateau_locs = new vector<int>();
	//// Following can be implemented with 
	//deriv[0] = 0;
	//for(int i = 1; i < l_signal; i++)
	//{
	//	deriv[i] = data[i] - data[i-1];

	//	if(fabs(deriv[i]) < zero_deriv)
	//	{
	//		//fprintf(stderr, "Pleateau loc: %d\n", i);
	//		plateau_locs->push_back(i);
	//	}
	//	else
	//	{
	//	}
	//} // i loop.

	//// Form the plateau signal.
	//vector<t_plateau*>* plateaus = new vector<t_plateau*>();

	//int* plateau_signal = new int[l_signal];
	//memset(plateau_signal, 0, sizeof(int) * l_signal);
	//int n_pl_pts = (int)plateau_locs->size(); 
	//int i = 0; 
	//while(i < n_pl_pts)
	//{
	//	int cur_start = plateau_locs->at(i);
	//	int cur_end = plateau_locs->at(i);

	//	while(i+1 < n_pl_pts &&
	//		plateau_locs->at(i+1) == plateau_locs->at(i)+1)
	//	{			
	//		cur_end = plateau_locs->at(i+1);

	//		i++;
	//	} // plateau finder loop.

	//	i++;

	//	t_plateau* new_plateau = new t_plateau();
	//	new_plateau->start = cur_start;
	//	new_plateau->end = cur_end;
	//	//fprintf(stderr, "Pleateau: %d-%d\n", cur_start, cur_end);

	//	plateaus->push_back(new_plateau);
	//} // i loop.	

	deriv[0] = 0;
	for(int i = 1; i <= l_signal; i++)
	{
			deriv[i] = data[i] - data[i-1];
	} // i loop.

	vector<t_plateau*>* plateaus = new vector<t_plateau*>();

	int i = 1;
	int cur_start = -1;
	int cur_end = -1;
	while(i <= l_signal)
	{
		// Are we starting a new plateau here?
		if(fabs(deriv[i]) < zero_deriv)
		{
			// Plateau: Get the beginning and the end.
			cur_start = i;
			cur_end = i;
			while(i <= l_signal &&
					fabs(deriv[i]) < zero_deriv)
			{
				cur_end = i;
				i++;
			} // i loop.

			t_plateau* new_plateau = new t_plateau();
			new_plateau->start = cur_start;
			new_plateau->end = cur_end;
			plateaus->push_back(new_plateau);
		}
		else
		{
			i++;
		}
	} // i loop.

	// Go over all the plateaus and set the max/min ver plateau.
	int l_win = 1;
	for(int i_pl = 0; i_pl < (int)plateaus->size(); i_pl++)
	{
		if(plateaus->at(i_pl)->start > l_win &&
			plateaus->at(i_pl)->end+l_win < l_signal &&
			deriv[plateaus->at(i_pl)->start-l_win] > 0 &&
			deriv[plateaus->at(i_pl)->end+l_win] < 0)
		{
			t_extrema_node* new_ext_node = new t_extrema_node();
			new_ext_node->extrema_posn = (plateaus->at(i_pl)->start + plateaus->at(i_pl)->end) / 2;
			new_ext_node->extrema_type = EXTREMA_MAX;
			new_ext_node->higher_node = NULL;
			new_ext_node->lower_node = NULL;
			new_ext_node->scale = i_scale;
			new_ext_node->height_at_extrema = data[new_ext_node->extrema_posn];
			extrema_nodes->push_back(new_ext_node);
			//fprintf(stderr, "Adding max\n");
			//p2n->push_back((plateaus->at(i_pl)->start + plateaus->at(i_pl)->end) / 2);
		}

		if(plateaus->at(i_pl)->start > l_win &&
			plateaus->at(i_pl)->end+l_win < l_signal &&
			deriv[plateaus->at(i_pl)->start-l_win] < 0 &&
			deriv[plateaus->at(i_pl)->end+l_win] > 0)
		{
			t_extrema_node* new_ext_node = new t_extrema_node();
			new_ext_node->extrema_posn = (plateaus->at(i_pl)->start + plateaus->at(i_pl)->end) / 2;
			new_ext_node->extrema_type = EXTREMA_MIN;
			new_ext_node->higher_node = NULL;
			new_ext_node->lower_node = NULL;
			new_ext_node->scale = i_scale;
			new_ext_node->height_at_extrema = data[new_ext_node->extrema_posn];
			extrema_nodes->push_back(new_ext_node);
			//fprintf(stderr, "Adding max\n");
			//n2p->push_back((plateaus->at(i_pl)->start + plateaus->at(i_pl)->end) / 2);
		}
	} // i_pl loop.

	// Add the sudden changes.
	for(int i = 1; i < l_signal; i++)
	{
		if(i+1 < l_signal)
		{
			if(deriv[i] > zero_deriv &&
				deriv[i+1] < -1 * zero_deriv)
			{
				t_extrema_node* new_ext_node = new t_extrema_node();
				new_ext_node->extrema_posn = i;
				new_ext_node->extrema_type = EXTREMA_MAX;
				new_ext_node->higher_node = NULL;
				new_ext_node->lower_node = NULL;
				new_ext_node->scale = i_scale;
				new_ext_node->height_at_extrema = data[new_ext_node->extrema_posn];
				extrema_nodes->push_back(new_ext_node);
				//p2n->push_back(i);
			}

			if(deriv[i] < -1 * zero_deriv &&
				deriv[i+1] > zero_deriv)
			{
				t_extrema_node* new_ext_node = new t_extrema_node();
				new_ext_node->extrema_posn = i;
				new_ext_node->extrema_type = EXTREMA_MIN;
				new_ext_node->higher_node = NULL;
				new_ext_node->lower_node = NULL;
				new_ext_node->scale = i_scale;
				new_ext_node->height_at_extrema = data[new_ext_node->extrema_posn];
				extrema_nodes->push_back(new_ext_node);
				//n2p->push_back(i);
			}
		}
	} // i loop.

	if((int)extrema_nodes->size() == 0 ||
		(int)extrema_nodes->size() == 1)
	{
if(__DUMP_MIN_MAX_UTILS_MSGS__)
{
		fprintf(stderr, "Found %d extrema.\n", (int)extrema_nodes->size());
}
		return;
	}

	sort(extrema_nodes->begin(), extrema_nodes->end(), sort_extremas_per_posn);

	t_extrema_node* begin_ext_node = new t_extrema_node();
	begin_ext_node->extrema_posn = 0;
	begin_ext_node->extrema_type = EXTREMA_MIN;
	begin_ext_node->higher_node = NULL;
	begin_ext_node->lower_node = NULL;
	begin_ext_node->scale = i_scale;
	begin_ext_node->height_at_extrema = data[begin_ext_node->extrema_posn];

	t_extrema_node* end_ext_node = new t_extrema_node();
	end_ext_node->extrema_posn = l_signal-1;
	end_ext_node->extrema_type = EXTREMA_MIN;
	end_ext_node->higher_node = NULL;
	end_ext_node->lower_node = NULL;
	end_ext_node->scale = i_scale;
	end_ext_node->height_at_extrema = data[end_ext_node->extrema_posn];

	if(extrema_nodes->at(0)->extrema_type == EXTREMA_MAX)
	{
		begin_ext_node->extrema_type = EXTREMA_MIN;
	}
	else
	{
		begin_ext_node->extrema_type = EXTREMA_MAX;
	}

	if(extrema_nodes->back()->extrema_type == EXTREMA_MAX)
	{
		end_ext_node->extrema_type = EXTREMA_MIN;
	}
	else
	{
		end_ext_node->extrema_type = EXTREMA_MAX;
	}

	extrema_nodes->push_back(begin_ext_node);
	extrema_nodes->push_back(end_ext_node);

	sort(extrema_nodes->begin(), extrema_nodes->end(), sort_extremas_per_posn);

	// Set the derivative map.
	int i_cur_nuc = 0;
	for(int i_ext = 0; i_ext < (int)extrema_nodes->size(); i_ext++)
	{
		if(i_ext > 0 &&
			extrema_nodes->at(i_ext-1)->extrema_type == extrema_nodes->at(i_ext)->extrema_type)
		{
			fprintf(stderr, "Consecutive same extrema: %d, %d: %d\n", 
				extrema_nodes->at(i_ext-1)->extrema_posn, 
				extrema_nodes->at(i_ext)->extrema_posn, 
				extrema_nodes->at(i_ext)->extrema_type);
			exit(0);
		}

		int der_val = 0;
		if(extrema_nodes->at(i_ext)->extrema_type == EXTREMA_MAX)
		{
			der_val = 1;
		}
		else
		{
			der_val = -1;
		}

		for(int i_nuc = i_cur_nuc; i_nuc <= extrema_nodes->at(i_ext)->extrema_posn-1; i_nuc++)
		{
			derivative_sign_map[i_nuc] = der_val;
		} // i_nuc loop.

		derivative_sign_map[extrema_nodes->at(i_ext)->extrema_posn] = 0;
		i_cur_nuc = extrema_nodes->at(i_ext)->extrema_posn+1;
		//cur_type = extrema_nodes->at(i_ext)->extrema_type;
	} // i_ext loop.

if(__DUMP_MIN_MAX_UTILS_MSGS__)
{
	fprintf(stderr, "Found %d extrema.\n", (int)extrema_nodes->size());
}
	//for(int i = 0; i < 20; i++)
	//{
	//	fprintf(stderr, "%d: %d\n", extrema_nodes->at(i)->extrema_posn, extrema_nodes->at(i)->extrema_type);
	//}

	for(int i = 0; i < (int)extrema_nodes->size(); i++)
	{
		if(extrema_nodes->at(i)->extrema_type == EXTREMA_MAX)
		{
			maxes->push_back(extrema_nodes->at(i));
		}
		else
		{
			mins->push_back(extrema_nodes->at(i));
		}
	} // i loop.

	// Free memory. These are pretty large chunks of memory.
	delete [] deriv;
	//delete [] plateau_signal;
	for(int i_p = 0; i_p < (int)plateaus->size(); i_p++)
	{
		delete(plateaus->at(i_p));
	} // i_p loop.
	//delete plateau_locs;
}

// Assembly:
subq $0x1d8, %rsp            # imm = 0x1D8
movq %rdi, 0x1d0(%rsp)
movl %esi, 0x1cc(%rsp)
movq %rdx, 0x1c0(%rsp)
movq %rcx, 0x1b8(%rsp)
movq %r8, 0x1b0(%rsp)
movl %r9d, 0x1ac(%rsp)
movsd %xmm0, 0x1a0(%rsp)
movl $0x18, %edi
callq 0x2190
movq %rax, %rdi
movq %rdi, 0xe8(%rsp)
xorl %esi, %esi
movl $0x18, %edx
callq 0x2110
movq 0xe8(%rsp), %rdi
callq 0x1ae90
movq 0xe8(%rsp), %rax
movq %rax, 0x198(%rsp)
movl 0x1cc(%rsp), %eax
addl $0x2, %eax
cltq
movl $0x8, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
callq 0x2040
movq %rax, 0x190(%rsp)
movq 0x190(%rsp), %rax
xorps %xmm0, %xmm0
movsd %xmm0, (%rax)
movl $0x1, 0x18c(%rsp)
movl 0x18c(%rsp), %eax
cmpl 0x1cc(%rsp), %eax
jg 0x40b43
movq 0x1d0(%rsp), %rax
movslq 0x18c(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
movq 0x1d0(%rsp), %rax
movl 0x18c(%rsp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
subsd (%rax,%rcx,8), %xmm0
movq 0x190(%rsp), %rax
movslq 0x18c(%rsp), %rcx
movsd %xmm0, (%rax,%rcx,8)
movl 0x18c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x18c(%rsp)
jmp 0x40adc
movl $0x18, %edi
callq 0x2190
movq %rax, %rdi
movq %rdi, 0xe0(%rsp)
xorl %esi, %esi
movl $0x18, %edx
callq 0x2110
movq 0xe0(%rsp), %rdi
callq 0x41da0
movq 0xe0(%rsp), %rax
movq %rax, 0x180(%rsp)
movl $0x1, 0x17c(%rsp)
movl $0xffffffff, 0x178(%rsp) # imm = 0xFFFFFFFF
movl $0xffffffff, 0x174(%rsp) # imm = 0xFFFFFFFF
movl 0x17c(%rsp), %eax
cmpl 0x1cc(%rsp), %eax
jg 0x40d04
movq 0x190(%rsp), %rax
movslq 0x17c(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm1
movaps 0x141be(%rip), %xmm0    # 0x54d90
pand %xmm0, %xmm1
movsd 0x1a0(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x40cee
movl 0x17c(%rsp), %eax
movl %eax, 0x178(%rsp)
movl 0x17c(%rsp), %eax
movl %eax, 0x174(%rsp)
movl 0x17c(%rsp), %ecx
xorl %eax, %eax
cmpl 0x1cc(%rsp), %ecx
movb %al, 0xdf(%rsp)
jg 0x40c55
movq 0x190(%rsp), %rax
movslq 0x17c(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm1
movaps 0x14156(%rip), %xmm0    # 0x54d90
pand %xmm0, %xmm1
movsd 0x1a0(%rsp), %xmm0
ucomisd %xmm1, %xmm0
seta %al
movb %al, 0xdf(%rsp)
movb 0xdf(%rsp), %al
testb $0x1, %al
jne 0x40c62
jmp 0x40c83
movl 0x17c(%rsp), %eax
movl %eax, 0x174(%rsp)
movl 0x17c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x17c(%rsp)
jmp 0x40c05
movl $0x8, %edi
callq 0x2190
movq %rax, %rdi
movq %rdi, 0xd0(%rsp)
xorl %esi, %esi
movl $0x8, %edx
callq 0x2110
movq 0xd0(%rsp), %rax
movq %rax, 0x168(%rsp)
movl 0x178(%rsp), %ecx
movq 0x168(%rsp), %rax
movl %ecx, (%rax)
movl 0x174(%rsp), %ecx
movq 0x168(%rsp), %rax
movl %ecx, 0x4(%rax)
movq 0x180(%rsp), %rdi
leaq 0x168(%rsp), %rsi
callq 0x41db0
jmp 0x40cff
movl 0x17c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x17c(%rsp)
jmp 0x40ba2
movl $0x1, 0x164(%rsp)
movl $0x0, 0x160(%rsp)
movl 0x160(%rsp), %eax
movl %eax, 0xcc(%rsp)
movq 0x180(%rsp), %rdi
callq 0x41e20
movq %rax, %rcx
movl 0xcc(%rsp), %eax
cmpl %ecx, %eax
jge 0x41155
movq 0x180(%rsp), %rdi
movslq 0x160(%rsp), %rsi
callq 0x41e40
movq (%rax), %rax
movl (%rax), %eax
cmpl 0x164(%rsp), %eax
jle 0x40f42
movq 0x180(%rsp), %rdi
movslq 0x160(%rsp), %rsi
callq 0x41e40
movq (%rax), %rax
movl 0x4(%rax), %eax
addl 0x164(%rsp), %eax
cmpl 0x1cc(%rsp), %eax
jge 0x40f42
movq 0x190(%rsp), %rax
movq %rax, 0xc0(%rsp)
movq 0x180(%rsp), %rdi
movslq 0x160(%rsp), %rsi
callq 0x41e40
movq %rax, %rcx
movq 0xc0(%rsp), %rax
movq (%rcx), %rcx
movl (%rcx), %ecx
subl 0x164(%rsp), %ecx
movslq %ecx, %rcx
movsd (%rax,%rcx,8), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x40f42
movq 0x190(%rsp), %rax
movq %rax, 0xb8(%rsp)
movq 0x180(%rsp), %rdi
movslq 0x160(%rsp), %rsi
callq 0x41e40
movq %rax, %rcx
movq 0xb8(%rsp), %rax
movq (%rcx), %rcx
movl 0x4(%rcx), %ecx
addl 0x164(%rsp), %ecx
movslq %ecx, %rcx
xorps %xmm0, %xmm0
ucomisd (%rax,%rcx,8), %xmm0
jbe 0x40f42
movl $0x30, %edi
callq 0x2190
movq %rax, %rdi
movq %rdi, 0xa8(%rsp)
xorl %esi, %esi
movl $0x30, %edx
callq 0x2110
movq 0xa8(%rsp), %rax
movq %rax, 0x158(%rsp)
movq 0x180(%rsp), %rdi
movslq 0x160(%rsp), %rsi
callq 0x41e40
movq (%rax), %rax
movl (%rax), %eax
movl %eax, 0xb4(%rsp)
movq 0x180(%rsp), %rdi
movslq 0x160(%rsp), %rsi
callq 0x41e40
movq %rax, %rcx
movl 0xb4(%rsp), %eax
movq (%rcx), %rcx
addl 0x4(%rcx), %eax
movl $0x2, %ecx
cltd
idivl %ecx
movl %eax, %ecx
movq 0x158(%rsp), %rax
movl %ecx, (%rax)
movq 0x158(%rsp), %rax
movl $0x0, 0x4(%rax)
movq 0x158(%rsp), %rax
movq $0x0, 0x18(%rax)
movq 0x158(%rsp), %rax
movq $0x0, 0x10(%rax)
movl 0x1ac(%rsp), %ecx
movq 0x158(%rsp), %rax
movl %ecx, 0x8(%rax)
movq 0x1d0(%rsp), %rax
movq 0x158(%rsp), %rcx
movslq (%rcx), %rcx
movsd (%rax,%rcx,8), %xmm0
movq 0x158(%rsp), %rax
movsd %xmm0, 0x20(%rax)
movq 0x198(%rsp), %rdi
leaq 0x158(%rsp), %rsi
callq 0x41cf0
movq 0x180(%rsp), %rdi
movslq 0x160(%rsp), %rsi
callq 0x41e40
movq (%rax), %rax
movl (%rax), %eax
cmpl 0x164(%rsp), %eax
jle 0x4113d
movq 0x180(%rsp), %rdi
movslq 0x160(%rsp), %rsi
callq 0x41e40
movq (%rax), %rax
movl 0x4(%rax), %eax
addl 0x164(%rsp), %eax
cmpl 0x1cc(%rsp), %eax
jge 0x4113d
movq 0x190(%rsp), %rax
movq %rax, 0xa0(%rsp)
movq 0x180(%rsp), %rdi
movslq 0x160(%rsp), %rsi
callq 0x41e40
movq %rax, %rcx
movq 0xa0(%rsp), %rax
movq (%rcx), %rcx
movl (%rcx), %ecx
subl 0x164(%rsp), %ecx
movslq %ecx, %rcx
xorps %xmm0, %xmm0
ucomisd (%rax,%rcx,8), %xmm0
jbe 0x4113d
movq 0x190(%rsp), %rax
movq %rax, 0x98(%rsp)
movq 0x180(%rsp), %rdi
movslq 0x160(%rsp), %rsi
callq 0x41e40
movq %rax, %rcx
movq 0x98(%rsp), %rax
movq (%rcx), %rcx
movl 0x4(%rcx), %ecx
addl 0x164(%rsp), %ecx
movslq %ecx, %rcx
movsd (%rax,%rcx,8), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x4113d
movl $0x30, %edi
callq 0x2190
movq %rax, %rdi
movq %rdi, 0x88(%rsp)
xorl %esi, %esi
movl $0x30, %edx
callq 0x2110
movq 0x88(%rsp), %rax
movq %rax, 0x150(%rsp)
movq 0x180(%rsp), %rdi
movslq 0x160(%rsp), %rsi
callq 0x41e40
movq (%rax), %rax
movl (%rax), %eax
movl %eax, 0x94(%rsp)
movq 0x180(%rsp), %rdi
movslq 0x160(%rsp), %rsi
callq 0x41e40
movq %rax, %rcx
movl 0x94(%rsp), %eax
movq (%rcx), %rcx
addl 0x4(%rcx), %eax
movl $0x2, %ecx
cltd
idivl %ecx
movl %eax, %ecx
movq 0x150(%rsp), %rax
movl %ecx, (%rax)
movq 0x150(%rsp), %rax
movl $0x1, 0x4(%rax)
movq 0x150(%rsp), %rax
movq $0x0, 0x18(%rax)
movq 0x150(%rsp), %rax
movq $0x0, 0x10(%rax)
movl 0x1ac(%rsp), %ecx
movq 0x150(%rsp), %rax
movl %ecx, 0x8(%rax)
movq 0x1d0(%rsp), %rax
movq 0x150(%rsp), %rcx
movslq (%rcx), %rcx
movsd (%rax,%rcx,8), %xmm0
movq 0x150(%rsp), %rax
movsd %xmm0, 0x20(%rax)
movq 0x198(%rsp), %rdi
leaq 0x150(%rsp), %rsi
callq 0x41cf0
jmp 0x4113f
movl 0x160(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x160(%rsp)
jmp 0x40d1a
movl $0x1, 0x14c(%rsp)
movl 0x14c(%rsp), %eax
cmpl 0x1cc(%rsp), %eax
jge 0x413cb
movl 0x14c(%rsp), %eax
addl $0x1, %eax
cmpl 0x1cc(%rsp), %eax
jge 0x413b3
movq 0x190(%rsp), %rax
movslq 0x14c(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
ucomisd 0x1a0(%rsp), %xmm0
jbe 0x412a1
movq 0x190(%rsp), %rax
movl 0x14c(%rsp), %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
movsd (%rax,%rcx,8), %xmm1
movsd 0x10e87(%rip), %xmm0    # 0x52058
mulsd 0x1a0(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x412a1
movl $0x30, %edi
callq 0x2190
movq %rax, %rdi
movq %rdi, 0x80(%rsp)
xorl %esi, %esi
movl $0x30, %edx
callq 0x2110
movq 0x80(%rsp), %rax
movq %rax, 0x140(%rsp)
movl 0x14c(%rsp), %ecx
movq 0x140(%rsp), %rax
movl %ecx, (%rax)
movq 0x140(%rsp), %rax
movl $0x0, 0x4(%rax)
movq 0x140(%rsp), %rax
movq $0x0, 0x18(%rax)
movq 0x140(%rsp), %rax
movq $0x0, 0x10(%rax)
movl 0x1ac(%rsp), %ecx
movq 0x140(%rsp), %rax
movl %ecx, 0x8(%rax)
movq 0x1d0(%rsp), %rax
movq 0x140(%rsp), %rcx
movslq (%rcx), %rcx
movsd (%rax,%rcx,8), %xmm0
movq 0x140(%rsp), %rax
movsd %xmm0, 0x20(%rax)
movq 0x198(%rsp), %rdi
leaq 0x140(%rsp), %rsi
callq 0x41cf0
movq 0x190(%rsp), %rax
movslq 0x14c(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm1
movsd 0x10d9a(%rip), %xmm0    # 0x52058
mulsd 0x1a0(%rsp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x413b1
movq 0x190(%rsp), %rax
movl 0x14c(%rsp), %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
movsd (%rax,%rcx,8), %xmm0
ucomisd 0x1a0(%rsp), %xmm0
jbe 0x413b1
movl $0x30, %edi
callq 0x2190
movq %rax, %rdi
movq %rdi, 0x78(%rsp)
xorl %esi, %esi
movl $0x30, %edx
callq 0x2110
movq 0x78(%rsp), %rax
movq %rax, 0x138(%rsp)
movl 0x14c(%rsp), %ecx
movq 0x138(%rsp), %rax
movl %ecx, (%rax)
movq 0x138(%rsp), %rax
movl $0x1, 0x4(%rax)
movq 0x138(%rsp), %rax
movq $0x0, 0x18(%rax)
movq 0x138(%rsp), %rax
movq $0x0, 0x10(%rax)
movl 0x1ac(%rsp), %ecx
movq 0x138(%rsp), %rax
movl %ecx, 0x8(%rax)
movq 0x1d0(%rsp), %rax
movq 0x138(%rsp), %rcx
movslq (%rcx), %rcx
movsd (%rax,%rcx,8), %xmm0
movq 0x138(%rsp), %rax
movsd %xmm0, 0x20(%rax)
movq 0x198(%rsp), %rdi
leaq 0x138(%rsp), %rsi
callq 0x41cf0
jmp 0x413b3
jmp 0x413b5
movl 0x14c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x14c(%rsp)
jmp 0x41160
movq 0x198(%rsp), %rdi
callq 0x1aea0
cmpl $0x0, %eax
je 0x413ef
movq 0x198(%rsp), %rdi
callq 0x1aea0
cmpl $0x1, %eax
jne 0x4142e
testb $0x1, 0x23ded(%rip)     # 0x651e3
je 0x41429
movq 0x23be1(%rip), %rax     # 0x64fe0
movq (%rax), %rax
movq %rax, 0x70(%rsp)
movq 0x198(%rsp), %rdi
callq 0x1aea0
movq 0x70(%rsp), %rdi
movl %eax, %edx
leaq 0x15584(%rip), %rsi     # 0x569a6
movb $0x0, %al
callq 0x2250
jmp 0x41a6f
movq 0x198(%rsp), %rdi
callq 0x1af10
movq %rax, 0x130(%rsp)
movq 0x198(%rsp), %rdi
callq 0x1af40
movq %rax, 0x128(%rsp)
movq 0x130(%rsp), %rdi
movq 0x128(%rsp), %rsi
leaq -0xb0f(%rip), %rdx      # 0x40960
callq 0x1aec0
movl $0x30, %edi
callq 0x2190
movq %rax, %rdi
movq %rdi, 0x60(%rsp)
xorl %esi, %esi
movl $0x30, %edx
callq 0x2110
movq 0x60(%rsp), %rax
movq %rax, 0x120(%rsp)
movq 0x120(%rsp), %rax
movl $0x0, (%rax)
movq 0x120(%rsp), %rax
movl $0x1, 0x4(%rax)
movq 0x120(%rsp), %rax
movq $0x0, 0x18(%rax)
movq 0x120(%rsp), %rax
movq $0x0, 0x10(%rax)
movl 0x1ac(%rsp), %ecx
movq 0x120(%rsp), %rax
movl %ecx, 0x8(%rax)
movq 0x1d0(%rsp), %rax
movq 0x120(%rsp), %rcx
movslq (%rcx), %rcx
movsd (%rax,%rcx,8), %xmm0
movq 0x120(%rsp), %rax
movsd %xmm0, 0x20(%rax)
movl $0x30, %edi
callq 0x2190
movq %rax, %rdi
movq %rdi, 0x68(%rsp)
xorl %esi, %esi
movl $0x30, %edx
callq 0x2110
movq 0x68(%rsp), %rax
movq %rax, 0x118(%rsp)
movl 0x1cc(%rsp), %ecx
subl $0x1, %ecx
movq 0x118(%rsp), %rax
movl %ecx, (%rax)
movq 0x118(%rsp), %rax
movl $0x1, 0x4(%rax)
movq 0x118(%rsp), %rax
movq $0x0, 0x18(%rax)
movq 0x118(%rsp), %rax
movq $0x0, 0x10(%rax)
movl 0x1ac(%rsp), %ecx
movq 0x118(%rsp), %rax
movl %ecx, 0x8(%rax)
movq 0x1d0(%rsp), %rax
movq 0x118(%rsp), %rcx
movslq (%rcx), %rcx
movsd (%rax,%rcx,8), %xmm0
movq 0x118(%rsp), %rax
movsd %xmm0, 0x20(%rax)
movq 0x198(%rsp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x1af70
movq (%rax), %rax
cmpl $0x0, 0x4(%rax)
jne 0x415e3
movq 0x120(%rsp), %rax
movl $0x1, 0x4(%rax)
jmp 0x415f2
movq 0x120(%rsp), %rax
movl $0x0, 0x4(%rax)
movq 0x198(%rsp), %rdi
callq 0x41d60
movq (%rax), %rax
cmpl $0x0, 0x4(%rax)
jne 0x41619
movq 0x118(%rsp), %rax
movl $0x1, 0x4(%rax)
jmp 0x41628
movq 0x118(%rsp), %rax
movl $0x0, 0x4(%rax)
movq 0x198(%rsp), %rdi
leaq 0x120(%rsp), %rsi
callq 0x41cf0
movq 0x198(%rsp), %rdi
leaq 0x118(%rsp), %rsi
callq 0x41cf0
movq 0x198(%rsp), %rdi
callq 0x1af10
movq %rax, 0x110(%rsp)
movq 0x198(%rsp), %rdi
callq 0x1af40
movq %rax, 0x108(%rsp)
movq 0x110(%rsp), %rdi
movq 0x108(%rsp), %rsi
leaq -0xd33(%rip), %rdx      # 0x40960
callq 0x1aec0
movl $0x0, 0x104(%rsp)
movl $0x0, 0x100(%rsp)
movl 0x100(%rsp), %eax
movl %eax, 0x5c(%rsp)
movq 0x198(%rsp), %rdi
callq 0x1aea0
movq %rax, %rcx
movl 0x5c(%rsp), %eax
cmpl %ecx, %eax
jge 0x418dd
cmpl $0x0, 0x100(%rsp)
jle 0x417bd
movq 0x198(%rsp), %rdi
movl 0x100(%rsp), %eax
subl $0x1, %eax
movslq %eax, %rsi
callq 0x1af70
movq (%rax), %rax
movl 0x4(%rax), %eax
movl %eax, 0x58(%rsp)
movq 0x198(%rsp), %rdi
movslq 0x100(%rsp), %rsi
callq 0x1af70
movq %rax, %rcx
movl 0x58(%rsp), %eax
movq (%rcx), %rcx
cmpl 0x4(%rcx), %eax
jne 0x417bd
movq 0x238aa(%rip), %rax     # 0x64fe0
movq (%rax), %rax
movq %rax, 0x48(%rsp)
movq 0x198(%rsp), %rdi
movl 0x100(%rsp), %eax
subl $0x1, %eax
movslq %eax, %rsi
callq 0x1af70
movq (%rax), %rax
movl (%rax), %eax
movl %eax, 0x50(%rsp)
movq 0x198(%rsp), %rdi
movslq 0x100(%rsp), %rsi
callq 0x1af70
movq (%rax), %rax
movl (%rax), %eax
movl %eax, 0x54(%rsp)
movq 0x198(%rsp), %rdi
movslq 0x100(%rsp), %rsi
callq 0x1af70
movq 0x48(%rsp), %rdi
movl 0x50(%rsp), %edx
movl 0x54(%rsp), %ecx
movq (%rax), %rax
movl 0x4(%rax), %r8d
leaq 0x151d1(%rip), %rsi     # 0x56980
movb $0x0, %al
callq 0x2250
xorl %edi, %edi
callq 0x21f0
movl $0x0, 0xfc(%rsp)
movq 0x198(%rsp), %rdi
movslq 0x100(%rsp), %rsi
callq 0x1af70
movq (%rax), %rax
cmpl $0x0, 0x4(%rax)
jne 0x417f3
movl $0x1, 0xfc(%rsp)
jmp 0x417fe
movl $0xffffffff, 0xfc(%rsp) # imm = 0xFFFFFFFF
movl 0x104(%rsp), %eax
movl %eax, 0xf8(%rsp)
movl 0xf8(%rsp), %eax
movl %eax, 0x44(%rsp)
movq 0x198(%rsp), %rdi
movslq 0x100(%rsp), %rsi
callq 0x1af70
movq %rax, %rcx
movl 0x44(%rsp), %eax
movq (%rcx), %rcx
movl (%rcx), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jg 0x4186c
movl 0xfc(%rsp), %edx
movq 0x1b0(%rsp), %rax
movslq 0xf8(%rsp), %rcx
movl %edx, (%rax,%rcx,4)
movl 0xf8(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xf8(%rsp)
jmp 0x4180c
movq 0x1b0(%rsp), %rax
movq %rax, 0x38(%rsp)
movq 0x198(%rsp), %rdi
movslq 0x100(%rsp), %rsi
callq 0x1af70
movq %rax, %rcx
movq 0x38(%rsp), %rax
movq (%rcx), %rcx
movslq (%rcx), %rcx
movl $0x0, (%rax,%rcx,4)
movq 0x198(%rsp), %rdi
movslq 0x100(%rsp), %rsi
callq 0x1af70
movq (%rax), %rax
movl (%rax), %eax
addl $0x1, %eax
movl %eax, 0x104(%rsp)
movl 0x100(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x100(%rsp)
jmp 0x416ae
testb $0x1, 0x238ff(%rip)     # 0x651e3
je 0x41917
movq 0x236f3(%rip), %rax     # 0x64fe0
movq (%rax), %rax
movq %rax, 0x30(%rsp)
movq 0x198(%rsp), %rdi
callq 0x1aea0
movq 0x30(%rsp), %rdi
movl %eax, %edx
leaq 0x15096(%rip), %rsi     # 0x569a6
movb $0x0, %al
callq 0x2250
movl $0x0, 0xf4(%rsp)
movl 0xf4(%rsp), %eax
movl %eax, 0x2c(%rsp)
movq 0x198(%rsp), %rdi
callq 0x1aea0
movq %rax, %rcx
movl 0x2c(%rsp), %eax
cmpl %ecx, %eax
jge 0x419df
movq 0x198(%rsp), %rdi
movslq 0xf4(%rsp), %rsi
callq 0x1af70
movq (%rax), %rax
cmpl $0x0, 0x4(%rax)
jne 0x41998
movq 0x1c0(%rsp), %rax
movq %rax, 0x20(%rsp)
movq 0x198(%rsp), %rdi
movslq 0xf4(%rsp), %rsi
callq 0x1af70
movq 0x20(%rsp), %rdi
movq %rax, %rsi
callq 0x41cf0
jmp 0x419c7
movq 0x1b8(%rsp), %rax
movq %rax, 0x18(%rsp)
movq 0x198(%rsp), %rdi
movslq 0xf4(%rsp), %rsi
callq 0x1af70
movq 0x18(%rsp), %rdi
movq %rax, %rsi
callq 0x41cf0
jmp 0x419c9
movl 0xf4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xf4(%rsp)
jmp 0x41922
movq 0x190(%rsp), %rax
movq %rax, 0x10(%rsp)
cmpq $0x0, %rax
je 0x419fc
movq 0x10(%rsp), %rdi
callq 0x2220
movl $0x0, 0xf0(%rsp)
movl 0xf0(%rsp), %eax
movl %eax, 0xc(%rsp)
movq 0x180(%rsp), %rdi
callq 0x41e20
movq %rax, %rcx
movl 0xc(%rsp), %eax
cmpl %ecx, %eax
jge 0x41a6f
movq 0x180(%rsp), %rdi
movslq 0xf0(%rsp), %rsi
callq 0x41e40
movq (%rax), %rax
movq %rax, (%rsp)
cmpq $0x0, %rax
je 0x41a5a
movq (%rsp), %rdi
movl $0x8, %esi
callq 0x21a0
jmp 0x41a5c
movl 0xf0(%rsp), %eax
addl $0x1, %eax
movl %eax, 0xf0(%rsp)
jmp 0x41a07
addq $0x1d8, %rsp            # imm = 0x1D8
retq
nopw (%rax,%rax)