text:
module LibZstd

using Zstd_jll
export Zstd_jll

using CEnum

const INT_MAX = typemax(Cint)

ZSTD_EXPAND_AND_QUOTE(expr) = string(expr)

function ZDICT_trainFromBuffer(dictBuffer, dictBufferCapacity, samplesBuffer, samplesSizes, nbSamples)
    ccall((:ZDICT_trainFromBuffer, libzstd), Csize_t, (Ptr{Cvoid}, Csize_t, Ptr{Cvoid}, Ptr{Csize_t}, Cuint), dictBuffer, dictBufferCapacity, samplesBuffer, samplesSizes, nbSamples)
end

struct ZDICT_params_t
    compressionLevel::Cint
    notificationLevel::Cuint
    dictID::Cuint
end

function ZDICT_finalizeDictionary(dstDictBuffer, maxDictSize, dictContent, dictContentSize, samplesBuffer, samplesSizes, nbSamples, parameters)
    ccall((:ZDICT_finalizeDictionary, libzstd), Csize_t, (Ptr{Cvoid}, Csize_t, Ptr{Cvoid}, Csize_t, Ptr{Cvoid}, Ptr{Csize_t}, Cuint, ZDICT_params_t), dstDictBuffer, maxDictSize, dictContent, dictContentSize, samplesBuffer, samplesSizes, nbSamples, parameters)
end

function ZDICT_getDictID(dictBuffer, dictSize)
    ccall((:ZDICT_getDictID, libzstd), Cuint, (Ptr{Cvoid}, Csize_t), dictBuffer, dictSize)
end

function ZDICT_getDictHeaderSize(dictBuffer, dictSize)
    ccall((:ZDICT_getDictHeaderSize, libzstd), Csize_t, (Ptr{Cvoid}, Csize_t), dictBuffer, dictSize)
end

function ZDICT_isError(errorCode)
    ccall((:ZDICT_isError, libzstd), Cuint, (Csize_t,), errorCode)
end

function ZDICT_getErrorName(errorCode)
    ccall((:ZDICT_getErrorName, libzstd), Ptr{Cchar}, (Csize_t,), errorCode)
end

function ZSTD_versionNumber()
    ccall((:ZSTD_versionNumber, libzstd), Cuint, ())
end

function ZSTD_versionString()
    ccall((:ZSTD_versionString, libzstd), Ptr{Cchar}, ())
end

function ZSTD_compress(dst, dstCapacity, src, srcSize, compressionLevel)
    ccall((:ZSTD_compress, libzstd), Csize_t, (Ptr{Cvoid}, Csize_t, Ptr{Cvoid}, Csize_t, Cint), dst, dstCapacity, src, srcSize, compressionLevel)
end

function ZSTD_decompress(dst, dstCapacity, src, compressedSize)
    ccall((:ZSTD_decompress, libzstd), Csize_t, (Ptr{Cvoid}, Csize_t, Ptr{Cvoid}, Csize_t), dst, dstCapacity, src, compressedSize)
end

function ZSTD_getFrameContentSize(src, srcSize)
    ccall((:ZSTD_getFrameContentSize, libzstd), Culonglong, (Ptr{Cvoid}, Csize_t), src, srcSize)
end

function ZSTD_getDecompressedSize(src, srcSize)
    ccall((:ZSTD_getDecompressedSize, libzstd), Culonglong, (Ptr{Cvoid}, Csize_t), src, srcSize)
end

function ZSTD_findFrameCompressedSize(src, srcSize)
    ccall((:ZSTD_findFrameCompressedSize, libzstd), Csize_t, (Ptr{Cvoid}, Csize_t), src, srcSize)
end

function ZSTD_compressBound(srcSize)
    ccall((:ZSTD_compressBound, libzstd), Csize_t, (Csize_t,), srcSize)
end

function ZSTD_isError(code)
    ccall((:ZSTD_isError, libzstd), Cuint, (Csize_t,), code)
end

function ZSTD_getErrorName(code)
    ccall((:ZSTD_getErrorName, libzstd), Ptr{Cchar}, (Csize_t,), code)
end

function ZSTD_minCLevel()
    ccall((:ZSTD_minCLevel, libzstd), Cint, ())
end

function ZSTD_maxCLevel()
    ccall((:ZSTD_maxCLevel, libzstd), Cint, ())
end

function ZSTD_defaultCLevel()
    ccall((:ZSTD_defaultCLevel, libzstd), Cint, ())
end

mutable struct ZSTD_CCtx_s end

const ZSTD_CCtx = ZSTD_CCtx_s

function ZSTD_createCCtx()
    ccall((:ZSTD_createCCtx, libzstd), Ptr{ZSTD_CCtx}, ())
end

function ZSTD_freeCCtx(cctx)
    ccall((:ZSTD_freeCCtx, libzstd), Csize_t, (Ptr{ZSTD_CCtx},), cctx)
end

function ZSTD_compressCCtx(cctx, dst, dstCapacity, src, srcSize, compressionLevel)
    ccall((:ZSTD_compressCCtx, libzstd), Csize_t, (Ptr{ZSTD_CCtx}, Ptr{Cvoid}, Csize_t, Ptr{Cvoid}, Csize_t, Cint), cctx, dst, dstCapacity, src, srcSize, compressionLevel)
end

mutable struct ZSTD_DCtx_s end

const ZSTD_DCtx = ZSTD_DCtx_s

function ZSTD_createDCtx()
    ccall((:ZSTD_createDCtx, libzstd), Ptr{ZSTD_DCtx}, ())
end

function ZSTD_freeDCtx(dctx)
    ccall((:ZSTD_freeDCtx, libzstd), Csize_t, (Ptr{ZSTD_DCtx},), dctx)
end

function ZSTD_decompressDCtx(dctx, dst, dstCapacity, src, srcSize)
    ccall((:ZSTD_decompressDCtx, libzstd), Csize_t, (Ptr{ZSTD_DCtx}, Ptr{Cvoid}, Csize_t, Ptr{Cvoid}, Csize_t), dctx, dst, dstCapacity, src, srcSize)
end

@cenum ZSTD_strategy::UInt32 begin
    ZSTD_fast = 1
    ZSTD_dfast = 2
    ZSTD_greedy = 3
    ZSTD_lazy = 4
    ZSTD_lazy2 = 5
    ZSTD_btlazy2 = 6
    ZSTD_btopt = 7
    ZSTD_btultra = 8
    ZSTD_btultra2 = 9
end

@cenum ZSTD_cParameter::UInt32 begin
    ZSTD_c_compressionLevel = 100
    ZSTD_c_windowLog = 101
    ZSTD_c_hashLog = 102
    ZSTD_c_chainLog = 103
    ZSTD_c_searchLog = 104
    ZSTD_c_minMatch = 105
    ZSTD_c_targetLength = 106
    ZSTD_c_strategy = 107
    ZSTD_c_enableLongDistanceMatching = 160
    ZSTD_c_ldmHashLog = 161
    ZSTD_c_ldmMinMatch = 162
    ZSTD_c_ldmBucketSizeLog = 163
    ZSTD_c_ldmHashRateLog = 164
    ZSTD_c_contentSizeFlag = 200
    ZSTD_c_checksumFlag = 201
    ZSTD_c_dictIDFlag = 202
    ZSTD_c_nbWorkers = 400
    ZSTD_c_jobSize = 401
    ZSTD_c_overlapLog = 402
    ZSTD_c_experimentalParam1 = 500
    ZSTD_c_experimentalParam2 = 10
    ZSTD_c_experimentalParam3 = 1000
    ZSTD_c_experimentalParam4 = 1001
    ZSTD_c_experimentalParam5 = 1002
    ZSTD_c_experimentalParam6 = 1003
    ZSTD_c_experimentalParam7 = 1004
    ZSTD_c_experimentalParam8 = 1005
    ZSTD_c_experimentalParam9 = 1006
    ZSTD_c_experimentalParam10 = 1007
    ZSTD_c_experimentalParam11 = 1008
    ZSTD_c_experimentalParam12 = 1009
    ZSTD_c_experimentalParam13 = 1010
    ZSTD_c_experimentalParam14 = 1011
    ZSTD_c_experimentalParam15 = 1012
end

struct ZSTD_bounds
    error::Csize_t
    lowerBound::Cint
    upperBound::Cint
end

function ZSTD_cParam_getBounds(cParam)
    ccall((:ZSTD_cParam_getBounds, libzstd), ZSTD_bounds, (ZSTD_cParameter,), cParam)
end

function ZSTD_CCtx_setParameter(cctx, param, value)
    ccall((:ZSTD_CCtx_setParameter, libzstd), Csize_t, (Ptr{ZSTD_CCtx}, ZSTD_cParameter, Cint), cctx, param, value)
end

function ZSTD_CCtx_setPledgedSrcSize(cctx, pledgedSrcSize)
    ccall((:ZSTD_CCtx_setPledgedSrcSize, libzstd), Csize_t, (Ptr{ZSTD_CCtx}, Culonglong), cctx, pledgedSrcSize)
end

@cenum ZSTD_ResetDirective::UInt32 begin
    ZSTD_reset_session_only = 1
    ZSTD_reset_parameters = 2
    ZSTD_reset_session_and_parameters = 3
end

function ZSTD_CCtx_reset(cctx, reset)
    ccall((:ZSTD_CCtx_reset, libzstd), Csize_t, (Ptr{ZSTD_CCtx}, ZSTD_ResetDirective), cctx, reset)
end

function ZSTD_compress2(cctx, dst, dstCapacity, src, srcSize)
    ccall((:ZSTD_compress2, libzstd), Csize_t, (Ptr{ZSTD_CCtx}, Ptr{Cvoid}, Csize_t, Ptr{Cvoid}, Csize_t), cctx, dst, dstCapacity, src, srcSize)
end

@cenum ZSTD_dParameter::UInt32 begin
    ZSTD_d_windowLogMax = 100
    ZSTD_d_experimentalParam1 = 1000
    ZSTD_d_experimentalParam2 = 1001
    ZSTD_d_experimentalParam3 = 1002
    ZSTD_d_experimentalParam4 = 1003
end

function ZSTD_dParam_getBounds(dParam)
    ccall((:ZSTD_dParam_getBounds, libzstd), ZSTD_bounds, (ZSTD_dParameter,), dParam)
end

function ZSTD_DCtx_setParameter(dctx, param, value)
    ccall((:ZSTD_DCtx_setParameter, libzstd), Csize_t, (Ptr{ZSTD_DCtx}, ZSTD_dParameter, Cint), dctx, param, value)
end

function ZSTD_DCtx_reset(dctx, reset)
    ccall((:ZSTD_DCtx_reset, libzstd), Csize_t, (Ptr{ZSTD_DCtx}, ZSTD_ResetDirective), dctx, reset)
end

mutable struct ZSTD_inBuffer_s
    src::Ptr{Cvoid}
    size::Csize_t
    pos::Csize_t
end

const ZSTD_inBuffer = ZSTD_inBuffer_s

mutable struct ZSTD_outBuffer_s
    dst::Ptr{Cvoid}
    size::Csize_t
    pos::Csize_t
end

const ZSTD_outBuffer = ZSTD_outBuffer_s

const ZSTD_CStream = ZSTD_CCtx

function ZSTD_createCStream()
    ccall((:ZSTD_createCStream, libzstd), Ptr{ZSTD_CStream}, ())
end

function ZSTD_freeCStream(zcs)
    ccall((:ZSTD_freeCStream, libzstd), Csize_t, (Ptr{ZSTD_CStream},), zcs)
end

@cenum ZSTD_EndDirective::UInt32 begin
    ZSTD_e_continue = 0
    ZSTD_e_flush = 1
    ZSTD_e_end = 2
end

function ZSTD_compressStream2(cctx, output, input, endOp)
    ccall((:ZSTD_compressStream2, libzstd), Csize_t, (Ptr{ZSTD_CCtx}, Ptr{ZSTD_outBuffer}, Ptr{ZSTD_inBuffer}, ZSTD_EndDirective), cctx, output, input, endOp)
end

function ZSTD_CStreamInSize()
    ccall((:ZSTD_CStreamInSize, libzstd), Csize_t, ())
end

function ZSTD_CStreamOutSize()
    ccall((:ZSTD_CStreamOutSize, libzstd), Csize_t, ())
end

function ZSTD_initCStream(zcs, compressionLevel)
    ccall((:ZSTD_initCStream, libzstd), Csize_t, (Ptr{ZSTD_CStream}, Cint), zcs, compressionLevel)
end

function ZSTD_compressStream(zcs, output, input)
    ccall((:ZSTD_compressStream, libzstd), Csize_t, (Ptr{ZSTD_CStream}, Ptr{ZSTD_outBuffer}, Ptr{ZSTD_inBuffer}), zcs, output, input)
end

function ZSTD_flushStream(zcs, output)
    ccall((:ZSTD_flushStream, libzstd), Csize_t, (Ptr{ZSTD_CStream}, Ptr{ZSTD_outBuffer}), zcs, output)
end

function ZSTD_endStream(zcs, output)
    ccall((:ZSTD_endStream, libzstd), Csize_t, (Ptr{ZSTD_CStream}, Ptr{ZSTD_outBuffer}), zcs, output)
end

const ZSTD_DStream = ZSTD_DCtx

function ZSTD_createDStream()
    ccall((:ZSTD_createDStream, libzstd), Ptr{ZSTD_DStream}, ())
end

function ZSTD_freeDStream(zds)
    ccall((:ZSTD_freeDStream, libzstd), Csize_t, (Ptr{ZSTD_DStream},), zds)
end

function ZSTD_initDStream(zds)
    ccall((:ZSTD_initDStream, libzstd), Csize_t, (Ptr{ZSTD_DStream},), zds)
end

function ZSTD_decompressStream(zds, output, input)
    ccall((:ZSTD_decompressStream, libzstd), Csize_t, (Ptr{ZSTD_DStream}, Ptr{ZSTD_outBuffer}, Ptr{ZSTD_inBuffer}), zds, output, input)
end

function ZSTD_DStreamInSize()
    ccall((:ZSTD_DStreamInSize, libzstd), Csize_t, ())
end

