text:
@testset "File Reading" begin
    # Test reading a hex edited Nimrod file. The contents are an 8x8 grid
    # with "5" on the diagonals and "-1" on the off diagonals. Data is
    # stored as 2 Byte integers. The coordinate system is set up with (0,0)
    # in the top left corner and each resolution cell being 10x10m.
    @testset "16-Bit Integer Data" begin
        expectedData = ones(Int16, (8,8)) * -1;
        expectedData[[i for i in 1:9:64]] = 5
        expectedData[1,2] = 5
        testFile = readnimrod("test_hexed_composite_2BI.dat")

        @test size(testFile.data) == (8, 8)
        @test testFile.data == expectedData
        @test testFile.gridtype == NimrodFiles.nationalgrid
        @test isapprox(testFile.xpix_size, 10f0)
        @test isapprox(testFile.ypix_size, 10f0)
        @test testFile.llcorner == (0f0, -80f0)
        @test testFile.llcenter == (5f0, -75f0)
        @test testFile.trcenter == (75f0, -5f0)

        @test testFile.hdr_dump[105] == "mm/h*32"
        @test testFile.hdr_dump[106] == "Plr single site radars"
        @test testFile.hdr_dump[107] == "Rainfall rate Composite"
    end

    # Same thing but for 32-Bit integer data
    @testset "32-Bit Integer data" begin
        expectedData = ones(Int32, (8,8)) * -1;
        expectedData[[i for i in 1:9:64]] = 5
        expectedData[1,2] = 5
        testFile = readnimrod("test_hexed_composite_4BI.dat")

        @test size(testFile.data) == (8, 8)
        @test testFile.data == expectedData
        @test testFile.gridtype == NimrodFiles.nationalgrid
        @test isapprox(testFile.xpix_size, 10f0)
        @test isapprox(testFile.ypix_size, 10f0)
        @test testFile.llcorner == (0f0, -80f0)
        @test testFile.llcenter == (5f0, -75f0)
        @test testFile.trcenter == (75f0, -5f0)

        @test testFile.hdr_dump[105] == "mm/h*32"
        @test testFile.hdr_dump[106] == "Plr single site radars"
        @test testFile.hdr_dump[107] == "Rainfall rate Composite"
    end

    # And now 32-Bit Floating Point Data
    @testset "32-Bit Floating Point data" begin
        expectedData = ones(Float32, (8,8)) * -1;
        expectedData[[i for i in 1:9:64]] = 5
        expectedData[1,2] = 5.0
        testFile = readnimrod("test_hexed_composite_4BF.dat")

        @test size(testFile.data) == (8, 8)
        @test testFile.data == expectedData
        @test testFile.gridtype == NimrodFiles.nationalgrid
        @test isapprox(testFile.xpix_size, 10f0)
        @test isapprox(testFile.ypix_size, 10f0)
        @test testFile.llcorner == (0f0, -80f0)
        @test testFile.llcenter == (5f0, -75f0)
        @test testFile.trcenter == (75f0, -5f0)

        @test testFile.hdr_dump[105] == "mm/h*32"
        @test testFile.hdr_dump[106] == "Plr single site radars"
        @test testFile.hdr_dump[107] == "Rainfall rate Composite"
    end
end


text:
using SIMDVectors
using Base.Test

import SIMDVectors: VecRegister

