text:
#using AvailablePotentialEnergyFramework
#using NCDatasets
#using Statistics
#using JLD
#using Unitful: ustrip

"""
    getapeanalysis(file2d,file3d,output_name,outputInterval,FloatType::Type=Float64)

"""
function testAPEBudget()
file2d = "/Users/arreyes/Documents/Research/Developement/testNetCDF/timeSlab_2d.nc"
file3d = "/Users/arreyes/Documents/Research/Developement/testNetCDF/timeSlab_3d.nc"

Float_type = Float32

    day           = 86400
    sst           = 300
    dt            = 14400
    Pref          = 1000*1e2                 #Pa
    Ts            = sst                      #Sea surface temperature
    qs            = 25.7*1e-3
    Tvs           = Ts*(1+epsilon*qs)
    c1            = ustrip(Dryair.R/Dryair.cp)

    ds3d                = Dataset(file3d)
    ds2d                = Dataset(file2d)
    x                   = variable(ds3d,"x")[:]    :: Array{Float_type,1}
    y                   = variable(ds3d,"y")[:]    :: Array{Float_type,1}
    z                   = variable(ds3d,"z")[:]    :: Array{Float_type,1}
    t                   = variable(ds3d,"time")[:] :: Array{Float_type,1}
    P0                  = variable(ds3d,"p")[:]    :: Array{Float_type,1}
    U                   = variable(ds3d,"U")[:,:,:,:] :: Array{Float_type,4}
    V                   = variable(ds3d,"V")[:,:,:,:] :: Array{Float_type,4}
    W                   = variable(ds3d,"W")[:,:,:,:] :: Array{Float_type,4}
    RAD                 = variable(ds3d,"QRAD")[:,:,:,:] :: Array{Float_type,4}
    T                   = variable(ds3d,"TABS")[:,:,:,:] :: Array{Float_type,4}
    Tv                  = variable(ds3d,"QV")[:,:,:,:] :: Array{Float_type,4}
    PP                  = variable(ds3d,"PP")[:,:,:,:] :: Array{Float_type,4}
    SHF                 = variable(ds2d,"SHF")[:,:,:] :: Array{Float_type,3}
    LHF                 = variable(ds2d,"LHF")[:,:,:] :: Array{Float_type,3}
    close(ds3d)
    close(ds2d)

    ########## FilFloat_Typeering and chopping ##########

    @. SHF    = ustrip(g)/(1*ustrip(Dryair.cp)*Ts)*(SHF)
    @. LHF    = ustrip(g)/(1*ustrip(Dryair.cp)*Ts)*(epsilon*ustrip(Dryair.cp)*Ts/ustrip(Liquidwater.Lv*LHF))
    @. SHF    +=  LHF     # Now it is transformed

    ThetaV       = similar(T)
    xBar_Pt      = Array{eltype(T),4}(undef,1,1,size(PP,3),size(PP,4))
    xBar_Tv      = Array{eltype(T),4}(undef,1,1,size(Tv,3),size(Tv,4))
    xBar_ThetaV  = Array{eltype(T),4}(undef,1,1,size(ThetaV,3),size(ThetaV,4))
    #******
    dx           = x[2]-x[1]
    dy           = y[2]-y[1]                            # Grid size
    kz           = length(z)                            # vertical levels
    kx           = length(x)                            # # of horizonal grid points
    ky           = length(y)                            # # of horizonal grid points
    @.  RAD      = RAD/day                              # K/s #Heating rate per second;
    @.  Tv       = get_virtual_temperature.(T,Tv)#(1 + 1e-3*epsilon*Tv)*T              # Virtual temperature
    @.  P0       = P0*1e2
    PP          .= PP .+ reshape(P0,(1,1,kz,1))
    #ThetaV      .= Tv.*(PP./reshape(P0,(1,1,kz,1))).^c1 # Virtual potential temp
    ThetaV      .= get_potential_temperature.(Tv,PP,P0[1]) #Tv.*(PP/P0[1]).^c1 # Virtual potential temp
    mean!(xBar_Pt,PP)
    mean!(xBar_Tv,Tv)
    mean!(xBar_ThetaV,ThetaV)
    var_Tv       =  Tv     .- xBar_Tv
    var_ThetaV   =  ThetaV .- xBar_ThetaV
    rho0         = xBar_Pt./ustrip(Dryair.R)./xBar_Tv
    B            = ustrip(g) .* var_ThetaV./xBar_ThetaV
    @. RAD       = RAD*(ustrip(g)/xBar_Tv)                    # convert unit to buoyancy/s

    N2           = compute_N2(xBar_Tv,z)

    # PP           = []
    # T          = []
    # ThetaV     = []
    # Tv         = []
    # var_ThetaV = []
    # var_Tv     = []

    ### NOTE that SHF is now the sum, saving memory
    # Buoyancy budget
    dz          = 50
    #@info size(B), size(RAD), size(SHF), size(U),size(V) ,size(W), size(N2), size(dx),size(dy), size(dz), size(dt), size(x),size(y), size(z), size(t)
    #    dBdt, UdBdx,VdBdy, WN2, Qs, Diabatic_other = buoyancybudget(B, RAD, SHF, U,V ,W, N2, dx,dy, dz, dt, x,y, z, t);
    Diabatic_other = get_diabatic_as_residual_buoyancy(B, RAD, SHF, U,V ,W, N2, dx,dy, dz, dt);
    @info "hola"

    # APE budget
    z_up        = 15000
    z_BL        = 2000

        (int_mass,
     int_KE,
     int_APE,
     int_APE_rate,
     int_APE_Ub2,
     int_APE_Vb2,
     int_APE_WN2,
     int_APE_RAD,
     int_APE_DIA,
     xBar_APE_Fs,
     residual) = getapebudget(B, U,V, W, N2, RAD, SHF, Diabatic_other, rho0, x,y, z, t, dx,dy, dz, dt, z_up)

    # Diabatic_other .= Diabatic_other .- mean(Diabatic_other,dims=(1,2)) #They are now perturbations
    # RAD            .= RAD .- mean(RAD,dims=(1,2))
    # B              .= B .- mean(B,dims=(1,2))

    # dia_ape = Diabatic_other.*B
    # rad_ape = RAD.*B

    # jldopen(string("outputfile.jld"), "w") do file
    #     write(file,"int_APE",int_APE)
    #     write(file,"int_KE",int_KE)
    #     write(file,"int_RAD",int_APE_RAD)
    #     write(file,"int_DIA",int_APE_DIA)
    #     write(file,"int_WN2",int_APE_WN2)
    #     write(file,"int_Ub2",int_APE_Ub2)
    #     write(file,"int_Vb2",int_APE_Vb2)
    #     write(file,"int_APE_rate",int_APE_rate)
    #     write(file,"APE_Fs",xBar_APE_Fs)
    #     write(file,"convec_heating_anomaly",Diabatic_other)
    #     write(file,"rad_heating_anomaly",RAD)
    #     write(file,"buoyancy_anomaly",B)
    #     write(file,"radiative_ape_production",dia_ape)
    #     write(file,"convective_ape_production",rad_ape)
    # end

end

# """
#     getapeanalysis(file2d,file3d,output_name,outputInterval,FloatType::Type=Float64)

# """
# function testAPEBudget_distributed()

#     file2d = "/Users/arreyes/Documents/Research/Developement/testNetCDF/timeSlab_2d.nc"
#     file3d = "/Users/arreyes/Documents/Research/Developement/testNetCDF/timeSlab_3d.nc"

#     Float_type = Float32

#     day           = 86400
#     sst           = 300
#     dt            = 14400
#     Pref          = 1000*1e2                 #Pa
#     Ts            = sst                      #Sea surface temperature
#     qs            = 25.7*1e-3
#     Tvs           = Ts*(1+epsilon*qs)
#     c1            = (R/Dryair.cp)

#     # ds3d                = Dataset(file3d)
#     # ds2d                = Dataset(file2d)
#     # x                   = variable(ds3d,"x")[:]    :: Array{Float_type,1}
#     # y                   = variable(ds3d,"y")[:]    :: Array{Float_type,1}
#     # z                   = variable(ds3d,"z")[:]    :: Array{Float_type,1}
#     # t                   = variable(ds3d,"time")[:] :: Array{Float_type,1}
#     # P0                  = variable(ds3d,"p")[:]    :: Array{Float_type,1}
#     # U                   = variable(ds3d,"U")[:,:,:,:] :: Array{Float_type,4}
#     # V                   = variable(ds3d,"V")[:,:,:,:] :: Array{Float_type,4}
#     # W                   = variable(ds3d,"W")[:,:,:,:] :: Array{Float_type,4}
#     # RAD                 = variable(ds3d,"QRAD")[:,:,:,:] :: Array{Float_type,4}
#     # T                   = variable(ds3d,"TABS")[:,:,:,:] :: Array{Float_type,4}
#     # Tv                  = variable(ds3d,"QV")[:,:,:,:] :: Array{Float_type,4}
#     # PP                  = variable(ds3d,"PP")[:,:,:,:] :: Array{Float_type,4}
#     # SHF                 = variable(ds2d,"SHF")[:,:,:] :: Array{Float_type,3}
#     # LHF                 = variable(ds2d,"LHF")[:,:,:] :: Array{Float_type,3}
#     # close(ds3d)
#     # close(ds2d)

#     smooth_x      = smooth_y = 15 #it was 11
#     smooth_time   = floor(Int,12*5)+1
#     position = 2

#     sx  = sy = 100
#     sz  = 80
#     st  = 120
#     dx  = dy = 1000
#     dz  = 50
#     dt  = 7200

#     x   = y = collect(range(0,step = dx,length=sx));
#     z   = collect(range(0, step = dz,length = sz));
#     t   = collect(range(0, step = dt, length = st));

#     P0  = 1000*exp.(z./8000);
#     U   = V = 5.0rand(sx,sy,sz,st);
#     W   = 0.2rand(sx,sy,sz,st);
#     RAD = rand(sx,sy,sz,st);;
#     T   = 300 .+ rand(sx,sy,sz,st);
#     Tv  = 0.2rand(sx,sy,sz,st);
#     PP  = rand(sx,sy,sz,st);
#     SHF = rand(sx,sy,st);
#     LHF = rand(sx,sy,st);
#     B   = similar(RAD);
#     ########## smoothing  and chopping ##########

# @info "Smoothing batch 1"
#     fU   = @spawnat 2 cutborders!(filter_array(U,smooth_x,smooth_time,1),smooth_time,position)
#     U = fetch(fU)
#     fV   = @spawnat 3 cutborders!(filter_array(V,smooth_x,smooth_time,1),smooth_time,position)
#     V = fetch(fV)
#     fW   = @spawnat 2 cutborders!(filter_array(W,smooth_x,smooth_time,1),smooth_time,position)
#     W = fetch(fW)
#     fTv  = @spawnat 3 cutborders!(filter_array(Tv,smooth_x,smooth_time,1),smooth_time,position)
#     Tv = fetch(fTv)

#     fetch(@spawnat 2 GC.gc())
#     fetch(@spawnat 3 GC.gc())

#     @info "smoothing batch 2"
#     fT   = @spawnat 2 cutborders!(filter_array(T,smooth_x,smooth_time,1),smooth_time,position)
#     fPP  = @spawnat 3 cutborders!(filter_array(PP,smooth_x,smooth_time,1),smooth_time,position)
#     fRAD = @spawnat 3 cutborders!(filter_array(RAD,smooth_x,smooth_time,1),smooth_time,position)
#     SHF = cutborders!(filter_array(SHF,smooth_x,smooth_time,1),smooth_time,position)
#     LHF = cutborders!(filter_array(LHF,smooth_x,smooth_time,1),smooth_time,position)
#     t = cutborders!(t,smooth_time,position)

#     T = fetch(fT)
#     PP = fetch(fPP)
#     RAD = fetch(fRAD)
#     fetch(@spawnat 2 GC.gc())
#     fetch(@spawnat 3 GC.gc())

#     GC.gc()
#     GC.gc()

#     ## Processing

#     @info "Beginning processing"

#     @. SHF    = g/(1*Dryair.cp*Ts)*(SHF)
#     @. LHF    = g/(1*Dryair.cp*Ts)*(epsilon*Dryair.cp*Ts/Liquidwater.Lv*LHF)
#     @. SHF    +=  LHF     # Now it is transformed

#     ThetaV       = similar(T)
#     xBar_Pt      = Array{eltype(T),4}(undef,1,1,size(PP,3),size(PP,4))
#     xBar_Tv      = Array{eltype(T),4}(undef,1,1,size(Tv,3),size(Tv,4))
#     xBar_ThetaV  = Array{eltype(T),4}(undef,1,1,size(ThetaV,3),size(ThetaV,4))
#     #******
#     dx           = x[2]-x[1]
#     dy           = y[2]-y[1]                            # Grid size
#     kz           = length(z)                            # vertical levels
#     kx           = length(x)                            # # of horizonal grid points
#     ky           = length(y)                            # # of horizonal grid points
#     @.  RAD      = RAD/day                              # K/s #Heating rate per second;
#     @.  Tv       = (1 + 1e-3*epsilon*Tv)*T              # Virtual temperature
#     @.  P0       = P0*1e2
#     PP          .= PP .+ reshape(P0,(1,1,kz,1))
#     #ThetaV      .= Tv.*(PP./reshape(P0,(1,1,kz,1))).^c1 # Virtual potential temp
#     ThetaV      .= Tv.*(PP/P0[1]).^c1 # Virtual potential temp
#     mean!(xBar_Pt,PP)
#     mean!(xBar_Tv,Tv)
#     mean!(xBar_ThetaV,ThetaV)
#     var_Tv       =  Tv     .- xBar_Tv
#     var_ThetaV   =  ThetaV .- xBar_ThetaV
#     rho0         = dropdims(xBar_Pt./R./xBar_Tv,dims=(1,2))
#     B            = g .* var_ThetaV./xBar_ThetaV
#     @. RAD       = RAD*(g/xBar_Tv)                    # convert unit to buoyancy/s

#     N2           = compute_N2(xBar_Tv,z)

#     # PP           = []
#     # T          = []
#     # ThetaV     = []
#     # Tv         = []
#     # var_ThetaV = []
#     # var_Tv     = []

#     ### NOTE that SHF is now the sum, saving memory
#     # Buoyancy budget
#     dz          = 50
#     #@info size(B), size(RAD), size(SHF), size(U),size(V) ,size(W), size(N2), size(dx),size(dy), size(dz), size(dt), size(x),size(y), size(z), size(t)
#     @info "Computing buoyancy"
#      Diabatic_other = fetch(@spawnat 3  get_diabatic_as_residual_buoyancy(B, RAD, SHF, U,V ,W, N2, dx,dy, dz, dt, x,y, z, t))
#     fetch(@spawnat 3 GC.gc())

#     # APE budget
#     z_up        = 15000
#     z_BL        = 2000
#     @info "Computing APE budget"
#         (int_mass,
#      int_KE,
#      int_APE,
#      int_APE_rate,
#      int_APE_Ub2,
#      int_APE_Vb2,
#      int_APE_WN2,
#      int_APE_RAD,
#      int_APE_DIA,
#      xBar_APE_Fs,
#          residual) = fetch( @spawnat 3 getapebudget(B, U,V, W, N2, RAD, SHF, Diabatic_other, rho0, x,y, z, t, dx,dy, dz, dt, z_up))
#     fetch(@spawnat 3 GC.gc())

