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

using Markdown
using InteractiveUtils

# This Pluto notebook uses @bind for interactivity. When running this notebook outside of Pluto, the following 'mock version' of @bind gives bound variables a default value (instead of an error).
macro bind(def, element)
    quote
        local iv = try Base.loaded_modules[Base.PkgId(Base.UUID("6e696c72-6542-2067-7265-42206c756150"), "AbstractPlutoDingetjes")].Bonds.initial_value catch; b -> missing; end
        local el = $(esc(element))
        global $(esc(def)) = Core.applicable(Base.get, el) ? Base.get(el) : iv(el)
        el
    end
end

# ╔═╡ e7666210-a660-11eb-3e0d-7d9aec9a9f9e
begin
	#try
		using PlutoUI
		using Plots
		using Plots.PlotMeasures
		using LaTeXStrings
		using Markdown
		using HypertextLiteral
		#using Images
		#using LinearAlgebra
		#using SparseArrays
		#using SpecialFunctions
		#using StatsBase
		using Random
		#using Distributions
		md"""
		### Packages

		All needed Packages available :) """
	#catch
	#	using Pkg;
	#	Pkg.activate(mktempdir())
	#	Pkg.add("PlutoUI")
	#	Pkg.add("Plots")
	#	Pkg.add("LaTeXStrings")
	#	Pkg.add("Markdown")
	#	Pkg.add("Images")
#		Pkg.add("Random")
		#Pkg.add("LinearAlgebra")
		#Pkg.add("SparseArrays")
		#Pkg.add("SpecialFunctions")
		#Pkg.add("StatsBase")
		#Pkg.add("Distributions")
#	using PlutoUI, Plots, LaTeXStrings, Markdown, Images, Plots.PlotMeasures, Random
		#using LinearAlgebra
		#using SparseArrays
		#using StatsBase
		#using Random
	#	md"""
		### Packages

	#	Some Package sources not added, this will take approx. 3 minutes"""
#	end

end

# ╔═╡ ec784992-f4af-4ece-bf72-555960a054ca
html"""

"""

# ╔═╡ 8f919de1-356f-4e42-9f7e-5d29092ed80f
md"""
## Bayesian reasoning

The lighttower located at the unknown coordinates $(a|b)$ randomly emits light in all polar directions $\varphi$ measured to the perpendicular to the beach. The light hits the beach if the angle $\varphi$ of emitted light is in the interval $\varphi \in [-\pi/2, \pi/2]$. See the sketch below for a detailed definition of the used variables.

The location $x$ on the beach is given by

$x = \tan(\varphi)\cdot b + a$

"""

# ╔═╡ fd94fab8-c4c4-454e-9f5b-c0f1178143b3
begin
md"""
## Derivation of the Likelihood and Posterior
So let's derive the Likelihood to spot a flash on the coastline position ``x``:

We know, that the lightsource 🔦 of the lighthouse is constantly rotating so all angles are equally probable independent of the actual position of the lighthouse:

``p(\varphi|a,b) = p(\varphi) = \frac{1}{2\pi}``

Then we know the relation between angle (``\varphi``), position of the lighthouse ``(a,b)`` and the coastline position ``x`` to spot a flash on the beach:

``x = a + b \cdot \tan(\varphi), \quad ``  for  ``\varphi \in [-\pi/2, \pi/2]``

So we are looking for the probability
	``p(x|a,b)``
	and can use the transformation law:

$p(x|a,b) = p\big(\varphi(x)|a,b\big) \cdot \left\lvert \frac{d\varphi(x)}{dx}\right\rvert$

With ``\frac{d\varphi(x)}{dx} = \frac{b}{b+(x-a)^2}`` and ``p(\varphi(x)) = \frac{1}{\pi}`` (we have to restrict the angle of ``\varphi`` to the halfplane to hit the coastline) we obtain the following Likelihood:

$p(x|a,b) = \frac{1}{\pi} \frac{b}{b^2 + (x-a)^2}$

For the posterior

$p(a,b|x) = \frac{1}{Z} p(x|a,b) \cdot p(a,b)$

we can assume a flat prior ``p(a,b)``.

"""

end

# ╔═╡ d3f023b1-8a57-4690-b8d6-afbe2ff50d5e
begin

	a_slider = @bind a Scrubbable(-4:0.1:4, default= 1)
	b_slider = @bind b Scrubbable(0.1:0.1:4, default= 3)
	phi_slider = @bind φ Scrubbable(-pi/2:pi/120:pi/2, default= -3*pi/10)

	fix_beach_box = @bind fix_beach CheckBox()

	flashes = @bind generate_flash CounterButton("Generate Flashes")

	md"""
	## The program
	### Define sliders and general checkboxes and buttons
	"""
end

# ╔═╡ 3c1cc3af-11f9-44ac-b07f-69704c4841c4
@htl("""

$(
md"""
Angle of the emitted light ``\varphi``: $(phi_slider)

Horizontal distance of the lighthouse from the origin ``a``: $(a_slider)

Perpendicular distance of the lighthouse from the coastline ``b``: $(b_slider)

Fix beach length 👉 $(fix_beach_box)
"""
)

""")

# ╔═╡ ed56b559-ea17-41c7-8fe5-6ae9440fd5b5
begin
	rng = MersenneTwister(1 + (generate_flash % 10 )  + Int(round((φ+2) * 100)))
	md" ### Define random number seed"

end

# ╔═╡ b2dc9f9b-9f57-4ca8-82ef-9c6a3915d6d0
begin

	show_flash_box = @bind show_flashes CheckBox()
	md" ### CheckBox show flash"
end

# ╔═╡ 656ac69b-4cf5-440b-a894-83a7a80f42f0
begin

	show_calculation_box = @bind show_calculation CheckBox(default=false)
	md" ### Define start calculation Checkbox"
end

# ╔═╡ 936ccc78-8720-46b5-91eb-8d23f8699c99
@htl("""

$(
md"""
Deactivate Calcuation to change position of the lighthouse: 👉 $(show_calculation_box)
"""
)

""")

# ╔═╡ bbb80420-ccae-48e7-a943-8aae332cb254
if show_calculation
	html"""

	"""
else
html"""

	"""
end

# ╔═╡ a61337a8-e197-4a7b-817d-012a5c1c0f17
begin
	rand_phi = (rand(rng,100) .- 0.5) * pi

	x_new = tan.(rand_phi).*b .+ a

	md" ### Generate new sample of flash points"

end

# ╔═╡ 51b1234a-9808-4dad-a588-f61db077767f
begin
	range_a = -5:0.01:5
	range_b = 0.1:0.01:5

	p = zeros(length(range_b), length(range_a))
	lighttower = (0,0)

	if show_calculation
		for i = 1:length(range_a), j=1:length(range_b)
			a_temp = range_a[i]
			b_temp = range_b[j]

			p[j,i] = 1/pi * prod(b_temp ./(b_temp^2 .+ (x_new .- a_temp).^2))
		end
		p = p./sum(p);
	end

	index = findall(p .== maximum(p))[1]
	lighttower = (range_a[index[2]], range_b[index[1]])

	md""" ### Calculation of the Likelihood"""
end

# ╔═╡ b8942536-020b-4c8e-a875-b5aba3034d42
begin
	#a = 1

	x = a+b*tan(φ)
	if fix_beach
		beach_length = 10
	else
		beach_length = maximum([4, abs(x)])
	end
	a_dist = abs(a) > 0.10 ? 0.05 : 0
	a_dist_y = 0.15
	b_dist = beach_length/30
	# plot light ray
		plot([x,a], [0,b], linestyle = :solid, linewidth = 2, color = :yellow, label=false,
	size = (640,320),
		labelfontsize = 15,
		tickfontsize = 13,
		legendfontsize = 11,
		bottom_margin =5mm,
		left_margin = 5mm,
		right_margin = 5mm,
		titlefontsize = 12,
		#foreground_color_grid = :black,
		#foreground_color_xticks = :black,
		background_color = :transparent,
		#foreground_color_axis = :black,
		#foreground_color_text = :black,
		#foreground_color_border = :black,
		foreground_color = :black,
		fontfamily="Computer Modern")
	plot!([x,a], [0,b], linestyle = :dash, linewidth = 2, color = :yellow3, label="Light")
	# plot beach

	plot!([-beach_length,beach_length], [0,0], color = :black, linewidth = 3, label=false, ylim=[0,4])
	# plot perpendicular
	plot!([a,a], [0,b], color=:black, linewidth = 2, linestyle = :dash,label = false)
	# plot lighthouse
	plot!([a], [b], markercolor=:red, marker=:o,linealpha = 0,markersize = 8, label="Lighttower")
	# plot distance b
	plot!(b_dist .+ [a,a,NaN,a,a], [a_dist_y,b-a_dist_y,NaN,b-a_dist_y,a_dist_y], color = :red, linewidth = 2.5, linestyle = :solid, label="\$b\$",arrow = true)
	annotate!(a+2*b_dist, b/2,text("\${b}\$", :red))
	#plot distance a
	plot!([sign(a)*a_dist,a-sign(a)*a_dist, NaN,a-sign(a)*a_dist,sign(a)*a_dist], [a_dist_y,a_dist_y, NaN, a_dist_y,a_dist_y], color=:green, linewidth = 2.5, linestyle = :solid, label= "\$a\$", arrow = true)
annotate!((a+b_dist/2)/2,2*a_dist_y,text("\${a}\$", :green, :center))

 	# plot varphi
varphi = atan((x-a)/b)
pl_angle =sign(varphi).* (0:0.01:abs(varphi))
rad = 1

	annotate!(a + sin(varphi/2)*2*rad/3, b-cos(varphi/2)*2*rad/3,"\$\\varphi\$")

