text:
pkg_name = "TALib"
depsjl = joinpath(dirname(@__FILE__), "..", "deps", "deps.jl")
println(depsjl)
if isfile(depsjl)
    include(depsjl)
else
    error("$pkg_name not properly installed. Please run Pkg.build(\"$pkg_name\")")
end

include("constants.jl")
include("path.jl")

include("describe.jl")
include("tools.jl")

D_INDICATORS, INDICATORS, D_GROUPS = get_ta_func_constants()

for filename in ["ta_func_api_gen_level0.jl", "ta_func_api_gen_level1.jl",
        "ta_func_api_gen_level2_dataframe.jl", "ta_func_api_gen_level2_timearray.jl"]
    include(filename)
end

function generate_header()
    "# Auto generated file"
end

function generate_footer()
    "# end of auto generated file"
end

function generate_code(d::OrderedDict{Symbol,Any}, _generate_header::Function, _generate_code::Function, _generate_footer::Function)
    s_code = _generate_header()
    s_code *= "\n"
    for symb in keys(d)
        #println("## Generate code for $symb")
        s_code *= _generate_code(d, symb)
    end
    s_code *= "\n"
    s_code *= _generate_footer()
    s_code
end

function generate_all_code(d::OrderedDict{Symbol,Any})
    path = joinpath(basepath(), "generated")
    println("# Generate level 0 code")
    filename = joinpath(path, "ta_func_api_code_level0.jl")
    s_code = generate_code(d, generate_header, generate_ta_func_raw, generate_footer)
    f = open(filename, "w")
    write(f, s_code)
    close(f)

    println("# Generate level 1 code")
    filename = joinpath(path, "ta_func_api_code_level1.jl")
    s_code = generate_code(d, generate_header, generate_ta_func_with_arrays, generate_footer)
    f = open(filename, "w")
    write(f, s_code)
    close(f)

    println("# Generate level 2 code - DataFrames")
    filename = joinpath(path, "ta_func_api_code_level2_dataframes.jl")
    s_code = generate_code(d, generate_header_ta_func_with_dataframes, generate_ta_func_with_dataframes, generate_footer)
    f = open(filename, "w")
    write(f, s_code)
    close(f)

    println("# Generate level 2 code - TimeArrays")
    filename = joinpath(path, "ta_func_api_code_level2_timearrays.jl")
    s_code = generate_code(d, generate_header_ta_func_with_timearray, generate_ta_func_with_timearray, generate_footer)
    f = open(filename, "w")
    write(f, s_code)
    close(f)
end

generate_all_code(D_INDICATORS)


text:
chains = Vector{Vector{Vector{Float64}}}(undef, I_field)
folder="test/simulation/batch5 NT200 Dgain"

for i in 1 : I_field
    chains[i] = Vector{Vector{Float64}}(undef, 2)
    chains[i][1] = Vector{Float64}(undef, 0)
    chains[i][2] = Vector{Float64}(undef, 0)
    for resp in batch_size:batch_size:N_T
        @load string(folder,"/rep_1_item_", I_operational + i, "_resp_", resp, "_chain.jld2") chain
        r = Int64(resp/batch_size)
        for iter in 1:iter_mcmc_item
            push!(chains[i][1],chain[iter][1])
            push!(chains[i][2],chain[iter][2])
        end
    end
end

using Plots
plots=Vector{Plots.Plot}(undef, 5)
ma_window=1000
step_size = 1
starting_sample = Int64(iter_mcmc_item * (N_T/batch_size - 3 ))
for p in 1:5
    plots_p = Vector{Plots.Plot}(undef, 2)
    item=p+20

ma_a_1 =[sum(@view chains[item][1][i:(i+ma_window-1)])/ma_window for i in 1:(length(chains[item][1])-(ma_window-1))][starting_sample:step_size:end]
plots_p[1]=plot(ma_a_1);
plot!(plots_p[1], chains[item][1][(ma_window+starting_sample):step_size:end], alpha=0.2);
vline!(plots_p[1], ((collect((iter_mcmc_item-ma_window):(iter_mcmc_item):(iter_mcmc_item * N_T/batch_size)-starting_sample))./step_size) .+1  );
hline!(plots_p[1], [items[I_operational+item].parameters.a], ylim = (0,4) )

ma_b_1 =[sum(@view chains[item][2][i:(i+ma_window-1)])/ma_window for i in 1:(length(chains[item][2])-(ma_window-1))][starting_sample:step_size:end]
plots_p[2]=plot(ma_b_1);
plot!(plots_p[2], chains[item][2][(ma_window+starting_sample):step_size:end], alpha=0.2);
vline!(plots_p[2],collect((iter_mcmc_item-ma_window+starting_sample):iter_mcmc_item:(iter_mcmc_item * N_T/batch_size))./step_size);
hline!(plots_p[2],[items[I_operational+item].parameters.b], ylim = (-3,3));
plots[p] = plot(plots_p..., layout = (2, 1));
end

savefig(plot(plots..., layout = (1,5), legend = false, size=(1600,1200)),string(folder,"/file.pdf"))
plot(plots..., layout = (1,3), legend = false)

ext: jl


text:
export OutputContext, @rocprint, @rocprintln

"Internal representation of a static string."
struct DeviceStaticString{N} end
Base.sizeof(dss::DeviceStaticString{N}) where N = N

function Base.unsafe_load(ptr::DevicePtr{DeviceStaticString{N},AS.Global}) where N
    vec_ptr = convert(Ptr{UInt8}, ptr)
    vec_raw = Base.unsafe_wrap(Vector{UInt8}, vec_ptr, (N,))
    idx = findfirst(x->x==0, vec_raw)
    idx = idx === nothing ? N : idx
    return vec_raw[1:idx-1]
end
Base.unsafe_store!(ptr::DevicePtr{<:DeviceStaticString}, x) = nothing

struct OutputContext{HC}
    hostcall::HC
end
function OutputContext(io::IO=stdout; agent=get_default_agent(), buf_len=2^16, kwargs...)
    hc = HostCall(Int64, Tuple{DeviceStaticString{buf_len}}; agent=agent, continuous=true, kwargs...) do bytes
        print(io, String(bytes))
        Int64(length(bytes))
    end
    OutputContext(hc)
end

### macros

macro rocprint(oc, str)
    rocprint(oc, str)
end
macro rocprintln(oc, str)
    rocprint(oc, str, true)
end

### parse-time helpers

function rocprint(oc, str, nl=false)
    ex = Expr(:block)
    if !(str isa Expr)
        str = Expr(:string, str)
    end
    @assert str.head == :string
    for (idx,arg) in enumerate(str.args)
        if nl && idx == length(str.args)
            arg *= '\n'
        end
        N = rocprint!(ex, 1, oc, arg)
        N = rocprint!(ex, N, oc, '\0')
        dstr = DeviceStaticString{N}()
        push!(ex.args, :(hostcall!($(esc(oc)).hostcall, $dstr)))
    end
    return ex
end
function rocprint!(ex, N, oc, str::String)
    # TODO: push!(ex.args, :($rocprint!($(esc(oc)), $(Val(Symbol(str))))))
    off = N
    ptr = :(Base.unsafe_convert(DevicePtr{UInt8,AS.Global}, $(esc(oc)).hostcall.buf_ptr))
    for byte in codeunits(str)
        push!(ex.args, :(Base.unsafe_store!($ptr, $byte, $off)))
        off += 1
    end

    return off
end
function rocprint!(ex, N, oc, char::Char)
    @assert char == '\0' "Non-null chars not yet implemented"
    byte = UInt8(char)
    ptr = :(Base.unsafe_convert(DevicePtr{UInt8,AS.Global}, $(esc(oc)).hostcall.buf_ptr))
    push!(ex.args, :(Base.unsafe_store!($ptr, $byte, $N)))
    return N+1
end
function rocprint!(ex, N, oc, iex::Expr)
    for arg in iex.args
        N = rocprint!(ex, N, oc, arg)
    end
    return N
end
#= TODO: Support printing arbitrary values?
function rocprint!(ex, N, oc, sym::Symbol)
    push!(ex.args, :($rocprint!($(esc(oc)), $(QuoteNode(sym)))))
    return N+4
end
=#

### runtime helpers

#= TODO: LLVM hates me, but this should eventually work
# FIXME: Pass N and offset oc.buf_ptr appropriately
@inline @generated function rocprint!(oc::OutputContext, ::Val{str}) where str
    T_int1 = LLVM.Int1Type(JuliaContext())
    T_int32 = LLVM.Int32Type(JuliaContext())
    T_pint8 = LLVM.PointerType(LLVM.Int8Type(JuliaContext()))
    T_pint8_global = LLVM.PointerType(LLVM.Int8Type(JuliaContext()), convert(Int, AS.Global))
    T_nothing = LLVM.VoidType(JuliaContext())
    llvm_f, _ = create_function(T_nothing, [T_pint8_global])
    mod = LLVM.parent(llvm_f)
    T_intr = LLVM.FunctionType(T_nothing, [T_pint8_global, T_pint8, T_int32, T_int32, T_int1])
    intr = LLVM.Function(mod, "llvm.memcpy.p1i8.p0i8.i32", T_intr)
    Builder(JuliaContext()) do builder
        entry = BasicBlock(llvm_f, "entry", JuliaContext())
        position!(builder, entry)
        str_ptr = globalstring_ptr!(builder, String(str))
        buf_ptr = parameters(llvm_f)[1]
        # NOTE: There's a hidden alignment parameter (argument 4) that's not documented in the LangRef
        call!(builder, intr, [buf_ptr, str_ptr, ConstantInt(Int32(length(string(str))), JuliaContext()), ConstantInt(Int32(2), JuliaContext()), ConstantInt(T_int1, 0)])
        ret!(builder)
    end
    Core.println(unsafe_string(LLVM.API.LLVMPrintValueToString(LLVM.ref(llvm_f))))
    call_function(llvm_f, Nothing, Tuple{DevicePtr{UInt8,AS.Global}}, :((oc.hostcall.buf_ptr,)))
end
=#


text:
include("scoring.jl")
using DataFrames
using DataFramesMeta

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Type def
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

abstract Squad

immutable Offense <: Squad
  qb::DataFrame
  rb::DataFrame
  wr::DataFrame
  te::DataFrame
end

immutable DefenseST <: Squad
  def::DataFrame
  wr::DataFrame
end

immutable Kicker <: Squad
  k::DataFrame
end

# Season type - holds tables for positions in a given year
immutable Season
  off::Offense
  def::DefenseST
  k::Kicker

  function Season(year::AbstractString)
    tables = map(p -> with_team_abbr!(readtable(table_path(year, p))), ["QB", "RB", "WR", "TE", "DEF", "K"])
    Season(tables[1], tables[2], tables[3], tables[4], tables[5], tables[6])
  end

  function Season(year::Int64)
    Season(string(year))
  end

  function Season(qb::DataFrame, rb::DataFrame, wr::DataFrame, te::DataFrame, def::DataFrame, k::DataFrame)
    new(Offense(qb, rb, wr, te), DefenseST(def, wr), Kicker(k))
  end

  function Season(off::Offense, def::DefenseST, k::Kicker)
    new(off, def, k)
  end
end

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Constant table data
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

const ABBR_LOOKUP = Dict(
  "Arizona Cardinals" => "ARI",
  "Atlanta Falcons" => "ATL",
  "Baltimore Ravens" => "BAL",
  "Buffalo Bills" => "BUF",
  "Carolina Panthers" => "CAR",
  "Chicago Bears" => "CHI",
  "Cincinnati Bengals" => "CIN",
  "Cleveland Browns" => "CLE",
  "Dallas Cowboys" => "DAL",
  "Denver Broncos" => "DEN",
  "Detroit Lions" => "DET",
  "Green Bay Packers" => "GNB",
  "Houston Texans" => "HOU",
  "Indianapolis Colts" => "IND",
  "Jacksonville Jaguars" => "JAC",
  "Kansas City Chiefs" => "KAN",
  "Miami Dolphins" => "MIA",
  "Minnesota Vikings" => "MIN",
  "New England Patriots" => "NWE",
  "New Orleans Saints" => "NOR",
  "New York Giants" => "NYG",
  "New York Jets" => "NYJ",
  "Oakland Raiders" => "OAK",
  "Philadelphia Eagles" => "PHI",
  "Pittsburgh Steelers" => "PIT",
  "San Diego Chargers" => "SDG",
  "San Francisco 49ers" => "SFO",
  "Seattle Seahawks" => "SEA",
  "St. Louis Rams" => "STL",
  "Tampa Bay Buccaneers" => "TAM",
  "Tennessee Titans" => "TEN",
  "Washington Redskins" => "WAS"
)

const OFF_COL_MAP = Any[
  # Offensive
  (:rush_yds, :RushYds),
  (:rush_td, :RushTD),
  (:rec_yds, :RecYds),
  (:rec_td, :RecTD),
  (:pass_yds, :Yds),
  (:pass_td, :TD),
  (:pass_int, :Int),
  (:sack, :Sack),
  (:fum_l, :FumL),
  # Def / ST
  # (:pr_td, :PRTD),
  # (:kr_td, :KRTD)
]

const DEF_COL_MAP = Any[
  # (:pr_td, :PRTD),
  # (:kr_td, :KRTD),
  (:games, :G),
  (:papg, symbol("Pts/G")),
  (:int_td, :IntTD),
  (:fum_td, :DefTD), # not quite right
  (:sack, :Sack)
  # (:sfty, :Safety) # Not available?
]

const WR_ST_COL_MAP = Any[
  (:pr_td, :PRTD),
  (:kr_td, :KRTD)
]

const K_COL_MAP = Any[
  (:xp_made, :XPM),
  (:xp_att, :XPA),
  (:fg_made, :FGM),
  (:fg_att, :FGA),
  (:f0019, symbol("M0-19")),
  (:f2029, symbol("M20-29")),
  (:f3039, symbol("M30-39")),
  (:f4049, symbol("M40-49")),
  (:f50, symbol("M50+"))
]

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Private helpers
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

# Get the table logical path relative to current script by year and position
table_logical_path(year::String, position::AbstractString) = joinpath(dirname(@__FILE__), "..", "data", year, position)

# Get the FS path relative to the current location for the year and position
table_path(year::String, position::AbstractString) = string(table_logical_path(year, position), ".csv")

# Ensure that tables have a normalized key for access by team
function with_team_abbr!(df::DataFrame)
  # XXX Can't use @transform for this?
  df[:team_abbr] = map(team -> length(team) == 3 ? team : ABBR_LOOKUP[team], df[:Team])
  df
end

# Add a fantasy score column to the data frame
function score_table(df::DataFrame, col_map::Array, f::Function)
  # Julia doesn't support conditional list comprehensions or tuple destructuring,
  # so this is a bit of a mess. TODO - implement in julia?
  columns = [(pair[1], haskey(df, pair[2]) ? df[pair[2]] : 0) for pair in col_map]
  @transform(df, score = f(; columns...))
end

# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Public functions on Seasons and Squads
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

# Filter a season by team
function filter(season::Season, team::AbstractString)
  Season(filter(season.off, team), filter(season.def, team), filter(season.k, team))
end

function filter(squad::Offense, team::AbstractString)
  filtered = [@where(getfield(squad, f), :team_abbr .== team) for f in [:qb, :rb, :wr, :te]]
  Offense(filtered...)
