text:
#
# ICU - International Components for Unicode
#

module ICU

export set_locale

export U_FAILURE,
       U_SUCCESS,

       # ubrk
       UBRK_CHARACTER,
       UBRK_LINE,
       UBRK_SENTENCE,
       UBRK_TITLE,
       UBRK_WORD,
       UBreakIterator,
       ubrk_close,
       ubrk_next,
       ubrk_open,
       ubrk_setUText,

       # ucasemap
       ucasemap_utf8FoldCase,
       ucasemap_utf8ToLower,
       ucasemap_utf8ToTitle,
       ucasemap_utf8ToUpper,

       # ucnv
       UConverter,
       ucnv_close,
       ucnv_convertEx,
       ucnv_open,
       ucnv_toUChars,

       # ucol
       UCollator,
       ucol_close,
       ucol_open,
       ucol_strcoll,

       # ustring
       u_strFoldCase,
       u_strToLower,
       u_strToUpper,
       u_strToTitle,

       # utext
       UText,
       utext_close,
       utext_open

include("../deps/deps.jl")
include("../deps/versions.jl")

@windows_only begin
    # make sure versions match
    v1 = int(iculib[end-1:end])
    v2 = int(iculibi18n[end-1:end])
    v = max(v1, v2)
    if v1 < v2
        global const iculib = string(iculib[1:end-2], v)
    elseif v1 > v2
        global const iculibi18n = string(iculibi18n[1:end-2], v)
    end
end

dliculib = dlopen(iculib)
for (suffix,version) in [("",0);
                         [("_$i",i) for i in versions];
                         [("_$(string(i)[1])_$(string(i)[2])",i) for i in versions]]
    if dlsym_e(dliculib, "u_strToUpper"*suffix) != C_NULL
        @eval const version = $version
        for f in (:u_strFoldCase,
                  :u_strToLower,
                  :u_strToTitle,
                  :u_strToUpper,
                  :ubrk_close,
                  :ubrk_next,
                  :ubrk_open,
                  :ubrk_setUText,
                  :ucal_add,
                  :ucal_clear,
                  :ucal_close,
                  :ucal_get,
                  :ucal_getDefaultTimeZone,
                  :ucal_getTimeZoneDisplayName,
                  :ucal_getMillis,
                  :ucal_getNow,
                  :ucal_open,
                  :ucal_set,
                  :ucal_setDate,
                  :ucal_setDateTime,
                  :ucal_setMillis,
                  :ucasemap_open,
                  :ucasemap_close,
                  :ucasemap_getBreakIterator,
                  :ucasemap_utf8FoldCase,
                  :ucasemap_utf8ToLower,
                  :ucasemap_utf8ToTitle,
                  :ucasemap_utf8ToUpper,
                  :ucnv_close,
                  :ucnv_convertEx,
                  :ucnv_open,
                  :ucnv_toUChars,
                  :ucol_close,
                  :ucol_open,
                  :ucol_strcoll,
                  :ucol_strcollUTF8,
                  :udat_close,
                  :udat_format,
                  :udat_open,
                  :udat_parse,
                  :utext_close,
                  :utext_openUChars,
                  :utext_openUTF8)
            @eval const $(symbol(string('_',f))) = $(string(f,suffix))
        end
        break
    end
end

typealias UBool Int8
typealias UChar Uint16
typealias UErrorCode Int32

U_FAILURE(x::Int32) = x > 0
U_SUCCESS(x::Int32) = x <= 0
U_BUFFER_OVERFLOW_ERROR = 15

locale = C_NULL
casemap = C_NULL
collator = C_NULL

typealias LocaleString Union(ASCIIString,Ptr{None})

function set_locale(s::LocaleString)
    global casemap, collator
    if casemap != C_NULL
        ccall((_ucasemap_close,iculib), Void, (Ptr{Void},), casemap)
    end
    if collator != C_NULL
        ucol_close(collator)
    end
    err = UErrorCode[0]
    casemap = ccall((_ucasemap_open,iculib), Ptr{Void},
        (Ptr{Uint8},Int32,Ptr{UErrorCode}), s, 0, err)
    U_FAILURE(err[1]) && error("could not set casemap")
    collator = ucol_open(s)
    global locale = s
end

## utext ##

immutable UText
    p::Ptr{Void}
end

function utext_open(s::UTF8String)
    err = UErrorCode[0]
    p = ccall((_utext_openUTF8,iculib), Ptr{Void},
              (Ptr{Void},Ptr{Uint8},Int64,Ptr{UErrorCode}),
              C_NULL, s, -1, err)
    @assert U_SUCCESS(err[1])
    UText(p)
end

function utext_open(s::UTF16String)
    err = UErrorCode[0]
    p = ccall((_utext_openUChars,iculib), Ptr{Void},
              (Ptr{Void},Ptr{Uint16},Int64,Ptr{UErrorCode}),
              C_NULL, s.data, length(s.data), err)
    @assert U_SUCCESS(err[1])
    UText(p)
end

utext_close(t::UText) = ccall((_utext_close,iculib), Void, (Ptr{Void},), t.p)

## ustring ##

for f in [:u_strToLower, :u_strToUpper]
    @eval begin
        function ($f)(s::UTF16String)
            src = s.data
            destsiz = int32(2*length(src))
            dest = zeros(Uint16, destsiz)
            err = UErrorCode[0]
            n = ccall(($(symbol(string('_',f))),iculib), Int32,
                (Ptr{Uint16},Int32,Ptr{Uint16},Int32,Ptr{Uint8},Ptr{UErrorCode}),
                dest, destsiz, src, length(src), locale, err)
            U_FAILURE(err[1]) && error("failed to map case")
            return UTF16String(dest[1:n])
        end
    end
end

function u_strFoldCase(s::UTF16String)
    src = s.data
    destsiz = int32(2*length(src))
    dest = zeros(Uint16, destsiz)
    err = UErrorCode[0]
    n = ccall((_u_strFoldCase,iculib), Int32,
        (Ptr{Uint16},Int32,Ptr{Uint16},Int32,Uint32,Ptr{UErrorCode}),
        dest, destsiz, src, length(src), 0, err)
    U_FAILURE(err[1]) && error("failed to map case")
    return UTF16String(dest[1:n])
end

function u_strToTitle(s::UTF16String)
    src = s.data
    destsiz = int32(2*length(src))
    dest = zeros(Uint16, destsiz)
    err = UErrorCode[0]
    breakiter = ccall((_ucasemap_getBreakIterator,iculib),
        Ptr{Void}, (Ptr{Void},), casemap)
    n = ccall((_u_strToTitle,iculib), Int32,
        (Ptr{Uint16},Int32,Ptr{Uint16},Int32,Ptr{Void},Ptr{Uint8},Ptr{UErrorCode}),
        dest, destsiz, src, length(src), breakiter, locale, err)
    U_FAILURE(err[1]) && error("failed to map case")
    return UTF16String(dest[1:n])
end

## ucasemap ##

for f in [:ucasemap_utf8FoldCase,
          :ucasemap_utf8ToLower,
          :ucasemap_utf8ToTitle,
          :ucasemap_utf8ToUpper]
    @eval begin
        function ($f)(src::UTF8String)
            destsiz = int32(2*length(src))
            dest = zeros(Uint8, destsiz)
            err = UErrorCode[0]
            n = ccall(($(symbol(string('_',f))),iculib), Int32,
                (Ptr{Void},Ptr{Uint8},Int32,Ptr{Uint8},Int32,Ptr{UErrorCode}),
                casemap, dest, destsiz, src, -1, err)
            U_FAILURE(err[1]) && error("failed to map case")
            return utf8(dest[1:n])
        end
    end
end

## ubrk ##

typealias UBreakIteratorType Int32
const UBRK_CHARACTER = int32(0)
const UBRK_WORD = int32(1)
const UBRK_LINE = int32(2)
const UBRK_SENTENCE = int32(3)
const UBRK_TITLE = int32(4)

immutable UBreakIterator
    p::Ptr{Void}
end

function ubrk_open(kind::Integer, loc::LocaleString, s::Array{Uint16,1})
    err = UErrorCode[0]
    p = ccall((_ubrk_open,iculib), Ptr{Void},
            (UBreakIteratorType,Ptr{Uint8},Ptr{Uint16},Int32,Ptr{UErrorCode}),
            kind, loc, s, length(s), err)
    @assert U_SUCCESS(err[1])
    UBreakIterator(p)
end

function ubrk_open(kind::Integer, loc::LocaleString)
    err = UErrorCode[0]
    p = ccall((_ubrk_open,iculib), Ptr{Void},
            (UBreakIteratorType,Ptr{Uint8},Ptr{Uint16},Int32,Ptr{UErrorCode}),
            kind, loc, C_NULL, 0, err)
    @assert U_SUCCESS(err[1])
    UBreakIterator(p)
end

ubrk_close(bi::UBreakIterator) =
    ccall((_ubrk_close,iculib), Void, (Ptr{Void},), bi.p)

ubrk_next(bi::UBreakIterator) =
    ccall((_ubrk_next,iculib), Int32, (Ptr{Void},), bi.p)

function ubrk_setUText(bi::UBreakIterator, t::UText)
    err = UErrorCode[0]
    ccall((_ubrk_setUText,iculib), Void,
          (Ptr{Void},Ptr{Void},Ptr{UErrorCode}),
          bi.p, t.p, err)
    @assert U_SUCCESS(err[1])
    nothing
end

## ucnv ##

immutable UConverter
    p::Ptr{Void}
end

ucnv_close(c::UConverter) =
    ccall((_ucnv_close,iculibi18n), Void, (Ptr{Void},), c.p)

type UConverterPivot
    buf::Array{UChar,1}
    pos::Array{Ptr{UChar},1}

    function UConverterPivot(n::Int)
        buf = Array(UChar, n)
        p = pointer(buf)
        new(buf, [p,p])
    end
end

function ucnv_convertEx(dstcnv::UConverter, srccnv::UConverter,
                        dst::IOBuffer, src::IOBuffer, pivot::UConverterPivot,
                        reset::Bool=false, flush::Bool=true)
    p = Ptr{Uint8}[pointer(dst.data, position(dst)+1),
                   pointer(src.data, position(src)+1)]
    p0 = copy(p)
    err = UErrorCode[0]
    ccall((_ucnv_convertEx,iculibi18n), Void,
          (Ptr{Void},Ptr{Void},
           Ptr{Ptr{Uint8}},Ptr{Uint8},Ptr{Ptr{Uint8}},Ptr{Uint8},
           Ptr{UChar},Ptr{Ptr{UChar}},Ptr{Ptr{UChar}},Ptr{UChar},
           UBool,UBool,Ptr{UErrorCode}),
          dstcnv.p, srccnv.p,
          pointer(p, 1), pointer(dst.data, length(dst.data)+1),
          pointer(p, 2), pointer(src.data, src.size+1),
          pointer(pivot.buf, 1),
          pointer(pivot.pos, 1),
          pointer(pivot.pos, 2),
          pointer(pivot.buf, length(pivot.buf)+1),
          reset, flush, err)
    dst.size += p[1] - p0[1]
    dst.ptr += p[1] - p0[1]
    src.ptr += p[2] - p0[2]
    err[1] == U_BUFFER_OVERFLOW_ERROR && return true
    @assert U_SUCCESS(err[1])
    false
end

function ucnv_open(name::ASCIIString)
    err = UErrorCode[0]
    p = ccall((_ucnv_open,iculibi18n), Ptr{Void},
              (Ptr{Uint8},Ptr{UErrorCode}), name, err)
    U_SUCCESS(err[1]) || error("ICU: could not open converter ", name)
    UConverter(p)
end

function ucnv_toUChars(cnv::UConverter, b::Array{Uint8,1})
    u = Array(Uint16, 2*length(b))
    err = UErrorCode[0]
    n = ccall((_ucnv_toUChars,iculibi18n), Int32,
              (Ptr{Void},Ptr{UChar},Int32,Ptr{Cchar},Int32,Ptr{UErrorCode}),
              cnv.p, u, length(u), b, length(b), err)
    U_SUCCESS(err[1]) || error("ICU: could not open converter ", name)
    UTF16String(u[1:n])
end

## ucol ##

immutable UCollator
    p::Ptr{Void}
end

ucol_close(c::UCollator) =
    ccall((_ucol_close,iculibi18n), Void, (Ptr{Void},), c.p)

function ucol_open(loc::LocaleString)
    err = UErrorCode[0]
    p = ccall((_ucol_open,iculibi18n), Ptr{Void},
        (Ptr{Uint8},Ptr{UErrorCode}), loc, err)
    U_SUCCESS(err[1]) || error("ICU: could not open collator for locale ", locale)
    UCollator(p)
end

function ucol_strcoll(c::UCollator, a::Array{Uint8,1}, b::Array{Uint8,1})
    err = UErrorCode[0]
    o = ccall((_ucol_strcollUTF8,iculibi18n), Int32,
              (Ptr{Void},Ptr{Uint8},Int32,Ptr{Uint8},Int32,Ptr{UErrorCode}),
              c.p, a, -1, b, -1, err)
    @assert U_SUCCESS(err[1])
    o
end

function ucol_strcoll(c::UCollator, a::Array{Uint16,1}, b::Array{Uint16,1})
    err = UErrorCode[0]
    o = ccall((_ucol_strcoll,iculibi18n), Int32,
            (Ptr{Void},Ptr{Uint16},Int32,Ptr{Uint16},Int32,Ptr{UErrorCode}),
            c.p, a, length(a), b, length(b), err)
    @assert U_SUCCESS(err[1])
    o
end

ucol_strcoll(c::UCollator, a::UTF8String, b::UTF8String) =
    ucol_strcoll(c, a.data, b.data)
ucol_strcoll(c::UCollator, a::UTF16String, b::UTF16String) =
    ucol_strcoll(c, a.data, b.data)

## calendar ##

export ICUCalendar,
       add,
       clear,
       get,
       getDefaultTimeZone,
       getMillis,
       getNow,
       getTimeZoneDisplayName,
       set,
       setDate,
       setDateTime,
       setMillis

