text:
# This file is auto-generated by AWSMetadata.jl
using AWS
using AWS.AWSServices: route53_recovery_readiness
using AWS.Compat
using AWS.UUIDs

"""
    create_cell(cell_name)
    create_cell(cell_name, params::Dict{String,<:Any})

Creates a new Cell.

# Arguments
- `cell_name`: The name of the Cell to create

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"cells"`: A list of Cell arns contained within this Cell (for use in nested Cells, e.g.
  regions within which AZs)
- `"tags"`:
"""
function create_cell(cellName; aws_config::AbstractAWSConfig=global_aws_config())
    return route53_recovery_readiness(
        "POST",
        "/cells",
        Dict{String,Any}("cellName" => cellName);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function create_cell(
    cellName,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return route53_recovery_readiness(
        "POST",
        "/cells",
        Dict{String,Any}(
            mergewith(_merge, Dict{String,Any}("cellName" => cellName), params)
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    create_cross_account_authorization(cross_account_authorization)
    create_cross_account_authorization(cross_account_authorization, params::Dict{String,<:Any})

Create a new cross account readiness authorization.

# Arguments
- `cross_account_authorization`: The cross account authorization

"""
function create_cross_account_authorization(
    crossAccountAuthorization; aws_config::AbstractAWSConfig=global_aws_config()
)
    return route53_recovery_readiness(
        "POST",
        "/crossaccountauthorizations",
        Dict{String,Any}("crossAccountAuthorization" => crossAccountAuthorization);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function create_cross_account_authorization(
    crossAccountAuthorization,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return route53_recovery_readiness(
        "POST",
        "/crossaccountauthorizations",
        Dict{String,Any}(
            mergewith(
                _merge,
                Dict{String,Any}("crossAccountAuthorization" => crossAccountAuthorization),
                params,
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    create_readiness_check(readiness_check_name, resource_set_name)
    create_readiness_check(readiness_check_name, resource_set_name, params::Dict{String,<:Any})

Creates a new Readiness Check.

# Arguments
- `readiness_check_name`: The name of the ReadinessCheck to create
- `resource_set_name`: The name of the ResourceSet to check

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"tags"`:
"""
function create_readiness_check(
    readinessCheckName, resourceSetName; aws_config::AbstractAWSConfig=global_aws_config()
)
    return route53_recovery_readiness(
        "POST",
        "/readinesschecks",
        Dict{String,Any}(
            "readinessCheckName" => readinessCheckName, "resourceSetName" => resourceSetName
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function create_readiness_check(
    readinessCheckName,
    resourceSetName,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return route53_recovery_readiness(
        "POST",
        "/readinesschecks",
        Dict{String,Any}(
            mergewith(
                _merge,
                Dict{String,Any}(
                    "readinessCheckName" => readinessCheckName,
                    "resourceSetName" => resourceSetName,
                ),
                params,
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    create_recovery_group(recovery_group_name)
    create_recovery_group(recovery_group_name, params::Dict{String,<:Any})

Creates a new Recovery Group.

# Arguments
- `recovery_group_name`: The name of the RecoveryGroup to create

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"cells"`: A list of Cell arns
- `"tags"`:
"""
function create_recovery_group(
    recoveryGroupName; aws_config::AbstractAWSConfig=global_aws_config()
)
    return route53_recovery_readiness(
        "POST",
        "/recoverygroups",
        Dict{String,Any}("recoveryGroupName" => recoveryGroupName);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function create_recovery_group(
    recoveryGroupName,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return route53_recovery_readiness(
        "POST",
        "/recoverygroups",
        Dict{String,Any}(
            mergewith(
                _merge, Dict{String,Any}("recoveryGroupName" => recoveryGroupName), params
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    create_resource_set(resource_set_name, resource_set_type, resources)
    create_resource_set(resource_set_name, resource_set_type, resources, params::Dict{String,<:Any})

Creates a new Resource Set.

# Arguments
- `resource_set_name`: The name of the ResourceSet to create
- `resource_set_type`: AWS Resource type of the resources in the ResourceSet
- `resources`: A list of Resource objects

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"tags"`:
"""
function create_resource_set(
    resourceSetName,
    resourceSetType,
    resources;
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return route53_recovery_readiness(
        "POST",
        "/resourcesets",
        Dict{String,Any}(
            "resourceSetName" => resourceSetName,
            "resourceSetType" => resourceSetType,
            "resources" => resources,
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function create_resource_set(
    resourceSetName,
    resourceSetType,
    resources,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return route53_recovery_readiness(
        "POST",
        "/resourcesets",
        Dict{String,Any}(
            mergewith(
                _merge,
                Dict{String,Any}(
                    "resourceSetName" => resourceSetName,
                    "resourceSetType" => resourceSetType,
                    "resources" => resources,
                ),
                params,
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    delete_cell(cell_name)
    delete_cell(cell_name, params::Dict{String,<:Any})

Deletes an existing Cell.

# Arguments
- `cell_name`: The Cell to delete

"""
function delete_cell(cellName; aws_config::AbstractAWSConfig=global_aws_config())
    return route53_recovery_readiness(
        "DELETE",
        "/cells/$(cellName)";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function delete_cell(
    cellName,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return route53_recovery_readiness(
        "DELETE",
        "/cells/$(cellName)",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    delete_cross_account_authorization(cross_account_authorization)
    delete_cross_account_authorization(cross_account_authorization, params::Dict{String,<:Any})

Delete cross account readiness authorization

# Arguments
- `cross_account_authorization`: The cross account authorization

"""
function delete_cross_account_authorization(
    crossAccountAuthorization; aws_config::AbstractAWSConfig=global_aws_config()
)
    return route53_recovery_readiness(
        "DELETE",
        "/crossaccountauthorizations/$(crossAccountAuthorization)";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function delete_cross_account_authorization(
    crossAccountAuthorization,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return route53_recovery_readiness(
        "DELETE",
        "/crossaccountauthorizations/$(crossAccountAuthorization)",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    delete_readiness_check(readiness_check_name)
    delete_readiness_check(readiness_check_name, params::Dict{String,<:Any})

Deletes an existing Readiness Check.

# Arguments
- `readiness_check_name`: The ReadinessCheck to delete

"""
function delete_readiness_check(
    readinessCheckName; aws_config::AbstractAWSConfig=global_aws_config()
)
    return route53_recovery_readiness(
        "DELETE",
        "/readinesschecks/$(readinessCheckName)";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function delete_readiness_check(
    readinessCheckName,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return route53_recovery_readiness(
        "DELETE",
        "/readinesschecks/$(readinessCheckName)",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    delete_recovery_group(recovery_group_name)
    delete_recovery_group(recovery_group_name, params::Dict{String,<:Any})

Deletes an existing Recovery Group.

# Arguments
- `recovery_group_name`: The RecoveryGroup to delete

"""
function delete_recovery_group(
    recoveryGroupName; aws_config::AbstractAWSConfig=global_aws_config()
)
    return route53_recovery_readiness(
        "DELETE",
        "/recoverygroups/$(recoveryGroupName)";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function delete_recovery_group(
    recoveryGroupName,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return route53_recovery_readiness(
        "DELETE",
        "/recoverygroups/$(recoveryGroupName)",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    delete_resource_set(resource_set_name)
    delete_resource_set(resource_set_name, params::Dict{String,<:Any})

Deletes an existing Resource Set.

# Arguments
- `resource_set_name`: The ResourceSet to delete

"""
function delete_resource_set(
    resourceSetName; aws_config::AbstractAWSConfig=global_aws_config()
)
    return route53_recovery_readiness(
        "DELETE",
        "/resourcesets/$(resourceSetName)";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function delete_resource_set(
    resourceSetName,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return route53_recovery_readiness(
        "DELETE",
        "/resourcesets/$(resourceSetName)",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    get_architecture_recommendations(recovery_group_name)
    get_architecture_recommendations(recovery_group_name, params::Dict{String,<:Any})

Returns a collection of recommendations to improve resilliance and readiness check quality
for a Recovery Group.

# Arguments
- `recovery_group_name`: Name of RecoveryGroup (top level resource) to be analyzed.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"maxResults"`: Upper bound on number of records to return.
- `"nextToken"`: A token that can be used to resume pagination from the end of the
  collection.
"""
function get_architecture_recommendations(
    recoveryGroupName; aws_config::AbstractAWSConfig=global_aws_config()
)
    return route53_recovery_readiness(
        "GET",
        "/recoverygroups/$(recoveryGroupName)/architectureRecommendations";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function get_architecture_recommendations(
    recoveryGroupName,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return route53_recovery_readiness(
        "GET",
        "/recoverygroups/$(recoveryGroupName)/architectureRecommendations",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    get_cell(cell_name)
    get_cell(cell_name, params::Dict{String,<:Any})

Returns information about a Cell.

# Arguments
- `cell_name`: The Cell to get

"""
function get_cell(cellName; aws_config::AbstractAWSConfig=global_aws_config())
    return route53_recovery_readiness(
        "GET", "/cells/$(cellName)"; aws_config=aws_config, feature_set=SERVICE_FEATURE_SET
    )
end
function get_cell(
    cellName,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return route53_recovery_readiness(
        "GET",
        "/cells/$(cellName)",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    get_cell_readiness_summary(cell_name)
    get_cell_readiness_summary(cell_name, params::Dict{String,<:Any})

Returns information about readiness of a Cell.

# Arguments
- `cell_name`: The name of the Cell

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"maxResults"`: Upper bound on number of records to return.
- `"nextToken"`: A token used to resume pagination from the end of a previous request.
"""
function get_cell_readiness_summary(
    cellName; aws_config::AbstractAWSConfig=global_aws_config()
)
    return route53_recovery_readiness(
        "GET",
        "/cellreadiness/$(cellName)";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function get_cell_readiness_summary(
    cellName,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return route53_recovery_readiness(
        "GET",
        "/cellreadiness/$(cellName)",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    get_readiness_check(readiness_check_name)
    get_readiness_check(readiness_check_name, params::Dict{String,<:Any})

Returns information about a ReadinessCheck.

# Arguments
- `readiness_check_name`: The ReadinessCheck to get

"""
function get_readiness_check(
    readinessCheckName; aws_config::AbstractAWSConfig=global_aws_config()
)
    return route53_recovery_readiness(
        "GET",
        "/readinesschecks/$(readinessCheckName)";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function get_readiness_check(
    readinessCheckName,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return route53_recovery_readiness(
        "GET",
        "/readinesschecks/$(readinessCheckName)",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    get_readiness_check_resource_status(readiness_check_name, resource_identifier)
    get_readiness_check_resource_status(readiness_check_name, resource_identifier, params::Dict{String,<:Any})

Returns detailed information about the status of an individual resource within a Readiness
Check's Resource Set.

# Arguments
- `readiness_check_name`: The ReadinessCheck to get
- `resource_identifier`: The resource ARN or component Id to get

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"maxResults"`: Upper bound on number of records to return.
- `"nextToken"`: A token used to resume pagination from the end of a previous request.
"""
function get_readiness_check_resource_status(
    readinessCheckName,
    resourceIdentifier;
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return route53_recovery_readiness(
        "GET",
        "/readinesschecks/$(readinessCheckName)/resource/$(resourceIdentifier)/status";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function get_readiness_check_resource_status(
    readinessCheckName,
    resourceIdentifier,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return route53_recovery_readiness(
        "GET",
        "/readinesschecks/$(readinessCheckName)/resource/$(resourceIdentifier)/status",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    get_readiness_check_status(readiness_check_name)
    get_readiness_check_status(readiness_check_name, params::Dict{String,<:Any})

Returns information about the status of a Readiness Check.

# Arguments
- `readiness_check_name`: The ReadinessCheck to get

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"maxResults"`: Upper bound on number of records to return.
- `"nextToken"`: A token used to resume pagination from the end of a previous request.
"""
function get_readiness_check_status(
    readinessCheckName; aws_config::AbstractAWSConfig=global_aws_config()
)
    return route53_recovery_readiness(
        "GET",
        "/readinesschecks/$(readinessCheckName)/status";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function get_readiness_check_status(
    readinessCheckName,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return route53_recovery_readiness(
        "GET",
        "/readinesschecks/$(readinessCheckName)/status",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    get_recovery_group(recovery_group_name)
    get_recovery_group(recovery_group_name, params::Dict{String,<:Any})

Returns information about a Recovery Group.

# Arguments
- `recovery_group_name`: The RecoveryGroup to get

"""
function get_recovery_group(
    recoveryGroupName; aws_config::AbstractAWSConfig=global_aws_config()
)
    return route53_recovery_readiness(
        "GET",
        "/recoverygroups/$(recoveryGroupName)";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function get_recovery_group(
    recoveryGroupName,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return route53_recovery_readiness(
        "GET",
        "/recoverygroups/$(recoveryGroupName)",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    get_recovery_group_readiness_summary(recovery_group_name)
    get_recovery_group_readiness_summary(recovery_group_name, params::Dict{String,<:Any})

Returns information about a Recovery Group.

# Arguments
- `recovery_group_name`: The name of the RecoveryGroup

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"maxResults"`: Upper bound on number of records to return.
- `"nextToken"`: A token used to resume pagination from the end of a previous request.
"""
function get_recovery_group_readiness_summary(
    recoveryGroupName; aws_config::AbstractAWSConfig=global_aws_config()
)
    return route53_recovery_readiness(
        "GET",
        "/recoverygroupreadiness/$(recoveryGroupName)";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function get_recovery_group_readiness_summary(
    recoveryGroupName,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return route53_recovery_readiness(
        "GET",
        "/recoverygroupreadiness/$(recoveryGroupName)",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    get_resource_set(resource_set_name)
    get_resource_set(resource_set_name, params::Dict{String,<:Any})

Returns information about a Resource Set.

# Arguments
- `resource_set_name`: The ResourceSet to get

"""
function get_resource_set(
    resourceSetName; aws_config::AbstractAWSConfig=global_aws_config()
)
    return route53_recovery_readiness(
        "GET",
        "/resourcesets/$(resourceSetName)";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function get_resource_set(
    resourceSetName,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return route53_recovery_readiness(
        "GET",
        "/resourcesets/$(resourceSetName)",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    list_cells()
    list_cells(params::Dict{String,<:Any})

Returns a collection of Cells.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"maxResults"`: Upper bound on number of records to return.
- `"nextToken"`: A token used to resume pagination from the end of a previous request.
"""
function list_cells(; aws_config::AbstractAWSConfig=global_aws_config())
    return route53_recovery_readiness(
        "GET", "/cells"; aws_config=aws_config, feature_set=SERVICE_FEATURE_SET
    )
end
function list_cells(
    params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()
)
    return route53_recovery_readiness(
        "GET", "/cells", params; aws_config=aws_config, feature_set=SERVICE_FEATURE_SET
    )
end

"""
    list_cross_account_authorizations()
    list_cross_account_authorizations(params::Dict{String,<:Any})

Returns a collection of cross account readiness authorizations.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"maxResults"`: Upper bound on number of records to return.
- `"nextToken"`: A token used to resume pagination from the end of a previous request.
"""
function list_cross_account_authorizations(;
    aws_config::AbstractAWSConfig=global_aws_config()
)
    return route53_recovery_readiness(
        "GET",
        "/crossaccountauthorizations";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function list_cross_account_authorizations(
    params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()
)
    return route53_recovery_readiness(
        "GET",
        "/crossaccountauthorizations",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    list_readiness_checks()
    list_readiness_checks(params::Dict{String,<:Any})

Returns a collection of Readiness Checks.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"maxResults"`: Upper bound on number of records to return.
- `"nextToken"`: A token used to resume pagination from the end of a previous request.
"""
function list_readiness_checks(; aws_config::AbstractAWSConfig=global_aws_config())
    return route53_recovery_readiness(
        "GET", "/readinesschecks"; aws_config=aws_config, feature_set=SERVICE_FEATURE_SET
    )
end
function list_readiness_checks(
    params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()
)
    return route53_recovery_readiness(
        "GET",
        "/readinesschecks",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    list_recovery_groups()
    list_recovery_groups(params::Dict{String,<:Any})

Returns a collection of Recovery Groups.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"maxResults"`: Upper bound on number of records to return.
- `"nextToken"`: A token used to resume pagination from the end of a previous request.
"""
function list_recovery_groups(; aws_config::AbstractAWSConfig=global_aws_config())
    return route53_recovery_readiness(
        "GET", "/recoverygroups"; aws_config=aws_config, feature_set=SERVICE_FEATURE_SET
    )
end
function list_recovery_groups(
    params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()
)
    return route53_recovery_readiness(
        "GET",
        "/recoverygroups",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    list_resource_sets()
    list_resource_sets(params::Dict{String,<:Any})

Returns a collection of Resource Sets.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"maxResults"`: Upper bound on number of records to return.
- `"nextToken"`: A token used to resume pagination from the end of a previous request.
"""
function list_resource_sets(; aws_config::AbstractAWSConfig=global_aws_config())
    return route53_recovery_readiness(
        "GET", "/resourcesets"; aws_config=aws_config, feature_set=SERVICE_FEATURE_SET
    )
end
function list_resource_sets(
    params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()
)
    return route53_recovery_readiness(
        "GET",
        "/resourcesets",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    list_rules()
    list_rules(params::Dict{String,<:Any})

Returns a collection of rules that are applied as part of Readiness Checks.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"maxResults"`: Upper bound on number of records to return.
- `"nextToken"`: A token used to resume pagination from the end of a previous request.
- `"resourceType"`: Filter parameter which specifies the rules to return given a resource
  type.
"""
function list_rules(; aws_config::AbstractAWSConfig=global_aws_config())
    return route53_recovery_readiness(
        "GET", "/rules"; aws_config=aws_config, feature_set=SERVICE_FEATURE_SET
    )
end
function list_rules(
    params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()
)
    return route53_recovery_readiness(
        "GET", "/rules", params; aws_config=aws_config, feature_set=SERVICE_FEATURE_SET
    )
end

"""
    list_tags_for_resources(resource-arn)
    list_tags_for_resources(resource-arn, params::Dict{String,<:Any})

Returns a list of the tags assigned to the specified resource.

# Arguments
- `resource-arn`: The Amazon Resource Name (ARN) for the resource. You can get this from
  the response to any request to the resource.

"""
function list_tags_for_resources(
    resource_arn; aws_config::AbstractAWSConfig=global_aws_config()
)
    return route53_recovery_readiness(
        "GET",
        "/tags/$(resource-arn)";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function list_tags_for_resources(
    resource_arn,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return route53_recovery_readiness(
        "GET",
        "/tags/$(resource-arn)",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    tag_resource(resource-arn, tags)
    tag_resource(resource-arn, tags, params::Dict{String,<:Any})

Adds tags to the specified resource. You can specify one or more tags to add.

# Arguments
- `resource-arn`: The Amazon Resource Name (ARN) for the resource. You can get this from
  the response to any request to the resource.
- `tags`:

"""
function tag_resource(resource_arn, tags; aws_config::AbstractAWSConfig=global_aws_config())
    return route53_recovery_readiness(
        "POST",
        "/tags/$(resource-arn)",
        Dict{String,Any}("tags" => tags);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function tag_resource(
    resource_arn,
    tags,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return route53_recovery_readiness(
        "POST",
        "/tags/$(resource-arn)",
        Dict{String,Any}(mergewith(_merge, Dict{String,Any}("tags" => tags), params));
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    untag_resource(resource-arn, tag_keys)
    untag_resource(resource-arn, tag_keys, params::Dict{String,<:Any})

Removes tags from the specified resource. You can specify one or more tags to remove.

# Arguments
- `resource-arn`: The Amazon Resource Name (ARN) for the resource. You can get this from
  the response to any request to the resource.
- `tag_keys`: A comma-separated list of the tag keys to remove from the resource.

"""
function untag_resource(
    resource_arn, tagKeys; aws_config::AbstractAWSConfig=global_aws_config()
)
    return route53_recovery_readiness(
        "DELETE",
        "/tags/$(resource-arn)",
        Dict{String,Any}("tagKeys" => tagKeys);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function untag_resource(
    resource_arn,
    tagKeys,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return route53_recovery_readiness(
        "DELETE",
        "/tags/$(resource-arn)",
        Dict{String,Any}(mergewith(_merge, Dict{String,Any}("tagKeys" => tagKeys), params));
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    update_cell(cell_name, cells)
    update_cell(cell_name, cells, params::Dict{String,<:Any})

Updates an existing Cell.

# Arguments
- `cell_name`: The Cell to update
- `cells`: A list of Cell arns, completely replaces previous list

"""
function update_cell(cellName, cells; aws_config::AbstractAWSConfig=global_aws_config())
    return route53_recovery_readiness(
        "PUT",
        "/cells/$(cellName)",
        Dict{String,Any}("cells" => cells);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function update_cell(
    cellName,
    cells,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return route53_recovery_readiness(
        "PUT",
        "/cells/$(cellName)",
        Dict{String,Any}(mergewith(_merge, Dict{String,Any}("cells" => cells), params));
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    update_readiness_check(readiness_check_name, resource_set_name)
    update_readiness_check(readiness_check_name, resource_set_name, params::Dict{String,<:Any})

Updates an exisiting Readiness Check.

# Arguments
- `readiness_check_name`: The ReadinessCheck to update
- `resource_set_name`: The name of the ResourceSet to check

"""
function update_readiness_check(
    readinessCheckName, resourceSetName; aws_config::AbstractAWSConfig=global_aws_config()
)
    return route53_recovery_readiness(
        "PUT",
        "/readinesschecks/$(readinessCheckName)",
        Dict{String,Any}("resourceSetName" => resourceSetName);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function update_readiness_check(
    readinessCheckName,
    resourceSetName,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return route53_recovery_readiness(
        "PUT",
        "/readinesschecks/$(readinessCheckName)",
        Dict{String,Any}(
            mergewith(
                _merge, Dict{String,Any}("resourceSetName" => resourceSetName), params
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    update_recovery_group(cells, recovery_group_name)
    update_recovery_group(cells, recovery_group_name, params::Dict{String,<:Any})

Updates an existing Recovery Group.

# Arguments
- `cells`: A list of Cell arns, completely replaces previous list
- `recovery_group_name`: The RecoveryGroup to update

"""
function update_recovery_group(
    cells, recoveryGroupName; aws_config::AbstractAWSConfig=global_aws_config()
)
    return route53_recovery_readiness(
        "PUT",
        "/recoverygroups/$(recoveryGroupName)",
        Dict{String,Any}("cells" => cells);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function update_recovery_group(
    cells,
    recoveryGroupName,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return route53_recovery_readiness(
        "PUT",
        "/recoverygroups/$(recoveryGroupName)",
        Dict{String,Any}(mergewith(_merge, Dict{String,Any}("cells" => cells), params));
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    update_resource_set(resource_set_name, resource_set_type, resources)
    update_resource_set(resource_set_name, resource_set_type, resources, params::Dict{String,<:Any})

Updates an existing Resource Set.

# Arguments
- `resource_set_name`: The ResourceSet to update
- `resource_set_type`: AWS Resource Type of the resources in the ResourceSet
- `resources`: A list of Resource objects

"""
function update_resource_set(
    resourceSetName,
    resourceSetType,
    resources;
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return route53_recovery_readiness(
        "PUT",
        "/resourcesets/$(resourceSetName)",
        Dict{String,Any}("resourceSetType" => resourceSetType, "resources" => resources);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function update_resource_set(
    resourceSetName,
    resourceSetType,
    resources,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return route53_recovery_readiness(
        "PUT",
        "/resourcesets/$(resourceSetName)",
        Dict{String,Any}(
            mergewith(
                _merge,
                Dict{String,Any}(
                    "resourceSetType" => resourceSetType, "resources" => resources
                ),
                params,
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end


text:
using CayleyDickson
using Base.Test: @test, @test_throws

@test begin
    a = CayleyDickson.randomBigInt()
    b = CayleyDickson.randomBigInt()
    l = Exo1SplitQuaternion(Exo1Real(a, b))
    r = Exo1SplitQuaternion(a, 0, 0, 0, b, 0, 0, 0)
    l == r
end

@test begin
    a = CayleyDickson.randomBigFloat()
    isreal(Exo1SplitQuaternion(a))
end

@test begin
    a = 1
    !isreal(Exo1SplitQuaternion(a, a, a, a))
end

@test begin
    z = random(Exo1SplitQuaternion{Int})
    z == +(z)
end

@test begin
    a = CayleyDickson.randomBigFloat()
    real(Exo1SplitQuaternion(a)) == a
end

@test begin
    io = IOBuffer()
    show(io, Exo1SplitQuaternion(1.0, 2, 3, 4, 5, 6, 7, 8))
    l = String(take!(io))
    r = "[1: 1.0, i: 2.0, s: 3.0, is: 4.0, a: 5.0, ia: 6.0, sa: 7.0, (is)a: 8.0]"
    l == r
end

@test begin
    io = IOBuffer()
    show(io, Exo1SplitQuaternion(1.0, 2, 3, 4, 5, 6, 7))
    l = String(take!(io))
    r = "[1: 1.0, i: 2.0, s: 3.0, is: 4.0, a: 5.0, ia: 6.0, sa: 7.0, (is)a: 0.0]"
    l == r
end

@test begin
    io = IOBuffer()
    show(io, Exo1SplitQuaternion(1.0, 2, 3, 4, 5, 6))
    l = String(take!(io))
    r = "[1: 1.0, i: 2.0, s: 3.0, is: 4.0, a: 5.0, ia: 6.0, sa: 0.0, (is)a: 0.0]"
    l == r
end

@test begin
    io = IOBuffer()
    show(io, Exo1SplitQuaternion(1.0, 2, 3, 4, 5))
    l = String(take!(io))
    r = "[1: 1.0, i: 2.0, s: 3.0, is: 4.0, a: 5.0, ia: 0.0, sa: 0.0, (is)a: 0.0]"
    l == r
end

@test begin
    io = IOBuffer()
    show(io, Exo1SplitQuaternion(1.0, 2, 3, 4))
    l = String(take!(io))
    r = "[1: 1.0, i: 2.0, s: 3.0, is: 4.0, a: 0.0, ia: 0.0, sa: 0.0, (is)a: 0.0]"
    l == r
end

@test begin
    a = CayleyDickson.randomBigInt()
    b = CayleyDickson.randomBigFloat()
    c = CayleyDickson.randomBigInt()
    d = CayleyDickson.randomBigFloat()
    l = Exo1SplitQuaternion(SplitQuaternion(a, b, c, d))
    r = Exo1SplitQuaternion(a, b, c, d)
    l == r
end

@test begin
    a = CayleyDickson.randomBigInt()
    b = CayleyDickson.randomBigFloat()
    l = Exo1SplitQuaternion(Binion(a, b))
    r = Exo1SplitQuaternion(a, b)
    l == r
end

@test begin
    a = CayleyDickson.randomBigInt()
    b = CayleyDickson.randomBigFloat()
    c = CayleyDickson.randomBigInt()
    l = Exo1SplitQuaternion(a, b, c)
    r = Exo1SplitQuaternion(a, b, c, 0)
    l == r
end

@test begin
    x = random(Exo1SplitQuaternion{BigFloat})
    y = random(Exo1SplitQuaternion{BigFloat})
    x != y
end

@test begin
    a = CayleyDickson.randomBigInt()
    z = random(Exo1SplitQuaternion{BigInt})
    l = a + z
    r = z + a
    l == r
end

@test begin
    a = random(SplitQuaternion{BigInt})
    z = random(Exo1SplitQuaternion{BigInt})
    l = a + z
    r = z + a
    l == r
end

@test begin
    a = CayleyDickson.randomBigInt()
    z = random(Exo1SplitQuaternion{BigInt})
    l = a - z
    r = -(z - a)
    l == r
end

@test begin
    a = random(SplitQuaternion{BigInt})
    z = random(Exo1SplitQuaternion{BigInt})
    l = a - z
    r = -(z - a)
    l == r
end

@test begin
    x = random(Exo1SplitQuaternion{BigInt})
    y = random(Exo1SplitQuaternion{BigInt})
    l = x + y
    r = y + x
    l == r
end

@test begin
    x = random(Exo1SplitQuaternion{BigInt})
    y = random(Exo1SplitQuaternion{BigInt})
    l = x * y
    r = y * x
    l != r
end

@test begin
    x = random(Exo1SplitQuaternion{BigInt})
    y = random(Exo1SplitQuaternion{BigInt})
    l = x - y
    r = -(y - x)
    l == r
end

@test begin
    x = random(Exo1SplitQuaternion{BigInt})
    y = random(Exo1SplitQuaternion{BigInt})
    z = random(Exo1SplitQuaternion{BigInt})
    l = (x + y) + z
    r = x + (y + z)
    l == r
end

@test begin
    x = random(Exo1SplitQuaternion{BigInt})
    y = random(Exo1SplitQuaternion{BigInt})
    z = random(Exo1SplitQuaternion{BigInt})
    l = (x * y) * z
    r = x * (y * z)
    l != r
end

@test begin
    x = random(Exo1SplitQuaternion{BigInt})
    y = random(Exo1SplitQuaternion{BigInt})
    l = alternatorL(x, y)
    r = zero(Exo1SplitQuaternion{BigInt})
    l == r
end

@test begin
    x = random(Exo1SplitQuaternion{BigInt})
    y = random(Exo1SplitQuaternion{BigInt})
    l = alternatorR(x, y)
    r = zero(Exo1SplitQuaternion{BigInt})
    l == r
end

@test begin
    x = random(Exo1SplitQuaternion{BigInt})
    conj(conj(x)) == x
end

@test begin
    x = random(Exo1SplitQuaternion{Rational{BigInt}})
    inv(inv(x)) == x
end

@test begin
    x = random(Exo1SplitQuaternion{BigInt})
    y = random(Exo1SplitQuaternion{BigInt})
    l = conj(x * y)
    r = conj(y) * conj(x)
    l == r
end

@test begin
    x = random(Exo1SplitQuaternion{BigInt})
    y = random(Exo1SplitQuaternion{BigInt})
    l = conj(x + y)
    r = conj(x) + conj(y)
    l == r
end

@test begin
    x = random(Exo1SplitQuaternion{BigInt})
    y = random(Exo1SplitQuaternion{BigInt})
    l = conj(x - y)
    r = conj(x) - conj(y)
    l == r
end

@test begin
    x = random(Exo1SplitQuaternion{Rational{BigInt}})
    y = random(Exo1SplitQuaternion{Rational{BigInt}})
    l = inv(x * y)
    r = inv(y) * inv(x)
    l == r
end

@test begin
    x = random(Exo1SplitQuaternion{Rational{BigInt}})
    y = random(Exo1SplitQuaternion{Rational{BigInt}})
    l = inv(x / y)
    r = y / x
    l == r
end

@test begin
    x = random(Exo1SplitQuaternion{Rational{BigInt}})
    y = random(Exo1SplitQuaternion{Rational{BigInt}})
    l = inv(x \ y)
    r = y \ x
    l == r
end

@test begin
    x = random(Exo1SplitQuaternion{BigInt})
    y = random(Exo1SplitQuaternion{BigInt})
    z = random(Exo1SplitQuaternion{BigInt})
    l = x * (y + z)
    r = (x * y) + (x * z)
    l == r
end

@test begin
    a = CayleyDickson.randomBigInt()
    x = random(Exo1SplitQuaternion{BigInt})
    y = random(Exo1SplitQuaternion{BigInt})
    l = a * (x + y)
    r = (a * x) + (a * y)
    l == r
end

@test begin
    a = CayleyDickson.randomBigInt()
    x = random(Exo1SplitQuaternion{BigInt})
    l = a * x
    r = x * a
    l == r
end

@test begin
    a = random(SplitQuaternion{BigInt})
    x = random(Exo1SplitQuaternion{BigInt})
    l = commutator(a, x)
    r = zero(Exo1SplitQuaternion{BigInt})
    l != r
end

@test begin
    x = random(Exo1SplitQuaternion{BigInt})
    y = random(Exo1SplitQuaternion{BigInt})
    z = random(Exo1SplitQuaternion{BigInt})
    l = (x + y) * z
    r = (x * z) + (y * z)
    l == r
end

@test begin
    x = random(Exo1SplitQuaternion{BigInt})
    y = random(Exo1SplitQuaternion{BigInt})
    z = random(Exo1SplitQuaternion{BigInt})
    l = x * (y - z)
    r = (x * y) - (x * z)
    l == r
end

@test begin
    x = random(Exo1SplitQuaternion{BigInt})
    y = random(Exo1SplitQuaternion{BigInt})
    z = random(Exo1SplitQuaternion{BigInt})
    l = (x - y) * z
    r = (x * z) - (y * z)
    l == r
end

@test begin
    x = random(Exo1SplitQuaternion{BigInt})
    quadrance(x) > big(0) || quadrance(x) < big(0) || quadrance(x) == big(0)
end

@test begin
    x = random(Exo1SplitQuaternion{BigInt})
    y = random(Exo1SplitQuaternion{BigInt})
    l = quadrance(x * y)
    r = quadrance(x) * quadrance(y)
    l == r
end

@test_throws ErrorException begin
    inv(Exo1SplitQuaternion(0, 0.0))
end

@test_throws ErrorException begin
    random(Exo1SplitQuaternion{Int}) / 0
end

@test_throws ErrorException begin
    0 \ random(Exo1SplitQuaternion{Int})
end

@test begin
    a = CayleyDickson.randomBigRational()
    z = random(Exo1SplitQuaternion{Rational{BigInt}})
    l = z / a
    r = a \ z
    l == r
end

@test begin
    a = CayleyDickson.randomBigRational()
    z = random(Exo1SplitQuaternion{Rational{BigInt}})
    l = a / z
    r = z \ a
    l == r
end

@test begin
    z = random(Exo1SplitQuaternion{BigInt})
    z == z + zero(Exo1SplitQuaternion{BigInt})
end

@test begin
    z = random(Exo1SplitQuaternion{BigInt})
    z == z * one(Exo1SplitQuaternion{BigInt})
end

@test begin
    z = random(Exo1SplitQuaternion{BigInt})
    z == z + zero(z)
end

@test begin
    z = random(Exo1SplitQuaternion{BigInt})
    z == z * one(z)
end

@test begin
    widen(Exo1SplitQuaternion{Int32}) == Exo1SplitQuaternion{Int64}
end

@test begin
    float(Exo1SplitQuaternion{Int64}) == Exo1SplitQuaternion{Float64}
end

@test begin
    float(Exo1SplitQuaternion{Float64}) == Exo1SplitQuaternion{Float64}
end

ext: jl


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

name = "P4est"
version = v"2.8"

# Collection of sources required to complete build
sources = [
    ArchiveSource("https://p4est.github.io/release/p4est-2.8.tar.gz", "6a0586e3abac06c20e31b1018f3a82a564a6a0d9ff6b7f6c772a9e6b0f0cc5e4"),
]

# Bash recipe for building across all platforms
script = raw"""
cd p4est-*
if [[ "${target}" == *-freebsd* ]]; then
  export LIBS="-lm"
elif [[ "${target}" == x86_64-linux-musl ]]; then
  # We can't run Fortran programs for the native platform, so a check that the
  # Fortran compiler works would fail.  Small hack: swear that we're
  # cross-compiling.  See:
  # https://github.com/JuliaPackaging/BinaryBuilderBase.jl/issues/50.
  sed -i 's/cross_compiling=no/cross_compiling=yes/' configure
  sed -i 's/cross_compiling=no/cross_compiling=yes/' sc/configure
fi

# Set default preprocessor and linker flags
export CPPFLAGS="-I${includedir}"
export LDFLAGS="-L${libdir}"

# Special Windows treatment
FLAGS=()
if [[ "${target}" == *-mingw* ]]; then
  # Set linker flags only at build time (see https://docs.binarybuilder.org/v0.3/troubleshooting/#Windows)
  FLAGS+=(LDFLAGS="$LDFLAGS -no-undefined")
  # Configure does not find the correct Fortran compiler
  export F77="f77"
  # Link against ws2_32 to use the htonl function from winsock2.h
  export LIBS="-lmsmpi -lws2_32"
  # Disable MPI I/O on Windows since it causes p4est to crash
  mpiopts="--enable-mpi --disable-mpiio"
  # Linker looks for libmsmpi instead of msmpi, copy existing symlink
  cp -d ${libdir}/msmpi.dll ${libdir}/libmsmpi.dll
else
  # Use MPI including MPI I/O on all other platforms
  export CC="mpicc"
  export CXX="mpic++"
  mpiopts="--enable-mpi"
fi

# Configure, build, install
# Note: BLAS is disabled since it is only needed for SC if it is used outside of p4est
./configure --prefix=${prefix} --build=${MACHTYPE} --host=${target} --disable-static --without-blas ${mpiopts}
make -j${nproc} "${FLAGS[@]}"
make install
"""

# These are the platforms we will build for by default, unless further
# platforms are passed in on the command line
platforms = supported_platforms(; experimental=true)
# p4est with MPI enabled does not compile for 32 bit Windows
platforms = filter(p -> !(Sys.iswindows(p) && nbits(p) == 32), platforms)

# The products that we will ensure are always built
products = [
    LibraryProduct("libp4est", :libp4est),
    LibraryProduct("libsc", :libsc)
]

# Dependencies that must be installed before this package can be built
dependencies = [
    Dependency(PackageSpec(name="Zlib_jll", uuid="83775a58-1f1d-513f-b197-d71354ab007a")),
    Dependency(PackageSpec(name="MPICH_jll", uuid="7cb0a576-ebde-5e09-9194-50597f1243b4"); platforms=filter(!Sys.iswindows, platforms)),
    Dependency(PackageSpec(name="MicrosoftMPI_jll", uuid="9237b28f-5490-5468-be7b-bb81f5f5e6cf"); platforms=filter(Sys.iswindows, platforms))
]

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

max_stars_repo_name: jakebolewski/Yggdrasil

max_issues_repo_name: jakebolewski/Yggdrasil

max_forks_repo_name: jakebolewski/Yggdrasil


text:
import LinearAlgebra: det

"""
    CeedDim(dim)

The singleton object of type `CeedDim{dim}`, used for dispatch to linear algebra operations
specialized for small matrices (1, 2, or 3 dimensions).
"""
struct CeedDim{dim} end
@inline CeedDim(dim) = CeedDim{Int(dim)}()

"""
    det(J, ::CeedDim{dim})

Specialized determinant calculations for matrices of size 1, 2, or 3.
"""
@inline det(J, ::CeedDim{1}) = @inbounds J[1]
@inline det(J, ::CeedDim{2}) = @inbounds J[1]*J[4] - J[3]*J[2]
#! format: off
@inline det(J, ::CeedDim{3}) = @inbounds (
    J[1]*(J[5]*J[9] - J[6]*J[8]) -
    J[2]*(J[4]*J[9] - J[6]*J[7]) +
    J[3]*(J[4]*J[8] - J[5]*J[7])
)
#! format: on

"""
    setvoigt(J::StaticArray{Tuple{D,D},T,2})
    setvoigt(J, ::CeedDim{dim})

Given a symmetric matrix `J`, return a `SVector` that encodes `J` using the [Voigt
convention](https://en.wikipedia.org/wiki/Voigt_notation).

The size of the symmetric matrix `J` must be known statically, either specified using
[`CeedDim`](@ref) or `StaticArray`.
"""
@inline setvoigt(J::StaticArray{Tuple{D,D}}) where {D} = setvoigt(J, CeedDim(D))
@inline setvoigt(J, ::CeedDim{1}) = @inbounds @SVector [J[1]]
@inline setvoigt(J, ::CeedDim{2}) = @inbounds @SVector [J[1], J[4], J[2]]
@inline setvoigt(J, ::CeedDim{3}) = @inbounds @SVector [J[1], J[5], J[9], J[6], J[3], J[2]]

@inline function setvoigt!(V, J, ::CeedDim{1})
    @inbounds V[1] = J[1]
end

@inline function setvoigt!(V, J, ::CeedDim{2})
    @inbounds begin
        V[1] = J[1]
        V[2] = J[4]
        V[3] = J[2]
    end
end

@inline function setvoigt!(V, J, ::CeedDim{3})
    @inbounds begin
        V[1] = J[1]
        V[2] = J[5]
        V[3] = J[9]
        V[4] = J[6]
        V[5] = J[3]
        V[6] = J[2]
    end
end

"""
    getvoigt(V, ::CeedDim{dim})

Given a vector `V` that encodes a symmetric matrix using the [Voigt
convention](https://en.wikipedia.org/wiki/Voigt_notation), return the corresponding
`SMatrix`.
"""
@inline getvoigt(V, ::CeedDim{1}) = @inbounds @SMatrix [V[1]]
@inline getvoigt(V, ::CeedDim{2}) = @inbounds @SMatrix [V[1] V[3]; V[3] V[2]]
@inline getvoigt(V, ::CeedDim{3}) = @inbounds @SMatrix [
    V[1] V[6] V[5]
    V[6] V[2] V[4]
    V[5] V[4] V[3]
]
@inline getvoigt(V::StaticArray{Tuple{1}}) = getvoigt(V, CeedDim(1))
@inline getvoigt(V::StaticArray{Tuple{3}}) = getvoigt(V, CeedDim(2))
@inline getvoigt(V::StaticArray{Tuple{6}}) = getvoigt(V, CeedDim(3))

@inline function getvoigt!(J, V, ::CeedDim{1})
    @inbounds J[1, 1] = V[1]
end

@inline function getvoigt!(J, V, ::CeedDim{2})
    @inbounds begin
        #! format: off
        J[1,1] = V[1] ; J[1,2] = V[3]
        J[2,1] = V[3] ; J[2,2] = V[2]
        #! format: on
    end
end

@inline function getvoigt!(J, V, ::CeedDim{3})
    @inbounds begin
        #! format: off
        J[1,1] = V[1] ; J[1,2] = V[6] ; J[1,3] = V[5]
        J[2,1] = V[6] ; J[2,2] = V[2] ; J[2,3] = V[4]
        J[3,1] = V[5] ; J[3,2] = V[4] ; J[3,3] = V[3]
        #! format: on
    end
end

function tmp_view(obj, view_fn)
    str = mktemp() do fname, f
        cf = Libc.FILE(f)
        er = view_fn(obj, cf.ptr)
        ccall(:fflush, Cint, (Ptr{Cvoid},), cf)
        seek(f, 0)
        read(f, String)
    end
    chomp(str)
end

function ceed_show(io::IO, obj, view_fn)
    print(io, tmp_view(obj[], view_fn))
end

max_stars_repo_name: AdelekeBankole/libCEED

max_issues_repo_name: AdelekeBankole/libCEED

max_forks_repo_name: AdelekeBankole/libCEED


text:
# --------------------------------------------------------------------------- #
# IO functionality
# Saving and loading images, labels, models, ...

getext(fname) = splitext(fname)[2]
hasext(fname, ext) = getext(fname) == ext

joinext(fname, ext) = hasext(fname, ext) ? fname : fname * ext
joinext(fname, ext, autoext) = autoext ? joinext(fname, ext) : fname

# --------------------------------------------------------------------------- #
# Images

fileext(::Image) = ".tif"
fileext(::Type{<: Image}) = ".tif"

function imgsave(fname :: String, img :: GreyscaleImage, autoext = true)
  fname = joinext(fname, fileext(img), autoext)
  img = imgdata(img)
  FileIO.save(fname, convert(Array{Images.Gray{Images.N0f16}}, img))
end

function imgsave(fname :: String, img :: RGBImage, autoext = true)
  fname = joinext(fname, fileext(img), autoext)
  img = permutedims(imgdata(img), (3, 1, 2))
  FileIO.save(fname, Images.colorview(Images.RGB, img))
end

function imgload(fname :: String, autoext = true)
  fname = joinext(fname, fileext(Image), autoext)
  img = FileIO.load(fname)
  if eltype(img) <: Images.RGB
    img = permutedims(Images.channelview(img), (2, 3, 1))
    return RGBImage(img)
  else
    return GreyscaleImage(img)
  end
end

# --------------------------------------------------------------------------- #
# Labels

fileext(::Label) = ".dccl"
fileext(::Type{Label}) = ".dccl"

function lblsave(fname :: String, lbl :: Label, autoext = true)
  fname = joinext(fname, fileext(lbl), autoext)
  writedlm(fname, convert(Matrix{Int}, lbl))
end

function lblload(fname :: String, autoext = true)
  fname = joinext(fname, fileext(Label), autoext)
  return Label(readdlm(fname, Int))
end

# --------------------------------------------------------------------------- #
# Labeled images

function lmgsave(fname :: String, limg :: LabeledImage, autoext = true)
  basename = splitext(fname)[1]
  if autoext
    imgsave(fname, limg[1])
    if hasext(fname, fileext(Image))
      lblsave(basename, limg[2])
    else
      lblsave(fname, limg[2])
    end
  else
    imgsave(fname, limg[1], false)
    lblsave(basename, limg[2], true)
  end
end

function lmgload(fname :: String, autoext = true)
  basename = splitext(fname)[1]
  if autoext
    if hasext(fname, fileext(Image))
      return imgload(fname), lblload(basename)
    else
      return imgload(fname), lblload(fname)
    end
  else
    return imgload(fname, false), lblload(basename, true)
  end
end

function lmgload(imgname :: String, lblname :: String, axtoext = true)
  if autoext
    return imgload(imgname), lblload(lblname)
  else
    return imgload(imgname, false), lblload(lblname, false)
  end
end

# --------------------------------------------------------------------------- #
# Models

fileext(::Model) = ".dccm"
fileext(::Type{<: Model}) = ".dccm"

function modelsave(fname :: String,
                   model :: Model,
                   autoext = true;
                   name :: String = "",
                   description :: String = "")

  fname = joinext(fname, fileext(model), autoext)
  name = (name == "") ? splitext(basename(fname))[1] : name
  # Do not use JLD2.@save, since this worked buggy on distributed
  # file systems. See issue #55 of JLD2.jl. Disadvantage: Not using
  # nmap probably is much slower, which should however not be a
  # problem for the relatively small models used in this project
  JLD2.jldopen(fname, true, true, true, IOStream) do file
    write(file, "model", model)
    write(file, "name", name)
    write(file, "description", description)
  end
end

function modelload(fname :: String,
                   autoext = true;
                   name :: Bool = false,
                   description :: Bool = false)

  fname = joinext(fname, fileext(Model), autoext)
  returnname = name
  returndescr = description

  JLD2.@load fname model name description

  if returnname && returndescr return model, name, description
  elseif returndescr           return model, description
  elseif returnname            return model, name
  else                         return model
  end
end

# --------------------------------------------------------------------------- #
# Lessons

fileext(::Lesson) = ".dcct"
fileext(::Type{<: Lesson}) = ".dcct"

function lessonsave(fname :: String, lesson :: Lesson, autoext = true)
  fname = joinext(fname, fileext(lesson), autoext)
  JLD2.jldopen(fname, true, true, true, IOStream) do file
    write(file, "lesson", lesson)
  end
end

function lessonload(fname :: String, autoext = true)
  fname = joinext(fname, fileext(Lesson), autoext)
  JLD2.@load fname lesson
  return lesson
end

max_stars_repo_name: tscode/DCellC

max_issues_repo_name: tscode/DCellC


text:
module StringDistances

using Distances
import StatsAPI: pairwise, pairwise!

include("distances/utils.jl")
include("distances/edit.jl")
include("distances/qgram.jl")
include("distances/qgram_preprocessed.jl")

include("modifiers.jl")
include("normalize.jl")
include("pairwise.jl")
# Distances API
Distances.result_type(dist::StringDistance, s1::Type, s2::Type) = typeof(dist("", ""))
Distances.result_type(dist::StringDistance, s1, s2) = result_type(dist, typeof(s1), typeof(s2))

##############################################################################
##
## Export
##
##############################################################################

export
StringDistance,
Hamming,
Levenshtein,
DamerauLevenshtein,
Jaro,
JaroWinkler,
RatcliffObershelp,
AbstractQGramDistance,
QGramDict,
QGramSortedVector,
QGram,
Cosine,
Jaccard,
SorensenDice,
Overlap,
MorisitaOverlap,
NMD,
Partial,
TokenSort,
TokenSet,
TokenMax,
evaluate,
compare,
result_type,
qgrams,
findnearest,
pairwise,
pairwise!
end


text:
module Halfspace

using JLD
using StatsBase
using Convex
using SCS

include("common.jl")
include("opt.jl")
include("alg3.jl")
include("alg4.jl")

end # module

max_stars_repo_name: innerlee/Halfspace

max_issues_repo_name: innerlee/Halfspace

max_forks_repo_name: innerlee/Halfspace


text:
using LogFixPoint16s, Lorenz63, PyPlot

LogFixPoint16s.set_nfrac(10)

Δt = 0.005
N = 200000

XYZ0 = L63(Float64;N,Δt)
XYZ1 = L63(Float16;N,Δt)
XYZ2 = L63(LogFixPoint16;N,Δt)

## PLOTTING
pygui(true)
fig,(ax1,ax2,ax3) = subplots(1,3,sharex=true,sharey=true,figsize=(10,3.5))

ax1.plot(XYZ0[1,:],XYZ0[3,:],"k",lw=0.05)
ax2.plot(XYZ1[1,:],XYZ1[3,:],"k",lw=0.05)
ax3.plot(XYZ2[1,:],XYZ2[3,:],"k",lw=0.05)

ax1.set_xticks([])
ax1.set_yticks([])
ax1.set_xlabel("x")
ax2.set_xlabel("x")
ax3.set_xlabel("x")
ax1.set_ylabel("y")

ax1.set_title("Float64",loc="left")
ax2.set_title("Float16",loc="left")
ax3.set_title("LogFixPoint16",loc="left")
ax1.set_title("a",loc="right",fontweight="bold")
ax2.set_title("b",loc="right",fontweight="bold")
ax3.set_title("c",loc="right",fontweight="bold")

tight_layout()
savefig("lorenz_attractor.png",dpi=200)


text:
###
# Helper Tests
###
include("../src/helpers.jl")

facts("bootstrapping tests") do
	#single variate data
	srand(8765309)
	data = randn(1000)
	@fact boot(data, mean, .9, 10000) --> roughly(0.108, 1e-3)

	#multivariate data
	srand(8765309)
	data = randn(1000, 3)
	f= x->mean(minimum(x, 1)) # a nonsense function
	@fact boot(data, f, .9, 10000) --> roughly(-2.8777884239388682, 1e-8)
end

facts("t-approximations") do
	srand(8765309)
	data = randn(1000, 3)
	out = calcMeansT(data, .1)
	@fact out[1] --> roughly(0.004451891728022329, 1e-8)
	@fact out[2] --> roughly(0.06592683689569365, 1e-8)

	out = calcMeansT(data, .1, joint=false)
	@fact out[1] --> roughly(0.011243060792593858, 1e-8)
	@fact out[2] --> roughly(0.05913566783112214, 1e-8)
end

facts("fwdBackSigsTest") do
	srand(8675309); data = randn(100)
	sigfwd, sigback = calcSigsBoot(data, .1, 10000)
	@fact sigfwd  --> roughly(1.09, 1e-2)
	@fact sigback --> roughly(1.09, 1e-2)
end

facts("KSGammaTest") do
	@fact KSGamma(.1, 1000) --> roughly(0.0385517413380297)
end

facts("boot_mu_test") do
	srand(8675309); data = randn(100)
	@fact boot_mu(data, .1, 100) --> roughly(0.15,1e-2)
end

facts("boot_sigma_test") do
	srand(8675309); data = randn(100)
	@fact boot_sigma(data, .1, 100) --> roughly(0.20,1e-2)
end

facts("ab_thresh_test") do
	srand(8675309); data = randn(100, 3)
	@fact calc_ab_thresh(data, .2, 100, 100) --> roughly(0.177,1e-3)
end


text:
__precompile__()

module PerfLog

import Base: show, time_ns, gc_bytes
export TimerOutput, @timeit, @timeit_debug, reset_timer!, print_timer, timeit

using Crayons
using Printf
using Unicode
using UUIDs

include("TimerOutput.jl")
include("show.jl")
include("utilities.jl")

end # module


text:
using Test
using ExtensibleScheduler
using ExtensibleScheduler: real_time_clock, ClockException

@testset "Clocks" begin
    @testset "RealTimeClock" begin
        @test now(real_time_clock) isa DateTime

        @test_throws ClockException set(real_time_clock, DateTime(2010, 1, 1))
    end

    @testset "SimClock" begin
        dt_start = DateTime(2010, 1, 1, 13, 37)
        dt = dt_start
        clock = SimClock(dt)
        now_ = now(clock)
        @test now_ isa DateTime
        @test now_ == dt_start
        dt += Dates.Minute(1)
        set(clock, dt)
        @test now(clock) == dt

        dt -= Dates.Minute(2)
        @test_throws ClockException set(clock, dt)

    end
end


text:
# Constraints parameters
const BENCHED_CONSTRAINTS = deepcopy(usual_constraints)

const DEFAULT_CONCEPTS = [(:all_different, nothing)]
const DEFAULT_LANGUAGES = [:Julia] # [:Julia, :C, :CPP]
const DEFAULT_METRICS = [:hamming, :manhattan]
const DEFAULT_COMPLETE_SEARCH_LIMIT = 5^5# 6^6 # could be improved with multithreading
const DEFAULT_PARTIAL_SEARCH_LIMIT = 4^4
const DEFAULT_SAMPLINGS = [1000, 100]

const MINIMUM_DOMAIN_SIZE = 3
const MAXIMUM_DOMAIN_SIZE = 8 # NOTE - Check if it is too high

function domains_sizes(;
    min_domain_size=MINIMUM_DOMAIN_SIZE, max_domain_size=MAXIMUM_DOMAIN_SIZE
)
    return reverse(collect(min_domain_size:max_domain_size))
end

# Genetic Algorithms default parameters
const MAXIMUM_TOTAL_ITERATIONS = 12 # order => 2^15 = 32768 // lower this param
const MINIMUM_ICN_ITERATIONS = 5 # order => 2^5= 32
const MINIMUM_GENERATIONS = 5 # order => 2^5 = 32

function icn_iterations(;
    min_icn_iterations=MINIMUM_ICN_ITERATIONS,
    min_generations=MINIMUM_GENERATIONS,
    max_total_iterations=MAXIMUM_TOTAL_ITERATIONS,
)
    maximum_icn_iterations = max_total_iterations - min_generations
    return reverse([2^i for i in min_icn_iterations:maximum_icn_iterations])
end

function generations(;
    min_icn_iterations=MINIMUM_ICN_ITERATIONS,
    min_generations=MINIMUM_GENERATIONS,
    max_total_iterations=MAXIMUM_TOTAL_ITERATIONS,
)
    maximum_generations = max_total_iterations - min_icn_iterations
    return reverse([2^i for i in min_generations:maximum_generations])
end

const DEFAULT_POPULATIONS = reverse([2^i for i in 6:8]) # 2^5=32 to 2^10 = 1024

const DEFAULT_LOSS_SAMPLING_THRESHOLD = 2^10

root(n) = x -> round(Int, x^(1 / n))
constant(n) = _ -> n

const DEFAULT_LOSS_SAMPLER = [
    nothing, root(2), root(3), constant(DEFAULT_LOSS_SAMPLING_THRESHOLD)
]

const DEFAULT_MEMOIZATION = [true, false]

# All parameters
const ALL_PARAMETERS = Dict(
    # Search parameters
    :concept => DEFAULT_CONCEPTS,
    :complete_search_limit => DEFAULT_COMPLETE_SEARCH_LIMIT,
    :domains_size => domains_sizes(),
    :partial_search_limit => DEFAULT_PARTIAL_SEARCH_LIMIT,
    :sampling => DEFAULT_SAMPLINGS,
    :search => [:partial, :complete], # :flexible is also an option

    # # Learning parameter
    :metric => DEFAULT_METRICS,
    :generations => [32,64,128], #generations(),
    :icn_iterations => [32,64,128], #icn_iterations(),
    :language => DEFAULT_LANGUAGES,
    :population => DEFAULT_POPULATIONS,
    :loss_sampler => nothing, #DEFAULT_LOSS_SAMPLER,
    :loss_sampling_threshold => Inf, #DEFAULT_LOSS_SAMPLING_THRESHOLD,
    :memoize => DEFAULT_MEMOIZATION,
)

# ALL_PARAMETERS[:search] = [:flexible]
# ALL_PARAMETERS[:domains_size] = 8

"""
to run on khromeleque:
cd ~/.julia/dev/ICNBenchmarks/scripts
../../../../julia -t auto main.jl no_overlap "ALL_PARAMETERS[:generations] = [32,64,128]" "ALL_PARAMETERS[:icn_iterations] = [32,64,128]" "ALL_PARAMETERS[:loss_sampler] = nothing" "ALL_PARAMETERS[:loss_sampling_threshold] = Inf" "ALL_PARAMETERS[:population] = [64,128,256]" "ALL_PARAMETERS[:population] = [64,128,256]" "ALL_PARAMETERS[:complete_search_limit] = 256"
"""
ALL_PARAMETERS[:generations] = [32,64,128]
ALL_PARAMETERS[:icn_iterations] = [32,64,128]
ALL_PARAMETERS[:loss_sampler] = nothing
ALL_PARAMETERS[:loss_sampling_threshold] = Inf
ALL_PARAMETERS[:population] = [64,128,256]


text:
if !isdefined(:gym) include("../base.jl") end

import POMDPs: MDP, Solver

type CrossentropyPolicySolver <: Solver
    epochs::Int64
    n_samples::Int64
    percentile::Float64
    smoothing::Float64
    max_frame_iterations::Int64
    min_score::Float64
    min_score_step::Float64
    print_every_n::Int64
end

CrossentropyPolicySolver(epochs = 10, n_samples = 100, percentile = 0.5, smoothing = 0.1; max_frame_iterations = 100, print_every_n = 25, min_score = 0.0, min_score_step = 0.0) =
    CrossentropyPolicySolver(epochs, n_samples, percentile, smoothing, max_frame_iterations, min_score, min_score_step, print_every_n)

function solve(solver::CrossentropyPolicySolver, pomdp::MDP; verbose = true)

    policy = CrossentropyPolicy(pomdp)

    last_value = -1

    for i=1:solver.epochs

        batch_states  = Vector{Int64}[] # a list of lists of states in each session
        batch_actions = Vector{Int64}[] # a list of lists of actions in each session
        batch_rewards = Float64[] # a list of floats - total rewards at each session

        for j=1:solver.n_samples

            if verbose && (j == 1 || j % solver.print_every_n == 0)
                println("Epoch: $i, Episode: $j")
            end

            session_states, session_actions, session_reward, session_states_new, session_rewards = run_experiment(pomdp, policy, solver.max_frame_iterations; keep_history = true)
            push!(batch_states, session_states)
            push!(batch_actions, session_actions)
            append!(batch_rewards, session_reward)
        end

        # Identify threshold which filters out best performing games
        reward_threshold = quantile(batch_rewards, solver.percentile);
        reward_threshold += if reward_threshold == solver.min_score solver.min_score_step else zero(reward_threshold) end
        reward_valid_indices = batch_rewards .>= reward_threshold;
        reward_valid_indices_count = sum(reward_valid_indices)

        # Create a filtered view to best peforming games
        filtered_states  = view(batch_states, reward_valid_indices);
        filtered_actions = view(batch_actions, reward_valid_indices);

        # Create a new policy matrix which has identical structure and smoothing value
        if reward_valid_indices_count > 0

            policy_values = zeros(policy.action_map) + solver.smoothing;
            for ep in 1:reward_valid_indices_count
                map(x -> policy_values[filtered_actions[ep][x], filtered_states[ep][x]] += 1 , 1:length(filtered_actions[ep]));
            end

            policy_values = policy_values ./ sum(policy_values, 1)
            policy.action_map = policy_values

        end

        println("Threshold: $reward_threshold, Size: $(sum(reward_valid_indices))")
        println("Sum score: $(sum(batch_rewards)), Max score: $(maximum(batch_rewards)), Mean score: $(round(mean(batch_rewards), 2)), Median score: $(median(batch_rewards))")

    end

    return policy

end

max_stars_repo_name: dmitrijsc/practical-rl

max_issues_repo_name: dmitrijsc/practical-rl

max_forks_repo_name: dmitrijsc/practical-rl


text:
@testset "CircularBuffer" begin

    @testset "Core Functionality" begin
        cb = CircularBuffer{Int}(5)
        @testset "When empty" begin
            @test length(cb) == 0
            @test capacity(cb) == 5
            @test_throws BoundsError first(cb)
            @test isempty(cb) == true
            @test isfull(cb) == false
        end

        @testset "With 1 element" begin
            push!(cb, 1)
            @test length(cb) == 1
            @test capacity(cb) == 5
            @test isfull(cb) == false
        end

        @testset "Appending many elements" begin
            append!(cb, 2:8)
            @test length(cb) == capacity(cb)
            @test size(cb) == (length(cb),)
            @test isempty(cb) == false
            @test isfull(cb) == true
            @test convert(Array, cb) == Int[4,5,6,7,8]
        end

        @testset "getindex" begin
            @test cb[1] == 4
            @test cb[2] == 5
            @test cb[3] == 6
            @test cb[4] == 7
            @test cb[5] == 8
            @test_throws BoundsError cb[6]
            @test_throws BoundsError cb[3:6]
            @test cb[3:4] == Int[6,7]
            @test cb[[1,5]] == Int[4,8]
        end

        @testset "setindex" begin
            cb[3] = 999
            @test convert(Array, cb) == Int[4,5,999,7,8]
        end
    end

    @testset "other constructor" begin
        cb = CircularBuffer(10)
        @test length(cb) == 0
        @test typeof(cb) <: CircularBuffer{Any}
    end

    @testset "pushfirst" begin
        cb = CircularBuffer{Int}(5)  # New, empty one for full test coverage
        for i in -5:5
            pushfirst!(cb, i)
        end
        arr = convert(Array, cb)
        @test arr == Int[5, 4, 3, 2, 1]
        for (idx, n) in enumerate(5:1)
            @test arr[idx] == n
        end
    end

    @testset "Issue 429" begin
        cb = CircularBuffer{Int}(5)
        map(x -> pushfirst!(cb, x), 1:8)
        pop!(cb)
        pushfirst!(cb, 9)
        @test length(cb.buffer) == cb.capacity
        arr = convert(Array, cb)
        @test arr == Int[9, 8, 7, 6, 5]
    end

    @testset "Issue 379" begin
        cb = CircularBuffer{Int}(5)
        pushfirst!(cb, 1)
        @test cb == [1]
        pushfirst!(cb, 2)
        @test cb == [2, 1]
    end

    @testset "empty!" begin
        cb = CircularBuffer{Int}(5)
        push!(cb, 13)
        empty!(cb)
        @test length(cb) == 0
    end

    @testset "pop!" begin
        cb = CircularBuffer{Int}(5)
        for i in 0:5    # one extra to force wraparound
            push!(cb, i)
        end
        for j in 5:-1:1
            @test pop!(cb) == j
            @test convert(Array, cb) == collect(1:j-1)
        end
        @test isempty(cb)
        @test_throws ArgumentError pop!(cb)
    end

    @testset "popfirst!" begin
        cb = CircularBuffer{Int}(5)
        for i in 0:5    # one extra to force wraparound
            push!(cb, i)
        end
        for j in 1:5
            @test popfirst!(cb) == j
            @test convert(Array, cb) == collect(j+1:5)
        end
        @test isempty(cb)
        @test_throws ArgumentError popfirst!(cb)
    end

    @testset "fill!" begin
        @testset "fill an empty buffer" begin
            cb = CircularBuffer{Int}(3)
            fill!(cb, 42)
            @test Array(cb) == [42, 42, 42]
        end
        @testset "fill a non empty buffer" begin
            cb = CircularBuffer{Int}(3)
            push!(cb, 21)
            fill!(cb, 42)
            @test Array(cb) == [21, 42, 42]
        end
    end
end


text:
using Documenter, DocumenterMarkdown, BrainWave

if ispath("build/")
    rm("build/", recursive=true)
end

if ispath("site/")
    rm("site/", recursive=true)
end

include("runWeave.jl") #convert weave file to markdown
makedocs(format = Markdown(), modules = [BrainWave], source="src", build="build")
run(`mkdocs build`)


text:
function __init__()
    if isdefined(Main, :PLOTS_DEFAULTS)
        if haskey(Main.PLOTS_DEFAULTS, :theme)
            theme(Main.PLOTS_DEFAULTS[:theme])
        end
        for (k,v) in Main.PLOTS_DEFAULTS
            k == :theme || default(k, v)
        end
    end
    pushdisplay(PlotsDisplay())

    atreplinit(i -> begin
        if PlotDisplay() in Base.Multimedia.displays
            popdisplay(PlotsDisplay())
        end
        pushdisplay(PlotsDisplay())
    end)

    @require GLVisualize = "4086de5b-f4b6-55f3-abb0-b8c73827585f" include(joinpath(@__DIR__, "backends", "glvisualize.jl"))
    @require HDF5 = "f67ccb44-e63f-5c2f-98bd-6dc0ccc4ba2f" include(joinpath(@__DIR__, "backends", "hdf5.jl"))
    @require InspectDR = "d0351b0e-4b05-5898-87b3-e2a8edfddd1d" include(joinpath(@__DIR__, "backends", "inspectdr.jl"))
    @require PGFPlots = "3b7a836e-365b-5785-a47d-02c71176b4aa" include(joinpath(@__DIR__, "backends", "pgfplots.jl"))
    @require PlotlyJS = "f0f68f2c-4968-5e81-91da-67840de0976a" include(joinpath(@__DIR__, "backends", "plotlyjs.jl"))
    @require PyPlot = "d330b81b-6aea-500a-939a-2ce795aea3ee" include(joinpath(@__DIR__, "backends", "pyplot.jl"))
    @require UnicodePlots = "b8865327-cd53-5732-bb35-84acbb429228" include(joinpath(@__DIR__, "backends", "unicodeplots.jl"))

    # ---------------------------------------------------------
    # IJulia
    # ---------------------------------------------------------

    @require IJulia = "7073ff75-c697-5162-941a-fcdaad2a7d2a" begin
        if IJulia.inited

            """
            Add extra jupyter mimetypes to display_dict based on the plot backed.

            The default is nothing, except for plotly based backends, where it
            adds data for `application/vnd.plotly.v1+json` that is used in
            frontends like jupyterlab and nteract.
            """
            _extra_mime_info!(plt::Plot, out::Dict) = out
            function _extra_mime_info!(plt::Plot{PlotlyJSBackend}, out::Dict)
                out["application/vnd.plotly.v1+json"] = JSON.lower(plt.o)
                out
            end

            function _extra_mime_info!(plt::Plot{PlotlyBackend}, out::Dict)
                out["application/vnd.plotly.v1+json"] = Dict(
                    :data => plotly_series(plt),
                    :layout => plotly_layout(plt)
                )
                out
            end

            function IJulia.display_dict(plt::Plot)
                output_type = Symbol(plt.attr[:html_output_format])
                if output_type == :auto
                    output_type = get(_best_html_output_type, backend_name(plt.backend), :svg)
                end
                out = Dict()
                if output_type == :txt
                    mime = "text/plain"
                    out[mime] = sprint(show, MIME(mime), plt)
                elseif output_type == :png
                    mime = "image/png"
                    out[mime] = base64encode(show, MIME(mime), plt)
                elseif output_type == :svg
                    mime = "image/svg+xml"
                    out[mime] = sprint(show, MIME(mime), plt)
                elseif output_type == :html
                    mime = "text/html"
                    out[mime] = sprint(show, MIME(mime), plt)
                else
                    error("Unsupported output type $output_type")
                end
                _extra_mime_info!(plt, out)
                out
            end

            ENV["MPLBACKEND"] = "Agg"
        end
    end
end


text:
"""
    getData()

Reads the CSV data file and returns the dataframe, hosts and viruses.
"""
function getData()
    # reading the data file
    df = CSV.read("./data/virionette.csv");
    # making a sorted list of unique hosts and viruses
    hosts = sort(unique(df.host_species));
    viruses = sort(unique(df.virus_genus));

    return df, hosts, viruses
end

"""
    buildInteractionMatrix()

Prepares the interaction matrix with initial data and returns the interaction
matrix, the hosts, viruses, and the dataframe.
"""
function buildInteractionMatrix()
    # getting the data
    (df, hosts, viruses) = getData()
    # filling the matrix with ones where an interaction occurs
    interaction_matrix = zeros(Float64, (length(viruses), length(hosts)))
    for interaction in eachrow(df)
        host_idx = findfirst(hosts .== interaction.host_species)
        virus_idx = findfirst(viruses .== interaction.virus_genus)
        interaction_matrix[virus_idx, host_idx] = 1.0
    end

    return interaction_matrix, hosts, viruses, df
end

"""
    crossValidation(targetedValue, initialValueMatrix, α, rank,
        suspected_newData, unlikely_newData)

Computes the imputation for a given matrix if the targeted value is 0.
Computes the leave one out validation for a given matrix if the targeted value
is 1.
"""
function crossValidation(targetedValue, initialValueMatrix, α, rank, suspected_newData, unlikely_newData)
    # printing the parameters of the current test
    println("Targeted Value: $(targetedValue) ",
    println("Rank: $(rank)")
    println("Alpha: $(α)")
    # building the interaction matrix
    (interaction_matrix, hosts, viruses, df) = buildInteractionMatrix()
    # targeting the positions to impute
    positions_to_impute = findall(interaction_matrix .== targetedValue)
    # copying the interaction matrix aimed to be modified
    output_matrix = copy(interaction_matrix)
    # doing the imputation for every targeted value
    @showprogress for position in positions_to_impute
        output_matrix[position] = imputation(interaction_matrix,
            position, initialValueMatrix, rank)
    end
    # visualizing the interactions
    display(plot(generateHeatmap("Initial Matrix \n(targeted value: $(targetedValue), rank: $(rank))", interaction_matrix),
        generateHeatmap("Output matrix", output_matrix,)))

    # Calculating the variation between the initial and final matrices
    #println("Variation: $(calculateVariation(interaction_matrix, output_matrix))%")

    # getting the top 10 interactions
    (maxValues, delta) = getTopInteractions(10, interaction_matrix, output_matrix, hosts, viruses, df)
    # generating the table of results
    generateResultsTable(maxValues, α, rank, suspected_newData, unlikely_newData, delta, hosts)
end

"""
    imputation(matrix, position, initialValueMatrix, rank; tolerance=1e-2, maxiter=50)

This function returns the imputed value at a given position (expressed in
CartesianCoordinates) in the matrix, seeded from a value in initialeValueMatrix. The imputation
is done by iterating an SVD at a given rank, and stops when the iteration
difference is smaller than the absolute tolerance, or after maxiter steps
have been done. Returns the final value for the current imputed position.
"""
function imputation(matrix, position, initialValueMatrix, rank; tolerance = 1e-2, maxiter = 50)
    # making a temporary copy of the initial matrix
    tempMatrix = copy(matrix)
    # updating the current position to impute from the initial matrix to
    # the initial value determined by the filter
    tempMatrix[position] = initialValueMatrix[position]
    # setting the Δ and initial iteration values
    Δ = 1.0
    iter = 1
    # iterating the SVD
    while Δ > tolerance
        # increasing the iteration value
        iter += 1
        # approximating the matrix
        approx_matrix = lowrank(tempMatrix, rank)
        # the change in value is the absolute difference between the
        # next and current iteration
        Δ = abs(approx_matrix[position] - tempMatrix[position])
        #  updating the temporary matrix at the current imputed position
        tempMatrix[position] = approx_matrix[position]
        # we stop if there are more than a set number of iterations
        iter ≥ maxiter && break
    end

    return tempMatrix[position]
end

"""
    lowrank(matrix, svd_rank)

Returns the low rank appproximation of the matrix, after a SVD.
"""
function lowrank(matrix, svd_rank)
    # making sure that the rank of the matrix is greater than the chosen rank
    @assert svd_rank ≤ rank(matrix)
    # factorizing the matrix
    factorization = svd(matrix)
    # fixing to zero all the singular values found after the chosen rank
    factorization.S[(svd_rank + 1):end] .= zero(eltype(factorization.S))
    # Note that the SVD method returns Vt, which is the transposed
    # right singular matrix

    return factorization.U * Diagonal(factorization.S) * factorization.Vt
end

"""
    generateHeatMap(title, matrix)

Returns a heatmap based on the given matrix.
"""
function generateHeatmap(title, matrix)

    return heatmap(matrix, xlabel = "Hosts", ylabel = "Viruses", c = :Greys,
        leg = true, frame = :box, title = title)
end

"""
    calculateVariation(initial_matrix, output_matrix)

Calculates the variation between two matrices.
"""
function calculateVariation(initial_matrix, output_matrix)
    # calculating the variation between two matrices
    delta = sum(abs.(initial_matrix .- output_matrix))

    return round((delta/length(initial_matrix)) * 100, digits = 2);
end

"""
    getTopInteractions(top, initial_matrix, output_matrix, hosts, viruses, df)

Returns the top imputed interactions with the highest probabilities of occurrence.

"""
function getTopInteractions(top, initial_matrix, output_matrix, hosts, viruses, df)
    # Initializing the minimum value
    minValue = findmin(output_matrix)
    # Creating a buffer to stock the maximum probability values and their indexes
    maxValues = CircularBuffer{Tuple{Float64,Int64,Int64}}(top)
    # Initializing the maximum value array to the minimum value
    push!(maxValues, (minValue[1],minValue[2][1],minValue[2][2]));
    # Iterating through the matrix
    for r in 1:size(output_matrix,1)
        for c in 1:size(output_matrix,2)
            # making sure that the present interaction was initially missing, and is now a max
            # selecting only the betacoronaviruses and bat hosts
            if initial_matrix[r,c] == 0 && occursin("Betacoronavirus", viruses[r]) &&  first(df[(df.host_species .== hosts[c]),:]).host_order == "Chiroptera" && output_matrix[r,c] > findmin(maxValues)[1][1]
                # sorting the maximums
                sort!(maxValues)
                # adding the new value at the end of tthe array and overwriting the smallest one
                push!(maxValues, (output_matrix[r,c],r,c))
            end
        end
    end
    # sorting the array in decreasing order
    sort!(maxValues, rev=true)
    # printing the top10 interactions
    println("The top $(top) predicted interactions are:")
    for t in 1:top
        println("Virus: ", viruses[maxValues[t][2]], "  Host: ", hosts[maxValues[t][3]])
        #println("Virus: ", viruses[maxValues[t][2]], "  Host: ", hosts[maxValues[t][3]], " With: ", round(maxValues[t][1]*100, digits=1),"%")
    end
    # calculating the difference between the intial and finale value of the interaction with the highest score
    delta = maxValues[1][1] - initial_matrix[maxValues[1][2],maxValues[1][3]];
    println("The highest scoring interaction is:")
    println("Virus: ", viruses[maxValues[1][2]], "  Host: ", hosts[maxValues[1][3]], " With a Δ of: ", delta)

    # returning the array containing the top10
    return maxValues, delta
end

"""
    calculateInitialeValues(matrix, α)
Calculates the initial values to be attributed by applying a linear filter to the matrix,
using weighted parameters α.

"""
function calculateInitialeValues(matrix, α)
    # converting ones and zeros in boolean
    matrix_bool = convert(Array{Bool}, matrix.== 1)
    # converting matrix in bipartite network
    B = BipartiteNetwork(matrix_bool)
    # applying the linear filter
    F = linearfilter(B, α = α)

    #returning the adjacency matrix
    return(F.A)
end

"""
    generateResultsTable(top10, α, rank, suspected_newData, unlikely_newData, delta, hosts)

Generates an automated results table containing the combinations of alphas
used for the linear filter,the ranks used for the simulation,
and the number of species predicted in the top10 that are also included in the new dataset.
"""

function generateResultsTable(top10, α, rank, suspected_newData, unlikely_newData, delta, hosts)
    # creating a count to keep trace of the suspected and unlikely hosts
    suspected_count = 0;
    unlikely_count = 0;
    # updating the counts for suspected and unlikely hosts
    for i in 1:length(top10)
        if findfirst(suspected -> suspected == hosts[top10[i][3]], suspected_newData) != nothing
            suspected_count += 1;
        end
        if findfirst(unlikely -> unlikely == hosts[top10[i][3]], unlikely_newData) != nothing
            unlikely_count += 1;
        end
    end
    # collecting results
    results = DataFrame(Rank = [rank], Alpha = [α], Suspected = [suspected_count], Unlikely = [unlikely_count], Delta = [delta])
    # wrinting the results in a CSV file
    CSV.write("Results.csv", results, append = true, delim =';')
end


text:
@testset "conversions" begin
    warsaw = tz"Europe/Warsaw"
    zdt = ZonedDateTime(DateTime(2016, 11, 10, 1, 45), winnipeg)
    lzdt = LaxZonedDateTime(DateTime(2016, 11, 10, 1, 45), winnipeg)
    dne = LaxZonedDateTime(DateTime(2015, 3, 8, 2), winnipeg)
    amb = LaxZonedDateTime(DateTime(2016, 11, 6, 1, 45), winnipeg)

    atz_zdt = astimezone(zdt, warsaw)
    atz_lzdt = astimezone(lzdt, warsaw)
    @test atz_zdt == atz_lzdt
    @test timezone(atz_zdt) == timezone(atz_lzdt)
    @test DateTime(lzdt, UTC) == DateTime(atz_lzdt, UTC)

    atz_dne = astimezone(dne, warsaw)
    atz_amb = astimezone(amb, warsaw)
    @test timezone(atz_dne) != warsaw
    @test timezone(atz_amb) != warsaw
    @test !isvalid(atz_dne)
    @test !isvalid(atz_amb)
end


text:
using PyPlot
using DelimitedFiles
using PyCall
mpl = pyimport("tikzplotlib")

weak = readdlm("timing.txt")

figure()
pm = sortperm(weak[:,1])
weak = weak[pm,:]
semilogx(weak[:,1], weak[:,2], "o-", label = "Forward")
semilogx(weak[:,1], weak[:,3], "o-", label = "Backward")
xlabel("Number of Processors", fontsize = 20)
ylabel("Time (sec)", fontsize = 20)
gca().xaxis.set_tick_params(labelsize=20)
gca().yaxis.set_tick_params(labelsize=20)
legend(fontsize=18)
grid("on")
tight_layout()
savefig("elastic_weak.png")
mpl.save("../figures/elastic_weak.tex")


text:
import ProgressMeter

#####
##### Reporting progress.
#####

"""
$(TYPEDEF)

A placeholder type for not reporting any information.
"""
struct NoProgressReport end

"""
$(SIGNATURES)

Report to the given `reporter`.

The second argument can be

1. a string, which is displayed as is (this is supported by all reporters).

2. or a step in an MCMC chain with a known number of steps for progress reporters (see
[`make_mcmc_reporter`](@ref)).

`meta` arguments are key-value pairs.

In this context, a *step* is a NUTS transition, not a leapfrog step.
"""
report(reporter::NoProgressReport, step::Union{AbstractString,Integer}; meta...) = nothing

"""
$(SIGNATURES)

Return a reporter which can be used for progress reports with a known number of
`total_steps`. May return the same reporter, or a related object. Will display `meta` as
key-value pairs.

## Arguments:
- `reporter::NoProgressReport`: the original reporter
- `total_steps`: total number of steps

## Keyword arguments:
- `currently_warmup::Bool`: `true` if we are currently doing warmup; `false` if we are currently doing MCMC
- `meta`: key-value pairs that will be displayed by the reporter
"""
make_mcmc_reporter(reporter::NoProgressReport, total_steps; currently_warmup::Bool = false, meta...) = reporter

"""
$(TYPEDEF)

Report progress into the `Logging` framework, using `@info`.

For the information reported, a *step* is a NUTS transition, not a leapfrog step.

# Fields

$(FIELDS)
"""
@with_kw struct LogProgressReport{T}
    "ID of chain. Can be an arbitrary object, eg `nothing`."
    chain_id::T = nothing
    "Always report progress past `step_interval` of the last report."
    step_interval::Int = 100
    "Always report progress past this much time (in seconds) after the last report."
    time_interval_s::Float64 = 1000.0
end

"""
$(SIGNATURES)

Assemble log message metadata.

Currently, it adds `chain_id` *iff* it is not `nothing`.
"""
_log_meta(chain_id::Nothing, meta) = meta

_log_meta(chain_id, meta) = (chain_id = chain_id, meta...)

function report(reporter::LogProgressReport, message::AbstractString; meta...)
    @info message _log_meta(reporter.chain_id, meta)...
    nothing
end

"""
$(TYPEDEF)

A composite type for tracking the state for which the last log message was emitted, for MCMC
reporting with a given total number of steps (see [`make_mcmc_reporter`](@ref).

# Fields

$(FIELDS)
"""
mutable struct LogMCMCReport{T}
    "The progress report sink."
    log_progress_report::T
    "Total steps for this stage."
    total_steps::Int
    "Index of the last reported step."
    last_reported_step::Int
    "The last time a report was logged (determined using `time_ns`)."
    last_reported_time_ns::UInt64
end

function report(reporter::LogMCMCReport, message::AbstractString; meta...)
    @info message _log_meta(reporter.log_progress_report.chain_id, meta)...
    nothing
end

function make_mcmc_reporter(reporter::LogProgressReport, total_steps::Integer; currently_warmup::Bool = false, meta...)
    @info "Starting MCMC" total_steps = total_steps meta...
    LogMCMCReport(reporter, total_steps, -1, time_ns())
end

function report(reporter::LogMCMCReport, step::Integer; meta...)
    @unpack (log_progress_report, total_steps, last_reported_step,
             last_reported_time_ns) = reporter
    @unpack chain_id, step_interval, time_interval_s = log_progress_report
    @argcheck 1 ≤ step ≤ total_steps
    Δ_steps = step - last_reported_step
    t_ns = time_ns()
    Δ_time_s = (t_ns - last_reported_time_ns) / 1_000_000_000
    if last_reported_step < 0 || Δ_steps ≥ step_interval || Δ_time_s ≥ time_interval_s
        seconds_per_step = Δ_time_s / Δ_steps
        meta_progress = (step = step,
                         seconds_per_step = round(seconds_per_step; sigdigits = 2),
                         estimated_seconds_left = round((total_steps - step) *
                                                        seconds_per_step; sigdigits = 2))
        @info "MCMC progress" merge(_log_meta(chain_id, meta_progress), meta)...
        reporter.last_reported_step = step
        reporter.last_reported_time_ns = t_ns
    end
    nothing
end

"""
$(TYPEDEF)

Report progress via a progress bar, using `ProgressMeter.jl`.

Example usage:
```julia
julia> ProgressMeterReport()
```
"""
struct ProgressMeterReport
end

struct ProgressMeterReportMCMC{T}
    currently_warmup::Bool
    progress_meter::T
end

function make_mcmc_reporter(reporter::ProgressMeterReport, total_steps::Integer; currently_warmup::Bool=false, meta...)
    description = currently_warmup ? "Warmup: " : "MCMC: "
    return ProgressMeterReportMCMC(currently_warmup, ProgressMeter.Progress(total_steps, 1, description))
end

function report(reporter::ProgressMeterReport, message::AbstractString; meta...)
    return nothing
end

function report(reporter::ProgressMeterReportMCMC, message::AbstractString; meta...)
    return nothing
end

function report(reporter::ProgressMeterReport, step::Integer; meta...)
    return nothing
end

function report(reporter::ProgressMeterReportMCMC, step::Integer; meta...)
    ProgressMeter.next!(reporter.progress_meter)
    return nothing
end

"""
$(SIGNATURES)

Return a default reporter, taking the environment into account. Keyword arguments are passed
to constructors when applicable.
"""
function default_reporter(; kwargs...)
    if isinteractive()
        LogProgressReport(; kwargs...)
    else
        NoProgressReport()
    end
end


text:
# TODO: implement save

function _dot_read_one_graph(pg::DOT.Graph)
    isdir = pg.directed
    nvg = length(DOT.nodes(pg))
    nodedict = Dict(zip(collect(DOT.nodes(pg)), 1:nvg))
    if isdir
        g = DiGraph(nvg)
    else
        g = Graph(nvg)
    end
    for es in DOT.edges(pg)
        s = nodedict[es[1]]
        d = nodedict[es[2]]
        add_edge!(g, s, d)
    end
    return g
end

function loaddot(io::IO, gname::AbstractString)
    p = DOT.parse_dot(readall(io))
    for pg in p
        isdir = pg.directed
        possname = isdir? DOT.StringID("digraph") : DOT.StringID("graph")
        name = get(pg.id, possname).id
        name == gname && return _dot_read_one_graph(pg)
    end
    error("Graph $gname not found")
end

function loaddot_mult(io::IO)
    p = DOT.parse_dot(readall(io))

    graphs = Dict{AbstractString, SimpleGraph}()

    for pg in p
        isdir = pg.directed
        possname = isdir? DOT.StringID("digraph") : DOT.StringID("graph")
        name = get(pg.id, possname).id
        graphs[name] = _dot_read_one_graph(pg)
    end
    return graphs
end

filemap[:dot] = (loaddot, loaddot_mult, NI, NI)


text:
module OpenStreetMapX

using LibExpat
using Graphs
using SparseArrays
using DataStructures
using Serialization
using Statistics
using JSON
using HTTP
using StableRNGs
using Random

import Base.isapprox

export WGS84, OSGB36, NAD27 # Coordinate systems constants
export distance, getX, getY, getZ  # Auxiliary functions to calculate distances and get coordinates of points
export center, inbounds, onbounds, boundary_point #Functions for map bounds
export ECEF, LLA, ENU #Conversion functions
export MapData
export get_distance, a_star_algorithm #A* search algorithm implementation

export extract_highways, filter_highways #Highways extraction
export filter_roadways, classify_roadways,  filter_walkways, classify_walkways, filter_cycleways, classify_cycleways #Filtering and classification of cars, cycles and pedestrian Highways
export extract_buildings, filter_buildings, classify_buildings #Building extraction, filtering and classification
export filter_features, filter_features!, classify_features, filter_graph_features #Features filtering and classification
export crop! #crop map elements
export nearest_node, nodes_within_range, centroid #Nodes functions
export find_intersections, find_segments #Get intersections or segments of the road
export features_to_graph, find_optimal_waypoint_approx, find_optimal_waypoint_exact
export find_route, shortest_route, fastest_route #Routing funcions
export nodes_within_weights, nodes_within_driving_distance, nodes_within_driving_time #Find nodes within specified range
export get_map_data
export get_google_route
export encode, decode
export generate_point_in_bounds, point_to_nodes

export latlon

export ROAD_CLASSES, CYCLE_CLASSES, PED_CLASSES, SPEED_ROADS_URBAN, SPEED_ROADS_RURAL

include("types.jl") #types used in the package
include("classes.jl") #grouping highways into classes for routing and plotting
include("speeds.jl") # speed limits in kilometers per hour
include("polyline.jl") # Goole Polyline Algorithm Format encoder/decoder
include("a_star.jl")
include("points.jl") # points coordinates and constants
include("bounds.jl") #bounds of the map
include("conversion.jl") #conversion of geographical coordinates

include("parseMap.jl") #map parsing funcions
include("pbf.jl")
include("classification.jl") #highways, features and buildings classification functions
include("crop.jl") #cropping nodes and ways

include("google_routing.jl")

include("nodes.jl") #finding nearest nodes or nodes within some range
include("intersections.jl") #finding intersections
include("routing.jl") #routing functions

end


text:
module Dep442A

export check442A

check442A() = true

end # module


text:
function ALclear(; verbose = true)
    ((length(replset.commands)==0) || (replset.commands[end]=="#Session Started")) &&
      ((verbose && println("Activeset Already Empty")); return)

    newhistory = History()
    newreplset = activelogicset(newhistory)

    setactivehistory!(newhistory)
    setreplset!(newreplset)
    pushsessionhistory!(newreplset)
    verbose && println("Clearing Activeset")

end

function ALClear(; verbose = true)
    ALclear(verbose = false)
    setsessionhistory!(History())

    verbose && println("Clearing Everything!")
end


text:
function viewshape(img::Image, shape::Shape)
    imgc, img2 = ImageView.view(img)
    for i=1:size(shape, 1)
        annotate!(imgc, img2, AnnotationPoint(shape[i, 2], shape[i, 1], shape='.',
                                              size=4, color=RGB(1, 0, 0)))
    end
    imgc, img2
end
viewshape{N}(mat::Array{Float64, N}, shape::Shape) = viewshape(convert(Image, mat), shape)


text:
module SimpleDraw

include("abstract_shape.jl")
include("point.jl")
include("background.jl")
include("line.jl")
include("symmetry.jl")
include("circle.jl")
include("rectangle.jl")
include("bitmap.jl")
include("character.jl")
include("text.jl")
include("visualize.jl")

end