text:
mutable struct ProtoMetaLock
    lck::Union{Nothing,ReentrantLock}
end

function Base.lock(f, l::ProtoMetaLock)
    (l.lck === nothing) && (return f())
    lock(l.lck) do
        f()
    end
end

const MetaLock = ProtoMetaLock(ReentrantLock())

function enable_async_safety(dolock::Bool)
    if dolock
        (MetaLock.lck === nothing) && (MetaLock.lck = ReentrantLock())
    else
        (MetaLock.lck !== nothing) && (MetaLock.lck = nothing)
    end
    MetaLock.lck
end

const MSB = 0x80
const MASK7 = 0x7f
const MASK8 = 0xff
const MASK3 = 0x07

const WIRETYP_VARINT   = 0
const WIRETYP_64BIT    = 1
const WIRETYP_LENDELIM = 2
const WIRETYP_GRPSTART = 3   # deprecated
const WIRETYP_GRPEND   = 4   # deprecated
const WIRETYP_32BIT    = 5

"""
The abstract type from which all generated protobuf structs extend.
"""
abstract type ProtoType end

wiretypes(::Type{Int32})                            = [:int32, :sint32, :enum, :sfixed32]
wiretypes(::Type{Int64})                            = [:int64, :sint64, :sfixed64]
wiretypes(::Type{UInt32})                           = [:uint32, :fixed32]
wiretypes(::Type{UInt64})                           = [:uint64, :fixed64]
wiretypes(::Type{Bool})                             = [:bool]
wiretypes(::Type{Float64})                          = [:double]
wiretypes(::Type{Float32})                          = [:float]
wiretypes(::Type{T}) where {T<:AbstractString}      = [:string]
wiretypes(::Type{Vector{UInt8}})                    = [:bytes]
wiretypes(::Type{Dict{K,V}}) where {K,V}            = [:map]
wiretypes(::Type)                                   = [:obj]
wiretypes(::Type{Vector{T}}) where {T}              = wiretypes(T)

wiretype(::Type{T}) where {T}                       = wiretypes(T)[1]

defaultval(::Type{T}) where {T<:Number}             = [zero(T)]
defaultval(::Type{T}) where {T<:AbstractString}     = [convert(T,"")]
defaultval(::Type{Bool})                            = [false]
defaultval(::Type{Vector{T}}) where {T}             = Any[T[]]
defaultval(::Type)                                  = []

function _write_uleb(io::IO, x::T) where T <: Integer
    nw = 0
    cont = true
    while cont
        byte = x & MASK7
        if (x >>>= 7) != 0
            byte |= MSB
        else
            cont = false
        end
        nw += write(io, UInt8(byte))
    end
    nw
end

# max number of 7bit blocks for reading n bytes
# d,r = divrem(sizeof(T)*8, 7)
# (r > 0) && (d += 1)
const _max_n = [2, 3, 4, 5, 6, 7, 8, 10]

function _read_uleb_base(io::IO, ::Type{T}) where T <: Integer
    res = zero(T)
    n = 0
    byte = UInt8(MSB)
    while (byte & MSB) != 0
        byte = read(io, UInt8)
        res |= (convert(T, byte & MASK7) << (7*n))
        n += 1
    end
    n, res
end

function _read_uleb(io::IO, ::Type{Int32})
    n, res = _read_uleb_base(io, Int32)

    # negative int32 are encoded in 10 bytes (ref: https://developers.google.com/protocol-buffers/docs/encoding)
    # > if you use int32 or int64 as the type for a negative number, the resulting varint is always ten bytes long
    #
    # but Julia can be tolerant like the C protobuf implementation (unlike python)

    if n > _max_n[sizeof(res < 0 ? Int64 : Int32)]
        @debug("overflow reading Int32. returning 0")
        return Int32(0)
    end

    res
end

function _read_uleb(io::IO, ::Type{T}) where T <: Integer
    n, res = _read_uleb_base(io, T)
    # in case of overflow, consider it as missing field and return default value
    if n > _max_n[sizeof(T)]
        @debug("overflow reading integer type. returning 0", T)
        return zero(T)
    end
    res
end

function _write_zigzag(io::IO, x::T) where T <: Integer
    nbits = 8*sizeof(x)
    zx = (x << 1) ⊻ (x >> (nbits-1))
    _write_uleb(io, zx)
end

function _read_zigzag(io::IO, ::Type{T}) where T <: Integer
    zx = _read_uleb(io, UInt64)
    # result is positive if zx is even
    convert(T, iseven(zx) ? (zx >>> 1) : -signed((zx+1) >>> 1))
end

##
# read and write field keys
_write_key(io::IO, fld::Int, wiretyp::Int) = _write_uleb(io, (fld << 3) | wiretyp)
function _read_key(io::IO)
    key = _read_uleb(io, UInt64)
    wiretyp = key & MASK3
    fld = key >>> 3
    (fld, wiretyp)
end

##
# read and write field values
write_varint(io::IO, x::T) where {T <: Integer} = _write_uleb(io, x)
write_varint(io::IO, x::Int32) = _write_uleb(io, x < 0 ? Int64(x) : x)
write_bool(io::IO, x::Bool) = _write_uleb(io, x ? 1 : 0)
write_svarint(io::IO, x::T) where {T <: Integer} = _write_zigzag(io, x)

read_varint(io::IO, ::Type{T}) where {T <: Integer} = _read_uleb(io, T)
read_bool(io::IO) = Bool(_read_uleb(io, UInt64))
read_bool(io::IO, ::Type{Bool}) = read_bool(io)
read_svarint(io::IO, ::Type{T}) where {T <: Integer} = _read_zigzag(io, T)

write_fixed(io::IO, x::UInt32) = _write_fixed(io, x)
write_fixed(io::IO, x::UInt64) = _write_fixed(io, x)
write_fixed(io::IO, x::Int32) = _write_fixed(io, reinterpret(UInt32, x))
write_fixed(io::IO, x::Int64) = _write_fixed(io, reinterpret(UInt64, x))
write_fixed(io::IO, x::Float32) = _write_fixed(io, reinterpret(UInt32, x))
write_fixed(io::IO, x::Float64) = _write_fixed(io, reinterpret(UInt64, x))
function _write_fixed(io::IO, ux::T) where T <: Unsigned
    N = sizeof(ux)
    for n in 1:N
        write(io, UInt8(ux & MASK8))
        ux >>>= 8
    end
    N
end

read_fixed(io::IO, typ::Type{UInt32}) = _read_fixed(io, convert(UInt32,0), 4)
read_fixed(io::IO, typ::Type{UInt64}) = _read_fixed(io, convert(UInt64,0), 8)
read_fixed(io::IO, typ::Type{Int32}) = reinterpret(Int32, _read_fixed(io, convert(UInt32,0), 4))
read_fixed(io::IO, typ::Type{Int64}) = reinterpret(Int64, _read_fixed(io, convert(UInt64,0), 8))
read_fixed(io::IO, typ::Type{Float32}) = reinterpret(Float32, _read_fixed(io, convert(UInt32,0), 4))
read_fixed(io::IO, typ::Type{Float64}) = reinterpret(Float64, _read_fixed(io, convert(UInt64,0), 8))
function _read_fixed(io::IO, ret::T, N::Int) where T <: Unsigned
    for n in 0:(N-1)
        byte = convert(T, read(io, UInt8))
        ret |= (byte << (8*n))
    end
    ret
end

function write_bytes(io::IO, data::Vector{UInt8})
    n = _write_uleb(io, sizeof(data))
    n += write(io, data)
    n
end

function read_bytes(io::IO)
    n = _read_uleb(io, UInt64)
    data = Vector{UInt8}(undef, n)
    read!(io, data)
    data
end
read_bytes(io::IO, ::Type{Vector{UInt8}}) = read_bytes(io)

write_string(io::IO, x::AbstractString) = write_string(io, String(x))
write_string(io::IO, x::String) = write_bytes(io, @static isdefined(Base, :codeunits) ? unsafe_wrap(Vector{UInt8}, x) : Vector{UInt8}(x))

read_string(io::IO) = String(read_bytes(io))
read_string(io::IO, ::Type{T}) where {T <: AbstractString} = convert(T, read_string(io))

# TODO: wiretypes should become julia types, so that methods can be parameterized on them
writeproto() = 0
readproto() = nothing

