text:
## A chain is an arrangement of rotators between n and N
## Three types are specialized: Descending, Ascending, Twisted

#### Group rotators

abstract type AbstractRotatorChain{T,S} end

Base.eltype(A::AbstractRotatorChain) = eltype(A.x)
Base.length(A::AbstractRotatorChain) = length(A.x)

Base.@propagate_inbounds Base.getindex(A::AbstractRotatorChain, i::Int) = getindex(A.x, i)
Base.@propagate_inbounds Base.setindex!(A::AbstractRotatorChain, X, inds...) = setindex!(A.x, X, inds...)
Base.deleteat!(A::AbstractRotatorChain, j) = deleteat!(A.x, j)

Base.iterate(A::AbstractRotatorChain) = iterate(A.x)
Base.iterate(A::AbstractRotatorChain, st) = iterate(A.x, st)
*(A::AbstractRotatorChain, M::Array) = Vector(A) * M
*(M::Array, A::AbstractRotatorChain) = M * Vector(A)
LinearAlgebra.lmul!(A::AbstractRotatorChain, M::Array) = lmul!(Vector(A), M)
LinearAlgebra.rmul!(M::Array, A::AbstractRotatorChain) = rmul!(M, Vector(A))

function Base.size(C::AbstractRotatorChain)
    n, N = extrema(C)
    (N+1, N+1)
end

Base.extrema(C::AbstractRotatorChain) = extrema(idx.((C.x[1], C.x[end])))

function Base.Matrix(C::AbstractRotatorChain)
    S =  eltype(first(C.x).c)
    M = diagm(0 => ones(S, size(C)[2]))
    lmul!(C, M)
end

## Types of chains
struct DescendingChain{T, S, V <: AbstractVector{Rotator{T,S}}} <: AbstractRotatorChain{T,S}
  x::V
end

## We store ascending chain in order n, n-1, n-2, ...
struct AscendingChain{T,S, V <: AbstractVector{Rotator{T,S}}} <: AbstractRotatorChain{T,S}
  x::V
end

const MonotonicChain = Union{DescendingChain, AscendingChain}

Base.view(D::MonotonicChain, inds...) = DescendingChain(view(D.x, inds...))
Base.copy(D::DescendingChain) = DescendingChain(copy(D.x))
Base.copy(D::AscendingChain) = AscendingChain(copy(D.x))
Base.pop!(D::MonotonicChain) = pop!(D.x)
Base.popfirst!(D::MonotonicChain) = popfirst!(D.x)
Base.push!(D::MonotonicChain) = push!(D.x)
Base.pushfirst!(D::MonotonicChain) = pushfirst!(D.x)

Base.Vector(D::MonotonicChain) = D.x

Base.adjoint(A::AscendingChain) = DescendingChain(reverse(adjoint.(A.x)))
Base.adjoint(A::DescendingChain) = AscendingChain(reverse(adjoint.(A.x)))

function Base.getindex(A::AscendingChain{T}, i, j) where {T}
    N = length(A.x)
    S = eltype(first(A.x))

    if i == N + 1
        i -= 1; j -= 1
        ci, si = vals(A.x[N+1-i])

        j == N && return conj(ci)

        s = -S(si)
        for l in (j+1):(i-1)
            cj, sjj = vals(A.x[N+1-l])
            s *= -sjj
        end
        cj, sj = j > 0 ? vals(A.x[N+1-j]) : (one(S), zero(S))
        return s * conj(cj)

    else

        j > i+1 && return zero(S) # ascending chain's aree lower Hessian

        ci, si = vals(A.x[N+1-i])

        if j == i + 1
            return S(si)
        elseif j == i
            cj, sj  = j > 1 ? vals(A.x[N+1-(j-1)]) : (one(S), zeros(S))
            return conj(cj)*ci
        end

        s = one(S)
        for l in j:(i-1)
            cl, sl = vals(A.x[N+1-l])
            s *= -sl
        end

        cl, sl = j > 1 ? vals(A.x[N+1 - (j-1)]) : (one(S), zero(S))
        return ci * s * conj(cl)
    end

end

function Base.getindex(A::DescendingChain, i, j)

    N = length(A.x)
    S = eltype(first(A.x))

    if i > j + 1 || i <= 0 || j <= 0
        return zero(S)
    end

    if j == N + 1
        j -= 1
        cj, sj = vals(A.x[j])

        i == N+1 && return conj(cj)

        i -= 1
        s::S = sj
        for l in (i+1):j-1
            cj, sj = vals(A.x[l])
            s *= S(sj)
        end
        ci, si = i > 0 ? vals(A.x[i]) : (one(S), zero(real(S)))
        return s * conj(ci)

    else

        cj, sj = vals(A.x[j])

        if i == j + 1

            return -S(sj)

        elseif j == i

            ci, si  = i >= 2 ? vals(A.x[i-1]) : (one(S), zero(real(S)))
            return conj(ci)*cj

        end

        s = one(S)
        for l in i:(j-1)
            cl, sl = vals(A.x[l])
            s *= sl
        end

        cl, sl = i >= 2 ? vals(A.x[i-1]) : (one(S), zero(real(S)))
        return cj * s * conj(cl)
    end
end

## Structure to hold a twisted represenation
## pv is the position vector of length  n-1; we leave parametric so views can be used
struct TwistedChain{T,S, V <: AbstractVector{Rotator{T,S}}, PVt <: AbstractVector{Symbol}} <: AbstractRotatorChain{T,S}
  x::V
  pv::PVt
end

function Base.view(Tw::TwistedChain, inds::UnitRange)
    start, stop = inds.start, inds.stop
    TwistedChain(view(Tw.x, inds), view(Tw.pv, start:stop-1))
end

Base.copy(Tw::TwistedChain) = TwistedChain(copy(Tw.x), copy(Tw.pv))

## Twisted Chains requires a bit more effort
## Constructor from a twisted vector of rotators
function TwistedChain(xs::Vector{Rotator{T,S}}) where {T,S}
    if length(xs) > 0
        sigma = idx.(xs)
        ps = position_vector(sigma)
        TwistedChain(xs[sortperm(sigma)], ps)
    else
        TwistedChain(xs, Symbol[])
    end
end

function position_vector_indices(pv)

    inds = [1]

    for (j,d) in enumerate(pv)
        i = j + 1
        d == :left ? push!(inds, i) : pushfirst!(inds, i)
    end

    inds
end

function Base.Vector(Tw::TwistedChain)
    isempty(Tw.x) && return Tw.x

    return Tw.x[position_vector_indices(Tw.pv)]
end

## Find position vector from a permuation of 1...n
## If i is to the left of i+1, set  ps[i] = :left
## if i is to the right if i+1, set ps[i] = :right
## e.g. 4,3,2,1 -> r,r,r (descending)
##      1,2,3,4 -> l,l,l (ascending)
##      1,3,2,4 -> rlr  (CMV)
function position_vector(sigma)
    ## sigma a perm of 1....n
    sigma = sigma .- minimum(sigma) .+ 1
    n = length(sigma)
    n <= 1 && return Symbol[]
    ps =  repeat([:nothing],n-1)
    for (i,v) in enumerate(sigma)
       if v == 1

            if ps[1] == :nothing
              ps[1] = :left
            end
       elseif  v == n
            if ps[end] == :nothing
                ps[end] = :right
            end
       else
          if ps[v-1] == :nothing
                ps[v-1] =  :right
            end
            if ps[v]  == :nothing
                ps[v] = :left
            end
        end
    end
    ps
end

## note this is expensive
Base.adjoint(A::TwistedChain) = TwistedChain(reverse(adjoint.(Vector(A))))

# In a Twisted chain from n to N, pop off the N rotator
# and modify the position vector
function Base.pop!(A::TwistedChain)
    pop!(A.x), (isempty(A.pv) ? :nothing : pop!(A.pv))
end

## This should be an iterator
##   Indices of Tw.x  to  pass twisted chain from  right side to left side
## grab right terms from bottom
function iterate_rl(pv)
    # indices in Tw.x to move object from l to r
    N = length(pv)+1
    inds =  Int[]
    for (i,pi)  in enumerate(reverse(pv))
        if  pi  ==  :right
            j  = N  - i
            push!(inds, j+1)
        end
    end
    for i  in 1:N
        if  !(i in inds)
            push!(inds, i)
        end
    end
    inds
end

function iterate_lr(pv)
    # indices to move  object from left side to right
      # indices in Tw.x to move object from l to r
    N = length(pv)+1
    inds =  Int[]
    for (i,pi)  in enumerate(reverse(pv))
        if  pi  ==  :left
            j = N - i
            push!(inds, j+1)
        end
    end
    for i  in 1:N
        if  !(i in inds)
            push!(inds, i)
        end
    end
    inds
end

## Fish out of M the rotator with idx i
## return index in Ms.x and the rotator
function iget(Ms::TwistedChain, i)

    m,M = extrema(Ms)
    j = i - (m-1)
    U = Ms[j]

    j, U
end

## From a twisted chain and index i, return ascending part of i-1, i-2, ....
function ascending_part(Ms::TwistedChain, i, Δ=1)
    n, N = extrema(Ms)
    pv = Ms.pv

    start = i
    stop = i-1

    (i <  n || i > N + 1) && return  AscendingChain(view(Ms.x, 1:0)) #start:stop # empyt inds #(inds, Asc)
    while i > Δ
        i -= 1
        if i >= n && (i == N || pv[i-n+1] == :right) ## i-n+1 seems right when n != 1
            start = i
        else
            break
        end
    end

    AscendingChain(view(Ms.x, (stop-n+1):-1:(start-n+1)))

end

## Return (i+1):j where Ui, Ui+1, ... Uj is descending chain
function descending_part(Ms::TwistedChain, i, Δ=extrema(Ms)[2])
    n, N = extrema(Ms)
    pv = Ms.pv

    start = i+1
    stop = i
    (i <  n - 1 || i >= N) && return  DescendingChain(view(Ms.x, 1:0))
    while i < Δ
        i += 1
        if i <= N && (i <= n || pv[i-1-(n-1)] == :left)
            stop = i
        else
            break
        end
    end
    DescendingChain(view(Ms.x, (start-n+1):(stop-n+1)))

end

##################################################

## Various "passthrough" functions
## we have passthrough!(A,B) mutates A,B to return AB = BA
## If A or B is immutatble, return new one
# do not assume DescendingChain is 1 ... n
# left to  right; return U
function passthrough!(A::DescendingChain, U::AbstractRotator)
    i = idx(U)
    n = idx(A.x[1])
    N = idx(A.x[end])
    #@assert n <= i < N
    l = (i-n) + 1
    U, A[l], A[l+1] = turnover(A[l], A[l+1], U)
    U
end

function passthrough!(A::AscendingChain, U::AbstractRotator)
    i = idx(U)
    n = idx(A.x[end])
    N = idx(A.x[1])
    #@assert n < i <= N
    l = length(A.x)  - (i-n)
    U, A[l], A[l+1] = turnover(A[l], A[l+1], U)
    U

end

## right to left; return U
function passthrough!(U::AbstractRotator, A::DescendingChain)
    i = idx(U)
    n = idx(A.x[1])
    N = idx(A.x[end])
    #@assert n < i <= N
    l = (i-n) + 1
    A[l-1], A[l], U = turnover(U, A[l-1], A[l])
    U
end

function passthrough!(U::AbstractRotator, A::AscendingChain)
    i = idx(U)
    isempty(A.x) && return U
    n, N = extrema(A)
    #@assert n <= i < N
    l = length(A.x)  - (i-n)
    A[l-1], A[l], U = turnover(U, A[l-1], A[l])
    U
end

# Need to check  bounds to ensure possible
function passthrough!(A::DescendingChain, B::AscendingChain)
    m, M = extrema(A)
    n, N = extrema(B)
    if n >= m && N < M
        for (i, U) in enumerate(B.x)
            B[i] = passthrough!(A, U)
        end
    else
        lA = length(A.x)
        for i in 1:lA
            j = lA + 1 - i
            A[j] = passthrough!(A[j], B)
        end
    end
    return nothing
end

function passthrough!(A::AscendingChain, B::DescendingChain)
    m, M = idx(A.x[end]), idx(A.x[1])
    n, N = idx(B.x[1]), idx(B.x[end])

    if m+1 <= n && M >= N
        for (i, U) in enumerate(B.x)
            B[i] = passthrough!(A, U)
        end
    else
        lA = length(A.x)
        for i in 1:lA
            j = lA - i + 1

            A[j] = passthrough!(A[j], B)
        end
    end
    return nothing
end

## Pass a diagonal rotator through a chain
## [  D --> D [
##  [           [
## function passthrough(A::DescendingChain, D::DiagonalRotator, ::Val{:right})
##     XXX
## end

##  [ D --> D   [
## [          [
## function passthrough(A::AscendingChain, D::DiagonalRotator, ::Val{:right})
##     ## XXX write me, but not needed...
## end