plot!([a .+ sin.(pl_angle)*rad], [b.-cos.(pl_angle)*rad], label =false)

	# plot x
	annotate!(x,-2*a_dist_y, "\$x\$")

	if show_flashes
		plot!(x_new, zeros(size(x_new)), marker= :o, color = :orange,markeralpha = 0.4, linealpha = 0, label= "Flashes")
	end
	if show_calculation
	heatmap!(range_a, range_b, p, alpha = 0.4,
	title="The lighttower is most likely located at "*string(lighttower))
	end

	plot!([x,x], [-a_dist_y, a_dist_y]./2, linewidth = 3, color= :black, label = false, xlim = [-beach_length, beach_length])

end

# ╔═╡ ca076585-03b6-4381-b730-e32c7a30446e
if show_calculation
	heatmap(range_a, range_b, p,
	title="The lighttower is most likely located at "*string(lighttower),   colorbar_ticks = (0, "0"))
	#clim=(0,0.00006)
end

# ╔═╡ 16938d4f-6f25-4924-8bdf-b0eb638a6c4f
begin
	claire = "https://raw.githubusercontent.com/Captain-Bayes/images/main/claire_100px.gif"
	makabe = "https://raw.githubusercontent.com/Captain-Bayes/images/main/makeba_100px.gif"
	bayes = "https://raw.githubusercontent.com/Captain-Bayes/images/main/bayes_100px.gif"
	bernoulli = "https://raw.githubusercontent.com/Captain-Bayes/images/main/Bernoulli_wet.gif"
	island = "https://raw.githubusercontent.com/Captain-Bayes/images/main/Turtle_island_with_ship.png"
	map = "https://raw.githubusercontent.com/Captain-Bayes/images/main/Fishground_map.png"
	frogfish_image = "https://raw.githubusercontent.com/Captain-Bayes/images/main/frogfish_green_full.gif"
	venn = "https://raw.githubusercontent.com/Captain-Bayes/images/main/venn_100px.gif"
	angles_view = "https://raw.githubusercontent.com/Captain-Bayes/images/main/Gipfel_angles.png"
	mountain_view = "https://raw.githubusercontent.com/Captain-Bayes/images/main/Gipfel_view.png"
	image_of_data = "https://raw.githubusercontent.com/Captain-Bayes/images/main/Daten_brett.png"
	diagram_of_data = "https://raw.githubusercontent.com/Captain-Bayes/images/main/Diagram.png"
	treasure_map = "https://raw.githubusercontent.com/Captain-Bayes/images/main/Treasure_map_2.png"
	lighthouse_image = "https://raw.githubusercontent.com/Captain-Bayes/images/main/lighthouse_problem_draft.png"
	lighthouse_gif = "https://raw.githubusercontent.com/Captain-Bayes/images/main/Lighthouse.gif"
	lyra = "https://raw.githubusercontent.com/Captain-Bayes/images/main/lyra_100px.gif"

	md"""Images"""
end

# ╔═╡ 6c070606-1411-40fc-b6cd-8f27f052136b
md"""
# The lighthouse problem
$(Resource(lighthouse_gif, :width=>600))

$(Resource(lyra, :width=>150))
> *It tell you from my observations I know, there must be a lighthouse somewhere over the sea. Have a look at my data!*

> *Watch the **video** below for the full story:*

"""
#$(Resource(treasure_map, :width=>500))

# ╔═╡ 5fc032bb-990d-424e-a256-ef2979980606
begin
	xx =  [4.73,  0.45, -1.73,  1.09,  2.19,  0.12,  1.31,  1.00,
                     1.32,  1.07,  0.86, -0.49, -2.59,  1.73,  2.11,  1.61,
                     4.98,  1.71,  2.23,-57.20,  0.96,  1.25, -1.56,  2.45,
                     1.19,  2.17,-10.66,  1.91, -4.16,  1.92,  0.10,  1.98,
                    -2.51,  5.55, -0.47,  1.91,  0.95, -0.78, -0.84,  1.72,
                    -0.01,  1.48,  2.70,  1.21,  4.41, -4.79,  1.33,  0.81,
                     0.20,  1.58,  1.29, 16.19,  2.75, -2.38, -1.79,  6.50,
                   -18.53,  0.72,  0.94,  3.64,  1.94, -0.11,  1.57,  0.57]

md"""
## The data:
$(Resource(lyra, :width=>100))

*Click on the Checkbox 👉 $(show_flash_box) to see the position of the 100 flashes which I recorded. You can start a new observation by pressing the Button $(flashes)*.

> *Captain Bayes, can you help me to find the position of the lighthouse?*
	"""
end

# ╔═╡ 6dd8c883-dac4-4a31-b5ae-09ec067ba852
begin

	md"""

	*For sure Lyra, below you can find the __derivation__ how I perform this calculation.*

	*Just tick the checkbox to __start the calculation__ 👉 $(show_calculation_box)*

	$(Resource(bayes, :width=>100))

	"""

end

# ╔═╡ 7bf32131-f749-41da-9923-2970f1487f7e
begin
almost(text, headline=md"Almost there!") = Markdown.MD(Markdown.Admonition("warning", string(headline), [text]));
#brown

correct(text=md"Great! You got the right answer!", headline=md"Got it!") = Markdown.MD(Markdown.Admonition("correct", string(headline), [text]));
#green

keep_working(text=md"The answer is not quite right.", headline=md"Keep working on it!") = Markdown.MD(Markdown.Admonition("danger", string(headline), [text]));
#red

hint(text, headline=md"Hint") = Markdown.MD(Markdown.Admonition("hint", string(headline), [text]));
#blue

md"definition of boxes"
end

# ╔═╡ 5d349d39-c688-4431-b056-aa11d69376e9
function sr(variable, dig = 2; add_sign = false)
	# string and round - converts a variable into a string with the predifined precission - to be extended to scientific and other formats
	if dig == 0
		st = string(round(Int, variable))
	else
		st =  string(round(variable, digits = dig))
	end

	if add_sign
		st = (variable < 0 ? "" : "+") * st
	end

	return st

end

# ╔═╡ 1760c093-96c9-4ed9-8f4d-2c2ff3bfda5c
TableOfContents()

# ╔═╡ 00000000-0000-0000-0000-000000000001
PLUTO_PROJECT_TOML_CONTENTS = """
[deps]
HypertextLiteral = "ac1192a8-f4b3-4bfe-ba22-af5b92cd3ab2"
LaTeXStrings = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f"
Markdown = "d6f4376e-aef5-505a-96c1-9c027394607a"
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
PlutoUI = "7f904dfe-b85e-4ff6-b463-dae2292396a8"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"

[compat]
HypertextLiteral = "~0.9.3"
LaTeXStrings = "~1.3.0"
Plots = "~1.23.6"
PlutoUI = "~0.7.20"
"""

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

[[AbstractPlutoDingetjes]]
deps = ["Pkg"]
git-tree-sha1 = "0bc60e3006ad95b4bb7497698dd7c6d649b9bc06"
uuid = "6e696c72-6542-2067-7265-42206c756150"
version = "1.1.1"

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

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

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

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

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