function write_map(io::IO, fldnum::Int, dict::Dict)
    dmeta = mapentry_meta(typeof(dict))
    iob = IOBuffer()

    n = 0
    for key in keys(dict)
        @debug("write_map", key)
        val = dict[key]
        writeproto(iob, key, dmeta.ordered[1])
        @debug("write_map", val)
        writeproto(iob, val, dmeta.ordered[2])
        n += _write_key(io, fldnum, WIRETYP_LENDELIM)
        n += write_bytes(io, take!(iob))
    end
    n
end

function read_map(io, dict::Dict{K,V}) where {K,V}
    iob = IOBuffer(read_bytes(io))

    dmeta = mapentry_meta(Dict{K,V})
    key_wtyp, key_wfn, key_rfn, key_jtyp = WIRETYPES[dmeta.numdict[1].ptyp]
    val_wtyp, val_wfn, val_rfn, val_jtyp = WIRETYPES[dmeta.numdict[2].ptyp]
    key_val = Vector{Union{K,V}}(undef, 2)

    while !eof(iob)
        fldnum, wiretyp = _read_key(iob)
        @debug("reading map", fldnum)

        fldnum = Int(fldnum)
        attrib = dmeta.numdict[fldnum]

        if fldnum == 1
            key_val[1] = read_field(iob, nothing, attrib, key_wtyp, K)
        elseif fldnum == 2
            key_val[2] = read_field(iob, nothing, attrib, val_wtyp, V)
        else
            skip_field(iob, wiretyp)
        end
    end
    @debug("read map", key=key_val[1], val=key_val[2])
    dict[key_val[1]] = key_val[2]
    dict
end

const WIRETYPES = Dict{Symbol,Tuple}(
    :int32          => (WIRETYP_VARINT,     write_varint,  read_varint,   Int32),
    :int64          => (WIRETYP_VARINT,     write_varint,  read_varint,   Int64),
    :uint32         => (WIRETYP_VARINT,     write_varint,  read_varint,   UInt32),
    :uint64         => (WIRETYP_VARINT,     write_varint,  read_varint,   UInt64),
    :sint32         => (WIRETYP_VARINT,     write_svarint, read_svarint,  Int32),
    :sint64         => (WIRETYP_VARINT,     write_svarint, read_svarint,  Int64),
    :bool           => (WIRETYP_VARINT,     write_bool,    read_bool,     Bool),
    :enum           => (WIRETYP_VARINT,     write_varint,  read_varint,   Int32),

    :fixed64        => (WIRETYP_64BIT,      write_fixed,   read_fixed,    UInt64),
    :sfixed64       => (WIRETYP_64BIT,      write_fixed,   read_fixed,    Int64),
    :double         => (WIRETYP_64BIT,      write_fixed,   read_fixed,    Float64),

    :string         => (WIRETYP_LENDELIM,   write_string,  read_string,   AbstractString),
    :bytes          => (WIRETYP_LENDELIM,   write_bytes,   read_bytes,    Vector{UInt8}),
    :obj            => (WIRETYP_LENDELIM,   writeproto,    readproto,     Any),
    :map            => (WIRETYP_LENDELIM,   write_map,     read_map,      Dict),

    :fixed32        => (WIRETYP_32BIT,      write_fixed,   read_fixed,    UInt32),
    :sfixed32       => (WIRETYP_32BIT,      write_fixed,   read_fixed,    Int32),
    :float          => (WIRETYP_32BIT,      write_fixed,   read_fixed,    Float32)
)

#aliaswiretypes(wtype::Symbol) = wiretypes(WIRETYPES[wtype][4])

##
# read and write protobuf structures

mutable struct ProtoMetaAttribs
    fldnum::Int             # the field number in the structure
    fld::Symbol             # field name
    ptyp::Symbol            # protobuf type
    jtyp::Type              # Julia type
    occurrence::Int         # 0: optional, 1: required, 2: repeated
    packed::Bool            # if repeated, whether packed
    default::Array          # the default value, empty array if none is specified, first element is used if something is specified
    meta::Any               # the ProtoMeta if this is a nested type
end

mutable struct ProtoMeta
    jtype::Type
    symdict::Dict{Symbol,ProtoMetaAttribs}
    numdict::Dict{Int,ProtoMetaAttribs}
    ordered::Vector{ProtoMetaAttribs}
    oneofs::Vector{Int}
    oneof_names::Vector{Symbol}

    function ProtoMeta(jtype::Type, ordered::Vector{ProtoMetaAttribs}, oneofs::Vector{Int}=Int[], oneof_names::Vector{Symbol}=Symbol[])
        setprotometa!(new(), jtype, ordered, oneofs, oneof_names)
    end

    function ProtoMeta(jtype::Type)
        new(jtype)
    end
end

function setprotometa!(meta::ProtoMeta, jtype::Type, ordered::Vector{ProtoMetaAttribs}, oneofs::Vector{Int}, oneof_names::Vector{Symbol})
    symdict = Dict{Symbol,ProtoMetaAttribs}()
    numdict = Dict{Int,ProtoMetaAttribs}()
    for attrib in ordered
        symdict[attrib.fld] = numdict[attrib.fldnum] = attrib
    end
    meta.jtype = jtype
    meta.symdict = symdict
    meta.numdict = numdict
    meta.ordered = ordered
    meta.oneofs = oneofs
    meta.oneof_names = oneof_names
    meta
end

function writeproto(io::IO, val, attrib::ProtoMetaAttribs)
    fld = attrib.fldnum
    meta = attrib.meta
    ptyp = attrib.ptyp
    wiretyp, wfn, rfn, jtyp = WIRETYPES[ptyp]
    iob = IOBuffer()

    n = 0
    wfn(iob, convert(jtyp, val), meta)
    n += _write_key(io, fld, WIRETYP_LENDELIM)
    n += write_bytes(io, take!(iob))
    n
end

function writeproto(io::IO, val::T, attrib::ProtoMetaAttribs) where T<:Number
    fld = attrib.fldnum
    ptyp = attrib.ptyp
    wiretyp, wfn, rfn, jtyp = WIRETYPES[ptyp]

    n = 0
    n += _write_key(io, fld, wiretyp)
    n += wfn(io, convert(jtyp, val))
    n
end

function writeproto(io::IO, val::T, attrib::ProtoMetaAttribs) where T<:AbstractString
    fld = attrib.fldnum
    ptyp = attrib.ptyp
    wiretyp, wfn, rfn, jtyp = WIRETYPES[ptyp]

    n = 0
    n += _write_key(io, fld, wiretyp)
    n += write_string(io, val)
    n
end

writeproto(io::IO, val::Dict, attrib::ProtoMetaAttribs) = write_map(io, attrib.fldnum, convert(attrib.meta.jtype, val))

function writeproto(io::IO, val::Vector{UInt8}, attrib::ProtoMetaAttribs)
    fld = attrib.fldnum
    ptyp = attrib.ptyp
    wiretyp, wfn, rfn, jtyp = WIRETYPES[ptyp]

    n = 0
    n += _write_key(io, fld, wiretyp)
    n += write_bytes(io, val)
    n
end

function writeproto(io::IO, val::Array{T}, attrib::ProtoMetaAttribs) where T
    ptyp = attrib.ptyp
    wiretyp, wfn, rfn, jtyp = WIRETYPES[ptyp]

    writeproto(io, val, attrib, wfn)
end

function writeproto(io::IO, val::Array{T}, attrib::ProtoMetaAttribs, wfn::F) where {T,F}
    fld = attrib.fldnum
    meta = attrib.meta
    ptyp = attrib.ptyp
    wiretyp, _wfn, _rfn, jtyp = WIRETYPES[ptyp]
    iob = IOBuffer()

    n = 0
    (attrib.occurrence == 2) || error("expected meta attributes of $(attrib.fld) to specify an array")
    if attrib.packed
        # write elements as a length delimited field
        if ptyp === :obj
            error("can not write object field $fld as packed")
        else
            for eachval in val
                wfn(iob, convert(jtyp, eachval))
            end
        end
        n += _write_key(io, fld, WIRETYP_LENDELIM)
        n += write_bytes(io, take!(iob))
    else
        # write each element separately
        # maps can not be repeated
        if ptyp === :obj
            for eachval in val
                wfn(iob, convert(jtyp, eachval), meta)
                n += _write_key(io, fld, WIRETYP_LENDELIM)
                n += write_bytes(io, take!(iob))
            end
        else
            for eachval in val
                n += _write_key(io, fld, wiretyp)
                n += wfn(io, convert(jtyp, eachval))
            end
        end
    end
    n
end

