// File: andrakis[P]alisp/contrib/linenoise-ng/src/linenoise.cpp
// Function: InputBuffer::incrementalHistorySearch(PromptBase&, int)
int InputBuffer::incrementalHistorySearch(PromptBase& pi, int startChar) {
  size_t bufferSize;
  size_t ucharCount = 0;

  // if not already recalling, add the current line to the history list so we
  // don't have to
  // special case it
  if (historyIndex == historyLen - 1) {
    free(history[historyLen - 1]);
    bufferSize = sizeof(char32_t) * len + 1;
    unique_ptr<char[]> tempBuffer(new char[bufferSize]);
    copyString32to8(tempBuffer.get(), bufferSize, buf32);
    history[historyLen - 1] = strdup8(tempBuffer.get());
  }
  int historyLineLength = len;
  int historyLinePosition = pos;
  char32_t emptyBuffer[1];
  char emptyWidths[1];
  InputBuffer empty(emptyBuffer, emptyWidths, 1);
  empty.refreshLine(pi);  // erase the old input first
  DynamicPrompt dp(pi, (startChar == ctrlChar('R')) ? -1 : 1);

  dp.promptPreviousLen = pi.promptPreviousLen;
  dp.promptPreviousInputLen = pi.promptPreviousInputLen;
  dynamicRefresh(dp, buf32, historyLineLength,
                 historyLinePosition);  // draw user's text with our prompt

  // loop until we get an exit character
  int c = 0;
  bool keepLooping = true;
  bool useSearchedLine = true;
  bool searchAgain = false;
  char32_t* activeHistoryLine = 0;
  while (keepLooping) {
    c = linenoiseReadChar();
    c = cleanupCtrl(c);  // convert CTRL + <char> into normal ctrl

    switch (c) {
      // these characters keep the selected text but do not execute it
      case ctrlChar('A'):  // ctrl-A, move cursor to start of line
      case HOME_KEY:
      case ctrlChar('B'):  // ctrl-B, move cursor left by one character
      case LEFT_ARROW_KEY:
      case META + 'b':  // meta-B, move cursor left by one word
      case META + 'B':
      case CTRL + LEFT_ARROW_KEY:
      case META + LEFT_ARROW_KEY:  // Emacs allows Meta, bash & readline don't
      case ctrlChar('D'):
      case META + 'd':  // meta-D, kill word to right of cursor
      case META + 'D':
      case ctrlChar('E'):  // ctrl-E, move cursor to end of line
      case END_KEY:
      case ctrlChar('F'):  // ctrl-F, move cursor right by one character
      case RIGHT_ARROW_KEY:
      case META + 'f':  // meta-F, move cursor right by one word
      case META + 'F':
      case CTRL + RIGHT_ARROW_KEY:
      case META + RIGHT_ARROW_KEY:  // Emacs allows Meta, bash & readline don't
      case META + ctrlChar('H'):
      case ctrlChar('J'):
      case ctrlChar('K'):  // ctrl-K, kill from cursor to end of line
      case ctrlChar('M'):
      case ctrlChar('N'):  // ctrl-N, recall next line in history
      case ctrlChar('P'):  // ctrl-P, recall previous line in history
      case DOWN_ARROW_KEY:
      case UP_ARROW_KEY:
      case ctrlChar('T'):  // ctrl-T, transpose characters
      case ctrlChar(
          'U'):  // ctrl-U, kill all characters to the left of the cursor
      case ctrlChar('W'):
      case META + 'y':  // meta-Y, "yank-pop", rotate popped text
      case META + 'Y':
      case 127:
      case DELETE_KEY:
      case META + '<':  // start of history
      case PAGE_UP_KEY:
      case META + '>':  // end of history
      case PAGE_DOWN_KEY:
        keepLooping = false;
        break;

      // these characters revert the input line to its previous state
      case ctrlChar('C'):  // ctrl-C, abort this line
      case ctrlChar('G'):
      case ctrlChar('L'):  // ctrl-L, clear screen and redisplay line
        keepLooping = false;
        useSearchedLine = false;
        if (c != ctrlChar('L')) {
          c = -1;  // ctrl-C and ctrl-G just abort the search and do nothing
                   // else
        }
        break;

      // these characters stay in search mode and update the display
      case ctrlChar('S'):
      case ctrlChar('R'):
        if (dp.searchTextLen ==
            0) {  // if no current search text, recall previous text
          if (previousSearchText.length()) {
            dp.updateSearchText(previousSearchText.get());
          }
        }
        if ((dp.direction == 1 && c == ctrlChar('R')) ||
            (dp.direction == -1 && c == ctrlChar('S'))) {
          dp.direction = 0 - dp.direction;  // reverse direction
          dp.updateSearchPrompt();          // change the prompt
        } else {
          searchAgain = true;  // same direction, search again
        }
        break;

// job control is its own thing
#ifndef _WIN32
      case ctrlChar('Z'):  // ctrl-Z, job control
        disableRawMode();  // Returning to Linux (whatever) shell, leave raw
                           // mode
        raise(SIGSTOP);    // Break out in mid-line
        enableRawMode();   // Back from Linux shell, re-enter raw mode
        {
          bufferSize = historyLineLength + 1;
          unique_ptr<char32_t[]> tempUnicode(new char32_t[bufferSize]);
          copyString8to32(tempUnicode.get(), bufferSize, ucharCount,
                          history[historyIndex]);
          dynamicRefresh(dp, tempUnicode.get(), historyLineLength,
                         historyLinePosition);
        }
        continue;
        break;
#endif

      // these characters update the search string, and hence the selected input
      // line
      case ctrlChar('H'):  // backspace/ctrl-H, delete char to left of cursor
        if (dp.searchTextLen > 0) {
          unique_ptr<char32_t[]> tempUnicode(new char32_t[dp.searchTextLen]);
          --dp.searchTextLen;
          dp.searchText[dp.searchTextLen] = 0;
          copyString32(tempUnicode.get(), dp.searchText.get(),
                       dp.searchTextLen);
          dp.updateSearchText(tempUnicode.get());
        } else {
          beep();
        }
        break;

      case ctrlChar('Y'):  // ctrl-Y, yank killed text
        break;

      default:
        if (!isControlChar(c) && c <= 0x0010FFFF) {  // not an action character
          unique_ptr<char32_t[]> tempUnicode(
              new char32_t[dp.searchTextLen + 2]);
          copyString32(tempUnicode.get(), dp.searchText.get(),
                       dp.searchTextLen);
          tempUnicode[dp.searchTextLen] = c;
          tempUnicode[dp.searchTextLen + 1] = 0;
          dp.updateSearchText(tempUnicode.get());
        } else {
          beep();
        }
    }  // switch

    // if we are staying in search mode, search now
    if (keepLooping) {
      bufferSize = historyLineLength + 1;
      if (activeHistoryLine) {
        delete[] activeHistoryLine;
        activeHistoryLine = nullptr;
      }
      activeHistoryLine = new char32_t[bufferSize];
      copyString8to32(activeHistoryLine, bufferSize, ucharCount,
                      history[historyIndex]);
      if (dp.searchTextLen > 0) {
        bool found = false;
        int historySearchIndex = historyIndex;
        int lineLength = static_cast<int>(ucharCount);
        int lineSearchPos = historyLinePosition;
        if (searchAgain) {
          lineSearchPos += dp.direction;
        }
        searchAgain = false;
        while (true) {
          while ((dp.direction > 0) ? (lineSearchPos < lineLength)
                                    : (lineSearchPos >= 0)) {
            if (strncmp32(dp.searchText.get(),
                          &activeHistoryLine[lineSearchPos],
                          dp.searchTextLen) == 0) {
              found = true;
              break;
            }
            lineSearchPos += dp.direction;
          }
          if (found) {
            historyIndex = historySearchIndex;
            historyLineLength = lineLength;
            historyLinePosition = lineSearchPos;
            break;
          } else if ((dp.direction > 0) ? (historySearchIndex < historyLen - 1)
                                        : (historySearchIndex > 0)) {
            historySearchIndex += dp.direction;
            bufferSize = strlen8(history[historySearchIndex]) + 1;
            delete[] activeHistoryLine;
            activeHistoryLine = nullptr;
            activeHistoryLine = new char32_t[bufferSize];
            copyString8to32(activeHistoryLine, bufferSize, ucharCount,
                            history[historySearchIndex]);
            lineLength = static_cast<int>(ucharCount);
            lineSearchPos =
                (dp.direction > 0) ? 0 : (lineLength - dp.searchTextLen);
          } else {
            beep();
            break;
          }
        };  // while
      }
      if (activeHistoryLine) {
        delete[] activeHistoryLine;
        activeHistoryLine = nullptr;
      }
      bufferSize = historyLineLength + 1;
      activeHistoryLine = new char32_t[bufferSize];
      copyString8to32(activeHistoryLine, bufferSize, ucharCount,
                      history[historyIndex]);
      dynamicRefresh(dp, activeHistoryLine, historyLineLength,
                     historyLinePosition);  // draw user's text with our prompt
    }
  }  // while

  // leaving history search, restore previous prompt, maybe make searched line
  // current
  PromptBase pb;
  pb.promptChars = pi.promptIndentation;
  pb.promptBytes = pi.promptBytes;
  Utf32String tempUnicode(pb.promptBytes + 1);

  copyString32(tempUnicode.get(), &pi.promptText[pi.promptLastLinePosition],
               pb.promptBytes - pi.promptLastLinePosition);
  tempUnicode.initFromBuffer();
  pb.promptText = tempUnicode;
  pb.promptExtraLines = 0;
  pb.promptIndentation = pi.promptIndentation;
  pb.promptLastLinePosition = 0;
  pb.promptPreviousInputLen = historyLineLength;
  pb.promptCursorRowOffset = dp.promptCursorRowOffset;
  pb.promptScreenColumns = pi.promptScreenColumns;
  pb.promptPreviousLen = dp.promptChars;
  if (useSearchedLine && activeHistoryLine) {
    historyRecallMostRecent = true;
    copyString32(buf32, activeHistoryLine, buflen + 1);
    len = historyLineLength;
    pos = historyLinePosition;
  }
  if (activeHistoryLine) {
    delete[] activeHistoryLine;
    activeHistoryLine = nullptr;
  }
  dynamicRefresh(pb, buf32, len,
                 pos);  // redraw the original prompt with current input
  pi.promptPreviousInputLen = len;
  pi.promptCursorRowOffset = pi.promptExtraLines + pb.promptCursorRowOffset;
  previousSearchText =
      dp.searchText;  // save search text for possible reuse on ctrl-R ctrl-R
  return c;           // pass a character or -1 back to main loop
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x290, %rsp            # imm = 0x290
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl %edx, -0x14(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x160(%rbp)
movq $0x0, -0x28(%rbp)
movl 0x38e19(%rip), %eax     # 0x57aa8
movl 0x38e03(%rip), %ecx     # 0x57a98
subl $0x1, %ecx
cmpl %ecx, %eax
jne 0x1ed6f
movq 0x38de9(%rip), %rax     # 0x57a90
movl 0x38deb(%rip), %ecx     # 0x57a98
decl %ecx
movslq %ecx, %rcx
movq (%rax,%rcx,8), %rdi
callq 0x8510
movq -0x160(%rbp), %rax
movslq 0x14(%rax), %rax
leaq 0x1(,%rax,4), %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rdi
callq 0x8040
movq %rax, %rsi
leaq -0x30(%rbp), %rdi
movq %rdi, -0x168(%rbp)
callq 0x23f80
movq -0x168(%rbp), %rdi
callq 0x23fb0
movq %rax, %rdi
movq -0x160(%rbp), %rax
movq -0x20(%rbp), %rsi
movq (%rax), %rdx
callq 0x1fbb0
jmp 0x1ed12
leaq -0x30(%rbp), %rdi
callq 0x23fb0
movq %rax, %rdi
callq 0x1fc10
movq %rax, -0x170(%rbp)
jmp 0x1ed2c
movq -0x170(%rbp), %rdx
movq 0x38d56(%rip), %rax     # 0x57a90
movl 0x38d58(%rip), %ecx     # 0x57a98
subl $0x1, %ecx
movslq %ecx, %rcx
movq %rdx, (%rax,%rcx,8)
leaq -0x30(%rbp), %rdi
callq 0x23fe0
jmp 0x1ed6f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
leaq -0x30(%rbp), %rdi
callq 0x23fe0
jmp 0x1fba4
movq -0x160(%rbp), %rax
movl 0x14(%rax), %ecx
movl %ecx, -0x40(%rbp)
movl 0x18(%rax), %eax
movl %eax, -0x44(%rbp)
leaq -0x70(%rbp), %rdi
movq %rdi, -0x180(%rbp)
leaq -0x48(%rbp), %rsi
leaq -0x49(%rbp), %rdx
movl $0x1, %ecx
callq 0x24040
movq -0x180(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x1d280
movq -0x10(%rbp), %rsi
movl -0x14(%rbp), %eax
subl $0x12, %eax
setne %al
movzbl %al, %ecx
movl %ecx, %eax
leal -0x1(%rax,%rax), %edx
leaq -0xd0(%rbp), %rdi
movq %rdi, -0x178(%rbp)
callq 0x24090
movq -0x160(%rbp), %rax
movq -0x178(%rbp), %rdi
movq -0x10(%rbp), %rcx
movl 0x38(%rcx), %ecx
movl %ecx, -0x98(%rbp)
movq -0x10(%rbp), %rcx
movl 0x2c(%rcx), %ecx
movl %ecx, -0xa4(%rbp)
movq (%rax), %rsi
movl -0x40(%rbp), %edx
movl -0x44(%rbp), %ecx
callq 0x1fc30
jmp 0x1ee10
movl $0x0, -0xd4(%rbp)
movb $0x1, -0xd5(%rbp)
movb $0x1, -0xd6(%rbp)
movb $0x0, -0xd7(%rbp)
movq $0x0, -0xe0(%rbp)
testb $0x1, -0xd5(%rbp)
je 0x1f943
callq 0x1e8d0
movl %eax, -0x184(%rbp)
jmp 0x1ee54
movl -0x184(%rbp), %eax
movl %eax, -0xd4(%rbp)
movl -0xd4(%rbp), %edi
callq 0x1eac0
movl %eax, -0x188(%rbp)
jmp 0x1ee73
movl -0x188(%rbp), %eax
movl %eax, -0xd4(%rbp)
movl -0xd4(%rbp), %eax
movl %eax, -0x18c(%rbp)
decl %eax
subl $0x2, %eax
jb 0x1f151
jmp 0x1ee98
movl -0x18c(%rbp), %eax
subl $0x3, %eax
je 0x1f15d
jmp 0x1eea9
movl -0x18c(%rbp), %eax
addl $-0x4, %eax
subl $0x3, %eax
jb 0x1f151
jmp 0x1eebd
movl -0x18c(%rbp), %eax
subl $0x7, %eax
je 0x1f15d
jmp 0x1eece
movl -0x18c(%rbp), %eax
subl $0x8, %eax
je 0x1f301
jmp 0x1eedf
movl -0x18c(%rbp), %eax
addl $-0xa, %eax
subl $0x2, %eax
jb 0x1f151
jmp 0x1eef3
movl -0x18c(%rbp), %eax
subl $0xc, %eax
je 0x1f15d
jmp 0x1ef04
movl -0x18c(%rbp), %eax
addl $-0xd, %eax
subl $0x2, %eax
jb 0x1f151
jmp 0x1ef18
movl -0x18c(%rbp), %eax
subl $0x10, %eax
je 0x1f151
jmp 0x1ef29
movl -0x18c(%rbp), %eax
addl $-0x12, %eax
subl $0x2, %eax
jb 0x1f183
jmp 0x1ef3d
movl -0x18c(%rbp), %eax
addl $-0x14, %eax
subl $0x2, %eax
jb 0x1f151
jmp 0x1ef51
movl -0x18c(%rbp), %eax
subl $0x17, %eax
je 0x1f151
jmp 0x1ef62
movl -0x18c(%rbp), %eax
subl $0x19, %eax
je 0x1f40b
jmp 0x1ef73
movl -0x18c(%rbp), %eax
subl $0x1a, %eax
je 0x1f21b
jmp 0x1ef84
movl -0x18c(%rbp), %eax
subl $0x7f, %eax
je 0x1f151
jmp 0x1ef95
movl -0x18c(%rbp), %eax
subl $0x10200000, %eax       # imm = 0x10200000
je 0x1f151
jmp 0x1efa8
movl -0x18c(%rbp), %eax
subl $0x10400000, %eax       # imm = 0x10400000
je 0x1f151
jmp 0x1efbb
movl -0x18c(%rbp), %eax
subl $0x10600000, %eax       # imm = 0x10600000
je 0x1f151
jmp 0x1efce
movl -0x18c(%rbp), %eax
subl $0x10800000, %eax       # imm = 0x10800000
je 0x1f151
jmp 0x1efe1
movl -0x18c(%rbp), %eax
subl $0x10a00000, %eax       # imm = 0x10A00000
je 0x1f151
jmp 0x1eff4
movl -0x18c(%rbp), %eax
subl $0x10c00000, %eax       # imm = 0x10C00000
je 0x1f151
jmp 0x1f007
movl -0x18c(%rbp), %eax
subl $0x10e00000, %eax       # imm = 0x10E00000
je 0x1f151
jmp 0x1f01a
movl -0x18c(%rbp), %eax
subl $0x11000000, %eax       # imm = 0x11000000
je 0x1f151
jmp 0x1f02d
movl -0x18c(%rbp), %eax
subl $0x11200000, %eax       # imm = 0x11200000
je 0x1f151
jmp 0x1f040
movl -0x18c(%rbp), %eax
subl $0x30600000, %eax       # imm = 0x30600000
je 0x1f151
jmp 0x1f053
movl -0x18c(%rbp), %eax
subl $0x30800000, %eax       # imm = 0x30800000
je 0x1f151
jmp 0x1f066
movl -0x18c(%rbp), %eax
subl $0x40000008, %eax       # imm = 0x40000008
je 0x1f151
jmp 0x1f079
movl -0x18c(%rbp), %eax
subl $0x4000003c, %eax       # imm = 0x4000003C
je 0x1f151
jmp 0x1f08c
movl -0x18c(%rbp), %eax
subl $0x4000003e, %eax       # imm = 0x4000003E
je 0x1f151
jmp 0x1f09f
movl -0x18c(%rbp), %eax
subl $0x40000042, %eax       # imm = 0x40000042
je 0x1f151
jmp 0x1f0b2
movl -0x18c(%rbp), %eax
subl $0x40000044, %eax       # imm = 0x40000044
je 0x1f151
jmp 0x1f0c5
movl -0x18c(%rbp), %eax
subl $0x40000046, %eax       # imm = 0x40000046
je 0x1f151
jmp 0x1f0d4
movl -0x18c(%rbp), %eax
subl $0x40000059, %eax       # imm = 0x40000059
je 0x1f151
jmp 0x1f0e3
movl -0x18c(%rbp), %eax
subl $0x40000062, %eax       # imm = 0x40000062
je 0x1f151
jmp 0x1f0f2
movl -0x18c(%rbp), %eax
subl $0x40000064, %eax       # imm = 0x40000064
je 0x1f151
jmp 0x1f101
movl -0x18c(%rbp), %eax
subl $0x40000066, %eax       # imm = 0x40000066
je 0x1f151
jmp 0x1f110
movl -0x18c(%rbp), %eax
subl $0x40000079, %eax       # imm = 0x40000079
je 0x1f151
jmp 0x1f11f
movl -0x18c(%rbp), %eax
subl $0x50600000, %eax       # imm = 0x50600000
je 0x1f151
jmp 0x1f12e
movl -0x18c(%rbp), %eax
subl $0x50800000, %eax       # imm = 0x50800000
je 0x1f151
jmp 0x1f410
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
jmp 0x1fb98
movb $0x0, -0xd5(%rbp)
jmp 0x1f57b
movb $0x0, -0xd5(%rbp)
movb $0x0, -0xd6(%rbp)
cmpl $0xc, -0xd4(%rbp)
je 0x1f17e
movl $0xffffffff, -0xd4(%rbp) # imm = 0xFFFFFFFF
jmp 0x1f57b
cmpl $0x0, -0x78(%rbp)
jne 0x1f1d9
leaq 0x388b0(%rip), %rdi     # 0x57a40
callq 0x23df0
movq %rax, -0x198(%rbp)
jmp 0x1f19e
movq -0x198(%rbp), %rax
cmpq $0x0, %rax
je 0x1f1d7
leaq 0x3888e(%rip), %rdi     # 0x57a40
callq 0x23ec0
movq %rax, -0x1a0(%rbp)
jmp 0x1f1c0
movq -0x1a0(%rbp), %rsi
leaq -0xd0(%rbp), %rdi
callq 0x242c0
jmp 0x1f1d5
jmp 0x1f1d7
jmp 0x1f1d9
cmpl $0x1, -0x74(%rbp)
jne 0x1f1e8
cmpl $0x12, -0xd4(%rbp)
je 0x1f1f7
cmpl $-0x1, -0x74(%rbp)
jne 0x1f20f
cmpl $0x13, -0xd4(%rbp)
jne 0x1f20f
movl -0x74(%rbp), %eax
negl %eax
movl %eax, -0x74(%rbp)
leaq -0xd0(%rbp), %rdi
callq 0x24350
jmp 0x1f20d
jmp 0x1f216
movb $0x1, -0xd7(%rbp)
jmp 0x1f57b
callq 0x1fed0
jmp 0x1f222
movl $0x13, %edi
callq 0x8410
callq 0x1ff10
jmp 0x1f233
movl -0x40(%rbp), %eax
incl %eax
cltq
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rax
movl $0x4, %ecx
mulq %rcx
movq %rax, %rdi
movq $-0x1, %rax
cmovoq %rax, %rdi
callq 0x8040
movq %rax, -0x1a8(%rbp)
jmp 0x1f266
movq -0x1a8(%rbp), %rsi
leaq -0xe8(%rbp), %rdi
movq %rdi, -0x1b0(%rbp)
callq 0x244d0
movq -0x1b0(%rbp), %rdi
callq 0x24500
movq %rax, %rdi
movq -0x20(%rbp), %rsi
movq 0x387f6(%rip), %rax     # 0x57a90
movslq 0x38807(%rip), %rcx     # 0x57aa8
movq (%rax,%rcx,8), %rcx
leaq -0x28(%rbp), %rdx
callq 0x1ffe0
jmp 0x1f2b0
leaq -0xe8(%rbp), %rdi
callq 0x24500
movq %rax, %rsi
movl -0x40(%rbp), %edx
movl -0x44(%rbp), %ecx
leaq -0xd0(%rbp), %rdi
callq 0x1fc30
jmp 0x1f2d3
leaq -0xe8(%rbp), %rdi
callq 0x24530
jmp 0x1ee3a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
leaq -0xe8(%rbp), %rdi
callq 0x24530
jmp 0x1fb98
cmpl $0x0, -0x78(%rbp)
jle 0x1f3fd
movslq -0x78(%rbp), %rax
movl $0x4, %ecx
mulq %rcx
movq %rax, %rdi
movq $-0x1, %rax
cmovoq %rax, %rdi
callq 0x8040
movq %rax, -0x1b8(%rbp)
jmp 0x1f333
movq -0x1b8(%rbp), %rsi
leaq -0xf0(%rbp), %rdi
callq 0x244d0
movl -0x78(%rbp), %eax
decl %eax
movl %eax, -0x78(%rbp)
leaq -0x90(%rbp), %rdi
movslq -0x78(%rbp), %rsi
callq 0x23e10
movq %rax, -0x1c0(%rbp)
jmp 0x1f367
movq -0x1c0(%rbp), %rax
movl $0x0, (%rax)
leaq -0xf0(%rbp), %rdi
callq 0x24500
movq %rax, -0x1d0(%rbp)
leaq -0x90(%rbp), %rdi
callq 0x23ec0
movq %rax, -0x1c8(%rbp)
jmp 0x1f39c
movq -0x1c8(%rbp), %rsi
movq -0x1d0(%rbp), %rdi
movslq -0x78(%rbp), %rdx
callq 0x1e860
jmp 0x1f3b5
leaq -0xf0(%rbp), %rdi
callq 0x24500
movq %rax, %rsi
leaq -0xd0(%rbp), %rdi
callq 0x242c0
jmp 0x1f3d2
leaq -0xf0(%rbp), %rdi
callq 0x24530
jmp 0x1f406
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
leaq -0xf0(%rbp), %rdi
callq 0x24530
jmp 0x1fb98
callq 0x1e810
jmp 0x1f404
jmp 0x1f406
jmp 0x1f57b
jmp 0x1f57b
movl -0xd4(%rbp), %edi
callq 0x20020
movb %al, -0x1d1(%rbp)
jmp 0x1f423
movb -0x1d1(%rbp), %al
testb $0x1, %al
jne 0x1f570
jmp 0x1f433
cmpl $0x10ffff, -0xd4(%rbp)  # imm = 0x10FFFF
jg 0x1f570
movl -0x78(%rbp), %eax
addl $0x2, %eax
cltq
movl $0x4, %ecx
mulq %rcx
movq %rax, %rdi
movq $-0x1, %rax
cmovoq %rax, %rdi
callq 0x8040
movq %rax, -0x1e0(%rbp)
jmp 0x1f46f
movq -0x1e0(%rbp), %rsi
leaq -0xf8(%rbp), %rdi
movq %rdi, -0x1f8(%rbp)
callq 0x244d0
movq -0x1f8(%rbp), %rdi
callq 0x24500
movq %rax, -0x1f0(%rbp)
leaq -0x90(%rbp), %rdi
callq 0x23ec0
movq %rax, -0x1e8(%rbp)
jmp 0x1f4b1
movq -0x1e8(%rbp), %rsi
movq -0x1f0(%rbp), %rdi
movslq -0x78(%rbp), %rdx
callq 0x1e860
jmp 0x1f4ca
movl -0xd4(%rbp), %eax
movl %eax, -0x204(%rbp)
movslq -0x78(%rbp), %rsi
leaq -0xf8(%rbp), %rdi
callq 0x24590
movq %rax, -0x200(%rbp)
jmp 0x1f4ef
movq -0x200(%rbp), %rax
movl -0x204(%rbp), %ecx
movl %ecx, (%rax)
movl -0x78(%rbp), %eax
incl %eax
movslq %eax, %rsi
leaq -0xf8(%rbp), %rdi
callq 0x24590
movq %rax, -0x210(%rbp)
jmp 0x1f51b
movq -0x210(%rbp), %rax
movl $0x0, (%rax)
leaq -0xf8(%rbp), %rdi
callq 0x24500
movq %rax, %rsi
leaq -0xd0(%rbp), %rdi
callq 0x242c0
jmp 0x1f545
leaq -0xf8(%rbp), %rdi
callq 0x24530
jmp 0x1f579
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
leaq -0xf8(%rbp), %rdi
callq 0x24530
jmp 0x1fb98
callq 0x1e810
jmp 0x1f577
jmp 0x1f579
jmp 0x1f57b
testb $0x1, -0xd5(%rbp)
je 0x1f93e
movl -0x40(%rbp), %eax
addl $0x1, %eax
cltq
movq %rax, -0x20(%rbp)
cmpq $0x0, -0xe0(%rbp)
je 0x1f5c9
movq -0xe0(%rbp), %rax
movq %rax, -0x218(%rbp)
cmpq $0x0, %rax
je 0x1f5be
movq -0x218(%rbp), %rdi
callq 0x85a0
movq $0x0, -0xe0(%rbp)
movq -0x20(%rbp), %rax
movl $0x4, %ecx
mulq %rcx
movq %rax, %rdi
movq $-0x1, %rax
cmovoq %rax, %rdi
callq 0x8040
movq %rax, -0x220(%rbp)
jmp 0x1f5f1
movq -0x220(%rbp), %rax
movq %rax, -0xe0(%rbp)
movq -0xe0(%rbp), %rdi
movq -0x20(%rbp), %rsi
movq 0x3847f(%rip), %rax     # 0x57a90
movslq 0x38490(%rip), %rcx     # 0x57aa8
movq (%rax,%rcx,8), %rcx
leaq -0x28(%rbp), %rdx
callq 0x1ffe0
jmp 0x1f627
cmpl $0x0, -0x78(%rbp)
jle 0x1f883
movb $0x0, -0xf9(%rbp)
movl 0x3846a(%rip), %eax     # 0x57aa8
movl %eax, -0x100(%rbp)
movq -0x28(%rbp), %rax
movl %eax, -0x104(%rbp)
movl -0x44(%rbp), %eax
movl %eax, -0x108(%rbp)
testb $0x1, -0xd7(%rbp)
je 0x1f66f
movl -0x74(%rbp), %eax
addl -0x108(%rbp), %eax
movl %eax, -0x108(%rbp)
movb $0x0, -0xd7(%rbp)
jmp 0x1f678
jmp 0x1f67a
cmpl $0x0, -0x74(%rbp)
jle 0x1f697
movl -0x108(%rbp), %eax
cmpl -0x104(%rbp), %eax
setl %al
movb %al, -0x221(%rbp)
jmp 0x1f6a7
cmpl $0x0, -0x108(%rbp)
setge %al
movb %al, -0x221(%rbp)
movb -0x221(%rbp), %al
testb $0x1, %al
jne 0x1f6b3
jmp 0x1f71a
leaq -0x90(%rbp), %rdi
callq 0x23ec0
movq %rax, -0x230(%rbp)
jmp 0x1f6c8
movq -0x230(%rbp), %rdi
movq -0xe0(%rbp), %rax
movslq -0x108(%rbp), %rcx
leaq (%rax,%rcx,4), %rsi
movslq -0x78(%rbp), %rdx
callq 0x20060
movl %eax, -0x234(%rbp)
jmp 0x1f6f2
movl -0x234(%rbp), %eax
cmpl $0x0, %eax
jne 0x1f706
movb $0x1, -0xf9(%rbp)
jmp 0x1f71a
movl -0x74(%rbp), %eax
addl -0x108(%rbp), %eax
movl %eax, -0x108(%rbp)
jmp 0x1f67a
testb $0x1, -0xf9(%rbp)
je 0x1f746
movl -0x100(%rbp), %eax
movl %eax, 0x38379(%rip)     # 0x57aa8
movl -0x104(%rbp), %eax
movl %eax, -0x40(%rbp)
movl -0x108(%rbp), %eax
movl %eax, -0x44(%rbp)
jmp 0x1f881
cmpl $0x0, -0x74(%rbp)
jle 0x1f764
movl -0x100(%rbp), %eax
movl 0x38340(%rip), %ecx     # 0x57a98
subl $0x1, %ecx
cmpl %ecx, %eax
jl 0x1f771
jmp 0x1f871
cmpl $0x0, -0x100(%rbp)
jle 0x1f871
movl -0x74(%rbp), %ecx
movl -0x100(%rbp), %eax
addl %ecx, %eax
movl %eax, -0x100(%rbp)
movq 0x38307(%rip), %rax     # 0x57a90
movslq -0x100(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x200f0
movq %rax, -0x240(%rbp)
jmp 0x1f7a2
movq -0x240(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x20(%rbp)
movq -0xe0(%rbp), %rax
movq %rax, -0x248(%rbp)
cmpq $0x0, %rax
je 0x1f7d1
movq -0x248(%rbp), %rdi
callq 0x85a0
movq $0x0, -0xe0(%rbp)
movq -0x20(%rbp), %rax
movl $0x4, %ecx
mulq %rcx
movq %rax, %rdi
movq $-0x1, %rax
cmovoq %rax, %rdi
callq 0x8040
movq %rax, -0x250(%rbp)
jmp 0x1f804
movq -0x250(%rbp), %rax
movq %rax, -0xe0(%rbp)
movq -0xe0(%rbp), %rdi
movq -0x20(%rbp), %rsi
movq 0x3826c(%rip), %rax     # 0x57a90
movslq -0x100(%rbp), %rcx
movq (%rax,%rcx,8), %rcx
leaq -0x28(%rbp), %rdx
callq 0x1ffe0
jmp 0x1f83a
movq -0x28(%rbp), %rax
movl %eax, -0x104(%rbp)
cmpl $0x0, -0x74(%rbp)
jle 0x1f854
xorl %eax, %eax
movl %eax, -0x254(%rbp)
jmp 0x1f863
movl -0x104(%rbp), %eax
subl -0x78(%rbp), %eax
movl %eax, -0x254(%rbp)
movl -0x254(%rbp), %eax
movl %eax, -0x108(%rbp)
jmp 0x1f87a
callq 0x1e810
jmp 0x1f878
jmp 0x1f881
jmp 0x1f87c
jmp 0x1f676
jmp 0x1f883
cmpq $0x0, -0xe0(%rbp)
je 0x1f8b8
movq -0xe0(%rbp), %rax
movq %rax, -0x260(%rbp)
cmpq $0x0, %rax
je 0x1f8ad
movq -0x260(%rbp), %rdi
callq 0x85a0
movq $0x0, -0xe0(%rbp)
movl -0x40(%rbp), %eax
incl %eax
cltq
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rax
movl $0x4, %ecx
mulq %rcx
movq %rax, %rdi
movq $-0x1, %rax
cmovoq %rax, %rdi
callq 0x8040
movq %rax, -0x268(%rbp)
jmp 0x1f8eb
movq -0x268(%rbp), %rax
movq %rax, -0xe0(%rbp)
movq -0xe0(%rbp), %rdi
movq -0x20(%rbp), %rsi
movq 0x38185(%rip), %rax     # 0x57a90
movslq 0x38196(%rip), %rcx     # 0x57aa8
movq (%rax,%rcx,8), %rcx
leaq -0x28(%rbp), %rdx
callq 0x1ffe0
jmp 0x1f921
movq -0xe0(%rbp), %rsi
movl -0x40(%rbp), %edx
movl -0x44(%rbp), %ecx
leaq -0xd0(%rbp), %rdi
callq 0x1fc30
jmp 0x1f93c
jmp 0x1f93e
jmp 0x1ee3a
leaq -0x148(%rbp), %rdi
callq 0x245d0
jmp 0x1f951
movq -0x10(%rbp), %rax
movl 0x24(%rax), %eax
movl %eax, -0x130(%rbp)
movq -0x10(%rbp), %rax
movl 0x1c(%rax), %eax
movl %eax, -0x12c(%rbp)
movl -0x12c(%rbp), %esi
incl %esi
leaq -0x158(%rbp), %rdi
callq 0x23e40
jmp 0x1f981
leaq -0x158(%rbp), %rdi
callq 0x23ec0
movq %rax, -0x270(%rbp)
jmp 0x1f996
movq -0x10(%rbp), %rdi
movslq 0x28(%rdi), %rsi
callq 0x23e10
movq %rax, -0x278(%rbp)
jmp 0x1f9ac
movq -0x278(%rbp), %rsi
movq -0x270(%rbp), %rdi
movl -0x12c(%rbp), %eax
movq -0x10(%rbp), %rcx
movl 0x28(%rcx), %ecx
subl %ecx, %eax
movslq %eax, %rdx
callq 0x1e860
jmp 0x1f9d3
leaq -0x158(%rbp), %rdi
callq 0x24600
jmp 0x1f9e1
leaq -0x148(%rbp), %rdi
leaq -0x158(%rbp), %rsi
callq 0x24640
jmp 0x1f9f6
movl $0x0, -0x128(%rbp)
movq -0x10(%rbp), %rax
movl 0x24(%rax), %eax
movl %eax, -0x124(%rbp)
movl $0x0, -0x120(%rbp)
movl -0x40(%rbp), %eax
movl %eax, -0x11c(%rbp)
movl -0xa0(%rbp), %eax
movl %eax, -0x118(%rbp)
movq -0x10(%rbp), %rax
movl 0x34(%rax), %eax
movl %eax, -0x114(%rbp)
movl -0xb8(%rbp), %eax
movl %eax, -0x110(%rbp)
testb $0x1, -0xd6(%rbp)
je 0x1fac2
cmpq $0x0, -0xe0(%rbp)
je 0x1fac2
movq -0x160(%rbp), %rax
movb $0x1, 0x38046(%rip)     # 0x57aac
movq (%rax), %rdi
movq -0xe0(%rbp), %rsi
movl 0x10(%rax), %eax
incl %eax
movslq %eax, %rdx
callq 0x1e860
jmp 0x1fa7f
movq -0x160(%rbp), %rax
movl -0x40(%rbp), %ecx
movl %ecx, 0x14(%rax)
movl -0x44(%rbp), %ecx
movl %ecx, 0x18(%rax)
jmp 0x1fac2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
jmp 0x1fb8c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x38(%rbp)
movl %eax, -0x3c(%rbp)
leaq -0x158(%rbp), %rdi
callq 0x23b50
jmp 0x1fb8c
cmpq $0x0, -0xe0(%rbp)
je 0x1faf7
movq -0xe0(%rbp), %rax
movq %rax, -0x280(%rbp)
cmpq $0x0, %rax
je 0x1faec
movq -0x280(%rbp), %rdi
callq 0x85a0
movq $0x0, -0xe0(%rbp)
movq -0x160(%rbp), %rax
movq (%rax), %rsi
movl 0x14(%rax), %edx
movl 0x18(%rax), %ecx
leaq -0x148(%rbp), %rdi
callq 0x1fc30
jmp 0x1fb15
movq -0x160(%rbp), %rax
movl 0x14(%rax), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x2c(%rax)
movq -0x10(%rbp), %rax
movl 0x20(%rax), %ecx
movl -0x118(%rbp), %edx
addl %edx, %ecx
movl %ecx, 0x30(%rax)
leaq -0x90(%rbp), %rsi
leaq 0x37efa(%rip), %rdi     # 0x57a40
callq 0x24640
jmp 0x1fb4d
movl -0xd4(%rbp), %eax
movl %eax, -0x284(%rbp)
leaq -0x158(%rbp), %rdi
callq 0x23b50
leaq -0x148(%rbp), %rdi
callq 0x24700
leaq -0xd0(%rbp), %rdi
callq 0x24720
movl -0x284(%rbp), %eax
addq $0x290, %rsp            # imm = 0x290
popq %rbp
retq
leaq -0x148(%rbp), %rdi
callq 0x24700
leaq -0xd0(%rbp), %rdi
callq 0x24720
movq -0x38(%rbp), %rdi
callq 0x87b0
nopl (%rax)