text:
using REPL

abstract type CharStyle end
struct Block <: CharStyle end
struct Braile <: CharStyle end

"""
    REPLOutput <: GraphicOutput

    REPLOutput(init; tspan, kw...)

An output that is displayed directly in the REPL. It can either store or discard
simulation frames.

# Arguments:

- `init`: initialisation `AbstractArrayArray` or `NamedTuple` of `AbstractArrayArray`.

# Keywords

- `color`: a color from Crayons.jl
- `cutoff`: `Real` cutoff point to display a full or empty cell. Default is `0.5`
- `style`: `CharStyle` `Block()` or `Braile()` printing. `Braile` uses 1/4 the screen space of `Block`.

$GRAPHICOUTPUT_KEYWORDS

A `GraphicConfig` object can be also passed to the `graphicconfig` keyword, and other keywords will be ignored.
"""
mutable struct REPLOutput{T,F<:AbstractVector{T},E,GC,Co,St,Cu} <: GraphicOutput{T,F}
    frames::F
    running::Bool
    extent::E
    graphicconfig::GC
    color::Co
    style::St
    cutoff::Cu
end
function REPLOutput(;
    frames, running, extent, graphicconfig,
    color=:white, cutoff=0.5, style=Block(), kw...
)
    REPLOutput(frames, running, extent, graphicconfig, color, style, cutoff)
end

function showframe(frame::AbstractArray, o::REPLOutput, data::AbstractSimData)
    showframe(frame, o)
    # Print the timestamp in the top right corner
    _print_to_repl((0, 0), o.color, string("Time $(currenttime(data))"))
end
function showframe(frame::AbstractArray, o::REPLOutput)
    # Print the frame
    _print_to_repl((0, 0), o.color, _replframe(o, frame))
end

# Terminal commands
_savepos(io::IO=terminal.out_stream) = print(io, "\x1b[s")
_restorepos(io::IO=terminal.out_stream) = print(io, "\x1b[u")
_movepos(io::IO, c=(0,0)) = print(io, "\x1b[$(c[2]);$(c[1])H")
_cursor_hide(io::IO=terminal.out_stream) = print(io, "\x1b[?25l")
_cursor_show(io::IO=terminal.out_stream) = print(io, "\x1b[?25h")

_print_to_repl(pos, c::Symbol, s::String) = _print_to_repl(pos, Crayon(foreground=c), s)
function _print_to_repl(pos, color::Crayon, str::String)
    io = terminal.out_stream
    _savepos(io)
    _cursor_hide(io)
    _movepos(io, pos)
    print(io, color)
    print(io, str)
    _cursor_show(io)
    _restorepos(io)
end

# Block size constants to calculate the frame size as
# braile pixels are half the height and width of block pixels
const YBRAILE = 4
const XBRAILE = 2
const YBLOCK = 2
const XBLOCK = 1

_chartype(o::REPLOutput) = _chartype(o.style)
_chartype(s::Braile) = YBRAILE, XBRAILE, brailize
_chartype(s::Block) = YBLOCK, XBLOCK, blockize

# Generate a text frame to show in the repl, matching the available size
function _replframe(o, frame)
    ystep, xstep, charfunc = _chartype(o)

    # Limit output area to available terminal size.
    dispy, dispx = displaysize(stdout)
    youtput, xoutput = outputsize = size(frame)
    yoffset, xoffset = (0, 0)

    yrange = max(1, ystep * yoffset):min(youtput, ystep * (dispy + yoffset - 1))
    xrange = max(1, xstep * xoffset):min(xoutput, xstep * (dispx + xoffset - 1))
    window = view(adapt(Array, frame), yrange, xrange) # TODO make this more efficient on GPU
    charfunc(window, o.cutoff)
end


text:
__precompile__()
module Utils

export get_memoryuse, initlogo, printparams

include("map_removeEQ.jl")
using .Map_removeEQ

using SeisIO, Printf, Dates, JLD2, FileIO, Distributed

const KB = 1024.0 #[bytes]
const MB = 1024.0 * KB
const GB = 1024.0 * MB

"""
get_memoryuse(InputDict::Dict)

evaluate memory use and estimate computational time
"""
function get_memoryuse(InputDict::Dict)

    trial_id        = 1

    while true
        global t1 = @elapsed EE = map_removeEQ(trial_id, InputDict) #[s]

		global Stest = []

        for i = 1:size(EE[1])[1]
			push!(Stest, EE[1][i])
		end

        dl = [Stest[i].misc["dlerror"] for i in 1:size(Stest)[1]]
        if issubset(0, dl)
            break;
        else
            trial_id += 1
        end
    end

    numofitr = InputDict["NumofTimestamp"] # number of iteration by parallel processing
    if trial_id == numofitr - 1
        error("all requests you submitted with input dictionary was failed. Please check the station availability in your request.")
    end

    mem_per_requestid = 1.2 * sizeof(Stest) / GB #[GB] *for the safty, required memory is multiplied by 1.2

    max_num_of_processes_per_parallelcycle = floor(Int64, InputDict["MAX_MEM_PER_CPU"]/mem_per_requestid)
    estimated_downloadtime = now() + Second(round(3 * t1 * numofitr / nprocs()))

	printstyled("---EQ REMOVAL STATS SUMMARY---\n"; color=:cyan, bold=true)

    println(@sprintf("Number of processes is %d.", nprocs()))

    totaldownloadsize = mem_per_requestid * numofitr
    if totaldownloadsize < MB
        totaldownloadsize = totaldownloadsize * GB / MB #[MB]
        sizeunit = "MB"
    else
        sizeunit = "GB"
    end

	println(@sprintf("One process returns %4.2e [%s] of dataset so maximum num of parallel processes is %d.",
	 			totaldownloadsize, sizeunit, max_num_of_processes_per_parallelcycle))
	println(@sprintf("Download will finish at %s.", round(estimated_downloadtime, Dates.Second(1))))
    println("*We have a time lag with processing time above, like in 10 minutes or so.*")
    println("*This estimation also changes if some processes fail and are skipped.*")

    return max_num_of_processes_per_parallelcycle

end

"""
printparams(param::Dict)

print parameters
"""
function printparams(param::Dict)
    printstyled("---Input Parameters---\n"; color=:cyan, bold=true)
    for key in keys(param)
        println(@sprintf("%-24s = %-10s", key, string(param["$key"])))
    end
end

