text:
using Test
using DelimitedFiles

@testset "Find neighbors" begin

    include("../src/init.jl")

    @testset "Neighbors inside domain" begin
        actual = neighbors(4, 12, 3, 4)
        expected = Dict{String,Int64}("S" => 3, "W" => 1, "N" => 5, "E" => 7)
        @test (actual == expected)
    end;

    @testset "Neighbors near boundary" begin
        actual = neighbors(11, 12, 3, 4)
        expected = Dict{String,Int64}("S" => 10, "W" => 8, "N" => -1, "E" => -1)
        @test (actual == expected)
    end;

end;

@testset "End-to-end tests" begin

    reference_8x4_output = readdlm("resources/reference_8x4_output.dat")

    @testset "1 process, 8x4 grid" begin
        cmd = `mpirun -np 1 julia ../src/Diffusion_run.jl resources/test1_params.yml`
        run(cmd)
        expected = reference_8x4_output
        actual = readdlm("resources/test1.dat")
        @test all(actual .≈ expected)
    end;

    @testset "1 process, 4x8 grid" begin
        cmd = `mpirun -np 1 julia ../src/Diffusion_run.jl resources/test2_params.yml`
        run(cmd)
        nx = 4
        ny = 8
        expected = transpose(reshape(reference_8x4_output, nx + 2, ny + 2))
        actual = reshape(readdlm("resources/test2.dat"), ny + 2, nx + 2)
        @test all(actual .≈ expected)
    end;

    @testset "2x1 processes, 8x4 grid" begin
        cmd = `mpirun -np 2 julia ../src/Diffusion_run.jl resources/test3_params.yml`
        run(cmd)
        expected = reference_8x4_output
        actual = readdlm("resources/test3.dat")
        @test all(actual .≈ expected)
    end;

    @testset "2x1 processes, 4x8 grid" begin
        cmd = `mpirun -np 2 julia ../src/Diffusion_run.jl resources/test4_params.yml`
        run(cmd)
        nx = 4
        ny = 8
        expected = transpose(reshape(reference_8x4_output, nx + 2, ny + 2))
        actual = reshape(readdlm("resources/test4.dat"), ny + 2, nx + 2)
        @test all(actual .≈ expected)
    end;

    @testset "1x2 processes, 8x4 grid" begin
        cmd = `mpirun -np 2 julia ../src/Diffusion_run.jl resources/test5_params.yml`
        run(cmd)
        expected = reference_8x4_output
        actual = readdlm("resources/test5.dat")
        @test all(actual .≈ expected)
    end;

    @testset "1x2 processes, 4x8 grid" begin
        cmd = `mpirun -np 2 julia ../src/Diffusion_run.jl resources/test6_params.yml`
        run(cmd)
        nx = 4
        ny = 8
        expected = transpose(reshape(reference_8x4_output, nx + 2, ny + 2))
        actual = reshape(readdlm("resources/test6.dat"), ny + 2, nx + 2)
        @test all(actual .≈ expected)
    end;

end;


text:
# Command line interface functions

using Base.Filesystem

tored = "\x1b[1;31m"
toblue = "\x1b[1;34m"
tonormal = "\x1b[1;0m"

clictx = nothing

function climain(args)
    local out = undef
    local outdir = undef

    if length(args) == 0
        clihelp()
    elseif length(args) == 1
        if args[begin] ∈ ("help", "-h", "--help")
            clihelp()
        else
            out = clicompileall(args[begin])
            outdir = dirname(abspath(args[begin]))
        end
    elseif length(args) == 2
        args[begin] ∉ ("run", "build", "generate") && clihelp()

        method = args[begin]
        src = args[end]
        out = clicompileall(src, method)
        outdir = dirname(abspath(src))

        # Run tmp program
        if method == "run"
            cmd = `$out`
            run(cmd)

            out = nothing
        end
    else
        clihelp()
    end

    if isa(out, String) && isa(outdir, String)
        cmd = `cp $out $outdir`
        run(cmd)
    end
end

function clihelp()
    text = [
            "usage:",
            "   alpha <file>.alpha              Compile <file>.alpha to <file>",
            "   alpha run <file>.alpha          Run <file>.alpha",
            "   alpha build <file>.alpha        Build <file>.o object file",
            "   alpha generate <file>.alpha     Generate <file>.asm assembly code",
            "   alpha help                      Show help",
            "   alpha -h                        Show help",
            "   alpha --help                    Show help",
        ]

    for t in text
        println(t)
    end
end

# Preprocesses the source code
function preprocess(code)
    code = replace(code, "\t" => "    ")
    code[end] != '\n' && (code *= "\n")

    return code
end

# Alpha to NASM from src (alpha) to out (asm)
function cligenerate(src, out)
    local code
    open(src) do io
        code = read(io, String)
    end

    code = preprocess(code)

    global clictx = parse(code)
    clictx.sourcecode = code

    semanticanalysis!(clictx)

    open(out, "w") do io
        println(io, codegen!(clictx))
    end
end

# Build asm to object
function clibuild(src, out)
    cmd = `nasm -o $out -f elf64 $src`

    try
        run(cmd)
    catch e
        clierr("Failed to build using NASM, fix errors above to build")
    end
end

# Links th alpha source object file
# with the alphalib to out
function clicompile(src, out)
    libdir = alphalibdir()
    alphalibbin = "$libdir/bin/alpha.o"

    # Build alphalib
    cmd = Cmd(`make`, dir=libdir)
    cmdout = IOBuffer()

    try
        run(pipeline(cmd, stdout=cmdout))
    catch e
        # Show stdout if needed
        cmdoutstr = read(cmdout, String)
        if cmdoutstr != ""
            println("$toblue* Command output:$tonormal")
            println(cmdoutstr)
        end

        clierr("Failed to build alphalib, fix errors above to compile")
    end

    cmd = `gcc -static -o $out $src $alphalibbin`
    try
        run(cmd)
    catch e
        clierr("Failed to link, fix errors above to compile")
    end
end

# Wrapper that compiles everything up to the stop step
# Returns the path of the output
function clicompileall(src, stop="compile")
    src = abspath(src)
    source = splitext(basename(src))[begin]

    # Auto deleted
    tmp = mktempdir()
    asmout = "$tmp/$source.asm"
    objout = "$tmp/$source.o"
    exeout = "$tmp/$source"

    # Generate
    climake(cligenerate, src, out=asmout)

    if stop == "generate"
        return asmout
    end

    # Build
    clibuild(asmout, objout)

    if stop == "build"
        return objout
    end

    # Compile
    clicompile(objout, exeout)

    return exeout
end

function clierr(msg)
    println(stderr, "$(tored)Error$tonormal : $msg")
    exit(-1)
end

# Runs the function fun on path
# which outputs path with the new extension ext
function climake(fun, path; newext = nothing, verifext = "alpha", out = nothing)
    err = false

    slash = findlast('/', path)
    period = findlast('.', path)

    slash == nothing && (slash = -1)
    if period == nothing || slash > period
        err = true
    else
        ext = path[period + 1:end]
        ext != verifext && (err = true)
    end

    if err
        clierr("Invalid file $toblue$path$tonormal, must have a .$verifext extension")
    end

    # Generate out
    newext != nothing && out != nothing && (out = path[begin : period - 1] * "." * newext)

    fun(path, out)
end

# Returns the root dir of alpha
alphadir() = dirname(@__DIR__)
alphalibdir() = "$(alphadir())/alphalib"

ext: jl


text:
module FaultTolerantControl

# if you don't reexport `FlightSims`, many APIs, e.g., `State` would report an issue like:
# ERROR: Define the structure of state for your environment
# using Debugger  # tmp
using Reexport
@reexport using FlightSims
const FS = FlightSims
# `import` will help you to automatically extend the imported methods
import FlightSims: State, Params, Dynamics!, Dynamics
import FlightSims: Command
using LinearAlgebra
using Convex, Mosek, MosekTools
using Transducers, UnPack, ComponentArrays
import SplitApplyCombine
import MatrixEquations
using NumericalIntegration

# Fault
export AbstractFault, FaultSet
export AbstractActuatorFault, LoE
# FDI (fault detection and isoltion)
export AbstractFDI, LPFFDI, DelayFDI
# allocator
export PseudoInverseAllocator, ConstrainedAllocator, AdaptiveAllocator
# trajectory generation
export Bezier
# cost functional
export PositionAngularVelocityCostFunctional
export cost

include("utils.jl")
include("costs.jl")
include("faults.jl")
include("environments/environments.jl")
include("trajectory_generation.jl")

end


text:
using RLEVectors
using RCall

x = RLEVector([1,1,1,1,2,2])
y = RObject(x)
rcopy(RLEVector,y)
convert(RLEVector,y)
RLEVector(y)

@rput y
R"y = y + 2"
@rget y


text:
using InvertibleNetworks, Test, LinearAlgebra, Random

Random.seed!(11)

##############################################################################################################################
# 4D Tensor
X = randn(Float32, 28, 28, 2, 4)

# Squeeze and unsqueeze
@test isapprox(norm(X - unsqueeze(squeeze(X; pattern="column"); pattern="column")), 0f0; atol=1f-6)
@test isapprox(norm(X - unsqueeze(squeeze(X; pattern="patch"); pattern="patch")), 0f0; atol=1f-6)
@test isapprox(norm(X - unsqueeze(squeeze(X; pattern="checkerboard"); pattern="checkerboard")), 0f0; atol=1f-6)

#test norm preservation of orthogonal transforms
@test norm(X) ≈ norm(Haar_squeeze(X))

# Wavelet transform invertibility
Y = wavelet_squeeze(X)
X_ = wavelet_unsqueeze(Y)
@test isapprox(norm(X - X_)/norm(X), 0f0; atol=1f-5)
@test X ≈ invHaar_unsqueeze(Haar_squeeze(X))

# Wavelet transform adjoint test
X = randn(Float32, 28, 28, 2, 4)
Y = randn(Float32, 14, 14, 8, 4)
a = dot(Y, wavelet_squeeze(X))
b = dot(X, wavelet_unsqueeze(Y))
@test isapprox(a/b - 1f0, 0f0; atol=1f-5)
a = dot(Y, Haar_squeeze(X))
b = dot(X, invHaar_unsqueeze(Y))
@test isapprox(a/b - 1f0, 0f0; atol=1f-5)

# Split and cat
@test isapprox(norm(X - tensor_cat(tensor_split(X))), 0f0; atol=1f-5)

##############################################################################################################################
# 5D Tensor
X = randn(Float32, 16, 16, 16, 2, 4)

# Squeeze and unsqueeze
@test isapprox(norm(X - unsqueeze(squeeze(X; pattern="column"); pattern="column")), 0f0; atol=1f-6)
@test isapprox(norm(X - unsqueeze(squeeze(X; pattern="patch"); pattern="patch")), 0f0; atol=1f-6)

#test norm preservation of orthogonal transforms
@test norm(X) ≈ norm(Haar_squeeze(X))

# Wavelet transform invertibility
Y = wavelet_squeeze(X)
X_ = wavelet_unsqueeze(Y)
@test isapprox(norm(X - X_)/norm(X), 0f0; atol=1f-5)
@test X ≈ invHaar_unsqueeze(Haar_squeeze(X))

# Wavelet transform adjoint test
X = randn(Float32, 16, 16, 16, 2, 4)
Y = randn(Float32, 8, 8, 8, 16, 4)
a = dot(Y, wavelet_squeeze(X))
b = dot(X, wavelet_unsqueeze(Y))
@test isapprox(a/b - 1f0, 0f0; atol=1f-5)
a = dot(Y, Haar_squeeze(X))
b = dot(X, invHaar_unsqueeze(Y))
@test isapprox(a/b - 1f0, 0f0; atol=1f-5)

# Split and cat
@test isapprox(norm(X - tensor_cat(tensor_split(X))), 0f0; atol=1f-5)


text:
using ExportWebAssembly

include("../../lib/arrays/wasm-array.jl")
using .WASMVector

function arrsum(addr)
    y = asvec(Float32, addr)
    result = Float32(0)
    for x in y
	result += x
    end
    result
end

@code_warntype arrsum(Int32(1))

write_wasm("main.wasm", arrsum, Tuple{Int32}, linkwith = ("../../lib/memory/memory-utils.o", "../../lib/memory/emmalloc.o"))


text:
#############################################################
#
# Places & Geo Functions
#
#############################################################

function get_geo_id_place_id(place_id::AbstractString; options=Dict{AbstractString, AbstractString}())

    r = get_oauth("https://api.twitter.com/1.1/geo/id/$(place_id).json", options)

    return r.status == 200 ? to_PLACES(Requests.json(r)) : r

end

function get_geo_reverse_geocode(lat::AbstractString, long::AbstractString; options=Dict{AbstractString, AbstractString}())

    #Add required parameter(s) to options dict
    options["lat"] = lat
    options["long"] = long

    r = get_oauth("https://api.twitter.com/1.1/geo/reverse_geocode.json", options)

    #return to_PLACES(r["result"]["places"])
    return r.status == 200 ? to_PLACES(Requests.json(r)["result"]["places"]) : r

end

function get_geo_search(; options=Dict{AbstractString, AbstractString}())

    r = get_oauth("https://api.twitter.com/1.1/geo/search.json", options)

    #return to_PLACES(r["result"]["places"])
    return r.status == 200 ? to_PLACES(Requests.json(r)["result"]["places"]) : r

end

function get_geo_similar_places(lat::AbstractString, long::AbstractString, name::AbstractString; options=Dict{AbstractString, AbstractString}())

    #Add required parameter(s) to options dict
    options["lat"] = lat
    options["long"] = long
    options["name"] = name

    r = get_oauth("https://api.twitter.com/1.1/geo/similar_places.json", options)

    #return to_PLACES(r["result"]["places"])
    return r.status == 200 ? to_PLACES(Requests.json(r)["result"]["places"]) : r

end


text:
using ConstrainedDynamics

path = "examples/examples_files/atlas_simple.urdf"
mech, shapes = Mechanism(path, floating=false, g = -.5)


text:
# Appearance of out panel cut graphs in dot.

using Printf

function NahaGraphs.graph_attributes(::PanelGraph)
    Dict([
        (:bgcolor, "black"),
        (:color, "white")
    ])
end

function NahaGraphs.node_attributes(::PanelGraph)
    Dict([
        (:color, "white"),
        (:fontcolor, "white")
    ])
end

function NahaGraphs.edge_attributes(::PanelGraph)
    Dict([
        (:color, "white"),
    ])
end

function prettydistance(x)
    s = @sprintf("%.3f", svgdistance(x))
    # trim trailing decimal zeros:
    if '.' in s
        s = rstrip(s, '0')
    end
    return s
end

function NahaGraphs.dotID(panel::AbstractPanel)
    t = split(string(typeof(panel)), ".")[end]
    "$(t)_$(string(panel.uid))"
end

function shorttype(panel::AbstractPanel)
    split(string(typeof(panel)), ".")[end]
end

function dotlabel(panel::AbstractPanel)
    "$(shorttype(panel))\n$(panel.uid)"
end

function dotlabel(panel::AvailablePanel)
    join([
        "$(shorttype(panel))",
        panel.label,
        "length: $(prettydistance(panel.length))",
        "width: $(prettydistance(panel.width))",
        @sprintf("cost: %.2f", panel.cost)
    ], "\n")
end

function dotlabel(panel::FinishedPanel)
    join([
        "$(shorttype(panel))",
        panel.wanted.label,
        "length: $(prettydistance(panel.length))",
        "width: $(prettydistance(panel.width))",
        "x: $(prettydistance(panel.x))",
        "y: $(prettydistance(panel.y))",
        @sprintf("cost: %.2f", panel.cost)
    ], "\n")
end

function dotlabel(panel::Panel)
    join([
        "$(shorttype(panel))",
        "length: $(prettydistance(panel.length))",
        "width: $(prettydistance(panel.width))",
        "at: $(prettydistance(panel.cut_at))",
        pretty(panel.cut_axis),
        "x: $(prettydistance(panel.x))",
        "y: $(prettydistance(panel.y))",
        @sprintf("cost: %.2f", panel.cost)
    ], "\n")
end

dotshape(panel::AbstractPanel) = "box"

