text:
export  nodeCompositionReport

"""
```
nodeCompositionReport(
    mpSim::MPsim,
    timeGrid::Vector{Float64},
    nodes::String... )
```
This function generates a report on the composition of the nodes in `nodes` of the manpower simulation `mpSim`. The reports are generated on the grid of time points `timeGrid`, and the nodes can be any base or compound node.

This function will issue a warning and not generate any report in the following two cases:
1. There are no positive time points in the time grid;
2. None of the entered nodes are actual nodes in the simulation.

This function returns a `Dict{String, DataFrame}`, where the keys are the valid nodes, and the value is the composition report for that node. The base nodes are bundled in a single report with name `"Base nodes"`. In case the function issues a warning, its return value will be an empty dictionary.
"""
function nodeCompositionReport( mpSim::MPsim, timeGrid::Vector{Float64},
    nodes::String... )::Dict{String,DataFrame}

    result = Dict{String,DataFrame}()

    if now( mpSim ) == 0
        @warn "Simulation hasn't started yet, can't make report."
        return result
    end  # if now( mpSim ) == 0

    timeGrid = timeGrid[0.0 .<= timeGrid .<= now( mpSim )]
    timeGrid = unique( sort( timeGrid, rev = true ) )

    if isempty( timeGrid )
        @warn "No valid time points in time grid, cannot generate report."
        return result
    end  # if isempty( timeGrid )

    if timeGrid[end] > 0.0
        push!( timeGrid, 0.0 )
    end  # if timeGrid[end] > 0.0

    reverse!( timeGrid )

    nodes = filter( collect( nodes ) ) do nodeName
        return haskey( mpSim.baseNodeList, nodeName ) ||
            haskey( mpSim.compoundNodeList, nodeName )
    end  # filter( nodes ) do nodeName

    if isempty( nodes )
        @warn "No valid nodes in node list, cannot generate report."
        return result
    end  # if isempty( nodes )

    nodes = unique( nodes )

    # Get a population report on all the base nodes and component base nodes of
    #   the compound nodes.
    baseNodes = generateBaseNodeList( mpSim, nodes )
    baseNodeReport = nodePopReport( mpSim, timeGrid, baseNodes... )

    # Split off the report for the base nodes in the original list.
    isBaseNode = haskey.( Ref( mpSim.baseNodeList ), nodes )

    if any( isBaseNode )
        baseNodeList = nodes[isBaseNode]
        result["Base nodes"] = baseNodeReport[:, vcat( :timePoint,
            Symbol.( baseNodeList ) )]
    end  # if any( isBaseNode )

    # Generate the report for the compound nodes.
    for node in nodes[.!isBaseNode]
        result[node] = generateCompositionReport(
            mpSim.compoundNodeList[node], baseNodeReport )
    end  # for node in nodes[.!isBaseNode]

    return result

end  # nodeCompositionReport( mpSim, timeGrid, nodes )

"""
```
nodeCompositionReport(
    mpSim::MPsim,
    timeRes::Real,
    nodes::String... )
```
This function generates a report on the composition of the nodes in `nodes` of the manpower simulation `mpSim`. The reports are generated on a grid of time points with resolution `timeRes`, and the nodes can be any base or compound node.

This function will issue a warning and not generate any report in the following two cases:
1. The resolution of the time grid is ⩽ 0;
2. None of the entered nodes are actual nodes in the simulation.

This function returns a `Dict{String, DataFrame}`, where the keys are the valid nodes, and the value is the composition report for that node. The base nodes are bundled in a single report with name `"Base nodes"`. In case the function issues a warning, its return value will be an empty dictionary.
"""
nodeCompositionReport( mpSim::MPsim, timeRes::Real, nodes::String... ) =
    nodeCompositionReport( mpSim, generateTimeGrid( mpSim, timeRes ), nodes... )

include( joinpath( repPrivPath, "nodecomposition.jl" ) )


text:
"""
Three bouncing balls
q = (z1,z2,z3), u = (z1dot, z2dot, z3dot),
g(q) = (q[1],q[2],q[3])
W = del g / del q = I (3 x 3 identity)
M = [m1 0 0; 0 m2 0; 0 0 m3]
h = [-m1*g; -m2*g; -m3*g]
"""

using LinearAlgebra
using PyPlot
using TimeStepping

const m1 = m2 = m3 = 1.0
const g = 9.81
final_time = 2.0
q0 = [0.8; 1.0; 1.2]
u0 = [0.5; 2.0; -0.2]

function gap(q::AbstractArray, u::AbstractArray)
    return q, Matrix(1.0f0*I, 3, 3)
end

function dynamics(q::AbstractArray, u::AbstractArray)
    return convert.(Float32, [m1 0 0; 0 m2 0; 0 0 m3]), convert.(Float32, [-m1*g; -m2*g; -m3*g])
end

three_bb = Integrator(gap, dynamics, convert.(Float32, q0), convert.(Float32, u0); Δt=convert(Float32, 1e-3), ε=0.5f0)
integrate(three_bb, final_time)

fig = figure(1, clear=true)
fig.add_subplot(1,1,1)
fig.axes[1].clear()
fig.axes[1].plot(three_bb.t, getindex.(three_bb.q,1), "b", linewidth=2, label="ball 1")
fig.axes[1].plot(three_bb.t, getindex.(three_bb.q,2), "k", linewidth=2, label="ball 2")
fig.axes[1].plot(three_bb.t, getindex.(three_bb.q,3), "m", linewidth=2, label="ball 3")

fig.axes[1].set_title("Three bouncing balls", fontsize=18)
fig.axes[1].set_xlabel(L"$t$", fontsize=18)
fig.axes[1].set_ylabel(L"$z(t)$", fontsize=18)
fig.axes[1].legend(loc="best", fontsize="x-large")

fig.axes[1].autoscale_view()
fig.tight_layout()

ext: jl


text:
mutable struct ACWRPowerModel <: PowerModels.AbstractWRModel
    PowerModels.@pm_fields
end

function PowerModels.variable_bus_voltage(pm::ACWRPowerModel; kwargs...)
    variable_bus_voltage_magnitude_sqr(pm; kwargs...)
    variable_buspair_voltage_product(pm; kwargs...)

    nw = pm.cnw
    PowerModels.var(pm, nw)[:vr] = JuMP.@variable(
        pm.model,
        [i in PowerModels.ids(pm, nw, :bus)],
        base_name="$(nw)_vr",
        start = PowerModels.comp_start_value(PowerModels.ref(pm, nw, :bus, i), "vr_start", 1.0))
    PowerModels.var(pm, nw)[:vi] = JuMP.@variable(
        pm.model,
        [i in PowerModels.ids(pm, nw, :bus)],
        base_name="$(nw)_vi",
        start = PowerModels.comp_start_value(PowerModels.ref(pm, nw, :bus, i), "vi_start"))
end

function PowerModels.constraint_model_voltage(pm::ACWRPowerModel, n::Int)
    w  = var(pm, n, :w)
    wr = var(pm, n, :wr)
    wi = var(pm, n, :wi)
    vr = var(pm, n, :vr)
    vi = var(pm, n, :vi)
    for i in ids(pm, n, :bus)
        JuMP.@constraint(pm.model, w[i] == vr[i]^2 + vi[i]^2)
    end
    for (i,j) in ids(pm, n, :buspairs)
        JuMP.@constraint(pm.model, wr[(i,j)] == vr[i] * vr[j] + vi[i] * vi[j])
        JuMP.@constraint(pm.model, wi[(i,j)] == vi[i] * vr[j] - vr[i] * vi[j])
    end
end

build_acwr(data_file::String) = instantiate_model(PowerModels.parse_file(data_file), ACWRPowerModel, PowerModels.build_opf)


text:
#
# Static site generator for Tensor Network website
#

include("bibtex.jl")

function pause()
  a = readline(STDIN)
  (length(a) == 0) && return
  (a[1]=='q') && exit(0)
end

#
# Process citations
#
function processCitations(html::String)::Tuple{String,Dict{String,Int}}
  cite_re = r"\\(cite|onlinecite){(.+?)}"s
  citenums = Dict{String,Int}()
  res = String("")
  pos = 1
  match = false
  counter = 1
  for m in eachmatch(cite_re,html)
    match = true
    res *= html[pos:m.offset-1]
    names = split(convert(String,m.captures[2]),",")
    namenums = Tuple{Int,String,String}[]
    for name in names
      name = strip(name)
      if haskey(citenums,name)
        num = citenums[name]
      else
        citenums[name] = counter
        num = counter
        counter += 1
      end
      push!(namenums,(num,name,convert(String,m.captures[1])))
    end
    sort!(namenums, by = x -> x[1])
    for i in 1:length(namenums)
      (num,name,cmd) = namenums[i]
      if cmd == "cite"
        res *= "[$num]"
      elseif cmd == "onlinecite"
        res *= "$num"
        if i < length(namenums) res *= ", " end
      end
    end
    pos = m.offset+length(m.match)
  end
  if !match
    return (html,citenums)
  else
    res *= html[pos:end]
  end
  return (res,citenums)
end

#
# Process MathJax
#
function processMathJax(html::String)
  mj_re = r"(\@\@.+?\@\@|\$.+?\$|\\begin{equation}.+?\\end{equation}|\\begin{equation\*}.+?\\end{equation\*}|\\begin{align}.+?\\end{align})"s
  mjlist = String[]
  res = ""
  pos = 1
  match = false
  for m in eachmatch(mj_re,html)
    match = true
    res *= html[pos:m.offset-1]
    #res *= "\n\n
"*m.captures[1]*"
\n\n"
    push!(mjlist,m.captures[1])
    res *= "(MathJax$(length(mjlist)))"
    pos = m.offset+length(m.match)
  end
  if match
    res *= html[pos:end]
  else
    res = html
  end
  return (res,mjlist)
end

function restoreMathJax(html::String,mjlist::Array{String,1})
  res = html
  for (n,mj) in enumerate(mjlist)
    res = replace(res,"(MathJax$n)" => mj)
  end
  return res
end

#
# Process wiki-style links
#
function processWikiLinks(html::String,ifname::String)
  link_re = r"\[\[(.+?)\|(.*?)\]\]"
  sub_re = r"(.*?)(#.*)"
  missing_links = String[]
  res = ""
  pos = 1
  match = false
  for m in eachmatch(link_re,html)
    match = true
    res *= html[pos:m.offset-1]
    target = convert(String,m.captures[2])

    #If link has a "#" in it, split into target and sublink
    sublink = ""
    for sm in eachmatch(sub_re,target)
      target = convert(String,sm.captures[1])
      sublink = convert(String,sm.captures[2])
    end

    if isdir("src/"*target)
      res *= "["*m.captures[1]*"](/"*target*"/$sublink)"
    elseif isfile("src/"*target*".md")
      res *= "["*m.captures[1]*"](/"*target*".html$sublink)"
    else
      res *= "["*m.captures[1]*"](unknown_file)"
      push!(missing_links,target)
    end
    pos = m.offset+length(m.match)
  end
  if length(missing_links) > 0
    println("Missing/Incorrect Wiki Links in File $ifname:")
    for link in missing_links
      println("  $link")
    end
  end
  if !match
    return html
  else
    res *= html[pos:end]
  end
  return res
end

#
# Process arxiv preprint links
#
function processArxivLinks(html::String)
  link_re = r"(arxiv|cond-mat|quant-ph|math|math-ph|physics)[/:]\W*?([\d\.]+)"i
  res = ""
  pos = 1
  match = false
  for m in eachmatch(link_re,html)
    match = true
    res *= html[pos:m.offset-1]
    prefix = m.captures[1]
    number = m.captures[2]
    if lowercase(prefix) == "arxiv"
      res *= "arxiv:[$number](https://arxiv.org/abs/$number)"
    else
      nbprefix = replace(prefix,"-" => "‑") #non-breaking hypen
      res *= "$nbprefix/[$number](https://arxiv.org/abs/$prefix/$number)"
    end
    pos = m.offset+length(m.match)
  end
  if !match
    return html
  else
    res *= html[pos:end]
  end
  return res
end
function processCondMatLinks(html::String)
  link_re = r"arxiv:\W*?(\d+?\.\d+)"
  res = ""
  pos = 1
  match = false
  for m in eachmatch(link_re,html)
    match = true
    res *= html[pos:m.offset-1]
    res *= "arxiv:["*m.captures[1]*"](https://arxiv.org/abs/"*m.captures[1]*")"
    pos = m.offset+length(m.match)
  end
  if !match
    return html
  else
    res *= html[pos:end]
  end
  return res
end

function printEditFooter(of::IOStream,fname::String)
  template_edit_footer = open("template_edit_footer.html") do file read(file,String) end
  link = "https://github.com/TensorNetwork/tensornetwork.org/edit/master/"*fname
  out = replace(template_edit_footer,r"{github_link}" => link)
  print(of,out)
end

function generateRefs(citenums,btentries)
  keys = Array{String,1}(undef,length(citenums))
  for (k,v) in citenums
    keys[v] = k
  end
  rhtml = "\n"
  rhtml *= "## References\n"
  for (n,k) in enumerate(keys)
    if haskey(btentries,k)
      bt = btentries[k]
      rhtml *= "$n. "*convertToMD(bt)
      rhtml *= "\n"
    end
  end
  return rhtml
end

#
# Generate a Table of Contents if Requested
#
function generateTOC(input::String,has_refs::Bool)
  toc_re = r""is
  if occursin(toc_re,input)
    output = ""
    toc_html = "\n\n\n
\n"
    toc_html *= "Table of Contents

\n"
    lev = 1
    sec_re = r"\n(#+)(.*)"
    count = 1
    pos = 1
    for m in eachmatch(sec_re,input)
      nlev = length(m.captures[1])
      output *= input[pos:m.offset-1]
      if nlev > 1
        output *= " \n"
        name = strip(convert(String,m.captures[2]))
        name = replace(name,r"\\cite{.*?}" => "")
        name = replace(name,r"\\onlinecite{.*?}" => "")
        for n in 1:nlev toc_html *= "  " end
        if nlev == lev+1
          toc_html *= "
"
        elseif nlev == lev-1
          toc_html *= "
"
        end
        toc_html *= "
$name
\n"
        lev = nlev
        count += 1
      end
      output *= m.match
      pos = m.offset+length(m.match)
    end
    while lev != 2
      lev -= 1
      toc_html *= "
