// File: donfreiday[P]gb/./imgui/stb_textedit.h
// Function: ImGuiStb::stb_textedit_key(ImGuiTextEditState*, ImGuiStb::STB_TexteditState*, int)
static void stb_textedit_key(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int key)
{
retry:
   switch (key) {
      default: {
         int c = STB_TEXTEDIT_KEYTOTEXT(key);
         if (c > 0) {
            STB_TEXTEDIT_CHARTYPE ch = (STB_TEXTEDIT_CHARTYPE) c;

            // can't add newline in single-line mode
            if (c == '\n' && state->single_line)
               break;

            if (state->insert_mode && !STB_TEXT_HAS_SELECTION(state) && state->cursor < STB_TEXTEDIT_STRINGLEN(str)) {
               stb_text_makeundo_replace(str, state, state->cursor, 1, 1);
               STB_TEXTEDIT_DELETECHARS(str, state->cursor, 1);
               if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, &ch, 1)) {
                  ++state->cursor;
                  state->has_preferred_x = 0;
               }
            } else {
               stb_textedit_delete_selection(str,state); // implicity clamps
               if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, &ch, 1)) {
                  stb_text_makeundo_insert(state, state->cursor, 1);
                  ++state->cursor;
                  state->has_preferred_x = 0;
               }
            }
         }
         break;
      }

#ifdef STB_TEXTEDIT_K_INSERT
      case STB_TEXTEDIT_K_INSERT:
         state->insert_mode = !state->insert_mode;
         break;
#endif
         
      case STB_TEXTEDIT_K_UNDO:
         stb_text_undo(str, state);
         state->has_preferred_x = 0;
         break;

      case STB_TEXTEDIT_K_REDO:
         stb_text_redo(str, state);
         state->has_preferred_x = 0;
         break;

      case STB_TEXTEDIT_K_LEFT:
         // if currently there's a selection, move cursor to start of selection
         if (STB_TEXT_HAS_SELECTION(state))
            stb_textedit_move_to_first(state);
         else 
            if (state->cursor > 0)
               --state->cursor;
         state->has_preferred_x = 0;
         break;

      case STB_TEXTEDIT_K_RIGHT:
         // if currently there's a selection, move cursor to end of selection
         if (STB_TEXT_HAS_SELECTION(state))
            stb_textedit_move_to_last(str, state);
         else
            ++state->cursor;
         stb_textedit_clamp(str, state);
         state->has_preferred_x = 0;
         break;

      case STB_TEXTEDIT_K_LEFT | STB_TEXTEDIT_K_SHIFT:
         stb_textedit_clamp(str, state);
         stb_textedit_prep_selection_at_cursor(state);
         // move selection left
         if (state->select_end > 0)
            --state->select_end;
         state->cursor = state->select_end;
         state->has_preferred_x = 0;
         break;

#ifdef STB_TEXTEDIT_IS_SPACE
      case STB_TEXTEDIT_K_WORDLEFT:
         if (STB_TEXT_HAS_SELECTION(state))
            stb_textedit_move_to_first(state);
         else {
            state->cursor = stb_textedit_move_to_word_previous(str, state);
            stb_textedit_clamp( str, state );
         }
         break;

      case STB_TEXTEDIT_K_WORDRIGHT:
         if (STB_TEXT_HAS_SELECTION(state)) 
            stb_textedit_move_to_last(str, state);
         else {
            state->cursor = stb_textedit_move_to_word_next(str, state);
            stb_textedit_clamp( str, state );
         }
         break;

      case STB_TEXTEDIT_K_WORDLEFT | STB_TEXTEDIT_K_SHIFT:
         if( !STB_TEXT_HAS_SELECTION( state ) )
            stb_textedit_prep_selection_at_cursor(state);

         state->cursor = stb_textedit_move_to_word_previous(str, state);
         state->select_end = state->cursor;

         stb_textedit_clamp( str, state );
         break;

      case STB_TEXTEDIT_K_WORDRIGHT | STB_TEXTEDIT_K_SHIFT:
         if( !STB_TEXT_HAS_SELECTION( state ) )
            stb_textedit_prep_selection_at_cursor(state);

         state->cursor = stb_textedit_move_to_word_next(str, state);
         state->select_end = state->cursor;

         stb_textedit_clamp( str, state );
         break;