#     Diabatic_other .= Diabatic_other .- mean(Diabatic_other,dims=(1,2)) #They are now perturbations
#     RAD            .= RAD .- mean(RAD,dims=(1,2))
#     B              .= B .- mean(B,dims=(1,2))

#     dia_ape = Diabatic_other.*B
#     rad_ape = RAD.*B

#     # plot([int_APE_rate,
# #     int_APE_Ub2,
# #     int_APE_Vb2,
# #     int_APE_WN2,
# #     int_APE_RAD,
# #     int_APE_DIA,
# #     xBar_APE_Fs],label=["rate" "advu" "advv" "wn2" "rad" "dia" "fs" ])
# # plot!(residual,lw=4,label="residual")
#     return true
# end

# @test  testAPEBudget_distributed()

# """
#      run_distributed_test()
# Don't forget to first run: \n
# addprocs(2) \n
# @everywhere using Pkg \n
# @everywhere Pkg.activate("/users/arreyes/Documents/Research/Developement/AvailablePotentialEnergyFramework/") \n
# @everywhere using AvailablePotentialEnergyFramework \n
# """
# function run_distributed_test()
#     @info """ Don't forget to first run: \n
#     addprocs(2) \n
#     @everywhere using Pkg \n
#     @everywhere Pkg.activate("/users/arreyes/Documents/Research/Developement/AvailablePotentialEnergyFramework/") \n
#     @everywhere using AvailablePotentialEnergyFramework \n
# """
#     for i in 1:10
#         @info "Running ape budget, this is the $i iteration"
#         testAPEBudget_distributed()
#     end
# end


text:
function testplotdata()
  (g1,junk) = groupfortests()
  pd = FastHenryHelper.plotdata(g1)
  @test pd.title == "Test Title"
  @test pd.x ≈ [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,2.54e-7,2.54e-7,0.0,
    0.0,0.0,2.54e-7,2.54e-7,0.0,0.0,2.54e-7,2.54e-7,2.54e-7,2.54e-7,0.0,0.0,
    2.54e-8,1.016e-7,-1.5e-9,-1.5e-9,1.5e-9,1.5e-9,-1.5e-9,-1.5e-9,-1.5e-9,
    1.5e-9,1.5e-9,-1.5e-9,-1.5e-9,-1.5e-9,1.5e-9,1.5e-9,1.5e-9,1.5e-9]
  @test pd.y ≈ [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,2.54e-7,2.54e-7,
    0.0,0.0,0.0,2.54e-7,2.54e-7,0.0,0.0,0.0,2.54e-7,2.54e-7,2.54e-7,2.54e-7,
    5.08e-8,1.27e-7,-2.54e-8,2.54e-8,2.54e-8,-2.54e-8,-2.54e-8,-2.54e-8,
    2.54e-8,2.54e-8,-2.54e-8,-2.54e-8,2.54e-8,2.54e-8,2.54e-8,2.54e-8,
    -2.54e-8,-2.54e-8]
  @test pd.z ≈ [1.0,0.001,1.0e-5,1.0e-6,1.0e-9,2.54e-5,2.54e-8,
    -1.27e-8,-1.27e-8,-1.27e-8,-1.27e-8,-1.27e-8,1.27e-8,1.27e-8,1.27e-8,
    1.27e-8,1.27e-8,-1.27e-8,1.27e-8,-1.27e-8,1.27e-8,-1.27e-8,1.27e-8,0.0,
    0.0,1.0e-5,1.0e-5,1.0e-5,1.0e-5,1.0e-5,1.0e-6,1.0e-6,1.0e-6,1.0e-6,
    1.0e-6,1.0e-5,1.0e-6,1.0e-5,1.0e-6,1.0e-5,1.0e-6]
  @test pd.group == [1,2,3,4,5,6,7,8,8,8,8,8,8,8,8,8,8,9,9,10,10,11,11,12,13,
    14,14,14,14,14,14,14,14,14,14,15,15,16,16,17,17]
  @test pd.marker == [:circle,:circle,:circle,:circle,:circle,:circle,:circle,
    :none,:none,:none,:none,:circle,:circle,:none,:none,:none,:none]
  @test pd.markercolor == [:red,:red,:red,:red,:red,:red,:red,:red,:red,:red,
    :red,:green,:green,:red,:red,:red,:red]
  @test pd.markeralpha == [0.3,0.3,0.3,0.3,0.3,0.3,0.3,0.3,0.3,0.3,0.3,0.3,0.3,
    0.3,0.3,0.3,0.3]
  @test pd.markersize == [3.0,3.0,3.0,3.0,3.0,3.0,3.0,3.0,3.0,3.0,3.0,3.0,3.0,
    3.0,3.0,3.0,3.0]
  @test pd.markerstrokewidth == [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]
  @test pd.linecolor == [:blue,:blue,:blue,:blue,:blue,:blue,:blue,:green,
    :green,:green,:green,:green,:green,:blue,:blue,:blue,:blue]

  FastHenryHelper.pointsatlimits!(pd)
  @test pd.x[end-1:end] ≈ [0.5000001326,-0.49999988009999996]
  @test pd.y[end-1:end] ≈ [0.50000012065,-0.49999989204999995]
  @test pd.z[end-1:end] ≈ [1.0,-1.2699999996090838e-8]
  @test pd.group[end-1:end] == [18,19]
  @test pd.markeralpha[end-1:end] == [0.0,0.0]
  @test pd.markersize[end-1:end] == [0.0,0.0]
  @test pd.markerstrokewidth[end-1:end] == [0.0,0.0]
end
testplotdata()

function testplot()
  inductor = coilcraft1010vsgroup("1010VS-111ME")
  pd = FastHenryHelper.plotdata(inductor)
  FastHenryHelper.pointsatlimits!(pd)
end
testplot()

ext: jl


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

using Markdown
using InteractiveUtils

# This Pluto notebook uses @bind for interactivity. When running this notebook outside of Pluto, the following 'mock version' of @bind gives bound variables a default value (instead of an error).
macro bind(def, element)
    quote
        local el = $(esc(element))
        global $(esc(def)) = Core.applicable(Base.get, el) ? Base.get(el) : missing
        el
    end
end

# ╔═╡ 5e970055-1076-4841-9d2b-ec75e7142a41
using PlutoUI

# ╔═╡ db2292c8-d3f0-459c-b478-1e95ccab863c
begin
	using HypertextLiteral: JavaScript

	_transfer_data(data) = if isdefined(Main, :PlutoRunner) && isdefined(Main.PlutoRunner, :publish_to_js)
		# faster data transfer using MsgPack if available
		JavaScript(Main.PlutoRunner.publish_to_js(data))
	else
		data
	end
end

# ╔═╡ 3ffae4f4-ee7d-4207-a37c-f759292be96e
using CommonMark

# ╔═╡ f644142d-4146-43c0-8049-fb345282b31a
using HypertextLiteral

# ╔═╡ 227285cb-0f4a-47ba-9037-143307d6f691
cm"""
# Welcome to Pluto.jl!

How can you use this notebook? 🔎 For a basic summary see [this wiki entry](https://github.com/fonsp/Pluto.jl/wiki/%F0%9F%94%8E-Basic-Commands-in-Pluto.)
"""

# ╔═╡ 67dcf398-fc6a-4963-a390-d3dcfc69ea8d
"the " * "result" * " appears on the top ↑↑↑"

# ╔═╡ a6741b19-d378-4279-a1e4-70c18eb20cb5
x = 10 # definitions create dependencies

# ╔═╡ 415fd393-eca0-4630-9be5-8a8265560b0d
y = x * x  # try changing `x` and see what happens

# ╔═╡ f31bc6f0-4fd6-444f-89df-8680deea986d
sin(y)  # open the Live docs on the right, then click onto `sin`

# ╔═╡ 11c03bd1-8752-4b9d-a3c5-203fb7a5872f
cm"""Task: drag and drop the cells above to change their order"""

# ╔═╡ 396eb8cb-43cf-4c39-9610-b3e107b1e9dc
cm"""
## Keyboard Shortcuts

> `Shift+Enter`\- run cell
>
> `Ctrl+Enter`\- run cell and add cell below
>
> `Tab`\- show autocomplete
>
> `F1`\- show keyboard shortcuts
>
> The full list is [here](https://github.com/fonsp/Pluto.jl/issues/65#issue-595782206)
"""

# ╔═╡ d055e80b-6efb-4f78-9506-a886139598d9
cm"""## Caution with Mutation"""

# ╔═╡ 7fce21a5-9e97-44ce-b76a-5711fb62cd3b
cm""" only mutate/change variables in the very cell it was defined """

# ╔═╡ 68701cb6-71e9-4853-a8e8-7cbcaaaf234b
n_yesterday = 0

# ╔═╡ b4d2b9a0-a4a5-4c14-9092-93b0570628dd
begin
    n_today = n_yesterday
    n_today += 3
    n_today *= 2
end

# ╔═╡ cc8c129e-c955-414c-a415-a1879152a007
m_yesterday = Ref(0)

# ╔═╡ 618a2046-573e-4d44-9dba-5800951994cd
m_yesterday[] += 3

# ╔═╡ 2e4084dd-acf1-4350-95b3-f0e77cb28953
m_yesterday[] *= 2

# ╔═╡ 3c029c7f-752f-4c99-b465-2c19675d1732
cm"""# Interactivity"""

# ╔═╡ 788c2f4b-1679-4b2b-adc7-21f26e0fd277
cm"""
## Simple Interactivity
"""

# ╔═╡ 506ddcb3-c9eb-4e23-8a01-040b4103487e
cm"""
fix the following definition so that `z = 2x + y`
"""

# ╔═╡ c367af42-71ef-4401-93bd-d2ade01606f5
z = 3

# ╔═╡ 8ea36f83-4110-4505-b2e4-8a29c68f5560
cm"""## `@bind` Interactivity

Pluto comes with `@bind` which enables you to link html input elements to julia variables.
"""

# ╔═╡ 306f0d0a-5151-4ea6-9eb2-1a7d700118f2
@bind yourrange html"<input type=range >"

# ╔═╡ b103e55f-0d03-404c-a574-f116cf878ab6
yourrange

# ╔═╡ 4ad1bae8-ba32-4060-b06a-a1e109cd06fa
md"""
`a = ` $(@bind a html"<input type=range >")

`b = ` $(@bind b html"<input type=text >")

`c = ` $(@bind c html"<input type=button value='Click'>")

`d = ` $(@bind d html"<input type=checkbox >")

`e = ` $(@bind e html"<select><option value='one'>First</option><option value='two'>Second</option></select>")

`f = ` $(@bind f html"<input type=color >")
"""

# ╔═╡ 053a6e13-cfa7-431e-84cf-0839c8250f97
(a, b, c, d, e, f)

# ╔═╡ 780677dd-cf4c-46f8-b9dc-37a12a288242
cm"""
## PlutoUI

PlutoUI gives you a couple of useful helper functions.
"""

# ╔═╡ addf17dd-be2f-4cdc-952d-115061506532
@bind yourslider Slider(1:10, default=3, show_value=true)

# ╔═╡ 7f1fc43b-3f40-4d5b-ba2b-71916ff9b436
yourslider

# ╔═╡ 42e94190-dbae-46d3-9257-bf3318f65b9d
md"""comment and uncomment the following line"""

# ╔═╡ cdf7ba93-ec68-4f36-a650-def062ba61f4
TableOfContents()

# ╔═╡ 227c49cb-e986-45a6-89be-5558fcf3dba1
cm"""**Explore many more PlutoUI objects:**

1. copy the url `https://raw.githubusercontent.com/fonsp/Pluto.jl/main/sample/PlutoUI.jl.jl`
2. right-click on the Pluto logo at the very top, and click "open link in new tab"
3. In the Pluto main window paste the url in the textfield "open from file"
"""

# ╔═╡ 59fd9fa6-23a0-4ca5-97ce-091c5c74268d
md"""
## Custom JavaScript
"""

# ╔═╡ c7c8c86d-2de2-4862-9899-e63b78d24d29
@bind dims htl"""
<canvas width="200" height="200" style="position: relative"></canvas>

"""

# ╔═╡ e458f2cc-cd31-4e32-83c1-3cfec6b89a6e
dims

# ╔═╡ 37415d7a-4737-46ac-9f16-44d81ccc8793
begin
	ClickCounter(text="Click") = @htl("""

	<button>$(text)</button>

	""")

	@bind num_clicks ClickCounter("Click me")
end

# ╔═╡ 177bf468-c5f4-4b01-87c0-97a56f1e3109
num_clicks

# ╔═╡ 73840820-f592-4682-a3d4-de500c0669ae
cm"""**Advanced:** Transfer data from julia to javascript without copying."""

# ╔═╡ 93a0f206-77f0-4563-bfda-39b6571c39e8
my_data = (startX = 10, startY = 20)

# ╔═╡ 37c9fae8-0982-4026-83ac-0f913188a2bd
@bind dims_my_data htl"""
<canvas width="200" height="200" style="position: relative"></canvas>

"""

# ╔═╡ 40a43215-70b0-4d10-aee6-ddc7a4ce1257
dims_my_data

# ╔═╡ 9d7c3d14-e0e5-43bc-99e7-81774bf325fe
cm"""# Markdown and HTML"""

# ╔═╡ 354694a6-f889-439f-8fec-ca7822ec63c3
cm"""## Better CommonMark.jl instead of Markdown.jl"""

# ╔═╡ df3301c4-196f-4ee1-bdf4-c81c71a1104e
cm"""Standard julia markdown `md"some markdown"` can behave in surprising and undesired ways"""

# ╔═╡ feae1368-a19d-4f0c-96b9-7081b593037a
var = 1

# ╔═╡ dfe2781e-ca0e-4cce-a1a0-34c3e913ece6
md"$(var) value is has newline. But next inline use of $(var) works as expected"

# ╔═╡ 7b9093a2-842b-4f65-bb35-57cf151d91f5
cm"""some more surprising behaviours"""

# ╔═╡ ef887980-c97d-41f1-954a-9783c0775654
md"""
$(1 + 1) $(1 + 1)

$(1 + 1)$(1 + 1)

 $(1 + 1) $(1 + 1)

 $(1 + 1)$(1 + 1)
"""

# ╔═╡ 5d1d2a4d-84f2-4bfa-bf15-e3698bb27b39
cm"""**The solution:** Using `cm"some markdown"` from the package CommonMark.jl"""

# ╔═╡ b4a00d0c-34f0-4d06-9f65-64b4a764a3f8
cm"
$(1 + 1) $(1 + 1)

$(1 + 1)$(1 + 1)

 $(1 + 1) $(1 + 1)

 $(1 + 1)$(1 + 1)
"

# ╔═╡ 414a0d99-85b3-4025-8631-2310d07a7116
cm"""## Better HypertextLiteral.jl than Html"""

# ╔═╡ d45cd163-62ab-4319-b6e5-1d3a6b4aa791
cm"""With `html"..."` string-macro you cannot use standard interpolation"""

# ╔═╡ 799cc47b-9a65-4990-92ad-07b745341559
who = "😽"

