text:
#Physical constants

module constants

export M_sun, M_earth, AU, pc, G, kB, amu, c_ang, cc, c_kms, mu_gas, m_H, m_CO, m_12CO, m_13CO, m_C18O, number_densities, molnames, arcsec, deg, fftspace, MCO, lam0_12CO, lam0_13CO, lam0_C18O, lam0s, nyquist_factor, r_out_factor, Av_sigmaH, n_z_interpolator, X_H2, rho_gas_critical
export RADMC_SIZEAU_SHIFT
export DiskJockeyException, ModelException, ImageException
export DISKJOCKEY_VERSION

DISKJOCKEY_VERSION = v"0.1.5"

# Conversion from astronomical units to CGS units
M_sun = 1.99e33 # [g]
M_earth = 5.97219e27 # [g]
AU = 1.4959787066e13 # [cm]
pc = 3.0856776e18 # [cm]
G = 6.67259e-8 # [cm3 g-1 s-2]
kB = 1.380658e-16 # [erg K^-1] Boltzmann constant
c_ang = 2.99792458e18 # [A s^-1]
cc = 2.99792458e10 # [cm s^-1]
c_kms = 2.99792458e5 # [km s^-1]

# Conversion from degrees to radians
deg = pi/180. # [radians]

mu_gas = 2.37 # mean molecular weight of circumstellar gas
m_H = 1.6733e-24 # g mass of hydrogen atom

#Atomic
amu = 1.6605402e-24 # [g]

#CO
m_CO = 28.01 * amu #molecular weight of CO in g

m_12CO = 27.9949 * amu # [g]
m_13CO = 28.9983 * amu # [g]
m_C18O = 29.9992 * amu # [g]

atomic_massses = Dict([("12CO", m_12CO), ("13CO", m_13CO), ("C18O", m_C18O)])

# Using numbers from Charlie Qi
# Number ratios measured relative to all single H nuclei (not H2) [unitless]
f_12CO = 7.5e-5
X_12CO = 2 * f_12CO
X_13CO = 1/69. * X_12CO
X_C18O = 1/557. * X_12CO

# molecular hydrogen number ratio to gas [unitless]
# [n_H2/n_gas] = 0.8
X_H2 = 0.8

# To go from rho_gas to n_12CO
# n_12CO = rho_gas * X_H2 *

# Old number densities calculated as
# 12CO = 7.5e-5 / (mu_gas * amu)

# New number density calculated as
# 12CO = 0.8 * (2 * 7.5e-5)/ (mu_gas * amu)

# new/old = 1.6
# This means that the new total disk mass we use will be 1/1.6 times smaller than the old time.

# Use this to multiply against rho_gas to get n_12CO or n_13CO
number_densities = Dict{String, Float64}([("12CO", X_H2 * X_12CO/(mu_gas * amu)), ("13CO", X_H2 * X_13CO/(mu_gas * amu)), ("C18O", X_H2 * X_C18O/(mu_gas * amu))])

molnames = Dict{String, String}([("12CO", "co"), ("13CO", "13co"), ("C18O", "c18o")])

# Species can be "12CO", "13CO", etc.
# Transition can be "3-2", "2-1", etc.

# Key to this dictionary is then species * transition

# Rest frame wavelengths
lam0s = Dict{String, Float64}([("12CO2-1", cc/230.538e9 * 1e4 ),
            ("13CO2-1", cc/220.39868420e9 * 1e4),
            ("13CO3-2", cc/330.58796530e9 * 1e4),
            ("C18O2-1", cc/219.56035410e9 * 1e4),
            ("12CO3-2", cc/345.7959899e9 * 1e4)]) # microns

# Convert from Av to hydrogen *nuclei* column density for interstellar dust
# Av_sigmaH = 1.59e21 # [cm^-2] # "standard" number
Av_sigmaH = 1.0e20 # [cm^-2] # Charlie's number

# convert from arcseconds to radians
arcsec = pi / (180.0 * 3600) # [radians]  = 1/206265 radian/arcsec

# Used when determining the necessary number of pixels in an image, given distance. Anything below
# 2 is not Nyquist sampled. This is currently set to 2.2 to provide a degree of oversampling.
nyquist_factor = 2.2

# The bound at which to force the density to zero
# n_H2 = 100 [1/cm^3] average H2 number density in diffuse ISM
rho_gas_critical = (100.0/X_H2) * mu_gas * amu # [g/cm^3]

# The number of z points to use for the density interpolator
n_z_interpolator = 64
rho_gas_zero = 1e-50

# Fractional shift that exists between commanded size of image and actual size (actual size bigger)
# Therefore, use this to demand a size that is slightly smaller, so that the actual synthesized
# image comes out being the proper size.
RADMC_SIZEAU_SHIFT = 1.4233758746704833e-5

"Oftentimes it is necessary to get a symmetric coordinate array that spans ``N``
 elements from `-width` to `+width`, but makes sure that the middle point lands
 on ``0``. The indices go from ``0`` to ``N -1.``
 `linspace` returns  the end points inclusive, wheras we want to leave out the
 right endpoint, because we are sampling the function in a cyclic manner."
function fftspace(width::Real, N::Int)
    @assert(N % 2 == 0, "N must be even.")

    dx = width * 2.0 / N
    xx = Array{Float64}(undef, N)
    for i=1:N
        xx[i] = -width + (i - 1) * dx
    end
    return xx
end

# Convert result from MCMC to M_sun
function MCO(logCO::Float64)
    # Convert to Earth mass
    CO_earth = 10^logCO

    # Convert from Earth to M_sun
    CO_sun = CO_earth * M_earth/M_sun

    # Convert from 12CO to total gas mass using the mass ratio of 1e-4
    gas_mass = CO_sun / X_12CO

    logM_gas = log10(gas_mass)

    return logM_gas
end

# Abstract exception that serves as a catch-all for any error generated by the DiskJockey package.
abstract type DiskJockeyException <: Exception end

# Define the various types of Errors that we can Raise
mutable struct ModelException <: DiskJockeyException
    msg::String
end

mutable struct ImageException <: DiskJockeyException
    msg::String
end

end # Module


text:
using LinQuadOptInterface

const LQOI = LinQuadOptInterface
const MOI  = LQOI.MOI

const SUPPORTED_OBJECTIVES = [
    LQOI.SinVar,
    LQOI.Linear,
    LQOI.Quad
]

const SUPPORTED_CONSTRAINTS = [
    (LQOI.Linear, LQOI.EQ),
    (LQOI.Linear, LQOI.LE),
    (LQOI.Linear, LQOI.GE),
    # (Linear, IV),
    (LQOI.Quad, LQOI.EQ),
    (LQOI.Quad, LQOI.LE),
    (LQOI.Quad, LQOI.GE),
    (LQOI.SinVar, LQOI.EQ),
    (LQOI.SinVar, LQOI.LE),
    (LQOI.SinVar, LQOI.GE),
    (LQOI.SinVar, LQOI.IV),
    (LQOI.SinVar, MOI.ZeroOne),
    (LQOI.SinVar, MOI.Integer),
    (LQOI.VecVar, LQOI.SOS1),
    (LQOI.VecVar, LQOI.SOS2),
    (LQOI.SinVar, MOI.Semicontinuous{Float64}),
    (LQOI.SinVar, MOI.Semiinteger{Float64}),
    (LQOI.VecVar, MOI.Nonnegatives),
    (LQOI.VecVar, MOI.Nonpositives),
    (LQOI.VecVar, MOI.Zeros),
    (LQOI.VecLin, MOI.Nonnegatives),
    (LQOI.VecLin, MOI.Nonpositives),
    (LQOI.VecLin, MOI.Zeros)
]

mutable struct Optimizer <: LQOI.LinQuadOptimizer
    LQOI.@LinQuadOptimizerBase(Model)
    env::Union{Nothing, Env}
    params::Dict{String, Any}
    # The next two fields are used to cleverly manage calls to `update_model!`.
    # `needs_update` is used to record whether an update should be called before
    # accessing a model attribute (such as the value of a RHS term). One of the
    # main pain-points when using Gurobi through JuMP is the need to access the
    # number of variables. Unfortunately, in order to use the Gurobi API (i.e.
    # `num_vars(model.inner)`), we need to call `update_model!`. To avoid
    # frequent calls just for this case, we cache the number of variables in
    # `num_variables`. There are calls in `add_variables` and `delete_variables`
    # to adjust this value. In addition, we also cache the number of linear and
    # quadratic constraints.
    needs_update::Bool
    num_variables::Int
    num_linear_constraints::Int
    num_quadratic_constraints::Int

    """
        Optimizer(env = nothing; kwargs...)

    Create a new Optimizer object.

    You can share Gurobi `Env`s between models by passing an instance of `Env`
    as the first argument. By default, a new environment is created for every
    model.

    Note that we set the parameter `InfUnbdInfo` to `1` rather than the default
    of `0` so that we can query infeasibility certificates. Users are, however,
    free to overide this as follows `Gurobi.Optimizer(InfUndbInfo=0)`.
    """
    function Optimizer(env::Union{Nothing, Env} = nothing; kwargs...)
        model = new()
        model.env = env
        model.params = Dict{String, Any}()
        MOI.empty!(model)
        for (name, value) in kwargs
            model.params[string(name)] = value
            setparam!(model.inner, string(name), value)
        end
        return model
    end
end

function LQOI.LinearQuadraticModel(::Type{Optimizer}, env::Nothing)
    # The existing env is `Nothing`, so create a new one. Since we own this one,
    # make sure to finalize it.
    new_env = Env()
    return Model(new_env, "", finalize_env = true)
end

function LQOI.LinearQuadraticModel(::Type{Optimizer}, env::Env)
    # The user has passed an existing Env. Don't finalize it because we don't
    # own this one.
    return Model(env, "", finalize_env = false)
end

"""
    _require_update(model::Optimizer)

Sets the `model.needs_update` flag. Call this at the end of any mutating method.
"""
function _require_update(model::Optimizer)
    model.needs_update = true
    return
end

"""
    _require_update(model::Optimizer)

Calls `update_model!`, but only if the `model.needs_update` flag is set.
"""
function _update_if_necessary(model::Optimizer)
    if model.needs_update
        update_model!(model.inner)
        model.needs_update = false
    end
    return
end

MOI.get(::Optimizer, ::MOI.SolverName) = "Gurobi"

function MOI.empty!(model::Optimizer)
    MOI.empty!(model, model.env)
    setparam!(model.inner, "InfUnbdInfo", 1)
    for (name, value) in model.params
        setparam!(model.inner, name, value)
    end
    model.needs_update = false
    model.num_variables = 0
    model.num_linear_constraints = 0
    model.num_quadratic_constraints = 0
    return
end

LQOI.supported_constraints(::Optimizer) = SUPPORTED_CONSTRAINTS
LQOI.supported_objectives(::Optimizer)  = SUPPORTED_OBJECTIVES

LQOI.backend_type(::Optimizer, ::MOI.EqualTo{Float64})     = Cchar('=')
LQOI.backend_type(::Optimizer, ::MOI.LessThan{Float64})    = Cchar('<')
LQOI.backend_type(::Optimizer, ::MOI.GreaterThan{Float64}) = Cchar('>')
LQOI.backend_type(::Optimizer, ::MOI.Zeros)                = Cchar('=')
LQOI.backend_type(::Optimizer, ::MOI.Nonpositives)         = Cchar('<')
LQOI.backend_type(::Optimizer, ::MOI.Nonnegatives)         = Cchar('>')

function LQOI.change_variable_bounds!(model::Optimizer,
          columns::Vector{Int}, new_bounds::Vector{Float64},
          senses::Vector{Cchar})
    number_lower_bounds = count(x->x==Cchar('L'), senses)
    lower_cols   = fill(0, number_lower_bounds)
    lower_values = fill(0.0, number_lower_bounds)
    number_upper_bounds = count(x->x==Cchar('U'), senses)
    upper_cols   = fill(0, number_upper_bounds)
    upper_values = fill(0.0, number_upper_bounds)
    lower_index = 1
    upper_index = 1
    for (column, bound, sense) in zip(columns, new_bounds, senses)
        if sense == Cchar('L')
            lower_cols[lower_index]   = column
            lower_values[lower_index] = bound
            lower_index += 1
        elseif sense == Cchar('U')
            upper_cols[upper_index]   = column
            upper_values[upper_index] = bound
            upper_index += 1
        end
    end
    if number_lower_bounds > 0
        set_dblattrlist!(model.inner, "LB", lower_cols, lower_values)
    end
    if number_upper_bounds > 0
        set_dblattrlist!(model.inner, "UB", upper_cols, upper_values)
    end
    _require_update(model)
    return
end

function LQOI.set_variable_bound(model::Optimizer, var::LQOI.SinVar, set::LQOI.LE)
    column = LQOI.get_column(model, var)
    set_dblattrelement!(model.inner, "UB", column, set.upper)
    _require_update(model)
    return
end

function LQOI.set_variable_bound(model::Optimizer, var::LQOI.SinVar, set::LQOI.GE)
    column = LQOI.get_column(model, var)
    set_dblattrelement!(model.inner, "LB", column, set.lower)
    _require_update(model)
    return
end

function LQOI.set_variable_bound(model::Optimizer, var::LQOI.SinVar, set::LQOI.EQ)
    column = LQOI.get_column(model, var)
    set_dblattrelement!(model.inner, "LB", column, set.value)
    set_dblattrelement!(model.inner, "UB", column, set.value)
    _require_update(model)
    return
end

function LQOI.set_variable_bound(model::Optimizer, var::LQOI.SinVar, set::LQOI.IV)
    column = LQOI.get_column(model, var)
    set_dblattrelement!(model.inner, "LB", column, set.lower)
    set_dblattrelement!(model.inner, "UB", column, set.upper)
    _require_update(model)
    return
end

function LQOI.get_variable_lowerbound(model::Optimizer, column::Int)
    _update_if_necessary(model)
    return get_dblattrelement(model.inner, "LB", column)
end

function LQOI.get_variable_upperbound(model::Optimizer, column::Int)
    _update_if_necessary(model)
    return get_dblattrelement(model.inner, "UB", column)
end

function LQOI.get_number_linear_constraints(model::Optimizer)
    # See the definition in Optimizer.
    return model.num_linear_constraints
end

function LQOI.add_linear_constraints!(model::Optimizer,
        A::LQOI.CSRMatrix{Float64}, sense::Vector{Cchar}, rhs::Vector{Float64})
    add_constrs!(model.inner, A.row_pointers, A.columns, A.coefficients, sense, rhs)
    model.num_linear_constraints += length(rhs)
    _require_update(model)
    return
end

function LQOI.get_rhs(model::Optimizer, row::Int)
    _update_if_necessary(model)
    return get_dblattrelement(model.inner, "RHS", row)
end

