text:
"""
@author: Tobias Krauss, Anatoli Kalysch
"""
from idaapi import *
from idautils import *
from idc import *
from lib.Instruction import Instruction
from lib.Optimize import *
from lib.Register import (get_reg_by_size,
                          get_reg_class)
from lib.VmInstruction import VmInstruction
from lib.VmInstruction import (add_ret_pop,
                               to_vpush)

# import PseudoInstruction as PI
import distorm3
import lib.PseudoInstruction as PI
import lib.StartVal as SV
from ui.BBGraphViewer import show_graph
from lib.VMRepresentation import VMContext, get_vmr

bb_colors = [0xddddff, 0xffdddd, 0xddffdd, 0xffddff, 0xffffdd, 0xddffff]

def calc_code_addr(instr, base):
    """
    @param instr: Bytecode of a instruction of the virtual machine.
    @param base: Address of the jumptable of the virtual machine.
    @return Address of the executed x86 code
    """
    if SV.dissassm_type == SV.ASSEMBLER_32:
        return Dword((instr * 4) + base)
    else:
        return Qword((instr * 8) + base)

def get_instruction_list(vc, base):
    """
    @brief Generates a list of the executed x86 instructions for the
    given virtuel instruction (vc)
    @param vc: Bytecode of a instruction of the virtual machine.
    @param base: Address of the jumptable of the virtual machine.
    @return List of executed x86 instructions
    """
    inst_addr = calc_code_addr(vc, base)
    if not isCode(GetFlags(inst_addr)):
        MakeUnknown(inst_addr, 1, DOUNK_SIMPLE)
        MakeCode(inst_addr)
    inst_lst = []
    end_of_instruction_block = False
    while not end_of_instruction_block:
        size = ItemSize(inst_addr)
        inst_bytes = GetManyBytes(inst_addr, size)
        inst = Instruction(inst_addr, inst_bytes)
        if inst.is_uncnd_jmp():
            end_of_instruction_block = True
        elif inst.is_ret():
            inst_lst.append(inst)
            end_of_instruction_block = True
        else:
            inst_lst.append(inst)
            inst_addr = NextHead(inst_addr)
    return inst_lst

def clear_comments(ea, endaddr):
    """
    @brief Can be started from ida-python-shell.
    Clears all comments form ea to endaddr
    @param ea: Startaddress to remove comments
    @param endaddr: Endaddress
    """
    while ea <= endaddr:
        MakeComm(ea, "")
        ea = ea + 1

def get_start_push(vm_addr):
    """
    @brief Generates a list of the first instructions from the
    virtual machine
    @param vm_addr Address of the virtual machine function
    @return List of instructions
    """
    inst_addr = vm_addr
    ret = []
    end_of_instruction_block = False
    while not end_of_instruction_block:
        size = ItemSize(inst_addr)
        inst_bytes = GetManyBytes(inst_addr, size)
        inst = Instruction(inst_addr, inst_bytes)
        if inst.is_mov_basep_stackp():
            end_of_instruction_block = True
        else:
            inst_addr = NextHead(inst_addr)
            ret.append(inst)
    return ret

jump_dict = {}

def get_catch_reg(reg, length):
    """
    @brief Determines the right catch register for further usage
    @param reg Register from x86 code
    @param length Move size of catch instruction in bytes
    @return Register with right size or empty string
    """
    reg_class = get_reg_class(reg)
    if reg_class == None:
        return ''
    catch_reg = get_reg_by_size(reg_class, length * 8)
    if catch_reg == None:
        catch_reg = ''
    return catch_reg

def first_deobfuscate(ea, base, endaddr):
    """
    @brief Converts virtual code between ea and endaddr to VmInstructions
    @param ea Startaddress of virtual code
    @param base Address of the jumptable of the virtual machine.
    @param endaddr Endaddress of virtual code
    @return List of all VmInstructions between ea and endaddr
    """
    curraddr = ea
    instr_lst = []
    vminst_lst = []
    catch_value = None
    while curraddr <= endaddr:
        inst_addr = curraddr
        vc = Byte(curraddr)
        instr_lst = get_instruction_list(vc, base)
        if len(instr_lst) < 1:
            print 'error occured'
            curraddr += 1
            continue
        has_catch = False
        catch_instr = None
        for pos, inst in enumerate(instr_lst):
            if inst.is_catch_instr():
                catch_instr = inst
                has_catch = True
                break
        if has_catch:
            if catch_instr.is_byte_mov():
                catch_value = Byte(curraddr + 1)
                length = 2
            elif catch_instr.is_word_mov():
                catch_value = Word(curraddr + 1)
                length = 3
            elif catch_instr.is_double_mov():
                catch_value = Dword(curraddr + 1)
                length = 5
            elif catch_instr.is_quad_mov():
                catch_value = Qword(curraddr + 1)
                length = 9
        else:
            length = 1
        curraddr += length
        MakeUnknown(inst_addr, length, DOUNK_SIMPLE)
        if has_catch:
            catch_reg = get_catch_reg(catch_instr.get_op_str(1), length - 1)
        else:
            catch_reg = ''
        vm_inst = VmInstruction(instr_lst, catch_value,
                                catch_reg, inst_addr)
        vminst_lst.append(vm_inst)
        if (vm_inst.Pseudocode == None):
            continue
        if (vm_inst.Pseudocode.inst_type == PI.JMP_T or
                    vm_inst.Pseudocode.inst_type == PI.RET_T):
            if isCode(GetFlags(curraddr)):
                if curraddr in jump_dict:
                    curraddr = jump_dict[curraddr]
                    continue
                Jump(curraddr)
                answer = AskYN(0,
                               ('Should this regular x86 at address ' +
                                '{0:#x} instructions be deobfuscated?'.format(curraddr)))
                if answer == 0 or answer == -1:
                    old_addr = curraddr
                    curraddr = AskAddr(curraddr,
                                       'Insert Address where deobfuscation will be continued!')
                    jump_dict[old_addr] = curraddr
    return vminst_lst

def deobfuscate_all(base):
    """
    @brief Converts every possible virtual code to VmInstructions
    @param base Address of the jumptable of the virtual machine.
    @return List of all possible VmInstructions
    @remark This function is not used for deobfuscate the virtual code,
    its just a test if every possible virtual instruction is translated
    properly.
    """
    catch_byte = 0x00
    vm_inst_lst = []
    while catch_byte <= 0xff:
        inst_lst = get_instruction_list(catch_byte, base)
        vm_inst = VmInstruction(inst_lst, 0x0, '',
                                (SV.dissassm_type / 8 * catch_byte) + base)
        vm_inst.get_pseudo_code()
        vm_inst_lst.append(vm_inst)
        catch_byte += 1
    return vm_inst_lst

def display_ps_inst(ps_inst_lst):
    """
    @brief Displays PseudoInstructions in the comments of Ida
    @param ps_inst_lst List of PseudoInstructions
    """
    length = len(ps_inst_lst)
    comm = ''
    for pos, item in enumerate(ps_inst_lst):
        if pos < length - 1:
            addr = item.addr
            next_addr = ps_inst_lst[pos + 1].addr
        else:
            addr = item.addr
            next_addr = item.addr + 1
        if addr == next_addr:
            comm += str(item)[:len(str(item)) - 1] + '\t\t' + item.comment + '\n'
        else:
            comm += str(item)[:len(str(item)) - 1] + '\t\t' + item.comment + '\n'
            MakeComm(addr, comm)
            comm = ''

def display_vm_inst(vm_inst_lst):
    """
    @brief Displays VirtualInstructions in the comments of Ida
    @param vm_inst_lst List of VirtualInstructions
    """
    length = len(vm_inst_lst)
    comm = ''
    for pos, item in enumerate(vm_inst_lst):
        if pos < length - 1:
            addr = item.addr
            next_addr = vm_inst_lst[pos + 1].addr
        else:
            addr = item.addr
            next_addr = item.addr + 1
        if addr == next_addr:
            comm += str(item)[:len(str(item)) - 1] + '\n'
        else:
            comm += str(item)[:len(str(item)) - 1] + '\n'
            MakeComm(addr, comm)
            comm = ''

def read_in_comments(start, end):
    """
    @brief Read in all ida comments between start and end
    @param start Address where to start reading
    @param end Address where to end reading
    @return List of Tuples (comment, address of comment)
    """
    ret = []
    addr = start
    while addr <= end:
        comment = CommentEx(addr, 0)
        r_comment = CommentEx(addr, 1)
        if comment == None and r_comment == None:
            addr += 1
        elif r_comment == None and comment != None:
            ret.append((comment, addr))
            addr += 1
        elif r_comment != None and comment == None:
            print 'r_comment'
            ret.append((r_comment, addr))
            addr += 1
        else:
            erg_comm = r_comment + '\n' + comment
            ret.append((erg_comm, addr))
            addr += 1
    return ret

def find_start(start, end):
    """
    @brief tries to find startaddress of function due to
    crossrefernces

    @param start Startaddress of searching
    @param end Endaddress
    @return Startaddress of obfuscated function
    """
    addr = start
    erg = 0
    counter = 0
    while addr <= end:
        a = DfirstB(addr)
        if (a != BADADDR):
            counter += 1
            erg = addr
        addr += 1
    if counter != 1:
        print 'could not resolve start_addr'
        return BADADDR
    else:
        return erg

# Badaddr is set from Ida, so i can use this
def set_dissassembly_type():
    """
    @brief Determines if disassembly is 32 or 64 bitdeobfuscate
    """
    if BADADDR == 0xffffffffffffffff:
        SV.dissassm_type = SV.ASSEMBLER_64
    else:
        SV.dissassm_type = SV.ASSEMBLER_32

def get_jaddr_from_comments(pp_lst, comment_lst):
    """
    @brief reads in jump addresses wich were set by the
    reverse engineer

    @param pp_lst List of PseudoInstructions in push/pop represtentation
    @param comment_lst List of comments
    @return List of tuples (set jump address, address of jump instruction)
    """
    ret = []
    for comment, caddr in comment_lst:
        if 'jumps to: ' in comment:
            index = comment.find('jumps to: 0x')
            if index == -1:
                continue
            jmps = comment[index:len(comment)]
            index = jmps.find('0x')
            if index == -1:
                continue
            jmps = jmps[index:len(jmps)]
            str_lst = jmps.split(', ')
            for sub_str in str_lst:
                ret.append((long(sub_str, 16), caddr))
        else:
            continue
    return ret

def get_jmp_input_found(cjmp_addrs, jmp_addrs):
    """
    @brief Cobines the automatic found jump addresses
    with those from the reverse engineer

    @remark those addresses which were entered have preference
    @param cjmp_addrs Addresses form the reverse engineer
    @param jmp_addrs Automatic found addresses
    @return List of tuples (jump address, address of jump instruction)
    """
    ejmp_addrs = []
    ejmp_addrs += cjmp_addrs
    for (jaddr, inst_addr) in jmp_addrs:
        found = False
        for _, cinst_addr in cjmp_addrs:
            if cinst_addr == inst_addr:
                found = True
        if not found:
            ejmp_addrs.append((jaddr, inst_addr))
    return ejmp_addrs

def change_comments(pp_lst, cjmp_addrs):
    """
    @brief Sets the entered jump addresses in the comments
    of the PseudoInstructions

    @param pp_lst  List of PseudoInstructions in push/pop represtentation
    @param cjmp_addrs List of tuples (set jump address,
    address of jump instruction)
    """
    for item in pp_lst:
        if item.inst_type == PI.JMP_T:
            found_vals = []
            for jaddr, inst_addr in cjmp_addrs:
                if inst_addr == item.addr:
                    found_vals.append(jaddr)
            if len(found_vals) == 0:
                continue
            comment = 'jumps to: '
            found_addr = False
            for addr in found_vals:
                comment += '{0:#x}, '.format(addr)
            comment = comment[:len(comment) - 2]
            item.comment = comment

def get_jmp_addr(bb):
    """
    @param bb List of PseudoInstructions of one basic block
    @return Address of jump instruction in this basic block
    """
    for inst in bb:
        if inst.inst_type == PI.JMP_T:
            return inst.addr
    return None

def has_ret(bb):
    """
    @param bb List of PseudoInstructions of one basic block
    @return True if ret instruction is part of basic block, False otherwise
    """
    return (lambda bb: True if 'ret_T' in map(lambda inst: inst.inst_type, bb) else False)(bb)

def get_jmp_loc(jmp_addr, jmp_addrs):
    """
    @param jmp_addr Address of jmp instruction
    @param jmp_addrs List of Tuples (jump address, address of jmp instruction)
    @return A list of all addresses a jmp instruction can jump to
    """
    return [jmp_to for jmp_to, j_addr in jmp_addrs if j_addr == jmp_addr]