function writeproto(io::IO, obj, meta::ProtoMeta=meta(typeof(obj)))
    n = 0
    @debug("writeproto writing an obj", meta)
    for attrib in meta.ordered
        fld = attrib.fld
        if hasproperty(obj, fld)
            @debug("writeproto", field=fld)
            n += writeproto(io, getproperty(obj, fld), attrib)
        else
            @debug("not set", field=fld)
            (attrib.occurrence == 1) && error("missing required field $fld (#$(attrib.fldnum))")
        end
    end
    n
end

function read_lendelim_packed(io, fld, reader, jtyp::Type)
    iob = IOBuffer(read_bytes(io))
    while !eof(iob)
        val = reader(iob, jtyp)
        push!(fld, val)
    end
    nothing
end

function read_lendelim_obj(io, val, meta::ProtoMeta, reader)
    fld_buf = read_bytes(io)
    reader(IOBuffer(fld_buf), val, meta)
    val
end

instantiate(t::Type) = ccall(:jl_new_struct_uninit, Any, (Any,), t)
instantiate(t::Type{T}) where {T <: ProtoType} = T()

function skip_field(io::IO, wiretype::Integer)
    if wiretype == WIRETYP_LENDELIM
        read_bytes(io)
    elseif wiretype == WIRETYP_64BIT
        read_fixed(io, UInt64)
    elseif wiretype == WIRETYP_32BIT
        read_fixed(io, UInt32)
    elseif wiretype == WIRETYP_VARINT
        read_varint(io, UInt64)
    end
    nothing
end

function read_field(io, container, attrib::ProtoMetaAttribs, wiretyp, jtyp_specific)
    ptyp = attrib.ptyp
    fld = attrib.fld

    _wiretyp, wfn, rfn, jtyp = WIRETYPES[ptyp]
    isrepeat = (attrib.occurrence == 2)

    if jtyp_specific !== nothing
        jtyp = jtyp_specific
    elseif ptyp === :obj
        jtyp = attrib.meta.jtype
    elseif ptyp === :map
        jtyp = attrib.meta.jtype
    end

    if isrepeat
        arr_val = ((container !== nothing) && hasproperty(container, fld)) ? convert(Vector{jtyp}, getproperty(container, fld)) : jtyp[]
        # Readers should accept repeated fields in both packed and expanded form.
        # Allows compatibility with old writers when [packed = true] is added later.
        # Only repeated fields of primitive numeric types (isbitstype == true) can be declared "packed".
        # Maps can not be repeated
        if isbitstype(jtyp) && (wiretyp == WIRETYP_LENDELIM)
            read_lendelim_packed(io, arr_val, rfn, jtyp)
        elseif ptyp === :obj
            push!(arr_val, read_lendelim_obj(io, instantiate(jtyp), attrib.meta, rfn))
        else
            push!(arr_val, rfn(io, jtyp))
        end
        return arr_val
    else
        (wiretyp != _wiretyp) && !isrepeat && error("cannot read wire type $wiretyp as $ptyp")

        if ptyp === :obj
            val_obj = ((container !== nothing) && hasproperty(container, fld)) ? getproperty(container, fld) : instantiate(jtyp)
            return read_lendelim_obj(io, val_obj, attrib.meta, rfn)
        elseif ptyp === :map
            val_map = ((container !== nothing) && hasproperty(container, fld)) ? convert(jtyp, getproperty(container, fld)) : jtyp()
            return read_map(io, val_map)
        else
            @debug("reading", jtyp)
            return rfn(io, jtyp)
        end
    end
end

function readproto(io::IO, obj, meta::ProtoMeta=meta(typeof(obj)))
    @debug("readproto begin", typ=typeof(obj))
    clear(obj)
    while !eof(io)
        fldnum, wiretyp = _read_key(io)
        @debug("reading", typ=typeof(obj), fldnum)

        fldnum = Int(fldnum)
        attrib = get(meta.numdict, fldnum, nothing)

        # ignore unknown fields
        if attrib === nothing
            @debug("skipping unknown field", typ=typeof(obj), fldnum)
            skip_field(io, wiretyp)
            continue
        end

        val = read_field(io, obj, attrib, wiretyp, nothing)
        fld = attrib.fld
        if (attrib.occurrence == 2) || (attrib.ptyp === :obj) || (attrib.ptyp === :map)
            setproperty!(obj, fld, convert(attrib.jtyp, val))
        else
            setproperty!(obj, fld, val)
        end
    end

    setdefaultproperties!(obj, meta)
    @debug("readproto end", typ=typeof(obj))

    obj
end

function setdefaultproperties!(obj::ProtoType, meta::ProtoMeta=meta(typeof(obj)))
    for (idx,attrib) in enumerate(meta.ordered)
        fld = attrib.fld
        # TODO: do not fill if oneof the fields in the oneof
        if !hasproperty(obj, fld) && !isempty(attrib.default) && !_isset_oneof(obj, idx)
            default = attrib.default[1]
            setproperty!(obj, fld, convert(attrib.jtyp, deepcopy(default)))
            @debug("readproto set default", typ=typeof(obj), fld, default)
            _markdefaultproperty!(obj, fld)
        end
    end
    obj
 end

##
# helpers
const DEF_REQ = Symbol[]
const DEF_FNUM = Int[]
const DEF_VAL = Dict{Symbol,Any}()
const DEF_PACK = Symbol[]
const DEF_WTYPES = Dict{Symbol,Symbol}()
const DEF_ONEOFS = Int[]
const DEF_ONEOF_NAMES = Symbol[]
const DEF_FIELD_TYPES = Dict{Symbol,String}()

function metalock(f)
    lock(MetaLock) do
        f()
    end
end

_resolve_type(relativeto::Type, typ::Type) = typ
_resolve_type(relativeto::Type, typ::String) = Core.eval(relativeto.name.module, Meta.parse(typ))

function meta(target::ProtoMeta, typ::Type, all_fields::Vector{Pair{Symbol,Union{Type,String}}}, required::Vector{Symbol}, numbers::Vector{Int}, defaults::Dict{Symbol,Any},
        pack::Vector{Symbol}=DEF_PACK, wtypes::Dict=DEF_WTYPES, oneofs::Vector{Int}=DEF_ONEOFS, oneof_names::Vector{Symbol}=DEF_ONEOF_NAMES)
    attribs = ProtoMetaAttribs[]
    for fldidx in 1:length(all_fields)
        fldname = first(all_fields[fldidx])
        fldtyp = _resolve_type(typ, last(all_fields[fldidx]))
        fldnum = isempty(numbers) ? fldidx : numbers[fldidx]
        isarr = (fldtyp <: Array) && !(fldtyp === Vector{UInt8})
        repeat = isarr ? 2 : (fldname in required) ? 1 : 0

        elemtyp = isarr ? eltype(fldtyp) : fldtyp
        wtyp = get(wtypes, fldname, wiretype(elemtyp))
        packed = (isarr && (fldname in pack))
        default = haskey(defaults, fldname) ? Any[defaults[fldname]] : defaultval(fldtyp)

        fldmeta = (wtyp == :obj) ? meta(elemtyp) :
                  (wtyp == :map) ? mapentry_meta(elemtyp) : nothing
        push!(attribs, ProtoMetaAttribs(fldnum, fldname, wtyp, fldtyp, repeat, packed, default, fldmeta))
    end
    setprotometa!(target, typ, attribs, oneofs, oneof_names)
end

function mapentry_meta(typ::Type{Dict{K,V}}) where {K,V}
    target = ProtoMeta(typ)
    attribs = ProtoMetaAttribs[]
    push!(attribs, ProtoMetaAttribs(1, :key, wiretype(K), K, 0, false, defaultval(K), nothing))

    isarr = (V <: Array) && !(V === Vector{UInt8})
    repeat = isarr ? 2 : 0
    packed = isarr
    wtyp = wiretype(V)
    vmeta = (wtyp == :obj) ? meta(V) :
            (wtyp == :map) ? mapentry_meta(V) : nothing
    push!(attribs, ProtoMetaAttribs(2, :value, wtyp, V, repeat, packed, defaultval(V), vmeta))

    setprotometa!(target, typ, attribs, DEF_ONEOFS, DEF_ONEOF_NAMES)
end

function isfilled(obj)
    fldattribs = meta(typeof(obj)).ordered
    for idx in 1:length(fldattribs)
        fldattrib = fldattribs[idx]
        if fldattrib.occurrence == 1
            fldname = fldattrib.fld
            hasproperty(obj, fldname) || (return false)
            (fldattrib.meta !== nothing) && !isfilled(getproperty(obj, fldname)) && (return false)
        end
    end
    true
end

