### A Pluto.jl notebook ###
# v0.17.5

using Markdown
using InteractiveUtils

# ╔═╡ 4ea09c13-a7ea-4d0d-98bc-90c9a8fdf28d
begin
using Plots, Images,DataFrames,CSV,PlotThemes
gr()
#theme(:orange)
img = load(download("http://127.0.0.1:8080/halfcourt.png"))
x = range(-250, 250, length=size(img,1))
y = range(-50,420, length=size(img,2))

plot(x,y,img)
end

# ╔═╡ 411103c8-8636-11ec-2150-89fe0acea2d4
md"# NBA shot stat"

# ╔═╡ 05e3ea97-6b40-4d8e-88a0-8a86465fc9be
data=[[95,242,1],[129,43,0],[20,10,0],[-127,239,0],[-13,14,1],[30,252,1],[168,208,0],[130,17,1],[9,21,0],[-2,264,0],[-74,256,0],[-8,15,0],[110,45,1],[-75,241,1],[1,22,1],[7,20,1],[45,257,0],[-210,145,0],[226,12,0],[233,37,0],[196,120,1],[-221,144,0],[149,209,0],[-17,16,1],[-133,275,1],[-103,236,1],[-159,221,0],[127,101,0],[29,9,1],[-117,227,0],[192,184,1],[171,197,0],[-11,15,0],[239,17,1],[3,115,0],[-39,260,1],[-56,167,1],[-143,221,0],[79,251,0],[-100,232,1],[89,237,1],[22,250,1],[-47,13,0],[-4,-1,0],[-171,184,0],[-14,257,1],[-227,10,0],[90,273,0],[-4,3,1],[60,246,1],[-4,6,1],[154,148,1],[-168,174,0],[174,199,0],[-102,224,0],[-233,-5,1],[-59,232,0],[32,19,1],[-228,26,0],[180,187,0],[179,173,1],[-19,123,1],[76,44,1],[-100,267,0],[206,137,0],[155,157,1],[123,233,0],[-19,58,0],[-8,6,1],[-116,231,0],[-209,142,0],[79,165,1],[-3,18,0],[160,206,0],[-226,111,1],[-3,24,1],[174,19,0],[-13,17,1],[30,111,0],[-222,-13,1],[164,234,1],[-156,214,0],[-9,272,0],[-146,215,0],[5,27,1],[-90,243,1],[-226,126,0],[-1,120,1],[-7,22,1],[-229,112,0],[-5,25,1],[-61,127,1],[98,247,0],[120,237,1],[145,206,0],[-68,248,0],[140,260,0],[231,10,0],[-171,193,0],[-16,11,0],[232,-8,0],[5,20,0],[111,255,1],[-130,219,1],[51,287,0],[189,168,1],[13,8,1],[-205,46,1],[-100,226,1],[4,18,0],[-2,25,1],[130,54,1],[223,117,0],[8,15,1],[-8,11,1],[2,341,0],[68,124,1],[88,241,1],[-6,274,0],[-8,11,1],[-19,16,0],[-123,226,0],[-229,-8,0],[-231,-25,1],[134,207,1],[-221,39,0],[163,186,0],[-77,257,0],[76,244,1],[-5,17,1],[7,19,0],[-233,8,1],[-35,135,1],[154,201,1],[-165,206,1],[12,257,1],[218,120,0],[70,22,0],[3,24,1],[87,239,1],[229,75,1],[98,231,1],[7,30,1],[35,159,1],[-18,0,0],[-92,63,0],[55,212,0],[-3,13,1],[-158,104,0],[-71,243,0],[-21,169,0],[109,66,1],[36,99,0],[170,203,0],[163,189,1],[236,26,1],[-140,226,0],[-237,42,1],[80,233,1],[201,153,0],[-1,252,0],[114,84,1],[-131,226,1],[-112,111,0],[-84,280,0],[-7,79,0],[-194,13,0],[-1,104,0],[26,259,0],[-8,34,1],[58,247,0],[-229,125,0],[-128,222,1],[-6,24,0],[98,121,1],[-190,167,0],[94,242,0],[0,34,0],[-119,47,1],[-103,221,0],[6,20,0],[-116,229,1],[16,115,1],[-92,169,0],[-128,134,0],[-7,259,0],[129,220,1],[-5,8,0],[14,259,0],[49,216,1],[-163,215,1],[-67,127,1],[130,220,0],[96,-12,1],[-155,195,0],[7,150,1],[116,236,0],[-15,19,0],[-231,-16,0],[-205,145,1],[-103,129,0],[190,162,0],[58,260,1],[-157,136,1],[-108,150,0],[-3,174,1],[-18,264,0],[-197,199,1],[-67,249,0],[138,215,0],[-78,257,1],[-136,224,0],[65,137,0],[-6,16,0],[100,268,0],[-42,74,0],[100,180,0],[-129,232,0],[-136,216,0],[4,5,1],[-121,217,1],[-192,153,0],[193,159,0],[127,211,0],[102,202,0],[25,12,1],[128,-17,0],[136,239,0],[-55,173,1],[-123,146,1],[-163,145,0],[-121,148,1],[-40,65,0],[-11,144,1],[1,296,0],[-155,207,0],[-7,127,0],[-94,257,0],[88,194,1],[-140,229,1],[72,193,1],[94,232,1],[141,241,1],[105,150,0],[106,266,1],[142,218,0],[83,138,1],[120,253,0],[-35,206,1],[5,21,1],[-96,106,0],[40,256,1],[51,240,1],[207,150,0],[-200,152,0],[-230,1,0],[96,140,1],[-47,242,1],[16,0,1],[-179,143,0],[-19,7,1],[67,25,0],[-13,189,1],[221,13,0],[201,141,0],[29,142,1],[-35,25,1],[-203,149,1],[3,-10,1],[-115,137,0],[-229,86,0],[62,154,0],[-7,0,1],[166,179,1],[5,138,1],[119,164,0],[13,270,0],[226,92,0],[-225,81,1],[-6,12,1],[-10,5,1],[9,8,0],[182,164,0],[152,199,0],[1,3,1],[88,185,1],[131,3,0],[83,250,1],[-19,11,1],[141,217,0],[146,201,1],[46,154,1],[-110,289,0],[-5,13,1],[-224,8,1],[-29,280,1],[-18,260,0],[10,15,1],[-24,17,1],[171,193,1],[107,251,0],[-16,1,1],[35,130,0],[100,242,0],[-225,-1,0],[-9,285,0],[-155,226,0],[172,211,0],[18,16,0],[136,148,0],[-82,247,0],[22,106,0],[-232,15,0],[-83,374,0],[-28,291,0],[-7,31,0],[-115,147,1],[141,142,1],[-111,215,0],[49,222,1],[20,8,1],[112,153,0],[-226,-15,0],[40,283,1],[-226,84,1],[-161,211,0],[-4,251,0],[-101,-10,0],[141,103,1],[-19,8,1],[99,242,1],[138,113,0],[-171,199,0],[-9,23,0],[100,243,0],[-1,11,1],[-8,28,1],[-5,29,0],[-11,20,0],[167,195,0],[-7,22,1],[-210,150,1],[-118,237,0],[-222,27,0],[-59,132,1],[-234,22,0],[-2,17,1],[-107,188,0],[136,222,1],[122,236,1],[-190,46,1],[60,147,0],[19,257,1],[-144,75,1],[-126,225,0],[-52,110,1],[116,221,1],[-170,194,0],[-81,279,1],[-2,28,1],[93,260,0],[-145,51,0],[-102,71,0],[49,167,1],[11,25,1],[92,214,0],[3,15,0],[-226,17,0],[46,135,1],[7,30,0],[119,241,0],[-16,10,0],[138,155,1],[-174,197,1],[6,21,1],[9,257,0],[-231,8,1],[-127,252,1],[-228,62,0],[205,23,1],[-7,6,1],[-203,148,1],[0,14,1],[-201,153,1],[-5,0,1],[139,232,0],[166,199,0],[221,136,1],[-222,74,0],[217,127,0],[76,266,0],[-214,5,1],[190,187,0],[7,11,1],[-19,8,0],[66,219,0],[-43,79,0],[-94,256,1],[-137,225,1],[-11,74,0],[89,246,0],[-236,-22,1],[127,231,0],[-16,7,1],[-182,197,1],[24,32,1],[-14,21,1],[18,263,1],[-132,263,0],[-1,18,1],[128,241,1],[76,258,1],[214,141,0],[-232,46,1],[-185,188,1],[107,148,1],[84,255,1],[191,189,1],[8,15,0],[230,62,1],[-228,-13,1],[114,256,0],[78,243,1],[-222,52,0],[90,285,1],[-150,204,0],[119,52,1],[-86,25,1],[-6,257,1],[-58,22,0],[-185,155,1],[-9,1,1],[-79,229,1],[-220,52,0],[-207,155,0],[-96,256,1],[100,247,0],[-234,5,0],[8,10,1],[13,1,1],[-153,231,0],[3,274,1],[228,21,0],[-205,134,1],[-135,168,0],[-13,8,1],[119,163,1],[-41,243,1],[185,183,0],[2,22,0],[-19,20,1],[234,16,0],[15,15,1],[27,76,0],[198,160,0],[-9,15,1],[157,197,1],[116,251,0],[124,236,1],[-197,176,0],[-1,6,0],[-7,21,1],[-228,-22,0],[-149,228,1],[53,248,1],[8,269,1],[-126,235,0],[-235,56,1],[33,253,0],[-2,146,0],[3,7,1],[-131,226,0],[-57,254,1],[-136,241,0],[-18,4,1],[-6,21,1],[-146,216,1],[22,272,1],[-147,226,1],[29,276,0],[33,255,0],[14,15,0],[-116,225,0],[-89,259,0],[154,212,1],[-228,8,0],[-95,238,0],[-20,13,0],[10,20,0],[10,12,1],[226,97,1],[11,10,1],[199,180,0],[117,222,1],[122,81,0],[136,127,1],[128,239,1],[-144,221,1],[169,203,0],[126,142,1],[126,219,0],[-127,77,1],[99,230,0],[145,209,0],[12,131,1],[-209,133,0],[-30,159,1],[-164,189,1],[-230,-11,0],[-8,20,1],[6,248,1],[-62,138,0],[8,13,1],[67,250,0],[23,258,1],[6,9,1],[235,93,0],[16,21,1],[-8,18,1],[-130,236,1],[-224,138,1],[75,325,1],[-34,20,0],[-128,256,0],[-217,243,0],[8,16,0],[-9,13,0],[140,210,1],[6,157,1],[42,22,0],[-122,162,1],[87,244,1],[47,252,1],[230,64,0],[18,7,1],[144,480,0],[73,235,0],[18,261,1],[-231,1,0],[132,158,1],[20,37,0],[-75,232,1],[185,168,1],[-152,198,0],[-9,26,0],[103,232,0],[-162,187,0],[3,8,0],[65,253,1],[-13,260,0],[3,5,0],[24,256,0],[-193,171,0],[95,169,1],[0,3,0],[160,185,0],[-79,237,1],[-6,572,0],[-5,15,0],[214,137,1],[105,241,1],[-179,185,1],[231,95,0],[-40,263,0],[-179,181,0],[13,18,0],[-19,263,1],[-221,121,0],[227,12,0],[-226,113,0],[-150,206,0],[133,220,0],[-9,73,0],[-170,188,1],[-18,20,1],[70,252,0],[-78,159,0],[152,215,1],[-136,216,1],[-211,122,1],[175,188,1],[-131,255,0],[2,264,1],[61,256,1],[-78,157,1],[125,227,0],[3,15,1],[131,238,1],[-169,216,1],[-226,71,1],[-144,244,0],[-12,18,1],[82,199,1],[-157,210,0],[159,201,0],[-6,278,1],[110,147,0],[165,218,1],[46,104,1],[235,27,1],[-196,162,0],[-16,163,1],[6,30,1],[190,169,1],[141,209,0],[149,229,0],[-195,452,0],[-196,164,1],[-170,131,1],[5,11,1],[145,218,1],[-168,134,0],[19,36,0],[9,17,1],[-45,253,1],[131,227,1],[-50,263,1],[-1,128,0],[94,36,1],[146,202,0],[-38,273,1],[-5,12,1],[223,126,0],[67,55,1],[-163,188,0],[-18,10,0],[16,8,0],[-19,9,1],[-70,248,1],[235,82,0],[1,6,1],[37,47,0],[163,197,0],[130,225,0],[-229,6,0],[230,67,0],[-229,-4,0],[138,210,0],[-36,6,0],[-228,25,0],[-55,270,1],[-27,15,1],[3,34,1],[13,15,1],[13,41,0],[-32,16,0],[231,50,1],[-195,174,1],[-4,253,0],[106,10,1],[76,258,0],[234,22,0],[177,188,1],[214,120,1],[27,21,1],[88,226,0],[190,199,0],[111,231,0],[-15,6,1],[204,127,0],[38,22,1],[54,243,0],[-95,232,1],[-186,174,1],[-186,193,0],[-25,28,0],[-152,206,0],[-134,281,1],[-117,155,1],[157,247,0],[13,265,0],[2,102,1],[105,253,1],[26,33,0],[-2,23,1],[127,228,0],[-6,270,0],[225,53,0],[145,214,1],[36,262,0],[9,20,1],[-171,605,0],[226,109,0],[-69,156,1],[130,227,1],[160,211,1],[156,237,0],[167,199,0],[225,41,1],[144,231,0],[128,257,1],[-13,9,1],[1,59,1],[28,267,0],[127,226,1],[223,66,1],[128,231,0],[-6,18,1],[3,11,1],[-156,209,0],[-5,11,1],[1,32,0],[104,247,1],[-102,251,0],[52,91,0],[2,23,1],[-7,657,0],[-5,252,0],[85,267,0],[66,243,0],[116,232,0],[192,180,1],[115,138,1],[-3,16,0],[39,676,0],[6,0,1],[130,67,1],[132,226,1],[-2,78,1],[-89,263,1],[-96,147,1],[-23,12,0],[6,20,0],[-145,426,0],[123,42,0],[-194,151,0],[-82,231,0],[-55,17,0],[-4,25,0],[11,17,1],[-3,20,0],[-228,6,0],[-199,142,1],[198,139,1],[-29,251,0],[6,10,1],[-8,-4,1],[-228,31,0],[-60,243,1],[228,69,0],[-81,238,0],[10,11,1],[152,81,0],[198,36,0],[-134,262,0],[-79,362,1],[-20,251,1],[73,253,1],[8,13,1],[95,38,1],[-18,6,1],[180,185,1],[-13,266,1],[61,250,0],[-112,-1,1],[-16,269,1],[13,252,0],[-35,41,1],[125,262,1],[62,251,1],[-17,36,0],[176,186,1],[-89,275,1],[-168,217,0],[226,78,0],[105,163,0],[5,20,1],[4,18,0],[-166,191,1],[-144,609,0],[232,14,0],[-18,260,0],[101,85,0],[2,36,1],[236,20,1],[-144,218,1],[-102,142,1],[-234,-4,0],[-227,-1,0],[-46,158,1],[20,267,0],[104,246,0],[-76,247,1],[63,177,0],[-6,10,1],[230,56,0],[-133,222,1],[-177,183,0],[5,-5,0],[204,5,0],[-3,34,1],[140,84,1],[130,214,1],[114,231,1],[209,162,0],[-8,135,0],[18,26,0],[241,53,1],[165,299,0],[-124,243,1],[-144,204,1],[30,35,0],[143,230,0],[-160,122,0],[-186,80,0],[214,126,0],[-6,4,1],[-157,209,0],[-235,0,1],[-174,195,0],[-8,7,1],[-111,246,0],[-221,113,1],[0,11,0],[3,8,0],[-175,189,1],[26,174,1],[206,133,1],[6,12,1],[63,242,0],[117,217,0],[-24,18,1],[126,215,1],[224,84,0],[225,26,0],[-131,231,0],[92,157,1],[132,229,0],[-58,50,1],[-25,284,1],[2,278,1],[56,124,0],[38,248,1],[-177,210,0],[-11,16,1],[-23,47,1],[-32,32,0],[-236,33,1],[136,237,0],[71,160,1],[81,268,0],[9,18,1],[150,210,1],[-147,235,1],[90,248,0],[-119,100,0],[136,58,0],[83,279,0],[-109,132,1],[106,232,0],[89,144,0],[-215,126,0],[-113,115,1],[56,110,1],[103,142,1],[109,235,0],[158,-1,1],[184,190,1],[60,253,0],[-145,112,1],[18,27,0],[59,257,1],[-7,32,1],[217,132,1]]

