// File: BenLangmead[P]bowtie/./ebwt_search_backtrack.h
// Function: EbwtRangeSource::advanceBranch(int, unsigned short, PathManager&)
virtual void
	advanceBranch(int until, uint16_t minCost, PathManager& pm) {
		assert(curEbwt_ != NULL);

		// Let this->foundRange = false; we'll set it to true iff this call
		// to advance yielded a new valid-alignment range.
		this->foundRange = false;

		// Can't have already exceeded weighted hamming distance threshold
		assert_gt(qry_->length(), 0);
		assert_leq(qlen_, qry_->length());
		assert_geq(qual_->length(), qry_->length());
		assert(!pm.empty());

		do {
			assert(pm.repOk());
			// Get the highest-priority branch according to the priority
			// queue in 'pm'
			Branch* br = pm.front();
			// Shouldn't be curtailed or exhausted
			assert(!br->exhausted_);
			assert(!br->curtailed_);
			assert_gt(br->depth3_, 0);
			assert_leq(br->ham_, qualLim_);
			if(verbose_) {
				br->print(*qry_, *qual_, minCost, cout, (halfAndHalf_>0), partial_, fw_, ebwt_->fw());
				if(!br->edits_.empty()) {
					cout << "Edit: ";
					for(size_t i = 0; i < br->edits_.size(); i++) {
						Edit e = br->edits_.get(i);
						cout << (curEbwt_->fw() ? (qlen_ - e.pos - 1) : e.pos)
							 << (char)e.chr;
						if(i < br->edits_.size()-1) cout << " ";
					}
					cout << endl;
				}

			}
			assert(br->repOk((uint32_t)qlen_));

			ASSERT_ONLY(int stratum = br->cost_ >> 14); // shift the stratum over
			assert_lt(stratum, 4);
			// Not necessarily true with rounding
			uint32_t depth = br->tipDepth();

			const Ebwt& ebwt = *ebwt_;

			if(halfAndHalf_ > 0) assert_gt(depth3_, depth5_);

			bool reportedPartial = false;
			bool invalidExact = false;
			bool empty = false;
			bool hit = false;
			uint16_t cost = br->cost_;
			uint32_t cur = 0;
			uint32_t nedits = 0;

			if(halfAndHalf_ && !hhCheckTop(br, depth, 0)) {
				// Stop extending this branch because it violates a half-
				// and-half constraint
				if(metrics_ != NULL) metrics_->curBacktracks_++;
				pm.curtail(br, (uint32_t)qlen_, depth3_, qualOrder_);
				goto bail;
			}

			cur = (uint32_t)(qlen_ - depth - 1); // current offset into qry_
			if(depth < qlen_) {
				// Determine whether ranges at this location are candidates
				// for backtracking
				int c = (int)(*qry_)[cur]; // get char at this position
				int nextc = -1;
				if(cur < qlen_-1) nextc = (int)(*qry_)[cur+1];
				assert_leq(c, 4);
				// If any uncalled base's penalty is still under
				// the ceiling, then this position is an alternative
				uint8_t q[4] = {'!', '!', '!', '!'};
				uint8_t bestq;
				// get unrounded penalties at this position
				bestq = q[0] = q[1] = q[2] = q[3] =
					mmPenalty(maqPenalty_, qualAt(cur));

				// The current query position is a legit alternative if it a) is
				// not in the unrevisitable region, and b) its selection would
				// not necessarily cause the quality ceiling (if one exists) to
				// be exceeded
				bool curIsAlternative = (depth >= br->depth0_) &&
				                        (br->ham_ + bestq <= qualLim_);
				ASSERT_ONLY(TIndexOffU obot = br->bot_);
				TIndexOffU otop = br->top_;

				// If c is 'N', then it's a mismatch
				if(c == 4 && depth > 0) {
					// Force the 'else if(curIsAlternative)' or 'else'
					// branches below
					br->top_ = br->bot_ = 1;
				} else if(c == 4) {
					// We'll take the 'if(br->top == 0 && br->bot == 0)'
					// branch below
					assert_eq(0, br->top_);
					assert_eq(0, br->bot_);
				}

				// Get the range state for the current position
				RangeState *rs = br->rangeState();
				assert(rs != NULL);
				// Calculate the ranges for this position
				if(br->top_ == 0 && br->bot_ == 0) {
					// Calculate first quartet of ranges using the _fchr[]
					// array
								  rs->tops[0] = ebwt._fchr[0];
					rs->bots[0] = rs->tops[1] = ebwt._fchr[1];
					rs->bots[1] = rs->tops[2] = ebwt._fchr[2];
					rs->bots[2] = rs->tops[3] = ebwt._fchr[3];
					rs->bots[3]               = ebwt._fchr[4];
					ASSERT_ONLY(int r =)
					br->installRanges(c, nextc, qualLim_ - br->ham_, q);
					assert(r < 4 || c == 4);
					// Update top and bot
					if(c < 4) {
						br->top_ = rs->tops[c];
						br->bot_ = rs->bots[c];
					}
				} else if(curIsAlternative && (br->bot_ > br->top_ || c == 4)) {
					// Calculate next quartet of ranges.  We hope that the
					// appropriate cache lines are prefetched.
					assert(br->ltop_.valid());
								  rs->tops[0] =
					rs->bots[0] = rs->tops[1] =
					rs->bots[1] = rs->tops[2] =
					rs->bots[2] = rs->tops[3] =
					rs->bots[3]               = 0;
					if(br->lbot_.valid()) {
						if(metrics_ != NULL) metrics_->curBwtOps_++;
						ebwt.mapLFEx(br->ltop_, br->lbot_, (TIndexOffU*)rs->tops, (TIndexOffU*)rs->bots);
					} else {
#ifndef NDEBUG
						TIndexOffU tmptops[] = {0, 0, 0, 0};
						TIndexOffU tmpbots[] = {0, 0, 0, 0};
						SideLocus ltop, lbot;
						ltop.initFromRow(otop, ebwt_->_eh, ebwt_->_ebwt);
						lbot.initFromRow(obot, ebwt_->_eh, ebwt_->_ebwt);
						ebwt.mapLFEx(ltop, lbot, tmptops, tmpbots);
#endif
						if(metrics_ != NULL) metrics_->curBwtOps_++;
						int cc = ebwt.mapLF1((TIndexOffU&)otop, br->ltop_);
						br->top_ = otop;
						assert(cc == -1 || (cc >= 0 && cc < 4));
						if(cc >= 0) {
							assert_lt(cc, 4);
							rs->tops[cc] = br->top_;
							rs->bots[cc] = (br->top_ + 1);
						}
#ifndef NDEBUG
						for(int i = 0; i < 4; i++) {
							assert_eq(tmpbots[i] - tmptops[i],
							          rs->bots[i] - rs->tops[i]);
						}
#endif
					}
					ASSERT_ONLY(int r =)
					br->installRanges(c, nextc, qualLim_ - br->ham_, q);
					assert(r < 4 || c == 4);
					// Update top and bot
					if(c < 4) {
						br->top_ = rs->tops[c];
						br->bot_ = rs->bots[c];
					} else {
						br->top_ = br->bot_ = 1;
					}
				} else if(br->bot_ > br->top_) {
					// This read position is not a legitimate backtracking
					// alternative.  No need to do the bookkeeping for the
					// entire quartet, just do c.  We hope that the
					// appropriate cache lines are prefetched before now;
					// otherwise, we're about to take an expensive cache
					// miss.
					assert(br->ltop_.valid());
					rs->eliminated_ = true; // eliminate all alternatives leaving this node
					assert(br->eliminated(br->len_));
					if(c < 4) {
						if(br->top_ + 1 == br->bot_) {
							if(metrics_ != NULL) metrics_->curBwtOps_++;
							br->bot_ = br->top_ = ebwt.mapLF1(br->top_, br->ltop_, c);
							if(br->bot_ != OFF_MASK) br->bot_++;
						} else {
							if(metrics_ != NULL) metrics_->curBwtOps_++;
							br->top_ = ebwt.mapLF(br->ltop_, c);
							assert(br->lbot_.valid());
							if(metrics_ != NULL) metrics_->curBwtOps_++;
							br->bot_ = ebwt.mapLF(br->lbot_, c);
						}
					}
				} else {
					rs->eliminated_ = true;
				}
				assert(rs->repOk());
				// br->top_ and br->bot_ now contain the next top and bot
			} else {
				// The continuation had already processed the whole read
				assert_eq(qlen_, depth);
				cur = 0;
			}
			empty = (br->top_ == br->bot_);
			hit = (cur == 0 && !empty);

			// Check whether we've obtained an exact alignment when
			// we've been instructed not to report exact alignments
			nedits = (uint32_t)br->edits_.size();
			invalidExact = (hit && nedits == 0 && !reportExacts_);
			assert_leq(br->ham_, qualLim_);

			// Set this to true if the only way to make legal progress
			// is via one or more additional backtracks.
			if(halfAndHalf_ && !hhCheck(br, depth, empty)) {
				// This alignment doesn't satisfy the half-and-half
				// requirements; reject it
				if(metrics_ != NULL) metrics_->curBacktracks_++;
				pm.curtail(br, (uint32_t)qlen_, depth3_, qualOrder_);
				goto bail;
			}

			if(hit &&            // there is a range to report
			   !invalidExact &&  // not disqualified by no-exact-hits setting
			   !reportedPartial) // not an already-reported partial alignment
			{
				if(verbose_) {
					if(partial_) {
						cout << " Partial alignment:" << endl;
					} else {
						cout << " Final alignment:" << endl;
					}
					br->len_++;
					br->print((*qry_), (*qual_), minCost, cout, halfAndHalf_ > 0, partial_, fw_, ebwt_->fw());
					br->len_--;
					cout << endl;
				}
				assert_gt(br->bot_, br->top_);
				assert_leq(br->ham_, qualLim_);
				assert_leq((uint32_t)(br->cost_ & ~0xc000), qualLim_);
				if(metrics_ != NULL) metrics_->setReadHasRange();
				curRange_.top     = br->top_;
				curRange_.bot     = br->bot_;
				curRange_.cost    = br->cost_;
				curRange_.stratum = (br->cost_ >> 14);
				curRange_.numMms  = nedits;
				curRange_.fw      = fw_;
				curRange_.mms.clear();
				curRange_.refcs.clear();
				for(size_t i = 0; i < nedits; i++) {
					curRange_.mms.push_back((uint32_t)(qlen_ - br->edits_.get(i).pos - 1));
					curRange_.refcs.push_back((char)br->edits_.get(i).chr);
				}
				addPartialEdits();
				curRange_.ebwt    = ebwt_;
				this->foundRange  = true;
	#ifndef NDEBUG
				TIndexOff top2 = (TIndexOff)br->top_;
				top2++; // ensure it's not 0
				if(ebwt_->fw()) top2 = -top2;
				assert(allTops_.find(top2) == allTops_.end());
				allTops_.insert(top2);
	#endif
				assert(curRange_.repOk());
				// Must curtail because we've consumed the whole pattern
				if(metrics_ != NULL) metrics_->curBacktracks_++;
				pm.curtail(br, (uint32_t)qlen_, depth3_, qualOrder_);
			} else if(empty || cur == 0) {
				// The branch couldn't be extended further
				if(metrics_ != NULL) metrics_->curBacktracks_++;
				pm.curtail(br, (uint32_t)qlen_, depth3_, qualOrder_);
			} else {
				// Extend the branch by one position; no change to its cost
				// so there's no need to reconsider where it lies in the
				// priority queue
				assert_neq(0, cur);
				br->extend();
			}
		bail:
			// Make sure the front element of the priority queue is
			// extendable (i.e. not curtailed) and then prep it.
			if(!pm.splitAndPrep(rand_, (uint32_t)qlen_, qualLim_, depth3_,
			                    qualOrder_,
			                    ebwt_->_eh, ebwt_->_ebwt, ebwt_->_fw))
			{
				pm.reset(0);
				assert(pm.empty());
			}
			if(pm.empty()) {
				// No more branches
				break;
			}
			assert(!pm.front()->curtailed_);
			assert(!pm.front()->exhausted_);

			if(until == ADV_COST_CHANGES && pm.front()->cost_ != cost) break;
			else if(until == ADV_STEP) break;

		} while(!this->foundRange);
		if(!pm.empty()) {
			assert(!pm.front()->curtailed_);
			assert(!pm.front()->exhausted_);
		}
	}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x120, %rsp            # imm = 0x120