export UCAL_ERA,
       UCAL_YEAR,
       UCAL_MONTH,
       UCAL_WEEK_OF_YEAR,
       UCAL_WEEK_OF_MONTH,
       UCAL_DATE,
       UCAL_DAY_OF_YEAR,
       UCAL_DAY_OF_WEEK,
       UCAL_DAY_OF_WEEK_IN_MONTH,
       UCAL_AM_PM,
       UCAL_HOUR,
       UCAL_HOUR_OF_DAY,
       UCAL_MINUTE,
       UCAL_SECOND,
       UCAL_MILLISECOND,
       UCAL_ZONE_OFFSET,
       UCAL_DST_OFFSET,
       UCAL_YEAR_WOY,
       UCAL_DOW_LOCAL,
       UCAL_EXTENDED_YEAR,
       UCAL_JULIAN_DAY,
       UCAL_MILLISECONDS_IN_DAY,
       UCAL_IS_LEAP_MONTH

for (i,a) in enumerate([
        :UCAL_ERA,
        :UCAL_YEAR,
        :UCAL_MONTH,
        :UCAL_WEEK_OF_YEAR,
        :UCAL_WEEK_OF_MONTH,
        :UCAL_DATE,
        :UCAL_DAY_OF_YEAR,
        :UCAL_DAY_OF_WEEK,
        :UCAL_DAY_OF_WEEK_IN_MONTH,
        :UCAL_AM_PM,
        :UCAL_HOUR,
        :UCAL_HOUR_OF_DAY,
        :UCAL_MINUTE,
        :UCAL_SECOND,
        :UCAL_MILLISECOND,
        :UCAL_ZONE_OFFSET,
        :UCAL_DST_OFFSET,
        :UCAL_YEAR_WOY,
        :UCAL_DOW_LOCAL,
        :UCAL_EXTENDED_YEAR,
        :UCAL_JULIAN_DAY,
        :UCAL_MILLISECONDS_IN_DAY,
        :UCAL_IS_LEAP_MONTH
    ])
    @eval const $a = int32($i - 1)
end

typealias UDate Float64

type ICUCalendar
    ptr::Ptr{Void}
    ICUCalendar(p::Ptr) = (self = new(p); finalizer(self, close); self)
end

function ICUCalendar(timezone::String)
    tz_u16 = utf16(timezone)
    err = UErrorCode[0]
    p = ccall((_ucal_open,iculibi18n), Ptr{Void},
        (Ptr{Uint16},Int32,Ptr{Uint8},Int32,Ptr{UErrorCode}),
        tz_u16.data, length(tz_u16.data), locale, 0, err)
    ICUCalendar(p)
end
function ICUCalendar()
    err = UErrorCode[0]
    p = ccall((_ucal_open,iculibi18n), Ptr{Void},
        (Ptr{Uint16},Int32,Ptr{Uint8},Int32,Ptr{UErrorCode}),
        C_NULL, -1, locale, 0, err)
    ICUCalendar(p)
end

close(cal::ICUCalendar) =
    ccall((_ucal_close,iculibi18n), Void, (Ptr{Void},), cal.ptr)

getNow() = ccall((_ucal_getNow,iculibi18n), UDate, ())

function getMillis(cal::ICUCalendar)
    err = UErrorCode[0]
    ccall((_ucal_getMillis,iculibi18n), UDate, (Ptr{Void},Ptr{UErrorCode}),
        cal.ptr, err)
end

function setMillis(cal::ICUCalendar, millis::UDate)
    err = UErrorCode[0]
    ccall((_ucal_setMillis,iculibi18n), Void, (Ptr{Void},UDate,Ptr{UErrorCode}),
        cal.ptr, millis, err)
end

function setDate(cal::ICUCalendar, y::Integer, m::Integer, d::Integer)
    err = UErrorCode[0]
    ccall((_ucal_setDate,iculibi18n), Void,
        (Ptr{Void},Int32,Int32,Int32,Ptr{UErrorCode}),
        cal.ptr, y, m-1, d, err)
end

function setDateTime(cal::ICUCalendar, y::Integer, mo::Integer, d::Integer, h::Integer, mi::Integer, s::Integer)
    err = UErrorCode[0]
    ccall((_ucal_setDateTime,iculibi18n), Void,
        (Ptr{Void},Int32,Int32,Int32,Int32,Int32,Int32,Ptr{UErrorCode}),
        cal.ptr, y, mo-1, d, h, mi, s, err)
end

function clear(cal::ICUCalendar)
    err = UErrorCode[0]
    ccall((_ucal_clear,iculibi18n), Void, (Ptr{Void},Ptr{UErrorCode}), cal.ptr, err)
end

function get(cal::ICUCalendar, field::Int32)
    err = UErrorCode[0]
    ccall((_ucal_get,iculibi18n), Int32,
        (Ptr{Void},Int32,Ptr{UErrorCode}),
        cal.ptr, field, err)
end
get(cal::ICUCalendar, fields::Array{Int32,1}) = [get(cal,f) for f in fields]

function add(cal::ICUCalendar, field::Int32, amount::Integer)
    err = UErrorCode[0]
    ccall((_ucal_add,iculibi18n), Int32,
        (Ptr{Void},Int32,Int32,Ptr{UErrorCode}),
        cal.ptr, field, amount, err)
end

function set(cal::ICUCalendar, field::Int32, val::Integer)
    ccall((_ucal_set,iculibi18n), Void,
        (Ptr{Void},Int32,Int32), cal.ptr, field, val)
end

function getTimeZoneDisplayName(cal::ICUCalendar)
    bufsz = 64
    buf = Array(Uint16, bufsz)
    err = UErrorCode[0]
    len = ccall((_ucal_getTimeZoneDisplayName,iculibi18n), Int32,
                (Ptr{Void},Int32,Ptr{Uint8},Ptr{UChar},Int32,Ptr{UErrorCode}),
                cal.ptr, 1, locale, buf, bufsz, err)
    UTF16String(buf[1:len])
end

function getDefaultTimeZone()
    bufsz = 64
    buf = Array(Uint16, bufsz)
    err = UErrorCode[0]
    len = ccall((_ucal_getDefaultTimeZone,iculibi18n), Int32,
                (Ptr{UChar},Int32,Ptr{UErrorCode}), buf, bufsz, err)
    UTF16String(buf[1:len])
end

export ICUDateFormat,
       format,
       parse

export UDAT_NONE,
       UDAT_FULL,
       UDAT_LONG,
       UDAT_MEDIUM,
       UDAT_SHORT,
       UDAT_RELATIVE

const UDAT_NONE     = int32(-1)
const UDAT_FULL     = int32(0)
const UDAT_LONG     = int32(1)
const UDAT_MEDIUM   = int32(2)
const UDAT_SHORT    = int32(3)
const UDAT_RELATIVE = int32(1<<7)

type ICUDateFormat
    ptr::Ptr{Void}
    ICUDateFormat(p::Ptr) = (self = new(p); finalizer(self, close); self)
end

function ICUDateFormat(pattern::String, tz::String)
    pattern_u16 = utf16(pattern)
    tz_u16 = utf16(tz)
    err = UErrorCode[0]
    p = ccall((_udat_open,iculibi18n), Ptr{Void},
          (Int32, Int32, Ptr{Uint8}, Ptr{UChar}, Int32, Ptr{UChar}, Int32, Ptr{UErrorCode}),
          -2, -2, locale, tz_u16.data, length(tz_u16.data),
          pattern_u16.data, length(pattern_u16.data), err)
    U_FAILURE(err[1]) && error("bad date format")
    ICUDateFormat(p)
end
function ICUDateFormat(tstyle::Integer, dstyle::Integer, tz::String)
    tz_u16 = utf16(tz)
    err = UErrorCode[0]
    p = ccall((_udat_open,iculibi18n), Ptr{Void},
          (Int32, Int32, Ptr{Uint8}, Ptr{UChar}, Int32, Ptr{UChar}, Int32, Ptr{UErrorCode}),
          tstyle, dstyle, locale, tz_u16.data, length(tz_u16.data), C_NULL, -1, err)
    U_FAILURE(err[1]) && error("bad date format")
    ICUDateFormat(p)
end

close(df::ICUDateFormat) =
    ccall((_udat_close,iculibi18n), Void, (Ptr{Void},), df.ptr)

function format(df::ICUDateFormat, millis::Float64)
    err = UErrorCode[0]
    buflen = 64
    buf = zeros(UChar, buflen)
    len = ccall((_udat_format,iculibi18n), Int32,
          (Ptr{Void}, Float64, Ptr{UChar}, Int32, Ptr{Void}, Ptr{UErrorCode}),
          df.ptr, millis, buf, buflen, C_NULL, err)
    U_FAILURE(err[1]) && error("failed to format time")
    UTF16String(buf[1:len])
end

function parse(df::ICUDateFormat, s::String)
    s16 = utf16(s)
    err = UErrorCode[0]
    ret = ccall((_udat_parse,iculibi18n), Float64,
                (Ptr{Void}, Ptr{UChar}, Int32, Ptr{Int32}, Ptr{UErrorCode}),
                df.ptr, s16.data, length(s16.data), C_NULL, err)
    U_FAILURE(err[1]) && error("failed to parse string")
    ret
end

function test_icucalendar()
    cal = ICUCalendar("America/Los_Angeles")
    setMillis(cal, getNow())
    fields = [UCAL_YEAR, UCAL_MONTH, UCAL_DATE,
              UCAL_HOUR_OF_DAY, UCAL_MINUTE, UCAL_SECOND]
    println(get(cal,fields))
    clear(cal)
    df = ICUDateFormat()
    s = format(df, getNow())
    show(s)
end

## init ##

set_locale(locale)

end # module


text:
# Automatically generated using Clang.jl

