text:
# dag.jl:
# ======
# Node types for DAG
#

load("utils/req.jl")
req("utils/utils.jl")

abstract Expression

# == Node =====================================================================

type Node{T<:Expression}
    val::T
    args#::Vector{Node} # todo: add back once type inference bug is fixed

    name::Union(Symbol,Nothing)
    num_uses::Int

    # raw Node constructors
    function Node(val::T, args)
        if !isa(args, Vector{Node});   args = Node[args...];   end

        node = new(val, Node[args...], nothing, 0)
        check_args(node)
        node
    end
    function Node{S<:Expression}(val::S, args...)
        error("Node{$T}: No constructor for val = $val, args=$args")
    end

    # forwards typealias constructors to Node(T, args...)
    Node(targs...) = Node(T, targs...)
end

Node         {T<:Expression}(val::T, cargs...) = Node{T}(val, cargs...)
function Node{T<:Expression}(node::Node{T}, args) # copy node, but use new args
    newnode = Node(node.val, args)
    newnode.name = node.name
    newnode
end

typealias Nodes Vector{Node}

has_name(node::Node) = !is(node.name, nothing)
get_name(node::Node) = node.name

# == Expressions ==============================================================

## terminals ##
abstract Terminal      <: Expression
type       NoEx        <: Terminal; end
type       LiteralEx   <: Terminal; value; end
type       SymbolEx    <: Terminal;
    name::Symbol
    kind::Symbol
    SymbolEx(name::Symbol, kind::Symbol) = new(name, kind)
end

## nonterminals ##
abstract Nonterminal  <: Expression
abstract   Operation  <: Nonterminal # Nonterminal with storable value
abstract     FuncOp   <: Operation     # Operation without side effects
type           KnotEx   <: FuncOp; end   # To encode additional order relations
type           TupleEx  <: FuncOp; end
type           CallEx   <: FuncOp; end
type           RefEx    <: FuncOp; end
abstract     Action   <: Operation     # Operation with side effects
type           AssignEx <: Action; end
type       EllipsisEx   <: Nonterminal; end

## expression comparison ##
# (expression types without fields compare by identity already
isequal(n1::SymbolEx,  n2::SymbolEx) = (n1.name, n1.kind)==(n2.name, n2.kind)
isequal(n1::LiteralEx, n2::LiteralEx) = n1.value==n2.value

# -- Node types ---------------------------------------------------------------

## Node type aliases ##

typealias TerminalNode{T<:Terminal}    Node{T}
typealias NontermNode {T<:Nonterminal} Node{T}
typealias OpNode      {T<:Operation}   Node{T}
typealias FuncOpNode  {T<:FuncOp}      Node{T}
typealias ActionNode  {T<:Action}      Node{T}

typealias NoNode       Node{NoEx}
typealias LiteralNode  Node{LiteralEx}
typealias SymNode      Node{SymbolEx}

typealias CallNode     Node{CallEx}
typealias RefNode      Node{RefEx}
typealias TupleNode    Node{TupleEx}
typealias KnotNode     Node{KnotEx}

typealias EllipsisNode Node{EllipsisEx}
typealias AssignNode   Node{AssignEx}

## Node type dependent methods: constructors, checker, getters ##

Node      {T<:Terminal}(::Type{T}, targs...) = Node{T}(T(targs...), ())
check_args{T<:Terminal}(node::Node{T}) = (@expect length(node.args) == 0)

Node      {T<:Nonterminal}(::Type{T}, args...) = Node{T}(T(), args)
get_args  {T<:Nonterminal}(node::Node{T}) = node.args
check_args{T<:Nonterminal}(::Node{T}) = nothing

get_op       (node::CallNode) = node.args[1]
get_callargs (node::CallNode) = node.args[2:end]
check_args   (node::CallNode) = (@expect length(node.args) >= 1)

get_A        (node::RefNode) = node.args[1]
get_inds     (node::RefNode) = node.args[2:end]
check_args   (node::RefNode)  = (@expect length(node.args) >= 1)

check_args(node::KnotNode) = (@expect length(node.args) >= 1)

get_lhs      (node::AssignNode) = node.args[1]
get_rhs      (node::AssignNode) = node.args[2]
get_preevents(node::AssignNode) = node.args[3:end]
function check_args(node::AssignNode)
    get_lhs(node)::RefNode
    @expect length(node.args) >= 2
    @expect allp(arg->isa(arg, ActionNode), get_preevents(node))
end

max_stars_repo_name: toivoh/julia-kernels

max_issues_repo_name: toivoh/julia-kernels

max_forks_repo_name: toivoh/julia-kernels


text:
export PeriodicCollisions

struct PeriodicCollisions

    dt :: Array{Float64,2}
    fantome :: Array{Int, 2}

    function PeriodicCollisions( p :: Particles)

        #aij is stored in AP(i+j(j-1)/2) for $i \leq j$;

        dt = zeros(Float64, (p.n, p.n))
        fantome = zeros(Int, (p.n, p.n))
        fill!(dt, Inf)

        for i in 1:p.n, j in (i+1):p.n
            dt_local = Inf
            k = 0
            while (isinf(dt_local) && k < 9)
                k += 1
                dt_local = compute_dt(p, j, i, k)
            end

            dt[i, j] = dt_local
            fantome[i, j] = k
        end

        new( dt, fantome )

    end

end

function compute_dt!(pc :: PeriodicCollisions, i, p :: Particles)

    for j in 1:p.n
        if i != j
            dt_local = Inf
            k = 0
            while (isinf(dt_local) && k < 9)
                k += 1
                dt_local = compute_dt(p, j, i, k)
            end

            pc.dt[i,j] = dt_local
            pc.fantome[i,j] = k
        end
    end

end

function dt_min_position(pc :: PeriodicCollisions)
    p = argmin(pc.dt)
    dt_min = pc.dt[p]
    num_fant = pc.fantome[p]
    return dt_min, num_fant, p[1], p[2]
end

function reset!(pc :: PeriodicCollisions, i)
    pc.dt[i, :] .= Inf
    pc.dt[:, i] .= Inf
end

ext: jl


text:
logit(v::Float64) = log(v/(1-v))

inv_logit(w::Float64) = exp(w)/(1+exp(w))


text:
abstract type StochasticIntegrator{dType, tType} <: Integrator{dType, tType} end

abstract type SDEIntegrator{dType, tType} <: StochasticIntegrator{dType, tType} end
abstract type PSDEIntegrator{dType, tType} <: StochasticIntegrator{dType, tType} end
abstract type SPSDEIntegrator{dType, tType} <: StochasticIntegrator{dType, tType} end

noisedims(integrator::StochasticIntegrator) = error("noisedims() not implemented for ", typeof(integrator))

"Create AtomicSolution for SDE."
function Solutions.AtomicSolution(solution::SolutionSDE{AT,TT}, integrator::Integrator) where {DT, TT, AT <: AbstractArray{DT}}
    AtomicSolutionSDE(get_initial_conditions(solution, 1)..., zeros(DT,solution.nm), zeros(DT,solution.nm), get_internal_variables(integrator))
end

"Create AtomicSolution for partitioned SDE."
function Solutions.AtomicSolution(solution::SolutionPSDE{AT,TT}, integrator::Integrator) where {DT, TT, AT <: AbstractArray{DT}}
    AtomicSolutionPSDE(get_initial_conditions(solution, 1)..., zeros(DT,solution.nm), zeros(DT,solution.nm), get_internal_variables(integrator))
end


text:
#=
Tools for repeated games

This file contains code to build and manage repeated games

It currently only has tools for solving two player repeated
games, but could be extended to do more with some effort.
=#

"""
    RepeatedGame{N,T}

Type representing an N-player repeated game.

# Fields

- `sg::NormalFormGame{N, T}` : The stage game used to create the repeated game.
- `delta::Float64` : The common discount rate at which all players discount the
  future.
"""
struct RepeatedGame{N, T<:Real}
    sg::NormalFormGame{N, T}
    delta::Float64
end

# Type alias for 2 player game
"""
    RepGame2

Type representing a 2-player repeated game; alias for `RepeatedGame{2}`.
"""
const RepGame2 = RepeatedGame{2}

#
# Helper Functions (for 2 players)
#

"""
    RepeatedGame(p1, p2, delta)

Helper constructor that builds a repeated game for two players.

# Arguments

- `p1::Player` : The first player.
- `p2::Player` : The second player.
- `delta::Float64` : The common discount rate at which all players discount the
  future.

# Returns

- `::RepeatedGame` : The repeated game.
"""
RepeatedGame(p1::Player, p2::Player, delta::Float64) =
    RepeatedGame(NormalFormGame((p1, p2)), delta)

"""
    unpack(rpd)

Helper function that unpacks the elements of a repeated game.

# Arguments

- `rpd::RepeatedGame` : The repeated game.

# Returns

- `::Tuple{NormalFormGame, Float64}` : A tuple containing the stage game
  and the delta.
"""
unpack(rpd::RepeatedGame) = (rpd.sg, rpd.delta)

# Flow utility in terms of the players actions
flow_u_1(rpd::RepGame2, a1::Int, a2::Int) =
    rpd.sg.players[1].payoff_array[a1, a2]
flow_u_2(rpd::RepGame2, a1::Int, a2::Int) =
    rpd.sg.players[2].payoff_array[a2, a1]
flow_u(rpd::RepGame2, a1::Int, a2::Int) =
    [flow_u_1(rpd, a1, a2), flow_u_2(rpd, a1, a2)]

# Computes each players best deviation given an opponent's action
best_dev_i(rpd::RepGame2, i::Int, aj::Int) =
    argmax(rpd.sg.players[i].payoff_array[:, aj])
best_dev_1(rpd::RepGame2, a2::Int) = best_dev_i(rpd, 1, a2)
best_dev_2(rpd::RepGame2, a1::Int) = best_dev_i(rpd, 2, a1)