## Pass chain (Des, Asc, Twisted) through a chain (Des, Asc)
## Move twisted through down R <- L
## Pass chain (Des, Asc, Twisted) through a chain (Des, Asc)
## Move twisted through down R <- L
function passthrough!(A::DescendingChain, B::TwistedChain)
    length(B) == 0 && return nothing
    n,N = extrema(A)
    m,M = extrema(B)
    #@assert (m >= n && M < N)
    for i in iterate_rl(B.pv)
        B.x[i] = passthrough!(A, B.x[i])
    end
end

function passthrough!(A::AscendingChain, B::TwistedChain)
    length(B) == 0 && return nothing
    n,N = extrema(A)
    m,M = extrema(B)
    #@assert (m > n && M <= N)
    for i in iterate_rl(B.pv)
        B.x[i] = passthrough!(A, B.x[i])
    end
end

function passthrough!(B::TwistedChain, A::DescendingChain)
    length(B) == 0 && return nothing
    n,N = extrema(A)
    m,M = extrema(B)
    #@assert (m > n && M <= N)
    for i in iterate_lr(B.pv)
        B.x[i] = passthrough!(B.x[i], A)
    end
end

function passthrough!(B::TwistedChain, A::AscendingChain)
    length(B) == 0 && return nothing
    n,N = extrema(A)
    m,M = extrema(B)
    #@assert (m >= n && M < N)
    for i in iterate_lr(B.pv)
        B.x[i] = passthrough!(B.x[i], A)
    end
end


text:
export
    DLADescr,
    DSKDescr,
    EKAttDsc,
    EKSegSum,
    Ellipse,
    center,
    semi_major,
    semi_minor,
    Plane

struct Ellipse
    center::NTuple{3, SpiceDouble}
    semi_major::NTuple{3, SpiceDouble}
    semi_minor::NTuple{3, SpiceDouble}
end

center(e::Ellipse) = collect(e.center)
semi_major(e::Ellipse) = collect(e.semi_major)
semi_minor(e::Ellipse) = collect(e.semi_minor)

struct Plane
    normal::NTuple{3, SpiceDouble}
    constant::SpiceDouble
end

normal(p::Plane) = collect(p.normal)
constant(p::Plane) = p.constant

struct DLADescr
    bwdptr::SpiceInt
    fwdptr::SpiceInt
    ibase::SpiceInt
    isize::SpiceInt
    dbase::SpiceInt
    dsize::SpiceInt
    cbase::SpiceInt
    csize::SpiceInt
end

struct DSKDescr
    surfce::SpiceInt
    center::SpiceInt
    dclass::SpiceInt
    dtype::SpiceInt
    frmcde::SpiceInt
    corsys::SpiceInt
    corpar::NTuple{10, SpiceDouble}
    co1min::SpiceDouble
    co1max::SpiceDouble
    co2min::SpiceDouble
    co2max::SpiceDouble
    co3min::SpiceDouble
    co3max::SpiceDouble
    start::SpiceDouble
    stop::SpiceDouble
end

struct EKAttDsc
    cclass::SpiceInt
    dtype::SpiceInt
    strlen::SpiceInt
    size::SpiceInt
    indexd::SpiceInt
    nullok::SpiceInt
end

struct EKSegSum
    tabnam::NTuple{65, SpiceChar}
    nrows::SpiceInt
    ncols::SpiceInt
    cnames::NTuple{100*33, SpiceChar}
    cdescrs::NTuple{100, EKAttDsc}
end

tabnam(e::EKSegSum) = chararray_to_string(collect(e.tabnam))
cnames(e::EKSegSum) = chararray_to_string(reshape(collect(e.cnames), 33, 100))[1:e.ncols]

ext: jl


text:
#
# misc.jl --
#
# Implement XPA configuration methods and miscellaneous methods.
#
#------------------------------------------------------------------------------
#
# This file is part of XPA.jl released under the MIT "expat" license.
# Copyright (C) 2016-2020, Éric Thiébaut (https://github.com/JuliaAstro/XPA.jl).
#

#------------------------------------------------------------------------------
# CONFIGURATION METHODS

# The following default values are defined in "xpap.c" and can be changed by
# user environment variables.
const _DEFAULTS = Dict{String,Any}("XPA_MAXHOSTS" => 100,
                                   "XPA_SHORT_TIMEOUT" => 15,
                                   "XPA_LONG_TIMEOUT" => 180,
                                   "XPA_CONNECT_TIMEOUT" => 10,
                                   "XPA_TMPDIR" => "/tmp/.xpa",
                                   "XPA_VERBOSITY" => true,
                                   "XPA_IOCALLSXPA" => false)

"""
```julia
XPA.getconfig(key) -> val
```

yields the value associated with configuration parameter `key` (a string or a
symbol).  The following parameters are available (see XPA doc. for more
information):

| Key Name                | Default Value |
|:----------------------- |:------------- |
| `"XPA_MAXHOSTS"`        | `100`         |
| `"XPA_SHORT_TIMEOUT"`   | `15`          |
| `"XPA_LONG_TIMEOUT"`    | `180`         |
| `"XPA_CONNECT_TIMEOUT"` | `10`          |
| `"XPA_TMPDIR"`          | `"/tmp/.xpa"` |
| `"XPA_VERBOSITY"`       | `true`        |
| `"XPA_IOCALLSXPA"`      | `false`       |

Also see [`XPA.setconfig!`](@ref).

"""
function getconfig(key::AbstractString)
    haskey(_DEFAULTS, key) || error("unknown XPA parameter \"$key\"")
    def = _DEFAULTS[key]
    if haskey(ENV, key)
        val = haskey(ENV, key)
        return (isa(def, Bool) ? (parse(Int, val) != 0) :
                isa(def, Integer) ? parse(Int, val) :
                isa(def, AbstractString) ? val :
                error("unexpected type $(typeof(def)) for default value of \"$key\""))
    else
        return def
    end
end

"""
```julia
XPA.setconfig!(key, val) -> oldval
```

set the value associated with configuration parameter `key` to be `val`.  The
previous value is returned.

Also see [`XPA.getconfig`](@ref).

"""
function setconfig!(key::AbstractString,
                    val::T) where {T<:Union{Integer,Bool,AbstractString}}
    global _DEFAULTS, ENV
    old = getconfig(key) # also check validity of key
    def = _DEFAULTS[key]
    if isa(def, Integer) && isa(val, Integer)
        ENV[key] = string(val)
    elseif isa(def, Bool) && isa(val, Bool)
        ENV[key] = (val ? "1" : "0")
    elseif isa(def, AbstractString) && isa(val, AbstractString)
        ENV[key] = val
    else
        error("invalid type for XPA parameter \"$key\"")
    end
    return old
end

getconfig(key::Symbol) = getconfig(string(key))
setconfig!(key::Symbol, val) = setconfig!(string(key), val)

#------------------------------------------------------------------------------
# PRIVATE METHODS

"""
Private methods:

```julia
_get_field(T, ptr, off, def)
```

and

```julia
_get_field(T, ptr, off1, off2, def)
```

retrieve a field of type `T` at offset `off` (in bytes) with respect to address
`ptr`.  If two offsets are given, the first one refers to a pointer with
respect to which the second is applied.  If `ptr` is NULL, `def` is returned.

"""
_get_field(::Type{T}, ptr::Ptr{Cvoid}, off::UInt, def::T) where {T} =
    (ptr == C_NULL ? def : unsafe_load(convert(Ptr{T}, ptr + off)))

_get_field(::Type{String}, ptr::Ptr{Cvoid}, off::UInt, def::String) = begin
    ptr == C_NULL && return def
    buf = unsafe_load(convert(Ptr{Ptr{Byte}}, ptr + off))
    buf == C_NULL && return def
    return unsafe_string(buf)
end

function _get_field(::Type{T}, ptr::Ptr{Cvoid}, off1::UInt, off2::UInt,
                    def::T) where {T}
    _get_field(T, _get_field(Ptr{Cvoid}, ptr, off1, C_NULL), off2, def)
end

function _set_field(::Type{T}, ptr::Ptr{Cvoid}, off::UInt, val) where {T}
    @assert ptr != C_NULL
    unsafe_store!(convert(Ptr{T}, ptr + off), val)
end

let T = CDefs.XPARec, off = fieldoffset(T, Base.fieldindex(T, :comm, true))
    @eval _get_comm(conn::Handle) =
        _get_field(Ptr{Cvoid}, conn.ptr, $off, C_NULL)
end

for (func, memb, defval) in ((:get_name,      :name,         ""),
                             (:get_class,     :xclass,       ""),
                             (:get_send_mode, :send_mode,    0),
                             (:get_recv_mode, :receive_mode, 0),
                             (:get_method,    :method,       ""),
                             (:get_sendian,   :sendian,      "?"))
    T = CDefs.XPARec
    idx = Base.fieldindex(T, memb, true)
    off = fieldoffset(T, idx)
    if isa(defval, String)
        @assert fieldtype(T, idx) === Ptr{UInt8}
        typ = String
        def = defval
    else
        typ = fieldtype(T, idx)
        def = convert(typ, defval)
    end
    @eval $func(conn::Handle) = _get_field($typ, conn.ptr, $off, $def)
end

for (func, memb, defval) in ((:get_comm_status,  :status,   0),
                             (:get_comm_cmdfd,   :cmdfd,   -1),
                             (:get_comm_datafd,  :datafd,  -1),
                             (:get_comm_ack,     :ack,      1),
                             (:get_comm_cendian, :cendian, "?"),
                             (:get_comm_buf,     :buf,     NULL),
                             (:get_comm_len,     :len,      0))
    T = CDefs.XPACommRec
    idx = Base.fieldindex(T, memb, true)
    off = fieldoffset(T, idx)
    if isa(defval, String)
        @assert fieldtype(T, idx) === Ptr{UInt8}
        typ = String
        def = defval
    else
        typ = fieldtype(T, idx)
        def = convert(typ, defval)
    end
    @eval $func(conn::Handle) = _get_field($typ, _get_comm(conn), $off, $def)
    if memb == :buf || memb == :len
        @eval $(Symbol(:_set_comm_, memb))(conn::Handle, val) =
            unsafe_store!(convert(Ptr{$typ}, _get_comm(conn) + $off), val)
    end
end

"""
```julia
_malloc(len)
```

dynamically allocates `len` bytes and returns the corresponding byte pointer
(type `Ptr{UInt8}`).

"""
function _malloc(len::Integer) :: Ptr{Byte}
    ptr = ccall(:malloc, Ptr{Byte}, (Csize_t,), len)
    ptr != NULL || throw(OutOfMemoryError())
    return ptr
end

"""
```julia
_free(ptr)
```

frees dynamically allocated memory at address givne by `ptr` unless it is NULL.

"""
_free(ptr::Ptr{T}) where T =
    (ptr == Ptr{T}(0) || ccall(:free, Cvoid, (Ptr{T},), ptr))

"""
```julia
_memcpy!(dst, src, len) -> dst
```

copies `len` bytes from address `src` to destination `dst`.

"""
function _memcpy!(dst::Ptr, src::Ptr, len::Integer)
    if len > 0
        ccall(:memcpy, Ptr{Cvoid}, (Ptr{Cvoid}, Ptr{Cvoid}, Csize_t),
              dst, src, len)
    end
    return dst
end

function _memcpy!(dst::AbstractArray, src::Ptr, len::Integer)
    len == sizeof(dst) || error("bad number of bytes to copy")
    if len > 0
        ccall(:memcpy, Ptr{Cvoid}, (Ptr{Cvoid}, Ptr{Cvoid}, Csize_t),
              dst, src, len)
    end
    return dst
end


text:
using FantasyFootball
using Clustering
using DataFrames, DataFramesMeta
using Gadfly, Immerse

const BASE_DIR = dirname(@__FILE__)

function replacena!(df::AbstractDataFrame, replacement::Any)
    nrows, ncols = size(df)
    for j = 1:ncols
        for i = 1:nrows
            if isna(df[i, j])
                df[i, j] = replacement
            end
        end
    end
    df
end

# Get a DataFrame describing the aggregate of year, week, and kind.
function gettable(year::Int, week = 0, kind = "REG")
    dir = joinpath(BASE_DIR, "..", "data", "nflgame")
    # Construct the path for the table
    filename = "$(year)-season"
    if week > 0
        wk = ""
        if week < 10
            wk = "0"
        end
        wk *= string(week)
        filename *= "-week" * wk
    end
    filename *= "-" * lowercase(kind)
    filename *= ".csv"
    readtable(joinpath(dir, filename))
end

# Extract players matching the given position from a DataFrame
function getpos(table::AbstractDataFrame, pos::String)
    @where(@where(table, !isna(:pos)), :pos .== pos)
end

qb_stats = [
    :name,
    :team,
    :passing_att,
    :passing_cmp,
    # :passing_cmp_air_yds,
    # :passing_incmp,
    # :passing_incmp_air_yds,
    :passing_int,
    # :passing_sk,
    # :passing_sk_yds,
    :passing_tds,
    # :passing_twopta,
    # :passing_twoptm,
    # :passing_twoptmissed,
    :passing_yds,
    # :penalty,
    # :penalty_yds,
    :rushing_att,
    # :rushing_lng,
    :rushing_tds,
    # :rushing_twopta,
    # :rushing_twoptm,
    # :rushing_twoptmissed,
    :rushing_yds
]

