text:
module ExproniconLite
#= /home/roger/code/julia/Expronicon/src/expand.jl:114 =# @static if !(isdefined(#= /home/roger/code/julia/Expronicon/src/expand.jl:114 =# @__MODULE__(), :include_generated))
        function _include_generated(_path::String)
            #= /home/roger/code/julia/Expronicon/src/expand.jl:116 =# Base.@_noinline_meta
            mod = #= /home/roger/code/julia/Expronicon/src/expand.jl:117 =# @__MODULE__()
            (path, prev) = Base._include_dependency(mod, _path)
            code = read(path, String)
            tls = task_local_storage()
            tls[:SOURCE_PATH] = path
            try
                ex = include_string(mod, "quote $(code) end", path)
                mod.eval(mod.eval(ex))
                return
            finally
                if prev === nothing
                    delete!(tls, :SOURCE_PATH)
                else
                    tls[:SOURCE_PATH] = prev
                end
            end
        end
    end
#= /home/roger/code/julia/Expronicon/src/expand.jl:141 =# @static if VERSION < v"1.3"
        macro var_str(x)
            Symbol(x)
        end
    end
export NoDefault, JLExpr, JLFor, JLIfElse, JLFunction, JLField, JLKwField, JLStruct, JLKwStruct, @expr, @test_expr, compare_expr, compare_vars, AnalysisError, is_function, is_kw_function, is_struct, is_ifelse, is_for, is_field, is_field_default, is_datatype_expr, split_function, split_function_head, split_struct, split_struct_name, split_ifelse, uninferrable_typevars, has_symbol, is_literal, is_gensym, alias_gensym, has_kwfn_constructor, has_plain_constructor, no_default, prettify, rm_lineinfo, flatten_blocks, name_only, rm_annotations, rm_single_block, rm_nothing, replace_symbol, subtitute, eval_interp, eval_literal, codegen_ast, codegen_ast_kwfn, codegen_ast_kwfn_plain, codegen_ast_kwfn_infer, codegen_ast_struct, codegen_ast_struct_head, codegen_ast_struct_body, struct_name_plain, struct_name_without_inferable, xtuple, xnamedtuple, xcall, xpush, xgetindex, xfirst, xlast, xprint, xprintln, xmap, xmapreduce, xiterate, print_expr, sprint_expr
include("types.jl")
_include_generated("transform.jl")
_include_generated("analysis.jl")
include("codegen.jl")
_include_generated("printing.jl")
end


text:
s = open("input.txt") do file
    readlines(file);
end

function ParseLine(line)
    m = match(r"mem\[(\d+)\] = (\d+)", line);
    if m != nothing
        return map(x->parse(UInt64,x), m.captures);
    end

    m = match(r"mask = ([01X]+)", line);
    if m != nothing
        return (m.captures|>collect);
    end

    return ();
end

function SumMem(program)
    mem = Dict();
    oneMask = 0;
    zeroMask = -1;
    for line in program
        parsed = ParseLine(line);
        if length(parsed) == 0
            println(line);
            continue;
        end

        if length(parsed) == 1
            # new mask
            oneMask = parse(UInt64, String(map(x->ifelse(x=='1', '1', '0'), parsed[1])), base=2);
            zeroMask = parse(UInt64, String(map(x->ifelse(x=='0', '0', '1'), parsed[1])), base=2);
        else
            # put in mem
            val = parsed[2];
            val |= oneMask;
            val &= zeroMask;

            mem[parsed[1]] = val;
        end
    end

    return sum(map(UInt64,values(mem)));
end

println(Int(SumMem(s)))

ext: jl


text:
function grid_init_do_not_profile(inputs::Inputs, mype::Int32)::SimulationData

    ## Structure to hold all allocated simuluation data arrays
    simulation_data = SimulationData()

    ## Keep track of how much data we're allocating
    nbytes::UInt64 = 0

    ## Set the initial seed value
    seed::UInt64 = 42

    ##############################
    ## Initialize Nuclide Grids
    ##############################

    if mype == 0
        println("Initializing nuclide grids...")
    end

    ## First, we need to initialize our nuclide grid. This comes in the form
    ## of a flattened 2D array that hold all the information we need to define
    ## the cross sections for all isotopes in the simulation.
    ## The grid is composed of "NuclideGridPoint" structures, which hold the
    ## energy level of the grid point and all associated XS data at that level.
    ## An array of structures (AOS) is used instead of
    ## a structure of arrays, as the grid points themselves are accessed in
    ## a random order, but all cross section interaction channels and the
    ## energy level are read whenever the gridpoint is accessed, meaning the
    ## AOS is more cache efficient.

    ## Initialize Nuclide Grid
    simulation_data.length_nuclide_grid = inputs.n_isotopes * inputs.n_gridpoints

    resize!(simulation_data.nuclide_grid, simulation_data.length_nuclide_grid)

    nbytes += size(simulation_data.nuclide_grid)[1] * sizeof(NuclideGridPoint)
    println("nbytes: ", nbytes)

    return simulation_data

end


text:
# obtain and record medline dataframe from internet based on Readcube-generated bib file
#
# HGow to use
# First, Generate ris file from Readcube, selecting ALL references
#
# You can obtain reference data from DataFrame by
# make_html_from_dataframe
#
# You can obtain reference data from (Array of) String or Int64 of pmid (String may be separated by comma) by
# make_html_from_pmid
#
# You can obtain reference data from gcsv file by
# make_html_from_csv
#
# bibfile_abs is path of Readcube-generated ris file
# pmid_list_file_abs is path of list of pmid_data
# pubmed_data_processed_file_abs is path of csv file

#if new Reference style is needed, edit add_name_list_and_data_to_pmid_data or add_several_reference_string(pmid_data)
# in the module_Refrence_Tools
module module_Reference_Tools
    export obtain_medline_from_readcube_bib
    export make_html_from_pmid
    export make_html_from_csv
    export make_html_from_dataframe
    export custom_CSV_read
    export write_html

    using DataFrames
    using HTTP
    using CSV
    using Dates

# """
# sub funcyion of StringToIntpart
# """
    Base.@ccallable function LetterToInt(char::Char)::Int64
        x = Int(char)
        if ((x>=48) && (x<=57))
            return(x-48)
        else
            throw("invalid input; not number")
        end
        #vecx =  ['0'; '1'; '2'; '3'; '4'; '5'; '6'; '7'; '8'; '9']
        #return(findfirst((vecx .== char))-1)
    end

# """
# convert String to Integer; if cannot, throw error
# """
    Base.@ccallable function StringToIntpart(char::String)::Int64
        if (occursin(r"^-",char))
            signx = -1
            charx = replace(char, r"^-"=>"")
        else
            signx = 1
            charx = replace(char, r"^\+"=>"")
        end

        x1 = reverse(LetterToInt.(collect(charx)))

        fact = 1
        summed1 = 0
        for ix in 1:length(x1)
            summed1 = summed1 + fact * x1[ix]
            fact = fact*10
        end
        return(summed1*signx)
    end

    # """
    # #select item not included in old, from new
    # """
    Base.@ccallable function select_new(new::Array{String,1}, old::Array{String,1})::Array{String,1}
        boo = fill(false, length(new));
        for ix in 1:length(new)
            boo[ix] = !any(new[ix] .== old)
        end
        return(new[boo])
    end

# """
# #select item not included in old, from new (sumbol version)
# """
    Base.@ccallable function select_new(new::Array{Symbol,1}, old::Array{Symbol,1})::Array{Symbol,1}
        boo = fill(false, length(new));
        for ix in 1:length(new)
            boo[ix] = !any(new[ix] .== old)
        end
        return(new[boo])
    end

# """
# returns Array{String,1}
# each element is PMID concatenated with comma ("11253645,14522846,...""), with maximum unitnum
# """
    Base.@ccallable function join_by_unit(vec::Array{String,1}, unitnum::Int64, collapse::String=",")::Array{String,1}
        if (length(vec) == 0)
            return(fill("",1))
        end
        if (unitnum <= 0)
            return(fill("",1))
        end

        num = div(length(vec),unitnum)+1
        ret = fill("", num)
        for jx in 1:num
            rang = (unitnum*(jx-1)+1):min(unitnum*jx, length(vec))
            ret[jx] = join(vec[rang], collapse)
        end
        return(ret)
    end

# """
#  read CSV as all String
#  """
    Base.@ccallable function custom_CSV_read(file::String)::DataFrame
        temp = CSV.read(file;  missingstring = "this_is_missing_hahaha", limit = 2)
        types = fill(String, size(temp,2))
        return(CSV.read(file; missingstring = "this_is_missing_hahaha", types = types))
    end

# """
# delete first and last space and kaigyo   #
# """
    Base.@ccallable function delete_gomi_from_text(char::String)::String
        char = replace(char, r"^[ \n]*"=>"")
        char = replace(char, r"[ \n]*$"=>"")
        return(char)
    end

# """
# Base.@ccallable function keep_first(vec::Array{String,1})::Array{Bool, 1}
#     return is Array{Bool, 1}
# if a nth element is not equal to any of 1st to n-1th, return[n] is true
# """
    Base.@ccallable function keep_first(vec::Array{String,1})::Array{Bool, 1}
        if length(vec)<=1
            return(fill(true,size(vec)))
        end

        boo = fill(true, size(vec))
        for ix in 2:(length(vec))
            boo[ix] = all(vec[1:(ix-1)] .!= vec[ix])
        end
        return(boo)
    end

# """    Base.@ccallable function convert_readcube_bib(bibfile_abs::String, pmid_list_file_abs::String, unitnum::Int64=150, all_refresh::Bool=false)::Array{String,1}
# convert "readcube-exported bib file" to PMID Array, and write it  to "PMID_list_from_Julia.txt"
# returned value is new PMID list, concatenated with comma
# #
# bibfile_absis abs. path of bib file
# pmid_list_file_abs is abs. path of generated PMID Array file
# """
    Base.@ccallable function convert_readcube_bib(bibfile_abs::String, pmid_list_file_abs::String, unitnum::Int64=150, all_refresh::Bool=false)::Array{String,1}
        text = try
                    String.(split(read(bibfile_abs, String), "\n"));
                catch
                    fill("",0)
        end

        if (length(text)==0)
            return(fill("", 1))
        end

        text_old = try
                    String.(split(read(pmid_list_file_abs, String), ","));
                catch
                    fill("",0)
        end

        text_old_0 = copy(text_old)

        if (all_refresh)
            text_old = fill("",0)
        end

        #text = String.(split(read(bibfile_abs, String), "\n"));

        boo = fill(false, length(text));
        reg = r"pmid *= *\{.[^\{\}]*\}"

        # char = "pmid={28716377},"
        # occursin(reg,char)

        for ix in 1:length(text)
            boo[ix] = occursin(reg, text[ix]);
        end
        #length(boo[boo])
        text = text[boo]
        for ix in 1:length(text)
            text[ix] = replace(text[ix], r"pmid *= *\{"=>"")
            text[ix] = replace(text[ix], "},"=>"")
            text[ix] = replace(text[ix], " "=>"")
        end

        text = select_new(text, text_old) #only new PMID list are picked up

        if (all_refresh)
            text_old = select_new(text_old_0, text)
        end

        text_all = unique( [text_old; text] )

        if (length(text)==0)
            return(fill("", 1))
        end

        char1 =  join_by_unit(text, unitnum, ",")
        char2 = join(text_all, ",")

        try
            write(pmid_list_file_abs, char2);
        catch
            ;
        end
        return( char1 )
    end

    # """
    # Base.@ccallable function merge_dataframe(dfa::DataFrame, dfb::DataFrame)::DataFrame
    #
    #     merge two DataFrames
    #     both dfa and dfb column are left (if duplicated dfa column is left)
    #     """
    Base.@ccallable function merge_dataframe(dfa::DataFrame, dfb::DataFrame)::DataFrame
        df1 = copy(dfa)
        df2 = copy(dfb)
        boo = fill(true, size(df2, 1))

        for ix in 1:size(df2, 1)
            try
                boo[ix] = all(df2.PMID[ix] .!= df1.PMID)
            catch
                ;
            end
        end
        df2 = df2[boo, :]

        both = unique([names(df1); names(df2)])
        boo_n1 = fill(false, length(both))
        boo_n2 = fill(false, length(both))

        for ix in 1:length(both)
            boo_n1[ix] = all(both[ix] .!= names(df1))
            boo_n2[ix] = all(both[ix] .!= names(df2))
        end

        c_df1 = both[boo_n1]
        c_df2 = both[boo_n2]

        for ix in 1:length(c_df1)
            df1[c_df1[ix]] = fill("", size(df1,1))
        end
        for ix in 1:length(c_df2)
            df2[c_df2[ix]] = fill("", size(df2,1))
        end

        names(df1) == names(df2)

        return( copy(vcat(df1, df2)) )
     #only unincluded in df1

        # #return( join(df1, df2, on = :PMID, kind = :outer, makeuniwue) )
        #
        # data_vacant = DataFrame(fill(fill("", (size(df1,1) + size(df2,1))), length(both)), Symbol.(both))
        #
        # data_vacant
        #
        # if ((size(df1,1) != 0))
        #     for kx in names(df1)
        #         for jx in 1:size(df1,1)
        #             data_vacant[jx, kx] = df1[jx, kx] * ""
        #         end
        #     end
        # end
        #
        # if ((size(df2,1) != 0))
        #     for kx in names(df2)
        #         for ix in 1:size(df2,1)
        #             data_vacant[(size(df1,1) + jx), kx] = df2[jx, kx]
        #         end
        #     end
        # end
        #
        # #both are size 0
        # return(data_vacant)
    end