# SIMDVector
for LENGTH in (2, 5, 11)
	for T in (Float32, Float64, Int32, Int64)
		if T <: Integer
			# Use small numbers to prevent overflows
			vals = rand(T(1):T(10), LENGTH)
			vals2 = rand(T(1):T(10), LENGTH)
		else
			vals = rand(T, LENGTH)
			vals2 = rand(T, LENGTH)
		end
		s_vec = load(SIMDVector{LENGTH}, vals)
		s_vec2 = load(SIMDVector{LENGTH}, vals2)

		println(length(vals))

		store_vec = similar(vals)
		store!(store_vec, s_vec)
		@test store_vec == vals

		println("\nTesting unary functions length = $LENGTH, T = $T")
		for f in SIMDVectors.UNARY_FUNCS
			println(f)
			@eval func = $f
			if !method_exists(func, Tuple{T})
				continue
			end
			local f_s_vec
			try
				f_s_vec = func(s_vec)
			catch e
				(isa(e, DomainError) || isa(e, Base.Math.AmosException)) || rethrow(e)
				continue
			end
			@test f_s_vec[1] === func(vals[1])
			@test f_s_vec[end] === func(vals[end])
		end

		println("\nTesting binary functions length = $LENGTH, T = $T")
		for f in SIMDVectors.BINARY_FUNCS
			@eval func = $f
			println(f)
			if !method_exists(func, Tuple{T, T}) || !method_exists(func, Tuple{Vector{T}, Vector{T}})
				continue
			end
			local binary_s_vec
			local binary_vec
			try
				binary_s_vec = func(s_vec, s_vec2)
				binary_vec = func(vals, vals2)
			catch e
				(isa(e, DomainError) || isa(e, Base.Math.AmosException)) || rethrow(e)
				continue
			end

			@test binary_s_vec[1] === binary_vec[1]
			@test binary_s_vec[end] === binary_vec[end]
		end

		println("\nTesting reductions length = $LENGTH, T = $T")
		for (f, f_scal) in SIMDVectors.REDUCTION_FUNCS
			println(f)
			@eval func = $f
			@test func(s_vec) ≈ func(vals)
		end
	end
end

ext: jl


text:
using My-Julia-ML-Package
using Test

@testset "My-Julia-ML-Package.jl" begin
    # Write your tests here.
    @test sum_of_three(3,4,5) == 12
    @test sum_of_three(5,5,5) == 15
    @test sum_of_three(6,6,6) == 18
end


text:
using MLStyle

const data = join(bitstring.(hex2bytes(readline())))
const HEADER_SIZE = 6
const N_PACKETS_MANTISSA_SIZE = 11
const N_BITS_MANTISSA_SIZE = 15

bits2int(bs) = parse(Int, bs; base = 2)

@data Packet begin
    Literal(version::Int, value::Int)
    Operation(version::Int, op,  operands::Vector{Packet})
end

function parse_packet(bits)
    v = bits2int(bits[begin:3])
    t = bits2int(bits[4:6])
    packet, incr = @match t begin
        4 => parse_literal(v, bits[HEADER_SIZE + 1:end])
        _ => parse_operation(v, t, bits[HEADER_SIZE + 1:end])
    end
    packet, incr
end

function parse_literal(version, bits)
    i, guard, s = 1, '1', []

    while guard == '1'
        quintet = bits[i:i+4]
        push!(s, quintet[2:end])

        guard = quintet[1]
        i += 5
    end
    Literal(version, bits2int(join(s))), (i + HEADER_SIZE - 1)
end

function parse_operation(version, op, bits)
    val, incr = @match bits[1] begin
        '0' => begin
            l = bits2int(bits[2:2+N_BITS_MANTISSA_SIZE-1])
            parse_all_packets(bits[2+N_BITS_MANTISSA_SIZE:2+N_BITS_MANTISSA_SIZE+l-1])
        end
        '1' => begin
            l = bits2int(bits[2:2+N_PACKETS_MANTISSA_SIZE-1])
            parse_n_packets(bits[2+N_PACKETS_MANTISSA_SIZE:end], l)
        end
    end
    Operation(version, op, val), incr
end

function parse_all_packets(bits)
    l = []
    offset = 1
    while offset <= length(bits)
        packet, incr = parse_packet(bits[offset:end])
        offset += incr
        push!(l, packet)
    end
    l, offset + HEADER_SIZE + N_BITS_MANTISSA_SIZE
end

function parse_n_packets(bits, n)
    l = []
    offset = 1
    for _ in 1:n
        packet, incr = parse_packet(bits[offset:end])
        offset += incr
        push!(l, packet)
    end
    l, offset + HEADER_SIZE + N_PACKETS_MANTISSA_SIZE
end

parse_bits(bits) = parse_packet(bits) |> first

sum_versions(packet) = @match packet begin
    Literal(;version) => version
    Operation(;version, operands) => sum(sum_versions.(operands)) + version
end