function NahaGraphs.dotnode(io::IO, graph::PanelGraph, panel::AbstractPanel)
    attrs = dot_attributes_string(
        ;
        label=dotlabel(panel),
        shape=dotshape(panel))
    write(io, """  "$(dotID(panel))" [$attrs]\n""")
end

function NahaGraphs.dotedge(io::IO, graph::PanelGraph, from, to)
    diarc(io, from, to)
end


text:
@testset "Machine learning" begin
    @testset "Machine learning: K-Means clustering" begin
        # poinst is a vector of 2D points.
        points = [[0, 0], [1, 1], [5.0, 5.0], [10.0, 10.0]]
        @test KMeans.cluster(1, -1, points) == [[4.0, 4.0]] # 1 cluster, undefined number of iterations
        @test KMeans.cluster(1, 10, points) == [[4.0, 4.0]] # 1 cluster, 10 iterations
        # If we are looking for 2 clusters, it is obvious that the first one will be between the first two
        # points ([0, 0] and [1, 1]), and the second one will be between the last two points ([5, 5] and [10, 10])
        @test KMeans.cluster(2, -1, points) == [[0.5, 0.5], [7.5, 7.5]]
        # When the number of clusters is equal to the number of points,
        # each cluster will be assigned to a single point
        @test KMeans.cluster(4, -1, points) == points
        # When there are not enough points to create k clusters,
        # each cluster will have its coordinates set to 0
        KMeans.cluster(5, -1, points) == [[0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0], [0.0, 0.0]]
    end
end

max_issues_repo_name: AugustoCL/Julia

max_forks_repo_name: AugustoCL/Julia


text:
function as_neuro_data(x)

    T = eltype(T)
    dimnames(x)
    axes(x)
    metadata(x)
end

StructAxis


text:
# This file is a part of Julia. License is MIT: https://julialang.org/license

# Expr head => argument count bounds
const VALID_EXPR_HEADS = ObjectIdDict(
    :call => 1:typemax(Int),
    :invoke => 2:typemax(Int),
    :static_parameter => 1:1,
    :line => 1:3,
    :gotoifnot => 2:2,
    :(&) => 1:1,
    :(=) => 2:2,
    :method => 1:4,
    :const => 1:1,
    :null => 0:0, # TODO from @vtjnash: remove this + any :null handling code in Base
    :new => 1:typemax(Int),
    :return => 1:1,
    :the_exception => 0:0,
    :enter => 1:1,
    :leave => 1:1,
    :inbounds => 1:1,
    :boundscheck => 0:0,
    :copyast => 1:1,
    :meta => 0:typemax(Int),
    :global => 1:1,
    :foreigncall => 3:typemax(Int),
    :isdefined => 1:1,
    :simdloop => 0:0
)

# @enum isn't defined yet, otherwise I'd use it for this
const INVALID_EXPR_HEAD = "invalid expression head"
const INVALID_EXPR_NARGS = "invalid number of expression args"
const INVALID_LVALUE = "invalid LHS value"
const INVALID_RVALUE = "invalid RHS value"
const INVALID_CALL_ARG = "invalid :call argument"
const EMPTY_SLOTNAMES = "slotnames field is empty"
const SLOTFLAGS_MISMATCH = "length(slotnames) != length(slotflags)"
const SLOTTYPES_MISMATCH = "length(slotnames) != length(slottypes)"
const SLOTTYPES_MISMATCH_UNINFERRED = "uninferred CodeInfo slottypes field is not `nothing`"
const SSAVALUETYPES_MISMATCH = "not all SSAValues in AST have a type in ssavaluetypes"
const SSAVALUETYPES_MISMATCH_UNINFERRED = "uninferred CodeInfo ssavaluetypes field does not equal the number of present SSAValues"
const NON_TOP_LEVEL_METHOD = "encountered `Expr` head `:method` in non-top-level code (i.e. `nargs` > 0)"
const SIGNATURE_NARGS_MISMATCH = "method signature does not match number of method arguments"
const SLOTNAMES_NARGS_MISMATCH = "CodeInfo for method contains fewer slotnames than the number of method arguments"

struct InvalidCodeError <: Exception
    kind::String
    meta::Any
end

InvalidCodeError(kind) = InvalidCodeError(kind, nothing)

"""
    validate_code!(errors::Vector{>:InvalidCodeError}, c::CodeInfo)

Validate `c`, logging any violation by pushing an `InvalidCodeError` into `errors`.
"""
function validate_code!(errors::Vector{>:InvalidCodeError}, c::CodeInfo, is_top_level::Bool = false)
    ssavals = IntSet()
    lhs_slotnums = IntSet()
    walkast(c.code) do x
        if isa(x, Expr)
            !is_top_level && x.head == :method && push!(errors, InvalidCodeError(NON_TOP_LEVEL_METHOD))
            narg_bounds = get(VALID_EXPR_HEADS, x.head, -1:-1)
            nargs = length(x.args)
            if narg_bounds == -1:-1
                push!(errors, InvalidCodeError(INVALID_EXPR_HEAD, (x.head, x)))
            elseif !in(nargs, narg_bounds)
                push!(errors, InvalidCodeError(INVALID_EXPR_NARGS, (x.head, nargs, x)))
            elseif x.head == :(=)
                lhs, rhs = x.args
                if !is_valid_lvalue(lhs)
                    push!(errors, InvalidCodeError(INVALID_LVALUE, lhs))
                elseif isa(lhs, SlotNumber) && !in(lhs.id, lhs_slotnums)
                    n = lhs.id
                    push!(lhs_slotnums, n)
                end
                if !is_valid_rvalue(rhs)
                    push!(errors, InvalidCodeError(INVALID_RVALUE, rhs))
                end
            elseif x.head == :call || x.head == :invoke
                for arg in x.args
                    if !is_valid_rvalue(arg)
                        push!(errors, InvalidCodeError(INVALID_CALL_ARG, arg))
                    end
                end
            end
        elseif isa(x, SSAValue)
            id = x.id + 1 # ensures that id > 0 for use with IntSet
            !in(id, ssavals) && push!(ssavals, id)
        end
    end
    nslotnames = length(c.slotnames)
    nslotflags = length(c.slotflags)
    nssavals = length(ssavals)
    nslotnames == 0 && push!(errors, InvalidCodeError(EMPTY_SLOTNAMES))
    nslotnames != nslotflags && push!(errors, InvalidCodeError(SLOTFLAGS_MISMATCH, (nslotnames, nslotflags)))
    if c.inferred
        nslottypes = length(c.slottypes)
        nssavaluetypes = length(c.ssavaluetypes)
        nslottypes != nslotnames && push!(errors, InvalidCodeError(SLOTTYPES_MISMATCH, (nslotnames, nslottypes)))
        nssavaluetypes < nssavals && push!(errors, InvalidCodeError(SSAVALUETYPES_MISMATCH, (nssavals, nssavaluetypes)))
    else
        c.slottypes !== nothing && push!(errors, InvalidCodeError(SLOTTYPES_MISMATCH_UNINFERRED, c.slottypes))
        c.ssavaluetypes != nssavals && push!(errors, InvalidCodeError(SSAVALUETYPES_MISMATCH_UNINFERRED, (nssavals, c.ssavaluetypes)))
    end
    return errors
end

"""
    validate_code!(errors::Vector{>:InvalidCodeError}, mi::MethodInstance,
                   c::Union{Void,CodeInfo} = Core.Inference.retrieve_code_info(mi))

Validate `mi`, logging any violation by pushing an `InvalidCodeError` into `errors`.

If `isa(c, CodeInfo)`, also call `validate_code!(errors, c)`. It is assumed that `c` is
the `CodeInfo` instance associated with `mi`.
"""
function validate_code!(errors::Vector{>:InvalidCodeError}, mi::Core.MethodInstance,
                        c::Union{Void,CodeInfo} = Core.Inference.retrieve_code_info(mi))
    m = mi.def::Method
    n_sig_params = length(Core.Inference.unwrap_unionall(m.sig).parameters)
    if (m.isva ? (n_sig_params < (m.nargs - 1)) : (n_sig_params != m.nargs))
        push!(errors, InvalidCodeError(SIGNATURE_NARGS_MISMATCH, (m.isva, n_sig_params, m.nargs)))
    end
    if isa(c, CodeInfo)
        m.nargs > length(c.slotnames) && push!(errors, InvalidCodeError(SLOTNAMES_NARGS_MISMATCH))
        validate_code!(errors, c, m.nargs == 0)
    end
    return errors
end

validate_code(args...) = validate_code!(Vector{InvalidCodeError}(), args...)

function walkast(f, stmts::Array)
    for stmt in stmts
        f(stmt)
        isa(stmt, Expr) && walkast(f, stmt.args)
    end
end

is_valid_lvalue(x) = isa(x, SlotNumber) || isa(x, SSAValue) || isa(x, GlobalRef)

function is_valid_rvalue(x)
    isa(x, Expr) && return !in(x.head, (:gotoifnot, :line, :const, :meta))
    return !isa(x, GotoNode) && !isa(x, LabelNode) && !isa(x, LineNumberNode)
end

is_flag_set(byte::UInt8, flag::UInt8) = (byte & flag) == flag

max_stars_repo_name: visr/julia

max_issues_repo_name: visr/julia

max_forks_repo_name: visr/julia


text:
# This file is a part of BAT.jl, licensed under the MIT License (MIT).

using BAT
using Test

using LinearAlgebra, Distributions, StatsBase, ValueShapes

@testset "mode_estimators" begin
    prior = NamedTupleDist(
        x = Normal(2.0, 1.0),
        c = [4, 5],
        a = MvNormal([1.5, 0.5, 2.5], Matrix{Float32}(I, 3, 3))
    )

    posterior = PosteriorDensity(LogDVal(0), prior)

    true_mode_flat = [2.0, 1.5, 0.5, 2.5]
    true_mode = stripscalar(varshape(prior)(true_mode_flat))

    samples = @inferred(bat_sample(prior, IIDSampling(nsamples = 10^5))).result

    function test_findmode(posterior, algorithm, rtol)
        res = @inferred(bat_findmode(posterior, algorithm))
        @test keys(stripscalar(res.result)) == keys(true_mode)
        @test isapprox(unshaped(res.result), true_mode_flat, rtol = rtol)
    end

    function test_findmode_noinferred(posterior, algorithm, rtol)
        res = (bat_findmode(posterior, algorithm))
        @test keys(stripscalar(res.result)) == keys(true_mode)
        @test isapprox(unshaped(res.result), true_mode_flat, rtol = rtol)
    end

    @testset "ModeAsDefined" begin
        @test @inferred(bat_findmode(prior, ModeAsDefined())).result[] == true_mode
        @test @inferred(bat_findmode(BAT.DistributionDensity(prior), ModeAsDefined())).result[] == true_mode
        let post_modes = @inferred(bat_findmode(posterior)).result[]
            for k in keys(post_modes)
                @test isapprox(post_modes[k], true_mode[k], atol=0.001)
            end
        end
    end

    @testset "MaxDensitySampleSearch" begin
        @test @inferred(bat_findmode(samples, MaxDensitySampleSearch())).result isa ShapedAsNT
        m = bat_findmode(samples, MaxDensitySampleSearch())
        @test samples[m.mode_idx].v == stripscalar(m.result)
        @test isapprox(unshaped(m.result), true_mode_flat, rtol = 0.05)
    end

    @testset "MaxDensityNelderMead" begin
        test_findmode(posterior,  MaxDensityNelderMead(trafo = NoDensityTransform()), 0.01)
    end

    @testset "MaxDensityLBFGS" begin
        # Result Optim.maximize with LBFGS is not type-stable:
        test_findmode_noinferred(posterior, MaxDensityLBFGS(trafo = NoDensityTransform()), 0.01)
    end
end


text:
# exact k-medoids modeled similar as in Kotzur et al, 2017

"Holds results of kmedoids run"
mutable struct kmedoidsResult
    medoids::Array{Float64}
    assignments::Array{Int}
    totalcost::Float64
end

"""
    kmedoids_exact(
     data::Array{Float64},
     nclust::Int,
     _dist::SemiMetric = SqEuclidean(),
     env::Any;
     )
   results = kmedoids_exact()
   data { HOURS,DAYS }
Performs the exact kmedoids algorithm as in Kotzur et al, 2017
optimizer=Gurobi.Optimizer
"""
function kmedoids_exact(
   data::Array{Float64},
   nclust::Int,
   optimizer::DataType;
   _dist::SemiMetric = SqEuclidean(),
   )
   N_i = size(data,2)

  # calculate distance matrix
  d_mat=pairwise(_dist,data, dims=2)

  # create jump model
  m = JuMP.Model(with_optimizer(optimizer)) # GurobiSolver(env,OutputFlag=0)
  @variable(m,z[1:N_i,1:N_i],Bin)
  @variable(m,y[1:N_i],Bin)
  @objective(m,Min,sum(d_mat[i,j]*z[i,j] for i=1:N_i, j=1:N_i))
  for j=1:N_i
    @constraint(m,sum(z[i,j] for i=1:N_i)==1)
  end
  for i=1:N_i
    for j=1:N_i
    @constraint(m,z[i,j]<=y[i])
    end
  end
  @constraint(m,sum(y[i] for i=1:N_i) == nclust)

  # solve jump model
  optimize!(m)
  status=Symbol(termination_status(m))

  println("status: ",status)
  y_opt=round.(Integer,JuMP.value.(y))
  z_opt=round.(Integer,JuMP.value.(z))
   #println("y ",y_opt, " z ",z_opt)
  # determine centers and cluster mappings
  id = zeros(Int,N_i)
  ii=0
  for i=1:N_i
    if y_opt[i]==1
      ii +=1
      id[i]=ii
    end
  end
  nz = findall(!iszero,z_opt)
  centerids=Int[]
  for i=1:length(nz) # just take the first dimension of each of the elements of the array of cartesianCoordinates
    push!(centerids, nz[i][1])
  end
  clustids = zeros(Int,N_i)
  for i=1:N_i
    clustids[i] = id[centerids[i]]
  end
  centers = data[:,findall(id.!=0.0)]
  tot_dist = objective_value(m)
   # output centers
  results = kmedoidsResult(centers, clustids, tot_dist)

  return results

end #kmedoids_exact


text:
using QuadraticAssignmentProblem

using Gurobi
qap_set_optimizer!(Gurobi.Optimizer)

N = 8
alg = qap_lprounding

@show N
@show alg

A, B, optperm = generate_qap(N)

time = @elapsed P, perm = alg(A, B, :max)

@show time
@show perm
@show optperm

@show qap_objective(A, B, perm)
@show qap_objective(A, B, optperm)


text:
using Sim6502
using Test

c = CPU()
m = Memory()

@p ldx!(c, 0x80)
@p stx!(c, m, Π(0x00))
@p lda!(c, 0x40)
@p bit!(c, m, Π(0x00))

# @p lda!(c, 0x02)
# @p sta!(c, m, Π(0x0a00))
#
# @p lda!(c, 0x02)
# @p sta!(c, m, Π(0x0a01))
#
# @p jmp!(c, m, Π(0x0a00))

# @p jsr!(c, m, 0x0610)
# @p rts!(c, m)

@testset "instructions" begin

c = CPU()
m = Memory()

@testset "loading" begin

    @testset "lda" begin

    end

end

end


text:
# This file was generated, do not modify it. # hide
XGBR = @load XGBoostRegressor

xgb_mdl = XGBR(num_round=10, max_depth=10)
xgb = machine(xgb_mdl, X, y)
fit!(xgb, rows=train)

ypred = MLJ.predict(xgb, rows=test)
round(rms(ypred, y[test]), sigdigits=3)

max_issues_repo_name: alan-turing-institute/MLJTutorials

max_forks_repo_name: alan-turing-institute/MLJTutorials


text:
using RobotDynamics
using Test
using StaticArrays

struct MyModel <: RD.ContinuousDynamics end
model = MyModel()
@test_throws RD.NotImplementedError RD.state_dim(model)
@test_throws RD.NotImplementedError RD.control_dim(model)

model = Cartpole()
x,u = zeros(model)
@test sum(x) == 0
@test sum(u) == 0
x,u = rand(model)
@test sum(x) != 0
@test sum(u) != 0
xdot = RD.dynamics(model, x, u)
@test sum(x) != 0
xdot = RD.dynamics(model, x, u, 0.0)
@test sum(x) != 0
y = zeros(length(x))
RD.dynamics!(model, y, x, u)
@test y ≈ xdot
RD.dynamics!(model, y, x, u, 0.0)
@test y ≈ xdot