end

function filter(squad::Kicker, team::AbstractString)
  Kicker(@where(squad.k, :team_abbr .== team))
end

function filter(squad::DefenseST, team::AbstractString)
  filtered = [@where(getfield(squad, f), :team_abbr .== team) for f in [:def, :wr]]
  DefenseST(filtered...)
end

# Add fantasy score column to all frames in a season
function score(season::Season)
  Season(score(season.off), score(season.def), score(season.k))
end

function score(squad::Offense)
  scored = [score_table(getfield(squad, f), OFF_COL_MAP, score_off) for f in [:qb, :rb, :wr, :te]]
  Offense(scored...)
end

function score(squad::Kicker)
  Kicker(score_table(squad.k, K_COL_MAP, score_k))
end

function score(squad::DefenseST)
  # Score defensive team alone, sort by team
  def = sort(score_table(squad.def, DEF_COL_MAP, score_def_st), cols = [:team_abbr])
  # Score offensive team on their special teams plays
  wr = score_table(squad.wr, WR_ST_COL_MAP, score_def_st)
  # Group offensive players by their team to get an aggregate, sort in same
  # order as defense
  g_wr = sort(by(wr, :team_abbr, df -> sum(df[:score])), cols = [:team_abbr])
  # Combine defense and special teams by team. Add original defensive score in
  # a separate column for reference if needed.
  t_def = transform(def, score_def = def[:score], score = def[:score] + g_wr[:x1])
  DefenseST(t_def, wr)
end

max_stars_repo_name: jnu/FantasyFootball

max_issues_repo_name: jnu/FantasyFootball

max_forks_repo_name: jnu/FantasyFootball


text:
# ------------------------------------------------------------------
# Licensed under the MIT License. See LICENSE in the project root.
# ------------------------------------------------------------------

"""
    Functional(func)

The transform that applies a `func` elementwise.

    Functional(col₁ => func₁, col₂ => func₂, ..., colₙ => funcₙ)

Apply the corresponding `funcᵢ` function to each `colᵢ` column.

# Examples

```julia
Functional(cos)
Functional(sin)
Functional(:a => cos, :b => sin)
Functional("a" => cos, "b" => sin)
```
"""
struct Functional{F} <: Stateless
  func::F
end

Functional(pairs::Pair{Symbol}...) =
  Functional(NamedTuple(pairs))

Functional(pairs::Pair{K}...) where {K<:AbstractString} =
  Functional(NamedTuple(Symbol(k) => v for (k, v) in pairs))

Functional() = throw(ArgumentError("Cannot create a Functional object without arguments."))

# known invertible functions
inverse(::typeof(log))  = exp
inverse(::typeof(exp))  = log
inverse(::typeof(cos))  = acos
inverse(::typeof(acos)) = cos
inverse(::typeof(sin))  = asin
inverse(::typeof(asin)) = sin
inverse(::typeof(cosd))  = acosd
inverse(::typeof(acosd)) = cosd
inverse(::typeof(sind))  = asind
inverse(::typeof(asind)) = sind
inverse(::typeof(identity)) = identity

# fallback to nothing
inverse(::Any) = nothing

isrevertible(transform::Functional) =
  !isnothing(inverse(transform.func))

isrevertible(transform::Functional{<:NamedTuple}) =
  all(!isnothing, inverse.(values(transform.func)))

_functuple(func, names) = NamedTuple(nm => func for nm in names)
_functuple(func::NamedTuple, names) = func

function apply(transform::Functional, table)
  cols = Tables.columns(table)
  names = Tables.columnnames(cols)
  funcs = _functuple(transform.func, names)

  ncols = map(names) do nm
    x = Tables.getcolumn(cols, nm)
    func = get(funcs, nm, identity)
    func.(x)
  end

  𝒯 = (; zip(names, ncols)...)
  newtable = 𝒯 |> Tables.materializer(table)
  return newtable, nothing
end

function revert(transform::Functional, newtable, cache)
  @assert isrevertible(transform) "Transform is not revertible."

  cols = Tables.columns(newtable)
  names = Tables.columnnames(cols)
  funcs = _functuple(transform.func, names)

  ocols = map(names) do nm
    x = Tables.getcolumn(cols, nm)
    func = get(funcs, nm, identity)
    invfunc = inverse(func)
    invfunc.(x)
  end

  𝒯 = (; zip(names, ocols)...)
  𝒯 |> Tables.materializer(newtable)
end


text:
function visualize(result_quantile::DataFrame,problem::Union{pbtfProblem,pbsrtfProblem};legend_position::Symbol=:topleft)
    plt=plot(size=(800,600))
    scatter!(problem.x,problem.y,markersize=5,markercolor=:green,label="data",legendfontsize=20,
             xtickfontsize=20,ytickfontsize=20,markerstrokewidth=0,legend=legend_position)
    plot!(subplot=1,problem.xgrid,result_quantile[1:problem.n, Symbol("50.0%")],linewidth=5,label="posterior",c=:blue,
          ribbon=(result_quantile[1:problem.n, Symbol("50.0%")] .- result_quantile[1:problem.n, Symbol("2.5%")],
          result_quantile[1:problem.n, Symbol("97.5%")] .- result_quantile[1:problem.n, Symbol("50.0%")]),fillalpha=0.3)
end


text:
using GrammarExpts, ACASX_GE_Tree
acasx_ge_tree(; seed=1, config...)


text:
# This file is a part of PropDicts.jl, licensed under the MIT License (MIT).

"""
    PropDict <: AbstractDict{Union{Symbol,Int},Any}

PropDicts is a dictionary for that supports

Constructors:

    PropDict(dict::AbstractDict)

    PropDict(key1 => value, key2 => value2, ...)

During construction, keys are automatically converted to `Symbol`s and
`Int`s, values that are dicts are converted to `PropDict`s.

`PropDict` support deep merging:
```julia
x = PropDict(:a => PropDict(:b => 7, :c => 5, :d => 2), :e => "foo")
y = PropDict(:a => PropDict(:c => 42, :d => nothing), :f => "bar")

z = merge(x, y)
@assert z == PropDict(
    :a => PropDict(:b=>7, :d => nothing, :c => 42),
    :e => "foo", :f => "bar"
)

PropDicts.trim_null!(z)
@assert z == PropDict(
    :a => PropDict(:b=>7, :c => 42),
    :e => "foo", :f => "bar"
)
```
"""
struct PropDict <: AbstractDict{Union{Symbol,Int},Any}
    _internal_dict::Dict{Union{Symbol,Int},Any}

    PropDict() = new(Dict{Union{Symbol,Int},Any}())

    PropDict(dict::PropDict) = new(_dict(dict))

    PropDict(dict::Dict{Union{Symbol,Int},Any}) = is_props_dict_compatible(dict) ? new(dict) : convert(PropDict, dict)
end
export PropDict

PropDict(dict::AbstractDict) = convert(PropDict, dict)

PropDict(keys_and_values::Pair...) = PropDict(Dict(keys_and_values...))

_dict(p::PropDict) = getfield(p, :_internal_dict)

Base.parent(p::PropDict) = _dict(p)

is_props_dict_compatible(d::AbstractDict) = false

function is_props_dict_compatible(d::Dict{Union{Symbol,Int},Any})
    for (k, v) in d
        if !(isa(k, Symbol) || isa(k, Int))
            return false
        end

        if isa(v, AbstractDict)
            if !is_props_dict_compatible(v)
                return false
            end
        end
    end

    return true
end

Base.convert(::Type{PropDict}, d::PropDict) = d

function Base.convert(::Type{PropDict}, d::AbstractDict)
    result = PropDict()

    for (k, v) in d
        k_new = if isa(k, Symbol) || isa(k, Int)
            k
        else
            if isa(k, String)
                if occursin(integer_expr, k)
                    parse(Int, k)
                else
                    Symbol(k)
                end
            else
                throw(ArgumentError("Key type $(typeof(k)) is not supported for PropDict dictionaries"))
            end
        end

        v_new = if isa(v, AbstractDict)
            convert(PropDict, v)
        else
            v
        end

        result[k_new] = v_new
    end

    result
end

Base.convert(::Type{Dict}, p::PropDict) = _dict(p)
Base.convert(::Type{Dict{Union{Symbol,Int}}}, p::PropDict) = _dict(p)
Base.convert(::Type{Dict{Union{Symbol,Int},Any},}, p::PropDict) = _dict(p)

import Base.==
==(a::PropDict, b::PropDict) = _dict(a) == _dict(b)

@inline Base.keys(p::PropDict) = keys(_dict(p))

@inline Base.values(p::PropDict) = values(_dict(p))

@inline function Base.getproperty(p::PropDict, s::Symbol)
    if s == :_internal_dict
        getfield(p, :_internal_dict)
    else
        _dict(p)[s]
    end
end

@inline function Base.propertynames(p::PropDict, private::Bool = false)
    names = collect(filter(x -> x isa Symbol, keys(_dict(p))))
    if private
        [names..., :_internal_dict]
    else
        names
    end
end

Base.length(p::PropDict) = length(_dict(p))

Base.getindex(p::PropDict, key) = getindex(_dict(p), key)

Base.setindex!(p::PropDict, value, key) = setindex!(_dict(p), value, key)

Base.delete!(p::PropDict, key) = delete!(_dict(p), key)

Base.convert(::Type{PropDict}, s::AbstractString) =  PropDict(JSON.parse(s))

Base.print(io::IO, p::PropDict) = JSON.print(io, _dict(p))

Base.iterate(p::PropDict) = iterate(_dict(p))
Base.iterate(p::PropDict, i) = iterate(_dict(p), i)

function Base.merge!(p::PropDict, others::PropDict...)
    PropDict(deepmerge!(_dict(p), map(_dict, (others))...))
    p
end

Base.merge(p::PropDict, others::PropDict...) =
    PropDict(deepmerge(_dict(p), map(_dict, (others))...))

const integer_expr = r"^[+-]?[0-9]+$"

function Base.read(::Type{PropDict}, filename::AbstractString; subst_pathvar::Bool = false, subst_env::Bool = false, trim_null::Bool = false)
    abs_filename = abspath(filename)

    d = JSON.Parser.parsefile(abs_filename)

    var_values = Dict{String,String}()
    if subst_pathvar
        var_values["_"] = dirname(abs_filename)
    end

    if subst_pathvar || subst_env
        substitute_vars!(d, var_values, use_env = true, ignore_missing = false, recursive = true)
    end

    if trim_null
        trim_null!(d)
    end

    PropDict(d)
end

function Base.read(::Type{PropDict}, filenames::Vector{<:AbstractString}; subst_pathvar::Bool = false, subst_env::Bool = false, trim_null::Bool = false)
    p = PropDict()
    for f in filenames
        merge!(p, read(PropDict, f, subst_pathvar = subst_pathvar, subst_env = subst_env, trim_null = false))
    end

    if trim_null
        trim_null!(_dict(p))
    end

    p
end


text:
using StatsBase, Turing
using Gadfly

# include("ASCIIPlot.jl")
import Gadfly.ElementOrFunction

# First add a method to the basic Gadfly.plot function for QQPair types (generated by Distributions.qqbuild())
Gadfly.plot(qq::QQPair, elements::ElementOrFunction...) = Gadfly.plot(x=qq.qx, y=qq.qy, Geom.point, Theme(highlight_width=0px), elements...)

# Now some shorthand functions
qqplot(x, y, elements::ElementOrFunction...) = Gadfly.plot(qqbuild(x, y), elements...)
qqnorm(x, elements::ElementOrFunction...) = qqplot(Normal(), x, Guide.xlabel("Theoretical Normal quantiles"), Guide.ylabel("Observed quantiles"), elements...)

NSamples = 5000

@model gdemo_fw() = begin
  s ~ InverseGamma(2,3)
  m ~ Normal(0, sqrt(s))
  y ~ MvNormal([m; m; m], [sqrt(s) 0 0; 0 sqrt(s) 0; 0 0 sqrt(s)])
end

@model gdemo_bk(x) = begin
  # Backward Step 1: theta ~ theta | x
  s ~ InverseGamma(2,3)
  m ~ Normal(0,sqrt(s))
  x ~ MvNormal([m; m; m], [sqrt(s) 0 0; 0 sqrt(s) 0; 0 0 sqrt(s)])
  # Backward Step 2: x ~ x | theta
  y ~ MvNormal([m; m; m], [sqrt(s) 0 0; 0 sqrt(s) 0; 0 0 sqrt(s)])
end

fw = HMCDA(NSamples, 0.9, 0.1)
# bk = Gibbs(10, PG(10,10, :s, :y), HMC(1, 0.25, 5, :m));
bk = HMCDA(50, 0.9, 0.1);

s = sample(gdemo_fw(), fw);
# describe(s)

N = div(NSamples, 50)

x = [s[:y][1]...]
s_bk = Array{Turing.Chain}(undef, N)

simple_logger = Base.CoreLogging.SimpleLogger(stderr, Base.CoreLogging.Debug)
with_logger(simple_logger) do
  i = 1
  while i <= N
    try
      s_bk[i] = sample(gdemo_bk(x), bk);
      x = [s_bk[i][:y][end]...];
      i += 1
    catch
    end
  end
do

s2 = vcat(s_bk...);
# describe(s2)

qqplot(s[:m], s2[:m])
qqplot(s[:s], s2[:s])

using Test

qqm = qqbuild(s[:m], s2[:m])
X = qqm.qx
y = qqm.qy
slope = (1 / (transpose(X) * X)[1] * transpose(X) * y)[1]
@test slope ≈ 1.0 atol=0.1

# NOTE: test for s is not stable
#       probably due to the transformation
# qqs = qqbuild(s[:s], s2[:s])
# X = qqs.qx
# y = qqs.qy
# slope = (1 / (transpose(X) * X)[1] * transpose(X) * y)[1]
# @test slope ≈ 1.0 atol=0.1


text:
using Test
using StaticArrays
using ClimateMachine.VariableTemplates

struct TestModel{A, B, C}
    a::A
    b::B
    c::C
end

struct SubModelA end
struct SubModelB end
struct SubModelC{N} end

function state(m::TestModel, T)
    @vars begin
        ρ::T
        ρu::SVector{3, T}
        ρe::T
        a::state(m.a, T)
        b::state(m.b, T)
        c::state(m.c, T)
        S::SHermitianCompact{3, T, 6}
    end
end

state(m::SubModelA, T) = @vars()
state(m::SubModelB, T) = @vars(ρqt::T)
state(m::SubModelC{N}, T) where {N} = @vars(ρk::SVector{N, T})

model = TestModel(SubModelA(), SubModelB(), SubModelC{5}())

st = state(model, Float64)

@test varsize(st) == 17

v = Vars{st}(zeros(MVector{varsize(st), Float64}))
g = Grad{st}(zeros(MMatrix{3, varsize(st), Float64}))

@test v.ρ === 0.0
@test v.ρu === SVector(0.0, 0.0, 0.0)
v.ρu = SVector(1, 2, 3)
@test v.ρu === SVector(1.0, 2.0, 3.0)

@test v.b.ρqt === 0.0
v.b.ρqt = 12.0
@test v.b.ρqt === 12.0

@test v.S === zeros(SHermitianCompact{3, Float64, 6})
v.S = SHermitianCompact{3, Float64, 6}(1, 2, 3, 2, 3, 4, 3, 4, 5)
@test v.S[1, 1] === 1.0
@test v.S[1, 3] === 3.0
@test v.S[3, 1] === 3.0
@test v.S[3, 3] === 5.0

