text:
# DirichletSpaces

export ChebyshevDirichlet

#TODO: Type of Segment
struct ChebyshevDirichlet{left,right,D,R} <: PolynomialSpace{D,R}
    domain::D
    ChebyshevDirichlet{left,right,D,R}(d) where {left,right,D,R} = new(d)
    ChebyshevDirichlet{left,right,D,R}() where {left,right,D,R} = new(convert(D, ChebyshevInterval()))
end

for TYP in (:Number,:AbstractArray,:Vec,:Fun)
    @eval evaluate(f::AbstractVector,S::ChebyshevDirichlet,x::$TYP) =
        evaluate(Fun(Fun(S,f),canonicalspace(S)),x)
end
ChebyshevDirichlet{l,r}() where {l,r} =
    ChebyshevDirichlet{l,r,ChebyshevInterval{Float64},Float64}()
ChebyshevDirichlet{l,r}(d::Domain) where {l,r} =
    ChebyshevDirichlet{l,r,typeof(d),real(prectype(d))}(d)

spacescompatible(a::ChebyshevDirichlet{l,r,D,R},b::ChebyshevDirichlet{l,r,D,R}) where {l,r,D,R} =
    domainscompatible(a,b)

ChebyshevDirichlet() = ChebyshevDirichlet{1,1,ChebyshevInterval{Float64},Float64}()
ZeroChebyshevDirichlet(d) =
    ChebyshevDirichlet{1,1,ChebyshevInterval{Float64}}(d)|(3:∞)
ZeroChebyshevDirichlet() =
    ChebyshevDirichlet{1,1,ChebyshevInterval{Float64}}()|(3:∞)

canonicalspace(S::ChebyshevDirichlet) = Chebyshev(domain(S))

setdomain(S::ChebyshevDirichlet{l,r},d::Domain) where {l,r} = ChebyshevDirichlet{l,r}(d)

# These are used to make sure ChebyshevDirichlet comes first

Base.isless(a::Chebyshev,b::ChebyshevDirichlet) = false
<(a::Chebyshev,b::ChebyshevDirichlet) = false
<=(a::Chebyshev,b::ChebyshevDirichlet) = false
>(a::Chebyshev,b::ChebyshevDirichlet) = true
>=(a::Chebyshev,b::ChebyshevDirichlet) = true

Base.isless(a::ChebyshevDirichlet,b::Chebyshev) = true
<(a::ChebyshevDirichlet,b::Chebyshev) = true
<=(a::ChebyshevDirichlet,b::Chebyshev) = true
>(a::ChebyshevDirichlet,b::Chebyshev) = false
>=(a::ChebyshevDirichlet,b::Chebyshev) = false

## coefficients

# converts to f_0 T_0 + f_1 T_1 +  \sum f_k (T_k - T_{k-2})

function dirichlettransform!(w::AbstractVector)
    for k=length(w)-2:-1:1
        @inbounds w[k] += w[k+2]
    end

    w
end

function idirichlettransform!(w::AbstractVector)
    for k=3:length(w)
        @inbounds w[k-2]-= w[k]
    end

    w
end

# converts to f_0 T_0 + \sum f_k (T_k ± T_{k-1})

function idirichlettransform!(s::Bool,w::AbstractVector)
    for k=2:length(w)
        @inbounds w[k-1]+= (s ? -1 : 1)*w[k]
    end

    w
end

function dirichlettransform!(s::Bool,w::AbstractVector)
    for k=length(w)-1:-1:1
        @inbounds w[k] += (s ? 1 : -1)*w[k+1]
    end

    w
end

coefficients(v::AbstractVector,::Chebyshev,::ChebyshevDirichlet{1,1})=dirichlettransform!(copy(v))
coefficients(v::AbstractVector,::Chebyshev,::ChebyshevDirichlet{0,1})=dirichlettransform!(true,copy(v))
coefficients(v::AbstractVector,::Chebyshev,::ChebyshevDirichlet{1,0})=dirichlettransform!(false,copy(v))

coefficients(v::AbstractVector,::ChebyshevDirichlet{1,1},::Chebyshev)=idirichlettransform!(copy(v))
coefficients(v::AbstractVector,::ChebyshevDirichlet{0,1},::Chebyshev)=idirichlettransform!(true,copy(v))
coefficients(v::AbstractVector,::ChebyshevDirichlet{1,0},::Chebyshev)=idirichlettransform!(false,copy(v))

# recurrence
recα(::Type{T},::ChebyshevDirichlet{1,1},n) where {T} = zero(T)
recβ(::Type{T},::ChebyshevDirichlet{1,1},n) where {T} = n==1 ? one(T) : one(T)/2
recγ(::Type{T},::ChebyshevDirichlet{1,1},n) where {T} = n==2 ? one(T) : (n==3 ? zero(T) : one(T)/2)

## Dirichlet Conversion operators

Conversion(D::ChebyshevDirichlet,C::Chebyshev)=ConcreteConversion(D,C)

getindex(C::ConcreteConversion{ChebyshevDirichlet{1,0,D,R},CC,T},k::Integer,j::Integer) where {D,R,CC<:Chebyshev,T} =
    j==k || j==k+1 ? one(T) : zero(T)

getindex(C::ConcreteConversion{ChebyshevDirichlet{0,1,D,R},CC,T},k::Integer,j::Integer) where {D,R,CC<:Chebyshev,T} =
    j==k ? one(T) : ( j==k+1 ? -one(T) : zero(eltype(C)))

getindex(C::ConcreteConversion{ChebyshevDirichlet{1,1,D,R},CC,T},k::Integer,j::Integer) where {D,R,CC<:Chebyshev,T} =
    j==k ? one(T) : ( j==k+2 ? -one(T) : zero(eltype(C)))

function getindex(C::ConcreteConversion{ChebyshevDirichlet{2,2,D,R},CC,T},k::Integer,j::Integer) where {D,R,CC<:Chebyshev,T}
    if j==k
        one(T)
    elseif j==k+4
        2one(T)*(k+1)/k-1
    elseif k≥3 && j==k+2
        -2one(T)*(k-1)/(k-2)
    else
        zero(T)
    end
end

bandwidths(::ConcreteConversion{ChebyshevDirichlet{1,0,D,R},C}) where {D,R,C<:Chebyshev}=0,1
bandwidths(::ConcreteConversion{ChebyshevDirichlet{0,1,D,R},C}) where {D,R,C<:Chebyshev}=0,1
bandwidths(::ConcreteConversion{ChebyshevDirichlet{1,1,D,R},C}) where {D,R,C<:Chebyshev}=0,2
bandwidths(::ConcreteConversion{ChebyshevDirichlet{2,2,D,R},C}) where {D,R,C<:Chebyshev}=0,4

conversion_rule(b::ChebyshevDirichlet,a::Chebyshev)=b

# return the space that has banded Conversion to the other
# function conversion_rule(a::ChebyshevDirichlet,b::Ultraspherical)
#     @assert domainscompatible(a,b)
#
#     a
# end

## Evaluation Functional

bandwidths(B::ConcreteEvaluation{ChebyshevDirichlet{1,0,D,R},typeof(leftendpoint)}) where {D,R} = 0,0
bandwidths(B::ConcreteEvaluation{ChebyshevDirichlet{1,0,D,R},typeof(rightendpoint)}) where {D,R} = 0,∞
bandwidths(B::ConcreteEvaluation{ChebyshevDirichlet{0,1,D,R},typeof(leftendpoint)}) where {D,R} = 0,∞
bandwidths(B::ConcreteEvaluation{ChebyshevDirichlet{0,1,D,R},typeof(rightendpoint)}) where {D,R} = 0,0
bandwidths(B::ConcreteEvaluation{ChebyshevDirichlet{1,1,D,R},typeof(leftendpoint)}) where {D,R} = 0,1
bandwidths(B::ConcreteEvaluation{ChebyshevDirichlet{1,1,D,R},typeof(rightendpoint)}) where {D,R} = 0,1

function getindex(B::ConcreteEvaluation{ChebyshevDirichlet{1,0,D,R},typeof(leftendpoint)},kr::AbstractRange) where {D,R}
    d = domain(B)

    if B.order == 0
        Float64[k==1 ? 1.0 : 0.0 for k=kr]
    else
        (Evaluation(d,B.x,B.order)*Conversion(domainspace(B)))[kr]
    end
end

function getindex(B::ConcreteEvaluation{ChebyshevDirichlet{1,0,D,R},typeof(rightendpoint)},kr::AbstractRange) where {D,R}
    d = domain(B)

    if B.order == 0
        Float64[k==1 ? 1.0 : 2.0 for k=kr]
    else
        (Evaluation(d,B.x,B.order)*Conversion(domainspace(B)))[kr]
    end
end

function getindex(B::ConcreteEvaluation{ChebyshevDirichlet{0,1,D,R},typeof(leftendpoint)},kr::AbstractRange) where {D,R}
    S = Space(domain(B))

    if B.order == 0
        Float64[k==1 ? 1.0 : -(-1)^k*2.0 for k=kr]
    else
        (Evaluation(S,B.x,B.order)*Conversion(domainspace(B),S))[kr]
    end
end

function getindex(B::ConcreteEvaluation{ChebyshevDirichlet{0,1,D,R},typeof(rightendpoint)},kr::AbstractRange) where {D,R}
    S = Space(domain(B))

    if B.order == 0
        Float64[k==1 ? 1.0 : 0.0 for k=kr]
    else
        (Evaluation(S,B.x,B.order)*Conversion(domainspace(B),S))[kr]
    end
end

function getindex(B::ConcreteEvaluation{ChebyshevDirichlet{1,1,D,R},typeof(leftendpoint)},kr::AbstractRange) where {D,R}
    S = Space(domain(B))

    if B.order == 0
        Float64[k==1 ? 1.0 : (k==2 ? -1.0 : 0.0) for k=kr]
    else
        getindex(Evaluation(S,B.x,B.order)*Conversion(domainspace(B),S),kr)
    end
end

function getindex(B::ConcreteEvaluation{ChebyshevDirichlet{1,1,D,R},typeof(rightendpoint)},kr::AbstractRange) where {D,R}
    S = Space(domain(B))

    if B.order == 0
        Float64[k==1||k==2 ? 1.0 : 0.0 for k=kr]
    else
        getindex(Evaluation(S,B.x,B.order)*Conversion(domainspace(B),S),kr)
    end
end

function Evaluation(sp::ChebyshevDirichlet,x::Float64,ord::Integer)
    S=Space(domain(sp))
    EvaluationWrapper(sp,x,ord,Evaluation(S,x,ord)*Conversion(sp,S))
end


text:
# ----------------------------------------------------------------------------------- #
# Copyright (c) 2018 Varnerlab
# Robert Frederick Smith School of Chemical and Biomolecular Engineering
# Cornell University, Ithaca NY 14850
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
# ----------------------------------------------------------------------------------- #

# ----------------------------------------------------------------------------------- #
# Function: generate_problem_dictionary
# Description: Holds simulation and model parameters as key => value pairs in a Julia Dict()
# Generated on: 2018-03-15T00:00:56.939
#
# Output arguments:
# data_dictionary::Dict{AbstractString,Any} => Dictionary holding model and simulation parameters as key => value pairs
# ----------------------------------------------------------------------------------- #
function generate_problem_dictionary()

	# Load the stoichiometric network from disk -
	path_to_network_file = joinpath(_PATH_TO_CONFIG,"Network.dat")
	stoichiometric_matrix = readdlm(path_to_network_file, ',', Float64);

	# What is the system dimension? -
	(number_of_species,number_of_reactions) = size(stoichiometric_matrix)

	# Setup the flux bounds array -
	flux_bounds_array = zeros(number_of_reactions,2)
	# Update the flux_bounds_array for each reaction in your network
	flux_bounds_array[1,:] = [0, 3.1716]		# [mmol/gDW*hr] Bounds for v1 flux  E.C. 2.1.3.3
	flux_bounds_array[2,:] = [0, 7.308]			# [mmol/gDW*hr] Bounds for v2 flux  E.C. 6.3.4.5
	flux_bounds_array[3,:] = [0, 1.242]			# [mmol/gDW*hr] Bounds for v3 flux  E.C. 4.3.2.1
	flux_bounds_array[4,:] = [0, 8.964]			# [mmol/gDW*hr] Bounds for v4 flux  E.C. 3.5.3.1
	flux_bounds_array[5,:] = [-0.4932, 0.4932]	# [mmol/gDW*hr] Bounds for v5 flux  E.C. 1.14.13.39
	flux_bounds_array[6:19, 1] .= -10    			# [mmol/gDW*hr]  lower bound on exchange fluxes
	flux_bounds_array[6:19, 2] .= 10   			# [mmol/gDW*hr]  upper bound on exchange fluxes

	# Setup default species bounds array -
	species_bounds_array = zeros(number_of_species,2)
	# NOTE - we by default assume Sv = 0, so species_bounds_array should be a M x 2 array of zeros
	#        however, if you formulate the problem differently you *may* need to change this
	#        If S array includes external species, steady state Sv=0 no longer makes sense

	# Min/Max flag - default is minimum -
	is_minimum_flag = true

	# Setup the objective coefficient array -
	objective_coefficient_array = zeros(number_of_reactions)
	# Update me to maximize Urea production (Urea leaving the virtual box)
	# If is_minimum_flag = true => put a -1 in the index for Urea export
	objective_coefficient_array[17] = -1  # Urea Export:  b12 at rxn index 17 (see Network_Details.dat)

	# =============================== DO NOT EDIT BELOW THIS LINE ============================== #
	data_dictionary = Dict{String,Any}()
	data_dictionary["stoichiometric_matrix"] = stoichiometric_matrix
	data_dictionary["objective_coefficient_array"] = objective_coefficient_array
	data_dictionary["flux_bounds_array"] = flux_bounds_array;
	data_dictionary["species_bounds_array"] = species_bounds_array
	data_dictionary["is_minimum_flag"] = is_minimum_flag
	data_dictionary["number_of_species"] = number_of_species
	data_dictionary["number_of_reactions"] = number_of_reactions
	# =============================== DO NOT EDIT ABOVE THIS LINE ============================== #
	return data_dictionary
end

ext: jl


text:
using JuMP, Gurobi, Cbc
import XLSX

xf = XLSX.readxlsx("../data/data1_part2.xlsx")
l = xf["General!B1"] ## end time
N = xf["General!B3"] + 1  # number of locations
M = xf["General!B2"] ## number of providers
K = xf["General!B4"] ## number of service  types

# Clients
s = xf["Clients!A2:A$N"]
d = xf["Duration"][:]