eval(packet::Packet) = @match packet begin
    Literal(_, value) => value
    Operation(_, 0, operands) =>  sum(eval.(operands))
    Operation(_, 1, operands) => prod(eval.(operands))
    Operation(_, 2, operands) => minimum(eval.(operands))
    Operation(_, 3, operands) => maximum(eval.(operands))
    Operation(_, 5, operands) =>  >(eval.(operands)[1:2]...) ? 1 : 0
    Operation(_, 6, operands) =>  <(eval.(operands)[1:2]...) ? 1 : 0
    Operation(_, 7, operands) => ==(eval.(operands)[1:2]...) ? 1 : 0
end

# Part One
data |> parse_bits |> sum_versions |> println

# Part Two
data |> parse_bits |> eval |> println

max_stars_repo_name: pLOPeGG/JuliaOfCode

max_issues_repo_name: pLOPeGG/JuliaOfCode

max_forks_repo_name: pLOPeGG/JuliaOfCode


text:
# Autogenerated wrapper script for jlqml_jll for armv7l-linux-gnueabihf-cxx03
export libjlqml

using libcxxwrap_julia_jll
using Qt5Declarative_jll
using Qt5Svg_jll
JLLWrappers.@generate_wrapper_header("jlqml")
JLLWrappers.@declare_library_product(libjlqml, "libjlqml.so")
function __init__()
    JLLWrappers.@generate_init_header(libcxxwrap_julia_jll, Qt5Declarative_jll, Qt5Svg_jll)
    JLLWrappers.@init_library_product(
        libjlqml,
        "lib/libjlqml.so",
        RTLD_LAZY | RTLD_DEEPBIND,
    )

    JLLWrappers.@generate_init_footer()
end  # __init__()


text:
function drive_pump( mcu::SerialPort, steps::Int, mus_p_step::Int = convert(Int64, round(3e5)) )
    try
        write(mcu, "$mus_p_step,$steps")
        flush(mcu)
        println("$mus_p_step,$steps")
    catch
        @warn "Could not write to microcontroller! Is the correct serial port being used?"
    end
    return nothing
end

stop_pump( mcu::SerialPort ) = drive_pump( mcu, 0, 100 )

function drive_physical(mcu::SerialPort, cd::CalibrationData, vol_per_step, vol, time;
                        steps_per_rot::Float64 = 200.0, sec_per_min = 60.0u"s/minute")
    disp            = cd.beta ± cd.beta_uncertainty
    total_steps     = disp * value( vol ) * value( vol_per_step ) #steps/mL * mL = steps
    sec_per_step    = value( time ) / total_steps
    us_per_step     = sec_per_step * 1000000
    drive_pump( mcu, abs(Int( round( total_steps.val ) )), Int( round( us_per_step.val ).val ) )
    return nothing
end

max_stars_repo_name: JuliaMakers/MakerProjects

max_issues_repo_name: JuliaMakers/MakerProjects

max_forks_repo_name: JuliaMakers/JuliaMakerProjects


text:
using LAR
using PyCall
@pyimport larlib as p

function cmerge(models)
	V = hcat([models[k][1] for k=1:length(models)]...)
	shifts = [0]
	append!(shifts, [size(models[h][1],2) for h in 1:length(models)])
	FV = hcat([models[k][2]+shifts[k] for k=1:length(models)]...)
	EV = hcat([models[k][3]+shifts[k] for k=1:length(models)]...)
	return V,FV,EV
end

function boxes2lar(boxes)
	V = Array{Float64,1}[]
	EV = Array{Int64,1}[]
	FV = Array{Int64,1}[]
	for k=1:size(boxes,2)
		xm,ym,xM,yM = boxes[:,k]
		push!(V,[xm,ym])
		push!(V,[xM,yM])
		push!(V,[xm,yM])
		push!(V,[xM,ym])
		push!(EV,[ 4(k-1)+1, 4(k-1)+3 ])
		push!(EV,[ 4(k-1)+1, 4(k-1)+4 ])
		push!(EV,[ 4(k-1)+2, 4(k-1)+3 ])
		push!(EV,[ 4(k-1)+2, 4(k-1)+4 ])
		push!(FV,[ 4(k-1)+1, 4(k-1)+2, 4(k-1)+3, 4(k-1)+4])
	end
	return hcat(V...), hcat(EV...), hcat(FV...)
end

