text:
using Poly
using StaticArrays
using LinearAlgebra
using BenchmarkTools
using SIMD
using Base.Threads

num_threads = Base.Threads.nthreads()
LinearAlgebra.BLAS.set_num_threads(num_threads)
thread = false
if num_threads != 1
    thread = true
end

function mul_naive(A::Array{T,2}, B::Array{T,2}, C::Array{T,2}) where {T}
    N = size(C, 1)
    M = size(C, 2)
    R = size(A, 2)

    for i = 1:N
        for j = 1:M
            for k = 1:R
                C[i, j] += A[i, k] * B[k, j]
            end
        end
    end
end

function mul_simple(A::Array{T,2}, B::Array{T,2}, C::Array{T,2}) where {T}
    N = size(C, 1)
    M = size(C, 2)
    R = size(A, 2)

    @inbounds for j = 1:M
        for k = 1:R
            for i = 1:N
                C[i, j] += A[i, k] * B[k, j]
            end
        end
    end
end

function mul_optimized(A::Array{T,2}, B::Array{T,2}, C::Array{T,2}) where {T}
    N = size(C, 1)
    M = size(C, 2)
    R = size(A, 2)
    TILE_DIM = 64

    @simd for gj = 0:TILE_DIM:M-1
        @simd for t = 0:TILE_DIM:R-1
            @simd for gi = 0:TILE_DIM:N-1
            tile1 = @MArray zeros(TILE_DIM, TILE_DIM)
            tile2 = @MArray zeros(TILE_DIM, TILE_DIM)
                @simd for j = 1:TILE_DIM
                    @simd for i = 1:TILE_DIM
                        @inbounds tile1[i, j] = A[gi + i, t + j]
                        @inbounds tile2[i, j] = B[t + i, gj + j]
                    end
                end
                @simd for j = 1:TILE_DIM
                    @simd for k = 1:TILE_DIM
                        @simd for i = 1:TILE_DIM
                            @inbounds C[gi + i, gj + j] += tile1[i, k] * tile2[k, j]
                        end
                    end
                end
            end
        end
    end
end

function mul_optimized_v2(A::Array{T,2}, B::Array{T,2}, C::Array{T,2}) where {T}
    N = size(C, 1)
    M = size(C, 2)
    R = size(A, 2)
    TILE_DIM = 64

    @simd for gj = 0:TILE_DIM:M-1
        @simd for t = 0:TILE_DIM:R-1
            @simd for gi = 0:TILE_DIM:N-1
                @simd for j = 1:TILE_DIM
                    @simd for k = 1:TILE_DIM
                        @simd for i = 1:TILE_DIM
                            @inbounds C[gi + i, gj + j] += A[gi + i, t + k] * B[t + k, gj + j]
                        end
                    end
                end
            end
        end
    end
end

function mul_optimized_thread(A::Array{T,2}, B::Array{T,2}, C::Array{T,2}) where {T}
    N = size(C, 1)
    M = size(C, 2)
    R = size(A, 2)
    TILE_DIM = 64

    @threads for gj = 0:TILE_DIM:M-1
        @simd for t = 0:TILE_DIM:R-1
            @simd for gi = 0:TILE_DIM:N-1
                @simd for j = 1:TILE_DIM
                    @simd for k = 1:TILE_DIM
                        @simd for i = 1:TILE_DIM
                            @inbounds C[gi + i, gj + j] += A[gi + i, t + k] * B[t + k, gj + j]
                        end
                    end
                end
            end
        end
    end
end

function mul_poly(A::Array{T,2}, B::Array{T,2}, C::Array{T,2}) where {T}
    N = size(C, 1)
    M = size(C, 2)
    R = size(A, 2)

    @poly_loop for i = 1:N
        for j = 1:M
            for k = 1:R
                C[i, j] += A[i, k] * B[k, j]
            end
        end
    end
end

function mul_poly_rt(A::Array{T,2}, B::Array{T,2}, C::Array{T,2}) where {T}
    N = size(C, 1)
    M = size(C, 2)
    R = size(A, 2)

    @poly_loop for i = 1:$N
        for j = 1:$M
            for k = 1:$R
                C[i, j] += A[i, k] * B[k, j]
            end
        end
    end
end

function mul_poly_thread(A::Array{T,2}, B::Array{T,2}, C::Array{T,2}) where {T}
    N = size(C, 1)
    M = size(C, 2)
    R = size(A, 2)

    @poly_loop thread=true for i = 1:N
        for j = 1:M
            for k = 1:R
                C[i, j] += A[i, k] * B[k, j]
            end
        end
    end
end

n = 1024
r = 512
m = 1024
A = rand(n, r)
B = rand(r, m)
out = zeros(n, m)

basic = @benchmark mul_naive($A, $B, out) setup=(out=zeros($n, $m))
simple = @benchmark mul_simple($A, $B, out) setup=(out=zeros($n, $m))
optimized = @benchmark mul_optimized($A, $B, out) setup=(out=zeros($n, $m))
if thread
    optimized2 = @benchmark mul_optimized_thread($A, $B, out) setup=(out=zeros($n, $m))
    poly = @benchmark mul_poly_thread($A, $B, out) setup=(out=zeros($n, $m))
    polyrt = nothing
else
    optimized2 = @benchmark mul_optimized_v2($A, $B, out) setup=(out=zeros($n, $m))
    poly = @benchmark mul_poly($A, $B, out) setup=(out=zeros($n, $m))
    polyrt = @benchmark mul_poly_rt($A, $B, out) setup=(out=zeros($n, $m))
end
expert = @benchmark LinearAlgebra.mul!(out, $A, $B) setup=(out=zeros($n, $m))

@show allocs(basic)
@show allocs(simple)
@show allocs(optimized)
@show allocs(optimized2)
@show allocs(expert)
@show allocs(poly)
if !thread
    @show allocs(polyrt)
end
@show minimum(basic)
@show minimum(simple)
@show minimum(optimized)
@show minimum(optimized2)
@show minimum(expert)
@show minimum(poly)
if !thread
    @show minimum(polyrt)
end

rbasic = ratio(minimum(basic), minimum(poly))
rsimple = ratio(minimum(simple), minimum(poly))
roptimized = ratio(minimum(optimized), minimum(poly))
roptimized2 = ratio(minimum(optimized2), minimum(poly))
rexpert = ratio(minimum(expert), minimum(poly))

if !thread
    rbasicrt = ratio(minimum(basic), minimum(polyrt))
    rsimplert = ratio(minimum(simple), minimum(polyrt))
    roptimizedrt = ratio(minimum(optimized), minimum(polyrt))
    roptimized2rt = ratio(minimum(optimized2), minimum(polyrt))
    rexpertrt = ratio(minimum(expert), minimum(polyrt))
end

@show rbasic
@show rsimple
@show roptimized
@show roptimized2
@show rexpert

if !thread
    @show rbasicrt
    @show rsimplert
    @show roptimizedrt
    @show roptimized2rt
    @show rexpertrt
end

jbasic = judge(minimum(poly), minimum(basic))
jsimple = judge(minimum(poly), minimum(simple))
joptimized = judge(minimum(poly), minimum(optimized))
joptimized2 = judge(minimum(poly), minimum(optimized2))
jexpert = judge(minimum(poly), minimum(expert))

if !thread
    jbasicrt = judge(minimum(polyrt), minimum(basic))
    jsimplert = judge(minimum(polyrt), minimum(simple))
    joptimizedrt = judge(minimum(polyrt), minimum(optimized))
    joptimized2rt = judge(minimum(polyrt), minimum(optimized2))
    jexpertrt = judge(minimum(polyrt), minimum(expert))
end

@show jbasic
@show jsimple
@show joptimized
@show joptimized2
@show jexpert