v.S = ones(SMatrix{3, 3, Int64})
@test v.S[1, 1] === 1.0
@test v.S[1, 3] === 1.0
@test v.S[3, 1] === 1.0
@test v.S[3, 3] === 1.0

@test propertynames(v.a) == ()
@test propertynames(g.a) == ()

@test g.ρu == zeros(SMatrix{3, 3, Float64})
g.ρu = SMatrix{3, 3}(1:9)
@test g.ρu == SMatrix{3, 3, Float64}(1:9)

@test size(v.c.ρk) == (5,)
@test size(g.c.ρk) == (3, 5)

sv = similar(v)
@test typeof(sv) == typeof(v)
@test size(parent(sv)) == size(parent(v))

sg = similar(g)
@test typeof(sg) == typeof(g)
@test size(parent(sg)) == size(parent(g))

@test flattenednames(st) == [
    "ρ",
    "ρu[1]",
    "ρu[2]",
    "ρu[3]",
    "ρe",
    "b.ρqt",
    "c.ρk[1]",
    "c.ρk[2]",
    "c.ρk[3]",
    "c.ρk[4]",
    "c.ρk[5]",
    "S[1,1]",
    "S[2,1]",
    "S[3,1]",
    "S[2,2]",
    "S[3,2]",
    "S[3,3]",
]

max_stars_repo_name: mwarusz/CLIMA

max_issues_repo_name: mwarusz/CLIMA

max_forks_repo_name: mwarusz/CLIMA


text:
function helloworld()
    println("Hello World")
end

function helloworld(count::Int64)
    for i in 1:count
        println("helloworld : ", i)
    end
end

helloworld()
helloworld(2)

max_stars_repo_name: rpillar/JuliaExamples

max_issues_repo_name: rpillar/JuliaExamples

max_forks_repo_name: rpillar/JuliaExamples


text:
using Base.Dates
using BusinessDays
using Base.Test

bd = BusinessDays

###########
# types.jl
###########
bhc = bd.Brazil()
ushc = bd.USSettlement()
ukhc = bd.UKSettlement()
usnysehc = bd.USNYSE()
usgovbondhc = bd.USGovernmentBond()
hc_composite_BR_USA = CompositeHolidayCalendar([bd.Brazil(), bd.USSettlement()])
all_calendars_vec = [bhc, ushc, ukhc, hc_composite_BR_USA, usnysehc, usgovbondhc]

# two different instances of the same HolidayCalendar subtype should be equal
@test bhc == bd.Brazil()
@test ushc == bd.USSettlement()
@test bhc != ushc
@test bhc != Type(bd.Brazil) # content of list is an instance, not a singleton
@test string(bhc) == "BusinessDays.BRSettlement"

# Check typing system
@test isa(bhc,HolidayCalendar)
@test isa(ushc,HolidayCalendar)
@test isa(ukhc,HolidayCalendar)

################
## easter.jl
################

# easter dates from http://www.maa.mhn.de/StarDate/publ_holidays.html
@test_throws ErrorException bd.easter_date(Year(1100))
@test bd.easter_date(Year(1901)) == Date(1901, 04, 07)
@test bd.easter_date(Year(1902)) == Date(1902, 03, 30)
@test bd.easter_date(Year(1903)) == Date(1903, 04, 12)
@test bd.easter_date(Year(1904)) == Date(1904, 04, 03)
@test bd.easter_date(Year(1905)) == Date(1905, 04, 23)
@test bd.easter_date(Year(1906)) == Date(1906, 04, 15)
@test bd.easter_date(Year(1907)) == Date(1907, 03, 31)
@test bd.easter_date(Year(1908)) == Date(1908, 04, 19)
@test bd.easter_date(Year(1909)) == Date(1909, 04, 11)
@test bd.easter_date(Year(1910)) == Date(1910, 03, 27)
@test bd.easter_date(Year(1911)) == Date(1911, 04, 16)
@test bd.easter_date(Year(1912)) == Date(1912, 04, 07)
@test bd.easter_date(Year(1913)) == Date(1913, 03, 23)
@test bd.easter_date(Year(1914)) == Date(1914, 04, 12)
@test bd.easter_date(Year(1915)) == Date(1915, 04, 04)
@test bd.easter_date(Year(1916)) == Date(1916, 04, 23)
@test bd.easter_date(Year(1917)) == Date(1917, 04, 08)
@test bd.easter_date(Year(1918)) == Date(1918, 03, 31)
@test bd.easter_date(Year(1919)) == Date(1919, 04, 20)
@test bd.easter_date(Year(1920)) == Date(1920, 04, 04)
@test bd.easter_date(Year(1921)) == Date(1921, 03, 27)
@test bd.easter_date(Year(1922)) == Date(1922, 04, 16)
@test bd.easter_date(Year(1923)) == Date(1923, 04, 01)
@test bd.easter_date(Year(1924)) == Date(1924, 04, 20)
@test bd.easter_date(Year(1925)) == Date(1925, 04, 12)
@test bd.easter_date(Year(1926)) == Date(1926, 04, 04)
@test bd.easter_date(Year(1927)) == Date(1927, 04, 17)
@test bd.easter_date(Year(1928)) == Date(1928, 04, 08)
@test bd.easter_date(Year(1929)) == Date(1929, 03, 31)
@test bd.easter_date(Year(1930)) == Date(1930, 04, 20)
@test bd.easter_date(Year(1931)) == Date(1931, 04, 05)
@test bd.easter_date(Year(1932)) == Date(1932, 03, 27)
@test bd.easter_date(Year(1933)) == Date(1933, 04, 16)
@test bd.easter_date(Year(1934)) == Date(1934, 04, 01)
@test bd.easter_date(Year(1935)) == Date(1935, 04, 21)
@test bd.easter_date(Year(1936)) == Date(1936, 04, 12)
@test bd.easter_date(Year(1937)) == Date(1937, 03, 28)
@test bd.easter_date(Year(1938)) == Date(1938, 04, 17)
@test bd.easter_date(Year(1939)) == Date(1939, 04, 09)
@test bd.easter_date(Year(1940)) == Date(1940, 03, 24)
@test bd.easter_date(Year(1941)) == Date(1941, 04, 13)
@test bd.easter_date(Year(1942)) == Date(1942, 04, 05)
@test bd.easter_date(Year(1943)) == Date(1943, 04, 25)
@test bd.easter_date(Year(1944)) == Date(1944, 04, 09)
@test bd.easter_date(Year(1945)) == Date(1945, 04, 01)
@test bd.easter_date(Year(1946)) == Date(1946, 04, 21)
@test bd.easter_date(Year(1947)) == Date(1947, 04, 06)
@test bd.easter_date(Year(1948)) == Date(1948, 03, 28)
@test bd.easter_date(Year(1949)) == Date(1949, 04, 17)
@test bd.easter_date(Year(1950)) == Date(1950, 04, 09)
@test bd.easter_date(Year(1951)) == Date(1951, 03, 25)
@test bd.easter_date(Year(1952)) == Date(1952, 04, 13)
@test bd.easter_date(Year(1953)) == Date(1953, 04, 05)
@test bd.easter_date(Year(1954)) == Date(1954, 04, 18)
@test bd.easter_date(Year(1955)) == Date(1955, 04, 10)
@test bd.easter_date(Year(1956)) == Date(1956, 04, 01)
@test bd.easter_date(Year(1957)) == Date(1957, 04, 21)
@test bd.easter_date(Year(1958)) == Date(1958, 04, 06)
@test bd.easter_date(Year(1959)) == Date(1959, 03, 29)
@test bd.easter_date(Year(1960)) == Date(1960, 04, 17)
@test bd.easter_date(Year(1961)) == Date(1961, 04, 02)
@test bd.easter_date(Year(1962)) == Date(1962, 04, 22)
@test bd.easter_date(Year(1963)) == Date(1963, 04, 14)
@test bd.easter_date(Year(1964)) == Date(1964, 03, 29)
@test bd.easter_date(Year(1965)) == Date(1965, 04, 18)
@test bd.easter_date(Year(1966)) == Date(1966, 04, 10)
@test bd.easter_date(Year(1967)) == Date(1967, 03, 26)
@test bd.easter_date(Year(1968)) == Date(1968, 04, 14)
@test bd.easter_date(Year(1969)) == Date(1969, 04, 06)
@test bd.easter_date(Year(1970)) == Date(1970, 03, 29)
@test bd.easter_date(Year(1971)) == Date(1971, 04, 11)
@test bd.easter_date(Year(1972)) == Date(1972, 04, 02)
@test bd.easter_date(Year(1973)) == Date(1973, 04, 22)
@test bd.easter_date(Year(1974)) == Date(1974, 04, 14)
@test bd.easter_date(Year(1975)) == Date(1975, 03, 30)
@test bd.easter_date(Year(1976)) == Date(1976, 04, 18)
@test bd.easter_date(Year(1977)) == Date(1977, 04, 10)
@test bd.easter_date(Year(1978)) == Date(1978, 03, 26)
@test bd.easter_date(Year(1979)) == Date(1979, 04, 15)
@test bd.easter_date(Year(1980)) == Date(1980, 04, 06)
@test bd.easter_date(Year(1981)) == Date(1981, 04, 19)
@test bd.easter_date(Year(1982)) == Date(1982, 04, 11)
@test bd.easter_date(Year(1983)) == Date(1983, 04, 03)
@test bd.easter_date(Year(1984)) == Date(1984, 04, 22)
@test bd.easter_date(Year(1985)) == Date(1985, 04, 07)
@test bd.easter_date(Year(1986)) == Date(1986, 03, 30)
@test bd.easter_date(Year(1987)) == Date(1987, 04, 19)
@test bd.easter_date(Year(1988)) == Date(1988, 04, 03)
@test bd.easter_date(Year(1989)) == Date(1989, 03, 26)
@test bd.easter_date(Year(1990)) == Date(1990, 04, 15)
@test bd.easter_date(Year(1991)) == Date(1991, 03, 31)
@test bd.easter_date(Year(1992)) == Date(1992, 04, 19)
@test bd.easter_date(Year(1993)) == Date(1993, 04, 11)
@test bd.easter_date(Year(1994)) == Date(1994, 04, 03)
@test bd.easter_date(Year(1995)) == Date(1995, 04, 16)
@test bd.easter_date(Year(1996)) == Date(1996, 04, 07)
@test bd.easter_date(Year(1997)) == Date(1997, 03, 30)
@test bd.easter_date(Year(1998)) == Date(1998, 04, 12)
@test bd.easter_date(Year(1999)) == Date(1999, 04, 04)
@test bd.easter_date(Year(2000)) == Date(2000, 04, 23)
@test bd.easter_date(Year(2001)) == Date(2001, 04, 15)
@test bd.easter_date(Year(2002)) == Date(2002, 03, 31)
@test bd.easter_date(Year(2003)) == Date(2003, 04, 20)
@test bd.easter_date(Year(2004)) == Date(2004, 04, 11)
@test bd.easter_date(Year(2005)) == Date(2005, 03, 27)
@test bd.easter_date(Year(2006)) == Date(2006, 04, 16)
@test bd.easter_date(Year(2007)) == Date(2007, 04, 08)
@test bd.easter_date(Year(2008)) == Date(2008, 03, 23)
@test bd.easter_date(Year(2009)) == Date(2009, 04, 12)
@test bd.easter_date(Year(2010)) == Date(2010, 04, 04)
@test bd.easter_date(Year(2011)) == Date(2011, 04, 24)
@test bd.easter_date(Year(2012)) == Date(2012, 04, 08)
@test bd.easter_date(Year(2013)) == Date(2013, 03, 31)
@test bd.easter_date(Year(2014)) == Date(2014, 04, 20)
@test bd.easter_date(Year(2015)) == Date(2015, 04, 05)
@test bd.easter_date(Year(2016)) == Date(2016, 03, 27)
@test bd.easter_date(Year(2017)) == Date(2017, 04, 16)
@test bd.easter_date(Year(2018)) == Date(2018, 04, 01)
@test bd.easter_date(Year(2019)) == Date(2019, 04, 21)
@test bd.easter_date(Year(2020)) == Date(2020, 04, 12)
@test bd.easter_date(Year(2021)) == Date(2021, 04, 04)
@test bd.easter_date(Year(2022)) == Date(2022, 04, 17)
@test bd.easter_date(Year(2023)) == Date(2023, 04, 09)
@test bd.easter_date(Year(2024)) == Date(2024, 03, 31)
@test bd.easter_date(Year(2025)) == Date(2025, 04, 20)
@test bd.easter_date(Year(2026)) == Date(2026, 04, 05)
@test bd.easter_date(Year(2027)) == Date(2027, 03, 28)
@test bd.easter_date(Year(2028)) == Date(2028, 04, 16)
@test bd.easter_date(Year(2029)) == Date(2029, 04, 01)
@test bd.easter_date(Year(2030)) == Date(2030, 04, 21)
@test bd.easter_date(Year(2031)) == Date(2031, 04, 13)
@test bd.easter_date(Year(2032)) == Date(2032, 03, 28)
@test bd.easter_date(Year(2033)) == Date(2033, 04, 17)
@test bd.easter_date(Year(2034)) == Date(2034, 04, 09)
@test bd.easter_date(Year(2035)) == Date(2035, 03, 25)
@test bd.easter_date(Year(2036)) == Date(2036, 04, 13)
@test bd.easter_date(Year(2037)) == Date(2037, 04, 05)
@test bd.easter_date(Year(2038)) == Date(2038, 04, 25)
@test bd.easter_date(Year(2039)) == Date(2039, 04, 10)
@test bd.easter_date(Year(2040)) == Date(2040, 04, 01)
@test bd.easter_date(Year(2041)) == Date(2041, 04, 21)
@test bd.easter_date(Year(2042)) == Date(2042, 04, 06)
@test bd.easter_date(Year(2043)) == Date(2043, 03, 29)
@test bd.easter_date(Year(2044)) == Date(2044, 04, 17)
@test bd.easter_date(Year(2045)) == Date(2045, 04, 09)
@test bd.easter_date(Year(2046)) == Date(2046, 03, 25)
@test bd.easter_date(Year(2047)) == Date(2047, 04, 14)
@test bd.easter_date(Year(2048)) == Date(2048, 04, 05)
@test bd.easter_date(Year(2049)) == Date(2049, 04, 18)
@test bd.easter_date(Year(2050)) == Date(2050, 04, 10)
@test bd.easter_date(Year(2051)) == Date(2051, 04, 02)
@test bd.easter_date(Year(2052)) == Date(2052, 04, 21)
@test bd.easter_date(Year(2053)) == Date(2053, 04, 06)
@test bd.easter_date(Year(2054)) == Date(2054, 03, 29)
@test bd.easter_date(Year(2055)) == Date(2055, 04, 18)
@test bd.easter_date(Year(2056)) == Date(2056, 04, 02)
@test bd.easter_date(Year(2057)) == Date(2057, 04, 22)
@test bd.easter_date(Year(2058)) == Date(2058, 04, 14)
@test bd.easter_date(Year(2059)) == Date(2059, 03, 30)
@test bd.easter_date(Year(2060)) == Date(2060, 04, 18)
@test bd.easter_date(Year(2061)) == Date(2061, 04, 10)
@test bd.easter_date(Year(2062)) == Date(2062, 03, 26)
@test bd.easter_date(Year(2063)) == Date(2063, 04, 15)
@test bd.easter_date(Year(2064)) == Date(2064, 04, 06)
@test bd.easter_date(Year(2065)) == Date(2065, 03, 29)
@test bd.easter_date(Year(2066)) == Date(2066, 04, 11)
@test bd.easter_date(Year(2067)) == Date(2067, 04, 03)
@test bd.easter_date(Year(2068)) == Date(2068, 04, 22)
@test bd.easter_date(Year(2069)) == Date(2069, 04, 14)
@test bd.easter_date(Year(2070)) == Date(2070, 03, 30)
@test bd.easter_date(Year(2071)) == Date(2071, 04, 19)
@test bd.easter_date(Year(2072)) == Date(2072, 04, 10)
@test bd.easter_date(Year(2073)) == Date(2073, 03, 26)
@test bd.easter_date(Year(2074)) == Date(2074, 04, 15)
@test bd.easter_date(Year(2075)) == Date(2075, 04, 07)
@test bd.easter_date(Year(2076)) == Date(2076, 04, 19)
@test bd.easter_date(Year(2077)) == Date(2077, 04, 11)
@test bd.easter_date(Year(2078)) == Date(2078, 04, 03)

