text:
#=
This file is auto-generated. Do not edit.
=#

#! format: off

"""
    mutable struct ReactiveRenewableControllerAB <: ReactivePowerControl
        bus_control::Int
        from_branch_control::Int
        to_branch_control::Int
        branch_id_control::String
        VC_Flag::Int
        Ref_Flag::Int
        PF_Flag::Int
        V_Flag::Int
        T_fltr::Float64
        K_p::Float64
        K_i::Float64
        T_ft::Float64
        T_fv::Float64
        V_frz::Float64
        R_c::Float64
        X_c::Float64
        K_c::Float64
        e_lim::NamedTuple{(:min, :max), Tuple{Float64, Float64}}
        dbd_pnts::Tuple{Float64, Float64}
        Q_lim::NamedTuple{(:min, :max), Tuple{Float64, Float64}}
        T_p::Float64
        Q_lim_inner::NamedTuple{(:min, :max), Tuple{Float64, Float64}}
        V_lim::NamedTuple{(:min, :max), Tuple{Float64, Float64}}
        K_qp::Float64
        K_qi::Float64
        Q_ref::Float64
        V_ref::Float64
        ext::Dict{String, Any}
        states::Vector{Symbol}
        n_states::Int
    end

Parameters of Reactive Power Controller including REPCA1 and REECB1

# Arguments
- `bus_control::Int`: Bus Number for voltage control; , validation range: `(0, nothing)`
- `from_branch_control::Int`: Monitored branch FROM bus number for line drop compensation (if 0 generator power will be used), validation range: `(0, nothing)`
- `to_branch_control::Int`: Monitored branch TO bus number for line drop compensation (if 0 generator power will be used), validation range: `(0, nothing)`
- `branch_id_control::String`: Branch circuit id for line drop compensation (as a string). If 0 generator power will be used
- `VC_Flag::Int`: Voltage Compensator Flag for REPCA1, validation range: `(0, 1)`
- `Ref_Flag::Int`: Flag for Reactive Power Control for REPCA1. 0: Q-control, 1: V-control, validation range: `(0, 1)`
- `PF_Flag::Int`: Flag for Power Factor Control for Outer Control of REECB1. 0: Q-control, 1: Power Factor Control, validation range: `(0, 1)`
- `V_Flag::Int`: Flag for Voltage Control for Outer Control of REECB1. 0: Voltage Control, 1: Q-Control, validation range: `(0, 1)`
- `T_fltr::Float64`: Voltage or Q-power of REPCA Filter Time Constant, validation range: `(0, nothing)`
- `K_p::Float64`: Reactive power PI control proportional gain, validation range: `(0, nothing)`
- `K_i::Float64`: Reactive power PI control integral gain, validation range: `(0, nothing)`
- `T_ft::Float64`: Reactive power lead time constant (s), validation range: `(0, nothing)`
- `T_fv::Float64`: Reactive power lag time constant (s), validation range: `(0, nothing)`
- `V_frz::Float64`: Voltage below which state ξq_oc (integrator state) is freeze, validation range: `(0, nothing)`
- `R_c::Float64`: Line drop compensation resistance (used when VC_Flag = 1), validation range: `(0, nothing)`
- `X_c::Float64`: Line drop compensation reactance (used when VC_Flag = 1), validation range: `(0, nothing)`
- `K_c::Float64`: Reactive current compensation gain (pu) (used when VC_Flag = 0), validation range: `(0, nothing)`
- `e_lim::NamedTuple{(:min, :max), Tuple{Float64, Float64}}`: Upper/Lower limit on Voltage or Q-power deadband output `(e_min, e_max)`
- `dbd_pnts::Tuple{Float64, Float64}`: Voltage or Q-power error dead band thresholds `(dbd1, dbd2)`
- `Q_lim::NamedTuple{(:min, :max), Tuple{Float64, Float64}}`: Upper/Lower limit on reactive power V/Q control in REPCA `(Q_min, Q_max)`
- `T_p::Float64`: Active power lag time constant in REECB (s). Used only when PF_Flag = 1, validation range: `(0, nothing)`
- `Q_lim_inner::NamedTuple{(:min, :max), Tuple{Float64, Float64}}`: Upper/Lower limit on reactive power input in REECB `(Q_min_inner, Q_max_inner)`. Only used when V_Flag = 1
- `V_lim::NamedTuple{(:min, :max), Tuple{Float64, Float64}}`: Upper/Lower limit on reactive power PI controller in REECB `(V_min, V_max)`. Only used when V_Flag = 1
- `K_qp::Float64`: Reactive power regulator proportional gain (used when V_Flag = 1), validation range: `(0, nothing)`
- `K_qi::Float64`: Reactive power regulator integral gain (used when V_Flag = 1), validation range: `(0, nothing)`
- `Q_ref::Float64`: Reference Power Set-point, validation range: `(0, nothing)`
- `V_ref::Float64`: Reference Voltage Set-point, validation range: `(0, nothing)`
- `ext::Dict{String, Any}`
- `states::Vector{Symbol}`: The states of the ReactiveRenewableControllerAB model depends on the Flag
- `n_states::Int`: The states of the ReactiveRenewableControllerAB model depends on the Flag
"""
mutable struct ReactiveRenewableControllerAB <: ReactivePowerControl
    "Bus Number for voltage control; "
    bus_control::Int
    "Monitored branch FROM bus number for line drop compensation (if 0 generator power will be used)"
    from_branch_control::Int
    "Monitored branch TO bus number for line drop compensation (if 0 generator power will be used)"
    to_branch_control::Int
    "Branch circuit id for line drop compensation (as a string). If 0 generator power will be used"
    branch_id_control::String
    "Voltage Compensator Flag for REPCA1"
    VC_Flag::Int
    "Flag for Reactive Power Control for REPCA1. 0: Q-control, 1: V-control"
    Ref_Flag::Int
    "Flag for Power Factor Control for Outer Control of REECB1. 0: Q-control, 1: Power Factor Control"
    PF_Flag::Int
    "Flag for Voltage Control for Outer Control of REECB1. 0: Voltage Control, 1: Q-Control"
    V_Flag::Int
    "Voltage or Q-power of REPCA Filter Time Constant"
    T_fltr::Float64
    "Reactive power PI control proportional gain"
    K_p::Float64
    "Reactive power PI control integral gain"
    K_i::Float64
    "Reactive power lead time constant (s)"
    T_ft::Float64
    "Reactive power lag time constant (s)"
    T_fv::Float64
    "Voltage below which state ξq_oc (integrator state) is freeze"
    V_frz::Float64
    "Line drop compensation resistance (used when VC_Flag = 1)"
    R_c::Float64
    "Line drop compensation reactance (used when VC_Flag = 1)"
    X_c::Float64
    "Reactive current compensation gain (pu) (used when VC_Flag = 0)"
    K_c::Float64
    "Upper/Lower limit on Voltage or Q-power deadband output `(e_min, e_max)`"
    e_lim::NamedTuple{(:min, :max), Tuple{Float64, Float64}}
    "Voltage or Q-power error dead band thresholds `(dbd1, dbd2)`"
    dbd_pnts::Tuple{Float64, Float64}
    "Upper/Lower limit on reactive power V/Q control in REPCA `(Q_min, Q_max)`"
    Q_lim::NamedTuple{(:min, :max), Tuple{Float64, Float64}}
    "Active power lag time constant in REECB (s). Used only when PF_Flag = 1"
    T_p::Float64
    "Upper/Lower limit on reactive power input in REECB `(Q_min_inner, Q_max_inner)`. Only used when V_Flag = 1"
    Q_lim_inner::NamedTuple{(:min, :max), Tuple{Float64, Float64}}
    "Upper/Lower limit on reactive power PI controller in REECB `(V_min, V_max)`. Only used when V_Flag = 1"
    V_lim::NamedTuple{(:min, :max), Tuple{Float64, Float64}}
    "Reactive power regulator proportional gain (used when V_Flag = 1)"
    K_qp::Float64
    "Reactive power regulator integral gain (used when V_Flag = 1)"
    K_qi::Float64
    "Reference Power Set-point"
    Q_ref::Float64
    "Reference Voltage Set-point"
    V_ref::Float64
    ext::Dict{String, Any}
    "The states of the ReactiveRenewableControllerAB model depends on the Flag"
    states::Vector{Symbol}
    "The states of the ReactiveRenewableControllerAB model depends on the Flag"
    n_states::Int
end

function ReactiveRenewableControllerAB(bus_control, from_branch_control, to_branch_control, branch_id_control, VC_Flag, Ref_Flag, PF_Flag, V_Flag, T_fltr, K_p, K_i, T_ft, T_fv, V_frz, R_c, X_c, K_c, e_lim, dbd_pnts, Q_lim, T_p, Q_lim_inner, V_lim, K_qp, K_qi, Q_ref=1.0, V_ref=1.0, ext=Dict{String, Any}(), )
    ReactiveRenewableControllerAB(bus_control, from_branch_control, to_branch_control, branch_id_control, VC_Flag, Ref_Flag, PF_Flag, V_Flag, T_fltr, K_p, K_i, T_ft, T_fv, V_frz, R_c, X_c, K_c, e_lim, dbd_pnts, Q_lim, T_p, Q_lim_inner, V_lim, K_qp, K_qi, Q_ref, V_ref, ext, PowerSystems.get_reactiveRETypeAB_states(Ref_Flag, PF_Flag, V_Flag)[1], PowerSystems.get_reactiveRETypeAB_states(Ref_Flag, PF_Flag, V_Flag)[2], )
end

function ReactiveRenewableControllerAB(; bus_control, from_branch_control, to_branch_control, branch_id_control, VC_Flag, Ref_Flag, PF_Flag, V_Flag, T_fltr, K_p, K_i, T_ft, T_fv, V_frz, R_c, X_c, K_c, e_lim, dbd_pnts, Q_lim, T_p, Q_lim_inner, V_lim, K_qp, K_qi, Q_ref=1.0, V_ref=1.0, ext=Dict{String, Any}(), states=PowerSystems.get_reactiveRETypeAB_states(Ref_Flag, PF_Flag, V_Flag)[1], n_states=PowerSystems.get_reactiveRETypeAB_states(Ref_Flag, PF_Flag, V_Flag)[2], )
    ReactiveRenewableControllerAB(bus_control, from_branch_control, to_branch_control, branch_id_control, VC_Flag, Ref_Flag, PF_Flag, V_Flag, T_fltr, K_p, K_i, T_ft, T_fv, V_frz, R_c, X_c, K_c, e_lim, dbd_pnts, Q_lim, T_p, Q_lim_inner, V_lim, K_qp, K_qi, Q_ref, V_ref, ext, states, n_states, )
end

# Constructor for demo purposes; non-functional.
function ReactiveRenewableControllerAB(::Nothing)
    ReactiveRenewableControllerAB(;
        bus_control=0,
        from_branch_control=0,
        to_branch_control=0,
        branch_id_control="0",
        VC_Flag=0,
        Ref_Flag=0,
        PF_Flag=0,
        V_Flag=0,
        T_fltr=0,
        K_p=0,
        K_i=0,
        T_ft=0,
        T_fv=0,
        V_frz=0,
        R_c=0,
        X_c=0,
        K_c=0,
        e_lim=(min=0.0, max=0.0),
        dbd_pnts=(0.0, 0.0),
        Q_lim=(min=0.0, max=0.0),
        T_p=0,
        Q_lim_inner=(min=0.0, max=0.0),
        V_lim=(min=0.0, max=0.0),
        K_qp=0,
        K_qi=0,
        Q_ref=0,
        V_ref=0,
        ext=Dict{String, Any}(),
    )
end

