text:
# This file is mostly generated by `scripts/generate_precompile.jl`

const __bodyfunction__ = Dict{Method,Any}()

# Find keyword "body functions" (the function that contains the body
# as written by the developer, called after all missing keyword-arguments
# have been assigned values), in a manner that doesn't depend on
# gensymmed names.
# `mnokw` is the method that gets called when you invoke it without
# supplying any keywords.
function __lookup_kwbody__(mnokw::Method)
    function getsym(arg)
        isa(arg, Symbol) && return arg
        @assert isa(arg, GlobalRef)
        return arg.name
    end

    f = get(__bodyfunction__, mnokw, nothing)
    if f === nothing
        fmod = mnokw.module
        # The lowered code for `mnokw` should look like
        #   %1 = mkw(kwvalues..., #self#, args...)
        #        return %1
        # where `mkw` is the name of the "active" keyword body-function.
        ast = Base.uncompressed_ast(mnokw)
        if isa(ast, Core.CodeInfo) && length(ast.code) >= 2
            callexpr = ast.code[end-1]
            if isa(callexpr, Expr) && callexpr.head == :call
                fsym = callexpr.args[1]
                if isa(fsym, Symbol)
                    f = getfield(fmod, fsym)
                elseif isa(fsym, GlobalRef)
                    if fsym.mod === Core && fsym.name === :_apply
                        f = getfield(mnokw.module, getsym(callexpr.args[2]))
                    elseif fsym.mod === Core && fsym.name === :_apply_iterate
                        f = getfield(mnokw.module, getsym(callexpr.args[3]))
                    else
                        f = getfield(fsym.mod, fsym.name)
                    end
                else
                    f = missing
                end
            else
                f = missing
            end
        else
            f = missing
        end
        __bodyfunction__[mnokw] = f
    end
    return f
end

function _precompile_()
    ccall(:jl_generating_output, Cint, ()) == 1 || return nothing
    try; @assert(Base.precompile(Tuple{Core.kwftype(typeof(Type)),NamedTuple{(:rl, :ll, :url, :detail), NTuple{4, String}},Type{CompletionSuggestion},String,String,String,String})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{Core.kwftype(typeof(_collecttoplevelitems_static)),NamedTuple{(:inmod,), Tuple{Bool}},typeof(_collecttoplevelitems_static),Nothing,String})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{Core.kwftype(typeof(modulefiles)),NamedTuple{(:inmod,), Tuple{Bool}},typeof(modulefiles),String,String})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{Core.kwftype(typeof(toplevelitems)),NamedTuple{(:mod, :inmod), Tuple{String, Bool}},typeof(toplevelitems),String})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{Type{EvalError},StackOverflowError,Vector{StackFrame}})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{Type{GotoItem},String,ToplevelCall})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{Type{GotoItem},String,ToplevelMacroCall})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{Type{GotoItem},String,ToplevelModuleUsage})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(allprojects)})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(appendline),String,Int64})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(clearsymbols)})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(completion),Module,FuzzyCompletions.DictCompletion,String})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(completion),Module,FuzzyCompletions.FieldCompletion,String})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(completion),Module,FuzzyCompletions.KeywordCompletion,String})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(completion),Module,FuzzyCompletions.ModuleCompletion,String})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(completion),Module,FuzzyCompletions.PathCompletion,String})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(completion),Module,FuzzyCompletions.PropertyCompletion,String})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(completion),Module,REPL.REPLCompletions.DictCompletion,String})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(completion),Module,REPL.REPLCompletions.FieldCompletion,String})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(completion),Module,REPL.REPLCompletions.KeywordCompletion,String})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(completion),Module,REPL.REPLCompletions.ModuleCompletion,String})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(completion),Module,REPL.REPLCompletions.PathCompletion,String})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(completion),Module,REPL.REPLCompletions.PropertyCompletion,String})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(completiondetail!),Dict{String, Any}})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(description),MD})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(displayandrender),Module})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(displayandrender),Symbol})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(docs),String})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(eval),String,Int64,String,String})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(evalall),String,String,String})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(evalshow),String,Int64,String,String})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(evalsimple),String})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(finddevpackages)})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(fullREPLpath),String})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(fullpath),String})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(fuzzycompletionadapter),String})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(getdocs),Module,String,Module})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(getdocs),Module,String})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(getfield′),Any,String,Undefined})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(getfield′),Any,String})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(getfield′),Any,Symbol,Undefined})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(getfield′),Any,Symbol})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(getfield′),Module,String})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(getfield′),Module,Symbol,Function})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(getfield′),Module,Symbol})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(globaldatatip),String,String})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(globalgotoitems),String,Module,String,String})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(globalgotoitems),String,String,String,String})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(gotosymbol),String})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(handlemsg),Dict{String, Any},String})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(handlemsg),Dict{String, Any}})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(isactive),IOBuffer})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(iskeyword),String})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(ismacro),Any})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(ismacro),String})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(isundefined),Base.RefValue{Bool}})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(isundefined),Base.RefValue{Tuple{String, Int64}}})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(isundefined),Dict{Method, Any}})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(isundefined),Dict{String, Any}})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(isundefined),Dict{String, Dict{String, Vector{GotoItem}}}})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(isundefined),Dict{String, String}})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(isundefined),Dict{String, Vector{String}}})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(isundefined),Function})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(isundefined),HTML{String}})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(isundefined),Int64})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(isundefined),Module})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(isundefined),NTuple{19, Symbol}})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(isundefined),OrderedDict{String, Union{NamedTuple{(:rt, :desc), Tuple{String, String}}, NamedTuple{(:f, :m, :tt), Tuple{Any, Method, Type}}}}})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(isundefined),Regex})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(isundefined),String})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(isundefined),Type})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(isundefined),Undefined})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(isundefined),Vector{Any}})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(isundefined),Vector{String}})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(localgotoitem),String,Nothing,Int64,Int64,Int64,String})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(md_hlines),MD})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(moduledefinition),Module})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(modulefiles),Module})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(modulefiles),String,String})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(msg),String,Int64,Vararg{Any}})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(pkgpath),String})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(pluralize),Vector{Int64},String,String})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(processdoc!),MD,String,Vector{Any}})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(processdocs),Vector{Tuple{Float64, DocSeeker.DocObj}}})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(processval!),Any,String,Vector{Any}})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(processval!),Function,String,Vector{Any}})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(project_info)})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(realpath′),String})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(regeneratesymbols)})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(render),Inline,EvalError{StackOverflowError}})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(render),Inline,Function})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(render),Inline,Model})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(render),Inline,Module})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(render),Inline,Node{:div}})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(render),Inline,Node{:span}})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(render),Inline,Symbol})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(render),Inline,Type})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(renderMDinline),Vector{Any}})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(render′),Inline,Function})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(render′),Inline,Int64})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(render′),Inline,Module})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(render′),Inline,Nothing})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(render′),Inline,String})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(render′),Inline,Type})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(render′),Inline,Undefined})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(replcompletionadapter),String})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(searchcodeblocks),MD})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(searchdocs′),String,Bool,String})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(searchdocs′),String})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(str_value),EXPR})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(strlimit),String,Int64,String})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(strlimit),String,Int64})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(toplevelitems),String})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(trim),Vector{Float64},Int64})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(updatesymbols),String,Nothing,String})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(updatesymbols),String,String,String})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(use_compiled_modules)})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(view),Dict{Any, Any}})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(view),Dict{Symbol, Any}})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(view),Method})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(view),Node{:a}})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(view),Node{:blockquote}})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(view),Node{:em}})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(view),Node{:h1}})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(view),Node{:h2}})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(view),Node{:hr}})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(view),Node{:img}})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(view),Node{:li}})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(view),Node{:pre}})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(view),Node{:p}})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(view),Node{:strong}})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(view),Node{:ul}})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(view),String})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(view),SubString{String}})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(withpath),Function,String})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(workspace),String})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(wsicon),Module,Symbol,Any})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(wsicon),Module,Symbol,Array{Bool, 0}})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(wsicon),Module,Symbol,Base.EnvDict})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(wsicon),Module,Symbol,Complex{Bool}})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(wsicon),Module,Symbol,Dict{Method, Any}})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(wsicon),Module,Symbol,Dict{String, Any}})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(wsicon),Module,Symbol,Dict{String, Dict{String, Vector{GotoItem}}}})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(wsicon),Module,Symbol,Dict{String, String}})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(wsicon),Module,Symbol,Dict{String, Vector{String}}})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(wsicon),Module,Symbol,ErrorException})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(wsicon),Module,Symbol,Float16})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(wsicon),Module,Symbol,Float32})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(wsicon),Module,Symbol,Float64})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(wsicon),Module,Symbol,Function})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(wsicon),Module,Symbol,Int64})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(wsicon),Module,Symbol,Irrational{:π}})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(wsicon),Module,Symbol,Irrational{:ℯ}})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(wsicon),Module,Symbol,Module})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(wsicon),Module,Symbol,OrderedDict{String, Union{NamedTuple{(:rt, :desc), Tuple{String, String}}, NamedTuple{(:f, :m, :tt), Tuple{Any, Method, Type}}}}})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(wsicon),Module,Symbol,Regex})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(wsicon),Module,Symbol,String})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(wsicon),Module,Symbol,Type})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(wsicon),Module,Symbol,Undefined})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(wsicon),Module,Symbol,Vector{Any}})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(wsicon),Module,Symbol,Vector{String}})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(wstype),Module,Symbol,Any})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(wstype),Module,Symbol,ErrorException})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(wstype),Module,Symbol,Function})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(wstype),Module,Symbol,Module})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(wstype),Module,Symbol,Type})); catch err; @debug err; end
    try; @assert(Base.precompile(Tuple{typeof(wstype),Module,Symbol,Undefined})); catch err; @debug err; end
    try; isdefined(Atom, Symbol("#113#114")) && Base.precompile(Tuple{getfield(Atom, Symbol("#113#114")),HorizontalRule}); catch err; @debug err; end
    try; isdefined(Atom, Symbol("#113#114")) && Base.precompile(Tuple{getfield(Atom, Symbol("#113#114")),MD}); catch err; @debug err; end
    try; isdefined(Atom, Symbol("#113#114")) && Base.precompile(Tuple{getfield(Atom, Symbol("#113#114")),Markdown.Admonition}); catch err; @debug err; end
    try; isdefined(Atom, Symbol("#113#114")) && Base.precompile(Tuple{getfield(Atom, Symbol("#113#114")),Markdown.BlockQuote}); catch err; @debug err; end
    try; isdefined(Atom, Symbol("#113#114")) && Base.precompile(Tuple{getfield(Atom, Symbol("#113#114")),Markdown.Code}); catch err; @debug err; end
    try; isdefined(Atom, Symbol("#113#114")) && Base.precompile(Tuple{getfield(Atom, Symbol("#113#114")),Markdown.Footnote}); catch err; @debug err; end
    try; isdefined(Atom, Symbol("#113#114")) && Base.precompile(Tuple{getfield(Atom, Symbol("#113#114")),Markdown.Header{1}}); catch err; @debug err; end
    try; isdefined(Atom, Symbol("#113#114")) && Base.precompile(Tuple{getfield(Atom, Symbol("#113#114")),Markdown.Header{2}}); catch err; @debug err; end
    try; isdefined(Atom, Symbol("#113#114")) && Base.precompile(Tuple{getfield(Atom, Symbol("#113#114")),Markdown.List}); catch err; @debug err; end
    try; isdefined(Atom, Symbol("#113#114")) && Base.precompile(Tuple{getfield(Atom, Symbol("#113#114")),Markdown.Paragraph}); catch err; @debug err; end
    try; isdefined(Atom, Symbol("#115#116")) && Base.precompile(Tuple{getfield(Atom, Symbol("#115#116")),Vector{Any}}); catch err; @debug err; end
    try; isdefined(Atom, Symbol("#121#122")) && Base.precompile(Tuple{getfield(Atom, Symbol("#121#122")),Markdown.Bold}); catch err; @debug err; end
    try; isdefined(Atom, Symbol("#121#122")) && Base.precompile(Tuple{getfield(Atom, Symbol("#121#122")),Markdown.Code}); catch err; @debug err; end
    try; isdefined(Atom, Symbol("#121#122")) && Base.precompile(Tuple{getfield(Atom, Symbol("#121#122")),Markdown.Footnote}); catch err; @debug err; end
    try; isdefined(Atom, Symbol("#121#122")) && Base.precompile(Tuple{getfield(Atom, Symbol("#121#122")),Markdown.Image}); catch err; @debug err; end
    try; isdefined(Atom, Symbol("#121#122")) && Base.precompile(Tuple{getfield(Atom, Symbol("#121#122")),Markdown.Italic}); catch err; @debug err; end
    try; isdefined(Atom, Symbol("#121#122")) && Base.precompile(Tuple{getfield(Atom, Symbol("#121#122")),Markdown.LaTeX}); catch err; @debug err; end
    try; isdefined(Atom, Symbol("#121#122")) && Base.precompile(Tuple{getfield(Atom, Symbol("#121#122")),Markdown.Link}); catch err; @debug err; end
    try; isdefined(Atom, Symbol("#121#122")) && Base.precompile(Tuple{getfield(Atom, Symbol("#121#122")),String}); catch err; @debug err; end
    try; isdefined(Atom, Symbol("#123#124")) && Base.precompile(Tuple{getfield(Atom, Symbol("#123#124")),Model}); catch err; @debug err; end
    try; isdefined(Atom, Symbol("#131#132")) && Base.precompile(Tuple{getfield(Atom, Symbol("#131#132")),Text{String}}); catch err; @debug err; end
    try; isdefined(Atom, Symbol("#200#201")) && Base.precompile(Tuple{getfield(Atom, Symbol("#200#201"))}); catch err; @debug err; end
    try; isdefined(Atom, Symbol("#207#212")) && Base.precompile(Tuple{getfield(Atom, Symbol("#207#212"))}); catch err; @debug err; end
    try; isdefined(Atom, Symbol("#208#213")) && Base.precompile(Tuple{getfield(Atom, Symbol("#208#213"))}); catch err; @debug err; end
    try; isdefined(Atom, Symbol("#220#225")) && Base.precompile(Tuple{getfield(Atom, Symbol("#220#225"))}); catch err; @debug err; end
    try; isdefined(Atom, Symbol("#234#239")) && Base.precompile(Tuple{getfield(Atom, Symbol("#234#239"))}); catch err; @debug err; end
    try; isdefined(Atom, Symbol("#242#243")) && Base.precompile(Tuple{getfield(Atom, Symbol("#242#243")),MD}); catch err; @debug err; end
    try; isdefined(Atom, Symbol("#242#243")) && Base.precompile(Tuple{getfield(Atom, Symbol("#242#243")),Method}); catch err; @debug err; end
    try; isdefined(Atom, Symbol("#39#40")) && Base.precompile(Tuple{getfield(Atom, Symbol("#39#40"))}); catch err; @debug err; end
    try; isdefined(Atom, Symbol("#43#44")) && Base.precompile(Tuple{getfield(Atom, Symbol("#43#44")),String}); catch err; @debug err; end
    try; isdefined(Atom, Symbol("#45#47")) && Base.precompile(Tuple{getfield(Atom, Symbol("#45#47")),String}); catch err; @debug err; end
    try; isdefined(Atom, Symbol("#61#62")) && Base.precompile(Tuple{getfield(Atom, Symbol("#61#62"))}); catch err; @debug err; end
    try; isdefined(Atom, Symbol("#r#109")) && Base.precompile(Tuple{getfield(Atom, Symbol("#r#109")),Link}); catch err; @debug err; end
    try; @assert(let fbody = try __lookup_kwbody__(which(fixpath, (String,))) catch missing end
        if !ismissing(fbody)
            precompile(fbody, (String,String,typeof(fixpath),String,))
        end
    end); catch err; @debug err; end
