text:
# Note that this script can accept some limited command-line arguments, run
# `julia build_tarballs.jl --help` to see a usage message.
using BinaryBuilder, Pkg
import Pkg.Types: VersionSpec

# The version of this JLL is decoupled from the upstream version.
# Whenever we package a new upstream release, we initially map its
# version X.Y.Z to X00.Y00.Z00 (i.e., multiply each component by 100).
# So for example version 2.6.3 would become 200.600.300.
#
# Moreover, all our packages using this JLL use `~` in their compat ranges.
#
# Together, this allows us to increment the patch level of the JLL for minor tweaks.
# If a rebuild of the JLL is needed which keeps the upstream version identical
# but breaks ABI compatibility for any reason, we can increment the minor version
# e.g. go from 200.600.300 to 200.601.300.
# To package prerelease versions, we can also adjust the minor version; e.g. we may
# map a prerelease of 2.7.0 to 200.690.000.
#
# There is currently no plan to change the major version, except when upstream itself
# changes its major version. It simply seemed sensible to apply the same transformation
# to all components.

name = "polymake"
upstream_version = v"4.6"
version_offset = v"0.0.0"
version = VersionNumber(upstream_version.major*100+version_offset.major,
                        upstream_version.minor*100+version_offset.minor,
                        version_offset.patch)

# Collection of sources required to build polymake
sources = [
    ArchiveSource("https://github.com/polymake/polymake/archive/V$(upstream_version.major).$(upstream_version.minor).tar.gz",
                  "f88341465f412e1fed459313a7dc5fa3ddbc56807ecc7246e836ae25e54585a8")
    DirectorySource("./bundled")
]

# Bash recipe for building across all platforms
script = raw"""
# the prepared config files for non-native architectures
# assume a fixed source directory
mv $WORKSPACE/srcdir/{polymake-*,polymake}
cd $WORKSPACE/srcdir/polymake

# to be able to generate a similiar dependency tree at runtime
# we prepare a symlink tree for all dependencies
mkdir -p ${prefix}/deps
for dir in FLINT GMP MPFR PPL Perl bliss boost cddlib lrslib normaliz; do
   ln -s .. ${prefix}/deps/${dir}_jll
done

# adjust for hardcoded /workspace dirs
atomic_patch -p1 ../patches/relocatable.patch

# to unbreak ctrl+c in julia
atomic_patch -p1 ../patches/sigint.patch

# work around sigchld-handler conflicts with other libraries
atomic_patch -p1 ../patches/sigchld.patch

# patch for bliss compatibility
atomic_patch -p1 ../patches/bliss.patch

if [[ $target != x86_64-linux* ]] && [[ $target != i686-linux* ]]; then
  perl_arch=$(grep "perlxpath=" ../config/build-Opt-$target.ninja | cut -d / -f 3)
  perl_version=$(grep "perlxpath=" ../config/build-Opt-$target.ninja | cut -d / -f 2)
  # we cannot run configure and instead provide config files
  mkdir -p build/Opt
  mkdir -p build/perlx/$perl_version/$perl_arch
  cp ../config/config-$target.ninja build/config.ninja
  cp ../config/build-Opt-$target.ninja build/Opt/build.ninja
  cp ../config/targets.ninja build/targets.ninja
  ln -s ../config.ninja build/Opt/config.ninja
  cp ../config/perlx-config-$target.ninja build/perlx/$perl_version/$perl_arch/config.ninja

  atomic_patch -p1 ../patches/polymake-cross.patch
else
  unset LD_LIBRARY_PATH
  $bindir/perl \
  support/configure.pl CFLAGS="-Wno-error" CC="$CC" CXX="$CXX" \
              PERL=${prefix}/deps/Perl_jll/bin/perl \
              LDFLAGS="$LDFLAGS -L${prefix}/deps/Perl_jll/lib -Wl,-rpath,${prefix}/deps/Perl_jll/lib" \
              --prefix=${prefix} \
              --with-flint=${prefix}/deps/FLINT_jll \
              --with-gmp=${prefix}/deps/GMP_jll \
              --with-mpfr=${prefix}/deps/MPFR_jll \
              --with-ppl=${prefix}/deps/PPL_jll \
              --with-bliss=${prefix}/deps/bliss_jll \
              --with-boost=${prefix}/deps/boost_jll \
              --with-cdd=${prefix}/deps/cddlib_jll \
              --with-lrs=${prefix}/deps/lrslib_jll \
              --with-libnormaliz=${prefix}/deps/normaliz_jll \
              --without-singular \
              --without-native \
              --without-prereq
fi

# C++ templates to need quite a lot of memory during compilation...
(( nproc=1+nproc/3 ))

ninja -v -C build/Opt -j${nproc}

ninja -v -C build/Opt install

# remove target and sysroot
sed -i -e "s#--sysroot[ =]\S\+##g" ${libdir}/polymake/config.ninja
sed -i -e "s#-target[ =]\S\+##g" ${libdir}/polymake/config.ninja

# copy of build config that has prefix as a variable
sed -e "s#${prefix}#\${prefix}#g" ${libdir}/polymake/config.ninja > ${libdir}/polymake/config-reloc.ninja

# adjust perl path
sed -i -e "s|^#!.*perl|#!/usr/bin/env perl|g" ${bindir}/polymake*
sed -i -e "s#^PERL = .*#PERL = /usr/bin/env perl#g" ${libdir}/polymake/config*

# cleanup symlink tree
rm -rf ${prefix}/deps

# copy julia script to generate dependency-tree at load time
cp ../patches/generate_deps_tree.jl $prefix/share/polymake

install_license COPYING
"""

# These are the platforms we will build for by default, unless further
# platforms are passed in on the command line
platforms = filter!(p -> !Sys.iswindows(p) &&
                         arch(p) != "armv6l",
                    supported_platforms(;experimental=true))
platforms = expand_cxxstring_abis(platforms)

# The products that we will ensure are always built
products = [
    LibraryProduct("libpolymake", :libpolymake)
    LibraryProduct("libpolymake-apps-rt", :libpolymake_apps_rt)
    ExecutableProduct("polymake", :polymake)
    ExecutableProduct("polymake-config", Symbol("polymake_config"))
    FileProduct("share/polymake/generate_deps_tree.jl", :generate_deps_tree)
]

# Dependencies that must be installed before this package can be built
dependencies = [
    HostBuildDependency(PackageSpec(name="Perl_jll", version=v"5.34.0")),
    Dependency("CompilerSupportLibraries_jll"),
    Dependency("GMP_jll", v"6.2.0"),
    Dependency("MPFR_jll", v"4.1.1"),
    Dependency("FLINT_jll", compat = "~200.800.401"),
    Dependency("PPL_jll", compat = "~1.2.1"),
    Dependency("Perl_jll", compat = "=5.34.0"),
    Dependency("bliss_jll", compat = "~0.77.0"),
    Dependency("boost_jll", compat = "=1.76.0"),
    Dependency("cddlib_jll", compat = "~0.94.13"),
    Dependency("lrslib_jll", compat = "~0.3.3"),
    Dependency("normaliz_jll", compat = "~300.900.100"),
]

# Build the tarballs, and possibly a `build.jl` as well.
build_tarballs(ARGS, name, version, sources, script, platforms, products, dependencies;
               julia_compat="1.6",
               preferred_gcc_version=v"7")

max_stars_repo_name: sharanry/Yggdrasil

max_issues_repo_name: sharanry/Yggdrasil

max_forks_repo_name: sharanry/Yggdrasil


text:
#=AIHelp.jl --
functions which will help out the AI=#
module AIHelp
global board_max =4
function bishop(board,x::Int64,y::Int64) #Returns an array of Tuples(currentX,currentY,newX,newY) of legal coordinates to move
  #Bishop is correct
  #board_max = 9
  legalC = Array(Tuple{Int64,Int64,Int64,Int64},0)
  team = board[(x,y)][2]

  for i = 1:min(x-1,y-1)
    if !( (x-i,y-i) in keys(board))  #Empty square ahead
      push!(legalC,(x,y,x-i,y-i))
    elseif (!( get(board,(x-i,y-i),('x','x'))[2] == 'w' ) && team == 'w') || (!( get(board,(x-i,y-i),('x','x'))[2] == 'b' ) && team == 'b') #Enemy piece ahead
      push!(legalC,(x,y,x-i,y-i))
      break
    else #Friendly piece ahead
      break
    end
  end

  for i = 1:min(board_max-x,board_max-y)
    if !( (x+i,y+i) in keys(board) )
      push!(legalC,(x,y,x+i,y+i))
    elseif (!( get(board,(x+i,y+i),('x','x'))[2] == 'w' ) && team == 'w') || (!( get(board,(x+i,y+i),('x','x'))[2] == 'b' ) && team == 'b')
      push!(legalC,(x,y,x+i,y+i))
      break
    else
      break
    end
  end

  for i = 1:min(board_max-x,y-1)
    if !( (x+i,y-i) in keys(board) )
      push!(legalC,(x,y,x+i,y-i))
    elseif (!( get(board,(x+i,y-i),('x','x'))[2] == 'w' ) && team == 'w') || (!( get(board,(x+i,y-i),('x','x'))[2] == 'b' ) && team == 'b')
      push!(legalC,(x,y,x+i,y-i))
      break
    else
      break
    end
  end

  for i = 1:min(x-1,board_max-y)
    if !( (x-i,y+i) in keys(board) )
      push!(legalC,(x,y,x-i,y+i))
    elseif (!( get(board,(x-i,y+i),('x','x'))[2] == 'w' ) && team == 'w') || (!( get(board,(x-i,y+i),('x','x'))[2] == 'b' ) && team == 'b')
      push!(legalC,(x,y,x-i,y+i))
      break
    else
      break
    end
  end
  return legalC
end

function goldGeneral(board,x::Int64,y::Int64)
  #board_max = 9
  team = board[(x,y)][2]
  legalC = Array(Tuple{Int64,Int64,Int64,Int64},0)
  if team == 'w'
    potential=[(x,y,x,y+1),(x,y,x,y-1),(x,y,x-1,y+1),(x,y,x-1,y),(x,y,x+1,y),(x,y,x+1,y+1)]
    for i in eachindex(potential)
      if potential[i][3]<=board_max && potential[i][3]>0 && potential[i][4]<=board_max && potential[i][4]>0 #Makes sure move is not out of bounds
        if !(get(board,(potential[i][3],potential[i][4]),('x','x'))[2] == 'w') #Check that there's no friendly piece in the path
          push!(legalC,potential[i])
        end
      end
    end
  else #team == 'b'
      potential=[(x,y,x,y+1),(x,y,x,y-1),(x,y,x-1,y-1),(x,y,x-1,y),(x,y,x+1,y),(x,y,x+1,y-1)]
      for i in eachindex(potential)
        if potential[i][3]<=board_max && potential[i][3]>0 && potential[i][4]<=board_max && potential[i][4]>0 #Makes sure move is not out of bounds
          if !(get(board,(potential[i][3],potential[i][4]),('x','x'))[2] == 'b') #Check that there's no friendly piece in the path
            push!(legalC,potential[i])
          end
        end
      end
  end
  return legalC
end

function king(board,x::Int64,y::Int64)
  #board_max = 9
  team = board[(x,y)][2]
  legalC = Array(Tuple{Int64,Int64,Int64,Int64},0)
  if team == 'w'
    potential=[(x,y,x+1,y+1),(x,y,x,y-1),(x,y,x,y+1),(x,y,x-1,y),(x,y,x+1,y),(x,y,x-1,y-1),(x,y,x+1,y-1),(x,y,x-1,y+1)]
    for i in eachindex(potential)
      if potential[i][3]<=board_max && potential[i][3]>0 && potential[i][4]<=board_max && potential[i][4]>0 #Makes sure move is not out of bounds
        if !(get(board,(potential[i][3],potential[i][4]),('x','x'))[2] == 'w') #Check that there's no friendly piece in the path
          push!(legalC,potential[i])
        end
      end
    end
  else #Team == 'b'
    potential=[(x,y,x+1,y+1),(x,y,x,y-1),(x,y,x,y+1),(x,y,x-1,y),(x,y,x+1,y),(x,y,x-1,y-1),(x,y,x+1,y-1),(x,y,x-1,y+1)]
    for i in eachindex(potential)
      if potential[i][3]<=board_max && potential[i][3]>0 && potential[i][4]<=board_max && potential[i][4]>0 #Makes sure move is not out of bounds
        if !(get(board,(potential[i][3],potential[i][4]),('x','x')) == 'b') #Check that there's no friendly piece in the path
          push!(legalC,potential[i])
        end
      end
    end
  end

  return legalC
end

function lance(board,x::Int64,y::Int64)
  #board_max = 9
  team = board[(x,y)][2]
  legalC = Array(Tuple{Int64,Int64,Int64,Int64},0)
  if team == 'w'
    for i = 1:(board_max-y-1)
      if !( (x,y+i) in keys(board) ) #Empty square ahead
        push!(legalC,(x,y,x,y+i))
      elseif (!(get(board,(x,y+i),('x','x'))[2] == 'w' ) && team == 'w') || (!( get(board,(x,y+i),('x','x'))[2] == 'b' ) && team == 'b') #Enemy piece ahead
        push!(legalC,(x,y,x,y+i))
        break
      else #Friendly piece ahead
        break
      end
    end
  else #team == 'b'
    for i = 1:y-1
      if !( (x,y-i) in keys(board) ) #Empty square ahead
        push!(legalC,(x,y,x,y-i))
      elseif (!( get(board,(x,y-i),('x','x'))[2] == 'w' ) && team == 'w') || (!( get(board,(x,y-i),('x','x'))[2] == 'b' ) && team == 'b') #Enemy piece ahead
        push!(legalC,(x,y,x,y-i))
        break
      else #Friendly piece ahead
        break
      end
    end
  end
  return legalC