"""Get [`ReactiveRenewableControllerAB`](@ref) `bus_control`."""
get_bus_control(value::ReactiveRenewableControllerAB) = value.bus_control
"""Get [`ReactiveRenewableControllerAB`](@ref) `from_branch_control`."""
get_from_branch_control(value::ReactiveRenewableControllerAB) = value.from_branch_control
"""Get [`ReactiveRenewableControllerAB`](@ref) `to_branch_control`."""
get_to_branch_control(value::ReactiveRenewableControllerAB) = value.to_branch_control
"""Get [`ReactiveRenewableControllerAB`](@ref) `branch_id_control`."""
get_branch_id_control(value::ReactiveRenewableControllerAB) = value.branch_id_control
"""Get [`ReactiveRenewableControllerAB`](@ref) `VC_Flag`."""
get_VC_Flag(value::ReactiveRenewableControllerAB) = value.VC_Flag
"""Get [`ReactiveRenewableControllerAB`](@ref) `Ref_Flag`."""
get_Ref_Flag(value::ReactiveRenewableControllerAB) = value.Ref_Flag
"""Get [`ReactiveRenewableControllerAB`](@ref) `PF_Flag`."""
get_PF_Flag(value::ReactiveRenewableControllerAB) = value.PF_Flag
"""Get [`ReactiveRenewableControllerAB`](@ref) `V_Flag`."""
get_V_Flag(value::ReactiveRenewableControllerAB) = value.V_Flag
"""Get [`ReactiveRenewableControllerAB`](@ref) `T_fltr`."""
get_T_fltr(value::ReactiveRenewableControllerAB) = value.T_fltr
"""Get [`ReactiveRenewableControllerAB`](@ref) `K_p`."""
get_K_p(value::ReactiveRenewableControllerAB) = value.K_p
"""Get [`ReactiveRenewableControllerAB`](@ref) `K_i`."""
get_K_i(value::ReactiveRenewableControllerAB) = value.K_i
"""Get [`ReactiveRenewableControllerAB`](@ref) `T_ft`."""
get_T_ft(value::ReactiveRenewableControllerAB) = value.T_ft
"""Get [`ReactiveRenewableControllerAB`](@ref) `T_fv`."""
get_T_fv(value::ReactiveRenewableControllerAB) = value.T_fv
"""Get [`ReactiveRenewableControllerAB`](@ref) `V_frz`."""
get_V_frz(value::ReactiveRenewableControllerAB) = value.V_frz
"""Get [`ReactiveRenewableControllerAB`](@ref) `R_c`."""
get_R_c(value::ReactiveRenewableControllerAB) = value.R_c
"""Get [`ReactiveRenewableControllerAB`](@ref) `X_c`."""
get_X_c(value::ReactiveRenewableControllerAB) = value.X_c
"""Get [`ReactiveRenewableControllerAB`](@ref) `K_c`."""
get_K_c(value::ReactiveRenewableControllerAB) = value.K_c
"""Get [`ReactiveRenewableControllerAB`](@ref) `e_lim`."""
get_e_lim(value::ReactiveRenewableControllerAB) = value.e_lim
"""Get [`ReactiveRenewableControllerAB`](@ref) `dbd_pnts`."""
get_dbd_pnts(value::ReactiveRenewableControllerAB) = value.dbd_pnts
"""Get [`ReactiveRenewableControllerAB`](@ref) `Q_lim`."""
get_Q_lim(value::ReactiveRenewableControllerAB) = value.Q_lim
"""Get [`ReactiveRenewableControllerAB`](@ref) `T_p`."""
get_T_p(value::ReactiveRenewableControllerAB) = value.T_p
"""Get [`ReactiveRenewableControllerAB`](@ref) `Q_lim_inner`."""
get_Q_lim_inner(value::ReactiveRenewableControllerAB) = value.Q_lim_inner
"""Get [`ReactiveRenewableControllerAB`](@ref) `V_lim`."""
get_V_lim(value::ReactiveRenewableControllerAB) = value.V_lim
"""Get [`ReactiveRenewableControllerAB`](@ref) `K_qp`."""
get_K_qp(value::ReactiveRenewableControllerAB) = value.K_qp
"""Get [`ReactiveRenewableControllerAB`](@ref) `K_qi`."""
get_K_qi(value::ReactiveRenewableControllerAB) = value.K_qi
"""Get [`ReactiveRenewableControllerAB`](@ref) `Q_ref`."""
get_Q_ref(value::ReactiveRenewableControllerAB) = value.Q_ref
"""Get [`ReactiveRenewableControllerAB`](@ref) `V_ref`."""
get_V_ref(value::ReactiveRenewableControllerAB) = value.V_ref
"""Get [`ReactiveRenewableControllerAB`](@ref) `ext`."""
get_ext(value::ReactiveRenewableControllerAB) = value.ext
"""Get [`ReactiveRenewableControllerAB`](@ref) `states`."""
get_states(value::ReactiveRenewableControllerAB) = value.states
"""Get [`ReactiveRenewableControllerAB`](@ref) `n_states`."""
get_n_states(value::ReactiveRenewableControllerAB) = value.n_states

"""Set [`ReactiveRenewableControllerAB`](@ref) `bus_control`."""
set_bus_control!(value::ReactiveRenewableControllerAB, val) = value.bus_control = val
"""Set [`ReactiveRenewableControllerAB`](@ref) `from_branch_control`."""
set_from_branch_control!(value::ReactiveRenewableControllerAB, val) = value.from_branch_control = val
"""Set [`ReactiveRenewableControllerAB`](@ref) `to_branch_control`."""
set_to_branch_control!(value::ReactiveRenewableControllerAB, val) = value.to_branch_control = val
"""Set [`ReactiveRenewableControllerAB`](@ref) `branch_id_control`."""
set_branch_id_control!(value::ReactiveRenewableControllerAB, val) = value.branch_id_control = val
"""Set [`ReactiveRenewableControllerAB`](@ref) `VC_Flag`."""
set_VC_Flag!(value::ReactiveRenewableControllerAB, val) = value.VC_Flag = val
"""Set [`ReactiveRenewableControllerAB`](@ref) `Ref_Flag`."""
set_Ref_Flag!(value::ReactiveRenewableControllerAB, val) = value.Ref_Flag = val
"""Set [`ReactiveRenewableControllerAB`](@ref) `PF_Flag`."""
set_PF_Flag!(value::ReactiveRenewableControllerAB, val) = value.PF_Flag = val
"""Set [`ReactiveRenewableControllerAB`](@ref) `V_Flag`."""
set_V_Flag!(value::ReactiveRenewableControllerAB, val) = value.V_Flag = val
"""Set [`ReactiveRenewableControllerAB`](@ref) `T_fltr`."""
set_T_fltr!(value::ReactiveRenewableControllerAB, val) = value.T_fltr = val
"""Set [`ReactiveRenewableControllerAB`](@ref) `K_p`."""
set_K_p!(value::ReactiveRenewableControllerAB, val) = value.K_p = val
"""Set [`ReactiveRenewableControllerAB`](@ref) `K_i`."""
set_K_i!(value::ReactiveRenewableControllerAB, val) = value.K_i = val
"""Set [`ReactiveRenewableControllerAB`](@ref) `T_ft`."""
set_T_ft!(value::ReactiveRenewableControllerAB, val) = value.T_ft = val
"""Set [`ReactiveRenewableControllerAB`](@ref) `T_fv`."""
set_T_fv!(value::ReactiveRenewableControllerAB, val) = value.T_fv = val
"""Set [`ReactiveRenewableControllerAB`](@ref) `V_frz`."""
set_V_frz!(value::ReactiveRenewableControllerAB, val) = value.V_frz = val
"""Set [`ReactiveRenewableControllerAB`](@ref) `R_c`."""
set_R_c!(value::ReactiveRenewableControllerAB, val) = value.R_c = val
"""Set [`ReactiveRenewableControllerAB`](@ref) `X_c`."""
set_X_c!(value::ReactiveRenewableControllerAB, val) = value.X_c = val
"""Set [`ReactiveRenewableControllerAB`](@ref) `K_c`."""
set_K_c!(value::ReactiveRenewableControllerAB, val) = value.K_c = val
"""Set [`ReactiveRenewableControllerAB`](@ref) `e_lim`."""
set_e_lim!(value::ReactiveRenewableControllerAB, val) = value.e_lim = val
"""Set [`ReactiveRenewableControllerAB`](@ref) `dbd_pnts`."""
set_dbd_pnts!(value::ReactiveRenewableControllerAB, val) = value.dbd_pnts = val
"""Set [`ReactiveRenewableControllerAB`](@ref) `Q_lim`."""
set_Q_lim!(value::ReactiveRenewableControllerAB, val) = value.Q_lim = val
"""Set [`ReactiveRenewableControllerAB`](@ref) `T_p`."""
set_T_p!(value::ReactiveRenewableControllerAB, val) = value.T_p = val
"""Set [`ReactiveRenewableControllerAB`](@ref) `Q_lim_inner`."""
set_Q_lim_inner!(value::ReactiveRenewableControllerAB, val) = value.Q_lim_inner = val
"""Set [`ReactiveRenewableControllerAB`](@ref) `V_lim`."""
set_V_lim!(value::ReactiveRenewableControllerAB, val) = value.V_lim = val
"""Set [`ReactiveRenewableControllerAB`](@ref) `K_qp`."""
set_K_qp!(value::ReactiveRenewableControllerAB, val) = value.K_qp = val
"""Set [`ReactiveRenewableControllerAB`](@ref) `K_qi`."""
set_K_qi!(value::ReactiveRenewableControllerAB, val) = value.K_qi = val
"""Set [`ReactiveRenewableControllerAB`](@ref) `Q_ref`."""
set_Q_ref!(value::ReactiveRenewableControllerAB, val) = value.Q_ref = val
"""Set [`ReactiveRenewableControllerAB`](@ref) `V_ref`."""
set_V_ref!(value::ReactiveRenewableControllerAB, val) = value.V_ref = val
"""Set [`ReactiveRenewableControllerAB`](@ref) `ext`."""
set_ext!(value::ReactiveRenewableControllerAB, val) = value.ext = val


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

mutable struct ResourceSku <: SwaggerModel
    resourceType::Any # spec type: Union{ Nothing, String } # spec name: resourceType
    name::Any # spec type: Union{ Nothing, String } # spec name: name
    tier::Any # spec type: Union{ Nothing, String } # spec name: tier
    size::Any # spec type: Union{ Nothing, String } # spec name: size
    family::Any # spec type: Union{ Nothing, String } # spec name: family
    kind::Any # spec type: Union{ Nothing, String } # spec name: kind
    capacity::Any # spec type: Union{ Nothing, ResourceSkuCapacity } # spec name: capacity
    locations::Any # spec type: Union{ Nothing, Vector{String} } # spec name: locations
    apiVersions::Any # spec type: Union{ Nothing, Vector{String} } # spec name: apiVersions
    costs::Any # spec type: Union{ Nothing, Vector{ResourceSkuCosts} } # spec name: costs
    capabilities::Any # spec type: Union{ Nothing, Vector{ResourceSkuCapabilities} } # spec name: capabilities
    restrictions::Any # spec type: Union{ Nothing, Vector{ResourceSkuRestrictions} } # spec name: restrictions

    function ResourceSku(;resourceType=nothing, name=nothing, tier=nothing, size=nothing, family=nothing, kind=nothing, capacity=nothing, locations=nothing, apiVersions=nothing, costs=nothing, capabilities=nothing, restrictions=nothing)
        o = new()
        validate_property(ResourceSku, Symbol("resourceType"), resourceType)
        setfield!(o, Symbol("resourceType"), resourceType)
        validate_property(ResourceSku, Symbol("name"), name)
        setfield!(o, Symbol("name"), name)
        validate_property(ResourceSku, Symbol("tier"), tier)
        setfield!(o, Symbol("tier"), tier)
        validate_property(ResourceSku, Symbol("size"), size)
        setfield!(o, Symbol("size"), size)
        validate_property(ResourceSku, Symbol("family"), family)
        setfield!(o, Symbol("family"), family)
        validate_property(ResourceSku, Symbol("kind"), kind)
        setfield!(o, Symbol("kind"), kind)
        validate_property(ResourceSku, Symbol("capacity"), capacity)
        setfield!(o, Symbol("capacity"), capacity)
        validate_property(ResourceSku, Symbol("locations"), locations)
        setfield!(o, Symbol("locations"), locations)
        validate_property(ResourceSku, Symbol("apiVersions"), apiVersions)
        setfield!(o, Symbol("apiVersions"), apiVersions)
        validate_property(ResourceSku, Symbol("costs"), costs)
        setfield!(o, Symbol("costs"), costs)
        validate_property(ResourceSku, Symbol("capabilities"), capabilities)
        setfield!(o, Symbol("capabilities"), capabilities)
        validate_property(ResourceSku, Symbol("restrictions"), restrictions)
        setfield!(o, Symbol("restrictions"), restrictions)
        o
    end
end # type ResourceSku

const _property_map_ResourceSku = Dict{Symbol,Symbol}(Symbol("resourceType")=>Symbol("resourceType"), Symbol("name")=>Symbol("name"), Symbol("tier")=>Symbol("tier"), Symbol("size")=>Symbol("size"), Symbol("family")=>Symbol("family"), Symbol("kind")=>Symbol("kind"), Symbol("capacity")=>Symbol("capacity"), Symbol("locations")=>Symbol("locations"), Symbol("apiVersions")=>Symbol("apiVersions"), Symbol("costs")=>Symbol("costs"), Symbol("capabilities")=>Symbol("capabilities"), Symbol("restrictions")=>Symbol("restrictions"))
const _property_types_ResourceSku = Dict{Symbol,String}(Symbol("resourceType")=>"String", Symbol("name")=>"String", Symbol("tier")=>"String", Symbol("size")=>"String", Symbol("family")=>"String", Symbol("kind")=>"String", Symbol("capacity")=>"ResourceSkuCapacity", Symbol("locations")=>"Vector{String}", Symbol("apiVersions")=>"Vector{String}", Symbol("costs")=>"Vector{ResourceSkuCosts}", Symbol("capabilities")=>"Vector{ResourceSkuCapabilities}", Symbol("restrictions")=>"Vector{ResourceSkuRestrictions}")
Base.propertynames(::Type{ ResourceSku }) = collect(keys(_property_map_ResourceSku))
Swagger.property_type(::Type{ ResourceSku }, name::Symbol) = Union{Nothing,eval(Meta.parse(_property_types_ResourceSku[name]))}
Swagger.field_name(::Type{ ResourceSku }, property_name::Symbol) =  _property_map_ResourceSku[property_name]