end


text:
@testset "1052.grumpy-bookstore-owner.jl" begin
    @test max_satisfied([1, 0, 1, 2, 1, 1, 7, 5], [0, 1, 0, 1, 0, 1, 0, 1], 3) == 16
    @test max_satisfied([5, 8], [0, 1], 1) == 13
    @test max_satisfied([3], [1], 1) == 3
    @test max_satisfied([1], [0], 1) == 1
end

ext: jl


text:
# ---
# title: 400. Nth Digit
# id: problem400
# author: Indigo
# date: 2021-06-20
# difficulty: Medium
# categories: Math
# link: <https://leetcode.com/problems/nth-digit/description/>
# hidden: true
# ---
#
# Find the _n_ th digit of the infinite integer sequence 1, 2, 3, 4, 5, 6, 7, 8,
# 9, 10, 11, ...
#
# **Note:**
# _n_ is positive and will fit within the range of a 32-bit signed integer ( _n_
# < 231).
#
# **Example 1:**
#
#
#
#     Input:
#     3
#
#     Output:
#     3
#
#
# **Example 2:**
#
#
#
#     Input:
#     11
#
#     Output:
#     0
#
#     Explanation:
#     The 11th digit of the sequence 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ... is a 0, which is part of the number 10.
#
#
#
## @lc code=start
using LeetCode

function find_nth_digit(n::Int)
    ant = [0, 10, 190, 2890, 38890, 488890, 5888890, 68888890, 788888890]
    num_begin = [0, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000]
    idx = searchsortedlast(ant, n)
    num = (n - ant[idx]) ÷ idx + num_begin[idx]
    posi = (n - ant[idx]) % idx
    return num % (10^(idx - posi)) ÷ 10^(idx - posi - 1)
end
## @lc code=end


text:
# ----------------------------------------------------------------------------------- #
# Copyright (c) 2019 Varnerlab
# Robert Frederick School of Chemical and Biomolecular Engineering
# Cornell University, Ithaca NY 14850
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
# ----------------------------------------------------------------------------------- #

# ----------------------------------------------------------------------------------- #
# estimate_steady_state: estimates the steady-state vector for the dynamic system
#
# Type: GRN-JULIA
# Version: 1.0
#
# Input arguments:
# data_dictionary  - Data dictionary instance (holds model parameters)
#
# Return arguments:
# XSS - steady state vector
# ----------------------------------------------------------------------------------- #
function estimate_steady_state(data_dictionary)

    # Get the initial conditions -
    initial_condition_array = data_dictionary["initial_condition_array"];

    # calculate the steady-state soln -
    steady_state_prob = SteadyStateProblem(Balances, initial_condition_array, data_dictionary)
    steady_state_soln  = solve(steady_state_prob, DynamicSS(AutoTsit5(Rosenbrock23(autodiff=false));abstol=1e-8,reltol=1e-6,tspan=Inf))

    # return -
    return abs.(steady_state_soln.u)
end

# ----------------------------------------------------------------------------------- #
# AdjBalances: Evaluates adjoint model equations given time, state, parameter_index,
# and the data_dictionary.
#
# Type: GRN-JULIA
# Version: 1.0
#
# Input arguments:
# t  - current time
# dx - derivative vector
# x  - state array
# data_dictionary  - Data dictionary instance (holds model parameters)
#
# Return arguments:
# N/A - derivative array at current time step is filled in the function
# ----------------------------------------------------------------------------------- #
function AdjBalances(dx,x,data_dictionary,t)

    # look up the number of states -
    number_of_states = data_dictionary["number_of_states"]

    # grab the parameter index -
    parameter_index = data_dictionary["parameter_index"]

    # partition that state -
    state_array = x[1:number_of_states]
    sensitivity_array = x[(number_of_states+1):end]

    # call the balances -
    dxdt_array = calculate_balances(t,state_array,data_dictionary)

    # Calculate the sensitivity states -
    local_data_dictionary = deepcopy(data_dictionary)
    JM = calculate_jacobian(t,state_array,local_data_dictionary)
    BM = calculate_bmatrix(t,state_array,local_data_dictionary)

    # calulate the sensitivity state -
    dsdt_array = JM*sensitivity_array+BM[:,parameter_index]
    r_array = [dxdt_array ; dsdt_array]

    # package -
    number_of_total_states = length(r_array)
    for index = 1:number_of_total_states
        dx[index] = r_array[index]
    end
end

# ----------------------------------------------------------------------------------- #
# calculate_balances: Evaluates model equations given time, state and the data_dictionary.
# Type: GRN-JULIA
# Version: 1.0
#
# Input arguments:
# t  - current time
# x  - state array
# data_dictionary  - Data dictionary instance (holds model parameters)
#
# Return arguments:
# dxdt - derivative array at current time step
# ----------------------------------------------------------------------------------- #
function calculate_balances(t,x,data_dictionary)

    # get the structure arrays from the data_dictionary -
    AM = data_dictionary["dilution_degradation_matrix"]
    SM = data_dictionary["stoichiometric_matrix"]

    # what is my system size?
    number_of_states = data_dictionary["number_of_states"]

    # calculate the kinetics array -
    kinetics_array = calculate_txtl_kinetics_array(t,x,data_dictionary)

    # calculate the control array -
    transcription_control_array = calculate_transcription_control_array(t,x,data_dictionary)
    translation_control_array = calculate_translation_control_array(t,x,data_dictionary)

    # control_array is the transcription and translation control arrays -
    control_array = [transcription_control_array ; translation_control_array]

    # modfiy the kinetics -
    rV = kinetics_array.*control_array

    # remove last n states -
    x_main = x[1:12]

    # compute the dxdt vector -
    dxdt = AM*x_main+SM*rV

    # extra states -
    dxdt[13] = -(log(2)/4.0)*x[13]

    # return -
    return dxdt
end

# ----------------------------------------------------------------------------------- #
# Balances: Evaluates model equations given time, state and the data_dictionary.
# Type: GRN-JULIA
# Version: 1.0
#
# Input arguments:
# dx - derivative array
# t  - current time
# x  - state array
# data_dictionary  - Data dictionary instance (holds model parameters)
#
# Return arguments:
# N/A - dx is filled in the function and returned to the caller
# ----------------------------------------------------------------------------------- #
function Balances(dx,x,data_dictionary,t)

    # get the structure arrays from the data_dictionary -
    AM = data_dictionary["dilution_degradation_matrix"]
    SM = data_dictionary["stoichiometric_matrix"]
    half_life_translation = data_dictionary["half_life_translation_capacity"]

    # what is my system size?
    number_of_states = data_dictionary["number_of_states"]

    # calculate the kinetics array -
    kinetics_array = calculate_txtl_kinetics_array(t,x,data_dictionary)

    # calculate the control array -
    transcription_control_array = calculate_transcription_control_array(t,x,data_dictionary)
    translation_control_array = calculate_translation_control_array(t,x,data_dictionary)

    # control_array is the transcription and translation control arrays -
    control_array = [transcription_control_array ; translation_control_array]

    # modfiy the kinetics -
    rV = kinetics_array.*control_array

    # remove last n states -
    x_main = x[1:12]

    # compute the dxdt vector -
    dxdt = AM*x_main+SM*rV

    # add extra term for ssrA tag -
    #N = 1.26
    #dxdt[9] = dxdt[9] - (log(2)/12.0)*x[9]^N
    #dxdt[10] = dxdt[10] - (log(2)/8.0)*x[10]^N

    # package -
    for index = 1:number_of_states
        dx[index] = dxdt[index]
    end

    # extra states -
    # 8.0 w/o extra term
    # 6.0 => T5
    #dx[13] = -(log(2)/8.0)*x[13]
    dx[13] = -(log(2)/half_life_translation)*x[13]