## Providers
w = xf["Providers!B2:B$(M+1)"]
g = xf["Providers!A2:A$(K+1)"]
# clients who need certain type of service
A = xf["clients with service type"][:]

# providers who provide certain type of service
H = xf["provider with service type"][:]

s_test = ones(M, N)
for k in 1:M
    global s_test[k,:] = vcat([w[k]], s)
end
s = s_test

t = xf["Distances"][:]

model=Model(with_optimizer(Gurobi.Optimizer))
@variable(model, x[1:N, 1:N, 1:M, 1:K], Bin)
@variable(model, 1 <= u[1:N, 1:M] <= N-1)
@objective(model, Min, sum(g[k]*sum(x[1,j,v,k]*(sum(x[p,q,v,k]*(t[p,q] + d[p,k] + max(0, s[v,q] - s[v,p] - t[p,q] - d[p,k]) ) for p in skipmissing(A[k,:]) for q in skipmissing(A[k,:]))) for j in skipmissing(A[k,:]) for v in skipmissing(H[k,:])) for k in 1:K))

for k in 1:K
    for j in skipmissing(A[k,2:length(A[k,:])])
        @constraint(model, sum(x[i,j,v,k] for i in skipmissing(A[k,:]) for v in skipmissing(H[k,:])) == 1)
    end
end

for k in 1:K
    for p in skipmissing(A[k,2:length(A[k,:])])
        for v in skipmissing(H[k,:])
            @constraint(model, sum(x[i,p,v,k] for i in skipmissing(A[k,:])) == sum(x[p,j,v,k] for j in skipmissing(A[k,:])))
        end
    end
end

for k in 1:K
    for v in skipmissing(H[k,:])
        @constraint(model, sum(x[1,j,v,k] for j in skipmissing(A[k,2:length(A[k,:])])) <= 1)
    end
end

for k in 1:K
    @constraint(model, sum(x[1,j,v,k] for j in skipmissing(A[k,2:length(A[k,:])]) for v in skipmissing(H[k,:])) >= 1)
end

for k in 1:K
    for v in skipmissing(H[k,:])
        for i in skipmissing(A[k,2:length(A[k,:])])
            for j in skipmissing(A[k,2:length(A[k,:])])
                @constraint(model, u[i,v] - u[j,v] + (length(A[k,:])-1) * x[i,j,v,k] <= (length(A[k,:])-1) - 1 )
            end
        end
    end
end

for k in 1:K
    for j in skipmissing(A[k,2:length(A[k,:])])
        for v in skipmissing(H[k,:])
            @constraint(model, x[1,j,v,k]*(s[v,1] + t[1,j] + d[1,k]) <= s[v,j])
        end
    end
end

for k in 1:K
    for i in skipmissing(A[k,2:length(A[k,:])])
        for j in skipmissing(A[k,2:length(A[k,:])])
            for v in skipmissing(H[k,:])
                @constraint(model, x[i,j,v,k]*(s[v,i] + t[i,j] + d[i,k]) <= s[v,j])
            end
        end
    end
end

for k in 1:K
    for i in skipmissing(A[k,2:length(A[k,:])])
        for v in skipmissing(H[k,:])
            @constraint(model, x[i,1,v,k]*(s[v,i] + t[i,1] + d[i,k]) <= l)
        end
    end
end

optimize!(model)

for k in 1:K
    for v in 1:M
        if sum(value.(x[1,:,v,k])) == 1
            println("Provider $v provides service.")
            println("Provider $v costs $(g[k]) per hour.")
            # come back hr
            for i in 2:N
                if value.(x[i,1,v,k]) == 1
                    println("Provider $v comes back to 14HS at $(t[i,1] + s[v,i] + d[i,k])hr. \n")
                end
            end
        end
    end
end

function get_path(N, v, k)
    path = []
    for j in 2:N
        if value.(x[1,j,v,k]) == 1
            println("\nstart of path")
            println(1, " => ")
            path = vcat(path, [1])
            println(j, " => ")
            path = vcat(path, [j])
            i = j
            while value.(x[i,1,v,k]) == 0
                for m in 2:N
                    if value.(x[i,m,v,k]) == 1
                        println(m, " => ")
                        path = vcat(path, [m])
                        i = m
                        break
                    end
                end
            end
            println(1)
            path = vcat(path, [1])
            println("end of path.... or in client index below (not location)")
        end
    end
    for j in 2:N
        if value.(x[1,j,v,k]) == 1
            println("\nstart of path")
            println(0, " => ")
            println(j-1, " => ")
            i = j
            while value.(x[i,1,v,k]) == 0
                for m in 2:N
                    if value.(x[i,m,v,k]) == 1
                        println(m-1, " => ")
                        i = m
                        break
                    end
                end
            end
            println(0)
            println("end of path (in client index)")
        end
    end
    return path
end

function overview(path)
    println("$(s[v,1])hr: It is available at HS14 and leaves to client $(path[2]).")
    for i in 2:length(path)-1
        println("$(s[v,path[i-1]]+t[path[i-1], path[i]] + d[path[i-1],k])hr: It arrives at client $(path[i]).")
        if s[v,path[i-1]]+t[path[i-1], path[i]] + d[path[i-1],k] != s[v,path[i]]
            println(" It arrives early and waits until service start time.")
        end
        println("$(s[v,path[i]])hr: It serves for $(d[path[i],k]) hrs.")
        if path[i+1] == 1
            println("$(s[v,path[i]]+d[path[i],k])hr: It finishes the service at client $(path[i]) and leaves to HS14.")
        else
            println("$(s[v,path[i]]+d[path[i],k])hr: It finishes the service at client $(path[i]) and leaves to client $(path[i+1]).")
        end
    end
    println("$(s[v,path[length(path)-1]] + d[path[length(path)-1],k] + t[path[length(path)-1], 1])hr: It arrives back at HS14.\n")
end
v = 5
k = 3

path = get_path(N, v, k)

# print the overview of the path for provider k, where 'path' is found above using get_path(N,k)
overview(path)


text:
import Flux
using Statistics
using Gomah: chainercv

activations = Dict("relu" => Flux.relu)

struct Conv2DBNActiv
    conv
    bn
    function Conv2DBNActiv(link::PyObject)
        conv = ch2conv(link.conv)
        if link.activ == nothing
            activ = Flux.identity
        else
            activ = activations[link.activ.__name__]
            #activ = Flux.relu
        end
        bn = ch2bn(link.bn, activ)
        new(conv, bn)
    end
end

Flux.@treelike Conv2DBNActiv
function Flux.testmode!(c::Conv2DBNActiv)
    Flux.testmode!(c.bn)
end

(layer::Conv2DBNActiv)(x) = layer.bn(layer.conv(x))

struct BottleNeckA
    layers
    residual_conv
    function BottleNeckA(link::PyObject)
        layers = Conv2DBNActiv.([link.conv1, link.conv2, link.conv3])
        residual_conv = Conv2DBNActiv(link.residual_conv)
        new(Chain(layers...), Chain(residual_conv))
    end
end

Flux.@treelike BottleNeckA

function (bottleneck::BottleNeckA)(x)
    h1 = bottleneck.layers(x)
    h2 = bottleneck.residual_conv(x)
    y = Flux.relu.(h1 .+ h2)
    return y
end

function Flux.testmode!(bottleneck::BottleNeckA)
    Flux.testmode!.(bottleneck.layers)
    Flux.testmode!.(bottleneck.residual_conv)
end

struct BottleNeckB
    chain
    function BottleNeckB(link::PyObject)
        layers = [link.conv1, link.conv2, link.conv3]
        new(Chain(Conv2DBNActiv.(layers)...))
    end
end

Flux.@treelike BottleNeckB

function (bottleneckB::BottleNeckB)(x)
    h = bottleneckB.chain(x)
    Flux.relu.(h .+ x)
end

Flux.testmode!(bottleneck::BottleNeckB) = Flux.testmode!(bottleneck.chain)

function ResBlock(link)
    layers = Any[]
    push!(layers, BottleNeckA(link.a))
    for name in link.layer_names[2:end]
        chlay = py"getattr"(link, name)
        push!(layers, BottleNeckB(chlay))
    end
    Chain(layers...)
end

struct ResNet
    layers
    layer_names
    function ResNet(num::Int)
        PyResNet = chainercv.links.model.resnet.ResNet
        pyresnet = PyResNet(num, pretrained_model = "imagenet")
        #dummyX = np.ones((1, 3, 224, 224), dtype = np.float32)
        #resnet(dummyX)
        #resnet101=ResNet(101, pretrained_model="imagenet")
        #resnet152=ResNet(152, pretrained_model="imagenet")
        @show pyresnet.layer_names
        layers = [
            Conv2DBNActiv(pyresnet.conv1),
            MaxPool((3, 3), pad = (0, 1, 0, 1), stride = (2, 2)),
            ResBlock(pyresnet.res2),
            ResBlock(pyresnet.res3),
            ResBlock(pyresnet.res4),
            ResBlock(pyresnet.res5),
            x -> reshape(mean(x, dims = (1, 2)), :, size(x, 4)),
            ch2dense(pyresnet.fc6),
            Flux.softmax,
        ]
        new(layers, pyresnet.layer_names)
    end
end

function (res::ResNet)(x)
    h = x
    d = Dict()
    for (name, lay) in zip(res.layer_names, res.layers)
        h = lay(h)
        d[name] = h
    end
    return h, d
end

Flux.testmode!(resnet::ResNet) = Flux.testmode!(resnet.layers)


text:
#
# Abstract Interface.
#

"""
Abbreviation objects are used to automatically generate context-dependent markdown content
within documentation strings. Objects of this type interpolated into docstrings will be
expanded automatically before parsing the text to markdown.

$(:FIELDS)
"""
abstract type Abbreviation end

"""
$(:SIGNATURES)

Expand the [`Abbreviation`](@ref) `abbr` in the context of the `DocStr` `doc` and write
the resulting markdown-formatted text to the `IOBuffer` `buf`.
"""
format(abbr, buf, doc) = error("`format` not implemented for `$typeof(abbr)`.")

# Only extend `formatdoc` once with our abstract type. Within the package use a different
# `format` function instead to keep things decoupled from `Base` as much as possible.
Docs.formatdoc(buf::IOBuffer, doc::Docs.DocStr, part::Abbreviation) = format(part, buf, doc)

#
# Implementations.
#

#
# `TypeFields`
#

"""
The type for [`FIELDS`](@ref) abbreviations.

$(:FIELDS)
"""
struct TypeFields <: Abbreviation
    types::Bool
end

"""
An [`Abbreviation`](@ref) to include the names of the fields of a type as well as any
documentation that may be attached to the fields.

# Examples

The generated markdown text should look similar to to following example where a
type has three fields (`x`, `y`, and `z`) and the last two have documentation
attached.

```markdown

  - `x`

  - `y`

    Unlike the `x` field this field has been documented.

  - `z`

    Another documented field.
```
"""
const FIELDS = TypeFields(false)

"""
Identical to [`FIELDS`](@ref) except that it includes the field types.

# Examples

The generated markdown text should look similar to to following example where
a type has three fields; `x` of type `String`, `y` of type `Int`, and `z` of
type `Vector{Any}`.

```markdown

  - `x::String`

  - `y::Int`

    Unlike the `x` field this field has been documented.

  - `z::Array{Any, 1}`

    Another documented field.
```
"""
const TYPEDFIELDS = TypeFields(true)

function format(abbrv::TypeFields, buf, doc)
    local docs = get(doc.data, :fields, Dict())
    local binding = doc.data[:binding]
    local object = Docs.resolve(binding)
    # On 0.7 fieldnames() on an abstract type throws an error. We then explicitly return
    # an empty vector to be consistent with the behaviour on v0.6.
    local fields = isabstracttype(object) ? Symbol[] : fieldnames(object)
    if !isempty(fields)
        println(buf)
        for field in fields
            if abbrv.types
                println(buf, "  - `", field, "::", fieldtype(object, field), "`")
            else
                println(buf, "  - `", field, "`")
            end
            # Print the field docs if they exist and aren't a `doc"..."` docstring.
            if haskey(docs, field) && isa(docs[field], AbstractString)
                println(buf)
                for line in split(docs[field], "\n")
                    println(buf, isempty(line) ? "" : "    ", rstrip(line))
                end
            end
            println(buf)
        end
        println(buf)
    end
    return nothing
end

#
# `ModuleExports`
#

"""
The singleton type for [`EXPORTS`](@ref) abbreviations.

$(:FIELDS)
"""
struct ModuleExports <: Abbreviation end

"""
An [`Abbreviation`](@ref) to include all the exported names of a module is a sorted list of
`Documenter.jl`-style `@ref` links.

!!! note

    The names are sorted alphabetically and ignore leading `@` characters so that macros are
    *not* sorted before other names.

# Examples

The markdown text generated by the `EXPORTS` abbreviation looks similar to the following:

```markdown

  - [`bar`](@ref)
  - [`@baz`](@ref)
  - [`foo`](@ref)

```
"""
const EXPORTS = ModuleExports()

function format(::ModuleExports, buf, doc)
    local binding = doc.data[:binding]
    local object = Docs.resolve(binding)
    local exports = names(object)
    if !isempty(exports)
        println(buf)
        # Sorting ignores the `@` in macro names and sorts them in with others.
        for sym in sort(exports, by = s -> lstrip(string(s), '@'))
            # Skip the module itself, since that's always exported.
            sym === nameof(object) && continue
            # We print linked names using Documenter.jl cross-reference syntax
            # for ease of integration with that package.
            println(buf, "  - [`", sym, "`](@ref)")
        end
        println(buf)
    end
    return nothing
end

#
# `ModuleImports`
#

"""
The singleton type for [`IMPORTS`](@ref) abbreviations.

$(:FIELDS)
"""
struct ModuleImports <: Abbreviation end

"""
An [`Abbreviation`](@ref) to include all the imported modules in a sorted list.

# Examples

The markdown text generated by the `IMPORTS` abbreviation looks similar to the following:

```markdown

  - `Foo`
  - `Bar`
  - `Baz`

```
"""
const IMPORTS = ModuleImports()

function format(::ModuleImports, buf, doc)
    local binding = doc.data[:binding]
    local object = Docs.resolve(binding)
    local imports = unique(ccall(:jl_module_usings, Any, (Any,), object))
    if !isempty(imports)
        println(buf)
        for mod in sort(imports, by = string)
            println(buf, "  - `", mod, "`")
        end
        println(buf)
    end
end

#
# `MethodList`
#

"""
The singleton type for [`METHODLIST`](@ref) abbreviations.

$(:FIELDS)
"""
struct MethodList <: Abbreviation end