function check_required(o::ResourceSku)
    true
end

function validate_property(::Type{ ResourceSku }, name::Symbol, val)
end

ext: jl


text:
"""
```
durbin_koopman_smoother(y, T, R, C, Q, Z, D, E, s_0, P_0;
    Nt0 = 0, draw_states = true)

durbin_koopman_smoother(regime_indices, y, Ts, Rs, Cs, Qs,
    Zs, Ds, Es, s_0, P_0; Nt0 = 0, draw_states = true)
```

This program is a simulation smoother based on Durbin and Koopman's
\"A Simple and Efficient Simulation Smoother for State Space Time Series
Analysis\" (Biometrika, 2002).

Unlike other simulation smoothers (for example, that of Carter and Kohn,
1994), this method does not require separate draws for each period, draws
of the state vectors, or even draws from a conditional distribution.
Instead, vectors of shocks are drawn from the unconditional distribution
of shocks, which is then corrected (via a Kalman smoothing step), to
yield a draw of shocks conditional on the data. This is then used to
generate a draw of states conditional on the data. Drawing the states in
this way is much more efficient than other methods, as it avoids the need
for multiple draws of state vectors (requiring singular value
decompositions), as well as inverting state covariance matrices
(requiring the use of the computationally intensive and relatively
erratic Moore-Penrose pseudoinverse).

The state space is given by:

```
s_{t+1} = C + T*s_t + R*ϵ_t    (transition equation)
y_t     = D + Z*s_t + u_t      (measurement equation)

ϵ_t ∼ N(0, Q)
u_t ∼ N(0, E)
Cov(ϵ_t, u_t) = 0
```

### Inputs

- `y`: `Ny` x `Nt` matrix containing data `y_1, ... , y_T`
- `s_0`: `Ns` x 1 initial state vector
- `P_0`: `Ns` x `Ns` initial state covariance matrix
- `pred`: `Ns` x `Nt` matrix of one-step predicted state vectors `s_{t|t-1}`
  (from the Kalman filter)
- `vpred`: `Ns` x `Ns` x `Nt` array of mean squared errors `P_{t|t-1}` of
  predicted state vectors

**Method 1 only:** state-space system matrices `T`, `R`, `C`, `Q`, `Z`,
`D`, `E`. See `?kalman_filter`

**Method 2 only:** `regime_indices` and system matrices for each regime `Ts`,
`Rs`, `Cs`, `Qs`, `Zs`, `Ds`, `Es`. See `?kalman_filter`

where:

- `Nt`: number of periods for which we have data
- `Ns`: number of states
- `Ne`: number of shocks
- `Ny`: number of observables

### Keyword Arguments

- `Nt0`: if greater than 0, the returned smoothed states and shocks matrices
  will be shorter by that number of columns (taken from the beginning)
- `draw_states`: indicates whether to draw smoothed states from the distribution
  `N(s_{t|T}, P_{t|T})` or to use the mean `s_{t|T}` (reducing to the Koopman
  smoother)

### Outputs

- `s_smth`: `Ns` x `Nt` matrix of smoothed states `s_{t|T}`
- `ϵ_smth`: `Ne` x `Nt` matrix of smoothed shocks `ϵ_{t|T}`
"""
function durbin_koopman_smoother(y::Matrix{S},
    T::Matrix{S}, R::Matrix{S}, C::Vector{S},
    Q::Matrix{S}, Z::Matrix{S}, D::Vector{S}, E::Matrix{S},
    s_0::Vector{S}, P_0::Matrix{S};
    Nt0::Int = 0, draw_states::Bool = true) where {S<:AbstractFloat}

    Nt = size(y, 2)
    durbin_koopman_smoother(Range{Int}[1:Nt], y, Matrix{S}[T], Matrix{S}[R], Vector{S}[C],
        Matrix{S}[Q], Matrix{S}[Z], Vector{S}[D], Matrix{S}[E], s_0, P_0;
        Nt0 = Nt0, draw_states = draw_states)
end

function durbin_koopman_smoother(regime_indices::Vector{Range{Int}}, y::Matrix{S},
    Ts::Vector{Matrix{S}}, Rs::Vector{Matrix{S}}, Cs::Vector{Vector{S}}, Qs::Vector{Matrix{S}},
    Zs::Vector{Matrix{S}}, Ds::Vector{Vector{S}}, Es::Vector{Matrix{S}},
    s_0::Vector{S}, P_0::Matrix{S};
    Nt0::Int = 0, draw_states::Bool = true) where {S<:AbstractFloat}

    # Dimensions
    n_regimes = length(regime_indices)
    Nt = size(y,     2) # number of periods of data
    Ns = size(Ts[1], 1) # number of states
    Ne = size(Rs[1], 2) # number of shocks
    Ny = size(Zs[1], 1) # number of observables

    # Draw initial state s_0+
    s_plus_t = if draw_states
        U, eig, _ = svd(P_0)
        U * diagm(sqrt.(eig)) * randn(Ns)
    else
        zeros(S, Ns)
    end

    # Produce "fake" states and observables (s+ and y+) by
    # iterating the state-space system forward, drawing shocks ϵ+
    s_plus = zeros(S, Ns, Nt)
    ϵ_plus = zeros(S, Ne, Nt)
    y_plus = zeros(S, Ny, Nt)

    for i = 1:n_regimes
        # Get state-space system matrices for this regime
        T, R, C, Q = Ts[i], Rs[i], Cs[i], Qs[i]
        Z, D       = Zs[i], Ds[i]

        for t in regime_indices[i]
            s_plus_t = if draw_states
                ϵ_plus[:, t] = sqrt.(Qs[i]) * randn(Ne)
                T*s_plus_t + R*ϵ_plus[:, t] + C
            else
                T*s_plus_t + C
            end

            s_plus[:, t] = s_plus_t
            y_plus[:, t] = Z*s_plus_t + D
        end
    end

    # Replace y+ with NaNs wherever y has NaNs
    y_plus[isnan.(y)] = NaN

    # Compute y* = y - y+
    y_star = y - y_plus

    # Run the Kalman filter on y*
    # Note that we pass in `zeros(Ny)` instead of `D` because the
    # measurement equation for y* has no constant term
    Ds_star = fill(zeros(Ny), n_regimes)
    _, s_pred, P_pred, _, _, _, _, _, _ =
        kalman_filter(regime_indices, y_star, Ts, Rs, Cs, Qs,
                      Zs, Ds_star, Es, s_0, P_0; outputs = [:pred])

    # Kalman smooth y*
    s_star, ϵ_star = koopman_smoother(regime_indices, y_star, Ts, Rs, Cs, Qs,
                                      Zs, Ds_star, Es, s_0, P_0, s_pred, P_pred)

    # Compute smoothed states and shocks
    s_smth = s_plus + s_star
    ϵ_smth = ϵ_plus + ϵ_star

    # Trim the presample if needed
    if Nt0 > 0
        insample = Nt0+1:Nt

        s_smth = s_smth[:, insample]
        ϵ_smth = ϵ_smth[:, insample]
    end

    return s_smth, ϵ_smth
end


text:
module Poisson_examples
using FinEtools
using FinEtoolsHeatDiff

function Poisson_FE_H20_example()
    println("""

    Heat conduction example described by Amuthan A. Ramabathiran
    http://www.codeproject.com/Articles/579983/Finite-Element-programming-in-Julia:
    Unit cube, with known temperature distribution along the boundary,
    and uniform heat generation rate inside.  Mesh of regular quadratic HEXAHEDRA,
    in a grid of 30 x 30 x 30 edges (100079 degrees of freedom).
    Version: 06/03/2017
    """
    )
    t0 = time()

    A = 1.0 # dimension of the domain (length of the side of the square)
    thermal_conductivity = [i==j ? one(FFlt) : zero(FFlt) for i=1:3, j=1:3]; # conductivity matrix
    Q = -6.0; # internal heat generation rate
    function getsource!(forceout::FFltVec, XYZ::FFltMat, tangents::FFltMat, fe_label::FInt)
        forceout[1] = Q; #heat source
    end
    tempf(x) = (1.0 .+ x[:,1].^2 + 2.0 .* x[:,2].^2);#the exact distribution of temperature
    N = 30;# number of subdivisions along the sides of the square domain

    println("Mesh generation")
    @time fens,fes = H20block(A, A, A, N, N, N)

    geom = NodalField(fens.xyz)
    Temp = NodalField(zeros(size(fens.xyz,1),1))

    println("Searching nodes  for BC")
    Tolerance = 1.0/N/100.0
    @time l1 = selectnode(fens; box=[0. 0. 0. A 0. A], inflate = Tolerance)
    @time l2 = selectnode(fens; box=[A A 0. A 0. A], inflate = Tolerance)
    @time l3 = selectnode(fens; box=[0. A 0. 0. 0. A], inflate = Tolerance)
    @time l4 = selectnode(fens; box=[0. A A A 0. A], inflate = Tolerance)
    @time l5 = selectnode(fens; box=[0. A 0. A 0. 0.], inflate = Tolerance)
    @time l6 = selectnode(fens; box=[0. A 0. A A A], inflate = Tolerance)
    List = vcat(l1, l2, l3, l4, l5, l6)
    @time setebc!(Temp, List, true, 1, tempf(geom.values[List,:])[:])
    @time applyebc!(Temp)
    @time numberdofs!(Temp)

    println( "Number of free degrees of freedom: $(Temp.nfreedofs)")
    t1 = time()

    material = MatHeatDiff(thermal_conductivity)

    femm = FEMMHeatDiff(IntegDomain(fes, GaussRule(3, 3)), material)

    println("Conductivity")
    @time K = conductivity(femm, geom, Temp)
    println("Nonzero EBC")
    @time F2 = nzebcloadsconductivity(femm, geom, Temp);
    println("Internal heat generation")
    # fi = ForceIntensity(FFlt, getsource!);# alternative  specification
    fi = ForceIntensity(FFlt[Q]);
    @time F1 = distribloads(femm, geom, Temp, fi, 3);

    println("Solution of the system")
    @time U = K\(F1+F2)
    scattersysvec!(Temp,U[:])

    println("Total time elapsed = $(time() - t0) [s]")
    println("Solution time elapsed = $(time() - t1) [s]")

    Error= 0.0
    for k=1:size(fens.xyz,1)
        Error = Error + abs.(Temp.values[k,1] - tempf(reshape(fens.xyz[k,:], (1,3)))[1])
    end
    println("Error =$Error")

    # File =  "a.vtk"
    # MeshExportModule.vtkexportmesh (File, fes.conn, [geom.values Temp.values], MeshExportModule.T3; scalars=Temp.values, scalars_name ="Temperature")

    true

end # Poisson_FE_H20_example

function Poisson_FE_T10_example()
    println("""

    Heat conduction example described by Amuthan A. Ramabathiran
    http://www.codeproject.com/Articles/579983/Finite-Element-programming-in-Julia:
    Unit cube, with known temperature distribution along the boundary,
    and uniform heat generation rate inside.  Mesh of regular quadratic HEXAHEDRA,
    in a grid of 30 x 30 x 30 edges (100079 degrees of freedom).
    Version: 06/03/2017
    """
    )
    t0 = time()

    A = 1.0 # dimension of the domain (length of the side of the square)
    thermal_conductivity = [i==j ? one(FFlt) : zero(FFlt) for i=1:3, j=1:3]; # conductivity matrix
    Q = -6.0; # internal heat generation rate
    function getsource!(forceout::FFltVec, XYZ::FFltMat, tangents::FFltMat, fe_label::FInt)
        forceout[1] = Q; #heat source
    end
    tempf(x) = (1.0 .+ x[:,1].^2 + 2.0 .* x[:,2].^2);#the exact distribution of temperature
    N = 30;# number of subdivisions along the sides of the square domain

    println("Mesh generation")
    @time fens,fes = H20block(A, A, A, N, N, N)

    geom = NodalField(fens.xyz)
    Temp = NodalField(zeros(size(fens.xyz,1),1))

    println("Searching nodes  for BC")
    Tolerance = 1.0/N/100.0
    @time l1 = selectnode(fens; box=[0. 0. 0. A 0. A], inflate = Tolerance)
    @time l2 = selectnode(fens; box=[A A 0. A 0. A], inflate = Tolerance)
    @time l3 = selectnode(fens; box=[0. A 0. 0. 0. A], inflate = Tolerance)
    @time l4 = selectnode(fens; box=[0. A A A 0. A], inflate = Tolerance)
    @time l5 = selectnode(fens; box=[0. A 0. A 0. 0.], inflate = Tolerance)
    @time l6 = selectnode(fens; box=[0. A 0. A A A], inflate = Tolerance)
    List = vcat(l1, l2, l3, l4, l5, l6)
    @time setebc!(Temp, List, true, 1, tempf(geom.values[List,:])[:])
    @time applyebc!(Temp)
    @time numberdofs!(Temp)

    println( "Number of free degrees of freedom: $(Temp.nfreedofs)")
    t1 = time()

    material = MatHeatDiff(thermal_conductivity)

    femm = FEMMHeatDiff(IntegDomain(fes, GaussRule(3, 3)), material)

    println("Conductivity")
    @time K = conductivity(femm, geom, Temp)
    println("Nonzero EBC")
    @time F2 = nzebcloadsconductivity(femm, geom, Temp);
    println("Internal heat generation")
    # fi = ForceIntensity(FFlt, getsource!);# alternative  specification
    fi = ForceIntensity(FFlt[Q]);
    @time F1 = distribloads(femm, geom, Temp, fi, 3);

    println("Solution of the system")
    @time U = K\(F1+F2)
    scattersysvec!(Temp,U[:])

    println("Total time elapsed = $(time() - t0) [s]")
    println("Solution time elapsed = $(time() - t1) [s]")

    Error= 0.0
    for k=1:size(fens.xyz,1)
        Error = Error + abs.(Temp.values[k,1] - tempf(reshape(fens.xyz[k,:], (1,3)))[1])
    end
    println("Error =$Error")

    # File =  "a.vtk"
    # MeshExportModule.vtkexportmesh (File, fes.conn, [geom.values Temp.values], MeshExportModule.T3; scalars=Temp.values, scalars_name ="Temperature")

    true