function getqbs(year, week = 0; nona = false, attempts = 0)
    qbs = getpos(gettable(year, week), "QB")[:, qb_stats]

    if attempts > 0
        qbs = @where(
            @where(qbs, !isna(:passing_att)),
            :passing_att .>= attempts
        )
    end

    if nona
        replacena!(qbs, 0)
    end

    qbs
end

function qbstats(year, week = 0; k = 2, attempts = 0, nona = false)
    qbs = getqbs(year, week; attempts = attempts, nona = nona)
    # TODO replace NA with 0?
    cqbs = qbs[complete_cases(qbs), :]
    dqbs = @transform(cqbs,
            rush_rat = :passing_att ./ :rushing_att,
            pass_ypa = :passing_yds ./ :passing_att,
            rush_ypa = :rushing_yds ./ :rushing_att,
            pass_acc = :passing_cmp ./ :passing_att,
            pass_int_acc = :passing_int ./ :passing_att,
            td_prod = (:passing_tds + :rushing_tds) ./ (:passing_att + :rushing_att)
        )
    mtx = transpose(convert(Matrix{Float64}, dqbs[:, 3:end]))
    cluster = kmeans(mtx, k)
    # NB use string for cluster ID to get ordinal cluster scale from Gadfly
    @transform(dqbs, kcluster = ["k$(c)" for c in cluster.assignments])
end

function _join_weeks(year::Int, pull_week::Function)
    vcat([
        @transform(
            pull_week(year, wk),
            week="week$(wk)"
        ) for wk in 1:17
    ]...)
end

function _pull_qb_week(year::Int, week::Int)
    qbstats(year, week; nona=true, attempts=0)
end

function allqbwks(year::Int)
    _join_weeks(year, _pull_qb_week)
end

wr_stats = [
    :name,
    :team,
    # :receiving_lng,
    # :receiving_lngtd,
    :receiving_rec,
    :receiving_tar,
    :receiving_tds,
    # :receiving_twopta,
    # :receiving_twoptm,
    # :receiving_twoptmissed,
    :receiving_yac_yds,
    :receiving_yds
]

function getwrs(year, week = 0; targets = 0, nona = false)
    wrs = getpos(gettable(year, week), "WR")[:, wr_stats]

    if targets > 0
        wrs = @where(
            @where(wrs, !isna(:receiving_tar)),
            :receiving_tar .>= targets
        )
    end

    if nona
        replacena!(wrs, 0)
    end

    wrs
end

function _pull_wr_week(year::Int, week::Int)
    wrstats(year, week; nona=true, targets=0)
end

function allwrwks(year::Int)
    _join_weeks(year, _pull_wr_week)
end

function wrstats(year, week = 0; k = 2, targets = 0, nona = false)
    wrs = getwrs(year, week; targets = targets, nona = nona)
    cwrs = wrs[complete_cases(wrs), :]
    dwrs = @transform(cwrs,
        td_p_tar = :receiving_tds ./ :receiving_tar,
        yd_p_tar = :receiving_yds ./ :receiving_tar
    )
    mtx = transpose(convert(Matrix{Float64}, dwrs[:, 3:end]))
    cluster = kmeans(mtx, k)
    @transform(dwrs, kcluster = ["k$(c)" for c in cluster.assignments])
end

max_stars_repo_name: jnu/FantasyFootball

max_issues_repo_name: jnu/FantasyFootball

max_forks_repo_name: jnu/FantasyFootball


text:
module CameraTargetCrossfadeTriggerModule

using ..Ahorn, Maple

@mapdef Trigger "HonlyHelper/CameraTargetCrossfadeTrigger" CameraTargetCrossfadeTrigger(x::Integer, y::Integer, width::Integer=Maple.defaultTriggerWidth, height::Integer=Maple.defaultTriggerHeight, lerpStrengthA::Number=0.0, lerpStrengthB::Number=0.0, positionMode::String="NoEffect", xOnly::Bool=false, yOnly::Bool=false, deleteFlag::String="", nodes::Array{Tuple{Integer, Integer}, 1}=Tuple{Integer, Integer}[])

const placements = Ahorn.PlacementDict(
    "Camera Target Crossfade (HonlyHelper)" => Ahorn.EntityPlacement(
        CameraTargetCrossfadeTrigger,
        "rectangle",
        Dict{String, Any}(),
        function(trigger)
            trigger.data["nodes"] = [(Int(trigger.data["x"]) + Int(trigger.data["width"]) + 8, Int(trigger.data["y"])), (Int(trigger.data["x"]) + Int(trigger.data["width"]) + 8, Int(trigger.data["y"]) + 8)]
        end
    )
)

Ahorn.editingOptions(trigger::CameraTargetCrossfadeTrigger) = Dict{String, Any}(
        "positionMode" => Maple.trigger_position_modes
    )

function Ahorn.nodeLimits(trigger::CameraTargetCrossfadeTrigger)
    return 2, 2
end

end

max_stars_repo_name: HollyMagala/HonlyHelper

max_issues_repo_name: HollyMagala/HonlyHelper

max_forks_repo_name: HollyMagala/HonlyHelper


text:
using Random
abstract type DataSet end

export DataSet
export DataLoader

"""
    DataLoader(dataset::T;
               batchsize=1,
               shuffle=true,
               droplast=true,
               collatefn::Union{Function,Nothing}=nothing) where {T<:DataSet}

Suppose each element of the dataset returns a tuple sample (feat, label), everytime the DataLoader instance
fetchs a minibatch of data from a dataset and collates them into a batched sample (feats, labels).
"""
mutable struct DataLoader{T}
    data::T
    batchsize::Int
    batchnums::Int
    droplast::Bool
    shuffle::Bool
    imax::Int
    len::Int
    indices::Vector{Int}
    collate::Union{Function,Nothing}

    function DataLoader(dataset::T;
                        batchsize=1,
                        shuffle=true,
                        droplast=true,
                        collatefn::Union{Function,Nothing}=nothing) where {T<:DataSet}
        if batchsize <= 0
            throw(ArgumentError("batchsize should be positive, but got $batchsize"))
        end
        n = length(dataset)
        if n < batchsize
            @warn "# observations < batchsize, decreasing batchsize to $n"
            batchsize = n
        end
        rest = mod(n, batchsize)
        imax = (droplast && rest!=0) ? (n - rest) : n
        batchnums = ceil(Int, imax / batchsize)
        new{T}(dataset, batchsize, batchnums, droplast, shuffle, imax, n, 1:n, collatefn)
    end
end

function Base.iterate(d::DataLoader, i=0)
    i >= d.imax && return nothing
    if d.shuffle && i == 0
        shuffle!(d.indices)
    end
    next  = min(i + d.batchsize, d.len)
    idxs  = d.indices[i+1 : next]
    batch = [d.data[k] for k in idxs]

    if d.collate ≠ nothing
        return (d.collate(batch), next)
    else
        return (batch, next)
    end
end

function Base.length(d::DataLoader)
    n = d.len / d.batchsize
    d.droplast ? floor(Int, n) : ceil(Int, n)
end

function Base.getindex(d::DataLoader, k::Int)
    k > d.batchnums && return nothing
    if d.shuffle && k == 1
        shuffle!(d.indices)
    end
    start = 1 + (k-1)*d.batchsize
    final = min(k*d.batchsize, d.len)
    batch = [d.data[i] for i in d.indices[start:final]]
    if d.collate ≠ nothing
        return d.collate(batch)
    else
        return batch
    end
end

# pretty printing
function Base.show(io::IO, d::DataLoader{T}) where T
    println("DataLoader{$T}")
    println("————————————————————————")
    println("     data →  $T")
    println("batchsize →  $(d.batchsize)")
    println("batchnums →  $(d.batchnums)")
    println(" droplast →  $(d.droplast)")
    println("  shuffle →  $(d.shuffle)")
    println("     imax →  $(d.imax)")
    println("      len →  $(d.len)")
    println("  indices →  $(d.indices[1]):$(d.indices[2]-d.indices[1]):$(d.indices[end])")
    println("  collate →  $(d.collate)")
    print("————————————————————————")
end

max_stars_repo_name: sonosole/Delta

max_issues_repo_name: sonosole/Delta

max_forks_repo_name: sonosole/Delta


text:
module SwapBlock

using ..Ahorn, Maple

function swapFinalizer(entity)
    x, y = Ahorn.position(entity)

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

    entity.data["nodes"] = [(x + width, y)]
end

const placements = Ahorn.PlacementDict(
    "Swap Block ($(uppercasefirst(theme)))" => Ahorn.EntityPlacement(
        Maple.SwapBlock,
        "rectangle",
        Dict{String, Any}(
            "theme" => theme
        ),
        swapFinalizer
    ) for theme in Maple.swap_block_themes
)

Ahorn.editingOptions(entity::Maple.SwapBlock) = Dict{String, Any}(
    "theme" => Maple.swap_block_themes
)

Ahorn.nodeLimits(entity::Maple.SwapBlock) = 1, 1

Ahorn.minimumSize(entity::Maple.SwapBlock) = 16, 16
Ahorn.resizable(entity::Maple.SwapBlock) = true, true

function Ahorn.selection(entity::Maple.SwapBlock)
    x, y = Ahorn.position(entity)
    stopX, stopY = Int.(entity.data["nodes"][1])

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

    return [Ahorn.Rectangle(x, y, width, height), Ahorn.Rectangle(stopX, stopY, width, height)]
end

function getTextures(entity::Maple.SwapBlock)
    theme = lowercase(get(entity, "theme", "normal"))

    if theme == "moon"
        return "objects/swapblock/moon/blockRed", "objects/swapblock/moon/target", "objects/swapblock/moon/midBlockRed00"
    end

    return "objects/swapblock/blockRed", "objects/swapblock/target", "objects/swapblock/midBlockRed00"
end

function renderTrail(ctx, x::Number, y::Number, width::Number, height::Number, trail::String)
    tilesWidth = div(width, 8)
    tilesHeight = div(height, 8)

    for i in 2:tilesWidth - 1
        Ahorn.drawImage(ctx, trail, x + (i - 1) * 8, y + 2, 6, 0, 8, 6)
        Ahorn.drawImage(ctx, trail, x + (i - 1) * 8, y + height - 8, 6, 14, 8, 6)
    end

    for i in 2:tilesHeight - 1
        Ahorn.drawImage(ctx, trail, x + 2, y + (i - 1) * 8, 0, 6, 6, 8)
        Ahorn.drawImage(ctx, trail, x + width - 8, y + (i - 1) * 8, 14, 6, 6, 8)
    end

    for i in 2:tilesWidth - 1, j in 2:tilesHeight - 1
        Ahorn.drawImage(ctx, trail, x + (i - 1) * 8, y + (j - 1) * 8, 6, 6, 8, 8)
    end

    Ahorn.drawImage(ctx, trail, x + width - 8, y + 2, 14, 0, 6, 6)
    Ahorn.drawImage(ctx, trail, x + width - 8, y + height - 8, 14, 14, 6, 6)
    Ahorn.drawImage(ctx, trail, x + 2, y + 2, 0, 0, 6, 6)
    Ahorn.drawImage(ctx, trail, x + 2, y + height - 8, 0, 14, 6, 6)
end

function renderSwapBlock(ctx::Ahorn.Cairo.CairoContext, x::Number, y::Number, width::Number, height::Number, midResource::String, frame::String)
    midSprite = Ahorn.getSprite(midResource, "Gameplay")

    tilesWidth = div(width, 8)
    tilesHeight = div(height, 8)

    for i in 2:tilesWidth - 1
        Ahorn.drawImage(ctx, frame, x + (i - 1) * 8, y, 8, 0, 8, 8)
        Ahorn.drawImage(ctx, frame, x + (i - 1) * 8, y + height - 8, 8, 16, 8, 8)
    end

    for i in 2:tilesHeight - 1
        Ahorn.drawImage(ctx, frame, x, y + (i - 1) * 8, 0, 8, 8, 8)
        Ahorn.drawImage(ctx, frame, x + width - 8, y + (i - 1) * 8, 16, 8, 8, 8)
    end

    for i in 2:tilesWidth - 1, j in 2:tilesHeight - 1
        Ahorn.drawImage(ctx, frame, x + (i - 1) * 8, y + (j - 1) * 8, 8, 8, 8, 8)
    end

    Ahorn.drawImage(ctx, frame, x, y, 0, 0, 8, 8)
    Ahorn.drawImage(ctx, frame, x + width - 8, y, 16, 0, 8, 8)
    Ahorn.drawImage(ctx, frame, x, y + height - 8, 0, 16, 8, 8)
    Ahorn.drawImage(ctx, frame, x + width - 8, y + height - 8, 16, 16, 8, 8)

    Ahorn.drawImage(ctx, midSprite, x + div(width - midSprite.width, 2), y + div(height - midSprite.height, 2))