x,u = zeros(Float32,model)
@test x isa SVector{4,Float32}
@test u isa SVector{1,Float32}

x,u = rand(Float32,model)
@test x isa SVector{4,Float32}
@test u isa SVector{1,Float32}

x,u = fill(model, 10.0)
@test x ≈ @SVector fill(10,4)
@test u ≈ @SVector fill(10,1)

n,m = size(model)
t,dt = 0, 0.1
F = zeros(n,n+m)
y = zeros(n)
z = RD.KnotPoint(x,u,t,dt)
RD.jacobian!(RD.StaticReturn(), RD.ForwardAD(), model, F, y, z)
@test sum(F) != 0

D = RobotDynamics.DynamicsJacobian(n,m)
RD.jacobian!(RD.StaticReturn(), RD.ForwardAD(), model, D, y, z)
@test D.A == F[:,1:n]
@test D.B ≈ F[:,n .+ (1:m)]
RD.jacobian!(RD.StaticReturn(), RD.FiniteDifference(), model, D, y, z)
@test D.A ≈ F[:,1:n] atol=1e-6
@test D.B ≈ F[:,n .+ (1:m)] atol=1e-6

RD.jacobian!(RD.InPlace(), RD.ForwardAD(), model, D, y, z)
@test D.A == F[:,1:n]
@test D.B ≈ F[:,n .+ (1:m)]
RD.jacobian!(RD.InPlace(), RD.FiniteDifference(), model, D, y, z)
@test D.A ≈ F[:,1:n] atol=1e-6
@test D.B ≈ F[:,n .+ (1:m)] atol=1e-6

# Discretize
dmodel = RD.DiscretizedDynamics{RD.RK4}(model)
@test RD.discrete_dynamics(dmodel, x, u, t, dt) ≈ RD.discrete_dynamics(dmodel, z)

z_ = RD.KnotPoint(zero(x),zero(u),t,dt)
RD.propagate_dynamics!(RD.StaticReturn(), dmodel, z_, z)
@test RD.state(z_) ≈ RD.discrete_dynamics(dmodel, z)

F = zeros(n,n+m)
RD.jacobian!(RD.StaticReturn(), RD.ForwardAD(), dmodel, F, y, z)

# Error state
x0 = rand(model)[1]
@test RD.state_diff(model, x, x0) ≈ x - x0
@test RD.errstate_dim(model) == RD.state_dim(model)
G = zeros(n,n)
RD.state_diff_jacobian!(model, G, z)
@test G ≈ I(n)
G .= 0
RobotDynamics.state_diff_jacobian!(model, G, x)
@test G ≈ I(n)


text:
using FixedEffects, CategoricalArrays, Random, CuArrays, BenchmarkTools, Statistics

Random.seed!(1234)
N = 10000000
K = 100
id1 = categorical(Int.(rand(1:(N/K), N)))
id2 = categorical(Int.(rand(1:K, N)))
id3 = categorical(Int.(rand(1:(N/K), N)))

x = rand(N)
X = rand(N, 10)

(r_g, it_g, conv_g)=solve_residuals!(copy(x), deepcopy([FixedEffect(id1), FixedEffect(id2)]), method = :lsmr_gpu)
(r_c, it_c, conv_c)=solve_residuals!(copy(x), deepcopy([FixedEffect(id1), FixedEffect(id2)]), method = :lsmr);

@show r_c ≈ r_g
@show it_c, it_g
@show conv_c, conv_g

println("CPU Float64, size(x)=$(size(x)), 2 fixed effects")
@btime (r_c, it_c, conv_c)=solve_residuals!($x, [FixedEffect(id1), FixedEffect(id2)], method = :lsmr)
println("CPU Float32, size(x)=$(size(x)), 2 fixed effects")
@btime (r_c, it_c, conv_c)=solve_residuals!(Float32.(x), [FixedEffect(id1), FixedEffect(id2)], method = :lsmr)
println("GPU Float64, size(x)=$(size(x)), 2 fixed effects")
@btime (r_g, it_g, conv_g)=solve_residuals!($x, [FixedEffect(id1), FixedEffect(id2)], method = :lsmr_gpu)
println("GPU Float32, size(x)=$(size(x)), 2 fixed effects")
@btime (r_g, it_g, conv_g)=solve_residuals!(Float32.(x), [FixedEffect(id1), FixedEffect(id2)], method = :lsmr_gpu)

# Note that most of the GPU time is spend transferring memory
using Profile
Profile.clear()
@profile solve_residuals!(x, [FixedEffect(id1), FixedEffect(id2)], method = :lsmr_gpu);
Profile.print(noisefloor=1.0)

# More complicated problem
N = 8000000 # number of observations
M = 4000000 # number of workers
O = 500000 # number of firms
pid = rand(1:M, N)
fid = zeros(Int64, N)
for i in 1:N
    # low pid matches with low fid
    fid[i] = rand(max(1, div(pid[i], 8)-10):min(O, div(pid[i], 8)+10))
end
x = (pid .* fid .- mean(pid .* fid)) / std(pid .* fid)
pid = categorical(pid)
fid = categorical(fid)
K = 1
e = randn(length(x), K)
X = repeat(x, outer=[1,K]) + e

println("CPU Float64")
@time (rc6,i,c)=solve_residuals!(copy(X), [FixedEffect(pid), FixedEffect(fid)],
                                tol=sqrt(eps(Float32)))
@show i
println("CPU Float32")
@time (rc3,i,c)=solve_residuals!(Float32.(X), [FixedEffect(pid), FixedEffect(fid)],
                                tol=sqrt(eps(Float32)))
@show i

println("GPU Float64")
@time (rg6,i,c)=solve_residuals!(copy(X), [FixedEffect(pid), FixedEffect(fid)],
                                 method = :lsmr_gpu,
                                 tol=sqrt(eps(Float32)));
@show i

println("GPU Float32")
@time (rg3,i,c)=solve_residuals!(Float32.(X), [FixedEffect(pid), FixedEffect(fid)],
                                 method = :lsmr_gpu,
                                 tol=sqrt(eps(Float32)));
@show i
@show mean(rg3)
@show mean(rg6)
@show std(rg6-rg3)


text:
include("xsd_parse.jl")
include("xsd_transform.jl")
include("xsd_build.jl")

function xsd_rules(xsduri::AbstractString, startelement::AbstractString, rulenameprefix="")
	ast = parse_xsd(xsduri)
	transform_xsd_ast(ast, startelement)
	transform_ast(ast)
	build_xsd_rules(ast, rulenameprefix)
end

function xsd_generator(io::IO, genname::Symbol, xsduri::AbstractString, startelement::AbstractString)
	rules = xsd_rules(xsduri, startelement)
	description = "XML with root element " * escape_string(startelement)
	output_generator(io, genname, description, rules)
end

xsd_generator(genname::Symbol, xsduri::AbstractString, startelement::AbstractString) = include_generator(genname, xsd_generator, xsduri, startelement)


text:
# ] activate "I:\My Documents\00 AFIT\Research\Julia Projects\StrategyGames"
using Pkg; Pkg.activate(pwd())

############################
#
# Scratch work for results collection
#
###########################

## Robust collection

# # build nominal fixed attacker strategy (NE)
# pdbr = vcat(fill(0.95, gs.ni_stage[3]), fill(0.0, gs.ni_stage[5]), fill(0.85, gs.ni_stage[6]))
# _, _, _, σNE = cfr(25_000, g, gs)

# # check that DBR matches LP BR
# T = 3000
# u_dbr, _, _, _ = cfr_dbr(T, g, gs, ones(length(pconf)), σfix)
# _, u_br, _ = lp_best_response(gos, real_strat(σfix, gs, gos)[2], fixedplayer = 2)
# isapprox(mean(u_dbr), u_br, atol = 0.05)

## DOE design with some set factors and some constant factors

@everywhere function build_design(fn::String)
    # screening design
    # factor_names = ["radius",
    #                 "ncity", "ndp", "nap",
    #                 "ndpdc_p", "ndpac_p", "ndc_p", "nac_p",
    #                 "pp", "psc", "pdc", "pac",
    #                 "alpha", "beta", "gamma"]
    # col_types = [Float64,
    #                 Int64, Int64, Int64,
    #                 Float64, Float64, Float64, Float64,
    #                 Float64, Float64, Float64, Float64,
    #                 Float64, Float64, Float64]
    # factor_limits = [(0.2, 0.4),
    #                 (9, 15), (4, 8), (2, 6),
    #                 (0.2, 1.0), (0.2, 1.0), (0.2, 0.8), (0.2, 0.8),
    #                 (0.6, 0.95), (0.6, 0.95), (0.6, 0.95), (0.6, 0.95),
    #                 (1.0, 8.0), (-8.0, 8.0), (0.0, 8.0)]
    factor_names = ["size",
                    "pp", "psc", "pdc",
                    "alpha", "beta", "gamma"]
    col_types = [Int64,
                    Float64, Float64, Float64,
                    Float64, Float64, Float64]
    factor_limits = [(9, 15),
                    (0.55, 0.95), (0.55, 0.95), (0.55, 0.95),
                    (0.5, 4.0), (-4.0, 4.0), (0.0, 4.0)]
    const_names = ["radius", "pac",
                    "ncity", "ndp", "nap",
                    "ndpdc", "ndpac", "ndc", "nac"]
    const_types = [Float64, Float64,
                    Int64, Int64, Int64,
                    Int64, Int64, Int64, Int64]
    const_limits = [(0.3, 0.3), (0.0, 0.0),
                    (9, 15), (4,8), (2,6),
                    (4,8), (4,8), (2,6), (2,6)]
    design = CSV.read(joinpath(dir, fn), types = col_types)
    rename!(design, old => new for (old, new) = zip(names(design), Symbol.(factor_names)))
    l, w = size(design)
    for j in 1:w, i in 1:l
        if design[i, j] == -1
            design[i, j] = factor_limits[j][1]
        elseif design[i, j] == 1
            design[i, j] = factor_limits[j][2]
        elseif design[i, j] == 0
            design[i, j] = mean(factor_limits[j])
        else
            @warn "Unexpected factor design value at $i, $j."
        end
    end
    for j in 1:length(const_names)
        design[Symbol(const_names[j])] = Vector{const_types[j]}(undef, l)
    end
    for j in 1:length(const_names), i in 1:l
        if design.size[i] == factor_limits[1][1]
            design[i, j + w] = const_limits[j][1]
        elseif design.size[i] == factor_limits[1][2]
            design[i, j + w] = const_limits[j][2]
        elseif design.size[i] == mean(factor_limits[1])
            design[i, j + w] = mean(const_limits[j])
        else
            @warn "Unexpected const design value at $i, $j."
            return design
        end
    end
    return design
end

##

# SharedArray version of DOE results collection
# runs each run twice when I only want to run each run once...not sure what's
# going on

nruns = size(design, 1)
u_doe = SharedArray{Float64}(nruns)
converge_doe = SharedArray{Bool}(nruns)
iter_doe = SharedArray{Int64}(nruns)
t_doe = SharedArray{Float64}(nruns)

@distributed for i in 1:3
    println("Start $i")
    ui, convergei, iteri, ti = calc_run(design[i,:], gvec[i], gsvec[i], i)
    prtinln("Complete $i")
    @show ui, convergei, iteri, ti
    u_doe[i] = ui
    converge_doe[i] = convergei
    iter_doe[i] = iteri
    t_doe[i] = ti
end

##

gvec = [AirDefenseGame(i, 6, 3, 4, 4, 2, 2) for i in 7:15]
seqsizes = Vector{Int64}(undef, 9)
for (i, gi) in enumerate(gvec)
    A, An, na_stage = build_action(gi)
    ni, ni1, ni2, ni_stage = build_info(gi)
    ns1, ns2, ns1_stage, ns2_stage = build_nseq(gi, na_stage, ni_stage)
    seqsizes[i] = ns1 * ns2
end

## CFR means are not close to LP NE means.
# investigate n = 7
Random.seed!(579843)
ncity = 10
g = rexps["results"][ncity - 6][1]
gs = GameSet(g)
(u, r, s, σ, σs, converged), runtime = @timed dcfr_full(g, gs, iterlimit = 5_000, tol = 5e-5, α = 1.5, β = 0.0, γ = 2.0, discounted = false)
mean(u)
status, u_br, r_br = lp_best_response(gos, real_strat(σ, gs, gos)[1], fixedplayer = 1)

Random.seed!(579843)
ncity = 10
g = rexps["results"][ncity - 6][1]
gs = GameSet(g)
u, r, s, σ = cfr(5000, g, gs)
mean(u)

Random.seed!(579843)
ncity = 10
g = AirDefenseGame(ncity, 6, 3, 4, 4, 2, 2)
gs = GameSet(g)
gos = GameOptSet(g, gs, rexps["results"][ncity - 6][4])
status_ne, u_ne, r_ne, t_ne = lp_nash(gos)
u_ne

ind1 = 43
ind2 = 62491
h = [1, 6, 5, 1, 6, 120] # h associated with seq1, seq2
indu = findfirst(x -> x == h, z)
@test U[indu] == reward[ind1, ind2]

g = AirDefenseGame()
gs = GameSet(g)
A, An, na_stage = build_action(g)
ni, ni1, ni2, ni_stage = build_info(g)
ns1, ns2, ns1_stage, ns2_stage = build_seq(g, na_stage, ni_stage)
Σ1, Σ2, seq1defended_iads, seq2attacked_iads, seq2defended_iads, seq2attacked_cities = build_Σset(g, A, ns1, ns2)
Iset, I1set, I2set, seqI1, seqI2, nextseqI1, nextseqI2 = build_Iset(g, A, na_stage, ns1_stage, ns2_stage, ni1, ni2, ns1, ns2)
g.iads
i = 289
I1set[i]
Σ1[seqI1[i]]
nextseqI1[i]
i = 16
I2set[i]
Σ2[seqI2[i]]
nextseqI2[i]
ub = 100
ftab(ub) = hcat([I2set[i] for i = (ub - 25):ub], [Σ2[seqI2[i]] for i = (ub - 25):ub])

g = AirDefenseGame()
gs = GameSet(g)
A, An, na_stage = build_action(g)
ni, ni1, ni2, ni_stage = build_info(g)
ns1, ns2, ns1_stage, ns2_stage = build_seq(g, na_stage, ni_stage)
Σ1, Σ2, seqhist1, seqhist2 = build_Σset(g, A, ns1, ns2)
reward = build_utility_lp(g, gs, ns1, ns2, seq1defended_iads, seq2attacked_iads, seq2defended_iads, seq2attacked_cities)