end
function knight(board,x::Int64,y::Int64)
  #board_max = 9
  team = board[(x,y)][2]
  legalC = Array(Tuple{Int64,Int64,Int64,Int64},0)
  if team == 'w'
    potential=[(x,y,x+1,y+2),(x,y,x-1,y+2)]
    for i in eachindex(potential)
      if potential[i][3]<=board_max && potential[i][3]>0 && potential[i][4]<=board_max && potential[i][4]>0 #Makes sure move is not out of bounds
        if !(get(board,(potential[i][3],potential[i][4]),('x','x'))[2] == 'w') #Check that there's no friendly piece in the path
          push!(legalC,potential[i])
        end
      end
    end
  else #team == 'b'
      potential=[(x,y,x+1,y-2),(x,y,x-1,y-2)]
      for i in eachindex(potential)
        if potential[i][3]<=board_max && potential[i][3]>0 && potential[i][4]<=board_max && potential[i][4]>0 #Makes sure move is not out of bounds
          if !(get(board,(potential[i][3],potential[i][4]),('x','x'))[2] == 'b') #Check that there's no friendly piece in the path
            push!(legalC,potential[i])
          end
        end
      end
  end
  return legalC
end

function pawn(board,x::Int64,y::Int64)
  team = board[(x,y)][2]
  legalC = Array(Tuple{Int64,Int64,Int64,Int64},0)
  if team == 'w' && !( get(board,(x,y+1),('x','x'))[2] == 'w')
    push!(legalC,(x,y,x,y+1))
  elseif team == 'b' && !( get(board,(x,y-1),('x','x'))[2] == 'b')
    push!(legalC,(x,y,x,y-1))
  end
  return legalC
end

function rook(board,x::Int64,y::Int64)
  #board_max = 9
  legalC = Array(Tuple{Int64,Int64,Int64,Int64},0)
  team = board[(x,y)][2]

  for i = 1:(y-1)
    if !( (x,y-i) in keys(board) ) #Empty square ahead
      push!(legalC,(x,y,x,y-i))
    elseif (!(get(board,(x,y-1),('x','x'))[2] == 'w') && team == 'w') || (!(get(board,(x,y-1),('x','x'))[2] == 'b') && team == 'b') #Enemy piece ahead
      push!(legalC,(x,y,x,y-i))
      break
    else #Friendly piece ahead
      break
    end
  end

  for i = 1:(board_max-x)
    if !( (x+i,y) in keys(board) )
      push!(legalC,(x,y,x+i,y))
    elseif (!(get(board,(x,y+i),('x','x'))[2] == 'w') && team == 'w') || (!(get(board,(x,y+i),('x','x'))[2] == 'b') && team == 'b')
      push!(legalC,(x,y,x+i,y))
      break
    else
      break
    end
  end

  for i = 1:(x-1)
    if !( (x-i,y) in keys(board) )
      push!(legalC,(x,y,x-i,y))
    elseif (!(get(board,(x-i,y),('x','x'))[2] == 'w') && team == 'w') || (!(get(board,(x-i,y),('x','x'))[2] == 'b') && team == 'b')
      push!(legalC,(x,y,x-i,y))
      break
    else
      break
    end
  end

  for i = 1:(board_max-y)
    if !( (x,y+i) in keys(board) )
      push!(legalC,(x,y,x,y+i))
    elseif (!(get(board,(x,y+i),('x','x'))[2] == 'w') && team == 'w') || (!(get(board,(x,y+i),('x','x'))[2] == 'b') && team == 'b')
      push!(legalC,(x,y,x,y+i))
      break
    else
      break
    end
  end

  return legalC
end
function silverGeneral(board,x::Int64,y::Int64)
  #board_max = 9
  team = board[(x,y)][2]
  legalC = Array(Tuple{Int64,Int64,Int64,Int64},0)
  if team == 'w'
    potential=[(x,y,x,y+1),(x,y,x+1,y-1),(x,y,x-1,y+1),(x,y,x-1,y-1),(x,y,x+1,y+1)]
    for i in eachindex(potential)
      if potential[i][3]<=board_max && potential[i][3]>0 && potential[i][4]<=board_max && potential[i][4]>0 #Makes sure move is not out of bounds
        if !( get(board,(potential[i][3],potential[i][4]),('x','x'))[2] == 'w' ) #Check that there's no friendly piece in the path
          push!(legalC,potential[i])
        end
      end
    end
  else #team == 'b'
      potential=[(x,y,x,y-1),(x,y,x-1,y-1),(x,y,x-1,y+1),(x,y,x+1,y+1),(x,y,x+1,y-1)]
      for i in eachindex(potential)
        if potential[i][3]<=board_max && potential[i][3]>0 && potential[i][4]<=board_max && potential[i][4]>0 #Makes sure move is not out of bounds
          if !( get(board,(potential[i][3],potential[i][4]),('x','x'))[2] == 'b' ) #Check that there's no friendly piece in the path
            push!(legalC,potential[i])
          end
        end
      end
  end
  return legalC
end

function reverseChariot(board,x::Int64,y::Int64)
  #board_max = 9
  team = board[(x,y)][2]
  legalC = Array(Tuple{Int64,Int64,Int64,Int64},0)

  for i = 1:(y-1)
    if !( (x,y-i) in keys(board) ) #Empty square ahead
      push!(legalC,(x,y,x,y-i))
    elseif (!(get(board,(x,y-1),('x','x'))[2] == 'w') && team == 'w') || (!(get(board,(x,y-1),('x','x'))[2] == 'b') && team == 'b') #Enemy piece ahead
      push!(legalC,(x,y,x,y-i))
      break
    else #Friendly piece ahead
      break
    end
  end

  for i = 1:(board_max-y)
    if !( (x,y+i) in keys(board) )
      push!(legalC,(x,y,x,y+i))
    elseif (!(get(board,(x,y+i),('x','x'))[2] == 'w') && team == 'w') || (!(get(board,(x,y+i),('x','x'))[2] == 'b') && team == 'b')
      push!(legalC,(x,y,x,y+i))
      break
    else
      break
    end
  end

  return legalC
end
function copperGeneral(board,x::Int64,y::Int64)
  #board_max = 9
  team = board[(x,y)][2]
  legalC = Array(Tuple{Int64,Int64,Int64,Int64},0)
  if team == 'w'
    potential=[(x,y,x,y+1),(x,y,x,y-1),(x,y,x-1,y+1),(x,y,x+1,y+1)]
    for i in eachindex(potential)
      if potential[i][3]<=board_max && potential[i][3]>0 && potential[i][4]<=board_max && potential[i][4]>0 #Makes sure move is not out of bounds
        if !(get(board,(potential[i][3],potential[i][4]),('x','x'))[2] == 'w') #Check that there's no friendly piece in the path
          push!(legalC,potential[i])
        end
      end
    end
  else #team == 'b'
      potential=[(x,y,x,y+1),(x,y,x,y-1),(x,y,x-1,y-1),(x,y,x+1,y-1)]
      for i in eachindex(potential)
        if potential[i][3]<=board_max && potential[i][3]>0 && potential[i][4]<=board_max && potential[i][4]>0 #Makes sure move is not out of bounds
          if !(get(board,(potential[i][3],potential[i][4]),('x','x'))[2] == 'b') #Check that there's no friendly piece in the path
            push!(legalC,potential[i])
          end
        end
      end
  end
  return legalC
end
function dragonKing(board,x::Int64,y::Int64)
  #board_max = 9
  legalC = Array(Tuple{Int64,Int64,Int64,Int64},0)
  team = board[(x,y)][2]

  for i = 1:(y-1)
    if !( (x,y-i) in keys(board) ) #Empty square ahead
      push!(legalC,(x,y,x,y-i))
    elseif (!(get(board,(x,y-1),('x','x'))[2] == 'w') && team == 'w') || (!(get(board,(x,y-1),('x','x'))[2] == 'b') && team == 'b') #Enemy piece ahead
      push!(legalC,(x,y,x,y-i))
      break
    else #Friendly piece ahead
      break
    end
  end

  for i = 1:(board_max-x)
    if !( (x+i,y) in keys(board) )
      push!(legalC,(x,y,x+i,y))
    elseif (!(get(board,(x,y+i),('x','x'))[2] == 'w') && team == 'w') || (!(get(board,(x,y+i),('x','x'))[2] == 'b') && team == 'b')
      push!(legalC,(x,y,x+i,y))
      break
    else
      break
    end
  end

  for i = 1:(x-1)
    if !( (x-i,y) in keys(board) )
      push!(legalC,(x,y,x-i,y))
    elseif (!(get(board,(x-i,y),('x','x'))[2] == 'w') && team == 'w') || (!(get(board,(x-i,y),('x','x'))[2] == 'b') && team == 'b')
      push!(legalC,(x,y,x-i,y))
      break
    else
      break
    end
  end

  for i = 1:(board_max-y)
    if !( (x,y+i) in keys(board) )
      push!(legalC,(x,y,x,y+i))
    elseif (!(get(board,(x,y+i),('x','x'))[2] == 'w') && team == 'w') || (!(get(board,(x,y+i),('x','x'))[2] == 'b') && team == 'b')
      push!(legalC,(x,y,x,y+i))
      break
    else
      break
    end
  end

  if team == 'w'
    potential=[(x,y,x+1,y+1),(x,y,x-1,y-1),(x,y,x+1,y-1),(x,y,x-1,y+1)]
    for i in eachindex(potential)
      if potential[i][3]<=board_max && potential[i][3]>0 && potential[i][4]<=board_max && potential[i][4]>0 #Makes sure move is not out of bounds
        if !(get(board,(potential[i][3],potential[i][4]),('x','x'))[2] == 'w') #Check that there's no friendly piece in the path
          push!(legalC,potential[i])
        end
      end
    end
  else #Team == 'b'
    potential=[(x,y,x+1,y+1),(x,y,x-1,y-1),(x,y,x+1,y-1),(x,y,x-1,y+1)]
    for i in eachindex(potential)
      if potential[i][3]<=board_max && potential[i][3]>0 && potential[i][4]<=board_max && potential[i][4]>0 #Makes sure move is not out of bounds
        if !(get(board,(potential[i][3],potential[i][4]),('x','x')) == 'b') #Check that there's no friendly piece in the path
          push!(legalC,potential[i])
        end
      end
    end
  end

  return legalC
end
function drunkElephant(board,x::Int64,y::Int64)
  #board_max = 9
  team = board[(x,y)][2]
  legalC = Array(Tuple{Int64,Int64,Int64,Int64},0)
  if team == 'w'
    potential=[(x,y,x+1,y+1),(x,y,x,y+1),(x,y,x-1,y),(x,y,x+1,y),(x,y,x-1,y-1),(x,y,x+1,y-1),(x,y,x-1,y+1)]
    for i in eachindex(potential)
      if potential[i][3]<=board_max && potential[i][3]>0 && potential[i][4]<=board_max && potential[i][4]>0 #Makes sure move is not out of bounds
        if !(get(board,(potential[i][3],potential[i][4]),('x','x'))[2] == 'w') #Check that there's no friendly piece in the path
          push!(legalC,potential[i])
        end
      end
    end
  else #Team == 'b'
    potential=[(x,y,x+1,y+1),(x,y,x,y-1),(x,y,x-1,y),(x,y,x+1,y),(x,y,x-1,y-1),(x,y,x+1,y-1),(x,y,x-1,y+1)]
    for i in eachindex(potential)
      if potential[i][3]<=board_max && potential[i][3]>0 && potential[i][4]<=board_max && potential[i][4]>0 #Makes sure move is not out of bounds
        if !(get(board,(potential[i][3],potential[i][4]),('x','x')) == 'b') #Check that there's no friendly piece in the path
          push!(legalC,potential[i])
        end
      end
    end
  end

  return legalC
end
function ferociousLeopard(board,x::Int64,y::Int64)
  #board_max = 9
  team = board[(x,y)][2]
  legalC = Array(Tuple{Int64,Int64,Int64,Int64},0)
  if team == 'w'
    potential=[(x,y,x+1,y+1),(x,y,x,y-1),(x,y,x,y+1),(x,y,x-1,y-1),(x,y,x+1,y-1),(x,y,x-1,y+1)]
    for i in eachindex(potential)
      if potential[i][3]<=board_max && potential[i][3]>0 && potential[i][4]<=board_max && potential[i][4]>0 #Makes sure move is not out of bounds
        if !(get(board,(potential[i][3],potential[i][4]),('x','x'))[2] == 'w') #Check that there's no friendly piece in the path
          push!(legalC,potential[i])
        end
      end
    end
  else #Team == 'b'
    potential=[(x,y,x+1,y+1),(x,y,x,y-1),(x,y,x,y+1),(x,y,x-1,y-1),(x,y,x+1,y-1),(x,y,x-1,y+1)]
    for i in eachindex(potential)
      if potential[i][3]<=board_max && potential[i][3]>0 && potential[i][4]<=board_max && potential[i][4]>0 #Makes sure move is not out of bounds
        if !(get(board,(potential[i][3],potential[i][4]),('x','x')) == 'b') #Check that there's no friendly piece in the path
          push!(legalC,potential[i])
        end
      end
    end
  end

  return legalC
