text:
if !(VERSION.major==0&&VERSION.minor<=6)
	using Test
else
	using Base.Test
end
using FinancialToolbox

print_colored("Starting Hyper Dual Numbers Test\n",:green)

#Test Parameters
testToll=1e-14;
spot=10;K=10;r=0.02;T=2.0;sigma=0.2;d=0.01;
assert_(value,toll)=@test abs(value)<toll
#EuropeanCall Option
PriceCall=blsprice(spot,K,r,T,sigma,d);
DeltaCall=blsdelta(spot,K,r,T,sigma,d);
ThetaCall=blstheta(spot,K,r,T,sigma,d);
RhoCall=blsrho(spot,K,r,T,sigma,d);
LambdaCall=blslambda(spot,K,r,T,sigma,d);
VannaCall=blsvanna(spot,K,r,T,sigma,d);

#EuropeanPut Option
PricePut=blsprice(spot,K,r,T,sigma,d,false);
DeltaPut=blsdelta(spot,K,r,T,sigma,d,false);
ThetaPut=blstheta(spot,K,r,T,sigma,d,false);
RhoPut=blsrho(spot,K,r,T,sigma,d,false);
LambdaPut=blslambda(spot,K,r,T,sigma,d,false);
VannaPut=blsvanna(spot,K,r,T,sigma,d,false);

#Equals for both Options
Gamma=blsgamma(spot,K,r,T,sigma,d);
Vega=blsvega(spot,K,r,T,sigma,d);

########HYPER DUAL NUMBERS
using HyperDualNumbers;
DerToll=1e-13;
di=1e-15;
#Function definition
SpotHyper=hyper(spot,1.0,1.0,0.0);
rHyper=hyper(r,1.0,1.0,0.0);
THyper=hyper(T,1.0,1.0,0.0);
SigmaHyper=hyper(sigma,1.0,1.0,0.0);
KHyper=hyper(K,1.0,1.0,0.0);

#Function definition
#Call
F(spot)=blsprice(spot,K,r,T,sigma,d);
FF(spot)=blsdelta(spot,K,r,T,sigma,d);
G(r)=blsprice(spot,K,r,T,sigma,d);
H(T)=blsprice(spot,K,r,T,sigma,d);
L(sigma)=blsprice(spot,K,r,T,sigma,d);
P(spot)=blsprice(spot,K,r,T,sigma,d)*spot.value/blsprice(spot.value,K,r,T,sigma,d);
V(sigma)=blsdelta(spot,K,r,T,sigma,d);
VV(spot,sigma)=blsprice(spot,K,r,T,sigma,d);
#Put
F1(spot)=blsprice(spot,K,r,T,sigma,d,false);
FF1(spot)=blsdelta(spot,K,r,T,sigma,d,false);
G1(r)=blsprice(spot,K,r,T,sigma,d,false);
H1(T)=blsprice(spot,K,r,T,sigma,d,false);
P1(spot)=blsprice(spot,K,r,T,sigma,d,false)*spot.value/blsprice(spot.value,K,r,T,sigma,d,false);
V1(sigma)=blsdelta(spot,K,r,T,sigma,d,false);
V11(spot,sigma)=blsprice(spot,K,r,T,sigma,d,false);

#TEST
print_colored("--- European Call Sensitivities: HyperDualNumbers\n",:yellow)
print_colored("-----Testing Delta\n",:blue);
assert_(F(SpotHyper).epsilon1-DeltaCall,DerToll)
print_colored("-----Testing Gamma\n",:blue);
assert_(FF1(SpotHyper).epsilon1-Gamma,DerToll)
print_colored("-----Testing Gamma  2\n",:blue);
assert_(F(SpotHyper).epsilon12-Gamma,DerToll)
print_colored("-----Testing Rho\n",:blue);
assert_(G(rHyper).epsilon1-RhoCall,DerToll)
print_colored("-----Testing Theta\n",:blue);
assert_(-H(THyper).epsilon1-ThetaCall,DerToll)
print_colored("-----Testing Lambda\n",:blue);
assert_(P(SpotHyper).epsilon1-LambdaCall,DerToll)
print_colored("-----Testing Vanna\n",:blue);
assert_(V(SigmaHyper).epsilon1-VannaCall,DerToll)
print_colored("-----Testing Vanna  2\n",:blue);
assert_(VV(hyper(spot,1,0,0),hyper(sigma,0,1,0)).epsilon12-VannaCall,DerToll)

## Complex Test with Complex Step Approximation for European Put
#TEST
print_colored("--- European Put Sensitivities: HyperDualNumbers\n",:yellow)
print_colored("-----Testing Delta\n",:blue);
assert_(F1(SpotHyper).epsilon1-DeltaPut,DerToll)
print_colored("-----Testing Rho\n",:blue);
assert_(G1(rHyper).epsilon1-RhoPut,DerToll)
print_colored("-----Testing Theta\n",:blue);
assert_(-H1(THyper).epsilon1-ThetaPut,DerToll)
print_colored("-----Testing Lambda\n",:blue);
assert_(P1(SpotHyper).epsilon1-LambdaPut,DerToll)
print_colored("-----Testing Vanna\n",:blue);
assert_(V1(SigmaHyper).epsilon1-VannaPut,DerToll)
print_colored("-----Testing Vanna  2\n",:blue);
assert_(V11(hyper(spot,1,0,0),hyper(sigma,0,1,0)).epsilon12-VannaPut,DerToll)
print_colored("-----Testing Vega\n",:blue);
assert_(L(SigmaHyper).epsilon1-Vega,DerToll)
print_colored("Hyper Dual Numbers Test Passed\n\n",:green)

#TEST OF INPUT VALIDATION
print_colored("Starting Input Validation Test Hyper Dual Numbers\n",:magenta)
print_colored("----Testing Negative  Spot Price \n",:cyan)
@test_throws(ErrorException, blsprice(-SpotHyper,K,r,T,sigma,d))
@test_throws(ErrorException, blkprice(-SpotHyper,K,r,T,sigma))
@test_throws(ErrorException, blsdelta(-SpotHyper,K,r,T,sigma,d))
@test_throws(ErrorException, blsgamma(-SpotHyper,K,r,T,sigma,d))
@test_throws(ErrorException, blstheta(-SpotHyper,K,r,T,sigma,d))
@test_throws(ErrorException, blsrho(-SpotHyper,K,r,T,sigma,d))
@test_throws(ErrorException, blspsi(-SpotHyper,K,r,T,sigma,d))
@test_throws(ErrorException, blslambda(-SpotHyper,K,r,T,sigma,d))
@test_throws(ErrorException, blsvanna(-SpotHyper,K,r,T,sigma,d))
@test_throws(ErrorException, blsvega(-SpotHyper,K,r,T,sigma,d))

print_colored("----Testing Negative  Strike Price \n",:cyan)
@test_throws(ErrorException, blsprice(spot,-KHyper,r,T,sigma,d))
@test_throws(ErrorException, blkprice(spot,-KHyper,r,T,sigma))
@test_throws(ErrorException, blsdelta(spot,-KHyper,r,T,sigma,d))
@test_throws(ErrorException, blsgamma(spot,-KHyper,r,T,sigma,d))
@test_throws(ErrorException, blstheta(spot,-KHyper,r,T,sigma,d))
@test_throws(ErrorException, blsrho(spot,-KHyper,r,T,sigma,d))
@test_throws(ErrorException, blspsi(spot,-KHyper,r,T,sigma,d))
@test_throws(ErrorException, blslambda(spot,-KHyper,r,T,sigma,d))
@test_throws(ErrorException, blsvanna(spot,-KHyper,r,T,sigma,d))
@test_throws(ErrorException, blsvega(spot,-KHyper,r,T,sigma,d))

print_colored("----Testing Negative  Time to Maturity \n",:cyan)
@test_throws(ErrorException, blsprice(spot,K,r,-THyper,sigma,d))
@test_throws(ErrorException, blkprice(spot,K,r,-THyper,sigma))
@test_throws(ErrorException, blsdelta(spot,K,r,-THyper,sigma,d))
@test_throws(ErrorException, blsgamma(spot,K,r,-THyper,sigma,d))
@test_throws(ErrorException, blstheta(spot,K,r,-THyper,sigma,d))
@test_throws(ErrorException, blsrho(spot,K,r,-THyper,sigma,d))
@test_throws(ErrorException, blspsi(spot,K,r,-THyper,sigma,d))
@test_throws(ErrorException, blslambda(spot,K,r,-THyper,sigma,d))
@test_throws(ErrorException, blsvanna(spot,K,r,-THyper,sigma,d))
@test_throws(ErrorException, blsvega(spot,K,r,-THyper,sigma,d))

print_colored("----Testing Negative  Volatility \n",:cyan)
@test_throws(ErrorException, blsprice(spot,K,r,T,-SigmaHyper,d))
@test_throws(ErrorException, blkprice(spot,K,r,T,-SigmaHyper))
@test_throws(ErrorException, blsdelta(spot,K,r,T,-SigmaHyper,d))
@test_throws(ErrorException, blsgamma(spot,K,r,T,-SigmaHyper,d))
@test_throws(ErrorException, blstheta(spot,K,r,T,-SigmaHyper,d))
@test_throws(ErrorException, blsrho(spot,K,r,T,-SigmaHyper,d))
@test_throws(ErrorException, blspsi(spot,K,r,T,-SigmaHyper,d))
@test_throws(ErrorException, blslambda(spot,K,r,T,-SigmaHyper,d))
@test_throws(ErrorException, blsvanna(spot,K,r,T,-SigmaHyper,d))
@test_throws(ErrorException, blsvega(spot,K,r,T,-SigmaHyper,d))

print_colored("Hyper Dual Input Validation Test Passed\n",:magenta)


text:
#!/usr/bin/env julia

# The code for 01b is identical but needs a 3-point sliding sum, which
# I've adapted from SO code for a moving average.
#   https://stackoverflow.com/questions/59562325/moving-average-in-julia
moving_sum(vs,n) = [sum(@view vs[i:(i+n-1)]) for i in 1:(length(vs)-(n-1))]

function main()
    f_int = parse.(Int, readlines("input"))
    f_sum = moving_sum(f_int, 3)

    # `hold` will contain the previous depth
    # `counter' the number of times the depth increases
    hold = 0
    counter = 0

    for i in range(1, length(f_sum))
        val = f_sum[i]

        # There's no depth before the first one
        if i > 1
            if val > hold
                counter += 1
            end
        end
        hold = val
    end

    print(counter)
end

main()

ext: jl