# ╔═╡ 213c5b06-6125-4e8d-90e5-f6356a1deeb5
html"""

Hello $(who)!

"""

# ╔═╡ cc5aae01-9279-4cab-9ca7-45ecd7d09d29
cm"""**The solution:** Use `htl"..."` from the package HypertextLiteral.jl instead:"""

# ╔═╡ b908a9bf-6901-4a69-ba9e-a6ceff20fd9d
htl"""

 Hello $(who)!

"""

# ╔═╡ 732d4457-55c2-408c-a2c9-bf1b50ac5fbc
cool_features = [
	cm"Interpolate any **HTML-showable object**, such as plots and images, or another `@htl` literal."
	cm"Interpolated lists are expanded _(like in this cell!)_."
	"Easy syntax for CSS"
]

# ╔═╡ f753db9b-dcfb-4e92-88c4-8ed2ed0bf2f2
htl"""

It has a bunch of very cool features! Including:

$([
		htl"
$(item)
"
		for item in cool_features
	])

"""

# ╔═╡ 713a6c7c-198c-417a-8d62-560db42d7ea4
cm"""## Useful HTML helpers"""

# ╔═╡ 1ca41340-f768-42d0-82d5-db37cfc7129e
cm"`embed_display`"

# ╔═╡ a304bd24-370b-4abf-a6d9-f7576b4452a2
htl"""

	$(embed_display(rand(4)))
	$(embed_display(rand(4)))

"""

# ╔═╡ a79bc022-e895-4e01-a0c1-28f26d23b22a
cm"`details`"

# ╔═╡ f9f707d1-1471-4ca9-a1ac-66973e061294
details(x, summary="Show more") = htl"""

	$(summary)
	$(x)

"""

# ╔═╡ 5028238f-d4c3-4a7a-a2f4-d3cf83e18767
details("long content")

# ╔═╡ 6bb3ea1f-9bbf-4226-b554-ac7c5a86bb46
cm"""**Admonitions**"""

# ╔═╡ 422b8936-f2a0-4825-9d01-4076ab3d41a4
admonition(category, title, content) = Markdown.MD(Markdown.Admonition(category, title, [content]))

# ╔═╡ 24872f5f-de8b-4c36-bd25-df1440cac48d
admonition("warning", "WARNING: Not recommended!", cm"you can turn off reactivity entirely by wrapping it into a `Ref`")

# ╔═╡ f137a01d-9964-4588-aca3-350d97c2af35
begin
	admonition_categories = ["info", "note", "hint", "correct", "warning", "danger", "whatever"]
	map(admonition_categories) do cat
		admonition(cat, cat, cm"What  beautiful day.")
	end
end

# ╔═╡ 0980486b-dd4f-457a-b974-da3d6287d371
begin
	hint(text) = admonition("hint", "Hint", [text])

	almost(text) = admonition("warning", "Almost there!", [text])

	function keep_working(text=cm"The answer is not quite right.")
		admonition("danger", "Keep working on it!", [text])
	end

	function correct(text=cm"Great! You got the right answer! Let's move on to the next section.")
		admonition("correct", "Got it!", [text])
	end
end;

# ╔═╡ 5629f761-3068-4b90-99a6-ab08b06a3533
begin
	if z == 2x + y
		correct(cm"Congratulations 😸")
	else
		cm"""
		$(keep_working())
		$(hint(cm"try it with copy and paste 🗊"))
		"""
	end
end

# ╔═╡ a406aaf6-4c9d-4160-a747-0881166b18b5
hint(cm"hello")

# ╔═╡ 2452a747-6e0f-4fbd-a46f-f3007f9601a0
cm"""# Other"""

# ╔═╡ 58f54383-d123-4c28-9d3b-36cf9585498d
cm""" ## Pluto's Builtin Pkg Manager

By default Pluto creates a blank environment just for your notebook and will install all packages `using MyPackage` into that new environment.

That will create `Project.toml` and `Manifest.toml` files, two standard julia files which describe your dependencies.

Pluto stores the contents of[`Project.toml`and`Manifest.toml`](https://pkgdocs.julialang.org/v1/toml-files/)directly in the notebook file. For forwards-backwards compatibility, this is done using two extra "cells" at the bottom of the file, containing the two files as string literals. For example, here is a notebook that imports`HypertextLiteral`and`PlutoUI`:[`fonsp/Pluto file format demo.jl`](https://gist.github.com/fonsp/44e72741cefb6041506cb8c7040db1a7).
"""

# ╔═╡ 90233555-1edb-4f77-8e24-3c8921f7307d
cm"""
-------------

You can **deactive** this builtin package manager by activating a specific environment

For example the following will activate the nearest surrounding julia environment (quite handy).
```julia
begin
    import Pkg
    # activate the shared project environment
    Pkg.activate(Base.current_project())

    using Plots, PlutoUI, LinearAlgebra
end
```

You can also use this to manually specify a completely new independent julia environment, including specific versions.

```julia
begin
    import Pkg
    # activate a temporary environment
    Pkg.activate(mktempdir())
    Pkg.add([
        Pkg.PackageSpec(name="Plots", version="1"),
        Pkg.PackageSpec(name="PlutoUI", version="0.7"),
    ])
    using Plots, PlutoUI, LinearAlgebra
end
```
"""

# ╔═╡ 2d511f23-07fc-4290-bace-001bedc09d0f
cm"""
## Restrictions when using Pluto

Currently, you cannot use
* `Distributed`, and packages that use it ([#300](https://github.com/fonsp/Pluto.jl/issues/300))
* packages that use lots of macros to create their own syntax ([#196](https://github.com/fonsp/Pluto.jl/issues/196))
* `@async` in order to update values reactively. Use the `@bind`macro instead
"""

# ╔═╡ 40ea9be1-e45d-45dd-8f99-365f6ccf34d8
htl"""
$(md"## Pluto Dashboards - the bright Future")

Going to come within the next half year!!!

"""

# ╔═╡ 2f5ce1cc-5de6-47c5-b72f-03aa779aba5c
cm"""## Favourite Other Pluto Notebooks

A selection of my favourite Pluto Notebooks published online.

1. copy the url
2. right-click on the Pluto logo at the very top, and click "open link in new tab"
3. In the Pluto main window paste the url in the textfield “open from file”

|Description | URL |
|----|-------|
| interactive math puzzle for beginners | `https://raw.githubusercontent.com/fonsp/Pluto.jl/main/sample/Basic%20mathematics.jl` |
| interactive colour filters | `https://raw.githubusercontent.com/JuliaPluto/PlutoCon2021-demos/main/lukavdplas%20-%20Colour%20filters.jl` |
| super interactive story telling | `https://raw.githubusercontent.com/JuliaPluto/PlutoCon2021-demos/main/Moser%20%26%20Dorn%20%E2%80%94%20Interactive%20Storytelling%20-%20An%20Odyssey.jl` |
| interactive drawing | `https://raw.githubusercontent.com/JuliaPluto/PlutoCon2021-demos/main/PaulButler_PenPlottingWithPluto.jl` |
"""

# ╔═╡ 7058e0b8-a249-4d60-8b5c-4109c7b871f6
cm"""## Further Pluto Resources

- [official README](https://github.com/fonsp/Pluto.jl)
- [official FaQ/Wiki](https://github.com/fonsp/Pluto.jl/wiki)
- [pluto on binder](https://pluto-on-binder.glitch.me/)
"""

# ╔═╡ 00000000-0000-0000-0000-000000000001
PLUTO_PROJECT_TOML_CONTENTS = """
[deps]
CommonMark = "a80b9123-70ca-4bc0-993e-6e3bcb318db6"
HypertextLiteral = "ac1192a8-f4b3-4bfe-ba22-af5b92cd3ab2"
PlutoUI = "7f904dfe-b85e-4ff6-b463-dae2292396a8"

[compat]
CommonMark = "~0.8.3"
HypertextLiteral = "~0.9.0"
PlutoUI = "~0.7.14"
"""

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

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

[[CommonMark]]
deps = ["Crayons", "JSON", "URIs"]
git-tree-sha1 = "393ac9df4eb085c2ab12005fc496dae2e1da344e"
uuid = "a80b9123-70ca-4bc0-993e-6e3bcb318db6"
version = "0.8.3"

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

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

[[HypertextLiteral]]
git-tree-sha1 = "72053798e1be56026b81d4e2682dbe58922e5ec9"
uuid = "ac1192a8-f4b3-4bfe-ba22-af5b92cd3ab2"
version = "0.9.0"

[[IOCapture]]
deps = ["Logging", "Random"]
git-tree-sha1 = "f7be53659ab06ddc986428d3a9dcc95f6fa6705a"
uuid = "b5f81e59-6552-4d32-b1f0-c071b021bf89"
version = "0.2.2"

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

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

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

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

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

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

[[PlutoUI]]
deps = ["Base64", "Dates", "HypertextLiteral", "IOCapture", "InteractiveUtils", "JSON", "Logging", "Markdown", "Random", "Reexport", "UUIDs"]
git-tree-sha1 = "d1fb76655a95bf6ea4348d7197b22e889a4375f4"
uuid = "7f904dfe-b85e-4ff6-b463-dae2292396a8"
version = "0.7.14"

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

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

[[Reexport]]
git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b"
uuid = "189a3867-3050-52da-a836-e630ba90ab69"
version = "1.2.2"

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

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

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

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

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

# ╔═╡ Cell order:
# ╟─227285cb-0f4a-47ba-9037-143307d6f691
# ╠═67dcf398-fc6a-4963-a390-d3dcfc69ea8d
# ╠═a6741b19-d378-4279-a1e4-70c18eb20cb5
# ╠═415fd393-eca0-4630-9be5-8a8265560b0d
# ╠═f31bc6f0-4fd6-444f-89df-8680deea986d
# ╟─11c03bd1-8752-4b9d-a3c5-203fb7a5872f
# ╟─396eb8cb-43cf-4c39-9610-b3e107b1e9dc
# ╟─d055e80b-6efb-4f78-9506-a886139598d9
# ╟─7fce21a5-9e97-44ce-b76a-5711fb62cd3b
# ╠═68701cb6-71e9-4853-a8e8-7cbcaaaf234b
# ╠═b4d2b9a0-a4a5-4c14-9092-93b0570628dd
# ╟─24872f5f-de8b-4c36-bd25-df1440cac48d
# ╠═cc8c129e-c955-414c-a415-a1879152a007
# ╠═618a2046-573e-4d44-9dba-5800951994cd
# ╠═2e4084dd-acf1-4350-95b3-f0e77cb28953
# ╟─3c029c7f-752f-4c99-b465-2c19675d1732
# ╟─788c2f4b-1679-4b2b-adc7-21f26e0fd277
# ╟─506ddcb3-c9eb-4e23-8a01-040b4103487e
# ╠═c367af42-71ef-4401-93bd-d2ade01606f5
# ╟─5629f761-3068-4b90-99a6-ab08b06a3533
# ╟─8ea36f83-4110-4505-b2e4-8a29c68f5560
# ╠═b103e55f-0d03-404c-a574-f116cf878ab6
# ╠═306f0d0a-5151-4ea6-9eb2-1a7d700118f2
# ╠═053a6e13-cfa7-431e-84cf-0839c8250f97
# ╠═4ad1bae8-ba32-4060-b06a-a1e109cd06fa
# ╟─780677dd-cf4c-46f8-b9dc-37a12a288242
# ╠═5e970055-1076-4841-9d2b-ec75e7142a41
# ╠═7f1fc43b-3f40-4d5b-ba2b-71916ff9b436
# ╠═addf17dd-be2f-4cdc-952d-115061506532
# ╟─42e94190-dbae-46d3-9257-bf3318f65b9d
# ╠═cdf7ba93-ec68-4f36-a650-def062ba61f4
# ╟─227c49cb-e986-45a6-89be-5558fcf3dba1
# ╟─59fd9fa6-23a0-4ca5-97ce-091c5c74268d
# ╟─c7c8c86d-2de2-4862-9899-e63b78d24d29
# ╠═e458f2cc-cd31-4e32-83c1-3cfec6b89a6e
# ╟─37415d7a-4737-46ac-9f16-44d81ccc8793
# ╠═177bf468-c5f4-4b01-87c0-97a56f1e3109
# ╟─73840820-f592-4682-a3d4-de500c0669ae
# ╠═db2292c8-d3f0-459c-b478-1e95ccab863c
# ╠═93a0f206-77f0-4563-bfda-39b6571c39e8
# ╟─37c9fae8-0982-4026-83ac-0f913188a2bd
# ╠═40a43215-70b0-4d10-aee6-ddc7a4ce1257
# ╟─9d7c3d14-e0e5-43bc-99e7-81774bf325fe
# ╟─354694a6-f889-439f-8fec-ca7822ec63c3
# ╟─df3301c4-196f-4ee1-bdf4-c81c71a1104e
# ╠═feae1368-a19d-4f0c-96b9-7081b593037a
# ╠═dfe2781e-ca0e-4cce-a1a0-34c3e913ece6
# ╟─7b9093a2-842b-4f65-bb35-57cf151d91f5
# ╠═ef887980-c97d-41f1-954a-9783c0775654
# ╟─5d1d2a4d-84f2-4bfa-bf15-e3698bb27b39
# ╠═3ffae4f4-ee7d-4207-a37c-f759292be96e
# ╠═b4a00d0c-34f0-4d06-9f65-64b4a764a3f8
# ╟─414a0d99-85b3-4025-8631-2310d07a7116
# ╟─d45cd163-62ab-4319-b6e5-1d3a6b4aa791
# ╠═799cc47b-9a65-4990-92ad-07b745341559
# ╠═213c5b06-6125-4e8d-90e5-f6356a1deeb5
# ╟─cc5aae01-9279-4cab-9ca7-45ecd7d09d29
# ╠═f644142d-4146-43c0-8049-fb345282b31a
# ╠═b908a9bf-6901-4a69-ba9e-a6ceff20fd9d
# ╠═f753db9b-dcfb-4e92-88c4-8ed2ed0bf2f2
# ╟─732d4457-55c2-408c-a2c9-bf1b50ac5fbc
# ╟─713a6c7c-198c-417a-8d62-560db42d7ea4
# ╟─1ca41340-f768-42d0-82d5-db37cfc7129e
# ╠═a304bd24-370b-4abf-a6d9-f7576b4452a2
# ╟─a79bc022-e895-4e01-a0c1-28f26d23b22a
# ╠═5028238f-d4c3-4a7a-a2f4-d3cf83e18767
# ╠═f9f707d1-1471-4ca9-a1ac-66973e061294
# ╟─6bb3ea1f-9bbf-4226-b554-ac7c5a86bb46
# ╠═422b8936-f2a0-4825-9d01-4076ab3d41a4
# ╠═f137a01d-9964-4588-aca3-350d97c2af35
# ╠═a406aaf6-4c9d-4160-a747-0881166b18b5
# ╠═0980486b-dd4f-457a-b974-da3d6287d371
# ╟─2452a747-6e0f-4fbd-a46f-f3007f9601a0
# ╟─58f54383-d123-4c28-9d3b-36cf9585498d
# ╟─90233555-1edb-4f77-8e24-3c8921f7307d
# ╟─2d511f23-07fc-4290-bace-001bedc09d0f
# ╟─40ea9be1-e45d-45dd-8f99-365f6ccf34d8
# ╟─2f5ce1cc-5de6-47c5-b72f-03aa779aba5c
# ╟─7058e0b8-a249-4d60-8b5c-4109c7b871f6
# ╟─00000000-0000-0000-0000-000000000001
# ╟─00000000-0000-0000-0000-000000000002