function ZSTD_DStreamOutSize()
    ccall((:ZSTD_DStreamOutSize, libzstd), Csize_t, ())
end

function ZSTD_compress_usingDict(ctx, dst, dstCapacity, src, srcSize, dict, dictSize, compressionLevel)
    ccall((:ZSTD_compress_usingDict, libzstd), Csize_t, (Ptr{ZSTD_CCtx}, Ptr{Cvoid}, Csize_t, Ptr{Cvoid}, Csize_t, Ptr{Cvoid}, Csize_t, Cint), ctx, dst, dstCapacity, src, srcSize, dict, dictSize, compressionLevel)
end

function ZSTD_decompress_usingDict(dctx, dst, dstCapacity, src, srcSize, dict, dictSize)
    ccall((:ZSTD_decompress_usingDict, libzstd), Csize_t, (Ptr{ZSTD_DCtx}, Ptr{Cvoid}, Csize_t, Ptr{Cvoid}, Csize_t, Ptr{Cvoid}, Csize_t), dctx, dst, dstCapacity, src, srcSize, dict, dictSize)
end

mutable struct ZSTD_CDict_s end

const ZSTD_CDict = ZSTD_CDict_s

function ZSTD_createCDict(dictBuffer, dictSize, compressionLevel)
    ccall((:ZSTD_createCDict, libzstd), Ptr{ZSTD_CDict}, (Ptr{Cvoid}, Csize_t, Cint), dictBuffer, dictSize, compressionLevel)
end

function ZSTD_freeCDict(CDict)
    ccall((:ZSTD_freeCDict, libzstd), Csize_t, (Ptr{ZSTD_CDict},), CDict)
end

function ZSTD_compress_usingCDict(cctx, dst, dstCapacity, src, srcSize, cdict)
    ccall((:ZSTD_compress_usingCDict, libzstd), Csize_t, (Ptr{ZSTD_CCtx}, Ptr{Cvoid}, Csize_t, Ptr{Cvoid}, Csize_t, Ptr{ZSTD_CDict}), cctx, dst, dstCapacity, src, srcSize, cdict)
end

mutable struct ZSTD_DDict_s end

const ZSTD_DDict = ZSTD_DDict_s

function ZSTD_createDDict(dictBuffer, dictSize)
    ccall((:ZSTD_createDDict, libzstd), Ptr{ZSTD_DDict}, (Ptr{Cvoid}, Csize_t), dictBuffer, dictSize)
end

function ZSTD_freeDDict(ddict)
    ccall((:ZSTD_freeDDict, libzstd), Csize_t, (Ptr{ZSTD_DDict},), ddict)
end

function ZSTD_decompress_usingDDict(dctx, dst, dstCapacity, src, srcSize, ddict)
    ccall((:ZSTD_decompress_usingDDict, libzstd), Csize_t, (Ptr{ZSTD_DCtx}, Ptr{Cvoid}, Csize_t, Ptr{Cvoid}, Csize_t, Ptr{ZSTD_DDict}), dctx, dst, dstCapacity, src, srcSize, ddict)
end

function ZSTD_getDictID_fromDict(dict, dictSize)
    ccall((:ZSTD_getDictID_fromDict, libzstd), Cuint, (Ptr{Cvoid}, Csize_t), dict, dictSize)
end

function ZSTD_getDictID_fromCDict(cdict)
    ccall((:ZSTD_getDictID_fromCDict, libzstd), Cuint, (Ptr{ZSTD_CDict},), cdict)
end

function ZSTD_getDictID_fromDDict(ddict)
    ccall((:ZSTD_getDictID_fromDDict, libzstd), Cuint, (Ptr{ZSTD_DDict},), ddict)
end

function ZSTD_getDictID_fromFrame(src, srcSize)
    ccall((:ZSTD_getDictID_fromFrame, libzstd), Cuint, (Ptr{Cvoid}, Csize_t), src, srcSize)
end

function ZSTD_CCtx_loadDictionary(cctx, dict, dictSize)
    ccall((:ZSTD_CCtx_loadDictionary, libzstd), Csize_t, (Ptr{ZSTD_CCtx}, Ptr{Cvoid}, Csize_t), cctx, dict, dictSize)
end

function ZSTD_CCtx_refCDict(cctx, cdict)
    ccall((:ZSTD_CCtx_refCDict, libzstd), Csize_t, (Ptr{ZSTD_CCtx}, Ptr{ZSTD_CDict}), cctx, cdict)
end

function ZSTD_CCtx_refPrefix(cctx, prefix, prefixSize)
    ccall((:ZSTD_CCtx_refPrefix, libzstd), Csize_t, (Ptr{ZSTD_CCtx}, Ptr{Cvoid}, Csize_t), cctx, prefix, prefixSize)
end

function ZSTD_DCtx_loadDictionary(dctx, dict, dictSize)
    ccall((:ZSTD_DCtx_loadDictionary, libzstd), Csize_t, (Ptr{ZSTD_DCtx}, Ptr{Cvoid}, Csize_t), dctx, dict, dictSize)
end

function ZSTD_DCtx_refDDict(dctx, ddict)
    ccall((:ZSTD_DCtx_refDDict, libzstd), Csize_t, (Ptr{ZSTD_DCtx}, Ptr{ZSTD_DDict}), dctx, ddict)
end

function ZSTD_DCtx_refPrefix(dctx, prefix, prefixSize)
    ccall((:ZSTD_DCtx_refPrefix, libzstd), Csize_t, (Ptr{ZSTD_DCtx}, Ptr{Cvoid}, Csize_t), dctx, prefix, prefixSize)
end

function ZSTD_sizeof_CCtx(cctx)
    ccall((:ZSTD_sizeof_CCtx, libzstd), Csize_t, (Ptr{ZSTD_CCtx},), cctx)
end

function ZSTD_sizeof_DCtx(dctx)
    ccall((:ZSTD_sizeof_DCtx, libzstd), Csize_t, (Ptr{ZSTD_DCtx},), dctx)
end

function ZSTD_sizeof_CStream(zcs)
    ccall((:ZSTD_sizeof_CStream, libzstd), Csize_t, (Ptr{ZSTD_CStream},), zcs)
end

function ZSTD_sizeof_DStream(zds)
    ccall((:ZSTD_sizeof_DStream, libzstd), Csize_t, (Ptr{ZSTD_DStream},), zds)
end

function ZSTD_sizeof_CDict(cdict)
    ccall((:ZSTD_sizeof_CDict, libzstd), Csize_t, (Ptr{ZSTD_CDict},), cdict)
end

function ZSTD_sizeof_DDict(ddict)
    ccall((:ZSTD_sizeof_DDict, libzstd), Csize_t, (Ptr{ZSTD_DDict},), ddict)
end

mutable struct ZSTD_CCtx_params_s end

const ZSTD_CCtx_params = ZSTD_CCtx_params_s

struct ZSTD_Sequence
    offset::Cuint
    litLength::Cuint
    matchLength::Cuint
    rep::Cuint
end

struct ZSTD_compressionParameters
    windowLog::Cuint
    chainLog::Cuint
    hashLog::Cuint
    searchLog::Cuint
    minMatch::Cuint
    targetLength::Cuint
    strategy::ZSTD_strategy
end

struct ZSTD_frameParameters
    contentSizeFlag::Cint
    checksumFlag::Cint
    noDictIDFlag::Cint
end

struct ZSTD_parameters
    cParams::ZSTD_compressionParameters
    fParams::ZSTD_frameParameters
end

@cenum ZSTD_dictContentType_e::UInt32 begin
    ZSTD_dct_auto = 0
    ZSTD_dct_rawContent = 1
    ZSTD_dct_fullDict = 2
end

@cenum ZSTD_dictLoadMethod_e::UInt32 begin
    ZSTD_dlm_byCopy = 0
    ZSTD_dlm_byRef = 1
end

@cenum ZSTD_format_e::UInt32 begin
    ZSTD_f_zstd1 = 0
    ZSTD_f_zstd1_magicless = 1
end

@cenum ZSTD_forceIgnoreChecksum_e::UInt32 begin
    ZSTD_d_validateChecksum = 0
    ZSTD_d_ignoreChecksum = 1
end

@cenum ZSTD_refMultipleDDicts_e::UInt32 begin
    ZSTD_rmd_refSingleDDict = 0
    ZSTD_rmd_refMultipleDDicts = 1
end

@cenum ZSTD_dictAttachPref_e::UInt32 begin
    ZSTD_dictDefaultAttach = 0
    ZSTD_dictForceAttach = 1
    ZSTD_dictForceCopy = 2
    ZSTD_dictForceLoad = 3
end

@cenum ZSTD_literalCompressionMode_e::UInt32 begin
    ZSTD_lcm_auto = 0
    ZSTD_lcm_huffman = 1
    ZSTD_lcm_uncompressed = 2
end

@cenum ZSTD_useRowMatchFinderMode_e::UInt32 begin
    ZSTD_urm_auto = 0
    ZSTD_urm_disableRowMatchFinder = 1
    ZSTD_urm_enableRowMatchFinder = 2
end

function ZSTD_findDecompressedSize(src, srcSize)
    ccall((:ZSTD_findDecompressedSize, libzstd), Culonglong, (Ptr{Cvoid}, Csize_t), src, srcSize)
end

function ZSTD_decompressBound(src, srcSize)
    ccall((:ZSTD_decompressBound, libzstd), Culonglong, (Ptr{Cvoid}, Csize_t), src, srcSize)
end

function ZSTD_frameHeaderSize(src, srcSize)
    ccall((:ZSTD_frameHeaderSize, libzstd), Csize_t, (Ptr{Cvoid}, Csize_t), src, srcSize)
end

@cenum ZSTD_sequenceFormat_e::UInt32 begin
    ZSTD_sf_noBlockDelimiters = 0
    ZSTD_sf_explicitBlockDelimiters = 1
end

function ZSTD_generateSequences(zc, outSeqs, outSeqsSize, src, srcSize)
    ccall((:ZSTD_generateSequences, libzstd), Csize_t, (Ptr{ZSTD_CCtx}, Ptr{ZSTD_Sequence}, Csize_t, Ptr{Cvoid}, Csize_t), zc, outSeqs, outSeqsSize, src, srcSize)
end

function ZSTD_mergeBlockDelimiters(sequences, seqsSize)
    ccall((:ZSTD_mergeBlockDelimiters, libzstd), Csize_t, (Ptr{ZSTD_Sequence}, Csize_t), sequences, seqsSize)
end

function ZSTD_compressSequences(cctx, dst, dstSize, inSeqs, inSeqsSize, src, srcSize)
    ccall((:ZSTD_compressSequences, libzstd), Csize_t, (Ptr{ZSTD_CCtx}, Ptr{Cvoid}, Csize_t, Ptr{ZSTD_Sequence}, Csize_t, Ptr{Cvoid}, Csize_t), cctx, dst, dstSize, inSeqs, inSeqsSize, src, srcSize)
end

function ZSTD_writeSkippableFrame(dst, dstCapacity, src, srcSize, magicVariant)
    ccall((:ZSTD_writeSkippableFrame, libzstd), Csize_t, (Ptr{Cvoid}, Csize_t, Ptr{Cvoid}, Csize_t, Cuint), dst, dstCapacity, src, srcSize, magicVariant)
end

function ZSTD_estimateCCtxSize(compressionLevel)
    ccall((:ZSTD_estimateCCtxSize, libzstd), Csize_t, (Cint,), compressionLevel)
end

function ZSTD_estimateCCtxSize_usingCParams(cParams)
    ccall((:ZSTD_estimateCCtxSize_usingCParams, libzstd), Csize_t, (ZSTD_compressionParameters,), cParams)
end

function ZSTD_estimateCCtxSize_usingCCtxParams(params)
    ccall((:ZSTD_estimateCCtxSize_usingCCtxParams, libzstd), Csize_t, (Ptr{ZSTD_CCtx_params},), params)
end

function ZSTD_estimateDCtxSize()
    ccall((:ZSTD_estimateDCtxSize, libzstd), Csize_t, ())
end

function ZSTD_estimateCStreamSize(compressionLevel)
    ccall((:ZSTD_estimateCStreamSize, libzstd), Csize_t, (Cint,), compressionLevel)
end

function ZSTD_estimateCStreamSize_usingCParams(cParams)
    ccall((:ZSTD_estimateCStreamSize_usingCParams, libzstd), Csize_t, (ZSTD_compressionParameters,), cParams)
end

function ZSTD_estimateCStreamSize_usingCCtxParams(params)
    ccall((:ZSTD_estimateCStreamSize_usingCCtxParams, libzstd), Csize_t, (Ptr{ZSTD_CCtx_params},), params)
end

function ZSTD_estimateDStreamSize(windowSize)
    ccall((:ZSTD_estimateDStreamSize, libzstd), Csize_t, (Csize_t,), windowSize)
end

function ZSTD_estimateDStreamSize_fromFrame(src, srcSize)
    ccall((:ZSTD_estimateDStreamSize_fromFrame, libzstd), Csize_t, (Ptr{Cvoid}, Csize_t), src, srcSize)
end

function ZSTD_estimateCDictSize(dictSize, compressionLevel)
    ccall((:ZSTD_estimateCDictSize, libzstd), Csize_t, (Csize_t, Cint), dictSize, compressionLevel)
end

function ZSTD_estimateCDictSize_advanced(dictSize, cParams, dictLoadMethod)
    ccall((:ZSTD_estimateCDictSize_advanced, libzstd), Csize_t, (Csize_t, ZSTD_compressionParameters, ZSTD_dictLoadMethod_e), dictSize, cParams, dictLoadMethod)
end

function ZSTD_estimateDDictSize(dictSize, dictLoadMethod)
    ccall((:ZSTD_estimateDDictSize, libzstd), Csize_t, (Csize_t, ZSTD_dictLoadMethod_e), dictSize, dictLoadMethod)
end

function ZSTD_initStaticCCtx(workspace, workspaceSize)
    ccall((:ZSTD_initStaticCCtx, libzstd), Ptr{ZSTD_CCtx}, (Ptr{Cvoid}, Csize_t), workspace, workspaceSize)
end

function ZSTD_initStaticCStream(workspace, workspaceSize)
    ccall((:ZSTD_initStaticCStream, libzstd), Ptr{ZSTD_CStream}, (Ptr{Cvoid}, Csize_t), workspace, workspaceSize)