[[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 = "f2202b55d816427cd385a9a4f3ffb226bee80f99"
uuid = "83423d85-b0ee-5818-9007-b63ccbeb887a"
version = "1.16.1+0"

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

[[ChangesOfVariables]]
deps = ["LinearAlgebra", "Test"]
git-tree-sha1 = "9a1d594397670492219635b35a3d830b04730d62"
uuid = "9e997f8a-9a97-42d5-a9f1-ce6bfc15e2c0"
version = "0.1.1"

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

[[FFMPEG_jll]]
deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "JLLWrappers", "LAME_jll", "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"

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

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

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

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

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

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

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

[[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 = "fd75fa3a2080109a2c0ec9864a6e14c60cca3866"
uuid = "d2c73de3-f751-5644-a686-071e5b155ba9"
version = "0.62.0+0"

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

[[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"

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

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

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

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

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

[[Hyperscript]]
deps = ["Test"]
git-tree-sha1 = "8d511d5b81240fc8e6802386302675bdf47737b9"
uuid = "47d2ed2b-36de-50cf-bf87-49c2cf4b8b91"
version = "0.0.4"

[[HypertextLiteral]]
git-tree-sha1 = "2b078b5a615c6c0396c77810d92ee8c6f470d238"
uuid = "ac1192a8-f4b3-4bfe-ba22-af5b92cd3ab2"
version = "0.9.3"

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

[[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"

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

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

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

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

[[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"

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

[[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"

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

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

[[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"]
git-tree-sha1 = "0d185e8c33401084cab546a756b387b15f76720c"
uuid = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
version = "1.23.6"

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

[[StaticArrays]]
deps = ["LinearAlgebra", "Random", "Statistics"]
git-tree-sha1 = "3c76dde64d03699e074ac02eb2e8ba8254d428da"
uuid = "90137ffa-7385-5640-81b9-e52037218182"
version = "1.2.13"

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

[[StatsAPI]]
git-tree-sha1 = "0f2aa8e32d511f758a2ce49208181f7733a0936a"
uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0"
version = "1.1.0"

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

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

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

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

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

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

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

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

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

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

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

[[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"

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

[[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"

[[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"

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

[[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"

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

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

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

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

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

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

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

[[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:
# ╟─6c070606-1411-40fc-b6cd-8f27f052136b
# ╟─ec784992-f4af-4ece-bf72-555960a054ca
# ╟─8f919de1-356f-4e42-9f7e-5d29092ed80f
# ╟─3c1cc3af-11f9-44ac-b07f-69704c4841c4
# ╟─936ccc78-8720-46b5-91eb-8d23f8699c99
# ╟─b8942536-020b-4c8e-a875-b5aba3034d42
# ╟─5fc032bb-990d-424e-a256-ef2979980606
# ╟─6dd8c883-dac4-4a31-b5ae-09ec067ba852
# ╟─ca076585-03b6-4381-b730-e32c7a30446e
# ╟─fd94fab8-c4c4-454e-9f5b-c0f1178143b3
# ╟─d3f023b1-8a57-4690-b8d6-afbe2ff50d5e
# ╟─bbb80420-ccae-48e7-a943-8aae332cb254
# ╟─ed56b559-ea17-41c7-8fe5-6ae9440fd5b5
# ╟─b2dc9f9b-9f57-4ca8-82ef-9c6a3915d6d0
# ╟─656ac69b-4cf5-440b-a894-83a7a80f42f0
# ╟─a61337a8-e197-4a7b-817d-012a5c1c0f17
# ╟─51b1234a-9808-4dad-a588-f61db077767f
# ╟─e7666210-a660-11eb-3e0d-7d9aec9a9f9e
# ╟─16938d4f-6f25-4924-8bdf-b0eb638a6c4f
# ╟─7bf32131-f749-41da-9923-2970f1487f7e
# ╟─5d349d39-c688-4431-b056-aa11d69376e9
# ╠═1760c093-96c9-4ed9-8f4d-2c2ff3bfda5c
# ╟─00000000-0000-0000-0000-000000000001
# ╟─00000000-0000-0000-0000-000000000002

max_stars_repo_name: moserjo/bayes-imoox

max_issues_repo_name: moserjo/bayes-imoox

max_forks_repo_name: moserjo/bayes-imoox


text:
@indextype BodyID

"""
$(TYPEDEF)

A non-deformable body.

A `RigidBody` has inertia (represented as a [`SpatialInertia`](@ref)),
unless it represents a root (world) body. A `RigidBody` additionally stores
a list of definitions of coordinate systems that are rigidly attached to it.
"""
mutable struct RigidBody{T}
    name::String
    inertia::Union{SpatialInertia{T}, Nothing}
    frame_definitions::Vector{Transform3D{T}}
    contact_points::Vector{DefaultContactPoint{T}} # TODO: allow different contact models
    id::BodyID

    # inertia undefined; can be used for the root of a kinematic tree
    function RigidBody{T}(name::String) where {T}
        frame = CartesianFrame3D(name)
        new{T}(name, nothing, [one(Transform3D{T}, frame)], DefaultContactPoint{T}[], BodyID(-1))
    end

    # other bodies
    function RigidBody(name::String, inertia::SpatialInertia{T}) where {T}
        new{T}(name, inertia, [one(Transform3D{T}, inertia.frame)], DefaultContactPoint{T}[], BodyID(-1))
    end
end

Base.eltype(::Type{RigidBody{T}}) where {T} = T
Base.eltype(body::RigidBody) = eltype(typeof(body))
RigidBody(inertia::SpatialInertia) = RigidBody(string(inertia.frame), inertia)
Base.print(io::IO, b::RigidBody) = print(io, b.name)

function Base.show(io::IO, b::RigidBody)
    if get(io, :compact, false)
        print(io, b)
    else
        print(io, "RigidBody: \"$(string(b))\"")
    end
end

BodyID(b::RigidBody) = b.id
Base.convert(::Type{BodyID}, b::RigidBody) = BodyID(b)
@inline RigidBodyDynamics.Graphs.vertex_id_type(::Type{<:RigidBody}) = BodyID
@inline RigidBodyDynamics.Graphs.vertex_id(b::RigidBody) = convert(BodyID, b)
@inline RigidBodyDynamics.Graphs.set_vertex_id!(b::RigidBody, id::BodyID) = (b.id = id)

"""
$(SIGNATURES)

Whether the body has a defined inertia.
"""
has_defined_inertia(b::RigidBody) = b.inertia !== nothing

"""
$(SIGNATURES)

Return the spatial inertia of the body. If the inertia is undefined, calling
this method will result in an error.
"""
spatial_inertia(b::RigidBody{T}) where {T} = b.inertia::SpatialInertia{T}

"""
$(SIGNATURES)

Set the spatial inertia of the body.
"""
function spatial_inertia!(body::RigidBody, inertia::SpatialInertia)
    body.inertia = transform(inertia, frame_definition(body, inertia.frame))
end

"""
    frame_definitions(body)

Return the list of homogeneous transforms ([`Transform3D`](@ref)s) that define the
coordinate systems attached to `body` with respect to a single common frame
([`default_frame(body)`](@ref)).
"""
frame_definitions(body::RigidBody) = body.frame_definitions

"""
$(SIGNATURES)

Whether `frame` is attached to `body` (i.e. whether it is among
[`frame_definitions(body)`](@ref)).
"""
is_fixed_to_body(body::RigidBody, frame::CartesianFrame3D) = any((t) -> t.from == frame, frame_definitions(body))

"""
$(SIGNATURES)

The [`CartesianFrame3D`](@ref) with respect to which all other frames attached
to `body` are defined.

See [`frame_definitions(body)`](@ref), [`frame_definition(body, frame)`](@ref).
"""
default_frame(body::RigidBody) = body.frame_definitions[1].to # allows standardization on a frame to reduce number of transformations required

"""
$(SIGNATURES)

Return the [`Transform3D`](@ref) defining `frame` (attached to `body`) with
respect to [`default_frame(body)`](@ref).

Throws an error if `frame` is not attached to `body`.
"""
function frame_definition(body::RigidBody, frame::CartesianFrame3D)
    for transform in body.frame_definitions
        transform.from == frame && return transform
    end
    error("$frame not found among body fixed frame definitions for $body")
end

"""
$(SIGNATURES)

Return the transform from `CartesianFrame3D` `from` to `to`, both of which are
rigidly attached to `body`.
"""
function fixed_transform(body::RigidBody, from::CartesianFrame3D, to::CartesianFrame3D)
    transform = frame_definition(body, from)
    if transform.to != to
        transform = inv(frame_definition(body, to)) * transform
    end
    transform
end

"""
$(SIGNATURES)

Add a new frame definition to `body`, represented by a homogeneous transform
from the `CartesianFrame3D` to be added to any other frame that is already
attached to `body`.
"""
function add_frame!(body::RigidBody, transform::Transform3D)
    # note: overwrites any existing frame definition
    # transform.to needs to be among (transform.from for transform in frame_definitions(body))
    definitions = body.frame_definitions
    if transform.to != default_frame(body)
        transform = frame_definition(body, transform.to) * transform
    end
    filter!(t -> t.from != transform.from, definitions)
    push!(definitions, transform)
    transform
end

"""
$(SIGNATURES)

Change the default frame of `body` to `frame` (which should already be among
`body`'s frame definitions).
"""
function change_default_frame!(body::RigidBody, new_default_frame::CartesianFrame3D)
    if new_default_frame != default_frame(body)
        old_to_new = inv(frame_definition(body, new_default_frame))
        map!(tf -> old_to_new * tf, body.frame_definitions, body.frame_definitions)
        if has_defined_inertia(body)
            body.inertia = transform(spatial_inertia(body), old_to_new)
        end
        for point in contact_points(body)
            point.location = old_to_new * point.location
        end
    end
end

"""
$(SIGNATURES)

Add a new contact point to the rigid body
"""
function add_contact_point!(body::RigidBody{T}, point::DefaultContactPoint{T}) where {T}
    loc = location(point)
    tf = fixed_transform(body, loc.frame, default_frame(body))
    point.location = tf * loc
    push!(body.contact_points, point)
    nothing
end

"""
$(SIGNATURES)

Return the contact points attached to the body as an ordered collection.
"""
contact_points(body::RigidBody) = body.contact_points

ext: jl


text:
@info "Loading DataFrames"
using DataFrames

@info "Loading LinearAlgebra"
using LinearAlgebra

@info "Loading JuMP"
using JuMP

@info "Loading Cbc"
using Cbc

@info "Loading StatsBase"
using StatsBase

@info "Statistics"
using Statistics

include("../types.jl")
include("../utilities.jl")
include("../topsis.jl")
include("../vikor.jl")
include("../electre.jl")
include("../moora.jl")
include("../dematel.jl")
include("../ahp.jl")
include("../nds.jl")
include("../singlecriterion.jl")
include("../game.jl")
include("../dataenvelop.jl")
include("../grey.jl")
include("../saw.jl")
include("../aras.jl")
include("../wpm.jl")
include("../waspas.jl")
include("../edas.jl")
include("../marcos.jl")
include("../mabac.jl")
include("../mairca.jl")
include("../copras.jl")
include("../promethee.jl")
include("../cocoso.jl")
include("../critic.jl")
include("../summary.jl")
include("../entropy.jl")
include("../codas.jl")

decmat =[60.000 0.400 2540 500 990
6.350 0.150 1016 3000 1041
6.800 0.100 1727.2 1500 1676
10.000 0.200 1000 2000 965
2.500 0.100 560 500 915
4.500 0.080 1016 350 508
3.000 0.100 1778 1000 920]

df = makeDecisionMatrix(decmat)

w  = [0.036, 0.192, 0.326, 0.326, 0.12];
fns = [maximum, minimum, maximum, maximum, maximum];

result = codas(df, w, fns)
#df = DataFrame(
#:age        => [6.0, 4, 12],
#:size       => [140.0, 90, 140],
#:price      => [150000.0, 100000, 75000],
#:distance   => [950.0, 1500, 550],
#:population => [1500.0, 2000, 1100]);

#methods1 = [:topsis, :electre, :vikor, :moora, :cocoso, :wpm, :waspas]
#methods2 = [:aras, :saw, :edas, :marcos, :mabac, :mairca, :grey]

# result1 = summary(df, w, fns, methods1);
# result2 = summary(df, w, fns, methods2);

# @info result1
# @info result2

max_stars_repo_name: bahadirfyildirim/JMcDM

max_issues_repo_name: bahadirfyildirim/JMcDM

max_forks_repo_name: bahadirfyildirim/JMcDM


text:
mutable struct ImgItpLast{TO,N,TI,NC,A<:AbstractArray{TI,N}} <: AbstractCachedArray{TO,N,TI,NC,A}
    parent::A
    coefs::Vector{Float64}
    cached::Array{TO,NC}
    current_I::Tuple
end

function ImgItpLast(img::Array34{T}, coefs, nd_cache=ndims(img)-1, out_type=Float64) where {T}
    nd = ndims(img)
    map(check01, coefs)
    if size(img,3) !== length(coefs)
        error("Input image size in the Z-slice dimension (3) should equal the number of interpolation coefficients provided")
    end
    if nd_cache > nd
        error("nd_cache must be less than or equal to ndims(img)")
    end
    ncache_rngs = axes(img)[nd_cache+1:nd]
    ci = map(first, ncache_rngs)
    za = ImgItpLast{out_type,nd,T,nd_cache,typeof(img)}(img, coefs, zeros(out_type, size(img)[1:nd_cache]...), ci)
    update_cache!(za, ci)
    return za
end

ImgItpLast(img::Array34{T}, coef::Float64, nd_cache=ndims(img)-1, out_type=Float64) where {T} =
    ImgItpLast(img, fill(coef, size(img, 3)), nd_cache, out_type)

function update_cache!(A::ImgItpLast{TO,N,TI,2}, inds::NTuple{NQ, Int}) where {TO,N,TI,NQ}
    #sometimes indexing works better than views with memory-mapped arrays
    pslice = A.parent[:, :, inds...]
    pslice_next = A.parent[:, :, Base.front(inds)...,last(inds)+1]
    coef = A.coefs[first(inds)] #get coef for this slice
    interp!(A.cached, pslice, pslice_next, coef)
    A.current_I = inds
end

function update_cache!(A::ImgItpLast{TO,N,TI,3}, inds::NTuple{NQ,Int}) where {TO,N,TI,NQ}
    #sometimes indexing works better than views with memory-mapped arrays
    pslice = A.parent[:, :, :, inds...]
    pslice_next = A.parent[:, :, :, Base.front(inds)...,last(inds)+1]
    interp!(A.cached, pslice, pslice_next, A.coefs)
    A.current_I = inds
end

size(A::ImgItpLast) = (Base.front(size(A.parent))...,last(size(A.parent))-1,)
Base.axes(A::ImgItpLast) = (Base.front(axes(parent(A)))..., first(last(axes(parent(A)))):(last(last(axes(parent(A))))-1),)
show(io::IO, A::ImgItpLast{TO}) where {TO} = print(io, "ImgItpLast of size $(size(A)) mapped to element type $TO\n")
show(io::IO, ::MIME"text/plain", A::ImgItpLast{TO}) where {TO} = show(io, A)

ImgItpLast(img::ImageMeta, coefs, out_type=Float64; kwargs...) = ImageMeta(ImgItpLast(data(img), coefs, out_type; kwargs...), properties(img))
ImgItpLast(img::AxisArray, coefs, out_type=Float64; kwargs...) = match_axisspacing(ImgItpLast(data(img),coefs,out_type; kwargs...), img)

#user interface
interp_last(A::AbstractArray, coef::Float64; kwargs...) = interp_last(A, fill(coef, size(A,3)); kwargs...)

function interp_last(A::AbstractArray{T,N}, coefs::Vector{Float64}; cache3d=false, out_type=Float64) where {T,N}
    if !in(N, (3,4))
        warn("$N-dimensional input was provided.  Only 3D and 4D inputs are tested; this will probably fail")
    end
    if N ==3 && cache3d
        cache3d = false
        warn("The cache3d kwarg was set for a 3D input matrix. This is only useful for 4D timeseries; ignoring kwarg")
    end
    return cache3d ? ImgItpLast(A, coefs, 3, out_type) : ImgItpLast(A, coefs, 2, out_type)
end


text:
using BinDeps
using Compat

@BinDeps.setup

libogg = library_dependency("libogg", aliases = ["libogg"])

@osx_only begin
  using Homebrew
  provides( Homebrew.HB, "libogg", libogg, os = :Darwin )
end

provides( AptGet, "libogg0", libogg )

@compat @BinDeps.install Dict(:libogg => :libogg)


text:
include("protocols/fake.jl")
include("protocols/simple.jl")
include("protocols/http.jl")


text:
module Draw

import Voronoi
import Covering

TIKZ = true
MATPLOTLIB = false

if MATPLOTLIB
    using PyPlot
    using PyCall

    const patch = PyNULL()
    function __init__()
        copy!(patch, pyimport("matplotlib.patches"))
    end

    plt = PyPlot
end

tikz_text = ""
ax = nothing
WIDTH = nothing
HEIGHT = nothing
FRAME = 0.1

if TIKZ
    COLOR_BLACK = "black"
    COLOR_SILVER = "silver"
    COLOR_AZURE = "azure"
    COLOR_ORANGERED = "orangered"
    COLOR_TOMATO = "blue"
    COLOR_MAGENTA = "magenta"
    COLOR_GOLD = "gold"
    COLOR_GRAY = "gray"
    COLOR_TAN = "tan"
    COLOR_RED = "red"
    COLOR_GREEN = "green"
else
    COLOR_BLACK = "xkcd:black"
    COLOR_SILVER = "xkcd:silver"
    COLOR_AZURE = "xkcd:azure"
    COLOR_ORANGERED = "xkcd:orangered"
    COLOR_TOMATO = "xkcd:tomato"
    COLOR_MAGENTA = "xkcd:magenta"
    COLOR_GOLD = "xkcd:gold"
    COLOR_GRAY = "xkcd:gray"
    COLOR_TAN = "xkcd:tan"
    COLOR_RED = "xkcd:red"
    COLOR_GREEN = "xkcd:green"
end

colors = ["white"]
#colors = ["xkcd:grey", "xkcd:crimson", "xkcd:gold", "xkcd:green", "xkcd:azure", "xkcd:beige", "xkcd:silver", "xkcd:lavender", "xkcd:lightgreen", "xkcd:magenta", "xkcd:ivory", "xkcd:maroon", "xkcd:orange", "xkcd:orangered", "xkcd:orchid", "xkcd:pink", "xkcd:plum", "xkcd:gold", "xkcd:salmon", "xkcd:sienna", "xkcd:lime", "xkcd:tan", "xkcd:tomato", "xkcd:violet", "xkcd:wheat", "xkcd:indigo", "xkcd:yellowgreen", "xkcd:chocolate", "xkcd:coral", "xkcd:brown"]

function clear(title::String)
   global plt, ax
   global WIDTH, HEIGHT, FRAME

   plt.cla()
   plt.title(title)
   if WIDTH > 0
      ax.set_aspect("equal")
      ax.set_xlim([0 - FRAME, WIDTH + FRAME])
      ax.set_ylim([0 - FRAME, HEIGHT + FRAME])
      ax.grid(false)
      ax.get_xaxis().set_visible(false)
      ax.get_yaxis().set_visible(false)
   else
      ax.grid(true)
      ax.get_xaxis().set_visible(true)
      ax.get_yaxis().set_visible(true)
   end
end

function init(w, h, ion=true)
    if TIKZ
        global tikz_text

        tikz_text = "\\begin{tikzpicture}[thick, scale=3]\n"
    end

    if MATPLOTLIB
        global plt, ax
        global WIDTH, HEIGHT

        plt.pygui(true)
        if ion
            plt.ion()
        end

        plt.clf()
        #plt.xkcd() # uncomment for generalized wobbliness
        ax = plt.gca() # get current axes

        WIDTH = w
        HEIGHT = h
        clear("")
    end
end

function legend(xlabel, ylabel)
   global plt

   plt.xlabel(xlabel)
   plt.ylabel(ylabel)
   plt.legend()
end

function commit()
    if TIKZ
        global tikz_text

        tikz_text *= "\\end{tikzpicture}\n\n"
    end

    if MATPLOTLIB
        global plt

        plt.draw()
    end
end

function savefig(filename)
    if TIKZ
        global tikz_text

        filename *= ".tex"
        println("Escrevendo Tikz no arquivo ", filename)

        open(filename, "w") do io
            write(io, tikz_text)
        end;
    end

    if MATPLOTLIB
        global plt

        filename *= ".png"

        plt.savefig(filename)
    end
end

function arc(p::Tuple{Real, Real}, r, θ1, θ2, color)
    if TIKZ
        global tikz_text

        t1 = 2π*θ1/360
        x = p[1] + r*cos(t1)
        y = p[2] + r*sin(t1)

        if θ2 < θ1
            θ2 += 360
        end

        tikz_text *= "\\draw[$color] ($(x), $(y)) arc ($(θ1):$(θ2):$(r)cm);\n"
    end

    if MATPLOTLIB
        global ax

        ax.add_artist(patch.Arc((p[1], p[2]), 2r, 2r, 0, θ1, θ2, color=color, linewidth=3, zorder=1))
    end
end

function circle(p::Tuple{Real, Real}, color, fill, r, l, zorder=1)
    if TIKZ
        global tikz_text

        tikz_text *= "\\draw[$color] ($(p[1]), $(p[2])) circle ($(r)cm);\n"
        if fill
            tikz_text *= "\\fill[$color] ($(p[1]), $(p[2])) circle ($(r)cm);\n"
        end
    end

    if MATPLOTLIB
        global ax

        ax.add_artist(patch.Circle((p[1], p[2]), color=color, radius=r, fill=fill, zorder=zorder, linewidth=l))
    end
end

function point(p::Tuple{Real, Real}, color, fill)
    circle(p, color, fill, 0.005, 1)
end

function circle(p::Tuple{Real, Real}, color, r)
   circle(p, color, false, r, 1)
end

function startFill(color)
    if TIKZ
        global tikz_text

        tikz_text *= "\\filldraw[color=$color, fill=$color" * "!10] "
    end
end

function fillVertex(p::Tuple{Real, Real})
    if TIKZ
        global tikz_text

        tikz_text *= "($(p[1]), $(p[2])) -- "
    end
end

function endFill()
    if TIKZ
        global tikz_text

        tikz_text *= "cycle;\n"
    end
end

function line(p1::Tuple{Real, Real}, p2::Tuple{Real, Real}, color)
    if TIKZ
        global tikz_text

        tikz_text *= "\\draw[$color] ($(p1[1]), $(p1[2])) -- ($(p2[1]), $(p2[2]));\n"
    end

    if MATPLOTLIB
        global plt

        plt.plot([p1[1], p2[1]], [p1[2], p2[2]], color=color, linestyle="-", linewidth=3, zorder=1)
    end
end

function thinLine(p1::Tuple{Real, Real}, p2::Tuple{Real, Real}, color)
   global plt

   plt.plot([p1[1], p2[1]], [p1[2], p2[2]], color=color, linestyle="-", linewidth=1, zorder=1)
end

function plot(f, color, start, finish)
   global plt

   x = range(start, stop=finish, length=1000)
   y = map(f, x)

   plt.plot(x, y, color=color, linewidth=3, zorder=2)
end

function plot(x, y, color, label, style)
   global plt

   plt.plot(x, y, color=color, label=label, linestyle=style, linewidth=3, zorder=2)
end

function fortuneIteration(V::Voronoi.Diagram.DCEL, T::Voronoi.BeachLine.BST, Q::Voronoi.EventQueue.Heap, points::Array{Tuple{Real, Real}}, ly::Real)
	#clear("Computing Voronoi Voronoi.Diagram using Fortune's Algorithm")
	clear("")

   # draw points
   for p in points
      point(p, COLOR_BLACK, (ly <= p[2]))
      if ly < p[2]
         f = Voronoi.Geometry.parabola(p, ly)
         plot(f, COLOR_SILVER, 0, WIDTH)
      end
   end

   # calculate parabolas and breakpoints
	beachLineFoci = Voronoi.BeachLine.beachLine(T, ly)

   # draw beachline
   start = (0, HEIGHT)
   i = 2
   while i <= size(beachLineFoci)[1] + 2
      if i <= size(beachLineFoci)[1]
         finish = beachLineFoci[i]
      else
         finish = (WIDTH, start[2])
      end

      p = beachLineFoci[i-1]
		f = Voronoi.Geometry.parabola(p, ly)

		if f == nothing # point is over the sweep line
         if start == nothing # special case where there the first couple of points are on the same y coordinate
         else
            Draw.line((p[1], ly), (p[1], start[2]), COLOR_AZURE)
         end
		else
         if 0 <= start[1]
            st = start[1]
         else
            st = 0
         end

         if finish[1] <= WIDTH
            fn = finish[1]
         else
            fn = WIDTH
         end

			plot(f, COLOR_AZURE, st, fn)
		end

      start = finish
      i += 2
	end

   # draw circumcircles
   i = 1
   while i < Q.pos
      if isa(Q.data[i], Voronoi.EventQueue.CircleEvent) && !(Q.data[i].removed)
         b = Q.data[i].disappearingArc
         a = b.prev
         c = b.next
         O = Q.data[i].center
         r = O[2] - Q.data[i].coordinates[2]
         circle(O, COLOR_ORANGERED, r)
         thinLine(O, b.region.generator, COLOR_ORANGERED)
         point(O, COLOR_MAGENTA, true)
         point((O[1], O[2] - r), COLOR_ORANGERED, true)
      end

      i += 1
   end

   # draw diagram edges
   for he in V.halfEdges
      if he.origin != nothing && he.twin.origin != nothing
         Draw.line(he.origin, he.twin.origin, COLOR_BLACK)
      end
   end

   # draw sweepline
	line((0, ly), (WIDTH, ly), COLOR_GOLD)
	commit()
end

function voronoiDiagram(V::Voronoi.Diagram.DCEL)
    global WIDTH, HEIGHT

	clear("")

    regions = Voronoi.Diagram.regionBorders(V)

    # draw regions
    i = 1
    for region in regions
        if size(region[1])[1] > 0
            ax.fill(region[1], region[2], colors[(i % size(colors)[1])+ 1])
        end
        i += 1
    end

    # draw diagram edges
    for he in V.halfEdges
        if he.origin != nothing
            if he.twin != nothing
                Draw.line(he.origin, he.twin.origin, COLOR_SILVER)
            elseif he.next != nothing
                Draw.line(he.origin, he.next.origin, COLOR_SILVER)
            end
        end
    end

    # draw generators
    for r in V.regions
        point(r.generator, COLOR_BLACK, true)
    end
end

function crossingPoint(center, dir, r)
    vector = (dir[1] - center[1], dir[2] - center[2])
    n = sqrt(vector[1]^2 + vector[2]^2)
    unitVector = (vector[1]/n, vector[2]/n)
    crossingPoint = (center[1] + r * unitVector[1], center[2] + r * unitVector[2])

    return crossingPoint
end

function circles(r::Real, points)
    for center in points
        circle(center, COLOR_GRAY, false, r, 1)
        point(center, COLOR_BLACK, true)
    end
end

function filledPolygon(section::Covering.Section, color=COLOR_TAN)
    if TIKZ
        if section.borderHead == nothing
            return
        end

        startFill(color)

        el = section.borderHead.next
        fillVertex(el.origin)
        while (el != section.borderHead)
            el = el.next
            fillVertex(el.origin)
        end

        endFill()
    else
        return coverginSection(section, 0, color)
    end
end

function coveringSection(section::Covering.Section, r::Real, color=COLOR_TAN)
    if section.borderHead == nothing
        return
    end

    center = section.center

    #circle(center, COLOR_GRAY, false, r, 1)

    el = section.borderHead.next
    i = 0
    if el isa Covering.Arc
        arc(section.center, r,
            Covering.radianToDegrees(Covering.segmentAngle(center, el.origin)),
            Covering.radianToDegrees(Covering.segmentAngle(center, el.next.origin)),
            COLOR_TOMATO)
        #cp = crossingPoint(center, el.origin, r)
        #line(cp, center, COLOR_GREEN)
        #line(cp, el.origin, "xkcd:pale green")
    else
        if color !== nothing
            line(el.origin, el.next.origin, color)
        end
        #line(el.origin, center, COLOR_GREEN)
    end

    while (el != section.borderHead)
        el = el.next
        i += 1
        if el isa Covering.Arc
            arc(section.center, r,
                Covering.radianToDegrees(Covering.segmentAngle(center, el.origin)),
                Covering.radianToDegrees(Covering.segmentAngle(center, el.next.origin)),
                COLOR_TOMATO)

            #cp = crossingPoint(center, el.origin, r)
            #line(cp, center, COLOR_GREEN)
            #line(cp, el.origin, COLOR_GREENreen")
        else
            if color !== nothing
                line(el.origin, el.next.origin, color)
            end
            #line(el.origin, center, COLOR_GREEN)
        end
        for p in Covering.Covering.segmentArcIntersections(Voronoi.Diagram.HalfEdge(el.origin, false, nothing,
                                                                          Voronoi.Diagram.HalfEdge(el.next.origin, false, nothing, nothing, nothing, center),
                                                                          nothing, center), center, r)
            #point(p, COLOR_RED, true)
        end
    end
end

function coveringPartition(P::Covering.Partition, color=COLOR_TAN)
    for section in P.sections
        Draw.coveringSection(section, P.r, color)
    end
end

end # module

max_stars_repo_name: arthursantana/coveringWithCircles

max_issues_repo_name: arthursantana/coveringWithCircles

max_forks_repo_name: arthursantana/coveringWithCircles


text:
struct MockDofBasis{P} <: AbstractVector{PointValue}
  nodes::Vector{P}
end

function return_cache(b::MockDofBasis,field)
  return_cache(field,b.x)
end

function evaluate!(cache,b::MockDofBasis,field)
  evaluate!(cache,field,b.x)
end

Base.size(a::MockDofBasis) = (length(a.nodes),)
Base.axes(a::MockDofBasis) = (axes(a.nodes,1),)
# @santiagobadia : Not sure we want to create the moment dofs
Base.getindex(a::MockDofBasis,i::Integer) = PointValue(a.x[i])
Base.IndexStyle(::MockDofBasis) = IndexLinear()


text:
include(joinpath(pwd(),"src/models/quadrotor.jl"))
include(joinpath(pwd(),"src/constraints/free_time.jl"))

optimize = true

# Free-time model
model_ft = free_time_model(model)

function fd(model::Quadrotor, x⁺, x, u, w, h, t)
	midpoint_implicit(model, x⁺, x, u, w, u[end])
end

# Horizon
T = 31

# Time step
tf0 = 5.0
h0 = tf0 / (T-1)

# ul <= u <= uu
_uu = 5.0 * ones(model_ft.m)
_uu[end] = h0

uu_nom = copy(_uu)
uu1 = copy(_uu)
uu1[1] *= 0.5
uu2 = copy(_uu)
uu2[2] *= 0.5
uu3 = copy(_uu)
uu3[3] *= 0.5
uu4 = copy(_uu)
uu4[4] *= 0.5

_ul = zeros(model_ft.m)
_ul[end] = 0.0
ul_nom = copy(_ul)
@assert sum(_uu) > -1.0 * model_ft.mass * model.g[3]

ul, uu = control_bounds(model_ft, T, _ul, _uu)

# Initial and final states
x1 = zeros(model_ft.n)
x1[3] = 1.0
xT = copy(x1)
xT[1] = 3.0
xT[2] = 3.0

_xl = -Inf * ones(model_ft.n)
_xl[3] = 0.0

_xu = Inf * ones(model_ft.n)

xl, xu = state_bounds(model_ft, T, _xl, _xu, x1 = x1, xT = xT)

u_ref = [-1.0 * model_ft.mass * model_ft.g[3] / 4.0 * ones(4); 0.0]

# Objective
obj = quadratic_time_tracking_objective(
	[(t < T ? Diagonal(ones(model_ft.n))
		: Diagonal(1.0 * ones(model_ft.n))) for t = 1:T],
	[Diagonal([1.0e-1 * ones(4); 0.0]) for t = 1:T-1],
    [copy(xT) for t = 1:T],
	[copy(u_ref) for t = 1:T-1],
	1.0)

# Time step constraints
con_free_time = free_time_constraints(T)

# Problem
prob = trajectory_optimization_problem(model_ft,
			   obj,
			   T,
               xl = xl,
               xu = xu,
               ul = ul,
               uu = uu,
               con = con_free_time
               )

# Trajectory initialization
X0 = linear_interp(x1, xT, T) # linear interpolation on state
U0 = [[copy(u_ref[1:4]); h0] for t = 1:T-1] # random controls

# Pack trajectories into vector
Z0 = pack(X0, U0, prob)

#NOTE: may need to run examples multiple times to get good trajectories
# Solve nominal problem
if optimize
    @time Z̄ = solve(prob, copy(Z0))
    @save joinpath(@__DIR__, "sol.jld2") Z̄
else
    println("Loading solution...")
    @load joinpath(@__DIR__, "sol.jld2") Z̄
end

max_stars_repo_name: zacmanchester/DirectMotionPlanning

max_issues_repo_name: zacmanchester/DirectMotionPlanning

max_forks_repo_name: zacmanchester/DirectMotionPlanning


text:
function parse_kw(ps::ParseState, ::Type{Val{Tokens.TRY}})
    startbyte = ps.t.startbyte
    start_col = ps.t.startpos[2] + 4

    # Parsing
    kw = INSTANCE(ps)
    format_kw(ps)
    ret = EXPR{Try}(EXPR[kw], -ps.t.startbyte, Variable[], "")

    tryblock = EXPR{Block}(EXPR[], 0, Variable[], "")
    @catcherror ps startbyte @default ps @closer ps trycatch parse_block(ps, tryblock, start_col)
    push!(ret.args, tryblock)

    # try closing early
    if ps.nt.kind == Tokens.END
        next(ps)
        push!(ret.args, FALSE)
        push!(ret.args, EXPR{Block}(EXPR[], 0, Variable[], ""))
        push!(ret.args, INSTANCE(ps))
        ret.span += ps.nt.startbyte
        return ret
    end

    #  catch block
    if ps.nt.kind == Tokens.CATCH
        next(ps)
        # catch closing early
        if ps.nt.kind == Tokens.FINALLY || ps.nt.kind == Tokens.END
            push!(ret.args, INSTANCE(ps))
            caught = FALSE
            catchblock = EXPR{Block}(EXPR[], 0, Variable[], "")
        else
            start1 = ps.nt.startbyte
            start_col = ps.t.startpos[2] + 4
            push!(ret.args, INSTANCE(ps))
            if ps.ws.kind == SemiColonWS || ps.ws.kind == NewLineWS
                caught = FALSE
            else
                @catcherror ps startbyte caught = @default ps @closer ps ws @closer ps trycatch parse_expression(ps)
            end
            catchblock = EXPR{Block}(EXPR[], 0, Variable[], "")
            @catcherror ps startbyte @default ps @closer ps trycatch parse_block(ps, catchblock, start_col)
            if !(caught isa EXPR{IDENTIFIER} || caught == FALSE)
                unshift!(catchblock.args, caught)
                catchblock.span += caught.span
                caught = FALSE
            elseif caught isa EXPR{IDENTIFIER}
                push!(caught.defs, Variable(Expr(caught), :Any, caught))
            end
        end
    else
        caught = FALSE
        catchblock = EXPR{Block}(EXPR[], 0, Variable[], "")
    end
    push!(ret.args, caught)
    push!(ret.args, catchblock)

    # finally block
    if ps.nt.kind == Tokens.FINALLY
        if isempty(catchblock.args)
            ret.args[4] = FALSE
        end
        next(ps)
        start_col = ps.t.startpos[2] + 4
        push!(ret.args, INSTANCE(ps))
        finallyblock = EXPR{Block}(EXPR[], 0, Variable[], "")
        @catcherror ps startbyte parse_block(ps, finallyblock, start_col)
        push!(ret.args, finallyblock)
    end

    next(ps)
    push!(ret.args, INSTANCE(ps))
    ret.span += ps.nt.startbyte
    return ret
end


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

@doc raw"""NetworkPolicyIngressRule describes a particular set of traffic that is allowed to the pods matched by a NetworkPolicySpec's podSelector. The traffic must match both ports and from.

    IoK8sApiNetworkingV1NetworkPolicyIngressRule(;
        from=nothing,
        ports=nothing,
    )

    - from::Vector{IoK8sApiNetworkingV1NetworkPolicyPeer} : List of sources which should be able to access the pods selected for this rule. Items in this list are combined using a logical OR operation. If this field is empty or missing, this rule matches all sources (traffic not restricted by source). If this field is present and contains at least one item, this rule allows traffic only if the traffic matches at least one item in the from list.
    - ports::Vector{IoK8sApiNetworkingV1NetworkPolicyPort} : List of ports which should be made accessible on the pods selected for this rule. Each item in this list is combined using a logical OR. If this field is empty or missing, this rule matches all ports (traffic not restricted by port). If this field is present and contains at least one item, then this rule allows traffic only if the traffic matches at least one port in the list.
"""
mutable struct IoK8sApiNetworkingV1NetworkPolicyIngressRule <: SwaggerModel
    from::Any # spec type: Union{ Nothing, Vector{IoK8sApiNetworkingV1NetworkPolicyPeer} } # spec name: from
    ports::Any # spec type: Union{ Nothing, Vector{IoK8sApiNetworkingV1NetworkPolicyPort} } # spec name: ports

    function IoK8sApiNetworkingV1NetworkPolicyIngressRule(;from=nothing, ports=nothing)
        o = new()
        validate_property(IoK8sApiNetworkingV1NetworkPolicyIngressRule, Symbol("from"), from)
        setfield!(o, Symbol("from"), from)
        validate_property(IoK8sApiNetworkingV1NetworkPolicyIngressRule, Symbol("ports"), ports)
        setfield!(o, Symbol("ports"), ports)
        o
    end
end # type IoK8sApiNetworkingV1NetworkPolicyIngressRule

const _property_map_IoK8sApiNetworkingV1NetworkPolicyIngressRule = Dict{Symbol,Symbol}(Symbol("from")=>Symbol("from"), Symbol("ports")=>Symbol("ports"))
const _property_types_IoK8sApiNetworkingV1NetworkPolicyIngressRule = Dict{Symbol,String}(Symbol("from")=>"Vector{IoK8sApiNetworkingV1NetworkPolicyPeer}", Symbol("ports")=>"Vector{IoK8sApiNetworkingV1NetworkPolicyPort}")
Base.propertynames(::Type{ IoK8sApiNetworkingV1NetworkPolicyIngressRule }) = collect(keys(_property_map_IoK8sApiNetworkingV1NetworkPolicyIngressRule))
Swagger.property_type(::Type{ IoK8sApiNetworkingV1NetworkPolicyIngressRule }, name::Symbol) = Union{Nothing,eval(Base.Meta.parse(_property_types_IoK8sApiNetworkingV1NetworkPolicyIngressRule[name]))}
Swagger.field_name(::Type{ IoK8sApiNetworkingV1NetworkPolicyIngressRule }, property_name::Symbol) =  _property_map_IoK8sApiNetworkingV1NetworkPolicyIngressRule[property_name]

function check_required(o::IoK8sApiNetworkingV1NetworkPolicyIngressRule)
    true
end

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


text:
using YorkFit
using Base.Test

# Test least-squares estimate
let
    Xs = collect(1:10.0)
    Ys = 2.0 * Xs + 3.0
    (a, b) = YorkFit.lsq(Xs, Ys)
    @test isapprox(a, 3.0)
    @test isapprox(b, 2.0)
end

# Test components of York method with simple cases
let
    Xs = collect(1:10.0)
    Ys = 2.0*Xs + 3.0
    σXs = fill(0.05, 10)
    σYs = fill(0.02, 10)
    r = 0.0

    ωXs = YorkFit.ω.(σXs)
    ωYs = YorkFit.ω.(σYs)

    @test isapprox(ωXs, fill(400.0, 10))
    @test isapprox(ωYs, fill(2500.0, 10))

    αs = YorkFit.α.(ωXs, ωYs)
    @test isapprox(αs, fill(1000.0, 10))

    Ws = YorkFit.W.(ωXs, ωYs, fill(r, 10), 2.0, αs)
    @test isapprox(Ws, fill(1250/13, 10))

    barX = YorkFit.barvar(Ws, Xs)
    barY = YorkFit.barvar(Ws, Ys)

    @test isapprox(barX, 5.5)
    @test isapprox(barY, 14.0)

    Us = Xs - barX
    Vs = Ys - barY
    βs = YorkFit.β.(Ws, Us, Vs, ωXs, ωYs, 2.0, r, αs)
    @test isapprox(βs, collect(-4.5:1:4.5))
end

# Test fit methods
let
    Xs = collect(1.0:10.0)
    Ys = 2.0*Xs + 3.0
    σX = 0.25
    σY = 0.5
    r = 0.25

    # Expected results
    Ea = 3.0
    Eb = 2.0
    Eσb = 0.06741998624
    Eσa = 0.41833001326

    function testvals(a, b, σa, σb)
        @test isapprox(a, Ea)
        @test isapprox(b, Eb)
        @test isapprox(σa, Eσa)
        @test isapprox(σb, Eσb)
    end

    # Vector r, constant σX, Vector σY
    (a, b, σa, σb) = YorkFit.fit(Xs, Ys, σX, fill(σY, 10), fill(r, 10), niter=2)
    testvals(a, b, σa, σb)

    # Constant r, constant σX, Vector σY
    (a, b, σa, σb) = YorkFit.fit(Xs, Ys, σX, fill(σY, 10), r, niter=2)
    testvals(a, b, σa, σb)

    # Vector r, vector σX, constant σY
    (a, b, σa, σb) = YorkFit.fit(Xs, Ys, fill(σX, 10), σY, fill(r, 10), niter=2)
    testvals(a, b, σa, σb)

    # Constant r, vector σX, constant σY
    (a, b, σa, σb) = YorkFit.fit(Xs, Ys, fill(σX, 10), σY, r, niter=2)
    testvals(a, b, σa, σb)

    # Vector r, constant σX, σY
    (a, b, σa, σb) = YorkFit.fit(Xs, Ys, σX, σY, fill(r, 10), niter=2)
    testvals(a, b, σa, σb)

    # Constant σX, σY, r
    (a, b, σa, σb) = YorkFit.fit(Xs, Ys, σX, σY, r, niter=2)
    testvals(a, b, σa, σb)

    # Constant r, vector σX, Vector σY
    (a, b, σa, σb) = YorkFit.fit(Xs, Ys, fill(σX, 10), fill(σY, 10), r, niter=2)
    testvals(a, b, σa, σb)

    # Vector r, vector σX, Vector σY
    (a, b, σa, σb) = YorkFit.fit(Xs, Ys, fill(σX, 10), fill(σY, 10), fill(r, 10), niter=2)
    testvals(a, b, σa, σb)
end


text:
const OneDimensionalEnsembleModel = HydrostaticFreeSurfaceModel{TS, E, A, S, <:OneDimensionalEnsembleGrid, T, V, B, R, F, P, U, C, Φ, K, AF} where {TS, E, A, S, T, V, B, R, F, P, U, C, Φ, K, AF}

ensemble_size(model::OneDimensionalEnsembleModel) = model.grid.Nx
batch_size(model::OneDimensionalEnsembleModel) = model.grid.Ny

"""
    set!(model::OneDimensionalEnsembleModel,
         observations::OneDimensionalTimeSeriesBatch, time_index)

Set columns of each field in `model` to the model profile columns in `observations`,
where every field column in `model` that corresponds to the ith `OneDimensionalTimeSeries` object in `observations`
is set to the field column in `observations[i]` at time index `time_indices[i]`.
"""
function set!(model::OneDimensionalEnsembleModel,
              observations::OneDimensionalTimeSeriesBatch, time_indices::Vector)

    ensemble(x) = column_ensemble_interior(observations, x, time_indices, model.grid.Nx)

    set!(model, b = ensemble(:b),
                u = ensemble(:u),
                v = ensemble(:v),
                e = ensemble(:e)
        )
end

set!(model::OneDimensionalEnsembleModel, observations::OneDimensionalTimeSeriesBatch, time_index) = set!(model, observations, [time_index for i in observations])

"""
    initialize_forward_run!(model, observations::OneDimensionalTimeSeriesBatch, params, time_indices::Vector)

Set columns of each field in `model` to the corresponding profile columns in `observations`,
where every field column in `model` that corresponds to the ith `OneDimensionalTimeSeries` object in `observations`
is set to the field column in `observations[i]` at `time_indices[i]`.
"""
function initialize_forward_run!(model::OneDimensionalEnsembleModel, observations::OneDimensionalTimeSeriesBatch, params, time_indices::Vector)
    set!(model, params)
    set!(model, observations, time_indices)
    model.clock.time = 0.0
    model.clock.iteration = 0
    return nothing
end


text:
#!/usr/bin/env julia

# Lets add workers programatically, and see if they distribute to different cores.

# using ArgParse
#
# s = ArgParseSettings()
# @add_arg_table s begin
#     # "--opt1"
#     # help = "an option with an argument"
#     "--p", "-p"
#     help = "number of processes to add"
#     arg_type = Int
#     default = 0
# end
#
# parsed_args = parse_args(ARGS, s)
#
# p = parsed_args["p"]
#
# if p > 0
#     addprocs(p)
# end

nchild = nworkers()
println("Workers allocated ", nchild)
println("Total workers ", workers())

println("Total processes ", nprocs())

@everywhere function print_cpus()
    run(pipeline(`ps -eo pid,psr,pcpu,cmd`, `grep julia`))
end

println("Before map")
print_cpus()

# Trying to set path
@everywhere ENV["PATH"] = ENV["PATH"] * ":/n/home07/iczekala/.build/radmc-3d/version_0.38/src"

@everywhere function pcpus(mat)
    println("In map")
    print_cpus()
    run(`which radmc3d`)
    svd(mat)
end

M = [rand(1000,1000) for i=1:nchild]

pmap(pcpus, M)

println("After map.")
print_cpus()


text:
#!/usr/bin/env julia

using Luxor, Colors, ColorSchemes

width = 225  # pts
height = 225 # pts
Drawing(width, height, "/tmp/logo.pdf")

function spiral(colscheme)
  circle(0, 0, 90, :clip)
  for theta in pi/2 - pi/8:pi/8: (19 * pi)/8
    sethue(colorscheme(colscheme, rescale(theta, pi/2, (19 * pi)/8, 0, 1)))
    gsave()
    rotate(theta)
    move(5,0)
    curve(Point(40, 40), Point(50, -40), Point(80, 30))
    closepath()
    fill()
    grestore()
  end
  clipreset()
end

origin()
background("white")
scale(1.3, 1.3)
colscheme = loadcolorscheme("solarcolors")
colschememirror = vcat(colscheme, reverse(colscheme))
spiral(colschememirror)
finish()
preview()


text:
"""
    Genser.Tag{tag}

The type of genser tags.

Tags provide additional semantic metadata about a genser type.
They are particular useful for string values because some
(de)serializers are capable of including additional metadata
in their output.

Each tag is a singleton of a unique data type.
"""
struct Tag{tag} end

"""
    Genser.Tag(tag)

Construct a tag for a Genser type.
"""
Tag(tag) = Tag{Symbol(tag)}()
Base.show(io::IO, ::Tag{tag}) where {tag} = Base.print(io, "Genser.Tag(:$tag)")
Base.print(io::IO, ::Tag{tag}) where {tag} = Base.print(io, tag)

tags = [
    # Unit types
    :undefined,
    :null,

    # Primitive types
    :int8,
    :uint8,
    :int16,
    :uint16,
    :int32,
    :uint32,
    :int64,
    :uint64,
    :int128,
    :uint128,
    :bigint,
    :bool,
    :char,
    :float16,
    :float32,
    :float64,
    :rational,
    :bigfloat,

    # String types
    :str,
    :uri,

    # Binary types
    :binary,
    # TODO: Add string encoding suggestions (e.g. base64)

    # Other atoms
    :uuid,
    :symbol,

    # Array types
    :sequence,
    :tuple,
    :set,

    # Dict types
    :dict,
    :record,
    :namedtuple,

    # Union types
    :variant,
    :optional,

    # Any type
    :any,
]

for tag = tags
    tagstr = string(tag)
    @eval const $tag = Tag($tagstr)
end

"""
    Genser.GenserDataType{tag}

Base Genser data model type.
"""
abstract type GenserDataType{t} end

"""
    Genser.GenserValue{V, tag}

Base Genser data model type for simple values.
"""
struct GenserValue{V, t} <: GenserDataType{t}
    value::V
end

macro genservalue(T, tag = nothing)
    if isnothing(tag)
        tag = Symbol(lowercase(String(T)))
    end

    return quote
        const GenserType = GenserValue{$T, $tag}
        GenserType
    end
end

# Categories
"""
    Genser.GenserNumberValue{V <: Number, tag}

A category type for genser values that hold a Number.
"""
GenserNumberValue{V <: Number, t} = GenserValue{V, t}

"""
    Genser.GenserRealValue{V <: Real, tag}

A category type for genser values that hold a Real.
"""
GenserRealValue{V <: Real, t} = GenserValue{V, t}

"""
    Genser.GenserIntegerValue{V <: Integer, tag}

A category type for genser values that hold an Integer.
"""
GenserIntegerValue{V <: Integer, t} = GenserValue{V, t}

"""
    Genser.GenserSignedValue{V <: Signed, tag}

A category type for genser values that hold a Signed.
"""
GenserSignedValue{V <: Signed, t} = GenserValue{V, t}

"""
    Genser.GenserUnsignedValue{V <: Unsigned, tag}

A category type for genser values that hold an Unsigned.
"""
GenserUnsignedValue{V <: Unsigned, t} = GenserValue{V, t}

"""
    Genser.GenserFloatValue{V <: AbstractFloat, tag}

A category type for genser values that hold an AbstractFloat.
"""
GenserFloatValue{V <: AbstractFloat, t} = GenserValue{V, t}

"""
    Genser.GenserStringValue{tag}

A category type for genser values that hold an AbstractString.
"""
GenserStringValue{t} = GenserValue{AbstractString, t}

# Nothing types
"""
    Genser.GenserNothingValue{tag}

A category type for genser values that hold a Nothing.
"""
abstract type GenserNothingValue{t} <: GenserDataType{t} end

"""
    Genser.GenserUndefined()

A type that holds nothing, tagged to suggest that it holds an "undefined" value.
"""
struct GenserUndefined <: GenserNothingValue{undefined} end

"""
    Genser.GenserNull()

A type that holds nothing, tagged to suggest that it holds a "null" value.
"""
struct GenserNull <: GenserNothingValue{null} end

# Primitive types
"""
    Genser.GenserInt8(value::Int8)

A type that holds an Int8 value.
"""
const GenserInt8 = @genservalue(Int8)

"""
    Genser.GenserUInt8(value::UInt8)

A type that holds a UInt8 value.
"""
const GenserUInt8 = @genservalue(UInt8)

"""
    Genser.GenserInt16(value::Int16)

A type that holds an Int16 value.
"""
const GenserInt16 = @genservalue(Int16)

"""
    Genser.GenserUInt16(value::UInt16)

A type that holds a UInt16 value.
"""
const GenserUInt16 = @genservalue(UInt16)

"""
    Genser.GenserInt32(value::Int32)

A type that holds an Int32 value.
"""
const GenserInt32 = @genservalue(Int32)

"""
    Genser.GenserUInt32(value::Int32)

A type that holds a UInt32 value.
"""
const GenserUInt32 = @genservalue(UInt32)

"""
    Genser.GenserInt64(value::Int64)

A type that holds an Int64 value.
"""
const GenserInt64 = @genservalue(Int64)

"""
    Genser.GenserUInt64(value::UInt64)

A type that holds a UInt64 value.
"""
const GenserUInt64 = @genservalue(UInt64)

"""
    Genser.GenserInt128(value::Int128)

A type that holds an Int128 value.
"""
const GenserInt128 = @genservalue(Int128)

"""
    Genser.GenserUInt128(value::UInt128)

A type that holds a UInt128 value.
"""
const GenserUInt128 = @genservalue(UInt128)

"""
    Genser.GenserBigInt(value::BigInt)

A type that holds a BigInt value.
"""
const GenserBigInt = @genservalue(BigInt)

"""
    Genser.GenserBool(value::Bool)

A type that holds a Bool value.
"""
const GenserBool = @genservalue(Bool)

"""
    Genser.GenserChar(value::Char)

A type that holds a Char value.
"""
const GenserChar = @genservalue(Char)

"""
    Genser.GenserFloat16(value::Float16)

A type that holds a Float16 value.
"""
const GenserFloat16 = @genservalue(Float16)

"""
    Genser.GenserFloat32(value::Float32)

A type that holds a Float32 value.
"""
const GenserFloat32 = @genservalue(Float32)

"""
    Genser.GenserFloat64(value::Float64)

A type that holds a Float64 value.
"""
const GenserFloat64 = @genservalue(Float64)

"""
    Genser.GenserBigFloat(value::BigFloat)

A type that holds a BigFloat value.
"""
const GenserBigFloat = @genservalue(BigFloat)

"""
    Genser.GenserRational(value::Rational)

A type that holds a Rational value.
"""
const GenserRational = @genservalue(Rational)

"""
    Genser.GenserString(value::AbstractString)

A type that holds a String value.
"""
const GenserString = GenserStringValue{str}

"""
    Genser.GenserURI(value::AbstractString)

A type that holds a String value tagged as a URI value.
"""
const GenserURI = GenserStringValue{uri}

"""
    Genser.GenserBinaryValue{E <: Encoding}(value::Vector{UInt8})

A category type for genser values that hold binary data.
The encoding type parameter is used to convert the data to and from
a string representation for formats that do not support binary types.
"""
struct GenserBinaryValue{E<:Encoding} <: GenserDataType{binary}
    value::Vector{UInt8}
end

"""
    Genser.GenserBinary(value::Vector{UInt8})

A binary type with no string encoding.

This is the default Genser type for Vector{UInt8} value.
"""
const GenserBinary = GenserBinaryValue{Encoding{:none}}

"""
    Genser.GenserUUID(value::Base.UUID)

A type that holds a UUID value.

Typically, a UUID is serialized into its string representation
for text-based formats and binary representation for binary formats.
Some formats may have built-in support for the type.
"""
const GenserUUID = @genservalue(UUID, uuid)

"""
    Genser.GenserSymbol(value::Symbol)

A type that holds a Symbol value.

Typically, a Symbol is serialized into its string representation,
but formats may have built-in support for type type.
"""
const GenserSymbol = @genservalue(Symbol, symbol)

"""
    Genser.GenserSequence{V <: GenserDataType}(AbstractVector{V})

A type that holds an AbstractVector of values.
"""
struct GenserSequence{T <: GenserDataType} <: GenserDataType{sequence}
    value::AbstractVector{T}
end

"""
    Genser.GenserSet{V <: GenserDataType}(AbstractSet{V})

A type that holds an AbstractSet of values.

Typically, a set is serialized in the same format as a sequence.
"""
struct GenserSet{T <: GenserDataType} <: GenserDataType{set}
    value::AbstractSet{T}
end

"""
    Genser.GenserSet{V <: Tuple}(value::V)

A type that holds a Tuple of values.

Typically, a tuple is serialized in the same format as a sequence.
"""
struct GenserTuple{T <: Tuple} <: GenserDataType{tuple}
    value::T
end

"""
    Genser.GenserDict{K <: GenserDataType, V <: GenserDataType}(value::AbstractDict{K,V}())

A type that holds an AbstractDict of values.

For compatibility, the K type should be type that can be stringified.
"""
struct GenserDict{K <: GenserDataType, V <: GenserDataType} <: GenserDataType{dict}
    value::AbstractDict{K,V}
end

"""
    Genser.GenserRecord{V <: NamedTuple}(value::V)

A type that holds a fixed set of key-value pairs.

The is the default type for all structs.
"""
struct GenserRecord{T <: NamedTuple} <: GenserDataType{record}
    value::T
end

"""
    Genser.GenserOptional{V <: GenserDataType}(value::Union{GenserUndefined, V})

A type that may or may not hold a value.

The is the default type for all Union types that include Nothing.
"""
struct GenserOptional{T <: GenserDataType} <: GenserDataType{optional}
    value::Union{GenserUndefined,T}
end

"""
    Genser.GenserVariant{V <: GenserDataType}(value::V)

A type that may contain a value of one or more types.

The `V` type parameter is always a Union type.

The is the default type for all Union types that do not include Nothing.
"""
struct GenserVariant{T <: GenserDataType} <: GenserDataType{variant}
    value::T
end

"""
    Genser.GenserAny(value::GenserDataType)

A type that may or may hold any type of value.

The is the default type for the Any type.
"""
struct GenserAny <: GenserDataType{any}
    value::GenserDataType
end

"""
    Genser.tag(v) :: Genser.Tag

Get the tag of a Genser data type or Genser value.
"""
@inline function tag(::GenserDataType{t}) :: Tag where {t}
    t
end

@inline function tag(::Type{<: GenserDataType{t}}) :: Tag where {t}
    t
end

"""
    Genser.encoding(::Type{<: GenserDataType}) :: Genser.Encoding

Get the string encoding of a genser data type or value.
"""
@inline function encoding(::Type{<: GenserDataType}) :: Encoding
    Encoding("none")
end

@inline function encoding(::Type{<: GenserBinaryValue{E}}) :: Encoding where E
    E()
end

(==)(a::T, b::T) where {T <: GenserNothingValue} = tag(a) == tag(b)
(==)(a::T, b::T) where {T <: GenserDataType} = tag(a) == tag(b) && a.value == b.value


text:
struct JacobiSmoother

    C :: SparseMatrixCSC
    f :: Vector{Float64}
    asynch_steps :: Int64
    slices :: Vector{UnitRange}

end

function JacobiSmoother(A::SparseMatrixCSC, b::Vector{Float64}, w::Float64, pchunks, Nk, Nz, Na)

    D = w*Diagonal(1 ./ diag(A))
    C = I - D*A
    f = D * b

    chunksize = div(Nk, pchunks)
    pslices = collect(Iterators.partition(1:Nk, chunksize))
    # pslices = UnitRange{Int64}[g[1]:g[end] for g in pgroups]
    slices = UnitRange{Int64}[]
    for z=1:Nz
        slices = [slices; [s .+ (z-1)*Nk for s in pslices]]
    end

    return JacobiSmoother(C, f, Na, pslices)
end

function Base.:*(J::JacobiSmoother, v::Vector{Float64})

    out = pmap(J.slices) do inds
        x = v[:]
        C_loc = J.C[inds, :]
        f_loc = J.f[inds]

        for t=1:J.asynch_steps
            x[inds] = C_loc * x + f_loc
        end
        x[inds]
    end

    return vcat(out...)
end