include("easter-min-max.jl")

###################################
# isholiday.jl auxiliary functions
###################################
# weekday values:
# const Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday = 1,2,3,4,5,6,7
# see query.jl on Dates module
# See also dayofweek(dt) function.
# this should go to Base.Dates
# function findweekday(weekday_target :: Int, yy :: Int, mm:: Int, occurrence :: Int, ascending :: Bool )
@test bd.findweekday(Dates.Monday, 2015, 07, 1, true) == Date(2015, 07, 06)
@test bd.findweekday(Dates.Monday, 2015, 07, 2, true) == Date(2015, 07, 13)
@test bd.findweekday(Dates.Monday, 2015, 07, 3, true) == Date(2015, 07, 20)
@test bd.findweekday(Dates.Monday, 2015, 07, 4, true) == Date(2015, 07, 27)
@test bd.findweekday(Dates.Monday, 2015, 07, 5, true) == Date(2015, 08, 03)

@test bd.findweekday(Dates.Monday, 2015, 07, 1, false) == Date(2015, 07, 27)
@test bd.findweekday(Dates.Monday, 2015, 07, 2, false) == Date(2015, 07, 20)
@test bd.findweekday(Dates.Monday, 2015, 07, 3, false) == Date(2015, 07, 13)
@test bd.findweekday(Dates.Monday, 2015, 07, 4, false) == Date(2015, 07, 06)
@test bd.findweekday(Dates.Monday, 2015, 07, 5, false) == Date(2015, 06, 29)

@test bd.findweekday(Dates.Friday, 2015, 07, 1, true) == Date(2015, 07, 03)
@test bd.findweekday(Dates.Friday, 2015, 07, 2, true) == Date(2015, 07, 10)
@test bd.findweekday(Dates.Friday, 2015, 07, 3, true) == Date(2015, 07, 17)
@test bd.findweekday(Dates.Friday, 2015, 07, 4, true) == Date(2015, 07, 24)
@test bd.findweekday(Dates.Friday, 2015, 07, 5, true) == Date(2015, 07, 31)
@test bd.findweekday(Dates.Friday, 2015, 07, 6, true) == Date(2015, 08, 07)

@test bd.findweekday(Dates.Friday, 2015, 07, 1, false) == Date(2015, 07, 31)
@test bd.findweekday(Dates.Friday, 2015, 07, 2, false) == Date(2015, 07, 24)
@test bd.findweekday(Dates.Friday, 2015, 07, 3, false) == Date(2015, 07, 17)
@test bd.findweekday(Dates.Friday, 2015, 07, 4, false) == Date(2015, 07, 10)
@test bd.findweekday(Dates.Friday, 2015, 07, 5, false) == Date(2015, 07, 03)
@test bd.findweekday(Dates.Friday, 2015, 07, 6, false) == Date(2015, 06, 26)

@test bd.findweekday(Dates.Wednesday, 2015, 07, 1, true) == Date(2015, 07, 01)
@test bd.findweekday(Dates.Wednesday, 2015, 07, 2, true) == Date(2015, 07, 08)
@test bd.findweekday(Dates.Wednesday, 2015, 07, 3, true) == Date(2015, 07, 15)
@test bd.findweekday(Dates.Wednesday, 2015, 07, 4, true) == Date(2015, 07, 22)
@test bd.findweekday(Dates.Wednesday, 2015, 07, 5, true) == Date(2015, 07, 29)
@test bd.findweekday(Dates.Wednesday, 2015, 07, 6, true) == Date(2015, 08, 05)

@test bd.findweekday(Dates.Wednesday, 2015, 07, 1, false) == Date(2015, 07, 29)
@test bd.findweekday(Dates.Wednesday, 2015, 07, 2, false) == Date(2015, 07, 22)
@test bd.findweekday(Dates.Wednesday, 2015, 07, 3, false) == Date(2015, 07, 15)
@test bd.findweekday(Dates.Wednesday, 2015, 07, 4, false) == Date(2015, 07, 08)
@test bd.findweekday(Dates.Wednesday, 2015, 07, 5, false) == Date(2015, 07, 01)
@test bd.findweekday(Dates.Wednesday, 2015, 07, 6, false) == Date(2015, 06, 24)

@test_throws ErrorException bd.findweekday(Dates.Wednesday, 2015, 07, -1, false)
@test_throws ErrorException bd.findweekday(Dates.Wednesday, 2015, 07, -1, true)

len = typemax(UInt32) + 1
d0 = Date(1950, 2, 1)
d1 = d0 + Day(len)
@test_throws ErrorException bd._createbdayscache(bhc, d0, d1)

# Create HolidayCalendar instances
hc_brazil = bd.Brazil()
hc_usa = bd.USSettlement()
hc_uk = bd.UKSettlement()
hc_usnyse = bd.USNYSE()
hc_usgovbond = bd.USGovernmentBond()

