// File: wichtounet[P]articles/plf_colony_alpha/plf_colony.h
// Function: plf::colony<NonTrivialStringMovable, std::allocator<NonTrivialStringMovable>, unsigned short>::erase(plf::colony<NonTrivialStringMovable, std::allocator<NonTrivialStringMovable>, unsigned short>::colony_iterator<std::allocator<NonTrivialStringMovable>, true> const&, plf::colony<NonTrivialStringMovable, std::allocator<NonTrivialStringMovable>, unsigned short>::colony_iterator<std::allocator<NonTrivialStringMovable>, true> const&)
void erase(const const_iterator &iterator1, const const_iterator &iterator2)
	{
		assert(iterator1 != iterator2);
		assert(iterator1 < iterator2);

		iterator current = iterator1;

		if (current.group_pointer != iterator2.group_pointer)
		{
			if (current.element_pointer != current.group_pointer->elements + *(current.group_pointer->skipfield)) // if iterator1 is not the first non-erased element in it's group - most common case
			{
				const skipfield_pointer_type end = iterator1.group_pointer->skipfield + iterator1.group_pointer->size;
				skipfield_type number_of_group_erasures = 0;

				// Destroy elements first:
				do
				{
					#ifdef PLF_COLONY_TYPE_TRAITS_SUPPORT
						if (!(std::is_trivially_destructible<element_type>::value))
					#endif
					{
						PLF_COLONY_DESTROY(element_allocator_type, (*this), current.element_pointer); // Destruct element
					}

        			erased_locations.push(current.element_pointer);

					++current.skipfield_pointer;
					current.element_pointer += 1 + *current.skipfield_pointer;
					current.skipfield_pointer += *current.skipfield_pointer;
					++number_of_group_erasures;
				} while (current.skipfield_pointer != end);

				current.group_pointer->number_of_elements -= number_of_group_erasures;
				total_number_of_elements -= number_of_group_erasures;

				// Now update skipfield:
				skipfield_pointer_type current_skipfield = iterator1.skipfield_pointer;
				skipfield_type node_value = *(current_skipfield - 1); // Find value of left-hand node
				skipfield_type update_count = static_cast<skipfield_type>(end - current_skipfield);

				*(current_skipfield - node_value) = node_value + update_count; // Either set current node as the start node, or if previous node is part of a skipblock, update that skipblock's start node and join to that skipblock
				const bool left_node_is_zero = (node_value == 0);
				node_value += left_node_is_zero; // ie. set node_value to 1 if it was zero
				current_skipfield += left_node_is_zero; // Update current_skipfield in while loop below, if the previous node was non-zero
				update_count -= left_node_is_zero;

				// Vectorize the updates:
				while (update_count >= 4)
				{
					*(current_skipfield) = node_value + 1;
					*(current_skipfield + 1) = node_value + 2;
					*(current_skipfield + 2) = node_value + 3;
					*(current_skipfield + 3) = node_value + 4;

					current_skipfield += 4;
					node_value += 4;
					update_count -= 4;
				}

				while (current_skipfield != end)
				{
					*(current_skipfield++) = ++node_value;
				}

				current.group_pointer = current.group_pointer->next_group;
			}


			// Intermediate groups:
			group_pointer_type current_group, previous_group = current.group_pointer->previous_group;

			while (current.group_pointer != iterator2.group_pointer)
			{
				#ifdef PLF_COLONY_TYPE_TRAITS_SUPPORT
					if (!(std::is_trivially_destructible<element_type>::value)) // This should be removed by the compiler
				#endif
				{
					current.element_pointer = current.group_pointer->elements + *(current.group_pointer->skipfield);
					current.skipfield_pointer = current.group_pointer->skipfield + *(current.group_pointer->skipfield);
					const element_pointer_type end = current.group_pointer->last_endpoint;

					do
					{
						PLF_COLONY_DESTROY(element_allocator_type, (*this), current.element_pointer); // Destruct element
						++current.skipfield_pointer;
						current.element_pointer += 1 + *current.skipfield_pointer;
						current.skipfield_pointer += *current.skipfield_pointer;
					} while (current.element_pointer != end);
				}

				if (current.group_pointer->number_of_elements != static_cast<skipfield_type>(current.group_pointer->last_endpoint - current.group_pointer->elements)) // no erasures
				{
					consolidate_erased_locations(current.group_pointer);
				}

				total_number_of_elements -= current.group_pointer->number_of_elements;
				current_group = current.group_pointer;
				current.group_pointer = current.group_pointer->next_group;

				PLF_COLONY_DESTROY(group_allocator_type, group_allocator_pair, current_group);
				PLF_COLONY_DEALLOCATE(group_allocator_type, group_allocator_pair, current_group, 1);
			}

			current.element_pointer = current.group_pointer->elements + *(current.group_pointer->skipfield);
			current.skipfield_pointer = current.group_pointer->skipfield + *(current.group_pointer->skipfield);
			current.group_pointer->previous_group = previous_group;

			if (previous_group != NULL)
			{
				previous_group->next_group = current.group_pointer;
			}
			else
			{
				first_group = current.group_pointer;
				begin_iterator = iterator2; // This line is included here primarily to avoid a secondary if statement within the if block below - it will not be needed in any other situation
			}

			// If iterator2 is right at the start of the final group (if so, there is nothing more to be erased), return:
			if (iterator2.group_pointer->elements + *(iterator2.group_pointer->skipfield) == iterator2.element_pointer)
			{
				return;
			}
		}


		// Final group:
		// Code explanation:
		// If not erasing entire final group, 1. Destruct elements (if non-trivial destructor) and add locations to erased stack. 2. process skipfield.
		// If erasing entire group, 1. Destruct elements (if non-trivial destructor), 2. if no elements left in colony, clear() 3. otherwise reset end_iterator and consolidate_erased_locations if there were some prior erasures in group


		if (iterator2.element_pointer != current.group_pointer->last_endpoint || current.element_pointer != current.group_pointer->elements + *(current.group_pointer->skipfield)) // ie. not erasing entire group
		{
			skipfield_type number_of_group_erasures = 0;

			element_pointer_type current_element = current.element_pointer;
			skipfield_pointer_type current_skipfield = current.skipfield_pointer;

			do
			{
				#ifdef PLF_COLONY_TYPE_TRAITS_SUPPORT
					if (!(std::is_trivially_destructible<element_type>::value)) // This should be removed by the compiler
				#endif
				{
					PLF_COLONY_DESTROY(element_allocator_type, (*this), current_element);
				}

				erased_locations.push(current_element);

				++current_skipfield;
				current_element += 1 + *current_skipfield;
				current_skipfield += *current_skipfield;
				++number_of_group_erasures;
			} while(current_element != iterator2.element_pointer);

			total_number_of_elements -= number_of_group_erasures;
			current.group_pointer->number_of_elements -= number_of_group_erasures;

			// Update skipfield:
			skipfield_type node_value = *(current.skipfield_pointer - (current.group_pointer->skipfield != current.skipfield_pointer)); // Find value of left-hand node - if current node is at start of skipfield, we check the current node instead, which will always be zero.
			skipfield_type update_count = static_cast<skipfield_type>(iterator2.element_pointer - current.element_pointer);

			*(current.skipfield_pointer - node_value) = node_value + update_count; // Either set current node as the start node, or if previous node is part of a skipblock, update that skipblock's start node
			const bool left_node_is_zero = (node_value == 0);
			node_value += left_node_is_zero; // ie. set node_value to 1 if it was zero
			current.skipfield_pointer += left_node_is_zero; // Update current_skipfield in while loop below, if the previous node was non-zero
			update_count -= left_node_is_zero;

			// Vectorize the updates:
			while (update_count >= 4)
			{
				*(current.skipfield_pointer) = node_value + 1;
				*(current.skipfield_pointer + 1) = node_value + 2;
				*(current.skipfield_pointer + 2) = node_value + 3;
				*(current.skipfield_pointer + 3) = node_value + 4;

				current.skipfield_pointer += 4;
				node_value += 4;
				update_count -= 4;
			}

			while (current.skipfield_pointer != iterator2.skipfield_pointer)
			{
				*(current.skipfield_pointer++) = ++node_value;
			}

			if (iterator1.element_pointer == begin_iterator.element_pointer) // Retaining this check for the case when iterator1 and iterator2 have the same group
			{
				begin_iterator = iterator2;
			}
		}
		else // ie. full group erasure
		{
			#ifdef PLF_COLONY_TYPE_TRAITS_SUPPORT
				if (!(std::is_trivially_destructible<element_type>::value)) // This should be removed by the compiler
			#endif
			{
				while(current.element_pointer != iterator2.element_pointer)
				{
					PLF_COLONY_DESTROY(element_allocator_type, (*this), current.element_pointer);
					++current.skipfield_pointer;
					current.element_pointer += 1 + *current.skipfield_pointer;
					current.skipfield_pointer += *current.skipfield_pointer;
				}
			}

			// Note: it is not possible that next_group != NULL at this point (if it were, iterator2.element_pointer could not be == last_endpoint - which indicates that it is == end())

			if ((total_number_of_elements -= current.group_pointer->number_of_elements) != 0) // ie. previous_group != NULL
			{
				current.group_pointer->previous_group->next_group = NULL;
				end_iterator.group_pointer = current.group_pointer->previous_group;
				end_iterator.element_pointer = current.group_pointer->previous_group->last_endpoint;
				end_iterator.skipfield_pointer = current.group_pointer->previous_group->skipfield + current.group_pointer->previous_group->size;

				if (current.group_pointer->number_of_elements != static_cast<skipfield_type>(current.group_pointer->last_endpoint - current.group_pointer->elements)) // ie. some prior erasures exist in group
				{
					consolidate_erased_locations(current.group_pointer);
				}
			}
			else // ie. colony is now empty
			{
				first_group = NULL;
				clear();
			}

			PLF_COLONY_DESTROY(group_allocator_type, group_allocator_pair, current.group_pointer);
			PLF_COLONY_DEALLOCATE(group_allocator_type, group_allocator_pair, current.group_pointer, 1);
		}
	}