end

function ZSTD_initStaticDCtx(workspace, workspaceSize)
    ccall((:ZSTD_initStaticDCtx, libzstd), Ptr{ZSTD_DCtx}, (Ptr{Cvoid}, Csize_t), workspace, workspaceSize)
end

function ZSTD_initStaticDStream(workspace, workspaceSize)
    ccall((:ZSTD_initStaticDStream, libzstd), Ptr{ZSTD_DStream}, (Ptr{Cvoid}, Csize_t), workspace, workspaceSize)
end

function ZSTD_initStaticCDict(workspace, workspaceSize, dict, dictSize, dictLoadMethod, dictContentType, cParams)
    ccall((:ZSTD_initStaticCDict, libzstd), Ptr{ZSTD_CDict}, (Ptr{Cvoid}, Csize_t, Ptr{Cvoid}, Csize_t, ZSTD_dictLoadMethod_e, ZSTD_dictContentType_e, ZSTD_compressionParameters), workspace, workspaceSize, dict, dictSize, dictLoadMethod, dictContentType, cParams)
end

function ZSTD_initStaticDDict(workspace, workspaceSize, dict, dictSize, dictLoadMethod, dictContentType)
    ccall((:ZSTD_initStaticDDict, libzstd), Ptr{ZSTD_DDict}, (Ptr{Cvoid}, Csize_t, Ptr{Cvoid}, Csize_t, ZSTD_dictLoadMethod_e, ZSTD_dictContentType_e), workspace, workspaceSize, dict, dictSize, dictLoadMethod, dictContentType)
end

# typedef void * ( * ZSTD_allocFunction ) ( void * opaque , size_t size )
const ZSTD_allocFunction = Ptr{Cvoid}

# typedef void ( * ZSTD_freeFunction ) ( void * opaque , void * address )
const ZSTD_freeFunction = Ptr{Cvoid}

struct ZSTD_customMem
    customAlloc::ZSTD_allocFunction
    customFree::ZSTD_freeFunction
    opaque::Ptr{Cvoid}
end

function ZSTD_createCCtx_advanced(customMem)
    ccall((:ZSTD_createCCtx_advanced, libzstd), Ptr{ZSTD_CCtx}, (ZSTD_customMem,), customMem)
end

function ZSTD_createCStream_advanced(customMem)
    ccall((:ZSTD_createCStream_advanced, libzstd), Ptr{ZSTD_CStream}, (ZSTD_customMem,), customMem)
end

function ZSTD_createDCtx_advanced(customMem)
    ccall((:ZSTD_createDCtx_advanced, libzstd), Ptr{ZSTD_DCtx}, (ZSTD_customMem,), customMem)
end

function ZSTD_createDStream_advanced(customMem)
    ccall((:ZSTD_createDStream_advanced, libzstd), Ptr{ZSTD_DStream}, (ZSTD_customMem,), customMem)
end

function ZSTD_createCDict_advanced(dict, dictSize, dictLoadMethod, dictContentType, cParams, customMem)
    ccall((:ZSTD_createCDict_advanced, libzstd), Ptr{ZSTD_CDict}, (Ptr{Cvoid}, Csize_t, ZSTD_dictLoadMethod_e, ZSTD_dictContentType_e, ZSTD_compressionParameters, ZSTD_customMem), dict, dictSize, dictLoadMethod, dictContentType, cParams, customMem)
end

mutable struct POOL_ctx_s end

const ZSTD_threadPool = POOL_ctx_s

function ZSTD_createThreadPool(numThreads)
    ccall((:ZSTD_createThreadPool, libzstd), Ptr{ZSTD_threadPool}, (Csize_t,), numThreads)
end

function ZSTD_freeThreadPool(pool)
    ccall((:ZSTD_freeThreadPool, libzstd), Cvoid, (Ptr{ZSTD_threadPool},), pool)
end

function ZSTD_CCtx_refThreadPool(cctx, pool)
    ccall((:ZSTD_CCtx_refThreadPool, libzstd), Csize_t, (Ptr{ZSTD_CCtx}, Ptr{ZSTD_threadPool}), cctx, pool)
end

function ZSTD_createCDict_advanced2(dict, dictSize, dictLoadMethod, dictContentType, cctxParams, customMem)
    ccall((:ZSTD_createCDict_advanced2, libzstd), Ptr{ZSTD_CDict}, (Ptr{Cvoid}, Csize_t, ZSTD_dictLoadMethod_e, ZSTD_dictContentType_e, Ptr{ZSTD_CCtx_params}, ZSTD_customMem), dict, dictSize, dictLoadMethod, dictContentType, cctxParams, customMem)
end

function ZSTD_createDDict_advanced(dict, dictSize, dictLoadMethod, dictContentType, customMem)
    ccall((:ZSTD_createDDict_advanced, libzstd), Ptr{ZSTD_DDict}, (Ptr{Cvoid}, Csize_t, ZSTD_dictLoadMethod_e, ZSTD_dictContentType_e, ZSTD_customMem), dict, dictSize, dictLoadMethod, dictContentType, customMem)
end

function ZSTD_createCDict_byReference(dictBuffer, dictSize, compressionLevel)
    ccall((:ZSTD_createCDict_byReference, libzstd), Ptr{ZSTD_CDict}, (Ptr{Cvoid}, Csize_t, Cint), dictBuffer, dictSize, compressionLevel)
end

function ZSTD_getCParams(compressionLevel, estimatedSrcSize, dictSize)
    ccall((:ZSTD_getCParams, libzstd), ZSTD_compressionParameters, (Cint, Culonglong, Csize_t), compressionLevel, estimatedSrcSize, dictSize)
end

function ZSTD_getParams(compressionLevel, estimatedSrcSize, dictSize)
    ccall((:ZSTD_getParams, libzstd), ZSTD_parameters, (Cint, Culonglong, Csize_t), compressionLevel, estimatedSrcSize, dictSize)
end

function ZSTD_checkCParams(params)
    ccall((:ZSTD_checkCParams, libzstd), Csize_t, (ZSTD_compressionParameters,), params)
end

function ZSTD_adjustCParams(cPar, srcSize, dictSize)
    ccall((:ZSTD_adjustCParams, libzstd), ZSTD_compressionParameters, (ZSTD_compressionParameters, Culonglong, Csize_t), cPar, srcSize, dictSize)
end

function ZSTD_compress_advanced(cctx, dst, dstCapacity, src, srcSize, dict, dictSize, params)
    ccall((:ZSTD_compress_advanced, libzstd), Csize_t, (Ptr{ZSTD_CCtx}, Ptr{Cvoid}, Csize_t, Ptr{Cvoid}, Csize_t, Ptr{Cvoid}, Csize_t, ZSTD_parameters), cctx, dst, dstCapacity, src, srcSize, dict, dictSize, params)
end

function ZSTD_compress_usingCDict_advanced(cctx, dst, dstCapacity, src, srcSize, cdict, fParams)
    ccall((:ZSTD_compress_usingCDict_advanced, libzstd), Csize_t, (Ptr{ZSTD_CCtx}, Ptr{Cvoid}, Csize_t, Ptr{Cvoid}, Csize_t, Ptr{ZSTD_CDict}, ZSTD_frameParameters), cctx, dst, dstCapacity, src, srcSize, cdict, fParams)
end

function ZSTD_CCtx_loadDictionary_byReference(cctx, dict, dictSize)
    ccall((:ZSTD_CCtx_loadDictionary_byReference, libzstd), Csize_t, (Ptr{ZSTD_CCtx}, Ptr{Cvoid}, Csize_t), cctx, dict, dictSize)
end

function ZSTD_CCtx_loadDictionary_advanced(cctx, dict, dictSize, dictLoadMethod, dictContentType)
    ccall((:ZSTD_CCtx_loadDictionary_advanced, libzstd), Csize_t, (Ptr{ZSTD_CCtx}, Ptr{Cvoid}, Csize_t, ZSTD_dictLoadMethod_e, ZSTD_dictContentType_e), cctx, dict, dictSize, dictLoadMethod, dictContentType)
end

function ZSTD_CCtx_refPrefix_advanced(cctx, prefix, prefixSize, dictContentType)
    ccall((:ZSTD_CCtx_refPrefix_advanced, libzstd), Csize_t, (Ptr{ZSTD_CCtx}, Ptr{Cvoid}, Csize_t, ZSTD_dictContentType_e), cctx, prefix, prefixSize, dictContentType)
end

function ZSTD_CCtx_getParameter(cctx, param, value)
    ccall((:ZSTD_CCtx_getParameter, libzstd), Csize_t, (Ptr{ZSTD_CCtx}, ZSTD_cParameter, Ptr{Cint}), cctx, param, value)
end

function ZSTD_createCCtxParams()
    ccall((:ZSTD_createCCtxParams, libzstd), Ptr{ZSTD_CCtx_params}, ())
end

function ZSTD_freeCCtxParams(params)
    ccall((:ZSTD_freeCCtxParams, libzstd), Csize_t, (Ptr{ZSTD_CCtx_params},), params)
end

function ZSTD_CCtxParams_reset(params)
    ccall((:ZSTD_CCtxParams_reset, libzstd), Csize_t, (Ptr{ZSTD_CCtx_params},), params)
end

function ZSTD_CCtxParams_init(cctxParams, compressionLevel)
    ccall((:ZSTD_CCtxParams_init, libzstd), Csize_t, (Ptr{ZSTD_CCtx_params}, Cint), cctxParams, compressionLevel)
end

function ZSTD_CCtxParams_init_advanced(cctxParams, params)
    ccall((:ZSTD_CCtxParams_init_advanced, libzstd), Csize_t, (Ptr{ZSTD_CCtx_params}, ZSTD_parameters), cctxParams, params)
end

function ZSTD_CCtxParams_setParameter(params, param, value)
    ccall((:ZSTD_CCtxParams_setParameter, libzstd), Csize_t, (Ptr{ZSTD_CCtx_params}, ZSTD_cParameter, Cint), params, param, value)
end

function ZSTD_CCtxParams_getParameter(params, param, value)
    ccall((:ZSTD_CCtxParams_getParameter, libzstd), Csize_t, (Ptr{ZSTD_CCtx_params}, ZSTD_cParameter, Ptr{Cint}), params, param, value)
end

function ZSTD_CCtx_setParametersUsingCCtxParams(cctx, params)
    ccall((:ZSTD_CCtx_setParametersUsingCCtxParams, libzstd), Csize_t, (Ptr{ZSTD_CCtx}, Ptr{ZSTD_CCtx_params}), cctx, params)
end

function ZSTD_compressStream2_simpleArgs(cctx, dst, dstCapacity, dstPos, src, srcSize, srcPos, endOp)
    ccall((:ZSTD_compressStream2_simpleArgs, libzstd), Csize_t, (Ptr{ZSTD_CCtx}, Ptr{Cvoid}, Csize_t, Ptr{Csize_t}, Ptr{Cvoid}, Csize_t, Ptr{Csize_t}, ZSTD_EndDirective), cctx, dst, dstCapacity, dstPos, src, srcSize, srcPos, endOp)
end

function ZSTD_isFrame(buffer, size)
    ccall((:ZSTD_isFrame, libzstd), Cuint, (Ptr{Cvoid}, Csize_t), buffer, size)
end

function ZSTD_createDDict_byReference(dictBuffer, dictSize)
    ccall((:ZSTD_createDDict_byReference, libzstd), Ptr{ZSTD_DDict}, (Ptr{Cvoid}, Csize_t), dictBuffer, dictSize)
end

function ZSTD_DCtx_loadDictionary_byReference(dctx, dict, dictSize)
    ccall((:ZSTD_DCtx_loadDictionary_byReference, libzstd), Csize_t, (Ptr{ZSTD_DCtx}, Ptr{Cvoid}, Csize_t), dctx, dict, dictSize)
end

function ZSTD_DCtx_loadDictionary_advanced(dctx, dict, dictSize, dictLoadMethod, dictContentType)
    ccall((:ZSTD_DCtx_loadDictionary_advanced, libzstd), Csize_t, (Ptr{ZSTD_DCtx}, Ptr{Cvoid}, Csize_t, ZSTD_dictLoadMethod_e, ZSTD_dictContentType_e), dctx, dict, dictSize, dictLoadMethod, dictContentType)
end

function ZSTD_DCtx_refPrefix_advanced(dctx, prefix, prefixSize, dictContentType)
    ccall((:ZSTD_DCtx_refPrefix_advanced, libzstd), Csize_t, (Ptr{ZSTD_DCtx}, Ptr{Cvoid}, Csize_t, ZSTD_dictContentType_e), dctx, prefix, prefixSize, dictContentType)
end

function ZSTD_DCtx_setMaxWindowSize(dctx, maxWindowSize)
    ccall((:ZSTD_DCtx_setMaxWindowSize, libzstd), Csize_t, (Ptr{ZSTD_DCtx}, Csize_t), dctx, maxWindowSize)
end

function ZSTD_DCtx_getParameter(dctx, param, value)
    ccall((:ZSTD_DCtx_getParameter, libzstd), Csize_t, (Ptr{ZSTD_DCtx}, ZSTD_dParameter, Ptr{Cint}), dctx, param, value)
end

function ZSTD_DCtx_setFormat(dctx, format)
    ccall((:ZSTD_DCtx_setFormat, libzstd), Csize_t, (Ptr{ZSTD_DCtx}, ZSTD_format_e), dctx, format)
end

function ZSTD_decompressStream_simpleArgs(dctx, dst, dstCapacity, dstPos, src, srcSize, srcPos)
    ccall((:ZSTD_decompressStream_simpleArgs, libzstd), Csize_t, (Ptr{ZSTD_DCtx}, Ptr{Cvoid}, Csize_t, Ptr{Csize_t}, Ptr{Cvoid}, Csize_t, Ptr{Csize_t}), dctx, dst, dstCapacity, dstPos, src, srcSize, srcPos)
end

function ZSTD_initCStream_srcSize(zcs, compressionLevel, pledgedSrcSize)
    ccall((:ZSTD_initCStream_srcSize, libzstd), Csize_t, (Ptr{ZSTD_CStream}, Cint, Culonglong), zcs, compressionLevel, pledgedSrcSize)