# Computes the payoff of the best deviation
best_dev_payoff_i(rpd::RepGame2, i::Int, aj::Int) =
    maximum(rpd.sg.players[i].payoff_array[:, aj])
best_dev_payoff_1(rpd::RepGame2, a2::Int) =
    maximum(rpd.sg.players[1].payoff_array[:, a2])
best_dev_payoff_2(rpd::RepGame2, a1::Int) =
    maximum(rpd.sg.players[2].payoff_array[:, a1])

"""
    unitcircle(npts)

Places `npts` equally spaced points along the 2 dimensional unit circle and
returns the points with x coordinates in first column and y coordinates in
second column.

# Arguments

- `npts::Int` : Number of points to be placed.

# Returns

- `pts::Matrix{Float64}` : Matrix of shape `(nH, 2)` containing the coordinates
  of the points.
"""
function unitcircle(npts::Int)
    # Want our points placed on [0, 2π]
    incr = 2π / npts
    degrees = 0.0:incr:2π

    # Points on circle
    pts = Array{Float64}(undef, npts, 2)
    for i=1:npts
        x = degrees[i]
        pts[i, 1] = cos(x)
        pts[i, 2] = sin(x)
    end
    return pts
end

"""
    initialize_sg_hpl(nH, o, r)

Initializes subgradients, extreme points and hyperplane levels for the
approximation of the convex value set of a 2 player repeated game.

# Arguments

- `nH::Int` : Number of subgradients used for the approximation.
- `o::Vector{Float64}` : Origin for the approximation.
- `r::Float64` : Radius for the approximation.

# Returns

- `C::Vector{Float64}` : Vector of length `nH` containing the hyperplane
  levels.
- `H::Matrix{Float64}` : Matrix of shape `(nH, 2)` containing the subgradients.
- `Z::Matrix{Float64}` : Matrix of shape `(nH, 2)` containing the extreme
  points of the value set.
"""
function initialize_sg_hpl(nH::Int, o::Vector{Float64}, r::Float64)
    # First create unit circle
    H = unitcircle(nH)
    HT = H'

    # Choose origin and radius for big approximation
    Z = Array{Float64}(undef, 2, nH)
    for i=1:nH
        # We know that players can ever get worse than their
        # lowest punishment, so ignore anything below that
        Z[1, i] = o[1] + r*HT[1, i]
        Z[2, i] = o[2] + r*HT[2, i]
    end

    # Corresponding hyperplane levels
    C = dropdims(sum(HT .* Z, dims=1), dims=1)

    return C, H, Z
end

"""
    initialize_sg_hpl(rpd, nH)

Initializes subgradients, extreme points and hyperplane levels for the
approximation of the convex value set of a 2 player repeated game by choosing
an appropriate origin and radius.

# Arguments

- `rpd::RepeatedGame` : Two player repeated game.
- `nH::Int` : Number of subgradients used for the approximation.

# Returns

- `C::Vector{Float64}` : Vector of length `nH` containing the hyperplane
  levels.
- `H::Matrix{Float64}` : Matrix of shape `(nH, 2)` containing the subgradients.
- `Z::Matrix{Float64}` : Matrix of shape `(nH, 2)` containing the extreme
  points of the value set.
"""
function initialize_sg_hpl(rpd::RepeatedGame, nH::Int)
    # Choose the origin to be mean of max and min payoffs
    p1_min, p1_max = extrema(rpd.sg.players[1].payoff_array)
    p2_min, p2_max = extrema(rpd.sg.players[2].payoff_array)

    o = [(p1_min + p1_max)/2.0, (p2_min + p2_max)/2.0]
    r1 = max((p1_max - o[1])^2, (o[1] - p1_min)^2)
    r2 = max((p2_max - o[2])^2, (o[2] - p2_min)^2)
    r = sqrt(r1 + r2)

    return initialize_sg_hpl(nH, o, r)
end

#
# Linear Programming Functions
#
"""
    initialize_LP_matrices(rpd, H)

Initialize matrices for the linear programming problems.

# Arguments

- `rpd::RepeatedGame` : Two player repeated game.
- `H::Matrix{Float64}` : Matrix of shape `(nH, 2)` containing the subgradients
  used to approximate the value set, where `nH` is the number of subgradients.

# Returns

- `c::Vector{Float64}` : Vector of length `nH` used to determine which
  subgradient should be used, where `nH` is the number of subgradients.
- `A::Matrix{Float64}` : Matrix of shape `(nH+2, 2)` with nH set constraints
  and to be filled with 2 additional incentive compatibility constraints.
- `b::Vector{Float64}` : Vector of length `nH+2` to be filled with the values
  for the constraints.
"""
function initialize_LP_matrices(rpd::RepGame2, H::Matrix{Float64})
    # Need total number of subgradients
    nH = size(H, 1)

    # Create the c vector (objective)
    c = zeros(2)

    # Create the A matrix (constraints)
    A_H = H
    A_IC_1 = zeros(1, 2)
    A_IC_2 = zeros(1, 2)
    A_IC_1[1, 1] = -rpd.delta
    A_IC_2[1, 2] = -rpd.delta
    A = vcat(A_H, A_IC_1, A_IC_2)

    # Create the b vector (constraints)
    b = Array{Float64}(undef, nH + 2)

    return c, A, b
end

"""
    worst_value_i(rpd, H, C, i)

Given a constraint w ∈ W, this finds the worst possible payoff for agent i.

# Arguments

- `rpd::RepGame2` : Two player repeated game.
- `H::Matrix{Float64}` : Matrix of shape `(nH, 2)` containing the subgradients
  here `nH` is the number of subgradients.
- `C::Vector{Float64}` : The array containing the hyperplane levels.
- `i::Int` : The player of interest.
- `lp_solver::Union{Type{<:MathOptInterface.AbstractOptimizer},Function}` :
  Linear programming solver to be used internally. Pass a
  `MathOptInterface.AbstractOptimizer` type (such as `Clp.Optimizer`) if no
  option is needed, or a function (such as `() -> Clp.Optimizer(LogLevel=0)`)
  to supply options.

# Returns

- `out::Float64` : Worst possible payoff for player i.
"""
function worst_value_i(
    rpd::RepGame2, H::Matrix{Float64},
    C::Vector{Float64}, i::Int,
    lp_solver::Union{Type{TO},Function}=() -> Clp.Optimizer(LogLevel=0)
) where {TO<:MOI.AbstractOptimizer}
    # Objective depends on which player we are minimizing
    c = zeros(2)
    c[i] = 1.0

    CACHE = MOIU.UniversalFallback(MOIU.Model{Float64}())
    optimizer = MOIU.CachingOptimizer(CACHE, lp_solver())

    # Add variables
    x = MOI.add_variables(optimizer, 2)

    # Define objective function
    MOI.set(optimizer,
            MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(),
            MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.(c, x), 0.0))
    MOI.set(optimizer, MOI.ObjectiveSense(), MOI.MIN_SENSE)

    # Add constraints
    for i in 1:size(H,1)
        MOI.add_constraint(
            optimizer,
            MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.(H[i, :],x), 0.0),
            MOI.LessThan(C[i])
        )
    end

    # Optimize
    MOI.optimize!(optimizer)

    status = MOI.get(optimizer, MOI.TerminationStatus())

    if status == MOI.OPTIMAL
        variable_result = MOI.get(optimizer, MOI.VariablePrimal(), x)
        out = variable_result[i]
    else
        out = minimum(rpd.sg.players[i].payoff_array)
    end

    return out
end

"See `worst_value_i` for documentation"
worst_value_1(
    rpd::RepGame2,
    H::Matrix{Float64},
    C::Vector{Float64},
    lp_solver::Union{Type{TO},Function}=() -> Clp.Optimizer(LogLevel=0)
) where {TO<:MOI.AbstractOptimizer} = worst_value_i(rpd, H, C, 1, lp_solver)

"See `worst_value_i` for documentation"
worst_value_2(
    rpd::RepGame2,
    H::Matrix{Float64},
    C::Vector{Float64},
    lp_solver::Union{Type{TO},Function}=() -> Clp.Optimizer(LogLevel=0)
) where {TO<:MOI.AbstractOptimizer} = worst_value_i(rpd, H, C, 2, lp_solver)