function _isset_oneof(obj, idx::Int)
    m = meta(typeof(obj))
    oneofs = m.oneofs
    oneof_idx = isempty(oneofs) ? 0 : oneofs[idx]
    (oneof_idx > 0) || (return false)
    _which_oneof(obj, m, oneof_idx) !== Symbol()
end

function which_oneof(obj, oneof::Symbol)
    m = meta(typeof(obj))
    oneof_idx = something(findfirst(isequal(oneof), m.oneof_names))
    _which_oneof(obj, m, oneof_idx)
end

function _which_oneof(obj, m, oneof_idx)
    oneofs = m.oneofs
    for idx in 1:length(oneofs)
        if oneofs[idx] == oneof_idx
            fldname = m.ordered[idx].fld
            hasproperty(obj, fldname) && (return fldname)
        end
    end
    Symbol()
end

function _unset_oneof(obj, objmeta, fld)
    if !isempty(objmeta.oneofs)
        fldidx = 1
        while fldidx <= length(objmeta.ordered)
            if objmeta.ordered[fldidx].fld === fld
                break
            else
                fldidx += 1
            end
        end
        nameidx = objmeta.oneofs[fldidx]
        if nameidx > 0
            oneofprop = which_oneof(obj, objmeta.oneof_names[nameidx])
            (oneofprop === Symbol()) || clear(obj, oneofprop)
        end
    end
end

function show(io::IO, m::ProtoMeta)
    println(io, "ProtoMeta for $(m.jtype)")
    println(io, m.ordered)
end

propertynames(obj::ProtoType) = [attrib.fld for attrib in obj.__protobuf_jl_internal_meta.ordered]
hasproperty(obj::ProtoType, fld::Symbol) = haskey(obj.__protobuf_jl_internal_values, fld)
function setproperty!(obj::ProtoType, fld::Symbol, val)
    objmeta = obj.__protobuf_jl_internal_meta
    symdict = objmeta.symdict
    if fld in keys(symdict)
        _unset_oneof(obj, objmeta, fld)
        fldtype = symdict[fld].jtyp
        obj.__protobuf_jl_internal_values[fld] = isa(val, fldtype) ? val : convert(fldtype, val)
        delete!(obj.__protobuf_jl_internal_defaultset, fld)
    else
        setfield!(obj, fld, val)
    end
end
_markdefaultproperty!(obj::ProtoType, fld::Symbol) = push!(obj.__protobuf_jl_internal_defaultset, fld)
isdefaultproperty(obj::ProtoType, fld::Symbol) = fld in obj.__protobuf_jl_internal_defaultset

function clear(obj::ProtoType)
    empty!(obj.__protobuf_jl_internal_values)
    nothing
end

function clear(obj::ProtoType, fld::Symbol)
    delete!(obj.__protobuf_jl_internal_values, fld)
    nothing
end

##
# Enum Lookup
function lookup(en::T, val) where {T <: NamedTuple}
    for name in propertynames(en)
        (val == getproperty(en, name)) && return name
    end
    error("Enum has no value $val")
end


text:
import PlutoSliderServer

just_run_test_server = false
ENV["JULIA_DEBUG"] = PlutoSliderServer

if just_run_test_server
    include("./runtestserver.jl")
else
    ENV["HIDE_PLUTO_EXACT_VERSION_WARNING"] = "true"
    include("./configuration.jl")
    include("./static export.jl")
    include("./staterequest.jl")
    include("./filewatching.jl")
    include("./connections.jl")
end

ext: jl


text:
    export model_put
    """

        julia> model_put(aws,bucket,path,model_array,origins,deltas;[level])

    Stores a model array to AWS S3 bucket.

    # Signature

        function model_put{AT<:Number,OT<:Number,DT<:Number}(aws::AWSCore.AWSConfig,bucket::String,path::String,
            a::DenseArray{AT},origins::Vector{OT},deltas::Vector{DT};
            level::Int=1,max_size::Int=2000)

    # Arguments

    - `aws`: aws config created by AWSCore.aws_config
    - `bucket`: name of AWS S3 bucket
    - `path`: file key/path name
    - `model_array`: dense numeric array
    - `level`: Blosc compression level (0-9); 1 is typically OK, anything above 5 is typically an over-kill
    - `max_size`: maximum array size (MB<=2000) before going into multi-part mode

    # Examples

    - `model_put(aws,"slimbucket","tmp/test/small",a)`: put model `a` into bucket `slimbucket` under path `tmp/test/small`

    # Notes:

    - use `model_delete` to delete object created with `model_put`

    """
    function model_put(aws::AWSCore.AWSConfig,bucket::String,path::String,
            a::DenseArray{AT},os::Vector{OT},ds::Vector{DT};
            level::Int=1,max_size::Int=2000) where {AT<:Number,OT<:Number,DT<:Number}
        max_size > 2000 && warn("AWSS3/model_put: given max_size > 2000; using default 2000")
        cmp_max=min(2000*1024^2,max_size*1024^2) #blosc compression max 2147483631 bytes < (2*1024^3)
        szs=size(a)
        dims=length(szs)
        length(os)==dims || error("AWSS3/model_put: length of origins does not match array dimensions")
        length(ds)==dims || error("AWSS3/model_put: length of deltas does not match array dimensions")
        if sizeof(a)<cmp_max # single file
            tags=Dict("creator"=>"S3-SLIM","type"=>"Model")
                tags["eltype"]="$(AT)"
                tags["dims"]="$(dims)"
                tags["ns"]=join(map(i->(@sprintf "%d" szs[i]),1:dims),":")
                tags["os"]=join(map(i->(@sprintf "%f" os[i]),1:dims),":")
                tags["ds"]=join(map(i->(@sprintf "%f" ds[i]),1:dims),":")
            ac=Blosc.compress(vec(a);level=level);
            s3_put(aws, bucket, path, ac, tags=tags);
            return nothing
        else # multi-part files
            #warn("AWSS3/model_put: large array - going into multi-part mode";key="AWS S3 model_put",once=true)
            (nfiles,nelmts,parts,idxs,idxe)=file_parts(a,cmp_max)
                tags=Dict("creator"=>"S3-SLIM","type"=>"metaModel")
                tags["nfiles"]="$(nfiles)"
                tags["nelmts"]="$(nelmts)"
                tags["eltype"]="$(AT)"
                tags["dims"]="$(dims)"
                tags["ns"]=join(map(i->(@sprintf "%d" szs[i]),1:dims),":")
                tags["os"]=join(map(i->(@sprintf "%f" os[i]),1:dims),":")
                tags["ds"]=join(map(i->(@sprintf "%f" ds[i]),1:dims),":")
            #println((nfiles,nelmts,parts,idxs,idxe))
            #for i=1:nfiles println((i,parts[i],idxs[i],idxe[i])) end
            av=vec(a)
            for i=1:nfiles
                ppath=@sprintf("%s-parts/%6.6d",path,i)
                #println(ppath)
                pc=Blosc.compress(av[idxs[i]:idxe[i]];level=level);
                s3_put(aws, bucket, ppath, pc);
            end
            d=[parts idxs idxe]
            dc=Blosc.compress(vec(d);level=level);
            s3_put(aws, bucket, path, dc, tags=tags);
            return nothing
        end
    end

    export model_get
    """

        julia> model_get(aws,bucket,path;delete=false)

    Reads from AWS S3 bucket a model array stored by `model_put`.

    # Signature

        function model_get(aws::AWSCore.AWSConfig,
            bucket::String,path::String;delete::Bool=false)

    # Arguments

    - `aws`: aws config created by AWSCore.aws_config
    - `bucket`: name of AWS S3 bucket
    - `path`: file key/path name
    - `delete`: delete file key/path after reading

    # Examples

    - `(A,o,d)=model_get(aws,"slimbucket","tmp/test/small")`: gets model_array `a`, origins `o`, and deltas `d` from bucket `slimbucket` and path `tmp/test/small`

    # Notes:

    - use `model_delete` to delete object created with `model_put`

    """
    function model_get(aws::AWSCore.AWSConfig,bucket::String,path::String;delete::Bool=false)
        s3_exists(aws, bucket, path) || error("AWSS3/model_get: file $path does not exist in $bucket.")
        tags=s3_get_tags(aws, bucket, path);
        (haskey(tags,"creator")&&tags["creator"]=="S3-SLIM") || error("AWSS3/model_get: file $path in $bucket is unknown.")
        haskey(tags,"type") || error("AWSS3/model_get: file $path in $bucket does not have known type.")
        if tags["type"]=="Model" # single file
            eval(Meta.parse("edt=$(tags["eltype"])"))
            eval(Meta.parse("dims=$(tags["dims"])"))
            szs=parse.(Int,split(tags["ns"],":"))
            os=parse.(Float64,split(tags["os"],":"))
            ds=parse.(Float64,split(tags["ds"],":"))
            ac=s3_get(aws, bucket, path);
            a=reshape(Blosc.decompress(edt,ac),(szs...,));
            delete && model_delete(aws, bucket, path);
            return a,os,ds
        elseif tags["type"]=="metaModel" # multi-part files
            eval(parse("nfiles=$(tags["nfiles"])"))
            eval(parse("nelmts=$(tags["nelmts"])"))
            eval(parse("edt=$(tags["eltype"])"))
            eval(parse("dims=$(tags["dims"])"))
            szs=parse.(Int,split(tags["ns"],":"))
            os=parse.(Float64,split(tags["os"],":"))
            ds=parse.(Float64,split(tags["ds"],":"))
            dc=s3_get(aws, bucket, path);
            d=reshape(Blosc.decompress(Int,dc),(nfiles,3));
            parts=d[:,1]; idxs=d[:,2]; idxe=d[:,3];
            #println((nfiles,nelmts,parts,idxs,idxe))
            #for i=1:nfiles println((i,parts[i],idxs[i],idxe[i])) end
            av=Vector{edt}(nelmts)
            for i=1:nfiles
                ppath=@sprintf("%s-parts/%6.6d",path,i)
                #println(ppath)
                pc=s3_get(aws, bucket, ppath);
                av[idxs[i]:idxe[i]]=Blosc.decompress(edt,pc)
            end
            a=reshape(av,(szs...,))
            delete && model_delete(aws, bucket, path);
            return a,os,ds
        else
            error("AWSS3/model_get: file $path in $bucket is not an model stored with model_put.")
        end
    end

    export model_delete
    """

        julia> model_delete(aws,bucket,path)

    Deletes from AWS S3 bucket a model array stored by `model_put`.

    # Signature

        function model_delete(aws::AWSCore.AWSConfig,
            bucket::String,path::String)

    # Arguments

    - `aws`: aws config created by AWSCore.aws_config
    - `bucket`: name of AWS S3 bucket
    - `path`: file key/path name

    # Examples

    - `model_delete(aws,"slimbucket","tmp/test/small")`: deletes model_array stored by `model_put` as `tmp/test/small` and bucket `slimbucket`

    """
    function model_delete(aws::AWSCore.AWSConfig,bucket::String,path::String)

        s3_exists(aws, bucket, path) || error("AWSS3/model_delete: file $path does not exist in $bucket.")
        tags=s3_get_tags(aws, bucket, path);
        (haskey(tags,"creator")&&tags["creator"]=="S3-SLIM") || error("AWSS3/model_delete: file $path in $bucket is unknown.")
        haskey(tags,"type") || error("AWSS3/model_delete: file $path in $bucket does not have known type.")
        if tags["type"]=="Model" # single file
            s3_delete(aws,bucket,path)
        elseif tags["type"]=="metaModel" # multi-part files
            eval(parse("nfiles=$(tags["nfiles"])"))
            for i=1:nfiles
                ppath=@sprintf("%s-parts/%6.6d",path,i)
                s3_delete(aws,bucket,ppath)
            end
            s3_delete(aws,bucket,path)
        else
            error("AWSS3/model_delete: file $path in $bucket is not an array.")
        end
        return nothing
    end


