text:
"""
    _current_lower_upper_bound(minormax, low, upp, values_low, values_upp, values)

Returns a lower and upper bound of the extremum given that `low` and
`upp` and lower and upper bounds of the extremum and so are all values
in `values_low` and `Values_upp` respectively. It determines
**either** the minimum or the maximum depending on if `minormax = min`
or `minormax = max`.

This is mainly an internal function which implements behaviour which
is common for [`extrema_enclosure`](@ref), [`minimum_enclosure`](@ref)
and [`maximum_enclosure`](@ref).

"""
function _current_lower_upper_bound(
    minormax::Union{typeof(min),typeof(max)},
    low::Arf,
    upp::Arf,
    values_low::Vector{Arf},
    values_upp::Vector{Arf},
    values::Vector{Arb},
)
    if minormax isa typeof(min)
        minormax! = Arblib.min!
        minormaximum = minimum
    elseif minormax isa typeof(max)
        minormax! = Arblib.max!
        minormaximum = maximum
    end

    if all(isfinite, values)
        current_low = minormax(low, minormaximum(values_low))
        current_upp = minormax(upp, minormaximum(values_upp))
    elseif minormax isa typeof(min)
        current_low = Arf(-Inf, prec = precision(low))
        current_upp = upp
        for value in values_upp
            if isfinite(value)
                minormax!(current_upp, current_upp, value)
            end
        end
    elseif minormax isa typeof(max)
        current_low = upp
        for value in values_low
            if isfinite(value)
                minormax!(current_low, current_low, value)
            end
        end
        current_upp = Arf(Inf, prec = precision(low))
    end

    return current_low, current_upp
end

"""
    extrema_enclosure(f, a::Arf, b::Arf; degree, atol, rtol, abs_value, log_bisection, point_value_min, point_value_max, depth_start, maxevals, depth, threaded, verbose)

Compute both the minimum and maximum of the function `f` on the
interval `[a, b]` and return them as a 2-tuple.

The extrema are computed by enclosing the extrema of the function on
an interval using Taylor series through [`extrema_series`](@ref). The
degree of the expansion is kept constant and the interval is bisected
until the required tolerance is met.

The function `f` should support evaluation on both `Arb` and
`ArbSeries` and should return an enclosure of the result in both
cases. The degree used for `ArbSeries` can be set with the `degree`
argument (defaults to 8). If `degree` is negative then it will fall
back to direct evaluation with `Arb` and not make use of
[`extrema_series`](@ref), this is usually much slower but does not
require the function to be implemented for `ArbSeries`.

If `abs_value = true` the compute the extrema of `abs(f(x))` on the
interval `[a, b]`. For the computation of the maximum this is mostly
the same, only difference is that we have to take the absolute value
of the evaluations. For the minimum we have to take into account that
the polynomial might cross zero, in which case the minimum is zero.

If `log_bisection = true` then the intervals are bisected in a
logarithmic scale, see [`bisect_interval`](@ref) for details.

The arguments `point_value_min` and `point_value_max` can optionally
be set to a a priori upper or lower bounds of the min and max
respectively. Typically this is computed by evaluating `f` on some
(possibly well chosen) points before calling this method and taking
the minimum and maximum of the evaluations respectively. This can
allow the method to quicker discard subintervals where the extrema
could not possibly be located.

The argument `depth_start` bisect the interval using
[`bisect_interval_recursive`](@ref) before starting to compute the
extrema. This can be useful if it is known beforehand that a certain
number of bisections will be necessary before the enclosures get good
enough. It defaults to `0` which corresponds to not bisecting the
interval at all before starting.

The arguments `maxevals` and `depth` can be used to limit the number
of function evaluations and the number of bisections of the interval
respectively. Notice that `depth` takes `depth_start` into account, so
the maximum number of iterations is `depth - depth_start`.

If `threaded = true` then evaluate `f` in parallel on the intervals
using [`Threads.@threads`](@ref).

If `verbose = true` then output information about the process.

TODO: Currently this always computes both minimum and maximum on all
subintervals. Change it so that it takes into account if the
minimum/maximum could be located in the subinterval or not.

"""
function extrema_enclosure(
    f,
    a::Arf,
    b::Arf;
    degree::Integer = 8,
    atol = 0,
    rtol = sqrt(eps(one(a))),
    abs_value = false,
    log_bisection = false,
    point_value_min::Arb = Arb(Inf, prec = precision(a)),
    point_value_max::Arb = Arb(-Inf, prec = precision(a)),
    depth_start::Integer = 0,
    maxevals::Integer = 1000,
    depth::Integer = 20,
    threaded = false,
    verbose = false,
)
    check_interval(a, b)

    maybe_abs = abs_value ? abs : identity

    if a == b
        res = maybe_abs(f(Arb(a)))
        abs_value && Arblib.nonnegative_part!(res, res)
        return res, res
    end

    # List of intervals
    intervals = bisect_interval_recursive(a, b, depth_start, log_midpoint = log_bisection)

    # Stores the lower and upper bound of the minimum and the maximum
    # on the parts of the interval which are completed. Initially they
    # are set to the neutral element for minimum.
    min_low, min_upp = Arf(Inf, prec = precision(a)), Arf(Inf, prec = precision(a))
    max_low, max_upp = Arf(-Inf, prec = precision(a)), Arf(-Inf, prec = precision(a))

    iterations = 0
    evals = 0
    while true
        iterations += 1
        evals += length(intervals)

        # Compute enclosure of extrema on each remaining interval
        values_min = similar(intervals, Arb)
        values_max = similar(intervals, Arb)
        if degree < 0
            if threaded
                Threads.@threads for i in eachindex(intervals)
                    values_min[i] = values_max[i] = maybe_abs(f(Arb(intervals[i])))
                end
            else
                for i in eachindex(intervals)
                    values_min[i] = values_max[i] = maybe_abs(f(Arb(intervals[i])))
                end
            end
        else
            point_values = similar(values_min)
            if threaded
                Threads.@threads for i in eachindex(intervals)
                    values_min[i], values_max[i], point_values[i] =
                        extrema_series(f, intervals[i]...; degree, abs_value)
                end
            else
                for (i, (a, b)) in enumerate(intervals)
                    values_min[i], values_max[i], point_values[i] =
                        extrema_series(f, a, b; degree, abs_value)
                end
            end
            for point_value in filter(isfinite, point_values)
                Arblib.min!(point_value_min, point_value_min, point_value)
                Arblib.max!(point_value_max, point_value_max, point_value)
            end
        end

        # Get upper and lower bounds of extrema on each interval
        values_min_low = similar(values_min, Arf)
        values_min_upp = similar(values_min, Arf)
        values_max_low = similar(values_max, Arf)
        values_max_upp = similar(values_max, Arf)
        for i in eachindex(intervals)
            values_min_low[i], values_min_upp[i] = getinterval(values_min[i])
            values_max_low[i], values_max_upp[i] = getinterval(values_max[i])
        end

        # Compute current lower and upper bound of extrema
        min_current_low, min_current_upp = _current_lower_upper_bound(
            min,
            min_low,
            min_upp,
            values_min_low,
            values_min_upp,
            values_min,
        )
        max_current_low, max_current_upp = _current_lower_upper_bound(
            max,
            max_low,
            max_upp,
            values_max_low,
            values_max_upp,
            values_max,
        )

        min_current_upp = min(min_current_upp, ubound(point_value_min))
        max_current_low = max(max_current_low, lbound(point_value_max))

        # If we are not done split the intervals where extrema could
        # be located and which do not satisfy the tolerance
        next_intervals = sizehint!(empty(intervals), 2length(intervals))
        for i in eachindex(intervals)
            # Check if the extrema could be located in the interval
            possible_min = values_min_low[i] <= min_current_upp || !isfinite(values_min[i])
            possible_max = max_current_low <= values_max_upp[i] || !isfinite(values_max[i])
            if possible_min || possible_max
                tol_min = check_tolerance(values_min[i]; atol, rtol)
                tol_max = check_tolerance(values_max[i]; atol, rtol)

                if (!possible_min || tol_min) && (!possible_max || tol_max)
                    # If the interval satisfies the tolerance then add
                    # it to the lower and upper bound of the extrema
                    # for the finished parts of the interval.
                    Arblib.min!(min_low, min_low, values_min_low[i])
                    Arblib.min!(min_upp, min_upp, values_min_upp[i])
                    Arblib.max!(max_low, max_low, values_max_low[i])
                    Arblib.max!(max_upp, max_upp, values_max_upp[i])
                else
                    # Otherwise split the interval further
                    push!(
                        next_intervals,
                        bisect_interval(intervals[i]..., log_midpoint = log_bisection)...,
                    )
                end
            end
        end
        intervals = next_intervals

        verbose && @info "iteration: $(lpad(iterations, 2)), " *
              "remaining intervals: $(lpad(length(intervals) ÷ 2, 3)), " *
              "min: $(format_interval(min_current_low, min_current_upp)) " *
              "max: $(format_interval(max_current_low, max_current_upp))"

        non_finite_min = count(!isfinite, values_min)
        non_finite_max = count(!isfinite, values_max)
        verbose &&
            (non_finite_min > 0 || non_finite_max) > 0 &&
            @info "non-finite intervals: min: $(lpad(non_finite_min, 3)) " *
                  "max: $(lpad(non_finite_max, 3))"

        isempty(intervals) && break

        # Check if we have done the maximum number of function
        # evaluations or reached the maximum depth
        if evals >= maxevals || iterations >= depth - depth_start
            if verbose
                evals >= maxevals &&
                    @info "reached maximum number of evaluations $evals >= $maxevals"
                iterations >= depth - depth_start && @info "reached maximum depth $depth"
            end
            min_low, min_upp = min_current_low, min_current_upp
            max_low, max_upp = max_current_low, max_current_upp
            break
        end
    end

    res_min = Arb((min_low, min_upp))
    res_max = Arb((max_low, max_upp))
    if abs_value
        Arblib.nonnegative_part!(res_min, res_min)
        Arblib.nonnegative_part!(res_max, res_max)
    end
    return res_min, res_max
end

"""
    minimum_enclosure(f, a::Arf, b::Arf; degree, atol, rtol, abs_value, log_bisection, point_value_min, depth_start, maxevals, depth, threaded, verbose)

Compute the minimum of the function `f` on the interval `[a, b]`.

Takes the same arguments as [`extrema_polynomial`](@ref). The
algorithm is also the same except that it only looks for the minimum.
"""
function minimum_enclosure(
    f,
    a::Arf,
    b::Arf;
    degree::Integer = 8,
    atol = 0,
    rtol = sqrt(eps(one(a))),
    abs_value = false,
    log_bisection = false,
    point_value_min::Arb = Arb(Inf, prec = precision(a)),
    depth_start::Integer = 0,
    maxevals::Integer = 1000,
    depth::Integer = 20,
    threaded = false,
    verbose = false,
)
    check_interval(a, b)

    maybe_abs = abs_value ? abs : identity

    if a == b
        res = maybe_abs(f(Arb(a)))
        abs_value && Arblib.nonnegative_part!(res, res)
        return res
    end

    # List of intervals
    intervals = bisect_interval_recursive(a, b, depth_start, log_midpoint = log_bisection)

    # Stores the lower and upper bound of the minimum on the parts of
    # the interval which are completed. Initially they are set to the
    # neutral element for minimum.
    min_low, min_upp = Arf(Inf, prec = precision(a)), Arf(Inf, prec = precision(a))

    iterations = 0
    evals = 0
    while true
        iterations += 1
        evals += length(intervals)

        # Compute enclosure of minimum on each remaining interval
        values = similar(intervals, Arb)
        if degree < 0
            if threaded
                Threads.@threads for i in eachindex(intervals)
                    values[i] = maybe_abs(f(Arb(intervals[i])))
                end
            else
                for i in eachindex(intervals)
                    values[i] = maybe_abs(f(Arb(intervals[i])))
                end
            end
        else
            point_values = similar(values)
            if threaded
                Threads.@threads for i in eachindex(intervals)
                    values[i], point_values[i] =
                        minimum_series(f, intervals[i]...; degree, abs_value)
                end
            else
                for (i, (a, b)) in enumerate(intervals)
                    values[i], point_values[i] = minimum_series(f, a, b; degree, abs_value)
                end
            end
            for point_value in filter(isfinite, point_values)
                Arblib.min!(point_value_min, point_value_min, point_value)
            end
        end

        # Get upper and lower bounds of minimum on each interval
        values_low = similar(values, Arf)
        values_upp = similar(values, Arf)
        for i in eachindex(values)
            values_low[i], values_upp[i] = getinterval(values[i])
        end

        # Compute current lower and upper bound of minimum
        min_current_low, min_current_upp = _current_lower_upper_bound(
            min,
            min_low,
            min_upp,
            values_low,
            values_upp,
            values,
        )

        min_current_upp = min(min_current_upp, ubound(point_value_min))

        # If we are not done split the intervals where minimum could
        # be located and which do not satisfy the tolerance
        next_intervals = sizehint!(empty(intervals), 2length(intervals))
        for i in eachindex(intervals)
            # Check if the minimum could be located in the interval
            if values_low[i] <= min_current_upp || !isfinite(values[i])
                if check_tolerance(values[i]; atol, rtol)
                    # If the interval satisfies the tolerance then add
                    # it to the lower and upper bound of the minimum
                    # for the finished parts of the interval.
                    Arblib.min!(min_low, min_low, values_low[i])
                    Arblib.min!(min_upp, min_upp, values_upp[i])
                else
                    # Otherwise split the interval further
                    push!(
                        next_intervals,
                        bisect_interval(intervals[i]..., log_midpoint = log_bisection)...,
                    )
                end
            end
        end
        intervals = next_intervals

        verbose && @info "iteration: $(lpad(iterations, 2)), " *
              "remaining intervals: $(lpad(length(intervals) ÷ 2, 3)), " *
              "minimum: $(format_interval(min_current_low, min_current_upp))"

        non_finite = count(!isfinite, values)
        verbose && non_finite > 0 && @info "non-finite intervals: $non_finite"

        isempty(intervals) && break

        # Check if we have done the maximum number of function
        # evaluations or reached the maximum depth
        if evals >= maxevals || iterations >= depth - depth_start
            if verbose
                evals >= maxevals &&
                    @info "reached maximum number of evaluations $evals >= $maxevals"
                iterations >= depth - depth_start && @info "reached maximum depth $depth"
            end
            min_low, min_upp = min_current_low, min_current_upp
            break
        end
    end

    res = Arb((min_low, min_upp))
    abs_value && Arblib.nonnegative_part!(res, res)
    return res