end # Poisson_FE_T10_example

function Poisson_FE_T4_example()
    t0 = time()

    A = 1.0 # dimension of the domain (length of the side of the square)
    thermal_conductivity = [i==j ? one(FFlt) : zero(FFlt) for i=1:3, j=1:3]; # conductivity matrix
    Q = -6.0; # internal heat generation rate
    function getsource!(forceout::FFltVec, XYZ::FFltMat, tangents::FFltMat, fe_label::FInt)
        forceout[1] = Q; #heat source
    end
    tempf(x) = (1.0 .+ x[:,1].^2 + 2.0 .* x[:,2].^2);#the exact distribution of temperature
    N = 30;# number of subdivisions along the sides of the square domain

    println("Mesh generation")
    @time fens,fes = T4block(A, A, A, N, N, N)

    println("""
    Heat conduction example described by Amuthan A. Ramabathiran
    http://www.codeproject.com/Articles/579983/Finite-Element-programming-in-Julia:
    Unit cube, with known temperature distribution along the boundary,
    and uniform heat generation rate inside.  Mesh of regular quadratic TETRAHEDRA,
    in a grid of $(N) x $(N) x $(N) edges ($(count(fens)) degrees of freedom).
    Version: 07/03/2017
    """
    )

    geom = NodalField(fens.xyz)
    Temp = NodalField(zeros(size(fens.xyz,1),1))

    println("Searching nodes  for BC")
    Tolerance = 1.0/N/100.0
    @time l1 = selectnode(fens; box=[0. 0. 0. A 0. A], inflate = Tolerance)
    @time l2 = selectnode(fens; box=[A A 0. A 0. A], inflate = Tolerance)
    @time l3 = selectnode(fens; box=[0. A 0. 0. 0. A], inflate = Tolerance)
    @time l4 = selectnode(fens; box=[0. A A A 0. A], inflate = Tolerance)
    @time l5 = selectnode(fens; box=[0. A 0. A 0. 0.], inflate = Tolerance)
    @time l6 = selectnode(fens; box=[0. A 0. A A A], inflate = Tolerance)
    List = vcat(l1, l2, l3, l4, l5, l6)
    @time setebc!(Temp, List, true, 1, tempf(geom.values[List,:])[:])
    @time applyebc!(Temp)
    @time numberdofs!(Temp)

    println( "Number of free degrees of freedom: $(Temp.nfreedofs)")
    t1 = time()

    material = MatHeatDiff(thermal_conductivity)

    femm = FEMMHeatDiff(IntegDomain(fes, TetRule(1)), material)

    println("Conductivity")
    @time K = conductivity(femm, geom, Temp)
    println("Nonzero EBC")
    @time F2 = nzebcloadsconductivity(femm, geom, Temp);
    println("Internal heat generation")
    # fi = ForceIntensity(FFlt, getsource!);# alternative  specification
    fi = ForceIntensity(FFlt[Q]);
    @time F1 = distribloads(femm, geom, Temp, fi, 3);

    println("Solution of the system")
    @time U = K\(F1+F2)
    scattersysvec!(Temp,U[:])

    println("Total time elapsed = $(time() - t0) [s]")
    println("Solution time elapsed = $(time() - t1) [s]")

    Error= 0.0
    for k=1:size(fens.xyz,1)
        Error = Error + abs.(Temp.values[k,1] - tempf(reshape(fens.xyz[k,:], (1,3)))[1])
    end
    println("Error =$Error")

    # File =  "a.vtk"
    # MeshExportModule.vtkexportmesh (File, fes.conn, [geom.values Temp.values], MeshExportModule.T3; scalars=Temp.values, scalars_name ="Temperature")

    true

end # Poisson_FE_T4_example

function allrun()
    println("#####################################################")
    println("# Poisson_FE_H20_example ")
    Poisson_FE_H20_example()
    println("#####################################################")
    println("# Poisson_FE_T10_example ")
    Poisson_FE_T10_example()
    println("#####################################################")
    println("# Poisson_FE_T4_example ")
    Poisson_FE_T4_example()
end # function allrun

end # module Poisson_examples

max_stars_repo_name: PetrKryslUCSD/FinEtoolsHeatDiff

max_issues_repo_name: PetrKryslUCSD/FinEtoolsHeatDiff

max_forks_repo_name: PetrKryslUCSD/FinEtoolsHeatDiff


text:
import JSON

using ShowLint: apply

@testset "Patterns" begin
    @test SL.patterns_have_valid_indexes()

    function unchanged(pat::Pattern, code::String)
        result = apply(pat, code)
        ok = result == code
        if !ok
            error("\"$result\" != \"$code\"")
        end
        return ok
    end

    P = SL.patterns

    @test apply(P[1], "rand(1)[1]") == "rand()"
    @test apply(P[1], "rand(f(), 1)[1]") == "rand(f())"
    @test apply(P[1], "rand(f(),1)[1]") == "rand(f())"
    @test apply(P[2], "if x === missing") == "if ismissing(x)"
    @test apply(P[2], "x !== missing") == "!ismissing(x)"
    @test apply(P[3], "map(x -> f(x), A)") == "map(f, A)"
    @test unchanged(P[3], "y = x -> f(x) ? a : b")
    @test unchanged(P[3], "x -> f.(x),")
    @test apply(P[4], "x == true") == "x"
    @test apply(P[4], "x == false") == "!x"
    @test apply(P[4], "x != false") == "!!x"
    @test apply(P[5], "if x == x\n") == "if true\n"
    @test apply(P[5], "if x != x") == "if false"
    @test unchanged(P[5], "a.x == x")
    @test unchanged(P[5], "x == x[1]")
    @test unchanged(P[5], "x == x:y")
    @test unchanged(P[5], "a/x == x")
    @test unchanged(P[5], "f(x) == x")
    @test unchanged(P[5], "f(a, x) == x)")
    @test unchanged(P[5], "1*x == x)")
    @test unchanged(P[5], "x == x′")
    @test unchanged(P[5], "2 * x == x)")
    # I have no clue how to fix this false positive.
    # @test unchanged(P[5], "x == x + 2)")
    @test unchanged(P[5], "6x == x)")
    @test unchanged(P[5], "x == x'")
    @test unchanged(P[5], "x == x^2'")
    @test apply(P[6], "findfirst(a, b) === nothing") == "!occursin(a, b)"
    @test apply(P[6], "findfirst(a, b) !== nothing") == "occursin(a, b)"
    @test apply(P[7], "findall(x -> x == false, Y)") == "findall(.!Y)"
    @test apply(P[8], "map(x -> !x, A)") == "map(!, A)"
    @test apply(P[8], "x -> ~x") == "~"
    @test unchanged(P[8], "x -> !x.y")
    @test unchanged(P[8], "x -> !x[1]")
    @test apply(P[9], "f(a, b; c = c)") == "f(a, b; c)"
    @test apply(P[10], "if a == b && a == b") == "if a == b"
    @test apply(P[10], "if a == b && a == b") == "if a == b"
    @test apply(P[10], "x.y[1] && x.y[1]") == "x.y[1]"
    # @test unchanged(P[10], "a < b && b")
    @test apply(P[11], "dirname(dirname(pathof(Foo)))") == "pkgdir(Foo)"
end

max_stars_repo_name: rikhuijzer/display-lint

max_issues_repo_name: rikhuijzer/display-lint

max_forks_repo_name: rikhuijzer/ShowLint


text:
module Bijectors

using Reexport, Requires
@reexport using Distributions
using StatsFuns
using LinearAlgebra
using MappedArrays
using Roots
using Base.Iterators: drop
using LinearAlgebra: AbstractTriangular

export  TransformDistribution,
        PositiveDistribution,
        UnitDistribution,
        SimplexDistribution,
        PDMatDistribution,
        link,
        invlink,
        logpdf_with_trans,
        isclosedform,
        transform,
        forward,
        logabsdetjac,
        logabsdetjacinv,
        Bijector,
        ADBijector,
        Inverse,
        Composed,
        compose,
        Stacked,
        stack,
        Identity,
        DistributionBijector,
        bijector,
        transformed,
        TransformedDistribution,
        UnivariateTransformed,
        MultivariateTransformed,
        logpdf_with_jac,
        logpdf_forward,
        PlanarLayer,
        RadialLayer,
        InvertibleBatchNorm

if VERSION < v"1.1"
    using Compat: eachcol
end

const DEBUG = Bool(parse(Int, get(ENV, "DEBUG_BIJECTORS", "0")))
_debug(str) = @debug str

_eps(::Type{T}) where {T} = T(eps(T))
_eps(::Type{Real}) = eps(Float64)
_eps(::Type{<:Integer}) = eps(Float64)
_istracked(::Any) = false

function mapvcat(f, args...)
    out = map(f, args...)
    if _istracked(out)
        init = vcat(out[1])
        return reshape(reduce(vcat, drop(out, 1); init = init), size(out))
    else
        return out
    end
end
function mapvcat2(f, args...)
    out = map(f, args...)
    init = vcat(out[1])
    return reshape(reduce(vcat, drop(out, 1); init = init), size(out))
end

function maphcat(f, args...)
    out = map(f, args...)
    init = reshape(out[1], :, 1)
    return reduce(hcat, drop(out, 1); init = init)
end
function eachcolmaphcat(f, x1, x2)
    out = [f(x1[:,i], x2[i]) for i in 1:size(x1, 2)]
    init = reshape(out[1], :, 1)
    return reduce(hcat, drop(out, 1); init = init)
end
function eachcolmaphcat(f, x)
    out = map(f, eachcol(x))
    init = reshape(out[1], :, 1)
    return reduce(hcat, drop(out, 1); init = init)
end
function _sum(f, args...)
    init = f(first.(args)...)
    return mapreduce(f, +, drop.(args, 1)...; init = init)
end
function _sumeachcol(f, x1, x2)
    # Using a view below for x1 breaks Tracker
    return sum(f(x1[:,i], x2[i]) for i in 1:size(x1, 2))
end

# Discrete distributions

function logpdf_with_trans(d::DiscreteUnivariateDistribution, x::Integer, transform::Bool)
    return logpdf(d, x)
end
function logpdf_with_trans(
    d::DiscreteUnivariateDistribution,
    x::AbstractArray{<:Real},
    transform::Bool,
)
    return mapvcat(x) do x
        logpdf(d, x)
    end
end
function logpdf_with_trans(
    d::DiscreteMultivariateDistribution,
    x::AbstractVecOrMat{<:Real},
    transform::Bool,
)
    return logpdf(d, x)
end

#=
  NOTE: Codes below are adapted from
  https://github.com/brian-j-smith/Mamba.jl/blob/master/src/distributions/transformdistribution.jl
  The Mamba.jl package is licensed under the MIT License:
  > Copyright (c) 2014: Brian J Smith and other contributors:
  >
  > https://github.com/brian-j-smith/Mamba.jl/contributors
  >
  > Permission is hereby granted, free of charge, to any person obtaining
  > a copy of this software and associated documentation files (the
  > "Software"), to deal in the Software without restriction, including
  > without limitation the rights to use, copy, modify, merge, publish,
  > distribute, sublicense, and/or sell copies of the Software, and to
  > permit persons to whom the Software is furnished to do so, subject to
  > the following conditions:
  >
  > The above copyright notice and this permission notice shall be
  > included in all copies or substantial portions of the Software.
  >
  > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  > EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  > MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  > IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  > CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  > TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  > SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
=#

#############
# a ≦ x ≦ b #
#############

const TransformDistribution{T<:ContinuousUnivariateDistribution} = Union{T, Truncated{T}}
@inline function _clamp(x::T, dist::TransformDistribution) where {T <: Real}
    ϵ = _eps(T)
    bounds = (minimum(dist) + ϵ, maximum(dist) - ϵ)
    clamped_x = ifelse(x < bounds[1], bounds[1], ifelse(x > bounds[2], bounds[2], x))
    DEBUG && _debug("x = $x, bounds = $bounds, clamped_x = $clamped_x")
    return clamped_x