"""
An [`Abbreviation`](@ref) for including a list of all the methods that match a documented
`Method`, `Function`, or `DataType` within the current module.

# Examples

The generated markdown text will look similar to the following example where a function
`f` defines two different methods (one that takes a number, and the other a string):

````markdown
```julia
f(num)
```

defined at [`<path>:<line>`](<github-url>).

```julia
f(str)
```

defined at [`<path>:<line>`](<github-url>).
````
"""
const METHODLIST = MethodList()

function format(::MethodList, buf, doc)
    local binding = doc.data[:binding]
    local typesig = doc.data[:typesig]
    local modname = doc.data[:module]
    local func = Docs.resolve(binding)
    local groups = methodgroups(func, typesig, modname; exact = false)
    if !isempty(groups)
        println(buf)
        for group in groups
            println(buf, "```julia")
            for method in group
                printmethod(buf, binding, func, method)
                println(buf)
            end
            println(buf, "```\n")
            if !isempty(group)
                local method = group[1]
                local file = string(method.file)
                local line = method.line
                local path = cleanpath(file)
                local URL = url(method)
                isempty(URL) || println(buf, "defined at [`$path:$line`]($URL).")
            end
            println(buf)
        end
        println(buf)
    end
    return nothing
end

#
# `MethodSignatures`
#

"""
The singleton type for [`SIGNATURES`](@ref) abbreviations.

$(:FIELDS)
"""
struct MethodSignatures <: Abbreviation end

"""
An [`Abbreviation`](@ref) for including a simplified representation of all the method
signatures that match the given docstring. See [`printmethod`](@ref) for details on
the simplifications that are applied.

# Examples

The generated markdown text will look similar to the following example where a function `f`
defines method taking two positional arguments, `x` and `y`, and two keywords, `a` and the `b`.

````markdown
```julia
f(x, y; a, b...)
```
````
"""
const SIGNATURES = MethodSignatures()

function format(::MethodSignatures, buf, doc)
    local binding = doc.data[:binding]
    local typesig = doc.data[:typesig]
    local modname = doc.data[:module]
    local func = Docs.resolve(binding)
    local groups = methodgroups(func, typesig, modname)
    if !isempty(groups)
        println(buf)
        println(buf, "```julia")
        for group in groups
            for method in group
                printmethod(buf, binding, func, method)
                println(buf)
            end
        end
        println(buf, "\n```\n")
    end
end

#
# `TypedMethodSignatures`
#

"""
The singleton type for [`TYPEDSIGNATURES`](@ref) abbreviations.

$(:FIELDS)
"""
struct TypedMethodSignatures <: Abbreviation end

"""
An [`Abbreviation`](@ref) for including a simplified representation of all the method
signatures with types that match the given docstring. See [`printmethod`](@ref) for details on
the simplifications that are applied.

# Examples

The generated markdown text will look similar to the following example where a function `f`
defines method taking two positional arguments, `x` and `y`, and two keywords, `a` and the `b`.

````markdown
```julia
f(x::Int, y::Int; a, b...)
```
````
"""
const TYPEDSIGNATURES = TypedMethodSignatures()

function format(::TypedMethodSignatures, buf, doc)
    local binding = doc.data[:binding]
    local typesig = doc.data[:typesig]
    local modname = doc.data[:module]
    local func = Docs.resolve(binding)
    # TODO: why is methodgroups returning invalid methods?
    # the methodgroups always appears to return a Vector and the size depends on whether parametric types are used
    # and whether default arguments are used
    local groups = methodgroups(func, typesig, modname)
    if !isempty(groups)
        group = groups[end]
        println(buf)
        println(buf, "```julia")
        for (i, method) in enumerate(group)
            N = length(arguments(method))
            # return a list of tuples that represent type signatures
            tuples = find_tuples(typesig)
            # The following will find the tuple that matches the number of arguments in the function
            # ideally we would check that the method signature matches the Tuple{...} signature
            # but that is not straightforward because of how expressive Julia can be
            if Sys.iswindows()
                t = tuples[findlast(t -> t isa DataType && t <: Tuple && length(t.types) == N, tuples)]
            else
                t = tuples[findfirst(t -> t isa DataType && t <: Tuple && length(t.types) == N, tuples)]
            end
            printmethod(buf, binding, func, method, t)
            println(buf)
        end
        println(buf, "\n```\n")
    end
end

#
# `FunctionName`
#

"""
The singleton type for [`FUNCTIONNAME`](@ref) abbreviations.

$(:FIELDS)
"""
struct FunctionName <: Abbreviation end

"""
An [`Abbreviation`](@ref) for including the function name matching the method of
the docstring.

# Usage

This is mostly useful for not repeating the function name in docstrings where
the user wants to retain full control of the argument list, or the latter does
not exist (eg generic functions).

Note that the generated docstring snippet is not quoted, use indentation or
explicit quoting.

# Example

```julia
\"""
    \$(FUNCTIONNAME)(d, θ)

Calculate the logdensity `d` at `θ`.

Users should define their own methods for `$(FUNCTIONNAME)`.
\"""
function logdensity end
```
"""
const FUNCTIONNAME = FunctionName()

format(::FunctionName, buf, doc) = print(buf, doc.data[:binding].var)

#
# `TypeSignature`
#

"""
The singleton type for [`TYPEDEF`](@ref) abbreviations.
"""
struct TypeDefinition <: Abbreviation end

"""
An [`Abbreviation`](@ref) for including a summary of the signature of a type definition.
Some of the following information may be included in the output:

  * whether the object is an `abstract` type or a `bitstype`;
  * mutability (either `type` or `struct` is printed);
  * the unqualified name of the type;
  * any type parameters;
  * the supertype of the type if it is not `Any`.

# Examples

The generated output for a type definition such as:

```julia
\"""
\$(TYPEDEF)
\"""
struct MyType{S, T <: Integer} <: AbstractArray
    # ...
end
```

will look similar to the following:

````markdown
```julia
struct MyType{S, T<:Integer} <: AbstractArray
```
````

!!! note

    No information about the fields of the type is printed. Use the [`FIELDS`](@ref)
    abbreviation to include information about the fields of a type.
"""
const TYPEDEF = TypeDefinition()

function print_supertype(buf, object)
    super = supertype(object)
    super != Any && print(buf, " <: ", super)
end

function print_params(buf, object)
    if !isempty(object.parameters)
        print(buf, "{")
        join(buf, object.parameters, ", ")
        print(buf, "}")
    end
end

function print_primitive_type(buf, object)
    print(buf, "primitive type ", object.name.name)
    print_supertype(buf, object)
    print(buf, " ", sizeof(object) * 8)
    println(buf)
end

function print_abstract_type(buf, object)
    print(buf, "abstract type ", object.name.name)
    print_params(buf, object)
    print_supertype(buf, object)
    println(buf)
end

function print_mutable_struct_or_struct(buf, object)
    object.mutable && print(buf, "mutable ")
    print(buf, "struct ", object.name.name)
    print_params(buf, object)
    print_supertype(buf, object)
    println(buf)
end

@static if VERSION < v"0.7.0"
    isprimitivetype(x) = isbitstype(x)
end

function format(::TypeDefinition, buf, doc)
    local binding = doc.data[:binding]
    local object = gettype(Docs.resolve(binding))
    if isa(object, DataType)
        println(buf, "\n```julia")
        if isprimitivetype(object)
            print_primitive_type(buf, object)
        elseif isabstracttype(object)
            print_abstract_type(buf, object)
        else
            print_mutable_struct_or_struct(buf, object)
        end
        println(buf, "```\n")
    end
end

"""
The singleton type for [`README`](@ref) abbreviations.
"""
struct Readme <: Abbreviation end
"""
    README

An [`Abbreviation`](@ref) for including the package README.md.

!!! note
    The README.md file is interpreted as ["Julia flavored Markdown"]
    (https://docs.julialang.org/en/v1/manual/documentation/#Markdown-syntax-1),
    which has some differences compared to GitHub flavored markdown, and,
    for example, [][] link shortcuts are not supported.
"""
const README = Readme()
"""
The singleton type for [`LICENSE`](@ref) abbreviations.
"""
struct License <: Abbreviation end
"""
    LICENSE

An [`Abbreviation`](@ref) for including the package LICENSE.md.

!!! note
    The LICENSE.md file is interpreted as ["Julia flavored Markdown"]
    (https://docs.julialang.org/en/v1/manual/documentation/#Markdown-syntax-1),
    which has some differences compared to GitHub flavored markdown, and,
    for example, [][] link shortcuts are not supported.
"""
const LICENSE = License()

function format(::T, buf, doc) where T <: Union{Readme,License}
    m = get(doc.data, :module, nothing)
    m === nothing && return
    path = pathof(m)
    path === nothing && return
    try # wrap in try/catch since we shouldn't error in case some IO operation goes wrong
        r = T === Readme ? r"(?i)readme(?-i)" : r"(?i)license(?-i)"
        # assume README/LICENSE is located in the root of the repo
        root = normpath(joinpath(path, "..", ".."))
        for file in readdir(root)
            if occursin(r, file)
                str = read(joinpath(root, file), String)
                write(buf, str)
                return
            end
        end
    catch
    end
end

#
# `DocStringTemplate`
#

"""
The singleton type for [`DOCSTRING`](@ref) abbreviations.
"""
struct DocStringTemplate <: Abbreviation end

"""
An [`Abbreviation`](@ref) used in [`@template`](@ref) definitions to represent the location
of the docstring body that should be spliced into a template.

!!! warning

    This abbreviation must only ever be used in template strings; never normal docstrings.
"""
const DOCSTRING = DocStringTemplate()

# NOTE: no `format` needed for this 'mock' abbreviation.

is_docstr_template(::DocStringTemplate) = true
is_docstr_template(other) = false

"""
Internal abbreviation type used to wrap templated docstrings.

`Location` is a `Symbol`, either `:before` or `:after`. `dict` stores a
reference to a module's templates.
"""
struct Template{Location} <: Abbreviation
    dict::Dict{Symbol,Vector{Any}}
end

function format(abbr::Template, buf, doc)
    # Find the applicable template based on the kind of docstr.
    parts = get_template(abbr.dict, template_key(doc))
    # Replace the abbreviation with either the parts of the template found
    # before the `DOCSTRING` abbreviation, or after it. When no `DOCSTRING`
    # exists in the template, which shouldn't really happen then nothing will
    # get included here.
    for index in included_range(abbr, parts)
        # We don't call `DocStringExtensions.format` here since we need to be
        # able to format any content in docstrings, rather than just
        # abbreviations.
        Docs.formatdoc(buf, doc, parts[index])
    end
end

function included_range(abbr::Template, parts::Vector)
    # Select the correct indexing depending on what we find.
    build_range(::Template, ::Nothing) = 0:-1
    build_range(::Template{:before}, index) = 1:(index - 1)
    build_range(::Template{:after}, index) = (index + 1):lastindex(parts)
    # Search for index from either the front or back.
    find_index(::Template{:before}) = findfirst(is_docstr_template, parts)
    find_index(::Template{:after}) = findlast(is_docstr_template, parts)
    # Find and return the correct indices.
    return build_range(abbr, find_index(abbr))
end

function template_key(doc::Docs.DocStr)
    # Local helper methods for extracting the template key from a docstring.
    ismacro(b::Docs.Binding) = startswith(string(b.var), '@')
    objname(obj::Union{Function,Module,DataType,UnionAll,Core.IntrinsicFunction}, b::Docs.Binding) = nameof(obj)
    objname(obj, b::Docs.Binding) = Symbol("") # Empty to force resolving to `:CONSTANTS` below.
    # Select the key returned based on input argument types.
    _key(::Module, sig, binding)                 = :MODULES
    _key(::Function, ::typeof(Union{}), binding) = ismacro(binding) ? :MACROS : :FUNCTIONS
    _key(::Function, sig, binding)               = ismacro(binding) ? :MACROS : :METHODS
    _key(::DataType, ::typeof(Union{}), binding) = :TYPES
    _key(::DataType, sig, binding)               = :METHODS
    _key(other, sig, binding)                    = :DEFAULT

    binding = doc.data[:binding]
    obj = Docs.resolve(binding)
    name = objname(obj, binding)
    key = name === binding.var ? _key(obj, doc.data[:typesig], binding) : :CONSTANTS
    return key
end


text:
#### Mixing length model kernels
"""
    mixing_length(
        m::AtmosModel{FT},
        ml::MixingLengthModel,
        args,
        Δ::Tuple,
        Et::Tuple,
        ts_gm,
        ts_en,
        env,
    ) where {FT}

Returns the mixing length used in the diffusive turbulence closure, given:
 - `m`, an `AtmosModel`
 - `ml`, a `MixingLengthModel`
 - `args`, the top-level arguments
 - `Δ`, the detrainment rate
 - `Et`, the turbulent entrainment rate
 - `ts_gm`, grid-mean thermodynamic states
 - `ts_en`, environment thermodynamic states
 - `env`, NamedTuple of environment variables
"""
function mixing_length(
    m::AtmosModel{FT},
    ml::MixingLengthModel,
    args,
    Δ::Tuple,
    Et::Tuple,
    Shear²,
    ts_gm,
    ts_en,
    env,
) where {FT}
    @unpack state, aux, diffusive, t = args
    # TODO: use functions: obukhov_length, ustar, ϕ_m
    turbconv = turbconv_model(m)
    # Alias convention:
    gm = state
    en = state.turbconv.environment
    up = state.turbconv.updraft
    gm_aux = aux
    N_up = n_updrafts(turbconv)

    z = altitude(m, aux)
    param_set = parameter_set(m)
    _grav::FT = grav(param_set)
    ρinv = 1 / gm.ρ

    tke_en = max(en.ρatke, 0) * ρinv / env.a

    # buoyancy related functions
    # compute obukhov_length and ustar from SurfaceFlux.jl here
    ustar = turbconv.surface.ustar
    obukhov_length = turbconv.surface.obukhov_length

    ∂b∂z, Nˢ_eff = compute_buoyancy_gradients(m, args, ts_gm, ts_en)
    Grad_Ri = ∇Richardson_number(∂b∂z, Shear², 1 / ml.max_length, ml.Ri_c)
    Pr_t = turbulent_Prandtl_number(ml.Pr_n, Grad_Ri, ml.ω_pr)

    # compute L1
    Nˢ_fact = (sign(Nˢ_eff - eps(FT)) + 1) / 2
    coeff = min(ml.c_b * sqrt(tke_en) / Nˢ_eff, ml.max_length)
    L_Nˢ = coeff * Nˢ_fact + ml.max_length * (FT(1) - Nˢ_fact)

    # compute L2 - law of the wall
    # TODO: use zLL from altitude
    surf_vals = subdomain_surface_values(m, gm, gm_aux, turbconv.surface.zLL)

    L_W = ml.κ * max(z, 5) / (sqrt(turbconv.surface.κ_star²) * ml.c_m)
    if obukhov_length < -eps(FT)
        L_W *= min((FT(1) - ml.a2 * z / obukhov_length)^ml.a1, 1 / ml.κ)
    end

    # compute L3 - entrainment detrainment sources
    # Production/destruction terms
    a = ml.c_m * (Shear² - ∂b∂z / Pr_t) * sqrt(tke_en)
    # Dissipation term
    b = FT(0)
    a_up = vuntuple(i -> up[i].ρa * ρinv, N_up)
    w_up = vuntuple(N_up) do i
        fix_void_up(up[i].ρa, up[i].ρaw / up[i].ρa)
    end
    b = sum(
        ntuple(N_up) do i
            Δ[i] / gm.ρ / env.a *
            ((w_up[i] - env.w) * (w_up[i] - env.w) / 2 - tke_en) -
            (w_up[i] - env.w) * Et[i] / gm.ρ * env.w / env.a
        end,
    )

    c_neg = ml.c_d * tke_en * sqrt(tke_en)
    if abs(a) > ml.random_minval && 4 * a * c_neg > -b^2
        l_entdet =
            max(-b / FT(2) / a + sqrt(b^2 + 4 * a * c_neg) / 2 / a, FT(0))
    elseif abs(a) < eps(FT) && abs(b) > eps(FT)
        l_entdet = c_neg / b
    else
        l_entdet = FT(0)
    end
    L_tke = l_entdet

    if L_Nˢ < eps(FT) || L_Nˢ > ml.max_length
        L_Nˢ = ml.max_length
    end
    if L_W < eps(FT) || L_W > ml.max_length
        L_W = ml.max_length
    end
    if L_tke < eps(FT) || L_tke > ml.max_length
        L_tke = ml.max_length
    end

    l_mix =
        lamb_smooth_minimum(SVector(L_Nˢ, L_W, L_tke), ml.smin_ub, ml.smin_rm)
    return l_mix, ∂b∂z, Pr_t