text:
function GaussSeidelSolve(A::Any,B::Vector; Guess=false,ϵ=0.05, MaxItr=30, λ=1)
      #A = the matrix of coefficients 'A' must be squared
  #B = The Vector 'B' right hand side vector Vertical
    m,n =size(A)
    v = size(B,1)
    if m != n
        error("Matrix must be squared")
    elseif m != v
        error("Vector Length must be equal to Matrix")
    end

    w=1:m          #Count m range

    c=zeros(m,m-1)
    er=[1.]
    cond=false
    for i=1:m
        W=w[w.!=i]
       c[i,:]= A[i,W]
    end

    Guess==false ? X=zeros(1,m) : X=Guess'
    itr=2

    while cond==false

        X=vcat(X,X[[itr-1],:])
        #Relaxation
        X[itr,:]=λ.*X[itr,:].+(1-λ).*X[itr-1,:]

        for i=1:m
            W=w[w.!=i]
            X[itr,i]=(B[i]-(c[i,:]'*X[itr,W]))/A[i,i]
        end

        e=maximum((X[itr,:].-X[itr-1,:])./X[itr,:])
        push!(er,e)
        cond=er[itr] .<=ϵ || itr .>= MaxItr
        println("Iteration $(itr-1) Error $(er[itr]*100) %")

        itr += 1
    end #End while loop

    return X[end,:], itr
end


text:
using LinearAlgebra
using Random

mutable struct DiscreteHopfieldNet <: HopfieldNet
    s::BitArray{N} where {N} # State -- could have used Int's
    W::Array{Float64, N} where {N} # Weights
end

function DiscreteHopfieldNet(n::Integer)
    s = BitArray(rand(Bool, n))
    W = rand(n, n)
    DiscreteHopfieldNet(s, W)
end

function DiscreteHopfieldNet(N::Tuple)
    s = BitArray(rand(Bool, N))
    a = Vector{Int}()
    # for i in N
    #     push!(a, repeat([i], length(N))...)
    # end

    W = rand(Float64, repeat([N...],2)...)
    DiscreteHopfieldNet(s, W)
end

# Perform update on a certain neuron
# function update!(net::HN, ind::Tuple, θ::Float64 = 0.0) where {HN <: HopfieldNet}
#     N = size(net.s)
#     N_2 = size(net.W)
#     a = []
#     for i in 1:length(N_2)
#         if i <= length(N)
#             push!(a, ind[i])
#         else
#             push!(a, :)
#         end
#     end
#     dotp = dot(net.W[a...], net.s)
#     net.s[ind...] = dotp > θ ? +1 : -1
#     # net.s[ind...] = dot(net.W[a...], net.s) > 0.5 ? 1 : 0

#     return nothing
# end

# # Perform an update cycle on the whole network
# function cycle!(net::HN, θ::Float64 = 50.0) where {HN <: HopfieldNet}
#     N = size(net.s)
#     # N_2 = size(net.W)
#     randInd = [shuffle(1:i) for i in N]
#     for i in Base.Iterators.product(randInd...)
#         update!(net, i, θ)
#     end
#     return nothing
# end

function Base.show(io::IO, net::DiscreteHopfieldNet)
    # @printf io "A discrete Hopfield net with %d neurons\n" length(net.s)
    print(io, "A discrete Hopfield net with $(size(net.s)) neurons")
end

#=
# Perform one asynchronous update on randomly selected neuron
function update!(net::DiscreteHopfieldNet)
    i = rand(1:length(net.s))
    net.s[i] = dot(net.W[:, i], net.s) > 0 ? +1 : -1
    return nothing
end
=#


text:
@testset "subs" begin
    @test FP.subs("abc") == "abc"
    @test FP.subs("abc") !== "abc"
    @test FP.subs("abc") isa SubString
    @test FP.subs("abcd", 2) == "b"
    @test FP.subs("abcd", 2, 3) == "bc"
    @test FP.subs("abcd", 2:3) == "bc"
    a = FP.subs("abc")
    @test FP.subs(a) === a
    # invalid string indices
    @test_throws StringIndexError FP.subs("jμΛια", 2:3)
end

@testset "parent_string" begin
    s = "abcd"
    @test FP.parent_string(s) === s
    @test FP.parent_string(FP.subs(s, 2)) === s
end

@testset "from, to" begin
    s = "abcdef"
    @test FP.from(s) == firstindex(s)
    @test FP.to(s) == lastindex(s)
    ss = FP.subs(s, 2:3)
    @test FP.from(ss) == 2
    @test FP.to(ss) == 3
end

@testset "dedent" begin
    for wsp in ("    ", " ", "\t")
        @test FP.dedent("""
            $(wsp)hello
            $(wsp)bye
            """) == """
            hello
            bye
            """
        @test FP.dedent("""
            $(wsp)$(wsp)hello
            $(wsp)bye
            """) == """
            $(wsp)hello
            bye
            """
        @test FP.dedent("""
            $(wsp)abc

            $(wsp)def
            """) == """
            abc

            def
            """
    end
    # mixing
    wsp = "\t"
    @test FP.dedent("""
        $(wsp) hello
        $(wsp)$(wsp)bye
        """) == """
         hello
        $(wsp)bye
        """
    @test FP.dedent("""
         $(wsp)hello
        $(wsp)$(wsp)bye
        """) == """
         $(wsp)hello
        $(wsp)$(wsp)bye
        """
end

@testset "prev/next chars" begin
    s = "abc def ghi"
    ss = FP.subs(s, 5:7)
    @test FP.previous_chars(ss, 3) == ['b', 'c', ' ']
    @test FP.next_chars(ss, 3) == [' ', 'g', 'h']
    s = "jμΛι∀γϵ∛Ϡe"
    ss = FP.subs(s, 4:8)
    @test FP.previous_chars(ss, 2) == ['j', 'μ']
    @test FP.next_chars(ss, 3) == ['γ', 'ϵ', '∛']
end


text:
using DiffEqEnvironments
using DifferentialEquations
using LinearAlgebra
using ControlSystems
using Test
using ReinforcementLearningBase
using Plots

"""
This test defines an SISO system of form
    ṡ = A*s + B*a
    o = C*s
for the rocket car problem, where
    s = [p, ṗ]  ,
p being the position of the car.
The action used as an input to the system is
the car's acceleration p̈ ∈ [-1, 1]. Therefore
    ṡ = [ṗ, p̈] = [0 1; 0 0] * s + [0; 1] * u .
Full observation of the state is given, as
    o = s   .
"""
T = Float32

# System matrices
A = [0 1; 0 0]
B = [0, 1]

# weights for quadratic cost function
Q = I * 10
R = I

# Set range of control input
a_lb = -1.0; a_ub = 1.0

# Set IC & tspan for integration
s0 = [-0.75, 0.0]
tspan = (0f0, 5f0)

# Define ODEProblem of SISO LTI system
function lti(s, a, t)
    ṡ = A * s + B * a
end
prob_lti = ODEProblem(lti, s0, tspan)

# Use ControlSystems.jl to solve continuous algebraic Riccati eq.
P = care(A, B, Q, R) # P encodes value function as v(s)= -s'*P*s/2
K = -R \ B' * P
println("K=", K)

v_lqr(s) = -s' * P * s / 2
π_lqr(s) = clamp.(K * s, a_lb, a_ub) #  LQR controller w/ saturation

# Define closed-loop ODE for system with input saturations
function cl_ode(s, π, t)
    a = π(s)
    ṡ = lti(s, a, t)
end

function plot_value(v; levels=10)
    ps = range(-1, 1, length=100)
    ṗs = range(-1, 1, length=100)
    vp(p, ṗ) = v([p,ṗ])

    contour(ps, ṗs, vp, levels=levels,
        xlabel="p", ylabel="ṗ",
        fill=true, show=true)
end

p = plot_value(v_lqr)

# Plot LQR Solution
prob_lqr = ODEProblem(cl_ode, s0, tspan, π_lqr)
sol_lqr = solve(prob_lqr, Tsit5())

function plot_phase_portrait!(plt, π; n=20, scale=0.075)
    ṡ(s) = lti(s, π(s), 0) * scale
    ṡ(p, ṗ) = ṡ([p,ṗ])

    ps = range(-1, 1, length=n)
    ṗs = range(-1, 1, length=n)

    pps = [p for p in ps for ṗ in ṗs]
    ṗṗs = [ṗ for p in ps for ṗ in ṗs]
    quiver!(pps, ṗṗs, quiver=ṡ, lw=1, c=:black,
        xlim=(-1, 1), ylim=(-1, 1),
        arrow=(style = :closed; headlength = 0.1))
end

function plot_trajectory!(plt, s0, π; c=:black)
    prob = ODEProblem(cl_ode, s0, tspan, π)
    sol = solve(prob, Tsit5(), saveat=0.01)

    plot!(plt, sol[1,:], sol[2,:], lw=3, c=c,
        xlim=(-1, 1), ylim=(-1, 1), line=:arrow,
        legend=false, show=true)
end

p2 = plot_phase_portrait!(p, π_lqr)
p3 = plot_trajectory!(p, s0, π_lqr)

display(p)

# Define DiffEqEnv
r = QuadraticRewardFunction(Q, R)
n_actions = 1
dt = 0.1
env = DiffEqEnv(prob_lti, r, n_actions, dt, a_lb=a_lb, a_ub=a_ub)


text:
@testset "Records" begin
    @testset "Record" begin
        @testset "SimpleRecord (test)" begin
            rec = SimpleRecord("info", "blah")

            @test rec.level == "info"
            @test rec.msg == "blah"

            dict = Dict(rec)
            @test rec.msg == dict[:msg]
        end
    end

    @testset "AttributeRecord" begin
        @testset "ConstRecord (test)" begin
            rec = ConstRecord()

            @test rec.level == "error"
            @test rec.msg == "It's a ConstRecord"

            dict = Dict(rec)
            @test rec.msg == dict[:msg]
        end

        @testset "DefaultRecord" begin
            rec = DefaultRecord("Logger.example", "info", 20, "blah")

            @test haskey(rec, :date)
            @test rec.date == something(rec.date)

            dict = Dict(rec)
            @test rec.date == dict[:date]
        end
    end
end


text:
@testset "linear problems" begin
    @testset "lp1_test" begin
        #=
        primal
            min -4x_2 - 1
        s.t.
            x_1 >= 3         :y_2
            x_1 + 2x_2 <= 3  :y_3

        dual
            max 3y_2 + 3y_3 - 1
        s.t.
            y_2 >= 0
            y_3 <= 0
            y_2 + y_3 == 0    :x_1
            2y_3 == -4        :x_2
        =#
        primal_model = lp1_test()
        dual_model, primal_dual_map = dual_model_and_map(primal_model)

        @test MOI.get(dual_model, MOI.NumberOfVariables()) == 2
        list_of_cons = MOI.get(dual_model, MOI.ListOfConstraints())
        @test Set(list_of_cons) == Set(
            [
                (SVF, MOI.GreaterThan{Float64})
                (SVF, MOI.LessThan{Float64})
                (SAF{Float64}, MOI.EqualTo{Float64})
            ],
        )
        @test MOI.get(
            dual_model,
            MOI.NumberOfConstraints{SVF,MOI.GreaterThan{Float64}}(),
        ) == 1
        @test MOI.get(
            dual_model,
            MOI.NumberOfConstraints{SVF,MOI.LessThan{Float64}}(),
        ) == 1
        @test MOI.get(
            dual_model,
            MOI.NumberOfConstraints{SAF{Float64},MOI.EqualTo{Float64}}(),
        ) == 2
        obj_type = MOI.get(dual_model, MOI.ObjectiveFunctionType())
        @test obj_type == SAF{Float64}
        obj = MOI.get(dual_model, MOI.ObjectiveFunction{obj_type}())
        @test MOI.constant(obj) == -1.0
        @test MOI.coefficient.(obj.terms) == [3.0; 3.0]
    end

    @testset "lp7_test" begin
        #=
        primal
            min -4x1 -3x2 -1
        s.t.
            2x1 + x2 - 3 <= 0  :y_3
            x1 + 2x2 - 3 <= 0  :y_4
            x1 >= 1            :y_1
            x2 >= 0            :y_2

        dual
            max 3y_4 + 3y_3 + y_1 - 1
        s.a.
            y_1 + 2y_3 + y_4 = -4 :x_1
            y_2 + y_3 + 2y_4 = -3 :x_2
            y_1 >= 0
            y_2 >= 0
            y_3 <= 0
            y_4 <= 0
        =#
        primal_model = lp7_test()
        dual_model, primal_dual_map = dual_model_and_map(primal_model)

        @test MOI.get(dual_model, MOI.NumberOfVariables()) == 3
        list_of_cons = MOI.get(dual_model, MOI.ListOfConstraints())
        @test Set(list_of_cons) == Set(
            [
                (SVF, MOI.GreaterThan{Float64})
                (SAF{Float64}, MOI.EqualTo{Float64})
                (SAF{Float64}, MOI.GreaterThan{Float64})
                (VVF, MOI.Nonpositives)
            ],
        )
        @test MOI.get(
            dual_model,
            MOI.NumberOfConstraints{SVF,MOI.GreaterThan{Float64}}(),
        ) == 1
        @test MOI.get(
            dual_model,
            MOI.NumberOfConstraints{VVF,MOI.Nonpositives}(),
        ) == 1
        @test MOI.get(
            dual_model,
            MOI.NumberOfConstraints{SAF{Float64},MOI.EqualTo{Float64}}(),
        ) == 1
        obj_type = MOI.get(dual_model, MOI.ObjectiveFunctionType())
        @test obj_type == SAF{Float64}
        obj = MOI.get(dual_model, MOI.ObjectiveFunction{obj_type}())
        @test MOI.constant(obj) == -1.0
        @test MOI.coefficient.(obj.terms) ==
              (Sys.WORD_SIZE == 32 ? [1.0, 3.0, 3.0] : [3.0; 1.0; 3.0])
    end

    @testset "lp10_test" begin
        #=
        primal
            min x1
        s.t.
            2x1 + x2  == 3 :y_3
            x1 + 2x2  == 3 :y_4
            x1 >= 1        :y_1
            x2 == 0        :y_2

        dual
            max y_1 + 3y_3 + 3y_4
        s.t
            y_2 + y_3 + y_4 == 1.0 :x_1
            y_1 + y_3 + y_4 == 0.0 :x_2
            y_2 >= 0
        =#
        primal_model = lp10_test()
        dual_model, primal_dual_map = dual_model_and_map(primal_model)

        @test MOI.get(dual_model, MOI.NumberOfVariables()) == 3
        list_of_cons = MOI.get(dual_model, MOI.ListOfConstraints())
        @test Set(list_of_cons) == Set(
            [
                (SVF, MOI.GreaterThan{Float64})
                (SAF{Float64}, MOI.EqualTo{Float64})
            ],
        )
        @test MOI.get(
            dual_model,
            MOI.NumberOfConstraints{SVF,MOI.GreaterThan{Float64}}(),
        ) == 1
        @test MOI.get(
            dual_model,
            MOI.NumberOfConstraints{SAF{Float64},MOI.EqualTo{Float64}}(),
        ) == 1
        obj_type = MOI.get(dual_model, MOI.ObjectiveFunctionType())
        @test obj_type == SAF{Float64}
        obj = MOI.get(dual_model, MOI.ObjectiveFunction{obj_type}())
        @test MOI.constant(obj) == 0.0
        @test Set(MOI.coefficient.(obj.terms)) == Set([1.0; 3.0; 3.0])
    end

    @testset "lp12_test" begin
        #=
        primal
            min 4x_3 + 5
        s.t.
            x_1 + 2x_2 + x_3 <= 20 :y_3
            x_1 <= 1               :y_1
            x_2 <= 3               :y_2

        dual
            max 3y_2 + y_1 + 20y_3 + 5
        s.t.
            y_1 + y_3 == 0
            y_2 + 2y_3 == 0
            y_3 == 4.0
            y_1 <= 0
            y_2 <= 0
            y_3 <= 0
        =#
        primal_model = lp12_test()
        dual_model, primal_dual_map = dual_model_and_map(primal_model)

        @test MOI.get(dual_model, MOI.NumberOfVariables()) == 3
        list_of_cons = MOI.get(dual_model, MOI.ListOfConstraints())
        @test Set(list_of_cons) == Set(
            [
                (SVF, MOI.LessThan{Float64})
                (SAF{Float64}, MOI.EqualTo{Float64})
            ],
        )
        @test MOI.get(
            dual_model,
            MOI.NumberOfConstraints{SVF,MOI.LessThan{Float64}}(),
        ) == 3
        @test MOI.get(
            dual_model,
            MOI.NumberOfConstraints{SAF{Float64},MOI.EqualTo{Float64}}(),
        ) == 3
        obj_type = MOI.get(dual_model, MOI.ObjectiveFunctionType())
        @test obj_type == SAF{Float64}
        obj = MOI.get(dual_model, MOI.ObjectiveFunction{obj_type}())
        @test MOI.constant(obj) == 5.0
        @test Set(MOI.coefficient.(obj.terms)) == Set([1.0; 3.0; 20.0])
    end

    @testset "lp13_test" begin
        #=
        primal
           min -4x1 -3x2 -1
        s.t.
           2x1 + x2 - 3 <= 0  :y_3
           x1 + 2x2 - 3 <= 0  :y_4
           x1 >= 0            :y_1
           x2 >= 0            :y_2

        dual
           max 3y_4 + 3y_3 - 1
        s.a.
           y_1 + 2y_3 + y_4 = -4 :x_1
           y_2 + y_3 + 2y_4 = -3 :x_2
           y_1 >= 0
           y_2 >= 0
           y_3 <= 0
           y_4 <= 0
        =#
        primal_model = lp13_test()
        dual_model, primal_dual_map = dual_model_and_map(primal_model)

        @test MOI.get(dual_model, MOI.NumberOfVariables()) == 2
        list_of_cons = MOI.get(dual_model, MOI.ListOfConstraints())
        @test Set(list_of_cons) == Set([
            (VAF{Float64}, MOI.Nonnegatives)
            (VVF, MOI.Nonpositives)
        ])
        @test MOI.get(
            dual_model,
            MOI.NumberOfConstraints{VVF,MOI.Nonpositives}(),
        ) == 1
        @test MOI.get(
            dual_model,
            MOI.NumberOfConstraints{VVF,MOI.Nonnegatives}(),
        ) == 0
        @test MOI.get(
            dual_model,
            MOI.NumberOfConstraints{SAF{Float64},MOI.EqualTo{Float64}}(),
        ) == 0
        obj_type = MOI.get(dual_model, MOI.ObjectiveFunctionType())
        @test obj_type == SAF{Float64}
        obj = MOI.get(dual_model, MOI.ObjectiveFunction{obj_type}())
        @test MOI.constant(obj) == -1.0
        @test MOI.coefficient.(obj.terms) == [3.0; 3.0]
    end
end


text:
# [
#  [ MPIStateArray Name, Field Name, Maximum, Minimum, Mean, Standard Deviation ],
#  [         :                :          :        :      :          :           ],
# ]

parr = [
    ["state", :ρ, 12, 12, 12, 12],
    ["state", "ρu[1]", 12, 11, 12, 12],
    ["state", "ρu[2]", 12, 12, 11, 12],
    ["state", :ρθ, 11, 12, 10, 12],
]

#! format: off
rusanov_periodic = (
[
 [ "state",     "ρ", 9.76557021043823247908e-01,  1.00785052430958410596e+00,  1.00000023257151737788e+00,  5.40633258005515995870e-03 ],
 [ "state", "ρu[1]", -2.08235364819134516345e-01,  5.42021330588998817568e-01,  1.59191748432813973135e-01,  1.71679977050671228600e-01 ],
 [ "state", "ρu[2]", -4.44598929671790876750e-01,  3.96193527502323006306e-01, -9.19857600654994111977e-06,  2.23835345394622464710e-01 ],
 [ "state",    "ρθ", -1.05926174767863745529e+00,  1.78285318416958671328e+00,  3.38466687536443516793e-03,  2.92797512839404083795e-01 ],
],
    parr,
)

roeflux_periodic = (
[
 [ "state",     "ρ",  9.76408216346011381681e-01,  1.00685186827167338919e+00,  1.00000020920188337215e+00,  5.28437765352953326553e-03 ],
 [ "state", "ρu[1]", -2.51377173896010663867e-01,  5.33033893482195431091e-01,  1.59154423274343037598e-01,  1.96922130305308085152e-01 ],
 [ "state", "ρu[2]", -4.04321943123139071474e-01,  3.81969301036260144855e-01, -2.87040331153030903177e-05,  2.02392226536863034658e-01 ],
 [ "state",    "ρθ", -1.21186199231530267184e+00,  9.21722158564563742722e-01,  2.34662081315961668082e-03,  2.61922031216240580598e-01 ],
],
    parr,
)

rusanov = (
[
 [ "state",     "ρ",  9.76844648039728813416e-01,  1.00662311214286837036e+00,  1.00000043240984126669e+00,  6.05641827304116090597e-03 ],
 [ "state", "ρu[1]", -6.93213807814652027695e-01,  5.89769972499923134102e-01,  1.42589259313275984464e-01,  2.32576446220999155656e-01 ],
 [ "state", "ρu[2]", -5.73828377062444716650e-01,  5.07664260030296077275e-01, -4.23962044125134052130e-04,  1.96899492339057097245e-01 ],
 [ "state",    "ρθ", -3.65527466807722500874e+00,  4.07350442876234186684e+00,  1.27099405499731775426e-02,  5.02926135539447205502e-01 ],
],
    parr,
)

roeflux = (
[
 [ "state",     "ρ",  9.72455511248961124160e-01,  1.00730359035806360524e+00,  1.00000004243418749716e+00,  6.29619947553510493632e-03 ],
 [ "state", "ρu[1]", -3.40062758027173561715e-01,  5.98382642258275421199e-01,  1.61534160931526560301e-01,  1.83683987730847486652e-01 ],
 [ "state", "ρu[2]", -4.78833188511707363855e-01,  5.60276621431795018857e-01, -5.51384446753656887186e-05,  2.12893889070269098918e-01 ],
 [ "state",    "ρθ", -1.44374005663885895956e+01,  2.86753217014698513765e+00,  1.48814717217727286724e-03,  5.22593283079209602882e-01 ],
],
    parr,
)

rusanov_overintegration = (
[
 [ "state",     "ρ",  9.71215931957259970275e-01,  1.00598091306596182370e+00,  1.00000018331969764418e+00,  6.61958163862229592017e-03 ],
 [ "state", "ρu[1]", -3.70465052437365993665e-01,  7.21959883918644518275e-01,  1.59085030658594694941e-01,  2.39392692254175726285e-01 ],
 [ "state", "ρu[2]", -4.40021840550348763976e-01,  4.17225753221437845042e-01,  7.34809696136107232513e-05,  1.50458151629451780673e-01 ],
 [ "state",    "ρθ", -3.05207824503129643290e+00,  1.86668064854026383159e+00, -1.05021657861818027563e-02,  4.60981422911087401761e-01 ],
],
    parr,
)

roeflux_overintegration = (
[
 [ "state",     "ρ",  9.69901051313856066294e-01,  1.00695111308847851106e+00,  1.00000002953972089159e+00,  6.94722590819101589593e-03 ],
 [ "state", "ρu[1]", -4.21771768146742886962e-01,  6.34790159642324547384e-01,  1.59384804664454482470e-01,  2.22844788492525480716e-01 ],
 [ "state", "ρu[2]", -4.37678540756429201863e-01,  4.53959896024816400573e-01, -1.22554654623556756642e-04,  1.73930782418124457722e-01 ],
 [ "state",    "ρθ", -1.13636401173616619076e+00,  1.51145239791767727056e+00,  1.96870293018723595616e-03,  3.82573373360323043535e-01 ],
],
    parr,
)
#! format: on

refVals = (;
    rusanov_periodic,
    roeflux_periodic,
    rusanov,
    roeflux,
    rusanov_overintegration,
    roeflux_overintegration,
)


text:
using FresnelIntegrals
using Test
using QuadGK

@testset "FresnelIntegrals.jl" begin
    # Generate random complex number
    z = randn(ComplexF64)
    # Test by comparing to numeric solution
    @test fresnelc(z) ≈ quadgk(t->cos(π*t^2/2),0,z)[1]
    @test fresnels(z) ≈ quadgk(t->sin(π*t^2/2),0,z)[1]
    # Test just for code coverage 😄
    @test (fresnelc(z),fresnels(z)) == fresnel(z)
end


text:
function converttopartitionedbernoullidbm(mdbm::MultimodalDBM)
   Vector{Union{BernoulliRBM, PartitionedRBM{BernoulliRBM}}}(mdbm)
end

"""
    addlayer!(dbm, x)
Adds a pretrained layer to the BasicDBM `dbm`, given the dataset `x` as input
for the visible layer of the `dbm`.

# Optional keyword arguments:
* `isfirst`, `islast`: indicating that the new RBM should be trained as
   first (assumed if `dbm` is empty) or last layer of the DBM, respectively.
   If those flags are not set, the added layer is trained as intermediate layer.
   This information is needed to determine the factor for the weights during
   pretraining.
* `epochs`, `nhidden`, `learningrate`/`learningrates`, `pcd`, `cdsteps`,
  `monitoring`: used for fitting the weights of the last layer, see `fitrbm(x)`
"""
function addlayer!(dbm::BasicDBM, x::Matrix{Float64};
      isfirst::Bool = isempty(dbm),
      islast::Bool = false,
      nhidden::Int = size(x,2),
      epochs::Int = 10,
      learningrate::Float64 = 0.005,
      learningrates::Vector{Float64} = learningrate * ones(epochs),
      pcd::Bool = true,
      cdsteps::Int = 1,
      monitoring::Function = nomonitoring)

   warn("`addlayer!`` is deprecated. Please use the options of `fitdbm` instead.")
   # propagate input x up to last hidden layer
   hh = x
   for i = 1:length(dbm)
      hh = hiddenpotential(dbm[i], hh, 2.0) # intermediate layer, factor is 2.0
   end

   upfactor = downfactor = 2.0
   if isfirst
      downfactor = 1.0
   end
   if islast
      upfactor = 1.0
   end

   rbm = fitrbm(hh, nhidden = nhidden, epochs = epochs,
         rbmtype = BernoulliRBM,
         learningrate = learningrate,
         learningrates = learningrates,
         pcd = pcd, cdsteps = 1,
         upfactor = upfactor, downfactor = downfactor,
         monitoring = monitoring)

   push!(dbm, rbm)
   dbm
end

function defaultfinetuninglearningrates(learningrate, epochs)
   learningrate * 11.0 ./ (10.0 .+ (1:epochs))
end

"""
    fitdbm(x; ...)
Fits a (multimodal) DBM to the data set `x`.
The procedure consists of two parts:
First a stack of RBMs is pretrained in a greedy layerwise manner
(see `stackrbms(x)`). Then the weights of all layers are jointly
trained using the general Boltzmann Machine learning procedure
(see `traindbm!(dbm,x)`).

# Optional keyword arguments (ordered by importance):
* `nhiddens`: vector that defines the number of nodes in the hidden layers of
   the DBM. The default value specifies two hidden layers with the same size
   as the visible layer.
* `epochs`: number of training epochs for joint training
* `epochspretraining`: number of training epochs for pretraining,
   defaults to `epochs`
* `learningrate`/`learningrates`:
   learning rate(s) for joint training of layers (= fine tuning)
   using the learning algorithm for a general Boltzmann Machine.
   The learning rate for fine tuning is by default decaying with the number of epochs,
   starting with the given value for the `learningrate`.
   (For more details see `traindbm!`).
* `learningratepretraining`: learning rate for pretraining,
   defaults to `learningrate`
* `batchsizepretraining`: batchsize for pretraining, defaults to 1
* `nparticles`: number of particles used for sampling during joint training of
   DBM, default 100
* `pretraining`: The arguments for layerwise pretraining
   can be specified for each layer individually.
   This is done via a vector of `TrainLayer` objects.
   (For a detailed description of the possible parameters,
   see help for `TrainLayer`).
   If the number of training epochs and the learning rate are not specified
   explicitly for a layer, the values of `epochspretraining`,
   `learningratepretraining` and `batchsizepretraining` are used.
* `monitoring`: Monitoring function accepting a `dbm` and the number of epochs
   retuning nothing. Used for the monitoring of fine-tuning.
* `monitoringdatapretraining`: a `DataDict` that contains data used for
   monitoring the pretraining (see argument `monitoringdata` of `stackrbms`.)
* `optimizer`/`optimizers`: an optimizer or a vector of optimizers for each epoch
   (see `AbstractOptimizer`) used for fine-tuning.
* `optimizerpretraining`: an optimizer used for pre-training.
   Defaults to the `optimizer`.
"""
function fitdbm(x::Matrix{Float64};
      nhiddens::Vector{Int} = Vector{Int}(),
      epochs::Int = 10,
      nparticles::Int = 100,
      learningrate::Float64 = 0.005,
      learningrates::Vector{Float64} =
            defaultfinetuninglearningrates(learningrate, epochs),
      sdlearningrate::Float64 = 0.0,
      sdlearningrates::Vector{Float64} =
            defaultfinetuninglearningrates(sdlearningrate, epochs),
      learningratepretraining::Float64 = learningrate,
      epochspretraining::Int = epochs,
      batchsizepretraining::Int = 1,
      pretraining::AbstractTrainLayers = Vector{TrainLayer}(),
      monitoring::Function = nomonitoring,
      monitoringdatapretraining::DataDict = DataDict(),
      optimizer::AbstractOptimizer = NoOptimizer(),
      optimizers::Vector{<:AbstractOptimizer} = Vector{AbstractOptimizer}(),
      optimizerpretraining::AbstractOptimizer = optimizer)

   if isempty(pretraining) && isempty(nhiddens)
      # set default only if there is not any more detailed info
      nvariables = size(x,2)
      nhiddens = [nvariables; nvariables]
   end

   # Layerwise pre-training
   pretraineddbm = stackrbms(x, nhiddens = nhiddens,
         epochs = epochspretraining, predbm = true,
         batchsize = batchsizepretraining,
         learningrate = learningratepretraining,
         optimizer = optimizer,
         trainlayers = pretraining,
         monitoringdata = monitoringdatapretraining)
   # Fine-tuning using mean-field approximation in algorithm for
   # training a general Boltzmann machine
   traindbm!(pretraineddbm, x, epochs = epochs, nparticles = nparticles,
         learningrate = learningrate, learningrates = learningrates,
         sdlearningrate = sdlearningrate, sdlearningrates = sdlearningrates,
         optimizer = optimizer, optimizers = optimizers,
         monitoring = monitoring)
end

"""
    newparticleslike(particles)
Creates new and uninitialized particles of the same dimensions as the given
`particles`.
"""
function newparticleslike(particles::Particles)
   newparticles = Particles(undef, length(particles))
   for i in eachindex(particles)
      newparticles[i] = Matrix{Float64}(undef, size(particles[i]))
   end
   newparticles
end

"""
    meanfield(dbm, x)
    meanfield(dbm, x, eps)
Computes the mean-field approximation for the data set `x` and
returns a matrix of particles for the DBM.
The number of particles is equal to the number of samples in `x`.
`eps` is the convergence criterion for the fix-point iteration, default 0.001.
It is assumed that all nodes in in-between-layers are Bernoulli distributed.
"""
function meanfield(dbm::MultimodalDBM, x::Array{Float64,2}, eps::Float64 = 0.001)

   nlayers = length(dbm) + 1
   mu = Particles(undef, nlayers)

   # Initialization with single bottom-up pass using twice the weights for all
   # but the topmost layer (see [Salakhutdinov+Hinton, 2012], p. 1985)
   mu[1] = x
   for i=2:(nlayers-1)
      mu[i] = hiddenpotential(dbm[i-1], mu[i-1], 2.0)
   end
   mu[nlayers] = hiddenpotential(dbm[nlayers-1], mu[nlayers-1])

   newmu = newparticleslike(mu)
   newmu[1] = x
   input2 = newparticleslike(mu)

   # mean-field updates until convergence criterion is met
   delta = 1.0
   while delta > eps
      delta = 0.0

      for i = 2:(nlayers-1)
         # total input from layer below
         hiddeninput!(newmu[i], dbm[i-1], mu[i-1])
         # input from layer above
         visibleinput!(input2[i], dbm[i], mu[i+1])
         # combine input
         newmu[i] .+= input2[i]
         # By computing the potential,
         # the assumption is used that all nodes in in-between-layers
         # are Bernoulli-distributed:
         sigm!(newmu[i])

         delta = max(delta, maximum(abs.(mu[i] - newmu[i])))

         # swap new and old mu
         tmp = newmu[i]
         newmu[i] = mu[i]
         mu[i] = tmp
      end

      # last layer
      hiddenpotential!(newmu[end], dbm[end], mu[end-1])
      delta = max(delta, maximum(abs.(mu[end] - newmu[end])))

      # swap new and old mu
      tmp = newmu[end]
      newmu[end] = mu[end]
      mu[end] = tmp
   end

   mu
end

"""
    traindbm!(dbm, x; ...)
Trains the `dbm` (a `BasicDBM` or a more general `MultimodalDBM`) using
the learning procedure for a general Boltzmann Machine with the
training data set `x`.
A learning step consists of mean-field inference (positive phase),
stochastic approximation by Gibbs Sampling (negative phase) and the parameter
updates.

# Optional keyword arguments (ordered by importance):
* `epoch`: number of training epochs
* `learningrate`/`learningrates`: a vector of learning rates for each epoch to
   update the weights and biases. The learning rates should decrease with the
   epochs, e. g. like `a / (b + epoch)`. If only one value is given as
   `learningrate`, `a` and `b` are 11.0 and 10.0, respectively.
* `nparticles`: number of particles used for sampling, default 100
* `monitoring`: A function that is executed after each training epoch.
   It has to accept the trained DBM and the current epoch as arguments.
"""
function traindbm!(dbm::MultimodalDBM, x::Array{Float64,2};
      epochs::Int = 10,
      nparticles::Int = 100,
      learningrate::Float64 = 0.005,
      learningrates::Vector{Float64} =
            defaultfinetuninglearningrates(learningrate, epochs),
      sdlearningrate::Float64 = 0.0,
      sdlearningrates::Vector{Float64} =
            defaultfinetuninglearningrates(sdlearningrate, epochs),
      monitoring::Function = nomonitoring,
      optimizer::AbstractOptimizer = NoOptimizer(),
      optimizers::Vector{<:AbstractOptimizer} = Vector{AbstractOptimizer}())

   assert_enoughvaluesforepochs("learningrates", learningrates, epochs)

   optimizer = converttodbmoptimizer(optimizer, dbm)
   map!(opt -> converttodbmoptimizer(opt, dbm), optimizers, optimizers)
   optimizers = assertinitoptimizers(optimizer, optimizers, dbm,
         learningrates, sdlearningrates, epochs)

   particles = initparticles(dbm, nparticles)

   for epoch = 1:epochs
      traindbm!(dbm, x, particles, optimizers[epoch])

      # monitoring the learning process at the end of epoch
      monitoring(dbm, epoch)
   end

   dbm
end

"""
    traindbm!(dbm, x, particles, learningrate)
Trains the given `dbm` for one epoch.
"""
function traindbm!(dbm::MultimodalDBM, x::Array{Float64,2}, particles::Particles,
      optimizer::AbstractOptimizer)

   gibbssample!(particles, dbm)
   mu = meanfield(dbm, x)

   computegradient!(optimizer, mu, particles, dbm)
   updateparameters!(dbm, optimizer)

   dbm
end


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

include("../src/SeisXcorrelation.jl")

using Documenter, .SeisXcorrelation

makedocs(;
    modules=[SeisXcorrelation],
    format=Documenter.HTML(),
    pages=[
        "Home" => "index.md",
    ],
    repo="https://github.com/kura-okubo/SeisXcorrelation.jl/blob/{commit}{path}#L{line}",
    sitename="SeisXcorrelation.jl",
    authors="kurama",
)

deploydocs(;
    repo="github.com/kura-okubo/SeisXcorrelation.jl",
    target = "build",
    deps   = nothing,
    make   = nothing,
)

max_stars_repo_name: kura-okubo/SeisXcorrelation

max_issues_repo_name: kura-okubo/SeisXcorrelation

max_forks_repo_name: kura-okubo/SeisXcorrelation


text:
using Weave
convert_doc("presentation.jmd", "presentation.ipynb")


text:
module ImPlot

using CEnum

include("libcimplot/libcimplot.jl")

# Types
using .LibCImPlot
import CImGui: ImVec2, ImVec4
import .LibCImPlot: ImPlotStyleVar, ImPlotPoint, ImPlotColormap, ImPlotCol
import .LibCImPlot: ImPlotFlags, ImPlotAxisFlags

# Export plot flags
for i in [ImPlotFlags, ImPlotAxisFlags]
    for j in instances(i)
        @eval export $(Symbol(j))
    end
end

function BeginPlot(title_id::String, x_label, y_label, size::ImVec2;
                    flags::ImPlotFlags = ImPlotFlags_None,
                    x_flags::ImPlotAxisFlags = ImPlotAxisFlags_None,
                    y_flags::ImPlotAxisFlags = ImPlotAxisFlags_None,
                    y2_flags::ImPlotAxisFlags = ImPlotAxisFlags_None,
                    y3_flags::ImPlotAxisFlags = ImPlotAxisFlags_None)::Bool

    LibCImPlot.BeginPlot(title_id, x_label, y_label, size,
                         flags, x_flags, y_flags, y2_flags, y3_flags)
end

import .LibCImPlot: EndPlot

include("lines.jl")
include("shaded.jl")
include("scatter.jl")
include("heatmap.jl")
include("digital.jl")
include("barchart.jl")
include("piechart.jl")
include("errorbars.jl")
include("other.jl")
include("util.jl")
include("color.jl")
include("styling.jl")

end # module


text:
# SPDX-License-Identifier: X11
# 2020-09-17
# Alter Altar (400pt)

function _main()
  N = parse(Int, readline())
  C = Vector{Char}(undef, 0)
  W, R = 0, 0

  for i ∈ 1:N
    c = read(stdin, Char)
    c == 'R' && (R += 1)
    push!(C, c)
  end

  ans = R
  for c ∈ C
    c == 'R' ? R -= 1 : W += 1
    ans = min(ans, max(W,R))
  end

  println(ans)
end

_main()

max_stars_repo_name: jthvai/competitive-programming

max_issues_repo_name: jthvai/competitive-programming

max_forks_repo_name: jthvai/competitive-programming


text:
using ContinuousPOMDPTreeSearchExperiments
using ParticleFilters
using ARDESPOT
using BasicPOMCP
using POMCPOW
using POMDPs
using DiscreteValueIteration
using QMDP
using MCTS
using VDPTag2
using POMDPToolbox
using DataFrames
using Plots
using StatPlots
using Missings

@everywhere using POMDPToolbox
@everywhere using Missings

file_contents = readstring(@__FILE__())

# pomdp = VDPTagPOMDP(mdp=VDPTagMDP(agent_speed=2.0#=, dt=0.01=#))
pomdp = VDPTagPOMDP()
dpomdp = AODiscreteVDPTagPOMDP(pomdp, 30, 0.5)

@show max_time = 1.0
@show max_depth = 10

solvers = Dict{String, Union{Solver,Policy}}(
    "to_next" => ToNextML(mdp(pomdp)),
    "manage_uncertainty" => ManageUncertainty(pomdp, 0.01),

    "pomcpow" => begin
        rng = MersenneTwister(13)
        ro = ToNextMLSolver(rng)
        ro = RandomSolver(rng)
        solver = POMCPOWSolver(tree_queries=10_000_000,
                               criterion=MaxUCB(90.0),
                               final_criterion=MaxQ(),
                               max_depth=max_depth,
                               max_time=max_time,
                               k_action=20.0,
                               alpha_action=1/20,
                               k_observation=6.0,
                               alpha_observation=1/55,
                               estimate_value=FORollout(ro),
                               next_action=RootToNextMLFirst(rng),
                               check_repeat_obs=false,
                               check_repeat_act=false,
                               default_action=ReportWhenUsed(TagAction(false, 0.0)),
                               rng=rng
                              )
    end,

    "pft" => begin
        rng = MersenneTwister(13)
        m = 15
        node_updater = ObsAdaptiveParticleFilter(deepcopy(pomdp),
                                           LowVarianceResampler(m),
                                           0.05, rng)
        ro = ToNextML(mdp(pomdp), rng)
        ro = RandomSolver(rng)
        ev = SampleRollout(solve(ro, pomdp), rng)
        solver = DPWSolver(n_iterations=typemax(Int),
                           exploration_constant=90.0,
                           depth=max_depth,
                           max_time=max_time,
                           k_action = 20.0,
                           alpha_action = 1/20,
                           k_state = 6.0,
                           alpha_state = 1/55,
                           check_repeat_state=false,
                           check_repeat_action=false,
                           estimate_value=ev,
                           next_action=RootToNextMLFirst(rng),
                           default_action=ReportWhenUsed(TagAction(false, 0.0)),
                           rng=rng
                          )
        belief_mdp = GenerativeBeliefMDP(deepcopy(pomdp), node_updater)
        solve(solver, belief_mdp)
    end,
)

@show N=1000

alldata = DataFrame()

# for (k, solver) in solvers
test = ["pft", "pomcpow"]
# test = ["to_next", "manage_uncertainty"]
for (k, solver) in [(s, solvers[s]) for s in test]
    @show k
    if isa(solver, Solver)
        planner = solve(solver, pomdp)
    else
        planner = solver
    end
    sims = []
    for i in 1:N
        srand(planner, i+50_000)
        filter = SIRParticleFilter(deepcopy(pomdp), 100_000, rng=MersenneTwister(i+90_000))

        md = Dict(:solver=>k, :i=>i)
        hr = HistoryRecorder(max_steps=100, rng=MersenneTwister(i+70_000), capture_exception=true)
        sim = Sim(deepcopy(pomdp),
                  planner,
                  filter,
                  simulator=hr,
                  metadata=md,
                 )

        push!(sims, sim)
    end

    data = run_parallel(sims) do sim, hist
        if isnull(hist.exception)
            tq = [get(info, :tree_queries, missing) for info in eachstep(hist,"ai")]
            if isempty(tq)
                println("Empty history?")
                @show n_steps(hist)
                iters = missing
            else
                iters = mean(tq)
            end
            return [:steps=>n_steps(hist),
                    :reward=>discounted_reward(hist),
                    :iterations=>iters
                   ]
        else
            println("Simulator Caught a $(typeof(get(hist.exception)))")
            return [:exception_type => string(typeof(get(hist.exception)))]
        end
    end
    # data = run(sims)

    rs = data[:reward]
    println(@sprintf("reward: %6.3f ± %6.3f", mean(rs), std(rs)/sqrt(length(rs))))
    is = data[:iterations]
    println(@sprintf("iterations: mean: %6.3f", mean(is)))

    if isempty(alldata)
        alldata = data
    else
        alldata = vcat(alldata, data)
    end
end

# p = plot()
# for data in groupby(alldata, :solver)
#     histogram!(p, data[:steps], label=first(data[:solver]))
# end
#
# gui(p)

#=
datestring = Dates.format(now(), "E_d_u_HH_MM")
copyname = Pkg.dir("ContinuousPOMDPTreeSearchExperiments", "icaps_2018", "data", "subhunt_table_$(datestring).jl")
write(copyname, file_contents)
filename = Pkg.dir("ContinuousPOMDPTreeSearchExperiments", "icaps_2018", "data", "subhunt_$(datestring).csv")
println("saving to $filename...")
writetable(filename, alldata)
println("done.")
=#


text:
@info "IncrementalInference.jl is loading tools related to DifferentialEquations.jl"

using .DifferentialEquations

import .DifferentialEquations: solve

import IncrementalInference: getSample

export DERelative

"""
    $TYPEDEF

Build a full ODE solution into a relative factor to condense possible sensor data into a relative transformation,
but keeping the parameter estimation process fluid.  Assumes first and second variable in order
are of same dimension and compatible manifolds, such that ODE runs from Xi to Xi+1 on all
dimensions.  Internal state vector can be decoupled onto different domain as needed.

Notes
- Based on DifferentialEquations.jl
- `getSample` step does the `solve(ODEProblem)` step.
- `tspan` is taken from variables only once at object construction -- i.e. won't detect changed timestamps.
- Regular factor evaluation is done as full dimension `AbstractRelativeRoots`, and is basic linear difference.

DevNotes
- FIXME see 1025, `multihypo=` will not yet work.
- FIXME Lots of consolidation and standardization to do, see RoME.jl #244 regarding Manifolds.jl.
- TODO does not yet handle case where a factor spans across two timezones.
"""
struct DERelative{T <:InferenceVariable, P, D} <: AbstractRelativeRoots
  domain::Type{T}
  forwardProblem::P
  backwardProblem::P
  # second element of this data tuple is additional variables that will be passed down as a parameter
  data::D
  specialSampler::Function
end

"""
$SIGNATURES

Calculate a DifferentialEquations.jl ready `tspan::Tuple{Float64,Float64}` from DFGVariables.

DevNotes
- TODO does not yet incorporate Xi.nanosecond field.
- TODO does not handle timezone crossing properly yet.
"""
function _calcTimespan( Xi::AbstractVector{<:DFGVariable}  )
  #
  tsmps = getTimestamp.(Xi[1:2]) .|> DateTime .|> datetime2unix
  # toffs = (tsmps .- tsmps[1]) .|> x-> elemType(x.value*1e-3)
  return (tsmps...,)
end
# Notes
# - Can change numerical data return type using an additional first argument, `_calcTimespan(Float32, Xi)`.
# _calcTimespan(Xi::AbstractVector{<:DFGVariable}) = _calcTimespan(Float64, Xi)

# performance helper function, FIXME not compatible with all multihypo cases
_maketuplebeyond2args = (w1=nothing,w2=nothing,w3_...) -> (w3_...,)

function DERelative( Xi::AbstractVector{<:DFGVariable},
                      domain::Type{<:InferenceVariable},
                      f::Function,
                      data=()->();
                      dt::Real=1,
                      state0::AbstractVector{<:Real}=zeros(getDimension(domain)),
                      state1::AbstractVector{<:Real}=zeros(getDimension(domain)),
                      tspan::Tuple{<:Real,<:Real}=_calcTimespan(Xi),
                      problemType = DiscreteProblem )
  #
  datatuple = if 2 < length(Xi)
    datavec = getDimension.([_maketuplebeyond2args(Xi...)...]) .|> x->zeros(x)
    (data,datavec...,)
  else
    data
  end
  # forward time problem
  fproblem = problemType(f, state0, tspan, datatuple, dt=dt )
  # backward time problem
  bproblem = problemType(f, state1, (tspan[2],tspan[1]), datatuple, dt=-dt )
  # build the IIF recognizable object
  DERelative( domain, fproblem, bproblem, datatuple, getSample )
end

DERelative( dfg::AbstractDFG,
            labels::AbstractVector{Symbol},
            domain::Type{<:InferenceVariable},
            f::Function,
            data=()->();
            Xi::AbstractArray{<:DFGVariable}=getVariable.(dfg, labels),
            dt::Real=1,
            state0::AbstractVector{<:Real}=zeros(getDimension(domain)),
            state1::AbstractVector{<:Real}=zeros(getDimension(domain)),
            tspan::Tuple{<:Real,<:Real}=_calcTimespan(Xi),
            problemType = DiscreteProblem ) = DERelative( Xi, domain, f, data; dt=dt, state0=state0, state1=state1, tspan=tspan, problemType=problemType  )
#
#

# Xtra splat are variable points (X3::Matrix, X4::Matrix,...)
function _solveFactorODE!(measArr, prob, u0pts, Xtra...)
  # should more variables be included in calculation
  for (xid, xtra) in enumerate(Xtra)
    # update the data register before ODE solver calls the function
    prob.p[xid+1][:] = Xtra[xid][:]
  end

  # set the initial condition
  prob.u0[:] = u0pts[:]
  sol = DifferentialEquations.solve(prob)

  # extract solution from solved ode
  measArr[:] = sol.u[end]
  sol
end

# FIXME see #1025, `multihypo=` will not work properly yet
function getSample( cf::CalcFactor{<:DERelative},
                    N::Int=1 )
  #

  oder = cf.factor
  fmd_ = cf.metadata

  # how many trajectories to propagate?
  # @show getLabel(fmd_.fullvariables[2]), getDimension(fmd_.fullvariables[2])
  meas = zeros(getDimension(fmd_.fullvariables[2]), N)

  # pick forward or backward direction
  prob = oder.forwardProblem
  # buffer manifold operations for use during factor evaluation
  addOp, diffOp, _, _ = AMP.buildHybridManifoldCallbacks( getManifolds(fmd_.fullvariables[2]) )
  # set boundary condition
  u0pts = if fmd_.solvefor == DFG.getLabel(fmd_.fullvariables[1])
    # backward direction
    prob = oder.backwardProblem
    addOp, diffOp, _, _ = AMP.buildHybridManifoldCallbacks( getManifolds(fmd_.fullvariables[1]) )
    getBelief( fmd_.fullvariables[2] ) |> getPoints
  else
    # forward backward
    getBelief( fmd_.fullvariables[1] ) |> getPoints
  end

  # solve likely elements
  for i in 1:N
    idxArr = view.(fmd_.arrRef,:,i)
    _solveFactorODE!(view(meas, :,i), prob, view(u0pts, :,i), _maketuplebeyond2args(idxArr...)...)
    # _solveFactorODE!(meas, prob, u0pts, i, _maketuplebeyond2args(fmd_.arrRef...)...)
  end

  return (meas, diffOp)
end
# getDimension(oderel.domain)

# NOTE see #1025, CalcFactor should fix `multihypo=` in `cf.metadata` fields
function (cf::CalcFactor{<:DERelative})(meas1,
                                        diffOp,
                                        X...)
  #

  oderel = cf.factor

  # work on-manifold
  # diffOp = meas[2]
  # if backwardSolve else forward

  # check direction
  # TODO put solveforIdx in FMD?
  solveforIdx = 1
  if cf.metadata.solvefor == DFG.getLabel(cf.metadata.fullvariables[2])
    solveforIdx = 2
  elseif cf.metadata.solvefor in _maketuplebeyond2args(cf.metadata.variablelist...)
    # need to recalculate new ODE (forward) for change in parameters (solving for 3rd or higher variable)
    solveforIdx = 2
    # use forward solve for all solvefor not in [1;2]
    u0pts = getBelief(cf.metadata.fullvariables[1]) |> getPoints
    # update parameters for additional variables
    _solveFactorODE!(meas1, oderel.forwardProblem, u0pts[:,cf._sampleIdx], _maketuplebeyond2args(X...)...)
  end

  # find the difference between measured and predicted.
  ## assuming the ODE integrated from current X1 through to predicted X2 (ie `meas1[:,idx]`)
  ## FIXME, obviously this is not going to work for more compilcated groups/manifolds -- must fix this soon!
  # @show cf._sampleIdx, solveforIdx, meas1

  #FIXME
  res = zeros(size(X[2],1))
  for i in 1:size(X[2],1)
    # diffop( test, reference )   <===>   ΔX = test \ reference
    res[i] = diffOp[i]( X[solveforIdx][i], meas1[i] )
  end
  res
end

## the function
# ode.problem.f.f

#


text:
using MonteCarloMarkovKernels
using StaticArrays
using Random
using LinearAlgebra
import Statistics.mean

zero2 = [0.0, 0.0]
μ1 = [-1.0,0.0]
Σ1 = [1.0 1.5 ; 1.5 3.0]
propSigma = [2.0 1.2 ; 1.2 3.0]

Szero2 = SVector{2, Float64}(zero2)
SpropSigma = SMatrix{2, 2, Float64}(propSigma)

## slightly more complicated, but much more efficient approach
## uses StaticArrays and scratch space
function makelogMVN(μ::SVector{d, Float64}, Σ::SMatrix{d, d, Float64}) where d
  invΣ = inv(Σ)
  lognc = - 0.5 * d * log(2 * π) - 0.5 * logdet(Σ)
  function lpi(x::SVector{d, Float64})
    v = x - μ
    return lognc - 0.5*dot(v, invΣ * v)
  end
  return lpi
end

logtarget = makelogMVN(SVector{2, Float64}(μ1), SMatrix{2, 2, Float64}(Σ1))
P_RWM = makeRWMKernel(logtarget, SpropSigma)

seed!(12345)
chain = simulateChain(P_RWM, Szero2, 2^15)

cc = MonteCarloMarkovKernels.cov(chain)

@test maximum(abs.(mean(chain) - μ1)) < 0.1
@test maximum(abs.(cc - Σ1)) < 0.2
@test 0.2 < P_RWM(:acceptanceRate) < 0.5

## test that only custom RNG is used
Random.seed!(1); v1 = rand(); Random.seed!(1)
P_RWM = makeRWMKernel(logtarget, SpropSigma, MersenneTwister(12345))
chain = simulateChain(P_RWM, Szero2, 256)
v2 = rand()
@test v1 == v2


text:
################################################################################
# Update equations in 2D
################################################################################

function update_H(E::VecArray{T,2}, H::VecArray{T,2}, C::Coefficients{T,2}) where T
    s = size(H[1])
    Hx = zeros(T, size(H[1]))
    Hy = zeros(T, size(H[2]))
    Hz = zeros(T, size(H[3]))

    Threads.@threads for j in 1:(s[2]-1)
        for i in 1:(s[1]-1)
            @inbounds Hx[i,j] = C.H[1][i,j]*H[1][i,j] + C.H[4][i,j]*(- C.Km[2][j]*(E[3][i, j+1] - E[3][i, j]))
            @inbounds Hy[i,j] = C.H[2][i,j]*H[2][i,j] + C.H[5][i,j]*(C.Km[1][i]*(E[3][i+1, j] - E[3][i, j]))
            @inbounds Hz[i,j] = C.H[3][i,j]*H[3][i,j] + C.H[6][i,j]*(C.Km[2][j]*(E[1][i, j+1] - E[1][i, j]) - C.Km[1][i]*(E[2][i+1, j] - E[2][i, j]))
        end
    end
    for h in (Hx,Hy,Hz) #apply dirichlet boundary conditions
        for i in 1:2
            selectdim(h, i, size(h,i)) .= zeros(T, perpsize(h,i)...)
            selectdim(h, i, 1) .= zeros(T, perpsize(h,i)...)
        end
    end
    for (i,h) in enumerate((Hx,Hy,Hz)) #truncating the grid for the overhanging components
        for j in setdiff(1:2, i)
            selectdim(h, j, size(h,j)-1) .= zeros(T, perpsize(h,j)...)
        end
    end
    return (Hx, Hy, Hz)
end

function update_E(E::VecArray{T,2}, H::VecArray{T,2}, C::Coefficients{T,2}) where T
    s = size(E[1])
    Ex = zeros(T, size(H[1]))
    Ey = zeros(T, size(H[2]))
    Ez = zeros(T, size(H[3]))
    Threads.@threads for j in 2:s[2]
        for i in 2:s[1]
            @inbounds Ex[i,j] = C.E[1][i,j]*E[1][i,j] + C.E[4][i,j]*(C.Ke[2][j]*(H[3][i,j] - H[3][i,j-1]))
            @inbounds Ey[i,j] = C.E[2][i,j]*E[2][i,j] + C.E[5][i,j]*(-C.Ke[1][i]*(H[3][i, j] - H[3][i-1, j]))
            @inbounds Ez[i,j] = C.E[3][i,j]*E[3][i,j] + C.E[6][i,j]*(C.Ke[1][i]*(H[2][i,j] - H[2][i-1,j]) - C.Ke[2][j]*(H[1][i, j] - H[1][i, j-1]))
        end
    end
    for e in (Ex,Ey,Ez) #apply dirichlet boundary conditions
        for i in 1:2
            selectdim(e, i, 1) .= zeros(T, perpsize(e,i)...)
            selectdim(e, i, size(e,i)) .= zeros(T, perpsize(e,i)...)
        end
    end
    for (i,e) in enumerate((Ex,Ey))
        selectdim(e, i, size(e,i)-1) .= zeros(T, perpsize(e,i)...)
    end
    return (Ex, Ey, Ez)
end

################################################################################
# Update equations in 3D
################################################################################

function update_H(E::VecArray{T,3}, H::VecArray{T,3}, C::Coefficients{T,3}) where T
    s = size(H[1])
    Hx = zeros(T, size(H[1]))
    Hy = zeros(T, size(H[2]))
    Hz = zeros(T, size(H[3]))

    Threads.@threads for k in 1:(s[3]-1)
        for j in 1:(s[2]-1), i in 1:(s[1]-1)
        @inbounds Hx[i,j,k] = C.H[1][i,j,k]*H[1][i,j,k] + C.H[4][i,j,k]*(C.Km[3][k]*(E[2][i, j, k+1] - E[2][i, j, k]) - C.Km[2][j]*(E[3][i, j+1, k] - E[3][i, j, k]))
        @inbounds Hy[i,j,k] = C.H[2][i,j,k]*H[2][i,j,k] + C.H[5][i,j,k]*(C.Km[1][i]*(E[3][i+1, j, k] - E[3][i, j, k]) - C.Km[3][k]*(E[1][i, j, k+1] - E[1][i, j, k]))
        @inbounds Hz[i,j,k] = C.H[3][i,j,k]*H[3][i,j,k] + C.H[6][i,j,k]*(C.Km[2][j]*(E[1][i, j+1, k] - E[1][i, j, k]) - C.Km[1][i]*(E[2][i+1, j, k] - E[2][i, j, k]))
    end
    for h in (Hx,Hy,Hz) #apply dirichlet0 boundary conditions
        for i in 1:3
            selectdim(h, i, size(h,i)) .= zeros(T, perpsize(h,i)...)
            selectdim(h, i, 1) .= zeros(T, perpsize(h,i)...)
        end
    end
    for (i,h) in enumerate((Hx,Hy,Hz)) #truncating the grid for the overhanging components - implemented this way for simplicity
        for j in setdiff(1:3, i)
            selectdim(h, j, size(h,j)-1) .= zeros(T, perpsize(h,j)...)
        end
    end
    return (Hx, Hy, Hz)
end

function update_E(E::VecArray{T,3}, H::VecArray{T,3}, C::Coefficients{T,3}) where T
    s = size(E[1])
    Ex = zeros(T, size(H[1]))
    Ey = zeros(T, size(H[2]))
    Ez = zeros(T, size(H[3]))
    Threads.@threads for k in 2:s[3],
        for j in 2:s[2], i in 2:s[1]
        @inbounds Ex[i,j,k] = C.E[1][i,j,k]*E[1][i,j,k] + C.E[4][i,j,k]*(C.Ke[2][j]*(H[3][i,j,k] - H[3][i,j-1,k]) - C.Ke[3][k]*(H[2][i, j, k] - H[2][i, j, k-1]))
        @inbounds Ey[i,j,k] = C.E[2][i,j,k]*E[2][i,j,k] + C.E[5][i,j,k]*(C.Ke[3][k]*(H[1][i,j,k] - H[1][i,j,k-1]) - C.Ke[1][i]*(H[3][i, j, k] - H[3][i-1, j, k]))
        @inbounds Ez[i,j,k] = C.E[3][i,j,k]*E[3][i,j,k] + C.E[6][i,j,k]*(C.Ke[1][i]*(H[2][i,j,k] - H[2][i-1,j,k]) - C.Ke[2][j]*(H[1][i, j, k] - H[1][i, j-1, k]))
    end
    for e in (Ex,Ey,Ez) #apply dirichlet0 boundary conditions
        for i in 1:3
            selectdim(e, i, 1) .= zeros(T, perpsize(e,i)...)
            selectdim(e, i, size(e,i)) .= zeros(T, perpsize(e,i)...)
        end
    end
    for (i,e) in enumerate((Ex,Ey,Ez))
        selectdim(e, i, size(e,i)-1) .= zeros(T, perpsize(e,i)...)
    end
    return (Ex, Ey, Ez)
end


text:
#
# @description Defines the Cryptography.Padders module.
#
# @author Alejandro Claro (alejandro.claro@gmail.com)
#
# Copyright 2015 All rights reserved.
# Use of this source code is governed by a MIT-style license that can be found in the LICENSE file.
#
export PaddingMethod, PaddingError

# @description Defines the padding method abstract type.
abstract type PaddingMethod end

# @description Defines general padding error exception type.
struct PaddingError <: Exception end

include("Padders/ansix923_padder.jl")
include("Padders/pkcs7_padder.jl")


text:
# This file was generated by the Julia Swagger Code Generator
# Do not modify this file directly. Modify the swagger specification instead.

struct SchedulingV1alpha1Api <: SwaggerApi
    client::Swagger.Client
end

"""

create a PriorityClass
Param: body::IoK8sApiSchedulingV1alpha1PriorityClass (required)
Param: pretty::String
Param: dryRun::String
Param: fieldManager::String
Return: IoK8sApiSchedulingV1alpha1PriorityClass
"""
function createSchedulingV1alpha1PriorityClass(_api::SchedulingV1alpha1Api, body; pretty=nothing, dryRun=nothing, fieldManager=nothing, _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "POST", IoK8sApiSchedulingV1alpha1PriorityClass, "/apis/scheduling.k8s.io/v1alpha1/priorityclasses", ["BearerToken"], body)
    Swagger.set_param(_ctx.query, "pretty", pretty)  # type String
    Swagger.set_param(_ctx.query, "dryRun", dryRun)  # type String
    Swagger.set_param(_ctx.query, "fieldManager", fieldManager)  # type String
    Swagger.set_header_accept(_ctx, ["application/json", "application/yaml", "application/vnd.kubernetes.protobuf"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["*/*"] : [_mediaType])
    Swagger.exec(_ctx)
end

"""

delete collection of PriorityClass
Param: pretty::String
Param: allowWatchBookmarks::Bool
Param: body::IoK8sApimachineryPkgApisMetaV1DeleteOptions
Param: __continue__::String
Param: dryRun::String
Param: fieldSelector::String
Param: gracePeriodSeconds::Int32
Param: labelSelector::String
Param: limit::Int32
Param: orphanDependents::Bool
Param: propagationPolicy::String
Param: resourceVersion::String
Param: timeoutSeconds::Int32
Param: watch::Bool
Return: IoK8sApimachineryPkgApisMetaV1Status
"""
function deleteSchedulingV1alpha1CollectionPriorityClass(_api::SchedulingV1alpha1Api; pretty=nothing, allowWatchBookmarks=nothing, body=nothing, __continue__=nothing, dryRun=nothing, fieldSelector=nothing, gracePeriodSeconds=nothing, labelSelector=nothing, limit=nothing, orphanDependents=nothing, propagationPolicy=nothing, resourceVersion=nothing, timeoutSeconds=nothing, watch=nothing, _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "DELETE", IoK8sApimachineryPkgApisMetaV1Status, "/apis/scheduling.k8s.io/v1alpha1/priorityclasses", ["BearerToken"], body)
    Swagger.set_param(_ctx.query, "pretty", pretty)  # type String
    Swagger.set_param(_ctx.query, "allowWatchBookmarks", allowWatchBookmarks)  # type Bool
    Swagger.set_param(_ctx.query, "continue", __continue__)  # type String
    Swagger.set_param(_ctx.query, "dryRun", dryRun)  # type String
    Swagger.set_param(_ctx.query, "fieldSelector", fieldSelector)  # type String
    Swagger.set_param(_ctx.query, "gracePeriodSeconds", gracePeriodSeconds)  # type Int32
    Swagger.set_param(_ctx.query, "labelSelector", labelSelector)  # type String
    Swagger.set_param(_ctx.query, "limit", limit)  # type Int32
    Swagger.set_param(_ctx.query, "orphanDependents", orphanDependents)  # type Bool
    Swagger.set_param(_ctx.query, "propagationPolicy", propagationPolicy)  # type String
    Swagger.set_param(_ctx.query, "resourceVersion", resourceVersion)  # type String
    Swagger.set_param(_ctx.query, "timeoutSeconds", timeoutSeconds)  # type Int32
    Swagger.set_param(_ctx.query, "watch", watch)  # type Bool
    Swagger.set_header_accept(_ctx, ["application/json", "application/yaml", "application/vnd.kubernetes.protobuf"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["*/*"] : [_mediaType])
    Swagger.exec(_ctx)
end

"""

delete a PriorityClass
Param: name::String (required)
Param: pretty::String
Param: body::IoK8sApimachineryPkgApisMetaV1DeleteOptions
Param: dryRun::String
Param: gracePeriodSeconds::Int32
Param: orphanDependents::Bool
Param: propagationPolicy::String
Return: IoK8sApimachineryPkgApisMetaV1Status
"""
function deleteSchedulingV1alpha1PriorityClass(_api::SchedulingV1alpha1Api, name::String; pretty=nothing, body=nothing, dryRun=nothing, gracePeriodSeconds=nothing, orphanDependents=nothing, propagationPolicy=nothing, _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "DELETE", IoK8sApimachineryPkgApisMetaV1Status, "/apis/scheduling.k8s.io/v1alpha1/priorityclasses/{name}", ["BearerToken"], body)
    Swagger.set_param(_ctx.path, "name", name)  # type String
    Swagger.set_param(_ctx.query, "pretty", pretty)  # type String
    Swagger.set_param(_ctx.query, "dryRun", dryRun)  # type String
    Swagger.set_param(_ctx.query, "gracePeriodSeconds", gracePeriodSeconds)  # type Int32
    Swagger.set_param(_ctx.query, "orphanDependents", orphanDependents)  # type Bool
    Swagger.set_param(_ctx.query, "propagationPolicy", propagationPolicy)  # type String
    Swagger.set_header_accept(_ctx, ["application/json", "application/yaml", "application/vnd.kubernetes.protobuf"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["*/*"] : [_mediaType])
    Swagger.exec(_ctx)
end

"""

get available resources
Return: IoK8sApimachineryPkgApisMetaV1APIResourceList
"""
function getSchedulingV1alpha1APIResources(_api::SchedulingV1alpha1Api; _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "GET", IoK8sApimachineryPkgApisMetaV1APIResourceList, "/apis/scheduling.k8s.io/v1alpha1/", ["BearerToken"])
    Swagger.set_header_accept(_ctx, ["application/json", "application/yaml", "application/vnd.kubernetes.protobuf"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["application/json", "application/yaml", "application/vnd.kubernetes.protobuf"] : [_mediaType])
    Swagger.exec(_ctx)
end

"""

list or watch objects of kind PriorityClass
Param: pretty::String
Param: allowWatchBookmarks::Bool
Param: __continue__::String
Param: fieldSelector::String
Param: labelSelector::String
Param: limit::Int32
Param: resourceVersion::String
Param: timeoutSeconds::Int32
Param: watch::Bool
Return: IoK8sApiSchedulingV1alpha1PriorityClassList
"""
function listSchedulingV1alpha1PriorityClass(_api::SchedulingV1alpha1Api; pretty=nothing, allowWatchBookmarks=nothing, __continue__=nothing, fieldSelector=nothing, labelSelector=nothing, limit=nothing, resourceVersion=nothing, timeoutSeconds=nothing, watch=nothing, _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "GET", IoK8sApiSchedulingV1alpha1PriorityClassList, "/apis/scheduling.k8s.io/v1alpha1/priorityclasses", ["BearerToken"])
    Swagger.set_param(_ctx.query, "pretty", pretty)  # type String
    Swagger.set_param(_ctx.query, "allowWatchBookmarks", allowWatchBookmarks)  # type Bool
    Swagger.set_param(_ctx.query, "continue", __continue__)  # type String
    Swagger.set_param(_ctx.query, "fieldSelector", fieldSelector)  # type String
    Swagger.set_param(_ctx.query, "labelSelector", labelSelector)  # type String
    Swagger.set_param(_ctx.query, "limit", limit)  # type Int32
    Swagger.set_param(_ctx.query, "resourceVersion", resourceVersion)  # type String
    Swagger.set_param(_ctx.query, "timeoutSeconds", timeoutSeconds)  # type Int32
    Swagger.set_param(_ctx.query, "watch", watch)  # type Bool
    Swagger.set_header_accept(_ctx, ["application/json", "application/yaml", "application/vnd.kubernetes.protobuf", "application/json;stream=watch", "application/vnd.kubernetes.protobuf;stream=watch"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["*/*"] : [_mediaType])
    Swagger.exec(_ctx)
end

"""

partially update the specified PriorityClass
Param: name::String (required)
Param: body::IoK8sApimachineryPkgApisMetaV1Patch (required)
Param: pretty::String
Param: dryRun::String
Param: fieldManager::String
Param: force::Bool
Return: IoK8sApiSchedulingV1alpha1PriorityClass
"""
function patchSchedulingV1alpha1PriorityClass(_api::SchedulingV1alpha1Api, name::String, body; pretty=nothing, dryRun=nothing, fieldManager=nothing, force=nothing, _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "PATCH", IoK8sApiSchedulingV1alpha1PriorityClass, "/apis/scheduling.k8s.io/v1alpha1/priorityclasses/{name}", ["BearerToken"], body)
    Swagger.set_param(_ctx.path, "name", name)  # type String
    Swagger.set_param(_ctx.query, "pretty", pretty)  # type String
    Swagger.set_param(_ctx.query, "dryRun", dryRun)  # type String
    Swagger.set_param(_ctx.query, "fieldManager", fieldManager)  # type String
    Swagger.set_param(_ctx.query, "force", force)  # type Bool
    Swagger.set_header_accept(_ctx, ["application/json", "application/yaml", "application/vnd.kubernetes.protobuf"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["application/json-patch+json", "application/merge-patch+json", "application/strategic-merge-patch+json", "application/apply-patch+yaml"] : [_mediaType])
    Swagger.exec(_ctx)
end

"""

read the specified PriorityClass
Param: name::String (required)
Param: pretty::String
Param: exact::Bool
Param: __export__::Bool
Return: IoK8sApiSchedulingV1alpha1PriorityClass
"""
function readSchedulingV1alpha1PriorityClass(_api::SchedulingV1alpha1Api, name::String; pretty=nothing, exact=nothing, __export__=nothing, _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "GET", IoK8sApiSchedulingV1alpha1PriorityClass, "/apis/scheduling.k8s.io/v1alpha1/priorityclasses/{name}", ["BearerToken"])
    Swagger.set_param(_ctx.path, "name", name)  # type String
    Swagger.set_param(_ctx.query, "pretty", pretty)  # type String
    Swagger.set_param(_ctx.query, "exact", exact)  # type Bool
    Swagger.set_param(_ctx.query, "export", __export__)  # type Bool
    Swagger.set_header_accept(_ctx, ["application/json", "application/yaml", "application/vnd.kubernetes.protobuf"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["*/*"] : [_mediaType])
    Swagger.exec(_ctx)
end

"""

replace the specified PriorityClass
Param: name::String (required)
Param: body::IoK8sApiSchedulingV1alpha1PriorityClass (required)
Param: pretty::String
Param: dryRun::String
Param: fieldManager::String
Return: IoK8sApiSchedulingV1alpha1PriorityClass
"""
function replaceSchedulingV1alpha1PriorityClass(_api::SchedulingV1alpha1Api, name::String, body; pretty=nothing, dryRun=nothing, fieldManager=nothing, _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "PUT", IoK8sApiSchedulingV1alpha1PriorityClass, "/apis/scheduling.k8s.io/v1alpha1/priorityclasses/{name}", ["BearerToken"], body)
    Swagger.set_param(_ctx.path, "name", name)  # type String
    Swagger.set_param(_ctx.query, "pretty", pretty)  # type String
    Swagger.set_param(_ctx.query, "dryRun", dryRun)  # type String
    Swagger.set_param(_ctx.query, "fieldManager", fieldManager)  # type String
    Swagger.set_header_accept(_ctx, ["application/json", "application/yaml", "application/vnd.kubernetes.protobuf"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["*/*"] : [_mediaType])
    Swagger.exec(_ctx)
end

"""

watch changes to an object of kind PriorityClass. deprecated: use the 'watch' parameter with a list operation instead, filtered to a single item with the 'fieldSelector' parameter.
Param: name::String (required)
Param: allowWatchBookmarks::Bool
Param: __continue__::String
Param: fieldSelector::String
Param: labelSelector::String
Param: limit::Int32
Param: pretty::String
Param: resourceVersion::String
Param: timeoutSeconds::Int32
Param: watch::Bool
Return: IoK8sApimachineryPkgApisMetaV1WatchEvent
"""
function watchSchedulingV1alpha1PriorityClass(_api::SchedulingV1alpha1Api, name::String; allowWatchBookmarks=nothing, __continue__=nothing, fieldSelector=nothing, labelSelector=nothing, limit=nothing, pretty=nothing, resourceVersion=nothing, timeoutSeconds=nothing, watch=nothing, _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "GET", IoK8sApimachineryPkgApisMetaV1WatchEvent, "/apis/scheduling.k8s.io/v1alpha1/watch/priorityclasses/{name}", ["BearerToken"])
    Swagger.set_param(_ctx.path, "name", name)  # type String
    Swagger.set_param(_ctx.query, "allowWatchBookmarks", allowWatchBookmarks)  # type Bool
    Swagger.set_param(_ctx.query, "continue", __continue__)  # type String
    Swagger.set_param(_ctx.query, "fieldSelector", fieldSelector)  # type String
    Swagger.set_param(_ctx.query, "labelSelector", labelSelector)  # type String
    Swagger.set_param(_ctx.query, "limit", limit)  # type Int32
    Swagger.set_param(_ctx.query, "pretty", pretty)  # type String
    Swagger.set_param(_ctx.query, "resourceVersion", resourceVersion)  # type String
    Swagger.set_param(_ctx.query, "timeoutSeconds", timeoutSeconds)  # type Int32
    Swagger.set_param(_ctx.query, "watch", watch)  # type Bool
    Swagger.set_header_accept(_ctx, ["application/json", "application/yaml", "application/vnd.kubernetes.protobuf", "application/json;stream=watch", "application/vnd.kubernetes.protobuf;stream=watch"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["*/*"] : [_mediaType])
    Swagger.exec(_ctx)
end

"""

watch individual changes to a list of PriorityClass. deprecated: use the 'watch' parameter with a list operation instead.
Param: allowWatchBookmarks::Bool
Param: __continue__::String
Param: fieldSelector::String
Param: labelSelector::String
Param: limit::Int32
Param: pretty::String
Param: resourceVersion::String
Param: timeoutSeconds::Int32
Param: watch::Bool
Return: IoK8sApimachineryPkgApisMetaV1WatchEvent
"""
function watchSchedulingV1alpha1PriorityClassList(_api::SchedulingV1alpha1Api; allowWatchBookmarks=nothing, __continue__=nothing, fieldSelector=nothing, labelSelector=nothing, limit=nothing, pretty=nothing, resourceVersion=nothing, timeoutSeconds=nothing, watch=nothing, _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "GET", IoK8sApimachineryPkgApisMetaV1WatchEvent, "/apis/scheduling.k8s.io/v1alpha1/watch/priorityclasses", ["BearerToken"])
    Swagger.set_param(_ctx.query, "allowWatchBookmarks", allowWatchBookmarks)  # type Bool
    Swagger.set_param(_ctx.query, "continue", __continue__)  # type String
    Swagger.set_param(_ctx.query, "fieldSelector", fieldSelector)  # type String
    Swagger.set_param(_ctx.query, "labelSelector", labelSelector)  # type String
    Swagger.set_param(_ctx.query, "limit", limit)  # type Int32
    Swagger.set_param(_ctx.query, "pretty", pretty)  # type String
    Swagger.set_param(_ctx.query, "resourceVersion", resourceVersion)  # type String
    Swagger.set_param(_ctx.query, "timeoutSeconds", timeoutSeconds)  # type Int32
    Swagger.set_param(_ctx.query, "watch", watch)  # type Bool
    Swagger.set_header_accept(_ctx, ["application/json", "application/yaml", "application/vnd.kubernetes.protobuf", "application/json;stream=watch", "application/vnd.kubernetes.protobuf;stream=watch"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["*/*"] : [_mediaType])
    Swagger.exec(_ctx)
end

export createSchedulingV1alpha1PriorityClass, deleteSchedulingV1alpha1CollectionPriorityClass, deleteSchedulingV1alpha1PriorityClass, getSchedulingV1alpha1APIResources, listSchedulingV1alpha1PriorityClass, patchSchedulingV1alpha1PriorityClass, readSchedulingV1alpha1PriorityClass, replaceSchedulingV1alpha1PriorityClass, watchSchedulingV1alpha1PriorityClass, watchSchedulingV1alpha1PriorityClassList


text:
using GeoJSON, FactCheck, Compat

include(joinpath(dirname(@__FILE__),"geojson_samples.jl"))

feature = GeoJSON.parse(a)
@fact typeof(feature) --> Feature
@fact GeoJSON.geometry(feature) --> nothing
@fact GeoJSON.properties(feature) --> feature.properties
@fact typeof(feature.properties) --> Dict{AbstractString,Any}
@fact length(feature.properties) --> 1
@fact GeoJSON.hasbbox(feature) --> false
@fact GeoJSON.hascrs(feature) --> true
@fact GeoJSON.crs(feature) --> feature.crs
@fact feature.crs["properties"]["href"] --> "data.crs"
@fact feature.crs["properties"]["type"] --> "ogcwkt"
@fact feature.crs["type"] --> "link"
@fact "Ã" in keys(feature.properties) --> true
@fact feature.properties["Ã"] --> "Ã"
dict = GeoJSON.geojson2dict(feature)
@fact dict["geometry"] --> nothing
@fact dict["type"] --> "Feature"
@fact dict["crs"]["properties"]["href"] --> "data.crs"
@fact dict["crs"]["properties"]["type"] --> "ogcwkt"
@fact dict["crs"]["type"] --> "link"
@fact dict["properties"]["Ã"] --> "Ã"

feature = GeoJSON.parse(b)
@fact typeof(feature) --> Feature
@fact typeof(GeoJSON.geometry(feature)) --> MultiPoint
coords = GeoJSON.coordinates(GeoJSON.geometry(feature))
@fact string(GeoJSON.coordinates(GeoJSON.geometry(feature))) --> "[[-155.52,19.61],[-156.22,20.74],[-157.97,21.46]]"
@fact GeoJSON.properties(feature) --> feature.properties
@fact typeof(feature.properties) --> Dict{AbstractString,Any}
@fact length(feature.properties) --> 1
@fact GeoJSON.hasbbox(feature) --> false
@fact GeoJSON.hascrs(feature) --> false
@fact "Ã" in keys(feature.properties) --> false
@fact feature.properties["type"] --> "é"
@fact GeoJSON.hasid(feature) --> true
@fact GeoJSON.id(feature) --> feature.id
@fact feature.id --> 1

feature = GeoJSON.parse(c)
@fact typeof(feature) --> Feature
@fact GeoJSON.geometry(feature) --> nothing
@fact GeoJSON.properties(feature) --> feature.properties
@fact typeof(feature.properties) --> Dict{AbstractString,Any}
@fact length(feature.properties) --> 1
@fact feature.properties["type"] --> "meow"
@fact GeoJSON.hasbbox(feature) --> false
@fact GeoJSON.hascrs(feature) --> true
@fact GeoJSON.crs(feature) --> feature.crs
@fact typeof(feature.crs) --> Dict{AbstractString,Any}
@fact feature.crs["type"] --> "name"
@fact feature.crs["properties"]["name"] --> "urn:ogc:def:crs:EPSG::3785"
@fact GeoJSON.hasid(feature) --> true
@fact GeoJSON.id(feature) --> feature.id
@fact feature.id --> 1
dict = GeoJSON.geojson2dict(feature)
@fact dict["geometry"] --> nothing
@fact dict["id"] --> 1
@fact dict["type"] --> "Feature"
@fact dict["crs"]["properties"]["name"] --> "urn:ogc:def:crs:EPSG::3785"
@fact dict["crs"]["type"] --> "name"

feature = GeoJSON.parse(d)
@fact typeof(feature) --> Feature
@fact typeof(GeoJSON.geometry(feature)) --> MultiLineString
@fact GeoJSON.geometry(feature) --> feature.geometry
@fact string(feature.geometry.coordinates) --> "[[[3.75,9.25],[-130.95,1.52]],[[23.15,-34.25],[-1.35,-4.65],[3.45,77.95]]]"
@fact GeoJSON.hasbbox(feature.geometry) --> false
@fact GeoJSON.hascrs(feature.geometry) --> false
@fact GeoJSON.properties(feature) --> feature.properties
@fact typeof(feature.properties) --> Dict{AbstractString,Any}
@fact length(feature.properties) --> 1
@fact feature.properties["title"] --> "Dict 1"
@fact GeoJSON.hasbbox(feature) --> true
@fact GeoJSON.bbox(feature) --> feature.bbox
@fact GeoJSON.bbox(feature) --> roughly([-180.0, -90.0, 180.0, 90.0])
@fact GeoJSON.hascrs(feature) --> false
@fact GeoJSON.hasid(feature) --> true
@fact GeoJSON.id(feature) --> feature.id
@fact feature.id --> "1"

feature = GeoJSON.parse(e)
@fact typeof(feature) --> Feature
@fact typeof(GeoJSON.geometry(feature)) --> Point
@fact GeoJSON.geometry(feature) --> feature.geometry
@fact feature.geometry.coordinates --> [53, -4]
@fact GeoJSON.hasbbox(feature.geometry) --> false
@fact GeoJSON.hascrs(feature.geometry) --> true
@fact GeoJSON.crs(feature.geometry) --> feature.geometry.crs
@fact feature.geometry.crs["properties"]["href"] --> "http://example.com/crs/42"
@fact GeoJSON.crs(feature.geometry)["properties"]["type"] --> "proj4"
@fact feature.geometry.crs["type"] --> "link"
@fact GeoJSON.properties(feature) --> feature.properties
@fact typeof(feature.properties) --> Dict{AbstractString,Any}
@fact length(feature.properties) --> 3
@fact feature.properties["title"] --> "Feature 1"
@fact feature.properties["summary"] --> "The first feature"
@fact feature.properties["link"] --> "http://example.org/features/1"
@fact GeoJSON.hasbbox(feature) --> false
@fact GeoJSON.hascrs(feature) --> false
dict = GeoJSON.geojson2dict(feature)
@fact dict["geometry"]["coordinates"] --> roughly([53.0,-4.0])
@fact dict["geometry"]["type"] --> "Point"
@fact dict["geometry"]["crs"]["properties"]["href"] --> "http://example.com/crs/42"
@fact dict["id"] --> "1"
@fact dict["type"] --> "Feature"

feature = GeoJSON.parse(f)
@fact typeof(feature) --> Feature
@fact GeoJSON.geometry(feature) --> nothing
@fact GeoJSON.properties(feature) --> feature.properties
@fact typeof(feature.properties) --> Dict{AbstractString,Any}
@fact length(feature.properties) --> 1
@fact feature.properties["foo"] --> "bar"
@fact GeoJSON.hasbbox(feature) --> false
@fact GeoJSON.hascrs(feature) --> false

testobj = GeoJSON.parse(multipolygon)
@fact typeof(testobj) --> FeatureCollection
@fact GeoJSON.hasbbox(testobj) --> false
@fact GeoJSON.hascrs(testobj) --> false
features = GeoJSON.features(testobj)
@fact length(features) --> 1
feature = features[1]
@fact GeoJSON.hasid(feature) --> false
@fact GeoJSON.hasbbox(feature) --> true
@fact GeoJSON.bbox(feature) --> feature.bbox
@fact GeoJSON.bbox(feature) --> roughly([100.0, 0.0, 105.0, 1.0])
@fact GeoJSON.hascrs(feature) --> false
@fact typeof(GeoJSON.geometry(feature)) --> MultiPolygon
@fact GeoJSON.geometry(feature) --> feature.geometry
@fact GeoJSON.hasbbox(feature.geometry) --> false
@fact GeoJSON.hascrs(feature.geometry) --> false
@fact size(feature.geometry.coordinates) --> (1,)
@fact length(feature.geometry.coordinates) --> 1
@fact length(feature.geometry.coordinates[1]) --> 1
@fact length(feature.geometry.coordinates[1][1]) --> 4
@fact feature.geometry.coordinates[1][1][1] -->
    roughly([-117.914, 33.9666])
@fact feature.geometry.coordinates[1][1][2] -->
    roughly([-117.908,33.9677])
@fact feature.geometry.coordinates[1][1][3] -->
    roughly([-117.913,33.9644])
@fact feature.geometry.coordinates[1][1][4] -->
    feature.geometry.coordinates[1][1][4]
@fact feature.properties["addr2"] --> "Rowland Heights"
@fact feature.properties["cartodb_id"] --> 46
@fact feature.properties["addr1"] --> "18150 E. Pathfinder Rd."
@fact feature.properties["park"] --> "Pathfinder Park"

testobj = GeoJSON.parse(realmultipolygon)
@fact typeof(testobj) --> FeatureCollection
@fact GeoJSON.hasbbox(testobj) --> false
@fact GeoJSON.hascrs(testobj) --> false
features = GeoJSON.features(testobj)
@fact length(features) --> 1
feature = features[1]
@fact GeoJSON.hasid(feature) --> false
@fact GeoJSON.hasbbox(feature) --> false
@fact GeoJSON.hascrs(feature) --> false
@fact typeof(GeoJSON.geometry(feature)) --> MultiPolygon
@fact GeoJSON.geometry(feature) --> feature.geometry
@fact GeoJSON.hasbbox(feature.geometry) --> false
@fact GeoJSON.hascrs(feature.geometry) --> false
@fact size(feature.geometry.coordinates) --> (2,)
@fact string(feature.geometry.coordinates) --> "[[[[102.0,2.0],[103.0,2.0],[103.0,3.0],[102.0,3.0],[102.0,2.0]]],[[[100.0,0.0],[101.0,0.0],[101.0,1.0],[100.0,1.0],[100.0,0.0]],[[100.2,0.2],[100.8,0.2],[100.8,0.8],[100.2,0.8],[100.2,0.2]]]]"
dict = GeoJSON.geojson2dict(testobj)
@fact dict["type"] --> "FeatureCollection"
@fact dict["features"][1]["geometry"]["type"] --> "MultiPolygon"
dict = GeoJSON.geojson2dict(feature)
@fact dict["type"] --> "Feature"
@fact length(dict["geometry"]["coordinates"]) --> 2

testobj = GeoJSON.parse(polyline)
@fact typeof(testobj) --> FeatureCollection
@fact GeoJSON.hasbbox(testobj) --> false
@fact GeoJSON.hascrs(testobj) --> false
features = GeoJSON.features(testobj)
@fact length(features) --> 1
feature = features[1]
@fact typeof(feature.geometry) --> LineString
@fact feature.properties["InLine_FID"] --> 0
@fact feature.properties["SimLnFLag"] --> 0
@fact string(feature.geometry.coordinates) --> "[[-89.0,43.0],[-88.0,44.0],[-88.0,45.0]]"
dict = GeoJSON.geojson2dict(testobj)
@fact dict["type"] --> "FeatureCollection"
@fact dict["features"][1]["geometry"]["type"] --> "LineString"
dict = GeoJSON.geojson2dict(feature)
@fact dict["type"] --> "Feature"
@fact dict["id"] --> "a73ws67n775q"
@fact length(dict["geometry"]["coordinates"]) --> 3

testobj = GeoJSON.parse(point)
@fact typeof(testobj) --> FeatureCollection
feature = testobj.features[1]
@fact feature.properties["fax"] --> "305-571-8347"
@fact feature.properties["phone"] --> "305-571-8345"
@fact typeof(feature.geometry) --> Point
@fact feature.geometry.coordinates --> [-89.0, 44.0]
dict = GeoJSON.geojson2dict(testobj)
@fact dict["type"] --> "FeatureCollection"
@fact dict["features"][1]["geometry"]["type"] --> "Point"
dict = GeoJSON.geojson2dict(feature)
@fact dict["type"] --> "Feature"
@fact dict["id"] --> "a7vs0i9rnyyx"
@fact length(dict["geometry"]["coordinates"]) --> 2

testobj = GeoJSON.parse(pointnull)
@fact typeof(testobj) --> FeatureCollection
feature = testobj.features[1]
@fact GeoJSON.id(feature) --> feature.id
@fact feature.id --> "a7vs0i9rnyyx"
@fact feature.properties["fax"] --> "305-571-8347"
@fact feature.properties["phone"] --> "305-571-8345"
@fact typeof(feature.geometry) --> Void
dict = GeoJSON.geojson2dict(testobj)
@fact dict["type"] --> "FeatureCollection"
@fact dict["features"][1]["geometry"] --> "null"
dict = GeoJSON.geojson2dict(feature)
@fact dict["geometry"] --> "null"
@fact dict["id"] --> "a7vs0i9rnyyx"
@fact dict["type"] --> "Feature"

testobj = GeoJSON.parse(poly)
@fact typeof(testobj) --> FeatureCollection
feature = testobj.features[1]
@fact GeoJSON.id(feature) --> "a7ws7wldxold"
@fact feature.properties["DIST_NUM"] --> 7.0
@fact feature.properties["PHONE"] --> "686-3070"
@fact feature.properties["AREA_SQMI"] --> 12.41643
@fact feature.properties["LOCATION"]  --> "Bustleton Ave. & Bowler St"
@fact feature.properties["DIV_CODE"]  --> "NEPD"
@fact feature.properties["DIST_NUMC"] --> "07"
@fact typeof(feature.geometry) --> Polygon
@fact length(feature.geometry.coordinates) --> 1
@fact length(feature.geometry.coordinates[1]) --> 5
@fact feature.geometry.coordinates[1][1] -->
    feature.geometry.coordinates[1][end]
dict = GeoJSON.geojson2dict(testobj)
@fact dict["type"] --> "FeatureCollection"
@fact dict["features"][1] --> GeoJSON.geojson2dict(feature)
dict = GeoJSON.geojson2dict(feature)
@fact dict["geometry"]["type"] --> "Polygon"
@fact dict["id"] --> "a7ws7wldxold"
@fact dict["type"] --> "Feature"

testobj = GeoJSON.parse(polyhole)
@fact typeof(testobj) --> FeatureCollection
feature = testobj.features[1]
@fact feature.id --> "a7ws7wldxold"
@fact feature.properties["DIST_NUM"] --> 7.0
@fact feature.properties["PHONE"] --> "686-3070"
@fact feature.properties["AREA_SQMI"] --> 12.41643
@fact feature.properties["LOCATION"]  --> "Bustleton Ave. & Bowler St"
@fact feature.properties["DIV_CODE"]  --> "NEPD"
@fact feature.properties["DIST_NUMC"] --> "07"
@fact typeof(feature.geometry) --> Polygon
@fact length(feature.geometry.coordinates) --> 2
@fact length(feature.geometry.coordinates[1]) --> 5
@fact feature.geometry.coordinates[1][1] -->
    feature.geometry.coordinates[1][end]
@fact length(feature.geometry.coordinates[2]) --> 5
@fact feature.geometry.coordinates[2][1] -->
    feature.geometry.coordinates[2][end]
dict = GeoJSON.geojson2dict(testobj)
@fact dict["type"] --> "FeatureCollection"
@fact dict["features"][1] --> GeoJSON.geojson2dict(feature)
dict = GeoJSON.geojson2dict(feature)
@fact dict["geometry"]["type"] --> "Polygon"
@fact dict["id"] --> "a7ws7wldxold"
@fact dict["type"] --> "Feature"

testobj = GeoJSON.parse(collection)
@fact typeof(testobj) --> FeatureCollection
feature = testobj.features[1]
@fact feature.properties["STATE_ABBR"] --> "ZZ"
@fact feature.properties["STATE_NAME"] --> "Top"
@fact typeof(feature.geometry) --> GeometryCollection
@fact length(feature.geometry.geometries) --> 3
@fact typeof(feature.geometry.geometries[1]) --> Polygon
@fact typeof(feature.geometry.geometries[2]) --> Polygon
@fact typeof(feature.geometry.geometries[3]) --> Point
coords = feature.geometry.geometries[1].coordinates
@fact length(coords) --> 1
@fact length(coords[1]) --> 5
@fact coords[1][1] --> coords[1][end]
coords = feature.geometry.geometries[2].coordinates
@fact length(coords) --> 1
@fact length(coords[1]) --> 5
@fact coords[1][1] --> coords[1][end]
@fact feature.geometry.geometries[3].coordinates -->
    roughly([-94.0,46.0])
dict = GeoJSON.geojson2dict(testobj)
@fact dict["type"] --> "FeatureCollection"
@fact dict["features"][1] --> GeoJSON.geojson2dict(feature)
dict = GeoJSON.geojson2dict(feature)
@fact dict["geometry"]["type"] --> "GeometryCollection"
@fact length(dict["geometry"]["geometries"]) --> 3
@fact dict["geometry"]["geometries"][1]["type"] --> "Polygon"
@fact dict["geometry"]["geometries"][2]["type"] --> "Polygon"
@fact dict["geometry"]["geometries"][3]["type"] --> "Point"
@fact dict["id"] --> "a7xlmuwyjioy"
@fact dict["type"] --> "Feature"

buildings = GeoJSON.parse(osm_buildings)
@fact typeof(buildings) --> FeatureCollection
@fact GeoJSON.hasbbox(buildings) --> false
@fact GeoJSON.hascrs(buildings) --> false
@fact length(buildings.features) --> 4
@fact map(typeof,buildings.features) --> fill(Feature,4)

feature = buildings.features[1]
@fact typeof(feature) --> Feature
@fact typeof(GeoJSON.geometry(feature)) --> Polygon
@fact GeoJSON.properties(feature) --> feature.properties
@fact typeof(feature.properties) --> Dict{AbstractString,Any}
@fact length(feature.properties) --> 2
@fact feature.properties["height"] --> 150
@fact feature.properties["color"] --> "rgb(255,200,150)"
@fact GeoJSON.hasbbox(feature) --> false
@fact GeoJSON.hascrs(feature) --> false

building_dict = GeoJSON.geojson2dict(buildings)
@fact typeof(building_dict) --> Dict{AbstractString,Any}
@fact string(GeoJSON.parse(osm_buildings)) --> string(GeoJSON.dict2geojson(building_dict))

@fact GeoJSON.geojson(buildings) -->
"""{\"features\":[{\"geometry\":{\"coordinates\":[[[13.42634,52.49533],[13.4266,52.49524],[13.42619,52.49483],[13.42583,52.49495],[13.4259,52.49501],[13.42611,52.49494],[13.4264,52.49525],[13.4263,52.49529],[13.42634,52.49533]]],\"type\":\"Polygon\"},\"properties\":{\"height\":150,\"color\":\"rgb(255,200,150)\"},\"type\":\"Feature\"},{\"geometry\":{\"coordinates\":[[[13.42706,52.49535],[13.42745,52.4952],[13.42745,52.4952],[13.42741,52.49516],[13.42717,52.49525],[13.42692,52.49501],[13.42714,52.49494],[13.42686,52.49466],[13.4265,52.49478],[13.42657,52.49486],[13.42678,52.4948],[13.42694,52.49496],[13.42675,52.49503],[13.42706,52.49535]]],\"type\":\"Polygon\"},\"properties\":{\"height\":130,\"color\":\"rgb(180,240,180)\"},\"type\":\"Feature\"},{\"geometry\":{\"coordinates\":[[[[13.42746,52.4944],[13.42794,52.49494],[13.42799,52.49492],[13.42755,52.49442],[13.42798,52.49428],[13.42846,52.4948],[13.42851,52.49478],[13.428,52.49422],[13.42746,52.4944]]],[[[13.42803,52.49497],[13.428,52.49493],[13.42844,52.49479],[13.42847,52.49483],[13.42803,52.49497]]]],\"type\":\"MultiPolygon\"},\"properties\":{\"height\":120,\"color\":\"rgb(200,200,250)\"},\"type\":\"Feature\"},{\"geometry\":{\"coordinates\":[[[13.42857,52.4948],[13.42918,52.49465],[13.42867,52.49412],[13.4285,52.49419],[13.42896,52.49465],[13.42882,52.49469],[13.42837,52.49423],[13.42821,52.49428],[13.42863,52.49473],[13.42853,52.49476],[13.42857,52.4948]]],\"type\":\"Polygon\"},\"properties\":{\"height\":140,\"color\":\"rgb(150,180,210)\"},\"type\":\"Feature\"}],\"type\":\"FeatureCollection\"}"""

@fact GeoJSON.geojson(buildings) --> JSON.json(JSON.parse(osm_buildings))
@fact building_dict --> JSON.parse(osm_buildings)

obj = GeoJSON.parsefile(joinpath(dirname(@__FILE__),"tech_square.geojson"))
@fact typeof(obj) --> FeatureCollection
@fact length(GeoJSON.features(obj)) --> 171
feature = obj.features[1]
@fact GeoJSON.hasbbox(feature) --> false
@fact GeoJSON.hascrs(feature) --> false
@fact GeoJSON.hasid(feature) --> true
@fact GeoJSON.id(feature) --> feature.id
@fact feature.id --> "relation/2119819"
@fact typeof(feature.geometry) --> Polygon
@fact length(feature.geometry.coordinates) --> 1
@fact length(feature.geometry.coordinates[1]) --> 38
@fact feature.geometry.coordinates[1][1] --> feature.geometry.coordinates[1][end]

# Tests added for PR #19
v = Vector{Float64}[]
push!(v, [1.0;2.0])
push!(v, [3.0;4.0])
ls = LineString(v)
f = Feature(ls)
fc = FeatureCollection(Feature[f])
gj = GeoJSON.geojson2dict(ls)
fj = GeoJSON.geojson2dict(f)
fcj = GeoJSON.geojson2dict(fc)
@fact gj["type"] --> "LineString"
@fact fj["type"] --> "Feature"
@fact fj["geometry"]["type"] --> "LineString"
@fact fcj["type"] --> "FeatureCollection"
@fact fcj["features"][1]["type"] --> "Feature"
@fact fcj["features"][1]["geometry"]["type"] --> "LineString"


text:
"""The standard 2x2 block matrix form with square diagonal blocks."""
type StandardBlockMatrix{T,TA<:AbMat,TB<:AbMat,TC<:AbMat,TD<:AbMat} <: AbstractBlockMatrix{T}
    A::TA
    B::TB
    C::TC
    D::TD

    function StandardBlockMatrix(A::AbMat,B::AbMat,C::AbMat,D::AbMat)
      sA,sB,sC,sD= map(size,Any[A,B,C,D])
      if sA[1]==sA[2] && sD[1]==sD[2]
        sA[1]==sB[2]==sC[1] && sD[1]==sB[1]==sC[2] ? new(A,B,C,D) : error("off-diagonal blocks must have compatible dimensions")
      else
        error("block diagonals must be square")
      end
    end
end
function StandardBlockMatrix(A::AbMat,B::AbMat,C::AbMat,D::AbMat)
    T = promote_type(map(eltype,(A,B,C,D))...)
    return StandardBlockMatrix{T,typeof(A),typeof(B),typeof(C),typeof(D)}(A,B,C,D)
end
StandardBlockMatrix(blocks::Matrix) = StandardBlockMatrix(blocks...)

"""Returns the four blocks in a 2x2 matrix"""
function blocks(M::StandardBlockMatrix)
    theblocks = Array{Any,2}(2,2)
    theblocks[1,1] = M.A
    theblocks[2,1] = M.B
    theblocks[1,2] = M.C
    theblocks[2,2] = M.D
    return theblocks
end

#needs to be moved into abstract
#function Base.getindex(M::StandardBlockMatrix,i,j)
#  mA,nA = size(M.A)
#  if     i<=mA && j<=nA
#      return M.A[i,j]
#  elseif i>mA  && j<=nA
#      return M.C[i-mA,j]
#  elseif i<=mA && j>nA
#      return M.B[i,j-nA]
#  else
#      return M.D[i-mA,j-nA]
#  end
#end


text:
using Test
import LinearAlgebra.norm
include("../src/SSSTensor.jl")

 n = 3
 ord = 5
 tol = 1e-9
 nnz = 4

function set_up(n,ord,nnz)
    x = rand(n)
    indices = rand(1:n,nnz,ord)
    for i = 1:nnz
        indices[i,:] = indices[i,sortperm(indices[i, :])]
    end
    vals = rand(nnz)
    x, indices, vals
end

@testset "Contraction Tests" begin

  @testset "COOTen contraction tests" begin
    x, indices, vals = set_up(n,ord,nnz)

    DICTen_A = ssten.SSSTensor([(indices[i,:],vals[i]) for i in 1:nnz],n)
    COOTen_A  = ssten.COOTen(indices,vals,n)

    DICTen_contract = ssten.contract(DICTen_A,x,ord-1)
    COOTen_contract  = ssten.contract_k_1(COOTen_A,x)

    println(DICTen_contract)
    println(COOTen_contract)

    @test norm(DICTen_contract - COOTen_contract)/norm(COOTen_contract) < tol

    COOTen_contract = zeros(n)
    ssten.contract_k_1!(indices,vals,x,COOTen_contract)

    @test norm(DICTen_contract - COOTen_contract)/norm(COOTen_contract)< tol
  end

  @testset "inner product tests" begin
    _, indices, vals = set_up(n,ord,nnz)
    indices = [1 2 3; 2 3 4; 1 3 4; 1 2 4; 2 3 5; 1 2 5]
    vals = [.5,2.3,3.2,3.2,4.3,4.3]

    COOTen_A  = ssten.COOTen(indices,vals)

    test_vals = copy(vals)
    test_vals = test_vals.^2
    test_vals .*= 6

    @test ssten.inner_product(COOTen_A ,COOTen_A) == sum(test_vals)

  end
  #=
  @testset "in place low mem contraction tests" begin
    x = rand(n)
    indices = rand(1:n,nnz,ord)
    for i =1:nnz
        indices[i,:] = indices[i,sortperm(indices[i, :])]
    end
    vals = rand(nnz)

    A = ssten.SSSTensor([(indices[i,:],vals[i]) for i in 1:nnz])

    dictTen_contract = ssten.contract(A,x,ord-1)
    matTen_contract = zeros(n)
    ssten.contract_k_1!(indices,vals,x,matTen_contract)

    @test norm(dictTen_contract - matTen_contract)/norm(matTen_contract)< tol
  end
  =#
end