# """
# Base.@ccallable function get_pubmed_dataframe_from_pmid_list(char0::String)::DataFrame
#     obtain DataFrame from char0
#     char0 is String of single PMID or several PMID concatenated with comma
#
# Base.@ccallable function get_pubmed_dataframe_from_pmid_list(char::Array{String,1})::DataFrame
#     Array{String, 1} VERSION
#
#
# """
    Base.@ccallable function get_pubmed_dataframe_from_pmid_list(char0::String)::DataFrame
        if (char0 == r" *")
            #return DataFrame()
            return(data_vacant)
        end

        address = "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=pubmed&id=" * char0 * "&rettype=medline&retmode=text"
        http_message = replace(String(HTTP.request("GET", address; verbose=0)), "\r"=> "")
        http_message = replace(http_message, "\n      "=>" ")
        http_message = replace(http_message, "\""=>"")
        #http_message = replace(http_message, ","=>"\\,")

        vecx = String.(split(http_message, "\n\n"));
        vecx = vecx[occursin.("PMID- ", vecx)]
        vecx = delete_gomi_from_text.(vecx)

        dataframe_pmid = DataFrame()
        for ix in vecx
            vec2 = String.(split(ix, "\n"));
            vec2 = vec2[occursin.("-", SubString.(vec2,1,5))]

            df = DataFrame( Symbol("PMID") => fill("", 1), Symbol("OWN") => fill("", 1), Symbol("STAT") => fill("", 1), Symbol("DCOM") => fill("", 1), Symbol("LR") => fill("", 1), Symbol("IS") => fill("", 1), Symbol("VI") => fill("", 1), Symbol("IP") => fill("", 1), Symbol("DP") => fill("", 1), Symbol("TI") => fill("", 1), Symbol("PG") => fill("", 1), Symbol("LID") => fill("", 1), Symbol("AB") => fill("", 1), Symbol("CI") => fill("", 1), Symbol("FAU") => fill("", 1),Symbol("AU") => fill("", 1), Symbol("AD") => fill("", 1), Symbol("LA") => fill("", 1), Symbol("PT") => fill("", 1), Symbol("DEP") => fill("", 1), Symbol("PL") => fill("", 1), Symbol("TA") => fill("", 1), Symbol("JT") => fill("", 1), Symbol("JID") => fill("", 1), Symbol("RN") => fill("", 1), Symbol("SB") => fill("", 1), Symbol("MH") => fill("", 1), Symbol("OTO") => fill("", 1), Symbol("OT") => fill("", 1), Symbol("EDAT") => fill("", 1), Symbol("MHDA") => fill("", 1), Symbol("CRDT") => fill("", 1), Symbol("PHST") => fill("", 1), Symbol("AID") => fill("", 1), Symbol("PST") => fill("", 1), Symbol("SO")=> fill("", 1), Symbol("GR") => fill("", 1), Symbol("CIN") => fill("", 1), Symbol("PMC") => fill("", 1), Symbol("MID") => fill("", 1), Symbol("RF") => fill("", 1), Symbol("COIS") => fill("", 1), Symbol("SI") => fill("", 1), Symbol("AUID") => fill("", 1), Symbol("CN") => fill("", 1), Symbol("IR") => fill("", 1), Symbol("FIR") => fill("", 1), Symbol("EIN") => fill("", 1), Symbol("UOF") => fill("", 1), Symbol("EFR") => fill("", 1) )
            #if (length(vec2) != 0)
            if (length(vec2) != 0)
                vec0 = fill("", length(vec2))
                mat = [vec0 vec0]

                for jx in 1:length(vec2)
                    mat[jx,:] = ( String.(split(vec2[jx], "-",limit=2)) )
                end
                mat = delete_gomi_from_text.(mat)

                item = unique(mat[:,1])
                mat2 = [item fill("", length(item))]

                for kx in 1:length(item)
                    symb = Symbol(item[kx])
                    vecitem = (mat[:,2])[(mat[:,1]) .== item[kx]]
                    df[symb] = fill(join(vecitem, "\n"),1) #single row dataframe for ix
                end
            end
            dataframe_pmid = merge_dataframe(dataframe_pmid, df)
        end
        return(dataframe_pmid)
    end

    Base.@ccallable function get_pubmed_dataframe_from_pmid_list(char::Array{String,1})::DataFrame
        data_vacant = DataFrame( Symbol("PMID") => fill("", 0), Symbol("OWN") => fill("", 0), Symbol("STAT") => fill("", 0), Symbol("DCOM") => fill("", 0), Symbol("LR") => fill("", 0), Symbol("IS") => fill("", 0), Symbol("VI") => fill("", 0), Symbol("IP") => fill("", 0), Symbol("DP") => fill("", 0), Symbol("TI") => fill("", 0), Symbol("PG") => fill("", 0), Symbol("LID") => fill("", 0), Symbol("AB") => fill("", 0), Symbol("CI") => fill("", 0), Symbol("FAU") => fill("", 0),Symbol("AU") => fill("", 0), Symbol("AD") => fill("", 0), Symbol("LA") => fill("", 0), Symbol("PT") => fill("", 0), Symbol("DEP") => fill("", 0), Symbol("PL") => fill("", 0), Symbol("TA") => fill("", 0), Symbol("JT") => fill("", 0), Symbol("JID") => fill("", 0), Symbol("RN") => fill("", 0), Symbol("SB") => fill("", 0), Symbol("MH") => fill("", 0), Symbol("OTO") => fill("", 0), Symbol("OT") => fill("", 0), Symbol("EDAT") => fill("", 0), Symbol("MHDA") => fill("", 0), Symbol("CRDT") => fill("", 0), Symbol("PHST") => fill("", 0), Symbol("AID") => fill("", 0), Symbol("PST") => fill("", 0), Symbol("SO")=> fill("", 0), Symbol("GR") => fill("", 0), Symbol("CIN") => fill("", 0), Symbol("PMC") => fill("", 0), Symbol("MID") => fill("", 0), Symbol("RF") => fill("", 0), Symbol("COIS") => fill("", 0), Symbol("SI") => fill("", 0), Symbol("AUID") => fill("", 0), Symbol("CN") => fill("", 0), Symbol("IR") => fill("", 0), Symbol("FIR") => fill("", 0), Symbol("EIN") => fill("", 0), Symbol("UOF") => fill("", 0), Symbol("EFR") => fill("", 0) )

        dfret = data_vacant # DataFrame()
        for char0 in char
            dfret =  merge_dataframe(dfret, get_pubmed_dataframe_from_pmid_list(char0))
        end
        return(dfret)
    end

# """
# Base.@ccallable function add_char_to_pubmed_csv(char::String, csvfile::String = "", returnonlynew::Bool = false)::DataFrame
#     #char is PMID1,PMID2,PMID3....,PMIDn
#     ## get PMIDx reference information and add to CSV file
#     #if returnonlynew is true, returns added database, else, return merged one
#
# Base.@ccallable function add_char_to_pubmed_csv(char::Array{String,1}, csvfile::String, returnonlynew::Bool = false)::DataFrame
#     Array version
# """
    Base.@ccallable function add_char_to_pubmed_csv(char::String, csvfile::String = "", returnonlynew::Bool = false)::DataFrame
        data_vacant = DataFrame( Symbol("PMID") => fill("", 0), Symbol("OWN") => fill("", 0), Symbol("STAT") => fill("", 0), Symbol("DCOM") => fill("", 0), Symbol("LR") => fill("", 0), Symbol("IS") => fill("", 0), Symbol("VI") => fill("", 0), Symbol("IP") => fill("", 0), Symbol("DP") => fill("", 0), Symbol("TI") => fill("", 0), Symbol("PG") => fill("", 0), Symbol("LID") => fill("", 0), Symbol("AB") => fill("", 0), Symbol("CI") => fill("", 0), Symbol("FAU") => fill("", 0),Symbol("AU") => fill("", 0), Symbol("AD") => fill("", 0), Symbol("LA") => fill("", 0), Symbol("PT") => fill("", 0), Symbol("DEP") => fill("", 0), Symbol("PL") => fill("", 0), Symbol("TA") => fill("", 0), Symbol("JT") => fill("", 0), Symbol("JID") => fill("", 0), Symbol("RN") => fill("", 0), Symbol("SB") => fill("", 0), Symbol("MH") => fill("", 0), Symbol("OTO") => fill("", 0), Symbol("OT") => fill("", 0), Symbol("EDAT") => fill("", 0), Symbol("MHDA") => fill("", 0), Symbol("CRDT") => fill("", 0), Symbol("PHST") => fill("", 0), Symbol("AID") => fill("", 0), Symbol("PST") => fill("", 0), Symbol("SO")=> fill("", 0), Symbol("GR") => fill("", 0), Symbol("CIN") => fill("", 0), Symbol("PMC") => fill("", 0), Symbol("MID") => fill("", 0), Symbol("RF") => fill("", 0), Symbol("COIS") => fill("", 0), Symbol("SI") => fill("", 0), Symbol("AUID") => fill("", 0), Symbol("CN") => fill("", 0), Symbol("IR") => fill("", 0), Symbol("FIR") => fill("", 0), Symbol("EIN") => fill("", 0), Symbol("UOF") => fill("", 0), Symbol("EFR") => fill("", 0) )

        pmid_data_old = try
            custom_CSV_read(csvfile);
            pmid_data_old = pmid_data_old[(pmid_data_old.PMID .!= ""), :]
        catch
            data_vacant #DataFrame()
        end

        pmid_data_new = try
            get_pubmed_dataframe_from_pmid_list(char)
        catch
            data_vacant #DataFrame()
        end

        pmid_data = merge_dataframe(pmid_data_old, pmid_data_new)

        try
            CSV.write(csvfile, pmid_data)
        catch
            ;
        end

        if (returnonlynew)
            return(pmid_data_new)
        end
        return(pmid_data)
    end

    #char is PMID1,PMID2,PMID3....,PMIDn
    ## get PMIDx reference information and add to CSV file
    #if returnonlynew is true, returns added database, else, return merged one
    Base.@ccallable function add_char_to_pubmed_csv(char::Array{String,1}, csvfile::String, returnonlynew::Bool = false)::DataFrame
        data_vacant = DataFrame( Symbol("PMID") => fill("", 0), Symbol("OWN") => fill("", 0), Symbol("STAT") => fill("", 0), Symbol("DCOM") => fill("", 0), Symbol("LR") => fill("", 0), Symbol("IS") => fill("", 0), Symbol("VI") => fill("", 0), Symbol("IP") => fill("", 0), Symbol("DP") => fill("", 0), Symbol("TI") => fill("", 0), Symbol("PG") => fill("", 0), Symbol("LID") => fill("", 0), Symbol("AB") => fill("", 0), Symbol("CI") => fill("", 0), Symbol("FAU") => fill("", 0),Symbol("AU") => fill("", 0), Symbol("AD") => fill("", 0), Symbol("LA") => fill("", 0), Symbol("PT") => fill("", 0), Symbol("DEP") => fill("", 0), Symbol("PL") => fill("", 0), Symbol("TA") => fill("", 0), Symbol("JT") => fill("", 0), Symbol("JID") => fill("", 0), Symbol("RN") => fill("", 0), Symbol("SB") => fill("", 0), Symbol("MH") => fill("", 0), Symbol("OTO") => fill("", 0), Symbol("OT") => fill("", 0), Symbol("EDAT") => fill("", 0), Symbol("MHDA") => fill("", 0), Symbol("CRDT") => fill("", 0), Symbol("PHST") => fill("", 0), Symbol("AID") => fill("", 0), Symbol("PST") => fill("", 0), Symbol("SO")=> fill("", 0), Symbol("GR") => fill("", 0), Symbol("CIN") => fill("", 0), Symbol("PMC") => fill("", 0), Symbol("MID") => fill("", 0), Symbol("RF") => fill("", 0), Symbol("COIS") => fill("", 0), Symbol("SI") => fill("", 0), Symbol("AUID") => fill("", 0), Symbol("CN") => fill("", 0), Symbol("IR") => fill("", 0), Symbol("FIR") => fill("", 0), Symbol("EIN") => fill("", 0), Symbol("UOF") => fill("", 0), Symbol("EFR") => fill("", 0) )

        pmid_data_old = try
            custom_CSV_read(csvfile)
        catch
            data_vacant #DataFrame()
        end

        pmid_data_new = try
            get_pubmed_dataframe_from_pmid_list(char)
        catch
            data_vacant
        end

        pmid_data = merge_dataframe(pmid_data_old, pmid_data_new)

        try
            CSV.write(csvfile, pmid_data)
        catch
            ;
        end

        if (returnonlynew)
            return(pmid_data_new)
        end
        return(pmid_data)
    end

    Base.@ccallable function two_string_vector_combination(veca::Array{String, 1}, vecb::Array{String, 1})::Array{String, 1}
        # veca = ["DEP_"; "DP_"; ""]
        # vecb = ["Year"; "Month"; "Monthname"; "Monthabbr"; "Day"]
        vecx = fill("", 0)
        for jx in 1:length(veca)
            vecx = [vecx; (veca[jx] .* vecb)]
        end
        return(vecx)
    end

    Base.@ccallable function return_year_monthx3_day_sub_sub(charx0::String)::Array{String, 1}
        charx = replace(charx0, "\n"=>" ");
        charx = replace(charx, r" +"=>" ");
        charx = replace(charx, ", "=>" ");
        charx = replace(charx, r"^ "=>"");
        charx = replace(charx, r" $"=>"");

        char2 = String.(split(charx, " "));
        if (length(char2) < 3)
            return(fill("", 5))
        end

        date_in = try
            Dates.Date(charx, "yyyy u dd");
        catch
            try
                Dates.Date(charx, "yyyy U dd");
            catch
                return(fill("", 5))
            end
        end

        if (typeof(date_in) == Nothing)
            return(fill("", 5))
        end
        return(
        [string(year(date_in)); string(month(date_in)); monthname(date_in); monthabbr(date_in); string(day(date_in)); ]
        )
    end

    Base.@ccallable function return_year_monthx3_day_sub(charx::String)::Array{String, 1}
        charx = replace(charx, "\n"=>" ");
        charx = replace(charx, r" +"=>" ");
        charx = replace(charx, ", "=>" ");
        charx = replace(charx, r"^ "=>"");
        charx = replace(charx, r" $"=>"");

        retval = return_year_monthx3_day_sub_sub(charx)

        if (fill("", 5) != retval)
            return(retval)
        end

        char2 = String.(split(charx, " "));
        retval = fill("", 5)

        if (length(char2) < 3)
            char2 = [char2; fill("", (3 - length(char2)))]
        end

        x = try
            StringToIntpart(char2[1]); #parse(Int64, char2[1])
        catch
            0
        end

        if (typeof(x) != Int64)
            x = 0
        end

        if ((year(today()) < x) || (x < 1900))
            return(fill("", 5))
        end
        retval[1] = string(x)

        allmonth = [monthname.(1:12); monthabbr.(1:12)]

        y = findfirst(allmonth .== char2[2])
        if (typeof(y) == Nothing)
            return(retval)
        end

        y = mod(y-1, 12) + 1
        retval[2] = string(y)
        retval[3] = monthname(y)
        retval[4] = monthabbr(y)

        return(retval)
    end

    # charx = "2015 Janz"
    # return_year_monthx3_day_sub(charx)

    #return [year; month; monthname; monthabbr; day; ]
    Base.@ccallable function return_year_monthx3_day(charx::String)::Array{String, 1}
        if (charx == "")
            return(fill("", 5))
        end

        try
            (date_in = Dates.Date(charx, "yyyymmdd"));
            return(
            [string(year(date_in)); string(month(date_in)); monthname(date_in); monthabbr(date_in); string(day(date_in)); ]
            )
        catch
            return(return_year_monthx3_day_sub(charx))
        end
    end

    Base.@ccallable function vector_of_vector_to_array(vec::Array{Array{String,1},1})::Array{Union{String,Missing},2}
        nrow = length(vec)
        leng = fill(0, nrow)
        for ix in 1:nrow
            leng[ix] = length(vec[ix])
        end
        ncol = maximum(leng)

        myarray = Array{Union{String,Missing},2}(missing, nrow, ncol)
        for ix in 1:nrow
            myarray[ix, 1:length(vec[ix])] = vec[ix]
        end
        return(myarray)
    end

    # Base.@ccallable function vector_of_vector_to_array(vec)
    #     mytype = typeof(vec[1][1])
    #     nrow = length(vec)
    #     leng = fill(0, nrow)
    #     for ix in 1:nrow
    #         leng[ix] = length(vec[ix])
    #     end
    #     ncol = maximum(leng)
    #
    #     myarray = Array{Union{mytype,Missing},2}(missing, nrow, ncol)
    #     for ix in 1:nrow
    #         myarray[ix, 1:length(vec[ix])] = vec[ix]
    #     end
    #     return(myarray)
    # end

    # """
    # return splitted String (String Format) of String
    # return( String.(split(char, sep)) )
    # """
    Base.@ccallable function mysplit(char::String, sep::String)::Array{String, 1}
        return( String.(split(char, sep)) )
    end

    #return splitted Vector{String} (String Format) by char
    Base.@ccallable function mysplit(char::Array{String, 1}, sep::String)::Array{Array{String,1},1}
        vecx = split.(char, sep)
        ret = fill(fill("",2), length(vecx))

        for ix in 1:length(char)
            ret[ix] = String.(vecx[ix])
        end
        return( ret )
    end

    #First split Strng by sep1 then split substring by sep2...
    Base.@ccallable function doublesplit(char::String, sep1::String, sep2::String)::Array{Array{String,1},1}
        vecx = mysplit(char, sep1)
        # return(typeof(vecx))
        ret = fill(fill("",2), length(vecx))

        for ix in 1:length(vecx)
            ret[ix] = mysplit(vecx[ix], sep2)
        end
        return( ret )
    end

    #First split Array{String, 1} by sep1 then split substring by sep2...
    Base.@ccallable function doublesplit(char::Array{String, 1}, sep1::String, sep2::String)::Array{Array{Array{String,1},1},1}
        # sep2num = maximum(length.(mysplit.(char, sep2)))
        # sep1num = maximum(length.(mysplit.(char, sep1)))
        ret = fill(fill(fill("",2),2), length(char))
        for jx in 1:length(char)
            ret[jx] = doublesplit(char[jx], sep1, sep2)
        end
        return( ret )
    end
    # mysplit("a b n", " ")
    # mysplit(["a b n"; "e r t t"; "gfgf hg"], " ")
    #length( fill(fill("",1000), 12) )
    # charx="19781203"
    # #charx="1978 Dec"
    # return_year_monthx3_day(charx)
    # charx = "2015 Jan 4"
    # return_year_monthx3_day(charx)