end

function Ahorn.renderSelectedAbs(ctx::Ahorn.Cairo.CairoContext, entity::Maple.SwapBlock, room::Maple.Room)
    sprite = get(entity.data, "sprite", "block")
    startX, startY = Int(entity.data["x"]), Int(entity.data["y"])
    stopX, stopY = Int.(entity.data["nodes"][1])

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

    frame, trail, mid = getTextures(entity)

    renderSwapBlock(ctx, stopX, stopY, width, height, mid, frame)
    Ahorn.drawArrow(ctx, startX + width / 2, startY + height / 2, stopX + width / 2, stopY + height / 2, Ahorn.colors.selection_selected_fc, headLength=6)
end

function Ahorn.renderAbs(ctx::Ahorn.Cairo.CairoContext, entity::Maple.SwapBlock, room::Maple.Room)
    sprite = get(entity.data, "sprite", "block")

    startX, startY = Int(entity.data["x"]), Int(entity.data["y"])
    stopX, stopY = Int.(entity.data["nodes"][1])

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

    frame, trail, mid = getTextures(entity)

    renderTrail(ctx, min(startX, stopX), min(startY, stopY), abs(startX - stopX) + width, abs(startY - stopY) + height, trail)
    renderSwapBlock(ctx, startX, startY, width, height, mid, frame)
end

end


text:
using FunctionOperators, LinearAlgebra, Test