using JuMP, Clp, SparseArrays
m = Model(Clp.Optimizer)
X = sparse([1,2,3],[1,2,3], [0,2,0])
t = [1, 10, 100]
t' * X
@variable(m, r[1:3] >= 0)
@objective(m, Min, sum(r' * X))

using CSV, DataFrames
dir = pwd()
# fn = joinpath(dir, "data\\utility_fixed_default_100000.csv")
# CSV.write(fn, DataFrame(utility = u))

using Pkg; Pkg.activate(pwd())
using FileIO, JLD2
dir = pwd()
fn = joinpath(dir, "data\\vars_fixed_default_100000.jld2")
# # @ save fn u r s σ
# # @ load fn u r s σ

function rerr_approx(u)
    lb = round(Int, 0.9 * length(u))
    u_approx = mean(u[lb:end])
    um = cumsum(u) ./ collect(1:T)
    u_rerr_approx = abs.(um .- u_approx) ./ abs.(u_approx)
    u_rerr_approx
end

function rerr_approx(u)
    lb = round(Int, 0.9 * length(u))
    u_approx = mean(u[lb:end])
    um = cumsum(u) ./ collect(1:T)
    u_rerr_approx = abs.(um .- u_approx) ./ abs.(u_approx)
    return u_rerr_approx
end

############################
#
# Scratch work for comparison between history-form utility and sequence-form utility
#
###########################

s1_ind = 43
s2_ind = 62491
reward[s1_ind, s2_ind]
Σ[1][s1_ind]
Σ[2][s2_ind]
c1 = findfirst(x -> x == [1,2,3,4], A[1])
c2 = findfirst(x -> x == [1,2,5,6], A[2])
ac = findfirst(x -> x == [2,4], A[3])
c4 = 1
dc = findfirst(x -> x == [3,4], A[5])
ap = findfirst(x -> x == [8,9,10], A[6])
h = [c1, c2, ac, 1, dc, ap]
uind = findfirst(x -> x == h, z)
U[uind] == reward[s1_ind, s2_ind]

get_attcity(h, g, gs) = gs.A[6][h[6]]
get_defiads(h, g, gs) = getindex(g.iads, getindex(gs.A[1][h[1]], gs.A[5][h[5]]))
get_attiads(h, g, gs) = getindex(g.iads, getindex(gs.A[2][h[2]], gs.A[3][h[3]]))

# check that sequnce-form actions match history-form actions
seqactions[3][s2_ind, :] == get_attcity(h, g, gs)# attacked cities
seqactions[1][s1_ind, :] == get_defiads(h, g, gs)# defended iads
seqactions[2][s2_ind, :] == get_attiads(h, g, gs) # attacked iads
seqactions[3][s2_ind, :] # attacked cities
seqactions[1][s1_ind, :] # defended iads
seqactions[2][s2_ind, :]  # attacked iads
attcity = get_attcity(h, g, gs)
defiads = get_defiads(h, g, gs)
attiads = get_attiads(h, g, gs)
utility_defender(g, coverage(g), attcity, defiads, attiads)

function ft(seq1defended_iads, seq2attacked_iads, seq2attacked_cities)
    return seq1defended_iads, seq2attacked_iads, seq2attacked_cities
end

seq1defended_iads, seq2attacked_iads, seq2attacked_cities = ft(seqactions...)
utility_defender(g, coverage(g), seq2attacked_cities[s2_ind, :], seq1defended_iads[s1_ind, :], seq2attacked_iads[s2_ind, :])
utility_defender(g, coverage(g), seq2attacked_cities[s2_ind], seq1defended_iads[s1_ind], seq2attacked_iads[s2_ind])

reward, reward_timing, bytes, gct, memallocs = @timed reward_seq(g, A, seqn..., seqactions...)
using FileIO, JLD2
dir = pwd()
# fn = joinpath(dir, "data\\temp.jld2")
# @save fn g reward reward_timing

# Lookup is much slower than inplace calculation
# function leafutility_lookup(h::Array{Int64}, player::Int64, πi::Float64, πo::Float64, gs::GameSet)
#     U, z = gs.U, gs.z
#     ind = findfirst(x -> x == h, z)
#     u = player == 1 ? U[ind] * πo : -1.0 * U[ind] * πo
#     return u
# end

# Reduce code repitition by doing the same logic but with utility_defender
# function leafutility_rawcalc(h::Array{Int64}, player::Int64, πi::Float64, πo::Float64, g::AirDefenseGame, gs::GameSet)
#     c1, c2, ac, c4, dc, ap = h
#     attacked_cities = @view gs.A[6][h[6]][:]
#     defended_iads = getindex(g.iads, getindex(gs.A[1][h[1]], gs.A[5][h[5]]))
#     attacked_iads = getindex(g.iads, getindex(gs.A[2][h[2]], gs.A[3][h[3]]))
#     leaf_value = 0.0
#     for city in attacked_cities
#         q = 1.0
#         for defender in g.iads
#             if gs.C[defender, city] == 0
#                 q *= (1 - 0.0)
#             elseif defender ∈ attacked_iads && defender ∉ defended_iads
#                 q *= (1 - 0.0)
#             elseif defender ∉ attacked_iads
#                 q *= (1 - g.pp)
#             elseif defender ∈ attacked_iads && defender ∈ defended_iads
#                 q *= (1 - g.pp * (g.pdc * g.pac)) # if a defender is cyber attacked, it has pdc * pac of being cyver-defended
#             else
#                 @warn "Unexpected defense layout."
#             end
#         end
#         leaf_value += -1.0 * g.v[city] * q # defender's expected utility for a city
#     end
#     u = player == 1 ? leaf_value * πo : -1.0 * leaf_value * πo
#     return u
# end

############################################

using Distributed
addprocs(20); nprocs()
@everywhere using Pkg
@everywhere Pkg.activate(pwd())
@everywhere using JuMP, Clp
using BenchmarkTools

@everywhere function runm(ub::Float64)
    m = Model(Clp.Optimizer)
    @variable(m, 0 <= x <= 2 )
    @variable(m, 0 <= y <= 30 )
    @objective(m, Max, 5x + 3*y )
    @constraint(m, 1x + 5y <= ub )
    # print(m)
    status = solve(m)
    # println("Objective value: ", getobjectivevalue(m))
    # println("x = ", getvalue(x))
    # println("y = ", getvalue(y))
    return getobjectivevalue(m)
end

runm(3.2)

N = 1_000
sumobj = @distributed (+) for i = 1:N
    runm(3.0)
end

meanobj = sumobj / N

@everywhere function pc()
    nheads = @distributed (+) for i = 1:200_000_000_000
        Int(rand(Bool))
    end
    nheads
end

@everywhere f(x) = Int(rand(Bool))

@btime nheads = @distributed (+) for i = 1:200_000_000
    f(1)
end

a = zeros(10)
nheads = Threads.@threads for i = 1:10
    a[i] = i
end

#########################################

using Distributed
addprocs(3)
@everywhere using Pkg
@everywhere Pkg.activate(pwd())  # required
@everywhere using LightGraphs
@everywhere using JuMP
@everywhere using Clp

@everywhere function runm(ub::Float64)
    m = Model(Clp.Optimizer)
    @variable(m, 0 <= x <= 2 )
    @variable(m, 0 <= y <= 30 )

    @objective(m, Max, 5x + 3*y )
    @constraint(m, 1x + 5y <= ub )

    # print(m)

    status = solve(m)

    # println("Objective value: ", getobjectivevalue(m))
    # println("x = ", getvalue(x))
    # println("y = ", getvalue(y))
    return getobjectivevalue(m)
end

using BenchmarkTools
nprocs()
N = 1_000_000

# single processor
# N = 1_000, 160 ms
@btime [runm(3.0) for _ in 1:N]

# 21 processors
# N = 1_000, 7.6 ms
@btime sumobj = @distributed (+) for i = 1:N
    runm(3.0)
end

meanobj = sumobj / N
runm(3.0)

using Plots; gr()

plot(rand(5))

using Gadfly, RDatasets

Gadfly.push_theme(:default)
iris = dataset("datasets", "iris")
Gadfly.plot(iris, x=:SepalLength, y=:SepalWidth)

######## Game Size ########

using Pkg; Pkg.activate(pwd())
using Revise, BenchmarkTools
using Printf

function psize_full(ncity, ndp, nap, ndc, nac)
    npatch = 2
    nexploit = 2
    nn = binomial(ncity, ndp) * npatch * nexploit * binomial(ndp, nac) *
        2^nac * binomial(ndp, ndc) * 2^nac * binomial(ncity, nap)
    @sprintf("%.2E", nn)
end

function psize_rep(ncity, ndp, nap, ndc, nac)
    npatch = 2
    nexploit = 2
    nn = 1 * npatch * nexploit * binomial(ndp, nac) *
        2^nac * binomial(ndp, ndc) * 2^nac * 1
    @sprintf("%.2E", nn)
end

function gsize(ncity, ndp, nap, ndc, nac)
    nsig1 = binomial(ncity, ndp) * binomial(ndp, ndc)
    nsig2 = binomial(ndp, nac) * binomial(ncity, nap)
    ng = nsig1 * nsig2
    @sprintf("%.2E", ng)
end

function nI(ncity, ndp, nap, ndc, nac)
    nI11 = 1
    nI13 = nI11 * binomial(ncity, ndp) * 2 * 2^nac
    nI1 = @sprintf("%.2E", nI11 + nI13)
    nI22 = binomial(ncity, ndp) * 2
    nI24 = nI22 * binomial(ndp, nac) * binomial(ndp, ndc)
    nI2 = @sprintf("%.2E", nI22 + nI24)
    (nI1, nI2)
end

function nΣ(ncity, ndp, nap, ndc, nac)
    nΣ11 = binomial(ncity, ndp)
    nΣ13 = binomial(ndp, ndc)
    nΣ1 = @sprintf("%.2E", nΣ11 * nΣ13)
    nΣ22 = binomial(ndp, nac)
    nΣ24 = binomial(ncity, nap)
    nΣ2 = @sprintf("%.2E", nΣ22 * nΣ24)
    (nΣ1, nΣ2)
end

# small size
ncity = 6
ndp = 4
nap = 3
ndc = 2
nac = 2
psize_full(ncity, ndp, nap, ndc, nac) # 7E+05
psize_rep(ncity, ndp, nap, ndc, nac) # 2E+03
gsize(ncity, ndp, nap, ndc, nac)
nI(ncity, ndp, nap, ndc, nac)
nΣ(ncity, ndp, nap, ndc, nac)

# large size
ncity = 25
ndp = 3
nap = 2
ndc = 2
nac = 2
psize_full(ncity, ndp, nap, ndc, nac)
psize_rep(ncity, ndp, nap, ndc, nac)
gsize(ncity, ndp, nap, ndc, nac)
nI(ncity, ndp, nap, ndc, nac)
nΣ(ncity, ndp, nap, ndc, nac)

ncity = 35
nnd = binomial(ncity, 1) + binomial(ncity, 2) + binomial(ncity, 3)
nnt = nnd * binomial(ncity, 5)
@sprintf("%.2E", nnt)

# Calculate coverage matrix
using Random, Distances
n = 55
r = 0.3
x = rand(2, n)
dist = pairwise(Euclidean(), x)
A = [dist[i,j] < r ? 1 : 0 for i = 1:n, j = 1:n]

using Plots; gr()
labels = string.(A[2,:])
plot(x[1,:], x[2,:], seriestype = :scatter,
    series_annotations = labels)

# Distributed scratch
using Distributed
addprocs(10)

@everywhere using LinearAlgebra

@everywhere function fsvd(k::Int64)
    svd(rand(k,k)).U |> sum
end

function fast()
    responses = Vector{Float64}(undef, nworkers())
    @sync begin
        for (idx, pid) in enumerate(workers())
            @async responses[idx] = remotecall_fetch(fsvd, pid, 1_000)
        end
    end
end

function slow()
    responses = Vector{Float64}(undef, nworkers())
    for (idx, pid) in enumerate(workers())
        responses[idx] = fsvd(1_000)
    end
end

@btime fast()
@btime slow()

########## Large file manipulation

# JuliaDB Example from https://juliacomputing.com/blog/2019/02/27/juliadb.html
using Pkg
Pkg.activate(pwd())
using Distributed
addprocs(12)
@everywhere using Pkg
@everywhere Pkg.activate(pwd())
@everywhere using JuliaDB, OnlineStats

cd("C:\\Users\\AKeith\\JuliaProjectsLocal\\temp")
datadir = "data\\Stocks"

files = glob("*.txt", datadir)
t = loadtable(files, filenamecol = :Stocks)
groupreduce(Mean(), t, :Stock, select = :Volume)

###############################

using BenchmarkTools
const arr = ["a", "b", "c", "d", "e", "f", "g", "h", "i"]
const d = Dict(arr[i] => i for i in 1:length(arr))

function ff(s::String)
    findfirst(arr .== s)
end

function fdict(s::String)
    d[s]
end

@btime ff("a")
@btime fdict("a")
@btime ff("i")
@btime fdict("i")

max_stars_repo_name: ajkeith/Cyber-Air-Defense

max_issues_repo_name: ajkeith/Cyber-Air-Defense


text:
# ------------------------------------------------------------------
# Licensed under the MIT License. See LICENSE in the project root.
# ------------------------------------------------------------------

"""
    nelms(object)

Return the number of elements in `object`.
"""
function nelms end

"""
    ncoords(object)

Return the number of dimensions
(or coordinates) of the `object`.
"""
function ncoords end

"""
    coordtype(object)

Return the coordinate type of the `object`.
"""
function coordtype end

"""
    coordinates!(buff, object, ind)

Compute the coordinates of the `ind`-th
element of the `object` in `buff`.
"""
function coordinates! end


text:
#=
Constructors for Str strings

Copyright 2017-2018 Gandalf Software, Inc., Scott P. Jones
Licensed under MIT License, see LICENSE.md
=#

function _encode_ascii_latin(str, len)
    buf, out = _allocate(UInt8, len)
    @inbounds for ch in str
        set_codeunit!(out, ch%UInt8)
        out += 1
    end
    buf
end

function _encode_ascii_latin(pnt::Ptr{UInt8}, len)
    buf, out = _allocate(UInt8, len)
    fin = out + len
    @inbounds while out < fin
        ch8 = get_codeunit(pnt)
        set_codeunit!(out,
                      (ch8 <= 0x7f ? ch8 : (((ch8 & 3) << 6) | (get_codeunit(pnt += 1) & 0x3f))))
        pnt += 1
        out += 1
    end
    buf
end

@inline function safe_copy(::Type{Vector{T}}, ::Type{C}, str) where {T<:CodeUnitTypes,C<:CSE}
    @preserve str buf begin
        len = ncodeunits(str)
        buf, out = _allocate(T, len)
        _memcpy(out, pointer(str), len)
        Str(C, buf)
    end
end

@inline safe_copy(::Type{<:Str}, ::Type{C}, str) where {C<:CSE} = Str(C, str.data)
@inline safe_copy(::Type{String}, ::Type{C}, str) where {C<:CSE} = Str(C, _data(str))

function _str(str::AbstractString)
    # handle zero length string quickly
    isempty(str) && return empty_ascii
    len, flags, num4byte, num3byte, num2byte, latin1byte = unsafe_check_string(str)
    if flags == 0
        Str(ASCIICSE, _encode_ascii_latin(str, len))
    elseif num4byte != 0
        Str(_UTF32CSE, _encode_utf32(str, len))
    elseif num3byte + num2byte != 0
        Str(_UCS2CSE, _encode_utf16(str, len))
    else
        Str(latin1byte == 0 ? ASCIICSE : _LatinCSE, _encode_ascii_latin(str, len))
    end
end

function _str(str::T) where {T<:Union{Vector{UInt8}, Str{<:Binary_CSEs}, String}}
    # handle zero length string quickly
    (siz = sizeof(str)) == 0 && return empty_ascii
    @preserve str begin
        pnt = pointer(str)
        len, flags, num4byte, num3byte, num2byte, latin1byte = fast_check_string(pnt, siz)
        if flags == 0
            buf, out = _allocate(UInt8, len)
            _memcpy(out, pnt, len)
            Str(ASCIICSE, buf)
        elseif num4byte != 0
            Str(_UTF32CSE, _encode_utf32(pnt, len))
        elseif num3byte + num2byte != 0
            Str(_UCS2CSE, _encode_utf16(pnt, len))
        else
            Str(latin1byte == 0 ? ASCIICSE : _LatinCSE, _encode_ascii_latin(pnt, len))
        end
    end
end

function _str_cpy(::Type{T}, str, len) where {T}
    @preserve str begin
        buf, pnt = _allocate(T, len)
        @inbounds for ch in str
            set_codeunit!(pnt, ch%T)
            pnt += sizeof(T)
        end
        buf
    end
end

utf_length(::Type{<:CSE}, b, e) = Int(e - b) + 1

utf_length(l) = l < 0x80 ? l : ifelse(l < 0x800, l*2-0x80, l*3-0x880)

# Must have either 1,2,3 byte characters, or 3,4 byte characters
utf_length(::Type{UTF8CSE}, b, e) = utf_length(e) - utf_length(b)

utf_length(::Type{UTF16CSE}, b, e) =
    e <= 0xffff ? (e-b+1) : ifelse(b > 0xffff, (e-b+1)*2, (e*2-b-0xfffe))

function convert(::Type{<:Str{C}}, rng::UnitRange{<:CodeUnitTypes}) where {C<:CSE}
    isempty(rng) && return empty_str(C)
    b, e = rng.start, rng.stop
    isvalid(C, b) || strerror(StrErrors.INVALID, 1, b)
    isvalid(C, e) || strerror(StrErrors.INVALID, length(rng), e)
    # Need to calculate allocation length
    Str(C, _str_cpy(C, rng, Int(e - b) + 1))
end

function convert(::Type{<:Str{C}}, rng::UnitRange{<:CodeUnitTypes}
                 ) where {C<:Union{ASCIICSE,Latin_CSEs,UCS2_CSEs,UTF32_CSEs}}
    isempty(rng) && return empty_str(C)
    b, e = rng.start, rng.stop
    isvalid(C, b) || strerror(StrErrors.INVALID, 1, b)
    isvalid(C, e) || strerror(StrErrors.INVALID, length(rng), e)
    # If contains range 0xd800-0xdfff, then also invalid
    isempty(intersect(b%UInt32:e%UInt32, 0xd800:0xdfff)) || strerror(StrErrors.INVALID, 0, rng)
    Str(C, _str_cpy(C, rng, Int(e - b) + 1))
end

function convert(::Type{<:Str{C}}, rng::UnitRange{T}) where {C<:CSE,T<:AbstractChar}
    isempty(rng) && return empty_str(C)
    b, e = rng.start, rng.stop
    isvalid(C, b) || strerror(StrErrors.INVALID, 1, b)
    isvalid(C, e) || strerror(StrErrors.INVALID, length(rng), e)
    # If contains range 0xd800-0xdfff, then also invalid
    isempty(intersect(b%UInt32:e%UInt32, 0xd800:0xdfff)) || strerror(StrErrors.INVALID, 0, rng)
    # get counts in range
    Str(C, _str_cpy(C, rng, utf_length(C, b%UInt32, e%UInt32)))
end

function convert(::Type{<:Str{C}}, rng::UnitRange{<:CodeUnitTypes}
                 ) where {C<:Union{UTF8CSE,UTF16CSE}}
    isempty(rng) && return empty_str(C)
    b, e = rng.start, rng.stop
    isvalid(C, b) || strerror(StrErrors.INVALID, 1, b)
    isvalid(C, e) || strerror(StrErrors.INVALID, length(rng), e)
    # If contains range 0xd800-0xdfff, then also invalid
    isempty(intersect(b%UInt32:e%UInt32, 0xd800:0xdfff)) || strerror(StrErrors.INVALID, 0, rng)
    len = utf_length(C, b%UInt32, e%UInt32)
    buf, out = allocate(codeunit(T), len)
    if C === UTF8CSE
        while b <= min(e, 0x7f)
            set_codeunit!(out, b)
            out += 1
            b += 0x01
        end
        while b <= min(e, 0x7ff)
            out = output_utf8_2byte!(out, b)
            b += 0x01
        end
        while b <= min(e, 0xffff)
            out = output_utf8_3byte!(out, b)
            b += 0x01
        end
        while b <= e
            out = output_utf8_4byte!(out, b)
            b += 0x01
        end
    else
        while b <= min(e, 0xffff)
            set_codeunit!(out, b)
            out += 2
            b += 0x01
        end
        while b <= e
            c1, c2 = get_utf16(ch)
            set_codeunit!(out,     c1)
            set_codeunit!(out + 2, c2)
            out += 4
            b += 0x01
        end
    end
    Str(C, buf)
end

convert(::Type{S}, rng::UnitRange{T}) where {T<:AbstractChar,S<:Str{Union{UTF8CSE,UTF16CSE}}} =
    convert(S, (rng.start%UInt32):(rng.stop%UInt32))

convert(::Type{Str}, str::AbstractString) = _str(str)
convert(::Type{Str}, str::String)         = _str(str)
convert(::Type{Str}, str::Str) = str

convert(::Type{<:Str{C}}, str::AbstractString) where {C<:CSE} = convert(Str{C}, _str(str))
convert(::Type{<:Str{C}}, str::Str{C}) where {C<:CSE} = str

convert(::Type{<:Str{RawUTF8CSE}}, str::Str{ASCIICSE}) = Str(RawUTF8CSE, str.data)
convert(::Type{<:Str{RawUTF8CSE}}, str::Str{UTF8CSE})  = Str(RawUTF8CSE, str.data)
convert(::Type{<:Str{RawUTF8CSE}}, str::String)        = Str(RawUTF8CSE, str)

convert(::Type{UniStr}, str::AbstractString) = _str(str)
convert(::Type{UniStr}, str::String)         = _str(str)
convert(::Type{UniStr}, str::Str{<:Union{ASCIICSE,SubSet_CSEs}}) = str

function convert(::Type{T},
                 vec::AbstractArray{UInt8}) where {C<:Union{UTF8CSE,ASCIICSE},T<:Str{C}}
    is_valid(T, vec) || strerror(StrErrors.INVALID)
    Str(C, _str_cpy(UInt8, vec, length(vec)))
end

convert(::Type{<:Str{C}}, vec::AbstractArray{UInt8}) where {C<:Union{BinaryCSE,Text1CSE}} =
    Str(C, _str_cpy(UInt8, vec, length(vec)))
convert(::Type{<:Str{Text2CSE}}, vec::AbstractArray{UInt16}) =
    Str(Text2CSE, _str_cpy(UInt16, vec, length(vec)))
convert(::Type{<:Str{Text4CSE}}, vec::AbstractArray{UInt32}) =
    Str(Text4CSE, _str_cpy(UInt32, vec, length(vec)))

(::Type{Str})(str::AbstractString) = _str(str)
(::Type{Str})(str::String)         = _str(str)
(::Type{Str})(str::Str) = str

(::Type{UniStr})(str::AbstractString) = _str(str)
(::Type{UniStr})(str::String)         = _str(str)
(::Type{UniStr})(str::Str{<:Union{ASCIICSE,SubSet_CSEs}}) = str

function convert(::Type{UniStr}, str::T) where {T<:Str}
    # handle zero length string quickly
    is_empty(str) && return empty_ascii
    len, flags = count_chars(T, pointer(str), ncodeunits(str))
    if flags == 0
        Str(ASCIICSE, codeunit(T) == UInt8 ? str.data : _str_cpy(UInt8, str, len))
    elseif (flags & ~(UTF_LATIN1%UInt)) == 0
        Str(_LatinCSE, codeunit(T) == UInt8 ? str.data : _str_cpy(UInt8, str, len))
    elseif (flags & UTF_UNICODE4) == 0
        Str(_UCS2CSE, codeunit(T) == UInt16 ? str.data : _str_cpy(UInt16, str, len))
    else
        Str(_UTF32CSE, codeunit(T) == UInt32 ? str.data : _str_cpy(UInt32, str, len))
    end
end

#convert(::Type{<:Str{C}}, str::String) where {C} = convert(C, _str(str))

convert(::Type{<:Str{Text1CSE}}, str::MaybeSub{String}) = Str(Text1CSE, String(str))
convert(::Type{<:Str{BinaryCSE}}, str::MaybeSub{String}) = Str(BinaryCSE, String(str))
convert(::Type{<:Str{BinaryCSE}}, str::Str{<:Union{ASCIICSE,Latin_CSEs,UTF8_CSEs}}) =
    Str(BinaryCSE, str.data)
convert(::Type{<:Str{BinaryCSE}}, str::SubString{<:Str{<:Union{ASCIICSE,Latin_CSEs,UTF8_CSEs}}}) =
    Str(BinaryCSE, String(str))

#convert(::Type{<:Str{LatinCSE}}, str::Str{_LatinCSE}) = Str(LatinCSE, str.data)
convert(::Type{<:Str{UCS2CSE}},  str::Str{_UCS2CSE})  = Str(UCS2CSE,  str.data)
convert(::Type{<:Str{UTF32CSE}}, str::Str{_UTF32CSE}) = Str(UTF32CSE, str.data)

#convert(::Type{<:Str{LatinCSE}}, str::Str{ASCIICSE})  = Str(LatinCSE, str.data)

convert(::Type{String}, str::Str{<:Union{ASCIICSE,Text1CSE,BinaryCSE}}) = str.data

function convert(::Type{String}, vec::AbstractArray{<:Chr})
    out = get_iobuffer(sizeof(vec))
    @inbounds for ch in vec
        print(out, ch)
    end
    String(take!(out))
end

function convert(::Type{String}, vec::AbstractArray{<:Union{Text1Chr,ASCIIChr}})
    @preserve buf begin
        buf, pnt = _allocate(UInt8, length(vec))
        @inbounds for byt in vec
            set_codeunit!(pnt, byt)
            pnt += 1
        end
        buf
    end
end

function Str(vec::AbstractArray{T}) where {CS,BT,T<:Chr{CS,BT}}
    C = codepoint_cse(T)
    buf, pnt = _allocate(BT, length(vec))
    @inbounds for ch in vec
        set_codeunit!(pnt, ch%BT)
        pnt += sizeof(BT)
    end
    Str(C, buf)
end

"""Convert to a UniStr if valid Unicode, otherwise return a Text1Str"""
function unsafe_str end

function _unsafe_str8(::Type{T}, str; keywords...) where {T}
    # handle zero length string quickly
    (siz = sizeof(str)) == 0 && return empty_ascii
    @preserve str begin
        pnt = pointer(str)::Ptr{UInt8}
        len, flags, num4byte, num3byte, num2byte, latin1byte, invalids =
            unsafe_check_string(pnt, 1, siz; keywords...)
        if flags == 0
            # Don't allow this to be aliased to a mutable Vector{UInt8}
            safe_copy(T, ASCIICSE, str)
        elseif invalids != 0
            safe_copy(T, Text1CSE, str)
        elseif num4byte != 0
            Str(_UTF32CSE, _encode_utf32(pnt, len))
        elseif num2byte + num3byte != 0
            Str(_UCS2CSE, _encode_utf16(pnt, len))
        else
            Str(latin1byte == 0 ? ASCIICSE : _LatinCSE, _encode_ascii_latin(pnt, len))
        end
    end
end

unsafe_str(str::Vector{UInt8}; accept_invalids=true, kwargs...) =
    _unsafe_str8(Vector{UInt8}, str; accept_invalids=accept_invalids, kwargs...)

unsafe_str(str::MaybeSub{T}; accept_invalids=true, kwargs...
                    ) where {T<:Union{String,Text1Str,ASCIIStr,BinaryStr}} =
    _unsafe_str8(T, str; accept_invalids = accept_invalids, kwargs...)

function unsafe_str(str::Union{MaybeSub{<:AbstractString},AbstractArray{T}};
                    accept_invalids = true, kwargs...) where {T<:Union{AbstractChar,UInt16,UInt32}}
    # handle zero length string quickly
    is_empty(str) && return empty_ascii
    len, flags, num4byte, num3byte, num2byte, latin1byte, invalids =
        unsafe_check_string(str; accept_invalids   = accept_invalids, kwargs...)
    if flags == 0
        Str(ASCIICSE, _cvtsize(UInt8, str, len))
    elseif invalids != 0
        # Todo: Make sure this handles different sorts of SubStrings effectively
        siz = sizeof(eltype(T))
        C = siz == 4 ? Text4CSE : (siz == 2 ? Text2CSE : Text1CSE)
        S = codeunit(C)
        buf, pnt = _allocate(S, len)
        @inbounds for ch in str
            set_codeunit!(pnt, ch%S)
            pnt += siz
        end
        Str(C, buf)
    elseif num4byte != 0
        Str(_UTF32CSE, _encode_utf32(str, len))
    elseif num2byte + num3byte != 0
        Str(_UCS2CSE, _encode_utf16(str, len))
    else
        Str(latin1byte == 0 ? ASCIICSE : _LatinCSE, _encode_ascii_latin(str, len))
    end
end

# Fallback constructors for Str types, from any AbstractString
(::Type{T})(vec::S) where {T<:Str, S<:AbstractArray} = convert(T, vec)
(::Type{T})(str::S) where {T<:Str, S<:AbstractString} = convert(T, str)
(::Type{T})(str::S) where {T<:Str, S<:Str} = convert(T, str)
(::Type{T})(str::T) where {T<:Str} = str


text:
struct CFMap{T,N}
    result::T
    cf_type::Symbol
    img_size::Tuple{Vararg{Int,N}}
    zero_index::Tuple{Vararg{Int,N}}
end

function CFMap(img, cf_type)
    img_size = size(img)

    if cf_type == :full
        zero_index = img_size
        result_size = @. 2 * img_size - 1

    elseif cf_type == :central_symmetry
        zero_index = (img_size[1:end - 1]..., 1)
        result_size = (2 .* img_size[1:end - 1] .- 1 ..., img_size[end])

    elseif cf_type == :periodic_point_point
        zero_index = map(s -> 1, img_size)
        result_size = img_size

    else
        error("$cf_type is not supported")
    end

    result = similar(img, Float32, result_size)

    CFMap(result, cf_type, img_size, zero_index)
end

function dir_ixs(cfmap, dir)
    n = maximum(abs, dir)

    way = Float32.(collect(0:n) / (n == 0 ? 1 : n))

    if cfmap.cf_type == :central_symmetry && dir[end] < 0
        dir = .- dir
    end

    ixs = map((z, d) -> way .* d, cfmap.zero_index, dir)

    if cfmap.cf_type == :periodic_point_point
        for (ix, s) in zip(ixs, cfmap.img_size)
            out_ix = ix .< 0
            ix[out_ix] .+= s
        end
    end
    ixs
end

function dir_ixs(cfmap, dir::Symbol)
    tdir = to_tuple_dir(cfmap.img_size, dir)
    dir_ixs(cfmap, tdir)
end

function shiftmap(cfmap::CFMap)
    res = cfmap.result
    ns = size(res)
    ms = ns .÷ 2
    raw_ixs = map(m -> -m:m, ms)
    ixs = map((rix, n) -> mod.(rix, n) .+ 1, raw_ixs, ns)
    res[ixs...], raw_ixs
end

function itp_map(cfmap)
    if cfmap.cf_type == :periodic_point_point
        shiftres, xs = shiftmap(cfmap)
        itp = interpolate(xs, shiftres, Gridded(Linear()))
        extrapolate(itp, Periodic())
    else
        xs = map((ix, z) -> ix .- z, axes(cfmap.result), cfmap.zero_index)
        itp = interpolate(xs, cfmap.result, Gridded(Linear()))
    end
end

"""
    dir_from_map(cfmap, dir)

Return CF on one direcion using interpolations.

`CF.(r...)`, where `r = Map.dir_ixs(cfmap, dir)`.
"""
function dir_from_map(cfmap, dir)
    way = dir_ixs(cfmap, dir)
    itp = itp_map(cfmap)
    itp.(way...)
end

function surface_dirs(cfmap, dim, ispos)
    ixs = map(s -> -(s - 1):(s - 1), cfmap.img_size)
    map(ixs, 1:length(ixs)) do ix, d
        if d == dim
            if ispos
                ix[end]
            else
                ix[1]
            end
        else
            if d < dim
                ix[:]
            else
                ix[2:end-1]
            end
        end
    end
end

function all_dirs(cfmap)
    dirs = Vector{Tuple{Vararg{Int, ndims(cfmap.result)}}}()
    for i in 1:ndims(cfmap.result)
        for ispos in [true, false]

            s_dirs = surface_dirs(cfmap, i, ispos)
            for dir in Iterators.product(s_dirs...)
                push!(dirs, dir)
            end
        end
    end
    dirs
end

"""
    mean_dir(cfmap::CFMap)

Return averaged correlation function for r = 0, 1, 2, ...
"""
function mean_dir(cfmap::CFMap)
    data = cfmap.result

    m = cfmap.img_size |> norm |> floor |> Int
    m += ndims(data) > 1

    cfdir = zeros(Float32, m)
    weights = zeros(Float32, m)

    for ix in CartesianIndices(data)
        tix = Tuple(ix)
        r = norm(tix .- cfmap.zero_index)

        q = floor(Int, r) + 1
        α = q - r

        cfdir[q] += data[ix] * α
        cfdir[q + 1] += data[ix] * (1 - α)
        weights[q] += α
        weights[q + 1] += (1 - α)
    end

    cfdir ./= weights
end

"""
    restore_full_map(cfmap::CFMap)

Return centered full correlation function map.
"""
function restore_full_map(cfmap::CFMap{T,N}) where T where N
    res = cfmap.result

    if cfmap.cf_type == :full
        res

    elseif cfmap.cf_type == :central_symmetry
        n = size(res, N)
        reversed = reverse(res)
        [selectdim(reversed, N, 1:n - 1) res]

    elseif cfmap.cf_type == :periodic_point_point
        shiftmap(cfmap)[1]

    else
        error()
    end
end

function to_tuple_dir(img_size::Tuple{Int}, dir)
    if dir == :x
        (img_size[1] - 1,)
    else
        error(":$dir is not supported for 1D images")
    end
end

function to_tuple_dir(img_size::Tuple{Int,Int}, dir)
    if dir == :x
        (img_size[1] - 1, 0)
    elseif dir == :y
        (0, img_size[2] - 1)
    elseif dir == :xy
        q = minimum(img_size) - 1
        (q, q)
    elseif dir == :yx
        q = minimum(img_size) - 1
        (-q, q)
    else
        error(":$dir is not supported for 2D images")
    end
end

function to_tuple_dir(img_size::Tuple{Int,Int,Int}, dir)
    if dir == :x
        (img_size[1] - 1, 0, 0)
    elseif dir == :y
        (0, img_size[2] - 1, 0)
    elseif dir == :z
        (0, 0, img_size[3] - 1)
    else
        error(":$dir is not supported for 3D images")
    end
end

function cut_cfmap(cfmap, mask)
    if cfmap.cf_type == :central_symmetry && mask[end]
        error("negative direction in last dimension is not supported for $(cfmap.cf_type)")
    elseif cfmap.cf_type == :periodic_point_point && any(mask)
        error("negative direction is not supported for $(cfmap.cf_type)")
    end

    ixs = map(cfmap.zero_index, cfmap.img_size, mask) do z, s, m
        if m
            z:-1:1
        else
            z:z + s - 1
        end
    end

    view(cfmap.result, ixs...)
end


text:
module HonlyHelperRisingBlock

using ..Ahorn, Maple

@mapdef Entity "HonlyHelper/RisingBlock" RisingBlock(x::Integer, y::Integer, width::Integer=2, height::Integer=2,  tiletype::String="3")

const placements = Ahorn.PlacementDict(
    "Rising Block (Honly Helper)" => Ahorn.EntityPlacement(
        RisingBlock,
        "rectangle",
        Dict{String, Any}(),
        Ahorn.tileEntityFinalizer
    ),
)

Ahorn.editingOptions(entity::RisingBlock) = Dict{String, Any}(
    "tiletype" => Ahorn.tiletypeEditingOptions()
)

Ahorn.minimumSize(entity::RisingBlock) = 8, 8
Ahorn.resizable(entity::RisingBlock) = true, true

Ahorn.selection(entity::RisingBlock) = Ahorn.getEntityRectangle(entity)

Ahorn.renderAbs(ctx::Ahorn.Cairo.CairoContext, entity::RisingBlock, room::Maple.Room) = Ahorn.drawTileEntity(ctx, room, entity)

end

max_stars_repo_name: HollyMagala/HonlyHelper

max_issues_repo_name: HollyMagala/HonlyHelper

max_forks_repo_name: HollyMagala/HonlyHelper


text:
using MCMCChains
using Test

@testset "merge_union" begin
    @test @inferred(MCMCChains.merge_union((a = [1], b = [3.0]), (c = [3], a = [2.5]))) ==
        (a = [1.0, 2.5], b = [3.0], c = [3])
end

@testset "concatenation tests" begin
    v1 = rand(500, 5, 1)
    v2 = rand(500, 5, 1)
    v3 = rand(500, 4, 1)
    v4 = rand(500, 5, 4)

    c1 = Chains(v1, ["a1", "a2", "a3", "a4", "a5"])
    c2 = Chains(v2, ["a1", "a2", "a3", "a4", "a5"], start = 501)
    c3 = Chains(v3, ["z1", "z2", "z3", "z4"])
    c4 = Chains(v4, ["a1", "a2", "a3", "a4", "a5"])

    # Test dim 1
    c1_2 = cat(c1, c2; dims = 1)
    @test c1_2.value.data == cat(v1, v2, dims=1)
    @test range(c1_2) == 1:1:1000
    @test names(c1_2) == names(c1) == names(c2)
    @test chains(c1_2) == chains(c1) == chains(c2)
    @test c1_2.value == vcat(c1, c2).value

    # Test dim 2
    c1_3 = cat(c1, c3; dims = 2)
    @test c1_3.value.data == cat(v1, v3, dims=2)
    @test range(c1_3) == 1:1:500
    @test names(c1_3) == cat(names(c1), names(c3), dims=1)
    @test chains(c1_3) == chains(c1) == chains(c3)
    @test c1_3.value == hcat(c1, c3).value

    # Test dim 3
    c1_4 = cat(c1, c4; dims = 3)
    @test c1_4.value.data == cat(v1, v4, dims=3)
    @test range(c1_4) == 1:1:500
    @test names(c1_4) == names(c1) == names(c4)
    @test length(chains(c1_4)) == length(chains(c1)) + length(chains(c4))
    @test c1_4.value == chainscat(c1, c4).value
end

@testset "vcat" begin
    chn = Chains(rand(10, 5, 2), ["a", "b", "c", "d", "e"], Dict(:internal => ["d", "e"]))
    chn1 = Chains(rand(5, 5, 2), ["a", "b", "c", "d", "e"], Dict(:internal => ["a", "b"]))

    # incorrect thinning
    @test_throws ArgumentError vcat(chn, Chains(rand(2, 5, 2); thin = 2))

    # incorrect names
    @test_throws ArgumentError vcat(chn, Chains(rand(10, 5, 2), ["a", "b", "c", "d", "f"]))

    # incorrect number of chains
    @test_throws ArgumentError vcat(chn, Chains(rand(10, 5, 3), ["a", "b", "c", "d", "e"]))

    # concate the same chain
    chn2 = vcat(chn, chn)
    @test chn2.value.data == vcat(chn.value.data, chn.value.data)
    @test size(chn2) == (20, 5, 2)
    @test names(chn2) == names(chn)
    @test range(chn2) == 1:20
    @test chn2.name_map == (parameters = [:a, :b, :c], internal = [:d, :e])

    chn2a = cat(chn, chn)
    @test chn2a.value == chn2.value
    @test chn2a.name_map == chn2.name_map
    @test chn2a.info == chn2.info

    chn2b = cat(chn, chn; dims = Val(1))
    @test chn2b.value == chn2.value
    @test chn2b.name_map == chn2.name_map
    @test chn2b.info == chn2.info

    chn2c = cat(chn, chn; dims = 1)
    @test chn2c.value == chn2.value
    @test chn2c.name_map == chn2.name_map
    @test chn2c.info == chn2.info

    # concatenate a different chain
    chn3 = vcat(chn, chn1)
    @test chn3.value.data == vcat(chn.value.data, chn1.value.data)
    @test size(chn3) == (15, 5, 2)
    @test names(chn3) == names(chn)
    @test range(chn3) == 1:15
    # just take the name map of first argument
    @test chn3.name_map == (parameters = [:a, :b, :c], internal = [:d, :e])

    chn3a = cat(chn, chn1)
    @test chn3a.value == chn3.value
    @test chn3a.name_map == chn3.name_map
    @test chn3a.info == chn3.info

    chn3b = cat(chn, chn1; dims = Val(1))
    @test chn3b.value == chn3.value
    @test chn3b.name_map == chn3.name_map
    @test chn3b.info == chn3.info

    chn3c = cat(chn, chn1; dims = 1)
    @test chn3c.value == chn3.value
    @test chn3c.name_map == chn3.name_map
    @test chn3c.info == chn3.info
end

@testset "hcat" begin
    chn = Chains(rand(10, 3, 2), ["a", "b", "c"], Dict(:internal => ["c"]))
    chn1 = Chains(rand(10, 2, 2), ["d", "e"], Dict(:internal => ["d"]))

    # incorrect ranges
    @test_throws ArgumentError hcat(chn, Chains(rand(10, 2, 2); start = 2))
    @test_throws ArgumentError hcat(chn, Chains(rand(10, 2, 2); thin = 2))

    # non-unique names
    @test_throws ArgumentError hcat(chn, chn)

    # incorrect number of chains
    @test_throws ArgumentError hcat(chn, Chains(rand(10, 2, 3)))

    # concatenate two chains
    chn2 = hcat(chn, chn1)
    @test chn2.value.data == hcat(chn.value.data, chn1.value.data)
    @test size(chn2) == (10, 5, 2)
    @test names(chn2) == vcat(names(chn), names(chn1))
    @test range(chn2) == 1:10
    @test chn2.name_map == (parameters = [:a, :b, :e], internal = [:c, :d])

    chn2a = cat(chn, chn1; dims = Val(2))
    @test chn2a.value == chn2.value
    @test chn2a.name_map == chn2.name_map
    @test chn2a.info == chn2.info

    chn2b = cat(chn, chn1; dims = 2)
    @test chn2b.value == chn2.value
    @test chn2b.name_map == chn2.name_map
    @test chn2b.info == chn2.info
end

@testset "chainscat" begin
    chn = Chains(rand(10, 3, 3), ["a", "b", "c"], Dict(:internal => ["c"]))
    chn1 = Chains(rand(10, 3, 2), ["a", "b", "c"], Dict(:internal => ["a"]))

    # incorrect ranges
    @test_throws ArgumentError chainscat(chn, Chains(rand(10, 3, 2); start = 2))
    @test_throws ArgumentError chainscat(chn, Chains(rand(10, 3, 2); thin = 2))

    # incorrect names
    @test_throws ArgumentError chainscat(chn, Chains(rand(10, 3, 2), ["d", "e", "f"]))

    # concatenate two chains
    chn2 = chainscat(chn, chn1)
    @test chn2.value.data == cat(chn.value.data, chn1.value.data; dims = 3)
    @test size(chn2) == (10, 3, 5)
    @test names(chn2) == names(chn)
    @test range(chn2) == 1:10
    # just keep the name map of the first argument
    @test chn2.name_map == (parameters = [:a, :b], internal = [:c])

    chn2a = cat(chn, chn1; dims = Val(3))
    @test chn2a.value == chn2.value
    @test chn2a.name_map == chn2.name_map
    @test chn2a.info == chn2.info

    chn2b = cat(chn, chn1; dims = 3)
    @test chn2b.value == chn2.value
    @test chn2b.name_map == chn2.name_map
    @test chn2b.info == chn2.info
end


text:
using Documenter, DynClust

makedocs()


text:
Dict{Float32,String}(
1=>"POTOSÍ",
2=>"PUERTO CAICEDO",
3=>"CÓRDOBA",
4=>"PUERRES",
5=>"ORITO",
6=>"CONTADERO",
7=>"CARMEN DE APICALÁ",
8=>"ESPINAL",
9=>"GUAMO",
10=>"SUÁREZ",
11=>"ICONONZO",
12=>"MELGAR",
13=>"VALLE DE SAN JUAN",
14=>"RONCESVALLES",
15=>"VILLAVICENCIO",
16=>"ARBELÁEZ",
17=>"FLANDES",
18=>"GUTIÉRREZ",
19=>"TRUJILLO",
20=>"GÉNOVA",
21=>"BUGALAGRANDE",
22=>"SAN LUIS",
23=>"ROVIRA",
24=>"GUAYABETAL",
25=>"FOSCA",
26=>"NILO",
27=>"CUMARAL",
28=>"PIJAO",
29=>"RICAURTE",
30=>"TIBACUY",
31=>"PASCA",
32=>"BUENAVISTA",
33=>"QUETAME",
34=>"SEVILLA",
35=>"CAICEDONIA",
36=>"AGUA DE DIOS",
37=>"FUSAGASUGÁ",
38=>"UNE",
39=>"GIRARDOT",
40=>"EL CALVARIO",
41=>"PAPUNAUA(Cor. Departamental)",
42=>"GUADALUPE",
43=>"BOLÍVAR",
44=>"MAGÜÍ (Payán)",
45=>"LEIVA",
46=>"OPORAPA",
47=>"SUCRE",
48=>"LA VEGA",
49=>"ALTAMIRA",
50=>"Calamar",
51=>"SAN AGUSTÍN",
52=>"FLORENCIA",
53=>"BALBOA",
54=>"MIRANDA",
55=>"BARAYA",
56=>"PLANADAS",
57=>"PUERTO TEJADA",
58=>"FLORIDA",
59=>"MAPIRIPANA",
60=>"AIPE",
61=>"CANDELARIA",
62=>"MAPIRIPÁN",
63=>"PRADERA",
64=>"SAN JUAN DE ARAMA",
65=>"ALPUJARRA",
66=>"CALI",
67=>"FUENTE DE ORO",
68=>"MESETAS",
69=>"GRANADA",
70=>"ATACO",
71=>"NATAGAIMA",
72=>"YUMBO",
73=>"PALMIRA",
74=>"BARRANCO MINA",
75=>"EL CASTILLO",
76=>"EL DORADO",
77=>"EL CERRITO",
78=>"CACAHUAL",
79=>"RIOBLANCO",
80=>"URIBE",
81=>"SAN MARTÍN",
82=>"PRADO",
83=>"YARUMAL",
84=>"VIJES",
85=>"GINEBRA",
86=>"DOLORES",
87=>"GUACARÍ",
88=>"LA CUMBRE",
89=>"RESTREPO",
90=>"COYAIMA",
91=>"CASTILLA LA NUEVA",
92=>"SAN CARLOS DE GUAROA",
93=>"VILLARRICA",
94=>"BUGA",
95=>"PURIFICACIÓN",
96=>"CUBARRAL",
97=>"CABRERA",
98=>"CHAPARRAL",
99=>"SAN PEDRO",
100=>"YOTOCO",
101=>"CALIMA (El Darién)",
102=>"GUAMAL",
103=>"ORTEGA",
104=>"SAN ANTONIO",
105=>"VENECIA",
106=>"MACHETÁ",
107=>"QUEBRADANEGRA",
108=>"ZIPAQUIRÁ",
109=>"LA CAPILLA",
110=>"NEMOCÓN",
111=>"MANIZALES",
112=>"HERVEO",
113=>"FALAN",
114=>"RISARALDA",
115=>"TAURAMENA",
116=>"SAN JOSÉ DEL PALMAR",
117=>"VERGARA",
118=>"NIMAIMA",
119=>"PÁEZ",
120=>"GUASCA",
121=>"ANGOSTURA",
122=>"OROCUÉ",
123=>"SUESCA",
124=>"MIRAFLORES",
125=>"CHOCONTÁ",
126=>"ÚTICA",
127=>"TAUSA",
128=>"BELÉN DE UMBRÍA",
129=>"NEIRA",
130=>"ANSERMA",
131=>"ISTMINA",
132=>"TULUÁ",
133=>"RIOFRÍO",
134=>"ACACÍAS",
135=>"ANDALUCÍA",
136=>"SAN BERNARDO",
137=>"PANDI",
138=>"CÁQUEZA",
139=>"ZARZAL",
140=>"NARIÑO",
141=>"LA TEBAIDA",
142=>"CHIPAQUE",
143=>"COELLO",
144=>"ROLDANILLO",
145=>"VIOTÁ",
146=>"SIBATÉ",
147=>"SAN JUANITO",
148=>"UBAQUE",
149=>"LA VICTORIA",
150=>"EL LITORAL DEL SAN JUÁN (Docordó)",
151=>"MONTENEGRO",
152=>"CAJAMARCA",
153=>"ARMENIA",
154=>"La Victoria (Pacoa)",
155=>"SAN MIGUEL (La Dorada)",
156=>"GUATAQUÍ",
157=>"EL DOVIO",
158=>"TOCAIMA",
159=>"PUERTO LLERAS",
160=>"EL COLEGIO",
161=>"APULO",
162=>"PIEDRAS",
163=>"ANAPOIMA",
164=>"CHOACHÍ",
165=>"SAN ANTONIO DE  TEQUENDAMA",
166=>"JERUSALÉN",
167=>"OBANDO",
168=>"CIRCASIA",
169=>"LA PEDRERA",
170=>"Santander (Araracuara)",
171=>"Mirití-Paraná (Campoamor)",
172=>"PALOCABILDO",
173=>"GUALMATÁN",
174=>"ALDANA",
175=>"PUPIALES",
176=>"ILES",
177=>"FUNES",
178=>"SOLITA",
179=>"PUERTO GUZMÁN",
180=>"OSPINA",
181=>"VILLAGARZÓN",
182=>"CUMBAL",
183=>"SAPUYES",
184=>"IMUÉS",
185=>"Solano",
186=>"YACUANQUER",
187=>"SANTIAGO",
188=>"TANGUA",
189=>"GUAITARILLA",
190=>"CURILLO",
191=>"CONSACÁ",
192=>"SAN FRANCISCO",
193=>"TÚQUERRES",
194=>"COLÓN",
195=>"PROVIDENCIA",
196=>"TARQUI",
197=>"ROBERTO PAYÁN (San José)",
198=>"LA SIERRA",
199=>"SALADOBLANCO",
200=>"ISNOS",
201=>"LA ARGENTINA",
202=>"EL PAUJIL",
203=>"ROSAS",
204=>"GARZÓN",
205=>"EL DONCELLO",
206=>"PATÍA (El Bordo)",
207=>"SORACÁ",
208=>"SAN LUIS DE PALENQUE",
209=>"SUTATAUSA",
210=>"TORIBÍO",
211=>"LEJANÍAS",
212=>"COLOMBIA",
213=>"DAGUA",
214=>"SALDAÑA",
215=>"FRESNO",
216=>"PACHO",
217=>"CUCUNUBÁ",
218=>"BERBEO",
219=>"MANZANARES",
220=>"PITAL",
221=>"AGRADO",
222=>"SOTARÁ (Paispamba)",
223=>"PURACÉ (Coconuco)",
224=>"INZÁ",
225=>"EL RETORNO",
226=>"TIMBÍO",
227=>"PAICOL",
228=>"LA PLATA",
229=>"SAN FELIPE",
230=>"ARGELIA",
231=>"GIGANTE",
232=>"POPAYÁN",
233=>"TOTORÓ",
234=>"PUERTO RICO",
235=>"MOSQUERA",
236=>"OLAYA HERRERA (Bocas de Satinga)",
237=>"SANTA BÁRBARA (Iscuandé)",
238=>"TESALIA",
239=>"LA TOLA",
240=>"ÁREA EN LITIGIO",
241=>"NÁTAGA",
242=>"EL CHARCO",
243=>"GUAPI",
244=>"CAJIBÍO",
245=>"YAGUARÁ",
246=>"CAMPOALEGRE",
247=>"SILVIA",
248=>"EL TAMBO",
249=>"PIENDAMÓ",
250=>"RIVERA",
251=>"MORICHAL (Morichal Nuevo)",
252=>"SAN JOSÉ DEL GUAVIARE",
253=>"TIMBIQUÍ",
254=>"San Vicente del Caguán",
255=>"MORALES",
256=>"TERUEL",
257=>"PUERTO CONCORDIA",
258=>"SANTA MARÍA",
259=>"PÁEZ (Belalcázar)",
260=>"PALERMO",
261=>"BUENOS AIRES",
262=>"SANTANDER DE QUILICHAO",
263=>"TELLO",
264=>"CALOTO",
265=>"GUACHENE",
266=>"VISTAHERMOSA",
267=>"CORINTO",
268=>"PADILLA",
269=>"LÓPEZ",
270=>"VILLA RICA",
271=>"NEIVA",
272=>"SUTATENZA",
273=>"GUATEQUE",
274=>"VILLAHERMOSA",
275=>"MONTERREY",
276=>"BELALCAZAR",
277=>"MANTA",
278=>"VILLETA",
279=>"MANÍ",
280=>"CHINCHINÁ",
281=>"SESQUILÉ",
282=>"NOCAIMA",
283=>"CAMPOHERMOSO",
284=>"SUPATÁ",
285=>"CASABIANCA",
286=>"SAN JOSÉ",
287=>"MEDIO SAN JUAN (Andagoya)",
288=>"VITERBO",
289=>"SANTUARIO",
290=>"PALESTINA",
291=>"MARMATO",
292=>"SUPIA",
293=>"PENSILVANIA",
294=>"SAN EDUARDO",
295=>"MARIQUITA",
296=>"HONDA",
297=>"EL PEÑÓN",
298=>"VILLAGÓMEZ",
299=>"ARANZAZU",
300=>"MARQUETALIA",
301=>"JENESANO",
302=>"ANCUYA",
303=>"SIBUNDOY",
304=>"PASTO",
305=>"VALPARAÍSO",
306=>"MILÁN",
307=>"ALBANIA",
308=>"SANDONÁ",
309=>"MALLAMA (Piedrancha)",
310=>"LA FLORIDA",
311=>"BUESACO",
312=>"SANTA CRUZ (Guachavés)",
313=>"MOCOA",
314=>"LINARES",
315=>"ALBÁN (San José)",
316=>"EL TABLÓN",
317=>"CHACHAGUÍ",
318=>"ARBOLEDA (Berruecos)",
319=>"Cartagena del Chairá",
320=>"MORELIA",
321=>"SAN JOSÉ DEL FRAGUA",
322=>"PIAMONTE",
323=>"SAN PEDRO DE CARTAGO (Cartago)",
324=>"EL PEÑOL",
325=>"BELÉN",
326=>"LA CRUZ",
327=>"LA LLANADA",
328=>"SAN LORENZO",
329=>"COLÓN (Génova)",
330=>"TAMINANGO",
331=>"LA UNIÓN",
332=>"SAN PABLO",
333=>"Carurú",
334=>"BELÉN DE LOS ANDAQUÍES",
335=>"MONTAÑITA",
336=>"GUÁTICA",
337=>"SANTA ROSALÍA",
338=>"QUINCHÍA",
339=>"UNIÓN PANAMERICANA ( Animas)",
340=>"TADÓ",
341=>"OICATÁ",
342=>"BAGADÓ",
343=>"RIO QUITO (Paimadó)",
344=>"ATRATO (Yuto)",
345=>"LABRANZAGRANDE",
346=>"CHÍQUIZA",
347=>"SIPÍ",
348=>"QUIPILE",
349=>"FUNZA",
350=>"GACHALÁ",
351=>"ZIPACÓN",
352=>"TENA",
353=>"IBAGUÉ",
354=>"ALVARADO",
355=>"VERSALLES",
356=>"SALENTO",
357=>"ANZOÁTEGUI",
358=>"LA MESA",
359=>"VILLANUEVA",
360=>"ALCALÁ",
361=>"CAPARRAPÍ",
362=>"SAMACÁ",
363=>"BAJO BAUDÓ (Pizarro)",
364=>"RIOSUCIO",
365=>"CUMARIBO",
366=>"CUCAITA",
367=>"MISTRATÓ",
368=>"TRINIDAD",
369=>"SIMIJACA",
370=>"PÁCORA",
371=>"TUNJA",
372=>"TOTA",
373=>"SAN MIGUEL DE SEMA",
374=>"VICTORIA",
375=>"CARAMANTA",
376=>"PINCHOTE",
377=>"LANDÁZURI",
378=>"CHIQUINQUIRÁ",
379=>"FIRAVITOBA",
380=>"NUNCHÍA",
381=>"AGUADAS",
382=>"TUTA",
383=>"SANTA ROSA DE OSOS",
384=>"SAMANÁ",
385=>"NORCASIA",
386=>"MONGUÍ",
387=>"SAN PABLO DE BORBUR",
388=>"INÍRIDA",
389=>"VALLE DEL GUAMUEZ (La Hormiga)",
390=>"CUASPUD (Carlosama)",
391=>"MEDINA",
392=>"FÓMEQUE",
393=>"BARBACOAS",
394=>"LOS ANDES (Sotomayor)",
395=>"SANTA ROSA",
396=>"POLICARPA",
397=>"CUMBITARA",
398=>"SAN SEBASTIÁN",
399=>"PITALITO",
400=>"ALMAGUER",
401=>"EL ROSARIO",
402=>"SUAZA",
403=>"TIMANÁ",
404=>"ELÍAS",
405=>"MARSELLA",
406=>"GACHANCIPÁ",
407=>"VILLAMARIA",
408=>"NUEVO COLÓN",
409=>"TOPAIPÍ",
410=>"SAN CAYETANO",
411=>"LA PALMA",
412=>"GUADUAS",
413=>"PUEBLO RICO",
414=>"CIÉNEGA",
415=>"LA MERCED",
416=>"GUACHETÁ",
417=>"CHÁMEZA",
418=>"PUERTO BOYACÁ",
419=>"VILLAVIEJA",
420=>"SALAMINA",
421=>"CARMEN DE CARUPA",
422=>"VENTAQUEMADA",
423=>"PAIME",
424=>"BOYACÁ",
425=>"FÚQUENE",
426=>"PAJARITO",
427=>"CÉRTEGUI",
428=>"SUSA",
429=>"EL CANTÓN DEL SAN PABLO (Managrú)",
430=>"COPER",
431=>"PACHAVITA",
432=>"VILLAPINZÓN",
433=>"TURMEQUÉ",
434=>"AGUAZUL",
435=>"ZETAQUIRÁ",
436=>"UBATÉ",
437=>"FILADELFIA",
438=>"MARULANDA",
439=>"LENGUAZAQUE",
440=>"RECETOR",
441=>"MEDIO BAUDÓ(Boca de Pepé)",
442=>"PANÁ-PANÁ (Campo Alegre)",
443=>"ENCINO",
444=>"HELICONIA",
445=>"SUSACÓN",
446=>"PUERTO CARREÑO",
447=>"GUAPOTÁ",
448=>"SOATÁ",
449=>"ANZÁ",
450=>"COPACABANA",
451=>"CONCEPCIÓN",
452=>"SAN MATEO",
453=>"SAN JERÓNIMO",
454=>"YALÍ",
455=>"EL CARMEN",
456=>"FRONTINO",
457=>"MONGUA",
458=>"FILANDIA",
459=>"TORO",
460=>"BARRANCA DE UPÍA",
461=>"ULLOA",
462=>"PARATEBUENO",
463=>"PULÍ",
464=>"BOJACÁ",
465=>"UBALÁ",
466=>"CACHIPAY",
467=>"GAMA",
468=>"PALMAR",
469=>"SAN JOAQUÍN",
470=>"DON MATÍAS",
471=>"COVARACHÍA",
472=>"SAN CALIXTO",
473=>"FRANCISCO PIZARRO (Salahonda)",
474=>"Sincé",
475=>"San Juan de Betulia (Betulia)",
476=>"Palmito",
477=>"Sincelejo",
478=>"Talaigua Nuevo",
479=>"San Antero",
480=>"San Bernardo del Viento",
481=>"Buenavista",
482=>"San Pedro",
483=>"Morroa",
484=>"San Zenón",
485=>"CHIMICHAGUA",
486=>"San Sebastián de Buenavista",
487=>"Los Palmitos",
488=>"Tolú Viejo",
489=>"Astrea",
490=>"Colosó",
491=>"Chalán",
492=>"Santa Bárbara de Pinto",
493=>"Tolú",
494=>"Córdoba",
495=>"NÓVITA",
496=>"CHITARAQUE",
497=>"PAZ DE RIO",
498=>"COCORNÁ",
499=>"TITIRIBÍ",
500=>"CARTAGO",
501=>"SANTA ISABEL",
502=>"VENADILLO",
503=>"LA CALERA",
504=>"JUNÍN",
505=>"BOGOTÁ D.C.",
506=>"EL CAIRO",
507=>"BELTRÁN",
508=>"COTA",
509=>"ANOLAIMA",
510=>"MADRID",
511=>"ANSERMANUEVO",
512=>"DOSQUEBRADAS",
513=>"PUERTO GAITÁN",
514=>"FACATATIVÁ",
515=>"SORA",
516=>"CUÍTIVA",
517=>"TINJACÁ",
518=>"SÁCHICA",
519=>"OLAYA",
520=>"ENTRERRIOS",
521=>"SANTA FE DE ANTIOQUIA",
522=>"SAN JOSÉ DE MIRANDA",
523=>"CURITÍ",
524=>"TAME",
525=>"ENCISO",
526=>"CAÑASGORDAS",
527=>"VEGACHÍ",
528=>"URAMITA",
529=>"ZAPATOCA",
530=>"SAN ANDRÉS",
531=>"MURINDÓ",
532=>"VALPARAISO",
533=>"SOGAMOSO",
534=>"ANDES",
535=>"LA DORADA",
536=>"TÁMESIS",
537=>"PISVA",
538=>"SAN LUIS DE GACENO",
539=>"GUAYATÁ",
540=>"LÍBANO",
541=>"SABANALARGA",
542=>"CHAGUANÍ",
543=>"ALMEIDA",
544=>"SOMONDOCO",
545=>"SASAIMA",
546=>"TOCANCIPÁ",
547=>"EL ÁGUILA",
548=>"LA CELIA",
549=>"SOCHA",
550=>"TÁMARA",
551=>"LA CEJA",
552=>"SALGAR",
553=>"GÜEPSA",
554=>"CALDAS",
555=>"QUÍPAMA",
556=>"AQUITANIA",
557=>"PESCA",
558=>"MARIPÍ",
559=>"TOCA",
560=>"JARDÍN",
561=>"CAJICÁ",
562=>"CHIMA",
563=>"TIPACOQUE",
564=>"VALLE DE SAN JOSÉ",
565=>"GUACAMAYAS",
566=>"PANQUEBA",
567=>"PÁRAMO",
568=>"CAICEDO",
569=>"BARBOSA",
570=>"SANTA HELENA DEL OPÓN",
571=>"CALARCÁ",
572=>"SOACHA",
573=>"QUIMBAYA",
574=>"LA CHORRERA",
575=>"SOCORRO",
576=>"ONZAGA",
577=>"SAN ROQUE",
578=>"EL ESPINO",
579=>"SANTO DOMINGO",
580=>"VÉLEZ",
581=>"CISNEROS",
582=>"MACARAVITA",
583=>"CAPITANEJO",
584=>"URRAO",
585=>"SAN MIGUEL",
586=>"PUERTO RONDÓN",
587=>"SOPETRÁN",
588=>"HATO",
589=>"CRAVO NORTE",
590=>"MOGOTES",
591=>"SAN GIL",
592=>"MACEO",
593=>"PALMAS DEL SOCORRO",
594=>"GIRARDOTA",
595=>"EL COCUY",
596=>"BOAVITA",
597=>"CARACOLÍ",
598=>"FREDONIA",
599=>"PAIPA",
600=>"NUQUÍ",
601=>"CERINZA",
602=>"SANTA BÁRBARA",
603=>"DUITAMA",
604=>"LA BELLEZA",
605=>"ALTO BAUDÓ (Pie de Pato)",
606=>"PUERTO TRIUNFO",
607=>"LA MACARENA",
608=>"HOBO",
609=>"ALGECIRAS",
610=>"ÍQUIRA",
611=>"CALDONO",
612=>"JAMBALÓ",
613=>"CUBARÁ",
614=>"SARAVENA",
615=>"GUACA",
616=>"TOLEDO",
617=>"ARAUCA",
618=>"PIEDECUESTA",
619=>"SAN VICENTE DE CHUCURÍ",
620=>"FLORIDABLANCA",
621=>"BETULIA",
622=>"DABEIBA",
623=>"CAMPAMENTO",
624=>"GIRÓN",
625=>"PEQUE",
626=>"BRICEÑO",
627=>"BARRANCABERMEJA",
628=>"TONA",
629=>"BUCARAMANGA",
630=>"REMEDIOS",
631=>"AMALFI",
632=>"YONDÓ (Casabe)",
633=>"SILOS",
634=>"Carmen del Darién  (Curbaradó)",
635=>"CHARTA",
636=>"SABOYÁ",
637=>"PUERTO SALGAR",
638=>"SANTA SOFÍA",
639=>"BETANIA",
640=>"TÓPAGA",
641=>"GACHANTIVÁ",
642=>"CÓMBITA",
643=>"NOBSA",
644=>"AMAGÁ",
645=>"SATIVASUR",
646=>"SANTANA",
647=>"SOCOTÁ",
648=>"PAZ DE ARIPORO",
649=>"TENJO",
650=>"PEREIRA",
651=>"CHÍA",
652=>"MURILLO",
653=>"CHIVOR",
654=>"LA VIRGINIA",
655=>"BITUIMA",
656=>"EL ROSAL",
657=>"AMBALEMA",
658=>"ALBÁN",
659=>"GACHETÁ",
660=>"VIANÍ",
661=>"LÉRIDA",
662=>"SANTA ROSA DE CABAL",
663=>"SAN JUAN DE RIOSECO",
664=>"EL GUACAMAYO",
665=>"OIBA",
666=>"GUATAPÉ",
667=>"SAN CARLOS",
668=>"QUIBDÓ",
669=>"LA SALINA",
670=>"PEÑOL",
671=>"GUARNE",
672=>"LA UVITA",
673=>"CONTRATACIÓN",
674=>"COROMORO",
675=>"LA PAZ",
676=>"CHARALÁ",
677=>"SAN VICENTE",
678=>"OCAMONTE",
679=>"SAN RAFAEL",
680=>"CONFINES",
681=>"ALEJANDRÍA",
682=>"EBÉJICO",
683=>"BELLO",
684=>"TIBASOSA",
685=>"LA PINTADA",
686=>"YACOPÍ",
687=>"PORE",
688=>"HISPANIA",
689=>"ARCABUCO",
690=>"MOLAGAVITA",
691=>"BARICHARA",
692=>"CHIPATÁ",
693=>"SÁCAMA",
694=>"CARMEN DE VIBORAL",
695=>"TUTAZÁ",
696=>"CONCORDIA",
697=>"SABANETA",
698=>"SAN BENITO",
699=>"SATIVANORTE",
700=>"ENVIGADO",
701=>"ANGELÓPOLIS",
702=>"RETIRO",
703=>"SUAITA",
704=>"JERICÓ",
705=>"PUERTO BERRÍO",
706=>"CARCASÍ",
707=>"GUICÁN",
708=>"CIMITARRA",
709=>"GALÁN",
710=>"MÁLAGA",
711=>"BELMIRA",
712=>"LIBORINA",
713=>"BAHÍA SOLANO (Mutis)",
714=>"CEPITÁ",
715=>"CAROLINA",
716=>"ARATOCA",
717=>"YOLOMBÓ",
718=>"VIGIA DEL FUERTE",
719=>"GÓMEZ PLATA",
720=>"CHISCAS",
721=>"BOJAYÁ (Bellavista)",
722=>"FORTUL",
723=>"SAN JOSÉ DE LA MONTAÑA",
724=>"PUERTO PARRA",
725=>"LOS SANTOS",
726=>"SIMACOTA",
727=>"BURITICÁ",
728=>"VALENCIA",
729=>"SAN JACINTO DEL CAUCA",
730=>"MONTECRISTO",
731=>"GONZÁLEZ",
732=>"Morales",
733=>"ARENAL",
734=>"Gamarra",
735=>"AYAPEL",
736=>"Aguachica",
737=>"GUARANDA",
738=>"HACARÍ",
739=>"CUCUTILLA",
740=>"PLANETA RICA",
741=>"SAN PEDRO DE URABÁ",
742=>"Norosi",
743=>"PUEBLO NUEVO",
744=>"TIQUISIO (Puerto Rico)",
745=>"Ríoviejo",
746=>"NECOCLÍ",
747=>"SAN MARCOS",
748=>"MAJAGUAL",
749=>"SAN JUAN DE URABÁ",
750=>"La Gloria",
751=>"CANALETE",
752=>"CUNDAY",
753=>"SILVANIA",
754=>"MEDIO ATRATO (Beté)",
755=>"LA PRIMAVERA",
756=>"RIONEGRO",
757=>"AGUADA",
758=>"MARINILLA",
759=>"BOLIVAR",
760=>"PUERTO NARE",
761=>"HATO COROZAL",
762=>"CHITA",
763=>"FLORIÁN",
764=>"GÁMEZA",
765=>"SOTAQUIRÁ",
766=>"BUSBANZÁ",
767=>"CORRALES",
768=>"PUEBLORRICO",
769=>"JESÚS MARÍA",
770=>"SONSÓN",
771=>"PUENTE NACIONAL",
772=>"FLORESTA",
773=>"CIUDAD BOLÍVAR",
774=>"ABEJORRAL",
775=>"MONIQUIRÁ",
776=>"MONTEBELLO",
777=>"BETÉITIVA",
778=>"TOGÜÍ",
779=>"GIRALDO",
780=>"JORDÁN",
781=>"ABRIAQUÍ",
782=>"Santa Lucía",
783=>"El Copey",
784=>"Soplaviento",
785=>"San Cristóbal",
786=>"Turbaco",
787=>"San Estanislao",
788=>"El Piñón",
789=>"Campo de La Cruz",
790=>"Villanueva",
791=>"Manatí",
792=>"Santa Rosa",
793=>"Regidor",
794=>"ACHÍ",
795=>"Altos del Rosario",
796=>"ARBOLETES",
797=>"Pelaya",
798=>"CAIMITO",
799=>"LOS CÓRDOBAS",
800=>"MONTERÍA",
801=>"Barranco de Loba",
802=>"CERETÉ",
803=>"OCAÑA",
804=>"GÁMBITA",
805=>"San Martín de Loba",
806=>"El Peñón",
807=>"SAHAGÚN",
808=>"Dibulla",
809=>"SANTA MARTA",
810=>"Concordia",
811=>"Mahates",
812=>"VETAS",
813=>"CALIFORNIA",
814=>"ITUANGO",
815=>"LEBRIJA",
816=>"CANTAGALLO",
817=>"VALDIVIA",
818=>"ANORÍ",
819=>"MATANZA",
820=>"SEGOVIA",
821=>"Mutatá",
822=>"HERRÁN",
823=>"PAMPLONITA",
824=>"EL PLAYÓN",
825=>"ÁBREGO",
826=>"SALAZAR",
827=>"LABATECA",
828=>"CERRITO",
829=>"CHITAGÁ",
830=>"Riosucio",
831=>"SABANA DE TORRES",
832=>"ZARAGOZA",
833=>"TARAZÁ",
834=>"Chigorodó",
835=>"LA ESPERANZA",
836=>"SAN JOSE DE URE",
837=>"CÁCERES",
838=>"SAN ALBERTO",
839=>"EL BAGRE",
840=>"HATILLO DE LOBA",
841=>"CIÉNAGA DE ORO",
842=>"Sucre",
843=>"Tamalameque",
844=>"Pailitas",
845=>"SAN PELAYO",
846=>"GRAMALOTE",
847=>"DURANIA",
848=>"CÁCHIRA",
849=>"PAMPLONA",
850=>"CHINÁCOTA",
851=>"MERCADERES",
852=>"Miraflores",
853=>"MACANAL",
854=>"Magangué",
855=>"SUBACHOQUE",
856=>"TENZA",
857=>"TIBIRITA",
858=>"ARMERO (Guayabal)",
859=>"GARAGOA",
860=>"COGUA",
861=>"CONDOTO",
862=>"APÍA",
863=>"RIO IRÓ (Santa Rita)",
864=>"LA PEÑA",
865=>"YOPAL",
866=>"RÁQUIRA",
867=>"MUZO",
868=>"CHIVATÁ",
869=>"IZA",
870=>"Arroyohondo",
871=>"Arjona",
872=>"Suan",
873=>"San Diego",
874=>"Cerro de San Antonio",
875=>"Algarrobo",
876=>"MUTISCUA",
877=>"JAMUNDÍ",
878=>"PINILLOS",
879=>"San Benito Abad",
880=>"PUERTO ESCONDIDO",
881=>"COTORRA",
882=>"CHINÚ",
883=>"El Roble",
884=>"MARGARITA",
885=>"Galeras",
886=>"SAN FERNANDO",
887=>"SAMPUÉS",
888=>"SAN ANDRÉS DE SOTAVENTO",
889=>"Mompós",
890=>"TUCHÍN",
891=>"Cicuco",
892=>"Moñitos",
893=>"Corozal",
894=>"Momil",
895=>"Purisíma",
896=>"Guamal",
897=>"EL BANCO",
898=>"CONVENCIÓN",
899=>"TEORAMA",
900=>"LOURDES",
901=>"PUERTO LIBERTADOR",
902=>"APARTADÓ",
903=>"CAUCASIA",
904=>"EL ZULIA",
905=>"San Martín",
906=>"LA APARTADA",
907=>"Puerto Wilches",
908=>"MONTELÍBANO",
909=>"Santa Rosa del Sur",
910=>"Simití",
911=>"NECHÍ",
912=>"TIERRALTA",
913=>"Río de Oro",
914=>"LA PLAYA",
915=>"PUERTO SANTANDER",
916=>"Repelón",
917=>"El Guamo",
918=>"Zapayán",
919=>"TUBARÁ",
920=>"Sitionuevo",
921=>"Pijiño del Carmen",
922=>"Santa Ana",
923=>"Zambrano",
924=>"El Carmén de Bolívar",
925=>"ITAGÜÍ",
926=>"El Paso",
927=>"San Jacinto",
928=>"Nueva Granada",
929=>"Ariguaní (El Dificil)",
930=>"Tenerife",
931=>"Plato",
932=>"Bosconia",
933=>"María La Baja",
934=>"San Juan Nepomuceno",
935=>"San Onofre",
936=>"Chivolo",
937=>"Pedraza",
938=>"JUAN DE ACOSTA",
939=>"MALAMBO",
940=>"VILLA DEL ROSARIO",
941=>"CÚCUTA",
942=>"EL ENCANTO",
943=>"ARAUQUITA",
944=>"TARAIRA",
945=>"Pacoa (Cor. Departamental)",
946=>"Puerto Leguízamo",
947=>"PUERTO ASÍS",
948=>"PUERTO ALEGRÍA",
949=>"Clemencia",
950=>"Pivijai",
951=>"Sabanalarga",
952=>"Ponedera",
953=>"Pueblo Bello",
954=>"Palmar de Varela",
955=>"Remolino",
956=>"Santo Tomás",
957=>"Piojó",
958=>"SABANAGRANDE",
959=>"Baranoa",
960=>"Valledupar",
961=>"Aracataca",
962=>"Usiacurí",
963=>"Lorica",
964=>"Manaure",
965=>"SAN ANDRES Y  PROVIDENCIA (Santa Isabel)",
966=>"GUACHUCAL",
967=>"SAMANIEGO",
968=>"ACEVEDO",
969=>"MOTAVITA",
970=>"SUTAMARCHÁN",
971=>"VILLA DE LEIVA",
972=>"LLORÓ",
973=>"PAYA",
974=>"GUAYABAL DE SÍQUIMA",
975=>"SOPÓ",
976=>"GUATAVITA",
977=>"TABIO",
978=>"OTANCHE",
979=>"TARSO",
980=>"TASCO",
981=>"GUAVATÁ",
982=>"SANTA ROSA DE VITERBO",
983=>"SAN JOSÉ DE PARE",
984=>"CAREPA",
985=>"Ovejas",
986=>"Fundación",
987=>"El Retén",
988=>"Polonuevo",
989=>"PUERTO ARICA",
990=>"Candelaria",
991=>"Salamina",
992=>"SOLEDAD",
993=>"GALAPA",
994=>"Zona Bananera",
995=>"Puebloviejo",
996=>"Ciénaga",
997=>"BARRANQUILLA",
998=>"Coveñas",
999=>"Turbo",
1000=>"MEDELLÍN",
1001=>"BUENAVENTURA",
1002=>"LA ESTRELLA",
1003=>"MITÚ",
1004=>"YAVARATÉ  (Cor. Departamental)",
1005=>"CÁCOTA",
1006=>"Luruaco",
1007=>"BUCARASICA",
1008=>"LOS PATIOS",
1009=>"ARBOLEDAS",
1010=>"BOCHALEMA",
1011=>"RAGONVALIA",
1012=>"SURATÁ",
1013=>"Sabanas de San Ángel",
1014=>"RONDÓN",
1015=>"EL TARRA",
1016=>"VILLA CARO",
1017=>"SARDINATA",
1018=>"SIACHOQUE",
1019=>"TIBANÁ",
1020=>"RAMIRIQUÍ",
1021=>"ÚMBITA",
1022=>"VIRACACHÁ",
1023=>"CHINAVITA",
1024=>"PAUNA",
1025=>"TUNUNGUÁ",
1026=>"CABUYARO",
1027=>"PUERTO LÓPEZ",
1028=>"PUERTO COLOMBIA",
1029=>"TARAPACÁ",
1030=>"Becerrill",
1031=>"TIBÚ",
1032=>"CHIRIGUANÁ",
1033=>"Hato Nuevo",
1034=>"Fonseca",
1035=>"Agustín Codazzi",
1036=>"La Jagua de Ibirico",
1037=>"La Jagua del Pilar",
1038=>"El Molino",
1039=>"Urumita",
1040=>"La Paz",
1041=>"Manaure Balcón del Cesar",
1042=>"Albania",
1043=>"EL Carmen",
1044=>"IPIALES",
1045=>"CURUMANÍ",
1046=>"PUERTO NARIÑO",
1047=>"Uribia",
1048=>"JURADÓ",
1049=>"ACANDÍ",
1050=>"UNGUÍA",
1051=>"Barrancas",
1052=>"Distracción",
1053=>"San Juan del Cesar",
1054=>"Riohacha",
1055=>"Maicao",
1056=>"LA GUADALUPE",
1057=>"Cartagena de Indias",
1058=>"Turbana",
1059=>"Santa Catalina",
1060=>"TUMACO",
1061=>"LETICIA")


text:
module Compose3D

using Compat
using Measures
using ThreeJS

# Defining compose node type
abstract Compose3DNode

abstract Backend

import Base: length, start, next, done, isempty, getindex, setindex!,
             display, writemime, convert, zero, isless, max, fill, size, copy,
             min, max, +, -, *, /

import Measures: resolve, w, h, d

#exporting types and functions to be used by the user on importing the module
export Context, mm, cm, inch, pt, w, h, d, cube, box, compose, draw, sphere,
       pyramid, mesh_color, wireframe, cylinder, torus, parametric

import Patchwork: Elem

function isinstalled(pkg, ge=v"0.0.0")
    try
        # Pkg.installed might throw an error,
        # we need to account for it to be able to precompile
        ver = Pkg.installed(pkg)
        if ver != nothing && ver >= ge
            return true
        else
            return false
        end
    catch
        return false
    end
end

#Including files.
include("list.jl")
include("geometry.jl")
include("material.jl")
include("lights.jl")
include("camera.jl")
include("container.jl")
include("patchable.jl")

function writemime(io::IO, mime::MIME{symbol("text/html")}, ctx::Context)
	backend = ThreeJS.outerdiv() <<
        draw(Patchable3D(100, 100), ctx)
	display(backend)
end

end # module


text:
@testset "Polyhedral" begin
    @testset "Start Solutions Iterator" begin
        f = equations(cyclic(5))
        iter = HC.PolyhedralStartSolutionsIterator(f)

        mv = 0
        for (cell, X) in iter
            mv += cell.volume
            @test size(X,2) == cell.volume
            @test all(1:size(X,2)) do j
                x = @view X[:,j]
                all(1:length(cell.indices)) do i
                    a, b = cell.indices[i]
                    v_i = iter.start_coefficients[i][a] * prod(x.^iter.support[i][:,a]) +
                          iter.start_coefficients[i][b] * prod(x.^iter.support[i][:,b])
                    abs(v_i) < 1e-12
                end
            end
        end
        @test mv == 70

        Random.seed!(130793) # this seed should result in the use of 128 bit hnf
        f = equations(PolynomialTestSystems.tritangents())
        iter = HC.PolyhedralStartSolutionsIterator(f)
        @test sum(cell_X -> first(cell_X).volume, iter) == 12636
    end

    @testset "Polyhedral solve" begin
        f = equations(cyclic(5))
        result = solve(f; start_system=:polyhedral)
        @test nfinite(result) == 70

        @polyvar x y
        result1 = solve([(x-3),(y-2)], start_system=:polyhedral, system_scaling=nothing)
        @test [3,2] ≈ solutions(result1)[1] atol=1e-8
        result1 = solve([(x-3),(y-2)], start_system=:polyhedral, system_scaling=:equations_and_variables)
        @test [3,2] ≈ solutions(result1)[1] atol=1e-8
    end

    @testset "All affine solutions" begin
        @polyvar x y
        f = [2y + 3y^2 - x*y^3, x + 4*x^2 - 2*x^3*y]
        res = solve(f, start_system=:polyhedral, only_torus=true)
        @test nsolutions(res) == 3
        @test ntracked(res) == 3

        res = solve(f, start_system=:polyhedral, affine_tracking=false, only_torus=false)
        @test nsolutions(res) == 6
        @test ntracked(res) == 8

        res = solve(f, start_system=:polyhedral, affine_tracking=true, only_torus=false)
        @test nsolutions(res) == 6
        @test ntracked(res) == 8
    end
end