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

using Markdown
using InteractiveUtils

# ╔═╡ 8ae7bb38-5803-41d0-98e3-6d9dc4936406
using StatsPlots

# ╔═╡ 03eb200d-c3b4-43d6-b86f-017f5454bc86
using Random

# ╔═╡ 50cd5676-cdba-425d-84d3-7ad6fe21a2d5
md"""
The code in this notebook accompanies the essay "Riding the Covid Coaster," by Brian Hayes, published 17 August 2021 at [http://bit-player.org/2021/riding-the-covid-coaster](http://bit-player.org/2021/riding-the-covid-coaster). It explores various approaches to understanding the trajectory of the Covid-19 epidemic in the United States during its first 18 months.

This is one of three notebooks with code for the project:

* covidcurve.jl covers the reconstruction of the Covid-19 incidence curve and attempts to apply Fourier methods, looking for periodic signals in the data. Also a look at time derivatives. Includes code for figures 1, 3, 4, 5, 6, 7, 8, 9, 12.

* SIR_model.jl deals with exponential growth in epidemic processes, and models based on that idea. Figures 10, 11, 13, 14, 16, 17, 18, 19, 20, 21, 23, 24.

* us_states_data.jl breaks down the national Covid data set into records for inividual states and regions. Code for Figure 22.

The underlying data for most of this work was collected and curated by _The New York Times_. The archive is available at [https://github.com/nytimes/covid-19-data](https://github.com/nytimes/covid-19-data). The version I used in the code below, including data from 21 January 2020 through 20 July 2021, is commit c3ab8c1beba1f4728d284c7b1e58d7074254aff8. You can access the identical set of files at [https://github.com/nytimes/covid-19-data/tree/c3ab8c1beba1f4728d284c7b1e58d7074254aff8](https://github.com/nytimes/covid-19-data/tree/c3ab8c1beba1f4728d284c7b1e58d7074254aff8). But you should probably get the most up-to-date version, with the latest data.

Within the _Times_ archive I have used the files within a folder named "rolling-averages," which has daily new cases rather than cumulative cases, and has precomputed the seven-day trailing average of the data sequences.

The code is written in the [Julia programming language](https://julialang.org/) and organized in [Pluto.jl notebooks](https://github.com/fonsp/Pluto.jl).

Instructions:

1. You'll need a working installation of Julia with the Pluto.jl package installed. Version 0.15.1 or later is needed to automatically find, load, and install packages.

2. In a terminal window, cd to the directory where you have stored this file. Start Julia, then at the "julia>" prompt, type "using Pluto; Pluto.run('SIRmodel.jl')".

3. A browser window will open with this notebook displayed. Pluto will then download all the necessary packages and their dependencies, and will evaluate the cells in the proper order. This can take several minutes, and it can rev up your CPU fan. But then you're done.

"""

# ╔═╡ 035ad037-d231-4a7b-a451-213085be2eb4
# Figure 10

# Plot exponential growth of R^t for various values of R

exp_log_plot =
begin
	xs = 0:0.05:20
	plot(xs,
		[[0.8^x for x in xs],
		 [1.0^x for x in xs],
		 [1.25^x for x in xs],
		 [2.0^x for x in xs],
		 [3.0^x for x in xs]],
		ylims = [0.01, 1e10],
		yscale = :log10,
		yticks = [0.01, 1.0, 1e2, 1e4, 1e6, 1e8, 1e10],
		linewidth = 2.0,
		xlabel = "serial passage times",
		ylabel = "number of new cases",
		fontfamily = "helvetica",
		legend = false)
end

# ╔═╡ 243d8dbd-0f8f-4604-bdb9-9c9078e906be
md"""
#### SIR Models

This is a home-brewed discrete-time implementation of a SIR (susceptible-infective-recovered) model of epidemic dynamics. There are lots and lots of other implementations out there, mostly based on continuous-time differential equations.

Just within the Julia world, Simon Frost has written or collected more than two dozen versions at [https://github.com/epirecipes/sir-julia](https://github.com/epirecipes/sir-julia). And Roberto Alain Berwa has an implementation tuned specifically for Covid-19 at [https://nextjournal.com/berwa/sir-model-for-covid-19-estimating-R_o](https://nextjournal.com/berwa/sir-model-for-covid-19-estimating-R_o).
"""

# ╔═╡ 7fa5fed0-63a9-4332-a808-95e2b7bcf09d
# The basic model

# The population variables ss, ii, and rr are all floats in the interval
# [0, 1], with the condition that ss + ii + rr == 1.0 at all times. The
# initial infective density i0 is also a float in this range. β and γ are
# the infection and recovery constants. tmax is the total time span of the
# simulation measured in multiples of the serial passage time--the average
# time between acquiring an infection and infecting someone else. dt is the
# simulation time step; we start at tt = 0 and increment by dt until we
# reach tmax.

function sir(i0, β, γ, dt, tmax)
	steps = floor(Int, tmax / dt)

	times = zeros(steps)
	susceptibles = zeros(steps)
	infectives = zeros(steps)
	recovereds = zeros(steps)

	tt = 0.0        # time variable, in steps of dt
	ss = 1.0 - i0   # susceptible population as a function of tt
	ii = i0         # infective population as a function of tt
	rr = 0.0        # recovered population as a function of tt

	for count in 1:steps  # loop tmax/dt times

		times[count] = tt          # record current values in four vectors
		susceptibles[count] = ss
		infectives[count] = ii
		recovereds[count] = rr

		new_infections = dt * β * ss * ii  # calc infections and recoveries
		recoveries = dt * γ * ii

		ss = ss - new_infections              # update population numbers
		ii = ii + new_infections - recoveries
		rr = rr + recoveries
		tt = tt + dt                          # increment time
	end
	return (times, [susceptibles, infectives, recovereds])
end

# ╔═╡ b1f928d8-7175-4bd3-9adc-9cb93b0dbb40
# Figure 11 -- output of the basic SIR model

sir_graph =
plot(sir(0.000001, 0.6, 0.2, 0.1, 100),
	linecolor = [:green "#4100eb" "#dd4411"],
	linewidth = [2.0 3.5 2.0],
	label = false,
	annotationfontsize = 10,
	annotationhalign = :left,
	annotations = [(9, 0.90, "susceptibles"),
				   (44, 0.65, "recovereds"),
				   (45, 0.20, "infectives")],
	xticks = 0:20:100,
	yticks = 0.0:0.20:1.0,
	xlabel = "serial passage times",
	ylabel = "proportion of population"
	)

# ╔═╡ ad7091a0-399f-49ee-b273-4976ecb1b75e
# savefig(sir_graph, "SIR_model.svg")

# ╔═╡ 13abedaa-7df4-48c6-8d61-d81c8d585be8
# "SIR with fear" -- exploring feedback as a source of oscillatory
#  behavior in epidemic dynamics.

# We add two features to the basic SIR model. Negative feedback suppresses
# all new infections whenever the infection rate rises above a threshold. But
# the feedback may take effect only after a delay.

function sirf(i0, β, γ, threshold, delay, dt, tmax)
	steps = floor(Int, tmax / dt)

	times = zeros(steps)
	susceptibles = zeros(steps)
	infectives = zeros(steps)
	recovereds = zeros(steps)
	thresholds = fill(threshold, steps)

	tt = 0.0
	ss = 1.0 - i0
	ii = i0
	rr = 0.0
	ϕ  = 1.0

	for count in 1:steps

		times[count] = tt
		susceptibles[count] = ss
		infectives[count] = ii
		recovereds[count] = rr

		if count <= delay
			ϕ = 1.0
		else
			ϕ = infectives[count - delay] < threshold ? 1.0 : 0.0
		end

		new_infections = dt * β * ϕ * ss * ii
		recoveries = dt * γ * ii
		ss = ss - new_infections
		ii = ii + new_infections - recoveries
		rr = rr + recoveries
		tt = tt + dt
	end
	return (times, [susceptibles, infectives, recovereds, thresholds])
end

# ╔═╡ ef8592b6-7474-410c-9171-187893239151
sirf_result_no_delay = sirf(0.000001, 0.6, 0.2, 0.05, 0, 0.1, 100)

# ╔═╡ e3a0e0c3-1a96-4a9d-bbe3-a25061b1ee12
# Figure 13 -- SIR with feedback but no delay. Oscillations are too
# small in period and amplitude to be perceived.

sirf_graph_no_delay =
plot(sirf_result_no_delay,
	linecolor = [:green "#4100eb" "#dd4411" :black],
	linewidth = [2.0 2.5 2.0 0.75],
	linestyle = [:solid :solid :solid :dash],
	label = false,
	annotationfontsize = 10,
	annotationhalign = :left,
	annotations = [(33, 0.90, "susceptibles"),
				   (75, 0.69, "recovereds"),
				   (53, 0.09, "infectives"),
				   (3,  0.08, "threshold")],
	xticks = 0:20:100,
	yticks = 0.0:0.20:1.0,
	xlabel = "serial passage times",
	ylabel = "proportion of population"
	)

# ╔═╡ 228a6067-bddf-4e6e-b3d8-2a6ac47d3904
savefig(sirf_graph_no_delay, "SIR_model_with_feedback.svg")

# ╔═╡ 08be5eef-4bdc-4ee6-8e5e-507c8055c07e
sirf_result = sirf(0.000001, 0.6, 0.2, 0.05, 30, 0.1, 100)

# ╔═╡ 890fe7ce-d6cd-49c2-b888-421971118d8d
# Figure 14 -- SIR model with both feedback and delay.

sirf_graph =
plot(sirf_result,
	linecolor = [:green "#4100eb" "#dd4411" :black],
	linewidth = [2.0 2.5 2.0 0.75],
	linestyle = [:solid :solid :solid :dash],
	label = false,
	annotationfontsize = 10,
	annotationhalign = :left,
	annotations = [(30, 0.90, "susceptibles"),
				   (75, 0.69, "recovereds"),
				   (45, 0.12, "infectives"),
				   (3,  0.08, "threshold")],
	xticks = 0:20:100,
	yticks = 0.0:0.20:1.0,
	xlabel = "serial passage times",
	ylabel = "proportion of population"
	)

# ╔═╡ 7ba339f1-b03e-49d7-9821-bd731ffe664d
# savefig(sirf_graph, "SIR_model_with_oscillations.svg")

# ╔═╡ e8657ff4-4c7f-401c-a3e7-5098a90d99e5
# The basic SIR model uses exponential decay as well as exponential growth.
# Calculate the exponential falloff in infective numbers after new infections
# cease.