#
# Outer Hyper Plane Approximation
#
"""
    outerapproximation(rpd; nH=32, tol=1e-8, maxiter=500, check_pure_nash=true,
                       verbose=false, nskipprint=50,
                       plib=default_library(2, Float64),
                       lp_solver=() -> Clp.Optimizer(LogLevel=0))

Approximates the set of equilibrium values for a repeated game with the outer
hyperplane approximation described by Judd, Yeltekin, Conklin (2002).

# Arguments

- `rpd::RepGame2` : Two player repeated game.
- `nH::Int` : Number of subgradients used for the approximation.
- `tol::Float64` : Tolerance in differences of set.
- `maxiter::Int` : Maximum number of iterations.
- `check_pure_nash`: Whether to perform a check about whether a pure Nash
  equilibrium exists.
- `verbose::Bool` : Whether to display updates about iterations and distance.
- `nskipprint::Int` : Number of iterations between printing information
  (assuming verbose=true).
- `plib::Polyhedra.Library`: Allows users to choose a particular package for
  the geometry computations.
  (See [Polyhedra.jl](https://github.com/JuliaPolyhedra/Polyhedra.jl)
  docs for more info). By default, it chooses to use `Polyhedra.DefaultLibrary`.
- `lp_solver::Union{<:Type{MathOptInterface.AbstractOptimizer},Function}` :
  Linear programming solver to be used internally. Pass a
  `MathOptInterface.AbstractOptimizer` type (such as `Clp.Optimizer`) if no
  option is needed, or a function (such as `() -> Clp.Optimizer(LogLevel=0)`)
  to supply options.

# Returns

- `vertices::Matrix{Float64}` : Vertices of the outer approximation of the
  value set.
"""
function outerapproximation(
        rpd::RepGame2; nH::Int=32, tol::Float64=1e-8, maxiter::Int=500,
        check_pure_nash::Bool=true, verbose::Bool=false, nskipprint::Int=50,
        plib::Polyhedra.Library=default_library(2, Float64),
        lp_solver::Union{Type{TO},Function}=() -> Clp.Optimizer(LogLevel=0)
    ) where {TO<:MOI.AbstractOptimizer}

    # set up optimizer
    CACHE = MOIU.UniversalFallback(MOIU.Model{Float64}())
    optimizer = MOIU.CachingOptimizer(CACHE, lp_solver())

    # Long unpacking of stuff
    sg, delta = unpack(rpd)
    p1, p2 = sg.players
    po_1, po_2 = p1.payoff_array, p2.payoff_array
    p1_minpayoff, p1_maxpayoff = extrema(po_1)
    p2_minpayoff, p2_maxpayoff = extrema(po_2)

    # Check to see whether at least one pure strategy NE exists
    pure_nash_exists = check_pure_nash ? length(pure_nash(sg; ntofind=1)) > 0 :
                       true
    if !pure_nash_exists
        error("No pure action Nash equilibrium exists in stage game")
    end

    # Get number of actions for each player and create action space
    nA1, nA2 = num_actions(p1), num_actions(p2)
    nAS = nA1 * nA2
    AS = QuantEcon.gridmake(1:nA1, 1:nA2)

    # Create the unit circle, points, and hyperplane levels
    C, H, Z = initialize_sg_hpl(rpd, nH)
    Cnew = copy(C)

    # Create matrices for linear programming
    c, A, b = initialize_LP_matrices(rpd, H)

    # Set iterative parameters and iterate until converged
    iter, dist = 0, 10.0
    while (iter < maxiter) & (dist > tol)
        # Compute the current worst values for each agent
        _w1 = worst_value_1(rpd, H, C, lp_solver)
        _w2 = worst_value_2(rpd, H, C, lp_solver)

        # Update all set constraints -- Copies elements 1:nH of C into b
        copyto!(b, 1, C, 1, nH)

        # Iterate over all subgradients
        for ih=1:nH
            #
            # Subgradient specific instructions
            #
            h1, h2 = H[ih, :]

            # Put the right objective into c (negative because want maximize)
            c[1] = -h1
            c[2] = -h2

            # Allocate space to store all solutions
            Cia = Array{Float64}(undef, nAS)
            Wia = Array{Float64}(undef, 2, nAS)
            for ia=1:nAS
                #
                # Action specific instruction
                #
                a1, a2 = AS[ia, :]

                # Update incentive constraints
                b[nH+1] = (1-delta)*flow_u_1(rpd, a1, a2) -
                          (1-delta)*best_dev_payoff_1(rpd, a2) - delta*_w1
                b[nH+2] = (1-delta)*flow_u_2(rpd, a1, a2) -
                          (1-delta)*best_dev_payoff_2(rpd, a1) - delta*_w2

                MOI.empty!(optimizer)

                # Add variables
                x = MOI.add_variables(optimizer, 2)

                # Define objective function
                MOI.set(
                    optimizer,
                    MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(),
                    MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.(c, x), 0.0)
                    )
                MOI.set(optimizer, MOI.ObjectiveSense(), MOI.MIN_SENSE)

                # Add constraints
                for i in 1:size(A,1)
                    MOI.add_constraint(optimizer,
                                       MOI.ScalarAffineFunction(
                                       MOI.ScalarAffineTerm.(A[i, :],x), 0.0),
                                       MOI.LessThan(b[i]))
                end

                # Solve corresponding linear program
                MOI.optimize!(optimizer)

                status = MOI.get(optimizer, MOI.TerminationStatus())
                if status == MOI.OPTIMAL
                    # Pull out optimal value and compute
                    w_sol = MOI.get(optimizer, MOI.VariablePrimal(), x)
                    value = (1-delta)*flow_u(rpd, a1, a2) + delta*w_sol

                    # Save hyperplane level and continuation promises
                    Cia[ia] = h1*value[1] + h2*value[2]
                    Wia[:, ia] = value
                else
                    Cia[ia] = -Inf
                end
            end

            # Action which pushes furthest in direction h_i
            astar = argmax(Cia)
            a1star, a2star = AS[astar, :]

            # Get hyperplane level and continuation value
            Cstar = Cia[astar]
            Wstar = Wia[:, astar]
            if Cstar > -1e15
                Cnew[ih] = Cstar
            else
                error("Failed to find feasible action/continuation pair")
            end

            # Update the points
            Z[:, ih] = (1-delta)*flow_u(rpd, a1star, a2star) + delta*[Wstar[1],
                        Wstar[2]]
        end

        # Update distance and iteration counter
        dist = maximum(abs, C - Cnew)
        iter += 1

        if verbose && mod(iter, nskipprint) == 0
            println("$iter\t$dist\t($_w1, $_w2)")
        end

        if iter >= maxiter
            @warn "Maximum Iteration Reached"
        end

        # Update hyperplane levels
        copyto!(C, Cnew)
    end

    # Given the H-representation `(H, C)` of the computed polytope of
    # equilibrium payoff profiles, we obtain its V-representation `vertices`
    # using Polyhedra.jl (it uses `plib` which was chosen for computations)
    p = polyhedron(hrep(H, C), plib)
    vr = vrep(p)
    pts = points(vr)  # Vector of Vectors

    # Reduce the number of vertices by rounding points to the tolerance
    tol_int = round(Int, abs(log10(tol))) - 1

    # Find vertices that are unique within tolerance level
    vertices = Matrix{Float64}(undef, (length(pts), 2))
    for (i, pt) in enumerate(pts)
        vertices[i, :] = round.(pt, digits=tol_int)
    end
    vertices = unique(vertices, dims=1)

    return vertices
end


text:
import ACE.OrthPolys: TransformedPolys

# TODO: it feels like there should be a generic wrapper implementation which
#       unifies Rn, Ylm and Pk and then just needs a tiny bit of wrapping...

@doc raw"""
`struct Rn1pBasis <: OneParticleBasis`

One-particle basis of the form $R_n(r_{ij})$, i.e.,
no dependence on species or on $l$.

This does two things: (1) translates the `TransformedPolys` into a valid
one-particle basis; and (2) treat it as having vectorial input, i.e. value is
scalar but gradient is vectorial.

The default symbols are `:rr` for the state and `:n` for the index of the
basis function.
"""
mutable struct Rn1pBasis{T, TT, TJ, VSYM, NSYM, TDX} <: OneParticleBasis{T}
   R::TransformedPolys{T, TT, TJ}
   B_pool::VectorPool{T}
   dB_pool::VectorPool{TDX}
end

Rn1pBasis(R::TransformedPolys{T, TT, TJ}; varsym = :rr, nsym = :n
            ) where {T, TT, TJ} =
      Rn1pBasis{T, TT, TJ, varsym, nsym}(R)

function Rn1pBasis{T, TT, TJ, VSYM, NSYM}(R::TransformedPolys{T, TT, TJ}
                                         ) where {T, TT, TJ, VSYM, NSYM}
   TDX = DState{(VSYM,), Tuple{SVector{3, T}}}
   return Rn1pBasis{T, TT, TJ, VSYM, NSYM, TDX}(
               R, VectorPool{T}(), VectorPool{TDX}())
end

# ---------------------- Implementation of Rn1pBasis

Base.length(basis::Rn1pBasis) = length(basis.R)

_varsym(::Rn1pBasis{T, TT, TJ, VSYM, NSYM}) where {T, TT, TJ, VSYM, NSYM} = VSYM
_nsym(::Rn1pBasis{T, TT, TJ, VSYM, NSYM}) where {T, TT, TJ, VSYM, NSYM} = NSYM
_n(b, basis::Rn1pBasis) = getproperty(b, _nsym(basis))
_rr(X, Rn::Rn1pBasis) = getproperty(X, _varsym(Rn))

# -> TODO : figure out how to do this well!!!
# Base.rand(basis::Ylm1pBasis) =
#       AtomState(rand(basis.zlist.list), ACE.Random.rand_vec(basis.J))

get_spec(basis::Rn1pBasis, n::Integer) = NamedTuple{(_nsym(basis),)}((n,))

get_spec(basis::Rn1pBasis) = get_spec.(Ref(basis), 1:length(basis))

==(P1::Rn1pBasis, P2::Rn1pBasis) =
   ( (P1.R == P2.R) && (typeof(P1) == typeof(P2)) )

write_dict(basis::Rn1pBasis{T}) where {T} = Dict(
      "__id__" => "ACE_Rn1pBasis",
          "R" => write_dict(basis.R),
          "varsym" => _varsym(basis),
          "nsym" => _nsym(basis) )

read_dict(::Val{:ACE_Rn1pBasis}, D::Dict) =
            Rn1pBasis(read_dict(D["R"]),
                      varsym = Symbol(D["varsym"]),
                      nsym = Symbol(D["nsym"]))

# TODO: this seems really poor; should the valtype use a type promotion here
# what if the input is a Dual???
valtype(basis::Rn1pBasis{T}, args...) where {T} = T

# TODO: this should be a generic fallback I think
gradtype(B::Rn1pBasis, X::AbstractState) = dstate_type(valtype(B, X), X)

symbols(Rn::Rn1pBasis) = [ _nsym(Rn) ]

argsyms(Rn::Rn1pBasis) = ( _varsym(Rn), )

indexrange(Rn::Rn1pBasis) = NamedTuple{(_nsym(Rn),)}((1:length(Rn),))

isadmissible(b, basis::Rn1pBasis) = (1 <= _n(b, basis) <= length(basis))

degree(b, Rn::Rn1pBasis) = _n(b, Rn) - 1

