text:
using Logging

@testset "Travis CI deploy configuration" begin; with_logger(NullLogger()) do
    # Regular tag build
    withenv("TRAVIS_CI" => "true",
            "TRAVIS_PULL_REQUEST" => "false",
            "TRAVIS_REPO_SLUG" => "JuliaDocs/Documenter.jl",
            "TRAVIS_BRANCH" => "master",
            "TRAVIS_TAG" => "v1.2.3",
            "TRAVIS_EVENT_TYPE" => nothing,
            "DOCUMENTER_KEY" => "SGVsbG8sIHdvcmxkLg==",
        ) do
        cfg = Documenter.Travis()
        d = Documenter.deploy_folder(cfg; repo="github.com/JuliaDocs/Documenter.jl.git",
                                     devbranch="master", devurl="dev", push_preview=true)
        @test d.all_ok
        @test d.subfolder == "v1.2.3"
        @test d.repo == "github.com/JuliaDocs/Documenter.jl.git"
        @test d.branch == "gh-pages"
        @test Documenter.documenter_key(cfg) === "SGVsbG8sIHdvcmxkLg=="
        @test Documenter.authentication_method(cfg) === Documenter.SSH
    end
    # Broken tag build
    withenv("TRAVIS_CI" => "true",
            "TRAVIS_PULL_REQUEST" => "false",
            "TRAVIS_REPO_SLUG" => "JuliaDocs/Documenter.jl",
            "TRAVIS_BRANCH" => "master",
            "TRAVIS_TAG" => "not-a-version",
            "TRAVIS_EVENT_TYPE" => nothing,
            "DOCUMENTER_KEY" => "SGVsbG8sIHdvcmxkLg==",
        ) do
        cfg = Documenter.Travis()
        d = Documenter.deploy_folder(cfg; repo="github.com/JuliaDocs/Documenter.jl.git",
                                     devbranch="master", devurl="dev", push_preview=true)
        @test !d.all_ok
    end
    # Regular/broken devbranch build
    withenv("TRAVIS_CI" => "true",
            "TRAVIS_PULL_REQUEST" => "false",
            "TRAVIS_REPO_SLUG" => "JuliaDocs/Documenter.jl",
            "TRAVIS_BRANCH" => "master",
            "TRAVIS_TAG" => nothing,
            "TRAVIS_EVENT_TYPE" => nothing,
            "DOCUMENTER_KEY" => "SGVsbG8sIHdvcmxkLg==",
        ) do
        cfg = Documenter.Travis()
        d = Documenter.deploy_folder(cfg; repo="github.com/JuliaDocs/Documenter.jl.git",
                                     devbranch="master", devurl="hello-world", push_preview=true)
        @test d.all_ok
        @test d.subfolder == "hello-world"
        @test d.repo == "github.com/JuliaDocs/Documenter.jl.git"
        @test d.branch == "gh-pages"
        d = Documenter.deploy_folder(cfg; repo="github.com/JuliaDocs/Documenter.jl.git",
                                     devbranch="not-master", devurl="hello-world", push_preview=true)
        @test !d.all_ok
        @test Documenter.documenter_key(cfg) === "SGVsbG8sIHdvcmxkLg=="
    end
    # Regular pull request build
    withenv("TRAVIS_CI" => "true",
            "TRAVIS_PULL_REQUEST" => "42",
            "TRAVIS_REPO_SLUG" => "JuliaDocs/Documenter.jl",
            "TRAVIS_BRANCH" => "something",
            "TRAVIS_TAG" => nothing,
            "TRAVIS_EVENT_TYPE" => nothing,
            "DOCUMENTER_KEY" => "SGVsbG8sIHdvcmxkLg==",
        ) do
        cfg = Documenter.Travis()
        d = Documenter.deploy_folder(cfg; repo="github.com/JuliaDocs/Documenter.jl.git",
                                     devbranch="master", devurl="hello-world", push_preview=true)
        @test d.all_ok
        @test d.subfolder == "previews/PR42"
        @test d.repo == "github.com/JuliaDocs/Documenter.jl.git"
        @test d.branch == "gh-pages"
        d = Documenter.deploy_folder(cfg; repo="github.com/JuliaDocs/Documenter.jl.git",
                                     devbranch="master", devurl="hello-world", push_preview=false)
        @test !d.all_ok
        @test Documenter.documenter_key(cfg) === "SGVsbG8sIHdvcmxkLg=="
    end
    # Missing/broken environment variables
    withenv("TRAVIS_CI" => "true",
            "TRAVIS_PULL_REQUEST" => "false",
            "TRAVIS_REPO_SLUG" => "JuliaDocs/Documenter.jl",
            "TRAVIS_BRANCH" => "master",
            "TRAVIS_TAG" => "v1.2.3",
            "TRAVIS_EVENT_TYPE" => nothing,
            "DOCUMENTER_KEY" => nothing,
        ) do
        cfg = Documenter.Travis()
        d = Documenter.deploy_folder(cfg; repo="github.com/JuliaDocs/Documenter.jl.git",
                                     devbranch="master", devurl="hello-world", push_preview=false)
        @test !d.all_ok
    end
end end

@testset "GitHub Actions deploy configuration" begin; with_logger(NullLogger()) do
    # Regular tag build with GITHUB_TOKEN
    withenv("GITHUB_EVENT_NAME" => "push",
            "GITHUB_REPOSITORY" => "JuliaDocs/Documenter.jl",
            "GITHUB_REF" => "refs/tags/v1.2.3",
            "GITHUB_ACTOR" => "github-actions",
            "GITHUB_TOKEN" => "SGVsbG8sIHdvcmxkLg==",
            "DOCUMENTER_KEY" => nothing,
        ) do
        cfg = Documenter.GitHubActions()
        d = Documenter.deploy_folder(cfg; repo="github.com/JuliaDocs/Documenter.jl.git",
                                     devbranch="master", devurl="dev", push_preview=true)
        @test d.all_ok
        @test d.subfolder == "v1.2.3"
        @test d.repo == "github.com/JuliaDocs/Documenter.jl.git"
        @test d.branch == "gh-pages"
        @test Documenter.authentication_method(cfg) === Documenter.HTTPS
        @test Documenter.authenticated_repo_url(cfg) === "https://github-actions:SGVsbG8sIHdvcmxkLg==@github.com/JuliaDocs/Documenter.jl.git"
    end
    # Regular tag build with SSH deploy key (SSH key prioritized)
    withenv("GITHUB_EVENT_NAME" => "push",
            "GITHUB_REPOSITORY" => "JuliaDocs/Documenter.jl",
            "GITHUB_REF" => "refs/tags/v1.2.3",
            "GITHUB_ACTOR" => "github-actions",
            "GITHUB_TOKEN" => "SGVsbG8sIHdvcmxkLg==",
            "DOCUMENTER_KEY" => "SGVsbG8sIHdvcmxkLg==",
        ) do
        cfg = Documenter.GitHubActions()
        d = Documenter.deploy_folder(cfg; repo="github.com/JuliaDocs/Documenter.jl.git",
                                     devbranch="master", devurl="dev", push_preview=true)
        @test d.all_ok
        @test d.subfolder == "v1.2.3"
        @test d.repo == "github.com/JuliaDocs/Documenter.jl.git"
        @test d.branch == "gh-pages"
        @test Documenter.authentication_method(cfg) === Documenter.SSH
        @test Documenter.documenter_key(cfg) === "SGVsbG8sIHdvcmxkLg=="
    end
    # Broken tag build
    withenv("GITHUB_EVENT_NAME" => "push",
            "GITHUB_REPOSITORY" => "JuliaDocs/Documenter.jl",
            "GITHUB_REF" => "refs/tags/not-a-version",
            "GITHUB_ACTOR" => "github-actions",
            "GITHUB_TOKEN" => "SGVsbG8sIHdvcmxkLg==",
            "DOCUMENTER_KEY" => nothing,
        ) do
        cfg = Documenter.GitHubActions()
        d = Documenter.deploy_folder(cfg; repo="github.com/JuliaDocs/Documenter.jl.git",
                                     devbranch="master", devurl="dev", push_preview=true)
        @test !d.all_ok
    end
    # Regular devbranch build with GITHUB_TOKEN
    withenv("GITHUB_EVENT_NAME" => "push",
            "GITHUB_REPOSITORY" => "JuliaDocs/Documenter.jl",
            "GITHUB_REF" => "refs/heads/master",
            "GITHUB_ACTOR" => "github-actions",
            "GITHUB_TOKEN" => "SGVsbG8sIHdvcmxkLg==",
            "DOCUMENTER_KEY" => nothing,
        ) do
        cfg = Documenter.GitHubActions()
        d = Documenter.deploy_folder(cfg; repo="github.com/JuliaDocs/Documenter.jl.git",
                  devbranch="master", devurl="hello-world", push_preview=true)
        @test d.all_ok
        @test d.subfolder == "hello-world"
        d = Documenter.deploy_folder(cfg; repo="github.com/JuliaDocs/Documenter.jl.git",
                                     devbranch="not-master", devurl="hello-world", push_preview=true)
        @test !d.all_ok
        @test Documenter.authentication_method(cfg) === Documenter.HTTPS
        @test Documenter.authenticated_repo_url(cfg) === "https://github-actions:SGVsbG8sIHdvcmxkLg==@github.com/JuliaDocs/Documenter.jl.git"
    end
    # Regular devbranch build with SSH deploy key (SSH key prioritized)
    withenv("GITHUB_EVENT_NAME" => "push",
            "GITHUB_REPOSITORY" => "JuliaDocs/Documenter.jl",
            "GITHUB_REF" => "refs/heads/master",
            "GITHUB_ACTOR" => "github-actions",
            "GITHUB_TOKEN" => "SGVsbG8sIHdvcmxkLg==",
            "DOCUMENTER_KEY" => "SGVsbG8sIHdvcmxkLg==",
        ) do
        cfg = Documenter.GitHubActions()
        d = Documenter.deploy_folder(cfg; repo="github.com/JuliaDocs/Documenter.jl.git",
                                     devbranch="master", devurl="hello-world", push_preview=true)
        @test d.all_ok
        @test d.subfolder == "hello-world"
        d = Documenter.deploy_folder(cfg; repo="github.com/JuliaDocs/Documenter.jl.git",
                                     devbranch="not-master", devurl="hello-world", push_preview=true)
        @test !d.all_ok
        @test Documenter.authentication_method(cfg) === Documenter.SSH
        @test Documenter.documenter_key(cfg) === "SGVsbG8sIHdvcmxkLg=="
    end
    # Regular pull request build with GITHUB_TOKEN
    withenv("GITHUB_EVENT_NAME" => "pull_request",
            "GITHUB_REPOSITORY" => "JuliaDocs/Documenter.jl",
            "GITHUB_REF" => "refs/pull/42/merge",
            "GITHUB_ACTOR" => "github-actions",
            "GITHUB_TOKEN" => "SGVsbG8sIHdvcmxkLg==",
            "DOCUMENTER_KEY" => nothing,
        ) do
        cfg = Documenter.GitHubActions()
        d = Documenter.deploy_folder(cfg; repo="github.com/JuliaDocs/Documenter.jl.git",
                                     devbranch="master", devurl="hello-world", push_preview=true)
        @test d.all_ok
        @test d.subfolder == "previews/PR42"
        @test d.repo == "github.com/JuliaDocs/Documenter.jl.git"
        @test d.branch == "gh-pages"
        d = Documenter.deploy_folder(cfg; repo="github.com/JuliaDocs/Documenter.jl.git",
                                     devbranch="not-master", devurl="hello-world", push_preview=false)
        @test !d.all_ok
        @test Documenter.authentication_method(cfg) === Documenter.HTTPS
        @test Documenter.authenticated_repo_url(cfg) === "https://github-actions:SGVsbG8sIHdvcmxkLg==@github.com/JuliaDocs/Documenter.jl.git"
    end
    # Regular pull request build with SSH deploy key (SSH key prioritized)
    withenv("GITHUB_EVENT_NAME" => "pull_request",
            "GITHUB_REPOSITORY" => "JuliaDocs/Documenter.jl",
            "GITHUB_REF" => "refs/pull/42/merge",
            "GITHUB_ACTOR" => "github-actions",
            "GITHUB_TOKEN" => "SGVsbG8sIHdvcmxkLg==",
            "DOCUMENTER_KEY" => "SGVsbG8sIHdvcmxkLg==",
        ) do
        cfg = Documenter.GitHubActions()
        d = Documenter.deploy_folder(cfg; repo="github.com/JuliaDocs/Documenter.jl.git",
                                     devbranch="master", devurl="hello-world", push_preview=true)
        @test d.all_ok
        @test d.subfolder == "previews/PR42"
        @test d.repo == "github.com/JuliaDocs/Documenter.jl.git"
        @test d.branch == "gh-pages"
        d = Documenter.deploy_folder(cfg; repo="github.com/JuliaDocs/Documenter.jl.git",
                                     devbranch="not-master", devurl="hello-world", push_preview=false)
        @test !d.all_ok
        @test Documenter.authentication_method(cfg) === Documenter.SSH
        @test Documenter.documenter_key(cfg) === "SGVsbG8sIHdvcmxkLg=="
    end
    # Regular pull request build with SSH deploy key (SSH key prioritized), but push previews to a different repo and different branch
    withenv("GITHUB_EVENT_NAME" => "pull_request",
            "GITHUB_REPOSITORY" => "JuliaDocs/Documenter.jl",
            "GITHUB_REF" => "refs/pull/42/merge",
            "GITHUB_ACTOR" => "github-actions",
            "GITHUB_TOKEN" => "SGVsbG8sIHdvcmxkLg==",
            "DOCUMENTER_KEY" => "SGVsbG8sIHdvcmxkLg==",
        ) do
        cfg = Documenter.GitHubActions()
        d = Documenter.deploy_folder(cfg; repo="github.com/JuliaDocs/Documenter.jl.git",
                                     devbranch="master", devurl="hello-world", push_preview=true,
                                     repo_previews="github.com/JuliaDocs/Documenter-previews.jl.git",
                                     branch_previews="gh-pages-previews")
        @test d.all_ok
        @test d.subfolder == "previews/PR42"
        @test d.repo == "github.com/JuliaDocs/Documenter-previews.jl.git"
        @test d.branch == "gh-pages-previews"
        d = Documenter.deploy_folder(cfg; repo="github.com/JuliaDocs/Documenter.jl.git",
                                     devbranch="not-master", devurl="hello-world", push_preview=false,
                                     repo_previews="",
                                     branch_previews="")
        @test !d.all_ok
        @test Documenter.authentication_method(cfg) === Documenter.SSH
        @test Documenter.documenter_key(cfg) === "SGVsbG8sIHdvcmxkLg=="
    end
    # Regular pull request build with SSH deploy key (SSH key prioritized), but push previews to a different repo and different branch; use a different deploy key for previews
    withenv("GITHUB_EVENT_NAME" => "pull_request",
            "GITHUB_REPOSITORY" => "JuliaDocs/Documenter.jl",
            "GITHUB_REF" => "refs/pull/42/merge",
            "GITHUB_ACTOR" => "github-actions",
            "GITHUB_TOKEN" => "SGVsbG8sIHdvcmxkLg==",
            "DOCUMENTER_KEY" => "SGVsbG8sIHdvcmxkLg==",
            "DOCUMENTER_KEY_PREVIEWS" => "SGVsbG8sIHdvcmxkLw==",
        ) do
        cfg = Documenter.GitHubActions()
        d = Documenter.deploy_folder(cfg; repo="github.com/JuliaDocs/Documenter.jl.git",
                                     devbranch="master", devurl="hello-world", push_preview=true,
                                     repo_previews="github.com/JuliaDocs/Documenter-previews.jl.git",
                                     branch_previews="gh-pages-previews")
        @test d.all_ok
        @test d.subfolder == "previews/PR42"
        @test d.repo == "github.com/JuliaDocs/Documenter-previews.jl.git"
        @test d.branch == "gh-pages-previews"
        d = Documenter.deploy_folder(cfg; repo="github.com/JuliaDocs/Documenter.jl.git",
                                     devbranch="not-master", devurl="hello-world", push_preview=false,
                                     repo_previews="",
                                     branch_previews="")
        @test !d.all_ok
        @test Documenter.authentication_method(cfg) === Documenter.SSH
        @test Documenter.documenter_key(cfg) === "SGVsbG8sIHdvcmxkLg=="
        @test Documenter.documenter_key_previews(cfg) === "SGVsbG8sIHdvcmxkLw=="
    end
    # Missing environment variables
    withenv("GITHUB_EVENT_NAME" => "push",
            "GITHUB_REPOSITORY" => "JuliaDocs/Documenter.jl",
            "GITHUB_REF" => "refs/tags/v1.2.3",
            "GITHUB_ACTOR" => "github-actions",
            "GITHUB_TOKEN" => nothing,
            "DOCUMENTER_KEY" => nothing,
        ) do
        cfg = Documenter.GitHubActions()
        d = Documenter.deploy_folder(cfg; repo="github.com/JuliaDocs/Documenter.jl.git",
                                     devbranch="master", devurl="hello-world", push_preview=true)
        @test !d.all_ok
    end