end

link(d::TransformDistribution, x::Real) = _link(d, _clamp(x, d))
function _link(d::TransformDistribution, x::Real)
    a, b = minimum(d), maximum(d)
    lowerbounded, upperbounded = isfinite(a), isfinite(b)
    if lowerbounded && upperbounded
        return StatsFuns.logit((x - a) / (b - a))
    elseif lowerbounded
        return log(x - a)
    elseif upperbounded
        return log(b - x)
    else
        return x
    end
end

invlink(d::TransformDistribution, y::Real) = _clamp(_invlink(d, y), d)
function _invlink(d::TransformDistribution, y::Real)
    a, b = minimum(d), maximum(d)
    lowerbounded, upperbounded = isfinite(a), isfinite(b)
    if lowerbounded && upperbounded
        return (b - a) * StatsFuns.logistic(y) + a
    elseif lowerbounded
        return exp(y) + a
    elseif upperbounded
        return b - exp(y)
    else
        return y
    end
end

function logpdf_with_trans(
    d::TransformDistribution,
    x::Real,
    transform::Bool,
)
    return _logpdf_with_trans(d, x, transform)
end
function logpdf_with_trans(
    d::TransformDistribution,
    x::AbstractArray{<:Real},
    transform::Bool,
)
    return mapvcat(x -> _logpdf_with_trans(d, x, transform), x)
end
function _logpdf_with_trans(d::TransformDistribution, x::Real, transform::Bool)
    lp = logpdf(d, x)
    if transform
        x = _clamp(x, d)
        a, b = minimum(d), maximum(d)
        lowerbounded, upperbounded = isfinite(a), isfinite(b)
        if lowerbounded && upperbounded
            lp += log((x - a) * (b - x) / (b - a))
        elseif lowerbounded
            lp += log(x - a)
        elseif upperbounded
            lp += log(b - x)
        end
    end
    return lp
end

#########
# 0 < x #
#########

const PositiveDistribution = Union{
    BetaPrime, Chi, Chisq, Erlang, Exponential, FDist, Frechet, Gamma, InverseGamma,
    InverseGaussian, Kolmogorov, LogNormal, NoncentralChisq, NoncentralF, Rayleigh, Weibull,
}

_link(d::PositiveDistribution, x::Real) = log(x)
_invlink(d::PositiveDistribution, y::Real) = exp(y)
function _logpdf_with_trans(d::PositiveDistribution, x::Real, transform::Bool)
    return logpdf(d, x) + transform * log(x)
end

#############
# 0 < x < 1 #
#############

const UnitDistribution = Union{Beta, KSOneSided, NoncentralBeta}

_link(d::UnitDistribution, x::Real) = StatsFuns.logit(x)
_invlink(d::UnitDistribution, y::Real) = StatsFuns.logistic(y)
function _logpdf_with_trans(d::UnitDistribution, x::Real, transform::Bool)
    return logpdf(d, x) + transform * log(x * (one(x) - x))
end

###########
# ∑xᵢ = 1 #
###########

const SimplexDistribution = Union{Dirichlet}

_clamp(x, ::SimplexDistribution) = _clamp(x, SimplexBijector())

function link(
    d::SimplexDistribution,
    x::AbstractVecOrMat{<:Real},
    proj::Bool = true,
)
    return SimplexBijector{proj}()(x)
end

function link_jacobian(
    d::SimplexDistribution,
    x::AbstractVector{T},
    proj::Bool = true,
) where {T<:Real}
    return jacobian(SimplexBijector{proj}(), x)
end

function invlink(
    d::SimplexDistribution,
    y::AbstractVecOrMat{<:Real},
    proj::Bool = true
)
    return inv(SimplexBijector{proj}())(y)
end

function invlink_jacobian(
    d::SimplexDistribution,
    y::AbstractVector{T},
    proj::Bool = true
) where {T<:Real}
    return jacobian(inv(SimplexBijector{proj}()), y)
end

function logpdf_with_trans(
    d::SimplexDistribution,
    x::AbstractVecOrMat{<:Real},
    transform::Bool,
)
    ϵ = _eps(eltype(x))
    lp = logpdf(d, x .+ ϵ)
    if transform
        lp -= logabsdetjac(bijector(d), x)
    end
    return lp
end

# REVIEW: why do we put this piece of code here?
function logpdf_with_trans(d::Categorical, x::Int)
    return d.p[x] > 0.0 && insupport(d, x) ? log(d.p[x]) : eltype(d.p)(-Inf)
end

###############
# MvLogNormal #
###############

using Distributions: AbstractMvLogNormal

link(d::AbstractMvLogNormal, x::AbstractVecOrMat{<:Real}) = log.(x)
invlink(d::AbstractMvLogNormal, y::AbstractVecOrMat{<:Real}) = exp.(y)
function logpdf_with_trans(
    d::AbstractMvLogNormal,
    x::AbstractVector{<:Real},
    transform::Bool,
)
    if transform
        return logpdf(d, x) - logabsdetjac(Log{1}(), x)
    else
        return logpdf(d, x)
    end
end
function logpdf_with_trans(
    d::AbstractMvLogNormal,
    x::AbstractMatrix{<:Real},
    transform::Bool,
)
    if transform
        return logpdf(d, x) .- logabsdetjac(Log{1}(), x)
    else
        return logpdf(d, x)
    end
end

#####################
# Positive definite #
#####################

const PDMatDistribution = Union{InverseWishart, Wishart}

link(d::PDMatDistribution, X::AbstractMatrix{<:Real}) = PDBijector()(X)
invlink(d::PDMatDistribution, Y::AbstractMatrix{<:Real}) = inv(PDBijector())(Y)

function logpdf_with_trans(
    d::PDMatDistribution,
    X::AbstractMatrix{<:Real},
    transform::Bool
)
    _logpdf_with_trans_pd(d, X, transform)
end
function logpdf_with_trans(
    d::PDMatDistribution,
    X::AbstractArray{<:AbstractMatrix{<:Real}},
    transform::Bool
)
    mapvcat(x -> _logpdf_with_trans_pd(d, x, transform), X)
end
function _logpdf_with_trans_pd(
    d,
    X::AbstractMatrix{<:Real},
    transform::Bool,
)
    T = eltype(X)
    Xcf = cholesky(X, check = false)
    if !issuccess(Xcf)
        Xcf = cholesky(X + max(eps(T), eps(T) * norm(X)) * I)
    end
    lp = getlogp(d, Xcf, X)
    if transform && isfinite(lp)
        U = Xcf.U
        lp += sum((dim(d) .- (1:dim(d)) .+ 2) .* log.(diag(U)))
        lp += dim(d) * log(T(2))
    end
    return lp
end
function getlogp(d::Wishart, Xcf, X)
    return 0.5 * ((d.df - (dim(d) + 1)) * logdet(Xcf) - tr(d.S \ X)) - d.c0
end
function getlogp(d::InverseWishart, Xcf, X)
    Ψ = Matrix(d.Ψ)
    return -0.5 * ((d.df + dim(d) + 1) * logdet(Xcf) + tr(Xcf \ Ψ)) - d.c0
end

############################################
# Defaults (assume identity link function) #
############################################

# UnivariateDistributions
using Distributions: UnivariateDistribution

link(d::UnivariateDistribution, x::Real) = x
link(d::UnivariateDistribution, x::AbstractArray{<:Real}) = mapvcat(x) do x
    link(d, x)
end

invlink(d::UnivariateDistribution, y::Real) = y
invlink(d::UnivariateDistribution, y::AbstractArray{<:Real}) = mapvcat(y) do y
    invlink(d, y)
end

function logpdf_with_trans(
    d::UnivariateDistribution,
    x::Real,
    transform::Bool,
)
    return _logpdf_with_trans(d, x, transform)
end
function logpdf_with_trans(
    d::UnivariateDistribution,
    x::AbstractArray{<:Real},
    transform::Bool,
)
    return mapvcat(x) do x
        logpdf_with_trans(d, x, transform)
    end
end

# MultivariateDistributions
using Distributions: MultivariateDistribution

link(d::MultivariateDistribution, x::AbstractVecOrMat{<:Real}) = copy(x)

invlink(d::MultivariateDistribution, y::AbstractVecOrMat{<:Real}) = copy(y)

function logpdf_with_trans(d::MultivariateDistribution, x::AbstractVecOrMat{<:Real}, ::Bool)
    return logpdf(d, x)
end

# MatrixDistributions
using Distributions: MatrixDistribution

link(d::MatrixDistribution, X::AbstractMatrix{<:Real}) = copy(X)
link(d::MatrixDistribution, X::AbstractArray{<:AbstractMatrix{<:Real}}) = mapvcat(X) do x
    link(d, x)
end

invlink(d::MatrixDistribution, Y::AbstractMatrix{<:Real}) = copy(Y)
function invlink(d::MatrixDistribution, Y::AbstractArray{<:AbstractMatrix{<:Real}})
    return mapvcat(Y) do y
        invlink(d, y)
    end
end

function logpdf_with_trans(
    d::MatrixDistribution,
    X::Union{AbstractMatrix{<:Real}, AbstractArray{<:AbstractMatrix{<:Real}}},
    ::Bool,
)
    return logpdf(d, X)
end

include("interface.jl")

# optional dependencies
function __init__()
    @require ForwardDiff="f6369f11-7733-5829-9624-2563aa707210" include("compat/forwarddiff.jl")
    @require Tracker="9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" include("compat/tracker.jl")
    @require Zygote="e88e6eb3-aa80-5325-afca-941959d7151f" include("compat/zygote.jl")
    @require ReverseDiff="37e2e3b7-166d-5795-8a7a-e32c996b4267" include("compat/reversediff.jl")
    @require DistributionsAD="ced4e74d-a319-5a8a-b0ac-84af2272839c" include("compat/distributionsad.jl")
    @require Flux="587475ba-b771-5e3f-ad9e-33799f191a9c" include("compat/flux.jl")
end

end # module


text:
using DrWatson
@quickactivate
using ArgParse
using GenerativeAD
using StatsBase: fit!, predict, sample
using BSON

s = ArgParseSettings()
@add_arg_table! s begin
   "max_seed"
        required = true
        arg_type = Int
        help = "seed"
    "dataset"
        required = true
        arg_type = String
        help = "dataset"
    "contamination"
    	arg_type = Float64
    	help = "contamination rate of training data"
    	default = 0.0
end
parsed_args = parse_args(ARGS, s)
@unpack dataset, max_seed, contamination = parsed_args

modelname = "pidforest"
function sample_params()
	par_vec = (6:2:10, 50:25:200, [50, 100, 250, 500, 1000, 5000], 3:6, [0.05, 0.1, 0.2], )
	argnames = (:max_depth, :n_trees, :max_samples, :max_buckets, :epsilon, )

	return (;zip(argnames, map(x->sample(x, 1)[1], par_vec))...)
end

function GenerativeAD.edit_params(data, parameters)
	D, N = size(data[1][1])
	if N < parameters.max_samples
		# if there are not enough samples, choose closest multiple of 50
		@info "Not enough samples in training, changing max_samples for each tree."
		return merge(parameters, (;max_samples = max(25, N - mod(N, 50))))
	else
		return parameters
	end
end

function fit(data, parameters)
	model = GenerativeAD.Models.PIDForest(Dict(pairs(parameters)))

	try
		global info, fit_t, _, _, _ = @timed fit!(model, data[1][1])
	catch e
		@info "Failed training due to \n$e"
		return (fit_t = NaN,), []
	end

	training_info = (
		fit_t = fit_t,
		model = nothing
		)

	training_info, [(x -> predict(model, x, pct=p), merge(parameters, Dict(:percentile => p))) for p in [10, 25, 50]]
end

function remove_constant_features(data)
	X = data[1][1]
	mask = (maximum(X, dims=2) .== minimum(X, dims=2))[:]
	if any(mask)
		@info "Removing $(sum(mask)) features with constant values."
		return Tuple((data[i][1][.~mask,:], data[i][2]) for i in 1:3)
	end
	data
end

try_counter = 0
max_tries = 10*max_seed
cont_string = (contamination == 0.0) ? "" : "_contamination-$contamination"
while try_counter < max_tries
    parameters = sample_params()

    for seed in 1:max_seed
		savepath = datadir("experiments/tabular$cont_string/$(modelname)/$(dataset)/seed=$(seed)")
		mkpath(savepath)

		# get data
		data = GenerativeAD.load_data(dataset, seed=seed, contamination=contamination)
		data = remove_constant_features(data)
		edited_parameters = GenerativeAD.edit_params(data, parameters)

		if GenerativeAD.check_params(savepath, edited_parameters)
			@info "Started training PIDForest$(edited_parameters) on $(dataset):$(seed)"

			training_info, results = fit(data, edited_parameters)
			save_entries = merge(training_info, (modelname = modelname, seed = seed, dataset = dataset, contamination = contamination))

			for result in results
				GenerativeAD.experiment(result..., data, savepath; save_entries...)
			end
			global try_counter = max_tries + 1
		else
			@info "Model already present, trying new hyperparameters..."
			global try_counter += 1
		end
	end