end

max_stars_repo_name: varnerlab/Biophysical-TXTL-Model-Code

max_issues_repo_name: varnerlab/Biophysical-TXTL-Model-Code

max_forks_repo_name: varnerlab/Biophysical-TXTL-Model-Code


text:
# fld-write.jl

using MIRT: fld_write, fld_read
import MIRT: fld_write_data_fix

#using MIRT: ir_test_dir, ir_test_dir!
using Test: @test, @testset, @test_throws, @inferred

#=
"""
`dir = ir_test_dir!(path)`

set default test directory
"""
function ir_test_dir!(path::String)
	ENV["MIRT_TEST_DIR"] = path
end

"""
`dir = ir_test_dir`

return default test directory `ENV["MIRT_TEST_DIR"]`; default is `/tmp`
"""
function ir_test_dir()
#	get(ENV, "MIRT_TEST_DIR", "/tmp")
	try
		return ENV["MIRT_TEST_DIR"]
	catch
		return "/tmp"
	end
end
=#

"""
`fld_write_test1(file, data, ...)`
"""
function fld_write_test1(file, data ; raw::Bool=false, chat::Bool=false, kwarg...)
	@inferred fld_write(file, data ; raw=raw, kwarg...)
	tmp = fld_read(file, chat=chat)
	tmp != data && throw("test failed for file = $file")

	rm(file)
	if raw
		tmp = file[1:(end-4)] * ".raw"
		rm(tmp)
	end
	true
end

# test writing and reading AVS `.fld` files of all key types

dir = mktempdir()
file = joinpath(dir, "fld-write-test.fld")
chat = isinteractive()

@testset "write std" begin
	for dtype in (UInt8, Int16, Int32, Float32, Float64)
		for endian in (:le, :be)
			for raw in (false, true)
				chat && @info "dtype=$dtype endian=$endian raw=$raw"
				data = convert.(dtype, [5:8; 1:4])
				@test fld_write_test1(file, data, endian=endian, raw=raw,
					head = ["dtype=$dtype endian=$endian raw=$raw",],
					check=true, chat=false)
			end
		end
	end
end

@testset "write odd" begin
	for T in (BigFloat, Float16, BigInt, Int64, Bool)
		data = T.([1 0 1])
		@test fld_write_test1(file, data ; check=true, chat=false)
	end
end

@testset "fld convert" begin
#=
	pairs = (
		(BigFloat, Float64),
		(Float16, Float32),
		(BigInt, Int32),
		(Int64, Int32),
		(Bool, UInt8),
	)
	for (in, out) in pairs
		data = in.([1 0 1])
		@test eltype(fld_write_data_fix(data)) == out
	end
=#
	@test_throws ArgumentError fld_write_data_fix(Rational.([1 0 1]))
end

# for future testing of reading "multi" external files
@testset "write multi" begin
#	file = "../tmp2.fld"
#	file = "tmp.fld"
	data = rand(Float32, 7, 9, 2)
	file1 = "$(basename(file)).part1"
	file2 = "$(basename(file)).part2"
	head = [
		"# AVS field file"
		"ndim=3"
		"dim1=7"
		"dim2=9"
		"dim3=2"
		"nspace=3"
		"veclen=1"
		"data=float"
		"field=uniform"
		"variable 1 file=2 filetype=multi skip=0"
		file1
		file2
	]

	open(file, "w") do fid
		for line in head
			println(fid, line)
		end
	end

	file1 = joinpath(dirname(file), file1)
	file2 = joinpath(dirname(file), file2)
	write(file1, data[:,:,1])
	write(file2, data[:,:,2])

#	run(`cat $file`)
#	run(`ls -l $file1`)
#	run(`op range $file`)

	@test_throws String tmp = fld_read(file) # todo some day...
end


text:
# Test resample

using Turing
using Test

num_samples = Int(1e6)

resSystematic = Turing.resampleSystematic( [0.3, 0.4, 0.3], num_samples )
resStratified = Turing.resampleStratified( [0.3, 0.4, 0.3], num_samples )
resMultinomial= Turing.resampleMultinomial( [0.3, 0.4, 0.3], num_samples )
resResidual   = Turing.resampleResidual( [0.3, 0.4, 0.3], num_samples )
Turing.resample( [0.3, 0.4, 0.3])
resSystematic2=Turing.resample( [0.3, 0.4, 0.3], num_samples )

@test sum(resSystematic .== 2) ≈ (num_samples * 0.4) atol=1e-3*num_samples
@test sum(resSystematic2 .== 2) ≈ (num_samples * 0.4) atol=1e-3*num_samples
@test sum(resStratified .== 2) ≈ (num_samples * 0.4) atol=1e-3*num_samples
@test sum(resMultinomial .== 2) ≈ (num_samples * 0.4) atol=1e-2*num_samples
@test sum(resResidual .== 2) ≈ (num_samples * 0.4) atol=1e-2*num_samples


text:
const ESC = "\u001B" # escape code

print("$ESC[?1049h$ESC[H")
print("\n\nNow using an alternate screen buffer. Returning after count of: ")
foreach(x -> (sleep(1); print("  $x")), 5:-1:0)
print("$ESC[?1049l\n\n\n")

max_stars_repo_name: ethansaxenian/RosettaDecode

max_issues_repo_name: ethansaxenian/RosettaDecode

max_forks_repo_name: ethansaxenian/RosettaDecode


text:
using GoogleSheets

# Example based upon: # https://developers.google.com/sheets/api/quickstart/python

client = sheets_client(AUTH_SCOPE_READWRITE)

# The ID and range of a sample spreadsheet.
SAMPLE_SPREADSHEET_ID = "1pG4OyAdePAelCT2fSBTVJ9lVYo6M-ApuTyeEPz49DOM"
SAMPLE_RANGE_NAME = "Sheet1"

sheet = Spreadsheet(SAMPLE_SPREADSHEET_ID)
range = CellRange(sheet, SAMPLE_RANGE_NAME)
ranges = CellRanges(sheet, ["Sheet1!A1:B9", "Sheet1!B1:B9"])

println()
show(client, sheet)

values = ["0" "1" "2"; "a" "=A1+B1" 33]
println(values)

result = update!(client, range, values)

################################################################################

result = get(client, range)
println("RESULT: $(result)")

if isnothing(result.values)
    println("No data found.")
else
    for row in eachrow(result.values)
        println("ROW: $row")
    end
end

################################################################################

result = get(client, ranges)
println("RESULT: $(result)")

for r in result
    if isnothing(r.values)
        println("No data found.")
    else
        for row in eachrow(r.values)
            println("ROW: $(r.range) $row")
        end
    end
end

################################################################################

try
    delete_sheet!(client, sheet, "test sheet")
    println("Deleted sheet")
catch e
    println("No sheet to delete")
end

add_sheet!(client, sheet, "test sheet")

println()
show(client, sheet, "test sheet")

values = fill(11, 5, 5)
println("VALUES $(typeof(values)) $values")
result = update!(client, CellRange(sheet, "test sheet"), values)

freeze!(client, Sheet(client, sheet, "test sheet"), 2, 3)
append!(client, Sheet(client, sheet, "test sheet"), 1000, 3)

insert_rows!(client, CellIndexRange1D(Sheet(client, sheet, "test sheet"), 2, 3))
insert_cols!(client, CellIndexRange1D(Sheet(client, sheet, "test sheet"), 2, 3))

delete_rows!(client, CellIndexRange1D(Sheet(client, sheet, "test sheet"), 2, 3))
delete_cols!(client, CellIndexRange1D(Sheet(client, sheet, "test sheet"), 2, 3))

clear!(client, CellRange(sheet, "test sheet!B2:C3"))


text:
"""
    struct GridPortion{Dc,Dp,G} <: Grid{Dc,Dp}
      parent_grid::G
      cell_to_parent_cell::Vector{Int32}
      node_to_parent_node::Vector{Int32}
    end
"""
struct GridPortion{Dc,Dp,G} <: Grid{Dc,Dp}
  parent_grid::G
  cell_to_parent_cell::Vector{Int32}
  node_to_parent_node::Vector{Int32}
  cell_to_nodes::Table{Int32,Vector{Int32},Vector{Int32}}
  @doc """
      GridPortion(parent_grid::Grid{Dc,Dp},cell_to_parent_cell::Vector{Int32}) where {Dc,Dp}
  """
  function GridPortion(parent_grid::Grid,cell_to_parent_cell::AbstractVector{<:Integer})

    Dc = num_cell_dims(parent_grid)
    Dp = num_point_dims(parent_grid)

    parent_cell_to_parent_nodes = get_cell_node_ids(parent_grid)
    nparent_nodes = num_nodes(parent_grid)
    parent_node_to_coords = get_node_coordinates(parent_grid)

    node_to_parent_node, parent_node_to_node = _find_active_nodes(
      parent_cell_to_parent_nodes,cell_to_parent_cell,nparent_nodes)

    cell_to_nodes = _renumber_cell_nodes(
      parent_cell_to_parent_nodes,parent_node_to_node,cell_to_parent_cell)

    new{Dc,Dp,typeof(parent_grid)}(parent_grid,cell_to_parent_cell,node_to_parent_node,cell_to_nodes)
  end
end

function GridPortion(parent_grid::Grid,parent_cell_to_mask::AbstractArray{Bool})
  cell_to_parent_cell = findall(collect1d(parent_cell_to_mask))
  GridPortion(parent_grid,cell_to_parent_cell)
end

function GridPortion(parent_grid::Grid,parent_cell_to_mask::AbstractVector{Bool})
  cell_to_parent_cell = findall(parent_cell_to_mask)
  GridPortion(parent_grid,cell_to_parent_cell)
end

function OrientationStyle(::Type{GridPortion{Dc,Dp,G}}) where {Dc,Dp,G}
  OrientationStyle(G)
end

function RegularityStyle(::Type{GridPortion{Dc,Dp,G}}) where {Dc,Dp,G}
  RegularityStyle(G)
end

function get_node_coordinates(grid::GridPortion)
  parent_node_to_coords = get_node_coordinates(grid.parent_grid)
  lazy_map(Reindex(parent_node_to_coords),grid.node_to_parent_node)
end

function get_cell_node_ids(grid::GridPortion)
  grid.cell_to_nodes
end

function get_reffes(grid::GridPortion)
  get_reffes(grid.parent_grid)
end

function get_cell_type(grid::GridPortion)
  lazy_map(Reindex(get_cell_type(grid.parent_grid)),grid.cell_to_parent_cell)
end

# Helpers

function _find_active_nodes(oldcell_to_oldnodes,cell_to_oldcell,noldnodes)
  oldnode_is_active = fill(false,noldnodes)
  cache = array_cache(oldcell_to_oldnodes)
  for oldcell in cell_to_oldcell
    oldnodes = getindex!(cache,oldcell_to_oldnodes,oldcell)
    for oldnode in oldnodes
      oldnode_is_active[oldnode] = true
    end
  end
  node_to_oldnode = findall(oldnode_is_active)
  oldnode_to_node = fill(UNSET,noldnodes)
  oldnode_to_node[node_to_oldnode] = 1:length(node_to_oldnode)
  (node_to_oldnode, oldnode_to_node)
end