end end

@testset "GitLab CI deploy configuration" begin; with_logger(NullLogger()) do
    # Regular tag build
    withenv("GITLAB_CI" => "true",
            "CI_COMMIT_BRANCH" => "master",
            "CI_EXTERNAL_PULL_REQUEST_IID" => "",
            "CI_PROJECT_PATH_SLUG" => "juliadocs-documenter-jl",
            "CI_COMMIT_TAG" => "v1.2.3",
            "CI_PIPELINE_SOURCE" => "push",
            "DOCUMENTER_KEY" => "SGVsbG8sIHdvcmxkLg==",
        ) do
        cfg = Documenter.GitLab()
        d = Documenter.deploy_folder(cfg; repo="github.com/JuliaDocs/Documenter.jl.git",
                                     devbranch="master", devurl="dev", push_preview=true)
        @test d.all_ok
        @test d.subfolder == "v1.2.3"
        @test d.repo == "github.com/JuliaDocs/Documenter.jl.git"
        @test d.branch == "gh-pages"
        @test Documenter.documenter_key(cfg) === "SGVsbG8sIHdvcmxkLg=="
        @test Documenter.authentication_method(cfg) === Documenter.SSH
    end
    # Broken tag build
    withenv("GITLAB_CI" => "true",
            "CI_COMMIT_BRANCH" => "master",
            "CI_EXTERNAL_PULL_REQUEST_IID" => "",
            "CI_PROJECT_PATH_SLUG" => "juliadocs-documenter-jl",
            "CI_COMMIT_TAG" => "not-a-version",
            "CI_PIPELINE_SOURCE" => "push",
            "DOCUMENTER_KEY" => "SGVsbG8sIHdvcmxkLg==",
        ) do
        cfg = Documenter.GitLab()
        d = Documenter.deploy_folder(cfg; repo="github.com/JuliaDocs/Documenter.jl.git",
                                     devbranch="master", devurl="dev", push_preview=true)
        @test !d.all_ok
    end
    # Regular/broken devbranch build
    withenv(
            "GITLAB_CI" => "true",
            "CI_COMMIT_BRANCH" => "master",
            "CI_EXTERNAL_PULL_REQUEST_IID" => "",
            "CI_PROJECT_PATH_SLUG" => "juliadocs-documenter-jl",
            "CI_COMMIT_TAG" => nothing,
            "CI_PIPELINE_SOURCE" => "push",
            "DOCUMENTER_KEY" => "SGVsbG8sIHdvcmxkLg==",
        ) do
        cfg = Documenter.GitLab()
        d = Documenter.deploy_folder(cfg; repo="github.com/JuliaDocs/Documenter.jl.git",
                                     devbranch="master", devurl="hello-world", push_preview=true)
        @test d.all_ok
        @test d.subfolder == "hello-world"
        @test d.repo == "github.com/JuliaDocs/Documenter.jl.git"
        @test d.branch == "gh-pages"
        d = Documenter.deploy_folder(cfg; repo="github.com/JuliaDocs/Documenter.jl.git",
                                     devbranch="not-master", devurl="hello-world", push_preview=true)
        @test !d.all_ok
        @test Documenter.documenter_key(cfg) === "SGVsbG8sIHdvcmxkLg=="
    end
    # Regular pull request build
    withenv("GITLAB_CI" => "true",
            "CI_COMMIT_BRANCH" => "something",
            "CI_EXTERNAL_PULL_REQUEST_IID" => "42",
            "CI_PROJECT_PATH_SLUG" => "juliadocs-documenter-jl",
            "CI_COMMIT_TAG" => nothing,
            "CI_PIPELINE_SOURCE" => "push",
            "DOCUMENTER_KEY" => "SGVsbG8sIHdvcmxkLg==",
        ) do
        cfg = Documenter.GitLab()
        d = Documenter.deploy_folder(cfg; repo="github.com/JuliaDocs/Documenter.jl.git",
                                     devbranch="master", devurl="hello-world", push_preview=true)
        @test d.all_ok
        @test d.subfolder == "previews/PR42"
        @test d.repo == "github.com/JuliaDocs/Documenter.jl.git"
        @test d.branch == "gh-pages"
        d = Documenter.deploy_folder(cfg; repo="github.com/JuliaDocs/Documenter.jl.git",
                                     devbranch="master", devurl="hello-world", push_preview=false)
        @test !d.all_ok
        @test Documenter.documenter_key(cfg) === "SGVsbG8sIHdvcmxkLg=="
    end
    # Missing/broken environment variables
    withenv(
            "GITLAB_CI" => "true",
            "CI_COMMIT_BRANCH" => "master",
            "CI_EXTERNAL_PULL_REQUEST_IID" => "",
            "CI_PROJECT_PATH_SLUG" => "juliadocs-documenter-jl",
            "CI_COMMIT_TAG" => "v1.2.3",
            "CI_PIPELINE_SOURCE" => "push",
            "DOCUMENTER_KEY" => nothing,
        ) do
        cfg = Documenter.GitLab()
        d = Documenter.deploy_folder(cfg; repo="github.com/JuliaDocs/Documenter.jl.git",
                                     devbranch="master", devurl="hello-world", push_preview=false)
        @test !d.all_ok
    end
end end

@testset "Buildkite CI deploy configuration" begin; with_logger(NullLogger()) do
    # Regular tag build
    withenv("BUILDKITE" => "true",
            "BUILDKITE_BRANCH" => "master",
            "BUILDKITE_PULL_REQUEST" => "false",
            "BUILDKITE_TAG" => "v1.2.3",
            "DOCUMENTER_KEY" => "SGVsbG8sIHdvcmxkLg==",
        ) do
        cfg = Documenter.Buildkite()
        d = Documenter.deploy_folder(cfg; repo="github.com/JuliaDocs/Documenter.jl.git",
                                     devbranch="master", devurl="dev", push_preview=true)
        @test d.all_ok
        @test d.subfolder == "v1.2.3"
        @test d.repo == "github.com/JuliaDocs/Documenter.jl.git"
        @test d.branch == "gh-pages"
        @test Documenter.documenter_key(cfg) === "SGVsbG8sIHdvcmxkLg=="
        @test Documenter.authentication_method(cfg) === Documenter.SSH
    end
    # Broken tag build
    withenv("BUILDKITE" => "true",
            "BUILDKITE_BRANCH" => "master",
            "BUILDKITE_PULL_REQUEST" => "false",
            "BUILDKITE_TAG" => "not-a-version",
            "DOCUMENTER_KEY" => "SGVsbG8sIHdvcmxkLg==",
        ) do
        cfg = Documenter.Buildkite()
        d = Documenter.deploy_folder(cfg; repo="github.com/JuliaDocs/Documenter.jl.git",
                                     devbranch="master", devurl="dev", push_preview=true)
        @test !d.all_ok
    end
    # Regular/broken devbranch build
    withenv(
            "BUILDKITE" => "true",
            "BUILDKITE_BRANCH" => "master",
            "BUILDKITE_PULL_REQUEST" => "false",
            "BUILDKITE_TAG" => nothing,
            "DOCUMENTER_KEY" => "SGVsbG8sIHdvcmxkLg==",
        ) do
        cfg = Documenter.Buildkite()
        d = Documenter.deploy_folder(cfg; repo="github.com/JuliaDocs/Documenter.jl.git",
                                     devbranch="master", devurl="hello-world", push_preview=true)
        @test d.all_ok
        @test d.subfolder == "hello-world"
        @test d.repo == "github.com/JuliaDocs/Documenter.jl.git"
        @test d.branch == "gh-pages"
        d = Documenter.deploy_folder(cfg; repo="github.com/JuliaDocs/Documenter.jl.git",
                                     devbranch="not-master", devurl="hello-world", push_preview=true)
        @test !d.all_ok
        @test Documenter.documenter_key(cfg) === "SGVsbG8sIHdvcmxkLg=="
    end
    # Regular pull request build
    withenv("BUILDKITE" => "true",
            "BUILDKITE_BRANCH" => "something",
            "BUILDKITE_PULL_REQUEST" => "42",
            "BUILDKITE_TAG" => nothing,
            "DOCUMENTER_KEY" => "SGVsbG8sIHdvcmxkLg==",
        ) do
        cfg = Documenter.Buildkite()
        d = Documenter.deploy_folder(cfg; repo="github.com/JuliaDocs/Documenter.jl.git",
                                     devbranch="master", devurl="hello-world", push_preview=true)
        @test d.all_ok
        @test d.subfolder == "previews/PR42"
        @test d.repo == "github.com/JuliaDocs/Documenter.jl.git"
        @test d.branch == "gh-pages"
        d = Documenter.deploy_folder(cfg; repo="github.com/JuliaDocs/Documenter.jl.git",
                                     devbranch="master", devurl="hello-world", push_preview=false)
        @test !d.all_ok
        @test Documenter.documenter_key(cfg) === "SGVsbG8sIHdvcmxkLg=="
    end
    # Missing/broken environment variables
    withenv(
            "BUILDKITE" => "true",
            "BUILDKITE_BRANCH" => "master",
            "BUILDKITE_PULL_REQUEST" => "false",
            "BUILDKITE_TAG" => "v1.2.3",
            "DOCUMENTER_KEY" => nothing,
        ) do
        cfg = Documenter.Buildkite()
        d = Documenter.deploy_folder(cfg; repo="github.com/JuliaDocs/Documenter.jl.git",
                                     devbranch="master", devurl="hello-world", push_preview=false)
        @test !d.all_ok
    end
