text:
module JudyDicts

import  Base.getindex,
        Base.setindex!,
        Base.delete!,
        Base.show,
        Base.length,
        Base.start,
        Base.done,
        Base.next

const _judylib = "libJudy"
const MAX_STR_IDX_LEN = (1024*10)
const EMSG_UNSUP_TYPE = "no JudyDict available for this key and value type combination"

export  JudyDict,
        ju_set, ju_unset, ju_get,
        ju_mem_used,
        ju_count, ju_by_count,
        ju_first, ju_next, ju_last, ju_prev,
        ju_first_empty, ju_next_empty, ju_last_empty, ju_prev_empty

type JudyDict{Tk, Tv}
    pjarr::Array{Ptr{Void},1}
    nth_idx::Array
    gc_store::ObjectIdDict
    function JudyDict()
        if(Tk <: Int)
            j = new(zeros(Ptr{Void},1), zeros(Uint, 1), ObjectIdDict())
        elseif(Tk <: Array{Uint8})
            j = new(zeros(Ptr{Void},1), zeros(Uint8, 0), ObjectIdDict())
        elseif(Tk <: String)
            j = new(zeros(Ptr{Void},1), zeros(Uint8, MAX_STR_IDX_LEN), ObjectIdDict())
        else
            error(EMSG_UNSUP_TYPE)
        end
        finalizer(j, ju_free)
        j
    end
end

show(io::IO, j::JudyDict{Int, Bool}) = println(io, (j.pjarr[1] == C_NULL) ? "$(typeof(j)) (empty)" : "$(typeof(j)) (count: $(dec(ju_count(j))))")
show(io::IO, j::JudyDict{Int, Int}) = println(io, (j.pjarr[1] == C_NULL) ? "$(typeof(j)) (empty)" : "$(typeof(j)) (count: $(dec(ju_count(j))))")
show{K,V}(io::IO, j::JudyDict{K, V}) = println(io, (j.pjarr[1] == C_NULL) ? "$(typeof(j)) (empty)" : "$(typeof(j)) (populated)")

macro _ju_free(arr, fn)
    quote
        ccall(($(fn), _judylib), Uint, (Ptr{Ptr{Void}}, Ptr{Void}), $(arr).pjarr, C_NULL)
    end
end

ju_free(arr::JudyDict{Int, Bool}) = @_ju_free arr :Judy1FreeArray
ju_free{V}(arr::JudyDict{Int,V}) = @_ju_free arr :JudyLFreeArray
ju_free{V}(arr::JudyDict{String,V}) = @_ju_free arr :JudySLFreeArray
ju_free{V}(arr::JudyDict{Array{Uint8},V}) = @_ju_free arr :JudyHSFreeArray

## returns bytes of memory used currently by the judy array
ju_mem_used(arr::JudyDict{Int, Bool}) = ccall((:Judy1MemUsed, _judylib), Uint, (Ptr{Void},), arr.pjarr[1])
ju_mem_used{V}(arr::JudyDict{Int,V}) = ccall((:JudyLMemUsed, _judylib), Uint, (Ptr{Void},), arr.pjarr[1])

##
## INDEXABLE COLLECTIONS BEGIN
##

macro _unset(arr, val, idx)
    quote
        (nothing == val) ? (ju_unset(arr, idx); nothing) : error("Unknown value type: $(typeof(val))")
    end
end

delete!(arr::JudyDict{Int, Bool}, idx::Int) = (ju_unset(arr, idx); nothing)
setindex!(arr::JudyDict{Int, Bool}, isset::Bool, idx::Int) = isset ? ju_set(arr, idx) : ju_unset(arr, idx)
getindex(arr::JudyDict{Int, Bool}, idx::Int) = (ju_get(arr, idx) == 1)

#delete!(arr::JudyDict{Int, Int}, idx::Int) = (ju_unset(arr, idx); nothing)
setindex!(arr::JudyDict{Int, Int}, val::Any, idx::Int) = @_unset arr val idx
setindex!(arr::JudyDict{Int, Int}, val::Int, idx::Int) = (C_NULL != ju_set(arr, idx, val)) ? val : error("Error setting value")

delete!{V}(arr::JudyDict{Int,V}, idx::Int) = (ju_unset(arr, idx); nothing)
setindex!{V}(arr::JudyDict{Int,V}, val::V, idx::Int) = (C_NULL != ju_set(arr, idx, val)) ? val : error("Error setting value")
getindex{V}(arr::JudyDict{Int,V}, idx::Int) = ju_get(arr, idx)[1]

delete!{V}(arr::JudyDict{String, V}, idx::String) = (ju_unset(arr, idx); nothing)
setindex!(arr::JudyDict{String, Int}, val::Any, idx::String) = @_unset arr val idx
setindex!(arr::JudyDict{String, Int}, val::Int, idx::String) = (C_NULL != ju_set(arr, idx, val)) ? val : error("Error setting value")
setindex!{V}(arr::JudyDict{String, V}, val::V, idx::String) = (C_NULL != ju_set(arr, idx, val)) ? val : error("Error setting value")
getindex{V}(arr::JudyDict{String, V}, idx::String) = ju_get(arr, idx)[1]

delete!(arr::JudyDict{Array{Uint8}, Int}, idx::Array{Uint8}) = (ju_unset(arr, idx); nothing)
setindex!(arr::JudyDict{Array{Uint8}, Int}, val::Any, idx::Array{Uint8}) = @_unset arr val idx
setindex!(arr::JudyDict{Array{Uint8}, Int}, val::Integer, idx::Array{Uint8}) = (C_NULL != ju_set(arr, idx, val)) ? val : error("Error setting value")
getindex(arr::JudyDict{Array{Uint8}, Int}, idx::Array{Uint8}) = ju_get(arr, idx)[1]

length(arr::JudyDict{Int, Bool}) = int(ju_count(arr))
length{V}(arr::JudyDict{Int,V}) = int(ju_count(arr))

##
## INDEXABLE COLLECTIONS END
##

## set bit at the index
## return 1 if bit was previously unset (successful), otherwise 0 if the bit was already set (unsuccessful).
ju_set(arr::JudyDict{Int, Bool}, idx::Int) = ccall((:Judy1Set, _judylib), Int32, (Ptr{Ptr{Void}}, Uint, Ptr{Void}), arr.pjarr, convert(Uint, idx), C_NULL)

## set value (val) at index (idx)
## return a pointer to the value. the pointer is valid till the next call to a judy method.
## return C_NULL on error
function ju_set{V}(arr::JudyDict{Int,V}, idx::Int, val::V)
    ju_unset(arr, idx)      # unset first to remove old object from gc_store
    ret::Ptr{Uint} = ccall((:JudyLIns, _judylib), Ptr{Uint}, (Ptr{Ptr{Void}}, Uint, Ptr{Void}), arr.pjarr, convert(Uint, idx), C_NULL)
    if (ret != C_NULL)
        arr.gc_store[val] = val
        unsafe_store!(ret, convert(Uint, pointer_from_objref(val)))
    end
    ret
end
function ju_set(arr::JudyDict{Int, Int}, idx::Int, val::Int)
    ret::Ptr{Uint} = ccall((:JudyLIns, _judylib), Ptr{Uint}, (Ptr{Ptr{Void}}, Uint, Ptr{Void}), arr.pjarr, convert(Uint, idx), C_NULL)
    if (ret != C_NULL)
        unsafe_store!(ret, convert(Uint, val))
    end
    ret
end

function ju_set{V}(arr::JudyDict{String, V}, idx::String, val::V)
    @assert length(idx) < MAX_STR_IDX_LEN
    ju_unset(arr, idx)      # unset first to remove old object from gc_store
    ret::Ptr{Uint} = ccall((:JudySLIns, _judylib), Ptr{Uint}, (Ptr{Ptr{Void}}, Ptr{Uint8}, Ptr{Void}), arr.pjarr, idx, C_NULL)
    if (ret != C_NULL)
        arr.gc_store[val] = val
        unsafe_store!(ret, convert(Uint, pointer_from_objref(val)))
    end
    ret
end

function ju_set(arr::JudyDict{String, Int}, idx::String, val::Int)
    @assert length(idx) < MAX_STR_IDX_LEN
    ret::Ptr{Uint} = ccall((:JudySLIns, _judylib), Ptr{Uint}, (Ptr{Ptr{Void}}, Ptr{Uint8}, Ptr{Void}), arr.pjarr, bytestring(idx), C_NULL)
    if (ret != C_NULL)
        unsafe_store!(ret, convert(Uint, val))
    end
    ret
end

function ju_set(arr::JudyDict{Array{Uint8}, Int}, idx::Array{Uint8}, val::Int)
    ret::Ptr{Uint} = ccall((:JudyHSIns, _judylib), Ptr{Uint}, (Ptr{Ptr{Void}}, Ptr{Uint8}, Uint, Ptr{Void}), arr.pjarr, idx, convert(Uint, length(idx)), C_NULL)
    if (ret != C_NULL)
        unsafe_store!(ret, convert(Uint, val))
    end
    ret
end

## get the value at index (if set)
## return 1 if index's bit was set, 0 if it was unset (index was absent).
ju_get(arr::JudyDict{Int, Bool}, idx::Int) = ccall((:Judy1Test, _judylib), Int32, (Ptr{Void}, Uint, Ptr{Void}), arr.pjarr[1], convert(Uint, idx), C_NULL)

## get the value at index (if set)
## return a tuple (value, pointer to value) if index's bit was set, (undefined, C_NULL) if it was unset (index was absent).
## the pointer is valid till the next call to a judy method.
function ju_get(arr::JudyDict{Array{Uint8}, Int}, idx::Array{Uint8})
    ret::Ptr{Uint} = ccall((:JudyHSGet, _judylib), Ptr{Uint}, (Ptr{Void}, Ptr{Uint8}, Uint, Ptr{Void}), arr.pjarr[1], idx, convert(Uint, length(idx)), C_NULL)
    ((ret != C_NULL) ? unsafe_load(ret) : nothing, ret)
end

macro _ju_get(arr, idx, itype, fn)
    quote
        local ret::Ptr{Uint} = ccall(($(fn), _judylib), Ptr{Uint}, (Ptr{Void}, $(itype), Ptr{Void}), $(arr).pjarr[1], $(idx), C_NULL)
        ((ret != C_NULL) ? unsafe_load(ret) : nothing, ret)
    end
end

ju_get(arr::JudyDict{Int, Int}, idx::Int) = @_ju_get arr convert(Uint, idx) Uint :JudyLGet
ju_get(arr::JudyDict{String, Int}, idx::String) = @_ju_get arr bytestring(idx) Ptr{Uint8} :JudySLGet
function ju_get{V}(arr::JudyDict{Int,V}, idx::Int)
    ret_tuple = @_ju_get arr convert(Uint, idx) Uint :JudyLGet
    ((ret_tuple[2] != C_NULL) ? unsafe_pointer_to_objref(convert(Ptr{Void}, ret_tuple[1])) : nothing, ret_tuple[2])
end
function ju_get{V}(arr::JudyDict{String,V}, idx::String)
    ret_tuple = @_ju_get arr bytestring(idx) Ptr{Uint8} :JudySLGet
    ((ret_tuple[2] != C_NULL) ? unsafe_pointer_to_objref(convert(Ptr{Void}, ret_tuple[1])) : nothing, ret_tuple[2])
end

## unset value at index
## return 1 if index was previously set (successful), otherwise 0 if the index was already unset (unsuccessful).
macro _ju_unset(arr, idx, itype, fn)
    quote
        ccall(($(fn), _judylib), Int32, (Ptr{Ptr{Void}}, $(itype), Ptr{Void}), $(arr).pjarr, $(idx), C_NULL)
    end
end

ju_unset(arr::JudyDict{Int, Bool}, idx::Int) = @_ju_unset arr convert(Uint, idx) Uint :Judy1Unset
ju_unset(arr::JudyDict{Int, Int}, idx::Int) = @_ju_unset arr convert(Uint, idx) Uint :JudyLDel
ju_unset(arr::JudyDict{Array{Uint8}, Int}, idx::Array{Uint8}) = ccall((:JudyHSDel, _judylib), Int32, (Ptr{Ptr{Void}}, Ptr{Uint8}, Uint, Ptr{Void}), arr.pjarr, idx, convert(Uint, length(idx)), C_NULL)
function ju_unset{V}(arr::JudyDict{Int,V}, idx::Int)
    ret_tuple = ju_get(arr, idx)
    if(ret_tuple[2] != C_NULL)
        # we had a value set there. unset it from the array and delete the stored reference from gc_store
        ret = @_ju_unset arr convert(Uint, idx) Uint :JudyLDel
        delete!(arr.gc_store, ret_tuple[1])
        return ret
    end
    int32(0)
end
ju_unset(arr::JudyDict{String, Int}, idx::String) = @_ju_unset arr bytestring(idx) Ptr{Uint8} :JudySLDel
function ju_unset{V}(arr::JudyDict{String,V}, idx::String)
    ret_tuple = ju_get(arr, idx)
    if(ret_tuple[2] != C_NULL)
        # we had a value set there. unset it from the array and delete the stored reference from gc_store
        ret = @_ju_unset arr idx Ptr{Uint8} :JudySLDel
        delete!(arr.gc_store, ret_tuple[1])
        return ret
    end
    int32(0)
end

## count the number of indexes present between idx1 and idx2 (inclusive).
## returns the count.
## a return value of 0 can be valid as a count, or it can indicate a special case for fully populated array (32-bit machines only).
## see Judy documentation for ways to resolve this.
ju_count(arr::JudyDict{Int, Bool}, idx1::Int=0, idx2::Int=-1) = ccall((:Judy1Count, _judylib), Uint, (Ptr{Void}, Uint, Uint, Ptr{Void}), arr.pjarr[1], convert(Uint, idx1), convert(Uint, idx2), C_NULL)
ju_count{V}(arr::JudyDict{Int,V}, idx1::Int=0, idx2::Int=-1) = ccall((:JudyLCount, _judylib), Uint, (Ptr{Void}, Uint, Uint, Ptr{Void}), arr.pjarr[1], convert(Uint, idx1), convert(Uint, idx2), C_NULL)