end

"""
    maximum_enclosure(f, a::Arf, b::Arf; degree, atol, rtol, abs_value, log_bisection, point_value_max, depth_start, maxevals, depth, threaded, verbose)

Compute the maximum of the function `f` on the interval `[a, b]`.

Takes the same arguments as [`extrema_polynomial`](@ref). The
algorithm is also the same except that it only looks for the maximum.
"""
function maximum_enclosure(
    f,
    a::Arf,
    b::Arf;
    degree::Integer = 8,
    atol = 0,
    rtol = sqrt(eps(one(a))),
    abs_value = false,
    log_bisection = false,
    point_value_max::Arb = Arb(-Inf, prec = precision(a)),
    depth_start::Integer = 0,
    maxevals::Integer = 1000,
    depth::Integer = 20,
    threaded = false,
    verbose = false,
)
    check_interval(a, b)

    maybe_abs = abs_value ? abs : identity

    if a == b
        return maybe_abs(f(Arb(a)))
    end

    # List of intervals
    intervals = bisect_interval_recursive(a, b, depth_start, log_midpoint = log_bisection)

    # Stores the lower and upper bound of the maximum on the parts of
    # the interval which are completed. Initially they are set to the
    # neutral element for maximum.
    max_low, max_upp = Arf(-Inf, prec = precision(a)), Arf(-Inf, prec = precision(a))

    iterations = 0
    evals = 0
    while true
        iterations += 1
        evals += length(intervals)

        # Compute enclosure of maximum on each remaining interval
        values = similar(intervals, Arb)
        if degree < 0
            if threaded
                Threads.@threads for i in eachindex(intervals)
                    values[i] = maybe_abs(f(Arb(intervals[i])))
                end
            else
                for i in eachindex(intervals)
                    values[i] = maybe_abs(f(Arb(intervals[i])))
                end
            end
        else
            point_values = similar(values)
            if threaded
                Threads.@threads for i in eachindex(intervals)
                    values[i], point_values[i] =
                        maximum_series(f, intervals[i]...; degree, abs_value)
                end
            else
                for (i, (a, b)) in enumerate(intervals)
                    values[i], point_values[i] = maximum_series(f, a, b; degree, abs_value)
                end
            end
            for point_value in filter(isfinite, point_values)
                Arblib.max!(point_value_max, point_value_max, point_value)
            end
        end

        # Get upper and lower bounds of maximum on each interval
        values_low = similar(values, Arf)
        values_upp = similar(values, Arf)
        for i in eachindex(values)
            values_low[i], values_upp[i] = getinterval(Arf, values[i])
        end

        # Compute current lower and upper bound of maximum
        max_current_low, max_current_upp = _current_lower_upper_bound(
            max,
            max_low,
            max_upp,
            values_low,
            values_upp,
            values,
        )

        max_current_low = max(max_current_low, lbound(point_value_max))

        # If we are not done split the intervals where maximum could
        # be located and which do not satisfy the tolerance
        next_intervals = sizehint!(empty(intervals), 2length(intervals))
        for i in eachindex(intervals)
            # Check if the maximum could be located in the interval
            if max_current_low <= values_upp[i] || !isfinite(values[i])
                if check_tolerance(values[i]; atol, rtol)
                    # If the interval satisfies the tolerance then add
                    # it to the lower and upper bound of the maximum
                    # for the finished parts of the interval.
                    Arblib.max!(max_low, max_low, values_low[i])
                    Arblib.max!(max_upp, max_upp, values_upp[i])
                else
                    # Otherwise split the interval further
                    push!(
                        next_intervals,
                        bisect_interval(intervals[i]..., log_midpoint = log_bisection)...,
                    )
                end
            end
        end
        intervals = next_intervals

        verbose && @info "iteration: $(lpad(iterations, 2)), " *
              "remaining intervals: $(lpad(length(intervals) ÷ 2, 3)), " *
              "maximum: $(format_interval(max_current_low, max_current_upp))"

        non_finite = count(!isfinite, values)
        verbose && non_finite > 0 && @info "non-finite intervals: $non_finite"

        isempty(intervals) && break

        # Check if we have done the maximum number of function
        # evaluations or reached the maximum depth
        if evals >= maxevals || iterations >= depth - depth_start
            if verbose
                evals >= maxevals &&
                    @info "reached maximum number of evaluations $evals >= $maxevals"
                iterations >= depth - depth_start && @info "reached maximum depth $depth"
            end
            max_low, max_upp = max_current_low, max_current_upp
            break
        end
    end

    res = Arb((max_low, max_upp))
    abs_value && Arblib.nonnegative_part!(res, res)
    return res
end


