text:
# Alignment Operations
# ====================
#
# Alignment operation type.
#
# This file is a part of BioJulia.
# License is MIT: https://github.com/BioJulia/BioAlignments.jl/blob/master/LICENSE.md

"""
Alignment operation.
"""
primitive type Operation 8 end

# Conversion to and from integers
# -------------------------------

Base.convert(::Type{Operation}, op::UInt8) = reinterpret(Operation, op)
Base.convert(::Type{UInt8}, op::Operation) = reinterpret(UInt8, op)
Operation(c::UInt8) = convert(Operation, c)

Base.convert(::Type{Operation}, op::Integer) = Operation(convert(UInt8, op))
Base.convert(::Type{T}, op::Operation) where T<:Integer = T(convert(UInt8, op))
Operation(c::Integer) = convert(Operation, UInt8(c))

# Operation encoding definitions
# ------------------------------

# Invalid operation.
const OP_INVALID = convert(Operation, 0xff)

# Lookup table for conversion from Char to Operation.
const char_to_op = fill(OP_INVALID, 128)

# Lookup table for conversion from Operation to Char.
const op_to_char = fill('\0', 11)

# Lookup table for showing operations as constants.
const op_to_symbol = fill(Symbol(""), 11)

# Define operations.
for (name, char, doc, code) in [
        ("MATCH"       , 'M', "non-specific match"                                                             , 0x00),
        ("INSERT"      , 'I', "insertion into reference sequence"                                              , 0x01),
        ("DELETE"      , 'D', "deletion from reference sequence"                                               , 0x02),
        ("SKIP"        , 'N', "(typically long) deletion from the reference, e.g. due to RNA splicing"         , 0x03),
        ("SOFT_CLIP"   , 'S', "sequence removed from the beginning or end of the query sequence but stored"    , 0x04),
        ("HARD_CLIP"   , 'H', "sequence removed from the beginning or end of the query sequence and not stored", 0x05),
        ("PAD"         , 'P', "not currently supported, but present for SAM/BAM compatibility"                 , 0x06),
        ("SEQ_MATCH"   , '=', "match operation with matching sequence positions"                               , 0x07),
        ("SEQ_MISMATCH", 'X', "match operation with mismatching sequence positions"                            , 0x08),
        ("BACK"        , 'B', "not currently supported, but present for SAM/BAM compatibility"                 , 0x09),
        ("START"       , '0', "indicate the start of an alignment within the reference and query sequence"     , 0x0a),]
    sym = Symbol("OP_", name)
    @eval begin
        @doc $(string("`'", char, "'`: ", doc)) const $(sym) = convert(Operation, $(code))
        char_to_op[$(Int(char)+1)] = $(sym)
        op_to_char[$(code+1)] = $(char)
        op_to_symbol[$(code+1)] = $(Expr(:quote, sym))
    end
end

const OP_MAX_VALID = OP_START

function Base.isvalid(op::Operation)
    return reinterpret(UInt8, op) ≤ reinterpret(UInt8, OP_START)
end

"""
    ismatchop(op::Operation)

Test if `op` is a match operation (i.e. `op ∈ (OP_MATCH, OP_SEQ_MATCH, OP_SEQ_MISMATCH)`).
"""
function ismatchop(op::Operation)
    return op == OP_MATCH || op == OP_SEQ_MATCH || op == OP_SEQ_MISMATCH
end

"""
    isinsertop(op::Operation)

Test if `op` is a insertion operation (i.e. `op ∈ (OP_INSERT, OP_SOFT_CLIP, OP_HARD_CLIP)`).
"""
function isinsertop(op::Operation)
    return op == OP_INSERT || op == OP_SOFT_CLIP || op == OP_HARD_CLIP
end

"""
    isdeleteop(op::Operation)

Test if `op` is a deletion operation (i.e. `op ∈ (OP_DELETE, OP_SKIP)`).
"""
function isdeleteop(op::Operation)
    return op == OP_DELETE || op == OP_SKIP
end

"""
    isqueryop(op::Operation)

Test `op ∈ (OP_MATCH, OP_SOFT_CLIP, OP_INSERT, OP_SEQ_MATCH, OP_SEQ_MISMATCH)`.
"""
function isqueryop(op::Operation)
	return op == OP_MATCH || op == OP_SOFT_CLIP || op == OP_INSERT  || op == OP_SEQ_MATCH || op == OP_SEQ_MISMATCH
end

function Base.convert(::Type{Operation}, c::Char)
    i = convert(Int, c)
    @inbounds op = i < 128 ? char_to_op[i+1] : OP_INVALID
    if op == OP_INVALID
        throw(ArgumentError("invalid alignment operation character '$(c)'"))
    end
    return op
end

Operation(c::Char) = convert(Operation, c)

function Base.convert(::Type{Char}, op::Operation)
    if !isvalid(op)
        throw(ArgumentError("invalid alignment operation"))
    end
    return op_to_char[convert(UInt8, op) + 1]
end

function Base.print(io::IO, op::Operation)
    write(io, convert(Char, op))
    return
end

function Base.show(io::IO, op::Operation)
    if isvalid(op)
        print(io, op_to_symbol[convert(Int, op)+1])
    else
        print(io, "Invalid Operation")
    end
end


text:
## generate a sorted array of uniform(0,1) r.v.s
## This is the uniform spacing method, Algorithm B on p. 214 of
## L. Devroye. Non-uniform random variate generation. 1986.

## this version only fills vec[start+1:start+n]
@inline function sampleSortedUniforms!(vec::Vector{Float64},
  start::Int64, n::Int64, rng::RNG = GLOBAL_RNG) where RNG <: AbstractRNG
  s::Float64 = 0.0
  for i = 1:n
    @inbounds vec[start + i] = randexp(rng)
    @inbounds s += vec[start + i]
  end
  G::Float64 = 1.0 / (s + randexp(rng))
  @inbounds vec[start + 1] *= G
  for i = 2:n
    @inbounds vec[start + i] *= G
    @inbounds vec[start + i] += vec[start + i - 1]
  end
end

## this version fills vec
@inline function sampleSortedUniforms!(vec::Vector{Float64},
  rng::RNG = GLOBAL_RNG) where RNG <: AbstractRNG
  sampleSortedUniforms!(vec, 0, length(vec), rng)
end

## this version creates a vector of length n and fills it
@inline function sampleSortedUniforms(n::Int64,
  rng::RNG = GLOBAL_RNG) where RNG <: AbstractRNG
  vec::Vector{Float64} = Vector{Float64}(undef, n)
  sampleSortedUniforms!(vec, rng)
  return vec
end

ext: jl


text:
using GenomeAnnotations
#using Base.Test

# run Config-Test-1.jl first to configure local test store
# run Store
# write your own tests here
#@test 1 == 1


text:
#多対一のケース
function deferred_acceptance(prop_prefs::Vector{Vector{Int}},
                             resp_prefs::Vector{Vector{Int}},
                             caps::Vector{Int})
    m = length(prop_prefs)
    n = length(resp_prefs)
    prop_matched = zeros(Int64,m)
    resp_matched = zeros(Int64,sum(caps))
    count = ones(Int64,m)
    accept = zeros(Int64,n)
    indptr = Array{Int}(n+1)
    indptr[1] = 1
    for i in 1:n
        indptr[i+1] = indptr[i] + caps[i]
    end

    for j in 1:n
        for i in 1:m
            if prop_matched[i] == 0 && count[i] <= length(prop_prefs[i])
                k = prop_prefs[i][count[i]]
                if findfirst(resp_prefs[k], i) != 0
                    if accept[k] < caps[k]
                        resp_matched[indptr[k+1]-1 - accept[k]] = i
                        prop_matched[i] = k
                        accept[k]+=1
                    else
                        list = resp_matched[indptr[k]:indptr[k+1]-1]
                        ranking = zeros(Int64,caps[k])
                        for l in 1:caps[k]
                            ranking[l] = findfirst(resp_prefs[k], list[l])
                        end
                        if 0 < findfirst(resp_prefs[k], i) < maximum(ranking)
                            resp_matched[indptr[k] + indmax(ranking) - 1] = i
                            prop_matched[list[indmax(ranking)]] = 0
                            prop_matched[i] = k
                        end
                    end
                end
                count[i]+=1
            end
        end
    end
    return prop_matched, resp_matched, indptr
end

#一対一のケース
function deferred_acceptance(prop_prefs::Vector{Vector{Int}},
                                resp_prefs::Vector{Vector{Int}})
    caps = ones(Int, length(resp_prefs))
    prop_matched, resp_matched, indptr =
        deferred_acceptance(prop_prefs, resp_prefs, caps)
    return prop_matched, resp_matched
end

function deferred_acceptance(m_prefs::Vector{Vector{Int}},f_prefs::Vector{Vector{Int}})
    m_size = length(m_prefs)
    f_size = length(f_prefs)
    m_matched = zeros(Int64,m_size)
    f_matched = zeros(Int64,f_size)
    m_prp = ones(Int64,m_size)
    for j in 1:f_size
        for i in 1:m_size
            if m_matched[i] == 0 && m_prp[i] <= length(m_prefs[i])
                if findfirst(f_prefs[m_prefs[i][m_prp[i]]], i) != 0
                    if f_matched[m_prefs[i][m_prp[i]]] == 0
                        f_matched[m_prefs[i][m_prp[i]]] = i
                        m_matched[i] = m_prefs[i][m_prp[i]]
                    else
                        if 0 < findfirst(f_prefs[m_prefs[i][m_prp[i]]], i) < findfirst(f_prefs[m_prefs[i][m_prp[i]]], f_matched[m_prefs[i][m_prp[i]]])
                            m_matched[f_matched[m_prefs[i][m_prp[i]]]] = 0
                            m_matched[i] = m_prefs[i][m_prp[i]]
                            f_matched[m_prefs[i][m_prp[i]]] = i
                        end
                    end
                end
                m_prp[i]+=1
            end
        end
    end
    return(m_matched,f_matched)
end


text:
function save_config(d::AbstractDict)
    open(config_path, "w+") do io
        for (key, val) ∈ d
            !isnothing(val) && write(io, string(key, " ", val))
        end
    end
end

const config_types = Dict(
    :dst => String,
    :target => String,
)

const config_path = joinpath(homedir(), ".backup_config_jl")

function read_config()
    !isfile(config_path) && return DefaultDict(() -> nothing)
    options = filter(!isempty, split(readchomp(config_path), '\n'))
    d = DefaultDict(() -> nothing)
    map(options) do opt
        items = split(opt)
        length(items) > 1 || @warn "Skipping unknown configuration entry \"$opt\"."
        key = lowercase(first(items))
        val = join(items[2:end])
        sym = Symbol(key)

        d[sym] = config_types[sym](val)
    end
    d
end


text:
module Diagnotics

abstract type Action end

struct AddWhiteSpace <: Action
    range::UnitRange
end

struct DeleteWhiteSpace <: Action
    range::UnitRange
end

abstract type DiagnosticSeverity end
abstract type Error <: DiagnosticSeverity end
abstract type Warning <: DiagnosticSeverity end
abstract type Information <: DiagnosticSeverity end
abstract type Hint <: DiagnosticSeverity end

struct Diagnostic{S}
    loc::UnitRange
    code::Int
    action::Vector{Action}
end

@enum(ErrorCodes,
)

@enum(WarningCodes,
# Deprecations
Deprecationfunction,
Deprecationtype,
Deprecationimmutable,
Deprecationabstract,
Deprecationbitstype,
Deprecationtypealias,
DuplicateArgumentName,
ArgumentFunctionNameConflict,
SlurpingPosition,
KWPosition,
ImportInFunction,
DuplicateArgument,
LetNonAssignment,
RangeNonAssignment,
CondAssignment,
DeadCode,
DictParaMisSpec,
DictGenAssignment,
MisnamedConstructor,
LoopOverSingle,
AssignsToFuncName,
PossibleTypo)

end


text:
# This code generates the 2l+1 dimensional matrix Fourier coefficients
# for a function defined over the rotation and rotation/reflection groups
#
# The routines in this file are based upon:
#
#   FFTs on the Rotation Group
#   Peter J. Kostelec and Daniel N. Rockmore
#   J. Fourier. Anal. Appl., Vol. 14, Issue. 2, p. 145-179, 2008

# This file contains a slower, reference version of the Fourier transform

function w(B::Int, k::Int)
    s = 0.0

    for j in 0:B-1
        s += sin((2j + 1) * (2k + 1) * (π / (4B))) / (2j + 1)
    end

    s *= (2/B) * sin(π * (2k + 1) / (4B))
end