"
    end
    if has_refs
      toc_html *= "
References
\n"
    end
    toc_html *= "

\n\n\n"
    output *= input[pos:end]
    #println(toc_html)
    return replace(output,toc_re => toc_html)
  end
  return input
end

header_prenav = open("header_prenav.html") do file read(file,String) end
header_postnav = open("header_postnav.html") do file read(file,String) end
footer = open("footer.html") do file read(file,String) end

idir = "src"
odir = "../tensornetwork.org"
run(`mkdir -p $odir`)
run(`rm -f $odir/\*`)
run(`cp -r css $odir/`)
run(`cp -r images $odir/`)
run(`cp -r htaccess_file $odir/.htaccess`)
run(`chmod 644 $odir/.htaccess`)

for (root,dirs,files) in walkdir(idir)
  folderstring = root[4:end]
  curri = idir * folderstring
  curro = odir * folderstring

  folders = split(folderstring,"/")[2:end]

  for d in dirs
    run(`mkdir -p $curro/$d`)
  end
  for f in files
    (f[1]=='.') && continue
    (base,ext) = split(f,".")
    ifname = curri*"/"*f
    if ext == "md"
      ofname = curro*"/"*base*".html"
      mdstring = read(ifname,String)

      btfile = curri*"/"*base*".bib"
      has_refs = isfile(btfile)

      #if has_refs
      #  if mtime(ofname) > mtime(ifname) && mtime(ofname) > mtime(btfile)
      #    println("Skipping $(ifname), $(btfile), they are older than $(ofname).")
      #    continue
      #  end
      #else
      #  if mtime(ofname) > mtime(ifname)
      #    println("Skipping $(ifname), it is older than $(ofname).")
      #    continue
      #  end
      #end
      mdstring = generateTOC(mdstring,has_refs)
      (mdstring,mjlist) = processMathJax(mdstring)
      mdstring = processWikiLinks(mdstring,ifname)

      (mdstring,citenums) = processCitations(mdstring)
      btfile = curri*"/"*base*".bib"
      if has_refs
        bt = parseBibTex(btfile)
        refmd = generateRefs(citenums,bt)
        mdstring *= refmd
      end

      mdstring = processArxivLinks(mdstring)

      open("_tmp_file.md","w") do tf
        print(tf,mdstring)
      end
      html = read(`cmark --unsafe --smart _tmp_file.md`,String)
      #html = read(`python2.7 -m markdown _tmp_file.md`,String)

      html = restoreMathJax(html,mjlist)

      #
      # Put in backlinks
      #
      open(ofname,"w") do of
        print(of,header_prenav)

        if length(folders) > 0 || f!="index.md" #<-- don't show for main page
          print(of,"
	")
          print(of,"main/")
          tfold = "/"
          for fold in folders[1:end-1]
            tfold *= fold * "/"
            print(of,"$fold/")
          end
          if f!="index.md"
            if length(folders) > 0
                fold = folders[end]
                tfold *= fold * "/"
                print(of,"$fold/")
            end
            print(of,base)
          else
            (length(folders) > 0) && print(of,"$(folders[end])/")
          end
          print(of,"
")
        end
        print(of,header_postnav)
        print(of,html)
        printEditFooter(of,ifname)
        print(of,footer)
      end
      run(`rm -f _tmp_file.md`)

    #elseif ext == "png" || ext == "jpg"
    else
      run(`cp $ifname $(curro*"/"*f)`)
    end
  end
end


text:
function main(args)
    return args
end
# Load inline arguments for worker unit
num_workers, this = main(ARGS)
num_workers = parse(Int64, num_workers)
this        = parse(Int64, this)

#
# Load packages and functions
include("../../src/init.jl")
include("../../src/fct.jl")
include("../../src/worker_fct.jl")

#
# Output paths and filter settings
plots_base_path = "../../../waveforms/baselines/plots/raw/"
base_path_raw   = "../../../waveforms/baselines/raw_wf/"
base_path       = "../../../waveforms/baselines/raw_wf/"

run_strs = glob("../../../waveforms/calib/raw_v07.01/*")
runs = []
for run in run_strs
    isdir(run) ? push!(runs, basename(run)) : ""
end

run_keys  = []
for run in runs
    current_dir = pwd()
    ddir = "/remote/ceph/group/gerda/data/phase2/blind/v07.01/gen"
    cd(ddir*"/tier4/all/phy/$run/")
    files = glob("*.root")
    for meta_key in files
        push!(run_keys, split(meta_key, "-phy-all-tier")[1])
    end
    cd(current_dir)
end
@info("Run keys are gathered! Number of files: " * string(length(run_keys)))
run_keys = get_share_for_worker(run_keys, num_workers, this)
@info("This worker takes: " * string(length(run_keys)))

for id in run_keys
    Base.run(`clear`)
    # IJulia.clear_output(true)
    int_run = parse(Int64, split(split(id, "-")[2], "run")[end])
    str_run = lpad(int_run, 4, "0");
    ddir = "/remote/ceph/group/gerda/data/phase2/blind/v07.01/gen"
    channels = []
    for ch in 0:1:36
        filename = base_path_raw * "run" * str_run * "/" * lpad(ch, 2, "0") * "-" * channel_to_name[ch] * "/"
        !isdir(filename) ? mkpath(filename) : ""
        filename *= id * "-phy-bl-raw.h5"
        !isfile(filename) ? push!(channels, ch) : ""
    end
    println(length(channels))
    if length(channels) > 0
        filename1 = ddir*"/tier1/ged/phy/run"*str_run*"/"*id*"-phy-ged-tier1.root";
        filename4 = ddir*"/tier4/all/phy/run"*str_run*"/"*id*"-phy-all-tier4.root";
        tree = TFile(filename4)["tier4"];
        current_file_number = findall(x->x == id, run_keys)[1]
        @info("File "*string(current_file_number)*" of "*string(length(run_keys)))
        @info(">---------------------------------------------------------------------<")
        @info("Load waveforms")
        @time events = TypedTables.Table(raw2mgtevent.(TFile(filename1)["MGTree"].event[:]))
        @info("Start selecting & storing")
        waveforms    = events.fAuxWaveforms;
        for ch in channels
            index = findall(x->x[ch + 1] == 0, tree.energy[1:end])
            if length(index) > 0
                energy       = sum.(tree.energy[index])
                multiplicity = tree.multiplicity[index]
                timestamp    = tree.timestamp[index]
                channel      = Int.(zeros(length(index)) .+ ch)

                datasetID    = []
                map(x->push!(datasetID, x[ch+1]), tree.datasetID[index])

                waveform  = []
                map(x->push!(waveform, x[ch+1].wf), waveforms[index])

                filtered_dict = Table(
                    energy       = energy,
                    multiplicity = multiplicity,
                    timestamp    = timestamp,
                    run          = Int.(zeros(length(index)) .+ int_run),
                    datasetID    = datasetID,
                    channel      = channel,
                    waveform     = waveform
                )
                events   = nothing;

                filename = base_path_raw * "run" * str_run * "/" * lpad(ch, 2, "0") * "-" * channel_to_name[ch] * "/"
                filename *= id * "-phy-bl-raw.h5"
                HDF5.h5open(filename, "w") do h5f
                    LegendHDF5IO.writedata( h5f, "data", Table(
                            energy       = float.(filtered_dict.energy),
                            multiplicity = float.(filtered_dict.multiplicity),
                            timestamp    = float.(filtered_dict.timestamp),
                            run          = Int.(filtered_dict.run),
                            datasetID    = Int.(filtered_dict.datasetID),
                            channel      = Int.(filtered_dict.channel),
                            waveform     = StructArray{RDWaveform}(Array{RDWaveform,1}(filtered_dict.waveform))
                        )
                    )
                end

                @info("Ch" * lpad(ch, 2, "0") * "-" * channel_to_name[ch] * " | " * string(size(filtered_dict, 1)) * " baselines stored!")
            end
        end
    end
end


text:
function findid(id::String, ID::Array{String,1})
  c = 0
  for i = 1:length(ID)
    if ID[i] == id
      c = i
      break
    end
  end
  return c
end

function findid(id::DenseArray{UInt8,1}, ID::Array{String,1})
  c = 0
  for i = 1:length(ID)
    if codeunits(ID[i]) == id
      c = i
      break
    end
  end
  return c
end


text:
using Dash
using DashHtmlComponents
using DashCoreComponents
function fibonacci_app(clientside)
    app = dash()
    app.layout = html_div() do
        dcc_input(id = "n", type = "number", min = 0, max = 10, value = 4),
        html_div(id = "series"),
        html_div(id = "sum")
    end

    get_n(n::Int) = n
    function get_n(n::String)
        try
            return parse(Int, n)
        catch
            return 0
        end
    end
    get_n(n) = 0

    callback!(app, Output("series", "children"),Input("n", "value")) do n
        return [html_div(id=(i = i,)) for i in 1:get_n(n)]
    end

    if clientside
        callback!(
            """
            function(vals) {
                var len = vals.length;
                return len < 2 ? len : +(vals[len - 1] || 0) + +(vals[len - 2] || 0);
            }
            """, app,
            Output((i = MATCH,), "children"),
            Input((i = ALLSMALLER,), "children")
        )

        callback!(
            """
            function(vals) {
                var sum = vals.reduce(function(a, b) { return +a + +b; }, 0);
                return vals.length + ' elements, sum: ' + sum;
            }
            """, app,
            Output("sum", "children"),
            Input((i = ALL,), "children"),
        )
    else
        callback!(app,
            Output((i = MATCH,), "children"), Input((i = ALLSMALLER,), "children")
        ) do prev
            (length(prev) < 2) && return length(prev)
            return prev[end]  + prev[end - 1]

        end

        callback!(app, Output("sum", "children"), Input((i = ALL,), "children")) do seq

            seq_sum = isempty(seq) ? 0 : sum(get_n, seq)
            return "$(length(seq)) elements, sum: $(seq_sum)"
        end
    end

    return app
end


text:
#!/usr/bin/env julia

using Luxor

using Test

using Random
Random.seed!(42)

function triangle_tests(fname)
    Drawing(800, 800, fname)
    origin()
    background("white")
    fontsize(10)

    panes = Tiler(500, 500, 2, 2)

    @layer begin
        translate(first(panes[1]))
        # equilateral
        tri1 = [polar(100, θ) for θ in (0, 2π/3, 4π/3)]
        prettypoly(tri1, :stroke, close=true)

        orthocenter = triangleorthocenter(tri1...)
        incenter = triangleincenter(tri1...)
        center = trianglecenter(tri1...)
        circumcenter = trianglecircumcenter(tri1...)
        circle.((orthocenter, incenter, center, circumcenter), 2, :fill)

        # all centers are the same
        @test isapprox(orthocenter, incenter, atol=1.0e-12)
        @test isapprox(orthocenter, center,  atol=1.0e-12)
        @test isapprox(orthocenter, circumcenter, atol=1.0e-12)
    end

    @layer begin
        translate(first(panes[2]))
        # isosceles
        tri2 = [Point(0, 0), Point(80, -80), Point(160, 0)]
        prettypoly(tri2, :stroke, close=true)

        orthocenter = triangleorthocenter(tri2...)
        incenter = triangleincenter(tri2...)
        center = trianglecenter(tri2...)
        circumcenter = trianglecircumcenter(tri2...)
        circle.((orthocenter, incenter, center, circumcenter), 2, :fill)
        label.(["orthocenter", "incenter", "center", "circumcenter"], :e, (orthocenter, incenter, center, circumcenter))

        # all centers lie on the same vetical line
        @test isapprox(orthocenter.x, incenter.x)
        @test isapprox(orthocenter.x, center.x)
        @test isapprox(orthocenter.x, circumcenter.x)
    end

    @layer begin
        translate(first(panes[3]))
        # arbitrary
        tri3 = ngon(O + (50, 50), 160, 4, π/3, vertices=true)[1:3]
        prettypoly(tri3, :stroke, close=true)

        orthocenter = triangleorthocenter(tri3...)
        incenter = triangleincenter(tri3...)
        center = trianglecenter(tri3...)
        circumcenter = trianglecircumcenter(tri3...)
        circle.((orthocenter, incenter, center, circumcenter), 2, :fill)
        label.(("orthocenter", "incenter", "center", "circumcenter"), :N, (orthocenter + (0, 5), incenter +  (0, 15), center + (0, 20), circumcenter))
        # some are inside, some are outside
        @test isinside(incenter, tri3)
        @test isinside(center, tri3)
    end

    @test finish() == true
    println("...finished test: output in $(fname)")
end

triangle_tests("triangle-tests.svg")


text:
using DataFrames
using GZip

typealias Feature  Uint64
typealias Features Vector{Feature}
typealias Weights  Vector{Float64}

type DataHash
    label::Float64
    features::Features
end

type DataPoint
    label::Float64
    features
end

type LogisticModel
    weights::Vector{Float64}
    counts::Vector{Float64}
    num_bits::Int
    alpha::Float64
end
initialize_model(num_bits, alpha) = LogisticModel(zeros(2^num_bits), zeros(2^num_bits), num_bits, alpha)

function hash_feature(model::LogisticModel, f::Any)
    (hash(f) >> (64 - model.num_bits))::Feature
end

function hash_features(model::LogisticModel, d::DataPoint)
    DataHash(d.label, [hash_feature(model, f) for f=d.features])
end

function hash_features(model::LogisticModel, d)
    [hash_feature(model, f) for f=d]
end

function predict(model::LogisticModel, feas::Features)
    pred = 0.0
    for f=feas
        pred += model.weights[f+1]
    end
    1 / (1. + exp(-max(min(pred, 20.), -20.)))
end

function learn!(model::LogisticModel, d::DataHash)
    pred = predict(model, d.features)
    update = (pred-d.label)*model.alpha
    for f = d.features
        model.weights[f+1] -= update / sqrt(model.counts[f+1]+1)
        model.counts[f+1] += 1.0
    end
    pred
end

function learn!(model::LogisticModel, d::DataPoint)
    learn!(model, hash_features(model, d))
end

function log_loss(y, p)
    p = max(min(p, 1. - 10e-12), 10e-12)
    (y == 1) ? -log(p) : -log(1. - p)
end

raw_data_path     = ARGS[1]
working_data_path = ARGS[2]

alpha    = .1
num_bits = 20
model = initialize_model(num_bits, alpha)

f = gzopen(joinpath(raw_data_path, "train.gz"), "r")

i = 0
header = readline(f)
raw    = [header]
header_fea = [x*"-" for x=split(strip(header), ",")]
println(header_fea)
loss = 0

while !eof(f)
    i = i+1
    row = split(readline(f), ",")
    fea = [header_fea[i]*row[i] for i=3:length(row)]
    click = int(row[2])
    pred = learn!(model, DataPoint(click, fea))
    loss += log_loss(click, pred)
    if i%100_000==0 || eof(f)
        println(i/1e6, "m", " Loss ", loss/100_000)
        loss=0
    end
end

close(f)
println("Number of training lines ", i)

println("Reading test file ...")

f = gzopen(joinpath(raw_data_path, "test.gz"), "r")
header = readline(f)
raw    = [header]
i = 0
probs = Array(Float64, 0)
ids   = Array(ASCIIString, 0)

while !eof(f)
    i = i+1
    row = split(readline(f), ",")
    fea = [header_fea[i+1]*row[i] for i=2:length(row)]

    push!(ids, ASCIIString(row[1]))
    push!(probs, predict(model, hash_features(model, fea)))

    if i%100_000==0 || eof(f)
        println(i/1e6, "m")
    end
end

close(f)

submission = DataFrame(id=[string(x) for x=ids], click=vec(probs))
writetable(joinpath(working_data_path, "submission.csv"), submission)

max_stars_repo_name: benhamner/avazu-ctr-prediction

max_issues_repo_name: benhamner/avazu-ctr-prediction

max_forks_repo_name: benhamner/avazu-ctr-prediction


text:
@shorthands marginalhist

@recipe function f(::Type{Val{:marginalhist}}, plt::Plot; density = false)
    x, y = d[:x], d[:y]
    delete!(d, :density)

    # set up the subplots
    legend --> false
    link := :both
    grid --> false
    layout --> @layout [
        tophist           _
        hist2d{0.9w,0.9h} righthist
    ]

    # main histogram2d
    @series begin
        seriestype := :histogram2d
        right_margin --> 0mm
        top_margin --> 0mm
        subplot := 2
    end

    # these are common to both marginal histograms
    ticks := nothing
    guide := ""
    foreground_color_subplot := RGBA(0,0,0,0)
    fillcolor --> :black
    fillalpha --> 0.3
    linealpha --> 0.7

    if density
        trim := true
        seriestype := :density
    else
        seriestype := :histogram
    end

    # upper histogram
    @series begin
        subplot := 1
        bottom_margin --> 0mm
        y := x
    end

    # right histogram
    @series begin
        orientation := :h
        subplot := 3
        left_margin --> 0mm
        y := y
    end
end

# # now you can plot like:
# marginalhist(rand(1000), rand(1000))


text:
#!/usr/bin/env julia

using ArgParse

s = ArgParseSettings(description=" Given the output from the MCMC results, plot random draws of the proposed surface-density profiles.")
@add_arg_table s begin
    "--burn"
    help = "Amount of samples to delete from beginning of chain.npy"
    arg_type = Int
    "--draws"
    help = "How many draws of surface-density profiles to show."
    default = 15
    arg_type = Int
end

parsed_args = parse_args(ARGS, s)

import YAML
config = YAML.load(open(parsed_args["config"]))

using DiskJockey.model
using DiskJockey.constants

import PyPlot.plt
using LaTeXStrings

model = config["model"]
pars = convert_dict(config["parameters"], config["model"])

max_stars_repo_name: elnjensen/DiskJockey

max_issues_repo_name: elnjensen/DiskJockey

max_forks_repo_name: elnjensen/DiskJockey


text:
using LinearAlgebra
using Plots
using Random
using Ripserer
pgfplotsx()

function circ_rand(n, r, center)
    map(rand(n)) do φ
        (r * sin(2π * φ), r * cos(2π * φ)) .+ center
    end
end

function circ_equi(n, r, center)
    map(range(0, 1, length=n+1)[1:end-1]) do φ
        (r * sin(2π * φ), r * cos(2π * φ)) .+ center
    end
end

function annulus(n, r1, r2, center)
    points = Tuple{Float64,Float64}[]
    while length(points) < n
        v = 2r1 * (rand(2) .- 0.5)
        if r1 ≥ norm(v) > r2
            push!(points, (v[1], v[2]) .+ center)
        end
    end
    return points
end

Random.seed!(1337)
data = [
    circ_rand(20, 1, (0, 2));
    circ_equi(12, 1.5, (0, -2));
    annulus(40, 2, 1, (2 * √3, 0));
]

res_co = ripserer(data; reps=true)[2][end-2:end]
res_ho = ripserer(data; alg=:involuted)[2][end-2:end]

function plot_representatives(data, ints; kwargs...)
    plt = scatter(data; legend=false, aspect_ratio=1, markersize=2, kwargs...)
    foreach(ints) do int
        plot!(plt, int, data; threshold_strict=death(int))
    end
    return plt
end

plot(
    plot_representatives(data, res_co; title="Representative Cocycles"),
    plot_representatives(data, res_ho; title="Representative Cycles"),
    size=(600, 300),
)
savefig(joinpath(@__DIR__, "figures/cycle-cocycle-comparison.pdf"))


text:
using Test, TCX

tcx_sample_file="centry_park_run.tcx"
tcx_centrypark_run_file="centry_park_run.tcx"
tcx_treadmill_run_file="treadmill_run.tcx"
gpx_sample_file="shanghai_marathon_2018.gpx"

@testset "TCX tests" begin
    include("test_tcx_read_file.jl")
    include("test_tcx_read_dir.jl")
    include("test_tcx_read_str.jl")
    include("test_tcx.jl")
end


text:
#
# Creates types MOGA_Real, MOGA_Binary, and MOGA_Integer which can be used
# to create decision variable lists. MOGA_Real and MOGA_Integer have min
# and max values as part of the struct.
#
# Extends Base.Random.rand so that when given an instance of one of these types,
# returns a valid random value (i.e. within the specified bounds)

using Random

abstract type MOGA_Type end

struct MOGA_Real <: MOGA_Type
    min_value::Float64
    max_value::Float64
end

struct MOGA_Binary <: MOGA_Type
end

struct MOGA_Integer <: MOGA_Type
    min_value::Int64
    max_value::Int64
end

#Random.rand(rng::AbstractRNG, d::Random.SamplerTrivial{Die}) = rand(rng, 1:d[].nsides);
# function Random.rand(rng::AbstractRNG, t::MOGA_Real)
#     return (t.max_value - t.min_value) * rand() + t.min_value
# end
#
# Random.rand(rng::AbstractRNG, t::Random.SamplerTrivial{MOGA_Binary}) = rand(Bool)
function Random.rand(t::MOGA_Real)
    return (t.max_value - t.min_value) * rand() + t.min_value
end

Random.rand(t::MOGA_Binary) = rand(Bool)

function Random.rand(t::MOGA_Integer)
    return Int64(floor((1 + t.max_value - t.min_value) * rand()) + t.min_value)
end

max_stars_repo_name: phawthorne/echidna

max_issues_repo_name: phawthorne/echidna

max_forks_repo_name: phawthorne/echidna


text:
module MonteCarloTools

using LinearAlgebra
using QuantumModels
using ExactDiagonalizationTools

include("mctools.jl")
include("detmatrix.jl")
include("gutzwillerslater.jl")
include("vmc.jl")

export runVMC

end

max_stars_repo_name: amiragha/mps

max_issues_repo_name: amiragha/mps

max_forks_repo_name: amiragha/mps


text:
#=
    an excitation tensor has 4 legs (1,2),(3,4)
    the first and the last are virtual, the second is physical, the third is the utility leg
=#

include("excitransfers.jl")

"
    quasiparticle_excitation calculates the energy of the first excited state at momentum 'moment'
"
function quasiparticle_excitation(hamiltonian::Hamiltonian, momentum::Float64, mpsleft::InfiniteMPS, paramsleft=params(mpsleft,hamiltonian), mpsright::InfiniteMPS=mpsleft, paramsright=paramsleft;
    excitation_space=oneunit(space(mpsleft.AL[1],1)), num=1 , toler = 1e-10,krylovdim=30)

    V_initial = rand_quasiparticle(mpsleft,mpsright;excitation_space=excitation_space,momentum=momentum);

    #the function that maps x->B and then places this in the excitation hamiltonian
    eigEx(V) = effective_excitation_hamiltonian(hamiltonian, V, params(V,hamiltonian,paramsleft, paramsright))
    Es,Vs,convhist = eigsolve(eigEx, V_initial, num, :SR, tol=toler,krylovdim=krylovdim)
    convhist.converged<num && @warn "quasiparticle didn't converge k=$(moment) $(convhist.normres)"

    return Es,Vs
end

#pretty much identical to the infinite mps code, except for the lack of momentum label
function quasiparticle_excitation(hamiltonian::Hamiltonian, mpsleft::FiniteMPS, paramsleft=params(mpsleft,hamiltonian), mpsright::FiniteMPS=mpsleft, paramsright=paramsleft;
    excitation_space=oneunit(space(mpsleft.AL[1],1)),num=1, toler = 1e-10,krylovdim=30)

    V_initial = rand_quasiparticle(mpsleft,mpsright;excitation_space=excitation_space);

    #the function that maps x->B and then places this in the excitation hamiltonian
    eigEx(V) = effective_excitation_hamiltonian(hamiltonian, V, params(V,hamiltonian,paramsleft, paramsright))
    Es,Vs,convhist = eigsolve(eigEx, V_initial, num, :SR, tol=toler,krylovdim=krylovdim)
    convhist.converged<num && @warn "quasiparticle didn't converge $(convhist.normres)"

    return Es,Vs
end

#give it a vector of momentum points
function quasiparticle_excitation(hamiltonian::Hamiltonian, momenta::AbstractVector, mpsleft::InfiniteMPS, paramsleft=params(mpsleft,hamiltonian), mpsright::InfiniteMPS=mpsleft, paramsright=paramsleft;
    num=1,verbose=Defaults.verbose,kwargs...)

    tasks = map(enumerate(momenta)) do (i,p)
        @Threads.spawn begin
            (E,V) = quasiparticle_excitation(hamiltonian, p, mpsleft, paramsleft, mpsright, paramsright; num=num,kwargs...)
            verbose && println("Found excitations for p = $(p)")
            (E,V)
        end
    end

    fetched = fetch.(tasks);

    Ep = permutedims(reduce(hcat,map(x->x[1][1:num],fetched)));
    Bp = permutedims(reduce(hcat,map(x->x[2][1:num],fetched)));

    return Ep,Bp
end

function effective_excitation_hamiltonian(ham::MPOHamiltonian, exci::QP,pars=params(exci,ham))
    odim = ham.odim;

    Bs = [exci[i] for i in 1:length(exci)];
    toret = zero.(Bs);

    #do necessary contractions
    for i = 1:length(exci)
        for (j,k) in keys(ham,i)
            @tensor toret[i][-1,-2,-3,-4] +=    leftenv(pars.lpars,i,exci.left_gs)[j][-1,1,2]*
                                                Bs[i][2,3,-3,4]*
                                                ham[i,j,k][1,-2,5,3]*
                                                rightenv(pars.rpars,i,exci.right_gs)[k][4,5,-4]

            # <B|H|B>-<H>
            en = @tensor    conj(exci.left_gs.AC[i][11,12,13])*
                            leftenv(pars.lpars,i,exci.left_gs)[j][11,1,2]*
                            exci.left_gs.AC[i][2,3,4]*
                            ham[i,j,k][1,12,5,3]*
                            rightenv(pars.lpars,i,exci.left_gs)[k][4,5,13]

            toret[i] -= Bs[i]*en
            if i>1 || exci isa InfiniteQP
                @tensor toret[i][-1,-2,-3,-4] +=    pars.lBs[mod1(i-1,end)][j][-1,1,-3,2]*
                                                    exci.right_gs.AR[i][2,3,4]*
                                                    ham[i,j,k][1,-2,5,3]*
                                                    rightenv(pars.rpars,i,exci.right_gs)[k][4,5,-4]
            end
            if i<length(exci.left_gs) || exci isa InfiniteQP
                @tensor toret[i][-1,-2,-3,-4] +=    leftenv(pars.lpars,i,exci.left_gs)[j][-1,1,2]*
                                                    exci.left_gs.AL[i][2,3,4]*
                                                    ham[i,j,k][1,-2,5,3]*
                                                    pars.rBs[mod1(i+1,end)][k][4,-3,5,-4]
            end
        end

    end

    toret_vec = similar(exci);
    for i in 1:length(exci)
        toret_vec[i] = toret[i]
    end
    return toret_vec

end


text:
f(x) = abs(x)^.5 + 5x^3
for i in map(parseint,reverse(split(readline())))
    v = f(i)
    println("$i: ", v > 400 ? "TOO LARGE" : v)
end

max_stars_repo_name: ethansaxenian/RosettaDecode

max_issues_repo_name: ethansaxenian/RosettaDecode

max_forks_repo_name: ethansaxenian/RosettaDecode


text:
# AUTO GENERATED FILE - DO NOT EDIT

export 'feffery'_antdupload

"""
    'feffery'_antdupload(;kwargs...)

An AntdUpload component.

Keyword arguments:
- `id` (String; optional)
- `apiUrl` (String; optional)
- `buttonContent` (String; optional)
- `className` (String; optional)
- `directory` (Bool; optional)
- `failedTooltipInfo` (String; optional)
- `fileListMaxLength` (Real; optional)
- `fileMaxSize` (Real; optional)
- `fileTypes` (Array of Strings; optional)
- `lastUploadTaskRecord` (optional): . lastUploadTaskRecord has the following type: lists containing elements 'fileName', 'fileSize', 'completeTimestamp', 'taskStatus', 'taskId'.
Those elements have the following types:
  - `fileName` (String; optional)
  - `fileSize` (Real; optional)
  - `completeTimestamp` (Real; optional)
  - `taskStatus` (String; optional)
  - `taskId` (String; optional)
- `loading_state` (optional): . loading_state has the following type: lists containing elements 'is_loading', 'prop_name', 'component_name'.
Those elements have the following types:
  - `is_loading` (Bool; optional): Determines if the component is loading or not
  - `prop_name` (String; optional): Holds which property is loading
  - `component_name` (String; optional): Holds the name of the component that is loading
- `locale` (a value equal to: 'zh-cn', 'en-us'; optional)
- `multiple` (Bool; optional)
- `style` (Dict; optional)
- `uploadId` (String; optional)
"""
function 'feffery'_antdupload(; kwargs...)
        available_props = Symbol[:id, :apiUrl, :buttonContent, :className, :directory, :failedTooltipInfo, :fileListMaxLength, :fileMaxSize, :fileTypes, :lastUploadTaskRecord, :loading_state, :locale, :multiple, :style, :uploadId]
        wild_props = Symbol[]
        return Component("'feffery'_antdupload", "AntdUpload", "feffery_antd_components", available_props, wild_props; kwargs...)
end

max_stars_repo_name: ReilYoung/feffery-antd-components

max_issues_repo_name: ReilYoung/feffery-antd-components

max_forks_repo_name: ReilYoung/feffery-antd-components


text:
# For the definitive list of infix operators, examine the Julia parser code:
# https://github.com/JuliaLang/julia/blob/master/src/julia-parser.scm#L9
# Most of the infixes are omitted since JavaScript doesn't allow arbitrary
# unicode identifiers and/or the respective infixes don't exist in JavaScript.

# TODO:
# It would make sense (and might make things a bit easier/cleaner) to map infix
# and unary expressions into JSAST's with :infixop and :unaryop heads
# respectively.
# This means that 1 + 2 would become (:infixop, :+, 1, 2) instead of (:+, 1, 2).
# We would only need to have one deparse method for all infixes, and this allows
# us to disambiguate unary from infix at the JSAST level (instead of checking if
# length(jsast.args) > 1).

"""
    _isinfix(arg[, exclude_infix])

Returns true if arg is an infix symbol or infix JSNode unless it matches the
symbol provided for exclude.
"""
function _isinfix end

# _isinfix(::Symbol)
_isinfix(s::Symbol, x::Union{Symbol, Nothing}=nothing) = _isinfix(Val(s), x)
_isinfix(::Val{S}) where {S} = false
function _isinfix(val::Val{S}, x::Union{Symbol, Nothing}) where {S}
    return S != x && _isinfix(val)
end

# _isinfix(::JSNode)
_isinfix(::JSNode, x::Union{Symbol, Nothing}=nothing) = false
function _isinfix(j::JSAST, x::Union{Symbol, Nothing}=nothing)
    # We check j.args > 1 here to avoid redundant parenthesization around unary
    # operators. See TODO comment at start of this file.
    return _isinfix(j.head, x) && length(j.args) > 1
end

"""
Deparse an argument to an infix operator.

This is used to provide intelligent parenthesization when deparsing infix
operators. The use of the `exclude_infix` arg is to avoid redundant parentheses
around operators of the same type (this is necessary so that
`foo && bar && spam` in Julia is not deparsed as `foo && (bar && spam)` in JS).

NOTE: The exclusion argument is, strictly speaking, only necessary for
short-circuiting operators since they aren't represented as multiple-argument
functions in Julia's AST. So `1 + 2 + 3` becomes `(+ 1 2 3)` but
`foo && bar && spam` becomes `(&& foo (&& bar spam))`.
"""
function _deparse_infix_arg(arg::JSNode, exclude_infix=nothing)
    if !_isinfix(arg, exclude_infix)
        return deparse(arg)
    end
    return jsstring("(", deparse(arg), ")")
end

# These infix operators have their own distinct head symbols in Julia's AST and
# so we can crawl them as part of the "standard" crawl function.
for infix in (
        :(=), :(+=), :(-=), :(/=), :(*=),
        :(&&), :(||),
)
    # The inner QuoteNode is required so that @eval passes the operator
    # through as a symbol (and not directly interpolating it), and the outer
    # QuoteNode is required so that when crawl returns the Expr, the
    # operator is again passed through as a symbol and not literally
    # interpolated.
    sym = QuoteNode(infix)
    @eval begin
        _isinfix(::Val{$sym}) = true
        function crawl(h::Val{$sym}, args...)
            # NOTE: We use the `Expr` constructor hear instead of the :(...)
            # syntax to make interpolation easier here.
            return Expr(
                :call,
                :JSAST,
                QuoteNode($sym),
                crawl.(args)...,
            )
        end
        function deparse(::Val{$sym}, args...)
            return jsstring(
                join(_deparse_infix_arg.(args, $sym), string(" ", $sym, " "))
            )
        end
    end
end

# These infix operators are represented as function calls in Julia's AST and so
# we need to crawl them as part of the `crawl_call` process and deparse them
# into the appropriate infix for JavaScript.
# NOTE: For arithmetic operators (like `+` and `*`), if multiple are chained
# together, Julia generates a :call Expr with multiple arguments, so we need to
# handle crawling and deparsing `+(arg1, args2, args...)`.
# NOTE: For comparison operators (like `>=` and `==`), when multiple are
# chained, Julia generates an Expr with a :comparison head that lets us do
# things like `0 <= x <= 1`. We could potentially translate that to equivalent
# JavaScript (though we'd have to translate it as `0 <= x && x <= 1`).
for infix in (
        :+, :-, :*, :/,
        :in, :of, :(==), :(!=), :(===), :(!==),
        :(>), :(<), :(>=), :(<=),
)
    sym = QuoteNode(infix)
    @eval begin
        _isinfix(::Val{$sym}) = true
        function crawl_call(::Val{$sym}, arg1, arg2, args...)
            return Expr(
                :call,
                :JSAST,
                QuoteNode($sym),
                crawl.([arg1, arg2, args...])...,
            )
        end
        function deparse(::Val{$sym}, arg1, arg2, args...)
            return jsstring(
                join(
                    _deparse_infix_arg.([arg1, arg2, args...]),
                    string(" ", $sym, " "),
                )
            )
        end
    end
end

# Unary operators
for unary in (
        :+, :-,
)
    sym = QuoteNode(unary)
    @eval begin
        function crawl_call(::Val{$sym}, arg)
            return Expr(
                :call,
                :JSAST,
                QuoteNode($sym),
                crawl(arg),
            )
        end
        function deparse(::Val{$sym}, arg)
            return jsstring(
                string($sym),
                _isinfix(arg)
                    ? string("(", deparse(arg), ")")
                    : deparse(arg)
            )
        end
    end
end

function crawl(h::Val{:(.)}, lhs, rhs)
    # We unquote the RHS because of the way that Julia adds QuoteNode's to dot
    # expression.
    return :(JSAST(:(.), $(crawl(lhs)), $(crawl(_unquote(rhs)))))
end
function deparse(h::Val{:(.)}, lhs, rhs)
    return js"$(deparse(lhs)).$(deparse(rhs))"
end


text:
include(joinpath(@__DIR__, "bind_generator.jl"))

# Read in the API definition macros from the definitions file
defs = read(joinpath(@__DIR__, "api_defs.jl"), String)
# Have Julia expand/run the @bind macro to generate expressions for all of the functions
exprs = Base.include_string(@__MODULE__, "@macroexpand1 begin\n" * defs * "\nend", "api_defs.jl")
# Insert the conditional version helper expression
prepend!(exprs.args, _libhdf5_build_ver_expr.args)
Base.remove_linenums!(exprs)

# Definitions which are not automatically generated, but should still be documented as
# part of the raw low-level API:
append!(bound_api["H5P"],
        ["h5p_get_class_name"])   # defined in src/api_helpers.jl
append!(bound_api["H5T"],
        ["h5t_get_member_name",   # defined in src/api_helpers.jl
         "h5t_get_tag"])          # defined in src/api_helpers.jl

# Now dump the text representation to disk
open(joinpath(@__DIR__, "..", "src", "api.jl"), "w") do fid
    println(fid, """
# This file is autogenerated by HDF5.jl's `gen/gen_wrappers.jl` and should not be editted.
#
# To add new bindings, define the binding in `gen/api_defs.jl`, re-run
# `gen/gen_wrappers.jl`, and commit the updated `src/api.jl`.
""")
    function triplequote(s::String, indent = "", prefix = "")
        ret = indent * prefix * "\"\"\"\n"
        for l in eachline(IOBuffer(s))
            ret *= isempty(l) ? "\n" : indent * l * "\n"
        end
        ret *= indent * "\"\"\"\n"
        return ret
    end
    ismacro(ex, sym, n = 0) = isexpr(ex, :macrocall) && length(ex.args) >= n + 2 &&
                              ex.args[1] == sym
    for funcblock in exprs.args
        if ismacro(funcblock, Symbol("@doc"), 2)
            # Pretty print the doc macro as just a juxtaposed doc string and function
            # definition; the `@doc` construction is necessary in AST form for the docs
            # to be included in interactive use of `@bind`, but in source form we can
            # rely on Julia's parsing behavior.
            print(fid, triplequote(funcblock.args[3]), funcblock.args[4], "\n\n")
        elseif ismacro(funcblock, Symbol("@static"), 1) &&
               isexpr(funcblock.args[3], :if, 2) &&
               ismacro(funcblock.args[3].args[2], Symbol("@doc"), 2)
            # Within a @static block, we have to keep the @doc prefix, but we can still
            # switch to triple-quoting and there's special parsing to allow the function
            # definition to be on the next line.
            #
            # Work around the expression printer in this more complex case by printing
            # to a buffer and string-replacing a sentinel value
            docstr = funcblock.args[3].args[2].args[3]
            funcblock.args[3].args[2].args[3] = "SENTINEL_DOC"
            buf = sprint(print, funcblock)
            # Two-step deindent since `r"^\s{4}(\s{4})?"m => s"\1"` errors: see JuliaLang/julia#31456
            buf = replace(buf, r"^\s{4}"m => s"") # deindent
            buf = replace(buf, r"^(\s{4})\s{4}"m => s"\1") # deindent
            # Now format the doc string and replace (note need to indent `function`)
            buf = replace(buf, r"^\s+@doc \"SENTINEL_DOC\" "m =>
                               triplequote(docstr, " "^4, "@doc ") * " "^4)
            print(fid, buf, "\n\n")
        else
            # passthrough
            print(fid, funcblock, "\n\n")
        end
    end
end

# Also generate auto-docs that simply list all of the bound API functions
apidocs = ""
for (mod, desc, urltail) in (
    ("H5", "General Library Functions", "Library"),
    ("H5A", "Attribute Interface", "Attributes"),
    ("H5D", "Dataset Interface", "Datasets"),
    ("H5E", "Error Interface", "Error+Handling"),
    ("H5F", "File Interface", "Files"),
    ("H5G", "Group Interface", "Groups"),
    ("H5I", "Identifier Interface", "Identifiers"),
    ("H5L", "Link Interface", "Links"),
    ("H5O", "Object Interface", "Objects"),
    ("H5P", "Property Interface", "Property+Lists"),
    ("H5R", "Reference Interface", "References"),
    ("H5S", "Dataspace Interface", "Dataspaces"),
    ("H5T", "Datatype Interface", "Datatypes"),
    ("H5Z", "Filter Interface", "Filters"),
    ("H5DO", "Optimized Functions Interface", "Optimizations"),
    ("H5DS", "Dimension Scale Interface", "Dimension+Scales"),
    ("H5LT", "Lite Interface", "Lite"),
    ("H5TB", "Table Interface", "Tables"),
    )
    global apidocs
    funclist = sort!(bound_api[mod])
    index = join(["- [`$f`](@ref HDF5.$f)" for f in funclist], "\n")
    funcs = join(funclist, "\n")
    apidocs *= """
        ---

        ## [`$mod`](https://portal.hdfgroup.org/display/HDF5/$urltail) — $desc
        $index
        ```@docs
        $funcs
        ```

        """
end

open(joinpath(@__DIR__, "..", "docs", "src", "api_bindings.md"), "w") do fid
    write(fid,
"""
```@raw html
<!-- This file is auto-generated and should not be manually editted. To update, run the
gen/gen_wrappers.jl script -->
```
```@meta
CurrentModule = HDF5
```

# Low-level library bindings

At the lowest level, `HDF5.jl` operates by calling the public API of the HDF5 shared
library through a set of `ccall` wrapper functions.
This page documents the function names and nominal C argument types of the API which
have bindings in this package.
Note that in many cases, high-level data types are valid arguments through automatic
`ccall` conversions.
For instance, `HDF5Datatype` objects will be automatically converted to their `hid_t` ID
by Julia's `cconvert`+`unsafe_convert` `ccall` rules.

There are additional helper wrappers (often for out-argument functions) which are not
documented here.

$apidocs
"""
    )
end

nothing


text:
@params struct DensityFilter{_filtering,T} <: AbstractDensityFilter
    filtering::Val{_filtering}
    metadata::FilterMetadata
    rmin::T
    jacobian::AbstractMatrix{T}
end
function Base.show(::IO, ::MIME{Symbol("text/plain")}, ::DensityFilter)
    return println("TopOpt density filter")
end
Nonconvex.NonconvexCore.getdim(f::DensityFilter) = size(f.jacobian, 1)
DensityFilter{true}(args...) = DensityFilter(Val(true), args...)
DensityFilter{false}(args...) = DensityFilter(Val(false), args...)

DensityFilter(solver; rmin) = DensityFilter(Val(true), solver, rmin)
function DensityFilter(
    ::Val{filtering}, solver::AbstractFEASolver, args...
) where {filtering}
    return DensityFilter(Val(filtering), whichdevice(solver), solver, args...)
end
function DensityFilter(
    ::Val{true}, ::CPU, solver::TS, rmin::T, ::Type{TI}=Int
) where {T,TI<:Integer,TS<:AbstractFEASolver}
    metadata = FilterMetadata(solver, rmin, TI)
    TM = typeof(metadata)
    problem = solver.problem
    grid = problem.ch.dh.grid
    nnodes = getnnodes(grid)

    black = problem.black
    white = problem.white
    nel = length(black)
    nfc = sum(black) + sum(white)
    jacobian = getJacobian(solver, metadata)
    return DensityFilter(Val(true), metadata, rmin, jacobian)
end

function DensityFilter(
    ::Val{false}, ::CPU, solver::TS, rmin::T, ::Type{TI}=Int
) where {T,TS<:AbstractFEASolver,TI<:Integer}
    metadata = FilterMetadata(T, TI)
    cell_weights = T[]
    jacobian = zeros(T, 0, 0)
    return DensityFilter(Val(false), metadata, rmin, jacobian)
end

function (cf::DensityFilter{true,T})(x) where {T}
    cf.rmin <= 0 && return x
    @unpack jacobian = cf
    out = similar(x)
    mul!(out, jacobian, x)
    return out
end
function ChainRulesCore.rrule(f::DensityFilter{true}, x)
    return f(x), Δ -> (nothing, f.jacobian' * Δ)
end

(cf::DensityFilter{false})(x) = x

function getJacobian(solver, metadata::FilterMetadata)
    @unpack elementinfo, problem = solver
    @unpack black, white, varind, cellvolumes = elementinfo
    @unpack cell_neighbouring_nodes, cell_node_weights = metadata
    node_cells = elementinfo.metadata.node_cells

    T = eltype(cellvolumes)
    grid = problem.ch.dh.grid
    nnodes = getnnodes(grid)
    I = Int[]
    J = Int[]
    V = T[]
    for n in 1:nnodes
        r = node_cells.offsets[n]:(node_cells.offsets[n + 1] - 1)
        for i in r
            c = node_cells.values[i][1]
            if black[c] || white[c]
                continue
            end
            ind = varind[c]
            w = cellvolumes[c]
            push!(I, n)
            push!(J, ind)
            push!(V, w)
        end
    end
    mat1_transpose = sparse(J, I, V, length(solver.vars), nnodes)
    scalecols!(mat1_transpose)
    norm(V) == 0 && throw("Jacobian is all 0s.")

    I = Int[]
    J = Int[]
    V = T[]
    for i in 1:length(black)
        if black[i] || white[i]
            continue
        end
        ind = varind[i]
        nodes = cell_neighbouring_nodes[ind]
        if length(nodes) == 0
            continue
        end
        weights = cell_node_weights[ind]
        weights_sum = sum(weights)
        for (j, n) in enumerate(nodes)
            push!(I, ind)
            push!(J, n)
            push!(V, weights[j] / weights_sum)
        end
    end
    mat2_transpose = sparse(J, I, V, nnodes, length(solver.vars))
    norm(V) == 0 && throw("Jacobian is all 0s.")
    mat_transpose = mat1_transpose * mat2_transpose
    return mat_transpose'
end

function scalecols!(A::SparseMatrixCSC)
    @unpack colptr, nzval = A
    T = eltype(A)
    for col in 1:(length(colptr) - 1)
        inds = colptr[col]:(colptr[col + 1] - 1)
        s = sum(nzval[inds])
        if s != 0
            nzval[inds] .= nzval[inds] ./ s
        end
    end
    return A
end

@params struct ProjectedDensityFilter <: AbstractDensityFilter
    filter::DensityFilter
    preproj::Any
    postproj::Any
end
function Nonconvex.NonconvexCore.getdim(f::ProjectedDensityFilter)
    return Nonconvex.NonconvexCore.getdim(f.filter)
end
function (cf::ProjectedDensityFilter)(x)
    if cf.preproj isa Nothing
        fx = x
    else
        fx = cf.preproj.(x)
    end
    fx = cf.filter(fx)
    if cf.postproj isa Nothing
        out = fx
    else
        out = cf.postproj.(fx)
    end
    return out
end


text:
using KiteModels
using Documenter

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

makedocs(;
    modules=[KiteModels],
    authors="Uwe Fechner <fechner@aenarete.eu> and contributors",
    repo="https://github.com/ufechner7/KiteModels.jl/blob/{commit}{path}#{line}",
    sitename="KiteModels.jl",
    format=Documenter.HTML(;
        prettyurls=get(ENV, "CI", "false") == "true",
        canonical="https://ufechner7.github.io/KiteModels.jl",
        assets=String[],
    ),
    pages=[
        "Home" => "index.md",
        "Types" => "types.md",
        "Functions" => "functions.md",
        "Parameters" => "parameters.md",
        "Examples_1p" => "examples.md",
        "Examples_4p" => "examples_4p.md",
        "Quickstart" => "quickstart.md",
        "Advanced usage" => "advanced.md",
    ],
)

deploydocs(;
    repo="github.com/ufechner7/KiteModels.jl",
    devbranch="main",
)


text:
@testset "Fundamental Plasma Parameters" begin
    include("test_plasma_params.jl")
end


text:
"""
`IMWARP` - Apply affine transform to image using bilinear interpolation

    warped_img, warped_offset = imwarp(img, tform, offset)

* `img`: 2D array, image (todo: extend to Image type)
* `tform`: 3x3 matrix, affine transform (defined as row vector x matrix)
* `offset`: 2-element array, position of img[1,1] in global space
* `warped_img`: with pixel values the same type as original image (for Int type,
  pixel values are rounded)
* `warped_offset`: 2-element array, position of warped_img[1,1] in global space

The bounding box of the warped image is defined as the smallest
integer-valued rectangle that contains the affine transform of the
bounding box of the original image.

This means that `warped_offset` is constrained to be integer-valued,
though `offset` is allowed to have floating point values.  The integer
constraint removes the need for further interpolation in any
subsequent fusing of multiple warped tiles.

Bilinear interpolation, with extrapolation using zero fill value.

### Definitions

Global position of `img` pixels (analogous definitions for `warped_img`):

* [1,1] pixel has position (offset[1] - 0.5, offset[2] - 0.5) in global space
* [i,j] pixel has position (offset[1]+i-0.5, offset[2]+j-0.5)

e.g. with no offset, [i, j] pixel has median([i-1:i, j-1:j]) location in global space.

Affine transform of a global position:

* homogeneous coordinates [x, y, 1]  [ax + by + c, dx + ey + f, 1]
* or equivalently [x, y, 1]  [x, y, 1] * tform

        where `tform` = [a d 0;
                         b e 0;
                         c f 1]

Note that:

1. transform is *row* vector x matrix (right hand side matrix multiplication)
2. definition compatible with [MATLAB](http://www.mathworks.com/help/images/ref/affine2d-class.html), but not AffineTransforms.jl
3. meaning of transform depends on whether the image is in ij or xy format

Affine transform of an image (two equivalent definitions, provide scaling isn't an issue):

1. The value of `img` at a position is equal to the value of
the `warped_img` at the transformed position.
2. The value of `warped_img` at a position is equal to the value of
`img` at the inverse transformed position.

We apply definition 2 as it's compatible with gridding and interpolation.

Bounding box of an image of size (m,n):

* smallest rectangle in global space that contains the positions of the [1,1]
  and [m,n] pixels
* represented by the 4-tuple (offset[1],offset[2],m,n)

    (offset[1],offset[2])  ___________
                          |           |
                    height|           |
                       m  |           |
                          |___________|
                                n      (offset[1]+m,offset[2]+n)
                              width

"""
function imwarp{T}(img::Union{Array{T}, SharedArray{T}}, tform, offset=[0.0,0.0]; parallel = false)
  bb = BoundingBox{Float64}(offset..., size(img, 1), size(img, 2))
  wbb = tform_bb(bb, tform)
  tbb = snap_bb(wbb)
  warped_img = parallel && nprocs() != 1 ? SharedArray(T, tbb.h, tbb.w) : zeros(T, tbb.h, tbb.w)
  return imwarp!(warped_img, img, tform, offset; parallel = parallel)
end

function imwarp!{T}(warped_img::Union{Array{T}, SharedArray{T}}, img::Union{Array{T}, SharedArray{T}}, tform, offset=[0.0,0.0]; parallel = false)
  # img bb rooted at offset, with height and width calculated from image
  bb = BoundingBox{Float64}(offset..., size(img, 1), size(img, 2))
  # transform original bb to generate new bb (may contain continuous values)
  wbb = tform_bb(bb, tform)
  # snap transformed bb to the nearest exterior integer values
  tbb = snap_bb(wbb)
  # construct warped_img, pixels same Type as img, size calculated from tbb
  # WARNING: should have zero values, but unclear whether guaranteed by similar
  # warped_img = similar(img, tbb.h+1, tbb.w+1)
  #warped_img = zeros(T, tbb.h, tbb.w)
  if size(warped_img) != (tbb.h, tbb.w)
    println("The supplied output array size is incorrect. Aborting...")
    return;
  end
  # offset of warped_img from the global origin
  warped_offset = [tbb.i, tbb.j]
  #tform[3, 1:2] -= 1.0
  M = inv(tform)   # inverse transform in global space
#  M[3,1:2] -= offset'-1.0   # include conversion to pixel space of original img
  M[3,1:2] -= offset'-0.5   # include conversion to pixel space of original img
  x_max = size(img, 1);
  y_max = size(img, 2);

  function proc_range(idx, arr)
	worker_procs = setdiff(procs(), myid());
	nchunks = length(worker_procs);
	if nchunks == 0 return 1:length(arr); end
	if idx == myid() return 1:0; end
	splits = [round(Int64, s) for s in linspace(0, length(arr), nchunks + 1)];
	return splits[findfirst(worker_procs, idx)]+1:splits[findfirst(worker_procs, idx) + 1]
  end

  if parallel && nprocs() != 1
    if !(typeof(warped_img) <: SharedArray)
    	println("The supplied output array is not a SharedArray despite the parallel keyword set to true. Aborting...")
	return;
    end
    if !(typeof(img) <: SharedArray)
	  img_shared = SharedArray(eltype(img), size(img)...)
	  img_shared[:] = img;
	  img = img_shared;
	end
	@sync for p in procs()
      		j_range = proc_range(p, 1:size(warped_img, 2));
      		@async remotecall_wait(p, compute_and_write_columns!, warped_img, img, M, j_range, x_max, y_max, warped_offset)
	end
  else
  # cycle through all the pixels in warped_img
  for j = 1:size(warped_img,2)
    for i = 1:size(warped_img,1) # cycle through column-first for speed
	compute_and_write_pixel!(warped_img, img, M, i, j, x_max, y_max, warped_offset)
      end
    end
  end
  warped_img, warped_offset
end

function compute_and_write_columns!(warped_img, img, M, j_range, x_max, y_max, warped_offset)
  for j in j_range
    for i in 1:size(warped_img, 1)
	compute_and_write_pixel!(warped_img, img, M, i, j, x_max, y_max, warped_offset)
    end
  end
end

function compute_and_write_pixel!(warped_img, img, M, i, j, x_max, y_max, warped_offset)
        # convert from pixel to global space
        # (we index to zero, then add on the offset)
        @fastmath @inbounds u = i-0.5+warped_offset[1]
	@fastmath @inbounds v = j-0.5+warped_offset[2]
        # apply inv(tform), conversion back to pixel space included
        # x, y = [u, v, 1] * M - but writing it out moves faster
        @fastmath @inbounds x = M[1,1]*u + M[2,1]*v + M[3,1]
	@fastmath @inbounds y = M[1,2]*u + M[2,2]*v + M[3,2]
        # x, y = M[1,1]*u + M[1,2]*v + M[1,3], M[2,1]*u + M[2,2]*v + M[2,3]  # faster but differs by a matrix transpose

        # Slow...
        #warped_img[i,j] = round(Uint8, bilinear(img, x, y))
        #warped_img[i,j] = bilinear(img, x, y)
        # Bilinear interpolation
        fx, fy = floor(Int64, x), floor(Int64, y)
        wx, wy = x-fx, y-fy
	rwx, rwy = 1.0 - wx, 1.0 - wy
        # if 1 <= fx && fx+1 <= x_max && 1 <= fy && fy+1 <= y_max
        if 1 <= fx <= x_max - 1 && 1 <= fy <= y_max -1   # normal case
                # Expansion of p = [1-wx wx] * img[fx:fx+1, fy:fy+1] * [1-wy; wy]
                @fastmath @inbounds pff = rwy * rwx * img[fx,fy]
                @fastmath @inbounds pxf = rwy * wx * img[fx+1,fy]
		@fastmath @inbounds pfy = wy * rwx * img[fx,fy+1]
		@fastmath @inbounds pxy = wy * wx * img[fx+1,fy+1]
		@fastmath writepixel(warped_img, i, j, pff + pxf + pfy + pxy);
	else
	  if 1 <= fx <= x_max - 1
		if fy == 0
		@fastmath @inbounds pfy = wy * rwx * img[fx,fy+1]
		@fastmath @inbounds pxy = wy * wx * img[fx+1,fy+1]
		@fastmath writepixel(warped_img, i, j, pfy + pxy);
		elseif fy == y_max
                @fastmath @inbounds pff = rwy * rwx * img[fx,fy]
                @fastmath @inbounds pxf = rwy * wx * img[fx+1,fy]
		@fastmath writepixel(warped_img, i, j, pff + pxf);
	      end
	  elseif 1 <= fy <= y_max - 1
	    	if fx == 0
                @fastmath @inbounds pxf = rwy * wx * img[fx+1,fy]
		@fastmath @inbounds pxy = wy * wx * img[fx+1,fy+1]
		@fastmath writepixel(warped_img, i, j, pxf + pxy);
		elseif fx == x_max
                @fastmath @inbounds pff = rwy * rwx * img[fx,fy]
		@fastmath @inbounds pfy = wy * rwx * img[fx,fy+1]
		@fastmath writepixel(warped_img, i, j, pff + pfy);
	      end
	    elseif fx == 0 && fy == 0
		@fastmath @inbounds pxy = wy * wx * img[fx+1,fy+1]
		@fastmath writepixel(warped_img, i, j, pxy);
	    elseif fx == 0 && fy == y_max
                @fastmath @inbounds pxf = rwy * wx * img[fx+1,fy]
		@fastmath writepixel(warped_img, i, j, pxf);
	    elseif fx == x_max && fy == 0
		@fastmath @inbounds pfy = wy * rwx * img[fx,fy+1]
		@fastmath writepixel(warped_img, i, j, pfy);
	    elseif fx == x_max && fy == y_max
                @fastmath @inbounds pxy = rwy * rwx * img[fx,fy]
		@fastmath writepixel(warped_img, i, j, pxy);
	  end
	end

end

function writepixel{T<:Integer}(img::Array{T},i,j,pixelvalue)
  @fastmath @inbounds img[i,j]=round(T,pixelvalue)
end

function writepixel{T<:AbstractFloat}(img::Array{T},i,j,pixelvalue)
   @inbounds img[i,j]=pixelvalue
end

function writepixel{T<:Integer}(img::SharedArray{T},i,j,pixelvalue)
	@fastmath @inbounds img[i,j]=round(T,pixelvalue)
end

function writepixel{T<:AbstractFloat}(img::SharedArray{T},i,j,pixelvalue)
   @inbounds img[i,j]=pixelvalue
end

function writepixel{T<:Integer}(img::SharedArray{T},i,j,pixelvalue)
  img[i,j]=round(T,pixelvalue)
end

function writepixel{T<:AbstractFloat}(img::SharedArray{T},i,j,pixelvalue)
  img[i,j]=pixelvalue
end


text:
# You are given the following information, but you may prefer to do some
# research for yourself.
#
# * 1 Jan 1900 was a Monday.
# * Thirty days has September,
#   April, June and November.
#   All the rest have thirty-one,
#   Saving February alone,
#   Which has twenty-eight, rain or shine.
#   And on leap years, twenty-nine.
# * A leap year occurs on any year evenly divisible by 4, but not on a century
#   unless it is divisible by 400.
#
# How many Sundays fell on the first of the month during the twentieth century
# (1 Jan 1901 to 31 Dec 2000)?

import Dates
using ProjectEulerSolutions

# Trivial with the Dates module
function p019solution(first_year::Integer=1901, last_year::Integer=1901)::Integer
    total_days = 0
    for y in first_year:last_year
        for m in 1:12
            if Dates.dayofweek(Dates.Date("$y-$m-1")) == 7
                total_days += 1
            end
        end
    end
    return total_days
end

p019 = Problems.Problem(p019solution)

Problems.benchmark(p019, 1901, 2000)

max_stars_repo_name: gnujosh/julia-euler-project

max_issues_repo_name: gnujosh/julia-euler-project

max_forks_repo_name: gnujosh/julia-euler-project


text:
using PyPlot
using Camera
using SceneObjects
using Lighting

function render(object::Object; figAxis = [-1, 1, -1, 1], figNum=1, figTitle="Object")
  # make figure figNum current figure
  figure(figNum)
	# clear content of figure figNum
	clf()
  title("$figTitle");
	# set and label axis
	axis(figAxis)
	xlabel("X Axis")
	ylabel("Y Axis")
	# isometric z-projection of vertices onto plane z=0
	x = [v.e1 for v in object.vertices]
	y = [v.e2 for v in object.vertices]

	# plot projection data
	plot(x,y);
  show();
end

function render(object::Object, camera::ICamera; figNum=1)
	# transform scene given in world coordinates to camera space
	camObject = camera.worldToCam * object
	render(camObject; figNum=figNum);
end

function tracerays(scene::Scene, lights::SceneLights, camera::ICamera, shader::Function)
  nx = camera.nx;
  ny = camera.ny;
  screen = Array(Float32, nx, ny);
  for i = 1:nx
    for j = 1:ny
      ray = generateRay(camera, i, j);
      screen[i, j] = shader(ray, scene, lights);
    end
  end

  figure();
  gray();
  imshow(screen');
  colorbar();
end

max_stars_repo_name: fpoppinga/cg

max_issues_repo_name: fpoppinga/cg

max_forks_repo_name: fpoppinga/cg


text:
#=##############################################################################################
Filename: solve_wing_viscous_drag.jl
Author: Ryan Anderson
Contact: rymanderson@gmail.com
README: define an `Action` object to solve a CCBlade rotor
=###############################################################################################

"""
    solve_wing_viscous_drag <: Action

Inputs:

* `aircraft::Aircraft` : `Aircraft` system object
* `parameters<:Parameters` `Parameters` struct
* `freestream::Freestream` : `Freestream` object
* `environment::Environment` `Environment` object
* `step_range::AbstractArray` : array of times for which the simulation is run
* `stepi::Int` : index of the current step
* `step_symbol::String` : defines the step, e.g. `alpha` or `time`

`parameters <: Parameters` requires the following elements:

* `cls::Vector{Array{Float64,2}}` : each element is an array of size (nspanwisepanels, nsteps) containing local lift coefficients at each lifting line section, corresponding to each lifting surface
* `wing_strip_ys::Vector{Vector{Float64}}` : [i][j]th element is the jth dimensional spanwise coordinate coinciding with control points of the lifting line of the ith lifting surface
* `wing_strip_polars Vector{Vector{<:CCBlade.AFType}}` : [i][j]th element is a `<: CCBlade.AFType` object corresponding to the jth lifting line section of the ith lifting surface
* `cds_viscous::Vector{Array{Float64,2}}` : each element is an array of size (nspanwisepanels, nsteps) containing viscous-corrected local drag coefficients at each lifting line section, corresponding to each lifting surface
* `CDs_viscous::Array{Float64,1}` : ith element is the drag coefficient of the aircraft at the ith step

"""
function solve_wing_viscous_drag(aircraft, parameters, freestream, environment, step_range, stepi, step_symbol)
    # extract parameters
    cls = parameters.cls
    cds = parameters.cds
    wing_strip_ys = parameters.wing_strip_ys
    wing_strip_polars = parameters.wing_strip_polars
    # apply viscous correction
    nwings = length(aircraft.wing_system.system.surfaces)
    for iwing in 1:nwings

    end
    # update cds of aircraft.wing_system.system

    # extract forces and moments
    CF_viscous, CM_viscous = VL.body_forces(aircraft.wing_system.system; frame=VL.Wind())
    # store to `parameters`
    for iwing in 1:nwings
        parameters.cds[iwing][:,stepi] = cfs[iwing][1,:]
        parameters.cmxs[iwing][:,stepi] = cms[iwing][1,:]
        parameters.cmys[iwing][:,stepi] = cms[iwing][2,:]
        parameters.cmzs[iwing][:,stepi] = cms[iwing][3,:]
    end
    parameters.cds_viscous[stepi] .= cds_viscous
    parameters.CDs_viscous[stepi] = CF_viscous[1]

    return false
end

"""
solve_wing_viscous_drag(system, step_range)

Method returns initialized elements required for the `parameters <: Parameters` struct during simulation.

Inputs:

* `aircraft::Aircraft` : aircraft system to be simulated
* `step_range::AbstractArray` : defines each step of the simulation

Outputs:

* `CLs::Array{Float64,1}` : ith element is the lift coefficient of the aircraft at the ith step
* `CDs::Array{Float64,1}` : ith element is the drag coefficient of the aircraft at the ith step
* `CYs::Array{Float64,1}` : ith element is the side force coefficient of the aircraft at the ith step

"""
function solve_wing_viscous_drag(aircraft, step_range)

    CLs = zeros(length(step_range))
    CDs = zeros(length(step_range))
    CYs = zeros(length(step_range))

    return CLs, CDs, CYs
end

max_stars_repo_name: byuflowlab/AircraftSystems

max_issues_repo_name: byuflowlab/AircraftSystems

max_forks_repo_name: byuflowlab/AircraftSystems


text:
module TDD

    #Step 1
    function returnConnectedNode(graph::Vector{Vector{Int64}}, node::Int64)
        result = graph[node]
        if !(node in result)
            push!(result, node)
        end
        return sort(result)
    end

end


text:
using Home
using Test

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

max_stars_repo_name: carezende/homepage

max_issues_repo_name: carezende/homepage

max_forks_repo_name: carezende/homepage


text:
module CommunalHelperEntityPresets

const CustomDreamBlockData = :(dreamblock(
    x::Integer,
    y::Integer,
    width::Integer=Maple.defaultBlockWidth,
    height::Integer=Maple.defaultBlockHeight,
    featherMode::Bool=false,
    oneUse::Bool=false,
    refillCount::Integer=-1,
    below::Bool=false,
    quickDestroy::Bool=false,
))

const CustomCassetteBlockData = :(cassetteblock(
    x::Integer,
    y::Integer,
    width::Integer=Maple.defaultBlockWidth,
    height::Integer=Maple.defaultBlockHeight,
    index::Integer=0,
    tempo::Number=1.0,
    customColor="",
))

end


text:
# ---
# title: 690. Employee Importance
# id: problem690
# author: Tian Jun
# date: 2020-10-31
# difficulty: Easy
# categories: Hash Table, Depth-first Search, Breadth-first Search
# link: <https://leetcode.com/problems/employee-importance/description/>
# hidden: true
# ---
#
# You are given a data structure of employee information, which includes the
# employee's **unique id** , their  **importance value** and their  **direct**
# subordinates' id.
#
# For example, employee 1 is the leader of employee 2, and employee 2 is the
# leader of employee 3. They have importance value 15, 10 and 5, respectively.
# Then employee 1 has a data structure like [1, 15, [2]], and employee 2 has [2,
# 10, [3]], and employee 3 has [3, 5, []]. Note that although employee 3 is also
# a subordinate of employee 1, the relationship is **not direct**.
#
# Now given the employee information of a company, and an employee id, you need
# to return the total importance value of this employee and all their
# subordinates.
#
# **Example 1:**
#
#
#
#     Input: [[1, 5, [2, 3]], [2, 3, []], [3, 3, []]], 1
#     Output: 11
#     Explanation:
#     Employee 1 has importance value 5, and he has two direct subordinates: employee 2 and employee 3. They both have importance value 3. So the total importance value of employee 1 is 5 + 3 + 3 = 11.
#
#
#
#
# **Note:**
#
#   1. One employee has at most one **direct** leader and may have several subordinates.
#   2. The maximum number of employees won't exceed 2000.
#
#
## @lc code=start
using LeetCode

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


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

using Markdown
using InteractiveUtils

# ╔═╡ 9dfa6a82-3b9d-11eb-2557-3bb72249910a
using PaddedViews

# ╔═╡ 97dcb6ca-3b9b-11eb-2c96-0904d9a90046
s="""L.LL.LL.LL
LLLLLLL.LL
L.L.L..L..
LLLL.LL.LL
L.LL.LL.LL
L.LLLLL.LL
..L.L.....
LLLLLLLLLL
L.LLLLLL.L
L.LLLLL.LL"""

# ╔═╡ 1501f7ee-3ba3-11eb-2b57-7b10a8d1d5d4
sbig="""LLLLLLLLLLLLLLLLLLLLLLL.LLLLLLL.L.LLLLL.LLLL.LLLLLLLLL..LLL.LLLLLLLLLLLLLL.LLLLLLLLL.LLL.LLLLLL
LLLLLLLLLL.L.LLLLLLL.LL.LLLLLLL.LLLLLLLL.LLLLLLLLLLLLL.LLLLLLLLLLL.LLLLLLLL.LLLLLLLLLLLL.LLLLLL
LLLLLLLL.L.LLLLLLLLLLLL.LLLLLLL.LLLLLL.LLLLL.LLLLLLLLL.LLLLLLLLLLL.LLLLLLLLLLLLLLLL.LLLL.LLLLLL
.LLLLLLLLLLLLLLLLL.LLLL.LLLLLLL.LLLLLL.LLLLL.LLL.LLLLLLLLLL.LLLLLL.LLLLLLLL.LLLLLL.LLLLL.LLLLLL
LLLLLLLLLLLLLLLLLLLLLLL.LLLLLLL.LLL.LLLLL.LL.LLLLLLLLL.LLLL.LLLLLL.LLLLLLLL.LLLLLLL.LLLL.LLLLLL
LLL.LL..L..L.LL.L.L........L.............LLL....LL...L..L.L.....L..L.L.......L..L......LLLL.L.L
LLLLLLLLLLLLLLLLL..LLLL.LLLLLLL.LLLLLL.LLLLL.LLLLLLLLL.LLLL.LLLLLLLLLLLLLLL.LLLLLLL.LLLLL.LLLLL
LLLLLLLLLL.LLLL.LL.LLLL.LLLLLLLLLLLLLLLLLL.L.LLLLLLLLL.LLLL.L.L.LL.LLLLLLLLLLLLL.LL.LLLLLLLLLLL
LLLLLLLLLLLLLLLLL.LLLLL.LLLLLLL.LLLLLLLLLLLL.LLLLLLLLL.LLLL.LLLLLLLLLLLLLLL.LL.LLLLLLLLL.LLLLL.
LLLLLLLLLLLLLLLLL..LLL.LLLLLLLLLLLLLLL.LLLLL.LLLLLLLLL.LLLL.LLLLLL.LLLLLLLL.LLLLLLLLLLLL.LLLLLL
LLLLLLLLLL.LLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLL.LLLL.LLLLLLLLLLLLL.LLLL.LLLLLLLLLLL
LLLLLLLLLL.LLLLLLL.LLLLLLLLLLLL.LLLLLL.LLL.L..LLLLLLLL.LLLL.LLLLLL..LLLLLLLLLLLLLLL.LLLL.LLLLLL
L.LLLLLLLL..LLLLLL.LLLL.LLLLLLLLLLLLLL.LLLLL.LLLLLLLLLLLLLL.LLLLLLLLL.LLLLL.LLLLLLL.LLLL.LLLLLL
.LLLLLLLLL.LLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLL.LLLLLLL.LLLLLLLLLLL
LL.L..LL...LL..L..L.L.L.....L..LL...L.LLL......L.L...L.LL...L.L.L.........L.LL....L.LL.LL...LL.
LLLLLLLLLLLLLLLLLLLLLLL.LLLLLLL.LLLLLLLLLLLLLLLLLLLLLL.LLLL.LLLLLL.L.LLLLLLLLLLLLLL.LLL..LLLLLL
LLLLL.LLLL.LLLL.LLLLLLLLLLLLLLL.LLLLLL.L.LLL.LLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLL.LLLLLLL
LLL.LLLLLL.LLLLLLL.LLLL.LLL.LLL.LLLL.L.LL.LLLLLLLLLLLL.LLLL.LLL.LL.LLLLLLLLLLLLLLLLLLLLL.LL.LLL
LLLLLLLLLL.LLL.LLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLL.LLLLLLLLLLLLLLLL.LLLL.LLLLLL
...L...L..L.L...L..L......L.......L.L...L...L...L.....L...L...L....L...LL..L..L.............LL.
LLL..LLLLL.LLLLLLLLLLLL.LLLLLLL.LLLLLL.LLLLLLLLLLL.LLL.LLLL.LLLLLL.LLLLLLLLLLLLLLLL.LLLLL.LLLLL
LLLLLLLLLL.LLL..LLLLLLL.L.LLLLL.LLLLLLLLLLLL.LLLLLLLLL.LLLLLLLLLLL.LLL.LLLLLLLLLLLLLLLLLLLLLLLL
LLLLLL.L.L.L.LLLLLLLLLL.LLLLLLL.LLLLLL.LLLLL.LLLLLLLLLLLLLL.LLLLLL.LLLLLLLL.LLLLLLL.LLLL.LLLLL.
LLLLLL.LLL.LLLLLLLLLLLL.LLLLLLL.L.LLLLLLLLLL.LLLLLLLLL.LLLL.LLLLLL.LLL.LLLL.LLLLLLL.LLLL.LLLLL.
LLLLLLLLLL.LLLLLLL.LLLL.LLLLLLL.LLLLLL.LLLLL.LLL.LLLLL.L.LL.LLLLLL.LLLLLLLL..LLLLLLLLLLL.LLLLLL
LLLLLL.LLL.LLLLLLL.LLLL.LLLLLLL.LLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLL.LLLLLLLL.LLLLLLL.LLLLLLLLLLL
LLLLLLLLLL.LLLLLLL.LLLL.LLLLLLLLLLLLLLLLLLLL.LLLLLLLLL.LLLL.LLLLLL.LLLLLLL..LLLLLLLLL.LL.LLLLLL
LLLLLLLLLLLLLLLLLLLLLL..LLLLLLL.LLLLLL.LLLLL.LL.LLLLLL.LLLLLLLLLLL.LLLLL.L.LLLLLLLLLLLLL.LLLLLL
LLLLLLLLLL.LLLLLLLLLLLL.LLLLLLL.LLLLLLL.LLLL.LLLLLLLLLLLLLL.LLLLLLLLLLLLLLL.LL.LLLL.LLLL.LLLLLL
.L......L..L........LL..LLL...LL.L.....L..L.L..LLL..LLL..LL.LL...LLL.......L...LL...........LLL
LLLLLLLLLL.LL.LLLL.LLLL.LLLLLLL.LLLLL.LLLLLL.LLLLLLLLL.LLLLLLLLLLL.LLLLLLLL.LLLLLLLLLLLL.LLLLLL
LLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLL.LLLLL.LLL.LLLLLLLLLLL.LLLLLLLLLLLLLLLL.LLLL.LLLLLL
LLLLLLLLLL.LLLLLLL.LLLL.LLLLLL..LLLLLL.LLLLLLLLLLLLLLL.LL.L.L.LLLLLLLLLLLLL.LLLLLLL.LLL..LLLLLL
LLLLLL.LLL.LLLLLLL.LLLLLLLLL.LL.LLLLLL.LLLLLLLLLLLLLLL.LLLL.LLLLLL.LLL.LLLL.LLLLLLL.LLLL.LLLLLL
LLLLLLLLLLLLLLLL.L.LLLL.LLLLLL..LLLLLLLLLLLL.LLLLLLL.L.LLLLLLLLLLL.LLLLLLLL.LLLLLLL.LLLL..LLLLL
LLLLLLLLLL.LLLLLLL.LLLL.LLLLLLL.LLLLLLLLLLLL.LLLLLLLLLLLLLL.LLLLLL.LL.LLLLL.LL.L.LL.LLLLLLLLLLL
LLLLLL.LLL.LLLLLLL.LLLLLLL.LLLL.LLLLLLLLLLLL.LLLLLLLLL.LLL.LLLLLLL.LLLLLLLLLLLLLLL..LLLL.LLLLLL
LL.LLLLLLL.LLLLLLL.LLLLLLLLLLLL.LLLLLLLLLLLLL.LLLLLLLLLLLLLLLL.LLL.LLLLLLLL.LLLLLLLLLLLLLL.LLLL
LLLLLLLLLL.LLLLLLL.LLLL.LLL.LLL.LLLLLL.LLLL..LLLLLLLLLLLLLL.LLLLLLLLLLLLLLL.LLLLLLL.LLLL.LLLLLL
........LL.L..LLLL..L..LLLL..LLL.........L.L......LL.LL..L........L...L..LL..LLLL.L.L.....L.LL.
LL.LLLLLLL.LLLLLLL.LLLL.LLLL.LL.LLLLLLLLLLLLLLLLLLLLLL.LLLL.LLLLL..LLLLLLLLLLLLLLLL.LLLLL.L..LL
LLLLLLLLL.LLLLLLLL.LLL..LLLLLLL.LLLLLL.LLLLL.LLLLLLLLL.LLLL.LLLLLLLLLL.LLLL.LLLL.LLLLLLLLLLLLLL
LL.LLLLLLL.LLLLLLL.LLLL.LLLLLLLLLLLLLL.LLLLLLLL.LLLLLLLLLLL.LLLLLL.LLLLLLL..LLL.LLLLLLLLLL.LLLL
LLLLLLLLLLLLLLLLLLLLLLL.LLLLLLL.LLLLLLLLLLLL.LLLLLLLLL.LLLL.LLLLLL.LLL.LLL..LLLLLLL.LLLL.LLLLLL
LLL.LLLLLL.LLLLLLLLLLLLLLLLLLLL.LLLLLL..LLL.LLLLLLLLLL.LLLL.LLLLLL.LLLLLLLLLLLLLLLL.LLLL.LLLL.L
LLLLLLLLLL.LLLLLLL.LLLLLLLLLLLL.LLLLLL.LLLLLLLL.LLLLLLLLLLL.LLLLLL.LL.LLLL..LLLLLLLLLLLLLLLLLLL
..LL..LLL.....LL......L..L.L.LLL........LL......LLL...L......L.LL..L.LL.LL.L.......LL....LL...L
.LL.LLLLLLLLLLLLLL.L.LL.LLLLLLL.LLL.LL...L.L.LLLLLLLLL.LLLLLLLLLLLLL.LLLLLL.LLLLLLL.LLLL.LLLLLL
L.LLLLLLLLLLLL.LLL.LLLL.LLLLLLL.LLLLLLLLLLLL.LLLLLLLLLLLL.LLLLLLLL.LLL.LLLL.LLL.LLL.LLLL.LLLLLL
LLLLLLLLLL.LLLLLLL.LLLL.LLLLLLL.LLLLLLLLLLLL.LLLLLLLLL.LLL..L.LLLL.LLLLLLLL..LLL.LLLLLLL.LLLLLL
.LLLLLLLLL.LLL.LLL.LLLL.LLL..LLLLLLLLLLLLLLLLLLLLLLLLLL.LLL.LLLLLL.LLLLLLLL.LLLLLLL.LLLL.LLLLLL
L..L...LL...L.LL....L.LL.L..LL.L.........L.........LLLL..L.L..LL...L.L.L....LLL.....L..L.L...LL
.LLLLLLLLL.LLLL.LL.LLLL.LLLLLLLLL.LLLL.LLLLL.LLL.LLLLL.LLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLL.LLLLLL
LLLLLLLLLL.L..LLLL.LLLL.LLLLLLL..LLLLLLLLLLL.LLLLLLLLL.LLLL.LLLLLLLLLLLLLLL.LLLLLLLLLLLL.LLLLLL
LLLLLLLLLL.LLLLLLL.LLLL.LLLLLLL.LLLLLL.LLLLLLLL.LLLLL.LLLLLLLLLLLL.LLLLLLLL.LLLLLLL.LL.LLLLL.LL
LLLLLLLLLL.LLLLLLL.LLLL.LLLLLLL.LLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLL.LLLLLLL.LLLLLLLLLLL
L.LLLLLLLL.LLLLLLLLLLLL.LLLL.LL..LLLLL.LLLL.LLLLLL.LLLLLLLL.LLL.LLLLLLLLLLLLLLLLL.L.LLLL.LLLLLL
LLLLLLLLLL..LLLLLL.LLLLLLLLLLLL.L.LLLL.LLLLLLLLLLLLLLL.LLLL.LLLLLL..LL.LLLL.LLLLLLL.LLLL.LLLLLL
LLL.LLLLLLLLLLLLLL.LLLLLLLLLLLL.LL.LLL.LLLLL.LLLLL.LLL.LLLL.LLLLLL.LL.LLLL..LLLLLLL.LLLLLLLLLLL
LLLLLLLLLL.LLLLLLLLLLLL.LLLLLLL.LLLLLL.LLLLL.LLLLLLLL..LLLL.LLLLLLLLLLLLLLL.LLLLL.LLLLLL.LLLLLL
L.L...L...L..L..L....L...L..LLL..L....L..LL...LLL.LL.L...L.L..L.LLL..L....L.L...LL..L..L.L..L.L
LLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLL.LLLLLLLLL.LLLL.LLLLLL.LLLLLLLL.LLLLLLL.LLLL.LLLLLL
LLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLL.LLLL.LLLLLLLLLLLLLLLLLLLLLLL.LLLLL.LLL.L
LLLLLLLLLL.LLLLL.L.LLLL.LLLLLLL.LLLLLLLLLLLL.LLLLLLLLL.LLLL.LLLLLL.LLLLLLLLLLLLL.LLLL.LLLLLLLLL
L..LLLLLLLLL.LLLLL.L.LLLLLL.LLL.LLLLLL.LLLLLLLLLLLLLLL.LLLL.LLLLLL.LL.LLLLLLLLLLLLL.LLLLLLLLLLL
LLLLL.LLLL.LLLL.LL.LLLL.LLLLLLLLLLLLLLLLLLLL.LLLLLLLLL.LLLLLL.LL.L.LLL.LLLLLLLLL.LL.LLLL.LLLLLL
....L....L..L.....L....L..LL....L.L..L..LL.LLL...L.....L.LLL.L.LL.....L....L.L........L.LLL....
L.L.LL.LLL.LLLLL.L.LLLL.LLLLLLL.LLLLLL.LLLLL.LLLLLLLLL.LLLL.LLLLLLLL.LLLLLLLLLLL.LL.LLLL.LLLLLL
LLLLLLLLL.LLLLLLLL.LLLL.LLLLLLL.LLLLLL.LLLLL.LL.LLLLLL.LLLL.LLLLLL.LLLLLLL.LLLLLLLL.LLLL.LLLLLL
LLLLLLLLL.LL.LLLLLLLLLL.LLLL.LLLL.LLLLLLLLLLLLLLLLLLLL..LLL.L..LLL.LLL.L.LL.LLLLLL..LLLL.LLLLLL
LLLLLLLLLL.LLLLLLL.LLLL.LLLLLLL.LLLLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLL.LLLLLLLLLLL
LLLLLLLLLLLLLLLLLLLLLLL.LLLLLLL.LLLLLLLLLLLL.LLLLLLLLL.LLLL.LLLLLLLLLLLL.LL.LLLLLLL.LLLL.LLLLLL
.....LL.LL.L.....LL.LL..L...L...LLLLL......L.L....LL...LLL...LLLLL..LL..L....L......L.......L.L
LLLLLLLLLL.LLLL.LL.LLLL.L.LLLLL.LLLLLL.LL.LL.LLLLLLLLL.LLLL.LLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLLLLL
LLLLLLLLLL.LLLLLLL.LLLL.LLLLLLL.LLL.LL.LLLLL.LLLLLLLLLLLLLLLLLLLLL.LLLLLLLLLLLLLLLL.LLLLLLLLL.L
LLLL.LLLLL.LLLLLLL.LLLL.LLLLLLL.LLLLLL.LLLLLLL.LLLLLLLLLLLLLLLLLLL.LLLLLLLL.LLLLLLLLLLLL.LLLLLL
LLLLLLLLL..LLLLLLL.L.LL..LLLLLLLLLLLLL.LLLLL.LLLLLLLLLLLLLL.LLL.LL.LLLLLLLL.LLLL.LLLLLLLLLLLLLL
LLLLLLLLLLLLL.LLLLLLLLL.LLLLLL..LLLLLL.LLLLL.LLLLLLLLLLL.LLLLLLLLLL.LLLLLLL.LLLLLLL.LLLLLLLLLLL
..LLL..L..L...L..L..L.L.....L............L.....L..L....L.LL......L.....L..LLL..L.L..L..........
LLL.LLLLLL.LLLLLLLLLLLL.LL.LLLLLLLLLLL.LLLLLL.LLLLLLL..LLLL.LLLL.L.L.LLLL.LLLLLLLLLLLLLLLLLLLLL
LLLLLLLLLL.LLLLLLL.LLLL.LLLLLLL.LLLLLL.LL.LL.LLLLLLLLLL.LLL.LL.LLLLLLLLLLLL.LLLLLLLLLLLL.LLLLLL
.LLLLLLLLL.LLLL.LLLLLLLLLLLLL...LL.L.LLLLLLL.LLLLLLLLLLLLLLLLLLLLL.LLLLLLLL.LLLLLLLLLL.L.LLLLLL
LLLL.LLLLLLLLLLLLL.LLLL.LLLLLLLLLLLLLL.LLLLL.LLLLL.LLL.LLLL.LLLLLLLLLLLL.LLLLL.LLLLLLLLLLLLLLLL
LLLLLLLLLL.LLLLLLL.LLLLLLLLLLLL.LLLLLL.LLLLL.LLLLLLLLL.LLLLL.LLL.L.LLLLLLLL.LLLLLL..LLLLLLLLLLL
.LLLLLLLLL.LLLLLLL.LLLL.LLLLLL..LLLLLL.LLLLL.LLLLLLLLLLLLLLLLLLLLL.LLLLLLLL.LLLLLLL.LLLL.LLLLLL
.L.....LL......L........L.L....LLL......L...L.LL...L...L..LL................L...L..L...........
LLLLLLLLLL.LLLLLLL.LLLL.LLLL.LL.LLLLLL.LLLL..LLLLLLLLLLLLLLLLLLLLL.LLLLLLLL.LLLL.LL.LLL.LLLLLLL
LLLLLL.LLL.LLLLLL..LLL..LLLLLL..LLLLLL.LLLL..LLLLLLLLLLLLLLLLLLLLL.LLLLLLLL.LLLLLLL..LLLLLLLLLL
LLLLLL..LL.LLLLLLL.LLLL.LLLL.LL.LLL.LL.LLLLLLLLLLLLLLLLLLLL.LLLLLL.LLLLLLLLLLLLLLLL.LLLLLLLLLLL
LLLLLLLLLL.LLLLLLL.LLLLLLLLLLLL.LLLLLL.LLLLLLLLLLLLLLL.LL.L.LLLLLL.L.LLLLLL.LLLLLLLLLLLLLLLL.LL
LLLLLLLLLL.LLLLLL.LLLLLLL.LLLLL.LLLLL.LLLLLL.L.LLLLLLL.LL.LLLLLLLLLLL.LLLLLLLLLLLLL.LLLLLLLLLLL
LLLLLLLLLL.LLLLLLL.LLLL.LLLLLLLLLLLLLL.LLLL..LLLLLLLLL.LLLLLLLLLLLLL.LLLLLL.LLLLLLL.LL.L.LLLLLL
LLLLL.LLLL.LLLLLLL..LLLLLLLLLLL.LLLLLL.LLL.L.L.LLLLLLLLLLLL.LLLL.L.LLLLLLLL.LLLLLLL.LLLLLLLLLLL
....LLL...LLL.....L.L...LL...L..L....LL...L.L.LLLLL....L......LLLL......L..LLLLL.L.LL...LL..LLL
LLLLLLLLLLLLLLLLLLLLLLL.LLLLLLL.LL.LLL.LLLLL.LLLLLLLLL.LLLL.LLLLLL.LLLLLLLL.LLLLLLLLLLLL.LLLLLL
LLLLLLLLLLLLLLLLLL.LLLLLLLLLLLL.LLLLLL.LLLLL.LLLLLLLLL.LLLL.LLLLLL.LLLLLLLLLLLLLLLL.LLLLLLLLLLL
.LLLLLLLLL.L..LLLLLLLLLLLLLLLLL.LLLLLL.LLLL..LLLLLLLLL.LLLLLLLLLLL.LLLLLLLLLLLLLLLL.LLLLLLLLLLL
LLLLLLLLLL.LLLLLLL.LLLL.L.L.LLLLLLLLLL.LLLLLLLLLLLLLLLLLLLL.LLLLLL.LLLLLLLL.LLL.LLLL.LLL.LLLLLL
LLLLLLLLLLLLLLLLLL.LLLL.LLLLLLLLLLLLLLLLLLLLLLLLLLLLLL.LLLL.LLLLLL.LLLLLLLL..LLLLLL.LLLL.L.LLLL"""

# ╔═╡ c06dfe28-3b9b-11eb-0e90-73b965f01cef
res = collect.(split(sbig))

# ╔═╡ f2078fda-3b9b-11eb-02f6-69faf6d6ce6b
parsedict = Dict('L'=>0, '.'=>-1, '#'=>1)

# ╔═╡ 74450896-3ba2-11eb-27f9-5f052f8bf906
printdict = Dict(-1 => '.', 0 => 'L', 1 => '#')

# ╔═╡ 39aeaf84-3b9d-11eb-209a-15a19031a709
state = ((ch -> parsedict[ch]).(hcat(res...)))'

# ╔═╡ 85e5c7d2-3b9d-11eb-2a71-9fff27469aa8
function nextstate(state, countfn, occthreshold)
	emptyseat = state .== 0
	occupied = state .> 0
	occneigh = countfn(state)
	update1 = (emptyseat) .& (occneigh .== 0)  # 0 -> 1
	update2 = (occupied) .& (occneigh .>= occthreshold)  # 1 -> 0
	anyupdate = (sum(update1) + sum(update2)) > 0
	state + update1 - update2, anyupdate
end

# ╔═╡ 716c36ee-3b9d-11eb-02cd-59c13327fbb4
function run(countfn, occthreshold; maxiter=100)
	mystate = state
	for i=1:maxiter
		mystate, anyupdate = nextstate(mystate, countfn, occthreshold)
		if anyupdate
			println("Updated")
		else
			println("No change after $i steps")
			println("Sum:", sum(mystate.==1))
			break
		end
		#printstate(mystate)
	end
	mystate
end

# ╔═╡ 837a6fae-3ba2-11eb-3dd4-a971f8334552
function printstate(state)
	for col = 1:size(state, 1)
		for row = 1:size(state, 2)
			print(printdict[state[col,row]])
		end
		println()
	end
	println()
end

# ╔═╡ eb8e5ce6-3ba6-11eb-34e1-c541043ea307
"""
Part 2: for each seat, count the occupancy of the next seats in each of the eight cardinal directions.
"""
function countoccupiedneighbours2(state)
	accum = zeros(Int64, size(state))
	row, col = size(state)
	for i=1:row
		for j=1:col
			if state[i, j] < 0
				continue
			end
			for delta in (
					[0,1], [0,-1], [1,0], [-1,0],
					[1,1], [1,-1], [-1,1], [-1,-1])
				pos = [i,j] + delta
				while ((1 <= pos[1] <= row)
						&& (1 <= pos[2] <= col)
						&& (state[pos...] < 0))
					pos += delta
				end
				if ((1 <= pos[1] <= row) && (1 <= pos[2] <= col))
					if state[pos...] == 1
						accum[i,j] += 1
					end
				end
			end
		end
	end
	accum
end

# ╔═╡ f89e53ea-3c7c-11eb-323b-576f7f77da00
sum(run(countoccupiedneighbours2, 5) .== 1)

# ╔═╡ 19ad6462-3b9f-11eb-056e-1b99dc5b3979
"""
Shifts an array left or right and/or up or down and pads the empty row/column.
"""
function shiftpad(a, leftright, topbottom; v=0)
	row, col = size(a)
	if leftright == "l"
		yold = 1:col-1
		ynew = 2:col
	elseif leftright == "r"
		yold = 2:col
		ynew = 1:col-1
	else
		yold = ynew = 1:col
	end
	if topbottom == "t"
		xold = 1:row-1
		xnew = 2:row
	elseif topbottom == "b"
		xold = 2:row
		xnew = 1:row-1
	else
		xold = xnew = 1:row
	end

	PaddedView(v, convert(Array{Int64,2}, a)[xold, yold], (1:row, 1:col), (xnew, ynew))
end

# ╔═╡ 6100b904-3b9f-11eb-1d2e-d5f8ed748767
"""
Sums up the values in the eight neighbouring cells for a 2D array.
"""
function neighboursum(a)
	accum = zeros(Int64, size(a))
	for lr in ("", "l", "r")
		for tb in ("", "t", "b")
			if lr == "" && tb == ""
				continue
			end
			accum += shiftpad(a, lr, tb)
		end
	end
	accum
end

# ╔═╡ 222c5fc0-3c7c-11eb-3f59-095768dc679b
"""
Part 1: for each seat, count the occupied seats amongst the eight neighbouring spaces.
"""
function countoccupiedneighbours(state)
	neighboursum(state .> 0)
end

# ╔═╡ b5b08618-3c7c-11eb-1a95-25275bbf81af
sum(run(countoccupiedneighbours, 4) .== 1)

# ╔═╡ Cell order:
# ╠═97dcb6ca-3b9b-11eb-2c96-0904d9a90046
# ╟─1501f7ee-3ba3-11eb-2b57-7b10a8d1d5d4
# ╠═c06dfe28-3b9b-11eb-0e90-73b965f01cef
# ╠═f2078fda-3b9b-11eb-02f6-69faf6d6ce6b
# ╟─74450896-3ba2-11eb-27f9-5f052f8bf906
# ╠═39aeaf84-3b9d-11eb-209a-15a19031a709
# ╠═85e5c7d2-3b9d-11eb-2a71-9fff27469aa8
# ╠═716c36ee-3b9d-11eb-02cd-59c13327fbb4
# ╠═b5b08618-3c7c-11eb-1a95-25275bbf81af
# ╠═f89e53ea-3c7c-11eb-323b-576f7f77da00
# ╠═837a6fae-3ba2-11eb-3dd4-a971f8334552
# ╠═eb8e5ce6-3ba6-11eb-34e1-c541043ea307
# ╠═222c5fc0-3c7c-11eb-3f59-095768dc679b
# ╠═6100b904-3b9f-11eb-1d2e-d5f8ed748767
# ╠═9dfa6a82-3b9d-11eb-2557-3bb72249910a
# ╠═19ad6462-3b9f-11eb-056e-1b99dc5b3979

max_stars_repo_name: st--/advent-of-code

max_issues_repo_name: st--/advent-of-code

max_forks_repo_name: st--/advent-of-code


text:
# Loggers to record properties throughout a simulation

export
    TemperatureLogger,
    log_property!,
    CoordinateLogger,
    StructureWriter

"""
    TemperatureLogger(n_steps)
    TemperatureLogger(T, n_steps)

Log the temperature throughout a simulation.
"""
struct TemperatureLogger{T} <: Logger
    n_steps::Int
    temperatures::Vector{T}
end

TemperatureLogger(T::Type, n_steps::Integer) = TemperatureLogger(n_steps, T[])

TemperatureLogger(n_steps::Integer) = TemperatureLogger(DefaultFloat, n_steps)

function Base.show(io::IO, tl::TemperatureLogger)
    print(io, "TemperatureLogger{", eltype(tl.temperatures), "} with n_steps ",
                tl.n_steps, ", ", length(tl.temperatures),
                " temperatures recorded")
end

"""
    log_property!(logger, simulation, step_n)

Log a property thoughout a simulation.
Custom loggers should implement this function.
"""
function log_property!(logger::TemperatureLogger, s::Simulation, step_n::Integer)
    if step_n % logger.n_steps == 0
        push!(logger.temperatures, temperature(s))
    end
end

"""
    CoordinateLogger(n_steps; dims=3)

Log the coordinates throughout a simulation.
"""
struct CoordinateLogger{T} <: Logger
    n_steps::Int
    coords::Vector{Vector{T}}
end

function CoordinateLogger(T, n_steps::Integer; dims::Integer=3)
    return CoordinateLogger(n_steps,
                            Array{SArray{Tuple{dims}, T, 1, dims}, 1}[])
end

function CoordinateLogger(n_steps::Integer; dims::Integer=3)
    return CoordinateLogger(DefaultFloat, n_steps, dims=dims)
end

function Base.show(io::IO, cl::CoordinateLogger)
    print(io, "CoordinateLogger{", eltype(eltype(cl.coords)), "} with n_steps ",
                cl.n_steps, ", ", length(cl.coords), " frames recorded for ",
                length(first(cl.coords)), " atoms")
end

function log_property!(logger::CoordinateLogger, s::Simulation, step_n::Integer)
    if step_n % logger.n_steps == 0
        push!(logger.coords, deepcopy(s.coords))
    end
end

"""
    StructureWriter(n_steps, filepath)

Write 3D output structures to the PDB file format throughout a simulation.
"""
mutable struct StructureWriter <: Logger
    n_steps::Int
    filepath::String
    structure_n::Int
end

StructureWriter(n_steps::Integer, filepath::AbstractString) = StructureWriter(
        n_steps, filepath, 1)

function Base.show(io::IO, sw::StructureWriter)
    print(io, "StructureWriter with n_steps ", sw.n_steps, ", filepath \"",
                sw.filepath, "\", ", sw.structure_n - 1, " frames written")
end

function log_property!(logger::StructureWriter, s::Simulation, step_n::Integer)
    if step_n % logger.n_steps == 0
        append_model(logger, s)
        logger.structure_n += 1
    end
end

function append_model(logger::StructureWriter, s::Simulation)
    open(logger.filepath, "a") do output
        println(output, "MODEL     ", lpad(logger.structure_n, 4))
        for (i, coord) in enumerate(s.coords)
            at = s.atoms[i]
            at_rec = AtomRecord(
                false, i, at.name, ' ', at.resname, "A", at.resnum,
                ' ', 10 .* coord, 1.0, 0.0, "  ", "  "
            )
            println(output, pdbline(at_rec))
        end
        println(output, "ENDMDL")
    end
end


text:
"""
    sample mean
"""
function sample_mean(x)
    N = length(x)
    n = length(x[1])
    μ = sum(x) ./ N
    return μ
end

"""
    sample covariance
"""
function sample_covariance(x, β)
    N = length(x)
    μ = sample_mean(x)
    P = sum([(x[i] - μ) * (x[i] - μ)' for i = 1:N]) ./ (2.0 * β^2.0)
    return P
end

"""
    deterministic sampling
"""
function resample(x, β)
    n = length(x[1])
    μ = sample_mean(x)
    P = sample_covariance(x, β)
    cols = Array(sqrt(P))
    xs = [μ + s * β * cols[:,i] for s in [-1.0, 1.0] for i = 1:n]
    return xs
end

function resample_vec(x, n, N, β)
    _x = [x[(i - 1) * n .+ (1:n)] for i = 1:N]
    return vcat(resample(_x, β)...)
end

function resample_vec(x, n, N, β, k)
    _x = [x[(i - 1) * n .+ (1:n)] for i = 1:N]
    xs = resample(_x, β)
    return xs[k]
end

function resample(μ, P, β::T) where T
    n = length(μ)
    cols = Array(sqrt(P))
    xs = [μ + s * β * cols[:,i] for s in [-1.0, 1.0] for i = 1:n]
    return xs
end


text:
# To ensure a build, it isn't sufficient to modify highs_common.jl.
# You also need to update a line in this file:
#     Last updated: 2022-04-22

include("../highs_common.jl")

script = build_script(shared_libs = "OFF")

products = [
    ExecutableProduct("highs", :highs),
]

# In addition to BSD systems, we don't need to expand the C++ string ABI on Windows, because
# we're doing a fully static build, so no need to match user's libstdc++.
platforms = expand_cxxstring_abis(platforms; skip=!Sys.islinux)

dependencies = [
    # We do fully static build only on Windows, so in that case `CompilerSupportLibraries_jll`
    # is a build-only dependency, in the other cases it's also a runtime one.
    Dependency("CompilerSupportLibraries_jll"; platforms=filter(!Sys.iswindows, platforms)),
    BuildDependency("CompilerSupportLibraries_jll"; platforms=filter(Sys.iswindows, platforms)),
]

build_tarballs(
    ARGS,
    name * "static",
    version,
    sources,
    script,
    platforms,
    products,
    dependencies;
    preferred_gcc_version = v"6",
    julia_compat = "1.6",
)

max_stars_repo_name: MichelJuillard/Yggdrasil

max_issues_repo_name: MichelJuillard/Yggdrasil

max_forks_repo_name: MichelJuillard/Yggdrasil