max_stars_repo_path: 06 pluto notebooks - 01 introduction.jl

max_stars_repo_name: schlichtanders/fall-in-love-with-julia

max_issues_repo_path: 06 pluto notebooks - 01 introduction.jl

max_issues_repo_name: schlichtanders/fall-in-love-with-julia

max_forks_repo_path: 06 pluto notebooks - 01 introduction.jl

max_forks_repo_name: schlichtanders/fall-in-love-with-julia


text:
function TurnAroundRangeBuilder(arg0::CorrelatedRandomVectorGenerator, arg1::GroundStation, arg2::GroundStation, arg3::jdouble, arg4::jdouble, arg5::ObservableSatellite)
    return TurnAroundRangeBuilder((CorrelatedRandomVectorGenerator, GroundStation, GroundStation, jdouble, jdouble, ObservableSatellite), arg0, arg1, arg2, arg3, arg4, arg5)
end

function build(obj::TurnAroundRangeBuilder, arg0::Vector{SpacecraftState})
    return jcall(obj, "build", TurnAroundRange, (Vector{SpacecraftState},), arg0)
end


text:
###
### first(x)
###
Base.first(::OneToRange{T}) where {T} = one(T)

Base.first(::UnitSRange{T,F,L}) where {T,F,L} = F

Base.first(r::UnitMRange) = getfield(r, :start)

Base.first(::LinSRange{T,B,E,L,D}) where {T,B,E,L,D} = B

Base.first(r::LinMRange) = getfield(r, :start)

Base.first(r::AbstractStepRangeLen) = unsafe_getindex(r, 1)

"refhi(x::AbstractStepRangeLen) - Returns the `hi` component of a twice precision ref"
refhi(::StepSRangeLen{T,Tr,Ts,R,S,L,F}) where {T,Tr<:TwicePrecision,Ts,R,S,L,F} = gethi(R)
refhi(r::StepMRangeLen{T,R,S}) where {T,R<:TwicePrecision,S} = r.ref.hi
refhi(r::StepRangeLen{T,R,S}) where {T,R<:TwicePrecision,S} = r.ref.hi

"reflo(x::AbstractStepRangeLen) - Returns the `lo` component of a twice precision ref"
reflo(::StepSRangeLen{T,Tr,Ts,R,S,L,F}) where {T,Tr<:TwicePrecision,Ts,R,S,L,F} = getlo(R)
reflo(r::StepMRangeLen{T,R,S}) where {T,R<:TwicePrecision,S} = r.ref.lo
reflo(r::StepRangeLen{T,R,S}) where {T,R<:TwicePrecision,S} = r.ref.lo

"""
    can_set_first(x) -> Bool

Returns `true` if the first element of `x` can be set. If `x` is a range then
changing the first element will also change the length of `x`.
"""
can_set_first(::T) where {T} = can_set_first(T)
can_set_first(::Type{T}) where {T} = can_setindex(T)
can_set_first(::Type{T}) where {T<:StepMRangeLen} = true
can_set_first(::Type{T}) where {T<:LinMRange} = true
can_set_first(::Type{T}) where {T<:StepMRange} = true
can_set_first(::Type{T}) where {T<:UnitMRange} = true

"""
    set_first!(x, val)

Set the first element of `x` to `val`.
"""
function set_first!(x::AbstractVector{T}, val::T) where {T}
    can_set_first(x) || throw(MethodError(set_first!, (x, val)))
    setindex!(x, val, firstindex(x))
    return x
end
set_first!(x::AbstractVector{T}, val) where {T} = set_first!(x, convert(T, val))
set_first!(r::LinMRange{T}, val::T) where {T} = (setfield!(r, :start, val); r)
function set_first!(r::StepMRange{T,S}, val::T) where {T,S}
    setfield!(r, :start, val)
    setfield!(r, :stop, Base.steprange_last(val, step(r), last(r)))
end
set_first!(r::UnitMRange{T}, val::T) where {T} = (setfield!(r, :start, val); r)
set_first!(r::StepMRangeLen{T,R,S}, val::R) where {T,R,S} = (setfield!(r, :ref, val); r)
function set_first!(r::StepMRangeLen{T,R,S}, val) where {T,R,S}
    return set_ref!(r, val - (1 - r.offset) * step_hp(r))
end

"""
    set_ref!(x, val)
Set the reference field of an instance of `StepMRangeLen`.
"""
set_ref!(r::StepMRangeLen{T,R,S}, val::R) where {T,R,S} = (setfield!(r, :ref, val); r)
set_ref!(r::StepMRangeLen{T,R,S}, val) where {T,R,S} = set_ref!(r, convert(R, val))

"""
    set_offset!(x, val)

Set the offset field of an instance of `StepMRangeLen`.
"""
function set_offset!(r::StepMRangeLen, val::Int)
    1 <= val <= max(1,r.len) || throw(ArgumentError("StepMRangeLen: offset must be in [1,$len], got $offset"))
    setfield!(r, :offset, val)
    return r
end
set_offset!(r::StepMRangeLen, val) = set_offset!(r, Int(val))


text:
using Test

using StaticArrays
using CompScienceMeshes

#include(Pkg.dir("CompScienceMeshes","examples","matlab_patches.jl"))

m1 = meshrectangle(1.0, 1.0, 0.5)
m2 = meshrectangle(1.0, 1.0, 0.5)
translate!(m2, point(0,1,0))
#m2.vertices += point(0.0, 1.0, 0.0)

m = weld(m1, m2)

@test numcells(skeleton(m,0)) == 15

## The mysterious case of the cuboid
using CompScienceMeshes
using Test

width, height, depth = 1.0, 1.0, 1.0

h = 1/4

m = meshrectangle(width, height, h, 3)

m_front = rotate(m, 0.5*pi*[1,0,0])
m_left  = rotate(m, -0.5*pi*[0,1,0])

m_back  = translate(m_front, point(0,height,0))
fliporientation!(m_back)
m_right = translate(m_left, point(width,0,0))
fliporientation!(m_right)

m_bottom = fliporientation(m)

m_fine = meshrectangle(width, height, h)
m_top = translate(m_fine, point(0,0,height))
m_open = weld(m_front, m_left, m_back, m_right, m_bottom)

#patch(m_top)
ot = weld(m_open, m_top)
#patch(ot)

nvo = numcells(skeleton(m_open,0))
nvt = numcells(skeleton(m_top,0))
nvm = numcells(skeleton(ot,0))
nvb = numcells(skeleton(boundary(m_top),0))
@test nvm == nvo + nvt - nvb

# test that consecutive welding happens correctly
function meshopenbox(a, h)

    base = meshrectangle(a, a, h, 3)
    front = rotate(base, point(π/2,0,0))
    back = -translate(front, point(0,a,0))
    left = rotate(base, point(0,-π/2,0))
    right = -translate(left, point(a,0,0))

    return weld(-base, front, right, back, left)
end

function meshuboidwithdivision(a, h)

    m1 = meshopenbox(a,h)
    translate!(m1, point(0,0,-a))

    m2 = deepcopy(m1)
    m2.vertices = [point(v[1],v[2],-v[3]) for v in m2.vertices]

    m3 = meshrectangle(a, a, h, 3)

    m = weld(m1,m2,m3)
    return m
end

a = 1.0
m = meshopenbox(a,a)
@test numcells(skeleton(m,0)) == 8

m = meshuboidwithdivision(a,a)
verts = skeleton(m, 0)
@test numcells(verts) == 12

##
a = h = 1.0
base = meshrectangle(a, a, h, 3)
front = rotate(base, point(π/2,0,0))
back = -translate(front, point(0,a,0))
left = rotate(base, point(0,-π/2,0))
right = -translate(left, point(a,0,0))

m1= weld(-base, front)
@test numcells(skeleton(m1,0)) == 6
m2 = weld(m1, right)
@test numcells(skeleton(m2,0)) == 7

m3 = weld(front, right)
@test numcells(skeleton(m3,0)) == 6

#patch(m)

#Test boundary weld
a = 1.0; h = 1/4
# plate = meshrectangle(a, a, h, 3,structured=false)
plate = readmesh(joinpath(@__DIR__,"assets/plate025.in"))
sheet = weld(plate,plate,boundary=true)

SV = skeleton(sheet,0)
SE = skeleton(sheet,1)
SF = skeleton(sheet,2)
PV = skeleton(plate,0)
PE = skeleton(plate,1)
PF = skeleton(plate,2)

@testset "boundary weld" begin
    @test numcells(SF) == 2*numcells(PF)
    @test numcells(SE) == 2*numcells(PE) - numcells(boundary(plate))
    @test numcells(SV) == 2*numcells(PV) - 16
    @test numcells(PV) - numcells(PE) + numcells(PF) == 1
    @test numcells(SV) - numcells(SE) + numcells(SF) == 2
end


text:
# foundationdb scheduler metadata store

"""
Metadata store using Foundation DB
"""
mutable struct FdbExecutorMeta <: ExecutorMeta
    path::String
    brokerid::Int
    proclocal::Dict{String,Any}
    donetasks::Set{TaskIdType}
    sharemode::ShareMode
    add_annotation::Function
    del_annotation::Function
    result_callback::Union{Function,Void}
    taskstore::FdbTaskStore
    resultstore::FdbResultStore
    trigger::Channel

    function FdbExecutorMeta(path::String, sharethreshold::Int)
        sharemode = ShareMode(sharethreshold)
        trigger = Channel{Void}(64)
        proclocal = Dict{String,Any}()
        donetasks = Set{TaskIdType}()

        taskstore = FdbTaskStore(fdb_db[], path, sharemode)
        resultstore = FdbResultStore(fdb_db[], path)
        obj = new(path, myid(), proclocal, donetasks, sharemode,
            identity, identity, nothing,
            taskstore, resultstore, trigger)

        task_trigger = (x)->begin
            isready(trigger) || put!(trigger, nothing)
            nothing
        end
        result_trigger = (tid, resultbytes)->begin
            val = meta_deser(resultbytes)
            k = resultpath(obj, tid)
            proclocal[k] = val
            push!(donetasks, tid)
            if obj.result_callback !== nothing
                obj.result_callback(tid, val)
            end
            isready(trigger) || put!(trigger, nothing)
            nothing
        end

        set_callback(taskstore, task_trigger)
        set_callback(resultstore, result_trigger)
        obj
    end
end

function Base.show(io::IO, M::FdbExecutorMeta)
    print(io, "FdbExecutorMeta(", M.path, ")")
end

function init(M::FdbExecutorMeta, brokerid::Int; add_annotation=identity, del_annotation=identity, result_callback=nothing)
    M.brokerid = brokerid
    M.add_annotation = add_annotation
    M.del_annotation = del_annotation
    M.result_callback = result_callback

    init(M.taskstore)
    init(M.resultstore)
    start_processing_events(M.taskstore)
    start_processing_events(M.resultstore)
    nothing
end

function wait_trigger(M::FdbExecutorMeta; timeoutsec::Int=5)
    trigger = M.trigger
    fire = true
    if !isready(trigger)
        @schedule begin
            sleep(timeoutsec)
            fire && !isready(trigger) && put!(trigger, nothing)
        end
    end

    # process results and sharemode notifications
    take!(M.trigger)
    fire = false

    nothing
end

function delete!(M::FdbExecutorMeta)
    reset(M)
    if myid() === M.brokerid
        clear(M.taskstore)
        clear(M.resultstore)
    end
    nothing
end

function reset(M::FdbExecutorMeta)
    stop_processing_events(M.taskstore)
    stop_processing_events(M.resultstore)

    reset(M.sharemode)
    empty!(M.proclocal)
    empty!(M.donetasks)
    M.add_annotation = identity
    M.del_annotation = identity
    M.result_callback = nothing

    nothing
end

function cleanup(M::FdbExecutorMeta)
end

function detach(M::FdbExecutorMeta, pid)
    taskmap = Dict{TaskIdType,TaskIdType}()
    if myid() === M.brokerid
        for tid in keys(M.taskstore.taskprops)
            key, annotated_tid, reservation = M.taskstore.taskprops[tid]
            if reservation == pid
                taskmap[tid] = annotated_tid
            end
        end
    end
    taskmap
end

@timetrack function share_task(M::FdbExecutorMeta, id::TaskIdType, allow_dup::Bool)
    annotated_task = M.add_annotation(id)
    new_task(M.taskstore, id, annotated_task; allow_duplicate=allow_dup)
    yield()  # so that the event thread gets to pick up notifications if any
    nothing
end

@timetrack function steal_task(M::FdbExecutorMeta, selector=default_task_scheduler)
    taskid = NoTask
    while !isempty(M.taskstore.taskids)
        pos = selector(M.taskstore.taskids)
        trytaskid = M.taskstore.taskids[pos]
        if reserve_task(M.taskstore, trytaskid, myid())
            key, annotated_tid, reservation = M.taskstore.taskprops[trytaskid]
            taskid = M.del_annotation(annotated_tid)::TaskIdType
            (trytaskid in M.taskstore.taskids) && splice!(M.taskstore.taskids, pos)
            break
        else
            (trytaskid in M.taskstore.taskids) && splice!(M.taskstore.taskids, pos)
        end
    end
    taskid
end

@timetrack function set_result(M::FdbExecutorMeta, id::TaskIdType, val; refcount::Int=0, processlocal::Bool=true)
    k = resultpath(M, id)
    M.proclocal[k] = val
    if refcount > 1
        DagScheduler.RefCounter[].refcount(id, refcount)
    end
    if !processlocal
        val = meta_pack(val)
        serval = meta_ser(val)
        publish_result(M.resultstore, id, convert(Vector{UInt8}, serval))
        finish_task(M.taskstore, id)
    end
    push!(M.donetasks, id)
    yield()  # so that the event thread gets to pick up notifications if any
    nothing
end

@timetrack function get_result(M::FdbExecutorMeta, id::TaskIdType)
    k = resultpath(M, id)
    (k in keys(M.proclocal)) || on_event(M.resultstore)
    val = M.proclocal[k]
    meta_unpack(val)
end

function has_result(M::FdbExecutorMeta, id::TaskIdType)
    id in M.donetasks
end

function decr_result_ref(M::FdbExecutorMeta, id::TaskIdType)
    DagScheduler.RefCounter[].refcount(id, -1)
end

function export_local_result(M::FdbExecutorMeta, id::TaskIdType, executable)
    k = resultpath(M, id)
    (k in keys(M.proclocal)) || return

    val = repurpose_result_to_export(executable, M.proclocal[k])
    val = meta_pack(val)
    serval = meta_ser(val)

    publish_result(M.resultstore, id, convert(Vector{UInt8}, serval))
    finish_task(M.taskstore, id)

    nothing
end


text:
using EndpointRanges
using Base.Test

r1 = -3:7
r2 = 2:5
@test ibegin(r1) == -3
@test ibegin(r2) == 2
@test iend(r1) == 7
@test iend(r2) == 5

@test (ibegin+3)(r1) == 0
@test (ibegin+2)(r2) == 4
@test (iend+3)(r1) == 10
@test (iend-2)(r2) == 3