end;


text:
# This machinery included for servers without ITypeInfo support such as Rhino
# just call dispaxxx("Rhino.Interface") to handle naked IDispatch
# use this functionality on your own risk

function com_invoke(idspx::Ptr{IDispaxxx}, name::Symbol, flags::UInt16, args::Ref{DISPPARAMS}, ret::Ptr{Variant})

    fmid, fptr = unsafe_load.(unsafe_load(Ptr{Ptr{Ptr{Cvoid}}}(idspx)), (6, 7))
    wname = [push!(transcode(UInt16, String(name)), '\0')]
    memid = Ref(Clong(0))

    # idispatch getidsofnames
    ccall(fmid, Cint, (Ptr{IDispaxxx}, Ref{GUID}, Ref{Ptr{UInt16}}, Cuint, UInt32, Ref{Clong}),
        idspx, IID_NULL, wname, 1, LCID,  memid)

    # idispatch invoke
    ccall(fptr, Cint, (Ptr{IDispaxxx}, Clong, Ref{GUID}, UInt32, UInt16, Ref{DISPPARAMS}, Ptr{Variant}, Ptr{Cvoid}, Ptr{Cvoid}),
        idspx, memid[], IID_NULL, LCID, flags, args, ret, C_NULL, C_NULL)
end

function com_callfunc(idspx::Ptr{IDispaxxx}, name::Symbol, args::Array{Variant})
    var = Ref(Variant(0, 0, 0, 0, 0))
    arg = Ref(DISPPARAMS(pointer(reverse!(args)), C_NULL, length(args), 0))
    com_invoke(idspx, name, 0x0001, arg, Ptr{Variant}(pointer_from_objref(var)))

    ret = value(var[])
    variant_free.(args)
    variant_free(var[])
    return ret
end

function com_callmethod(idspx::Ptr{IDispaxxx}, name::Symbol, flag::UInt16 = 0x0001)
    var = Ref(Variant(0, 0, 0, 0, 0))
    arg = Ref(DISPPARAMS(C_NULL, C_NULL, 0, 0))

    com_invoke(idspx, name, flag, arg, Ptr{Variant}(pointer_from_objref(var)))

    ret = value(var[])
    variant_free(var[])
    if isa(ret, Ptr{IDispatch})
        return Ptr{IDispaxxx}(ret)
    else
        return ret
    end
end

function Base.getproperty(idspx::Ptr{IDispaxxx}, name::Symbol)
    return (args...) ->
        if length(args) > 0
            com_callfunc(idspx, name, collect(Variant.(args)))
        else
            com_callmethod(idspx, name)
        end
end

max_stars_repo_name: zaika-generative/ShapeFactory

max_issues_repo_name: zaika-generative/ShapeFactory

max_forks_repo_name: zaika-generative/ShapeFactory


text:
@testset "Basic reading" begin
    recordings_directory = joinpath(@__DIR__, "recordings")
    mkpath(recordings_directory)
    BrokenRecord.configure!(; path = recordings_directory)

    anonymous_auth = FHIRClientJSON.AnonymousAuth()
    oauth2_auth = FHIRClientJSON.OAuth2()
    FHIRClientJSON.set_token!(oauth2_auth, "helloworld")
    jwt_auth = FHIRClientJSON.JWTAuth()
    FHIRClientJSON.set_token!(jwt_auth, "helloworld")
    username_password_auth_1 = FHIRClientJSON.UsernamePassAuth("helloworld")
    FHIRClientJSON.set_password!(username_password_auth_1, "helloworld")
    username_password_auth_2 = FHIRClientJSON.UsernamePassAuth(; username = "helloworld")
    FHIRClientJSON.set_password!(username_password_auth_2, "helloworld")
    auths = [
        anonymous_auth,
        oauth2_auth,
        jwt_auth,
        username_password_auth_1,
        username_password_auth_2,
    ]

    for (i, auth) in enumerate(auths)
        base_url = FHIRClientJSON.BaseURL("https://hapi.fhir.org/baseR4")
        client = FHIRClientJSON.Client(base_url, auth)
        @test FHIRClientJSON.get_base_url(client) == base_url
        search_request_path = "/Patient?given=Jason&family=Argonaut"
        response_search_results_bundle = BrokenRecord.playback(() -> FHIRClientJSON.request_json(client, "GET", search_request_path), "recording-$(i)-1.bson")
        patient_id = response_search_results_bundle.entry[1].resource.id
        patient_request = "/Patient/$(patient_id)"
        patients = [
            BrokenRecord.playback(() -> FHIRClientJSON.request_json(client, "GET", patient_request), "recording-$(i)-2.bson")
            BrokenRecord.playback(() -> FHIRClientJSON.request_json(client, "GET", patient_request; body = JSON3.read("{}")), "recording-$(i)-3.bson")
            BrokenRecord.playback(() -> FHIRClientJSON.request_json(client, "GET", patient_request; query = Dict{String, String}()), "recording-$(i)-4.bson")
            BrokenRecord.playback(() -> FHIRClientJSON.request_json(client, "GET", patient_request; body = JSON3.read("{}"), query = Dict{String, String}()), "recording-$(i)-5.bson")
        ]
        for patient in patients
            @test patient isa AbstractDict
            @test only(patient.name).use == "usual"
            @test only(patient.name).text == "Jason Argonaut"
            @test only(patient.name).family == "Argonaut"
            @test only(only(patient.name).given) == "Jason"
            @test patient.birthDate == "1985-08-01"
        end
        Base.shred!(auth)
        Base.shred!(client)
    end

    for i in 1:length(auths)
        Base.shred!(auths[i])
    end
end


text:
### Day 23
## Safe Cracking
## Author: Thanasis Georgiou
workspace()

# Convert anything to integer
int(any) = parse(Int, any)

# Type union of String and Int to use in instructions
IntOrString = Union{Int, String}

# Instruction struct
immutable Instruction
  opcode::String
  args::Array{IntOrString}
end

# A CPU with registers, a program counter and program ROM
type CPU
  gpreg::Dict{String, Int}
  pc::Int
  program::Array{Instruction}
end

# Supported opcodes
opcodes = Dict{String, Function}()

opcodes["cpy"] = function (cpu::CPU, args::Array{IntOrString})
  # Deconstruct args
  (from, to) = args

  # Value to copy
  value = isa(from, String)? cpu.gpreg[from] : from

  # Set target register
  cpu.gpreg[to] = value
end

opcodes["inc"] = function (cpu::CPU, args::Array{IntOrString})
  # Increment the register
  cpu.gpreg[args[1]] += 1
end

opcodes["dec"] = function (cpu::CPU, args::Array{IntOrString})
  # Decrement the register
  cpu.gpreg[args[1]] -= 1
end

opcodes["jnz"] = function (cpu::CPU, args::Array{IntOrString})
  # Deconstruct args
  (cond, jump) = args

  # Value to check
  value = isa(cond, String)? cpu.gpreg[cond] : cond

  # Jump if the value is not zero
  if value != 0
    jump = isa(jump, String)? cpu.gpreg[jump] : jump
    cpu.pc += jump
  end
end

opcodes["mul"] = function (cpu::CPU, args::Array{IntOrString})
  # Deconstruct array
  (times, with, to) = args

  # Parse args
  times = isa(times, String)? cpu.gpreg[times] : times
  with = isa(with, String)? cpu.gpreg[with] : with

  cpu.gpreg[to] += times * with
end

opcodes["tgl"] = function (cpu::CPU, args::Array{IntOrString})
  # Parse offset
  offset = isa(args[1], String)? cpu.gpreg[args[1]] : args[1]

  # Get instruction at offset
  if cpu.pc + offset > length(cpu.program)
    return
  end
  instr = cpu.program[cpu.pc + offset]

  # Switch instruction
  newOpcode = ""
  if length(instr.args) == 1
    if instr.opcode != "inc"
      newOpcode = "inc"
    else
      newOpcode = "dec"
    end
  elseif length(instr.args) == 2
    if instr.opcode == "jnz"
      newOpcode = "cpy"
    else
      newOpcode = "jnz"
    end
  end

  # Add back to program memory
  cpu.program[cpu.pc + offset] = Instruction(newOpcode, copy(instr.args))
end

opcodes["nop"] = function(cpu::CPU, args::Array{IntOrString})
end

# Go forward one clock cycle
function clock(cpu::CPU)::Bool
  # Get current instruction from program memory
  instr = cpu.program[cpu.pc]

  # Store program counter
  pc = cpu.pc

  # Execute instruction
  opcodes[instr.opcode](cpu, instr.args)

  # If the program counter didn't change by some instruction, we should move it to the next line in ROM
  if cpu.pc == pc
    cpu.pc += 1
  end

  # Check if there are more instructions to execute
  return cpu.pc <= length(cpu.program)
end

# Parse an instruction string into a struct
function parseInstruction(instr::String)::Instruction
  # Split at spaces
  instr = split(instr, ' ')
  argCount = length(instr) - 1

  # Arguments array
  args = Array(IntOrString, argCount)
  for i = 1:argCount
    arg = instr[i + 1]
    args[i] = get(tryparse(Int, arg), String(arg))
  end

  # Return struct
  return Instruction(instr[1], args)
end

function createCPU(rom::Array{String})::CPU
  # Initialize registers
  registers = Dict{String, Int}()
  registers["a"] = 0
  registers["b"] = 0
  registers["c"] = 0
  registers["d"] = 0

  # Create CPU
  return CPU(registers, 1, map(instr -> parseInstruction(instr), rom))
end

# Read input from file
f = open("safe-op.asm")
rom = map(line -> chomp(line), readlines(f))
close(f)

# Create CPU
cpu = createCPU(rom)

# Number of eggs in register a
cpu.gpreg["a"] = 12

# Execute program
i = 0
while clock(cpu)
  i += 1
end

# Print cpu state
println("Execution finished in $i clocks.")


text:
import Base: print, length, push!

type FIRFilter{Th,Tx}
    q::Ptr{Th}
    tx::Type{Tx}
end

Base.show(io::IO, obj::FIRFilter) = print(io::IO, "FIRFilter")

function Base.showall(io::IO, obj::FIRFilter)
    println(io::IO)
    print(obj)
end