function _renumber_cell_nodes(oldcell_to_oldnodes,oldnode_to_node,cell_to_oldcell)
  ncells = length(cell_to_oldcell)
  cell_to_nodes_ptrs = zeros(Int32,ncells+1)
  cache = array_cache(oldcell_to_oldnodes)
  for (cell,oldcell) in enumerate(cell_to_oldcell)
    oldnodes = getindex!(cache,oldcell_to_oldnodes,oldcell)
    cell_to_nodes_ptrs[cell+1] = length(oldnodes)
  end
  length_to_ptrs!(cell_to_nodes_ptrs)
  ndata = cell_to_nodes_ptrs[end]-1
  cell_to_nodes_data = zeros(Int32,ndata)
  for (cell,oldcell) in enumerate(cell_to_oldcell)
    oldnodes = getindex!(cache,oldcell_to_oldnodes,oldcell)
    a = cell_to_nodes_ptrs[cell]-1
    for (lnode,oldnode) in enumerate(oldnodes)
      node = oldnode_to_node[oldnode]
      @assert node > 0
      cell_to_nodes_data[a+lnode] = node
    end
  end
  Table(cell_to_nodes_data,cell_to_nodes_ptrs)
end


text:
module SimpleWorkflows

include("jobs.jl")
include("graph.jl")

end


text:
# file containing methods for requesting historical simulations from GEOGloWS

"""
    historic_simulation(parameters::AbstractDict{Symbol,<:Any})

returns simulated streamflow data based on the ERA-5 dataset. A successful
response will return a time series with date-value pairs.
"""
function historic_simulation(parameters::AbstractDict{Symbol,<:Any})
    endpoint = "HistoricSimulation"

    r = _make_request(baseurl, endpoint, parameters)

    _read_response(r, parameters[:return_format]; with_dates = true)

end

"""
    historic_simulation(reach_id::Int; return_format::Symbol = :csv)

returns simulated streamflow data based on the ERA-5 dataset. A successful
response will return a time series with date-value pairs.
"""
function historic_simulation(reach_id::Int; return_format::Symbol = :csv)

    parameters = Dict(:reach_id => reach_id, :return_format => return_format)

    historic_simulation(parameters)
end

"""
    historic_simulation(lat::Real, lon::Real; return_format::Symbol = :csv)

returns simulated streamflow data based on the ERA-5 dataset. A successful
response will return a time series with date-value pairs.
"""
function historic_simulation(lat::Real, lon::Real; return_format::Symbol = :csv)

    parameters = Dict(:lat => lat, :lon => lon, :return_format => return_format)

    historic_simulation(parameters)
end

"""
    return_periods(parameters::AbstractDict{Symbol,<:Any})

returns the 2, 5, 10, 25, 50, and 100 year return period based on the 40-years
simulated streamflow data and using the Gumbel Method. A successful response
will return key-value pairs for earch return period along with metadata.
"""
function return_periods(parameters::AbstractDict{Symbol,<:Any})

    endpoint = "ReturnPeriods"

    r = _make_request(baseurl, endpoint, parameters)

    _read_response(r, parameters[:return_format])

    return result

end

"""
    return_periods(reach_id::Int; return_format::Symbol = :csv, forcing::Symbol = :era_5,)

returns the 2, 5, 10, 25, 50, and 100 year return period based on the 40-years
simulated streamflow data and using the Gumbel Method. A successful response
will return key-value pairs for earch return period along with metadata.
"""
function return_periods(
    reach_id::Int;
    return_format::Symbol = :csv,
    forcing::Symbol = :era_5,
)
    parameters = Dict(
        :reach_id => reach_id,
        :return_format => return_format,
        :forcing => forcing,
    )

    return_periods(parameters)
end

"""
    return_periods(lat::Real, lon::Real; return_format::Symbol = :csv, forcing::Symbol = :era_5,)

returns the 2, 5, 10, 25, 50, and 100 year return period based on the 40-years
simulated streamflow data and using the Gumbel Method. A successful response
will return key-value pairs for earch return period along with metadata.
"""
function return_periods(
    lat::Real,
    lon::Real;
    return_format::Symbol = :csv,
    forcing::Symbol = :era_5,
)
    parameters = Dict(
        :lat => lat,
        :lon => lon,
        :return_format => return_format,
        :forcing => forcing,
    )

    return_periods(parameters)
end

"""
    daily_averages(parameters::AbstractDict{Symbol,<:Any})

returns the average flow for each day of the year for the Historic Simulation
"""
function daily_averages(parameters::AbstractDict{Symbol,<:Any})
    endpoint = "DailyAverages"

    r = _make_request(baseurl, endpoint, parameters)

    _read_response(r, parameters[:return_format])

end

"""
    daily_averages(reach_id::Int; return_format::Symbol = :csv)

returns the average flow for each day of the year for the Historic Simulation
"""
function daily_averages(reach_id::Int; return_format::Symbol = :csv)
    parameters = Dict(:reach_id => reach_id, :return_format => return_format)

    daily_averages(parameters)
end

"""
    daily_averages(lat::Real, lon::Real; return_format::Symbol = :csv)

returns the average flow for each day of the year for the Historic Simulation
"""
function daily_averages(lat::Real, lon::Real; return_format::Symbol = :csv)
    parameters = Dict(:lat => lat, :lon => lon, :return_format => return_format)

    daily_averages(parameters)
end

"""
    monthly_averages(parameters::AbstractDict{Symbol,<:Any})

returns the average flow for each month of the year for the Historic Simulation
"""
function monthly_averages(parameters::AbstractDict{Symbol,<:Any})
    endpoint = "MonthlyAverages"

    r = _make_request(baseurl, endpoint, parameters)

    _read_response(r, parameters[:return_format])

end

"""
    monthly_averages(reach_id::Int; return_format::Symbol = :csv)

returns the average flow for each month of the year for the Historic Simulation
"""
function monthly_averages(reach_id::Int; return_format::Symbol = :csv)
    parameters = Dict(:reach_id => reach_id, :return_format => return_format)

    monthly_averages(parameters)
end

"""
    monthly_averages(lat::Real, lon::Real; return_format::Symbol = :csv)

returns the average flow for each month of the year for the Historic Simulation
"""
function monthly_averages(lat::Real, lon::Real; return_format::Symbol = :csv)
    parameters = Dict(:lat => lat, :lon => lon, :return_format => return_format)

    monthly_averages(parameters)
end


text:
module RandomVariates

export
# SEED, A, C, MOD,
bernoulli_rng,
beta_rng,
binomial_rng,
erlang_rng,
expon_rng,
gamma_rng,
geometric_rng,
neg_binomial_rng,
conv_neg_binomial_rng,
normal_rng,
lognormal_rng,
mv_normal_rng,
poisson_rng,
uniform_rng,
weibull_rng,
tausworthe_rng,
triag_rng

include("uniform.jl")
include("exponential.jl")
include("erlang.jl")
include("weibull.jl")
include("bernoulli.jl")
include("geometric.jl")
include("poisson.jl")
include("binomial.jl")
include("neg_binomial.jl")
include("normal.jl")
include("gamma.jl")
include("beta.jl")
include("tausworthe.jl")
include("triangular.jl")

using Dates

global SEED = Dates.value(Dates.now())  # Use current epoch time as default seed

# using POSIX params for LCG
# https://en.wikipedia.org/wiki/Linear_congruential_generator#Parameters_in_common_use
const A = 25214903917
const C = 11
const MOD = 2^48

"""
    set_seed(seed::Int)

Set the global `SEED` variable.
"""
function set_seed(seed::Int)
    global SEED = seed
end

"""
    set_user_seed(seed::Int)

Set a user-defined seed as global `SEED` variable.
"""
function set_user_seed(seed::Int)
    global SEED = seed * 7856209
end

"""
    seed_setter(seed::Union{Int, Nothing}=nothing)

Set a user defined seed, if given.
"""
function seed_setter(seed::Union{Int, Nothing}=nothing)
    if !isnothing(seed)
        set_user_seed(seed)  # only set user seed once so we get new seed in subsequent calls
    end
end

"""
    get_seed()

Get the global `SEED` variable.
"""
function get_seed()
	return SEED
end

"""
    check_p(p::Real)
Check that parameter `p` falls between 0 and 1.
"""
function check_p(p::Real)
    if (p > 1) || (p < 0)
        throw(ArgumentError("Parameter `p` must fall between 0 and 1."))
    end
end

# End of Module
end


text:
"""
This function does nothing if product is not of Capacity type.
"""
function update_forward_profit!(product::T,
                               finance_data::Finance,
                               scenario_name::String,
                               update_year::Int64,
                               profit::Float64) where T <: Product
    return
end

"""
This function updates the capacity market forward reveneues.
"""
function update_forward_profit!(product::Capacity,
                               finance_data::Finance,
                               scenario_name::String,
                               update_year::Int64,
                               profit::Float64)

    for i = 1:length(get_scenario_profit(finance_data)[scenario_name])
        set_scenario_profit!(finance_data,
                        scenario_name,
                        get_name(product),
                        i,
                        update_year,
                        profit)
    end
    return
end

"""
This function does nothing if the project is retired.
"""
function update_realized_profits!(project::P,
                                  market_prices::MarketPrices,
                                  capacity_factors::Dict{Symbol, Array{Float64, 2}},
                                  reserve_up_perc::Dict{Symbol, Array{Float64, 2}},
                                  reserve_down_perc::Dict{Symbol, Array{Float64, 2}},
                                  capacity_accepted_bids::Dict{Symbol, Float64},
                                  rec_accepted_bids::Dict{String, Float64},
                                  rep_hour_weight::Vector{Float64},
                                  iteration_year::Int64,
                                  capacity_forward_years::Int64) where P <: Project{Retired}

end

"""
This function updates the annual realized profit for active projects.
Returns nothing.
"""
function update_realized_profits!(project::P,
                                  market_prices::MarketPrices,
                                  capacity_factors::Dict{String, Array{Float64, 2}},
                                  reserve_up_perc::Dict{String, Array{Float64, 2}},
                                  reserve_down_perc::Dict{String, Array{Float64, 2}},
                                  capacity_accepted_bids::Dict{String, Float64},
                                  rec_accepted_bids::Dict{String, Float64},
                                  realized_hour_weight::Vector{Float64},
                                  iteration_year::Int64,
                                  capacity_forward_years::Int64) where P <: Project{<: BuildPhase}

    for product in get_products(project)
        profit, update_year = calculate_realized_profit(get_name(project),
                                           get_maxcap(project),
                                           get_zone(get_tech(project)),
                                           product,
                                           market_prices,
                                           capacity_factors,
                                           reserve_up_perc,
                                           reserve_down_perc,
                                           capacity_accepted_bids,
                                           rec_accepted_bids,
                                           realized_hour_weight,
                                           iteration_year,
                                           capacity_forward_years)

        finance_data =  get_finance_data(project)
        profit_array_length =  size(get_realized_profit(finance_data), 2)
        if !isnothing(profit) && update_year <= profit_array_length
            set_realized_profit!(finance_data,
                    get_name(product),
                    update_year,
                    profit)

            for scenario_name in keys(get_scenario_profit(finance_data))
                update_forward_profit!(product, finance_data, scenario_name, update_year, profit)
            end
        end

    end

    return
end

"""
THis function updates the annual cash flow of Existing projects.
"""
function update_annual_cashflow!(project::Project{Existing}, iteration_year::Int64)
    finance_data = get_finance_data(project)
    annual_revenue = sum(get_realized_profit(finance_data)[:, iteration_year])
    annual_cashflow = annual_revenue - get_fixed_OM_cost(finance_data)
    set_annual_cashflow!(finance_data, iteration_year, get_annual_cashflow(finance_data)[iteration_year] + annual_cashflow)
    return
end