for a in (1:20,
          range(1,2,20),      # StepRange
          1.0:2.0:39.0,       # FloatRange
          linspace(1,100,20), # LinSpace
          collect(1:20),
          view(0:21, 2:21))
    @test a[ibegin:20] == a[1:20]
    @test a[1:iend]    == a[1:20]
    @test a[ibegin+2:iend-3] == a[3:17]
    @test a[ibegin+2:iend÷2] == a[3:10]
    @test a[2*ibegin+1:iend÷2] == a[3:10]
    @test a[1:(ibegin+iend)÷2] == a[1:10]
    @test view(a, 1:(ibegin+iend)÷2) == view(a, 1:10)
    @test view(a, ibegin+2:iend-3) == view(a, 3:17)
end


text:
using EffectiveWaves

include("../average_waves/integral_form.jl")

# physical parameters
medium = Medium(1.0,1.0+0.0im)
specie = Specie(ρ=0.5, r=0.5, c=0.2, volfrac=0.1)

k = 0.8;
θin = 0.0
ω = real(k*medium.c)

ho = maximum_hankel_order(ω, medium, [specie]; tol=tol*1e4)

X0 = 6.
X1 = 8.
amps = map(8:1:16) do X_max
    X = 0.0:0.05:X_max
    i_X0 = findmin(abs.(X0 .- X))[2]
    i_X1 = findmin(abs.(X1 .- X))[2]
    avg_wave = AverageWave(ω, medium, specie; hankel_order=ho, X=X)
    avg_wave.amplitudes[i_X0:i_X1,:,:]
end

errs = [norm(amps[i][:] - amps[end][:])/norm(amps[end][:]) for i in eachindex(amps)[1:end-1]]
sum(log.(errs) .< -2:-1.2:-10.5) == 8

# plot((8:1:16)[1:end-1],errs)


text:
using Test, MPI
include(joinpath("..","..","testhelpers.jl"))

@testset "ODE Solvers" begin
    tests = [(1, "ode_tests_basic.jl"), (1, "genericcb_tests.jl")]
    runmpi(tests, @__FILE__)
end


text:
function minTrig!(g::AbstractGraph)
    mg = construct_metagraph(g)
    origin_edges = edges(g)
    for i in 1:nv(g)
        mv = min_triangles(mg)
        sedges = getsaturate(mg, mv)
        add_edges!(mg, sedges)
        sedges::Vector{Vector{Int}} = [edge_m2s(mg, e[1], e[2]) for e in sedges]
        add_edges!(g, sedges)
        rem_vertex!(mg, mv)
    end
    data = Dict("added_edges" => setdiff(edges(g), origin_edges))
    return data
end

function minTrig(g::AbstractGraph)
    cg = deepcopy(g)
    data = minTrig!(cg)
    return cg, data
end

function maxTrig!(g::AbstractGraph)
    mg = construct_metagraph(g)
    origin_edges = edges(g)
    for i in 1:nv(g)
        mv = max_triangles(mg)
        sedges = getsaturate(mg, mv)
        add_edges!(mg, sedges)
        sedges::Vector{Vector{Int}} = [edge_m2s(mg, e[1], e[2]) for e in sedges]
        add_edges!(g, sedges)
        rem_vertex!(mg, mv)
    end
    data = Dict("added_edges" => setdiff(edges(g), origin_edges))
    return data
end

function maxTrig(g::AbstractGraph)
    cg = deepcopy(g)
    data = maxTrig!(cg)
    return cg, data
end

max_stars_repo_name: charlyalizadeh/OPFdecgen

max_issues_repo_name: charlyalizadeh/OPFdecgen

max_forks_repo_name: charlyalizadeh/OPFdecgen


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

mutable struct SecurityRuleAssociations <: SwaggerModel
    networkInterfaceAssociation::Any # spec type: Union{ Nothing, NetworkInterfaceAssociation } # spec name: networkInterfaceAssociation
    subnetAssociation::Any # spec type: Union{ Nothing, SubnetAssociation } # spec name: subnetAssociation
    defaultSecurityRules::Any # spec type: Union{ Nothing, Vector{SecurityRule} } # spec name: defaultSecurityRules
    effectiveSecurityRules::Any # spec type: Union{ Nothing, Vector{EffectiveNetworkSecurityRule} } # spec name: effectiveSecurityRules

    function SecurityRuleAssociations(;networkInterfaceAssociation=nothing, subnetAssociation=nothing, defaultSecurityRules=nothing, effectiveSecurityRules=nothing)
        o = new()
        validate_property(SecurityRuleAssociations, Symbol("networkInterfaceAssociation"), networkInterfaceAssociation)
        setfield!(o, Symbol("networkInterfaceAssociation"), networkInterfaceAssociation)
        validate_property(SecurityRuleAssociations, Symbol("subnetAssociation"), subnetAssociation)
        setfield!(o, Symbol("subnetAssociation"), subnetAssociation)
        validate_property(SecurityRuleAssociations, Symbol("defaultSecurityRules"), defaultSecurityRules)
        setfield!(o, Symbol("defaultSecurityRules"), defaultSecurityRules)
        validate_property(SecurityRuleAssociations, Symbol("effectiveSecurityRules"), effectiveSecurityRules)
        setfield!(o, Symbol("effectiveSecurityRules"), effectiveSecurityRules)
        o
    end
end # type SecurityRuleAssociations

const _property_map_SecurityRuleAssociations = Dict{Symbol,Symbol}(Symbol("networkInterfaceAssociation")=>Symbol("networkInterfaceAssociation"), Symbol("subnetAssociation")=>Symbol("subnetAssociation"), Symbol("defaultSecurityRules")=>Symbol("defaultSecurityRules"), Symbol("effectiveSecurityRules")=>Symbol("effectiveSecurityRules"))
const _property_types_SecurityRuleAssociations = Dict{Symbol,String}(Symbol("networkInterfaceAssociation")=>"NetworkInterfaceAssociation", Symbol("subnetAssociation")=>"SubnetAssociation", Symbol("defaultSecurityRules")=>"Vector{SecurityRule}", Symbol("effectiveSecurityRules")=>"Vector{EffectiveNetworkSecurityRule}")
Base.propertynames(::Type{ SecurityRuleAssociations }) = collect(keys(_property_map_SecurityRuleAssociations))
Swagger.property_type(::Type{ SecurityRuleAssociations }, name::Symbol) = Union{Nothing,eval(Meta.parse(_property_types_SecurityRuleAssociations[name]))}
Swagger.field_name(::Type{ SecurityRuleAssociations }, property_name::Symbol) =  _property_map_SecurityRuleAssociations[property_name]

function check_required(o::SecurityRuleAssociations)
    true
end

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


text:
include("QuadForm/Basic.jl")
include("QuadForm/Lattices.jl")


text:
using DataDrivenControl
using FlightSims
using UnPack
using Plots
using LinearAlgebra
using Transducers
using LaTeXStrings
using DiffEqCallbacks

struct LinearSystem_ZOH_Gain
    linear::LinearSystem
    controller::LinearIRL
end

function FlightSims.State(env::LinearSystem_ZOH_Gain)
    @unpack linear = env
    State(linear)
end

function FlightSims.Dynamics!(env::LinearSystem_ZOH_Gain)
    @unpack linear, controller = env
    @Loggable function dynamics!(dx, x, w, t)
        u = optimal_input(controller, x, w)
        @onlylog param = w
        @onlylog i = controller.i
        @nested_log Dynamics!(linear)(dx, x, w, t; u=u)
    end
end