for (sigstr, Ty, Th, Tx) in (rrrf, crcf, cccf)

    # FIRFILT() FIRFILT(_create)(TC * _h, unsigned int _n);

    @eval begin
        function FIRFilter(::Type{$Tx}, h::Vector{$Th} )
            q   = ccall(($"firfilt_$(sigstr)_create", liquiddsp), Ptr{$Th}, (Ptr{$Th}, Cuint), h, length(h))
            obj = FIRFilter(q,$Tx)
            finalizer(obj, destroy)
            return obj
        end
    end

    # /* print filter object information
    # void FIRFILT(_print)(FIRFILT() _q);

    @eval begin
        function print( obj::FIRFilter{$Th,$Tx} )
            obj.q == C_NULL && error("`obj` is a NULL pointer")
            ccall(($"firfilt_$(sigstr)_print", liquiddsp), Void, (Ptr{$Th},), obj.q)
        end
    end

    # /* reset filter object's internal buffer
    # void FIRFILT(_reset)(FIRFILT() _q);

    @eval begin
        function reset!( obj::FIRFilter{$Th,$Tx} )
            obj.q == C_NULL && error("`obj` is a NULL pointer")
            ccall(($"firfilt_$(sigstr)_reset", liquiddsp), Void, (Ptr{$Th},), obj.q)
        end
    end

    # /* return length of filter object
    # unsigned int FIRFILT(_get_length)(FIRFILT() _q);

    @eval begin
        function length( obj::FIRFilter{$Th,$Tx} )
            obj.q == C_NULL && error("`obj` is a NULL pointer")
            ccall(($"firfilt_$(sigstr)_length", liquiddsp), Cint, (Ptr{$Th},), obj.q)
        end
    end

    # /* destroy filter object and free all internal memory
    # void FIRFILT(_destroy)(FIRFILT() _q);

    @eval begin
        function destroy( obj::FIRFilter{$Th,$Tx} )
            obj.q == C_NULL && return
            ccall(($"firfilt_$(sigstr)_destroy", liquiddsp), Void, (Ptr{$Th},), obj.q)
            obj.q = C_NULL
        end
    end

    # /* execute the filter on a block of input samples; the
    # /* input and output buffers may be the same
    # /*  _q      : filter object
    # /*  _x      : pointer to input array [size: _n x 1]
    # /*  _n      : number of input, output samples
    # /*  _y      : pointer to output array [size: _n x 1]
    # void FIRFILT(_execute_block)(FIRFILT()    _q,
    #                              TI *         _x,
    #                              unsigned int _n,
    #                              TO *         _y);

    @eval begin
        function execute( obj::FIRFilter{$Th,$Tx}, x::Vector{$Tx} )
            obj.q == C_NULL && error("`obj` is a NULL pointer")
            xLen = length(x)
            y = Array($Ty, xLen)
            ccall(($"firfilt_$(sigstr)_execute_block", liquiddsp), Void, (Ptr{$Th}, Ptr{$Tx}, Cuint, Ptr{$Ty}), obj.q, x, xLen, y)
            return y
        end
    end

    # /* execute the filter on internal buffer and coefficients
    # /*  _q      : filter object
    # /*  _y      : pointer to single output sample
    # void FIRFILT(_execute)(FIRFILT() _q,
    #                        TO *      _y);

    @eval begin
        function execute( obj::FIRFilter{$Th,$Tx})
            obj.q == C_NULL && error("`obj` is a NULL pointer")
            y = Array($Ty ,1)
            ccall(($"firfilt_$(sigstr)_execute", liquiddsp), Void, (Ptr{$Th}, Ptr{$Ty}), obj.q, y)
            return y[1]
        end
    end

    # /* push sample into filter object's internal buffer
    # /*  _q      : filter object
    # /*  _x      : single input sample
    # void FIRFILT(_push)(FIRFILT() _q,
    #                     TI        _x);

    if Tx<:Complex && VERSION.minor < 4
        @eval begin
            function push!( obj::FIRFilter{$Th,$Tx}, x::$Tx )
                obj.q == C_NULL && error("`obj` is a NULL pointer")
                ccall(($"firfilt_$(sigstr)_push", liquiddsp), Void, (Ptr{$Th}, ($realtype($Tx), $realtype($Tx))), obj.q, (real(x), imag(x)))
            end
        end
    else
        @eval begin
            function push!( obj::FIRFilter{$Th,$Tx}, x::$Tx )
                obj.q == C_NULL && error("`obj` is a NULL pointer")
                ccall(($"firfilt_$(sigstr)_push", liquiddsp), Void, (Ptr{$Th}, $Tx), obj.q, x)
            end
        end
    end

    # /* compute complex frequency response of filter object
    # /*  _q      : filter object
    # /*  _fc     : frequency to evaluate
    # /*  _H      : pointer to output complex frequency response
    # void FIRFILT(_freqresponse)(FIRFILT()              _q,
    #                             float                  _fc,
    #                             liquid_float_complex * _H);

    @eval begin
        function freqresponse( obj::FIRFilter{$Th,$Tx}, f::Real )
            obj.q == C_NULL && error("`obj` is a NULL pointer")
            0 <= f <= 0.5 || throw(ArgumentError("f must be normalized 0.5 == nyquist"))
            z = Array(Complex64, 1)
            ccall(($"firfilt_$(sigstr)_freqresponse", liquiddsp), Float32, (Ptr{$Th}, Float32, Ptr{Complex64}), obj.q, f, z)
            return z[1]
        end
    end

    # /* compute and return group delay of filter object
    # /*  _q      : filter object
    # /*  _fc     : frequency to evaluate
    # float FIRFILT(_groupdelay)(FIRFILT() _q,
    #                            float     _fc);

    @eval begin
        function groupdelay( obj::FIRFilter{$Th,$Tx}, f::Real )
            obj.q == C_NULL && error("`obj` is a NULL pointer")
            0 <= f <= 0.5 || throw(ArgumentError("f must be normalized 0.5 == nyquist"))
            ccall(($"firfilt_$(sigstr)_groupdelay", liquiddsp), Float32, (Ptr{$Th}, Float32), obj.q, f)
        end
    end
end

# Handle conversion of taps tp Float32
FIRFilter(Tx::Type, h::AbstractVector) = FIRFilter(Tx, limitprecision(h))

# If passed only taps, assume x will be the same type
function FIRFilter(h::AbstractVector)
    h = limitprecision(h)
    FIRFilter(eltype(h), h)
end

function gettaps{Th,Tx}(obj::FIRFilter{Th,Tx})
    hLenPtr = convert(Ptr{Cuint}, obj.q+sizeof(obj.q))
    hLen    = unsafe_load(hLenPtr)
    hPtr    = convert(Ptr{Ptr{Th}}, obj.q)
    h       = pointer_to_array(unsafe_load(hPtr), hLen)
end

# /* create using Kaiser-Bessel windowed sinc method
# /*  _n      : filter length, _n > 0
# /*  _fc     : filter cut-off frequency 0 < _fc < 0.5
# /*  _As     : filter stop-band attenuation [dB], _As > 0
# /*  _mu     : fractional sample offset, -0.5 < _mu < 0.5
# FIRFILT() FIRFILT(_create_kaiser)(unsigned int _n,
#                                   float        _fc,
#                                   float        _As,
#                                   float        _mu);
#
# /* create from square-root Nyquist prototype
# /*  _type   : filter type (e.g. LIQUID_FIRFILT_RRC)
# /*  _k      : nominal samples/symbol, _k > 1
# /*  _m      : filter delay [symbols], _m > 0
# /*  _beta   : rolloff factor, 0 < beta <= 1
# /*  _mu     : fractional sample offset,-0.5 < _mu < 0.5
# FIRFILT() FIRFILT(_create_rnyquist)(int          _type,
#                                     unsigned int _k,
#                                     unsigned int _m,
#                                     float        _beta,
#                                     float        _mu);
#
# /* re-create filter
# /*  _q      : original filter object
# /*  _h      : pointer to filter coefficients [size: _n x 1]
# /*  _n      : filter length, _n > 0
# FIRFILT() FIRFILT(_recreate)(FIRFILT()    _q,
#                              TC *         _h,
#                              unsigned int _n);
#
#
#
#
# /* set output scaling for filter
# void FIRFILT(_set_scale)(FIRFILT() _q,
#                          TC        _scale);
#

max_stars_repo_name: JayKickliter/LiquidDSP

max_issues_repo_name: JayKickliter/LiquidDSP

max_forks_repo_name: JayKickliter/LiquidDSP


text:
# abstract supertype of specific semidiscretizations such as
# - SemidiscretizationHyperbolic for hyperbolic conservation laws
# - SemidiscretizationEulerGravity for Euler with self-gravity
abstract type AbstractSemidiscretization end

"""
    AbstractEquations{NDIMS, NVARS}

An abstract supertype of specific equations such as the compressible Euler equations.
The type parameters encode the number of spatial dimensions (`NDIMS`) and the
number of primary variables (`NVARS`) of the physics model.
"""
abstract type AbstractEquations{NDIMS, NVARS} end

"""
    AbstractMesh{NDIMS}

An abstract supertype of specific mesh types such as `TreeMesh` or `CurvedMesh`.
The type parameters encode the number of spatial dimensions (`NDIMS`).
"""
abstract type AbstractMesh{NDIMS} end

# abstract supertype of specific SBP bases such as a Lobatto-Legendre nodal basis
abstract type AbstractBasisSBP{RealT<:Real} end

# abstract supertype of mortar methods, e.g. using L² projections
abstract type AbstractMortar{RealT<:Real} end

# abstract supertype of mortar methods using L² projection
# which will be specialized for different SBP bases
abstract type AbstractMortarL2{RealT<:Real} <: AbstractMortar{RealT} end

# abstract supertype of functionality related to the analysis of
# numerical solutions, e.g. the calculation of errors
abstract type SolutionAnalyzer{RealT<:Real} end

# abstract supertype of grid-transfer methods used for AMR,
# e.g. refinement and coarsening based on L² projections
abstract type AdaptorAMR{RealT<:Real} end

# abstract supertype of AMR grid-transfer operations using L² projections
# which will be specialized for different SBP bases
abstract type AdaptorL2{RealT<:Real} <: AdaptorAMR{RealT} end

# TODO: Taal decide, which abstract types shall be defined here?

struct BoundaryConditionPeriodic end

"""
    boundary_condition_periodic = BoundaryConditionPeriodic()

A singleton struct indicating periodic boundary conditions.
"""
const boundary_condition_periodic = BoundaryConditionPeriodic()

Base.show(io::IO, ::BoundaryConditionPeriodic) = print(io, "boundary_condition_periodic")


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

using Markdown
using InteractiveUtils

# ╔═╡ 0255a190-df31-11eb-2591-09600ea47d50
begin
	using Plots
	using Printf
	using CSV
	using DataFrames
	using LinearAlgebra
end

# ╔═╡ 369b8ad0-387f-4509-afe3-03e5bf79ddb8
md"_Compressible Similarity, version 1_"

# ╔═╡ 90714396-cbc5-4c42-8853-4da1c83674fd
md"""
## **Compressible Blasius**

#### **Description:**

This notebook computes the compressible version of Blasius Similarity Solution coupled with the energy equation

		selfsimilar(M∞, T∞, Tw, ηmax, N, ϵ)

If the arguments are missing, it will use the default values.

		selfsimilar(M∞=1.0, T∞=300, Tw=2.0, ηmax=10, N=100, ϵ=1e-9)

#### **Compressible Blasius Equation**
Boundary-layer velocity and temperature profiles on the flat plate can be projected onto single profile wich is self-similar profile. It can be represented using the ordinary differential equations (ODEs) below:

$$(cf'')'+ff'' =0$$
$$(a_1g'+a_2f'f'')'+fg'=0$$

where

$$f'=\frac{u}{u_e}$$
$$c=\frac{\rho \mu}{\rho_e \mu_e}$$
$$g=\frac{H}{H_e}$$
$$a_1=\frac{c}{\sigma}$$
$$a_2=\frac{(\gamma-1)M^2}{1+(\frac{\gamma-1}{2})M^2}\left(1-\frac{1}{\sigma}\right)c$$

and H is the enthalpy, γ is the ratio of specific heats, M is the edge Mach number, and σ is the Prandtl number. σ and M can be defined as

$$M=\frac{u_e}{\sqrt{\gamma \mathfrak{R}T_e}}$$
$$\sigma=\frac{\mu c_p}{k}$$

In this code, σ is assumed as 0.72. The viscosity μ is a function of T and it is calculated as

$$μ = c₁\frac{T^{3/2}}{(T+c₂)}$$

c₂ is 110.4 Kelvin. c₁ is disappearing on the nondimensionalizing process. The boundary conditions for the system of ODEs are

$$y=0;  f=f'=0$$
$$y\rightarrow \infty;  f',g \rightarrow 0$$

The resultant equations along with the boundary conditions are solved with the Runge-Kutta scheme with Newton's iteration method for the missing boundary condition.

Details of RK:
Numerical Recipes, Cambridge

Details of Similarity solution formulation:
Boundary-Layer Theory, 7ᵗʰ edition, Schlichting

Feel free to ask questions!

*Furkan Oz*
[foz@okstate.edu](foz@okstate.edu)

*Kursat Kara*
[kursat.kara@okstate.edu](kursat.kara@okstate.edu)

"""

# ╔═╡ 93f57edd-4d2b-41fd-ba6e-2d84a24b7585
function Y1(y₂)
    return y₂
end

# ╔═╡ b30b23d8-ee53-4927-8215-a725a50105d1
function Y2(y₃)
    return y₃
end

# ╔═╡ 454845db-90ad-4236-b038-0bc6f8c9fcc2
function Y3(y₁,y₃,y₄,y₅,cμ,T∞)
    return -y₃*((y₅/(2*(y₄)))-(y₅/(y₄+cμ/T∞)))-y₁*y₃*((y₄+cμ/T∞)/(sqrt(y₄)*(1+cμ/T∞)));
end

# ╔═╡ 3b96c692-d6a2-46dc-8469-c2b1dbc9ae28
function Y4(y₅)
    return y₅
end

# ╔═╡ ee61b590-56e1-4379-9cf0-58d27affdf1e
function Y5(y₁,y₃,y₄,y₅,cμ,T∞,M∞,Pr,γ)
    return -y₅^2*((0.5/y₄)-(1/(y₄+cμ/T∞)))-Pr*y₁*y₅/sqrt(y₄)*(y₄+cμ/T∞)/(1+cμ/T∞)-(γ-1)*Pr*M∞^2*y₃^2;
end

# ╔═╡ df41fba9-b24b-485b-a4b5-b3bcd1f69485
function RK(N,h,y1,y2,y3,y4,y5,cμ,T∞,Pr,γ,M∞)
	for i=1:N
		k11 = Y1(y2[i]);
		k21 = Y2(y3[i]);
		k31 = Y3(y1[i], y3[i], y4[i], y5[i],cμ,T∞);
		k41 = Y4(y5[i]);
		k51 = Y5(y1[i], y3[i], y4[i], y5[i],cμ,T∞,M∞,Pr,γ);

		k12 = Y1(y2[i]+0.5*h*k21);
		k22 = Y2(y3[i]+0.5*h*k31);
		k32 = Y3(y1[i]+0.5*h*k11, y3[i]+0.5*h*k31, y4[i]+0.5*h*k41, y5[i]+0.5*h*k51,cμ,T∞);
		k42 = Y4(y5[i]+0.5*h*k51);
		k52 = Y5(y1[i]+0.5*h*k11, y3[i]+0.5*h*k31, y4[i]+0.5*h*k41, y5[i]+0.5*h*k51,cμ,T∞,M∞,Pr,γ);

		k13 = Y1(y2[i]+0.5*h*k22);
		k23 = Y2(y3[i]+0.5*h*k32);
		k33 = Y3(y1[i]+0.5*h*k12, y3[i]+0.5*h*k32, y4[i]+0.5*h*k42, y5[i]+0.5*h*k52,cμ,T∞);
		k43 = Y4(y5[i]+0.5*h*k52);
		k53 = Y5(y1[i]+0.5*h*k12, y3[i]+0.5*h*k32, y4[i]+0.5*h*k42, y5[i]+0.5*h*k52,cμ,T∞,M∞,Pr,γ);

		k14 = Y1(y2[i]+h*k23);
		k24 = Y2(y3[i]+h*k33);
		k34 = Y3(y1[i]+h*k13, y3[i]+h*k33, y4[i]+h*k43, y5[i]+h*k53,cμ,T∞);
		k44 = Y4(y5[i]+h*k53);
		k54 = Y5(y1[i]+h*k13, y3[i]+h*k33, y4[i]+h*k43, y5[i]+h*k53,cμ,T∞,M∞,Pr,γ);

		y5[i+1] = y5[i] + (1/6)*(k51 + 2*k52 + 2*k53 + k54)*h;
		y4[i+1] = y4[i] + (1/6)*(k41 + 2*k42 + 2*k43 + k44)*h;
		y3[i+1] = y3[i] + (1/6)*(k31 + 2*k32 + 2*k33 + k34)*h;
		y2[i+1] = y2[i] + (1/6)*(k21 + 2*k22 + 2*k23 + k24)*h;
		y1[i+1] = y1[i] + (1/6)*(k11 + 2*k12 + 2*k13 + k14)*h;
	end
	return y1,y2,y3,y4,y5