# """
# Base.@ccallable function add_name_list_and_data_to_pmid_data(pmid_data0::DataFrame)::DataFrame
#     add author name list and DEP&DP year, month, day
# """
    Base.@ccallable function add_name_list_and_data_to_pmid_data(pmid_data0::DataFrame)::DataFrame
        pmid_data = copy(pmid_data0)
        ##subroutine
        reg=r"[#\\$%&_{}<>^|~\\\\]<>"
        for jx in (names(pmid_data))
            vecx = (pmid_data[jx])
            for ix in 1:length(vecx)
                (pmid_data[jx])[ix] = replace((pmid_data[jx])[ix], reg=>"")
            end
        end

        rownum = size(pmid_data,1)

        veca = ["DEP_"; "DP_"; ""]
        vecb = ["Year"; "Month"; "Monthname"; "Monthabbr"; "Day"]
        vecx = two_string_vector_combination(veca, vecb)

        symb = Symbol.(vecx)

        arr1 = vector_of_vector_to_array(return_year_monthx3_day.(pmid_data.DEP))
        arr2 = vector_of_vector_to_array(return_year_monthx3_day.(pmid_data.DP))

        arr3 = vector_of_vector_to_array(return_year_monthx3_day.(pmid_data.DEP))
        arr4 = vector_of_vector_to_array(return_year_monthx3_day.(pmid_data.DP))

        arr = [arr1 arr2 arr4]
        #arr[12,:]

        for ix in 1:size(arr3, 1)
            if (arr3[ix, 1] == "")
                arr3[ix, 1:5] = arr2[ix, 1:5]
            end
            if (arr4[ix, 1] == "")
                arr4[ix, 1:5] = arr1[ix, 1:5]
            end
        end
        # arr3: DEP優先
        # arr4: DP優先  Use this

        for ix in 1:15
            pmid_data[symb[ix]] = arr[:,ix]
        end

        allfau = doublesplit(pmid_data.FAU, "\n", ",")

        # allfau[67]
        # pmid_data[67:67,:]
        # size(pmid_data,1)

        pmid_data.Firstname_Full = fill("",rownum)
        pmid_data.Firstname_0 = fill("",rownum)
        pmid_data.Firstname_1 = fill("",rownum)
        pmid_data.Firstname_2 = fill("",rownum)
        pmid_data.Firstname_3 = fill("",rownum)
        pmid_data.Firstname_4 = fill("",rownum)
        pmid_data.Firstname_5 = fill("",rownum)
        pmid_data.Lastname = fill("",rownum)

        for kx in 1:rownum
            firstname = fill("", length(allfau[kx]))
            fs0 = fill("", length(allfau[kx]))
            fs1 = fill("", length(allfau[kx]))
            fs2 = fill("", length(allfau[kx]))
            fs3 = fill("", length(allfau[kx]))
            fs4 = fill("", length(allfau[kx]))
            fs5 = fill("", length(allfau[kx]))
            lastname = fill("", length(allfau[kx]))

            for jx in 1:length(allfau[kx])
                firstname[jx] = try
                    allfau[kx][jx][2]
                catch
                    ""
                end
                firstname[jx] = replace(firstname[jx], r" +"=>" ")
                firstname[jx] = replace(firstname[jx], r"^ "=>"")
                firstname[jx] = replace(firstname[jx], r" $"=>"")

                fs0[jx] = replace(firstname[jx], r"[^A-Z-]"=>"") #A-B
                fs1[jx] = replace(fs0[jx], "-"=>"") #AB

                fs2[jx] = replace(fs0[jx], r"[A-Z]"=>function(char) return(char * " "); end)
                fs2[jx] = replace(fs2[jx], " -"=>"-")
                fs2[jx] = replace(fs2[jx], r" +$"=>"") #A Z-H

                fs3[jx] = replace(fs1[jx], r"[A-Z]"=>function(char) return(char * " "); end)
                fs3[jx] = replace(fs3[jx], r" +$"=>"") #A Z H

                fs4[jx] = replace(fs0[jx], r"[A-Z]"=>function(char) return(char * ". "); end)
                fs4[jx] = replace(fs4[jx], r" +$"=>"") #A. Z. -H.

                fs5[jx] = replace(fs1[jx], r"[A-Z]"=>function(char) return(char * ". "); end)
                fs5[jx] = replace(fs5[jx], r" +$"=>"") #A. Z. H.

                lastname[jx] = replace(allfau[kx][jx][1], r" +"=>" ")
                lastname[jx] = replace(lastname[jx], r"^ "=>"")
                lastname[jx] = replace(lastname[jx], r" $"=>"")
            end

            pmid_data.Firstname_Full[kx] = join(firstname , "\n")
            pmid_data.Firstname_0[kx] = join(fs0 , "\n")
            pmid_data.Firstname_1[kx] = join(fs1 , "\n")
            pmid_data.Firstname_2[kx] = join(fs2 , "\n")
            pmid_data.Firstname_3[kx] = join(fs3 , "\n")
            pmid_data.Firstname_4[kx] = join(fs4 , "\n")
            pmid_data.Firstname_5[kx] = join(fs5 , "\n")
            pmid_data.Lastname[kx] = join(lastname , "\n")
        end

        return(pmid_data)
    end

# """
#     #authorstyle = ["#Lastname"; " "; "#Firstname_1"]
#     #Lastname and #Firstname_XXX are replaced with variables
#     Firstname_Full is full version
#     Firstname_0 is A-B style
#     Firstname_1 is AB
#     Firstname_2 is A Z-H
#     Firstname_3 is A Z H
#     Firstname_4 is A. Z. -H.
#     Firstname_5 is A. Z. H
#
#     #get author list for eachrow
# """
    Base.@ccallable function get_each_author(pmid_data0::DataFrame, authorstyle::Array{String, 1} = ["#Lastname"; " "; "#Firstname_1"])::Array{String, 1}
        pmid_data = copy(pmid_data0)
        rownum = size(pmid_data, 1)
        ret = fill("", rownum)

        for kx in 1:rownum
            vecvec = fill(fill("",1), length(authorstyle))
            boox = fill(true, length(authorstyle))

            for jx in 1:length(authorstyle)
                if (occursin(r"^ *#", authorstyle[jx]))
                    vecvec[jx] = String.(split( (pmid_data[kx:kx, :])[Symbol(replace(authorstyle[jx], r"^ *#"=>""))][1], "\n") )
                    boox[jx] = false
                end
            end

            num = length.(vecvec)
            maxnum = maximum(num)
            for jx in 1:length(authorstyle)
                if (boox[jx])
                    vecvec[jx] = fill(authorstyle[jx], maxnum)
                end
            end

            char = fill("", maxnum)
            for jx in 1:length(authorstyle)
                char = char .* vecvec[jx]
            end

            ret[kx]= join(char, "\n")
        end
        return(ret)
    end

# """
#     ##get author List
#     #max_all #max author number expressed without et al
#     #etal_num #author number written when et al is used
#     #authorstyle: authorstyle
#     #sep_vec
#     #[1] #sep between authors
#     #[2] #sep between last two authors
#     #[3] #sep between only TWO auhtors
#     #[4] #sep between author and other part
#     #[5] #et. al
# """
    Base.@ccallable function get_author_list(pmid_data0::DataFrame, max_all::Int64 = 1, etal_num::Int64 = 1,
        authorstyle::Array{String, 1} = ["#Lastname"; " "; "#Firstname_1"],
        sep_vec::Array{String, 1} = [", "; ", and"; " and "; ". "; ", et. al. "])::Array{String, 1}

        pmid_data = copy(pmid_data0)
        sepauthor = sep_vec[1]
        seplast2 = sep_vec[2]
        sep2 = sep_vec[3]
        sepafter = sep_vec[4]
        etal = sep_vec[5]

        #########Base.@ccallable function(pmid_data)
        author_list = get_each_author(pmid_data, authorstyle)

        max_all2 = max_all
        etal_num2 = min(etal_num, max_all2)

        if (max_all2 <= 1)
            for ix in 1:length(author_list)
                vec2 = String.(split(author_list[ix], "\n"))

                if (length(vec2) == 1)
                    author_list[ix] = author_list[ix] * sepafter
                else
                    author_list[ix] = vec2[1] * etal
                end
            end
            return(author_list);
        end

        if (max_all2 == 2)
            for ix in 1:length(author_list)
                vec2 = String.(split(author_list[ix], "\n"))

                if (length(vec2) == 1)
                    author_list[ix] = author_list[ix] * sepafter
                elseif (length(vec2) == 2)
                    author_list[ix] = join(vec2, sep2) * sepafter
                else
                    author_list[ix] = join(vec2[1:2], sepauthor) * etal
                end
            end
            return(author_list);
        end

        for ix in 1:length(author_list)
            vec2 = String.(split(author_list[ix], "\n"))

            if (length(vec2) == 1)
                author_list[ix] = author_list[ix] * sepafter
            elseif (length(vec2) == 2)
                author_list[ix] = join(vec2, sep2) * sepafter
            elseif (length(vec2) <= max_all2)
                author_list[ix] = join(vec2[1:(length(vec2)-1)], sepauthor) * seplast2 * vec2[length(vec2)] * sepafter
            else
                author_list[ix] = join(vec2[1:etal_num2], sepauthor) * etal
            end

            # char = author_list[ix]
            # loc = findlast("\n", char)
            # char = SubString( char, 1:( minimum(loc)-1 ) ) * seplast2 * SubString( char, ( maximum(loc)+1 ):lastindex(char) )
            # author_list[ix] = replace(char, "\n"=>sepauthor)
        end
        return(author_list);
        ######end of Base.@ccallable function
    end

    # """
    #     ##make a reference style
    #     #max_all #max author number expressed without et al
    #     #etal_num #author number written when et al is used
    #     #authorstyle: authorstyle
    #
    #     #sep_vec
    #     #[1] #sep between authors
    #     #[2] #sep between last two authors
    #     #[3] #sep between only TWO auhtors
    #     #[4] #sep between author and other part
    #     #[5] #et. al
    #
    #     #refstyle
    #     "%author_list" is replaced with author list Array{String}
    #     #TI etc is MEDLINE item
    # """
    Base.@ccallable function add_single_reference_string(pmid_data0::DataFrame, refname::String, max_all::Int64 = 1, etal_num::Int64 = 1,
        authorstyle::Array{String, 1} = ["#Lastname"; " "; "#Firstname_1"],
        sep_vec::Array{String, 1} = [", "; ", and"; " and "; ". "; ", et. al. "],
        refstyle = ["%author_list"; "#TI"; " "; "#TA"; " "; "#Year"; " <b>"; "#VI"; "</b>: "; "#PG"; ". "]
        )::DataFrame
        pmid_data = copy(pmid_data0)
        author_list = get_author_list(pmid_data, max_all, etal_num, authorstyle, sep_vec)

        rownum = size(pmid_data, 1)
        ret = fill("", rownum)

        vecvec = fill(fill("", rownum), length(refstyle))

        for jx in 1:length(refstyle)
            if (refstyle[jx] == "%author_list")
                vecvec[jx] = author_list
            elseif (occursin(r"^ *#", refstyle[jx]))
                vecvec[jx] = pmid_data[Symbol(replace(refstyle[jx], r"^ *#"=>""))]
            else
                reg=r"[#\\$%&_{}<>^|~\\\\]<>"
                charx = replace(refstyle[jx], reg=>"")
                vecvec[jx] = fill(charx, rownum)
            end
            ret = ret .* vecvec[jx]
        end

        ret2 = copy(ret)

        for ix in 1:length(ret2)
            ret2[ix] = replace(ret2[ix], "<b>"=>"\\textbf{")
            ret2[ix] = replace(ret2[ix], "<i>"=>"\\textit{")
            ret2[ix] = replace(ret2[ix], "</b>"=>"}")
            ret2[ix] = replace(ret2[ix], "</i>"=>"}")
        end

        if (refname != "")
            refname3 = Symbol("Ref_" * refname * "_html")
            refname4 = Symbol("Ref_" * refname * "_tex")

            if (all(refname3 .!= names(pmid_data)))
                pmid_data[refname3] = ret
            end
            if (all(refname4 .!= names(pmid_data)))
                pmid_data[refname4] = ret2
            end
        end
        # val = fill(fill("",1),2)
        # val[1] = ret
        # val[2] = ret2
        return(pmid_data)
    end