"""
initlogo()

print initial logo
"""
function initlogo()

    print("
    _____      _      ______
   /  ___|    (_)     | ___ \\
   \\ `--.  ___ _ ___  | |_/ /___ _ __ ___   _____   _____
    `--. \\/ _ \\ / __| |    // _ \\ '_ ` _ \\ / _ \\ \\ / / _ \\
   /\\__/ /  __/ \\__ \\ | |\\ \\  __/ | | | | | (_) \\ V /  __/
   \\____/ \\___|_|___/ \\_| \\_\\___|_| |_| |_|\\___/ \\_/ \\___|
    ______ ____
   |  ____/ __ \\       |
   | |__ | |  | |      |
   |  __|| |  | |      |  v1.0 (Last update 07/07/2019)
   | |___| |__| |      |  © Kurama Okubo
   |______\\___\\_\\      |

")

    println("Job start running at "*string(now())*"\n")

end

end

ext: jl


text:
function combinaSoluciones_v2(fitness_ss, fitness_cs, lb, ub, numParticles, maxIterations)

    cond_1 = true
    xopt_1 = []
    fopt_1 = 0
    while cond_1
        xopt_1, fopt_1 = evol(fitness_ss, lb, ub, numParticles, maxIterations, false)
        if fopt_1 < 0
            cond_1 = false
            display("fitness_ss ok")
        end
    end
    cond = true
    delta = 1
    xopt_cs = xopt_1
    fopt_cs = fopt_1
#    while cond
        fopt_cs = fitness_cs(xopt_cs)
        if fopt_cs < 0
            display("fitness_cs ok")
            cond = false
        else
            numParticles_cs = numParticles
            maxIterations_cs = maxIterations
            lb_cs = xopt_cs - [3 0 0 3 3 0]'
            xopt_cs, fopt_cs = evol(fitness_cs, lb, xopt_cs, numParticles_cs, maxIterations_cs, false)
            display("fitness_cs ok")
        end
#    end

    return xopt_cs, fopt_cs

end


text:
module Chemistry

using JSON

export atomic_number,
       chemical_symbol,
       atomic_mass,
       symmetry,
       lattice_constant,
       rnn

data = JSON.parsefile(@__FILE__()[1:end-16] * "data/asedata.json")

_symbols = [Symbol(s) for s in data["symbols"]]
_masses = [Float64(m) for m in data["masses"]]
_refstates = Dict{String, Any}[ d == nothing ? Dict{String, Any}() : d
                                for d in data["refstates"]]

# the next array is generated from bulk data. I don't like storing it
# like this at all, this should be rewritten, but I don't fell like it
# right now.
const _rnn = [-1.0, -1.0, -1.0, 3.02243, 2.22873, -1.0, 1.54586, -1.0, -1.0,
   -1.0, 3.13248, 3.66329, 3.19823, 2.86378, 2.35126, -1.0, -1.0, -1.0, 3.71938,
   4.52931, 3.94566, 3.25752, 2.89607, 2.6154, 2.49415, -1.0, 2.48549, 2.49875,
   2.48902, 2.55266, 2.66, -1.0, 2.45085, -1.0, 3.53122, -1.0, 4.04465, 4.84108,
   4.29921, 3.55822, 3.17748, 2.85788, 2.72798, 2.70767, 2.64627, 2.68701,
   2.75065, 2.89207, 2.98, -1.0, -1.0, -1.0, 3.91893, -1.0, 4.38406, 5.23945,
   4.34745, 3.72861, 3.64867, 3.6416, 3.63168, -1.0, -1.0, 3.99238, 3.57345,
   3.524, 3.50263, 3.48854, 3.46905, 3.44956, 3.88202, 3.44157, 3.13374,
   2.86654, 2.73664, 2.73976, 2.67994, 2.71529, 2.77186, 2.885, -1.0, 3.41215,
   3.50018, -1.0, 3.35, -1.0, -1.0, -1.0, -1.0, 3.75474, 3.5921, -1.0, -1.0,
   -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0,
   -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0,-1.0, -1.0, -1.0]

const _numbers = Dict{Symbol, Int}()
for (n, sym) in enumerate(_symbols)
   _numbers[sym] = n - 1
end

atomic_number(sym::Symbol) = _numbers[sym]

chemical_symbol(z::Integer) = _symbols[z+1]

atomic_mass(z::Integer) = _masses[z+1]
atomic_mass(sym::Symbol) = atomic_mass(atomic_number(sym))

element_name(z::Integer) = _names[z+1]
element_name(sym::Symbol) = element_name(atomic_number(sym))

rnn(z::Integer) = _rnn[z+1]       # >>> TODO: move to utils ?? bulk as well??
rnn(sym::Symbol) = rnn(atomic_number(sym))

symmetry(z::Integer) = Symbol(_refstates[z+1]["symmetry"])
symmetry(sym::Symbol) = symmetry(atomic_number(sym))

lattice_constant(z::Integer) = Float64( _refstates[z+1]["a"] )
lattice_constant(sym::Symbol) = lattice_constant(atomic_number(sym))

refstate(z::Integer) = _refstates[z+1]
refstate(sym::Symbol) = refstate(atomic_number(sym))

end


text:
using PackageCompiler
create_sysimage([:Pluto, :PlutoUI, :Distributions, :Plots, :StatsPlots];
                precompile_execution_file = "warmup.jl",
                replace_default = false,
                sysimage_path = "PlotsSysimage.so",
                cpu_target = PackageCompiler.default_app_cpu_target())

max_stars_repo_name: roualdes/customfiles

max_issues_repo_name: roualdes/customfiles

max_forks_repo_name: roualdes/customfiles


text:
# Load modules
using Plots, LaTeXStrings
pyplot()
using ThinFilmsTools
using Optim

# Wavelength range [nm] and angle of incidence [degrees]
beam = PlaneWave(200:2100, [60.])

# Refractive indices of media
incident = RIdb.air(beam.λ)
emergent = RIdb.fused_silica_uv(beam.λ)

# Define the RI model to use
layers = [
    LayerTMMO(incident),
    ModelFit(:tauclorentz),
    LayerTMMO(emergent),
]

# Data
Ψexp, Δexp = SpectraDB.tantala_spectrum(beam.λ)
plot(1240.0./beam.λ, Ψexp)
plot!(1240.0./beam.λ, Δexp)
gui()

## Search
seed = [vcat(92.0, # thickness
             [1.5, 4.3, # ϵinf, Eg
              340, 5.0, 2.8, # osc 1, A1, E01, Γ1
              715, 2, 0.5, # osc 2
              41, 5, 0.8, # osc 3
             ],
        ),
]

# Spectrum type: ellipsometry with the input experimental spectra
spectype = Ellipsometry([Ψexp Δexp])

## Optimization using Optim
options = Optim.Options(
    g_abstol=1e-8, g_reltol=1e-8, iterations=10^5, show_trace=true, store_trace=true,
);

solOptim0 = fit_tmm_optics(
    spectype, seed, beam, layers;
    options=options, alg = LBFGS(), oftype=SumMeanAbs(),
)

plot(FitSpectrumEllip(),
    solOptim0.beam.λ, solOptim0.spectrumExp, solOptim0.spectrumFit,
    xaxis=("Wavelength [nm]"),
)
gui()
# plot(FitSpectrum(),
#     solOptim0.Beam.λ, solOptim0.spectrumExp, solOptim0.spectrumFit,
#     xaxis=("Wavelength [nm]"),
# )
# gui()
# julia> solOptim0.optParams
# 1-element Array{Array{Float64,1},1}:
#  [91.9939987559028, 1.4024927693924976, 4.359976200010805, 339.99868736615565, 5.093422704869424, 2.642028933308104, 715.0005849269817, 1.9891814175404072, 0.7171551391581684, 41.000188071713396, 4.94789281453286, 0.7311345356462031]
#
# julia> solOptim0.objfunMin
# 0.015678263617751792

lb = 0.5.*solOptim0.optParams
ub = 2.0.*solOptim0.optParams
# Thickness
lb[1][1] = 0.9.*solOptim0.optParams[1][1]
ub[1][1] = 1.2.*solOptim0.optParams[1][1]
# Egap
lb[1][3] = 3.0
ub[1][3] = 6.0
# solOptim = FitTMMOptics(
    # Ellipsometry(), solOptim0.optParams, beam, hcat(Ψexp, Δexp), layers;
    # options=options, alg=SAMIN(), lb=lb, ub=ub,
# )
solOptim = fit_tmm_optics(
    spectype, solOptim0.optParams, beam, layers;
    options=options, alg=SAMIN(), lb=lb, ub=ub, oftype=SumMeanAbs(),
)
plot(FitSpectrumEllip(),
    solOptim.beam.λ, solOptim.spectrumExp, solOptim.spectrumFit,
    xaxis=("Wavelength [nm]"),
)
gui()
# plot(FitSpectrum(),
#     solOptim.Beam.λ, solOptim.spectrumExp, solOptim.spectrumFit,
#     xaxis=("Wavelength [nm]"),
# )
# gui()

# julia> solOptim.objfunMin
# 0.01011540926111779
#
# julia> solOptim.optParams
# 1-element Array{Array{Float64,1},1}:
#  [92.41268518127337, 1.294018564396567, 4.258287813517591, 348.0769327939244, 3.7171269504011133, 4.97982821966445, 574.0431000488865, 3.7406423898551893, 0.580618765881699, 81.73269057321525, 5.273106528658877, 1.0466795973678233]


text:
function get_ant(;
    timestep=0.05,
    gravity=[0.0; 0.0; -9.81],
    friction_coefficient=0.5,
    spring=0.0,
    damper=1.0,
    contact_feet=true,
    contact_body=true,
    limits::Bool=true,
    joint_limits=[[-30.0, 30.0, -30.0, -70.0, -30.0, -70.0, -30.0, 30.0] * π / 180.0,
                  [ 30.0, 70.0,  30.0, -30.0,  30.0, -30.0,  30.0, 70.0] * π / 180.0],
    T=Float64)

    path = joinpath(@__DIR__, "../deps/ant.urdf")
    mech = Mechanism(path, true, T,
        gravity=gravity,
        timestep=timestep,
        spring=spring,
        damper=damper)

    # joint limits
    joints = deepcopy(mech.joints)

    if limits
        hiparent_vertex = get_joint(mech, :hip_1)
        joints[hiparent_vertex.id] = add_limits(mech, hiparent_vertex,
            rot_limits=[SVector{1}(joint_limits[1][1]), SVector{1}(joint_limits[2][1])])

        ankle1 = get_joint(mech, :ankle_1)
        joints[ankle1.id] = add_limits(mech, ankle1,
            rot_limits=[SVector{1}(joint_limits[1][2]), SVector{1}(joint_limits[2][2])])

        hip2 = get_joint(mech, :hip_2)
        joints[hip2.id] = add_limits(mech, hip2,
            rot_limits=[SVector{1}(joint_limits[1][3]), SVector{1}(joint_limits[2][3])])

        ankle2 = get_joint(mech, :ankle_2)
        joints[ankle2.id] = add_limits(mech, ankle2,
            rot_limits=[SVector{1}(joint_limits[1][4]), SVector{1}(joint_limits[2][4])])

        hip3 = get_joint(mech, :hip_3)
        joints[hip3.id] = add_limits(mech, hip3,
            rot_limits=[SVector{1}(joint_limits[1][5]), SVector{1}(joint_limits[2][5])])

        ankle3 = get_joint(mech, :ankle_3)
        joints[ankle3.id] = add_limits(mech, ankle3,
            rot_limits=[SVector{1}(joint_limits[1][6]), SVector{1}(joint_limits[2][6])])

        hip4 = get_joint(mech, :hip_4)
        joints[hip4.id] = add_limits(mech, hip4,
            rot_limits=[SVector{1}(joint_limits[1][7]), SVector{1}(joint_limits[2][7])])

        ankle4 = get_joint(mech, :ankle_4)
        joints[ankle4.id] = add_limits(mech, ankle4,
            rot_limits=[SVector{1}(joint_limits[1][8]), SVector{1}(joint_limits[2][8])])

        mech = Mechanism(Origin{T}(), mech.bodies, [joints...],
            gravity=gravity,
            timestep=timestep,
            spring=spring,
            damper=damper)
    end

    if contact_feet
        origin = Origin{T}()
        bodies = mech.bodies
        joints = mech.joints

        # foot contact
        normal = [0.0; 0.0; 1.0]
        foot_names = [:front_left_foot, :front_right_foot, :left_back_foot, :right_back_foot]
        foot = [get_body(mech, name) for name in foot_names]
        p = [[0.2; 0.2; 0.0], [-0.2; 0.2; 0.0], [-0.2; -0.2; 0.0], [0.2; -0.2; 0.0]]
        o = [[0.0; 0.0; f.shape.rh[1]] for f in foot]
        contacts = [contact_constraint(foot[i], normal, friction_coefficient=friction_coefficient, contact_point=p[i], offset=o[i]) for i = 1:length(foot_names)]

        if contact_body
            # torso contact
            torso = get_body(mech, :torso)
            p = [0.0; 0.0; 0.0]
            o = [0.0; 0.0; torso.shape.r]
            torso_contacts = contact_constraint(torso, normal, friction_coefficient=friction_coefficient, contact_point=p, offset=o)

            # elbow contact
            elbow_names = [:aux_1, :aux_2, :aux_3, :aux_4]
            elbow = [get_body(mech, e) for e in elbow_names]
            p = [-[0.1; 0.1; 0.0], -[-0.1; 0.1; 0.0], -[-0.1;-0.1; 0.0], -[0.1; -0.1; 0.0]]
            o = [[0.0; 0.0; e.shape.rh[1]] for e in elbow]
            elbow_contacts = [contact_constraint(elbow[i], normal, friction_coefficient=friction_coefficient, contact_point=p[i], offset=o[i]) for i = 1:length(elbow_names)]

            contacts = [contacts..., torso_contacts, elbow_contacts...]
        end
        mech = Mechanism(origin, bodies, joints, contacts,
        gravity=gravity,
        timestep=timestep,
        spring=spring,
        damper=damper)
    end

    return mech
end

function initialize_ant!(mechanism::Mechanism;
        body_position=[0.0; 0.0; 0.63],
        body_orientation=[0.0; 0.0; 0.0 * π],
        ankle_orientation=0.25)

    set_minimal_coordinates!(mechanism, get_joint(mechanism, :floating_base), [body_position; body_orientation])

    for i in [1, 4]
        set_minimal_coordinates!(mechanism, get_joint(mechanism, Symbol("hip_$i")), [0.0 * π])
        set_minimal_coordinates!(mechanism, get_joint(mechanism, Symbol("ankle_$i")), [ankle_orientation * π])
    end

    for i in [2, 3]
        set_minimal_coordinates!(mechanism, get_joint(mechanism, Symbol("hip_$i")), [0.0 * π])
        set_minimal_coordinates!(mechanism, get_joint(mechanism, Symbol("ankle_$i")), [-ankle_orientation * π])
    end

    zero_velocity!(mechanism)
end


text:
using Plots, Distributions
using IPMeasures
using IPMeasures: crit_mmd2_var, crit_mxy_over_mltpl, crit_mxy_over_sum
plotlyjs()

function sample_blobs(n, ratio, rows=5, cols=5, sep=10)
    correlation = (ratio - 1) / (ratio + 1)
    # generate within-blob variation
    X = rand(Distributions.Normal(0,1), 2, n)

    corr_sigma = [1  correlation;  correlation 1]
    Y = rand(Distributions.MultivariateNormal([0,0], corr_sigma), n)

    # assign to blobs
    X[1, :] .+= rand(1:rows,n) .* sep
    X[2, :] .+= rand(1:cols,n) * sep
    Y[1, :] .+= rand(1:rows,n) * sep
    Y[2, :] .+= rand(1:cols,n) * sep

    (X, Y)
end

@testset "Criteria comparison" begin
    γs = -3:0.1:2
    x = randn(2,1000);
    y = rand(2,1000) .- [0.5,0.5];
    y = randn(2,1000) .* [0.01,0.01];
    x, y = sample_blobs(2000, 6.0, 5, 5, 10)
    plot(γs, [crit_mmd2_var(IPMeasures.IMQKernel(10.0^γ), x, y, 1000) for γ in γs], label = "MMD2 / √VAR")
    plot!(γs, [crit_mxy_over_mltpl(IPMeasures.IMQKernel(10.0^γ), x, y) for γ in γs], label = "M(X,Y) / SQRT(M(X,X) * M(Y,Y)")
    p = plot!(γs, [crit_mxy_over_sum(IPMeasures.IMQKernel(10.0^γ), x, y) for γ in γs], label = "M(X,Y) / (M(X,X) + M(Y,Y)")
    @test p != nothing
end


text:
@testset "fixPoint.jl" begin
    @testset "fixPoint!()" begin
        trailer = SeaPearl.Trailer()
        x = SeaPearl.IntVar(2, 6, "x", trailer)
        y = SeaPearl.IntVar(5, 8, "y", trailer)
        z = SeaPearl.IntVar(6, 15, "z", trailer)
        t = SeaPearl.IntVar(6, 10, "t", trailer)
        u = SeaPearl.IntVar(10, 25, "u", trailer)

        constraint = SeaPearl.Equal(x, y, trailer)

        constraint3 = SeaPearl.Equal(z, t, trailer)

        model = SeaPearl.CPModel(trailer)

        SeaPearl.addVariable!(model, x)
        SeaPearl.addVariable!(model, y)
        SeaPearl.addVariable!(model, z)
        SeaPearl.addVariable!(model, t)
        SeaPearl.addVariable!(model, u)

        SeaPearl.addConstraint!(model, constraint)
        SeaPearl.addConstraint!(model, constraint3)
        feasability, prunedDomains = SeaPearl.fixPoint!(model)

        rightPruning = SeaPearl.CPModification("x" => [2, 3, 4],"z" => [11, 12, 13, 14, 15],"y" => [7, 8])

        @test prunedDomains == rightPruning
        @test feasability
        @test sum(map(x-> length(x[2]),collect(rightPruning))) == 10
        @test sum(map(x-> length(x[2]),collect(prunedDomains))) == 10

        @test length(x.domain) == 2
        @test length(y.domain) == 2
        @test length(z.domain) == 5
        @test length(t.domain) == 5

        constraint2 = SeaPearl.Equal(y, z, trailer)
        SeaPearl.addConstraint!(model, constraint2)

        SeaPearl.fixPoint!(model, Array{SeaPearl.Constraint}([constraint2]))

        @test SeaPearl.isbound(x)
        @test SeaPearl.isbound(y)
        @test SeaPearl.isbound(z)
        @test SeaPearl.isbound(t)

        constraint4 = SeaPearl.Equal(u, z, trailer)
        SeaPearl.addConstraint!(model, constraint4)

        feasability2, pruned = SeaPearl.fixPoint!(model, Array{SeaPearl.Constraint}([constraint4]))
        @test !feasability2
    end
end


text:
function ccc(x::AbstractVector, y::AbstractVector; lim=(0, Inf))
    x = vcat(x...)
    y = vcat(y...)
    @assert length(x) == length(y)
    mask = trues(length(x))
    for i in eachindex(x)
        mask[i] = !isnan(x[i]) & !isnan(y[i]) & (x[i]>lim[1]) & (x[i]<lim[2]) & (y[i]>lim[1]) & (y[i]<lim[2])
    end
    x = x[mask]
    y = y[mask]

    mx = mean(x)
    my = mean(y)
    sx = var(x) * (length(x) - 1) / length(x)
    sy = var(y) * (length(y) - 1) / length(y)
    sxy = sum((x .- mx) .* (y .- my)) / length(x)
    ccc_value = 2 * sxy / (sx + sy + (mx - mx)^2)
    return ccc_value
end

function ccc(fits::Dict; lim=(0, Inf))
    models = keys(fits)
    ccc_values = Dict()
    for model_a in models
        inner_dict = Dict()
        for model_b in models
            inner_dict[model_b] = ccc(fits[model_a], fits[model_b], lim=lim)
        end
        ccc_values[model_a] = inner_dict
    end
    return ccc_values
end

function apply_mask(; data, mask)
    @assert length(size(data)) >= length(size(mask))
    mask_indices = findall(mask)
    return data[mask_indices, :]
end

function negatives_to_zero!(x::AbstractArray)
    for i in eachindex(x)
        x[i] = x[i] < 0 ? 0 : x[i]
    end
    return x
end

function crop(data::AbstractArray; mask=nothing)
    if isnothing(mask)
        mask = @. !isnan(data) & (data > 0)
    end
    xlim = findall(vec(sum(mask, dims = [2,3])) .> 0)
    ylim = findall(vec(sum(mask, dims = [1,3])) .> 0)
    return data[xlim, ylim, :]
end
function crop(data::NamedTuple; mask=nothing)
    for key in keys(data)
        data[key] = crop(data[key]; mask = mask)
    end
    return data
end


text:
#libhts_detected = false
function detecthts()
    false
end

#=
function append_code()
    codes = """
    kstring_t * get_ptr_of_kstr(int num){
      char * ch = (char *)malloc(num);
      kstring_t *p = (kstring_t *)malloc(sizeof(kstring_t));
      p->l = 0;
      p->m = num;
      p->s = ch;
      return p;
    };
    """
    open("sam.c","a+") do file
        write(file, codes)
    end
end
=#

using BinDeps
@BinDeps.setup

if !detecthts()

    hts = library_dependency("hts", aliases=["libhts","libhts.so","libhts.dylib","libhts.dll"])
    _prefix = joinpath(BinDeps.depsdir(hts),"usr")
    _srcdir = joinpath(BinDeps.depsdir(hts),"src")
    _htsdir = joinpath(_srcdir,"htslib-1.3")
    _libdir = joinpath(_prefix, "lib")

    provides(BuildProcess,
             (@build_steps begin
              CreateDirectory(_srcdir)
              CreateDirectory(_libdir)
              @build_steps begin
              ChangeDirectory(_srcdir)
              `rm -rf htslib`
              `wget https://github.com/samtools/htslib/releases/download/1.3/htslib-1.3.tar.bz2`
              `tar xvf htslib-1.3.tar.bz2`

              @linux_only FileRule(joinpath(_libdir, "libhts.so"), @build_steps begin
                                   ChangeDirectory(_htsdir)
                                   `autoconf`
                                   `./configure`
                                   `make libhts.so`
                                   `cp libhts.so $_libdir`
                                   end)
              @osx_only FileRule(joinpath(_libdir, "libhts.dylib"), @build_steps begin
                                 ChangeDirectory(_htsdir)
                                 `autoconf`
                                 `./configure`
                                 `make libhts.dylib`
                                 `cp libhts.dylib $_libdir`
                                 end)

              end
             end), hts)

    @BinDeps.install Dict(:hts => :hts)

end


text:
using LinearAlgebra

a = [1.0000000           sqrt(2.0)           2.0000000
    sqrt(2.0)           3.0000000           sqrt(2.0)
    2.0000000           sqrt(2.0)           1.0000000]

display(eigen!(a))

max_stars_repo_name: j-hayes/jacobi

max_issues_repo_name: j-hayes/jacobi

max_forks_repo_name: j-hayes/jacobi


text:
#
# Restricted Two-body Problem models
#

"""
A `ModelingToolkit.ODESystem` for the Restricted Two-body Problem.

The order of the states follows: `[x, y, z, ẋ, ẏ, ż]`.

The order of the parameters follows: `[μ]`.

# Extended Help
The Restricted Two-body Problem is a simplified dynamical model
describing one small body (spacecraft, etc.) and one celestial
body. The gravity of the celestial body exhibits a force on the
small body. This model is commonly used as a simplification to
descibe our solar systems' planets orbiting our sun, or a
spacecraft orbiting Earth.

### Usage

```julia
model = R2BP()
```
"""
@memoize function R2BP(; stm=false, structural_simplify=true, name=:R2BP)

    @parameters t μ
    @variables x(t) y(t) z(t) ẋ(t) ẏ(t) ż(t)
    δ = Differential(t)
    r = @SVector [x,y,z]
    v = @SVector [ẋ,ẏ,ż]

    eqs = vcat(
        δ.(r) .~ v,
        δ.(v) .~ -μ .* (r ./ norm(r)^3)
    )

    if stm
        @variables Φ[1:6,1:6](t)
        Φ = Symbolics.scalarize(Φ)
        A = Symbolics.jacobian(map(el -> el.rhs, eqs), vcat(r,v))

        LHS = map(δ, Φ)
        RHS = map(simplify, A * Φ)

        eqs = vcat(eqs, [LHS[i] ~ RHS[i] for i in 1:length(LHS)])
    end

    if string(name) == "R2BP" && stm
        modelname = Symbol("R2BPWithSTM")
    else
        modelname = name
    end

    sys = ODESystem(
        eqs, t, stm  ? vcat(r,v,Φ...) : vcat(r,v), [μ];
        name = modelname
    )
    return structural_simplify ? ModelingToolkit.structural_simplify(sys) : sys
end

"""
Returns an `ODEFunction` for R2BP dynamics.
Results are cached with `Memoize.jl`.

The order of the states follows: `[x, y, z, ẋ, ẏ, ż]`.

The order of the parameters follows: `[μ]`.

# Extended Help

### Usage

The `stm`, `structural_simplify`, and `name` keyword arguments
are passed to `R2BP`. All other keyword arguments are passed
directly to `SciMLBase.ODEFunction`.

```julia
f = R2BPFunction(; stm=false, structural_simplify=true, name=:R2BP, jac=true)
let u = randn(6), p = randn(1), t = 0
    f(u, p, t)
end
```
"""
@memoize function R2BPFunction(; stm=false, structural_simplify=true, name=:R2BP, kwargs...)
    defaults = (; jac=true)
    options  = merge(defaults, kwargs)
    return ODEFunction(
        R2BP(; stm=stm, structural_simplify=structural_simplify, name=name);
        options...
    )
end


text:
"""
    AbstractSolver{T} <: MathOptInterface.AbstractNLPEvaluator

Abstract solver for trajectory optimization problems

# Interface
Any type that inherits from `AbstractSolver` must define the following methods:
```julia
model = get_model(::AbstractSolver)::AbstractModel
obj   = get_objective(::AbstractSolver)::AbstractObjective
E     = get_cost_expansion(::AbstractSolver)::QuadraticExpansion  # quadratic error state expansion
Z     = get_trajectory(::AbstractSolver)::Traj
n,m,N = Base.size(::AbstractSolver)
x0    = get_initial_state(::AbstractSolver)::StaticVector
solve!(::AbstractSolver)
```

Optional methods for line search and merit function interface. Note that these do not
    have to return `Traj`
```julia
Z     = get_solution(::AbstractSolver)  # current solution (defaults to get_trajectory)
Z     = get_primals(::AbstractSolver)   # current primals estimate used in the line search
dZ    = get_step(::AbstractSolver)      # current step in the primal variables
```

Optional methods
```julia
opts  = options(::AbstractSolver)       # options struct for the solver. Defaults to `solver.opts`
st    = solver_stats(::AbstractSolver)  # dictionary of solver statistics. Defaults to `solver.stats`
iters = iterations(::AbstractSolver)    #
```
"""
abstract type AbstractSolver{T} end

# Default getters
@inline TO.get_model(solver::AbstractSolver) = solver.model
@inline TO.get_objective(solver::AbstractSolver) = solver.obj
@inline TO.get_trajectory(solver::AbstractSolver) = solver.Z.Z_
@inline get_cost_expansion(solver::AbstractSolver) = solver.E
@inline get_cost_expansion_error(solver::AbstractSolver) = solver.E
@inline get_error_state_jacobians(solver::AbstractSolver) = solver.G
@inline get_initial_state(solver::AbstractSolver) = solver.x0

@inline get_solution(solver::AbstractSolver) = get_trajectory(solver)
@inline get_primals(solver::AbstractSolver) = solver.Z̄
@inline get_step(solver::AbstractSolver) = solver.δZ
@inline stats(solver::AbstractSolver) = solver.stats
iterations(solver::AbstractSolver) = stats(solver).iterations
@inline options(solver::AbstractSolver) = solver.opts
set_options!(solver::AbstractSolver; opts...) = set_options!(options(solver); opts...)
reset!(solver::AbstractSolver) = reset_solver!(solver)  # default method
solvername(solver::S) where S <: AbstractSolver = solvername(S)
is_parentsolver(solver::AbstractSolver) = stats(solver).parent == solvername(solver)

"""
    reset_solver!(solver::AbstractSolver)

Reset solver stats and constraints.
"""
function reset_solver!(solver::AbstractSolver)
    # Reset the stats only if it's the top level solver
    opts = options(solver)::SolverOptions
    reset!(stats(solver), opts.iterations, solvername(solver))

    if is_constrained(solver)
        reset!(get_constraints(solver), opts)
    end
end

"""
    terminate!(solver::AbstractSolver)

Perform any necessary actions after finishing the solve.
"""
function terminate!(solver::AbstractSolver)
    # Time solve
    stat = stats(solver)
    stat.tsolve = (time_ns() - stat.tstart)*1e-6  # in ms

    # Delete extra stats entries, only if terminal solver
    trim!(stats(solver), solvername(solver))

    # Print solve summary
    if solver.opts.show_summary && is_parentsolver(solver)
        print_summary(solver)
    end
end

"""
    TerminationStatus

* `UNSOLVED`: Initial value. Solve either hasn't been attempted or is in process..
* `SOLVE_SUCCEEDED`: Solve met all the required convergence criteria.
* `MAX_ITERATIONS`: Solve was unable to meet the required convergence criteria within the maximum number of iterations.
* `MAX_ITERATIONS_OUTER`: Solve was unable to meet the required constraint satisfaction the maximum number of outer loop iterations.
* `MAXIMUM_COST`: Cost exceeded maximum allowable cost.
* `STATE_LIMIT`: State values exceeded the imposed numerical limits.
* `CONTROL_LIMIT`: Control values exceeded the imposed numerical limits.
* `NO_PROGRESS`: iLQR was unable to make any progress for `dJ_counter_limit` consecutive iterations.
* `COST_INCREASE`: The cost increased during the iLQR forward pass.
"""
@enum(TerminationStatus, UNSOLVED, SOLVE_SUCCEEDED, MAX_ITERATIONS, MAX_ITERATIONS_OUTER,
    MAXIMUM_COST, STATE_LIMIT, CONTROL_LIMIT, NO_PROGRESS, COST_INCREASE)

@inline status(solver::AbstractSolver) = stats(solver).status

function print_summary(solver::S) where S <: AbstractSolver
    stat = stats(solver)
    col_h1 = crayon"bold green"
    col_h2 = crayon"bold blue"
    col0 = Crayon(reset=true)
    get_color(v::Bool) = v ? crayon"green" : crayon"red"

    # Info header
    println(col_h1, "\nSOLVE COMPLETED")
    print(col0," solved using the ")
    print(col0, crayon"bold cyan", solvername(solver))
    print(col0, " Solver,\n part of the Altro.jl package developed by the REx Lab at Stanford and Carnegie Mellon Universities\n")

    # Stats
    println(col_h2, "\n  Solve Statistics")
    println(col0, "    Total Iterations: ", iterations(solver))
    println(col0, "    Solve Time: ", stat.tsolve, " (ms)")

    # Convergence
    println(col_h2, "\n  Covergence")
    if iterations(solver) == 0
        println(crayon"red", "    Solver failed to make it through the first iteration.")
    else
        println(col0, "    Terminal Cost: ", stat.cost[end])
        println(col0, "    Terminal dJ: ", get_color(stat.dJ[end] < solver.opts.cost_tolerance), stat.dJ[end])
        println(col0, "    Terminal gradient: ", get_color(stat.gradient[end] < solver.opts.gradient_tolerance), stat.gradient[end])
        if is_constrained(solver)
            println(col0, "    Terminal constraint violation: ", get_color(stat.c_max[end] < solver.opts.constraint_tolerance), stat.c_max[end])
        end
    end
    println(col0, "    Solve Status: ", crayon"bold", get_color(status(solver) == SOLVE_SUCCEEDED), status(solver))
    print(Crayon(reset=true))  # reset output color
end

"$(TYPEDEF) Unconstrained optimization solver. Will ignore
any constraints in the problem"
abstract type UnconstrainedSolver{T} <: AbstractSolver{T} end

"""$(TYPEDEF)
Abstract solver for constrained trajectory optimization problems

In addition to the methods required for `AbstractSolver`, all `ConstrainedSolver`s
    must define the following method
```julia
get_constraints(::ConstrainedSolver)::ConstrainSet
```
"""
abstract type ConstrainedSolver{T} <: AbstractSolver{T} end

is_constrained(::Type{<:AbstractSolver})::Bool = true
is_constrained(::Type{<:ConstrainedSolver})::Bool = true
is_constrained(::Type{<:UnconstrainedSolver})::Bool = false
is_constrained(solver::AbstractSolver) = is_constrained(typeof(solver)) && !isempty(get_constraints(solver))

@inline get_duals(solver::ConstrainedSolver) = get_duals(get_constraints(solver))
@inline set_duals!(solver::ConstrainedSolver, λ) = set_duals!(get_constraints(solver), λ)
@inline set_duals!(solver::AbstractSolver, λ) = nothing

function TO.cost(solver::AbstractSolver, Z=get_trajectory(solver))
    obj = get_objective(solver)
    TO.cost(obj, Z)
end

function TO.cost_expansion!(solver::AbstractSolver)
    Z = get_trajectory(solver)
    E, obj = get_cost_expansion(solver), get_objective(solver)
    cost_expansion!(E, obj, Z)
end

TO.error_expansion!(solver::AbstractSolver) = error_expansion_uncon!(solver)

""" $(SIGNATURES)
Calculate all the constraint values given the trajectory `Z`
"""
function update_constraints!(solver::ConstrainedSolver, Z::Traj=get_trajectory(solver))
    conSet = get_constraints(solver)
    TO.evaluate!(conSet, Z)
end

function update_active_set!(solver::ConstrainedSolver,
        Z=get_trajectory(solver); tol=solver.opts.active_set_tolerance)
    conSet = get_constraints(solver)
    update_active_set!(conSet, Val(tol))
end

""" $(SIGNATURES)
Calculate all the constraint Jacobians given the trajectory `Z`
"""
function constraint_jacobian!(solver::ConstrainedSolver, Z=get_trajectory(solver))
    conSet = get_constraints(solver)
    TO.jacobian!(conSet, Z)
    return nothing
end

#--- Error Expansion ---#
function error_expansion_uncon!(solver::AbstractSolver)
    E  = get_cost_expansion_error(solver)
    E0 = get_cost_expansion(solver)
    G  = get_error_state_jacobians(solver)
    error_expansion!(E, E0, get_model(solver), G)
end

function TO.error_expansion!(solver::ConstrainedSolver)
    error_expansion_uncon!(solver)
    conSet = get_constraints(solver)
    G = get_error_state_jacobians(solver)
    error_expansion!(conSet, get_model(solver), G)
end

#--- Gradient Norm ---#
function norm_grad(solver::UnconstrainedSolver, recalculate::Bool=true)
    if recalculate
        cost_expansion!(solver)
    end
    norm_grad(get_cost_expansion(solver))
end

function norm_grad(solver::ConstrainedSolver, recalculate::Bool=true)
    conSet = get_constraints(solver)
    if recalculate
        cost_expansion!(solver)
        jacobian
    end
    norm_grad(get_cost_expansion(solver))
end

#--- Rollout ---#
function rollout!(solver::AbstractSolver)
    Z = get_trajectory(solver)
    model = get_model(solver)
    x0 = get_initial_state(solver)
    rollout!(integration(solver), model, Z, x0)
end

TO.states(solver::AbstractSolver) = [state(z) for z in get_trajectory(solver)]
function TO.controls(solver::AbstractSolver)
    N = size(solver)[3]
    Z = get_trajectory(solver)
    [control(Z[k]) for k = 1:N-1]
end

TO.set_initial_state!(solver::AbstractSolver, x0) = copyto!(get_initial_state(solver), x0)

@inline TO.initial_states!(solver::AbstractSolver, X0) = RobotDynamics.set_states!(get_trajectory(solver), X0)
@inline TO.initial_controls!(solver::AbstractSolver, U0) = RobotDynamics.set_controls!(get_trajectory(solver), U0)
function TO.initial_trajectory!(solver::AbstractSolver, Z0::Traj)
    Z = get_trajectory(solver)
    for k in eachindex(Z)
        RobotDynamics.set_z!(Z[k], Z0[k].z)
    end
end

# Default getters
@inline RobotDynamics.get_times(solver::AbstractSolver) =
    RobotDynamics.get_times(get_trajectory(solver))

# Line Search and Merit Functions
"""
    get_primals(solver)
    get_primals(solver, α::Real)

Get the primal variables used during the line search. When called without an `α` it should
return the container where the temporary primal variables are stored. When called with a
step length `α` it returns `z + α⋅dz` where `z = get_solution(solver)` and `dz = get_step(solver)`.
"""
function get_primals(solver::AbstractSolver, α)
    z = get_solution(solver)
    z̄ = get_primals(solver)
    dz = get_step(solver)
    z̄ .= z .+ α*dz
end

# Constrained solver
TO.num_constraints(solver::AbstractSolver) = num_constraints(get_constraints(solver))

function TO.max_violation(solver::ConstrainedSolver, Z::Traj=get_trajectory(solver); recalculate=true)
    conSet = get_constraints(solver)
    if recalculate
        TO.evaluate!(conSet, Z)
    end
    TO.max_violation(conSet)
end

function TO.norm_violation(solver::ConstrainedSolver, Z::Traj=get_trajectory(solver); recalculate=true, p=2)
    conSet = get_constraints(solver)
    if recalculate
        evaluate!(conSet, Z)
    end
    TO.norm_violation(conSet, p)
end

@inline TO.findmax_violation(solver::ConstrainedSolver) =
    TO.findmax_violation(get_constraints(solver))

function second_order_correction!(solver::ConstrainedSolver)
    conSet = get_constraints(solver)
	Z = get_primals(solver)     # get the current value of z + α⋅δz
	evaluate!(conSet, Z)        # update constraints at new step
	throw(ErrorException("second order correction not implemented yet..."))
end

"""
	cost_dgrad(solver, Z, dZ; recalculate)

Return the scalar directional gradient of the cost evaluated at `Z` in the direction of `dZ`,
where `Z` and `dZ` are the types returned by `get_primals(solver)` and `get_step(solver)`,
and must be able to be converted to a vector of `KnotPoint`s via `Traj()`.
"""
function cost_dgrad(solver::AbstractSolver, Z=get_primals(solver), dZ=get_step(solver);
		recalculate=true)
	E = get_cost_expansion(solver)
	if recalculate
		obj = get_objective(solver)
		cost_gradient!(E, obj, Traj(Z))
	end
	TO.dgrad(E, Traj(dZ))
end

"""
	norm_dgrad(solver, Z, dZ; recalculate, p)

Calculate the directional derivative of `norm(c(Z), p)` in the direction of `dZ`, where
`c(Z)` is the vector of constraints evaluated at `Z`.
`Z` and `dZ` are the types returned by `get_primals(solver)` and `get_step(solver)`,
and must be able to be converted to a vector of `KnotPoint`s via `Traj()`.
"""
function norm_dgrad(solver::AbstractSolver, Z=get_primals(solver), dZ=get_step(solver);
		recalculate=true, p=1)
    conSet = get_constraints(solver)
	if recalculate
		Z_ = Traj(Z)
		evaluate!(conSet, Z_)
		jacobian!(conSet, Z_)
	end
    Dc = TO.norm_dgrad(conSet, Traj(dZ), 1)
end

"""
	dhess(solver, Z, dZ; recalculate)

Calculate the scalar 0.5*dZ'G*dZ where G is the hessian of cost, evaluating the cost hessian
at `Z`.
"""
function cost_dhess(solver::AbstractSolver, Z=TO.get_primals(solver),
		dZ=TO.get_step(solver); recalculate=true)
	E = get_cost_expansion(solver)
	if recalculate
		obj = get_objective(solver)
		cost_hessian!(E, obj, Traj(Z))
	end
	TO.dhess(solver.E, Traj(dZ))
end

# Logging
log_level(solver::AbstractSolver) = OuterLoop

is_verbose(solver::AbstractSolver) =
    log_level(solver) >= LogLevel(-100*options(solver).verbose)

function set_verbosity!(solver::AbstractSolver)
    llevel = log_level(solver)
    if is_verbose(solver)
        set_logger()
        Logging.disable_logging(LogLevel(llevel.level-1))
    else
        Logging.disable_logging(llevel)
    end
end

function clear_cache!(solver::AbstractSolver)
    llevel = log_level(solver)
    if is_verbose(solver)
        SolverLogging.clear_cache!(global_logger().leveldata[llevel])
    end
end


text:
using PregnancyCoagDataAnalysisKit
using Test

# default test -
function default_test()::Bool
    return true
end

@testset "default_test_set" begin
    @test default_test() == true
end

max_stars_repo_name: varnerlab/PregnancyCoagDataAnalysisKit

max_issues_repo_name: varnerlab/PregnancyCoagDataAnalysisKit

max_forks_repo_name: varnerlab/PregnancyCoagDataAnalysisKit


text:
using memoJuliaClassJa
using Documenter

## Adopted from docs/make.jl in Documenter.jl
# The DOCSARGS environment variable can be used to pass additional arguments to make.jl.
# This is useful on CI, if you need to change the behavior of the build slightly but you
# can not change the .travis.yml or make.jl scripts any more (e.g. for a tag build).
if haskey(ENV, "DOCSARGS")
    for arg in split(ENV["DOCSARGS"])
        (arg in ARGS) || push!(ARGS, arg)
    end
end

makedocs(
    modules=[memoJuliaClassJa],
    authors="Hiroharu Sugawara <hsugawa@gmail.com>",
    clean = false,
    sitename="memoJuliaClassJa.jl",
    format=Documenter.HTML(;
        prettyurls=get(ENV, "CI", "false") == "true",
        canonical="https://hsugawa8651.github.io/memoJuliaClassJa.jl/stable/",
        assets=String[],
    ),
    linkcheck = !("skiplinks" in ARGS),
    linkcheck_ignore = [
        # timelessrepo.com seems to 404 on any CURL request...
        "http://timelessrepo.com/json-isnt-a-javascript-subset",
        # We'll ignore links that point to GitHub's edit pages, as they redirect to the
        # login screen and cause a warning:
        r"https://github.com/([A-Za-z0-9_.-]+)/([A-Za-z0-9_.-]+)/edit(.*)",
    ] ∪ (get(ENV, "GITHUB_ACTIONS", nothing)  == "true" ? [
        # Extra ones we ignore only on CI.
        #
        # It seems that CTAN blocks GitHub Actions?
        "https://ctan.org/pkg/minted",
    ] : []),
    pages= [
	"Home" => "index.md",
		"LICENSE.md",
		"LICENSEja.md",
		"ch00.md",
		"ch01.md",
		"ch02.md",
		"ch03.md",
		"ch04.md",
		"ch05.md",
		"ch06.md",
		"ch07.md",
		"ch08.md",
		"ch09.md",
		"ch10.md",
		"ch11.md",
		"ch12.md",
		"ch13.md",
		"porting.md"
	],
   # strict = !("strict=false" in ARGS),
   doctest = ("doctest=only" in ARGS) ? :only : true,
)

deploydocs(
    repo="github.com/hsugawa8651/memoJuliaClassJa.jl.git",
    devbranch="develop",
    push_preview = true,
)