end

# ╔═╡ 6cf78f5d-7eda-4abd-9281-3269e077b48a
"""
Computes the compressible Similarity Solution
This notebook computes the compressible Similarity Solution

		selfsimilar(M∞, T∞, Tw, ηmax, N, ϵ)

If the arguments are missing, it will use the default values.

		selfsimilar(M∞=1.0, T∞=300, Tw=2.0, ηmax=10, N=100, ϵ=1e-9)

Furkan Oz,
foz@okstate.edu,

"""
function selfsimilar(M∞=1.0, T∞=300, Tw=2.0, ηmax=10, N=100, ϵ=1e-9)
    Δη = ηmax/N
    γ  = 1.4   # Ratio of specific heat
    cμ = 110.4 # Sutherland law coefficient for [Kelvin]
    Pr = 0.72  # Prandtl Number
	adi = 1

    Δ = 1e-10     # Small number for shooting method (Decrease when ϵ is decreased)

    # Initializing the solution vectors
    y1 = zeros(N+1)   # f
    y2 = zeros(N+1)   # f'
    y3 = zeros(N+1)   # f''
    y4 = zeros(N+1)   # ρ(η)
    y5 = zeros(N+1)   # ρ(η)'
    η  = [i*Δη for i=0:N]

	if adi==1
		y1[1] = 0.0
    	y2[1] = 0.0
    	y5[1] = 0.0

    	α₀ = 0.1 	  # Initial Guess
    	β₀ = 2.3118      # Initial Guess
	elseif adi==0
		y1[1] = 0
    	y2[1] = 0
    	y4[1] = Tw

    	α₀ = 0.1 	  # Initial Guess
    	β₀ = 3.0      # Initial Guess
	end

    y2n = 1
    y4n = 1
    for i=1:100000
        if adi==1
    		y1[1] = 0.0
        	y2[1] = 0.0
        	y5[1] = 0.0

            y3[1] = α₀;    # Initial Guess
            y4[1] = β₀;    # Initial Guess
    	elseif adi==0
    		y1[1] = 0
        	y2[1] = 0
        	y4[1] = Tw

            y3[1] = α₀;    # Initial Guess
            y5[1] = β₀;    # Initial Guess
    	end

		# First solution for Newton's iteration
        y1,y2,y3,y4,y5 = RK(N,Δη,y1,y2,y3,y4,y5,cμ,T∞,Pr,γ,M∞)

        # Storing the freestream values for Newton's iteration method
        y₂ₒ = y2[N+1];
        y₄ₒ = y4[N+1];

        # Small number addition for Newton's iteration method
        if adi==1
    		y1[1] = 0.0
        	y2[1] = 0.0
        	y5[1] = 0.0

            y3[1] = α₀+Δ;   # Initial Guess + Small number
            y4[1] = β₀;    # Initial Guess
    	elseif adi==0
    		y1[1] = 0
        	y2[1] = 0
        	y4[1] = Tw

            y3[1] = α₀+Δ;    # Initial Guess + Small number
            y5[1] = β₀;    # Initial Guess
    	end

		# Second solution for Newton's iteration
        y1,y2,y3,y4,y5 = RK(N,Δη,y1,y2,y3,y4,y5,cμ,T∞,Pr,γ,M∞)

        # Storing the freestream values for Newton's iteration method
        y₂ₙ₁ = y2[N+1];
        y₄ₙ₁ = y4[N+1];

        # Small number addition for Newton's iteration method
        # Small number addition for Newton's iteration method
        if adi==1
    		y1[1] = 0.0
        	y2[1] = 0.0
        	y5[1] = 0.0

            y3[1] = α₀;   # Initial Guess
            y4[1] = β₀+Δ;    # Initial Guess + Small number
    	elseif adi==0
    		y1[1] = 0
        	y2[1] = 0
        	y4[1] = Tw

            y3[1] = α₀;    # Initial Guess
            y5[1] = β₀+Δ;    # Initial Guess + Small number
    	end

		# Third solution for Newton's iteration
        y1,y2,y3,y4,y5 = RK(N,Δη,y1,y2,y3,y4,y5,cμ,T∞,Pr,γ,M∞)

        # Storing the freestream values for Newton's iteration method
        y₂ₙ₂ = y2[N+1];
        y₄ₙ₂ = y4[N+1];

        # Calculation of the next initial guess with Newton's iteration method
        p₁₁ = (y₂ₙ₁-y₂ₒ)/Δ;
        p₂₁ = (y₄ₙ₁-y₄ₒ)/Δ;
        p₁₂ = (y₂ₙ₂-y₂ₒ)/Δ;
        p₂₂ = (y₄ₙ₂-y₄ₒ)/Δ;
        r₁ = 1-y₂ₒ;
        r₂ = 1-y₄ₒ;
        Δα = (p₂₂*r₁-p₁₂*r₂)/(p₁₁*p₂₂-p₁₂*p₂₁);
        Δβ = (p₁₁*r₂-p₂₁*r₁)/(p₁₁*p₂₂-p₁₂*p₂₁);
        α₀ = α₀ + Δα;
        β₀ = β₀ + Δβ;

        #@show(norm(y4))
		if (abs(y2[N+1]-1.0)<ϵ) && (abs(y4[N+1]-1.0)<ϵ) && (abs(y2n-norm(y2))<ϵ) && (abs(y4n-norm(y4))<ϵ)
        	break
    	end
        y2n = norm(y2)
        y4n = norm(y4)
    end

	# Copying values for logical names
    U = y2
    T = y4

    # Integration for η --> y transformation
    y = zeros(N+1);
    for i=2:N+1
       y[i] = y[i-1] + y4[i]*(η[i]-η[i-1]);
    end
    y = y*sqrt(2);

    return η,y,U,T,N
end

# ╔═╡ f044ac30-60d8-4ebe-8048-463ba4b8bebd
ηtest, ytest, Utest, Ttest, Ntest = selfsimilar();

# ╔═╡ 724e9305-48a8-41ef-88c1-f7f4f2b6e346
begin
	plot([Utest,Ttest],ηtest,
	        title = "Compressible Blasius Profiles",
	        label = ["U" "T"],
	        legend = :topleft,
	        xlabel = "U,T",
	        ylabel = "\\eta",
	        linewidth = 2,
	        linecolor = :black,
	        markershape = :circle,
	        markercolor = [:red :blue],
		)
end

# ╔═╡ 00000000-0000-0000-0000-000000000001
PLUTO_PROJECT_TOML_CONTENTS = """
[deps]
CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"

[compat]
CSV = "~0.8.5"
DataFrames = "~1.2.0"
Plots = "~1.18.1"
"""