movw %dx, %ax
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movw %ax, -0xe(%rbp)
movq %rcx, -0x18(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x88(%rbp)
movb $0x0, 0x9(%rax)
movq -0x18(%rbp), %rdi
callq 0x43ca0
movq %rax, %rcx
movq -0x88(%rbp), %rax
movq %rcx, -0x20(%rbp)
testb $0x1, 0xb4(%rax)
je 0x3f544
movq -0x88(%rbp), %rax
movq -0x20(%rbp), %rcx
movq %rcx, -0xa8(%rbp)
movq 0x18(%rax), %rcx
movq %rcx, -0xa0(%rbp)
movq 0x58(%rax), %rcx
movq %rcx, -0x98(%rbp)
movw -0xe(%rbp), %cx
movw %cx, -0xaa(%rbp)
cmpl $0x0, 0x90(%rax)
setg %cl
movb %cl, -0x89(%rbp)
movb 0x94(%rax), %cl
movb %cl, -0xab(%rbp)
movb 0x70(%rax), %cl
movb %cl, -0xac(%rbp)
movq 0x68(%rax), %rdi
callq 0x402a0
movb -0xac(%rbp), %r10b
movb -0xab(%rbp), %r9b
movw -0xaa(%rbp), %cx
movq -0xa8(%rbp), %rdi
movq -0xa0(%rbp), %rsi
movq -0x98(%rbp), %rdx
movb %al, %r8b
movb -0x89(%rbp), %al
movzbl %r8b, %r11d
andl $0x1, %r11d
movq %rsp, %r8
movl %r11d, 0x10(%r8)
movzbl %r10b, %r10d
andl $0x1, %r10d
movl %r10d, 0x8(%r8)
movzbl %r9b, %r9d
andl $0x1, %r9d
movl %r9d, (%r8)
movzwl %cx, %ecx
movzbl %al, %r9d
andl $0x1, %r9d
movq 0x68bcc(%rip), %r8      # 0xa7fb8
callq 0x43cc0
movq -0x20(%rbp), %rdi
addq $0x50, %rdi
callq 0x444a0
testb $0x1, %al
jne 0x3f542
movq 0x68bab(%rip), %rdi     # 0xa7fb8
leaq 0x4d8b7(%rip), %rsi     # 0x8cccb
callq 0xa5d0
movq $0x0, -0x28(%rbp)
movq -0x28(%rbp), %rax
movq %rax, -0xb8(%rbp)
movq -0x20(%rbp), %rdi
addq $0x50, %rdi
callq 0x41bd0
movq %rax, %rcx
movq -0xb8(%rbp), %rax
cmpq %rcx, %rax
jae 0x3f52f
movq -0x20(%rbp), %rdi
addq $0x50, %rdi
movq -0x28(%rbp), %rsi
callq 0x41d50
movq %rax, %rcx
movq -0x88(%rbp), %rax
movl (%rcx), %ecx
movl %ecx, -0x2c(%rbp)
movq 0x10(%rax), %rdi
callq 0x402a0
testb $0x1, %al
jne 0x3f47b
jmp 0x3f4a4
movq -0x88(%rbp), %rax
movq 0x50(%rax), %rax
movl -0x2c(%rbp), %ecx
shrl $0x14, %ecx
andl $0x3ff, %ecx            # imm = 0x3FF
movl %ecx, %ecx
subq %rcx, %rax
subq $0x1, %rax
movq %rax, -0xc0(%rbp)
jmp 0x3f4b8
movl -0x2c(%rbp), %eax
shrl $0x14, %eax
andl $0x3ff, %eax            # imm = 0x3FF
movl %eax, %eax
movq %rax, -0xc0(%rbp)
movq -0xc0(%rbp), %rsi
movq 0x68af2(%rip), %rdi     # 0xa7fb8
callq 0xa130
movq %rax, %rdi
movl -0x2c(%rbp), %eax
andl $0xff, %eax
movsbl %al, %esi
callq 0xa720
movq -0x28(%rbp), %rax
movq %rax, -0xc8(%rbp)
movq -0x20(%rbp), %rdi
addq $0x50, %rdi
callq 0x41bd0
movq %rax, %rcx
movq -0xc8(%rbp), %rax
subq $0x1, %rcx
cmpq %rcx, %rax
jae 0x3f51c
movq 0x68aa8(%rip), %rdi     # 0xa7fb8
leaq 0x4dbed(%rip), %rsi     # 0x8d104
callq 0xa5d0
jmp 0x3f51e
movq -0x28(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x28(%rbp)
jmp 0x3f421
movq 0x68a82(%rip), %rdi     # 0xa7fb8
movq 0x68a2b(%rip), %rsi     # 0xa7f68
callq 0xa640
jmp 0x3f544
movq -0x20(%rbp), %rdi
callq 0x43bc0
movw %ax, %cx
movq -0x88(%rbp), %rax
movzwl %cx, %ecx
movl %ecx, -0x30(%rbp)
movq 0x68(%rax), %rcx
movq %rcx, -0x38(%rbp)
cmpl $0x0, 0x90(%rax)
jle 0x3f570
jmp 0x3f570
movq -0x88(%rbp), %rax
movb $0x0, -0x39(%rbp)
movb $0x0, -0x3a(%rbp)
movb $0x0, -0x3b(%rbp)
movb $0x0, -0x3c(%rbp)
movq -0x20(%rbp), %rcx
movw 0x10(%rcx), %cx
movw %cx, -0x3e(%rbp)
movl $0x0, -0x44(%rbp)
movl $0x0, -0x48(%rbp)
cmpl $0x0, 0x90(%rax)
je 0x3f621
movq -0x88(%rbp), %rdi
movq -0x20(%rbp), %rsi
movl -0x30(%rbp), %edx
xorl %ecx, %ecx
movq $-0x1, %r8
callq 0x444d0
testb $0x1, %al
jne 0x3f621
movq -0x88(%rbp), %rax
cmpq $0x0, 0x180(%rax)
je 0x3f5f0
movq -0x88(%rbp), %rax
movq 0x180(%rax), %rax
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
movq -0x88(%rbp), %rax
movq -0x18(%rbp), %rdi
movq -0x20(%rbp), %rsi
movq 0x50(%rax), %rcx
movl %ecx, %edx
movl 0x9c(%rax), %ecx
movb 0x85(%rax), %al
andb $0x1, %al
movzbl %al, %r8d
callq 0x44560
jmp 0x40063
movq -0x88(%rbp), %rcx
movq 0x50(%rcx), %rax
movl -0x30(%rbp), %edx
subq %rdx, %rax
subq $0x1, %rax
movl %eax, -0x44(%rbp)
movl -0x30(%rbp), %eax
cmpq 0x50(%rcx), %rax
jae 0x3fb72
movq -0x88(%rbp), %rax
movq 0x18(%rax), %rdi
movl -0x44(%rbp), %eax
movl %eax, %esi
callq 0x403a0
movq -0x88(%rbp), %rcx
movsbl (%rax), %eax
movl %eax, -0x4c(%rbp)
movl $0xffffffff, -0x50(%rbp) # imm = 0xFFFFFFFF
movl -0x44(%rbp), %eax
movq 0x50(%rcx), %rcx
subq $0x1, %rcx
cmpq %rcx, %rax
jae 0x3f69f
movq -0x88(%rbp), %rax
movq 0x18(%rax), %rdi
movl -0x44(%rbp), %eax
addl $0x1, %eax
movl %eax, %eax
movl %eax, %esi
callq 0x403a0
movsbl (%rax), %eax
movl %eax, -0x50(%rbp)
movq -0x88(%rbp), %rdi
movl 0x4a074(%rip), %eax     # 0x89720
movl %eax, -0x54(%rbp)
movb 0x84(%rdi), %al
movb %al, -0xca(%rbp)
movl -0x44(%rbp), %eax
movl %eax, %esi
callq 0x44620
movb -0xca(%rbp), %cl
andb $0x1, %cl
movzbl %cl, %edi
movzbl %al, %esi
callq 0x1fad0
movb %al, -0x51(%rbp)
movb %al, -0x52(%rbp)
movb %al, -0x53(%rbp)
movb %al, -0x54(%rbp)
movb %al, -0x55(%rbp)
movl -0x30(%rbp), %ecx
movq -0x20(%rbp), %rax
movzwl 0x4(%rax), %edx
xorl %eax, %eax
cmpl %edx, %ecx
movb %al, -0xc9(%rbp)
jb 0x3f723
movq -0x88(%rbp), %rcx
movq -0x20(%rbp), %rax
movzwl 0x12(%rax), %eax
movzbl -0x55(%rbp), %edx
addl %edx, %eax
cmpl 0x88(%rcx), %eax
setbe %al
movb %al, -0xc9(%rbp)
movb -0xc9(%rbp), %al
andb $0x1, %al
movb %al, -0x56(%rbp)
movq -0x20(%rbp), %rax
movl 0x24(%rax), %eax
movl %eax, -0x5c(%rbp)
cmpl $0x4, -0x4c(%rbp)
jne 0x3f75c
cmpl $0x0, -0x30(%rbp)
jbe 0x3f75c
movq -0x20(%rbp), %rax
movl $0x1, 0x28(%rax)
movq -0x20(%rbp), %rax
movl $0x1, 0x24(%rax)
jmp 0x3f766
cmpl $0x4, -0x4c(%rbp)
jne 0x3f764
jmp 0x3f764
jmp 0x3f766
movq -0x20(%rbp), %rdi
callq 0x44650
movq %rax, -0x68(%rbp)
movq -0x20(%rbp), %rax
cmpl $0x0, 0x24(%rax)
jne 0x3f865
movq -0x20(%rbp), %rax
cmpl $0x0, 0x28(%rax)
jne 0x3f865
movq -0x88(%rbp), %rax
movq -0x38(%rbp), %rcx
movq 0x90(%rcx), %rcx
movl (%rcx), %edx
movq -0x68(%rbp), %rcx
movl %edx, (%rcx)
movq -0x38(%rbp), %rcx
movq 0x90(%rcx), %rcx
movl 0x4(%rcx), %edx
movq -0x68(%rbp), %rcx
movl %edx, 0x4(%rcx)
movq -0x68(%rbp), %rcx
movl %edx, 0x10(%rcx)
movq -0x38(%rbp), %rcx
movq 0x90(%rcx), %rcx
movl 0x8(%rcx), %edx
movq -0x68(%rbp), %rcx
movl %edx, 0x8(%rcx)
movq -0x68(%rbp), %rcx
movl %edx, 0x14(%rcx)
movq -0x38(%rbp), %rcx
movq 0x90(%rcx), %rcx
movl 0xc(%rcx), %edx
movq -0x68(%rbp), %rcx
movl %edx, 0xc(%rcx)
movq -0x68(%rbp), %rcx
movl %edx, 0x18(%rcx)
movq -0x38(%rbp), %rcx
movq 0x90(%rcx), %rcx
movl 0x10(%rcx), %edx
movq -0x68(%rbp), %rcx
movl %edx, 0x1c(%rcx)
movq -0x20(%rbp), %rdi
movl -0x4c(%rbp), %esi
movl -0x50(%rbp), %edx
movl 0x88(%rax), %ecx
movq -0x20(%rbp), %rax
movzwl 0x12(%rax), %eax
subl %eax, %ecx
leaq -0x54(%rbp), %r8
callq 0x44670
cmpl $0x4, -0x4c(%rbp)
jge 0x3f860
movq -0x68(%rbp), %rax
movslq -0x4c(%rbp), %rcx
movl (%rax,%rcx,4), %ecx
movq -0x20(%rbp), %rax
movl %ecx, 0x24(%rax)
movq -0x68(%rbp), %rax
movslq -0x4c(%rbp), %rcx
movl 0x10(%rax,%rcx,4), %ecx
movq -0x20(%rbp), %rax
movl %ecx, 0x28(%rax)
jmp 0x3fb70
testb $0x1, -0x56(%rbp)
je 0x3fa2e
movq -0x20(%rbp), %rax
movl 0x28(%rax), %eax
movq -0x20(%rbp), %rcx
cmpl 0x24(%rcx), %eax
ja 0x3f889
cmpl $0x4, -0x4c(%rbp)
jne 0x3fa2e
movq -0x68(%rbp), %rax
movl $0x0, 0x1c(%rax)
movq -0x68(%rbp), %rax
movl $0x0, 0xc(%rax)
movq -0x68(%rbp), %rax
movl $0x0, 0x18(%rax)
movq -0x68(%rbp), %rax
movl $0x0, 0x8(%rax)
movq -0x68(%rbp), %rax
movl $0x0, 0x14(%rax)
movq -0x68(%rbp), %rax
movl $0x0, 0x4(%rax)
movq -0x68(%rbp), %rax
movl $0x0, 0x10(%rax)
movq -0x68(%rbp), %rax
movl $0x0, (%rax)
movq -0x20(%rbp), %rdi
addq $0x3c, %rdi
callq 0x44950
testb $0x1, %al
jne 0x3f8f3
jmp 0x3f942
movq -0x88(%rbp), %rax
cmpq $0x0, 0x180(%rax)
je 0x3f91b
movq -0x88(%rbp), %rax
movq 0x180(%rax), %rax
movl 0x4(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x4(%rax)
movq -0x38(%rbp), %rdi
movq -0x20(%rbp), %rsi
addq $0x2c, %rsi
movq -0x20(%rbp), %rdx
addq $0x3c, %rdx
movq -0x68(%rbp), %rcx
movq -0x68(%rbp), %r8
addq $0x10, %r8
callq 0x44970
jmp 0x3f9bc
movq -0x88(%rbp), %rax
cmpq $0x0, 0x180(%rax)
je 0x3f96a
movq -0x88(%rbp), %rax
movq 0x180(%rax), %rax
movl 0x4(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x4(%rax)
movq -0x38(%rbp), %rdi
movq -0x20(%rbp), %rdx
addq $0x2c, %rdx
leaq -0x5c(%rbp), %rsi
callq 0x44a40
movl %eax, -0x6c(%rbp)
movl -0x5c(%rbp), %ecx
movq -0x20(%rbp), %rax
movl %ecx, 0x24(%rax)
cmpl $0x0, -0x6c(%rbp)
jl 0x3f9ba
movq -0x20(%rbp), %rax
movl 0x24(%rax), %edx
movq -0x68(%rbp), %rax
movslq -0x6c(%rbp), %rcx
movl %edx, (%rax,%rcx,4)
movq -0x20(%rbp), %rax
movl 0x24(%rax), %edx
addl $0x1, %edx
movq -0x68(%rbp), %rax
movslq -0x6c(%rbp), %rcx
movl %edx, 0x10(%rax,%rcx,4)
jmp 0x3f9bc
movq -0x88(%rbp), %rax
movq -0x20(%rbp), %rdi
movl -0x4c(%rbp), %esi
movl -0x50(%rbp), %edx
movl 0x88(%rax), %ecx
movq -0x20(%rbp), %rax
movzwl 0x12(%rax), %eax
subl %eax, %ecx
leaq -0x54(%rbp), %r8
callq 0x44670
cmpl $0x4, -0x4c(%rbp)
jge 0x3fa13
movq -0x68(%rbp), %rax
movslq -0x4c(%rbp), %rcx
movl (%rax,%rcx,4), %ecx
movq -0x20(%rbp), %rax
movl %ecx, 0x24(%rax)
movq -0x68(%rbp), %rax
movslq -0x4c(%rbp), %rcx
movl 0x10(%rax,%rcx,4), %ecx
movq -0x20(%rbp), %rax
movl %ecx, 0x28(%rax)
jmp 0x3fa29
movq -0x20(%rbp), %rax
movl $0x1, 0x28(%rax)
movq -0x20(%rbp), %rax
movl $0x1, 0x24(%rax)
jmp 0x3fb6e
movq -0x20(%rbp), %rax
movl 0x28(%rax), %eax
movq -0x20(%rbp), %rcx
cmpl 0x24(%rcx), %eax
jbe 0x3fb64
movq -0x68(%rbp), %rax
movb $0x1, 0x28(%rax)
cmpl $0x4, -0x4c(%rbp)
jge 0x3fb62
movq -0x20(%rbp), %rax
movl 0x24(%rax), %eax
addl $0x1, %eax
movq -0x20(%rbp), %rcx
cmpl 0x28(%rcx), %eax
jne 0x3fad6
movq -0x88(%rbp), %rax
cmpq $0x0, 0x180(%rax)
je 0x3fa8f
movq -0x88(%rbp), %rax
movq 0x180(%rax), %rax
movl 0x4(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x4(%rax)
movq -0x38(%rbp), %rdi
movq -0x20(%rbp), %rax
movl 0x24(%rax), %esi
movq -0x20(%rbp), %rdx
addq $0x2c, %rdx
movl -0x4c(%rbp), %ecx
callq 0x44b00
movl %eax, %ecx
movq -0x20(%rbp), %rax
movl %ecx, 0x24(%rax)
movq -0x20(%rbp), %rax
movl %ecx, 0x28(%rax)
movq -0x20(%rbp), %rax
cmpl $-0x1, 0x28(%rax)
je 0x3fad1
movq -0x20(%rbp), %rax
movl 0x28(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x28(%rax)
jmp 0x3fb60
movq -0x88(%rbp), %rax
cmpq $0x0, 0x180(%rax)
je 0x3fafe
movq -0x88(%rbp), %rax
movq 0x180(%rax), %rax
movl 0x4(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x4(%rax)
movq -0x38(%rbp), %rdi
movq -0x20(%rbp), %rsi
addq $0x2c, %rsi
movl -0x4c(%rbp), %edx
callq 0x44bb0
movl %eax, %edx
movq -0x88(%rbp), %rax
movq -0x20(%rbp), %rcx
movl %edx, 0x24(%rcx)
cmpq $0x0, 0x180(%rax)
je 0x3fb43
movq -0x88(%rbp), %rax
movq 0x180(%rax), %rax
movl 0x4(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x4(%rax)
movq -0x38(%rbp), %rdi
movq -0x20(%rbp), %rsi
addq $0x3c, %rsi
movl -0x4c(%rbp), %edx
callq 0x44bb0
movl %eax, %ecx
movq -0x20(%rbp), %rax
movl %ecx, 0x28(%rax)
jmp 0x3fb62
jmp 0x3fb6c
movq -0x68(%rbp), %rax
movb $0x1, 0x28(%rax)
jmp 0x3fb6e
jmp 0x3fb70
jmp 0x3fb79
movl $0x0, -0x44(%rbp)
movq -0x20(%rbp), %rax
movl 0x24(%rax), %eax
movq -0x20(%rbp), %rcx
cmpl 0x28(%rcx), %eax
sete %al
andb $0x1, %al
movb %al, -0x3b(%rbp)
xorl %eax, %eax
cmpl $0x0, -0x44(%rbp)
movb %al, -0xcb(%rbp)
jne 0x3fba8
movb -0x3b(%rbp), %al
xorb $-0x1, %al
movb %al, -0xcb(%rbp)
movb -0xcb(%rbp), %al
andb $0x1, %al
movb %al, -0x3c(%rbp)
movq -0x20(%rbp), %rdi
addq $0x50, %rdi
callq 0x41bd0
movl %eax, -0x48(%rbp)
xorl %eax, %eax
testb $0x1, -0x3c(%rbp)
movb %al, -0xcc(%rbp)
je 0x3fbf4
xorl %eax, %eax
cmpl $0x0, -0x48(%rbp)
movb %al, -0xcc(%rbp)
jne 0x3fbf4
movq -0x88(%rbp), %rax
movb 0x8c(%rax), %al
xorb $-0x1, %al
movb %al, -0xcc(%rbp)
movq -0x88(%rbp), %rax
movb -0xcc(%rbp), %cl
andb $0x1, %cl
movb %cl, -0x3a(%rbp)
cmpl $0x0, 0x90(%rax)
je 0x3fc86
movq -0x88(%rbp), %rdi
movq -0x20(%rbp), %rsi
movl -0x30(%rbp), %edx
movb -0x3b(%rbp), %al
andb $0x1, %al
movzbl %al, %ecx
callq 0x44c30
testb $0x1, %al
jne 0x3fc86
movq -0x88(%rbp), %rax
cmpq $0x0, 0x180(%rax)
je 0x3fc55
movq -0x88(%rbp), %rax
movq 0x180(%rax), %rax
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
movq -0x88(%rbp), %rax
movq -0x18(%rbp), %rdi
movq -0x20(%rbp), %rsi
movq 0x50(%rax), %rcx
movl %ecx, %edx
movl 0x9c(%rax), %ecx
movb 0x85(%rax), %al
andb $0x1, %al
movzbl %al, %r8d
callq 0x44560
jmp 0x40063
testb $0x1, -0x3c(%rbp)
je 0x3fff6
testb $0x1, -0x3a(%rbp)
jne 0x3fff6
testb $0x1, -0x39(%rbp)
jne 0x3fff6
movq -0x88(%rbp), %rax
testb $0x1, 0xb4(%rax)
je 0x3fe12
movq -0x88(%rbp), %rax
testb $0x1, 0x94(%rax)
je 0x3fcec
movq 0x682e9(%rip), %rdi     # 0xa7fb8
leaq 0x4cffc(%rip), %rsi     # 0x8ccd2
callq 0xa5d0
movq %rax, %rdi
movq 0x68283(%rip), %rsi     # 0xa7f68
callq 0xa640
jmp 0x3fd0e
movq 0x682c5(%rip), %rdi     # 0xa7fb8
leaq 0x4cfec(%rip), %rsi     # 0x8cce6
callq 0xa5d0
movq %rax, %rdi
movq 0x6825f(%rip), %rsi     # 0xa7f68
callq 0xa640
movq -0x88(%rbp), %rax
movq -0x20(%rbp), %rcx
movw 0xe(%rcx), %dx
addw $0x1, %dx
movw %dx, 0xe(%rcx)
movq -0x20(%rbp), %rcx
movq %rcx, -0xe8(%rbp)
movq 0x18(%rax), %rcx
movq %rcx, -0xe0(%rbp)
movq 0x58(%rax), %rcx
movq %rcx, -0xd8(%rbp)
movw -0xe(%rbp), %cx
movw %cx, -0xea(%rbp)
cmpl $0x0, 0x90(%rax)
setg %cl
movb %cl, -0xcd(%rbp)
movb 0x94(%rax), %cl
movb %cl, -0xeb(%rbp)
movb 0x70(%rax), %cl
movb %cl, -0xec(%rbp)
movq 0x68(%rax), %rdi
callq 0x402a0
movb -0xec(%rbp), %r10b
movb -0xeb(%rbp), %r9b
movw -0xea(%rbp), %cx
movq -0xe8(%rbp), %rdi
movq -0xe0(%rbp), %rsi
movq -0xd8(%rbp), %rdx
movb %al, %r8b
movb -0xcd(%rbp), %al
movzbl %r8b, %r11d
andl $0x1, %r11d
movq %rsp, %r8
movl %r11d, 0x10(%r8)
movzbl %r10b, %r10d
andl $0x1, %r10d
movl %r10d, 0x8(%r8)
movzbl %r9b, %r9d
andl $0x1, %r9d
movl %r9d, (%r8)
movzwl %cx, %ecx
movzbl %al, %r9d
andl $0x1, %r9d
movq 0x681ce(%rip), %r8      # 0xa7fb8
callq 0x43cc0
movq -0x20(%rbp), %rax
movw 0xe(%rax), %cx
addw $-0x1, %cx
movw %cx, 0xe(%rax)
movq 0x681b2(%rip), %rdi     # 0xa7fb8
movq 0x6815b(%rip), %rsi     # 0xa7f68
callq 0xa640
movq -0x88(%rbp), %rax
cmpq $0x0, 0x180(%rax)
je 0x3fe36
movq -0x88(%rbp), %rax
movq 0x180(%rax), %rdi
callq 0x44d90
movq -0x88(%rbp), %rdi
movq -0x20(%rbp), %rax
movl 0x24(%rax), %eax
movl %eax, 0xb8(%rdi)
movq -0x20(%rbp), %rax
movl 0x28(%rax), %eax
movl %eax, 0xbc(%rdi)
movq -0x20(%rbp), %rax
movw 0x10(%rax), %ax
movw %ax, 0xc0(%rdi)
movq -0x20(%rbp), %rax
movzwl 0x10(%rax), %eax
sarl $0xe, %eax
movl %eax, 0xc4(%rdi)
movl -0x48(%rbp), %eax
movl %eax, 0xc8(%rdi)
movb 0x70(%rdi), %al
andb $0x1, %al
movb %al, 0xcc(%rdi)
addq $0xb8, %rdi
addq $0x18, %rdi
callq 0x401d0
movq -0x88(%rbp), %rdi
addq $0xb8, %rdi
addq $0x38, %rdi
callq 0x401f0
movq $0x0, -0x78(%rbp)
movq -0x78(%rbp), %rax
movl -0x48(%rbp), %ecx
cmpq %rcx, %rax
jae 0x3ff87
movq -0x88(%rbp), %rax
movq %rax, %rcx
addq $0xb8, %rcx
addq $0x18, %rcx
movq %rcx, -0x108(%rbp)
movq 0x50(%rax), %rax
movq %rax, -0x100(%rbp)
movq -0x20(%rbp), %rdi
addq $0x50, %rdi
movq -0x78(%rbp), %rsi
callq 0x41d50
movq -0x108(%rbp), %rdi
movq %rax, %rcx
movq -0x100(%rbp), %rax
movl (%rcx), %ecx
shrl $0x14, %ecx
andl $0x3ff, %ecx            # imm = 0x3FF
movl %ecx, %ecx
subq %rcx, %rax
subq $0x1, %rax
movl %eax, -0x7c(%rbp)
leaq -0x7c(%rbp), %rsi
callq 0x32160
movq -0x88(%rbp), %rax
addq $0xb8, %rax
addq $0x38, %rax
movq %rax, -0xf8(%rbp)
movq -0x20(%rbp), %rdi
addq $0x50, %rdi
movq -0x78(%rbp), %rsi
callq 0x41d50
movq -0xf8(%rbp), %rdi
movl (%rax), %eax
andl $0xff, %eax
movb %al, -0x7d(%rbp)
leaq -0x7d(%rbp), %rsi
callq 0x40fe0
movq -0x78(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x78(%rbp)
jmp 0x3feba
movq -0x88(%rbp), %rdi
callq 0x40a90
movq -0x88(%rbp), %rax
movq 0x68(%rax), %rcx
movq %rcx, 0x110(%rax)
movb $0x1, 0x9(%rax)
cmpq $0x0, 0x180(%rax)
je 0x3ffc8
movq -0x88(%rbp), %rax
movq 0x180(%rax), %rax
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
movq -0x88(%rbp), %rax
movq -0x18(%rbp), %rdi
movq -0x20(%rbp), %rsi
movq 0x50(%rax), %rcx
movl %ecx, %edx
movl 0x9c(%rax), %ecx
movb 0x85(%rax), %al
andb $0x1, %al
movzbl %al, %r8d
callq 0x44560
jmp 0x40061
testb $0x1, -0x3b(%rbp)
jne 0x40002
cmpl $0x0, -0x44(%rbp)
jne 0x40056
movq -0x88(%rbp), %rax
cmpq $0x0, 0x180(%rax)
je 0x40028
movq -0x88(%rbp), %rax
movq 0x180(%rax), %rax
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
movq -0x88(%rbp), %rax
movq -0x18(%rbp), %rdi
movq -0x20(%rbp), %rsi
movq 0x50(%rax), %rcx
movl %ecx, %edx
movl 0x9c(%rax), %ecx
movb 0x85(%rax), %al
andb $0x1, %al
movzbl %al, %r8d
callq 0x44560
jmp 0x4005f
movq -0x20(%rbp), %rdi
callq 0x44db0
jmp 0x40061
jmp 0x40063
movq -0x88(%rbp), %rax
movq -0x18(%rbp), %rdi
movq %rax, %rsi
addq $0xa0, %rsi
movq 0x50(%rax), %rcx
movl %ecx, %edx
movl 0x88(%rax), %ecx
movl 0x9c(%rax), %r8d
movb 0x85(%rax), %r9b
movq 0x68(%rax), %r11
addq $0xf8, %r11
movq 0x68(%rax), %r10
movq 0xb8(%r10), %r10
movq 0x68(%rax), %rax
movb 0x10(%rax), %al
andb $0x1, %r9b
andb $0x1, %al
movzbl %r9b, %r9d
movq %r11, (%rsp)
movq %r10, 0x8(%rsp)
movzbl %al, %eax
movl %eax, 0x10(%rsp)
callq 0x44de0
testb $0x1, %al
jne 0x400dd
movq -0x18(%rbp), %rdi
xorl %esi, %esi
callq 0x44ff0
movq -0x18(%rbp), %rdi
callq 0x45050
testb $0x1, %al
jne 0x400ec
jmp 0x400ee
jmp 0x4012b
cmpl $0x2, -0xc(%rbp)
jne 0x4010b
movq -0x18(%rbp), %rdi
callq 0x43ca0
movzwl 0x10(%rax), %eax
movzwl -0x3e(%rbp), %ecx
cmpl %ecx, %eax
je 0x4010b
jmp 0x4012b
cmpl $0x3, -0xc(%rbp)
jne 0x40113
jmp 0x4012b
jmp 0x40115
jmp 0x40117
movq -0x88(%rbp), %rax
movb 0x9(%rax), %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x3f2fc
movq -0x18(%rbp), %rdi
callq 0x45050
testb $0x1, %al
jne 0x4013a
jmp 0x4013a
addq $0x120, %rsp            # imm = 0x120
popq %rbp
retq
nopw %cs:(%rax,%rax)
nopl (%rax)