end
function dragonHorse(board,x::Int64,y::Int64)
  #board_max = 9
  legalC = Array(Tuple{Int64,Int64,Int64,Int64},0)
  team = board[(x,y)][2]

  for i = 1:min(x-1,y-1)
    if !( (x-i,y-i) in keys(board))  #Empty square ahead
      push!(legalC,(x,y,x-i,y-i))
    elseif (!( get(board,(x-i,y-i),('x','x'))[2] == 'w' ) && team == 'w') || (!( get(board,(x-i,y-i),('x','x'))[2] == 'b' ) && team == 'b') #Enemy piece ahead
      push!(legalC,(x,y,x-i,y-i))
      break
    else #Friendly piece ahead
      break
    end
  end

  for i = 1:min(board_max-x,board_max-y)
    if !( (x+i,y+i) in keys(board) )
      push!(legalC,(x,y,x+i,y+i))
    elseif (!( get(board,(x+i,y+i),('x','x'))[2] == 'w' ) && team == 'w') || (!( get(board,(x+i,y+i),('x','x'))[2] == 'b' ) && team == 'b')
      push!(legalC,(x,y,x+i,y+i))
      break
    else
      break
    end
  end

  for i = 1:min(board_max-x,y-1)
    if !( (x+i,y-i) in keys(board) )
      push!(legalC,(x,y,x+i,y-i))
    elseif (!( get(board,(x+i,y-i),('x','x'))[2] == 'w' ) && team == 'w') || (!( get(board,(x+i,y-i),('x','x'))[2] == 'b' ) && team == 'b')
      push!(legalC,(x,y,x+i,y-i))
      break
    else
      break
    end
  end

  for i = 1:min(x-1,board_max-y)
    if !( (x-i,y+i) in keys(board) )
      push!(legalC,(x,y,x-i,y+i))
    elseif (!( get(board,(x-i,y+i),('x','x'))[2] == 'w' ) && team == 'w') || (!( get(board,(x-i,y+i),('x','x'))[2] == 'b' ) && team == 'b')
      push!(legalC,(x,y,x-i,y+i))
      break
    else
      break
    end
  end

  if team == 'w'
    potential=[(x,y,x,y-1),(x,y,x,y+1),(x,y,x-1,y),(x,y,x+1,y)]
    for i in eachindex(potential)
      if potential[i][3]<=board_max && potential[i][3]>0 && potential[i][4]<=board_max && potential[i][4]>0 #Makes sure move is not out of bounds
        if !(get(board,(potential[i][3],potential[i][4]),('x','x'))[2] == 'w') #Check that there's no friendly piece in the path
          push!(legalC,potential[i])
        end
      end
    end
  else #Team == 'b'
    potential=[(x,y,x,y-1),(x,y,x,y+1),(x,y,x-1,y),(x,y,x+1,y)]
    for i in eachindex(potential)
      if potential[i][3]<=board_max && potential[i][3]>0 && potential[i][4]<=board_max && potential[i][4]>0 #Makes sure move is not out of bounds
        if !(get(board,(potential[i][3],potential[i][4]),('x','x')) == 'b') #Check that there's no friendly piece in the path
          push!(legalC,potential[i])
        end
      end
    end
  end

  return legalC
end
function lion(board,x::Int64,y::Int64)
end
function kirin(board,x::Int64,y::Int64)
  #board_max = 9
  team = board[(x,y)][2]
  legalC = Array(Tuple{Int64,Int64,Int64,Int64},0)
  if team == 'w'
    potential=[(x,y,x+1,y+1),(x,y,x,y-2),(x,y,x,y+2),(x,y,x-2,y),(x,y,x+2,y),(x,y,x-1,y-1),(x,y,x+1,y-1),(x,y,x-1,y+1)]
    for i in eachindex(potential)
      if potential[i][3]<=board_max && potential[i][3]>0 && potential[i][4]<=board_max && potential[i][4]>0 #Makes sure move is not out of bounds
        if !(get(board,(potential[i][3],potential[i][4]),('x','x'))[2] == 'w') #Check that there's no friendly piece in the path
          push!(legalC,potential[i])
        end
      end
    end
  else #Team == 'b'
    potential=[(x,y,x+1,y+1),(x,y,x,y-2),(x,y,x,y+2),(x,y,x-2,y),(x,y,x+2,y),(x,y,x-1,y-1),(x,y,x+1,y-1),(x,y,x-1,y+1)]
    for i in eachindex(potential)
      if potential[i][3]<=board_max && potential[i][3]>0 && potential[i][4]<=board_max && potential[i][4]>0 #Makes sure move is not out of bounds
        if !(get(board,(potential[i][3],potential[i][4]),('x','x')) == 'b') #Check that there's no friendly piece in the path
          push!(legalC,potential[i])
        end
      end
    end
  end

  return legalC
end
function sideMover(board,x::Int64,y::Int64)
  #board_max = 9
  legalC = Array(Tuple{Int64,Int64,Int64,Int64},0)
  team = board[(x,y)][2]

  for i = 1:(board_max-x)
    if !( (x+i,y) in keys(board) )
      push!(legalC,(x,y,x+i,y))
    elseif (!(get(board,(x,y+i),('x','x'))[2] == 'w') && team == 'w') || (!(get(board,(x,y+i),('x','x'))[2] == 'b') && team == 'b')
      push!(legalC,(x,y,x+i,y))
      break
    else
      break
    end
  end

  for i = 1:(x-1)
    if !( (x-i,y) in keys(board) )
      push!(legalC,(x,y,x-i,y))
    elseif (!(get(board,(x-i,y),('x','x'))[2] == 'w') && team == 'w') || (!(get(board,(x-i,y),('x','x'))[2] == 'b') && team == 'b')
      push!(legalC,(x,y,x-i,y))
      break
    else
      break
    end
  end

  if team == 'w'
    potential=[(x,y,x,y-1),(x,y,x,y+1)]
    for i in eachindex(potential)
      if potential[i][3]<=board_max && potential[i][3]>0 && potential[i][4]<=board_max && potential[i][4]>0 #Makes sure move is not out of bounds
        if !(get(board,(potential[i][3],potential[i][4]),('x','x'))[2] == 'w') #Check that there's no friendly piece in the path
          push!(legalC,potential[i])
        end
      end
    end
  else #Team == 'b'
    potential=[(x,y,x,y-1),(x,y,x,y+1)]
    for i in eachindex(potential)
      if potential[i][3]<=board_max && potential[i][3]>0 && potential[i][4]<=board_max && potential[i][4]>0 #Makes sure move is not out of bounds
        if !(get(board,(potential[i][3],potential[i][4]),('x','x')) == 'b') #Check that there's no friendly piece in the path
          push!(legalC,potential[i])
        end
      end
    end
  end
  return legalC

end
function goBetween(board,x::Int64,y::Int64)
  #board_max = 9
  legalC = Array(Tuple{Int64,Int64,Int64,Int64},0)
  team = board[(x,y)][2]
  if team == 'w'
    potential=[(x,y,x,y-1),(x,y,x,y+1)]
    for i in eachindex(potential)
      if potential[i][3]<=board_max && potential[i][3]>0 && potential[i][4]<=board_max && potential[i][4]>0 #Makes sure move is not out of bounds
        if !(get(board,(potential[i][3],potential[i][4]),('x','x'))[2] == 'w') #Check that there's no friendly piece in the path
          push!(legalC,potential[i])
        end
      end
    end
  else #Team == 'b'
    potential=[(x,y,x,y-1),(x,y,x,y+1)]
    for i in eachindex(potential)
      if potential[i][3]<=board_max && potential[i][3]>0 && potential[i][4]<=board_max && potential[i][4]>0 #Makes sure move is not out of bounds
        if !(get(board,(potential[i][3],potential[i][4]),('x','x')) == 'b') #Check that there's no friendly piece in the path
          push!(legalC,potential[i])
        end
      end
    end
  end
  return legalC
end
function blindTiger(board,x::Int64,y::Int64)
  #board_max = 9
  team = board[(x,y)][2]
  legalC = Array(Tuple{Int64,Int64,Int64,Int64},0)
  if team == 'w'
    potential=[(x,y,x+1,y+1),(x,y,x,y-1),(x,y,x-1,y),(x,y,x+1,y),(x,y,x-1,y-1),(x,y,x+1,y-1),(x,y,x-1,y+1)]
    for i in eachindex(potential)
      if potential[i][3]<=board_max && potential[i][3]>0 && potential[i][4]<=board_max && potential[i][4]>0 #Makes sure move is not out of bounds
        if !(get(board,(potential[i][3],potential[i][4]),('x','x'))[2] == 'w') #Check that there's no friendly piece in the path
          push!(legalC,potential[i])
        end
      end
    end
  else #Team == 'b'
    potential=[(x,y,x+1,y+1),(x,y,x,y+1),(x,y,x-1,y),(x,y,x+1,y),(x,y,x-1,y-1),(x,y,x+1,y-1),(x,y,x-1,y+1)]
    for i in eachindex(potential)
      if potential[i][3]<=board_max && potential[i][3]>0 && potential[i][4]<=board_max && potential[i][4]>0 #Makes sure move is not out of bounds
        if !(get(board,(potential[i][3],potential[i][4]),('x','x')) == 'b') #Check that there's no friendly piece in the path
          push!(legalC,potential[i])
        end
      end
    end
  end

  return legalC
end
function queen(board,x::Int64,y::Int64)
  #board_max = 9
  legalC = Array(Tuple{Int64,Int64,Int64,Int64},0)
  team = board[(x,y)][2]

  for i = 1:min(x-1,y-1)
    if !( (x-i,y-i) in keys(board))  #Empty square ahead
      push!(legalC,(x,y,x-i,y-i))
    elseif (!( get(board,(x-i,y-i),('x','x'))[2] == 'w' ) && team == 'w') || (!( get(board,(x-i,y-i),('x','x'))[2] == 'b' ) && team == 'b') #Enemy piece ahead
      push!(legalC,(x,y,x-i,y-i))
      break
    else #Friendly piece ahead
      break
    end
  end

  for i = 1:min(board_max-x,board_max-y)
    if !( (x+i,y+i) in keys(board) )
      push!(legalC,(x,y,x+i,y+i))
    elseif (!( get(board,(x+i,y+i),('x','x'))[2] == 'w' ) && team == 'w') || (!( get(board,(x+i,y+i),('x','x'))[2] == 'b' ) && team == 'b')
      push!(legalC,(x,y,x+i,y+i))
      break
    else
      break
    end
  end

  for i = 1:min(board_max-x,y-1)
    if !( (x+i,y-i) in keys(board) )
      push!(legalC,(x,y,x+i,y-i))
    elseif (!( get(board,(x+i,y-i),('x','x'))[2] == 'w' ) && team == 'w') || (!( get(board,(x+i,y-i),('x','x'))[2] == 'b' ) && team == 'b')
      push!(legalC,(x,y,x+i,y-i))
      break
    else
      break
    end
  end

  for i = 1:min(x-1,board_max-y)
    if !( (x-i,y+i) in keys(board) )
      push!(legalC,(x,y,x-i,y+i))
    elseif (!( get(board,(x-i,y+i),('x','x'))[2] == 'w' ) && team == 'w') || (!( get(board,(x-i,y+i),('x','x'))[2] == 'b' ) && team == 'b')
      push!(legalC,(x,y,x-i,y+i))
      break
    else
      break
    end
  end

    for i = 1:(y-1)
      if !( (x,y-i) in keys(board) ) #Empty square ahead
        push!(legalC,(x,y,x,y-i))
      elseif (!(get(board,(x,y-1),('x','x'))[2] == 'w') && team == 'w') || (!(get(board,(x,y-1),('x','x'))[2] == 'b') && team == 'b') #Enemy piece ahead
        push!(legalC,(x,y,x,y-i))
        break
      else #Friendly piece ahead
        break
      end
    end

    for i = 1:(board_max-x)
      if !( (x+i,y) in keys(board) )
        push!(legalC,(x,y,x+i,y))
      elseif (!(get(board,(x,y+i),('x','x'))[2] == 'w') && team == 'w') || (!(get(board,(x,y+i),('x','x'))[2] == 'b') && team == 'b')
        push!(legalC,(x,y,x+i,y))
        break
      else
        break
      end
    end

    for i = 1:(x-1)
      if !( (x-i,y) in keys(board) )
        push!(legalC,(x,y,x-i,y))
      elseif (!(get(board,(x-i,y),('x','x'))[2] == 'w') && team == 'w') || (!(get(board,(x-i,y),('x','x'))[2] == 'b') && team == 'b')
        push!(legalC,(x,y,x-i,y))
        break
      else
        break
      end
    end

    for i = 1:(board_max-y)
      if !( (x,y+i) in keys(board) )
        push!(legalC,(x,y,x,y+i))
      elseif (!(get(board,(x,y+i),('x','x'))[2] == 'w') && team == 'w') || (!(get(board,(x,y+i),('x','x'))[2] == 'b') && team == 'b')
        push!(legalC,(x,y,x,y+i))
        break
      else
        break
      end
    end

    return legalC
end
function verticalMover(board,x::Int64,y::Int64)
  #board_max = 9
  legalC = Array(Tuple{Int64,Int64,Int64,Int64},0)
  team = board[(x,y)][2]

  for i = 1:(y-1)
    if !( (x,y-i) in keys(board) ) #Empty square ahead
      push!(legalC,(x,y,x,y-i))
    elseif (!(get(board,(x,y-1),('x','x'))[2] == 'w') && team == 'w') || (!(get(board,(x,y-1),('x','x'))[2] == 'b') && team == 'b') #Enemy piece ahead
      push!(legalC,(x,y,x,y-i))
      break
    else #Friendly piece ahead
      break
    end
  end

  for i = 1:(board_max-y)
    if !( (x,y+i) in keys(board) )
      push!(legalC,(x,y,x,y+i))
    elseif (!(get(board,(x,y+i),('x','x'))[2] == 'w') && team == 'w') || (!(get(board,(x,y+i),('x','x'))[2] == 'b') && team == 'b')
      push!(legalC,(x,y,x,y+i))
      break
    else
      break
    end
  end
  if team == 'w'
    potential=[(x,y,x-1,y),(x,y,x+1,y)]
    for i in eachindex(potential)
      if potential[i][3]<=board_max && potential[i][3]>0 && potential[i][4]<=board_max && potential[i][4]>0 #Makes sure move is not out of bounds
        if !(get(board,(potential[i][3],potential[i][4]),('x','x'))[2] == 'w') #Check that there's no friendly piece in the path
          push!(legalC,potential[i])
        end
      end
    end
  else #Team == 'b'
    potential=[(x,y,x-1,y),(x,y,x+1,y)]
    for i in eachindex(potential)
      if potential[i][3]<=board_max && potential[i][3]>0 && potential[i][4]<=board_max && potential[i][4]>0 #Makes sure move is not out of bounds
        if !(get(board,(potential[i][3],potential[i][4]),('x','x')) == 'b') #Check that there's no friendly piece in the path
          push!(legalC,potential[i])
        end
      end
    end
  end
  return legalC