# ╔═╡ 00000000-0000-0000-0000-000000000002
PLUTO_MANIFEST_TOML_CONTENTS = """
# This file is machine-generated - editing it directly is not advised

[[Adapt]]
deps = ["LinearAlgebra"]
git-tree-sha1 = "84918055d15b3114ede17ac6a7182f68870c16f7"
uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e"
version = "3.3.1"

[[Artifacts]]
deps = ["Pkg"]
git-tree-sha1 = "c30985d8821e0cd73870b17b0ed0ce6dc44cb744"
uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33"
version = "1.3.0"

[[Base64]]
uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"

[[Bzip2_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "c3598e525718abcc440f69cc6d5f60dda0a1b61e"
uuid = "6e34b625-4abd-537c-b88f-471c36dfa7a0"
version = "1.0.6+5"

[[CSV]]
deps = ["Dates", "Mmap", "Parsers", "PooledArrays", "SentinelArrays", "Tables", "Unicode"]
git-tree-sha1 = "b83aa3f513be680454437a0eee21001607e5d983"
uuid = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
version = "0.8.5"

[[Cairo_jll]]
deps = ["Artifacts", "Bzip2_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "JLLWrappers", "LZO_jll", "Libdl", "Pixman_jll", "Pkg", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"]
git-tree-sha1 = "e2f47f6d8337369411569fd45ae5753ca10394c6"
uuid = "83423d85-b0ee-5818-9007-b63ccbeb887a"
version = "1.16.0+6"

[[ColorSchemes]]
deps = ["ColorTypes", "Colors", "FixedPointNumbers", "Random", "StaticArrays"]
git-tree-sha1 = "c8fd01e4b736013bc61b704871d20503b33ea402"
uuid = "35d6a980-a343-548e-a6ea-1d62b119f2f4"
version = "3.12.1"

[[ColorTypes]]
deps = ["FixedPointNumbers", "Random"]
git-tree-sha1 = "024fe24d83e4a5bf5fc80501a314ce0d1aa35597"
uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f"
version = "0.11.0"

[[Colors]]
deps = ["ColorTypes", "FixedPointNumbers", "Reexport"]
git-tree-sha1 = "417b0ed7b8b838aa6ca0a87aadf1bb9eb111ce40"
uuid = "5ae59095-9a9b-59fe-a467-6f913c188581"
version = "0.12.8"

[[Compat]]
deps = ["Base64", "Dates", "DelimitedFiles", "Distributed", "InteractiveUtils", "LibGit2", "Libdl", "LinearAlgebra", "Markdown", "Mmap", "Pkg", "Printf", "REPL", "Random", "SHA", "Serialization", "SharedArrays", "Sockets", "SparseArrays", "Statistics", "Test", "UUIDs", "Unicode"]
git-tree-sha1 = "dc7dedc2c2aa9faf59a55c622760a25cbefbe941"
uuid = "34da2185-b29b-5c13-b0c7-acf172513d20"
version = "3.31.0"

[[CompilerSupportLibraries_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "8e695f735fca77e9708e795eda62afdb869cbb70"
uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae"
version = "0.3.4+0"

[[Contour]]
deps = ["StaticArrays"]
git-tree-sha1 = "9f02045d934dc030edad45944ea80dbd1f0ebea7"
uuid = "d38c429a-6771-53c6-b99e-75d170b6e991"
version = "0.5.7"

[[Crayons]]
git-tree-sha1 = "3f71217b538d7aaee0b69ab47d9b7724ca8afa0d"
uuid = "a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f"
version = "4.0.4"

[[DataAPI]]
git-tree-sha1 = "ee400abb2298bd13bfc3df1c412ed228061a2385"
uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a"
version = "1.7.0"

[[DataFrames]]
deps = ["Compat", "DataAPI", "Future", "InvertedIndices", "IteratorInterfaceExtensions", "LinearAlgebra", "Markdown", "Missings", "PooledArrays", "PrettyTables", "Printf", "REPL", "Reexport", "SortingAlgorithms", "Statistics", "TableTraits", "Tables", "Unicode"]
git-tree-sha1 = "1dadfca11c0e08e03ab15b63aaeda55266754bad"
uuid = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
version = "1.2.0"

[[DataStructures]]
deps = ["Compat", "InteractiveUtils", "OrderedCollections"]
git-tree-sha1 = "4437b64df1e0adccc3e5d1adbc3ac741095e4677"
uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
version = "0.18.9"

[[DataValueInterfaces]]
git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6"
uuid = "e2d170a0-9d28-54be-80f0-106bbe20a464"
version = "1.0.0"

[[Dates]]
deps = ["Printf"]
uuid = "ade2ca70-3891-5945-98fb-dc099432e06a"

[[DelimitedFiles]]
deps = ["Mmap"]
uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab"

[[Distributed]]
deps = ["Random", "Serialization", "Sockets"]
uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b"

[[EarCut_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "92d8f9f208637e8d2d28c664051a00569c01493d"
uuid = "5ae413db-bbd1-5e63-b57d-d24a61df00f5"
version = "2.1.5+1"

[[Expat_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "1402e52fcda25064f51c77a9655ce8680b76acf0"
uuid = "2e619515-83b5-522b-bb60-26c02a35a201"
version = "2.2.7+6"

[[FFMPEG]]
deps = ["FFMPEG_jll"]
git-tree-sha1 = "b57e3acbe22f8484b4b5ff66a7499717fe1a9cc8"
uuid = "c87230d0-a227-11e9-1b43-d7ebe4e7570a"
version = "0.4.1"

[[FFMPEG_jll]]
deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "JLLWrappers", "LAME_jll", "LibVPX_jll", "Libdl", "Ogg_jll", "OpenSSL_jll", "Opus_jll", "Pkg", "Zlib_jll", "libass_jll", "libfdk_aac_jll", "libvorbis_jll", "x264_jll", "x265_jll"]
git-tree-sha1 = "3cc57ad0a213808473eafef4845a74766242e05f"
uuid = "b22a6f82-2f65-5046-a5b2-351ab43fb4e5"
version = "4.3.1+4"

[[FixedPointNumbers]]
deps = ["Statistics"]
git-tree-sha1 = "335bfdceacc84c5cdf16aadc768aa5ddfc5383cc"
uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93"
version = "0.8.4"

[[Fontconfig_jll]]
deps = ["Artifacts", "Bzip2_jll", "Expat_jll", "FreeType2_jll", "JLLWrappers", "Libdl", "Libuuid_jll", "Pkg", "Zlib_jll"]
git-tree-sha1 = "35895cf184ceaab11fd778b4590144034a167a2f"
uuid = "a3f928ae-7b40-5064-980b-68af3947d34b"
version = "2.13.1+14"

[[Formatting]]
deps = ["Printf"]
git-tree-sha1 = "8339d61043228fdd3eb658d86c926cb282ae72a8"
uuid = "59287772-0a20-5a39-b81b-1366585eb4c0"
version = "0.4.2"

[[FreeType2_jll]]
deps = ["Artifacts", "Bzip2_jll", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"]
git-tree-sha1 = "cbd58c9deb1d304f5a245a0b7eb841a2560cfec6"
uuid = "d7e528f0-a631-5988-bf34-fe36492bcfd7"
version = "2.10.1+5"

[[FriBidi_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "0d20aed5b14dd4c9a2453c1b601d08e1149679cc"
uuid = "559328eb-81f9-559d-9380-de523a88c83c"
version = "1.0.5+6"

[[Future]]
deps = ["Random"]
uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820"

[[GLFW_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Libglvnd_jll", "Pkg", "Xorg_libXcursor_jll", "Xorg_libXi_jll", "Xorg_libXinerama_jll", "Xorg_libXrandr_jll"]
git-tree-sha1 = "a199aefead29c3c2638c3571a9993b564109d45a"
uuid = "0656b61e-2033-5cc2-a64a-77c0f6c09b89"
version = "3.3.4+0"

[[GR]]
deps = ["Base64", "DelimitedFiles", "GR_jll", "HTTP", "JSON", "Libdl", "LinearAlgebra", "Pkg", "Printf", "Random", "Serialization", "Sockets", "Test", "UUIDs"]
git-tree-sha1 = "b83e3125048a9c3158cbb7ca423790c7b1b57bea"
uuid = "28b8d3ca-fb5f-59d9-8090-bfdbd6d07a71"
version = "0.57.5"

[[GR_jll]]
deps = ["Artifacts", "Bzip2_jll", "Cairo_jll", "FFMPEG_jll", "Fontconfig_jll", "GLFW_jll", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Libtiff_jll", "Pixman_jll", "Pkg", "Qt5Base_jll", "Zlib_jll", "libpng_jll"]
git-tree-sha1 = "e14907859a1d3aee73a019e7b3c98e9e7b8b5b3e"
uuid = "d2c73de3-f751-5644-a686-071e5b155ba9"
version = "0.57.3+0"

[[GeometryBasics]]
deps = ["EarCut_jll", "IterTools", "LinearAlgebra", "StaticArrays", "StructArrays", "Tables"]
git-tree-sha1 = "15ff9a14b9e1218958d3530cc288cf31465d9ae2"
uuid = "5c1252a2-5f33-56bf-86c9-59e7332b4326"
version = "0.3.13"

[[Gettext_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Pkg", "XML2_jll"]
git-tree-sha1 = "8c14294a079216000a0bdca5ec5a447f073ddc9d"
uuid = "78b55507-aeef-58d4-861c-77aaff3498b1"
version = "0.20.1+7"

[[Glib_jll]]
deps = ["Artifacts", "Gettext_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Libiconv_jll", "Libmount_jll", "PCRE_jll", "Pkg", "Zlib_jll"]
git-tree-sha1 = "04690cc5008b38ecbdfede949220bc7d9ba26397"
uuid = "7746bdde-850d-59dc-9ae8-88ece973131d"
version = "2.59.0+4"

[[Grisu]]
git-tree-sha1 = "53bb909d1151e57e2484c3d1b53e19552b887fb2"
uuid = "42e2da0e-8278-4e71-bc24-59509adca0fe"
version = "1.0.2"

[[HTTP]]
deps = ["Base64", "Dates", "IniFile", "Logging", "MbedTLS", "NetworkOptions", "Sockets", "URIs"]
git-tree-sha1 = "c6a1fff2fd4b1da29d3dccaffb1e1001244d844e"
uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3"
version = "0.9.12"

[[IniFile]]
deps = ["Test"]
git-tree-sha1 = "098e4d2c533924c921f9f9847274f2ad89e018b8"
uuid = "83e8ac13-25f8-5344-8a64-a9f2b223428f"
version = "0.5.0"

[[InteractiveUtils]]
deps = ["Markdown"]
uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240"

[[InvertedIndices]]
deps = ["Test"]
git-tree-sha1 = "15732c475062348b0165684ffe28e85ea8396afc"
uuid = "41ab1584-1d38-5bbf-9106-f11c6c58b48f"
version = "1.0.0"

[[IterTools]]
git-tree-sha1 = "05110a2ab1fc5f932622ffea2a003221f4782c18"
uuid = "c8e1da08-722c-5040-9ed9-7db0dc04731e"
version = "1.3.0"

[[IteratorInterfaceExtensions]]
git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856"
uuid = "82899510-4779-5014-852e-03e436cf321d"
version = "1.0.0"

[[JLLWrappers]]
deps = ["Preferences"]
git-tree-sha1 = "642a199af8b68253517b80bd3bfd17eb4e84df6e"
uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210"
version = "1.3.0"

[[JSON]]
deps = ["Dates", "Mmap", "Parsers", "Unicode"]
git-tree-sha1 = "81690084b6198a2e1da36fcfda16eeca9f9f24e4"
uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
version = "0.21.1"

[[JpegTurbo_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "9aff0587d9603ea0de2c6f6300d9f9492bbefbd3"
uuid = "aacddb02-875f-59d6-b918-886e6ef4fbf8"
version = "2.0.1+3"

[[LAME_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "df381151e871f41ee86cee4f5f6fd598b8a68826"
uuid = "c1c5ebd0-6772-5130-a774-d5fcae4a789d"
version = "3.100.0+3"

[[LZO_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "f128cd6cd05ffd6d3df0523ed99b90ff6f9b349a"
uuid = "dd4b983a-f0e5-5f8d-a1b7-129d4a5fb1ac"
version = "2.10.0+3"

[[LaTeXStrings]]
git-tree-sha1 = "c7f1c695e06c01b95a67f0cd1d34994f3e7db104"
uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f"
version = "1.2.1"

[[Latexify]]
deps = ["Formatting", "InteractiveUtils", "LaTeXStrings", "MacroTools", "Markdown", "Printf", "Requires"]
git-tree-sha1 = "a4b12a1bd2ebade87891ab7e36fdbce582301a92"
uuid = "23fbe1c1-3f47-55db-b15f-69d7ec21a316"
version = "0.15.6"

[[LibGit2]]
deps = ["Printf"]
uuid = "76f85450-5226-5b5a-8eaa-529ad045b433"

[[LibVPX_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "85fcc80c3052be96619affa2fe2e6d2da3908e11"
uuid = "dd192d2f-8180-539f-9fb4-cc70b1dcf69a"
version = "1.9.0+1"

[[Libdl]]
uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb"

[[Libffi_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "a2cd088a88c0d37eef7d209fd3d8712febce0d90"
uuid = "e9f186c6-92d2-5b65-8a66-fee21dc1b490"
version = "3.2.1+4"

[[Libgcrypt_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgpg_error_jll", "Pkg"]
git-tree-sha1 = "b391a18ab1170a2e568f9fb8d83bc7c780cb9999"
uuid = "d4300ac3-e22c-5743-9152-c294e39db1e4"
version = "1.8.5+4"

[[Libglvnd_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll", "Xorg_libXext_jll"]
git-tree-sha1 = "7739f837d6447403596a75d19ed01fd08d6f56bf"
uuid = "7e76a0d4-f3c7-5321-8279-8d96eeed0f29"
version = "1.3.0+3"

[[Libgpg_error_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "ec7f2e8ad5c9fa99fc773376cdbc86d9a5a23cb7"
uuid = "7add5ba3-2f88-524e-9cd5-f83b8a55f7b8"
version = "1.36.0+3"

[[Libiconv_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "cba7b560fcc00f8cd770fa85a498cbc1d63ff618"
uuid = "94ce4f54-9a6c-5748-9c1c-f9c7231a4531"
version = "1.16.0+8"

[[Libmount_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "51ad0c01c94c1ce48d5cad629425035ad030bfd5"
uuid = "4b2f31a3-9ecc-558c-b454-b3730dcb73e9"
version = "2.34.0+3"

[[Libtiff_jll]]
deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Pkg", "Zlib_jll", "Zstd_jll"]
git-tree-sha1 = "291dd857901f94d683973cdf679984cdf73b56d0"
uuid = "89763e89-9b03-5906-acba-b20f662cd828"
version = "4.1.0+2"

[[Libuuid_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "f879ae9edbaa2c74c922e8b85bb83cc84ea1450b"
uuid = "38a345b3-de98-5d2b-a5d3-14cd9215e700"
version = "2.34.0+7"

[[LinearAlgebra]]
deps = ["Libdl"]
uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"

[[Logging]]
uuid = "56ddb016-857b-54e1-b83d-db4d58db5568"

[[MacroTools]]
deps = ["Markdown", "Random"]
git-tree-sha1 = "6a8a2a625ab0dea913aba95c11370589e0239ff0"
uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09"
version = "0.5.6"

[[Markdown]]
deps = ["Base64"]
uuid = "d6f4376e-aef5-505a-96c1-9c027394607a"

[[MbedTLS]]
deps = ["Dates", "MbedTLS_jll", "Random", "Sockets"]
git-tree-sha1 = "1c38e51c3d08ef2278062ebceade0e46cefc96fe"
uuid = "739be429-bea8-5141-9913-cc70e7f3736d"
version = "1.0.3"

[[MbedTLS_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "0eef589dd1c26a3ac9d753fe1a8bcad63f956fa6"
uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1"
version = "2.16.8+1"

[[Measures]]
git-tree-sha1 = "e498ddeee6f9fdb4551ce855a46f54dbd900245f"
uuid = "442fdcdd-2543-5da2-b0f3-8c86c306513e"
version = "0.3.1"

[[Missings]]
deps = ["DataAPI"]
git-tree-sha1 = "4ea90bd5d3985ae1f9a908bd4500ae88921c5ce7"
uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28"
version = "1.0.0"

[[Mmap]]
uuid = "a63ad114-7e13-5084-954f-fe012c677804"

[[NaNMath]]
git-tree-sha1 = "bfe47e760d60b82b66b61d2d44128b62e3a369fb"
uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3"
version = "0.3.5"

[[NetworkOptions]]
git-tree-sha1 = "ed3157f48a05543cce9b241e1f2815f7e843d96e"
uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908"
version = "1.2.0"

[[Ogg_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "a42c0f138b9ebe8b58eba2271c5053773bde52d0"
uuid = "e7412a2a-1a6e-54c0-be00-318e2571c051"
version = "1.3.4+2"

[[OpenSSL_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "71bbbc616a1d710879f5a1021bcba65ffba6ce58"
uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95"
version = "1.1.1+6"

[[Opus_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "f9d57f4126c39565e05a2b0264df99f497fc6f37"
uuid = "91d4177d-7536-5919-b921-800302f37372"
version = "1.3.1+3"

[[OrderedCollections]]
git-tree-sha1 = "85f8e6578bf1f9ee0d11e7bb1b1456435479d47c"
uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d"
version = "1.4.1"

[[PCRE_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "1b556ad51dceefdbf30e86ffa8f528b73c7df2bb"
uuid = "2f80f16e-611a-54ab-bc61-aa92de5b98fc"
version = "8.42.0+4"

[[Parsers]]
deps = ["Dates"]
git-tree-sha1 = "c8abc88faa3f7a3950832ac5d6e690881590d6dc"
uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0"
version = "1.1.0"

[[Pixman_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "6a20a83c1ae86416f0a5de605eaea08a552844a3"
uuid = "30392449-352a-5448-841d-b1acce4e97dc"
version = "0.40.0+0"

[[Pkg]]
deps = ["Dates", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "UUIDs"]
uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"

[[PlotThemes]]
deps = ["PlotUtils", "Requires", "Statistics"]
git-tree-sha1 = "a3a964ce9dc7898193536002a6dd892b1b5a6f1d"
uuid = "ccf2f8ad-2431-5c83-bf29-c5338b663b6a"
version = "2.0.1"

[[PlotUtils]]
deps = ["ColorSchemes", "Colors", "Dates", "Printf", "Random", "Reexport", "Statistics"]
git-tree-sha1 = "501c20a63a34ac1d015d5304da0e645f42d91c9f"
uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043"
version = "1.0.11"

[[Plots]]
deps = ["Base64", "Contour", "Dates", "FFMPEG", "FixedPointNumbers", "GR", "GeometryBasics", "JSON", "Latexify", "LinearAlgebra", "Measures", "NaNMath", "PlotThemes", "PlotUtils", "Printf", "REPL", "Random", "RecipesBase", "RecipesPipeline", "Reexport", "Requires", "Scratch", "Showoff", "SparseArrays", "Statistics", "StatsBase", "UUIDs"]
git-tree-sha1 = "b93181645c1209d912d5632ba2d0094bc00703ad"
uuid = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
version = "1.18.1"

[[PooledArrays]]
deps = ["DataAPI", "Future"]
git-tree-sha1 = "cde4ce9d6f33219465b55162811d8de8139c0414"
uuid = "2dfb63ee-cc39-5dd5-95bd-886bf059d720"
version = "1.2.1"

[[Preferences]]
deps = ["TOML"]
git-tree-sha1 = "00cfd92944ca9c760982747e9a1d0d5d86ab1e5a"
uuid = "21216c6a-2e73-6563-6e65-726566657250"
version = "1.2.2"

[[PrettyTables]]
deps = ["Crayons", "Formatting", "Markdown", "Reexport", "Tables"]
git-tree-sha1 = "0d1245a357cc61c8cd61934c07447aa569ff22e6"
uuid = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d"
version = "1.1.0"

[[Printf]]
deps = ["Unicode"]
uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7"

[[Qt5Base_jll]]
deps = ["Artifacts", "CompilerSupportLibraries_jll", "Fontconfig_jll", "Glib_jll", "JLLWrappers", "Libdl", "Libglvnd_jll", "OpenSSL_jll", "Pkg", "Xorg_libXext_jll", "Xorg_libxcb_jll", "Xorg_xcb_util_image_jll", "Xorg_xcb_util_keysyms_jll", "Xorg_xcb_util_renderutil_jll", "Xorg_xcb_util_wm_jll", "Zlib_jll", "xkbcommon_jll"]
git-tree-sha1 = "16626cfabbf7206d60d84f2bf4725af7b37d4a77"
uuid = "ea2cea3b-5b76-57ae-a6ef-0a8af62496e1"
version = "5.15.2+0"

[[REPL]]
deps = ["InteractiveUtils", "Markdown", "Sockets"]
uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb"

[[Random]]
deps = ["Serialization"]
uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"

[[RecipesBase]]
git-tree-sha1 = "b3fb709f3c97bfc6e948be68beeecb55a0b340ae"
uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01"
version = "1.1.1"

[[RecipesPipeline]]
deps = ["Dates", "NaNMath", "PlotUtils", "RecipesBase"]
git-tree-sha1 = "2a7a2469ed5d94a98dea0e85c46fa653d76be0cd"
uuid = "01d81517-befc-4cb6-b9ec-a95719d0359c"
version = "0.3.4"

[[Reexport]]
git-tree-sha1 = "5f6c21241f0f655da3952fd60aa18477cf96c220"
uuid = "189a3867-3050-52da-a836-e630ba90ab69"
version = "1.1.0"

[[Requires]]
deps = ["UUIDs"]
git-tree-sha1 = "4036a3bd08ac7e968e27c203d45f5fff15020621"
uuid = "ae029012-a4dd-5104-9daa-d747884805df"
version = "1.1.3"

[[SHA]]
uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce"

[[Scratch]]
deps = ["Dates"]
git-tree-sha1 = "0b4b7f1393cff97c33891da2a0bf69c6ed241fda"
uuid = "6c6a2e73-6563-6170-7368-637461726353"
version = "1.1.0"

[[SentinelArrays]]
deps = ["Dates", "Random"]
git-tree-sha1 = "ffae887d0f0222a19c406a11c3831776d1383e3d"
uuid = "91c51154-3ec4-41a3-a24f-3f23e20d615c"
version = "1.3.3"

[[Serialization]]
uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b"

[[SharedArrays]]
deps = ["Distributed", "Mmap", "Random", "Serialization"]
uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383"

[[Showoff]]
deps = ["Dates", "Grisu"]
git-tree-sha1 = "91eddf657aca81df9ae6ceb20b959ae5653ad1de"
uuid = "992d4aef-0814-514b-bc4d-f2e9a6c4116f"
version = "1.0.3"

[[Sockets]]
uuid = "6462fe0b-24de-5631-8697-dd941f90decc"

[[SortingAlgorithms]]
deps = ["DataStructures"]
git-tree-sha1 = "b3363d7460f7d098ca0912c69b082f75625d7508"
uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c"
version = "1.0.1"

[[SparseArrays]]
deps = ["LinearAlgebra", "Random"]
uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"

[[StaticArrays]]
deps = ["LinearAlgebra", "Random", "Statistics"]
git-tree-sha1 = "896d55218776ab8f23fb7b222a5a4a946d4aafc2"
uuid = "90137ffa-7385-5640-81b9-e52037218182"
version = "1.2.5"

[[Statistics]]
deps = ["LinearAlgebra", "SparseArrays"]
uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"

[[StatsAPI]]
git-tree-sha1 = "1958272568dc176a1d881acb797beb909c785510"
uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0"
version = "1.0.0"

[[StatsBase]]
deps = ["DataAPI", "DataStructures", "LinearAlgebra", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"]
git-tree-sha1 = "2f6792d523d7448bbe2fec99eca9218f06cc746d"
uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"
version = "0.33.8"

[[StructArrays]]
deps = ["Adapt", "DataAPI", "StaticArrays", "Tables"]
git-tree-sha1 = "000e168f5cc9aded17b6999a560b7c11dda69095"
uuid = "09ab397b-f2b6-538f-b94a-2f83cf4a842a"
version = "0.6.0"

[[TOML]]
deps = ["Dates"]
git-tree-sha1 = "44aaac2d2aec4a850302f9aa69127c74f0c3787e"
uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76"
version = "1.0.3"

[[TableTraits]]
deps = ["IteratorInterfaceExtensions"]
git-tree-sha1 = "c06b2f539df1c6efa794486abfb6ed2022561a39"
uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c"
version = "1.0.1"

[[Tables]]
deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "LinearAlgebra", "TableTraits", "Test"]
git-tree-sha1 = "8ed4a3ea724dac32670b062be3ef1c1de6773ae8"
uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c"
version = "1.4.4"

[[Test]]
deps = ["Distributed", "InteractiveUtils", "Logging", "Random"]
uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[[URIs]]
git-tree-sha1 = "97bbe755a53fe859669cd907f2d96aee8d2c1355"
uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4"
version = "1.3.0"

[[UUIDs]]
deps = ["Random", "SHA"]
uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"

[[Unicode]]
uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5"

[[Wayland_jll]]
deps = ["Artifacts", "Expat_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Pkg", "XML2_jll"]
git-tree-sha1 = "dc643a9b774da1c2781413fd7b6dcd2c56bb8056"
uuid = "a2964d1f-97da-50d4-b82a-358c7fce9d89"
version = "1.17.0+4"

[[Wayland_protocols_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Wayland_jll"]
git-tree-sha1 = "2839f1c1296940218e35df0bbb220f2a79686670"
uuid = "2381bf8a-dfd0-557d-9999-79630e7b1b91"
version = "1.18.0+4"

[[XML2_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Pkg", "Zlib_jll"]
git-tree-sha1 = "be0db24f70aae7e2b89f2f3092e93b8606d659a6"
uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a"
version = "2.9.10+3"

[[XSLT_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgcrypt_jll", "Libgpg_error_jll", "Pkg", "XML2_jll"]
git-tree-sha1 = "2b3eac39df218762d2d005702d601cd44c997497"
uuid = "aed1982a-8fda-507f-9586-7b0439959a61"
version = "1.1.33+4"

[[Xorg_libX11_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libxcb_jll", "Xorg_xtrans_jll"]
git-tree-sha1 = "5be649d550f3f4b95308bf0183b82e2582876527"
uuid = "4f6342f7-b3d2-589e-9d20-edeb45f2b2bc"
version = "1.6.9+4"

[[Xorg_libXau_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "4e490d5c960c314f33885790ed410ff3a94ce67e"
uuid = "0c0b7dd1-d40b-584c-a123-a41640f87eec"
version = "1.0.9+4"

[[Xorg_libXcursor_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXfixes_jll", "Xorg_libXrender_jll"]
git-tree-sha1 = "12e0eb3bc634fa2080c1c37fccf56f7c22989afd"
uuid = "935fb764-8cf2-53bf-bb30-45bb1f8bf724"
version = "1.2.0+4"

[[Xorg_libXdmcp_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "4fe47bd2247248125c428978740e18a681372dd4"
uuid = "a3789734-cfe1-5b06-b2d0-1dd0d9d62d05"
version = "1.1.3+4"

[[Xorg_libXext_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"]
git-tree-sha1 = "b7c0aa8c376b31e4852b360222848637f481f8c3"
uuid = "1082639a-0dae-5f34-9b06-72781eeb8cb3"
version = "1.3.4+4"

[[Xorg_libXfixes_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"]
git-tree-sha1 = "0e0dc7431e7a0587559f9294aeec269471c991a4"
uuid = "d091e8ba-531a-589c-9de9-94069b037ed8"
version = "5.0.3+4"

[[Xorg_libXi_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXext_jll", "Xorg_libXfixes_jll"]
git-tree-sha1 = "89b52bc2160aadc84d707093930ef0bffa641246"
uuid = "a51aa0fd-4e3c-5386-b890-e753decda492"
version = "1.7.10+4"

[[Xorg_libXinerama_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXext_jll"]
git-tree-sha1 = "26be8b1c342929259317d8b9f7b53bf2bb73b123"
uuid = "d1454406-59df-5ea1-beac-c340f2130bc3"
version = "1.1.4+4"

[[Xorg_libXrandr_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXext_jll", "Xorg_libXrender_jll"]
git-tree-sha1 = "34cea83cb726fb58f325887bf0612c6b3fb17631"
uuid = "ec84b674-ba8e-5d96-8ba1-2a689ba10484"
version = "1.5.2+4"

[[Xorg_libXrender_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"]
git-tree-sha1 = "19560f30fd49f4d4efbe7002a1037f8c43d43b96"
uuid = "ea2f1a96-1ddc-540d-b46f-429655e07cfa"
version = "0.9.10+4"

[[Xorg_libpthread_stubs_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "6783737e45d3c59a4a4c4091f5f88cdcf0908cbb"
uuid = "14d82f49-176c-5ed1-bb49-ad3f5cbd8c74"
version = "0.1.0+3"

[[Xorg_libxcb_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "XSLT_jll", "Xorg_libXau_jll", "Xorg_libXdmcp_jll", "Xorg_libpthread_stubs_jll"]
git-tree-sha1 = "daf17f441228e7a3833846cd048892861cff16d6"
uuid = "c7cfdc94-dc32-55de-ac96-5a1b8d977c5b"
version = "1.13.0+3"

[[Xorg_libxkbfile_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"]
git-tree-sha1 = "926af861744212db0eb001d9e40b5d16292080b2"
uuid = "cc61e674-0454-545c-8b26-ed2c68acab7a"
version = "1.1.0+4"

[[Xorg_xcb_util_image_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_xcb_util_jll"]
git-tree-sha1 = "0fab0a40349ba1cba2c1da699243396ff8e94b97"
uuid = "12413925-8142-5f55-bb0e-6d7ca50bb09b"
version = "0.4.0+1"

[[Xorg_xcb_util_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libxcb_jll"]
git-tree-sha1 = "e7fd7b2881fa2eaa72717420894d3938177862d1"
uuid = "2def613f-5ad1-5310-b15b-b15d46f528f5"
version = "0.4.0+1"

[[Xorg_xcb_util_keysyms_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_xcb_util_jll"]
git-tree-sha1 = "d1151e2c45a544f32441a567d1690e701ec89b00"
uuid = "975044d2-76e6-5fbe-bf08-97ce7c6574c7"
version = "0.4.0+1"

[[Xorg_xcb_util_renderutil_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_xcb_util_jll"]
git-tree-sha1 = "dfd7a8f38d4613b6a575253b3174dd991ca6183e"
uuid = "0d47668e-0667-5a69-a72c-f761630bfb7e"
version = "0.3.9+1"

[[Xorg_xcb_util_wm_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_xcb_util_jll"]
git-tree-sha1 = "e78d10aab01a4a154142c5006ed44fd9e8e31b67"
uuid = "c22f9ab0-d5fe-5066-847c-f4bb1cd4e361"
version = "0.4.1+1"

[[Xorg_xkbcomp_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libxkbfile_jll"]
git-tree-sha1 = "4bcbf660f6c2e714f87e960a171b119d06ee163b"
uuid = "35661453-b289-5fab-8a00-3d9160c6a3a4"
version = "1.4.2+4"

[[Xorg_xkeyboard_config_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_xkbcomp_jll"]
git-tree-sha1 = "5c8424f8a67c3f2209646d4425f3d415fee5931d"
uuid = "33bec58e-1273-512f-9401-5d533626f822"
version = "2.27.0+4"

[[Xorg_xtrans_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "79c31e7844f6ecf779705fbc12146eb190b7d845"
uuid = "c5fb5394-a638-5e4d-96e5-b29de1b5cf10"
version = "1.4.0+3"

[[Zlib_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "320228915c8debb12cb434c59057290f0834dbf6"
uuid = "83775a58-1f1d-513f-b197-d71354ab007a"
version = "1.2.11+18"

[[Zstd_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "2c1332c54931e83f8f94d310fa447fd743e8d600"
uuid = "3161d3a3-bdf6-5164-811a-617609db77b4"
version = "1.4.8+0"

[[libass_jll]]
deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"]
git-tree-sha1 = "acc685bcf777b2202a904cdcb49ad34c2fa1880c"
uuid = "0ac62f75-1d6f-5e53-bd7c-93b484bb37c0"
version = "0.14.0+4"

[[libfdk_aac_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "7a5780a0d9c6864184b3a2eeeb833a0c871f00ab"
uuid = "f638f0a6-7fb0-5443-88ba-1cc74229b280"
version = "0.1.6+4"

[[libpng_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"]
git-tree-sha1 = "6abbc424248097d69c0c87ba50fcb0753f93e0ee"
uuid = "b53b4c65-9356-5827-b1ea-8c7a1a84506f"
version = "1.6.37+6"

[[libvorbis_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Ogg_jll", "Pkg"]
git-tree-sha1 = "fa14ac25af7a4b8a7f61b287a124df7aab601bcd"
uuid = "f27f6e37-5d2b-51aa-960f-b287f2bc3b7a"
version = "1.3.6+6"

[[x264_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "d713c1ce4deac133e3334ee12f4adff07f81778f"
uuid = "1270edf5-f2f9-52d2-97e9-ab00b5d0237a"
version = "2020.7.14+2"

[[x265_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "487da2f8f2f0c8ee0e83f39d13037d6bbf0a45ab"
uuid = "dfaa095f-4041-5dcd-9319-2fabd8486b76"
version = "3.0.0+3"

[[xkbcommon_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Wayland_jll", "Wayland_protocols_jll", "Xorg_libxcb_jll", "Xorg_xkeyboard_config_jll"]
git-tree-sha1 = "ece2350174195bb31de1a63bea3a41ae1aa593b6"
uuid = "d8fb68d0-12a3-5cfd-a85a-d49703b185fd"
version = "0.9.1+5"
"""