def deobfuscate(code_saddr,  base_addr, code_eaddr, vm_addr, display=4, real_start=0):
    """
    @brief This function does the deobfuscation between code_saddr and code_eaddr
    @param code_saddr Address of the start of obfuscated code
    @param base_addr Address of the jumptable of the virtual machine
    @param code_eaddr Address of the end of obfuscated code
    @param vm_addr Address of the virtual machine function
    @param display Set output type
        * 0 : VirtualInstruction
        * 1 : PseudoInstruction Push/Pop representation
        * 2 : PseudoInstruction full optimized
    @param real_start Address of entry point of the function
    @return The lowest found jump address
    """
    set_dissassembly_type()
    comment_list = read_in_comments(code_saddr, code_eaddr)
    if real_start == 0:
        start_addr = find_start(code_saddr, code_eaddr)
    else:
        start_addr = real_start
    if start_addr == BADADDR:
        start_addr = code_saddr
    f_start_lst = []
    if vm_addr != 0:
        f_start_lst = get_start_push(vm_addr)
        f_start_lst = to_vpush(f_start_lst, start_addr)
    vm_inst_lst = first_deobfuscate(code_saddr, base_addr, code_eaddr)
    vm_inst_lst1 = deobfuscate_all(base_addr)
    display_vm_inst(vm_inst_lst1)
    pseudo_lst = add_ret_pop(vm_inst_lst)
    push_pop_lst = []
    lst = []
    for inst in pseudo_lst:
        if inst.addr == start_addr:
            lst = f_start_lst
        lst += inst.make_pop_push_rep()
        for rep in lst:
            push_pop_lst.append(rep)
        lst = []
    cjmp_addrs = get_jaddr_from_comments(push_pop_lst, comment_list)
    jmp_addrs = get_jmp_addresses(push_pop_lst, code_eaddr)
    jmp_addrs = get_jmp_input_found(cjmp_addrs, jmp_addrs)
    change_comments(push_pop_lst, cjmp_addrs)
    basic_blocks = find_basic_blocks(push_pop_lst, start_addr, jmp_addrs)
    if basic_blocks == None:
        basic_blocks = [(code_saddr, code_eaddr)]
    color_basic_blocks(basic_blocks)
    basic_lst = make_bb_lists(push_pop_lst, basic_blocks)
    has_loc = has_locals(basic_lst)
    clear_comments(code_saddr, code_eaddr)
    if display == 0:
        vm_list = f_start_lst + pseudo_lst
        display_vm_inst(vm_list)
    elif display == 1:
        display_ps_inst(push_pop_lst)
    else:
        opt_basic = []
        display_lst = []
        nodes = []
        edges = []
        for lst in basic_lst:
            opt_lst = optimize(lst, has_loc)
            display_lst += opt_lst
            opt_basic.append(opt_lst)
        display_ps_inst(display_lst)
        for node, bb in enumerate(opt_basic):
            if bb == []:
                continue
            nodes.append(('bb%d' % (node)))

            if has_ret(bb):
                continue

            jmp_addr = get_jmp_addr(bb)
            if jmp_addr == None:
                edges.append(('bb%d' % (node), 'bb%d' % (node + 1)))
            else:
                jmp_locs = get_jmp_loc(jmp_addr, jmp_addrs)
                for loc in jmp_locs:
                    for pos, (saddr, eaddr) in enumerate(basic_blocks):
                        if loc >= saddr and loc < eaddr:
                            edges.append(('bb%d' % (node), 'bb%d' % (pos)))
        try:
            g = show_graph(nodes, edges, opt_basic, jmp_addrs, basic_blocks, real_start)
        except Exception, e:
            print e.message
    if jmp_addrs != []:
        min_jmp = min(jmp_addrs)[0]
    else:
        min_jmp = BADADDR
    return min_jmp

# need this to auto delete all variables
# so there are no objects left in ida python shell
# TODO
# * problem mit x64 push/pop
# * vebpmov Problem?
# * evtl schreibe start push to comments
def start(code_saddr, base_addr, code_eaddr, vm_addr, display=4, real_start=0):
    """
    @brief Entrypoint of the deobfuscation; starts
    deobfuscate until the minimal code start address is found
    @param code_saddr Address of the start of obfuscated code
    @param base_addr Address of the jumptable of the virtual machine
    @param code_eaddr Address of the end of obfuscated code
    @param vm_addr Address of the virtual machine function
    @param display Set output type
        * 0 : VirtualInstruction
        * 1 : PseudoInstruction Push/Pop representation
        * 2 : PseudoInstruction full optimized
    @param real_start Address of entry point of the function
    """
    old_min = BADADDR
    n_min = code_saddr
    start = real_start
    while old_min > n_min:
        old_min = n_min
        n_min = deobfuscate(old_min, base_addr, code_eaddr, vm_addr, display, start)
        if start == 0:
            start = code_saddr
            # if n_min < 0x4048b6:# TODO
            #    break

def color_basic_blocks(basic_lst):
    """
    @brief Colors the basic blocks
    @param basic_lst List of Tuples: (address start basic block,
    address end basic block)
    """
    color = 0
    for start, end in basic_lst:
        if (start + 1 == end):
            continue
        pos = start
        while pos < end:
            SetColor(pos, CIC_ITEM, bb_colors[color % len(bb_colors)])
            pos += 1
        color += 1

def make_bb_lists(pp_lst, basic_lst):
    """
    @brief Generates basic blocks and returns them in a list
    @param pp_lst  List of PseudoInstructions in push/pop represtentation
    @param basic_lst List of Tuples: (address start basic block,
    address end basic block)
    @return List of basic block lists
    """
    bb_lists = []
    for (s_addr, e_addr) in basic_lst:
        bb_lst = []
        for inst in pp_lst:
            if inst.addr >= s_addr and inst.addr < e_addr:
                bb_lst.append(inst)
        bb_lists.append(bb_lst)
    return bb_lists

def has_locals(bb_lsts):
    """
    @brief Determines if the function reserves space for local variables
    @param List of basic blocks
    @return True if function has locals, False otherwise
    """
    has_ebp_mov = False
    for bb in bb_lsts:
        has_ebp_mov = False
        for inst in bb:
            if inst.inst_type == PI.MOV_EBP_T:
                has_ebp_mov = True
            if inst.inst_type == PI.RET_T and has_ebp_mov:
                return True
    return False

def print_bb(bb_lsts):
    """
    @brief Print start and end of basic block; is used for debugging
    @param bb_lsts List of basic block lists
    """
    block_count = 1
    for lst in bb_lsts:
        print 'Start BB', block_count
        for inst in lst:
            print str(inst)[:len(str(inst)) - 1]
        print 'End BB', block_count
        block_count += 1

def get_distorm_info(inst_addr):
    """
    @brief Prints whole distrom3 info of the given instruction
    @param inst_addr Address of instruction
    """
    size = ItemSize(inst_addr)
    inst_bytes = GetManyBytes(inst_addr, size)
    inst = distorm3.Decompose(inst_addr,
                              inst_bytes, distorm3.Decode64Bits, 0)
    print inst[0]
    i = inst[0]
    print 'InstBytes ', i.instructionBytes
    print 'Opcode ', i.opcode
    for o in i.operands:
        print 'operand ', o
        print 'operand type', o.type
    for f in i.flags:
        print 'flag ', f
        print 'raw_flags ', i.rawFlags
    print 'inst_class ', i.instructionClass
    print 'flow_control ', i.flowControl
    print 'address ', i.address
    print 'size ', i.size
    print 'dt ', i.dt
    print 'valid ', i.valid
    print 'segment ', i.segment
    print 'unused_Prefixes ', i.unusedPrefixesMask
    print 'mnemonic ', i.mnemonic
    print 'inst_class ', i.instructionClass

def jmp_to_orig(address, base):
    """
    @brief Jumps to the executed x86 code
    @param address Address of virtual code
    @param base Address of the jumptable of the virtual machine
    """
    if SV.dissassm_type == 64:
        Jump(Qword((Byte(address) * 8) + base))
    else:
        Jump(Dword((Byte(address) * 4) + base))

        ###########
        # outdated
        ###########

        # change bad prog style
        # def reg_to_value(instr_lst, reg, value):
        #    erg = []
        #    for item in instr_lst:
        #        if reg in item.Op1:
        #            item.Op1 = item.Op1.replace(reg, '{0:#x}'.format(value))
        #        if reg in item.Op2:
        #            item.Op2 = item.Op2.replace(reg, '{0:#x}'.format(value))
        #        erg.append(item)
        #    return erg

        # def remove_vm_inst(instr_lst):
        #    erg = []
        #    for item in instr_lst:
        #        if not item.is_vinst():
        #            erg.append(item)
        #    return erg

        # seems to work
        # def test_scretch_operand():
        #    t60 = PI.ScretchOperand(PI.SVARIABLE_T, 60, 4)
        #    t10 = PI.ScretchOperand(PI.SVARIABLE_T, 60, 4)
        #    t11 = PI.ScretchOperand(PI.SVARIABLE_T, 11, 4)
        #
        #    inst0 = PI.PseudoInstruction('vpop', 0, [t60], 4)
        #    inst1 = PI.PseudoInstruction('vpop', 0, [t10], 4)
        # inst1.op_lst[0].value = 0xcaffee
        # inst0.op_lst[0].value = 0xbabe5
        #    print inst1.op_lst[0].value
        #    print '{0:#x}'.format(inst1.op_lst[0].value)

def static_vmctx(manual=False):
    """
    Compute the VM context values statically.
    :param manual: Bool -> Print result to the console
    """
    vm_ctx = VMContext()
    vm_seg_start = None
    vm_seg_end = None
    prev = 0
    # try to find the vm Segment via name -> easiest case but also easy to foil
    for addr in Segments():
        if SegName(addr).startswith('.vmp'):
            vm_seg_start = SegStart(addr)
            vm_seg_end = SegEnd(addr)
            break
    for f in Functions(vm_seg_start, vm_seg_end):
        if (GetFunctionAttr(f, FUNCATTR_END) - GetFunctionAttr(f, FUNCATTR_START)) > prev:
            prev = GetFunctionAttr(f, FUNCATTR_END) - GetFunctionAttr(f, FUNCATTR_START)
            vm_addr = f

    base_addr = NextHead(vm_addr)
    while base_addr < vm_seg_end:
        if GetMnem(base_addr).startswith('jmp'):
            try:
                base_addr = int(re.findall(r'.*off_([0123456789abcdefABCDEF]*)\[.*\]', GetOpnd(base_addr, 0))[0], 16)
                break
            except Exception, e:
                print e.message
                print e.args
        else:
            base_addr = NextHead(base_addr)
    if base_addr > vm_seg_end:
        base_addr = AskAddr(base_addr, 'Could not determine the Startaddr of the jmp table, please specify: ')

    code_start = PrevAddr(vm_seg_end)
    while not GetDisasm(code_start).__contains__('jmp'):
        code_start = PrevAddr(code_start)
    code_end = vm_seg_end
    code_start += 1

    vm_ctx.code_start = code_start
    vm_ctx.code_end = code_end
    vm_ctx.base_addr = base_addr
    vm_ctx.vm_addr = vm_addr

    vmr = get_vmr()
    vmr.vm_ctx = vm_ctx

    if manual:
        print 'Code Start: %x; Code End: %x; Base Addr: %x; VM Addr: %x' % (code_start, code_end, base_addr, vm_addr)

def static_deobfuscate(display=0, userchoice=False):
    """
    Wrapper for deobfuscate function which allows for manual user Input.
    :param display: Bool -> use output window or BBGraphViewer
    :param userchoice: let user input vm context values
    """
    vmr = get_vmr()
    if vmr.code_start == BADADDR:
        try:
            vm_ctx = static_vmctx()
            vmr.vm_ctx = vm_ctx
        except Exception, e:
            print e.message
            print e.args
    if userchoice:
        code_start = AskAddr(vmr.code_start, 'Choose start of byte code:')
        code_end = AskAddr(vmr.code_end, 'Choose end of byte code:')
        base_addr = AskAddr(vmr.base_addr, 'Coose start of jmp table:')
        vm_addr = AskAddr(vmr.vm_addr, 'Choose start of the virtual machine function:')
        deobfuscate(code_start, base_addr, code_end, vm_addr, display)
    else:
        deobfuscate(vmr.code_start, vmr.base_addr, vmr.code_end, vmr.vm_addr, display)


text:
In the following example, we'll render our Unity Application using a device pixel ratio which matches the device pixel ratio of the browser. We'll create an event listener using a media matcher which will update the device pixel ratio of the Unity Application when the device pixel ratio changes.