end
function phoenix(board,x::Int64,y::Int64)
  #board_max = 9
  team = board[(x,y)][2]
  legalC = Array(Tuple{Int64,Int64,Int64,Int64},0)
  if team == 'w'
    potential=[(x,y,x+2,y+2),(x,y,x,y-1),(x,y,x,y+1),(x,y,x-1,y),(x,y,x+1,y),(x,y,x-2,y-2),(x,y,x+2,y-2),(x,y,x-2,y+2)]
    for i in eachindex(potential)
      if potential[i][3]<=board_max && potential[i][3]>0 && potential[i][4]<=board_max && potential[i][4]>0 #Makes sure move is not out of bounds
        if !(get(board,(potential[i][3],potential[i][4]),("x",'x'))[2] == 'w') #Check that there's no friendly piece in the path
          push!(legalC,potential[i])
        end
      end
    end
  else #Team == 'b'
    potential=[(x,y,x+2,y+2),(x,y,x,y-1),(x,y,x,y+1),(x,y,x-1,y),(x,y,x+1,y),(x,y,x-2,y-2),(x,y,x+2,y-2),(x,y,x-2,y+2)]
    for i in eachindex(potential)
      if potential[i][3]<=board_max && potential[i][3]>0 && potential[i][4]<=board_max && potential[i][4]>0 #Makes sure move is not out of bounds
        if !(get(board,(potential[i][3],potential[i][4]),('x','x')) == 'b') #Check that there's no friendly piece in the path
          push!(legalC,potential[i])
        end
      end
    end
  end

  return legalC
end

function legalMoves(board,x,y)
  target = board[(x,y)]
  unit = target[1]
#  println("$unit at $x , $y")
  funDict = Dict("bishop" => bishop, "gold general" => goldGeneral, "king" => king, "lance" => lance, "knight" => knight, "pawn" => pawn, "rook" => rook, "silver general" => silverGeneral,
  "phoenix" => phoenix, "vertical mover" => verticalMover, "go-between" => goBetween, "queen" => queen, "lion" => lion, "dragon king" => dragonKing, "dragon horse"=> dragonHorse, "side mover" => sideMover,
  "kirin" => kirin, "blind tiger"=> blindTiger, "reverse chariot" => reverseChariot, "drunk elephant" => drunkElephant, "ferocious leopard" => ferociousLeopard, "blind tiger" => blindTiger)
  funDict[unit](board,x,y)
end

function legalMovesPlayer(board,team,shogiType)
  board_max_dict = Dict("standard" => 9, "chu" => 12)
  global board_max = 4 #board_max_dict[shogiType]
  legalC = Array(Tuple{Int64,Int64,Int64,Int64},0) #Initialize an array of tuples for coordinates
   currentTeam = team #Define currentTeam (either 'b' or 'w)
   #board_max = 9
  #=for x in 1:board_max
    for y in 1:board_max
      if board[(x,y)][2] == currentTeam
        append!(legalC,legalMoves(board,x,y))
      end
    end
  end=#
  for (x,y) in keys(board)
    if board[(x,y)][2] == currentTeam
      append!(legalC,legalMoves(board,x,y))
    end
  end
  return legalC
end
export legalMovesPlayer
end #End module "AI"

ext: jl

max_stars_repo_name: kinoroy/Shogi

max_issues_repo_name: kinoroy/Shulia

max_forks_repo_name: kinoroy/Shulia


text:
using Pkg

include("../test/load.jl")

Pkg.activate("docs/.")

using Documenter
using DocStringExtensions

makedocs(sitename = "OCTHaGOn",
    format = Documenter.HTML(prettyurls = get(ENV, "CI", nothing) == "true"),
    modules = [OCTHaGOn],
    pages = [
        "Home" => "index.md",
        "Installation" => "installation.md",
        "Basic usage" => "basic.md",
        "API reference" => [
            "api/datastructures.md",
            "api/constraints.md",
            "api/sampling.md",
            "api/jump_utils.md",
            "api/iai_wrappers.md",
            "api/mi_approximation.md",
            "api/helpers.md"
        ]
    ]
)

# deploydocs(deps = nothing, make = nothing,
#   repo = "github.com/1ozturkbe/OCTHaGOn.jl.git",
#   target = "build",
#   push_preview = true)


text:
compute_R_star(rho_star, M_star) = cbrt(3.0 * M_star / (4.0 * π * rho_star))
compute_R_star_nom(G::Real) = 1.0
compute_R_star_nom(G) = 1.0u"Rsun"
compute_M_star(rho_star, R_star) = 4.0 * π * R_star^3 * rho_star / 3.0
compute_M_planet_nom(G::Real) = 0.0
compute_M_planet_nom(G) = 0.0u"Msun"
compute_M_tot(m1, m2) = m1 + m2
compute_M_tot(a, G, period) = 4.0 * π^2 * a^3 / (G * period^2)
compute_a(aR_star, R_star) = R_star * aR_star
compute_a(M_tot, period, G) = cbrt(G * M_tot * period^2 / (4.0 * π^2))
compute_a_X(a, m, M) = a * m / M
compute_period(M_tot, a, G) = 2.0 * π * sqrt(a^3 / (G * M_tot))
compute_rho_star(M_star, R_star) = 3.0 * M_star / (4.0 * π * R_star^3)
function compute_E0(ecc, cos_omega, sin_omega)
    y = sqrt(1.0 - ecc) * cos_omega
    x = sqrt(1.0 + ecc) * (1.0 + sin_omega)
    return 2.0 * atan(y, x)
end
compute_M0(ecc, E0) = E0 - ecc * sin(E0)
compute_M(t, t0, t_ref, n) = (t - t0 - t_ref) * n

# Spherical density
compute_rho(M, R) = 0.75 * M / (π * R^3)
compute_rho(M, R::Nothing) = nothing

# Semi-major axis / star radius ratio, assuming circular orbit
function compute_aor(duration, period, b; r=nothing)
    r = isnothing(r) ? 0.0 : r
    sin_ϕ, cos_ϕ = sincos(π * duration / period)
    return sqrt((1 + r)^2 - (b * cos_ϕ)^2) / sin_ϕ
end

# Impact radius
function compute_b(a_planet, R_star, duration, period, incl_factor_inv, ecc, sin_omega)
    c = sin(π * duration / (period * incl_factor_inv))
    c_sq = c^2
    ecc_sin_omega = ecc*sin_omega
    aor = a_planet / R_star
    num = aor^2 * c_sq - 1.0
    den = c_sq * ecc_sin_omega^2 + 2.0 * c_sq * ecc_sin_omega + c_sq - ecc^4 + 2.0 * ecc^2 - 1.0
    return sqrt(num / den) * (1.0 - ecc) * (1.0 + ecc)
end
compute_b(cos_incl, dcosi_db) = cos_incl / dcosi_db

# Inclination factor
compute_incl_factor_inv(ecc, sin_omega) = (1.0 - ecc) * (1.0 + ecc) / (1.0 + ecc * sin_omega)

# Jacobian for cos(i) -> b
compute_dcosi_db(a, R_star, incl_factor_inv) = R_star / (a * incl_factor_inv)

# Planet radius
compute_R_planet(R_star, r, R_planet) = R_planet
compute_R_planet(R_star, r, R_planet::Nothing) = iszero(r) ? zero(R_star) : R_star * r

# Transit times
compute_t0_tp(t0::Nothing, tp; M0, n) = (tp + M0 / n, tp)
compute_t0_tp(t0, tp::Nothing; M0, n) = (t0, t0 - M0 / n)
compute_t0_tp(t0::Nothing, tp::Nothing; kwargs...) = throw(ArgumentError("Please specify either `t0` or `tp`"))
compute_t0_tp(t0, tp; kwargs...) = throw(ArgumentError("Please only specify one of `t0` or `tp`"))


text:
# Julia wrapper for header: Coin_C_defines.h
# Automatically generated using Clang.jl

# Julia wrapper for header: Clp_C_Interface.h
# Automatically generated using Clang.jl

function Clp_Version()
    ccall((:Clp_Version, libClp), Cstring, ())
end

function Clp_VersionMajor()
    ccall((:Clp_VersionMajor, libClp), Cint, ())
end

function Clp_VersionMinor()
    ccall((:Clp_VersionMinor, libClp), Cint, ())
end

function Clp_VersionRelease()
    ccall((:Clp_VersionRelease, libClp), Cint, ())
end

function Clp_newModel()
    ccall((:Clp_newModel, libClp), Ptr{Clp_Simplex}, ())
end

function Clp_deleteModel(model)
    ccall((:Clp_deleteModel, libClp), Cvoid, (Ptr{Clp_Simplex},), model)
end

function ClpSolve_new()
    ccall((:ClpSolve_new, libClp), Ptr{Clp_Solve}, ())
end

function ClpSolve_delete(solve)
    ccall((:ClpSolve_delete, libClp), Cvoid, (Ptr{Clp_Solve},), solve)
end

function Clp_loadProblem(model, numcols, numrows, start, index, value, collb, colub, obj, rowlb, rowub)
    ccall((:Clp_loadProblem, libClp), Cvoid, (Ptr{Clp_Simplex}, Cint, Cint, Ptr{CoinBigIndex}, Ptr{Cint}, Ptr{Cdouble}, Ptr{Cdouble}, Ptr{Cdouble}, Ptr{Cdouble}, Ptr{Cdouble}, Ptr{Cdouble}), model, numcols, numrows, start, index, value, collb, colub, obj, rowlb, rowub)
end

function Clp_loadQuadraticObjective(model, numberColumns, start, column, element)
    ccall((:Clp_loadQuadraticObjective, libClp), Cvoid, (Ptr{Clp_Simplex}, Cint, Ptr{CoinBigIndex}, Ptr{Cint}, Ptr{Cdouble}), model, numberColumns, start, column, element)
end

function Clp_readMps(model, filename, keepNames, ignoreErrors)
    ccall((:Clp_readMps, libClp), Cint, (Ptr{Clp_Simplex}, Cstring, Cint, Cint), model, filename, keepNames, ignoreErrors)
end

function Clp_writeMps(model, filename, formatType, numberAcross, objSense)
    ccall((:Clp_writeMps, libClp), Cint, (Ptr{Clp_Simplex}, Cstring, Cint, Cint, Cdouble), model, filename, formatType, numberAcross, objSense)
end

function Clp_copyInIntegerInformation(model, information)
    ccall((:Clp_copyInIntegerInformation, libClp), Cvoid, (Ptr{Clp_Simplex}, Cstring), model, information)
end

function Clp_deleteIntegerInformation(model)
    ccall((:Clp_deleteIntegerInformation, libClp), Cvoid, (Ptr{Clp_Simplex},), model)
end

function Clp_resize(model, newNumberRows, newNumberColumns)
    ccall((:Clp_resize, libClp), Cvoid, (Ptr{Clp_Simplex}, Cint, Cint), model, newNumberRows, newNumberColumns)
end

function Clp_deleteRows(model, number, which)
    ccall((:Clp_deleteRows, libClp), Cvoid, (Ptr{Clp_Simplex}, Cint, Ptr{Cint}), model, number, which)
end

function Clp_addRows(model, number, rowLower, rowUpper, rowStarts, columns, elements)
    ccall((:Clp_addRows, libClp), Cvoid, (Ptr{Clp_Simplex}, Cint, Ptr{Cdouble}, Ptr{Cdouble}, Ptr{CoinBigIndex}, Ptr{Cint}, Ptr{Cdouble}), model, number, rowLower, rowUpper, rowStarts, columns, elements)
end

function Clp_deleteColumns(model, number, which)
    ccall((:Clp_deleteColumns, libClp), Cvoid, (Ptr{Clp_Simplex}, Cint, Ptr{Cint}), model, number, which)
end

function Clp_addColumns(model, number, columnLower, columnUpper, objective, columnStarts, rows, elements)
    ccall((:Clp_addColumns, libClp), Cvoid, (Ptr{Clp_Simplex}, Cint, Ptr{Cdouble}, Ptr{Cdouble}, Ptr{Cdouble}, Ptr{CoinBigIndex}, Ptr{Cint}, Ptr{Cdouble}), model, number, columnLower, columnUpper, objective, columnStarts, rows, elements)
end

function Clp_chgRowLower(model, rowLower)
    ccall((:Clp_chgRowLower, libClp), Cvoid, (Ptr{Clp_Simplex}, Ptr{Cdouble}), model, rowLower)
end

function Clp_chgRowUpper(model, rowUpper)
    ccall((:Clp_chgRowUpper, libClp), Cvoid, (Ptr{Clp_Simplex}, Ptr{Cdouble}), model, rowUpper)
end

function Clp_chgColumnLower(model, columnLower)
    ccall((:Clp_chgColumnLower, libClp), Cvoid, (Ptr{Clp_Simplex}, Ptr{Cdouble}), model, columnLower)
end

function Clp_chgColumnUpper(model, columnUpper)
    ccall((:Clp_chgColumnUpper, libClp), Cvoid, (Ptr{Clp_Simplex}, Ptr{Cdouble}), model, columnUpper)
end

function Clp_chgObjCoefficients(model, objIn)
    ccall((:Clp_chgObjCoefficients, libClp), Cvoid, (Ptr{Clp_Simplex}, Ptr{Cdouble}), model, objIn)
end

function Clp_modifyCoefficient(model, row, column, newElement, keepZero)
    ccall((:Clp_modifyCoefficient, libClp), Cvoid, (Ptr{Clp_Simplex}, Cint, Cint, Cdouble, Bool), model, row, column, newElement, keepZero)
end

function Clp_dropNames(model)
    ccall((:Clp_dropNames, libClp), Cvoid, (Ptr{Clp_Simplex},), model)
end

function Clp_copyNames(model, rowNames, columnNames)
    ccall((:Clp_copyNames, libClp), Cvoid, (Ptr{Clp_Simplex}, Ptr{Cstring}, Ptr{Cstring}), model, rowNames, columnNames)
end

function Clp_numberRows(model)
    ccall((:Clp_numberRows, libClp), Cint, (Ptr{Clp_Simplex},), model)
end

function Clp_numberColumns(model)
    ccall((:Clp_numberColumns, libClp), Cint, (Ptr{Clp_Simplex},), model)
end

function Clp_primalTolerance(model)
    ccall((:Clp_primalTolerance, libClp), Cdouble, (Ptr{Clp_Simplex},), model)
end

function Clp_setPrimalTolerance(model, value)
    ccall((:Clp_setPrimalTolerance, libClp), Cvoid, (Ptr{Clp_Simplex}, Cdouble), model, value)
end

function Clp_dualTolerance(model)
    ccall((:Clp_dualTolerance, libClp), Cdouble, (Ptr{Clp_Simplex},), model)
end

function Clp_setDualTolerance(model, value)
    ccall((:Clp_setDualTolerance, libClp), Cvoid, (Ptr{Clp_Simplex}, Cdouble), model, value)