## locate the nth index that is present (n starts wih 1)
## to refer to the last index in a fully populated array (all indexes present, which is rare), use n = 0.
## return tuple (1, index_pos) on success or (0, undefined) on not found/error
function ju_by_count(arr::JudyDict{Int, Bool}, n::Int)
    ret::Int32 = ccall((:Judy1ByCount, _judylib), Int32, (Ptr{Void}, Uint, Ptr{Uint}, Ptr{Void}), arr.pjarr[1], convert(Uint, n), pointer(arr.nth_idx), C_NULL)
    return (ret, arr.nth_idx[1])
end

## locate the nth index that is present (n starts wih 1)
## return tuple (value at index, pointer to value, index_pos) on success or (undefined, C_NULL, undefined) on not found/error
function ju_by_count(arr::JudyDict{Int,Int}, n::Int)
    ret::Ptr{Uint} = ccall((:JudyLByCount, _judylib), Ptr{Uint}, (Ptr{Void}, Uint, Ptr{Uint}, Ptr{Void}), arr.pjarr[1], convert(Uint, n), pointer(arr.nth_idx), C_NULL)
    ret_val::Uint = (ret != C_NULL) ? unsafe_load(ret) : C_NULL
    return (ret_val, ret, arr.nth_idx[1])
end
function ju_by_count{V}(arr::JudyDict{Int,V}, n::Int)
    ret::Ptr{Uint} = ccall((:JudyLByCount, _judylib), Ptr{Uint}, (Ptr{Void}, Uint, Ptr{Uint}, Ptr{Void}), arr.pjarr[1], convert(Uint, n), pointer(arr.nth_idx), C_NULL)
    if(ret != C_NULL)
        ret_val::Uint = unsafe_load(ret)
        (unsafe_pointer_to_objref(convert(Ptr{Void}, ret_val)), ret, arr.nth_idx[1])
    else
        (nothing, C_NULL, arr.nth_idx[1])
    end
end

macro _strlen(ba)
    quote
        ccall((:strlen, "libc"), Uint, (Ptr{Uint8},), $(ba))
    end
end

macro _strcpy(dest, src)
    quote
        ccall((:strcpy, "libc"), Ptr{Uint8}, (Ptr{Uint8},Ptr{Uint8}), $(dest), $(src))
    end
end

## iterators. return tuple of (value, index)
start(arr::JudyDict{Int, Bool}) = ju_first(arr)
done(arr::JudyDict{Int, Bool}, state) = (0 == state[1])
next(arr::JudyDict{Int, Bool}, state) = done(arr, state) ? (nothing, state) : ((true, state[2]), ju_next(arr))

start{V}(arr::JudyDict{Int, V}) = ju_first(arr)
done{V}(arr::JudyDict{Int, V}, state) = (C_NULL == state[2])
next{V}(arr::JudyDict{Int, V}, state) = done(arr, state) ? (nothing, state) : ((state[1], state[3]), ju_next(arr))

start{V}(arr::JudyDict{String, V}) = ju_first(arr)
done{V}(arr::JudyDict{String, V}, state) = (C_NULL == state[2])
next{V}(arr::JudyDict{String, V}, state) = done(arr, state) ? (nothing, state) : ((state[1], state[3]), ju_next(arr))

## The base iteration methods return a pointer to the value as well
function ju_first(arr::JudyDict{Int, Bool}, idx::Int=0)
    arr.nth_idx[1] = convert(Uint, idx)
    ret::Int32 = ccall((:Judy1First, _judylib), Int32, (Ptr{Void}, Ptr{Uint}, Ptr{Void}), arr.pjarr[1], pointer(arr.nth_idx), C_NULL)
    return (ret, arr.nth_idx[1])
end

function ju_first(arr::JudyDict{Int, Int}, idx::Int=0)
    arr.nth_idx[1] = convert(Uint, idx)
    ret::Ptr{Uint} = ccall((:JudyLFirst, _judylib), Ptr{Uint}, (Ptr{Void}, Ptr{Uint}, Ptr{Void}), arr.pjarr[1], pointer(arr.nth_idx), C_NULL)
    ret_val::Uint = (ret != C_NULL) ? unsafe_load(ret) : C_NULL
    return (ret_val, ret, arr.nth_idx[1])
end
function ju_first{V}(arr::JudyDict{Int, V}, idx::Int=0)
    arr.nth_idx[1] = convert(Uint, idx)
    ret::Ptr{Uint} = ccall((:JudyLFirst, _judylib), Ptr{Uint}, (Ptr{Void}, Ptr{Uint}, Ptr{Void}), arr.pjarr[1], pointer(arr.nth_idx), C_NULL)
    if(ret != C_NULL)
        return (unsafe_pointer_to_objref(convert(Ptr{Void}, unsafe_load(ret))), ret, arr.nth_idx[1])
    end
    (C_NULL, C_NULL, arr.nth_idx[1])
end

function ju_first(arr::JudyDict{String, Int}, idx::String="")
    @assert length(idx) < MAX_STR_IDX_LEN
    @_strcpy arr.nth_idx bytestring(idx)
    ret::Ptr{Uint} = ccall((:JudySLFirst, _judylib), Ptr{Uint}, (Ptr{Void}, Ptr{Uint8}, Ptr{Void}), arr.pjarr[1], pointer(arr.nth_idx), C_NULL)
    if(ret != C_NULL)
        len::Uint = @_strlen arr.nth_idx
        return (unsafe_load(ret), ret, ASCIIString(arr.nth_idx[1:len]))
    end
    (uint(0), C_NULL, "")
end
function ju_first{V}(arr::JudyDict{String, V}, idx::String="")
    @assert length(idx) < MAX_STR_IDX_LEN
    @_strcpy arr.nth_idx bytestring(idx)
    ret::Ptr{Uint} = ccall((:JudySLFirst, _judylib), Ptr{Uint}, (Ptr{Void}, Ptr{Uint8}, Ptr{Void}), arr.pjarr[1], pointer(arr.nth_idx), C_NULL)
    if(ret != C_NULL)
        len::Uint = @_strlen arr.nth_idx
        return (unsafe_pointer_to_objref(convert(Ptr{Void}, unsafe_load(ret))), ret, ASCIIString(arr.nth_idx[1:len]))
    end
    (nothing, C_NULL, "")
end

ju_next(arr::JudyDict{Int, Bool}, idx::Int) = ju_next(arr, convert(Uint, idx))
function ju_next(arr::JudyDict{Int, Bool}, idx::Uint)
    arr.nth_idx[1] = idx
    ju_next(arr)
end
function ju_next(arr::JudyDict{Int, Bool})
    ret::Int32 = ccall((:Judy1Next, _judylib), Int32, (Ptr{Void}, Ptr{Uint}, Ptr{Void}), arr.pjarr[1], pointer(arr.nth_idx), C_NULL)
    return (ret, arr.nth_idx[1])
end

function ju_next{V}(arr::JudyDict{Int, V}, idx::Int)
    arr.nth_idx[1] = convert(Uint, idx)
    ju_next(arr)
end
function ju_next(arr::JudyDict{Int, Int})
    ret::Ptr{Uint} = ccall((:JudyLNext, _judylib), Ptr{Uint}, (Ptr{Void}, Ptr{Uint}, Ptr{Void}), arr.pjarr[1], pointer(arr.nth_idx), C_NULL)
    ret_val::Uint = (ret != C_NULL) ? unsafe_load(ret) : C_NULL
    return (ret_val, ret, arr.nth_idx[1])
end
function ju_next{V}(arr::JudyDict{Int, V})
    ret::Ptr{Uint} = ccall((:JudyLNext, _judylib), Ptr{Uint}, (Ptr{Void}, Ptr{Uint}, Ptr{Void}), arr.pjarr[1], pointer(arr.nth_idx), C_NULL)
    if(ret != C_NULL)
        return (unsafe_pointer_to_objref(convert(Ptr{Void}, unsafe_load(ret))), ret, arr.nth_idx[1])
    end
    (C_NULL, C_NULL, arr.nth_idx[1])
end

function ju_next{V}(arr::JudyDict{String, V}, idx::String)
    @assert length(idx) < MAX_STR_IDX_LEN
    @_strcpy arr.nth_idx bytestring(idx)
    ju_next(arr)
end
function ju_next(arr::JudyDict{String, Int})
    ret::Ptr{Uint} = ccall((:JudySLNext, _judylib), Ptr{Uint}, (Ptr{Void}, Ptr{Uint8}, Ptr{Void}), arr.pjarr[1], pointer(arr.nth_idx), C_NULL)
    if(ret != C_NULL)
        len::Uint = @_strlen arr.nth_idx
        return (unsafe_load(ret), ret, ASCIIString(arr.nth_idx[1:len]))
    end
    (uint(0), C_NULL, "")
end
function ju_next{V}(arr::JudyDict{String, V})
    ret::Ptr{Uint} = ccall((:JudySLNext, _judylib), Ptr{Uint}, (Ptr{Void}, Ptr{Uint8}, Ptr{Void}), arr.pjarr[1], pointer(arr.nth_idx), C_NULL)
    if(ret != C_NULL)
        len::Uint = @_strlen arr.nth_idx
        return (unsafe_pointer_to_objref(convert(Ptr{Void}, unsafe_load(ret))), ret, ASCIIString(arr.nth_idx[1:len]))
    end
    (nothing, C_NULL, "")
end

function ju_last(arr::JudyDict{Int, Bool}, idx::Int=-1)
    arr.nth_idx[1] = convert(Uint, idx)
    ret::Int32 = ccall((:Judy1Last, _judylib), Int32, (Ptr{Void}, Ptr{Uint}, Ptr{Void}), arr.pjarr[1], pointer(arr.nth_idx), C_NULL)
    return (ret, arr.nth_idx[1])
end

function ju_last(arr::JudyDict{Int, Int}, idx::Int=-1)
    arr.nth_idx[1] = convert(Uint, idx)
    ret::Ptr{Uint} = ccall((:JudyLLast, _judylib), Ptr{Uint}, (Ptr{Void}, Ptr{Uint}, Ptr{Void}), arr.pjarr[1], pointer(arr.nth_idx), C_NULL)
    ret_val::Uint = (ret != C_NULL) ? unsafe_load(ret) : C_NULL
    return (ret_val, ret, arr.nth_idx[1])
end
function ju_last{V}(arr::JudyDict{Int, V}, idx::Int=-1)
    arr.nth_idx[1] = convert(Uint, idx)
    ret::Ptr{Uint} = ccall((:JudyLLast, _judylib), Ptr{Uint}, (Ptr{Void}, Ptr{Uint}, Ptr{Void}), arr.pjarr[1], pointer(arr.nth_idx), C_NULL)
    if(ret != C_NULL)
        return (unsafe_pointer_to_objref(convert(Ptr{Void}, unsafe_load(ret))), ret, arr.nth_idx[1])
    end
    return (C_NULL, C_NULL, arr.nth_idx[1])
end

function ju_last(arr::JudyDict{String, Int})
    ccall((:memset, "libc"), Ptr{Uint8}, (Ptr{Uint8}, Uint8, Uint), pointer(arr.nth_idx), 0xff, MAX_STR_IDX_LEN-1)
    arr.nth_idx[MAX_STR_IDX_LEN-1] = 0
    ret::Ptr{Uint} = ccall((:JudySLLast, _judylib), Ptr{Uint}, (Ptr{Void}, Ptr{Uint8}, Ptr{Void}), arr.pjarr[1], pointer(arr.nth_idx), C_NULL)
    if(ret != C_NULL)
        ret_val::Uint = unsafe_load(ret)
        len::Uint = @_strlen arr.nth_idx
        return (ret_val, ret, ASCIIString(arr.nth_idx[1:len]))
    end
    (uint(0), C_NULL, "")
end
function ju_last(arr::JudyDict{String, Int}, idx::String)
    @assert length(idx) < MAX_STR_IDX_LEN
    @_strcpy arr.nth_idx bytestring(idx)
    ret::Ptr{Uint} = ccall((:JudySLLast, _judylib), Ptr{Uint}, (Ptr{Void}, Ptr{Uint8}, Ptr{Void}), arr.pjarr[1], pointer(arr.nth_idx), C_NULL)
    if(ret != C_NULL)
        ret_val::Uint = unsafe_load(ret)
        len::Uint = @_strlen arr.nth_idx
        return (ret_val, ret, ASCIIString(arr.nth_idx[1:len]))
    end
    (uint(0), C_NULL, "")
end
function ju_last{V}(arr::JudyDict{String, V})
    ccall((:memset, "libc"), Ptr{Uint8}, (Ptr{Uint8}, Uint8, Uint), pointer(arr.nth_idx), 0xff, MAX_STR_IDX_LEN-1)
    arr.nth_idx[MAX_STR_IDX_LEN-1] = 0
    ret::Ptr{Uint} = ccall((:JudySLLast, _judylib), Ptr{Uint}, (Ptr{Void}, Ptr{Uint8}, Ptr{Void}), arr.pjarr[1], pointer(arr.nth_idx), C_NULL)
    if(ret != C_NULL)
        len::Uint = @_strlen arr.nth_idx
        return (unsafe_pointer_to_objref(convert(Ptr{Void}, unsafe_load(ret))), ret, ASCIIString(arr.nth_idx[1:len]))
    end
    (nothing, C_NULL, "")
end
function ju_last{V}(arr::JudyDict{String, V}, idx::String)
    @assert length(idx) < MAX_STR_IDX_LEN
    @_strcpy arr.nth_idx bytestring(idx)
    ret::Ptr{Uint} = ccall((:JudySLLast, _judylib), Ptr{Uint}, (Ptr{Void}, Ptr{Uint8}, Ptr{Void}), arr.pjarr[1], pointer(arr.nth_idx), C_NULL)
    if(ret != C_NULL)
        len::Uint = @_strlen arr.nth_idx
        return (unsafe_pointer_to_objref(convert(Ptr{Void}, unsafe_load(ret))), ret, ASCIIString(arr.nth_idx[1:len]))
    end
    (nothing, C_NULL, "")
end

ju_prev(arr::JudyDict{Int, Bool}, idx::Int) = ju_prev(arr, convert(Uint, idx))
function ju_prev(arr::JudyDict{Int, Bool}, idx::Uint)
    arr.nth_idx[1] = idx
    ju_prev(arr)