```jsx showLineNumbers title="App.jsx"
import React, { useState, useEffect, useCallback } from "react";
import { Unity, useUnityContext } from "react-unity-webgl";

function App() {
  const { unityProvider, isLoaded, loadingProgression } = useUnityContext({
    loaderUrl: "build/myunityapp.loader.js",
    dataUrl: "build/myunityapp.data",
    frameworkUrl: "build/myunityapp.framework.js",
    codeUrl: "build/myunityapp.wasm",
  });

  // We'll use a state to store the device pixel ratio.
  const [devicePixelRatio, setDevicePixelRatio] = useState(
    window.devicePixelRatio
  );

  const handleChangePixelRatio = useCallback(
    function () {
      // A function which will update the device pixel ratio of the Unity
      // Application to match the device pixel ratio of the browser.
      const updateDevicePixelRatio = function () {
        setDevicePixelRatio(window.devicePixelRatio);
      };
      // A media matcher which watches for changes in the device pixel ratio.
      const mediaMatcher = window.matchMedia(
        `screen and (resolution: ${devicePixelRatio}dppx)`
      );
      // Adding an event listener to the media matcher which will update the
      // device pixel ratio of the Unity Application when the device pixel
      // ratio changes.
      mediaMatcher.addEventListener("change", updateDevicePixelRatio);
      return function () {
        // Removing the event listener when the component unmounts.
        mediaMatcher.removeEventListener("change", updateDevicePixelRatio);
      };
    },
    [devicePixelRatio]
  );

  return (
    <Unity
      unityProvider={unityProvider}
      style={{ width: 800, height: 600 }}
      devicePixelRatio={devicePixelRatio}
    />
  );
}
```

redpajama_set_name: RedPajamaGithub


text:
 define(function(require, exports, module){

    var Backbone = require('backbone');

    var privilegeModel = Backbone.Model.extend({

        urlRoot: '/privileges',
        //url: function(){
        //    var origUrl = Backbone.Model.prototype.url.call(this);
        //    var parsedUrl = origUrl + (origUrl.charAt(origUrl.length - 1) == '/' ? '' : '/');
        //    return parsedUrl;

        //},

        defaults: {
            priv_name: '',
            priv_desc: '',
            priv_type: '',
            criteria: '',
            enabled: '',
            is_selected: false
        },

        // set is_selected attribute status.
        toggle_select: function() {
            this.set({is_selected: !this.get('is_selected')});
        }
    });

    module.exports = privilegeModel;
 });


text:
#ifndef STROMX_RUNTIME_OUTPUTNODETEST_H
#define STROMX_RUNTIME_OUTPUTNODETEST_H

#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/TestFixture.h>
#include "stromx/runtime/DataContainer.h"

namespace stromx
{
    namespace runtime
    {
        class Operator;

        namespace impl
        {
            class OutputNode;
            class InputNode;
        }

        class OutputNodeTest : public CPPUNIT_NS :: TestFixture
        {
            CPPUNIT_TEST_SUITE (OutputNodeTest);
            CPPUNIT_TEST(testGetOutputData);
            CPPUNIT_TEST(testAddConnectedInputs);
            CPPUNIT_TEST(testRemoveConnectedInputs);
            CPPUNIT_TEST(testTwoInputs);
            CPPUNIT_TEST(testReset);
            CPPUNIT_TEST_SUITE_END ();

        public:
            OutputNodeTest() : m_operatorWrapper(0), m_outputNode(0) {}

            void setUp();
            void tearDown();

        protected:
            void testGetOutputData();
            void testAddConnectedInputs();
            void testRemoveConnectedInputs();
            void testTwoInputs();
            void testReset();

        private:
            Operator* m_operatorWrapper;
            DataContainer m_container;
            impl::OutputNode* m_outputNode;
        };
    }
}

#endif // STROMX_RUNTIME_OUTPUTNODETEST_H


text:
package com.helicalinsight.efw.utility;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;

/**
 * The class uses RandomAccessFile api to write a file with a particular
 * encoding
 *
 * @author Rajasekhar
 */
public class FileStatusInspectionUtility {

    private static final Logger logger = LoggerFactory.getLogger(FileStatusInspectionUtility.class);

    /**
     * returns true only if the file is completely written
     *
     * @param file       The file to written
     * @param htmlString The content of the file to be written
     * @param encoding   Encoding of the content. Usually utf-8
     * @return true only if the file is completely written
     */
    public boolean isCompletelyWritten(File file, String htmlString, String encoding) {
        RandomAccessFile stream = null;
        try {
            stream = new RandomAccessFile(file, "rw");
            byte[] html = htmlString.getBytes(encoding);
            stream.write(html);
            return true;
        } catch (IOException ex) {
            logger.error("Exception stack trace is ", ex);
            logger.info("Skipping file " + file.getName() + " as it's not completely written");
        } finally {
            ApplicationUtilities.closeResource(stream);
        }
        return false;
    }
}


text:
<?php
namespace Eduardokum\LaravelBoleto\Cnab\Retorno;

use Eduardokum\LaravelBoleto\Contracts\Boleto\Boleto as BoletoContract;
use Eduardokum\LaravelBoleto\Contracts\Cnab\Retorno;
use Eduardokum\LaravelBoleto\Util;

class Factory
{
    /**
     * @param $file
     *
     * @return Retorno
     * @throws \Exception
     */
    public static function make($file)
    {
        if (!$file_content = Util::file2array($file)) {
            throw new \Exception("Arquivo: não existe");
        }

        if (!Util::isHeaderRetorno($file_content[0])) {
            throw new \Exception("Arquivo: $file, não é um arquivo de retorno");
        }

        $instancia = self::getBancoClass($file_content);
        return $instancia->processar();
    }

    /**
     * @param $file_content
     *
     * @return mixed
     * @throws \Exception
     */
    private static function getBancoClass($file_content)
    {
        $banco = '';
        $namespace = '';
        if (Util::isCnab400($file_content)) {
            $banco = mb_substr($file_content[0], 76, 3);
            $namespace = __NAMESPACE__ . '\\Cnab400\\';
        } elseif (Util::isCnab240($file_content)) {
            $banco = mb_substr($file_content[0], 0, 3);
            $namespace = __NAMESPACE__ . '\\Cnab240\\';
        }

        $aBancos = [
            BoletoContract::COD_BANCO_BB => 'Banco\\Bb',
            BoletoContract::COD_BANCO_SANTANDER => 'Banco\\Santander',
            BoletoContract::COD_BANCO_CEF => 'Banco\\Caixa',
            BoletoContract::COD_BANCO_INTER => 'Banco\\Inter',
            BoletoContract::COD_BANCO_BRADESCO => 'Banco\\Bradesco',
            BoletoContract::COD_BANCO_ITAU => 'Banco\\Itau',
            BoletoContract::COD_BANCO_HSBC => 'Banco\\Hsbc',
            BoletoContract::COD_BANCO_SICREDI => 'Banco\\Sicredi',
            BoletoContract::COD_BANCO_BANRISUL => 'Banco\\Banrisul',
            BoletoContract::COD_BANCO_BANCOOB => 'Banco\\Bancoob',
            BoletoContract::COD_BANCO_BNB => 'Banco\\Bnb',
            BoletoContract::COD_BANCO_UNICRED => 'Banco\\Unicred',
        ];

        if (array_key_exists($banco, $aBancos)) {
            $bancoClass = $namespace . Util::getBancoClass($banco);
            return new $bancoClass($file_content);
        }

        throw new \Exception("Banco: $banco, inválido");
    }
}


text:
require 'analysand'
require 'celluloid'
require 'listen'

# Watches a directory containing CouchDB documents for changes and installs
# said changes.
class CouchdbDocUpdater
  include Celluloid
  include Celluloid::Logger

  def initialize(path, uri, credentials)
    @db = Analysand::Database.new(uri)
    @credentials = credentials
    @path = path

    start_listener
  end

  def stop
    @listener.stop
  end

  def id_from_path(path)
    raise '#id_from_path must be implemented'
  end

  def start_listener
    @listener = Listen.to(@path) do |modified, added, removed|
      removed.each { |path| delete_set(path) }
      added.each { |path| add_set(path) }
      modified.each { |path| add_set(path) }
    end

    @listener.only /\.json$/
    @listener.start
  end

  def add_set(path)
    doc_id = id_from_path(path)
    doc = JSON.parse(File.read(path))

    resp = @db.head(doc_id, @credentials)
    rev = resp.etag if resp.success?
    doc['_rev'] = rev if rev

    resp = @db.put(doc_id, doc, @credentials)
    info "PUT #{@db.uri}#{doc_id} #{resp.code}"
  end

  def delete_set(path)
    doc_id = id_from_path(path)

    resp = @db.head(doc_id, @credentials)
    rev = resp.etag if resp.success?

    @db.delete(doc_id, rev, @credentials)
    info "DELETE #{@db.uri}#{doc_id} #{resp.code}"
  end
end