function f̂(f::Function, B::Int, l::Int, M::Int, M′::Int)
    s = 0.0

    for j₁ in 0:2B-1, j₂ in 0:2B-1, k in 0:2B-1
        α = (2π * j₁) / (2B)
        β = π * (2k + 1) / (4B)
        γ = (2π * j₂) / (2B)

        s += w(B, k) * f(O3(α, β, γ)) * wigner_D̃(l, M, M′, α, β, γ)'
    end

    s /= (2B)^2
end

f̂_matrix(f::Function, B::Int, l::Int) = [f̂(f, B, l, M′, M) for M in -l:l, M′ in -l:l]

fourier_coeffs(f::Function, B::Int) = [f̂_matrix(f, B, l) for l in 0:B-1]

function T₂(f::Function, B::Int, k::Int, M::Int, M′::Int)
    s = 0.0

    for j₂ in 0:2B-1
        γ = (2π * j₂) / (2B)
        s += exp(im * M′ * γ) * exp(-im * ((2π * j₂) / (2B)) * (B)) * T₁(f, B, k, M, j₂)
    end

    s /= 2B
end

function fft_f̂(f::Function, B::Int, l::Int, M::Int, M′::Int)
    s = 0.0

    for k in 0:2B-1
        β = π * (2k + 1) / (4B)
        s += w(B, k) * wigner_d̃(l, M, M′, β) * T₂(f, B, k, M, M′)
    end

    return s
end

fft_f̂_matrix(f::Function, B::Int, l::Int) = [fft_f̂(f, B, l, M′, M) for M in -l:l, M′ in -l:l]

fft_fourier_coeffs(f::Function, B::Int) = [fft_f̂_matrix(f, B, l) for l in 0:B-1]

function T₁(f::Function, B::Int, k::Int, M::Int, j₂::Int)
    β = π * (2k + 1) / (4B)
    γ = (2π * j₂) / (2B)

    s = 0.0
    for j₁ in 0:2B-1
        α = (2π * j₁) / (2B)
        s += exp(im * M * α) * exp(-im * ((2π * j₁) / (2B)) * (B)) * f(O3(α, β, γ))
    end

    s /= 2B
end


text:
using Mux
using HTTP
using JSON
using OpenIDConnect
using JWTs

headers(req) = req[:headers]
query(req) = parse_query(req[:query])
function parse_query(qstr)
    res = Dict{String,String}()
    for qsub in split(qstr, '&')
        nv = split(qsub, '=')
        res[nv[1]] = length(nv) > 1 ? nv[2] : ""
    end
    res
end

function pretty(j)
    iob = IOBuffer()
    JSON.print(iob, j, 4)
    String(take!(iob))
end

function login(oidcctx::OIDCCtx)
    openid_config = oidcctx.openid_config
    issuer = openid_config["issuer"]
    openid_config_url = issuer * ".well-known/openid-configuration"

    """

    """
end

function show_token(oidcctx::OIDCCtx, authresp, authenticated)
    id_token = authresp["id_token"]
    jwt = JWT(;jwt=id_token)
    isvalid = flow_validate_id_token(oidcctx, string(jwt))

    token_claims = claims(jwt)

    jbox_auth = Dict(
        "Authorization" => ("Bearer " * id_token)
    )

    authenticated[] = true
    can_refresh = "refresh_token" in keys(authresp)
    refresh_link = can_refresh ? """
Refresh""" : ""

    """
    OpenID Authentication:

$(pretty(authresp))

    JWT Token:

$(pretty(token_claims))

    Authentication Bearer Token:

$(pretty(jbox_auth))

    Validation success: $isvalid
    $(refresh_link)
    """
end

function token(oidcctx::OIDCCtx, req, authenticated)
    resp = query(req)
    code = resp["code"]
    authresp = flow_get_token(oidcctx, code)
    show_token(oidcctx, authresp, authenticated)
end

function refresh(oidcctx::OIDCCtx, req, authenticated)
    resp = query(req)
    refresh_token = resp["refresh_token"]
    authresp = flow_refresh_token(oidcctx, refresh_token)
    show_token(oidcctx, authresp, authenticated)
end

function main()
    if length(ARGS) != 1
        println("Usage: julia oidc_standalone.jl <configuration_file>")
        exit(1)
    end

    config = open(ARGS[1]) do f
            JSON.parse(f)
        end
    oidcctx = OIDCCtx(String(config["issuer"]), "http://127.0.0.1:8888/auth/login", String(config["client_id"]), String(config["client_secret"]), ["openid", "email", "profile", "offline_access"])
    authenticated = Ref(false)

    @app test = (
         Mux.defaults,
         page("/", req->login(oidcctx)),
         page("/auth/login", req->token(oidcctx, req, authenticated)),
         page("/auth/refresh", req->refresh(oidcctx, req, authenticated)),
         Mux.notfound())

    @info("Standalone OIDC test server starting on port 8888")
    serve(test, 8888)

    while config["do_refresh"] || !(authenticated[])
        sleep(10)
    end
    sleep(10)
end

main()


text:
using SIMD

function transpose_blocks!(data::AbstractVector{T}, ::Val{V}, ::Val{J}) where {T,V,J}
    block_size = V*J
    num_blocks = div(length(data), block_size)

    for k in 1:num_blocks
        block = ntuple(l->vload(Vec{V, T}, data, 1 + (k-1)*block_size + (l-1)*V), Val(J))
        transposed_block = transpose_vecs(block...)
        for v in 1:V
            vstore(transposed_block[v], data, 1 + (k-1)*block_size + (v-1)*J)
        end
    end
    data
end

"""In-place transpose of a 3 dimensional array VKJ into VJK."""
@generated function transpose!(data::AbstractVector{T}, ::Val{V}, ::Val{J}, ::Val{K}) where {T,V,J,K}
    seeds = find_transpose_cycles(Val(K), Val(J))
    :(transpose!(data, Val(V), Val(J), Val(K), $seeds))
end

@inline function transpose!(data::AbstractVector{T}, ::Val{V}, ::Val{J}, ::Val{K}, cycle_seeds) where {T,V,J,K}
    kjm = K*J-1
    @inbounds for c in cycle_seeds
        a = c
        base = pointer(data)
        vlen = V * sizeof(T)
        v1 = vloada(Vec{V, T}, base + vlen * a)
        while true
            pa = (a * K) % kjm
            if pa == c break end
            vpa = vload(Vec{V, T}, base + vlen * pa)
            vstore(vpa, base + vlen * a)
            a = pa
        end
        vstore(v1, base + vlen * a)
    end
    nothing
end

"""Find the cycle seeds to transpose a matrix with K rows and J columns into J rows and K columns."""
function find_transpose_cycles(::Val{J}, ::Val{K}) where {J,K}
    cycles = BitSet(1:K*J-2)
    cycle_seeds = Int32[]
    while length(cycles) > 0
        a = popfirst!(cycles)
        cmin = a
        while true
            pa = (a * K) % (K*J-1)
            if pa ∉ cycles break end
            cmin = min(cmin, pa)
            setdiff!(cycles, Set([pa]))
            a = pa
        end
        push!(cycle_seeds, cmin)
    end
    (cycle_seeds...,)
end

"""
    transpose_vecs(input::Vararg{Vec{N,T}, L}) where {L,N,T}

Transposes a matrix of L vectors of size N into N vectors of size L. Sizes should be powers of 2.
"""
@generated function transpose_vecs(input::Vararg{Vec{N,T}, L})::Vararg{N, Vec{L,T}} where {L,N,T}

    ex = Expr[Expr(:meta, :inline)]

    pa = Val(ntuple(a->((a-1)*N)%(2*N-1), Val(N)))
    pb = Val(ntuple(a->div(N,2)+((a-1)*N)%(2*N-1), Val(N)))

    for t in 1:L
        a1 = Symbol("input_", 0, "_", t)
        push!(ex, :($a1 = input[$t]))
    end

    nsteps = mylog(L)

    L_2 = div(L,2)

    for st in 1:nsteps
        for t in 1:L_2
            a1 = Symbol("input_", st-1, "_", t)
            a2 = Symbol("input_", st-1, "_", t+L_2)
            b1 = Symbol("input_", st, "_", t*2-1)
            b2 = Symbol("input_", st, "_", t*2)
            append!(ex, [:($b1 = shufflevector($a1, $a2, $pa)),
                         :($b2 = shufflevector($a1, $a2, $pb))])
        end
    end

    ## Reshape matrix if not square
    if N < L

        outsteps = mylog(div(L,N))
        for st in 1:outsteps
            pcat = Val(ntuple(a->a-1, N*2^st))
            for t in 1:N*2^(outsteps-st)
                a1 = Symbol("input_", nsteps+st-1, "_", t*2-1)
                a2 = Symbol("input_", nsteps+st-1, "_", t*2)
                b1 = Symbol("input_", nsteps+st, "_", t)
                push!(ex, :($b1 = shufflevector($a1, $a2, $pcat)))
            end
        end

        push!(ex, Expr(:tuple, ntuple(t->Symbol("input_", nsteps+outsteps, "_", t), Val(N))...))

    elseif N > L

        outsteps = mylog(div(N,L))
        for st in 1:outsteps
            pleft = Val(ntuple(a->a-1, div(N,2^st)))
            pright = Val(ntuple(a->a-1+div(N,2^st), div(N,2^st)))
            for t in 1:L*2^(st-1)
                a1 = Symbol("input_", nsteps+st-1, "_", t)
                b1 = Symbol("input_", nsteps+st, "_", t*2-1)
                b2 = Symbol("input_", nsteps+st, "_", t*2)
                append!(ex, [:($b1 = shufflevector($a1, $pleft)),
                             :($b2 = shufflevector($a1, $pright))])
            end
        end

        push!(ex, Expr(:tuple, ntuple(t->Symbol("input_", nsteps+outsteps, "_", t), Val(N))...))

    else

        push!(ex, Expr(:tuple, ntuple(t->Symbol("input_", nsteps, "_", t), Val(L))...))

    end

    quote $(ex...) end
end


text:
# Load data
data = parse.(Int, readlines("input.txt"))

# Part 1
ans1 = sum([data[i] > data[i-1] for i in 2:length(data)])
@info "Number of times depth measurement increases = $ans1"

# Part 2
ans2 = sum([sum(data[i-2:i]) > sum(data[i-3:i-1]) for i in 4:length(data)])
@info "Number of times the sum of a three-measurement window increases = $ans2"


text:
"""
Plot and animate a system evolving alongside its power spectrum
"""
function animatespectrum(S::Process; downsample=100, trail=1000, nwindows=20, phasogram=false, colorgradient=cgrad([:black, :crimson]), dpi=200, dospectrum=true, linewidth=1.5)
    # Phasogram really requires a high sampling period
    t = times(S)
    p = parameterseries(S)[end, :]
    X = timeseries(S)
    remainder = length(t)%nwindows
    X1X, t1t = [reshape(i[1:end-remainder], ((length(i)-remainder)÷nwindows, nwindows)) for i ∈ (vec(X[:, 1]), t)]
    bounds = mapslices(extrema, X, dims=1)
    x = vec(X[:, 1])
    y = vec(X[:, 2])
    if size(X, 2) > 3
        z = vec(X[:, 3])
    else
        z = fill(nothing, size(x))
    end
    xprev = zeros(size(x))
    anim = @animate for i = 1:downsample:length(x)
            print("\u1b[1GFrame $(i÷downsample)/$(length(x)÷downsample)")
            trailidxs = i-trail:i
            trailidxs = trailidxs[trailidxs .> 0]
            if isempty(trailidxs)
                trailidxs = [1]
            end
            widx = findfirst(mean(t1t, dims=1)[:].>=t[i])
            if isnothing(widx)
                widx = size(t1t, 2)
            end
            if dospectrum
                plot(t1t[:, widx], X1X[:, widx], seriestype=:spectrogram, teval=1, layout=(phasogram ? (@layout [a{0.8h}; b{0.65w} c{0.35w}]) : (@layout [a{0.7h}; b])), subplot=2, size=(1000, 1000), framestyle=:box, left_margin=10Plots.mm, ylims=(10^-5, 10^10), nwindows=1, axis=nothing, grid=true, colorbar=false, color=:black, gridlinewidth=4.0, dpi=dpi)
            end
            if phasogram
                # Gonna be very tricky here. Only take the top half of frequencies, and perform all sorts of rotations to get a nice visualisation
                alignshift = 0.0# -mean(x[Int(ceil(length(x)/2)):end]) # Becuase only relative phases really matter, rotate so that the phases betwene frames are mostly aligned
                alignreflect = 1.0 # sum(x .- xprev) > sum(x.+alignshift) ? -1.0 : 1.0 # Should we also reflect?
                plot!(t1t[:, widx], X1X[:, widx], seriestype=:spectrogram, teval=1, subplot=3, nwindows=1, phasogram=true, colorbar=nothing, topfreqs = nothing, axis=nothing, gridlinewidth=4.0, margin = 2Plots.mm, foreground_text_color=:white)
            end
            if size(X, 2) == 2
                plot!(x[trailidxs], y[trailidxs], z[trailidxs]; seriestype=:trail, subplot=1, axis=nothing, framestyle=:none, xlims=bounds[1].+[-0.1, 0.1], ylims=bounds[2].+[-0.1, 0.1], zlims=bounds[3].+[-0.1, 0.1], markersize=0.0, linez=p[trailidxs], clims=extrema(p), colorbar=nothing, color=colorgradient, linewidth)
            else
                plot!(x[trailidxs], y[trailidxs]; seriestype=:trail, subplot=1, axis=nothing, framestyle=:none, xlims=bounds[1].+[-0.1, 0.1], ylims=bounds[2].+[-0.1, 0.1], markersize=0.0, linez=p[trailidxs], clims=extrema(p), colorbar=nothing, color=colorgradient, symmetric=true, linewidth)
            end
            xprev = copy(x)
    end
    anim