text:
#   Generating #define constants
const MD5_CBLOCK                     = 64
const MD5_LBLOCK                     = (MD5_CBLOCK/4)
const MD5_DIGEST_LENGTH              = 16
const EVP_MAX_MD_SIZE                = 64
const EVP_MAX_KEY_LENGTH             = 64
const EVP_MAX_IV_LENGTH              = 16
const EVP_MAX_BLOCK_LENGTH           = 32
const NID_undef                      = 0
const NID_itu_t                      = 645
const NID_ccitt                      = 404
const NID_iso                        = 181
const NID_joint_iso_itu_t            = 646
const NID_joint_iso_ccitt            = 393
const NID_member_body                = 182
const NID_identified_organization    = 676
const NID_hmac_md5                   = 780
const NID_hmac_sha1                  = 781
const NID_certicom_arc               = 677
const NID_international_organizations = 647
const NID_wap                        = 678
const NID_wap_wsg                    = 679
const NID_selected_attribute_types   = 394
const NID_clearance                  = 395
const NID_ISO_US                     = 183
const NID_X9_57                      = 184
const NID_X9cm                       = 185
const NID_dsa                        = 116
const NID_dsaWithSHA1                = 113
const NID_ansi_X9_62                 = 405
const NID_X9_62_prime_field          = 406
const NID_X9_62_characteristic_two_field = 407
const NID_X9_62_id_characteristic_two_basis = 680
const NID_X9_62_onBasis              = 681
const NID_X9_62_tpBasis              = 682
const NID_X9_62_ppBasis              = 683
const NID_X9_62_id_ecPublicKey       = 408
const NID_X9_62_c2pnb163v1           = 684
const NID_X9_62_c2pnb163v2           = 685
const NID_X9_62_c2pnb163v3           = 686
const NID_X9_62_c2pnb176v1           = 687
const NID_X9_62_c2tnb191v1           = 688
const NID_X9_62_c2tnb191v2           = 689
const NID_X9_62_c2tnb191v3           = 690
const NID_X9_62_c2onb191v4           = 691
const NID_X9_62_c2onb191v5           = 692
const NID_X9_62_c2pnb208w1           = 693
const NID_X9_62_c2tnb239v1           = 694
const NID_X9_62_c2tnb239v2           = 695
const NID_X9_62_c2tnb239v3           = 696
const NID_X9_62_c2onb239v4           = 697
const NID_X9_62_c2onb239v5           = 698
const NID_X9_62_c2pnb272w1           = 699
const NID_X9_62_c2pnb304w1           = 700
const NID_X9_62_c2tnb359v1           = 701
const NID_X9_62_c2pnb368w1           = 702
const NID_X9_62_c2tnb431r1           = 703
const NID_X9_62_prime192v1           = 409
const NID_X9_62_prime192v2           = 410
const NID_X9_62_prime192v3           = 411
const NID_X9_62_prime239v1           = 412
const NID_X9_62_prime239v2           = 413
const NID_X9_62_prime239v3           = 414
const NID_X9_62_prime256v1           = 415
const NID_ecdsa_with_SHA1            = 416
const NID_ecdsa_with_Recommended     = 791
const NID_ecdsa_with_Specified       = 792
const NID_ecdsa_with_SHA224          = 793
const NID_ecdsa_with_SHA256          = 794
const NID_ecdsa_with_SHA384          = 795
const NID_ecdsa_with_SHA512          = 796
const NID_secp112r1                  = 704
const NID_secp112r2                  = 705
const NID_secp128r1                  = 706
const NID_secp128r2                  = 707
const NID_secp160k1                  = 708
const NID_secp160r1                  = 709
const NID_secp160r2                  = 710
const NID_secp192k1                  = 711
const NID_secp224k1                  = 712
const NID_secp224r1                  = 713
const NID_secp256k1                  = 714
const NID_secp384r1                  = 715
const NID_secp521r1                  = 716
const NID_sect113r1                  = 717
const NID_sect113r2                  = 718
const NID_sect131r1                  = 719
const NID_sect131r2                  = 720
const NID_sect163k1                  = 721
const NID_sect163r1                  = 722
const NID_sect163r2                  = 723
const NID_sect193r1                  = 724
const NID_sect193r2                  = 725
const NID_sect233k1                  = 726
const NID_sect233r1                  = 727
const NID_sect239k1                  = 728
const NID_sect283k1                  = 729
const NID_sect283r1                  = 730
const NID_sect409k1                  = 731
const NID_sect409r1                  = 732
const NID_sect571k1                  = 733
const NID_sect571r1                  = 734
const NID_wap_wsg_idm_ecid_wtls1     = 735
const NID_wap_wsg_idm_ecid_wtls3     = 736
const NID_wap_wsg_idm_ecid_wtls4     = 737
const NID_wap_wsg_idm_ecid_wtls5     = 738
const NID_wap_wsg_idm_ecid_wtls6     = 739
const NID_wap_wsg_idm_ecid_wtls7     = 740
const NID_wap_wsg_idm_ecid_wtls8     = 741
const NID_wap_wsg_idm_ecid_wtls9     = 742
const NID_wap_wsg_idm_ecid_wtls10    = 743
const NID_wap_wsg_idm_ecid_wtls11    = 744
const NID_wap_wsg_idm_ecid_wtls12    = 745
const NID_cast5_cbc                  = 108
const NID_cast5_ecb                  = 109
const NID_cast5_cfb64                = 110
const NID_cast5_ofb64                = 111
const NID_pbeWithMD5AndCast5_CBC     = 112
const NID_id_PasswordBasedMAC        = 782
const NID_id_DHBasedMac              = 783
const NID_rsadsi                     = 1
const NID_pkcs                       = 2
const NID_pkcs1                      = 186
const NID_rsaEncryption              = 6
const NID_md2WithRSAEncryption       = 7
const NID_md4WithRSAEncryption       = 396
const NID_md5WithRSAEncryption       = 8
const NID_sha1WithRSAEncryption      = 65
const NID_rsaesOaep                  = 919
const NID_mgf1                       = 911
const NID_rsassaPss                  = 912
const NID_sha256WithRSAEncryption    = 668
const NID_sha384WithRSAEncryption    = 669
const NID_sha512WithRSAEncryption    = 670
const NID_sha224WithRSAEncryption    = 671
const NID_pkcs3                      = 27
const NID_dhKeyAgreement             = 28
const NID_pkcs5                      = 187
const NID_pbeWithMD2AndDES_CBC       = 9
const NID_pbeWithMD5AndDES_CBC       = 10
const NID_pbeWithMD2AndRC2_CBC       = 168
const NID_pbeWithMD5AndRC2_CBC       = 169
const NID_pbeWithSHA1AndDES_CBC      = 170
const NID_pbeWithSHA1AndRC2_CBC      = 68
const NID_id_pbkdf2                  = 69
const NID_pbes2                      = 161
const NID_pbmac1                     = 162
const NID_pkcs7                      = 20
const NID_pkcs7_data                 = 21
const NID_pkcs7_signed               = 22
const NID_pkcs7_enveloped            = 23
const NID_pkcs7_signedAndEnveloped   = 24
const NID_pkcs7_digest               = 25
const NID_pkcs7_encrypted            = 26
const NID_pkcs9                      = 47
const NID_pkcs9_emailAddress         = 48
const NID_pkcs9_unstructuredName     = 49
const NID_pkcs9_contentType          = 50
const NID_pkcs9_messageDigest        = 51
const NID_pkcs9_signingTime          = 52
const NID_pkcs9_countersignature     = 53
const NID_pkcs9_challengePassword    = 54
const NID_pkcs9_unstructuredAddress  = 55
const NID_pkcs9_extCertAttributes    = 56
const NID_ext_req                    = 172
const NID_SMIMECapabilities          = 167
const NID_SMIME                      = 188
const NID_id_smime_mod               = 189
const NID_id_smime_ct                = 190
const NID_id_smime_aa                = 191
const NID_id_smime_alg               = 192
const NID_id_smime_cd                = 193
const NID_id_smime_spq               = 194
const NID_id_smime_cti               = 195
const NID_id_smime_mod_cms           = 196
const NID_id_smime_mod_ess           = 197
const NID_id_smime_mod_oid           = 198
const NID_id_smime_mod_msg_v3        = 199
const NID_id_smime_mod_ets_eSignature_88 = 200
const NID_id_smime_mod_ets_eSignature_97 = 201
const NID_id_smime_mod_ets_eSigPolicy_88 = 202
const NID_id_smime_mod_ets_eSigPolicy_97 = 203
const NID_id_smime_ct_receipt        = 204
const NID_id_smime_ct_authData       = 205
const NID_id_smime_ct_publishCert    = 206
const NID_id_smime_ct_TSTInfo        = 207
const NID_id_smime_ct_TDTInfo        = 208
const NID_id_smime_ct_contentInfo    = 209
const NID_id_smime_ct_DVCSRequestData = 210
const NID_id_smime_ct_DVCSResponseData = 211
const NID_id_smime_ct_compressedData = 786
const NID_id_ct_asciiTextWithCRLF    = 787
const NID_id_smime_aa_receiptRequest = 212
const NID_id_smime_aa_securityLabel  = 213
const NID_id_smime_aa_mlExpandHistory = 214
const NID_id_smime_aa_contentHint    = 215
const NID_id_smime_aa_msgSigDigest   = 216
const NID_id_smime_aa_encapContentType = 217
const NID_id_smime_aa_contentIdentifier = 218
const NID_id_smime_aa_macValue       = 219
const NID_id_smime_aa_equivalentLabels = 220
const NID_id_smime_aa_contentReference = 221
const NID_id_smime_aa_encrypKeyPref  = 222
const NID_id_smime_aa_signingCertificate = 223
const NID_id_smime_aa_smimeEncryptCerts = 224
const NID_id_smime_aa_timeStampToken = 225
const NID_id_smime_aa_ets_sigPolicyId = 226
const NID_id_smime_aa_ets_commitmentType = 227
const NID_id_smime_aa_ets_signerLocation = 228
const NID_id_smime_aa_ets_signerAttr = 229
const NID_id_smime_aa_ets_otherSigCert = 230
const NID_id_smime_aa_ets_contentTimestamp = 231
const NID_id_smime_aa_ets_CertificateRefs = 232
const NID_id_smime_aa_ets_RevocationRefs = 233
const NID_id_smime_aa_ets_certValues = 234
const NID_id_smime_aa_ets_revocationValues = 235
const NID_id_smime_aa_ets_escTimeStamp = 236
const NID_id_smime_aa_ets_certCRLTimestamp = 237
const NID_id_smime_aa_ets_archiveTimeStamp = 238
const NID_id_smime_aa_signatureType  = 239
const NID_id_smime_aa_dvcs_dvc       = 240
const NID_id_smime_alg_ESDHwith3DES  = 241
const NID_id_smime_alg_ESDHwithRC2   = 242
const NID_id_smime_alg_3DESwrap      = 243
const NID_id_smime_alg_RC2wrap       = 244
const NID_id_smime_alg_ESDH          = 245
const NID_id_smime_alg_CMS3DESwrap   = 246
const NID_id_smime_alg_CMSRC2wrap    = 247
const NID_id_alg_PWRI_KEK            = 893
const NID_id_smime_cd_ldap           = 248
const NID_id_smime_spq_ets_sqt_uri   = 249
const NID_id_smime_spq_ets_sqt_unotice = 250
const NID_id_smime_cti_ets_proofOfOrigin = 251
const NID_id_smime_cti_ets_proofOfReceipt = 252
const NID_id_smime_cti_ets_proofOfDelivery = 253
const NID_id_smime_cti_ets_proofOfSender = 254
const NID_id_smime_cti_ets_proofOfApproval = 255
const NID_id_smime_cti_ets_proofOfCreation = 256
const NID_friendlyName               = 156
const NID_localKeyID                 = 157
const NID_ms_csp_name                = 417
const NID_LocalKeySet                = 856
const NID_x509Certificate            = 158
const NID_sdsiCertificate            = 159
const NID_x509Crl                    = 160
const NID_pbe_WithSHA1And128BitRC4   = 144
const NID_pbe_WithSHA1And40BitRC4    = 145
const NID_pbe_WithSHA1And3_Key_TripleDES_CBC = 146
const NID_pbe_WithSHA1And2_Key_TripleDES_CBC = 147
const NID_pbe_WithSHA1And128BitRC2_CBC = 148
const NID_pbe_WithSHA1And40BitRC2_CBC = 149
const NID_keyBag                     = 150
const NID_pkcs8ShroudedKeyBag        = 151
const NID_certBag                    = 152
const NID_crlBag                     = 153
const NID_secretBag                  = 154
const NID_safeContentsBag            = 155
const NID_md2                        = 3
const NID_md4                        = 257
const NID_md5                        = 4
const NID_md5_sha1                   = 114
const NID_hmacWithMD5                = 797
const NID_hmacWithSHA1               = 163
const NID_hmacWithSHA224             = 798
const NID_hmacWithSHA256             = 799
const NID_hmacWithSHA384             = 800
const NID_hmacWithSHA512             = 801
const NID_rc2_cbc                    = 37
const NID_rc2_ecb                    = 38
const NID_rc2_cfb64                  = 39
const NID_rc2_ofb64                  = 40
const NID_rc2_40_cbc                 = 98
const NID_rc2_64_cbc                 = 166
const NID_rc4                        = 5
const NID_rc4_40                     = 97
const NID_des_ede3_cbc               = 44
const NID_rc5_cbc                    = 120
const NID_rc5_ecb                    = 121
const NID_rc5_cfb64                  = 122
const NID_rc5_ofb64                  = 123
const NID_ms_ext_req                 = 171
const NID_ms_code_ind                = 134
const NID_ms_code_com                = 135
const NID_ms_ctl_sign                = 136
const NID_ms_sgc                     = 137
const NID_ms_efs                     = 138
const NID_ms_smartcard_login         = 648
const NID_ms_upn                     = 649
const NID_idea_cbc                   = 34
const NID_idea_ecb                   = 36
const NID_idea_cfb64                 = 35
const NID_idea_ofb64                 = 46
const NID_bf_cbc                     = 91
const NID_bf_ecb                     = 92
const NID_bf_cfb64                   = 93
const NID_bf_ofb64                   = 94
const NID_id_pkix                    = 127
const NID_id_pkix_mod                = 258
const NID_id_pe                      = 175
const NID_id_qt                      = 259
const NID_id_kp                      = 128
const NID_id_it                      = 260
const NID_id_pkip                    = 261
const NID_id_alg                     = 262
const NID_id_cmc                     = 263
const NID_id_on                      = 264
const NID_id_pda                     = 265
const NID_id_aca                     = 266
const NID_id_qcs                     = 267
const NID_id_cct                     = 268
const NID_id_ppl                     = 662
const NID_id_ad                      = 176
const NID_id_pkix1_explicit_88       = 269
const NID_id_pkix1_implicit_88       = 270
const NID_id_pkix1_explicit_93       = 271
const NID_id_pkix1_implicit_93       = 272
const NID_id_mod_crmf                = 273
const NID_id_mod_cmc                 = 274
const NID_id_mod_kea_profile_88      = 275
const NID_id_mod_kea_profile_93      = 276
const NID_id_mod_cmp                 = 277
const NID_id_mod_qualified_cert_88   = 278
const NID_id_mod_qualified_cert_93   = 279
const NID_id_mod_attribute_cert      = 280
const NID_id_mod_timestamp_protocol  = 281
const NID_id_mod_ocsp                = 282
const NID_id_mod_dvcs                = 283
const NID_id_mod_cmp2000             = 284
const NID_info_access                = 177
const NID_biometricInfo              = 285
const NID_qcStatements               = 286
const NID_ac_auditEntity             = 287
const NID_ac_targeting               = 288
const NID_aaControls                 = 289
const NID_sbgp_ipAddrBlock           = 290
const NID_sbgp_autonomousSysNum      = 291
const NID_sbgp_routerIdentifier      = 292
const NID_ac_proxying                = 397
const NID_sinfo_access               = 398
const NID_proxyCertInfo              = 663
const NID_id_qt_cps                  = 164
const NID_id_qt_unotice              = 165
const NID_textNotice                 = 293
const NID_server_auth                = 129
const NID_client_auth                = 130
const NID_code_sign                  = 131
const NID_email_protect              = 132
const NID_ipsecEndSystem             = 294
const NID_ipsecTunnel                = 295
const NID_ipsecUser                  = 296
const NID_time_stamp                 = 133
const NID_OCSP_sign                  = 180
const NID_dvcs                       = 297
const NID_id_it_caProtEncCert        = 298
const NID_id_it_signKeyPairTypes     = 299
const NID_id_it_encKeyPairTypes      = 300
const NID_id_it_preferredSymmAlg     = 301
const NID_id_it_caKeyUpdateInfo      = 302
const NID_id_it_currentCRL           = 303
const NID_id_it_unsupportedOIDs      = 304
const NID_id_it_subscriptionRequest  = 305
const NID_id_it_subscriptionResponse = 306
const NID_id_it_keyPairParamReq      = 307
const NID_id_it_keyPairParamRep      = 308
const NID_id_it_revPassphrase        = 309
const NID_id_it_implicitConfirm      = 310
const NID_id_it_confirmWaitTime      = 311
const NID_id_it_origPKIMessage       = 312
const NID_id_it_suppLangTags         = 784
const NID_id_regCtrl                 = 313
const NID_id_regInfo                 = 314
const NID_id_regCtrl_regToken        = 315
const NID_id_regCtrl_authenticator   = 316
const NID_id_regCtrl_pkiPublicationInfo = 317
const NID_id_regCtrl_pkiArchiveOptions = 318
const NID_id_regCtrl_oldCertID       = 319
const NID_id_regCtrl_protocolEncrKey = 320
const NID_id_regInfo_utf8Pairs       = 321
const NID_id_regInfo_certReq         = 322
const NID_id_alg_des40               = 323
const NID_id_alg_noSignature         = 324
const NID_id_alg_dh_sig_hmac_sha1    = 325
const NID_id_alg_dh_pop              = 326
const NID_id_cmc_statusInfo          = 327
const NID_id_cmc_identification      = 328
const NID_id_cmc_identityProof       = 329
const NID_id_cmc_dataReturn          = 330
const NID_id_cmc_transactionId       = 331
const NID_id_cmc_senderNonce         = 332
const NID_id_cmc_recipientNonce      = 333
const NID_id_cmc_addExtensions       = 334
const NID_id_cmc_encryptedPOP        = 335
const NID_id_cmc_decryptedPOP        = 336
const NID_id_cmc_lraPOPWitness       = 337
const NID_id_cmc_getCert             = 338
const NID_id_cmc_getCRL              = 339
const NID_id_cmc_revokeRequest       = 340
const NID_id_cmc_regInfo             = 341
const NID_id_cmc_responseInfo        = 342
const NID_id_cmc_queryPending        = 343
const NID_id_cmc_popLinkRandom       = 344
const NID_id_cmc_popLinkWitness      = 345
const NID_id_cmc_confirmCertAcceptance = 346
const NID_id_on_personalData         = 347
const NID_id_on_permanentIdentifier  = 858
const NID_id_pda_dateOfBirth         = 348
const NID_id_pda_placeOfBirth        = 349
const NID_id_pda_gender              = 351
const NID_id_pda_countryOfCitizenship = 352
const NID_id_pda_countryOfResidence  = 353
const NID_id_aca_authenticationInfo  = 354
const NID_id_aca_accessIdentity      = 355
const NID_id_aca_chargingIdentity    = 356
const NID_id_aca_group               = 357
const NID_id_aca_role                = 358
const NID_id_aca_encAttrs            = 399
const NID_id_qcs_pkixQCSyntax_v1     = 359
const NID_id_cct_crs                 = 360
const NID_id_cct_PKIData             = 361
const NID_id_cct_PKIResponse         = 362
const NID_id_ppl_anyLanguage         = 664
const NID_id_ppl_inheritAll          = 665
const NID_Independent                = 667
const NID_ad_OCSP                    = 178
const NID_ad_ca_issuers              = 179
const NID_ad_timeStamping            = 363
const NID_ad_dvcs                    = 364
const NID_caRepository               = 785
const NID_id_pkix_OCSP_basic         = 365
const NID_id_pkix_OCSP_Nonce         = 366
const NID_id_pkix_OCSP_CrlID         = 367
const NID_id_pkix_OCSP_acceptableResponses = 368
const NID_id_pkix_OCSP_noCheck       = 369
const NID_id_pkix_OCSP_archiveCutoff = 370
const NID_id_pkix_OCSP_serviceLocator = 371
const NID_id_pkix_OCSP_extendedStatus = 372
const NID_id_pkix_OCSP_valid         = 373
const NID_id_pkix_OCSP_path          = 374
const NID_id_pkix_OCSP_trustRoot     = 375
const NID_algorithm                  = 376
const NID_md5WithRSA                 = 104
const NID_des_ecb                    = 29
const NID_des_cbc                    = 31
const NID_des_ofb64                  = 45
const NID_des_cfb64                  = 30
const NID_rsaSignature               = 377
const NID_dsa_2                      = 67
const NID_dsaWithSHA                 = 66
const NID_shaWithRSAEncryption       = 42
const NID_des_ede_ecb                = 32
const NID_des_ede3_ecb               = 33
const NID_des_ede_cbc                = 43
const NID_des_ede_cfb64              = 60
const NID_des_ede3_cfb64             = 61
const NID_des_ede_ofb64              = 62
const NID_des_ede3_ofb64             = 63
const NID_desx_cbc                   = 80
const NID_sha                        = 41
const NID_sha1                       = 64
const NID_dsaWithSHA1_2              = 70
const NID_sha1WithRSA                = 115
const NID_ripemd160                  = 117
const NID_ripemd160WithRSA           = 119
const NID_sxnet                      = 143
const NID_X500                       = 11
const NID_X509                       = 12
const NID_commonName                 = 13
const NID_surname                    = 100
const NID_serialNumber               = 105
const NID_countryName                = 14
const NID_localityName               = 15
const NID_stateOrProvinceName        = 16
const NID_streetAddress              = 660
const NID_organizationName           = 17
const NID_organizationalUnitName     = 18
const NID_title                      = 106
const NID_description                = 107
const NID_searchGuide                = 859
const NID_businessCategory           = 860
const NID_postalAddress              = 861
const NID_postalCode                 = 661
const NID_postOfficeBox              = 862
const NID_physicalDeliveryOfficeName = 863
const NID_telephoneNumber            = 864
const NID_telexNumber                = 865
const NID_teletexTerminalIdentifier  = 866
const NID_facsimileTelephoneNumber   = 867
const NID_x121Address                = 868
const NID_internationaliSDNNumber    = 869
const NID_registeredAddress          = 870
const NID_destinationIndicator       = 871
const NID_preferredDeliveryMethod    = 872
const NID_presentationAddress        = 873
const NID_supportedApplicationContext = 874
const NID_member                     = 875
const NID_owner                      = 876
const NID_roleOccupant               = 877
const NID_seeAlso                    = 878
const NID_userPassword               = 879
const NID_userCertificate            = 880
const NID_cACertificate              = 881
const NID_authorityRevocationList    = 882
const NID_certificateRevocationList  = 883
const NID_crossCertificatePair       = 884
const NID_name                       = 173
const NID_givenName                  = 99
const NID_initials                   = 101
const NID_generationQualifier        = 509
const NID_x500UniqueIdentifier       = 503
const NID_dnQualifier                = 174
const NID_enhancedSearchGuide        = 885
const NID_protocolInformation        = 886
const NID_distinguishedName          = 887
const NID_uniqueMember               = 888
const NID_houseIdentifier            = 889
const NID_supportedAlgorithms        = 890
const NID_deltaRevocationList        = 891
const NID_dmdName                    = 892
const NID_pseudonym                  = 510
const NID_role                       = 400
const NID_X500algorithms             = 378
const NID_rsa                        = 19
const NID_mdc2WithRSA                = 96
const NID_mdc2                       = 95
const NID_id_ce                      = 81
const NID_subject_directory_attributes = 769
const NID_subject_key_identifier     = 82
const NID_key_usage                  = 83
const NID_private_key_usage_period   = 84
const NID_subject_alt_name           = 85
const NID_issuer_alt_name            = 86
const NID_basic_constraints          = 87
const NID_crl_number                 = 88
const NID_crl_reason                 = 141
const NID_invalidity_date            = 142
const NID_delta_crl                  = 140
const NID_issuing_distribution_point = 770
const NID_certificate_issuer         = 771
const NID_name_constraints           = 666
const NID_crl_distribution_points    = 103
const NID_certificate_policies       = 89
const NID_any_policy                 = 746
const NID_policy_mappings            = 747
const NID_authority_key_identifier   = 90
const NID_policy_constraints         = 401
const NID_ext_key_usage              = 126
const NID_freshest_crl               = 857
const NID_inhibit_any_policy         = 748
const NID_target_information         = 402
const NID_no_rev_avail               = 403
const NID_anyExtendedKeyUsage        = 910
const NID_netscape                   = 57
const NID_netscape_cert_extension    = 58
const NID_netscape_data_type         = 59
const NID_netscape_cert_type         = 71
const NID_netscape_base_url          = 72
const NID_netscape_revocation_url    = 73
const NID_netscape_ca_revocation_url = 74
const NID_netscape_renewal_url       = 75
const NID_netscape_ca_policy_url     = 76
const NID_netscape_ssl_server_name   = 77
const NID_netscape_comment           = 78
const NID_netscape_cert_sequence     = 79
const NID_ns_sgc                     = 139
const NID_org                        = 379
const NID_dod                        = 380
const NID_iana                       = 381
const NID_Directory                  = 382
const NID_Management                 = 383
const NID_Experimental               = 384
const NID_Private                    = 385
const NID_Security                   = 386
const NID_SNMPv2                     = 387
const NID_Mail                       = 388
const NID_Enterprises                = 389
const NID_dcObject                   = 390
const NID_mime_mhs                   = 504
const NID_mime_mhs_headings          = 505
const NID_mime_mhs_bodies            = 506
const NID_id_hex_partial_message     = 507
const NID_id_hex_multipart_message   = 508
const NID_rle_compression            = 124
const NID_zlib_compression           = 125
const NID_aes_128_ecb                = 418
const NID_aes_128_cbc                = 419
const NID_aes_128_ofb128             = 420
const NID_aes_128_cfb128             = 421
const NID_id_aes128_wrap             = 788
const NID_aes_128_gcm                = 895
const NID_aes_128_ccm                = 896
const NID_id_aes128_wrap_pad         = 897
const NID_aes_192_ecb                = 422
const NID_aes_192_cbc                = 423
const NID_aes_192_ofb128             = 424
const NID_aes_192_cfb128             = 425
const NID_id_aes192_wrap             = 789
const NID_aes_192_gcm                = 898
const NID_aes_192_ccm                = 899
const NID_id_aes192_wrap_pad         = 900
const NID_aes_256_ecb                = 426
const NID_aes_256_cbc                = 427
const NID_aes_256_ofb128             = 428
const NID_aes_256_cfb128             = 429
const NID_id_aes256_wrap             = 790
const NID_aes_256_gcm                = 901
const NID_aes_256_ccm                = 902
const NID_id_aes256_wrap_pad         = 903
const NID_aes_128_cfb1               = 650
const NID_aes_192_cfb1               = 651
const NID_aes_256_cfb1               = 652
const NID_aes_128_cfb8               = 653
const NID_aes_192_cfb8               = 654
const NID_aes_256_cfb8               = 655
const NID_aes_128_ctr                = 904
const NID_aes_192_ctr                = 905
const NID_aes_256_ctr                = 906
const NID_aes_128_xts                = 913
const NID_aes_256_xts                = 914
const NID_des_cfb1                   = 656
const NID_des_cfb8                   = 657
const NID_des_ede3_cfb1              = 658
const NID_des_ede3_cfb8              = 659
const NID_sha256                     = 672
const NID_sha384                     = 673
const NID_sha512                     = 674
const NID_sha224                     = 675
const NID_dsa_with_SHA224            = 802
const NID_dsa_with_SHA256            = 803
const NID_hold_instruction_code      = 430
const NID_hold_instruction_none      = 431
const NID_hold_instruction_call_issuer = 432
const NID_hold_instruction_reject    = 433
const NID_data                       = 434
const NID_pss                        = 435
const NID_ucl                        = 436
const NID_pilot                      = 437
const NID_pilotAttributeType         = 438
const NID_pilotAttributeSyntax       = 439
const NID_pilotObjectClass           = 440
const NID_pilotGroups                = 441
const NID_iA5StringSyntax            = 442
const NID_caseIgnoreIA5StringSyntax  = 443
const NID_pilotObject                = 444
const NID_pilotPerson                = 445
const NID_account                    = 446
const NID_document                   = 447
const NID_room                       = 448
const NID_documentSeries             = 449
const NID_Domain                     = 392
const NID_rFC822localPart            = 450
const NID_dNSDomain                  = 451
const NID_domainRelatedObject        = 452
const NID_friendlyCountry            = 453
const NID_simpleSecurityObject       = 454
const NID_pilotOrganization          = 455
const NID_pilotDSA                   = 456
const NID_qualityLabelledData        = 457
const NID_userId                     = 458
const NID_textEncodedORAddress       = 459
const NID_rfc822Mailbox              = 460
const NID_info                       = 461
const NID_favouriteDrink             = 462
const NID_roomNumber                 = 463
const NID_photo                      = 464
const NID_userClass                  = 465
const NID_host                       = 466
const NID_manager                    = 467
const NID_documentIdentifier         = 468
const NID_documentTitle              = 469
const NID_documentVersion            = 470
const NID_documentAuthor             = 471
const NID_documentLocation           = 472
const NID_homeTelephoneNumber        = 473
const NID_secretary                  = 474
const NID_otherMailbox               = 475
const NID_lastModifiedTime           = 476
const NID_lastModifiedBy             = 477
const NID_domainComponent            = 391
const NID_aRecord                    = 478
const NID_pilotAttributeType27       = 479
const NID_mXRecord                   = 480
const NID_nSRecord                   = 481
const NID_sOARecord                  = 482
const NID_cNAMERecord                = 483
const NID_associatedDomain           = 484
const NID_associatedName             = 485
const NID_homePostalAddress          = 486
const NID_personalTitle              = 487
const NID_mobileTelephoneNumber      = 488
const NID_pagerTelephoneNumber       = 489
const NID_friendlyCountryName        = 490
const NID_organizationalStatus       = 491
const NID_janetMailbox               = 492
const NID_mailPreferenceOption       = 493
const NID_buildingName               = 494
const NID_dSAQuality                 = 495
const NID_singleLevelQuality         = 496
const NID_subtreeMinimumQuality      = 497
const NID_subtreeMaximumQuality      = 498
const NID_personalSignature          = 499
const NID_dITRedirect                = 500
const NID_audio                      = 501
const NID_documentPublisher          = 502
const NID_id_set                     = 512
const NID_set_ctype                  = 513
const NID_set_msgExt                 = 514
const NID_set_attr                   = 515
const NID_set_policy                 = 516
const NID_set_certExt                = 517
const NID_set_brand                  = 518
const NID_setct_PANData              = 519
const NID_setct_PANToken             = 520
const NID_setct_PANOnly              = 521
const NID_setct_OIData               = 522
const NID_setct_PI                   = 523
const NID_setct_PIData               = 524
const NID_setct_PIDataUnsigned       = 525
const NID_setct_HODInput             = 526
const NID_setct_AuthResBaggage       = 527
const NID_setct_AuthRevReqBaggage    = 528
const NID_setct_AuthRevResBaggage    = 529
const NID_setct_CapTokenSeq          = 530
const NID_setct_PInitResData         = 531
const NID_setct_PI_TBS               = 532
const NID_setct_PResData             = 533
const NID_setct_AuthReqTBS           = 534
const NID_setct_AuthResTBS           = 535
const NID_setct_AuthResTBSX          = 536
const NID_setct_AuthTokenTBS         = 537
const NID_setct_CapTokenData         = 538
const NID_setct_CapTokenTBS          = 539
const NID_setct_AcqCardCodeMsg       = 540
const NID_setct_AuthRevReqTBS        = 541
const NID_setct_AuthRevResData       = 542
const NID_setct_AuthRevResTBS        = 543
const NID_setct_CapReqTBS            = 544
const NID_setct_CapReqTBSX           = 545
const NID_setct_CapResData           = 546
const NID_setct_CapRevReqTBS         = 547
const NID_setct_CapRevReqTBSX        = 548
const NID_setct_CapRevResData        = 549
const NID_setct_CredReqTBS           = 550
const NID_setct_CredReqTBSX          = 551
const NID_setct_CredResData          = 552
const NID_setct_CredRevReqTBS        = 553
const NID_setct_CredRevReqTBSX       = 554
const NID_setct_CredRevResData       = 555
const NID_setct_PCertReqData         = 556
const NID_setct_PCertResTBS          = 557
const NID_setct_BatchAdminReqData    = 558
const NID_setct_BatchAdminResData    = 559
const NID_setct_CardCInitResTBS      = 560
const NID_setct_MeAqCInitResTBS      = 561
const NID_setct_RegFormResTBS        = 562
const NID_setct_CertReqData          = 563
const NID_setct_CertReqTBS           = 564
const NID_setct_CertResData          = 565
const NID_setct_CertInqReqTBS        = 566
const NID_setct_ErrorTBS             = 567
const NID_setct_PIDualSignedTBE      = 568
const NID_setct_PIUnsignedTBE        = 569
const NID_setct_AuthReqTBE           = 570
const NID_setct_AuthResTBE           = 571
const NID_setct_AuthResTBEX          = 572
const NID_setct_AuthTokenTBE         = 573
const NID_setct_CapTokenTBE          = 574
const NID_setct_CapTokenTBEX         = 575
const NID_setct_AcqCardCodeMsgTBE    = 576
const NID_setct_AuthRevReqTBE        = 577
const NID_setct_AuthRevResTBE        = 578
const NID_setct_AuthRevResTBEB       = 579
const NID_setct_CapReqTBE            = 580
const NID_setct_CapReqTBEX           = 581
const NID_setct_CapResTBE            = 582
const NID_setct_CapRevReqTBE         = 583
const NID_setct_CapRevReqTBEX        = 584
const NID_setct_CapRevResTBE         = 585
const NID_setct_CredReqTBE           = 586
const NID_setct_CredReqTBEX          = 587
const NID_setct_CredResTBE           = 588
const NID_setct_CredRevReqTBE        = 589
const NID_setct_CredRevReqTBEX       = 590
const NID_setct_CredRevResTBE        = 591
const NID_setct_BatchAdminReqTBE     = 592
const NID_setct_BatchAdminResTBE     = 593
const NID_setct_RegFormReqTBE        = 594
const NID_setct_CertReqTBE           = 595
const NID_setct_CertReqTBEX          = 596
const NID_setct_CertResTBE           = 597
const NID_setct_CRLNotificationTBS   = 598
const NID_setct_CRLNotificationResTBS = 599
const NID_setct_BCIDistributionTBS   = 600
const NID_setext_genCrypt            = 601
const NID_setext_miAuth              = 602
const NID_setext_pinSecure           = 603
const NID_setext_pinAny              = 604
const NID_setext_track2              = 605
const NID_setext_cv                  = 606
const NID_set_policy_root            = 607
const NID_setCext_hashedRoot         = 608
const NID_setCext_certType           = 609
const NID_setCext_merchData          = 610
const NID_setCext_cCertRequired      = 611
const NID_setCext_tunneling          = 612
const NID_setCext_setExt             = 613
const NID_setCext_setQualf           = 614
const NID_setCext_PGWYcapabilities   = 615
const NID_setCext_TokenIdentifier    = 616
const NID_setCext_Track2Data         = 617
const NID_setCext_TokenType          = 618
const NID_setCext_IssuerCapabilities = 619
const NID_setAttr_Cert               = 620
const NID_setAttr_PGWYcap            = 621
const NID_setAttr_TokenType          = 622
const NID_setAttr_IssCap             = 623
const NID_set_rootKeyThumb           = 624
const NID_set_addPolicy              = 625
const NID_setAttr_Token_EMV          = 626
const NID_setAttr_Token_B0Prime      = 627
const NID_setAttr_IssCap_CVM         = 628
const NID_setAttr_IssCap_T2          = 629
const NID_setAttr_IssCap_Sig         = 630
const NID_setAttr_GenCryptgrm        = 631
const NID_setAttr_T2Enc              = 632
const NID_setAttr_T2cleartxt         = 633
const NID_setAttr_TokICCsig          = 634
const NID_setAttr_SecDevSig          = 635
const NID_set_brand_IATA_ATA         = 636
const NID_set_brand_Diners           = 637
const NID_set_brand_AmericanExpress  = 638
const NID_set_brand_JCB              = 639
const NID_set_brand_Visa             = 640
const NID_set_brand_MasterCard       = 641
const NID_set_brand_Novus            = 642
const NID_des_cdmf                   = 643
const NID_rsaOAEPEncryptionSET       = 644
const NID_ipsec3                     = 749
const NID_ipsec4                     = 750
const NID_whirlpool                  = 804
const NID_cryptopro                  = 805
const NID_cryptocom                  = 806
const NID_id_GostR3411_94_with_GostR3410_2001 = 807
const NID_id_GostR3411_94_with_GostR3410_94 = 808
const NID_id_GostR3411_94            = 809
const NID_id_HMACGostR3411_94        = 810
const NID_id_GostR3410_2001          = 811
const NID_id_GostR3410_94            = 812
const NID_id_Gost28147_89            = 813
const NID_gost89_cnt                 = 814
const NID_id_Gost28147_89_MAC        = 815
const NID_id_GostR3411_94_prf        = 816
const NID_id_GostR3410_2001DH        = 817
const NID_id_GostR3410_94DH          = 818
const NID_id_Gost28147_89_CryptoPro_KeyMeshing = 819
const NID_id_Gost28147_89_None_KeyMeshing = 820
const NID_id_GostR3411_94_TestParamSet = 821
const NID_id_GostR3411_94_CryptoProParamSet = 822
const NID_id_Gost28147_89_TestParamSet = 823
const NID_id_Gost28147_89_CryptoPro_A_ParamSet = 824
const NID_id_Gost28147_89_CryptoPro_B_ParamSet = 825
const NID_id_Gost28147_89_CryptoPro_C_ParamSet = 826
const NID_id_Gost28147_89_CryptoPro_D_ParamSet = 827
const NID_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet = 828
const NID_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet = 829
const NID_id_Gost28147_89_CryptoPro_RIC_1_ParamSet = 830
const NID_id_GostR3410_94_TestParamSet = 831
const NID_id_GostR3410_94_CryptoPro_A_ParamSet = 832
const NID_id_GostR3410_94_CryptoPro_B_ParamSet = 833
const NID_id_GostR3410_94_CryptoPro_C_ParamSet = 834
const NID_id_GostR3410_94_CryptoPro_D_ParamSet = 835
const NID_id_GostR3410_94_CryptoPro_XchA_ParamSet = 836
const NID_id_GostR3410_94_CryptoPro_XchB_ParamSet = 837
const NID_id_GostR3410_94_CryptoPro_XchC_ParamSet = 838
const NID_id_GostR3410_2001_TestParamSet = 839
const NID_id_GostR3410_2001_CryptoPro_A_ParamSet = 840
const NID_id_GostR3410_2001_CryptoPro_B_ParamSet = 841
const NID_id_GostR3410_2001_CryptoPro_C_ParamSet = 842
const NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet = 843
const NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet = 844
const NID_id_GostR3410_94_a          = 845
const NID_id_GostR3410_94_aBis       = 846
const NID_id_GostR3410_94_b          = 847
const NID_id_GostR3410_94_bBis       = 848
const NID_id_Gost28147_89_cc         = 849
const NID_id_GostR3410_94_cc         = 850
const NID_id_GostR3410_2001_cc       = 851
const NID_id_GostR3411_94_with_GostR3410_94_cc = 852
const NID_id_GostR3411_94_with_GostR3410_2001_cc = 853
const NID_id_GostR3410_2001_ParamSet_cc = 854
const NID_camellia_128_cbc           = 751
const NID_camellia_192_cbc           = 752
const NID_camellia_256_cbc           = 753
const NID_id_camellia128_wrap        = 907
const NID_id_camellia192_wrap        = 908
const NID_id_camellia256_wrap        = 909
const NID_camellia_128_ecb           = 754
const NID_camellia_128_ofb128        = 766
const NID_camellia_128_cfb128        = 757
const NID_camellia_192_ecb           = 755
const NID_camellia_192_ofb128        = 767
const NID_camellia_192_cfb128        = 758
const NID_camellia_256_ecb           = 756
const NID_camellia_256_ofb128        = 768
const NID_camellia_256_cfb128        = 759
const NID_camellia_128_cfb1          = 760
const NID_camellia_192_cfb1          = 761
const NID_camellia_256_cfb1          = 762
const NID_camellia_128_cfb8          = 763
const NID_camellia_192_cfb8          = 764
const NID_camellia_256_cfb8          = 765
const NID_kisa                       = 773
const NID_seed_ecb                   = 776
const NID_seed_cbc                   = 777
const NID_seed_cfb128                = 779
const NID_seed_ofb128                = 778
const NID_hmac                       = 855
const NID_cmac                       = 894
const NID_rc4_hmac_md5               = 915
const NID_aes_128_cbc_hmac_sha1      = 916
const NID_aes_192_cbc_hmac_sha1      = 917
const NID_aes_256_cbc_hmac_sha1      = 918
const EVP_PK_RSA                     = 0x0001
const EVP_PK_DSA                     = 0x0002
const EVP_PK_DH                      = 0x0004
const EVP_PK_EC                      = 0x0008
const EVP_PKT_SIGN                   = 0x0010
const EVP_PKT_ENC                    = 0x0020
const EVP_PKT_EXCH                   = 0x0040
const EVP_PKS_RSA                    = 0x0100
const EVP_PKS_DSA                    = 0x0200
const EVP_PKS_EC                     = 0x0400
const EVP_PKT_EXP                    = 0x1000
const EVP_PKEY_NONE                  = NID_undef
const EVP_PKEY_RSA                   = NID_rsaEncryption
const EVP_PKEY_RSA2                  = NID_rsa
const EVP_PKEY_DSA                   = NID_dsa
const EVP_PKEY_DSA1                  = NID_dsa_2
const EVP_PKEY_DSA2                  = NID_dsaWithSHA
const EVP_PKEY_DSA3                  = NID_dsaWithSHA1
const EVP_PKEY_DSA4                  = NID_dsaWithSHA1_2
const EVP_PKEY_DH                    = NID_dhKeyAgreement
const EVP_PKEY_EC                    = NID_X9_62_id_ecPublicKey
const EVP_PKEY_HMAC                  = NID_hmac
const EVP_PKEY_CMAC                  = NID_cmac
const EVP_PKEY_MO_SIGN               = 0x0001
const EVP_PKEY_MO_VERIFY             = 0x0002
const EVP_PKEY_MO_ENCRYPT            = 0x0004
const EVP_PKEY_MO_DECRYPT            = 0x0008
const EVP_MD_FLAG_ONESHOT            = 0x0001
const EVP_MD_FLAG_PKEY_DIGEST        = 0x0002
const EVP_MD_FLAG_PKEY_METHOD_SIGNATURE = 0x0004
const EVP_MD_FLAG_DIGALGID_MASK      = 0x0018
const EVP_MD_FLAG_DIGALGID_NULL      = 0x0000
const EVP_MD_FLAG_DIGALGID_ABSENT    = 0x0008
const EVP_MD_FLAG_DIGALGID_CUSTOM    = 0x0018
const EVP_MD_FLAG_FIPS               = 0x0400
const EVP_MD_CTRL_DIGALGID           = 0x1
const EVP_MD_CTRL_MICALG             = 0x2
const EVP_MD_CTRL_ALG_CTRL           = 0x1000
const EVP_MD_CTX_FLAG_ONESHOT        = 0x0001
const EVP_MD_CTX_FLAG_CLEANED        = 0x0002
const EVP_MD_CTX_FLAG_REUSE          = 0x0004
const EVP_MD_CTX_FLAG_NON_FIPS_ALLOW = 0x0008
const EVP_MD_CTX_FLAG_PAD_MASK       = 0xF0
const EVP_MD_CTX_FLAG_PAD_PKCS1      = 0x00
const EVP_MD_CTX_FLAG_PAD_X931       = 0x10
const EVP_MD_CTX_FLAG_PAD_PSS        = 0x20
const EVP_MD_CTX_FLAG_NO_INIT        = 0x0100
const EVP_CIPH_STREAM_CIPHER         = 0x0
const EVP_CIPH_ECB_MODE              = 0x1
const EVP_CIPH_CBC_MODE              = 0x2
const EVP_CIPH_CFB_MODE              = 0x3
const EVP_CIPH_OFB_MODE              = 0x4
const EVP_CIPH_CTR_MODE              = 0x5
const EVP_CIPH_GCM_MODE              = 0x6
const EVP_CIPH_CCM_MODE              = 0x7
const EVP_CIPH_XTS_MODE              = 0x10001
const EVP_CIPH_MODE                  = 0xF0007
const EVP_CIPH_VARIABLE_LENGTH       = 0x8
const EVP_CIPH_CUSTOM_IV             = 0x10
const EVP_CIPH_ALWAYS_CALL_INIT      = 0x20
const EVP_CIPH_CTRL_INIT             = 0x40
const EVP_CIPH_CUSTOM_KEY_LENGTH     = 0x80
const EVP_CIPH_NO_PADDING            = 0x100
const EVP_CIPH_RAND_KEY              = 0x200
const EVP_CIPH_CUSTOM_COPY           = 0x400
const EVP_CIPH_FLAG_DEFAULT_ASN1     = 0x1000
const EVP_CIPH_FLAG_LENGTH_BITS      = 0x2000
const EVP_CIPH_FLAG_FIPS             = 0x4000
const EVP_CIPH_FLAG_NON_FIPS_ALLOW   = 0x8000
const EVP_CIPH_FLAG_CUSTOM_CIPHER    = 0x100000
const EVP_CIPH_FLAG_AEAD_CIPHER      = 0x200000
const EVP_CTRL_INIT                  = 0x0
const EVP_CTRL_SET_KEY_LENGTH        = 0x1
const EVP_CTRL_GET_RC2_KEY_BITS      = 0x2
const EVP_CTRL_SET_RC2_KEY_BITS      = 0x3
const EVP_CTRL_GET_RC5_ROUNDS        = 0x4
const EVP_CTRL_SET_RC5_ROUNDS        = 0x5
const EVP_CTRL_RAND_KEY              = 0x6
const EVP_CTRL_PBE_PRF_NID           = 0x7
const EVP_CTRL_COPY                  = 0x8
const EVP_CTRL_GCM_SET_IVLEN         = 0x9
const EVP_CTRL_GCM_GET_TAG           = 0x10
const EVP_CTRL_GCM_SET_TAG           = 0x11
const EVP_CTRL_GCM_SET_IV_FIXED      = 0x12
const EVP_CTRL_GCM_IV_GEN            = 0x13
const EVP_CTRL_CCM_SET_IVLEN         = EVP_CTRL_GCM_SET_IVLEN
const EVP_CTRL_CCM_GET_TAG           = EVP_CTRL_GCM_GET_TAG
const EVP_CTRL_CCM_SET_TAG           = EVP_CTRL_GCM_SET_TAG
const EVP_CTRL_CCM_SET_L             = 0x14
const EVP_CTRL_CCM_SET_MSGLEN        = 0x15
const EVP_CTRL_AEAD_TLS1_AAD         = 0x16
const EVP_CTRL_AEAD_SET_MAC_KEY      = 0x17
const EVP_CTRL_GCM_SET_IV_INV        = 0x18
const EVP_GCM_TLS_FIXED_IV_LEN       = 4
const EVP_GCM_TLS_EXPLICIT_IV_LEN    = 8
const EVP_GCM_TLS_TAG_LEN            = 16
const EVP_des_cfb                    = EVP_des_cfb64
const EVP_des_ede_cfb                = EVP_des_ede_cfb64
const EVP_des_ede3_cfb               = EVP_des_ede3_cfb64
const EVP_rc2_cfb                    = EVP_rc2_cfb64
const EVP_bf_cfb                     = EVP_bf_cfb64
const EVP_cast5_cfb                  = EVP_cast5_cfb64
const EVP_aes_128_cfb                = EVP_aes_128_cfb128
const EVP_aes_192_cfb                = EVP_aes_192_cfb128
const EVP_aes_256_cfb                = EVP_aes_256_cfb128
const EVP_camellia_128_cfb           = EVP_camellia_128_cfb128
const EVP_camellia_192_cfb           = EVP_camellia_192_cfb128
const EVP_camellia_256_cfb           = EVP_camellia_256_cfb128
const EVP_seed_cfb                   = EVP_seed_cfb128
const EVP_PBE_TYPE_OUTER             = 0x0
const EVP_PBE_TYPE_PRF               = 0x1
const EVP_PKEY_OP_UNDEFINED          = 0
const EVP_PKEY_OP_PARAMGEN           = (1<<1)
const EVP_PKEY_OP_KEYGEN             = (1<<2)
const EVP_PKEY_OP_SIGN               = (1<<3)
const EVP_PKEY_OP_VERIFY             = (1<<4)
const EVP_PKEY_OP_VERIFYRECOVER      = (1<<5)
const EVP_PKEY_OP_SIGNCTX            = (1<<6)
const EVP_PKEY_OP_VERIFYCTX          = (1<<7)
const EVP_PKEY_OP_ENCRYPT            = (1<<8)
const EVP_PKEY_OP_DECRYPT            = (1<<9)
const EVP_PKEY_OP_DERIVE             = (1<<10)
const EVP_PKEY_OP_TYPE_SIG           = (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY | EVP_PKEY_OP_VERIFYRECOVER | EVP_PKEY_OP_SIGNCTX | EVP_PKEY_OP_VERIFYCTX)
const EVP_PKEY_OP_TYPE_CRYPT         = (EVP_PKEY_OP_ENCRYPT | EVP_PKEY_OP_DECRYPT)
const EVP_PKEY_OP_TYPE_GEN           = (EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN)
const EVP_PKEY_CTRL_MD               = 1
const EVP_PKEY_CTRL_PEER_KEY         = 2
const EVP_PKEY_CTRL_PKCS7_ENCRYPT    = 3
const EVP_PKEY_CTRL_PKCS7_DECRYPT    = 4
const EVP_PKEY_CTRL_PKCS7_SIGN       = 5
const EVP_PKEY_CTRL_SET_MAC_KEY      = 6
const EVP_PKEY_CTRL_DIGESTINIT       = 7
const EVP_PKEY_CTRL_SET_IV           = 8
const EVP_PKEY_CTRL_CMS_ENCRYPT      = 9
const EVP_PKEY_CTRL_CMS_DECRYPT      = 10
const EVP_PKEY_CTRL_CMS_SIGN         = 11
const EVP_PKEY_CTRL_CIPHER           = 12
const EVP_PKEY_ALG_CTRL              = 0x1000
const EVP_PKEY_FLAG_AUTOARGLEN       = 2
const EVP_PKEY_FLAG_SIGCTX_CUSTOM    = 4
const EVP_F_AESNI_INIT_KEY           = 165
const EVP_F_AESNI_XTS_CIPHER         = 176
const EVP_F_AES_INIT_KEY             = 133
const EVP_F_AES_XTS                  = 172
const EVP_F_AES_XTS_CIPHER           = 175
const EVP_F_CAMELLIA_INIT_KEY        = 159
const EVP_F_CMAC_INIT                = 173
const EVP_F_D2I_PKEY                 = 100
const EVP_F_DO_SIGVER_INIT           = 161
const EVP_F_DSAPKEY2PKCS8            = 134
const EVP_F_DSA_PKEY2PKCS8           = 135
const EVP_F_ECDSA_PKEY2PKCS8         = 129
const EVP_F_ECKEY_PKEY2PKCS8         = 132
const EVP_F_EVP_CIPHERINIT_EX        = 123
const EVP_F_EVP_CIPHER_CTX_COPY      = 163
const EVP_F_EVP_CIPHER_CTX_CTRL      = 124
const EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH = 122
const EVP_F_EVP_DECRYPTFINAL_EX      = 101
const EVP_F_EVP_DIGESTINIT_EX        = 128
const EVP_F_EVP_ENCRYPTFINAL_EX      = 127
const EVP_F_EVP_MD_CTX_COPY_EX       = 110
const EVP_F_EVP_MD_SIZE              = 162
const EVP_F_EVP_OPENINIT             = 102
const EVP_F_EVP_PBE_ALG_ADD          = 115
const EVP_F_EVP_PBE_ALG_ADD_TYPE     = 160
const EVP_F_EVP_PBE_CIPHERINIT       = 116
const EVP_F_EVP_PKCS82PKEY           = 111
const EVP_F_EVP_PKCS82PKEY_BROKEN    = 136
const EVP_F_EVP_PKEY2PKCS8_BROKEN    = 113
const EVP_F_EVP_PKEY_COPY_PARAMETERS = 103
const EVP_F_EVP_PKEY_CTX_CTRL        = 137
const EVP_F_EVP_PKEY_CTX_CTRL_STR    = 150
const EVP_F_EVP_PKEY_CTX_DUP         = 156
const EVP_F_EVP_PKEY_DECRYPT         = 104
const EVP_F_EVP_PKEY_DECRYPT_INIT    = 138
const EVP_F_EVP_PKEY_DECRYPT_OLD     = 151
const EVP_F_EVP_PKEY_DERIVE          = 153
const EVP_F_EVP_PKEY_DERIVE_INIT     = 154
const EVP_F_EVP_PKEY_DERIVE_SET_PEER = 155
const EVP_F_EVP_PKEY_ENCRYPT         = 105
const EVP_F_EVP_PKEY_ENCRYPT_INIT    = 139
const EVP_F_EVP_PKEY_ENCRYPT_OLD     = 152
const EVP_F_EVP_PKEY_GET1_DH         = 119
const EVP_F_EVP_PKEY_GET1_DSA        = 120
const EVP_F_EVP_PKEY_GET1_ECDSA      = 130
const EVP_F_EVP_PKEY_GET1_EC_KEY     = 131
const EVP_F_EVP_PKEY_GET1_RSA        = 121
const EVP_F_EVP_PKEY_KEYGEN          = 146
const EVP_F_EVP_PKEY_KEYGEN_INIT     = 147
const EVP_F_EVP_PKEY_NEW             = 106
const EVP_F_EVP_PKEY_PARAMGEN        = 148
const EVP_F_EVP_PKEY_PARAMGEN_INIT   = 149
const EVP_F_EVP_PKEY_SIGN            = 140
const EVP_F_EVP_PKEY_SIGN_INIT       = 141
const EVP_F_EVP_PKEY_VERIFY          = 142
const EVP_F_EVP_PKEY_VERIFY_INIT     = 143
const EVP_F_EVP_PKEY_VERIFY_RECOVER  = 144
const EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT = 145
const EVP_F_EVP_RIJNDAEL             = 126
const EVP_F_EVP_SIGNFINAL            = 107
const EVP_F_EVP_VERIFYFINAL          = 108
const EVP_F_FIPS_CIPHERINIT          = 166
const EVP_F_FIPS_CIPHER_CTX_COPY     = 170
const EVP_F_FIPS_CIPHER_CTX_CTRL     = 167
const EVP_F_FIPS_CIPHER_CTX_SET_KEY_LENGTH = 171
const EVP_F_FIPS_DIGESTINIT          = 168
const EVP_F_FIPS_MD_CTX_COPY         = 169
const EVP_F_HMAC_INIT_EX             = 174
const EVP_F_INT_CTX_NEW              = 157
const EVP_F_PKCS5_PBE_KEYIVGEN       = 117
const EVP_F_PKCS5_V2_PBE_KEYIVGEN    = 118
const EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN = 164
const EVP_F_PKCS8_SET_BROKEN         = 112
const EVP_F_PKEY_SET_TYPE            = 158
const EVP_F_RC2_MAGIC_TO_METH        = 109
const EVP_F_RC5_CTRL                 = 125
const EVP_R_AES_IV_SETUP_FAILED      = 162
const EVP_R_AES_KEY_SETUP_FAILED     = 143
const EVP_R_ASN1_LIB                 = 140
const EVP_R_BAD_BLOCK_LENGTH         = 136
const EVP_R_BAD_DECRYPT              = 100
const EVP_R_BAD_KEY_LENGTH           = 137
const EVP_R_BN_DECODE_ERROR          = 112
const EVP_R_BN_PUBKEY_ERROR          = 113
const EVP_R_BUFFER_TOO_SMALL         = 155
const EVP_R_CAMELLIA_KEY_SETUP_FAILED = 157
const EVP_R_CIPHER_PARAMETER_ERROR   = 122
const EVP_R_COMMAND_NOT_SUPPORTED    = 147
const EVP_R_CTRL_NOT_IMPLEMENTED     = 132
const EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED = 133
const EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH = 138
const EVP_R_DECODE_ERROR             = 114
const EVP_R_DIFFERENT_KEY_TYPES      = 101
const EVP_R_DIFFERENT_PARAMETERS     = 153
const EVP_R_DISABLED_FOR_FIPS        = 163
const EVP_R_ENCODE_ERROR             = 115
const EVP_R_EVP_PBE_CIPHERINIT_ERROR = 119
const EVP_R_EXPECTING_AN_RSA_KEY     = 127
const EVP_R_EXPECTING_A_DH_KEY       = 128
const EVP_R_EXPECTING_A_DSA_KEY      = 129
const EVP_R_EXPECTING_A_ECDSA_KEY    = 141
const EVP_R_EXPECTING_A_EC_KEY       = 142
const EVP_R_INITIALIZATION_ERROR     = 134
const EVP_R_INPUT_NOT_INITIALIZED    = 111
const EVP_R_INVALID_DIGEST           = 152
const EVP_R_INVALID_KEY_LENGTH       = 130
const EVP_R_INVALID_OPERATION        = 148
const EVP_R_IV_TOO_LARGE             = 102
const EVP_R_KEYGEN_FAILURE           = 120
const EVP_R_MESSAGE_DIGEST_IS_NULL   = 159
const EVP_R_METHOD_NOT_SUPPORTED     = 144
const EVP_R_MISSING_PARAMETERS       = 103
const EVP_R_NO_CIPHER_SET            = 131
const EVP_R_NO_DEFAULT_DIGEST        = 158
const EVP_R_NO_DIGEST_SET            = 139
const EVP_R_NO_DSA_PARAMETERS        = 116
const EVP_R_NO_KEY_SET               = 154
const EVP_R_NO_OPERATION_SET         = 149
const EVP_R_NO_SIGN_FUNCTION_CONFIGURED = 104
const EVP_R_NO_VERIFY_FUNCTION_CONFIGURED = 105
const EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE = 150
const EVP_R_OPERATON_NOT_INITIALIZED = 151
const EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE = 117
const EVP_R_PRIVATE_KEY_DECODE_ERROR = 145
const EVP_R_PRIVATE_KEY_ENCODE_ERROR = 146
const EVP_R_PUBLIC_KEY_NOT_RSA       = 106
const EVP_R_TOO_LARGE                = 164
const EVP_R_UNKNOWN_CIPHER           = 160
const EVP_R_UNKNOWN_DIGEST           = 161
const EVP_R_UNKNOWN_PBE_ALGORITHM    = 121
const EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS = 135
const EVP_R_UNSUPPORTED_ALGORITHM    = 156
const EVP_R_UNSUPPORTED_CIPHER       = 107
const EVP_R_UNSUPPORTED_KEYLENGTH    = 123
const EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION = 124
const EVP_R_UNSUPPORTED_KEY_SIZE     = 108
const EVP_R_UNSUPPORTED_PRF          = 125
const EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM = 118
const EVP_R_UNSUPPORTED_SALT_TYPE    = 126
const EVP_R_WRONG_FINAL_BLOCK_LENGTH = 109
const EVP_R_WRONG_PUBLIC_KEY_TYPE    = 110
const HMAC_MAX_MD_CBLOCK             = 128
const SHA_LBLOCK                     = 16
const SHA_CBLOCK                     = (SHA_LBLOCK*4)
const SHA_LAST_BLOCK                 = (SHA_CBLOCK-8)
const SHA_DIGEST_LENGTH              = 20
const SHA256_CBLOCK                  = (SHA_LBLOCK*4)
const SHA224_DIGEST_LENGTH           = 28
const SHA256_DIGEST_LENGTH           = 32
const SHA384_DIGEST_LENGTH           = 48
const SHA512_DIGEST_LENGTH           = 64
const SHA512_CBLOCK                  = (SHA_LBLOCK*8)