text:
# Sze, S. M., & Irvin, J. C. (1968). Resistivity, mobility and impurity levels in GaAs, Ge, and Si at 300°K. Solid-State Electronics, 11(6), 599–602.
# https://doi.org/10.1016/0038-1101(68)90012-9

const nSi_data = [99873827497317.61  49.302642963526765
148082468167739.22  32.09212960738206
194131379643419.66  23.701262528656034
242272374546063.44  18.41120725607611
295011986797974.1  15.042876700010876
341972739340117.8  12.927583972484706
386759998735408.8  11.250926818107038
482680213609803.8  8.850820775847145
681344367356955.5  6.373640569764252
871577399973363.6  5.077702778971148
1426020583647375.2  2.9875826376787464
1916322544065341  2.32076257838392
2391696881466672  1.8723838269268553
3376160637548445.5  1.3654737756744455
4766169032891821  1.0342492830690573
5804226768950241  0.8888156648487106
7799866801191494  0.6904345031490022
9977608904425678  0.55005003136958
14436595430096552  0.40623294112544817
19399387500631524  0.3076925647367394
28768571539470620  0.22157513560466263
38661677607382260  0.1765227689725715
48255586346090580  0.1479170652237846
66466370588408696  0.11490239143391535
96178818707792260  0.08925650016959505
146210990420867400  0.06933469985354365
191729795804511970  0.05958502302708236
284366633707162270  0.04628581312844892
382216623835435300  0.04028272392839588
581058613569092200  0.03168940440349858
780982113332051600  0.027233317445456286
951163515531508400  0.024616418285271273
1410858227982555100  0.020112844307861498
1896203469292910000  0.01685353634909295
2367067191346242600  0.015234049292239822
3780028792783300000  0.011250926818107056
5606653507564298000  0.0089633015456371
8735277100246356000  0.0066197402807380455
11739215713144541000  0.005273763597374311
15391818257565354000  0.004201461281180297
19690139795062202000  0.0034328038967573337
26458915031288810000  0.0026001048371539098
33023214942238142000  0.002124415630566529
46615089780956150000  0.0015298311866137819
76289339181933120000  0.0010473930533995747
142970417462953750000  0.000656424290624687
194524429315225260000  0.0005296010185684199
281508030652849300000  0.00043271050679719644
378348790665551940000  0.00036258930578458696
484115663944655040000  0.00033613073619570826
683648003445255200000  0.0003038313204882885
896644873962979500000  0.0002888648497597531 ]


text:
# tc.jl
#
# author: Wade Shen
# swade@ll.mit.edu
# Copyright © 2014 Massachusetts Institute of Technology, Lincoln Laboratory
# version 0.1
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
export tc_train, lid_tokenizer, lid_iterating_tokenizer

Base.iteratorsize{T}(::Type{IterTools.Chain{T}}) = Base.SizeUnknown()

# -------------------------------------------------------------------------------------------------------------------------
# LID
# -------------------------------------------------------------------------------------------------------------------------
function lid_iterating_tokenizer(text)
  x   = strip(text)
  if x == ""
    return []
  end
  res = chain(split(x, default_space),
              ngram_iterator(x, order = 1),
              ngram_iterator(x, order = 2),
              ngram_iterator(x, order = 3)
              )
  return res
end

function lid_tokenizer(text)
  x   = strip(text)
  if x == ""
    return []
  end
  res = split(x, default_space)
  ngrams!(res, x, order = 1)
  ngrams!(res, x, order = 2)
  ngrams!(res, x, order = 3)
  return res
end

# -------------------------------------------------------------------------------------------------------------------------
# training for text classifiers
# -------------------------------------------------------------------------------------------------------------------------
function tc_features(text, bkgmodel)
  counts = sparse_count(text, bkgmodel)
  total = sum(counts)
  if total != 0.0
    counts /= sum(counts)
  end
  return apply(bkgmodel, counts)
end

function tc_train(text, truth, preprocess::Function; cutoff = 1e10, mincount = 2, prune = 0.0,
                  iteration_method = :lazy,
                  trainer = (fvs, truth, init_model) -> train_mira(fvs, truth, init_model, iterations = 3, average = true),
                  logger = Log(STDERR))
  mapper = iteration_method == :eager ? map : lazy_map

  # define class index
  classes = Dict{AbstractString, Int32}()
  i       = 1
  @timer logger "indexing truth" for t in truth
    if !(t in keys(classes))
      classes[t] = i
      i += 1
    end
  end

  # prep model
  @timer logger "preprocessing input"     preprocessed_text = mapper(preprocess, text)
  @timer logger "making background model" bkgmodel          = make_background(preprocessed_text, mincount = mincount, prune = prune,
                                                                              norm = stats -> tfnorm(stats, squash = sqrt, cutoff = cutoff))
  @timer logger "making feature vectors"  fvs               = mapper(text -> tc_features(text, bkgmodel), preprocessed_text)
  @timer logger "initializating model"    init_model        = LinearModel(classes, vocab_size(bkgmodel))
  @timer logger "training final model"    model             = trainer(fvs, truth, init_model)

  return bkgmodel, ptext -> tc_features(ptext, bkgmodel), model
end