# ╔═╡ Cell order:
# ╟─0255a190-df31-11eb-2591-09600ea47d50
# ╟─369b8ad0-387f-4509-afe3-03e5bf79ddb8
# ╟─90714396-cbc5-4c42-8853-4da1c83674fd
# ╠═93f57edd-4d2b-41fd-ba6e-2d84a24b7585
# ╠═b30b23d8-ee53-4927-8215-a725a50105d1
# ╠═454845db-90ad-4236-b038-0bc6f8c9fcc2
# ╠═3b96c692-d6a2-46dc-8469-c2b1dbc9ae28
# ╠═ee61b590-56e1-4379-9cf0-58d27affdf1e
# ╠═df41fba9-b24b-485b-a4b5-b3bcd1f69485
# ╠═6cf78f5d-7eda-4abd-9281-3269e077b48a
# ╠═f044ac30-60d8-4ebe-8048-463ba4b8bebd
# ╠═724e9305-48a8-41ef-88c1-f7f4f2b6e346
# ╟─00000000-0000-0000-0000-000000000001
# ╟─00000000-0000-0000-0000-000000000002


text:
# Automatically generated using Clang.jl

# Skipping MacroDefinition: SODIUM_EXPORT __attribute__ ( ( visibility ( "default" ) ) )
# Skipping MacroDefinition: SODIUM_EXPORT_WEAK SODIUM_EXPORT __attribute__ ( ( weak ) )
# Skipping MacroDefinition: CRYPTO_ALIGN ( x ) __attribute__ ( ( aligned ( x ) ) )
# Skipping MacroDefinition: SODIUM_MIN ( A , B ) ( ( A ) < ( B ) ? ( A ) : ( B ) )
# Skipping MacroDefinition: SODIUM_SIZE_MAX SODIUM_MIN ( UINT64_MAX , SIZE_MAX )

const crypto_hash_sha512_BYTES = UInt32(64)

struct crypto_hash_sha512_state
    state::NTuple{8, UInt64}
    count::NTuple{2, UInt64}
    buf::NTuple{128, UInt8}
end

const crypto_sign_ed25519_BYTES = UInt32(64)
const crypto_sign_ed25519_SEEDBYTES = UInt32(32)
const crypto_sign_ed25519_PUBLICKEYBYTES = UInt32(32)
const crypto_sign_ed25519_SECRETKEYBYTES = UInt32(32) + UInt32(32)

struct crypto_sign_ed25519ph_state
    hs::crypto_hash_sha512_state
end


text:
using TriangleIntersect
using Base.Test

a = Point(0,0,0)
b = Point(1,0,0)
c = Point(0,1,0)
t = Triangle(a,b,c)
r = Ray(Point(0.1,0.1,1), Point(0.1,0.1,-1))

@test intersect(r, t) == Intersection(Point(0.2,0.2,0.0), 1.02, true)

# yeah, more tests are needed :)