#endif

      case STB_TEXTEDIT_K_RIGHT | STB_TEXTEDIT_K_SHIFT:
         stb_textedit_prep_selection_at_cursor(state);
         // move selection right
         ++state->select_end;
         stb_textedit_clamp(str, state);
         state->cursor = state->select_end;
         state->has_preferred_x = 0;
         break;

      case STB_TEXTEDIT_K_DOWN:
      case STB_TEXTEDIT_K_DOWN | STB_TEXTEDIT_K_SHIFT: {
         StbFindState find;
         StbTexteditRow row;
         int i, sel = (key & STB_TEXTEDIT_K_SHIFT) != 0;

         if (state->single_line) {
            // on windows, up&down in single-line behave like left&right
            key = STB_TEXTEDIT_K_RIGHT | (key & STB_TEXTEDIT_K_SHIFT);
            goto retry;
         }

         if (sel)
            stb_textedit_prep_selection_at_cursor(state);
         else if (STB_TEXT_HAS_SELECTION(state))
            stb_textedit_move_to_last(str,state);

         // compute current position of cursor point
         stb_textedit_clamp(str, state);
         stb_textedit_find_charpos(&find, str, state->cursor, state->single_line);

         // now find character position down a row
         if (find.length) {
            float goal_x = state->has_preferred_x ? state->preferred_x : find.x;
            float x;
            int start = find.first_char + find.length;
            state->cursor = start;
            STB_TEXTEDIT_LAYOUTROW(&row, str, state->cursor);
            x = row.x0;
            for (i=0; i < row.num_chars; ++i) {
               float dx = STB_TEXTEDIT_GETWIDTH(str, start, i);
               #ifdef STB_TEXTEDIT_GETWIDTH_NEWLINE
               if (dx == STB_TEXTEDIT_GETWIDTH_NEWLINE)
                  break;
               #endif
               x += dx;
               if (x > goal_x)
                  break;
               ++state->cursor;
            }
            stb_textedit_clamp(str, state);

            state->has_preferred_x = 1;
            state->preferred_x = goal_x;

            if (sel)
               state->select_end = state->cursor;
         }
         break;
      }
         
      case STB_TEXTEDIT_K_UP:
      case STB_TEXTEDIT_K_UP | STB_TEXTEDIT_K_SHIFT: {
         StbFindState find;
         StbTexteditRow row;
         int i, sel = (key & STB_TEXTEDIT_K_SHIFT) != 0;

         if (state->single_line) {
            // on windows, up&down become left&right
            key = STB_TEXTEDIT_K_LEFT | (key & STB_TEXTEDIT_K_SHIFT);
            goto retry;
         }

         if (sel)
            stb_textedit_prep_selection_at_cursor(state);
         else if (STB_TEXT_HAS_SELECTION(state))
            stb_textedit_move_to_first(state);

         // compute current position of cursor point
         stb_textedit_clamp(str, state);
         stb_textedit_find_charpos(&find, str, state->cursor, state->single_line);

         // can only go up if there's a previous row
         if (find.prev_first != find.first_char) {
            // now find character position up a row
            float goal_x = state->has_preferred_x ? state->preferred_x : find.x;
            float x;
            state->cursor = find.prev_first;
            STB_TEXTEDIT_LAYOUTROW(&row, str, state->cursor);
            x = row.x0;
            for (i=0; i < row.num_chars; ++i) {
               float dx = STB_TEXTEDIT_GETWIDTH(str, find.prev_first, i);
               #ifdef STB_TEXTEDIT_GETWIDTH_NEWLINE
               if (dx == STB_TEXTEDIT_GETWIDTH_NEWLINE)
                  break;
               #endif
               x += dx;
               if (x > goal_x)
                  break;
               ++state->cursor;
            }
            stb_textedit_clamp(str, state);

            state->has_preferred_x = 1;
            state->preferred_x = goal_x;

            if (sel)
               state->select_end = state->cursor;
         }
         break;
      }

      case STB_TEXTEDIT_K_DELETE:
      case STB_TEXTEDIT_K_DELETE | STB_TEXTEDIT_K_SHIFT:
         if (STB_TEXT_HAS_SELECTION(state))
            stb_textedit_delete_selection(str, state);
         else {
            int n = STB_TEXTEDIT_STRINGLEN(str);
            if (state->cursor < n)
               stb_textedit_delete(str, state, state->cursor, 1);
         }
         state->has_preferred_x = 0;
         break;

      case STB_TEXTEDIT_K_BACKSPACE:
      case STB_TEXTEDIT_K_BACKSPACE | STB_TEXTEDIT_K_SHIFT:
         if (STB_TEXT_HAS_SELECTION(state))
            stb_textedit_delete_selection(str, state);
         else {
            stb_textedit_clamp(str, state);
            if (state->cursor > 0) {
               stb_textedit_delete(str, state, state->cursor-1, 1);
               --state->cursor;
            }
         }
         state->has_preferred_x = 0;
         break;
         
      case STB_TEXTEDIT_K_TEXTSTART:
         state->cursor = state->select_start = state->select_end = 0;
         state->has_preferred_x = 0;
         break;

      case STB_TEXTEDIT_K_TEXTEND:
         state->cursor = STB_TEXTEDIT_STRINGLEN(str);
         state->select_start = state->select_end = 0;
         state->has_preferred_x = 0;
         break;
        
      case STB_TEXTEDIT_K_TEXTSTART | STB_TEXTEDIT_K_SHIFT:
         stb_textedit_prep_selection_at_cursor(state);
         state->cursor = state->select_end = 0;
         state->has_preferred_x = 0;
         break;

      case STB_TEXTEDIT_K_TEXTEND | STB_TEXTEDIT_K_SHIFT:
         stb_textedit_prep_selection_at_cursor(state);
         state->cursor = state->select_end = STB_TEXTEDIT_STRINGLEN(str);
         state->has_preferred_x = 0;
         break;


      case STB_TEXTEDIT_K_LINESTART: {
         StbFindState find;
         stb_textedit_clamp(str, state);
         stb_textedit_move_to_first(state);
         stb_textedit_find_charpos(&find, str, state->cursor, state->single_line);
         state->cursor = find.first_char;
         state->has_preferred_x = 0;
         break;
      }

      case STB_TEXTEDIT_K_LINEEND: {
         StbFindState find;
         stb_textedit_clamp(str, state);
         stb_textedit_move_to_first(state);
         stb_textedit_find_charpos(&find, str, state->cursor, state->single_line);
         state->cursor = find.first_char + find.length;
         if (find.length > 0 && STB_TEXTEDIT_GETCHAR(str, state->cursor-1) == STB_TEXTEDIT_NEWLINE)
            state->cursor--;
         state->has_preferred_x = 0;
         break;
      }

      case STB_TEXTEDIT_K_LINESTART | STB_TEXTEDIT_K_SHIFT: {
         StbFindState find;
         stb_textedit_clamp(str, state);
         stb_textedit_prep_selection_at_cursor(state);
         stb_textedit_find_charpos(&find, str, state->cursor, state->single_line);
         state->cursor = state->select_end = find.first_char;
         state->has_preferred_x = 0;
         break;
      }

      case STB_TEXTEDIT_K_LINEEND | STB_TEXTEDIT_K_SHIFT: {
         StbFindState find;
         stb_textedit_clamp(str, state);
         stb_textedit_prep_selection_at_cursor(state);
         stb_textedit_find_charpos(&find, str, state->cursor, state->single_line);
         state->cursor = state->select_end = find.first_char + find.length;
         if (find.length > 0 && STB_TEXTEDIT_GETCHAR(str, state->cursor-1) == STB_TEXTEDIT_NEWLINE)
            state->cursor = state->select_end = state->cursor - 1;
         state->has_preferred_x = 0;
         break;
      }