text:
gausslegendre(n::Int) = gausslegendre(Float64, n)
gausslegendre(::Type{Float64}, n) = FastGaussQuadrature.gausslegendre(n)
gausslegendre(::Type{T}, n) where {T} = GaussQuadrature.legendre(T, n)

gausslaguerre(n::Int) = gausslaguerre(Float64, n)
gausslaguerre(n::Int, α::T) where {T<:AbstractFloat} = gausslaguerre(T, n, α)
gausslaguerre(n::Int, α) = gausslaguerre(n, float(α))
gausslaguerre(::Type{T}, n::Int) where {T} = gausslaguerre(T, n, zero(T))
gausslaguerre(::Type{Float64}, n, α) = FastGaussQuadrature.gausslaguerre(n, α)

gaussjacobi(n::Int) = gaussjacobi(Float64, n)
gaussjacobi(n::Int, α::Number, β::Number) = gaussjacobi(n, promote(α, β)...)
gaussjacobi(n::Int, α::N, β::N) where {N<:Number} = gaussjacobi(n, float(α), float(β))
gaussjacobi(n::Int, α::T, β::T) where {T<:AbstractFloat} =
    gaussjacobi(T, n, α, β)
gaussjacobi(::Type{T}, n::Int) where {T} = gaussjacobi(T, n, zero(T), zero(T))
gaussjacobi(::Type{Float64}, n, α, β) = FastGaussQuadrature.gaussjacobi(n, α, β)

gausshermite(n::Int) = gausshermite(Float64, n)
gausshermite(::Type{Float64}, n) = FastGaussQuadrature.gausshermite(n)


text:
SetIndex(idx) = Optic(
    obj->(obj, getindex(obj, idx)),
    (obj, update)->setindex(obj, update, idx)
)


text:
using JuMP, EAGO

                     m = Model()

                     EAGO.register_eago_operators!(m)

                     @variable(m, -1 <= x[i=1:3] <= 1)

                     @variable(m, -12.75118444054646 <= q <= 9.039664285972906)

                     add_NL_constraint(m, :((0.715796138346545 + -0.1516695982843861*(-0.317423658088571 + -0.8843064794993589*(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3]))/(1 + exp(-(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3])))) + 0.6219431368805965*(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3]))/(1 + exp(-(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3])))) + -0.24757066957523488*(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3]))/(1 + exp(-(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3])))))/(1 + exp(-(-0.317423658088571 + -0.8843064794993589*(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3]))/(1 + exp(-(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3])))) + 0.6219431368805965*(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3]))/(1 + exp(-(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3])))) + -0.24757066957523488*(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3]))/(1 + exp(-(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3]))))))) + -0.0820632819191216*(-0.8960501996212993 + -0.7682728024607406*(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3]))/(1 + exp(-(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3])))) + -0.3378399703859083*(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3]))/(1 + exp(-(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3])))) + 0.4153867033969405*(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3]))/(1 + exp(-(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3])))))/(1 + exp(-(-0.8960501996212993 + -0.7682728024607406*(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3]))/(1 + exp(-(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3])))) + -0.3378399703859083*(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3]))/(1 + exp(-(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3])))) + 0.4153867033969405*(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3]))/(1 + exp(-(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3]))))))) + -0.0571486344530765*(0.054021626349418206 + -0.05819989275612114*(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3]))/(1 + exp(-(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3])))) + 0.8875139231924525*(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3]))/(1 + exp(-(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3])))) + 0.11280184637312685*(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3]))/(1 + exp(-(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3])))))/(1 + exp(-(0.054021626349418206 + -0.05819989275612114*(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3]))/(1 + exp(-(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3])))) + 0.8875139231924525*(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3]))/(1 + exp(-(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3])))) + 0.11280184637312685*(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3]))/(1 + exp(-(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3]))))))))/(1 + exp(-(0.715796138346545 + -0.1516695982843861*(-0.317423658088571 + -0.8843064794993589*(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3]))/(1 + exp(-(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3])))) + 0.6219431368805965*(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3]))/(1 + exp(-(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3])))) + -0.24757066957523488*(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3]))/(1 + exp(-(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3])))))/(1 + exp(-(-0.317423658088571 + -0.8843064794993589*(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3]))/(1 + exp(-(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3])))) + 0.6219431368805965*(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3]))/(1 + exp(-(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3])))) + -0.24757066957523488*(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3]))/(1 + exp(-(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3]))))))) + -0.0820632819191216*(-0.8960501996212993 + -0.7682728024607406*(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3]))/(1 + exp(-(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3])))) + -0.3378399703859083*(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3]))/(1 + exp(-(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3])))) + 0.4153867033969405*(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3]))/(1 + exp(-(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3])))))/(1 + exp(-(-0.8960501996212993 + -0.7682728024607406*(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3]))/(1 + exp(-(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3])))) + -0.3378399703859083*(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3]))/(1 + exp(-(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3])))) + 0.4153867033969405*(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3]))/(1 + exp(-(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3]))))))) + -0.0571486344530765*(0.054021626349418206 + -0.05819989275612114*(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3]))/(1 + exp(-(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3])))) + 0.8875139231924525*(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3]))/(1 + exp(-(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3])))) + 0.11280184637312685*(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3]))/(1 + exp(-(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3])))))/(1 + exp(-(0.054021626349418206 + -0.05819989275612114*(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3]))/(1 + exp(-(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3])))) + 0.8875139231924525*(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3]))/(1 + exp(-(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3])))) + 0.11280184637312685*(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3]))/(1 + exp(-(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3])))))))))) + (-0.8464220616292248 + -0.9331432460947604*(-0.317423658088571 + -0.8843064794993589*(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3]))/(1 + exp(-(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3])))) + 0.6219431368805965*(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3]))/(1 + exp(-(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3])))) + -0.24757066957523488*(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3]))/(1 + exp(-(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3])))))/(1 + exp(-(-0.317423658088571 + -0.8843064794993589*(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3]))/(1 + exp(-(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3])))) + 0.6219431368805965*(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3]))/(1 + exp(-(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3])))) + -0.24757066957523488*(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3]))/(1 + exp(-(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3]))))))) + 0.425513343659472*(-0.8960501996212993 + -0.7682728024607406*(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3]))/(1 + exp(-(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3])))) + -0.3378399703859083*(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3]))/(1 + exp(-(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3])))) + 0.4153867033969405*(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3]))/(1 + exp(-(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3])))))/(1 + exp(-(-0.8960501996212993 + -0.7682728024607406*(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3]))/(1 + exp(-(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3])))) + -0.3378399703859083*(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3]))/(1 + exp(-(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3])))) + 0.4153867033969405*(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3]))/(1 + exp(-(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3]))))))) + 0.1421259709107252*(0.054021626349418206 + -0.05819989275612114*(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3]))/(1 + exp(-(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3])))) + 0.8875139231924525*(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3]))/(1 + exp(-(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3])))) + 0.11280184637312685*(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3]))/(1 + exp(-(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3])))))/(1 + exp(-(0.054021626349418206 + -0.05819989275612114*(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3]))/(1 + exp(-(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3])))) + 0.8875139231924525*(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3]))/(1 + exp(-(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3])))) + 0.11280184637312685*(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3]))/(1 + exp(-(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3]))))))))/(1 + exp(-(-0.8464220616292248 + -0.9331432460947604*(-0.317423658088571 + -0.8843064794993589*(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3]))/(1 + exp(-(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3])))) + 0.6219431368805965*(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3]))/(1 + exp(-(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3])))) + -0.24757066957523488*(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3]))/(1 + exp(-(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3])))))/(1 + exp(-(-0.317423658088571 + -0.8843064794993589*(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3]))/(1 + exp(-(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3])))) + 0.6219431368805965*(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3]))/(1 + exp(-(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3])))) + -0.24757066957523488*(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3]))/(1 + exp(-(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3]))))))) + 0.425513343659472*(-0.8960501996212993 + -0.7682728024607406*(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3]))/(1 + exp(-(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3])))) + -0.3378399703859083*(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3]))/(1 + exp(-(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3])))) + 0.4153867033969405*(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3]))/(1 + exp(-(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3])))))/(1 + exp(-(-0.8960501996212993 + -0.7682728024607406*(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3]))/(1 + exp(-(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3])))) + -0.3378399703859083*(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3]))/(1 + exp(-(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3])))) + 0.4153867033969405*(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3]))/(1 + exp(-(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3]))))))) + 0.1421259709107252*(0.054021626349418206 + -0.05819989275612114*(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3]))/(1 + exp(-(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3])))) + 0.8875139231924525*(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3]))/(1 + exp(-(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3])))) + 0.11280184637312685*(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3]))/(1 + exp(-(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3])))))/(1 + exp(-(0.054021626349418206 + -0.05819989275612114*(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3]))/(1 + exp(-(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3])))) + 0.8875139231924525*(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3]))/(1 + exp(-(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3])))) + 0.11280184637312685*(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3]))/(1 + exp(-(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3])))))))))) + (-0.5205460270098605 + 0.13812073353255405*(-0.317423658088571 + -0.8843064794993589*(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3]))/(1 + exp(-(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3])))) + 0.6219431368805965*(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3]))/(1 + exp(-(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3])))) + -0.24757066957523488*(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3]))/(1 + exp(-(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3])))))/(1 + exp(-(-0.317423658088571 + -0.8843064794993589*(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3]))/(1 + exp(-(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3])))) + 0.6219431368805965*(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3]))/(1 + exp(-(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3])))) + -0.24757066957523488*(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3]))/(1 + exp(-(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3]))))))) + 0.7749706249828683*(-0.8960501996212993 + -0.7682728024607406*(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3]))/(1 + exp(-(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3])))) + -0.3378399703859083*(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3]))/(1 + exp(-(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3])))) + 0.4153867033969405*(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3]))/(1 + exp(-(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3])))))/(1 + exp(-(-0.8960501996212993 + -0.7682728024607406*(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3]))/(1 + exp(-(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3])))) + -0.3378399703859083*(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3]))/(1 + exp(-(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3])))) + 0.4153867033969405*(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3]))/(1 + exp(-(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3]))))))) + 0.5007112790542019*(0.054021626349418206 + -0.05819989275612114*(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3]))/(1 + exp(-(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3])))) + 0.8875139231924525*(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3]))/(1 + exp(-(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3])))) + 0.11280184637312685*(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3]))/(1 + exp(-(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3])))))/(1 + exp(-(0.054021626349418206 + -0.05819989275612114*(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3]))/(1 + exp(-(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3])))) + 0.8875139231924525*(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3]))/(1 + exp(-(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3])))) + 0.11280184637312685*(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3]))/(1 + exp(-(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3]))))))))/(1 + exp(-(-0.5205460270098605 + 0.13812073353255405*(-0.317423658088571 + -0.8843064794993589*(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3]))/(1 + exp(-(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3])))) + 0.6219431368805965*(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3]))/(1 + exp(-(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3])))) + -0.24757066957523488*(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3]))/(1 + exp(-(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3])))))/(1 + exp(-(-0.317423658088571 + -0.8843064794993589*(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3]))/(1 + exp(-(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3])))) + 0.6219431368805965*(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3]))/(1 + exp(-(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3])))) + -0.24757066957523488*(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3]))/(1 + exp(-(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3]))))))) + 0.7749706249828683*(-0.8960501996212993 + -0.7682728024607406*(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3]))/(1 + exp(-(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3])))) + -0.3378399703859083*(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3]))/(1 + exp(-(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3])))) + 0.4153867033969405*(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3]))/(1 + exp(-(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3])))))/(1 + exp(-(-0.8960501996212993 + -0.7682728024607406*(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3]))/(1 + exp(-(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3])))) + -0.3378399703859083*(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3]))/(1 + exp(-(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3])))) + 0.4153867033969405*(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3]))/(1 + exp(-(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3]))))))) + 0.5007112790542019*(0.054021626349418206 + -0.05819989275612114*(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3]))/(1 + exp(-(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3])))) + 0.8875139231924525*(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3]))/(1 + exp(-(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3])))) + 0.11280184637312685*(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3]))/(1 + exp(-(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3])))))/(1 + exp(-(0.054021626349418206 + -0.05819989275612114*(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3]))/(1 + exp(-(0.5491785730840042 + -0.947600132880416*$(x[1]) + -0.5975167017748926*$(x[2]) + -0.008573066442256305*$(x[3])))) + 0.8875139231924525*(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3]))/(1 + exp(-(0.2436152968029921 + 0.15213749662876674*$(x[1]) + -0.7774236630629989*$(x[2]) + 0.8200325525995154*$(x[3])))) + 0.11280184637312685*(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3]))/(1 + exp(-(-0.7915430864078541 + -0.04671642019396449*$(x[1]) + 0.6799142288942424*$(x[2]) + 0.9251799998319439*$(x[3])))))))))) - $q <= 0.0))

                     @objective(m, Min, q)

                     return m