degree(b, Rn::Rn1pBasis, weight::Dict) = weight[_nsym(Rn)] * degree(b, Rn)

get_index(basis::Rn1pBasis, b) = _n(b, basis)

rand_radial(basis::Rn1pBasis) = rand_radial(basis.R)

# ---------------------------  Evaluation code
#

evaluate!(B, basis::Rn1pBasis, X::AbstractState) =
      evaluate!(B, basis.R, norm(_rr(X, basis)))

function evaluate(basis::Rn1pBasis, X::AbstractState)
   rr = _rr(X, basis)
   return evaluate(basis.R, norm(rr))
end

function evaluate_d!(dB, basis::Rn1pBasis, X::AbstractState)
   TDX = eltype(dB)
   RR = _varsym(basis)
   rr = _rr(X, basis)
   r = norm(rr)
   r̂ = rr / r
   dRdr = acquire_dB!(basis.R, r)
   evaluate_d!(dRdr, basis.R, r)
   for n = 1:length(basis)
      dB[n] = TDX( NamedTuple{(RR,)}( (dRdr[n] * r̂,) ) )
   end
   release_dB!(basis.R, dRdr)
   return dB
end

function evaluate_ed!(B, dB, basis::Rn1pBasis, X::AbstractState)
   evaluate!(B, basis, X)
   evaluate_d!(dB, basis, X)
   return B, dB
end

# ----------------- AD ... experimental

import ChainRules: rrule, NoTangent

function _rrule_evaluate(basis::Rn1pBasis, X::AbstractState,
                         w::AbstractVector{<: Number})
   rr = _rr(X, basis)
   r = norm(rr)
   a = _rrule_evaluate(basis.R, r, real.(w))
   TDX = ACE.dstate_type(a/r, X)
   return TDX( NamedTuple{(_varsym(basis),)}( (a * rr / r,)) )
end

rrule(::typeof(evaluate), basis::Rn1pBasis, X::AbstractState) =
                  evaluate(basis, X),
                  w -> (NoTangent(), NoTangent(), _rrule_evaluate(basis, X, w))

function _rrule_evaluate_d(basis::Rn1pBasis, X::AbstractState,
                           w::AbstractVector,
                           dRn = evaluate_d(basis.R, norm(_rr(X, basis))))
   rr = _rr(X, basis); r = norm(rr); r̂ = rr/r
   w_r̂ = [ dot(_rr(w, basis), r̂)  for w in w ]
   w2 = [ _rr(w[n], basis) - w_r̂[n] * r̂ for n = 1:length(w) ]
   a = _rrule_evaluate_d(basis.R, r, w_r̂)
   b = sum(dRn .* w2) / r
   TDX = ACE.dstate_type(a, X)
   return TDX( NamedTuple{(_varsym(basis),)}( (a * r̂ + b,) ) )
end

function rrule(::typeof(evaluate_d), basis::Rn1pBasis, X::AbstractState)
   rr = _rr(X, basis); r = norm(rr); r̂ = rr/r
   dRn_ = evaluate_d(basis.R, r);
   TDX = dstate_type(valtype(basis, X), X)
   dRn = [ TDX( NamedTuple{(_varsym(basis),)}( (dr * r̂,) ) )
           for dr in dRn_ ]
   return dRn,
          w -> (NoTangent(), NoTangent(), _rrule_evaluate_d(basis, X, w, dRn_))
end