end

function ZSTD_initCStream_usingDict(zcs, dict, dictSize, compressionLevel)
    ccall((:ZSTD_initCStream_usingDict, libzstd), Csize_t, (Ptr{ZSTD_CStream}, Ptr{Cvoid}, Csize_t, Cint), zcs, dict, dictSize, compressionLevel)
end

function ZSTD_initCStream_advanced(zcs, dict, dictSize, params, pledgedSrcSize)
    ccall((:ZSTD_initCStream_advanced, libzstd), Csize_t, (Ptr{ZSTD_CStream}, Ptr{Cvoid}, Csize_t, ZSTD_parameters, Culonglong), zcs, dict, dictSize, params, pledgedSrcSize)
end

function ZSTD_initCStream_usingCDict(zcs, cdict)
    ccall((:ZSTD_initCStream_usingCDict, libzstd), Csize_t, (Ptr{ZSTD_CStream}, Ptr{ZSTD_CDict}), zcs, cdict)
end

function ZSTD_initCStream_usingCDict_advanced(zcs, cdict, fParams, pledgedSrcSize)
    ccall((:ZSTD_initCStream_usingCDict_advanced, libzstd), Csize_t, (Ptr{ZSTD_CStream}, Ptr{ZSTD_CDict}, ZSTD_frameParameters, Culonglong), zcs, cdict, fParams, pledgedSrcSize)
end

function ZSTD_resetCStream(zcs, pledgedSrcSize)
    ccall((:ZSTD_resetCStream, libzstd), Csize_t, (Ptr{ZSTD_CStream}, Culonglong), zcs, pledgedSrcSize)
end

struct ZSTD_frameProgression
    ingested::Culonglong
    consumed::Culonglong
    produced::Culonglong
    flushed::Culonglong
    currentJobID::Cuint
    nbActiveWorkers::Cuint
end

function ZSTD_getFrameProgression(cctx)
    ccall((:ZSTD_getFrameProgression, libzstd), ZSTD_frameProgression, (Ptr{ZSTD_CCtx},), cctx)
end

function ZSTD_toFlushNow(cctx)
    ccall((:ZSTD_toFlushNow, libzstd), Csize_t, (Ptr{ZSTD_CCtx},), cctx)
end

function ZSTD_initDStream_usingDict(zds, dict, dictSize)
    ccall((:ZSTD_initDStream_usingDict, libzstd), Csize_t, (Ptr{ZSTD_DStream}, Ptr{Cvoid}, Csize_t), zds, dict, dictSize)
end

function ZSTD_initDStream_usingDDict(zds, ddict)
    ccall((:ZSTD_initDStream_usingDDict, libzstd), Csize_t, (Ptr{ZSTD_DStream}, Ptr{ZSTD_DDict}), zds, ddict)
end

function ZSTD_resetDStream(zds)
    ccall((:ZSTD_resetDStream, libzstd), Csize_t, (Ptr{ZSTD_DStream},), zds)
end

function ZSTD_compressBegin(cctx, compressionLevel)
    ccall((:ZSTD_compressBegin, libzstd), Csize_t, (Ptr{ZSTD_CCtx}, Cint), cctx, compressionLevel)
end

function ZSTD_compressBegin_usingDict(cctx, dict, dictSize, compressionLevel)
    ccall((:ZSTD_compressBegin_usingDict, libzstd), Csize_t, (Ptr{ZSTD_CCtx}, Ptr{Cvoid}, Csize_t, Cint), cctx, dict, dictSize, compressionLevel)
end

function ZSTD_compressBegin_usingCDict(cctx, cdict)
    ccall((:ZSTD_compressBegin_usingCDict, libzstd), Csize_t, (Ptr{ZSTD_CCtx}, Ptr{ZSTD_CDict}), cctx, cdict)
end

function ZSTD_copyCCtx(cctx, preparedCCtx, pledgedSrcSize)
    ccall((:ZSTD_copyCCtx, libzstd), Csize_t, (Ptr{ZSTD_CCtx}, Ptr{ZSTD_CCtx}, Culonglong), cctx, preparedCCtx, pledgedSrcSize)
end

function ZSTD_compressContinue(cctx, dst, dstCapacity, src, srcSize)
    ccall((:ZSTD_compressContinue, libzstd), Csize_t, (Ptr{ZSTD_CCtx}, Ptr{Cvoid}, Csize_t, Ptr{Cvoid}, Csize_t), cctx, dst, dstCapacity, src, srcSize)
end

function ZSTD_compressEnd(cctx, dst, dstCapacity, src, srcSize)
    ccall((:ZSTD_compressEnd, libzstd), Csize_t, (Ptr{ZSTD_CCtx}, Ptr{Cvoid}, Csize_t, Ptr{Cvoid}, Csize_t), cctx, dst, dstCapacity, src, srcSize)
end

function ZSTD_compressBegin_advanced(cctx, dict, dictSize, params, pledgedSrcSize)
    ccall((:ZSTD_compressBegin_advanced, libzstd), Csize_t, (Ptr{ZSTD_CCtx}, Ptr{Cvoid}, Csize_t, ZSTD_parameters, Culonglong), cctx, dict, dictSize, params, pledgedSrcSize)
end

function ZSTD_compressBegin_usingCDict_advanced(cctx, cdict, fParams, pledgedSrcSize)
    ccall((:ZSTD_compressBegin_usingCDict_advanced, libzstd), Csize_t, (Ptr{ZSTD_CCtx}, Ptr{ZSTD_CDict}, ZSTD_frameParameters, Culonglong), cctx, cdict, fParams, pledgedSrcSize)
end

@cenum ZSTD_frameType_e::UInt32 begin
    ZSTD_frame = 0
    ZSTD_skippableFrame = 1
end

struct ZSTD_frameHeader
    frameContentSize::Culonglong
    windowSize::Culonglong
    blockSizeMax::Cuint
    frameType::ZSTD_frameType_e
    headerSize::Cuint
    dictID::Cuint
    checksumFlag::Cuint
end

function ZSTD_getFrameHeader(zfhPtr, src, srcSize)
    ccall((:ZSTD_getFrameHeader, libzstd), Csize_t, (Ptr{ZSTD_frameHeader}, Ptr{Cvoid}, Csize_t), zfhPtr, src, srcSize)
end

function ZSTD_getFrameHeader_advanced(zfhPtr, src, srcSize, format)
    ccall((:ZSTD_getFrameHeader_advanced, libzstd), Csize_t, (Ptr{ZSTD_frameHeader}, Ptr{Cvoid}, Csize_t, ZSTD_format_e), zfhPtr, src, srcSize, format)
end

function ZSTD_decodingBufferSize_min(windowSize, frameContentSize)
    ccall((:ZSTD_decodingBufferSize_min, libzstd), Csize_t, (Culonglong, Culonglong), windowSize, frameContentSize)
end

function ZSTD_decompressBegin(dctx)
    ccall((:ZSTD_decompressBegin, libzstd), Csize_t, (Ptr{ZSTD_DCtx},), dctx)
end

function ZSTD_decompressBegin_usingDict(dctx, dict, dictSize)
    ccall((:ZSTD_decompressBegin_usingDict, libzstd), Csize_t, (Ptr{ZSTD_DCtx}, Ptr{Cvoid}, Csize_t), dctx, dict, dictSize)
end

function ZSTD_decompressBegin_usingDDict(dctx, ddict)
    ccall((:ZSTD_decompressBegin_usingDDict, libzstd), Csize_t, (Ptr{ZSTD_DCtx}, Ptr{ZSTD_DDict}), dctx, ddict)
end

function ZSTD_nextSrcSizeToDecompress(dctx)
    ccall((:ZSTD_nextSrcSizeToDecompress, libzstd), Csize_t, (Ptr{ZSTD_DCtx},), dctx)
end

function ZSTD_decompressContinue(dctx, dst, dstCapacity, src, srcSize)
    ccall((:ZSTD_decompressContinue, libzstd), Csize_t, (Ptr{ZSTD_DCtx}, Ptr{Cvoid}, Csize_t, Ptr{Cvoid}, Csize_t), dctx, dst, dstCapacity, src, srcSize)
end

function ZSTD_copyDCtx(dctx, preparedDCtx)
    ccall((:ZSTD_copyDCtx, libzstd), Cvoid, (Ptr{ZSTD_DCtx}, Ptr{ZSTD_DCtx}), dctx, preparedDCtx)
end

@cenum ZSTD_nextInputType_e::UInt32 begin
    ZSTDnit_frameHeader = 0
    ZSTDnit_blockHeader = 1
    ZSTDnit_block = 2
    ZSTDnit_lastBlock = 3
    ZSTDnit_checksum = 4
    ZSTDnit_skippableFrame = 5
end

function ZSTD_nextInputType(dctx)
    ccall((:ZSTD_nextInputType, libzstd), ZSTD_nextInputType_e, (Ptr{ZSTD_DCtx},), dctx)
end

function ZSTD_getBlockSize(cctx)
    ccall((:ZSTD_getBlockSize, libzstd), Csize_t, (Ptr{ZSTD_CCtx},), cctx)
end

function ZSTD_compressBlock(cctx, dst, dstCapacity, src, srcSize)
    ccall((:ZSTD_compressBlock, libzstd), Csize_t, (Ptr{ZSTD_CCtx}, Ptr{Cvoid}, Csize_t, Ptr{Cvoid}, Csize_t), cctx, dst, dstCapacity, src, srcSize)
end

function ZSTD_decompressBlock(dctx, dst, dstCapacity, src, srcSize)
    ccall((:ZSTD_decompressBlock, libzstd), Csize_t, (Ptr{ZSTD_DCtx}, Ptr{Cvoid}, Csize_t, Ptr{Cvoid}, Csize_t), dctx, dst, dstCapacity, src, srcSize)
end

function ZSTD_insertBlock(dctx, blockStart, blockSize)
    ccall((:ZSTD_insertBlock, libzstd), Csize_t, (Ptr{ZSTD_DCtx}, Ptr{Cvoid}, Csize_t), dctx, blockStart, blockSize)
end

@cenum ZSTD_ErrorCode::UInt32 begin
    ZSTD_error_no_error = 0
    ZSTD_error_GENERIC = 1
    ZSTD_error_prefix_unknown = 10
    ZSTD_error_version_unsupported = 12
    ZSTD_error_frameParameter_unsupported = 14
    ZSTD_error_frameParameter_windowTooLarge = 16
    ZSTD_error_corruption_detected = 20
    ZSTD_error_checksum_wrong = 22
    ZSTD_error_dictionary_corrupted = 30
    ZSTD_error_dictionary_wrong = 32
    ZSTD_error_dictionaryCreation_failed = 34
    ZSTD_error_parameter_unsupported = 40
    ZSTD_error_parameter_outOfBound = 42
    ZSTD_error_tableLog_tooLarge = 44
    ZSTD_error_maxSymbolValue_tooLarge = 46
    ZSTD_error_maxSymbolValue_tooSmall = 48
    ZSTD_error_stage_wrong = 60
    ZSTD_error_init_missing = 62
    ZSTD_error_memory_allocation = 64
    ZSTD_error_workSpace_tooSmall = 66
    ZSTD_error_dstSize_tooSmall = 70
    ZSTD_error_srcSize_wrong = 72
    ZSTD_error_dstBuffer_null = 74
    ZSTD_error_frameIndex_tooLarge = 100
    ZSTD_error_seekableIO = 102
    ZSTD_error_dstBuffer_wrong = 104
    ZSTD_error_srcBuffer_wrong = 105
    ZSTD_error_maxCode = 120
end

function ZSTD_getErrorCode(functionResult)
    ccall((:ZSTD_getErrorCode, libzstd), ZSTD_ErrorCode, (Csize_t,), functionResult)
end

function ZSTD_getErrorString(code)
    ccall((:ZSTD_getErrorString, libzstd), Ptr{Cchar}, (ZSTD_ErrorCode,), code)
end

const ZDICTLIB_VISIBILITY = nothing

const ZDICTLIB_API = ZDICTLIB_VISIBILITY

const ZSTDLIB_VISIBILITY = nothing

const ZSTDLIB_API = ZSTDLIB_VISIBILITY

const ZSTD_VERSION_MAJOR = 1

const ZSTD_VERSION_MINOR = 5

const ZSTD_VERSION_RELEASE = 0

const ZSTD_VERSION_NUMBER = ZSTD_VERSION_MAJOR * 100 * 100 + ZSTD_VERSION_MINOR * 100 + ZSTD_VERSION_RELEASE

const ZSTD_LIB_VERSION = VersionNumber(ZSTD_VERSION_MAJOR, ZSTD_VERSION_MINOR, ZSTD_VERSION_RELEASE)

const ZSTD_VERSION_STRING = ZSTD_EXPAND_AND_QUOTE(ZSTD_LIB_VERSION)

const ZSTD_CLEVEL_DEFAULT = 3

const ZSTD_MAGICNUMBER = 0xfd2fb528

const ZSTD_MAGIC_DICTIONARY = 0xec30a437

const ZSTD_MAGIC_SKIPPABLE_START = 0x184d2a50

const ZSTD_MAGIC_SKIPPABLE_MASK = 0xfffffff0

const ZSTD_BLOCKSIZELOG_MAX = 17

const ZSTD_BLOCKSIZE_MAX = 1 << ZSTD_BLOCKSIZELOG_MAX

const ZSTD_CONTENTSIZE_UNKNOWN = Culonglong(0) - 1

const ZSTD_CONTENTSIZE_ERROR = Culonglong(0) - 2

const ZSTD_FRAMEHEADERSIZE_MAX = 18

const ZSTD_SKIPPABLEHEADERSIZE = 8

const ZSTD_WINDOWLOG_MAX_32 = 30

const ZSTD_WINDOWLOG_MAX_64 = 31

const ZSTD_WINDOWLOG_MAX = if sizeof(Csize_t) == 4
            ZSTD_WINDOWLOG_MAX_32
        else
            ZSTD_WINDOWLOG_MAX_64
        end

const ZSTD_WINDOWLOG_MIN = 10

