text:
using RvSpectMLBase
import EchelleInstruments
import EchelleInstruments: EXPRES
#using EchelleCCFs
using Experimental
#using DataFrames, Query
using Stheno, TemporalGPs
using Statistics
using Optim

all_spectra = include(joinpath(pkgdir(EchelleInstruments),"examples/read_expres_data_101501.jl"))

order_list_timeseries = extract_orders(all_spectra,pipeline_plan, recalc=true )

function calc_logλ_grid(chunklist_timeseries, obs_idx, obs_jdx, chunk_idx; sample_scale_factor::Real = 1, Δv::Real = 0, skip_edge_pixels::Integer = 100)
	@assert 1+skip_edge_pixels < length(chunklist_timeseries[obs_idx][chunk_idx].λ)-skip_edge_pixels

	minlogλ = log( max(chunklist_timeseries[obs_idx][chunk_idx].λ[1+skip_edge_pixels], chunklist_timeseries[obs_jdx][chunk_idx].λ[1+skip_edge_pixels] ))
	maxlogλ = log( min(chunklist_timeseries[obs_idx][chunk_idx].λ[end-skip_edge_pixels], chunklist_timeseries[obs_jdx][chunk_idx].λ[end-skip_edge_pixels] ))
	logλ_grid = range(minlogλ, stop=maxlogλ, length = 1+2*(ceil(Int,sample_scale_factor*length(chunklist_timeseries[obs_idx][chunk_idx].λ)//2)-skip_edge_pixels) )
end

function calc_logλ_grid_all_pairs(chunklist_timeseries, chunk_idx; sample_scale_factor::Real = 1, Δv::Real = 0, skip_edge_pixels::Integer = 100)
	@assert 1+skip_edge_pixels < length(chunklist_timeseries[1][chunk_idx].λ)-skip_edge_pixels

	minlogλ = log( maximum(map(obs_idx->chunklist_timeseries[obs_idx][chunk_idx].λ[1+skip_edge_pixels], 1:length(chunklist_timeseries)) ))
	maxlogλ = log( minimum(map(obs_idx->chunklist_timeseries[obs_idx][chunk_idx].λ[end-skip_edge_pixels], 1:length(chunklist_timeseries)) ))
	logλ_grid = range(minlogλ, stop=maxlogλ, length = 1+2*(ceil(Int,sample_scale_factor*length(chunklist_timeseries[1][chunk_idx].λ)//2)-skip_edge_pixels) )
end

function calc_cross_cor_obs_chunklist(chunklist_timeseries, obs_idx, obs_jdx, chunk_idx; sample_scale_factor::Real = 1, Δv::Real = 0, skip_edge_pixels::Integer = 100)
	logλ_grid = calc_logλ_grid(chunklist_timeseries, obs_idx, obs_jdx, chunk_idx, sample_scale_factor=sample_scale_factor, Δv=Δv, skip_edge_pixels=skip_edge_pixels )
	Δlogλ = log(RvSpectMLBase.calc_doppler_factor(Δv))
	(pixels, order) = chunklist_timeseries[obs_idx][chunk_idx].flux.indices
	blaze = chunklist_timeseries.metadata[obs_idx][:blaze][pixels,order]
	pred_spec1 = Experimental.TemporalGPInterpolation.predict_mean( log.(chunklist_timeseries[obs_idx][chunk_idx].λ).+0.5*Δlogλ,
										chunklist_timeseries[obs_idx][chunk_idx].flux ./ blaze,
										logλ_grid, sigmasq_obs=chunklist_timeseries[obs_idx][chunk_idx].var ./ blaze.^2,
										use_logx = false, use_logy = false, smooth_factor = 1)
	(pixels, order) = chunklist_timeseries[obs_jdx][chunk_idx].flux.indices
	blaze = chunklist_timeseries.metadata[obs_jdx][:blaze][pixels,order]
	pred_spec2 = Experimental.TemporalGPInterpolation.predict_mean( log.(chunklist_timeseries[obs_jdx][chunk_idx].λ).-0.5*Δlogλ,
										chunklist_timeseries[obs_jdx][chunk_idx].flux ./ blaze,
										logλ_grid, sigmasq_obs=chunklist_timeseries[obs_jdx][chunk_idx].var ./ blaze.^2,
										use_logx = false, use_logy = false, smooth_factor = 1)
	scale_factor = mean(pred_spec1)/mean(pred_spec2)
	result = mean( (pred_spec1 .- scale_factor.*pred_spec2 ).^2 )
	return result
end

function calc_cross_cor_obs_chunklist_alt(chunklist_timeseries, obs_idx, obs_jdx, chunk_idx; sample_scale_factor::Real = 1, Δv::Real = 0, skip_edge_pixels::Integer = 100)
	logλ_grid = calc_logλ_grid(chunklist_timeseries, obs_idx, obs_jdx, chunk_idx, sample_scale_factor=sample_scale_factor, Δv=Δv, skip_edge_pixels=skip_edge_pixels )
	Δlogλ = log(RvSpectMLBase.calc_doppler_factor(Δv))
	(pixels, order) = chunklist_timeseries[obs_idx][chunk_idx].flux.indices
	blaze = chunklist_timeseries.metadata[obs_idx][:blaze][pixels,order]
	spec1_gp = TemporalGPInterpolation.construct_gp_posterior( log.(chunklist_timeseries[obs_idx][chunk_idx].λ).+0.5*Δlogλ,
										chunklist_timeseries[obs_idx][chunk_idx].flux ./ blaze,
										logλ_grid, sigmasq_obs=chunklist_timeseries[obs_idx][chunk_idx].var ./ blaze.^2,
										use_logx = false, use_logy = false, smooth_factor = 1)
	marginal_gp1 = marginals(spec1_gp(logλ_grid))
	(pixels, order) = chunklist_timeseries[obs_jdx][chunk_idx].flux.indices
	blaze = chunklist_timeseries.metadata[obs_jdx][:blaze][pixels,order]
	spec2_gp = TemporalGPInterpolation.construct_gp_posterior( log.(chunklist_timeseries[obs_jdx][chunk_idx].λ).-0.5*Δlogλ,
										chunklist_timeseries[obs_jdx][chunk_idx].flux ./ blaze,
										logλ_grid, sigmasq_obs=chunklist_timeseries[obs_jdx][chunk_idx].var ./ blaze.^2,
										use_logx = false, use_logy = false, smooth_factor = 1)
	marginal_gp2 = marginals(spec2_gp(logλ_grid))
	#scale_factor = mean(pred_spec1)/mean(pred_spec2)
	scale_factor = mean(mean.(marginal_gp1)./mean.(marginal_gp2))
	mean_diff = (mean.(marginal_gp1) .- scale_factor .* mean.(marginal_gp2))
	var_diff = (var.(marginal_gp1) .+ scale_factor .* var.(marginal_gp2))
	result = mean(mean_diff.^2 ./ var_diff)
end

function calc_cross_cor_obs_chunklist_all_pairs(chunklist_timeseries, chunk_idx; sample_scale_factor::Real = 1, Δv::Real = 0, skip_edge_pixels::Integer = 100, max_num_obs::Integer = 0)
	logλ_grid = calc_logλ_grid_all_pairs(chunklist_timeseries, chunk_idx, sample_scale_factor=sample_scale_factor, Δv=Δv, skip_edge_pixels=skip_edge_pixels )
	num_obs = max_num_obs > 0 ? max_num_obs : length(chunklist_timeseries)
	spec_gps = Any[]
	for obs_idx in 1:num_obs
		(pixels, order) = chunklist_timeseries[obs_idx][chunk_idx].flux.indices
		blaze = chunklist_timeseries.metadata[obs_idx][:blaze][pixels,order]
		spec1_gp = Experimental.TemporalGPInterpolation.construct_gp_posterior( log.(chunklist_timeseries[obs_idx][chunk_idx].λ),
										chunklist_timeseries[obs_idx][chunk_idx].flux ./ blaze,
										sigmasq_obs=chunklist_timeseries[obs_idx][chunk_idx].var ./ blaze.^2,
										use_logx = false, smooth_factor = 1)
	   push!(spec_gps,spec1_gp)
   end
   χ² = zeros(num_obs,num_obs)
   Δrv = zeros(num_obs,num_obs)
   σrv = zeros(num_obs,num_obs)
   rv_eps = 0.01
   #logλ_grid = collect(logλ_grid)
   for obs_idx in 1:num_obs
	   #marginal_gp1 = marginals(spec_gps[obs_idx](logλ_grid.-0.5*Δlogλ))
	   marginal_gp1 = marginals(spec_gps[obs_idx](logλ_grid))
	   for obs_jdx in 1:num_obs
		   	if obs_idx == obs_jdx   continue   end
			#marginal_gp2 = marginals(spec_gps[obs_jdx](logλ_grid.+0.5*Δlogλ))
			function func_to_minimize(θ)
				@assert length(θ) == 1
				dv = θ[1]
				Δlogλ = log(RvSpectMLBase.calc_doppler_factor(dv))
				marginal_gp2 = marginals(spec_gps[obs_jdx](logλ_grid.+Δlogλ))
				scale_factor = mean(mean.(marginal_gp1)./mean.(marginal_gp2))
				mean_diff = (mean.(marginal_gp1) .- scale_factor .* mean.(marginal_gp2))
				var_diff = (var.(marginal_gp1) .+ scale_factor .* var.(marginal_gp2))
				chi2 = sum(mean_diff.^2 ./ var_diff)
				return chi2
			end
			#=
			res = optimize(func_to_minimize, [0.0], Newton(), Optim.Options(x_tol=rv_eps) )
			if !Optim.converged(res)
				@warn "optim didn't converged for $obs_idx and $obs_jdx ."
				println(summary(res))
			else
				χ²[obs_idx,obs_jdx] = minimum(res)
				rv_bf = Optim.minimizer(res)[1]
				#dchi2drv = (func_to_minimize(rv_bf+rv_eps)-func_to_minimize(rv_bf-rv_eps))/(2*rv_eps)
				d2chi2drv2 = (func_to_minimize(rv_bf+rv_eps)-2func_to_minimize(rv_bf)+func_to_minimize(rv_bf-rv_eps))/(2*rv_eps)^2
				Δrv[obs_idx,obs_jdx] = rv_bf
				σrv[obs_idx,obs_jdx] = 2.0 /d2chi2drv2
			end
			=#
			rv_bf = 0
			chisq_v0 = func_to_minimize(rv_bf)
			dchi2drv = (func_to_minimize(rv_bf+rv_eps)-func_to_minimize(rv_bf-rv_eps))/(2*rv_eps)
			d2chi2drv2 = (func_to_minimize(rv_bf+rv_eps)-2func_to_minimize(rv_bf)+func_to_minimize(rv_bf-rv_eps))/(2*rv_eps)^2
			v_at_min_of_quadratic = -dchi2drv/(2*d2chi2drv2)
			Δrv[obs_idx,obs_jdx] = v_at_min_of_quadratic
			σrv[obs_idx,obs_jdx] = 2.0 /d2chi2drv2
			χ²[obs_idx,obs_jdx] = func_to_minimize(v_at_min_of_quadratic)
			#=
			marginal_gp2 = marginals(spec_gps[obs_jdx](logλ_grid.+Δlogλ))
			scale_factor = mean(mean.(marginal_gp1)./mean.(marginal_gp2))
			mean_diff = (mean.(marginal_gp1) .- scale_factor .* mean.(marginal_gp2))
			var_diff = (var.(marginal_gp1) .+ scale_factor .* var.(marginal_gp2))
			results[obs_idx,obs_jdx] = sum(mean_diff.^2 ./ var_diff)
			=#
		end
  end
  return (Δrv=Δrv, σrv=σrv, χ²=χ²)
end

function plot_Δ_chunk(chunklist_timeseries, obs_idx, obs_jdx, chunk_idx; sample_scale_factor::Real = 1, Δv::Real = 0, skip_edge_pixels::Integer = 100)
	logλ_grid = calc_logλ_grid(chunklist_timeseries, obs_idx, obs_jdx, chunk_idx, sample_scale_factor=sample_scale_factor, Δv=Δv, skip_edge_pixels=skip_edge_pixels )
	Δlogλ = log(RvSpectMLBase.calc_doppler_factor(Δv))
	(pixels, order) = chunklist_timeseries[obs_idx][chunk_idx].flux.indices
	blaze = chunklist_timeseries.metadata[obs_idx][:blaze][pixels,order]
	pred_spec1 = Experimental.TemporalGPInterpolation.predict_mean( log.(chunklist_timeseries[obs_idx][chunk_idx].λ).+0.5*Δlogλ,
										chunklist_timeseries[obs_idx][chunk_idx].flux ./ blaze,
										logλ_grid, sigmasq_obs=chunklist_timeseries[obs_idx][chunk_idx].var ./ blaze.^2,
										use_logx = false, use_logy = true, smooth_factor = 1)

	(pixels, order) = chunklist_timeseries[obs_jdx][chunk_idx].flux.indices
	blaze = chunklist_timeseries.metadata[obs_jdx][:blaze][pixels,order]
	pred_spec2 = Experimental.TemporalGPInterpolation.predict_mean( log.(chunklist_timeseries[obs_jdx][chunk_idx].λ).-0.5*Δlogλ,
										chunklist_timeseries[obs_jdx][chunk_idx].flux ./ blaze,
										logλ_grid, sigmasq_obs=chunklist_timeseries[obs_jdx][chunk_idx].var  ./ blaze.^2,
										use_logx = false, use_logy = true, smooth_factor = 1)
	result = pred_spec1 .- pred_spec2 .* (mean(pred_spec1)/mean(pred_spec2))
end

using StatsBase
function compute_ave_Δrv_weighted(Δrv::AbstractArray{T1,2}, σ_rv::AbstractArray{T2,2}) where {T1<:Real, T2<:Real}
    @assert size(Δrv) == size(σ_rv)
    n = size(Δrv)[1]
    rv_out = zeros(n)
    weight = zeros(n)
    σ_rv_out = zeros(n)
    for i in 1:n
        wsum = 0.0
        for j in 1:n
            if i==j   continue   end
            weight[j] = 1 / σ_rv[i,j]^2
            #rv_out[i] += Δrv[i,j] * weight[i]
            #wsum += weight[i]
        end
        #rv_out[i] /= wsum
		rv_out[i] = mean(Δrv[:,i], Weights(weight))
        #σ_rv_out[i] = std(Δrv[:,i], Weights(weight), mean=rv_out[i])
		σ_rv_out[i] = std(Δrv[:,i], Weights(weight), mean=rv_out[i])
		println(i,": rv: ", rv_out[i], "  σ_rv: ", σ_rv_out[i] )
    end
    return (rvs=rv_out, σ_rv=σ_rv_out)
end

@time order5_cross_cor_gp_results = calc_cross_cor_obs_chunklist_all_pairs(order_list_timeseries, 5, Δv=0 ) #, max_num_obs =3)
compute_ave_Δrv_weighted(order5_cross_cor_gp_results.Δrv, order5_cross_cor_gp_results.σrv)

using JLD2
using Distributed

num_chunks_fit = num_chunks(order_list_timeseries)
results = pmap(ch-> calc_cross_cor_obs_chunklist_all_pairs(order_list_timeseries, ch, Δv=0), 1:num_chunks_fit)
 order_cross_cor_gp_results = results
 gp_pair_rvs = pmap(ch-> compute_ave_Δrv_weighted(results[ch].Δrv, results[ch].σrv), 1:num_chunks_fit)
 @save "gp_all_pairs_fits.jld2" order_cross_cor_gp_results gp_pair_rvs
 std_of_gp_pair_rvs = map(obsid->std(map(ch->gp_pair_rvs[ch].rvs[obsid], 1:num_chunks_fit) ), 1:length(order_list_timeseries) )
 mean_of_gp_pair_σ_rvs = map(obsid->mean(map(ch->gp_pair_rvs[ch].σ_rv[obsid], 1:num_chunks_fit) ), 1:length(order_list_timeseries) )
 mean_of_gp_pair_rvs = map(obsid->mean(map(ch->gp_pair_rvs[ch].rvs[obsid], 1:num_chunks_fit) ), 1:length(order_list_timeseries) )

scatter(mean_of_gp_pair_rvs)

#=
using Plots
plt = plot()
 logλ_grid = calc_logλ_grid(order_list_timeseries, 5, 6, 5 )
 plot!(exp.(logλ_grid),plot_Δ_chunk(order_list_timeseries, 5, 6, 5, Δv=0))
 plot!(exp.(logλ_grid),plot_Δ_chunk(order_list_timeseries, 5, 6, 5, Δv=100))
 plot!(exp.(logλ_grid),plot_Δ_chunk(order_list_timeseries, 5, 6, 5, Δv=-100))
 xlims!(5360,5370)

plot_Δ_chunk(order_list_timeseries, 5, 6, 5, Δv=0)

Δv_list = range(-10,stop=10,length=51)
 score_list_5 = map(Δv->calc_cross_cor_obs_chunklist(order_list_timeseries, 5, 6, 5, Δv=Δv), Δv_list)
 score_list_6 = map(Δv->calc_cross_cor_obs_chunklist(order_list_timeseries, 5, 6, 6, Δv=Δv), Δv_list)
 score_list_7 = map(Δv->calc_cross_cor_obs_chunklist(order_list_timeseries, 5, 6, 7, Δv=Δv), Δv_list)
 plt = plot()
 plot!(Δv_list, score_list_5./minimum(score_list_5))
 plot!(Δv_list, score_list_6./minimum(score_list_6))
 plot!(Δv_list, score_list_7./minimum(score_list_7))

using Plots

plt = plot()
plot!(exp.(logλ_grid),pred_spec1)
plot!(exp.(logλ_grid),pred_spec2)
display(plt)
=#

using Distributed
using ProgressMeter

num_chunks_fit = 10 # num_chunks(order_list_timeseries)

@time order_cross_cor_gp_results =  @showprogress pmap(order->calc_cross_cor_obs_chunklist_all_pairs(order_list_timeseries, order, Δv=0), 1:num_chunks_fit )
@time gp_pair_rvs = @showprogress pmap(ch->compute_ave_Δrv_weighted(order_cross_cor_gp_results[ch].Δrv,order_cross_cor_gp_results[ch].σrv), 1:num_chunks_fit )

std_of_gp_pair_rvs = map(obsid->std(map(ch->gp_pair_rvs[ch].rvs[obsid], 1:num_chunks_fit) ), 1:length(order_list_timeseries) )
mean_of_gp_pair_rvs = map(obsid->mean(map(ch->gp_pair_rvs[ch].rvs[obsid], 1:num_chunks_fit) ), 1:length(order_list_timeseries) )

using Plots
plt = plot(); map(i->scatter!(plt,gp_pair_rvs[i].rvs, label=:none),1:num_chunks(order_list_timeseries)) ; display(plt)

scatter(std_of_gp_pair_rvs)
scatter(mean_of_gp_pair_rvs)

using JLD2
@save "gp_all_pairs_fits.jld2" order_cross_cor_gp_results


text:
using SparseArrays

"""
Sparse N-mode array.

`vals` contains all (`L`) non-zero elements.
`pos` is `N`x`L` matrix of non-zero elements indices.
`dims` is `NTuple` of array dimensions.
"""
struct SparseArray{T, N} <: AbstractArray{T, N}
    vals::Vector{T}
    pos::Vector{CartesianIndex{N}}
    dims::NTuple{N,Int}
end

Base.size(a::SparseArray) = a.dims
Base.size(a::SparseArray, i::Int) = a.dims[i]
Base.length(a::SparseArray) = prod(a.dims)
SparseArrays.nnz(a::SparseArray) = length(a.vals)

"""
Convert dense N-dimensional array into N-dimensional a `SparseArray`.
"""
function SparseArray{T,N}(arr::DenseArray{T,N}) where {T,N}
    pos = Vector{CartesianIndex{N}}()
    vals = Vector{T}()

    @inbounds for (i, cart) in enumerate(CartesianIndices(arr))
        (arr[i] == 0) && continue
        push!(vals, arr[i])
        push!(pos, cart)
    end

    return SparseArray{T,N}(vals, pos, size(arr))
end

SparseArray(arr::DenseArray{T, N}) where {T, N} = SparseArray{T,N}(arr)

"""
SS-HOPM (Shifted Symmetric Higher-order Power Method)
for computing tensor eigenpars.
"""
function sshopm(tnsr::AbstractArray{T,N},
                alpha::Real;
                tol::Float64=1e-5,
                maxiter::Int=1000,
                verbose::Bool=false) where {T,N}

    r = size(tnsr, 1)
    all(isequal(r), size(tnsr)) || throw(DimensionMismatch("Input tensor should have the same dimension in all modes, got $(size(tnsr))."))
    x = randn(r)
    x .*= 1/norm(x)
    x_old = similar(x)
    converged = false
    niters = 0
    pb = Progress(maxiter, "High-order power iterations ")
    while !converged && niters < maxiter
        update!(pb, niters)

        copyto!(x_old, x)
        x .= flipsign.(nmul(tnsr, x) .+ alpha .* x, alpha)
        x .*= 1/norm(x)
        converged = norm(x .- x_old) < tol
        niters += 1
    end

    verbose && _iter_status(converged, niters, maxiter)
    return (dot(x, nmul(tnsr, x)), flipsign.(x, alpha))
end

# (N-1)-way tensor × vector contraction
function nmul(tnsr::StridedArray{T,N}, x::Vector{T}) where {T, N}
    v = copy(tnsr)
    for i in 2:N
        v = tensorcontract(v, collect(i-1:N), x, N)
    end
    return v
end

# (N-1)-way sparse tensor × vector contraction
function nmul(tnsr::SparseArray{T,N}, x::Vector{T}) where {T, N}
    v = zeros(T, size(tnsr, 1))
    @inbounds for i in 1:nnz(tnsr)
        posi = tnsr.pos[i]
        v[posi[1]] += tnsr.vals[i] * prod(ntuple(k -> x[posi[k+1]], N-1))
    end
    return v
end

ext: jl


text:
struct House <: Item
    address
    city
    country
end

struct Room <: Item
    house::House
end

Base.@kwdef struct Desk <: Item
    top
    main_drawer
    side_drawer_1
    side_drawer_2
    side_drawer_3
    drawers_top
end

struct MainCompartment <: Item end
struct LightSuitcase <: Item end


text:
using FymEnvs
using Plots
ENV["GKSwstype"]="nul"  # do not show plot

function test_f16linearlateral()
    f16 = F16LinearLateral()

    function step(env; action=nothing)
        t = time(env.clock)
        sys = env.systems["f16"]
        x = sys.state
        u = zeros(2)
        update!(env)
        next_obs = sys.state
        reward = zeros(1)
        done = time_over(env.clock)
        info = Dict("time" => t, "state" => x, "input" => u)
        return next_obs, reward, done, info
    end
    function set_dyn(env, t; deriv=f16.deriv)
        sys = env.systems["f16"]
        x = sys.state
        u = zeros(2)
        sys.dot = deriv(x, u)
    end

    systems = Dict("f16" => f16.system)
    env = BaseEnv()
    systems!(env, systems)
    dyn!(env, set_dyn)
    step!(env, step)
    reset!(env)

    log_dir = "data/test"
    file_name = "f16.h5"
    _sample(env, nothing, log_dir, file_name)

    data = load(joinpath(log_dir, file_name))
    @show env
    @show size(data["state"])
    t, x = data["time"], data["state"]
    p = plot(t, x)
    savefig(p, joinpath(log_dir, "f16.pdf"))
end

function test_glidingvehicle3dof()
    gv3 = GlidingVehicle3DOF()

    function step(env; action=nothing)
        t = time(env.clock)
        sys = env.systems["gv3"]
        state = sys.state
        input = zeros(2)
        update!(env)
        next_obs = sys.state
        reward = zeros(1)
        done = time_over(env.clock)
        info = Dict("time" => t, "state" => state, "input" => input)
        return next_obs, reward, done, info
    end
    function set_dyn(env, t; deriv=gv3.deriv)
        sys = env.systems["gv3"]
        state = sys.state
        input = zeros(2)
        sys.dot = deriv(state, input)
    end

    systems = Dict("gv3" => gv3.system)
    env = BaseEnv()
    systems!(env, systems)
    dyn!(env, set_dyn)
    step!(env, step)
    reset!(env)

    log_dir = "data/test"
    file_name = "gv3.h5"
    _sample(env, nothing, log_dir, file_name)

    data = load(joinpath(log_dir, file_name))
    @show env
    @show size(data["state"]), size(data["input"])
    t, x = data["time"], data["state"]
    p = plot(t, x)
    savefig(p, joinpath(log_dir, "gv3.pdf"))
end

function _sample(env, agent, log_dir, file_name)
    logger = Logger(log_dir=log_dir, file_name=file_name, max_len=1000)
    obs = observe_flat(env)
    i = 0
    @time while true
        if agent == nothing
            action = nothing
        end
        next_obs, reward, done, info = env.step(action=action)
        record(logger, info)
        obs = next_obs
        i += 1
        if done
            break
        end
    end
    close!(env)
    close!(logger)
end

test_f16linearlateral()
test_glidingvehicle3dof()


text:
dict = Dict("hello" => 13, "world" => 31, "!" => 71)

# applying a function to key-value pairs:
foreach(println, dict)

# iterating over key-value pairs:
for (key, value) in dict
    println("dict[$key] = $value")
end

# iterating over keys:
for key in keys(dict)
    @show key
end

# iterating over values:
for value in values(dict)
    @show value
end

max_stars_repo_name: ethansaxenian/RosettaDecode

max_issues_repo_name: ethansaxenian/RosettaDecode

max_forks_repo_name: ethansaxenian/RosettaDecode


text:
using Resonance

# - Takes ~ 6min for 1500 samples:
# - Writes to ENV["SCRATCH_SPACE"], which is "./scratch/" unless otherwise set
Resonance.write_gfs_arrow()
Resonance.write_gfs_arrow(; kind="ecs_rename", stratified=true)
Resonance.write_gfs_arrow(; kind="kos_rename", stratified=true)
Resonance.write_gfs_arrow(; kind="pfams_rename", stratified=true)

max_stars_repo_name: Klepac-Ceraj-Lab/ResonanceAnalysis

max_issues_repo_name: Klepac-Ceraj-Lab/ResonanceAnalysis

max_forks_repo_name: Klepac-Ceraj-Lab/ResonanceAnalysis


text:
"""

    constructMolAlpha!(myMolData::OneMol_WithPhonons{FT},
                       myPeriodicData::PeriodicData{FT},
                       freq::Union{FT, Complex{FT}},
                       k::Array{FT, 1}=zeros(FT, 3)) where FT<:AbstractFloat

Construct the inverse molecular susceptibility `myMolData.alphainv` in-place at frequency
`freq` and wavevector `k`, the latter of which must be a 3-element real vector. With
phonons, `myMolData.alphainv` will be a matrix, the vector of atomic polarizabilities
`myMolData.alpha0` will depend on the elements of `myMolData.alphainv`, and
`myMolData.alphae` will be independent of these two. Without phonons, all three will be
simply related to each other.

"""
function constructMolAlpha!(myMolData::OneMol_WithPhonons{FT},
                            myPeriodicData::PeriodicData{FT},
                            freq::Union{FT, Complex{FT}},
                            k::Array{FT, 1}=zeros(FT, 3)) where FT<:AbstractFloat

    Ke3N = vecNto3N(myMolData.Ke);
    Qeinv3N = vecNto3N(1 ./ myMolData.Qe);

    setindex!(myMolData.alphainv, KIk(myMolData, myPeriodicData, k),
              1:3*myMolData.numatoms, 1:3*myMolData.numatoms);
    addtodiag!(myMolData.alphainv,
               Ke3N .- vecNto3N(1im.*freq.*myMolData.BI .+ freq^2 .* myMolData.MI));
    setindex!(myMolData.alphainv, inv(myMolData.alphainv),
              1:3*myMolData.numatoms, 1:3*myMolData.numatoms);
    mulMatDiagright!(myMolData.alphainv, Ke3N);
    mulMatDiagleft!(myMolData.alphainv, Ke3N);
    subtractfromdiag!(myMolData.alphainv,
                      Ke3N .- vecNto3N(1im.*freq.*myMolData.Be .+ freq^2 .* myMolData.Me));
    mulMatDiagright!(myMolData.alphainv, Qeinv3N);
    mulMatDiagleft!(myMolData.alphainv, Qeinv3N);

    alpha = inv(myMolData.alphainv);
    alphacarttr = Array{eltype(alpha), 2}(undef, myMolData.numatoms, myMolData.numatoms);
    @inbounds for qq=1:myMolData.numatoms
        @inbounds for pp=1:myMolData.numatoms
            alphacarttr[pp, qq] = tr(alpha[3*pp-2:3*pp, 3*qq-2:3*qq]);
        end
    end

    setindex!(myMolData.alpha0, abs.(vec(sum(alphacarttr, dims=2))), 1:myMolData.numatoms);
    lmul!(1/3, myMolData.alpha0);
    setindex!(myMolData.alphae,
              myMolData.Qe.^2 ./ (myMolData.Ke .-
                                  (1im.*freq.*myMolData.Be .+ freq^2 .* myMolData.Me)),
              1:myMolData.numatoms);

end

"""

    constructMolAlpha!(myMolData::OneMol_NoPhonons{FT},
                       myPeriodicData::PeriodicData{FT},
                       freq::Union{FT, Complex{FT}},
                       k::Array{FT, 1}=zeros(FT, 3)) where FT<:AbstractFloat

Construct the inverse molecular susceptibility `myMolData.alphainv` in-place at frequency
`freq` and wavevector `k`, the latter of which must be a 3-element real vector. Without
phonons, `myMolData.alphainv` will be a vector, and the vectors `myMolData.alpha0` and
`myMolData.alphae` will be simply related to `myMolData.alphainv`.

"""
function constructMolAlpha!(myMolData::OneMol_NoPhonons{FT},
                            myPeriodicData::PeriodicData{FT},
                            freq::Union{FT, Complex{FT}},
                            k::Array{FT, 1}=zeros(FT, 3)) where FT<:AbstractFloat

    setindex!(myMolData.alphainv,
              (myMolData.Ke .- (1im.*freq.*myMolData.Be .+
                                freq^2 .* myMolData.Me))./(myMolData.Qe.^2),
              1:myMolData.numatoms);
    setindex!(myMolData.alphae, 1 ./ myMolData.alphainv, 1:myMolData.numatoms);
    setindex!(myMolData.alpha0, abs.(myMolData.alphae), 1:myMolData.numatoms);

end

"""

    KIk(myMolData::OneMol_WithPhonons{FT}, myPeriodicData::PeriodicData{FT},
        k::Array{FT, 1}=zeros(FT, 3)) where FT<:AbstractFloat

Construct the `k`-dependence of the internuclear spring constant matrix (only if phonons are
present), and return the result. Return `myMolData.KI` if the geometry has no periodic
dimensions.

See also: [`constructMolAlpha!(myMolData::OneMol_WithPhonons{FT},
                       myPeriodicData::PeriodicData{FT},
                       freq::Union{FT, Complex{FT}},
                       k::Array{FT, 1}=zeros(FT, 3)) where FT<:AbstractFloat`](@ref).

"""
function KIk(myMolData::OneMol_WithPhonons{FT}, myPeriodicData::PeriodicData{FT},
             k::Array{FT, 1}=zeros(FT, 3)) where FT<:AbstractFloat

    if (myPeriodicData.numdims < 1)
        return complex(myMolData.KI);
    end
    if (length(k) != 3)
        error("KIk(): k must have length 3");
    end
    currKIk = zeros(Complex{FT}, 3*myMolData.numatoms, 3*myMolData.numatoms);
    currKIblock = zeros(Complex{FT}, 3*myMolData.numatoms, 3*myMolData.numatoms);
    for nn2=1:myMolData.numblocks2
        for nn1=1:myMolData.numblocks1
            currKIblock[:, :] .= myMolData.KI[3*(nn1-1)*myMolData.numatoms+1:3*nn1*myMolData.numatoms,
                      3*(nn2-1)*myMolData.numatoms+1:3*nn2*myMolData.numatoms];
#            setindex!(currKIblock, myMolData.KI,
#                      3*(nn1-1)*myMolData.numatoms+1:3*nn1*myMolData.numatoms,
#                      3*(nn2-1)*myMolData.numatoms+1:3*nn2*myMolData.numatoms);
            lmul!(exp(-1im*dot(k,
                               myMolData.blocklist1[nn1] .*
                               myPeriodicData.latticevecs[:, 1] .+
                               myMolData.blocklist2[nn2] .*
                               myPeriodicData.latticevecs[:, 2])),
                  currKIblock);
            hermpart!(currKIblock);
            currKIk[:, :] .+= currKIblock[:, :];
        end
    end
    hermpart!(currKIk);
    return currKIk;

end


text:
using Test
using OpenQuantumSystems
using Random, SparseArrays, LinearAlgebra, StableRNGs

@testset "operators dense" begin

    Random.seed!(StableRNG(0), 1)

    D(op1::AbstractOperator, op2::AbstractOperator) =
        abs(tracedistance_nh(dense(op1), dense(op2)))
    D(x1::StateVector, x2::StateVector) = norm(x2 - x1)
    D(op1::Array, op2::Array) = abs(norm(op1 - op2))

    b = GenericBasis([3])
    one_op = OneDenseOperator(b)
    one_op_ref = [
        1.0+0.0im 0.0+0.0im 0.0+0.0im
        0.0+0.0im 1.0+0.0im 0.0+0.0im
        0.0+0.0im 0.0+0.0im 1.0+0.0im
    ]
    @test 1e-12 > D(one_op.data, one_op_ref)

    annihilation_op = AnnihilationOperator(b)
    annihilation_op_ref = [0.0 1.0 0.0; 0.0 0.0 1.4142135623730951; 0.0 0.0 0.0]
    @test 1e-12 > D(annihilation_op.data, annihilation_op_ref)

    creation_op = CreationOperator(b)
    creation_op_ref = [0.0 0.0 0.0; 1.0 0.0 0.0; 0.0 1.4142135623730951 0.0]
    @test 1e-12 > D(creation_op.data, creation_op_ref)

    position_op = PositionOperator(b)
    position_op_ref = [0.0 0.7071067811865475 0.0; 0.7071067811865475 0.0 1.0; 0.0 1.0 0.0]
    @test 1e-12 > D(position_op.data, position_op_ref)

    momentum_op = MomentumOperator(b)
    momentum_op_ref = ComplexF64[0.0 + 0.0im -0.0 - 0.7071067811865475im 0.0 + 0.0im; 0.0 + 0.7071067811865475im 0.0 + 0.0im -0.0 - 1.0im; 0.0 + 0.0im 0.0 + 1.0im 0.0 + 0.0im]
    @test 1e-12 > D(momentum_op.data, momentum_op_ref)

    shift_op = ShiftOperator(b, 1.0)
    shift_op_ref = [0.779728662995649 + 0.0im -0.5431245605675081 + 0.0im 0.3115107121936076 + 0.0im; 0.5431245605675084 + 0.0im 0.33918598898694735 + 0.0im -0.7680941196124976 + 0.0im; 0.31151071219360765 + 0.0im 0.7680941196124975 + 0.0im 0.559457325991298 + 0.0im]
    @test 1e-12 > D(shift_op.data, shift_op_ref)

end # testset

max_stars_repo_name: detrin/OpenQuantumSystems

max_issues_repo_name: detrin/OpenQuantumSystems


text:
print("threshold: execute functions ...\n")

#threshold
x = randn(200)*2
for th in (BiggestTH(), HardTH(), SoftTH(), SemiSoftTH(), SteinTH())
    threshold(x, th, 2)
end
for th in (PosTH(), NegTH())
    threshold(x, th)
end

# denoising
vs = VisuShrink(10)
n = 2^8
x0 = testfunction(n, "Doppler")
x = x0 + 0.05*randn(n)
y = denoise(x, TI=true)
y = denoise(x, TI=true, nspin = 8)
y = denoise(x, TI=false)
y = denoise(x, nothing)
y = denoise(randn(32,32), TI=true)

# best basis
wt = wavelet(WT.db4)
x = sin(4*linspace(0,2*pi-eps(),1024))
tree = bestbasistree(x, wt)
xtb = wpt(x, wt, tree)
@test_approx_eq iwpt(xtb, wt, tree) x

x = sin(4*linspace(0,2*pi-eps(),5*64)) # non-dyadic
tree = bestbasistree(x, wt)
xtb = wpt(x, wt, tree)
@test_approx_eq iwpt(xtb, wt, tree) x

#matching pursuit
N = 128
M = 64
y=randn(N)
Arr = randn(M,N)
func(a::AbstractVector) = Arr*a
funct(a::AbstractVector) = Arr'*a
x = func(y)
matchingpursuit(x, func, funct, 0.1)


text:
# syntax: proto2
# COV_EXCL_START
using ProtoBuf
import ProtoBuf.meta

const EventType = (;[
    Symbol("EVENT_CREATE") => Int32(0),
    Symbol("EVENT_CLOSE") => Int32(1),
    Symbol("EVENT_APPEND") => Int32(2),
    Symbol("EVENT_RENAME") => Int32(3),
    Symbol("EVENT_METADATA") => Int32(4),
    Symbol("EVENT_UNLINK") => Int32(5),
    Symbol("EVENT_TRUNCATE") => Int32(6),
]...)

const INodeType = (;[
    Symbol("I_TYPE_FILE") => Int32(0),
    Symbol("I_TYPE_DIRECTORY") => Int32(1),
    Symbol("I_TYPE_SYMLINK") => Int32(2),
]...)

const MetadataUpdateType = (;[
    Symbol("META_TYPE_TIMES") => Int32(0),
    Symbol("META_TYPE_REPLICATION") => Int32(1),
    Symbol("META_TYPE_OWNER") => Int32(2),
    Symbol("META_TYPE_PERMS") => Int32(3),
    Symbol("META_TYPE_ACLS") => Int32(4),
    Symbol("META_TYPE_XATTRS") => Int32(5),
]...)

mutable struct EventProto <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function EventProto(; kwargs...)
        obj = new(meta(EventProto), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
        end
        obj
    end
end # mutable struct EventProto
const __meta_EventProto = Ref{ProtoMeta}()
function meta(::Type{EventProto})
    ProtoBuf.metalock() do
        if !isassigned(__meta_EventProto)
            __meta_EventProto[] = target = ProtoMeta(EventProto)
            req = Symbol[:_type,:contents]
            allflds = Pair{Symbol,Union{Type,String}}[:_type => Int32, :contents => Array{UInt8,1}]
            meta(target, EventProto, allflds, req, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_EventProto[]
    end
end
function Base.getproperty(obj::EventProto, name::Symbol)
    if name === :_type
        return (obj.__protobuf_jl_internal_values[name])::Int32
    elseif name === :contents
        return (obj.__protobuf_jl_internal_values[name])::Array{UInt8,1}
    else
        getfield(obj, name)
    end
end

mutable struct EventBatchProto <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function EventBatchProto(; kwargs...)
        obj = new(meta(EventBatchProto), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
        end
        obj
    end
end # mutable struct EventBatchProto
const __meta_EventBatchProto = Ref{ProtoMeta}()
function meta(::Type{EventBatchProto})
    ProtoBuf.metalock() do
        if !isassigned(__meta_EventBatchProto)
            __meta_EventBatchProto[] = target = ProtoMeta(EventBatchProto)
            req = Symbol[:txid]
            allflds = Pair{Symbol,Union{Type,String}}[:txid => Int64, :events => Base.Vector{EventProto}]
            meta(target, EventBatchProto, allflds, req, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_EventBatchProto[]
    end
end
function Base.getproperty(obj::EventBatchProto, name::Symbol)
    if name === :txid
        return (obj.__protobuf_jl_internal_values[name])::Int64
    elseif name === :events
        return (obj.__protobuf_jl_internal_values[name])::Base.Vector{EventProto}
    else
        getfield(obj, name)
    end
end

mutable struct CreateEventProto <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function CreateEventProto(; kwargs...)
        obj = new(meta(CreateEventProto), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
        end
        obj
    end
end # mutable struct CreateEventProto
const __meta_CreateEventProto = Ref{ProtoMeta}()
function meta(::Type{CreateEventProto})
    ProtoBuf.metalock() do
        if !isassigned(__meta_CreateEventProto)
            __meta_CreateEventProto[] = target = ProtoMeta(CreateEventProto)
            req = Symbol[:_type,:path,:ctime,:ownerName,:groupName,:perms]
            val = Dict{Symbol,Any}(:defaultBlockSize => 0)
            allflds = Pair{Symbol,Union{Type,String}}[:_type => Int32, :path => AbstractString, :ctime => Int64, :ownerName => AbstractString, :groupName => AbstractString, :perms => FsPermissionProto, :replication => Int32, :symlinkTarget => AbstractString, :overwrite => Bool, :defaultBlockSize => Int64]
            meta(target, CreateEventProto, allflds, req, ProtoBuf.DEF_FNUM, val, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_CreateEventProto[]
    end
end
function Base.getproperty(obj::CreateEventProto, name::Symbol)
    if name === :_type
        return (obj.__protobuf_jl_internal_values[name])::Int32
    elseif name === :path
        return (obj.__protobuf_jl_internal_values[name])::AbstractString
    elseif name === :ctime
        return (obj.__protobuf_jl_internal_values[name])::Int64
    elseif name === :ownerName
        return (obj.__protobuf_jl_internal_values[name])::AbstractString
    elseif name === :groupName
        return (obj.__protobuf_jl_internal_values[name])::AbstractString
    elseif name === :perms
        return (obj.__protobuf_jl_internal_values[name])::FsPermissionProto
    elseif name === :replication
        return (obj.__protobuf_jl_internal_values[name])::Int32
    elseif name === :symlinkTarget
        return (obj.__protobuf_jl_internal_values[name])::AbstractString
    elseif name === :overwrite
        return (obj.__protobuf_jl_internal_values[name])::Bool
    elseif name === :defaultBlockSize
        return (obj.__protobuf_jl_internal_values[name])::Int64
    else
        getfield(obj, name)
    end
end

mutable struct CloseEventProto <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function CloseEventProto(; kwargs...)
        obj = new(meta(CloseEventProto), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
        end
        obj
    end
end # mutable struct CloseEventProto
const __meta_CloseEventProto = Ref{ProtoMeta}()
function meta(::Type{CloseEventProto})
    ProtoBuf.metalock() do
        if !isassigned(__meta_CloseEventProto)
            __meta_CloseEventProto[] = target = ProtoMeta(CloseEventProto)
            req = Symbol[:path,:fileSize,:timestamp]
            allflds = Pair{Symbol,Union{Type,String}}[:path => AbstractString, :fileSize => Int64, :timestamp => Int64]
            meta(target, CloseEventProto, allflds, req, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_CloseEventProto[]
    end
end
function Base.getproperty(obj::CloseEventProto, name::Symbol)
    if name === :path
        return (obj.__protobuf_jl_internal_values[name])::AbstractString
    elseif name === :fileSize
        return (obj.__protobuf_jl_internal_values[name])::Int64
    elseif name === :timestamp
        return (obj.__protobuf_jl_internal_values[name])::Int64
    else
        getfield(obj, name)
    end
end

mutable struct TruncateEventProto <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function TruncateEventProto(; kwargs...)
        obj = new(meta(TruncateEventProto), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
        end
        obj
    end
end # mutable struct TruncateEventProto
const __meta_TruncateEventProto = Ref{ProtoMeta}()
function meta(::Type{TruncateEventProto})
    ProtoBuf.metalock() do
        if !isassigned(__meta_TruncateEventProto)
            __meta_TruncateEventProto[] = target = ProtoMeta(TruncateEventProto)
            req = Symbol[:path,:fileSize,:timestamp]
            allflds = Pair{Symbol,Union{Type,String}}[:path => AbstractString, :fileSize => Int64, :timestamp => Int64]
            meta(target, TruncateEventProto, allflds, req, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_TruncateEventProto[]
    end
end
function Base.getproperty(obj::TruncateEventProto, name::Symbol)
    if name === :path
        return (obj.__protobuf_jl_internal_values[name])::AbstractString
    elseif name === :fileSize
        return (obj.__protobuf_jl_internal_values[name])::Int64
    elseif name === :timestamp
        return (obj.__protobuf_jl_internal_values[name])::Int64
    else
        getfield(obj, name)
    end
end

mutable struct AppendEventProto <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function AppendEventProto(; kwargs...)
        obj = new(meta(AppendEventProto), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
        end
        obj
    end
end # mutable struct AppendEventProto
const __meta_AppendEventProto = Ref{ProtoMeta}()
function meta(::Type{AppendEventProto})
    ProtoBuf.metalock() do
        if !isassigned(__meta_AppendEventProto)
            __meta_AppendEventProto[] = target = ProtoMeta(AppendEventProto)
            req = Symbol[:path]
            val = Dict{Symbol,Any}(:newBlock => false)
            allflds = Pair{Symbol,Union{Type,String}}[:path => AbstractString, :newBlock => Bool]
            meta(target, AppendEventProto, allflds, req, ProtoBuf.DEF_FNUM, val, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_AppendEventProto[]
    end
end
function Base.getproperty(obj::AppendEventProto, name::Symbol)
    if name === :path
        return (obj.__protobuf_jl_internal_values[name])::AbstractString
    elseif name === :newBlock
        return (obj.__protobuf_jl_internal_values[name])::Bool
    else
        getfield(obj, name)
    end
end

mutable struct RenameEventProto <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function RenameEventProto(; kwargs...)
        obj = new(meta(RenameEventProto), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
        end
        obj
    end
end # mutable struct RenameEventProto
const __meta_RenameEventProto = Ref{ProtoMeta}()
function meta(::Type{RenameEventProto})
    ProtoBuf.metalock() do
        if !isassigned(__meta_RenameEventProto)
            __meta_RenameEventProto[] = target = ProtoMeta(RenameEventProto)
            req = Symbol[:srcPath,:destPath,:timestamp]
            allflds = Pair{Symbol,Union{Type,String}}[:srcPath => AbstractString, :destPath => AbstractString, :timestamp => Int64]
            meta(target, RenameEventProto, allflds, req, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_RenameEventProto[]
    end
end
function Base.getproperty(obj::RenameEventProto, name::Symbol)
    if name === :srcPath
        return (obj.__protobuf_jl_internal_values[name])::AbstractString
    elseif name === :destPath
        return (obj.__protobuf_jl_internal_values[name])::AbstractString
    elseif name === :timestamp
        return (obj.__protobuf_jl_internal_values[name])::Int64
    else
        getfield(obj, name)
    end
end

mutable struct MetadataUpdateEventProto <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function MetadataUpdateEventProto(; kwargs...)
        obj = new(meta(MetadataUpdateEventProto), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
        end
        obj
    end
end # mutable struct MetadataUpdateEventProto
const __meta_MetadataUpdateEventProto = Ref{ProtoMeta}()
function meta(::Type{MetadataUpdateEventProto})
    ProtoBuf.metalock() do
        if !isassigned(__meta_MetadataUpdateEventProto)
            __meta_MetadataUpdateEventProto[] = target = ProtoMeta(MetadataUpdateEventProto)
            req = Symbol[:path,:_type]
            allflds = Pair{Symbol,Union{Type,String}}[:path => AbstractString, :_type => Int32, :mtime => Int64, :atime => Int64, :replication => Int32, :ownerName => AbstractString, :groupName => AbstractString, :perms => FsPermissionProto, :acls => Base.Vector{AclEntryProto}, :xAttrs => Base.Vector{XAttrProto}, :xAttrsRemoved => Bool]
            meta(target, MetadataUpdateEventProto, allflds, req, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_MetadataUpdateEventProto[]
    end
end
function Base.getproperty(obj::MetadataUpdateEventProto, name::Symbol)
    if name === :path
        return (obj.__protobuf_jl_internal_values[name])::AbstractString
    elseif name === :_type
        return (obj.__protobuf_jl_internal_values[name])::Int32
    elseif name === :mtime
        return (obj.__protobuf_jl_internal_values[name])::Int64
    elseif name === :atime
        return (obj.__protobuf_jl_internal_values[name])::Int64
    elseif name === :replication
        return (obj.__protobuf_jl_internal_values[name])::Int32
    elseif name === :ownerName
        return (obj.__protobuf_jl_internal_values[name])::AbstractString
    elseif name === :groupName
        return (obj.__protobuf_jl_internal_values[name])::AbstractString
    elseif name === :perms
        return (obj.__protobuf_jl_internal_values[name])::FsPermissionProto
    elseif name === :acls
        return (obj.__protobuf_jl_internal_values[name])::Base.Vector{AclEntryProto}
    elseif name === :xAttrs
        return (obj.__protobuf_jl_internal_values[name])::Base.Vector{XAttrProto}
    elseif name === :xAttrsRemoved
        return (obj.__protobuf_jl_internal_values[name])::Bool
    else
        getfield(obj, name)
    end
end

mutable struct UnlinkEventProto <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function UnlinkEventProto(; kwargs...)
        obj = new(meta(UnlinkEventProto), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
        end
        obj
    end
end # mutable struct UnlinkEventProto
const __meta_UnlinkEventProto = Ref{ProtoMeta}()
function meta(::Type{UnlinkEventProto})
    ProtoBuf.metalock() do
        if !isassigned(__meta_UnlinkEventProto)
            __meta_UnlinkEventProto[] = target = ProtoMeta(UnlinkEventProto)
            req = Symbol[:path,:timestamp]
            allflds = Pair{Symbol,Union{Type,String}}[:path => AbstractString, :timestamp => Int64]
            meta(target, UnlinkEventProto, allflds, req, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_UnlinkEventProto[]
    end
end
function Base.getproperty(obj::UnlinkEventProto, name::Symbol)
    if name === :path
        return (obj.__protobuf_jl_internal_values[name])::AbstractString
    elseif name === :timestamp
        return (obj.__protobuf_jl_internal_values[name])::Int64
    else
        getfield(obj, name)
    end
end

mutable struct EventsListProto <: ProtoType
    __protobuf_jl_internal_meta::ProtoMeta
    __protobuf_jl_internal_values::Dict{Symbol,Any}
    __protobuf_jl_internal_defaultset::Set{Symbol}

    function EventsListProto(; kwargs...)
        obj = new(meta(EventsListProto), Dict{Symbol,Any}(), Set{Symbol}())
        values = obj.__protobuf_jl_internal_values
        symdict = obj.__protobuf_jl_internal_meta.symdict
        for nv in kwargs
            fldname, fldval = nv
            fldtype = symdict[fldname].jtyp
            (fldname in keys(symdict)) || error(string(typeof(obj), " has no field with name ", fldname))
            values[fldname] = isa(fldval, fldtype) ? fldval : convert(fldtype, fldval)
        end
        obj
    end
end # mutable struct EventsListProto
const __meta_EventsListProto = Ref{ProtoMeta}()
function meta(::Type{EventsListProto})
    ProtoBuf.metalock() do
        if !isassigned(__meta_EventsListProto)
            __meta_EventsListProto[] = target = ProtoMeta(EventsListProto)
            req = Symbol[:firstTxid,:lastTxid,:syncTxid]
            allflds = Pair{Symbol,Union{Type,String}}[:events => Base.Vector{EventProto}, :firstTxid => Int64, :lastTxid => Int64, :syncTxid => Int64, :batch => Base.Vector{EventBatchProto}]
            meta(target, EventsListProto, allflds, req, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES)
        end
        __meta_EventsListProto[]
    end
end
function Base.getproperty(obj::EventsListProto, name::Symbol)
    if name === :events
        return (obj.__protobuf_jl_internal_values[name])::Base.Vector{EventProto}
    elseif name === :firstTxid
        return (obj.__protobuf_jl_internal_values[name])::Int64
    elseif name === :lastTxid
        return (obj.__protobuf_jl_internal_values[name])::Int64
    elseif name === :syncTxid
        return (obj.__protobuf_jl_internal_values[name])::Int64
    elseif name === :batch
        return (obj.__protobuf_jl_internal_values[name])::Base.Vector{EventBatchProto}
    else
        getfield(obj, name)
    end
end

export EventType, INodeType, MetadataUpdateType, EventProto, EventBatchProto, CreateEventProto, CloseEventProto, TruncateEventProto, AppendEventProto, RenameEventProto, MetadataUpdateEventProto, UnlinkEventProto, EventsListProto
# COV_EXCL_STOP


text:
using CompositeGrids
using Documenter

DocMeta.setdocmeta!(CompositeGrids, :DocTestSetup, :(using CompositeGrids); recursive=true)

makedocs(;
    modules=[CompositeGrids],
    authors="Kun Chen, Tao Wang, Xiansheng Cai",
    repo="https://github.com/iintSjds/CompositeGrids.jl/blob/{commit}{path}#{line}",
    sitename="CompositeGrids.jl",
    format=Documenter.HTML(;
        prettyurls=get(ENV, "CI", "false") == "true",
        canonical="https://iintSjds.github.io/CompositeGrids.jl",
        assets=String[],
    ),
    pages=[
        "Home" => "index.md",
        "Manual" => Any[
        ],
        "Library" => Any[
            "lib/simple.md",
            "lib/composite.md",
            "lib/interpolate.md",
                # map(s -> "lib/$(s)", sort(readdir(joinpath(@__DIR__, "src/lib"))))
                # "Internals" => map(s -> "lib/$(s)", sort(readdir(joinpath(@__DIR__, "src/lib"))))
        ]
    ],
)

deploydocs(;
    repo="github.com/iintSjds/CompositeGrids.jl.git",
    devbranch="dev"
)


text:
export @searchhistory

using REPL: LineEdit, LineEditREPL,
    REPLHistoryProvider, find_hist_file, hist_from_file
using REPL.LineEdit: edit_insert, InputAreaState

newline_symbol = "⏎"
# newline_symbol = "⏎⃣"

"""
Some random character from Unicode Private Use Area.
"""
const fake_newline = '\uf056'  # = rand('\uE000':'\uF8FF')

function escape_history(code::String)
    code = replace(code, newline_symbol => fake_newline)
    code = replace(code, '\n' => newline_symbol)
    return code
end

function unescape_history(code::String)
    code = replace(code, newline_symbol => '\n')
    code = replace(code, fake_newline => newline_symbol)
    return code
end

const history_provider = Ref{REPLHistoryProvider}()

"""
    load_history_provider() :: REPLHistoryProvider
"""
function load_history_provider()
    if !isdefined(history_provider, 1)
        history_provider[] = REPLHistoryProvider(Dict())
    end
    hp = history_provider[]
    if !isempty(hp.history)
        return hp
    end
    path = find_hist_file()
    if !isfile(path)
        return hp
    end
    open(path) do file
        hist_from_file(hp, file, path)
    end
    return hp
end

"""
    get_history_provider() :: REPLHistoryProvider
"""
function get_history_provider()
    try
        return Base.active_repl.interface.modes[1].hist
    catch
        return load_history_provider()
    end
end

function write_transformed_history(io::IO,
                                   hp = get_history_provider())
    seen = Set(String[])
    for (mode, code) in Iterators.reverse(zip(hp.modes, hp.history))
        if mode == :julia
            if !(code in seen)
                write(io, escape_history(code))
                write(io, "\n")
                push!(seen, code)
            end
        end
    end
end

function _set_next_input(repl::LineEditREPL, code::AbstractString)
    @async begin
        for _ in 1:10
            sleep(0.01)
            if LineEdit.state(repl.mistate).ias != InputAreaState(0, 0)
                edit_insert(repl.mistate, code)
                return
            end
        end
        @warn "Could not insert:\n$code"
    end
end

function _set_next_input(repl::Any, code::AbstractString)
    @info "Setting next input to $repl is not supported. Got:\n$code"
end

function is_ijulia()
    try
        return Main.IJulia.inited
    catch
        return false
    end
end

function set_next_input(code::AbstractString)
    repl = try
        Base.active_repl
    catch
        nothing
    end
    if repl == nothing && is_ijulia()
        Main.IJulia.load_string(code, true)  # replace = true
        return
    else
        _set_next_input(repl, code)
    end
end

function searchhistory()
    result = run_matcher(write_transformed_history)
    set_next_input(rstrip(unescape_history(result)))
    return nothing
end

"""
    @searchhistory

Search history interactively.  Interactively narrows down the code you
looking for from the REPL history.

_Limitation/feature in IJulia_:
In IJulia, `@searchhistory` searches history of terminal REPL, not the
history of the current IJulia session.
"""
macro searchhistory()
    :(searchhistory())
end


text:
function drawFiller(ctx::Cairo.CairoContext, camera::Camera, filler::Filler; alpha=nothing)
    if ctx.ptr != C_NULL
        x, y = Int(filler.x) * 8, Int(filler.y) * 8
        w, h = Int(filler.w) * 8, Int(filler.h) * 8

        Cairo.save(ctx)

        translate(ctx, -camera.x, -camera.y)
        scale(ctx, camera.scale, camera.scale)
        translate(ctx, x, y)

        Ahorn.drawRectangle(ctx, 0, 0, w, h, colors.filler_room_fill)

        Cairo.restore(ctx)
    end
end

function fillerVisible(camera::Camera, width::Int, height::Int, filler::Filler)
    actuallX = camera.x / camera.scale
    actuallY = camera.y / camera.scale

    actuallWidth = width / camera.scale
    actuallHeight = height / camera.scale

    x, y = Int(filler.x) * 8, Int(filler.y) * 8
    w, h = Int(filler.w) * 8, Int(filler.h) * 8

    cameraRect = Rectangle(actuallX, actuallY, actuallWidth, actuallHeight)
    fillerRect = Rectangle(x, y, w, h)

    return checkCollision(cameraRect, fillerRect)
end

max_stars_repo_name: asdfsdfadfasfasd/Ahorn

max_issues_repo_name: asdfsdfadfasfasd/Ahorn

max_forks_repo_name: asdfsdfadfasfasd/Ahorn


text:
"""
Tools to generate, and save to JSON, info about packages, names and docstrings.

You may either call this file from the shell, e.g. with (from the
directory where the script resides)

```zsh
% julia --project=@. generate_docstring.jl
```

or, which is more common, from the Julia REPL, with

```julia
julia> include("generate_docstring.jl")

julia> main()
```

The second option makes more sense, since one would usually activate
and add packages to the environment, and then run `main()` to generate
the JSON files, with the updated set of packages.

See [`main`](@ref) for more details.
"""

using Pkg
using JSON

"""
    list_of_pkgs()::Vector{String}

Return the list of Packages available for import, discarding jll packages.
"""
function list_of_pkgs()::Vector{String}
    pkgs = Vector{String}()
    append!(pkgs, ["Keywords", "Base",
        "Artifacts", "Base64", "CRC32c", "Dates", "DelimitedFiles",
        "Distributed", "Downloads", "FileWatching", "Future",
        "InteractiveUtils", "LazyArtifacts", "LibGit2", "LinearAlgebra",
        "Logging", "Markdown", "Mmap", "Printf", "Profile", "REPL",
        "Random", "SHA", "Serialization", "SharedArrays", "Sockets",
        "SparseArrays", "Statistics", "SuiteSparse", "TOML", "Test",
        "UUIDs", "Unicode"])
    for pkg in keys(Pkg.project().dependencies)
        push!(pkgs, pkg)
    end
    @info "$(length(pkgs)-2) packages found besides Base and the set of keywords"
    return pkgs
end

"""
    get_pkg_docs(pkg::String)::Dict{String, Vector{String}}

Return a Dict with the names as keys, and with each value being a vector,
where the first element indicates whether the associated name is "exported"
or "nonexported" from the package, while the second element contains the
corresponding docstring.

Only names with meaningful docstrings are retrieved.
"""
function get_pkg_docs(pkg::String)::Dict{String, Vector{String}}
    pkg_docs = Dict{String, Vector{String}}()
    num_exported = 0
    try
        let
            eval(Expr(:import, Expr(:., Symbol(pkg))))
            names_exported = names(eval(Symbol(pkg)))
            for name in names(eval(Symbol(pkg)), all=true)
                doc = string(eval(:(Base.Docs.@doc $(Symbol(pkg)).$(Symbol(name)))))
                if !startswith(string(name), "#")
                    if !occursin("No documentation found", doc) || occursin("[1]", doc)
                        exported = name in names_exported ? "exported" : "nonexported"
                        num_exported += exported == "exported" ? 1 : 0
                        push!(pkg_docs, string(name) => [exported, string(eval(:(Base.Docs.@doc $(Symbol(pkg)).$name)))])
                    end
                end
            end
        end
    catch
        nothing
    end
    @info "$(length(pkg_docs)) names retrieved ($num_exported of them exported) from package $pkg"
    return pkg_docs
end

"""
    get_all_docs()::Dict{String, Dict{String, Vector{String}}}

Return a Dict with the packages as keys and the info about the package
as values (see [get_pkg_docs](@ref)).
"""
function get_all_docs()::Dict{String, Dict{String, Vector{String}}}
    all_docs = Dict{String, Dict{String, Vector{String}}}()
    Keywords = [
        "baremodule", "begin", "break", "catch", "const",
        "continue", "do", "else", "elseif", "end", "export", "false",
        "finally", "for", "function", "global", "if", "import",
        "let", "local", "macro", "module", "quote", "return",
        "struct", "true", "try", "using", "while", "abstract type",
        "mutable struct", "primitive type", "where", "in", "isa"
    ]
    for pkg in list_of_pkgs()
        if pkg == "Keywords"
            pkg_docs = Dict{String, Vector{String}}()
            for name in Keywords
                if !startswith(string(name), "#")
                    doc = string(eval(:(Base.Docs.@doc $(Symbol(name)))))
                    if !occursin("No documentation found", doc) || occursin("[1]", doc)
                        push!(pkg_docs, string(name) => Vector{String}(["exported", doc]))
                    end
                end
            end
            push!(all_docs, pkg => pkg_docs)
            @info "$(length(pkg_docs)) keyword names retrieved"
        else
            pkg_docs = get_pkg_docs(pkg)
            if length(pkg_docs) > 0
                push!(all_docs, pkg => pkg_docs)
            end
        end
    end
    @info "$(length(all_docs)-2) packages found with docstrings"
    return all_docs
end

"""
    save_docs(docs_filename::String, all_docs::Dict{String, Dict{String, Vector{String}}})::Nothing

Save all available documentation info as a JSON file with the given filename.
"""
function save_docs(filename::String, all_docs::Dict{String, Dict{String, Vector{String}}})::Nothing
    write(filename, JSON.json(all_docs, 4))
    return nothing
end

"""
    load_all_docs(filename)::Dict{String, Dict{String, Vector{String}}}

Return a Dict with the all the available documentation info present
in the given JSON file.
"""
function load_docs(filename)::Dict{String, Dict{String, Vector{String}}}
    all_docs = JSON.parsefile(filename)
    all_docs = convert(Dict{String, Dict{String, Vector{String}}}, docs)
    return all_docs
end

"""
    get_all_names(docs::Dict{String, Dict{String, Vector{String}}})::Dict{String,Dict{String,String}}

Return a Dict with all the names (keys) available with docstrings and where
the values is another Dict whose keys are the packages where the name appears
in and the values indicate whether the name is "exported" from the packaged or
"nonexported".
"""
function get_all_names(all_docs::Dict{String, Dict{String, Vector{String}}})::Dict{String,Dict{String,String}}
    all_names = Dict{String,Dict{String,String}}()
    for (pkg, docs) in all_docs
        for name in keys(docs)
            if name in keys(all_names)
                push!(all_names[name], pkg => all_docs[pkg][name][1])
            else
                push!(all_names, name => Dict(pkg => all_docs[pkg][name][1]))
            end
        end
    end
    @info "$(length(all_names)) total names found."
    return all_names
end

"""
    save_names(filename::String, all_names::Dict{String,Dict{String,String}})::Nothing

Save to a JSON file the list of names and the corresponding package info
(see [`get_all_names`](@ref)).
"""
function save_names(filename::String, all_names::Dict{String,Dict{String,String}})::Nothing
    write(filename, JSON.json(all_names, 4))
    return nothing
end

"""
    load_names(filename::String)::Dict{String,Vector{Vector{String}}}

Return a Dict, read from the given JSON file, that contains the list of names
and the associated info from the packages each name appears in. (see [`get_all_names`](@ref)).
"""
function load_names(filename::String)::Dict{String,Dict{String,String}}
    all_names = JSON.parsefile(filename)
    all_names = convert(Dict{String,Dict{String,String}}, all_names)
    return all_names
end

"""
    main()

Generate, and save to JSON files, info about packages, names and docstrings.

The information is generated into two Dicts, and each Dict is saved in JSON format.

One Dict contains all the packages as keys, with each value being another Dict,
containing all the names in the package as keys, with the values being a vector,
where the first element indicates whether the name is "exported" or "nonexported"
from the package, and the second element contains the corresponding docstring.

The other Dict contains all the names as keys, with each value being another Dict,
whose keys are the packages where the name appears in and the values indicate
whether the name is "exported" from the packaged or "nonexported".

The JSON files are saved, respectively in "../../data/docs/all_docs.json"
and "../../data/docs/all_names.json", both relative to the script path.
"""
function main()
    all_docs = get_all_docs()
    all_names = get_all_names(all_docs)
    save_docs(joinpath(@__DIR__, "..", "data", "docs", "all_docs.json"), all_docs)
    save_names(joinpath(@__DIR__, "..", "data", "docs", "all_names.json"), all_names)
end

if abspath(PROGRAM_FILE) == @__FILE__
    main()
end


text:
# Note that this script can accept some limited command-line arguments, run
# `julia build_tarballs.jl --help` to see a usage message.
using BinaryBuilder, Pkg

name = "Bloaty"
version = v"1.0.0"

# Collection of sources required to complete build
sources = [
    ArchiveSource("https://github.com/google/bloaty/releases/download/v1.0/bloaty-1.0.tar.bz2",
                  "e1cf9830ba6c455218fdb50e7a8554ff256da749878acfaf77c032140d7ddde0")
]

# Bash recipe for building across all platforms
script = raw"""
cd $WORKSPACE/srcdir/bloaty*/
apk add protobuf
mkdir build && cd build
cmake -DCMAKE_INSTALL_PREFIX=${prefix} \
    -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TARGET_TOOLCHAIN} \
    -DCMAKE_BUILD_TYPE=Release \
    ..
make -j${nproc}
make install

# Remove extra stuff
rm ${bindir}/protoc*
rm ${libdir}/*.a
rm -r ${prefix}/include
rm -r ${prefix}/lib/cmake/
rm -r ${prefix}/lib/pkgconfig/
rm -rf ${prefix}/lib64/
"""

# These are the platforms we will build for by default, unless further
# platforms are passed in on the command line
platforms = expand_cxxstring_abis([p for p in supported_platforms() if !Sys.iswindows(p)])

# The products that we will ensure are always built
products = [
    ExecutableProduct("bloaty", :bloaty)
]

# Dependencies that must be installed before this package can be built
dependencies = [
    Dependency("Zlib_jll")
]

# Build the tarballs, and possibly a `build.jl` as well.
build_tarballs(ARGS, name, version, sources, script, platforms, products, dependencies)

max_stars_repo_name: sharanry/Yggdrasil

max_issues_repo_name: sharanry/Yggdrasil

max_forks_repo_name: sharanry/Yggdrasil


text:
# Chemfiles.jl, a modern library for chemistry file reading and writing
# Copyright (C) Guillaume Fraux and contributors -- BSD license

export positions, velocities, add_atom!, remove_atom!, add_velocities!,
has_velocities, set_cell!, set_topology!, set_step!, guess_bonds!, distance,
dihedral, out_of_plane, add_bond!, remove_bond!, add_residue!

"""
Create a new empty ``Frame``.
"""
function Frame()
    handle = lib.chfl_frame()
    return Frame(handle)
end

"""
Free the allocated memory for the ``Frame`` object.
"""
function _free(frame::Frame)
    lib.chfl_frame_free(frame.handle)
end

"""
Get the ``frame`` size, *i.e.* the current number of atoms.
"""
function Base.size(frame::Frame)
    n = Ref{UInt64}(0)
    _check(
        lib.chfl_frame_atoms_count(frame.handle, n)
    )
    return n[]
end

"""
Resize the positions and the velocities in a ``frame``, to make space for
``natoms`` atoms. This function may invalidate any pointer to the positions or
the velocities if the new size is bigger than the old one. In all the cases,
previous data is conserved. This function conserve the presence or absence of
velocities.
"""
function Base.resize!(frame::Frame, natoms::Integer)
    _check(
        lib.chfl_frame_resize(frame.handle, UInt64(natoms))
    )
end

"""
Get the positions in a ``Frame`` as an array. The positions are readable and
writable from this array. If the frame is resized (by writing to it, or calling
``resize!``), the array is invalidated.
"""
function positions(frame::Frame)
    ptr = Ref{Ptr{Float64}}()
    natoms = Ref{UInt64}(0)
    _check(
        lib.chfl_frame_positions(frame.handle, ptr, natoms)
    )
    return unsafe_wrap(Array{Float64, 2}, ptr[], (3, Int(natoms[])), false)
end

"""
Get the velocities in a ``Frame`` as an array. The velocities are readable and
writable from this array. If the frame is resized (by writing to it, or calling
``resize!``), the array is invalidated.

If the frame do not have velocity, this function will error. You can use
``add_velocities!`` to add velocities to a frame before calling this function.
"""
function velocities(frame::Frame)
    ptr = Ref{Ptr{Float64}}()
    natoms = Ref{UInt64}(0)
    _check(
        lib.chfl_frame_velocities(frame.handle, ptr, natoms)
    )
    return unsafe_wrap(Array{Float64, 2}, ptr[], (3, Int(natoms[])), false)
end

"""
Add velocities to this ``frame``. The storage is initialized with the result of
``size(frame)`` as number of atoms. If the frame already have velocities, this
does nothing.
"""
function add_velocities!(frame::Frame)
    _check(
        lib.chfl_frame_add_velocities(frame.handle)
    )
    return nothing
end

"""
Check if a ``frame`` contains velocity data or not.
"""
function has_velocities(frame::Frame)
    result = Ref{UInt8}(0)
    _check(
        lib.chfl_frame_has_velocities(frame.handle, result)
    )
    return convert(Bool, result[])
end

"""
Set the ``cell`` associated with a ``frame``.
"""
function set_cell!(frame::Frame, cell::UnitCell)
    _check(
        lib.chfl_frame_set_cell(frame.handle, cell.handle)
    )
    return nothing
end

"""
Set the ``topology`` associated with a ``frame``.
"""
function set_topology!(frame::Frame, topology::Topology)
    _check(
        lib.chfl_frame_set_topology(frame.handle, topology.handle)
    )
    return nothing
end

"""
Get the ``frame`` step, *i.e.* the frame number in the trajectory.
"""
function Base.step(frame::Frame)
    result = Ref{UInt64}(0)
    _check(
        lib.chfl_frame_step(frame.handle, result)
    )
    return result[]
end

"""
Set the ``frame`` step to ``step``.
"""
function set_step!(frame::Frame, step::Integer)
    _check(
        lib.chfl_frame_set_step(frame.handle, UInt64(step))
    )
    return nothing
end

"""
Guess the bonds, angles and dihedrals in the ``frame`` using a distance criteria.
"""
function guess_bonds!(frame::Frame)
    _check(lib.chfl_frame_guess_topology(frame.handle))
    return nothing
end

"""
Calculate the distance between two atoms.
"""
function distance(frame::Frame, i::Integer, j::Integer)
    result = Ref{Float64}(0)
    _check(
        lib.chfl_frame_distance(frame.handle, UInt64(i), UInt64(j), result)
    )
    return result[]
end

"""
Calculate the angle made by three atoms.
"""
function Base.angle(frame::Frame, i::Integer, j::Integer, k::Integer)
    result = Ref{Float64}(0)
    _check(
        lib.chfl_frame_angle(frame.handle, UInt64(i), UInt64(j), UInt64(k), result)
    )
    return result[]
end

"""
Calculate the dihedral (torsional) angle made by four unbranched atoms.
"""
function dihedral(frame::Frame, i::Integer, j::Integer, k::Integer, m::Integer)
    result = Ref{Float64}(0)
    _check(
        lib.chfl_frame_dihedral(frame.handle, UInt64(i), UInt64(j), UInt64(k), UInt64(m), result)
    )
    return result[]
end

"""
Calculate the out-of-plane (improper) angle made by four atoms.
"""
function out_of_plane(frame::Frame, i::Integer, j::Integer, k::Integer, m::Integer)
    result = Ref{Float64}(0)
    _check(
        lib.chfl_frame_out_of_plane(frame.handle, UInt64(i), UInt64(j), UInt64(k), UInt64(m), result)
    )
    return result[]
end

"""
Add an ``atom`` and the corresponding ``position`` and ``velocity`` data to a
``frame``.
"""
function add_atom!(frame::Frame, atom::Atom, position::Vector{Float64}, velocity::Vector{Float64} = Float64[0.0,0.0,0.0])
    _check(
        lib.chfl_frame_add_atom(frame.handle, atom.handle, position, velocity)
    )
    return nothing
end

"""
Remove the ``atom`` at ``index`` from the ``frame``.

This modify all the ``atoms`` indexes after ``index``, and invalidate any
array obtained using ``positions`` or ``velocities``.
"""
function remove_atom!(frame::Frame, index::Integer)
    _check(
        lib.chfl_frame_remove(frame.handle, UInt64(index))
    )
    return nothing
end

"""
Set a named property for the given ``Frame``.
"""
function set_property!(frame::Frame, name::String, property)

    prop = Property(property)

    _check(
        lib.chfl_frame_set_property(frame.handle, pointer(name), prop.handle)
    )
    return nothing
end

"""
Get a named property for the given atom.
"""
function property(frame::Frame, name::String)
    get(Property(lib.chfl_frame_get_property(frame.handle, pointer(name))))
end

"""
Add an additional bond to the ``Frames``'s ``Topology``.
"""
function add_bond!(frame::Frame, i::Integer, j::Integer)
    _check(
        lib.chfl_frame_add_bond(frame.handle, UInt64(i), UInt64(j))
    )
    return nothing
end

"""
Remove a bond from the ``Frames``'s ``Topology``.
"""
function remove_bond!(frame::Frame, i::Integer, j::Integer)
    _check(
        lib.chfl_frame_remove_bond(frame.handle, UInt64(i), UInt64(j))
    )
    return nothing
end

"""
Add a residue to the ``Frames``'s ``Topology``.
"""
function add_residue!(frame::Frame, residue::Residue)
    _check(
        lib.chfl_frame_add_residue(frame.handle, residue.handle)
    )
    return nothing
end

"""
Make a deep copy of a ``frame``.
"""
function Base.deepcopy(frame::Frame)
    handle = lib.chfl_frame_copy(frame.handle)
    return Frame(handle)
end

# Iteration support
Base.start(frame::Frame) = 0
Base.done(frame::Frame, index) = (index == size(frame))
Base.next(frame::Frame, index) = (Atom(frame, index), index + 1)


text:
module TestMain_VariableTimestep

using Test
using Mimi

import Mimi:
    reset_variables,
    variable, variable_names, external_param, build,
    compdef, compdefs, dimension, compinstance

@defcomp foo1 begin
    index1 = Index()

    par1 = Parameter()
    par2 = Parameter{Bool}(index=[time,index1], description="description par 1")
    par3 = Parameter(index=[time])

    var1 = Variable()
    var2 = Variable(index=[time])
    var3 = Variable(index=[time,index1])

    idx3 = Index()
    idx4 = Index()
    var4 = Variable{Bool}(index=[idx3])
    var5 = Variable(index=[index1, idx4])
end

x1 = Model()
set_dimension!(x1, :index1, [:r1, :r2, :r3])
set_dimension!(x1, :time, [2010, 2015, 2030])
set_dimension!(x1, :idx3, 1:3)
set_dimension!(x1, :idx4, 1:4)
add_comp!(x1, foo1)
set_param!(x1, :foo1, :par1, 5.0)

@test length(dimension(x1.md, :index1)) == 3

# @test_throws MethodError x1.Parameters.par1 = Array{Float64}(1,2)

par1 = external_param(x1, :par1)
@test par1.value == 5.0

update_param!(x1, :par1, 6.0)
par1 = external_param(x1, :par1)
@test par1.value == 6.0

set_param!(x1, :foo1, :par2, [true true false; true false false; true true true])

set_param!(x1, :foo1, :par3, [1.0, 2.0, 3.0])

build(x1)

ci = compinstance(x1, :foo1)
reset_variables(ci)

# Check all variables are defaulted
@test isnan(get_var_value(ci, :var1))

m = Model()
set_dimension!(m, :time, 20)
set_dimension!(m, :index1, 5)
add_comp!(m, foo1)

@test :var1 in variable_names(x1, :foo1)

end #module


text:
lazify(flag::Nothing, f) = maybe_lazy(f)
lazify(flag::Bool, f) = flag ? lazy(f) : f

"""
apply `f` to any node that has a value. `f` gets the node itself
and must return a node.
"""
function mapvalued(f, t::Node; walk=postwalk)
    walk(x->hasvalue(x) ? f(x) : x, t)
end

"""
    load(f, t::FileTree; dirs=false)

Walk the tree and optionally load data for nodes in it.

`f(file)` is the loader function which takes `File` as input.
Call `path(file)` to get the String path to read the  file.

If `dirs = true` then `f` can either get a `File` or `FileTree`.
nodes within `FileTree` will have already been loaded.

If `NoValue()` is returned by `f`, no value is attached to the node.
`hasvalue(x)` tells you if `x` already has a value or not.
"""
function load(f, t::Node; dirs=false, walk=postwalk, lazy=false)

    loader = x -> begin
        (!dirs && x isa FileTree) && return x
        f′ = lazify(lazy, f)
        setvalue(x, f′(x))
    end

    walk(loader, t)
end

"""
    mapvalues(f, x::FileTree)

(See `load` to load values into nodes of a tree.)

Apply `f` to the value of all nodes in `x` which have a value.
Returns a new tree where every value is replaced with the result of applying `f`.

`f` may return `NoValue()` to cause no value to be associated with a node.
"""
function mapvalues(f, t::Node; lazy=nothing, walk=postwalk)
    mapvalued(x -> setvalue(x, lazify(lazy, f)(x[])), t; walk=postwalk)
end

"""
    reducevalues(f, t::FileTree; associative=true)

Use `f` to combine values in the tree.

- `associative=true` assumes `f` can be applied in an associative way
"""
function reducevalues(f, t::FileTree; associative=true, lazy=nothing)
    f′ = lazify(lazy, f)
    itr = getindex.(collect(Iterators.filter(hasvalue, Leaves(t))))
    associative ? assocreduce(f′, itr) : reduce(f′, itr)
end
reducevalues(f, t::File; associative=true, lazy=nothing) = t[]

"""
Associative reduce
"""
function assocreduce(f, xs)
    length(xs) == 1 && return xs[1]
    l = length(xs)
    m = div(l, 2)
    f(assocreduce(f, xs[1:m]), assocreduce(f, xs[m+1:end]))
end

"""
    save(f, x::Node)

Save a FileTree to disk. Creates the directory structure
and calls `f` with `File` for every file in the tree which
has a value associated with it.

(see `load` and `mapvalues` for associating values with files.)
"""
function save(f, t::Node; lazy=nothing, exec=true)
    t′ = mapvalued(t) do x
        isempty(x) && return NoValue()

        function saver(file, val)
            d = string(dirname(file))
            # TODO: this does not work if `string` is not called
            if !isdir(d)
                mkpath(d)
            end
            # XXX: serialization pitfall!
            f(setvalue(file, val))
        end

        setvalue(x, lazify(lazy, saver)(x, x[]))
    end

    # placeholder task that waits and returns nothing
    (exec ? FileTrees.exec : identity)(reducevalues((x,y)->nothing, t′))
end


text:
"""
A `FrequencyAdapter` adapts the frequencies with which a set of
values/strategies/methods should be applied/tried in an optimization problem.
It is based on the `Adaptive Coordinate Frequencies` scheme described in:

T. Glasmachers and U. Dogan, "Accelerated Coordinate Descent with
Adaptive Coordinate Frequencies", 2013.

but generalized so that it can support more than the adaptation of only
the coordinates in a Coordinate Descent scheme. The things that are being
adapted are identified by integers in 1:n, with n being the main parameter.
"""
mutable struct FrequencyAdapter
    n::Int                # number of methods to select from
    eta::Float64          # 0..1, running average decay rate
    c::Float64            # positive, sensitivity to progress changes
    pmin::Float64         # minimal method probability
    pmax::Float64         # maximal method probability

    p::Vector{Float64}    # Current method weights
    psum::Float64         # Sum of p[i]
    a::Vector{Float64}    # Number of pending method applications
    deltahat::Float64     # Running average of the progress values.

    block::Vector{Int}    # current queue of methods to apply
    block_pos::Int		# current position in the queue

    numupdates::Int     # Number of times we have been updated.
    min_updates::Int    # Number of updates until we start adapting frequencies.

    function FrequencyAdapter(n; c = 0.2, eta = 1/n, pmin = 0.05, pmax = 20.0)
        new(n, eta, c, pmin, pmax,
            fill(1/n, n), 1.0,
            zeros(Float64, n),
            0.0,
            shuffle!(collect(1:n)), 1,
            0, n)
    end
end

frequencies(fa::FrequencyAdapter) = weights(fa.p)

"""
    next(fa::FrequencyAdapter)

Give the index of the method that should be used at the next iteration.

`FrequencyAdapter` maintains a block of randomly shuffled methods.
The function takes the next available method in the block.
If the block is empty, it is repopulated.

The methods are randomly shuffled each time the block is regenerated, since we need
to know their effectiveness at every period of the optimization process.
"""
function next(fa::FrequencyAdapter)
    if fa.block_pos > length(fa.block)
        fill_block!(fa)
    end
    #println("Taking $(fa.block_pos) from block = ", fa.block)
    fa.block_pos += 1
    return fa.block[fa.block_pos-1]
end

"""
Fill the block of methods to apply.
"""
function fill_block!(fa::FrequencyAdapter)
    #print("Creating new block, psum = $(fa.psum), a = ", fa.a, ", p = ", fa.p)
    empty!(fa.block)
    # fill the block according to the fa.p and fa.a
    last_pos = 0 # position in the block
    for i in 1:fa.n
        ai = fa.a[i]
        pi = fa.p[i]
        ai += (fa.n * pi / fa.psum)
        if ai >= 1.0
            # block should have at least one i-th method
            nai = floor(Int, ai)
            @assert nai > 0
            ai -= nai # adjust the remainder
            new_pos = last_pos + nai
            resize!(fa.block, new_pos)
            fa.block[(last_pos+1):(new_pos)] .= i
            last_pos = new_pos
        end
        fa.a[i] = ai
    end
    # Due to rounding errors the block is sometimes empty so we select the one
    # with largest a value.
    if last_pos == 0
        #println("Empty block created. Rectifying., std(p) = ", std(fa.p))
        #print("psum = $(fa.psum), a = ", fa.a, ", p = ", fa.p)
        i = argmax(fa.a)
        fa.a[i] = 0
        resize!(fa.block, 1)
        fa.block[1] = i
    end
    #println("Created new block = ", block)
    fa.block_pos = 1
    shuffle!(fa.block)
end

"""
Update the internal model of progress and success rate of each method based
on the latest progress value of one method. Progress values should be larger
the larger the progress/improvement was.
"""
function update!(fa::FrequencyAdapter, methodIndex, progress)
    # If we already have collected a few samples of progress rates we can update
    # the pi. This is the common case.
    if fa.numupdates >= fa.min_updates
        pnew = fa.deltahat > 0 ? clamp(fa.p[methodIndex] * exp(fa.c * (progress / fa.deltahat - 1)),
                                       fa.pmin, fa.pmax) : fa.pmin
        #print("i = ", methodIndex, ", pi = ", fa.p[methodIndex], ", pnew = ", pnew, ", psum = ", fa.psum)
        fa.psum += (pnew - fa.p[methodIndex])
        fa.p[methodIndex] = pnew
        #print(", new psum = ", fa.psum, ", deltahat = ", fa.deltahat)
        fa.deltahat = (1 - fa.eta) * fa.deltahat + fa.eta * progress
        #println(", new deltahat = ", fa.deltahat)
    else
        # Until we have collected at least min_updates we just sum the progress
        # values so we can later calculate their average.
        fa.deltahat += progress
    end
    fa.numupdates += 1
    if fa.numupdates == fa.min_updates
        #print("Setting deltahat, was = ", fa.deltahat, " (min_updates = $(fa.min_updates))")
        fa.deltahat = fa.deltahat / fa.min_updates
        #println(", now = ", fa.deltahat)
    end
end


text:
function RecWalk(TrainSet, ItemModel, α=0.01)
    n,m = size(TrainSet)
    Muu = speye(n)
    Mii = RowStochastic(ItemModel,"dmax")
    Hui = RowStochastic(TrainSet)
    Hiu = RowStochastic(TrainSet')
    H = vcat(hcat(spzeros(n,n),Hui), hcat(Hiu,spzeros(m,m)))
    M = vcat(hcat(Muu,spzeros(n,m)), hcat(spzeros(m,n),Mii))
    P = α*H+(1-α)*M
    return P
end

function RowStochastic(A, strategy="standard")
    if strategy == "dmax"
        row_sums = sum(A, 2)
        dmax = maximum(row_sums)
        A_temp = 1 / dmax * A
        return (I - spdiagm(vec(sum(A_temp, 2)))) + A_temp
    else
        row_sums = sum(A, 2)
        row_sums[sum(A, 2) .== 0] = 1 # replacing the zero row sums with 1
        return spdiagm(vec(1 ./ row_sums)) * A
    end

end

function readItemModel(filename, m)
    A = readdlm(filename, skipblanks = false)
    A[A .== ""] = 0; A = Array{Float64}(A)
    s1, s2 = size(A)
    rows = []; cols = []; vals = Float64[];
    for i = 1:s1
        items = Array{Int64}(A[i,1:2:s2 - 1])
        indx = find(items .> 0)
        items = items[indx]
        scores =  A[i,2 * indx]
        append!(rows, i * ones(length(items)))
        append!(cols, items)
        append!(vals, scores)
    end
    if maximum(rows) < m || maximum(cols) < m
        append!(rows, [m])
        append!(cols, [m])
        append!(vals, [0])
    end
    return sparse(rows, cols, vals)
end

@everywhere function Single_HR_RR_NDCG(Π, T, K)
    target = Π[T[1]]
    pos = sum(Π[T].>=target)
    if 1 <= pos <= K
            HR = 1; RR = 1 / pos; NDCG = 1/log2(pos+1)
    else
            HR = 0; RR = 0; NDCG = 0
    end
    return HR, RR, NDCG
end

max_stars_repo_name: nikolakopoulos/RecWalk

max_issues_repo_name: nikolakopoulos/RecWalk

max_forks_repo_name: nikolakopoulos/RecWalk


text:
using FactCheck
using BioFeatures
using Compat
include(Pkg.dir("GenomicTiles", "src","Tiles.jl"))

# --- Test tiles with overlap
tile = Tile(1,160,1)
df1 = DataFrame( region_id = ["R1","R1"],
                 start     = [1,100],
                 stop      = [50,300],
                 rtype     = ["NT","NB"] )
F = Features(df1)
dmap = @Compat.Dict("NT"=> 3.0,
                    "NB"=-3.0,
                    "MIXED"=1.0)
set_tile_value(tile,F,:rtype,dmap)
tile

# --- Test tiles with proportional overlap
expected_value = 49/299 + 200/299
49/299
200/299

tile = Tile(1,300,0)
set_tile_value1(tile,F)
tile

expected_value = 49/159 + 60/159
49/159
60/159
tile = Tile(1,160,0)
set_tile_value1(tile,F)
tile

expected_value= 100/200
tile = Tile(200,400,0)
set_tile_value1(tile,F)

expected_value =1
tile = Tile(1,100,0)
set_tile_value1(tile,F)
tile

expected_value = 50/50
tile = Tile(1,50,0)
set_tile_value1(tile,F)
tile

expected_value = 1
tile = Tile(1,45,0)
set_tile_value1(tile,F)
tile


text:
module Types
	RGB = Tuple{UInt8, UInt8, UInt8}
	export RGB
end


text:
struct GradFreeLocalOptimizer <: LocalOptimizer
    algo::Symbol
    options::Dict{Symbol,Any}
end

need_gradient(::GradFreeLocalOptimizer) = false

function BOBYQAOptimizer(; options...)
    GradFreeLocalOptimizer(:LN_BOBYQA, Dict{Symbol,Any}(options))
end

function minimize(o::GradFreeLocalOptimizer, f, lb, ub, x0)
    opt = create_nlopt(o.algo, lb, ub; min_objective = f, o.options...)
    fx, x, ret = NLopt.optimize(opt, x0)
    ret == :FORCED_STOP && throw(InterruptException())
    return fx, x, ret
end

function maximize(o::GradFreeLocalOptimizer, f, lb, ub, x0)
    opt = create_nlopt(o.algo, lb, ub; max_objective = f, o.options...)
    fx, x, ret = NLopt.optimize(opt, x0)
    ret == :FORCED_STOP && throw(InterruptException())
    return fx, x, ret
end


text:
# src/pair.jl
# Currency Pairs

import Base: numerator, denominator, inv, *, /, string
import Unitful: ustrip, unit

export CurrencyPair, CurrencyMarket, newmarket, ratio

"""```
struct CurrencyPair
```
Definition of a pair of Currencies to be used as an exchange rate.
"""
struct CurrencyPair
    base_currency::CurrencyFreeUnits
    quote_currency::CurrencyFreeUnits
end

"""```
struct CurrencyMarket{T <: Number}
```
Definition of a Currency Market with a `pair` of currencies trading at a given `value`.
"""
struct CurrencyMarket{T<:Number}
    pair::CurrencyPair
    value::T
end

"""```
CurrencyMarket(base_currency, quote_currency, value::T)
    === CurrencyMarket(CurrencyPair(base_currency, quote_currency), value)
```
Build a `CurrencyMarket` from the components of a `CurrencyPair` and a `value`.
"""
function CurrencyMarket(
    base_currency::CurrencyFreeUnits,
    quote_currency::CurrencyFreeUnits,
    value::T,
) where {T}
    return CurrencyMarket(CurrencyPair(base_currency, quote_currency), value)
end

"""```
newmarket(pair::CurrencyPair, value::T)
    === CurrencyMarket(pair, value)
```
Build a new market from a `pair` and a market `value`.
"""
function newmarket(pair::CurrencyPair, value::T) where {T}
    return CurrencyMarket(pair, value)
end

"""```
newmarket(base_currency, quote_currency, value::T)
    === CurrencyMarket(base_currency, quote_currency, value)
```
Build a new market from a `base_currency`, a `quote_currency`, and a market `value`.
"""
function newmarket(
    base_currency::CurrencyFreeUnits,
    quote_currency::CurrencyFreeUnits,
    value::T,
) where {T}
    return CurrencyMarket(base_currency, quote_currency, value)
end

"""```
newmarket(market::CurrencyMarket{T}, value::T)
    === CurrencyMarket(market.pair, value)
```
Build a new market from an existing `market` and a new market `value`.
"""
function newmarket(market::CurrencyMarket{T}, value::T) where {T}
    return CurrencyMarket(market.pair, value)
end

"""```
numerator(pair::CurrencyPair)
    === pair.quote_currency
```
Return the `numerator` of the currency `pair`.
"""
numerator(pair::CurrencyPair) = pair.quote_currency

"""```
denominator(pair::CurrencyPair)
    === pair.base_currency
```
Return the `denominator` of the currency `pair`.
"""
denominator(pair::CurrencyPair) = pair.base_currency

"""```
ratio(pair::CurrencyPair)
    === numerator(pair) / denominator(pair)
```
Represent a currency `pair` as a ratio.
"""
ratio(pair::CurrencyPair) = numerator(pair) / denominator(pair)

"""```
ratio(market::CurrencyMarket)
    === market.value * ratio(market.pair)
```
Represent a currency `market` as a ratio.
"""
ratio(market::CurrencyMarket) = market.value * ratio(market.pair)

"""```
inv(pair::CurrencyPair)
    === CurrencyPair(pair.quote_currency, pair.base_currency)
```
Invert a currency `pair`, swapping the `base_currency` and the `quote_currency`.
"""
inv(pair::CurrencyPair) = CurrencyPair(pair.quote_currency, pair.base_currency)

"""```
inv(market::CurrencyMarket)
    === newmarket(inv(market.pair), inv(market.value))
```
Invert a currency `market`, swapping the `base_currency` and the `quote_currency`,
and inverting the `market.value`.
"""
inv(market::CurrencyMarket) = newmarket(inv(market.pair), inv(market.value))

"""```
p1::CurrencyPair * p2::CurrencyPair
```
Multiply two `CurrencyPair`s together, cancelling out the `base_currency` from the
left-hand-side with the `quote_currency` from the right-hand-side.
"""
function *(p1::CurrencyPair, p2::CurrencyPair)
    if p1.base_currency != p2.quote_currency
        throw(Unitful.DimensionError("`$(p1.base_currency)` from `$p1` should match `$(p2.quote_currency)` from `$p2`"))
    end
    return CurrencyPair(p2.base_currency, p1.quote_currency)
end

"""```
pair::CurrencyPair * market::CurrencyMarket
    === newmarket(pair * market.pair, market.value)
```
Multiply a `pair` by a `market` by multiplying the underlying `pair`s and
building a new market at the `market.value`.
"""
function *(pair::CurrencyPair, market::CurrencyMarket)
    return newmarket(pair * market.pair, market.value)
end

"""```
pair::CurrencyPair * value::Currency{R}
```
Mulitply a currency `pair` by a `value` in the base currency to get a value
in the quote currency.
"""
function *(pair::CurrencyPair, value::Currency{R}) where {R}
    if unit(value) != pair.base_currency
        throw(DimensionMismatch("`$value` should have units of `$(pair.base_currency)`"))
    end
    return ustrip(value) * pair.quote_currency
end

"""```
pair::CurrencyPair * x
    === newmarket(pair, x)
```
Mulitplying a `pair` by an arbitrary value `x` making a new market at the value `x`.
"""
*(pair::CurrencyPair, x) = newmarket(pair, x)

"""```
x * pair::CurrencyPair
    === pair * x
```
Mulitplying a `pair` by an arbitrary value `x` making a new market at the value `x`.
"""
*(x, pair::CurrencyPair) = pair * x

"""```
pair::CurrencyPair / x
    === pair * inv(x)
```
Dividing a `pair` by an arbitrary value `x` making a new market at the value `inv(x)`.
"""
/(pair::CurrencyPair, x) = pair * inv(x)

"""```
x / pair::CurrencyPair
    === x * inv(pair)
```
Dividing an arbitrary value `x` by a `pair` making a new reversed market at the value `x`.
"""
/(x, pair::CurrencyPair) = x * inv(pair)

"""```
p1::CurrencyMarket * p2::CurrencyMarket
    === newmarket(p1.pair * p2.pair, p1.value * p2.value)
```
Mulitplying two markets `p1` and `p2` resulting in a market with multiplied pairs
and multiplied values.
"""
function *(p1::CurrencyMarket, p2::CurrencyMarket)
    return newmarket(p1.pair * p2.pair, p1.value * p2.value)
end

"""```
market::CurrencyMarket * pair::CurrencyPair
    === pair * market
```
Mulitplying a `market` by a `pair` is the same as the `pair * market`.
"""
*(market::CurrencyMarket, pair::CurrencyPair) = pair * market

"""```
market::CurrencyMarket * value::Currency{T}
    === market.pair * (market.value * value)
```
Multiplying a `market` by a currency `value` resulting in a new market at
the pair and resulting multiplied values.
"""
function *(market::CurrencyMarket{T}, value::Currency{R}) where {T,R}
    return market.pair * (market.value * value)
end

"""```
market::CurrencyMarket * x
    === newmarket(market, market.value * x)
```
Multiplying a `market` by an arbitrary value `x` resulting in a new market
with value `market.value * x`.
"""
*(market::CurrencyMarket, x) = newmarket(market, market.value * x)

"""```
x * market::CurrencyMarket
    === market * x
```
Multiplying arbitrary value `x` by a `market` resulting in a new market
with value `market.value * x`.
"""
*(x, market::CurrencyMarket) = market * x

"""```
market::CurrencyMarket / x
    === market * inv(x)
```
Dividing a `market` by arbitrary value `x` resulting in a new market
with value `market.value / x`.
"""
/(market::CurrencyMarket, x) = market * inv(x)

"""```
x / market::CurrencyMarket
    === x * inv(market)
```
Dividing arbitrary value `x` by a `market` resulting in a new market
with inverted pair and value `x / market.value`.
"""
/(x, market::CurrencyMarket) = x * inv(market)

"""```
string(pair::CurrencyPair)
    === string(pair.base_currency, "/", pair.quote_currency)
```
Return the string representation of a currency `pair`.
"""
function string(pair::CurrencyPair)
    return string(pair.base_currency, "/", pair.quote_currency)
end

"""```
string(market::CurrencyMarket)
    === string(market.pair, " @ ", market.value)
```
Return the string representation of a currency `market`.
"""
function string(market::CurrencyMarket)
    return string(market.pair, " @ ", market.value)
end


text:
using Gadfly, Distributions

set_default_plot_size(6inch, 3inch)

vals = rand(MultivariateNormal([0.0, 0.0], [1.0 0.5; 0.5 1.0]), 10000)
plot(x=vals[1,:], y=vals[2,:], Geom.hexbin)


text:
using JuliaName, Base.Test

X = rand(150)

@test SelectionSort(X) == sort!(X)


text:
using Literate: Literate
using Test: @testset
import Pkg

# Create markdown and notebook files for `file`
function create_files(title, file, repo_src, pages_dir, notebooks_dir; folder="")
    notebook_filename = first(splitext(file)) * ".ipynb"
    if !isempty(folder)
        notebook_filename = joinpath(folder, notebook_filename)
    end

    binder_logo   = "https://mybinder.org/badge_logo.svg"
    nbviewer_logo = "https://raw.githubusercontent.com/jupyter/design/master/logos/Badges/nbviewer_badge.svg"
    download_logo = "https://camo.githubusercontent.com/aea75103f6d9f690a19cb0e17c06f984ab0f472d9e6fe4eadaa0cc438ba88ada/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f646f776e6c6f61642d6e6f7465626f6f6b2d627269676874677265656e"

    notebook_path = "tutorials/notebooks/$notebook_filename"
    binder_url   = "https://mybinder.org/v2/gh/trixi-framework/Trixi.jl/tutorial_notebooks?filepath=$notebook_path"
    nbviewer_url = "https://nbviewer.jupyter.org/github/trixi-framework/Trixi.jl/blob/tutorial_notebooks/$notebook_path"
    download_url = "https://raw.githubusercontent.com/trixi-framework/Trixi.jl/tutorial_notebooks/$notebook_path"

    binder_badge   = "# [![]($binder_logo)]($binder_url)"
    nbviewer_badge = "# [![]($nbviewer_logo)]($nbviewer_url)"
    download_badge = "# [![]($download_logo)]($download_url)"

    # Generate notebook file
    function preprocess_notebook(content)
        warning = "# **Note:** To improve responsiveness via caching, the notebooks are updated only once a week. They are only
        # available for the latest stable release of Trixi at the time of caching.\n\n"
        return string("# # $title\n\n", warning, content)
    end
    Literate.notebook(joinpath(repo_src, folder, file), joinpath(notebooks_dir, folder); execute=false, preprocess=preprocess_notebook, credit=false)

    # Generate markdown file
    function preprocess_docs(content)
        return string("# # [$title](@id $(splitext(file)[1]))\n $binder_badge\n $nbviewer_badge\n $download_badge\n\n", content)
    end
    Literate.markdown(joinpath(repo_src, folder, file), joinpath(pages_dir, folder); preprocess=preprocess_docs,)
end

# Create tutorials with Literate.jl
function create_tutorials(files)
    repo_src        = joinpath(@__DIR__, "src", "files")

    pages_dir       = joinpath(@__DIR__, "..", "src", "tutorials")
    notebooks_dir   = joinpath(pages_dir, "notebooks")

    Sys.rm(pages_dir;       recursive=true, force=true)

    Sys.rm("out"; recursive=true, force=true)

    # Run tests on all tutorial files
    @testset "TrixiTutorials" begin
        for (i, (title, filename)) in enumerate(files)
            if filename isa Vector # Several files of one topic
                for j in eachindex(filename)
                    @testset "$(filename[j][2][2])" begin include(joinpath(repo_src, filename[j][2][1], filename[j][2][2])) end
                end
            else # Single files
                @testset "$title" begin include(joinpath(repo_src, filename)) end
            end
        end
    end

    # Generate markdown file for introduction page
    Literate.markdown(joinpath(repo_src, "index.jl"), pages_dir; name="introduction")
    # Navigation system for makedocs
    pages = Any["Introduction" => "tutorials/introduction.md",]

    # Create markdown and notebook files for tutorials
    for (i, (title, filename)) in enumerate(files)
        # Several files of one topic are created seperately and pushed to `pages` together.
        if filename isa Vector
            vector = []
            for j in eachindex(filename)
                create_files("$i.$j: $title: $(filename[j][1])", filename[j][2][2], repo_src,
                             pages_dir, notebooks_dir; folder=filename[j][2][1])

                path = "$(filename[j][2][1])/$(splitext(filename[j][2][2])[1]).md"
                push!(vector, "$i.$j $(filename[j][1])" => "tutorials/$path")
            end
            # Add to navigation menu
            push!(pages, ("$i $title" => vector))
        else # Single files
            create_files("$i: $title", filename, repo_src, pages_dir, notebooks_dir)
            # Add to navigation menu
            path = first(splitext(filename)) * ".md"
            push!(pages, ("$i $title" => "tutorials/$path"))
        end
    end

    return pages
end


text:
#------------------------------------------------------------------------------
function egarch11LL(par::Vector,y,x)

  (T,k) = (size(x,1),size(x,2))

  #lns2(t) = omega + alpha*abs(u(t-1)/s[t-1]) + beta1*lns2(t-1) + gamma1*u(t-1)/s[t-1]
  b = par[1:k]                                     #mean equation, y = x'*b
  (omega,alpha,beta1,gamma1) = par[k+1:k+4]
  yhat = x*b
  u    = y - yhat
  s2_0 = var(u)

  lns2    = zeros(typeof(alpha),T)
  lns2[1] = log(s2_0)
  for t = 2:T
    s_t1   = sqrt(exp(lns2[t-1]))
    lns2[t] = omega + alpha*abs(u[t-1])/s_t1 + beta1*lns2[t-1] + gamma1*u[t-1]/s_t1
  end
  s2 = exp.(lns2)

  LL_t    = -(1/2)*log(2*pi) .- (1/2)*log.(s2) - (1/2)*(u.^2)./s2
  LL_t[1] = 0

  LL = sum(LL_t)

  return LL,LL_t,s2,yhat,u

end
#------------------------------------------------------------------------------

#------------------------------------------------------------------------------

function DccLL(par,v,s2,Qbar)

  #(α,β) = par
  (α,β) = DccParTrans(par)             #restrict

  (T,n) = (size(v,1),size(v,2))

  u = v .* sqrt.(s2)

  Sigma = fill(NaN,(n,n,T))
  Q_t   = copy(Qbar)                    #starting guess
  LL_t  = zeros(T)
  for t = 2:T
    Q_t     = (1-α-β)*Qbar + α*v[t-1,:]*v[t-1,:]' + β*Q_t
    q_t     = diag(Q_t)
    R_t     = Q_t./sqrt.(q_t*q_t')
    d_t     = s2[t,:]
    Sigma_t = R_t.*sqrt.(d_t*d_t')
    LL_t[t] = -n*log(2*pi) - logdet(Sigma_t) - u[t,:]'*inv(Sigma_t)*u[t,:]
    Sigma[:,:,t] = Sigma_t
  end

  LL_t = 0.5*LL_t
  LL = sum(LL_t)

  return LL, LL_t, Sigma

end
#------------------------------------------------------------------------------

function DccParTrans(par)
    (a,b) = par
    α      = exp(a)/(1+exp(a)+exp(b))
    β      = exp(b)/(1+exp(a)+exp(b))
  return α,β
end
#------------------------------------------------------------------------------

max_stars_repo_name: duzaichuan/FinancialEconometrics

max_issues_repo_name: duzaichuan/FinancialEconometrics

max_forks_repo_name: duzaichuan/FinancialEconometrics