end
(try_counter == max_tries) ? (@info "Reached $(max_tries) tries, giving up.") : nothing


text:
include("ModB.jl")
include("ModA.jl")

module TestModuleBroken

using ..A
using ..B

p = A.Parameters(1)

b = B.BStruct(params = p)

B.g(b)

end # module

max_stars_repo_name: tgflynn/IncludeGuards

max_issues_repo_name: tgflynn/IncludeGuards

max_forks_repo_name: tgflynn/IncludeGuards


text:
using Sigma
using Base.Test

# Should be able to sample from any distribution
function cansample(X::RandVar; nsamples = 100)
  samples = rand(X, nsamples)
  @test typeof(samples) == Vector{rangetype(X)}
  @test length(samples) == nsamples
  return true
end

# Should be able to sample from any distribution
function test_randvar(X::RandVar)
  @test cansample(X)
end

randvars = [
  uniform(1, 0, 1),
  uniform(0, 1),
  exponential(0.5),
  exponential(1,0.5),
  logistic(1.0,1.0)]

for randvar in randvars
  println("Testing $(randvar)")
  test_randvar(randvar)
end

## Test Arithmetic
## ===============

## Goal is to test real valued
for op in (+,-,/,*,^)
  for r1 in randvars, r2 in randvars
    println("Testing $op($r1, $r2)")
    test_randvar(op(r1, r2))
  end
end

real_floating = [exp,log,sin,
  cos,tan,asin,
  acos,atan,sinh,
  cosh,tanh,atan2]

for op in real_floating
  for r in RandVar
    println("Testing $op($r)")
    test_randvar(op(r))
  end
end


text:
using Literate
include("../literate_utlis.jl")

Literate.notebook(
    joinpath(@__DIR__, "report.jl"),
    @__DIR__;
    preprocess = preprocess_natural_comment,
)


text:
using FoldingTrees
using REPL.TerminalMenus
using Test

function collectexposed(root)
    function collect!(lines, depths, node, depth)
        push!(lines, node.data)
        push!(depths, depth)
        if !node.foldchildren
            for child in node.children
                collect!(lines, depths, child, depth+1)
            end
        end
        return lines, depths
    end

    lines, depths = eltype(root)[], Int[]
    return collect!(lines, depths, root, 0)
end

function getroot(node)
    while !isroot(node)
        node = node.parent
    end
    return node
end

function checknext(node, depth, lines, depths)
    for i = 2:count_open_leaves(getroot(node))
        node, depth = next(node, depth)
        @test node.data == lines[i]
        @test depth == depths[i]
    end
end

function checkprev(node, depth, lines, depths)
    for i = count_open_leaves(getroot(node)):-1:2
        @test node.data == lines[i]
        @test depth == depths[i]
        node, depth = prev(node, depth)
    end
end

# From REPL/test/TerminalMenus/dynamic_menu.jl
matchback(str) = match(r"\e\[(\d+)A", str)

function linesplitter(str)
    strs = split(str, '\n')
    s1 = strs[1]
    m = matchback(s1)
    if m === nothing
        nback, startidx = 0, 1
    else
        nback = parse(Int, m.captures[1])
        startidx = m.offset+length(m.match)
    end
    strs[1] = s1[startidx:end]  # discard the portion that moves the terminal
    @test all(s->startswith(s, "\e[2K"), strs)
    return nback, replace.(map(s->s[5:end], strs), ('\r'=>"",))
end

@testset "FoldingTrees.jl" begin
    root = Node("")
    child1 = Node("1", root)
    child1a = Node("1a", child1)
    child1a1 = Node("1a1", child1a)
    child1b = Node("1b", child1)
    child1b1 = Node("1b1", child1b)
    child1b2 = Node("1b2", child1b)
    child2 = Node("2", root)
    child3 = Node("3", root)
    child3a = Node("3a", child3)
    child3b = Node("3b", child3)
    child3b1 = Node("3b1", child3b)
    child3c = Node("3c", child3)

    for folded in (false, true)
        # For child2, folding has no impact, so we can run the same tests
        child2.foldchildren = folded

        @test count_open_leaves(root) == 13
        @test count_open_leaves(child1) == 6
        @test count_open_leaves(child2) == 1
        @test count_open_leaves(child3) == 5

        lines, depths = collectexposed(root)
        @test collect(root) == lines
        @test collect(child1) == lines[2:7]
        @test collect(child2) == lines[8:8]
        @test collect(child3) == lines[9:end]
        checknext(root, 0, lines, depths)
        checkprev(child3c, 2, lines, depths)
    end

    child1b.foldchildren = true
    @test count_open_leaves(root) == 11
    @test count_open_leaves(child1) == 4
    @test count_open_leaves(child2) == 1
    @test count_open_leaves(child3) == 5
    lines, depths = collectexposed(root)
    @test collect(root) == lines
    @test collect(child1) == lines[2:5]
    @test collect(child2) == lines[6:6]
    @test collect(child3) == lines[7:end]
    checknext(root, 0, lines, depths)
    checkprev(child3c, 2, lines, depths)

    child1b.foldchildren = false
    child1a.foldchildren = true
    @test count_open_leaves(root) == 12
    @test count_open_leaves(child1) == 5
    @test count_open_leaves(child2) == 1
    @test count_open_leaves(child3) == 5
    lines, depths = collectexposed(root)
    @test collect(root) == lines
    @test collect(child1) == lines[2:6]
    @test collect(child2) == lines[7:7]
    @test collect(child3) == lines[8:end]
    checknext(root, 0, lines, depths)
    checkprev(child3c, 2, lines, depths)

    child3b.foldchildren = true
    @test count_open_leaves(root) == 11
    @test count_open_leaves(child1) == 5
    @test count_open_leaves(child2) == 1
    @test count_open_leaves(child3) == 4
    lines, depths = collectexposed(root)
    @test collect(root) == lines
    @test collect(child1) == lines[2:6]
    @test collect(child2) == lines[7:7]
    @test collect(child3) == lines[8:end]
    checknext(root, 0, lines, depths)
    checkprev(child3c, 2, lines, depths)

    io = IOBuffer()
    foreach(unfold!, nodes(root))
    FoldingTrees.print_tree(io, root)
    @test String(take!(io)) == "  \n├─   1\n│  ├─   1a\n│  │  └─   1a1\n│  └─   1b\n│     ├─   1b1\n│     └─   1b2\n├─   2\n└─   3\n   ├─   3a\n   ├─   3b\n   │  └─   3b1\n   └─   3c\n"
    fold!(child1b)
    FoldingTrees.print_tree(io, root)
    @test String(take!(io)) == "  \n├─   1\n│  ├─   1a\n│  │  └─   1a1\n│  └─ + 1b\n├─   2\n└─   3\n   ├─   3a\n   ├─   3b\n   │  └─   3b1\n   └─   3c\n"
    @test !toggle!(child1b)
end

if isdefined(FoldingTrees, :TreeMenu)
    @testset "TreeMenu" begin
        @testset "writeoption" begin
            buf = IOBuffer()
            str = "abcdefg"
            FoldingTrees.writeoption(buf, str, 0; width=10)
            @test String(take!(buf)) == str
            FoldingTrees.writeoption(buf, str, 0; width=3)
            @test String(take!(buf)) == "abc"
            FoldingTrees.writeoption(buf, str, 5; width=10)
            @test String(take!(buf)) == "abcde"
            FoldingTrees.writeoption(buf, "Once\n upon\n a time", 0; width=100)
            @test String(take!(buf)) == "Once upon a time"
            FoldingTrees.writeoption(buf, "Once\r\n upon\r\n a time", 0; width=100)
            @test String(take!(buf)) == "Once upon a time"
            printstyled(IOContext(buf, :color=>true), "This is a long string", color=:red)
            str = String(take!(buf))
            FoldingTrees.writeoption(buf, str, 0; width=100)
            @test String(take!(buf)) == str
            FoldingTrees.writeoption(buf, str, 0; width=10)
            @test String(take!(buf)) == "\e[31mThis is a \e[39m"
            @test_throws ErrorException("terminal escape code \\ex not supported") FoldingTrees.writeoption(buf, "This is \ex junk", 0; width=10)
            @test_throws ErrorException("terminal escape code \\e[x not supported") FoldingTrees.writeoption(buf, "This is \e[x junk", 0; width=10)

            # Fallback for writeoption
            take!(buf)
            FoldingTrees.writeoption(buf, 3.2, 0; width=10)
            @test String(take!(buf)) == "3.2"
        end

        root = Node("")
        child1 = Node("1", root)
        child1a = Node("1a", child1)
        child1a1 = Node("1a1", child1a)
        child1b = Node("1b", child1)
        child1b1 = Node("1b1", child1b)
        child1b2 = Node("1b2", child1b)
        child2 = Node("2", root)
        menu = TreeMenu(root)
        @test TerminalMenus.numoptions(menu) == 8
        io = IOBuffer()
        state = TerminalMenus.printmenu(io, menu, 2; init=true)
        str = String(take!(io))
        nback, lines = linesplitter(str)
        @test nback == 0
        @test lines[2] == " >    1"
        @test lines[3] == "       1a"
        @test lines[4] == "        1a1"
        @test lines[8] == "      2"
        @test length(lines) == 8

        menu.cursoridx = 3
        TerminalMenus.keypress(menu, UInt32(' '))
        @test TerminalMenus.numoptions(menu) == 7
        state = TerminalMenus.printmenu(io, menu, 2; oldstate=state)
        str = String(take!(io))
        nback, lines = linesplitter(str)
        @test nback == 7
        @test lines[2] == " >    1"
        @test lines[3] == "   +   1a"
        @test lines[4] == "       1b"
        @test lines[8] == "\e[1A"   # ANSI escape code for "move up"
        @test length(lines) == 8

        TerminalMenus.pick(menu, 4)
        @test TerminalMenus.selected(menu) == child1b
        TerminalMenus.cancel(menu)
        @test TerminalMenus.selected(menu) === nothing

        # Dynamic `pagesize` when (un)folding:
        foreach(unfold!, nodes(root))

        menu = TreeMenu(root; dynamic = true)
        state = TerminalMenus.printmenu(io, menu, 2; init = true)
        str = String(take!(io))
        nback, lines = linesplitter(str)
        @test nback == 0
        @test length(lines) == 8
        @test lines[2] == " >    1"
        @test menu.pagesize == 8

        # pagesize shrink
        TerminalMenus.keypress(menu, UInt32(' '))
        state = TerminalMenus.printmenu(io, menu, 2; init = true)
        str = String(take!(io))
        nback, lines = linesplitter(str)
        @test length(lines) == 3
        @test lines[2] == " > +  1"
        @test lines[3] == "      2"
        @test menu.pagesize == 3

        # pagesize regrow
        TerminalMenus.keypress(menu, UInt32(' '))
        state = TerminalMenus.printmenu(io, menu, 2; init = true)
        str = String(take!(io))
        nback, lines = linesplitter(str)
        @test length(lines) == 8
        @test lines[2] == " >    1"
        @test menu.pagesize == 8

        # Fold that the for the pagesize limiting tests next:
        TerminalMenus.keypress(menu, UInt32(' '))

        # `maxsize` limiting when unfolding:

        menu = TreeMenu(root; dynamic = true, maxsize = 5)
        state = TerminalMenus.printmenu(io, menu, 2; init = true)
        str = String(take!(io))
        nback, lines = linesplitter(str)
        @test nback == 0
        @test length(lines) == 3
        @test lines[2] == " > +  1"
        @test lines[3] == "      2"
        @test menu.pagesize == 3

        TerminalMenus.keypress(menu, UInt32(' '))
        state = TerminalMenus.printmenu(io, menu, 2; init = true)
        str = String(take!(io))
        nback, lines = linesplitter(str)
        @test nback == 0
        @test length(lines) == 5
        @test lines[5] == "v      1b"
        @test menu.pagesize == 5
    end
end


text:
using OrdinaryDiffEq
using Trixi

###############################################################################
# semidiscretization of the compressible Euler equations

equations = CompressibleEulerEquations3D(1.4)

initial_condition = initial_condition_convergence_test
source_terms = source_terms_convergence_test

volume_flux  = flux_ranocha
surface_flux = flux_lax_friedrichs
solver = DGMulti(polydeg = 3, element_type = Hex(),
                 approximation_type = periodic_derivative_operator(
                   derivative_order=1, accuracy_order=4, xmin=-1.0, xmax=1.0, N=20),
                 surface_integral= SurfaceIntegralWeakForm(surface_flux),
                 volume_integral = VolumeIntegralFluxDifferencing(volume_flux))

mesh = DGMultiMesh(solver)

semi = SemidiscretizationHyperbolic(mesh, equations, initial_condition, solver;
                                    source_terms=source_terms)

###############################################################################
# ODE solvers, callbacks etc.

tspan = (0.0, 0.4)
ode = semidiscretize(semi, tspan)

summary_callback = SummaryCallback()

analysis_interval = 100
analysis_callback = AnalysisCallback(semi, interval=analysis_interval, uEltype=real(solver))

alive_callback = AliveCallback(analysis_interval=analysis_interval)