################
# bdayscache.jl
################
for usecache in [false, true]

    print("##########################\n")
    print(" Using cache: $(usecache)\n")
    print("##########################\n")

    if usecache
        bd.initcache(all_calendars_vec)
    end

    ################
    # bdays.jl
    ################
    #export
    #   isweekend, isbday, tobday, advancebdays, bdays

    dt_friday = Date(2015, 06, 26)
    dt_saturday = Date(2015, 06, 27)
    dt_sunday = Date(2015, 06, 28)
    dt_monday = Date(2015, 06, 29)
    dt_newyears = Date(2016,1,1)

    # Bounds tests
    if !usecache
        # this should work
        isbday(hc_brazil, Date(1600,2,1))
        isbday(hc_brazil, Date(3000,2,1))
        bdays(hc_brazil, Date(1600,2,1), Date(1600, 2, 5))
        bdays(hc_brazil, Date(3000,2,1), Date(3000, 2, 5))
    else
        #this should not work
        @test_throws ErrorException isbday(hc_brazil, Date(1600,2,1))
        @test_throws ErrorException isbday(hc_brazil, Date(3000,2,1))
        @test_throws ErrorException bdays(hc_brazil, Date(1600,2,1), Date(1600, 2, 5))
        @test_throws ErrorException bdays(hc_brazil, Date(3000,2,1), Date(3000, 2, 5))
    end

    @test_throws ErrorException isbday(:UnknownCalendar, Date(2016,1,1))
    @test_throws ErrorException isbday("UnknownCalendar", Date(2016,1,1))

    @test isweekend(dt_friday) == false
    @test isweekend(dt_saturday) == true
    @test isweekend(dt_sunday) == true
    @test isweekend(dt_monday) == false

    @test isbday(hc_brazil, dt_friday) == true
    @test isbday(hc_brazil, dt_saturday) == false
    @test isbday(hc_brazil, dt_sunday) == false
    @test isbday(hc_brazil, dt_monday) == true

    @test isholiday(hc_brazil, dt_friday) == false
    @test isholiday(hc_brazil, dt_saturday) == false
    @test isholiday(hc_brazil, dt_sunday) == false
    @test isholiday(hc_brazil, dt_monday) == false
    @test isholiday(hc_brazil, dt_newyears) == true

    # Symbol
    @test isholiday(:Brazil, dt_friday) == false
    @test isholiday(:Brazil, dt_saturday) == false
    @test isholiday(:Brazil, dt_sunday) == false
    @test isholiday(:Brazil, dt_monday) == false
    @test isholiday(:Brazil, dt_newyears) == true

    # String
    @test isholiday("Brazil", dt_friday) == false
    @test isholiday("Brazil", dt_saturday) == false
    @test isholiday("Brazil", dt_sunday) == false
    @test isholiday("Brazil", dt_monday) == false
    @test isholiday("Brazil", dt_newyears) == true

    @test isholiday(bd.NullHolidayCalendar(), Date(2000,10,1)) == false

    # Brazil HolidayCalendar tests
    @test isbday(hc_brazil, Date(2014, 12, 31)) == true # wednesday
    @test isbday(hc_brazil, Date(2015, 01, 01)) == false # new year
    @test isbday(hc_brazil, Date(2015, 01, 02)) == true # friday

    @test isbday(hc_brazil, Date(2015, 04, 20)) == true # monday
    @test isbday(hc_brazil, Date(2015, 04, 21)) == false # tiradentes
    @test isbday(hc_brazil, Date(2015, 04, 22)) == true # wednesday

    @test isbday(hc_brazil, Date(2015, 04, 30)) == true # thursday
    @test isbday(hc_brazil, Date(2015, 05, 01)) == false # labor day
    @test isbday(hc_brazil, Date(2015, 05, 02)) == false # saturday

    @test isbday(hc_brazil, Date(2015, 09, 06)) == false # sunday
    @test isbday(hc_brazil, Date(2015, 09, 07)) == false # independence day
    @test isbday(hc_brazil, Date(2015, 09, 08)) == true # tuesday

    @test isbday(hc_brazil, Date(2015, 10, 11)) == false # sunday
    @test isbday(hc_brazil, Date(2015, 10, 12)) == false # Nossa Senhora Aparecida
    @test isbday(hc_brazil, Date(2015, 10, 13)) == true # tuesday

    @test isbday(hc_brazil, Date(2015, 11, 01)) == false # sunday
    @test isbday(hc_brazil, Date(2015, 11, 02)) == false # Finados
    @test isbday(hc_brazil, Date(2015, 11, 03)) == true # tuesday

    @test isbday(hc_brazil, Date(2013, 11, 14)) == true # thursday
    @test isbday(hc_brazil, Date(2013, 11, 15)) == false # Republic
    @test isbday(hc_brazil, Date(2013, 11, 16)) == false # saturday

    @test isbday(hc_brazil, Date(2013, 12, 24)) == true # tuesday
    @test isbday(hc_brazil, Date(2013, 12, 25)) == false # Christmas
    @test isbday(hc_brazil, Date(2013, 12, 26)) == true # thursday

    @test isbday(hc_brazil, Date(2013, 02, 08)) == true # friday
    @test isbday(hc_brazil, Date(2013, 02, 09)) == false # saturday
    @test isbday(hc_brazil, Date(2013, 02, 10)) == false # sunday
    @test isbday(hc_brazil, Date(2013, 02, 11)) == false # segunda carnaval
    @test isbday(hc_brazil, Date(2013, 02, 12)) == false # terca carnaval
    @test isbday(hc_brazil, Date(2013, 02, 13)) == true # wednesday

    @test isbday(hc_brazil, Date(2013, 03, 28)) == true # thursday
    @test isbday(hc_brazil, Date(2013, 03, 29)) == false # sexta-feira santa
    @test isbday(hc_brazil, Date(2013, 03, 30)) == false # saturday

    @test isbday(hc_brazil, Date(2013, 05, 29)) == true # wednesday
    @test isbday(hc_brazil, Date(2013, 05, 30)) == false # Corpus Christi
    @test isbday(hc_brazil, Date(2013, 05, 31)) == true # friday

    # Symbol
    @test isbday(:Brazil, Date(2013, 05, 29)) == true # wednesday
    @test isbday(:Brazil, Date(2013, 05, 30)) == false # Corpus Christi
    @test isbday(:Brazil, Date(2013, 05, 31)) == true # friday

    # String
    @test isbday("Brazil", Date(2013, 05, 29)) == true # wednesday
    @test isbday("Brazil", Date(2013, 05, 30)) == false # Corpus Christi
    @test isbday("Brazil", Date(2013, 05, 31)) == true # friday

    # USSettlement HolidayCaledar tests
    # Federal Holidays listed on https://www.opm.gov/policy-data-oversight/snow-dismissal-procedures/federal-holidays/#url=2015
    @test isbday(hc_usa, Date(2014, 12, 31)) == true
    @test isbday(hc_usa, Date(2015, 01, 01)) == false # New Year's Day - Thursday
    @test isbday(hc_usa, Date(2015, 01, 02)) == true

    @test isbday(hc_usa, Date(2015, 01, 18)) == false
    @test isbday(hc_usa, Date(2015, 01, 19)) == false # Birthday of Martin Luther King, Jr. - Monday
    @test isbday(hc_usa, Date(2015, 01, 20)) == true

    @test isbday(hc_usa, Date(1982,01,18)) == true # not a holiday for Martin Luther King

    @test isbday(hc_usa, Date(2015, 02, 15)) == false
    @test isbday(hc_usa, Date(2015, 02, 16)) == false # Washington’s Birthday - Monday
    @test isbday(hc_usa, Date(2015, 02, 17)) == true

    @test isbday(hc_usa, Date(2015, 05, 24)) == false
    @test isbday(hc_usa, Date(2015, 05, 25)) == false # Memorial Day - Monday
    @test isbday(hc_usa, Date(2015, 05, 26)) == true

    @test isbday(hc_usa, Date(2015, 07, 02)) == true
    @test isbday(hc_usa, Date(2015, 07, 03)) == false # Independence Day - Friday
    @test isbday(hc_usa, Date(2015, 07, 04)) == false

    @test isbday(hc_usa, Date(2015, 09, 06)) == false
    @test isbday(hc_usa, Date(2015, 09, 07)) == false # Labor Day - Monday
    @test isbday(hc_usa, Date(2015, 09, 08)) == true

    @test isbday(hc_usa, Date(2015, 10, 11)) == false
    @test isbday(hc_usa, Date(2015, 10, 12)) == false # Columbus Day - Monday
    @test isbday(hc_usa, Date(2015, 10, 13)) == true

    @test isbday(hc_usa, Date(2015, 11, 10)) == true
    @test isbday(hc_usa, Date(2015, 11, 11)) == false # Veterans Day - Wednesday
    @test isbday(hc_usa, Date(2015, 11, 12)) == true

    @test isbday(hc_usa, Date(2015, 11, 25)) == true
    @test isbday(hc_usa, Date(2015, 11, 26)) == false # Thanksgiving Day - Thursday
    @test isbday(hc_usa, Date(2015, 11, 27)) == true

    @test isbday(hc_usa, Date(2015, 12, 24)) == true
    @test isbday(hc_usa, Date(2015, 12, 25)) == false # Christmas - Friday
    @test isbday(hc_usa, Date(2015, 12, 26)) == false

    @test isbday(hc_usa, Date(2010, 12, 31)) == false # new years day observed
    @test isbday(hc_usa, Date(2004, 12, 31)) == false # new years day observed

    @test isbday(hc_usa, Date(2013, 03, 28)) == true # thursday
    @test isbday(hc_usa, Date(2013, 03, 29)) == true # good friday
    @test isbday(hc_usa, Date(2013, 03, 30)) == false # saturday

    # Symbol
    @test isbday(:USSettlement, Date(2015, 12, 24)) == true
    @test isbday(:USSettlement, Date(2015, 12, 25)) == false # Christmas - Friday
    @test isbday(:USSettlement, Date(2015, 12, 26)) == false

    # String
    @test isbday("USSettlement", Date(2015, 12, 24)) == true
    @test isbday("USSettlement", Date(2015, 12, 25)) == false # Christmas - Friday
    @test isbday("USSettlement", Date(2015, 12, 26)) == false

    ## USNYSE HolidayCalendar tests

    @test isbday(hc_usnyse, Date(2014, 12, 31)) == true
    @test isbday(hc_usnyse, Date(2015, 01, 01)) == false # New Year's Day - Thursday
    @test isbday(hc_usnyse, Date(2015, 01, 02)) == true

    @test isbday(hc_usnyse, Date(2015, 01, 18)) == false
    @test isbday(hc_usnyse, Date(2015, 01, 19)) == false # Birthday of Martin Luther King, Jr. - Monday
    @test isbday(hc_usnyse, Date(2015, 01, 20)) == true

    @test isbday(hc_usnyse, Date(2015, 02, 15)) == false
    @test isbday(hc_usnyse, Date(2015, 02, 16)) == false # Washington’s Birthday - Monday
    @test isbday(hc_usnyse, Date(2015, 02, 17)) == true

    @test isbday(hc_usnyse, Date(2015, 05, 24)) == false
    @test isbday(hc_usnyse, Date(2015, 05, 25)) == false # Memorial Day - Monday
    @test isbday(hc_usnyse, Date(2015, 05, 26)) == true

    @test isbday(hc_usnyse, Date(2015, 07, 02)) == true
    @test isbday(hc_usnyse, Date(2015, 07, 03)) == false # Independence Day - Friday
    @test isbday(hc_usnyse, Date(2015, 07, 04)) == false

    @test isbday(hc_usnyse, Date(2015, 09, 06)) == false
    @test isbday(hc_usnyse, Date(2015, 09, 07)) == false # Labor Day - Monday
    @test isbday(hc_usnyse, Date(2015, 09, 08)) == true

    @test isbday(hc_usnyse, Date(2015, 10, 11)) == false
    @test isbday(hc_usnyse, Date(2015, 10, 12)) == true # Columbus Day - Monday
    @test isbday(hc_usnyse, Date(2015, 10, 13)) == true

    @test isbday(hc_usnyse, Date(2015, 11, 10)) == true
    @test isbday(hc_usnyse, Date(2015, 11, 11)) == true # Veterans Day - Wednesday
    @test isbday(hc_usnyse, Date(2015, 11, 12)) == true

    @test isbday(hc_usnyse, Date(2015, 11, 25)) == true
    @test isbday(hc_usnyse, Date(2015, 11, 26)) == false # Thanksgiving Day - Thursday
    @test isbday(hc_usnyse, Date(2015, 11, 27)) == true

    @test isbday(hc_usnyse, Date(2015, 12, 24)) == true
    @test isbday(hc_usnyse, Date(2015, 12, 25)) == false # Christmas - Friday
    @test isbday(hc_usnyse, Date(2015, 12, 26)) == false

    @test isbday(hc_usnyse, Date(2010, 12, 31)) == true # Friday before new years
    @test isbday(hc_usnyse, Date(2004, 12, 31)) == true # Friday before new years

    @test isbday(hc_usnyse, Date(2013, 03, 28)) == true # thursday
    @test isbday(hc_usnyse, Date(2013, 03, 29)) == false # good friday
    @test isbday(hc_usnyse, Date(2013, 03, 30)) == false # saturday

    # Symbol
    @test isbday(:USNYSE, Date(2015, 12, 24)) == true
    @test isbday(:USNYSE, Date(2015, 12, 25)) == false # Christmas - Friday
    @test isbday(:USNYSE, Date(2015, 12, 26)) == false

    # String
    @test isbday("USNYSE", Date(2015, 12, 24)) == true
    @test isbday("USNYSE", Date(2015, 12, 25)) == false # Christmas - Friday
    @test isbday("USNYSE", Date(2015, 12, 26)) == false

    ## USGovernmentBond HolidayCalendar tests
    @test isbday(hc_usgovbond, Date(2014, 12, 31)) == true
    @test isbday(hc_usgovbond, Date(2015, 01, 01)) == false # New Year's Day - Thursday
    @test isbday(hc_usgovbond, Date(2015, 01, 02)) == true

    @test isbday(hc_usgovbond, Date(2015, 01, 18)) == false
    @test isbday(hc_usgovbond, Date(2015, 01, 19)) == false # Birthday of Martin Luther King, Jr. - Monday
    @test isbday(hc_usgovbond, Date(2015, 01, 20)) == true

    @test isbday(hc_usgovbond, Date(2015, 02, 15)) == false
    @test isbday(hc_usgovbond, Date(2015, 02, 16)) == false # Washington’s Birthday - Monday
    @test isbday(hc_usgovbond, Date(2015, 02, 17)) == true

    @test isbday(hc_usgovbond, Date(2015, 05, 24)) == false
    @test isbday(hc_usgovbond, Date(2015, 05, 25)) == false # Memorial Day - Monday
    @test isbday(hc_usgovbond, Date(2015, 05, 26)) == true

    @test isbday(hc_usgovbond, Date(2015, 07, 02)) == true
    @test isbday(hc_usgovbond, Date(2015, 07, 03)) == false # Independence Day - Friday
    @test isbday(hc_usgovbond, Date(2015, 07, 04)) == false

    @test isbday(hc_usgovbond, Date(2015, 09, 06)) == false
    @test isbday(hc_usgovbond, Date(2015, 09, 07)) == false # Labor Day - Monday
    @test isbday(hc_usgovbond, Date(2015, 09, 08)) == true

    @test isbday(hc_usgovbond, Date(2015, 10, 11)) == false
    @test isbday(hc_usgovbond, Date(2015, 10, 12)) == false # Columbus Day - Monday
    @test isbday(hc_usgovbond, Date(2015, 10, 13)) == true

    @test isbday(hc_usgovbond, Date(2015, 11, 10)) == true
    @test isbday(hc_usgovbond, Date(2015, 11, 11)) == false # Veterans Day - Wednesday
    @test isbday(hc_usgovbond, Date(2015, 11, 12)) == true

    @test isbday(hc_usgovbond, Date(2015, 11, 25)) == true
    @test isbday(hc_usgovbond, Date(2015, 11, 26)) == false # Thanksgiving Day - Thursday
    @test isbday(hc_usgovbond, Date(2015, 11, 27)) == true

    @test isbday(hc_usgovbond, Date(2015, 12, 24)) == true
    @test isbday(hc_usgovbond, Date(2015, 12, 25)) == false # Christmas - Friday
    @test isbday(hc_usgovbond, Date(2015, 12, 26)) == false

    @test isbday(hc_usgovbond, Date(2010, 12, 31)) == true # Friday before new years
    @test isbday(hc_usgovbond, Date(2004, 12, 31)) == true # Friday before new years

    @test isbday(hc_usgovbond, Date(2013, 03, 28)) == true # thursday
    @test isbday(hc_usgovbond, Date(2013, 03, 29)) == false # good friday
    @test isbday(hc_usgovbond, Date(2013, 03, 30)) == false # saturday

    # Symbol
    @test isbday(:USGovernmentBond, Date(2015, 12, 24)) == true
    @test isbday(:USGovernmentBond, Date(2015, 12, 25)) == false # Christmas - Friday
    @test isbday(:USGovernmentBond, Date(2015, 12, 26)) == false

    # String
    @test isbday("USGovernmentBond", Date(2015, 12, 24)) == true
    @test isbday("USGovernmentBond", Date(2015, 12, 25)) == false # Christmas - Friday
    @test isbday("USGovernmentBond", Date(2015, 12, 26)) == false

    ## UKSettlement HolidayCalendar tests
    @test isbday(hc_uk, Date(2014, 12, 31)) == true
    @test isbday(hc_uk, Date(2015, 01, 01)) == false # New Year's Day Thursday
    @test isbday(hc_uk, Date(2015, 01, 02)) == true

    @test isbday(hc_uk, Date(2015, 08, 30)) == false
    @test isbday(hc_uk, Date(2015, 08, 31)) == false # Monday   Summer bank holiday
    @test isbday(hc_uk, Date(2015, 09, 01)) == true

    @test isbday(hc_uk, Date(2015, 12, 24)) == true
    @test isbday(hc_uk, Date(2015, 12, 25)) == false # 25 December  Friday  Christmas Day
    @test isbday(hc_uk, Date(2015, 12, 26)) == false
    @test isbday(hc_uk, Date(2015, 12, 27)) == false
    @test isbday(hc_uk, Date(2015, 12, 28)) == false # Monday   Boxing Day (substitute day)
    @test isbday(hc_uk, Date(2015, 12, 29)) == true

    @test isbday(hc_uk, Date(2016, 03, 24)) == true
    @test isbday(hc_uk, Date(2016, 03, 25)) == false # 25 March Friday  Good Friday
    @test isbday(hc_uk, Date(2016, 03, 26)) == false
    @test isbday(hc_uk, Date(2016, 03, 27)) == false
    @test isbday(hc_uk, Date(2016, 03, 28)) == false # 28 March Monday  Easter Monday
    @test isbday(hc_uk, Date(2016, 03, 29)) == true

    @test isbday(hc_uk, Date(2016, 05, 01)) == false
    @test isbday(hc_uk, Date(2016, 05, 02)) == false # 2 May    Monday  Early May bank holiday
    @test isbday(hc_uk, Date(2016, 05, 03)) == true

    @test isbday(hc_uk, Date(2016, 05, 29)) == false
    @test isbday(hc_uk, Date(2016, 05, 30)) == false # 30 May   Monday  Spring bank holiday
    @test isbday(hc_uk, Date(2016, 05, 31)) == true

    @test isbday(hc_uk, Date(2016, 08, 28)) == false
    @test isbday(hc_uk, Date(2016, 08, 29)) == false # 29 August    Monday  Summer bank holiday
    @test isbday(hc_uk, Date(2016, 08, 30)) == true

    @test isbday(hc_uk, Date(2016, 12, 23)) == true
    @test isbday(hc_uk, Date(2016, 12, 24)) == false
    @test isbday(hc_uk, Date(2016, 12, 25)) == false
    @test isbday(hc_uk, Date(2016, 12, 26)) == false # 26 December  Monday  Boxing Day
    @test isbday(hc_uk, Date(2016, 12, 27)) == false # 27 December  Tuesday Christmas Day (substitute day)
    @test isbday(hc_uk, Date(2016, 12, 28)) == true

    # 2012 UK Holidays
    @test isbday(hc_uk, Date(2011, 12, 30)) == true
    @test isbday(hc_uk, Date(2011, 12, 31)) == false
    @test isbday(hc_uk, Date(2012, 01, 01)) == false
    @test isbday(hc_uk, Date(2012, 01, 02)) == false # 2 January    Monday  New Year’s Day (substitute day)
    @test isbday(hc_uk, Date(2012, 01, 03)) == true

    @test isbday(hc_uk, Date(2012, 04, 05)) == true
    @test isbday(hc_uk, Date(2012, 04, 06)) == false # 6 April  Friday  Good Friday
    @test isbday(hc_uk, Date(2012, 04, 07)) == false
    @test isbday(hc_uk, Date(2012, 04, 08)) == false
    @test isbday(hc_uk, Date(2012, 04, 09)) == false # 9 April  Monday  Easter Monday
    @test isbday(hc_uk, Date(2012, 04, 10)) == true

    @test isbday(hc_uk, Date(2012, 05, 06)) == false
    @test isbday(hc_uk, Date(2012, 05, 07)) == false # 7 May    Monday  Early May bank holiday
    @test isbday(hc_uk, Date(2012, 05, 08)) == true

    @test isbday(hc_uk, Date(2012, 06, 01)) == true
    @test isbday(hc_uk, Date(2012, 06, 02)) == false
    @test isbday(hc_uk, Date(2012, 06, 03)) == false
    @test isbday(hc_uk, Date(2012, 06, 04)) == false # 4 June   Monday  Spring bank holiday (substitute day)
    @test isbday(hc_uk, Date(2012, 06, 05)) == false # 5 June   Tuesday Queen’s Diamond Jubilee (extra bank holiday)
    @test isbday(hc_uk, Date(2012, 06, 06)) == true

    @test isbday(hc_uk, Date(2011, 04, 29)) == false # wedding

    @test isbday(hc_uk, Date(2012, 08, 26)) == false
    @test isbday(hc_uk, Date(2012, 08, 27)) == false # 27 August    Monday  Summer bank holiday
    @test isbday(hc_uk, Date(2012, 08, 28)) == true

    @test isbday(hc_uk, Date(2012, 12, 24)) == true
    @test isbday(hc_uk, Date(2012, 12, 25)) == false # 25 December  Tuesday Christmas Day
    @test isbday(hc_uk, Date(2012, 12, 26)) == false # 26 December  Wednesday   Boxing Day
    @test isbday(hc_uk, Date(2012, 12, 27)) == true

    # 1999 UK holidays
    @test isbday(hc_uk, Date(1999, 12, 26)) == false # Sunday
    @test isbday(hc_uk, Date(1999, 12, 27)) == false # Christmas observed
    @test isbday(hc_uk, Date(1999, 12, 28)) == false # Boxing observed
    @test isbday(hc_uk, Date(1999, 12, 29)) == true
    @test isbday(hc_uk, Date(1999, 12, 30)) == true
    @test isbday(hc_uk, Date(1999, 12, 31)) == false

    @test tobday(hc_brazil, Date(2013, 02, 08)) == Date(2013, 02, 08) # regular friday
    @test tobday(hc_brazil, Date(2013, 02, 09)) == Date(2013, 02, 13) # after carnaval
    @test tobday(hc_brazil, Date(2013, 02, 09); forward = true) == Date(2013, 02, 13) # after carnaval
    @test tobday(hc_brazil, Date(2013, 02, 13); forward = false) == Date(2013, 02, 13) # after carnaval
    @test tobday(hc_brazil, Date(2013, 02, 12); forward = false) == Date(2013, 02, 08) # before carnaval

    @test tobday(:Brazil, Date(2013, 02, 08)) == Date(2013, 02, 08) # regular friday
    @test tobday(:Brazil, Date(2013, 02, 09)) == Date(2013, 02, 13) # after carnaval
    @test tobday(:Brazil, Date(2013, 02, 09); forward = true) == Date(2013, 02, 13) # after carnaval
    @test tobday(:Brazil, Date(2013, 02, 13); forward = false) == Date(2013, 02, 13) # after carnaval
    @test tobday(:Brazil, Date(2013, 02, 12); forward = false) == Date(2013, 02, 08) # before carnaval

    @test tobday("Brazil", Date(2013, 02, 08)) == Date(2013, 02, 08) # regular friday
    @test tobday("Brazil", Date(2013, 02, 09)) == Date(2013, 02, 13) # after carnaval
    @test tobday("Brazil", Date(2013, 02, 09); forward = true) == Date(2013, 02, 13) # after carnaval
    @test tobday("Brazil", Date(2013, 02, 13); forward = false) == Date(2013, 02, 13) # after carnaval
    @test tobday("Brazil", Date(2013, 02, 12); forward = false) == Date(2013, 02, 08) # before carnaval

    @test advancebdays(hc_brazil, Date(2013, 02, 06), 0) == Date(2013, 02, 06) # regular wednesday
    @test advancebdays(hc_brazil, Date(2013, 02, 06), 1) == Date(2013, 02, 07) # regular thursday
    @test advancebdays(hc_brazil, Date(2013, 02, 06), 2) == Date(2013, 02, 08) # regular friday
    @test advancebdays(hc_brazil, Date(2013, 02, 06), 3) == Date(2013, 02, 13) # after carnaval wednesday
    @test advancebdays(hc_brazil, Date(2013, 02, 06), 4) == Date(2013, 02, 14) # after carnaval thursday

    @test advancebdays(:Brazil, Date(2013, 02, 06), 0) == Date(2013, 02, 06) # regular wednesday
    @test advancebdays(:Brazil, Date(2013, 02, 06), 1) == Date(2013, 02, 07) # regular thursday
    @test advancebdays(:Brazil, Date(2013, 02, 06), 2) == Date(2013, 02, 08) # regular friday
    @test advancebdays(:Brazil, Date(2013, 02, 06), 3) == Date(2013, 02, 13) # after carnaval wednesday
    @test advancebdays(:Brazil, Date(2013, 02, 06), 4) == Date(2013, 02, 14) # after carnaval thursday

    @test advancebdays("Brazil", Date(2013, 02, 06), 0) == Date(2013, 02, 06) # regular wednesday
    @test advancebdays("Brazil", Date(2013, 02, 06), 1) == Date(2013, 02, 07) # regular thursday
    @test advancebdays("Brazil", Date(2013, 02, 06), 2) == Date(2013, 02, 08) # regular friday
    @test advancebdays("Brazil", Date(2013, 02, 06), 3) == Date(2013, 02, 13) # after carnaval wednesday
    @test advancebdays("Brazil", Date(2013, 02, 06), 4) == Date(2013, 02, 14) # after carnaval thursday

    @test bdays(hc_brazil, Date(2013, 02, 06), Date(2013, 02, 06)) == Day(0)
    @test bdays(hc_brazil, Date(2013, 02, 06), Date(2013, 02, 07)) == Day(1)
    @test bdays(hc_brazil, Date(2013, 02, 07), Date(2013, 02, 06)).value == -1
    @test bdays(hc_brazil, Date(2013, 02, 06), Date(2013, 02, 08)).value == 2
    @test bdays(hc_brazil, Date(2013, 02, 08), Date(2013, 02, 06)).value == -2
    @test bdays(hc_brazil, Date(2013, 02, 06), Date(2013, 02, 09)).value == 3
    @test bdays(hc_brazil, Date(2013, 02, 06), Date(2013, 02, 10)).value == 3
    @test bdays(hc_brazil, Date(2013, 02, 06), Date(2013, 02, 11)).value == 3
    @test bdays(hc_brazil, Date(2013, 02, 06), Date(2013, 02, 12)).value == 3
    @test bdays(hc_brazil, Date(2013, 02, 06), Date(2013, 02, 13)).value == 3
    @test bdays(hc_brazil, Date(2013, 02, 06), Date(2013, 02, 14)).value == 4
    @test bdays(hc_brazil, Date(2013, 02, 14), Date(2013, 02, 06)).value == -4

    # dates are treated per value
    d0 = Date(2013, 02, 06)
    d1 = Date(2013, 02, 14)
    @test bdays(hc_brazil, d0, d1).value == 4
    @test d0 == Date(2013, 02, 06) # d0 is changed inside bdays function, but outer-scope value remains the same
    @test d1 == Date(2013, 02, 14)

    d0 = Date(2015, 06, 29) ; d2 = Date(2100, 12, 20)
    @test bdays(hc_brazil, d0, d2).value == 21471

    # Tests for Composite Calendar
    @test isholiday(hc_composite_BR_USA, Date(2012,9,3)) # US Labor Day
    @test isholiday(hc_composite_BR_USA, Date(2012,9,7)) # BR Independence Day
    @test bdays(hc_composite_BR_USA, Date(2012,8,31), Date(2012,9,10)) == Day(4) # 3/sep labor day US, 7/sep Indep day BR

    println("Timing composite calendar bdays calculation")
    @time bdays(hc_composite_BR_USA, Date(2012,8,31), Date(2012,9,10))

    println("Timing single bdays calculation")
    @time bdays(hc_brazil, d0, d2)

    println("Timing 100 bdays calculations")
    @time for i in 1:100 bdays(hc_brazil, d0, d2) end

    dInicio = Date(1950, 01, 01) ; dFim = Date(2100, 12, 20)

    if !usecache
        println("Timing cache creation")
        @time x = bd._createbdayscache(hc_brazil, dInicio, dFim)
    end

    if usecache
        println("a million...")
        @time for i in 1:1000000 bdays(hc_brazil, d0, d2) end
    end

    # Vector functions
    d0 = Date(2000,01,04)
    d1 = Date(2020,01,04)

    d1vec = convert(Vector{Date}, d0:d1)
    d0vec = fill(d0, length(d1vec))

    r = bdays(hc_brazil, d0vec, d1vec)
    b = isbday(hc_brazil, d0vec)
    b2 = isbday(:Brazil, d0vec)
    b3 = isbday("Brazil", d0vec)
    @test tobday([hc_brazil, hc_usa], [Date(2015,11,11), Date(2015,11,11)]) == [Date(2015,11,11), Date(2015,11,12)]
    @test tobday([:Brazil, :USSettlement], [Date(2015,11,11), Date(2015,11,11)]) == [Date(2015,11,11), Date(2015,11,12)]
    @test tobday(["Brazil", "USSettlement"], [Date(2015,11,11), Date(2015,11,11)]) == [Date(2015,11,11), Date(2015,11,12)]

    # Vector with different sizes
    @test_throws ErrorException bdays(hc_brazil, fill(d0, length(d1vec)+1), d1vec)
    @test_throws ErrorException bdays([hc_brazil, hc_usa], [Date(2015,11,11)], [Date(2015,11,11),Date(2015,11,11)])
    @test_throws ErrorException tobday([hc_brazil, hc_usa], fill(d0, 3))
    @test_throws ErrorException isbday( [hc_brazil, hc_usa, hc_uk], [Date(2015,01,01), Date(2015,01,01)])

    println("Timing vectorized functions (vector length $(length(d0vec)))")
    @time bdays(hc_brazil, d0vec, d1vec)
    @time bdays(:Brazil, d0vec, d1vec)
    @time bdays("Brazil", d0vec, d1vec)
    @time isbday(hc_brazil, d0vec)
    @time isbday(:Brazil, d0vec)
    @time isbday("Brazil", d0vec)

    d2001 = convert(Array{Date,1}, Date(2001,01,01):Date(2001,01,15))

    @test isweekend(d2001) == [ false, false, false, false, false, true, true, false, false, false, false, false, true, true, false]
    @test tobday(hc_brazil, d2001; forward=true) == [ Date(2001,01,02), Date(2001,01,02), Date(2001,01,03), Date(2001,01,04), Date(2001,01,05), Date(2001,01,08), Date(2001,01,08), Date(2001,01,08), Date(2001,01,09), Date(2001,01,10), Date(2001,01,11), Date(2001,01,12), Date(2001,01,15), Date(2001,01,15), Date(2001,01,15)]
    @test tobday(hc_brazil, d2001; forward=false) == [ Date(2000,12,29), Date(2001,01,02), Date(2001,01,03), Date(2001,01,04), Date(2001,01,05), Date(2001,01,05), Date(2001,01,05), Date(2001,01,08), Date(2001,01,09), Date(2001,01,10), Date(2001,01,11), Date(2001,01,12), Date(2001,01,12), Date(2001,01,12), Date(2001,01,15)]

    @test tobday(:Brazil, d2001; forward=true) == [ Date(2001,01,02), Date(2001,01,02), Date(2001,01,03), Date(2001,01,04), Date(2001,01,05), Date(2001,01,08), Date(2001,01,08), Date(2001,01,08), Date(2001,01,09), Date(2001,01,10), Date(2001,01,11), Date(2001,01,12), Date(2001,01,15), Date(2001,01,15), Date(2001,01,15)]
    @test tobday("Brazil", d2001; forward=false) == [ Date(2000,12,29), Date(2001,01,02), Date(2001,01,03), Date(2001,01,04), Date(2001,01,05), Date(2001,01,05), Date(2001,01,05), Date(2001,01,08), Date(2001,01,09), Date(2001,01,10), Date(2001,01,11), Date(2001,01,12), Date(2001,01,12), Date(2001,01,12), Date(2001,01,15)]

    @test bdays([hc_brazil, hc_usa], [Date(2012,8,31), Date(2012,8,31)], [Date(2012,9,10), Date(2012,9,10)]) == [Day(5), Day(5)] # 1/sep labor day US, 7/sep Indep day BR
    @test isbday([hc_brazil, hc_usa], [Date(2012, 09, 07), Date(2012, 09, 03)]) == [false, false] # 1/sep labor day US, 7/sep Indep day BR
    @test advancebdays(hc_brazil, Date(2015,9,1), [0, 1, 3, 4, 5]) == [Date(2015,9,1),Date(2015,9,2),Date(2015,9,4),Date(2015,9,8),Date(2015,9,9)]
    @test advancebdays(hc_brazil, Date(2015,9,1), 0:5) == [Date(2015,9,1),Date(2015,9,2),Date(2015,9,3),Date(2015,9,4),Date(2015,9,8),Date(2015,9,9)]
    @test listholidays(hc_brazil, Date(2016,1,1), Date(2016,5,30)) == [Date(2016,1,1),Date(2016,2,8),Date(2016,2,9),Date(2016,3,25),Date(2016,4,21),Date(2016,5,1),Date(2016,5,26)]

    @test bdays([:Brazil, :USSettlement], [Date(2012,8,31), Date(2012,8,31)], [Date(2012,9,10), Date(2012,9,10)]) == [Day(5), Day(5)] # 1/sep labor day US, 7/sep Indep day BR
    @test isbday([:Brazil, :USSettlement], [Date(2012, 09, 07), Date(2012, 09, 03)]) == [false, false] # 1/sep labor day US, 7/sep Indep day BR
    @test advancebdays(:Brazil, Date(2015,9,1), [0, 1, 3, 4, 5]) == [Date(2015,9,1),Date(2015,9,2),Date(2015,9,4),Date(2015,9,8),Date(2015,9,9)]
    @test advancebdays(:Brazil, Date(2015,9,1), 0:5) == [Date(2015,9,1),Date(2015,9,2),Date(2015,9,3),Date(2015,9,4),Date(2015,9,8),Date(2015,9,9)]
    @test listholidays(:Brazil, Date(2016,1,1), Date(2016,5,30)) == [Date(2016,1,1),Date(2016,2,8),Date(2016,2,9),Date(2016,3,25),Date(2016,4,21),Date(2016,5,1),Date(2016,5,26)]

    @test bdays(["Brazil", "USSettlement"], [Date(2012,8,31), Date(2012,8,31)], [Date(2012,9,10), Date(2012,9,10)]) == [Day(5), Day(5)] # 1/sep labor day US, 7/sep Indep day BR
    @test isbday(["Brazil", "USSettlement"], [Date(2012, 09, 07), Date(2012, 09, 03)]) == [false, false] # 1/sep labor day US, 7/sep Indep day BR
    @test advancebdays("Brazil", Date(2015,9,1), [0, 1, 3, 4, 5]) == [Date(2015,9,1),Date(2015,9,2),Date(2015,9,4),Date(2015,9,8),Date(2015,9,9)]
    @test advancebdays("Brazil", Date(2015,9,1), 0:5) == [Date(2015,9,1),Date(2015,9,2),Date(2015,9,3),Date(2015,9,4),Date(2015,9,8),Date(2015,9,9)]
    @test listholidays("Brazil", Date(2016,1,1), Date(2016,5,30)) == [Date(2016,1,1),Date(2016,2,8),Date(2016,2,9),Date(2016,3,25),Date(2016,4,21),Date(2016,5,1),Date(2016,5,26)]

    @test listbdays("Brazil", Date(2016,5,18), Date(2016,5,23)) == [Date(2016,5,18),Date(2016,5,19),Date(2016,5,20),Date(2016,5,23)]
    @test listbdays("Brazil", Date(2016,5,18), Date(2016,5,18)) == [Date(2016,5,18)]
    @test isempty(listbdays("Brazil", Date(2016,5,21), Date(2016,5,21)))
    @test isempty(listbdays("Brazil", Date(2016,5,21), Date(2016,5,22)))
    @test listbdays("Brazil", Date(2016,5,21), Date(2016,5,23)) == [Date(2016,5,23)]