# """
# Base.@ccallable function add_several_reference_string(pmid_data0::DataFrame)::DataFrame
# add several reference stylesheet to  pmid_data0
# """
    Base.@ccallable function add_several_reference_string(pmid_data0::DataFrame)::DataFrame
        pmid_data = copy(pmid_data0)
        max_all = 1 #max author number expressed without et al
        etal_num = 1 #author number written when et al is used

        authorstyle = ["#Lastname"; " "; "#Firstname_1"] #style of author
        sep_vec = [", "; ", and "; " and "; ". "; ", et. al. "]

        refstyle = ["%author_list"; "#TA"; " "; "#Year"; " <b>"; "#VI"; "</b>: "; "#PG"; ". "]

        #get reference string
        pmid_data = add_single_reference_string(pmid_data, "0", max_all, etal_num, authorstyle, sep_vec, refstyle)

        max_all = 6
        etal_num = 3

        authorstyle = ["#Lastname"; " "; "#Firstname_1"] #style of author
        sep_vec = [", "; ", and "; " and "; ". "; ", et. al. "]

        refstyle = ["%author_list"; "#TI"; " "; "#TA"; " "; "#Year"; " <b>"; "#VI"; "</b>: "; "#PG"; ". "]

        pmid_data = add_single_reference_string(pmid_data, "Lancet", max_all, etal_num, authorstyle, sep_vec, refstyle)

        return(pmid_data)
    end

# """
# Base.@ccallable function add_PMID_to_list_and_write_to_csv(char0::String, pmid_list_file_abs::String, pubmed_data_generated_file_abs::String)::DataFrame
# """
    Base.@ccallable function add_PMID_to_list_and_write_to_csv(char0::String, pmid_list_file_abs::String, pubmed_data_generated_file_abs::String)::DataFrame
        char = replace(char0, " "=>"")
        char = replace(char, "\t"=>"")
        char = replace(char, "\n"=>",")
        char = replace(char, r",+"=>",")

        char = replace(char, "?term="=>"")
        char = replace(char, r"https://www-ncbi-nlm-nih-gov.*/pubmed/"=>"")
        char = replace(char, "https://www.ncbi.nlm.nih.gov/pubmed/"=>"")

        if (occursin(r"[^0-9,]", char))
            return(DataFrame( Symbol("PMID") => fill("", 0), Symbol("OWN") => fill("", 0), Symbol("STAT") => fill("", 0), Symbol("DCOM") => fill("", 0), Symbol("LR") => fill("", 0), Symbol("IS") => fill("", 0), Symbol("VI") => fill("", 0), Symbol("IP") => fill("", 0), Symbol("DP") => fill("", 0), Symbol("TI") => fill("", 0), Symbol("PG") => fill("", 0), Symbol("LID") => fill("", 0), Symbol("AB") => fill("", 0), Symbol("CI") => fill("", 0), Symbol("FAU") => fill("", 0),Symbol("AU") => fill("", 0), Symbol("AD") => fill("", 0), Symbol("LA") => fill("", 0), Symbol("PT") => fill("", 0), Symbol("DEP") => fill("", 0), Symbol("PL") => fill("", 0), Symbol("TA") => fill("", 0), Symbol("JT") => fill("", 0), Symbol("JID") => fill("", 0), Symbol("RN") => fill("", 0), Symbol("SB") => fill("", 0), Symbol("MH") => fill("", 0), Symbol("OTO") => fill("", 0), Symbol("OT") => fill("", 0), Symbol("EDAT") => fill("", 0), Symbol("MHDA") => fill("", 0), Symbol("CRDT") => fill("", 0), Symbol("PHST") => fill("", 0), Symbol("AID") => fill("", 0), Symbol("PST") => fill("", 0), Symbol("SO")=> fill("", 0), Symbol("GR") => fill("", 0), Symbol("CIN") => fill("", 0), Symbol("PMC") => fill("", 0), Symbol("MID") => fill("", 0), Symbol("RF") => fill("", 0), Symbol("COIS") => fill("", 0), Symbol("SI") => fill("", 0), Symbol("AUID") => fill("", 0), Symbol("CN") => fill("", 0), Symbol("IR") => fill("", 0), Symbol("FIR") => fill("", 0), Symbol("EIN") => fill("", 0), Symbol("UOF") => fill("", 0), Symbol("EFR") => fill("", 0) ))
        end

        text = String.(split(char, ","));

        text_old = try
                    String.(split(read(pmid_list_file_abs, String), ","));
                catch
                    fill("",0)
        end

        text_all = unique([text_old; select_new(text, text_old)])
        #text = String.(split(read(bibfile_abs, String), "\n"));

        char2 = join(text_all, ",")

        try
            write(pmid_list_file_abs, char2);
        catch
            ;
        end

        pmid_data = add_char_to_pubmed_csv(char, pubmed_data_generated_file_abs, true)
        pmid_data = add_name_list_and_data_to_pmid_data(pmid_data)
        pmid_data = add_several_reference_string(pmid_data)
        return(copy(pmid_data))
    end

    Base.@ccallable function add_PMID_to_list_and_write_to_csv(char0::Array{String, 1}, pmid_list_file_abs::String, pubmed_data_generated_file_abs::String)::DataFrame
        subdata = DataFrame( Symbol("PMID") => fill("", 0), Symbol("OWN") => fill("", 0), Symbol("STAT") => fill("", 0), Symbol("DCOM") => fill("", 0), Symbol("LR") => fill("", 0), Symbol("IS") => fill("", 0), Symbol("VI") => fill("", 0), Symbol("IP") => fill("", 0), Symbol("DP") => fill("", 0), Symbol("TI") => fill("", 0), Symbol("PG") => fill("", 0), Symbol("LID") => fill("", 0), Symbol("AB") => fill("", 0), Symbol("CI") => fill("", 0), Symbol("FAU") => fill("", 0),Symbol("AU") => fill("", 0), Symbol("AD") => fill("", 0), Symbol("LA") => fill("", 0), Symbol("PT") => fill("", 0), Symbol("DEP") => fill("", 0), Symbol("PL") => fill("", 0), Symbol("TA") => fill("", 0), Symbol("JT") => fill("", 0), Symbol("JID") => fill("", 0), Symbol("RN") => fill("", 0), Symbol("SB") => fill("", 0), Symbol("MH") => fill("", 0), Symbol("OTO") => fill("", 0), Symbol("OT") => fill("", 0), Symbol("EDAT") => fill("", 0), Symbol("MHDA") => fill("", 0), Symbol("CRDT") => fill("", 0), Symbol("PHST") => fill("", 0), Symbol("AID") => fill("", 0), Symbol("PST") => fill("", 0), Symbol("SO")=> fill("", 0), Symbol("GR") => fill("", 0), Symbol("CIN") => fill("", 0), Symbol("PMC") => fill("", 0), Symbol("MID") => fill("", 0), Symbol("RF") => fill("", 0), Symbol("COIS") => fill("", 0), Symbol("SI") => fill("", 0), Symbol("AUID") => fill("", 0), Symbol("CN") => fill("", 0), Symbol("IR") => fill("", 0), Symbol("FIR") => fill("", 0), Symbol("EIN") => fill("", 0), Symbol("UOF") => fill("", 0), Symbol("EFR") => fill("", 0) )

        for ix in char0
            subdata = merge_dataframe(subdata, add_PMID_to_list_and_write_to_csv(ix, pmid_list_file_abs, pubmed_data_generated_file_abs))
        end
        return(copy(subdata))
    end

    Base.@ccallable function get_pmid_from_URL(char::String)::String
        char = replace(char, "?term="=>"")
        char = replace(char, r"https://www-ncbi-nlm-nih-gov.*/pubmed/"=>"")
        char = replace(char, "https://www.ncbi.nlm.nih.gov/pubmed/"=>"")
        return(char)
    end #of Base.@ccallable function

    #write html file and return String
    Base.@ccallable function write_html(htmltitle::String, htmlbody::String, outputfile::String = "", iopen::Bool = false)::String
        char1 = "<!DOCTYPE html>  <html lang=\"ja\"> \n<head> <meta charset=\"UTF-8\">\n<title> " * htmltitle * " </title>\n<style> </style>\n</head>\n<body>\n" * htmlbody * "\n</body>\n</html>"

        try
            write(outputfile, char1)
        catch
            ;
        end
        if (iopen)
            try
                run(`explorer $outputfile`)
            catch
                ;
            end
        end
        return(char1)
    end

    Base.@ccallable function char_from_0_to_9XX(x::Int64)::Char
        return(Char(0x30+x))
    end

    Base.@ccallable function Int64ToString(x::Int64)::String
        if (x < 0)
            char0 = "-"
            x2 = -x
        else
            char0 = ""
            x2 = x
        end
        return( char0 * join( char_from_0_to_9XX.(reverse(digits(x2))) ) )
    end

# """
# Base.@ccallable function make_html_from_dataframe(pmid_data0::DataFrame, writehtml::Bool = true)::String
#
# make html file of reference and show it from dataframe
# """
    Base.@ccallable function make_html_from_dataframe(pmid_data0::DataFrame, writehtml::Bool = true)::String
        pmid_data= copy(pmid_data0)
        # pmid_data.FAU

        boo1 = fill(false, length(names(pmid_data)))
        boo2 = fill(false, length(names(pmid_data)))
        for ix in 1:length(names(pmid_data))
            boo1[ix] = occursin(r"Ref_.*_html", String.(names(pmid_data))[ix])
            boo2[ix] = occursin("PMID", String.(names(pmid_data))[ix])
        end

        boo = boo1.|boo2
        boo1x = boo1[boo]
        boo2x = boo2[boo]

        #sum(Int64.(boo))
        pmid_data = pmid_data[boo]
        newname = String.(names(pmid_data))
        newname2 = fill("", length(newname))

        for ix in 1:length(newname)
            newname[ix] = replace(newname[ix], "_html" => ")")
            newname[ix] = replace(newname[ix], "Ref_" => "Ref (type ")
        end

        newname[boo1x] = "\n<h2>" .* newname[boo1x] .* "</h2>\n"
        newname[boo2x] = "\n<h1> " .* newname[boo2x] .* ": "
        newname2[boo2x] .= "</h1>\n"

        output = fill("", (size(pmid_data, 1)))

        for ix in 1:size(pmid_data, 1)
            tempx = fill("", (size(pmid_data, 2)))
            for jx in 1:size(pmid_data, 2)
                tempx[jx] = newname[jx] * (pmid_data[ix, jx]) * newname2[jx]
            end
            output[ix] = join(tempx)*"\n"
        end
        ret = join(output)

        if (writehtml)
            write_html("Reference List", ret, "test.html", true)
        end
        return(ret)
        #write_html("test", ret, "test.html", true)
    end #of Base.@ccallable function

    # """
    # Base.@ccallable function make_html_from_pmid(char1::String, writehtml::Bool = true)::String
    # Base.@ccallable function make_html_from_pmid(charx::Array{String,1}, writehtml::Bool = true)::Strin
    # Base.@ccallable function make_html_from_pmid(int::Int64, writehtml::Bool = true)::String
    # ase.@ccallable Base.@ccallable function make_html_from_pmid(int::Array{Int64,1}, writehtml::Bool = true)::String
    #
    # make html filefrom PMID and show it from dataframe
    # """
    Base.@ccallable function make_html_from_pmid(char1::String, writehtml::Bool = true)::String
        char = String.(split(char1, ","))
        charx = get_pmid_from_URL.(char)
        #charx = get_pmid_from_URL(char1)

        pmid_list_file_abs = "PMID_list_from_Julia.txt"
        pubmed_data_generated_file_abs = ""
        #for known pmid_data
        newdata= add_PMID_to_list_and_write_to_csv(charx, pmid_list_file_abs, pubmed_data_generated_file_abs)
        # newdata.FAU

        ret = make_html_from_dataframe(newdata, writehtml)
        return(ret)
        #write_html("test", ret, "test.html", true)
    end #of Base.@ccallable function

    Base.@ccallable function make_html_from_pmid(charx::Array{String,1}, writehtml::Bool = true)::String
        ret = ""
        for ix in charx
            ret = ret * make_html_from_pmid(ix, false) * "\n\n"
        end
        if (writehtml)
            write_html("Reference List", ret, "test.html", true)
        end
        return(ret)
    end

    Base.@ccallable function make_html_from_pmid(int::Int64, writehtml::Bool = true)::String
        charx = Int64ToString(int)
        ret = make_html_from_pmid(charx, writehtml)
        return( ret )
    end

    Base.@ccallable function make_html_from_pmid(int::Array{Int64,1}, writehtml::Bool = true)::String
        charx = Int64ToString.(int)
        ret = make_html_from_pmid(charx, writehtml)
        return( ret )
    end

