// File: /workspace/github_cpp_makefile_star2_O2/chhylp123[P]hifiasm/Overlaps.cpp
// Function: get_ref_nid_flank(u_trans_t*, ma_ug_t*, ma_ug_t*, ma_ug_t*, scaf_res_t*, scaf_res_t*, unsigned long, unsigned long, unsigned long, asg32_v*)
uint64_t get_ref_nid_flank(u_trans_t *z, ma_ug_t *ref, ma_ug_t *hu1, ma_ug_t *hu2, scaf_res_t *cp1, scaf_res_t *cp2, uint64_t is_beg, uint64_t gap_bd, uint64_t flank_len, asg32_v *res)
{
    scaf_res_t *sc = NULL; uint64_t id, s_end, e_end, rn = res->n;
    if(z->tn < hu1->u.n) {
        sc = cp1; id = z->tn;
    } else {
        sc = cp2; id = z->tn - hu1->u.n;
    }

    if(is_beg) {
        s_end = 0; e_end = 1;
    } else {
        s_end = 1; e_end = 0;
    }

    if(z->rev) {
        s_end ^= 1; e_end ^= 1;
    }


    ul_vec_t *idx = &(sc->a[id]); uint64_t k, m, a_n, os, oe, m0; 
    uc_block_t *a, *am = NULL; uint64_t max_len = 0, cgap, clen; int64_t ami, amn = 0, as, ae, amz; 
    // if(z->tn == 5) {
    //     fprintf(stderr, "\n[M::%s] h1tg%.6u%c(%c)\ts::%u\te::%u\ts_end::%lu\te_end::%lu\n", __func__, z->tn+1, "lc"[hu1->u.a[z->tn].circ], "+-"[z->rev], z->ts, z->te, s_end, e_end);
    // }
    
    for (k = 0; k < idx->bb.n; k++) {
        a = idx->bb.a + idx->bb.a[k].ts; a_n = idx->bb.a[k].te - idx->bb.a[k].ts;
        os = MAX(z->ts, idx->bb.a[k].qs); 
        oe = MIN(z->te, idx->bb.a[k].qe);
        // if(z->tn == 5) {
        //     fprintf(stderr, "[M::%s] idx->bb.a[%lu]::[%u, %u), o[%lu, %lu), a_n::%lu\n", __func__, k, idx->bb.a[k].qs, idx->bb.a[k].qe, os, oe, a_n);
        // }
        if(os >= oe) continue;
        for(m = 0; m < a_n && a[m].qe <= os; m++); 
        // {
            // if(z->tn == 5) fprintf(stderr, "+(%lu)utg%.6u%c[%u,%u),", m, (a[m].hid)+1, "lc"[ref->u.a[a[m].hid].circ], a[m].qs, a[m].qe);
        // }
        // if(z->tn == 5) fprintf(stderr, "\n[M::%s] +m::%lu\n", __func__, m);
        if(m >= a_n) continue;
        for(m0 = m; m < a_n && a[m].qs < oe; m++); 
        // {
            // if(z->tn == 5) fprintf(stderr, "-(%lu)utg%.6u%c[%u,%u),", m, (a[m].hid)+1, "lc"[ref->u.a[a[m].hid].circ], a[m].qs, a[m].qe);
        // }
        // if(z->tn == 5) fprintf(stderr, "\n[M::%s] -m::%lu\n", __func__, m);
        if(m <= m0) continue;

        os = MAX(z->ts, a[m0].qs); 
        oe = MIN(z->te, a[m-1].qe);
        // if(z->tn == 5) {
        //     fprintf(stderr, "[M::%s] m0::%lu, m::%lu, o[%lu, %lu), a_n::%lu\n", __func__, m0, m, os, oe, a_n);
        // }
        if(oe <= os) continue;
        clen = oe - os; cgap = 0;
        if(s_end) {
            cgap = os - z->ts;
        } else if(e_end) {
            cgap = z->te - oe;
        }
        if(cgap > gap_bd) continue;
        if(clen > max_len) {
            max_len = clen; am = a + m0; amn = m - m0;
        }
    }

    // if(z->tn == 49 && z->ts == 0 && z->te == 2143149) {
    //     fprintf(stderr, "-0-[M::%s] h1tg%.6ul(%c)\tts::%u\tte::%u\tamn::%ld\ts_end::%lu\te_end::%lu\n", __func__,
    //     z->tn+1, "+-"[z->rev], z->ts, z->te, amn, s_end, e_end);
    // }

    // if(z->tn == 5) fprintf(stderr, "[M::%s] amn::%ld\n", __func__, amn);

    if((!am) || (!amn)) return 0;
    os = oe = 0; as = 0; ae = amn;
    if(s_end) {
        for(ami = 0; (ami < amn) && ((z->ts + flank_len) >= am[ami].qe); ami++);
        if((ami < amn) && ((z->ts + flank_len) >= am[ami].qs)) ami++;
        as = 0; ae = ami;
    } else if(e_end) {
        for(ami = amn - 1; (ami >= 0) && (z->te <= (am[ami].qs + flank_len)); ami--);
        if((ami >= 0) && (z->te <= (am[ami].qe + flank_len))) ami--;
        ami++; as = ami; ae = amn;
    }
    // if(z->tn == 49 && z->ts == 0 && z->te == 2143149) {
    //     fprintf(stderr, "-1-[M::%s] h1tg%.6ul(%c)\tts::%u\tte::%u\tas::%ld\tae::%ld\n", __func__,
    //     z->tn+1, "+-"[z->rev], z->ts, z->te, as, ae);
    // }
    // if(z->tn == 5) fprintf(stderr, "+[M::%s] as::%ld, ae::%ld\n", __func__, as, ae);
    if(as >= ae) return 0;
    
    ///make sure there are no identical node
    if(s_end) {
        for (ami = as; ami < ae; ami++) {
            for (amz = ami + 1; (amz < ae) && (am[ami].hid != am[amz].hid); amz++);
            if(amz < ae) {
                ae = ami + 1; break;
            }
        }
    } else if(e_end) {
        for (ami = ae - 1; ami >= as; ami--) {
            for (amz = ami - 1; (amz >= as) && (am[ami].hid != am[amz].hid); amz--);
            if(amz >= as) {
                as = ami; break;
            }
        }
    }
    // if(z->tn == 49 && z->ts == 0 && z->te == 2143149) {
    //     fprintf(stderr, "-1-[M::%s] h1tg%.6ul(%c)\tts::%u\tte::%u\tas::%ld\tae::%ld\n", __func__,
    //     z->tn+1, "+-"[z->rev], z->ts, z->te, as, ae);
    // }
    // if(z->tn == 5) fprintf(stderr, "+[M::%s] as::%ld, ae::%ld\n", __func__, as, ae);
    if(as >= ae) return 0;

    uint32_t *fp = NULL, r2n = 0;
    kv_resize(uint32_t, *res, rn + ((ae - as)<<1));
    for (ami = as; ami < ae; ami++) {
        m = ((uint64_t)(am[ami].hid<<1))|((uint64_t)(!!(am[ami].rev))); m ^= ((uint64_t)(!!(z->rev)));
        kv_push(uint32_t, *res, m);
    }
    rn = res->n - rn;
    if(z->rev) {
        fp = res->a + res->n - rn; r2n = rn>>1;
        for (k = 0; k < r2n; k++) {
            m = fp[k]; fp[k] = fp[rn - k -1]; fp[rn - k -1] = m;
        }
    }

    if(s_end) {
        for (ami = as; ami < ae; ami++) {
            m = ((am[ami].qs>=z->ts)?(am[ami].qs-z->ts):(0));
            kv_push(uint32_t, *res, m);
        }
    } else if(e_end) {
        for (ami = as; ami < ae; ami++) {
            m = ((z->te>=am[ami].qe)?(z->te-am[ami].qe):(0));
            kv_push(uint32_t, *res, m);
        }
    }
    if(z->rev) {
        fp = res->a + res->n - rn; r2n = rn>>1;
        for (k = 0; k < r2n; k++) {
            m = fp[k]; fp[k] = fp[rn - k - 1]; fp[rn - k - 1] = m;
        }
    }
    
    return rn;
    // return ((uint64_t)(am->hid<<1))|((uint64_t)(!!(am->rev))); 
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %rdi, %rbx
movl 0x14(%rdi), %eax
movq (%rdx), %rcx
xorl %edx, %edx
cmpq %rax, %rcx
cmovaq %rdx, %rcx
cmovbeq %r9, %r8
movq 0x88(%rsp), %rsi
subq %rcx, %rax
cmpq $0x0, 0x70(%rsp)
movq (%rsi), %rcx
movq %rcx, 0x28(%rsp)
setne %cl
movb 0x28(%rdi), %sil
shrb $0x6, %sil
xorb %cl, %sil
movb %sil, 0xf(%rsp)
movq (%r8), %rcx
imulq $0x58, %rax, %rax
leaq (%rcx,%rax), %rsi
addq $0x20, %rsi
movq (%rsi), %rdi
movq $0x0, 0x10(%rsp)
xorl %r8d, %r8d
movq $0x0, 0x18(%rsp)
cmpq %rdi, %rdx
je 0x9f379
movq 0x10(%rsi), %r11
imulq $0x24, %rdx, %r15
movl 0xc(%rbx), %r10d
movl 0x10(%rbx), %r9d
movl 0x4(%r11,%r15), %eax
movl 0x8(%r11,%r15), %ecx
cmpl %eax, %r10d
cmoval %r10d, %eax
cmpl %ecx, %r9d
cmovbl %r9d, %ecx
cmpl %ecx, %eax
jae 0x9f371
movl 0xc(%r11,%r15), %r13d
imulq $0x24, %r13, %rbp
leaq (%r11,%rbp), %r14
movl 0x10(%r11,%r15), %r12d
subl %r13d, %r12d
addq %r11, %rbp
addq $0x4, %rbp
movq %r14, %r11
xorl %r13d, %r13d
cmpq %r13, %r12
je 0x9f371
cmpl %eax, 0x8(%r11)
ja 0x9f2fb
incq %r13
addq $0x24, %r11
addq $0x24, %rbp
jmp 0x9f2df
movq %r13, %rax
cmpq %rax, %r12
je 0x9f314
cmpl %ecx, (%rbp)
jae 0x9f311
incq %rax
addq $0x24, %rbp
jmp 0x9f2fe
movq %rax, %r12
movq %r12, %rcx
subq %r13, %rcx
jbe 0x9f371
movl 0x4(%r11), %r15d
cmpl %r15d, %r10d
cmoval %r10d, %r15d
imulq $0x24, %r12, %rax
movl -0x1c(%r14,%rax), %eax
cmpl %eax, %r9d
cmovbl %r9d, %eax
cmpl %r15d, %eax
jbe 0x9f371
testb $0x1, 0xf(%rsp)
je 0x9f34a
je 0x9f352
subq %rax, %r9
jmp 0x9f355
movq %r15, %r9
subq %r10, %r9
jmp 0x9f355
xorl %r9d, %r9d
cmpq 0x78(%rsp), %r9
ja 0x9f371
subq %r15, %rax
cmpq %r8, %rax
jbe 0x9f371
movq %r11, 0x10(%rsp)
movq %rax, %r8
movq %rcx, 0x18(%rsp)
incq %rdx
jmp 0x9f284
xorl %r13d, %r13d
cmpq $0x0, 0x10(%rsp)
je 0x9f65b
movq 0x18(%rsp), %r8
testq %r8, %r8
je 0x9f65b
testb $0x1, 0xf(%rsp)
je 0x9f3fa
je 0x9f435
movq %r8, %r15
sarq $0x3f, %r15
andq %r8, %r15
imulq $0x24, %r8, %rax
movq 0x10(%rsp), %rcx
addq %rax, %rcx
addq $0x8, %rcx
movq %r8, %rax
testq %rax, %rax
jle 0x9f45f
decq %rax
movl 0x10(%rbx), %edx
movl -0x28(%rcx), %esi
addq 0x80(%rsp), %rsi
addq $-0x24, %rcx
cmpq %rdx, %rsi
jae 0x9f3c0
movl (%rcx), %ecx
addq 0x80(%rsp), %rcx
leaq 0x1(%rax), %r15
cmpq %rdx, %rcx
cmovaeq %rax, %r15
jmp 0x9f45f
xorl %r15d, %r15d
testq %r8, %r8
cmovleq %r15, %r8
movq 0x10(%rsp), %rax
leaq 0x8(%rax), %rcx
movq %r8, %rdx
negq %rdx
xorl %eax, %eax
cmpq %rax, %rdx
je 0x9f45f
movl 0xc(%rbx), %esi
addq 0x80(%rsp), %rsi
movl (%rcx), %edi
cmpq %rdi, %rsi
jb 0x9f44c
decq %rax
addq $0x24, %rcx
jmp 0x9f415
xorl %r15d, %r15d
movl $0x0, %r13d
testq %r8, %r8
jg 0x9f52a
jmp 0x9f65b
movl -0x4(%rcx), %ecx
cmpq %rcx, %rsi
adcq $-0x1, %rax
negq %rax
xorl %r15d, %r15d
movq %rax, %r8
cmpq %r8, %r15
jge 0x9f658
testb $0x1, 0xf(%rsp)
je 0x9f4cf
je 0x9f52a
imulq $0x24, %r8, %rax
movq 0x10(%rsp), %rcx
addq %rcx, %rax
addq $-0x48, %rax
leaq -0x1(%r8), %rcx
movq %r8, %rdx
cmpq %r15, %rdx
jle 0x9f52a
movq %r8, %r11
decq %rdx
imulq $0x24, %rdx, %rsi
addq 0x10(%rsp), %rsi
movq %rcx, %rdi
movq %rax, %r8
decq %rdi
cmpq %r15, %rdi
jl 0x9f4c3
leaq -0x24(%r8), %r9
movl (%rsi), %r10d
cmpl (%r8), %r10d
movq %r9, %r8
jne 0x9f4aa
jmp 0x9f524
addq $-0x24, %rax
decq %rcx
movq %r11, %r8
jmp 0x9f48c
imulq $0x24, %r15, %rax
movq 0x10(%rsp), %rcx
addq %rcx, %rax
addq $0x24, %rax
movq %r15, %rcx
cmpq %r8, %rcx
jge 0x9f52a
leaq 0x1(%rcx), %rdx
imulq $0x24, %rcx, %rsi
addq 0x10(%rsp), %rsi
movq %rax, %rdi
incq %rcx
cmpq %r8, %rcx
jge 0x9f516
movq %r8, %r10
leaq 0x24(%rdi), %r8
movl (%rsi), %r9d
cmpl (%rdi), %r9d
movq %r8, %rdi
movq %r10, %r8
jne 0x9f4f7
jmp 0x9f51f
addq $0x24, %rax
movq %rdx, %rcx
jmp 0x9f4e2
movq %rdx, %r8
jmp 0x9f52a
movq %rdx, %r15
movq %r11, %r8
movq %r8, %rax
subq %r15, %rax
movq 0x88(%rsp), %rsi
jle 0x9f658
movq 0x28(%rsp), %rcx
leaq (%rcx,%rax,2), %rax
cmpq %rax, 0x8(%rsi)
movq %r8, 0x18(%rsp)
jae 0x9f5b0
decq %rax
movq %rax, %rcx
shrq %rcx
orq %rax, %rcx
movq %rcx, %rax
shrq $0x2, %rax
orq %rcx, %rax
movq %rax, %rcx
shrq $0x4, %rcx
orq %rax, %rcx
movq %rcx, %rax
shrq $0x8, %rax
orq %rcx, %rax
movq %rax, %rcx
shrq $0x10, %rcx
orq %rax, %rcx
leaq 0x1(%rcx), %rax
movq %rax, 0x8(%rsi)
movq 0x10(%rsi), %rdi
leaq 0x4(,%rcx,4), %rsi
callq 0x2370
movq 0x18(%rsp), %r8
movq 0x88(%rsp), %rsi
movq %rax, 0x10(%rsi)
imulq $0x24, %r15, %rcx
movq 0x10(%rsp), %rax
movq %rcx, 0x20(%rsp)
leaq (%rcx,%rax), %r14
addq $0x20, %r14
movq %r15, %r12
movq %r15, 0x30(%rsp)
cmpq %r8, %r12
jge 0x9f66d
movl -0x20(%r14), %r15d
movl (%r14), %r13d
movl 0x28(%rbx), %ebp
movq (%rsi), %rcx
movq 0x10(%rsi), %rax
cmpq 0x8(%rsi), %rcx
jne 0x9f628
leaq (%rcx,%rcx), %rsi
testq %rcx, %rcx
pushq $0x2
popq %rcx
cmoveq %rcx, %rsi
movq 0x88(%rsp), %rcx
movq %rsi, 0x8(%rcx)
shlq $0x2, %rsi
movq %rax, %rdi
callq 0x2370
movq 0x18(%rsp), %r8
movq 0x88(%rsp), %rsi
movq %rax, 0x10(%rsi)
movq (%rsi), %rcx
shrl $0x5, %r13d
andl $0x1, %r13d
leal (%r13,%r15,2), %edx
shrl $0x6, %ebp
andl $0x1, %ebp
xorl %edx, %ebp
leaq 0x1(%rcx), %rdx
movq %rdx, (%rsi)
movl %ebp, (%rax,%rcx,4)
incq %r12
addq $0x24, %r14
movq 0x30(%rsp), %r15
jmp 0x9f5ce
xorl %r13d, %r13d
movq %r13, %rax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq (%rsi), %rcx
movq %rcx, %r13
movq 0x28(%rsp), %rax
subq %rax, %r13
testb $0x40, 0x28(%rbx)
jne 0x9f721
testb $0x1, 0xf(%rsp)
je 0x9f76b
je 0x9f7f2
movq 0x10(%rsp), %rax
movq 0x20(%rsp), %rdx
leaq (%rdx,%rax), %r12
addq $0x8, %r12
xorl %r14d, %r14d
movq 0x88(%rsp), %rsi
cmpq %r8, %r15
jge 0x9f7fa
movl 0x10(%rbx), %ebp
subl (%r12), %ebp
cmovbl %r14d, %ebp
movq 0x10(%rsi), %rax
cmpq 0x8(%rsi), %rcx
jne 0x9f70b
leaq (%rcx,%rcx), %rsi
testq %rcx, %rcx
pushq $0x2
popq %rcx
cmoveq %rcx, %rsi
movq 0x88(%rsp), %rcx
movq %rsi, 0x8(%rcx)
shlq $0x2, %rsi
movq %rax, %rdi
callq 0x2370
movq 0x18(%rsp), %r8
movq 0x88(%rsp), %rsi
movq %rax, 0x10(%rsi)
movq (%rsi), %rcx
leaq 0x1(%rcx), %rdx
movq %rdx, (%rsi)
movl %ebp, (%rax,%rcx,4)
incq %r15
addq $0x24, %r12
movq %rdx, %rcx
jmp 0x9f6b3
movq %rax, %rdi
movq 0x88(%rsp), %rax
movq 0x10(%rax), %rsi
movq %r13, %rax
shrq %rax
movl %eax, %eax
leaq (%rsi,%rcx,4), %rdx
addq $-0x4, %rdx
leaq (%rsi,%rdi,4), %rsi
xorl %edi, %edi
cmpq %rdi, %rax
je 0x9f685
movl (%rsi,%rdi,4), %r8d
movl (%rdx), %r9d
movl %r9d, (%rsi,%rdi,4)
movl %r8d, (%rdx)
movq 0x18(%rsp), %r8
incq %rdi
addq $-0x4, %rdx
jmp 0x9f746
movq 0x10(%rsp), %rax
movq 0x20(%rsp), %rdx
leaq (%rdx,%rax), %r12
addq $0x4, %r12
xorl %r14d, %r14d
movq 0x88(%rsp), %rsi
cmpq %r8, %r15
jge 0x9f7fa
movl (%r12), %ebp
subl 0xc(%rbx), %ebp
cmovbl %r14d, %ebp
movq 0x10(%rsi), %rax
cmpq 0x8(%rsi), %rcx
jne 0x9f7dc
leaq (%rcx,%rcx), %rsi
testq %rcx, %rcx
pushq $0x2
popq %rcx
cmoveq %rcx, %rsi
movq 0x88(%rsp), %rcx
movq %rsi, 0x8(%rcx)
shlq $0x2, %rsi
movq %rax, %rdi
callq 0x2370
movq 0x18(%rsp), %r8
movq 0x88(%rsp), %rsi
movq %rax, 0x10(%rsi)
movq (%rsi), %rcx
leaq 0x1(%rcx), %rdx
movq %rdx, (%rsi)
movl %ebp, (%rax,%rcx,4)
incq %r15
addq $0x24, %r12
movq %rdx, %rcx
jmp 0x9f788
movq 0x88(%rsp), %rsi
testb $0x40, 0x28(%rbx)
je 0x9f65b
movq 0x10(%rsi), %rsi
leaq (,%r13,4), %rdx
leaq (%rsi,%rcx,4), %rax
subq %rdx, %rax
movq %r13, %rdx
shrq %rdx
movl %edx, %edx
leaq (%rsi,%rcx,4), %rcx
addq $-0x4, %rcx
xorl %esi, %esi
cmpq %rsi, %rdx
je 0x9f65b
movl (%rax,%rsi,4), %edi
movl (%rcx), %r8d
movl %r8d, (%rax,%rsi,4)
movl %edi, (%rcx)
incq %rsi
addq $-0x4, %rcx
jmp 0x9f829