function decline(n, γ, reps)
	vec = [n]
	for i in 1:reps
		n -= n * γ
		push!(vec, n)
	end
	vec
end

# ╔═╡ 798a62d7-700b-400e-9bc9-efbe0b7758bc
# Figure 16

exponential_decline_bargraph =
plot(decline(1.0, 0.2, 10),
	seriestype = :bar,
	xticks = (1.0:1.0:11.0, 0:1:10),
	yticks = (0:0.2:1.0),
	size = [350, 200],
	fontfamily = "helvetica",
	guidefontsize = 10,
	fillcolor = "#4100eb",
	xlabel = "serial passage times",
	ylabel = "fraction remaining",
	legend = false
)

# ╔═╡ cb4c6cbb-5e44-49da-b82f-3551a1b3abbf
# savefig(exponential_decline_bargraph, "exponential_decline_bargraph.svg")

# ╔═╡ 235956e8-e4d6-49bc-b175-d7c2aed732a8
# Instead of exponential decay in infective numbers, we assign
# the infectious period a fixed duration. At each time step the
# newly recruited infectives enter a queue of length q, and
# progress through it at one place per time step. After q steps
# they reach the head of the q and are transformed into recovereds.

function sirq(i0, β, q, dt, tmax)
	steps = floor(Int, tmax / dt)

	times = zeros(steps)
	susceptibles = zeros(steps)
	infectives = zeros(steps)
	recovereds = zeros(steps)
	Q = zeros(Int(ceil(q / dt)))

	tt = 0
	ss = 1 - i0
	ii = i0
	rr = 0

	for count in 1:steps

		times[count] = tt
		susceptibles[count] = ss
		infectives[count] = ii
		recovereds[count] = rr

		new_infections = dt * β * ss * ii
		recoveries = pop!(Q)
		ss = ss - new_infections
		ii = ii + new_infections - recoveries
		rr = rr + recoveries
		tt = tt + dt
		pushfirst!(Q, new_infections)
	end
	return (times, [susceptibles, infectives, recovereds])
end

# ╔═╡ 3e2cd644-1f53-4f51-891b-c54ae816f557
# Figure 17 -- SIR model with infectious period equal to 3 serial
# passage times.

sirq_graph_3p0 =
plot(sirq(0.000001, 0.6, 3.0, 0.1, 100),
	linecolor = [:green "#4100eb" "#dd4411"],
	linewidth = [2.0 3.5 2.0],
	label = false,
	fontfamily = "helvetica",
	annotationfontsize = 10,
	annotationhalign = :left,
	annotations = [(0, 0.97, "susceptibles"),
				   (60, 0.79, "recovereds"),
				   (12, 0.18, "infectives"),
				   (75, 0.97, "duration = 3.0 TSP")],
	xticks = 0:20:100,
	yticks = 0.0:0.20:1.0,
	xlabel = "serial passage times",
	ylabel = "proportion of population"
	)

# ╔═╡ 7cc0d1e9-3cab-48cc-b873-181e006a620e
# savefig(sirq_graph_3p0, "sirq_0p000001_0p6_3p0_0p1_100.svg")

# ╔═╡ 462e8b4d-5bf1-4153-b9d5-46b74f308721
# Figure 18 -- SIR model with infectious period equal to 2 serial
# passage times.

sirq_graph_2p0 =
plot(sirq(0.000001, 0.6, 2.0, 0.1, 100),
	linecolor = [:green "#4100eb" "#dd4411"],
	linewidth = [2.0 3.5 2.0],
	label = false,
	fontfamily = "helvetica",
	annotationfontsize = 10,
	annotationhalign = :left,
	annotations = [(0, 0.97, "susceptibles"),
				   (85, 0.35, "recovereds"),
				   (62, 0.05, "infectives"),
				   (75, 0.97, "duration = 2.0 SPT")],
	xticks = 0:20:100,
	yticks = 0.0:0.20:1.0,
	xlabel = "serial passage times",
	ylabel = "proportion of population"
	)

# ╔═╡ bff6a040-8d4a-4f00-a4e9-9f8147a21b41
# savefig(sirq_graph_2p0, "sirq_0p000001_0p6_2p0_0p1_100.svg")

# ╔═╡ f24f1556-cf68-4f54-bb35-7ac9b01d0a85
# SIR model with vaccination

function sirv(i0, β, γ, v, v_date, dt, tmax)
	steps = floor(Int, tmax / dt)

	times = zeros(steps)
	susceptibles = zeros(steps)
	infectives = zeros(steps)
	recovereds = zeros(steps)
	vaccinateds = zeros(steps)

	tt = 0
	ss = 1 - i0
	ii = i0
	rr = 0
	vv = 0

	for count in 1:steps

		times[count] = tt
		susceptibles[count] = ss
		infectives[count] = ii
		recovereds[count] = rr
		vaccinateds[count] = vv

		new_infections = dt * β * ss * ii
		recoveries = dt * γ * ii
		new_vaccinations = (vv == 0 && tt > v_date) ? v : 0

		vv = vv + new_vaccinations
		ss = ss - new_infections - new_vaccinations
		ii = ii + new_infections - recoveries
		rr = rr + recoveries
		tt = tt + dt
	end
	return (times, [susceptibles, infectives, recovereds, vaccinateds])
end

# ╔═╡ 4ae90a2a-67f1-4dc9-b6ed-d2e2e85aadd7
# Figure 23

sirv_graph_0p6_0p2_0p5_0 =
plot(sirv(0.000001, 0.6, 0.2, 0.5, 0, 0.1, 100),
	linecolor = [:green "#4100eb" "#dd4411" :orange],
	linewidth = [3.5 3.5 2.0 2.0],
	# label = false,
	label = ["susceptibles" "infectives" "recovereds" "vaccinateds"],
	annotationfontsize = 10,
	annotationhalign = :left,
	# annotations = [(3, 0.96, "susceptibles"),
				   # (62, 0.61, "recovereds"),
				   # (17, 0.18, "infectives"),
				   # (62, 0.37, "vaccinateds")],
	xticks = 0:20:100,
	yticks = 0.0:0.20:1.0,
	xlabel = "serial passage times",
	ylabel = "proportion of population"
	)

# ╔═╡ 09f9e4c9-315f-4433-b021-08150d6ce413
# savefig(sirv_graph_0p6_0p2_0p5_0, "sirv_graph_0p6_0p2_0p5_0.svg")

# ╔═╡ f0e6437c-609e-48f9-abc8-f3d325f35ec3
# Figure 24

sirv_graph_0p6_0p1_0p5_0 =
plot(sirv(0.000001, 0.6, 0.1, 0.5, 0, 0.1, 100),
	linecolor = [:green "#4100eb" "#dd4411" :orange],
	linewidth = [3.5 3.5 2.0 2.0],
	# label = false,
	label = ["susceptibles" "infectives" "recovereds" "vaccinateds"],
	annotationfontsize = 10,
	annotationhalign = :left,
	# annotations = [(3, 0.96, "susceptibles"),
				   # (62, 0.61, "recovereds"),
				   # (17, 0.18, "infectives"),
				   # (62, 0.37, "vaccinateds")],
	xticks = 0:20:100,
	yticks = 0.0:0.20:1.0,
	xlabel = "serial passage times",
	ylabel = "proportion of population"
	)

# ╔═╡ cb0c1428-5146-4402-93ef-27c3cd4fd9d4
# savefig(sirv_graph_0p6_0p1_0p5_0, "sirv_graph_0p6_0p1_0p5_0.svg")

# ╔═╡ 3438d796-9efc-44d0-9c08-a6c90305dee0
md"""
#### Random mini-epidemics

The last topic to be taken up here is the possibility that the observed profile of the Covid incidence curve might be the result of summing many small, randomly timed mini-epidemics.
"""

# ╔═╡ e8139300-8097-4ba0-96e3-5135047c70d7
# Generate a standard SIR curve with a specified starting time
# 0 ≤ tstart ≤ tmax.

function asynchSIR(i0, β, γ, dt, tmax, tstart)
	steps = floor(Int, tmax / dt)

	times = zeros(steps)
	susceptibles = zeros(steps)
	infectives = zeros(steps)
	recovereds = zeros(steps)

	tt = 0.0
	ss = 1.0 - i0
	ii = i0
	rr = 0.0

	for count in 1:steps

		times[count] = tt
		tt += dt

		if tt >= tstart
			susceptibles[count] = ss
			infectives[count] = ii
			recovereds[count] = rr

			new_infections = dt * β * ss * ii
			recoveries = dt * γ * ii
			ss = ss - new_infections
			ii = ii + new_infections - recoveries
			rr = rr + recoveries
		end
	end
	return infectives
end

# ╔═╡ 8103f855-a617-438b-8cb9-8fa0e7fde319
# Generate N SIR curves with start times chosen uniformly at
# random from the interval 0 ≤ tstart ≤ 0.8 * tmax. The parameter
# β is also allowed to vary around the specied value by an amount
# drawn from a normal distribution with mean 0 and sdev 0.1.

function multiSIR(N, i0, β, γ, dt, tmax)
	steps = floor(Int, tmax / dt)
	curves = zeros(steps, N)
	times = collect(0.0:dt:tmax-dt)

	for i in 1:N
		tstart = rand() * (0.8 * tmax)
		rand_β = β + (randn() * 0.1)
		this_curve = asynchSIR(i0, rand_β, γ, dt, tmax, tstart)
		curves[1:end, i] .= this_curve
	end

	sumcurve = zeros(steps)
	for j in 1:steps
		sumcurve[j] = sum(curves[j, 1:end])
	end

	scale_factor = 1 / maximum(sumcurve)
	sumcurve .= sumcurve * scale_factor
	curves .= curves * scale_factor

	return ((times, curves), (times, sumcurve))
end

# ╔═╡ 3fdd5a77-45df-494e-9786-c8aa22daa82e
# Figure 19 -- Draw N randomly timed SIR curves and their sum curve.
# The published figure shows results with N = 6 and N = 50. Because of
# the randomness involved, rerunning this procedure will not replicate
# the published figure, but the character of the result should be
# the same.

asynch_sir_graph =
begin
	the_curves = multiSIR(20, 0.001, 0.6, 0.2, 0.1, 100)
	plot(the_curves[1],
		linecolor = ["#dd4411"],
		linewidth = 1.0,
		label = false,
		xticks = 0:20:100,
		yticks = 0.0:0.20:1.0,
		xlabel = "serial passage times",
		ylabel = "proportion of population")
	plot!(the_curves[2],
		linecolor = ["#4100eb"],
		linewidth = 3.0,
		label = false,
		legend = false)