end
function ju_prev(arr::JudyDict{Int, Bool})
    ret::Int32 = ccall((:Judy1Prev, _judylib), Int32, (Ptr{Void}, Ptr{Uint}, Ptr{Void}), arr.pjarr[1], pointer(arr.nth_idx), C_NULL)
    return (ret, arr.nth_idx[1])
end

function ju_prev{V}(arr::JudyDict{Int, V}, idx::Int)
    arr.nth_idx[1] = convert(Uint, idx)
    ju_prev(arr)
end
function ju_prev(arr::JudyDict{Int, Int})
    ret::Ptr{Uint} = ccall((:JudyLPrev, _judylib), Ptr{Uint}, (Ptr{Void}, Ptr{Uint}, Ptr{Void}), arr.pjarr[1], pointer(arr.nth_idx), C_NULL)
    ret_val::Uint = (ret != C_NULL) ? unsafe_load(ret) : C_NULL
    return (ret_val, ret, arr.nth_idx[1])
end
function ju_prev{V}(arr::JudyDict{Int, V})
    ret::Ptr{Uint} = ccall((:JudyLPrev, _judylib), Ptr{Uint}, (Ptr{Void}, Ptr{Uint}, Ptr{Void}), arr.pjarr[1], pointer(arr.nth_idx), C_NULL)
    if(ret != C_NULL)
        return (unsafe_pointer_to_objref(convert(Ptr{Void}, unsafe_load(ret))), ret, arr.nth_idx[1])
    end
    return (C_NULL, C_NULL, arr.nth_idx[1])
end

function ju_prev{V}(arr::JudyDict{String, V}, idx::String)
    @assert length(idx) < MAX_STR_IDX_LEN
    @_strcpy arr.nth_idx bytestring(idx)
    ju_prev(arr)
end
function ju_prev(arr::JudyDict{String, Int})
    ret::Ptr{Uint} = ccall((:JudySLPrev, _judylib), Ptr{Uint}, (Ptr{Void}, Ptr{Uint}, Ptr{Void}), arr.pjarr[1], pointer(arr.nth_idx), C_NULL)
    if(ret != C_NULL)
        ret_val::Uint = unsafe_load(ret)
        len::Uint = @_strlen arr.nth_idx
        return (ret_val, ret, ASCIIString(arr.nth_idx[1:len]))
    end
    (0, C_NULL, "")
end
function ju_prev{V}(arr::JudyDict{String, V})
    ret::Ptr{Uint} = ccall((:JudySLPrev, _judylib), Ptr{Uint}, (Ptr{Void}, Ptr{Uint}, Ptr{Void}), arr.pjarr[1], pointer(arr.nth_idx), C_NULL)
    if(ret != C_NULL)
        len::Uint = @_strlen arr.nth_idx
        return (unsafe_pointer_to_objref(convert(Ptr{Void}, unsafe_load(ret))), ret, ASCIIString(arr.nth_idx[1:len]))
    end
    (nothing, C_NULL, "")
end

macro _ju_iter_empty_cont(arr, fn)
    quote
        ret::Int32 = ccall(($(fn), _judylib), Ptr{Uint}, (Ptr{Void}, Ptr{Uint}, Ptr{Void}), $(arr).pjarr[1], pointer($(arr).nth_idx), C_NULL)
        (ret, $(arr).nth_idx[1])
    end
end

macro _ju_iter_empty(arr, idx, fn)
    quote
        $(arr).nth_idx[1] = $(idx)
        @_ju_iter_empty_cont $(arr) $(fn)
    end
end

ju_first_empty(arr::JudyDict{Int, Bool}, idx::Int=0) = @_ju_iter_empty arr convert(Uint, idx) :Judy1FirstEmpty
ju_first_empty{V}(arr::JudyDict{Int, V}, idx::Int=0) = @_ju_iter_empty arr convert(Uint, idx) :JudyLFirstEmpty

ju_next_empty(arr::JudyDict{Int, Bool}, idx::Int) = @_ju_iter_empty arr convert(Uint, idx) :Judy1NextEmpty
ju_next_empty(arr::JudyDict{Int, Bool}) = @_ju_iter_empty_cont arr :Judy1NextEmpty

ju_next_empty{V}(arr::JudyDict{Int, V}, idx::Int) = @_ju_iter_empty arr convert(Uint, idx) :JudyLNextEmpty
ju_next_empty{V}(arr::JudyDict{Int, V}) = @_ju_iter_empty_cont arr :JudyLNextEmpty

ju_last_empty(arr::JudyDict{Int, Bool}, idx::Int=-1) = @_ju_iter_empty arr convert(Uint, idx) :Judy1LastEmpty
ju_last_empty{V}(arr::JudyDict{Int, V}, idx::Int=-1) = @_ju_iter_empty arr convert(Uint, idx) :JudyLLastEmpty

ju_prev_empty(arr::JudyDict{Int, Bool}, idx::Int) = @_ju_iter_empty arr convert(Uint, idx) :Judy1PrevEmpty
ju_prev_empty(arr::JudyDict{Int, Bool}) = @_ju_iter_empty_cont arr :Judy1PrevEmpty

ju_prev_empty{V}(arr::JudyDict{Int, V}, idx::Int) = @_ju_iter_empty arr convert(Uint, idx) :JudyLPrevEmpty
ju_prev_empty{V}(arr::JudyDict{Int, V}) = @_ju_iter_empty_cont arr :JudyLPrevEmpty

end


text:
function *(A::PotLogArray,B::PotLogArray)
    logprefactor=maximum([maximum(A.content[:]) maximum(B.content[:])]);
    AA=PotArray(A.variables,exp.(A.content-logprefactor))
    BB=PotArray(B.variables,exp.(B.content-logprefactor))
    AB=AA*BB
    L=PotLogArray(AB.variables,2*logprefactor+log.(AB.content))
    return L
end

function /(A::PotLogArray,B::PotLogArray)
    BB=deepcopy(B)
    BB.content=-BB.content
    return A*BB
end

function +(A::PotLogArray,B::PotLogArray)
    logprefactor=maximum([maximum(A.content[:]) maximum(B.content[:])]);
    AA=PotArray(A.variables,exp.(A.content-logprefactor))
    BB=PotArray(B.variables,exp.(B.content-logprefactor))
    AB=AA+BB
    L=PotLogArray(AB.variables,logprefactor+log.(AB.content))
    return L
end

function -(A::PotLogArray,B::PotLogArray)
    logprefactor=maximum([maximum(A.content[:]) maximum(B.content[:])]);
    AA=PotArray(A.variables,exp.(A.content-logprefactor))
    BB=PotArray(B.variables,exp.(B.content-logprefactor))
    AB=AA-BB
    L=PotLogArray(AB.variables,logprefactor+log.(AB.content))
    return L
end

function *(A::PotArray,B::PotLogArray)
    logprefactor=maximum([maximum(log.(A.content[:])) maximum(B.content[:])]);
    AA=PotArray(A.variables,exp.(log.(A.content)-logprefactor))
    BB=PotArray(B.variables,exp.(B.content-logprefactor))
    AB=AA*BB
    L=PotLogArray(AB.variables,2*logprefactor+log.(AB.content))
    return L
end

function *(A::PotLogArray,B::Const)
    return B*A
end

function *(A::PotLogArray,B::PotArray)
    return B*A
end

function sum(A::PotLogArray,variables=A.variables;SumOver::Any=true)
    # Sum a PotLogArray over specified variables
    # eg sum(pot,[1 2])
    # sum(pot,[1 2],false) sums over all variables in pot except for [1 2]

    A=standardise(A) # makes A a vector potential if A is 1 D array

    logprefactor=maximum(A.content[:]);
    pA=PotArray(A.variables,exp.(A.content-logprefactor))

    if !SumOver
        variables = setdiff(A.variables,variables);
    end

    newvars=setdiff(A.variables,variables)
    table_variables=memberinds(variables,A.variables)
    tmp=sum(pA.content,table_variables)
    #tmp=squeeze(tmp,find(memberinds(size(tmp),1)))
    tmp=squeeze(tmp,tuple(find(memberinds(size(tmp),1))...))

    return PotLogArray(newvars,log.(tmp)+logprefactor)
end

ext: jl


text:
#   This file is part of UnitSystems.jl
#   It is licensed under the MIT license
#   UnitSystems Copyright (C) 2020 Michael Reed
#       _           _                         _
#      | |         | |                       | |
#   ___| |__   __ _| | ___ __ __ ___   ____ _| | __ _
#  / __| '_ \ / _` | |/ / '__/ _` \ \ / / _` | |/ _` |
# | (__| | | | (_| |   <| | | (_| |\ V / (_| | | (_| |
#  \___|_| |_|\__,_|_|\_\_|  \__,_| \_/ \__,_|_|\__,_|
#
#   https://github.com/chakravala
#   https://crucialflow.com

@doc """
    T/K == (9/5)*T

Converts temperature `T` from Kelvin to degrees Rankine (°R).
""" K

@doc """
    T/°R == (5/9)*T

Converts temperature `T` from degrees Rankine to Kelvin (K).
""" °R

"""
    moles(N::Real,U::UnitSystem=Metric) = N/avogadro(U)

Converts the number of molecules `N` to number of moles (mol).
"""
@pure moles(N::Number,U::UnitSystem=Metric) = N/avogadro(U)

"""
    molecules(n::Real,U::UnitSystem=Metric) = n*avogadro(U)

Converts the number of moles `n` to number of molecules (dimensionless).
"""
@pure molecules(n::Number,U::UnitSystem=Metric) = n*avogadro(U)

# thermodynamics

@pure temperature(U::UnitSystem,S::UnitSystem) = unit((boltzmann(U)*electronmass(S)*lightspeed(S)^2*gravity(U))/(boltzmann(S)*electronmass(U)*lightspeed(U)^2*gravity(S)))
@pure entropy(U::UnitSystem,S::UnitSystem) = unit(energy(U,S)/temperature(U,S))
@pure specificentropy(U::UnitSystem,S::UnitSystem) = unit(specificenergy(U,S)/temperature(U,S))
@pure volumeheatcapacity(U::UnitSystem,S::UnitSystem) = unit(entropy(U,S)/volume(U,S))
@pure thermalconductivity(U::UnitSystem,S::UnitSystem) = unit(force(U,S)/time(U,S)/temperature(U,S))
@pure thermalconductance(U::UnitSystem,S::UnitSystem) = unit(thermalconductivity(U,S)*length(U,S))
@pure thermalresistivity(U::UnitSystem,S::UnitSystem) = thermalconductivity(S,U)
@pure thermalresistance(U::UnitSystem,S::UnitSystem) = thermalconductance(S,U)
@pure thermalexpansion(U::UnitSystem,S::UnitSystem) = temperature(S,U)
@pure lapserate(U::UnitSystem,S::UnitSystem) = unit(temperature(U,S)/length(U,S))

# molar

@pure molality(U::UnitSystem,S::UnitSystem) = molarmass(S,U)
@pure molaramount(U::UnitSystem,S::UnitSystem) = unit(mass(U,S)*molality(U,S))
@pure molarity(U::UnitSystem,S::UnitSystem) = unit(molaramount(U,S)/volume(U,S))
@pure molarvolume(U::UnitSystem,S::UnitSystem) = unit(volume(U,S)/molaramount(U,S))
@pure molarentropy(U::UnitSystem,S::UnitSystem) = unit(entropy(U,S)/molaramount(U,S))
@pure molarenergy(U::UnitSystem,S::UnitSystem) = unit(energy(U,S)/molaramount(U,S))
@pure molarconductivity(U::UnitSystem,S::UnitSystem) = unit(conductivity(U,S)*area(U,S)/molaramount(U,S))
@pure molarsusceptibility(U::UnitSystem,S::UnitSystem) = unit(specificsusceptibility(U,S)*molarmass(U,S))
@pure catalysis(U::UnitSystem,S::UnitSystem) = unit(molaramount(U,S)/time(U,S))
@pure specificity(U::UnitSystem,S::UnitSystem) = unit(volume(U,S)/molaramount(U,S)/time(U,S))

# photometrics

@pure luminousflux(U::UnitSystem,S::UnitSystem) = unit(frequency(U,S)*luminousenergy(U,S))
@pure luminousintensity(U::UnitSystem,S::UnitSystem) = unit(luminousflux(U,S)/solidangle(U,S))
@pure illuminance(U::UnitSystem,S::UnitSystem) = unit(luminousflux(U,S)/area(U,S))
@pure luminance(U::UnitSystem,S::UnitSystem) = unit(luminousintensity(U,S)/area(U,S))
@pure luminousenergy(U::UnitSystem,S::UnitSystem) = unit(frequency(U,S)*(luminousefficacy(S)*planck(S))/(luminousefficacy(U)*planck(U)))
@pure luminousexposure(U::UnitSystem,S::UnitSystem) = unit(illuminance(U,S)*time(U,S))

include("thermodynamicdocs.jl")


text:
# Perform a *successful* step
function DiffEqBase.step!(integrator::ODEFilterIntegrator)
    loopheader!(integrator)
    check_error!(integrator) != :Success && return
    perform_step!(integrator)
    loopfooter!(integrator)
    while !integrator.accept_step
        loopheader!(integrator)
        check_error!(integrator) != :Success && return
        perform_step!(integrator)
        loopfooter!(integrator)
    end
end

function check_error!(integrator::ODEFilterIntegrator)
    code = check_error(integrator)
    if code != :Success
        integrator.retcode = code
        postamble!(integrator)
    end
    return code
end

max_stars_repo_name: nathanaelbosch/capos

max_issues_repo_name: nathanaelbosch/capos

max_forks_repo_name: nathanaelbosch/capos


text:
using Documenter, FinancialToolbox

makedocs(format = Documenter.HTML(
        prettyurls = get(ENV, "CI", nothing) == "true",
		assets = ["assets/favicon.ico","assets/logo.png"]    ),
	sitename="FinancialToolbox.jl",
	modules = [FinancialToolbox],
		pages = [
				"index.md",
				"starting.md",
				"dates.md",
				"bls.md"
			])
get(ENV, "CI", nothing) == "true" ? deploydocs(
    repo = "github.com/rcalxrc08/FinancialToolbox.jl.git",
) : nothing;


text:
function nthetas(lshaped::AbstractLShapedSolver, ::AbstractExecution)
    return nthetas(lshaped.nscenarios, lshaped.aggregation, scenarioproblems(lshaped.stochasticprogram))
end