function boxes3lar(boxes)
	V = Array{Float64,1}[]
	EV = Array{Int64,1}[]
	FV = Array{Int64,1}[]
	for k=1:size(boxes,2)
		xm,ym,zm,xM,yM,zM = boxes[:,k]
		push!(V,[xm,ym,zm])
		push!(V,[xM,yM,zm])
		push!(V,[xm,yM,zm])
		push!(V,[xM,ym,zm])
		push!(V,[xm,ym,zM])
		push!(V,[xM,yM,zM])
		push!(V,[xm,yM,zM])
		push!(V,[xM,ym,zM])

		push!(EV,[ 8(k-1)+1, 8(k-1)+3 ])
		push!(EV,[ 8(k-1)+1, 8(k-1)+4 ])
		push!(EV,[ 8(k-1)+2, 8(k-1)+3 ])
		push!(EV,[ 8(k-1)+2, 8(k-1)+4 ])
		push!(EV,[ 8(k-1)+4+1, 8(k-1)+4+3 ])
		push!(EV,[ 8(k-1)+4+1, 8(k-1)+4+4 ])
		push!(EV,[ 8(k-1)+4+2, 8(k-1)+4+3 ])
		push!(EV,[ 8(k-1)+4+2, 8(k-1)+4+4 ])
		push!(EV,[ 8(k-1)+1, 8(k-1)+4+1 ])
		push!(EV,[ 8(k-1)+2, 8(k-1)+4+2 ])
		push!(EV,[ 8(k-1)+3, 8(k-1)+4+3 ])
		push!(EV,[ 8(k-1)+4, 8(k-1)+4+4 ])

		push!(FV,[ 8(k-1)+1, 8(k-1)+2, 8(k-1)+3, 8(k-1)+4])
		push!(FV,[ 8(k-1)+4+1, 8(k-1)+4+2, 8(k-1)+4+3, 8(k-1)+4+4])
		push!(FV,[ 8(k-1)+1, 8(k-1)+3, 8(k-1)+4+1, 8(k-1)+4+3])
		push!(FV,[ 8(k-1)+1, 8(k-1)+4, 8(k-1)+4+1, 8(k-1)+4+4])
		push!(FV,[ 8(k-1)+2, 8(k-1)+3, 8(k-1)+4+2, 8(k-1)+4+3])
		push!(FV,[ 8(k-1)+2, 8(k-1)+4, 8(k-1)+4+2, 8(k-1)+4+4])
	end
	return hcat(V...), hcat(EV...), hcat(FV...)
end

params = PyObject(pyeval("list([1.,0.,0.,0.1,  0.,1.,0.,0.1,  0.,0.,1.,0.1, 0.,0.,0.,0.1, 100.])"))
glass = p.MATERIAL(params)

function submanifoldMapping(V::Array{Float64,2},FV::Array{Int64,2},pivotFace::Int64)
	FW = [FV[:,k] for k=1:size(FV,2)]
	return submanifoldMapping(V,FW,pivotFace)
end

#function submanifoldMapping(V::Array{Float64,2},FV::Array{Array{Int64,1},1},pivotFace::Int64)
#    tx,ty,tz = V[:,FV[pivotFace][1]]
#    T = eye(4)
#    T[1,4], T[2,4], T[3,4] = -tx,-ty,-tz
#    facet = [ V[:,v] - [tx,ty,tz] for v in FV[pivotFace] ]
#    normal = normalize(p.COVECTOR(facet)[2:end])
#    a = normal
#    b = Float64[0,0,1]
#    if norm(cross(a,b)) < 10^-5.
#    	axis = normalize(cross(a,b))
#    else
#    	axis = b
#    end
#    angle = atan2(norm(cross(a,b)), dot(a,b))
#    # general 3D rotation (Rodrigues' rotation formula)
#    M = eye(4)
#    Cos, Sin = cos(angle), sin(angle)
#    I, u = eye(3), axis
#    Ux = [0        -u[3]      u[2];
#          u[3]        0      -u[1];
#         -u[2]      u[1]        0]
#    UU = [u[1]*u[1]    u[1]*u[2]    u[1]*u[3] ;
#          u[2]*u[1]    u[2]*u[2]    u[2]*u[3] ;
#          u[3]*u[1]    u[3]*u[2]    u[3]*u[3] ]
#    M[1:3,1:3] = Cos*I + Sin*Ux + (1.0-Cos)*UU
#    transform = M *  T
#    return transform
#end