if !thread
    @show jbasicrt
    @show jsimplert
    @show joptimizedrt
    @show joptimized2rt
    @show jexpertrt
end


text:
# This was run in Julia 1.5.0

using GeneticVariation, VCFTools, OrdinalMultinomialModels, Random, DataFrames, CSV

vcffile = "vcf_test.vcf.gz"
D = convert_ds(Float64, vcffile; key="DS", impute=true, center=false, scale=false)

#find two SNPs that are fairly independent to simulate the trait from
using Statistics
toplist = sortperm(vec(var(D, dims=[1])), rev=true)[1:30]
lastcor = 1
for i in toplist, j in toplist
    curcor = abs(Statistics.cor(D[:, i], D[:, j]))
    if curcor < lastcor
        lastcor = curcor
        println("$i and $j cor is $curcor")
    end
end

#returns 86 and 656 as uncorrelated markers that still have high variance

people, snps = nsamples(vcffile), nrecords(vcffile)
Random.seed!(310)
sex = rand(0:1, people)
X = [sex D[:, 86] D[:, 656]]
θ = [-1.5; 0; 1.5]
β = [0.5; 0.5; -0.5]
y = rpolr(X, β, θ, LogitLink())

df = DataFrame(y = y, sex = sex)
CSV.write("vcf_example.csv", df)

#ordinalgwas(@formula(y ~ sex), "vcf_example.csv", "test"; geneticformat = "VCF", vcftype=:DS)
#ordinalgwas(@formula(y ~ sex), "vcf_example.csv", "test"; geneticformat = "VCF", vcftype=:DS, snpinds = [86; 656], test=:LRT)

ext: jl

max_stars_repo_name: Hua-Zhou/PolrGWAS

max_issues_repo_name: Hua-Zhou/PolrGWAS


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