end
export animatespectrum

# Plot the spectrogram of a time series as a heatmap. Optionally give a time at which to evaluate the spectrogram, in which case the plot will be a path.
@shorthands spectrogram
@recipe function f(::Type{Val{:spectrogram}}, x, y, z; teval=nothing, nwindows=20, nperseg=length(x)÷nwindows, phasogram=false, topfreqs=nothing)
    t = x
    Δt = (t[2] - t[1])
    fs = 1/Δt
    #@assert all((t[2:end] .- t[1:end-1]) .≈ Δt) # Check regularly sampled
    #𝑓, 𝑡, 𝑍 = stft(y; fs=fs, nperseg=nperseg)
    𝑓, 𝑡, 𝑍 = wft(y, t; nwindows)
    𝑡 .+= t[1]
    if phasogram # Show phases instead of spectrum
        S = angle.(𝑍)
        if !isnothing(topfreqs)
            idxs = Int(ceil(length(𝑓)/topfreqs)):length(𝑓)
            𝑓 = 𝑓[idxs]
            S = S[idxs, :]
        end
    else
        S = abs.(𝑍).^2
    end
    if isnothing(teval)
        seriestype := :heatmap
        if phasogram
            scale := :linear
            colorbar_title := "ϕ"
            z := Surface((S[2:end, 1:end-1]))
        else
            colorbar_title := "log₁₀(S)"
            z := Surface(log10.(S[2:end, 1:end-1]))
        end
        yscale --> :log
        x := 𝑡[1:end-1]
        y := 𝑓[2:end]
    else
        seriestype := (phasogram ? :phasogram : :path)
        _, tidx = findmin(abs.(𝑡.-teval))
        if phasogram
            title --> ""
            dolog := false
        else
            scale --> :log
            xguide --> "f"
            yguide --> "S"
            linewidth --> 2.5
        end
        legend --> nothing
        seriescolor --> :black
        x := 𝑓[2:end]
        y := S[2:end, tidx]
    end
    ()
end

@recipe function f(::Type{Val{:phasogram}}, x, y, z; dolog=false)
    projection := :polar
    seriestype := :scatter
    x := dolog ? y[x .> 0] : y
    y := dolog ? log10.(x[x .> 0]) .- min(log10.(x[x .> 0])...) : x
    markersize --> 2
    markercolor --> :black
    title --> (dolog ? "log₁₀(f)" : "f") #(dolog ? "log₁₀(f) + min[log₁₀(f)]" : "f")
    label --> nothing
    ()
end


text:
# ---
# title: 993. Cousins in Binary Tree
# id: problem993
# author: Tian Jun
# date: 2020-10-31
# difficulty: Easy
# categories: Tree, Breadth-first Search
# link: <https://leetcode.com/problems/cousins-in-binary-tree/description/>
# hidden: true
# ---
#
# In a binary tree, the root node is at depth `0`, and children of each depth
# `k` node are at depth `k+1`.
#
# Two nodes of a binary tree are _cousins_ if they have the same depth, but have
# **different parents**.
#
# We are given the `root` of a binary tree with unique values, and the values
# `x` and `y` of two different nodes in the tree.
#
# Return `true` if and only if the nodes corresponding to the values `x` and `y`
# are cousins.
#
#
#
# **Example 1:
# ![](https://assets.leetcode.com/uploads/2019/02/12/q1248-01.png)**
#
#
#
#     Input: root = [1,2,3,4], x = 4, y = 3
#     Output: false
#
#
# **Example 2:
# ![](https://assets.leetcode.com/uploads/2019/02/12/q1248-02.png)**
#
#
#
#     Input: root = [1,2,3,null,4,null,5], x = 5, y = 4
#     Output: true
#
#
# **Example 3:**
#
# **![](https://assets.leetcode.com/uploads/2019/02/13/q1248-03.png)**
#
#
#
#     Input: root = [1,2,3,null,4], x = 2, y = 3
#     Output: false
#
#
#
#
# **Constraints:**
#
#   * The number of nodes in the tree will be between `2` and `100`.
#   * Each node has a unique integer value from `1` to `100`.
#
#
## @lc code=start
using LeetCode

## add your code here:
## @lc code=end


text:
using ContourIntegrals

### Use expressions for the operators, noted in their respective csvs
file1 = "OperatorShifts/KerrNewman/TuekolskyShifts.csv"
file2 = "OperatorShifts/KerrNewman/TuekolskyFrequencyDerivative.csv"
T = OperatorShift(file1,file2)

### Get the integrand in the contour integral for the inner product computation
ψ = qnmfunctionnew(2,2,2,0,0.5)
weight = let r₊ = ψ.R.r₊ , r₋ = ψ.R.r₋ , s = ψ.s
    (r,z) -> ((r-r₊)*(r-r₋))^s
end
Ts = OperatorSandwich(ψ,T,weight,ψ)
δT = Ts.δT;
∂ωT = Ts.∂ωT;

### Compute the expressions so that they compile the first time
δT(2.2,0.1) |> println
∂ωT(2.2,0.1) |> println

### Define the useful contours
r₊ = ψ.R.r₊ ; r₋ = ψ.R.r₋ ; s = ψ.s ; Δr = 0.1*(r₊-r₋); ϵ = eps(0.1);

point1 = r₊ + Δr - Δr*im
point2 = r₊ - Δr - Δr*im

radial1 = SemiInfiniteLine(point1 , point1 + Δr*im , false)
angular = LineSegment(-1.0+100*ϵ , 1.0-100*ϵ , true) #to avoid the NaNs at the edges
C1 = radial1 ⊗ angular

radial2 = LineSegment(point1,point2,true)
C2 = radial2 ⊗ angular

radial3 = SemiInfiniteLine(point2 , point2 + Δr*im , true)
C3 = radial3 ⊗ angular

TheContour = C1⊕C2⊕C3

### Define Transformed Functions (that live on the compactified domain [0,1]⊗[0,1])
δTₒ = TransformIntegrand(δT , thedomain)
∂ωTₒ = TransformIntegrand(∂ωT , thedomain)

### Compute the expressions so that they compile the first time
δTₒ(0.1,0.1) |> println
∂ωTₒ(0.1,0.1) |> println

#=
### Use expressions for the operators, noted in their respective csvs
file1b = "OperatorShifts/KerrNewman0/TuekolskyShifts.csv"
file2b = "OperatorShifts/KerrNewman0/TuekolskyFrequencyDerivative.csv"
Tb = OperatorShift(file1b,file2b)

### Get the integrand in the contour integral for the inner product computation
Tsb = OperatorSandwich(ψ,Tb,weight,ψ)
δTb = Tsb.δT;
∂ωTb = Tsb.∂ωT;

### Compute the expressions so that they compile the first time
δTb(2.2,0.1) |> println
∂ωTb(2.2,0.1) |> println

### Define Transformed Functions (that live on the compactified domain [0,1]⊗[0,1])
δTbₒ = TransformIntegrand(δTb , thedomain)
∂ωTbₒ = TransformIntegrand(∂ωTb , thedomain)

### Compute the expressions so that they compile the first time
δTbₒ(0.1,0.1) |> println
∂ωTbₒ(0.1,0.1) |> println
=#

max_stars_repo_name: Potatoasad/KerrQNMShifts

max_issues_repo_name: Potatoasad/KerrQNMShifts

max_forks_repo_name: Potatoasad/KerrQNMShifts


text:
@testset "Day6.jl" begin
    # Write your tests here.
    lines = [
        "abc",
        "",
        "a",
        "b",
        "c",
        "",
        "ab",
        "ac",
        "",
        "a",
        "a",
        "a",
        "a",
        "",
        "b"]
    @test solve(Day6_1, lines) == 11

    @test solve(Day6_2, lines) == 6
end


text:
function _move_loop!(
    N::Integer,
    positions::AbstractArray,
    forces::AbstractArray,
    pot::PairwisePotential,
    energies::AbstractArray,
    interval::Integer,
    params;
    rdf = nothing,
    zfactor = nothing,
    msd = nothing,
)
    # * Main loop
    for i = 1:N
        # Always re-compute random numbers
        rng_matrix!(params.random_matrix, params.rng_list)

        # We check for the MeanSquaredDisplacement first as it needs special treatment
        # with the periodic boundary conditions
        if !isnothing(msd)
            ermak!(
                positions,
                forces,
                params.τ,
                params.boxl,
                params.random_matrix;
                pbc = false,
            )
            total_energy = energy_force!(positions, forces, params, pot)
            # We save positions in time here as needed by the MeanSquaredDisplacement
            if i % msd.interval == 0
                record_positions!(msd, positions, params.τ)
            end
        else
            # If it happens that we don't need the MeanSquaredDisplacement, then we proceed
            # moving the particles around
            ermak!(positions, forces, params.τ, params.boxl, params.random_matrix)

            # We check to see if we need to compute physical observables, if not
            # we just move particles around and check their energy
            if isnothing(rdf) && isnothing(zfactor)
                total_energy = energy_force!(positions, forces, params, pot)

                # We now check to see if the PairDistributionFunction is needed, if so
                # we step in and compute it
            elseif !isnothing(rdf)
                total_energy = energy_force!(positions, forces, params, pot; gofr = rdf)
                rdf.naverage += 1
                # If it so happens that the CompressibilityFactor needs to be computed
                # as well, we check to see if the object is passed and compute it
                if !isnothing(zfactor)
                    total_energy =
                        energy_force!(positions, forces, params, pot; zfactor = zfactor)
                    zfactor.naverage += 1
                end

                # If nothing but the CompressibilityFactor is needed, we compute it here
            elseif !isnothing(zfactor)
                total_energy =
                    energy_force!(positions, forces, params, pot; zfactor = zfactor)
                zfactor.naverage += 1
            end
        end

        # Finally, we check the interval and print the total energy
        # as well as save it
        if i % interval == 0
            @show total_energy
            idx = Int(i / interval)
            energies[idx] = total_energy
        end
    end

    # Lastly, we update the energy for the full system
    total_energy = energy_force!(positions, forces, params, pot)

    return total_energy
end

function _prepare(s::SimulationSystem, N::Integer, interval::Integer)
    # Allocate information for random values
    (_, rng_list) = _create_rngs(s.dims; seed = s.params.seed)
    random_matrix = zeros(typeof(s.boxl), size(s.system.positions))

    # Create an energy array to store values
    energy_size = Int(N / interval)

    # 2 dimensions because we only need the energy value and the movement number
    energies = zeros(energy_size, 2)

    # A collection of multiple parameters, it makes it easier to move it around
    # functions
    params = (
        N = s.params.N,
        rc = s.rc,
        boxl = s.boxl,
        rc2 = s.rc * s.rc,
        random_matrix = random_matrix,
        rng_list = rng_list,
        τ = s.params.τ,
    )

    return energies, params
end

function move!(N::Integer, s::SimulationSystem, pot::PairwisePotential; interval = 1000)
    # Retrieve system information
    @unpack positions, forces = s.system

    # Prepare all the arrays
    (energies, params) = _prepare(s, N, interval)

    # And then we move all the particles
    total_energy = _move_loop!(N, positions, forces, pot, energies, interval, params)
    # Lastly, we assign the system's energy
    s.energy = total_energy
end