ext: jl


text:
#
# Conjugate gradient
#
# This is an independent implementation of:
#   W. W. Hager and H. Zhang (2006) Algorithm 851: CG_DESCENT, a
#     conjugate gradient method with guaranteed descent. ACM
#     Transactions on Mathematical Software 32: 113–137.
#
# Code comments such as "HZ, stage X" or "HZ, eqs Y" are with
# reference to a particular point in this paper.
#
# Several aspects of the following have also been incorporated:
#   W. W. Hager and H. Zhang (2013) The limited memory conjugate
#     gradient method.
#
# This paper will be denoted HZ2013 below.
#
#
# There are some modifications and/or extensions from what's in the
# paper (these may or may not be extensions of the cg_descent code
# that can be downloaded from Hager's site; his code has undergone
# numerous revisions since publication of the paper):
#
# cgdescent: the termination condition employs a "unit-correct"
#   expression rather than a condition on gradient
#   components---whether this is a good or bad idea will require
#   additional experience, but preliminary evidence seems to suggest
#   that it makes "reasonable" choices over a wider range of problem
#   types.
#
# both: checks for Inf/NaN function values
#
# both: support maximum value of alpha (equivalently, c). This
#   facilitates using these routines for constrained minimization
#   when you can calculate the distance along the path to the
#   disallowed region. (When you can't easily calculate that
#   distance, it can still be handled by returning Inf/NaN for
#   exterior points. It's just more efficient if you know the
#   maximum, because you don't have to test values that won't
#   work.) The maximum should be specified as the largest value for
#   which a finite value will be returned.  See, e.g., limits_box
#   below.  The default value for alphamax is Inf. See alphamaxfunc
#   for cgdescent and alphamax for linesearch_hz.