end

function Clp_dualObjectiveLimit(model)
    ccall((:Clp_dualObjectiveLimit, libClp), Cdouble, (Ptr{Clp_Simplex},), model)
end

function Clp_setDualObjectiveLimit(model, value)
    ccall((:Clp_setDualObjectiveLimit, libClp), Cvoid, (Ptr{Clp_Simplex}, Cdouble), model, value)
end

function Clp_objectiveOffset(model)
    ccall((:Clp_objectiveOffset, libClp), Cdouble, (Ptr{Clp_Simplex},), model)
end

function Clp_setObjectiveOffset(model, value)
    ccall((:Clp_setObjectiveOffset, libClp), Cvoid, (Ptr{Clp_Simplex}, Cdouble), model, value)
end

function Clp_problemName(model, maxNumberCharacters, array)
    ccall((:Clp_problemName, libClp), Cvoid, (Ptr{Clp_Simplex}, Cint, Cstring), model, maxNumberCharacters, array)
end

function Clp_setProblemName(model, maxNumberCharacters, array)
    ccall((:Clp_setProblemName, libClp), Cint, (Ptr{Clp_Simplex}, Cint, Cstring), model, maxNumberCharacters, array)
end

function Clp_numberIterations(model)
    ccall((:Clp_numberIterations, libClp), Cint, (Ptr{Clp_Simplex},), model)
end

function Clp_setNumberIterations(model, numberIterations)
    ccall((:Clp_setNumberIterations, libClp), Cvoid, (Ptr{Clp_Simplex}, Cint), model, numberIterations)
end

function maximumIterations(model)
    ccall((:maximumIterations, libClp), Cint, (Ptr{Clp_Simplex},), model)
end

function Clp_setMaximumIterations(model, value)
    ccall((:Clp_setMaximumIterations, libClp), Cvoid, (Ptr{Clp_Simplex}, Cint), model, value)
end

function Clp_maximumSeconds(model)
    ccall((:Clp_maximumSeconds, libClp), Cdouble, (Ptr{Clp_Simplex},), model)
end

function Clp_setMaximumSeconds(model, value)
    ccall((:Clp_setMaximumSeconds, libClp), Cvoid, (Ptr{Clp_Simplex}, Cdouble), model, value)
end

function Clp_hitMaximumIterations(model)
    ccall((:Clp_hitMaximumIterations, libClp), Cint, (Ptr{Clp_Simplex},), model)
end

function Clp_status(model)
    ccall((:Clp_status, libClp), Cint, (Ptr{Clp_Simplex},), model)
end

function Clp_setProblemStatus(model, problemStatus)
    ccall((:Clp_setProblemStatus, libClp), Cvoid, (Ptr{Clp_Simplex}, Cint), model, problemStatus)
end

function Clp_secondaryStatus(model)
    ccall((:Clp_secondaryStatus, libClp), Cint, (Ptr{Clp_Simplex},), model)
end

function Clp_setSecondaryStatus(model, status)
    ccall((:Clp_setSecondaryStatus, libClp), Cvoid, (Ptr{Clp_Simplex}, Cint), model, status)
end

function Clp_optimizationDirection(model)
    ccall((:Clp_optimizationDirection, libClp), Cdouble, (Ptr{Clp_Simplex},), model)
end

function Clp_setOptimizationDirection(model, value)
    ccall((:Clp_setOptimizationDirection, libClp), Cvoid, (Ptr{Clp_Simplex}, Cdouble), model, value)
end

function Clp_primalRowSolution(model)
    ccall((:Clp_primalRowSolution, libClp), Ptr{Cdouble}, (Ptr{Clp_Simplex},), model)
end

function Clp_primalColumnSolution(model)
    ccall((:Clp_primalColumnSolution, libClp), Ptr{Cdouble}, (Ptr{Clp_Simplex},), model)
end

function Clp_dualRowSolution(model)
    ccall((:Clp_dualRowSolution, libClp), Ptr{Cdouble}, (Ptr{Clp_Simplex},), model)
end

function Clp_dualColumnSolution(model)
    ccall((:Clp_dualColumnSolution, libClp), Ptr{Cdouble}, (Ptr{Clp_Simplex},), model)
end

function Clp_rowLower(model)
    ccall((:Clp_rowLower, libClp), Ptr{Cdouble}, (Ptr{Clp_Simplex},), model)
end

function Clp_rowUpper(model)
    ccall((:Clp_rowUpper, libClp), Ptr{Cdouble}, (Ptr{Clp_Simplex},), model)
end

function Clp_objective(model)
    ccall((:Clp_objective, libClp), Ptr{Cdouble}, (Ptr{Clp_Simplex},), model)
end

function Clp_columnLower(model)
    ccall((:Clp_columnLower, libClp), Ptr{Cdouble}, (Ptr{Clp_Simplex},), model)
end

function Clp_columnUpper(model)
    ccall((:Clp_columnUpper, libClp), Ptr{Cdouble}, (Ptr{Clp_Simplex},), model)
end

function Clp_getNumElements(model)
    ccall((:Clp_getNumElements, libClp), CoinBigIndex, (Ptr{Clp_Simplex},), model)
end

function Clp_getVectorStarts(model)
    ccall((:Clp_getVectorStarts, libClp), Ptr{CoinBigIndex}, (Ptr{Clp_Simplex},), model)
end

function Clp_getIndices(model)
    ccall((:Clp_getIndices, libClp), Ptr{Cint}, (Ptr{Clp_Simplex},), model)
end

function Clp_getVectorLengths(model)
    ccall((:Clp_getVectorLengths, libClp), Ptr{Cint}, (Ptr{Clp_Simplex},), model)
end

function Clp_getElements(model)
    ccall((:Clp_getElements, libClp), Ptr{Cdouble}, (Ptr{Clp_Simplex},), model)
end

function Clp_objectiveValue(model)
    ccall((:Clp_objectiveValue, libClp), Cdouble, (Ptr{Clp_Simplex},), model)
end

function Clp_integerInformation(model)
    ccall((:Clp_integerInformation, libClp), Cstring, (Ptr{Clp_Simplex},), model)
end

function Clp_infeasibilityRay(model)
    ccall((:Clp_infeasibilityRay, libClp), Ptr{Cdouble}, (Ptr{Clp_Simplex},), model)
end

function Clp_unboundedRay(model)
    ccall((:Clp_unboundedRay, libClp), Ptr{Cdouble}, (Ptr{Clp_Simplex},), model)
end

function Clp_freeRay(model, ray)
    ccall((:Clp_freeRay, libClp), Cvoid, (Ptr{Clp_Simplex}, Ptr{Cdouble}), model, ray)
end

function Clp_statusExists(model)
    ccall((:Clp_statusExists, libClp), Cint, (Ptr{Clp_Simplex},), model)
end

function Clp_statusArray(model)
    ccall((:Clp_statusArray, libClp), Ptr{Cuchar}, (Ptr{Clp_Simplex},), model)
end

function Clp_copyinStatus(model, statusArray)
    ccall((:Clp_copyinStatus, libClp), Cvoid, (Ptr{Clp_Simplex}, Ptr{Cuchar}), model, statusArray)
end

function Clp_getColumnStatus(model, sequence)
    ccall((:Clp_getColumnStatus, libClp), Cint, (Ptr{Clp_Simplex}, Cint), model, sequence)
end

function Clp_getRowStatus(model, sequence)
    ccall((:Clp_getRowStatus, libClp), Cint, (Ptr{Clp_Simplex}, Cint), model, sequence)
end

function Clp_setColumnStatus(model, sequence, value)
    ccall((:Clp_setColumnStatus, libClp), Cvoid, (Ptr{Clp_Simplex}, Cint, Cint), model, sequence, value)
end

function Clp_setRowStatus(model, sequence, value)
    ccall((:Clp_setRowStatus, libClp), Cvoid, (Ptr{Clp_Simplex}, Cint, Cint), model, sequence, value)
end

function Clp_setUserPointer(model, pointer)
    ccall((:Clp_setUserPointer, libClp), Cvoid, (Ptr{Clp_Simplex}, Ptr{Cvoid}), model, pointer)
end

function Clp_getUserPointer(model)
    ccall((:Clp_getUserPointer, libClp), Ptr{Cvoid}, (Ptr{Clp_Simplex},), model)
end

function Clp_registerCallBack(model, userCallBack)
    ccall((:Clp_registerCallBack, libClp), Cvoid, (Ptr{Clp_Simplex}, clp_callback), model, userCallBack)
end

function Clp_clearCallBack(model)
    ccall((:Clp_clearCallBack, libClp), Cvoid, (Ptr{Clp_Simplex},), model)
end

function Clp_setLogLevel(model, value)
    ccall((:Clp_setLogLevel, libClp), Cvoid, (Ptr{Clp_Simplex}, Cint), model, value)
end

function Clp_logLevel(model)
    ccall((:Clp_logLevel, libClp), Cint, (Ptr{Clp_Simplex},), model)
end

function Clp_lengthNames(model)
    ccall((:Clp_lengthNames, libClp), Cint, (Ptr{Clp_Simplex},), model)
end

function Clp_rowName(model, iRow, name)
    ccall((:Clp_rowName, libClp), Cvoid, (Ptr{Clp_Simplex}, Cint, Cstring), model, iRow, name)
end

function Clp_columnName(model, iColumn, name)
    ccall((:Clp_columnName, libClp), Cvoid, (Ptr{Clp_Simplex}, Cint, Cstring), model, iColumn, name)
end

function Clp_setRowName(model, iRow, name)
    ccall((:Clp_setRowName, libClp), Cvoid, (Ptr{Clp_Simplex}, Cint, Cstring), model, iRow, name)
end

function Clp_setColumnName(model, iColumn, name)
    ccall((:Clp_setColumnName, libClp), Cvoid, (Ptr{Clp_Simplex}, Cint, Cstring), model, iColumn, name)
end

function Clp_initialSolve(model)
    ccall((:Clp_initialSolve, libClp), Cint, (Ptr{Clp_Simplex},), model)
end

function Clp_initialSolveWithOptions(model, arg1)
    ccall((:Clp_initialSolveWithOptions, libClp), Cint, (Ptr{Clp_Simplex}, Ptr{Clp_Solve}), model, arg1)
end

function Clp_initialDualSolve(model)
    ccall((:Clp_initialDualSolve, libClp), Cint, (Ptr{Clp_Simplex},), model)
end

function Clp_initialPrimalSolve(model)
    ccall((:Clp_initialPrimalSolve, libClp), Cint, (Ptr{Clp_Simplex},), model)
end

function Clp_initialBarrierSolve(model)
    ccall((:Clp_initialBarrierSolve, libClp), Cint, (Ptr{Clp_Simplex},), model)
end

function Clp_initialBarrierNoCrossSolve(model)
    ccall((:Clp_initialBarrierNoCrossSolve, libClp), Cint, (Ptr{Clp_Simplex},), model)
end

function Clp_dual(model, ifValuesPass)
    ccall((:Clp_dual, libClp), Cint, (Ptr{Clp_Simplex}, Cint), model, ifValuesPass)
end

function Clp_primal(model, ifValuesPass)
    ccall((:Clp_primal, libClp), Cint, (Ptr{Clp_Simplex}, Cint), model, ifValuesPass)
end

function Clp_idiot(model, tryhard)
    ccall((:Clp_idiot, libClp), Cvoid, (Ptr{Clp_Simplex}, Cint), model, tryhard)
end

function Clp_scaling(model, mode)
    ccall((:Clp_scaling, libClp), Cvoid, (Ptr{Clp_Simplex}, Cint), model, mode)
end

function Clp_scalingFlag(model)
    ccall((:Clp_scalingFlag, libClp), Cint, (Ptr{Clp_Simplex},), model)
end

function Clp_crash(model, gap, pivot)
    ccall((:Clp_crash, libClp), Cint, (Ptr{Clp_Simplex}, Cdouble, Cint), model, gap, pivot)
end

function Clp_primalFeasible(model)
    ccall((:Clp_primalFeasible, libClp), Cint, (Ptr{Clp_Simplex},), model)
end

function Clp_dualFeasible(model)
    ccall((:Clp_dualFeasible, libClp), Cint, (Ptr{Clp_Simplex},), model)
end

function Clp_dualBound(model)
    ccall((:Clp_dualBound, libClp), Cdouble, (Ptr{Clp_Simplex},), model)
end

function Clp_setDualBound(model, value)
    ccall((:Clp_setDualBound, libClp), Cvoid, (Ptr{Clp_Simplex}, Cdouble), model, value)
end

function Clp_infeasibilityCost(model)
    ccall((:Clp_infeasibilityCost, libClp), Cdouble, (Ptr{Clp_Simplex},), model)
end

function Clp_setInfeasibilityCost(model, value)
    ccall((:Clp_setInfeasibilityCost, libClp), Cvoid, (Ptr{Clp_Simplex}, Cdouble), model, value)
end

function Clp_perturbation(model)
    ccall((:Clp_perturbation, libClp), Cint, (Ptr{Clp_Simplex},), model)
end

function Clp_setPerturbation(model, value)
    ccall((:Clp_setPerturbation, libClp), Cvoid, (Ptr{Clp_Simplex}, Cint), model, value)
end

function Clp_algorithm(model)
    ccall((:Clp_algorithm, libClp), Cint, (Ptr{Clp_Simplex},), model)
end

function Clp_setAlgorithm(model, value)
    ccall((:Clp_setAlgorithm, libClp), Cvoid, (Ptr{Clp_Simplex}, Cint), model, value)
end

function Clp_sumDualInfeasibilities(model)
    ccall((:Clp_sumDualInfeasibilities, libClp), Cdouble, (Ptr{Clp_Simplex},), model)
end

function Clp_numberDualInfeasibilities(model)
    ccall((:Clp_numberDualInfeasibilities, libClp), Cint, (Ptr{Clp_Simplex},), model)
end

function Clp_sumPrimalInfeasibilities(model)
    ccall((:Clp_sumPrimalInfeasibilities, libClp), Cdouble, (Ptr{Clp_Simplex},), model)
end

function Clp_numberPrimalInfeasibilities(model)
    ccall((:Clp_numberPrimalInfeasibilities, libClp), Cint, (Ptr{Clp_Simplex},), model)
end