text:
/**/
/* font */
/**/
@import url(http://fonts.googleapis.com/css?family=Open+Sans:300,400,700);

/**/
/* defaults */
/**/
.crazy-form {
	margin: 0;
	outline: none;
	box-shadow: 0 0 20px rgba(0,0,0,.3);
	font: 10px/1.55 'Open Sans', Helvetica, Arial, sans-serif;
	color: #666;
}
.crazy-form header {
	display: block;
	padding: 8px 4px;
	border-bottom: 1px solid rgba(0,0,0,.1);
	background: rgba(15,0,111,.9);
	font-size: 25px;
	font-weight: 300;
	color: #FFFFFF;
}
.crazy-form fieldset {
	display: block;
	padding: 8px 9px 0.5px;
	border: none;
	background: rgba(255,255,255,.9);
}
.crazy-form fieldset + fieldset {
	border-top: 1px solid rgba(0,0,0,.1);
}
.crazy-form section {
	margin-bottom: 8px;
}
.crazy-form footer {
	display: block;
	padding: 15px 30px 25px;
	border-top: 1px solid rgba(0,0,0,.1);
	background: rgba(248,248,248,.9);
}
.crazy-form footer:after {
	content: '';
	display: table;
	clear: both;
}
.crazy-form a {
	color: #2da5da;
}
.crazy-form .label {
	display: block;
	margin-bottom: 6px;
	line-height: 19px;
	font-weight: 400;
}
.crazy-form .label.col {
	margin: 0;
	padding-top: 10px;
}
.crazy-form .note {
	margin-top: 6px;
	padding: 0 1px;
	font-size: 11px;
	line-height: 15px;
	color: #999;
}
.crazy-form .input,
.crazy-form .select,
.crazy-form .textarea,
.crazy-form .radio,
.crazy-form .checkbox,
.crazy-form .toggle,
.crazy-form .button {
	position: relative;
	display: block;
}
.crazy-form .input input,
.crazy-form .select select,
.crazy-form .textarea textarea {
	display: block;
	box-sizing: border-box;
	-moz-box-sizing: border-box;
	width: 100%;
	height: 39px;
	padding: 6px 10px;
	outline: none;
	border-width: 2px;
	border-style: solid;
	border-radius: 0;
	background: #fff;
	font: 15px/23px 'Open Sans', Helvetica, Arial, sans-serif;
	color: #404040;
	appearance: normal;
	-moz-appearance: none;
	-webkit-appearance: none;
}
.crazy-form .progress {
	float: right;
	margin-top: 10px;
	line-height: 39px;
	color: #232323;
}
.crazy-form button::-moz-focus-inner {
	padding: 0;
	border: 0;
}

/**/
/* captcha inputs */
/**/
.crazy-form .input-captcha img {
	position: absolute;
	top: 2px;
	right: 2px;
	border-left: 1px solid #e5e5e5;
}

/**/
/* file inputs */
/**/
.crazy-form .input-file .button {
	position: absolute;
	top: 4px;
	right: 4px;
	float: none;
	height: 31px;
	margin: 0;
	padding: 0 20px;
	font-size: 13px;
	line-height: 31px;
}
.crazy-form .input-file .button:hover {
	box-shadow: none;
}
.crazy-form .input-file .button input {
	position: absolute;
	top: 0;
	right: 0;
	padding: 0;
	font-size: 30px;
	cursor: pointer;
	opacity: 0;
}

/**/
/* selects */
/**/
.crazy-form .select i {
	position: absolute;
	top: 2px;
	right: 2px;
	width: 28px;
	height: 35px;
	background: #fff;
	pointer-events: none;
}
.crazy-form .select i:after,
.crazy-form .select i:before {
	content: '';
	position: absolute;
	right: 10px;
	border-right: 4px solid transparent;
	border-left: 4px solid transparent;
}
.crazy-form .select i:after {
	bottom: 12px;
	border-top: 4px solid #404040;
}
.crazy-form .select i:before {
	top: 12px;
	border-bottom: 4px solid #404040;
}
.crazy-form .select select {
	padding-right: 28px;
}
.crazy-form .select-multiple select {
	height: auto;
}

/**/
/* textareas */
/**/
.crazy-form .textarea textarea {
	height: auto;
	resize: none;
}
.crazy-form .textarea-resizable textarea {
	resize: vertical;
}
.crazy-form .textarea-expandable textarea {
	height: 39px;
}
.crazy-form .textarea-expandable textarea:focus {
	height: auto;
}

/**/
/* radios and checkboxes */
/**/
.crazy-form .radio,
.crazy-form .checkbox {
	margin-bottom: 4px;
	padding-left: 27px;
	font-size: 15px;
	line-height: 27px;
	color: #404040;
	cursor: pointer;
}
.crazy-form .radio:last-child,
.crazy-form .checkbox:last-child {
	margin-bottom: 0;
}
.crazy-form .radio input,
.crazy-form .checkbox input {
	position: absolute;
	left: -9999px;
}
.crazy-form .radio i,
.crazy-form .checkbox i {
	position: absolute;
	top: 5px;
	left: 0;
	display: block;
	width: 13px;
	height: 13px;
	outline: none;
	border-width: 2px;
	border-style: solid;
	background: #fff;
}
.crazy-form .radio i {
	border-radius: 50%;
}
.crazy-form .radio input + i:after,
.crazy-form .checkbox input + i:after {
	position: absolute;
	opacity: 0;
	-ms-transition: opacity 0.1s;
	-moz-transition: opacity 0.1s;
	-webkit-transition: opacity 0.1s;
}
.crazy-form .radio input + i:after {
	content: '';
	top: 4px;
	left: 4px;
	width: 5px;
	height: 5px;
	border-radius: 50%;
}
.crazy-form .checkbox input + i:after {
	content: '\f00c';
	top: -1px;
	left: -1px;
	width: 15px;
	height: 15px;
	font: normal 12px/16px FontAwesome;
	text-align: center;
}
.crazy-form .radio input:checked + i:after,
.crazy-form .checkbox input:checked + i:after {
	opacity: 1;
}
.crazy-form .inline-group {
	margin: 0 -30px -4px 0;
}
.crazy-form .inline-group:after {
	content: '';
	display: table;
	clear: both;
}
.crazy-form .inline-group .radio,
.crazy-form .inline-group .checkbox {
	float: left;
	margin-right: 30px;
}
.crazy-form .inline-group .radio:last-child,
.crazy-form .inline-group .checkbox:last-child {
	margin-bottom: 4px;
}

/**/
/* toggles */
/**/
.crazy-form .toggle {
	margin-bottom: 4px;
	padding-right: 61px;
	font-size: 15px;
	line-height: 27px;
	color: #404040;
	cursor: pointer;
}
.crazy-form .toggle:last-child {
	margin-bottom: 0;
}
.crazy-form .toggle input {
	position: absolute;
	left: -9999px;
}
.crazy-form .toggle i {
	content: '';
	position: absolute;
	top: 4px;
	right: 0;
	display: block;
	width: 49px;
	height: 17px;
	border-width: 2px;
	border-style: solid;
	border-radius: 12px;
	background: #fff;
}
.crazy-form .toggle i:after {
	content: 'OFF';
	position: absolute;
	top: 2px;
	right: 8px;
	left: 8px;
	font-style: normal;
	font-size: 9px;
	line-height: 13px;
	font-weight: 700;
	text-align: left;
	color: #5f5f5f;
}
.crazy-form .toggle i:before {
	content: '';
	position: absolute;
	z-index: 1;
	top: 4px;
	right: 4px;
	display: block;
	width: 9px;
	height: 9px;
	border-radius: 50%;
	opacity: 1;
	-ms-transition: right 0.2s;
	-moz-transition: right 0.2s;
	-webkit-transition: right 0.2s;
}
.crazy-form .toggle input:checked + i:after {
	content: 'ON';
	text-align: right;
}
.crazy-form .toggle input:checked + i:before {
	right: 36px;
}

/**/
/* ratings */
/**/
.crazy-form .rating {
	margin-bottom: 4px;
	font-size: 15px;
	line-height: 27px;
	color: #404040;
}
.crazy-form .rating:last-child {
	margin-bottom: 0;
}
.crazy-form .rating input {
	position: absolute;
	left: -9999px;
}
.crazy-form .rating label {
	display: block;
	float: right;
	height: 17px;
	margin-top: 5px;
	padding: 0 2px;
	font-size: 17px;
	line-height: 17px;
	cursor: pointer;
}

/**/
/* buttons */
/**/
.crazy-form .button {
	float: right;
	height: 39px;
	overflow: hidden;
	margin: 10px 0 0 20px;
	padding: 0 25px;
	outline: none;
	border: 0;
	font: 300 15px/39px 'Open Sans', Helvetica, Arial, sans-serif;
	text-decoration: none;
	color: #fff;
	cursor: pointer;
}
.crazy-form .button-uploading {
	position: relative;
	color: transparent;
	cursor: default;
}
.crazy-form .button-uploading:after {
	content: 'Uploading...';
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	color: #fff;
	-o-animation: blink 1s linear infinite;
	-ms-animation: blink 1s linear infinite;
	-moz-animation: blink 1s linear infinite;
	-webkit-animation: blink 1s linear infinite;
}
@-o-keyframes blink
{
  0% {opacity: 1}
  50% {opacity: 0.3}
  100% {opacity: 1}
}
@-ms-keyframes blink
{
  0% {opacity: 1}
  50% {opacity: 0.3}
  100% {opacity: 1}
}
@-moz-keyframes blink
{
  0% {opacity: 1}
  50% {opacity: 0.3}
  100% {opacity: 1}
}
@-webkit-keyframes blink
{
  0% {opacity: 1}
  50% {opacity: 0.3}
  100% {opacity: 1}
}

/**/
/* icons */
/**/
.crazy-form .icon-append,
.crazy-form .icon-prepend {
	position: absolute;
	top: 5px;
	width: 29px;
	height: 29px;
	font-size: 15px;
	line-height: 29px;
	text-align: center;
}
.crazy-form .icon-append {
	right: 5px;
	padding-left: 3px;
	border-left-width: 1px;
	border-left-style: solid;
}
.crazy-form .icon-prepend {
	left: 5px;
	padding-right: 3px;
	border-right-width: 1px;
	border-right-style: solid;
}
.crazy-form .input .icon-prepend + input,
.crazy-form .textarea .icon-prepend + textarea {
	padding-left: 46px;
}
.crazy-form .input .icon-append + input,
.crazy-form .textarea .icon-append + textarea {
	padding-right: 46px;
}
.crazy-form .input .icon-prepend + .icon-append + input,
.crazy-form .textarea .icon-prepend + .icon-append + textarea {
	padding-left: 46px;
}

/**/
/* grid */
/**/
.crazy-form .row {
	margin: 0 -15px;
}
.crazy-form .row:after {
	content: '';
	display: table;
	clear: both;
}
.crazy-form .col {
	float: left;
	min-height: 1px;
	padding-right: 15px;
	padding-left: 15px;
	box-sizing: border-box;
	-moz-box-sizing: border-box;
}
.crazy-form .col-1 {
	width: 8.33%;
}
.crazy-form .col-2 {
	width: 16.66%;
}
.crazy-form .col-3 {
	width: 25%;
}
.crazy-form .col-4 {
	width: 33.33%;
}
.crazy-form .col-5 {
	width: 41.66%;
}
.crazy-form .col-6 {
	width: 50%;
}
.crazy-form .col-7 {
	width: 58.33%;
}
.crazy-form .col-8 {
	width: 66.67%;
}
.crazy-form .col-9 {
	width: 75%;
}
.crazy-form .col-10 {
	width: 83.33%;
}
.crazy-form .col-11 {
	width: 91.66%;
}
@media screen and (max-width: 600px) {
	.crazy-form .col {
		float: none;
		width: 100%;
	}
}

/**/
/* tooltips */
/**/
.crazy-form .tooltip {
	position: absolute;
	z-index: 1;
	left: -9999px;
	padding: 2px 8px 3px;
	font-size: 11px;
	line-height: 16px;
	font-weight: 400;
	background: rgba(0,0,0,0.9);
	color: #fff;
	opacity: 0;
	-ms-transition: margin 0.3s, opacity 0.3s;
	-moz-transition: margin 0.3s, opacity 0.3s;
	-webkit-transition: margin 0.3s, opacity 0.3s;
}
.crazy-form .tooltip:after {
	content: '';
	position: absolute;
}
.crazy-form .input input:focus + .tooltip,
.crazy-form .textarea textarea:focus + .tooltip {
	opacity: 1;
}

.crazy-form .tooltip-top-right {
	bottom: 100%;
	margin-bottom: 15px;
}
.crazy-form .tooltip-top-right:after {
	top: 100%;
	right: 16px;
	border-top: 4px solid rgba(0,0,0,0.9);
	border-right: 4px solid transparent;
	border-left: 4px solid transparent;
}
.crazy-form .input input:focus + .tooltip-top-right,
.crazy-form .textarea textarea:focus + .tooltip-top-right {
	right: 0;
	left: auto;
	margin-bottom: 5px;
}

.crazy-form .tooltip-top-left {
	bottom: 100%;
	margin-bottom: 15px;
}
.crazy-form .tooltip-top-left:after {
	top: 100%;
	left: 16px;
	border-top: 4px solid rgba(0,0,0,0.9);
	border-right: 4px solid transparent;
	border-left: 4px solid transparent;
}
.crazy-form .input input:focus + .tooltip-top-left,
.crazy-form .textarea textarea:focus + .tooltip-top-left {
	right: auto;
	left: 0;
	margin-bottom: 5px;
}

.crazy-form .tooltip-right {
	top: 9px;
	white-space: nowrap;
	margin-left: 15px;
}
.crazy-form .tooltip-right:after {
	top: 6px;
	right: 100%;
	border-top: 4px solid transparent;
	border-right: 4px solid rgba(0,0,0,0.9);
	border-bottom: 4px solid transparent;
}
.crazy-form .input input:focus + .tooltip-right,
.crazy-form .textarea textarea:focus + .tooltip-right {
	left: 100%;
	margin-left: 5px;
}

.crazy-form .tooltip-left {
	top: 9px;
	white-space: nowrap;
	margin-right: 15px;
}
.crazy-form .tooltip-left:after {
	top: 6px;
	left: 100%;
	border-top: 4px solid transparent;
	border-bottom: 4px solid transparent;
	border-left: 4px solid rgba(0,0,0,0.9);
}
.crazy-form .input input:focus + .tooltip-left,
.crazy-form .textarea textarea:focus + .tooltip-left {
	right: 100%;
	left: auto;
	margin-right: 5px;
}

.crazy-form .tooltip-bottom-right {
	top: 100%;
	margin-top: 15px;
}
.crazy-form .tooltip-bottom-right:after {
	bottom: 100%;
	right: 16px;
	border-right: 4px solid transparent;
	border-bottom: 4px solid rgba(0,0,0,0.9);
	border-left: 4px solid transparent;
}
.crazy-form .input input:focus + .tooltip-bottom-right,
.crazy-form .textarea textarea:focus + .tooltip-bottom-right {
	right: 0;
	left: auto;
	margin-top: 5px;
}

.crazy-form .tooltip-bottom-left {
	top: 100%;
	margin-top: 15px;
}
.crazy-form .tooltip-bottom-left:after {
	bottom: 100%;
	left: 16px;
	border-right: 4px solid transparent;
	border-bottom: 4px solid rgba(0,0,0,0.9);
	border-left: 4px solid transparent;
}
.crazy-form .input input:focus + .tooltip-bottom-left,
.crazy-form .textarea textarea:focus + .tooltip-bottom-left {
	right: auto;
	left: 0;
	margin-top: 5px;
}

/**/
/* normal state */
/**/
.crazy-form .input input,
.crazy-form .select select,
.crazy-form .textarea textarea,
.crazy-form .radio i,
.crazy-form .checkbox i,
.crazy-form .toggle i,
.crazy-form .icon-append,
.crazy-form .icon-prepend {
	border-color: #e5e5e5;
	-ms-transition: border-color 0.3s;
	-moz-transition: border-color 0.3s;
	-webkit-transition: border-color 0.3s;
}
.crazy-form .toggle i:before {
	background-color: #2da5da;
}
.crazy-form .rating label {
	color: #ccc;
	-ms-transition: color 0.3s;
	-moz-transition: color 0.3s;
	-webkit-transition: color 0.3s;
}
.crazy-form .button {
	background-color: #0f006f;
	opacity: 0.8;
	-ms-transition: opacity 0.2s;
	-moz-transition: opacity 0.2s;
	-webkit-transition: opacity 0.2s;
	color: #FFFFFF;
}
.crazy-form .button.button-secondary {
	background-color: #b3b3b3;
}
.crazy-form .icon-append,
.crazy-form .icon-prepend {
	color: #ccc;
}

/**/
/* hover state */
/**/
.crazy-form .input:hover input,
.crazy-form .select:hover select,
.crazy-form .textarea:hover textarea,
.crazy-form .radio:hover i,
.crazy-form .checkbox:hover i,
.crazy-form .toggle:hover i,
.crazy-form .ui-slider-handle:hover {
	border-color: #8dc9e5;
}
.crazy-form .rating input + label:hover,
.crazy-form .rating input + label:hover ~ label {
	color: #2da5da;
}
.crazy-form .button:hover {
	opacity: 1;
}

/**/
/* focus state */
/**/
.crazy-form .input input:focus,
.crazy-form .select select:focus,
.crazy-form .textarea textarea:focus,
.crazy-form .radio input:focus + i,
.crazy-form .checkbox input:focus + i,
.crazy-form .toggle input:focus + i {
	border-color: #2da5da;
}

/**/
/* checked state */
/**/
.crazy-form .radio input + i:after {
	background-color: #2da5da;
}
.crazy-form .checkbox input + i:after {
	color: #2da5da;
}
.crazy-form .radio input:checked + i,
.crazy-form .checkbox input:checked + i,
.crazy-form .toggle input:checked + i {
	border-color: #2da5da;
}
.crazy-form .rating input:checked ~ label {
	color: #2da5da;
}

/**/
/* error state */
/**/
.crazy-form .state-error input,
.crazy-form .state-error select,
.crazy-form .state-error select + i,
.crazy-form .state-error textarea,
.crazy-form .radio.state-error i,
.crazy-form .checkbox.state-error i,
.crazy-form .toggle.state-error i,
.crazy-form .toggle.state-error input:checked + i {
	background: #fff0f0;
}
.crazy-form .state-error + em {
	display: block;
	margin-top: 6px;
	padding: 0 1px;
	font-style: normal;
	font-size: 11px;
	line-height: 15px;
	color: #ee9393;
}
.crazy-form .rating.state-error + em {
	margin-top: -4px;
	margin-bottom: 4px;
}

/**/
/* success state */
/**/
.crazy-form .state-success input,
.crazy-form .state-success select,
.crazy-form .state-success select + i,
.crazy-form .state-success textarea,
.crazy-form .radio.state-success i,
.crazy-form .checkbox.state-success i,
.crazy-form .toggle.state-success i,
.crazy-form .toggle.state-success input:checked + i {
	background: #f0fff0;
}
.crazy-form .state-success + em {
	display: block;
	margin-top: 6px;
	padding: 0 1px;
	font-style: normal;
	font-size: 11px;
	line-height: 15px;
	color: #ee9393;
}
.crazy-form .note-success {
	color: #6fb679;
}

/**/
/* disabled state */
/**/
.crazy-form .input.state-disabled input,
.crazy-form .select.state-disabled,
.crazy-form .textarea.state-disabled,
.crazy-form .radio.state-disabled,
.crazy-form .checkbox.state-disabled,
.crazy-form .toggle.state-disabled,
.crazy-form .button.state-disabled {
	cursor: default;
	opacity: 0.5;
}
.crazy-form .input.state-disabled:hover input,
.crazy-form .select.state-disabled:hover select,
.crazy-form .textarea.state-disabled:hover textarea,
.crazy-form .radio.state-disabled:hover i,
.crazy-form .checkbox.state-disabled:hover i,
.crazy-form .toggle.state-disabled:hover i {
	border-color: #e5e5e5;
}

/**/
/* submited state */
/**/
.crazy-form .message {
	display: none;
	color: #6fb679;
}
.crazy-form .message i {
	display: block;
	margin: 0 auto 20px;
	width: 81px;
	height: 81px;
	border: 1px solid #6fb679;
	border-radius: 50%;
	font-size: 30px;
	line-height: 81px;
}
.crazy-form.submited fieldset,
.crazy-form.submited footer {
	display: none;
}
.crazy-form.submited .message {
	display: block;
	padding: 25px 30px;
	background: rgba(255,255,255,.9);
	font: 300 18px/27px 'Open Sans', Helvetica, Arial, sans-serif;
	text-align: center;
}

/**/
/* datepicker */
/**/
.ui-datepicker {
	display: none;
	padding: 10px 12px;
	background: rgba(255,255,255,0.9);
	box-shadow: 0 0 10px rgba(0,0,0,.3);
	font: 13px/1.55 'Open Sans', Helvetica, Arial, sans-serif;
	text-align: center;
	color: #666;
}
.ui-datepicker a {
	color: #404040;
}
.ui-datepicker-header {
	position: relative;
	margin: -10px -12px 10px;
	padding: 10px;
	border-bottom: 1px solid rgba(0,0,0,.1);
	font-size: 15px;
	line-height: 27px;
}
.ui-datepicker-prev,
.ui-datepicker-next {
	position: absolute;
	top: 0;
	display: block;
	width: 47px;
	height: 47px;
	font-size: 15px;
	line-height: 47px;
	text-decoration: none;
	cursor: pointer;
}
.ui-datepicker-prev {
	left: 0;
}
.ui-datepicker-next {
	right: 0;
}
.ui-datepicker-calendar {
	border-collapse: collapse;
	font-size: 13px;
	line-height: 27px;
}
.ui-datepicker-calendar th {
	color: #999;
}
.ui-datepicker-calendar a,
.ui-datepicker-calendar span {
	display: block;
	width: 31px;
	margin: auto;
	text-decoration: none;
	color: #404040;
}
.ui-datepicker-calendar a:hover {
	background: rgba(0,0,0,.05);
}
.ui-datepicker-calendar span {
	color: #bfbfbf;
}
.ui-datepicker-today a {
	font-weight: 700;
}
.ui-datepicker-calendar .ui-state-active {
	background: rgba(0,0,0,.05);
	cursor: default;
}
.ui-datepicker-inline {
	border: 2px solid #e5e5e5;
	background: #fff;
	box-shadow: none;
}
.ui-datepicker-inline .ui-datepicker-header {
	line-height: 47px;
}
.ui-datepicker-inline .ui-datepicker-calendar {
	width: 100%;
}

/**/
/* slider */
/**/
.crazy-form .ui-slider {
	position: relative;
	height: 3px;
	border: 2px solid #e5e5e5;
	background: #fff;
	margin: 12px 6px 26px;
}
.crazy-form .ui-slider-handle {
	position: absolute;
	width: 15px;
	height: 15px;
	margin: -8px 0 0 -8px;
	border: 2px solid #e5e5e5;
	outline: none;
	background: #fff;
	-ms-transition: border-color 0.3s;
	-moz-transition: border-color 0.3s;
	-webkit-transition: border-color 0.3s;
}

/**/
/* modal */
/**/
.crazy-form-modal {
	position: fixed;
	z-index: 1;
	display: none;
	width: 400px;
}
.crazy-form-modal-overlay {
	position: fixed;
	top: 0;
	left: 0;
	display: none;
	width: 100%;
	height: 100%;
	background: rgba(0,0,0,0.7);
}

/**/
/* bootstrap compatibility */
/**/
.crazy-form *,
.crazy-form *:after,
.crazy-form *:before {
	margin: 0;
	padding: 0;
	box-sizing: content-box;
	-moz-box-sizing: content-box;
}
.crazy-form .label {
	border-radius: 0;
	font-size: 100%;
	text-align: left;
	white-space: normal;
	color: inherit;
}
.crazy-form .radio,
.crazy-form .checkbox {
	font-weight: 400;
}
.crazy-form .radio + .radio,
.crazy-form .checkbox + .checkbox {
  margin-top: 0;
}
.navbar-default .navbar-nav>li>a:hover, .navbar-default .navbar-nav>li>a:focus
	{
	color: #000; /*Sets the text hover color on navbar*/
}
.navbar-default .navbar-nav>.active>a, .navbar-default .navbar-nav>.active>a:hover,
	.navbar-default .navbar-nav>.active>a:focus {
	color: white; /*BACKGROUND color for active*/
	background-color: #030033;
}
.navbar-header>.navbar-brand {
	color: #FFFFFF;
	font-family : cursive;
	font-size: 2.5em;
}

.navbar-default {
	background-color: #0f006f;
	border-color: #030033;
}

.dropdown-menu>li>a:hover, .dropdown-menu>li>a:focus {
	color: #262626;
	text-decoration: none;
	background-color: #66CCFF; /*change color of links in drop down here*/
}

.nav>li>a:hover, .nav>li>a:focus {
	text-decoration: none;
	background-color: silver; /*Change rollover cell color here*/
}

.navbar-default .navbar-nav>li>a {
	color: white; /*Change active text color here*/
}
.row-no-padding
  [class*="col-"] {
    padding-left: 0;
    padding-right: 0;
  }


text:
#ifndef OVR_OSX_HIDDevice_h
#define OVR_OSX_HIDDevice_h

#include "OVR_HIDDevice.h"

#include "OVR_OSX_DeviceManager.h"

#include <IOKit/IOKitLib.h>

namespace OVR { namespace OSX {

class HIDDeviceManager;

//-------------------------------------------------------------------------------------
// ***** OSX HIDDevice

class HIDDevice : public OVR::HIDDevice, public DeviceManagerThread::Notifier
{
private:
    friend class HIDDeviceManager;

public:
    HIDDevice(HIDDeviceManager* manager);

    // This is a minimal constructor used during enumeration for us to pass
    // a HIDDevice to the visit function (so that it can query feature reports).
    HIDDevice(HIDDeviceManager* manager, IOHIDDeviceRef device);

    virtual ~HIDDevice();

    bool HIDInitialize(const String& path);
    void HIDShutdown();

    virtual bool SetFeatureReport(UByte* data, UInt32 length);
	virtual bool GetFeatureReport(UByte* data, UInt32 length);

    bool Write(UByte* data, UInt32 length);

    bool Read(UByte* pData, UInt32 length, UInt32 timeoutMilliS);
    bool ReadBlocking(UByte* pData, UInt32 length);

    // DeviceManagerThread::Notifier
    UInt64 OnTicks(UInt64 ticksMks);

private:
    bool initInfo();
    bool openDevice();
    void closeDevice(bool wasUnplugged);
    bool setupDevicePluggedInNotification();
    CFStringRef generateRunLoopModeString(IOHIDDeviceRef device);

    static void staticHIDReportCallback(void* pContext,
                                        IOReturn result,
                                        void* pSender,
                                        IOHIDReportType reportType,
                                        uint32_t reportId,
                                        uint8_t* pReport,
                                        CFIndex reportLength);
    void hidReportCallback(UByte* pData, UInt32 length);

    static void staticDeviceRemovedCallback(void* pContext,
                                            IOReturn result,
                                            void* pSender);
    void deviceRemovedCallback();

    static void staticDeviceAddedCallback(void* pContext,
                                          io_iterator_t iterator);
    void deviceAddedCallback(io_iterator_t iterator);

    bool                    InMinimalMode;
    HIDDeviceManager*       HIDManager;
    IOHIDDeviceRef          Device;
    HIDDeviceDesc           DevDesc;

    enum { ReadBufferSize = 96 };
    UByte                   ReadBuffer[ReadBufferSize];

    UInt16                  InputReportBufferLength;
    UInt16                  OutputReportBufferLength;
    UInt16                  FeatureReportBufferLength;

    IONotificationPortRef   RepluggedNotificationPort;
    io_iterator_t           RepluggedNotification;
};

//-------------------------------------------------------------------------------------
// ***** OSX HIDDeviceManager

class HIDDeviceManager : public OVR::HIDDeviceManager
{
	friend class HIDDevice;

public:
    HIDDeviceManager(OSX::DeviceManager* Manager);
    virtual ~HIDDeviceManager();

    virtual bool Initialize();
    virtual void Shutdown();

    virtual bool Enumerate(HIDEnumerateVisitor* enumVisitor);
    virtual OVR::HIDDevice* Open(const String& path);

    static HIDDeviceManager* CreateInternal(DeviceManager* manager);

private:
    CFRunLoopRef getRunLoop();
    bool initializeManager();
    bool initVendorProductVersion(IOHIDDeviceRef device, HIDDeviceDesc* pDevDesc);
    bool initUsage(IOHIDDeviceRef device, HIDDeviceDesc* pDevDesc);
    bool initStrings(IOHIDDeviceRef device, HIDDeviceDesc* pDevDesc);
    bool initSerialNumber(IOHIDDeviceRef device, HIDDeviceDesc* pDevDesc);
    bool getVendorId(IOHIDDeviceRef device, UInt16* pResult);
    bool getProductId(IOHIDDeviceRef device, UInt16* pResult);
    bool getLocationId(IOHIDDeviceRef device, SInt32* pResult);
    bool getSerialNumberString(IOHIDDeviceRef device, String* pResult);
    bool getPath(IOHIDDeviceRef device, String* pPath);
    bool getIntProperty(IOHIDDeviceRef device, CFStringRef key, int32_t* pResult);
    bool getStringProperty(IOHIDDeviceRef device, CFStringRef propertyName, String* pResult);
    bool getFullDesc(IOHIDDeviceRef device, HIDDeviceDesc* desc);

    static void staticDeviceMatchingCallback(void *inContext,
                                             IOReturn inResult,
                                             void *inSender,
                                             IOHIDDeviceRef inIOHIDDeviceRef);

    DeviceManager* DevManager;

    IOHIDManagerRef HIDManager;
};

}} // namespace OVR::OSX

#endif // OVR_OSX_HIDDevice_h


text:
ArangoDB Maintainers manual
===========================
This file contains documentation about the build process, documentation generation means, unittests - put short - if you want to hack parts of arangod this could be interesting for you.

Configure
=========
 * *--enable-relative* - relative mode so you can run without make install
 * *--enable-maintainer-mode* - generate lex/yacc files
 * *--with-backtrace* - add backtraces to native code asserts & exceptions
 * *--enable-failure-tests* - adds javascript hook to crash the server for data integrity tests

CFLAGS
------
Add backtraces to cluster requests so you can easily track their origin:

    -DDEBUG_CLUSTER_COMM

V8 Special flags:

    -DENABLE_GDB_JIT_INTERFACE

(enable (broken) GDB intergation of JIT)
At runtime arangod needs to be started with these options:

    --javascript.v8-options="--gdbjit_dump"
    --javascript.v8-options="--gdbjit_full"

Debugging the Make process
--------------------------
If the compile goes wrong for no particular reason, appending 'verbose=' adds more output. For some reason V8 has VERBOSE=1 for the same effect.

Runtime
-------
 * start arangod with `--console` to get a debug console
 * Cheapen startup for valgrind: `--no-server --javascript.gc-frequency 1000000 --javascript.gc-interval 65536 --scheduler.threads=1 --javascript.v8-contexts=1`
 * to have backtraces output set this on the prompt: `ENABLE_NATIVE_BACKTRACES(true)`

Startup
-------
We now have a startup rc file: `~/.arangod.rc`. It's evaled as javascript.
A sample version to help working with the arangod rescue console may look like that:

    ENABLE_NATIVE_BACKTRACES(true);
    internal = require("internal");
    fs = require("fs");
    db = internal.db;
    time = internal.time;
    timed = function (cb) {
      var s  = time();
      cb();
      return time() - s;
    };
    print = internal.print;

__________________________________________________________________________________________________________

JSLint
======
(we switched to jshint a while back - this is still named jslint for historical reasons)

Make target
-----------
use

    make gitjslint

to lint your modified files.

    make jslint

to find out whether all of your files comply to jslint. This is required to make continuous integration work smoothly.

if you want to add new files / patterns to this make target, edit js/Makefile.files

to be safe from committing non-linted stuff add **.git/hooks/pre-commit** with:

    make gitjslint

Use jslint standalone for your js file
--------------------------------------
If you want to search errors in your js file, jslint is very handy - like a compiler is for C/C++.
You can invoke it like this:

    bin/arangosh --jslint js/server/modules/org/arangodb/testing.js

__________________________________________________________________________________________________________

ArangoDB Unittesting Framework
==============================
Dependencies
------------
 * Ruby, rspec, httparty, boost_test (compile time)

Filename conventions
====================
Special patterns in the test filenames are used to select tests to be executed or skipped depending on parameters:

-cluster
--------
These tests will only run if clustering is tested. (option 'cluster' needs to be true).

-noncluster
-----------
These tests will only run if no cluster is used. (option 'cluster' needs to be false)

-timecritical
-------------
These tests are critical to execution time - and thus may fail if arangod is to slow. This may happen i.e. if you run the tests in valgrind, so you want to avoid them since they will fail anyways. To skip them, set the option *skipTimeCritical* to *true*.

-disabled
---------
These tests are disabled. You may however want to run them by hand.

replication
-----------
(only applies to ruby tests)
These tests aren't run automatically since they require a manual set up environment.

-spec
-----
These tests are ran using the jasmine framework instead of jsunity.

-nightly
--------
These tests produce a certain thread on infrastructure or the test system, and therefore should only be executed once per day.

Test frameworks used
====================
There are several major places where unittests live:
 - *UnitTests/HttpInterface*        - rspec tests
 - *UnitTests/Basics*               - boost unittests
 - *UnitTests/Geo*                  - boost unittests
 - *js/server/tests*                - runneable on the server
 - *js/common/tests*                - runneable on the server & via arangosh
 - *js/common/test-data*
 - *js/client/tests*                - runneable via arangosh
 - *js/apps/system/aardvark/test*

HttpInterface - RSpec Client Tests
---------------------------------
These tests work on the plain RESTfull interface of arangodb, and thus also test invalid HTTP-requests and so forth, plus check error handling in the server.

jsUnity on arangod
------------------
you can engage single tests when running arangod with console like this:

    require("jsunity").runTest("js/server/tests/aql-queries-simple.js");

jsUnity via arangosh
--------------------
arangosh is similar, however, you can only run tests which are intended to be ran via arangosh:

    require("jsunity").runTest("js/client/tests/shell-client.js");

jasmine tests
-------------

Jasmine tests cover two important usecase:
  - testing the UI components of aardvark
-spec

aardvark

Invocation methods
==================

Make-targets
------------
Most of the tests can be invoked via the main Makefile: (UnitTests/Makefile.unittests)
 - unittests
  - unittests-brief
  - unittests-verbose
 - unittests-recovery
 - unittests-config
 - unittests-boost
 - unittests-single
 - unittests-shell-server
 - unittests-shell-server-only
 - unittests-shell-server-aql
 - unittests-shell-client-readonly
 - unittests-shell-client
 - unittests-http-server
 - unittests-ssl-server
 - unittests-import
 - unittests-replication
  - unittests-replication-server
  - unittests-replication-http
  - unittests-replication-data
 - unittests-upgrade
 - unittests-dfdb
 - unittests-foxx-manager
 - unittests-dump
 - unittests-arangob
 - unittests-authentication
 - unittests-authentication-parameters

Javascript framework
--------------------
(used in our local Jenkins and TravisCI integration; required for running cluster tests)

Invoked like that:

    scripts/unittest all

calling it without parameters like this:

    scripts/unittest

will give you a extensive usage help which we won't duplicate here.

Choosing facility
_________________

The first parameter chooses the facility to execute.
Available choices include:
 - *all*:                (calls multiple) This target is utilized by most of the jenkins builds invoking unit tests.
 - *single_client*:      (see Running a single unittestsuite)
 - *single_server*:      (see Running a single unittestsuite)
 - *single_localserver*: (see Running a single unittestsuite)
 - many more -           call without arguments for more details.

Passing Options
---------------

Different facilities may take different options. The above mentioned usage output contains
the full detail.

A commandline for running a single test (-> with the facility 'single_server') using
valgrind could look like this. Options are passed as regular long values in the
syntax --option value --sub:option value. Using Valgrind could look like this:

    ./scripts/unittest single_server --test js/server/tests/aql-escaping.js \
      --extraargs:server.threads 1 \
      --extraargs:scheduler.threads 1 \
      --extraargs:javascript.gc-frequency 1000000 \
      --extraargs:javascript.gc-interval 65536 \
      --valgrind /usr/bin/valgrind \
      --valgrindargs:log-file /tmp/valgrindlog.%p

 - we specify the test to execute
 - we specify some arangod arguments via --extraargs which increase the server performance
 - we specify to run using valgrind (this is supported by all facilities
 - we specify some valgrind commandline arguments

Running a single unittestsuite
------------------------------
Testing a single test with the framework directly on a server:

    scripts/unittest single_server --test js/server/tests/aql-escaping.js

Testing a single test with the framework via arangosh:

    scripts/unittest single_client --test js/server/tests/aql-escaping.js

Testing a single rspec test:

    scripts/unittest http_server --test api-users-spec.rb

**scripts/unittest** is mostly only a wrapper; The backend functionality lives in:
**js/server/modules/org/arangodb/testing.js**

Running foxx tests with a fake foxx Repo
----------------------------------------
Since downloading fox apps from github can be cumbersome with shaky DSL
and DOS'ed github, we can fake it like this:

    export FOXX_BASE_URL="http://germany/fakegit/"
    ./scripts/unittest single_server --test 'js/server/tests/shell-foxx-manager-spec.js'

arangod Emergency console
-------------------------

    require("jsunity").runTest("js/server/tests/aql-escaping.js");

arangosh client
---------------

    require("jsunity").runTest("js/server/tests/aql-escaping.js");

arangod commandline arguments
-----------------------------

    bin/arangod /tmp/dataUT --javascript.unit-tests="js/server/tests/aql-escaping.js" --no-server

    make unittest

    js/common/modules/loadtestrunner.js

__________________________________________________________________________________________________________

Windows debugging
=================
For the average \*nix user windows debugging has some awkward methods.

Coredump generation
-------------------
Coredumps can be created using the task manager; switch it to detail view, the context menu offers to *create dump file*; the generated file ends in a directory that explorer hides from you - AppData - you have to type that in the location bar.
This however only for running processes which is not as useful as having dumps of crashing processes. While its a common feature to turn on coredumps with the system facilities on \*nix systems, its not as easy in windows.
You need an external program [from the Sysinternals package: ProcDump](https://technet.microsoft.com/en-us/sysinternals/dd996900.aspx). First look up the PID of arangod, you can finde it in the brackets in the arangodb logfile. Then invoke *procdump* like this:

    procdump -accepteula -e -ma < PID of arangod >

It will keep on running and monitor arangod until eventually a crash happens. You will then get a core dump if an incident occurs or *Dump count not reached.* if nothing happened, *Dump count reached.* if a dump was written - the filename will be printed above.

Debugging symbols
-----------------
Releases are supported by a public symbol server so you will be able to debug cores.
Releases starting with **2.5.6, 2.6.3** onwards are supported; Note that you should run the latest version of a release series before reporting bugs.
Either [WinDbg](http://go.microsoft.com/fwlink/p/?linkid=84137) or Visual studio support setting the symbol path
via the environment variable or in the menu. Given we want to store the symbols on *e:\symbol_cach* we add the arangodb symbolserver like this:

    set _NT_SYMBOL_PATH=cache*e:\symbol_cache\cache;srv*e:\symbol_cache\arango*https://www.arangodb.com/repositories/symsrv/;SRV*e:\symbol_cache\ms*http://msdl.microsoft.com/download/symbols

You then will be able to see stack traces in the debugger.

__________________________________________________________________________________________________________

Documentation
=============
Dependencies to build documentation:

- [swagger 2](http://swagger.io/) for the API-Documentation inside aardvark (no installation required)

- Python Setuptools

    https://pypi.python.org/pypi/setuptools

    Download setuptools zip file, extract to any folder, use bundled python 2.6 to install:

        python ez_install.py

  This will place the required files in python's Lib/site-packages folder.

- MarkdownPP

    https://github.com/triAGENS/markdown-pp/

    Checkout the code with Git, use bundled python 2.6 to install:

        python setup.py install

- [Node.js](https://nodejs.org/)

    Make sure the option to *Add to PATH* is enabled.
    After installation, the following commands should be available everywhere:

    - `node`
    - `npm`

    If not, add the installation path to your environment variable PATH.

- [Gitbook](https://github.com/GitbookIO/gitbook)

    Can be installed with Node's package manager NPM:

        npm install gitbook-cli -g

- Calibre2 (optional, only required if you want to build the e-book version)

  http://calibre-ebook.com/download

  Run the installer and follow the instructions.

Generate users documentation
============================
If you've edited REST-Documentation, first invoke `make swagger`.
If you've edited examples, see below howto regenerate them.
Run the `make` command in `arangodb/Documentation/Books` to generate it.
The documentation will be generated into `arangodb/Documentation/Books/books/Users` -
use your favourite browser to read it.

You may encounter permission problem with gitbook and its NPM invokations;
In that case you need to run the command as root / Administrator.

On windows you may see "device busy" errors, retry. Make shure you don't have
intermediate files in the ppbooks / books -sub folder open (i.e. browser or editor)
It can also temporarily occur during phases of high HDD / SSD load.

The build-scripts contain several sanity checks, i.e. whether all examples are
used, and no dead references are there. (see building examples in that case below)

If the markdown files aren't converted to html, or `index.html` shows a single
chapter only (content of `README.md`), make sure
[Cygwin create native symlinks](https://docs.arangodb.com/cookbook/CompilingUnderWindows.html)
It does not, if `SUMMARY.md` in `Books/ppbooks/` looks like this:

    !<symlink>ÿþf o o

If sub-chapters do not show in the navigation, try another browser (Firefox).
Chrome's security policies are pretty strict about localhost and file://
protocol. You may access the docs through a local web server to lift the
restrictions.

Using Gitbook
=============

The `make` command in `arangodb/Documentation/Books/` generates a website
version of the manual. If you want to generate PDF, ePUB etc., run below
build commands in `arangodb/Documentation/Books/books/Users/`. Calibre's
`ebook-convert` will be used for the conversion.

Generate a PDF:

    gitbook pdf ./ppbooks/Users ./target/path/filename.pdf

Generate an ePub:

    gitbook epub ./ppbooks/Users ./target/path/filename.epub

Where to add new...
-------------------
 - js/action/api/* - markdown comments in source with execution section
 - Documentation/Books/Users/SUMMARY.md - index of all sub documentations
 - Documentation/Scripts/generateSwaggerApi.py - list of all sections to be adjusted if

generate
--------
 - `make examples` - on top level to generate Documentation/Examples
 - `make examples FILTER_EXAMPLE=geoIndexSelect` will only produce one example - *geoIndexSelect*
 - `make examples FILTER_EXAMPLE='MOD.*'` will only produce the examples matching that regex; Note that
   examples with enumerations in their name may base on others in their series - so you should generate the whole group.
 - `make examples server.endpoint=tcp://127.0.0.1:8529` will utilize an existing arangod instead of starting a new one.
   this does seriously cut down the execution time.
 - alternatively you can use generateExamples (i.e. on windows since the make target is not portable) like that:
    `./scripts/generateExamples
       --server.endpoint 'tcp://127.0.0.1:8529'
       --withPython 3rdParty/V8-4.3.61/third_party/python_26/python26.exe
       --onlyThisOne 'MOD.*'`
 - `make examples-inspect-file` generates a file where you can inspect all examples for readability.
 - `make swagger` - on top level to generate the documentation interactively with the server; you may use
    [the swagger editor](https://github.com/swagger-api/swagger-editor) to revalidate whether
    *js/apps/system/_admin/aardvark/APP/api-docs.json* is accurate.
 - `cd Documentation/Books; make` - to generate the HTML documentation

write markdown
--------------
*mdpp* files are used for the structure. To join it with parts extracted from the program documentation
you need to place hooks:
  - `@startDocuBlock <tdocuBlockName>` is replaced by a Docublock extracted from source.
  - `@startDocuBlockInline <docuBlockName>` till `@endDocuBlock <docuBlockName>`
     is replaced in with its own evaluated content - so  *@EXAMPLE_ARANGOSH_[OUTPUT | RUN]* sections are executed
     the same way as inside of source code documentation.

Read / use the documentation
----------------------------
 - `file:///Documentation/Books/books/Users/index.html` contains the generated documentation
 - JS-Console - Tools/API - Interactive swagger documentation which you can play with.

arangod Example tool
====================
`make example` picks examples from the source code documentation, executes them, and creates a transcript including their results.
*Hint: Windows users may use ./scripts/generateExamples for this purpose*

Here is how its details work:
  - all ending with *.cpp*, *.js* and *.mdpp* are searched.
  - all lines inside of source code starting with '///' are matched, all lines in .mdpp files.
  - an example start is marked with *@EXAMPLE_ARANGOSH_OUTPUT* or *@EXAMPLE_ARANGOSH_RUN*
  - the example is named by the string provided in brackets after the above key
  - the output is written to `Documentation/Examples/<name>.generated`
  - examples end with *@END_EXAMPLE_[OUTPUT|RUN]*
  - all code in between is executed as javascript in the **arangosh** while talking to a valid **arangod**. You may inspect the
    generated js code in `/tmp/arangosh.examples.js`

OUTPUT and RUN specifics
---------------------------
By default, Examples should be self contained and thus not depend on each other. They should clean up the collections they create.
Building will fail if resources aren't cleaned.
However, if you intend a set of OUTPUT and RUN to demonstrate interactively and share generated *ids*, you have to use an alphabetical
sortable naming scheme so they're executed in sequence. Using `<modulename>_<sequencenumber>[a|b|c|d]_thisDoesThat` seems to be a good scheme.

  - OUTPUT is intended to create samples that the users can cut'n'paste into their arangosh. Its used for javascript api documentation.
    * wrapped lines:
      Lines starting with a pipe (`/// |`) are joined together with the next following line.
      You have to use this if you want to execute loops, functions or commands which shouldn't be torn apart by the framework.
    * Lines starting with *var*:
      The command behaves similar to the arangosh: the server reply won't be printed.
      However, the variable will be in the scope of the other lines - else it won't.
    * Lines starting with a Tilde (`/// ~`):
      These lines can be used for setup/teardown purposes. They are completely invisible in the generated example transcript.
    * `~removeIgnoreCollection("test")` - the collection test may live across several tests.
    * `~addIgnoreCollection("test")` - the collection test will again be alarmed if left over.

  - it is executed line by line. If a line is intended to fail (aka throw an exception),
    you have to specify `// xpError(ERROR_ARANGO_DOCUMENT_KEY_UNEXPECTED)` so the exception will be caught;
    else the example is marked as broken.
    If you need to wrap that line, you may want to make the next line starting by a tilde to suppress an empty line:

        /// | someLongStatement()
        /// ~ // xpError(ERROR_ARANGO_DOCUMENT_KEY_UNEXPECTED)

 - RUN is intended to be pasted into a unix shell with *cURL* to demonstrate how the REST-HTTP-APIs work.
   The whole chunk of code is executed at once, and is expected **not to throw**.
   You should use **assert(condition)** to ensure the result is what you've expected.
   The *body* can be a string, or a javascript object which is then represented in JSON format.

    * Send the HTTP-request: `var response = logCurlRequest('POST', url, body);`
    * check its response:    `assert(response.code === 200);`
    * output a JSON server Reply: `logJsonResponse(response);` (will fail if its not a valid json)
    * output HTML to the user: `logHtmlResponse(response);` (i.e. redirects have HTML documents)
    * output the plain text to dump to the user: `logRawResponse(response);`
    * dump the reply to the errorlog for testing (will mark run as failed): `logErrorResponse(response);`

Swagger integration
===================
`make swagger` scans the sourcecode, and generates swagger output.
It scans for all documentationblocks containing `@RESTHEADER`.
It is a prerequisite for integrating these blocks into the gitbook documentation.

Tokens may have curly brackets with comma separated fields. They may optionally be followed by subsequent text
lines with a long descriptions.

Sections group a set of tokens; they don't have parameters.

**Types**
Swagger has several native types referenced below:
*[integer|long|float|double|string|byte|binary|boolean|date|dateTime|password]* -
[see the swagger documentation](https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#data-types)

It consists of several sections which in term have sub-parameters:

**Supported Sections:**

RESTQUERYPARAMETERS
-------------------
Parameters to be appended to the URL in form of ?foo=bar
add *RESTQUERYPARAM*s below

RESTURLPARAMETERS
-----------------
Section of parameters placed in the URL in curly brackets, add *RESTURLPARAM*s below.

RESTDESCRIPTION
---------------
Long text describing this route.

RESTRETURNCODES
---------------
should consist of several *RESTRETURNCODE* tokens.

**Supported Tokens:**

RESTHEADER
----------
Up to 2 parameters.
* *[GET|POST|PUT|DELETE] <url>* url should start with a */*, it may contain parameters in curly brackets, that
  have to be documented in subsequent *RESTURLPARAM* tokens in the *RESTURLPARAMETERS* section.

RESTURLPARAM
------------
Consists of 3 values separated by ',':
Attributes:
  - *name*: name of the parameter
  - *type*:
  - *[required|optionas]* Optional is not supported anymore. Split the docublock into one with and one without.

Folowed by a long description.

RESTALLBODYPARAM
----------------
This API has a schemaless json body (in doubt just plain ascii)

RESTBODYPARAM
-------------
Attributes:
  - name - the name of the parameter
  - type - the swaggertype of the parameter
  - required/optional - whether the user can ommit this parameter
  - subtype / format (can be empty)
    - subtype: if type is object or array, this references the enclosed variables.
               can be either a swaggertype, or a *RESTRUCT*
    - format: if type is a native swagger type, some support a format to specify them

RESTSTRUCT
----------
Groups a set of attributes under the `structure name` to an object that can be referenced
in other *RESTSTRUCT*s or *RESTBODYPARAM* attributes of type array or object

Attributes:
  - name - the name of the parameter
  - structure name - the **type** under which this structure can be reached (should be uniq!)
  - type - the swaggertype of the parameter (or another *RESTSTRUCT*...)
  - required/optional - whether the user can ommit this parameter
  - subtype / format (can be empty)
    - subtype: if type is object or array, this references the enclosed variables.
               can be either a swaggertype, or a *RESTRUCT*
    - format: if type is a native swagger type, some support a format to specify them


text:
#include "core/html/ClassList.h"

#include "core/dom/Document.h"
#include "wtf/PtrUtil.h"

namespace blink {

using namespace HTMLNames;

ClassList::ClassList(Element* element) : DOMTokenList(nullptr), m_element(element) { }

unsigned ClassList::length() const
{
    return m_element->hasClass() ? classNames().size() : 0;
}

const AtomicString ClassList::item(unsigned index) const
{
    if (index >= length())
        return AtomicString();
    return classNames()[index];
}

bool ClassList::containsInternal(const AtomicString& token) const
{
    return m_element->hasClass() && classNames().contains(token);
}

const SpaceSplitString& ClassList::classNames() const
{
    ASSERT(m_element->hasClass());
    if (m_element->document().inQuirksMode()) {
        if (!m_classNamesForQuirksMode)
            m_classNamesForQuirksMode = wrapUnique(new SpaceSplitString(value(), SpaceSplitString::ShouldNotFoldCase));
        return *m_classNamesForQuirksMode.get();
    }
    return m_element->classNames();
}

DEFINE_TRACE(ClassList)
{
    visitor->trace(m_element);
    DOMTokenList::trace(visitor);
}

} // namespace blink


text:
package flickr

import (
	"bytes"
	"crypto/hmac"
	"crypto/md5"
	"crypto/sha1"
	"encoding/base64"
	"fmt"
	"math/rand"
	"net/http"
	"net/url"
	"sort"
	"strings"
	"time"
)

// Generate a random string of 8 chars, needed for OAuth signature
func generateNonce() string {
	rand.Seed(time.Now().UTC().UnixNano())
	// For convenience, use a set of chars we don't need to url-escape
	var letters = []rune("123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ")
	b := make([]rune, 8)
	for i := range b {
		b[i] = letters[rand.Intn(len(letters))]
	}
	return string(b)
}

// An utility type to wrap all resources and data needed to complete requests
// to the Flickr API
type FlickrClient struct {
	// Flickr application api key
	ApiKey string
	// Flickr application api secret
	ApiSecret string
	// A generic HTTP client to perform GET and POST requests
	HTTPClient *http.Client
	// The base url for API endpoints
	EndpointUrl string
	// A string containing POST or GET, needed for OAuth signing
	HTTPVerb string
	// A set of url params to query the API
	Args url.Values
	// User access token
	OAuthToken string
	// User secret token
	OAuthTokenSecret string
	// User flickr ID
	Id string
}

// Create a Flickr client, apiKey and apiSecret are mandatory
func NewFlickrClient(apiKey string, apiSecret string) *FlickrClient {
	return &FlickrClient{
		ApiKey:     apiKey,
		ApiSecret:  apiSecret,
		HTTPClient: &http.Client{},
		HTTPVerb:   "GET",
		Args:       url.Values{},
	}
}

// Sign the next request performed by the FlickrClient
func (c *FlickrClient) Sign(tokenSecret string) {
	// the "oauth_signature" param must not be included in the signing process
	c.Args.Del("oauth_signature")
	c.Args.Set("oauth_signature", c.getSignature(tokenSecret))
}

// Set the mandatory params for an OAuth request
func (c *FlickrClient) SetOAuthDefaults() {
	c.Args.Add("oauth_version", "1.0")
	c.Args.Add("oauth_signature_method", "HMAC-SHA1")
	c.Args.Add("oauth_nonce", generateNonce())
	c.Args.Add("oauth_timestamp", fmt.Sprintf("%d", time.Now().Unix()))
}

// Sign the request with a default set of OAuth parameters, needed to authorize
// users for certain writing/destructive operations.
func (c *FlickrClient) OAuthSign() {
	c.SetOAuthDefaults()
	c.Args.Set("oauth_token", c.OAuthToken)
	c.Args.Set("oauth_consumer_key", c.ApiKey)
	c.Args.Set("api_key", c.ApiKey)

	c.Sign(c.OAuthTokenSecret)
}

// Specific signing process for API calls: not the same as OAuth sign, used
// for requests that don't need user authorizations.
func (c *FlickrClient) ApiSign() {
	c.Args.Set("api_key", c.ApiKey)
	// the "api_sig" param must not be included in the signing process
	c.Args.Del("api_sig")
	c.Args.Set("api_sig", c.getApiSignature(c.ApiSecret))
}

// Evaluate the complete URL to make requests (base url + params)
func (c *FlickrClient) GetUrl() string {
	return fmt.Sprintf("%s?%s", c.EndpointUrl, c.Args.Encode())
}

// Remove all query params
func (c *FlickrClient) ClearArgs() {
	c.Args = url.Values{}
}

// Reset Args and set the default endpoint
func (c *FlickrClient) Init() {
	c.ClearArgs()
	c.EndpointUrl = API_ENDPOINT
}

// Get the base string to compose the signature
func (c *FlickrClient) getSigningBaseString() string {
	request_url := url.QueryEscape(c.EndpointUrl)
	flickr_encoded := strings.Replace(c.Args.Encode(), "+", "%20", -1)
	query := url.QueryEscape(flickr_encoded)

	ret := fmt.Sprintf("%s&%s&%s", c.HTTPVerb, request_url, query)
	return ret
}

// Compute the signature of a signed request
func (c *FlickrClient) getSignature(token_secret string) string {
	key := fmt.Sprintf("%s&%s", url.QueryEscape(c.ApiSecret), url.QueryEscape(token_secret))
	base_string := c.getSigningBaseString()

	mac := hmac.New(sha1.New, []byte(key))
	mac.Write([]byte(base_string))

	ret := base64.StdEncoding.EncodeToString(mac.Sum(nil))

	return ret
}

// Sign API requests. This method differs from the signing process needed for
// OAuth authenticated requests.
func (c *FlickrClient) getApiSignature(token_secret string) string {
	var buf bytes.Buffer
	buf.WriteString(token_secret)

	keys := make([]string, 0, len(c.Args))
	for k := range c.Args {
		keys = append(keys, k)
	}
	// args needs to be in alphabetical order
	sort.Strings(keys)

	for _, k := range keys {
		arg := c.Args[k][0]
		buf.WriteString(k)
		buf.WriteString(arg)
	}

	base := buf.String()

	data := []byte(base)
	return fmt.Sprintf("%x", md5.Sum(data))
}


text:
from PySide import QtCore, QtGui

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(776, 589)
        self.centralWidget = QtGui.QWidget(MainWindow)
        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.centralWidget.sizePolicy().hasHeightForWidth())
        self.centralWidget.setSizePolicy(sizePolicy)
        self.centralWidget.setObjectName("centralWidget")
        self.gridLayout = QtGui.QGridLayout(self.centralWidget)
        self.gridLayout.setObjectName("gridLayout")
        self.graphicsView = QtGui.QGraphicsView(self.centralWidget)
        self.graphicsView.setDragMode(QtGui.QGraphicsView.ScrollHandDrag)
        self.graphicsView.setResizeAnchor(QtGui.QGraphicsView.AnchorUnderMouse)
        self.graphicsView.setObjectName("graphicsView")
        self.gridLayout.addWidget(self.graphicsView, 0, 0, 1, 1)
        self.tabWidget = QtGui.QTabWidget(self.centralWidget)
        self.tabWidget.setObjectName("tabWidget")
        self.tab = QtGui.QWidget()
        self.tab.setObjectName("tab")
        self.gridLayout_2 = QtGui.QGridLayout(self.tab)
        self.gridLayout_2.setObjectName("gridLayout_2")
        self.scrollArea = QtGui.QScrollArea(self.tab)
        self.scrollArea.setWidgetResizable(True)
        self.scrollArea.setObjectName("scrollArea")
        self.scrollAreaWidgetContents = QtGui.QWidget()
        self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 734, 173))
        self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents")
        self.gridLayout_3 = QtGui.QGridLayout(self.scrollAreaWidgetContents)
        self.gridLayout_3.setObjectName("gridLayout_3")
        self.formLayout_2 = QtGui.QFormLayout()
        self.formLayout_2.setLabelAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
        self.formLayout_2.setObjectName("formLayout_2")
        self.selectModelButton = QtGui.QToolButton(self.scrollAreaWidgetContents)
        self.selectModelButton.setObjectName("selectModelButton")
        self.formLayout_2.setWidget(0, QtGui.QFormLayout.LabelRole, self.selectModelButton)
        self.modelPathLabel = QtGui.QLabel(self.scrollAreaWidgetContents)
        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.modelPathLabel.sizePolicy().hasHeightForWidth())
        self.modelPathLabel.setSizePolicy(sizePolicy)
        self.modelPathLabel.setStyleSheet("background-color: rgb(175, 175, 175);")
        self.modelPathLabel.setScaledContents(False)
        self.modelPathLabel.setWordWrap(False)
        self.modelPathLabel.setTextInteractionFlags(QtCore.Qt.TextBrowserInteraction)
        self.modelPathLabel.setObjectName("modelPathLabel")
        self.formLayout_2.setWidget(0, QtGui.QFormLayout.FieldRole, self.modelPathLabel)
        self.selectWeightsButton = QtGui.QToolButton(self.scrollAreaWidgetContents)
        self.selectWeightsButton.setObjectName("selectWeightsButton")
        self.formLayout_2.setWidget(1, QtGui.QFormLayout.LabelRole, self.selectWeightsButton)
        self.weightsPathLabel = QtGui.QLabel(self.scrollAreaWidgetContents)
        self.weightsPathLabel.setStyleSheet("background-color: rgb(175, 175, 175);")
        self.weightsPathLabel.setObjectName("weightsPathLabel")
        self.formLayout_2.setWidget(1, QtGui.QFormLayout.FieldRole, self.weightsPathLabel)
        self.selectMeanButton = QtGui.QToolButton(self.scrollAreaWidgetContents)
        self.selectMeanButton.setObjectName("selectMeanButton")
        self.formLayout_2.setWidget(2, QtGui.QFormLayout.LabelRole, self.selectMeanButton)
        self.meanPathLabel = QtGui.QLabel(self.scrollAreaWidgetContents)
        self.meanPathLabel.setStyleSheet("background-color: rgb(175, 175, 175);")
        self.meanPathLabel.setObjectName("meanPathLabel")
        self.formLayout_2.setWidget(2, QtGui.QFormLayout.FieldRole, self.meanPathLabel)
        self.gridLayout_3.addLayout(self.formLayout_2, 0, 0, 1, 1)
        self.formLayout_3 = QtGui.QFormLayout()
        self.formLayout_3.setObjectName("formLayout_3")
        self.loadModelButton = QtGui.QPushButton(self.scrollAreaWidgetContents)
        self.loadModelButton.setStyleSheet("background-color: rgb(255, 64, 64);")
        self.loadModelButton.setObjectName("loadModelButton")
        self.formLayout_3.setWidget(0, QtGui.QFormLayout.LabelRole, self.loadModelButton)
        self.loadInfoLabel = QtGui.QLabel(self.scrollAreaWidgetContents)
        self.loadInfoLabel.setStyleSheet("background-color: rgb(175, 175, 175);")
        self.loadInfoLabel.setObjectName("loadInfoLabel")
        self.formLayout_3.setWidget(0, QtGui.QFormLayout.FieldRole, self.loadInfoLabel)
        self.gridLayout_3.addLayout(self.formLayout_3, 1, 0, 1, 1)
        self.scrollArea.setWidget(self.scrollAreaWidgetContents)
        self.gridLayout_2.addWidget(self.scrollArea, 0, 0, 1, 1)
        self.tabWidget.addTab(self.tab, "")
        self.tab_2 = QtGui.QWidget()
        self.tab_2.setObjectName("tab_2")
        self.formLayoutWidget = QtGui.QWidget(self.tab_2)
        self.formLayoutWidget.setGeometry(QtCore.QRect(10, 10, 165, 91))
        self.formLayoutWidget.setObjectName("formLayoutWidget")
        self.formLayout = QtGui.QFormLayout(self.formLayoutWidget)
        self.formLayout.setContentsMargins(0, 0, 0, 0)
        self.formLayout.setObjectName("formLayout")
        self.label_5 = QtGui.QLabel(self.formLayoutWidget)
        self.label_5.setObjectName("label_5")
        self.formLayout.setWidget(1, QtGui.QFormLayout.LabelRole, self.label_5)
        self.layersComboBox = QtGui.QComboBox(self.formLayoutWidget)
        self.layersComboBox.setObjectName("layersComboBox")
        self.formLayout.setWidget(1, QtGui.QFormLayout.FieldRole, self.layersComboBox)
        self.label = QtGui.QLabel(self.formLayoutWidget)
        self.label.setObjectName("label")
        self.formLayout.setWidget(2, QtGui.QFormLayout.LabelRole, self.label)
        self.showNFilters = QtGui.QSpinBox(self.formLayoutWidget)
        self.showNFilters.setObjectName("showNFilters")
        self.formLayout.setWidget(2, QtGui.QFormLayout.FieldRole, self.showNFilters)
        self.tabWidget.addTab(self.tab_2, "")
        self.tab_3 = QtGui.QWidget()
        self.tab_3.setObjectName("tab_3")
        self.tabWidget.addTab(self.tab_3, "")
        self.gridLayout.addWidget(self.tabWidget, 1, 0, 1, 1)
        self.gridLayout.setRowStretch(0, 6)
        self.gridLayout.setRowStretch(1, 4)
        MainWindow.setCentralWidget(self.centralWidget)

        self.retranslateUi(MainWindow)
        self.tabWidget.setCurrentIndex(0)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "Feature Candy", None, QtGui.QApplication.UnicodeUTF8))
        self.selectModelButton.setText(QtGui.QApplication.translate("MainWindow", "...", None, QtGui.QApplication.UnicodeUTF8))
        self.modelPathLabel.setText(QtGui.QApplication.translate("MainWindow", "Model definition path...", None, QtGui.QApplication.UnicodeUTF8))
        self.selectWeightsButton.setText(QtGui.QApplication.translate("MainWindow", "...", None, QtGui.QApplication.UnicodeUTF8))
        self.weightsPathLabel.setText(QtGui.QApplication.translate("MainWindow", "Weights path...", None, QtGui.QApplication.UnicodeUTF8))
        self.selectMeanButton.setText(QtGui.QApplication.translate("MainWindow", "...", None, QtGui.QApplication.UnicodeUTF8))
        self.meanPathLabel.setText(QtGui.QApplication.translate("MainWindow", "Mean path...", None, QtGui.QApplication.UnicodeUTF8))
        self.loadModelButton.setText(QtGui.QApplication.translate("MainWindow", "Load", None, QtGui.QApplication.UnicodeUTF8))
        self.loadInfoLabel.setText(QtGui.QApplication.translate("MainWindow", "No model loaded yet", None, QtGui.QApplication.UnicodeUTF8))
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), QtGui.QApplication.translate("MainWindow", "Choose Model", None, QtGui.QApplication.UnicodeUTF8))
        self.label_5.setText(QtGui.QApplication.translate("MainWindow", "Choose Layer", None, QtGui.QApplication.UnicodeUTF8))
        self.label.setText(QtGui.QApplication.translate("MainWindow", "#filters", None, QtGui.QApplication.UnicodeUTF8))
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), QtGui.QApplication.translate("MainWindow", "Explore filters", None, QtGui.QApplication.UnicodeUTF8))
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_3), QtGui.QApplication.translate("MainWindow", "Page", None, QtGui.QApplication.UnicodeUTF8))