function LQOI.get_linear_constraint(model::Optimizer, row::Int)
    _update_if_necessary(model)
    A = SparseArrays.sparse(get_constrs(model.inner, row, 1)')
    # note: we return 1-index columns
    return A.rowval, A.nzval
end

function LQOI.change_matrix_coefficient!(model::Optimizer, row::Int, col::Int, coef::Float64)
    chg_coeffs!(model.inner, row, col, coef)
    _require_update(model)
    return
end

function LQOI.change_objective_coefficient!(model::Optimizer, col::Int, coef::Float64)
    set_dblattrelement!(model.inner, "Obj", col, coef)
    _require_update(model)
    return
end

function LQOI.change_rhs_coefficient!(model::Optimizer, row::Int, coef::Float64)
    set_dblattrelement!(model.inner, "RHS", row, coef)
    _require_update(model)
    return
end

function LQOI.delete_linear_constraints!(model::Optimizer, first_row::Int, last_row::Int)
    _update_if_necessary(model)
    del_constrs!(model.inner, collect(first_row:last_row))
    model.num_linear_constraints -= last_row - first_row + 1
    _require_update(model)
    return
end

function LQOI.delete_quadratic_constraints!(model::Optimizer, first_row::Int, last_row::Int)
    _update_if_necessary(model)
    delqconstrs!(model.inner, collect(first_row:last_row))
    model.num_quadratic_constraints -= last_row - first_row + 1
    _require_update(model)
    return
end

function LQOI.change_variable_types!(model::Optimizer, columns::Vector{Int}, vtypes::Vector{Cchar})
    set_charattrlist!(model.inner, "VType", Cint.(columns), vtypes)
    _require_update(model)
    return
end

function LQOI.change_linear_constraint_sense!(model::Optimizer, rows::Vector{Int}, senses::Vector{Cchar})
    set_charattrlist!(model.inner, "Sense", Cint.(rows), senses)
    _require_update(model)
    return
end

function LQOI.add_sos_constraint!(model::Optimizer, columns::Vector{Int}, weights::Vector{Float64}, sos_type)
    add_sos!(model.inner, sos_type, columns, weights)
    _require_update(model)
    return
end

function LQOI.delete_sos!(model::Optimizer, first_row::Int, last_row::Int)
    _update_if_necessary(model)
    del_sos!(model.inner, Cint.(first_row:last_row))
    _require_update(model)
    return
end

# TODO improve getting processes
function LQOI.get_sos_constraint(model::Optimizer, idx)
    _update_if_necessary(model)
    A, types = get_sos_matrix(model.inner)
    line = A[idx,:] #sparse vec
    cols = line.nzind
    vals = line.nzval
    typ = types[idx] == Cint(1) ? :SOS1 : :SOS2
    return cols, vals, typ
end

function LQOI.get_number_quadratic_constraints(model::Optimizer)
    # See the definition of Optimizer.
    return model.num_quadratic_constraints
end

function scalediagonal!(V, I, J, scale)
    #  LQOI assumes 0.5 x' Q x, but Gurobi requires the list of terms, e.g.,
    #  2x^2 + xy + y^2, so we multiply the diagonal of V by 0.5. We don't
    #  multiply the off-diagonal terms since we assume they are symmetric and we
    #  only need to give one.
    #
    #  We also need to make sure that after adding the constraint we un-scale
    #  the vector because we can't modify user-data.
    for i in 1:length(I)
        if I[i] == J[i]
            V[i] *= scale
        end
    end
    return
end
function LQOI.add_quadratic_constraint!(model::Optimizer,
        affine_columns::Vector{Int}, affine_coefficients::Vector{Float64},
        rhs::Float64, sense::Cchar,
        I::Vector{Int}, J::Vector{Int}, V::Vector{Float64})
    @assert length(I) == length(J) == length(V)
    scalediagonal!(V, I, J, 0.5)
    add_qconstr!(model.inner, affine_columns, affine_coefficients, I, J, V, sense, rhs)
    scalediagonal!(V, I, J, 2.0)
    model.num_quadratic_constraints += 1
    _require_update(model)
    return
end

function LQOI.get_quadratic_constraint(model::Optimizer, row::Int)
    _update_if_necessary(model)
    affine_cols, affine_coefficients, I, J, V = getqconstr(model.inner, row)
    # note: we return 1-index columns here
    affine_cols .+= 1
    I .+= 1
    J .+= 1
    return affine_cols, affine_coefficients, SparseArrays.sparse(I, J, V)
end

function LQOI.get_quadratic_rhs(model::Optimizer, row::Int)
    _update_if_necessary(model)
    return get_dblattrelement(model.inner, "QCRHS", row)
end

function LQOI.set_quadratic_objective!(model::Optimizer, I::Vector{Int}, J::Vector{Int}, V::Vector{Float64})
    @assert length(I) == length(J) == length(V)
    delq!(model.inner)
    scalediagonal!(V, I, J, 0.5)
    add_qpterms!(model.inner, I, J, V)
    scalediagonal!(V, I, J, 2.0)
    _require_update(model)
    return
end

function LQOI.set_linear_objective!(model::Optimizer, columns::Vector{Int}, coefficients::Vector{Float64})
    nvars = LQOI.get_number_variables(model)
    obj = zeros(Float64, nvars)
    for (col, coef) in zip(columns, coefficients)
        obj[col] += coef
    end
    _update_if_necessary(model)
    set_dblattrarray!(model.inner, "Obj", 1, nvars, obj)
    _require_update(model)
    return
end

function LQOI.set_constant_objective!(model::Optimizer, value::Real)
    set_dblattr!(model.inner, "ObjCon", value)
    if LQOI.get_number_variables(model) > 0
        # Work-around for https://github.com/JuliaOpt/LinQuadOptInterface.jl/pull/44#issuecomment-409373755
        _update_if_necessary(model)
        set_dblattrarray!(model.inner, "Obj", 1, 1,
            get_dblattrarray(model.inner, "Obj", 1, 1))
    end
    _require_update(model)
    return
end

function LQOI.change_objective_sense!(model::Optimizer, sense::Symbol)
    if sense == :min
        set_sense!(model.inner, :minimize)
    elseif sense == :max
        set_sense!(model.inner, :maximize)
    else
        error("Invalid objective sense: $(sense)")
    end
    _require_update(model)
    return
end

function LQOI.get_linear_objective!(model::Optimizer, dest)
    _update_if_necessary(model)
    get_dblattrarray!(dest, model.inner, "Obj", 1)
    return dest
end

function LQOI.get_constant_objective(model::Optimizer)
    _update_if_necessary(model)
    return get_dblattr(model.inner, "ObjCon")
end

function LQOI.get_objectivesense(model::Optimizer)
    _update_if_necessary(model)
    sense = model_sense(model.inner)
    if sense == :maximize
        return MOI.MAX_SENSE
    elseif sense == :minimize
        return MOI.MIN_SENSE
    else
        error("Invalid objective sense: $(sense)")
    end
end

function LQOI.get_number_variables(model::Optimizer)
    # See the comment in the definition of Optimizer.
    return model.num_variables
end

function LQOI.add_variables!(model::Optimizer, N::Int)
    add_cvars!(model.inner, zeros(N))
    model.num_variables += N
    _require_update(model)
    return
end

function LQOI.delete_variables!(model::Optimizer, first_col::Int, last_col::Int)
    _update_if_necessary(model)
    del_vars!(model.inner, Cint.(first_col:last_col))
    model.num_variables -= length(first_col:last_col)
    _require_update(model)
    return
end

function LQOI.add_mip_starts!(model::Optimizer, columns::Vector{Int}, starts::Vector{Float64})
    _update_if_necessary(model)
    nvars = LQOI.get_number_variables(model)
    x = zeros(nvars)
    for (col, val) in zip(columns, starts)
        x[col] = val
    end
    loadbasis(model.inner, x)
    _require_update(model)
    return
end
function MOI.supports(
        ::Optimizer, ::MOI.VariablePrimalStart, ::Type{MOI.VariableIndex})
    return true
end

LQOI.solve_mip_problem!(model::Optimizer) = LQOI.solve_linear_problem!(model)

LQOI.solve_quadratic_problem!(model::Optimizer) = LQOI.solve_linear_problem!(model)

function LQOI.solve_linear_problem!(model::Optimizer)
    # Note: Gurobi will call update regardless, so we don't have to.
    optimize(model.inner)
    return
end

function LQOI.get_termination_status(model::Optimizer)
    stat = get_status(model.inner)
    if stat == :loaded
        return MOI.OTHER_ERROR
    elseif stat == :optimal
        return MOI.OPTIMAL
    elseif stat == :infeasible
        return MOI.INFEASIBLE
    elseif stat == :inf_or_unbd
        return MOI.INFEASIBLE_OR_UNBOUNDED
    elseif stat == :unbounded
        return MOI.DUAL_INFEASIBLE
    elseif stat == :cutoff
        return MOI.OBJECTIVE_LIMIT
    elseif stat == :iteration_limit
        return MOI.ITERATION_LIMIT
    elseif stat == :node_limit
        return MOI.NODE_LIMIT
    elseif stat == :time_limit
        return MOI.TIME_LIMIT
    elseif stat == :solution_limit
        return MOI.SOLUTION_LIMIT
    elseif stat == :interrupted
        return MOI.INTERRUPTED
    elseif stat == :numeric
        return MOI.NUMERICAL_ERROR
    elseif stat == :suboptimal
        return MOI.OTHER_LIMIT
    elseif stat == :inprogress
        return MOI.OTHER_ERROR
    elseif stat == :user_obj_limit
        return MOI.OBJECTIVE_LIMIT
    end
    return MOI.OTHER_ERROR
end

function LQOI.get_primal_status(model::Optimizer)
    stat = get_status(model.inner)
    if stat == :optimal
        return MOI.FEASIBLE_POINT
    elseif stat == :solution_limit
        return MOI.FEASIBLE_POINT
    elseif (stat == :inf_or_unbd || stat == :unbounded) && has_primal_ray(model)
        return MOI.INFEASIBILITY_CERTIFICATE
    elseif stat == :suboptimal
        return MOI.FEASIBLE_POINT
    elseif is_mip(model.inner) && get_sol_count(model.inner) > 0
        return MOI.FEASIBLE_POINT
    else
        return MOI.NO_SOLUTION
    end
end

function LQOI.get_dual_status(model::Optimizer)
    stat = get_status(model.inner)
    if is_mip(model.inner) || is_qcp(model.inner)
        return MOI.NO_SOLUTION
    else
        if stat == :optimal
            return MOI.FEASIBLE_POINT
        elseif stat == :solution_limit
            return MOI.FEASIBLE_POINT
        elseif (stat == :inf_or_unbd || stat == :infeasible) && has_dual_ray(model)
            return MOI.INFEASIBILITY_CERTIFICATE
        elseif stat == :suboptimal
            return MOI.FEASIBLE_POINT
        end
    end
    return MOI.NO_SOLUTION
end

function LQOI.get_variable_primal_solution!(model::Optimizer, dest)
    get_dblattrarray!(dest, model.inner, "X", 1)
    return
end

function LQOI.get_linear_primal_solution!(model::Optimizer, dest)
    get_dblattrarray!(dest, model.inner, "RHS", 1)
    dest .-= get_dblattrarray(model.inner, "Slack", 1, num_constrs(model.inner))
    return
end

function LQOI.get_quadratic_primal_solution!(model::Optimizer, dest)
    get_dblattrarray!(dest, model.inner, "QCRHS", 1)
    dest .-= get_dblattrarray(model.inner, "QCSlack", 1, num_qconstrs(model.inner))
    return
end

function LQOI.get_variable_dual_solution!(model::Optimizer, dest)
    get_dblattrarray!(dest, model.inner, "RC", 1)
    return
end

function LQOI.get_linear_dual_solution!(model::Optimizer, dest)
    get_dblattrarray!(dest, model.inner, "Pi", 1)
    return
end

function LQOI.get_quadratic_dual_solution!(model::Optimizer, dest)
    get_dblattrarray!(dest, model.inner, "QCPi", 1)
    return
end

LQOI.get_objective_value(model::Optimizer) = get_objval(model.inner)

function LQOI.get_objective_bound(model::Optimizer)
    return get_objbound(model.inner)
end

function LQOI.get_relative_mip_gap(model::Optimizer)
    value = LQOI.get_objective_value(model)
    bound = LQOI.get_objective_bound(model)
    return abs(value - bound) / abs(bound)
end

function LQOI.get_iteration_count(instance::Optimizer)
    return get_iter_count(instance.inner)
end

function LQOI.get_barrier_iterations(instance::Optimizer)
    return get_barrier_iter_count(instance.inner)
end

function LQOI.get_node_count(instance::Optimizer)
    return get_node_count(instance.inner)
end

function LQOI.get_farkas_dual!(instance::Optimizer, dest)
    get_dblattrarray!(dest, instance.inner, "FarkasDual", 1)
    dest .*= -1.0
    return
end

function has_dual_ray(model::Optimizer)
    try
        # Note: for performance reasons, we try to get 1 element because for
        # some versions of Gurobi, we cannot query 0 elements without error.
        Gurobi.get_dblattrarray(model.inner, "FarkasDual", 1, 1)
        return true
    catch ex
        if isa(ex, Gurobi.GurobiError)
            return false
        else
            rethrow(ex)
        end
    end
end

function LQOI.get_unbounded_ray!(model::Optimizer, dest)
    get_dblattrarray!(dest, model.inner, "UnbdRay", 1)
    return
end

function has_primal_ray(model::Optimizer)
    try
        # Note: for performance reasons, we try to get 1 element because for
        # some versions of Gurobi, we cannot query 0 elements without error.
        Gurobi.get_dblattrarray(model.inner, "UnbdRay", 1, 1)
        return true
    catch ex
        if isa(ex, Gurobi.GurobiError)
            return false
        else
            rethrow(ex)
        end
    end
end

# ==============================================================================
#    Callbacks in Gurobi
# ==============================================================================
struct CallbackFunction <: MOI.AbstractOptimizerAttribute end
function MOI.set(model::Optimizer, ::CallbackFunction, f::Function)
    set_callback_func!(model.inner, f)
    update_model!(model.inner)
    return
end

"""
    loadcbsolution!(m::Optimizer, cb_data::GurobiCallbackData, cb_where::Int)

Load the variable primal solution in a callback.

This can only be called in a callback from `CB_MIPSOL`. After it is called, you
can access the `VariablePrimal` attribute as usual.
"""
function loadcbsolution!(model::Optimizer, cb_data::CallbackData, cb_where::Cint)
    if cb_where != CB_MIPSOL
        error("loadcbsolution! can only be called from CB_MIPSOL.")
    end
    Gurobi.cbget_mipsol_sol(cb_data, cb_where, model.variable_primal_solution)
    return
end

"""
    cblazy!(cb_data::Gurobi.CallbackData, m::Optimizer, func::LQOI.Linear, set::S) where S <: Union{LQOI.LE, LQOI.GE, LQOI.EQ}

Add a lazy cut to the model `m`.

You must have the option `LazyConstraints` set  via `Optimizer(LazyConstraint=1)`.
This can only be called in a callback from `CB_MIPSOL`.
"""
function cblazy!(cb_data::CallbackData, model::Optimizer,
        func::LQOI.Linear, set::S) where S <: Union{LQOI.LE, LQOI.GE, LQOI.EQ}
    columns = [
        Cint(LQOI.get_column(model, term.variable_index)) for term in func.terms]
    coefficients = [term.coefficient for term in func.terms]
    sense = Char(LQOI.backend_type(model, set))
    rhs = MOI.Utilities.getconstant(set)
    return cblazy(cb_data, columns, coefficients, sense, rhs)
end

# The default implementation in LQOI is too slow for Gurobi since it has a
# lookup of the variable bounds (calling _update_if_required), but it also sets
# the variable bounds and the VType (calling _require_update). Thus, if you add
# multiple ZeroOne constraints in sequence, you will call update every time!
function MOI.add_constraint(
        model::Optimizer, variable::MOI.SingleVariable, set::MOI.ZeroOne)
    variable_type = model.variable_type[variable.variable]
    if variable_type != LQOI.CONTINUOUS
        error("Cannot make variable binary because it is $(variable_type).")
    end
    model.variable_type[variable.variable] = LQOI.BINARY
    model.last_constraint_reference += 1
    index = MOI.ConstraintIndex{MOI.SingleVariable, MOI.ZeroOne}(
        model.last_constraint_reference)
    dict = LQOI.constrdict(model, index)
    dict[index] = (variable.variable, -Inf, Inf)
    column = LQOI.get_column(model, variable)
    set_charattrelement!(model.inner, "VType", column, Char('B'))
    _require_update(model)
    return index
end

function MOI.delete(model::Optimizer,
                    index::MOI.ConstraintIndex{MOI.SingleVariable, MOI.ZeroOne})
    LQOI.__assert_valid__(model, index)
    LQOI.delete_constraint_name(model, index)
    dict = LQOI.constrdict(model, index)
    (variable, lower, upper) = dict[index]
    model.variable_type[variable] = LQOI.CONTINUOUS
    column = LQOI.get_column(model, variable)
    set_charattrelement!(model.inner, "VType", column, Char('C'))
    _require_update(model)
    delete!(dict, index)
    return
end

ext: jl


text:
# example 3: version information, default values, options with
#            types and variable number of arguments

using ArgParse

function main(args)

    s = ArgParseSettings("Example 3 for argparse.jl: " *
                         "version info, default values, " *
                         "options with types, variable " *
                         "number of arguments.",
                         version = "Version 1.0", # version info
                         add_version = true)      # audo-add version option

    @add_arg_table! s begin
        "--opt1"
            nargs = '?'              # '?' means optional argument
            arg_type = Int           # only Int arguments allowed
            default = 0              # this is used when the option is not passed
            constant = 1             # this is used if --opt1 is paseed with no argument
            help = "an option"
        "--karma", "-k"
            action = :count_invocations  # increase a counter each time the option is given
            help = "increase karma"
        "arg1"
            nargs = 2                        # eats up two arguments; puts the result in a Vector
            help = "first argument, two " *
                   "entries at once"
            required = true
        "arg2"
            nargs = '*'                            # eats up as many arguments as possible before an option
            default = Any["no_arg_given"]          # since the result will be a Vector{Any}, the default must
                                                   # also be (or it can be [] or nothing)
            help = "second argument, eats up " *
                   "as many items as possible " *
                   "before an option"
    end

    parsed_args = parse_args(args, s)
    println("Parsed args:")
    for (key,val) in parsed_args
        println("  $key  =>  $(repr(val))")
    end
end

main(ARGS)

max_stars_repo_name: dbindel/btg

max_issues_repo_name: dbindel/btg

max_forks_repo_name: dbindel/btg


text:
Base.@kwdef struct MarkdownString
    isTrusted::Bool = false
    supportThemeIcons::Bool = true
    value::String
end

JSONRPC.@dict_readable struct ReplRunCodeRequestParams <: JSONRPC.Outbound
    filename::String
    line::Int
    column::Int
    code::String
    mod::String
    showCodeInREPL::Bool
    showResultInREPL::Bool
    showErrorInREPL::Bool
    softscope::Bool
end

struct Frame
    path::String
    line::Int
end
Frame(st::Base.StackFrame) = Frame(fullpath(string(st.file)), st.line)

JSONRPC.@dict_readable struct ReplRunCodeRequestReturn <: JSONRPC.Outbound
    inline::String
    all::String
    stackframe::Union{Nothing,Vector{Frame}}
end
ReplRunCodeRequestReturn(inline, all) = ReplRunCodeRequestReturn(inline, all, nothing)

JSONRPC.@dict_readable mutable struct ReplWorkspaceItem <: JSONRPC.Outbound
    head::String
    id::Int
    haschildren::Bool
    lazy::Bool
    icon::String
    value::String
    canshow::Bool
    type::String
end

JSONRPC.@dict_readable struct GetCompletionsRequestParams <: JSONRPC.Outbound
    line::String
    mod::String
end

struct ParameterInformation
    label::Union{String,UnitRange{Int}}
    documentation::Union{Missing,String,MarkdownString}
end

struct SignatureInformation
    activeParameter::Union{Missing,Int}
    documentation::Union{Missing,String,MarkdownString}
    label::String
    parameters::Vector{ParameterInformation}
end

struct SignatureHelp
    activeParameter::Int
    activeSignature::Int
    signatures::Vector{SignatureInformation}
end

struct SignatureHelpContext
    activeSignatureHelp::Union{Missing,SignatureHelp}
    isRetrigger::Bool
    triggerCharacter::Union{Missing,String}
    triggerKind::Int
end

JSONRPC.@dict_readable struct GetSignatureHelpRequestParams
    sig::String
    mod::String
    context::Dict # TODO: annotate with SignatureHelpContext
end

JSONRPC.@dict_readable mutable struct DebugConfigTreeItem <: JSONRPC.Outbound
    label::String
    hasChildren::Bool
    juliaAccessor::String
end

JSONRPC.@dict_readable mutable struct GetTableDataRequest <: JSONRPC.Outbound
    id::String
    startRow::Int
    endRow::Int
    filterModel::Any
    sortModel::Any
end

const repl_runcode_request_type = JSONRPC.RequestType("repl/runcode", ReplRunCodeRequestParams, ReplRunCodeRequestReturn)
const repl_interrupt_notification_type = JSONRPC.NotificationType("repl/interrupt", Nothing)
const repl_getvariables_request_type = JSONRPC.RequestType("repl/getvariables", Nothing, Vector{ReplWorkspaceItem})
const repl_getlazy_request_type = JSONRPC.RequestType("repl/getlazy", NamedTuple{(:id,),Tuple{Int}}, Vector{ReplWorkspaceItem})
const repl_showingrid_notification_type = JSONRPC.NotificationType("repl/showingrid", NamedTuple{(:code,),Tuple{String}})
const repl_loadedModules_request_type = JSONRPC.RequestType("repl/loadedModules", Nothing, Vector{String})
const repl_isModuleLoaded_request_type = JSONRPC.RequestType("repl/isModuleLoaded", NamedTuple{(:mod,),Tuple{String}}, Bool)
const repl_startdebugger_notification_type = JSONRPC.NotificationType("repl/startdebugger", NamedTuple{(:debugPipename,),Tuple{String}})
const repl_showprofileresult_notification_type = JSONRPC.NotificationType("repl/showprofileresult", NamedTuple{(:trace,),Tuple{Dict{Any, Any}}})
const repl_showprofileresult_file_notification_type = JSONRPC.NotificationType("repl/showprofileresult_file", NamedTuple{(:filename,),Tuple{String}})
const repl_toggle_plot_pane_notification_type = JSONRPC.NotificationType("repl/togglePlotPane", NamedTuple{(:enable,),Tuple{Bool}})
const repl_toggle_diagnostics_notification_type = JSONRPC.NotificationType("repl/toggleDiagnostics", NamedTuple{(:enable,),Tuple{Bool}})
const repl_toggle_progress_notification_type = JSONRPC.NotificationType("repl/toggleProgress", Bool)
const cd_notification_type = JSONRPC.NotificationType("repl/cd", NamedTuple{(:uri,),Tuple{String}})
const activate_project_notification_type = JSONRPC.NotificationType("repl/activateProject", NamedTuple{(:uri,),Tuple{String}})
const repl_getdebugitems_request_type = JSONRPC.RequestType("repl/getDebugItems", NamedTuple{(:juliaAccessor,),Tuple{String}}, Vector{DebugConfigTreeItem})

const repl_gettabledata_request_type = JSONRPC.RequestType("repl/getTableData", GetTableDataRequest, Any)
const repl_clearlazytable_notification_type = JSONRPC.NotificationType("repl/clearLazyTable", NamedTuple{(:id,),Tuple{String}})

const repl_getcompletions_request_type = JSONRPC.RequestType("repl/getcompletions", GetCompletionsRequestParams, Vector)
const repl_resolvecompletion_request_type = JSONRPC.RequestType("repl/resolvecompletion", Dict, Dict)

max_stars_repo_name: dpinol/julia-vscode

max_issues_repo_name: dpinol/julia-vscode

max_forks_repo_name: dpinol/julia-vscode


text:
using ProfileCanvas
using Test

@testset "ProfileCanvas.jl" begin
    function profile_test(n)
        for i = 1:n
            A = randn(100,100,20)
            m = maximum(A)
            Am = mapslices(sum, A; dims=2)
            B = A[:,:,5]
            Bsort = mapslices(sort, B; dims=1)
            b = rand(100)
            C = B.*b
        end
    end

    trace = @profview profile_test(10)
    html = sprint(show, "text/html", trace)
    @test occursin("const viewer = new ProfileViewer(", html)
end


text:
#=
header.jl

Many legacy medical imaging data files have a structured "header" at the top
that contains scan information.
This code is designed to read such scan headers.

2019-12-23 Jeff Fessler
=#

export header_read, header_write
export header_example, header_init, header_size, header_string

"""
    hd = header_example()

Return example of header description

out
- `hd` header definition array (N × 3)
"""
function header_example()
    hd = [
        :date 10 Cuchar
        :age 1 Int32
        :height 1 Float32
        :other 3 UInt16
    ]
    return (hd, 24)
end

"""
    ht = header_init(hd::Matrix{Any})

Return named tuple initialized with arbitrary values for testing

in
- `hd` header definition array (N × 3), e.g., from `header_example()`

out
- `ht::NamedTuple`
"""
function header_init(hd::Matrix{Any})
    nset = size(hd, 1)
    vals = Array{Any}(undef, nset)
    cset = Cuchar.(97:122) # a:z in ascii
    for i = 1:nset
        row = hd[i, :]
        n = row[2]
        T = row[3]
        Tr = T == Cuchar ? cset : T
        vals[i] = n > 1 ? rand(Tr, n) : rand(Tr)
    end
    return (; zip(hd[:, 1], vals)...) # NamedTuple
end

"""
    bytes = header_size(hd::Matrix{Any})
return total size of header in bytes

in
- `hd` header definition array (N × 3), e.g., from `header_example()`

out
= `bytes::Int`
"""
function header_size(hd::Matrix{Any})
    nset = size(hd, 1)
    total = Int(0)
    for i = 1:nset
        row = hd[i, :]
        T = row[3]
        total += row[2] * sizeof(T)
    end
    return total
end

"""
    header_write(fid::IOStream, ht::NamedTuple)

Write header to `fid`

in
- `fid::IOStream` from open(file, "w")
- `ht::NamedTuple` from `header_init()` or `header_read()`
"""
function header_write(fid::IOStream, ht::NamedTuple; bytes::Int = 0)
    tmp = write(fid, values(ht)...)
    bytes > 0 && bytes != tmp && throw("bytes written mismatch")
    nothing
end

"""
    ht = header_read(fid::IOStream, hd::Matrix{Any} ; seek0::Bool)

Read header from scan file

in
- `fid::IOStream` from open(file, "r")
- `hd` header definition array (N × 3), e.g., from `header_example()`

option
- `seek0::Bool` seek to `0` location in file first? default `true`

out
- `ht::NamedTuple` with header values, accessed by ht.key
"""
function header_read(fid::IOStream, hd::Matrix{Any}; seek0::Bool = true)
    size(hd, 2) != 3 && throw("bad hd size")

    seek0 && seek(fid, 0)

    nset = size(hd, 1)
    vals = Array{Any}(undef, nset)
    for i = 1:nset
        row = hd[i, :]
        n = row[2]
        T = row[3]
        if n == 1
            vals[i] = read(fid, T)
        else
            data = Array{T}(undef, n)
            read!(fid, data)
            vals[i] = data
        end
    end
    return (; zip(hd[:, 1], vals)...) # NamedTuple
end

"""
    ht = header_string(ht::NamedTuple ; strip::Bool)

Convert each `Array{Cuchar}` to `String` in NamedTuple

in
- `ht::NamedTuple` from `header_init()` or `header_read()`

option
- `strip::Bool` strip tail white space characters from strings? default `false`

out
- `ht::NamedTuple`
"""
function header_string(ht::NamedTuple; strip::Bool = false)
    npair = length(ht)
    vals = Array{Any}(undef, npair)
    for (i, key) in enumerate(keys(ht))
        val = ht[key]
        if val isa Array{Cuchar}
            val = String(copy(val)) # copy is essential here!
            val = strip ? rstrip(val) : val
        end
        vals[i] = val
    end
    return (; zip(keys(ht), vals)...) # NamedTuple
end


text:
module Day12

using Advent: save_input

# - Originally used tuples as coordinates but complex numbers are faster.
# - Better performance with ComplexF64 than Complex{Int64}.
# - Slight speedup but higher memory usage without @views when indexing strings.

function solve_a(filename)
    coord = 0.0 + 0im
    dir = 1.0 + 0im
    for line in eachline(filename)
        inst, arg = Symbol(line[1]), parse(Int, line[2:end])

        inst == :N && (coord += arg * im)
        inst == :S && (coord -= arg * im)
        inst == :E && (coord += arg)
        inst == :W && (coord -= arg)
        inst == :L && (dir *= im^div(arg, 90))
        inst == :R && (dir *= (-im)^div(arg, 90))
        inst == :F && (coord += dir * arg)
    end

    sum(abs, reim(coord)) |> Int
end

function solve_b(filename)
    coord = 0.0 + 0im
    waypoint = 10.0 + 1im
    for line in eachline(filename)
        inst, arg = Symbol(line[1]), parse(Int, line[2:end])

        inst == :N && (waypoint += arg * im)
        inst == :S && (waypoint -= arg * im)
        inst == :E && (waypoint += arg)
        inst == :W && (waypoint -= arg)
        inst == :L && (waypoint *= im^div(arg, 90))
        inst == :R && (waypoint *= (-im)^div(arg, 90))
        inst == :F && (coord += waypoint * arg)
    end

    sum(abs, reim(coord)) |> Int
end

solve(filename = save_input(2020, 12)) = solve_a(filename), solve_b(filename)

end

max_stars_repo_name: AnAverageHuman/competitive

max_issues_repo_name: AnAverageHuman/competitive

max_forks_repo_name: AnAverageHuman/competitive


text:
using aoc2019.computer: load_program, io, run

input = joinpath(@__DIR__, "input")
p = load_program(input)

stdin, stdout = io()
put!(stdin, 1)
run(copy(p), stdin, stdout)
close(stdout)
signals = [signal for signal in stdout]
p1 = first(signals)
@assert p1 == 2350741403

stdin, stdout = io()
put!(stdin, 2)
run(copy(p), stdin, stdout)
close(stdout)
signals = [signal for signal in stdout]
p2 = first(signals)
@assert p2 == 53088

print("-----------------------------------------------------------------------\n")
print("sensor boost -- part one\n    boost keycode : $p1\n")
print("sensor boost -- part one\n    ceres coords  : $p2\n")
print("-----------------------------------------------------------------------\n")


text:
using CovarianceMatrices
using Dierckx
using JLD2

basepath = @__DIR__

x = 0.1:.01:32
itr = Iterators.product(x, 1:175000)
out = map(i -> CovarianceMatrices.kernel(QuadraticSpectralKernel(1), i[2]/i[1]), itr)
r7 = vec(convert(Array{Float64}, mapslices(u -> findfirst(abs.(u) .< 1e-07), out, dims = 2)))
r8 = vec(convert(Array{Float64}, mapslices(u -> findfirst(abs.(u) .< 1e-08), out, dims = 2)))
r9 = vec(convert(Array{Float64}, mapslices(u -> findfirst(abs.(u) .< 1e-09), out, dims = 2)))

spline7 = Spline1D(collect(x), r7)
spline8 = Spline1D(collect(x), r8)
spline9 = Spline1D(collect(x), r9)

x0 = collect(x)
spval7 = Dierckx.evaluate(spline7, x0)
spval8 = Dierckx.evaluate(spline8, x0)
spval9 = Dierckx.evaluate(spline9, x0)

@show maximum(abs(spval7-r7))
@show maximum(abs(spval8-r8))
@show maximum(abs(spval9-r9))

@save "qs_spline_e7.jld2" spline7
@save "qs_spline_e8.jld2" spline8
@save "qs_spline_e9.jld2" spline9


text:
module MaxHelpingHandCustomSeekerBarrier

using ..Ahorn, Maple

@mapdef Entity "MaxHelpingHand/CustomSeekerBarrier" CustomSeekerBarrier(x::Integer, y::Integer, width::Integer=Maple.defaultBlockWidth, height::Integer=Maple.defaultBlockHeight,
    color::String="FFFFFF", particleColor::String="FFFFFF", transparency::Number=0.15, particleTransparency::Number=0.5, particleDirection::Number=0.0)

const placements = Ahorn.PlacementDict(
    "Seeker Barrier (Custom) (max480's Helping Hand)" => Ahorn.EntityPlacement(
        CustomSeekerBarrier,
        "rectangle"
    ),
)

Ahorn.minimumSize(entity::CustomSeekerBarrier) = 8, 8
Ahorn.resizable(entity::CustomSeekerBarrier) = true, true

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

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

    return Ahorn.Rectangle(x, y, width, height)
end

function Ahorn.render(ctx::Ahorn.Cairo.CairoContext, entity::CustomSeekerBarrier, room::Maple.Room)
    width = Int(get(entity.data, "width", 32))
    height = Int(get(entity.data, "height", 32))

    Ahorn.drawRectangle(ctx, 0, 0, width, height, (0.25, 0.25, 0.25, 0.8), (0.0, 0.0, 0.0, 0.0))
end

end

max_stars_repo_name: Kitty-Cats/MaxHelpingHand

max_issues_repo_name: Kitty-Cats/MaxHelpingHand

max_forks_repo_name: Kitty-Cats/MaxHelpingHand


text:
module FluxTraining

#=
Refactoring:
- better serialization of Learners
=#

using LightGraphs
using BSON: @load, @save
using Flux
using Flux: Params, onecold
using Flux.Optimise: update!
using Glob
using DocStringExtensions
import OnlineStats
using OnlineStats: EqualWeight, Mean, OnlineStat
using Parameters
using ProgressMeter: Progress, next!
using Statistics: mean
using UUIDs
using Zygote
using Animations
using TensorBoardLogger
using Zygote: Grads, gradient
using ValueHistories
using DataStructures: DefaultDict

# functional
include("./functional/anneal.jl")
include("./functional/metrics.jl")

# utilities
include("./util/ioutils.jl")

# callback system
include("./callbacks/protect.jl")
include("./callbacks/phases.jl")
include("./callbacks/events.jl")
include("./callbacks/callback.jl")
include("./callbacks/graph.jl")
include("./callbacks/execution.jl")

# logging
include("./callbacks/logging/Loggables.jl")
include("./callbacks/logging/logger.jl")
include("./callbacks/logging/tensorboard.jl")

# callback implementations
include("./callbacks/callbacks.jl")
include("./callbacks/customcallback.jl")
include("./callbacks/metrics.jl")
include("./callbacks/recorder.jl")

# hyperparameter scheduling
include("./callbacks/hyperparameters.jl")
include("./callbacks/scheduler.jl")

# learner
include("./learner.jl")

include("./train.jl")

# TODO: remove old exports
export AbstractCallback,
    Accuracy,
    Loss,
    CancelBatchException,
    CancelEpochException,
    CancelFittingException,
    Checkpointer,
    CheckpointAny,
    CheckpointLowest,
    CustomCallback,
    DataLoader,
    EarlyStopping,
    ToGPU,
    GarbageCollect,
    Learner,
    Metric,
    Recorder,
    ProgressBarLogger,
    Metrics,
    MetricsPrinter,
    ParamSchedule,
    ParamScheduler,
    TrainingPhase,
    ValidationPhase,
    Schedule,
    Scheduler,
    Logger,
    TensorBoardBackend,
    StopOnNaNLoss,

    LearningRate,

    accuracy,
    anneal_linear,
    anneal_cosine,
    anneal_exp,
    anneal_const,
    endtraining,
    fit!,
    loadmodel,
    loadweights,
    onecycle,
    savemodel,
    saveweights,
    setschedule!,
    splitdataset,
    starttraining

end # module


text:
using Dice
using Dice: num_flips, num_nodes, to_dice_ir

code = @dice begin
    n = 10
    x = Vector(undef, n)
    x[1] = flip(0.5)
    for i=2:n
        x[i] = if x[i-1]
            flip(0.9)
        else
            flip(0.4)
        end
    end
    x[end]
end

# BDD analysis
bdd = compile(code)
num_flips(bdd)
num_nodes(bdd)
infer(code, :bdd)

# IR analysis
to_dice_ir(code)
has_dice_binary() && rundice(code)
has_dice_binary() && infer(code, :ocaml)


text:
function variablecost(m::JuMP.AbstractModel, devices::Array{PowerSystems.RenewableCurtailment,1}, device_formulation::Type{D}, system_formulation::Type{S}) where {D <: AbstractRenewableDispatchForm, S <: PM.AbstractPowerFormulation}

    p_re = m[:p_re]
    time_index = m[:p_re].axes[2]
    name_index = m[:p_re].axes[1]

    var_cost = AffExpr()

    for  (ix, name) in enumerate(name_index)
        if !isa(devices[ix].econ.curtailpenalty,Nothing)
            c = gencost(m, p_re[name,:], devices[ix].econ.curtailpenalty)
        else
            continue
        end
            (isa(var_cost,JuMP.AffExpr) && isa(c,JuMP.AffExpr)) ? JuMP.add_to_expression!(var_cost,c) : (isa(var_cost,JuMP.GenericQuadExpr) && isa(c,JuMP.GenericQuadExpr) ? JuMP.add_to_expression!(var_cost,c) : var_cost += c)
    end

    return var_cost

end


text:
using Test

using DataAndPlotting

filename = "array.h5"

arr = initialize()
rm(filename, force=true)
output(arr, filename)

arr2 = input(filename)

@test isequal(arr2, arr)

plotname = "wave.png"
arr = initialize()
makeplot(arr, plotname)


text:
module CairoColors

using Pkg;
Pkg.add("Cairo");
import Cairo;

const EMERALD = [
    0.247,
    0.765,
    0.502,
]

function SetCairoRGBA_EMERALD(ctx)
  return Cairo.set_source_rgba(
    ctx,
    EMERALD[1]::Float64,
    EMERALD[2]::Float64,
    EMERALD[3]::Float64,
    1.000::Float64)
end

  const NIAGARA = [
    0.165,
    0.733,
    0.608,
  ]

  function SetCairoRGBA_NIAGARA(ctx)
    return Cairo.set_source_rgba(
      ctx,
      NIAGARA[1]::Float64,
      NIAGARA[2]::Float64,
      NIAGARA[3]::Float64,
      1.000::Float64)
  end

  const JAVA = [
    0.137,
    0.796,
    0.655,
  ]

  function SetCairoRGBA_JAVA(ctx)
    return Cairo.set_source_rgba(
      ctx,
      JAVA[1]::Float64,
      JAVA[2]::Float64,
      JAVA[3]::Float64,
      1.000::Float64)
  end

  const REBECCA_PURPLE = [
    0.400,
    0.200,
    0.600,
  ]

  function SetCairoRGBA_REBECCA_PURPLE(ctx)
    return Cairo.set_source_rgba(
      ctx,
      REBECCA_PURPLE[1]::Float64,
      REBECCA_PURPLE[2]::Float64,
      REBECCA_PURPLE[3]::Float64,
      1.000::Float64)
  end

  const ELECTRIC_INDIGO = [
    0.549,
    0.078,
    0.988,
  ]

  function SetCairoRGBA_ELECTRIC_INDIGO(ctx)
    return Cairo.set_source_rgba(
      ctx,
      ELECTRIC_INDIGO[1]::Float64,
      ELECTRIC_INDIGO[2]::Float64,
      ELECTRIC_INDIGO[3]::Float64,
      1.000::Float64)
  end

  const YELLOW = [
    1.000,
    1.000,
    0.000,
  ]

  function SetCairoRGBA_YELLOW(ctx)
    return Cairo.set_source_rgba(
      ctx,
      YELLOW[1]::Float64,
      YELLOW[2]::Float64,
      YELLOW[3]::Float64,
      1.000::Float64)
  end

  const CYAN = [
    0.000,
    1.000,
    1.000,
  ]

  function SetCairoRGBA_CYAN(ctx)
    return Cairo.set_source_rgba(
      ctx,
      CYAN[1]::Float64,
      CYAN[2]::Float64,
      CYAN[3]::Float64,
      1.000::Float64)
  end

  const SILVER = [
    0.753,
    0.753,
    0.753,
  ]

  function SetCairoRGBA_SILVER(ctx)
    return Cairo.set_source_rgba(
      ctx,
      SILVER[1]::Float64,
      SILVER[2]::Float64,
      SILVER[3]::Float64,
      1.000::Float64)
  end

  const GRAY = [
    0.502,
    0.502,
    0.502,
  ]

  function SetCairoRGBA_GRAY(ctx)
    return Cairo.set_source_rgba(
      ctx,
      GRAY[1]::Float64,
      GRAY[2]::Float64,
      GRAY[3]::Float64,
      1.000::Float64)
  end

  const MAROON = [
    0.502,
    0.000,
    0.000,
  ]

  function SetCairoRGBA_MAROON(ctx)
    return Cairo.set_source_rgba(
      ctx,
      MAROON[1]::Float64,
      MAROON[2]::Float64,
      MAROON[3]::Float64,
      1.000::Float64)
  end

  const OLIVE = [
    0.502,
    0.502,
    0.000,
  ]

  function SetCairoRGBA_OLIVE(ctx)
    return Cairo.set_source_rgba(
      ctx,
      OLIVE[1]::Float64,
      OLIVE[2]::Float64,
      OLIVE[3]::Float64,
      1.000::Float64)
  end

  const DARK_RED = [
    0.545,
    0.000,
    0.000,
  ]

  function SetCairoRGBA_DARK_RED(ctx)
    return Cairo.set_source_rgba(
      ctx,
      DARK_RED[1]::Float64,
      DARK_RED[2]::Float64,
      DARK_RED[3]::Float64,
      1.000::Float64)
  end

  const BROWN = [
    0.647,
    0.165,
    0.165,
  ]

  function SetCairoRGBA_BROWN(ctx)
    return Cairo.set_source_rgba(
      ctx,
      BROWN[1]::Float64,
      BROWN[2]::Float64,
      BROWN[3]::Float64,
      1.000::Float64)
  end

  const FIREBRICK = [
    0.698,
    0.133,
    0.133,
  ]

  function SetCairoRGBA_FIREBRICK(ctx)
    return Cairo.set_source_rgba(
      ctx,
      FIREBRICK[1]::Float64,
      FIREBRICK[2]::Float64,
      FIREBRICK[3]::Float64,
      1.000::Float64)
  end

  const CRIMSON = [
    0.863,
    0.078,
    0.235,
  ]

  function SetCairoRGBA_CRIMSON(ctx)
    return Cairo.set_source_rgba(
      ctx,
      CRIMSON[1]::Float64,
      CRIMSON[2]::Float64,
      CRIMSON[3]::Float64,
      1.000::Float64)
  end

  const RED = [
    1.000,
    0.000,
    0.000,
  ]

  function SetCairoRGBA_RED(ctx)
    return Cairo.set_source_rgba(
      ctx,
      RED[1]::Float64,
      RED[2]::Float64,
      RED[3]::Float64,
      1.000::Float64)
  end

  const TOMATO = [
    1.000,
    0.388,
    0.278,
  ]

  function SetCairoRGBA_TOMATO(ctx)
    return Cairo.set_source_rgba(
      ctx,
      TOMATO[1]::Float64,
      TOMATO[2]::Float64,
      TOMATO[3]::Float64,
      1.000::Float64)
  end

  const CORAL = [
    1.000,
    0.498,
    0.314,
  ]

  function SetCairoRGBA_CORAL(ctx)
    return Cairo.set_source_rgba(
      ctx,
      CORAL[1]::Float64,
      CORAL[2]::Float64,
      CORAL[3]::Float64,
      1.000::Float64)
  end

  const INDIAN_RED = [
    0.804,
    0.361,
    0.361,
  ]

  function SetCairoRGBA_INDIAN_RED(ctx)
    return Cairo.set_source_rgba(
      ctx,
      INDIAN_RED[1]::Float64,
      INDIAN_RED[2]::Float64,
      INDIAN_RED[3]::Float64,
      1.000::Float64)
  end

  const LIGHT_CORAL = [
    0.941,
    0.502,
    0.502,
  ]

  function SetCairoRGBA_LIGHT_CORAL(ctx)
    return Cairo.set_source_rgba(
      ctx,
      LIGHT_CORAL[1]::Float64,
      LIGHT_CORAL[2]::Float64,
      LIGHT_CORAL[3]::Float64,
      1.000::Float64)
  end

  const DARK_SALMON = [
    0.914,
    0.588,
    0.478,
  ]

  function SetCairoRGBA_DARK_SALMON(ctx)
    return Cairo.set_source_rgba(
      ctx,
      DARK_SALMON[1]::Float64,
      DARK_SALMON[2]::Float64,
      DARK_SALMON[3]::Float64,
      1.000::Float64)
  end

  const SALMON = [
    0.980,
    0.502,
    0.447,
  ]

  function SetCairoRGBA_SALMON(ctx)
    return Cairo.set_source_rgba(
      ctx,
      SALMON[1]::Float64,
      SALMON[2]::Float64,
      SALMON[3]::Float64,
      1.000::Float64)
  end

  const LIGHT_SALMON = [
    1.000,
    0.627,
    0.478,
  ]

  function SetCairoRGBA_LIGHT_SALMON(ctx)
    return Cairo.set_source_rgba(
      ctx,
      LIGHT_SALMON[1]::Float64,
      LIGHT_SALMON[2]::Float64,
      LIGHT_SALMON[3]::Float64,
      1.000::Float64)
  end

  const ORANGE_RED = [
    1.000,
    0.271,
    0.000,
  ]

  function SetCairoRGBA_ORANGE_RED(ctx)
    return Cairo.set_source_rgba(
      ctx,
      ORANGE_RED[1]::Float64,
      ORANGE_RED[2]::Float64,
      ORANGE_RED[3]::Float64,
      1.000::Float64)
  end

  const DARK_ORANGE = [
    1.000,
    0.549,
    0.000,
  ]

  function SetCairoRGBA_DARK_ORANGE(ctx)
    return Cairo.set_source_rgba(
      ctx,
      DARK_ORANGE[1]::Float64,
      DARK_ORANGE[2]::Float64,
      DARK_ORANGE[3]::Float64,
      1.000::Float64)
  end

  const ORANGE = [
    1.000,
    0.647,
    0.000,
  ]

  function SetCairoRGBA_ORANGE(ctx)
    return Cairo.set_source_rgba(
      ctx,
      ORANGE[1]::Float64,
      ORANGE[2]::Float64,
      ORANGE[3]::Float64,
      1.000::Float64)
  end

  const GOLD = [
    1.000,
    0.843,
    0.000,
  ]

  function SetCairoRGBA_GOLD(ctx)
    return Cairo.set_source_rgba(
      ctx,
      GOLD[1]::Float64,
      GOLD[2]::Float64,
      GOLD[3]::Float64,
      1.000::Float64)
  end

  const DARK_GOLDEN_ROD = [
    0.722,
    0.525,
    0.043,
  ]

  function SetCairoRGBA_DARK_GOLDEN_ROD(ctx)
    return Cairo.set_source_rgba(
      ctx,
      DARK_GOLDEN_ROD[1]::Float64,
      DARK_GOLDEN_ROD[2]::Float64,
      DARK_GOLDEN_ROD[3]::Float64,
      1.000::Float64)
  end

  const GOLDEN_ROD = [
    0.855,
    0.647,
    0.125,
  ]

  function SetCairoRGBA_GOLDEN_ROD(ctx)
    return Cairo.set_source_rgba(
      ctx,
      GOLDEN_ROD[1]::Float64,
      GOLDEN_ROD[2]::Float64,
      GOLDEN_ROD[3]::Float64,
      1.000::Float64)
  end

  const PALE_GOLDEN_ROD = [
    0.933,
    0.910,
    0.667,
  ]

  function SetCairoRGBA_PALE_GOLDEN_ROD(ctx)
    return Cairo.set_source_rgba(
      ctx,
      PALE_GOLDEN_ROD[1]::Float64,
      PALE_GOLDEN_ROD[2]::Float64,
      PALE_GOLDEN_ROD[3]::Float64,
      1.000::Float64)
  end

  const DARK_KHAKI = [
    0.741,
    0.718,
    0.420,
  ]

  function SetCairoRGBA_DARK_KHAKI(ctx)
    return Cairo.set_source_rgba(
      ctx,
      DARK_KHAKI[1]::Float64,
      DARK_KHAKI[2]::Float64,
      DARK_KHAKI[3]::Float64,
      1.000::Float64)
  end

  const KHAKI = [
    0.941,
    0.902,
    0.549,
  ]

  function SetCairoRGBA_KHAKI(ctx)
    return Cairo.set_source_rgba(
      ctx,
      KHAKI[1]::Float64,
      KHAKI[2]::Float64,
      KHAKI[3]::Float64,
      1.000::Float64)
  end

  const YELLOW_GREEN = [
    0.604,
    0.804,
    0.196,
  ]

  function SetCairoRGBA_YELLOW_GREEN(ctx)
    return Cairo.set_source_rgba(
      ctx,
      YELLOW_GREEN[1]::Float64,
      YELLOW_GREEN[2]::Float64,
      YELLOW_GREEN[3]::Float64,
      1.000::Float64)
  end

  const DARK_OLIVE_GREEN = [
    0.333,
    0.420,
    0.184,
  ]

  function SetCairoRGBA_DARK_OLIVE_GREEN(ctx)
    return Cairo.set_source_rgba(
      ctx,
      DARK_OLIVE_GREEN[1]::Float64,
      DARK_OLIVE_GREEN[2]::Float64,
      DARK_OLIVE_GREEN[3]::Float64,
      1.000::Float64)
  end

  const OLIVE_DRAB = [
    0.420,
    0.557,
    0.137,
  ]

  function SetCairoRGBA_OLIVE_DRAB(ctx)
    return Cairo.set_source_rgba(
      ctx,
      OLIVE_DRAB[1]::Float64,
      OLIVE_DRAB[2]::Float64,
      OLIVE_DRAB[3]::Float64,
      1.000::Float64)
  end

  const LAWN_GREEN = [
    0.486,
    0.988,
    0.000,
  ]

  function SetCairoRGBA_LAWN_GREEN(ctx)
    return Cairo.set_source_rgba(
      ctx,
      LAWN_GREEN[1]::Float64,
      LAWN_GREEN[2]::Float64,
      LAWN_GREEN[3]::Float64,
      1.000::Float64)
  end

  const CHART_REUSE = [
    0.498,
    1.000,
    0.000,
  ]

  function SetCairoRGBA_CHART_REUSE(ctx)
    return Cairo.set_source_rgba(
      ctx,
      CHART_REUSE[1]::Float64,
      CHART_REUSE[2]::Float64,
      CHART_REUSE[3]::Float64,
      1.000::Float64)
  end

  const GREEN_YELLOW = [
    0.678,
    1.000,
    0.184,
  ]

  function SetCairoRGBA_GREEN_YELLOW(ctx)
    return Cairo.set_source_rgba(
      ctx,
      GREEN_YELLOW[1]::Float64,
      GREEN_YELLOW[2]::Float64,
      GREEN_YELLOW[3]::Float64,
      1.000::Float64)
  end

  const DARK_GREEN = [
    0.000,
    0.392,
    0.000,
  ]

  function SetCairoRGBA_DARK_GREEN(ctx)
    return Cairo.set_source_rgba(
      ctx,
      DARK_GREEN[1]::Float64,
      DARK_GREEN[2]::Float64,
      DARK_GREEN[3]::Float64,
      1.000::Float64)
  end

  const GREEN = [
    0.000,
    0.502,
    0.000,
  ]

  function SetCairoRGBA_GREEN(ctx)
    return Cairo.set_source_rgba(
      ctx,
      GREEN[1]::Float64,
      GREEN[2]::Float64,
      GREEN[3]::Float64,
      1.000::Float64)
  end

  const FOREST_GREEN = [
    0.133,
    0.545,
    0.133,
  ]

  function SetCairoRGBA_FOREST_GREEN(ctx)
    return Cairo.set_source_rgba(
      ctx,
      FOREST_GREEN[1]::Float64,
      FOREST_GREEN[2]::Float64,
      FOREST_GREEN[3]::Float64,
      1.000::Float64)
  end

  const LIME = [
    0.000,
    1.000,
    0.000,
  ]

  function SetCairoRGBA_LIME(ctx)
    return Cairo.set_source_rgba(
      ctx,
      LIME[1]::Float64,
      LIME[2]::Float64,
      LIME[3]::Float64,
      1.000::Float64)
  end

  const LIME_GREEN = [
    0.196,
    0.804,
    0.196,
  ]

  function SetCairoRGBA_LIME_GREEN(ctx)
    return Cairo.set_source_rgba(
      ctx,
      LIME_GREEN[1]::Float64,
      LIME_GREEN[2]::Float64,
      LIME_GREEN[3]::Float64,
      1.000::Float64)
  end

  const LIGHT_GREEN = [
    0.565,
    0.933,
    0.565,
  ]

  function SetCairoRGBA_LIGHT_GREEN(ctx)
    return Cairo.set_source_rgba(
      ctx,
      LIGHT_GREEN[1]::Float64,
      LIGHT_GREEN[2]::Float64,
      LIGHT_GREEN[3]::Float64,
      1.000::Float64)
  end

  const PALE_GREEN = [
    0.596,
    0.984,
    0.596,
  ]

  function SetCairoRGBA_PALE_GREEN(ctx)
    return Cairo.set_source_rgba(
      ctx,
      PALE_GREEN[1]::Float64,
      PALE_GREEN[2]::Float64,
      PALE_GREEN[3]::Float64,
      1.000::Float64)
  end

  const DARK_SEA_GREEN = [
    0.561,
    0.737,
    0.561,
  ]

  function SetCairoRGBA_DARK_SEA_GREEN(ctx)
    return Cairo.set_source_rgba(
      ctx,
      DARK_SEA_GREEN[1]::Float64,
      DARK_SEA_GREEN[2]::Float64,
      DARK_SEA_GREEN[3]::Float64,
      1.000::Float64)
  end

  const MEDIUM_SPRING_GREEN = [
    0.000,
    0.980,
    0.604,
  ]

  function SetCairoRGBA_MEDIUM_SPRING_GREEN(ctx)
    return Cairo.set_source_rgba(
      ctx,
      MEDIUM_SPRING_GREEN[1]::Float64,
      MEDIUM_SPRING_GREEN[2]::Float64,
      MEDIUM_SPRING_GREEN[3]::Float64,
      1.000::Float64)
  end

  const SPRING_GREEN = [
    0.000,
    1.000,
    0.498,
  ]

  function SetCairoRGBA_SPRING_GREEN(ctx)
    return Cairo.set_source_rgba(
      ctx,
      SPRING_GREEN[1]::Float64,
      SPRING_GREEN[2]::Float64,
      SPRING_GREEN[3]::Float64,
      1.000::Float64)
  end

  const SEA_GREEN = [
    0.180,
    0.545,
    0.341,
  ]

  function SetCairoRGBA_SEA_GREEN(ctx)
    return Cairo.set_source_rgba(
      ctx,
      SEA_GREEN[1]::Float64,
      SEA_GREEN[2]::Float64,
      SEA_GREEN[3]::Float64,
      1.000::Float64)
  end

  const MEDIUM_AQUA_MARINE = [
    0.400,
    0.804,
    0.667,
  ]

  function SetCairoRGBA_MEDIUM_AQUA_MARINE(ctx)
    return Cairo.set_source_rgba(
      ctx,
      MEDIUM_AQUA_MARINE[1]::Float64,
      MEDIUM_AQUA_MARINE[2]::Float64,
      MEDIUM_AQUA_MARINE[3]::Float64,
      1.000::Float64)
  end

  const MEDIUM_SEA_GREEN = [
    0.235,
    0.702,
    0.443,
  ]

  function SetCairoRGBA_MEDIUM_SEA_GREEN(ctx)
    return Cairo.set_source_rgba(
      ctx,
      MEDIUM_SEA_GREEN[1]::Float64,
      MEDIUM_SEA_GREEN[2]::Float64,
      MEDIUM_SEA_GREEN[3]::Float64,
      1.000::Float64)
  end

  const LIGHT_SEA_GREEN = [
    0.125,
    0.698,
    0.667,
  ]

  function SetCairoRGBA_LIGHT_SEA_GREEN(ctx)
    return Cairo.set_source_rgba(
      ctx,
      LIGHT_SEA_GREEN[1]::Float64,
      LIGHT_SEA_GREEN[2]::Float64,
      LIGHT_SEA_GREEN[3]::Float64,
      1.000::Float64)
  end

  const DARK_SLATE_GRAY = [
    0.184,
    0.310,
    0.310,
  ]

  function SetCairoRGBA_DARK_SLATE_GRAY(ctx)
    return Cairo.set_source_rgba(
      ctx,
      DARK_SLATE_GRAY[1]::Float64,
      DARK_SLATE_GRAY[2]::Float64,
      DARK_SLATE_GRAY[3]::Float64,
      1.000::Float64)
  end

  const TEAL = [
    0.000,
    0.502,
    0.502,
  ]

  function SetCairoRGBA_TEAL(ctx)
    return Cairo.set_source_rgba(
      ctx,
      TEAL[1]::Float64,
      TEAL[2]::Float64,
      TEAL[3]::Float64,
      1.000::Float64)
  end

  const DARK_CYAN = [
    0.000,
    0.545,
    0.545,
  ]

  function SetCairoRGBA_DARK_CYAN(ctx)
    return Cairo.set_source_rgba(
      ctx,
      DARK_CYAN[1]::Float64,
      DARK_CYAN[2]::Float64,
      DARK_CYAN[3]::Float64,
      1.000::Float64)
  end

  const AQUA = [
    0.000,
    1.000,
    1.000,
  ]

  function SetCairoRGBA_AQUA(ctx)
    return Cairo.set_source_rgba(
      ctx,
      AQUA[1]::Float64,
      AQUA[2]::Float64,
      AQUA[3]::Float64,
      1.000::Float64)
  end

  const LIGHT_CYAN = [
    0.878,
    1.000,
    1.000,
  ]

  function SetCairoRGBA_LIGHT_CYAN(ctx)
    return Cairo.set_source_rgba(
      ctx,
      LIGHT_CYAN[1]::Float64,
      LIGHT_CYAN[2]::Float64,
      LIGHT_CYAN[3]::Float64,
      1.000::Float64)
  end

  const DARK_TURQUOISE = [
    0.000,
    0.808,
    0.820,
  ]

  function SetCairoRGBA_DARK_TURQUOISE(ctx)
    return Cairo.set_source_rgba(
      ctx,
      DARK_TURQUOISE[1]::Float64,
      DARK_TURQUOISE[2]::Float64,
      DARK_TURQUOISE[3]::Float64,
      1.000::Float64)
  end

  const TURQUOISE = [
    0.251,
    0.878,
    0.816,
  ]

  function SetCairoRGBA_TURQUOISE(ctx)
    return Cairo.set_source_rgba(
      ctx,
      TURQUOISE[1]::Float64,
      TURQUOISE[2]::Float64,
      TURQUOISE[3]::Float64,
      1.000::Float64)
  end

  const MEDIUM_TURQUOISE = [
    0.282,
    0.820,
    0.800,
  ]

  function SetCairoRGBA_MEDIUM_TURQUOISE(ctx)
    return Cairo.set_source_rgba(
      ctx,
      MEDIUM_TURQUOISE[1]::Float64,
      MEDIUM_TURQUOISE[2]::Float64,
      MEDIUM_TURQUOISE[3]::Float64,
      1.000::Float64)
  end

  const PALE_TURQUOISE = [
    0.686,
    0.933,
    0.933,
  ]

  function SetCairoRGBA_PALE_TURQUOISE(ctx)
    return Cairo.set_source_rgba(
      ctx,
      PALE_TURQUOISE[1]::Float64,
      PALE_TURQUOISE[2]::Float64,
      PALE_TURQUOISE[3]::Float64,
      1.000::Float64)
  end

  const AQUA_MARINE = [
    0.498,
    1.000,
    0.831,
  ]

  function SetCairoRGBA_AQUA_MARINE(ctx)
    return Cairo.set_source_rgba(
      ctx,
      AQUA_MARINE[1]::Float64,
      AQUA_MARINE[2]::Float64,
      AQUA_MARINE[3]::Float64,
      1.000::Float64)
  end

  const POWDER_BLUE = [
    0.690,
    0.878,
    0.902,
  ]

  function SetCairoRGBA_POWDER_BLUE(ctx)
    return Cairo.set_source_rgba(
      ctx,
      POWDER_BLUE[1]::Float64,
      POWDER_BLUE[2]::Float64,
      POWDER_BLUE[3]::Float64,
      1.000::Float64)
  end

  const CADET_BLUE = [
    0.373,
    0.620,
    0.627,
  ]

  function SetCairoRGBA_CADET_BLUE(ctx)
    return Cairo.set_source_rgba(
      ctx,
      CADET_BLUE[1]::Float64,
      CADET_BLUE[2]::Float64,
      CADET_BLUE[3]::Float64,
      1.000::Float64)
  end

  const STEEL_BLUE = [
    0.275,
    0.510,
    0.706,
  ]

  function SetCairoRGBA_STEEL_BLUE(ctx)
    return Cairo.set_source_rgba(
      ctx,
      STEEL_BLUE[1]::Float64,
      STEEL_BLUE[2]::Float64,
      STEEL_BLUE[3]::Float64,
      1.000::Float64)
  end

  const CORN_FLOWER_BLUE = [
    0.392,
    0.584,
    0.929,
  ]

  function SetCairoRGBA_CORN_FLOWER_BLUE(ctx)
    return Cairo.set_source_rgba(
      ctx,
      CORN_FLOWER_BLUE[1]::Float64,
      CORN_FLOWER_BLUE[2]::Float64,
      CORN_FLOWER_BLUE[3]::Float64,
      1.000::Float64)
  end

  const DEEP_SKY_BLUE = [
    0.000,
    0.749,
    1.000,
  ]

  function SetCairoRGBA_DEEP_SKY_BLUE(ctx)
    return Cairo.set_source_rgba(
      ctx,
      DEEP_SKY_BLUE[1]::Float64,
      DEEP_SKY_BLUE[2]::Float64,
      DEEP_SKY_BLUE[3]::Float64,
      1.000::Float64)
  end

  const DODGER_BLUE = [
    0.118,
    0.565,
    1.000,
  ]

  function SetCairoRGBA_DODGER_BLUE(ctx)
    return Cairo.set_source_rgba(
      ctx,
      DODGER_BLUE[1]::Float64,
      DODGER_BLUE[2]::Float64,
      DODGER_BLUE[3]::Float64,
      1.000::Float64)
  end

  const LIGHT_BLUE = [
    0.678,
    0.847,
    0.902,
  ]

  function SetCairoRGBA_LIGHT_BLUE(ctx)
    return Cairo.set_source_rgba(
      ctx,
      LIGHT_BLUE[1]::Float64,
      LIGHT_BLUE[2]::Float64,
      LIGHT_BLUE[3]::Float64,
      1.000::Float64)
  end

  const SKY_BLUE = [
    0.529,
    0.808,
    0.922,
  ]

  function SetCairoRGBA_SKY_BLUE(ctx)
    return Cairo.set_source_rgba(
      ctx,
      SKY_BLUE[1]::Float64,
      SKY_BLUE[2]::Float64,
      SKY_BLUE[3]::Float64,
      1.000::Float64)
  end

  const LIGHT_SKY_BLUE = [
    0.529,
    0.808,
    0.980,
  ]

  function SetCairoRGBA_LIGHT_SKY_BLUE(ctx)
    return Cairo.set_source_rgba(
      ctx,
      LIGHT_SKY_BLUE[1]::Float64,
      LIGHT_SKY_BLUE[2]::Float64,
      LIGHT_SKY_BLUE[3]::Float64,
      1.000::Float64)
  end

  const MIDNIGHT_BLUE = [
    0.098,
    0.098,
    0.439,
  ]

  function SetCairoRGBA_MIDNIGHT_BLUE(ctx)
    return Cairo.set_source_rgba(
      ctx,
      MIDNIGHT_BLUE[1]::Float64,
      MIDNIGHT_BLUE[2]::Float64,
      MIDNIGHT_BLUE[3]::Float64,
      1.000::Float64)
  end

  const NAVY = [
    0.000,
    0.000,
    0.502,
  ]

  function SetCairoRGBA_NAVY(ctx)
    return Cairo.set_source_rgba(
      ctx,
      NAVY[1]::Float64,
      NAVY[2]::Float64,
      NAVY[3]::Float64,
      1.000::Float64)
  end

  const DARK_BLUE = [
    0.000,
    0.000,
    0.545,
  ]

  function SetCairoRGBA_DARK_BLUE(ctx)
    return Cairo.set_source_rgba(
      ctx,
      DARK_BLUE[1]::Float64,
      DARK_BLUE[2]::Float64,
      DARK_BLUE[3]::Float64,
      1.000::Float64)
  end

  const MEDIUM_BLUE = [
    0.000,
    0.000,
    0.804,
  ]

  function SetCairoRGBA_MEDIUM_BLUE(ctx)
    return Cairo.set_source_rgba(
      ctx,
      MEDIUM_BLUE[1]::Float64,
      MEDIUM_BLUE[2]::Float64,
      MEDIUM_BLUE[3]::Float64,
      1.000::Float64)
  end

  const BLUE = [
    0.000,
    0.000,
    1.000,
  ]

  function SetCairoRGBA_BLUE(ctx)
    return Cairo.set_source_rgba(
      ctx,
      BLUE[1]::Float64,
      BLUE[2]::Float64,
      BLUE[3]::Float64,
      1.000::Float64)
  end

  const ROYAL_BLUE = [
    0.255,
    0.412,
    0.882,
  ]

  function SetCairoRGBA_ROYAL_BLUE(ctx)
    return Cairo.set_source_rgba(
      ctx,
      ROYAL_BLUE[1]::Float64,
      ROYAL_BLUE[2]::Float64,
      ROYAL_BLUE[3]::Float64,
      1.000::Float64)
  end

  const BLUE_VIOLET = [
    0.541,
    0.169,
    0.886,
  ]

  function SetCairoRGBA_BLUE_VIOLET(ctx)
    return Cairo.set_source_rgba(
      ctx,
      BLUE_VIOLET[1]::Float64,
      BLUE_VIOLET[2]::Float64,
      BLUE_VIOLET[3]::Float64,
      1.000::Float64)
  end

  const INDIGO = [
    0.294,
    0.000,
    0.510,
  ]

  function SetCairoRGBA_INDIGO(ctx)
    return Cairo.set_source_rgba(
      ctx,
      INDIGO[1]::Float64,
      INDIGO[2]::Float64,
      INDIGO[3]::Float64,
      1.000::Float64)
  end

  const DARK_SLATE_BLUE = [
    0.282,
    0.239,
    0.545,
  ]

  function SetCairoRGBA_DARK_SLATE_BLUE(ctx)
    return Cairo.set_source_rgba(
      ctx,
      DARK_SLATE_BLUE[1]::Float64,
      DARK_SLATE_BLUE[2]::Float64,
      DARK_SLATE_BLUE[3]::Float64,
      1.000::Float64)
  end

  const SLATE_BLUE = [
    0.416,
    0.353,
    0.804,
  ]

  function SetCairoRGBA_SLATE_BLUE(ctx)
    return Cairo.set_source_rgba(
      ctx,
      SLATE_BLUE[1]::Float64,
      SLATE_BLUE[2]::Float64,
      SLATE_BLUE[3]::Float64,
      1.000::Float64)
  end

  const MEDIUM_SLATE_BLUE = [
    0.482,
    0.408,
    0.933,
  ]

  function SetCairoRGBA_MEDIUM_SLATE_BLUE(ctx)
    return Cairo.set_source_rgba(
      ctx,
      MEDIUM_SLATE_BLUE[1]::Float64,
      MEDIUM_SLATE_BLUE[2]::Float64,
      MEDIUM_SLATE_BLUE[3]::Float64,
      1.000::Float64)
  end

  const MEDIUM_PURPLE = [
    0.576,
    0.439,
    0.859,
  ]

  function SetCairoRGBA_MEDIUM_PURPLE(ctx)
    return Cairo.set_source_rgba(
      ctx,
      MEDIUM_PURPLE[1]::Float64,
      MEDIUM_PURPLE[2]::Float64,
      MEDIUM_PURPLE[3]::Float64,
      1.000::Float64)
  end

  const DARK_MAGENTA = [
    0.545,
    0.000,
    0.545,
  ]

  function SetCairoRGBA_DARK_MAGENTA(ctx)
    return Cairo.set_source_rgba(
      ctx,
      DARK_MAGENTA[1]::Float64,
      DARK_MAGENTA[2]::Float64,
      DARK_MAGENTA[3]::Float64,
      1.000::Float64)
  end

  const DARK_VIOLET = [
    0.580,
    0.000,
    0.827,
  ]

  function SetCairoRGBA_DARK_VIOLET(ctx)
    return Cairo.set_source_rgba(
      ctx,
      DARK_VIOLET[1]::Float64,
      DARK_VIOLET[2]::Float64,
      DARK_VIOLET[3]::Float64,
      1.000::Float64)
  end

  const DARK_ORCHID = [
    0.600,
    0.196,
    0.800,
  ]

  function SetCairoRGBA_DARK_ORCHID(ctx)
    return Cairo.set_source_rgba(
      ctx,
      DARK_ORCHID[1]::Float64,
      DARK_ORCHID[2]::Float64,
      DARK_ORCHID[3]::Float64,
      1.000::Float64)
  end

  const MEDIUM_ORCHID = [
    0.729,
    0.333,
    0.827,
  ]

  function SetCairoRGBA_MEDIUM_ORCHID(ctx)
    return Cairo.set_source_rgba(
      ctx,
      MEDIUM_ORCHID[1]::Float64,
      MEDIUM_ORCHID[2]::Float64,
      MEDIUM_ORCHID[3]::Float64,
      1.000::Float64)
  end

  const PURPLE = [
    0.502,
    0.000,
    0.502,
  ]

  function SetCairoRGBA_PURPLE(ctx)
    return Cairo.set_source_rgba(
      ctx,
      PURPLE[1]::Float64,
      PURPLE[2]::Float64,
      PURPLE[3]::Float64,
      1.000::Float64)
  end

  const THISTLE = [
    0.847,
    0.749,
    0.847,
  ]

  function SetCairoRGBA_THISTLE(ctx)
    return Cairo.set_source_rgba(
      ctx,
      THISTLE[1]::Float64,
      THISTLE[2]::Float64,
      THISTLE[3]::Float64,
      1.000::Float64)
  end

  const PLUM = [
    0.867,
    0.627,
    0.867,
  ]

  function SetCairoRGBA_PLUM(ctx)
    return Cairo.set_source_rgba(
      ctx,
      PLUM[1]::Float64,
      PLUM[2]::Float64,
      PLUM[3]::Float64,
      1.000::Float64)
  end

  const VIOLET = [
    0.933,
    0.510,
    0.933,
  ]

  function SetCairoRGBA_VIOLET(ctx)
    return Cairo.set_source_rgba(
      ctx,
      VIOLET[1]::Float64,
      VIOLET[2]::Float64,
      VIOLET[3]::Float64,
      1.000::Float64)
  end

  const MAGENTA = [
    1.000,
    0.000,
    1.000,
  ]

  function SetCairoRGBA_MAGENTA(ctx)
    return Cairo.set_source_rgba(
      ctx,
      MAGENTA[1]::Float64,
      MAGENTA[2]::Float64,
      MAGENTA[3]::Float64,
      1.000::Float64)
  end

  const ORCHID = [
    0.855,
    0.439,
    0.839,
  ]

  function SetCairoRGBA_ORCHID(ctx)
    return Cairo.set_source_rgba(
      ctx,
      ORCHID[1]::Float64,
      ORCHID[2]::Float64,
      ORCHID[3]::Float64,
      1.000::Float64)
  end

  const MEDIUM_VIOLET_RED = [
    0.780,
    0.082,
    0.522,
  ]

  function SetCairoRGBA_MEDIUM_VIOLET_RED(ctx)
    return Cairo.set_source_rgba(
      ctx,
      MEDIUM_VIOLET_RED[1]::Float64,
      MEDIUM_VIOLET_RED[2]::Float64,
      MEDIUM_VIOLET_RED[3]::Float64,
      1.000::Float64)
  end

  const PALE_VIOLET_RED = [
    0.859,
    0.439,
    0.576,
  ]

  function SetCairoRGBA_PALE_VIOLET_RED(ctx)
    return Cairo.set_source_rgba(
      ctx,
      PALE_VIOLET_RED[1]::Float64,
      PALE_VIOLET_RED[2]::Float64,
      PALE_VIOLET_RED[3]::Float64,
      1.000::Float64)
  end

  const DEEP_PINK = [
    1.000,
    0.078,
    0.576,
  ]

  function SetCairoRGBA_DEEP_PINK(ctx)
    return Cairo.set_source_rgba(
      ctx,
      DEEP_PINK[1]::Float64,
      DEEP_PINK[2]::Float64,
      DEEP_PINK[3]::Float64,
      1.000::Float64)
  end

  const HOT_PINK = [
    1.000,
    0.412,
    0.706,
  ]

  function SetCairoRGBA_HOT_PINK(ctx)
    return Cairo.set_source_rgba(
      ctx,
      HOT_PINK[1]::Float64,
      HOT_PINK[2]::Float64,
      HOT_PINK[3]::Float64,
      1.000::Float64)
  end

  const LIGHT_PINK = [
    1.000,
    0.714,
    0.757,
  ]

  function SetCairoRGBA_LIGHT_PINK(ctx)
    return Cairo.set_source_rgba(
      ctx,
      LIGHT_PINK[1]::Float64,
      LIGHT_PINK[2]::Float64,
      LIGHT_PINK[3]::Float64,
      1.000::Float64)
  end

  const PINK = [
    1.000,
    0.753,
    0.796,
  ]

  function SetCairoRGBA_PINK(ctx)
    return Cairo.set_source_rgba(
      ctx,
      PINK[1]::Float64,
      PINK[2]::Float64,
      PINK[3]::Float64,
      1.000::Float64)
  end

  const ANTIQUE_WHITE = [
    0.980,
    0.922,
    0.843,
  ]

  function SetCairoRGBA_ANTIQUE_WHITE(ctx)
    return Cairo.set_source_rgba(
      ctx,
      ANTIQUE_WHITE[1]::Float64,
      ANTIQUE_WHITE[2]::Float64,
      ANTIQUE_WHITE[3]::Float64,
      1.000::Float64)
  end

  const BEIGE = [
    0.961,
    0.961,
    0.863,
  ]

  function SetCairoRGBA_BEIGE(ctx)
    return Cairo.set_source_rgba(
      ctx,
      BEIGE[1]::Float64,
      BEIGE[2]::Float64,
      BEIGE[3]::Float64,
      1.000::Float64)
  end

  const BISQUE = [
    1.000,
    0.894,
    0.769,
  ]

  function SetCairoRGBA_BISQUE(ctx)
    return Cairo.set_source_rgba(
      ctx,
      BISQUE[1]::Float64,
      BISQUE[2]::Float64,
      BISQUE[3]::Float64,
      1.000::Float64)
  end

  const BLANCHED_ALMOND = [
    1.000,
    0.922,
    0.804,
  ]

  function SetCairoRGBA_BLANCHED_ALMOND(ctx)
    return Cairo.set_source_rgba(
      ctx,
      BLANCHED_ALMOND[1]::Float64,
      BLANCHED_ALMOND[2]::Float64,
      BLANCHED_ALMOND[3]::Float64,
      1.000::Float64)
  end

  const WHEAT = [
    0.961,
    0.871,
    0.702,
  ]

  function SetCairoRGBA_WHEAT(ctx)
    return Cairo.set_source_rgba(
      ctx,
      WHEAT[1]::Float64,
      WHEAT[2]::Float64,
      WHEAT[3]::Float64,
      1.000::Float64)
  end

  const CORN_SILK = [
    1.000,
    0.973,
    0.863,
  ]

  function SetCairoRGBA_CORN_SILK(ctx)
    return Cairo.set_source_rgba(
      ctx,
      CORN_SILK[1]::Float64,
      CORN_SILK[2]::Float64,
      CORN_SILK[3]::Float64,
      1.000::Float64)
  end

  const LEMON_CHIFFON = [
    1.000,
    0.980,
    0.804,
  ]

  function SetCairoRGBA_LEMON_CHIFFON(ctx)
    return Cairo.set_source_rgba(
      ctx,
      LEMON_CHIFFON[1]::Float64,
      LEMON_CHIFFON[2]::Float64,
      LEMON_CHIFFON[3]::Float64,
      1.000::Float64)
  end

  const LIGHT_GOLDEN_ROD_YELLOW = [
    0.980,
    0.980,
    0.824,
  ]

  function SetCairoRGBA_LIGHT_GOLDEN_ROD_YELLOW(ctx)
    return Cairo.set_source_rgba(
      ctx,
      LIGHT_GOLDEN_ROD_YELLOW[1]::Float64,
      LIGHT_GOLDEN_ROD_YELLOW[2]::Float64,
      LIGHT_GOLDEN_ROD_YELLOW[3]::Float64,
      1.000::Float64)
  end

  const LIGHT_YELLOW = [
    1.000,
    1.000,
    0.878,
  ]

  function SetCairoRGBA_LIGHT_YELLOW(ctx)
    return Cairo.set_source_rgba(
      ctx,
      LIGHT_YELLOW[1]::Float64,
      LIGHT_YELLOW[2]::Float64,
      LIGHT_YELLOW[3]::Float64,
      1.000::Float64)
  end

  const SADDLE_BROWN = [
    0.545,
    0.271,
    0.075,
  ]

  function SetCairoRGBA_SADDLE_BROWN(ctx)
    return Cairo.set_source_rgba(
      ctx,
      SADDLE_BROWN[1]::Float64,
      SADDLE_BROWN[2]::Float64,
      SADDLE_BROWN[3]::Float64,
      1.000::Float64)
  end

  const SIENNA = [
    0.627,
    0.322,
    0.176,
  ]

  function SetCairoRGBA_SIENNA(ctx)
    return Cairo.set_source_rgba(
      ctx,
      SIENNA[1]::Float64,
      SIENNA[2]::Float64,
      SIENNA[3]::Float64,
      1.000::Float64)
  end

  const CHOCOLATE = [
    0.824,
    0.412,
    0.118,
  ]

  function SetCairoRGBA_CHOCOLATE(ctx)
    return Cairo.set_source_rgba(
      ctx,
      CHOCOLATE[1]::Float64,
      CHOCOLATE[2]::Float64,
      CHOCOLATE[3]::Float64,
      1.000::Float64)
  end

  const PERU = [
    0.804,
    0.522,
    0.247,
  ]

  function SetCairoRGBA_PERU(ctx)
    return Cairo.set_source_rgba(
      ctx,
      PERU[1]::Float64,
      PERU[2]::Float64,
      PERU[3]::Float64,
      1.000::Float64)
  end

  const SANDY_BROWN = [
    0.957,
    0.643,
    0.376,
  ]

  function SetCairoRGBA_SANDY_BROWN(ctx)
    return Cairo.set_source_rgba(
      ctx,
      SANDY_BROWN[1]::Float64,
      SANDY_BROWN[2]::Float64,
      SANDY_BROWN[3]::Float64,
      1.000::Float64)
  end

  const BURLY_WOOD = [
    0.871,
    0.722,
    0.529,
  ]

  function SetCairoRGBA_BURLY_WOOD(ctx)
    return Cairo.set_source_rgba(
      ctx,
      BURLY_WOOD[1]::Float64,
      BURLY_WOOD[2]::Float64,
      BURLY_WOOD[3]::Float64,
      1.000::Float64)
  end

  const TAN = [
    0.824,
    0.706,
    0.549,
  ]

  function SetCairoRGBA_TAN(ctx)
    return Cairo.set_source_rgba(
      ctx,
      TAN[1]::Float64,
      TAN[2]::Float64,
      TAN[3]::Float64,
      1.000::Float64)
  end

  const ROSY_BROWN = [
    0.737,
    0.561,
    0.561,
  ]

  function SetCairoRGBA_ROSY_BROWN(ctx)
    return Cairo.set_source_rgba(
      ctx,
      ROSY_BROWN[1]::Float64,
      ROSY_BROWN[2]::Float64,
      ROSY_BROWN[3]::Float64,
      1.000::Float64)
  end

  const MOCCASIN = [
    1.000,
    0.894,
    0.710,
  ]

  function SetCairoRGBA_MOCCASIN(ctx)
    return Cairo.set_source_rgba(
      ctx,
      MOCCASIN[1]::Float64,
      MOCCASIN[2]::Float64,
      MOCCASIN[3]::Float64,
      1.000::Float64)
  end

  const NAVAJO_WHITE = [
    1.000,
    0.871,
    0.678,
  ]

  function SetCairoRGBA_NAVAJO_WHITE(ctx)
    return Cairo.set_source_rgba(
      ctx,
      NAVAJO_WHITE[1]::Float64,
      NAVAJO_WHITE[2]::Float64,
      NAVAJO_WHITE[3]::Float64,
      1.000::Float64)
  end

  const PEACH_PUFF = [
    1.000,
    0.855,
    0.725,
  ]

  function SetCairoRGBA_PEACH_PUFF(ctx)
    return Cairo.set_source_rgba(
      ctx,
      PEACH_PUFF[1]::Float64,
      PEACH_PUFF[2]::Float64,
      PEACH_PUFF[3]::Float64,
      1.000::Float64)
  end

  const MISTY_ROSE = [
    1.000,
    0.894,
    0.882,
  ]

  function SetCairoRGBA_MISTY_ROSE(ctx)
    return Cairo.set_source_rgba(
      ctx,
      MISTY_ROSE[1]::Float64,
      MISTY_ROSE[2]::Float64,
      MISTY_ROSE[3]::Float64,
      1.000::Float64)
  end

  const LAVENDER_BLUSH = [
    1.000,
    0.941,
    0.961,
  ]

  function SetCairoRGBA_LAVENDER_BLUSH(ctx)
    return Cairo.set_source_rgba(
      ctx,
      LAVENDER_BLUSH[1]::Float64,
      LAVENDER_BLUSH[2]::Float64,
      LAVENDER_BLUSH[3]::Float64,
      1.000::Float64)
  end

  const LINEN = [
    0.980,
    0.941,
    0.902,
  ]

  function SetCairoRGBA_LINEN(ctx)
    return Cairo.set_source_rgba(
      ctx,
      LINEN[1]::Float64,
      LINEN[2]::Float64,
      LINEN[3]::Float64,
      1.000::Float64)
  end

  const OLD_LACE = [
    0.992,
    0.961,
    0.902,
  ]

  function SetCairoRGBA_OLD_LACE(ctx)
    return Cairo.set_source_rgba(
      ctx,
      OLD_LACE[1]::Float64,
      OLD_LACE[2]::Float64,
      OLD_LACE[3]::Float64,
      1.000::Float64)
  end

  const PAPAYA_WHIP = [
    1.000,
    0.937,
    0.835,
  ]

  function SetCairoRGBA_PAPAYA_WHIP(ctx)
    return Cairo.set_source_rgba(
      ctx,
      PAPAYA_WHIP[1]::Float64,
      PAPAYA_WHIP[2]::Float64,
      PAPAYA_WHIP[3]::Float64,
      1.000::Float64)
  end

  const SEA_SHELL = [
    1.000,
    0.961,
    0.933,
  ]

  function SetCairoRGBA_SEA_SHELL(ctx)
    return Cairo.set_source_rgba(
      ctx,
      SEA_SHELL[1]::Float64,
      SEA_SHELL[2]::Float64,
      SEA_SHELL[3]::Float64,
      1.000::Float64)
  end

  const MINT_CREAM = [
    0.961,
    1.000,
    0.980,
  ]

  function SetCairoRGBA_MINT_CREAM(ctx)
    return Cairo.set_source_rgba(
      ctx,
      MINT_CREAM[1]::Float64,
      MINT_CREAM[2]::Float64,
      MINT_CREAM[3]::Float64,
      1.000::Float64)
  end

  const SLATE_GRAY = [
    0.439,
    0.502,
    0.565,
  ]

  function SetCairoRGBA_SLATE_GRAY(ctx)
    return Cairo.set_source_rgba(
      ctx,
      SLATE_GRAY[1]::Float64,
      SLATE_GRAY[2]::Float64,
      SLATE_GRAY[3]::Float64,
      1.000::Float64)
  end

  const LIGHT_SLATE_GRAY = [
    0.467,
    0.533,
    0.600,
  ]

  function SetCairoRGBA_LIGHT_SLATE_GRAY(ctx)
    return Cairo.set_source_rgba(
      ctx,
      LIGHT_SLATE_GRAY[1]::Float64,
      LIGHT_SLATE_GRAY[2]::Float64,
      LIGHT_SLATE_GRAY[3]::Float64,
      1.000::Float64)
  end

  const LIGHT_STEEL_BLUE = [
    0.690,
    0.769,
    0.871,
  ]

  function SetCairoRGBA_LIGHT_STEEL_BLUE(ctx)
    return Cairo.set_source_rgba(
      ctx,
      LIGHT_STEEL_BLUE[1]::Float64,
      LIGHT_STEEL_BLUE[2]::Float64,
      LIGHT_STEEL_BLUE[3]::Float64,
      1.000::Float64)
  end

  const LAVENDER = [
    0.902,
    0.902,
    0.980,
  ]

  function SetCairoRGBA_LAVENDER(ctx)
    return Cairo.set_source_rgba(
      ctx,
      LAVENDER[1]::Float64,
      LAVENDER[2]::Float64,
      LAVENDER[3]::Float64,
      1.000::Float64)
  end

  const FLORAL_WHITE = [
    1.000,
    0.980,
    0.941,
  ]

  function SetCairoRGBA_FLORAL_WHITE(ctx)
    return Cairo.set_source_rgba(
      ctx,
      FLORAL_WHITE[1]::Float64,
      FLORAL_WHITE[2]::Float64,
      FLORAL_WHITE[3]::Float64,
      1.000::Float64)
  end

  const ALICE_BLUE = [
    0.941,
    0.973,
    1.000,
  ]

  function SetCairoRGBA_ALICE_BLUE(ctx)
    return Cairo.set_source_rgba(
      ctx,
      ALICE_BLUE[1]::Float64,
      ALICE_BLUE[2]::Float64,
      ALICE_BLUE[3]::Float64,
      1.000::Float64)
  end

  const GHOST_WHITE = [
    0.973,
    0.973,
    1.000,
  ]

  function SetCairoRGBA_GHOST_WHITE(ctx)
    return Cairo.set_source_rgba(
      ctx,
      GHOST_WHITE[1]::Float64,
      GHOST_WHITE[2]::Float64,
      GHOST_WHITE[3]::Float64,
      1.000::Float64)
  end

  const HONEYDEW = [
    0.941,
    1.000,
    0.941,
  ]

  function SetCairoRGBA_HONEYDEW(ctx)
    return Cairo.set_source_rgba(
      ctx,
      HONEYDEW[1]::Float64,
      HONEYDEW[2]::Float64,
      HONEYDEW[3]::Float64,
      1.000::Float64)
  end

  const IVORY = [
    1.000,
    1.000,
    0.941,
  ]

  function SetCairoRGBA_IVORY(ctx)
    return Cairo.set_source_rgba(
      ctx,
      IVORY[1]::Float64,
      IVORY[2]::Float64,
      IVORY[3]::Float64,
      1.000::Float64)
  end

  const AZURE = [
    0.941,
    1.000,
    1.000,
  ]

  function SetCairoRGBA_AZURE(ctx)
    return Cairo.set_source_rgba(
      ctx,
      AZURE[1]::Float64,
      AZURE[2]::Float64,
      AZURE[3]::Float64,
      1.000::Float64)
  end

  const SNOW = [
    1.000,
    0.980,
    0.980,
  ]

  function SetCairoRGBA_SNOW(ctx)
    return Cairo.set_source_rgba(
      ctx,
      SNOW[1]::Float64,
      SNOW[2]::Float64,
      SNOW[3]::Float64,
      1.000::Float64)
  end

  const BLACK = [
    0.000,
    0.000,
    0.000,
  ]

  function SetCairoRGBA_BLACK(ctx)
    return Cairo.set_source_rgba(
      ctx,
      BLACK[1]::Float64,
      BLACK[2]::Float64,
      BLACK[3]::Float64,
      1.000::Float64)
  end

  const DIM_GRAY = [
    0.412,
    0.412,
    0.412,
  ]

  function SetCairoRGBA_DIM_GRAY(ctx)
    return Cairo.set_source_rgba(
      ctx,
      DIM_GRAY[1]::Float64,
      DIM_GRAY[2]::Float64,
      DIM_GRAY[3]::Float64,
      1.000::Float64)
  end

  const DARK_GRAY = [
    0.663,
    0.663,
    0.663,
  ]

  function SetCairoRGBA_DARK_GRAY(ctx)
    return Cairo.set_source_rgba(
      ctx,
      DARK_GRAY[1]::Float64,
      DARK_GRAY[2]::Float64,
      DARK_GRAY[3]::Float64,
      1.000::Float64)
  end

  const LIGHT_GRAY = [
    0.827,
    0.827,
    0.827,
  ]

  function SetCairoRGBA_LIGHT_GRAY(ctx)
    return Cairo.set_source_rgba(
      ctx,
      LIGHT_GRAY[1]::Float64,
      LIGHT_GRAY[2]::Float64,
      LIGHT_GRAY[3]::Float64,
      1.000::Float64)
  end

  const GAINSBORO = [
    0.863,
    0.863,
    0.863,
  ]

  function SetCairoRGBA_GAINSBORO(ctx)
    return Cairo.set_source_rgba(
      ctx,
      GAINSBORO[1]::Float64,
      GAINSBORO[2]::Float64,
      GAINSBORO[3]::Float64,
      1.000::Float64)
  end

  const WHITE_SMOKE = [
    0.961,
    0.961,
    0.961,
  ]

  function SetCairoRGBA_WHITE_SMOKE(ctx)
    return Cairo.set_source_rgba(
      ctx,
      WHITE_SMOKE[1]::Float64,
      WHITE_SMOKE[2]::Float64,
      WHITE_SMOKE[3]::Float64,
      1.000::Float64)
  end

  const WHITE = [
    1.000,
    1.000,
    1.000,
  ]

  function SetCairoRGBA_WHITE(ctx)
    return Cairo.set_source_rgba(
      ctx,
      WHITE[1]::Float64,
      WHITE[2]::Float64,
      WHITE[3]::Float64,
      1.000::Float64)
  end

  c = CairoRGBSurface(256,256)
  cr = CairoContext(c)
  save(cr)
  SetCairoRGBA_ELECTRIC_INDIGO(cr)
  rectangle(cr,0.0,0.0,256.0,256.0)
  fill(cr)
  restore(cr)
  save(cr)
  write_to_png(c,"sample_electric_indigo.png");
end # module


text:
VERSION >= v"0.4-" && __precompile__()

module YAML
    import Base: start, next, done, isempty, length, show
    import Codecs
    using Compat

    if VERSION < v"0.4-dev"
        using Dates
    end

    include("scanner.jl")
    include("parser.jl")
    include("composer.jl")
    include("constructor.jl")

    function load(ts::TokenStream)
        events = EventStream(ts)
        node = compose(events)
        return construct_document(Constructor(), node)
    end

    function load(input::IO)
        return load(TokenStream(input))
    end

    type YAMLDocIterator
        input::IO
        ts::TokenStream
        next_doc

        function YAMLDocIterator(input::IO)
            it = new(input, TokenStream(input), nothing)
            it.next_doc = eof(it.input) ? nothing : load(it.ts)
            return it
        end
    end

    function start(it::YAMLDocIterator)
        nothing
    end

    function next(it::YAMLDocIterator, state)
        doc = it.next_doc
        if eof(it.input)
            it.next_doc = nothing
        else
            reset!(it.ts)
            it.next_doc = load(it.ts)
        end
        return doc, nothing
    end

    function done(it::YAMLDocIterator, state)
        return it.next_doc === nothing
    end

    function load_all(input::IO)
        YAMLDocIterator(input)
    end

    load(input::AbstractString) = load(IOBuffer(input))
    load_all(input::AbstractString) = load_all(IOBuffer(input))

    function load_file(filename::AbstractString)
        input = open(filename)
        data = load(input)
        close(input)
        data
    end

    function load_all_file(filename::AbstractString)
        input = open(filename)
        data = load_all(input)
        close(input)
        data
    end
end


text:
# helper function for testing to load the example results
function load_example(path, ncol, delim = ',', skiplines = 1) #make sure to use nscenario+1 cols

    nlines = countlines(path) - skiplines
    output = Array{Float64, 2}(undef, nlines, ncol)
    filestream = open(path, "r")

    try
        for skip in 1:skiplines
            readline(filestream)
        end

        for (index, line) in enumerate(eachline(filestream))
            parsedline = parse.(Float64, split(line, delim, keepempty = false))
            output[index, :] = parsedline
        end
    finally
        close(filestream)
    end

    return output
end

# helper function for testing to interpolate the results to match wellbore segmentation
function match_example(well::Wellbore, example::Array{Float64,2})
    nrow = length(well.md)
    ncol = size(example)[2]
    output = Array{Float64, 2}(undef, nrow, ncol)
    output[:, 1] = well.md

    output[1, 2:end] = example[1, 2:end]
    for depth_index in 2:length(well.md)
        depth = well.md[depth_index]
        row_above = example[example[:,1] .<= depth, :][end,:]

        if row_above[1] == depth
            output[depth_index,2:end] = row_above[2:end]
        else
            row_below = example[example[:,1] .> depth, :][1,:]
            #interpolated_row = y1 + (y2 - y1)/(x2 - x1) * (depth - x1) :
            interpolated_values = [row_above[i] + (row_below[i] - row_above[i])/(row_below[1] - row_above[1]) * (depth - row_above[1]) for i in 2:ncol]
            output[depth_index,2:end] = interpolated_values
        end
    end

    return output
end

#%% general parameters
dp_est = 10 #psi
error_tolerance = 0.1 #psi
outlet_pressure = 220 - 14.65 #WHP in psig
oil_API = 35
sg_gas = 0.65
CO2 = 0.005
sg_water = 1.07
roughness = 0.0006500
BHT = 165
id = 2.441

#%% scenario parameters
scenarios = (:A, :B, :C, :D, :E)

parameters =    (rate = (A = 500, B = 250, C = 1000, D = 3000, E = 50),
                 WC = (A = 0.5, B = 0.25, C = 0.75, D = 0.85, E = 0.25),
                 GLR = (A = 4500, B = 6000, C = 3000, D = 1200, E = 10000),
                 WHT = (A = 100, B = 90, C = 105, D = 115, E = 80))

#%% load test Wellbore
testpath = joinpath(dirname(dirname(pathof(PressureDrop))), "test/testdata/Sawgrass_9_32")
surveypath = joinpath(testpath, "Test_survey_Sawgrass_9.csv")
testwell = read_survey(path = surveypath, id = id)

#%% generate linear temperature profiles
function create_temps(scenario)
        WHT = parameters[:WHT][scenario]

        return linear_wellboretemp(WHT = WHT, BHT = BHT, wellbore = testwell)
end

temps = [create_temps(s) for s in scenarios]
temp_profiles = NamedTuple{scenarios}(temps) #temp profiles labelled by scenario

@testset "Beggs and Brill with Palmer correction - scenarios" begin

# load test results to compare & generate interpolations from expected results at same depths as test well segmentation
examplepath = joinpath(testpath,"Perform_BandB_with_Palmer_correction.csv")
test_example = load_example(examplepath, length(scenarios)+1)
matched_example = match_example(testwell, test_example)
matched_example[:,2:end] = matched_example[:,2:end] .- 14.65 #convert to psig

# generate test data -- map across all examples
corr = BeggsAndBrill
test_results = Array{Float64, 2}(undef, length(testwell.md), 1 + length(scenarios))
test_results[:,1] = testwell.md
for (index, scenario) in enumerate(scenarios)
    WC = parameters[:WC][scenario]
    rate = parameters[:rate][scenario]
    q_o = rate * (1 - WC)
    q_w = rate * WC
    GLR = parameters[:GLR][scenario]

    test_results[:,index+1] = traverse_topdown(wellbore = testwell, roughness = roughness, temperatureprofile = temp_profiles[scenario],
                             pressurecorrelation = corr, dp_est = dp_est, error_tolerance = error_tolerance,
                             q_o = q_o, q_w = q_w, GLR = GLR, APIoil = oil_API, sg_water = sg_water, sg_gas = sg_gas,
                             WHP = outlet_pressure, molFracCO2 = CO2)
end

# compare test data
# NOTE: points after the first survey point at > 90° inclination are discarded;
# the reference data appears to force positive frictional effects.
hz_index = findnext(x -> x >= 90, testwell.inc, 1)
compare_tolerance = 40 #every scenario except the high-rate scenario can take a 15-psi tolerance
for index in 2:length(scenarios)+1
    println("Comparing scenario ", index-1, " on index ", index)
    @test all( abs.(test_results[1:hz_index,index] .- matched_example[1:hz_index,index])  .<= compare_tolerance )
    println("Max difference : ", maximum(abs.(test_results[1:hz_index,index] .- matched_example[1:hz_index,index])))
end

end #testset for B&B scenarios

@testset "Hagedorn & Brown with G&W correction - scenarios" begin

# load test results to compare & generate interpolations from expected results at same depths as test well segmentation
examplepath = joinpath(testpath,"Perform_HandB_with_GriffithWallis.csv")
test_example = load_example(examplepath, length(scenarios)+1)
matched_example = match_example(testwell, test_example)
matched_example[:,2:end] = matched_example[:,2:end] .- 14.65 #convert to psig

# generate test data -- map across all examples
corr = HagedornAndBrown
test_results = Array{Float64, 2}(undef, length(testwell.md), 1 + length(scenarios))
test_results[:,1] = testwell.md
for (index, scenario) in enumerate(scenarios)
    WC = parameters[:WC][scenario]
    rate = parameters[:rate][scenario]
    q_o = rate * (1 - WC)
    q_w = rate * WC
    GLR = parameters[:GLR][scenario]

    test_results[:,index+1] = traverse_topdown(wellbore = testwell, roughness = roughness, temperatureprofile = temp_profiles[scenario],
                             pressurecorrelation = corr, dp_est = dp_est, error_tolerance = error_tolerance,
                             q_o = q_o, q_w = q_w, GLR = GLR, APIoil = oil_API, sg_water = sg_water, sg_gas = sg_gas,
                             WHP = outlet_pressure, molFracCO2 = CO2)
end

# compare test data
# NOTE: points after the first survey point at > 90° inclination are discarded
hz_index = findnext(x -> x >= 90, testwell.inc, 1)
compare_tolerance = 85 #lposer tolerance to H&B due to wide range of methods to calculate correlating groups & reynolds numbers
for index in 2:length(scenarios)+1
    println("Comparing scenario ", index-1, " on index ", index)
    @test all( abs.(test_results[1:hz_index,index] .- matched_example[1:hz_index,index])  .<= compare_tolerance )
    println("Max difference : ", maximum(abs.(test_results[1:hz_index,index] .- matched_example[1:hz_index,index])))
end

end #H&B testset


text:
module Packing

using ..Structs

export max_side, PackResult, pack

# Packing Algorithm
# Inspired by [this blog post](https://blackpawn.com/texts/lightmaps/default.html)

PackResult = Vector{Union{NTuple{N,Float64},Nothing}} where {N}

function partition!(
    node::SpaceNode{N},
    dim::Integer,
    pos::Real,
)::NTuple{2,SpaceNode{N}} where {N}
    space = node.data

    left_dims = Tuple(
        i == dim ? pos : space.rect.dims[i]
        for i=1:N
    )
    left_pos = space.rect.pos

    right_dims = Tuple(
        i == dim ? space.rect.dims[i] - pos : space.rect.dims[i]
        for i=1:N
    )
    right_pos = Tuple(
        i == dim ? space.rect.pos[i] + pos : space.rect.pos[i]
        for i=1:N
    )

    left_space = RectangularSpace(left_dims, left_pos)
    left_node = leftchild!(node, left_space)
    right_space = RectangularSpace(right_dims, right_pos)
    right_node = rightchild!(node, right_space)

    return left_node, right_node
end

function partition!(
    node::SpaceNode{N},
    rect::Rectangle{N},
)::NTuple{N,Float64} where {N}
    # We want to split the dimensions in descending order
    # to leave as much contiguous space as possible
    space = node.data
    dim_diff = space.rect.dims .- rect.dims |> collect
    dim_order = sortperm(dim_diff, rev = true)

    target = node
    for dim in dim_order
        # Always split the left child
        target, _ = partition!(target, dim, rect.dims[dim])
    end

    # The leftmost space is now occupied
    target.data.empty = false
    # Return the newly occupied position
    return target.data.rect.pos
end

function insert!(
    node::SpaceNode{N},
    rect::Rectangle{N},
)::Union{NTuple{N,Float64},Nothing} where {N}
    # TODO: Use BFS? Or iterate over leaves, sorted by size?
    if !isleaf(node)
        new_pos = insert!(node.left, rect)
        if new_pos != nothing
            return new_pos
        else
            return insert!(node.right, rect)
        end
    else
        space = node.data
        if isempty(space)
            if samesize(rect, space)
                space.empty = false
                return space.rect.pos
            elseif fits(rect, space)
                return partition!(node, rect)
            end
        end
    end
    return nothing
end

function pack(
    container_dims::NTuple{N,<:Real},
    rect_dims::Vector{NTuple{N,T}},
)::PackResult{N} where {T<:Real} where {N}
    root = BinaryNode(RectangularSpace(container_dims, Tuple(zeros(N))))
    rectangles = Rectangle.(rect_dims)
    positions = PackResult{N}([])
    for rect in rectangles
        pos = insert!(root, rect)
        push!(positions, pos)
    end

    return positions
end

function pack(
    container_dims::NTuple{N,<:Real},
    rect_dims::Vector{Vector{T}},
)::PackResult{N} where {T<:Real} where {N}
    return pack(container_dims, rect_dims .|> Tuple)
end

end # module


text:
using Polynomials

p = Poly([-42,0,-12,1])
q = Poly([-3,1])

d, r = divrem(p,q)

println(p, " divided by ", q, " is ", d, " with remainder ", r, ".")

max_stars_repo_name: ethansaxenian/RosettaDecode

max_issues_repo_name: ethansaxenian/RosettaDecode

max_forks_repo_name: ethansaxenian/RosettaDecode


text:
using DataFrames, VML

function sqrt_bench()

    N = [1,2,3,4,5,6,7,8,9,
         10,20,30,40,50,60,70,80,90,100,200,300,400,500,750,
         1_000,2_500,5_000,7_500,10_000,100_000,1_000_000]

    # df = DataFrame(N=Int64[],ALLOC=Float64[],JULIA=Float64[],MKL=Float64[])
    df = DataFrame(N=Int64[],ALLOC=Float64[],JULIA=Float64[])

    @inbounds for i in 1:length(N)
        T = Float64
        n = N[i]
        a = rand(T,n)
        dest = zeros(T,n)
        # sqrt(a)
        # VML.sqrt!(dest,a)

        nrep = 1000
        ncycle = 10_000 ÷ n + 1

        gc()
        tcpu1 = 0.0 ; tcpu2 = 0.0 ; talloc = 0.0
        for j in 1:nrep
            talloc += @elapsed for k in 1:ncycle Vector{T}(n) end
            tcpu1 += @elapsed for k in 1:ncycle sqrt(a) end
            # tcpu2 += @elapsed for k in 1:ncycle VML.sqrt!(dest,a) end
        end
        talloc = talloc / nrep / ncycle / n * 1e9
        tcpu1 = tcpu1 / nrep / ncycle / n * 1e9
        # tcpu2 = tcpu2 / nrep / ncycle / n * 1e9

        # push!(df,[n,talloc, tcpu1, tcpu2])
        push!(df,[n,talloc, tcpu1])
    end
    df
end

df = sqrt_bench();
df[:diff] = df[:JULIA]-df[:ALLOC]
println(df)

path = Pkg.dir("MKL") * "/benchmark/final/"
writetable(path * "sqrt_allocationimpact_data.csv", df, separator=',')


text:
# This should probably be in a seperate package

function fit_np!(P, a, x)
    map(x->fill!(x, zero(eltype(P[1]))), P)
    nxobs = zeros(length(P[1]))
    @inbounds for i_obs = 1:length(a)
        x_obs = x[i_obs]
        nxobs[x_obs] += 1
        P[a[i_obs]][x_obs] += 1
    end
    for ia = 1:length(P)
        for i = 1:length(P[1])
            if nxobs[i] == 0
                P[ia][i] = 0.5
            elseif P[ia][i] == 0
                P[ia][i] = 1e-6
            elseif P[ia][i] == nxobs[i]
                P[ia][i] = P[ia][i]/nxobs[i] - 1e-6
            else
                P[ia][i] = P[ia][i]/nxobs[i]
            end
        end
    end
    ConvergenceNPL() # should probably save this
end