"""
This function updates the annual cash flow of Queue projects
"""
function update_annual_cashflow!(project::Project{Queue}, iteration_year::Int64)
    finance_data = get_finance_data(project)
    queue_cost = get_queue_cost(finance_data)
    decision_year = get_decision_year(project)

    queue_year =  iteration_year - decision_year + 1

    annual_queuecost = queue_cost[queue_year]
    set_annual_cashflow!(finance_data, iteration_year, get_annual_cashflow(finance_data)[iteration_year] - annual_queuecost)
    return
end

"""
This function updates the annual cash flow of Planned projects
"""
function update_annual_cashflow!(project::Project{Planned}, iteration_year::Int64)
    finance_data = get_finance_data(project)

    queue_cost = get_queue_cost(finance_data)
    decision_year = get_decision_year(project)

    if decision_year + length(queue_cost) == iteration_year
        investment_cost = get_effective_investment_cost(finance_data)
        set_annual_cashflow!(finance_data, iteration_year, get_annual_cashflow(finance_data)[iteration_year] - investment_cost)
    end

    return
end

"""
This function does nothing if project is in Option or Retired phase.
"""
function update_annual_cashflow!(project::Union{Project{Retired}, Project{Option}}, iteration_year::Int64)
    return
end

"""
This function keeps forecasts the same for all scenarios if Kalman Filter based updates are deactivated.
"""
function update_scenario_data!(scenario_data::Vector{Scenario}, kf::Nothing, iteration_year::Int64)
    for scenario in scenario_data
        parameter_values = deepcopy(get_parameter_values(scenario)[iteration_year])
        set_parameter_values!(scenario, iteration_year + 1, parameter_values)
    end

    return
end

"""
This function updates the forecasts for all scenarios using Kalman Filters and scaling factors.
"""
function update_scenario_data!(scenario_data::Vector{Scenario}, kf::KalmanFilter, iteration_year::Int64)
    state_estimate_data = get_state_estimate(kf)
    for scenario in scenario_data
        parameter_values = deepcopy(get_parameter_values(scenario)[iteration_year])

        axis_val = AxisArrays.axisvalues(parameter_values)
        parameter_multipliers = get_parameter_multipliers(scenario)
        for parameter in axis_val[1]
            for year in axis_val[2]
                parameter_values[parameter, year] = state_estimate_data[parameter] * parameter_multipliers[parameter]
            end
        end
        set_parameter_values!(scenario, iteration_year + 1, parameter_values)
    end

    return
end

"""
This function does nothing if forecast is Perfect.
"""
function update_forecast!(forecast::Perfect, measurement::AxisArrays.AxisArray{Float64, 1}, iteration_year::Int64)
    return
end

"""
This function updates the forecasts using Kalman Filters if they are Imperfect.
"""
function update_forecast!(forecast::Imperfect, measurement::AxisArrays.AxisArray{Float64, 1}, iteration_year::Int64)
    update_belief!(get_kalman_filter(forecast), measurement)
    update_scenario_data!(get_scenario_data(forecast), get_kalman_filter(forecast), iteration_year)
    return
end


text:
export Operator, Plus, Minus, Times, Divide
export calculate_typed, calculate_branch

abstract type Operator end
struct Plus  <: Operator end
struct Minus <: Operator end
struct Times <: Operator end
struct Divide <: Operator end

(::Plus)(a, b) = a + b
(::Minus)(a, b) = a - b
(::Times)(a, b) = a * b
(::Divide)(a, b) = a / b

"""
    calculate_typed(numbers, operations)

`calculate_typed` performs the computations decribed by `operations` on the values in `numbers`.
`numbers[1]` and `numbers[2]` get combined via `operations[1]`, and the result is then kept and updated
with additional elements of each.

# Examples

```julia
julia> numbers = [1, 2, 5];

julia> operations = Operator[Plus(), Divide()]

julia> calculate_typed(numbers, operations)
0.6
```

This corresponds to the calculation: `1 Plus() 2 -> 3`, followed by `3 Divide() 5 -> 0.6`.
The `3` in the second calculation is the result of the first calculation.
"""
function calculate_typed(numbers::AbstractVector{<:Real}, operations::AbstractVector{Operator})
    a = Float64(numbers[1])
    for i = 1:length(operations)
        b = numbers[i+1]
        op = operations[i]
        a = op(a, b)
    end
    return a
end

"""
calculate_typed(numbers, operations)

`calculate_branch` does the same job as `calculate_typed`, except the operations are encoded as a string.

# Examples

```julia
julia> numbers = [1, 2, 5];

julia> operations = "+/";

julia> calculate_branch(numbers, operations)
0.6
```
"""
function calculate_branch(numbers::AbstractVector{<:Real}, operations::AbstractString)
    # Duplicate the function above, except instead of iterating through Operators,
    # iterate through the characters in `operations` (which will all be one of `+`, `-`, `*`, `/`)
    # Do not create an Operator from the character, instead just use a set of `if...elseif...end`
    # conditionals.
    error("you have to implement this function")
end


text:
# AWS S3 example
# to put array into a bucket 'slimbucket' in region 'us-west-2' under name 'tmp/test/small'

# safe only if using one Cloud provider

using AWSCore
using CloudExtras.AWSextras

aws = aws_config(region="us-east-1")

a=randn(11,12,13);

array_put(aws, "slimbucket", "tmp/test/small", a);

A=array_get(aws, "slimbucket", "tmp/test/small");

array_delete(aws, "slimbucket", "tmp/test/small");


text:
module ToyECDSA

using SHA

import Base.in, Base.==, Base.+, Base.*

export ECDSA_Key, ECDSA_Public_Key, genkey, ECDSA_sign, isverifiedECDSA

# T will be BigInt in most applications
struct CurveFP{T}
    p::T
    a::T
    b::T
    CurveFP(p, a::T, b::T) where T <: Number = new{T}(p, a, b)
end

struct PointEC{T}
    curve::CurveFP{T}
    x::T
    y::T
    order::Union{Number, Nothing}
    function PointEC(curve, x::T, y::T, order=nothing) where T <: Number
        @assert((x, y) in curve)
        new{T}(curve, x, y, order)
    end
end

struct PointINF end
const INFINITY = PointINF()

function ==(point_a::PointEC, point_b::PointEC)
    if point_a.curve == point_b.curve && point_a.x == point_b.x && point_a.y == point_b.y
        return true
    end
    return false
end

function ==(curve_a::CurveFP, curve_b::CurveFP)
    if curve_a.a == curve_b.a && curve_a.b == curve_b.b && curve_a.p == curve_b.p
        return true
    end
    return false
end

+(point_a::PointINF, point_b::PointINF) = point_b
+(point_a::PointINF, point_b::PointEC) = point_b
+(point_a::PointEC, point_b::PointINF) = point_a

function +(point_a::PointEC, point_b::PointEC)
     @assert(point_a.curve == point_b.curve)
     if point_a.x == point_b.x
         if (point_a.y + point_b.y) % point_a.curve.p == 0
             return INFINITY
         else
             return double(point_a)
        end
    end
    p = point_a.curve.p
    λ = (point_a.y - point_b.y) * invmod(point_a.x - point_b.x, p)
    xr = mod(λ * λ - point_a.x - point_b.x, p)
    yr = mod(λ * (point_a.x - xr) - point_a.y, p)
    return PointEC(point_a.curve, xr, yr, point_a.order)
end

*(point_a::PointINF, int_b::Number) = INFINITY
*(int_b::Number, point_a::PointINF) = INFINITY
*(int_b::Number, point_a::PointEC) = point_a * int_b

function *(point_a::PointEC, int_b::Number)
    leftmost_bit(x) = big"2"^Int(trunc(log(2, x)))
    if point_a.order != nothing
        int_b %= point_a.order
    end
    if int_b == 0
        return INFINITY
    end
    int_3b = 3 * int_b
    negative_a = PointEC(point_a.curve, point_a.x, -point_a.y, point_a.order)
    i = BigInt(leftmost_bit(int_3b) ÷ 2)
    result = point_a
    while i > 1
        result = double(result)
        if (int_3b & i) != 0 && (int_b & i) == 0
            result += point_a
        end
        if (int_3b & i) == 0 && (int_b & i) != 0
            result += negative_a
        end
        i ÷= 2
    end
    return result
end

in(z::Tuple, curve::CurveFP) = (z[2]^2 - (z[1]^3 + curve.a*z[1] + curve.b)) % curve.p == 0
in(x::Number,y::Number, curve::CurveFP) = (y^2 -(x^3 + curve.a*x + curve.b)) % curve.p == 0
in(p::PointEC, curve::CurveFP) = (p.y^2 - (p.x^3 + curve.a * p.x + curve.b)) % curve.p == 0
in(point::PointINF, curve::CurveFP) = true

double(point_a::PointINF) = INFINITY

function double(point_a::PointEC)
  a, p = point_a.curve.a, point_a.curve.p
  l = mod((3 * point_a.x^2 + a) * invmod(2 * point_a.y, p), p)
  x3 = mod(l^2 - 2 * point_a.x, p)
  y3 = mod(l * (point_a.x - x3) - point_a.y, p)
  return PointEC(point_a.curve, x3, y3, point_a.order)
end

const secp256k1 = (  # use the Bitcoin ECDSA curve
    p = big"0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F",
    a = big"0x0",
    b = big"0x7",
    r = big"0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141",
    Gx = big"0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798",
    Gy = big"0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8",
)
@assert((secp256k1.Gy^2 - secp256k1.Gx^3 - 7) % secp256k1.p == 0)

function generatemultiplier(stdcurve)
    return foldl((x, y) -> 16 * BigInt(x) + y, rand(0:16, ndigits(stdcurve.r - 1, base=16)))
end

struct ECDSA_Key
    E::CurveFP
    secret::BigInt
    G::PointEC
    r::BigInt
    W::PointEC
end

struct ECDSA_Public_Key
    E::CurveFP
    G::PointEC
    r::BigInt
    W::PointEC
end

function genkey(curve=secp256k1) # default: use Bitcoin standard EC curve secp256k1
    E = CurveFP(curve.p, curve.a, curve.b)
    s = generatemultiplier(curve)
    G = PointEC(E, curve.Gx, curve.Gy, curve.r)
    W = s * G
    return ECDSA_Key(E, s, G, curve.r, W)
end

aspublickey(k::ECDSA_Key) = ECDSA_Public_Key(k.E, k.G, k.r, k.W)
privatekey(k::ECDSA_Key) = k.secret

function ECDSA_sign(m::String, key::ECDSA_Key, digestfunction=sha256)
    r, f = key.r, digestfunction(codeunits(m)) # f = H(m)
    # order of curve points length must be >= sha digest length (in bytes)
    @assert(ndigits(r, base=16) >= length(f))
    c, d, bindigest = BigInt(0), BigInt(0), foldl((x, y) -> 16 * BigInt(x) + y, f)
    while c == 0 || d == 0
        u = generatemultiplier(secp256k1)
        V = u * key.G
        c = mod(V.x, r)
        d = mod((invmod(u, r) * (bindigest + key.secret * c)), r)
    end
    return aspublickey(key), c, d
end

function isverifiedECDSA(m::String, publickey, c, d, digestfunction=sha256)
    if 1 <= c < publickey.r && 1 <= d < publickey.r
        r, f = publickey.r, digestfunction(codeunits(m))
        h, bindigest = invmod(d, r), foldl((x, y) -> 16 * BigInt(x) + y, f)
        h1, h2 = mod(bindigest * h, r), mod(c * h, r)
        verifierpoint = h1 * publickey.G + h2 * publickey.W
        return mod(verifierpoint.x, r) == c
    end
    return false
end

end  # module


