text:
"Generate k-nearest neighborhood graph edges with distances"
function find_nn(X::AbstractMatrix{T}, k::Int=12) where T<:Real
    m, n = size(X)
    r = Array{T}(undef, (n, n))
    d = Array{T}(undef, k, n)
    e = Array{Int}(undef, k, n)

    mul!(r, transpose(X), X)
    sa2 = sum(X.^2, dims=1)

    @inbounds for j = 1 : n
        @inbounds for i = 1 : j-1
             r[i,j] = r[j,i]
        end
        r[j,j] = 0
        @inbounds for i = j+1 : n
            v = sa2[i] + sa2[j] - 2 * r[i,j]
            r[i,j] = isnan(v) ? NaN : sqrt(max(v, 0.))
        end
        e[:, j] = sortperm(r[:,j])[2:k+1]
        d[:, j] = r[e[:, j],j]
    end

    return (d, e)
end

function adjmat(D::AbstractMatrix{T}, E::AbstractMatrix{<:Integer}) where {T<:Real}
    @assert size(D) == size(E) "Distance and edge matrix must be of the same size"
    n = size(D, 2)
    W = spzeros(T, n, n)
    @inbounds for II in CartesianIndices(D)
        d  = D[II]
        ii = E[II]
        j = II[2]
        W[ii, j] = d
        W[j, ii] = d
    end
    return W
end

"Crate a graph with largest connected component of adjacency matrix `W`"
function largest_component(G)
    CC = connected_components(G)
    if length(CC) > 1
        @warn "Found $(length(CC)) connected components. Largest component is selected."
        C = CC[argmax(map(length, CC))]
        G = first(induced_subgraph(G, C))
    else
        C = first(CC)
    end
    return G, C
end

"Generate a swiss roll dataset"
function swiss_roll(n::Int = 1000, noise::Float64=0.05)
    t = (3 * pi / 2) * (1 .+ 2 * rand(n, 1))
    height = 30 * rand(n, 1)
    X = [t .* cos.(t) height t .* sin.(t)] + noise * randn(n, 3)
    labels = vec(rem.(sum([round.(Int, t / 2) round.(Int, height / 12)], dims=2), 2))
    return collect(transpose(X)), labels
end

"Perform spectral decomposition for Ax=λI"
function decompose(M::AbstractMatrix{<:Real}, d::Int)
    W = isa(M, AbstractSparseArray) ? Symmetric(Matrix(M)) : Symmetric(M)
    F = eigen!(W)
    idx = sortperm(F.values)[2:d+1]
    return F.values[idx], F.vectors[:,idx]
end

"Perform spectral decomposition for Ax=λB"
function decompose(A::AbstractMatrix{<:Real}, B::AbstractMatrix{<:Real}, d::Int)
    AA = isa(A, AbstractSparseArray) ? Symmetric(full(A)) : Symmetric(A)
    BB = isa(B, AbstractSparseArray) ? Symmetric(full(B)) : Symmetric(B)
    F = eigen(AA, BB)
    idx = sortperm(F.values)[2:d+1]
    return F.values[idx], F.vectors[:,idx]
end