callbacks = CallbackSet(summary_callback,
                        analysis_callback, alive_callback)

###############################################################################
# run the simulation

sol = solve(ode, RDPK3SpFSAL49(), abstol = 1.0e-7, reltol = 1.0e-7,
            save_everystep = false, callback = callbacks)
summary_callback() # print the timer summary


text:
"""
    trac2markdown(relurl; getattachments)

Writes markdown file to $MARKDOWNDIR, and downloads attachment to $MARKDOWNDIR if getattachments=true.
Returns names of linked wikipages
"""
function trac2markdown(relurl::String; getattachments=false)

    @info "Converting $(Trac2Markdown.WIKIDIR)$relurl.wiki"

    s = read("$(Trac2Markdown.WIKIDIR)$relurl.wiki",String)

    ## download attachments
    if getattachments
        for attachment in eachmatch(r"\[raw-attachment:(.+?) .+?\]", s)
            capture = attachment.captures[1]
            @info "Downloading $capture"
            mkpath(joinpath(MARKDOWNDIR, relurl))
            download(joinpath(attachmenturl, relurl, capture), joinpath(MARKDOWNDIR, relurl, capture))
        end
    end

    # Get names of linked subwiki's
    subwikis = String[]
    for subwiki in eachmatch(r"\[wiki:(.+?) .+?\]", s)
        capture = subwiki.captures[1]
        push!(subwikis, capture)
    end

    # To create relative url in Markdown we need the nestling level
    # So we can point to the docs/src directory
    nestinglevel = length(splitpath(relurl))-1
    wikisub = repeat("../",nestinglevel)
    sstr = SubstitutionString("[\\3]($wikisub\\1.md\\2)")
    s = replace(s,r"\[wiki:([^ #]+)(#?[^ ]*?) (.+?)\]" => sstr)

    # convert text to markdown
    mdtxt  = trac2md(s)

    # write to file
    mkpath(dirname(joinpath(MARKDOWNDIR, relurl)))

    # Add meta block to change the EditURL to point to hirlam.org
    wikiurl = "$(Trac2Markdown.wikiurl)/$relurl"
    meta="```@meta\r\nEditURL=\"$wikiurl?action=edit\"\r\n```\r\n"

    meta_mdtxt = meta .* mdtxt

    write(joinpath(MARKDOWNDIR, "$relurl.md"), meta_mdtxt)

    return subwikis
end

function getfromwikidir(relurl)

end

# The .wiki extension is added to avoid conflict with
# having a file with the same name as a directory


text:
## Metsa-Oy Forest Products Supply Chain
## Edward J. Xu <edxu96@outlook.com>
## Jan 24th, 2020

function optim_2(alpha_t, beta_t, a_i, b_i, e_i, c_i, r_saw, r_plywood, a_j,
    c_j, r_j, a_paper_t, b_paper_j, c_paper, r_paper, gamma_ik, delta_ik,
    gamma_jk, delta_jk, gamma_paper_k, delta_paper_k, p_fuel, sigma, omega_i,
    omega_j, omega_paper, nu_saw, nu_plywood, nu_j, nu_paper, o_saw, o_plywood,
    o_j, o_paper, i_t1, i_t2, j_t2)

  mod = Model(with_optimizer(Gurobi.Optimizer, Presolve=0, OutputFlag=0))

  @variable(mod, h_mt[1:3, 1:6]>=0, integer=true)
  @variable(mod, y_mi[1:3, 1:5]>=0)
  @variable(mod, y_mj[1:3, 1:2]>=0)
  @variable(mod, y_paper_m[1:3]>=0)
  @variable(mod, z_mik[1:3, 1:5, 1:4]>=0)
  @variable(mod, z_mjk[1:3, 1:2, 1:4]>=0)
  @variable(mod, z_paper_mk[1:3, 1:4]>=0)
  @variable(mod, 0 <= x_saw_m[1:3] <= r_saw * nu_saw)
  @variable(mod, 0 <= x_plywood_m[1:3] <= r_plywood * nu_plywood)
  @variable(mod, x_mj[1:3, 1:2] >= 0)
  @variable(mod, 0 <= x_paper_m[1:3] <= r_paper * nu_paper)

  @objective(mod, Max,
    sum(
      (-sum(alpha_t[t] * h_mt[m, t] + beta_t[t] * h_mt[m, t]^2
        for t = 1:6) +
      -sum(c_i[i] * y_mi[m, i] for i=1:5) +
      -sum(c_j[j] * y_mj[m, j] for j=1:2) - c_paper * y_paper_m[m] +
      sum(alpha_t[t] * (
        h_mt[m, t] - sum(a_i[i] * y_mi[m, i] for i in i_t1[t])
        ) for t=1:3) +
      sum(alpha_t[t] * (h_mt[m, t] + sum(b_i[i] * y_mi[m, i] for i
        in i_t2[t-3]) - sum(a_j[j] * y_mj[m, j] for j in j_t2[t-3]) -
        a_paper_t[t-3] * y_paper_m[m]) for t=4:6) +
      p_fuel * sum(e_i[i] * y_mi[m, i] for i=1:5) +
      sum(omega_i[i]^(m-1) * gamma_ik[i, k] * z_mik[m, i, k] -
        omega_i[i]^(m-1) * delta_ik[i, k] * z_mik[m, i, k]^2
        for i=1:5, k=1:4) +
      sum(omega_j[j]^(m-1) * gamma_jk[j, k] * z_mjk[m, j, k] -
        omega_j[j]^(m-1) * delta_jk[j, k] * z_mjk[m, j, k]^2
        for j=1:2, k=1:4) +
      sum(omega_paper^(m-1) * gamma_paper_k[k] * z_paper_mk[m, k] -
        omega_paper^(m-1) * delta_paper_k[k] * z_paper_mk[m, k]^2
        for k=1:4)) * sigma^(m-1) for m = 1:3
      ) +

    ## cost of capacity expansion
    -sum(
      (o_saw * (x_saw_m[m] - x_saw_m[m - 1]) +
        o_plywood * (x_plywood_m[m] - x_plywood_m[m-1]) +
        sum(o_j[j] * (x_mj[m, j] - x_mj[m-1, j]) for j=1:2) +
        o_paper * (x_paper_m[m] - x_paper_m[m-1])
        ) * sigma^(m-2) for m = 2:3
      )
    )

  @constraint(mod, mat_cons_1[t=1:3, m=1:3],
    h_mt[m, t] >= sum(a_i[i] * y_mi[m, i] for i in i_t1[t]))
  @constraint(mod, mat_cons_2[t=4:6, m=1:3],
    h_mt[m, t] + sum(b_i[i] * y_mi[m, i] for i in i_t2[t-3]) >=
    sum(a_j[j] * y_mj[m, j] for j in j_t2[t-3]) +
    a_paper_t[t-3] * y_paper_m[m])
  @constraint(mod, mat_cons_3[j=1:2, m=1:3],
    y_mj[m, j] >= b_paper_j[j] * y_paper_m[m])
  @constraint(mod, mat_cons_4[i=1:5, m=1:3],
    y_mi[m, i] >= sum(z_mik[m, i, k] for k=1:4))
  @constraint(mod, mat_cons_5[j=1:2, m=1:3],
    y_mj[m, j] - b_paper_j[j] * y_paper_m[m] >= sum(z_mjk[m, j, k] for k=1:4))
  @constraint(mod, vec_cons_6[m=1:3],
    y_paper_m[m] >= sum(z_paper_mk[m, k] for k=1:4))
  @constraint(mod, vec_cons_7[m=1:3],
    sum(y_mi[m, i] for i=1:3) <= x_saw_m[m])
  @constraint(mod, vec_cons_8[m=1:3],
    sum(y_mi[m, i] for i=4:5) <= x_plywood_m[m])
  @constraint(mod, mat_cons_9[j=1:2, m=1:3],
    y_mj[m, j] <= x_mj[m, j])
  @constraint(mod, vec_cons_10[m=1:3],
    y_paper_m[m] <= x_paper_m[m])

  ## relation between capacities
  @constraint(mod, vec_cons_11[m=2:3],
    x_saw_m[m-1] <= x_saw_m[m])
  @constraint(mod, vec_cons_12[m=2:3],
    x_plywood_m[m-1] <= x_plywood_m[m])
  @constraint(mod, mat_cons_13[m=2:3, j=1:2],
    x_mj[m-1, j] <= x_mj[m, j])
  @constraint(mod, vec_cons_14[m=2:3],
    x_paper_m[m-1] <= x_paper_m[m])
  @constraint(mod, mat_cons_15[m=2:3, j=1:2],
    x_mj[m, j] <= r_j[j] * nu_j[j])
    # the result of max constraints are set when defining the variables.
  @constraint(mod, x_saw_m[1] == r_saw)
  @constraint(mod, x_plywood_m[1] == r_plywood)
  @constraint(mod, vec_cons_16[j=1:2], x_mj[1, j] == r_j[j])
  @constraint(mod, x_paper_m[1] == r_paper)

  optimize!(mod)

  result_h_mt = value_mat(h_mt)
  result_y_mi = value_mat(y_mi)
  result_y_mj = value_mat(y_mj)
  result_y_paper_m = value_vec(y_paper_m)
  result_z_mik = value_mat3(z_mik)
  result_z_mjk = value_mat3(z_mjk)
  result_z_paper_mk = value_mat(z_paper_mk)
  result_x_saw_m = value_vec(x_saw_m)
  result_x_plywood_m = value_vec(x_plywood_m)
  result_x_mj = value_mat(x_mj)
  result_x_paper_m = value_vec(x_paper_m)
  result_obj = objective_value(mod)

  println("result_obj = $result_obj ;")
  # println(result_h_mt)
  # println(result_y_mi)
  # println(result_y_mj)
  # println(result_y_paper_m)

  print_result_2(result_h_mt, result_y_mi, result_y_mj, result_y_paper_m,
    result_z_mik, result_z_mjk, result_z_paper_mk, alpha_t, beta_t, a_i, b_i,
    e_i, c_i, r_saw, r_plywood, a_j, c_j, r_j, a_paper_t, b_paper_j, c_paper,
    r_paper, gamma_ik, delta_ik, gamma_jk, delta_jk, gamma_paper_k,
    delta_paper_k, p_fuel, sigma, omega_i, omega_j, omega_paper, nu_saw,
    nu_plywood, nu_j, nu_paper, o_saw, o_plywood, o_j, o_paper, i_t1, i_t2,
    j_t2, result_x_saw_m, result_x_plywood_m, result_x_mj, result_x_paper_m)
end


text:
"""
This module provides utilities to build neural networks with Flux,
along with a library of standard architectures.
"""
module FluxLib

export SimpleNet, SimpleNetHP, ResNet, ResNetHP, Gcn, GcnHP, Gin, GinHP, GraphSAGE, GraphSAGEHP

using ..AlphaZero

using CUDA
using Base: @kwdef
#using Statistics: var

import Flux
import GraphNeuralNetworks

CUDA.allowscalar(false)
array_on_gpu(::Array) = false
array_on_gpu(::CuArray) = true
array_on_gpu(arr) = error("Usupported array type: ", typeof(arr))

using Flux: relu, softmax, flatten, σ
using Flux: Chain, Dense, Conv, BatchNorm, SkipConnection, Parallel
using GraphNeuralNetworks: GCNConv, SAGEConv
import Zygote

function Flux.unbatch(g::GraphNeuralNetworks.GNNGraph, x)
  changes = g.graph_indicator[1:end-1] .!= g.graph_indicator[2:end]
  index =  [0; Array(findall(changes)); length(g.graph_indicator)]
  return [x[index[i]+1:index[i+1]] for i in 1:g.num_graphs]
end

#####
##### Flux Networks
#####

"""
    FluxNetwork <: AbstractNetwork

Abstract type for neural networks implemented using the _Flux_ framework.

The `regularized_params_` function must be overrided for all layers containing
parameters that are subject to regularization.

Provided that the above holds, `FluxNetwork` implements the full
network interface with the following exceptions:
[`Network.HyperParams`](@ref), [`Network.hyperparams`](@ref),
[`Network.forward`](@ref) and [`Network.on_gpu`](@ref).
"""
abstract type FluxNetwork <: AbstractNetwork end

function Base.copy(nn::Net) where Net <: FluxNetwork
  #new = Net(Network.hyperparams(nn))
  #Flux.loadparams!(new, Flux.params(nn))
  #return new
  return Base.deepcopy(nn)
end

Network.to_cpu(nn::FluxNetwork) = Flux.cpu(nn)

function Network.to_gpu(nn::FluxNetwork)
  CUDA.allowscalar(false)
  return Flux.gpu(nn)
end

function Network.set_test_mode!(nn::FluxNetwork, mode)
  Flux.testmode!(nn, mode)
end

Network.convert_input(nn::FluxNetwork, x) =
  Network.on_gpu(nn) ? Flux.gpu(x) : x

Network.convert_output(nn::FluxNetwork, x) = Flux.cpu(x)

Network.params(nn::FluxNetwork) = [Flux.params(nn)]

Network.set_params!(nn::FluxNetwork, weights) = Flux.loadparams!(nn, weights[1])