# """
# Base.@ccallable function make_html_from_csv(csvfile::String, writehtml::Bool = true)::String
# make html file from generated CSV and show it from dataframe
# """
    Base.@ccallable function make_html_from_csv(csvfile::String, writehtml::Bool = true)::String
        try
            pmid_data = custom_CSV_read(csvfile)
            ret = make_html_from_dataframe(pmid_data, writehtml)
            return(ret)
        catch
            return("")
        end
    end #of Base.@ccallable function

# """
# Base.@ccallable function obtain_medline_from_readcube_bib(bibfile_abs::String, pmid_list_file_abs::String, pubmed_data_processed_file_abs::String)::DataFrame
#
#     # obtain and record medline dataframe from internet
#     # pmid_list_file_abs is list of pmid_data
#     # pubmed_data_processed_file_abs is csv file
# """
    Base.@ccallable function obtain_medline_from_readcube_bib(bibfile_abs::String, pmid_list_file_abs::String, pubmed_data_processed_file_abs::String)::DataFrame
        unitnum = 150;
        #obtain PMID strings joined by "," as char
        char = convert_readcube_bib(bibfile_abs, pmid_list_file_abs, unitnum, true)
        pmid_data = add_char_to_pubmed_csv(char, "")

        pmid_data = add_name_list_and_data_to_pmid_data(pmid_data)
        pmid_data = add_several_reference_string(pmid_data)

        try
            CSV.write(pubmed_data_processed_file_abs, pmid_data)
        catch
            throw("file not found: ")
        end
        return(pmid_data)
    end #of Base.@ccallable function

end  # module


text:
using LinearAlgebraicRepresentation
using Base.Test

@testset "Integration Tests" begin

	@testset "M" begin
		@test LinearAlgebraicRepresentation.M(0,0)==0.5
		@test LinearAlgebraicRepresentation.M(1,0)==0.16666666666666666
		@test LinearAlgebraicRepresentation.M(2,0)==0.08333333333333333
		@test LinearAlgebraicRepresentation.M(3,0)==0.05
		@test LinearAlgebraicRepresentation.M(1,1)==0.041666666666666685
		@test LinearAlgebraicRepresentation.M(2,0)==0.08333333333333333
		@test LinearAlgebraicRepresentation.M(2,1)==0.016666666666666663
		@test LinearAlgebraicRepresentation.M(3,0)==0.05
		@test LinearAlgebraicRepresentation.M(3,1)==0.008333333333333338
		@test LinearAlgebraicRepresentation.M(3,2)==0.0023809523809523586
		@test LinearAlgebraicRepresentation.M(3,3)==0.0008928571428571397
	end

	@testset "TT" begin
		tau=[0.0 1.0 0.0; 0.0 0.0 1.0; 0.0 0.0 0.0];
		@test LinearAlgebraicRepresentation.TT(tau, 0,0,0)==0.5
		@test LinearAlgebraicRepresentation.TT(tau, 1,0,0)==0.16666666666666666
		@test LinearAlgebraicRepresentation.TT(tau, 1,1,0)==0.041666666666666685
		@test LinearAlgebraicRepresentation.TT(tau, 1,1,1)==0.0
		@test LinearAlgebraicRepresentation.TT(tau, 2,0,0)==0.08333333333333333
		@test LinearAlgebraicRepresentation.TT(tau, 2,1,0)==0.016666666666666663
		@test LinearAlgebraicRepresentation.TT(tau, 2,2,0)==0.005555555555555545
		@test LinearAlgebraicRepresentation.TT(tau, 2,2,1)==0.0
		@test LinearAlgebraicRepresentation.TT(tau, 2,2,2)==0.0
	end

	@testset "II" begin
		V = [0.0 1.0 0.0; 0.0 0.0 1.0; 0.0 0.0 0.0];
		FV = [[1,2,3]];
		P = V,FV;
		@test LinearAlgebraicRepresentation.II(P, 0,0,0)==0.5
		@test LinearAlgebraicRepresentation.II(P, 1,0,0)==0.16666666666666666
		@test LinearAlgebraicRepresentation.II(P, 0,1,0)>=0.1666666666666666
		@test LinearAlgebraicRepresentation.II(P, 0,0,1)==0.0
		@test LinearAlgebraicRepresentation.II(P, 1,1,1)==0.0
	end

	@testset "III" begin
		V = [0.0 1.0 0.0 0.0; 0.0 0.0 1.0 0.0; 0.0 0.0 0.0 1.0];
		FV = [[1, 2, 4], [1, 3, 2], [4, 3, 1], [2, 3, 4]];
		P = V,FV;
		@test LinearAlgebraicRepresentation.III(P, 0,0,0)>0.166666666
		@test LinearAlgebraicRepresentation.III(P, 0,0,0)<0.166666888
		@test LinearAlgebraicRepresentation.III(P, 1,0,0)>0.041666666
		@test LinearAlgebraicRepresentation.III(P, 1,0,0)<0.041666888
		@test LinearAlgebraicRepresentation.III(P, 0,1,0)>0.041666666
		@test LinearAlgebraicRepresentation.III(P, 0,1,0)<0.041666888
		@test LinearAlgebraicRepresentation.III(P, 0,0,1)>0.041666666
		@test LinearAlgebraicRepresentation.III(P, 0,0,1)<0.041666888
		@test LinearAlgebraicRepresentation.III(P, 10,10,10)>1.3377e-11
		@test LinearAlgebraicRepresentation.III(P, 10,10,10)<1.3388e-11
	end

	@testset "surface" begin
		V,FV = LinearAlgebraicRepresentation.simplexGrid([1,1]);
		P = [V;[0 0 0 0]], FV
		@test LinearAlgebraicRepresentation.surface(P)==1.0
		p = LinearAlgebraicRepresentation.Struct([LinearAlgebraicRepresentation.t(0.5,0.5,0), LinearAlgebraicRepresentation.r(0,0,pi/4), P]);
		q = LinearAlgebraicRepresentation.struct2lar(p);
		@test LinearAlgebraicRepresentation.surface(q)>1.0000000
		@test LinearAlgebraicRepresentation.surface(q)<1.0000222
	end

	@testset "volume" begin
		V = [0.0 1.0 0.0 0.0; 0.0 0.0 1.0 0.0; 0.0 0.0 0.0 1.0];
		FV = [[1, 2, 4], [1, 3, 2], [4, 3, 1], [2, 3, 4]];
		P = V,FV;
		@test LinearAlgebraicRepresentation.volume(P)>0.166666666
		@test LinearAlgebraicRepresentation.volume(P)<0.166668888
	end

	@testset "firstMoment" begin
		V = [0.0 1.0 0.0 0.0; 0.0 0.0 1.0 0.0; 0.0 0.0 0.0 1.0];
		FV = [[1, 2, 4], [1, 3, 2], [4, 3, 1], [2, 3, 4]];
		P = V,FV;
		@test LinearAlgebraicRepresentation.firstMoment(P)[1]<0.0416667
		@test LinearAlgebraicRepresentation.firstMoment(P)[1]>0.0416665

		@test LinearAlgebraicRepresentation.firstMoment(P)[2]<0.0416667
		@test LinearAlgebraicRepresentation.firstMoment(P)[2]>0.0416665

		@test LinearAlgebraicRepresentation.firstMoment(P)[3]<0.0416667
		@test LinearAlgebraicRepresentation.firstMoment(P)[3]>0.0416665

		@test abs(LinearAlgebraicRepresentation.firstMoment(P)[1]-LinearAlgebraicRepresentation.firstMoment(P)[2])<0.00001
		@test abs(LinearAlgebraicRepresentation.firstMoment(P)[2]-LinearAlgebraicRepresentation.firstMoment(P)[3])<0.00001
		@test abs(LinearAlgebraicRepresentation.firstMoment(P)[3]-LinearAlgebraicRepresentation.firstMoment(P)[1])<0.00001
	end

	@testset "secondMoment" begin
		V = [0.0 1.0 0.0 0.0; 0.0 0.0 1.0 0.0; 0.0 0.0 0.0 1.0];
		FV = [[1, 2, 4], [1, 3, 2], [4, 3, 1], [2, 3, 4]];
		P = V,FV;
		@test LinearAlgebraicRepresentation.secondMoment(P)[1]<0.0166666669
		@test LinearAlgebraicRepresentation.secondMoment(P)[1]>0.0166666664

		@test LinearAlgebraicRepresentation.secondMoment(P)[2]<0.0166666669
		@test LinearAlgebraicRepresentation.secondMoment(P)[2]>0.0166666664

		@test LinearAlgebraicRepresentation.secondMoment(P)[3]<0.0166666669
		@test LinearAlgebraicRepresentation.secondMoment(P)[3]>0.0166666664

		@test abs(LinearAlgebraicRepresentation.secondMoment(P)[1]-LinearAlgebraicRepresentation.secondMoment(P)[2])<0.00001
		@test abs(LinearAlgebraicRepresentation.secondMoment(P)[2]-LinearAlgebraicRepresentation.secondMoment(P)[3])<0.00001
		@test abs(LinearAlgebraicRepresentation.secondMoment(P)[3]-LinearAlgebraicRepresentation.secondMoment(P)[1])<0.00001
	end

	@testset "inertiaProduct" begin
		V = [0.0 1.0 0.0 0.0; 0.0 0.0 1.0 0.0; 0.0 0.0 0.0 1.0];
		FV = [[1, 2, 4], [1, 3, 2], [4, 3, 1], [2, 3, 4]];
		P = V,FV;
		@test LinearAlgebraicRepresentation.inertiaProduct(P)[1]<0.00833666
		@test LinearAlgebraicRepresentation.inertiaProduct(P)[1]>0.00833000

		@test LinearAlgebraicRepresentation.inertiaProduct(P)[2]<0.00833666
		@test LinearAlgebraicRepresentation.inertiaProduct(P)[2]>0.00833000

		@test LinearAlgebraicRepresentation.inertiaProduct(P)[3]<0.00833666
		@test LinearAlgebraicRepresentation.inertiaProduct(P)[3]>0.00833000
	end

	@testset "centroid" begin
		V = [0.0 1.0 0.0 0.0; 0.0 0.0 1.0 0.0; 0.0 0.0 0.0 1.0];
		FV = [[1, 2, 4], [1, 3, 2], [4, 3, 1], [2, 3, 4]];
		P = V,FV;
		@test LinearAlgebraicRepresentation.centroid(P)[1]<0.26
		@test LinearAlgebraicRepresentation.centroid(P)[1]>0.24

		@test LinearAlgebraicRepresentation.centroid(P)[2]<0.26
		@test LinearAlgebraicRepresentation.centroid(P)[2]>0.24

		@test LinearAlgebraicRepresentation.centroid(P)[3]<0.26
		@test LinearAlgebraicRepresentation.centroid(P)[3]>0.24
	end

	@testset "inertiaMoment" begin
		V = [0.0 1.0 0.0 0.0; 0.0 0.0 1.0 0.0; 0.0 0.0 0.0 1.0];
		FV = [[1, 2, 4], [1, 3, 2], [4, 3, 1], [2, 3, 4]];
		P = V,FV;
		@test LinearAlgebraicRepresentation.inertiaMoment(P)[1]<0.0333555
		@test LinearAlgebraicRepresentation.inertiaMoment(P)[1]>0.0333111

		@test LinearAlgebraicRepresentation.inertiaMoment(P)[2]<0.0333555
		@test LinearAlgebraicRepresentation.inertiaMoment(P)[2]>0.0333111

		@test LinearAlgebraicRepresentation.inertiaMoment(P)[3]<0.0333555
		@test LinearAlgebraicRepresentation.inertiaMoment(P)[3]>0.0333111
	end

end


text:
# Autogenerated wrapper script for seatd_jll for i686-linux-gnu
export libseat, seatd

JLLWrappers.@generate_wrapper_header("seatd")
JLLWrappers.@declare_library_product(libseat, "libseat.so.1")
JLLWrappers.@declare_executable_product(seatd)
function __init__()
    JLLWrappers.@generate_init_header()
    JLLWrappers.@init_library_product(
        libseat,
        "lib/libseat.so",
        RTLD_LAZY | RTLD_DEEPBIND,
    )

    JLLWrappers.@init_executable_product(
        seatd,
        "bin/seatd",
    )

    JLLWrappers.@generate_init_footer()
end  # __init__()


text:
isdefined(Base, :__precompile__) && __precompile__()

module InfrastructureSystems

import CSV
import DataFrames
import Dates
import JSON3
import Random
import Pkg
import PrettyTables
import TimeSeries
using DataStructures: SortedDict

using DocStringExtensions