text:
highway_styles = Dict(
	"motorway" => Dict("color" => 0xf98d72, "width"=>  6, "spec"=>  "-", "is_polygon" =>  false), #bright blue
	"trunk" => Dict("color" => 0x965748, "width"=>  5, "spec"=>  "-", "is_polygon" =>  false), #brown
	"primary" => Dict("color" => 0xff6868, "width"=>  5, "spec"=>  "-", "is_polygon" =>  false), #orange
	"secondary" => Dict("color" => 0xfc4b4b, "width"=>  4, "spec"=>  "-", "is_polygon" =>  false), #orange-ish red
	"tertiary" => Dict("color" => 0xfc3232, "width"=>  3, "spec"=>  "-", "is_polygon" =>  false), #red
	"unclassified" => Dict("color" => 0xF1EEE8, "width"=>  2, "spec"=>  "-", "is_polygon" =>  false),
	"residential" => Dict("color" => 0xF1EEE8, "width"=>  2, "spec"=>  "-", "is_polygon" =>  false),
	"service" => Dict("color" => 0xfceec7, "width"=>  1, "spec"=>  "-", "is_polygon" =>  false),
	"motorway_link" => Dict("color" => 0xe891a1, "width"=>  2, "spec"=>  "-", "is_polygon" =>  false),
	"trunk_link" => Dict("color" => 0xA9A9A9, "width"=>  2, "spec"=>  "-", "is_polygon" =>  false),
	"primary_link" => Dict("color" => 0xA9A9A9, "width"=>  2, "spec"=>  "-", "is_polygon" =>  false),
	"secondary_link" => Dict("color" => 0xA9A9A9, "width"=>  2, "spec"=>  "-", "is_polygon" =>  false),
	"tertiary_link" => Dict("color" => 0xA9A9A9, "width"=>  2, "spec"=>  "-", "is_polygon" =>  false),
	"living_street" => Dict("color" => 0xF1EEE8, "width"=>  2, "spec"=>  "-", "is_polygon" =>  false),
	"yes" => Dict("color" => 0xF1EEE8, "width"=>  2, "spec"=>  "-", "is_polygon" =>  false),
	"pedestrian" => Dict("color" => 0x888888, "width"=>  2, "spec"=>  "-", "is_polygon" =>  false),
	"pedestrian_area" => Dict("color" => 0x888888, "width"=>  2, "spec"=>  "-", "is_polygon" =>  true),
	"track" => Dict("color" => 0x909090, "width"=>  1, "spec"=>  ":", "is_polygon" =>  false),
	"bus_guideway" => Dict("color" => 0x989898, "width"=>  1, "spec"=>  ":", "is_polygon" =>  false),
	"escape" => Dict("color" => 0xA0A0A0, "width"=>  1, "spec"=>  ":", "is_polygon" =>  false),
	"raceway" => Dict("color" => 0xA8A8A8, "width"=>  1, "spec"=>  ":", "is_polygon" =>  false),
	"road" => Dict("color" => 0xA9A9A9, "width"=>  1, "spec"=>  ":", "is_polygon" =>  false),
	"footway" => Dict("color" => 0xB0B0B0, "width"=>  1, "spec"=>  ":", "is_polygon" =>  false),
	"bridleway" => Dict("color" => 0xB8B8B8, "width"=>  1, "spec"=>  ":", "is_polygon" =>  false),
	"steps" => Dict("color" => 0xBEBEBE, "width"=>  1, "spec"=>  ":", "is_polygon" =>  false),
	"path" => Dict("color" => 0xC0C0C0, "width"=>  1, "spec"=>  ":", "is_polygon" =>  false)
)
building_styles = Dict(
	"yes" => Dict("color" => 0xe891a1, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"house" => Dict("color" => 0x91f2ce, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"residential" => Dict("color" => 0x91f2ce, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"garage" => Dict("color" => 0x91f2ce, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"apartments" => Dict("color" => 0x91f2ce, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true), #all residential stuff is greenish
	"hut" => Dict("color" => 0xe891a1, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"detached" => Dict("color" => 0xe891a1, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"shed" => Dict("color" => 0x876d6c, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"terrace" => Dict("color" => 0xe891a1, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"garages" => Dict("color" => 0xe891a1, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"school" => Dict("color" => 0xb2effc, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"university" => Dict("color" => 0xb2effc, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true), #schools are blue
	"construction" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"farm" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"hotel" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"dormitory" => Dict("color" => 0xb2effc, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"houseboat" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"bungalow" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"static_caravan" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"cabin" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"commercial" => Dict("color" => 0xfcf2b2, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"office" => Dict("color" => 0xfcf2b2, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"industrial" => Dict("color" => 0x876d6c, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"retail" => Dict("color" => 0xfcf2b2, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"supermarket" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"warehouse" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"kiosk" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"religious" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"cathedral" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"chapel" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"church" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"mosque" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"temple" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"synagogue" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"shrine" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"bakehouse" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"kindergarten" => Dict("color" => 0xb2effc, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"civic" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"government" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"hospital" => Dict("color" => 0xA9A9A9, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"stadium" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"train_station" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"transportation" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"university" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"grandstand" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"public" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"toilets" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"barn" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"bridge" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"bunker" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"carport" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"conservatory" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"cowshed" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"digester" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"farm_auxiliary" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"garbage_shed" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"greenhouse" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"hangar" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"hut" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"pavilion" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"parking" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"riding_hall" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"roof" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"sports_hall" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"stable" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"sty" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"transformer_tower" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"service" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"ruins" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"water_tower" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"tech_cab"  => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"stilt_house" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"sports_centre" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"slurry_tank" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"semidetached_house" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"semi" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"remote_digital_terminal" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"proposed" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"planned" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"marquee" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"manufacture" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"ground_station" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"exit" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"entrance" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"container" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"condominium" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"college" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"central_office" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"allotment_house" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"brewery" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"boathouse" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"barrack" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
)
waterway_styles = Dict(
	"stream" => Dict("color" => 0x9ec3ff, "width"=>  3, "spec"=>  "-", "is_polygon" =>  false),
	"ditch" => Dict("color" => 0x9ec3ff, "width"=>  1, "spec"=>  "-", "is_polygon" =>  false),
	"river" => Dict("color" => 0x9ec3ff, "width"=>  5, "spec"=>  "-", "is_polygon" =>  false),
	"drain" => Dict("color" => 0x9ec3ff, "width"=>  1, "spec"=>  "-", "is_polygon" =>  false),
	"riverbank" => Dict("color" => 0x9ec3ff, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"canal" => Dict("color" => 0x9ec3ff, "width"=>  1, "spec"=>  "-", "is_polygon" =>  false),
	"other" => Dict("color" => 0x9ec3ff, "width"=>  1, "spec"=>  "-", "is_polygon" =>  false),
	"dock" => Dict("color" => 0x808080, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"boatyard" => Dict("color" => 0x808080, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"dam" => Dict("color" => 0x808080, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
)
leisure_styles = Dict(
	"pitch" => Dict("color" => 0xbff9b6, "width"=>  2, "spec"=>  "-", "is_polygon" =>  true),
	"swimming_pool" => Dict("color" => 0x9ec3ff, "width"=>  2, "spec"=>  "-", "is_polygon" =>  true),
	"park" => Dict("color" => 0xbff9b6, "width"=>  2, "spec"=>  "-", "is_polygon" =>  true),
	"playground" => Dict("color" => 0xbff9b6, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"garden" => Dict("color" => 0xbff9b6, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"sports_centre" => Dict("color" => 0x30bc0d, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"other" => Dict("color" => 0x808080, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
)
nature_styles = Dict(
	"wood" => Dict("color" => 0xADD19E, "width"=>  2, "spec"=>  "-", "is_polygon" =>  true),
	"tree_row" => Dict("color" => 0xADD19E, "width"=>  2, "spec"=>  "-", "is_polygon" =>  false),
	"tree" => Dict("color" => 0xADD19E, "width"=>  2, "spec"=>  "-", "is_polygon" =>  false),
	"scrub" => Dict("color" => 0xB5E3B5, "width"=>  2, "spec"=>  "-", "is_polygon" =>  true),
	"heath" => Dict("color" => 0xD6D99F, "width"=>  2, "spec"=>  "-", "is_polygon" =>  true),
	"grassland" => Dict("color" => 0xC6E4B4, "width"=>  2, "spec"=>  "-", "is_polygon" =>  true),
	"bare_rock" => Dict("color" => 0xDAD5D0, "width"=>  2, "spec"=>  "-", "is_polygon" =>  true),
	"scree" => Dict("color" => 0xEDE4DC, "width"=>  2, "spec"=>  "-", "is_polygon" =>  true),
	"shingle" => Dict("color" => 0xF9F9F9, "width"=>  2, "spec"=>  "-", "is_polygon" =>  true),
	"sand" => Dict("color" => 0xF1E5C2, "width"=>  2, "spec"=>  "-", "is_polygon" =>  true),
	"mud" => Dict("color" => 0xDDCEC0, "width"=>  2, "spec"=>  "-", "is_polygon" =>  true),
	"water" => Dict("color" => 0xF9F9F9, "width"=>  2, "spec"=>  "-", "is_polygon" =>  true),
	"wetland" => Dict("color" => 0xF9F9F9, "width"=>  2, "spec"=>  "-", "is_polygon" =>  true),
	"glacier" => Dict("color" => 0xDDECEC, "width"=>  2, "spec"=>  "-", "is_polygon" =>  true),
	"bay" => Dict("color" => 0xF9F9F9, "width"=>  2, "spec"=>  "-", "is_polygon" =>  true),
	"beach" => Dict("color" => 0xFFF1BA, "width"=>  2, "spec"=>  "-", "is_polygon" =>  true),

)
amenity_styles = Dict(
	"administration" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"advertising" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"air_filling" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"alm" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"ambulance_station" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"animal_boarding" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"animal_breeding" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"animal_shelter" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"architect_office" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"archive" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"arts_centre" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"artwork" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"atm" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"audiologist" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"baby_hatch" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"baking_oven" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"bank" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"bar" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"bbq" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"bench" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"bicycle_parking" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"bicycle_rental" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"bicycle_repair_station" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"bicycle_trailer_sharing" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"biergarten" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"bikeshed" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"blood_donation" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"boat_rental" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"boat_sharing" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"boat_storage" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"brothel" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"bts" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"buggy_parking" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"building_yard" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"bureau_de_change" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"bus_station" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"bus_stop" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"cafe" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"canoe_hire" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"car_pooling" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"car_rental" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"car_repair" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"car_sharing" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"car_wash" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"carwash" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"casino" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"charging_station" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"childcare" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"cinema" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"citymap_post" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"clinic" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"cloakroom" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"clock" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"clothes_dryer" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"club" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"coast_guard" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"coast_radar_station" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"college" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"community_center" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"community_centre" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"compressed_air" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"concert_hall" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"concession_stand" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"conference_centre" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"courier" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"courthouse" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"coworking_space" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"crematorium" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"crematory" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"crucifix" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"crypt" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"culture_center" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"customs" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"dancing_school" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"dead_pub" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"dentist" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"device_charging_station" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"disused" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"dive_centre" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"doctor" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"doctors" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"dog_bin" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"dog_waste_bin" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"dojo" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"donation" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"dressing_room" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"drinking_water" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"driving_school" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"dryer" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"education" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"embassy" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"emergency_phone" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"ev_charging" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"events_venue" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"exercise_point" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"exhibition_centre" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"fab_lab" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"fast_food" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"feeding_place" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"ferry_terminal" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"festival_grounds" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"financial_advice" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"fire_hydrant" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"fire_station" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"first_aid" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"firstaid" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"fish_spa" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"fitness_station" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"flight_school" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"food_court" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"fountain" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"fridge" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"fuel" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"gambling" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"game_feeding" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"garages" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"grave_yard" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"grit_bin" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"gym" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"harbourmaster" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"hookah_lounge" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"hospice" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"hospital" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"hotel" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"hunting_stand" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"ice_cream" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"internet_cafe" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"jobcentre" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"juice_bar" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"kindergarten" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"kiosk" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"kitchen" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"kneipp_water_cure" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"language_school" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"lavoir" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"letter_box" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"library" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"life_ring" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"lifeboat_station" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"loading_dock" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"lounger" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"love_hotel" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"marae" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"marketplace" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"medical_supply" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"microwave" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"milk_dispenser" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"mobile_library" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"monastery" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"money_transfer" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"mortuary" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"motorcycle_parking" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"motorcycle_rental" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"music_school" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"music_venue" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"nightclub" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"nursery" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"nursing_home" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"nutritionist" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"office" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"park" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"parking" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"parking_entrance" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"parking_space" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"parkink" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"payment_centre" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"payment_terminal" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"pharmacy" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"photo_booth" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"place_of_worship" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"planetarium" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"police" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"polling_station" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"post_box" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"post_office" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"preschool" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"printer" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"prison" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"prison_camp" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"proposed" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"pub" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"public_bath" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"public_bookcase" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"public_building" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"ranger_station" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"reception_desk" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"recycling" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"refugee_housing" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"register_office" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"rescue_box" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"rescue_station" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"research_institute" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"restaurant" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"retirement_home" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"sanatorium" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"sanitary_dump_station" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"sauna" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"sceptic_tank" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"school" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"seat" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"security_booth" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"septic_tank" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"shelter" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"shop" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"shower" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"ski_rental" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"ski_school" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"smoking_area" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"snow_removal_station" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"social_centre" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"social_facility" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"spa" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"stables" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"stool" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"street_lamp" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"street_light" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"stripclub" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"studio" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"swimming_pool" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"swingerclub" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"table" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"taxi" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"taxi_point" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"telephone" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"television" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"theatre" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"ticket_booth" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"ticket_validator" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"toilet" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"toilets" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"townhall" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"training" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"trolley_bay" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"tuition" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"university" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"vacuum_cleaner" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"vehicle_inspection" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"vehicle_ramp" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"vending_machine" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"veterinary" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"veterinary_pharmacy" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"vivarium" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"washing_machine" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"waste_basket" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"waste_disposal" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"waste_transfer_station" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"water" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"watering_place" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"weighbridge" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"winery" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"yacht_club" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
	"youth_centre" => Dict("color" => 0xf2d2d8, "width"=>  1, "spec"=>  "-", "is_polygon" =>  true),
)
tag2style = Dict(
	"waterway" => waterway_styles,
	"building" => building_styles,
	"highway" => highway_styles,
	"leisure" => leisure_styles,
	"nature" => nature_styles,
	"amenity" => amenity_styles,
)
function get_way_style(tags::Dict, cascade::Array{Any})
		println()
		println()
		println()
		println("<----------NEW STYLE---------->")
		if cascade != []
			style = nothing
			for rule in cascade
				d = rule[2]
				if d == Dict()
					continue
				end
				for i in keys(d)
					if haskey(tags, i)
						if d[i][1] == "yes"
							if style == nothing
								style = rule[end]
							else
								style = merge(style, rule[end])
							end
							println("$(i) -- true")
							continue
						end
						operator = d[i][2]
						if operator == "="
							operator = "=="
						end
						if tryparse(Float64, tags[i]) != nothing && tryparse(Float64, d[i][1]) !=nothing
							eval_statement = "$(tags[i])$(operator)$(d[i][1])"
						else
							eval_statement = "\"$(tags[i])\"$(operator)\"$(d[i][1])\""
						end
						println("$(eval_statement) -- $(eval(Meta.parse(eval_statement)))")
						if eval(Meta.parse(eval_statement)) == true
							if style == nothing
								style = rule[end]
							else
								style = merge(style, rule[end])
							end
						end
					end
				end
			end
			show(style)
			for i in keys(tags)
				if occursin(i, "name")
					println(tags[i])
				end
			end
			return style
		end
        for tag in ["waterway", "building", "amenity", "highway", "leisure", "nature"]
            if haskey(tags, tag)
                if haskey(tag2style[tag], tags[tag])
                    return tag2style[tag][tags[tag]]
                end
            end
        end
        return Dict("color" => 0xD3D3D3, "width"=>  1, "spec"=>  "-", "is_polygon" =>  false)
    end


text:
fname = :ARCqKsparse
c = Combi(hessian_sparse,PDataK,solve_modelKARC,preprocessKARC,decreaseKARC,TparamsKARC())
include("Template.jl")


text:
using Random, Distributions, KernelDensity, Plots; pyplot()
Random.seed!(0)

mu1, sigma1 = 10, 5
mu2, sigma2 = 40, 12
dist1, dist2 = Normal(mu1,sigma1), Normal(mu2,sigma2)
p = 0.3
mixRv() = (rand() <= p) ? rand(dist1) : rand(dist2)
mixPDF(x) = p*pdf(dist1,x) + (1-p)*pdf(dist2,x)

n = 2000
data = [mixRv() for _ in 1:n]

kdeDist = kde(data)

xGrid = -20:0.1:80
pdfKDE = pdf(kdeDist,xGrid)

plot(xGrid, pdfKDE, c=:blue, label="KDE PDF")
stephist!(data, bins=50, c=:black, normed=:true, label="Histogram")
p1 = plot!(xGrid, mixPDF.(xGrid), c=:red, label="Underlying PDF",
    xlims=(-20,80), ylims=(0,0.035), legend=:topleft,
    xlabel="X", ylabel = "Density")

hVals = [0.5,2,10]
kdeS = [kde(data,bandwidth=h) for h in hVals]
plot(xGrid, pdf(kdeS[1],xGrid), c = :green, label= "h=$(hVals[1])")
plot!(xGrid, pdf(kdeS[2],xGrid), c = :blue, label= "h=$(hVals[2])")
p2 = plot!(xGrid, pdf(kdeS[3],xGrid), c = :purple, label= "h=$(hVals[3])",
    xlims=(-20,80), ylims=(0,0.035), legend=:topleft,
    xlabel="X", ylabel = "Density")
plot(p1,p2,size = (800,400))

max_stars_repo_name: Yoshinobu-Ishizaki/StatsWithJuliaBook

max_issues_repo_name: Yoshinobu-Ishizaki/StatsWithJuliaBook

max_forks_repo_name: Yoshinobu-Ishizaki/StatsWithJuliaBook


text:
using RandomObjects
using Base.Test

type A
    i::Int
    s::Vector{String}
end

immutable B
    a::A
    f::Float64
    as::Vector{A}
end

type C{S}
    ab::Tuple{A, B, S}
end

const TESTTYPES = [Int, String, A, B, C{Int}, Dict{Int, String}, Matrix{Float32}]

@testset "Test random(T)::T" begin
    for T in TESTTYPES
        n = rand(0:5)
        dims = tuple(rand(1:2, rand(1:4))...)
        @test typeof(@inferred random(T)) == T
        @test length(@inferred random(T, n)) == n

        arr1 = @inferred random(T, dims)
        arr2 = @inferred random(T, dims...)
        for arr in [arr1, arr2]
            @test typeof(arr) == Array{T, length(dims)}
            @test size(arr) == dims
        end
    end
end


text:
@inline function normalize(class::PharmClass)
    system = class.system::String
    if system == "NDC"
        old_value = class.value::String
        new_value = _normalize_ndc(old_value)::String
        return PharmClass(system, new_value)
    else
        return class
    end
end

@inline function _normalize_ndc(old_ndc_value::String)
    return old_ndc_value
end


text:
"""
Example from the book:
    Witten, Ian H., Eibe Frank, and Mark A. Hall.
    Data Mining Practical Machine Learning Tools and Techniques
    Third Edition. Morgan Kaufmann, 2017.

Depending on weather information like outlook, temperature, humidity and windy a game is played (or not).

A call to `get_best_tree` with these indepentend variables and the dependent outcome (`play`) results in
a one-level decision tree for further predictions.
"""

using OneRule
using DataFrames

weather = DataFrame(
    outlook = ["sunny", "sunny", "overcast", "rainy", "rainy", "rainy", "overcast", "sunny", "sunny", "rainy",  "sunny", "overcast", "overcast", "rainy"],
    temperature = ["hot", "hot", "hot", "mild", "cool", "cool", "cool", "mild", "cool", "mild", "mild", "mild", "hot", "mild"],
    humidity = ["high", "high", "high", "high", "normal", "normal", "normal", "high", "normal", "normal", "normal", "high", "normal", "high"],
    windy = ["false", "true", "false", "false", "false", "true", "true", "false", "false", "false", "true", "true", "false", "true"]
)

play = ["no", "no", "yes", "yes", "yes", "no", "yes", "no", "yes", "yes", "yes", "yes", "yes", "no"]

t = get_best_tree(weather, play)

max_stars_repo_name: roland-KA/OneRule

max_issues_repo_name: roland-KA/OneRule

max_forks_repo_name: roland-KA/OneRule


text:
module NP4
# All test running on 4 procs here

using TestApp
using PartitionedArrays
const PArrays = PartitionedArrays
using MPI

if ! MPI.Initialized()
  MPI.Init()
end

include("runtests_np4_body.jl")

if MPI.Comm_size(MPI.COMM_WORLD) == 4
  prun(all_tests,mpi,(2,2))
elseif MPI.Comm_size(MPI.COMM_WORLD) == 1
  prun(all_tests,mpi,(1,1))
else
  MPI.Abort(MPI.COMM_WORLD,0)
end

end #module


text:
function Makie.mesh(grid::AdaptiveGrid{2})
    nodes = getnodes(grid)
    coords = [node.x[i] for node in nodes, i in 1:JuAFEM.getdim(grid)]
    cells = getcells(grid)
    connectivity = getproperty.(cells, :nodes)
    elements = [element[i] for element in connectivity, i in 1:4]
    #scene = Makie.scatter(coords[:,1], coords[:,2], scale_plot=false)
    hangingnodes = getncinfo(grid)
    hangingnodes = nodes[getindex.(hangingnodes,1)]
    hangingcoords = [node.x[i] for node in hangingnodes, i in 1:JuAFEM.getdim(grid)]
    scene = Makie.scatter(hangingcoords[:,1], hangingcoords[:,2], scale_plot=false,markersize=10)
    for (idx, element) in enumerate(eachrow(elements))
        Makie.lines!(scene, coords[element[[1,2,3,4,1]],1], coords[element[[1,2,3,4,1]],2], scale_plot=false)
        midpoint = ((coords[element[1],1] + coords[element[2],1]) / 2, (coords[element[2],2] + coords[element[3],2]) / 2)
        Makie.text!("cell $idx", position=midpoint, textsize=0.04)
    end
    return scene
end

function Makie.mesh(grid::AdaptiveGrid{3})
    nodes = getnodes(grid)
    coords = [node.x[i] for node in nodes, i in 1:JuAFEM.getdim(grid)]
    cells = getcells(grid)
    connectivity = getproperty.(cells, :nodes)
    elements = [element[i] for element in connectivity, i in 1:8]
    #scene = Makie.scatter(coords[:,1], coords[:,2], scale_plot=false)
    ncinfo = getncinfo(grid)
    hangingnodes = nodes[getindex.(ncinfo,1)]
    hangingcoords = [node.x[i] for node in hangingnodes, i in 1:JuAFEM.getdim(grid)]
    scene = Makie.scatter(hangingcoords[:,1], hangingcoords[:,2],hangingcoords[:,3], scale_plot=false,markersize=10)
    for (idx,hangingcoord) in enumerate(eachrow(hangingcoords))
        number = getindex.(ncinfo,1)[idx]
        Makie.text!("node $number", position=(hangingcoord...,), textsize=0.04)
    end

    for (idx, element) in enumerate(eachrow(elements))
        Makie.lines!(scene, coords[element[[1,2,3,4,1]],1], coords[element[[1,2,3,4,1]],2], coords[element[[1,2,3,4,1]],3], scale_plot=false)
        Makie.lines!(scene, coords[element[[1,5]],1], coords[element[[1,5]],2], coords[element[[1,5]],3], scale_plot=false)
        Makie.lines!(scene, coords[element[[2,6]],1], coords[element[[2,6]],2], coords[element[[2,6]],3], scale_plot=false)
        Makie.lines!(scene, coords[element[[3,7]],1], coords[element[[3,7]],2], coords[element[[3,7]],3], scale_plot=false)
        Makie.lines!(scene, coords[element[[4,8]],1], coords[element[[4,8]],2], coords[element[[4,8]],3], scale_plot=false)
        Makie.lines!(scene, coords[element[[5,6,7,8,5]],1], coords[element[[5,6,7,8,5]],2], coords[element[[5,6,7,8,5]],3], scale_plot=false)
        midpoint = ((coords[element[1],1] + coords[element[2],1]) / 2, (coords[element[2],2] + coords[element[3],2]) / 2, (coords[element[4],3] + coords[element[8],3]) / 2)
        Makie.text!("cell $idx", position=midpoint, textsize=0.04)
    end
    return scene
end

function Makie.mesh!(grid::AdaptiveGrid)
    nodes = getnodes(grid)
    coords = [node.x[i] for node in nodes, i in 1:JuAFEM.getdim(grid)]
    cells = getcells(grid)
    connectivity = getproperty.(cells, :nodes)
    elements = [element[i] for element in connectivity, i in 1:4]
    for (coordidx,coord) in enumerate(eachrow(coords))
        Makie.scatter!([coord[1]], [coord[2]], scale_plot=false)
        Makie.text!("$coordidx", position=(coord[1],coord[2], 0.3), textsize=0.04)
    end
    for element in eachrow(elements)
        Makie.lines!(coords[element[[1,2,3,4,1]],1], coords[element[[1,2,3,4,1]],2], scale_plot=false)
    end
end

function Makie.mesh(dh::JuAFEM.AbstractDofHandler, u::Array{T,1}, args...; field::Int=1, scale_plot=false, shading=false, kwargs...) where T
    # extract data
    grid = dh.grid
    nodes = getnodes(grid)
    coords = [node.x[i] for node in nodes, i in 1:JuAFEM.getdim(grid)]
    cells = getcells(grid)
    connectivity = getproperty.(cells, :nodes)
    elements = [element[i] for element in connectivity, i in 1:4]

    # nodes != dofs, hence we need to sort the solution vector node -> dof mapping
    solution = zeros(getnnodes(grid))
    for cell in CellIterator(dh)
        _celldofs = celldofs(cell)
        counter = 1
        for node in getnodes(cell)
            solution[node] = u[_celldofs[counter]]
            counter += 1
        end
    end

    # plot like Guttenberg in 15th century
    triangle_elements = vcat(elements[:,[1,2,3]], elements[:,[3,4,1]])
    return AbstractPlotting.mesh(coords, triangle_elements, color=solution, args...; scale_plot=scale_plot, shading=shading, kwargs...)
end

function Makie.mesh!(dh::JuAFEM.AbstractDofHandler, u::Array{T,1}, args...; field::Int=1, scale_plot=false, shading=false, kwargs...) where T
    # extract data
    grid = dh.grid
    nodes = getnodes(grid)
    coords = [node.x[i] for node in nodes, i in 1:JuAFEM.getdim(grid)]
    cells = getcells(grid)
    connectivity = getproperty.(cells, :nodes)
    elements = [element[i] for element in connectivity, i in 1:4]

    # nodes != dofs, hence we need to sort the solution vector node -> dof mapping
    solution = zeros(getnnodes(grid))
    for cell in CellIterator(dh)
        _celldofs = celldofs(cell)
        counter = 1
        for node in getnodes(cell)
            solution[node] = u[_celldofs[counter]]
            counter += 1
        end
    end

    # plot like Guttenberg in 15th century
    triangle_elements = vcat(elements[:,[1,2,3]], elements[:,[3,4,1]])
    return AbstractPlotting.mesh!(coords, triangle_elements, color=solution, args...; scale_plot=scale_plot, shading=shading, kwargs...)
end

function Makie.surface(dh::JuAFEM.AbstractDofHandler, u::Array{T,1}, args...; field::Int=1, scale_plot=false, shading=false, kwargs...) where T
    @assert JuAFEM.getdim(dh.grid) == 2 "Only 2D solutions supported!"
    C = getcelltype(dh.grid)
    nodes = getnodes(dh.grid)
    cells = getcells(dh.grid)
    coords = [node.x[i] for node in nodes, i in 1:2]
    connectivity = getproperty.(cells, :nodes)
    N = length(vertices(cells[1]))
    elements = [element[i] for element in connectivity, i in 1:N]
    solution = zeros(getnnodes(dh.grid))
    for cell in CellIterator(dh)
        _celldofs = celldofs(cell)
        counter = 1
        for node in getnodes(cell)
            solution[node] = u[_celldofs[counter]]
            counter += 1
        end
    end
    points = [AbstractPlotting.Point3f0(coord[1], coord[2], solution[idx]) for (idx, coord) in enumerate(eachrow(coords))]
    triangle_elements = vcat(elements[:,[1,2,3]], elements[:,[3,4,1]])
    return AbstractPlotting.mesh(points, triangle_elements, color=solution, args...; scale_plot=scale_plot, shading=shading, kwargs...)
end

function Makie.surface!(dh::JuAFEM.AbstractDofHandler, u::Array{T,1}, args...; field::Int=1, scale_plot=false, shading=false, kwargs...) where T
    @assert JuAFEM.getdim(dh.grid) == 2 "Only 2D solutions supported!"
    C = getcelltype(dh.grid)
    nodes = getnodes(dh.grid)
    cells = getcells(dh.grid)
    coords = [node.x[i] for node in nodes, i in 1:2]
    connectivity = getproperty.(cells, :nodes)
    N = length(vertices(cells[1]))
    elements = [element[i] for element in connectivity, i in 1:N]
    solution = zeros(getnnodes(dh.grid))
    for cell in CellIterator(dh)
        _celldofs = celldofs(cell)
        counter = 1
        for node in getnodes(cell)
            solution[node] = u[_celldofs[counter]]
            counter += 1
        end
    end
    points = [AbstractPlotting.Point3f0(coord[1], coord[2], solution[idx]) for (idx, coord) in enumerate(eachrow(coords))]
    triangle_elements = vcat(elements[:,[1,2,3]], elements[:,[3,4,1]])
    return AbstractPlotting.mesh!(points, triangle_elements, color=solution, args...; scale_plot=scale_plot, shading=shading, kwargs...)
end

function plot_solution2D(dh::JuAFEM.AbstractDofHandler, u; plotgrid=false)
    scene = Makie.mesh(dh, u)
    if plotgrid
        Makie.mesh!(dh.grid)
    end
    Makie.center!(scene)
    ls = Makie.colorlegend(:viridis, minimum(u):maximum(u) / 2:maximum(u), camera=Makie.campixel!, raw=true, width=(30, 300))
    scene_final = Makie.vbox(scene, ls)
end

function plot_solution3D(dh::JuAFEM.AbstractDofHandler, u; plotgrid=false)
    scene = Makie.surface(dh, u)
    if plotgrid
        Makie.mesh!(dh.grid)
    end
    Makie.center!(scene)
    ls = Makie.colorlegend(:viridis, minimum(u):maximum(u) / 2:maximum(u), camera=Makie.campixel!, raw=true, width=(30, 300))
    scene_final = Makie.vbox(scene, ls)
end


text:
using Kaleido_jll

mutable struct Pipes
    stdin::Pipe
    stdout::Pipe
    stderr::Pipe
    proc::Base.Process
    Pipes() = new()
end

const P = Pipes()

const ALL_FORMATS = ["png", "jpeg", "webp", "svg", "pdf", "eps", "json"]
const TEXT_FORMATS = ["svg", "json", "eps"]

function _restart_kaleido_process()
    if isdefined(P, :proc) && process_running(P.proc)
        kill(P.proc)
    end
    _start_kaleido_process()
end

function _start_kaleido_process()
    global P
    try
        BIN = let
            art = Kaleido_jll.artifact_dir
            cmd = if Sys.islinux() || Sys.isapple()
                joinpath(art, "kaleido")
            else
                # Windows
                joinpath(art, "kaleido.cmd")
            end
            no_sandbox = "--no-sandbox"
            Sys.isapple() ? `$(cmd) plotly --disable-gpu --single-process` : `$(cmd) plotly --disable-gpu $(no_sandbox)`
        end
        kstdin = Pipe()
        kstdout = Pipe()
        kstderr = Pipe()
        kproc = run(pipeline(BIN,
                             stdin=kstdin, stdout=kstdout, stderr=kstderr),
                    wait=false)
        process_running(kproc) || error("There was a problem startink up kaleido.")
        close(kstdout.in)
        close(kstderr.in)
        close(kstdin.out)
        Base.start_reading(kstderr.out)
        P.stdin = kstdin
        P.stdout = kstdout
        P.stderr = kstderr
        P.proc = kproc

        # read startup message and check for errors
        res = readline(P.stdout)
        if length(res) == 0
            error("Could not start Kaleido process")
        end

        js = JSON.parse(res)
        if get(js, "code", 0) != 0
            error("Could not start Kaleido process")
        end
    catch e
        @warn "Kaleido is not available on this system. Julia will be unable to save images of any plots."
        @warn "$e"
    end
    nothing
end

function savefig(
        p::Plot;
        width::Union{Nothing,Int}=nothing,
        height::Union{Nothing,Int}=nothing,
        scale::Union{Nothing,Real}=nothing,
        format::String="png"
    )::Vector{UInt8}
    if !(format in ALL_FORMATS)
        error("Unknown format $format. Expected one of $ALL_FORMATS")
    end

    # construct payload
    _get(x, def) = x === nothing ? def : x
    payload = Dict(
        :width => _get(width, 700),
        :height => _get(height, 500),
        :scale => _get(scale, 1),
        :format => format,
        :data => p
    )

    _ensure_kaleido_running()

    # convert payload to vector of bytes
    bytes = transcode(UInt8, JSON.json(payload))
    write(P.stdin, bytes)
    write(P.stdin, transcode(UInt8, "\n"))
    flush(P.stdin)

    # read stdout and parse to json
    res = readline(P.stdout)
    js = JSON.parse(res)

    # check error code
    code = get(js, "code", 0)
    if code != 0
        msg = get(js, "message", nothing)
        error("Transform failed with error code $code: $msg")
    end

    # get raw image
    img = String(js["result"])

    # base64 decode if needed, otherwise transcode to vector of byte
    if format in TEXT_FORMATS
        return transcode(UInt8, img)
    else
        return base64decode(img)
    end
end

"""
    savefig(
        io::IO,
        p::Plot;
        width::Union{Nothing,Int}=nothing,
        height::Union{Nothing,Int}=nothing,
        scale::Union{Nothing,Real}=nothing,
        format::String="png"
    )

Save a plot `p` to the io stream `io`. They keyword argument `format`
determines the type of data written to the figure and must be one of
$(join(ALL_FORMATS, ", ")), or html. `scale` sets the
image scale. `width` and `height` set the dimensions, in pixels. Defaults
are taken from `p.layout`, or supplied by plotly
"""
function savefig(io::IO,
        p::Plot;
        width::Union{Nothing,Int}=nothing,
        height::Union{Nothing,Int}=nothing,
        scale::Union{Nothing,Real}=nothing,
        format::String="png")

    if format == "html"
        return show(io, MIME("text/html"), p, include_mathjax="cdn", include_plotlyjs="cdn", full_html=true)
    end

    bytes = savefig(p, width=width, height=height, scale=scale, format=format)
    write(io, bytes)
end

"""
    savefig(
        p::Plot, fn::AbstractString;
        format::Union{Nothing,String}=nothing,
        width::Union{Nothing,Int}=nothing,
        height::Union{Nothing,Int}=nothing,
        scale::Union{Nothing,Real}=nothing,
    )

Save a plot `p` to a file named `fn`. If `format` is given and is one of
$(join(ALL_FORMATS, ", ")), or html; it will be the format of the file. By
default the format is guessed from the extension of `fn`. `scale` sets the
image scale. `width` and `height` set the dimensions, in pixels. Defaults
are taken from `p.layout`, or supplied by plotly
"""
function savefig(
        p::Plot, fn::AbstractString;
        format::Union{Nothing,String}=nothing,
        width::Union{Nothing,Int}=nothing,
        height::Union{Nothing,Int}=nothing,
        scale::Union{Nothing,Real}=nothing,
    )
    ext = split(fn, ".")[end]
    if format === nothing
        format = String(ext)
    end

    open(fn, "w") do f
        savefig(f, p; format=format, scale=scale, width=width, height=height)
    end
    return fn
end

_kaleido_running() = isdefined(P, :stdin) && isopen(P.stdin) && process_running(P.proc)
_ensure_kaleido_running() = !_kaleido_running() && _restart_kaleido_process()

const _KALEIDO_MIMES = Dict(
    "application/pdf" => "pdf",
    "image/png" => "png",
    "image/svg+xml" => "svg",
    "image/eps" => "eps",
    "image/jpeg" => "jpeg",
    "image/jpeg" => "jpeg",
    "application/json" => "json",
    "application/json; charset=UTF-8" => "json",
)

for (mime, fmt) in _KALEIDO_MIMES
    @eval function Base.show(
        io::IO, ::MIME{Symbol($mime)}, plt::Plot,
        width::Union{Nothing,Int}=nothing,
        height::Union{Nothing,Int}=nothing,
        scale::Union{Nothing,Real}=nothing,
    )
        savefig(io, plt, format=$fmt)
    end

    @eval function Base.show(
        io::IO, ::MIME{Symbol($mime)}, plt::SyncPlot,
        width::Union{Nothing,Int}=nothing,
        height::Union{Nothing,Int}=nothing,
        scale::Union{Nothing,Real}=nothing,
    )
        savefig(io, plt.plot, format=$fmt)
    end
end


text:
const def_file_blk_sz = (64*1024*1024)
##
# MapInputReader to read block sized dataframes
type FsBlockReader <: MapStreamInputReader
    fbr::BlockIO
    end_byte::Union{Char,Void}
    block_sz::Int
    function FsBlockReader(path::AbstractString="", end_byte::Union{Char,Void}=nothing, block_sz::Int=def_file_blk_sz)
        ret = new()
        ret.end_byte = end_byte
        ret.block_sz = block_sz
        !isempty(path) && reset_pos(ret, path)
        ret
    end
end
get_stream(fr::FsBlockReader) = fr.fbr
function reset_pos(fr::FsBlockReader, path::AbstractString)
    u = URI(path)
    frag = u.fragment
    path = u.path
    f = open(path, "r")
    blksz = fr.block_sz
    blk = parse(Int, frag)
    begn = blksz*(blk-1)+1
    endn = min(filesize(path), blksz*blk)
    #logmsg("processing block $blk range $begn : $endn")
    fr.fbr = BlockIO(f, begn:endn, fr.end_byte)
end

##
# Input for map
type MRFsFileInput <: MRInput
    source_spec
    reader_fn::Function

    file_list
    file_info
    block_sz::Int

    function MRFsFileInput(source_spec, reader_fn::Function, block_sz::Int=def_file_blk_sz)
        new(source_spec, reader_fn, nothing, nothing, block_sz)
    end
end

input_reader_type(inp::MRFsFileInput) = (MRFsFileInput, inp.block_sz)
get_input_reader(::Type{MRFsFileInput}, block_sz::Int) = FsBlockReader("", '\n', block_sz)

function expand_file_inputs(inp::MRFsFileInput)
    fl = ASCIIString[]
    infol = Stat[]
    rwild = r"[\*\[\?]"
    fspec = ""

    function get_files(path::AbstractString, pattern::Regex)
        function filt(fname::AbstractString)
            isdir(fname) && return false
            ismatch(pattern, basename(fname))
        end
        dir_list = readdir(path)
        filter(filt, map(x->joinpath(path,x),dir_list))
    end

    function add_file(f::AbstractString)
        push!(fl, f)
        push!(infol, stat(f))
    end

    function add_dir(path::AbstractString, pattern::Regex=r".*")
        for filt_fname in get_files(path, pattern)
            add_file(filt_fname)
        end
    end

    for fspec in inp.source_spec
        if(ismatch(rwild, fspec))                                                           # a directory with wild card specification
            dirname,pattern = ('/' in fspec) ? rsplit(fspec, '/', limit=2) : ("", fspec)    # separate the directory path and wild card specification
            (isempty(pattern) || ismatch(rwild,dirname)) && error(string("wild card must be part of file name. invalid url: ", fspec))
            isempty(dirname) && (dirname = ".")
            add_dir(dirname, Regex(pattern))
        else
            isdir(fspec) ? add_dir(fspec) : add_file(fspec)        # can be a directory or a file
        end
    end
    inp.file_list = fl
    inp.file_info = infol
    inp
end

max_stars_repo_name: tanmaykm/HadoopBlocks

max_issues_repo_name: tanmaykm/HadoopBlocks

max_forks_repo_name: tanmaykm/HadoopBlocks


text:
function YawCompensation(arg0::Frame, arg1::GroundPointing)
    return YawCompensation((Frame, GroundPointing), arg0, arg1)
end

function get_attitude(obj::YawCompensation, arg0::FieldPVCoordinatesProvider, arg1::FieldAbsoluteDate, arg2::Frame)
    return jcall(obj, "getAttitude", FieldAttitude, (FieldPVCoordinatesProvider, FieldAbsoluteDate, Frame), arg0, arg1, arg2)
end

function get_attitude(obj::YawCompensation, arg0::PVCoordinatesProvider, arg1::AbsoluteDate, arg2::Frame)
    return jcall(obj, "getAttitude", Attitude, (PVCoordinatesProvider, AbsoluteDate, Frame), arg0, arg1, arg2)
end

function get_base_state(obj::YawCompensation, arg0::FieldPVCoordinatesProvider, arg1::FieldAbsoluteDate, arg2::Frame)
    return jcall(obj, "getBaseState", FieldAttitude, (FieldPVCoordinatesProvider, FieldAbsoluteDate, Frame), arg0, arg1, arg2)
end

function get_base_state(obj::YawCompensation, arg0::PVCoordinatesProvider, arg1::AbsoluteDate, arg2::Frame)
    return jcall(obj, "getBaseState", Attitude, (PVCoordinatesProvider, AbsoluteDate, Frame), arg0, arg1, arg2)
end

function get_target_pv(obj::YawCompensation, arg0::FieldPVCoordinatesProvider, arg1::FieldAbsoluteDate, arg2::Frame)
    return jcall(obj, "getTargetPV", TimeStampedFieldPVCoordinates, (FieldPVCoordinatesProvider, FieldAbsoluteDate, Frame), arg0, arg1, arg2)
end

function get_target_pv(obj::YawCompensation, arg0::PVCoordinatesProvider, arg1::AbsoluteDate, arg2::Frame)
    return jcall(obj, "getTargetPV", TimeStampedPVCoordinates, (PVCoordinatesProvider, AbsoluteDate, Frame), arg0, arg1, arg2)
end

function get_underlying_attitude_provider(obj::YawCompensation)
    return jcall(obj, "getUnderlyingAttitudeProvider", AttitudeProvider, ())
end

function get_yaw_angle(obj::YawCompensation, arg0::FieldPVCoordinatesProvider, arg1::FieldAbsoluteDate, arg2::Frame)
    return jcall(obj, "getYawAngle", RealFieldElement, (FieldPVCoordinatesProvider, FieldAbsoluteDate, Frame), arg0, arg1, arg2)
end

function get_yaw_angle(obj::YawCompensation, arg0::PVCoordinatesProvider, arg1::AbsoluteDate, arg2::Frame)
    return jcall(obj, "getYawAngle", jdouble, (PVCoordinatesProvider, AbsoluteDate, Frame), arg0, arg1, arg2)
end


text:
using EventSimulation
using Distributions

mutable struct Customer
    tin::Float64
    tout::Float64
end

mutable struct Server
    queue::SimQueue{Customer}
    customer::Union{Customer, Nothing}
end

mutable struct State <: AbstractState
    servers::Vector{Server}
    left_customers::Vector{Customer}
    shortest::Bool
    ad::Exponential{Float64}
    sd::Exponential{Float64}
end

function arrival(s)
    if s.state.shortest
        qlen = [length(s.queue) for s in s.state.servers]
        idleserver = isnothing.(s.customer for s in s.state.servers)
        i = argmin(qlen .- idleserver)
        q = s.state.servers[i].queue
    else
        q = rand(s.state.servers).queue
    end
    provide!(s, q, Customer(s.now, NaN))
end

function request_service(server)
    function start_service(s, customer)
        @assert isnothing(server.customer)
        server.customer = customer
        register!(s, finish_service, rand(s.state.sd))
    end

    function finish_service(s)
        server.customer.tout = s.now
        push!(s.state.left_customers, server.customer)
        server.customer = nothing
        request!(s, server.queue, request_service(server))
    end
    start_service
end

function runsim(ar::Number, sr::Number, n::Integer, shortest::Bool)
    servers = [Server(SimQueue{Customer}(), nothing) for i in 1:n]
    ss = State(servers, Customer[],
               shortest, Exponential(1/ar), Exponential(1/sr))
    s = Scheduler(ss)
    repeat_register!(s, arrival, x -> rand(ss.ad))
    for server in ss.servers
        request!(s, server.queue, request_service(server))
    end
    go!(s, 1_000_000)
    mean(c.tout - c.tin for c in s.state.left_customers)
end

@show runsim(1, 0.4, 3, true)
@show runsim(1, 0.4, 3, false)