// Assembly:
subq $0x98, %rsp
movq %rdi, 0x90(%rsp)
movq %rsi, 0x88(%rsp)
movq %rdx, 0x80(%rsp)
movq 0x90(%rsp), %rax
movq %rax, 0x8(%rsp)
movq 0x88(%rsp), %rsi
leaq 0x68(%rsp), %rdi
callq 0xd1990
movq 0x68(%rsp), %rax
movq 0x80(%rsp), %rcx
cmpq (%rcx), %rax
je 0xd14ca
movq 0x70(%rsp), %rax
movq 0x68(%rsp), %rcx
movq 0x10(%rcx), %rcx
movq 0x68(%rsp), %rdx
movq 0x18(%rdx), %rdx
movzwl (%rdx), %edx
movslq %edx, %rdx
imulq $0x28, %rdx, %rdx
addq %rdx, %rcx
cmpq %rcx, %rax
je 0xd127d
movq 0x88(%rsp), %rax
movq (%rax), %rax
movq 0x18(%rax), %rax
movq 0x88(%rsp), %rcx
movq (%rcx), %rcx
movzwl 0x32(%rcx), %ecx
movslq %ecx, %rcx
shlq %rcx
addq %rcx, %rax
movq %rax, 0x60(%rsp)
movw $0x0, 0x5e(%rsp)
movq 0x8(%rsp), %rdi
movq 0x70(%rsp), %rsi
callq 0x39870
movq 0x8(%rsp), %rdi
addq $0x48, %rdi
movq 0x70(%rsp), %rsi
callq 0xce6f0
movq 0x78(%rsp), %rax
addq $0x2, %rax
movq %rax, 0x78(%rsp)
movq 0x78(%rsp), %rax
movzwl (%rax), %ecx
addl $0x1, %ecx
movq 0x70(%rsp), %rax
movslq %ecx, %rcx
imulq $0x28, %rcx, %rcx
addq %rcx, %rax
movq %rax, 0x70(%rsp)
movq 0x78(%rsp), %rax
movzwl (%rax), %ecx
movq 0x78(%rsp), %rax
movslq %ecx, %rcx
shlq %rcx
addq %rcx, %rax
movq %rax, 0x78(%rsp)
movw 0x5e(%rsp), %ax
addw $0x1, %ax
movw %ax, 0x5e(%rsp)
movq 0x78(%rsp), %rax
cmpq 0x60(%rsp), %rax
jne 0xd1054
movq 0x8(%rsp), %rax
movzwl 0x5e(%rsp), %esi
movq 0x68(%rsp), %rcx
movzwl 0x30(%rcx), %edx
subl %esi, %edx
movw %dx, 0x30(%rcx)
movzwl 0x5e(%rsp), %ecx
movl %ecx, %edx
movq 0x38(%rax), %rcx
subq %rdx, %rcx
movq %rcx, 0x38(%rax)
movq 0x88(%rsp), %rax
movq 0x10(%rax), %rax
movq %rax, 0x50(%rsp)
movq 0x50(%rsp), %rax
movw -0x2(%rax), %ax
movw %ax, 0x4e(%rsp)
movq 0x60(%rsp), %rax
movq 0x50(%rsp), %rcx
subq %rcx, %rax
sarq %rax
movw %ax, 0x4c(%rsp)
movzwl 0x4e(%rsp), %eax
movzwl 0x4c(%rsp), %ecx
addl %ecx, %eax
movw %ax, %dx
movq 0x50(%rsp), %rax
movzwl 0x4e(%rsp), %ecx
movslq %ecx, %rsi
xorl %ecx, %ecx
subq %rsi, %rcx
movw %dx, (%rax,%rcx,2)
movzwl 0x4e(%rsp), %eax
cmpl $0x0, %eax
sete %al
andb $0x1, %al
movb %al, 0x4b(%rsp)
movb 0x4b(%rsp), %al
andb $0x1, %al
movzbl %al, %ecx
movzwl 0x4e(%rsp), %eax
addl %ecx, %eax
movw %ax, 0x4e(%rsp)
movb 0x4b(%rsp), %al
andb $0x1, %al
movzbl %al, %ecx
movq 0x50(%rsp), %rax
movslq %ecx, %rcx
shlq %rcx
addq %rcx, %rax
movq %rax, 0x50(%rsp)
movb 0x4b(%rsp), %al
andb $0x1, %al
movzbl %al, %ecx
movzwl 0x4c(%rsp), %eax
subl %ecx, %eax
movw %ax, 0x4c(%rsp)
movzwl 0x4c(%rsp), %eax
cmpl $0x4, %eax
jl 0xd123d
movzwl 0x4e(%rsp), %eax
addl $0x1, %eax
movw %ax, %cx
movq 0x50(%rsp), %rax
movw %cx, (%rax)
movzwl 0x4e(%rsp), %eax
addl $0x2, %eax
movw %ax, %cx
movq 0x50(%rsp), %rax
movw %cx, 0x2(%rax)
movzwl 0x4e(%rsp), %eax
addl $0x3, %eax
movw %ax, %cx
movq 0x50(%rsp), %rax
movw %cx, 0x4(%rax)
movzwl 0x4e(%rsp), %eax
addl $0x4, %eax
movw %ax, %cx
movq 0x50(%rsp), %rax
movw %cx, 0x6(%rax)
movq 0x50(%rsp), %rax
addq $0x8, %rax
movq %rax, 0x50(%rsp)
movzwl 0x4e(%rsp), %eax
addl $0x4, %eax
movw %ax, 0x4e(%rsp)
movzwl 0x4c(%rsp), %eax
subl $0x4, %eax
movw %ax, 0x4c(%rsp)
jmp 0xd11b7
jmp 0xd123f
movq 0x50(%rsp), %rax
cmpq 0x60(%rsp), %rax
je 0xd126f
movw 0x4e(%rsp), %cx
addw $0x1, %cx
movw %cx, 0x4e(%rsp)
movq 0x50(%rsp), %rax
movq %rax, %rdx
addq $0x2, %rdx
movq %rdx, 0x50(%rsp)
movw %cx, (%rax)
jmp 0xd123f
movq 0x68(%rsp), %rax
movq 0x8(%rax), %rax
movq %rax, 0x68(%rsp)
movq 0x68(%rsp), %rax
movq 0x20(%rax), %rax
movq %rax, 0x38(%rsp)
movq 0x68(%rsp), %rax
movq 0x80(%rsp), %rcx
cmpq (%rcx), %rax
je 0xd13fe
movq 0x68(%rsp), %rax
movq 0x10(%rax), %rax
movq 0x68(%rsp), %rcx
movq 0x18(%rcx), %rcx
movzwl (%rcx), %ecx
movslq %ecx, %rcx
imulq $0x28, %rcx, %rcx
addq %rcx, %rax
movq %rax, 0x70(%rsp)
movq 0x68(%rsp), %rax
movq 0x18(%rax), %rax
movq 0x68(%rsp), %rcx
movq 0x18(%rcx), %rcx
movzwl (%rcx), %ecx
movslq %ecx, %rcx
shlq %rcx
addq %rcx, %rax
movq %rax, 0x78(%rsp)
movq 0x68(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x30(%rsp)
movq 0x8(%rsp), %rdi
movq 0x70(%rsp), %rsi
callq 0x39870
movq 0x78(%rsp), %rax
addq $0x2, %rax
movq %rax, 0x78(%rsp)
movq 0x78(%rsp), %rax
movzwl (%rax), %ecx
addl $0x1, %ecx
movq 0x70(%rsp), %rax
movslq %ecx, %rcx
imulq $0x28, %rcx, %rcx
addq %rcx, %rax
movq %rax, 0x70(%rsp)
movq 0x78(%rsp), %rax
movzwl (%rax), %ecx
movq 0x78(%rsp), %rax
movslq %ecx, %rcx
shlq %rcx
addq %rcx, %rax
movq %rax, 0x78(%rsp)
movq 0x70(%rsp), %rax
cmpq 0x30(%rsp), %rax
jne 0xd12f5
movq 0x68(%rsp), %rax
movzwl 0x30(%rax), %eax
movl %eax, 0x4(%rsp)
movq 0x68(%rsp), %rax
movq (%rax), %rax
movq 0x68(%rsp), %rcx
movq 0x10(%rcx), %rcx
subq %rcx, %rax
movl $0x28, %ecx
cqto
idivq %rcx
movq %rax, %rcx
movl 0x4(%rsp), %eax
movzwl %cx, %ecx
cmpl %ecx, %eax
je 0xd13a0
movq 0x8(%rsp), %rdi
movq 0x68(%rsp), %rsi
callq 0xcea60
movq 0x8(%rsp), %rdi
movq 0x68(%rsp), %rax
movzwl 0x30(%rax), %eax
movl %eax, %ecx
movq 0x38(%rdi), %rax
subq %rcx, %rax
movq %rax, 0x38(%rdi)
movq 0x68(%rsp), %rax
movq %rax, 0x40(%rsp)
movq 0x68(%rsp), %rax
movq 0x8(%rax), %rax
movq %rax, 0x68(%rsp)
addq $0x42, %rdi
movq 0x40(%rsp), %rsi
callq 0x3c580
movq 0x8(%rsp), %rdi
addq $0x42, %rdi
movq 0x40(%rsp), %rsi
movl $0x1, %edx
callq 0x3c550
jmp 0xd128b
movq 0x68(%rsp), %rax
movq 0x10(%rax), %rax
movq 0x68(%rsp), %rcx
movq 0x18(%rcx), %rcx
movzwl (%rcx), %ecx
movslq %ecx, %rcx
imulq $0x28, %rcx, %rcx
addq %rcx, %rax
movq %rax, 0x70(%rsp)
movq 0x68(%rsp), %rax
movq 0x18(%rax), %rax
movq 0x68(%rsp), %rcx
movq 0x18(%rcx), %rcx
movzwl (%rcx), %ecx
movslq %ecx, %rcx
shlq %rcx
addq %rcx, %rax
movq %rax, 0x78(%rsp)
movq 0x38(%rsp), %rcx
movq 0x68(%rsp), %rax
movq %rcx, 0x20(%rax)
cmpq $0x0, 0x38(%rsp)
je 0xd146b
movq 0x68(%rsp), %rcx
movq 0x38(%rsp), %rax
movq %rcx, 0x8(%rax)
jmp 0xd148a
movq 0x8(%rsp), %rdi
movq 0x68(%rsp), %rax
movq %rax, 0x30(%rdi)
movq 0x80(%rsp), %rsi
addq $0x18, %rdi
callq 0xd19d0
movq 0x80(%rsp), %rax
movq (%rax), %rax
movq 0x10(%rax), %rax
movq 0x80(%rsp), %rcx
movq (%rcx), %rcx
movq 0x18(%rcx), %rcx
movzwl (%rcx), %ecx
movslq %ecx, %rcx
imulq $0x28, %rcx, %rcx
addq %rcx, %rax
movq 0x80(%rsp), %rcx
cmpq 0x8(%rcx), %rax
jne 0xd14c8
jmp 0xd1910
jmp 0xd14ca
movq 0x80(%rsp), %rax
movq 0x8(%rax), %rax
movq 0x68(%rsp), %rcx
cmpq (%rcx), %rax
jne 0xd150d
movq 0x70(%rsp), %rax
movq 0x68(%rsp), %rcx
movq 0x10(%rcx), %rcx
movq 0x68(%rsp), %rdx
movq 0x18(%rdx), %rdx
movzwl (%rdx), %edx
movslq %edx, %rdx
imulq $0x28, %rdx, %rdx
addq %rdx, %rcx
cmpq %rcx, %rax
je 0xd179f
movw $0x0, 0x2e(%rsp)
movq 0x70(%rsp), %rax
movq %rax, 0x20(%rsp)
movq 0x78(%rsp), %rax
movq %rax, 0x18(%rsp)
movq 0x8(%rsp), %rdi
movq 0x20(%rsp), %rsi
callq 0x39870
movq 0x8(%rsp), %rdi
addq $0x48, %rdi
movq 0x20(%rsp), %rsi
callq 0xce6f0
movq 0x18(%rsp), %rax
addq $0x2, %rax
movq %rax, 0x18(%rsp)
movq 0x18(%rsp), %rax
movzwl (%rax), %ecx
addl $0x1, %ecx
movq 0x20(%rsp), %rax
movslq %ecx, %rcx
imulq $0x28, %rcx, %rcx
addq %rcx, %rax
movq %rax, 0x20(%rsp)
movq 0x18(%rsp), %rax
movzwl (%rax), %ecx
movq 0x18(%rsp), %rax
movslq %ecx, %rcx
shlq %rcx
addq %rcx, %rax
movq %rax, 0x18(%rsp)
movw 0x2e(%rsp), %ax
addw $0x1, %ax
movw %ax, 0x2e(%rsp)
movq 0x20(%rsp), %rax
movq 0x80(%rsp), %rcx
cmpq 0x8(%rcx), %rax
jne 0xd1528
movq 0x8(%rsp), %rax
movzwl 0x2e(%rsp), %ecx
movl %ecx, %edx
movq 0x38(%rax), %rcx
subq %rdx, %rcx
movq %rcx, 0x38(%rax)
movzwl 0x2e(%rsp), %edx
movq 0x68(%rsp), %rax
movzwl 0x30(%rax), %ecx
subl %edx, %ecx
movw %cx, 0x30(%rax)
movq 0x78(%rsp), %rax
movq 0x68(%rsp), %rcx
movq 0x18(%rcx), %rcx
cmpq 0x78(%rsp), %rcx
setne %cl
andb $0x1, %cl
movzbl %cl, %ecx
movslq %ecx, %rdx
xorl %ecx, %ecx
subq %rdx, %rcx
movw (%rax,%rcx,2), %ax
movw %ax, 0x16(%rsp)
movq 0x80(%rsp), %rax
movq 0x8(%rax), %rax
movq 0x70(%rsp), %rcx
subq %rcx, %rax
movl $0x28, %ecx
cqto
idivq %rcx
movw %ax, 0x14(%rsp)
movzwl 0x16(%rsp), %eax
movzwl 0x14(%rsp), %ecx
addl %ecx, %eax
movw %ax, %dx
movq 0x78(%rsp), %rax
movzwl 0x16(%rsp), %ecx
movslq %ecx, %rsi
xorl %ecx, %ecx
subq %rsi, %rcx
movw %dx, (%rax,%rcx,2)
movzwl 0x16(%rsp), %eax
cmpl $0x0, %eax
sete %al
andb $0x1, %al
movb %al, 0x13(%rsp)
movb 0x13(%rsp), %al
andb $0x1, %al
movzbl %al, %ecx
movzwl 0x16(%rsp), %eax
addl %ecx, %eax
movw %ax, 0x16(%rsp)
movb 0x13(%rsp), %al
andb $0x1, %al
movzbl %al, %ecx
movq 0x78(%rsp), %rax
movslq %ecx, %rcx
shlq %rcx
addq %rcx, %rax
movq %rax, 0x78(%rsp)
movb 0x13(%rsp), %al
andb $0x1, %al
movzbl %al, %ecx
movzwl 0x14(%rsp), %eax
subl %ecx, %eax
movw %ax, 0x14(%rsp)
movzwl 0x14(%rsp), %eax
cmpl $0x4, %eax
jl 0xd1734
movzwl 0x16(%rsp), %eax
addl $0x1, %eax
movw %ax, %cx
movq 0x78(%rsp), %rax
movw %cx, (%rax)
movzwl 0x16(%rsp), %eax
addl $0x2, %eax
movw %ax, %cx
movq 0x78(%rsp), %rax
movw %cx, 0x2(%rax)
movzwl 0x16(%rsp), %eax
addl $0x3, %eax
movw %ax, %cx
movq 0x78(%rsp), %rax
movw %cx, 0x4(%rax)
movzwl 0x16(%rsp), %eax
addl $0x4, %eax
movw %ax, %cx
movq 0x78(%rsp), %rax
movw %cx, 0x6(%rax)
movq 0x78(%rsp), %rax
addq $0x8, %rax
movq %rax, 0x78(%rsp)
movzwl 0x16(%rsp), %eax
addl $0x4, %eax
movw %ax, 0x16(%rsp)
movzwl 0x14(%rsp), %eax
subl $0x4, %eax
movw %ax, 0x14(%rsp)
jmp 0xd16ae
jmp 0xd1736
movq 0x78(%rsp), %rax
movq 0x80(%rsp), %rcx
cmpq 0x10(%rcx), %rax
je 0xd176d
movw 0x16(%rsp), %cx
addw $0x1, %cx
movw %cx, 0x16(%rsp)
movq 0x78(%rsp), %rax
movq %rax, %rdx
addq $0x2, %rdx
movq %rdx, 0x78(%rsp)
movw %cx, (%rax)
jmp 0xd1736
movq 0x8(%rsp), %rcx
movq 0x88(%rsp), %rax
movq 0x8(%rax), %rax
cmpq 0x20(%rcx), %rax
jne 0xd179a
movq 0x8(%rsp), %rdi
movq 0x80(%rsp), %rsi
addq $0x18, %rdi
callq 0xd19d0
jmp 0xd1910
jmp 0xd17a1
movq 0x70(%rsp), %rax
movq 0x80(%rsp), %rcx
cmpq 0x8(%rcx), %rax
je 0xd180d
movq 0x8(%rsp), %rdi
movq 0x70(%rsp), %rsi
callq 0x39870
movq 0x78(%rsp), %rax
addq $0x2, %rax
movq %rax, 0x78(%rsp)
movq 0x78(%rsp), %rax
movzwl (%rax), %ecx
addl $0x1, %ecx
movq 0x70(%rsp), %rax
movslq %ecx, %rcx
imulq $0x28, %rcx, %rcx
addq %rcx, %rax
movq %rax, 0x70(%rsp)
movq 0x78(%rsp), %rax
movzwl (%rax), %ecx
movq 0x78(%rsp), %rax
movslq %ecx, %rcx
shlq %rcx
addq %rcx, %rax
movq %rax, 0x78(%rsp)
jmp 0xd17a1
movq 0x8(%rsp), %rcx
movq 0x68(%rsp), %rax
movzwl 0x30(%rax), %eax
movl %eax, %edx
movq 0x38(%rcx), %rax
subq %rdx, %rax
movq %rax, 0x38(%rcx)
cmpq $0x0, %rax
je 0xd18d3
movq 0x8(%rsp), %rax
movq 0x68(%rsp), %rcx
movq 0x20(%rcx), %rcx
movq $0x0, 0x8(%rcx)
movq 0x68(%rsp), %rcx
movq 0x20(%rcx), %rcx
movq %rcx, (%rax)
movq 0x68(%rsp), %rcx
movq 0x20(%rcx), %rcx
movq (%rcx), %rcx
movq %rcx, 0x8(%rax)
movq 0x68(%rsp), %rcx
movq 0x20(%rcx), %rcx
movq 0x18(%rcx), %rcx
movq 0x68(%rsp), %rdx
movq 0x20(%rdx), %rdx
movzwl 0x32(%rdx), %edx
movslq %edx, %rdx
shlq %rdx
addq %rdx, %rcx
movq %rcx, 0x10(%rax)
movq 0x68(%rsp), %rax
movzwl 0x30(%rax), %eax
movl %eax, (%rsp)
movq 0x68(%rsp), %rax
movq (%rax), %rax
movq 0x68(%rsp), %rcx
movq 0x10(%rcx), %rcx
subq %rcx, %rax
movl $0x28, %ecx
cqto
idivq %rcx
movq %rax, %rcx
movl (%rsp), %eax
movzwl %cx, %ecx
cmpl %ecx, %eax
je 0xd18d1
movq 0x8(%rsp), %rdi
movq 0x68(%rsp), %rsi
callq 0xcea60
jmp 0xd18e5
movq 0x8(%rsp), %rdi
movq $0x0, 0x30(%rdi)
callq 0x3c7a0
movq 0x8(%rsp), %rdi
addq $0x42, %rdi
movq 0x68(%rsp), %rsi
callq 0x3c580
movq 0x8(%rsp), %rdi
addq $0x42, %rdi
movq 0x68(%rsp), %rsi
movl $0x1, %edx
callq 0x3c550
addq $0x98, %rsp
retq
nopl (%rax,%rax)