end

include("perftests.jl")

bd.cleancache(hc_brazil)
bd.cleancache()

type CustomCalendar <: HolidayCalendar end
cc = CustomCalendar()
@test_throws ErrorException isholiday(cc, Date(2015,1,1))
import BusinessDays.isholiday
isholiday(::CustomCalendar, dt::Date) = dt == Date(2015,8,27)
@test isholiday(cc, Date(2015,8,26)) == false
@test isholiday(cc, Date(2015,8,27)) == true
bd.initcache(cc)
@test isholiday(cc, Date(2015,8,26)) == false
@test isholiday(cc, Date(2015,8,27)) == true
bd.cleancache(cc)

sym_vec = [:Brazil, :UKSettlement]
bd.initcache(sym_vec)
bd.cleancache(sym_vec)

str_vec = ["Brazil", "UKSettlement"]
bd.initcache(str_vec)
bd.cleancache(str_vec)

bd.initcache("UKSettlement", Date(2000,1,1), Date(2000,5,2))
bd.cleancache("UKSettlement")

#=
INFO: Testing BusinessDays
easter minimum month is 3 on date 2100-03-28
easter maximum month is 4 on date 2099-04-12
##########################
 Using cache: false
##########################
Timing composite calendar bdays calculation
  0.000022 seconds (30 allocations: 1.219 KB)
Timing single bdays calculation
  0.016914 seconds (31.22 k allocations: 2.382 MB, 30.99% gc time)
Timing 100 bdays calculations
  0.610497 seconds (3.12 M allocations: 238.206 MB, 1.74% gc time)
Timing cache creation
  0.010609 seconds (55.15 k allocations: 4.470 MB, 7.17% gc time)
Timing vectorized functions (vector length 7306)
  4.731765 seconds (26.71 M allocations: 1.990 GB, 1.70% gc time)
  4.709852 seconds (26.71 M allocations: 1.990 GB, 1.69% gc time)
  4.703030 seconds (26.71 M allocations: 1.990 GB, 1.62% gc time)
  0.001923 seconds (7.31 k allocations: 578.000 KB)
  0.001742 seconds (7.31 k allocations: 578.000 KB)
  0.001734 seconds (7.31 k allocations: 578.000 KB)