function submanifoldMapping(V::Array{Float64,2},FV::Array{Array{Int64,1},1},pivotFace::Int64)
    tx,ty,tz = V[:,FV[pivotFace][1]]
    T = eye(4)
    T[1,4], T[2,4], T[3,4] = -tx,-ty,-tz
    facet = [ V[:,v] - [tx,ty,tz] for v in FV[pivotFace] ]
	centroid = p.CCOMB(PyObject(facet))
	u1 = facet[1]-centroid
	u2 = facet[2]-centroid
	u3 = cross(u1,u2)
	M = eye(4)
	M[1:3,1:3] = inv([u1 u2 u3])
    transform = M *  T
    return transform
end


text:
using SemidefiniteProgramming

sdp = SparseSDP(maximize=true)

setobj!(sdp, 1, 1, 1, 1.0)
setobj!(sdp, 2, 1, 1, 2.0)
setobj!(sdp, 3, 1, 1, 3.0)
setobj!(sdp, 3, 2, 2, 4.0)

setrhs!(sdp, 1, 10.0)
setcon!(sdp, 1, 1, 1, 1, 1.0)
setcon!(sdp, 1, 2, 1, 1, 1.0)

setrhs!(sdp, 2, 20.0)
setcon!(sdp, 2, 2, 1, 1, 1.0)
setcon!(sdp, 2, 3, 1, 1, 5.0)
setcon!(sdp, 2, 3, 1, 2, 2.0)
setcon!(sdp, 2, 3, 2, 1, 2.0)
setcon!(sdp, 2, 3, 2, 2, 6.0)

println(obj(solve(sdp, CSDP())))


text:
using ThermodynamicIntegration
using Distributions
using Test
using LinearAlgebra
using Turing
@testset "ThermodynamicIntegration.jl" begin
    include("thermint.jl")
    include("turing.jl")
end


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

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 iv = try Base.loaded_modules[Base.PkgId(Base.UUID("6e696c72-6542-2067-7265-42206c756150"), "AbstractPlutoDingetjes")].Bonds.initial_value catch; b -> missing; end
        local el = $(esc(element))
        global $(esc(def)) = Core.applicable(Base.get, el) ? Base.get(el) : iv(el)
        el
    end
end

# ╔═╡ 4934e4de-b03d-419f-a076-9a8116f5ddf5
begin
using Pkg;
Pkg.activate(".") ;
end

# ╔═╡ 0814234d-459a-404b-9253-7f7665ea6a38
begin
Pkg.add(PackageSpec(url="https://github.com/Pocket-titan/DarkMode"))
import DarkMode
DarkMode.enable()
end

# ╔═╡ 14519106-d4cf-4a77-acca-a22b7c426334
using Images, ImageMagick, ImageDraw,  BoundingSphere

# ╔═╡ f5642319-05ee-4731-ad26-80bcd4f6aa7b
begin

### Important
### Webcam related utils

function camera_input(;max_size=200, default_url="https://i.imgur.com/SUmi94P.png")
"""

			<button id="stop" title="Stop video">✖</button>
			<button id="pop-out" title="Pop out/pop in">⏏</button>

		<video playsinline autoplay></video>

		<button id="shutter" title="Click to take a picture">📷</button>

		Enable webcam

""" |> HTML
end

function process_raw_camera_data(raw_camera_data)
	# the raw image data is a long byte array, we need to transform it into something
	# more "Julian" - something with more _structure_.

	# The encoding of the raw byte stream is:
	# every 4 bytes is a single pixel
	# every pixel has 4 values: Red, Green, Blue, Alpha
	# (we ignore alpha for this notebook)

	# So to get the red values for each pixel, we take every 4th value, starting at
	# the 1st:
	reds_flat = UInt8.(raw_camera_data["data"][1:4:end])
	greens_flat = UInt8.(raw_camera_data["data"][2:4:end])
	blues_flat = UInt8.(raw_camera_data["data"][3:4:end])

	# but these are still 1-dimensional arrays, nicknamed 'flat' arrays
	# We will 'reshape' this into 2D arrays:

	width = raw_camera_data["width"]
	height = raw_camera_data["height"]

	# shuffle and flip to get it in the right shape
	reds = reshape(reds_flat, (width, height))' / 255.0
	greens = reshape(greens_flat, (width, height))' / 255.0
	blues = reshape(blues_flat, (width, height))' / 255.0

	# we have our 2D array for each color
	# Let's create a single 2D array, where each value contains the R, G and B value of
	# that pixel

	RGB.(reds, greens, blues)