function Clp_saveModel(model, fileName)
    ccall((:Clp_saveModel, libClp), Cint, (Ptr{Clp_Simplex}, Cstring), model, fileName)
end

function Clp_restoreModel(model, fileName)
    ccall((:Clp_restoreModel, libClp), Cint, (Ptr{Clp_Simplex}, Cstring), model, fileName)
end

function Clp_checkSolution(model)
    ccall((:Clp_checkSolution, libClp), Cvoid, (Ptr{Clp_Simplex},), model)
end

function Clp_getNumRows(model)
    ccall((:Clp_getNumRows, libClp), Cint, (Ptr{Clp_Simplex},), model)
end

function Clp_getNumCols(model)
    ccall((:Clp_getNumCols, libClp), Cint, (Ptr{Clp_Simplex},), model)
end

function Clp_getIterationCount(model)
    ccall((:Clp_getIterationCount, libClp), Cint, (Ptr{Clp_Simplex},), model)
end

function Clp_isAbandoned(model)
    ccall((:Clp_isAbandoned, libClp), Cint, (Ptr{Clp_Simplex},), model)
end

function Clp_isProvenOptimal(model)
    ccall((:Clp_isProvenOptimal, libClp), Cint, (Ptr{Clp_Simplex},), model)
end

function Clp_isProvenPrimalInfeasible(model)
    ccall((:Clp_isProvenPrimalInfeasible, libClp), Cint, (Ptr{Clp_Simplex},), model)
end

function Clp_isProvenDualInfeasible(model)
    ccall((:Clp_isProvenDualInfeasible, libClp), Cint, (Ptr{Clp_Simplex},), model)
end

function Clp_isPrimalObjectiveLimitReached(model)
    ccall((:Clp_isPrimalObjectiveLimitReached, libClp), Cint, (Ptr{Clp_Simplex},), model)
end

function Clp_isDualObjectiveLimitReached(model)
    ccall((:Clp_isDualObjectiveLimitReached, libClp), Cint, (Ptr{Clp_Simplex},), model)
end

function Clp_isIterationLimitReached(model)
    ccall((:Clp_isIterationLimitReached, libClp), Cint, (Ptr{Clp_Simplex},), model)
end

function Clp_getObjSense(model)
    ccall((:Clp_getObjSense, libClp), Cdouble, (Ptr{Clp_Simplex},), model)
end

function Clp_setObjSense(model, objsen)
    ccall((:Clp_setObjSense, libClp), Cvoid, (Ptr{Clp_Simplex}, Cdouble), model, objsen)
end

function Clp_getRowActivity(model)
    ccall((:Clp_getRowActivity, libClp), Ptr{Cdouble}, (Ptr{Clp_Simplex},), model)
end

function Clp_getColSolution(model)
    ccall((:Clp_getColSolution, libClp), Ptr{Cdouble}, (Ptr{Clp_Simplex},), model)
end

function Clp_setColSolution(model, input)
    ccall((:Clp_setColSolution, libClp), Cvoid, (Ptr{Clp_Simplex}, Ptr{Cdouble}), model, input)
end

function Clp_getRowPrice(model)
    ccall((:Clp_getRowPrice, libClp), Ptr{Cdouble}, (Ptr{Clp_Simplex},), model)
end

function Clp_getReducedCost(model)
    ccall((:Clp_getReducedCost, libClp), Ptr{Cdouble}, (Ptr{Clp_Simplex},), model)
end

function Clp_getRowLower(model)
    ccall((:Clp_getRowLower, libClp), Ptr{Cdouble}, (Ptr{Clp_Simplex},), model)
end

function Clp_getRowUpper(model)
    ccall((:Clp_getRowUpper, libClp), Ptr{Cdouble}, (Ptr{Clp_Simplex},), model)
end

function Clp_getObjCoefficients(model)
    ccall((:Clp_getObjCoefficients, libClp), Ptr{Cdouble}, (Ptr{Clp_Simplex},), model)
end

function Clp_getColLower(model)
    ccall((:Clp_getColLower, libClp), Ptr{Cdouble}, (Ptr{Clp_Simplex},), model)
end

function Clp_getColUpper(model)
    ccall((:Clp_getColUpper, libClp), Ptr{Cdouble}, (Ptr{Clp_Simplex},), model)
end

function Clp_getObjValue(model)
    ccall((:Clp_getObjValue, libClp), Cdouble, (Ptr{Clp_Simplex},), model)
end

function Clp_printModel(model, prefix)
    ccall((:Clp_printModel, libClp), Cvoid, (Ptr{Clp_Simplex}, Cstring), model, prefix)
end

function Clp_getSmallElementValue(model)
    ccall((:Clp_getSmallElementValue, libClp), Cdouble, (Ptr{Clp_Simplex},), model)
end

function Clp_setSmallElementValue(model, value)
    ccall((:Clp_setSmallElementValue, libClp), Cvoid, (Ptr{Clp_Simplex}, Cdouble), model, value)
end

function ClpSolve_setSpecialOption(arg1, which, value, extraInfo)
    ccall((:ClpSolve_setSpecialOption, libClp), Cvoid, (Ptr{Clp_Solve}, Cint, Cint, Cint), arg1, which, value, extraInfo)
end

function ClpSolve_getSpecialOption(arg1, which)
    ccall((:ClpSolve_getSpecialOption, libClp), Cint, (Ptr{Clp_Solve}, Cint), arg1, which)
end

function ClpSolve_setSolveType(arg1, method, extraInfo)
    ccall((:ClpSolve_setSolveType, libClp), Cvoid, (Ptr{Clp_Solve}, Cint, Cint), arg1, method, extraInfo)
end

function ClpSolve_getSolveType(arg1)
    ccall((:ClpSolve_getSolveType, libClp), Cint, (Ptr{Clp_Solve},), arg1)
end

function ClpSolve_setPresolveType(arg1, amount, extraInfo)
    ccall((:ClpSolve_setPresolveType, libClp), Cvoid, (Ptr{Clp_Solve}, Cint, Cint), arg1, amount, extraInfo)
end

function ClpSolve_getPresolveType(arg1)
    ccall((:ClpSolve_getPresolveType, libClp), Cint, (Ptr{Clp_Solve},), arg1)
end

function ClpSolve_getPresolvePasses(arg1)
    ccall((:ClpSolve_getPresolvePasses, libClp), Cint, (Ptr{Clp_Solve},), arg1)
end

function ClpSolve_getExtraInfo(arg1, which)
    ccall((:ClpSolve_getExtraInfo, libClp), Cint, (Ptr{Clp_Solve}, Cint), arg1, which)
end

function ClpSolve_setInfeasibleReturn(arg1, trueFalse)
    ccall((:ClpSolve_setInfeasibleReturn, libClp), Cvoid, (Ptr{Clp_Solve}, Cint), arg1, trueFalse)
end

function ClpSolve_infeasibleReturn(arg1)
    ccall((:ClpSolve_infeasibleReturn, libClp), Cint, (Ptr{Clp_Solve},), arg1)
end

function ClpSolve_doDual(arg1)
    ccall((:ClpSolve_doDual, libClp), Cint, (Ptr{Clp_Solve},), arg1)
end

function ClpSolve_setDoDual(arg1, doDual)
    ccall((:ClpSolve_setDoDual, libClp), Cvoid, (Ptr{Clp_Solve}, Cint), arg1, doDual)
end

function ClpSolve_doSingleton(arg1)
    ccall((:ClpSolve_doSingleton, libClp), Cint, (Ptr{Clp_Solve},), arg1)
end

function ClpSolve_setDoSingleton(arg1, doSingleton)
    ccall((:ClpSolve_setDoSingleton, libClp), Cvoid, (Ptr{Clp_Solve}, Cint), arg1, doSingleton)
end

function ClpSolve_doDoubleton(arg1)
    ccall((:ClpSolve_doDoubleton, libClp), Cint, (Ptr{Clp_Solve},), arg1)
end

function ClpSolve_setDoDoubleton(arg1, doDoubleton)
    ccall((:ClpSolve_setDoDoubleton, libClp), Cvoid, (Ptr{Clp_Solve}, Cint), arg1, doDoubleton)
end

function ClpSolve_doTripleton(arg1)
    ccall((:ClpSolve_doTripleton, libClp), Cint, (Ptr{Clp_Solve},), arg1)
end

function ClpSolve_setDoTripleton(arg1, doTripleton)
    ccall((:ClpSolve_setDoTripleton, libClp), Cvoid, (Ptr{Clp_Solve}, Cint), arg1, doTripleton)
end

function ClpSolve_doTighten(arg1)
    ccall((:ClpSolve_doTighten, libClp), Cint, (Ptr{Clp_Solve},), arg1)
end

function ClpSolve_setDoTighten(arg1, doTighten)
    ccall((:ClpSolve_setDoTighten, libClp), Cvoid, (Ptr{Clp_Solve}, Cint), arg1, doTighten)
end

function ClpSolve_doForcing(arg1)
    ccall((:ClpSolve_doForcing, libClp), Cint, (Ptr{Clp_Solve},), arg1)
end

function ClpSolve_setDoForcing(arg1, doForcing)
    ccall((:ClpSolve_setDoForcing, libClp), Cvoid, (Ptr{Clp_Solve}, Cint), arg1, doForcing)
end

function ClpSolve_doImpliedFree(arg1)
    ccall((:ClpSolve_doImpliedFree, libClp), Cint, (Ptr{Clp_Solve},), arg1)
end

function ClpSolve_setDoImpliedFree(arg1, doImpliedFree)
    ccall((:ClpSolve_setDoImpliedFree, libClp), Cvoid, (Ptr{Clp_Solve}, Cint), arg1, doImpliedFree)
end

function ClpSolve_doDupcol(arg1)
    ccall((:ClpSolve_doDupcol, libClp), Cint, (Ptr{Clp_Solve},), arg1)
end

function ClpSolve_setDoDupcol(arg1, doDupcol)
    ccall((:ClpSolve_setDoDupcol, libClp), Cvoid, (Ptr{Clp_Solve}, Cint), arg1, doDupcol)
end

function ClpSolve_doDuprow(arg1)
    ccall((:ClpSolve_doDuprow, libClp), Cint, (Ptr{Clp_Solve},), arg1)
end

function ClpSolve_setDoDuprow(arg1, doDuprow)
    ccall((:ClpSolve_setDoDuprow, libClp), Cvoid, (Ptr{Clp_Solve}, Cint), arg1, doDuprow)
end

function ClpSolve_doSingletonColumn(arg1)
    ccall((:ClpSolve_doSingletonColumn, libClp), Cint, (Ptr{Clp_Solve},), arg1)
end

function ClpSolve_setDoSingletonColumn(arg1, doSingleton)
    ccall((:ClpSolve_setDoSingletonColumn, libClp), Cvoid, (Ptr{Clp_Solve}, Cint), arg1, doSingleton)
end

function ClpSolve_presolveActions(arg1)
    ccall((:ClpSolve_presolveActions, libClp), Cint, (Ptr{Clp_Solve},), arg1)
end

function ClpSolve_setPresolveActions(arg1, action)
    ccall((:ClpSolve_setPresolveActions, libClp), Cvoid, (Ptr{Clp_Solve}, Cint), arg1, action)
end

function ClpSolve_substitution(arg1)
    ccall((:ClpSolve_substitution, libClp), Cint, (Ptr{Clp_Solve},), arg1)
end

function ClpSolve_setSubstitution(arg1, value)
    ccall((:ClpSolve_setSubstitution, libClp), Cvoid, (Ptr{Clp_Solve}, Cint), arg1, value)
end


text:
# utils for running gcloud command, reading ~/.config/gcloud directory or
# interacting with google cloud api.

"""
    read_access_token()
    read_refresh_token()

Obtain google cloud access token or refresh token with
`gcloud auth print-access-token` or `gcloud auth print-refresh-token`
command. The access token usually expires after one hour, the refresh
token can be used to obtain new access token.
"""
read_access_token, read_refresh_token

function read_access_token()
    token = read(`gcloud auth --quiet print-access-token`, String)
    token = rstrip(token)
    token
end

function read_refresh_token()
    token = read(`gcloud auth --quiet print-refresh-token`, String)
    token = rstrip(token)
    token
end

"""
    read_active_account()

Read active account name from `gcloud auth list` command.
"""
function read_active_account()
    account = read(`gcloud --quiet auth list`, String)
    account = rstrip(account)
    account = split(account, "\n")
    account = filter(startswith("*"), account)
    length(account) != 1 && error("error finding active account with 'gcloud auth list'")
    account = account[1]
    account = replace(account, r"\* *" => "")
    account
end

"""
    read_account_state(account)

Read account auth states as a dictionary for a given account from
`gcloud auth describe` command.
"""
function read_account_desc(account)
    info = read(`gcloud auth describe $account`, String)
    info = rstrip(info)
    info = split(info, "\n")
    info = filter(contains(": "), info)
    info = map(x -> split(x, ": "), info)
    Dict{String,String}(info)
end

"""
    read_application_default_credentials()

Read content from "~/.config/gcloud/application_default_credentials.json".
It contains client_id, client_secret and refresh_token.
"""
function read_application_default_credentials()
    json = open(joinpath(homedir(), ".config/gcloud/application_default_credentials.json")) do f
        read(f, String)
    end
    dict = JSON.parse(json)
    dict
end

"""
    fetch_access_token_info(token)

Get access token information (e.g. expiration time) by querying google api.
"""
function http_access_token_info(token)
    query = "https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=" * token
    res = HTTP.get(query)
    @assert HTTP.status(res) == 200
    json = String(HTTP.body(res))
    dict = JSON.parse(json)
    dict
end

"""
    http_reauth_access_token(;refresh_token, client_id, client_secret)

Obtain a new access token with refresh_token, client_id and client_secret from google api.
"""
# FIXME: this is not done right, check
# https://github.com/google/google-reauth-python/blob/master/google_reauth/reauth.py#L150-L199
# https://github.com/googleapis/google-auth-library-python/blob/master/google/oauth2/credentials.py#L207-L254
function http_reauth_access_token(;refresh_token, client_id, client_secret)
    params = [
        "client_id" => client_id,
        "client_secret" => client_secret,
        "grant_type" => "refresh_token",
        "refresh_token" => refresh_token,
        "scope" => ["https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/accounts.reauth"]
    ]
    res = HTTP.post("https://www.googleapis.com/oauth2/v4/token"; query = params, redirect=false)
    @assert HTTP.status(res) == 200
    json = String(HTTP.body(res))
    dict = JSON.parse(json)
    dict