##########################
 Using cache: true
##########################
Timing composite calendar bdays calculation
  0.000006 seconds (7 allocations: 112 bytes)
Timing single bdays calculation
  0.000004 seconds (5 allocations: 80 bytes)
Timing 100 bdays calculations
  0.000066 seconds (500 allocations: 7.813 KB)
a million...
  0.589832 seconds (5.00 M allocations: 76.294 MB, 2.34% gc time)
Timing vectorized functions (vector length 7306)
  0.004112 seconds (29.23 k allocations: 513.766 KB)
  0.004052 seconds (29.23 k allocations: 513.766 KB)
  0.004037 seconds (29.23 k allocations: 513.766 KB)
  0.001003 seconds (1 allocation: 7.219 KB)
  0.000980 seconds (1 allocation: 7.219 KB)
  0.000979 seconds (1 allocation: 7.219 KB)
Perftests
  0.017908 seconds (1.48 k allocations: 374.630 KB)
  0.000005 seconds (9 allocations: 240 bytes)
  0.575191 seconds (5.00 M allocations: 76.294 MB, 1.38% gc time)
  1.226357 seconds (8.00 M allocations: 122.070 MB, 1.37% gc time)
  1.547292 seconds (8.00 M allocations: 122.070 MB, 1.36% gc time)
type
  0.000568 seconds (5.00 k allocations: 78.125 KB)
  0.000487 seconds (4.00 k allocations: 70.547 KB)
  0.000581 seconds (7.01 k allocations: 125.313 KB)
sym
  0.001273 seconds (8.00 k allocations: 125.000 KB)
  0.000504 seconds (4.00 k allocations: 70.547 KB)
  0.001064 seconds (7.01 k allocations: 125.313 KB)
str
  0.002078 seconds (8.00 k allocations: 125.000 KB)
  0.000630 seconds (4.00 k allocations: 70.547 KB)
  0.001645 seconds (7.01 k allocations: 125.313 KB)
initcache type
  0.013472 seconds (62.46 k allocations: 5.062 MB)
initcache sym
  0.028815 seconds (62.46 k allocations: 5.062 MB)
initcache str
  0.025278 seconds (62.46 k allocations: 5.062 MB)
INFO: BusinessDays tests passed
=#


text:
# Parts of this code were taken / derived from Graphs.jl. See LICENSE for
# licensing details.
"""
    struct FloydWarshallState{T, U}

An [`AbstractPathState`](@ref) designed for Floyd-Warshall shortest-paths calculations.
"""
struct FloydWarshallState{T,U<:Integer} <: AbstractPathState
    dists::Matrix{T}
    parents::Matrix{U}
end

@doc """
    floyd_warshall_shortest_paths(g, distmx=weights(g))

Use the [Floyd-Warshall algorithm](http://en.wikipedia.org/wiki/Floyd–Warshall_algorithm)
to compute the shortest paths between all pairs of vertices in graph `g` using an
optional distance matrix `distmx`. Return a [`LightGraphs.FloydWarshallState`](@ref) with relevant
traversal information.

### Performance
Space complexity is on the order of ``\\mathcal{O}(|V|^2)``.
"""
function floyd_warshall_shortest_paths(
    g::AbstractGraph{U},
    distmx::AbstractMatrix{T}=weights(g)
) where T<:Real where U<:Integer
    nvg = nv(g)
    # if we do checkbounds here, we can use @inbounds later
    checkbounds(distmx, Base.OneTo(nvg), Base.OneTo(nvg))

    dists = fill(typemax(T), (Int(nvg), Int(nvg)))
    parents = zeros(U, (Int(nvg), Int(nvg)))

    @inbounds for v in vertices(g)
        dists[v, v] = zero(T)
    end
    undirected = !is_directed(g)
    @inbounds for e in edges(g)
        u = src(e)
        v = dst(e)

        d = distmx[u, v]

        dists[u, v] = min(d, dists[u, v])
        parents[u, v] = u
        if undirected
            dists[v, u] = min(d, dists[v, u])
            parents[v, u] = v
        end
    end

    @inbounds for pivot in vertices(g)
        # Relax dists[u, v] = min(dists[u, v], dists[u, pivot]+dists[pivot, v]) for all u, v
        for v in vertices(g)
            d = dists[pivot, v]
            d == typemax(T) && continue
            p = parents[pivot, v]
            for u in vertices(g)
                ans = (dists[u, pivot] == typemax(T) ? typemax(T) : dists[u, pivot] + d)
                if dists[u, v] > ans
                    dists[u, v] = ans
                    parents[u, v] = p
                end
            end
        end
    end
    fws = FloydWarshallState(dists, parents)
    return fws
end

function enumerate_paths(s::FloydWarshallState{T,U}, v::Integer) where T where U<:Integer
    pathinfo = s.parents[v, :]
    paths = Vector{Vector{U}}()
    for i in 1:length(pathinfo)
        if (i == v) || (s.dists[v, i] == typemax(T))
            push!(paths, Vector{U}())
        else
            path = Vector{U}()
            currpathindex = i
            while currpathindex != 0
                push!(path, currpathindex)
                if pathinfo[currpathindex] == currpathindex
                    currpathindex = 0
                else
                    currpathindex = pathinfo[currpathindex]
                end
            end
            push!(paths, reverse(path))
        end
    end
    return paths
end

enumerate_paths(s::FloydWarshallState) = [enumerate_paths(s, v) for v in 1:size(s.parents, 1)]
enumerate_paths(st::FloydWarshallState, s::Integer, d::Integer) = enumerate_paths(st, s)[d]


text:
module Misc

export Bounded

#needs some unit tests
struct Bounded{T<:Real, Min, Max}
    val::T
    function Bounded(val::T, min_val::Real, max_val::Real) where {T}
        new{T, min_val, max_val}(min(max(val, min_val), max_val))
    end
end

Bounded{T}(x::Bounded) where {T} = convert(Bounded{T}, x)
Bounded{T,Min,Max}(x::Bounded) where {T,Min,Max} = convert(Bounded{T,Min,Max}, x)
(T::Type{<:Real})(x::Bounded) = convert(T, x)

Base.convert(::Type{T}, x::Bounded) where {T<:Real} = T(x.val)
Base.convert(::Type{Bounded{T,Min,Max}}, x::Real) where {T, Min, Max} = Bounded(T(x), Min, Max)

function Base.convert(::Type{Bounded{T1,Min,Max}}, x::Bounded{T2}) where {T1, T2, Min, Max}
    Bounded(T1(x.val), Min, Max)
end

function Base.convert(::Type{Bounded{T1}}, x::Bounded{T2,Min,Max}) where {T1, T2, Min, Max}
    #since the conversion target does not specify bounds, take them from the conversion source
    Bounded(T1(x.val), Min, Max)
end

function Base.promote_rule(::Type{Bounded{T1,Min,Max}}, ::Type{T2}) where {T1, T2, Min, Max}
    Bounded{promote_type(T1,T2),Min,Max}
end

#addition and subtraction between Bounded and Reals not required by now

end#module


text:
type Priors
	dists::Array{Distribution}
	lb::Array{F,1}
	ub::Array{F,1}
end

function Priors(;dists = [], lb = [], ub = [])
	isempty(dists) ? error("Need to specify prior distributions!") : nothing
	isempty(lb) ? lb = -Inf * ones(length(dists)) : nothing
	isempty(ub) ? ub = Inf * ones(length(dists)) : nothing
	return Priors(dists,lb,ub)
end

max_stars_repo_name: jlepird/prefEl

max_issues_repo_name: jlepird/prefEl

max_forks_repo_name: jlepird/prefEl


text:
"""
Type for storing NamedD
"""
mutable struct NamedD{T<:Union{Srcs,Recs}}
	grid::StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}}
	d::NamedArrays.NamedArray{Array{Float64,2},1,Array{Array{Float64,2},1},Tuple{OrderedCollections.OrderedDict{Symbol,Int64}}}
	sr::T
#	NamedD{T}(grid,d,sr)=any([(size(dd)≠(length(grid),sr.n)) for dd in d]) ? error("NamedD construction") : new(grid,d,sr)
end

"""
Simplify getting properties
"""
function Base.getindex(obj::NamedD, sym::Symbol)
	if(sym ∈ [:nr, :ns, :n])
		return obj.sr.n
	else
		return Base.getindex(obj.d, sym)
	end
end

"""
Initialize with zeros, given grid and names.
"""
function Base.zero(::Type{NamedD}, grid::StepRangeLen, s::Union{Srcs,Recs}, fields::Vector{Symbol})
	nt=length(grid); nf=length(fields)
	return NamedD(grid,NamedArray([zeros(nt,s.n) for i in fields], (fields,)),s)
end
NamedD(grid, s::Union{Srcs,Recs}, fields::Vector{Symbol})=zero(NamedD, grid, s, fields)

VNamedD=Union{Array{NamedD{Recs},1},Array{NamedD{Srcs},1}}

function Array{NamedD{Recs},1}(grid::StepRangeLen, ss::SSrcs, sr::Vector{Recs}, fields::Vector{Symbol})
	return [NamedD(grid,sr[i],fields) for i in 1:ss.n]
end
function Array{NamedD{Srcs},1}(grid::StepRangeLen, ss::SSrcs, sr::Vector{Srcs}, fields::Vector{Symbol})
	return [NamedD(grid,sr[i],fields) for i in 1:ss.n]
end

function Array{NamedD{Srcs},1}(grid::StepRangeLen, ss::SSrcs, sr::Srcs, fields::Vector{Symbol})
	return [NamedD(grid,sr,fields) for i in 1:ss.n]
end
function Array{NamedD{Recs},1}(grid::StepRangeLen, ss::SSrcs, sr::Recs, fields::Vector{Symbol})
	return [NamedD(grid,sr,fields) for i in 1:ss.n]
end

"""
Print information about `NamedD`.
To be implemented
"""
function Base.show(io::Base.IO, src::NamedD)
	println(io,"\tNamedD")
#	println(io,"\t> number of supersources:\t",src.nss)
#	println(io,"\t> sources per supersource:\t","min\t",minimum(src.ns[:]), "\tmax\t", maximum(src.ns[:]))
end

#function Base.isapprox(src1::NamedD, src2::NamedD)
#	vec=([(src1.nss==src2.nss), (src1.fields==src2.fields), (src1.ns==src2.ns),
#       		(isequal(src1.grid, src2.grid)),
#		])
#	return all(vec)
#end

"""
```
rmul!(srcwav[1], b)
```
Scale `srcwav` for first supersource by a scalar `b` overwriting in-place.
"""
function LinearAlgebra.rmul!(dat::NamedD, x::Number)
	for dd in dat.d
		rmul!(dd, x)
	end
end

"""
```
rmul!(srcwav, b)
```
Scale `srcwav` for all supersources by a scalar `b` overwriting in-place.
"""
function LinearAlgebra.rmul!(dat::VNamedD, x::Number)
	for d in dat
		rmul!(d,x)
	end
end

"""
```julia
update!(srcwav[1], [:P, :Vx], w)
```
Populate first supersource of `srcwav` by a wavelet `w` for `:P` and `:Vx` fields.
"""
function update!(d::NamedD, fields::Vector{Symbol}, w::AbstractArray)
	@assert length(w)==length(d.grid)
	@inbounds for f in fields
		@assert f ∈ names(d.d)[1]
		@inbounds for i in 1:d[:n]
			for it in 1:length(d.grid)
				d.d[f][it,i]=w[it]
			end
		end
	end
	return d
end

"""
```julia
update!(srcwav, [:P, :Vx], w)
```
Populate `srcwav` by a wavelet vector `w` for `:P` and `:Vx` fields.
"""
function update!(dat::VNamedD, fields::Vector{Symbol}, w::AbstractArray)
	for d in dat
		update!(d,fields,w)
	end
end

"""
```julia
isequal(srcwav[1], srcwav[2])
```
Assert if wavelets due to first two supersources are equal.
"""
function Base.isequal(dat1::NamedD, dat2::NamedD)
	return (dat1.grid==dat2.grid) && (dat1.d==dat2.d)
end

"""
```julia
isequal(srcwav1, srcwav2)
```
Assert if `srcwav1` and `srcwav2` are equal.
"""
function Base.isequal(dat1::VNamedD, dat2::VNamedD)
	return all([isequal(dat1[i],dat2[i]) for i in 1:length(dat1)])
end

"""
Return if two `NamedD`'s have same dimensions and bounds.
"""
function issimilar(dat1::NamedD, dat2::NamedD)
	return isequal(dat1.grid, dat2.grid) && isequal(names(dat1.d), names(dat2.d)) && (size(dat1.d)==size(dat2.d))
end

"""
```julia
issimilar(srcwav1, srcwav2)
```
Assert if `srcwav1` and `srcwav2` have same dimensions and fields.
"""
function issimilar(dat1::VNamedD, dat2::VNamedD)
	@assert length(dat1)==length(dat2)
	return all([issimilar(dat1[i],dat2[i]) for i in 1:length(dat1)])
end

function Base.length(data::NamedD)
	return length(data.grid)*data[:n]*length(names(data.d)[1])
end

"""
Return a vec of data object sorted in the order
time, channels
"""
function Base.vec(data::NamedD)
	v=Vector{Float64}()
	for dd in data.d
		append!(v,dd)
	end
	return v
end

"""
```julia
v=vec(srcwav)
Reshape `srcwav` as a one-dimensional column vector.
```
"""
function Base.vec(data::VNamedD)
	v=Vector{Float64}()
	for d in data
		append!(v,vec(d))
	end
	return v
end

function Base.copyto!(d::NamedD, v::AbstractVector{Float64}, i0=1)
#	@assert length(d)==length(v)
	for dd in d.d
		for i in 1:d[:n]
			for it in 1:length(d.grid)
				dd[it,i]=v[i0]
				i0+=1
			end
		end
	end
	return i0
end

"""
```julia
v=vec(srcwav)
randn!(v)
copyto!(srcwav, v)
```
Copy `v` to `srcwav`. The sizes of the two objects much match.
No memory allocations.
"""
function Base.copyto!(d::VNamedD, v::AbstractVector{Float64})
	i0=1
	for i in 1:length(d)
		dd=d[i]
		i0=copyto!(dd,v,i0)
	end
	return d
end

function Base.copyto!(v::AbstractVector{Float64}, d::NamedD,i0=1)
	for dd in d.d
		for i in 1:d[:n]
			for it in 1:length(d.grid)
				v[i0]=dd[it,i]
				i0+=1
			end
		end
	end
	return i0
end

"""
```julia
copyto!(v, srcwav)
```
Same as `vec(srcwav)`, but in-place operation.
"""
function Base.copyto!(v::AbstractVector{Float64}, d::VNamedD)
	i0=1
	for i in 1:length(d)
		dd=d[i]
		i0=copyto!(v,dd,i0)
	end
	return d
end

function Random.randn!(data::NamedD)
	for dd in data.d
		Random.randn!(dd)
	end
	return data
end

"""
Fill `srcwav` with Random values.
"""
function Random.randn!(data::VNamedD)
	for d in data
		Random.randn!(d)
	end
end

function Base.copyto!(dataout::NamedD, data::NamedD)
	for i in names(dataout.d)[1]
		d1=dataout.d[i]
		d2=data.d[i]
		copyto!(d1,d2)
	end
end