const ZSTD_HASHLOG_MAX = if ZSTD_WINDOWLOG_MAX < 30
            ZSTD_WINDOWLOG_MAX
        else
            30
        end

const ZSTD_HASHLOG_MIN = 6

const ZSTD_CHAINLOG_MAX_32 = 29

const ZSTD_CHAINLOG_MAX_64 = 30

const ZSTD_CHAINLOG_MAX = if sizeof(Csize_t) == 4
            ZSTD_CHAINLOG_MAX_32
        else
            ZSTD_CHAINLOG_MAX_64
        end

const ZSTD_CHAINLOG_MIN = ZSTD_HASHLOG_MIN

const ZSTD_SEARCHLOG_MAX = ZSTD_WINDOWLOG_MAX - 1

const ZSTD_SEARCHLOG_MIN = 1

const ZSTD_MINMATCH_MAX = 7

const ZSTD_MINMATCH_MIN = 3

const ZSTD_TARGETLENGTH_MAX = ZSTD_BLOCKSIZE_MAX

const ZSTD_TARGETLENGTH_MIN = 0

const ZSTD_STRATEGY_MIN = ZSTD_fast

const ZSTD_STRATEGY_MAX = ZSTD_btultra2

const ZSTD_OVERLAPLOG_MIN = 0

const ZSTD_OVERLAPLOG_MAX = 9

const ZSTD_WINDOWLOG_LIMIT_DEFAULT = 27

const ZSTD_LDM_HASHLOG_MIN = ZSTD_HASHLOG_MIN

const ZSTD_LDM_HASHLOG_MAX = ZSTD_HASHLOG_MAX

const ZSTD_LDM_MINMATCH_MIN = 4

const ZSTD_LDM_MINMATCH_MAX = 4096

const ZSTD_LDM_BUCKETSIZELOG_MIN = 1

const ZSTD_LDM_BUCKETSIZELOG_MAX = 8

const ZSTD_LDM_HASHRATELOG_MIN = 0

const ZSTD_LDM_HASHRATELOG_MAX = ZSTD_WINDOWLOG_MAX - ZSTD_HASHLOG_MIN

const ZSTD_TARGETCBLOCKSIZE_MIN = 64

const ZSTD_TARGETCBLOCKSIZE_MAX = ZSTD_BLOCKSIZE_MAX

const ZSTD_SRCSIZEHINT_MIN = 0

const ZSTD_SRCSIZEHINT_MAX = INT_MAX

const ZSTD_HASHLOG3_MAX = 17

const ZSTD_c_rsyncable = ZSTD_c_experimentalParam1

const ZSTD_c_format = ZSTD_c_experimentalParam2

const ZSTD_c_forceMaxWindow = ZSTD_c_experimentalParam3

const ZSTD_c_forceAttachDict = ZSTD_c_experimentalParam4

const ZSTD_c_literalCompressionMode = ZSTD_c_experimentalParam5

const ZSTD_c_targetCBlockSize = ZSTD_c_experimentalParam6

const ZSTD_c_srcSizeHint = ZSTD_c_experimentalParam7

const ZSTD_c_enableDedicatedDictSearch = ZSTD_c_experimentalParam8

const ZSTD_c_stableInBuffer = ZSTD_c_experimentalParam9

const ZSTD_c_stableOutBuffer = ZSTD_c_experimentalParam10

const ZSTD_c_blockDelimiters = ZSTD_c_experimentalParam11

const ZSTD_c_validateSequences = ZSTD_c_experimentalParam12

const ZSTD_c_splitBlocks = ZSTD_c_experimentalParam13

const ZSTD_c_useRowMatchFinder = ZSTD_c_experimentalParam14

const ZSTD_c_deterministicRefPrefix = ZSTD_c_experimentalParam15

const ZSTD_d_format = ZSTD_d_experimentalParam1

const ZSTD_d_stableOutBuffer = ZSTD_d_experimentalParam2

const ZSTD_d_forceIgnoreChecksum = ZSTD_d_experimentalParam3

const ZSTD_d_refMultipleDDicts = ZSTD_d_experimentalParam4

const ZSTDERRORLIB_VISIBILITY = nothing

const ZSTDERRORLIB_API = ZSTDERRORLIB_VISIBILITY

# exports
const PREFIXES = ["ZSTD_", "ZDICT_"]
for name in names(@__MODULE__; all=true), prefix in PREFIXES
    if startswith(string(name), prefix)
        @eval export $name
    end
end

end # module


text:
module TestORDFile
    using Base.Test
    import RollCallDataIO

    path = joinpath(dirname(@__FILE__), "data", "senate113.ord")
    io = open(path, "r")
    ord_file = RollCallDataIO.read(RollCallDataIO.ORDFile, io)
    close(io)

    @test isa(ord_file, RollCallDataIO.ORDFile)

    roll_call = RollCallDataIO.roll_call(ord_file)
    @test isa(roll_call, RollCallDataIO.RollCall)

    @test isa(roll_call.votes, Matrix{Int})
    n_legislators, n_bills = size(roll_call.votes)

    @test isa(RollCallDataIO.congresses(ord_file), Vector{Int})
    @test length(RollCallDataIO.congresses(ord_file)) == n_legislators
    @test all(RollCallDataIO.congresses(ord_file) .== 113)

    @test isa(RollCallDataIO.icpsr_ids(ord_file), Vector{Int})
    @test length(RollCallDataIO.icpsr_ids(ord_file)) == n_legislators
    @test RollCallDataIO.icpsr_ids(ord_file)[1] == 99911
    @test RollCallDataIO.icpsr_ids(ord_file)[2] == 49700
    @test RollCallDataIO.icpsr_ids(ord_file)[3] == 94659
    @test RollCallDataIO.icpsr_ids(ord_file)[104] == 29940
    @test RollCallDataIO.icpsr_ids(ord_file)[105] == 49706
    @test RollCallDataIO.icpsr_ids(ord_file)[106] == 40707

    @test isa(RollCallDataIO.icpsr_states(ord_file), Vector{Int})
    @test length(RollCallDataIO.icpsr_states(ord_file)) == n_legislators
    @test RollCallDataIO.icpsr_states(ord_file)[1] == 99
    @test RollCallDataIO.icpsr_states(ord_file)[2] == 41
    @test RollCallDataIO.icpsr_states(ord_file)[3] == 41
    @test RollCallDataIO.icpsr_states(ord_file)[104] == 25
    @test RollCallDataIO.icpsr_states(ord_file)[105] == 68
    @test RollCallDataIO.icpsr_states(ord_file)[106] == 68

    @test isa(RollCallDataIO.cds(ord_file), Vector{Int})
    @test length(RollCallDataIO.cds(ord_file)) == n_legislators
    @test RollCallDataIO.cds(ord_file)[1] == 0
    @test RollCallDataIO.cds(ord_file)[2] == 0
    @test RollCallDataIO.cds(ord_file)[3] == 0
    @test RollCallDataIO.cds(ord_file)[104] == 0
    @test RollCallDataIO.cds(ord_file)[105] == 0
    @test RollCallDataIO.cds(ord_file)[106] == 0

    @test isa(RollCallDataIO.kh_states(ord_file), Vector{UTF8String})
    @test length(RollCallDataIO.kh_states(ord_file)) == n_legislators
    @test RollCallDataIO.kh_states(ord_file)[1] == "USA"
    @test RollCallDataIO.kh_states(ord_file)[2] == "ALABAMA"
    @test RollCallDataIO.kh_states(ord_file)[3] == "ALABAMA"
    @test RollCallDataIO.kh_states(ord_file)[104] == "WISCONS"
    @test RollCallDataIO.kh_states(ord_file)[105] == "WYOMING"
    @test RollCallDataIO.kh_states(ord_file)[106] == "WYOMING"

    @test isa(RollCallDataIO.parties(ord_file), Vector{Int})
    @test length(RollCallDataIO.parties(ord_file)) == n_legislators
    @test RollCallDataIO.parties(ord_file)[1] == 100
    @test RollCallDataIO.parties(ord_file)[2] == 200
    @test RollCallDataIO.parties(ord_file)[3] == 200
    @test RollCallDataIO.parties(ord_file)[104] == 100
    @test RollCallDataIO.parties(ord_file)[105] == 200
    @test RollCallDataIO.parties(ord_file)[106] == 200

    # TODO: Figure out what this field really is
    RollCallDataIO.unknowns(ord_file)

    @test isa(RollCallDataIO.legislators(ord_file), Vector{UTF8String})
    @test length(RollCallDataIO.legislators(ord_file)) == n_legislators
    @test RollCallDataIO.legislators(ord_file)[1] == "OBAMA"
    @test RollCallDataIO.legislators(ord_file)[2] == "SESSIONS"
    @test RollCallDataIO.legislators(ord_file)[3] == "SHELBY"
    @test RollCallDataIO.legislators(ord_file)[104] == "BALDWIN"
    @test RollCallDataIO.legislators(ord_file)[105] == "ENZI"
    @test RollCallDataIO.legislators(ord_file)[106] == "BARASSO"

    @test vec(roll_call.votes[1, 1:5]) == Int[9, 9, 9, 1, 1]
    @test vec(roll_call.votes[2, 1:5]) == Int[6, 6, 1, 6, 1]
    @test vec(roll_call.votes[3, 1:5]) == Int[6, 6, 6, 1, 1]
    @test vec(roll_call.votes[104, 1:5]) == Int[1, 1, 6, 1, 1]
    @test vec(roll_call.votes[105, 1:5]) == Int[1, 1, 1, 6, 1]
    @test vec(roll_call.votes[106, 1:5]) == Int[1, 1, 1, 6, 1]
end

ext: jl

max_stars_repo_name: johnmyleswhite/RollCallDataIO

max_issues_repo_name: johnmyleswhite/RollCallDataIO

max_forks_repo_name: johnmyleswhite/RollCallDataIO


text:
immutable Route
    dst :: Int
    cost :: Int
end

type Node
    neighbours :: Array{Route, 1}
end

function readPlaces(f)
    n = int(readline(f))

    nodes = Array(Node, n)

    for i in 1:n
        nodes[i] = Node([])
    end

    while !eof(f)
        route = split(readline(f))

        src = int(route[1]) + 1
        dst = int(route[2]) + 1
        cost = int(route[3])

	push!(nodes[src].neighbours, Route(dst, cost))
    end
    n, nodes
end

function getLongestPath(nodes :: Array{Node, 1}, nodeid :: Int, visited :: Array{Bool, 1})
    visited[nodeid] = true
    m = 0
    for neighbour in nodes[nodeid].neighbours
        @inbounds if !visited[neighbour.dst]
            const dist = neighbour.cost + getLongestPath(nodes, neighbour.dst, visited)
            m = max(dist, m)
        end
    end
    visited[nodeid] = false
    m
end

function main()
    n, nodes = open(readPlaces, "agraph")
    visited = fill(false, n)

    getLongestPath([Node([])], 1, visited)

    t = @elapsed len = getLongestPath(nodes, 1, visited)

    println(len, " LANGUAGE Julia ", int(t*1000), " ms")
end

main()

max_stars_repo_name: yazd/LPATHBench

max_issues_repo_name: yazd/LPATHBench

max_forks_repo_name: yazd/LPATHBench


text:
extended_source_modeling(model::Model, srcData, recGeometry, recData, weights, perturbation, srcnum::UnitRange{Int64}, op::Char, mode::Int64) =
    extended_source_modeling(model, srcData, recGeometry, recData, weights, perturbation, srcnum, op, mode, Options())

function extended_source_modeling(model::Model, srcData, recGeometry, recData, weights, dm, srcnum::UnitRange{Int64}, op::Char, mode::Int64, options)
# extended_source_modeling function for multiple sources. Depending on the operator and mode, this function distributes the sources
# and if applicable the input data amongst the available workers.

    results = judipmap(j ->extended_source_modeling(model, subsample(srcData, j), subsample(recGeometry, j),
                                                    subsample(recData, j), weights, dm, op, mode, subsample(options, j)), srcnum)

    if op=='F' || (op=='J' && mode==1)
        argout1 = vcat(results...)
    elseif op=='J' && mode==-1
        argout1 = sum(results)
    else
        error("operation no defined")
    end
    return argout1
end


text:
module Internal

import ForwardDiff # TODO: remove the dependency on ForwardDiff.jl
import LogDensityProblems
import LinearAlgebra
import TransformVariables

const _default_fuzz_factor = 0.01

function gradient_vector(transformed_gradient_problem,
                         theta)
    transformed_log_density = parent(transformed_gradient_problem)
    transformation = transformed_log_density.transformation
    theta_inversetransformed = TransformVariables.inverse(transformation,
                                                          theta)
    result = _gradient_vector(transformed_gradient_problem,
                              theta_inversetransformed)
    return result
end

function _gradient_vector(transformed_gradient_problem,
                          theta)
    log_likelihood_value, gradient = LogDensityProblems.logdensity_and_gradient(transformed_gradient_problem,
                                                                                theta)
    return gradient
end

function hessian_matrix(transformed_gradient_problem,
                        theta)
    transformed_log_density = parent(transformed_gradient_problem)
    transformation = transformed_log_density.transformation
    theta_inversetransformed = TransformVariables.inverse(transformation,
                                                          theta)
    result = _hessian_matrix(transformed_gradient_problem,
                             theta_inversetransformed)
    return result
end

function _hessian_matrix(transformed_gradient_problem,
                         theta)
    @assert transformed_gradient_problem isa LogDensityProblems.ForwardDiffLogDensity
    ℓ = transformed_gradient_problem.ℓ
    logdensity_closure = LogDensityProblems._logdensity_closure(ℓ)
    hessian = ForwardDiff.hessian(logdensity_closure,
                                  theta)
    return hessian
end

function _is_approximately_zero(a::AbstractArray;
                                tolerance = 1e-4)
    result = all( abs.(a) .< tolerance )
    return result
end

function _is_approximately_hermitian(m::AbstractMatrix;
                                     tolerance = 1e-4)
    LinearAlgebra.checksquare(m)
    result = _is_approximately_zero(m - LinearAlgebra.adjoint(m);
                                    tolerance = tolerance)
    return result
end