end

end

# ╔═╡ 1a0324de-ee19-11ea-1d4d-db37f4136ad3
@bind raw_camera_data camera_input(;max_size=100)

# ╔═╡ 43f08085-b9b3-4e9b-b2ff-a0907b48a897
begin

### Important
### contour related utils

# rotate direction clocwise
function clockwise(dir)
    return (dir)%8 + 1
end

# rotate direction counterclocwise
function counterclockwise(dir)
    return (dir+6)%8 + 1
end

# move from current pixel to next in given direction
function move(pixel, image, dir, dir_delta)
    newp = pixel + dir_delta[dir]
    height, width = size(image)
    if (0 < newp[1] <= height) &&  (0 < newp[2] <= width)
        if image[newp]!=0
            return newp
        end
    end
    return CartesianIndex(0, 0)
end

# finds direction between two given pixels
function from_to(from, to, dir_delta)
    delta = to-from
    return findall(x->x == delta, dir_delta)[1]
end

function detect_move(image, p0, p2, nbd, border, done, dir_delta)
    dir = from_to(p0, p2, dir_delta)
    moved = clockwise(dir)
    p1 = CartesianIndex(0, 0)
    while moved != dir ## 3.1
        newp = move(p0, image, moved, dir_delta)
        if newp[1]!=0
            p1 = newp
            break
        end
        moved = clockwise(moved)
    end

    if p1 == CartesianIndex(0, 0)
        return
    end

    p2 = p1 ## 3.2
    p3 = p0 ## 3.2
    done .= false
    while true
        dir = from_to(p3, p2, dir_delta)
        moved = counterclockwise(dir)
        p4 = CartesianIndex(0, 0)
        done .= false
        while true ## 3.3
            p4 = move(p3, image, moved, dir_delta)
            if p4[1] != 0
                break
            end
            done[moved] = true
            moved = counterclockwise(moved)
        end
        push!(border, p3) ## 3.4
        if p3[1] == size(image, 1) || done[3]
            image[p3] = -nbd
        elseif image[p3] == 1
            image[p3] = nbd
        end

        if (p4 == p0 && p3 == p1) ## 3.5
            break
        end
        p2 = p3
        p3 = p4
    end
end

function find_contours(image)
    nbd = 1
    lnbd = 1
    image = Float64.(image)
    contour_list =  Vector{typeof(CartesianIndex[])}()
    done = [false, false, false, false, false, false, false, false]

    # Clockwise Moore neighborhood.
    dir_delta = [CartesianIndex(-1, 0) , CartesianIndex(-1, 1), CartesianIndex(0, 1), CartesianIndex(1, 1), CartesianIndex(1, 0), CartesianIndex(1, -1), CartesianIndex(0, -1), CartesianIndex(-1,-1)]

    height, width = size(image)

    for i=1:height
        lnbd = 1
        for j=1:width
            fji = image[i, j]
            is_outer = (image[i, j] == 1 && (j == 1 || image[i, j-1] == 0)) ## 1 (a)
            is_hole = (image[i, j] >= 1 && (j == width || image[i, j+1] == 0))

            if is_outer || is_hole
                # 2
                border = CartesianIndex[]

                from = CartesianIndex(i, j)

                if is_outer
                    nbd += 1
                    from -= CartesianIndex(0, 1)

                else
                    nbd += 1
                    if fji > 1
                        lnbd = fji
                    end
                    from += CartesianIndex(0, 1)
                end

                p0 = CartesianIndex(i,j)
                detect_move(image, p0, from, nbd, border, done, dir_delta) ## 3
                if isempty(border) ##TODO
                    push!(border, p0)
                    image[p0] = -nbd
                end
                push!(contour_list, border)
            end
            if fji != 0 && fji != 1
                lnbd = abs(fji)
            end

        end
    end
    return contour_list
end

# a contour is a vector of 2 int arrays
function draw_contour(image, color, contour)
    for ind in contour
        image[ind] = color
    end
end
function draw_contours(image, color, contours)
    for cnt in contours
        draw_contour(image, color, cnt)
    end
end

end