end

# ╔═╡ 341c32a3-3fae-472b-8771-c7f9fbaf4704
# savefig(asynch_sir_graph, "miltiSIR_12.svg")

# ╔═╡ 0bb71f07-9381-4e77-9fe3-1c59854d18f5
# Figure 20. -- Generate multiSIR plots, without scales, but
# with a label indicating the number of component curves.

function multiSIRplot(N, i0, β, γ, dt, tmax, filename_prefix)
	results = multiSIR(N, i0, β, γ, dt, tmax)
	filename = filename_prefix * "_" * "$N" *".svg"

	p =	plot(results[1],
			linecolor = ["#dd4411"],
			linewidth = 1.0,
			label = false,
			framestyle = :box,
			annotationfontsize = 10,
			annotationhalign = :left,
			annotations = (0.0, 0.90, "N = $N"),
			xticks = false,
			yticks = false)
			# xticks = 0:20:100,
			# yticks = 0.0:0.20:1.0,
			# xlabel = "serial passage times",
			# ylabel = "proportion of population")
	plot!(p, results[2],
			linecolor = ["#4100eb"],
			linewidth = 3.0,
			label = false,
			legend = false)
	savefig(p, filename)
	return p
end

# ╔═╡ 20fd7570-5c1f-4316-87f3-b972a1a0364f
multiSIRplot(12, 0.001, 0.6, 0.2, 0.1, 100, "multiSIRplot")

# ╔═╡ 8bfed4f2-724c-44ea-b6f4-02c836391be7
# Figure 20 -- create a tableau of multiple multiSIR graphs.

multiSIR_tableau =
[multiSIRplot(N, 0.001, 0.6, 0.2, 0.1, 100, "multiSIR_tableau_A") for N in [3, 4, 5, 6, 8, 10, 15, 20, 30, 40, 50, 60, 100]]

# ╔═╡ 64460f92-6dd3-4c13-b3b9-bb2660436b40
# for i in 1:length(multiSIR_tableau)
# 	savefig(multiSIR_tableau[i], "multiSIR_tableau_A_$i.svg")
# end

# ╔═╡ 7b8a3922-21a9-4905-84ad-e2d8edf51cce
# Written to gather some statistics on the number of peaks and
# troughs in a curve representing the sum of N mini-epidemics.

function count_peaks_and_troughs(curve)
	deriv = diff(curve)
	crossings = map(sign, deriv)
	peaks = 0
	troughs = 0
	i = 1
	while crossings[i] == 0
		i += 1
	end
	previous = crossings[i]
	for j in i+1:length(crossings)
		if crossings[j] == -previous
			if crossings[j] < 0
				peaks += 1
			else
				troughs += 1
			end
			previous = -previous
		end
	end
	return (peaks, troughs)
end

# ╔═╡ bbf05eef-188d-4e31-ae40-f85a8269a3b6

function collect_peak_counts(N, reps)
	counts = zeros(Int, 20)
	for i in 1:reps
		multiSIRrecord = multiSIR(N, 0.001, 0.6, 0.2, 0.1, 100)
		peaks, troughs = count_peaks_and_troughs(multiSIRrecord[2][2])
		counts[peaks+1] += 1
	end
	return counts
end

# ╔═╡ 16e5e214-d5b7-480e-8243-9cbf36ababf8
peak_data = [collect_peak_counts(n, 1000) for n in [4, 5, 6, 8, 10, 15, 30, 50, 100]]

# ╔═╡ e252ca21-48d3-49f4-9bee-649a5610240a
# Figure 21

peak_data_plot =
plot(peak_data,
	seriestype = :bar,
	layout = (9, 1),
	size = (400, 600),
	fillcolor = "#4100eb",
	framestyle = :grid,
	xlims = [1, 12],
	# xticks = (1:1:12, ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11"]),
	xticks = false,
	legend = false,
	yticks = false)

# ╔═╡ 933d49c9-31fc-4d02-9b83-d523bf828476
# savefig(peak_data_plot, "peak_numbers_bar_graph.svg")

# ╔═╡ 00000000-0000-0000-0000-000000000001
PLUTO_PROJECT_TOML_CONTENTS = """
[deps]
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
StatsPlots = "f3b207a7-027a-5e70-b257-86293d7955fd"

[compat]
StatsPlots = "~0.14.26"
"""

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

[[AbstractFFTs]]
deps = ["LinearAlgebra"]
git-tree-sha1 = "485ee0867925449198280d4af84bdb46a2a404d0"
uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c"
version = "1.0.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"

[[Arpack]]
deps = ["Arpack_jll", "Libdl", "LinearAlgebra"]
git-tree-sha1 = "2ff92b71ba1747c5fdd541f8fc87736d82f40ec9"
uuid = "7d9fca2a-8960-54d3-9f78-7d1dccf2cb97"
version = "0.4.0"

[[Arpack_jll]]
deps = ["Libdl", "OpenBLAS_jll", "Pkg"]
git-tree-sha1 = "e214a9b9bd1b4e1b4f15b22c0994862b66af7ff7"
uuid = "68821587-b530-5797-8361-c406ea357684"
version = "3.5.0+3"

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

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

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