max_stars_repo_name: PSORLab/RSActivationFunctions

max_issues_repo_name: PSORLab/RSActivationFunctions

max_forks_repo_name: PSORLab/RSActivationFunctions


text:
#
# The bare type of a value or an object in the database.
#

# Aliases for special data types.

typealias None Union{}

# Domain decorations.

typealias Decoration Pair{Symbol,Any}
typealias Decorations Vector{Decoration}

const NO_DECORATIONS = Decoration[]

function decoration{T}(decors::Decorations, name::Symbol, ::Type{T}, default::T)
    for (n, v) in decors
        if n == name && isa(v, T)
            return v::T
        end
    end
    return default
end

function decorate(decors::Decorations, d::Decoration)
    decors = copy(decors)
    for k in eachindex(decors)
        n = decors[k].first
        if n >= d.first
            if n == d.first
                decors[k] = d
            else
                insert!(decors, k, d)
            end
            return decors
        end
    end
    push!(decors, d)
    return decors
end

decorate(d::Decoration) =
    decors -> decorate(decors, d)

decorate(d::Pair{Symbol}) =
    decorate(Decoration(d.first, d.second))

# A domain is a value type, a nominal entity class, or a record.

immutable Domain
    desc    # ::Union{Type, Symbol, Vector{Output}}
    decors::Decorations

    Domain(desc::Union{Type, Symbol}, decors::Decorations=NO_DECORATIONS) =
        new(desc, decors)

    Domain(desc::Vector, decors::Decorations=NO_DECORATIONS) =
        new(convert(Vector{Output}, desc), decors)
end

convert(::Type{Domain}, desc::Union{Type, Symbol}) =
    Domain(desc)

setdecorations(dom::Domain, decors::Decorations=NO_DECORATIONS) =
    Domain(dom.desc, decors)

setdecorations(decors::Decorations=NO_DECORATIONS) =
    dom -> setdecorations(dom, decors)

function show(io::IO, dom::Domain)
    if isdata(dom)
        T = datatype(dom)
        if T <: Union{}
            print(io, "None")
        else
            print(io, T)
        end
    elseif isentity(dom)
        print(io, classname(dom))
    elseif isrecord(dom)
        print(io, "{")
        comma = false
        for otype in fields(dom)
            if comma
                print(io, ", ")
            end
            comma = true
            print(io, otype)
        end
        print(io, "}")
    end
    decors = decorations(dom)
    if !isempty(decors)
        print(io, "[")
        comma = false
        for (n, v) in decors
            if comma
                print(io, ", ")
            end
            comma = true
            print(io, n, "=")
            if v !== nothing
                show(io, v)
            else
                print(io, "?")
            end
        end
        print(io, "]")
    end
end

# Decorations.

decorations(dom::Domain) = dom.decors

decoration(dom::Domain, name, T, default) =
    decoration(dom.decors, name, T, default)

decorate(dom::Domain, d::Decoration) =
    Domain(dom.desc, decorate(dom.decors, d))

# The domain kind.

isdata(dom::Domain) = isdata(dom.desc)
isany(dom::Domain) = isany(dom.desc)
isvoid(dom::Domain) = isvoid(dom.desc)
isnone(dom::Domain) = isnone(dom.desc)
isentity(dom::Domain) = isentity(dom.desc)
isrecord(dom::Domain) = isrecord(dom.desc)

isdata(desc::Type) = true
isany(desc::Type) = desc == Any
isvoid(desc::Type) = desc == Void
isnone(desc::Type) = desc == None
isentity(desc::Type) = false
isrecord(desc::Type) = false

isdata(desc::Symbol) = false
isany(desc::Symbol) = false
isvoid(desc::Symbol) = false
isnone(desc::Symbol) = false
isentity(desc::Symbol) = true
isrecord(desc::Symbol) = false

# The native Julia type that can represent the domain values.

datatype(dom::Domain) = datatype(dom.desc)
datatype(desc::Type) = desc
datatype(desc::Symbol) = Entity{desc}

# The name of an entity class.

const NO_CLASSNAME = Symbol("")

classname(dom::Domain) = classname(dom.desc)
classname(desc::Type) = NO_CLASSNAME
classname(desc::Symbol) = desc