function _all_eigenvalues_are_negative(m::AbstractMatrix;
                                       fuzz_factor = _default_fuzz_factor)
    eigvals = LinearAlgebra.eigvals(m)
    a = all( eigvals .< 0 )
    b = all( eigvals .< -abs(fuzz_factor) )
    result = a && b
    return result
end

function _all_eigenvalues_are_positive(m::AbstractMatrix;
                                       fuzz_factor = _default_fuzz_factor)
    eigvals = LinearAlgebra.eigvals(m)
    a = all( eigvals .> 0 )
    b = all( eigvals .> abs(fuzz_factor) )
    result = a && b
    return result
end

function _is_approximately_negative_definite(m::AbstractMatrix;
                                             tolerance = 1e-4,
                                             fuzz_factor = _default_fuzz_factor)
    # Let `m` be a Hermitian matrix. Then `m` is negative
    # definite if and only if all of its eigenvalues are
    # negative.
    a = _is_approximately_hermitian(m;
                                    tolerance = tolerance)
    b = _all_eigenvalues_are_negative(m;
                                      fuzz_factor = fuzz_factor)
    result = a && b
    return result
end

function _is_approximately_positive_definite(m::AbstractMatrix;
                                             tolerance = 1e-4,
                                             fuzz_factor = _default_fuzz_factor)
    # Let `m` be a Hermitian matrix. Then `m` is positive
    # definite if and only if all of its eigenvalues are
    # positive.
    a = _is_approximately_hermitian(m;
                                    tolerance = tolerance)
    b = _all_eigenvalues_are_positive(m;
                                      fuzz_factor = fuzz_factor)
    result = a && b
    return result
end

end # module


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

using Markdown
using InteractiveUtils

# This Pluto notebook uses @bind for interactivity. When running this notebook outside of Pluto, the following 'mock version' of @bind gives bound variables a default value (instead of an error).
macro bind(def, element)
    quote
        local el = $(esc(element))
        global $(esc(def)) = Core.applicable(Base.get, el) ? Base.get(el) : missing
        el
    end
end

# ╔═╡ c5af5d4a-455b-11eb-0b57-4d8d63615b85
begin
	using MLDatasets
	using SimilaritySearch
	using NeighborhoodApproximationIndex
	using Colors
	using PlutoUI
end

# ╔═╡ 5cd87a9e-5506-11eb-2744-6f02144677ff
md"""
# Using the Neighborhood Approximation (NAPP) Index on CIFAR-10

This example shows how to create a NAPP over datasets of images easily.
"""

# ╔═╡ d8d27dbc-5507-11eb-20e9-0f16ddba080b
md"""
As first step, you must download the dataset (CIFAR10) before fetching the train data, e.g.

```CIFAR10.download()```

apparently, this doesn't work on Pluto and must be done using the terminal directly and accepting the terms and conditions of using the dataset.

You can also accept it from Pluto passing keyworkd argument `i_accept_the_terms_of_use=true`, e.g., `CIFAR10.download(i_accept_the_terms_of_use=true)`.

"""

# ╔═╡ cad95a24-5509-11eb-336f-91e5091503ec
# CIFAR10.download(i_accept_the_terms_of_use=true)

# ╔═╡ a23b0cae-455d-11eb-0e50-4dc31c050cc1
begin
	T, y = CIFAR10.traindata()
	n = size(T, 4)
	X = [Float32.(view(T, :, :, :, i)) for i in 1:n]

	size(X)
	#length(X), size(X[1]), length(X[1])
end

# ╔═╡ 7d8db714-55c8-11eb-37a0-dd7e0744f6e1
function rgbimage(arr)
	A = Matrix{RGB}(undef, 32, 32)
	for i in 1:32, j in 1:32
		A[j, i] = RGB(arr[i, j, :]...)
	end

	A
end

# ╔═╡ 1ce583f6-54fb-11eb-10ad-b5dc9328ca3b
index = DeloneInvIndex(SqL2Distance(), X; numcenters=128, initial=:rand, maxiters=3, ksearch=3);
# index = fit(Sequential, X);

# ╔═╡ 5b743cbc-54fa-11eb-1be4-4b619e1070b2
begin
	sel = @bind example_symbol Slider(1:n, default=rand(1:n))
	distsel = @bind distname PlutoUI.Select([
			"L2" => "Euclidean",
			"L1" => "Manhattan",
			"LInf" => "Chebyshev",
			"p0.5" => "Minkowski with p=0.5",
			"Cos" => "Cosine"
			])

	ksel = @bind k html"<input type='range' min='1' max='15' step='1' default='3'>"

	sep = Matrix{RGB}(undef, 32, 6) # separator
	for i in eachindex(sep)
		sep[i] = RGB(1.0, 1.0, 1.0)
	end

	md"""

	query id: $(sel) |
	distance function: $(distsel)
	k: $(ksel)
	"""
end

# ╔═╡ ac0acb1c-618b-11eb-28f7-c966f3da7449
begin
	q = rgbimage(X[example_symbol]) # just to distinguish easily
	dist = Dict(
		"L2" => L2Distance(),
		"L1" => L1Distance(),
		"LInf" => LInftyDistance(),
		"p0.5" => LpDistance(0.5),
		"Cos" => CosineDistance(),
	)[distname]

	res = KnnResult(k)
	index_ = copy(index, dist=dist)
	with_terminal() do
		println("search time:")
		@time search(index_, X[example_symbol], res)

		for p in res
			print(p.id => p.dist, ", ")
		end
		println("end; k=$(length(res))")
	end
end

# ╔═╡ def63abc-45e7-11eb-231d-11d94709acd3
begin
	h = hcat(q, sep, [rgbimage(X[p.id]) for p in res]...)

	md"""

Query Id: $(example_symbol)
database size: $(length(X))

# Result:
$(h)

note: the blank space separates query from results

	"""
end

# ╔═╡ c1b7e0ac-54fd-11eb-2153-b599f834da36

# ╔═╡ Cell order:
# ╠═5cd87a9e-5506-11eb-2744-6f02144677ff
# ╠═c5af5d4a-455b-11eb-0b57-4d8d63615b85
# ╠═d8d27dbc-5507-11eb-20e9-0f16ddba080b
# ╠═cad95a24-5509-11eb-336f-91e5091503ec
# ╠═a23b0cae-455d-11eb-0e50-4dc31c050cc1
# ╠═7d8db714-55c8-11eb-37a0-dd7e0744f6e1
# ╠═1ce583f6-54fb-11eb-10ad-b5dc9328ca3b
# ╟─5b743cbc-54fa-11eb-1be4-4b619e1070b2
# ╟─ac0acb1c-618b-11eb-28f7-c966f3da7449
# ╟─def63abc-45e7-11eb-231d-11d94709acd3
# ╠═c1b7e0ac-54fd-11eb-2153-b599f834da36


text:
function visit_internal_node(obj::BSPTreeVisitor, arg0::BSPTree)
    return jcall(obj, "visitInternalNode", void, (BSPTree,), arg0)
end

function visit_leaf_node(obj::BSPTreeVisitor, arg0::BSPTree)
    return jcall(obj, "visitLeafNode", void, (BSPTree,), arg0)
end

function visit_order(obj::BSPTreeVisitor, arg0::BSPTree)
    return jcall(obj, "visitOrder", BSPTreeVisitor_Order, (BSPTree,), arg0)
end


text:
function eigenfunction_plotdata(u::StandaloneVertexEigenfunction{T}) where {T}
    v = u.vertex
    orientation = ifelse(T == arb, u.orientation, u.parent(u.orientation) * u.parent(π))
    θ = ifelse(T == arb, u.θ, u.parent(u.θ) * u.parent(π))

    vertex = (Float64[u.vertex[1]], Float64[u.vertex[2]])
    edges = begin
        s1, c1 = sincos(orientation)
        v1 = v + 0.1 * SVector(c1, s1)
        s2, c2 = sincos(orientation + θ)
        v2 = v + 0.1 * SVector(c2, s2)
        (Float64[v1[1], u.vertex[1], v2[1]], Float64[v1[2], u.vertex[2], v2[2]])
    end
    arc = begin
        res = [
            v + 0.1 * SVector(cos(orientation + t * θ), sin(orientation + t * θ))
            for t in range(0, 1, length = 20)
        ]
        (Float64.(getindex.(res, 1)), Float64.(getindex.(res, 2)))
    end

    return vertex, edges, arc
end

function eigenfunction_plotdata(u::StandaloneInteriorEigenfunction{T}) where {T}
    vertex = (Float64[u.vertex[1]], Float64[u.vertex[2]])
    edge = begin
        orientation = ifelse(T == arb, u.orientation, u.parent(u.orientation) * u.parent(π))
        s, c = sincos(orientation)
        v = u.vertex + 0.1 * SVector(c, s)
        (Float64[u.vertex[1], v[1]], Float64[u.vertex[2], v[2]])
    end
    arc = begin
        res = [u.vertex + 0.1 * SVector(cos(θ), sin(θ)) for θ in range(0, 2π, length = 50)]
        (Float64.(getindex.(res, 1)), Float64.(getindex.(res, 2)))
    end

    return vertex, edge, arc
end

function eigenfunction_plotdata(u::StandaloneLightningEigenfunction{T,S}) where {T,S}
    v = u.vertex
    orientation = ifelse(S == arb, u.orientation, u.parent(u.orientation) * u.parent(π))
    θ = ifelse(S == arb, u.θ, u.parent(u.θ) * u.parent(π))

    vertex = (Float64[u.vertex[1]], Float64[u.vertex[2]])
    edges = begin
        s1, c1 = sincos(orientation)
        v1 = v + 0.1 * SVector(c1, s1)
        s2, c2 = sincos(orientation + θ)
        v2 = v + 0.1 * SVector(c2, s2)
        (Float64[v1[1], u.vertex[1], v2[1]], Float64[v1[2], u.vertex[2], v2[2]])
    end
    arc = begin
        res = [
            v + 0.1 * SVector(cos(orientation + t * θ), sin(orientation + t * θ))
            for t in range(0, 1, length = 20)
        ]
        (Float64.(getindex.(res, 1)), Float64.(getindex.(res, 2)))
    end

    charges = begin
        n = div(length(coefficients(u)) - 1, 3) + 1
        cs = [charge(u, i, n, true) for i = 1:n]
        (Float64.(getindex.(cs, 1)), Float64.(getindex.(cs, 2)))
    end

    return vertex, edges, arc, charges
end

@recipe function f(u::StandaloneVertexEigenfunction)
    seriestype := [:path :path :scatter]
    linewidth := [2 3 3]
    markersize := 5
    label --> ["" "u" ""]
    seriescolor := [:blue :blue :red]
    linestyle := [:dot :solid :solid]

    vertex, edges, arc = eigenfunction_plotdata(u)

    x = hcat(
        arc[1],
        [edges[1]; fill(NaN, length(arc[1]) - length(edges[1]))],
        [vertex[1]; fill(NaN, length(arc[1]) - length(vertex[1]))],
    )
    y = hcat(
        arc[2],
        [edges[2]; fill(NaN, length(arc[2]) - length(edges[2]))],
        [vertex[2]; fill(NaN, length(arc[2]) - length(vertex[2]))],
    )

    return (x, y)
end

@recipe function f(u::StandaloneInteriorEigenfunction)
    seriestype := [:path :path :scatter]
    linewidth := [2 2 3]
    markersize := 5
    label --> ["" "" "u"]
    seriescolor := [:blue :blue :red]
    linestyle := [:dot :solid :solid]
    vertex, edge, arc = eigenfunction_plotdata(u)

    x = hcat(
        arc[1],
        [edge[1]; fill(NaN, length(arc[1]) - length(edge[1]))],
        [vertex[1]; fill(NaN, length(arc[1]) - length(vertex[1]))],
    )
    y = hcat(
        arc[2],
        [edge[2]; fill(NaN, length(arc[2]) - length(edge[2]))],
        [vertex[2]; fill(NaN, length(arc[2]) - length(vertex[2]))],
    )
    return (x, y)
end

@recipe function f(u::StandaloneLightningEigenfunction)
    seriestype --> [:path :path :scatter :scatter]
    linewidth := [2 3 3 2]
    markersize := [5 5 5 2]
    label --> ["" "" "u" ""]
    seriescolor := [:blue :blue :red :green]
    linestyle := [:dot :solid :solid :solid]

    vertex, edges, arc, charges = eigenfunction_plotdata(u)

    x = hcat(
        arc[1],
        [edges[1]; fill(NaN, length(arc[1]) - length(edges[1]))],
        [vertex[1]; fill(NaN, length(arc[1]) - length(vertex[1]))],
        [charges[1]; fill(NaN, length(arc[1]) - length(charges[1]))],
    )
    y = hcat(
        arc[2],
        [edges[2]; fill(NaN, length(arc[2]) - length(edges[2]))],
        [vertex[2]; fill(NaN, length(arc[2]) - length(vertex[2]))],
        [charges[2]; fill(NaN, length(arc[2]) - length(charges[2]))],
    )

    return (x, y)
end

@userplot EigenfunctionPlot

@recipe function f(h::EigenfunctionPlot)
    if length(h.args) != 1 || !(typeof(h.args[1]) <: CombinedEigenfunction)
        error(
            "EigenfunctionPlots should be given a CombinedEigenfunction. Got: $(typeof(h.args))",
        )
    end
    u = h.args[1]

    for v in u.us
        @series begin
            label := ""
            v
        end
    end

    return nothing
end

@userplot EigenfunctionHeatmap