struct ConjugateGradient{Tf, T, Tprep<:Union{Function, Nothing}, IL, L} <: FirstOrderOptimizer
    eta::Tf
    P::T
    precondprep!::Tprep
    alphaguess!::IL
    linesearch!::L
    manifold::Manifold
end

Base.summary(::ConjugateGradient) = "Conjugate Gradient"

"""
# Conjugate Gradient Descent
## Constructor
```julia
ConjugateGradient(; alphaguess = LineSearches.InitialHagerZhang(),
linesearch = LineSearches.HagerZhang(),
eta = 0.4,
P = nothing,
precondprep = (P, x) -> nothing,
manifold = Flat())
```
The strictly positive constant ``eta`` is used in determining
the next step direction, and the default here deviates from the one used in the
original paper (where it was ``0.01``). See more details in the original papers
referenced below.

## Description
The `ConjugateGradient` method implements Hager and Zhang (2006) and elements
from Hager and Zhang (2013). Notice, the default `linesearch` is `HagerZhang`
from LineSearches.jl. This line search is exactly the one proposed in Hager and
Zhang (2006).

## References
 - W. W. Hager and H. Zhang (2006) Algorithm 851: CG_DESCENT, a conjugate gradient method with guaranteed descent. ACM Transactions on Mathematical Software 32: 113-137.
 - W. W. Hager and H. Zhang (2013), The Limited Memory Conjugate Gradient Method. SIAM Journal on Optimization, 23, pp. 2150-2168.
"""
function ConjugateGradient(; alphaguess = LineSearches.InitialHagerZhang(),
                             linesearch = LineSearches.HagerZhang(),
                             eta::Real = 0.4,
                             P::Any = nothing,
                             precondprep = (P, x) -> nothing,
                             manifold::Manifold=Flat())

    ConjugateGradient(eta,
                      P, precondprep,
                      alphaguess, linesearch,
                      manifold)