# List of record fields.

fields(dom::Domain) = fields(dom.desc)

max_stars_repo_name: rbt-lang/rbt-proto

max_issues_repo_name: rbt-lang/rbt-proto

max_forks_repo_name: rbt-lang/rbt-proto


text:
function ShotProfileLSWEM(m,m0,d,param=Dict())

	# least squares shot profile wave equation migration of isotropic 1C data.
	cost = get(param,"cost","cost")   # cost function output text file
	precon = get(param,"precon",false)   # flag for preconditioning by smoothing the image
	wd = join(["tmp_LSM_wd_",string(int(rand()*100000))])
	CalculateSampling(d,wd,param)
	param["wd"] = wd
	param["tmute"] = 0.;
	param["vmute"] = 999999.;
	if (precon == true)
		param["operators"] = [ApplyDataWeights SeisMute ShotProfileWEM
                                      SeisSmoothStructure SeisSmoothGathers]
	else
		param["operators"] = [ApplyDataWeights SeisMute ShotProfileWEM]
	end
	ConjugateGradients(m,m0,d,cost,param)
	SeisRemove(wd)

end

max_stars_repo_name: fercarozzi/myseismicjulia

max_issues_repo_name: fercarozzi/myseismicjulia

max_forks_repo_name: fercarozzi/myseismicjulia


text:
###!/usr/bin/env julia

#Start Test Script
using Alistair
using Base.Test

# TEST OPTIONS
const TEST_SIZE_1 = 10
const PRINT_RESULTS = false

# GENERATE TEST DATA
beta = [0.7; 0.45]
X = hcat(ones(TEST_SIZE_1,1), collect(1.0:TEST_SIZE_1))
Y = X * beta + 0.1*randn(TEST_SIZE_1, 1)

# Run test
tic()

@time @test Alistair.issingletonarray(X) == false
@time @test Alistair.isrowarray(X) == false
@time @test Alistair.iscolumnarray(Y) == true
@time @test Alistair.hasintercept(X) == true

@time @test Alistair.aprod(X, 1.0) == X
@time @test Alistair.aprod(1, X) == X
@time @test Alistair.aprod(X, [1]) == X
@time @test Alistair.aprod([1], X) == X
@time @test Alistair.aprod(X', Y) == X' * Y

@time @test include("linreg_tests.jl")
@time @test include("genreg_tests.jl")
@time @test include("glmreg_tests.jl")

# End test
toc()


text:
function trace(f, args...)
    untracked_args = untrack.(args)
    @debug "tracking `$f$((untracked_args...,)))`"
    ret, pullback = rrule(f, untracked_args...)
    tracked = Record(f, args, pullback, zero(ret), false)
    return if ret isa AbstractArray
        TrackedArray(ret, tracked)
    elseif ret isa Real
        TrackedReal(ret, tracked)
    elseif ret isa Complex
        TrackedComplex(ret, tracked)
    else
        error("unsupported return type $(typeof(ret))")
    end
end

accumulate_grad!(x::Number, grad) = x + grad
accumulate_grad!(x::AbstractArray, grad) = (x .+= grad)

backpropagate!(tracked_value::Tuple, _grad) = backpropagate!.(tracked_value, ChainRules.unthunk(_grad))
function backpropagate!(tracked_value, _grad)
    @show tracked_value
    grad = unthunk(_grad)
    is_tracked(tracked_value) || error("expect tracked value")
    record = tracked_value.record::Record
    record.grad = accumulate_grad!(record.grad, grad)
    record.is_leaf && return

    # we won't have callable objects in our tape
    # since we always trace to TrackedType
    @debug "back propagating `pullback$((record.f, untrack.(record.args)...))($grad)`"
    grad_args = Base.tail(record.pullback(record.grad))
    for (arg, grad_arg) in zip(record.args, grad_args)
        is_tracked(arg) && backpropagate!(arg, grad_arg)
    end
    return
end

function gradient(f, args...)
    tracked_args = track.(args)
    ret = f(tracked_args...)
    # let's only support complex-value params not returned loss
    ret isa Real || error("cannot differentiate return type $(typeof(ret)), expect a `Real`")
    backpropagate!(ret, one(untrack(ret)))
    return map(tracked_args) do arg
        arg.record.grad
    end
end


text:
module CairoPlot

using Cairo
using Dates

export crplot
export write_to_png

include("main.jl")

#precompile(crplot(0:10, 0:2:20))

end


text:
Base.promote_rule(::Type{<:MagLike}, ::Type{<:Union{Float64,MagLike}}) = Mag
Base.promote_rule(::Type{<:ArfLike}, ::Type{<:Union{AbstractFloat,Integer,MagLike}}) = Arf
Base.promote_rule(
    ::Type{<:ArbLike},
    ::Type{<:Union{AbstractFloat,Integer,Rational,ArfLike,ArbRef}},
) = Arb
Base.promote_rule(
    ::Type{<:AcbLike},
    ::Type{
        <:Union{
            AbstractFloat,
            Integer,
            Rational,
            Complex{<:Union{AbstractFloat,Integer,Rational}},
            ArfLike,
            ArbLike,
            AcbRef,
        },
    },
) = Acb

for (jf, af) in [(:+, :add!), (:-, :sub!), (:*, :mul!), (:/, :div!)]
    @eval function Base.$jf(x::T, y::T) where {T<:MagOrRef}
        z = T()
        $af(z, x, y)
        z
    end
end

function Base.:(^)(x::T, k::Integer) where {T<:MagOrRef}
    z = T()
    pow!(z, x, convert(UInt, k))
    z
end

for (jf, af) in [(:+, :add!), (:-, :sub!), (:*, :mul!), (:/, :div!)]
    @eval function Base.$jf(x::T, y::T) where {T<:Union{Arf,ArfRef,Arb,ArbRef,Acb,AcbRef}}
        z = T(prec = max(precision(x), precision(y)))
        $af(z, x, y)
        z
    end
end
function Base.:(-)(x::T) where {T<:Union{Arf,ArfRef,Arb,ArbRef,Acb,AcbRef}}
    z = T(prec = precision(x))
    neg!(z, x)
    z
end
function Base.:(^)(x::T, k::Integer) where {T<:Union{Arb,ArbRef,Acb,AcbRef}}
    z = T(prec = precision(x))
    pow!(z, x, convert(UInt, k))
    z
end

for f in [
    :sqrt,
    :exp,
    :expm1,
    :log,
    :log1p,
    :sin,
    :cos,
    :tan,
    :cot,
    :asin,
    :acos,
    :atan,
    :acot,
    :sinc,
    :sinh,
    :cosh,
    :tanh,
    :asinh,
    :acosh,
    :atanh,
    :sec,
    :asec,
    :sech,
    :asech,
]
    @eval function Base.$f(x::T) where {T<:Union{Arb,ArbRef,Acb,AcbRef}}
        z = T(prec = precision(x))
        $(Symbol(f, :!))(z, x)
        z
    end
end

Base.real(z::AcbLike; prec = _precision(z)) = get_real!(Arb(prec = prec), z)
Base.imag(z::AcbLike; prec = _precision(z)) = get_imag!(Arb(prec = prec), z)
Base.conj(z::AcbLike) = conj!(Acb(prec = _precision(z)), z)
Base.abs(z::AcbLike) = abs!(Arb(prec = _precision(z)), z)


text:
# utility functions to work with Transducers.jl

_is_thread_safe_rng(rng) = false
if VERSION ≥ v"1.7.0"
    _is_thread_safe_rng(rng::Random.TaskLocalRNG) = true
    _is_thread_safe_rng(rng::typeof(Random.GLOBAL_RNG)) = true
end

function _default_executor(rng; kwargs...)
    if _is_thread_safe_rng(rng)
        return Transducers.PreferParallel(; kwargs...)
    else
        return Transducers.SequentialEx()
    end
end

# transducer-friendly findmax, ignoring NaNs
function _findmax(x)
    return Transducers.foldxl(x |> Transducers.Enumerate(); init=missing) do xmax_imax, i_xi
        xmax_imax === missing && return reverse(i_xi)
        i, xi = i_xi
        isnan(xi) && return xmax_imax
        xmax = first(xmax_imax)
        isnan(xmax) && return (xi, i)
        return xi > xmax ? (xi, i) : xmax_imax
    end
end

# WARNING: Type piracy!
# https://github.com/JuliaFolds/Transducers.jl/issues/521
Base.size(x::Transducers.ProgressLoggingFoldable) = size(x.foldable)