@recipe function f(
    h::EigenfunctionHeatmap;
    absolute_value = false,
    twosided = !absolute_value,
    include_exterior = false,
)
    if !(length(h.args) == 3 || length(h.args) == 5) ||
       !(typeof(h.args[1]) <: AbstractDomain) ||
       !(typeof(h.args[2]) <: AbstractEigenfunction) ||
       !(typeof(h.args[3]) <: Union{Real,arb})
        throw(
            ArgumentError(
                "EigenfunctionHeatmap should be given a domain, an eigenfunction, an eigenvalue " *
                "and x, y. Got: $(typeof(h.args))",
            ),
        )
    end
    if length(h.args) == 5
        domain, u, λ, xs, ys = h.args[1:5]
    elseif length(h.args) == 3
        domain, u, λ = h.args[1:3]
        xs = 50
        ys = 50
    end

    vs = vertices(domain)
    if typeof(xs) <: Integer
        xs = range(extrema(Float64.(collect(getindex.(vs, 1))))..., length = xs)
    end
    if typeof(ys) <: Integer
        ys = range(extrema(Float64.(collect(getindex.(vs, 2))))..., length = ys)
    end

    pts = SVector.(domain.parent.(xs'), domain.parent.(ys))
    res = similar(pts, Float64)
    let λ = domain.parent(λ)
        Threads.@threads for i in eachindex(pts)
            if include_exterior || pts[i] ∈ domain
                res[i] = ifelse(absolute_value, abs, identity)(u(pts[i], λ))
            else
                res[i] = 0
            end
        end
    end

    xlims := extrema(xs)
    ylims := extrema(ys)
    label := ""
    aspect_ratio --> :equal

    if twosided
        # Make the color bar symmetric around 0
        m = maximum(abs, res)
        clims --> (-m, m)
    end

    @series begin
        seriestype := :heatmap
        if twosided
            seriescolor --> :balance
        else
            seriescolor --> :matter
        end
        xs, ys, res
    end

    @series begin
        domain, 100, 0
    end

    return nothing
end


text:
type MockSolver <: AbstractMathProgSolver
  vars_decomposition
  cstrs_decomposition
  sp_mult
  sp_prio
  obj_magnitude
  obj_lb
  obj_ub
  vars_branching_priorities
  oracles
  genvarcallbacks
  gencstrcallbacks
end
export MockSolver

function MockSolver()
  MockSolver(nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing)
end

type MockMathProgModel <: AbstractMathProgModel
  solver::MockSolver
end

LinearQuadraticModel(s::MockSolver) = MockMathProgModel(s)
ConicModel(s::MockSolver) = LPQPtoConicBridge(LinearQuadraticModel(s))
supportedcones(s::MockSolver) = [:Free,:Zero,:NonNeg,:NonPos]

################################################################################
######################   BlockDecomposition.BlockSolverInterface ###############
################################################################################
set_constrs_decomposition!(s::MockSolver, cstrs_decomposition_list) =
  (s.cstrs_decomposition = cstrs_decomposition_list)

set_vars_decomposition!(s::MockSolver, vars_decomposition_list) =
  (s.vars_decomposition = vars_decomposition_list)

set_sp_mult!(s::MockSolver, sp_multiplities) =
  (s.sp_mult = sp_multiplities)

set_var_branching_prio!(s::MockSolver, var_priorities) =
  (s.vars_branching_priorities = var_priorities)

set_sp_prio!(s::MockSolver, sp_priorities) =
  (s.sp_prio = sp_priorities)

set_var_generic!(s::MockSolver, genvarsfcts) =
  (s.genvarcallbacks = genvarsfcts)

set_cstr_generic!(s::MockSolver, gencstrcbs) =
  (s.gencstrcallbacks = gencstrcbs)

function set_objective_bounds_and_magnitude!(s::MockSolver, magnitude, lb, ub)
  s.obj_magnitude = (lb > magnitude || ub < magnitude)? NaN : magnitude
  s.obj_lb = (lb > -Inf)? lb : NaN
  s.obj_ub = (ub < Inf)? ub : NaN
end

getcurrentcost(m::MockMathProgModel, varidx) = error("GetCurrentCost not implemented")

set_oracles!(s::MockSolver, oracles) = (s.oracles = oracles)

################################################################################
##################### MathProgBase.SolverInterface #############################
## Loads problem data from the given file
function loadproblem!(m::MockMathProgModel, filename::AbstractString)
  println("loadproblem!(error) not implemented")
end

## Loads the provided problem data to set up the linear programming problem
##  loadproblem!(m::MockMathProgModel, A, l, u, c, lb, ub, sense)
##  which is the following LP
##        minₓ cᵀx
##        s.c. lb ≤ Ax ≤ ub
##              l ≤  x ≤ u
## sense specifies the direction of optimization problem (:Min or :Max)
function loadproblem!(m::MockMathProgModel, A, l, u, c, lb, ub, sense)
  println("Fake optimization.")
end

## Returns a vector containing the lower bounds l on the variables.
getvarLB(m::MockMathProgModel) = println("getvarLB! not implemented")

## Sets the lower bounds on the variables.
setvarLB!(m::MockMathProgModel, l) = println("setvarLB! not implemented")

##  Returns a vector containing the upper bounds u on the variables.
getvarUB(m::MockMathProgModel) = println("getvarUB not implemented")

## Sets the upper bounds on the variables.
setvarUB!(m::MockMathProgModel, u) = println("setvarUB! not implemented")

## Returns a vector containing the lower bounds lb on the linear constraints.
getconstrLB(m::MockMathProgModel) = println("getconstrLB not implemented")

## Sets the lower bounds on the linear constraints.
setconstrLB!(m::MockMathProgModel, lb) = println("setconstrLB! not implemented")

## Returns a vector containing the upper bounds ub on the linear constraints.
getconstrUB(m::MockMathProgModel) = println("getconstrUB not implemented")

## Sets the upper bounds on the linear constraints.
setconstrUB!(m::MockMathProgModel, ub) = println("setconstrUB! not implemented")

## Returns a vector containing the linear objective coefficients c.
getobj(m::MockMathProgModel) = println("getobj not implemented")

## Sets the linear objective coefficients.
setobj!(m::MockMathProgModel, c) = println("setobj! not implemented")

## Returns the full linear constraint matrix A, typically as a SparseMatrixCSC.
getconstrmatrix(m::MockMathProgModel) = error("getconstrmatrix! not implemented")

## Adds a new variable to the model, with lower bound l (-Inf if none), upper
## bound u (Inf if none), and objective coefficient objcoef. Constraint
## coefficients for this new variable are specified in a sparse format: the
## constrcoef vector contains the nonzero coefficients, and the constridx vector
## contains the indices of the corresponding linear constraints.
function addvar!(m::MockMathProgModel, constridx, constrcoef, l, u, objcoef)
  println("addvar! not implemented")
end

## Adds a new variable to the model, with lower bound l (-Inf if none),
## upper bound u (Inf if none), and objective coefficient objcoef. This is
## equivalent to calling the above method with empty arrays for the constraint
## coefficients.
function addvar!(m::MockMathProgModel, l, u, objcoef)
  println("addvar! not implemented")
end

## Adds a new linear constraint to the model, with lower bound lb (-Inf if none)
## and upper bound ub (Inf if none). Coefficients for this new constraint are
## specified in a sparse format: the coef vector contains the nonzero
## coefficients, and the varidx vector contains the indices of the corresponding
## variables.
# function addconstr!(m::MockMathProgModel, varidx, coef, lb, ub)
#   println("addconstr! not implemented")
# end
function addconstr!(m::MockMathProgModel, varidx, coef, lb, ub)
  println("addconstr! not implemented")
end

## Returns the number of linear constraints in the model.
numlinconstr(m::MockMathProgModel) = println("numlinconstr not implemented")

## Returns a vector containing the values of the linear constraints at the
## solution. This is the vector Ax.
getconstrsolution(m::MockMathProgModel) =
  println("getconstrsolution not implemented")

## Returns the dual solution vector corresponding to the variable bounds,
## known as the reduced costs. Not available when integer variables are present.
getreducedcosts(m::MockMathProgModel) =
  println("getreducedcosts not implemented")

######################## SOLVE INTERFACE ######################################

## Returns the solution vector found by the solver.
getsolution(m::MockMathProgModel) = println("getsolution not implemented")

## Returns the objective value of the solution found by the solver. In
## particular, this may be the objective value for the best feasible solution if
## optimality is not attained or proven.
getobjval(m::MockMathProgModel) = println("getobjval not implemented")

## Solves the optimization problem.
function optimize!(m::MockMathProgModel)
  println("Fake optimize!")
end

## Returns the termination status after solving. Possible values include
## :Optimal, :Infeasible, :Unbounded, :UserLimit (iteration limit or timeout),
## and :error. Solvers may return other statuses, for example, when presolve
## indicates that the model is either infeasible or unbounded, but did not
## determine which.
function status(m::MockMathProgModel)
  println("Fake status")
  return :Optimal
end

## Returns the best known bound on the optimal objective value. This is used,
## for example, when a branch-and-bound method is stopped before finishing.
getobjbound(m::AbstractMathProgModel) = println("getobjbound not implemented")

## Returns the final relative optimality gap as optimization terminated.
getobjgap(m::AbstractMathProgModel) = println("getobjgap not implemented")

## Returns an object that may be used to access a solver-specific API for this
## model.
getrawsolver(m::AbstractMathProgModel) = println("getrawsolver not implemented")

##  Returns the total elapsed solution time as reported by the solver.
getsolvetime(m::AbstractMathProgModel) = println("getsolvetime not implemented")

## Sets the optimization sense of the model. Accepted values are :Min and :Max.
setsense!(m::MockMathProgModel, sense) = println("setsense! not implemented")

## Returns the optimization sense of the model.
getsense(m::MockMathProgModel) = println("getsense not implemented")

## Returns the number of variables in the model.
numvar(m::MockMathProgModel) = println("numvar not implemented")

## Returns the total number of constraints in the model.
numconstr(m::MockMathProgModel) = println("numconstr not implemented")

## Release any resources and memory used by the model. Note that the Julia
## garbage collector takes care of this automatically, but automatic collection
## cannot always be forced. This method is useful for more precise control of
## resources, especially in the case of commercial solvers with licensing
## restrictions on the number of concurrent runs. Users must discard the model
## object after this method is invoked.
freemodel!(m::AbstractMathProgModel) = println("freemodel! not implemented")

## Sets the types of the variables to those indicated by the vector v. Valid
## types are :Int for integer, :Cont for continuous, :Bin for binary, :SemiCont
## for semicontinuous, and :SemiInt for semi-integer.
setvartype!(m::MockMathProgModel, typ::Vector{Symbol}) =
    println("setvartype! not implemented")

## Returns a vector indicating the types of each variable, with values described
## above.
getvartype(m::MockMathProgModel) = println("getvartype not implemented")

## It is the philosophy of MathProgBase to not abstract over most solver
## parameters, because very few are universal, and we do not want to make it
## difficult for users who already familiar with the parameters of their solver
## of choice. However, in certain situations an abstraction over parameters is
## needed, for example, in meta-solvers which must adjust parameters of a
## subsolver inside a loop. Parameters set using these methods should override
## any parameters provided in a solver-dependent way. Solvers/models may chose
## to implement the following method:

## Sets solver-independent parameters via keyword arguments. Curent valid
## parameters are TimeLimit and Silent. TimeLimit (Float64): If the solve is not
## completed to optimality tolerances within the given number of seconds, the
## solver should return immediately with status :UserLimit. Silent (Bool): If
## set to true, the solver should disable any output to the console. If set to
## false, the parameter has no effect.
function setparameters!(m::Union{AbstractMathProgSolver, AbstractMathProgModel}; kwargs...)
    println("setparameters! not yet implemented")
end

## If these parameter-setting methods are called on an AbstractMathProgSolver,
## then they should apply to all new models created from the solver
## (but not existing models). If they are called on an AbstractMathProgModel,
## they should apply to that model only. Unrecognized parameters
## (those not listed above) should be ignored or trigger a warning message.


text:
@testset "386.lexicographical-numbers.jl" begin
    @test lexical_order(13) == [1, 10, 11, 12, 13, 2, 3, 4, 5, 6, 7, 8, 9]
    @test lexical_order(112) ==
          [1, 10, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 11, 110, 111, 112, 12,
           13, 14, 15, 16, 17, 18, 19, 2, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 3, 30, 31,
           32, 33, 34, 35, 36, 37, 38, 39, 4, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 5, 50,
           51, 52, 53, 54, 55, 56, 57, 58, 59, 6, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 7,
           70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 8, 80, 81, 82, 83, 84, 85, 86, 87, 88,
           89, 9, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99]
end


text:
using FromFile

@from "../types.jl" import MyInt

myrand = floor(Int, 1000 * rand())

add_same_rand(x::MyInt)::MyInt = MyInt(x.value + myrand)


text:
function send_notification(filename)
    msg = JSON.parsefile(filename)
    TelegramClient(msg["token"]; chat_id=msg["chat_id"])
    result = try sendMessage(text = msg["str"])
        catch nothing
    end
    if result !== nothing
        rm(filename)
    end
end
export send_notification

function create_notification(notification_type, config, usr; params = Dict(), notification_folder = joinpath(Pinguu.base_dir[2:end], "notification/"))
    chat_id_check = haskey(usr, "telegram")
    if config["notification"]["status"] == "true" && chat_id_check
        msg = Dict()
        msg["token"]   = ENV["telegram"]
        msg["chat_id"] = usr["telegram"]
        msg["type"]    = notification_type

        bot_str = "{" * config["name"] * "} "
        msg_str = ""
        pinguus = [
            "\r\n (o_\r\n// \\\r\nV_/_ ",
            "\r\n_o)\r\n// \\\r\nV_/_ ",
            "\r\n (O_\r\n// \\\r\nV_/_",
            "\r\n                (o_\r\n(o_  (o_  // \\\r\n(/)_ (/)_ V_/_ "
        ]
        i = rand(eachindex(pinguus))
        sell_precision = config["base_coin"] == "EUR" ? 2 : config["sell_precision"]

        if notification_type == "buy exec"         && config["notification"]["buy_exec"] == true

            msg_str = bot_str *  " BUY wurde ausgeführt!\r\nOrder: " * string(params["extra_iteration"]) * "\r\nOrder Volumen: " * params["executedQty"] * " " * config["farm_coin"]

        elseif notification_type == "partial buy exec"         && usr["user_id"] == "1"

            msg_str = bot_str *  " PARTIAL BUY wurde ausgeführt!\r\nOrder: " * string(params["extra_iteration"]) * "\r\nOrder Volumen: " * params["executedQty"] * " " * config["farm_coin"]

        elseif notification_type == "take profit"  && config["notification"]["take_profit"] == true

            msg_str = bot_str *  " Take profit!\r\nProfit: " * format(params["val"], precision=sell_precision) * " " * params["coin"] * pinguus[i]

        elseif notification_type == "new cycle"    && config["notification"]["new_cycle"] == true

            msg_str = bot_str *  " Neuer Zyklus wurde begonnen. \r\nPreis: " * params["ticker"] * " " * config["base_coin"]

        elseif notification_type == "cycle closed" && config["notification"]["general_info"] == true

            msg_str = bot_str *  " Der Zyklus wurde abgebrochen. Es wird auf ein neues Signal gewartet."

        elseif notification_type == "no volume"    && config["notification"]["general_info"] == true

            msg_str = bot_str *  " Dein Order Volumen ist aufgebraucht. Bis zum Verkauf wird dieser Bot nichts mehr tun."

        elseif notification_type == "testing"

            msg_str = bot_str * pinguus[i]

        end
        msg["str"] = msg_str
        if msg["str"] != ""
            id   = string(now()) * "-" * lpad(Int(rand(1:1:1e9)), 6, "0") * ".json"
            file = joinpath(notification_folder, id)
            open(file, "w") do f
                JSON.print(f, msg, 4)
            end
        end
    end
end
export create_notification

function send_daily_summary(user_id, telegram_id)
    day = string(today() - Day(1))
    yr,m,d = split(day, "-")
    closed_files = glob(joinpath(Pinguu.base_dir[2:end], "users/" * string(user_id) * "/*/closed_orders/" * yr * "/" * m * ".json"))
    day_profit = 0
    bot_profits = Dict()
    for closed in closed_files
        tmp = JSON.parsefile(closed)
        if haskey(tmp, day)
            if haskey(tmp[day], "profit")
                day_profit += tmp[day]["profit"]
                bot_profits[JSON.parsefile(split(closed, "closed_orders")[1] * "config.json")["name"]] = tmp[day]["profit"]
            end
        end
    end

    msg = "Gestrige Zusammenfassung:
---
Profit: " * format(day_profit, precision=2) * " €
"
    for (k,v) in bot_profits
        msg *= "    " * k * ": " * format(v, precision=2) * " €
"
    end

    TelegramClient(ENV["telegram"]; chat_id=telegram_id)
    sendMessage(text = msg)
end
export send_daily_summary

function send_weekly_summary(user_id, telegram_id)
    day_profit = 0
    bot_profits = Dict()
    for n in 1:1:7
        day = string(today() - Day(n))
        yr,m,d = split(day, "-")
        closed_files = glob(joinpath(Pinguu.base_dir[2:end], "users/" * string(user_id) * "/*/closed_orders/" * yr * "/" * m * ".json"))
        for closed in closed_files
            tmp = JSON.parsefile(closed)
            if haskey(tmp, day)
                if haskey(tmp[day], "profit")
                    tmp_config = JSON.parsefile(split(closed, "closed_orders")[1] * "config.json")
                    if tmp_config["base_coin"] == "EUR"
                        day_profit += tmp[day]["profit"]
                        !haskey(bot_profits, tmp_config["name"]) ? bot_profits[tmp_config["name"]] = 0 : ""
                        bot_profits[tmp_config["name"]] += tmp[day]["profit"]
                    else
                        for (k,trade) in tmp[day]["trades"]
                            day_profit += trade["profit_EUR"]
                            !haskey(bot_profits, tmp_config["name"]) ? bot_profits[tmp_config["name"]] = 0 : ""
                            bot_profits[tmp_config["name"]] += trade["profit_EUR"]
                        end
                    end
                end
            end
        end
    end
    msg = "Wöchentliche Zusammenfassung:
---
Profit: " * format(day_profit, precision=2) * " €
"
    for (k,v) in bot_profits
        msg *= "    " * k * ": " * format(v, precision=2) * " €
"
    end

    TelegramClient(ENV["telegram"]; chat_id=telegram_id)
    sendMessage(text = msg)
end
export send_weekly_summary


text:
using DrWatson
@quickactivate "StatReth"

# %%
using CSV
using DataFrames
using Turing
using Plots

include(srcdir("quap.jl"))
include(srcdir("tools.jl"))

# %%
# Load the data, don't forget to drop everything missing.
d = DataFrame(CSV.File(datadir("exp_raw/cherry_blossoms.csv"), missingstring = "NA"))
d2 = dropmissing(d, :doy)

# %%
using BSplines: BSplineBasis, basismatrix

num_knots = 15
knot_list = quantile(d2.year, range(0, 1, length = num_knots))

basis = BSplineBasis(4, knot_list)
B = basismatrix(basis, d2.year)

@model function spline(doy, B = B)
    α ~ Normal(100, 10)
    w ~ filldist(Normal(0, 2), size(B, 2))
    σ ~ Exponential(1)
    μ = α .+ B * w
    doy ~ MvNormal(μ, σ)
end

m = spline(d2.doy)

# %%
# Sample from the prior. Looks pretty reasonable.
prior = sample(m, Prior(), 100) |> DataFrame
w_str = ["w[$i]" for i in 1:length(basis)]

scatter(d2.year, d2.doy, alpha = 0.3)
for r in eachrow(prior)
    p = r.α .+ B * Array(r[w_str])
    plot!(d2.year, p, color = :black, alpha = 0.2)
end
plot!(legend = false)

# %%
"""
It looks like the prior on the weights "controls" the possible amplitude of the wiggle (as
opposed to the number of knots which controls its frequency).
"""


text:
module SpectralProjectioGradientTests

using OptimPack
using Test

# The Rosenbrock function writes:
#
#    f(x) = sum((1 .- x[1:2:end]).^2) + sum(c10*(x[2:2:end] - x[1:2:end].^2).^2)
#
# The following method returns the cost function f(x) and overwrites
# the values of gx by the gradient ∇f(x).
function rosenbrock_fg!(x::AbstractVector{T},
                        gx::AbstractVector{T}) where {T<:AbstractFloat}
    # Check standard indexing and compatibility of dimensions.
    @assert !Base.has_offset_axes(x, gx)
    @assert size(x) == size(gx)

    # A few constants.
    c1 = T(1)
    c2 = T(2)
    c10 = T(10)
    c200 = T(200)

    # Compute f(x) and store ∇f(x) in gx.
    x1 = x[1:2:end]
    x2 = x[2:2:end]
    t1 = c1 .- x1
    t2 = c10*(x2 - x1.*x1)
    g2 = c200*(x2 - x1.*x1)
    gx[1:2:end] = -c2*(x1 .* g2 + t1)
    gx[2:2:end] = g2
    return sum(t1.*t1) + sum(t2.*t2)
end

function rosenbrock_init!(x0::AbstractVector{T}) where {T<:AbstractFloat}
  x0[1:2:end] .= -1.2
  x0[2:2:end] .=  1.0
  return x0
end

# The following function overwrites `dst` with `src` projected on the positive
# hyperorthant.
function nonnegative_projector!(dst::AbstractArray{T,N},
                                src::AbstractArray{T,N}) where {T,N}
    @assert axes(dst) == axes(src)
    @inbounds for i in eachindex(dst, src)
        dst[i] = max(src[i], zero(T))
    end
    return dst
end

T = Float32
n = 20
x0 = Vector{T}(undef, n)
xexact = ones(T, n) # exact solution

res = spg2(rosenbrock_fg!, copyto!, rosenbrock_init!(x0), 10;
           maxit=500, maxfc=1000, printer=nothing, verb=true)
x1 = res.x
println("Result without bounds: ", sqrt(sum((x1 - xexact).^2)/sum(xexact.^2)))

println()
res = spg2(rosenbrock_fg!,  nonnegative_projector!, rosenbrock_init!(x0), 10;
           maxit=500, maxfc=1000, printer=nothing, verb=true)
x2 = res.x

println("Result without bounds: ", sqrt(sum((x2 - xexact).^2)/sum(xexact.^2)))

end # module


text:
"""
Broadcast a message to all connected web pages to be interpreted by WebSocket listener. For example, in JavaScript:

var sock = new WebSocket('ws://'+window.location.host);
sock.onmessage = function( message ){
    var msg = JSON.parse(message.data);
    console.log(msg);
}
"""
function broadcast(route,args::Dict)
    if haskey(connections,route)
        for (cid,client) in connections[route]
            if isopen(client)
                write(client, json(args))
            end
        end
    end
end
broadcast(r,t,d) = broadcast(r,Dict("type"=>t,"data"=>d))

function broadcast(args::Dict)
    for route in keys(connections)
        for (cid,client) in connections[route]
            if isopen(client)
                write(client, json(args))
            end
        end
    end
end
broadcast(t,d) = broadcast(Dict("type"=>t,"data"=>d))
broadcast(d) = broadcast(Dict("type"=>"say","data"=>d))

"""
Send a message to the specified connection to be interpreted by WebSocket listener. For example, in JavaScript:

var sock = new WebSocket('ws://'+window.location.host);
sock.onmessage = function( message ){
    var msg = JSON.parse(message.data);
    console.log(msg);
}
"""
function message(route,args::Dict)
    id = pop!(args,"id");
    if haskey(connections,route) && haskey(connections[route],id)
        client = connections[route][id]
        if isopen(client)
            write(client,json(args))
        end
    end
end
message(route,mid,mtype,mdata) = message(route,Dict("id" => mid, "type" => mtype, "data" => mdata))
message(route,mid,mdata) = message(route,Dict("id" => mid, "type" => "say", "data" => mdata))

"""
Block Julia control flow until until callback["notify"](name) is called.
"""
function block(f::Function,name)
    conditions[name] = Condition()
    f()
    wait(conditions[name])
    delete!(conditions,name)
    return nothing
end

"""Add a JS library to the current page from a url."""
function add_library(url)
    name = basename(url)
    block(name) do
        Pages.broadcast("script","
            var script = document.createElement('script');
            script.charset = 'utf-8';
            script.type = 'text/javascript';
            script.src = '$(url)';
            script.onload = function() {
                Pages.notify('$(name)');
            };
            document.head.appendChild(script);
        ")
    end
end

mutable struct Element
    id::String
    tag::String
    name::String
    attributes::Dict{String,String}
    style::Dict{String,String}
    innerHTML::String
    parent_id::String

    function Element(;id,tag="div", name="element", attributes=Dict{String,String}(), style=Dict{String,String}(), innerHTML="", parent_id="body")
        new(id,tag,name,attributes,style,innerHTML,parent_id)
    end
end

function update(io::IO,element::Element)
    # Add attributes to element
    for (key,value) in element.attributes
        print(io,"document.getElementById('$(element.id)').setAttribute('$(key)','$(value)');")
    end
    # Add element style
    ioStyle = IOBuffer()
    for (key,value) in element.style
        print(ioStyle,"$(key): $(value);")
    end
    style = String(take!(ioStyle))
    isempty(style) || print(io,"document.getElementById('$(element.id)').setAttribute('style','$(style)');")
    # Add innerHTML to element
    isempty(element.innerHTML) || print(io,"document.getElementById('$(element.id)').innerHTML = '$(element.innerHTML)';")
    return io
end
function update(element::Element)
    script = String(take!(update(IOBuffer(),element)))
    Pages.broadcast("script",script)
end

function append(io::IO,element::Element)
    # Add element if it doesn't already exist
    print(io,"
        var parent = document.getElementById('$(element.parent_id)');
    ")
    if !isempty(element.id)
        print(io,"
            var element = document.getElementById('$(element.id)');
            if (element === null) {
                element = document.createElement('$(element.tag)');
                element.setAttribute('id','$(element.id)');
                parent.appendChild(element);
            };
        ")
    else
        print(io,"parent.appendChild(document.createElement('$(element.tag)'))")
    end
    update(io,element)
end
function append(element::Element)
    script = String(take!(append(IOBuffer(),element)))
    Pages.broadcast("script",script)
end

function remove(io::IO,id::String)
    print(io,"
        var element = document.getElementById('$(id)');
        element.parentNode.removeChild(element);
    ")
    return io
end
function remove(id::String)
    script = String(take!(remove(IOBuffer(),id)))
    Pages.broadcast("script",script)
end

# function add_select(io::IO,options,element::Element)
#     element.tag == "select" || return warn("Element must have tag = select.")
#     add(io,element)
#     remove(io,"option",parent=element.name)
#     # print(io,"""
#     #     $(element.name).selectAll("option").remove();
#     # """)
#     for key in keys(options)
#         print(io,"""
#             $(element.name).append("option").attr("value","$(key)").text("$(options[key])");
#         """)
#     end
#     io
# end
# function add_select(options,element::Element)
#     Pages.broadcast("script",String(take!(add_select(IOBuffer(),options,element))))
# end

# function add_table(io::IO,df::DataFrame;table = Element(tag="table",name="table"),tr = Element(tag="tr",name="row"),th = Element(tag="th",name="header"),td = Element(tag="td",name="cell"))
#     table.tag == "table" || return warn("Element must have tag = table.")
#     tr.tag == "tr" || return warn("Element must have tag = tr.")
#     th.tag == "th" || return warn("Element must have tag = th.")
#     td.tag == "td" || return warn("Element must have tag = td.")
#     add(io,table)
#     remove(io,"tr",parent=table.name)
#     # ==========================================================================
#     # Add header
#     print(io,"""
#         var $(tr.name) = null;
#     """)
#     append(io,tr,parent=table.name)
#     print(io,"""
#         var $(th.name) = null;
#     """)
#     for name in names(df)
#         th.html = string(name)
#         append(io,th,parent=tr.name)
#     end
#     # ==========================================================================
#     # Add data
#     print(io,"""
#         var $(td.name) = null;
#     """)
#     for irow in 1:size(df,1)
#         row = df[irow,:]
#         append(io,tr,parent=table.name)
#         for name in names(df)
#             td.html = string(row[name][1])
#             append(io,td,parent=tr.name)
#         end
#     end
#     io
# end
# function add_table(df::DataFrame;table = Element(tag="table",name="table"),tr = Element(tag="tr",name="row"),th = Element(tag="th",name="header"),td = Element(tag="td",name="cell"))
#     Pages.broadcast("script",String(take!(add_table(IOBuffer(),df,table=table,tr=tr,th=th,td=td))))
# end

max_stars_repo_name: TheGreyNet/Pages

max_issues_repo_name: TheGreyNet/Pages

max_forks_repo_name: TheGreyNet/Pages