@template (FUNCTIONS, METHODS) = """
                                 $(TYPEDSIGNATURES)
                                 $(DOCSTRING)
                                 """

# IS should not export any function since it can have name clashes with other packages.
# Do not add export statements.

"""
Base type for any struct in the SIIP packages.
All structs must implement a kwarg-only constructor to allow deserializing from a Dict.
"""
abstract type InfrastructureSystemsType end

"""
Base type for structs that are stored in a system.

Required interface functions for subtypes:
- get_name()
- get_internal()

Optional interface functions:
- get_time_series_container()

Subtypes may contain time series.
"""
abstract type InfrastructureSystemsComponent <: InfrastructureSystemsType end

"""
Base type for auxillary structs. These should not be stored in a system.
"""
abstract type DeviceParameter <: InfrastructureSystemsType end

"""
Return the internal time_series storage container or nothing, if the type doesn't store
time series.

Subtypes need to implement this method if they store time series.
"""
function get_time_series_container(value::InfrastructureSystemsComponent)
    return nothing
end

set_time_series_container!(value::InfrastructureSystemsComponent) = nothing

get_name(value::InfrastructureSystemsComponent) = value.name
set_name!(value::InfrastructureSystemsComponent, name) = value.name = name
get_internal(value::InfrastructureSystemsComponent) = value.internal

include("common.jl")
include("utils/assert_op.jl")
include("utils/recorder_events.jl")
include("utils/flatten_iterator_wrapper.jl")
include("utils/generate_structs.jl")
include("utils/lazy_dict_from_iterator.jl")
include("utils/logging.jl")
include("utils/stdout_redirector.jl")
include("utils/utils.jl")
include("internal.jl")
include("time_series_storage.jl")
include("abstract_time_series.jl")
include("forecasts.jl")
include("static_time_series.jl")
include("time_series_container.jl")
include("time_series_parser.jl")
include("components.jl")
include("generated/includes.jl")
include("single_time_series.jl")
include("deterministic_single_time_series.jl")
include("deterministic.jl")
include("probabilistic.jl")
include("scenarios.jl")
include("deterministic_metadata.jl")
include("hdf5_time_series_storage.jl")
include("in_memory_time_series_storage.jl")
include("time_series_formats.jl")
include("time_series_cache.jl")
include("time_series_parameters.jl")
include("time_series_utils.jl")
include("component.jl")
include("results.jl")
include("serialization.jl")
include("system_data.jl")
include("validation.jl")
include("utils/print.jl")
include("utils/test.jl")
include("units.jl")
include("deprecated.jl")

end # module


text:
using ABCDistances
using Distributions
Libdl.dlopen("/usr/lib/liblapack.so.3", Libdl.RTLD_GLOBAL); ##Needed to avoid PyPlot problems on my work machine
##I sometimes also need run "export LD_LIBRARY_PATH=$HOME/.julia/v0.6/Conda/deps/usr/lib/:$LD_LIBRARY_PATH" - see https://github.com/JuliaPy/Conda.jl/issues/105
using PyPlot

######################################################################
##Define plotting functions
######################################################################
plot_cols = ("b", "g", "r", "c", "m", "y", "k");
function plot_init(out::ABCPMCOutput, i::Int)
    ssim = out.init_sims[i]
    n = min(2500, size(ssim)[2])
    s1 = vec(ssim[1,1:n])
    s2 = vec(ssim[2,1:n])
    plot(s1, s2, ".", color=plot_cols[i])
    return nothing
end
function plot_acc(out::ABCPMCOutput, i::Int)
    w = out.abcdists[i].w
    h = out.thresholds[i]
    h < Inf || return nothing
    ##Plot appropriate ellipse
    θ = 0:0.1:6.3
    x = (h/w[1])*sin.(θ)+sobs[1]
    y = (h/w[2])*cos.(θ)+sobs[2]
    plot(x, y, lw=3, color=plot_cols[i])
    return nothing
end

######################################################################
##Run ABC
######################################################################
##Set up abcinput
function sample_sumstats(pars::Array)
    success = true
    stats = [pars[1] + 0.1*randn(1); randn(1)]
    (success, stats)
end

sobs = [0.0,0.0];

abcinput = ABCInput();
abcinput.prior = MvNormal(1, 100.0);
abcinput.sample_sumstats = sample_sumstats;
abcinput.abcdist = WeightedEuclidean(sobs);
abcinput.nsumstats = 2;

##Perform ABC-PMC
srand(20);
pmcoutput_alg5 = abcPMC5(abcinput, 1000, 1/2, 50000, store_init=true);
srand(20);
abcinput.abcdist = pmcoutput_alg5.abcdists[1];
pmcoutput_alg4 = abcPMC4(abcinput, 1000, 1/2, 50000, h1=pmcoutput_alg5.thresholds[1], store_init=true);
srand(20);
pmcoutput_alg2 = abcPMC2(abcinput, 1000, 1/2, 50000, h1=pmcoutput_alg5.thresholds[1], store_init=true);
srand(20);
abcinput.abcdist = WeightedEuclidean(sobs);
pmcoutput_alg3V = abcPMC3V(abcinput, 1000, 1/2, 50000, store_init=true);
srand(20);
abcinput.abcdist = MahalanobisEmp(sobs);
pmcoutput_alg5_Mahalanobis = abcPMC5(abcinput, 1000, 1/2, 50000, store_init=true);

##Look at weights
pmcoutput_alg2.abcdists[1].w
pmcoutput_alg3V.abcdists[1].w ##The same
[pmcoutput_alg4.abcdists[i].w for i in 1:pmcoutput_alg4.niterations]
[pmcoutput_alg5.abcdists[i].w for i in 1:pmcoutput_alg5.niterations]

##Plot simulations from each importance density and acceptance regions
##First for the three analyses shown in the paper
nits = min(pmcoutput_alg2.niterations, pmcoutput_alg5.niterations, pmcoutput_alg4.niterations)
PyPlot.figure(figsize=(13,12))
PyPlot.subplot(231)
for i in 1:nits
    plot_init(pmcoutput_alg2, i)
end
PyPlot.xlabel(L"$s_1$")
PyPlot.ylabel(L"$s_2$")
PyPlot.title("Algorithm 2 simulations")
PyPlot.subplot(232)
for i in 1:nits
    plot_init(pmcoutput_alg4, i)
end
PyPlot.xlabel(L"$s_1$")
PyPlot.ylabel(L"$s_2$")
PyPlot.title("Algorithm 4 simulations")
PyPlot.subplot(233)
for i in 1:nits
    plot_init(pmcoutput_alg5, i)
end
PyPlot.xlabel(L"$s_1$")
PyPlot.ylabel(L"$s_2$")
PyPlot.title("Algorithm 5 simulations")
PyPlot.subplot(234)
for i in 1:nits
    plot_acc(pmcoutput_alg2, i)
end
PyPlot.xlabel(L"$s_1$")
PyPlot.ylabel(L"$s_2$")
PyPlot.title("Algorithm 2 acceptance regions")
PyPlot.subplot(235)
for i in 1:nits
    plot_acc(pmcoutput_alg4, i)
end
PyPlot.xlabel(L"$s_1$")
PyPlot.ylabel(L"$s_2$")
PyPlot.title("Algorithm 4 acceptance regions")
PyPlot.subplot(236)
for i in 1:nits
    plot_acc(pmcoutput_alg5, i)
end
PyPlot.xlabel(L"$s_1$")
PyPlot.ylabel(L"$s_2$")
PyPlot.title("Algorithm 5 acceptance regions")
PyPlot.tight_layout()
PyPlot.savefig("normal_acc_regions.pdf")

##Preceding plot for two analyses omitted from the paper
##(Mahalanobis acc region omitted as this would need extra code)
nits = min(pmcoutput_alg3V.niterations, pmcoutput_alg5_Mahalanobis.niterations)
PyPlot.figure(figsize=(12,12))
PyPlot.subplot(221)
for i in 1:nits
    plot_init(pmcoutput_alg3V, i)
end
PyPlot.xlabel(L"$s_1$")
PyPlot.ylabel(L"$s_2$")
PyPlot.subplot(222)
for i in 1:nits
    plot_init(pmcoutput_alg5_Mahalanobis, i)
end
PyPlot.xlabel(L"$s_1$")
PyPlot.ylabel(L"$s_2$")
PyPlot.subplot(223)
for i in 1:nits
    plot_acc(pmcoutput_alg3V, i)
end
PyPlot.xlabel(L"$s_1$")
PyPlot.ylabel(L"$s_2$")
PyPlot.tight_layout()

##Plot MSEs
get_mses(p, w) = sum(p.^2.*w) / sum(w)
s1 = pmcoutput_alg2;
s2 = pmcoutput_alg4;
s3 = pmcoutput_alg5;
MSE1 = Float64[get_mses(s1.parameters[1,:,i], s1.weights[:,i])  for i in 1:s1.niterations];
MSE2 = Float64[get_mses(s2.parameters[1,:,i], s2.weights[:,i])  for i in 1:s2.niterations];
MSE3 = Float64[get_mses(s3.parameters[1,:,i], s3.weights[:,i])  for i in 1:s3.niterations];
PyPlot.figure(figsize=(12,3));
plot(s1.cusims, log10.(MSE1), "b-o");
plot(s2.cusims, log10.(MSE2), "g-^");
plot(s3.cusims, log10.(MSE3), "y-*");
xlabel("Simulations");
ylabel("log₁₀(MSE)");
legend(["Algorithm 2","Algorithm 4","Algorithm 5"], loc="lower left");
PyPlot.tight_layout();
PyPlot.savefig("normal_MSE.pdf");

##Add lines for other algorithms
s4 = pmcoutput_alg3V;
s5 = pmcoutput_alg5_Mahalanobis;
MSE4 = Float64[get_mses(s4.parameters[1,:,i], s4.weights[:,i])  for i in 1:nits];
MSE5 = Float64[get_mses(s5.parameters[1,:,i], s5.weights[:,i])  for i in 1:nits];
plot(s4.cusims[1:nits], log10.(MSE4), "r-x");
plot(s5.cusims[1:nits], log10.(MSE5), "k-|");
legend(["Algorithm 2", "Algorithm 4", "Alg 5", "Alg 3 (variant)", "Alg 5 Mahalanobis"]);

#####################################################
##Exploratory investigation of different alpha values
##(as requested by reviewers)
#####################################################
alphas = 0.05:0.05:0.95;
MSEs_alg5 = zeros(alphas);
MSEs_alg4 = zeros(alphas);
MSEs_alg3 = zeros(alphas);
for i in 1:length(alphas)
    abcinput.abcdist = WeightedEuclidean(sobs)
    srand(20)
    x = abcPMC5(abcinput, 1000, alphas[i], 50000)
    nits = x.niterations
    MSEs_alg5[i] = (nits == 0) ? Inf : get_mses(x.parameters[1,:,nits], x.weights[:,nits])
    srand(20)
    x = abcPMC3(abcinput, 1000, alphas[i], 50000)
    nits = x.niterations
    MSEs_alg3[i] = (nits == 0) ? Inf : get_mses(x.parameters[1,:,nits], x.weights[:,nits])
    if nits > 0
        abcinput.abcdist = x.abcdists[1]
    end
    srand(20)
    x = abcPMC4(abcinput, 1000, alphas[i], 50000)
    nits = x.niterations
    MSEs_alg4[i] = (nits == 0) ? Inf : get_mses(x.parameters[1,:,nits], x.weights[:,nits])
end

PyPlot.figure();
plot(alphas, log10.(MSEs_alg5), "r-x");
plot(alphas, log10.(MSEs_alg3), "b-o");
plot(alphas, log10.(MSEs_alg4), "g-*");
##MSE is minimised by alpha approximately equal to 0.5


text:
using Test

@testset "Tokenize" begin
    include("julia_simple_func.jl")
end


text:
# Chemfiles.jl, a modern library for chemistry file reading and writing
# Copyright (C) Guillaume Fraux and contributors -- BSD license

export name, id, add_atom!, residue_for_atom

"""
Create a new residue with the given ``name``
"""
function Residue(name::String)
    handle = lib.chfl_residue(pointer(name))
    return Residue(handle)
end

"""
Create a new residue with the given ``name`` and residue identifier ``resid``.
"""
function Residue(name::String, resid::Integer)
    handle = lib.chfl_residue_with_id(pointer(name), UInt64(resid))
    return Residue(handle)
end

"""
Get a copy of the residue at ``index`` from a ``topology``.

The residue index in the topology is not always the same as the residue
identifier.
"""
function Residue(topology::Topology, index::Integer)
    handle = lib.chfl_residue_from_topology(topology.handle, UInt64(index))
    return Residue(handle)
end

"""
Get a copy of the residue containing the atom at ``index`` in the ``topology``.

This function will return ``nothing`` if the atom is not in a residue, or if
the ``index`` is bigger than the number of atoms in the topology.
"""
function residue_for_atom(topology::Topology, index::Integer)
    handle = lib.chfl_residue_for_atom(topology.handle, UInt64(index))
    if Int(handle) == 0
        return nothing
    else
        return Residue(handle)
    end
end

"""
Free the allocated memory for the ``Residue`` object.
"""
function _free(residue::Residue)
    lib.chfl_residue_free(residue.handle)
end

"""
Get the name of a ``residue``.
"""
function name(residue::Residue)
    return _call_with_growing_buffer(
        (buffer, size) -> _check(lib.chfl_residue_name(residue.handle, buffer, size))
    )
end

"""
Get the identifier of a ``residue`` in the initial topology.
"""
function id(residue::Residue)
    resid = Ref{UInt64}(0)
    _check(
        lib.chfl_residue_id(residue.handle, resid)
    )
    return resid[]
end

"""
Get the number of atoms in a ``residue``.
"""
function Base.size(residue::Residue)
    atoms = Ref{UInt64}(0)
    _check(
        lib.chfl_residue_atoms_count(residue.handle, atoms)
    )
    return atoms[]
end