# ╔═╡ dfb7c6be-ee0d-11ea-194e-9758857f7b20
begin

### Important
### Object tracker is here

"""
function objecttracker(img)

Return image which tracks green colored objects from the input image

## Details
Steps

- Converts image to HSV space
- Set HSV value range to create binary mask which can identify green objects
- Find contours from that binary mask
- Pick the largest contour area and find its bounding box
- Draw the bounding box on the input image
- return the resultant image

""";
function objecttracker(img)
	hsv_img = HSV.(img)
	channels = channelview(float.(hsv_img))
	hue_img = channels[1,:,:]
	val_img = channels[3,:,:]
	satur_img = channels[2,:,:]
	mask = zeros(size(hue_img))
	h, s, v = 150,  150, 255
	h1, s1, v1 = 120,  80, 90
	for ind in eachindex(hue_img)
	    if hue_img[ind] <= h && satur_img[ind] <= s/255 && val_img[ind] <= v/255
			if  hue_img[ind] >= h1 && satur_img[ind] >= s1/255 && val_img[ind] >= v1/255
	        mask[ind] = 1
			end
	    end
	end
	cnts1 = find_contours(mask)
	if length(cnts1) != 0
		nums = findmax(map(x->length(x),cnts1))[2]
		maxcontourarea = cnts1[nums]
		pts = map(x->[float(x[1]),float(x[2])],maxcontourarea)
		center, radius = boundingsphere(pts)
		center = [ round(Int,  center[1]),  round(Int,  center[2])]
		radius =  round(Int,  radius)
		# draw_contours(img, RGB(1,0,0), cnts1)
		final_image = draw(RGB{N0f8}.(img), Polygon(RectanglePoints(Point(center[2]-radius-10, center[1]-radius-10), Point(center[2]+radius+10, center[1]+radius+10))), RGB(0,1,0))
		# final_image = image
	else
		final_image = img
	end
	return final_image
end;

end

# ╔═╡ 594acafd-01d4-4eee-b9e6-5b886953b5b1
begin
image = process_raw_camera_data(raw_camera_data);
objecttracker(image)
end

# ╔═╡ Cell order:
# ╠═14519106-d4cf-4a77-acca-a22b7c426334
# ╟─f5642319-05ee-4731-ad26-80bcd4f6aa7b
# ╟─dfb7c6be-ee0d-11ea-194e-9758857f7b20
# ╟─1a0324de-ee19-11ea-1d4d-db37f4136ad3
# ╠═594acafd-01d4-4eee-b9e6-5b886953b5b1
# ╟─0814234d-459a-404b-9253-7f7665ea6a38
# ╟─43f08085-b9b3-4e9b-b2ff-a0907b48a897
# ╟─4934e4de-b03d-419f-a076-9a8116f5ddf5

max_stars_repo_name: ashwani-rathee/Sigil

max_issues_repo_name: ashwani-rathee/Sigil

max_forks_repo_name: ashwani-rathee/Sigil


text:
"""
Determine the number of meters per pixel

### Parameters
* `lat`: latitude in radians
* `z`: zoom level

Source: http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#Resolution_and_Scale
"""
function resolution(lat::Real, z::Integer)
    meter_per_pixel = 156543.03 # For zoom = 0 at equator
    meter_per_pixel * cos(lat) / (2^z)
end

"Convert from `lat,lon` to tile numbers (float64)"
function lonlat2tile(lon::Real, lat::Real, z::Integer)
    latradian = deg2rad(lat); n = 2^z
    x = (lon + 180)/360*n
    y = (1 - log(tan(latradian) + 1/cos(latradian))/pi)/2*n
    x, y
end

"Convert from `lat,lon` to tile numbers, rounding them down to integers"
function ilonlat2tile(lon::Real, lat::Real, z::Integer)
    x, y = lonlat2tile(lon, lat, z)
    floor(Int, x), floor(Int, y)
end

"Convert geographical coordinates to tile coordinates"
function lonlat2tile(
        lon::Real, lat::Real, z::Integer, xmin::Real, ymin::Real,
        tilesizex::Integer, tilesizey::Integer
    )
    x, y = lonlat2tile(lon, lat, z)
    floor(Int,(x-xmin)*tilesizex)+1, floor(Int,(y-ymin)*tilesizey)+1
end