"""
```julia
copyto!(srcwav1, srcwav2)
```
Copy `srcwav2` to `srcwav1`, which has same size.
"""
function Base.copyto!(dataout::VNamedD, data::VNamedD)
	for i in 1:length(dataout)
		d1=dataout[i]
		d2=data[i]
		copyto!(d1,d2)
	end
end

function Base.iszero(data::NamedD)
	return maximum(broadcast(maximum,abs,data.d)) == 0.0 ? true : false
end

"""
```julia
iszero(srcwav)
```
Returns bool if `srcwav` has all zeros.
"""
function Base.iszero(data::VNamedD)
	return all([iszero(d) for d in data])
end

function LinearAlgebra.dot(data1::NamedD, data2::NamedD)
	dotd = 0.0;
	for iff in names(data1.d)[1]
		dd1=data1.d[iff]
		dd2=data2.d[iff]
		dotd += LinearAlgebra.dot(dd1,dd2)
	end
	return dotd
end

"""
```julia
dot(srcwav1, srcwav2)
```
Returns dot product. The sizes must match.
"""
function LinearAlgebra.dot(data1::VNamedD, data2::VNamedD)
	dotd = 0.0;
	for i in 1:length(data1)
		dd1=data1[i]
		dd2=data2[i]
		dotd += LinearAlgebra.dot(dd1,dd2)
	end
	return dotd
end

function Base.fill!(data::NamedD, k::Float64)
	for dd in data.d
		fill!(dd,k)
	end
end

"""
```julia
fill!(srcwav, b)
```
In-place method to fill `srcwav` with scalar `b`.
"""
function Base.fill!(data::VNamedD, k::Float64)
	for d in data
		fill!(d,k)
	end
end

function Base.reverse!(data::NamedD)
	for dd in data.d
		for i in 1:data[:n]
			dv=view(dd,:,i)
			reverse!(dv)
		end
	end
end

"""
```julia
reverse!(srcwav)
```
Perform in-place time-reversal operation for each wavelet in `srcwav`.
"""
function Base.reverse!(data::VNamedD)
	for d in data
		reverse!(d)
	end
end

include("misfits.jl")
include("statistics.jl")


text:
# by lazarusA # HIDE
# using GLMakie # HIDE
using CairoMakie, ColorSchemes
CairoMakie.activate!() # HIDE
let
    x = LinRange(0,2π,100) # with 100 points in the interval.
    fig = Figure(resolution = (700, 450), font =:sans)
    ax = Axis(fig, xlabel = "x", ylabel = "")
    line1 = lines!(x, sin.(x), color = x,  colormap = :thermal, linewidth = 2)
    line2 = lines!(x, cos.(x), color = :black,  linewidth = 1)
    line3 = lines!(x, -cos.(x), color = :dodgerblue)
    leg = Legend(fig, [line2, line3], ["  sin(x)", "- cos(x)"], tellwidth = false,
    halign = :left, valign = :top, margin = (10, 10, 10, 10))
    cbar = Colorbar(fig, line1, label = "cos(x)", ticklabelsize = 14,
        labelpadding = 5, width = 10)
    #limits!(ax, 0,2π,-1.01,1.01)
    fig[1, 1] = ax
    fig[1, 1] = leg
    fig[1, 2] = cbar
    colgap!(fig.layout, 5)
    fig
    #save("MulticoloredLinesCbarOut.png", fig, px_per_unit = 2)
    save(joinpath(@__DIR__, "output", "LinesAndMulticoloredLineCbarOut.png"), fig, px_per_unit = 2) # HIDE
end
using Pkg # HIDE
Pkg.status(["CairoMakie", "ColorSchemes"]) # HIDE

max_stars_repo_name: MisterBiggs/BeautifulMakie

max_issues_repo_name: MisterBiggs/BeautifulMakie

max_forks_repo_name: MisterBiggs/BeautifulMakie


text:
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#
# Description
# ==============================================================================
#
#     Define the functions that replica some required C macros.
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

################################################################################
#                                    IOCTL
################################################################################

# Constants and macros obtained from `linux/include/uapi/asm-generic/ioctl.h`
# tag 4.19.

const _IOC_NRBITS   = 8
const _IOC_TYPEBITS = 8

const _IOC_SIZEBITS = 14
const _IOC_DIRBITS  = 2

const _IOC_NRMASK   = ((1 << _IOC_NRBITS)-1)
const _IOC_TYPEMASK = ((1 << _IOC_TYPEBITS)-1)
const _IOC_SIZEMASK = ((1 << _IOC_SIZEBITS)-1)
const _IOC_DIRMASK  = ((1 << _IOC_DIRBITS)-1)

const _IOC_NRSHIFT   = 0
const _IOC_TYPESHIFT = (_IOC_NRSHIFT+_IOC_NRBITS)
const _IOC_SIZESHIFT = (_IOC_TYPESHIFT+_IOC_TYPEBITS)
const _IOC_DIRSHIFT  = (_IOC_SIZESHIFT+_IOC_SIZEBITS)

const _IOC_WRITE = UInt32(1)
const _IOC_READ  = UInt32(2)

_IOC(dir,type,nr,size) = (dir  << _IOC_DIRSHIFT)  |
                         (type << _IOC_TYPESHIFT) |
                         (nr   << _IOC_NRSHIFT)   |
                         (size << _IOC_SIZESHIFT)

_IOW(type,nr,size) = _IOC(_IOC_WRITE, type, nr, size)
_IOR(type,nr,size) = _IOC(_IOC_READ,  type, nr, size)

################################################################################
#                                     I2C
################################################################################

# Constants and macros obtained from `linux/include/uapi/linux/i2c-dev.h` tag
# v4.19.

const I2C_SLAVE       = 0x0703
const I2C_SLAVE_FORCE = 0x0706
const I2C_TENBIT      = 0x0704
const I2C_FUNCS       = 0x0705
const I2C_RDWR        = 0x0707
const I2C_PEC         = 0x0708
const I2C_SMBUS       = 0x0720

# Functionality
# ==============================================================================

# Constants and macros obtained from `linux/include/uapi/linux/i2c.h` tag v4.19.

const I2C_FUNC_I2C                    = 0x00000001
const I2C_FUNC_10BIT_ADDR             = 0x00000002
const I2C_FUNC_PROTOCOL_MANGLING      = 0x00000004
const I2C_FUNC_SMBUS_PEC              = 0x00000008
const I2C_FUNC_NOSTART                = 0x00000010
const I2C_FUNC_SLAVE                  = 0x00000020
const I2C_FUNC_SMBUS_BLOCK_PROC_CALL  = 0x00008000
const I2C_FUNC_SMBUS_QUICK            = 0x00010000
const I2C_FUNC_SMBUS_READ_BYTE        = 0x00020000
const I2C_FUNC_SMBUS_WRITE_BYTE       = 0x00040000
const I2C_FUNC_SMBUS_READ_BYTE_DATA   = 0x00080000
const I2C_FUNC_SMBUS_WRITE_BYTE_DATA  = 0x00100000
const I2C_FUNC_SMBUS_READ_WORD_DATA   = 0x00200000
const I2C_FUNC_SMBUS_WRITE_WORD_DATA  = 0x00400000
const I2C_FUNC_SMBUS_PROC_CALL        = 0x00800000
const I2C_FUNC_SMBUS_READ_BLOCK_DATA  = 0x01000000
const I2C_FUNC_SMBUS_WRITE_BLOCK_DATA = 0x02000000
const I2C_FUNC_SMBUS_READ_I2C_BLOCK   = 0x04000000
const I2C_FUNC_SMBUS_WRITE_I2C_BLOCK  = 0x08000000
const I2C_FUNC_SMBUS_HOST_NOTIFY      = 0x10000000

const  I2C_FUNC_SMBUS_BYTE       = (I2C_FUNC_SMBUS_READ_BYTE |
                                    I2C_FUNC_SMBUS_WRITE_BYTE)
const  I2C_FUNC_SMBUS_BYTE_DATA  = (I2C_FUNC_SMBUS_READ_BYTE_DATA |
                                    I2C_FUNC_SMBUS_WRITE_BYTE_DATA)
const  I2C_FUNC_SMBUS_WORD_DATA  = (I2C_FUNC_SMBUS_READ_WORD_DATA |
                                    I2C_FUNC_SMBUS_WRITE_WORD_DATA)
const  I2C_FUNC_SMBUS_BLOCK_DATA = (I2C_FUNC_SMBUS_READ_BLOCK_DATA |
                                    I2C_FUNC_SMBUS_WRITE_BLOCK_DATA)
const  I2C_FUNC_SMBUS_I2C_BLOCK  = (I2C_FUNC_SMBUS_READ_I2C_BLOCK |
                                    I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)

const I2C_FUNC_SMBUS_EMUL = (I2C_FUNC_SMBUS_QUICK |
                             I2C_FUNC_SMBUS_BYTE |
                             I2C_FUNC_SMBUS_BYTE_DATA |
                             I2C_FUNC_SMBUS_WORD_DATA |
                             I2C_FUNC_SMBUS_PROC_CALL |
                             I2C_FUNC_SMBUS_WRITE_BLOCK_DATA |
                             I2C_FUNC_SMBUS_I2C_BLOCK |
                             I2C_FUNC_SMBUS_PEC)

const I2C_SMBUS_BLOCK_MAX        = UInt8(32)

const I2C_SMBUS_READ             = 0x01
const I2C_SMBUS_WRITE            = 0x00

const I2C_SMBUS_QUICK            = UInt32(0)
const I2C_SMBUS_BYTE             = UInt32(1)
const I2C_SMBUS_BYTE_DATA        = UInt32(2)
const I2C_SMBUS_WORD_DATA        = UInt32(3)
const I2C_SMBUS_PROC_CALL        = UInt32(4)
const I2C_SMBUS_BLOCK_DATA       = UInt32(5)
const I2C_SMBUS_I2C_BLOCK_BROKEN = UInt32(6)
const I2C_SMBUS_BLOCK_PROC_CALL  = UInt32(7)
const I2C_SMBUS_I2C_BLOCK_DATA   = UInt32(8)

################################################################################
#                                     SPI
################################################################################

# Constants and macros obtained from `linux/include/uapi/linux/spi/spidev.h` tag
# v4.19.
const SPI_CPHA      = 0x01
const SPI_CPOL      = 0x02

const SPI_MODE_0    = (0|0)
const SPI_MODE_1    = (0|SPI_CPHA)
const SPI_MODE_2    = (SPI_CPOL|0)
const SPI_MODE_3    = (SPI_CPOL|SPI_CPHA)

const SPI_CS_HIGH   = 0x04
const SPI_LSB_FIRST = 0x08
const SPI_3WIRE     = 0x10
const SPI_LOOP      = 0x20
const SPI_NO_CS     = 0x40
const SPI_READY     = 0x80

const SPI_IOC_MAGIC = UInt('k')

SPI_MSGSIZE(N) =
    ( N*sizeof(struct_spi_ioc_transfer) < (1 << _IOC_SIZEBITS) ) ?
        N*sizeof(struct_spi_ioc_transfer) : 0

# In the past, we were using `NTuple{SPI_MSGSIZE(N), Cchar}` to create a type so
# that the function `_IOC_TYPECHECK(t) = sizeof(t)` could retrieve the correct
# size. However, this was causing 3 allocations. Thus, the system was simplified
# to avoid this. Now, the functions `_IOR` and `_IOW` must receive the size
# instead of the type as it was coded in the Kernel source.
SPI_IOC_MESSAGE(N) = _IOW(SPI_IOC_MAGIC, 0, sizeof(Cchar)*SPI_MSGSIZE(N))

const SPI_IOC_RD_MODE = _IOR(SPI_IOC_MAGIC, 1, sizeof(__u8))
const SPI_IOC_WR_MODE = _IOW(SPI_IOC_MAGIC, 1, sizeof(__u8))

const SPI_IOC_RD_LSB_FIRST = _IOR(SPI_IOC_MAGIC, 2, sizeof(__u8))
const SPI_IOC_WR_LSB_FIRST = _IOW(SPI_IOC_MAGIC, 2, sizeof(__u8))

const SPI_IOC_RD_BITS_PER_WORD = _IOR(SPI_IOC_MAGIC, 3, sizeof(__u8))
const SPI_IOC_WR_BITS_PER_WORD = _IOW(SPI_IOC_MAGIC, 3, sizeof(__u8))

const SPI_IOC_RD_MAX_SPEED_HZ = _IOR(SPI_IOC_MAGIC, 4, sizeof(__u32))
const SPI_IOC_WR_MAX_SPEED_HZ = _IOW(SPI_IOC_MAGIC, 4, sizeof(__u32))


text:
# ---
# title: 648. Replace Words
# id: problem648
# author: Tian Jun
# date: 2020-10-31
# difficulty: Medium
# categories: Hash Table, Trie
# link: <https://leetcode.com/problems/replace-words/description/>
# hidden: true
# ---
#
# In English, we have a concept called **root** , which can be followed by some
# other word to form another longer word - let's call this word **successor**.
# For example, when the **root** `"an"` is followed by the **successor**  word
# `"other"`, we can form a new word `"another"`.
#
# Given a `dictionary` consisting of many **roots** and a `sentence` consisting
# of words separated by spaces, replace all the **successors** in the sentence
# with the **root** forming it. If a **successor** can be replaced by more than
# one **root** , replace it with the **root** that has  **the shortest length**.
#
# Return _the`sentence`_ after the replacement.
#
#
#
# **Example 1:**
#
#
#
#     Input: dictionary = ["cat","bat","rat"], sentence = "the cattle was rattled by the battery"
#     Output: "the cat was rat by the bat"
#
#
# **Example 2:**
#
#
#
#     Input: dictionary = ["a","b","c"], sentence = "aadsfasf absbs bbab cadsfafs"
#     Output: "a a b c"
#
#
# **Example 3:**
#
#
#
#     Input: dictionary = ["a", "aa", "aaa", "aaaa"], sentence = "a aa a aaaa aaa aaa aaa aaaaaa bbb baba ababa"
#     Output: "a a a a a a a a bbb baba a"
#
#
# **Example 4:**
#
#
#
#     Input: dictionary = ["catt","cat","bat","rat"], sentence = "the cattle was rattled by the battery"
#     Output: "the cat was rat by the bat"
#
#
# **Example 5:**
#
#
#
#     Input: dictionary = ["ac","ab"], sentence = "it is abnormal that this solution is accepted"
#     Output: "it is ab that this solution is ac"
#
#
#
#
# **Constraints:**
#
#   * `1 <= dictionary.length <= 1000`
#   * `1 <= dictionary[i].length <= 100`
#   * `dictionary[i]` consists of only lower-case letters.
#   * `1 <= sentence.length <= 10^6`
#   * `sentence` consists of only lower-case letters and spaces.
#   * The number of words in `sentence` is in the range `[1, 1000]`
#   * The length of each word in `sentence` is in the range `[1, 1000]`
#   * Each two consecutive words in `sentence` will be separated by exactly one space.
#   * `sentence` does not have leading or trailing spaces.
#
#
## @lc code=start
using LeetCode

## add your code here:
## @lc code=end


text:
function GeometryFreeCycleSlipDetector(arg0::jdouble, arg1::jdouble, arg2::jint)
    return GeometryFreeCycleSlipDetector((jdouble, jdouble, jint), arg0, arg1, arg2)
end