function timestamp(lshaped::AbstractLShapedSolver, ::AbstractExecution)
    return lshaped.data.iterations
end

function current_decision(lshaped::AbstractLShapedSolver, ::AbstractExecution)
    return lshaped.x
end

function incumbent_decision(::AbstractLShapedSolver, ::Integer, regularization::AbstractRegularization, ::AbstractExecution)
    return regularization.ξ
end

function incumbent_objective(::AbstractLShapedSolver, ::Integer, regularization::AbstractRegularization, ::AbstractExecution)
    return regularization.data.Q̃
end

function incumbent_trustregion(::AbstractLShapedSolver, ::Integer, rd::RegularizedDecomposition, ::AbstractExecution)
    return rd.data.σ
end

function incumbent_trustregion(::AbstractLShapedSolver, ::Integer, tr::TrustRegion, ::AbstractExecution)
    return tr.data.Δ
end

function start_workers!(::AbstractLShapedSolver, ::AbstractExecution)
    return nothing
end

function close_workers!(::AbstractLShapedSolver, ::AbstractExecution)
    return nothing
end

function readd_cuts!(lshaped::AbstractLShapedSolver, consolidation::Consolidation, ::AbstractExecution)
    for i in eachindex(consolidation.cuts)
        for cut in consolidation.cuts[i]
            add_cut!(lshaped, cut; consider_consolidation = false, check = false)
        end
        for cut in consolidation.feasibility_cuts[i]
            add_cut!(lshaped, cut; consider_consolidation = false, check = false)
        end
    end
    return nothing
end

function subobjectives(lshaped::AbstractLShapedSolver, execution::AbstractExecution)
    return execution.subobjectives
end

function set_subobjectives(lshaped::AbstractLShapedSolver, Qs::AbstractVector, execution::AbstractExecution)
    execution.subobjectives .= Qs
    return nothing
end

function model_objectives(lshaped::AbstractLShapedSolver, execution::AbstractExecution)
    return execution.model_objectives
end

function set_model_objectives(lshaped::AbstractLShapedSolver, θs::AbstractVector, execution::AbstractExecution)
    ids = active_model_objectives(lshaped)
    execution.model_objectives[ids] .= θs[ids]
    return nothing
end

function solve_master!(lshaped::AbstractLShapedSolver, ::AbstractExecution)
    try
        solve_regularized_master!(lshaped, lshaped.regularization)
    catch
        # Master problem could not be solved for some reason.
        @unpack Q,θ = lshaped.data
        gap = abs(θ-Q)/(abs(Q)+1e-10)
        # Always print this warning
        @warn "Master problem could not be solved, solver returned status $(status(lshaped.mastersolver)). The following relative tolerance was reached: $(@sprintf("%.1e",gap)). Aborting procedure."
        return :StoppedPrematurely
    end
    if status(lshaped.mastersolver) == :Infeasible
        @warn "Master is infeasible. Aborting procedure."
        return :Infeasible
    end
    if status(lshaped.mastersolver) == :Unbounded
        @warn "Master is unbounded. Aborting procedure."
        return :Unbounded
    end
    return :Optimal
end

function iterate!(lshaped::AbstractLShapedSolver, ::AbstractExecution)
    # Resolve all subproblems at the current optimal solution
    Q, added = resolve_subproblems!(lshaped)
    if Q == Inf && !handle_feasibility(lshaped.feasibility)
        @warn "Stochastic program is not second-stage feasible at the current decision. Rerun procedure with feasibility_cuts = true to use feasibility cuts."
        return :Infeasible
    end
    if Q == -Inf
        return :Unbounded
    end
    lshaped.data.Q = Q
    # Update incumbent (if applicable)
    take_step!(lshaped)
    # Solve master problem
    status = solve_master!(lshaped)
    if status != :Optimal
        return status
    end
    # Update master solution
    update_solution!(lshaped, lshaped.mastersolver)
    lshaped.data.θ = calculate_estimate(lshaped)
    # Log progress
    log!(lshaped)
    # Check optimality
    if check_optimality(lshaped) || (lshaped.regularization isa NoRegularization && !added)
        # Optimal
        lshaped.data.Q = calculate_objective_value(lshaped)
        # Final log
        log!(lshaped; optimal = true)
        return :Optimal
    end
    # Project (if applicable)
    project!(lshaped)
    # Consolidate (if applicable)
    consolidate!(lshaped, lshaped.consolidation)
    # Just return a valid status for this iteration
    return :Valid
end


text:
function base64url_encode(s) :: String
    encoded_str = Base64URL.base64urlencode(s)

    # removes trailing padding
    for i in lastindex(encoded_str):-1:1 # encoded_str is made of ASCII chars only
        if encoded_str[i] == '='
            continue
        else
            return encoded_str[1:i]
        end
    end
end

function base64url_decode(s::AbstractString)
    @assert isascii(s)

    # adds padding back
    r = rem(lastindex(s), 4)
    if r != 0
        for i in 1:(4 - r)
            s *= "="
        end
    end

    return Base64URL.base64urldecode(s)
end

find_dots(str::AbstractString) = findall(x -> x == '.', str)

function jws_split(str::AbstractString)
    dot_indexes = find_dots(str)

    if isempty(dot_indexes)
        throw(MalformedJWTError("JWT must contain at least one '.' character."))
    elseif length(dot_indexes) > 2
        throw(NotSupportedJWTError("JWE format is not supported. Only JWS is supported for now."))
    end

    header = SubString(str, 1, dot_indexes[1] - 1)

    if length(dot_indexes) == 1
        claims = SubString(str, dot_indexes[1] + 1, lastindex(str))
        signature = ""
    else
        claims = SubString(str, dot_indexes[1] + 1, dot_indexes[2] - 1)
        signature = SubString(str, dot_indexes[2] + 1, lastindex(str))
    end

    return header, claims, signature
end

function jws_header_dict(header_encoded::AbstractString)
    try
        header_dict = JSON.parse(String(base64url_decode(header_encoded)))
        @assert haskey(header_dict, "alg") "\"alg\" attribute is missing."
        @assert haskey(header_dict, "typ") "\"typ\" attribute is missing."
        @assert header_dict["typ"] == "JWT" "Expected \"typ\" == \"JWT\". Found $(header_dict["typ"])."
        return header_dict
    catch e
        throw(MalformedJWTError("Couldn't parse header ($e)."))
    end
end

function jws_claims_dict(claims_encoded::AbstractString)
    try
        claims_dict = JSON.parse(String(base64url_decode(claims_encoded)))
        return claims_dict
    catch err
        throw(MalformedJWTError("Couldn't parse claims ($err)."))
    end
end

function decode_as_json(encoding::Encoding, str::AbstractString)
    header_encoded, claims_encoded, signature_encoded = jws_split(str)
    header_dict = jws_header_dict(header_encoded)

    if isempty(signature_encoded)
        throw(MalformedJWTError("Expected alg $(alg(encoding)), but found empty signature field."))
    end

    if header_dict["alg"] != alg(encoding)
        throw(MalformedJWTError("Expected alg $(alg(encoding)). Found $(header_dict["alg"])."))
    end

    verify(encoding, str)

    try
        return String(base64url_decode(claims_encoded))
    catch err
        throw(MalformedJWTError("Couldn't parse claims: ($err)."))
    end
end

function decode(encoding::Encoding, str::AbstractString)
    json_str = decode_as_json(encoding, str)

    try
        claims_dict = JSON.parse(json_str)
        return claims_dict
    catch err
        throw(MalformedJWTError("Couldn't parse claims ($err)."))
    end
end

function has_valid_signature(encoding::Encoding, str::AbstractString) :: Bool
    last_dot_index = findlast( x -> x == '.', str)
    if last_dot_index == 0
        throw(MalformedJWTError("JWT must contain at least one '.' character."))
    end
    header_and_claims_encoded = SubString(str, 1, last_dot_index - 1)

    if lastindex(str) <= last_dot_index + 1
       throw(MalformedJWTError("JWT has no signature."))
    end

    signature_encoded = SubString(str, last_dot_index + 1, lastindex(str))
    return has_valid_signature(encoding, header_and_claims_encoded, signature_encoded)
end

function verify(encoding::Encoding, str::AbstractString)
    if !has_valid_signature(encoding, str)
        throw(InvalidSignatureError())
    end
    nothing
end

function encode(encoding::Encoding, claims_dict::Dict{S, A}) where {S<:AbstractString, A}
    return encode(encoding, JSON.json(claims_dict))
end

function encode(encoding::Encoding, claims_json::AbstractString)
    header_encoded = base64url_encode("""{"alg":"$(alg(encoding))","typ":"JWT"}""")
    claims_encoded = base64url_encode(claims_json)
    header_and_claims_encoded = header_encoded * "." * claims_encoded
    signature = sign(encoding, header_and_claims_encoded)
    return header_and_claims_encoded * "." * signature
end


text:
module TestClock

using Mimi
using Test

import Mimi:
    AbstractTimestep, FixedTimestep, VariableTimestep, Clock, timestep, time_index,
    advance

t_f = FixedTimestep{1850, 10, 3000}(1)
c_f = Clock{FixedTimestep}(1850, 10, 3000)
@test timestep(c_f) == t_f
@test time_index(c_f) == 1
advance(c_f)
@test time_index(c_f) == 2

years = Tuple([2000:1:2024; 2025:5:2105])
t_v = VariableTimestep{years}()
c_v = Clock{VariableTimestep}(years)
@test timestep(c_v) == t_v

end #module


text:
using Test
import GeoInterface
import ArchGDAL; const AG = ArchGDAL

@testset "Reproject a Geometry" begin
    @testset "Method 1" begin
        AG.importEPSG(2927) do source; AG.importEPSG(4326) do target
            AG.createcoordtrans(source, target) do transform
                AG.fromWKT("POINT (1120351.57 741921.42)") do point
                    @test AG.toWKT(point) == "POINT (1120351.57 741921.42)"
                    AG.transform!(point, transform)
                    @test GeoInterface.coordinates(point) ≈ [47.348801380288485, -122.5981351308777]
        end end end end
    end

    @testset "Method 2" begin
        AG.importEPSG(2927) do source; AG.importEPSG(4326) do target
            AG.createcoordtrans(source, target) do transform
                xs = [47.348801, 47.348801]
                ys = [-122.598135,-122.598135]
                zs = [0.0, 0.0]
                @test AG.transform!(xs, ys, zs, transform) == true
                @test xs ≈ [45.151458, 45.151458]
                @test ys ≈ [-126.863475, -126.863475]
                @test zs ≈ [0.0, 0.0]
        end end end
    end
end

@testset "Get Projection" begin
    AG.read("ospy/data1/sites.shp") do dataset
        layer = AG.getlayer(dataset, 0)
        spatialref = AG.getspatialref(layer)
        @test AG.toWKT(spatialref)[1:6] == "PROJCS"
        @test AG.toWKT(spatialref, false)[1:6] == "PROJCS"
        @test AG.toPROJ4(spatialref) == "+proj=utm +zone=12 +datum=WGS84 +units=m +no_defs"
        @test AG.toXML(spatialref)[1:17] == "<gml:ProjectedCRS"
        @test AG.toMICoordSys(spatialref) == "Earth Projection 8, 104, \"m\", -111, 0, 0.9996, 500000, 0"
        AG.nextfeature(layer) do feature
            @test AG.toPROJ4(AG.getspatialref(AG.getgeom(feature))) == "+proj=utm +zone=12 +datum=WGS84 +units=m +no_defs"
        end
    end
    AG.importEPSG(26912) do spatialref
        @test AG.toPROJ4(spatialref) == "+proj=utm +zone=12 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs"
        @test AG.toWKT(spatialref)[1:6] == "PROJCS"
        AG.morphtoESRI!(spatialref)
        @test AG.toPROJ4(spatialref) == "+proj=utm +zone=12 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs"
        AG.morphfromESRI!(spatialref)
        @test AG.toPROJ4(spatialref) == "+proj=utm +zone=12 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs"
        AG.importEPSGA!(spatialref, 4326)
        @test AG.toPROJ4(spatialref) == "+proj=longlat +datum=WGS84 +no_defs"
    end

    AG.importEPSGA(4326) do spatialref
        cloneref = AG.clone(spatialref)
        AG.clone(spatialref) do cloneref2
            @test AG.toWKT(cloneref) == AG.toWKT(cloneref2)
        end
        @test AG.toWKT(cloneref) == AG.toWKT(AG.importEPSGA(4326))
        @test AG.toPROJ4(spatialref) == "+proj=longlat +datum=WGS84 +no_defs"
    end
end


text:
module Withopen

export withopen

"""
withopen(`zcat a.gz`, `viatmp -gz c.gz` ) do rio,wio
               rio|>eachline|> ll->foreach(ll) do l
                  chomp(l)|>_->"=\$_=\n"|> _->print(wio, _)
               end

end
"""
function withopen(func::Function, readcmd::Cmd, writecmd::Cmd)
    open(readcmd) do rio
        open(writecmd,"w") do wio
             func(rio,wio)
        end
    end
end

end # module

max_stars_repo_name: closescreen/Withopen

max_issues_repo_name: closescreen/Withopen

max_forks_repo_name: closescreen/Withopen