const IVIFGEN_MAJOR_VERSION = Int32(5)
const IVIFGEN_MINOR_VERSION = Int32(0)
const IVIFGEN_CLASS_SPEC_MAJOR_VERSION = Int32(5)
const IVIFGEN_CLASS_SPEC_MINOR_VERSION = Int32(0)
const IVIFGEN_DRIVER_VENDOR = "National Instruments"
const IVIFGEN_DRIVER_DESCRIPTION = "IviFgen Class Driver"
const IVIFGEN_ATTR_CACHE = IVI_ATTR_CACHE
const IVIFGEN_ATTR_RANGE_CHECK = IVI_ATTR_RANGE_CHECK
const IVIFGEN_ATTR_QUERY_INSTRUMENT_STATUS = IVI_ATTR_QUERY_INSTRUMENT_STATUS
const IVIFGEN_ATTR_RECORD_COERCIONS = IVI_ATTR_RECORD_COERCIONS
const IVIFGEN_ATTR_SIMULATE = IVI_ATTR_SIMULATE
const IVIFGEN_ATTR_INTERCHANGE_CHECK = IVI_ATTR_INTERCHANGE_CHECK
const IVIFGEN_ATTR_SPY = IVI_ATTR_SPY
const IVIFGEN_ATTR_USE_SPECIFIC_SIMULATION = IVI_ATTR_USE_SPECIFIC_SIMULATION
const IVIFGEN_ATTR_GROUP_CAPABILITIES = IVI_ATTR_GROUP_CAPABILITIES
const IVIFGEN_ATTR_FUNCTION_CAPABILITIES = IVI_ATTR_FUNCTION_CAPABILITIES
const IVIFGEN_ATTR_CLASS_DRIVER_PREFIX = IVI_ATTR_CLASS_DRIVER_PREFIX
const IVIFGEN_ATTR_CLASS_DRIVER_VENDOR = IVI_ATTR_CLASS_DRIVER_VENDOR
const IVIFGEN_ATTR_CLASS_DRIVER_DESCRIPTION = IVI_ATTR_CLASS_DRIVER_DESCRIPTION
const IVIFGEN_ATTR_CLASS_DRIVER_CLASS_SPEC_MAJOR_VERSION = IVI_ATTR_CLASS_DRIVER_CLASS_SPEC_MAJOR_VERSION
const IVIFGEN_ATTR_CLASS_DRIVER_CLASS_SPEC_MINOR_VERSION = IVI_ATTR_CLASS_DRIVER_CLASS_SPEC_MINOR_VERSION
const IVIFGEN_ATTR_SPECIFIC_DRIVER_PREFIX = IVI_ATTR_SPECIFIC_DRIVER_PREFIX
const IVIFGEN_ATTR_SPECIFIC_DRIVER_LOCATOR = IVI_ATTR_SPECIFIC_DRIVER_LOCATOR
const IVIFGEN_ATTR_IO_RESOURCE_DESCRIPTOR = IVI_ATTR_IO_RESOURCE_DESCRIPTOR
const IVIFGEN_ATTR_LOGICAL_NAME = IVI_ATTR_LOGICAL_NAME
const IVIFGEN_ATTR_SPECIFIC_DRIVER_VENDOR = IVI_ATTR_SPECIFIC_DRIVER_VENDOR
const IVIFGEN_ATTR_SPECIFIC_DRIVER_DESCRIPTION = IVI_ATTR_SPECIFIC_DRIVER_DESCRIPTION
const IVIFGEN_ATTR_SPECIFIC_DRIVER_CLASS_SPEC_MAJOR_VERSION = IVI_ATTR_SPECIFIC_DRIVER_CLASS_SPEC_MAJOR_VERSION
const IVIFGEN_ATTR_SPECIFIC_DRIVER_CLASS_SPEC_MINOR_VERSION = IVI_ATTR_SPECIFIC_DRIVER_CLASS_SPEC_MINOR_VERSION
const IVIFGEN_ATTR_INSTRUMENT_FIRMWARE_REVISION = IVI_ATTR_INSTRUMENT_FIRMWARE_REVISION
const IVIFGEN_ATTR_INSTRUMENT_MANUFACTURER = IVI_ATTR_INSTRUMENT_MANUFACTURER
const IVIFGEN_ATTR_INSTRUMENT_MODEL = IVI_ATTR_INSTRUMENT_MODEL
const IVIFGEN_ATTR_SUPPORTED_INSTRUMENT_MODELS = IVI_ATTR_SUPPORTED_INSTRUMENT_MODELS
const IVIFGEN_ATTR_CLASS_DRIVER_REVISION = IVI_ATTR_CLASS_DRIVER_REVISION
const IVIFGEN_ATTR_SPECIFIC_DRIVER_REVISION = IVI_ATTR_SPECIFIC_DRIVER_REVISION
const IVIFGEN_ATTR_DRIVER_SETUP = IVI_ATTR_DRIVER_SETUP
const IVIFGEN_ATTR_CHANNEL_COUNT = IVI_ATTR_CHANNEL_COUNT
const IVIFGEN_ATTR_OUTPUT_MODE = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(1)
const IVIFGEN_ATTR_REF_CLOCK_SOURCE = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(2)
const IVIFGEN_ATTR_OUTPUT_ENABLED = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(3)
const IVIFGEN_ATTR_OUTPUT_IMPEDANCE = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(4)
const IVIFGEN_ATTR_OPERATION_MODE = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(5)
const IVIFGEN_ATTR_SAMPLE_CLOCK_SOURCE = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(21)
const IVIFGEN_ATTR_SAMPLE_CLOCK_OUTPUT_ENABLED = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(22)
const IVIFGEN_ATTR_TERMINAL_CONFIGURATION = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(31)
const IVIFGEN_ATTR_FUNC_WAVEFORM = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(101)
const IVIFGEN_ATTR_FUNC_AMPLITUDE = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(102)
const IVIFGEN_ATTR_FUNC_DC_OFFSET = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(103)
const IVIFGEN_ATTR_FUNC_FREQUENCY = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(104)
const IVIFGEN_ATTR_FUNC_START_PHASE = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(105)
const IVIFGEN_ATTR_FUNC_DUTY_CYCLE_HIGH = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(106)
const IVIFGEN_ATTR_ARB_WAVEFORM_HANDLE = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(201)
const IVIFGEN_ATTR_ARB_GAIN = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(202)
const IVIFGEN_ATTR_ARB_OFFSET = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(203)
const IVIFGEN_ATTR_ARB_SAMPLE_RATE = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(204)
const IVIFGEN_ATTR_MAX_NUM_WAVEFORMS = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(205)
const IVIFGEN_ATTR_WAVEFORM_QUANTUM = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(206)
const IVIFGEN_ATTR_MIN_WAVEFORM_SIZE = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(207)
const IVIFGEN_ATTR_MAX_WAVEFORM_SIZE = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(208)
const IVIFGEN_ATTR_ARB_FREQUENCY = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(209)
const IVIFGEN_ATTR_ARB_SEQUENCE_HANDLE = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(211)
const IVIFGEN_ATTR_MAX_NUM_SEQUENCES = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(212)
const IVIFGEN_ATTR_MIN_SEQUENCE_LENGTH = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(213)
const IVIFGEN_ATTR_MAX_SEQUENCE_LENGTH = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(214)
const IVIFGEN_ATTR_MAX_LOOP_COUNT = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(215)
const IVIFGEN_ATTR_MIN_WAVEFORM_SIZE64 = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(221)
const IVIFGEN_ATTR_MAX_WAVEFORM_SIZE64 = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(222)
const IVIFGEN_ATTR_BINARY_ALIGNMENT = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(241)
const IVIFGEN_ATTR_SAMPLE_BIT_RESOLUTION = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(242)
const IVIFGEN_ATTR_OUTPUT_DATA_MASK = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(261)
const IVIFGEN_ATTR_SEQUENCE_DEPTH_MAX = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(281)
const IVIFGEN_ATTR_TRIGGER_SOURCE = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(302)
const IVIFGEN_ATTR_INTERNAL_TRIGGER_RATE = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(310)
const IVIFGEN_ATTR_START_TRIGGER_DELAY = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(320)
const IVIFGEN_ATTR_START_TRIGGER_SLOPE = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(321)
const IVIFGEN_ATTR_START_TRIGGER_SOURCE = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(322)
const IVIFGEN_ATTR_START_TRIGGER_THRESHOLD = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(323)
const IVIFGEN_ATTR_STOP_TRIGGER_DELAY = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(330)
const IVIFGEN_ATTR_STOP_TRIGGER_SLOPE = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(331)
const IVIFGEN_ATTR_STOP_TRIGGER_SOURCE = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(332)
const IVIFGEN_ATTR_STOP_TRIGGER_THRESHOLD = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(333)
const IVIFGEN_ATTR_HOLD_TRIGGER_DELAY = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(340)
const IVIFGEN_ATTR_HOLD_TRIGGER_SLOPE = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(341)
const IVIFGEN_ATTR_HOLD_TRIGGER_SOURCE = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(342)
const IVIFGEN_ATTR_HOLD_TRIGGER_THRESHOLD = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(343)
const IVIFGEN_ATTR_BURST_COUNT = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(350)
const IVIFGEN_ATTR_RESUME_TRIGGER_DELAY = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(360)
const IVIFGEN_ATTR_RESUME_TRIGGER_SLOPE = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(361)
const IVIFGEN_ATTR_RESUME_TRIGGER_SOURCE = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(362)
const IVIFGEN_ATTR_RESUME_TRIGGER_THRESHOLD = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(363)
const IVIFGEN_ATTR_ADVANCE_TRIGGER_DELAY = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(370)
const IVIFGEN_ATTR_ADVANCE_TRIGGER_SLOPE = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(371)
const IVIFGEN_ATTR_ADVANCE_TRIGGER_SOURCE = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(372)
const IVIFGEN_ATTR_ADVANCE_TRIGGER_THRESHOLD = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(373)
const IVIFGEN_ATTR_AM_ENABLED = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(401)
const IVIFGEN_ATTR_AM_SOURCE = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(402)
const IVIFGEN_ATTR_AM_INTERNAL_DEPTH = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(403)
const IVIFGEN_ATTR_AM_INTERNAL_WAVEFORM = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(404)
const IVIFGEN_ATTR_AM_INTERNAL_FREQUENCY = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(405)
const IVIFGEN_ATTR_FM_ENABLED = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(501)
const IVIFGEN_ATTR_FM_SOURCE = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(502)
const IVIFGEN_ATTR_FM_INTERNAL_DEVIATION = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(503)
const IVIFGEN_ATTR_FM_INTERNAL_WAVEFORM = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(504)
const IVIFGEN_ATTR_FM_INTERNAL_FREQUENCY = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(505)
const IVIFGEN_ATTR_DATAMARKER_AMPLITUDE = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(601)
const IVIFGEN_ATTR_DATAMARKER_BIT_POSITION = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(602)
const IVIFGEN_ATTR_DATAMARKER_COUNT = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(603)
const IVIFGEN_ATTR_DATAMARKER_DELAY = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(604)
const IVIFGEN_ATTR_DATAMARKER_DESTINATION = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(605)
const IVIFGEN_ATTR_DATAMARKER_POLARITY = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(606)
const IVIFGEN_ATTR_DATAMARKER_SOURCE_CHANNEL = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(607)
const IVIFGEN_ATTR_SPARSEMARKER_AMPLITUDE = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(701)
const IVIFGEN_ATTR_SPARSEMARKER_COUNT = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(702)
const IVIFGEN_ATTR_SPARSEMARKER_DELAY = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(703)
const IVIFGEN_ATTR_SPARSEMARKER_DESTINATION = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(704)
const IVIFGEN_ATTR_SPARSEMARKER_POLARITY = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(705)
const IVIFGEN_ATTR_SPARSEMARKER_WFMHANDLE = IVI_CLASS_PUBLIC_ATTR_BASE + Int32(706)
const IVIFGEN_VAL_OUTPUT_FUNC = Int32(0)
const IVIFGEN_VAL_OUTPUT_ARB = Int32(1)
const IVIFGEN_VAL_OUTPUT_SEQ = Int32(2)
const IVIFGEN_VAL_OUT_MODE_CLASS_EXT_BASE = Int32(500)
const IVIFGEN_VAL_OUT_MODE_SPECIFIC_EXT_BASE = Int32(1000)
const IVIFGEN_VAL_OPERATE_CONTINUOUS = Int32(0)
const IVIFGEN_VAL_OPERATE_BURST = Int32(1)
const IVIFGEN_VAL_OP_MODE_CLASS_EXT_BASE = Int32(500)
const IVIFGEN_VAL_OP_MODE_SPECIFIC_EXT_BASE = Int32(1000)
const IVIFGEN_VAL_REF_CLOCK_INTERNAL = Int32(0)
const IVIFGEN_VAL_REF_CLOCK_EXTERNAL = Int32(1)
const IVIFGEN_VAL_REF_CLOCK_RTSI_CLOCK = Int32(101)
const IVIFGEN_VAL_CLK_SRC_CLASS_EXT_BASE = Int32(500)
const IVIFGEN_VAL_CLK_SRC_SPECIFIC_EXT_BASE = Int32(1000)
const IVIFGEN_VAL_WFM_SINE = Int32(1)
const IVIFGEN_VAL_WFM_SQUARE = Int32(2)
const IVIFGEN_VAL_WFM_TRIANGLE = Int32(3)
const IVIFGEN_VAL_WFM_RAMP_UP = Int32(4)
const IVIFGEN_VAL_WFM_RAMP_DOWN = Int32(5)
const IVIFGEN_VAL_WFM_DC = Int32(6)
const IVIFGEN_VAL_WFM_CLASS_EXT_BASE = Int32(500)
const IVIFGEN_VAL_WFM_SPECIFIC_EXT_BASE = Int32(1000)
const IVIFGEN_VAL_EXTERNAL = Int32(1)
const IVIFGEN_VAL_SOFTWARE_TRIG = Int32(2)
const IVIFGEN_VAL_INTERNAL_TRIGGER = Int32(3)
const IVIFGEN_VAL_TTL0 = Int32(111)
const IVIFGEN_VAL_TTL1 = Int32(112)
const IVIFGEN_VAL_TTL2 = Int32(113)
const IVIFGEN_VAL_TTL3 = Int32(114)
const IVIFGEN_VAL_TTL4 = Int32(115)
const IVIFGEN_VAL_TTL5 = Int32(116)
const IVIFGEN_VAL_TTL6 = Int32(117)
const IVIFGEN_VAL_TTL7 = Int32(118)
const IVIFGEN_VAL_ECL0 = Int32(119)
const IVIFGEN_VAL_ECL1 = Int32(120)
const IVIFGEN_VAL_PXI_STAR = Int32(131)
const IVIFGEN_VAL_RTSI_0 = Int32(141)
const IVIFGEN_VAL_RTSI_1 = Int32(142)
const IVIFGEN_VAL_RTSI_2 = Int32(143)
const IVIFGEN_VAL_RTSI_3 = Int32(144)
const IVIFGEN_VAL_RTSI_4 = Int32(145)
const IVIFGEN_VAL_RTSI_5 = Int32(146)
const IVIFGEN_VAL_RTSI_6 = Int32(147)
const IVIFGEN_VAL_TRIG_SRC_CLASS_EXT_BASE = Int32(500)
const IVIFGEN_VAL_TRIG_SRC_SPECIFIC_EXT_BASE = Int32(1000)
const IVIFGEN_VAL_TRIGGER_SOURCE_NONE = ""
const IVIFGEN_VAL_TRIGGER_SOURCE_IMMEDIATE = "Immediate"
const IVIFGEN_VAL_TRIGGER_SOURCE_EXTERNAL = "External"
const IVIFGEN_VAL_TRIGGER_SOURCE_INTERNAL = "Internal"
const IVIFGEN_VAL_TRIGGER_SOURCE_SOFTWARE = "Software"
const IVIFGEN_VAL_TRIGGER_SOURCE_LAN0 = "LAN0"
const IVIFGEN_VAL_TRIGGER_SOURCE_LAN1 = "LAN1"
const IVIFGEN_VAL_TRIGGER_SOURCE_LAN2 = "LAN2"
const IVIFGEN_VAL_TRIGGER_SOURCE_LAN3 = "LAN3"
const IVIFGEN_VAL_TRIGGER_SOURCE_LAN4 = "LAN4"
const IVIFGEN_VAL_TRIGGER_SOURCE_LAN5 = "LAN5"
const IVIFGEN_VAL_TRIGGER_SOURCE_LAN6 = "LAN6"
const IVIFGEN_VAL_TRIGGER_SOURCE_LAN7 = "LAN7"
const IVIFGEN_VAL_TRIGGER_SOURCE_LXI0 = "LXI0"
const IVIFGEN_VAL_TRIGGER_SOURCE_LXI1 = "LXI1"
const IVIFGEN_VAL_TRIGGER_SOURCE_LXI2 = "LXI2"
const IVIFGEN_VAL_TRIGGER_SOURCE_LXI3 = "LXI3"
const IVIFGEN_VAL_TRIGGER_SOURCE_LXI4 = "LXI4"
const IVIFGEN_VAL_TRIGGER_SOURCE_LXI5 = "LXI5"
const IVIFGEN_VAL_TRIGGER_SOURCE_LXI6 = "LXI6"
const IVIFGEN_VAL_TRIGGER_SOURCE_LXI7 = "LXI7"
const IVIFGEN_VAL_TRIGGER_SOURCE_TTL0 = "TTL0"
const IVIFGEN_VAL_TRIGGER_SOURCE_TTL1 = "TTL1"
const IVIFGEN_VAL_TRIGGER_SOURCE_TTL2 = "TTL2"
const IVIFGEN_VAL_TRIGGER_SOURCE_TTL3 = "TTL3"
const IVIFGEN_VAL_TRIGGER_SOURCE_TTL4 = "TTL4"
const IVIFGEN_VAL_TRIGGER_SOURCE_TTL5 = "TTL5"
const IVIFGEN_VAL_TRIGGER_SOURCE_TTL6 = "TTL6"
const IVIFGEN_VAL_TRIGGER_SOURCE_TTL7 = "TTL7"
const IVIFGEN_VAL_TRIGGER_SOURCE_PXI_STAR = "PXI_STAR"
const IVIFGEN_VAL_TRIGGER_SOURCE_PXI_TRIG0 = "PXI_TRIG0"
const IVIFGEN_VAL_TRIGGER_SOURCE_PXI_TRIG1 = "PXI_TRIG1"
const IVIFGEN_VAL_TRIGGER_SOURCE_PXI_TRIG2 = "PXI_TRIG2"
const IVIFGEN_VAL_TRIGGER_SOURCE_PXI_TRIG3 = "PXI_TRIG3"
const IVIFGEN_VAL_TRIGGER_SOURCE_PXI_TRIG4 = "PXI_TRIG4"
const IVIFGEN_VAL_TRIGGER_SOURCE_PXI_TRIG5 = "PXI_TRIG5"
const IVIFGEN_VAL_TRIGGER_SOURCE_PXI_TRIG6 = "PXI_TRIG6"
const IVIFGEN_VAL_TRIGGER_SOURCE_PXI_TRIG7 = "PXI_TRIG7"
const IVIFGEN_VAL_TRIGGER_SOURCE_PXIE_DSTARA = "PXIe_DSTARA"
const IVIFGEN_VAL_TRIGGER_SOURCE_PXIE_DSTARB = "PXIe_DSTARB"
const IVIFGEN_VAL_TRIGGER_SOURCE_PXIE_DSTARC = "PXIe_DSTARC"
const IVIFGEN_VAL_TRIGGER_SOURCE_RTSI0 = "RTSI0"
const IVIFGEN_VAL_TRIGGER_SOURCE_RTSI1 = "RTSI1"
const IVIFGEN_VAL_TRIGGER_SOURCE_RTSI2 = "RTSI2"
const IVIFGEN_VAL_TRIGGER_SOURCE_RTSI3 = "RTSI3"
const IVIFGEN_VAL_TRIGGER_SOURCE_RTSI4 = "RTSI4"
const IVIFGEN_VAL_TRIGGER_SOURCE_RTSI5 = "RTSI5"
const IVIFGEN_VAL_TRIGGER_SOURCE_RTSI6 = "RTSI6"
const IVIFGEN_VAL_SAMPLE_CLOCK_SOURCE_INTERNAL = Int32(0)
const IVIFGEN_VAL_SAMPLE_CLOCK_SOURCE_EXTERNAL = Int32(1)
const IVIFGEN_VAL_MARKER_POLARITY_ACTIVE_HIGH = Int32(0)
const IVIFGEN_VAL_MARKER_POLARITY_ACTIVE_LOW = Int32(1)
const IVIFGEN_VAL_AM_INTERNAL = Int32(0)
const IVIFGEN_VAL_AM_EXTERNAL = Int32(1)
const IVIFGEN_VAL_AM_SOURCE_CLASS_EXT_BASE = Int32(500)
const IVIFGEN_VAL_AM_SOURCE_SPECIFIC_EXT_BASE = Int32(1000)
const IVIFGEN_VAL_AM_INTERNAL_SINE = Int32(1)
const IVIFGEN_VAL_AM_INTERNAL_SQUARE = Int32(2)
const IVIFGEN_VAL_AM_INTERNAL_TRIANGLE = Int32(3)
const IVIFGEN_VAL_AM_INTERNAL_RAMP_UP = Int32(4)
const IVIFGEN_VAL_AM_INTERNAL_RAMP_DOWN = Int32(5)
const IVIFGEN_VAL_AM_INTERNAL_WFM_CLASS_EXT_BASE = Int32(500)
const IVIFGEN_VAL_AM_INTERNAL_WFM_SPECIFIC_EXT_BASE = Int32(1000)
const IVIFGEN_VAL_FM_INTERNAL = Int32(0)
const IVIFGEN_VAL_FM_EXTERNAL = Int32(1)
const IVIFGEN_VAL_FM_SOURCE_CLASS_EXT_BASE = Int32(500)
const IVIFGEN_VAL_FM_SOURCE_SPECIFIC_EXT_BASE = Int32(1000)
const IVIFGEN_VAL_FM_INTERNAL_SINE = Int32(1)
const IVIFGEN_VAL_FM_INTERNAL_SQUARE = Int32(2)
const IVIFGEN_VAL_FM_INTERNAL_TRIANGLE = Int32(3)
const IVIFGEN_VAL_FM_INTERNAL_RAMP_UP = Int32(4)
const IVIFGEN_VAL_FM_INTERNAL_RAMP_DOWN = Int32(5)
const IVIFGEN_VAL_FM_INTERNAL_WFM_CLASS_EXT_BASE = Int32(500)
const IVIFGEN_VAL_FM_INTERNAL_WFM_SPECIFIC_EXT_BASE = Int32(1000)
const IVIFGEN_VAL_BINARY_ALIGNMENT_LEFT = Int32(0)
const IVIFGEN_VAL_BINARY_ALIGNMENT_RIGHT = Int32(1)
const IVIFGEN_VAL_BINARY_ALIGNMENT_CLASS_EXT_BASE = Int32(500)
const IVIFGEN_VAL_BINARY_ALIGNMENT_SPECIFIC_EXT_BASE = Int32(1000)
const IVIFGEN_VAL_TERMINAL_CONFIGURATION_SINGLE_ENDED = Int32(0)
const IVIFGEN_VAL_TERMINAL_CONFIGURATION_DIFFERENTIAL = Int32(1)
const IVIFGEN_VAL_TERMINAL_CONFIGURATION_CLASS_EXT_BASE = Int32(500)
const IVIFGEN_VAL_TERMINAL_CONFIGURATION_SPECIFIC_EXT_BASE = Int32(1000)
const IVIFGEN_VAL_TRIGGER_POSITIVE = Int32(0)
const IVIFGEN_VAL_TRIGGER_NEGATIVE = Int32(1)
const IVIFGEN_VAL_TRIGGER_EITHER = Int32(2)
const IVIFGEN_VAL_TRIGGER_CLASS_EXT_BASE = Int32(500)
const IVIFGEN_VAL_TRIGGER_SPECIFIC_EXT_BASE = Int32(1000)
const IVIFGEN_VAL_ALL_WAVEFORMS = -(Int32(1))
const IVIFGEN_VAL_ALL_SEQUENCES = -(Int32(1))
const IVIFGEN_ERROR_NO_WFMS_AVAILABLE = IVI_CLASS_ERROR_BASE + Int32(4)
const IVIFGEN_ERROR_WFM_IN_USE = IVI_CLASS_ERROR_BASE + Int32(8)
const IVIFGEN_ERROR_NO_SEQS_AVAILABLE = IVI_CLASS_ERROR_BASE + Int32(9)
const IVIFGEN_ERROR_SEQ_IN_USE = IVI_CLASS_ERROR_BASE + Int32(13)
const IVIFGEN_ERROR_INVALID_WFM_CHANNEL = IVI_CLASS_ERROR_BASE + Int32(14)
const IVIFGEN_ERROR_TRIGGER_NOT_SOFTWARE = IVI_CROSS_CLASS_ERROR_BASE + Int32(1)
const IVIFGEN_ERRMSG_NO_WFMS_AVAILABLE = "The function generator's waveform memory is full."
const IVIFGEN_ERRMSG_WFM_IN_USE = "The waveform is currently in use."
const IVIFGEN_ERRMSG_NO_SEQS_AVAILABLE = "The function generator's sequence memory is full."
const IVIFGEN_ERRMSG_SEQ_IN_USE = "The sequence is currently in use."
const IVIFGEN_ERRMSG_INVALID_WFM_CHANNEL = "The waveform was created on a different channel than the one for which it is being configured."
const IVIFGEN_ERRMSG_TRIGGER_NOT_SOFTWARE = "The trigger source is not set to software trigger."