end

mutable struct ConjugateGradientState{Tx,T,G} <: AbstractOptimizerState
    x::Tx
    x_previous::Tx
    g_previous::G
    f_x_previous::T
    y::Tx
    py::Tx
    pg::Tx
    s::Tx
    @add_linesearch_fields()
end

function initial_state(method::ConjugateGradient, options, d, initial_x)
    T = eltype(initial_x)
    initial_x = copy(initial_x)
    retract!(method.manifold, initial_x)

    value_gradient!!(d, initial_x)

    project_tangent!(method.manifold, gradient(d), initial_x)
    pg = copy(gradient(d))

    # Could move this out? as a general check?
    #=
    # Output messages
    isfinite(value(d)) || error("Initial f(x) is not finite ($(value(d)))")
    if !all(isfinite, gradient(d))
        @show gradient(d)
        @show find(.!isfinite.(gradient(d)))
        error("Gradient must have all finite values at starting point")
    end
    =#
    # Determine the intial search direction
    #    if we don't precondition, then this is an extra superfluous copy
    #    TODO: consider allowing a reference for pg instead of a copy
    method.precondprep!(method.P, initial_x)
    ldiv!(pg, method.P, gradient(d))
    if method.P != nothing
        project_tangent!(method.manifold, pg, initial_x)
    end

    ConjugateGradientState(initial_x, # Maintain current state in state.x
                         similar(initial_x), # Maintain previous state in state.x_previous
                         similar(gradient(d)), # Store previous gradient in state.g_previous
                         real(T)(NaN), # Store previous f in state.f_x_previous
                         similar(initial_x), # Intermediate value in CG calculation
                         similar(initial_x), # Preconditioned intermediate value in CG calculation
                         pg, # Maintain the preconditioned gradient in pg
                         -pg, # Maintain current search direction in state.s
                         @initial_linesearch()...)