// @TODO:
//    STB_TEXTEDIT_K_PGUP      - move cursor up a page
//    STB_TEXTEDIT_K_PGDOWN    - move cursor down a page
   }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x120, %rsp            # imm = 0x120
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl %edx, -0x14(%rbp)
movl -0x14(%rbp), %eax
movl %eax, -0x110(%rbp)
subl $0x10000, %eax          # imm = 0x10000
je 0x24add
jmp 0x2479c
movl -0x110(%rbp), %eax
subl $0x10001, %eax          # imm = 0x10001
je 0x24b1b
jmp 0x247af
movl -0x110(%rbp), %eax
subl $0x10002, %eax          # imm = 0x10002
je 0x24eaa
jmp 0x247c2
movl -0x110(%rbp), %eax
subl $0x10003, %eax          # imm = 0x10003
je 0x24d05
jmp 0x247d5
movl -0x110(%rbp), %eax
subl $0x10004, %eax          # imm = 0x10004
je 0x2520a
jmp 0x247e8
movl -0x110(%rbp), %eax
subl $0x10005, %eax          # imm = 0x10005
je 0x25257
jmp 0x247fb
movl -0x110(%rbp), %eax
subl $0x10006, %eax          # imm = 0x10006
je 0x25150
jmp 0x2480e
movl -0x110(%rbp), %eax
subl $0x10007, %eax          # imm = 0x10007
je 0x2517d
jmp 0x24821
movl -0x110(%rbp), %eax
subl $0x10008, %eax          # imm = 0x10008
je 0x25083
jmp 0x24834
movl -0x110(%rbp), %eax
subl $0x10009, %eax          # imm = 0x10009
je 0x250e6
jmp 0x24847
movl -0x110(%rbp), %eax
subl $0x1000a, %eax          # imm = 0x1000A
je 0x24aa9
jmp 0x2485a
movl -0x110(%rbp), %eax
subl $0x1000b, %eax          # imm = 0x1000B
je 0x24ac3
jmp 0x2486d
movl -0x110(%rbp), %eax
subl $0x1000c, %eax          # imm = 0x1000C
je 0x24ba6
jmp 0x24880
movl -0x110(%rbp), %eax
subl $0x1000d, %eax          # imm = 0x1000D
je 0x24be8
jmp 0x24893
movl -0x110(%rbp), %eax
subl $0x30000, %eax          # imm = 0x30000
je 0x24b5f
jmp 0x248a6
movl -0x110(%rbp), %eax
subl $0x30001, %eax          # imm = 0x30001
je 0x24cc8
jmp 0x248b9
movl -0x110(%rbp), %eax
subl $0x30002, %eax          # imm = 0x30002
je 0x24eaa
jmp 0x248cc
movl -0x110(%rbp), %eax
subl $0x30003, %eax          # imm = 0x30003
je 0x24d05
jmp 0x248df
movl -0x110(%rbp), %eax
subl $0x30004, %eax          # imm = 0x30004
je 0x252de
jmp 0x248f2
movl -0x110(%rbp), %eax
subl $0x30005, %eax          # imm = 0x30005
je 0x25332
jmp 0x24905
movl -0x110(%rbp), %eax
subl $0x30006, %eax          # imm = 0x30006
je 0x251b1
jmp 0x24918
movl -0x110(%rbp), %eax
subl $0x30007, %eax          # imm = 0x30007
je 0x251dc
jmp 0x2492b
movl -0x110(%rbp), %eax
subl $0x30008, %eax          # imm = 0x30008
je 0x25083
jmp 0x2493e
movl -0x110(%rbp), %eax
subl $0x30009, %eax          # imm = 0x30009
je 0x250e6
jmp 0x24951
movl -0x110(%rbp), %eax
subl $0x3000c, %eax          # imm = 0x3000C
je 0x24c2e
jmp 0x24964
movl -0x110(%rbp), %eax
subl $0x3000d, %eax          # imm = 0x3000D
je 0x24c7b
jmp 0x24977
movl -0x14(%rbp), %edi
callq 0x2b150
movl %eax, -0x18(%rbp)
cmpl $0x0, -0x18(%rbp)
jle 0x24aa4
movl -0x18(%rbp), %eax
movw %ax, -0x1a(%rbp)
cmpl $0xa, -0x18(%rbp)
jne 0x249a8
movq -0x10(%rbp), %rax
cmpb $0x0, 0x10(%rax)
je 0x249a8
jmp 0x253c6
movq -0x10(%rbp), %rax
cmpb $0x0, 0xc(%rax)
je 0x24a4e
movq -0x10(%rbp), %rax
movl 0x4(%rax), %eax
movq -0x10(%rbp), %rcx
cmpl 0x8(%rcx), %eax
jne 0x24a4e
movq -0x10(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x114(%rbp)
movq -0x8(%rbp), %rdi
callq 0x2b180
movl %eax, %ecx
movl -0x114(%rbp), %eax
cmpl %ecx, %eax
jge 0x24a4e
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x10(%rbp), %rax
movl (%rax), %edx
movl $0x1, %r8d
movl %r8d, %ecx
callq 0x2b1a0
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movl (%rax), %esi
movl $0x1, %edx
callq 0x2b220
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movl (%rax), %esi
leaq -0x1a(%rbp), %rdx
movl $0x1, %ecx
callq 0x2b2e0
testb $0x1, %al
jne 0x24a39
jmp 0x24a4c
movq -0x10(%rbp), %rax
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
movq -0x10(%rbp), %rax
movb $0x0, 0xf(%rax)
jmp 0x24aa2
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x2b400
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movl (%rax), %esi
leaq -0x1a(%rbp), %rdx
movl $0x1, %ecx
callq 0x2b2e0
testb $0x1, %al
jne 0x24a79
jmp 0x24aa0
movq -0x10(%rbp), %rdi
movq -0x10(%rbp), %rax
movl (%rax), %esi
movl $0x1, %edx
callq 0x2b4c0
movq -0x10(%rbp), %rax
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
movq -0x10(%rbp), %rax
movb $0x0, 0xf(%rax)
jmp 0x24aa2
jmp 0x24aa4
jmp 0x253c6
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x2b4f0
movq -0x10(%rbp), %rax
movb $0x0, 0xf(%rax)
jmp 0x253c6
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x2b750
movq -0x10(%rbp), %rax
movb $0x0, 0xf(%rax)
jmp 0x253c6
movq -0x10(%rbp), %rax
movl 0x4(%rax), %eax
movq -0x10(%rbp), %rcx
cmpl 0x8(%rcx), %eax
je 0x24af8
movq -0x10(%rbp), %rdi
callq 0x2b940
jmp 0x24b0e
movq -0x10(%rbp), %rax
cmpl $0x0, (%rax)
jle 0x24b0c
movq -0x10(%rbp), %rax
movl (%rax), %ecx
addl $-0x1, %ecx
movl %ecx, (%rax)
jmp 0x24b0e
movq -0x10(%rbp), %rax
movb $0x0, 0xf(%rax)
jmp 0x253c6
movq -0x10(%rbp), %rax
movl 0x4(%rax), %eax
movq -0x10(%rbp), %rcx
cmpl 0x8(%rcx), %eax
je 0x24b3a
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x2b990
jmp 0x24b45
movq -0x10(%rbp), %rax
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x2b9f0
movq -0x10(%rbp), %rax
movb $0x0, 0xf(%rax)
jmp 0x253c6
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x2b9f0
movq -0x10(%rbp), %rdi
callq 0x2ba90
movq -0x10(%rbp), %rax
cmpl $0x0, 0x8(%rax)
jle 0x24b8c
movq -0x10(%rbp), %rax
movl 0x8(%rax), %ecx
addl $-0x1, %ecx
movl %ecx, 0x8(%rax)
movq -0x10(%rbp), %rax
movl 0x8(%rax), %ecx
movq -0x10(%rbp), %rax
movl %ecx, (%rax)
movq -0x10(%rbp), %rax
movb $0x0, 0xf(%rax)
jmp 0x253c6
movq -0x10(%rbp), %rax
movl 0x4(%rax), %eax
movq -0x10(%rbp), %rcx
cmpl 0x8(%rcx), %eax
je 0x24bc1
movq -0x10(%rbp), %rdi
callq 0x2b940
jmp 0x24be3
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x2bad0
movl %eax, %ecx
movq -0x10(%rbp), %rax
movl %ecx, (%rax)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x2b9f0
jmp 0x253c6
movq -0x10(%rbp), %rax
movl 0x4(%rax), %eax
movq -0x10(%rbp), %rcx
cmpl 0x8(%rcx), %eax
je 0x24c07
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x2b990
jmp 0x24c29
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x2bb40
movl %eax, %ecx
movq -0x10(%rbp), %rax
movl %ecx, (%rax)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x2b9f0
jmp 0x253c6
movq -0x10(%rbp), %rax
movl 0x4(%rax), %eax
movq -0x10(%rbp), %rcx
cmpl 0x8(%rcx), %eax
jne 0x24c47
movq -0x10(%rbp), %rdi
callq 0x2ba90
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x2bad0
movl %eax, %ecx
movq -0x10(%rbp), %rax
movl %ecx, (%rax)
movq -0x10(%rbp), %rax
movl (%rax), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x8(%rax)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x2b9f0
jmp 0x253c6
movq -0x10(%rbp), %rax
movl 0x4(%rax), %eax
movq -0x10(%rbp), %rcx
cmpl 0x8(%rcx), %eax
jne 0x24c94
movq -0x10(%rbp), %rdi
callq 0x2ba90
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x2bb40
movl %eax, %ecx
movq -0x10(%rbp), %rax
movl %ecx, (%rax)
movq -0x10(%rbp), %rax
movl (%rax), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x8(%rax)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x2b9f0
jmp 0x253c6
movq -0x10(%rbp), %rdi
callq 0x2ba90
movq -0x10(%rbp), %rax
movl 0x8(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x8(%rax)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x2b9f0
movq -0x10(%rbp), %rax
movl 0x8(%rax), %ecx
movq -0x10(%rbp), %rax
movl %ecx, (%rax)
movq -0x10(%rbp), %rax
movb $0x0, 0xf(%rax)
jmp 0x253c6
movl -0x14(%rbp), %eax
andl $0x20000, %eax          # imm = 0x20000
cmpl $0x0, %eax
setne %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, -0x54(%rbp)
movq -0x10(%rbp), %rax
cmpb $0x0, 0x10(%rax)
je 0x24d3a
movl -0x14(%rbp), %eax
andl $0x20000, %eax          # imm = 0x20000
orl $0x10001, %eax          # imm = 0x10001
movl %eax, -0x14(%rbp)
jmp 0x24786
cmpl $0x0, -0x54(%rbp)
je 0x24d4b
movq -0x10(%rbp), %rdi
callq 0x2ba90
jmp 0x24d6a
movq -0x10(%rbp), %rax
movl 0x4(%rax), %eax
movq -0x10(%rbp), %rcx
cmpl 0x8(%rcx), %eax
je 0x24d68
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x2b990
jmp 0x24d6a
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x2b9f0
movq -0x8(%rbp), %rsi
movq -0x10(%rbp), %rax
movl (%rax), %edx
movq -0x10(%rbp), %rax
movzbl 0x10(%rax), %ecx
leaq -0x34(%rbp), %rdi
callq 0x2bbc0
cmpl $0x0, -0x24(%rbp)
je 0x24ea5
movq -0x10(%rbp), %rax
cmpb $0x0, 0xf(%rax)
je 0x24db9
movq -0x10(%rbp), %rax
movss 0x14(%rax), %xmm0
movss %xmm0, -0x118(%rbp)
jmp 0x24dc6
movss -0x34(%rbp), %xmm0
movss %xmm0, -0x118(%rbp)
movss -0x118(%rbp), %xmm0
movss %xmm0, -0x58(%rbp)
movl -0x28(%rbp), %eax
addl -0x24(%rbp), %eax
movl %eax, -0x60(%rbp)
movl -0x60(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, (%rax)
movq -0x8(%rbp), %rsi
movq -0x10(%rbp), %rax
movl (%rax), %edx
leaq -0x4c(%rbp), %rdi
callq 0x2bda0
movss -0x4c(%rbp), %xmm0
movss %xmm0, -0x5c(%rbp)
movl $0x0, -0x50(%rbp)
movl -0x50(%rbp), %eax
cmpl -0x38(%rbp), %eax
jge 0x24e6d
movq -0x8(%rbp), %rdi
movl -0x60(%rbp), %esi
movl -0x50(%rbp), %edx
callq 0x2be60
movss %xmm0, -0x64(%rbp)
movss -0x64(%rbp), %xmm0
movss 0x3624a(%rip), %xmm1    # 0x5b07c
ucomiss %xmm1, %xmm0
jne 0x24e3b
jp 0x24e3b
jmp 0x24e6d
movss -0x64(%rbp), %xmm0
addss -0x5c(%rbp), %xmm0
movss %xmm0, -0x5c(%rbp)
movss -0x5c(%rbp), %xmm0
ucomiss -0x58(%rbp), %xmm0
jbe 0x24e57
jmp 0x24e6d
movq -0x10(%rbp), %rax
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
movl -0x50(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x50(%rbp)
jmp 0x24e09
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x2b9f0
movq -0x10(%rbp), %rax
movb $0x1, 0xf(%rax)
movss -0x58(%rbp), %xmm0
movq -0x10(%rbp), %rax
movss %xmm0, 0x14(%rax)
cmpl $0x0, -0x54(%rbp)
je 0x24ea3
movq -0x10(%rbp), %rax
movl (%rax), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x8(%rax)
jmp 0x24ea5
jmp 0x253c6
movl -0x14(%rbp), %eax
andl $0x20000, %eax          # imm = 0x20000
cmpl $0x0, %eax
setne %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, -0x9c(%rbp)
movq -0x10(%rbp), %rax
cmpb $0x0, 0x10(%rax)
je 0x24ee2
movl -0x14(%rbp), %eax
andl $0x20000, %eax          # imm = 0x20000
orl $0x10000, %eax          # imm = 0x10000
movl %eax, -0x14(%rbp)
jmp 0x24786
cmpl $0x0, -0x9c(%rbp)
je 0x24ef6
movq -0x10(%rbp), %rdi
callq 0x2ba90
jmp 0x24f11
movq -0x10(%rbp), %rax
movl 0x4(%rax), %eax
movq -0x10(%rbp), %rcx
cmpl 0x8(%rcx), %eax
je 0x24f0f
movq -0x10(%rbp), %rdi
callq 0x2b940
jmp 0x24f11
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x2b9f0
movq -0x8(%rbp), %rsi
movq -0x10(%rbp), %rax
movl (%rax), %edx
movq -0x10(%rbp), %rax
movzbl 0x10(%rax), %ecx
leaq -0x7c(%rbp), %rdi
callq 0x2bbc0
movl -0x68(%rbp), %eax
cmpl -0x70(%rbp), %eax
je 0x2507e
movq -0x10(%rbp), %rax
cmpb $0x0, 0xf(%rax)
je 0x24f62
movq -0x10(%rbp), %rax
movss 0x14(%rax), %xmm0
movss %xmm0, -0x11c(%rbp)
jmp 0x24f6f
movss -0x7c(%rbp), %xmm0
movss %xmm0, -0x11c(%rbp)
movss -0x11c(%rbp), %xmm0
movss %xmm0, -0xa0(%rbp)
movl -0x68(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, (%rax)
movq -0x8(%rbp), %rsi
movq -0x10(%rbp), %rax
movl (%rax), %edx
leaq -0x94(%rbp), %rdi
callq 0x2bda0
movss -0x94(%rbp), %xmm0
movss %xmm0, -0xa4(%rbp)
movl $0x0, -0x98(%rbp)
movl -0x98(%rbp), %eax
cmpl -0x80(%rbp), %eax
jge 0x25040
movq -0x8(%rbp), %rdi
movl -0x68(%rbp), %esi
movl -0x98(%rbp), %edx
callq 0x2be60
movss %xmm0, -0xa8(%rbp)
movss -0xa8(%rbp), %xmm0
movss 0x3608f(%rip), %xmm1    # 0x5b07c
ucomiss %xmm1, %xmm0
jne 0x24ff6
jp 0x24ff6
jmp 0x25040
movss -0xa8(%rbp), %xmm0
addss -0xa4(%rbp), %xmm0
movss %xmm0, -0xa4(%rbp)
movss -0xa4(%rbp), %xmm0
ucomiss -0xa0(%rbp), %xmm0
jbe 0x25021
jmp 0x25040
movq -0x10(%rbp), %rax
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
movl -0x98(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x98(%rbp)
jmp 0x24fb8
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x2b9f0
movq -0x10(%rbp), %rax
movb $0x1, 0xf(%rax)
movss -0xa0(%rbp), %xmm0
movq -0x10(%rbp), %rax
movss %xmm0, 0x14(%rax)
cmpl $0x0, -0x9c(%rbp)
je 0x2507c
movq -0x10(%rbp), %rax
movl (%rax), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x8(%rax)
jmp 0x2507e
jmp 0x253c6
movq -0x10(%rbp), %rax
movl 0x4(%rax), %eax
movq -0x10(%rbp), %rcx
cmpl 0x8(%rcx), %eax
je 0x250a2
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x2b400
jmp 0x250d9
movq -0x8(%rbp), %rdi
callq 0x2b180
movl %eax, -0xac(%rbp)
movq -0x10(%rbp), %rax
movl (%rax), %eax
cmpl -0xac(%rbp), %eax
jge 0x250d7
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x10(%rbp), %rax
movl (%rax), %edx
movl $0x1, %ecx
callq 0x2bef0
jmp 0x250d9
movq -0x10(%rbp), %rax
movb $0x0, 0xf(%rax)
jmp 0x253c6
movq -0x10(%rbp), %rax
movl 0x4(%rax), %eax
movq -0x10(%rbp), %rcx
cmpl 0x8(%rcx), %eax
je 0x25105
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x2b400
jmp 0x25143
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x2b9f0
movq -0x10(%rbp), %rax
cmpl $0x0, (%rax)
jle 0x25141
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x10(%rbp), %rax
movl (%rax), %edx
subl $0x1, %edx
movl $0x1, %ecx
callq 0x2bef0
movq -0x10(%rbp), %rax
movl (%rax), %ecx
addl $-0x1, %ecx
movl %ecx, (%rax)
jmp 0x25143
movq -0x10(%rbp), %rax
movb $0x0, 0xf(%rax)
jmp 0x253c6
movq -0x10(%rbp), %rax
movl $0x0, 0x8(%rax)
movq -0x10(%rbp), %rax
movl $0x0, 0x4(%rax)
movq -0x10(%rbp), %rax
movl $0x0, (%rax)
movq -0x10(%rbp), %rax
movb $0x0, 0xf(%rax)
jmp 0x253c6
movq -0x8(%rbp), %rdi
callq 0x2b180
movl %eax, %ecx
movq -0x10(%rbp), %rax
movl %ecx, (%rax)
movq -0x10(%rbp), %rax
movl $0x0, 0x8(%rax)
movq -0x10(%rbp), %rax
movl $0x0, 0x4(%rax)
movq -0x10(%rbp), %rax
movb $0x0, 0xf(%rax)
jmp 0x253c6
movq -0x10(%rbp), %rdi
callq 0x2ba90
movq -0x10(%rbp), %rax
movl $0x0, 0x8(%rax)
movq -0x10(%rbp), %rax
movl $0x0, (%rax)
movq -0x10(%rbp), %rax
movb $0x0, 0xf(%rax)
jmp 0x253c6
movq -0x10(%rbp), %rdi
callq 0x2ba90
movq -0x8(%rbp), %rdi
callq 0x2b180
movl %eax, %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x8(%rax)
movq -0x10(%rbp), %rax
movl %ecx, (%rax)
movq -0x10(%rbp), %rax
movb $0x0, 0xf(%rax)
jmp 0x253c6
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x2b9f0
movq -0x10(%rbp), %rdi
callq 0x2b940
movq -0x8(%rbp), %rsi
movq -0x10(%rbp), %rax
movl (%rax), %edx
movq -0x10(%rbp), %rax
movzbl 0x10(%rax), %ecx
leaq -0xc4(%rbp), %rdi
callq 0x2bbc0
movl -0xb8(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, (%rax)
movq -0x10(%rbp), %rax
movb $0x0, 0xf(%rax)
jmp 0x253c6
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x2b9f0
movq -0x10(%rbp), %rdi
callq 0x2b940
movq -0x8(%rbp), %rsi
movq -0x10(%rbp), %rax
movl (%rax), %edx
movq -0x10(%rbp), %rax
movzbl 0x10(%rax), %ecx
leaq -0xdc(%rbp), %rdi
callq 0x2bbc0
movl -0xd0(%rbp), %ecx
addl -0xcc(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, (%rax)
cmpl $0x0, -0xcc(%rbp)
jle 0x252d1
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movl (%rax), %esi
subl $0x1, %esi
callq 0x2bf40
movzwl %ax, %eax
movzwl 0x54208(%rip), %ecx     # 0x794ca
cmpl %ecx, %eax
jne 0x252d1
movq -0x10(%rbp), %rax
movl (%rax), %ecx
addl $-0x1, %ecx
movl %ecx, (%rax)
movq -0x10(%rbp), %rax
movb $0x0, 0xf(%rax)
jmp 0x253c6
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x2b9f0
movq -0x10(%rbp), %rdi
callq 0x2ba90
movq -0x8(%rbp), %rsi
movq -0x10(%rbp), %rax
movl (%rax), %edx
movq -0x10(%rbp), %rax
movzbl 0x10(%rax), %ecx
leaq -0xf4(%rbp), %rdi
callq 0x2bbc0
movl -0xe8(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x8(%rax)
movq -0x10(%rbp), %rax
movl %ecx, (%rax)
movq -0x10(%rbp), %rax
movb $0x0, 0xf(%rax)
jmp 0x253c6
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x2b9f0
movq -0x10(%rbp), %rdi
callq 0x2ba90
movq -0x8(%rbp), %rsi
movq -0x10(%rbp), %rax
movl (%rax), %edx
movq -0x10(%rbp), %rax
movzbl 0x10(%rax), %ecx
leaq -0x10c(%rbp), %rdi
callq 0x2bbc0
movl -0x100(%rbp), %ecx
addl -0xfc(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x8(%rax)
movq -0x10(%rbp), %rax
movl %ecx, (%rax)
cmpl $0x0, -0xfc(%rbp)
jle 0x253be
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movl (%rax), %esi
subl $0x1, %esi
callq 0x2bf40
movzwl %ax, %eax
movzwl 0x54126(%rip), %ecx     # 0x794ca
cmpl %ecx, %eax
jne 0x253be
movq -0x10(%rbp), %rax
movl (%rax), %ecx
subl $0x1, %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x8(%rax)
movq -0x10(%rbp), %rax
movl %ecx, (%rax)
movq -0x10(%rbp), %rax
movb $0x0, 0xf(%rax)
addq $0x120, %rsp            # imm = 0x120
popq %rbp
retq
nop