text:
"""
    project_reach(plot_vars, n, δ, Rsets, [algorithm]; [ε], [projection_matrix], [transformation_matrix])

Projection of a reachability analysis result in 2D.

### Input

- `plot_vars`         -- variables to plot; two-dimensional index vector
- `n`                 -- system dimension
- `δ`                 -- time discretization
- `Rsets`             -- reachable states representation
- `algorithm`         -- (optional, default: `"explicit"`) reachability
                         algorithm backend, see `available_algorithms`
- `ε`                 -- (optional, default: `Inf`) error bound for the
                         approximation
- `set_type`          -- (optional, default: `Hyperrectangle`) set type for the
                         approximation
- `projection_matrix` -- (optional, default: `nothing`) projection matrix; if
                         not passed, the function computes `projection_matrix`
                         from `plot_vars`
- `transformation_matrix` -- (optional, default: `nothing`) transformation
                             matrix
- `output_function`   -- (optional, default: `false`) switch denoting whether
                         the passed set is one-dimensional, representing an
                         output function

### Notes

The `plot_vars` argument is required even if the optional argument
`projection_matrix` is passed, because we also determine whether time is used as
a dimension from this variable.
"""
function project_reach(plot_vars::Vector{Int64}, n::Int64,
    δ::Float64, Rsets::Vector{<:LazySets.CartesianProductArray{numeric_type}},
    algorithm::String="explicit";
    ε::Float64=Inf, set_type::Type{<:LazySet}=Hyperrectangle,
    projection_matrix::Union{AbstractMatrix, Void}=nothing,
    transformation_matrix::Union{AbstractMatrix, Void}=nothing,
    output_function::Bool=false
    )::Vector{<:LazySet} where {numeric_type<:Real}

    # parse input
    assert(length(plot_vars) == 2)
    # first projection dimension
    xaxis = plot_vars[1]
    if xaxis == 0
        got_time = true
        xaxis = n+1 # we add a new dimension for time
    else
        got_time = false
        if (xaxis <= 0 || xaxis > n)
            throw(DomainError())
        end
    end

    # build projection matrix
    m = got_time ? n+1 : n
    if projection_matrix == nothing
        # projection to a state variable
        yaxis = plot_vars[2]
        if (yaxis <= 0 || yaxis > n)
            throw(DomainError())
        end
        projection_matrix = sparse([1, 2], [xaxis, yaxis], [1.0, 1.0], 2, m)
    else
        @assert(size(projection_matrix) == (1,n))
        # make vector a 2-row matrix
        projection_matrix = sparse(fill(2, n), 1:n, projection_matrix[1, :], 2, m)
        projection_matrix[1, xaxis] = 1.0
    end

    # apply optional transformation to projection matrix
    if (transformation_matrix != nothing)
        if got_time
            # add another dimension for time: block matrix [S 0; 0 1]
            transformation_matrix = sparse(cat([1, 2], transformation_matrix, [1]))
        end
        projection_matrix = projection_matrix * transformation_matrix
    end

    N = length(Rsets)

    # allocate output and define overapproximation function
    if ε < Inf
        oa = x -> overapproximate(x, HPolygon, ε)
        RsetsProj = Vector{HPolygon{numeric_type}}(N)
    else
        oa = x -> overapproximate(x, set_type)
        RsetsProj = Vector{set_type{numeric_type}}(N)
    end

    if got_time
        radius = δ/2.0
        t = radius
        @inbounds for i in 1:N
            RsetsProj[i] = oa(projection_matrix *
                CartesianProduct(Rsets[i], BallInf([t], radius)))
            t = t + δ
        end
    else
        @inbounds for i in 1:N
            RsetsProj[i] = oa(projection_matrix * Rsets[i])
        end
    end

    return RsetsProj
end

"""
    project_reach(plot_vars, n, δ, Rsets, [algorithm]; [ε], [projection_matrix], [transformation_matrix])

This algorithm projects a sequence of sets into the time variable, or can be
used to take a linear combination of the given variables.

The input `Rsets` is an array of sets (instead of a `CartesianProductArray`).
This array contains the collection of reach sets in 2D.

WARNING:

It is assumed that the variable given in plot_vars belongs to the block computed
in the sequence of 2D sets `Rsets`.
"""
function project_reach(plot_vars::Vector{Int64}, n::Int64, δ::Float64,
    Rsets::Vector{<:LazySets.LazySet{numeric_type}}, algorithm::String;
    ε::Float64=Inf, set_type::Type{<:LazySet}=Hyperrectangle,
    projection_matrix::Union{AbstractMatrix, Void}=nothing,
    transformation_matrix::Union{AbstractMatrix, Void}=nothing,
    output_function::Bool=false
    )::Vector{<:LazySet} where {numeric_type<:Real}

    # parse input
    assert(length(plot_vars) == 2)
    # first projection dimension
    xaxis = plot_vars[1]
    if xaxis == 0
        got_time = true
        xaxis = 3  # time is associated to dimension 3
    else
        got_time = false
        if (xaxis <= 0 || xaxis > n)
            throw(DomainError())
        end
        # map back to 2d block
        xaxis = iseven(xaxis) ? 2 : 1
    end

    # build projection matrix
    if projection_matrix == nothing
        # projection to a state variable
        yaxis = plot_vars[2]
        if (yaxis <= 0 || yaxis > n)
            throw(DomainError())
        end
        # map back to 2d block
        yaxis = iseven(yaxis) ? 2 : 1
        m = got_time ? 3 : 2
        projection_matrix = sparse([1, 2], [xaxis, yaxis], [1.0, 1.0], 2, m)
    elseif !output_function
        error("projection matrix not allowed for this algorithm")
    end

    N = length(Rsets)

    # allocate output and define overapproximation function
    if ε < Inf
        oa = x -> overapproximate(x, HPolygon, ε)
        RsetsProj = Vector{HPolygon{numeric_type}}(N)
    else
        oa = x -> overapproximate(x, set_type)
        RsetsProj = Vector{set_type{numeric_type}}(N)
    end

    if output_function
        radius = δ/2.0
        t = radius
        @inbounds for i in 1:N
            RsetsProj[i] = oa(CartesianProduct(BallInf([t], radius), Rsets[i]))
            t = t + δ
        end
    elseif got_time # x variable is 'time'
        radius = δ/2.0
        t = radius
        @inbounds for i in 1:N
            RsetsProj[i] = oa(projection_matrix *
                CartesianProduct(Rsets[i], BallInf([t], radius)))
            t = t + δ
        end
    else
        @inbounds for i in 1:N
            RsetsProj[i] = oa(projection_matrix * Rsets[i])
        end
    end

    return RsetsProj
end


text:
using ToyFHE
using OffsetArrays
using Test
using Primes
using GaloisFields
using LinearAlgebra

N = 2^5
q₀ = nextprime(Int128(2)^40 + 1, 1; interval=2N)
q₁ = nextprime(q₀ + 2N, 1; interval=2N)
ps = nextprime(q₁ + 2N, 1; interval=2N)

ℛ = let CT = ToyFHE.CRTEncoded{3, Tuple{GaloisField.((q₀,q₁,ps))...}}
    ζ₂n = GaloisFields.minimal_primitive_root(CT, 2N)
    ToyFHE.NegacyclicRing{CT, N}(ζ₂n)
end

scale = 2^40
Tscale = FixedRational{scale}

plain = CKKSEncoding{Tscale}(zero(ℛ))
plain .= OffsetArray(1:div(N,2), 0:div(N,2)-1)

plain_matrix = ones(Float32, 4, 4)

ckks_params = CKKSParams(ℛ, 1, 3.2)
kp = keygen(ckks_params)

c = encrypt(kp, plain)

gk = keygen(GaloisKey, kp.priv; steps=4)
ek = keygen(EvalMultKey, kp.priv)

function encrypted_matmul(gk, weights, x::ToyFHE.CipherText)
    result = repeat(diag(weights), size(weights, 2)).*x
    rotated = x
    for k = 2:size(weights, 2)
        rotated = ToyFHE.rotate(gk, rotated)
        result += repeat(diag(circshift(weights, (0,(k-1)))), size(weights, 2)) .* rotated
    end
    result
end