text:
"""
`Colorant{T,N}` is the abstract super-type of all types in ColorTypes,
and refers to both (opaque) colors and colors-with-transparency (alpha
channel) information.  `T` is the element type (extractable with
`eltype`) and `N` is the number of *meaningful* entries (extractable
with `length`), i.e., the number of arguments you would supply to the
constructor.
"""
abstract Colorant{T,N}

# Colors (without transparency)
"""
`Color{T,N}` is the abstract supertype for a color (or
grayscale) with no transparency.
"""
abstract Color{T, N} <: Colorant{T,N}

"""
`AbstractRGB{T}` is an abstract supertype for red/green/blue color types that
can be constructed as `C(r, g, b)` and for which the elements can be
extracted as `red(c)`, `green(c)`, `blue(c)`. You should *not* make
assumptions about internal storage order, the number of fields, or the
representation. One `AbstractRGB` color-type, `RGB24`, is not
parametric and does not have fields named `r`, `g`, `b`.
"""
abstract AbstractRGB{T}      <: Color{T,3}

# Types with transparency
"""
`TransparentColor{C,T,N}` is the abstract type for any
color-with-transparency.  The `C` parameter refers to the type of the
pure color (without transparency) and can be extracted with
`color_type`. `T` is the element type of both `C` and the `alpha`
channel, and `N` has the same meaning as in `Colorant` (and is 1 larger
than the corresponding color type).

All transparent types should support two modes of construction:

    P(color, alpha)
    P(component1, component2, component3, alpha) (assuming a 3-component color)

For a `Colorant` `c`, the color component can be extracted with
`color(c)`, and the alpha channel with `alpha(c)`. Note that types
such as `ARGB32` do not have a field named `alpha`.

Most concrete types, like `RGB`, have both `ARGB` and `RGBA`
transparent analogs.  These two indicate different internal storage
order (see `AlphaColor` and `ColorAlpha`, and the `alphacolor` and
`coloralpha` functions).
"""
abstract TransparentColor{C<:Color,T,N} <: Colorant{T,N}

"""
`AlphaColor` is an abstract supertype for types like `ARGB`, where the
alpha channel comes first in the internal storage order. **Note** that
the constructor order is still `(color, alpha)`.
"""
abstract AlphaColor{C,T,N} <: TransparentColor{C,T,N}

"""
`ColorAlpha` is an abstract supertype for types like `RGBA`, where the
alpha channel comes last in the internal storage order.
"""
abstract ColorAlpha{C,T,N} <: TransparentColor{C,T,N}

# These are types we'll dispatch on. Not exported.
typealias AbstractGray{T}                    Color{T,1}
typealias Color3{T}                          Color{T,3}
typealias TransparentGray{C<:AbstractGray,T} TransparentColor{C,T,2}
typealias Transparent3{C<:Color3,T}          TransparentColor{C,T,4}
typealias TransparentRGB{C<:AbstractRGB,T}   TransparentColor{C,T,4}
typealias ColorantUFixed{T<:UFixed,N}        Colorant{T,N}

"""
`RGB` is the standard Red-Green-Blue (sRGB) colorspace.  Values of the
individual color channels range from 0 (black) to 1 (saturated). If
you want "Integer" storage types (e.g., 255 for full color), use `U8(1)`
instead (see FixedPointNumbers).
"""
immutable RGB{T<:Fractional} <: AbstractRGB{T}
    r::T # Red [0,1]
    g::T # Green [0,1]
    b::T # Blue [0,1]
end

"""
`BGR` is a variant of `RGB` with the opposite storage order.  Note
that the constructor is still called in the order `BGR(r, g, b)`.
This storage order is noteworthy because on little-endian machines,
`BGRA` (with transparency) can be `reinterpret`ed to the `UInt32`
color format used by libraries such as Cairo and OpenGL.
"""
immutable BGR{T<:Fractional} <: AbstractRGB{T}
    b::T
    g::T
    r::T

    BGR(r::Real, g::Real, b::Real) = new(b, g, r)
end
BGR{T<:Fractional}(r::T, g::T, b::T) = BGR{T}(r, g, b)

"""
`RGB1` is a variant of `RGB` which has a padding element inserted at
the beginning. In some applications it may have useful
memory-alignment properties.

Like all other AbstractRGB objects, the constructor is still called
`RGB1(r, g, b)`.
"""
immutable RGB1{T<:Fractional} <: AbstractRGB{T}
    alphadummy::T
    r::T
    g::T
    b::T

    RGB1(r::Real, g::Real, b::Real) = new(one(T), r, g, b)
end
RGB1{T<:Fractional}(r::T, g::T, b::T) = RGB1{T}(r, g, b)

"""
`RGB4` is a variant of `RGB` which has a padding element inserted at
the end. In some applications it may have useful
memory-alignment properties.

Like all other AbstractRGB objects, the constructor is still called
`RGB4(r, g, b)`.
"""
immutable RGB4{T<:Fractional} <: AbstractRGB{T}
    r::T
    g::T
    b::T
    alphadummy::T

    RGB4(r::Real, g::Real, b::Real) = new(r, g, b, one(T))
end
RGB4{T<:Fractional}(r::T, g::T, b::T) = RGB4{T}(r, g, b)

"`HSV` is the Hue-Saturation-Value colorspace."
immutable HSV{T<:AbstractFloat} <: Color{T,3}
    h::T # Hue in [0,360)
    s::T # Saturation in [0,1]
    v::T # Value in [0,1]
end

"`HSB` (Hue-Saturation-Brightness) is an alias for `HSV`."
typealias HSB HSV

"`HSL` is the Hue-Saturation-Lightness colorspace."
immutable HSL{T<:AbstractFloat} <: Color{T,3}
    h::T # Hue in [0,360)
    s::T # Saturation in [0,1]
    l::T # Lightness in [0,1]
end

"`HSI` is the Hue-Saturation-Intensity colorspace."
immutable HSI{T<:AbstractFloat} <: Color{T,3}
    h::T
    s::T
    i::T
end

"""
`XYZ` is the CIE 1931 XYZ colorspace. It is a linear colorspace,
meaning that mathematical operations such as addition, subtraction,
and scaling make "colorimetric sense" in this colorspace.
"""
immutable XYZ{T<:AbstractFloat} <: Color{T,3}
    x::T
    y::T
    z::T
end

"`xyY` is the CIE 1931 xyY (chromaticity + luminance) space"
immutable xyY{T<:AbstractFloat} <: Color{T,3}
    x::T
    y::T
    Y::T
end

"`Lab` is the CIELAB colorspace."
immutable Lab{T<:AbstractFloat} <: Color{T,3}
    l::T # Luminance in approximately [0,100]
    a::T # Red/Green
    b::T # Blue/Yellow
end

"`LCHab` is the Luminance-Chroma-Hue, Polar-Lab colorspace"
immutable LCHab{T<:AbstractFloat} <: Color{T,3}
    l::T # Luminance in [0,100]
    c::T # Chroma
    h::T # Hue in [0,360)
end

"`Luv` is the CIELUV colorspace"
immutable Luv{T<:AbstractFloat} <: Color{T,3}
    l::T # Luminance
    u::T # Red/Green
    v::T # Blue/Yellow
end

"`LCHuv` is the Luminance-Chroma-Hue, Polar-Luv colorspace"
immutable LCHuv{T<:AbstractFloat} <: Color{T,3}
    l::T # Luminance
    c::T # Chroma
    h::T # Hue
end

"`DIN99` is the (L99, a99, b99) adaptation of CIELAB"
immutable DIN99{T<:AbstractFloat} <: Color{T,3}
    l::T # L99
    a::T # a99
    b::T # b99
end

"`DIN99d` is the (L99d, a99d, b99d) improvement on DIN99"
immutable DIN99d{T<:AbstractFloat} <: Color{T,3}
    l::T # L99d
    a::T # a99d
    b::T # b99d
end

"`DIN99o` is the (L99o, a99o, b99o) adaptation of CIELAB"
immutable DIN99o{T<:AbstractFloat} <: Color{T,3}
    l::T # L99o
    a::T # a99o
    b::T # b99o
end

"""
`LMS` is the Long-Medium-Short colorspace based on activation of the
three cone photoreceptors.  Like `XYZ`, this is a linear color space.
"""
immutable LMS{T<:AbstractFloat} <: Color{T,3}
    l::T # Long
    m::T # Medium
    s::T # Short
end

"`YIQ` is a color encoding, for example used in NTSC transmission."
immutable YIQ{T<:AbstractFloat} <: Color{T,3}
    y::T
    i::T
    q::T
end

"`YCbCr` is the Y'CbCr color encoding often used in digital photography or video"
immutable YCbCr{T<:AbstractFloat} <: Color{T,3}
    y::T
    cb::T
    cr::T
end

"""
`RGB24` uses a `UInt32` representation of color, 0xAARRGGBB, where
R=red, G=green, B=blue and A is irrelevant. This format is often used
by external libraries such as Cairo.

`RGB24` colors do not have fields named `r`, `g`, `b`, but you can
still extract the individual components with `red(c)`, `green(c)`,
`blue(c)`.  You can construct them directly from a `UInt32`, or as
`RGB(r, g, b)`.
"""
immutable RGB24 <: AbstractRGB{U8}
    color::UInt32
end
RGB24() = RGB24(0)
_RGB24(r::UInt8, g::UInt8, b::UInt8) = RGB24(UInt32(r)<<16 | UInt32(g)<<8 | UInt32(b))
RGB24(r::UFixed8, g::UFixed8, b::UFixed8) = _RGB24(reinterpret(r), reinterpret(g), reinterpret(b))
RGB24(r, g, b) = RGB24(U8(r), U8(g), U8(b))

"""
`ARGB32` uses a `UInt32` representation of color, 0xAARRGGBB, where
R=red, G=green, B=blue and A is the alpha channel. This format is
often used by external libraries such as Cairo.  On a little-endian
machine, this type has the exact same storage format as `BGRA{U8}`.

`ARGB32` colors do not have fields named `alpha`, `r`, `g`, `b`, but
you can still extract the individual components with `alpha(c)`,
`red(c)`, `green(c)`, `blue(c)`.  You can construct them directly from
a `UInt32`, or as `ARGB32(r, g, b, alpha)`.
"""
immutable ARGB32 <: AlphaColor{RGB24, U8, 4}
    color::UInt32
end
ARGB32() = ARGB32(UInt32(0xff)<<24)
_ARGB32(r::UInt8, g::UInt8, b::UInt8, alpha::UInt8) = ARGB32(UInt32(alpha)<<24 | UInt32(r)<<16 | UInt32(g)<<8 | UInt32(b))
ARGB32(r::UFixed8, g::UFixed8, b::UFixed8, alpha::UFixed8 = U8(1)) = _ARGB32(reinterpret(r), reinterpret(g), reinterpret(b), reinterpret(alpha))
ARGB32(r, g, b, alpha = 1) = ARGB32(U8(r), U8(g), U8(b), U8(alpha))
ARGB32{T}(c::AbstractRGB{T}, alpha = alpha(c)) = ARGB32(red(c), green(c), blue(c), alpha)

"""
`Gray` is a grayscale object. You can extract its value with `gray(c)`.
"""
immutable Gray{T<:Union{Fractional,Bool}} <: AbstractGray{T}
    val::T
end

"""
`Gray24` uses a `UInt32` representation of color, 0xAAIIIIII, where
I=intensity (grayscale value) and A is irrelevant. Each II pair is
assumed to be the same.  This format is often used by external
libraries such as Cairo.

You can extract the single gray value with `gray(c)`.  You can
construct them directly from a `UInt32`, or as `Gray24(i)`. Note that
`i` is interpreted on a scale from 0 (black) to 1 (white).
"""
immutable Gray24 <: AbstractGray{U8}
    color::UInt32

    Gray24(c::UInt32, _) = new(c)