lonlat2tile(basemap::BaseMap, lon::Real, lat::Real) = lonlat2tile(
    lon, lat, basemap.zoom, basemap.xmin, basemap.ymin,
    basemap.tilesize[2], basemap.tilesize[1]
)

"""
Convert a box from geographical to tile coordinates (integers), at a given zoom.
"""
function tilebox(
        minlon::Real,
        minlat::Real,
        maxlon::Real,
        maxlat::Real,
        z::Integer
    )
    xmin, ymin = ilonlat2tile(minlon, minlat, z)
    xmax, ymax = ilonlat2tile(maxlon, maxlat, z)
    xmin, ymin, xmax, ymax
end

"Determine the correct tiles for `(xmin, ymin, xmax, ymax)` at zoom `z`"
function correctbox(
        xmin::Integer,
        ymin::Integer,
        xmax::Integer,
        ymax::Integer,
        z::Integer
    )
    new_xmin = max(0, min(xmin, xmax))
    new_ymin = max(0, min(ymin, ymax))
    new_xmax = min(2^z - 1, max(xmin, xmax))
    new_ymax = min(2^z - 1, max(ymin, ymax))
    new_xmin, new_ymin, new_xmax, new_ymax
end

function boxsize(provider::AbstractProvider, xmin, ymin, xmax, ymax)
    abs(xmax - xmin) + 1, abs(ymax - ymin) + 1
end


text:
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#
# Description
# ==============================================================================
#
#   Functions to print the numbers using the text backend.
#
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #

# Printing function for the text backend.
function _pn_text(
    io::IO,
    number::Number;
    always_print_base::Bool = false,
    compact::Bool = true,
    significand_format::String = "%g",
    show_base::Bool = true,
    show_significand::Bool = true,
    multiplication_sign::Char = '×',
    new_decimal_base::Union{Nothing, Number} = nothing
)
    if number isa Rational
        number_str = _render_number_text(number; compact)
    else
        number_str = _render_number_text(
            number;
            always_print_base,
            multiplication_sign,
            new_decimal_base,
            significand_format,
            show_base,
            show_significand
        )
    end

    # Output to the IO buffer
    # ==========================================================================
    print(io, number_str)

    return nothing
end


text:
import AstroTime.AstroDates: Date, Time, year, month, day, j2000

const REFERENCES = (
    (-4713, 12, 31, -2451546),
    (-4712, 01, 01, -2451545),
    ( 0000, 12, 31,  -730122),
    ( 0001, 01, 01,  -730121),
    ( 1500, 02, 28,  -182554),
    ( 1500, 02, 29,  -182553),
    ( 1500, 03, 01,  -182552),
    ( 1582, 10, 04,  -152385),
    ( 1582, 10, 15,  -152384),
    ( 1600, 02, 28,  -146039),
    ( 1600, 02, 29,  -146038),
    ( 1600, 03, 01,  -146037),
    ( 1700, 02, 28,  -109514),
    ( 1700, 03, 01,  -109513),
    ( 1800, 02, 28,   -72990),
    ( 1800, 03, 01,   -72989),
    ( 1858, 11, 15,   -51546),
    ( 1858, 11, 16,   -51545),
    ( 1999, 12, 31,       -1),
    ( 2000, 01, 01,        0),
    ( 2000, 02, 28,       58),
    ( 2000, 02, 29,       59),
    ( 2000, 03, 01,       60),
)

@testset "DateTime" begin
    @testset for ref in REFERENCES
        s = Date(ref[end])
        @test year(s) == ref[1]
        @test month(s) == ref[2]
        @test day(s) == ref[3]
        @test j2000(s) == ref[end]
        @test j2000(Date(ref[1:3]...)) == ref[end]
    end

    @test_throws ArgumentError Date(2018, 2, 29)
    @test_throws ArgumentError Date(2018, 0, 1)
    @test_throws ArgumentError Date(2018, 13, 1)
    @test_throws ArgumentError Time(24, 59, 59.0)
    @test_throws ArgumentError Time(23, 60, 59.0)
    @test_throws ArgumentError Time(23, 59, 61.0)
    @test_throws ArgumentError Time(86401, 0)

    @test Date(2000, 1) == Date(2000, 1, 1)
    @test Date(-2000, 1) == Date(-2000, 1, 1)
end