@test reshape(collect(decrypt(kp, encrypted_matmul(gk, plain_matrix, c))), (4,4)) ≈ (plain_matrix*reshape(collect(plain), 4,4)')' atol=10^-5


text:
function find(r)
    c = 1
    cc = 1
    while !isborder(r,Ost)
        move!(r,Ost)
        c += 1
    end
    move!(r,Nord)
    i=0
    while true
        while !isborder(r,West)
            move!(r,West)
            cc += 1
        end
        if cc == c
            cc = 1
            move!(r,Nord)
        else
            i=1
        break
    end
    while !isborder(r,Ost)
        move!(r,Ost)
        cc += 1
    end
    if cc == c
        cc = 1
        move!(r,Nord)
    else
        i = 3
    break
    end
end
return i
end

function cornerwithwall!(r)
    x=0
    y=0
    while !isborder(r,Sud)
        move!(r,Sud)
        y+= 1
    end
    while !isborder(r,West)
        move!(r,West)
        x += 1
    end
    while !isborder(r,Sud)
        move!(r,Sud)
        y+= 1
    end
    while !isborder(r,West)
        move!(r,West)
        x += 1
    end
    return x, y
end

function secondcorner(r)
    while !isborder(r,Sud)
        move!(r,Sud)
    end
    while !isborder(r,West)
        move!(r,West)
    end
end

function back(r,x,y)
    for i in 1:x
        move!(r,Ost)
    end
    for i in 1:y
        move!(r,Nord)
    end
end

function ob(r,i)
    putmarker!(r)
    while isborder(r,HorizonSide(i))
        move!(r,HorizonSide(0))
        putmarker!(r)
    end
    move!(r,HorizonSide(i))
    putmarker!(r)
    while isborder(r,HorizonSide(2))
        move!(r,HorizonSide(i))
        putmarker!(r)
    end
    move!(r,HorizonSide(2))
    putmarker!(r)
    i += 2
    while isborder(r,HorizonSide(i % 4))
        move!(r,HorizonSide(2))
        putmarker!(r)
    end
    move!(r,HorizonSide(i % 4))
    putmarker!(r)
    while isborder(r,HorizonSide(0))
        move!(r,HorizonSide(i % 4))
        putmarker!(r)
    end
end
function task6(r)
    x,y = cornerwithwall!(r)
    i=find(r)
    ob(r,i)
    secondcorner(r)
    back(r,x,y)
end
task6(r)


text:
@testset "Join" begin
    @test_throws ErrorException("Invalid joinType") Join(Table("wikipedia"), Lookup("lookup"), "prefix", "condition", "outer")
end


text:
module PGQuery

import Libdl
import JSON: parse
using AbstractTrees

# Load in `deps.jl`, complaining if it does not exist
const depsjl_path = joinpath(@__DIR__, "..", "deps", "deps.jl")
if !isfile(depsjl_path)
    error("PGQuery was not build properly. Please run Pkg.build(\"PGQuery\").")
end

# Module initialization function
function __init__()
    include(depsjl_path)
end

using CEnum

include(joinpath(@__DIR__, "gen", "ctypes.jl"))
export Ctm, Ctime_t, Cclock_t

include(joinpath(@__DIR__, "gencode_type_ext.jl"))

include(joinpath(@__DIR__, "gen", "libpg_common.jl"))
include(joinpath(@__DIR__, "gen", "libpg_api.jl"))

include(joinpath(@__DIR__, "gencode_ext.jl"))
include(joinpath(@__DIR__, "abstract_trees.jl"))
include(joinpath(@__DIR__, "exceptions.jl"))

function parse_query(query_str)
    parse_query(parsed_qry -> nothing, query_str)
end

function parse_query(consumer::Function, query_str)
    ctx = pg_query_enter_memory_context("pg_query_parse")
    try
        res::PgQueryInternalParsetreeAndError = pg_query_raw_parse(query_str)

        if(res.error != C_NULL)
            throw(SQLParserException(res.error))
        elseif res.tree  == C_NULL
            throw(SQLParserNoParseTreeException())
        end

        return consumer(unsafe_load(res.tree))
    finally
        pg_query_exit_memory_context(ctx)
    end
end

function parse_query_json(query_str)
    parse_query_json(parsed_qry -> nothing, query_str)
end

function parse_query_json(consumer::Function, query_str)
    res::PgQueryParseResult = pg_query_parse(query_str)

    if res.error != C_NULL
        throw(SQLParserException(res.error))
    else
        consumer(convert_cstring_to_str(res.parse_tree))
    end
end

# export everything with "pg_query_" prefix
foreach(names(@__MODULE__, all=true)) do s
   if startswith(string(s), "pg_query_")
       @eval export $s
   end
end

export SQLParserNoParseTreeException, SQLParserException, parse_query, parse_query_json

end # module


text:
@symbol_func function p_bar(cur_reactor::AbstractReactor)
  cur_p = K_nT(cur_reactor)

  cur_p *= cur_reactor.n_bar

  cur_p *= cur_reactor.T_bar

  cur_p
end


text:
push!(LOAD_PATH,"../src/")

using Documenter

using HawkesSimulator ; global const H = HawkesSimulator

DocMeta.setdocmeta!(HawkesSimulator, :DocTestSetup, :(using HawkesSimulator); recursive=true)

makedocs(;
    modules=[HawkesSimulator],
    authors="Dylan Festa <dylan.festa@gmail.com>",
    repo="https://github.com/dylanfesta/HawkesSimulator.jl/blob/{commit}{path}#{line}",
    sitename="HawkesSimulator.jl",
    format=Documenter.HTML(;
        prettyurls=get(ENV, "CI", "false") == "true",
        canonical="https://dylanfesta.github.io/HawkesSimulator.jl",
        assets=String[],
    ),
    pages=[
        "Home" => "index.md",
    ],
)

deploydocs(;
    repo="github.com/dylanfesta/HawkesSimulator.jl",
    devbranch="main",
)


text:
using Printf
using LinearAlgebra
using Random

include("../common/PWGrid_v02.jl")

include("../common/ortho_gram_schmidt.jl")
include("../common/wrappers_fft.jl")
include("../common/gen_lattice_pwscf.jl")

include("gen_dr.jl")
include("init_pot_harm_3d.jl")
include("op_K.jl")
include("op_Vpot.jl")
include("op_H.jl")
include("calc_rho.jl")
include("calc_grad.jl")
include("calc_Etot.jl")
include("schsolve_Emin_sd.jl")
include("schsolve_Emin_cg.jl")
include("Kprec.jl")
include("diag_lobpcg.jl")
include("diag_davidson.jl")

function test_main( Ns; solution_method="diag_lobpcg" )

    LatVecs = gen_lattice_sc(6.0)
    pw = PWGrid( Ns, LatVecs )

    Ω  = pw.Ω
    r  = pw.r
    G  = pw.gvec.G
    G2 = pw.gvec.G2
    Npoints = prod(Ns)
    Ngwx = pw.gvecw.Ngwx

    @printf("Ns   = (%d,%d,%d)\n", Ns[1], Ns[2], Ns[3])
    @printf("Ngwx = %d\n", Ngwx)

    actual = Npoints/Ngwx
    theor = 1/(4*pi*0.25^3/3)
    @printf("Compression: actual, theor: %f , %f\n", actual, theor)

    # Generate array of distances
    center = sum(LatVecs,dims=2)/2
    dr = gen_dr( r, center )

    # Setup potential
    Vpot = init_pot_harm_3d( pw, dr )
    println("sum(Vpot)*Ω/Npoints = ", sum(Vpot)*Ω/Npoints)

    Nstates = 4
    srand(2222)
    psi  = rand(ComplexF64,Ngwx,Nstates)
    psi = ortho_gram_schmidt(psi)

    if solution_method == "Emin"
        #psi, Etot = schsolve_Emin_sd( pw, Vpot, psi, NiterMax=10 )
        psi, Etot = schsolve_Emin_cg( pw, Vpot, psi, NiterMax=1000 )

        Y = ortho_gram_schmidt(psi)
        mu = Y' * op_H( pw, Vpot, Y )
        evals, evecs = eigen(mu)
        Psi = Y*evecs

    elseif solution_method == "lobpcg"
        evals, psi = diag_lobpcg( pw, Vpot, psi, verbose=true, tol_avg=1e-10 )

    elseif solution_method == "davidson"
        evals, psi = diag_davidson( pw, Vpot, psi, verbose=true, tol_avg=1e-10, NiterMax=20 )
        evals, psi = diag_davidson( pw, Vpot, psi, verbose=true, tol_avg=1e-10, NiterMax=100 )

    else
        println("Unknown solution_method = ", solution_method)
        exit()

    end

    for ist = 1:Nstates
        @printf("State # %d, Energy = %18.10f\n", ist, real(evals[ist]))
    end

end

@time test_main( [30, 30, 30], solution_method="Emin" )
#@time test_main( [30, 30, 30], solution_method="lobpcg" )
#@time test_main( [30, 30, 30], solution_method="davidson" )


text:
using Metalhead, Test
using Flux

# PRETRAINED_MODELS = [(VGG19, false), ResNet50, GoogLeNet, DenseNet121, SqueezeNet]
PRETRAINED_MODELS = []

@testset "AlexNet" begin
  model = AlexNet()
  @test size(model(rand(Float32, 256, 256, 3, 2))) == (1000, 2)
  @test_throws ArgumentError AlexNet(pretrain = true)
  @test_skip gradtest(model, rand(Float32, 256, 256, 3, 2))
end

@testset "VGG" begin
  @testset "$model(BN=$bn)" for model in [VGG11, VGG13, VGG16, VGG19], bn in [true, false]
    imsize = (224, 224)
    m = model(batchnorm = bn)

    @test size(m(rand(Float32, imsize..., 3, 2))) == (1000, 2)
    if (model, bn) in PRETRAINED_MODELS
      @test (model(batchnorm = bn, pretrain = true); true)
    else
      @test_throws ArgumentError model(batchnorm = bn, pretrain = true)
    end
    @test_skip gradtest(m, rand(Float32, imsize..., 3, 2))
  end
end

@testset "ResNet" begin
  @testset for model in [ResNet18, ResNet34, ResNet50, ResNet101, ResNet152]
    m = model()

    @test size(m(rand(Float32, 256, 256, 3, 2))) == (1000, 2)
    if model in PRETRAINED_MODELS
      @test (model(pretrain = true); true)
    else
      @test_throws ArgumentError model(pretrain = true)
    end
    @test_skip gradtest(m, rand(Float32, 256, 256, 3, 2))
  end

  @testset "Shortcut C" begin
    m = Metalhead.resnet(Metalhead.basicblock, :C;
                         channel_config = [1, 1],
                         block_config = [2, 2, 2, 2])

    @test size(m(rand(Float32, 256, 256, 3, 2))) == (1000, 2)
  end
end

@testset "ResNeXt" begin
  @testset for depth in [50, 101, 152]
    m = ResNeXt(depth)

    @test size(m(rand(Float32, 224, 224, 3, 2))) == (1000, 2)
    if ResNeXt in PRETRAINED_MODELS
      @test (ResNeXt(depth, pretrain = true); true)
    else
      @test_throws ArgumentError ResNeXt(depth, pretrain = true)
    end
    @test_skip gradtest(m, rand(Float32, 224, 224, 3, 2))
  end
end

@testset "GoogLeNet" begin
  m = GoogLeNet()
  @test size(m(rand(Float32, 224, 224, 3, 2))) == (1000, 2)
  @test_throws ArgumentError (GoogLeNet(pretrain = true); true)
  @test_skip gradtest(m, rand(Float32, 224, 224, 3, 2))
end

@testset "Inception3" begin
  m = Inception3()
  @test size(m(rand(Float32, 299, 299, 3, 2))) == (1000, 2)
  @test_throws ArgumentError Inception3(pretrain = true)
  @test_skip gradtest(m, rand(Float32, 299, 299, 3, 2))
end

@testset "SqueezeNet" begin
  m = SqueezeNet()
  @test size(m(rand(Float32, 227, 227, 3, 2))) == (1000, 2)
  @test_throws ArgumentError (SqueezeNet(pretrain = true); true)
  @test_skip gradtest(m, rand(Float32, 227, 227, 3, 2))
end

GC.gc()

@testset "DenseNet" begin
  @testset for model in [DenseNet121, DenseNet161, DenseNet169, DenseNet201]
    m = model()

    @test size(m(rand(Float32, 224, 224, 3, 2))) == (1000, 2)
    if model in PRETRAINED_MODELS
      @test (model(pretrain = true); true)
    else
      @test_throws ArgumentError model(pretrain = true)
    end
    @test_skip gradtest(m, rand(Float32, 224, 224, 3, 2))
  end
end

@testset "MobileNet" verbose = true begin
  @testset "MobileNetv2" begin

    m = MobileNetv2()

    @test size(m(rand(Float32, 224, 224, 3, 2))) == (1000, 2)
    if MobileNetv2 in PRETRAINED_MODELS
      @test (MobileNetv2(pretrain = true); true)
    else
      @test_throws ArgumentError MobileNetv2(pretrain = true)
    end
    @test_skip gradtest(m, rand(Float32, 224, 224, 3, 2))
  end

  @testset "MobileNetv3" verbose = true begin
    @testset for mode in [:small, :large]
      m = MobileNetv3(mode)

      @test size(m(rand(Float32, 224, 224, 3, 2))) == (1000, 2)
      if MobileNetv3 in PRETRAINED_MODELS
        @test (MobileNetv3(mode; pretrain = true); true)
      else
        @test_throws ArgumentError MobileNetv3(mode; pretrain = true)
      end
      @test_skip gradtest(m, rand(Float32, 224, 224, 3, 2))
    end
  end
end

GC.gc()

@testset "ConvNeXt" verbose = true begin
  @testset for mode in [:tiny, :small, :base, :large, :xlarge]
    @testset for drop_path_rate in [0.0, 0.5, 0.99]
      m = ConvNeXt(mode; drop_path_rate)

      @test size(m(rand(Float32, 224, 224, 3, 2))) == (1000, 2)
      @test_skip gradtest(m, rand(Float32, 224, 224, 3, 2))
    end
  end
end

@testset "UNetDynamic" verbose = true begin
  @test_nowarn begin
      model = UNetDynamic(Models.xresnet18(), (128, 128, 3, 1), 4)
      @test Flux.outputsize(model, (128, 128, 3, 1)) == (128, 128, 4, 1)

      model = UNetDynamic(Models.xresnet18(), (128, 128, 3, 1), 4, fdownscale=1)
      @test Flux.outputsize(model, (128, 128, 3, 1)) == (64, 64, 4, 1)
  end
end


text:
"""
    ClimaCoupler

Coupling module sufficient for initial atmos-ocean-land coupled simulation.
"""
module ClimaCoupler

include("CoupledSimulations/clock.jl")
include("CoupledSimulations/coupled_simulation.jl")
include("CouplerState/coupler_state.jl")

end

max_stars_repo_name: CliMA/CouplerMachine

max_issues_repo_name: CliMA/CouplerMachine


text:
module ObjectTileNames

names = Dict{Int, String}(
    -1 => "Air (-1)",
    0 => "Grass A (0)",
    1 => "Grass B (1)",
    2 => "Grass C (2)",
    3 => "Grass D (3)",
    8 => "Fence Top A (8)",
    9 => "Fence Top B (9)",
    10 => "Fence Top C (10)",
    11 => "Fence Top D (11)",
    12 => "Fence Top E (12)",
    13 => "Fence Top F (13)",
    14 => "Dark BG Wood Top (14)",
    15 => "Dark BG Right A (15)",
    16 => "Dark BG Left A (16)",
    17 => "Tower Right A (17)",
    18 => "Snow Left A (18)",
    19 => "Tower Bottom Innermost Left (19)",
    20 => "Tower Bottom Innermost Right (20)",
    22 => "Snow Inner (22)",
    23 => "Snow Bottom Inner A (23)",
    24 => "Snow Bottom Inner B (24)",
    25 => "Temple B Right A (25)",
    26 => "Cliffside Bottom A (26)",
    27 => "Cliffside Bottom B (27)",
    28 => "Temple Bottom Alt A (28)",
    29 => "Temple Bottom Alt B (29)",
    34 => "Snow Pile Left Blue (34)",
    35 => "Snow Pile Right Blue (35)",
    36 => "Snow Pile Left Medium (36)",
    37 => "Snow Pile Right Medium (37)",
    38 => "Snow Pile Small (38)",
    39 => "Snow Pile Medium (39)",
    40 => "Fence A (40)",
    41 => "Fence B (41)",
    42 => "Fence C (42)",
    43 => "Fence D (43)",
    44 => "Fence E (44)",
    45 => "Fence F (45)",
    46 => "Dark BG Wood Base (46)",
    47 => "Dark BG Right B (47)",
    48 => "Dark BG Left B (48)",
    49 => "Tower Right B (49)",
    50 => "Snow Left B (50)",
    51 => "Tower Bottom Inner Left (51)",
    52 => "Tower Bottom Inner Right (52)",
    53 => "Tower Inner (53)",
    54 => "Snow Right Inner A (54)",
    55 => "Snow Corner Bottom Right (55)",
    56 => "Snow Corner Bottom Left (56)",
    57 => "Temple B Right B (57)",
    58 => "Cliffside Left A (58)",
    64 => "Icicles A (64)",
    65 => "Icicles B (65)",
    66 => "Icicles C (66)",
    67 => "Icicles D (67)",
    68 => "Snow Pile Left Big (68)",
    69 => "Snow Pile Right Big (69)",
    70 => "Snow Pile Left Small (70)",
    71 => "Snow Pile Right Small (71)",
    72 => "Fence Mossy Top A (72)",
    73 => "Fence Mossy Top B (73)",
    74 => "Fence Mossy Top C (74)",
    75 => "Fence Mossy Top D (75)",
    76 => "Fence Mossy Top E (76)",
    77 => "Fence Mossy Top F (77)",
    78 => "Dark BG A (78)",
    79 => "Dark BG Wood Hollow Top (79)",
    80 => "Dark BG B (80)",
    81 => "Tower Right C (81)",
    83 => "Tower Bottom Edge Left (83)",
    84 => "Tower Bottom Edge Middle (84)",
    85 => "Tower Bottom Edge Right (85)",
    86 => "Snow Right Inner B (86)",
    87 => "Snow Right A (87)",
    88 => "Snow Left C (88)",
    89 => "Temple B Right C (89)",
    90 => "Cliffside Left B (90)",
    96 => "Flat Grass A (96)",
    97 => "Flat Grass B (97)",
    98 => "Flat Grass C (98)",
    99 => "Flat Grass D (99)",
    100 => "Pipe A (100)",
    101 => "Pipe B (101)",
    102 => "Pipe C (102)",
    103 => "Pipe Bottom (103)",
    104 => "Fence Mossy A (104)",
    105 => "Fence Mossy B (105)",
    106 => "Fence Mossy C (106)",
    107 => "Fence Mossy D (107)",
    108 => "Fence Mossy E (108)",
    109 => "Fence Mossy F (109)",
    110 => "Dark BG C (110)",
    111 => "Dark BG Wood Hollow Base (111)",
    112 => "Dark BG D (112)",
    113 => "Snow Right Deep A (113)",
    114 => "Snow Right Deep B (114)",
    118 => "Snow Right B (118)",
    119 => "Snow Top A (119)",
    120 => "Snow Left D (120)",
    121 => "Cliffside Big A (121)",
    122 => "Cliffside Big Inner A (122)",
    128 => "Hanging Grass A (128)",
    129 => "Hanging Grass B (129)",
    130 => "Hanging Grass C (130)",
    131 => "Hanging Grass D (131)",
    132 => "Pipe D (132)",
    133 => "Pipe Bottom Broken (133)",
    134 => "Pipe Bottom Turn (134)",
    135 => "Pipe Top (135)",
    136 => "Fence Snowy Top A (136)",
    137 => "Fence Snowy Top B (137)",
    138 => "Fence Snowy Top C (138)",
    139 => "Fence Snowy Top D (139)",
    140 => "Fence Snowy Top E (140)",
    141 => "Fence Snowy Top F (141)",
    142 => "Stone Left A (142)",
    150 => "Snow Corner Top Right (150)",
    151 => "Snow Top B (151)",
    152 => "Snow Corner Top Left (152)",
    153 => "Cliffside Big B (153)",
    154 => "Cliffside Big Inner B (154)",
    160 => "Wood Left A (160)",
    161 => "Wood Inner A (161)",
    162 => "Wood Inner B (162)",
    163 => "Wood Right A (163)",
    164 => "Wood Edge Bottom Left (164)",
    165 => "Wood Edge Bottom (165)",
    166 => "Wood Edge Bottom Right (166)",
    168 => "Fence Snowy A (168)",
    169 => "Fence Snowy B (169)",
    170 => "Fence Snowy C (170)",
    171 => "Fence Snowy D (171)",
    172 => "Fence Snowy E (172)",
    173 => "Fence Snowy F (173)",
    174 => "Stone Left B (174)",
    185 => "Cliffside Big C (185)",
    186 => "Cliffside Big Inner C (186)",
    192 => "Wood Left B (192)",
    193 => "Wood Inner C (193)",
    194 => "Wood Inner D (194)",
    195 => "Wood Right B (195)",
    196 => "Wood Edge Top Left (196)",
    197 => "Wood Edge Top (197)",
    198 => "Wood Edge Top Right (198)",
    200 => "Reflection Top Left (200)",
    201 => "Reflection Top Right (201)",
    202 => "Reflection Inner A (202)",
    203 => "Reflection Inner B (203)",
    206 => "Stone Left C (206)",
    217 => "Cliffside Big D (217)",
    218 => "Cliffside Big Inner D (218)",
    224 => "Wood Left C (224)",
    225 => "Wood Inner E (225)",
    226 => "Wood Inner F (226)",
    227 => "Wood Right C (227)",
    228 => "Wood Edge Right (228)",
    232 => "Reflection Bottom Left (232)",
    233 => "Reflection Bottom Right (233)",
    234 => "Reflection Inner C (234)",
    235 => "Reflection Inner D (235)",
    249 => "Cliffside Big E (249)",
    250 => "Cliffside Big Inner E (250)",
    256 => "Wood Left D (256)",
    257 => "Wood Inner G (257)",
    258 => "Wood Inner H (258)",
    259 => "Wood Right D (259)",
    260 => "Pool Edges Corner A (260)",
    261 => "Pool Edges Bottom (261)",
    262 => "Pool Edges Corner B (262)",
    288 => "Temple Left A (288)",
    289 => "Temple Bottom A (289)",
    290 => "Temple Bottom B (290)",
    291 => "Temple Bottom C (291)",
    292 => "Temple Right A (292)",
    320 => "Temple Left B (320)",
    324 => "Temple Right B (324)",
    352 => "Temple Left C (352)"
)

end


text:
# Displaying color swatches
# -------------------------

const max_width = 180
const max_height = 150
const max_swatch_size = 25
const default_max_swatches = 128 * 128

function Base.show(io::IO, mime::MIME"image/svg+xml", c::Color)
    write_declaration(io, mime)
    write(io,
        """
        <svg xmlns="http://www.w3.org/2000/svg" version="1.1"
             width="25mm" height="25mm" viewBox="0 0 1 1">
            <rect width="1" height="1" fill="#$(hex(c))" stroke="none"/>
        </svg>
        """)
    flush(io) # return nothing
end

function Base.show(io::IO, mime::MIME"image/svg+xml", c::TransparentColor)
    show(io, mime, [c], max_swatches=default_max_swatches)
end

function Base.show(io::IO, mime::MIME"image/svg+xml", cs::AbstractVector{T};
                   max_swatches::Integer=0) where T <: Color
    mat = Base.ReshapedArray(cs, (1, length(cs)), ())
    show(io, mime, mat, max_swatches=max_swatches)
end

function Base.show(io::IO, mime::MIME"image/svg+xml",cs::AbstractVector{T};
                   max_swatches::Integer=0) where T <: TransparentColor

    # use random id to avoid id collision when the SVG is embedded inline
    id = "pat_" * string(rand(UInt32), base=62)
    n = length(cs)
    actual_max_swatches = max_swatches > 0 ? max_swatches : default_max_swatches
    # When `max_swatches` is specified, the following warning is suppressed.
    if max_swatches == 0 && n > actual_max_swatches
        trunc = n - actual_max_swatches
        @warn """Last $trunc swatches (of $n-element Array) are truncated."""
        yield()
    end
    w = min(n * max_swatch_size, max_width)

    scale = n * max_swatch_size / w # 1 for square, >1 for portrait
    rscale = round(scale, digits=3)
    pat_scale = rscale == 1 ? "" : """patternTransform="scale($rscale,1)" """

    # the following are with the assumption that scale >= 1 (i.e. not landscape)
    if rscale == 1
        shape = "0v1h-1z" # triangle
    else # rscale > 1
        simplify(x) = replace(string(round(x, digits=2)), r"^0"=>"")
        d1 = simplify((1 - 1 / scale) / 2)
        d2 = simplify((1 + 1 / scale) / 2)
        shape = """$(d1)V1h-1V$(d2)z""" # trapezoid
    end
    write_declaration(io, mime)
    write(io,
        """
        <svg xmlns="http://www.w3.org/2000/svg" version="1.1"
             width="$(w)mm" height="25mm" viewBox="0 0 $n 1" stroke="none"
             preserveAspectRatio="none" shape-rendering="crispEdges">
        <defs>
            <pattern id="$id" width=".2" height=".2"
                     patternUnits="userSpaceOnUse" $pat_scale>
                <path d="M.1,0h.1v.1h-.2v.1h.1z" fill="#999" opacity=".5" />
            </pattern>
        </defs>
        <rect width="$n" height="1" fill="url(#$id)" />
        """)
    for i in 1:min(n, actual_max_swatches)
        hexc = hex(color(cs[i]))
        opacity = string(round(alpha(cs[i]), digits=4))
        op = replace(opacity, r"(^0(?!\.0$))|(\.0$)"=>"")
        write(io,
            """
            <path d="M$i,$shape" fill="#$hexc" />
            <path d="M$(i-1),0h1v1h-1z" fill="#$hexc" fill-opacity="$op" />
            """)
    end
    write(io, "</svg>")
    flush(io) # return nothing
end

function Base.show(io::IO, mime::MIME"image/svg+xml", cs::AbstractMatrix{T};
                   max_swatches::Integer=0) where T <: Color
    m, n = size(cs)
    actual_max_swatches = max_swatches > 0 ? max_swatches : default_max_swatches
    if m * n > actual_max_swatches
        return show_strokes(io, mime, cs, max_swatches=max_swatches)
    end
    w = min(n * max_swatch_size, max_width)
    h = min(m * max_swatch_size, max_height)
    if max_width * m > max_height * n
        w = max(h * n / m, max_swatch_size)
    else
        h = max(w * m / n, max_swatch_size)
    end

    simplify(x) = replace(string(round(x, digits=2)), r"(^0(?=\.))|(.0+$)"=>"")
    sw = simplify(1 - (w / n < 3.6 ? 0 : n / w))
    sh = simplify(1 - (h / m < 3.6 ? 0 : m / h))
    if sw == "1" && sh == "1"
        return show_strokes(io, mime, cs, max_swatches=max_swatches)
    end

    comp(x) = round(x)==round(x, digits=2) ? Int(round(x)) : round(x, digits=2)
    write_declaration(io, mime)
    write(io,
        """
        <svg xmlns="http://www.w3.org/2000/svg" version="1.1"
             width="$(comp(w))mm" height="$(comp(h))mm"
             viewBox="0 0 $n $m" preserveAspectRatio="none"
             shape-rendering="crispEdges" stroke="none">
        """)

    for i in 1:m, j in 1:n
        c = hex(cs[i, j])
        write(io,
            """
            <rect width="$sw" height="$sh" x="$(j-1)" y="$(i-1)" fill="#$c" />
            """)
    end

    write(io, "</svg>")
    flush(io) # return nothing
end

# TODO: add `show` method for `AbstractMatrix{T} where T<:TransparentColor`
# Unlike the case of opaque `Color`, hasty generalization has some problems:
#  - Large matrices (i.e. images) may cause performance (size or speed) issue
#  - User may expect a raster image to be displayed instead of swatches
#  - ImageShow.jl(v0.2.0) suppresses only the SVG matrices of opaque `Color`
#  - Checker pattern is less useful when each swatch is smaller than the checker
#  - Area-average as reduction method is perceptually meaningless for alpha

function show_strokes(io::IO, mime::MIME"image/svg+xml", cs::AbstractMatrix{T};
                      max_swatches::Integer=0) where T <: Color
    m, n = size(cs)
    actual_max_swatches = max_swatches > 0 ? max_swatches : default_max_swatches
    # When `max_swatches` is specified, the following warning is suppressed.
    if max_swatches == 0 && m * n > actual_max_swatches
        @warn """
            Output swatches are reduced due to the large size ($m×$n).
            Load the ImageShow package for large images."""
        yield()
    end
    w = max_width
    h = max_height
    if max_width * m > max_height * n
        w = n / m * h
    else
        h = m / n * w
    end

    # decimation factor `d` is rounded to integer to simplify the SVG document
    d = Int(ceil(sqrt(m * n / actual_max_swatches)))

    comp(x) = round(x)==round(x, digits=2) ? Int(round(x)) : round(x, digits=2)
    write_declaration(io, mime)
    write(io,
        """
        <svg xmlns="http://www.w3.org/2000/svg" version="1.1"
             width="$(comp(w))mm" height="$(comp(h))mm"
             viewBox="0 -$(comp(d/2)) $n $m" stroke-width="$d"
             stroke-linecap="butt" shape-rendering="crispEdges">
        """)

    for i in 1:d:m, j in 1:d:n
        # since there is no universal way,
        # calculate the mean color in "RGB space"
        csum = Float32[0, 0, 0]
        u = min(n-j+1, d) # cell width
        v = min(m-i+1, d) # cell height
        for y in i:i+v-1, x in j:j+u-1
            rgb = convert(RGB{Float32}, cs[y, x])
            csum[1] += red(rgb) # avoid array allocation
            csum[2] += green(rgb)
            csum[3] += blue(rgb)
        end
        csum /= (u * v)
        c = hex(RGB{Float32}(csum[1], csum[2], csum[3]))
        write(io,
            """
            <path d="M$(j-1),$(i-1)h$d" stroke="#$c" />
            """)
    end

    write(io, "</svg>")
    flush(io) # return nothing
end

function write_declaration(io::IO, ::MIME"image/svg+xml")
    write(io,
        """
        <?xml version="1.0" encoding="UTF-8"?>
        <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
         "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
        """)
    flush(io) # return nothing
end


text:
@testset "fetch.jl" begin
    @testset "_unpack_df" begin
        test_df = DataFrame(
            :a => [1, 2],
            :b => [Dict("s" => 5, "t" => 6), Dict("s" => 2, "t" => 7)]
        )

        expected = DataFrame(
            :a => [1, 2],
            :s => [5, 2],
            :t => [6, 7]
        )

        _test_df_inequality(_unpack_df(test_df, :b), expected)
    end

    @testset "_unpack_values" begin
        @testset "dicts" begin
            ex = Dict("s" => 5, "t" => 6)

            @test issetequal(_unpack_values(ex), [5, 6])
        end
        @testset "arrays" begin
            ex1 = Dict("s" => 5, "t" => 6)
            ex2 = Dict("s" => 2, "t" => 7)
            @test _unpack_values([ex1, ex2]) == [6 7; 5 2]
        end
    end

    @testset "_parse_datetime" begin
        dt = "2021-10-01T01:01Z"
        @test _parse_datetime(dt) == DateTime(2021, 10, 1, 1, 1)
    end

    @testset "_parse_data" begin
        @testset "dataframe dispatch" begin
            ex = DataFrame(
                :from => ["2021-10-01T01:01Z", "2021-05-01T01:01Z"],
                :to => ["2021-10-02T01:01Z", "2021-05-02T01:01Z"]
            )

            expected =  DataFrame(
                :from => [DateTime(2021, 10, 1, 1, 1), DateTime(2021, 05, 1, 1, 1)],
                :to => [DateTime(2021, 10, 2, 1, 1), DateTime(2021, 05, 2, 1, 1)]
            )
            @test _parse_data(ex) == expected
        end

        @testset "array dispatch" begin
            ex = DataFrame(
                :from => ["2021-10-01T01:01Z", "2021-05-01T01:01Z"],
                :to => ["2021-10-02T01:01Z", "2021-05-02T01:01Z"]
            )

            expected = DataFrame(
                :from => [
                    DateTime(2021, 10, 1, 1, 1),
                    DateTime(2021, 05, 1, 1, 1),
                    DateTime(2021, 10, 1, 1, 1),
                    DateTime(2021, 05, 1, 1, 1),
                ],
                :to => [
                    DateTime(2021, 10, 2, 1, 1),
                    DateTime(2021, 05, 2, 1, 1),
                    DateTime(2021, 10, 2, 1, 1),
                    DateTime(2021, 05, 2, 1, 1),
                ]
            )

            data = [ex, ex]
            @test _parse_data(data) == expected
        end

        @testset "convert_mix" begin
            ex1 = Dict("fuel" => "hydro", "perc" => 0.5)
            ex2 = Dict("fuel" => "gas", "perc" => 0.1)
            data = [ex1, ex2]

            expected = Dict("hydro"=> 0.5, "gas"=> 0.1)
            @test _convert_mix(data) == expected
        end
    end

    @testset "get carbon intensity" begin
        @testset "short date range" begin
            start_date = ZonedDateTime(2021, 1, 1, tz"UTC")
            end_date = ZonedDateTime(2021, 1, 10, tz"UTC")

            data = get_carbon_intensity(start_date, end_date)

            @test maximum(data.to) <= end_date.utc_datetime
            @test minimum(data.to) >= start_date.utc_datetime

            @test data isa DataFrame
            @test !isempty(data)
            @test issetequal(names(data), ["to", "from", "forecast", "actual", "index"])
        end

        @testset "longer daterange" begin
            start_date = ZonedDateTime(2021, 1, 1, tz"UTC")
            end_date = ZonedDateTime(2021, 2, 1, tz"UTC")

            data = get_carbon_intensity(start_date, end_date)

            @test maximum(data.to) <= end_date.utc_datetime
            @test minimum(data.to) >= start_date.utc_datetime

            @test data isa DataFrame
            @test !isempty(data)
            @test issetequal(names(data), ["to", "from", "forecast", "actual", "index"])
        end
    end

    @testset "get regional data" begin
        @testset "shorter daterange" begin
            start_date = ZonedDateTime(2021, 1, 1, tz"UTC")
            end_date = ZonedDateTime(2021, 1, 10, tz"UTC")

            data = get_regional_data(start_date, end_date)

            @test data isa NamedTuple
            @test issetequal(propertynames(data), [:intensity, :generation])

            intensity = data.intensity
            generation = data.generation

            @test maximum(intensity.to) <= end_date.utc_datetime
            @test minimum(intensity.to) >= start_date.utc_datetime

            @test maximum(generation.to) <= end_date.utc_datetime
            @test minimum(generation.to) >= start_date.utc_datetime

            @test intensity isa DataFrame
            @test !isempty(intensity)
            @test issetequal(
                names(intensity),
                [
                    "to", "from", "forecast", "shortname", "dnoregion",
                    "regionid", "generationmix", "index"
                ]
            )

            @test generation isa DataFrame
            @test !isempty(generation)
            @test issetequal(
                names(generation),
                [
                    "to", "from", "intensity", "shortname", "dnoregion",
                    "regionid", "coal", "hydro", "biomass", "imports",
                    "nuclear", "other", "solar", "gas", "wind"
                ]
            )
        end

        @testset "longer daterange" begin
            start_date = ZonedDateTime(2021, 1, 1, tz"UTC")
            end_date = ZonedDateTime(2021, 2, 1, tz"UTC")

            data = get_regional_data(start_date, end_date)

            @test data isa NamedTuple
            @test issetequal(propertynames(data), [:intensity, :generation])

            intensity = data.intensity
            generation = data.generation

            @test maximum(intensity.to) <= end_date.utc_datetime
            @test minimum(intensity.to) >= start_date.utc_datetime

            @test maximum(generation.to) <= end_date.utc_datetime
            @test minimum(generation.to) >= start_date.utc_datetime

            @test intensity isa DataFrame
            @test !isempty(intensity)
            @test  issetequal(
                names(intensity),
                [
                    "to", "from", "forecast", "shortname", "dnoregion",
                    "regionid", "generationmix", "index"
                ]
            )

            @test generation isa DataFrame
            @test !isempty(generation)
            @test issetequal(
                names(generation),
                [
                    "to", "from", "intensity", "shortname", "dnoregion",
                    "regionid",  "coal", "hydro", "biomass", "imports",
                    "nuclear", "other", "solar", "gas", "wind"
                ]
            )
        end
    end

    @testset "get todays forecast" begin
        @testset "default" begin
            data = get_todays_forecast()
            @test data isa DataFrame
            @test !isempty(data)
            @test issetequal(names(data), ["to", "from", "forecast", "actual", "index"])
        end

        @testset "region kwarg" begin
            data = get_todays_forecast(regional=true)

            @test data isa DataFrame
            @test !isempty(data)
            @test issetequal(
                names(data),
                [
                    "to", "from", "forecast", "shortname", "dnoregion",
                    "regionid", "generationmix", "index"
                ]
            )
        end

        @testset "specific region" begin
            data = get_todays_forecast(regional=true, region = "North Scotland")

            @test data isa DataFrame
            @test all(data.shortname.=="North Scotland")
            @test issetequal(
                names(data),
                [
                    "to", "from", "forecast", "shortname", "dnoregion",
                    "regionid", "generationmix", "index"
                ]
            )
        end

        @testset "throw error on bad region" begin
            @test_throws DomainError get_todays_forecast(regional=true, region = "not a region")
        end
    end
end


text:
# Copyright 2017, Iain Dunning, Joey Huchette, Miles Lubin, and contributors    #src
# This Source Code Form is subject to the terms of the Mozilla Public License   #src
# v.2.0. If a copy of the MPL was not distributed with this file, You can       #src
# obtain one at https://mozilla.org/MPL/2.0/.                                   #src

# # The SteelT3 problem

# The steelT3 model from AMPL: A Modeling Language for Mathematical Programming,
# 2nd ed by Robert Fourer, David Gay, and Brian W. Kernighan.
#
# Originally contributed by Louis Luangkesorn, April 3, 2015.

using JuMP
import GLPK
import Test

function example_steelT3(; verbose = true)
    T = 4
    prod = ["bands", "coils"]
    area = Dict(
        "bands" => ("east", "north"),
        "coils" => ("east", "west", "export")
    )
    avail = [40, 40, 32, 40]
    rate = Dict("bands" => 200, "coils" => 140)
    inv0 = Dict("bands" => 10, "coils" => 0)
    prodcost = Dict("bands" => 10, "coils" => 11)
    invcost = Dict("bands" => 2.5, "coils" => 3)
    revenue = Dict(
        "bands" => Dict(
            "east" => [25.0, 26.0, 27.0, 27.0],
            "north" => [26.5, 27.5, 28.0, 28.5],
        ),
        "coils" => Dict(
            "east" =>[30, 35, 37, 39],
            "west" => [29, 32, 33, 35],
            "export" => [25, 25, 25, 28],
        )
    )
    market = Dict(
        "bands" => Dict(
            "east" => [2000, 2000, 1500, 2000],
            "north" => [4000, 4000, 2500, 4500],
        ),
        "coils" => Dict(
            "east" => [1000, 800, 1000, 1100],
            "west" => [2000, 1200, 2000, 2300],
            "export" => [1000, 500, 500, 800],
        )
    )
    ## Model
    model = Model(GLPK.Optimizer)
    ## Decision Variables
    @variables(model, begin
        make[p in prod, t in 1:T] >= 0
        inventory[p in prod, t in 0:T] >= 0
        0 <= sell[p in prod, a in area[p], t in 1:T] <= market[p][a][t]
    end)
    @constraints(model, begin
        [p = prod, a = area[p], t = 1:T], sell[p, a, t] <= market[p][a][t]
        ## Total of hours used by all products may not exceed hours available,
        ## in each week
        [t in 1:T], sum(1 / rate[p] * make[p, t] for p in prod) <= avail[t]
        ## Initial inventory must equal given value
        [p in prod], inventory[p, 0] == inv0[p]
        ## Tons produced and taken from inventory must equal tons sold and put
        ## into inventory.
        [p in prod, t in 1:T], make[p, t] + inventory[p, t - 1] == sum(sell[p, a, t] for a in area[p]) + inventory[p, t]
    end)
    ## Maximize total profit: total revenue less costs for all products in all
    ## weeks.
    @objective(
        model,
        Max,
        sum(
            revenue[p][a][t] * sell[p, a, t] -
            prodcost[p] * make[p, t] -
            invcost[p] * inventory[p, t]
            for p in prod, a in area[p], t in 1:T
        )
    )
    optimize!(model)
    Test.@test termination_status(model) == MOI.OPTIMAL
    Test.@test primal_status(model) == MOI.FEASIBLE_POINT
    Test.@test objective_value(model) == 172850.0
    if verbose
        println("RESULTS:")
        for p in prod
            println("make $(p)")
            for t in 1:T
                print(value(make[p, t]), "\t")
            end
            println()
            println("Inventory $(p)")
            for t in 1:T
                print(value(inventory[p, t]), "\t")
            end
            println()
            for a in area[p]
                println("sell $(p) $(a)")
            for t in 1:T
                print(value(sell[p, a, t]), "\t")
            end
            println()
            end
        end
    end
    return
end

example_steelT3()

max_stars_repo_name: ethansaxenian/RosettaDecode

max_issues_repo_name: ethansaxenian/RosettaDecode

max_forks_repo_name: ethansaxenian/RosettaDecode


text:
using Covid_Forecast
using Test

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


text:
## Pendulum
# https://github.com/HarvardAgileRoboticsLab/unscented-dynamic-programming/blob/master/pendulum_dynamics.m
function pendulum_dynamics!(xdot,x,u)
    m = 1.
    l = 0.5
    b = 0.1
    lc = 0.5
    I = 0.25
    g = 9.81
    xdot[1] = x[2]
    xdot[2] = (u[1] - m*g*lc*sin(x[1]) - b*x[2])/I
end
n,m = 2,1

#create some empty functions (haven't updated for new model definition)
function blank_error()

end

function blank_expansion()

end

model = Model(pendulum_dynamics!,n,m,blank_error,blank_expansion) # inplace model

# initial conditions
x0 = [0; 0.]

# goal
xf = [pi; 0] # (ie, swing up)

# costs
Q = 1e-3*Matrix(I,n,n)
Qf = 100.0*Matrix(I,n,n)
R = 1e-2*Matrix(I,m,m)

# simulation
tf = 5.

obj_uncon = LQRObjective(Q, R, Qf, tf, x0, xf)

# Constraints
u_bound = 2
u_min = [-u_bound]
u_max = [u_bound]
obj_con = ConstrainedObjective(obj_uncon, u_min=u_min, u_max=u_max) # constrained objective

# Set up problem
pendulum = [model,obj_uncon]
pendulum_constrained = [model, obj_con]


text:
load_example()
@testset "conventional cleaning" begin
@test size(conventional_cleaning(radiance_datacube, clouds_datacube)) == size(radiance_datacube)
end

@testset "PatnaikSTT2021 cleaning" begin
    @test size(PatnaikSTT2021(radiance_datacube, clouds_datacube)) == size(radiance_datacube)
end


text:
@enum TimeCorrectionType begin
    tctUnknown
    tctGPUT  # /< GPS  to UTC using A0, A1
    tctGAUT  # /< GAL  to UTC using A0, A1
    tctSBUT  # /< SBAS to UTC using A0, A1, incl. provider and UTC ID
    tctGLUT  # /< GLO  to UTC using A0 = -TauC , A1 = 0
    tctGPGA  # /< GPS  to GAL using A0 = A0G   , A1 = A1G
    tctGAGP  # /< GAL  to GPS using A0 = A0G   , A1 = A1G
    tctGLGP  # /< GLO  to GPS using A0 = -TauGPS, A1 = 0
    tctQZGP  # /< QZS  to GPS using A0, A1
    tctQZUT  # /< QZS  to UTC using A0, A1
    tctBDUT  # /< BDT  to UTC using A0, A1
    tctBDGP  # /< BDT  to GPS using A0, A1  !! not in RINEX
    tctIRUT  # /< IRN  to UTC using A0, A1
    tctIRGP  # /< IRN  to GPS using A0, A1
end

const str2tct = Dict{String,TimeCorrectionType}(
    "GPUT" => tctGPUT,
    "GAUT" => tctGAUT,
    "SBUT" => tctSBUT,
    "GLUT" => tctGLUT,
    "GPGA" => tctGPGA,
    "GAGP" => tctGAGP,
    "GLGP" => tctGLGP,
    "QZGP" => tctQZGP,
    "QZUT" => tctQZUT,
    "BDUT" => tctBDUT,
    "BDGP" => tctBDGP,
    "IRUT" => tctIRUT,
    "IRGP" => tctIRGP,

)
function str2TimeCorrectionType(str::String,
    str2tct::Dict{String,TimeCorrectionType}=str2tct)
    haskey(str2tct, str) || throw(error("no such TimeSystemType: $str"))
    str2tct[str]
end

const tct2tsts = Dict(
    tctGPUT => (tstGPS, tstUTC),
    tctGAUT => (tstGAL, tstUTC),
    tctSBUT => (tstGPS, tstUTC),
    tctGLUT => (tstGLO, tstUTC),
    tctGPGA => (tstGPS, tstGAL),
    tctGAGP => (tstGAL, tstGPS),
    tctGLGP => (tstGLO, tstGPS),
    tctQZGP => (tstQZS, tstGPS),
    tctQZUT => (tstQZS, tstUTC),
    tctBDUT => (tstBDT, tstUTC),
    tctBDGP => (tstBDT, tstGPS),
    tctIRUT => (tstIRN, tstUTC),
    tctIRGP => (tstIRN, tstGPS),
)
function tct2TimeSystemTypes(tct::TimeCorrectionType,
    tct2tsts::Dict{TimeCorrectionType,Tuple{TimeSystemType,TimeSystemType}}=tct2tsts,
)::Tuple{TimeSystemType,TimeSystemType}
    haskey(tct2tsts, tct) ||
        throw(error("no such TimeCorrectionType: $tct"))
    tct2tsts[tct]
end
@with_kw struct TimeSystemCorrection
    type::TimeCorrectionType
    frTST::TimeSystemType
    toTST::TimeSystemType
    A0::Float64
    A1::Float64
        # /< reference time for polynominal (week,sow) - MUST BE GPS TIME
    refWeek::Int64
    refSOW::Int64
        # /< reference time (yr,mon,day) for RINEX ver 2 GLO
    refYr::Int64
    refMon::Int64
    refDay::Int64
        # /< string 'EGNOS' 'WAAS' or 'MSAS'
    geoProvider::String
        # /< UTC Identifier [0 unknown, 1=UTC(NIST),
        # /<  2=UTC(USNO), 3=UTC(SU), 4=UTC(BIPM),
        # /<  5=UTC(Europe), 6=UTC(CRL)]
    geoUTCid::String

end

function getTimeSystemCorrection(tp::TimeCorrectionType,
    A0::Float64,A1::Float64,
    refWeek::Int64, refSOW::Int64,
    geoProvider::String, geoUTCid::String)
    frTST, toTST = tct2TimeSystemTypes(tp)

    dt = gpsws2datetime(refWeek, refSOW)

    TimeSystemCorrection(tp, frTST, toTST,
                    A0, A1, refWeek, refSOW,
                    year(dt), month(dt), day(dt),
                    geoProvider, geoUTCid,)
    # if in(tp, Set([tctGLGP, tctGLUT, tctBDUT,
    #         tctGPUT, tctGPGA, tctQZGP, tctQZUT, ]))
    # end
    #  if(tc.type == TimeSystemCorrection::GLGP ||
    #     tc.type == TimeSystemCorrection::GLUT ||        // TD ?
    #     tc.type == TimeSystemCorrection::BDUT ||        // TD ?
    #     tc.type == TimeSystemCorrection::GPUT ||
    #     tc.type == TimeSystemCorrection::GPGA ||
    #     tc.type == TimeSystemCorrection::QZGP ||
    #     tc.type == TimeSystemCorrection::QZUT)

    #  {
    #     GPSWeekSecond gws(tc.refWeek,tc.refSOW);
    #     CivilTime ct(gws);
    #     tc.refYr = ct.year;
    #     tc.refMon = ct.month;
    #     tc.refDay = ct.day;
    #  }

    #  if(tc.type == TimeSystemCorrection::GAUT)
    #  {
    #     GALWeekSecond gws(tc.refWeek,tc.refSOW);
    #     CivilTime ct(gws);
    #     tc.refYr = ct.year;
    #     tc.refMon = ct.month;
    #     tc.refDay = ct.day;
    #  }

    #     //if(tc.type == TimeSystemCorrection::GLUT)
    #     // {
    #     //   tc.refYr =  1980;
    #     //   tc.refMon = 1;
    #     //   tc.refDay = 6;
    #     //   tc.refWeek = 0;
    #     //   tc.refSOW = 0;
    #     //}

end


text:
module Xadrez end

xadrez(n, m) = n == 0 || m == 0 ? "" : mapreduce ( z-> mapreduce(y -> string((z + y -2) % 2), * , [1:n]) * "\n", * , [1:m])

export xadrez

max_stars_repo_name: raphaelpanta/julia-lang-exemplos

max_issues_repo_name: raphaelpanta/julia-lang-exemplos

max_forks_repo_name: raphaelpanta/julia-lang-exemplos