function specDecompose(M::AbstractArray, tol::Real, dim::Int, use_naive::Bool)
    @info("Entering: specDecompose")
    n, _ = size(M)
    V = Matrix(qr(randn(n, dim+1))); _, Q, Λ = schur(Symmetric(V' * Matrix(M * V)))
    V[:] = V * Q; gap = diff(sort(Λ))[1]; itIdx = 0
    while true
        itIdx += 1
        V = Matrix(qr(M \ V).Q)
        ϵ₂, ϵComp, Λ[:] = _2infPert(M, V, gap=gap)
        @info("it: $(itIdx) - ϵ₂: $(ϵ₂) - ϵI: $(ϵComp)")
        if use_naive && (ϵ₂ ≤ tol * sqrt(n))
            break
        end
        (ϵComp ≤ tol) && break
    end
    idx = sortperm(Λ)[2:(dim+1)]
    return Λ[idx], V[:, idx]
end

"""
    2infPert(A, V; gap=1.0)

Compute the 2→∞ residual, substituting `V` for the true eigenvector
matrix. Return both residuals as well the current Ritz values.
"""
function _2infPert(A, V; gap=1.0)
    # Rayleigh-Ritz
    _, Q, D = schur(V' * Matrix(A * V)); V[:] = V * Q
    E = Matrix(A * V) - D' .* V
    # compute residuals
    ϵ₂    = opnorm(E)
    # ϵ₂    = first(svds(E, nsv=1, ritzvec=false)[1].S)
    ϵInf  = sqrt(maximum(sum(E.^2, dims=2)))
    ϵFac  = (ϵ₂ / gap)
    vv2E  = E - V * (V'E)
    nrm0  = sqrt(maximum(sum(V.^2, dims=2)))
    nrm1  = sqrt(maximum(sum(vv2E.^2, dims=2)))
    ϵComp = 8 * nrm0 * ϵFac^2 + 2 * (nrm1 / gap) * (1 + 2 * ϵFac)
    return ϵFac, min(ϵComp, ϵ₂), D
end


text:
# Copyright (c) 2017: Miles Lubin and contributors
# Copyright (c) 2017: Google Inc.
#
# Use of this source code is governed by an MIT-style license that can be found
# in the LICENSE.md file or at https://opensource.org/licenses/MIT.

function print_node(io::IO, b::LazyBridgeOptimizer, node::VariableNode)
    S, = b.variable_types[node.index]
    MOIU.print_with_acronym(
        io,
        "[$(node.index)] constrained variables in `$S` are",
    )
    return
end

function print_node(io::IO, b::LazyBridgeOptimizer, node::ConstraintNode)
    F, S = b.constraint_types[node.index]
    MOIU.print_with_acronym(io, "($(node.index)) `$F`-in-`$S` constraints are")
    return
end

function print_node(io::IO, b::LazyBridgeOptimizer, node::ObjectiveNode)
    F, = b.objective_types[node.index]
    MOIU.print_with_acronym(
        io,
        "|$(node.index)| objective function of type `$F` is",
    )
    return
end

function print_node_info(
    io::IO,
    b::LazyBridgeOptimizer,
    node::AbstractNode;
    debug_unsupported = false,
)
    print(io, " ")
    print_node(io, b, node)
    d = _dist(b.graph, node)
    if d == INFINITY
        print(io, " not supported")
        if debug_unsupported
            print(io, " because")
            print_unsupported(io, b, node)
        else
            println(io)
        end
    else
        index = bridge_index(b.graph, node)
        if iszero(index) ||
           (node isa VariableNode && !is_variable_edge_best(b.graph, node))
            @assert node isa VariableNode
            println(
                io,
                " supported (distance $d) by adding free variables and then constrain them, see ($(b.graph.variable_constraint_node[node.index].index)).",
            )
        else
            print(io, " bridged (distance $d) by ")
            MOIU.print_with_acronym(io, string(_bridge_type(b, node, index)))
            println(io, ".")
        end
    end
    return
end

function print_graph(b::LazyBridgeOptimizer; kwargs...)
    print_graph(Base.stdout, b; kwargs...)
    return
end

function print_graph(io::IO, b::LazyBridgeOptimizer; kwargs...)
    println(io, b.graph)
    print_nodes(
        io,
        b,
        variable_nodes(b.graph),
        constraint_nodes(b.graph),
        objective_nodes(b.graph);
        kwargs...,
    )
    return
end

function print_nodes(
    io::IO,
    b::LazyBridgeOptimizer,
    variable_nodes,
    constraint_nodes,
    objective_nodes;
    kwargs...,
)
    for node in variable_nodes
        print_node_info(io, b, node; kwargs...)
    end
    for node in constraint_nodes
        print_node_info(io, b, node; kwargs...)
    end
    for node in objective_nodes
        print_node_info(io, b, node; kwargs...)
    end
    return
end

function print_if_unsupported(
    io::IO,
    b::LazyBridgeOptimizer,
    node::AbstractNode,
)
    if _dist(b.graph, node) != INFINITY
        return
    end
    print(io, "   ")
    print_node(io, b, node)
    print(io, " not supported\n")
    return
end

function print_unsupported(io::IO, b::LazyBridgeOptimizer, edge::Edge)
    for node in edge.added_variables
        print_if_unsupported(io, b, node)
    end
    for node in edge.added_constraints
        print_if_unsupported(io, b, node)
    end
    return
end

function print_unsupported(io::IO, b::LazyBridgeOptimizer, edge::ObjectiveEdge)
    for node in edge.added_variables
        print_if_unsupported(io, b, node)
    end
    for node in edge.added_constraints
        print_if_unsupported(io, b, node)
    end
    print_if_unsupported(io, b, edge.added_objective)
    return
end

function print_unsupported(
    io::IO,
    b::LazyBridgeOptimizer,
    edges::Vector,
    index_to_bridge::Function,
)
    no_bridge = true
    for edge in edges
        if no_bridge
            println(io, ":")
            no_bridge = false
        end
        MOIU.print_with_acronym(
            io,
            "   Cannot use `$(index_to_bridge(edge.bridge_index))` because:\n",
        )
        print_unsupported(io, b, edge)
    end
    if no_bridge
        println(io, " no added bridge supports bridging it.")
    end
    return
end

function _bridge_type(
    b::LazyBridgeOptimizer,
    node::VariableNode,
    bridge_index::Int,
)
    return Variable.concrete_bridge_type(
        b.variable_bridge_types[bridge_index],
        b.variable_types[node.index]...,
    )
end

function _bridge_type(
    b::LazyBridgeOptimizer,
    node::ConstraintNode,
    bridge_index::Int,
)
    return Constraint.concrete_bridge_type(
        b.constraint_bridge_types[bridge_index],
        b.constraint_types[node.index]...,
    )
end

function _bridge_type(
    b::LazyBridgeOptimizer,
    node::ObjectiveNode,
    bridge_index::Int,
)
    return Objective.concrete_bridge_type(
        b.objective_bridge_types[bridge_index],
        b.objective_types[node.index]...,
    )
end

function print_unsupported(io::IO, b::LazyBridgeOptimizer, node::VariableNode)
    print_unsupported(
        io,
        b,
        b.graph.variable_edges[node.index],
        bridge_index -> _bridge_type(b, node, bridge_index),
    )
    print(io, "   Cannot add free variables and then constrain them because")
    constraint_node = b.graph.variable_constraint_node[node.index]
    if constraint_node.index == -1
        println(
            io,
            " free variables are bridged but no functionize bridge was added.",
        )
    else
        println(io, ":")
        print_if_unsupported(io, b, constraint_node)
    end
    return
end

function print_unsupported(io::IO, b::LazyBridgeOptimizer, node::ConstraintNode)
    print_unsupported(
        io,
        b,
        b.graph.constraint_edges[node.index],
        bridge_index -> _bridge_type(b, node, bridge_index),
    )
    return
end

function print_unsupported(io::IO, b::LazyBridgeOptimizer, node::ObjectiveNode)
    print_unsupported(
        io,
        b,
        b.graph.objective_edges[node.index],
        bridge_index -> _bridge_type(b, node, bridge_index),
    )
    return
end

function add_unsupported(
    graph::Graph,
    edges::Vector{Edge},
    variables,
    constraints,
    objectives,
)
    for edge in edges
        for node in edge.added_variables
            add_unsupported(graph, node, variables, constraints, objectives)
        end
        for node in edge.added_constraints
            add_unsupported(graph, node, variables, constraints, objectives)
        end
    end
    return
end

function add_unsupported(
    graph::Graph,
    edges::Vector{ObjectiveEdge},
    variables,
    constraints,
    objectives,
)
    for edge in edges
        for node in edge.added_variables
            add_unsupported(graph, node, variables, constraints, objectives)
        end
        for node in edge.added_constraints
            add_unsupported(graph, node, variables, constraints, objectives)
        end
        add_unsupported(
            graph,
            edge.added_objective,
            variables,
            constraints,
            objectives,
        )
    end
    return
end

function add_unsupported(
    graph::Graph,
    node::VariableNode,
    variables,
    constraints,
    objectives,
)
    if _dist(graph, node) != INFINITY || node in variables
        return
    end
    push!(variables, node)
    add_unsupported(
        graph,
        graph.variable_edges[node.index],
        variables,
        constraints,
        objectives,
    )
    constraint_node = graph.variable_constraint_node[node.index]
    if constraint_node.index != -1
        add_unsupported(
            graph,
            graph.variable_constraint_node[node.index],
            variables,
            constraints,
            objectives,
        )
    end
    return
end

function add_unsupported(
    graph::Graph,
    node::ConstraintNode,
    variables,
    constraints,
    objectives,
)
    if _dist(graph, node) != INFINITY || node in constraints
        return
    end
    push!(constraints, node)
    add_unsupported(
        graph,
        graph.constraint_edges[node.index],
        variables,
        constraints,
        objectives,
    )
    return
end

function add_unsupported(
    graph::Graph,
    node::ObjectiveNode,
    variables,
    constraints,
    objectives,
)
    if _dist(graph, node) != INFINITY || node in objectives
        return
    end
    push!(objectives, node)
    add_unsupported(
        graph,
        graph.objective_edges[node.index],
        variables,
        constraints,
        objectives,
    )
    return
end

function _sort(nodes::Set)
    vector = collect(nodes)
    sort!(vector, by = node -> node.index)
    return vector
end

function debug_unsupported(io::IO, b::LazyBridgeOptimizer, node::AbstractNode)
    variables = Set{VariableNode}()
    constraints = Set{ConstraintNode}()
    objectives = Set{ObjectiveNode}()
    add_unsupported(b.graph, node, variables, constraints, objectives)
    print_nodes(
        io,
        b,
        _sort(variables),
        _sort(constraints),
        _sort(objectives),
        debug_unsupported = true,
    )
    return
end

const UNSUPPORTED_MESSAGE =
    " are not supported and cannot be bridged into supported" *
    " constrained variables and constraints. See details below:"

function debug(
    b::LazyBridgeOptimizer,
    S::Type{<:MOI.AbstractSet};
    io::IO = Base.stdout,
)
    if (
        S <: MOI.AbstractScalarSet &&
        MOI.supports_add_constrained_variable(b, S)
    ) || (
        S <: MOI.AbstractVectorSet &&
        MOI.supports_add_constrained_variables(b, S)
    )
        MOIU.print_with_acronym(
            io,
            "Constrained variables in `$S` are supported.\n",
        )
    else
        MOIU.print_with_acronym(io, "Constrained variables in `$S`")
        println(io, UNSUPPORTED_MESSAGE)
        debug_unsupported(io, b, node(b, S))
    end
    return
end

"""
    debug_supports_add_constrained_variable(
        b::LazyBridgeOptimizer,
        S::Type{<:MOI.AbstractSet};
        io::IO = Base.stdout
    )

Prints to `io` explanations for the value of
[`MOI.supports_add_constrained_variable`](@ref) with the same arguments.
"""
function debug_supports_add_constrained_variable(
    b::LazyBridgeOptimizer,
    S::Type{<:MOI.AbstractSet};
    kwargs...,
)
    debug(b, S; kwargs...)
    return
end

function debug(
    b::LazyBridgeOptimizer,
    F::Type{<:MOI.AbstractFunction},
    S::Type{<:MOI.AbstractSet};
    io::IO = Base.stdout,
)
    if MOI.supports_constraint(b, F, S)
        MOIU.print_with_acronym(io, "`$F`-in-`$S` constraints are supported.\n")
    else
        MOIU.print_with_acronym(io, "`$F`-in-`$S` constraints")
        println(io, UNSUPPORTED_MESSAGE)
        debug_unsupported(io, b, node(b, F, S))
    end
    return
end

"""
    debug_supports_constraint(
        b::LazyBridgeOptimizer,
        F::Type{<:MOI.AbstractFunction},
        S::Type{<:MOI.AbstractSet};
        io::IO = Base.stdout,
    )

Prints to `io` explanations for the value of [`MOI.supports_constraint`](@ref)
with the same arguments.
"""
function debug_supports_constraint(
    b::LazyBridgeOptimizer,
    F::Type{<:MOI.AbstractFunction},
    S::Type{<:MOI.AbstractSet};
    kwargs...,
)
    return debug(b, F, S; kwargs...)
end

function debug(
    b::LazyBridgeOptimizer,
    F::Type{<:MOI.AbstractScalarFunction};
    io::IO = Base.stdout,
)
    MOIU.print_with_acronym(io, "Objective function of type `$F` is")
    if supports_bridging_objective_function(b, F)
        MOIU.print_with_acronym(io, " supported.\n")
    else
        MOIU.print_with_acronym(
            io,
            " not supported and cannot be bridged" *
            " into a supported objective function by adding only supported" *
            " constrained variables and constraints. See details below:\n",
        )
        debug_unsupported(io, b, node(b, F))
    end
    return
end

"""
    debug_supports(
        b::LazyBridgeOptimizer,
        ::MOI.ObjectiveFunction{F};
        io::IO = Base.stdout,
    ) where F

Prints to `io` explanations for the value of [`MOI.supports`](@ref) with the
same arguments.
"""
function debug_supports(
    b::LazyBridgeOptimizer,
    ::MOI.ObjectiveFunction{F};
    kwargs...,
) where {F}
    debug(b, F; kwargs...)
    return
end

ext: jl

max_stars_repo_name: JuliaOpt/MathOptInterface

max_issues_repo_name: JuliaOpt/MathOptInterface

max_forks_repo_name: JuliaOpt/MathOptInterface


text:
using Decimals
using Test

@testset "Decimals" begin

global d = [
    Decimal(0, 2, -1)
    Decimal(0, 1, -1)
    Decimal(0, 100, -4)
    Decimal(0, 1512, -2)
    Decimal(1, 3, -2)
    Decimal(1, 4, -6)
]

include("test_constructor.jl")
include("test_decimal.jl")
include("test_norm.jl")
include("test_arithmetic.jl")
include("test_equals.jl")
include("test_round.jl")

end


text:
# Base mathematical operations

function Base.clamp!(A::AbstractGPUArray, low, high)
    gpu_call(A, low, high) do ctx, A, low, high
        I = @cartesianidx A
        A[I] = clamp(A[I], low, high)
        return
    end
    return A
end


text:
#vamos a imprimir el archivo (funciona en linux, en windows debería ejecutarse otra orden)
run(`cat ../instances/SAWYER30.IN2`)

using JuMP, CPLEX #CPLEX es el solver de IP de IBM.
#using JuMP, GLPK

## leo archivo y guardo datos
function readFile(filename)
    f = open(filename, "r") # "r" -> read
    s = readlines(f) #leer el archivo y guardarlo en la variable s
    nt=parse(Int,s[1]) #lee el número de tareas
    duracion=zeros(Int, nt) #crea vector de duraciones
    precedencias=zeros(Int,nt,nt) #crea vector de precedencias
    println("tareas ",nt)
    for i in 1:nt #para cada pieza
        duracion[i]=parse(Int,s[1+i])
    end
    println("duraciones",duracion)
    c=1
    while true
        divided=split(s[nt+1+c],",")
        if parse(Int,divided[1])==(-1)
            break
        end
        precedencias[parse(Int,divided[1]),parse(Int,divided[2])]=1
        c+=1
    end
    println("precedencias",precedencias)
    close(f)
    return nt,duracion,precedencias
end

function salbp1(nt,c,duracion,precedencias)
    model = Model(CPLEX.Optimizer)
    #model=Model(GLPK.Optimizer)
    #set_optimizer_attribute(model,"msg_lev",GLPK.GLP_MSG_ALL)
    @variable(model,x[1:nt,1:nt],Bin) #tarea i en estación j
    @variable(model,y[1:nt],Bin) #Estación j
    #minimizar el número de estaciones
    @objective(model, Min, sum(y[i] for i in 1:nt))
    #asignar cada tarea
    @constraint(model,[i in 1:nt],
        sum(x[i,j] for j in 1:nt) == 1
    )
    #tiempo de ciclo
    @constraint(model,[j in 1:nt],
        sum(duracion[i]*x[i,j] for i in 1:nt) <= c*y[j]
    )
    #precedencias
    for i in 1:nt
        for j in 1:nt
            if precedencias[i,j]==1
                @constraint(model,
                    sum(k*x[i,k] for k in 1:nt) <= sum(k*x[j,k] for k in 1:nt)
                )
            end
        end
    end

    #println(model)
    optimize!(model)
    println("Objective: ",objective_value(model))
    for i in 1:nt
        println("y[$i] = ", JuMP.value(y[i]))
    end
end

nt,duracion,precedencias=readFile("../instances/SAWYER30.IN2")
for i in 25:40
  salbp1(nt,i,duracion,precedencias)
end


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

"""
    GeoStatsProcess(solver)

Geostatistical process with simulation `solver`.
"""
struct GeoStatsProcess{S} <: TimelessProcess
  solver::S
end

function evolve!(land::Matrix, proc::GeoStatsProcess)
  domain   = CartesianGrid(size(land))
  problem  = SimulationProblem(domain, :land => Float64, 1)
  solution = solve(problem, proc.solver)
  land[:] .= solution[:land][1]
  nothing
end


text: # moved to test/autoencoder_reversediff.jl


text:
"""
    wasserstein(μ, ν; metric=Euclidean(), p=Val(1), kwargs...)

Compute the `p`-Wasserstein distance with respect to the `metric` between measures `μ` and
`ν`.

Order `p` can be provided as a scalar of type `Real` or as a parameter of a value type
`Val(p)`. For certain combinations of `metric` and `p`, such as `metric=Euclidean()` and
`p=Val(2)`, the computations are more efficient if `p` is specified as a value type. The
remaining keyword arguments are forwarded to [`ot_cost`](@ref).

See also: [`squared2wasserstein`](@ref), [`ot_cost`](@ref)
"""
function wasserstein(μ, ν; metric=Euclidean(), p::Union{Real,Val}=Val(1), kwargs...)
    cost = ot_cost(p2distance(metric, p), μ, ν; kwargs...)
    return prt(cost, p)
end

# compute the cost function corresponding to a metric and exponent `p`
p2distance(metric, ::Val{1}) = metric
p2distance(metric, ::Val{P}) where {P} = (x, y) -> metric(x, y)^P
p2distance(d::Euclidean, ::Val{2}) = SqEuclidean(d.thresh)
p2distance(metric, p) = (x, y) -> metric(x, y)^p

# compute the `p` root
prt(x, ::Val{1}) = x
prt(x, ::Val{2}) = sqrt(x)
prt(x, ::Val{3}) = cbrt(x)
prt(x, ::Val{P}) where {P} = x^(1 / P)
prt(x, p) = x^(1 / p)

"""
    squared2wasserstein(μ, ν; metric=Euclidean(), kwargs...)

Compute the squared 2-Wasserstein distance with respect to the `metric` between measures `μ`
and `ν`.

The remaining keyword arguments are forwarded to [`ot_cost`](@ref).

See also: [`wasserstein`](@ref), [`ot_cost`](@ref)
"""
function squared2wasserstein(μ, ν; metric=Euclidean(), kwargs...)
    return ot_cost(p2distance(metric, Val(2)), μ, ν; kwargs...)
end


text: if true 1 end

max_stars_repo_name: gabriel-doriath-dohler/pjulia

max_issues_repo_name: gabriel-doriath-dohler/pjulia

max_forks_repo_name: gabriel-doriath-dohler/pjulia


text:
module Money

export Monetary, AssetMismatch

using FixedPointDecimals
import Base: print, show,
             convert, promote_rule, decompose,
             abs, sign, flipsign,
             round, trunc, floor, ceil,
             ==, <, <=,
             +, -, *, /,
             min, max, minmax, div, rem, divrem

struct Monetary{name,decimals} <: Real where {name<:Symbol, decimals<:Int}
    amount::FixedDecimal{BigInt,decimals}
end

"""
Get the number `d::Int` of stored digits after the decimal point.
"""
decimals(::Monetary{n,d}) where {n,d} = d

"""
Get the asset name `n::Symbol` of the monetary value.
"""
name(::Monetary{n,d}) where {n,d} = n

function Monetary(asset::Union{Symbol,String}, amount::A; decimal_digits = 18) where {A<:Union{AbstractString,Integer}}
    if typeof(asset) == Symbol
        s = asset
    else
        s = Symbol(asset)
    end

    if typeof(amount) <: AbstractString
        fd = parse(FixedDecimal{BigInt,decimal_digits}, amount)
    else
        fd = FixedDecimal{BigInt,decimal_digits}(amount)
    end

    Monetary{s,decimal_digits}(fd)
end

const M = Monetary

function show(io::IO, x::Monetary)
    asset_position    = get(io, :asset_position, :left)
    decimal_point     = get(io, :decimal_point, '.')
    thousands_point   = get(io, :thousands_point, ',')
    display_thousands = get(io, :display_thousands, false)
    digits_left       = get(io, :digits_left, -1)
    digits_right      = get(io, :digits_right, decimals(x))

    if asset_position == :left
        print(io, name(x), " ", x.amount)
    else
        print(io, x.amount, " ", name(x))
    end
end

print(io::IO, x::Monetary) = show(io, x)

struct AssetMismatch <: Exception
    base::Symbol
    counter::Symbol
end

function Base.showerror(io::IO, e::AssetMismatch)
    print(io, "Assets of different kinds: ", e.base, "/", e.counter)
end

convert(::Type{Monetary{n,d}}, x::Integer) where {n,d} = Monetary(n,x, decimal_digits=d)
convert(::Type{Monetary{n,d}}, x::String)  where {n,d} = Monetary(n,x, decimal_digits=d)

function convert(::Type{Monetary{n,d}}, x::N) where {n,d,N<:Number}
    if N <: FixedDecimal
        Monetary{n,d}(x)
    elseif N <: Monetary
        Monetary{n,d}(x.amount)
    else
        throw(InexactError(:convert,Monetary{n,d},x))
    end
end

function convert(::Type{Monetary{xn,xd}}, x::Monetary{yn,yd}) where {xn,yn,xd,yd}
    if xn != yn
        throw(AssetMismatch(xn,yn))
    end

    if xd != yd
        throw(InexactError(:convert,Monetary,x))
    end

    x
end

function promote_rule(::Type{Monetary{n,d}}, x::Type{N}) where {n,d,N<:Number}
    if N <: Union{Integer,FixedDecimal,Monetary}
        Monetary{n,d}
    else
        throw(InexactError(:convert,Monetary,x))
    end
end

function promote_rule(::Type{Monetary{n,d}}, x::Type{String}) where {n,d}
    Monetary{n,d}
end

function promote_rule(::Type{Monetary{xn,xd}},::Type{Monetary{yn,yd}}) where {xn,yn,xd,yd}
    if xn == yn
        Monetary{xn,max(xd,yd)}
    else
        # TODO: test if this makes sense
        # throw(AssetMismatch(xn,yn))
        Monetary{name,max(xd,yd)} where name
    end
end

# unary operators
abs(x::Monetary{n,d}) where {n,d} = Monetary{n,d}(abs(x.amount))
sign(x::Monetary) = sign(x.amount.i)
round(x::Monetary{n,d}, rm::RoundingMode{:Nearest}=RoundNearest) where {n,d} = Monetary{n,d}(round(x.amount, rm))
decompose(x::Monetary) = FixedPointDecimals.decompose(x.amount)
trunc(x::Monetary{n,d}) where {n,d} = Monetary{n,d}(trunc(x.amount))
floor(x::Monetary{n,d}) where {n,d} = Monetary{n,d}(floor(x.amount))
ceil(x::Monetary{n,d}) where {n,d} = Monetary{n,d}(ceil(x.amount))

# binary operators
+(x::Monetary{n,d}, y::Monetary{n,d}) where {n,d} = Monetary{n,d}(x.amount + y.amount)
-(x::Monetary{n,d}, y::Monetary{n,d}) where {n,d} = Monetary{n,d}(x.amount - y.amount)
*(x::Monetary{n,d}, y::Monetary{n,d}) where {n,d} = Monetary{n,d}(x.amount * y.amount)
/(x::Monetary{n,d}, y::Monetary{n,d}) where {n,d} = Monetary{n,d}(x.amount / y.amount)

==(x::Monetary{n,d}, y::Monetary{n,d}) where {n,d} = x.amount == y.amount
 <(x::Monetary{n,d}, y::Monetary{n,d}) where {n,d} = x.amount  < y.amount
<=(x::Monetary{n,d}, y::Monetary{n,d}) where {n,d} = x.amount <= y.amount

min(x::Monetary{n,d}, y::Monetary{n,d}) where {n,d} = Monetary{n,d}(min(x.amount, y.amount))
max(x::Monetary{n,d}, y::Monetary{n,d}) where {n,d} = Monetary{n,d}(max(x.amount, y.amount))
minmax(x::Monetary{n,d}, y::Monetary{n,d}) where {n,d} = (min(x,y),max(x,y))

div(x::Monetary{n,d}, y::Monetary{n,d}) where {n,d} = Monetary{n,d}(div(x.amount, y.amount))
rem(x::Monetary{n,d}, y::Monetary{n,d}) where {n,d} = Monetary{n,d}(rem(x.amount, y.amount))
divrem(x::Monetary{n,d}, y::Monetary{n,d}) where {n,d} = (div(x,y), rem(x,y))

flipsign(x::Monetary{n,d}, y::Monetary{n,d}) where {n,d} = Monetary{n,d}(flipsign(x.amount,y.amount))

# promotion rules for n-ary operators
+(x::Monetary, y::Real) = +(promote(x,y)...)
-(x::Monetary, y::Real) = -(promote(x,y)...)
*(x::Monetary, y::Real) = *(promote(x,y)...)
/(x::Monetary, y::Real) = /(promote(x,y)...)

==(x::Monetary, y::Real) = ==(promote(x,y)...)
 <(x::Monetary, y::Real) =  <(promote(x,y)...)
<=(x::Monetary, y::Real) = <=(promote(x,y)...)

min(x::Monetary, y::Real) = min(promote(x,y)...)
max(x::Monetary, y::Real) = max(promote(x,y)...)
minmax(x::Monetary, y::Real) = minmax(promote(x,y)...)

div(x::Monetary, y::Real) = div(promote(x,y)...)
rem(x::Monetary, y::Real) = rem(promote(x,y)...)
divrem(x::Monetary, y::Real) = divrem(promote(x,y)...)

flipsign(x::Monetary, y::Real) = flipsign(promote(x,y)...)

# promotion for strings
+(x::Monetary, y::AbstractString) = +(promote(x,y)...)
-(x::Monetary, y::AbstractString) = -(promote(x,y)...)
*(x::Monetary, y::AbstractString) = *(promote(x,y)...)
/(x::Monetary, y::AbstractString) = /(promote(x,y)...)
+(x::AbstractString, y::Monetary) = +(promote(x,y)...)
-(x::AbstractString, y::Monetary) = -(promote(x,y)...)
*(x::AbstractString, y::Monetary) = *(promote(x,y)...)
/(x::AbstractString, y::Monetary) = /(promote(x,y)...)

==(x::Monetary, y::AbstractString) = ==(promote(x,y)...)
 <(x::Monetary, y::AbstractString) =  <(promote(x,y)...)
<=(x::Monetary, y::AbstractString) = <=(promote(x,y)...)
==(x::AbstractString, y::Monetary) = ==(promote(x,y)...)
 <(x::AbstractString, y::Monetary) =  <(promote(x,y)...)
<=(x::AbstractString, y::Monetary) = <=(promote(x,y)...)

min(x::Monetary, y::AbstractString) = min(promote(x,y)...)
max(x::Monetary, y::AbstractString) = max(promote(x,y)...)
minmax(x::Monetary, y::AbstractString) = minmax(promote(x,y)...)
min(x::AbstractString, y::Monetary) = min(promote(x,y)...)
max(x::AbstractString, y::Monetary) = max(promote(x,y)...)
minmax(x::AbstractString, y::Monetary) = minmax(promote(x,y)...)

div(x::Monetary, y::AbstractString) = div(promote(x,y)...)
rem(x::Monetary, y::AbstractString) = rem(promote(x,y)...)
divrem(x::Monetary, y::AbstractString) = divrem(promote(x,y)...)
div(x::AbstractString, y::Monetary) = div(promote(x,y)...)
rem(x::AbstractString, y::Monetary) = rem(promote(x,y)...)
divrem(x::AbstractString, y::Monetary) = divrem(promote(x,y)...)

flipsign(x::Monetary, y::AbstractString) = flipsign(promote(x,y)...)

end # module


text:
struct Program
    context::AbstractContext
    vertexarray::AbstractArray
    uniforms::Dict{Symbol, Any}
    source::String
end

struct InstancedProgram
    program::Program
    per_instance::AbstractArray
end

name_type_iter(x) = (s = Tables.schema(x); zip(s.names, s.types))

function InstancedProgram(
        context::AbstractContext, shader,
        instance::AbstractVector,
        per_instance::AbstractVector;
        uniforms...
    )

    # instance = convert_uniform(context, instance)
    # per_instance = convert_uniform(context, per_instance)
    c_uniforms = Dict{Symbol, Any}()
    src = sprint() do io
        println(io, "// Instance inputs: ")
        for (name, T) in name_type_iter(instance)
            println(io, "in ", type_string(context, T), " $name;")
        end

        println(io, "\n// Per instance attributes: ")
        for (name, T) in name_type_iter(per_instance)
            println(io, "in ", type_string(context, T), " $name;")
        end

        println(io, "\n// Uniforms: ")
        for (name, v) in uniforms
            vc = convert_uniform(context, v)
            T = typeof(vc)
            println(io, "uniform ", type_string(context, T), " $name;")
            c_uniforms[name] = vc
        end
        println(io)
        println(io, shader)
    end
    InstancedProgram(
        Program(context, instance, c_uniforms, src),
        per_instance
    )
end


text:
using Colors, Test
@test isempty(detect_ambiguities(Colors, Base, Core))

include("algorithms.jl")
include("conversion.jl")
include("colormaps.jl")
include("colordiff.jl")
include("din99.jl")
include("display.jl")
include("parse.jl")
include("utilities.jl")


text:
println("\n\n\nRunning tests ...")

using InformedDifferentialEvolution
using Base.Test

optimum = [-2 4]'
costf(x) = (r = sqrt(sum((x-optimum).^2)); sin(r)^2+r/2)
costf2(x, ignore) = (r = sqrt(sum((x-optimum).^2)); sin(r)^2+r/2)

best, info = de(costf, [-10,-10], [10,10])
@test best == optimum

best, info = de(costf2, [-10,-10], [10,10], data = 1)
@test best == optimum

f(x) = sum(abs(x))
predictor(r,pop,costs) = r[:] = vcat(mean(pop,1), mean(pop,1))
mi = [-1,-1]; ma = [1,1]

best, info = de(f, mi, ma, predictors = [predictor, :default])
@test maximum(abs(best)) < 0.000001

function g(x, previouscost = Inf)
    r = 0.
    for i = -5:5
        r += abs(x[1])+abs(x[2]+i)
        if r > previouscost
            break
        end
    end
    r
end
best, info = de(g, [-100,-100], [100,100])
@test best == [0 0]'

println("   done running tests!")


text:
# using <package name>
using Random

# Print without new line
print("Hello World")

# Print with new line
println("Hello World")

for i in range(1, 10, step = 1)
    println(i)
end

function square(a::Int)
    return a*a
end

# Call the function
print(square(6))

# Vectorization
vec_sq = square.([1, 2, 3, 4])

# Mapping
mapped_vec = map(x->square(x)+4, [1,2,3,4])

max_issues_repo_name: chaitak-gorai/Study-Group

max_forks_repo_name: chaitak-gorai/Study-Group


text:
using JuliaTemplateRepo
using Test

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


text:
@testset "shorthands" begin

    @testset "xlims!" begin
        # test xlims of empty scene throws sane error
        scene = Scene()
        @test_throws ArgumentError xlims!(scene, (0,1))
        @test_throws ArgumentError ylims!(scene, (0,1))
        @test_throws ArgumentError zlims!(scene, (0,1))
        lines!(scene, rand(3), rand(3), rand(3))
        xlims!(scene, (0,1))
        ylims!(scene, (0,1))
        zlims!(scene, (0,1))
    end

    # update! is called when a scene is displayed and may cause ticks to change
    scene2d = scatter(1:10, 1:10);
    update!(scene2d)
    scene = scatter(1:10, 1:10, 1:10);
    update!(scene)
    axis = scene[Axis]

    @testset "tick labels" begin

        @test xticklabels(scene) == ["0.0", "2.5", "5.0", "7.5", "10.0"]
        @test yticklabels(scene) == ["0.0", "2.5", "5.0", "7.5", "10.0"]
        @test zticklabels(scene) == ["0.0", "2.5", "5.0", "7.5", "10.0"]
        @test_throws AssertionError("The Scene does not have a z-axis!") zticklabels(scene2d)

        @test xtickrange(scene) == [0.0, 2.5, 5.0, 7.5, 10.0]
        @test ytickrange(scene) == [0.0, 2.5, 5.0, 7.5, 10.0]
        @test ztickrange(scene) == [0.0, 2.5, 5.0, 7.5, 10.0]
        @test_throws AssertionError("The Scene does not have a z-axis!") ztickrange(scene2d)

        xticks!(scene, xticklabels=["a", "b", "c", "d", "e"])
        @test xticklabels(scene) == ["a", "b", "c", "d", "e"]

        yticks!(scene, yticklabels=["a", "b", "c", "d", "e", "f"], ytickrange=collect(range(2.0, stop=10.0, length=6)))
        @test yticklabels(scene) == ["a", "b", "c", "d", "e", "f"]

        yticks!(scene2d, yticklabels=["a", "b", "c", "d", "e", "f"], ytickrange=collect(range(2.0, stop=10.0, length=6)))
        @test yticklabels(scene2d) == ["a", "b", "c", "d", "e", "f"]

        zticks!(scene, zticklabels=["2", "10"], ztickrange=[2.0, 10.0])
        @test zticklabels(scene) == ["2", "10"]

        @test_throws AssertionError("The Scene does not have a z-axis!") zticks!(scene2d, zticklabels=["2", "10"], ztickrange=[2.0, 10.0])
    end

    @testset "tick rotation" begin
        @test xtickrotation(scene) == axis.ticks.rotation[][1]
        @test ytickrotation(scene) == axis.ticks.rotation[][2]
        @test ztickrotation(scene) == axis.ticks.rotation[][3]

        xtickrotation!(0.0)
        @test xtickrotation(scene) == 0.0

        ytickrotation!(0.0)
        @test ytickrotation(scene) == 0.0

        ztickrotation!(0.0)
        @test ztickrotation(scene) == 0.0

        @test_throws AssertionError("The Scene does not have a z-axis!") ztickrotation(scene2d)
        @test_throws AssertionError("The Scene does not have a z-axis!") ztickrotation!(scene2d, 0.0)
    end

end


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

"""
    CrossValidation(k; shuffle=true, loss=Dict())

`k`-fold cross-validation. Optionally, `shuffle` the
data, and specify `loss` function  from `LossFunctions.jl`
for some of the variables.

## References

* Geisser, S. 1975. [The predictive sample reuse method with applications]
  (https://www.jstor.org/stable/2285815)
* Burman, P. 1989. [A comparative study of ordinary cross-validation, v-fold
  cross-validation and the repeated learning-testing methods]
  (https://www.jstor.org/stable/2336116)
"""
struct CrossValidation <: ErrorEstimationMethod
  k::Int
  shuffle::Bool
  loss::Dict{Symbol,SupervisedLoss}
end

CrossValidation(k::Int; shuffle=true, loss=Dict()) =
  CrossValidation(k, shuffle, loss)

function Base.error(solver, problem, method::CrossValidation)
  # uniform weights
  weighting = UniformWeighting()

  # random folds
  folding = UniformFolding(method.k, method.shuffle)

  wcv = WeightedCrossValidation(weighting, folding,
                                lambda=1, loss=method.loss)

  error(solver, problem, wcv)
end


text:
using TensorOperations
using Base.Test

include("methods.jl")
include("tensor.jl")


text:
module TestElectrical

using ModiaMath.plot
using Modia
using Modia.Electric
using Base.Test

result = simulate(Resistor, 1)
@test result["i"][end] == 0.0
@test result["v"][end] == 0.0

@model ParallelResistors begin
  R1=Resistor(R=1, p=Pin(v=Float(start=0.0)), n=Pin(v=Float(start=0.0)))
  R2=Resistor(R=1)
@equations begin
  connect(R1.p, R2.p)
  connect(R1.n, R2.n)
  end
end

result = simulate(ParallelResistors, 1)
@test result["R1.i"][end] == 0.0
@test result["R1.v"][end] == 0.0

# -----------------------------------

# result = simulate(Capacitor, 1)

@model ParallelCapacitors begin
  C1=Capacitor(C=2, v=Float(start=1.0))
  C2=Capacitor(C=1, v=Float(state=false))
  ground=Ground()
@equations begin
  connect(C1.p, C2.p)
  connect(C1.n, C2.n)
  connect(C1.n, ground.p)
  end
end

result = simulate(ParallelCapacitors, 1)
@test result["C2.v"][end] == 1.0

# -----------------------------------

# result = simulate(Inductor, 1)

@model InductorsInSeries begin
  V=ConstantVoltage(V=10)
  L1=Inductor(L=1, i = Current(start=0.0))
  R1=Resistor(R=100) # , n=Pin(v=Float(start=0.0)))
  R2=Resistor(R=100) # , n=Pin(v=Float(start=0.0)))
  L2=Inductor(L=1, i = Current(start=0.0))
@equations begin
  connect(V.p, L1.p)
  connect(L1.n, R1.p)
  connect(L1.n, R2.p)
  connect(R1.n, L2.p)
  connect(R2.n, L2.p)
  connect(L2.n, V.n)
  end
end

# result = simulate(InductorsInSeries, 1)

# -----------------------------------

@model ParallelCapacitorCircuit begin
  R=Resistor(R=100.0)
  C=Capacitor(C=2.5E-2, v = Float(start=0.0))
  C2=Capacitor(C=2.5E-2, v = Float(state=false))
  V=StepVoltage(startTime=10, V=100)
#  Vt=ConstantVoltage(V=10.0)
  ground=Ground()
@equations begin
  connect(V.n, ground.p)
#  connect(Vt.n, ground.p)
  connect(V.p, R.p)
  connect(R.n, C.p)
  connect(C.n, V.n)
  connect(C.n, C2.n)
  connect(C.p, C2.p)
  end
end

checkSimulation(ParallelCapacitorCircuit, 1, "C1.v", 1.0, useKinsol=true, removeSingularities=false)

end


text:
include("impl.jl")

## NNPACK supports only Float32
for (front_name, backend) in (
        :conv          => :_nnpack,
        :∇conv_data    => :_nnpack,
        :∇conv_filter  => :_nnpack,
    )
    @eval begin
        function $(Symbol("$(front_name)$(backend)!"))(
                        out::Array{T1,4}, in1::Array{T2,4}, in2::Array{T3,4},
                        cdims::ConvDims; kwargs...) where {T1, T2, T3}
            @warn "Automatically converting input tensor to Float32. This will have performance implications" maxlog=1
            # Output must of the same type as in the function signature
            T1.($(Symbol("$(front_name)$(backend)!"))(Float32.(out), Float32.(in1),
                                                      Float32.(in2), cdims; kwargs...))
        end
    end
end

function maxpool_nnpack!(y::Array{T1, 4}, x::Array{T2, 4}, pdims::PoolDims;
                         kwargs...) where {T1, T2}
    @warn "Automatically converting input tensor to Float32. This will have performance implications" maxlog=1
    # We want the output to be of the same type as desired
    T1.(maxpool_nnpack!(Float32.(y), Float32.(x), pdims; kwargs...))
end

"""
    nnpack_supported_operation(cdims::ConvDims)
    nnpack_supported_operation(pdims::PoolDims)

Returns `true` if nnpack supports the convolution/pooling operation for the given parameters.
"""
function nnpack_supported_operation(pdims::PoolDims{2, K, S, P, (1, 1)}) where {K, S, P}
    val = input_size(pdims)[1:2] .+ (P[1] + P[2], P[3] + P[4]) .- K
    return val .% S == (0, 0) ? true : false
end

function nnpack_supported_operation(cdims::ConvDims{2, K, (1, 1), P, (1, 1)}) where {K, S, P}
    return true
end

# Return false for everything else
nnpack_supported_operation(dims) = false


text:
module ThreadSafeDicts

using Distributed

import Base.getindex, Base.setindex!, Base.get!, Base.get, Base.empty!, Base.pop!
import Base.haskey, Base.delete!, Base.print, Base.iterate, Base.length

export ThreadSafeDict, EnableLock, DisableLock

"""
    ThreadSafeDict(pairs::Vector{Pair{K,V}})
Struct and constructor for ThreadSafeDict. There is one lock per Dict struct. All functions lock this lock, pass
arguments to the d member Dict, unlock the spinlock, and then return what is returned by the Dict.
"""
mutable struct ThreadSafeDict{K, V} <: AbstractDict{K, V}
    dlock::Threads.SpinLock
    enabled::Bool
    d::Dict
    ThreadSafeDict{K, V}() where V where K = new(Threads.SpinLock(), true, Dict{K, V}())
    ThreadSafeDict{K, V}(itr) where V where K = new(Threads.SpinLock(), true, Dict{K, V}(itr))
end
ThreadSafeDict() = ThreadSafeDict{Any,Any}()
ThreadSafeDict(d::Dict) = ThreadSafeDict{typeof(d.keys[1]),typeof(d.vals[1])}(d)

function EnableLock(dic::ThreadSafeDict)
    dic.enabled = true
    unlock(dic.dlock)
end

function DisableLock(dic::ThreadSafeDict)
    dic.enabled = false
    lock(dic.dlock)
end

function getindex(dic::ThreadSafeDict, k)
    if dic.enabled
        lock(dic.dlock)
        v = getindex(dic.d, k)
        unlock(dic.dlock)
        return v
    else
        return getindex(dic.d, k)
    end
end

function setindex!(dic::ThreadSafeDict, k, v)
    if dic.enabled
        lock(dic.dlock)
        h = setindex!(dic.d, k, v)
        unlock(dic.dlock)
        return h
    else
        return setindex!(dic.d, k, v)
    end
end

function haskey(dic::ThreadSafeDict, k)
    if dic.enabled
        lock(dic.dlock)
        b = haskey(dic.d, k)
        unlock(dic.dlock)
        return b
    else
        return haskey(dic.d, k)
    end
end

function get(dic::ThreadSafeDict, k, v)
    if dic.enabled
        lock(dic.dlock)
        v = get(dic.d, k, v)
        unlock(dic.dlock)
        return v
    else
        return get(dic.d, k, v)
    end
end

function get!(dic::ThreadSafeDict, k, v)
    if dic.enabled
        lock(dic.dlock)
        v = get!(dic.d, k, v)
        unlock(dic.dlock)
        return v
    else
        return get!(dic.d, k, v)
    end
end

function pop!(dic::ThreadSafeDict)
    if dic.enabled
        lock(dic.dlock)
        p = pop!(dic.d)
        unlock(dic.dlock)
        return p
    else
        return pop!(dic.d)
    end
end

function empty!(dic::ThreadSafeDict)
    if dic.enabled
        lock(dic.dlock)
        d = empty!(dic.d)
        unlock(dic.dlock)
        return d
    else
        return empty!(dic.d)
    end
end

function delete!(dic::ThreadSafeDict, k)
    if dic.enabled
        lock(dic.dlock)
        p = delete!(dic.d, k)
        unlock(dic.dlock)
        return p
    else
        return delete!(dic.d, k)
    end
end

function length(dic::ThreadSafeDict)
    if dic.enabled
        lock(dic.dlock)
        len = length(dic.d)
        unlock(dic.dlock)
        return len
    else
        return length(dic.d)
    end
end

function iterate(dic::ThreadSafeDict)
    if dic.enabled
        lock(dic.dlock)
        p = iterate(dic.d)
        unlock(dic.dlock)
        return p
    else
        return iterate(dic.d)
    end
end

function iterate(dic::ThreadSafeDict, i)
    if dic.enabled
        lock(dic.dlock)
        p = iterate(dic.d, i)
        unlock(dic.dlock)
        return p
    else
        return iterate(dic.d, i)
    end
end

function print(io::IO, dic::ThreadSafeDict)
    print(io, "Dict was ", islocked(dic.dlock) ? "locked" : "unlocked", ", contents: ")
    lock(dic.dlock)
    print(io, dic.d)
    unlock(dic.dlock)
end

end # module


text:
using CPLEX
# using GLPK
# using Cbc
using JuMP

include("seqata_test_model_util.jl")
include("../src/solvers/mip_discret.jl")

# ===========
# Préparation des arguments
args = Args.parse_commandline()
const TEST_LEVEL = 1
Args.set(:level, TEST_LEVEL) # sera passé temporairement à 0
Args.set(:itermax, 300)
Args.set(:outdir, "/tmp") # equivalent à l'option -d/tmp

# ===========
# Construction de l'instance mini
inst = instance_build_mini10()
@test inst.nb_planes == 10

# ===========
lg1("1. Création d'un MipDiscretSolver pour CPLEX... ")
Args.set("external_mip_solver", :cplex)
Args.set(:level, 0)
solver = MipDiscretSolver(inst)
Args.set(:level, TEST_LEVEL)

# backend_model = JuMP.backend(solver.model).optimizer.model
# @test typeof(backend_model) == CPLEX.Optimizer
@test Symbol(lowercase(solver_name(solver.model))) == :cplex
ln1(" fait.")

# ===========
lg1("2. Résolution par MipDiscretSolver pour CPLEX (cost=700.0 ?)... ")
# Args.set(:level, 0)
solve(solver)
# Args.set(:level, TEST_LEVEL)
bestsol = solver.bestsol
@test bestsol.cost == 700.0
ln1(" (cost=$(solver.bestsol.cost)) fait.\n")


text:
module CommunalHelperTimedTriggerSpikes

using ..Ahorn, Maple
using Ahorn.CommunalHelper

const pos = :(spike(
    x::Integer,
    y::Integer,
))
const data = :(
    type::String="default",
    Delay::Number=0.4,
    WaitForPlayer::Bool=false,
    Grouped::Bool=false,
    Rainbow::Bool=false,
    TriggerAlways::Bool=false,
)
const heightData = appendkwargs(pos, :(height::Integer=Maple.defaultSpikeHeight), data)
const widthData = appendkwargs(pos, :(width::Integer=Maple.defaultSpikeWidth), data)

@mapdefdata Entity "CommunalHelper/TimedTriggerSpikesLeft" TimedTriggerSpikesLeft heightData
@mapdefdata Entity "CommunalHelper/TimedTriggerSpikesUp" TimedTriggerSpikesUp widthData
@mapdefdata Entity "CommunalHelper/TimedTriggerSpikesRight" TimedTriggerSpikesRight heightData
@mapdefdata Entity "CommunalHelper/TimedTriggerSpikesDown" TimedTriggerSpikesDown widthData

const placements = Ahorn.PlacementDict()

const TimedTriggerSpikes = Dict{String,Type}(
    "up" => TimedTriggerSpikesUp,
    "down" => TimedTriggerSpikesDown,
    "left" => TimedTriggerSpikesLeft,
    "right" => TimedTriggerSpikesRight,
)

const spikeTypes = String["default", "outline", "cliffside", "reflection"]

const triggerSpikeColors = [
    (242, 90, 16, 255) ./ 255,
    (255, 0, 0, 255) ./ 255,
    (242, 16, 103, 255) ./ 255,
]

const TriggerSpikesUnion = Union{
    TimedTriggerSpikesUp,
    TimedTriggerSpikesDown,
    TimedTriggerSpikesLeft,
    TimedTriggerSpikesRight,
}

for variant in spikeTypes, (dir, entity) in TimedTriggerSpikes
    key = "Timed Trigger Spikes ($(uppercasefirst(dir)), $(uppercasefirst(variant))) (Communal Helper)"
    placements[key] = Ahorn.EntityPlacement(
        entity,
        "rectangle",
        Dict{String,Any}(
            "type" => variant,
        )
    )
end

Ahorn.editingOptions(entity::TriggerSpikesUnion) = Dict{String,Any}(
    "type" => spikeTypes,
    "Grouped" => Dict{String,Bool}(
        "Not Grouped" => false,
        "Grouped (Requires Max's Helping Hand)" => true,
    ),
    "Rainbow" => Dict{String,Bool}(
        "Default" => false,
        "Rainbow (Requires Viv's Helper)" => true,
    ),
)

const directions = Dict{String,String}(
    "CommunalHelper/TimedTriggerSpikesUp" => "up",
    "CommunalHelper/TimedTriggerSpikesDown" => "down",
    "CommunalHelper/TimedTriggerSpikesLeft" => "left",
    "CommunalHelper/TimedTriggerSpikesRight" => "right",
)

const offsets = Dict{String,Tuple{Integer,Integer}}(
    "up" => (4, -4),
    "down" => (4, 4),
    "left" => (-4, 4),
    "right" => (4, 4),
)

const renderOffsets = Dict{String,Tuple{Integer,Integer}}(
    "up" => (0, 5),
    "down" => (0, -4),
    "left" => (5, 0),
    "right" => (-4, 0),
)

const rotations = Dict{String,Number}(
    "up" => 0,
    "right" => pi / 2,
    "down" => pi,
    "left" => 3 * pi / 2,
)

const rotationOffsets = Dict{String,Tuple{Number,Number}}(
    "up" => (3, -1),
    "right" => (4, 3),
    "down" => (5, 5),
    "left" => (-1, 4),
)

const resizeDirections = Dict{String,Tuple{Bool,Bool}}(
    "up" => (true, false),
    "down" => (true, false),
    "left" => (false, true),
    "right" => (false, true),
)

function Ahorn.renderSelectedAbs(ctx::Ahorn.Cairo.CairoContext, entity::TriggerSpikesUnion)
    direction = get(directions, entity.name, "up")
    theta = rotations[direction] - pi / 2

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

    x, y = Ahorn.position(entity)
    cx, cy = x + floor(Int, width / 2) - 8 * (direction == "left"),
    y + floor(Int, height / 2) - 8 * (direction == "up")

    Ahorn.drawArrow(ctx, cx, cy, cx + cos(theta) * 24, cy + sin(theta) * 24, Ahorn.colors.selection_selected_fc, headLength=6)
end

function Ahorn.selection(entity::TriggerSpikesUnion)
    x, y = Ahorn.position(entity)

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

    direction = get(directions, entity.name, "up")

    ox, oy = offsets[direction]

    return Ahorn.Rectangle(x + ox - 4, y + oy - 4, width, height)
end

Ahorn.minimumSize(entity::TriggerSpikesUnion) = 8, 8

function Ahorn.resizable(entity::TriggerSpikesUnion)
    direction = get(directions, entity.name, "up")
    return resizeDirections[direction]
end

function Ahorn.render(ctx::Ahorn.Cairo.CairoContext, entity::TriggerSpikesUnion)
    variant = get(entity.data, "type", "default")
    direction = get(directions, entity.name, "up")
    TriggerSpikesOffset = renderOffsets[direction]

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

    if variant == "dust"
        rng = Ahorn.getSimpleEntityRng(entity)

        updown = direction == "up" || direction == "down"

        for ox in 0:8:width-8, oy in 0:8:height-8
            color1 = rand(rng, triggerSpikeColors)
            color2 = rand(rng, triggerSpikeColors)

            drawX = ox + rotationOffsets[direction][1]
            drawY = oy + rotationOffsets[direction][2]

            Ahorn.drawSprite(ctx, "danger/triggertentacle/wiggle_v06", drawX, drawY, rot=rotations[direction], tint=color1)
            Ahorn.drawSprite(ctx, "danger/triggertentacle/wiggle_v03", drawX + 3 * updown, drawY + 3 * !updown, rot=rotations[direction], tint=color2)
        end
    else
        for ox in 0:8:width-8, oy in 0:8:height-8
            drawX, drawY = (ox, oy) .+ offsets[direction] .+ TriggerSpikesOffset
            Ahorn.drawSprite(ctx, "danger/spikes/$(variant)_$(direction)00", drawX, drawY)
        end
    end
end

const spikes = [
    TimedTriggerSpikesLeft,
    TimedTriggerSpikesUp,
    TimedTriggerSpikesRight,
    TimedTriggerSpikesDown,
]

for i in 0:3
    left, current, right, opposite = circshift(spikes, i)
    size = iseven(i) ? :(entity.width) : :(entity.height)
    dirCheck = isodd(i) ? :(horizontal) : :(!horizontal)

    @eval begin
        function Ahorn.flipped(entity::$current, horizontal::Bool)
            if $dirCheck
                return $opposite(entity.x, entity.y, $size, entity.type)
            end
        end

        function Ahorn.rotated(entity::$current, steps::Int)
            if steps > 0
                return Ahorn.rotated($right(entity.x, entity.y, $size, entity.type), steps - 1)

            elseif steps < 0
                return Ahorn.rotated($left(entity.x, entity.y, $size, entity.type), steps + 1)
            end

            return entity
        end
    end
end

end


text:
# ---
# title: 3. Longest Substring Without Repeating Characters
# id: problem3
# author: Tian Jun
# date: 2020-10-31
# difficulty: Medium
# categories: Hash Table, Two Pointers, String, Sliding Window
# link: <https://leetcode.com/problems/longest-substring-without-repeating-characters/description/>
# hidden: true
# ---
#
# Given a string `s`, find the length of the **longest substring** without
# repeating characters.
#
#
#
# **Example 1:**
#
#
#
#     Input: s = "abcabcbb"
#     Output: 3
#     Explanation: The answer is "abc", with the length of 3.
#
#
# **Example 2:**
#
#
#
#     Input: s = "bbbbb"
#     Output: 1
#     Explanation: The answer is "b", with the length of 1.
#
#
# **Example 3:**
#
#
#
#     Input: s = "pwwkew"
#     Output: 3
#     Explanation: The answer is "wke", with the length of 3.
#     Notice that the answer must be a substring, "pwke" is a subsequence and not a substring.
#
#
# **Example 4:**
#
#
#
#     Input: s = ""
#     Output: 0
#
#
#
#
# **Constraints:**
#
#   * `0 <= s.length <= 5 * 104`
#   * `s` consists of English letters, digits, symbols and spaces.
#
#
## @lc code=start
using LeetCode

function length_of_longest_substring(s::String)::Int
    max_string, max_len = "", 0
    for c in s
        ## if c occurs twice in max_string
        if c in max_string
            max_string = max_string[(findfirst(c, max_string) + 1):end] * c
        else
            max_string *= c
            max_len = max(length(max_string), max_len)
        end
    end
    return max_len
end
## @lc code=end


text:
# TODO fully implement this function
function interchange_rxn!(model::MetNet, rxn1_ider::IDER_TYPE, rxn2_ider::IDER_TYPE)
    rxn1_idx = rxnindex(model, rxn1_ider)
    rxn2_idx = rxnindex(model, rxn2_ider)

    # S
    temp = model.S[:, rxn1_idx]
    model.S[:, rxn1_idx] .= model.S[:, rxn2_idx]
    model.S[:, rxn2_idx] .= temp

    # rxn
    temp = model.rxns[rxn1_idx]
    model.rxns[rxn1_idx] = model.rxns[rxn2_idx]
    model.rxns[rxn2_idx] = temp

    # rxnNames
    temp = model.rxnNames[rxn1_idx]
    model.rxnNames[rxn1_idx] = model.rxnNames[rxn2_idx]
    model.rxnNames[rxn2_idx] = temp

    # lb
    temp = model.lb[rxn1_idx]
    model.lb[rxn1_idx] = model.lb[rxn2_idx]
    model.lb[rxn2_idx] = temp

    # ub
    temp = model.ub[rxn1_idx]
    model.ub[rxn1_idx] = model.ub[rxn2_idx]
    model.ub[rxn2_idx] = temp

    # rev
    temp = model.rev[rxn1_idx]
    model.rev[rxn1_idx] = model.rev[rxn2_idx]
    model.rev[rxn2_idx] = temp

end


text:
# XXX finds provided string tuple in tree structure and returns node id (or false), tuple does not need to start at the top level of tree, in that case function can return an array instead of a number
function lookupTupleTree(input_uni::Tuple{Vararg{String,N} where N},tree_obj::Tree, startLvl_int::Int= 1)

	if isempty(tree_obj.nodes) return false end

	# find leading and trailing empty entries
	firstVal_int = findfirst(x -> x != "",input_uni)
	lastVal_int = findlast(x -> x != "",input_uni)

	# adjust input uni and start level according to removed values
	startLvl_int = plus(firstVal_int,startLvl_int) - 1
	input_uni = input_uni[firstVal_int:lastVal_int]

	gap_arr = findall(input_uni .== "")

	if startLvl_int == 1 && isempty(gap_arr)
		return getDicEmpty(tree_obj.srcTup,input_uni)
	else
		noGap_arr = reverse(setdiff(1:length(input_uni),gap_arr))

		# initialize by searching for last entry in input tuple
		crtLvl_int = noGap_arr[1] + startLvl_int - 1
		found_arr = getDicEmpty(tree_obj.srcStr,(input_uni[noGap_arr[1]],crtLvl_int))

		# checks which nodes found initially actually comply with rest of input_uni
		for i in noGap_arr[2:end]
			crtLvlItr_int = i + startLvl_int - 1
			found_arr = getDicEmpty(tree_obj.srcStr,(input_uni[i],crtLvlItr_int)) |> (y -> filter(x -> goUp(x,tree_obj.up,crtLvl_int-crtLvlItr_int,tree_obj.nodes) in y,found_arr))
		end
	end
	return found_arr
end

# XXX sorts inputs nodes according to their tree position
function sortSiblings(nodesIndex_arr::Array{Int,1},tree_obj::Tree)
	hertiLine_mat = map(x -> getAncestors(x, tree_obj,:tup),nodesIndex_arr)

    rowNum_int = length(nodesIndex_arr)
    colNum_int = maximum([hertiLine_mat[i][1][2] .+ 1 for i = 1:rowNum_int])

    herti_mat = zeros(Int64, rowNum_int, colNum_int)

    for (row, row_arr) in enumerate(hertiLine_mat)
		for ele in row_arr
            herti_mat[row,tree_obj.nodes[ele[1]].lvl+1] = ele[1]
        end
    end

    order_mat = sortslices(hcat(nodesIndex_arr,herti_mat), dims=1, by = x-> x[2:end,1])

    return order_mat[:,1]
end

# XXX goes up the tree from x for the number of steps defined by steps_int
function goUp(x::Int,up::Dict{Int,Int},steps_int::Int,nodes_dic::Dict{Int,Node})
	startLvl_int = nodes_dic[x].lvl
	steps_ctr = 0
	while steps_ctr < steps_int
		x = up[x]
		steps_ctr = startLvl_int - nodes_dic[x].lvl
	end
	return x
end

# XXX gets all parents (id, level) combination, if node is already on top level returns itself, if limitLvl_int is set only provide parents until that level
getAncestors(startNode_int::Int,tree_obj::Tree,retType::Symbol,limitLvl_int::Int=0) = getAncestors(startNode_int::Int,tree_obj::Tree,Val{retType}(),limitLvl_int::Int)

# XXX returns an array of tuples with ancestors (idx,level)
function getAncestors(startNode_int::Int,tree_obj::Tree,retType::Val{:tup},limitLvl_int::Int=0)

	# gets level of start node
	currLvl_int = tree_obj.nodes[startNode_int].lvl

	# return array, if no further going up the tree is required
	if currLvl_int == 0 || limitLvl_int == currLvl_int  return [(startNode_int, currLvl_int)] end
	# initialize move up the tree
	heri_arr = Array{Tuple{Int,Int},1}()
	next = startNode_int

	# loops up the tree and obtains (id, level) combinations
	while limitLvl_int < currLvl_int
		next = tree_obj.up[next]
		currLvl_int = tree_obj.nodes[next].lvl
		push!(heri_arr, (next, currLvl_int))
	end

	return heri_arr
end

# XXX returns an array of integers with ancestors
function getAncestors(startNode_int::Int,tree_obj::Tree,retType::Val{:int},limitLvl_int::Int=0)

	# gets level of start node
	currLvl_int = tree_obj.nodes[startNode_int].lvl

	# return array, if no further going up the tree is required
	if currLvl_int == 0 || limitLvl_int == currLvl_int  return [startNode_int] end
	# initialize move up the tree
	heri_arr = Array{Int,1}()
	next = startNode_int

	# loops up the tree and obtains (id, level) combinations
	while limitLvl_int < currLvl_int
		next = tree_obj.up[next]
		currLvl_int = tree_obj.nodes[next].lvl
		push!(heri_arr, next)
	end

	return heri_arr
end

# XXX gets all children of node
function getDescendants(startNode_int::Int,tree_obj::Tree,getAll::Bool = false, limitLvl_int::Int=0)

	# determines starting point
	startLvl_int = tree_obj.nodes[startNode_int].lvl

	# sets limits to maximum value if none provided
	if limitLvl_int == 0 limitLvl_int = tree_obj.height end

	if startLvl_int == limitLvl_int || (getAll && isempty(tree_obj.nodes[startNode_int].down)) return [startNode_int] end

	startIdx_arr = tree_obj.nodes[startNode_int].down

	curLvl_int = startLvl_int

	# initialize array of all children
	if getAll allIdx_arr = startIdx_arr end

	while curLvl_int < (limitLvl_int-1)
		lookUp_arr = vcat(map(x -> tree_obj.nodes[x].down,startIdx_arr)...)
		if isempty(lookUp_arr)
			#break;
		else
			startIdx_arr = lookUp_arr
			if getAll allIdx_arr = vcat(allIdx_arr,startIdx_arr) end
		end
		curLvl_int = curLvl_int + 1
	end

	return getAll ? allIdx_arr : startIdx_arr
end

# XXX returns all nodes of tree on the level provided
getNodesLvl(tree_obj::Tree, level_int::Int) = filter(r -> r.lvl == level_int, sort(collect(values(tree_obj.nodes)), by = x -> x.idx))

# XXX returns (unique) tuple with strings of node itself and its parents
function getUniName(nodeIdx_int::Int, tree_obj::Tree)
	if nodeIdx_int == 0 return ("none",) end
	relNodes_arr = tree_obj.nodes[nodeIdx_int].lvl == 1 ? [nodeIdx_int] : vcat(reverse(getAncestors(nodeIdx_int,tree_obj,:tup,1))..., nodeIdx_int)
	return tuple(map(x -> tree_obj.nodes[x[1]].val, relNodes_arr)...)
end

createFullString(nodeIdx_int::Int,tree_obj::Tree) = join(getUniName(nodeIdx_int,tree_obj)," < ")


text:
const SYSTEM_CATALOG = [
    SystemDescriptor(
        name = "c_sys14",
        description = "14-bus system",
        category = PSITestSystems,
        raw_data = "data/data_14bus_pu.jl",
        build_function = build_c_sys14,
    ),
    SystemDescriptor(
        name = "c_sys14_dc",
        description = "14-bus system with DC line",
        category = PSITestSystems,
        raw_data = "data/data_14bus_pu.jl",
        build_function = build_c_sys14_dc,
    ),
    SystemDescriptor(
        name = "c_sys5",
        description = "5-bus system",
        category = PSITestSystems,
        raw_data = "data/data_5bus_pu.jl",
        build_function = build_c_sys5,
    ),
    SystemDescriptor(
        name = "c_sys5_bat",
        description = "5-bus system with Storage Device",
        category = PSITestSystems,
        raw_data = "data/data_5bus_pu.jl",
        build_function = build_c_sys5_bat,
    ),
    SystemDescriptor(
        name = "c_sys5_dc",
        description = "Systems with HVDC data in the branches",
        category = PSITestSystems,
        raw_data = "data/data_5bus_pu.jl",
        build_function = build_c_sys5_dc,
    ),
    SystemDescriptor(
        name = "c_sys5_ed",
        description = "5-bus System for Economic Dispatch Simulations",
        category = PSITestSystems,
        raw_data = "data/data_5bus_pu.jl",
        build_function = build_c_sys5_ed,
    ),
    SystemDescriptor(
        name = "c_sys5_hy",
        description = "5-bus system with HydroDispatch",
        category = PSITestSystems,
        raw_data = "data/data_5bus_pu.jl",
        build_function = build_c_sys5_hy,
    ),
    SystemDescriptor(
        name = "c_sys5_hy_ed",
        description = "5-bus system with Hydro-Power for Economic Dispatch Simulations",
        category = PSITestSystems,
        raw_data = "data/data_5bus_pu.jl",
        build_function = build_c_sys5_hy_ed,
    ),
    SystemDescriptor(
        name = "c_sys5_hy_ems_ed",
        description = "5-bus system with Hydro-Power for Economic Dispatch Simulations",
        category = PSITestSystems,
        raw_data = "data/data_5bus_pu.jl",
        build_function = build_c_sys5_hy_ems_ed,
    ),
    SystemDescriptor(
        name = "c_sys5_phes_ed",
        description = "5-bus system with Hydro Pumped Energy Storage for Economic Dispatch Simulations",
        category = PSITestSystems,
        raw_data = "data/data_5bus_pu.jl",
        build_function = build_c_sys5_phes_ed,
    ),
    SystemDescriptor(
        name = "c_sys5_hy_uc",
        description = "5-bus system with Hydro-Power for Unit Commitment Simulations",
        category = PSITestSystems,
        raw_data = "data/data_5bus_pu.jl",
        build_function = build_c_sys5_hy_uc,
    ),
    SystemDescriptor(
        name = "c_sys5_hy_ems_uc",
        description = "5-bus system with Hydro-Power for Unit Commitment Simulations",
        category = PSITestSystems,
        raw_data = "data/data_5bus_pu.jl",
        build_function = build_c_sys5_hy_ems_uc,
    ),
    SystemDescriptor(
        name = "c_sys5_hyd",
        description = "5-bus system with Hydro Energy Reservoir",
        category = PSITestSystems,
        raw_data = "data/data_5bus_pu.jl",
        build_function = build_c_sys5_hyd,
    ),
    SystemDescriptor(
        name = "c_sys5_hyd_ems",
        description = "5-bus system with Hydro Energy Reservoir",
        category = PSITestSystems,
        raw_data = "data/data_5bus_pu.jl",
        build_function = build_c_sys5_hyd_ems,
    ),
    SystemDescriptor(
        name = "c_sys5_il",
        description = "System with Interruptible Load",
        category = PSITestSystems,
        raw_data = "data/data_5bus_pu.jl",
        build_function = build_c_sys5_il,
    ),
    SystemDescriptor(
        name = "c_sys5_ml",
        description = "",
        category = PSITestSystems,
        raw_data = "data/data_5bus_pu.jl",
        build_function = build_c_sys5_ml,
    ),
    SystemDescriptor(
        name = "c_sys5_re",
        description = "5-bus system with Renewable Energy",
        category = PSITestSystems,
        raw_data = "data/data_5bus_pu.jl",
        build_function = build_c_sys5_re,
    ),
    SystemDescriptor(
        name = "c_sys5_re_only",
        description = "5-bus system with only Renewable Energy",
        category = PSITestSystems,
        raw_data = "data/data_5bus_pu.jl",
        build_function = build_c_sys5_re_only,
    ),
    SystemDescriptor(
        name = "c_sys5_uc",
        description = "5-bus system for Unit Commitment Simulations",
        category = PSITestSystems,
        raw_data = "data/data_5bus_pu.jl",
        build_function = build_c_sys5_uc,
    ),
    SystemDescriptor(
        name = "c_sys5_uc_non_spin",
        description = "5-bus system for Unit Commitment with Non-Spinning Reserve Simulations",
        category = PSITestSystems,
        raw_data = "data/data_5bus_pu.jl",
        build_function = build_c_sys5_uc_non_spin,
    ),
    SystemDescriptor(
        name = "c_sys5_uc_re",
        description = "5-bus system for Unit Commitment Simulations with Renewable Units",
        category = PSITestSystems,
        raw_data = "data/data_5bus_pu.jl",
        build_function = build_c_sys5_uc_re,
    ),
    SystemDescriptor(
        name = "c_sys5_pglib",
        description = "5-bus with ThermalMultiStart",
        category = PSITestSystems,
        raw_data = "data/data_5bus_pu.jl",
        build_function = build_c_sys5_pglib,
    ),
    SystemDescriptor(
        name = "c_sys5_pwl_uc",
        description = "5-bus with SOS cost function for Unit Commitment Simulations",
        category = PSITestSystems,
        raw_data = "data/data_5bus_pu.jl",
        build_function = build_c_sys5_pwl_uc,
    ),
    SystemDescriptor(
        name = "c_sys5_pwl_ed",
        description = "5-bus with pwl cost function",
        category = PSITestSystems,
        raw_data = "data/data_5bus_pu.jl",
        build_function = build_c_sys5_pwl_ed,
    ),
    SystemDescriptor(
        name = "c_sys5_pwl_ed_nonconvex",
        description = "5-bus with SOS cost function for Economic Dispatch Simulations",
        category = PSITestSystems,
        raw_data = "data/data_5bus_pu.jl",
        build_function = build_c_sys5_pwl_ed_nonconvex,
    ),
    SystemDescriptor(
        name = "c_sys5_reg",
        description = "5-bus with regulation devices and AGC",
        category = PSITestSystems,
        raw_data = "data/data_5bus_pu.jl",
        build_function = build_c_sys5_reg,
    ),
    SystemDescriptor(
        name = "c_ramp_test",
        description = "1-bus for ramp testing",
        category = PSITestSystems,
        raw_data = "",
        build_function = build_sys_ramp_testing,
    ),
    SystemDescriptor(
        name = "c_duration_test",
        description = "1 Bus for duration testing",
        category = PSITestSystems,
        raw_data = "",
        build_function = build_duration_test_sys,
    ),
    SystemDescriptor(
        name = "c_linear_pwl_test",
        description = "1 Bus lineal PWL linear testing",
        category = PSITestSystems,
        raw_data = "",
        build_function = build_pwl_test_sys,
    ),
    SystemDescriptor(
        name = "c_sos_pwl_test",
        description = "1 Bus lineal PWL sos testing",
        category = PSITestSystems,
        raw_data = "",
        build_function = build_sos_test_sys,
    ),
    SystemDescriptor(
        name = "c_market_bid_cost",
        description = "1 bus system with MarketBidCost Model",
        category = PSITestSystems,
        raw_data = "",
        build_function = build_pwl_marketbid_sys,
    ),
    SystemDescriptor(
        name = "5_bus_hydro_uc_sys",
        description = "5-bus hydro unit commitment data",
        category = SIIPExampleSystems,
        raw_data = joinpath(PACKAGE_DIR, "data"),
        build_function = build_5_bus_hydro_uc_sys,
    ),
    SystemDescriptor(
        name = "5_bus_hydro_ed_sys",
        description = "5-bus hydro economic dispatch data",
        category = SIIPExampleSystems,
        raw_data = joinpath(PACKAGE_DIR, "data"),
        build_function = build_5_bus_hydro_ed_sys,
    ),
    SystemDescriptor(
        name = "5_bus_hydro_wk_sys",
        description = "5-bus hydro system for weekly dispatch",
        category = SIIPExampleSystems,
        raw_data = joinpath(PACKAGE_DIR, "data"),
        build_function = build_5_bus_hydro_wk_sys,
    ),
    SystemDescriptor(
        name = "5_bus_hydro_uc_sys_with_targets",
        description = "5-bus hydro unit commitment data with energy targets",
        category = SIIPExampleSystems,
        raw_data = joinpath(PACKAGE_DIR, "data"),
        build_function = build_5_bus_hydro_uc_sys_targets,
    ),
    SystemDescriptor(
        name = "5_bus_hydro_ed_sys_with_targets",
        description = "5-bus hydro economic dispatch data with energy targets",
        category = SIIPExampleSystems,
        raw_data = joinpath(PACKAGE_DIR, "data"),
        build_function = build_5_bus_hydro_ed_sys_targets,
    ),
    SystemDescriptor(
        name = "5_bus_hydro_wk_sys_with_targets",
        description = "5-bus hydro system for weekly dispatch with energy targets",
        category = SIIPExampleSystems,
        raw_data = joinpath(PACKAGE_DIR, "data"),
        build_function = build_5_bus_hydro_wk_sys_targets,
    ),
    SystemDescriptor(
        name = "psse_RTS_GMLC_sys",
        description = "PSSE .raw RTS-GMLC system",
        category = PSSETestSystems,
        raw_data = joinpath(PACKAGE_DIR, "data", "psse_raw", "RTS-GMLC.RAW"),
        build_function = build_psse_RTS_GMLC_sys,
    ),
    SystemDescriptor(
        name = "test_RTS_GMLC_sys",
        description = "RTS-GMLC test system with day-ahead forecast",
        category = PSITestSystems,
        raw_data = joinpath(PACKAGE_DIR, "data", "RTS_GMLC"),
        build_function = build_test_RTS_GMLC_sys,
    ),
    SystemDescriptor(
        name = "RTS_GMLC_sys",
        description = "RTS-GMLC Full system from git repo for day-ahead simulations",
        category = PSITestSystems,
        raw_data = joinpath(PACKAGE_DIR, "data", "RTS-GMLC-master"),
        build_function = build_RTS_GMLC_sys,
        download_function = download_RTS,
    ),
    SystemDescriptor(
        name = "modified_RTS_GMLC_DA_sys",
        description = "Modified RTS-GMLC Full system for day-ahead simulations
            with modifications to reserve definitions to improve feasibility",
        category = PSITestSystems,
        raw_data = joinpath(PACKAGE_DIR, "data", "RTS-GMLC-master"),
        build_function = build_modified_RTS_GMLC_DA_sys,
        download_function = download_RTS,
    ),
    SystemDescriptor(
        name = "modified_RTS_GMLC_RT_sys",
        description = "Modified RTS-GMLC Full system for real-time simulations
            with modifications to reserve definitions to improve feasibility",
        category = PSITestSystems,
        raw_data = joinpath(PACKAGE_DIR, "data", "RTS-GMLC-master"),
        build_function = build_modified_RTS_GMLC_RT_sys,
        download_function = download_RTS,
    ),
    # SystemDescriptor(
    #     name =  "US_sys",
    #     description =  "US test system",
    #     category =  SIIPExampleSystems,
    #     raw_data =  "",
    #     build_function  =  build_US_sys
    # ),
    # SystemDescriptor(
    #     name =  "psse_ACTIVSg10k_sys",
    #     description =  "ACTIVSg10k Test system",
    #     category =  PSSETestSystems,
    #     raw_data =  joinpath(PACKAGE_DIR, "data", "ACTIVSg10k",  "ACTIVSg10k.RAW"),
    #     build_function  =  build_ACTIVSg10k_sys
    # ),
    # SystemDescriptor(
    #     name =  "psse_ACTIVSg70k_sys",
    #     description =  "ACTIVSg70k Test system",
    #     category =  PSSETestSystems,
    #     raw_data =  joinpath(PACKAGE_DIR, "data", "ACTIVSg70k",  "ACTIVSg70k.RAW"),
    #     build_function  =  build_ACTIVSg70k_sys
    # ),
    SystemDescriptor(
        name = "psse_ACTIVSg2000_sys",
        description = "PSSE ACTIVSg2000 Test system",
        category = PSSETestSystems,
        raw_data = joinpath(PACKAGE_DIR, "data"),
        build_function = build_psse_ACTIVSg2000_sys,
    ),
    SystemDescriptor(
        name = "matpower_ACTIVSg2000_sys",
        description = "MATPOWER ACTIVSg2000 Test system",
        category = MatPowerTestSystems,
        raw_data = joinpath(PACKAGE_DIR, "data", "matpower", "ACTIVSg2000.m"),
        build_function = build_matpower_ACTIVSg2000_sys,
    ),
    SystemDescriptor(
        name = "tamu_ACTIVSg2000_sys",
        description = "TAMU ACTIVSg2000 Test system",
        category = PSYTestSystems,
        raw_data = joinpath(PACKAGE_DIR, "data"),
        build_function = build_tamu_ACTIVSg2000_sys,
    ),
    SystemDescriptor(
        name = "matpower_ACTIVSg10k_sys",
        description = "ACTIVSg10k Test system",
        category = MatPowerTestSystems,
        raw_data = joinpath(PACKAGE_DIR, "data", "matpower", "case_ACTIVSg10k.m"),
        build_function = build_matpower_ACTIVSg10k_sys,
    ),
    SystemDescriptor(
        name = "matpower_case2_sys",
        description = "Matpower Test system",
        category = MatPowerTestSystems,
        raw_data = joinpath(PACKAGE_DIR, "data", "matpower", "case2.m"),
        build_function = build_matpower_case2_sys,
    ),
    SystemDescriptor(
        name = "matpower_case3_tnep_sys",
        description = "Matpower Test system",
        category = MatPowerTestSystems,
        raw_data = joinpath(PACKAGE_DIR, "data", "matpower", "case3_tnep.m"),
        build_function = build_matpower_case3_tnep_sys,
    ),
    SystemDescriptor(
        name = "matpower_case5_asym_sys",
        description = "Matpower Test system",
        category = MatPowerTestSystems,
        raw_data = joinpath(PACKAGE_DIR, "data", "matpower", "case5_asym.m"),
        build_function = build_matpower_case5_asym_sys,
    ),
    SystemDescriptor(
        name = "matpower_case5_dc_sys",
        description = "Matpower Test system",
        category = MatPowerTestSystems,
        raw_data = joinpath(PACKAGE_DIR, "data", "matpower", "case5_dc.m"),
        build_function = build_matpower_case5_dc_sys,
    ),
    SystemDescriptor(
        name = "matpower_case5_gap_sys",
        description = "Matpower Test system",
        category = MatPowerTestSystems,
        raw_data = joinpath(PACKAGE_DIR, "data", "matpower", "case5_gap.m"),
        build_function = build_matpower_case5_gap_sys,
    ),
    SystemDescriptor(
        name = "matpower_case5_pwlc_sys",
        description = "Matpower Test system",
        category = MatPowerTestSystems,
        raw_data = joinpath(PACKAGE_DIR, "data", "matpower", "case5_pwlc.m"),
        build_function = build_matpower_case5_pwlc_sys,
    ),
    SystemDescriptor(
        name = "matpower_case5_re_intid_sys",
        description = "Matpower Test system",
        category = MatPowerTestSystems,
        raw_data = joinpath(PACKAGE_DIR, "data", "matpower", "case5_re_intid.m"),
        build_function = build_matpower_case5_re_intid_sys,
    ),
    SystemDescriptor(
        name = "matpower_case5_re_uc_pwl_sys",
        description = "Matpower Test system",
        category = MatPowerTestSystems,
        raw_data = joinpath(PACKAGE_DIR, "data", "matpower", "case5_re_uc_pwl.m"),
        build_function = build_matpower_case5_re_uc_pwl_sys,
    ),
    SystemDescriptor(
        name = "matpower_case5_re_uc_sys",
        description = "Matpower Test system",
        category = MatPowerTestSystems,
        raw_data = joinpath(PACKAGE_DIR, "data", "matpower", "case5_re_uc.m"),
        build_function = build_matpower_case5_re_uc_sys,
    ),
    SystemDescriptor(
        name = "matpower_case5_re_sys",
        description = "Matpower Test system",
        category = MatPowerTestSystems,
        raw_data = joinpath(PACKAGE_DIR, "data", "matpower", "case5_re.m"),
        build_function = build_matpower_case5_re_sys,
    ),
    SystemDescriptor(
        name = "matpower_case5_th_intid_sys",
        description = "Matpower Test system",
        category = MatPowerTestSystems,
        raw_data = joinpath(PACKAGE_DIR, "data", "matpower", "case5_th_intid.m"),
        build_function = build_matpower_case5_th_intid_sys,
    ),
    SystemDescriptor(
        name = "matpower_case5_tnep_sys",
        description = "Matpower Test system",
        category = MatPowerTestSystems,
        raw_data = joinpath(PACKAGE_DIR, "data", "matpower", "case5_tnep.m"),
        build_function = build_matpower_case5_tnep_sys,
    ),
    SystemDescriptor(
        name = "matpower_case5_sys",
        description = "Matpower Test system",
        category = MatPowerTestSystems,
        raw_data = joinpath(PACKAGE_DIR, "data", "matpower", "case5.m"),
        build_function = build_matpower_case5_sys,
    ),
    SystemDescriptor(
        name = "matpower_case6_sys",
        description = "Matpower Test system",
        category = MatPowerTestSystems,
        raw_data = joinpath(PACKAGE_DIR, "data", "matpower", "case6.m"),
        build_function = build_matpower_case6_sys,
    ),
    SystemDescriptor(
        name = "matpower_case7_tplgy_sys",
        description = "Matpower Test system",
        category = MatPowerTestSystems,
        raw_data = joinpath(PACKAGE_DIR, "data", "matpower", "case7_tplgy.m"),
        build_function = build_matpower_case7_tplgy_sys,
    ),
    SystemDescriptor(
        name = "matpower_case14_sys",
        description = "Matpower Test system",
        category = MatPowerTestSystems,
        raw_data = joinpath(PACKAGE_DIR, "data", "matpower", "case14.m"),
        build_function = build_matpower_case14_sys,
    ),
    SystemDescriptor(
        name = "matpower_case24_sys",
        description = "Matpower Test system",
        category = MatPowerTestSystems,
        raw_data = joinpath(PACKAGE_DIR, "data", "matpower", "case24.m"),
        build_function = build_matpower_case24_sys,
    ),
    SystemDescriptor(
        name = "matpower_case30_sys",
        description = "Matpower Test system",
        category = MatPowerTestSystems,
        raw_data = joinpath(PACKAGE_DIR, "data", "matpower", "case30.m"),
        build_function = build_matpower_case30_sys,
    ),
    SystemDescriptor(
        name = "matpower_frankenstein_00_sys",
        description = "Matpower Frankenstein Test system",
        category = MatPowerTestSystems,
        raw_data = joinpath(PACKAGE_DIR, "data", "matpower", "frankenstein_00.m"),
        build_function = build_matpower_frankenstein_00_sys,
    ),
    SystemDescriptor(
        name = "matpower_RTS_GMLC_sys",
        description = "Matpower RTS-GMLC Test system",
        category = MatPowerTestSystems,
        raw_data = joinpath(PACKAGE_DIR, "data", "matpower", "RTS_GMLC.m"),
        build_function = build_matpower_RTS_GMLC_sys,
    ),
    SystemDescriptor(
        name = "matpower_case5_strg_sys",
        description = "Matpower Test system",
        category = MatPowerTestSystems,
        raw_data = joinpath(PACKAGE_DIR, "data", "pm_data", "matpower", "case5_strg.m"),
        build_function = build_matpower_case5_strg_sys,
    ),
    SystemDescriptor(
        name = "pti_case3_sys",
        description = "PSSE 3-bus Test system",
        category = PSSETestSystems,
        raw_data = joinpath(PACKAGE_DIR, "data", "pm_data", "pti", "case3.raw"),
        build_function = build_pti_case3_sys,
    ),
    SystemDescriptor(
        name = "pti_case5_alc_sys",
        description = "PSSE 5-bus alc Test system",
        category = PSSETestSystems,
        raw_data = joinpath(PACKAGE_DIR, "data", "pm_data", "pti", "case5_alc.raw"),
        build_function = build_pti_case5_alc_sys,
    ),
    SystemDescriptor(
        name = "pti_case5_sys",
        description = "PSSE 5-bus Test system",
        category = PSSETestSystems,
        raw_data = joinpath(PACKAGE_DIR, "data", "pm_data", "pti", "case5.raw"),
        build_function = build_pti_case5_sys,
    ),
    SystemDescriptor(
        name = "pti_case7_tplgy_sys",
        description = "PSSE 7-bus Test system",
        category = PSSETestSystems,
        raw_data = joinpath(PACKAGE_DIR, "data", "pm_data", "pti", "case7_tplgy.raw"),
        build_function = build_pti_case7_tplgy_sys,
    ),
    SystemDescriptor(
        name = "pti_case14_sys",
        description = "PSSE 14-bus Test system",
        category = PSSETestSystems,
        raw_data = joinpath(PACKAGE_DIR, "data", "pm_data", "pti", "case14.raw"),
        build_function = build_pti_case14_sys,
    ),
    SystemDescriptor(
        name = "pti_case24_sys",
        description = "PSSE 24-bus Test system",
        category = PSSETestSystems,
        raw_data = joinpath(PACKAGE_DIR, "data", "pm_data", "pti", "case24.raw"),
        build_function = build_pti_case24_sys,
    ),
    SystemDescriptor(
        name = "pti_case30_sys",
        description = "PSSE 30-bus Test system",
        category = PSSETestSystems,
        raw_data = joinpath(PACKAGE_DIR, "data", "pm_data", "pti", "case30.raw"),
        build_function = build_pti_case30_sys,
    ),
    SystemDescriptor(
        name = "pti_case73_sys",
        description = "PSSE 73-bus Test system",
        category = PSSETestSystems,
        raw_data = joinpath(PACKAGE_DIR, "data", "pm_data", "pti", "case73.raw"),
        build_function = build_pti_case73_sys,
    ),
    SystemDescriptor(
        name = "pti_frankenstein_00_2_sys",
        description = "PSSE frankenstein Test system",
        category = PSSETestSystems,
        raw_data = joinpath(PACKAGE_DIR, "data", "pm_data", "pti", "frankenstein_00_2.raw"),
        build_function = build_pti_frankenstein_00_2_sys,
    ),
    SystemDescriptor(
        name = "pti_frankenstein_00_sys",
        description = "PSSE frankenstein Test system",
        category = PSSETestSystems,
        raw_data = joinpath(PACKAGE_DIR, "data", "pm_data", "pti", "frankenstein_00.raw"),
        build_function = build_pti_frankenstein_00_sys,
    ),
    SystemDescriptor(
        name = "pti_frankenstein_20_sys",
        description = "PSSE frankenstein Test system",
        category = PSSETestSystems,
        raw_data = joinpath(PACKAGE_DIR, "data", "pm_data", "pti", "frankenstein_20.raw"),
        build_function = build_pti_frankenstein_20_sys,
    ),
    SystemDescriptor(
        name = "pti_frankenstein_70_sys",
        description = "PSSE frankenstein Test system",
        category = PSSETestSystems,
        raw_data = joinpath(PACKAGE_DIR, "data", "pm_data", "pti", "frankenstein_70.raw"),
        build_function = build_pti_frankenstein_70_sys,
    ),
    SystemDescriptor(
        name = "pti_parser_test_a_sys",
        description = "PSSE Test system",
        category = PSSETestSystems,
        raw_data = joinpath(PACKAGE_DIR, "data", "pm_data", "pti", "parser_test_a.raw"),
        build_function = build_pti_parser_test_a_sys,
    ),
    # SystemDescriptor(
    #     name =  "pti_parser_test_b_sys",
    #     description =  "PSSE Test system",
    #     category =  PSSETestSystems,
    #     raw_data =  joinpath(PACKAGE_DIR, "data", "pm_data", "pti", "parser_test_b.raw"),
    #     build_function  =  build_pti_parser_test_b_sys
    # ),
    # SystemDescriptor(
    #     name =  "pti_parser_test_c_sys",
    #     description =  "PSSE Test system",
    #     category =  PSSETestSystems,
    #     raw_data =  joinpath(PACKAGE_DIR, "data", "pm_data", "pti", "parser_test_c.raw"),
    #     build_function  =  build_pti_parser_test_c_sys
    # ),
    # SystemDescriptor(
    #     name =  "pti_parser_test_d_sys",
    #     description =  "PSSE Test system",
    #     category =  PSSETestSystems,
    #     raw_data =  joinpath(PACKAGE_DIR, "data", "pm_data", "pti", "parser_test_d.raw"),
    #     build_function  =  build_pti_parser_test_d_sys
    # ),
    # SystemDescriptor(
    #     name =  "pti_parser_test_e_sys",
    #     description =  "PSSE Test system",
    #     category =  PSSETestSystems,
    #     raw_data =  joinpath(PACKAGE_DIR, "data", "pm_data", "pti", "parser_test_e.raw"),
    #     build_function  =  build_pti_parser_test_e_sys
    # ),
    # SystemDescriptor(
    #     name =  "pti_parser_test_f_sys",
    #     description =  "PSSE Test system",
    #     category =  PSSETestSystems,
    #     raw_data =  joinpath(PACKAGE_DIR, "data", "pm_data", "pti", "parser_test_f.raw"),
    #     build_function  =  build_pti_parser_test_f_sys
    # ),
    # SystemDescriptor(
    #     name =  "pti_parser_test_g_sys",
    #     description =  "PSSE Test system",
    #     category =  PSSETestSystems,
    #     raw_data =  joinpath(PACKAGE_DIR, "data", "pm_data", "pti", "parser_test_g.raw"),
    #     build_function  =  build_pti_parser_test_g_sys
    # ),
    # SystemDescriptor(
    #     name =  "pti_parser_test_h_sys",
    #     description =  "PSSE Test system",
    #     category =  PSSETestSystems,
    #     raw_data =  joinpath(PACKAGE_DIR, "data", "pm_data", "pti", "parser_test_h.raw"),
    #     build_function  =  build_pti_parser_test_h_sys
    # ),
    # SystemDescriptor(
    #     name =  "pti_parser_test_i_sys",
    #     description =  "PSSE Test system",
    #     category =  PSSETestSystems,
    #     raw_data =  joinpath(PACKAGE_DIR, "data", "pm_data", "pti", "parser_test_i.raw"),
    #     build_function  =  build_pti_parser_test_i_sys
    # ),
    # SystemDescriptor(
    #     name =  "pti_parser_test_j_sys",
    #     description =  "PSSE Test system",
    #     category =  PSSETestSystems,
    #     raw_data =  joinpath(PACKAGE_DIR, "data", "pm_data", "pti", "parser_test_j.raw"),
    #     build_function  =  build_pti_parser_test_j_sys
    # ),
    SystemDescriptor(
        name = "pti_three_winding_mag_test_sys",
        description = "PSSE Test system",
        category = PSSETestSystems,
        raw_data = joinpath(
            PACKAGE_DIR,
            "data",
            "pm_data",
            "pti",
            "three_winding_mag_test.raw",
        ),
        build_function = build_pti_three_winding_mag_test_sys,
    ),
    SystemDescriptor(
        name = "pti_three_winding_test_2_sys",
        description = "PSSE Test system",
        category = PSSETestSystems,
        raw_data = joinpath(
            PACKAGE_DIR,
            "data",
            "pm_data",
            "pti",
            "three_winding_test_2.raw",
        ),
        build_function = build_pti_three_winding_test_2_sys,
    ),
    SystemDescriptor(
        name = "pti_three_winding_test_sys",
        description = "PSSE Test system",
        category = PSSETestSystems,
        raw_data = joinpath(
            PACKAGE_DIR,
            "data",
            "pm_data",
            "pti",
            "three_winding_test.raw",
        ),
        build_function = build_pti_three_winding_test_sys,
    ),
    SystemDescriptor(
        name = "pti_two_winding_mag_test_sys",
        description = "PSSE Test system",
        category = PSSETestSystems,
        raw_data = joinpath(
            PACKAGE_DIR,
            "data",
            "pm_data",
            "pti",
            "two_winding_mag_test.raw",
        ),
        build_function = build_pti_two_winding_mag_test_sys,
    ),
    SystemDescriptor(
        name = "pti_two_terminal_hvdc_test_sys",
        description = "PSSE Test system",
        category = PSSETestSystems,
        raw_data = joinpath(
            PACKAGE_DIR,
            "data",
            "pm_data",
            "pti",
            "two-terminal-hvdc_test.raw",
        ),
        build_function = build_pti_two_terminal_hvdc_test_sys,
    ),
    SystemDescriptor(
        name = "pti_vsc_hvdc_test_sys",
        description = "PSSE Test system",
        category = PSSETestSystems,
        raw_data = joinpath(PACKAGE_DIR, "data", "pm_data", "pti", "vsc-hvdc_test.raw"),
        build_function = build_pti_vsc_hvdc_test_sys,
    ),
    SystemDescriptor(
        name = "psse_Benchmark_4ger_33_2015_sys",
        description = "PSSE Benchmark system",
        category = PSSETestSystems,
        raw_data = joinpath(PACKAGE_DIR, "data"),
        build_function = build_psse_Benchmark_4ger_33_2015_sys,
    ),
    SystemDescriptor(
        name = "psse_OMIB_sys",
        description = "PSSE OMIB Test system",
        category = PSSETestSystems,
        raw_data = joinpath(PACKAGE_DIR, "data"),
        build_function = build_psse_OMIB_sys,
    ),
    SystemDescriptor(
        name = "psse_3bus_gen_cls_sys",
        description = "PSSE 3-bus Test system with CLS",
        category = PSSETestSystems,
        raw_data = joinpath(PACKAGE_DIR, "data", "PSSE_test"),
        build_function = build_psse_3bus_gen_cls_sys,
    ),
    SystemDescriptor(
        name = "psse_3bus_SEXS_sys",
        description = "PSSE 3-bus Test system with SEXS",
        category = PSSETestSystems,
        raw_data = joinpath(PACKAGE_DIR, "data", "PSSE_test"),
        build_function = build_psse_3bus_sexs_sys,
    ),
    SystemDescriptor(
        name = "psse_240_case_renewable_sys",
        description = "PSSE 240 Bus Case system with Renewables https://www.nrel.gov/grid/test-case-repository.html",
        category = PSSETestSystems,
        raw_data = joinpath(PACKAGE_DIR, "data", "PSSE_test"),
        build_function = build_psse_240_case_renewable_sys,
    ),
    SystemDescriptor(
        name = "psse_3bus_no_cls_sys",
        description = "PSSE 3-bus Test system without CLS",
        category = PSSETestSystems,
        raw_data = joinpath(PACKAGE_DIR, "data", "PSSE_test"),
        build_function = build_psse_3bus_no_cls_sys,
    ),
    SystemDescriptor(
        name = "psse_renewable_parsing_1",
        description = "PSSE 3-bus Test system with REPCA, REECB and REGCA",
        category = PSSETestSystems,
        raw_data = joinpath(PACKAGE_DIR, "data", "PSSE_test"),
        build_function = psse_renewable_parsing_1,
    ),
    SystemDescriptor(
        name = "dynamic_inverter_sys",
        description = "PSY test dynamic inverter system",
        category = PSYTestSystems,
        raw_data = "",
        build_function = build_dynamic_inverter_sys,
    ),
    SystemDescriptor(
        name = "c_sys5_bat_ems",
        description = "5-bus system with Storage Device with EMS",
        category = PSITestSystems,
        raw_data = "data/data_5bus_pu.jl",
        build_function = build_c_sys5_bat_ems,
    ),
    SystemDescriptor(
        name = "c_sys5_pglib_sim",
        description = "5-bus with ThermalMultiStart for simulation",
        category = PSITestSystems,
        raw_data = "data/data_5bus_pu.jl",
        build_function = build_c_sys5_pglib_sim,
    ),
    SystemDescriptor(
        name = "c_sys5_hybrid",
        description = "5-bus system with Hybrid devices",
        category = PSITestSystems,
        raw_data = "data/data_5bus_pu.jl",
        build_function = build_c_sys5_hybrid,
    ),
    SystemDescriptor(
        name = "c_sys5_hybrid_uc",
        description = "5-bus system with Hybrid devices and thermal UC devices",
        category = PSITestSystems,
        raw_data = "data/data_5bus_pu.jl",
        build_function = build_c_sys5_hybrid_uc,
    ),
    SystemDescriptor(
        name = "5_bus_matpower_DA",
        description = "matpower 5-bus system with DA time series",
        category = SIIPExampleSystems,
        raw_data = joinpath(PACKAGE_DIR, "data", "matpower", "case5_re_uc.m"),
        build_function = build_5_bus_matpower_DA,
    ),
    SystemDescriptor(
        name = "5_bus_matpower_RT",
        description = "matpower 5-bus system with RT time series",
        category = SIIPExampleSystems,
        raw_data = joinpath(PACKAGE_DIR, "data", "matpower", "case5_re_uc.m"),
        build_function = build_5_bus_matpower_RT,
    ),
    SystemDescriptor(
        name = "5_bus_matpower_AGC",
        description = "matpower 5-bus system with AGC time series",
        category = SIIPExampleSystems,
        raw_data = joinpath(PACKAGE_DIR, "data", "matpower", "case5_re_uc.m"),
        build_function = build_5_bus_matpower_AGC,
    ),
    SystemDescriptor(
        name = "hydro_test_case_c_sys",
        description = "test system for HydroGen Energy Target formulation(case-c)",
        category = PSITestSystems,
        raw_data = "data/data_5bus_pu.jl",
        build_function = build_hydro_test_case_c_sys,
    ),
    SystemDescriptor(
        name = "hydro_test_case_b_sys",
        description = "test system for HydroGen Energy Target formulation(case-b)",
        category = PSITestSystems,
        raw_data = "data/data_5bus_pu.jl",
        build_function = build_hydro_test_case_b_sys,
    ),
    SystemDescriptor(
        name = "hydro_test_case_d_sys",
        description = "test system for HydroGen Energy Target formulation(case-d)",
        category = PSITestSystems,
        raw_data = "data/data_5bus_pu.jl",
        build_function = build_hydro_test_case_d_sys,
    ),
    SystemDescriptor(
        name = "hydro_test_case_e_sys",
        description = "test system for HydroGen Energy Target formulation(case-e)",
        category = PSITestSystems,
        raw_data = "data/data_5bus_pu.jl",
        build_function = build_hydro_test_case_e_sys,
    ),
    SystemDescriptor(
        name = "hydro_test_case_f_sys",
        description = "test system for HydroGen  Energy Target formulation(case-f)",
        category = PSITestSystems,
        raw_data = "data/data_5bus_pu.jl",
        build_function = build_hydro_test_case_f_sys,
    ),
    SystemDescriptor(
        name = "batt_test_case_b_sys",
        description = "test system for Storage Energy Target formulation(case-b)",
        category = PSITestSystems,
        raw_data = "data/data_5bus_pu.jl",
        build_function = build_batt_test_case_b_sys,
    ),
    SystemDescriptor(
        name = "batt_test_case_d_sys",
        description = "test system for Storage Energy Target formulation(case-d)",
        category = PSITestSystems,
        raw_data = "data/data_5bus_pu.jl",
        build_function = build_batt_test_case_d_sys,
    ),
    SystemDescriptor(
        name = "batt_test_case_c_sys",
        description = "test system for Storage Energy Target formulation(case-c)",
        category = PSITestSystems,
        raw_data = "data/data_5bus_pu.jl",
        build_function = build_batt_test_case_c_sys,
    ),
    SystemDescriptor(
        name = "batt_test_case_e_sys",
        description = "test system for Storage Energy Target formulation(case-e)",
        category = PSITestSystems,
        raw_data = "data/data_5bus_pu.jl",
        build_function = build_batt_test_case_e_sys,
    ),
    SystemDescriptor(
        name = "batt_test_case_f_sys",
        description = "test system for Storage Energy Target formulation(case-f)",
        category = PSITestSystems,
        raw_data = "data/data_5bus_pu.jl",
        build_function = build_batt_test_case_f_sys,
    ),
]


text:
JProperties = @jimport java.util.Properties

#Wrapper
type Properties
    jproperties::JProperties
end

#Constructors
##key, value argument
function Properties(key::AbstractString, value::AbstractString)
    jproperties = JProperties(())
    jcall(jproperties, "setProperty", JObject, (JString, JString), key, value)
    return Properties(jproperties)
end

##Dictionary argument
function Properties(d::Dict{String, String})
    jproperties = JProperties(())
    for (k, v) in d
        jcall(jproperties, "setProperty", JObject, (JString, JString), k, v)
    end
    return Properties(jproperties)
end

##Value-only argument. Key defaults to "annotators"
function Properties(value::AbstractString)
    return Properties("annotators", value)
end

#Convenience methods
##Returns a string 'val' corresponding to property 'key'
function get_property(jprops::JProperties, key::AbstractString)
    return jcall(jprops, "getProperty", JString, (JString,), key)
end

##'key' defaults to "annotators"
function get_property(jprops::JProperties)
    return jcall(jprops, "getProperty", JString, (JString,), "annotators")
end

#=
#set_property: Methods for setting properties of a JProperties object.
#All return a JProperties object.

##key, value argument.
function set_property(key::AbstractString, value::AbstractString)
    jprops = JProperties(())
    jcall(jprops, "setProperty", JObject, (JString, JString), key, value)
    return jprops
end

##Dict argument
function set_property(d::Dict{String, String})
    jprops = JProperties(())
    for (k, v) in d
        jcall(jprops, "setProperty", JObject, (JString, JString), k, v)
    end
    return jprops
end

##value-only argument. key defaults to "annotators"
function set_property(value::AbstractString)
    set_property("annotators", value)
end

#Returns the value corresponding to 'key' in the JProperties object argument.
#Returns a string of the 'key' property in jprops::JProperties.
#Usage: value = get_property(jprops, key)
function get_property(jprops::JProperties, key::AbstractString)
    return jcall(jprops, "getProperty", JString, (JString,), key)
end

#Returns a string of the 'annotators' property in jprops::JProperties.
#Usage: annotators = get_annotators(jprops)
function get_annotators(jprops::JProperties)
    return jcall(jprops, "getProperty", JString, (JString,), "annotators")
end

#function set_property(jprops::JProperties, key::AbstractString, value::AbstractString)
#    jcall(jprops, "setProperty", JObject, (JString, JString), key, value)
#end

#=
function to_jprops(d::Dict{String, String})
    jprops = JProperties(())
    for (k, v) in d
        set_property(jprops, k, v)
    end
    return jprops
end
=#


text:
module StreamRequest

using ..IOExtras
using ..Messages
using ..Streams
import ..ConnectionPool
using ..MessageRequest
import ..RedirectRequest: nredirects
import ..@debug, ..DEBUG_LEVEL, ..printlncompact, ..sprintcompact

export streamlayer

"""
    streamlayer(stream) -> HTTP.Response

Create a [`Stream`](@ref) to send a `Request` and `body` to an `IO`
stream and read the response.

Send the `Request` body in a background task and begins reading the response
immediately so that the transmission can be aborted if the `Response` status
indicates that the server does not wish to receive the message body.
[RFC7230 6.5](https://tools.ietf.org/html/rfc7230#section-6.5).
"""
function streamlayer(stream::Stream; iofunction=nothing, verbose=0, redirect_limit::Int=3, kw...)::Response
    response = stream.message
    req = response.request
    io = stream.stream
    verbose == 1 && printlncompact(req)
    @debug 2 "client startwrite"
    startwrite(stream)

    if verbose == 2
        println(req)
        if iofunction === nothing && !isbytes(req.body)
            println("$(typeof(req)).body: $(sprintcompact(req.body))")
        end
    end

    write_error = nothing
    try
        @sync begin
            if iofunction === nothing
                @async try
                    writebody(stream, req)
                    @debug 2 "client closewrite"
                    closewrite(stream)
                catch e
                    write_error = e
                    isopen(io) && try; close(io); catch; end
                end
                @debug 2 "client startread"
                startread(stream)
                readbody(stream, response, redirect_limit == nredirects(req))
            else
                iofunction(stream)
            end
            if isaborted(stream)
                # The server may have closed the connection.
                # Don't propagate such errors.
                try; close(io); catch; end
            end
        end
    catch e
        if write_error !== nothing
            throw(write_error)
        else
            rethrow(e)
        end
    end

    @debug 2 "client closewrite"
    closewrite(stream)
    @debug 2 "client closeread"
    closeread(stream)

    verbose == 1 && printlncompact(response)
    verbose == 2 && println(response)

    return response
end

function writebody(stream::Stream, req::Request)

    if !isbytes(req.body)
        writebodystream(stream, req.body)
        closebody(stream)
    else
        write(stream, req.body)
    end
    req.context[:retrycount] = get(req.context, :retrycount, 0) + 1
    return
end

function writebodystream(stream, body)
    for chunk in body
        writechunk(stream, chunk)
    end
end

function writebodystream(stream, body::IO)
    write(stream, body)
end

writechunk(stream, body::IO) = writebodystream(stream, body)
writechunk(stream, body) = write(stream, body)

function readbody(stream::Stream, res::Response, redirectlimitreached)
    if isbytes(res.body)
        res.body = read(stream)
    else
        if redirectlimitreached || !isredirect(res)
            write(res.body, stream)
        end
    end
end

end # module StreamRequest