end
Gray24() = Gray24(0)
_Gray24(val::UInt8) = (g = UInt32(val); Gray24(g<<16 | g<<8 | g, 0))
Gray24(val::UFixed8) = _Gray24(reinterpret(val))
Gray24(val) = Gray24(U8(val))

"""
`AGray32` uses a `UInt32` representation of color, 0xAAIIIIII, where
I=intensity (grayscale value) and A=alpha. Each II pair is
assumed to be the same.  This format is often used by external
libraries such as Cairo.

You can extract the single gray value with `gray(c)` and the alpha as
`alpha(c)`.  You can construct them directly from a `UInt32`, or as
`AGray32(i,alpha)`. Note that `i` and `alpha` are interpreted on a
scale from 0 (black) to 1 (white).
"""
immutable AGray32 <: AlphaColor{Gray24, U8, 2}
    color::UInt32

    AGray32(c::UInt32, dummy1, dummy2) = new(c)
end
AGray32() = AGray32(0)
_AGray32(val::UInt8, alpha::UInt8 = 0xff) = (g = UInt32(val); AGray32(UInt32(alpha)<<24 | g<<16 | g<<8 | g, 0, 0))
AGray32(val::UFixed8, alpha::UFixed8 = UFixed8(1)) = _AGray32(reinterpret(val), reinterpret(alpha))
AGray32(val, alpha = 1) = AGray32(U8(val), U8(alpha))

# Generated code:
#   - more constructors for colors
#   - TransparentColor definitions (e.g., ARGB), exports, and constructors
#   - coloralpha(::Color) and alphacolor(::Color) traits for corresponding types

# Note: with the exceptions of `alphacolor` and `coloralpha`, all
# traits in the rest of this file are intended just for internal use

const color3types = filter(x->(!x.abstract && length(fieldnames(x))>1), union(subtypes(Color), subtypes(AbstractRGB)))
const parametric3 = filter(x->!isempty(x.parameters), color3types)

# Provide the field names in the order expected by the constructor
colorfields{C<:Color}(::Type{C}) = (fieldnames(C)...)
colorfields{C<:RGB1}(::Type{C}) = (:r, :g, :b)
colorfields{C<:RGB4}(::Type{C}) = (:r, :g, :b)
colorfields{C<:BGR }(::Type{C}) = (:r, :g, :b)
colorfields{P<:TransparentColor}(::Type{P}) = tuple(colorfields(color_type(P))..., :alpha)
colorfields(c::Colorant) = colorfields(typeof(c))

# Generate convenience constructors for a type
macro make_constructors(C, fields, elty)
    # elty = default element type when supplied with Integer arguments
    fields = fields.args
    Tfields = Expr[:($f::T) for f in fields]
    realfields = Expr[:($f::Real) for f in fields]
    zfields = zeros(Int, length(fields))
    esc(quote
        # More constructors for the non-alpha version
        $C{T<:Integer}($(Tfields...)) = $C{$elty}($(fields...))
        $C($(realfields...)) = $C(promote($(fields...))...)
        $C() = $C{$elty}($(zfields...))
    end)
end

# Generate transparent versions
macro make_alpha(C, acol, cola, fields, constrfields, ub, elty)
    # ub = upper-bound on T in C{T}
    # elty = default element type when supplied with Integer arguments
    fields = fields.args
    constrfields = constrfields.args
    N = length(fields)+1
    Tfields       = Expr[:($f::T)    for f in fields]
    Tconstrfields = Expr[:($f::T)    for f in constrfields]
    realfields    = Expr[:($f::Real) for f in constrfields]
    cfields       = Expr[:(c.$f)     for f in constrfields]
    cinnerfields  = Expr[:(c.$f)     for f in fields]
    zfields       = zeros(Int, length(fields))
    Tconstr = Expr(:<:, :T, ub)
    exportexpr = Expr(:export, acol, cola)
    esc(quote
        immutable $acol{$Tconstr} <: AlphaColor{$C{T}, T, $N}
            alpha::T
            $(Tfields...)

            $acol($(realfields...), alpha::Real=one(T)) = new(alpha, $(fields...))
            $acol(c::$C, alpha::Real=one(T)) = new(alpha, $(cinnerfields...))
        end
        immutable $cola{$Tconstr} <: ColorAlpha{$C{T}, T, $N}
            $(Tfields...)
            alpha::T

            $cola($(realfields...), alpha::Real=one(T)) = new($(fields...), alpha)
            $cola(c::$C, alpha::Real=one(T)) = new($(cinnerfields...), alpha)
        end
        $exportexpr
        alphacolor{C<:$C}(::Type{C}) = $acol
        coloralpha{C<:$C}(::Type{C}) = $cola

        # More constructors for the alpha versions
        $acol{T<:Integer}($(Tconstrfields...), alpha::T=1) = $acol{$elty}($(fields...), alpha)
        function $acol($(constrfields...))
            p = promote($(constrfields...))
            T = typeof(p[1])
            $acol{T}(p...)
        end
        function $acol($(constrfields...), alpha)
            p = promote($(constrfields...), alpha)
            T = typeof(p[1])
            $acol{T}(p...)
        end
        $acol(c::Color, alpha::Real) = convert($acol, c, alpha)
        $acol() = $acol{$elty}($(zfields...))

        $cola{T<:Integer}($(Tconstrfields...), alpha::T=1) = $cola{$elty}($(fields...), alpha)
        function $cola($(constrfields...))
            p = promote($(constrfields...))
            T = typeof(p[1])
            $cola{T}(p...)
        end
        function $cola($(constrfields...), alpha)
            p = promote($(constrfields...), alpha)
            T = typeof(p[1])
            $cola{T}(p...)
        end
        $cola(c::Color, alpha::Real) = convert($cola, c, alpha)
        $cola() = $cola{$elty}($(zfields...))
    end)
end

eltype_default{C<:AbstractRGB  }(::Type{C}) = U8
eltype_default{C<:AbstractGray }(::Type{C}) = U8
eltype_default{C<:Color  }(::Type{C}) = Float32
eltype_default{P<:Colorant        }(::Type{P}) = eltype_default(color_type(P))

# Upper bound on element type for each color type
eltype_ub{P<:Colorant        }(::Type{P}) = eltype_ub(eltype_default(P))
eltype_ub{T<:FixedPoint   }(::Type{T}) = Fractional
eltype_ub{T<:AbstractFloat}(::Type{T}) = AbstractFloat

ctypes = union(setdiff(parametric3, [RGB1,RGB4]), [Gray])

# the arg list for C below should be identical to ctypes above.
for (C, acol, cola) in [(DIN99d, :ADIN99d, :DIN99dA),
                        (DIN99o, :ADIN99o, :DIN99oA),
                        (DIN99, :ADIN99, :DIN99A),
                        (HSI, :AHSI, :HSIA),
                        (HSL, :AHSL, :HSLA),
                        (HSV, :AHSV, :HSVA),
                        (LCHab, :ALCHab, :LCHabA),
                        (LCHuv, :ALCHuv, :LCHuvA),
                        (LMS, :ALMS, :LMSA),
                        (Lab, :ALab, :LabA),
                        (Luv, :ALuv, :LuvA),
                        (XYZ, :AXYZ, :XYZA),
                        (YCbCr, :AYCbCr, :YCbCrA),
                        (YIQ, :AYIQ, :YIQA),
                        (xyY, :AxyY, :xyYA),
                        (BGR, :ABGR, :BGRA),
                        (RGB, :ARGB, :RGBA),
                        (Gray, :AGray, :GrayA)]
    fn  = Expr(:tuple, fieldnames(C)...)
    cfn = Expr(:tuple, colorfields(C)...)
    elty = eltype_default(C)
    ub   = eltype_ub(C)
    Csym = C.name.name
    @eval @make_constructors $Csym $fn $elty
    @eval @make_alpha $Csym $acol $cola $fn $cfn $ub $elty
end

# RGB1 and RGB4 require special handling because of the alphadummy field
@make_constructors RGB1 (r,g,b) U8
@make_constructors RGB4 (r,g,b) U8
alphacolor{C<:Gray24}(::Type{C}) = AGray32
alphacolor{C<:RGB24}(::Type{C}) = ARGB32
alphacolor{C<:RGB1}(::Type{C}) = ARGB
alphacolor{C<:RGB4}(::Type{C}) = ARGB
coloralpha{C<:RGB1}(::Type{C}) = RGBA
coloralpha{C<:RGB4}(::Type{C}) = RGBA

"""
`alphacolor(RGB)` returns `ARGB`, i.e., the corresponding transparent
color type with storage order (alpha, color).
""" alphacolor

"""
`coloralpha(RGB)` returns `RGBA`, i.e., the corresponding transparent
color type with storage order (color, alpha).
""" coloralpha


text:
# https://discourse.julialang.org/t/aliases-for-union-t-nothing-and-union-t-missing/15402/41
macro optional(ex)
    return :(Union{$ex,Nothing})
end

string_datetime() = replace(string(now()), (":" => "_"))

function generate_data_subdir(
    callerfile; parent=dirname(@__DIR__), subdir=string_datetime()
)
    datadir = joinpath(parent, "data", basename(callerfile), subdir)
    @info "Generating data directory" datadir
    mkpath(datadir)
    return datadir
end

function local_grid(npoints::Integer, percentage::Real; scale=1.0f0, type=:centered)
    @argcheck zero(percentage) < percentage <= one(percentage)
    @argcheck type in (:centered, :negative, :positive)
    @argcheck !iszero(scale)
    width = percentage * scale * npoints
    if type == :centered
        translation = width / 2.0f0
    elseif type == :negative
        translation = width
    elseif type == :positive
        translation = 0.0f0
    end
    return [n * percentage * scale - translation for n in 0:(npoints - 1)]
end

function controller_shape(controller)
    # this method is brittle as any function inside the Chain
    # will not be identified, could be a problem if those change dimensions

    # Flux Layers have fields (:weight, :bias, :σ)
    # FastLayers have fields (:out, :in, :σ, :initial_params, :bias)
    dims_input = [l.in for l in controller.layers[1:end] if typeof(l) <: FastDense]
    dims_output = [l.out for l in controller.layers[1:end] if typeof(l) <: FastDense]
    return push!(dims_input, pop!(dims_output))
end

function scaled_sigmoids(control_ranges)
    return (x, p) -> [
        (control_ranges[i][2] - control_ranges[i][1]) * sigmoid_fast(x[i]) +
        control_ranges[i][1] for i in eachindex(control_ranges)
    ]
end

find_array_param(arr::AbstractArray{T}) where {T} = T

struct ControlODE{uType<:Real,tType<:Real}
    controller::Function
    system!::Function
    u0::AbstractVector{uType}
    tspan::Tuple{tType,tType}
    tsteps::AbstractVector{tType}
    integrator::AbstractODEAlgorithm
    sensealg::AbstractSensitivityAlgorithm
    prob::AbstractODEProblem
    function ControlODE(
        controller,
        system!,
        u0,
        tspan;
        tsteps::Union{Nothing, AbstractVector{<:Real}}=nothing,
        Δt::Union{Nothing,Real}=nothing,
        npoints::Union{Nothing,Real}=nothing,
        input::Symbol=:state,
        integrator=INTEGRATOR,  # Tsit5()
        sensealg=SENSEALG,
    )
        # check tsteps construction
        if !isnothing(tsteps)
            @argcheck tspan[begin] == tsteps[begin]
            @argcheck tspan[end] == tsteps[end]
        elseif !isnothing(Δt)
            tsteps = range(tspan...; step=Δt)
        elseif !isnothing(npoints)
            tsteps = range(tspan...; length=npoints)
        else
            # @argcheck !isnothing(tsteps) || !isnothing(Δt) || !isnothing(npoints)
            throw(
                ArgumentError(
                    "Either tsteps, Δt or npoints keyword must be provided (they follow that order of priority if multiple are given).",
                ),
            )
        end

        # check domain types
        time_type = find_array_param(tsteps)
        space_type = find_array_param(u0)
        control_type = find_array_param(controller(u0, initial_params(controller)))
        @argcheck space_type == control_type

        # construct ODE problem
        dudt!(du, u, p, t) = system!(du, u, p, t, controller; input)
        prob = ODEProblem(dudt!, u0, tspan)

        return new{space_type,time_type}(
            controller, system!, u0, tspan, tsteps, integrator, sensealg, prob
        )
    end