# Skipping MacroDefinition: IVIFGEN_ERROR_CODES_AND_MSGS { IVIFGEN_ERROR_NO_WFMS_AVAILABLE , IVIFGEN_ERRMSG_NO_WFMS_AVAILABLE } , { IVIFGEN_ERROR_WFM_IN_USE , IVIFGEN_ERRMSG_WFM_IN_USE } , { IVIFGEN_ERROR_NO_SEQS_AVAILABLE , IVIFGEN_ERRMSG_NO_SEQS_AVAILABLE } , { IVIFGEN_ERROR_SEQ_IN_USE , IVIFGEN_ERRMSG_SEQ_IN_USE } , { IVIFGEN_ERROR_INVALID_WFM_CHANNEL , IVIFGEN_ERRMSG_INVALID_WFM_CHANNEL } , { IVIFGEN_ERROR_TRIGGER_NOT_SOFTWARE , IVIFGEN_ERRMSG_TRIGGER_NOT_SOFTWARE }

ext: jl


text:
using Markdown
using Latexify

arr = ["x/(y-1)", 1.0, 3//2, :(x-y), :symb]

M = vcat(hcat(arr...), hcat(arr...))
head = ["col$i" for i in 1:size(M, 2)]
side = ["row$i" for i in 1:size(M, 1)]

@test mdtable(arr) == Markdown.md"
| $\frac{x}{y - 1}$ |
| -----------------:|
|             $1.0$ |
|     $\frac{3}{2}$ |
|           $x - y$ |
|            $symb$ |
"

@test mdtable(arr; head = ["head"]) == Markdown.md"
|              head |
| -----------------:|
| $\frac{x}{y - 1}$ |
|             $1.0$ |
|     $\frac{3}{2}$ |
|           $x - y$ |
|            $symb$ |
"

@test mdtable(arr; head = ["head"], side=1:length(arr)) == Markdown.md"
|   ∘ |              head |
| ---:| -----------------:|
|   1 | $\frac{x}{y - 1}$ |
|   2 |             $1.0$ |
|   3 |     $\frac{3}{2}$ |
|   4 |           $x - y$ |
|   5 |            $symb$ |
"

@test mdtable(arr; head = ["head"], side=1:length(arr)+1) == Markdown.md"
|   1 |              head |
| ---:| -----------------:|
|   2 | $\frac{x}{y - 1}$ |
|   3 |             $1.0$ |
|   4 |     $\frac{3}{2}$ |
|   5 |           $x - y$ |
|   6 |            $symb$ |
"

@test mdtable(arr, arr) == Markdown.md"
| $\frac{x}{y - 1}$ | $\frac{x}{y - 1}$ |
| -----------------:| -----------------:|
|             $1.0$ |             $1.0$ |
|     $\frac{3}{2}$ |     $\frac{3}{2}$ |
|           $x - y$ |           $x - y$ |
|            $symb$ |            $symb$ |
"

@test mdtable(arr, arr; head = ["col1", "col2"]) == Markdown.md"
|              col1 |              col2 |
| -----------------:| -----------------:|
| $\frac{x}{y - 1}$ | $\frac{x}{y - 1}$ |
|             $1.0$ |             $1.0$ |
|     $\frac{3}{2}$ |     $\frac{3}{2}$ |
|           $x - y$ |           $x - y$ |
|            $symb$ |            $symb$ |
"

@test mdtable(M) == Markdown.md"
| $\frac{x}{y - 1}$ | $1.0$ | $\frac{3}{2}$ | $x - y$ | $symb$ |
| -----------------:| -----:| -------------:| -------:| ------:|
| $\frac{x}{y - 1}$ | $1.0$ | $\frac{3}{2}$ | $x - y$ | $symb$ |
"

@test mdtable(M, head=head) == Markdown.md"
|              col1 |  col2 |          col3 |    col4 |   col5 |
| -----------------:| -----:| -------------:| -------:| ------:|
| $\frac{x}{y - 1}$ | $1.0$ | $\frac{3}{2}$ | $x - y$ | $symb$ |
| $\frac{x}{y - 1}$ | $1.0$ | $\frac{3}{2}$ | $x - y$ | $symb$ |
"

@test mdtable(M, head=head, side=side) == Markdown.md"
|    ∘ |              col1 |  col2 |          col3 |    col4 |   col5 |
| ----:| -----------------:| -----:| -------------:| -------:| ------:|
| row1 | $\frac{x}{y - 1}$ | $1.0$ | $\frac{3}{2}$ | $x - y$ | $symb$ |
| row2 | $\frac{x}{y - 1}$ | $1.0$ | $\frac{3}{2}$ | $x - y$ | $symb$ |
"

@test mdtable(M, head=side, side=head, transpose=true) == Markdown.md"
|    ∘ |              row1 |              row2 |
| ----:| -----------------:| -----------------:|
| col1 | $\frac{x}{y - 1}$ | $\frac{x}{y - 1}$ |
| col2 |             $1.0$ |             $1.0$ |
| col3 |     $\frac{3}{2}$ |     $\frac{3}{2}$ |
| col4 |           $x - y$ |           $x - y$ |
| col5 |            $symb$ |            $symb$ |
"

m = ["one_two_tree"; "four_five_six"; "seven_eight"]
@test latexify(m; env=:mdtable, latex=false, escape_underscores=true) == Markdown.md"
|  one\_two\_tree |
| -------------:|
| four\_five\_six |
|   seven_eight |
"

using DataFrames
d = DataFrame(A = 11:13, B = [:X, :Y, :Z])

@test latexify(d; env=:mdtable, side=1:3) == Markdown.md"
|   ∘ |    A |   B |
| ---:| ----:| ---:|
|   1 | $11$ | $X$ |
|   2 | $12$ | $Y$ |
|   3 | $13$ | $Z$ |
"

@test latexify(d; env=:mdtable) == Markdown.md"
|    A |   B |
| ----:| ---:|
| $11$ | $X$ |
| $12$ | $Y$ |
| $13$ | $Z$ |
"

@test latexify(((1.0, 2), (3, 4)); env=:mdtable) == Markdown.md"
| $1.0$ | $3$ |
| -----:| ---:|
|   $2$ | $4$ |
"

# @test_throws MethodError mdtable(M; bad_kwarg="should error")


text:
using CSV
using DataFrames

fn = ARGS[1]

data = DataFrame(CSV.File(fn))

constcols = [c for c in names(data) if all(coalesce.(data[!,c],"") .== coalesce(data[1,c],""))]
constvals = [c => data[1,c] for c in constcols]
select!(data, Not(constcols))

table = String[]

colname_cvt = Dict("N" => "N", "method" => "Method", "time" => "Time", "obj" => "Objective", "ratio" => "\$\\alpha\$")
header = [haskey(colname_cvt, c) ? colname_cvt[c] : c for c in names(data)]
header_str = foldl((a,b) -> a * " & " * b, header) * " \\\\\n"
push!(table, header_str)
push!(table, "\\hline\n")

method_lookup = Dict(
	"opt" => "Quadratic Programming",
	"lin" => "Linearization",
	"lpr" => "LP + Rounding",
	"faq" => "FAQ",
	"rand" => "Random Search",
	"mms" => "MMS",
	"ns" => "NS",
	"star" => "Common Star Packing",
	"dense" => "Dense Subgraph Mapping",
)

fmt(v::String, m) = (m == "method") ? method_lookup[v] : v
fmt(v::Int, m) = string(v)
fmt(v::Float64, m) = (v < 100) ? string(round(v, sigdigits=4)) : string(round(v, digits=2))

for row in eachrow(data)
	s = [fmt(row[c],c) for c in names(data)]
	line = foldl((a,b) -> a * " & " * b, s) * " \\\\\n"
	push!(table, line)
end

table_str = foldl(*, table)

println("Params:")
println(constvals)

println("Table:")
print(table_str)


text:
function Krest(r)
    for side in 0:3
        GoToTheWallAndMark(r, HorizonSide(side))
    end
end

function GoToTheWallAndMark(r::Robot, side::HorizonSide)
    x = 0
    while isborder(r, side) != true
        putmarker!(r)
        move!(r, side)
        x = x + 1
    end
    putmarker!(r)
    while x != 0
        move!(r, HorizonSide((Int(side) + 2) % 4))
        x = x - 1
    end
end


text:
using CSV
using DataFrames
using Land
using Land.CanopyLayers
using Land.Photosynthesis
using Land.PlantHydraulics
using Land.SoilPlantAirContinuum
using Land.StomataModels
using Pkg.Artifacts
using PkgUtility
using Test

ENV["JULIA_LOG_LEVEL"] = "WARN"

include("test_CanopyLayers.jl"   )
include("test_Photosynthesis.jl" )
include("test_PlantHydraulics.jl")
include("test_StomataModels.jl"  )
include("test_SPAC.jl"           )
include("test_Land.jl"           )

max_stars_repo_name: bbuman/Land

max_issues_repo_name: bbuman/Land

max_forks_repo_name: bbuman/Land


text:
using LogGaussianCoxProcessWithLaplaceApproximation
using PointPatternStatistics
using Distributions: logpdf
using Test

@testset "LogGaussianCoxProcessWithLaplaceApproximation.jl" begin
    win = (x=(0, 40), y=(0, 40))
    di = Discretization(0.1:0.2:39.9, win)
    xy = [(40*rand(), 40*rand()) for _ in 1:1000]
    pp = PointPattern(xy, win)
    @test isfinite(logpdf(LogGaussianCoxProcess(2, 1.5, 2.3, randn(200, 200)), di, pp))
    @test rand(LogGaussianCoxProcess(2, 1.5, 2.3, randn(200, 200)), di) isa PointPattern
end


text:
"""
Abstract type for a subsystem that contains multiple instances of StaticInjection

Subtypes must implement:
- get_subcomponents(subsystem::StaticInjectionSubsystem)

The subcomponents in subtypes must be attached to the System as masked components.
"""
abstract type StaticInjectionSubsystem <: StaticInjection end

"""
Efficiently add all time series data in the subcomponent to the subsystem by copying the
underlying references.
"""
function copy_subcomponent_time_series!(
    subsystem::StaticInjectionSubsystem,
    subcomponent::Component,
)
    existing_ts = Set((typeof(x), get_name(x)) for x in get_time_series_multiple(subsystem))
    name_mapping = Dict{String, String}()
    for ts in get_time_series_multiple(subcomponent)
        name = get_name(ts)
        key = (typeof(ts), name)
        if !(key in existing_ts)
            new_name = make_subsystem_time_series_name(subcomponent, ts)
            if name in keys(name_mapping)
                IS.@assert_op new_name == name_mapping[name]
                continue
            end
            name_mapping[name] = new_name
        end
    end

    copy_time_series!(subsystem, subcomponent, name_mapping = name_mapping)
    @info "Copied time series from $(summary(subcomponent)) to $(summary(subsystem))"
end

function make_subsystem_time_series_name(subcomponent::Component, ts::TimeSeriesData)
    return IS.strip_module_name(typeof(subcomponent)) * "__" * get_name(ts)
end


text:
@testset "Meshes" begin
  @testset "CartesianGrid" begin
    @test isgrid(CartesianGrid{1,T})
    @test isgrid(CartesianGrid{2,T})
    @test isgrid(CartesianGrid{3,T})

    grid = CartesianGrid{T}(100)
    @test embeddim(grid) == 1
    @test coordtype(grid) == T
    @test size(grid) == (100,)
    @test minimum(grid) == P1(0)
    @test maximum(grid) == P1(100)
    @test extrema(grid) == (P1(0), P1(100))
    @test spacing(grid) == T[1]
    @test nelements(grid) == 100
    @test eltype(grid) <: Segment{1,T}
    @test measure(grid) ≈ T(100)

    grid = CartesianGrid{T}(200,100)
    @test embeddim(grid) == 2
    @test coordtype(grid) == T
    @test size(grid) == (200, 100)
    @test minimum(grid) == P2(0, 0)
    @test maximum(grid) == P2(200, 100)
    @test extrema(grid) == (P2(0, 0), P2(200, 100))
    @test spacing(grid) == T[1, 1]
    @test nelements(grid) == 200*100
    @test eltype(grid) <: Quadrangle{2,T}
    @test measure(grid) ≈ T(200*100)

    grid = CartesianGrid((200,100,50), T.((0,0,0)), T.((1,1,1)))
    @test embeddim(grid) == 3
    @test coordtype(grid) == T
    @test size(grid) == (200, 100, 50)
    @test minimum(grid) == P3(0, 0, 0)
    @test maximum(grid) == P3(200, 100, 50)
    @test extrema(grid) == (P3(0, 0, 0), P3(200, 100, 50))
    @test spacing(grid) == T[1, 1, 1]
    @test nelements(grid) == 200*100*50
    @test eltype(grid) <: Hexahedron{3,T}
    @test measure(grid) ≈ T(200*100*50)

    grid = CartesianGrid(T.((0,0,0)), T.((1,1,1)), T.((0.1,0.1,0.1)))
    @test embeddim(grid) == 3
    @test coordtype(grid) == T
    @test size(grid) == (10, 10, 10)
    @test minimum(grid) == P3(0, 0, 0)
    @test maximum(grid) == P3(1, 1, 1)
    @test spacing(grid) == T[0.1, 0.1, 0.1]

    grid = CartesianGrid(T.((-1.,-1.)), T.((1.,1.)), dims=(200,100))
    @test embeddim(grid) == 2
    @test coordtype(grid) == T
    @test size(grid) == (200, 100)
    @test minimum(grid) == P2(-1., -1.)
    @test maximum(grid) == P2(1., 1.)
    @test spacing(grid) == T[2/200, 2/100]
    @test nelements(grid) == 200*100
    @test eltype(grid) <: Quadrangle{2,T}

    grid = CartesianGrid((20,10,5), T.((0,0,0)), T.((5,5,5)))
    @test embeddim(grid) == 3
    @test coordtype(grid) == T
    @test size(grid) == (20, 10, 5)
    @test minimum(grid) == P3(0, 0, 0)
    @test maximum(grid) == P3(100, 50, 25)
    @test extrema(grid) == (P3(0, 0, 0), P3(100, 50, 25))
    @test spacing(grid) == T[5, 5, 5]
    @test nelements(grid) == 20*10*5
    @test eltype(grid) <: Hexahedron{3,T}
    @test vertices(grid[1]) == P3[(0, 0, 0), (5, 0, 0), (5, 5, 0), (0, 5, 0), (0, 0, 5), (5, 0, 5), (5, 5, 5), (0, 5, 5)]
    @test all(centroid(grid, i) == centroid(grid[i]) for i in 1:nelements(grid))

    # indexing into a subgrid
    grid = CartesianGrid{T}(10,10)
    sub  = grid[1:2,1:2]
    @test size(sub) == (2,2)
    @test spacing(sub) == spacing(grid)
    @test minimum(sub) == minimum(grid)
    @test maximum(sub) == P2(2,2)
    sub  = grid[1:1,2:3]
    @test size(sub) == (1,2)
    @test spacing(sub) == spacing(grid)
    @test minimum(sub) == P2(0,1)
    @test maximum(sub) == P2(1,3)
    sub  = grid[2:4,3:7]
    @test size(sub) == (3,5)
    @test spacing(sub) == spacing(grid)
    @test minimum(sub) == P2(1,2)
    @test maximum(sub) == P2(4,7)
    grid = CartesianGrid(P2(1,1), P2(11,11), dims=(10,10))
    sub = grid[2:4,3:7]
    @test size(sub) == (3,5)
    @test spacing(sub) == spacing(grid)
    @test minimum(sub) == P2(2,3)
    @test maximum(sub) == P2(5,8)

    # subgrid from Cartesian ranges
    grid = CartesianGrid{T}(10,10)
    sub1 = grid[1:2,4:6]
    sub2 = grid[CartesianIndex(1,4):CartesianIndex(2,6)]
    @test sub1 == sub2

    grid = CartesianGrid{T}(200,100)
    @test centroid(grid, 1) == P2(0.5, 0.5)
    @test centroid(grid, 2) == P2(1.5, 0.5)
    @test centroid(grid, 200*100) == P2(199.5, 99.5)
    @test nelements(grid) == 200*100
    @test eltype(grid) <: Quadrangle{2,T}
    @test grid[1] == Quadrangle(P2[(0,0), (1,0), (1,1), (0,1)])
    @test grid[2] == Quadrangle(P2[(1,0), (2,0), (2,1), (1,1)])

    # GridTopology from CartesianGrid
    grid = CartesianGrid{T}(5,5)
    topo = topology(grid)
    vs = collect(vertices(grid))
    for i in 1:nelements(grid)
      inds = indices(element(topo, i))
      @test vs[[inds...]] == vertices(element(grid, i))
    end

    # convert topology
    grid = CartesianGrid{T}(10,10)
    mesh = topoconvert(HalfEdgeTopology, grid)
    @test mesh isa SimpleMesh
    @test nvertices(mesh) == 121
    @test nelements(mesh) == 100
    @test eltype(mesh) <: Quadrangle

    grid = CartesianGrid{T}(200,100)
    if T == Float32
      @test sprint(show, MIME"text/plain"(), grid) == "200×100 CartesianGrid{2,Float32}\n  minimum: Point(0.0f0, 0.0f0)\n  maximum: Point(200.0f0, 100.0f0)\n  spacing: (1.0f0, 1.0f0)"
    elseif T == Float64
      @test sprint(show, MIME"text/plain"(), grid) == "200×100 CartesianGrid{2,Float64}\n  minimum: Point(0.0, 0.0)\n  maximum: Point(200.0, 100.0)\n  spacing: (1.0, 1.0)"
    end

    if visualtests
      @test_reference "data/grid-1D-$T.png" plot(CartesianGrid{T}(10))
      @test_reference "data/grid-2D-$T.png" plot(CartesianGrid{T}(10,20))
      @test_reference "data/grid-3D-$T.png" plot(CartesianGrid{T}(10,20,30))
      @test_reference "data/grid-1D-$T-data.png" plot(CartesianGrid{T}(10),[1,2,3,4,5,5,4,3,2,1])
      @test_reference "data/grid-2D-$T-data.png" plot(CartesianGrid{T}(10,10),1:100)
      # @test_reference "data/grid3D-data.png" plot(RegularGrid(10,10,10),1:1000)
    end
  end

  @testset "SimpleMesh" begin
    @test !isgrid(SimpleMesh)

    points = P2[(0,0), (1,0), (0,1), (1,1), (0.5,0.5)]
    connec = connect.([(1,2,5),(2,4,5),(4,3,5),(3,1,5)], Triangle)
    mesh = SimpleMesh(points, connec)
    triangles = Triangle.([
      P2[(0.0,0.0), (1.0,0.0), (0.5,0.5)],
      P2[(1.0,0.0), (1.0,1.0), (0.5,0.5)],
      P2[(1.0,1.0), (0.0,1.0), (0.5,0.5)],
      P2[(0.0,1.0), (0.0,0.0), (0.5,0.5)]
    ])
    @test vertices(mesh) == points
    @test collect(faces(mesh, 2)) == triangles
    @test collect(elements(mesh)) == triangles
    @test nelements(mesh) == 4
    for i in 1:length(triangles)
      @test mesh[i] == triangles[i]
    end
    @test eltype(mesh) <: Triangle{2,T}
    @test measure(mesh) ≈ T(1)

    points = P2[(0,0), (1,0), (0,1), (1,1), (0.25,0.5), (0.75,0.5)]
    Δs = connect.([(3,1,5),(4,6,2)], Triangle)
    □s = connect.([(1,2,6,5),(5,6,4,3)], Quadrangle)
    mesh = SimpleMesh(points, [Δs; □s])
    elms = [
      Triangle(P2[(0.0,1.0), (0.0,0.0), (0.25,0.5)]),
      Triangle(P2[(1.0,1.0), (0.75,0.5), (1.0,0.0)]),
      Quadrangle(P2[(0.0,0.0), (1.0,0.0), (0.75,0.5), (0.25,0.5)]),
      Quadrangle(P2[(0.25,0.5), (0.75,0.5), (1.0,1.0), (0.0,1.0)])
    ]
    @test collect(elements(mesh)) == elms
    @test nelements(mesh) == 4
    for i in 1:length(elms)
      @test mesh[i] == elms[i]
    end
    @test eltype(mesh) <: Polygon{2,T}

    # test for https://github.com/JuliaGeometry/Meshes.jl/issues/177
    points = P3[(0,0,0),(1,0,0),(1,1,1),(0,1,0)]
    connec = connect.([(1,2,3,4),(3,4,1)], [Tetrahedron, Triangle])
    mesh = SimpleMesh(points, connec)
    topo = topology(mesh)
    @test collect(faces(topo, 2)) == [connect((3,4,1), Triangle)]
    @test collect(faces(topo, 3)) == [connect((1,2,3,4), Tetrahedron)]

    # test for https://github.com/JuliaGeometry/Meshes.jl/issues/187
    points  = P3[(0,0,0),(1,0,0),(1,1,1),(0,1,0)]
    connec  = connect.([(1,2,3,4),(3,4,1)], [Tetrahedron, Triangle])
    mesh    = SimpleMesh(points[4:-1:1], connec)
    meshvp  = SimpleMesh(view(points, 4:-1:1), connec)
    @test mesh == meshvp

    points = P2[(0,0), (1,0), (0,1), (1,1), (0.5,0.5)]
    connec = connect.([(1,2,5),(2,4,5),(4,3,5),(3,1,5)], Triangle)
    mesh = SimpleMesh(points, connec)
    bytes = @allocated faces(mesh, 2)
    @test bytes < 100
    cells = faces(mesh, 2)
    bytes = @allocated collect(cells)
    @test bytes < 800

    points = P2[(0,0), (1,0), (0,1), (1,1), (0.5,0.5)]
    connec = connect.([(1,2,5),(2,4,5),(4,3,5),(3,1,5)], Triangle)
    mesh = SimpleMesh(points, connec)
    @test centroid(mesh, 1) == centroid(Triangle(P2[(0,0), (1,0), (0.5,0.5)]))
    @test centroid(mesh, 2) == centroid(Triangle(P2[(1,0), (1,1), (0.5,0.5)]))
    @test centroid(mesh, 3) == centroid(Triangle(P2[(1,1), (0,1), (0.5,0.5)]))
    @test centroid(mesh, 4) == centroid(Triangle(P2[(0,1), (0,0), (0.5,0.5)]))

    # merge operation
    mesh₁ = SimpleMesh(P2[(0,0), (1,0), (0,1)], connect.([(1,2,3)]))
    mesh₂ = SimpleMesh(P2[(1,0), (1,1), (0,1)], connect.([(1,2,3)]))
    mesh  = merge(mesh₁, mesh₂)
    @test vertices(mesh) == [vertices(mesh₁); vertices(mesh₂)]
    @test collect(elements(topology(mesh))) == connect.([(1,2,3),(4,5,6)])

    # convert any mesh to SimpleMesh
    grid = CartesianGrid{T}(10,10)
    mesh = convert(SimpleMesh, grid)
    @test mesh isa SimpleMesh
    @test topology(mesh) == GridTopology(10,10)
    @test nvertices(mesh) == 121
    @test nelements(mesh) == 100
    @test eltype(mesh) <: Quadrangle

    points = P2[(0,0), (1,0), (0,1), (1,1), (0.5,0.5)]
    connec = connect.([(1,2,5),(2,4,5),(4,3,5),(3,1,5)], Triangle)
    mesh = SimpleMesh(points, connec)
    if T == Float32
      @test sprint(show, MIME"text/plain"(), mesh) == "4 SimpleMesh{2,Float32}\n  5 vertices\n    └─Point(0.0f0, 0.0f0)\n    └─Point(1.0f0, 0.0f0)\n    └─Point(0.0f0, 1.0f0)\n    └─Point(1.0f0, 1.0f0)\n    └─Point(0.5f0, 0.5f0)\n  4 elements\n    └─Triangle(1, 2, 5)\n    └─Triangle(2, 4, 5)\n    └─Triangle(4, 3, 5)\n    └─Triangle(3, 1, 5)"
    elseif T == Float64
      @test sprint(show, MIME"text/plain"(), mesh) == "4 SimpleMesh{2,Float64}\n  5 vertices\n    └─Point(0.0, 0.0)\n    └─Point(1.0, 0.0)\n    └─Point(0.0, 1.0)\n    └─Point(1.0, 1.0)\n    └─Point(0.5, 0.5)\n  4 elements\n    └─Triangle(1, 2, 5)\n    └─Triangle(2, 4, 5)\n    └─Triangle(4, 3, 5)\n    └─Triangle(3, 1, 5)"
    end
  end
end


text:
l1, l2, l3 = Leaf.([1, 2, 3])
n1nt = NTVertex(1, (a = l1, c = l3, b = l2))
n2nt = NTVertex(2, (c = l3, a = l1))
n3nt = (b = l2, c = l3)
n4nt = NTVertex(4, (b = l2,))
n5nt = NamedTuple()
n1d = Dict("a" => l1, "c" => l3, "b" => l2)
n2d = Dict("c" => l3, "a" => l1)
n3d = Dict("c" => l3, "b" => l2)
n4d = Dict("b" => l2)
n5d = Dict()
n1pv = VectorVertex(1, [l1, l2, l3])
n2pv = [3 => l3, 1 => l1]
n3pv = [3 => l3, 2 => l2]
n4pv = [2 => l2]
n5pv = Pair[]
n1v = [l1, l2, l3]
n2v = BinaryVertex(2, l1, l3)
n3v = [l2]
n4v = []
n1t = (l1, l2, l3)
n2t = (l1, l3)
n3t = SingletonVertex(2, l2)
n4t = ()

@testset "NamedTuple children pairing" begin
    @test _children_pairs((n1nt, n2nt), false) == (a = (l1, l1), c = (l3, l3))
    @test _children_pairs((n1nt, n2nt), true) == (a = (l1, l1), b = (l2, nothing), c = (l3, l3))

    @test _children_pairs((n1nt, n3nt), false) == (b = (l2, l2), c = (l3, l3))
    @test _children_pairs((n1nt, n3nt), true) == (a = (l1, nothing), b = (l2, l2), c = (l3, l3))
    @test _children_pairs((n3nt, n1nt), true) == (a = (nothing, l1), b = (l2, l2), c = (l3, l3))

    @test _children_pairs((n1nt, n4nt), false) == (b = (l2, l2),)
    @test _children_pairs((n1nt, n4nt), true) == (a = (l1, nothing), b = (l2, l2), c = (l3, nothing))

    @test _children_pairs((n1nt, n2nt, n3nt), false) == (c = (l3, l3, l3),)
    @test _children_pairs((n1nt, n2nt, n3nt), true) == (a = (l1, l1, nothing), b = (l2, nothing, l2), c = (l3, l3, l3))

    @test _children_pairs((n1nt, n2nt, n3nt, n4nt), false) == NamedTuple()
    @test _children_pairs((n1nt, n2nt, n3nt, n4nt), true) == (a = (l1, l1, nothing, nothing), b = (l2, nothing, l2, l2), c = (l3, l3, l3, nothing))

    for n in [n1nt, n2nt, n3nt, n4nt]
        @test _children_pairs((n, n5nt, nothing), false) == NamedTuple()
        @test _children_pairs((n, nothing), false) == NamedTuple()
        @test _children_pairs((n, n5nt), false) == NamedTuple()
        res = (; (Symbol(k) => (ch, nothing, nothing) for (k,ch) in _childsort(children(n)) |> pairs)...)
        @test _children_pairs((n, n5nt, nothing), true) == res
        res = (; (Symbol(k) => (ch, nothing) for (k,ch) in _childsort(children(n)) |> pairs)...)
        @test _children_pairs((n, nothing), true) == res
        @test _children_pairs((n, n5nt), true) == res
    end
end

@testset "Dict children pairing" begin
    @test _children_pairs((n1d, n2d), false) == OrderedDict("a" => (l1, l1), "c" => (l3, l3))
    @test _children_pairs((n1d, n2d), true) == OrderedDict("a" => (l1, l1), "b" => (l2, nothing), "c" => (l3, l3))

    @test _children_pairs((n1d, n3d), false) == OrderedDict("b" => (l2, l2), "c" => (l3, l3))
    @test _children_pairs((n1d, n3d), true) == OrderedDict("a" => (l1, nothing), "b" => (l2, l2), "c" => (l3, l3))
    @test _children_pairs((n3d, n1d), true) == OrderedDict("a" => (nothing, l1), "b" => (l2, l2), "c" => (l3, l3))

    @test _children_pairs((n1d, n4d), false) == OrderedDict("b" => (l2, l2),)
    @test _children_pairs((n1d, n4d), true) == OrderedDict("a" => (l1, nothing), "b" => (l2, l2), "c" => (l3, nothing))

    @test _children_pairs((n1d, n2d, n3d), false) == OrderedDict("c" => (l3, l3, l3),)
    @test _children_pairs((n1d, n2d, n3d), true) == OrderedDict("a" => (l1, l1, nothing), "b" => (l2, nothing, l2), "c" => (l3, l3, l3))

    @test _children_pairs((n1d, n2d, n3d, n4d), false) == OrderedDict()
    @test _children_pairs((n1d, n2d, n3d, n4d), true) == OrderedDict("a" => (l1, l1, nothing, nothing),
                                                                     "b" => (l2, nothing, l2, l2), "c" => (l3, l3, l3, nothing))

    for n in [n1d, n2d, n3d, n4d]
        @test _children_pairs((n, n5d, nothing), false) == OrderedDict()
        @test _children_pairs((n, nothing), false) == OrderedDict()
        @test _children_pairs((n, n5d), false) == OrderedDict()
        res = OrderedDict(k => (ch, nothing, nothing) for (k,ch) in children(n) |> pairs)
        @test _children_pairs((n, n5d, nothing), true) == res
        res = OrderedDict(k => (ch, nothing) for (k,ch) in children(n) |> pairs)
        @test _children_pairs((n, nothing), true) == res
        @test _children_pairs((n, n5d), true) == res
    end
end

@testset "PairVec children pairing" begin
    @test _children_pairs((n1pv, n2pv), false) == [1 => (l1, l1), 3 => (l3, l3)]
    @test _children_pairs((n1pv, n2pv), true) == [1 => (l1, l1), 2 => (l2, nothing), 3 => (l3, l3)]

    @test _children_pairs((n1pv, n3pv), false) == [2 => (l2, l2), 3 => (l3, l3)]
    @test _children_pairs((n1pv, n3pv), true) == [1 => (l1, nothing), 2 => (l2, l2), 3 => (l3, l3)]
    @test _children_pairs((n3pv, n1pv), true) == [1 => (nothing, l1), 2 => (l2, l2), 3 => (l3, l3)]

    @test _children_pairs((n1pv, n4pv), false) == [2 => (l2, l2),]
    @test _children_pairs((n1pv, n4pv), true) == [1 => (l1, nothing), 2 => (l2, l2), 3 => (l3, nothing)]

    @test _children_pairs((n1pv, n2pv, n3pv), false) == [3 => (l3, l3, l3),]
    @test _children_pairs((n1pv, n2pv, n3pv), true) == [1 => (l1, l1, nothing), 2 => (l2, nothing, l2), 3 => (l3, l3, l3)]

    @test _children_pairs((n1pv, n2pv, n3pv, n4pv), false) == []
    @test _children_pairs((n1pv, n2pv, n3pv, n4pv), true) == [1 => (l1, l1, nothing, nothing), 2 => (l2, nothing, l2, l2), 3 => (l3, l3, l3, nothing)]

    for n in [n1pv, n2pv, n3pv, n4pv]
        @test _children_pairs((n, n5pv, nothing), false) == []
        @test _children_pairs((n, nothing), false) == []
        @test _children_pairs((n, n5pv), false) == []
        res = [k => (ch, nothing, nothing) for (k,ch) in _childsort(children(n))]
        @test _children_pairs((n, n5pv, nothing), true) == res
        res = [k => (ch, nothing) for (k,ch) in _childsort(children(n))]
        @test _children_pairs((n, nothing), true) == res
        @test _children_pairs((n, n5pv), true) == res
    end
end

struct SameKeys
end

NodeType(::Type{<:SameKeys}) = HierarchicalUtils.InnerNode()
children(t::SameKeys) = ["a" => 1, "b" => 2, "a" => 2]

@testset "duplicate keys in Pair vecs" begin
    @test_throws ArgumentError _children_pairs((SameKeys(),), true)
    @test_throws ArgumentError _children_pairs((SameKeys(),), false)
    @test_throws ArgumentError _children_pairs((SameKeys(), SameKeys()), true)
    @test_throws ArgumentError _children_pairs((SameKeys(), SameKeys()), false)
end

@testset "Vector children pairing" begin
    @test _children_pairs((n1v, n2v), false) == [(l1, l1), (l2, l3)]
    @test _children_pairs((n1v, n2v), true) == [(l1, l1), (l2, l3), (l3, nothing)]

    @test _children_pairs((n1v, n3v), false) == [(l1, l2)]
    @test _children_pairs((n1v, n3v), true) == [(l1, l2), (l2, nothing), (l3, nothing)]

    @test _children_pairs((n2v, n3v), false) == [(l1, l2)]
    @test _children_pairs((n2v, n3v), true) == [(l1, l2), (l3, nothing)]

    for n in [n1v, n2v, n3v]
        @test _children_pairs((n, n4v, nothing), false) == []
        @test _children_pairs((n, nothing), false) == []
        @test _children_pairs((n, n4v), false) == []
        res = [(ch, nothing, nothing) for ch in _childsort(children(n))]
        @test _children_pairs((n, n4v, nothing), true) == res
        res = [(ch, nothing) for ch in _childsort(children(n))]
        @test _children_pairs((n, nothing), true) == res
        @test _children_pairs((n, n4v), true) == res
    end
end

@testset "Tuple children pairing" begin
    @test _children_pairs((n1t, n2t), false) == ((l1, l1), (l2, l3))
    @test _children_pairs((n1t, n2t), true) == ((l1, l1), (l2, l3), (l3, nothing))

    @test _children_pairs((n1t, n3t), false) == ((l1, l2),)
    @test _children_pairs((n1t, n3t), true) == ((l1, l2), (l2, nothing), (l3, nothing))

    @test _children_pairs((n2t, n3t), false) == ((l1, l2),)
    @test _children_pairs((n2t, n3t), true) == ((l1, l2), (l3, nothing))

    for n in [n1t, n2t, n3t]
        @test _children_pairs((n, n4t, nothing), false) == ()
        @test _children_pairs((n, nothing), false) == ()
        @test _children_pairs((n, n4t), false) == ()
        res = tuple(((ch, nothing, nothing) for ch in _childsort(children(n)))...)
        @test _children_pairs((n, n4t, nothing), true) == res
        res = tuple(((ch, nothing) for ch in _childsort(children(n)))...)
        @test _children_pairs((n, nothing), true) == res
        @test _children_pairs((n, n4t), true) == res
    end
end

@testset "Different types of children" begin
    for chs in [
                [Dict(), (;), (), []],
                [Leaf(1), NTVertex(2, (;)), SingletonVertex(3, nothing), VectorVertex(4, [])]
               ]
        for (ch1, ch2, ch3, ch4) in permutations(chs)
            n1 = NTVertex(1, (a=ch1, b=ch2))
            n2 = (a=ch3, b=ch4)
            @test _children_pairs((n1, n2), true) == (a=(ch1, ch3), b=(ch2, ch4))

            n1 = Dict(:a => ch1, :b => ch2)
            n2 = Dict(:a => ch3, :b => ch4)
            @test _children_pairs((n1, n2), true) == Dict(:a => (ch1, ch3), :b => (ch2, ch4))

            n1 = BinaryVertex(1, ch1, ch2)
            n2 = [ch3, ch4]
            @test _children_pairs((n1, n2), true) == [(ch1, ch3), (ch2, ch4)]

            n1 = VectorVertex(1, [ch1, ch2])
            n2 = [1 => ch3, 2 => ch4]
            @test _children_pairs((n1, n2), true) == [1 => (ch1, ch3), 2 => (ch2, ch4)]

            n1 = (ch1, ch2)
            n2 = SingletonVertex(1, ch3)
            n3 = (ch3, ch4)
            @test _children_pairs((n1, n2), true) == ((ch1, ch3), (ch2, nothing))
            @test _children_pairs((n1, n3), true) == ((ch1, ch3), (ch2, ch4))
        end
    end
end

@testset "Different types of children iterables" begin
    for chs in [
                [Dict(), (;), ()],
                [Leaf(1), NTVertex(2, (;)), VectorVertex(4, [])]
               ]
        for (ch1, ch2, ch3) in permutations(chs)
            n1 = (a=ch1,)
            n2 = Dict(:a => ch2)
            n3 = [:a => ch3]
            @test _children_pairs((n1, n2, n3), true) == [:a => (ch1, ch2, ch3)]

            n1 = (ch1,)
            n2 = [ch2]
            @test _children_pairs((n1, n2), true) == [(ch1, ch2)]
        end
    end
end

@testset "Different types keys" begin
    n1 = (a=l1, b=l2)
    n2 = Dict("a" => l1, "b" => l2)
    n3 = [1 => l1, 2 => l2]
    @test _children_pairs((n1, n2, n3), false) == []
    @test_throws MethodError _children_pairs((n1, n2, n3), true)
end

@testset "Incompatible types" begin
    for (a, b) in product([n1nt, n2nt, n3nt, n4nt, n1d, n2d, n3d, n4d, n1pv, n2pv, n3pv, n4pv],
                          [n1v, n2v, n3v, n1t, n2t, n3t])
        @test_throws ArgumentError _children_pairs((a, b), true)
        @test_throws ArgumentError _children_pairs((b, a), true)
        @test_throws ArgumentError _children_pairs((a, b), false)
        @test_throws ArgumentError _children_pairs((b, a), false)
    end
end


text:
using ArviZ
using ArviZPlots
using Distributions
using Documenter
using Plots

makedocs(;
    modules=[ArviZPlots],
    authors="Seth Axen <seth.axen@gmail.com> and contributors",
    repo="https://github.com/arviz-devs/ArviZPlots.jl/blob/{commit}{path}#L{line}",
    sitename="ArviZPlots.jl",
    format=Documenter.HTML(;
        prettyurls=get(ENV, "CI", "false") == "true",
        canonical="https://arviz-devs.github.io/ArviZPlots.jl",
        assets=String[],
    ),
    pages=[
        "Home" => "index.md", "Examples" => "examples.md", "Reference" => "reference.md"
    ],
)

deploydocs(; devbranch="main", repo="github.com/arviz-devs/ArviZPlots.jl")


text:
using Base64, Pkg
Pkg.add(url="https://github.com/TuringLang/TuringTutorials", rev="artifacts")
using TuringTutorials

## Text Utilities

function find_yaml_header(lines)
    yaml = []
    yaml_start, yaml_stop = 1, length(lines)

    # read out YAML block.
    if strip(lines[1]) == "---"
        for i = 2:length(lines)
            if strip(lines[i]) == "---"
                yaml = lines[1:i]
                yaml_stop = i
                break
            end
        end
    end
    return yaml, yaml_start, yaml_stop
end

function remove_yaml(file, key=nothing)
    lines = readlines(file, keep=true)
    yaml, yaml_start, yaml_stop = find_yaml_header(lines)
    if !isempty(yaml)
        open(file, "w+") do f
            # write back YAML lines.
            if key !== nothing
                for line in yaml
                    startswith(line, key * ":") || write(f, line)
                end
            end
            # write back non-YAML lines
            for line in lines[yaml_stop + 1 : end]
                write(f, line)
            end
        end
    end

    return yaml
end

function tidy_api(file)
    lines = readlines(file, keep=true)

    # Find the ID sections.
    for i = 1:(length(lines)-1)
	first = lines[i]
	second = lines[i+1]
        if startswith(first, "<a id=") && startswith(second, "**")
            first = replace(first, "\n" => "")
	    second = replace(second, "\n" => "")
	    # final_line = replace(first, ">" => ">$second", count = 1)

	    lines[i] = "### $first $second"
	    lines[i+1] = ""
        end
    end

    # Write lines back.
    open(file, "w+") do f
        for line in lines
            write(f, line)
        end
    end
end

## Utilities for Tutorial docs preprocess

"""
            fix_header_1

        This function is used to add a first-level header into the
        markdown file.

        There are no H1 titles for documents in tutorials, so we need
        this.
        """
function fix_header_1(file)
    lines = readlines(file, keep=true)
    yaml, yaml_start, yaml_stop = find_yaml_header(lines)
    isempty(yaml) && return

    for line in lines[yaml_stop + 1 : end]
        strip(line) == "" && continue
        if startswith(line, "# ") # has a h1 title
            return
        else # no h1 title
            break
        end
    end

    title = "Untitled"
    for line in yaml
        if startswith(line, "title:")
            title = line[7:end] |> strip
            break
        end
    end
    title = strip(title, ['"'])

    open(file, "w+") do f
        for line in yaml
            write(f, line)
        end
        write(f, "\n# $title\n")
        # write back non-YAML lines
        for line in lines[yaml_stop + 1 : end]
            write(f, line)
        end
    end
end

function fix_image_path(file)
    # ![](/tutorials/figures/image.png)
    # to
    # ![](../figures/image.png)
    lines = readlines(file, keep=true)
    open(file, "w+") do f
        for line in lines
            line = replace(line, "](figures/" => "](../figures/")
            write(f, line)
        end
    end
end

## Building Utilities

function preprocess_markdown(folder)
    @debug "preprocess_markdown" folder
    yaml_dict = Dict()

    try
        for (root, dirs, files) in walkdir(folder)
            for file in files
		if endswith(file, ".md")
	            full_path = joinpath(root, file)
	            yaml_dict[full_path] = remove_yaml(full_path)
		end
            end
        end
    catch e
        # println("Markdown copy error: $e")
        rethrow(e)
    end

    return yaml_dict
end

function postprocess_markdown(folder, yaml_dict; original = "")
    try
        for (root, dirs, files) in walkdir(folder)
            for file in files
                full_path = joinpath(root, file)
                original_path = full_path

                if length(original) > 0
                    # original_path = abspath(original, file)
                    original_path = replace(full_path, folder => original)
                    # original_path = replace(
                    #     full_path,
                    #     joinpath("docs", "site") => joinpath("docs", "src")
                    # )
                end

                if haskey(yaml_dict, original_path)
                    # println("Original: $original_path => Full path: $full_path")

                    txt = open(f -> read(f, String), full_path)
                    open(full_path, "w+") do f
                        # Add in the yaml block.
                        for line in yaml_dict[original_path]
                            write(f, line)
                        end

                        # This is needed to replace the hyperlinks Documenter.jl generates
                        # for the API pages.
			txt = replace(txt, "api.md" => "{{site.baseurl}}/docs/library/")
			txt = replace(txt, "bijectors.md" => "{{site.baseurl}}/docs/library/bijectors/")
			txt = replace(txt, "advancedhmc.md" => "{{site.baseurl}}/docs/library/advancedhmc/")

                        # Add the rest of the text.
			if original_path == full_path
			    write(f, txt)
			else
			    write(f, replace(txt, "![](figures" => "![](/{{site.baseurl}}/tutorials/figures"))
			end
                    end
                elseif endswith(file, ".md")
                    println("Original: $original_path")
                    println("Full:     $full_path \n")
                end

		# Make specific api items headers.
		if file == "api.md" && original_path != full_path
		    tidy_api(full_path)
		end
            end
        end
    catch e
        # println("Markdown copy error: $e")
        rethrow(e)
    end

    return yaml_dict
end

function cp_by_write(src, dest; force::Bool=false)

    if isdir(src)
        for (root, dirs, files) in walkdir(src)
            new_root = replace(root, src => dest)
            mkpath(new_root)

            for file in files
                src_file = joinpath(root, file)
                dest_file = joinpath(new_root, file)

                if !ispath(dest_file) || force
                    @debug "Making $dest_file from $src_file"
                    open(src_file, "r") do f_in
                        open(dest_file, "w+") do f_out
                            write(f_out, read(f_in))
                        end
                    end
                end
            end
        end
    else
        # Assume it's a file
        if !ispath(dest) || force
            @debug "Making $dest from $src"
            open(src, "r") do f_in
                open(dest, "w+") do f_out
                    write(f_out, read(f_in))
                end
            end
        end
    end

    return dest
end

function with_clean_docs(func, source, target)
    src_temp = mktempdir()
    cp_by_write(source, src_temp, force=true)
    yaml_dict = preprocess_markdown(src_temp)

    try
        func(src_temp, target)
        yaml_dict = postprocess_markdown(target, yaml_dict, original=src_temp)
    catch e
        rethrow(e)
    finally
        # Put back the original files in the event of an error.
        # cp(src_temp, source_path, force=true)
        rm(src_temp, recursive=true)
    end
    return yaml_dict
end

function copy_tutorial(tutorial_dest_path)
    @info "Tutorial destination path $tutorial_dest_path"
    ispath(tutorial_dest_path) || mkpath(tutorial_dest_path)

    # Make a workspace
    tmp_path = tempname()
    mkdir(tmp_path)

    # Get the path of `TuringTutorials`
    md_path = joinpath(dirname(pathof(TuringTutorials)), "..", "markdown")

    # Copy the .md versions of all examples.
    try
        @debug(md_path)
        for tutorial_src in readdir(md_path)
            # Construct the full path
            tutorial_src_path = joinpath(md_path, tutorial_src)
            for (dir, subdirs, files) in walkdir(tutorial_src_path)
                # Change base directory of source path
                dir_new = replace(dir, tutorial_src_path => tmp_path)
                # Make the path if it does not exist
                mkpath(dir_new)
                # Copy over the files ensuring that we have write access
                println("Copying $dir to $dir_new")
                cp_by_write(dir, dir_new, force=true)

                for file in files
                    dest_path = joinpath(dir_new, file)

                    if endswith(dest_path, ".md")
                        # remove_yaml(target_path, "permalink")
                        fix_header_1(dest_path)
                        print("fixing image path")
                        fix_image_path(dest_path)
                    end
                end
            end
        end

        # Copy from temporary workspace to destination
        cp(tmp_path, tutorial_dest_path, force=true)
        index = joinpath(@__DIR__, "_tutorials/index.md")
        cp(index, tutorial_dest_path * "/index.md", force=true)
    catch e
        rethrow(e)
    finally
        # Clean up temporary workspace
        rm(tmp_path, recursive=true)
    end
end

function with_baseurl(func, baseurl, config_path)
    jekyll_config = config_path
    lines = readlines(jekyll_config, keep=true)
    open(jekyll_config, "w+") do f
        for line in lines
            if startswith(line, "baseurl:")
                write(f, "baseurl: \"$(baseurl)\"\n")
                continue
            end
            write(f, line)
        end
    end
    ret = func()
    open(jekyll_config, "w+") do f
        for line in lines
            write(f, line)
        end
    end
    return ret
end


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

__precompile__(true)

module LegendDSP

using RadiationDetectorDSP
using RadiationDetectorSignals

# package code goes here

end # module


text:
include("prime.jl")
function  is_circular_prime(n::Int)
	if (!is_prime(n))
		return false
	end
	s=string(n)
	for i=1:length(s)
		if (!is_prime( parse(Int,s[i:length(s)]*s[1:i-1])))
			return false
		end

	end

	return true

end

function  compute()
	const N=1000000
	ans =sum( 1 for i =1:N if is_circular_prime(i))
	return ans

end

println(compute())


text:
using Documenter, particleMDI

makedocs(modules=particleMDI,
        doctest=true)

deploydocs(deps = Deps.pip("mkdocs", "python-markdown-math"),
    repo = "github.com/nathancunn/particleMDI.jl.git",
    julia  = "0.4.5",
    osname = "linux")


text:
using ShortTermFundingMonitor
using Test

# write tests here


text:
using Documenter, Test

include("test_lesbrary_datadeps.jl")
include("test_synthetic_observations.jl")
include("test_transformations.jl")
include("test_parameters.jl")
include("test_forward_map.jl")
include("test_lesbrary_forward_map.jl")
include("test_ensemble_column_models.jl")
include("test_ensemble_kalman_inversion.jl")
include("test_utils.jl")

@testset "Doctests" begin
    using ParameterEstimocean, Distributions

    doctest(ParameterEstimocean)
end


text:
function load_case(case_path::String)
    # config
    df_config = CSV.read(joinpath(case_path, "config.tsv"), DataFrame, delim = "\t")
    n_job = df_config[1, "N_job"]
    is_sequential = df_config[1, "Sequential"] == 1
    plot_range = df_config[1, "Plot_range"]

    # machines
    df_machines = CSV.read(joinpath(case_path, "machines.tsv"), DataFrame, delim = "\t")
    machines = Vector{Machine}()
    for i = 1:size(df_machines)[1]
        push!(machines, Machine(i, df_machines[i, :Machine_type], df_machines[i, :Machine_name]))
    end

    # job definitions
    df_operations = CSV.read(joinpath(case_path, "operations.tsv"), DataFrame, delim = "\t")
    df_dependency = CSV.read(joinpath(case_path, "dependency.tsv"), DataFrame, delim = "\t")
    df_tcmb = CSV.read(joinpath(case_path, "tcmb.tsv"), DataFrame, delim = "\t")

    jobs = [Job(job_id, [], [], []) for job_id = 1:n_job]

    for job_id = 1:n_job
        for i = 1:size(df_operations)[1]
            push!(
                jobs[job_id].operations,
                Operation(
                    job_id,
                    df_operations[i, :Operation_ID],
                    df_operations[i, :Compatible_machine],
                    df_operations[i, :Processing_time] * 60,
                    df_operations[i, :Note],
                ),
            )
        end

        for i = 1:size(df_dependency)[1]
            push!(jobs[job_id].dag, (df_dependency[i, :Operation_ID_1], df_dependency[i, :Operation_ID_2]))
        end

        for i = 1:size(df_tcmb)[1]
            push!(
                jobs[job_id].constraints,
                TCMB(
                    df_tcmb[i, :Operation_ID_1],
                    Symbol(df_tcmb[i, :Point_1]),
                    df_tcmb[i, :Operation_ID_2],
                    Symbol(df_tcmb[i, :Point_2]),
                    df_tcmb[i, :Time_constraint] * 60,
                ),
            )
        end
    end

    # create batch
    batches = Vector{Batch}()
    if is_sequential
        for job_id = 1:n_job
            push!(batches, Batch([jobs[job_id]]))
        end
    else
        push!(batches, Batch(jobs))
    end

    return machines, batches, plot_range
end


text:
module TestIndexing
    using Base.Test
    using NullableArrays
    import NullableArrays: unsafe_getindex_notnull,
                           unsafe_getvalue_notnull

    x = NullableArray(Int, (5, 2))

    for i in eachindex(x)
        x[i] = i
    end

    for i in eachindex(x)
        y = x[i]
        @test isa(y, Nullable{Int})
        @test get(y) === i
    end

    for i in eachindex(x)
        x[i] = Nullable{Int}()
    end

    for i in eachindex(x)
        y = x[i]
        @test isa(y, Nullable{Int})
        @test isnull(y)
    end

    _values = rand(10, 10)
    _isnull = rand(Bool, 10, 10)
    X = NullableArray(_values, _isnull)

    # Base.getindex{T, N}(X::NullableArray{T, N})
    @test isequal(getindex(X), X[1])

    # Base.getindex{T, N}(X::NullableArray{T, N}, I::Nullable{Int}...)
    @test_throws NullException getindex(X, Nullable{Int}(), Nullable{Int}())
    if _isnull[1]
        @test isnull(getindex(X, Nullable(1)))
    else
        @test isequal(getindex(X, Nullable(1)), Nullable(_values[1]))
    end

    # Scalar getindex
    for i = 1:100
        if _isnull[i]
            @test isnull(X[i])
        else
            @test isequal(X[i], Nullable(_values[i]))
        end
    end
    for i = 1:10, j = 1:10
        if _isnull[i, j]
            @test isnull(X[i, j])
        else
            @test isequal(X[i, j], Nullable(_values[i, j]))
        end
    end

    # ensure that the NullableArray returned by getindex maintains its parent field
    str = "something"
    x = NullableArray([pointer(str), pointer(str, 5)], [false, false], Vector{UInt8}(str))
    @test x[1:2].parent === x.parent
    @test x[:].parent === x.parent

    # getindex with AbstractVectors
    rg = 2:9
    v = X[rg]
    for i = 1:length(rg)
        if _isnull[rg[i]]
            @test isnull(v[i])
        else
            @test isequal(v[i], Nullable(_values[rg[i]]))
        end
    end

    v = X[rg, 9]
    for i = 1:length(rg)
        if _isnull[rg[i], 9]
            @test isnull(v[i])
        else
            @test isequal(v[i], Nullable(_values[rg[i], 9]))
        end
    end

    rg2 = 5:7
    v = X[rg, rg2]
    for j = 1:length(rg2), i = 1:length(rg)
        if _isnull[rg[i], rg2[j]]
            @test isnull(v[i, j])
        else
            @test isequal(v[i, j], Nullable(_values[rg[i], rg2[j]]))
        end
    end

    # range indexing
    Z_values = reshape(collect(1:125), (5,5,5))
    Z = NullableArray(Z_values)

    if VERSION > v"0.5.0-dev+1195" # PR #13612 in JuliaLang
        @test isequal(Z[1, 1:4, 1], NullableArray([1, 6, 11, 16]))
    else
        @test isequal(Z[1, 1:4, 1], NullableArray([1 6 11 16]))
    end

    # getindex with AbstractVector{Bool}
    b = bitrand(10, 10)
    rg = find(b)
    v = X[b]
    for i = 1:length(rg)
        if _isnull[rg[i]]
            @test isnull(v[i])
        else
            @test isequal(v[i], Nullable(_values[rg[i]]))
        end
    end

    # getindex with NullableVector with null entries throws error
    @test_throws NullException X[NullableArray([1, 2, 3, nothing], Int, Void)]

    # getindex with NullableVector and non-null entries
    @test isequal(X[NullableArray([1, 2, 3])], X[[1, 2, 3]])

    # indexing with Nullables

    n = rand(1:5)
    siz = [ rand(2:5) for i in n ]
    A = rand(siz...)
    M = rand(Bool, siz...)
    Z = NullableArray(A, M)
    i = rand(1:length(Z))
    @test isequal(Z[Nullable(i)], Z[i])
    I = [ rand(1:size(Z,i)) for i in 1:n ]
    NI = [ Nullable(i) for i in I ]
    @test isequal(Z[NI...], Z[I...])

    #----- test setindex! -----#

    # setindex! with scalar indices
    _values = rand(10, 10)
    for i = 1:100
        X[i] = _values[i]
    end
    @test isequal(X, NullableArray(_values))

    _values = rand(10, 10)
    for i = 1:10, j = 1:10
        X[i, j] = _values[i, j]
    end
    @test isequal(X, NullableArray(_values))

    _values = rand(10, 10)
    for i = 1:10, j = 1:10
        X[i, j] = Nullable(_values[i, j])
    end
    @test isequal(X, NullableArray(_values))

    # ----- test nullify! -----#
    _isnull = bitrand(10, 10)
    for i = 1:100
        _isnull[i] && (nullify!(X, i))
    end

    # setindex! with scalar and vector indices
    rg = 2:9
    _values[rg] = 1.0
    X[rg] = 1.0
    for i = 1:length(rg)
        @test isequal(X[rg[i]], Nullable(1.0))
    end

    # setindex! with NA and vector indices
    rg = 5:13
    _isnull[rg] = true
    nullify!(X, rg)
    for i = 1:length(rg)
        @test isnull(X[rg[i]])
    end

    # setindex! with vector and vector indices
    rg = 12:67
    _values[rg] = rand(length(rg))
    X[rg] = _values[rg]
    for i = 1:length(rg)
        @test isequal(X[rg[i]], Nullable(_values[rg[i]]))
    end

    #----- test UNSAFE INDEXING -----#

    X = NullableArray([1, 2, 3, 4, 5], [true, false, false, false, false])

    @test isequal(unsafe_getindex_notnull(X, 1), Nullable(1))
    @test isequal(unsafe_getindex_notnull(X, 2), Nullable(2))
    @test isequal(unsafe_getvalue_notnull(X, 1), 1)
    @test isequal(unsafe_getvalue_notnull(X, 2), 2)

    #----- test Base.checkbounds -----#

    X = NullableArray([1:10...])
    b = vcat(false, fill(true, 9))

    if VERSION >= v"0.5.0-dev+4697"
        # Base.checkindex(::Type{Bool}, inds::UnitRange, i::Nullable)
        @test_throws NullException checkindex(Bool, 1:1, Nullable{Int}())
        @test checkindex(Bool, 1:10, Nullable(1)) == true
        @test isequal(X[Nullable(1)], Nullable(1))

        # Base.checkindex{N}(::Type{Bool}, inds::UnitRange, I::NullableArray{Bool, N})
        @test checkindex(Bool, 1:5, NullableArray([true, false, true, false, true]))
        @test isequal(X[b], NullableArray([2:10...]))

        # Base.checkindex{T<:Real}(::Type{Bool}, inds::UnitRange, I::NullableArray{T})
        @test checkindex(Bool, 1:10, NullableArray([1:10...]))
        @test checkindex(Bool, 1:10, NullableArray([10, 11])) == false
        @test_throws BoundsError checkbounds(X, NullableArray([10, 11]))
    else
        # Base.checkbounds{T<:Real}(::Type{Bool}, sz::Int, x::Nullable{T})
        @test_throws NullException checkbounds(Bool, 1, Nullable(1, true))
        @test checkbounds(Bool, 10, Nullable(1)) == true
        @test isequal(X[Nullable(1)], Nullable(1))

        # Base.checkbounds(::Type{Bool}, sz::Int, X::NullableVector{Bool})
        @test checkbounds(Bool, 5, NullableArray([true, false, true, false, true]))
        @test isequal(X[b], NullableArray([2:10...]))

        # Base.checkbounds{T<:Real}(::Type{Bool}, sz::Int, I::NullableArray{T})
        @test checkbounds(Bool, 10, NullableArray([1:10...]))
        @test checkbounds(Bool, 10, NullableArray([10, 11])) == false
        @test_throws BoundsError checkbounds(X, NullableArray([10, 11]))
    end

    #---- test Base.to_index -----#

    # Base.to_index(X::NullableArray)
    @test Base.to_index(X) == [1:10...]
    push!(X, Nullable{Int}())
    @test_throws NullException Base.to_index(X)

end


text:
export profileIdx, sample, sample_kspace

include("Regular.jl")
include("Random.jl")
include("Lines.jl")
include("PoissonDisk.jl")
include("VDPoissonDisk.jl")
include("CalibrationArea.jl")
include("PointSpreadFunction.jl")
include("Incoherence.jl")

"""
    sample(shape::NTuple{N,Int64}, redFac::Float64, patFunc::String; kargs...)

generates a `Vector{Int64}` of indices to sample an Array of of size `shape` with
a reduction factor `redFac`.

# Arguments
* `shape::NTuple{N,Int64}` - size of the Array to be sampled
* `redFac::Float64`        - subsampling factor
* `patFunc::String`        - name of the sampling function
                            ("random, "regular", "lines", "poisson" or "vdPoisson")
"""
function sample(shape::NTuple{N,Int64}, redFac::Float64, patFunc::String; kargs...) where N
  if redFac < 1
    error("Reduction factor redFac must be >= 1")
  end

  if patFunc == "random"
    return sample_random(shape,redFac;kargs...)
  elseif patFunc == "regular"
    return sample_regular(shape,redFac;kargs...)
  elseif patFunc == "lines"
    return sample_lines(shape,redFac;kargs...)
  elseif patFunc == "poisson"
    return sample_poissondisk(shape,redFac;kargs...)
  elseif patFunc == "vdPoisson"
    return sample_vdpoisson(shape,redFac;kargs...)
  else
    @error "Sample function $(patFunc) not found."
  end
end

"""
    sample_kspace(data::AbstractArray, redFac::Float64, patFunc::String; kargs...)

subsamples the Array `data` with a reduction factor `redFac`
and returns both the subsampled Array (as a vector) and the sampled indices (as a vector)

# Arguments
* `data::AbstractArray`    - array to be sampled
* `redFac::Float64`        - subsampling factor
* `patFunc::String`        - name of the sampling function
                            ("random, "regular", "lines", "poisson" or "vdPoisson")
* `kargs...`               - addional keyword arguments
"""
function sample_kspace(data::AbstractArray,redFac::Float64,patFunc::AbstractString;kargs...)
  patOut = sample(size(data),redFac,patFunc;kargs...)
  patOut = sort(patOut)
  return data[patOut],patOut
end

"""
    sample_kspace(acqData::AcquisitionData,redFac::Float64,
                patFunc::AbstractString; rand=true, profiles=true,
                seed = 1234, kargs...)

subsamples the data in `acqData` with reduction factor `redFac`
and returns a new `AcquisitionData` object.

# Arguments
* `acqData::AcquisitionDatay` - AcquisitionData to be sampled
* `redFac::Float64`           - subsampling factor
* `patFunc::String`           - name of the sampling function
                                ("random, "regular", "lines", "poisson" or "vdPoisson")
* (`rand=true`)               - use different patterns for the different contrasts
* (`profiles=true`)           - sample complete profiles
* (`seed=1234`)               - seed for the random number generator
* `kargs...`                  - addional keyword arguments
"""
function sample_kspace(acqData::AcquisitionData,redFac::Float64,
                       patFunc::AbstractString; rand=true, profiles=true,
                       seed = 1234, kargs...)
  acqData2 = deepcopy(acqData)
  sample_kspace!(acqData2,redFac,patFunc;rand=rand,profiles=profiles,seed=seed,kargs...)
  return acqData2
end

"""
    sample_kspace(acqData::AcquisitionData,redFac::Float64,
                patFunc::AbstractString; rand=true, profiles=true,
                seed = 1234, kargs...)

subsamples the data in acqData object with reduction factor `redFac`. Performs the same
subsampling as `sample_kspace` but operates in-place on acqData.
"""
function sample_kspace!(acqData::AcquisitionData,redFac::Float64,
                       patFunc::AbstractString; rand=true, profiles=true,
                       seed = 1234, kargs...)

  numContr, numSl, numRep = numContrasts(acqData), numSlices(acqData), numRepetitions(acqData)

  for echo = 1:numContr
    tr = trajectory(acqData,echo)
    if dims(tr)==2
      samplingShape = ( numSamplingPerProfile(tr), numProfiles(tr) )
    else
      samplingShape = ( numSamplingPerProfile(tr), numProfiles(tr), numSlices(tr) )
    end
    # only sample full profiles
    if profiles
      patOut = sample(samplingShape,redFac,"lines"; sampleFunc=patFunc, seed=seed, kargs...)
    else
      patOut = sample(samplingShape,redFac,patFunc; seed=seed, kargs...)
    end
    patOut = sort(patOut)
    for slice=1:numSl, rep=1:numRep
      acqData.kdata[echo,slice, rep] = acqData.kdata[echo,slice,rep][patOut,:]
    end
    acqData.subsampleIndices[echo] = patOut
    rand && (seed += 1)
  end
end

function profileIdx(acqData::AcquisitionData,contr::Int)
  tr = trajectory(acqData,contr)
  numSamp = numSamplingPerProfile(tr)
  numProf = div(length(acqData.subsampleIndices[contr]),numSamp)
  idx = [div(acqData.subsampleIndices[contr][numSamp*(prof-1)+1],numSamp)+1 for prof=1:numProf]
end