@testset "Functionality test" begin
    Op₁ = FunctionOperator{Float64}("Op₁",
        x -> x .^ 3, x -> cbrt.(x), (10,10), (10,10))
    Op₂ = FunctionOperator{Float64}("Op₂",
        x -> x .+ 2, x -> x .- 2, (10,10), (10,10))
    bOp₁ = FunctionOperator{Float64}("bOp₁",
        (b,x) -> b.=x.^3, (b,x) -> b.=cbrt.(x), (10,10), (10,10))
    bOp₂ = FunctionOperator{Float64}("bOp₂",
        (b,x) -> b.=x.+2, (b,x) -> b.=x.-2, (10,10), (10,10))
    w = reshape([1 2 3 4 5], 1, 1, 5)
    Op₃ = FunctionOperator{Float64}("Op₃",
        x -> x .* w, x -> x[:,:,1], (10,10), (10,10,5))
    Op₄ = FunctionOperator{Float64}("Op₄",
        x -> repeat(x, outer=(1,1,5)), x -> x[:,:,5], (10,10), (10, 10, 5))
    bOp₃ = FunctionOperator{Float64}("bOp₃",
        (b,x) -> broadcast!(*, b, reshape(x, 10, 10, 1), w), (b,x) -> b .= x[:,:,1], (10,10), (10,10,5))
    bOp₄ = FunctionOperator{Float64}("bOp₄",
        (b,x) -> b.=repeat(x, outer=(1,1,5)), (b,x) -> b .= x[:,:,5], (10,10), (10, 10, 5))
    Op₅ = FunctionOperator{Float64}("Op₅",
        x -> -x .^ 3, x -> -cbrt.(x), (10,10,5), (10,10,5))
    Op₆ = FunctionOperator{Float64}("Op₆",
        x -> x .+ 5, x -> x .- 5, (10,10,5), (10,10,5))
    bOp₅ = FunctionOperator{Float64}("bOp₅",
        (b,x) -> b.=-x.^3, (b,x) -> b.=-cbrt.(x), (10,10,5), (10,10,5))
    bOp₆ = FunctionOperator{Float64}("bOp₆",
        (b,x) -> b.=x.+5, (b,x) -> b.=x.-5, (10,10,5), (10,10,5))
    data₁ = [sin(i+j) for i=1:10, j=1:10]
    data₂ = [sin(i+j+k) for i=1:10, j=1:10, k=1:5]
    function manual_tests()
        @test Op₁ * (ones(10,10)*2) == ones(10,10)*8
        @test Op₁' * (ones(10,10)*8) == ones(10,10)*2
        @test Op₁ * I * (ones(10,10)*2) == ones(10,10)*8
        @test Op₁' * I * (ones(10,10)*8) == ones(10,10)*2
        @test I * Op₁ * (ones(10,10)*2) == ones(10,10)*8
        @test I * Op₁' * (ones(10,10)*8) == ones(10,10)*2
        @test Op₁ * 2 * (ones(10,10)*2) == ones(10,10)*64
        @test Op₁' * 2 * (ones(10,10)*4) == ones(10,10)*2
        @test 2 * Op₁ * (ones(10,10)*2) == ones(10,10)*16
        @test 2 * Op₁' * (ones(10,10)*8) == ones(10,10)*4
        @test Op₃ * Op₁ * (ones(10,10)*2) == ones(10,10)*8 .* w
        @test (Op₃ * Op₁)' * (ones(10,10)*8 .* w) == Op₁' * Op₃' * (ones(10,10)*8 .* w)
        @test (Op₃ * Op₁)' * (ones(10,10)*8 .* w) == ones(10,10)*2
        @test (Op₃ + Op₄) * (ones(10,10)*2) == Op₃ * (ones(10,10)*2) + Op₄ * (ones(10,10)*2)
        @test (Op₃ - Op₄) * (ones(10,10)*2) == Op₃ * (ones(10,10)*2) - Op₄ * (ones(10,10)*2)
        @test 3I * Op₃ * (ones(10,10)*2) == (ones(10,10)*2 .* w) * 3
        @test Op₃ * 3I * (ones(10,10)*2) == ones(10,10)*6 .* w
        @test (Op₃ * 3I)' * (ones(10,10)*2 .* w) == ones(10,10)*6
        @test (Op₅ + 3I) * (ones(10,10,5)*2) == Op₅ * (ones(10,10,5)*2) + (ones(10,10,5)*6)
        @test (Op₅ - 3I) * (ones(10,10,5)*2) == Op₅ * (ones(10,10,5)*2) - (ones(10,10,5)*6)
        @test (3I + Op₅) * (ones(10,10,5)*2) == (ones(10,10,5)*6) + Op₅ * (ones(10,10,5)*2)
        @test (3I - Op₅) * (ones(10,10,5)*2) == (ones(10,10,5)*6) - Op₅ * (ones(10,10,5)*2)
        output = zeros(10, 10)
        @test Op₁ * (ones(10,10)*2) == mul!(output, Op₁, ones(10,10)*2)
        @test Op₁' * (ones(10,10)*2) == mul!(output, Op₁', ones(10,10)*2)
        @test Op₁ * bOp₂ * (ones(10,10)*2) == mul!(output, Op₁ * bOp₂, ones(10,10)*2)
        @test (Op₁ * bOp₂)' * (ones(10,10)*2) == mul!(output, (Op₁ * bOp₂)', ones(10,10)*2)
        combined = bOp₁ * Op₂
        @test mul!(output, combined, ones(10,10)*2) == mul!(output, combined, ones(10,10)*2)
        combined = (bOp₁ * Op₂)'
        @test mul!(output, combined, ones(10,10)*2) == mul!(output, combined, ones(10,10)*2)
        @test (Op₃ - Op₄) * I * (ones(10,10)*2) == Op₃ * (ones(10,10)*2) - Op₄ * (ones(10,10)*2)
        @test I * (Op₃ - Op₄) * (ones(10,10)*2) == Op₃ * (ones(10,10)*2) - Op₄ * (ones(10,10)*2)
    end
    @testset "Fidelity (manually checked)" begin
        @testset "Without automatic reshape" begin
            manual_tests()
        end
        @testset "With automatic reshape" begin
            FunctionOperators_global_settings.auto_reshape = true
            manual_tests()
            FunctionOperators_global_settings.auto_reshape = false
        end
    end
    @testset "Just for coverage" begin
        combined = Op₁ + Op₂
        combined.operator = :%
        @test_throws ErrorException combined * data₁
    end
    @testset "Adjoint of addition/substraction" begin
        @test_throws ErrorException (Op₃ + Op₄)' * ones(10,10,5)
        @test_throws ErrorException (Op₃ - Op₄)' * ones(10,10,5)
    end
    @testset "Automated" begin
        @testset "Combine" begin
            function combineMul(item1, item2)
                if item1.op.inDims ≠ item2.op.outDims
                    @test_throws DimensionMismatch item1.op * item2.op
                    missing
                else
                    (op = item1.op * item2.op,
                    forw = x -> (x₁ = item2.op * x; item1.op * x₁),
                    backw = x -> (x₁ = item1.op' * x; item2.op' * x₁),
                    hasAddOrSub = item1.hasAddOrSub || item2.hasAddOrSub)
                end
            end
            function combineMulScalingRight(item1)
                (op = item1.op * 5I,
                forw = x -> (x₁ = 5 * x; item1.op * x₁),
                backw = x -> (x₁ = item1.op' * x; 5 * x₁),
                hasAddOrSub = item1.hasAddOrSub)
            end
            function combineMulScalingLeft(item1)
                (op = 4I * item1.op,
                forw = x -> (x₁ = item1.op * x; 4 * x₁),
                backw = x -> (x₁ = 4 * x; item1.op' * x₁),
                hasAddOrSub = item1.hasAddOrSub)
            end
            function combineAdd(item1, item2)
                if item1.op.inDims ≠ item2.op.inDims || item1.op.outDims ≠ item2.op.outDims
                    @test_throws DimensionMismatch item1.op + item2.op
                    missing
                else
                    (op = item1.op + item2.op,
                    forw = x -> (x₁ = item1.op * x; x₂ = item2.op * x; x₁ + x₂),
                    backw = x -> throw(AssertionError("This should not be invoked")),
                    hasAddOrSub = true)
                end
            end
            function combineAddScalingRight(item1)
                if item1.op.inDims ≠ item1.op.outDims
                    @test_throws DimensionMismatch item1.op + 6I
                    missing
                else
                    (op = item1.op + 6I,
                    forw = x -> (x₁ = item1.op * x; x₂ = 6 * x; x₁ + x₂),
                    backw = x -> throw(AssertionError("This should not be invoked")),
                    hasAddOrSub = true)
                end
            end
            function combineAddScalingLeft(item1)
                if item1.op.inDims ≠ item1.op.outDims
                    @test_throws DimensionMismatch 7I + item1.op
                    missing
                else
                    (op = 7I + item1.op,
                    forw = x -> (x₁ = 7 * x; x₂ = item1.op * x; x₁ + x₂),
                    backw = x -> throw(AssertionError("This should not be invoked")),
                    hasAddOrSub = true)
                end
            end
            function combineSub(item1, item2)
                if item1.op.inDims ≠ item2.op.inDims || item1.op.outDims ≠ item2.op.outDims
                    @test_throws DimensionMismatch item1.op - item2.op
                    missing
                else
                    (op = item1.op - item2.op,
                    forw = x -> (x₁ = item1.op * x; x₂ = item2.op * x; x₁ - x₂),
                    backw = x -> throw(AssertionError("This should not be invoked")),
                    hasAddOrSub = true)
                end
            end
            function combineSubScalingRight(item1)
                if item1.op.inDims ≠ item1.op.outDims
                    @test_throws DimensionMismatch item1.op - 3I
                    missing
                else
                    (op = item1.op - 3I,
                    forw = x -> (x₁ = item1.op * x; x₂ = 3 * x; x₁ - x₂),
                    backw = x -> throw(AssertionError("This should not be invoked")),
                    hasAddOrSub = true)
                end
            end
            function combineSubScalingLeft(item1)
                if item1.op.inDims ≠ item1.op.outDims
                    @test_throws DimensionMismatch 11I - item1.op
                    missing
                else
                    (op = 11I - item1.op,
                    forw = x -> (x₁ = 11 * x; x₂ = item1.op * x; x₁ - x₂),
                    backw = x -> throw(AssertionError("This should not be invoked")),
                    hasAddOrSub = true)
                end
            end
            function combineAdjoint(item1)
                if item1.hasAddOrSub
                    @test_throws ErrorException item1.op' * (item1.outDims == size(data₁) ? data₁ : data₂)
                    missing
                else
                    (op = item1.op',
                    forw = item1.backw,
                    backw = item1.forw,
                    hasAddOrSub = false)
                end
            end
            function allTypeOfCombinationOfOne(item1)
                [combineMulScalingRight(item1), combineMulScalingLeft(item1),
                 combineAddScalingRight(item1), combineAddScalingLeft(item1),
                 combineSubScalingRight(item1), combineSubScalingLeft(item1),
                 combineAdjoint(item1)]
            end
            function allTypeOfCombinationOfTwo(item1, item2)
                [combineMul(item1, item2), combineAdd(item1, item2), combineSub(item1, item2)]
            end
            function Cartesian_product_with_itself(list)
                new_list1 = [allTypeOfCombinationOfOne(item1) for item1 in list]
                new_list2 = [allTypeOfCombinationOfTwo(item1, item2)
                    for item1 in list, item2 in list]
                collect(skipmissing(vcat(list, new_list1..., new_list2...)))
            end
            Ops = [Op₁, bOp₁, Op₃, bOp₃, Op₅, bOp₅]
            global list
            list = [(op = op, forw = x -> op * x, backw = x -> op' * x, hasAddOrSub = false)
                for op in Ops]
            list = Cartesian_product_with_itself(list)
            # it would be nice to repeat this step, but it would be never completed...
            #list = Cartesian_product_with_itself(list)
            # instead:
            function combine_special_cases(list)
                new_list = []
                push!(new_list, [combineMul(item1, list[1]) for item1 in list]...)
                push!(new_list, [combineMul(list[1], item1) for item1 in list]...)
                push!(new_list, [combineMul(item1, list[2]) for item1 in list]...)
                push!(new_list, [combineMul(list[2], item1) for item1 in list]...)
                push!(new_list, [combineMul(item1, list[3]) for item1 in list]...)
                push!(new_list, [combineMul(list[3], item1) for item1 in list]...)
                push!(new_list, [combineMul(item1, list[4]) for item1 in list]...)
                push!(new_list, [combineMul(list[4], item1) for item1 in list]...)
                spec₁ = combineAdd(list[1], list[2])
                push!(new_list, [combineMul(item1, spec₁) for item1 in list]...)
                push!(new_list, [combineAdd(item1, spec₁) for item1 in list]...)
                push!(new_list, [combineMul(spec₁, item1) for item1 in list]...)
                spec₂ = combineAdd(list[2], list[1])
                push!(new_list, [combineMul(item1, spec₂) for item1 in list]...)
                push!(new_list, [combineSub(item1, spec₁) for item1 in list]...)
                push!(new_list, [combineMul(spec₂, item1) for item1 in list]...)
                list = collect(skipmissing(vcat(list, new_list...)))
                new_list = []
                push!(new_list, [combineAdjoint(item1) for item1 in list]...)
                collect(skipmissing(vcat(list, new_list...)))
            end
            list = combine_special_cases(list)
            println("Number of generated operators: ", length(list))
        end
        @testset "Fidelity" begin
            global list
            getName(op) = op isa FunctionOperator && op.adjoint ? op.name*"'" : op.name
            normName(str) = replace(FunctionOperators.normalizeExpression(getName(str)), "b" => "")
            results = [(name = getName(op.op),
                        normalized_name = normName(op.op),
                        mult_res = op.op * (op.op.inDims == size(data₁) ? data₁ : data₂),
                        forw_res = op.forw(op.op.inDims == size(data₁) ? data₁ : data₂),
                        plan = op.op isa FunctionOperator ? op.op.name : op.op.plan_string)
                            for op in list]
            for res in results
                res.mult_res ≠ res.forw_res && println(res.name, ", ", res.plan)
                @test res.mult_res == res.forw_res
            end
            counter = 0
            for (i,res1) in enumerate(results), (j,res2) in enumerate(results)
                i >= j && continue
                if res1.normalized_name == res2.normalized_name
                    counter += 1
                    res1.mult_res ≠ res2.mult_res && println(i, ", ", res1.name, ", ", res1.plan, "\n", j, res2.name, ", ", res2.plan)
                    @test res1.mult_res == res2.mult_res
                end
            end
            println("Pairwise matches between operators: ", counter, " (match means same functionality that checked for same result)")
        end
    end
end;


text:
### QuantumOscillator.jl
# Convenience functionality for handling finite-dimensional systems,
# specifically related to the (truncated) harmonic oscillator
###

"""
    osc(n::Int[, name="Osc(n)"::QName])

Create harmonic oscillator in Fock basis with `n` levels.

### Default ops for QFactor:
  - 'i' : identity operator
  - 'n' : number operator
  - 'd' : lowering operator
  - 'u' : raising operator
  - 'x' : in-phase quadrature
  - 'y' : out-of-phase quadrature

"""
function osc(levels::Int, name=""::QName)
    if name == ""
        name = "Osc($(levels))"
    end
    s = QFactor(levels, name)
    s.ops['d'] = sparse([x == y - 1 ? sqrt(QComp(x)) : QComp(0) for x=1:levels, y=1:levels])
    s.ops['u'] = s('d')'
    s.ops['n'] = let l=1:levels; sparse(l,l,map(QComp, 0:(levels - 1))) end
    s.ops['x'] = s('d') + s('u')
    s.ops['y'] = (s('d') - s('u')) .* im
    s
end

"""
    coherentvec(o::QObj, α::Number)::QKet

Create a coherent state ket vector with amplitude `α`.
"""
function coherentvec(o::QObj, α::Number)::QKet
  m = length(o)
  nbar = abs2(α)
  @assert (nbar + 3*sqrt(nbar) <= m) "Mean n of $nbar too large for max n of $m."
  e = exp(-nbar/2)
  cv = map(k -> QComp(e*α^k/sqrt(gamma(k+1))), 0:(m - 1))
  sparsevec(cv / norm(cv))
end

"""
    coherent(o::QObj, α::QComp)::QKet

Create a coherent state projection operator with amplitude `α`.
"""
coherent(o::QObj, α) = projector(coherentvec(o, α))


text:
function toInt(i::String)
    return parse(UInt64, i; base=2)
end

function pgn2uintGen()
    pgn =  Dict{String,UInt64}()
    uint = Dict{UInt64,String}()
    i = 0
    for rank in 8:-1:1
        for file in 1:8
            square = "0"^i * "1" * "0"^(63 - i)
            square_int = toInt(square)
            coord = string(Char(Int('a')+(file - 1)))*string(rank)
            push!(pgn, coord=>square_int)
            push!(uint, square_int=>coord)
            i += 1
        end
    end
    return pgn, uint
end
const PGN2UINT, UINT2PGN = pgn2uintGen()
const A1 = PGN2UINT["a1"]
const B1 = PGN2UINT["b1"]
const C1 = PGN2UINT["c1"]
const D1 = PGN2UINT["d1"]
const E1 = PGN2UINT["e1"]
const F1 = PGN2UINT["f1"]
const G1 = PGN2UINT["g1"]
const H1 = PGN2UINT["h1"]
const B1C1D1 = B1|C1|D1
const F1G1 = F1|G1
const A8 = PGN2UINT["a8"]
const B8 = PGN2UINT["b8"]
const C8 = PGN2UINT["c8"]
const D8 = PGN2UINT["d8"]
const E8 = PGN2UINT["e8"]
const F8 = PGN2UINT["f8"]
const G8 = PGN2UINT["g8"]
const H8 = PGN2UINT["h8"]
const B8C8D8 = B8|C8|D8
const F8G8 = F8|G8

function pgn2intGen()
    pgn = Dict{String,Int64}()
    int = Dict{Int64,String}()

    i = 1
    for rank in 8:-1:1
        for file in 1:8
            coord = string(Char(Int('a') + (file - 1)))*string(rank)
            push!(pgn, coord=>i)
            push!(int, i=>coord)
            i += 1
        end
    end
    return pgn, int
end
const PGN2INT, INT2PGN = pgn2intGen()

function int2uintGen()
    int = Dict{Int64,UInt64}()
    uint = Dict{UInt64,Int64}()

    for i = 1:64
        pgn = INT2PGN[i]
        pgnuint = PGN2UINT[pgn]
        push!(int, i=>pgnuint)
        push!(uint, pgnuint=>i)
    end
    return int, uint
end
const INT2UINT, UINT2INT = int2uintGen()


text:
using CSV, Clustering, Plots

DC_data = CSV.read("DC_Coordinates.csv", header=true)
DC_coordinates = (Matrix{Float64}(DC_data[:,1:2]))
DC_population = (Vector{Int64}(DC_data[:,3]))
num_DC = size(DC_data,1)

municipality_data = CSV.read("Municipality_Population_Coordinates.csv", header=true)
municipality_coordinates = (Matrix{Float64}(municipality_data[:,7:8]))
municipality_population = (Vector{Int64}(municipality_data[:,9]))

clustering_points = [DC_coordinates'  municipality_coordinates']
clustering_weights = [DC_population ; municipality_population]

result = kmeans(clustering_points, num_DC, init=[n for n=1:num_DC], weights=clustering_weights, display=:iter)

graph_points = DC_coordinates'
markers = [0 for n=1:num_DC]
c_population = []

for c =1:num_DC

    c_members = findall(g->g==c, result.assignments)

    tot_c=-100000000
    for m in c_members
        tot_c+=clustering_weights[m]
    end
        global c_population
        append!(c_population, tot_c)

    for n in 1:30
        i = rand(c_members)
        global graph_points = hcat(graph_points, clustering_points[:,i])
        append!(markers, result.assignments[i])
    end
end

DC_data.Poblacion = c_population
print(DC_data)
CSV.write("DC_Coordinates.csv", DC_data)

res = scatter(graph_points[1,:], graph_points[2,:], marker_z = markers,
        color=palette(:tab20), markersize=3, legend=false)

display(res)
a = assignments(result)
c = counts(result)
M = result.centers

max_stars_repo_name: valenmgama/optimization-tec

max_issues_repo_name: valenmgama/optimization-tec

max_forks_repo_name: valenmgama/optimization-tec


text:
#!/usr/bin/env julia

using LocalPackageServer
using LocalPackageServer: PkgStorageServer, GitStorageServer, Config

if isempty(ARGS)
    println("Usage: run_server.jl config.toml")
else
    LocalPackageServer.start(ARGS[1])
end


text:
# Example for building JOLI operator having functions
# defining action for forward and transpose mapping
#
# we will use plain matrix to fake the actions

using JOLI

# forward function
function fwd(A::AbstractMatrix,vin::AbstractVector,RDT::DataType)
    vout=A*vin
    return jo_convert(RDT,vout)
end

# transpose function
function fwdT(A::AbstractMatrix,vin::AbstractVector,RDT::DataType)
    vout=A.'*vin
    return jo_convert(RDT,vout)
end

# define matrix for mapping functions
a=rand(ComplexF32,3,3)

# define JOLI operator with desired domain and range using
# using joLinearFunctionFwdT constructor
# note forced dropping imaginary part for transpose/adjoint operators
A=joLinearFunctionFwdT(3,3,
    v->fwd(a,v,ComplexF64),v->fwdT(a,v,Float32),
    Float32,ComplexF64;name="my_A")
show(A)

# disable warining for implicit inacurate conversions - use only after debugging your code
jo_convert_warn_set(false)

# display elements of the operator
println("forward: A")
show(A); display(elements(A)); println()
println("transpose: A.'")
show(A.'); display(elements(A.')); println()
println("adjoint: A'")
show(A'); display(elements(A')); println()
println("conjugate: conj(A)")
show(conj(A)); display(elements(conj(A))); println()

# multiply by vector
x=rand(Float32,3)
y=A*x
println("y: ",y)
xx=A'*y
println("xx: ",xx)


text:
"""
    DVec{K,V,D<:AbstractDict{K,V},S}

Dictionary-based vector-like data structure for use with FCIQMC and
[KrylovKit](https://github.com/Jutho/KrylovKit.jl). While mostly behaving like a `Dict`, it
supports various linear algebra operations such as `norm` and `dot`. It has a
[`StochasticStyle`](@ref) that is used to select an appropriate spawning strategy in the
FCIQMC algorithm.

See also: [`AbstractDVec`](@ref).

## Constructors

* `DVec(dict::AbstractDict[; style, capacity])`: create a `DVec` with `dict` for storage.
  Note that the data may or may not be copied.

* `DVec(args...[; style, capacity])`: `args...` are passed to the `Dict` constructor. The
  `Dict` is used for storage.

* `DVec{K,V}([; style, capacity])`: create an empty `DVec{K,V}`.

* `DVec(dv::AbstractDVec[; style, capacity])`: create a `DVec` with the same contents as
   `adv`. The `style` is inherited from `dv` by default.

The default `style` is selected based on the `DVec`'s `valtype` (see
[`default_style`](@ref)). If a style is given and the `valtype` does not match the `style`'s
`eltype`, the values are converted to an appropriate type.

The capacity argument is optional and sets the initial size of the `DVec` via `sizehint!`.

## Examples

```jldoctest
julia> dv = DVec(:a => 1)
DVec{Symbol,Int64} with 1 entries, style = IsStochasticInteger{Int64}()
  :a => 1

julia> dv = DVec(:a => 2, :b => 3; style=IsDeterministic())
DVec{Symbol,Float64} with 2 entries, style = IsDeterministic{Float64}()
  :a => 2.0
  :b => 3.0
```
"""
struct DVec{K,V,S<:StochasticStyle{V},D<:AbstractDict{K,V}} <: AbstractDVec{K,V}
    storage::D
    style::S
end

###
### Constructors
###
# Vararg
function DVec(args...; kwargs...)
    storage = Dict(args...)
    return DVec(storage; kwargs...)
end
# In this constructor, the style matches the dict's valtype.
function DVec(
    dict::AbstractDict{K,V}; style::StochasticStyle{V}=default_style(V), capacity=0
) where {K,V}
    capacity > 0 && sizehint!(dict, capacity)
    return DVec(dict, style)
end
# In this constructor, the dict has to be converted to the appropriate valtype.
function DVec(
    dict::Dict{K}; style::StochasticStyle{V}=default_style(valtype(dict)), capacity=0
) where {K,V}
    storage = convert(Dict{K,V}, dict)
    return DVec(storage, style)
end
# Empty constructor.
function DVec{K,V}(; style::StochasticStyle=default_style(V), capacity=0) where {K,V}
    return DVec(Dict{K,V}(); style, capacity)
end
# From another DVec
function DVec(dv::AbstractDVec{K,V}, style=StochasticStyle(dv), capacity=0) where {K,V}
    dvec = DVec{K,V}(; style, capacity=max(capacity, length(dv)))
    return copyto!(dvec, dv)
end

function Base.empty(dvec::DVec{K,V}) where {K,V}
    return DVec{K,V}(; style=StochasticStyle(dvec))
end
function Base.empty(dvec::DVec{K}, ::Type{V}) where {K,V}
    return DVec{K,V}()
end
function Base.empty(dvec::DVec, ::Type{K}, ::Type{V}) where {K,V}
    return DVec{K,V}()
end

###
### Show
###
function Base.summary(io::IO, dvec::DVec{K,V,S}) where {K,V,S}
    len = length(dvec)
    print(io, "DVec{$K,$V} with $len entries, style = $(dvec.style)")
end

###
### Interface
###
StochasticStyle(dv::DVec) = dv.style
storage(dv::DVec) = dv.storage

function Base.getindex(dvec::DVec{<:Any,V}, add) where V
    return get(dvec.storage, add, zero(V))
end
function Base.setindex!(dvec::DVec, v, k)
    if iszero(v)
        delete!(dvec, k)
    else
        dvec.storage[k] = convert(valtype(dvec), v)
    end
    return v
end

Base.pairs(dvec::DVec) = dvec.storage

function LinearAlgebra.rmul!(dvec::DVec, α::Number)
    rmul!(dvec.storage.vals, α)
    return dvec
end

import Base:
    get, get!, haskey, getkey, pop!, isempty, length, values, keys, delete!, empty!, sizehint!
@delegate DVec.storage [get, get!, haskey, getkey, pop!, isempty, length, values, keys]
@delegate_return_parent DVec.storage [delete!, empty!, sizehint!]

# simd sum for Dict
function Base.sum(f::F, dvec::DVec{<:Any,V,<:Any,<:Dict}) where {F,V}
    if isempty(dvec)
        return f(zero(V))
    else
        vals = dvec.storage.vals
        slots = dvec.storage.slots
        result = f(vals[1] * (slots[1] == 0x1))
        @inbounds @simd for i in 2:length(vals)
            result += f(vals[i] * (slots[i] == 0x1))
        end
        return result
    end
end


text:
module IndianTrafficSim

include("Environment.jl")

using .Environment: plot_environment!

export plot_environment!

end


text:
module Tracker

import Base: ==

export TrackedArray, TrackedVector, TrackedMatrix, param, back!

tracker(x) = nothing

istracked(x) = tracker(x) ≠ nothing
isleaf(x) = !istracked(x) || isleaf(tracker(x))
data(x) = istracked(x) ? data(tracker(x)) : x
grad(x) = grad(tracker(x))

struct Call{F,As<:Tuple}
  func::F
  args::As
end

Call(f, args...) = Call{typeof(f),typeof(args)}(f, args)

# When deserialising, the object_id changes
a::Call == b::Call = a.func == b.func && a.args == b.args

@inline (c::Call)() = c.func(data.(c.args)...)

mutable struct Tracked{T}
  ref::UInt32
  f::Call
  isleaf::Bool
  data::T
  grad::T
  Tracked{T}(f::Call, data::T) where T = new(0, f, false, data)
  Tracked{T}(f::Call, data::T, grad::T) where T = new(0, f, false, data, grad)
  Tracked{T}(f::Call{Void}, data::T, grad::T) where T = new(0, f, true, data, grad)
end

Tracked(f::Call, x) = Tracked{typeof(x)}(f, x)
Tracked(f::Call, x, Δ) = Tracked{typeof(x)}(f, x, Δ)

track(f::Call, x) = Tracked(f, x)
track(f::Call) = track(f, f())
track(f, xs...) = track(Call(f, xs...))

istracked(x::Tracked) = true
isleaf(x::Tracked) = x.f == Call(nothing)
data(x::Tracked) = x.data
grad(x::Tracked) = x.grad

include("back.jl")
include("scalar.jl")
include("array.jl")
include("numeric.jl")

param(x::Number) = TrackedReal(float(x))
param(xs::AbstractArray) = TrackedArray(float.(xs))

import NNlib.cudata
import Adapt.adapt

cudata(x::TrackedArray) = data(x)
adapt(T, xs::TrackedArray) = param(adapt(T, data(xs)))

end


text:
"""
	An implementation of the Myers algorithm as proposed in [1].

	[1]E. Myers (1986). "An O(ND) Difference Algorithm and Its Variations".
	   Algorithmica. 1 (2): 251–266. doi:10.1007/BF01840446. S2CID 6996809.
"""
struct Myers <: StringDiffAlgorithm end # TODO(paul): add timeout

stringdiff(::Myers, a, b) =
	myers(a, b)

function myers(a, b)
	trace = ses(a, b)
	moves = backtrack(trace, a, b)
	apply_edits(moves, a, b)
end

function ses(a, b)
	N = length(a)
	M = length(b)
	max = length(a) + length(b)

	trace = Vector{Int}[]
	v = zeros(Int, 2*max+2)

	for d in 0:max
		push!(trace, copy(v))
		for k in -d:2:d
			x = if k == -d || (k != d && v[k+max] < v[k+2+max])
				v[k+2+max]
			else
				v[k+max]+1
			end
			y = x - k

			while x < N && y < M && a[x+1] == b[y+1]
				x += 1
				y += 1
			end

			v[k+max+1] = x

			if x >= N && y >= M
				return trace
			end
		end
	end
	throw("length of a ses is greater than max")
end

function backtrack(trace, a, b)
	x, y = length(a), length(b)
	max = length(a) + length(b)

	moves = []
	for (d,v) in reverse(enumerate(trace) |> collect)
		d = d-1
		k = x - y

		prev_k = if k == -d || (k != d && v[k+max] < v[k+2+max])
			k + 1
		else
			k - 1
		end
		prev_x = v[prev_k+1+max]
		prev_y = prev_x - prev_k

		while x > prev_x && y > prev_y
			push!(moves, (x-1, y-1, x, y))
			x, y = x - 1, y - 1
		end

		d > 0 && push!(moves, (prev_x, prev_y, x, y))

		x, y = prev_x, prev_y
	end

	moves
end

function apply_edits(moves, a, b)
	diffs = AbstractDiff[]
	for (prev_x, prev_y, x, y) in reverse(moves)
		a_line = get(a, prev_x+1, a[1])
		b_line = get(b, prev_y+1, a[1])

		if x == prev_x
			push!(diffs, Insertion(b_line))
		elseif y == prev_y
			push!(diffs, Deletion(a_line))
		else
			push!(diffs, Equality(b_line))
		end
	end

	diffs
end

export myers


text:
#using Base.Dates, Requests, JuliaDB, CSV, FileIO, DataFrames, TextParse, HTTP, SQLite, DataStreams
#using Missings

const mercado2mic=Dict(
"Euronext Access Lisbon"=>"ENXL",
"Euronext Access Paris"=>"XMLI",
"Euronext Amsterdam"=>"XAMS",
"Euronext Amsterdam, Brussels"=>"XAMS",
"Euronext Amsterdam, Paris"=>"XAMS",
"Euronext Brussels"=>"XBRU",
"Euronext Expert Market"=>"VPXB",
"Euronext Growth Brussels"=>"ALXB",
"Euronext Growth Paris"=>"ALXP",
"Euronext Lisbon"=>"XLIS",
"Euronext Paris"=>"XPAR",
"Euronext Paris, Amsterdam"=>"XPAR"
)

const df1 = DateFormat("dd uuu yyyy");

# Download/Ler de URL Remoto/Ficheiro dados em formato CSV usando TextParse
function download(fonte, delim = "," ; saltar=0, datatipo="y-m-d", header=true, na = [""])
    try
    if na == [""]
        return TextParse.csvread(
            fonte,
            skiplines_begin = saltar,
            colparsers = [TextParse.DateTimeToken(Date, DateFormat(datatipo))],
            header_exists=header)
    else
        return TextParse.csvread(
            fonte,
            skiplines_begin = saltar,
            header_exists = header,
            colparsers = [TextParse.DateTimeToken(Date, DateFormat(datatipo)), TextParse.NAToken(TextParse.Numeric(Float64), nastrings = na)])
    end
    catch # catching ERROR: LoadError: BoundsError: attempt to access ""
        return 0
    end
end

#function juliadb(textp, colindex, colseries; nomes::Array{Symbol,1}=[:Data,:Serie])
#    return  table(textp[1][colindex], textp[1][colseries], names=nomes, pkey = (nomes[colindex]))
# end

 #Euro = [Nome1	ISIN2	Symbol3	Location4	Maturity5	TradingCurrency6	Abrir7	Máximo8	Mínimo9	Fecho10	LastDate11	TimeZone12	Quantidade13	Turnover14]

function catalogo(Bolsa, Instrumento, Local="")
    colunas = [:ISIN :Emissão :Mercado :Maturidade]
    if Bolsa == "Euronext"
        if Instrumento == "Bonds"
            fonte = conformar("Euronext_Bonds_EU_2018-05-06.csv")
            resp = TextParse.csvread(fonte,skiplines_begin=5)
            tabela = table(resp[1][2], resp[1][1],resp[1][3], resp[1][4],names=colunas)
            if Local == ""
                return tabela
            else
                return filter(y->y.Mercado=="$Bolsa $Local",tabela)
            end
        end
    end
end

function info(isin)
    a = catalogo("Euronext", "Bonds")
    b = filter(y->y.ISIN==isin,a)
    issuename = select(b,2)      # Nome Emissão
    mic  = select(b,3)      # Codigo do mercado:"ENXL","XMLI","XAMS","XAMS","XAMS","XBRU","VPXB","ALXB","ALXP","XLIS","XPAR","XPAR"
    maturidade = select(b,4)
    return issuename[1], mic[1], maturidade[1]
end

function euronextBonds(isin; inicio="1000-01-01",fim="3000-01-01")
    colunas = [:ISIN, :Emissão, :Mercado,:Maturidade,:Data,:Abertura,:Máximo,:Mínimo,:Fecho,:NTrades,:Turnover]
    tabela = JuliaDB.table(["-"])

    iniciounix = datetime2unix(DateTime(inicio))*1000
    fimunix = datetime2unix(DateTime(fim))*1000
    euronextlocal = info(isin)[2]
    mic = mercado2mic[euronextlocal]
    euronextURL = "https://www.euronext.com/nyx_eu_listings/price_chart/download_historical?typefile=csv&separator=point&mic=$(mic)&isin=$(isin)&namefile=Price_Data_Historical&from=$(iniciounix)&to=$(fimunix)"

    fonte = conformar(euronextURL)
    resp = download(fonte, saltar = 4, header = false)
    # Catching ERROR: LoadError: BoundsError: attempt to access "" at index [0]
    if resp == 0
        return table([isin], [info(isin)[1]], [info(isin)[2]], [info(isin)[3]], [DataValues.DataValue{Date}()],[DataValues.DataValue{Float64}()],[DataValues.DataValue{Float64}()],[DataValues.DataValue{Float64}()],[DataValues.DataValue{Float64}()],[DataValues.DataValue{Int64}()], [DataValues.DataValue{Float64}()], names=colunas)
    end
    len = length(resp[1][1])
    col_ISIN = fill(isin,(len,1)) # resp[1][1], surge como TextParse.StrRange
    col_Nome = fill(info(isin)[1],(len,1))
    col_Mercado = fill(info(isin)[2],(len,1))  # resp[1][2]
    col_Maturidade = fill(info(isin)[3],(len,1))

    tabela = table(col_ISIN,col_Nome,col_Mercado,col_Maturidade,resp[1][3],resp[1][4],resp[1][5],resp[1][6],resp[1][7],resp[1][9],resp[1][10],names=colunas)
    return tabela
end

function factsheet(isin,mic)
    nomes = [:ISIN, :MIC, :Activo, :Mercado, :Emitente, :País, :PreçoEmissão, :Denominação, :DataEmissão, :DataReembolso,:TipoReembolso,:NotaçãoPreço,:TipoCoupon,:TaxaCoupon,:FreqCoupon]
    url = "https://www.euronext.com/en/factsheet-ajax?instrument_id=$(isin)-$(mic)&instrument_type=bonds"
    resp = HTTP.request("GET",url)
    text = String(resp.body)
    z = split(text,"<strong>")
    tabela = table([isin], [mic], names=[:ISIN, :MIC], pkey=:ISIN)
    lenz = length(z)
    j = 2
    for i in [2,3,5,7,8,9,10,11,12,14,23,24,25]
        j = j+1
        q = split(z[i],"</strong>")
        qnovo = strip(q[1])
        if (j == 7) || (j==8)
            if qnovo == "-"
                valor1 = [DataValues.DataValue{Float64}()] #Tb poderiamos usar missing
            else
                valor1 = [parse(Float64,String(qnovo))]
            end
            tabela = pushcol(tabela,nomes[j],valor1)
        elseif (j==9) || (j==10)
            if qnovo == "-"
                valor2 = [DataValues.DataValue{Date}()] #Tb poderiamos usar missing
            else
                valor2 = [Date(String(qnovo),df1)]
            end
            tabela = pushcol(tabela,nomes[j],valor2)
        else
            if qnovo == "-"
                valor3 = [DataValues.DataValue{String}()] #Tb poderiamos usar missing
            else
                valor3 = String[qnovo]
            end
            tabela = pushcol(tabela,nomes[j],valor3)
        end
    end
    return tabela
end

max_stars_repo_name: iscalprog/Iscalc

max_issues_repo_name: iscalprog/Iscalc

max_forks_repo_name: iscalprog/Iscalc


text:
using MetaArrays: MetaArray
using Base.Iterators: partition
using WAV: wavread
using DSP: hilbert
using PaddedViews: PaddedView

export signal, analytic, isanalytic, samples
export padded, toframe, domain
export partition

struct SamplingInfo
  fs::Float32
end

Base.keys(x::SamplingInfo) = fieldnames(typeof(x))

const SampledSignal = MetaArray{<:Any,SamplingInfo,T} where T
const SampledSignalVector = MetaArray{<:AbstractVector,SamplingInfo,T} where T
const SampledSignalMatrix = MetaArray{<:AbstractMatrix,SamplingInfo,T} where T

SignalBase.nframes(x::AbstractArray) = size(x, 1)
SignalBase.framerate(x::SampledSignal) = x.fs
SignalBase.framerate(x::AbstractArray) = 1.0
SignalBase.nchannels(x::AbstractArray) = size(x, 2)
SignalBase.sampletype(x::AbstractArray) = eltype(x)

"""
$(SIGNATURES)
Returns the domain of the signal.
"""
domain(x) = (0:nframes(x)-1) ./ framerate(x)

function Base.show(io::IO, mime::MIME"text/plain", s::SampledSignal{T}) where T
  print(io, "SampledSignal @ ", framerate(s), " Hz, ")
  show(io, mime, samples(s))
end

"""
$(TYPEDSIGNATURES)
Creates a signal with frame rate `fs`.
"""
signal(x::AbstractArray, fs) = MetaArray(SamplingInfo(inHz(fs)), x)
signal(x::Base.Iterators.Flatten, fs) = signal(collect(x), fs)

"""
$(TYPEDSIGNATURES)
Creates a signal with frame rate `fs`. If the original signal's frame rate is
the same as `fs`, this method simply returns the original signal. Otherwise, it
creates a new signal with the specified frame rate and data from the original
signal. Do note that this method does not resample the signal.
"""
signal(x::SampledSignal, fs) = fs == framerate(x) ? x : signal(samples(x), fs)

"""
$(TYPEDSIGNATURES)
Loads a signal from a WAV file.
"""
function signal(filename::AbstractString; start=1, nsamples=missing)
  if start == 1 && nsamples === missing
    data, fs = wavread(filename)
  elseif start == 1
    data, fs = wavread(filename; subrange=nsamples)
  else
    if nsamples === missing
      n, ch = wavread(filename; format="size")
      nsamples = n - start + 1
    end
    data, fs = wavread(filename; subrange=start:(start+nsamples-1))
  end
  signal(data, fs)
end

"""
$(TYPEDSIGNATURES)
Creates an empty signal of length `n` samples, and frame rate `fs`.
"""
signal(n::Int, fs) = signal(Array{Float64}(undef, n), fs)

"""
$(TYPEDSIGNATURES)
Creates an empty signal of length `n` samples, `ch` channels, and frame rate `fs`.
"""
signal(n::Int, ch::Int, fs) = signal(Array{Float64}(undef, n, ch), fs)

"""
$(TYPEDSIGNATURES)
Creates an empty signal of type `T`, length `n` samples, and frame rate `fs`.
"""
signal(T::Type, n::Int, fs) = signal(Array{T}(undef, n), fs)

"""
$(TYPEDSIGNATURES)
Creates an empty signal of type `T`, length `n` samples, `ch` channels, and frame rate `fs`.
"""
signal(T::Type, n::Int, ch::Int, fs) = signal(Array{T}(undef, n, ch), fs)

"""
$(TYPEDSIGNATURES)
Creates a curried function that takes in an array and creates a signal with sampling rate `fs`.
"""
signal(fs) = x -> signal(x, fs)

"""
$(SIGNATURES)
Converts a signal to analytic representation.
"""
analytic(s::SampledSignal) = isanalytic(s) ? s : signal(hilbert(s)/√2.0, framerate(s))
analytic(s) = isanalytic(s) ? s : hilbert(s)/√2.0

"""
$(SIGNATURES)
Checks if a signal is analytic.
"""
isanalytic(s) = eltype(s) <: Complex

"""
$(SIGNATURES)
Gets the underlying samples in the signal.
"""
samples(s::SampledSignal) = getfield(s, :data)
samples(s) = s

"""
$(SIGNATURES)
Generates a padded view of a signal with optional delay/advance.
"""
function padded(s::AbstractVector{T}, padding; delay=0, fill=zero(T)) where {T}
  if length(padding) == 1
    left = padding
    right = padding
  else
    left = padding[1]
    right = padding[2]
  end
  PaddedView(fill, s, (1-left:length(s)+right,), (1+delay:delay+length(s),))
end

function padded(s::SampledSignal{T}, padding; delay=0, fill=zero(T)) where T
  signal(padded(samples(s), padding; delay=delay, fill=fill), framerate(s))
end

"""
    partition(x, n; step=n, flush=true)

Iterates over the signal `x`, `n` samples at a time, with a step size of `step`. If `flush` is
enabled, the last partition may be smaller than `n` samples.

When applied to a multichannel signal `x`, each partition contains samples from all channels.

# Examples:
```julia-repl
julia> x = signal(collect(1:10), 1.0);
julia> collect(partition(x, 5))
2-element Array{SubArray{Int64,1,Array{Int64,1},Tuple{UnitRange{Int64}},true},1}:
 [1, 2, 3, 4, 5]
 [6, 7, 8, 9, 10]

julia> collect(partition(x, 5; step=2))
5-element Array{SubArray{Int64,1,Array{Int64,1},Tuple{UnitRange{Int64}},true},1}:
 [1, 2, 3, 4, 5]
 [3, 4, 5, 6, 7]
 [5, 6, 7, 8, 9]
 [7, 8, 9, 10]
 [9, 10]

julia> collect(partition(x, 5; step=2, flush=false))
3-element Array{SubArray{Int64,1,Array{Int64,1},Tuple{UnitRange{Int64}},true},1}:
 [1, 2, 3, 4, 5]
 [3, 4, 5, 6, 7]
 [5, 6, 7, 8, 9]

julia> x = signal(hcat(collect(1:10), collect(11:20)), 1.0);
julia> collect(partition(x, 5))[1]
5×2 view(::Array{Int64,2}, 1:5, :) with eltype Int64:
 1  11
 2  12
 3  13
 4  14
 5  15
```
"""
function Base.Iterators.partition(s::SampledSignal, n::Integer; step::Integer=n, flush::Bool=true)
  n < 1 && throw(ArgumentError("cannot create partitions of length $n"))
  step < 1 && throw(ArgumentError("cannot create partitions with step size $step"))
  v = samples(s)
  return SignalPartitionIterator{typeof(v)}(v, Int(n), Int(step), flush)
end

struct SignalPartitionIterator{T <: AbstractArray}
  c::T
  n::Int
  step::Int
  flush::Bool
end

Base.IteratorEltype(::Type{SignalPartitionIterator}) = Base.HasEltype()
Base.IteratorSize(::Type{SignalPartitionIterator}) = Base.HasLength()

Base.eltype(::Type{SignalPartitionIterator{T}}) where {T<:AbstractVector} = AbstractVector{eltype(T)}
Base.eltype(::Type{SignalPartitionIterator{T}}) where {T<:AbstractMatrix} = AbstractMatrix{eltype(T)}
Base.eltype(::Type{SignalPartitionIterator{T}}) where {T<:Vector} = SubArray{eltype(T), 1, T, Tuple{UnitRange{Int}}, true}
Base.eltype(::Type{SignalPartitionIterator{T}}) where {T<:Matrix} = SubArray{eltype(T), 2, T, Tuple{UnitRange{Int},Base.Slice{Base.OneTo{Int64}}}, false}

function Base.length(itr::SignalPartitionIterator)
  l = size(itr.c, 1)
  itr.flush || (l -= itr.n-1)
  return div(l, itr.step) + ((mod(l, itr.step) > 0) ? 1 : 0)
end

function Base.iterate(itr::SignalPartitionIterator{<:AbstractRange}, state=1)
  l = length(itr.c)
  state > l && return nothing
  itr.flush || state + itr.n - 1 <= l || return nothing
  r = min(state + itr.n - 1, l)
  return @inbounds itr.c[state:r], state + itr.step
end

function Base.iterate(itr::SignalPartitionIterator{<:AbstractVector}, state=1)
  l = length(itr.c)
  state > l && return nothing
  itr.flush || state + itr.n - 1 <= l || return nothing
  r = min(state + itr.n - 1, l)
  return @inbounds view(itr.c, state:r), state + itr.step
end

function Base.iterate(itr::SignalPartitionIterator{<:AbstractMatrix}, state=1)
  l = size(itr.c, 1)
  state > l && return nothing
  itr.flush || state + itr.n - 1 <= l || return nothing
  r = min(state + itr.n - 1, l)
  return @inbounds view(itr.c, state:r, :), state + itr.step
end

"""
$(SIGNATURES)
Converts time to signal frame number.

# Examples:
```julia-repl
julia> x = signal(randn(2000), 8kHz);
julia> toframe(0.2s, x)
1601

julia> toframe([0.2s, 201ms], x)
2-element Array{Int64,1}:
 1601
 1609

julia> toframe(0.2:0.01:0.3, x)
 11-element Array{Int64,1}:
  1601
  1681
  1761
   ⋮
```
"""
toframe(t, s::SampledSignal) = 1 .+ round.(Int, inseconds.(t)*framerate(s))

"""
    (:)(start::Unitful.Time, stop::Unitful.Time)

Generates a time range index for a signal.

# Examples:
```julia-repl
julia> x = signal(randn(2000), 8kHz)
julia> x[0.2𝓈:0.201𝓈]
SampledSignal @ 8000.0 Hz, 9-element Array{Float64,1}:
 -0.08671384898800058
 -0.665143340284631
 -0.3955367460364236
  1.2386430598616671
 -0.4882254309443194
 -1.080437097803303
  0.8209785486953832
  1.3477512734963886
 -0.27722340584395494
```
"""
(::Colon)(t1::Units.Unitful.Time, t2::Units.Unitful.Time) = tuple(inseconds(t1), inseconds(t2))
(::Colon)(t1::Real, t2::Units.Unitful.Time) = tuple(inseconds(t1), inseconds(t2))

Base.getindex(s::SampledSignal, t::NTuple{2}) = Base.getindex(s, toframe(t[1], s):toframe(t[2], s))
Base.getindex(s::SampledSignal, t::NTuple{2}, ndx...) = Base.getindex(s, toframe(t[1], s):toframe(t[2], s), ndx...)
Base.setindex!(s::SampledSignal, v, t::NTuple{2}) = Base.setindex!(s, v, toframe(t[1], s):toframe(t[2], s))
Base.setindex!(s::SampledSignal, v, t::NTuple{2}, ndx...) = Base.setindex!(s, v, toframe(t[1], s):toframe(t[2], s), ndx...)


text:
module SymbolServer

using Serialization, Pkg, SHA
include("from_static_lint.jl")

server = Server(abspath(joinpath(@__DIR__, "..", "..", "store")), Pkg.Types.Context(), Dict{String,Any}())
if Sys.isunix()
    global const nullfile = "/dev/null"
elseif Sys.iswindows()
    global const nullfile = "nul"
else
    error("Platform not supported")
end

while true
    message, payload = deserialize(stdin)
    if message == :debugmessage
        @info(payload)
        serialize(stdout, (:success, nothing))
    elseif message == :close
        break
    elseif message == :get_context
        serialize(stdout, (:success, server.context))
    elseif message == :load_core
        core_pkgs = load_core()
        SymbolServer.save_store_to_disc(core_pkgs["Base"], joinpath(server.storedir, "Base.jstore"))
        SymbolServer.save_store_to_disc(core_pkgs["Core"], joinpath(server.storedir, "Core.jstore"))
        serialize(stdout, (:success, nothing))
    elseif message == :load_package
        pkg = PackageID(first(payload), last(payload))
        open(nullfile, "w") do f
            redirect_stdout(f) do # seems necessary incase packages print on startup
                SymbolServer.import_package_names(pkg, server.depot, server.context)
            end
        end
        for  (uuid, pkg) in server.depot
            SymbolServer.save_store_to_disc(pkg, joinpath(server.storedir, "$uuid.jstore"))
        end
        serialize(stdout, (:success, [k=>v.name for (k,v) in server.depot if v.name isa String]))
    elseif message == :load_all
        for pkg in SymbolServer.context_deps(server.context)
            open(nullfile, "w") do f
                redirect_stdout(f) do # seems necessary incase packages print on startup
                    SymbolServer.import_package_names(PackageID(first(pkg), string(last(pkg))), server.depot, server.context)
                end
            end
        end

        for (uuid, pkg) in server.depot
            SymbolServer.save_store_to_disc(pkg, joinpath(server.storedir, "$uuid.jstore"))
        end
        serialize(stdout, (:success, [k=>v.name for (k,v) in server.depot if v.name isa String]))
    else
        serialize(stdout, (:failure, nothing))
    end
end

end


text:
using Makie

function draw_truss!(scene, X::Matrix{Float64}, T::Matrix{Int}, S::Matrix{Int}, area::Vector{Float64}; line_width::Float64=1.0, draw_supp::Bool=true, supp_scale::Float64=0.1, color=:black, xaxis_label::String="x", plot_limits=undef)

    @assert(size(T, 1) == length(area))
    a = reshape([area area]', 2*length(area))
    # a ./= maximum(a)
    a .*= line_width

    # seg_ids = reshape([T[:,1] T[:,2]], length(T[:,1])+length(T[:,2]))
    seg_ids = reshape(T', prod(size(T)))
    if plot_limits == undef
        max_xlim = maximum(X[:,1]) - minimum(X[:,1])
        max_ylim = maximum(X[:,2]) - minimum(X[:,2])
        max_lim = max(max_xlim, max_ylim)
        plot_limits = FRect(minimum(X[:,1]), minimum(X[:,2]),
                       max_lim, max_lim)
    end

    linesegments!(scene, X[seg_ids, 1], X[seg_ids, 2], linewidth = a,
                  color = color,
                  limits = plot_limits,
                  axis = (names = (axisnames = (xaxis_label, "y"),),
                          grid = (linewidth = (1, 1),),
                          )
                  )
    if draw_supp
        fix_ids = (Int).(S[:,1])
        # arrows!(scene,
        #       vcat(truss.X[fix_ids, 1],truss.X[fix_ids, 1]),
        #       vcat(truss.X[fix_ids, 2],truss.X[fix_ids, 2]),
        #       vcat(truss.S[:,2], zeros(size(truss.S,1))).*supp_scale,
        #       vcat(zeros(size(truss.S,1)), truss.S[:,3]).*supp_scale,
        #       linecolor = :green, arrowcolor = :green)
        for i=1:size(S,1)
            if 1 == S[i,2]
                arrows!(scene, [X[S[i,1], 1]], [X[S[i,1], 2]], [supp_scale], [0], linecolor = :green, arrowcolor = :green, limits = plot_limits,
                # linewidth = supp_scale*10,
                arrowsize = 0.1,
                )
            end
            if 1 == S[i,3]
                arrows!(scene, [X[S[i,1], 1]], [X[S[i,1], 2]], [0], [supp_scale], linecolor = :green, arrowcolor = :green, limits = plot_limits,
                # linewidth = supp_scale*10,
                arrowsize = 0.1,
                )
            end
            if 1 == S[i,4]
                scatter!(scene, [X[S[i,1], 1]], [X[S[i,1], 2]], color = :green, markersize=supp_scale, marker=:x, limits = plot_limits)
            else
                scatter!(scene, [X[S[i,1], 1]], [X[S[i,1], 2]], color = :green, markersize=supp_scale, marker=:circle, limits = plot_limits)
            end
        end
    end
    # axis = scene[Axis]
    # axis[:grid][:linewidth] = (1, 1)
    return scene
end

function draw_load!(scene, X::Matrix{Float64}, load::Matrix{Float64}; load_scale::Float64=0.1, xaxis_label::String="x", plot_limits=undef)
    fix_ids = (Int).(load[:,1])

    if plot_limits == undef
        max_xlim = maximum(X[:,1]) - minimum(X[:,1])
        max_ylim = maximum(X[:,2]) - minimum(X[:,2])
        max_lim = max(max_xlim, max_ylim)
        plot_limits = FRect(minimum(X[:,1]), minimum(X[:,2]),
                       max_lim, max_lim)
    end

    arrows!(scene, X[fix_ids, 1], X[fix_ids, 2],
            load[:,2].*load_scale, load[:,3].*load_scale,
            linecolor = :orange, arrowcolor = :orange,
            # linewidth = load_scale*10,
            arrowsize = 0.1,
            limits = plot_limits,
            axis = (names = (axisnames = (xaxis_label, "y"),),)
            )
    # axis = scene[Axis]
    # axis[:grid][:linewidth] = (1, 1)
end

function draw_deformed!(scene, truss::Truss, U::Vector{Float64}, node_dof::Int;
    line_width::Float64=10, deform_scale::Float64=5.0)

    n_v = size(truss.X, 1)
    n_e = size(truss.T, 1)
    a = ones(Float64, 2*n_e)
    a .*= line_width

    seg_ids = reshape([truss.T[:,1] truss.T[:,2]], length(truss.T[:,1])+length(truss.T[:,2]))
    max_lim = max(maximum(truss.X[:,1]) - minimum(truss.X[:,1]),
                  maximum(truss.X[:,2]) - minimum(truss.X[:,2]))
    limits = FRect(minimum(truss.X[:,1]), minimum(truss.X[:,2]),
                   max_lim, max_lim)

    node_U = reshape(U, (node_dof, Int.(length(U)/node_dof)))'
    DX = truss.X[seg_ids, 1] + node_U[seg_ids, 1]
    DY = truss.X[seg_ids, 2] + node_U[seg_ids, 2]
    linesegments!(scene, DX .* deform_scale, DY .* deform_scale,
                  linewidth = a,
                  color = :blue,
                  limits = limits,
                  # axis = (names = (axisnames = ("x", "y"),),
                  #         grid = (linewidth = (1, 1),),
                  #         )
                          )
end


text:
export LangevinNVT

abstract type Thermostat end

struct NoThermostat<:Thermostat end

struct LangevinNVT<:Thermostat
    invdt::Float64
    gamma::Float64
    function LangevinNVT(;dt::Float64=0.0,gamma::Float64=0.0)
        invdt=1.0/dt
        new(invdt::Float64,
            gamma::Float64)
    end
end

function init(::LangevinNVT,input::Dict)
    gamma=input["LangevinNVT"]["gamma"]
    dt=input["dt"]
    thermostat=LangevinNVT(dt=dt,gamma=gamma)
    return thermostat
end

struct BerendsenNVT <: Thermostat
    τ::Float64
    function BerendsenNVT(;τ=0.0)
        new(τ::Float64)
    end
end

function init(::BerendsenNVT,input::Dict)
    tau=input["BerendsenNVT"]["tau"]
    thermostat=BerendsenNVT(τ=tau)
    return thermostat
end


text:
using AdFem
using ADCME
using PyPlot
using JLD2
using Revise
using ADCME
using PyCall
DIR = abspath(joinpath(@__DIR__, ".."))
py"""
import sys
sys.path.insert(0, $DIR)
"""
opt = pyimport("optim.optim")

@load "data/fwd.jld2" SOL

function f(x, y)
    return sin(2π*10y+π/8)
end

mmesh = Mesh(joinpath(PDATA, "twoholes_large.stl"))

using Random; Random.seed!(SEED)
idx = rand(1:length(SOL), length(SOL)÷5)
xy = gauss_nodes(mmesh)
θ = Variable(fc_init([2,20,20,20,1]))
Kappa = squeeze(fc(xy, [20, 20, 20,1], θ, activation="tanh")) + 2.0
F = eval_f_on_gauss_pts(f, mmesh)
L = compute_fem_laplace_matrix1(Kappa, mmesh)
RHS = compute_fem_source_term1(F, mmesh)

bd = bcnode(mmesh)
L, RHS = impose_Dirichlet_boundary_conditions(L, RHS, bd, zeros(length(bd)))

sol = L\RHS
loss = sum((sol - SOL)^2)*1e10


text:
module Operations

using ..Types
using ..Universes: Element, AreaElements

export check, Fraction, exists, not_exists, new

function check end

exists(element::Element) = convert(Bool, element)
exists(elements::AreaElements) = convert(Bool, elements)

not_exists(element::Element) = !exists(element)
not_exists(elements::AreaElements) = !exists(elements)

function Base.count(elements::AreaElements)
    counter = 0

    for element in elements
        if isenabled(element)
            counter += 1
        end
    end

    return counter
end

struct Fraction <: Checkable
    border::Float32
end

function check(element::Element, parameters::Fraction)
    return rand(Float32) < parameters.border
end

function (checker::Checkable)(element::E) where {E<:Element}
    if check(element, checker)
        return element
    end

    return disable(element)
end

function (checker::Checkable)(elements::Vector{E}) where {E<:Element}
    # TODO: replace with boolean template assigment

    for (i, e) in enumerate(elements)
        if isenabled(e) && !check(e, checker)
            elements[i] = disable(elements[i])
        end
    end

    return elements
end

function new(elements::AreaElements)
    for (i, element) in enumerate(elements)
        if isenabled(element)
            elements[i] = construct_new_element(typeof(element), element.universe, element.topology_index)
        end
    end

    return elements
end

function new(element::Element)
    if isenabled(element)
        return construct_new_element(typeof(element), element.universe, element.topology_index)
    end

    return element
end

end

max_stars_repo_name: Tiendil/pcg-julia

max_issues_repo_name: Tiendil/pcg-julia

max_forks_repo_name: Tiendil/pcg-julia


text:
@option struct NeRFConfig
    x_dim::Int=3
    d_dim::Int=3
    n_input_layers::Int=5
    n_mid_layers::Int=4
    hidden_dim::Int=256
    color_layer_dim::Int=128
    x_freqs::Int=10
    d_freqs::Int=4
end

struct NeRFModel
    input_layers
    mid_layers
    density
    color
    x_freqs::Int
    d_freqs::Int
end

Flux.@functor NeRFModel (input_layers, mid_layers, density, color,)

function sinusodial_emb(coords, freqs::Int)
    coeffs = 2 .^ range(0, freqs-1)
    coeffs = Flux.Adapt.adapt(typeof(coords), coeffs)
    inputs = unsqueeze(coords, dims=1) .* coeffs
    @check size(inputs) == (freqs, size(coords)...)
    sines = sin.(inputs)
    cosines = cos.(inputs)
    combined = vcat(sines, cosines)
    return (reshape(combined, :, size(combined)[begin+2:end]...))
end

function NeRFModel(;config::NeRFConfig)
    x_emb_dim = config.x_dim * 2 * config.x_freqs
    d_emb_dim = config.d_dim * 2 * config.d_freqs
    layers = [Dense(config.hidden_dim, config.hidden_dim, relu) for _ in 2:config.n_input_layers]
    input_layers = Chain(Dense(x_emb_dim, config.hidden_dim, relu), layers...)

    layers = [Dense(config.hidden_dim, config.hidden_dim, relu) for _ in 2:config.n_mid_layers]
    mid_layers = Chain(Dense(config.hidden_dim+x_emb_dim, config.hidden_dim), layers...)

    density = Dense(config.hidden_dim, 1, softplus)
    color = Chain(Dense(config.hidden_dim+d_emb_dim, config.color_layer_dim, relu), Dense(config.color_layer_dim, 3, tanh_fast))
    return NeRFModel(input_layers, mid_layers, density, color, config.x_freqs, config.d_freqs)
end

function (m::NeRFModel)(x, d)
    x_emb = sinusodial_emb(x, m.x_freqs)
    d_emb = sinusodial_emb(d, m.d_freqs)
    z = m.input_layers(x_emb)
    z1 = vcat(z, x_emb)
    z2 = m.mid_layers(z1)
    density = m.density(z2)
    z3 = vcat(z2, d_emb)
    rgb = m.color(z3)
    return density, rgb
end


text:
# ---
# title: 368. Largest Divisible Subset
# id: problem368
# author: Tian Jun
# date: 2020-10-31
# difficulty: Medium
# categories: Math, Dynamic Programming
# link: <https://leetcode.com/problems/largest-divisible-subset/description/>
# hidden: true
# ---
#
# Given a set of **distinct** positive integers, find the largest subset such
# that every pair (Si, Sj) of elements in this subset satisfies:
#
# Si % Sj = 0 or Sj % Si = 0.
#
# If there are multiple solutions, return any subset is fine.
#
# **Example 1:**
#
#
#
#     Input: [1,2,3]
#     Output: [1,2] (of course, [1,3] will also be ok)
#
#
# **Example 2:**
#
#
#
#     Input: [1,2,4,8]
#     Output: [1,2,4,8]
#
#
#
## @lc code=start
using LeetCode

## add your code here:
## @lc code=end