end
# TODO follow recommended interface https://github.com/SciML/CommonSolve.jl
function solve(code::ControlODE, params; kwargs...)
    return solve(
        code.prob,
        code.integrator;
        p=params,
        saveat=code.tsteps,
        sensealg=code.sensealg,
        kwargs...,
    )
end

function chebyshev_interpolation(
    timepoints, values; undersample=length(timepoints) ÷ 4::Integer
)
    @argcheck length(timepoints) == length(values)
    @argcheck undersample <= length(timepoints)
    space = Chebyshev(Interval(timepoints[1], timepoints[end]))
    # http://juliaapproximation.github.io/ApproxFun.jl/stable/faq/
    # Create a Vandermonde matrix by evaluating the basis at the grid
    V = Array{Float64}(undef, length(timepoints), undersample)
    for k in 1:undersample
        V[:, k] = Fun(space, [zeros(k - 1); 1]).(timepoints)
    end
    return Fun(space, V \ vec(values))  # chebyshev_interpolation as one-variable function
end

function collocation_preconditioner(u0, collocation; plot=true, kwargs...)
    @info "Solving through collocation..."
    infopt_model, time_collocation, states_collocation, controls_collocation = collocation(
        u0; kwargs...
    )
    num_controls = size(controls_collocation, 1)
    # interpolations = [
    #     DataInterpolations.LinearInterpolation(controls_collocation[i, :], time_collocation) for i in 1:num_controls
    # ]
    interpolations = [
        chebyshev_interpolation(time_collocation, controls_collocation[i, :]) for
        i in 1:num_controls
    ]
    function control_profile(t, p)
        Zygote.ignore() do
            return [interpolations[i](t) for i in 1:num_controls]
        end
    end
    if plot
        for c in 1:num_controls
            display(
                lineplot(
                    t -> control_profile(t, nothing)[c],
                    time_collocation[begin],
                    time_collocation[end];
                    xlim=(time_collocation[begin], time_collocation[end]),
                ),
            )
            plot_collocation(
                controls_collocation[c, :], interpolations[c], time_collocation
            )
        end
    end
    return control_profile,
    infopt_model, time_collocation, states_collocation,
    controls_collocation
end

# Feller, C., & Ebenbauer, C. (2014).
# Continuous-time linear MPC algorithms based on relaxed logarithmic barrier functions.
# IFAC Proceedings Volumes, 47(3), 2481–2488.
# https://doi.org/10.3182/20140824-6-ZA-1003.01022

function quadratic_relaxation(z, δ)
    return one(typeof(z)) / 2 * (((z - 2δ) / δ)^2 - one(typeof(z))) - log(δ)
end
exponential_relaxation(z, δ) = exp(one(typeof(z)) - z / δ) - one(typeof(z)) - log(δ)
function relaxed_log_barrier(z; δ=0.3f0)
    return max(z > δ ? -log(z) : exponential_relaxation(z, δ), zero(typeof(z)))
end
function relaxed_log_barrier(z, lower, upper; δ=(upper - lower) / convert(typeof(z), 2))
    return relaxed_log_barrier(z - lower; δ) + relaxed_log_barrier(upper - z; δ)
end

indicator_function(z; δ) = min(z, zero(typeof(z)))


text:
using Flux
using Flux: onehot
using Flux.Data.Sentiment
using Flux.Data: Tree, leaves

function getdata()
    traintrees = Sentiment.train()

    ## Get the raw labels and phrases as separate trees.
    labels  = map.(x -> x[1], traintrees)
    phrases = map.(x -> x[2], traintrees)

    ## All tokens in the training set.
    tokens = vcat(map(leaves, phrases)...)

    ## Count how many times each token appears.
    freqs = Dict{String,Int}()
    for t in tokens
      freqs[t] = get(freqs, t, 0) + 1
    end

    ## Replace singleton tokens with an "unknown" marker.
    ## This roughly cuts our "alphabet" of tokens in half.
    phrases = map.(t -> get(freqs, t, 0) == 1 ? "UNK" : t, phrases)

    ## Our alphabet of tokens.
    alphabet = unique(vcat(map(leaves, phrases)...))

    ## One-hot-encode our training data with respect to the alphabet.
    phrases_e = map.(t -> t == nothing ? t : onehot(t, alphabet), phrases)
    labels_e  = map.(t -> onehot(t, 0:4), labels)

    train = map.(tuple, phrases_e, labels_e)
    return train, alphabet
end


text:
module MatrixBase

using MatrixMarket
using Base.Threads

ex = :(macro dowhile(branch, sym, cond)
           quote
               s = string($sym)
               $sym != :while && error("expected :while symbol, got :$s")
               $(esc(branch))
               while $(esc(cond))
                   $(esc(branch))
               end
           end
       end)

ex.args[1].args[1] = :do
@eval $ex

abstract type GenericCSRMat end

mutable struct CSRMat{T<:Any} <: GenericCSRMat

  # Is complex
  is_complex::Bool

  # nrows, ncols
  Dims::NTuple{2, Int}

  # Iterators
  X::Tuple{Base.OneTo{Int64},Base.OneTo{Int64}}

  # Data arrays
  csrVals::Vector{T}
  csrRows::Vector{Int32}
  csrCols::Vector{Int32}
  diagIdx::Vector{Int32} #for ILU etc.

  # Avg number of nz elements in a row
  N::Int

  function CSRMat{T}(path::String) where T

    is_complex = (T == ComplexF16 || T == ComplexF32 || T == ComplexF64)

    M = MatrixMarket.mmread(path)

    #collect basic info
    (nrows, ncols) = size(M)
    if nrows != ncols; error("Rectangle matrices are not allowed"); end

    (rows, cols) = axes(M)

    prec = eltype(M)

    nnz = 0
    for i in M
      if i != 0.0; nnz += 1; end
    end

    println("Element type : ", prec,", number of nnz : ", nnz, ", number of rows : ", nrows, ", number of cols : ", ncols)

    #convert into CSR format.
    csrVals = Vector{prec}(undef, nnz)
    csrRows = Vector{Int32}(undef, nrows+1)
    csrCols = Vector{Int32}(undef, nnz)
    diagIdx = Vector{Int32}(undef, nrows)

    #construct CSR matrix (with fortran indexing convention)
    csrRows[1] = 1

    e = 1
    c = 1
    d = 1

    avg_row_nnz = 0
    #
    for j in rows
      row_nnz = 0
      for i in cols
        if M[j,i] != 0.0

          csrVals[e] = convert(T, M[j,i])
          csrCols[c] = i
          if j == i
            diagIdx[d] = i; d +=1
          end #store diag index

          row_nnz += 1; e += 1; c += 1

        end #if
      end #for i
      csrRows[j+1] = csrRows[j] + row_nnz

      avg_row_nnz += row_nnz
    end #for j

    if csrRows[nrows+1] != nnz+1; error("Conversion failed, incorrect number of nnz detected."); end

    avg_row_nnz = round( Float64(avg_row_nnz) / Float64(nrows))
    # call constructor
    new(is_complex, (nrows, ncols), (rows, cols), csrVals, csrRows, csrCols, view(diagIdx, 1:(d-1)), avg_row_nnz)

  end #CSRMat{T}

end #CSRMat

function print_CSRMat_info(m::GenericCSRMat)
  println(" ")
  println("General info for ", typeof(m), ": ")
  println("Element type : ", typeof(m.csrVals[1]),", number of nnz : ", (m.csrRows[m.Dims[1]+1] - 1) , ", number of rows : ", m.Dims[1], ", number of cols : ", m.Dims[2], " average number of nz elements in a row ", m.N)
end

function csrmv(b::AbstractArray, m::GenericCSRMat, x::AbstractArray)

@threads  for j in m.X[1]
#  for j in m.X[1]
    offset  = m.csrRows[j] - m.csrRows[1]
    row_nnz = m.csrRows[j+1] - m.csrRows[j]
    b[j]    = 0.0

    for i in 1:row_nnz
      cid   = m.csrCols[offset+i]
      b[j] += m.csrVals[offset+i]*x[cid]
    end

  end

end

function csrmv(m::GenericCSRMat, x::AbstractArray)

   b = zero(typeof(x)(undef, length(x)))
@threads  for j in m.X[1]
#  for j in m.X[1]
    offset  = m.csrRows[j] - m.csrRows[1]
    row_nnz = m.csrRows[j+1] - m.csrRows[j]
    b[j]    = 0.0

    for i in 1:row_nnz
      cid   = m.csrCols[offset+i]
      b[j] += m.csrVals[offset+i]*x[cid]
    end

  end

  return b
end

function ilu0(M::GenericCSRMat)

  println("Perform ILU decomposition on matrix ", typeof(M) )

  m = deepcopy(M)

  iw  = Vector{Int}(undef, m.Dims[1])

  for i in m.X[1]
    iw .=@. -1 #elementwise assingment

    for k in m.csrRows[i]:(m.csrRows[i+1] - 1); iw[m.csrCols[k]] = k; end

    j = m.csrRows[i]

    @do begin

      jrow = m.csrRows[j]
      if i <= jrow; break; end

      m.csrVals[j] *= m.csrVals[m.diagIdx[jrow]]

      tl = m.csrVals[j]

      for jj in (m.diagIdx[jrow] + 1):(ia[jrow+1] - 1)

        jw = iw[m.csrCols[jj]]
        if jw != -1; l[jw] -= (tl * l[jj]); end

      end #for jj
      j += 1

    end :while j <= (m.csrRows[i+1] - 1)

    m.diagIdx[i] = j

    if jrow != i
      error("ILU_CR - Fatal error! JROW != I, JROW = ", jrow,", I = ", i)
    end

    if  m.csrVals[j] == 0.0
      error("ILU_CR - Fatal error! Zero pivot on step I = ", i,", L[j] = 0.0 for j = ", j)
    end

    m.csrVals[j] = 1.0 / m.csrVals[j];
  end #for i

  for k in m.X[1]; m.csrVals[m.diagIdx[k]] = 1.0 / m.csrVals[m.diagIdx[k]]; end

  return m

end #ilu0

function ilu0(out::AbstractArray, m::GenericCSRMat, inp::AbstractArray)

  out .=@. inp

#  Solve L * w = w where L is unit lower triangular.

  for i in 2:length(tmp)
    for j in m.csrRows[i]:(m.diagIdx[i]-1); out[i] -= m.csrVals[i]*out[m.csrCols[j]]; end
  end

#  Solve U * w = w, where U is upper triangular.

  for i in length(tmp):-1:1
    for j in (m.diagIdx[i] + 1):m.csrRows[i+1]; out[i] -= m.csrVals[j]*out[m.csrCols[j]]; end
    out[i] /= m.csrVals[m.diagIdx[i]]
  end
end #ilu0

end #MatrixBase

max_stars_repo_name: alexstrel/QJulia

max_issues_repo_name: alexstrel/QJulia

max_forks_repo_name: alexstrel/QJulia