"""
Add the atom at the given ``index`` in the ``residue``.
"""
function add_atom!(residue::Residue, index::Integer)
    _check(
        lib.chfl_residue_add_atom(residue.handle, UInt64(index))
    )
    return nothing
end

"""
Check if the atom at the given ``index`` is in the ``residue``.
"""
function Base.contains(residue::Residue, index::Integer)
    result = Ref{UInt8}(0)
    _check(
        lib.chfl_residue_contains(residue.handle, UInt64(index), result)
    )
    return convert(Bool, result[])
end

"""
Make a deep copy of a ``residue``.
"""
function Base.deepcopy(residue::Residue)
    handle = lib.chfl_residue_copy(residue.handle)
    return Residue(handle)
end


text:
using DDL
using Test

@testset "DDL.jl" begin
    # Write your tests here.
end


text:
export PathResult,
    solution,
    accuracy,
    residual,
    steps,
    accepted_steps,
    rejected_steps,
    winding_number,
    path_number,
    start_solution,
    multiplicity,
    last_path_point,
    valuation,
    is_success,
    is_at_infinity,
    is_excess_solution,
    is_failed,
    is_finite,
    is_singular,
    is_nonsingular,
    is_real

"""
    PathResult

A `PathResult` is the result of tracking of a path with [`track`](@ref) using an [`AbstractPathTracker`](@ref) (
e.g. [`EndgameTracker`](@ref))

## Fields

General solution information:
* `return_code`: See the list of return codes below.
* `solution::V`: The solution vector.
* `t::Float64`: The value of `t` at which `solution` was computed. Note that if
  `return_code` is `:at_infinity`, then `t` is the value when this was decided.
* `accuracy::Float64`: An estimate the (relative) accuracy of the computed solution.
* `residual::Float64`: The infinity norm of `H(solution,t)`.
* `condition_jacobian::Float64`: This is the condition number of the Jacobian at the
  solution. A high condition number indicates a singular solution or a
  solution on a positive dimensional component.
* `winding_number:Union{Nothing, Int}`: The computed winding number. This is a lower bound
  on the multiplicity of the solution. It is ``nothing`` if the Cauchy endgame was not used.
* `extended_precision::Bool`: Indicate whether extended precision is necessary to achieve
  the accuracy of the `solution`.
* `path_number::Union{Nothing,Int}`: The number of the path (optional).
* `start_solution::Union{Nothing,V}`: The start solution of the path (optional).

Performance information:
* `accepted_steps::Int`: The number of accepted steps during the path tracking.
* `rejected_steps::Int`: The number of rejected steps during the path tracking.
* `extended_precision_used::Bool`: Indicates whether extended precision was
  necessary to track the path.

Additional path and solution informations
* `valuation::Vector{Float64}`: An approximation of the valuation of the
  Puiseux series expansion of ``x(t)``.
* `last_path_point::Tuple{V,Float64}`: The last pair ``(x,t)`` before the solution was
  computed. If the solution was computed with the Cauchy endgame, then the pair ``(x,t)``
  can be used to rerun the endgame.

## Return codes

Possible return codes are:
* `:success`: The `EndgameTracker` obtained a solution.
* `:at_infinity`: The `EndgameTracker` stopped the tracking of the path since it determined
  that that path is diverging towards infinity.
* `:at_zero`: The `EndgameTracker` stopped the tracking of the path since it determined
  that that path has a solution where at least one coordinate is 0. This only happens if
  the option `zero_is_at_infinity` is `true`.
* `:excess_solution`: For the solution of the system, the system had to be
  modified which introduced artificial solutions and this solution is one of them.
* various return codes indicating termination of the tracking
"""
Base.@kwdef mutable struct PathResult
    return_code::Symbol
    solution::Vector{ComplexF64}
    t::Float64
    accuracy::Float64
    residual::Float64
    multiplicity::Union{Nothing,Int}
    condition_jacobian::Float64
    winding_number::Union{Nothing,Int}
    extended_precision::Bool
    path_number::Union{Nothing,Int}
    start_solution::Any
    last_path_point::Tuple{Vector{ComplexF64},Float64}
    valuation::Union{Nothing,Vector{Float64}}
    ω::Float64
    μ::Float64
    # performance stats
    accepted_steps::Int
    rejected_steps::Int
    steps_eg::Int = 0
    extended_precision_used::Bool
end

Base.show(io::IO, r::PathResult) = print_fieldnames(io, r)
Base.show(io::IO, ::MIME"application/prs.juno.inline", r::PathResult) = r

"""
    solution(r::PathResult)

Get the solution of the path.
"""
solution(r::PathResult) = r.solution

"""
    accuracy(r::PathResult)

Get the accuracy of the solution. This is an estimate of the (relative) distance to the
true solution.
"""
accuracy(r::PathResult) = r.accuracy

"""
    residual(r::PathResult)

Get the residual of the solution.
"""
residual(r::PathResult) = r.residual

"""
    steps(r::PathResult)

Total number of steps the path tracker performed.
"""
steps(r::PathResult) = accepted_steps(r) + rejected_steps(r)

"""
    accepted_steps(r::PathResult)

Total number of steps the path tracker accepted.
"""
accepted_steps(r::PathResult) = r.accepted_steps

"""
    rejected_steps(r::PathResult)

Total number of steps the path tracker rejected.
"""
rejected_steps(r::PathResult) = r.rejected_steps

"""
    winding_number(r::PathResult)

Get the winding number of the solution of the path. Returns `nothing` if it wasn't computed.
"""
winding_number(r::PathResult) = r.winding_number

"""
    cond(r::PathResult)

Return the condition number of the Jacobian of the result. A high condition number indicates
that the solution is singular or on a positive dimensional component.
"""
LA.cond(r::PathResult) = r.condition_jacobian

"""
    path_number(r::PathResult)

Get the number of the path. Returns `nothing` if it wasn't provided.
"""
path_number(r::PathResult) = r.path_number

"""
    start_solution(r::PathResult)

Get the start solution of the path.
"""
start_solution(r::PathResult) = r.start_solution

"""
    multiplicity(r::PathResult)

Get the multiplicity of the solution of the path. Returns `nothing` if it wasn't computed.
"""
multiplicity(r::PathResult) = r.multiplicity

"""
    last_path_point(r::PathResult)

Returns a tuple `(x,t)` containing the last zero of `H(x, t)` before the Cauchy endgame was used.
Returns `nothing` if the endgame strategy was not invoked.
"""
last_path_point(r::PathResult) = r.last_path_point

"""
    valuation(r::PathResult)

Get the computed valuation of the path.
"""
valuation(r::PathResult) = r.valuation

"""
    is_success(r::PathResult)

Checks whether the path is successfull.
"""
is_success(r::PathResult) = r.return_code == :success

"""
    is_at_infinity(r::PathResult)

Checks whether the path goes to infinity.
"""
is_at_infinity(r::PathResult) = r.return_code == :at_infinity || r.return_code == :at_zero

"""
    is_excess_solution(r::PathResult)

Checks whether the path is successfull.
"""
is_excess_solution(r::PathResult) = r.return_code == :excess_solution

"""
    is_failed(r::PathResult)

Checks whether the path failed.
"""
is_failed(r::PathResult) = !(is_at_infinity(r) || is_success(r) || is_excess_solution(r))

"""
    is_finite(r::PathResult)

Checks whether the path result is finite.
"""
is_finite(r::PathResult) = is_success(r)
Base.isfinite(r::PathResult) = is_finite(r)

"""
    is_singular(r::PathResult; tol::Float64 = 1e10)

Checks whether the path result `r` is singular. This is true if
the winding number is larger than  1 or if the condition number of the Jacobian
is larger than `tol`.
"""
is_singular(r::PathResult; tol::Float64 = 1e10) = is_singular(r, tol)
function is_singular(r::PathResult, tol::Real)
    (unpack(r.condition_jacobian, 1.0) > tol || unpack(winding_number(r), 1) > 1) &&
        is_success(r)
end

"""
    is_nonsingular(r::PathResult; tol::Float64 = 1e10)

Checks whether the path result is non-singular. This is true if
it is not singular.
"""
is_nonsingular(r::PathResult; kwargs...) = !is_singular(r; kwargs...) && is_success(r)
is_nonsingular(r::PathResult, tol::Real) = !is_singular(r, tol) && is_success(r)

"""
    is_real(r::PathResult; tol::Float64 = 1e-6)

We consider a result as `real` if the infinity-norm of the imaginary part of the solution
is at most `tol`.
"""
is_real(r::PathResult; tol::Float64 = 1e-6) = is_real(r, tol)
is_real(r::PathResult, tol::Real) = maximum(abs ∘ imag, r.solution) < tol
# provide fallback since this in in Base
Base.isreal(r::PathResult, tol) = is_real(r, tol)
Base.isreal(r::PathResult; kwargs...) = is_real(r; kwargs...)


text:
# This file is a part of Julia. License is MIT: https://julialang.org/license

module Foo
include("SubFoo.jl")
import Bar, Baz, Qux
this = "Foo1"
which = "path"
end

max_stars_repo_name: Dictino/julia

max_issues_repo_name: Dictino/julia

max_forks_repo_name: Dictino/julia


text:
" State feedback parameters. These modfy state based on state. "
abstract type AbstractStateFeedback end

@mix @columns struct KAutophagy{Mo}
    # Field         | Default  | Unit       | Pror           | Limits       | Log  | Description
    K_autophagy::Mo | 0.000001 | mol        | Beta(2.0, 2.0) | [1e-8, 1e-3] | true | "Half saturation metabolic rate for reincorporation of tissues. Necessary to not break the laws of thermodynamics!"
end
" Autophagy. Parameters for self reabsorbtion when metabolic rates fall "
@KAutophagy struct LosslessAutophagy{Mo} <: AbstractStateFeedback end
@KAutophagy struct StructuralLossAutophagy{Mo} <: AbstractStateFeedback end

@KAutophagy struct DissipativeAutophagy{Mo,MoMo} <: AbstractStateFeedback
    r_EC_V::MoMo    | 0.0      | mol*mol^-1 | Beta(2.0, 2.0)  | [0.0,1.0]   | _    | "Recovery of C from structure"
    r_EN_V::MoMo    | 0.5      | mol*mol^-1 | Beta(2.0, 2.0)  | [0.0,1.0]   | _    | "Recovery of N from structure"
end

"""
Function to apply feedback on growth the process, such as autopagy in resource shortage.
"""
feedback!(o, u) = feedback!(feedback_pars(o), o, u)
feedback!(f::Nothing, o, u) = nothing
feedback!(f, o, u) = begin
    c, n, v = feedback(f, o, u)
    o.J[:C,:fbk] += c
    o.J[:N,:fbk] += n
    o.J[:V,:fbk] += v
    nothing
end
feedback(f::LosslessAutophagy, o, u) = begin
    aph = autophagy(f, o, u)
    c, n, v = aph, aph * n_N_V(o), -aph
end
feedback(f::StructuralLossAutophagy, o, u) = begin
    aph = autophagy(f, o, u)
    c, n, v = zero(aph), zero(aph), -aph
end
feedback(f::DissipativeAutophagy, o, u) = begin
    aph = autophagy(f, o, u)
    c, n, v = aph * f.r_EC_V, aph * f.r_EN_V * n_N_V(o), -aph
end

autophagy(f, o, u) = begin
    hs = half_saturation(oneunit(f.K_autophagy), f.K_autophagy, rate(o.vars))
    u.V * (oneunit(hs) - hs)
end


text:
using FDTDSolver
using Test

@testset "FDTDSolver.jl" begin
    # Write your tests here.
end


text:
module CommunalHelperMoveSwapBlock
using ..Ahorn, Maple

@mapdef Entity "CommunalHelper/MoveSwapBlock" MoveSwapBlock(
    x::Integer,
    y::Integer,
    width::Integer=Maple.defaultBlockWidth,
    height::Integer=Maple.defaultBlockHeight,
    direction::String="Left",
    canSteer::Bool=false,
    returns::Bool=true,
    freezeOnSwap::Bool=true,
    moveSpeed::Number=60.0,
    moveAcceleration::Number=300.0,
    swapSpeedMultiplier::Number=1.0,
)

const placements = Ahorn.PlacementDict(
    "Move Swap Block (Communal Helper)" => Ahorn.EntityPlacement(
        MoveSwapBlock,
        "rectangle",
        Dict{String,Any}(),
        Ahorn.SwapBlock.swapFinalizer,
    ),
)

Ahorn.editingOptions(entity::MoveSwapBlock) = Dict{String,Any}(
    "direction" => Maple.move_block_directions,
    "moveSpeed" => Dict{String,Number}(
        "Slow" => 60.0,
        "Fast" => 75.0,
    ),
)

Ahorn.minimumSize(entity::MoveSwapBlock) = 16, 16
Ahorn.resizable(entity::MoveSwapBlock) = true, true
Ahorn.nodeLimits(entity::MoveSwapBlock) = 1, 1

function Ahorn.selection(entity::MoveSwapBlock)
    x, y = Ahorn.position(entity)
    stopX, stopY = Int.(entity.data["nodes"][1])

    width = Int(get(entity.data, "width", 8))
    height = Int(get(entity.data, "height", 8))

    return [
        Ahorn.Rectangle(x, y, width, height),
        Ahorn.Rectangle(stopX, stopY, width, height),
    ]
end

const midColor = (4, 3, 23) ./ 255
const highlightColor = (59, 50, 101) ./ 255

const arrow = "objects/CommunalHelper/moveSwapBlock/midBlockCardinal"
const arrowRotations = Dict{String,Number}(
    "Up" => 0,
    "Right" => pi / 2,
    "Down" => pi,
    "Left" => pi / 2 * 3,
)

const gem = "objects/CommunalHelper/moveSwapBlock/midBlockOrange"
const gemOffsets = Dict{String,Tuple{Int,Int}}(
    "Up" => (0, -1),
    "Right" => (1, 0),
    "Down" => (0, 1),
    "Left" => (-1, 0),
)

const button = "objects/moveBlock/button"
const buttonColor = (255, 126, 16, 255) ./ 255