end

function parse_gsurl(gsurl)
    @assert startswith(gsurl, "gs://")
    gsurl = gsurl[(length("gs://") + 1):end]
    bucket = split(gsurl, "/")[1]
    path = gsurl[(length(bucket) + 2):end]
    bucket, path
end

function fetch_gcs(gsurl::AbstractString, access_token::AbstractString; range=nothing)
    (bucket, path) = parse_gsurl(gsurl)
    api = "https://$bucket.storage-download.googleapis.com/$path"
    headers = [
        "Authorization" => "Bearer " * access_token
    ]
    if !isnothing(range)
        @assert 1 <= first(range) <= last(range)
        push!(headers, "Range" => "bytes=$(first(range)-1)-$(last(range)-1)")
    end
    res = HTTP.get(api; retry=true, redirect=false, headers=headers)
    !isnothing(range) ? (@assert HTTP.status(res) == 206) : (@assert HTTP.status(res) == 200)
    return HTTP.body(res)
end

function fetch_object_info(gsurl::AbstractString, access_token::AbstractString)
    (bucket, path) = parse_gsurl(gsurl)
    path = HTTP.escapeuri(path)
    api = "https://storage.googleapis.com/storage/v1/b/$bucket/o/$path"
    headers = [
        "Authorization" => "Bearer " * access_token
    ]
    res = HTTP.get(api; retry=true, redirect=false, headers=headers)
    @assert HTTP.status(res) == 200
    JSON.parse(String(HTTP.body(res)))
end


text:
"""
`module  PhotoExcitationAutoion`
    ... a submodel of JAC that contains all methods for computing photo-excitation-autoionization cross
        sections and rates.
"""
module PhotoExcitationAutoion

    using Printf, ..AngularMomentum, ..AutoIonization, ..Basics, ..Continuum, ..ManyElectron, ..Nuclear, ..PhotoEmission,
                  ..Radial, ..TableStrings
    ##x global JAC_counter = 0

    """
    `struct  PhotoExcitationAutoion.Settings`
        ... defines a type for the details and parameters of computing photon-impact excitation-autoionization pathways
            |i(N)>  --> |m(N)>  --> |f(N-1)>.

        + multipoles              ::Array{Basics.EmMultipole,1}    ... Specifies the multipoles of the radiation field that are to be included.
        + gauges                  ::Array{Basics.UseGauge,1}       ... Specifies the gauges to be included into the computations.
        + printBeforeComputation  ::Bool                               ... True, if all energies and lines are printed before their evaluation.
        + selectPathways          ::Bool                               ... True if particular pathways are selected for the computations.
        + selectedPathways        ::Array{Tuple{Int64,Int64,Int64},1}  ... List of list of pathways, given by tupels (inital, inmediate, final).
        + maxKappa                ::Int64                              ... Maximum kappa value of partial waves to be included.
    """
    struct Settings
        multipoles                ::Array{Basics.EmMultipole,1}
        gauges                    ::Array{Basics.UseGauge,1}
        printBeforeComputation    ::Bool
        selectPathways            ::Bool
        selectedPathways          ::Array{Tuple{Int64,Int64,Int64},1}
        maxKappa                  ::Int64
    end

    """
    `PhotoExcitationAutoion.Settings()`
        ... constructor for the default values of photon-impact excitation-autoionizaton settings.
    """
    function Settings()
        Settings( Basics.EmMultipole[], UseGauge[], false,  false, Tuple{Int64,Int64,Int64}[], 0)
    end

    # `Base.show(io::IO, settings::PhotoExcitationAutoion.Settings)`
    # 	... prepares a proper printout of the variable settings::PhotoExcitationAutoion.Settings.
    function Base.show(io::IO, settings::PhotoExcitationAutoion.Settings)
        println(io, "multipoles:              $(settings.multipoles)  ")
        println(io, "gauges:                  $(settings.gauges)  ")
        println(io, "printBeforeComputation:  $(settings.printBeforeComputation)  ")
        println(io, "selectPathways:          $(settings.selectPathways)  ")
        println(io, "selectedPathways:        $(settings.selectedPathways)  ")
        println(io, "maxKappa:                $(settings.maxKappa)  ")
    end

    """
    `struct  PhotoExcitationAutoion.Pathway`
        ... defines a type for a photon-impact excitation pathway that may include the definition of different
            excitation and autoionization channels and their corresponding amplitudes.

        + initialLevel        ::Level           ... initial-(state) level
        + intermediateLevel   ::Level           ... intermediate-(state) level
        + finalLevel          ::Level           ... final-(state) level
        + excitEnergy         ::Float64         ... photon excitation energy of this pathway
        + electronEnergy      ::Float64         ... energy of the (finally outgoing, scattered) electron
        + crossSection        ::EmProperty      ... total cross section of this pathway
        + hasChannels         ::Bool            ... Determines whether the individual excitation and autoionization channels
                                                    are defined in terms of their multipole, gauge, free-electron kappa,
                                                    phases and the total angular momentum/parity as well as the amplitude,
                                                    or not.
        + excitChannels       ::Array{PhotoEmission.Channel,1}  ... List of excitation channels of this pathway.
        + augerChannels       ::Array{AutoIonization.Channel,1} ... List of Auger channels of this pathway.
    """
    struct  Pathway
        initialLevel          ::Level
        intermediateLevel     ::Level
        finalLevel            ::Level
        excitEnergy           ::Float64
        electronEnergy        ::Float64
        crossSection          ::EmProperty
        hasChannels           ::Bool
        excitChannels         ::Array{PhotoEmission.Channel,1}
        augerChannels         ::Array{AutoIonization.Channel,1}
    end

    """
    `PhotoExcitationAutoion.Pathway()`
        ... 'empty' constructor for an photon-impact excitation-autoionization pathway between a specified initial, intermediate
            and final level.
    """
    function Pathway()
        Pathway(Level(), Level(), Level(), 0., 0., EmProperty(0., 0.), false, PhotoEmission.Channel[], AutoIonization.Channel[] )
    end

    # `Base.show(io::IO, pathway::PhotoExcitationAutoion.Pathway)`
    #		... prepares a proper printout of the variable pathway::PhotoExcitationAutoion.Pathway.
    function Base.show(io::IO, pathway::PhotoExcitationAutoion.Pathway)
        println(io, "initialLevel:               $(pathway.initialLevel)  ")
        println(io, "intermediateLevel:          $(pathway.intermediateLevel)  ")
        println(io, "finalLevel:                 $(pathway.finalLevel)  ")
        println(io, "excitEnergy                 $(pathway.excitEnergy)  ")
        println(io, "electronEnergy              $(pathway.electronEnergy)  ")
        println(io, "crossSection:               $(pathway.crossSection)  ")
        println(io, "hasChannels:                $(pathway.hasChannels)  ")
        println(io, "excitEnergy:                $(pathway.excitEnergy)  ")
        println(io, "augerEnergy:                $(pathway.augerEnergy)  ")
    end

    """
    `PhotoExcitationAutoion.computeAmplitudesProperties(pathway::PhotoExcitationAutoion.Pathway, nm::Nuclear.Model, grid::Radial.Grid,
                                                        nrContinuum::Int64, settings::PhotoExcitationAutoion.Settings)`
        ... to compute all amplitudes and properties of the given pathway; a line::PhotoExcitationAutoion.Pathway is returned for which
            the amplitudes and properties have now been evaluated.
    """
    function  computeAmplitudesProperties(pathway::PhotoExcitationAutoion.Pathway, nm::Nuclear.Model, grid::Radial.Grid, nrContinuum::Int64,
                                          settings::PhotoExcitationAutoion.Settings)
        # Compute all excitation channels
        neweChannels = PhotoEmission.Channel[]
        for eChannel in pathway.excitChannels
            amplitude   = PhotoEmission.amplitude("absorption", eChannel.multipole, eChannel.gauge, pathway.excitEnergy,
                                                  pathway.intermediateLevel, pathway.initialLevel, grid)
             push!( neweChannels, PhotoEmission.Channel( eChannel.multipole, eChannel.gauge, amplitude))
        end
        # Compute all AutoIonization decay channels
        newaChannels = AutoIonization.Channel[];   contSettings = Continuum.Settings(false, nrContinuum)
        for aChannel in pathway.augerChannels
            newnLevel   = Basics.generateLevelWithSymmetryReducedBasis(pathway.intermediateLevel)
            newnLevel   = Basics.generateLevelWithExtraSubshell(Subshell(101, aChannel.kappa), newnLevel)
            newfLevel   = Basics.generateLevelWithSymmetryReducedBasis(pathway.finalLevel)
            cOrbital, phase  = Continuum.generateOrbitalForLevel(pathway.electronEnergy, Subshell(101, aChannel.kappa), newfLevel, nm, grid, contSettings)
            newcLevel   = Basics.generateLevelWithExtraElectron(cOrbital, aChannel.symmetry, newfLevel)
            newcChannel = AutoIonization.Channel( aChannel.kappa, aChannel.symmetry, phase, Complex(0.))
            amplitude = 1.0
            ## amplitude   = AutoIonization.amplitude("Coulomb", aChannel, newnLevel, newcLevel, grid)
            push!( newaChannels, AutoIonization.Channel( aChannel.kappa, aChannel.symmetry, phase, amplitude))
        end
        #
        crossSection = EmProperty(-1., -1.)
        pathway = PhotoExcitationAutoion.Pathway( pathway.initialLevel, pathway.intermediateLevel, pathway.finalLevel,
                                                  pathway.excitEnergy, pathway.electronEnergy, crossSection, true, neweChannels, newaChannels)
        return( pathway )
    end

    """
    `PhotoExcitationAutoion.computePathways(finalMultiplet::Multiplet, intermediateMultiplet::Multiplet, initialMultiplet::Multiplet,
                                            nm::Nuclear.Model, grid::Radial.Grid, settings::PhotoExcitation.Settings; output=true)`
        ... to compute the photo-excitation-autoionization amplitudes and all properties as requested by the given settings. A list of
            lines::Array{PhotoExcitationAutoion.Lines} is returned.
    """
    function  computePathways(finalMultiplet::Multiplet, intermediateMultiplet::Multiplet, initialMultiplet::Multiplet, nm::Nuclear.Model,
                              grid::Radial.Grid, settings::PhotoExcitationAutoion.Settings; output=true)
        println("")
        printstyled("PhotoExcitationAutoion.computePathways(): The computation of photo-excitation-autoionization amplitudes starts now ... \n", color=:light_green)
        printstyled("---------------------------------------------------------------------------------------------------------------------- \n", color=:light_green)
        println("")
        #
        pathways = PhotoExcitationAutoion.determinePathways(finalMultiplet, intermediateMultiplet, initialMultiplet, settings)
        # Display all selected lines before the computations start
        if  settings.printBeforeComputation    PhotoExcitationAutoion.displayPathways(pathways)    end
        # Determine maximum (electron) energy and check for consistency of the grid
        maxEnergy = 0.;   for  pathway in pathways   maxEnergy = max(maxEnergy, pathway.electronEnergy)   end
        nrContinuum = Continuum.gridConsistency(maxEnergy, grid)
        # Calculate all amplitudes and requested properties
        newPathways = PhotoExcitationAutoion.Pathway[]
        for  pathway in pathways
            push!( newPathways, PhotoExcitationAutoion.computeAmplitudesProperties(pathway, nm, grid, nrContinuum, settings) )
        end
        # Print all results to screen
        PhotoExcitationAutoion.displayResults(stdout, newPathways)
        printSummary, iostream = Defaults.getDefaults("summary flag/stream")
        if  printSummary    PhotoExcitationAutoion.displayResults(iostream, newPathways)   end
        #
        if    output    return( newPathways )
        else            return( nothing )
        end
    end

    """
    `PhotoExcitationAutoion.determinePathways(finalMultiplet::Multiplet, intermediateMultiplet::Multiplet, initialMultiplet::Multiplet,
                                              settings::PhotoExcitationAutoion.Settings)`
        ... to determine a list of photoexcitation-autoionization pathways between the levels from the given initial-, intermediate- and
            final-state multiplets and by taking into account the particular selections and settings for this computation; an
            Array{PhotoExcitationAutoion.Line,1} is returned. Apart from the level specification, all physical properties are set to zero
            during the initialization process.
    """
    function  determinePathways(finalMultiplet::Multiplet, intermediateMultiplet::Multiplet, initialMultiplet::Multiplet,
                                settings::PhotoExcitationAutoion.Settings)
        if    settings.selectPathways    selectPathways = true;   selectedPathways = Basics.determine("selected pathways", settings.selectedPathways)
        else                             selectPathways = false
        end

        pathways = PhotoExcitationAutoion.Pathway[]
        for  i = 1:length(initialMultiplet.levels)
            for  n = 1:length(intermediateMultiplet.levels)
                for  f = 1:length(finalMultiplet.levels)
                    if  selectPathways  &&  !(haskey(selectedPathways, (i,n,f)) )    continue   end
                    ##x println("PhotoExcitationAutoion.determineLines-aa: angular i = $i, f = $f")
                    eEnergy = intermediateMultiplet.levels[n].energy - initialMultiplet.levels[i].energy
                    aEnergy = intermediateMultiplet.levels[n].energy - finalMultiplet.levels[f].energy
                    if  eEnergy < 0.   ||   aEnergy < 0    continue    end

                    rSettings = PhotoEmission.Settings( settings.multipoles, settings.gauges, false, false, false, Tuple{Int64,Int64}[], 0., 0., 0.)
                    eChannels = PhotoEmission.determineChannels(intermediateMultiplet.levels[n], initialMultiplet.levels[i], rSettings)
                    aSettings = AutoIonization.Settings( false, false, false, Tuple{Int64,Int64}[], 0., 0., settings.maxKappa, "Coulomb")
                    aChannels = AutoIonization.determineChannels(finalMultiplet.levels[f], intermediateMultiplet.levels[n], aSettings)
                    push!( pathways, PhotoExcitationAutoion.Pathway(initialMultiplet.levels[i], intermediateMultiplet.levels[n],
                                            finalMultiplet.levels[f], eEnergy, aEnergy, EmProperty(0., 0.), true, eChannels, aChannels) )
                end
            end
        end
        return( pathways )
    end

    #==
    """
    `PhotoExcitationAutoion.determineChannels(finalLevel::Level, intermediateLevel::Level, initialLevel::Level,
                                              settings::PhotoExcitationAutoion.Settings)`
        ... to determine a list of photoexcitation-autoionization Channels for a pathway from the initial to and
            intermediate and to a final level, and by taking into account the particular settings of for this computation;
            an Array{PhotoExcitationAutoion.Channel,1} is returned.
    """
    function determineChannels(finalLevel::Level, intermediateLevel::Level, initialLevel::Level, settings::PhotoExcitationAutoion.Settings)
        symi      = LevelSymmetry(initialLevel.J, initialLevel.parity);    symf = LevelSymmetry(finalLevel.J, finalLevel.parity)
        symn      = LevelSymmetry(intermediateLevel.J, intermediateLevel.parity)
        # Determine first the radiative channels
        rChannels = PhotoEmission.Channel[];
        for  mp in settings.multipoles
            if   AngularMomentum.isAllowedMultipole(symi, mp, symn)
                hasMagnetic = false
                for  gauge in settings.gauges
                    # Include further restrictions if appropriate
                    if     string(mp)[1] == 'E'  &&   gauge == Basics.UseCoulomb      push!(rChannels, PhotoEmission.Channel(mp, Basics.Coulomb,   0.) )
                    elseif string(mp)[1] == 'E'  &&   gauge == Basics.UseBabushkin    push!(rChannels, PhotoEmission.Channel(mp, Basics.Babushkin, 0.) )
                    elseif string(mp)[1] == 'M'  &&   !(hasMagnetic)                  push!(rChannels, PhotoEmission.Channel(mp,Basics.Magnetic,  0.) );
                                                        hasMagnetic = true;
                    end
                end
            end
        end

        # Determine next the AutoIonization channels
        aChannels = AutoIonization.Channel[];
        kappaList = AngularMomentum.allowedKappaSymmetries(symn, symf)
        for  kappa in kappaList
            push!(aChannels, AutoIonization.Channel(kappa, symi, 0., Complex(0.)) )
        end

        # Now combine all these channels
        channels  = PhotoExcitationAutoion.Channel[];
        for    r in rChannels
            for    a in aChannels
                push!(channels,  PhotoExcitationAutoion.Channel(r, a) )
            end
        end

        return( channels )
    end  ==#

    """
    `PhotoExcitationAutoion.displayPathways(pathways::Array{PhotoExcitationAutoion.Line,1})`
        ... to display a list of pathways and channels that have been selected due to the prior settings. A neat table of
            all selected transitions and energies is printed but nothing is returned otherwise.
    """
    function  displayPathways(pathways::Array{PhotoExcitationAutoion.Pathway,1})
        println(" ")
        println("  Selected photo-excitation-autoionization pathways:")
        println(" ")
        println("  ", TableStrings.hLine(170))
        sa = "     ";   sb = "     "
        sa = sa * TableStrings.center(23, "Levels"; na=2);            sb = sb * TableStrings.center(23, "i  --  m  --  f"; na=2);
        sa = sa * TableStrings.center(23, "J^P symmetries"; na=3);    sb = sb * TableStrings.center(23, "i  --  m  --  f"; na=3);
        sa = sa * TableStrings.center(14, "Energy m-i"; na=4);
        sb = sb * TableStrings.center(14, TableStrings.inUnits("energy"); na=4)
        sa = sa * TableStrings.center(14, "Energy m-f"; na=3);
        sb = sb * TableStrings.center(14, TableStrings.inUnits("energy"); na=3)
        sa = sa * TableStrings.flushleft(57, "List of multipoles, gauges, kappas and total symmetries"; na=4)
        sb = sb * TableStrings.flushleft(57, "partial (multipole, gauge, total J^P)                  "; na=4)
        println(sa);    println(sb);    println("  ", TableStrings.hLine(170))
        #
        for  pathway in pathways
            sa  = "  ";    isym = LevelSymmetry( pathway.initialLevel.J,      pathway.initialLevel.parity)
                           msym = LevelSymmetry( pathway.intermediateLevel.J, pathway.intermediateLevel.parity)
                           fsym = LevelSymmetry( pathway.finalLevel.J,        pathway.finalLevel.parity)
            sa = sa * TableStrings.center(23, TableStrings.levels_imf(pathway.initialLevel.index, pathway.intermediateLevel.index,
                                                                              pathway.finalLevel.index); na=2)
            sa = sa * TableStrings.center(23, TableStrings.symmetries_imf(isym, msym, fsym);  na=4)
            sa = sa * @sprintf("%.8e", Defaults.convertUnits("energy: from atomic", pathway.excitEnergy))   * "    "
            sa = sa * @sprintf("%.8e", Defaults.convertUnits("energy: from atomic", pathway.electronEnergy)) * "   "
            kappaMultipoleSymmetryList = Tuple{Int64,EmMultipole,EmGauge,LevelSymmetry}[]
            for  ech in pathway.excitChannels
                for  ach in pathway.augerChannels
                    ##x eChannel = pathway.channels[i].excitationChannel;    aChannel = pathway.channels[i].augerChannel;
                    push!( kappaMultipoleSymmetryList, (ach.kappa, ech.multipole, ech.gauge, ach.symmetry) )
                end
            end
            wa = TableStrings.kappaMultipoleSymmetryTupels(85, kappaMultipoleSymmetryList)
            if  length(wa) > 0    sb = sa * wa[1];    println( sb )    end
            for  i = 2:length(wa)
                sb = TableStrings.hBlank( length(sa) ) * wa[i];    println( sb )
            end
        end
        println("  ", TableStrings.hLine(170))
        #
        return( nothing )
    end

    """
    `PhotoExcitationAutoion.displayResults(stream::IO, pathways::Array{PhotoExcitationAutoion.Line,1})`
        ... to list all results, energies, cross sections, etc. of the selected lines. A neat table is printed but
            nothing is returned otherwise.
    """
    function  displayResults(stream::IO, pathways::Array{PhotoExcitationAutoion.Pathway,1})
        println(stream, " ")
        println(stream, "  Partial photo-excitation & autoionization cross sections:")
        println(stream, " ")
        println(stream, "  ", TableStrings.hLine(135))
        sa = "     ";   sb = "     "
        sa = sa * TableStrings.center(23, "Levels"; na=2);            sb = sb * TableStrings.center(23, "i  --  m  --  f"; na=2);
        sa = sa * TableStrings.center(23, "J^P symmetries"; na=3);    sb = sb * TableStrings.center(23, "i  --  m  --  f"; na=3);
        sa = sa * TableStrings.center(14, "Energy m-i"; na=4);
        sb = sb * TableStrings.center(14, TableStrings.inUnits("energy"); na=4)
        sa = sa * TableStrings.center(14, "Energy m-f"; na=3);
        sb = sb * TableStrings.center(14, TableStrings.inUnits("energy"); na=3)
        sa = sa * TableStrings.center(10, "Multipoles"; na=3);                        sb = sb * TableStrings.hBlank(14)
        sa = sa * TableStrings.center(30, "Cou -- Cross sections -- Bab"; na=2);
        sb = sb * TableStrings.center(30, TableStrings.inUnits("cross section")*"          "*
                                              TableStrings.inUnits("cross section"); na=2)
        println(stream, sa);    println(stream, sb);    println("  ", TableStrings.hLine(135))
        #
        for  pathway in pathways
            sa  = "  ";    isym = LevelSymmetry( pathway.initialLevel.J,      pathway.initialLevel.parity)
                           msym = LevelSymmetry( pathway.intermediateLevel.J, pathway.intermediateLevel.parity)
                           fsym = LevelSymmetry( pathway.finalLevel.J,        pathway.finalLevel.parity)
            sa = sa * TableStrings.center(23, TableStrings.levels_imf(pathway.initialLevel.index, pathway.intermediateLevel.index,
                                                                              pathway.finalLevel.index); na=2)
            sa = sa * TableStrings.center(23, TableStrings.symmetries_imf(isym, msym, fsym);  na=4)
            sa = sa * @sprintf("%.8e", Defaults.convertUnits("energy: from atomic", pathway.excitEnergy))    * "    "
            sa = sa * @sprintf("%.8e", Defaults.convertUnits("energy: from atomic", pathway.electronEnergy)) * "    "
            multipoles = EmMultipole[]
            for  ech in pathway.excitChannels
                multipoles = push!( multipoles, ech.multipole)
            end
            multipoles = unique(multipoles);   mpString = TableStrings.multipoleList(multipoles) * "          "
            sa = sa * TableStrings.flushleft(11, mpString[1:10];  na=3)
            sa = sa * @sprintf("%.6e", Defaults.convertUnits("cross section: from atomic", pathway.crossSection.Coulomb))     * "    "
            sa = sa * @sprintf("%.6e", Defaults.convertUnits("cross section: from atomic", pathway.crossSection.Babushkin))   * "    "
            println(stream, sa)
        end
        println(stream, "  ", TableStrings.hLine(135))
        #
        return( nothing )
    end