[[Bzip2_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "c3598e525718abcc440f69cc6d5f60dda0a1b61e"
uuid = "6e34b625-4abd-537c-b88f-471c36dfa7a0"
version = "1.0.6+5"

[[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 = "e2f47f6d8337369411569fd45ae5753ca10394c6"
uuid = "83423d85-b0ee-5818-9007-b63ccbeb887a"
version = "1.16.0+6"

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

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

[[ColorSchemes]]
deps = ["ColorTypes", "Colors", "FixedPointNumbers", "Random", "StaticArrays"]
git-tree-sha1 = "ed268efe58512df8c7e224d2e170afd76dd6a417"
uuid = "35d6a980-a343-548e-a6ea-1d62b119f2f4"
version = "3.13.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 = "344f143fa0ec67e47917848795ab19c6a455f32c"
uuid = "34da2185-b29b-5c13-b0c7-acf172513d20"
version = "3.32.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 = "ee400abb2298bd13bfc3df1c412ed228061a2385"
uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a"
version = "1.7.0"

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

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

[[DataValues]]
deps = ["DataValueInterfaces", "Dates"]
git-tree-sha1 = "d88a19299eba280a6d062e135a43f00323ae70bf"
uuid = "e7dc6d0d-1eca-5fa6-8ad6-5aecde8b7ea5"
version = "0.4.13"

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

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

[[Distances]]
deps = ["LinearAlgebra", "Statistics", "StatsAPI"]
git-tree-sha1 = "abe4ad222b26af3337262b8afb28fab8d215e9f8"
uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7"
version = "0.10.3"

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

[[Distributions]]
deps = ["FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SparseArrays", "SpecialFunctions", "Statistics", "StatsBase", "StatsFuns"]
git-tree-sha1 = "3889f646423ce91dd1055a76317e9a1d3a23fff1"
uuid = "31c24e10-a181-5473-b8eb-7969acd0382f"
version = "0.25.11"

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

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

[[EarCut_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "92d8f9f208637e8d2d28c664051a00569c01493d"
uuid = "5ae413db-bbd1-5e63-b57d-d24a61df00f5"
version = "2.1.5+1"

[[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", "LibVPX_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 = "3cc57ad0a213808473eafef4845a74766242e05f"
uuid = "b22a6f82-2f65-5046-a5b2-351ab43fb4e5"
version = "4.3.1+4"

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

[[FFTW_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "3676abafff7e4ff07bbd2c42b3d8201f31653dcc"
uuid = "f5851436-0d7a-5f13-b9de-f02708fd171a"
version = "3.3.9+8"

[[FillArrays]]
deps = ["LinearAlgebra", "Random", "SparseArrays", "Statistics"]
git-tree-sha1 = "8c8eac2af06ce35973c3eadb4ab3243076a408e7"
uuid = "1a297f60-69ca-5386-bcde-b61e274b549b"
version = "0.12.1"

[[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 = "35895cf184ceaab11fd778b4590144034a167a2f"
uuid = "a3f928ae-7b40-5064-980b-68af3947d34b"
version = "2.13.1+14"

[[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 = "cbd58c9deb1d304f5a245a0b7eb841a2560cfec6"
uuid = "d7e528f0-a631-5988-bf34-fe36492bcfd7"
version = "2.10.1+5"

[[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 = "dba1e8614e98949abfa60480b13653813d8f0157"
uuid = "0656b61e-2033-5cc2-a64a-77c0f6c09b89"
version = "3.3.5+0"

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

[[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 = "eaf96e05a880f3db5ded5a5a8a7817ecba3c7392"
uuid = "d2c73de3-f751-5644-a686-071e5b155ba9"
version = "0.58.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"

[[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 = "c6a1fff2fd4b1da29d3dccaffb1e1001244d844e"
uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3"
version = "0.9.12"

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

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

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

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

[[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 = "81690084b6198a2e1da36fcfda16eeca9f9f24e4"
uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
version = "0.21.1"

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

[[KernelDensity]]
deps = ["Distributions", "DocStringExtensions", "FFTW", "Interpolations", "StatsBase"]
git-tree-sha1 = "591e8dc09ad18386189610acafb970032c519707"
uuid = "5ab0869b-81aa-558d-bb23-cbf5423bbe9b"
version = "0.6.3"

[[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 = "c7f1c695e06c01b95a67f0cd1d34994f3e7db104"
uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f"
version = "1.2.1"

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

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

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

[[LibVPX_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "12ee7e23fa4d18361e7c2cde8f8337d4c3101bc7"
uuid = "dd192d2f-8180-539f-9fb4-cc70b1dcf69a"
version = "1.10.0+0"

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

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

[[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 = ["DocStringExtensions", "LinearAlgebra"]
git-tree-sha1 = "7bd5f6565d80b6bf753738d2bc40a5dfea072070"
uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688"
version = "0.2.5"

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

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

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

[[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 = "4ea90bd5d3985ae1f9a908bd4500ae88921c5ce7"
uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28"
version = "1.0.0"

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

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

[[MultivariateStats]]
deps = ["Arpack", "LinearAlgebra", "SparseArrays", "Statistics", "StatsBase"]
git-tree-sha1 = "8d958ff1854b166003238fe191ec34b9d592860a"
uuid = "6f286f6a-111f-5878-ab1e-185364afe411"
version = "0.8.0"

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

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

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

[[Observables]]
git-tree-sha1 = "fe29afdef3d0c4a8286128d4e45cc50621b1e43d"
uuid = "510215fc-4207-5dde-b226-833fc4488ee2"
version = "0.4.0"

[[OffsetArrays]]
deps = ["Adapt"]
git-tree-sha1 = "4f825c6da64aebaa22cc058ecfceed1ab9af1c7e"
uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881"
version = "1.10.3"

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

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

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

[[OpenSpecFun_jll]]
deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "13652491f6856acfd2db29360e1bbcd4565d04f1"
uuid = "efe28fd5-8261-553b-a9e1-b2916fc3738e"
version = "0.5.5+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"

[[PDMats]]
deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse"]
git-tree-sha1 = "4dd403333bcf0909341cfe57ec115152f937d7d8"
uuid = "90014a1f-27ba-587c-ab20-58faa44d9150"
version = "0.11.1"

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

[[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 = "501c20a63a34ac1d015d5304da0e645f42d91c9f"
uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043"
version = "1.0.11"

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

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

[[QuadGK]]
deps = ["DataStructures", "LinearAlgebra"]
git-tree-sha1 = "12fbe86da16df6679be7521dfb39fbc861e1dc7b"
uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc"
version = "2.4.1"

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

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

[[Ratios]]
git-tree-sha1 = "37d210f612d70f3f7d57d488cb3b6eff56ad4e41"
uuid = "c84ed2f1-dad5-54f0-aa8e-dbefe2724439"
version = "0.4.0"

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

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

[[Reexport]]
git-tree-sha1 = "5f6c21241f0f655da3952fd60aa18477cf96c220"
uuid = "189a3867-3050-52da-a836-e630ba90ab69"
version = "1.1.0"

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

[[Rmath]]
deps = ["Random", "Rmath_jll"]
git-tree-sha1 = "bf3188feca147ce108c76ad82c2792c57abe7b1f"
uuid = "79098fc4-a85e-5d69-aa6a-4863f24498fa"
version = "0.7.0"

[[Rmath_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "68db32dff12bb6127bac73c209881191bf0efbb7"
uuid = "f50d1b31-88e8-58de-be2c-1cc44531875f"
version = "0.3.0+0"

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

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

[[SentinelArrays]]
deps = ["Dates", "Random"]
git-tree-sha1 = "35927c2c11da0a86bcd482464b93dadd09ce420f"
uuid = "91c51154-3ec4-41a3-a24f-3f23e20d615c"
version = "1.3.5"

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

[[SpecialFunctions]]
deps = ["ChainRulesCore", "LogExpFunctions", "OpenSpecFun_jll"]
git-tree-sha1 = "508822dca004bf62e210609148511ad03ce8f1d8"
uuid = "276daf66-3868-5448-9aa4-cd146d93841b"
version = "1.6.0"

[[StaticArrays]]
deps = ["LinearAlgebra", "Random", "Statistics"]
git-tree-sha1 = "885838778bb6f0136f8317757d7803e0d81201e4"
uuid = "90137ffa-7385-5640-81b9-e52037218182"
version = "1.2.9"

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

[[StatsAPI]]
git-tree-sha1 = "1958272568dc176a1d881acb797beb909c785510"
uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0"
version = "1.0.0"

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

[[StatsFuns]]
deps = ["LogExpFunctions", "Rmath", "SpecialFunctions"]
git-tree-sha1 = "30cd8c360c54081f806b1ee14d2eecbef3c04c49"
uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c"
version = "0.9.8"

[[StatsPlots]]
deps = ["Clustering", "DataStructures", "DataValues", "Distributions", "Interpolations", "KernelDensity", "LinearAlgebra", "MultivariateStats", "Observables", "Plots", "RecipesBase", "RecipesPipeline", "Reexport", "StatsBase", "TableOperations", "Tables", "Widgets"]
git-tree-sha1 = "e7d1e79232310bd654c7cef46465c537562af4fe"
uuid = "f3b207a7-027a-5e70-b257-86293d7955fd"
version = "0.14.26"

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

[[SuiteSparse]]
deps = ["Libdl", "LinearAlgebra", "Serialization", "SparseArrays"]
uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9"

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

[[TableOperations]]
deps = ["SentinelArrays", "Tables", "Test"]
git-tree-sha1 = "a7cf690d0ac3f5b53dd09b5d613540b230233647"
uuid = "ab02a1b2-a7df-11e8-156e-fb1833f50b87"
version = "1.0.0"

[[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 = "8ed4a3ea724dac32670b062be3ef1c1de6773ae8"
uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c"
version = "1.4.4"

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

[[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", "Wayland_jll"]
git-tree-sha1 = "2839f1c1296940218e35df0bbb220f2a79686670"
uuid = "2381bf8a-dfd0-557d-9999-79630e7b1b91"
version = "1.18.0+4"

[[Widgets]]
deps = ["Colors", "Dates", "Observables", "OrderedCollections"]
git-tree-sha1 = "eae2fbbc34a79ffd57fb4c972b08ce50b8f6a00d"
uuid = "cc8bc4a8-27d6-5769-a93b-9d913e69aa62"
version = "0.6.3"

[[WoodburyMatrices]]
deps = ["LinearAlgebra", "SparseArrays"]
git-tree-sha1 = "59e2ad8fd1591ea019a5259bd012d7aee15f995c"
uuid = "efce3f68-66dc-5838-9240-27a6d6f5f9b6"
version = "0.5.3"

[[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", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"]
git-tree-sha1 = "acc685bcf777b2202a904cdcb49ad34c2fa1880c"
uuid = "0ac62f75-1d6f-5e53-bd7c-93b484bb37c0"
version = "0.14.0+4"

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

[[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 = "d713c1ce4deac133e3334ee12f4adff07f81778f"
uuid = "1270edf5-f2f9-52d2-97e9-ab00b5d0237a"
version = "2020.7.14+2"

[[x265_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"]
git-tree-sha1 = "487da2f8f2f0c8ee0e83f39d13037d6bbf0a45ab"
uuid = "dfaa095f-4041-5dcd-9319-2fabd8486b76"
version = "3.0.0+3"

[[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:
# ╠═50cd5676-cdba-425d-84d3-7ad6fe21a2d5
# ╠═8ae7bb38-5803-41d0-98e3-6d9dc4936406
# ╠═03eb200d-c3b4-43d6-b86f-017f5454bc86
# ╠═035ad037-d231-4a7b-a451-213085be2eb4
# ╟─243d8dbd-0f8f-4604-bdb9-9c9078e906be
# ╠═7fa5fed0-63a9-4332-a808-95e2b7bcf09d
# ╠═b1f928d8-7175-4bd3-9adc-9cb93b0dbb40
# ╠═ad7091a0-399f-49ee-b273-4976ecb1b75e
# ╠═13abedaa-7df4-48c6-8d61-d81c8d585be8
# ╠═ef8592b6-7474-410c-9171-187893239151
# ╠═e3a0e0c3-1a96-4a9d-bbe3-a25061b1ee12
# ╠═228a6067-bddf-4e6e-b3d8-2a6ac47d3904
# ╠═08be5eef-4bdc-4ee6-8e5e-507c8055c07e
# ╠═890fe7ce-d6cd-49c2-b888-421971118d8d
# ╠═7ba339f1-b03e-49d7-9821-bd731ffe664d
# ╠═e8657ff4-4c7f-401c-a3e7-5098a90d99e5
# ╠═798a62d7-700b-400e-9bc9-efbe0b7758bc
# ╠═cb4c6cbb-5e44-49da-b82f-3551a1b3abbf
# ╠═235956e8-e4d6-49bc-b175-d7c2aed732a8
# ╠═3e2cd644-1f53-4f51-891b-c54ae816f557
# ╠═7cc0d1e9-3cab-48cc-b873-181e006a620e
# ╠═462e8b4d-5bf1-4153-b9d5-46b74f308721
# ╠═bff6a040-8d4a-4f00-a4e9-9f8147a21b41
# ╠═f24f1556-cf68-4f54-bb35-7ac9b01d0a85
# ╠═4ae90a2a-67f1-4dc9-b6ed-d2e2e85aadd7
# ╠═09f9e4c9-315f-4433-b021-08150d6ce413
# ╠═f0e6437c-609e-48f9-abc8-f3d325f35ec3
# ╠═cb0c1428-5146-4402-93ef-27c3cd4fd9d4
# ╟─3438d796-9efc-44d0-9c08-a6c90305dee0
# ╠═e8139300-8097-4ba0-96e3-5135047c70d7
# ╠═8103f855-a617-438b-8cb9-8fa0e7fde319
# ╠═3fdd5a77-45df-494e-9786-c8aa22daa82e
# ╠═341c32a3-3fae-472b-8771-c7f9fbaf4704
# ╠═20fd7570-5c1f-4316-87f3-b972a1a0364f
# ╠═0bb71f07-9381-4e77-9fe3-1c59854d18f5
# ╠═8bfed4f2-724c-44ea-b6f4-02c836391be7
# ╠═64460f92-6dd3-4c13-b3b9-bb2660436b40
# ╠═7b8a3922-21a9-4905-84ad-e2d8edf51cce
# ╠═bbf05eef-188d-4e31-ae40-f85a8269a3b6
# ╠═16e5e214-d5b7-480e-8243-9cbf36ababf8
# ╠═e252ca21-48d3-49f4-9bee-649a5610240a
# ╠═933d49c9-31fc-4d02-9b83-d523bf828476
# ╟─00000000-0000-0000-0000-000000000001
# ╟─00000000-0000-0000-0000-000000000002

max_stars_repo_name: bit-player/Covidcurve

max_issues_repo_name: bit-player/Covidcurve

max_forks_repo_name: bit-player/Covidcurve


text:
"""
    eom_ar1(x, p, n) -> Function

Equations of motion for a bivariate, order one autoregressive model, where
x -> y [1].

## Equations of motion

```math
\\begin{aligned}
dx &= a_1 x + \\xi_{1} \\\\
dy &= b_1 y - c_{xy} x + \\xi_{2},
\\end{aligned}
```

where ``\\xi_{1}`` and ``\\xi_{2}`` are drawn from normal distributions
with zero mean and standard deviation `σ` at each iteration.

## References

1. Paluš, M., Krakovská, A., Jakubík, J., & Chvosteková, M. (2018). Causality,
    dynamical systems and the arrow of time. Chaos: An Interdisciplinary Journal of
    Nonlinear Science, 28(7), 075307. http://doi.org/10.1063/1.5019944
"""
function eom_ar1_unidir(x, p, n)
    a₁, b₁, c_xy, σ = (p...,)
    x, y = (x...,)
    ξ₁ = rand(Normal(0, σ))
    ξ₂ = rand(Normal(0, σ))

    dx = a₁*x + ξ₁
    dy = b₁*y + c_xy*x + ξ₂
    return SVector{2}(dx, dy)
end

function ar1_unidir(uᵢ, a₁, b₁, c_xy, σ)
    p = [a₁, b₁, c_xy, σ]
    DiscreteDynamicalSystem(eom_ar1_unidir, uᵢ, p)
end

"""
    ar1(uᵢ, a₁ = 0.90693, b₁ = 0.40693, c_xy = 0.5,
        σ = 0.40662) -> DiscreteDynamicalSystem

A bivariate, order one autoregressive model, where ``x \\to y`` [1].

## Equations of motion

```math
\\begin{aligned}
dx &= a_1 x + \\xi_{1} \\\\
dy &= b_1 y - c_{xy} x + \\xi_{2},
\\end{aligned}
```

where ``\\xi_{1}`` and ``\\xi_{2}`` are drawn from normal distributions
with zero mean and standard deviation `σ` at each iteration.

## References

1. Paluš, M., Krakovská, A., Jakubík, J., & Chvosteková, M. (2018). Causality,
    dynamical systems and the arrow of time. Chaos: An Interdisciplinary Journal of
    Nonlinear Science, 28(7), 075307. http://doi.org/10.1063/1.5019944
"""
ar1_unidir(;uᵢ = rand(2), a₁ = 0.90693, b₁ = 0.40693, c_xy = 0.5, σ = 0.40662) =
    ar1_unidir(uᵢ, a₁, b₁, c_xy, σ)

ext: jl


text:
# Mandatory
export polyhedron, loadpolyhedron!
export hrepiscomputed, hrep, vrepiscomputed, vrep
export volume, volume_simplex, unscaled_volume_simplex, surface, center_of_mass

"""
    polyhedron(rep::Representation{T})

Creates a polyhedron from the representation `rep` using the default library included in the Polyhedra package.
"""
polyhedron(rep::Representation{T}) where {T} = polyhedron(rep, default_library(FullDim(rep), T))

"""
    hrepiscomputed(p::Polyhedron)

Returns whether the H-representation of this polyhedron has been computed.
"""
function hrepiscomputed end

"""
    hrep(p::Polyhedron)

Returns an H-representation for the polyhedron `p`.
"""
hrep(p::Polyhedron) = error("`hrep` not implemented for `$(eltype(p))`")

"""
    vrepiscomputed(p::Polyhedron)

Returns whether the V-representation of this polyhedron has been computed.
"""
function vrepiscomputed end

"""
    vrep(p::Polyhedron)

Returns a V-representation for the polyhedron `p`.
"""
vrep(p::Polyhedron) = error("`vrep` not implemented for `$(eltype(p))`")

"""
    volume(p::Polyhedron{T}) where {T}

Returns the `fulldim(p)`-dimensional hyper-volume of the polyhedron `p`.
Returns `Inf` or `-one(T)` if it is infinite depending on whether the type `T` has an infinite value.
"""
function volume(p::Polyhedron{T}) where T
    return reduce(+, unscaled_volume_simplex(Δ) for Δ in triangulation(p);
                  init=zero(T)) / factorial(fulldim(p))
end

function unscaled_volume_simplex(s)
    A = Matrix{coefficient_type(s)}(undef, fulldim(s), npoints(s) - 1)
    v = first(points(s))
    for (i, p) in enumerate(Iterators.drop(points(s), 1))
        A[:, i] = p - v
    end
    return abs(det(A))
end
function volume_simplex(s)
    return unscaled_volume_simplex(s) / factorial(fulldim(s))
end

"""
    center_of_mass(p::Polyhedron{T}) where {T}

Returns the center of mass of `p`, represented as a `Vector{T}` of length `fulldim(p)`.
Throws an error if `p` is degenerate.
"""
function center_of_mass(p::Polyhedron{T}) where T
    # Implementation strategy: For a simplex, the center of mass coincides with
    # the centroid which is easy to compute.  So we triangulate `p` into
    # simplices and compute a volume-weighted average of these simplices'
    # centers of mass.
    simplices = triangulation(p)
    isempty(simplices) && error("Tried to compute center of mass of a degenerate polyhedron")
    unscaled_center = zeros(T, fulldim(p))
    unscaled_vol = zero(T)
    for Δ in simplices
        v = unscaled_volume_simplex(Δ)
        unscaled_center += v * sum(points(Δ))
        unscaled_vol += v
    end
    return unscaled_center / (unscaled_vol * (fulldim(p) + 1))
end

"""
    surface(p::Polyhedron{T}) where {T}

Returns the `fulldim(p)-1`-dimensional hyper-volume of the surface of the polyhedron `p`.
Returns `Inf` or `-one(T)` if it is infinite depending on whether the type `T` has an infinite value.
"""
function surface end

loadpolyhedron!(p::Polyhedron, filename::AbstractString, extension::Type{Val{:ine}}) = error("loadpolyhedron! not implemented for .ine")
loadpolyhedron!(p::Polyhedron, filename::AbstractString, extension::Type{Val{:ext}}) = error("loadpolyhedron! not implemented for .ext") # FIXME ExtFileVRepresentation or just ExtFile

loadpolyhedron!(p::Polyhedron, filename::AbstractString, extension::Symbol) = loadpolyhedron!(p, filename, Val{extension})

function loadpolyhedron!(p::Polyhedron, filename::AbstractString, extension::AbstractString)
    s = something(findfirst(isequal(extension), ["ext", "ine"]), 0)
    if s == 0
        error("Invalid extension $extension, please give 'ext' for V-representation or 'ine' for H-representation")
    end
    loadpolyhedron!(p, filename, [:ext, :ine][s])
end


text:
using DiffEqDiffTools, Test, LinearAlgebra

# TODO: add tests for GPUArrays
# TODO: add tests for DEDataArrays

# Derivative tests
x = collect(range(-2π, stop=2π, length=100))
y = sin.(x)
df = fill(0., 100)
epsilon = fill(0., 100)
df_ref = cos.(x)
forward_cache = DiffEqDiffTools.DerivativeCache(x, y, epsilon, Val{:forward})
central_cache = DiffEqDiffTools.DerivativeCache(x, nothing, epsilon, Val{:central})
complex_cache = DiffEqDiffTools.DerivativeCache(x, nothing, nothing, Val{:complex})

err_func(a,b) = maximum(abs.(a-b))

@time @testset "Derivative single point f : R -> R tests" begin
    @test err_func(DiffEqDiffTools.finite_difference_derivative(sin, π/4, Val{:forward}), √2/2) < 1e-4
    @test err_func(DiffEqDiffTools.finite_difference_derivative(sin, π/4, Val{:central}), √2/2) < 1e-8
    @test err_func(DiffEqDiffTools.finite_difference_derivative(sin, π/4, Val{:complex}), √2/2) < 1e-15
end

@time @testset "Derivative StridedArray f : R -> R tests" begin
    @test err_func(DiffEqDiffTools.finite_difference_derivative(sin, x, Val{:forward}), df_ref) < 1e-4
    @test err_func(DiffEqDiffTools.finite_difference_derivative(sin, x, Val{:central}), df_ref) < 1e-8
    @test err_func(DiffEqDiffTools.finite_difference_derivative(sin, x, Val{:complex}), df_ref) < 1e-15

    @test err_func(DiffEqDiffTools.finite_difference_derivative(sin, x, Val{:forward}, eltype(x), y, epsilon), df_ref) < 1e-4
    @test err_func(DiffEqDiffTools.finite_difference_derivative(sin, x, Val{:central}, eltype(x), y, epsilon), df_ref) < 1e-8
    @test err_func(DiffEqDiffTools.finite_difference_derivative(sin, x, Val{:complex}, eltype(x), y, epsilon), df_ref) < 1e-15

    @test err_func(DiffEqDiffTools.finite_difference_derivative!(df, sin, x, Val{:forward}), df_ref) < 1e-4
    @test err_func(DiffEqDiffTools.finite_difference_derivative!(df, sin, x, Val{:central}), df_ref) < 1e-8
    @test err_func(DiffEqDiffTools.finite_difference_derivative!(df, sin, x, Val{:complex}), df_ref) < 1e-15

    @test err_func(DiffEqDiffTools.finite_difference_derivative!(df, sin, x, Val{:forward}, eltype(x), y, epsilon), df_ref) < 1e-4
    @test err_func(DiffEqDiffTools.finite_difference_derivative!(df, sin, x, Val{:central}, eltype(x), y, epsilon), df_ref) < 1e-8
    @test err_func(DiffEqDiffTools.finite_difference_derivative!(df, sin, x, Val{:complex}, eltype(x), y, epsilon), df_ref) < 1e-15

    @test err_func(DiffEqDiffTools.finite_difference_derivative!(df, sin, x, forward_cache), df_ref) < 1e-4
    @test err_func(DiffEqDiffTools.finite_difference_derivative!(df, sin, x, central_cache), df_ref) < 1e-8
    @test err_func(DiffEqDiffTools.finite_difference_derivative!(df, sin, x, complex_cache), df_ref) < 1e-15
end

x = x + im*x
f(x) = sin(x) + cos(x)
y = f.(x)
df = zero(x)
epsilon = similar(real(x))
df_ref = cos.(x) - sin.(x)
forward_cache = DiffEqDiffTools.DerivativeCache(x, y, epsilon, Val{:forward})
central_cache = DiffEqDiffTools.DerivativeCache(x, y, epsilon, Val{:central})

@time @testset "Derivative single point f : C -> C tests" begin
    @test err_func(DiffEqDiffTools.finite_difference_derivative(f, π/4+im*π/4, Val{:forward}, Val{:Complex}), cos(π/4+im*π/4)-sin(π/4+im*π/4)) < 1e-3
    @test err_func(DiffEqDiffTools.finite_difference_derivative(f, π/4+im*π/4, Val{:central}, Val{:Complex}), cos(π/4+im*π/4)-sin(π/4+im*π/4)) < 1e-7
end

@time @testset "Derivative StridedArray f : C -> C tests" begin
    @test err_func(DiffEqDiffTools.finite_difference_derivative(f, x, Val{:forward}), df_ref) < 1e-3
    @test err_func(DiffEqDiffTools.finite_difference_derivative(f, x, Val{:central}), df_ref) < 1e-6

    @test err_func(DiffEqDiffTools.finite_difference_derivative(f, x, Val{:forward}, eltype(x), y), df_ref) < 1e-3
    @test err_func(DiffEqDiffTools.finite_difference_derivative(f, x, Val{:central}, eltype(x), y), df_ref) < 1e-6

    @test err_func(DiffEqDiffTools.finite_difference_derivative(f, x, Val{:forward}, eltype(x), y, epsilon), df_ref) < 1e-3
    @test err_func(DiffEqDiffTools.finite_difference_derivative(f, x, Val{:central}, eltype(x), y, epsilon), df_ref) < 1e-6

    @test err_func(DiffEqDiffTools.finite_difference_derivative!(df, f, x, Val{:forward}, eltype(x)), df_ref) < 1e-3
    @test err_func(DiffEqDiffTools.finite_difference_derivative!(df, f, x, Val{:central}, eltype(x)), df_ref) < 1e-6

    @test err_func(DiffEqDiffTools.finite_difference_derivative!(df, f, x, Val{:forward}, eltype(x), y), df_ref) < 1e-3
    @test err_func(DiffEqDiffTools.finite_difference_derivative!(df, f, x, Val{:central}, eltype(x), y), df_ref) < 1e-6

    @test err_func(DiffEqDiffTools.finite_difference_derivative!(df, f, x, Val{:forward}, eltype(x), y, epsilon), df_ref) < 1e-3
    @test err_func(DiffEqDiffTools.finite_difference_derivative!(df, f, x, Val{:central}, eltype(x), y, epsilon), df_ref) < 1e-6

    @test err_func(DiffEqDiffTools.finite_difference_derivative!(df, f, x, forward_cache), df_ref) < 1e-3
    @test err_func(DiffEqDiffTools.finite_difference_derivative!(df, f, x, central_cache), df_ref) < 1e-6
end

x = collect(range(-2π, stop=2π, length=100))
f(x) = sin(x) + im*cos(x)
y = f.(x)
df = fill(zero(Complex{eltype(x)}), size(x))
epsilon = similar(real(x))
df_ref = cos.(x) - im*sin.(x)
forward_cache = DiffEqDiffTools.DerivativeCache(x, y, epsilon, Val{:forward}, eltype(df))
central_cache = DiffEqDiffTools.DerivativeCache(x, y, epsilon, Val{:central}, eltype(df))

@time @testset "Derivative single point f : R -> C tests" begin
    @test err_func(DiffEqDiffTools.finite_difference_derivative(f, π/4, Val{:forward}, Val{:Complex}), cos(π/4)-im*sin(π/4)) < 1e-3
    @test err_func(DiffEqDiffTools.finite_difference_derivative(f, π/4, Val{:central}, Val{:Complex}), cos(π/4)-im*sin(π/4)) < 1e-7
end

@time @testset "Derivative StridedArray f : R -> C tests" begin
    @test err_func(DiffEqDiffTools.finite_difference_derivative(f, x, Val{:forward}, Complex{eltype(x)}), df_ref) < 1e-3
    @test err_func(DiffEqDiffTools.finite_difference_derivative(f, x, Val{:central}, Complex{eltype(x)}), df_ref) < 1e-6

    @test err_func(DiffEqDiffTools.finite_difference_derivative(f, x, Val{:forward}, Complex{eltype(x)}, y), df_ref) < 1e-3
    @test err_func(DiffEqDiffTools.finite_difference_derivative(f, x, Val{:central}, Complex{eltype(x)}, y), df_ref) < 1e-6

    @test err_func(DiffEqDiffTools.finite_difference_derivative(f, x, Val{:forward}, Complex{eltype(x)}, y, epsilon), df_ref) < 1e-3
    @test err_func(DiffEqDiffTools.finite_difference_derivative(f, x, Val{:central}, Complex{eltype(x)}, y, epsilon), df_ref) < 1e-6

    @test err_func(DiffEqDiffTools.finite_difference_derivative!(df, f, x, Val{:forward}, Complex{eltype(x)}), df_ref) < 1e-3
    @test err_func(DiffEqDiffTools.finite_difference_derivative!(df, f, x, Val{:central}, Complex{eltype(x)}), df_ref) < 1e-6

    @test err_func(DiffEqDiffTools.finite_difference_derivative!(df, f, x, Val{:forward}, Complex{eltype(x)}, y), df_ref) < 1e-3
    @test err_func(DiffEqDiffTools.finite_difference_derivative!(df, f, x, Val{:central}, Complex{eltype(x)}, y), df_ref) < 1e-6

    @test err_func(DiffEqDiffTools.finite_difference_derivative!(df, f, x, Val{:forward}, Complex{eltype(x)}, y, epsilon), df_ref) < 1e-3
    @test err_func(DiffEqDiffTools.finite_difference_derivative!(df, f, x, Val{:central}, Complex{eltype(x)}, y, epsilon), df_ref) < 1e-6

    @test err_func(DiffEqDiffTools.finite_difference_derivative!(df, f, x, forward_cache), df_ref) < 1e-3
    @test err_func(DiffEqDiffTools.finite_difference_derivative!(df, f, x, central_cache), df_ref) < 1e-6
end

#=
x = x + im*x
f(x) = abs2(x)
y = f.(x)
df = fill(zero(eltype(x)), size(x))
epsilon = similar(real(x))
df_ref = 2*conj.(x)
forward_cache = DiffEqDiffTools.DerivativeCache(x, y, epsilon, Val{:forward}, eltype(df))
central_cache = DiffEqDiffTools.DerivativeCache(x, y, epsilon, Val{:central}, eltype(df))
@show typeof(DiffEqDiffTools.finite_difference_derivative(f, 1.+im*1., Val{:forward}, real(eltype(x))))

@time @testset "Derivative single point f : C -> R tests" begin
    @test err_func(DiffEqDiffTools.finite_difference_derivative(f, 1.+im*1., Val{:forward}, real(eltype(x))), 2.-2.*im) < 1e-3
    @test err_func(DiffEqDiffTools.finite_difference_derivative(f, 1.+im*1., Val{:central}, real(eltype(x))), 2.-2.*im) < 1e-7
end

@time @testset "Derivative StridedArray f : C -> R tests" begin
    @test err_func(DiffEqDiffTools.finite_difference_derivative(f, x, Val{:forward}, real(eltype(x))), df_ref) < 1e-3
    @test err_func(DiffEqDiffTools.finite_difference_derivative(f, x, Val{:central}, real(eltype(x))), df_ref) < 1e-6

    @test err_func(DiffEqDiffTools.finite_difference_derivative(f, x, Val{:forward}, real(eltype(x)), y), df_ref) < 1e-3
    @test err_func(DiffEqDiffTools.finite_difference_derivative(f, x, Val{:central}, real(eltype(x)), y), df_ref) < 1e-6

    @test err_func(DiffEqDiffTools.finite_difference_derivative(f, x, Val{:forward}, real(eltype(x)), y, epsilon), df_ref) < 1e-3
    @test err_func(DiffEqDiffTools.finite_difference_derivative(f, x, Val{:central}, real(eltype(x)), y, epsilon), df_ref) < 1e-6

    @test err_func(DiffEqDiffTools.finite_difference_derivative!(df, f, x, Val{:forward}, real(eltype(x))), df_ref) < 1e-3
    @test err_func(DiffEqDiffTools.finite_difference_derivative!(df, f, x, Val{:central}, real(eltype(x))), df_ref) < 1e-6

    @test err_func(DiffEqDiffTools.finite_difference_derivative!(df, f, x, Val{:forward}, real(eltype(x)), y), df_ref) < 1e-3
    @test err_func(DiffEqDiffTools.finite_difference_derivative!(df, f, x, Val{:central}, real(eltype(x)), y), df_ref) < 1e-6

    @test err_func(DiffEqDiffTools.finite_difference_derivative!(df, f, x, Val{:forward}, real(eltype(x)), y, epsilon), df_ref) < 1e-3
    @test err_func(DiffEqDiffTools.finite_difference_derivative!(df, f, x, Val{:central}, real(eltype(x)), y, epsilon), df_ref) < 1e-6

    @test err_func(DiffEqDiffTools.finite_difference_derivative!(df, f, x, forward_cache), df_ref) < 1e-3
    @test err_func(DiffEqDiffTools.finite_difference_derivative!(df, f, x, central_cache), df_ref) < 1e-6
end
=#

# Gradient tests
f(x) = 2x[1] + x[2]^2
x = rand(2)
fx = f(x)
df = fill(0.,2)
df_ref = [2., 2*x[2]]
forward_cache = DiffEqDiffTools.GradientCache(df,x,Val{:forward})
central_cache = DiffEqDiffTools.GradientCache(df,x,Val{:central})
complex_cache = DiffEqDiffTools.GradientCache(df,x,Val{:complex})

@time @testset "Gradient of f:vector->scalar real-valued tests" begin
    @test err_func(DiffEqDiffTools.finite_difference_gradient(f, x, Val{:forward}), df_ref) < 1e-4
    @test err_func(DiffEqDiffTools.finite_difference_gradient(f, x, Val{:central}), df_ref) < 1e-8
    @test err_func(DiffEqDiffTools.finite_difference_gradient(f, x, Val{:complex}), df_ref) < 1e-15

    @test err_func(DiffEqDiffTools.finite_difference_gradient!(df, f, x, Val{:forward}), df_ref) < 1e-4
    @test err_func(DiffEqDiffTools.finite_difference_gradient!(df, f, x, Val{:central}), df_ref) < 1e-8
    @test err_func(DiffEqDiffTools.finite_difference_gradient!(df, f, x, Val{:complex}), df_ref) < 1e-15

    @test err_func(DiffEqDiffTools.finite_difference_gradient!(df, f, x, forward_cache), df_ref) < 1e-4
    @test err_func(DiffEqDiffTools.finite_difference_gradient!(df, f, x, central_cache), df_ref) < 1e-8
    @test err_func(DiffEqDiffTools.finite_difference_gradient!(df, f, x, complex_cache), df_ref) < 1e-15
end

f(x) = 2x[1] + im*2x[1] + x[2]^2
x = x + im*x
fx = f(x)
df = zero(x)
df_ref = conj([2.0+2.0*im, 2.0*x[2]])
forward_cache = DiffEqDiffTools.GradientCache(df,x,Val{:forward})
central_cache = DiffEqDiffTools.GradientCache(df,x,Val{:central})

@time @testset "Gradient of f : C^N -> C tests" begin
    @test err_func(DiffEqDiffTools.finite_difference_gradient(f, x, Val{:forward}), df_ref) < 1e-4
    @test err_func(DiffEqDiffTools.finite_difference_gradient(f, x, Val{:central}), df_ref) < 1e-8

    @test err_func(DiffEqDiffTools.finite_difference_gradient!(df, f, x, Val{:forward}), df_ref) < 1e-4
    @test err_func(DiffEqDiffTools.finite_difference_gradient!(df, f, x, Val{:central}), df_ref) < 1e-8

    @test err_func(DiffEqDiffTools.finite_difference_gradient!(df, f, x, forward_cache), df_ref) < 1e-4
    @test err_func(DiffEqDiffTools.finite_difference_gradient!(df, f, x, central_cache), df_ref) < 1e-8
end

f(x) = sum(abs2, x)
x = ones(2) * (1 + im)
fx = f(x)
df = zero(x)
df_ref = 2*x
forward_cache = DiffEqDiffTools.GradientCache(df,x,Val{:forward})
central_cache = DiffEqDiffTools.GradientCache(df,x,Val{:central})

@time @testset "Gradient of f : C^N -> R tests" begin
    @test err_func(DiffEqDiffTools.finite_difference_gradient(f, x, Val{:forward}), df_ref) < 1e-4
    @test err_func(DiffEqDiffTools.finite_difference_gradient(f, x, Val{:central}), df_ref) < 1e-8

    @test err_func(DiffEqDiffTools.finite_difference_gradient!(df, f, x, Val{:forward}), df_ref) < 1e-4
    @test err_func(DiffEqDiffTools.finite_difference_gradient!(df, f, x, Val{:central}), df_ref) < 1e-8

    @test err_func(DiffEqDiffTools.finite_difference_gradient!(df, f, x, forward_cache), df_ref) < 1e-4
    @test err_func(DiffEqDiffTools.finite_difference_gradient!(df, f, x, central_cache), df_ref) < 1e-8
end

f(x) = 2*x[1] + im*x[2]^2
x = ones(2)
fx = f(x)
df = fill(zero(eltype(fx)), size(x))
df_ref = [2.0, -im*2*x[2]]
forward_cache = DiffEqDiffTools.GradientCache(df,x,Val{:forward},eltype(df))
central_cache = DiffEqDiffTools.GradientCache(df,x,Val{:central},eltype(df))

@time @testset "Gradient of f : R^N -> C tests" begin
    @test err_func(DiffEqDiffTools.finite_difference_gradient(f, x, Val{:forward}, eltype(df)), df_ref) < 1e-4
    @test err_func(DiffEqDiffTools.finite_difference_gradient(f, x, Val{:central}, eltype(df)), df_ref) < 1e-8

    @test err_func(DiffEqDiffTools.finite_difference_gradient!(df, f, x, Val{:forward}, eltype(df)), df_ref) < 1e-4
    @test err_func(DiffEqDiffTools.finite_difference_gradient!(df, f, x, Val{:central}, eltype(df)), df_ref) < 1e-8

    @test err_func(DiffEqDiffTools.finite_difference_gradient!(df, f, x, forward_cache), df_ref) < 1e-4
    @test err_func(DiffEqDiffTools.finite_difference_gradient!(df, f, x, central_cache), df_ref) < 1e-8
end

f(df,x) = (df[1]=sin(x); df[2]=cos(x); df)
x = 2π * rand()
fx = fill(0.,2)
f(fx,x)
df = fill(0.,2)
df_ref = [cos(x), -sin(x)]
forward_cache = DiffEqDiffTools.GradientCache(df,x,Val{:forward})
central_cache = DiffEqDiffTools.GradientCache(df,x,Val{:central})
complex_cache = DiffEqDiffTools.GradientCache(df,x,Val{:complex})

@time @testset "Gradient of f:scalar->vector real-valued tests" begin
    @test_broken err_func(DiffEqDiffTools.finite_difference_gradient(f, x, Val{:forward}), df_ref) < 1e-4
    @test err_func(DiffEqDiffTools.finite_difference_gradient(f, x, Val{:forward}, eltype(x), Val{true}, fx), df_ref) < 1e-4
    @test err_func(DiffEqDiffTools.finite_difference_gradient(f, x, Val{:central}, eltype(x), Val{true}, fx), df_ref) < 1e-8
    @test err_func(DiffEqDiffTools.finite_difference_gradient(f, x, Val{:complex}, eltype(x), Val{true}, fx), df_ref) < 1e-15

    @test err_func(DiffEqDiffTools.finite_difference_gradient!(df, f, x, Val{:forward}), df_ref) < 1e-4
    @test err_func(DiffEqDiffTools.finite_difference_gradient!(df, f, x, Val{:central}), df_ref) < 1e-8
    @test err_func(DiffEqDiffTools.finite_difference_gradient!(df, f, x, Val{:complex}), df_ref) < 1e-15

    @test err_func(DiffEqDiffTools.finite_difference_gradient!(df, f, x, forward_cache), df_ref) < 1e-4
    @test err_func(DiffEqDiffTools.finite_difference_gradient!(df, f, x, central_cache), df_ref) < 1e-8
    @test err_func(DiffEqDiffTools.finite_difference_gradient!(df, f, x, complex_cache), df_ref) < 1e-15
end

f(df,x) = (df[1]=sin(x); df[2]=cos(x); df)
x = (2π * rand()) * (1 + im)
fx = fill(zero(typeof(x)), 2)
f(fx,x)
df = zero(fx)
df_ref = [cos(x), -sin(x)]
forward_cache = DiffEqDiffTools.GradientCache(df,x,Val{:forward})
central_cache = DiffEqDiffTools.GradientCache(df,x,Val{:central})

@time @testset "Gradient of f:vector->scalar complex-valued tests" begin
    @test err_func(DiffEqDiffTools.finite_difference_gradient(f, x, Val{:forward}, eltype(x), Val{true}, fx), df_ref) < 1e-4
    @test err_func(DiffEqDiffTools.finite_difference_gradient(f, x, Val{:central}, eltype(x), Val{true}, fx), df_ref) < 1e-7

    @test err_func(DiffEqDiffTools.finite_difference_gradient!(df, f, x, Val{:forward}), df_ref) < 1e-4
    @test err_func(DiffEqDiffTools.finite_difference_gradient!(df, f, x, Val{:central}), df_ref) < 1e-7

    @test err_func(DiffEqDiffTools.finite_difference_gradient!(df, f, x, forward_cache), df_ref) < 1e-4
    @test err_func(DiffEqDiffTools.finite_difference_gradient!(df, f, x, central_cache), df_ref) < 1e-7
end

# Jacobian tests
function f(fvec,x)
    fvec[1] = (x[1]+3)*(x[2]^3-7)+18
    fvec[2] = sin(x[2]*exp(x[1])-1)
end
x = rand(2); y = rand(2)
f(y,x)
J_ref = [[-7+x[2]^3 3*(3+x[1])*x[2]^2]; [exp(x[1])*x[2]*cos(1-exp(x[1])*x[2]) exp(x[1])*cos(1-exp(x[1])*x[2])]]
J = zero(J_ref)
df = zero(x)
df_ref = diag(J_ref)
epsilon = zero(x)
forward_cache = DiffEqDiffTools.JacobianCache(x,Val{:forward})
central_cache = DiffEqDiffTools.JacobianCache(x)
complex_cache = DiffEqDiffTools.JacobianCache(x,Val{:complex})
f_in = copy(y)

@time @testset "Jacobian StridedArray real-valued tests" begin
    @test err_func(DiffEqDiffTools.finite_difference_jacobian(f, x, forward_cache), J_ref) < 1e-4
    @test err_func(DiffEqDiffTools.finite_difference_jacobian(f, x, forward_cache, f_in), J_ref) < 1e-4
    @test err_func(DiffEqDiffTools.finite_difference_jacobian(f, x, central_cache), J_ref) < 1e-8
    @test err_func(DiffEqDiffTools.finite_difference_jacobian(f, x), J_ref) < 1e-8
    @test err_func(DiffEqDiffTools.finite_difference_jacobian(f, x, complex_cache), J_ref) < 1e-14
end

function f(fvec,x)
    fvec[1] = (im*x[1]+3)*(x[2]^3-7)+18
    fvec[2] = sin(x[2]*exp(x[1])-1)
end
x = rand(2) + im*rand(2)
y = similar(x)
f(y,x)
J_ref = [[im*(-7+x[2]^3) 3*(3+im*x[1])*x[2]^2]; [exp(x[1])*x[2]*cos(1-exp(x[1])*x[2]) exp(x[1])*cos(1-exp(x[1])*x[2])]]
J = zero(J_ref)
df = zero(x)
df_ref = diag(J_ref)
epsilon = zero(real.(x))
forward_cache = DiffEqDiffTools.JacobianCache(x,Val{:forward})
central_cache = DiffEqDiffTools.JacobianCache(x)
f_in = copy(y)

@time @testset "Jacobian StridedArray f : C^N -> C^N tests" begin
    @test err_func(DiffEqDiffTools.finite_difference_jacobian(f, x, forward_cache), J_ref) < 1e-4
    @test err_func(DiffEqDiffTools.finite_difference_jacobian(f, x, forward_cache, f_in), J_ref) < 1e-4
    @test err_func(DiffEqDiffTools.finite_difference_jacobian(f, x, central_cache), J_ref) < 1e-8
    @test err_func(DiffEqDiffTools.finite_difference_jacobian(f, x), J_ref) < 1e-8
end


text:
# ======================================
# Kronecker powers
# ======================================

using LinearAlgebra: checksquare

"""
    kron_pow(x::IA.Interval, pow::Int)

Given an interval x and an integer pow, compute `x^pow`.

### Input

- `x`   -- interval
- `pow` -- integer

### Output

An interval enclosure of `x^pow`.

### Examples

```julia
julia> [kron_pow(2 .. 3, i) for i in 1:3]
3-element Array{IntervalArithmetic.Interval{Float64},1}:
  [2, 3]
  [4, 9]
 [8, 27]
```
"""
function kron_pow(x::IA.Interval, pow::Int)
    return x^pow
end

"""
    kron_pow(x::Interval, pow::Int)

Given an interval x and an integer pow, compute `x^pow`.

### Input

- `x`   -- interval
- `pow` -- integer

### Output

An interval enclosure of `x^pow` as a LazySets `Interval`.
"""
function kron_pow(x::Interval, pow::Int)
    return Interval(kron_pow(x.dat, pow))
end

"""
    kron_pow(H::AbstractHyperrectangle, pow::Int)

Given hyperrectangular set `H` and an integer `pow`, compute the Kronecker power
`H^{⊗ pow}`.

### Input

- `H`   -- hyperrectangular set
- `pow` -- integer power

### Output

A hyperrectangle.

### Algorithm

We compute `H^{⊗ pow}` where `H` is a hyperrectangular set by working with `H`
as a product of intervals.

See also `kron_pow` which requires `DynamicPolynomials.jl`.
"""
function kron_pow(H::AbstractHyperrectangle, pow::Int, algorithm=nothing)
    if pow == 1
        return H
    end

    if isnothing(algorithm)
        if isdefined(@__MODULE__, :DynamicPolynomials)
            algorithm = "symbolic"
        else
            algorithm = "explicit"
        end
    end
    if algorithm == "explicit"
        return _kron_pow_explicit(H, pow)
    elseif algorithm == "symbolic"
        return _kron_pow_symbolic(H, pow)
    else
        throw(ArgumentError("algorithm \"$algorithm\" is not known"))
    end
end

function _kron_pow_explicit(H::AbstractHyperrectangle, pow::Int)
    x = [Interval(low(H, j), high(H, j)) for j in 1:dim(H)]
    r = reduce(kron, fill(x, pow))

    low_r = min.(r)
    high_r = max.(r)
    return Hyperrectangle(low=low_r, high=high_r)
end

"""
    kron_pow_stack(x::Union{<:Interval, <:IA.Interval}, pow::Int)

Return an array with the interval powers `[x, x^2, …, x^pow]`.

### Input

- `x`   -- interval
- `pow` -- integer power

### Output

A vector of elements of the same type as `x` such that the `i`-th element is the interval `x^i`.
"""
function kron_pow_stack(x::Union{<:Interval, <:IA.Interval}, pow::Int)
    return [kron_pow(x, i) for i in 1:pow]
end

"""
    kron_pow_stack(H::AbstractHyperrectangle, pow::Int)

Return the Cartesian product array ``H × H^{⊗2} × ⋯ × H^{⊗pow}`` where ``H`` is a
hyperrectangular set and ``H^{⊗ i}`` is the `i`-th Kronecker power of ``H``.

### Input

- `H`   -- hyperrectangular set
- `pow` -- integer power

### Output

A Cartesian product array of hyperrectangles.
"""
function kron_pow_stack(H::AbstractHyperrectangle, pow::Int)
    out = [kron_pow(H, i) for i in 1:pow]
    return CartesianProductArray(out)
end

# ------------------------------------------------------------
# Functionality that requires DynamicPolynomials.jl
# ------------------------------------------------------------

function load_kron_dynamicpolynomials()
return quote

function _kron_pow_symbolic(H::AbstractHyperrectangle{N}, pow::Int) where {N}
    n = dim(H)
    @polyvar x[1:n]
    B = convert(IntervalBox, H)
    dict = Dict((x[i] => i for i in 1:n)...)
    y = kron_pow(x, pow)

    out = Vector{IA.Interval{N}}(undef, length(y))
    for (i, p) in enumerate(y)
        aux = interval(1)
        for (xj, j) in powers(p)
            aux = aux * B[dict[xj]]^j
        end
        out[i] = aux
    end
    Bpow = IntervalBox(out)
    Hpow = convert(Hyperrectangle, Bpow)
    return Hpow
end

end end  # quote / load_kron_dynamicpolynomials()

# ------------------------------------------------------------
# Functionality that requires MultivariatePolynomials.jl
# ------------------------------------------------------------

function load_kron_multivariate()
return quote

import Base: findfirst, findall

"""
    kron_pow(x::Vector{<:AbstractVariable}, pow::Int)

Compute the higher order concrete Kronecker power: `x ⊗ x ⊗ ... ⊗ x`, `pow` times
for a vector of symbolic monomials.

### Input

- `x`   -- polynomial variable
- `pow` -- integer

### Output

Vector of multivariate monomial corresponding to `x^{⊗ pow}`.

### Examples

```julia
julia> using DynamicPolynomials

julia> @polyvar x[1:2]
(PolyVar{true}[x₁, x₂],)

julia> x
2-element Array{PolyVar{true},1}:
 x₁
 x₂

julia> kron_pow(x, 2)
4-element Array{Monomial{true},1}:
 x₁²
 x₁x₂
 x₁x₂
 x₂²
```
"""
function kron_pow(x::Vector{<:AbstractVariable}, pow::Int)
    @assert pow > 0 "expected positive power, got $pow"
    if pow == 1
        return x
    else
        return kron(x, kron_pow(x, pow-1))
    end
end

"""
    findfirst(y::Vector{<:AbstractMonomialLike}, x::AbstractMonomialLike)

Return the first position of the multivariate monomial ``x`` in the vector of monomials ``y``.

### Input

- `y` -- vector of multivariate monomials
- `x` -- multivariate monomials

### Output

An integer where each integer represents the index in the array `y`
corresponding to the first match, i.e. `y[i] == x` where `i` is the output integer,
or `nothing` if there is no match.

### Notes

Let ``x = (x_1, x_2, …, x_n)`` be given, and let ``y_i = x^{[i]}``.
Given the multi-index ``I = (i_1, i_2, …, i_n)``, this function returns the
first position of ``x^I`` in the array ``y`` (resp. all positions using `findall`).

### Examples

```julia
julia> using DynamicPolynomials

julia> @polyvar x[1:2]
(PolyVar{true}[x₁, x₂],)

julia> y = kron_pow(x, 2)
4-element Array{Monomial{true},1}:
 x₁²
 x₁x₂
 x₁x₂
 x₂²

julia> findfirst(y, x[1]*x[2])
2
```
"""
function findfirst(y::Vector{<:AbstractMonomialLike}, x::AbstractMonomialLike)
    pow = exponents(x)
    @assert sum(pow) == sum(exponents(first(y))) "power indices don't match the power in the lifted vector"
    xv = variables(x)
    _findfirst(y, xv, pow)
end

"""
    findall(y::Vector{<:AbstractMonomialLike}, x::AbstractMonomialLike)

Return all positions of the multivariate monomial ``x`` in the vector of monomials ``y``.

### Input

- `y` -- vector of multivariate monomials
- `x` -- multivariate monomials

### Output

A vector of integers where each integer represents the index in the array `y`
corresponding to a match, i.e. `y[i] == x` for all elements `i` in the output array.

### Notes

Let ``x = (x_1, x_2, …, x_n)`` be given, and let ``y_i = x^{[i]}``.
Given the multi-index ``I = (i_1, i_2, …, i_n)``, this function returns all
positions of ``x^I`` in the array ``y`` (resp. the first position using `findfirst`).

### Examples

```julia
julia> using DynamicPolynomials

julia> @polyvar x[1:2]
(PolyVar{true}[x₁, x₂],)

julia> y = kron_pow(x, 2)
4-element Array{Monomial{true},1}:
 x₁²
 x₁x₂
 x₁x₂
 x₂²

julia> findall(y, x[1]*x[2])
2-element Array{Int64,1}:
 2
 3
```
"""
function findall(y::Vector{<:AbstractMonomialLike}, x::AbstractMonomialLike)
    pow = exponents(x)
    @assert sum(pow) == sum(exponents(first(y))) "power indices don't match the power in the lifted vector"
    xv = variables(x)
    _findall(y, xv, pow)
end

function _findfirst(y, x, pow)
    yp = powers.(y)
    t = ntuple(i -> (x[i], pow[i]), length(pow))
    idx = findfirst(pi -> pi == t, yp)
end

function _findall(y, x, pow)
    yp = powers.(y)
    t = ntuple(i -> (x[i], pow[i]), length(pow))
    idx = findall(pi -> pi == t, yp)
end

end end  # quote / load_kron_multivariate()


text:
#!/usr/bin/env -S julia
using FASTX,BioAlignments,BioSequences,ArgParse

function main()
	scoremodel = AffineGapScoreModel(EDNAFULL, gap_open=-5, gap_extend=-1);

end

main()

max_stars_repo_name: jdurbin/sandbox

max_issues_repo_name: jdurbin/sandbox

max_forks_repo_name: jdurbin/sandbox


text:
function parse_css(filepath::String)
	open(filepath) do file
		out = []
		while !eof(file)
				ind_out = []
				selector_dict = Dict()
				str = readuntil(file, '}')
				match_selector = match(r"([a-z]+)\s*?({|\[)", str)
				if match_selector == nothing
					continue
				end
				show(match_selector)
				selector = match_selector[1]
				push!(ind_out,selector)
				for i in eachmatch(r"((?<=\[).+?(?=\]))", str)
					if i != nothing
						if occursin(r"(.+?)([!|=|<|>|~]{1,2})(.+)", i.match)
							m = match(r"(.+?)([!|=|<|>|~]{1,2})(.+)", i.match)
							operator = m[2]
							selector_dict[m[1]] = (m[3], operator)
						else
							selector_dict[i.match] = ("yes", "=")
						end
					end
				end
				push!(ind_out,selector_dict)
				cur_style = Dict("color"=>0xD3D3D3, "width"=>0, "spec"=>"-", "is_polygon"=>false, "font-size"=>.6)
				for m in eachmatch(r"([a-z]+?):(.+?);", str)
					tag = m[1]
					val = m[2]
					if(tag == "color")
						cur_style["color"] = tryparse(Int, val)
						if(cur_style["color"]  == nothing)
							cur_style["color"]  = String(val)
						end
					end
					if(tag == "width")
						cur_style["width"] = tryparse(Int, val)
						if(cur_style["width"] == nothing)
							cur_style["width"] = 1
						end
					end
					if(tag == "font-size")
						cur_style["font-size"] = tryparse(Float64, val)
					end
					if(tag == "text")
						cur_style["text"] = val
					end
				end
				push!(ind_out, cur_style)
				tupleized=tuple(ind_out...)
				push!(out, tupleized)
		end
				println()
		println()
		println()

		for i in out
			println("Rule:")
			println(i)
		end
				println()
		println()
		println()

		return out
	end
end