"""
    add_draft_app_version_resource_mappings(app_arn, resource_mappings)
    add_draft_app_version_resource_mappings(app_arn, resource_mappings, params::Dict{String,<:Any})

Adds the resource mapping for the draft application version.

# Arguments
- `app_arn`: The Amazon Resource Name (ARN) of the application. The format for this ARN is:
  arn:partition:dcps:region:account:app/app-id. For more information about ARNs, see  Amazon
  Resource Names (ARNs) in the AWS General Reference.
- `resource_mappings`:  Mappings used to map logical resources from the template to
  physical resources. You can use the mapping type CFN_STACK if the application template uses
  a logical stack name. Or you can map individual resources by using the mapping type
  RESOURCE. We recommend using the mapping type CFN_STACK if the application is backed by a
  CloudFormation stack.

"""
function add_draft_app_version_resource_mappings(
    appArn, resourceMappings; aws_config::AbstractAWSConfig=global_aws_config()
)
    return resiliencehub(
        "POST",
        "/add-draft-app-version-resource-mappings",
        Dict{String,Any}("appArn" => appArn, "resourceMappings" => resourceMappings);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function add_draft_app_version_resource_mappings(
    appArn,
    resourceMappings,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return resiliencehub(
        "POST",
        "/add-draft-app-version-resource-mappings",
        Dict{String,Any}(
            mergewith(
                _merge,
                Dict{String,Any}(
                    "appArn" => appArn, "resourceMappings" => resourceMappings
                ),
                params,
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

Creates a Resilience Hub application. A Resilience Hub application is a collection of
Amazon Web Services resources structured to prevent and recover Amazon Web Services
application disruptions. To describe a Resilience Hub application, you provide an
application name, resources from one or more–up to five–CloudFormation stacks, and an
appropriate resiliency policy.
After you create a Resilience Hub application, you
publish it so that you can run a resiliency assessment on it. You can then use
recommendations from the assessment to improve resiliency by running another assessment,
comparing results, and then iterating the process until you achieve your goals for recovery
time objective (RTO) and recovery point objective (RPO).

# Arguments
- `name`: The name for the application.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"clientToken"`: Used for an idempotency token. A client token is a unique,
  case-sensitive string of up to 64 ASCII characters. You should not reuse the same client
  token for other API requests.
- `"description"`: The optional description for an app.
- `"policyArn"`: The Amazon Resource Name (ARN) of the resiliency policy. The format for
  this ARN is: arn:partition:dcps:region:account:resiliency-policy/policy-id. For more
  information about ARNs, see  Amazon Resource Names (ARNs) in the AWS General Reference.
- `"tags"`: The tags assigned to the resource. A tag is a label that you assign to an
  Amazon Web Services resource. Each tag consists of a key/value pair.
"""
function create_app(name; aws_config::AbstractAWSConfig=global_aws_config())
    return resiliencehub(
        "POST",
        "/create-app",
        Dict{String,Any}("name" => name, "clientToken" => string(uuid4()));
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function create_app(
    name, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()
)
    return resiliencehub(
        "POST",
        "/create-app",
        Dict{String,Any}(
            mergewith(
                _merge,
                Dict{String,Any}("name" => name, "clientToken" => string(uuid4())),
                params,
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    create_recommendation_template(assessment_arn, name)
    create_recommendation_template(assessment_arn, name, params::Dict{String,<:Any})

Creates a new recommendation template.

# Arguments
- `assessment_arn`: The Amazon Resource Name (ARN) of the assessment. The format for this
  ARN is: arn:partition:dcps:region:account:app-assessment/app-id. For more information about
  ARNs, see  Amazon Resource Names (ARNs) in the AWS General Reference.
- `name`: The name for the recommendation template.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"bucketName"`: The name of the Amazon S3 bucket that will contain the recommendation
  template.
- `"clientToken"`: Used for an idempotency token. A client token is a unique,
  case-sensitive string of up to 64 ASCII characters. You should not reuse the same client
  token for other API requests.
- `"format"`: The format for the recommendation template.  CfnJson  The template is
  CloudFormation JSON.  CfnYaml  The template is CloudFormation YAML.
- `"recommendationIds"`: Identifiers for the recommendations used to create a
  recommendation template.
- `"recommendationTypes"`: An array of strings that specify the recommendation template
  type or types.  Alarm  The template is an AlarmRecommendation template.  Sop  The template
  is a SopRecommendation template.  Test  The template is a TestRecommendation template.
- `"tags"`: The tags assigned to the resource. A tag is a label that you assign to an
  Amazon Web Services resource. Each tag consists of a key/value pair.
"""
function create_recommendation_template(
    assessmentArn, name; aws_config::AbstractAWSConfig=global_aws_config()
)
    return resiliencehub(
        "POST",
        "/create-recommendation-template",
        Dict{String,Any}(
            "assessmentArn" => assessmentArn,
            "name" => name,
            "clientToken" => string(uuid4()),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function create_recommendation_template(
    assessmentArn,
    name,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return resiliencehub(
        "POST",
        "/create-recommendation-template",
        Dict{String,Any}(
            mergewith(
                _merge,
                Dict{String,Any}(
                    "assessmentArn" => assessmentArn,
                    "name" => name,
                    "clientToken" => string(uuid4()),
                ),
                params,
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    create_resiliency_policy(policy, policy_name, tier)
    create_resiliency_policy(policy, policy_name, tier, params::Dict{String,<:Any})

Creates a resiliency policy for an application.

# Arguments
- `policy`: The type of resiliency policy to be created, including the recovery time
  objective (RTO) and recovery point objective (RPO) in seconds.
- `policy_name`: The name of the policy
- `tier`: The tier for this resiliency policy, ranging from the highest severity
  (MissionCritical) to lowest (NonCritical).

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"clientToken"`: Used for an idempotency token. A client token is a unique,
  case-sensitive string of up to 64 ASCII characters. You should not reuse the same client
  token for other API requests.
- `"dataLocationConstraint"`: Specifies a high-level geographical location constraint for
  where your resilience policy data can be stored.
- `"policyDescription"`: The description for the policy.
- `"tags"`: The tags assigned to the resource. A tag is a label that you assign to an
  Amazon Web Services resource. Each tag consists of a key/value pair.
"""
function create_resiliency_policy(
    policy, policyName, tier; aws_config::AbstractAWSConfig=global_aws_config()
)
    return resiliencehub(
        "POST",
        "/create-resiliency-policy",
        Dict{String,Any}(
            "policy" => policy,
            "policyName" => policyName,
            "tier" => tier,
            "clientToken" => string(uuid4()),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function create_resiliency_policy(
    policy,
    policyName,
    tier,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return resiliencehub(
        "POST",
        "/create-resiliency-policy",
        Dict{String,Any}(
            mergewith(
                _merge,
                Dict{String,Any}(
                    "policy" => policy,
                    "policyName" => policyName,
                    "tier" => tier,
                    "clientToken" => string(uuid4()),
                ),
                params,
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

Deletes an AWS Resilience Hub application. This is a destructive action that can't be
undone.

# Arguments
- `app_arn`: The Amazon Resource Name (ARN) of the application. The format for this ARN is:
  arn:partition:dcps:region:account:app/app-id. For more information about ARNs, see  Amazon
  Resource Names (ARNs) in the AWS General Reference.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"clientToken"`: Used for an idempotency token. A client token is a unique,
  case-sensitive string of up to 64 ASCII characters. You should not reuse the same client
  token for other API requests.
- `"forceDelete"`: A boolean option to force the deletion of a Resilience Hub application.
"""
function delete_app(appArn; aws_config::AbstractAWSConfig=global_aws_config())
    return resiliencehub(
        "POST",
        "/delete-app",
        Dict{String,Any}("appArn" => appArn, "clientToken" => string(uuid4()));
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function delete_app(
    appArn, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()
)
    return resiliencehub(
        "POST",
        "/delete-app",
        Dict{String,Any}(
            mergewith(
                _merge,
                Dict{String,Any}("appArn" => appArn, "clientToken" => string(uuid4())),
                params,
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

Deletes an AWS Resilience Hub application assessment. This is a destructive action that
can't be undone.

# Arguments
- `assessment_arn`: The Amazon Resource Name (ARN) of the assessment. The format for this
  ARN is: arn:partition:dcps:region:account:app-assessment/app-id. For more information about
  ARNs, see  Amazon Resource Names (ARNs) in the AWS General Reference.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"clientToken"`: Used for an idempotency token. A client token is a unique,
  case-sensitive string of up to 64 ASCII characters. You should not reuse the same client
  token for other API requests.
"""
function delete_app_assessment(
    assessmentArn; aws_config::AbstractAWSConfig=global_aws_config()
)
    return resiliencehub(
        "POST",
        "/delete-app-assessment",
        Dict{String,Any}(
            "assessmentArn" => assessmentArn, "clientToken" => string(uuid4())
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function delete_app_assessment(
    assessmentArn,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return resiliencehub(
        "POST",
        "/delete-app-assessment",
        Dict{String,Any}(
            mergewith(
                _merge,
                Dict{String,Any}(
                    "assessmentArn" => assessmentArn, "clientToken" => string(uuid4())
                ),
                params,
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

Deletes a recommendation template. This is a destructive action that can't be undone.

# Arguments
- `recommendation_template_arn`: The Amazon Resource Name (ARN) for a recommendation
  template.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"clientToken"`: Used for an idempotency token. A client token is a unique,
  case-sensitive string of up to 64 ASCII characters. You should not reuse the same client
  token for other API requests.
"""
function delete_recommendation_template(
    recommendationTemplateArn; aws_config::AbstractAWSConfig=global_aws_config()
)
    return resiliencehub(
        "POST",
        "/delete-recommendation-template",
        Dict{String,Any}(
            "recommendationTemplateArn" => recommendationTemplateArn,
            "clientToken" => string(uuid4()),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function delete_recommendation_template(
    recommendationTemplateArn,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return resiliencehub(
        "POST",
        "/delete-recommendation-template",
        Dict{String,Any}(
            mergewith(
                _merge,
                Dict{String,Any}(
                    "recommendationTemplateArn" => recommendationTemplateArn,
                    "clientToken" => string(uuid4()),
                ),
                params,
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

Deletes a resiliency policy. This is a destructive action that can't be undone.

# Arguments
- `policy_arn`: The Amazon Resource Name (ARN) of the resiliency policy. The format for
  this ARN is: arn:partition:dcps:region:account:resiliency-policy/policy-id. For more
  information about ARNs, see  Amazon Resource Names (ARNs) in the AWS General Reference.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"clientToken"`: Used for an idempotency token. A client token is a unique,
  case-sensitive string of up to 64 ASCII characters. You should not reuse the same client
  token for other API requests.
"""
function delete_resiliency_policy(
    policyArn; aws_config::AbstractAWSConfig=global_aws_config()
)
    return resiliencehub(
        "POST",
        "/delete-resiliency-policy",
        Dict{String,Any}("policyArn" => policyArn, "clientToken" => string(uuid4()));
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function delete_resiliency_policy(
    policyArn,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return resiliencehub(
        "POST",
        "/delete-resiliency-policy",
        Dict{String,Any}(
            mergewith(
                _merge,
                Dict{String,Any}(
                    "policyArn" => policyArn, "clientToken" => string(uuid4())
                ),
                params,
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

Describes an AWS Resilience Hub application.

# Arguments
- `app_arn`: The Amazon Resource Name (ARN) of the application. The format for this ARN is:
  arn:partition:dcps:region:account:app/app-id. For more information about ARNs, see  Amazon
  Resource Names (ARNs) in the AWS General Reference.

"""
function describe_app(appArn; aws_config::AbstractAWSConfig=global_aws_config())
    return resiliencehub(
        "POST",
        "/describe-app",
        Dict{String,Any}("appArn" => appArn);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function describe_app(
    appArn, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()
)
    return resiliencehub(
        "POST",
        "/describe-app",
        Dict{String,Any}(mergewith(_merge, Dict{String,Any}("appArn" => appArn), params));
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

Describes an assessment for an AWS Resilience Hub application.

# Arguments
- `assessment_arn`: The Amazon Resource Name (ARN) of the assessment. The format for this
  ARN is: arn:partition:dcps:region:account:app-assessment/app-id. For more information about
  ARNs, see  Amazon Resource Names (ARNs) in the AWS General Reference.

"""
function describe_app_assessment(
    assessmentArn; aws_config::AbstractAWSConfig=global_aws_config()
)
    return resiliencehub(
        "POST",
        "/describe-app-assessment",
        Dict{String,Any}("assessmentArn" => assessmentArn);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function describe_app_assessment(
    assessmentArn,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return resiliencehub(
        "POST",
        "/describe-app-assessment",
        Dict{String,Any}(
            mergewith(_merge, Dict{String,Any}("assessmentArn" => assessmentArn), params)
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    describe_app_version_resources_resolution_status(app_arn, app_version)
    describe_app_version_resources_resolution_status(app_arn, app_version, params::Dict{String,<:Any})

Returns the resolution status for the specified resolution identifier for an application
version. If resolutionId is not specified, the current resolution status is returned.

# Arguments
- `app_arn`: The Amazon Resource Name (ARN) of the application. The format for this ARN is:
  arn:partition:dcps:region:account:app/app-id. For more information about ARNs, see  Amazon
  Resource Names (ARNs) in the AWS General Reference.
- `app_version`: The version of the application.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"resolutionId"`: The identifier for a specific resolution.
"""
function describe_app_version_resources_resolution_status(
    appArn, appVersion; aws_config::AbstractAWSConfig=global_aws_config()
)
    return resiliencehub(
        "POST",
        "/describe-app-version-resources-resolution-status",
        Dict{String,Any}("appArn" => appArn, "appVersion" => appVersion);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function describe_app_version_resources_resolution_status(
    appArn,
    appVersion,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return resiliencehub(
        "POST",
        "/describe-app-version-resources-resolution-status",
        Dict{String,Any}(
            mergewith(
                _merge,
                Dict{String,Any}("appArn" => appArn, "appVersion" => appVersion),
                params,
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    describe_app_version_template(app_arn, app_version)
    describe_app_version_template(app_arn, app_version, params::Dict{String,<:Any})

Describes details about an AWS Resilience Hub

# Arguments
- `app_arn`: The Amazon Resource Name (ARN) of the application. The format for this ARN is:
  arn:partition:dcps:region:account:app/app-id. For more information about ARNs, see  Amazon
  Resource Names (ARNs) in the AWS General Reference.
- `app_version`: The version of the application.

"""
function describe_app_version_template(
    appArn, appVersion; aws_config::AbstractAWSConfig=global_aws_config()
)
    return resiliencehub(
        "POST",
        "/describe-app-version-template",
        Dict{String,Any}("appArn" => appArn, "appVersion" => appVersion);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function describe_app_version_template(
    appArn,
    appVersion,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return resiliencehub(
        "POST",
        "/describe-app-version-template",
        Dict{String,Any}(
            mergewith(
                _merge,
                Dict{String,Any}("appArn" => appArn, "appVersion" => appVersion),
                params,
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

Describes the status of importing resources to an application version.

# Arguments
- `app_arn`: The Amazon Resource Name (ARN) of the application. The format for this ARN is:
  arn:partition:dcps:region:account:app/app-id. For more information about ARNs, see  Amazon
  Resource Names (ARNs) in the AWS General Reference.

"""
function describe_draft_app_version_resources_import_status(
    appArn; aws_config::AbstractAWSConfig=global_aws_config()
)
    return resiliencehub(
        "POST",
        "/describe-draft-app-version-resources-import-status",
        Dict{String,Any}("appArn" => appArn);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function describe_draft_app_version_resources_import_status(
    appArn, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()
)
    return resiliencehub(
        "POST",
        "/describe-draft-app-version-resources-import-status",
        Dict{String,Any}(mergewith(_merge, Dict{String,Any}("appArn" => appArn), params));
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

Describes a specified resiliency policy for an AWS Resilience Hub application. The returned
policy object includes creation time, data location constraints, the Amazon Resource Name
(ARN) for the policy, tags, tier, and more.

# Arguments
- `policy_arn`: The Amazon Resource Name (ARN) of the resiliency policy. The format for
  this ARN is: arn:partition:dcps:region:account:resiliency-policy/policy-id. For more
  information about ARNs, see  Amazon Resource Names (ARNs) in the AWS General Reference.

"""
function describe_resiliency_policy(
    policyArn; aws_config::AbstractAWSConfig=global_aws_config()
)
    return resiliencehub(
        "POST",
        "/describe-resiliency-policy",
        Dict{String,Any}("policyArn" => policyArn);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function describe_resiliency_policy(
    policyArn,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return resiliencehub(
        "POST",
        "/describe-resiliency-policy",
        Dict{String,Any}(
            mergewith(_merge, Dict{String,Any}("policyArn" => policyArn), params)
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    import_resources_to_draft_app_version(app_arn, source_arns)
    import_resources_to_draft_app_version(app_arn, source_arns, params::Dict{String,<:Any})

Imports resources from sources such as a CloudFormation stack, resource-groups, or
application registry app to a draft application version.

# Arguments
- `app_arn`: The Amazon Resource Name (ARN) of the application. The format for this ARN is:
  arn:partition:dcps:region:account:app/app-id. For more information about ARNs, see  Amazon
  Resource Names (ARNs) in the AWS General Reference.
- `source_arns`: The Amazon Resource Names (ARNs) for the resources that you want to import.

"""
function import_resources_to_draft_app_version(
    appArn, sourceArns; aws_config::AbstractAWSConfig=global_aws_config()
)
    return resiliencehub(
        "POST",
        "/import-resources-to-draft-app-version",
        Dict{String,Any}("appArn" => appArn, "sourceArns" => sourceArns);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function import_resources_to_draft_app_version(
    appArn,
    sourceArns,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return resiliencehub(
        "POST",
        "/import-resources-to-draft-app-version",
        Dict{String,Any}(
            mergewith(
                _merge,
                Dict{String,Any}("appArn" => appArn, "sourceArns" => sourceArns),
                params,
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

Lists the alarm recommendations for a AWS Resilience Hub application.

# Arguments
- `assessment_arn`: The Amazon Resource Name (ARN) of the assessment. The format for this
  ARN is: arn:partition:dcps:region:account:app-assessment/app-id. For more information about
  ARNs, see  Amazon Resource Names (ARNs) in the AWS General Reference.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"maxResults"`: The maximum number of results to include in the response. If more results
  exist than the specified MaxResults value, a token is included in the response so that the
  remaining results can be retrieved.
- `"nextToken"`: Null, or the token from a previous call to get the next set of results.
"""
function list_alarm_recommendations(
    assessmentArn; aws_config::AbstractAWSConfig=global_aws_config()
)
    return resiliencehub(
        "POST",
        "/list-alarm-recommendations",
        Dict{String,Any}("assessmentArn" => assessmentArn);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function list_alarm_recommendations(
    assessmentArn,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return resiliencehub(
        "POST",
        "/list-alarm-recommendations",
        Dict{String,Any}(
            mergewith(_merge, Dict{String,Any}("assessmentArn" => assessmentArn), params)
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

Lists the assessments for an AWS Resilience Hub application. You can use request parameters
to refine the results for the response object.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"appArn"`: The Amazon Resource Name (ARN) of the application. The format for this ARN
  is: arn:partition:dcps:region:account:app/app-id. For more information about ARNs, see
  Amazon Resource Names (ARNs) in the AWS General Reference.
- `"assessmentName"`: The name for the assessment.
- `"assessmentStatus"`: The current status of the assessment for the resiliency policy.
- `"complianceStatus"`: The current status of compliance for the resiliency policy.
- `"invoker"`: Specifies the entity that invoked a specific assessment, either a User or
  the System.
- `"maxResults"`: The maximum number of results to include in the response. If more results
  exist than the specified MaxResults value, a token is included in the response so that the
  remaining results can be retrieved.
- `"nextToken"`: Null, or the token from a previous call to get the next set of results.
- `"reverseOrder"`: The default is to sort by ascending startTime. To sort by descending
  startTime, set reverseOrder to true.
"""
function list_app_assessments(; aws_config::AbstractAWSConfig=global_aws_config())
    return resiliencehub(
        "GET",
        "/list-app-assessments";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function list_app_assessments(
    params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()
)
    return resiliencehub(
        "GET",
        "/list-app-assessments",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

Lists the compliances for an AWS Resilience Hub component.

# Arguments
- `assessment_arn`: The Amazon Resource Name (ARN) of the assessment. The format for this
  ARN is: arn:partition:dcps:region:account:app-assessment/app-id. For more information about
  ARNs, see  Amazon Resource Names (ARNs) in the AWS General Reference.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"maxResults"`: The maximum number of results to include in the response. If more results
  exist than the specified MaxResults value, a token is included in the response so that the
  remaining results can be retrieved.
- `"nextToken"`: Null, or the token from a previous call to get the next set of results.
"""
function list_app_component_compliances(
    assessmentArn; aws_config::AbstractAWSConfig=global_aws_config()
)
    return resiliencehub(
        "POST",
        "/list-app-component-compliances",
        Dict{String,Any}("assessmentArn" => assessmentArn);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function list_app_component_compliances(
    assessmentArn,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return resiliencehub(
        "POST",
        "/list-app-component-compliances",
        Dict{String,Any}(
            mergewith(_merge, Dict{String,Any}("assessmentArn" => assessmentArn), params)
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

Lists the recommendations for an AWS Resilience Hub component.

# Arguments
- `assessment_arn`: The Amazon Resource Name (ARN) of the assessment. The format for this
  ARN is: arn:partition:dcps:region:account:app-assessment/app-id. For more information about
  ARNs, see  Amazon Resource Names (ARNs) in the AWS General Reference.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"maxResults"`: The maximum number of results to include in the response. If more results
  exist than the specified MaxResults value, a token is included in the response so that the
  remaining results can be retrieved.
- `"nextToken"`: Null, or the token from a previous call to get the next set of results.
"""
function list_app_component_recommendations(
    assessmentArn; aws_config::AbstractAWSConfig=global_aws_config()
)
    return resiliencehub(
        "POST",
        "/list-app-component-recommendations",
        Dict{String,Any}("assessmentArn" => assessmentArn);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function list_app_component_recommendations(
    assessmentArn,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return resiliencehub(
        "POST",
        "/list-app-component-recommendations",
        Dict{String,Any}(
            mergewith(_merge, Dict{String,Any}("assessmentArn" => assessmentArn), params)
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    list_app_version_resource_mappings(app_arn, app_version)
    list_app_version_resource_mappings(app_arn, app_version, params::Dict{String,<:Any})

Lists how the resources in an application version are mapped/sourced from. Mappings can be
physical resource identifiers, CloudFormation stacks, resource-groups, or an application
registry app.

# Arguments
- `app_arn`: The Amazon Resource Name (ARN) of the application. The format for this ARN is:
  arn:partition:dcps:region:account:app/app-id. For more information about ARNs, see  Amazon
  Resource Names (ARNs) in the AWS General Reference.
- `app_version`: The version of the application.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"maxResults"`: The maximum number of results to include in the response. If more results
  exist than the specified MaxResults value, a token is included in the response so that the
  remaining results can be retrieved.
- `"nextToken"`: Null, or the token from a previous call to get the next set of results.
"""
function list_app_version_resource_mappings(
    appArn, appVersion; aws_config::AbstractAWSConfig=global_aws_config()
)
    return resiliencehub(
        "POST",
        "/list-app-version-resource-mappings",
        Dict{String,Any}("appArn" => appArn, "appVersion" => appVersion);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function list_app_version_resource_mappings(
    appArn,
    appVersion,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return resiliencehub(
        "POST",
        "/list-app-version-resource-mappings",
        Dict{String,Any}(
            mergewith(
                _merge,
                Dict{String,Any}("appArn" => appArn, "appVersion" => appVersion),
                params,
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    list_app_version_resources(app_arn, app_version)
    list_app_version_resources(app_arn, app_version, params::Dict{String,<:Any})

Lists all the resources in an application version.

# Arguments
- `app_arn`: The Amazon Resource Name (ARN) of the application. The format for this ARN is:
  arn:partition:dcps:region:account:app/app-id. For more information about ARNs, see  Amazon
  Resource Names (ARNs) in the AWS General Reference.
- `app_version`: The version of the application.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"maxResults"`: The maximum number of results to include in the response. If more results
  exist than the specified MaxResults value, a token is included in the response so that the
  remaining results can be retrieved.
- `"nextToken"`: Null, or the token from a previous call to get the next set of results.
- `"resolutionId"`: The identifier for a specific resolution.
"""
function list_app_version_resources(
    appArn, appVersion; aws_config::AbstractAWSConfig=global_aws_config()
)
    return resiliencehub(
        "POST",
        "/list-app-version-resources",
        Dict{String,Any}("appArn" => appArn, "appVersion" => appVersion);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function list_app_version_resources(
    appArn,
    appVersion,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return resiliencehub(
        "POST",
        "/list-app-version-resources",
        Dict{String,Any}(
            mergewith(
                _merge,
                Dict{String,Any}("appArn" => appArn, "appVersion" => appVersion),
                params,
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

Lists the different versions for the Resilience Hub applications.

# Arguments
- `app_arn`: The Amazon Resource Name (ARN) of the application. The format for this ARN is:
  arn:partition:dcps:region:account:app/app-id. For more information about ARNs, see  Amazon
  Resource Names (ARNs) in the AWS General Reference.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"maxResults"`: The maximum number of results to include in the response. If more results
  exist than the specified MaxResults value, a token is included in the response so that the
  remaining results can be retrieved.
- `"nextToken"`: Null, or the token from a previous call to get the next set of results.
"""
function list_app_versions(appArn; aws_config::AbstractAWSConfig=global_aws_config())
    return resiliencehub(
        "POST",
        "/list-app-versions",
        Dict{String,Any}("appArn" => appArn);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function list_app_versions(
    appArn, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()
)
    return resiliencehub(
        "POST",
        "/list-app-versions",
        Dict{String,Any}(mergewith(_merge, Dict{String,Any}("appArn" => appArn), params));
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

Lists your Resilience Hub applications.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"appArn"`: The Amazon Resource Name (ARN) of the application. The format for this ARN
  is: arn:partition:dcps:region:account:app/app-id. For more information about ARNs, see
  Amazon Resource Names (ARNs) in the AWS General Reference.
- `"maxResults"`: The maximum number of results to include in the response. If more results
  exist than the specified MaxResults value, a token is included in the response so that the
  remaining results can be retrieved.
- `"name"`: The name for the one of the listed applications.
- `"nextToken"`: Null, or the token from a previous call to get the next set of results.
"""
function list_apps(; aws_config::AbstractAWSConfig=global_aws_config())
    return resiliencehub(
        "GET", "/list-apps"; aws_config=aws_config, feature_set=SERVICE_FEATURE_SET
    )
end
function list_apps(
    params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()
)
    return resiliencehub(
        "GET", "/list-apps", params; aws_config=aws_config, feature_set=SERVICE_FEATURE_SET
    )
end

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

Lists the recommendation templates for the Resilience Hub applications.

# Arguments
- `assessment_arn`: The Amazon Resource Name (ARN) of the assessment. The format for this
  ARN is: arn:partition:dcps:region:account:app-assessment/app-id. For more information about
  ARNs, see  Amazon Resource Names (ARNs) in the AWS General Reference.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"maxResults"`: The maximum number of results to include in the response. If more results
  exist than the specified MaxResults value, a token is included in the response so that the
  remaining results can be retrieved.
- `"name"`: The name for one of the listed recommendation templates.
- `"nextToken"`: Null, or the token from a previous call to get the next set of results.
- `"recommendationTemplateArn"`: The Amazon Resource Name (ARN) for a recommendation
  template.
- `"reverseOrder"`: The default is to sort by ascending startTime. To sort by descending
  startTime, set reverseOrder to true.
- `"status"`: The status of the action.
"""
function list_recommendation_templates(
    assessmentArn; aws_config::AbstractAWSConfig=global_aws_config()
)
    return resiliencehub(
        "GET",
        "/list-recommendation-templates",
        Dict{String,Any}("assessmentArn" => assessmentArn);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function list_recommendation_templates(
    assessmentArn,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return resiliencehub(
        "GET",
        "/list-recommendation-templates",
        Dict{String,Any}(
            mergewith(_merge, Dict{String,Any}("assessmentArn" => assessmentArn), params)
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

Lists the resiliency policies for the Resilience Hub applications.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"maxResults"`: The maximum number of results to include in the response. If more results
  exist than the specified MaxResults value, a token is included in the response so that the
  remaining results can be retrieved.
- `"nextToken"`: Null, or the token from a previous call to get the next set of results.
- `"policyName"`: The name of the policy
"""
function list_resiliency_policies(; aws_config::AbstractAWSConfig=global_aws_config())
    return resiliencehub(
        "GET",
        "/list-resiliency-policies";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function list_resiliency_policies(
    params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()
)
    return resiliencehub(
        "GET",
        "/list-resiliency-policies",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

Lists the standard operating procedure (SOP) recommendations for the Resilience Hub
applications.

# Arguments
- `assessment_arn`: The Amazon Resource Name (ARN) of the assessment. The format for this
  ARN is: arn:partition:dcps:region:account:app-assessment/app-id. For more information about
  ARNs, see  Amazon Resource Names (ARNs) in the AWS General Reference.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"maxResults"`: The maximum number of results to include in the response. If more results
  exist than the specified MaxResults value, a token is included in the response so that the
  remaining results can be retrieved.
- `"nextToken"`: Null, or the token from a previous call to get the next set of results.
"""
function list_sop_recommendations(
    assessmentArn; aws_config::AbstractAWSConfig=global_aws_config()
)
    return resiliencehub(
        "POST",
        "/list-sop-recommendations",
        Dict{String,Any}("assessmentArn" => assessmentArn);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function list_sop_recommendations(
    assessmentArn,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return resiliencehub(
        "POST",
        "/list-sop-recommendations",
        Dict{String,Any}(
            mergewith(_merge, Dict{String,Any}("assessmentArn" => assessmentArn), params)
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

Lists the suggested resiliency policies for the Resilience Hub applications.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"maxResults"`: The maximum number of results to include in the response. If more results
  exist than the specified MaxResults value, a token is included in the response so that the
  remaining results can be retrieved.
- `"nextToken"`: Null, or the token from a previous call to get the next set of results.
"""
function list_suggested_resiliency_policies(;
    aws_config::AbstractAWSConfig=global_aws_config()
)
    return resiliencehub(
        "GET",
        "/list-suggested-resiliency-policies";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function list_suggested_resiliency_policies(
    params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()
)
    return resiliencehub(
        "GET",
        "/list-suggested-resiliency-policies",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

Lists the tags for your resources in your Resilience Hub applications.

# Arguments
- `resource_arn`: The Amazon Resource Name (ARN) for a specific resource in your Resilience
  Hub application.

"""
function list_tags_for_resource(
    resourceArn; aws_config::AbstractAWSConfig=global_aws_config()
)
    return resiliencehub(
        "GET",
        "/tags/$(resourceArn)";
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function list_tags_for_resource(
    resourceArn,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return resiliencehub(
        "GET",
        "/tags/$(resourceArn)",
        params;
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

Lists the test recommendations for the Resilience Hub application.

# Arguments
- `assessment_arn`: The Amazon Resource Name (ARN) of the assessment. The format for this
  ARN is: arn:partition:dcps:region:account:app-assessment/app-id. For more information about
  ARNs, see  Amazon Resource Names (ARNs) in the AWS General Reference.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"maxResults"`: The maximum number of results to include in the response. If more results
  exist than the specified MaxResults value, a token is included in the response so that the
  remaining results can be retrieved.
- `"nextToken"`: Null, or the token from a previous call to get the next set of results.
"""
function list_test_recommendations(
    assessmentArn; aws_config::AbstractAWSConfig=global_aws_config()
)
    return resiliencehub(
        "POST",
        "/list-test-recommendations",
        Dict{String,Any}("assessmentArn" => assessmentArn);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function list_test_recommendations(
    assessmentArn,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return resiliencehub(
        "POST",
        "/list-test-recommendations",
        Dict{String,Any}(
            mergewith(_merge, Dict{String,Any}("assessmentArn" => assessmentArn), params)
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    list_unsupported_app_version_resources(app_arn, app_version)
    list_unsupported_app_version_resources(app_arn, app_version, params::Dict{String,<:Any})

Lists the resources that are not currently supported in AWS Resilience Hub. An unsupported
resource is a resource that exists in the object that was used to create an app, but is not
supported by Resilience Hub.

# Arguments
- `app_arn`: The Amazon Resource Name (ARN) of the application. The format for this ARN is:
  arn:partition:dcps:region:account:app/app-id. For more information about ARNs, see  Amazon
  Resource Names (ARNs) in the AWS General Reference.
- `app_version`: The version of the application.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"maxResults"`: The maximum number of results to include in the response. If more results
  exist than the specified MaxResults value, a token is included in the response so that the
  remaining results can be retrieved.
- `"nextToken"`: Null, or the token from a previous call to get the next set of results.
- `"resolutionId"`: The identifier for a specific resolution.
"""
function list_unsupported_app_version_resources(
    appArn, appVersion; aws_config::AbstractAWSConfig=global_aws_config()
)
    return resiliencehub(
        "POST",
        "/list-unsupported-app-version-resources",
        Dict{String,Any}("appArn" => appArn, "appVersion" => appVersion);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function list_unsupported_app_version_resources(
    appArn,
    appVersion,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return resiliencehub(
        "POST",
        "/list-unsupported-app-version-resources",
        Dict{String,Any}(
            mergewith(
                _merge,
                Dict{String,Any}("appArn" => appArn, "appVersion" => appVersion),
                params,
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

Publishes a new version of a specific Resilience Hub application.

# Arguments
- `app_arn`: The Amazon Resource Name (ARN) of the application. The format for this ARN is:
  arn:partition:dcps:region:account:app/app-id. For more information about ARNs, see  Amazon
  Resource Names (ARNs) in the AWS General Reference.

"""
function publish_app_version(appArn; aws_config::AbstractAWSConfig=global_aws_config())
    return resiliencehub(
        "POST",
        "/publish-app-version",
        Dict{String,Any}("appArn" => appArn);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function publish_app_version(
    appArn, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()
)
    return resiliencehub(
        "POST",
        "/publish-app-version",
        Dict{String,Any}(mergewith(_merge, Dict{String,Any}("appArn" => appArn), params));
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    put_draft_app_version_template(app_arn, app_template_body)
    put_draft_app_version_template(app_arn, app_template_body, params::Dict{String,<:Any})

Adds or updates the app template for a draft version of a Resilience Hub app.

# Arguments
- `app_arn`: The Amazon Resource Name (ARN) of the application. The format for this ARN is:
  arn:partition:dcps:region:account:app/app-id. For more information about ARNs, see  Amazon
  Resource Names (ARNs) in the AWS General Reference.
- `app_template_body`: A JSON string that contains the body of the app template.

"""
function put_draft_app_version_template(
    appArn, appTemplateBody; aws_config::AbstractAWSConfig=global_aws_config()
)
    return resiliencehub(
        "POST",
        "/put-draft-app-version-template",
        Dict{String,Any}("appArn" => appArn, "appTemplateBody" => appTemplateBody);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function put_draft_app_version_template(
    appArn,
    appTemplateBody,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return resiliencehub(
        "POST",
        "/put-draft-app-version-template",
        Dict{String,Any}(
            mergewith(
                _merge,
                Dict{String,Any}("appArn" => appArn, "appTemplateBody" => appTemplateBody),
                params,
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

Removes resource mappings from a draft application version.

# Arguments
- `app_arn`: The Amazon Resource Name (ARN) of the application. The format for this ARN is:
  arn:partition:dcps:region:account:app/app-id. For more information about ARNs, see  Amazon
  Resource Names (ARNs) in the AWS General Reference.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"appRegistryAppNames"`: The names of the registered applications to remove from the
  resource mappings.
- `"logicalStackNames"`: The names of the CloudFormation stacks to remove from the resource
  mappings.
- `"resourceGroupNames"`: The names of the resource groups to remove from the resource
  mappings.
- `"resourceNames"`: The names of the resources to remove from the resource mappings.
"""
function remove_draft_app_version_resource_mappings(
    appArn; aws_config::AbstractAWSConfig=global_aws_config()
)
    return resiliencehub(
        "POST",
        "/remove-draft-app-version-resource-mappings",
        Dict{String,Any}("appArn" => appArn);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function remove_draft_app_version_resource_mappings(
    appArn, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()
)
    return resiliencehub(
        "POST",
        "/remove-draft-app-version-resource-mappings",
        Dict{String,Any}(mergewith(_merge, Dict{String,Any}("appArn" => appArn), params));
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    resolve_app_version_resources(app_arn, app_version)
    resolve_app_version_resources(app_arn, app_version, params::Dict{String,<:Any})

Resolves the resources for an application version.

# Arguments
- `app_arn`: The Amazon Resource Name (ARN) of the application. The format for this ARN is:
  arn:partition:dcps:region:account:app/app-id. For more information about ARNs, see  Amazon
  Resource Names (ARNs) in the AWS General Reference.
- `app_version`: The version of the application.

"""
function resolve_app_version_resources(
    appArn, appVersion; aws_config::AbstractAWSConfig=global_aws_config()
)
    return resiliencehub(
        "POST",
        "/resolve-app-version-resources",
        Dict{String,Any}("appArn" => appArn, "appVersion" => appVersion);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function resolve_app_version_resources(
    appArn,
    appVersion,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return resiliencehub(
        "POST",
        "/resolve-app-version-resources",
        Dict{String,Any}(
            mergewith(
                _merge,
                Dict{String,Any}("appArn" => appArn, "appVersion" => appVersion),
                params,
            ),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

"""
    start_app_assessment(app_arn, app_version, assessment_name)
    start_app_assessment(app_arn, app_version, assessment_name, params::Dict{String,<:Any})

Creates a new application assessment for an application.

# Arguments
- `app_arn`: The Amazon Resource Name (ARN) of the application. The format for this ARN is:
  arn:partition:dcps:region:account:app/app-id. For more information about ARNs, see  Amazon
  Resource Names (ARNs) in the AWS General Reference.
- `app_version`: The version of the application.
- `assessment_name`: The name for the assessment.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"clientToken"`: Used for an idempotency token. A client token is a unique,
  case-sensitive string of up to 64 ASCII characters. You should not reuse the same client
  token for other API requests.
- `"tags"`: The tags assigned to the resource. A tag is a label that you assign to an
  Amazon Web Services resource. Each tag consists of a key/value pair.
"""
function start_app_assessment(
    appArn, appVersion, assessmentName; aws_config::AbstractAWSConfig=global_aws_config()
)
    return resiliencehub(
        "POST",
        "/start-app-assessment",
        Dict{String,Any}(
            "appArn" => appArn,
            "appVersion" => appVersion,
            "assessmentName" => assessmentName,
            "clientToken" => string(uuid4()),
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function start_app_assessment(
    appArn,
    appVersion,
    assessmentName,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return resiliencehub(
        "POST",
        "/start-app-assessment",
        Dict{String,Any}(
            mergewith(
                _merge,
                Dict{String,Any}(
                    "appArn" => appArn,
                    "appVersion" => appVersion,
                    "assessmentName" => assessmentName,
                    "clientToken" => string(uuid4()),
                ),
                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})

Applies one or more tags to a resource.

# Arguments
- `resource_arn`: The Amazon Resource Name (ARN) of the resource.
- `tags`: The tags to assign to the resource. Each tag consists of a key/value pair.

"""
function tag_resource(resourceArn, tags; aws_config::AbstractAWSConfig=global_aws_config())
    return resiliencehub(
        "POST",
        "/tags/$(resourceArn)",
        Dict{String,Any}("tags" => tags);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function tag_resource(
    resourceArn,
    tags,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return resiliencehub(
        "POST",
        "/tags/$(resourceArn)",
        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 one or more tags from a resource.

# Arguments
- `resource_arn`: The Amazon Resource Name (ARN) of the resource.
- `tag_keys`: The keys of the tags to remove.

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

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

Updates an application.

# Arguments
- `app_arn`: The Amazon Resource Name (ARN) of the application. The format for this ARN is:
  arn:partition:dcps:region:account:app/app-id. For more information about ARNs, see  Amazon
  Resource Names (ARNs) in the AWS General Reference.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"clearResiliencyPolicyArn"`: Specifies if the resiliency policy ARN should be cleared.
- `"description"`: The optional description for an app.
- `"policyArn"`: The Amazon Resource Name (ARN) of the resiliency policy. The format for
  this ARN is: arn:partition:dcps:region:account:resiliency-policy/policy-id. For more
  information about ARNs, see  Amazon Resource Names (ARNs) in the AWS General Reference.
"""
function update_app(appArn; aws_config::AbstractAWSConfig=global_aws_config())
    return resiliencehub(
        "POST",
        "/update-app",
        Dict{String,Any}("appArn" => appArn);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function update_app(
    appArn, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()
)
    return resiliencehub(
        "POST",
        "/update-app",
        Dict{String,Any}(mergewith(_merge, Dict{String,Any}("appArn" => appArn), params));
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end

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

Updates a resiliency policy.

# Arguments
- `policy_arn`: The Amazon Resource Name (ARN) of the resiliency policy. The format for
  this ARN is: arn:partition:dcps:region:account:resiliency-policy/policy-id. For more
  information about ARNs, see  Amazon Resource Names (ARNs) in the AWS General Reference.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"dataLocationConstraint"`: Specifies a high-level geographical location constraint for
  where your resilience policy data can be stored.
- `"policy"`: The type of resiliency policy to be created, including the recovery time
  objective (RTO) and recovery point objective (RPO) in seconds.
- `"policyDescription"`: The description for the policy.
- `"policyName"`: The name of the policy
- `"tier"`: The tier for this resiliency policy, ranging from the highest severity
  (MissionCritical) to lowest (NonCritical).
"""
function update_resiliency_policy(
    policyArn; aws_config::AbstractAWSConfig=global_aws_config()
)
    return resiliencehub(
        "POST",
        "/update-resiliency-policy",
        Dict{String,Any}("policyArn" => policyArn);
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end
function update_resiliency_policy(
    policyArn,
    params::AbstractDict{String};
    aws_config::AbstractAWSConfig=global_aws_config(),
)
    return resiliencehub(
        "POST",
        "/update-resiliency-policy",
        Dict{String,Any}(
            mergewith(_merge, Dict{String,Any}("policyArn" => policyArn), params)
        );
        aws_config=aws_config,
        feature_set=SERVICE_FEATURE_SET,
    )
end


text:
function randomizedtrellis(cover,stegos,message,hhat,h,embpath,randomnodes::Float64)
    x=readlsb(cover,embpath);
    newstegos=deepcopy(stegos)
    stego=deepcopy(stegos[1])

    path=zeros(UInt8,2^h,length(x));
    numofblocks=length(message);

    wght=zeros(2^h);        #holds the costs of current "state"
    newwght=zeros(2^h);     #contained for holding costs of currently generated states
    wght[2:end]=Inf64;
    indx=1  #this indexes the cover
    indm=1  #this indexes the message bits
    y=zeros(UInt8,length(x))
    calculated_costs = 0
    for i in 1:numofblocks #iterate over the number of subblocks, each encodes one message bit
        hh=min(h,length(message)-indm+1)  #this is effective height of the submatrix, which is needed
        for j in 1:length(hhat) #iterate over columns of the H matrix
            # println("pidx $(embpath[indx])")
            for k in 0:2^hh-1 # iterate over each state of the matrix
                # println()
                # there are two possibilities to reach the state k. Either we code zero,
                # in which case the price (weight) is equal to weight of the same state in previous iteration + possible change,
                # or we code one and the state is reached from other state determined by the column of the hhat matrix.
                ind0=k+1 #index of the case, when the current LSB should be zero, i.e we are not adding current hhat[j]
                ind1=(k ⊻ hhat[j])&(2^hh-1)+1 #index to the state to which we come in case we are adding current hhat[j]

                #the determination of the cost is not entirely easy, since we arrive from two
                # different sources. The option here is either to use the current version of the image
                # and have the LSB cleared, which should correspond to w00, or come from the alternative and have
                # and have LSB set, which should correspond to w11

                #if we want to decide the way randomly
                w00 = isinf(wght[ind0]) ? wght[ind0] : rand()
                w11 = isinf(wght[ind1]) ? wght[ind1] : rand()

                if rand()>randomnodes
                    if Int(mod(stegos[ind0][embpath[indx]],2))==0
                        w00=wght[ind0]
                        w11=(isinf(wght[ind1])) ? wght[ind1] : LSBcostfun(stegos[ind1],embpath[indx])[2] ;
                    else
                        w11=wght[ind1]
                        w00=(isinf(wght[ind0])) ? wght[ind0] : LSBcostfun(stegos[ind0],embpath[indx])[1];
                    end
                    calculated_costs +=1
                end

                # choose the less costly path to the state, update weights
                # and update the current feature vector and sums
                if w00<w11
                    copy!(newstegos[ind0],stegos[ind0])
                    path[ind0,indx] = 0x0
                    newwght[ind0] = (isinf(w00)) ? w00 : matchlsb!(newstegos[ind0],0x0,embpath[indx])
                else
                    copy!(newstegos[ind0],stegos[ind1])
                    path[ind0,indx] = 0x1
                    newwght[ind0] = (isinf(w11)) ? w11 : matchlsb!(newstegos[ind0],0x1,embpath[indx])
                end
            end
            indx+=1
            (stegos,newstegos)=swap(stegos,newstegos)
            (wght,newwght)=swap(wght,newwght)
        end

        # once we have traversed the trellis, we need to determine which path through trellises codes the message and
        # remove the others
        # println("reducing the number of states")
        for j = 0:2^(hh-1)-1
            midx=2*j + message[indm]+1
            wght[j+1] = wght[midx]
            copy!(stegos[j+1],stegos[midx])
         end
        wght[2^(hh-1)+1:end]=Inf64;
        newwght[2^(hh-1)+1:end]=Inf64;
        indm+=1
    end

    #there is no need to walkback the trellis, since we have already embedded image in stegos[1]
    embedding_cost = wght[1]
    info(@sprintf("embedding costs by stc = %g calculated_costs = %.3f",embedding_cost,Float64(calculated_costs)/(2^h*length(cover))))

    # check that the extracted message match the embedded message
    if !isinf(embedding_cost)
        extm=extract(readlsb(stegos[1],embpath),hhat,h)[1:length(message)];
        (sum(abs.(extm.!=message))==0) ? info("message has been correctly extracted") : warn("message has not been correctly extracted");
    end
    return(deepcopy(stegos[1]),wght[1])
end

randomizedtrellis(cover,stegos,message,hhat,h,randomnodes::Float64) = randomizedtrellis(cover,stegos,message,hhat,h,randperm(length(cover)),randomnodes)


text:
# The PC is centered on a rectangular grid, while the grid-based FD sits in a cubic grid.

using DelimitedFiles
using MAT
# using DSP

function smoothObj(Obj,times)
Obj = copy(Obj);
for k = 1:times
	Obj[2:end-1,2:end-1,2:end-1] = 	(Obj[2:end-1,2:end-1,2:end-1].*3.0 +
									Obj[3:end  ,2:end-1,2:end-1] +
									Obj[1:end-2,2:end-1,2:end-1] +
									Obj[2:end-1,1:end-2,2:end-1] +
									Obj[2:end-1,3:end  ,2:end-1] +
									Obj[2:end-1,2:end-1,1:end-2] +
									Obj[2:end-1,2:end-1,3:end  ])./9.0;
end
return Obj;
end

# function smoothObj9(Obj,times)
# for k=1:times
	# Obj = conv([1;2;1]/4.0,[1;2;1]/4.0,Obj);
# end
# return Obj;
# end

PC_orig = readdlm("fandisksmall.xyz");
Ns = PC_orig[:,4:6];
PC = PC_orig[:,1:3];
println(maximum(PC,dims=1));
# PC = PC*Diagonal(0.5./maximum(PC,dims=1)[:]);
println(maximum(PC,dims=1));
F = matopen("fandisksmall.mat");
B = read(F,"B");
n = size(B);
println(n)
pad = div.([400;400;400] .- collect(n),2) .+ 20;
B_pad = zeros(n[1]+2*pad[1],n[2]+2*pad[2],n[3]+2*pad[3]);
B_pad[pad[1]+1:end-pad[1],pad[2]+1:end-pad[2],pad[3]+1:end-pad[3]] .= B;
println("Smooth!")
B_pad = smoothObj(B_pad,3);

println(minimum(PC.+[23/50.0 12.75/50.0 25.0/50.0],dims=1))
println(maximum(PC.+[23/50.0 12.75/50.0 25.0/50.0],dims=1))

PC_subs = ceil.(Int64,(PC.+[23/50.0 12.75/50.0 25.0/50.0]).*400) .+ pad';
println("starting test");
for k = 1:size(PC_subs,1)
	testval = B_pad[PC_subs[k,1],PC_subs[k,2],PC_subs[k,3]];
	if testval >= 1.0 - 1e-8 || testval < 1e-8
		display(B_pad[PC_subs[k,1].+ (-1:1),PC_subs[k,2].+ (-1:1),PC_subs[k,3].+ (-1:1)]);
		println(testval)
		error("IM HERE");
	end
end

max_stars_repo_name: BGUCompSci/ShapeReconstructionPaLS

max_issues_repo_name: BGUCompSci/ShapeReconstructionPaLS

max_forks_repo_name: BGUCompSci/ShapeReconstructionPaLS


text:
export get_image, zeroonenorm

using Zygote: @adjoint

# ---------- #
# Processing #
# ---------- #

"""
    get_image(image, width, height)

Reshapes and normalizes a Vec3 color format to the RGB format of Images
for easy loading, saving and visualization.

### Arguments:

* `image`  - The rendered image in flattened Vec3 format
           (i.e., the output of the raytrace, rasterize, etc.)
* `width`  - Width of the output image
* `height` - Height of the output image
"""
function get_image(im::Vec3{T}, width, height) where {T}
    low = eltype(T)(0)
    high = eltype(T)(1)
    color_r = reshape(im.x, width, height)
    color_g = reshape(im.y, width, height)
    color_b = reshape(im.z, width, height)

    im_arr = zeroonenorm(permutedims(reshape(hcat(color_r, color_g, color_b), (width, height, 3)), (3, 2, 1)))

    return colorview(RGB, im_arr)
end

"""
    zeroonenorm(x::AbstractArray)

Normalizes the elements of the array to values between `0` and `1`.

!!! note
    This function exists because the version of Zygote we use returns
    incorrect gradient for `1/maximum(x)` function. This has been fixed
    on the latest release of Zygote.
"""
zeroonenorm(x) = (x .- minimum(x)) ./ (maximum(x) - minimum(x))