# ╔═╡ 05f077a2-e28d-4ee7-b45f-49f94a251dd6
struct shot
  x::Int64
  y::Int64
  f::Bool
end

# ╔═╡ a082b107-834a-4135-923b-f8da543ab4fb
begin

  mapshot=map(x->Dict("x" => x[1], "y" => x[2], "f" =>x[3]),data)
  x_value=map(x->x["x"],mapshot)
  y_value=map(x->x["y"],mapshot)
  scatter!(x_value,y_value,markersize=0.8,markerstrokewidth=0.08,xlims=(-250,250),ylims=(-50,420))
end

# ╔═╡ 00000000-0000-0000-0000-000000000001
PLUTO_PROJECT_TOML_CONTENTS = """
[deps]
CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
Images = "916415d5-f1e6-5110-898d-aaa5f9f070e0"
PlotThemes = "ccf2f8ad-2431-5c83-bf29-c5338b663b6a"
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"

[compat]
CSV = "~0.10.2"
DataFrames = "~1.3.2"
Images = "~0.25.1"
PlotThemes = "~2.0.1"
Plots = "~1.25.7"
"""

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

julia_version = "1.7.1"
manifest_format = "2.0"

[[deps.AbstractFFTs]]
deps = ["ChainRulesCore", "LinearAlgebra"]
git-tree-sha1 = "6f1d9bc1c08f9f4a8fa92e3ea3cb50153a1b40d4"
uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c"
version = "1.1.0"

[[deps.Adapt]]
deps = ["LinearAlgebra"]
git-tree-sha1 = "af92965fb30777147966f58acb05da51c5616b5f"
uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e"
version = "3.3.3"

[[deps.ArgTools]]
uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f"

[[deps.ArnoldiMethod]]
deps = ["LinearAlgebra", "Random", "StaticArrays"]
git-tree-sha1 = "62e51b39331de8911e4a7ff6f5aaf38a5f4cc0ae"
uuid = "ec485272-7323-5ecc-a04f-4719b315124d"
version = "0.2.0"

[[deps.ArrayInterface]]
deps = ["Compat", "IfElse", "LinearAlgebra", "Requires", "SparseArrays", "Static"]
git-tree-sha1 = "1bdcc02836402d104a46f7843b6e6730b1948264"
uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9"
version = "4.0.2"

[[deps.Artifacts]]
uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33"

[[deps.AxisAlgorithms]]
deps = ["LinearAlgebra", "Random", "SparseArrays", "WoodburyMatrices"]
git-tree-sha1 = "66771c8d21c8ff5e3a93379480a2307ac36863f7"
uuid = "13072b0f-2c55-5437-9ae7-d433b7a33950"
version = "1.0.1"

[[deps.AxisArrays]]
deps = ["Dates", "IntervalSets", "IterTools", "RangeArrays"]
git-tree-sha1 = "d127d5e4d86c7680b20c35d40b503c74b9a39b5e"
uuid = "39de3d68-74b9-583c-8d2d-e117c070f3a9"
version = "0.4.4"

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