end end

struct CustomConfig <: Documenter.DeployConfig end
Documenter.deploy_folder(::CustomConfig; kwargs...) = Documenter.DeployDecision(; all_ok = true, subfolder = "v1.2.3")
struct BrokenConfig <: Documenter.DeployConfig end

@testset "Custom configuration" begin; with_logger(NullLogger()) do
        cfg = CustomConfig()
        d = Documenter.deploy_folder(cfg; repo="github.com/JuliaDocs/Documenter.jl.git",
                                     devbranch="master", devurl="dev", push_preview=true)
        @test d.all_ok
        @test d.subfolder == "v1.2.3"
        cfg = BrokenConfig()
        @test (@test_logs (:warn, r"Documenter\.deploy_folder\(::BrokenConfig; kwargs\.\.\.\) not implemented") Documenter.deploy_folder(cfg)) == Documenter.DeployDecision(; all_ok = false)
        @test (@test_logs (:warn, r"Documenter could not auto-detect") Documenter.deploy_folder(nothing)) == Documenter.DeployDecision(; all_ok = false)
end end

@testset "Autodetection of deploy system" begin
    withenv("TRAVIS_REPO_SLUG" => "JuliaDocs/Documenter.jl",
            "GITHUB_REPOSITORY" => nothing,
        ) do
        cfg = Documenter.auto_detect_deploy_system()
        @test cfg isa Documenter.Travis
    end
    withenv("TRAVIS_REPO_SLUG" => nothing,
            "GITHUB_REPOSITORY" => "JuliaDocs/Documenter.jl",
        ) do
        cfg = Documenter.auto_detect_deploy_system()
        @test cfg isa Documenter.GitHubActions
    end
    withenv("TRAVIS_REPO_SLUG" => nothing,
            "GITHUB_REPOSITORY" => nothing,
        ) do
        cfg = Documenter.auto_detect_deploy_system()
        @test cfg === nothing
    end
end
##
@testset "Remote repository paths" begin
    uhu = Documenter.user_host_upstream("github.com/JuliaDocs/Documenter.jl.git")
    @test uhu == ("git", "github.com", "git@github.com:JuliaDocs/Documenter.jl.git")

    uhu = Documenter.user_host_upstream("github.com:JuliaDocs/Documenter.jl.git")
    @test uhu == ("git", "github.com", "git@github.com:JuliaDocs/Documenter.jl.git")

    uhu = Documenter.user_host_upstream("gitlab.com/JuliaDocs/Documenter.jl")
    @test uhu == ("git", "gitlab.com", "git@gitlab.com:JuliaDocs/Documenter.jl")

    uhu = Documenter.user_host_upstream("user@page.com:path/to/repo")
    @test uhu == ("user", "page.com", "user@page.com:path/to/repo")

    uhu = Documenter.user_host_upstream("user@page.com/path/to/repo")
    @test uhu == ("user", "page.com", "user@page.com:path/to/repo")

    uhu = Documenter.user_host_upstream("user@subdom.long-page.com:/path/to/repo")
    @test uhu == ("user", "subdom.long-page.com", "user@subdom.long-page.com:path/to/repo")

    @test_throws ErrorException Documenter.user_host_upstream("https://github.com/JuliaDocs/Documenter.jl.git")
    @test_throws ErrorException Documenter.user_host_upstream("user@subdom.long-page.com")
end

@testset "version_tag_strip_build" begin
    using Documenter: version_tag_strip_build
    @test version_tag_strip_build("v1.2.3") == "v1.2.3"
    @test version_tag_strip_build("v1.2.3+build") == "v1.2.3"
    @test version_tag_strip_build("v1.2.3+1") == "v1.2.3"
    @test version_tag_strip_build("v1.2.3-DEV") == "v1.2.3-DEV"
    @test version_tag_strip_build("v1.2.3-DEV+build") == "v1.2.3-DEV"
    @test version_tag_strip_build("v1.2") == "v1.2"
    @test version_tag_strip_build("v1.2+build-build") == "v1.2"
    @test version_tag_strip_build("v1.2-1+build-build") == "v1.2-1"
    @test version_tag_strip_build("v0") == "v0"
    @test version_tag_strip_build("v0+build-build") == "v0"
    @test version_tag_strip_build("v0-A+build-build") == "v0-A"
    # In case the tag does not have v, no v in the output
    @test version_tag_strip_build("1.2") == "1.2"
    @test version_tag_strip_build("1.2.3-DEV+build") == "1.2.3-DEV"
    # If it's not a valid version number
    @test version_tag_strip_build("") === nothing
    @test version_tag_strip_build("+A") === nothing
    @test version_tag_strip_build("X.Y.Z") === nothing
    @test version_tag_strip_build("1#2") === nothing
    @test version_tag_strip_build(".1") === nothing
end


text:
#=
   From https://reference.wolfram.com/language/ref/BinomialDistribution.html
   """
   Compute the probability that there are between 60 and 80 heads in 100 coin flips.
   ... and an unfair coin (p:0.6)
   """

   From Mathematica:
    - fair coin 0.028444
    - unfair coin: 0.543289

   Distributions of variable fair_coin_60_80 (num:0)
   0.00000 =>    9707  (0.970700)
   1.00000 =>     293  (0.029300)

   Distributions of variable unfair_coin_60_80 (num:0)
   1.00000 =>    5455  (0.545500)
   0.00000 =>    4545  (0.454500)

   Cf ~/webppl/binomial_coin.wppl

=#

using Turing
include("jl_utils.jl")

@model function binomial_coin()
    n = 100

    head ~ filldist(flip(0.5),n)
    headUnfair ~ filldist(flip(0.6),n)

    numHeads ~ Dirac(sum(head))
    numHeadsUnfair ~ Dirac(sum(headUnfair))

    fair_coin_60_80 ~ Dirac(numHeads >= 60 && numHeads <= 80)
    unfair_coin_60_80 ~ Dirac(numHeadsUnfair >= 60 && numHeadsUnfair <= 80)

end

model = binomial_coin()

num_chains = 4
# chs = sample(model, Prior(), 1000)
# chs = sample(model, MH(), 10_000)
# chs = sample(model, PG(15), 10_000)
# chs = sample(model, IS(), 10_000)
chs = sample(model, SMC(), 10_000)
# chs = sample(model, SMC(), MCMCThreads(), 10_000, num_chains)

# chs = sample(model, SGLD(), 10_000)
# chs = sample(model,NUTS(), 10_000)
# chs = sample(model,HMC(0.01,5), 10_000)

display(chs)
# display(plot(chs))

show_var_dist_pct(chs,:fair_coin_60_80)
show_var_dist_pct(chs,:unfair_coin_60_80)

ext: jl

max_stars_repo_name: tias/hakank

max_issues_repo_name: tias/hakank

max_forks_repo_name: tias/hakank