function move!(
    N::Integer,
    s::SimulationSystem,
    pot::PairwisePotential,
    grobject::PairDistributionFunction;
    interval = 1000,
)
    # Retrieve system information
    @unpack positions, forces = s.system
    (energies, params) = _prepare(s, N, interval)

    # Pass in the PairDistributionFunction object and move particles
    total_energy =
        _move_loop!(N, positions, forces, pot, energies, interval, params; rdf = grobject)
    s.energy = total_energy

    # After all the statistics have been collected, we normalize the
    # PairDistributionFunction object
    grobject.naverage = N
    compute_rdf!(grobject, s)
end

function move!(
    N::Integer,
    s::SimulationSystem,
    pot::PairwisePotential,
    grobject::PairDistributionFunction,
    zfactor::ZFactor;
    interval = 1000,
)
    # Retrieve system information
    @unpack positions, forces = s.system
    (energies, params) = _prepare(s, N, interval)

    # Pass in the PairDistributionFunction and CompressibilityFactor objects
    total_energy = _move_loop!(
        N,
        positions,
        forces,
        pot,
        energies,
        interval,
        params;
        rdf = grobject,
        zfactor = zfactor,
    )

    # We compute the full CompressibilityFactor here
    zfactor.zval = compute_z(zfactor, s.params.N)

    # After all the statistics have been collected, we normalize the
    # PairDistributionFunction object
    grobject.naverage = N
    compute_rdf!(grobject, s)

    # Assign the full system's energy
    s.energy = total_energy
end

function move!(
    N::Integer,
    s::SimulationSystem,
    pot::PairwisePotential,
    zfactor::ZFactor;
    interval = 1000,
)
    # Retrieve system information
    @unpack positions, forces = s.system
    (energies, params) = _prepare(s, N, interval)
    total_energy = _move_loop!(
        N,
        positions,
        forces,
        pot,
        energies,
        interval,
        params;
        zfactor = zfactor,
    )
    # We compute the full CompressibilityFactor here
    zfactor.zval = compute_z(zfactor, s.params.N)

    # Assign the full system's energy
    s.energy = total_energy
end

function move!(
    N::Integer,
    s::SimulationSystem,
    pot::PairwisePotential,
    msd::MeanSquaredDisplacement;
    interval = 1000,
)
    # Retrieve system information
    @unpack positions, forces = s.system
    (energies, params) = _prepare(s, N, interval)
    _move_loop!(N, positions, forces, pot, energies, interval, params; msd = msd)

    # Compute and normalize the MeanSquaredDisplacement with all the recorded positions
    difusion!(msd)
end

function move!(
    N::Integer,
    s::SimulationSystem,
    pot::PairwisePotential,
    msd::MeanSquaredDisplacement,
    sft::SelfScatteringFunction;
    interval = 1000,
)
    # Retrieve system information
    @unpack positions, forces = s.system
    (energies, params) = _prepare(s, N, interval)
    _move_loop!(N, positions, forces, pot, energies, interval, params; msd = msd)

    # Copy the displacement vector from the MeanSquaredDisplacement to the
    # SelfScatteringFunction
    sft.dft[:, 1] = copy(msd.wt[:, 1])

    # Compute and normalize the MeanSquaredDisplacement and the SelfScatteringFunction
    # with all the recorded positions
    difusion!(msd, sft)
end


text:
"""
Synthesizing units bind multiple substrates to synthesize compounds,
depending on their availability
"""
abstract type AbstractSynthesizingUnit end

"""
    synthesizing_unit(::AbstractSynthesizingUnit, v, w)

Apply a synthesizing unit formulation to substrates
`v` and `w`, returning the amount of compound.
"""
function synthesizing_unit end

"""
    ParallelComplementarySU(k)

0-parameter synthesizing unit that merges two compounds stoichiometrically.

See Ledder et al 2019. for details.

$(FIELDDOCTABLE)
"""
struct ParallelComplementarySU <: AbstractSynthesizingUnit end

synthesizing_unit(::ParallelComplementarySU, v, w) = v * w * (v + w) / (v^2 + w^2 + v * w)

"""
    MinimumRuleSU(k)

0-parameter synthesizing unit where law of the minimum controls
the production of one compound form two other compounds.

$(FIELDDOCTABLE)
"""
struct MinimumRuleSU <: AbstractSynthesizingUnit end

synthesizing_unit(::MinimumRuleSU, v, w) = min(v, w)

"""
    KfamilySU(k)

Flexible 1-parameter synthesizing unit with variable curve. Both `MinimumRuleSU`
and `ParallelComplementarySU` can be approximated with this rule.

$(FIELDDOCTABLE)
"""
@columns struct KfamilySU{K} <: AbstractSynthesizingUnit
    k::K | 1.0 | _ | (0.0, 10.0)  | _ | "Synthesizing unit parameter. Effiency = 2^-1/k"
end

synthesizing_unit(f::KfamilySU, v, w) = (v^-f.k + w^-f.k)^(-1/f.k)

"""
    stoich_merge(Ja, Jb, ya, yb)

Merge fluxes stoichiometrically into general reserve Eab based on yield
fractions ya and yb. An unmixed proportion is returned as unmixed reserves Ea and Eb.
"""
stoich_merge(su, Jv, Jw, yv, yw) = begin
    JEvw = synthesizing_unit(su, Jv * yv, Jw * yw)
    (Jv - JEvw / yv), (Jw - JEvw / yw), JEvw
end


text:
# ✅ 1 https://github.com/MichaelHatherly/CommonMark.jl/blob/master/test/samples/cmark/inline-autolink.md
# ✅ 2 https://github.com/MichaelHatherly/CommonMark.jl/blob/master/test/samples/cmark/inline-backticks.md
# ✅ 3 https://github.com/MichaelHatherly/CommonMark.jl/blob/master/test/samples/cmark/inline-em-flat.md
# ✅ 4 https://github.com/MichaelHatherly/CommonMark.jl/blob/master/test/samples/cmark/inline-em-nested.md
# ✅ 5 https://github.com/MichaelHatherly/CommonMark.jl/blob/master/test/samples/cmark/inline-em-worst.md
# ✅ 6 https://github.com/MichaelHatherly/CommonMark.jl/blob/master/test/samples/cmark/inline-entity.md
# ✅ 7 https://github.com/MichaelHatherly/CommonMark.jl/blob/master/test/samples/cmark/inline-escape.md
# 🚫 8 https://github.com/MichaelHatherly/CommonMark.jl/blob/master/test/samples/cmark/inline-html.md
# ✅ 9 https://github.com/MichaelHatherly/CommonMark.jl/blob/master/test/samples/cmark/inline-links-flat.md
# ✅ 10 https://github.com/MichaelHatherly/CommonMark.jl/blob/master/test/samples/cmark/inline-links-nested.md
# 🚫 11 https://github.com/MichaelHatherly/CommonMark.jl/blob/master/test/samples/cmark/inline-newlines.md

@testset "1|autolinks" begin
    s = """
        closed (valid) autolinks:

        <ftp://1.2.3.4:21/path/foo>
        <http://foo.bar.baz?q=hello&id=22&boolean>
        <http://veeeeeeeeeeeeeeeeeeery.loooooooooooooooooooooooooooooooong.autolink/>
        <teeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeest@gmail.com>

        these are not autolinks:

        <ftp://1.2.3.4:21/path/foo
        <http://foo.bar.baz?q=hello&id=22&boolean
        <http://veeeeeeeeeeeeeeeeeeery.loooooooooooooooooooooooooooooooong.autolink
        <teeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeest@gmail.com
        < http://foo.bar.baz?q=hello&id=22&boolean >
        """
    b = s |> md_blockifier
    a = filter!(e -> e.name == :AUTOLINK, b)
    @test a[1] // "<ftp://1.2.3.4:21/path/foo>"
    @test a[2] // "<http://foo.bar.baz?q=hello&id=22&boolean>"
    @test a[3] // "<http://veeeeeeeeeeeeeeeeeeery.loooooooooooooooooooooooooooooooong.autolink/>"
    @test a[4] // "<teeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeest@gmail.com>"
    @test length(a) == 4
end

# XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX

@testset "2|backticks" begin
    s = """
        `lots`of`backticks`

        ``i``wonder``how``this``will``be``parsed``
        """
    b = s |> md_blockifier
    filter!(e -> !(e // "\n"), b)
    @test b[1] // "`lots`"
    @test b[2] // "`backticks`"
    @test b[3] // "``i``"
    @test b[4] // "``how``"
    @test b[5] // "``will``"
    @test b[6] // "``parsed``"
end

# XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX

@testset "3|em" begin
    s = """
        *this* *is* *your* *basic* *boring* *emphasis*

        _this_ _is_ _your_ _basic_ _boring_ _emphasis_

        **this** **is** **your** **basic** **boring** **emphasis**
        """
    b = s |> md_blockifier
    filter!(e -> !(e // "\n"), b)
    @test ct(b[1]) // "this"
    @test ct(b[2]) // "is"
    @test ct(b[3]) // "your"

    @test ct(b[7]) // "this"
    @test ct(b[8]) // "is"
    @test ct(b[9]) // "your"

    @test ct(b[13]) // "this"
    @test ct(b[14]) // "is"
    @test ct(b[15]) // "your"
end

# XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX

@testset "4|em2" begin
    s = """
        *this *is *a *bunch* of* nested* emphases*

        __this __is __a __bunch__ of__ nested__ emphases__

        ***this ***is ***a ***bunch*** of*** nested*** emphases***
        """
    b = s |> md_blockifier
    filter!(e -> !(e // "\n"), b)

    @test b[1] // "*this *is *a *bunch* of* nested* emphases*"
    @test b[2] // "__this __is __a __bunch__ of__ nested__ emphases__"
    @test b[3] // "***this ***is ***a ***bunch*** of*** nested*** emphases***"
end

# XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX

@testset "5|em3" begin
    b = """
        *this *is *a *worst *case *for *em *backtracking

        __this __is __a __worst __case __for __em __backtracking

        ***this ***is ***a ***worst ***case ***for ***em ***backtracking
        """ |> md_blockifier
    filter!(e -> !(e // "\n"), b)
    @test length(b) == 0
end

# XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX

@testset "6|entity" begin
    s = """
        entities:

          & © Æ Ď ¾ ℋ ⅆ ∲

        # Ӓ Ϡ &#98765432;

        non-entities:

        &18900987654321234567890; &1234567890098765432123456789009876543212345678987654;

        &qwertyuioppoiuytrewqwer; &oiuytrewqwertyuioiuytrewqwertyuioytrewqwertyuiiuytri;
        """
    t = s |> toks
    filter!(t -> t.name ∉ FP.MD_IGNORE, t)

    gt = [" ", "&", "©", "Æ", "Ď", "¾",
          "ℋ", "ⅆ", "∲",
          "#", "Ӓ", "Ϡ"]

    for i in 1:12
        @test t[i] // gt[i]
    end

    # NOTE: we do not validate the names, so the last two entities ARE caught as such
    # this does not have consequences though
    # however, we don't accept &#98765432; as it has too many chars.

    # fewer than 32 characters
    @test t[13] // "&qwertyuioppoiuytrewqwer;"

    # last one is not taken as it's more than 32.
end

# XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX

@testset "7|escapes" begin
    s = raw"""
        \!\"\#\$\%\&\'\*\+\,\.\/\:\;\<\=\>\?

        \@ \^ \_ \` \{ \| \} \~ \- \'

        <!--
        Not OK as clash with something else (latex/math/...)

            \t\e\s\t\i\n\g \e\s\c\a\p\e \s\e\q\u\e\n\c\e\s
            \\\(\)
            \[ \]
            \
            \\
            \\\
            \\\\
            \\\\\
        -->
        """
    b = s |> slice
    for (t, gt) in zip(filter(t -> t.name ∉ FP.MD_IGNORE, b[1].inner_tokens), [
                        raw"\!", raw"\#", raw"\$", raw"\%", raw"\&",
                        raw"\'", raw"\*", raw"\+", raw"\,", raw"\.",
                        raw"\/", raw"\:", raw"\;", raw"\<", raw"\=", raw"\>", raw"\?"])
        @test t // gt
    end
    for (t, gt) in zip(filter(t -> t.name ∉ FP.MD_IGNORE, b[4].inner_tokens), [
                        raw"\@", raw"\^", raw"\_", raw"\`", raw"\{",
                        raw"\|", raw"\}", raw"\~", raw"\-", raw"\'"])
        @test t // gt
    end
end

# XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX XXX

@testset "9|links" begin
    # cropped example as we're stricter than CM
    s = """
        Valid links:

         [this is a link]()
         [this is a link](<http://something.example.com/foo/bar>)
         [this is a link](http://something.example.com/foo/bar 'test')
         ![this is an image]()
         ![this is an image](<http://something.example.com/foo/bar>)
         ![this is an image](http://something.example.com/foo/bar 'test')
        """
    b = s |> md_blockifier
    filter!(!isempty, b)

    @test b[1] // "[this is a link]()"
    @test b[2] // "[this is a link](<http://something.example.com/foo/bar>)"
    @test b[3] // "[this is a link](http://something.example.com/foo/bar 'test')"
    @test b[4] // "![this is an image]()"
    @test b[5] // "![this is an image](<http://something.example.com/foo/bar>)"
    @test b[6] // "![this is an image](http://something.example.com/foo/bar 'test')"
end

@testset "10|links2" begin
    s = """
        Valid links:

        [[[[[[[[](test)](test)](test)](test)](test)](test)](test)]

        [ [[[[[[[[[[[[[[[[[[ [](test) ]]]]]]]]]]]]]]]]]] ](test)
        """
    b = s |> md_blockifier
    filter!(!isempty, b)
    @test b[1] // "[[[[[[[[](test)](test)](test)](test)](test)](test)](test)]"
    @test b[2] // "[ [[[[[[[[[[[[[[[[[[ [](test) ]]]]]]]]]]]]]]]]]] ](test)"
end


text:
# julia Gtk interface
module Gtk
#=it's na
if isdefined(Base, :Experimental) && isdefined(Base.Experimental, Symbol("@optlevel"))
    @eval Base.Experimental.@optlevel 1
end=#

# Import Binary Definitions (for building by a binary builder)
using GTK3_jll, Glib_jll # handmade collection of custom package Imports
using Xorg_xkeyboard_config_jll, gdk_pixbuf_jll, adwaita_icon_theme_jll, hicolor_icon_theme_jll #Gnome Imports
using Librsvg_jll #svg maker wrapper
using JLLWrappers #Julia Wrapper
using Pkg.Artifacts #ERROR: Unable to parse `Pkg.Artifacts` as a package.Fix using Artifacts
const libgdk = libgdk3
const libgtk = libgtk3
const libgdk_pixbuf = libgdkpixbuf

const suffix = :Leaf #define :leaf # concrete
#include(safe_path("GLib.jl")) # GLib/GLib.jl") #TODO: fix
#include("..\GLib.jl") #need to include Glib

using .GLib
using .GLib.MutableTypes
import .GLib: set_gtk_property!, get_gtk_property, getproperty, FieldRef
import .GLib:
    signal_connect, signal_handler_disconnect,
    signal_handler_block, signal_handler_unblock, signal_handler_is_connected,
    signal_emit, unsafe_convert,
    AbstractStringLike, bytestring

import Base: convert, show, run, size, resize!, length, getindex, setindex!,
             insert!, push!, append!, pushfirst!, pop!, splice!, delete!, deleteat!,
             parent, isempty, empty!, first, last, in, popfirst!,
             eltype, copy, isvalid, string, sigatomic_begin, sigatomic_end, (:), iterate

export showall, select!, start

using Reexport
@reexport using Graphics
import .Graphics: width, height, getgc

using Cairo
import Cairo: destroy
using Serialization

const Index{I<:Integer} = Union{I, AbstractVector{I}}
export GAccessor
#=TODO: add files ending with exports
include("basic_exports.jl")
include("long_exports.jl")
include("long_leaf_exports.jl")
=#

global const libgtk_version = VersionNumber(
      ccall((:gtk_get_major_version, libgtk), Cint, ()),
      ccall((:gtk_get_minor_version, libgtk), Cint, ()),
      ccall((:gtk_get_micro_version, libgtk), Cint, ()))

#= Required files (for Building GUI Items )
include("application.jl")
include("builder.jl") #3

include("interfaces.jl")
include("container.jl")
include("toolbar.jl") #5

include("boxes.jl")
include("buttons.jl") #4

include("gdk.jl") #1
include("gtktypes.jl")
include("cairo.jl") #2

include("base.jl")
include("gio.jl")
include("cairo.jl")

include("events.jl")
include("layout.jl")
include("lists.jl")
include("displays.jl")

include("text.jl")
include("menus.jl")
include("selectors.jl")
include("theme.jl")
include("misc.jl")

=#
function __init__()
    # Set XDG_DATA_DIRS so that Gtk can find its icons and schemas
    ENV["XDG_DATA_DIRS"] = join(filter(x -> x !== nothing, [
            dirname(adwaita_icons_dir),
            dirname(hicolor_icons_dir),
            joinpath(dirname(GTK3_jll.libgdk3_path::String), "..", "share"),
            get(ENV, "XDG_DATA_DIRS", nothing)::Union{String,Nothing},
        ]), Sys.iswindows() ? ";" : ":")

    # Next, ensure that gdk-pixbuf has its loaders.cache file; we generate a
    # MutableArtifacts.toml file that maps in a loaders.cache we dynamically
    # generate by running `gdk-pixbuf-query-loaders:`
    mutable_artifacts_toml = joinpath(dirname(@__DIR__), "MutableArtifacts.toml")
    loaders_cache_name = "gdk-pixbuf-loaders-cache"
    loaders_cache_hash = artifact_hash(loaders_cache_name, mutable_artifacts_toml)
    loaders_dir_name = "gdk-pixbuf-loaders-dir"
    loaders_dir_hash = artifact_hash(loaders_dir_name, mutable_artifacts_toml)

    if loaders_cache_hash === nothing
        if Librsvg_jll.is_available()
            # Copy loaders into a directory
            loaders_dir_hash = create_artifact() do art_dir
                loaders_dir = mkdir(joinpath(art_dir, "loaders_dir"))
                pixbuf_loaders = joinpath.(gdk_pixbuf_loaders_dir, readdir(gdk_pixbuf_loaders_dir))
                push!(pixbuf_loaders, Librsvg_jll.libpixbufloader_svg)
                cp.(pixbuf_loaders, joinpath.(loaders_dir, basename.(pixbuf_loaders)))
            end

            loaders_dir = joinpath(artifact_path(loaders_dir_hash), "loaders_dir")
            # Pkg removes "execute" permissions on Windows
            Sys.iswindows() && chmod(artifact_path(loaders_dir_hash), 0o755; recursive = true)#grant access to msft
            # Run gdk-pixbuf-query-loaders, capture output
            loader_cache_contents = gdk_pixbuf_query_loaders() do gpql
                withenv("GDK_PIXBUF_MODULEDIR" => loaders_dir, JLLWrappers.LIBPATH_env => Librsvg_jll.LIBPATH[]) do
                    return String(readchomp(`$gpql`))
                end
            end

            bind_artifact!(mutable_artifacts_toml,
                loaders_dir_name,
                loaders_dir_hash;
                force = true
            )
        else  # just use the gdk_pixbuf directory
            loader_cache_contents = gdk_pixbuf_query_loaders() do gpql
                withenv("GDK_PIXBUF_MODULEDIR" => gdk_pixbuf_loaders_dir) do
                    return String(read(`$gpql`))
                end
            end
        end
        # Write cache out to file in new artifact
        loaders_cache_hash = create_artifact() do art_dir
            open(joinpath(art_dir, "loaders.cache"), "w") do io
                write(io, loader_cache_contents)
            end
        end
        bind_artifact!(mutable_artifacts_toml,
            loaders_cache_name,
            loaders_cache_hash;
            force = true
        )
    end

    # Point gdk to our cached loaders
    ENV["GDK_PIXBUF_MODULE_FILE"] = joinpath(artifact_path(loaders_cache_hash), "loaders.cache")
    ENV["GDK_PIXBUF_MODULEDIR"] = Librsvg_jll.is_available() && loaders_dir_hash !== nothing ?
                                  joinpath(artifact_path(loaders_dir_hash), "loaders_dir") :
                                  gdk_pixbuf_loaders_dir

    if Sys.islinux() || Sys.isfreebsd()
        # Needed by xkbcommon:
        # https://xkbcommon.org/doc/current/group__include-path.html.  Related
        # to issue https://github.com/JuliaGraphics/Gtk.jl/issues/469
        ENV["XKB_CONFIG_ROOT"] = joinpath(Xorg_xkeyboard_config_jll.artifact_dir::String,
            "share", "X11", "xkb")
    end

    GError() do error_check #Gerror not Defined
        ccall((:gtk_init_with_args, libgtk), Bool,
            (Ptr{Nothing}, Ptr{Nothing}, Ptr{UInt8}, Ptr{Nothing}, Ptr{UInt8}, Ptr{Ptr{GError}}),
            C_NULL, C_NULL, "Julia Gtk Bindings", C_NULL, C_NULL, error_check)
    end

    # if g_main_depth > 0, a glib main-loop is already running
    # unfortunately, this call does not reliably reflect the state after the
    # loop has been stopped (or restarted), so only use it once at the start
    gtk_main_running[] = ccall((:g_main_depth, GLib.libglib), Cint, ()) > 0

    # Given GLib provides `g_idle_add` to specify what happens during idle, this allows
    # that call to also start the eventloop
    GLib.gtk_eventloop_f[] = enable_eventloop

    auto_idle[] = get(ENV, "GTK_AUTO_IDLE", "true") == "true"

    # by default, defer starting the event loop until either `show`, `showall`, or `g_idle_add` is called (during Idle)
    # this allows that call to also start the eventloop
    #GLib.gtk_eventloop_f[] = enable_eventloop
    enable_eventloop(!auto_idle[])
end

const auto_idle = Ref{Bool}(true) # control default via ENV["GTK_AUTO_IDLE"] #TODO:check if changed in latest version
const gtk_main_running = Ref{Bool}(false)
const quit_task = Ref{Task}()
const enable_eventloop_lock = Base.ReentrantLock()

"""
1. thread handling: the use of lock:
    Gtk.enable_eventloop(b::Bool = true)
Shortcomming: on lock, only one thread can passs by; in this function (it's gotta be the event loop)

2.Set whether Gtk's event loop is running
"""
function enable_eventloop(b::Bool = true; wait_stopped::Bool = false)
    lock(enable_eventloop_lock) do # handle widgets (that are being displayed/destructed by different threads)

        isassigned(quit_task) && wait(quit_task[]) #flag check - on special event: Prevents starting, while the asynch is still stopping
                    if b
                        if !is_eventloop_running()
                            global gtk_main_task = schedule(Task(gtk_main)) #Warning: changed: gtk_main_task → gtk_main
                            gtk_main_running[] = true #set `all` true
                        end

        else
            if is_eventloop_running()
                # @async & short sleep as needed on MacOS, otherwise
                # the Window doesn't always finish closing before the eventloop stops
                # @async and short sleep is needer on MacOS at least, otherwise
                # the window doesn't always finish closing before the eventloop stops.
                quit_task[] = @async begin
                    sleep(0.2)
                    gtk_quit()
                    gtk_main_running[] = false # negate `all` running threads
                end
                wait_stopped && wait(quit_task[])
            end
        end
    end
end

# Given GLib provides `g_idle_add` to specify what happens during idle, this allows
# that call to also start the eventloop
GLib.gtk_eventloop_f[] = enable_eventloop

#const auto_idle = Ref{Bool}(true) # control default via ENV["GTK_AUTO_IDLE"]
auto_idle[] = get(ENV, "GTK_AUTO_IDLE", "true") == "true"

    #const enable_eventloop_lock = Base.ReentrantLock()
    # by default, defer starting the event loop until either `show`, `showall`, or `g_idle_add` is called
                quit_task[] = @async begin

                    sleep(0.2)
                    gtk_quit()
                    gtk_main_running[] = false
                end
                wait_stopped && wait(quit_task[])
            #=end
        end
    end=#
end

"""
    Gtk.pause_eventloop(f; force = false)

Pauses the eventloop around a function. Restores the state of the eventloop after
pausing. Respects whether Gtk.jl is configured to allow auto-stopping of the
eventloop, unless `force = true`.
"""
function pause_eventloop(f; force = false)
    was_running = is_eventloop_running()
    (force || auto_idle[]) && enable_eventloop(false, wait_stopped = true)
    try
        f()
    finally
        (force || auto_idle[]) && enable_eventloop(was_running)
    end
end

"""
    Gtk.is_eventloop_running()::Bool

Check whether Gtk's event loop is running.
"""
is_eventloop_running() = gtk_main_running[]

const ser_version = Serialization.ser_version
let cachedir = joinpath(splitdir(@__FILE__)[1], "..", "gen")
    fastgtkcache = joinpath(cachedir, "gtk$(libgtk_version.major)_julia_ser$(ser_version)")
    if isfile(fastgtkcache) & true #old error && was a boolean Literal
        open(fastgtkcache) do cache
            while !eof(cache)
                Core.eval(Gtk, deserialize(cache))
            end
        end
    else
        gboxcache = joinpath(cachedir, "gbox$(libgtk_version.major)")
        map(eval, include(gboxcache).args)
        constcache = joinpath(cachedir, "gconsts$(libgtk_version.major)")
        map(eval, include(constcache).args)
    end
end
const _ = GAccessor #TODO: No Definition for GAcessor (Gnome Accessor) #Infer: Gnome wrapper package
using .GConstants
#= TODO:UncommentMe
include("windows.jl")
include("gl_area.jl")
=#
if Base.VERSION >= v"1.4.2"
  #=  include("precompile.jl") =#
    _precompile_()
end

# Alternative Interface (`using Gtk.ShortNames`)
module ShortNames
using .Gtk
import GLib:
    signal_connect, signal_handler_disconnect,
    signal_handler_block, signal_handler_unblock, signal_handler_is_connected,
    signal_emit
import GLib.@g_type_delegate
import Gtk: suffix
#export Gtk
#= TODO: fix the following files before Uncomenting #UncommentMe
    include("basic_exports.jl")
    include("short_exports.jl")
    include("short_leaf_exports.jl")
=##enforce Using the .ShortNames
end
using .ShortNames
end

max_stars_repo_name: adamwillisMastery/MiniGtk

max_issues_repo_name: adamwillisMastery/MiniGtk

max_forks_repo_name: adamwillisMastery/MiniGtk


text:
function DiffEqBase.__solve(
    prob::DiffEqBase.AbstractODEProblem{uType,tType,isinplace},
    alg::AlgType,
    timeseries=[],ts=[],ks=[];
    verbose=true,
    save_start=true, dt = nothing,
    timeseries_errors=true,
    callback=nothing, alias_u0=false, kwargs...) where {uType,tType,isinplace,AlgType<:GeometricIntegratorAlgorithm}

    if dt == nothing
        error("dt required for fixed timestep methods.")
    end

    N = ceil(Int,(prob.tspan[end]-prob.tspan[1]) / dt)

    isstiff = !(typeof(alg) <: Union{GIImplicitEuler,GIImplicitMidpoint,GIRadIIA2,
                                     GIRadIIA3,GISRK3,GIGLRK})

    if verbose
        warned = !isempty(kwargs) && check_keywords(alg, kwargs, warnlist)
        if !(typeof(prob.f) <: DiffEqBase.AbstractParameterizedFunction) && isstiff
            if DiffEqBase.has_tgrad(prob.f)
                warn("Explicit t-gradient given to this stiff solver is ignored.")
                warned = true
            end
            if DiffEqBase.has_jac(prob.f)
                warn("Explicit Jacobian given to this stiff solver is ignored.")
                warned = true
            end
        end
        warned && warn_compat()
    end

    if callback != nothing
        error("GeometricIntegrators is not compatible with callbacks.")
    end

    u0 = prob.u0

    if typeof(u0) <: Number
        u = [u0]
    else
        if alias_u0
            u = u0
        else
            u = deepcopy(u0)
        end
    end

    if typeof(u) <: Tuple
        sizeu = size(u[1])
    else
        sizeu = size(u)
    end

    p = prob.p

    if !isinplace && typeof(u)<:AbstractArray
        f! = (t,u,du) -> (du[:] = vec(prob.f(reshape(u,sizeu),p,t)); nothing)
    elseif !(typeof(u)<:Vector{Float64})
        f! = (t,u,du) -> (prob.f(reshape(du,sizeu),reshape(u,sizeu),p,t); nothing)
    elseif typeof(prob.problem_type) <: DiffEqBase.StandardODEProblem
        f! = (t,u,du) -> prob.f(du,u,p,t)
    end

    _alg = get_tableau_from_alg(alg)
    if typeof(prob.problem_type) <: DiffEqBase.StandardODEProblem
        ode = ODE(f!, vec(prob.u0))
    elseif typeof(prob.problem_type) <: DiffEqBase.AbstractDynamicalODEProblem
        ode = PODE((t,u,v,du)->prob.f.f2(du,v,u,t),
                   (t,u,v,dv)->prob.f.f1(dv,v,u,t),
                   vec(prob.u0.x[1]),vec(prob.u0.x[2]))
    end
    integrator = Integrator(ode,_alg,dt)
    sol = integrate(integrator, N)

    if save_start
        start_idx = 1
        ts = prob.tspan[1]:dt:prob.tspan[end]
    else
        start_idx = 2
        ts = (prob.tspan[1]+dt):dt:prob.tspan[end]
    end

    if typeof(u0) <: DiffEqBase.RecursiveArrayTools.ArrayPartition
        _timeseries = Vector{typeof(u0.x[1])}(undef,0)
        for i=start_idx:(sol.q.nt+1)
            push!(_timeseries, reshape(view(sol.q, :, i-1)', length(u0.x[1])))
        end
    elseif typeof(u0) <: Union{AbstractArray}
        _timeseries = Vector{uType}(undef,0)
        for i=start_idx:(sol.q.nt+1)
            push!(_timeseries, reshape(view(sol.q, :, i-1)', sizeu))
        end
    else
        _timeseries = vec(sol.q)
    end

    DiffEqBase.build_solution(prob,  alg, ts, _timeseries,
                   timeseries_errors = timeseries_errors,
                   retcode = :Success)
end

function get_tableau_from_alg(alg)
    typeof(alg) == GIEuler && (_alg = getTableauExplicitEuler())
    typeof(alg) == GIMidpoint && (_alg = getTableauExplicitMidpoint())
    typeof(alg) == GIHeun && (_alg = getTableauHeun())
    typeof(alg) == GIKutta && (_alg = getTableauKutta())
    typeof(alg) == GIERK4 && (_alg = getTableauERK4())
    typeof(alg) == GIERK438 && (_alg = getTableauERK438())
    typeof(alg) == GIImplicitEuler && (_alg = getTableauImplicitEuler())
    typeof(alg) == GIImplicitMidpoint && (_alg = getTableauImplicitMidpoint())
    typeof(alg) == GIRadIIA2 && (_alg = getTableauRadIIA2())
    typeof(alg) == GIRadIIA3 && (_alg = getTableauRadIIA3())
    typeof(alg) == GISRK3 && (_alg = getTableauSRK3())
    typeof(alg) == GIGLRK && (_alg = getTableauGLRK(alg.s))
    typeof(alg) == GISymplecticEulerA && (_alg = getTableauSymplecticEulerA())
    typeof(alg) == GISymplecticEulerB && (_alg = getTableauSymplecticEulerB())
    typeof(alg) == GILobattoIIIAIIIB2 && (_alg = getTableauLobattoIIIAIIIB2())
    typeof(alg) == GILobattoIIIBIIIA2 && (_alg = getTableauLobattoIIIBIIIA2())
    _alg
end


text:
using ...Octo

# keywords
using .Octo.AdapterBase:
    ADD, ALL, ALTER, AND, AS, ASC, BEGIN, BETWEEN, BIGINT, BY, COMMIT, COLUMN, CONSTRAINT, CREATE, DATABASE, DEFAULT, DELETE, DESC, DISTINCT, DROP, EXCEPT, EXECUTE, EXISTS, FOREIGN, FROM, FULL, GROUP,
    HAVING, IF, IN, INDEX, INNER, INSERT, INTERSECT, INTO, IS, JOIN, KEY, LEFT, LIKE, LIMIT, NULL, OFF, OFFSET, ON, OR, ORDER, OUTER, OVER,
    PARTITION, PREPARE, PRIMARY, RECURSIVE, REFERENCES, RELEASE, RIGHT, ROLLBACK, SAVEPOINT, SELECT, SET, TABLE, TO, TRANSACTION, TRIGGER, UNION, UPDATE, USING, VALUES, WHERE, WITH

# aggregate functions
using .Octo.AdapterBase: AVG, COUNT, EVERY, MAX, MIN, NOT, SOME, SUM

# ranking functions
using .Octo.AdapterBase: DENSE_RANK, RANK, ROW_NUMBER

#                                     ()        ?
using .Octo.AdapterBase: Field, Raw, Enclosed, PlaceHolder, VectorOfTuples
using .Octo.AdapterBase: Structured, SubQuery, _to_sql
import .Octo.AdapterBase: _placeholder, _placeholders

using .Octo.DBMS
using .Octo.Repo
using .Octo.Schema
using .Octo.Pretty
using .Octo: @sql_keywords, @sql_functions
using .Octo.Queryable: from, as


text:
module FlightMechanicsSimulator

using DataFrames
using NLsolve
using OrdinaryDiffEq
using StaticArrays
using SimulationLogs

using FlightMechanicsUtils

import Base: eltype

export ConstantInput, StepInput, DoubletInput, RampInput, SinusoidalInput, get_value
include("models/inputs.jl")

export ISA1976, F16StevensAtmosphere
export get_density, get_height, get_pressure, get_sound_velocity, get_temperature
include("models/atmosphere.jl")

export LHDownGravity
export get_gravity_accel, get_gravity_body, get_gravity_horizon
include("models/gravity.jl")

export Aircraft
export get_mass, get_inertia_tensor, get_xcg_mac
export get_chord, get_surface, get_wing_span, get_aspect_ratio
export calculate_prop_forces_moments, calculate_prop_gyro_effects, calculate_pdot
export calculate_aero_forces_moments
export tgear
include("models/aircraft.jl")

export DSState, DSStateDot
export get_x, get_n_states, get_x_names, state_eqs
export get_xdot, get_ds_state
export get_earth_position, get_height
export get_euler_angles
export get_tas, get_α, get_β, get_tasαβ
export get_body_velocity, get_horizon_velocity
export get_ang_vel_body, get_euler_angles_rates
export get_engine_power
export get_tas_dot, get_α_dot, get_β_dot, get_tasαβ_dot
export get_accel_body
export get_ang_accel_body
export get_engine_power_dot
include("models/dynamic_system.jl")

export SixDOFAeroEuler
export sixdof_aero_earth_euler_fixed_mass
include("dynamics/sixdof_aero_euler.jl")

export SixDOFBodyEuler
export sixdof_body_earth_euler_fixed_mass
include("dynamics/sixdof_body_euler.jl")

export trim
include("trimmer.jl")

export simulate
export f
include("simulation.jl")

export F16
export F16Stevens
include("F16Stevens/F16Stevens.jl")  # F16 submodule
using .F16Stevens

end


text:
#
# @description Unit tests for RC4 stream-cipher.
#
# @author Alejandro Claro (alejandro.claro@gmail.com)
#
# Copyright 2017 All rights reserved.
# Use of this source code is governed by a MIT-style license that can be found in the LICENSE file.
#
@testset "RC4 cipher tests" begin
  cipher = Rc4Cipher([ 0x01, 0x02, 0x03, 0x04, 0x05 ])

  @test key_size(cipher) == 5

  @test_throws ArgumentError Rc4Cipher(UInt8[])
  @test_throws ArgumentError Rc4Cipher(zeros(UInt8, 33))

  @test encrypt!(cipher, [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]) == UInt8[ 0xb2, 0x39, 0x63, 0x05, 0xf0, 0x3d, 0xc0, 0x27 ]

  reset!(cipher)

  @test decrypt!(cipher, UInt8[ 0xb2, 0x39, 0x63, 0x05, 0xf0, 0x3d, 0xc0, 0x27 ]) == [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
end


text:
include("perm.jl")

using GLVisualize

window = glscreen()
view(visualize(GLNormalMesh(poly2)), window)
renderloop(window)


text:
# This file contains the normplot function

# load packages
using PyPlot
using Distributions

# normplot

doc"""
    normplot(x)

Normal probability plot.
"""
function normplot(x::Vector)

  x = sort(x)
  p_i = zeros(length(x))
  z_i = zeros(length(x))
  prob_i = zeros(length(x))

  n = length(x)

  a = 1/3

  for i = 1:n
    p_i[i] = (i-a)/(n-a+1)
    z_i[i] = quantile(Normal(0,1), p_i[i])
    prob_i[i] = cdf(Normal(0,1), z_i[i])
  end

  PyPlot.figure(figsize=(7,5))
  PyPlot.plot(x, z_i, "b*")
  PyPlot.xlabel("Data")
  PyPlot.ylabel("Quantile")

  #=
  PyPlot.figure()
  PyPlot.plot(x, prob_i, "b*")
  PyPlot.xlabel("Data")
  PyPlot.ylabel("Probability")
  PyPlot.yscale("log")
  =#

end

max_stars_repo_name: SamuelWiqvist/adamcmcpaper

max_issues_repo_name: SamuelWiqvist/adamcmcpaper

max_forks_repo_name: SamuelWiqvist/adamcmcpaper


text:
using Oceananigans.Operators: Δzᶜᶜᶜ, Δzᶜᶜᶠ

"""
Update the hydrostatic pressure perturbation pHY′. This is done by integrating
the `buoyancy_perturbation` downwards:

    `pHY′ = ∫ buoyancy_perturbation dz` from `z=0` down to `z=-Lz`
"""
@kernel function _update_hydrostatic_pressure!(pHY′, grid, buoyancy, C)
    i, j = @index(Global, NTuple)

    @inbounds pHY′[i, j, grid.Nz] = - ℑzᵃᵃᶠ(i, j, grid.Nz+1, grid, z_dot_g_b, buoyancy, C) * Δzᶜᶜᶠ(i, j, grid.Nz+1, grid)

    @unroll for k in grid.Nz-1 : -1 : 1
        @inbounds pHY′[i, j, k] = pHY′[i, j, k+1] - ℑzᵃᵃᶠ(i, j, k+1, grid, z_dot_g_b, buoyancy, C) * Δzᶜᶜᶠ(i, j, k+1, grid)
    end
end

update_hydrostatic_pressure!(model) = update_hydrostatic_pressure!(model.grid, model)

update_hydrostatic_pressure!(::AbstractGrid{<:Any, <:Any, <:Any, <:Flat}, model) = nothing

update_hydrostatic_pressure!(grid, model) = update_hydrostatic_pressure!(model.pressures.pHY′, model.architecture, model.grid, model.buoyancy, model.tracers)

function update_hydrostatic_pressure!(pHY′, arch, grid, buoyancy, tracers)
    pressure_calculation = launch!(arch, grid, :xy, _update_hydrostatic_pressure!,
                                   pHY′, grid, buoyancy, tracers,
                                   dependencies = Event(device(arch)))

    # Fill halo regions for pressure
    wait(device(arch), pressure_calculation)

    fill_halo_regions!(pHY′, arch)
    return nothing
end


text:
"
This script contains the functions to evaluate the expectation values ⟨Â⟩ for the displaced oscillator

The parameters to be given are: ω, λ, g, γ, α, and a list of sampled times t, plus r and θ for the squeezed states

"

export ann_a, num_a, quad_a, quads_a, nums_a

"`quad_a(α, λ, ω, γ, t)` evaluate the position quadrature operator average for the coherent state. α ∈ Complex"
quad_a(α, λ, ω, γ, t) = (α + (λ/ω)) * exp(-γ * t * (1 - exp(1im * ω/γ))) + (conj(α) + (λ/ω)) * exp(-γ * t * (1 - exp(-1im * ω/γ))) - 2 * (λ/ω)

"`num_a(α, λ, ω, γ, t)` evaluate the number operator average for the coherent state. α ∈ Complex"
num_a(α, λ, ω, γ, t) = abs2(α) + (λ/ω) * (α + conj(α)) + 2 * (λ/ω)^2 - (λ/ω) * ((α + (λ/ω)) * exp(-γ * t * (1 - exp(1im * ω/γ))) + (conj(α) + (λ/ω)) * exp(-γ * t * (1 - exp(-1im * ω/γ))))

# Squeezed coefficients
μ(r) = cosh(r)
ν(r, θ) = exp(1im * θ) * sinh(r)

"`quads_a(α, r, θ, λ, ω, γ, t)` evaluate the position quadrature operator average for the squeezed state. α ∈ Complex"
quads_a(α, r, θ, λ, ω, γ, t) = (μ(r) * conj(α) + conj(ν(r, θ)) * α + (λ/ω)) * exp(-γ * t * (1 - exp(1im * ω/γ))) + (μ(r) * α + ν(r, θ) * conj(α) + (λ/ω)) * exp(-γ * t * (1 - exp(-1im * ω/γ))) - 2 * (λ/ω)

# Number operator squeezed coefficients
ncf1(r, θ, α) = (μ(r)^2 + abs2(ν(r, θ))) * abs2(α)
ncf2(r, θ, α) = μ(r) * (ν(r, θ) * conj(α)^2 + conj(ν(r, θ)) * α^2)
ncf3(r, θ, α) = (μ(r) - conj(ν(r, θ))) * α + (μ(r) - ν(r, θ)) * conj(α)
ncf4(r, θ, α) = μ(r) * conj(α) - conj(ν(r, θ)) * α
ncf5(r, θ, α) = μ(r) * α - ν(r, θ) * conj(α)

"`nums_a(α, r, θ, λ, ω, γ, t)` evaluate the number operator average for the squeezed state. α ∈ Complex"
nums_a(α, r, θ, λ, ω, γ, t) = (ncf1(r, θ, α) - ncf2(r, θ, α) + (λ/ω) * ncf3(r, θ, α) + 2 * (λ/ω)^2 + abs2(ν(r, θ))) - (λ/ω) * ((ncf4(r, θ, α) + (λ/ω)) * exp(-γ * t * (1 - exp(1im * ω/γ))) + (ncf5(r, θ, α) + (λ/ω)) * exp(-γ * t * (1 - exp(-1im * ω/γ))))

max_stars_repo_name: rurz/IntrinsicDecoherence

max_issues_repo_name: rurz/IntrinsicDecoherence

max_forks_repo_name: rurz/IntrinsicDecoherence


text:
using BenchmarkTools

struct Polymer
    init::String
    rules::Dict{String,Tuple{String,String}}
end

function Base.iterate(p::Polymer, state=Dict{String,Int}())
    if isempty(state)
        state = Dict(p.init[i:(i + 1)] => 1 for i in 1:(length(p.init) - 1))
        state[p.init[end:end]] = 1
    end
    tmpdict = Dict{String,Int}()
    for (k, v) in state
        if haskey(p.rules, k)
            tmpdict[first(p.rules[k])] = get!(tmpdict, first(p.rules[k]), 0) + v
            tmpdict[last(p.rules[k])] = get!(tmpdict, last(p.rules[k]), 0) + v
        else
            tmpdict[k] = get!(tmpdict, k, 0) + v
        end
    end
    state = tmpdict
    lettercounts = zeros(Int, 26)
    for (k, v) in state
        lettercounts[k[begin] - 'A' + 1] += v
    end
    filter!(k -> k > 0, lettercounts)
    return maximum(lettercounts) - minimum(lettercounts), state
end

function day14()
    part = [0, 0]
    lines = strip.(readlines("AoCdata/AoC_2021_day14.txt"))
    template, rulelines = lines[begin], lines[(begin + 2):end]
    rules = Dict(
        s[begin:(begin + 1)] => (s[begin] * s[end], s[end] * s[begin + 1]) for
        s in rulelines
    )

    poly = Polymer(template, rules)
    for (i, diff) in enumerate(poly)
        if i == 10
            part[1] = diff
        elseif i == 40
            part[2] = diff
            break
        end
    end

    return part
end

part = day14()
println("Part 1: ", part[1])
println("Part 2: ", part[2])

@btime day14()

#=
Part 1: 2170
Part 2: 2422444761283
  851.600 μs (1004 allocations: 303.16 KiB)
=#


text:
"""
# module HyperCollate

- Julia version:
- Author: bramb
- Date: 2019-02-20

# Examples

```jldoctest
julia>using HyperCollate
```
"""
module HyperCollate

    export
        tokenize,
        to_graph,
        to_dot,
        string_value,
        Collation,add_witness!,collate!,needs_witness,ready_to_collate,is_collated,
        ranking,
        add_subst,
        show_svg,show_png
#         xp_parse,
#         create_an_array_of_the_xml_nodes,
#         convert_to_xml_blocks,
#         transform_block_into_text_nodes_named_tuple,
#         get_triples,group_triples,serialize_grouped_triples,to_graph

#     include("xmlparser.jl")
    include("parser3.jl")
    include("xml_preprocessor.jl")
    include("collater.jl")
    include("display.jl")

end


text:
using LinearSolve
using Documenter

DocMeta.setdocmeta!(LinearSolve, :DocTestSetup, :(using LinearSolve); recursive=true)

makedocs(
    sitename="LinearSolve.jl",
    authors="Chris Rackauckas",
    modules=[LinearSolve],
    clean=true,doctest=false,
    format = Documenter.HTML(#analytics = "UA-90474609-3",
                             assets = ["assets/favicon.ico"],
                             canonical="https://linearsolve.sciml.ai/stable/"),
    pages=[
        "Home" => "index.md",
        "Tutorials" => Any[
            "tutorials/linear.md"
            "tutorials/caching_interface.md"
        ],
        "Basics" => Any[
            "basics/LinearProblem.md",
            "basics/common_solver_opts.md",
            "basics/CachingAPI.md",
            "basics/Preconditioners.md",
            "basics/FAQ.md"
        ],
        "Solvers" => Any[
            "solvers/solvers.md"
        ],
        "Advanced" => Any[
            "advanced/developing.md"
        ]
    ]
)

deploydocs(;
    repo="github.com/SciML/LinearSolve.jl",
    devbranch="main",
)


text:
inpt = """AlphaCentauri to Snowdin = 66
AlphaCentauri to Tambi = 28
AlphaCentauri to Faerun = 60
AlphaCentauri to Norrath = 34
AlphaCentauri to Straylight = 34
AlphaCentauri to Tristram = 3
AlphaCentauri to Arbre = 108
Snowdin to Tambi = 22
Snowdin to Faerun = 12
Snowdin to Norrath = 91
Snowdin to Straylight = 121
Snowdin to Tristram = 111
Snowdin to Arbre = 71
Tambi to Faerun = 39
Tambi to Norrath = 113
Tambi to Straylight = 130
Tambi to Tristram = 35
Tambi to Arbre = 40
Faerun to Norrath = 63
Faerun to Straylight = 21
Faerun to Tristram = 57
Faerun to Arbre = 83
Norrath to Straylight = 9
Norrath to Tristram = 50
Norrath to Arbre = 60
Straylight to Tristram = 27
Straylight to Arbre = 81
Tristram to Arbre = 90"""
places = Vector{ASCIIString}()
for line in split(inpt, '\n')
	p1 = split(line)[1]
	p2 = split(line)[3]
	if !(p1 in places)
		push!(places, p1)
	end
	if !(p2 in places)
		push!(places, p2)
	end
end

distances = zeros(Int64, (length(places), length(places)))
println(inpt)
println(places)
for line in split(inpt, '\n')
	place1 = split(line)[1]
	place2 = split(line)[3]
	dist = parse(Int, split(line)[end])
	println(place1, place2, dist)
	i = findfirst(places, place1)
	j = findfirst(places, place2)
	distances[i,j] = dist
	distances[j,i] = dist
end
println(distances)

shortest = (0, places)
for p in permutations(places)
	sum = 0
	for city in 2:length(p)
		i = findfirst(places, p[city])
		j = findfirst(places, p[city-1])
		sum += distances[i, j]
	end
	if sum > shortest[1]
		shortest = (sum, p)
	end
end

println(shortest)

max_stars_repo_name: jstrube/adventofcode

max_issues_repo_name: jstrube/adventofcode

max_forks_repo_name: jstrube/adventofcode


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

@doc raw"""ObjectMetricSource indicates how to scale on a metric describing a kubernetes object (for example, hits-per-second on an Ingress object).

    IoK8sApiAutoscalingV2beta1ObjectMetricSource(;
        averageValue=nothing,
        metricName=nothing,
        selector=nothing,
        target=nothing,
        targetValue=nothing,
    )

    - averageValue::IoK8sApimachineryPkgApiResourceQuantity : averageValue is the target value of the average of the metric across all relevant pods (as a quantity)
    - metricName::String : metricName is the name of the metric in question.
    - selector::IoK8sApimachineryPkgApisMetaV1LabelSelector : selector is the string-encoded form of a standard kubernetes label selector for the given metric When set, it is passed as an additional parameter to the metrics server for more specific metrics scoping When unset, just the metricName will be used to gather metrics.
    - target::IoK8sApiAutoscalingV2beta1CrossVersionObjectReference : target is the described Kubernetes object.
    - targetValue::IoK8sApimachineryPkgApiResourceQuantity : targetValue is the target value of the metric (as a quantity).
"""
mutable struct IoK8sApiAutoscalingV2beta1ObjectMetricSource <: SwaggerModel
    averageValue::Any # spec type: Union{ Nothing, IoK8sApimachineryPkgApiResourceQuantity } # spec name: averageValue
    metricName::Any # spec type: Union{ Nothing, String } # spec name: metricName
    selector::Any # spec type: Union{ Nothing, IoK8sApimachineryPkgApisMetaV1LabelSelector } # spec name: selector
    target::Any # spec type: Union{ Nothing, IoK8sApiAutoscalingV2beta1CrossVersionObjectReference } # spec name: target
    targetValue::Any # spec type: Union{ Nothing, IoK8sApimachineryPkgApiResourceQuantity } # spec name: targetValue

    function IoK8sApiAutoscalingV2beta1ObjectMetricSource(;averageValue=nothing, metricName=nothing, selector=nothing, target=nothing, targetValue=nothing)
        o = new()
        validate_property(IoK8sApiAutoscalingV2beta1ObjectMetricSource, Symbol("averageValue"), averageValue)
        setfield!(o, Symbol("averageValue"), averageValue)
        validate_property(IoK8sApiAutoscalingV2beta1ObjectMetricSource, Symbol("metricName"), metricName)
        setfield!(o, Symbol("metricName"), metricName)
        validate_property(IoK8sApiAutoscalingV2beta1ObjectMetricSource, Symbol("selector"), selector)
        setfield!(o, Symbol("selector"), selector)
        validate_property(IoK8sApiAutoscalingV2beta1ObjectMetricSource, Symbol("target"), target)
        setfield!(o, Symbol("target"), target)
        validate_property(IoK8sApiAutoscalingV2beta1ObjectMetricSource, Symbol("targetValue"), targetValue)
        setfield!(o, Symbol("targetValue"), targetValue)
        o
    end
end # type IoK8sApiAutoscalingV2beta1ObjectMetricSource

const _property_map_IoK8sApiAutoscalingV2beta1ObjectMetricSource = Dict{Symbol,Symbol}(Symbol("averageValue")=>Symbol("averageValue"), Symbol("metricName")=>Symbol("metricName"), Symbol("selector")=>Symbol("selector"), Symbol("target")=>Symbol("target"), Symbol("targetValue")=>Symbol("targetValue"))
const _property_types_IoK8sApiAutoscalingV2beta1ObjectMetricSource = Dict{Symbol,String}(Symbol("averageValue")=>"IoK8sApimachineryPkgApiResourceQuantity", Symbol("metricName")=>"String", Symbol("selector")=>"IoK8sApimachineryPkgApisMetaV1LabelSelector", Symbol("target")=>"IoK8sApiAutoscalingV2beta1CrossVersionObjectReference", Symbol("targetValue")=>"IoK8sApimachineryPkgApiResourceQuantity")
Base.propertynames(::Type{ IoK8sApiAutoscalingV2beta1ObjectMetricSource }) = collect(keys(_property_map_IoK8sApiAutoscalingV2beta1ObjectMetricSource))
Swagger.property_type(::Type{ IoK8sApiAutoscalingV2beta1ObjectMetricSource }, name::Symbol) = Union{Nothing,eval(Base.Meta.parse(_property_types_IoK8sApiAutoscalingV2beta1ObjectMetricSource[name]))}
Swagger.field_name(::Type{ IoK8sApiAutoscalingV2beta1ObjectMetricSource }, property_name::Symbol) =  _property_map_IoK8sApiAutoscalingV2beta1ObjectMetricSource[property_name]

function check_required(o::IoK8sApiAutoscalingV2beta1ObjectMetricSource)
    (getproperty(o, Symbol("metricName")) === nothing) && (return false)
    (getproperty(o, Symbol("target")) === nothing) && (return false)
    (getproperty(o, Symbol("targetValue")) === nothing) && (return false)
    true
end

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


text:
function update_v!(k::Int, s::State, c::Constants, d::Data)
  sumZk = sum(s.Z[:, k])
  newA = s.alpha / c.K + sumZk
  newB = 1 + d.J - sumZk

  s.v[k] = rand(Beta(newA, newB))
end

function update_v_sb!(k::Int, s::State, c::Constants, d::Data, tuners::Tuners)
  lp(vk::Float64) = log(s.alpha) + (s.alpha - 1.0) * log(vk)

  function ll(vk::Float64)
    new_v = deepcopy(s.v)
    new_v[k] = vk
    b = cumprod(new_v)

    out = 0.0
    for j in 1:d.J
      for q in k:c.K
        if s.Z[j, q]
          out += log(b[q])
        else
          out += log1p(-b[q])
        end
      end
    end

    return out
  end

  log_prob(vk::Float64) = ll(vk) + lp(vk)

  s.v[k] = MCMC.metLogitAdaptive(s.v[k], log_prob, tuners.v[k])
end

function update_v!(s::State, c::Constants, d::Data,
                   tuners::Tuners, sb_ibp::Bool)
  for k in 1:c.K
    if sb_ibp
      update_v_sb!(k, s, c, d, tuners)
    else
      update_v!(k, s, c, d)
    end
  end

  # Truncate v_k's for numerical stability in update_alpha
  clamp!(s.v, 1e-6, 1 - 1e-6)
end


text:
using RMatrix
using Test

@testset "RMatrix.jl" begin
    # Write your tests here.
end


text:
using Crazyflie
using ProgressMeter

# temporary
using PyCall
using DelimitedFiles

function reset_estimator(cf)
    cf.param.set_value("kalman.resetEstimation", "1")
    sleep(0.1)
    cf.param.set_value("kalman.resetEstimation", "0")
    lconfig = logger.LogConfig(name="Kalman Variance", period_in_ms=500)
    lconfig.add_variable("kalman.varPX", "float")
    lconfig.add_variable("kalman.varPY", "float")
    lconfig.add_variable("kalman.varPZ", "float")
    varx = ones(10)*1000
    vary = ones(10)*1000
    varz = ones(10)*1000
    record(cf, lconfig) do logs
        for entry in logs
            data = entry[2]
            push!(varx, data["kalman.varPX"])
            push!(vary, data["kalman.varPY"])
            push!(varz, data["kalman.varPZ"])
            popfirst!(varx); popfirst!(vary); popfirst!(varz)
            threshx = (maximum(varx) - minimum(varx)) < 0.001
            threshy = (maximum(vary) - minimum(vary)) < 0.001
            threshz = (maximum(varz) - minimum(varz)) < 0.001
            if threshx && threshy && threshz
                break
            end
        end
    end
end

function enable_commander(cf)
    cf.param.set_value("commander.enHighLevel", "1")
    cf.high_level_commander
end

# because commander.land is not reliable
function land(commander, duration)
    print("Landing\n")
    for i = 1:10
        commander.land(0.0, duration)
        sleep(0.1)
    end
    sleep(duration)
    commander.stop()
end

# because commander.takeoff is not reliable
function takeoff(commander, height, duration)
    print("Taking Off\n")
    for i = 1:5
        commander.takeoff(height, duration)
        sleep(0.1)
    end
    sleep(duration)
end

function hover(uri="radio://0/80/2M")
    play(uri) do cf
        commander = enable_commander(cf)
        reset_estimator(cf)
        takeoff(commander, 1.0, 2.0) # height, duration
        sleep(5.0)
        land(commander, 5.0) # duration
    end
    return nothing
end


text:
# Doesn't really make sense to precompile this!
__precompile__(false)
module GLBooks

# GL packages
import GLVisualize
using GeometryTypes, GLWindow

using Colors, Images, Reactive, FileIO
import GLVisualize: mm, layoutscreens, IRect, _view, visualize, glscreen
import GLVisualize: x_partition_abs, loadasset
import GLWindow: hide!, show!

const _icon_size = Signal(9mm)
icon_size() = value(_icon_size)

function play_controls(screen)
    # load the icons
    paths = [
        "rewind_inactive.png", "rewind_active.png",
        "back_inactive.png", "back_active.png",
    ]

    imgs = map(paths) do path
        img = convert(Matrix{RGBA{N0f8}}, loadasset(path))
        img, flipdim(img, 2)
    end
    # create buttons
    iconrect = IRect(0, 0, icon_size(), icon_size())
    buttons = [
        GLVisualize.toggle_button(imgs[1][1], imgs[2][1], screen; primitive = iconrect),
        GLVisualize.button(imgs[3][1], screen; primitive = iconrect),
        GLVisualize.button(imgs[3][2], screen; primitive = iconrect),
        GLVisualize.toggle_button(imgs[1][2], imgs[2][2], screen; primitive = iconrect),
    ]
    visual = visualize(
        map(first, buttons), direction = 1
    )
    signals = map(last, buttons)
    visual, signals
end

global edit_screen, view_screen, widgetlist, new_block, init

global _block_position = 0
const navigation = []
const parent_screen = Ref{Screen}()
const blocklist = Screen[]
const current_widgetlist = []

edit_screen() = blocklist[_block_position].children[1]
view_screen() = blocklist[_block_position].children[2]
widgetlist() = current_widgetlist[_block_position]

step_page(dir) = max(mod1(dir, length(blocklist)), 1)

function handle_drop(files::Vector{String})
    for f in files
        try
            drawpage(load(f))
        catch e
            warn(e)
        end
    end
end

function init()
    global _block_position
    _block_position = 0
    parent_screen[] = glscreen()
    @async GLWindow.renderloop(parent_screen[])
    empty!(blocklist)
    for list in current_widgetlist
        for (nameobj, s) in list
            close(s, false)
        end
    end
    empty!(current_widgetlist)
    if !isempty(navigation) # old signals in there
        for s in navigation[end]
            close(s, false) # close old signal
        end
        empty!(navigation)
    end
    push!(navigation, play_controls(parent_screen[])...)
    s1 = map(handle_drop, parent_screen[].inputs[:dropped_files])
    position = 1
    control_s = map(zip(navigation[2], [-1, -1, 1, 1])) do sdir
        s, dir = sdir
        map(s, init = nothing) do s
            position = if s && !isempty(blocklist)
                for (i, block) in enumerate(blocklist)
                    position == i ? show!(block) : hide!(block)
                end
                step_page(position + dir)
            else
                position
            end
            _block_position = position
            nothing
        end
    end
    push!(control_s, s1)
    push!(navigation, control_s)
end
function new_block()
    global _block_position
    _block_position += 1
    hidden = !isempty(blocklist) # only show first block
    parent = Screen(parent_screen[], hidden = Signal(hidden)) # copy screen, to make it easier to save!
    editarea, viewarea = x_partition_abs(parent.area, round(Int, 8 * icon_size()))
    edit_screen = Screen(parent, area = editarea)
    view_screen = Screen(parent, area = viewarea, name = :GLBook)
    GLVisualize.add_screen(view_screen) # make screen available
    edit_screen.stroke = (1, RGBA(0.9f0, 0.9f0, 0.9f0))
    push!(current_widgetlist, Any[("navigation" => copy(navigation[1]), Signal(0))])
    push!(blocklist, parent)
    return view_screen
end

function playbutton(name)
    visual, signal = GLVisualize.playbutton(edit_screen())
    signal = map(!, signal)
    push!(widgetlist(), (name => visual, signal))
    signal
end
function playbutton(f, name)
    signal = playbutton(name)
    preserve(map(f, signal))
end

function slider(range, name; slider_length = 5*icon_size(), kw_args...)
    visual, signal = GLVisualize.labeled_slider(
        range, edit_screen(); slider_length = slider_length, kw_args...
    )
    push!(widgetlist(), (name => visual, signal))
    signal
end
function slider(f::Function, range, name; kw_args...)
    signal = slider(range, name; kw_args...)
    s2 = map(f, signal)
    s2
end

function drawpage(x, style = :default; kw_args...)
    _view(visualize(x, style; kw_args...), view_screen())
end

macro block(title, block)
    last, view_screen = gensym(), gensym()
    esc(quote
        let
            $view_screen = GLBooks.new_block()

            $last = $(block)

            push!(GLBooks.widgetlist(), ("title:" => visualize($title), Signal(0)))

            # TODO make this a GLVisualize function e.g., isvisualizable
            if applicable(GLVisualize._default, $last, GLAbstraction.Style{:default}(), Dict{Symbol,Any}())
                GLBooks.drawpage($last)
            end
            widgets = convert(Vector{Pair}, map(first, GLBooks.widgetlist()))
            GLVisualize._view(GLVisualize.visualize(
                widgets,
                text_scale = 4*GLVisualize.mm,
                width = 8*GLBooks.icon_size()
            ), GLBooks.edit_screen(), camera = :fixed_pixel)

            for cam in keys($view_screen.cameras)
                GLAbstraction.center!($view_screen, cam) # TODO, don't center corrupt bb's
            end
            $last
        end
    end)
end

export @block, slider, drawpage, playbutton

end # module


text:
function login()

end

login()