end # module


text:
struct BudgetedBipartiteMatchingInstance{T, U} <: CombinatorialInstance
    matching::BipartiteMatchingInstance{T}
    weight::Dict{Edge{T}, U}
    budget::U

    function BudgetedBipartiteMatchingInstance(
        graph::AbstractGraph{T},
        reward::Dict{Edge{T}, Float64},
        weight::Dict{Edge{T}, U},
        budget::U,
    ) where {T, U}
        matching = BipartiteMatchingInstance(graph, reward)
        return new{T, U}(matching, weight, budget)
    end
end

function _budgeted_bipartite_matching_compute_value(
    i::BudgetedBipartiteMatchingInstance{T, U},
    solution::Vector{Edge{T}},
) where {T, U}
    return _budgeted_bipartite_matching_compute_value(i.matching, solution)
end

function _budgeted_bipartite_matching_compute_value(
    i::BipartiteMatchingInstance{T},
    solution::Vector{Edge{T}},
) where {T}
    return sum(
        i.reward[(e in keys(i.reward)) ? e : reverse(e)] for e in solution
    )
end

function _budgeted_bipartite_matching_compute_weight(
    i::BudgetedBipartiteMatchingInstance{T, U},
    solution::Vector{Edge{T}},
) where {T, U}
    return sum(
        i.weight[(e in keys(i.weight)) ? e : reverse(e)] for e in solution
    )
end

abstract type BudgetedBipartiteMatchingSolution{T, U} <: CombinatorialSolution
    # instance::BudgetedBipartiteMatchingInstance{T, U}
    # solution::Vector{Edge{T}}
    # value::Float64 # TODO: remove me, only useful for Lagrangian.
end


text:
using BlockDiagonals
using ChainRulesCore
using ChainRulesTestUtils
using Documenter
using FiniteDifferences # For overloading to_vec
using Test
using LinearAlgebra

push!(ChainRulesTestUtils.TRANSFORMS_TO_ALT_TANGENTS, x -> @thunk(x))

@testset "BlockDiagonals" begin
    # The doctests fail version other than 64bit julia 1.6.x, due to printing differences
    Sys.WORD_SIZE == 64 && v"1.6" <= VERSION < v"1.7" && doctest(BlockDiagonals)
    include("blockdiagonal.jl")
    include("base_maths.jl")
    include("chainrules.jl")
    include("linalg.jl")
end  # tests


text:
export MtlDim

const MTLDim = MtSize
"""
    CuDim3(x)

    CuDim3((x,))
    CuDim3((x, y))
    CuDim3((x, y, x))

A type used to specify dimensions, consisting of 3 integers for respectively the `x`, `y`
and `z` dimension. Unspecified dimensions default to `1`.

Often accepted as argument through the `CuDim` type alias, eg. in the case of
[`cudacall`](@ref) or [`launch`](@ref), allowing to pass dimensions as a plain integer or a
tuple without having to construct an explicit `CuDim3` object.
"""
#=struct MtlDim3
    x::NsUInteger
    y::NsUInteger
    z::NsUInteger
end
=#
const MtlDim3 = MTLDim

MtlDim3(dims::Integer)             = MtlDim3(dims,    NsUInteger(1), NsUInteger(1))
MtlDim3(dims::NTuple{1,<:Integer}) = MtlDim3(dims[1], NsUInteger(1), NsUInteger(1))
MtlDim3(dims::NTuple{2,<:Integer}) = MtlDim3(dims[1], dims[2],       NsUInteger(1))
MtlDim3(dims::NTuple{3,<:Integer}) = MtlDim3(dims[1], dims[2],       dims[3])

# Type alias for conveniently specifying the dimensions
# (e.g. `(len, 2)` instead of `CuDim3((len, 2))`)
const MtlDim = Union{Integer,
                     Tuple{Integer},
                     Tuple{Integer, Integer},
                     Tuple{Integer, Integer, Integer}}


text:
__precompile__()

"""
    calcimp.jl

Input impedance calculation program by Julia.
Returns [freq::Float, impedance::Complex] Dataframe.

Available parameters :
- minfreq : default = 0.0
- maxfreq : default = 2000.0
- stepfreq : default = 2.5
- temperature : default = 24.0 (celusius)
- radiation : default = "PIPE". Candidates are PIPE, BAFFLE, NONE.

# Example:

```julia
calcimp(file.xmen) # with default params
```

```julia
calcimp(file.xmen, params) # with custom params
```
"""
module Calcimp

include("mensur.jl")
include("utilities.jl")

# export structs, functions
export Men
export calcimp, initcalcparam, readxmen, calcprs # mensur.jl
export dBSPL, hztonote, notetohz # utilities.jl

end


text:
# Largest product in a series

function solve()
    open(joinpath("..", "data", "p008.txt")) do data
        number = join(readlines(data))
        return maximum(
            prod(parse(Int, n) for n in (number[i:(i + 12)]))
            for i in 1:(1000 - 13))
    end
end

print(Int(solve()))

max_stars_repo_name: wephy/project-euler

max_issues_repo_name: wephy/project-euler

max_forks_repo_name: wephy/project-euler