end

function update_state!(d, state::ConjugateGradientState, method::ConjugateGradient)
        # Search direction is predetermined

        # Maintain a record of the previous gradient
        copyto!(state.g_previous, gradient(d))

        # Determine the distance of movement along the search line
        lssuccess = perform_linesearch!(state, method, ManifoldObjective(method.manifold, d))

        # Update current position # x = x + alpha * s
        @. state.x = state.x + state.alpha * state.s
        retract!(method.manifold, state.x)

        # Update the function value and gradient
        value_gradient!(d, state.x)
        project_tangent!(method.manifold, gradient(d), state.x)

        # Check sanity of function and gradient
        isfinite(value(d)) || error("Non-finite f(x) while optimizing ($(value(d)))")

        # Determine the next search direction using HZ's CG rule
        #  Calculate the beta factor (HZ2013)
        # -----------------
        # Comment on py: one could replace the computation of py with
        #    ydotpgprev = dot(y, pg)
        #    dot(y, py)  >>>  dot(y, pg) - ydotpgprev
        # but I am worried about round-off here, so instead we make an
        # extra copy, which is probably minimal overhead.
        # -----------------
        method.precondprep!(method.P, state.x)
        dPd = real(dot(state.s, method.P, state.s))
        etak = method.eta * real(dot(state.s, state.g_previous)) / dPd # New in HZ2013
        state.y .= gradient(d) .- state.g_previous
        ydots = real(dot(state.y, state.s))
        copyto!(state.py, state.pg)        # below, store pg - pg_previous in py
        ldiv!(state.pg, method.P, gradient(d))
        state.py .= state.pg .- state.py
        # ydots may be zero if f is not strongly convex or the line search does not satisfy Wolfe
        betak = (real(dot(state.y, state.pg)) - real(dot(state.y, state.py)) * real(dot(gradient(d), state.s)) / ydots) / ydots
        # betak may be undefined if ydots is zero (may due to f not strongly convex or non-Wolfe linesearch)
        beta = NaNMath.max(betak, etak) # TODO: Set to zero if betak is NaN?
        state.s .= beta.*state.s .- state.pg
        project_tangent!(method.manifold, state.s, state.x)
        lssuccess == false # break on linesearch error
end

update_g!(d, state, method::ConjugateGradient) = nothing

function assess_convergence(state::ConjugateGradientState, d, options)
  default_convergence_assessment(state, d, options)
end

function trace!(tr, d, state, iteration, method::ConjugateGradient, options)
  common_trace!(tr, d, state, iteration, method, options)
end


text:
module Makie

using AbstractPlotting
using GeometryTypes, Colors, ColorVectorSpace, StaticArrays
import IntervalSets
using IntervalSets: ClosedInterval, (..)
using ImageCore
import FileIO
using LinearAlgebra, Statistics
using Base64

module ContoursHygiene
    import Contour
end
using .ContoursHygiene
const Contours = ContoursHygiene.Contour

using Primes
using Base.Iterators: repeated, drop
using FreeType, FreeTypeAbstraction, UnicodeFun
using PlotUtils, Showoff
using Base: RefValue
import Base: push!, isopen, show

for name in names(AbstractPlotting)
    @eval import AbstractPlotting: $(name)
    @eval export $(name)
end

# Unexported names
using AbstractPlotting: @info, @log_performance, @warn, NativeFont, Key, @key_str

export (..), GLNormalUVMesh
# conflicting identifiers
using AbstractPlotting: Text, volume, VecTypes
using GeometryTypes: widths
export widths, decompose

const has_ffmpeg = Ref(false)

struct OpenGLBackend <: AbstractDisplay
end

function __init__()
    AbstractPlotting.register_backend!(OpenGLBackend())
    has_ffmpeg[] = try
        success(`ffmpeg -h`)
    catch
        false
    end
end

function logo()
    FileIO.load(joinpath(@__DIR__, "..", "docs", "src", "assets", "logo.png"))
end

include("makie_recipes.jl")
include("utils.jl")
include("glbackend/glbackend.jl")
# include("cairo/cairo.jl")
include("output.jl")
include("video_io.jl")

end