text:
function (::DirectEllipseFit)(observations::AbstractObservations)
    @unpack data = observations
    # # Convert the N x 2 matrix to a one-dimensional array of 2D points.
    # ℳ = svectors(transpose(data[1]), Val{2}())
    ℳ = data[1]
    N = length(ℳ)
    𝐃₁ = zeros(N, 3)
    𝐃₂ = zeros(N, 3)
    for n = 1:N
        𝐦 = ℳ[n]
        # Quadratic part of the design matrix.
        𝐃₁[n, 1] = 𝐦[1]^2
        𝐃₁[n, 2] = 𝐦[1]*𝐦[2]
        𝐃₁[n, 3] = 𝐦[2]^2
        # Linear part of the design matrix.
        𝐃₂[n, 1] = 𝐦[1]
        𝐃₂[n, 2] = 𝐦[2]
        𝐃₂[n, 3] = 1.0
    end
    # Quadratic part of the scatter matrix.
    𝐒₁ = 𝐃₁' * 𝐃₁
    # Combined part of the scatter matrix.
    𝐒₂ = 𝐃₁' * 𝐃₂
    # Linear part of the scatter matrix.
    𝐒₃ = 𝐃₂' * 𝐃₂
    # For getting a₂ from a₁.
    𝐓 = -inv(𝐒₃) * 𝐒₂'
    # Reduce scatter matrix.
    𝐌 = 𝐒₁ + 𝐒₂ * 𝐓
    # Premultiply by inv(C₁).
    𝐌₀ = vcat(𝐌[3,:]' / 2, -𝐌[2,:]', 𝐌[1,:]' / 2)
    # Solve eigensystem.
    F = eigen(𝐌₀)
    evec = F.vectors
    evalue = F.values
    # Evaluate a'Ca.
    cond = 4 * evec[1,:] .* evec[3,:] - evec[2,:].^2
    index = findfirst(cond .> 0)
    # Ellipse coefficients.
    𝛉₁ = SVector(evec[:, index]...)
    𝛉 = vcat(𝛉₁, 𝐓 * 𝛉₁)
    return 𝛉 / norm(𝛉)
end


text:
function gaussnodes(pgauss::Int,dim::Int,elemtype::Int)

d0 = pwd();
ii = findlast("Exasim", d0);

# filename = string(d0[1:ii[end]],"Preprocessing/gaussnodes.mat");
# vars = MAT.matread(filename);
#
# xgauss1 = vars["xgauss"][elemtype+1,pgauss,dim];
# wgauss1 = vars["wgauss"][elemtype+1,pgauss,dim];

#fn = string(d0[1:ii[end]],"Preprocessing/gaussnodes.bin");
fn = string(d0[1:ii[end]],"/Version0.1/Julia/Preprocessing/gaussnodes.bin");
tmp = reinterpret(Float64,read(fn));

ndims = Int(tmp[1]);
k1 = 2; k2 = (k1-1)+(ndims);
narrays = Int.(tmp[k1:k2]);
k1 = k2+1; k2 = (k1-1) + prod(narrays);
sz1 = reshape(Int.(tmp[k1:k2]), (narrays...,));
k1 = k2+1; k2 = (k1-1) + prod(narrays);
sz2 = reshape(Int.(tmp[k1:k2]), (narrays...,));
sz = sz1.*sz2;
lz = cumsum([0; sz[:]]);
lz1 = reshape(lz[1:end-1],(narrays...,));
lz2 = reshape(lz[2:end],(narrays...,));

e = elemtype+1;
i = 1;
m1 = k2+1 + lz1[i,e,pgauss,dim];
m2 = m1-1 + lz2[i,e,pgauss,dim]-lz1[i,e,pgauss,dim];
xgauss = reshape(tmp[m1:m2],sz1[i,e,pgauss,dim],sz2[i,e,pgauss,dim]);
i = 2;
m1 = k2+1 + lz1[i,e,pgauss,dim];
m2 = m1-1 + lz2[i,e,pgauss,dim]-lz1[i,e,pgauss,dim];
wgauss = reshape(tmp[m1:m2],sz1[i,e,pgauss,dim],sz2[i,e,pgauss,dim]);

# display(xgauss - xgauss1)
# display(wgauss - wgauss1)

return xgauss, wgauss;

end

max_stars_repo_name: glwagner/Exasim

max_issues_repo_name: glwagner/Exasim

max_forks_repo_name: glwagner/Exasim


text:
#=
    Multi-processing case.
    Requires Distributed to be installed.
    - Uncomment below, specifying number of desired processes (default is number of system cores)
    - Prefix all code below with `@everywhere`
=#
#= using Distributed
addprocs(length(Sys.cpu_info()))
@everywhere =#

import Pkg
Pkg.pkg"activate ."

# using .MyPkg
include("src/Todo.jl")
Settings = MyPkg.Settings
MyPkg.main(ARGS)


text:
"""
Contains templates and a helper macro [`@setupDocstringMarkup`](@ref) to easily
set up consistent docstring formats across modules.
"""
module Documentation

using DocStringExtensions

export @setupDocstringMarkup

@template (FUNCTIONS, MACROS, METHODS) = """
                                         $(TYPEDSIGNATURES)
                                         $(DOCSTRING)
                                         """

@template MODULES = """
                    $(DOCSTRING)

                    # Exports
                    $(EXPORTS)

                    # Imports
                    $(IMPORTS)
                    """

@template TYPES = """
                  $(TYPEDEF)
                  $(DOCSTRING)

                  # Fields
                  $(TYPEDFIELDS)
                  """

"""
Helper macro ensuring consistent docstring markup across modules through
templating.
"""
macro setupDocstringMarkup()
  # This needs to be done in separate `eval`s as otherwise the @template macro
  # will not yet be available for the latter definitions
  __module__.eval(:(using DocStringExtensions))
  __module__.eval(quote
    @template (FUNCTIONS, MACROS, METHODS) = Documentation
    @template MODULES = Documentation
    @template TYPES = Documentation
  end)
end

end


text:
function Base.hash(a::AbstractPrimitive)
    # need special hash since primitives might not be immutable
    flds = fieldnames(typeof(a))
    h = hash(flds) # field symbols
    hash(typeof(a), h) # typename
    for i = 1:length(flds)
        h = hash(a.(i), h) # values
    end
    h
end

function Base.isequal(a::AbstractPrimitive, b::AbstractPrimitive)
    hash(a) == hash(b)
end


text:
using SparseArrays, LinearAlgebra
using JuMP, BilevelJuMP
using Random

function bench_rand(rows, cols, density, optimizer, mode, seed = 1234)

    # seed = 1234
    # rows = 5
    # cols = 5
    # density = 0.4

    rng = Random.MersenneTwister(seed)

    f_A(r, n) = ifelse.(rand(r, n) .> 0.25, 1, -1) .* (15 .+ 30 .* rand(r, n))

    Al = sprand(rng, rows, cols, density, f_A)
    Au = sprand(rng, rows, cols, density, f_A)

    Bl = sprand(rng, rows, cols, density, f_A)
    Bu = sprand(rng, rows, cols, density, f_A)

    bl = 50 * rand(rng, rows)
    bu = 50 * rand(rng, rows)

    s_l = diagm(0 => ifelse.(rand(rng, rows) .> 0.2, 1, -1))
    s_u = diagm(0 => ifelse.(rand(rng, rows) .> 0.2, 1, -1))

    f_c(r, n) = 20 .* 2 .* (rand(r, n) .- 0.5)

    cl = sprand(rng, cols, 0.5, f_c)
    cu = sprand(rng, cols, 0.5, f_c)

    # MOI.empty!(optimizer)
    model = BilevelModel(optimizer, mode = mode)
    try
        JuMP.set_time_limit_sec(model, MAX_TIME)
    catch e
        @show e
        @show "failed to set limit time"
    end
    @variable(Upper(model), -1000 <= x[1:cols] <= 1000)
    @variable(Lower(model), -1000 <= y[1:cols] <= 1000)

    @constraint(Upper(model), (s_u * Au) * x .+ (s_u * Bu) * y .<= s_u * bu)
    @constraint(Lower(model), (s_l * Al) * x .+ (s_l * Bl) * y .<= s_l * bl)

    @objective(Upper(model), Min, cu' * x)
    @objective(Lower(model), Min, cl' * y)

    #=
        Optimize
    =#

    optimize!(model)

    @show primal_st = primal_status(model)
    @show term_st = termination_status(model) #in [MOI.OPTIMAL, MOI.LOCALLY_SOLVED, MOI.ALMOST_LOCALLY_SOLVED]

    solve_t = JuMP.solve_time(model)
    build_t = BilevelJuMP.build_time(model)

    obj_l = try
        objective_value(Lower(model))
    catch
        NaN
    end
    obj_u = try
        objective_value(Upper(model))
    catch
         NaN
    end
    gap = try
        bound = objective_bound(Upper(model))
        abs(obj_u - bound)/max(abs(bound), 1e-8)
    catch
        NaN
    end

    return primal_st, term_st, solve_t, build_t, obj_l, obj_u, gap
end


text:
using Test
using RadeonProRender, GeometryBasics, Colors
const RPR = RadeonProRender

context = RPR.Context(resource=RPR.RPR_CREATION_FLAGS_ENABLE_CPU)
scene = RPR.Scene(context)
matsys = RPR.MaterialSystem(context, 0)
camera = RPR.Camera(context)
lookat!(camera, Vec3f(8, 0, 5), Vec3f(2, 0, 2), Vec3f(0, 0, 1))
RPR.rprCameraSetFocalLength(camera, 45.0)
set!(scene, camera)
set!(context, scene)
env_light = RadeonProRender.EnvironmentLight(context)
image_path = RPR.assetpath("studio026.exr")
img = RPR.Image(context, image_path)
set!(env_light, img)
setintensityscale!(env_light, 1.1)
push!(scene, env_light)

light = RPR.PointLight(context)
transform!(light, Float32[1.0 0.0 0.0 2.0; 0.0 1.0 0.0 0.0; 0.0 0.0 1.0 5.0; 0.0 0.0 0.0 1.0])
f = 20
RPR.setradiantpower!(light, 500 / f, 641 / f, 630 / f)
push!(scene, light)

function add_shape!(scene, context, matsys, mesh; material=RPR.RPR_MATERIAL_NODE_DIFFUSE,
                    color=colorant"green", roughness=0.01)
    rpr_mesh = RadeonProRender.Shape(context, mesh)
    push!(scene, rpr_mesh)
    m = RPR.MaterialNode(matsys, material)
    set!(m, RPR.RPR_MATERIAL_INPUT_COLOR, color)
    set!(m, RPR.RPR_MATERIAL_INPUT_ROUGHNESS, roughness, roughness, roughness, roughness)
    set!(rpr_mesh, m)
    return rpr_mesh, m
end

mesh, mat = add_shape!(scene, context, matsys, Rect3f(Vec3f(-10, -10, -1), Vec3f(20, 20, 1));
                       color=colorant"white")
mesh, mat = add_shape!(scene, context, matsys, Rect3f(Vec3f(0, -10, 0), Vec3f(0.1, 20, 5));
                       color=colorant"white")
mesh, mat = add_shape!(scene, context, matsys, Rect3f(Vec3f(0, -2, 0), Vec3f(5, 0.1, 5));
                       color=colorant"white")
mesh, mat = add_shape!(scene, context, matsys, Rect3f(Vec3f(0, 2, 0), Vec3f(5, 0.1, 5));
                       color=colorant"white")

mesh, mat_sphere = add_shape!(scene, context, matsys, Tesselation(Sphere(Point3f(2, 0, 2), 1.0f0), 100);
                              material=RPR.RPR_MATERIAL_NODE_MICROFACET, roughness=0.2, color=colorant"red")
fb_size = (800, 600)
frame_buffer = RPR.FrameBuffer(context, RGBA, fb_size)
frame_bufferSolved = RPR.FrameBuffer(context, RGBA, fb_size)
set!(context, RPR.RPR_AOV_COLOR, frame_buffer)
set_standard_tonemapping!(context)
clear!(frame_buffer)
path = joinpath(@__DIR__, "test.png")
RPR.rprContextSetParameterByKey1u(context, RPR.RPR_CONTEXT_ITERATIONS, 1)
@time RPR.render(context)
RPR.rprContextResolveFrameBuffer(context, frame_buffer, frame_bufferSolved, false)
RPR.save(frame_bufferSolved, path)

@test isfile(path)


text:
# First attempt model to real data
# Note: currently works (but doesn't produce good parameter estimates) with metropolis hastings
# Need to troubleshoot NUTS/autodiff
# TODO: put this into a function

# Read in the data
flume1Data = prepData("/Users/elizabethmohr/Documents/MSU/RProjects/SAM_Data_Analysis/cleanedData/SCFlume1.csv")
# TODO: Modify to grab data from MySQL database once it's set up

# Set initial and historical conditions
flume1C0 = 330.3375
flume1Bkg = 314.2000

# Specify parameters
τ₋ = 0.1;
τ₊ = 900.0;
α = 1.6;
k = 0.0;
s = 27.0;
sHZ = s/3;
sCH = s - sHZ
qPerUnitHZ = qCalc_powerLaw(1, τ₋, τ₊, α)
p = [τ₋, τ₊, α, k, qPerUnitHZ, sHZ, sCH]

tspan = (0.0, τ₊) # model run time
h(p,t) = flume1Bkg  # background specific conductance
u0 = [330.3375] # concentration in channel after spike

# Problem definition
@sam_model("firstOrder", "power law")
prob = DDEProblem(sam_model!, u0, h, tspan, p)

# Specify model to sample from
flume1Model = fit_sam_model(flume1Data, prob, flume1Bkg, flume1C0, 0.0)

# Sample posterior distributions
# Note: need to start julia with multiple threads for this to work
flume1Chains = sample(flume1Model, NUTS(0.65), MCMCThreads(), 10, 3)

# Save chain 1
write("/MCMCOutput/flume1chains.jls", flume1Chains)

# Evaluate chain mixing
gelmandiag(flume1Chains)

# Convert chains to a dataframe
flume1ChainsDF = DataFrame(flume1Chains)

# Trace plot for alpha parameter
@df flume1Chains plot(
    :iteration,:α, group = (:chain),lw = 3,
    xguidefontsize=15, xlabel = "Iteration",
    ylabel = "α", yguidefontsize = 15,
    legendtitle = "Chain", background_color = :black,
    color_palette = palette([colorant"#3D8D59", colorant"#77BDC6",colorant"#18537E"]),
    legend = :false
    )
savefig("plots/alphaTracePlot.png")

# Trace plot for maximum residence time
@df flume1Chains plot(
    :iteration,:τ₊, group = (:chain),lw = 3,
    xguidefontsize=15, xlabel = "Iteration", ylabel = "τ₊",yguidefontsize = 15,
    legendtitle = "Chain", background_color = :black,
    color_palette = palette([colorant"#3D8D59", colorant"#77BDC6",colorant"#18537E"]),
    legend = :false)
savefig("plots/tauMaxTracePlot.png")

# Remove burn-in
filter!(:iteration => iteration -> iteration > 500, flume1ChainsDF)

# Posterior plot for alpha
@df flume1ChainsDF density(
    :α, group = (:chain),lw = 3,
    xguidefontsize=15, xlabel = "α", ylabel = "Probability Density",yguidefontsize = 15,
    legendtitle = "Chain", background_color = :black,
    color_palette = palette([colorant"#3D8D59", colorant"#77BDC6",colorant"#18537E"])
    )
savefig("plots/alphaPostPlot.png")

# Posterior plot for maximum residence time
@df flume1ChainsDF density(
    :τ₊, group = (:chain),lw = 3,
    xguidefontsize=15, xlabel = "τ₊", ylabel = "Probability Density",yguidefontsize = 15,
    legendtitle = "Chain", background_color = :black,
    color_palette = palette([colorant"#3D8D59", colorant"#77BDC6",colorant"#18537E"]),
    legend = :false
    )
savefig("plots/tauMaxPostPlot.png")

# Plot multiple realizations with data
using GR
flume1Plot = StatsPlots.scatter(
    flume1Data[1,:], flume1Data[2,:], background_color = :black,
    xguidefontsize=15, yguidefontsize = 15, ylabel = "Specific Conductance (uS/cm)",
    markerstrokewidth = 0, markercolor = colorant"#64ADA2", markerstrokecolor = colorant"#64ADA2"
    )
n = 100
rows = rand(1:nrow(flume1ChainsDF), n)
for k in 1:n
    τ₋ = 0.01
    α = flume1ChainsDF[rows[k], :α]
    τ₊ = flume1ChainsDF[rows[k], :τ₊]

    qPerUnitHZ = qCalc_powerLaw(1, τ₋, τ₊, α)
    h(p,t) = flume1Bkg
    resol = solve(remake(prob, u0 = [330.3375], h = h, p = [0.01, τ₊, α, 0.0, qPerUnitHZ, 9.0, 18.0]), MethodOfSteps(RK4()), saveat=1)
    plot!(resol, alpha=0.2, color = "#BBBBBB", legend = :false)
end
xlabel!("Minutes Since Salt Release")

display(flume1Plot)

for k in 1:n
    z = zeros(length(flume1Data[1,:]))
    for j in 1:length(flume1Data[1,:])
        z[j] = flume1ChainsDF[rows[k],j+3]
    end
    plot!(flume1Data[1,:], z, alpha=0.1, color = "#BBBBBB",legend = :false)
end

display(flume1Plot)

max_stars_repo_name: elizabethjmohr/hyporheicBGC

max_issues_repo_name: elizabethjmohr/hyporheicBGC

max_forks_repo_name: elizabethjmohr/hyporheicBGC


text:
cipher(input::AbstractString) = map(x->isletter(x) ? Char(219-Int(x)) : x, lowercase(filter(c -> isletter(c) || isnumeric(c), input)))
encode(input::AbstractString) = join(collect((m.match for m = eachmatch(r"(.{1,5})", cipher(input)))), ' ')
decode(input::AbstractString) = cipher(input)


text:
struct Grid{T}
    τ::Array{T,1}
    dτ::T
    W::Array{T,1}
    dW::T
    ω0::T
    λ0::T
    convt::T
    convw::T
    npts::Int64
    wnpts::Int64
end

function grid(λ0, τ)
    ω0 = 2pi*c/λ0
    dτ = τ[2] - τ[1]
    dW = 2pi/(τ[end]-τ[1])
    W = Vector((0:length(τ)/2)*dW)
    convw = 1/dτ
    convt = dτ
    npts = length(τ)
    wnpts = length(W)
    return Grid(τ, dτ, W, dW, ω0, λ0, convt, convw, npts, wnpts)
end

max_stars_repo_name: SabbahMohammed/Dev

max_issues_repo_name: SabbahMohammed/Dev

max_forks_repo_name: SabbahMohammed/Dev


text:
const NoStyle = Style{:nostyle}
class(::Style) = "markdown"

# Block elements

Markdown.html(io::IO, md::Styled) = html(io, content(md))

function Markdown.html(io::IO, c::Styled{<:AbstractVector})
    for md ∈ content(c)
        html(io, style(c)(md))
        println(io)
    end
end

Markdown.html(io::IO, md::Styled{Markdown.MD}) = html(io, style(md)(md.content))

function Markdown.html(io::IO, header::Styled{Markdown.Header{l}}) where l
    Markdown.withtag(io, "h$l") do
        Markdown.htmlinline(io, style(header)(header.text))
    end
end

# function Markdown.html(io::IO, code::Styled{Markdown.Code})
#     Markdown.withtag(io, :pre) do
#         maybe_lang = !isempty(code.language) ? Any[:class => "language-$(code.language)"] : []
#         Markdown.withtag(io, :code, maybe_lang...) do
#             Markdown.htmlesc(io, code.code)
#             # TODO should print newline if this is longer than one line ?
#         end
#     end
# end

function Markdown.html(io::IO, md::Styled{Markdown.Paragraph})
    Markdown.withtag(io, :p) do
        Markdown.htmlinline(io, style(md)(md.content))
    end
end

function Markdown.html(io::IO, md::Styled{Markdown.BlockQuote})
    Markdown.withtag(io, :blockquote) do
        println(io)
        html(io, style(md)(md.content))
    end
end

function Markdown.html(io::IO, f::Styled{Markdown.Footnote})
    Markdown.withtag(io, :div, :class => "footnote", :id => "footnote-$(f.id)") do
        Markdown.withtag(io, :p, :class => "footnote-title") do
            print(io, f.id)
        end
        html(io, style(f)(f.text))
    end
end

function Markdown.html(io::IO, md::Styled{Markdown.Admonition})
    Markdown.withtag(io, :div, :class => "admonition $(md.category)") do
        Markdown.withtag(io, :p, :class => "admonition-title") do
            print(io, md.title)
        end
        html(io, style(md)(md.content))
    end
end

function Markdown.html(io::IO, md::Styled{Markdown.List})
    maybe_attr = md.ordered > 1 ? Any[:start => string(md.ordered)] : []
    Markdown.withtag(io, Markdown.isordered(content(md)) ? :ol : :ul, maybe_attr...) do
        for item ∈ md.items
            println(io)
            Markdown.withtag(io, :li) do
                html(io, style(md)(item))
            end
        end
        println(io)
    end
end

# function Markdown.html(io::IO, md::Styled{Markdown.HorizontalRule})
#     Markdown.tag(io, :hr)
# end

# Inline elements

Markdown.htmlinline(io::IO, md::Styled) = Markdown.htmlinline(io, content(md))

function Markdown.htmlinline(io::IO, c::Styled{<:AbstractVector})
    for x ∈ content(c)
        Markdown.htmlinline(io, style(c)(x))
    end
end

# function Markdown.htmlinline(io::IO, code::Styled{Markdown.Code})
#     Markdown.withtag(io, :code) do
#         Markdown.htmlesc(io, code.code)
#     end
# end

# function Markdown.htmlinline(io::IO, md::Styled{<:Union{Symbol,AbstractString}})
#     Markdown.htmlesc(io, content(md))
# end

function Markdown.htmlinline(io::IO, md::Styled{Markdown.Bold})
    Markdown.withtag(io, :strong) do
        Markdown.htmlinline(io, style(md)(md.text))
    end
end

function Markdown.htmlinline(io::IO, md::Styled{Markdown.Italic})
    Markdown.withtag(io, :em) do
        Markdown.htmlinline(io, style(md)(md.text))
    end
end

# function Markdown.htmlinline(io::IO, md::Styled{Markdown.Image})
#     Markdown.tag(io, :img, :src => md.url, :alt => md.alt)
# end

# function Markdown.htmlinline(io::IO, f::Styled{Markdown.Footnote})
#     Markdown.withtag(io, :a, :href => "#footnote-$(f.id)", :class => "footnote") do
#         print(io, "[", f.id, "]")
#     end
# end

function Markdown.htmlinline(io::IO, link::Styled{Markdown.Link})
    Markdown.withtag(io, :a, :href => link.url) do
        Markdown.htmlinline(io, style(link)(link.text))
    end
end

# function Markdown.htmlinline(io::IO, br::Styled{Markdown.LineBreak})
#     Markdown.tag(io, :br)
# end

# Extra elements

function Markdown.html(io::IO, md::Styled{Markdown.Table})
    Markdown.withtag(io, :table) do
        for (i, _) ∈ enumerate(md.rows)
            htmltablerow(io, md, i)
        end
    end
end
function htmltablerow(io::IO, md::Styled{Markdown.Table}, i::Integer)
    Markdown.withtag(io, :tr) do
        for (j, c) ∈ enumerate(md.rows[i])
            alignment = md.align[j]
            alignment = alignment === :l ? "left" : alignment === :r ? "right" : "center"
            Markdown.withtag(io, i == 1 ? :th : :td, ("align", alignment)) do
                Markdown.htmlinline(io, style(md)(c))
            end
        end
    end
end


text:
module Quaternionic

using StaticArrays, Latexify, LaTeXStrings, LinearAlgebra, Requires
import Random: AbstractRNG, default_rng, randn!
import Symbolics

export AbstractQuaternion
export Quaternion, QuaternionF64, QuaternionF32, QuaternionF16, imx, imy, imz, 𝐢, 𝐣, 𝐤
export Rotor, RotorF64, RotorF32, RotorF16
export QuatVec, QuatVecF64, QuatVecF32, QuatVecF16
export (⋅), (×), (×̂), normalize
export abs2vec, absvec
export from_float_array, to_float_array,
    from_euler_angles, to_euler_angles,
    from_euler_phases, to_euler_phases!, to_euler_phases,
    from_spherical_coordinates, to_spherical_coordinates,
    from_rotation_matrix, to_rotation_matrix
export distance, distance2
export align
export unflip, unflip!, slerp, squad
export ∂log, log∂log, ∂exp, exp∂exp, slerp∂slerp, slerp∂slerp∂τ, squad∂squad∂t
export precessing_nutating_example

abstract type AbstractQuaternion{T<:Real} <: Number end

include("quaternion.jl")
include("base.jl")
include("algebra.jl")
include("math.jl")
include("random.jl")
include("conversion.jl")
include("distance.jl")
include("alignment.jl")
include("interpolation.jl")
include("gradients.jl")
include("examples.jl")

function __init__()
    @require ForwardDiff="f6369f11-7733-5829-9624-2563aa707210" begin
        # Let ForwardDiff act naturally on quaternions.
        @inline function ForwardDiff.extract_derivative(::Type{T}, y::AbstractQuaternion) where {T}
            Quaternion(ForwardDiff.extract_derivative(T, y.components))
        end
    end

    # @require DifferentialEquations="0c46a032-eb83-5123-abaf-570d42b7fbaa" begin
    # end
end

end  # module


text:
using RecipesBase
#import PlotUtils: cgrad, palette, color_list
using UnitfulRecipes

@recipe function f(x::AbstractArray{S},y::AbstractArray{T}) where {S <: PhysicalQuantity, T <: PhysicalQuantity}
    value.(x), value.(y)
end
@recipe function f(x::AbstractArray{S},y::AbstractArray{T}) where {S <: PhysicalQuantity, T}
    value.(x), y
end
@recipe function f(x::AbstractArray{S},y::AbstractArray{T}) where {S, T <: PhysicalQuantity}
    x, value.(y)
end

max_stars_repo_name: UCLAMAEThreads/ThermofluidQuantities

max_issues_repo_name: UCLAMAEThreads/ThermofluidQuantities

max_forks_repo_name: UCLAMAEThreads/ThermofluidQuantities


text:
# scheduler metadata store

#const MAP_NUM_ENTRIES = 1024*5     # max number of results to store in shared dict
const MAP_NUM_ENTRIES = 1024*100  # max number of results to store in shared dict
const MAP_ENTRY_SZ = 256           # max size of each result stored in shared dict
const DONE_TASKS_SZ = 1024*100     # size of shm, limits the max number of nodes in dag (roughly > (total_dag_nodes / nphyiscal nodes))
const SHARED_TASKS_SZ = 1024*100   # size of shm, limits the max number of nodes in dag (roughly > (total_dag_nodes / nphyiscal nodes))

mutable struct ShmemExecutorMeta <: ExecutorMeta
    path::String
    brokerid::Int
    shmdict::ShmDict
    proclocal::Dict{String,Any}
    allsharedtasks::SharedCircularDeque{TaskIdType}
    sharedtasks::SharedCircularDeque{TaskIdType}
    donetasks::SharedCircularDeque{TaskIdType}
    sharemode::ShareMode
    sharedcounter::ResourceCounter
    trigger::Union{Void,RemoteChannel{Channel{Void}}}
    add_annotation::Function
    del_annotation::Function
    result_callback_pos::Int
    result_callback::Union{Function,Void}

    function ShmemExecutorMeta(path::String, sharethreshold::Int)
        path = joinpath("/dev/shm", startswith(path, '/') ? path[2:end] : path)
        isdir(path) || mkpath(path)

        mkpath(shmdictpath(path))
        mkpath(donetaskspath(path))
        mkpath(sharedtaskspath(path))
        mkpath(allsharedtaskspath(path))
        mkpath(sharedcounterpath(path))

        nentries = get(DagScheduler.META_IMPL, :map_num_entries, MAP_NUM_ENTRIES)
        entry_sz = get(DagScheduler.META_IMPL, :map_entry_sz, MAP_ENTRY_SZ)
        shared_tasks_sz = get(DagScheduler.META_IMPL, :shared_tasks_sz, SHARED_TASKS_SZ)
        done_tasks_sz = get(DagScheduler.META_IMPL, :done_tasks_sz, DONE_TASKS_SZ)

        shmdict = ShmDict(shmdictpath(path), nentries, entry_sz; create=true)
        sharedtasks = SharedCircularDeque{TaskIdType}(sharedtaskspath(path), shared_tasks_sz; create=false)
        allsharedtasks = SharedCircularDeque{TaskIdType}(allsharedtaskspath(path), shared_tasks_sz; create=false)
        donetasks = SharedCircularDeque{TaskIdType}(donetaskspath(path), done_tasks_sz; create=false)
        sharedcounter = ResourceCounter(sharedcounterpath(path), 2; create=true)
        trigger = nothing
        new(path, 0, shmdict, Dict{String,Any}(),
            allsharedtasks, sharedtasks, donetasks,
            ShareMode(sharethreshold), sharedcounter, trigger,
            identity, identity, 0, nothing)
    end
end

donetaskspath(M::ShmemExecutorMeta) = donetaskspath(M.path)
donetaskspath(path::String) = joinpath(path, "tasks.done")
sharedtaskspath(M::ShmemExecutorMeta) = sharedtaskspath(M.path)
sharedtaskspath(path::String) = joinpath(path, "tasks.shared")
allsharedtaskspath(M::ShmemExecutorMeta) = allsharedtaskspath(M.path)
allsharedtaskspath(path::String) = joinpath(path, "tasks.allshared")
sharedcounterpath(M::ShmemExecutorMeta) = sharedcounterpath(M.path)
sharedcounterpath(path::String) = joinpath(path, "counter")
shmdictpath(M::ShmemExecutorMeta) = shmdictpath(M.path)
shmdictpath(path::String) = joinpath(path, "shmdict")

detach(M::ShmemExecutorMeta, pid) = Dict{TaskIdType,TaskIdType}()

function init(M::ShmemExecutorMeta, brokerid::Int; add_annotation=identity, del_annotation=identity, result_callback=nothing)
    M.brokerid = brokerid
    M.add_annotation = add_annotation
    M.del_annotation = del_annotation
    M.result_callback = result_callback
    M.trigger = brokercall(broker_register, M)
    nothing
end

function sync_sharemode(M::ShmemExecutorMeta)
    created, deleted = count(M.sharedcounter)
    if created < deleted
        created = deleted
    end
    shared = created - deleted
    M.sharemode.nshared = shared
    M.sharemode.ncreated = created
    M.sharemode.ndeleted = deleted
    nothing
end

function wait_trigger(M::ShmemExecutorMeta; timeoutsec::Int=5)
    trigger = M.trigger
    fire = true
    if !isready(trigger)
        @schedule begin
            sleep(timeoutsec)
            fire && !isready(trigger) && put!(trigger, nothing)
        end
    end
    take!(trigger)
    fire = false
    if M.result_callback !== nothing
        invoke_result_callbacks(M)
    end
    sync_sharemode(M)
    nothing
end

function pull_trigger(M::ShmemExecutorMeta)
    brokercall(broker_ping, M)
    nothing
end

function invoke_result_callbacks(M::ShmemExecutorMeta)
    L = withlock(M.donetasks.lck) do
        length(M.donetasks)
    end
    ids = TaskIdType[M.donetasks[idx] for idx in (M.result_callback_pos+1):L]
    M.result_callback_pos += length(ids)
    for id in ids
        val = get_result(M, id)
        M.result_callback(id, val)
    end
    nothing
end

function delete!(M::ShmemExecutorMeta)
    empty!(M.donetasks)
    empty!(M.sharedtasks)
    empty!(M.allsharedtasks)
    Semaphores.reset(M.sharedcounter, Cushort[0,0])

    shared_tasks_sz = get(DagScheduler.META_IMPL, :shared_tasks_sz, SHARED_TASKS_SZ)
    done_tasks_sz = get(DagScheduler.META_IMPL, :done_tasks_sz, DONE_TASKS_SZ)

    M.allsharedtasks = SharedCircularDeque{TaskIdType}(allsharedtaskspath(M), shared_tasks_sz; create=true)
    M.sharedtasks = SharedCircularDeque{TaskIdType}(sharedtaskspath(M), shared_tasks_sz; create=true)
    M.donetasks = SharedCircularDeque{TaskIdType}(donetaskspath(M), done_tasks_sz; create=true)
    if myid() === M.brokerid
        deregister(pinger)
        withlock(M.shmdict.lck) do
            empty!(M.shmdict)
        end
    end

    nothing
end

function reset(M::ShmemExecutorMeta; delete::Bool=false, dropdb::Bool=true)
    empty!(M.proclocal)
    DagScheduler.reset(M.sharemode)
    M.add_annotation = identity
    M.del_annotation = identity
    M.result_callback = nothing
    M.result_callback_pos = 0
    nothing
end

function cleanup(M::ShmemExecutorMeta)
    delete!(M.allsharedtasks)
    delete!(M.sharedtasks)
    delete!(M.donetasks)
    delete!(M.sharedcounter)
    delete!(M.shmdict)
    rm(M.path; force=true, recursive=true)
    nothing
end

function share_task(M::ShmemExecutorMeta, id::TaskIdType, allow_dup::Bool)
    canshare = false
    withlock(M.allsharedtasks.lck) do
        if !(id in M.allsharedtasks)
            canshare = true
            push!(M.allsharedtasks, id)
        end
    end

    canshare |= allow_dup

    if canshare
        annotated = M.add_annotation(id)
        withlock(M.sharedtasks.lck) do
            push!(M.sharedtasks, annotated)
        end
        change(M.sharedcounter, [SemBuf(0,1)])
        sync_sharemode(M)
        pull_trigger(M)
    end
    nothing
end

function steal_task(M::ShmemExecutorMeta, selector=default_task_scheduler)
    task = NoTask
    withlock(M.sharedtasks.lck) do
        if !isempty(M.sharedtasks)
            pos = selector(M.sharedtasks[1:end])
            task = splice!(M.sharedtasks, pos)
        end
    end
    if task !== NoTask
        change(M.sharedcounter, [SemBuf(1,1)])
        sync_sharemode(M)
        pull_trigger(M)
        task = M.del_annotation(task)
    end
    task
end

function set_result(M::ShmemExecutorMeta, id::TaskIdType, val; refcount::Int=0, processlocal::Bool=true)
    k = resultpath(M, id)
    M.proclocal[k] = val
    if refcount > 1
        DagScheduler.RefCounter[].refcount(id, refcount)
    end

    if !processlocal
        val = meta_pack(val)
        withlock(M.shmdict.lck) do
            M.shmdict[k] = val
        end

        withlock(M.donetasks.lck) do
            push!(M.donetasks, id)
        end

        pull_trigger(M)
    end

    sync_sharemode(M)

    nothing
end

function get_result(M::ShmemExecutorMeta, id::TaskIdType)
    k = resultpath(M, id)
    if k in keys(M.proclocal)
        val = M.proclocal[k]
    else
        sval = withlock(M.shmdict.lck) do
            M.shmdict[k]
        end
        val = deserialize(IOBuffer(sval))
    end
    meta_unpack(val)
end

function has_result(M::ShmemExecutorMeta, id::TaskIdType)
    k = resultpath(M, id)
    (k in keys(M.proclocal)) && (return true)

    withlock(M.donetasks.lck) do
        id in M.donetasks
    end
end

function decr_result_ref(M::ShmemExecutorMeta, id::TaskIdType)
    #=
    k = resultpath(M, id)

    withlock(M.shmdict.lck) do
        val, refcount = deserialize(IOBuffer(M.shmdict[k]))
        refcount -= 1
        if refcount > 0
            M.shmdict[k] = (val,refcount)
        else
            delete!(M.shmdict, k)
            (k in keys(M.proclocal)) && delete!(M.proclocal, k)
        end
        refcount
    end
    =#
    DagScheduler.RefCounter[].refcount(id, -1)
end

function export_local_result(M::ShmemExecutorMeta, id::TaskIdType, executable)
    k = resultpath(M, id)
    (k in keys(M.proclocal)) || return

    val = repurpose_result_to_export(executable, M.proclocal[k])
    val = meta_pack(val)

    withlock(M.shmdict.lck) do
        M.shmdict[k] = val
    end

    withlock(M.donetasks.lck) do
        push!(M.donetasks, id)
    end

    pull_trigger(M)

    nothing
end

ifpingneeded(recepient::RemoteChannel{Channel{Void}}, val::Void) = !isready(recepient)

function broker_ping()
    put!(pinger, nothing, ifpingneeded)
    nothing
end

function broker_register()
    register(pinger)
end


text:
#= ######################################################
model2D - plotting functions
###################################################### =#

function plot_model(fig, ax, m::Model; shownvec = false, shownodes = false, showcom = false, showleg = true, colors = to_colormap(:rainbow, m.npar), linewidth = 3.0, legpos = "bottom")
    # plot model
    elem_lines = Vector(undef,m.npar)
    plt_elem = Vector(undef,m.npar)
    plt_nodes = Vector(undef,m.npar)
    plt_com = Vector(undef,m.npar)
    plt_nvec = Vector(undef,m.npar)
    # colors = [:red, :green, :blue, :orange]
    # colors = to_colormap(:rainbow, m.npar)
    for p = 1:m.npar
        erange = m.elem2par[p].first:m.elem2par[p].last
        # plot elements
        elem_lines[p] = [Point2f0(m.nodes[m.elem[i].node1].x, m.nodes[m.elem[i].node1].y) =>
                    Point2f0(m.nodes[m.elem[i].node2].x, m.nodes[m.elem[i].node2].y) for i in erange]
        plt_elem[p] = linesegments!(ax, elem_lines[p], color = colors[p], linewidth = linewidth)
        # plot nodes
        if shownodes == true
            local nodes_points = [Point2f0(m.nodes[m.elem[i].node1].x, m.nodes[m.elem[i].node1].y) for i in erange]
            append!(nodes_points, [Point2f0(m.nodes[m.elem[i].node2].x, m.nodes[m.elem[i].node2].y) for i in erange])
            plt_nodes[p] = scatter!(ax, nodes_points, color = colors[p], markersize = 10)
        end
        # plot com
        if showcom == true
            local com_points = [Point2f0(m.elem[i].com.x, m.elem[i].com.y) for i in erange]
            plt_com[p] = scatter!(ax, com_points, color = :grey, markersize = 10)
        end
        # plot nvec as linesegments
        if shownvec == true
            local com_points = [Point2f0(m.elem[i].com.x, m.elem[i].com.y) for i in erange]
            # local nvec_lines = [Point2f0(m.elem[i].com.x, m.elem[i].com.y) =>
            #             Point2f0(m.elem[i].com.x + m.elem[i].nvec.x, m.elem[i].com.y + m.elem[i].nvec.y) for i in erange]
            # plt_nvec[p] = linesegments!(ax, nvec_lines, color = colors[p], linewidth = linewidth)
            # plot nvec as arrows
            scale = 0.1 # default 0.3
            arrowsize = 0.01 # default 0.05
            local nvec_directions = [Point2f0(m.elem[i].nvec.x * scale, m.elem[i].nvec.y * scale) for i in erange]
            lw_arrow = linewidth * 0.5
            arrows!(ax, com_points, nvec_directions, arrowcolor = colors[p], arrowsize = arrowsize, linecolor = colors[p], linewidth = lw_arrow)
        end
    end
    # legend
    if showleg == true
        leg_string = ["part $i" for i = 1:m.npar]
        if legpos == "right"
            leg = fig[1, end+1] = Legend(fig, plt_elem, leg_string)
        elseif legpos == "bottom"
            leg = fig[end+1, 1] = Legend(fig, plt_elem, leg_string, orientation = :horizontal, tellwidth = false, tellheight = true)
        end
        # leg.padding = (5.0f0, 5.0f0, 4.0f0, 4.0f0)
        # leg.linewidth = 1.0
        # leg.patchsize = (5, 3)
        # leg.rowgap = 0.1
        # leg.colgap = 8
        # axislegend(ax, plt_elem, leg_string, position = :rt, orientation = :horizontal)
    end
end

function plot_model_elements(fig, ax, m::Model, erange; shownvec = false, shownodes = false, showcom = false, color = :cyan, linewidth = 3.0, linestyle = nothing)
    # plot only given elements
    # color = :cyan
    # plot elements
    elem_lines = [Point2f0(m.nodes[m.elem[i].node1].x, m.nodes[m.elem[i].node1].y) =>
                Point2f0(m.nodes[m.elem[i].node2].x, m.nodes[m.elem[i].node2].y) for i in erange]
    plt_elem = linesegments!(ax, elem_lines, color = color, linewidth = linewidth, linestyle = linestyle)
    # plot nodes
    if shownodes == true
        local nodes_points = [Point2f0(m.nodes[m.elem[i].node1].x, m.nodes[m.elem[i].node1].y) for i in erange]
        append!(nodes_points, [Point2f0(m.nodes[m.elem[i].node2].x, m.nodes[m.elem[i].node2].y) for i in erange])
        plt_nodes = scatter!(ax, nodes_points, color = color, markersize = 10)
    end
    # plot com
    if showcom == true
        local com_points = [Point2f0(m.elem[i].com.x, m.elem[i].com.y) for i in erange]
        plt_com = scatter!(ax, com_points, color = :grey, markersize = 10)
    end
    # plot nvec as linesegments
    if shownvec == true
        local com_points = [Point2f0(m.elem[i].com.x, m.elem[i].com.y) for i in erange]
        # plot nvec as arrows
        scale = 0.1
        arrowsize = 0.01 # default 0.05
        local nvec_directions = [Point2f0(m.elem[i].nvec.x * scale, m.elem[i].nvec.y * scale) for i in erange]
        lw_arrow = linewidth * 0.5
        arrows!(ax, com_points, nvec_directions, arrowcolor = color, arrowsize = arrowsize, linecolor = color, linewidth = lw_arrow)
    end
end

#= ######################################################
raycast2D - plotting functions
###################################################### =#

function plot_empty_tiles(fig, ax, dx::T1, dy::T1, n::T2; linewidth = 3.0) where {T1<:AbstractFloat, T2<:Integer}
    # plot empty tiles
    # plot x lines
    t_lines = [Point2f0(i*dx, 0) => Point2f0(i*dx, n*dy) for i = 0:1:n]
    plt_elem = linesegments!(ax, t_lines, color = :black, linewidth = linewidth)
    # plot y lines
    t_lines = [Point2f0(0, i*dy) => Point2f0(n*dx, i*dy) for i = 0:1:n]
    linesegments!(ax, t_lines, color = :black, linewidth = linewidth)
end

function plot_occupied_tiles(fig, ax, dx::T1, dy::T1, n::T2, t_occ::Matrix{Union{Vector{T2},Missing}}) where {T1<:AbstractFloat, T2<:Integer}
    # plot occ tiles
    for i = 1:n, j = 1:n
        if !ismissing(t_occ[i,j])
            poly!(ax, Rect((i-1)*dx, (j-1)*dy, dx, dy), color = (:red, 0.3))
        end
    end
end

function plot_points_and_connection(fig, ax, p1::Point2D{T}, p2::Point2D{T}) where T<:AbstractFloat
    linesegments!(ax, [Point2f0(p1.x, p1.y) => Point2f0(p2.x, p2.y)], color = :blue, linewidth = 3)
    scatter!(ax, Point2f0(p1.x, p1.y), color = :green, markersize = 15)
    scatter!(ax, Point2f0(p2.x, p2.y), color = :red, markersize = 15)
end

#= ######################################################
view2D - plotting functions
###################################################### =#

function plot_existing(fig, ax, m::Model, e::T, mat; color = :yellow, linewidth = 2) where T<:Integer
    # plot a single element e with all its existing connections
    exist = Vector{T}()
    for i = 1:m.nelem
        if mat[e,i] != 0
            push!(exist, i)
        end
    end
    # plot rays
    # color = :yellow
    ray_lines = [Point2f0(m.elem[e].com.x, m.elem[e].com.y) =>
                Point2f0(m.elem[i].com.x, m.elem[i].com.y) for i in exist]
    plt_ray = linesegments!(ax, ray_lines, color = color, linewidth = linewidth)
end

function plot_model_shadow_1to1(fig, ax, m::Model, mat, source, target)
    # plot specified parts of model with their values in global colormap
    # plot source
    color_source = :yellow
    ns = (m.elem2par[source].last - m.elem2par[source].first + 1)
    source_lines = Vector{Pair{Point{2,Float32},Point{2,Float32}}}(undef,ns)
    erange_source = m.elem2par[source].first:m.elem2par[source].last
    source_lines = [Point2f0(m.nodes[m.elem[i].node1].x, m.nodes[m.elem[i].node1].y) =>
                Point2f0(m.nodes[m.elem[i].node2].x, m.nodes[m.elem[i].node2].y) for i=erange_source]
    # plot target
    nt = (m.elem2par[target].last - m.elem2par[target].first + 1)
    target_lines = Vector{Pair{Point{2,Float32},Point{2,Float32}}}(undef,nt)
    erange_target = m.elem2par[target].first:m.elem2par[target].last
    target_lines = [Point2f0(m.nodes[m.elem[i].node1].x, m.nodes[m.elem[i].node1].y) =>
                Point2f0(m.nodes[m.elem[i].node2].x, m.nodes[m.elem[i].node2].y) for i=erange_target]
    hitcount = zeros(Int64,nt)
    for i = 1:nt
        etarget = m.elem2par[target].first - 1 + i
        hitcount[i] = sum(mat[erange_source,etarget])
    end
    # all parts except source/target
    rest = collect(1:m.npar)
    filter!(x->x != target, rest)
    filter!(x->x != source, rest)
    color_rest = :blue
    nr = 0
    for p in rest
        nr += (m.elem2par[p].last - m.elem2par[p].first + 1)
    end
    rest_lines = Vector{Pair{Point{2,Float32},Point{2,Float32}}}(undef,nr)
    s1 = 0
    s2 = 0
    for p in rest
        s1 = (s2 + 1)
        s2 = (s1 + (m.elem2par[p].last - m.elem2par[p].first))
        erange_rest = m.elem2par[p].first:m.elem2par[p].last
        rest_lines[s1:s2] = [Point2f0(m.nodes[m.elem[i].node1].x, m.nodes[m.elem[i].node1].y) =>
                Point2f0(m.nodes[m.elem[i].node2].x, m.nodes[m.elem[i].node2].y) for i=erange_rest]
    end
    # plot it
    plt_source = linesegments!(ax, source_lines, color = color_source, linewidth = 3)
    plt_target = linesegments!(ax, target_lines, color = hitcount, colormap = Reverse(:Greys_3), linewidth = 3)
    plt_rest = linesegments!(ax, rest_lines, color = color_rest, linewidth = 3)
end

function plot_model_shadow_1toAll(fig, ax, m::Model, mat, source)
    # plot specified parts of model with their values in global colormap
    # plot source
    color_source = :yellow
    ns = (m.elem2par[source].last - m.elem2par[source].first + 1)
    source_lines = Vector{Pair{Point{2,Float32},Point{2,Float32}}}(undef,ns)
    erange_source = m.elem2par[source].first:m.elem2par[source].last
    source_lines = [Point2f0(m.nodes[m.elem[i].node1].x, m.nodes[m.elem[i].node1].y) =>
                Point2f0(m.nodes[m.elem[i].node2].x, m.nodes[m.elem[i].node2].y) for i=erange_source]
    # plot targets
    nt = m.nelem - ns
    target = collect(1:m.npar)
    filter!(x->x != source, target)
    target_lines = Vector{Pair{Point{2,Float32},Point{2,Float32}}}(undef,nt)
    hitcount = zeros(Int64,nt)
    s1 = 0
    s2 = 0
    for p in target
        s1 = (s2 + 1)
        s2 = (s1 + (m.elem2par[p].last - m.elem2par[p].first))
        erange_target = m.elem2par[p].first:m.elem2par[p].last
        target_lines[s1:s2] = [Point2f0(m.nodes[m.elem[i].node1].x, m.nodes[m.elem[i].node1].y) =>
                Point2f0(m.nodes[m.elem[i].node2].x, m.nodes[m.elem[i].node2].y) for i=erange_target]
        k = 0
        for j = s1:s2
            k += 1
            etarget = erange_target[k]
            hitcount[j] = sum(mat[erange_source,etarget])
        end
    end
    # plot it
    plt_source = linesegments!(ax, source_lines, color = color_source, linewidth = 5)
    plt_target = linesegments!(ax, target_lines, color = hitcount, colormap = :coolwarm, linewidth = 5)
    # colorbar
    cbar = fig[1, end+1] = Colorbar(fig, plt_target, label = "hit-intensity")
    cbar.width = 30
    cbar.height = Relative(2/3)
    valmin = minimum(hitcount)
    valmax = maximum(hitcount)
    valdelta = (valmax - valmin) / 10
    cbar.ticks = valmin:valdelta:valmax
end

#= ######################################################
therm2D - plotting functions
###################################################### =#

function plot_model_with_value(fig, ax, m::Model, val::Vector{T}, val_label; parts = 1:m.npar, cmap = :jet, linewidth = 5.0, showcbar = true, cbarpos = "right") where T<:AbstractFloat
    # plot specified parts of model with their values in global colormap
    n = 0
    for p in parts
        n += (m.elem2par[p].last - m.elem2par[p].first + 1)
    end
    pval = Vector{T}(undef,n)
    elem_lines = Vector{Pair{Point{2,Float32},Point{2,Float32}}}(undef,n)
    s1 = 0
    s2 = 0
    for p in parts
        s1 = (s2 + 1)
        s2 = (s1 + (m.elem2par[p].last - m.elem2par[p].first))
        # println(s1, " --> ", s2)
        erange = m.elem2par[p].first:m.elem2par[p].last
        pval[s1:s2] = val[erange]
        elem_lines[s1:s2] = [Point2f0(m.nodes[m.elem[i].node1].x, m.nodes[m.elem[i].node1].y) =>
                Point2f0(m.nodes[m.elem[i].node2].x, m.nodes[m.elem[i].node2].y) for i=erange]
    end
    plt_elem = linesegments!(ax, elem_lines, color = pval, colormap = cmap, linewidth = linewidth)
    # all at once
    # elem_lines = [Point2f0(m.nodes[m.elem[i].node1].x, m.nodes[m.elem[i].node1].y) =>
    #             Point2f0(m.nodes[m.elem[i].node2].x, m.nodes[m.elem[i].node2].y) for i=1:m.nelem]
    # plt_elem = linesegments!(ax, elem_lines, color = val, colormap = :viridis, linewidth = 3)
    # colorbar
    if showcbar == true
        if cbarpos == "right"
            cbar = fig[1, end+1] = Colorbar(fig, plt_elem, label = val_label)
        elseif cbarpos == "bottom"
            cbar = fig[end+1,1] = Colorbar(fig, plt_elem, label = val_label)
            cbar.vertical = false
        end
        # cbar.width = 12
        # cbar.height = Relative(2/3)
        # cbar.labelpadding = 1.0 # default 5.0
        # cbar.ticklabelpad = 1.0 # default 3.0
        # cbar.ticksize = 2.0 # default 6.0
    else
        cbar = 0
    end
    valmin = minimum(pval)
    valmax = maximum(pval)
    valdelta = (valmax - valmin) / 10
    # cbar.ticks = valmin:valdelta:valmax
    println("values between: ", valmin, " and ", valmax)
    return cbar
end

#= ######################################################
others - plotting functions
###################################################### =#

function setup_axis(ax, linewidth)
    # for springer heat and mass transfer
    ax.spinewidth = linewidth
    ax.xtickwidth = linewidth
    ax.ytickwidth = linewidth
    ax.xgridwidth = linewidth
    ax.ygridwidth = linewidth
    ax.xlabelpadding = 0.0 # default 3.0
    ax.ylabelpadding = 0.0
    ax.xticklabelpad = 0.0 # default 2.0
    ax.yticklabelpad = 1.5
    ax.xticksize = 2.0 # default 6.0
    ax.yticksize = 2.0
end


text:
using Documenter, ExternalBallistics
push!(LOAD_PATH,"../src/")
makedocs(sitename="My Documentation")

makedocs(
         sitename = "ExternalBallistics.jl",
         modules  = [ExternalBallistics],
         pages=[
                "Home" => "index.md"
               ])
deploydocs(;
    repo="github.com/YayeIrene/ExternalBallistics.jl.git",
)


text:
import NNlib: softmax, softmax!, ∇softmax, ∇softmax!,
              logsoftmax, logsoftmax!, ∇logsoftmax, ∇logsoftmax!

using CUDA.CUDNN: CUDNN_SOFTMAX_LOG, CUDNN_SOFTMAX_MODE_CHANNEL,
                CUDNN_SOFTMAX_FAST, CUDNN_SOFTMAX_ACCURATE, cudnnSoftmaxForward!,
                cudnnSoftmaxBackward

# Softmax

# @denizyuret: do not do inplace operations with softmax/logsoftmax when (1) cpu version is not, (2) one can use softmax!
function softmax(x::T; dims=1) where {T<:DenseCuArray}
    softmax!(similar(x), x; dims)
end

function ∇softmax(dy::T, x::T, y::T; dims=1) where {T<:DenseCuArray}
    ∇softmax!(similar(x), dy, x, y; dims)
end

function logsoftmax(x::T; dims=1) where {T<:DenseCuArray}
    logsoftmax!(similar(x), x; dims)
end

function ∇logsoftmax(dy::T, x::T, y::T; dims=1) where {T<:DenseCuArray}
    ∇logsoftmax!(similar(x), dy, x, y; dims)
end

# @denizyuret: backup implementations for unsupported/slow size/dims combinations:
function _softmax!(y::T, x::T; dims) where {T<:DenseCuArray}
    y .= exp.(x .- maximum(x; dims))
    y ./= sum(y; dims)
end

function _∇softmax!(dx::T, dy::T, x::T, y::T; dims) where {T<:DenseCuArray}
    dx .= y .* (dy .- sum(dy .* y; dims))
end

function _logsoftmax!(y::T, x::T; dims) where {T<:DenseCuArray}
    y .= x .- maximum(x; dims)
    y .-= log.(sum(exp.(y); dims))
end

function _∇logsoftmax!(dx::T, dy::T, x::T, y::T; dims) where {T<:DenseCuArray}
    dx .= dy .- sum(dy; dims) .* exp.(y)
end

# Trick by @norci to use cudnn for softmax dims args that are contiguous:
# If dims=(dmin:dmax) then CUDNN_SOFTMAX_MODE_CHANNEL does the trick with reshape
#    (1, prod(size(x)[1:dmin-1]), prod(size(x)[dmin:dmax]), :)
# softmaxdims returns nothing when the backup implementation should be used.

function softmaxdims(x, dims)
    dims === Colon() && return (1, 1, length(x), 1)
    mind,maxd = minimum(dims),maximum(dims)
    all(i in dims for i in mind:maxd) || return nothing # cannot handle if not contiguous
    stride = dimsize = 1
    for i in 1:(mind-1); stride *= size(x,i); end # Using size(x,i) assumes trailing dims = 1, robust to maxd > ndims(x)
    for i in mind:maxd; dimsize *= size(x,i); end
    batchsize = length(x)÷(stride*dimsize)
    # Here is a region where cudnn is slower, so we go with the backup:
    batchsize == 1 && 64 <= stride <= 4096 && 64 <= dimsize <= 4096 && return nothing
    return (1, stride, dimsize, batchsize)
end

# Determine softmax algo based on math_mode

softmaxalgo() = (CUDA.math_mode()===CUDA.FAST_MATH ? CUDNN_SOFTMAX_FAST : CUDNN_SOFTMAX_ACCURATE)

# Main implementations:

function softmax!(y::T, x::T = y; dims=1) where {T<:DenseCuArray}
    s = softmaxdims(x, dims)
    s === nothing && return _softmax!(y, x; dims)
    cudnnSoftmaxForward!(reshape(y,s), reshape(x,s); mode = CUDNN_SOFTMAX_MODE_CHANNEL, algo = softmaxalgo())
    return y
end

function ∇softmax!(dx::T, dy::T, x::T, y::T; dims=1) where {R,T<:DenseCuArray{R}}
    s = softmaxdims(x, dims)
    s === nothing && return _∇softmax!(dx, dy, x, y; dims)
    xDesc = cudnnTensorDescriptor(reshape(x,s))
    alpha, beta = scalingParameter(R,1), scalingParameter(R,0)
    cudnnSoftmaxBackward(handle(), softmaxalgo(), CUDNN_SOFTMAX_MODE_CHANNEL,
                         alpha, xDesc, y, xDesc, dy, beta, xDesc, dx)
    return dx
end

function logsoftmax!(y::T, x::T = y; dims=1) where {T<:DenseCuArray}
    s = softmaxdims(x, dims)
    s === nothing && return _logsoftmax!(y, x; dims)
    cudnnSoftmaxForward!(reshape(y,s), reshape(x,s); mode = CUDNN_SOFTMAX_MODE_CHANNEL, algo = CUDNN_SOFTMAX_LOG)
    return y
end

function ∇logsoftmax!(dx::T, dy::T, x::T, y::T; dims=1) where {R,T<:DenseCuArray{R}}
    s = softmaxdims(x, dims)
    s === nothing && return _∇logsoftmax!(dx, dy, x, y; dims)
    xDesc = cudnnTensorDescriptor(reshape(x,s))
    alpha, beta = scalingParameter(R,1), scalingParameter(R,0)
    cudnnSoftmaxBackward(handle(), CUDNN_SOFTMAX_LOG, CUDNN_SOFTMAX_MODE_CHANNEL,
                         alpha, xDesc, y, xDesc, dy, beta, xDesc, dx)
    return dx
end


text:
module Thyra
using CxxWrap, MPI
import ..libjltrilinos
import ..CxxUnion
import ..Teuchos
import ..Tpetra

export LinearOpWithSolve

@wrapmodule(libjltrilinos, :register_thyra)

struct LinearOpWithSolve{ST,LT,GT,NT}
  lows::CxxWrap.SmartPointer{Thyra.LinearOpWithSolveBase{ST}}
  domainmap::CxxWrap.SmartPointer{Tpetra.Map{LT,GT,NT}}
  rangespace::CxxWrap.SmartPointer{Thyra.TpetraVectorSpace{ST,LT,GT,NT}}
  domainspace::CxxWrap.SmartPointer{Thyra.TpetraVectorSpace{ST,LT,GT,NT}}

  function LinearOpWithSolve{ST,LT,GT,NT}(A::CxxUnion{Tpetra.CrsMatrix{ST,LT,GT,NT}}, parameters::CxxUnion{Teuchos.ParameterList}, verbosity::Teuchos.EVerbosityLevel) where {ST,LT,GT,NT}
    lows_factory = Thyra.BelosLinearOpWithSolveFactory(ST)
    Thyra.setParameterList(lows_factory, parameters)
    Thyra.setVerbLevel(lows_factory, verbosity)

    lows = Thyra.createOp(lows_factory)
    domainmap = Tpetra.getDomainMap(A)
    rangespace = Thyra.tpetraVectorSpace(Tpetra.getRangeMap(A))
    domainspace = Thyra.tpetraVectorSpace(domainmap)
    A_thyra = Thyra.tpetraLinearOp(rangespace, domainspace, A)
    Thyra.initializeOp(lows_factory, A_thyra, lows)

    return new{ST,LT,GT,NT}(lows, domainmap, rangespace, domainspace)
  end
end

function LinearOpWithSolve(A::CxxUnion{Tpetra.CrsMatrix{ST,LT,GT,NT}}, parameters::CxxUnion{Teuchos.ParameterList}=Teuchos.ParameterList(), verbosity::Teuchos.EVerbosityLevel=Teuchos.VERB_NONE) where {ST,LT,GT,NT}
  return LinearOpWithSolve{ST,LT,GT,NT}(A,parameters,verbosity)
end

import Base: \

function \(A::LinearOpWithSolve{ST,LT,GT,NT}, b::CxxUnion{Tpetra.Vector{ST,LT,GT,NT}}) where {ST,LT,GT,NT}
  x = Tpetra.Vector(A.domainmap)
  x_th = Thyra.tpetraVector(A.domainspace, x)
  b_th = Thyra.tpetraVector(A.rangespace, b)
  status = Thyra.solve(A.lows, Thyra.NOTRANS, b_th, x_th)
  return x
end

end # module


text:
push!(LOAD_PATH, "./src")
using DelimitedFiles

using WriteVTK

using CommonUtils
using Basis1D
using Basis2DQuad
using UniformQuadMesh
using UnPack

using SetupDG

# Initial condition 2D shocktube
const γ = 1.4
const rhoL  = 8.0
const uL    = 8.25*cos(pi/6)
const vL    = -8.25*sin(pi/6)
const pL    = 116.5
const rhouL = rhoL*uL
const rhovL = rhoL*vL
const EL    = pL/(γ-1)+.5*rhoL*(uL^2+vL^2)
const betaL = rhoL/(2*pL)
const rhoR  = 1.4
const uR    = 0.0
const vR    = 0.0
const pR    = 1.0
const rhouR = rhoR*uR
const rhovR = rhoR*vR
const ER    = pR/(γ-1)+.5*rhoR*(uR^2+vR^2)
const betaR = rhoR/(2*pR)

N = 3
K1D = 250
# N = 2
# K1D = 50
t = 0.2
CFL = 0.75
XLENGTH = 7/2
Np = (N+1)*(N+1)

"Mesh related variables"
VX, VY, EToV = uniform_quad_mesh(Int(round(XLENGTH*K1D)),K1D)
@. VX = (VX+1)/2*XLENGTH
@. VY = (VY+1)/2

rd = init_reference_quad(N,gauss_lobatto_quad(0,0,N))
md = init_mesh((VX,VY),EToV,rd)
@unpack x,y = md;

@unpack VDM = rd
rp,sp = equi_nodes_2D(10)
Vp = vandermonde_2D(N,rp,sp)/VDM

r_vtk = x[1:4]
x_vtk = []
y_vtk = []
for k = 1:Int(round(3.5*K1D))
    push!(x_vtk,r_vtk[1]+(k-1)*1/K1D)
    push!(x_vtk,r_vtk[2]+(k-1)*1/K1D)
    push!(x_vtk,r_vtk[3]+(k-1)*1/K1D)
    push!(x_vtk,r_vtk[4]+(k-1)*1/K1D)
end
for k = 1:K1D
    push!(y_vtk,r_vtk[1]+(k-1)*1/K1D)
    push!(y_vtk,r_vtk[2]+(k-1)*1/K1D)
    push!(y_vtk,r_vtk[3]+(k-1)*1/K1D)
    push!(y_vtk,r_vtk[4]+(k-1)*1/K1D)
end

x_vtk = x_vtk .* ones((N+1)*K1D,1)'
y_vtk = y_vtk' .* ones((N+1)*Int(round(3.5*K1D)),1)
rho_vtk,rhou_vtk,rhov_vtk,E_vtk = (zeros(size(x_vtk)) for i = 1:4)

# tarr = []
# filenames = readdir("/data/yl184")
# for fn in filenames
#     for str in split(fn,",")
#         if length(str) < 2
#             continue
#         end
#         if "t=" == str[1:2]
#             append!(tarr,parse(Float64,str[3:end]))
#         end
#     end
# end
# unique!(tarr)

# pvd = paraview_collection("/data/yl184/N=$N,K1D=$K1D,CFL=$CFL,x=$XLENGTH,element-wise", append=true)

# for t in tarr
    # if t > 0.0
        # println("Current time $t")
        # flush(stdout)
        vtk_grid("N=$N,K1D=$K1D,t=$t,CFL=$CFL,x=$XLENGTH",x_vtk,y_vtk) do vtk
            rho = readdlm("N=$N,K1D=$K1D,t=$t,CFL=$CFL,x=$XLENGTH,rho,dmr.txt")
            rhou = readdlm("N=$N,K1D=$K1D,t=$t,CFL=$CFL,x=$XLENGTH,rhou,dmr.txt")
            rhov = readdlm("N=$N,K1D=$K1D,t=$t,CFL=$CFL,x=$XLENGTH,rhov,dmr.txt")
            E = readdlm("N=$N,K1D=$K1D,t=$t,CFL=$CFL,x=$XLENGTH,E,dmr.txt")

            for k = 1:Int(round(3.5*K1D))*K1D
                kx = mod1(k,Int(round(3.5*K1D)))
                ky = div(k-1,Int(round(3.5*K1D)))+1
                rho_vtk[(kx-1)*(N+1)+1:(kx-1)*(N+1)+N+1, (ky-1)*(N+1)+1:(ky-1)*(N+1)+N+1] = rho[:,k]
                rhou_vtk[(kx-1)*(N+1)+1:(kx-1)*(N+1)+N+1, (ky-1)*(N+1)+1:(ky-1)*(N+1)+N+1] = rhou[:,k]
                rhov_vtk[(kx-1)*(N+1)+1:(kx-1)*(N+1)+N+1, (ky-1)*(N+1)+1:(ky-1)*(N+1)+N+1] = rhov[:,k]
                E_vtk[(kx-1)*(N+1)+1:(kx-1)*(N+1)+N+1, (ky-1)*(N+1)+1:(ky-1)*(N+1)+N+1] = E[:,k]
            end

            vtk["rho"]  = rho_vtk
            vtk["rhou"] = rhou_vtk
            vtk["rhov"] = rhov_vtk
            vtk["E"]    = E_vtk
            # pvd[t] = vtk
        end
    # end
# end

# vtk_save(pvd)

max_stars_repo_name: yiminllin/ESDG-PosLimit

max_issues_repo_name: yiminllin/ESDG-PosLimit

max_forks_repo_name: yiminllin/ESDG-PosLimit


text:
function nlp_002_010(
    optimizer,
    objective_tol,
    primal_tol,
    dual_tol,
    termination_target = TERMINATION_TARGET_LOCAL,
    primal_target = PRIMAL_TARGET_LOCAL,
)
    # Test Goals:
    # - all have start values
    # - non-linear constraints without objective
    # - functions log

    model = Model(optimizer)

    @variable(model, x, start = 1)
    @variable(model, y, start = -1.12)

    @NLconstraint(model, y == log(x) - 0.1)
    @NLconstraint(model, x == cos(y)^2 + 1.5)

    optimize!(model)

    check_status(model, FEASIBLE_PROBLEM, termination_target, primal_target)
    check_objective(model, 0.0, tol = objective_tol)
    return check_solution(
        [x, y],
        [2.1285148443189033, 0.6554244804634232],
        tol = primal_tol,
    )
end


text:
function runexamples()
    origcwd = pwd()
    packagedir = Pkg.dir("FinEtools")
    cd(packagedir)
    exds = readdir("./examples")

    function doex(ex1)
        include(ex1)
    end

    for exd1 in exds
        cd("./examples/" * exd1);
        println("\nExamples in folder $(pwd())\n")
        exss = readdir(".")
        for ex1 in exss
            n,ext = splitext(ex1)
            if ext==".jl"
                println("\nExample $ex1 in $(pwd()) ($n $ext)\n")
                doex(ex1)
            end
        end
        cd(packagedir)
    end

    cd(origcwd)
end


text:
module BenchArray
using BenchmarkTools
using Statistics
using Gadfly
using MLStyle
using DataFrames
import Match
import Rematch
using ..ArbitrarySampler
using ..Utils

mod′(n) = x -> mod(x, n)
len_in(rng) = x -> length(x) in rng
is_in(rng) = x -> x in rng

integer20 = @spec ::Integer isa mod′(20)

struct UserTy{T}
    a::T
    b::Symbol
end
@as_record UserTy

specs = [
    :s1 => (@spec [1, _, _, $integer20{2, 5}..., 10, 7, ::String, [1, 2, 3]]),
    :s2 => (@spec [10, 20, [27, ::UInt8], ::String, ::Symbol, _{2, 10}...]),
    :s3 => (@spec [
        (1, 2, ::String),
        (::Int, ::Int isa (x -> x % 4 + 8)),
        12,
        9,
        9,
        _{2, 10}...,
        3,
    ]),
    :s4 => (@spec [_, _, _, _, 8, _, ::Integer, UserTy(::String, :bb)]),
    :s5 => (@spec [$integer20, _, UserTy(1, :a), _, UserTy(2, :b)]),
    :s6 => (@spec [_, 125, _]),
    :s7 => (@spec [2, (), (), _{2, 3}..., 1, 2, 3, 10]),
    :_ => @spec(_),
]

implementations = [
    :MLStyle => function (x)
        @match x begin
            [1, _, _, xs..., 10, 7, ::String, &[1, 2, 3]] && if sum(xs) < 37
            end => 1
            [10, 20, [27, ::UInt8], ::String, ::Symbol, _...] => 2
            [(1, 2, ::String), (::Int, ::Int && 7:11), 12, 9, 9, _..., 3] => 3
            [_, _, _, _, 8, _, ::Integer, UserTy(::String, :bb)] => 4
            [_, _, UserTy(1, :a), UserTy(2, :b)] => 5
            _ => 6
        end
    end,
    :Rematch => function (x)
        Rematch.@match x begin
            [1, _, _, x..., 10, 7, _::String, [1, 2, 3]] where {sum(x) < 37} => 1
            [10, 20, [27, _::UInt8], _::String, _::Symbol, _...] => 2
            [(1, 2, _::String), (_::Int, v::Int), 12, 9, 9, _..., 3] where {v in 7:11} => 3
            [_, _, _, _, 8, _, _::Integer, UserTy(_::String, :bb)] => 4
            [_, _, UserTy(1, :a), UserTy(2, :b)] => 5
            _ => 6
        end
    end,
    Symbol("Match.jl") => function (x)
        Match.@match x begin
            [1, _, _, x..., 10, 7, _::String, [1, 2, 3]], if sum(x) < 37
            end => 1
            [10, 20, [27, _::UInt8], _::String, _::Symbol, _...] => 2
            [(1, 2, _::String), (_::Int, v::Int), 12, 9, 9, _..., 3], if v in 7:11
            end => 3
            [_, _, _, _, 8, _, _::Integer, UserTy(_::String, :bb)] => 4
            [_, _, UserTy(1, :a), UserTy(2, :b)] => 5
            _ => 6
        end
    end,
]

records = NamedTuple{(:time_mean, :implementation, :case)}[]
for (spec_id, spec) in specs
    # group_key = string(spec_id)
    # suite[group_key] = BenchmarkGroup()
    for (impl_id, impl_fn) in implementations
        bench′ =
            @benchmark $impl_fn(sample) setup = (sample = $generate($spec)) samples = 2000
        time′ = mean(bench′.times)
        @info :bench (spec_id, impl_id, time′)
        push!(records, (time_mean = time′, implementation = impl_id, case = spec_id))
    end
end

df = DataFrame(records)

@info df

theme = Theme(
    guide_title_position = :left,
    colorkey_swatch_shape = :circle,
    minor_label_font = "Consolas",
    major_label_font = "Consolas",
    point_size = 5px,
)

report_meantime, df_time = report(df, Guide.title("Arrays"); benchfield = :time_mean)

open("stats/bench-array.txt", "w") do f
    write(f, string(df))
end

draw(SVG("stats/bench-array.svg", 14inch, 6inch), report_meantime)

end