text:
package com.smassive.comicviewr.data.bean.vo.comic.mapper;

import com.smassive.comicviewr.data.bean.vo.comic.ComicVo;
import com.smassive.comicviewr.data.bean.vo.mapper.ImageVoMapper;
import com.smassive.comicviewr.domain.bean.ComicBo;

import java.util.ArrayList;
import java.util.List;

import io.realm.RealmResults;

public final class ComicVoMapper {

    private ComicVoMapper() {
    }

    public static ComicBo toBo(ComicVo vo) {
        ComicBo bo = null;

        if (vo != null) {
            bo = new ComicBo();

            bo.setId(vo.getId());
            bo.setTitle(vo.getTitle());
            bo.setPageCount(vo.getPageCount());
            bo.setDescription(vo.getDescription());
            bo.setThumbnailUrl(ImageVoMapper.toString(vo.getThumbnail()));
            bo.setImageUrls(ImageVoMapper.toString(vo.getImages()));
        }

        return bo;
    }

    public static List<ComicBo> toBo(RealmResults<ComicVo> vos) {
        List<ComicBo> bos = null;

        if (vos != null && !vos.isEmpty()) {
            bos = new ArrayList<>();

            for (ComicVo vo : vos) {
                bos.add(toBo(vo));
            }
        }

        return bos;
    }
}