text:
@testset "kernelkroneckermat" begin
    rng = MersenneTwister(123456)
    k = SqExponentialKernel()
    x = range(0, 1; length=10)
    X = vcat(collect.(Iterators.product(x, x))'...)

    @test all(collect(kernelkronmat(k, collect(x), 2)) .≈ kernelmatrix(k, X; obsdim=1))
    @test all(collect(kernelkronmat(k, [x, x])) .≈ kernelmatrix(k, X; obsdim=1))
    @test_throws AssertionError kernelkronmat(LinearKernel(), collect(x), 2)
end


text:
using GLVisualize, GeometryTypes, GLAbstraction, Colors, FileIO

if !isdefined(:runtests)
    window = glscreen()
end
const static_example = true

# loadasset is defined as `loadasset(name) = load(assetphat(name))`
# load comes from FileIO, which automatically detects the file format and loads it
# in general, load will try to load the mesh as is, which may return different
# meshtypes. This is why it's wrapped into GLNormalMesh, to guarantee some type
# stability.
# Formats supported are currently: obj, stl, ply, off and 2DM
msh = GLNormalMesh(loadasset("cat.obj"))

_view(visualize(msh), window)

if !isdefined(:runtests)
    renderloop(window)
end


text:
@testset "SVDD_util_test" begin

    @testset "merge pool" begin
        pools = labelmap([:U, :Lin, :Lout, :U, :U, :Lin])

        @test [] == SVDD.merge_pools(pools, [])

        @test [1,4,5] == SVDD.merge_pools(pools, :U)
        @test [1,4,5] == sort(SVDD.merge_pools(pools, :U, :U))
        @test [2,6] == SVDD.merge_pools(pools, :Lin)
        @test [3] == SVDD.merge_pools(pools, :Lout)

        @test [2,3,6] == sort(SVDD.merge_pools(pools, :Lin, :Lout))
        @test collect(1:6) == sort(SVDD.merge_pools(pools, :U, :Lin, :Lout))

        @test_throws ArgumentError SVDD.merge_pools(pools, :A)
    end

    @testset "labelmap2vec" begin
        @testset "Symbol" begin
            labelvec = [:yes,:no,:no,:yes,:yes]
            @test labelvec == labelmap2vec(labelmap(labelvec))
            labelvec = Vector{Symbol}(undef, 0)
            @test labelvec == labelmap2vec(labelmap(labelvec))
        end

        @testset "Float64" begin
            labelvec = [1.,-1,-1,1,1]
            @test labelvec == labelmap2vec(labelmap(labelvec))
            labelvec = Vector{Float64}(undef, 0)
            @test labelvec == labelmap2vec(labelmap(labelvec))
        end
    end

    @testset "classify" begin
        @testset "single space" begin
            scores = [2.0, 0.0, 0.01, -0.1, -5.0]
            expected = [:outlier, :inlier, :outlier, :inlier, :inlier]
            actual = SVDD.classify.(scores)
            @test MLLabelUtils.islabelenc(actual, SVDD.class_label_enc)
            @test expected == actual
        end

        @testset "subspaces" begin
            scores = [[2.0, 0.0, 0.01, -0.1, -5.0],
                      [2.0, 0.0, 0.0, -0.1, 5.0]]
            expected_local = [[:outlier, :inlier, :outlier, :inlier, :inlier],
                              [:outlier, :inlier, :inlier, :inlier, :outlier]]
            expected_global = [:outlier, :inlier, :outlier, :inlier, :outlier]

            actual_local = SVDD.classify(scores, Val(:Subspace))
            actual_global = SVDD.classify(scores, Val(:Global))
            @test expected_local == actual_local
            @test expected_global == actual_global
        end
    end

    @testset "adjust kernel" begin
        K1 = [2 -1 0; -1 2 -1; 0 -1 2]
        K2 = [1 2; 2 1]
        @testset "single space" begin
            @assert all(eigen(K1).values .> 0)
            @test K1 ≈ SVDD.adjust_kernel_matrix(K1)

            @assert any(eigen(K2).values .< 0)
            K2_adjusted = SVDD.adjust_kernel_matrix(K2, warn_threshold = 2)
            @test !(K2 ≈ K2_adjusted)
            @test all(eigen(K2_adjusted).values .>= 0.0)

            Random.seed!(42)
            dummy_data, _ = generate_mvn_with_outliers(2, 100, 42, true, true)
            model = SVDD.VanillaSVDD(dummy_data)
            init_strategy = SVDD.FixedParameterInitialization(MLKernels.GaussianKernel(4), 0.1)
            SVDD.initialize!(model, init_strategy)
            K_old = copy(model.K)
            @assert any(eigen(model.K).values .< 0)

            @test_throws ArgumentError SVDD.adjust_kernel_matrix([3 -2; 4 -1])
        end

        @testset "subspaces" begin
            K = [K1, K2]
            @assert all(eigen(K[1]).values .> 0)
            @assert any(eigen(K[2]).values .< 0)
            K_adjusted = SVDD.adjust_kernel_matrix(K, warn_threshold = 2)
            @test K[1] ≈ K_adjusted[1]
            @test !(K[2] ≈ K_adjusted[2])
            @test all(eigen(K_adjusted[2]).values .>= 0.0)
        end
    end

    @testset "min_max_normalize" begin
        @test min_max_normalize([1,2]) ≈ [0.0, 1.0]
        @test min_max_normalize([-1,2]) ≈ [0.0, 1.0]
        @test isnan(min_max_normalize(1))
        @test isnan(min_max_normalize(-1))
        @test min_max_normalize([0, 20, -20, 0]) ≈ [0.5, 1.0, 0.0, 0.5]
    end
end


text:
### A Pluto.jl notebook ###
# v0.12.21

using Markdown
using InteractiveUtils

# ╔═╡ b5007056-88c2-11eb-3239-470733674ca3
using JLD2, FileIO

# ╔═╡ bea8d4fe-88c4-11eb-2a35-0f3276b7076d
begin
	import WGLMakie
	using JSServe, PlutoUI
end

# ╔═╡ 2bec13b6-88cb-11eb-1457-d95c48ff85a2
using Statistics

# ╔═╡ 8c7ee592-88d2-11eb-2789-512bf260207a
using StatsBase

# ╔═╡ ef87ed26-88db-11eb-3394-8fb21920d78d
using Plots

# ╔═╡ 8bcb8340-88c7-11eb-23ba-dd0227976b38
Page()

# ╔═╡ b1277040-88c4-11eb-2521-dfd292c1a1e0
function makie(f::Function)
    scene = WGLMakie.Scene(resolution = (600, 400))
	f(scene)

    return scene
end

# ╔═╡ b541d858-88c6-11eb-1e7d-13b6602f09ea
begin
	Core.eval(Main, :(include("../src/scrna.jl")))
	Core.eval(Main, :(include("../src/geo.jl")))
	Core.eval(Main, :(include("../src/infer.jl")))
end

# ╔═╡ dedf10d6-88c6-11eb-0ea2-514f6361094a
data = load("../3_4_5_6_7_my_normalization.jld2");

# ╔═╡ b701d1fa-88c3-11eb-1f24-bb1005bec7ab
begin
	seq = data["seq"]
	fit = data["fit"]
	embryo = data["embryo"]
	G = data["G"]
	D = data["D"]
	ξ = data["ξ"]
	ι = data["ι"]
	N = data["N"]
	F = data["F"]
	Ñ = data["Ñ"]
	r⃗ = data["r⃗"]
	ϕ = data["ϕ"]
	Ψ = data["Ψ"]
	Ψᵣ = data["Ψᵣ"]
	Ψₗ = data["Ψₗ"]
end;

# ╔═╡ ba24dc84-88cc-11eb-105d-97c13fdde18e
cor(Main.PointCloud.distance(ξ[:,1:3]')[:],  D[ι,ι][:])

# ╔═╡ 1250df04-88cb-11eb-1f48-959d13fc78d3
seq.gene[sortperm([corspearman(vec(N[i,ι]), ξ[:,1]) for i in 1:size(seq,1)])][1:50]

# ╔═╡ 40ec2332-88cb-11eb-2b86-6bcd9a437bad
seq.gene[sortperm([cor(vec(N[i,ι]), ξ[:,1]) for i in 1:size(seq,1)])][end-25:end]

# ╔═╡ 51172176-88cb-11eb-0899-1380eb084dac
seq.gene[sortperm([cor(vec(N[i,ι]), ξ[:,2]) for i in 1:size(seq,1)])][1:25]

# ╔═╡ 6218aee0-88cb-11eb-3d3a-497601ba793f
seq.gene[sortperm([cor(vec(N[i,ι]), ξ[:,2]) for i in 1:size(seq,1)])][end-25:end]

# ╔═╡ 71fb7928-88cb-11eb-1862-0be3d30b3e1a
seq.gene[sortperm([cor(vec(N[i,ι]), ξ[:,3]) for i in 1:size(seq,1)])][1:50]

# ╔═╡ 7aa9a540-88cb-11eb-0da4-e9aecdbf0967
seq.gene[sortperm([corspearman(vec(N[i,ι]), ξ[:,3]) for i in 1:size(seq,1)])][end-50:end]

# ╔═╡ 4797eeda-88c8-11eb-2402-23e143690c43
begin
	AP = r⃗[ι,1]
	DV = atan.(r⃗[ι,2],  r⃗[ι,3])
end;

# ╔═╡ 54205940-88c7-11eb-1b18-857742525b2f
makie() do s
	WGLMakie.scatter!(s, ξ[1:2:end,1], ξ[1:2:end,2], ξ[1:2:end,3], color=AP[1:2:end], markersize=2000)
end

# ╔═╡ 79f38d1c-88c8-11eb-20b3-877aba8b565b
makie() do s
	WGLMakie.scatter!(s, ξ[:,1], ξ[:,2], ξ[:,3], color=DV, markersize=2000)
end

# ╔═╡ b59d8c1c-88ca-11eb-0c32-edab0455d918
makie() do s
	WGLMakie.scatter!(s, ξ[:,1], ξ[:,2], ξ[:,3],
		color=vec(N["shg",ι]),
		markersize=2000
	)
end

# ╔═╡ 2769a0ee-88c9-11eb-1a77-63ab8dfa82e6
begin
   Ψ2  = ϕ(0.05)
   Ψₗ2 = Ψ2  ./ sum(Ψ,dims=2)
   Ψᵣ2 = (Ψ2 ./ sum(Ψ,dims=1))'

   G2  = Main.scRNA.Count(seq.data * Ψₗ2',seq.gene,fill("",3039))

   r⃗2 = Ψᵣ2 * embryo
end;

# ╔═╡ 06670396-88d1-11eb-3817-7db908739dd3
mt_index = occursin.("mt:", G2.gene)

# ╔═╡ 97d25ed0-88c8-11eb-1fea-fb8a3bcbb95e
makie() do s
	WGLMakie.scatter!(s, -embryo[:,1], embryo[:,2], embryo[:,3],
		color=G2["sna",:], #vec(sum(G2[mt_index,:],dims=1)),
		markersize=2000)
end

# ╔═╡ e69357f6-88e4-11eb-39f7-d514156f22a5
makie() do s
	WGLMakie.scatter!(s, -embryo[:,1], embryo[:,2], embryo[:,3],
		color=G2["myo",:], #vec(sum(G2[mt_index,:],dims=1)),
		markersize=2000)
end

# ╔═╡ fd3e3ace-88db-11eb-1376-f5a1e24b25f3
scatter(embryo[:,1], vec(G2["run",:])); scatter!(embryo[:,1], vec(G2["eve",:]).+.10); scatter!(embryo[:,1], vec(G2["ftz",:]).-.1);xaxis!((-100, 100))

# ╔═╡ Cell order:
# ╠═b5007056-88c2-11eb-3239-470733674ca3
# ╠═bea8d4fe-88c4-11eb-2a35-0f3276b7076d
# ╠═2bec13b6-88cb-11eb-1457-d95c48ff85a2
# ╠═8c7ee592-88d2-11eb-2789-512bf260207a
# ╠═8bcb8340-88c7-11eb-23ba-dd0227976b38
# ╠═b1277040-88c4-11eb-2521-dfd292c1a1e0
# ╠═b541d858-88c6-11eb-1e7d-13b6602f09ea
# ╠═dedf10d6-88c6-11eb-0ea2-514f6361094a
# ╟─b701d1fa-88c3-11eb-1f24-bb1005bec7ab
# ╠═ba24dc84-88cc-11eb-105d-97c13fdde18e
# ╠═1250df04-88cb-11eb-1f48-959d13fc78d3
# ╟─40ec2332-88cb-11eb-2b86-6bcd9a437bad
# ╟─51172176-88cb-11eb-0899-1380eb084dac
# ╟─6218aee0-88cb-11eb-3d3a-497601ba793f
# ╠═71fb7928-88cb-11eb-1862-0be3d30b3e1a
# ╠═7aa9a540-88cb-11eb-0da4-e9aecdbf0967
# ╠═4797eeda-88c8-11eb-2402-23e143690c43
# ╠═54205940-88c7-11eb-1b18-857742525b2f
# ╠═79f38d1c-88c8-11eb-20b3-877aba8b565b
# ╠═b59d8c1c-88ca-11eb-0c32-edab0455d918
# ╠═06670396-88d1-11eb-3817-7db908739dd3
# ╠═97d25ed0-88c8-11eb-1fea-fb8a3bcbb95e
# ╠═e69357f6-88e4-11eb-39f7-d514156f22a5
# ╠═ef87ed26-88db-11eb-3394-8fb21920d78d
# ╠═fd3e3ace-88db-11eb-1376-f5a1e24b25f3
# ╟─2769a0ee-88c9-11eb-1a77-63ab8dfa82e6

max_stars_repo_name: nnoll/seqspace

max_issues_repo_name: nnoll/seqspace

max_forks_repo_name: nnoll/seqspace


text:
using Documenter, ModelerToolbox

makedocs(
    doctest=false
)

run(`mkdocs build -c`)

if "publish" in ARGS
    run(`mkdocs gh-deploy -c -b gh-pages -r origin -v`)
end


text:
@testset "Check For Focus Function Tests" begin

  @test isdefined(Julz, :check_for_focus) == true

end


text: # ## Tests


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

@doc raw"""EndpointConditions represents the current condition of an endpoint.

    IoK8sApiDiscoveryV1beta1EndpointConditions(;
        ready=nothing,
    )

    - ready::Bool : ready indicates that this endpoint is prepared to receive traffic, according to whatever system is managing the endpoint. A nil value indicates an unknown state. In most cases consumers should interpret this unknown state as ready.
"""
mutable struct IoK8sApiDiscoveryV1beta1EndpointConditions <: SwaggerModel
    ready::Any # spec type: Union{ Nothing, Bool } # spec name: ready

    function IoK8sApiDiscoveryV1beta1EndpointConditions(;ready=nothing)
        o = new()
        validate_property(IoK8sApiDiscoveryV1beta1EndpointConditions, Symbol("ready"), ready)
        setfield!(o, Symbol("ready"), ready)
        o
    end
end # type IoK8sApiDiscoveryV1beta1EndpointConditions

const _property_map_IoK8sApiDiscoveryV1beta1EndpointConditions = Dict{Symbol,Symbol}(Symbol("ready")=>Symbol("ready"))
const _property_types_IoK8sApiDiscoveryV1beta1EndpointConditions = Dict{Symbol,String}(Symbol("ready")=>"Bool")
Base.propertynames(::Type{ IoK8sApiDiscoveryV1beta1EndpointConditions }) = collect(keys(_property_map_IoK8sApiDiscoveryV1beta1EndpointConditions))
Swagger.property_type(::Type{ IoK8sApiDiscoveryV1beta1EndpointConditions }, name::Symbol) = Union{Nothing,eval(Base.Meta.parse(_property_types_IoK8sApiDiscoveryV1beta1EndpointConditions[name]))}
Swagger.field_name(::Type{ IoK8sApiDiscoveryV1beta1EndpointConditions }, property_name::Symbol) =  _property_map_IoK8sApiDiscoveryV1beta1EndpointConditions[property_name]

function check_required(o::IoK8sApiDiscoveryV1beta1EndpointConditions)
    true
end

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


text:
"""
	optimize_newton!(x, f, g, h)

Newton minimization of `f`, with first and second derivatives
`g` and  `h`. Starts the iteration from `x0`.
"""
function optimize_newton(x, f, g, h;
						 grtol=1e-4,
						 gatol=1e-4,
						 prints=false)
	while true
		fx = f(x)
		gx = g(x)
		hx = h(x)

		# check convergence
		abs(gx / fx) ≤ grtol && break
		abs(gx) ≤ gatol && break

		if prints
			println("|G|=$(abs(gx))")
		end

		# move point to next position
		x -= gx / hx
	end

	return x
end


text:
include("MenuItems.jl")
using .MenuItems
import .MenuItems: MenuItem
export MenuItems, MenuItem

include("ToggleMenuItems.jl")
using .ToggleMenuItems
import .ToggleMenuItems: ToggleMenuItem
export ToggleMenuItems, ToggleMenuItem

include("Menus.jl")
using .Menus
import .Menus: Menu
export Menus, Menu

include("MenuBars.jl")
using .MenuBars
import .MenuBars: MenuBar
export MenuBars, MenuBar

include("MainMenuBars.jl")
using .MainMenuBars
import .MainMenuBars: MainMenuBar
export MainMenuBars, MainMenuBar


text:
module ParameterTests

include("testsets.jl")
include("macro.jl")
include("strategies.jl")

# Now include the various strategies we have
include("strategies/numbers.jl")
include("strategies/dates.jl")
include("strategies/arrays.jl")
include("strategies/strings.jl")

export @paramtest, SingleParameterTestSet, ParameterTestSet, SearchStrategy, draw
export integers, dates, vectors, floats, strings, symbols

end # module


text:
@testset "LayeredArray" begin
    c = LayeredArray([2,6,4])
    @test layerof(c) == 1
    # getindex
    for i in eachindex(c)
        @test (@inferred c[i])::Int == [2,6,4][i]
    end
    @test (@inferred c[[1,3]])::LayeredVector{1, Int, <: SubArray} == [2,4]
    @test (@inferred c[1:2])::LayeredVector{1, Int, <: SubArray} == [2,6]
    @test (@inferred view(c, [1,3]))::SubArray == [2,4]
    @test (@inferred view(c, 1:2))::SubArray == [2,6]
    # setindex!
    for i in eachindex(c)
        c[i] = 2i
        @test (@inferred c[i])::Int == 2i
    end
end