# See [1, Example 2. Continuous-Time Optimal Adaptive Control Using IRL]
# Refs
# [1] “Reinforcement Learning and Feedback Control: Using Natural Decision Methods to Design Optimal Adaptive Controllers,” IEEE Control Syst., vol. 32, no. 6, pp. 76–105, Dec. 2012, doi: 10.1109/MCS.2012.2214134.
function main()
        n, m = 2, 1
        A = [   -10  1;
             -0.002 -2]
        B = [0 2]'
        Q = Matrix(I, n, n)
        R = Matrix(I, m, m)
        cost = DataDrivenControl.QuadraticCost(Q, R)
        linear = LinearSystem(A, B)
        controller = DataDrivenControl.LinearIRL(Q, R, B; T=0.04)
        env = LinearSystem_ZOH_Gain(linear, controller)
        x0 = State(env)(rand(2))
        # TODO: add callback to update param `w`
        # simulation
        P_true = [0.0500 0.0039;
                  0.0039 0.2085]  # true solution
        w_true = [P_true[1, 1], P_true[2, 1]+P_true[1, 2], P_true[2, 2]]
        scale = 0.1
        w0 = w_true + scale*randn(3)  # perturbed initial guess
        tf = 5.0
        simulator = Simulator(x0, Dynamics!(env), w0;
                              tf=tf,
                             )
        Δt = 0.01
        # TODO: data buffer is a duplicate of saving callback (see `df`)
        # data buffer
        buffer = DataDrivenControl.DataBuffer()
        function update!(integrator)
            t = integrator.t
            x = integrator.u  # convention of DifferentialEquations.jl
            w = integrator.p  # convention of DifferentialEquations.jl
            u = optimal_input(controller, x, w)  # TODO: not to be duplicate of control input in dynamics for stable coding
            push!(buffer, controller, cost;
                  t=t, x=copy(x), u=copy(u), w=copy(w))
            eps = 1e-1
            sc = DistanceStopCondition(eps)
            # value_iteration!(controller, buffer, w; sc=sc)
            policy_iteration!(controller, buffer, w; sc=sc)
        end
        cb_irl = PeriodicCallback(update!, controller.T; initial_affect=true)  # stack initial data
        df = solve(simulator;
                   callback=cb_irl,
                   savestep=Δt,
                  )
        # plot
        ts = df.time
        xs = df.sol |> Map(datum -> datum.state) |> collect
        us = df.sol |> Map(datum -> datum.input) |> collect
        ws = df.sol |> Map(datum -> datum.param) |> collect
        is = df.sol |> Map(datum -> datum.i) |> collect
        fig_x = plot(ts, hcat(xs...)'; label=[L"x_{1}" L"x_{2}"], legend=:outerbottomright)
        fig_u = plot(ts, hcat(us...)'; label=L"u", legend=:outerbottomright)
        fig_w = plot(ts, hcat(ws...)'; label=[L"w_{1}" L"w_{2}" L"w_{3}"], legend=:outerbottomright)
        fig_iter = plot(ts, hcat(is...)'; label="iter")
        ws_true = ts |> Map(t -> w_true) |> collect
        plot!(fig_w, ts, hcat(ws_true...)'; color=:black, label=nothing)
        fig = plot(fig_x, fig_u, fig_w, fig_iter)
end


text:
include(joinpath("HelperFuncs", "runtests.jl"))
include(joinpath("DistributionUtils", "runtests.jl"))
include(joinpath("LESUtils", "runtests.jl"))
include(joinpath("KalmanProcessUtils", "runtests.jl"))
include(joinpath("TurbulenceConvectionUtils", "runtests.jl"))
include(joinpath("ReferenceModels", "runtests.jl"))
include(joinpath("ReferenceStats", "runtests.jl"))
include(joinpath("Pipeline", "runtests.jl"))
include(joinpath("NetCDFIO", "runtests.jl"))


text:
using MacroTools

export query, SELECT, @querify

# Recursively translate an Expr (garnered through `@where`) and turn it into a String
querify(e) = string(e)
querify(e::Symbol) = string("\"", e, "\"")
querify(e::AbstractString) = string("'", e, "'")
querify(e::QuoteNode) = querify(e.value)
function querify(e::Expr)
    args = e.args
    head = e.head

    # Peel :call and :macrocall nodes first
    if head == :call
        head = args[1]
        args = args[2:end]
    elseif head == :macrocall && length(args) == 3 && args[2] == nothing
        head = args[1]
        args = args[3:end]
    end

    if head == :&&
        head = "AND"
    elseif head == :||
        head = "OR"
    elseif head == Symbol("==")
        head = "="
    elseif head == :~
        head = "=~"
    elseif head == Symbol("@r_str")
        return string("/", args[1], "/")
    else
        head = string(head)
    end

    return string(querify(args[1]), " ", head, " ", querify(args[2]))
end

macro querify(ex)
    return querify(MacroTools.striplines(ex))
end

# A structure describing a database query
struct Query
    # "SELECT", "UPDATE", etc...
    verb::String

    # Fields and tags, e.g. what we're selecting
    fields::Vector{String}
    tags::Vector{String}

    # Measurements, e.g. what we're selecting from
    measurements::Vector{String}

    # QueryCondition, e.g. limiting our selection's scope
    condition::Union{String,Nothing}

    limit::Union{Int,Nothing}
end

function Query(verb::String; fields::Vector = String[],
                             tags::Vector = String[],
                             measurements::Vector = String[],
                             condition::Union{String,Nothing} = nothing,
                             limit::Union{Int,Nothing} = nothing)
    if isempty(fields) && !isempty(tags)
        @warn(
            "InfluxDB has strange behavior when 'fields' is empty but 'tags' is not!",
            "https://docs.influxdata.com/influxdb/v1.7/query_language/data_exploration/#selecting-tag-keys-in-the-select-clause",
        )
    end

    # Canonicalize everything, get correct types, etc...
    return Query(
        verb,
        String.(fields),
        String.(tags),
        String.(measurements),
        condition,
        limit,
    )
end

SELECT(;kwargs...) = Query("SELECT"; kwargs...)

function join_typed(io, v::Vector, type_name, delim = ",")
    if isempty(v)
        return
    end

    # Write out the first one
    write(io, "\"", v[1], "\"", "::", type_name)
    for idx in 2:length(v)
        write(io, delim, "\"", v[idx], "\"", "::", type_name)
    end
end

function payload(q::Query)
    buff = IOBuffer()
    payload!(buff, q)
    return String(take!(buff))
end

function payload!(io::IO, q::Query)
    write(io, q.verb, " ")

    # Start with fields/tags, e.g. what we're selecting
    if isempty(q.fields)
        write(io, "*")
    else
        join_typed(io, q.fields, "field")
        if !isempty(q.tags)
            write(io, ",")
            join_typed(io, q.tags, "tag")
        end
    end

    # If we have measurements, specify them here:
    if !isempty(q.measurements)
        write(io, " FROM ")
        join(io, [string("\"", m, "\"") for m in q.measurements], ",")
    end

    if q.condition != nothing
        write(io, " WHERE ")
        write(io, q.condition)
    end

    if q.limit != nothing
        write(io, " LIMIT ", string(q.limit))
    end
end


text:
using Random
function fit_warmstart!(lnr, X, y, tree)
  IAI.IAIBase.resetinternalparams!(lnr)
  criterion = IAI.IAIBase.process_criterion(lnr)
  IAI.IAIBase.validate_criterion(criterion, lnr, :criterion)
  data = IAI.IAIBase.Data(tree, X, nothing, y)
  mins, maxs = IAI.IAIBase.get_extrema(data.features.X_numeric,
                                   data.features.n_numeric_orig_features)
  data.features.X_mins .= mins
  data.features.X_maxs .= maxs
  lnr.normalize_X && IAI.IAIBase.normalize_X!(data.features)
  IAI.IAIBase._preprocess!(lnr, data, IAI.IAIBase.gettasktype(lnr))
  lnr.prb_ = IAI.IAIBase.Problem(lnr, data, criterion)

  ls = IAI.OptimalTrees.LocalSearcher(lnr, lnr.prb_)
  IAI.OptimalTrees.init!(ls, lnr)
  Random.seed!(ls.rng_gen, ls.random_seed)

  lnr.all_trees_ = deepcopy(tree.all_trees_)
  for t in 1:length(lnr.all_trees_)
    rng = IAI.IAIBase.RandomStreams.next_stream(ls.rng_gen)
    IAI.OptimalTrees.set_rng!(ls, rng)

    tree = lnr.all_trees_[t]

    if lnr.normalize_X
      IAI.IAIBase.normalize_X!(tree, lnr.prb_.data.features)
    end
    if :normalize_y in fieldnames(typeof(lnr)) && lnr.normalize_y
      IAI.IAIBase.normalize_y!(tree, lnr.prb_.data.target)
    end

    IAI.OptimalTrees.local_search!(tree, ls)

    IAITrees.finalize_capacity!(tree)
    IAI.OptimalTrees.update_tree_fits!(tree, ls.data, ls.evaluators, true)
    lnr.all_trees_[t] = tree

  end
  best_ind = argmin([IAI.OptimalTrees.train_error(lnr, tree)
                     for tree in lnr.all_trees_])
  lnr.tree_ = lnr.all_trees_[best_ind]

  lnr
end


text:
module Clang

include("shards/JLLEnvs.jl")
using .JLLEnvs

include("LibClang.jl")
using .LibClang

include("cltypes.jl")
export CLCursor, CLType, CLToken
foreach(names(@__MODULE__; all=true)) do s
    x = getfield(@__MODULE__, s)
    if x isa DataType && supertype(x) in [CLCursor, CLType, CLToken]
        @eval export $s
    end
end

include("index.jl")
export Index

include("trans_unit.jl")
export TranslationUnit, spelling, parse_header, parse_headers

include("cursor.jl")
export kind, name, spelling, value
export get_filename, get_file_line_column, get_function_args
export is_typedef_anon, is_forward_declaration, is_inclusion_directive
export search, children

include("type.jl")
export has_elaborated_reference, get_elaborated_cursor
export has_function_reference
export fields

include("token.jl")
export TokenList, tokenize

include("dump.jl")
export dumpobj

include("generator/Generators.jl")
using .Generators

function version()
    cxstr = clang_getClangVersion()
    ptr = clang_getCString(cxstr)
    s = unsafe_string(ptr)
    clang_disposeString(cxstr)
    return s
end

const LLVM_VERSION = match(r"[0-9]+.[0-9]+.[0-9]+", version()).match
const LLVM_DIR = normpath(joinpath(dirname(LibClang.Clang_jll.libclang_path), ".."))
const LLVM_LIBDIR = joinpath(LLVM_DIR, "lib")
const LLVM_INCLUDE = joinpath(LLVM_LIBDIR, "clang", LLVM_VERSION, "include")
const CLANG_INCLUDE = LLVM_INCLUDE

export LLVM_VERSION, LLVM_LIBDIR, LLVM_INCLUDE, CLANG_INCLUDE

end


text:
i=1
while true
    i=rand(1:8)
    if i==3
        break
    end
    if i==7
        continue
    end
    println(i)
end

for i in [5,5,5,3,3,3,5,5,5]
    for j in 1:i
        print('*')
    end
    println()
end

max_stars_repo_name: Rratic/JuliaGuide

max_issues_repo_name: Rratic/JuliaGuide

max_forks_repo_name: Rratic/JuliaGuide


text:
module ProxOptim

export Gradient, Fista, MFista
export proximal_iter!

export TV_FGP, TV1_FGP, TV_GP, TV1_GP
export iter_TV_prox!,
    get_FTV_prox!, get_FTV1_prox!,
    get_TV_prox!, get_TV1_prox!

include("proximal_optim.jl")
include("TV_prox.jl")

end


text:
# Author: Youngjun Kim, youngjun@stanford.edu
# Date: 08/19/2014
#
# Originally written in MATLAB by Mykel Kochenderfer, mykel@stanford.edu
# Converted by Youngjun Kim, youngjun@stanford.edu

#   LOAD_SCRIPTS(FILENAME) returns a structure holding the encounter
#   scripts stored in the specified file.
#
#   SCRIPTS FILE:
#   The scripts file contains a set of scripted encounters. Each
#   encounter is defined by a set of encounter scripts associated with a
#   fixed number of aircraft. The file is organized as follows:
#
#   [Header]
#   uint32 (number of encounters)
#   uint32 (number of aircraft)
#       [Encounter 1]
#           [Initial]
#               [Aircraft 1]
#               double (initial airspeed in ft/s)
#               double (initial north position in ft)
#               double (initial east position in ft)
#               double (initial altitude in ft)
#               double (initial heading angle in radians)
#               double (initial flight path angle in radians)
#               double (initial roll angle in radians)
#               double (initial airspeed acceleration in ft/s^2)
#               ...
#               [Aircraft n]
#               double (initial airspeed in ft/s)
#               double (initial north position in ft)
#               double (initial east position in ft)
#               double (initial altitude in ft)
#               double (initial heading angle in radians)
#               double (initial flight path angle in radians)
#               double (initial roll angle in radians)
#               double (initial airspeed acceleration in ft/s^2)
#           [Updates]
#               [Aircraft 1]
#               uint8 (number of updates)
#                   [Update 1]
#                   double (time in s)
#                   double (commanded vertical rate in ft/s)
#                   double (commanded turn rate in rad/s)
#                   double (commanded airspeed acceleration in ft/s^2)
#                   ...
#                   [Update m]
#                   double (time in s)
#                   double (commanded vertical rate in ft/s)
#                   double (commanded turn rate in rad/s)
#                   double (commanded airspeed acceleration in ft/s^2)
#               ...
#               [Aircraft n]
#                   ...
#       ...
#       [Encounter k]
#           ...
#
#   SCRIPTS STRUCTURE:
#   The waypoints structure is an m x n structure matrix, where m is the
#   number of aircraft and n is the number of encounters. This structure
#   matrix has two fields: initial and update. The initial field is an 8
#   element array specifying the airspeed, north position, east position,
#   altitude, heading, flight path angle, roll angle, and airspeed
#   acceleration. The update field is a 4 x n matrix, where n is the number
#   of updates. The rows correspond to the time, vertical rate, turn rate
#   and airspeed acceleration.
#   The script also takes an additional parameter through varargin:  the
#   number of encounters to load, 'limit'.  load_encounters will load the
#   minimum of this value and the number of encounters specified in the
#   encounter file.  If specified, this impacts 'n' in the above paragraph.

function load_encounters(filename, initial_dim, update_dim, num_update_type; limit = 0)

    fio = open(filename, "r")

    num_encounters = read(fio, UInt32)
    num_ac = read(fio, UInt32)

    if limit != 0
        num_encounters = min(num_encounters, limit)
    end

    encounters = Array(Any, num_ac, num_encounters)

    for i = 1:num_encounters
        for j = 1:num_ac
            encounters[j, i] = Dict()
        end

        for j = 1:num_ac
            encounters[j, i]["initial"] = read(fio, Float64, initial_dim)
        end

        for j = 1:num_ac
            num_update = read(fio, num_update_type)

            encounters[j, i]["update"] = reshape(read(fio, Float64, update_dim * num_update), Int64(update_dim), Int64(num_update))
        end
    end

    close(fio)

    return encounters, num_ac, num_encounters
end

function load_scripts(filename; limit = 0)

    scripts, num_ac, num_enc = load_encounters(filename, 8, 4, UInt8; limit = limit)
end

if false
    scripts, num_ac, num_enc = load_scripts("encounters_0.dat", limit = 2)

    println(num_ac)
    println(num_enc)
    dump(scripts)
end


text:
using SuccessiveConvexProgrammings
using Test

using LinearAlgebra

function print_message(title)
    println(">"^6 * title * "<"^6)
end

function my_dynamics(x, u)
    A = [0 1 0; 0 0 1; 0 0 0]
    return A*x + sin.(u)
end

function test_zero_order_hold()
    print_message("zero_order_hold")
    dt = 0.01
    ts = collect(0:dt:0.1)
    # linearisation points
    x_k = zeros(length(ts), 3)
    u_k = (pi/4) * ones(length(ts), 3)

    disc = ZeroOrderHoldDiscretiser(my_dynamics,
                                    ts=ts, x_k=x_k, u_k=u_k)
    Ad, Bd, cd = discretise(disc)

    eps = 1e-4
    A = [0 1 0; 0 0 1; 0 0 0]
    for i in 1:length(ts)
        @test norm(Ad[i] - exp(A * dt)) < eps
    end
end

test_zero_order_hold()


text:
init_grad(x) = zero(x)
zero_grad!(x) = zero(x)
zero_grad!(x::AbstractArray) = (x .= 0)

scan(c::Call) = foreach(scan, c.args)

function scan(x::Tracked)
  x.isleaf && return
  ref = x.ref += 1
  if ref == 1
    scan(x.f)
    isdefined(x, :grad) && (x.grad = zero_grad!(x.grad))
  else
    isdefined(x, :grad) || (x.grad = init_grad(x.data))
  end
  return
end

function scan(x)
  istracked(x) && scan(tracker(x))
  return
end

back_(f, y, args...) = back(f, args...)
back_(c::Call, y, Δ) = back_(c.func, y, Δ, c.args...)
back_(::Call{Void}, y, Δ) = nothing

accum!(x, Δ) = x .+ Δ
accum!(x::AbstractArray, Δ) = (x .+= Δ)

function back(x::Tracked, Δ)
  x.isleaf && (x.grad = accum!(x.grad, Δ); return)
  ref = x.ref -= 1
  if isdefined(x, :grad)
    x.grad = accum!(x.grad, Δ)
    ref == 0 && back_(x.f, x.data, x.grad)
  else
    ref == 0 && back_(x.f, x.data, Δ)
  end
  return
end

back(x, Δ) = back(tracker(x), Δ)
back(x::Void, Δ) = error("Can't backpropagate through `nothing`")

macro back(x, Δ)
  quote
    x = $(esc(x))
    istracked(x) && back(x, $(esc(Δ)))
  end
end

# Interface methods

# TODO: if an error occurs in `back` the refcounts will be broken
# and `back` will silently fail to update.

function back!(x::Tracked, Δ)
  scan(x)
  back(x, Δ)
end

back!(x, Δ) = back!(tracker(x), Δ)


text:
module osamplet4
using StaticArrays
function osamplet4mesh()
    xyz = [
    0.0 0.0 0.0
    1.0 0.0 0.0
    2.0 0.0 0.0
    3.0 0.0 0.0
    0.0 2.0 0.0
    1.0 2.0 0.0
    2.0 2.0 0.0
    3.0 2.0 0.0
    0.0 4.0 0.0
    1.0 4.0 0.0
    2.0 4.0 0.0
    3.0 4.0 0.0
    0.0 6.0 0.0
    1.0 6.0 0.0
    2.0 6.0 0.0
    3.0 6.0 0.0
    0.0 8.0 0.0
    1.0 8.0 0.0
    2.0 8.0 0.0
    3.0 8.0 0.0
    0.0 0.0 2.5
    1.0 0.0 2.5
    2.0 0.0 2.5
    3.0 0.0 2.5
    0.0 2.0 2.5
    1.0 2.0 2.5
    2.0 2.0 2.5
    3.0 2.0 2.5
    0.0 4.0 2.5
    1.0 4.0 2.5
    2.0 4.0 2.5
    3.0 4.0 2.5
    0.0 6.0 2.5
    1.0 6.0 2.5
    2.0 6.0 2.5
    3.0 6.0 2.5
    0.0 8.0 2.5
    1.0 8.0 2.5
    2.0 8.0 2.5
    3.0 8.0 2.5
    0.0 0.0 5.0
    1.0 0.0 5.0
    2.0 0.0 5.0
    3.0 0.0 5.0
    0.0 2.0 5.0
    1.0 2.0 5.0
    2.0 2.0 5.0
    3.0 2.0 5.0
    0.0 4.0 5.0
    1.0 4.0 5.0
    2.0 4.0 5.0
    3.0 4.0 5.0
    0.0 6.0 5.0
    1.0 6.0 5.0
    2.0 6.0 5.0
    3.0 6.0 5.0
    0.0 8.0 5.0
    1.0 8.0 5.0
    2.0 8.0 5.0
    3.0 8.0 5.0
    ]
    c = [1 25 21 22
    6 5 2 26
    26 2 22 25
    5 26 25 2
    2 1 22 25
    5 25 1 2
    21 45 41 42
    26 25 22 46
    46 22 42 45
    25 46 45 22
    22 21 42 45
    25 45 21 22
    5 29 25 26
    10 9 6 30
    30 6 26 29
    9 30 29 6
    6 5 26 29
    9 29 5 6
    25 49 45 46
    30 29 26 50
    50 26 46 49
    29 50 49 26
    26 25 46 49
    29 49 25 26
    9 33 29 30
    14 13 10 34
    34 10 30 33
    13 34 33 10
    10 9 30 33
    13 33 9 10
    29 53 49 50
    34 33 30 54
    54 30 50 53
    33 54 53 30
    30 29 50 53
    33 53 29 30
    13 37 33 34
    18 17 14 38
    38 14 34 37
    17 38 37 14
    14 13 34 37
    17 37 13 14
    33 57 53 54
    38 37 34 58
    58 34 54 57
    37 58 57 34
    34 33 54 57
    37 57 33 34
    2 26 22 23
    7 6 3 27
    27 3 23 26
    6 27 26 3
    3 2 23 26
    6 26 2 3
    22 46 42 43
    27 26 23 47
    47 23 43 46
    26 47 46 23
    23 22 43 46
    26 46 22 23
    6 30 26 27
    11 10 7 31
    31 7 27 30
    10 31 30 7
    7 6 27 30
    10 30 6 7
    26 50 46 47
    31 30 27 51
    51 27 47 50
    30 51 50 27
    27 26 47 50
    30 50 26 27
    10 34 30 31
    15 14 11 35
    35 11 31 34
    14 35 34 11
    11 10 31 34
    14 34 10 11
    30 54 50 51
    35 34 31 55
    55 31 51 54
    34 55 54 31
    31 30 51 54
    34 54 30 31
    14 38 34 35
    19 18 15 39
    39 15 35 38
    18 39 38 15
    15 14 35 38
    18 38 14 15
    34 58 54 55
    39 38 35 59
    59 35 55 58
    38 59 58 35
    35 34 55 58
    38 58 34 35
    3 27 23 24
    8 7 4 28
    28 4 24 27
    7 28 27 4
    4 3 24 27
    7 27 3 4
    23 47 43 44
    28 27 24 48
    48 24 44 47
    27 48 47 24
    24 23 44 47
    27 47 23 24
    7 31 27 28
    12 11 8 32
    32 8 28 31
    11 32 31 8
    8 7 28 31
    11 31 7 8
    27 51 47 48
    32 31 28 52
    52 28 48 51
    31 52 51 28
    28 27 48 51
    31 51 27 28
    11 35 31 32
    16 15 12 36
    36 12 32 35
    15 36 35 12
    12 11 32 35
    15 35 11 12
    31 55 51 52
    36 35 32 56
    56 32 52 55
    35 56 55 32
    32 31 52 55
    35 55 31 32
    15 39 35 36
    20 19 16 40
    40 16 36 39
    19 40 39 16
    16 15 36 39
    19 39 15 16
    35 59 55 56
    40 39 36 60
    60 36 56 59
    39 60 59 36
    36 35 56 59
    39 59 35 36
    ]
    return xyz, c
end
end

module mt4mesh1
using StaticArrays
using MeshCore: P1, T4, ShapeColl,  manifdim, nvertices, nridges, nshapes
using MeshCore: ir_bbyridges, ir_skeleton, ir_bbyfacets, nshifts, _sense
using MeshCore: IncRel, transpose, nrelations, nentities
using MeshCore: VecAttrib, attribute, ir_code
using MeshSteward: Mesh, attach!, increl, basecode
using ..osamplet4: osamplet4mesh
using Test
function test()
    xyz, cc = osamplet4mesh()
    # Construct the initial incidence relation
    N, T = size(xyz, 2), eltype(xyz)
    locs =  VecAttrib([SVector{N, T}(xyz[i, :]) for i in 1:size(xyz, 1)])
    vrts = ShapeColl(P1, length(locs))
    vrts.attributes["geom"] = locs
    tets = ShapeColl(T4, size(cc, 1))
    ir30 = IncRel(tets, vrts, cc)

    mesh = Mesh()
    attach!(mesh, ir30)
    irc = basecode(mesh)
    @test irc == (3, 0)

    @test increl(mesh, (3, 0)) == ir30
    ir = increl(mesh, (3, 0))
    locs = attribute(ir.right, "geom")
    @test locs[nshapes(ir.right)] == [3.0, 8.0, 5.0]

    true
end
end
using .mt4mesh1
mt4mesh1.test()

module mmeshio2a
using StaticArrays
using MeshCore: nshapes
using MeshCore: attribute, nrelations, ir_skeleton
using MeshSteward: import_NASTRAN, vtkwrite
using MeshSteward: Mesh, attach!, increl, basecode
using Test
function test()
    connectivities = import_NASTRAN(joinpath("data", "trunc_cyl_shell_0.nas"))
    connectivity = connectivities[1]
    mesh = Mesh()
    attach!(mesh, connectivity)
    irc = basecode(mesh)
    connectivity = increl(mesh, irc)
    @test (nshapes(connectivity.right), nshapes(connectivity.left)) == (376, 996)
    vertices = connectivity.right
    geom = attribute(vertices, "geom")
    # @show typeof(geom)
    # @show typeof(geom.val)
    vtkwrite("trunc_cyl_shell_0", connectivity)
    try rm("trunc_cyl_shell_0" * ".vtu"); catch end

    connectivity0 = ir_skeleton(ir_skeleton(ir_skeleton(connectivity)))
    @test (nshapes(connectivity0.right), nshapes(connectivity0.left)) == (376, 376)
    vtkwrite("trunc_cyl_shell_0-boundary-skeleton", connectivity0)
    try rm("trunc_cyl_shell_0-boundary-skeleton" * ".vtu"); catch end
    true
end
end
using .mmeshio2a
mmeshio2a.test()

module mmeshio3
using StaticArrays
using MeshCore: nshapes
using MeshCore: attribute, nrelations, ir_skeleton
using MeshSteward: import_NASTRAN, vtkwrite, export_MESH
using MeshSteward: Mesh, attach!, increl, load, basecode, nspacedims
using Test
function test()
    connectivities = import_NASTRAN(joinpath("data", "trunc_cyl_shell_0.nas"))
    connectivity = connectivities[1]
    mesh = Mesh()
    attach!(mesh, connectivity)
    connectivity = increl(mesh, (3, 0))
    @test (nshapes(connectivity.right), nshapes(connectivity.left)) == (376, 996)

    export_MESH("trunc_cyl_shell_0.mesh", connectivity)
    mesh2 = Mesh("new mesh")
    mesh2 = load(mesh2, "trunc_cyl_shell_0.mesh")
    connectivity = increl(mesh2, (3, 0))
    @test (nshapes(connectivity.right), nshapes(connectivity.left)) == (376, 996)
    irc = basecode(mesh)
    @test irc == (3, 0)
    @test nspacedims(mesh2) == 3
    try rm("trunc_cyl_shell_0" * ".mesh"); catch end
    try rm("trunc_cyl_shell_0-xyz" * ".dat"); catch end
    try rm("trunc_cyl_shell_0-conn" * ".dat"); catch end
    true
end
end
using .mmeshio3
mmeshio3.test()

module mmeshio4
using StaticArrays
using MeshCore: nshapes
using MeshCore: attribute, nrelations, ir_skeleton
using MeshSteward: import_NASTRAN, vtkwrite, export_MESH
using MeshSteward: Mesh, attach!, increl, load, basecode, nspacedims, save
using Test
function test()
    connectivities = import_NASTRAN(joinpath("data", "trunc_cyl_shell_0.nas"))
    connectivity = connectivities[1]
    mesh = Mesh()
    attach!(mesh, connectivity)
    save(mesh, "trunc_cyl_shell_0")
    mesh2 = Mesh()
    mesh2 = load(mesh2, "trunc_cyl_shell_0")
    @test nspacedims(mesh) == nspacedims(mesh2)
    try rm("trunc_cyl_shell_0" * ".mesh"); catch end
    try rm("trunc_cyl_shell_0-xyz" * ".dat"); catch end
    try rm("trunc_cyl_shell_0-conn" * ".dat"); catch end

    true
end
end
using .mmeshio4
mmeshio4.test()

module mmfind1
using MeshSteward: boundingbox
using MeshSteward: Mesh, attach!, increl, load, basecode, nspacedims, save, baseincrel
using MeshSteward: vselect
using MeshSteward: import_NASTRAN, vtkwrite
using MeshCore: nshapes
using Test
function test()
	connectivities = import_NASTRAN(joinpath("data", "trunc_cyl_shell_0.nas"))
	mesh = Mesh()
	attach!(mesh, connectivities[1])
	# vtkwrite("trunc_cyl_shell_0-elements", baseincrel(mesh))
    selectedv = vselect(mesh, box = boundingbox([-Inf -Inf 0.5; Inf Inf 0.5]), inflate = 0.001)
	# vtkwrite("trunc_cyl_shell_0-selected-vertices", selectedv)
	@test nshapes(selectedv.left) == 44
end
end
using .mmfind1
mmfind1.test()

module mmbd1
using MeshSteward: import_NASTRAN, vtkwrite
using MeshSteward: Mesh, attach!, boundary
using MeshSteward: summary
using Test
function test()
	connectivities = import_NASTRAN(joinpath("data", "trunc_cyl_shell_0.nas"))
	connectivity = connectivities[1]
	mesh = Mesh()
	attach!(mesh, connectivity)
	bir = boundary(mesh)
    s = summary(mesh)
    vtkwrite("trunc_cyl_shell_0-boundary", bir)
	try rm("trunc_cyl_shell_0-boundary" * ".vtu"); catch end
end
end
using .mmbd1
mmbd1.test()

module mmvtx1
using MeshSteward: import_NASTRAN, vtkwrite
using MeshSteward: Mesh, attach!, vertices
using MeshSteward: summary
using MeshCore: nshapes
using Test
function test()
    connectivities = import_NASTRAN(joinpath("data", "trunc_cyl_shell_0.nas"))
    connectivity = connectivities[1]
    mesh = Mesh()
    attach!(mesh, connectivity)
    vir = vertices(mesh)
    @test nshapes(vir.right) == nshapes(vir.left)
    @test nshapes(vir.right) == nshapes(connectivity.right)
    # s = summary(mesh)
    # vtkwrite("trunc_cyl_shell_0-vertices", vir)
    # try rm("trunc_cyl_shell_0-vertices" * ".vtu"); catch end
end
end
using .mmvtx1
mmvtx1.test()

module mmvtx2
using MeshSteward: import_NASTRAN, vtkwrite
using MeshSteward: Mesh, attach!, vertices, submesh
using MeshSteward: summary, basecode, boundary, eselect, label, initbox, updatebox!, baseincrel
using MeshCore: nshapes, attribute, ir_subset
using Test
function test()
    connectivities = import_NASTRAN(joinpath("data", "trunc_cyl_shell_0.nas"))
    connectivity = connectivities[1]
    mesh = Mesh()
    attach!(mesh, connectivity)
    @test basecode(mesh) == (3, 0)
    vir = vertices(mesh)
    @test nshapes(vir.right) == nshapes(vir.left)
    @test nshapes(vir.right) == nshapes(connectivity.right)
    geom = attribute(vir.right, "geom")
    box = initbox(geom[1])
    for i in 1:length(geom)
        updatebox!(box, geom[i])
    end
    box[1] = (box[1] + box[2]) / 2
    ir = baseincrel(mesh)
    el = eselect(ir; box = box, inflate = 0.0009)
    @test length(el)  == 498
    label(mesh, (3, 0), :left, el, 8)
    el = eselect(ir; label = 8)
    @test length(el)  == 498

    # @test length(el) == 44
    @test summary(mesh) == "Mesh mesh: ((3, 0), \"\") = (elements, vertices): elements = 996 x T4 {label,}, vertices = 376 x P1 {geom,}; "
    # vtkwrite("trunc_cyl_shell_0-full", ir)
    # vtkwrite("trunc_cyl_shell_0-subset", ir_subset(ir, el))
    # try rm("trunc_cyl_shell_0-vertices" * ".vtu"); catch end
    return true
end
end
using .mmvtx2
mmvtx2.test()

module mmvtx3
using MeshSteward: import_NASTRAN, vtkwrite, geometry
using MeshSteward: Mesh, attach!, vertices, submesh, increl, baseincrel
using MeshSteward: summary, basecode, boundary, eselect, label, initbox, updatebox!, baseincrel
using MeshCore: nshapes, attribute, ir_subset, ir_code, nrelations
using Test
function test()
    connectivities = import_NASTRAN(joinpath("data", "trunc_cyl_shell_0.nas"))
    connectivity = connectivities[1]
    mesh = Mesh()
    attach!(mesh, connectivity)
    @test basecode(mesh) == (3, 0)
    vir = vertices(mesh)
    @test nshapes(vir.right) == nshapes(vir.left)
    @test nshapes(vir.right) == nshapes(connectivity.right)
    geom = geometry(mesh)
    box = initbox(geom[1])
    for i in 1:length(geom)
        updatebox!(box, geom[i])
    end
    box[1] = (box[1] + box[2]) / 2
    ir = baseincrel(mesh)
    el = eselect(ir; box = box, inflate = 0.0009)
    @test length(el)  == 498
    label(mesh, (3, 0), :left, el, 8)
    el = eselect(ir; label = 8)
    @test length(el)  == 498

    halfmesh = submesh(mesh, el)
    # @show  summary(halfmesh)
    @test nrelations(baseincrel(halfmesh)) == 498

    bir = boundary(mesh)
    bir2 = increl(mesh, (ir_code(bir), "boundary"))
    @test summary(bir) == summary(bir2)
    # @test length(el) == 44
    # @show  summary(mesh)
    # vtkwrite("trunc_cyl_shell_0-full", ir)
    # vtkwrite("trunc_cyl_shell_0-subset", ir_subset(ir, el))
    try rm("trunc_cyl_shell_0-full" * ".vtu"); catch end
    try rm("trunc_cyl_shell_0-subset" * ".vtu"); catch end
    try rm("trunc_cyl_shell_0-vertices" * ".vtu"); catch end
    return true
end
end
using .mmvtx3
mmvtx3.test()

module mmvtx4
using MeshCore: nshapes, attribute, ir_subset, ir_code, nrelations
using MeshSteward.Exports
using Test
function test()
    connectivities = import_NASTRAN(joinpath("data", "trunc_cyl_shell_0.nas"))
    connectivity = connectivities[1]
    mesh = Mesh()
    attach!(mesh, connectivity)
    @test basecode(mesh) == (3, 0)
    vir = vertices(mesh)
    @test nshapes(vir.right) == nshapes(vir.left)
    @test nshapes(vir.right) == nshapes(connectivity.right)
    geom = geometry(mesh)
    box = initbox(geom[1])
    for i in 1:length(geom)
        updatebox!(box, geom[i])
    end
    box[1] = (box[1] + box[2]) / 2
    ir = baseincrel(mesh)
    el = eselect(ir; box = box, inflate = 0.0009)
    @test length(el)  == 498
    label(mesh, (3, 0), :left, el, 8)
    el = eselect(ir; label = 8)
    @test length(el)  == 498

    halfmesh = submesh(mesh, el)
    # @show  summary(halfmesh)
    @test nrelations(baseincrel(halfmesh)) == 498

    bir = boundary(mesh)
    bir2 = increl(mesh, (ir_code(bir), "boundary"))
    @test summary(bir) == summary(bir2)
    # @test length(el) == 44
    # @show  summary(mesh)
    # vtkwrite("trunc_cyl_shell_0-full", ir)
    # vtkwrite("trunc_cyl_shell_0-subset", ir_subset(ir, el))
    try rm("trunc_cyl_shell_0-full" * ".vtu"); catch end
    try rm("trunc_cyl_shell_0-subset" * ".vtu"); catch end
    try rm("trunc_cyl_shell_0-vertices" * ".vtu"); catch end
    return true
end
end
using .mmvtx4
mmvtx4.test()


text:
abstract type AbstractDimIndices{T,N} <: AbstractArray{T,N} end

dims(di::AbstractDimIndices) = di.dims

Base.size(di::AbstractDimIndices) = map(length, dims(di))
Base.axes(di::AbstractDimIndices) = map(d -> axes(d, 1), dims(di))

for f in (:getindex, :view, :dotview)
    @eval begin
        @propagate_inbounds Base.$f(A::AbstractDimIndices, i1::Selector, I::Selector...) =
            Base.$f(A, dims2indices(A, i1, I)...)
        @propagate_inbounds function Base.$f(A::AbstractDimIndices, i1::Dimension, I::Dimension...; kw...)
            Base.$f(A, dims2indices(A, i1, I..., kwdims(values(kw))...)...)
        end
    end
end

(::Type{<:AbstractDimIndices})(::Nothing; kw...) = throw(ArgumentError("Object has no `dims` method"))
(::Type{T})(x; kw...) where T<:AbstractDimIndices = T(dims(x); kw...)
(::Type{T})(dim::Dimension; kw...) where T<:AbstractDimIndices = T((dim,); kw...)

_format(dims::Tuple{}) = ()
function _format(dims::Tuple)
    ax = map(d -> axes(val(d), 1), dims)
    return format(dims, ax)
end

"""
    DimIndices <: AbstractArray

    DimIndices(x)
    DimIndices(dims::Tuple)
    DimIndices(dims::Dimension)

Like `CartesianIndices`, but for `Dimension`s. Behaves as an `Array` of `Tuple`
of `Dimension(i)` for all combinations of the axis indices of `dims`.

This can be used to view/index into arbitrary dimensions over an array, and
is especially useful when combined with `otherdims`, to iterate over the
indices of unknown dimension.
"""
struct DimIndices{T,N,D<:Tuple{Vararg{<:Dimension}}} <: AbstractDimIndices{T,N}
    dims::D
end
function DimIndices(dims::D) where {D<:Tuple{Vararg{<:Dimension}}}
    T = typeof(map(d -> rebuild(d, 1), dims))
    N = length(dims)
    dims = N > 0 ? _format(dims) : dims
    DimIndices{T,N,typeof(dims)}(dims)
end

function Base.getindex(di::DimIndices, i1::Int, I::Int...)
    map(dims(di), (i1, I...)) do d, i
        rebuild(d, axes(d, 1)[i])
    end
end

"""
    DimPoints <: AbstractArray

    DimPoints(x; order)
    DimPoints(dims::Tuple; order)
    DimPoints(dims::Dimension; order)

Like `CartesianIndices`, but for the point values of the dimension index.
Behaves as an `Array` of `Tuple` lookup values (whatever they are) for all
combinations of the lookup values of `dims`.

Either a `Dimension`, a `Tuple` of `Dimension` or an object that defines a
`dims` method can be passed in.

# Keywords

- `order`: determines the order of the points, the same as the order of `dims` by default.
"""
struct DimPoints{T,N,D<:DimTuple,O} <: AbstractDimIndices{T,N}
    dims::D
    order::O
end
function DimPoints(dims::DimTuple; order=dims)
    order = map(d -> basetypeof(d)(), order)
    T = Tuple{map(eltype, dims)...}
    N = length(dims)
    dims = N > 0 ? _format(dims) : dims
    DimPoints{T,N,typeof(dims),typeof(order)}(dims, order)
end

function Base.getindex(dp::DimPoints, i1::Int, I::Int...)
    # Get dim-wrapped point values at i1, I...
    pointdims = map(dims(dp), (i1, I...)) do d, i
        rebuild(d, d[i])
    end
    # Return the unwrapped point sorted by `order
    return map(val, DD.dims(pointdims, dp.order))
end

"""
    DimKeys <: AbstractArray

    DimKeys(x)
    DimKeys(dims::Tuple)
    DimKeys(dims::Dimension)

Like `CartesianIndices`, but for the lookup values of Dimensions. Behaves as an
`Array` of `Tuple` of `Dimension(At(lookupvalue))` for all combinations of the
lookup values of `dims`.
"""
struct DimKeys{T,N,D<:Tuple{<:Dimension,Vararg{<:Dimension}},S} <: AbstractDimIndices{T,N}
    dims::D
    selectors::S
end
function DimKeys(dims::DimTuple; atol=nothing, selectors=_selectors(dims, atol))
    DimKeys(dims, selectors)
end
function DimKeys(dims::DimTuple, selectors)
    T = typeof(map(rebuild, dims, selectors))
    N = length(dims)
    dims = N > 0 ? _format(dims) : dims
    DimKeys{T,N,typeof(dims),typeof(selectors)}(dims, selectors)
end

function _selectors(dims, atol)
    map(dims) do d
        atol1 = _atol(eltype(d), atol)
        At{eltype(d),typeof(atol1),Nothing}(first(d), atol1, nothing)
    end
end
function _selectors(dims, atol::Tuple)
    map(dims, atol) do d, a
        atol1 = _atol(eltype(d), a)
        At{eltype(d),typeof(atol1),Nothing}(first(d), atol1, nothing)
    end
end
function _selectors(dims, atol::Nothing)
    map(dims) do d
        atolx = _atol(eltype(d), nothing)
        v = first(val(d))
        At{typeof(v),typeof(atolx),Nothing}(v, atolx, nothing)
    end
end

_atol(::Type, atol) = atol
_atol(T::Type{<:AbstractFloat}, atol::Nothing) = eps(T)

function Base.getindex(di::DimKeys, i1::Int, I::Int...)
    map(dims(di), di.selectors, (i1, I...)) do d, s, i
        rebuild(d, rebuild(s; val=index(d)[i])) # At selector with the value at i
    end
end


text:
mutable struct CodeGen
    ctx::LLVM.Context
    builder::LLVM.Builder
    current_scope::CurrentScope
    mod::LLVM.Module

    CodeGen(ctx::LLVM.Context) =
        new(
            ctx,
            LLVM.Builder(ctx),
            CurrentScope(),
            LLVM.Module("KaleidoscopeModule", ctx),
        )
end

current_scope(cg::CodeGen) = cg.current_scope
function new_scope(f, cg::CodeGen)
    open_scope!(current_scope(cg))
    f()
    pop!(current_scope(cg))
end
Base.show(io::IO, cg::CodeGen) = print(io, "CodeGen")

function create_entry_block_allocation(cg::CodeGen, fn::LLVM.Function, varname::String)
    local alloc
    LLVM.Builder(cg.ctx) do builder
        # Set the builder at the start of the function
        entry_block = LLVM.entry(fn)
        if isempty(LLVM.instructions(entry_block))
            LLVM.position!(builder, entry_block)
        else
            LLVM.position!(builder, first(LLVM.instructions(entry_block)))
        end
        alloc = LLVM.alloca!(builder, LLVM.DoubleType(cg.ctx), varname)
    end
    return alloc
end

function codegen(cg::CodeGen, expr::NumberExprAST)
    return LLVM.ConstantFP(LLVM.DoubleType(cg.ctx), expr.val)
end

function codegen(cg::CodeGen, expr::VariableExprAST)
    V = get(current_scope(cg), expr.name, nothing)
    V == nothing && error("did not find variable $(expr.name)")
    return LLVM.load!(cg.builder, V, expr.name)
end

function codegen(cg::CodeGen, expr::BinaryExprAST)
    if expr.op == Kinds.EQUAL
        var = expr.lhs
        if !(var isa VariableExprAST)
            error("destination of '=' must be a variable")
        end
        R = codegen(cg, expr.rhs)
        V = get(current_scope(cg), var.name, nothing)
        V == nothing && error("unknown variable name $(var.name)")
        LLVM.store!(cg.builder, R, V)
        return R
    end
    L = codegen(cg, expr.lhs)
    R = codegen(cg, expr.rhs)

    if expr.op == Kinds.PLUS
        return LLVM.fadd!(cg.builder, L, R, "addtmp")
    elseif expr.op == Kinds.MINUS
        return LLVM.fsub!(cg.builder, L, R, "subtmp")
    elseif expr.op == Kinds.STAR
        return LLVM.fmul!(cg.builder, L, R, "multmp")
    elseif expr.op == Kinds.SLASH
        return LLVM.fdiv!(cg.builder, L, R, "divtmp")
    elseif expr.op == Kinds.LESS
        L = LLVM.fcmp!(cg.builder, LLVM.API.LLVMRealOLT, L, R, "cmptmp")
        return LLVM.uitofp!(cg.builder, L, LLVM.DoubleType(cg.ctx), "booltmp")
    elseif expr.op == Kinds.GREATER
        L = LLVM.fcmp!(cg.builder, LLVM.API.LLVMRealOGT, L, R, "cmptmp")
        return LLVM.uitofp!(cg.builder, L, LLVM.DoubleType(cg.ctx), "booltmp")
    else
        error("Unhandled binary operator $(expr.op)")
    end
end

function codegen(cg::CodeGen, expr::CallExprAST)
    if !haskey(LLVM.functions(cg.mod), expr.callee)
        error("encountered undeclared function $(expr.callee)")
    end
    func =  LLVM.functions(cg.mod)[expr.callee]

    if length(LLVM.parameters(func)) != length(expr.args)
        error("number of parameters mismatch")
    end

    args = LLVM.Value[]
    for v in expr.args
        push!(args, codegen(cg, v))
    end

    return LLVM.call!(cg.builder, func, args, "calltmp")
end

function codegen(cg::CodeGen, expr::PrototypeAST)
    if haskey(LLVM.functions(cg.mod), expr.name)
            error("existing function exists")
    end
    args = [LLVM.DoubleType(cg.ctx) for i in 1:length(expr.args)]
    func_type = LLVM.FunctionType(LLVM.DoubleType(cg.ctx), args)
    func = LLVM.Function(cg.mod, expr.name, func_type)
    LLVM.linkage!(func, LLVM.API.LLVMExternalLinkage)

    for (i, param) in enumerate(LLVM.parameters(func))
        LLVM.name!(param, expr.args[i])
    end
    return func
end

function codegen(cg::CodeGen, expr::FunctionAST)
    # create new function...
    the_function = codegen(cg, expr.proto)

    entry = LLVM.BasicBlock(the_function, "entry", cg.ctx)
    LLVM.position!(cg.builder, entry)

    new_scope(cg) do
        for (i, param) in enumerate(LLVM.parameters(the_function))
            argname = expr.proto.args[i]
            alloc = create_entry_block_allocation(cg, the_function, argname)
            LLVM.store!(cg.builder, param, alloc)
            current_scope(cg)[argname] = alloc
        end

        body = codegen(cg, expr.body)
        LLVM.ret!(cg.builder, body)
        LLVM.verify(the_function)
    end
    return the_function
end

function codegen(cg::CodeGen, expr::IfExprAST)
    func = LLVM.parent(LLVM.position(cg.builder))
    then = LLVM.BasicBlock(func, "then", cg.ctx)
    elsee = LLVM.BasicBlock(func, "else", cg.ctx)
    merge = LLVM.BasicBlock(func, "ifcont", cg.ctx)

    local phi
    new_scope(cg) do
        # if
        cond = codegen(cg, expr.cond)
        zero = LLVM.ConstantFP(LLVM.DoubleType(cg.ctx), 0.0)
        condv = LLVM.fcmp!(cg.builder, LLVM.API.LLVMRealONE, cond, zero, "ifcond")
        LLVM.br!(cg.builder, condv, then, elsee)

        # then
        LLVM.position!(cg.builder, then)
        thencg = codegen(cg, expr.then)
        LLVM.br!(cg.builder, merge)
        then_block = position(cg.builder)

        # else
        LLVM.position!(cg.builder, elsee)
        elsecg = codegen(cg, expr.elsee)
        LLVM.br!(cg.builder, merge)
        else_block = position(cg.builder)

        # merge
        LLVM.position!(cg.builder, merge)
        phi = LLVM.phi!(cg.builder, LLVM.DoubleType(cg.ctx), "iftmp")
        append!(LLVM.incoming(phi), [(thencg, then_block), (elsecg, else_block)])
    end

    return phi
end

function codegen(cg::CodeGen, expr::ForExprAST)
    new_scope(cg) do
        # Allocate loop variable
        startblock = position(cg.builder)
        func = LLVM.parent(startblock)
        alloc = create_entry_block_allocation(cg, func, expr.varname)
        current_scope(cg)[expr.varname] = alloc
        start = codegen(cg, expr.start)
        LLVM.store!(cg.builder, start, alloc)

        # Loop block
        loopblock = LLVM.BasicBlock(func, "loop", cg.ctx)
        LLVM.br!(cg.builder, loopblock)
        LLVM.position!(cg.builder, loopblock)

        # Code for loop block
        codegen(cg, expr.body)
        step = codegen(cg, expr.step)
        endd = codegen(cg, expr.endd)

        curvar = LLVM.load!(cg.builder, alloc, expr.varname)
        nextvar = LLVM.fadd!(cg.builder, curvar, step, "nextvar")
        LLVM.store!(cg.builder, nextvar, alloc)

        endd = LLVM.fcmp!(cg.builder, LLVM.API.LLVMRealONE, endd,
            LLVM.ConstantFP(LLVM.DoubleType(cg.ctx), 0.0))

        loopendblock = position(cg.builder)
        afterblock = LLVM.BasicBlock(func, "afterloop", cg.ctx)

        LLVM.br!(cg.builder, endd, loopblock, afterblock)
        LLVM.position!(cg.builder, afterblock)
    end

    # loops return 0.0 for now
    return LLVM.ConstantFP(LLVM.DoubleType(cg.ctx), 0.0)
end

function codegen(cg::CodeGen, expr::VarExprAST)
    local initval
    for (varname, init) in expr.varnames
        initval = codegen(cg, init)
        local V
        if isglobalscope(current_scope(cg))
            V = LLVM.GlobalVariable(cg.mod, LLVM.DoubleType(cg.ctx), varname)
            LLVM.initializer!(V, initval)
        else
            func = LLVM.parent(LLVM.position(cg.builder))
            V = create_entry_block_allocation(cg, func, varname)
            LLVM.store!(cg.builder, initval, V)
        end
        current_scope(cg)[varname] = V
    end
    return initval
end

function codegen(cg::CodeGen, block::BlockExprAST)
    local v
    new_scope(cg) do
        for expr in block.exprs
            v = codegen(cg, expr)
        end
    end
    return v
end


text:
# All types `J <: AbstractJob` must implement:
#
# - `J(submission::JobSubmission)`: create an instance of `J` from `submission`
# - `submission(job::J)`: return the `JobSubmission` used to create `job`
# - `isvalid(submission::JobSubmission, ::Type{J})`: return true if `submission` is a valid input for `J`, false otherwise
# - `Base.run(job::J)`: execute `job`
# - `Base.summary(job::J)`: a short string identifying/describing `job`

abstract type AbstractJob end

reply_status(job::AbstractJob, args...; kwargs...) = reply_status(submission(job), "Nanosoldier/$(nameof(typeof(job)))", args...; kwargs...)
reply_comment(job::AbstractJob, args...; kwargs...) = reply_comment(submission(job), args...; kwargs...)
upload_report_repo!(job::AbstractJob, args...; kwargs...) = upload_report_repo!(submission(job), args...; kwargs...)

function branchref(config::Config, reponame::AbstractString, branchname::AbstractString)
    shastr = GitHub.branch(reponame, branchname; auth=config.auth).commit.sha
    return BuildRef(reponame, shastr)
end

function tagref(config::Config, reponame::AbstractString, tagname::AbstractString)
    shastr = GitHub.tag(reponame, tagname; auth=config.auth).object["sha"]
    return BuildRef(reponame, shastr)
end

# check that isdaily is well-formed (no extra parameters, on a recent master commit, not a PR)
# and not accidentally submitted elsewhere
function validatate_isdaily(submission::JobSubmission)
    if submission.prnumber === nothing && submission.kwargs == Dict(:isdaily => "true")
        config = submission.config
        for commit in GitHub.commits(config.trackrepo; auth=config.auth, page_limit=1, params=Dict("per_page" => 50))[1]
            if commit.sha == submission.statussha
                return
            end
        end
    end
    error("invalid commit to run isdaily")
end

datedirname(date::Dates.Date) = joinpath(Dates.format(date, dateformat"yyyy-mm"),
                                         Dates.format(date, dateformat"dd"))

# Put `str` into Markdown literally
# XXX: In a table, | would instead written with | instead.
#      Should we make that a bool arg to give the context?
markdown_escaped(str) = replace(str, r"[\\`*_#+-.!{}[\]()<>|]" => s"\\\0")

# Put `str` inside Markdown code marks
function markdown_escaped_code(str)
    ticks = eachmatch(r"`+", str)
    isempty(ticks) && return "`$str`"
    ticks = maximum(x -> length(x.match), ticks) + 1
    ticks = "`"^ticks
    return string(ticks, startswith(str, '`') ? " " : "", str, endswith(str, '`') ? " " : "", ticks)
end

include("BenchmarkJob.jl")
include("PkgEvalJob.jl")