[[deps.Bzip2_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "19a35467a82e236ff51bc17a3a44b69ef35185a2"
uuid = "6e34b625-4abd-537c-b88f-471c36dfa7a0"
version = "1.0.8+0"

[[deps.CEnum]]
git-tree-sha1 = "215a9aa4a1f23fbd05b92769fdd62559488d70e9"
uuid = "fa961155-64e5-5f13-b03f-caf6b980ea82"
version = "0.4.1"

[[deps.CSV]]
deps = ["CodecZlib", "Dates", "FilePathsBase", "InlineStrings", "Mmap", "Parsers", "PooledArrays", "SentinelArrays", "Tables", "Unicode", "WeakRefStrings"]
git-tree-sha1 = "9519274b50500b8029973d241d32cfbf0b127d97"
uuid = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
version = "0.10.2"

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

[[deps.Calculus]]
deps = ["LinearAlgebra"]
git-tree-sha1 = "f641eb0a4f00c343bbc32346e1217b86f3ce9dad"
uuid = "49dc2e85-a5d0-5ad3-a950-438e2897f1b9"
version = "0.5.1"

[[deps.CatIndices]]
deps = ["CustomUnitRanges", "OffsetArrays"]
git-tree-sha1 = "a0f80a09780eed9b1d106a1bf62041c2efc995bc"
uuid = "aafaddc9-749c-510e-ac4f-586e18779b91"
version = "0.2.2"

[[deps.ChainRulesCore]]
deps = ["Compat", "LinearAlgebra", "SparseArrays"]
git-tree-sha1 = "f9982ef575e19b0e5c7a98c6e75ee496c0f73a93"
uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"
version = "1.12.0"

[[deps.ChangesOfVariables]]
deps = ["ChainRulesCore", "LinearAlgebra", "Test"]
git-tree-sha1 = "bf98fa45a0a4cee295de98d4c1462be26345b9a1"
uuid = "9e997f8a-9a97-42d5-a9f1-ce6bfc15e2c0"
version = "0.1.2"

[[deps.Clustering]]
deps = ["Distances", "LinearAlgebra", "NearestNeighbors", "Printf", "SparseArrays", "Statistics", "StatsBase"]
git-tree-sha1 = "75479b7df4167267d75294d14b58244695beb2ac"
uuid = "aaaa29a8-35af-508c-8bc3-b662a17a0fe5"
version = "0.14.2"

[[deps.CodecZlib]]
deps = ["TranscodingStreams", "Zlib_jll"]
git-tree-sha1 = "ded953804d019afa9a3f98981d99b33e3db7b6da"
uuid = "944b1d66-785c-5afd-91f1-9de20f533193"
version = "0.7.0"

[[deps.ColorSchemes]]
deps = ["ColorTypes", "Colors", "FixedPointNumbers", "Random"]
git-tree-sha1 = "6b6f04f93710c71550ec7e16b650c1b9a612d0b6"
uuid = "35d6a980-a343-548e-a6ea-1d62b119f2f4"
version = "3.16.0"

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

[[deps.ColorVectorSpace]]
deps = ["ColorTypes", "FixedPointNumbers", "LinearAlgebra", "SpecialFunctions", "Statistics", "TensorCore"]
git-tree-sha1 = "3f1f500312161f1ae067abe07d13b40f78f32e07"
uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4"
version = "0.9.8"

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

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

[[deps.CompilerSupportLibraries_jll]]
deps = ["Artifacts", "Libdl"]
uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae"

[[deps.ComputationalResources]]
git-tree-sha1 = "52cb3ec90e8a8bea0e62e275ba577ad0f74821f7"
uuid = "ed09eef8-17a6-5b46-8889-db040fac31e3"
version = "0.3.2"

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

[[deps.CoordinateTransformations]]
deps = ["LinearAlgebra", "StaticArrays"]
git-tree-sha1 = "681ea870b918e7cff7111da58791d7f718067a19"
uuid = "150eb455-5306-5404-9cee-2592286d6298"
version = "0.6.2"

[[deps.Crayons]]
git-tree-sha1 = "249fe38abf76d48563e2f4556bebd215aa317e15"
uuid = "a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f"
version = "4.1.1"

[[deps.CustomUnitRanges]]
git-tree-sha1 = "1a3f97f907e6dd8983b744d2642651bb162a3f7a"
uuid = "dc8bdbbb-1ca9-579f-8c36-e416f6a65cce"
version = "1.0.2"

[[deps.DataAPI]]
git-tree-sha1 = "cc70b17275652eb47bc9e5f81635981f13cea5c8"
uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a"
version = "1.9.0"

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

[[deps.DataStructures]]
deps = ["Compat", "InteractiveUtils", "OrderedCollections"]
git-tree-sha1 = "3daef5523dd2e769dad2365274f760ff5f282c7d"
uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
version = "0.18.11"

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

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

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

[[deps.Distances]]
deps = ["LinearAlgebra", "SparseArrays", "Statistics", "StatsAPI"]
git-tree-sha1 = "3258d0659f812acde79e8a74b11f17ac06d0ca04"
uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7"
version = "0.10.7"

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

[[deps.DocStringExtensions]]
deps = ["LibGit2"]
git-tree-sha1 = "b19534d1895d702889b219c382a6e18010797f0b"
uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae"
version = "0.8.6"

[[deps.Downloads]]
deps = ["ArgTools", "LibCURL", "NetworkOptions"]
uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6"

[[deps.DualNumbers]]
deps = ["Calculus", "NaNMath", "SpecialFunctions"]
git-tree-sha1 = "84f04fe68a3176a583b864e492578b9466d87f1e"
uuid = "fa6b7ba4-c1ee-5f82-b5fc-ecf0adba8f74"
version = "0.6.6"

[[deps.EarCut_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "3f3a2501fa7236e9b911e0f7a588c657e822bb6d"
uuid = "5ae413db-bbd1-5e63-b57d-d24a61df00f5"
version = "2.2.3+0"

[[deps.EllipsisNotation]]
deps = ["ArrayInterface"]
git-tree-sha1 = "d7ab55febfd0907b285fbf8dc0c73c0825d9d6aa"
uuid = "da5c29d0-fa7d-589e-88eb-ea29b0a81949"
version = "1.3.0"

[[deps.Expat_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "ae13fcbc7ab8f16b0856729b050ef0c446aa3492"
uuid = "2e619515-83b5-522b-bb60-26c02a35a201"
version = "2.4.4+0"

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

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

[[deps.FFTViews]]
deps = ["CustomUnitRanges", "FFTW"]
git-tree-sha1 = "cbdf14d1e8c7c8aacbe8b19862e0179fd08321c2"
uuid = "4f61f5a4-77b1-5117-aa51-3ab5ef4ef0cd"
version = "0.3.2"

[[deps.FFTW]]
deps = ["AbstractFFTs", "FFTW_jll", "LinearAlgebra", "MKL_jll", "Preferences", "Reexport"]
git-tree-sha1 = "463cb335fa22c4ebacfd1faba5fde14edb80d96c"
uuid = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341"
version = "1.4.5"

[[deps.FFTW_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "c6033cc3892d0ef5bb9cd29b7f2f0331ea5184ea"
uuid = "f5851436-0d7a-5f13-b9de-f02708fd171a"
version = "3.3.10+0"

[[deps.FileIO]]
deps = ["Pkg", "Requires", "UUIDs"]
git-tree-sha1 = "67551df041955cc6ee2ed098718c8fcd7fc7aebe"
uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549"
version = "1.12.0"

[[deps.FilePathsBase]]
deps = ["Compat", "Dates", "Mmap", "Printf", "Test", "UUIDs"]
git-tree-sha1 = "04d13bfa8ef11720c24e4d840c0033d145537df7"
uuid = "48062228-2e41-5def-b9a4-89aafe57970f"
version = "0.9.17"

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

[[deps.Fontconfig_jll]]
deps = ["Artifacts", "Bzip2_jll", "Expat_jll", "FreeType2_jll", "JLLWrappers", "Libdl", "Libuuid_jll", "Pkg", "Zlib_jll"]
git-tree-sha1 = "21efd19106a55620a188615da6d3d06cd7f6ee03"
uuid = "a3f928ae-7b40-5064-980b-68af3947d34b"
version = "2.13.93+0"

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

[[deps.FreeType2_jll]]
deps = ["Artifacts", "Bzip2_jll", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"]
git-tree-sha1 = "87eb71354d8ec1a96d4a7636bd57a7347dde3ef9"
uuid = "d7e528f0-a631-5988-bf34-fe36492bcfd7"
version = "2.10.4+0"

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

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

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

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

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

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

[[deps.Gettext_jll]]
deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Libiconv_jll", "Pkg", "XML2_jll"]
git-tree-sha1 = "9b02998aba7bf074d14de89f9d37ca24a1a0b046"
uuid = "78b55507-aeef-58d4-861c-77aaff3498b1"
version = "0.21.0+0"

[[deps.Ghostscript_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "78e2c69783c9753a91cdae88a8d432be85a2ab5e"
uuid = "61579ee1-b43e-5ca0-a5da-69d92c66a64b"
version = "9.55.0+0"

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

[[deps.Graphics]]
deps = ["Colors", "LinearAlgebra", "NaNMath"]
git-tree-sha1 = "1c5a84319923bea76fa145d49e93aa4394c73fc2"
uuid = "a2bd30eb-e257-5431-a919-1863eab51364"
version = "1.1.1"

[[deps.Graphite2_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "344bf40dcab1073aca04aa0df4fb092f920e4011"
uuid = "3b182d85-2403-5c21-9c21-1e1f0cc25472"
version = "1.3.14+0"

[[deps.Graphs]]
deps = ["ArnoldiMethod", "Compat", "DataStructures", "Distributed", "Inflate", "LinearAlgebra", "Random", "SharedArrays", "SimpleTraits", "SparseArrays", "Statistics"]
git-tree-sha1 = "d727758173afef0af878b29ac364a0eca299fc6b"
uuid = "86223c79-3864-5bf0-83f7-82e725a168b6"
version = "1.5.1"

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

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

[[deps.HarfBuzz_jll]]
deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "Graphite2_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Pkg"]
git-tree-sha1 = "129acf094d168394e80ee1dc4bc06ec835e510a3"
uuid = "2e76f6c2-a576-52d4-95c1-20adfe4de566"
version = "2.8.1+1"

[[deps.IfElse]]
git-tree-sha1 = "debdd00ffef04665ccbb3e150747a77560e8fad1"
uuid = "615f187c-cbe4-4ef1-ba3b-2fcf58d6d173"
version = "0.1.1"

[[deps.ImageAxes]]
deps = ["AxisArrays", "ImageBase", "ImageCore", "Reexport", "SimpleTraits"]
git-tree-sha1 = "c54b581a83008dc7f292e205f4c409ab5caa0f04"
uuid = "2803e5a7-5153-5ecf-9a86-9b4c37f5f5ac"
version = "0.6.10"

[[deps.ImageBase]]
deps = ["ImageCore", "Reexport"]
git-tree-sha1 = "b51bb8cae22c66d0f6357e3bcb6363145ef20835"
uuid = "c817782e-172a-44cc-b673-b171935fbb9e"
version = "0.1.5"

[[deps.ImageContrastAdjustment]]
deps = ["ImageCore", "ImageTransformations", "Parameters"]
git-tree-sha1 = "0d75cafa80cf22026cea21a8e6cf965295003edc"
uuid = "f332f351-ec65-5f6a-b3d1-319c6670881a"
version = "0.3.10"

[[deps.ImageCore]]
deps = ["AbstractFFTs", "ColorVectorSpace", "Colors", "FixedPointNumbers", "Graphics", "MappedArrays", "MosaicViews", "OffsetArrays", "PaddedViews", "Reexport"]
git-tree-sha1 = "9a5c62f231e5bba35695a20988fc7cd6de7eeb5a"
uuid = "a09fc81d-aa75-5fe9-8630-4744c3626534"
version = "0.9.3"

[[deps.ImageDistances]]
deps = ["Distances", "ImageCore", "ImageMorphology", "LinearAlgebra", "Statistics"]
git-tree-sha1 = "7a20463713d239a19cbad3f6991e404aca876bda"
uuid = "51556ac3-7006-55f5-8cb3-34580c88182d"
version = "0.2.15"

[[deps.ImageFiltering]]
deps = ["CatIndices", "ComputationalResources", "DataStructures", "FFTViews", "FFTW", "ImageBase", "ImageCore", "LinearAlgebra", "OffsetArrays", "Reexport", "SparseArrays", "StaticArrays", "Statistics", "TiledIteration"]
git-tree-sha1 = "15bd05c1c0d5dbb32a9a3d7e0ad2d50dd6167189"
uuid = "6a3955dd-da59-5b1f-98d4-e7296123deb5"
version = "0.7.1"

[[deps.ImageIO]]
deps = ["FileIO", "Netpbm", "OpenEXR", "PNGFiles", "QOI", "Sixel", "TiffImages", "UUIDs"]
git-tree-sha1 = "816fc866edd8307a6e79a575e6585bfab8cef27f"
uuid = "82e4d734-157c-48bb-816b-45c225c6df19"
version = "0.6.0"

[[deps.ImageMagick]]
deps = ["FileIO", "ImageCore", "ImageMagick_jll", "InteractiveUtils", "Libdl", "Pkg", "Random"]
git-tree-sha1 = "5bc1cb62e0c5f1005868358db0692c994c3a13c6"
uuid = "6218d12a-5da1-5696-b52f-db25d2ecc6d1"
version = "1.2.1"

[[deps.ImageMagick_jll]]
deps = ["Artifacts", "Ghostscript_jll", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Libtiff_jll", "Pkg", "Zlib_jll", "libpng_jll"]
git-tree-sha1 = "f025b79883f361fa1bd80ad132773161d231fd9f"
uuid = "c73af94c-d91f-53ed-93a7-00f77d67a9d7"
version = "6.9.12+2"

[[deps.ImageMetadata]]
deps = ["AxisArrays", "ImageAxes", "ImageBase", "ImageCore"]
git-tree-sha1 = "36cbaebed194b292590cba2593da27b34763804a"
uuid = "bc367c6b-8a6b-528e-b4bd-a4b897500b49"
version = "0.9.8"

[[deps.ImageMorphology]]
deps = ["ImageCore", "LinearAlgebra", "Requires", "TiledIteration"]
git-tree-sha1 = "7668b123ecfd39a6ae3fc31c532b588999bdc166"
uuid = "787d08f9-d448-5407-9aad-5290dd7ab264"
version = "0.3.1"

[[deps.ImageQualityIndexes]]
deps = ["ImageContrastAdjustment", "ImageCore", "ImageDistances", "ImageFiltering", "OffsetArrays", "Statistics"]
git-tree-sha1 = "1d2d73b14198d10f7f12bf7f8481fd4b3ff5cd61"
uuid = "2996bd0c-7a13-11e9-2da2-2f5ce47296a9"
version = "0.3.0"

[[deps.ImageSegmentation]]
deps = ["Clustering", "DataStructures", "Distances", "Graphs", "ImageCore", "ImageFiltering", "ImageMorphology", "LinearAlgebra", "MetaGraphs", "RegionTrees", "SimpleWeightedGraphs", "StaticArrays", "Statistics"]
git-tree-sha1 = "36832067ea220818d105d718527d6ed02385bf22"
uuid = "80713f31-8817-5129-9cf8-209ff8fb23e1"
version = "1.7.0"

[[deps.ImageShow]]
deps = ["Base64", "FileIO", "ImageBase", "ImageCore", "OffsetArrays", "StackViews"]
git-tree-sha1 = "d0ac64c9bee0aed6fdbb2bc0e5dfa9a3a78e3acc"
uuid = "4e3cecfd-b093-5904-9786-8bbb286a6a31"
version = "0.3.3"

[[deps.ImageTransformations]]
deps = ["AxisAlgorithms", "ColorVectorSpace", "CoordinateTransformations", "ImageBase", "ImageCore", "Interpolations", "OffsetArrays", "Rotations", "StaticArrays"]
git-tree-sha1 = "42fe8de1fe1f80dab37a39d391b6301f7aeaa7b8"
uuid = "02fcd773-0e25-5acc-982a-7f6622650795"
version = "0.9.4"

[[deps.Images]]
deps = ["Base64", "FileIO", "Graphics", "ImageAxes", "ImageBase", "ImageContrastAdjustment", "ImageCore", "ImageDistances", "ImageFiltering", "ImageIO", "ImageMagick", "ImageMetadata", "ImageMorphology", "ImageQualityIndexes", "ImageSegmentation", "ImageShow", "ImageTransformations", "IndirectArrays", "IntegralArrays", "Random", "Reexport", "SparseArrays", "StaticArrays", "Statistics", "StatsBase", "TiledIteration"]
git-tree-sha1 = "11d268adba1869067620659e7cdf07f5e54b6c76"
uuid = "916415d5-f1e6-5110-898d-aaa5f9f070e0"
version = "0.25.1"

[[deps.Imath_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "87f7662e03a649cffa2e05bf19c303e168732d3e"
uuid = "905a6f67-0a94-5f89-b386-d35d92009cd1"
version = "3.1.2+0"

[[deps.IndirectArrays]]
git-tree-sha1 = "012e604e1c7458645cb8b436f8fba789a51b257f"
uuid = "9b13fd28-a010-5f03-acff-a1bbcff69959"
version = "1.0.0"

[[deps.Inflate]]
git-tree-sha1 = "f5fc07d4e706b84f72d54eedcc1c13d92fb0871c"
uuid = "d25df0c9-e2be-5dd7-82c8-3ad0b3e990b9"
version = "0.1.2"

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

[[deps.InlineStrings]]
deps = ["Parsers"]
git-tree-sha1 = "61feba885fac3a407465726d0c330b3055df897f"
uuid = "842dd82b-1e85-43dc-bf29-5d0ee9dffc48"
version = "1.1.2"

[[deps.IntegralArrays]]
deps = ["ColorTypes", "FixedPointNumbers", "IntervalSets"]
git-tree-sha1 = "00019244715621f473d399e4e1842e479a69a42e"
uuid = "1d092043-8f09-5a30-832f-7509e371ab51"
version = "0.1.2"

[[deps.IntelOpenMP_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "d979e54b71da82f3a65b62553da4fc3d18c9004c"
uuid = "1d5cc7b8-4909-519e-a0f8-d0f5ad9712d0"
version = "2018.0.3+2"

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

[[deps.Interpolations]]
deps = ["AxisAlgorithms", "ChainRulesCore", "LinearAlgebra", "OffsetArrays", "Random", "Ratios", "Requires", "SharedArrays", "SparseArrays", "StaticArrays", "WoodburyMatrices"]
git-tree-sha1 = "b15fc0a95c564ca2e0a7ae12c1f095ca848ceb31"
uuid = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59"
version = "0.13.5"

[[deps.IntervalSets]]
deps = ["Dates", "EllipsisNotation", "Statistics"]
git-tree-sha1 = "3cc368af3f110a767ac786560045dceddfc16758"
uuid = "8197267c-284f-5f27-9208-e0e47529a953"
version = "0.5.3"

[[deps.InverseFunctions]]
deps = ["Test"]
git-tree-sha1 = "a7254c0acd8e62f1ac75ad24d5db43f5f19f3c65"
uuid = "3587e190-3f89-42d0-90ee-14403ec27112"
version = "0.1.2"

[[deps.InvertedIndices]]
git-tree-sha1 = "bee5f1ef5bf65df56bdd2e40447590b272a5471f"
uuid = "41ab1584-1d38-5bbf-9106-f11c6c58b48f"
version = "1.1.0"

[[deps.IrrationalConstants]]
git-tree-sha1 = "7fd44fd4ff43fc60815f8e764c0f352b83c49151"
uuid = "92d709cd-6900-40b7-9082-c6be49f344b6"
version = "0.1.1"

[[deps.IterTools]]
git-tree-sha1 = "fa6287a4469f5e048d763df38279ee729fbd44e5"
uuid = "c8e1da08-722c-5040-9ed9-7db0dc04731e"
version = "1.4.0"

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

[[deps.JLD2]]
deps = ["DataStructures", "FileIO", "MacroTools", "Mmap", "Pkg", "Printf", "Reexport", "TranscodingStreams", "UUIDs"]
git-tree-sha1 = "bcb31db46795eeb64480c89d854615bc78a13289"
uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819"
version = "0.4.19"

[[deps.JLLWrappers]]
deps = ["Preferences"]
git-tree-sha1 = "abc9885a7ca2052a736a600f7fa66209f96506e1"
uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210"
version = "1.4.1"

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

[[deps.JpegTurbo_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "d735490ac75c5cb9f1b00d8b5509c11984dc6943"
uuid = "aacddb02-875f-59d6-b918-886e6ef4fbf8"
version = "2.1.0+0"

[[deps.LAME_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "f6250b16881adf048549549fba48b1161acdac8c"
uuid = "c1c5ebd0-6772-5130-a774-d5fcae4a789d"
version = "3.100.1+0"

[[deps.LZO_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "e5b909bcf985c5e2605737d2ce278ed791b89be6"
uuid = "dd4b983a-f0e5-5f8d-a1b7-129d4a5fb1ac"
version = "2.10.1+0"

[[deps.LaTeXStrings]]
git-tree-sha1 = "f2355693d6778a178ade15952b7ac47a4ff97996"
uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f"
version = "1.3.0"

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

[[deps.LazyArtifacts]]
deps = ["Artifacts", "Pkg"]
uuid = "4af54fe1-eca0-43a8-85a7-787d91b784e3"

[[deps.LibCURL]]
deps = ["LibCURL_jll", "MozillaCACerts_jll"]
uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21"

[[deps.LibCURL_jll]]
deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"]
uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0"

[[deps.LibGit2]]
deps = ["Base64", "NetworkOptions", "Printf", "SHA"]
uuid = "76f85450-5226-5b5a-8eaa-529ad045b433"

[[deps.LibSSH2_jll]]
deps = ["Artifacts", "Libdl", "MbedTLS_jll"]
uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8"

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

[[deps.Libffi_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "0b4a5d71f3e5200a7dff793393e09dfc2d874290"
uuid = "e9f186c6-92d2-5b65-8a66-fee21dc1b490"
version = "3.2.2+1"

[[deps.Libgcrypt_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgpg_error_jll", "Pkg"]
git-tree-sha1 = "64613c82a59c120435c067c2b809fc61cf5166ae"
uuid = "d4300ac3-e22c-5743-9152-c294e39db1e4"
version = "1.8.7+0"

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

[[deps.Libgpg_error_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "c333716e46366857753e273ce6a69ee0945a6db9"
uuid = "7add5ba3-2f88-524e-9cd5-f83b8a55f7b8"
version = "1.42.0+0"

[[deps.Libiconv_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "42b62845d70a619f063a7da093d995ec8e15e778"
uuid = "94ce4f54-9a6c-5748-9c1c-f9c7231a4531"
version = "1.16.1+1"

[[deps.Libmount_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "9c30530bf0effd46e15e0fdcf2b8636e78cbbd73"
uuid = "4b2f31a3-9ecc-558c-b454-b3730dcb73e9"
version = "2.35.0+0"

[[deps.Libtiff_jll]]
deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Pkg", "Zlib_jll", "Zstd_jll"]
git-tree-sha1 = "340e257aada13f95f98ee352d316c3bed37c8ab9"
uuid = "89763e89-9b03-5906-acba-b20f662cd828"
version = "4.3.0+0"

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

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

[[deps.LogExpFunctions]]
deps = ["ChainRulesCore", "ChangesOfVariables", "DocStringExtensions", "InverseFunctions", "IrrationalConstants", "LinearAlgebra"]
git-tree-sha1 = "e5718a00af0ab9756305a0392832c8952c7426c1"
uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688"
version = "0.3.6"

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

[[deps.MKL_jll]]
deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "Pkg"]
git-tree-sha1 = "5455aef09b40e5020e1520f551fa3135040d4ed0"
uuid = "856f044c-d86e-5d09-b602-aeab76dc8ba7"
version = "2021.1.1+2"

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

[[deps.MappedArrays]]
git-tree-sha1 = "e8b359ef06ec72e8c030463fe02efe5527ee5142"
uuid = "dbb5928d-eab1-5f90-85c2-b9b0edb7c900"
version = "0.4.1"

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

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

[[deps.MbedTLS_jll]]
deps = ["Artifacts", "Libdl"]
uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1"

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

[[deps.MetaGraphs]]
deps = ["Graphs", "JLD2", "Random"]
git-tree-sha1 = "2af69ff3c024d13bde52b34a2a7d6887d4e7b438"
uuid = "626554b9-1ddb-594c-aa3c-2596fe9399a5"
version = "0.7.1"

[[deps.Missings]]
deps = ["DataAPI"]
git-tree-sha1 = "bf210ce90b6c9eed32d25dbcae1ebc565df2687f"
uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28"
version = "1.0.2"

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

[[deps.MosaicViews]]
deps = ["MappedArrays", "OffsetArrays", "PaddedViews", "StackViews"]
git-tree-sha1 = "b34e3bc3ca7c94914418637cb10cc4d1d80d877d"
uuid = "e94cdb99-869f-56ef-bcf0-1ae2bcbe0389"
version = "0.3.3"

[[deps.MozillaCACerts_jll]]
uuid = "14a3606d-f60d-562e-9121-12d972cd8159"

[[deps.NaNMath]]
git-tree-sha1 = "b086b7ea07f8e38cf122f5016af580881ac914fe"
uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3"
version = "0.3.7"

[[deps.NearestNeighbors]]
deps = ["Distances", "StaticArrays"]
git-tree-sha1 = "16baacfdc8758bc374882566c9187e785e85c2f0"
uuid = "b8a86587-4115-5ab1-83bc-aa920d37bbce"
version = "0.4.9"

[[deps.Netpbm]]
deps = ["FileIO", "ImageCore"]
git-tree-sha1 = "18efc06f6ec36a8b801b23f076e3c6ac7c3bf153"
uuid = "f09324ee-3d7c-5217-9330-fc30815ba969"
version = "1.0.2"

[[deps.NetworkOptions]]
uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908"

[[deps.OffsetArrays]]
deps = ["Adapt"]
git-tree-sha1 = "043017e0bdeff61cfbb7afeb558ab29536bbb5ed"
uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881"
version = "1.10.8"

[[deps.Ogg_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "887579a3eb005446d514ab7aeac5d1d027658b8f"
uuid = "e7412a2a-1a6e-54c0-be00-318e2571c051"
version = "1.3.5+1"

[[deps.OpenBLAS_jll]]
deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"]
uuid = "4536629a-c528-5b80-bd46-f80d51c5b363"

[[deps.OpenEXR]]
deps = ["Colors", "FileIO", "OpenEXR_jll"]
git-tree-sha1 = "327f53360fdb54df7ecd01e96ef1983536d1e633"
uuid = "52e1d378-f018-4a11-a4be-720524705ac7"
version = "0.3.2"

[[deps.OpenEXR_jll]]
deps = ["Artifacts", "Imath_jll", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"]
git-tree-sha1 = "923319661e9a22712f24596ce81c54fc0366f304"
uuid = "18a262bb-aa17-5467-a713-aee519bc75cb"
version = "3.1.1+0"

[[deps.OpenLibm_jll]]
deps = ["Artifacts", "Libdl"]
uuid = "05823500-19ac-5b8b-9628-191a04bc5112"

[[deps.OpenSSL_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "648107615c15d4e09f7eca16307bc821c1f718d8"
uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95"
version = "1.1.13+0"

[[deps.OpenSpecFun_jll]]
deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "13652491f6856acfd2db29360e1bbcd4565d04f1"
uuid = "efe28fd5-8261-553b-a9e1-b2916fc3738e"
version = "0.5.5+0"

[[deps.Opus_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "51a08fb14ec28da2ec7a927c4337e4332c2a4720"
uuid = "91d4177d-7536-5919-b921-800302f37372"
version = "1.3.2+0"

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

[[deps.PCRE_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "b2a7af664e098055a7529ad1a900ded962bca488"
uuid = "2f80f16e-611a-54ab-bc61-aa92de5b98fc"
version = "8.44.0+0"

[[deps.PNGFiles]]
deps = ["Base64", "CEnum", "ImageCore", "IndirectArrays", "OffsetArrays", "libpng_jll"]
git-tree-sha1 = "2271d1c3b0103844a9f4af6cd17d70d146d5295f"
uuid = "f57f5aa1-a3ce-4bc8-8ab9-96f992907883"
version = "0.3.13"

[[deps.PaddedViews]]
deps = ["OffsetArrays"]
git-tree-sha1 = "03a7a85b76381a3d04c7a1656039197e70eda03d"
uuid = "5432bcbf-9aad-5242-b902-cca2824c8663"
version = "0.5.11"

[[deps.Parameters]]
deps = ["OrderedCollections", "UnPack"]
git-tree-sha1 = "34c0e9ad262e5f7fc75b10a9952ca7692cfc5fbe"
uuid = "d96e819e-fc66-5662-9728-84c9c7592b0a"
version = "0.12.3"

[[deps.Parsers]]
deps = ["Dates"]
git-tree-sha1 = "0b5cfbb704034b5b4c1869e36634438a047df065"
uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0"
version = "2.2.1"

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

[[deps.Pkg]]
deps = ["Artifacts", "Dates", "Downloads", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"]
uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"

[[deps.PkgVersion]]
deps = ["Pkg"]
git-tree-sha1 = "a7a7e1a88853564e551e4eba8650f8c38df79b37"
uuid = "eebad327-c553-4316-9ea0-9fa01ccd7688"
version = "0.1.1"

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

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

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

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

[[deps.Preferences]]
deps = ["TOML"]
git-tree-sha1 = "2cf929d64681236a2e074ffafb8d568733d2e6af"
uuid = "21216c6a-2e73-6563-6e65-726566657250"
version = "1.2.3"

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

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

[[deps.ProgressMeter]]
deps = ["Distributed", "Printf"]
git-tree-sha1 = "afadeba63d90ff223a6a48d2009434ecee2ec9e8"
uuid = "92933f4c-e287-5a05-a399-4b506db050ca"
version = "1.7.1"

[[deps.QOI]]
deps = ["ColorTypes", "FileIO", "FixedPointNumbers"]
git-tree-sha1 = "18e8f4d1426e965c7b532ddd260599e1510d26ce"
uuid = "4b34888f-f399-49d4-9bb3-47ed5cae4e65"
version = "1.0.0"

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

[[deps.Quaternions]]
deps = ["DualNumbers", "LinearAlgebra"]
git-tree-sha1 = "adf644ef95a5e26c8774890a509a55b7791a139f"
uuid = "94ee1d12-ae83-5a48-8b1c-48b8ff168ae0"
version = "0.4.2"

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

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

[[deps.RangeArrays]]
git-tree-sha1 = "b9039e93773ddcfc828f12aadf7115b4b4d225f5"
uuid = "b3c3ace0-ae52-54e7-9d0b-2c1406fd6b9d"
version = "0.3.2"

[[deps.Ratios]]
deps = ["Requires"]
git-tree-sha1 = "01d341f502250e81f6fec0afe662aa861392a3aa"
uuid = "c84ed2f1-dad5-54f0-aa8e-dbefe2724439"
version = "0.4.2"

[[deps.RecipesBase]]
git-tree-sha1 = "6bf3f380ff52ce0832ddd3a2a7b9538ed1bcca7d"
uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01"
version = "1.2.1"

[[deps.RecipesPipeline]]
deps = ["Dates", "NaNMath", "PlotUtils", "RecipesBase"]
git-tree-sha1 = "37c1631cb3cc36a535105e6d5557864c82cd8c2b"
uuid = "01d81517-befc-4cb6-b9ec-a95719d0359c"
version = "0.5.0"

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

[[deps.RegionTrees]]
deps = ["IterTools", "LinearAlgebra", "StaticArrays"]
git-tree-sha1 = "4618ed0da7a251c7f92e869ae1a19c74a7d2a7f9"
uuid = "dee08c22-ab7f-5625-9660-a9af2021b33f"
version = "0.3.2"

[[deps.RelocatableFolders]]
deps = ["SHA", "Scratch"]
git-tree-sha1 = "cdbd3b1338c72ce29d9584fdbe9e9b70eeb5adca"
uuid = "05181044-ff0b-4ac5-8273-598c1e38db00"
version = "0.1.3"

[[deps.Requires]]
deps = ["UUIDs"]
git-tree-sha1 = "838a3a4188e2ded87a4f9f184b4b0d78a1e91cb7"
uuid = "ae029012-a4dd-5104-9daa-d747884805df"
version = "1.3.0"

[[deps.Rotations]]
deps = ["LinearAlgebra", "Quaternions", "Random", "StaticArrays", "Statistics"]
git-tree-sha1 = "405148000e80f70b31e7732ea93288aecb1793fa"
uuid = "6038ab10-8711-5258-84ad-4b1120ba62dc"
version = "1.2.0"

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

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

[[deps.SentinelArrays]]
deps = ["Dates", "Random"]
git-tree-sha1 = "15dfe6b103c2a993be24404124b8791a09460983"
uuid = "91c51154-3ec4-41a3-a24f-3f23e20d615c"
version = "1.3.11"

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

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

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

[[deps.SimpleTraits]]
deps = ["InteractiveUtils", "MacroTools"]
git-tree-sha1 = "5d7e3f4e11935503d3ecaf7186eac40602e7d231"
uuid = "699a6c99-e7fa-54fc-8d76-47d257e15c1d"
version = "0.9.4"

[[deps.SimpleWeightedGraphs]]
deps = ["Graphs", "LinearAlgebra", "Markdown", "SparseArrays", "Test"]
git-tree-sha1 = "a6f404cc44d3d3b28c793ec0eb59af709d827e4e"
uuid = "47aef6b3-ad0c-573a-a1e2-d07658019622"
version = "1.2.1"

[[deps.Sixel]]
deps = ["Dates", "FileIO", "ImageCore", "IndirectArrays", "OffsetArrays", "REPL", "libsixel_jll"]
git-tree-sha1 = "8fb59825be681d451c246a795117f317ecbcaa28"
uuid = "45858cf5-a6b0-47a3-bbea-62219f50df47"
version = "0.1.2"

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

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

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

[[deps.SpecialFunctions]]
deps = ["ChainRulesCore", "IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"]
git-tree-sha1 = "a4116accb1c84f0a8e1b9932d873654942b2364b"
uuid = "276daf66-3868-5448-9aa4-cd146d93841b"
version = "2.1.1"

[[deps.StackViews]]
deps = ["OffsetArrays"]
git-tree-sha1 = "46e589465204cd0c08b4bd97385e4fa79a0c770c"
uuid = "cae243ae-269e-4f55-b966-ac2d0dc13c15"
version = "0.1.1"

[[deps.Static]]
deps = ["IfElse"]
git-tree-sha1 = "d4da8b728580709d736704764e55d6ef38cb7c87"
uuid = "aedffcd0-7271-4cad-89d0-dc628f76c6d3"
version = "0.5.3"

[[deps.StaticArrays]]
deps = ["LinearAlgebra", "Random", "Statistics"]
git-tree-sha1 = "a635a9333989a094bddc9f940c04c549cd66afcf"
uuid = "90137ffa-7385-5640-81b9-e52037218182"
version = "1.3.4"

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

[[deps.StatsAPI]]
git-tree-sha1 = "d88665adc9bcf45903013af0982e2fd05ae3d0a6"
uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0"
version = "1.2.0"

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

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

[[deps.TOML]]
deps = ["Dates"]
uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76"

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

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

[[deps.Tar]]
deps = ["ArgTools", "SHA"]
uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e"

[[deps.TensorCore]]
deps = ["LinearAlgebra"]
git-tree-sha1 = "1feb45f88d133a655e001435632f019a9a1bcdb6"
uuid = "62fd8b95-f654-4bbd-a8a5-9c27f68ccd50"
version = "0.1.1"

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

[[deps.TiffImages]]
deps = ["ColorTypes", "DataStructures", "DocStringExtensions", "FileIO", "FixedPointNumbers", "IndirectArrays", "Inflate", "OffsetArrays", "PkgVersion", "ProgressMeter", "UUIDs"]
git-tree-sha1 = "991d34bbff0d9125d93ba15887d6594e8e84b305"
uuid = "731e570b-9d59-4bfa-96dc-6df516fadf69"
version = "0.5.3"

[[deps.TiledIteration]]
deps = ["OffsetArrays"]
git-tree-sha1 = "5683455224ba92ef59db72d10690690f4a8dc297"
uuid = "06e1c1a7-607b-532d-9fad-de7d9aa2abac"
version = "0.3.1"

[[deps.TranscodingStreams]]
deps = ["Random", "Test"]
git-tree-sha1 = "216b95ea110b5972db65aa90f88d8d89dcb8851c"
uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa"
version = "0.9.6"

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

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

[[deps.UnPack]]
git-tree-sha1 = "387c1f73762231e86e0c9c5443ce3b4a0a9a0c2b"
uuid = "3a884ed6-31ef-47d7-9d2a-63182c4928ed"
version = "1.0.2"

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

[[deps.UnicodeFun]]
deps = ["REPL"]
git-tree-sha1 = "53915e50200959667e78a92a418594b428dffddf"
uuid = "1cfade01-22cf-5700-b092-accc4b62d6e1"
version = "0.4.1"

[[deps.Unzip]]
git-tree-sha1 = "34db80951901073501137bdbc3d5a8e7bbd06670"
uuid = "41fe7b60-77ed-43a1-b4f0-825fd5a5650d"
version = "0.1.2"

[[deps.Wayland_jll]]
deps = ["Artifacts", "Expat_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Pkg", "XML2_jll"]
git-tree-sha1 = "3e61f0b86f90dacb0bc0e73a0c5a83f6a8636e23"
uuid = "a2964d1f-97da-50d4-b82a-358c7fce9d89"
version = "1.19.0+0"

[[deps.Wayland_protocols_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "66d72dc6fcc86352f01676e8f0f698562e60510f"
uuid = "2381bf8a-dfd0-557d-9999-79630e7b1b91"
version = "1.23.0+0"

[[deps.WeakRefStrings]]
deps = ["DataAPI", "InlineStrings", "Parsers"]
git-tree-sha1 = "c69f9da3ff2f4f02e811c3323c22e5dfcb584cfa"
uuid = "ea10d353-3f73-51f8-a26c-33c1cb351aa5"
version = "1.4.1"

[[deps.WoodburyMatrices]]
deps = ["LinearAlgebra", "SparseArrays"]
git-tree-sha1 = "de67fa59e33ad156a590055375a30b23c40299d3"
uuid = "efce3f68-66dc-5838-9240-27a6d6f5f9b6"
version = "0.5.5"

[[deps.XML2_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Pkg", "Zlib_jll"]
git-tree-sha1 = "1acf5bdf07aa0907e0a37d3718bb88d4b687b74a"
uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a"
version = "2.9.12+0"

[[deps.XSLT_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgcrypt_jll", "Libgpg_error_jll", "Libiconv_jll", "Pkg", "XML2_jll", "Zlib_jll"]
git-tree-sha1 = "91844873c4085240b95e795f692c4cec4d805f8a"
uuid = "aed1982a-8fda-507f-9586-7b0439959a61"
version = "1.1.34+0"

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

[[deps.Zlib_jll]]
deps = ["Libdl"]
uuid = "83775a58-1f1d-513f-b197-d71354ab007a"

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

[[deps.libass_jll]]
deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"]
git-tree-sha1 = "5982a94fcba20f02f42ace44b9894ee2b140fe47"
uuid = "0ac62f75-1d6f-5e53-bd7c-93b484bb37c0"
version = "0.15.1+0"

[[deps.libblastrampoline_jll]]
deps = ["Artifacts", "Libdl", "OpenBLAS_jll"]
uuid = "8e850b90-86db-534c-a0d3-1478176c7d93"

[[deps.libfdk_aac_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "daacc84a041563f965be61859a36e17c4e4fcd55"
uuid = "f638f0a6-7fb0-5443-88ba-1cc74229b280"
version = "2.0.2+0"

[[deps.libpng_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"]
git-tree-sha1 = "94d180a6d2b5e55e447e2d27a29ed04fe79eb30c"
uuid = "b53b4c65-9356-5827-b1ea-8c7a1a84506f"
version = "1.6.38+0"

[[deps.libsixel_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "78736dab31ae7a53540a6b752efc61f77b304c5b"
uuid = "075b6546-f08a-558a-be8f-8157d0f608a5"
version = "1.8.6+1"

[[deps.libvorbis_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Ogg_jll", "Pkg"]
git-tree-sha1 = "b910cb81ef3fe6e78bf6acee440bda86fd6ae00c"
uuid = "f27f6e37-5d2b-51aa-960f-b287f2bc3b7a"
version = "1.3.7+1"

[[deps.nghttp2_jll]]
deps = ["Artifacts", "Libdl"]
uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d"

[[deps.p7zip_jll]]
deps = ["Artifacts", "Libdl"]
uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0"

[[deps.x264_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "4fea590b89e6ec504593146bf8b988b2c00922b2"
uuid = "1270edf5-f2f9-52d2-97e9-ab00b5d0237a"
version = "2021.5.5+0"

[[deps.x265_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "ee567a171cce03570d77ad3a43e90218e38937a9"
uuid = "dfaa095f-4041-5dcd-9319-2fabd8486b76"
version = "3.5.0+0"

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

# ╔═╡ Cell order:
# ╠═411103c8-8636-11ec-2150-89fe0acea2d4
# ╠═4ea09c13-a7ea-4d0d-98bc-90c9a8fdf28d
# ╟─05e3ea97-6b40-4d8e-88a0-8a86465fc9be
# ╠═05f077a2-e28d-4ee7-b45f-49f94a251dd6
# ╠═a082b107-834a-4135-923b-f8da543ab4fb
# ╟─00000000-0000-0000-0000-000000000001
# ╟─00000000-0000-0000-0000-000000000002


module Units

export second, minute, hour, day, year, meter, kilometer,
       seconds, minutes, hours, days, years, meters, kilometers,
       KiB, MiB, GiB, TiB

#####
##### Convenient definitions
#####

"""
    second

A `Float64` constant equal to 1.0. Useful for increasing the clarity of scripts, e.g. `Δt = 1second`.
"""
const second = 1.0

"""
    seconds

A `Float64` constant equal to 1.0. Useful for increasing the clarity of scripts, e.g. `Δt = 7seconds`.
"""
const seconds = second

"""
    minute

A `Float64` constant equal to 60`seconds`. Useful for increasing the clarity of scripts, e.g. `Δt = 1minute`.
"""
const minute = 60seconds

"""
    minutes

A `Float64` constant equal to 60`seconds`. Useful for increasing the clarity of scripts, e.g. `Δt = 15minutes`.
"""
const minutes = minute

"""
    hour

A `Float64` constant equal to 60`minutes`. Useful for increasing the clarity of scripts, e.g. `Δt = 1hour`.
"""
const hour = 60minutes

"""
    hours

A `Float64` constant equal to 60`minutes`. Useful for increasing the clarity of scripts, e.g. `Δt = 3hours`.
"""
const hours = hour

"""
    day

A `Float64` constant equal to 24`hours`. Useful for increasing the clarity of scripts, e.g. `stop_time = 1day`.
"""
const day = 24hours

"""
    days

A `Float64` constant equal to 24`hours`. Useful for increasing the clarity of scripts, e.g. `stop_time = 7days`.
"""
const days = day

"""
    year

A `Float64` constant equal to 365`days`. Useful for increasing the clarity of scripts, e.g. `stop_time = 1year`.
"""
const year = 365days

"""
    years

A `Float64` constant equal to 365`days`. Useful for increasing the clarity of scripts, e.g. `stop_time = 100years`.
"""
const years = year

"""
    meter

A `Float64` constant equal to 1.0. Useful for increasing the clarity of scripts, e.g. `Lx = 1meter`.
"""
const meter = 1.0

"""
    meters

A `Float64` constant equal to 1.0. Useful for increasing the clarity of scripts, e.g. `Lx = 50meters`.
"""
const meters = meter

"""
    kilometer

A `Float64` constant equal to 1000`meters`. Useful for increasing the clarity of scripts, e.g. `Lx = 1kilometer`.
"""
const kilometer = 1000meters

"""
    kilometers

A `Float64` constant equal to 1000`meters`. Useful for increasing the clarity of scripts, e.g. `Lx = 5000kilometers`.
"""
const kilometers = kilometer

"""
    KiB

A `Float64` constant equal to 1024.0. Useful for increasing the clarity of scripts, e.g. `max_filesize = 250KiB`.
"""
const KiB = 1024.0

"""
    MiB

A `Float64` constant equal to 1024`KiB`. Useful for increasing the clarity of scripts, e.g. `max_filesize = 100MiB`.
"""
const MiB = 1024KiB

"""
    GiB

A `Float64` constant equal to 1024`MiB`. Useful for increasing the clarity of scripts, e.g. `max_filesize = 50GiB`.
"""
const GiB = 1024MiB

"""
    TiB

A `Float64` constant equal to 1024`GiB`. Useful for increasing the clarity of scripts, e.g. `max_filesize = 2TiB`.
"""
const TiB = 1024GiB

end


module Cqdldl

using SparseArrays
using LinearAlgebra

using QDLDL_jll
const libqdldl = QDLDL_jll.libqdldl

const QDLDL_int = Clonglong
const QDLDL_float = Cdouble
const QDLDL_bool = Cuchar

export QDLDLException, QDLDLSolver

struct QDLDLException <: Exception
    msg::String
end

Base.@kwdef mutable struct QDLDLFlags
    haselimtree::Bool = false
    isfactordone::Bool = false
    isfactorsuccess::Bool = false
end

mutable struct QDLDLBufferDims{Ti}
    n::Ti      # current dimension
    n0::Ti     # max dimension size
    nnzA0::Ti  # max nnzA
    nnzL0::Ti  # max nnzL
end

struct QDLDLSolver{Tv <: Union{Float32, Float64}, Ti <: Integer}
    flags::QDLDLFlags
    dims::QDLDLBufferDims{Ti}
    Ap::Vector{Ti}
    Ai::Vector{Ti}
    Ax::Vector{Tv}
    work::Vector{Ti}
    Lnz::Vector{Ti}
    etree::Vector{Ti}
    Lp::Vector{Ti}
    Li::Vector{Ti}
    Lx::Vector{Tv}
    D::Vector{Tv}
    Dinv::Vector{Tv}
    bwork::Vector{QDLDL_bool}
    iwork::Vector{Ti}
    fwork::Vector{Tv}
    # L::SparseMatrixCSC{Tv,Ti}
    function QDLDLSolver{Tv}(n::Integer, nnzA::Integer, nnzL::Integer) where Tv
        n, nnzA, nnzL = promote(n, nnzA, nnzL)
        dims = QDLDLBufferDims(n, n, nnzA, nnzL)
        Ti = typeof(n)

        flags = QDLDLFlags()
        Ap = zeros(Ti, n + 1)
        Ai = zeros(Ti, nnzA)
        Ax = zeros(Tv, nnzA)
        work = zeros(Ti,n)
        Lnz = zeros(Ti,n)
        etree = zeros(Ti,n)
        Lp = zeros(Ti, n+1)
        Lp[end] = nnzL
        Li = zeros(Ti, nnzL)
        Lx = zeros(Tv, nnzL)
        D = zeros(Tv, n)
        Dinv = zeros(Tv, n)
        bwork = zeros(QDLDL_bool, n)
        iwork = zeros(Ti, 3n)
        fwork = zeros(Tv, n)
        new{Tv,Ti}(flags, dims, Ap, Ai, Ax, work, Lnz, etree, Lp, Li, Lx, D, Dinv, bwork, iwork, fwork)
    end
    function QDLDLSolver(A::SparseMatrixCSC{Tv}; calctree::Bool=true) where Tv <: Union{Float32, Float64}
        Ti = QDLDL_int
        flags = QDLDLFlags()

        # Convert to upper triangular
        if !istriu(A)
            @warn "A not upper triangular. Creating a new upper-triangular matrix."
            A = triu(A)
        end
        @assert A.n == A.m "A must be a square matrix."
        n = A.n
        Ap = A.colptr .- 1  # convert to 0-based indexing
        Ai = A.rowval .- 1  # convert to 0-based indexing
        Ax = A.nzval
        work = zeros(Ti,n)
        Lnz = zeros(Ti,n)
        etree = zeros(Ti,n)
        F = new{Tv,Ti}(flags, n, Ap, Ai, Ax, work, Lnz, etree)
        if calctree
            return eliminationtree!(F)
        end
        return F
    end
    function QDLDLSolver(qdldl::QDLDLSolver{Tv,Ti}) where {Tv,Ti}
        nnzL = sum(qdldl.Lnz)
        n = qdldl.n
        nnzL = sum(qdldl.Lnz)
        if nnzL == 0 || !qdldl.flags.haselimtree
            throw(QDLDLException(
                "Cannot initialize a complete QDLDL objective without calculating the elimination tree."
            ))
        end
        Lp = zeros(Ti, n+1)
        Lp[end] = nnzL
        Li = zeros(Ti, nnzL)
        Lx = zeros(Tv, nnzL)
        D = zeros(Tv, n)
        Dinv = zeros(Tv, n)
        bwork = zeros(QDLDL_bool, n)
        iwork = zeros(Ti, 3n)
        fwork = zeros(Tv, n)
        # L = SparseMatrixCSC{Tv,Ti}(n, n, copy(Li), copy(Lp), copy(Lx))
        new{Tv,Ti}(qdldl.flags,
            qdldl.n, qdldl.Ap, qdldl.Ai, qdldl.Ax, qdldl.work, qdldl.Lnz, qdldl.etree,
            Lp, Li, Lx, D, Dinv, bwork, iwork, fwork
        )
    end
end
Base.size(F::QDLDLSolver) = (F.dims.n, F.dims.n)
Base.size(F::QDLDLSolver, i::Integer) = i <= 2 ? F.dims.n : 1

function Base.resize!(F::QDLDLSolver, n::Integer)
    if n > F.dims.n0
        @warn "New dimension $n is greater than the buffer size $(F.dims.n0)."
        F.dims.n0 = n
    end
    resize!(F.Ap, n+1)
    resize!(F.work, n)
    resize!(F.Lnz, n)
    resize!(F.etree, n)
    resize!(F.Lp, n+1)
    resize!(F.D, n)
    resize!(F.Dinv, n)
    resize!(F.bwork, n)
    resize!(F.iwork, 3n)
    resize!(F.fwork, n)
    F.dims.n = n
    return F
end

function checkfullyinitialized(F::QDLDLSolver)
    if !isdefined(F, :Lp)
        throw(QDLDLException(
            "Cannot call factor! on an object that hasn't been initialized.\n" *
            "You may need to create a new QDLDL object using QDLDL(F::QDLDL)."
        ))
    end
end

function eliminationtree!(F::QDLDLSolver, A::SparseMatrixCSC; check::Bool=true)
    n = size(F,1)
    if !istriu(A)
        @warn "A not upper triangular. Creating a new upper-triangular matrix."
        A = triu(A)
    end
    nnzA = nnz(A)
    if nnzA > F.dims.nnzA0
        @warn "Nonzeros buffer size not large enough for A matrix. Increasing from $(F.dims.nnzA0) to $nnzA."
        F.dims.nnzA0 = nnzA
    end
    resize!(F.Ai, nnzA)
    resize!(F.Ax, nnzA)
    F.Ap .= A.colptr .- 1
    F.Ai .= A.rowval .- 1
    F.Ax .= A.nzval
    eliminationtree!(F; check=check, newsolver=false)
    nnzL = sum(F.Lnz)
    if nnzL > F.dims.nnzL0
        @warn "Nonzeros buffer size not large enough for L matrix. Increasing from $(F.dims.nnzL0) to $nnzL."
        F.dims.nnzL0 = nnzL
    end
    resize!(F.Li, nnzL)
    resize!(F.Lx, nnzL)
    F.Lp[end] = nnzL
    return F
end

function eliminationtree!(F::QDLDLSolver; check::Bool=true, newsolver::Bool=true)
    out = qdldl_etree(F.dims.n, F.Ap, F.Ai, F.work, F.Lnz, F.etree)
    if check && out == -1
        throw(QDLDLException(
            "Cannot calculate the elimination tree. Matrix is not upper triangular or has an empty column."
        ))
    elseif check && out == -2
        throw(QDLDLException(
            "Cannot calculate the elimination tree. Number of nonzero elements in L overflowed an $QDLDL_int."
        ))
    end
    F.flags.haselimtree = out >= 0
    if out >= 0
        return newsolver ? QDLDLSolver(F) : F
    else
        return F
    end
end

function factor!(F::QDLDLSolver; check::Bool=true)
    if !F.flags.haselimtree
        throw(QDLDLException("Cannot call factor! before eliminationtree!."))
    end
    checkfullyinitialized(F)

    out = qdldl_factor(
        F.dims.n, F.Ap, F.Ai, F.Ax, F.Lp, F.Li, F.Lx, F.D, F.Dinv, F.Lnz, F.etree, F.bwork,
        F.iwork, F.fwork
    )
    if check && out == -1
        throw(QDLDLException(
            "Cannot calculate factorization. Matrix not quasidefinite."
        ))
    end
    F.flags.isfactorsuccess = out != -1
    F.flags.isfactordone = true
    return F
end

function solve!(F::QDLDLSolver{T}, b::Vector{T}) where T
    if !F.flags.isfactordone
        throw(QDLDLException("Cannot call solve! before factor!."))
    end
    if F.dims.n != size(b,1)
        throw(DimensionMismatch("Cannot solve system. Expected a vector of length $(F.dims.n), got $(size(b,1))"))
    end
    checkfullyinitialized(F)
    qdldl_solve(F.dims.n, F.Lp, F.Li, F.Lx, F.Dinv, b)
    return b
end

function solveL!(F::QDLDLSolver{T}, b::Vector{T}) where T
    if !F.flags.isfactordone
        throw(QDLDLException("Cannot call solve! before factor!."))
    end
    if F.dims.n != size(b,1)
        throw(DimensionMismatch("Cannot solve system. Expected a vector of length $(F.dims.n), got $(size(b,1))"))
    end
    checkfullyinitialized(F)
    qdldl_Lsolve(F.dims.n, F.Lp, F.Li, F.Lx, b)
    return b
end

function solveLt!(F::QDLDLSolver{T}, b::Vector{T}) where T
    if !F.flags.isfactordone
        throw(QDLDLException("Cannot call solve! before factor!."))
    end
    if F.dims.n != size(b,1)
        throw(DimensionMismatch("Cannot solve system. Expected a vector of length $(F.dims.n), got $(size(b,1))"))
    end
    checkfullyinitialized(F)
    qdldl_Ltsolve(F.dims.n, F.Lp, F.Li, F.Lx, b)
    return b
end

function getL(F::QDLDLSolver{Tv,Ti}) where {Tv,Ti}
    return SparseMatrixCSC{Tv,Ti}(F.dims.n, F.dims.n, F.Lp .+ 1, F.Li .+ 1, F.Lx)
end

##############################
# Factorization Interface
##############################
struct QDLDLFactorization{Tv <: Union{Float32, Float64}, Ti <: Integer} <: LinearAlgebra.Factorization{Tv}
    solver::QDLDLSolver{Tv,Ti}
end
QDLDLFactorization(args...) = QDLDLFactorization(QDLDLSolver(args...))
getsolver(F::QDLDLFactorization) = getfield(F, :solver)

function qdldl(A::SparseMatrixCSC; check::Bool=true)
    F = QDLDLSolver(A)
    F = eliminationtree!(F)
    if F.flags.haselimtree
        factor!(F, check=check)
    end
    return QDLDLFactorization(F)
end

function Base.getproperty(F::QDLDLFactorization, d::Symbol)
    solver = getsolver(F)
    if d == :d
        solver.D
    elseif d == :dinv
        solver.Dinv
    elseif d == :D
        Diagonal(solver.D)
    elseif d == :Dinv
        Diagonal(solver.Dinv)
    elseif d == :L
        LowerTriangular(getL(solver))
    end
end

LinearAlgebra.issuccess(F::QDLDLFactorization) = getsolver(F).flags.isfactorsuccess

function LinearAlgebra.logabsdet(F::QDLDLFactorization{T}) where T
    return sum(log ∘ abs, F.d), prod(sign, F.d)
end

function LinearAlgebra.ldiv!(F::QDLDLFactorization, b)
    solver = getsolver(F)
    solver.flags.haselimtree || eliminationtree!(solver)
    solver.flags.isfactordone || factor!(solver)
    solve!(solver, b)
end

##############################
# C Interface Wrapper
##############################
function qdldl_etree(n::Int, Ap::Vector{Int}, Ai::Vector{Int}, work::Vector{Int},
    Lnz::Vector{Int}, etree::Vector{Int}
)
    @assert length(Ap) == n+1
    nnz = Ap[end]
    @assert length(Ai) == nnz
    @assert length(work) == n
    @assert length(Lnz) == n
    @assert length(etree) == n
    ccall((:QDLDL_etree, libqdldl), QDLDL_int,
        (QDLDL_int, Ptr{QDLDL_int}, Ptr{QDLDL_int}, Ref{QDLDL_int}, Ref{QDLDL_int},
        Ref{QDLDL_int}),
        n, Ap, Ai, work, Lnz, etree
    )
end

function qdldl_factor(
    n::QDLDL_int,
    Ap::Vector{QDLDL_int},
    Ai::Vector{QDLDL_int},
    Ax::Vector{QDLDL_float},
    Lp::Vector{QDLDL_int},
    Li::Vector{QDLDL_int},
    Lx::Vector{QDLDL_float},
    D::Vector{QDLDL_float},
    Dinv::Vector{QDLDL_float},
    Lnz::Vector{QDLDL_int},
    etree::Vector{QDLDL_int},
    bwork::Vector{QDLDL_bool},
    iwork::Vector{QDLDL_int},
    fwork::Vector{QDLDL_float}
)
    @assert length(Ap) == n+1
    nnzA = Ap[end]
    @assert length(Ai) == nnzA
    @assert length(Ax) == nnzA
    @assert length(Lp) == n+1
    nnzL = Lp[end]
    @assert length(Li) == nnzL
    @assert length(Lx) == nnzL
    @assert length(D) == n
    @assert length(Dinv) == n
    @assert length(Lnz) == n
    @assert length(etree) == n
    @assert length(bwork) == n
    @assert length(iwork) == 3n
    @assert length(fwork) == n

    ccall((:QDLDL_factor, libqdldl), QDLDL_int,
        (
            QDLDL_int,           # n
            Ptr{QDLDL_int},      # Ap
            Ptr{QDLDL_int},      # Ai
            Ptr{QDLDL_float},    # Ax
            Ref{QDLDL_int},      # Lx
            Ref{QDLDL_int},      # Li
            Ref{QDLDL_float},    # Lx
            Ref{QDLDL_float},    # D
            Ref{QDLDL_float},    # Dinv
            Ptr{QDLDL_int},      # Lnz
            Ptr{QDLDL_int},      # etree
            Ref{QDLDL_bool},     # bwork
            Ref{QDLDL_int},      # iwork
            Ref{QDLDL_float}     # fwork
        ),
        n, Ap, Ai, Ax, Lp, Li, Lx, D, Dinv, Lnz, etree, bwork, iwork, fwork
    )
end

function qdldl_solve(
    n::QDLDL_int,
    Lp::Vector{QDLDL_int},
    Li::Vector{QDLDL_int},
    Lx::Vector{QDLDL_float},
    Dinv::Vector{QDLDL_float},
    x::Vector{QDLDL_float}
)
    nnzL = Lp[end]
    @assert length(Li) == nnzL
    @assert length(Lx) == nnzL
    @assert length(Dinv) == n
    @assert length(x) == n
    ccall((:QDLDL_solve, libqdldl), Cvoid,
        (QDLDL_int, Ptr{QDLDL_int}, Ptr{QDLDL_int}, Ptr{QDLDL_float}, Ptr{QDLDL_float},
        Ref{QDLDL_float}),
        n, Lp, Li, Lx, Dinv, x
    )
end

"""
    qdldl_Lsolve

Solves ``(L+I)x = b``.
"""
function qdldl_Lsolve(
    n::QDLDL_int,
    Lp::Vector{QDLDL_int},
    Li::Vector{QDLDL_int},
    Lx::Vector{QDLDL_float},
    x::Vector{QDLDL_float}
)
    nnzL = Lp[end]
    @assert length(Li) == nnzL
    @assert length(Lx) == nnzL
    @assert length(x) == n
    ccall((:QDLDL_Lsolve, libqdldl), Cvoid,
        (QDLDL_int, Ptr{QDLDL_int}, Ptr{QDLDL_int}, Ptr{QDLDL_float}, Ref{QDLDL_float}),
        n, Lp, Li, Lx, x
    )
end

"""
    qdldl_Lsolve

Solves ``(L+I)^T x = b``.
"""
function qdldl_Ltsolve(
    n::QDLDL_int,
    Lp::Vector{QDLDL_int},
    Li::Vector{QDLDL_int},
    Lx::Vector{QDLDL_float},
    x::Vector{QDLDL_float}
)
    nnzL = Lp[end]
    @assert length(Li) == nnzL
    @assert length(Lx) == nnzL
    @assert length(x) == n
    ccall((:QDLDL_Ltsolve, libqdldl), Cvoid,
        (QDLDL_int, Ptr{QDLDL_int}, Ptr{QDLDL_int}, Ptr{QDLDL_float}, Ref{QDLDL_float}),
        n, Lp, Li, Lx, x
    )
end

end


"""
TODO: Document mutation module.
"""
module mutation
import StatsBase.sample
importall common, variation
using core, utility, representation, individual, species
export Mutation, MutationDefinition, mutate!

"""
The base type used by all mutation operation definitions.
"""
abstract MutationDefinition <: VariationDefinition

"""
The base type for all mutation operations.
"""
abstract Mutation <: Variation

"""
Subjects the first `n` individuals from a provided collection to mutation,
performed using a supplied mutation operator.
"""
operate!(m::Mutation, srcs::IndividualCollection, n::Int) =
  operate!(m, srcs.stages[m.stage][1:n])

"""
Subjects a list of chromosomes to mutation, performed using a supplied mutation
operator.
"""
operate!{T}(m::Mutation, srcs::Vector{IndividualStage{T}}) =
  for src in srcs; operate!(m, src); end

"""
Performs the mutation operation on the provided individual stage provided that
it is in a valid state.
"""
operate!{T}(m::Mutation, src::IndividualStage{T}) =
  if valid(src); set(src, mutate!(m, get(src))); end

"""
All mutation operators accept a single individual.
"""
num_inputs(m::Mutation) = 1

"""
All mutation operators produce a single individual.
"""
num_outputs(m::Mutation) = 1

# Load all mutation operations.
include("mutation/null.jl")
include("mutation/bit_flip.jl")
include("mutation/gaussian.jl")
include("mutation/single_swap.jl")
include("mutation/reverse.jl")
end


#=
This file is auto-generated. Do not edit.
=#
"""
    mutable struct NormPumpParams <: TechnicalParams
        flow_bep::Float64
        effncy_bep::Float64
        head_bep::Float64
        power_bep::Float64
        internal::InfrastructureSystemsInternal
    end

Coefficients that characterize pumps with a normalized representation of head, efficiency, and power. Currently only single-speed

# Arguments
- `flow_bep::Float64`: flow rate at the best efficiency point
- `effncy_bep::Float64`: efficiency at the best efficiency point
- `head_bep::Float64`: head at the best efficiency point
- `power_bep::Float64`: power at the best efficiency point
- `internal::InfrastructureSystemsInternal`: internal reference, do not modify
"""
mutable struct NormPumpParams <: TechnicalParams
    "flow rate at the best efficiency point"
    flow_bep::Float64
    "efficiency at the best efficiency point"
    effncy_bep::Float64
    "head at the best efficiency point"
    head_bep::Float64
    "power at the best efficiency point"
    power_bep::Float64
    "internal reference, do not modify"
    internal::InfrastructureSystemsInternal
end

function NormPumpParams(flow_bep, effncy_bep, head_bep, power_bep, )
    NormPumpParams(flow_bep, effncy_bep, head_bep, power_bep, InfrastructureSystemsInternal(), )
end

function NormPumpParams(; flow_bep, effncy_bep, head_bep, power_bep, )
    NormPumpParams(flow_bep, effncy_bep, head_bep, power_bep, )
end

# Constructor for demo purposes; non-functional.
function NormPumpParams(::Nothing)
    NormPumpParams(;
        flow_bep=0.0,
        effncy_bep=0.0,
        head_bep=0.0,
        power_bep=0.0,
    )
end

"""Get NormPumpParams flow_bep."""
get_flow_bep(value::NormPumpParams) = value.flow_bep
"""Get NormPumpParams effncy_bep."""
get_effncy_bep(value::NormPumpParams) = value.effncy_bep
"""Get NormPumpParams head_bep."""
get_head_bep(value::NormPumpParams) = value.head_bep
"""Get NormPumpParams power_bep."""
get_power_bep(value::NormPumpParams) = value.power_bep
"""Get NormPumpParams internal."""
get_internal(value::NormPumpParams) = value.internal


###
### Particle Filtering and Particle MCMC Samplers.
###

#######################
# Particle Transition #
#######################

"""
    ParticleTransition{T, F<:AbstractFloat}

Fields:
- `θ`: The parameters for any given sample.
- `lp`: The log pdf for the sample's parameters.
- `le`: The log evidence retrieved from the particle.
- `weight`: The weight of the particle the sample was retrieved from.
"""
struct ParticleTransition{T, F<:AbstractFloat}
    θ::T
    lp::F
    le::F
    weight::F
end

function additional_parameters(::Type{<:ParticleTransition})
    return [:lp,:le, :weight]
end

DynamicPPL.getlogp(t::ParticleTransition) = t.lp

####
#### Generic Sequential Monte Carlo sampler.
####

"""
$(TYPEDEF)

Sequential Monte Carlo sampler.

# Fields

$(TYPEDFIELDS)
"""
struct SMC{space, R} <: ParticleInference
    resampler::R
end

"""
    SMC(space...)
    SMC([resampler = ResampleWithESSThreshold(), space = ()])
    SMC([resampler = resample_systematic, ]threshold[, space = ()])

Create a sequential Monte Carlo sampler of type [`SMC`](@ref) for the variables in `space`.

If the algorithm for the resampling step is not specified explicitly, systematic resampling
is performed if the estimated effective sample size per particle drops below 0.5.
"""
function SMC(resampler = Turing.Core.ResampleWithESSThreshold(), space::Tuple = ())
    return SMC{space, typeof(resampler)}(resampler)
end

# Convenient constructors with ESS threshold
function SMC(resampler, threshold::Real, space::Tuple = ())
    return SMC(Turing.Core.ResampleWithESSThreshold(resampler, threshold), space)
end
SMC(threshold::Real, space::Tuple = ()) = SMC(resample_systematic, threshold, space)

# If only the space is defined
SMC(space::Symbol...) = SMC(space)
SMC(space::Tuple) = SMC(Turing.Core.ResampleWithESSThreshold(), space)

mutable struct SMCState{V<:VarInfo, F<:AbstractFloat} <: AbstractSamplerState
    vi                   ::   V
    # The logevidence after aggregating all samples together.
    average_logevidence  ::   F
    particles            ::   ParticleContainer
end

function SMCState(model::Model)
    vi = VarInfo(model)
    particles = ParticleContainer(Trace[])

    return SMCState(vi, 0.0, particles)
end

function Sampler(alg::SMC, model::Model, s::Selector)
    dict = Dict{Symbol, Any}()
    state = SMCState(model)
    return Sampler(alg, dict, s, state)
end

function AbstractMCMC.sample_init!(
    ::AbstractRNG,
    model::AbstractModel,
    spl::Sampler{<:SMC},
    N::Integer;
    kwargs...
)
    # set the parameters to a starting value
    initialize_parameters!(spl; kwargs...)

    # reset the VarInfo
    vi = spl.state.vi
    reset_num_produce!(vi)
    set_retained_vns_del_by_spl!(vi, spl)
    resetlogp!(vi)
    empty!(vi)

    # create a new set of particles
    T = Trace{typeof(spl),typeof(vi),typeof(model)}
    particles = T[Trace(model, spl, vi) for _ in 1:N]

    # create a new particle container
    spl.state.particles = pc = ParticleContainer(particles)

    # Perform particle sweep.
    logevidence = sweep!(pc, spl.alg.resampler)
    spl.state.average_logevidence = logevidence

    return
end

function AbstractMCMC.step!(
    ::AbstractRNG,
    model::AbstractModel,
    spl::Sampler{<:SMC},
    ::Integer,
    transition;
    iteration=-1,
    kwargs...
)
    # check that we received a real iteration number
    @assert iteration >= 1 "step! needs to be called with an 'iteration' keyword argument."

    # grab the weight
    pc = spl.state.particles
    weight = getweight(pc, iteration)

    # update the master vi
    particle = pc.vals[iteration]
    params = tonamedtuple(particle.vi)

    # This is pretty useless since we reset the log probability continuously in the
    # particle sweep.
    lp = getlogp(particle.vi)

    return ParticleTransition(params, lp, spl.state.average_logevidence, weight)
end

####
#### Particle Gibbs sampler.
####

"""
$(TYPEDEF)

Particle Gibbs sampler.

Note that this method is particle-based, and arrays of variables
must be stored in a [`TArray`](@ref) object.

# Fields

$(TYPEDFIELDS)
"""
struct PG{space,R} <: ParticleInference
    """Number of particles."""
    nparticles::Int
    """Resampling algorithm."""
    resampler::R
end

isgibbscomponent(::PG) = true

"""
    PG(n, space...)
    PG(n, [resampler = ResampleWithESSThreshold(), space = ()])
    PG(n, [resampler = resample_systematic, ]threshold[, space = ()])

Create a Particle Gibbs sampler of type [`PG`](@ref) with `n` particles for the variables
in `space`.

If the algorithm for the resampling step is not specified explicitly, systematic resampling
is performed if the estimated effective sample size per particle drops below 0.5.
"""
function PG(
    nparticles::Int,
    resampler = Turing.Core.ResampleWithESSThreshold(),
    space::Tuple = (),
)
    return PG{space, typeof(resampler)}(nparticles, resampler)
end

# Convenient constructors with ESS threshold
function PG(nparticles::Int, resampler, threshold::Real, space::Tuple = ())
    return PG(nparticles, Turing.Core.ResampleWithESSThreshold(resampler, threshold), space)
end
function PG(nparticles::Int, threshold::Real, space::Tuple = ())
    return PG(nparticles, resample_systematic, threshold, space)
end

# If only the number of particles and the space is defined
PG(nparticles::Int, space::Symbol...) = PG(nparticles, space)
function PG(nparticles::Int, space::Tuple)
    return PG(nparticles, Turing.Core.ResampleWithESSThreshold(), space)
end

mutable struct PGState{V<:VarInfo, F<:AbstractFloat} <: AbstractSamplerState
    vi                   ::   V
    # The logevidence after aggregating all samples together.
    average_logevidence  ::   F
end

function PGState(model::Model)
    vi = VarInfo(model)
    return PGState(vi, 0.0)
end

const CSMC = PG # type alias of PG as Conditional SMC

"""
    Sampler(alg::PG, model::Model, s::Selector)

Return a `Sampler` object for the PG algorithm.
"""
function Sampler(alg::PG, model::Model, s::Selector)
    info = Dict{Symbol, Any}()
    state = PGState(model)
    return Sampler(alg, info, s, state)
end

function AbstractMCMC.step!(
    ::AbstractRNG,
    model::AbstractModel,
    spl::Sampler{<:PG},
    ::Integer,
    transition;
    kwargs...
)
    # obtain or create reference particle
    vi = spl.state.vi
    ref_particle = isempty(vi) ? nothing : forkr(Trace(model, spl, vi))

    # reset the VarInfo before new sweep
    reset_num_produce!(vi)
    set_retained_vns_del_by_spl!(vi, spl)
    resetlogp!(vi)

    # create a new set of particles
    num_particles = spl.alg.nparticles
    T = Trace{typeof(spl),typeof(vi),typeof(model)}
    if ref_particle === nothing
        particles = T[Trace(model, spl, vi) for _ in 1:num_particles]
    else
        particles = Vector{T}(undef, num_particles)
        @inbounds for i in 1:(num_particles - 1)
            particles[i] = Trace(model, spl, vi)
        end
        @inbounds particles[num_particles] = ref_particle
    end

    # create a new particle container
    pc = ParticleContainer(particles)

    # Perform a particle sweep.
    logevidence = sweep!(pc, spl.alg.resampler)

    # pick a particle to be retained.
    Ws = getweights(pc)
    indx = randcat(Ws)

    # extract the VarInfo from the retained particle.
    params = tonamedtuple(vi)
    spl.state.vi = pc.vals[indx].vi

    # This is pretty useless since we reset the log probability continuously in the
    # particle sweep.
    lp = getlogp(spl.state.vi)

    # update the master vi.
    return ParticleTransition(params, lp, logevidence, 1.0)
end

function AbstractMCMC.sample_end!(
    ::AbstractRNG,
    ::AbstractModel,
    spl::Sampler{<:ParticleInference},
    N::Integer,
    ts::Vector{<:ParticleTransition};
    resume_from = nothing,
    kwargs...
)
    # Exponentiate the average log evidence.
    # loge = exp(mean([t.le for t in ts]))
    loge = mean(t.le for t in ts)

    # If we already had a chain, grab the logevidence.
    if resume_from isa MCMCChains.Chains
        # pushfirst!(samples, resume_from.info[:samples]...)
        pre_loge = resume_from.logevidence
        # Calculate new log-evidence
        pre_n = length(resume_from)
        loge = (pre_loge * pre_n + loge * N) / (pre_n + N)
    elseif resume_from !== nothing
        error("keyword argument `resume_from` has to be `nothing` or a `MCMCChains.Chains` object")
    end

    # Store the logevidence.
    spl.state.average_logevidence = loge
end

function DynamicPPL.assume(
    rng,
    spl::Sampler{<:Union{PG,SMC}},
    dist::Distribution,
    vn::VarName,
    ::Any
)
    vi = current_trace().vi
    if inspace(vn, spl)
        if ~haskey(vi, vn)
            r = rand(rng, dist)
            push!(vi, vn, r, dist, spl)
        elseif is_flagged(vi, vn, "del")
            unset_flag!(vi, vn, "del")
            r = rand(rng, dist)
            vi[vn] = vectorize(dist, r)
            setgid!(vi, spl.selector, vn)
            setorder!(vi, vn, get_num_produce(vi))
        else
            updategid!(vi, vn, spl)
            r = vi[vn]
        end
    else # vn belongs to other sampler <=> conditionning on vn
        if haskey(vi, vn)
            r = vi[vn]
        else
            r = rand(rng, dist)
            push!(vi, vn, r, dist, Selector(:invalid))
        end
        lp = logpdf_with_trans(dist, r, istrans(vi, vn))
        acclogp!(vi, lp)
    end
    return r, 0
end

function DynamicPPL.observe(spl::Sampler{<:Union{PG,SMC}}, dist::Distribution, value, vi)
    produce(logpdf(dist, value))
    return 0
end

####
#### Resampling schemes for particle filters
####

# Some references
#  - http://arxiv.org/pdf/1301.4019.pdf
#  - http://people.isy.liu.se/rt/schon/Publications/HolSG2006.pdf
# Code adapted from: http://uk.mathworks.com/matlabcentral/fileexchange/24968-resampling-methods-for-particle-filtering

# Default resampling scheme
function resample(w::AbstractVector{<:Real}, num_particles::Integer=length(w))
    return resample_systematic(w, num_particles)
end

# More stable, faster version of rand(Categorical)
function randcat(p::AbstractVector{<:Real})
    T = eltype(p)
    r = rand(T)
    s = 1
    for j in eachindex(p)
        r -= p[j]
        if r <= zero(T)
            s = j
            break
        end
    end
    return s
end

function resample_multinomial(w::AbstractVector{<:Real}, num_particles::Integer)
    return rand(Distributions.sampler(Categorical(w)), num_particles)
end

function resample_residual(w::AbstractVector{<:Real}, num_particles::Integer)
    # Pre-allocate array for resampled particles
    indices = Vector{Int}(undef, num_particles)

    # deterministic assignment
    residuals = similar(w)
    i = 1
    @inbounds for j in 1:length(w)
        x = num_particles * w[j]
        floor_x = floor(Int, x)
        for k in 1:floor_x
            indices[i] = j
            i += 1
        end
        residuals[j] = x - floor_x
    end

    # sampling from residuals
    if i <= num_particles
        residuals ./= sum(residuals)
        rand!(Categorical(residuals), view(indices, i:num_particles))
    end

    return indices
end

"""
    resample_stratified(weights, n)

Return a vector of `n` samples `x₁`, ..., `xₙ` from the numbers 1, ..., `length(weights)`,
generated by stratified resampling.

In stratified resampling `n` ordered random numbers `u₁`, ..., `uₙ` are generated, where
``uₖ \\sim U[(k - 1) / n, k / n)``. Based on these numbers the samples `x₁`, ..., `xₙ`
are selected according to the multinomial distribution defined by the normalized `weights`,
i.e., `xᵢ = j` if and only if
``uᵢ \\in [\\sum_{s=1}^{j-1} weights_{s}, \\sum_{s=1}^{j} weights_{s})``.
"""
function resample_stratified(weights::AbstractVector{<:Real}, n::Integer)
    # check input
    m = length(weights)
    m > 0 || error("weight vector is empty")

    # pre-calculations
    @inbounds v = n * weights[1]

    # generate all samples
    samples = Array{Int}(undef, n)
    sample = 1
    @inbounds for i in 1:n
        # sample next `u` (scaled by `n`)
        u = oftype(v, i - 1 + rand())

        # as long as we have not found the next sample
        while v < u
            # increase and check the sample
            sample += 1
            sample > m &&
                error("sample could not be selected (are the weights normalized?)")

            # update the cumulative sum of weights (scaled by `n`)
            v += n * weights[sample]
        end

        # save the next sample
        samples[i] = sample
    end

    return samples
end

"""
    resample_systematic(weights, n)

Return a vector of `n` samples `x₁`, ..., `xₙ` from the numbers 1, ..., `length(weights)`,
generated by systematic resampling.

In systematic resampling a random number ``u \\sim U[0, 1)`` is used to generate `n` ordered
numbers `u₁`, ..., `uₙ` where ``uₖ = (u + k − 1) / n``. Based on these numbers the samples
`x₁`, ..., `xₙ` are selected according to the multinomial distribution defined by the
normalized `weights`, i.e., `xᵢ = j` if and only if
``uᵢ \\in [\\sum_{s=1}^{j-1} weights_{s}, \\sum_{s=1}^{j} weights_{s})``.
"""
function resample_systematic(weights::AbstractVector{<:Real}, n::Integer)
    # check input
    m = length(weights)
    m > 0 || error("weight vector is empty")

    # pre-calculations
    @inbounds v = n * weights[1]
    u = oftype(v, rand())

    # find all samples
    samples = Array{Int}(undef, n)
    sample = 1
    @inbounds for i in 1:n
        # as long as we have not found the next sample
        while v < u
            # increase and check the sample
            sample += 1
            sample > m &&
                error("sample could not be selected (are the weights normalized?)")

            # update the cumulative sum of weights (scaled by `n`)
            v += n * weights[sample]
        end

        # save the next sample
        samples[i] = sample

        # update `u`
        u += one(u)
    end

    return samples
end


module MCMCBenchmarks

using Reexport

@reexport using Turing, CmdStan, StatsPlots, Pkg, Tracker
@reexport using Statistics, DataFrames, Random, Parameters, DynamicHMC
@reexport using LogDensityProblems, TransformVariables, Dates, FillArrays
@reexport using AdvancedHMC, ForwardDiff, Distributed, CSV, SpecialFunctions
import Base: get
import MCMCChains: Chains

include("plotting.jl")
include("Utilities.jl")
include("TOML/print.jl")
include("TOML/TOML.jl")
include("TOML/parser.jl")
include("core_benchmarking.jl")
include("helper_functions.jl")

export
  modifyConfig!,
  addChainSummary!,
  removeBurnin,
  toDict,
  addKW!,
  setreps,
  compileStanModel,
  addPerformance!,
  updateResults!,
  runSampler,
  benchmark!,
  benchmark,
  pbenchmark,
  MCMCSampler,
  AHMCNUTS,
  CmdStanNUTS,
  DHMCNUTS,
  DNNUTS,
  plotdensity,
  plotsummary,
  plotscatter,
  plotrecovery,
  nptochain,
  setprocs,
  save,
  Permutation,
  initChains,
  initStan,
  getMetadata,
  run_all_benchmarks
end # module