function Ahorn.renderSelectedAbs(ctx::Ahorn.Cairo.CairoContext, entity::MoveSwapBlock)
    startX, startY = Int(entity.data["x"]), Int(entity.data["y"])
    stopX, stopY = Int.(entity.data["nodes"][1])

    width = Int(get(entity.data, "width", 32))
    height = Int(get(entity.data, "height", 32))
    direction = get(entity.data, "direction", "Up")

    renderSwapBlock(ctx, stopX, stopY, width, height, direction)
    Ahorn.drawArrow(ctx, startX + width / 2, startY + height / 2, stopX + width / 2, stopY + height / 2, Ahorn.colors.selection_selected_fc, headLength=6)
end

function Ahorn.renderAbs(ctx::Ahorn.Cairo.CairoContext, entity::MoveSwapBlock)
    startX, startY = Int(entity.data["x"]), Int(entity.data["y"])
    stopX, stopY = Int.(entity.data["nodes"][1])
    width = Int(get(entity.data, "width", 32))
    height = Int(get(entity.data, "height", 32))
    direction = get(entity.data, "direction", "Up")

    Ahorn.SwapBlock.renderTrail(ctx, min(startX, stopX), min(startY, stopY), abs(startX - stopX) + width, abs(startY - stopY) + height, "objects/swapblock/moon/target")
    renderSwapBlock(ctx, startX, startY, width, height, direction)
    renderMoveBlockButtons(ctx, entity, startX, startY, width, height)
end

function renderSwapBlock(ctx::Ahorn.Cairo.CairoContext, x::Number, y::Number, width::Number, height::Number, dir::String)
    Ahorn.SwapBlock.renderSwapBlock(ctx, x, y, width, height, "objects/swapblock/midBlockRed00", "objects/swapblock/blockRed")

    # I don't really trust the way Ahorn handles rotation in sprites
    arrowSprite = Ahorn.getSprite(arrow, "Gameplay")
    Ahorn.Cairo.save(ctx)
    Ahorn.Cairo.translate(ctx, x + div(width, 2), y + div(height, 2))
    Ahorn.Cairo.rotate(ctx, arrowRotations[dir])
    Ahorn.Cairo.translate(ctx, -div(arrowSprite.width, 2), -div(arrowSprite.height, 2))
    Ahorn.drawImage(ctx, arrowSprite, 0, 0)
    Ahorn.Cairo.restore(ctx)

    gemSprite = Ahorn.getSprite(gem, "Gameplay")
    gemX, gemY = gemOffsets[dir]
    Ahorn.drawImage(ctx, gemSprite, x + div(width - gemSprite.width, 2) + gemX, y + div(height - gemSprite.height, 2) + gemY)
end

function renderMoveBlockButtons(ctx, entity::MoveSwapBlock, x::Integer, y::Integer, width::Integer, height::Integer)
    tilesWidth = div(width, 8)
    tilesHeight = div(height, 8)

    canSteer = get(entity.data, "canSteer", false)
    direction = (get(entity.data, "direction", "Up"))

    for i in 2:tilesWidth-1
        if canSteer && (direction != "Up" && direction != "Down")
            Ahorn.drawImage(ctx, button, x + (i - 1) * 8, y - 2, 6, 0, 8, 6, tint=buttonColor)
        end
    end

    for i in 2:tilesHeight-1
        if canSteer && (direction == "Up" || direction == "Down")
            Ahorn.Cairo.save(ctx)

            Ahorn.rotate(ctx, -pi / 2)
            Ahorn.drawImage(ctx, button, i * 8 - height - 8 - y, x-2, 6, 0, 8, 6, tint=buttonColor)
            Ahorn.scale(ctx, 1, -1)
            Ahorn.drawImage(ctx, button, i * 8 - height - 8 - y, -2 - width - x, 6, 0, 8, 6, tint=buttonColor)

            Ahorn.Cairo.restore(ctx)
        end
    end

    if canSteer && (direction != "Up" && direction != "Down")
        Ahorn.Cairo.save(ctx)

        Ahorn.drawImage(ctx, button, x + 2, y - 2, 0, 0, 6, 6, tint=buttonColor)
        Ahorn.scale(ctx, -1, 1)
        Ahorn.drawImage(ctx, button, 2 - width - x, y - 2, 0, 0, 6, 6, tint=buttonColor)

        Ahorn.Cairo.restore(ctx)
    end

    if canSteer && (direction == "Up" || direction == "Down")
        Ahorn.Cairo.save(ctx)

        Ahorn.rotate(ctx, -pi / 2)
        Ahorn.drawImage(ctx, button, 2 - height - y, x - 2, 0, 0, 8, 6, tint=buttonColor)
        Ahorn.drawImage(ctx, button, -10 - y, x - 2, 14, 0, 8, 6, tint=buttonColor)
        Ahorn.scale(ctx, 1, -1)
        Ahorn.drawImage(ctx, button, 2-height-y, - 2 -width - x, 0, 0, 8, 6, tint=buttonColor)
        Ahorn.drawImage(ctx, button, -10-y, -2 -width - x, 14, 0, 8, 6, tint=buttonColor)

        Ahorn.Cairo.restore(ctx)
    end
end

end


text:
# Autogenerated wrapper script for SentencePiece_jll for x86_64-w64-mingw32-cxx11
export libsentencepiece, libsentencepiece_train, spm_decode, spm_encode, spm_export_vocab, spm_normalize, spm_train

JLLWrappers.@generate_wrapper_header("SentencePiece")
JLLWrappers.@declare_library_product(libsentencepiece, "libsentencepiece.dll")
JLLWrappers.@declare_library_product(libsentencepiece_train, "libsentencepiece_train.dll")
JLLWrappers.@declare_executable_product(spm_decode)
JLLWrappers.@declare_executable_product(spm_encode)
JLLWrappers.@declare_executable_product(spm_export_vocab)
JLLWrappers.@declare_executable_product(spm_normalize)
JLLWrappers.@declare_executable_product(spm_train)
function __init__()
    JLLWrappers.@generate_init_header()
    JLLWrappers.@init_library_product(
        libsentencepiece,
        "bin\\libsentencepiece.dll",
        RTLD_LAZY | RTLD_DEEPBIND,
    )

    JLLWrappers.@init_library_product(
        libsentencepiece_train,
        "bin\\libsentencepiece_train.dll",
        RTLD_LAZY | RTLD_DEEPBIND,
    )

    JLLWrappers.@init_executable_product(
        spm_decode,
        "bin\\spm_decode.exe",
    )

    JLLWrappers.@init_executable_product(
        spm_encode,
        "bin\\spm_encode.exe",
    )

    JLLWrappers.@init_executable_product(
        spm_export_vocab,
        "bin\\spm_export_vocab.exe",
    )

    JLLWrappers.@init_executable_product(
        spm_normalize,
        "bin\\spm_normalize.exe",
    )

    JLLWrappers.@init_executable_product(
        spm_train,
        "bin\\spm_train.exe",
    )

    JLLWrappers.@generate_init_footer()
end  # __init__()


text:
function test_field_root()
    K, a = FiniteField(31, 1, "a")
    @test root(K(22), 7) == 13
    @test root(K(25), 5) == 5
    @test root(K(23), 3) == 29
    @test root(K(1),  2) == 30
    @test root(K(1),  5) == 16
    @test root(K(1),  7) == 1

    K, a = FiniteField(5, 4, "a")
    @test root(3a^2 + a + 1, 13)^13 == 3a^2 + a + 1

    K, a = FiniteField(29, 2, "a")
    b = a^2 + 5a + 1
    @test                       root(b, 11) == 3a + 20
    @test_throws ErrorException root(b,  5)
    @test                       root(b,  3) == 14a + 18

    K, a = FiniteField(29, 5, "a")
    b = a^2 + 5a + 1
    @test                       root(b, 5) == 19a^4 + 2a^3 + 2a^2 + 16a + 3
    @test_throws ErrorException root(b, 7)
    @test_throws ErrorException root(b, 4)

    for p in [2, 3, 5, 7, 11]
        for n in [2, 5, 10]
            q = p^n
            K, a = FiniteField(p, n, "a")

            for r in factors(q-1)
                r == 1 && continue
                x = rand(K)
                y = x^r

                @test root(y,        r)^r      == y
                @test root(y^41,   41r)^(41r)  == y^41
                @test root(y^307, 307r)^(307r) == y^307
            end
        end
    end

    K, a = FiniteField(13, 1, "a")
    b = zero(K)
    @test_throws DomainError root(b, -2)
    @test_throws DomainError root(b, -1)
    @test_throws DomainError root(b,  0)
    @test                    root(b,  1) == b
    @test                    root(b,  2) == b

    @test root(K(3), -1) == root(K( 9), 1)
    @test root(K(3), -2) == root(K( 9), 2)
    @test root(K(4), -1) == root(K(10), 1)
    @test root(K(4), -2) == root(K(10), 2)

    @test_throws DomainError root(K(-2), 0)
    @test_throws DomainError root(K(-1), 0)
    @test                    root(K( 1), 0) == 1
    @test_throws DomainError root(K( 2), 0)
end

function test_field_roots()
    K, a = FiniteField(31, 1, "a")
    @test roots(K(22), 7) == [13]
    @test roots(K(25), 5) == [5,18,9,20,10]
    @test roots(K(23), 3) == [29,12,21]
    @test roots(K(1),  2) == [1,30]
    @test roots(K(1),  5) == [1,16,8,4,2]
    @test roots(K(1),  7) == [1]

    K, a = FiniteField(5, 4, "a")
    @test roots(3a^2 + a + 1, 13) == [4a^2+3a+3, 4a^3+3a^2+1, 4a^3+2a^2+a+2, 4a, 3a^3+2a^2+4, 2a+1, a^3+3a^2+a, 3a^3+3a+3, 3a^3+3a^2+4, 3a^3+2a^2+2, a^3+a^2, 3a^2+2a, 3a^3+2a^2+4a]

    K, a = FiniteField(29, 2, "a")
    b = a^2 + 5a + 1
    @test roots(b, 11) == [3a + 20]
    @test roots(b,  5) == []
    @test roots(b,  3) == [14a+18, 10a+13, 5a+27]

    K, a = FiniteField(29, 5, "a")
    b = a^2 + 5a + 1
    @test roots(b, 5) == [19a^4 + 2a^3 + 2a^2 + 16a + 3]
    @test roots(b, 7) == []
    @test roots(b, 4) == []

    K, a = FiniteField(13, 1, "a")
    b = zero(K)
    @test_throws DomainError roots(b, -2)
    @test_throws DomainError roots(b, -1)
    @test_throws DomainError roots(b,  0)
    @test                    roots(b,  1) == [b]
    @test                    roots(b,  2) == [b]

    @test roots(K(3), -1) == roots(K( 9), 1)
    @test roots(K(3), -2) == roots(K( 9), 2)
    @test roots(K(4), -1) == roots(K(10), 1)
    @test roots(K(4), -2) == roots(K(10), 2)

    @test_throws DomainError roots(K(-2), 0)
    @test_throws DomainError roots(K(-1), 0)
    @test                    roots(K( 1), 0) == [1,2,4,8,3,6,12,11,9,5,10,7]
    @test_throws DomainError roots(K( 2), 0)

    K, a = FiniteField(3, 2, "a")
    @test roots(K(1), 0) == [0a+1,a,a+1,2a+1,0a+2,2a,2a+2,a+2]
end

function test_field_all()
    print(rpad("Math.Algebra.Field...", 50, ' '))

    test_field_root()
    test_field_roots()

    println("PASS")
end


text:
@testset "@cenum" begin
	@eval @cenum OpaqueEnum
	@eval @cenum OpaqueEnum
	@test_throws ErrorException sizeof(OpaqueEnum)
	@test sizeof(Ptr{OpaqueEnum}) == sizeof(Ptr{Cvoid})

	@eval @cenum SimpleEnum
	@eval @cenum SimpleEnum {
		SE1,
		SE2,
		SE3,
	}
	@test sizeof(SimpleEnum) == 4
	@test SE1 == 0
	@test SE2 == 1
	@test SE3 == 2

	@eval @cenum LessSimpleEnum {
		LSE1,
		LSE2,
		LSE3 = -1,
	}
	@test sizeof(LessSimpleEnum) == 4
	@test LSE1 == 0
	@test LSE2 == 1
	@test LSE3 == -1

	@eval @cenum ComplexEnum {
		CE1 = 1,
		CE2 = CE1,
		CE3 = 0,
		CE4,
	}
	@test sizeof(ComplexEnum) == 4
	@test CE1 == 1
	@test CE2 == 1
	@test CE3 == 0
	@test CE4 == 1

	@eval @cenum TrickyEnum {
		TE1 = -1,
		TE2 = 0xffffffff,
	}
	@test sizeof(TrickyEnum) == 8
	@test TE1 == -1
	@test TE2 == 0xffffffff

	@eval @cenum PackedSimpleEnum {
		PSE1,
		PSE2,
		PSE3,
	} __packed__
	@test sizeof(PackedSimpleEnum) == 1
	@test PSE1 == 0
	@test PSE2 == 1
	@test PSE3 == 2

	@eval @cenum PackedLessSimpleEnum {
		PLSE1,
		PLSE2,
		PLSE3 = -1,
	} __packed__
	@test sizeof(PackedLessSimpleEnum) == 1
	@test PLSE1 == 0
	@test PLSE2 == 1
	@test PLSE3 == -1

	@eval @cenum PackedComplexEnum {
		PCE1 = 1,
		PCE2 = PCE1,
		PCE3 = 0,
		PCE4,
	} __packed__
	@test sizeof(PackedComplexEnum) == 1
	@test PCE1 == 1
	@test PCE2 == 1
	@test PCE3 == 0
	@test PCE4 == 1

	@eval @cenum PackedTrickyEnum {
		PTE1 = -1,
		PTE2 = 0xffffffff,
	} __packed__
	@test sizeof(PackedTrickyEnum) == 8
	@test PTE1 == -1
	@test PTE2 == 0xffffffff
end