# This should be included in Flux
function lossgrads(f, args...)
  val, back = Zygote.pullback(f, args...)
  grad = back(Zygote.sensitivity(val))
  return val, grad
end

function Network.train!(callback, nn::FluxNetwork, opt::Adam, loss, data, n)
  optimiser = Flux.ADAM(opt.lr)
  params = Flux.params(nn)
  for (i, d) in enumerate(data)
    d = Network.convert_input_tuple(nn, d)
    l, grads = lossgrads(params) do
      loss(d...)
    end
    Flux.update!(optimiser, params, grads)
    callback(i, l)
  end
end

function Network.train!(
    callback, nn::FluxNetwork, opt::CyclicNesterov, loss, data, n)
  lr = CyclicSchedule(
    opt.lr_base,
    opt.lr_high,
    opt.lr_low, n=n)
  momentum = CyclicSchedule(
    opt.momentum_high,
    opt.momentum_low,
    opt.momentum_high, n=n)
  optimiser = Flux.Nesterov(opt.lr_low, opt.momentum_high)
  params = Flux.params(nn)
  for (i, d) in enumerate(data)
    l, grads = lossgrads(params) do
      loss(d...)
    end
    Flux.update!(optimiser, params, grads)
    optimiser.eta = lr[i]
    optimiser.rho = momentum[i]
    callback(i, l)
  end
end

regularized_params_(l) = []
regularized_params_(l::GraphNeuralNetworks.GCNConv) = [l.weight, l.bias]
regularized_params_(l::GraphNeuralNetworks.SAGEConv) = [l.weight, l.bias]
regularized_params_(l::Flux.Dense) = [l.weight]
regularized_params_(l::Flux.Conv) = [l.weight]

function Network.regularized_params(net::FluxNetwork)
  return (w for l in Flux.modules(net) for w in regularized_params_(l))
end

function Network.gc(::FluxNetwork)
  GC.gc(true)
  # CUDA.reclaim()
end

#####
##### Common functions between two-head neural networks
#####

"""
    TwoHeadNetwork <: FluxNetwork

An abstract type for two-head neural networks implemented with Flux.

Subtypes are assumed to have fields
`hyper`, `gspec`, `common`, `vhead` and `phead`. Based on those, an implementation
is provided for [`Network.hyperparams`](@ref), [`Network.game_spec`](@ref),
[`Network.forward`](@ref) and [`Network.on_gpu`](@ref), leaving only
[`Network.HyperParams`](@ref) to be implemented.
"""
abstract type TwoHeadNetwork <: FluxNetwork end

abstract type TwoHeadGraphNeuralNetwork <: TwoHeadNetwork end

Network.params(nn::TwoHeadNetwork) = [Flux.params(nn.common), Flux.params(nn.vhead), Flux.params(nn.phead)]

function Network.set_params!(nn::TwoHeadNetwork, weights)
  Flux.loadparams!(nn.common,weights[1])
  Flux.loadparams!(nn.vhead, weights[2])
  Flux.loadparams!(nn.phead, weights[3])
end

function Network.forward(nn::TwoHeadGraphNeuralNetwork, state)
  c = nn.common(state, state.ndata.x)
  v = nn.vhead(state, c)
  p = nn.phead(state, c)
  p = softmax_nodes(state, p)
  p = Flux.unbatch(state, p)
  return (p, v)
end

function Network.forward(nn::TwoHeadNetwork, state)
  c = nn.common(state)
  v = nn.vhead(c)
  p = nn.phead(c)
  return (p, v)
end

# Flux.@functor does not work with abstract types
function Flux.functor(nn::Net) where Net <: TwoHeadNetwork
  children = (nn.common, nn.vhead, nn.phead)
  constructor = cs -> Net(nn.gspec, nn.hyper, cs...)
  return (children, constructor)
end

Network.hyperparams(nn::TwoHeadNetwork) = nn.hyper

Network.game_spec(nn::TwoHeadNetwork) = nn.gspec

Network.on_gpu(nn::TwoHeadNetwork) = array_on_gpu(nn.vhead[end].bias)

#####
##### Include networks library
#####

include("architectures/simplenet.jl")
include("architectures/resnet.jl")
include("architectures/gcn.jl")
include("architectures/gin.jl")
include("architectures/graphSAGE.jl")
end


text:
# Error bar plotting/annotation

function PlotErrorBars(label_id, x::AbstractArray{T}, y::AbstractArray{T}, err::AbstractArray{T}, count::Integer, offset::Integer = 0, stride::Integer = sizeof(T)) where {T<:ImPlotData}
    LibCImPlot.PlotErrorBars(label_id, x, y, err, count, offset, stride)
end

function PlotErrorBars(label_id, x::AbstractArray{T}, y::AbstractArray{T}, neg::AbstractArray{T}, pos::AbstractArray{T}, count::Integer, offset::Integer = 0, stride::Integer = sizeof(T)) where {T<:ImPlotData}
    LibCImPlot.PlotErrorBars(label_id, x, y, neg, pos, count, offset, stride)
end

function PlotErrorBars(label_id, x::AbstractArray{T}, y::AbstractArray{T}, err::AbstractArray{T}, count::Integer, offset::Integer = 0, stride::Integer = sizeof(Float64)) where {T<:Real}
    LibCImPlot.PlotErrorBars(label_id, Float64.(x), Float64.(y), Float64.(err), count, offset, stride)
end

function PlotErrorBars(label_id, x::AbstractArray{T}, y::AbstractArray{T}, neg::AbstractArray{T}, pos::AbstractArray{T}, count::Integer, offset::Integer = 0, stride::Integer = sizeof(Float64)) where {T<:Real}
    LibCImPlot.PlotErrorBars(label_id, Float64.(x), Float64.(y), Floa64.(neg), Float64.(pos), count, offset, stride)
end

function PlotErrorBars(x::AbstractArray{T}, y::AbstractArray{T}, error::AbstractArray{T};
                       label_id::String = "",
                       count::Integer = min(length(x), length(y), length(error)),
                       offset::Integer = 0, stride::Integer = 1) where {T <: ImPlotData}

    LibCImPlot.PlotErrorBars(label_id, x, y, error, count, offset, stride * sizeof(T))
end

function PlotErrorBars(x::AbstractArray{T}, y::AbstractArray{T},
                       negative::AbstractArray{T}, positive::AbstractArray{T};
                       label_id::String = "",
                       count::Integer = min(length(x), length(y), length(negative), length(positive)),
                       offset::Integer = 0, stride::Integer = 1) where {T <: ImPlotData}

    LibCImPlot.PlotErrorBars(label_id, x, y, negative, positive, count, offset, stride * sizeof(T))
end

function PlotErrorBars(x::AbstractArray{T1}, y::AbstractArray{T2}, error::AbstractArray{T3};
                       kwargs...) where {T1<:Real,T2<:Real,T3<:Real}

    PlotErrorBars(promote(x,y,error)...; kwargs...)
end

function PlotErrorBars(x::AbstractArray{T1}, y::AbstractArray{T2}, neg::AbstractArray{T3},
                       pos::AbstractArray{T4}; kwargs...) where {T1<:Real,T2<:Real,T3<:Real,T4<:Real}

    PlotErrorBars(promote(x,y,pos,neg)...; kwargs...)
end

function PlotErrorBarsH(label_id, x::AbstractArray{T}, y::AbstractArray{T}, err::AbstractArray{T}, count::Integer, offset::Integer = 0, stride::Integer = sizeof(T)) where {T<:ImPlotData}
    LibCImPlot.PlotErrorBarsH(label_id, x, y, err, count, offset, stride)
end

function PlotErrorBarsH(label_id, x::AbstractArray{T}, y::AbstractArray{T}, neg::AbstractArray{T}, pos::AbstractArray{T}, count::Integer, offset::Integer = 0, stride::Integer = sizeof(T)) where {T<:ImPlotData}
    LibCImPlot.PlotErrorBarsH(label_id, x, y, neg, pos, count, offset, stride)
end

function PlotErrorBarsH(label_id, x::AbstractArray{T}, y::AbstractArray{T}, err::AbstractArray{T}, count::Integer, offset::Integer = 0, stride::Integer = sizeof(Float64)) where {T<:Real}
    LibCImPlot.PlotErrorBarsH(label_id, Float64.(x), Float64.(y), Float64.(err), count, offset, stride)
end

function PlotErrorBarsH(label_id, x::AbstractArray{T}, y::AbstractArray{T}, neg::AbstractArray{T}, pos::AbstractArray{T}, count::Integer, offset::Integer = 0, stride::Integer = sizeof(Float64)) where {T<:Real}
    LibCImPlot.PlotErrorBarsH(label_id, Float64.(x), Float64.(y), Floa64.(neg), Float64.(pos), count, offset, stride)
end

function PlotErrorBarsH(x::AbstractArray{T}, y::AbstractArray{T}, error::AbstractArray{T};
                       label_id::String = "",
                       count::Integer = min(length(x), length(y), length(error)),
                       offset::Integer = 0, stride::Integer = 1) where {T <: ImPlotData}

    LibCImPlot.PlotErrorBarsH(label_id, x, y, error, count, offset, stride * sizeof(T))
end

function PlotErrorBarsH(x::AbstractArray{T}, y::AbstractArray{T},
                       negative::AbstractArray{T}, positive::AbstractArray{T};
                       label_id::String = "",
                       count::Integer = min(length(x), length(y), length(negative), length(positive)),
                       offset::Integer = 0, stride::Integer = 1) where {T <: ImPlotData}

    LibCImPlot.PlotErrorBarsH(label_id, x, y, negative, positive, count, offset, stride * sizeof(T))
end

function PlotErrorBarsH(x::AbstractArray{T1}, y::AbstractArray{T2}, error::AbstractArray{T3};
                       kwargs...) where {T1<:Real,T2<:Real,T3<:Real}

    PlotErrorBarsH(promote(x,y,error)...; kwargs...)
end

function PlotErrorBarsH(x::AbstractArray{T1}, y::AbstractArray{T2}, neg::AbstractArray{T3},
                       pos::AbstractArray{T4}; kwargs...) where {T1<:Real,T2<:Real,T3<:Real,T4<:Real}

    PlotErrorBarsH(promote(x,y,neg,pos)...; kwargs...)
end


text:
"""
    CircularArc2(c::Circle2)

Constructs an arc from a full circle.
"""
CircularArc2(c::Circle2)

"""
    CircularArc2(c::Circle2, p::Point2, q::Point2)

Constructs the circular arc supported by `c`, whose source is `p` and whose
target is `q` when traversing the circle in counterclockwise direction.

If `p` and `q` are the same, the arc is in fact a full circle.

!!! info "Precondition"

    `p` and `q` lie on `c`.
"""
CircularArc2(c::Circle2, p::Point2, q::Point2)

"""
    CircularArc2(p::Point2, q::Point2, r::Point2)

Constructs an arc that is supported by the circle of type [`Circle2`](@ref)
passing through points `p`, `q` and `r`.

The source and target are respectively `p` and `r`, when traversing the
supporting circle in the counterclockwise direction.  Note that, depending on
the orientation of the point triple `(p,q,r)`, `q` may not lie on the arc.

!!! info "Precondition"

    `p`, `q`, and `r` are not collinear.
"""
CircularArc2(p::Point2, q::Point2, r::Point2)

"""
    supporting_circle(ca::CircularArc2)

Returns the supporting circle of `ca`.
"""
supporting_circle(ca::CircularArc2)

"""
    center(ca::CircularArc2)

Returns the center of `ca`'s supporting circle.
"""
center(ca::CircularArc2)

"""
    squared_radius(ca::CircularArc2)

Returns the squared radius of `ca`'s supporting circle.
"""
squared_radius(ca::CircularArc2)

"""
    source(ca::CircularArc2)

Returns the arc's starting point, supposing its supporting circle is
traversed in counterclockwise direction.
"""
source(ca::CircularArc2)

"""
    target(ca::CircularArc2)

Returns the arc's ending point, supposing its supporting circle is traversed
in counterclockwise direction.
"""
target(ca::CircularArc2)

"""
    left(ca::CircularArc2)

Returns the arc's leftmost point.

!!! info "Precondition"

    `is_x_monotone(ca)`
"""
left(ca::CircularArc2)

"""
    right(ca::CircularArc2)

Returns the arc's rightmost point.

!!! info "Precondition"

    `is_x_monotone(ca)`
"""
right(ca::CircularArc2)

"""
    bbox(ca::CircularArc2)

Returns a bounding box containing the arc.
"""
bbox(ca::CircularArc2)

"""
    is_x_monotone(ca::CircularArc2)

Tests whether the arc is x-monotone.
"""
is_x_monotone(ca::CircularArc2)

"""
    is_y_monotone(ca::CircularArc2)

Tests whether the arc is y-monotone.
"""
is_y_monotone(ca::CircularArc2)

"""
==(ca₁::CircularArc2, ca₂::CircularArc2)

Test for equality.

Two arcs are equal, iff their non-oriented supporting circles are equal (i.e.
they have the same center and same squared radius) and their endpoints are
equal.
"""
==(ca₁::CircularArc2, ca₂::CircularArc2)